Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
network.c
Go to the documentation of this file.
1 /*
2  *
3  * arch/xtensa/platforms/iss/network.c
4  *
5  * Platform specific initialization.
6  *
7  * Authors: Chris Zankel <[email protected]>
8  * Based on work form the UML team.
9  *
10  * Copyright 2005 Tensilica Inc.
11  *
12  * This program is free software; you can redistribute it and/or modify it
13  * under the terms of the GNU General Public License as published by the
14  * Free Software Foundation; either version 2 of the License, or (at your
15  * option) any later version.
16  *
17  */
18 
19 #include <linux/list.h>
20 #include <linux/irq.h>
21 #include <linux/spinlock.h>
22 #include <linux/slab.h>
23 #include <linux/timer.h>
24 #include <linux/if_ether.h>
25 #include <linux/inetdevice.h>
26 #include <linux/init.h>
27 #include <linux/if_tun.h>
28 #include <linux/etherdevice.h>
29 #include <linux/interrupt.h>
30 #include <linux/ioctl.h>
31 #include <linux/bootmem.h>
32 #include <linux/ethtool.h>
33 #include <linux/rtnetlink.h>
34 #include <linux/platform_device.h>
35 
36 #include <platform/simcall.h>
37 
38 #define DRIVER_NAME "iss-netdev"
39 #define ETH_MAX_PACKET 1500
40 #define ETH_HEADER_OTHER 14
41 #define ISS_NET_TIMER_VALUE (2 * HZ)
42 
43 
44 static DEFINE_SPINLOCK(opened_lock);
45 static LIST_HEAD(opened);
46 
47 static DEFINE_SPINLOCK(devices_lock);
48 static LIST_HEAD(devices);
49 
50 /* ------------------------------------------------------------------------- */
51 
52 /* We currently only support the TUNTAP transport protocol. */
53 
54 #define TRANSPORT_TUNTAP_NAME "tuntap"
55 #define TRANSPORT_TUNTAP_MTU ETH_MAX_PACKET
56 
57 struct tuntap_info {
60  unsigned char gw[ETH_ALEN];
61  int fd;
62 };
63 
64 /* ------------------------------------------------------------------------- */
65 
66 
67 /* This structure contains out private information for the driver. */
68 
70 
73 
75  struct net_device *dev;
77  struct timer_list tl;
79 
80  struct timer_list timer;
81  unsigned int timer_val;
82 
83  int index;
84  int mtu;
85 
86  unsigned char mac[ETH_ALEN];
87  int have_mac;
88 
89  struct {
90  union {
92  } info;
93 
94  int (*open)(struct iss_net_private *lp);
96  int (*read)(struct iss_net_private *lp, struct sk_buff **skb);
97  int (*write)(struct iss_net_private *lp, struct sk_buff **skb);
98  unsigned short (*protocol)(struct sk_buff *skb);
99  int (*poll)(struct iss_net_private *lp);
100  } tp;
101 
102 };
103 
104 /* ================================ HELPERS ================================ */
105 
106 
107 static char *split_if_spec(char *str, ...)
108 {
109  char **arg, *end;
110  va_list ap;
111 
112  va_start(ap, str);
113  while ((arg = va_arg(ap, char**)) != NULL) {
114  if (*str == '\0')
115  return NULL;
116  end = strchr(str, ',');
117  if (end != str)
118  *arg = str;
119  if (end == NULL)
120  return NULL;
121  *end ++ = '\0';
122  str = end;
123  }
124  va_end(ap);
125  return str;
126 }
127 
128 
129 #if 0
130 /* Adjust SKB. */
131 
132 struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra)
133 {
134  if ((skb != NULL) && (skb_tailroom(skb) < extra)) {
135  struct sk_buff *skb2;
136 
137  skb2 = skb_copy_expand(skb, 0, extra, GFP_ATOMIC);
138  dev_kfree_skb(skb);
139  skb = skb2;
140  }
141  if (skb != NULL)
142  skb_put(skb, extra);
143 
144  return skb;
145 }
146 #endif
147 
148 /* Return the IP address as a string for a given device. */
149 
150 static void dev_ip_addr(void *d, char *buf, char *bin_buf)
151 {
152  struct net_device *dev = d;
153  struct in_device *ip = dev->ip_ptr;
154  struct in_ifaddr *in;
155  __be32 addr;
156 
157  if ((ip == NULL) || ((in = ip->ifa_list) == NULL)) {
158  printk(KERN_WARNING "Device not assigned an IP address!\n");
159  return;
160  }
161 
162  addr = in->ifa_address;
163  sprintf(buf, "%d.%d.%d.%d", addr & 0xff, (addr >> 8) & 0xff,
164  (addr >> 16) & 0xff, addr >> 24);
165 
166  if (bin_buf) {
167  bin_buf[0] = addr & 0xff;
168  bin_buf[1] = (addr >> 8) & 0xff;
169  bin_buf[2] = (addr >> 16) & 0xff;
170  bin_buf[3] = addr >> 24;
171  }
172 }
173 
174 /* Set Ethernet address of the specified device. */
175 
176 static void inline set_ether_mac(void *d, unsigned char *addr)
177 {
178  struct net_device *dev = d;
179  memcpy(dev->dev_addr, addr, ETH_ALEN);
180 }
181 
182 
183 /* ======================= TUNTAP TRANSPORT INTERFACE ====================== */
184 
185 static int tuntap_open(struct iss_net_private *lp)
186 {
187  struct ifreq ifr;
188  char *dev_name = lp->tp.info.tuntap.dev_name;
189  int err = -EINVAL;
190  int fd;
191 
192  /* We currently only support a fixed configuration. */
193 
194  if (!lp->tp.info.tuntap.fixed_config)
195  return -EINVAL;
196 
197  if ((fd = simc_open("/dev/net/tun", 02, 0)) < 0) { /* O_RDWR */
198  printk("Failed to open /dev/net/tun, returned %d "
199  "(errno = %d)\n", fd, errno);
200  return fd;
201  }
202 
203  memset(&ifr, 0, sizeof ifr);
204  ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
205  strlcpy(ifr.ifr_name, dev_name, sizeof ifr.ifr_name);
206 
207  if ((err = simc_ioctl(fd, TUNSETIFF, (void*) &ifr)) < 0) {
208  printk("Failed to set interface, returned %d "
209  "(errno = %d)\n", err, errno);
210  simc_close(fd);
211  return err;
212  }
213 
214  lp->tp.info.tuntap.fd = fd;
215  return err;
216 }
217 
218 static void tuntap_close(struct iss_net_private *lp)
219 {
220 #if 0
221  if (lp->tp.info.tuntap.fixed_config)
222  iter_addresses(lp->tp.info.tuntap.dev, close_addr, lp->host.dev_name);
223 #endif
224  simc_close(lp->tp.info.tuntap.fd);
225  lp->tp.info.tuntap.fd = -1;
226 }
227 
228 static int tuntap_read (struct iss_net_private *lp, struct sk_buff **skb)
229 {
230 #if 0
231  *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
232  if (*skb == NULL)
233  return -ENOMEM;
234 #endif
235 
236  return simc_read(lp->tp.info.tuntap.fd,
237  (*skb)->data, (*skb)->dev->mtu + ETH_HEADER_OTHER);
238 }
239 
240 static int tuntap_write (struct iss_net_private *lp, struct sk_buff **skb)
241 {
242  return simc_write(lp->tp.info.tuntap.fd, (*skb)->data, (*skb)->len);
243 }
244 
245 unsigned short tuntap_protocol(struct sk_buff *skb)
246 {
247  return eth_type_trans(skb, skb->dev);
248 }
249 
250 static int tuntap_poll(struct iss_net_private *lp)
251 {
252  return simc_poll(lp->tp.info.tuntap.fd);
253 }
254 
255 /*
256  * Currently only a device name is supported.
257  * ethX=tuntap[,[mac address][,[device name]]]
258  */
259 
260 static int tuntap_probe(struct iss_net_private *lp, int index, char *init)
261 {
262  const int len = strlen(TRANSPORT_TUNTAP_NAME);
263  char *dev_name = NULL, *mac_str = NULL, *rem = NULL;
264 
265  /* Transport should be 'tuntap': ethX=tuntap,mac,dev_name */
266 
267  if (strncmp(init, TRANSPORT_TUNTAP_NAME, len))
268  return 0;
269 
270  if (*(init += strlen(TRANSPORT_TUNTAP_NAME)) == ',') {
271  if ((rem=split_if_spec(init+1, &mac_str, &dev_name)) != NULL) {
272  printk("Extra garbage on specification : '%s'\n", rem);
273  return 0;
274  }
275  } else if (*init != '\0') {
276  printk("Invalid argument: %s. Skipping device!\n", init);
277  return 0;
278  }
279 
280  if (dev_name) {
281  strncpy(lp->tp.info.tuntap.dev_name, dev_name,
282  sizeof lp->tp.info.tuntap.dev_name);
283  lp->tp.info.tuntap.fixed_config = 1;
284  } else
285  strcpy(lp->tp.info.tuntap.dev_name, TRANSPORT_TUNTAP_NAME);
286 
287 
288 #if 0
289  if (setup_etheraddr(mac_str, lp->mac))
290  lp->have_mac = 1;
291 #endif
293 
294  //lp->info.tuntap.gate_addr = gate_addr;
295 
296  lp->tp.info.tuntap.fd = -1;
297 
298  lp->tp.open = tuntap_open;
299  lp->tp.close = tuntap_close;
300  lp->tp.read = tuntap_read;
301  lp->tp.write = tuntap_write;
302  lp->tp.protocol = tuntap_protocol;
303  lp->tp.poll = tuntap_poll;
304 
305  printk("TUN/TAP backend - ");
306 #if 0
307  if (lp->host.gate_addr != NULL)
308  printk("IP = %s", lp->host.gate_addr);
309 #endif
310  printk("\n");
311 
312  return 1;
313 }
314 
315 /* ================================ ISS NET ================================ */
316 
317 static int iss_net_rx(struct net_device *dev)
318 {
319  struct iss_net_private *lp = netdev_priv(dev);
320  int pkt_len;
321  struct sk_buff *skb;
322 
323  /* Check if there is any new data. */
324 
325  if (lp->tp.poll(lp) == 0)
326  return 0;
327 
328  /* Try to allocate memory, if it fails, try again next round. */
329 
330  if ((skb = dev_alloc_skb(dev->mtu + 2 + ETH_HEADER_OTHER)) == NULL) {
331  lp->stats.rx_dropped++;
332  return 0;
333  }
334 
335  skb_reserve(skb, 2);
336 
337  /* Setup skb */
338 
339  skb->dev = dev;
340  skb_reset_mac_header(skb);
341  pkt_len = lp->tp.read(lp, &skb);
342  skb_put(skb, pkt_len);
343 
344  if (pkt_len > 0) {
345  skb_trim(skb, pkt_len);
346  skb->protocol = lp->tp.protocol(skb);
347 
348  lp->stats.rx_bytes += skb->len;
349  lp->stats.rx_packets++;
350  // netif_rx(skb);
351  netif_rx_ni(skb);
352  return pkt_len;
353  }
354  kfree_skb(skb);
355  return pkt_len;
356 }
357 
358 static int iss_net_poll(void)
359 {
360  struct list_head *ele;
361  int err, ret = 0;
362 
363  spin_lock(&opened_lock);
364 
365  list_for_each(ele, &opened) {
366  struct iss_net_private *lp;
367 
368  lp = list_entry(ele, struct iss_net_private, opened_list);
369 
370  if (!netif_running(lp->dev))
371  break;
372 
373  spin_lock(&lp->lock);
374 
375  while ((err = iss_net_rx(lp->dev)) > 0)
376  ret++;
377 
378  spin_unlock(&lp->lock);
379 
380  if (err < 0) {
381  printk(KERN_ERR "Device '%s' read returned %d, "
382  "shutting it down\n", lp->dev->name, err);
383  dev_close(lp->dev);
384  } else {
385  // FIXME reactivate_fd(lp->fd, ISS_ETH_IRQ);
386  }
387  }
388 
389  spin_unlock(&opened_lock);
390  return ret;
391 }
392 
393 
394 static void iss_net_timer(unsigned long priv)
395 {
396  struct iss_net_private* lp = (struct iss_net_private*) priv;
397 
398  spin_lock(&lp->lock);
399 
400  iss_net_poll();
401 
402  mod_timer(&lp->timer, jiffies + lp->timer_val);
403 
404  spin_unlock(&lp->lock);
405 }
406 
407 
408 static int iss_net_open(struct net_device *dev)
409 {
410  struct iss_net_private *lp = netdev_priv(dev);
411  char addr[sizeof "255.255.255.255\0"];
412  int err;
413 
414  spin_lock(&lp->lock);
415 
416  if ((err = lp->tp.open(lp)) < 0)
417  goto out;
418 
419  if (!lp->have_mac) {
420  dev_ip_addr(dev, addr, &lp->mac[2]);
421  set_ether_mac(dev, lp->mac);
422  }
423 
424  netif_start_queue(dev);
425 
426  /* clear buffer - it can happen that the host side of the interface
427  * is full when we get here. In this case, new data is never queued,
428  * SIGIOs never arrive, and the net never works.
429  */
430  while ((err = iss_net_rx(dev)) > 0)
431  ;
432 
433  spin_lock(&opened_lock);
434  list_add(&lp->opened_list, &opened);
435  spin_unlock(&opened_lock);
436 
437  init_timer(&lp->timer);
439  lp->timer.data = (unsigned long) lp;
440  lp->timer.function = iss_net_timer;
441  mod_timer(&lp->timer, jiffies + lp->timer_val);
442 
443 out:
444  spin_unlock(&lp->lock);
445  return err;
446 }
447 
448 static int iss_net_close(struct net_device *dev)
449 {
450  struct iss_net_private *lp = netdev_priv(dev);
451 printk("iss_net_close!\n");
452  netif_stop_queue(dev);
453  spin_lock(&lp->lock);
454 
455  spin_lock(&opened_lock);
456  list_del(&opened);
457  spin_unlock(&opened_lock);
458 
459  del_timer_sync(&lp->timer);
460 
461  lp->tp.close(lp);
462 
463  spin_unlock(&lp->lock);
464  return 0;
465 }
466 
467 static int iss_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
468 {
469  struct iss_net_private *lp = netdev_priv(dev);
470  unsigned long flags;
471  int len;
472 
473  netif_stop_queue(dev);
474  spin_lock_irqsave(&lp->lock, flags);
475 
476  len = lp->tp.write(lp, &skb);
477 
478  if (len == skb->len) {
479  lp->stats.tx_packets++;
480  lp->stats.tx_bytes += skb->len;
481  dev->trans_start = jiffies;
482  netif_start_queue(dev);
483 
484  /* this is normally done in the interrupt when tx finishes */
485  netif_wake_queue(dev);
486 
487  } else if (len == 0) {
488  netif_start_queue(dev);
489  lp->stats.tx_dropped++;
490 
491  } else {
492  netif_start_queue(dev);
493  printk(KERN_ERR "iss_net_start_xmit: failed(%d)\n", len);
494  }
495 
496  spin_unlock_irqrestore(&lp->lock, flags);
497 
498  dev_kfree_skb(skb);
499  return NETDEV_TX_OK;
500 }
501 
502 
503 static struct net_device_stats *iss_net_get_stats(struct net_device *dev)
504 {
505  struct iss_net_private *lp = netdev_priv(dev);
506  return &lp->stats;
507 }
508 
509 static void iss_net_set_multicast_list(struct net_device *dev)
510 {
511 #if 0
512  if (dev->flags & IFF_PROMISC)
513  return;
514  else if (!netdev_mc_empty(dev))
515  dev->flags |= IFF_ALLMULTI;
516  else
517  dev->flags &= ~IFF_ALLMULTI;
518 #endif
519 }
520 
521 static void iss_net_tx_timeout(struct net_device *dev)
522 {
523 #if 0
524  dev->trans_start = jiffies;
525  netif_wake_queue(dev);
526 #endif
527 }
528 
529 static int iss_net_set_mac(struct net_device *dev, void *addr)
530 {
531 #if 0
532  struct iss_net_private *lp = netdev_priv(dev);
533  struct sockaddr *hwaddr = addr;
534 
535  spin_lock(&lp->lock);
536  memcpy(dev->dev_addr, hwaddr->sa_data, ETH_ALEN);
537  spin_unlock(&lp->lock);
538 #endif
539 
540  return 0;
541 }
542 
543 static int iss_net_change_mtu(struct net_device *dev, int new_mtu)
544 {
545 #if 0
546  struct iss_net_private *lp = netdev_priv(dev);
547  int err = 0;
548 
549  spin_lock(&lp->lock);
550 
551  // FIXME not needed new_mtu = transport_set_mtu(new_mtu, &lp->user);
552 
553  if (new_mtu < 0)
554  err = new_mtu;
555  else
556  dev->mtu = new_mtu;
557 
558  spin_unlock(&lp->lock);
559  return err;
560 #endif
561  return -EINVAL;
562 }
563 
564 void iss_net_user_timer_expire(unsigned long _conn)
565 {
566 }
567 
568 
569 static struct platform_driver iss_net_driver = {
570  .driver = {
571  .name = DRIVER_NAME,
572  },
573 };
574 
575 static int driver_registered;
576 
577 static const struct net_device_ops iss_netdev_ops = {
578  .ndo_open = iss_net_open,
579  .ndo_stop = iss_net_close,
580  .ndo_get_stats = iss_net_get_stats,
581  .ndo_start_xmit = iss_net_start_xmit,
582  .ndo_validate_addr = eth_validate_addr,
583  .ndo_change_mtu = iss_net_change_mtu,
584  .ndo_set_mac_address = iss_net_set_mac,
585  //.ndo_do_ioctl = iss_net_ioctl,
586  .ndo_tx_timeout = iss_net_tx_timeout,
587  .ndo_set_rx_mode = iss_net_set_multicast_list,
588 };
589 
590 static int iss_net_configure(int index, char *init)
591 {
592  struct net_device *dev;
593  struct iss_net_private *lp;
594  int err;
595 
596  if ((dev = alloc_etherdev(sizeof *lp)) == NULL) {
597  printk(KERN_ERR "eth_configure: failed to allocate device\n");
598  return 1;
599  }
600 
601  /* Initialize private element. */
602 
603  lp = netdev_priv(dev);
604  *lp = ((struct iss_net_private) {
605  .device_list = LIST_HEAD_INIT(lp->device_list),
606  .opened_list = LIST_HEAD_INIT(lp->opened_list),
607  .lock = __SPIN_LOCK_UNLOCKED(lp.lock),
608  .dev = dev,
609  .index = index,
610  //.fd = -1,
611  .mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0 },
612  .have_mac = 0,
613  });
614 
615  /*
616  * Try all transport protocols.
617  * Note: more protocols can be added by adding '&& !X_init(lp, eth)'.
618  */
619 
620  if (!tuntap_probe(lp, index, init)) {
621  printk("Invalid arguments. Skipping device!\n");
622  goto errout;
623  }
624 
625  printk(KERN_INFO "Netdevice %d ", index);
626  if (lp->have_mac)
627  printk("(%pM) ", lp->mac);
628  printk(": ");
629 
630  /* sysfs register */
631 
632  if (!driver_registered) {
633  platform_driver_register(&iss_net_driver);
634  driver_registered = 1;
635  }
636 
637  spin_lock(&devices_lock);
638  list_add(&lp->device_list, &devices);
639  spin_unlock(&devices_lock);
640 
641  lp->pdev.id = index;
642  lp->pdev.name = DRIVER_NAME;
644  SET_NETDEV_DEV(dev,&lp->pdev.dev);
645 
646  /*
647  * If this name ends up conflicting with an existing registered
648  * netdevice, that is OK, register_netdev{,ice}() will notice this
649  * and fail.
650  */
651  snprintf(dev->name, sizeof dev->name, "eth%d", index);
652 
653  dev->netdev_ops = &iss_netdev_ops;
654  dev->mtu = lp->mtu;
655  dev->watchdog_timeo = (HZ >> 1);
656  dev->irq = -1;
657 
658  rtnl_lock();
659  err = register_netdevice(dev);
660  rtnl_unlock();
661 
662  if (err) {
663  printk("Error registering net device!\n");
664  /* XXX: should we call ->remove() here? */
665  free_netdev(dev);
666  return 1;
667  }
668 
669  init_timer(&lp->tl);
670  lp->tl.function = iss_net_user_timer_expire;
671 
672 #if 0
673  if (lp->have_mac)
674  set_ether_mac(dev, lp->mac);
675 #endif
676  return 0;
677 
678 errout:
679  // FIXME: unregister; free, etc..
680  return -EIO;
681 
682 }
683 
684 /* ------------------------------------------------------------------------- */
685 
686 /* Filled in during early boot */
687 
688 struct list_head eth_cmd_line = LIST_HEAD_INIT(eth_cmd_line);
689 
690 struct iss_net_init {
691  struct list_head list;
692  char *init; /* init string */
693  int index;
694 };
695 
696 /*
697  * Parse the command line and look for 'ethX=...' fields, and register all
698  * those fields. They will be later initialized in iss_net_init.
699  */
700 
701 #define ERR KERN_ERR "iss_net_setup: "
702 
703 static int iss_net_setup(char *str)
704 {
705  struct iss_net_private *device = NULL;
706  struct iss_net_init *new;
707  struct list_head *ele;
708  char *end;
709  int n;
710 
711  n = simple_strtoul(str, &end, 0);
712  if (end == str) {
713  printk(ERR "Failed to parse '%s'\n", str);
714  return 1;
715  }
716  if (n < 0) {
717  printk(ERR "Device %d is negative\n", n);
718  return 1;
719  }
720  if (*(str = end) != '=') {
721  printk(ERR "Expected '=' after device number\n");
722  return 1;
723  }
724 
725  spin_lock(&devices_lock);
726 
727  list_for_each(ele, &devices) {
728  device = list_entry(ele, struct iss_net_private, device_list);
729  if (device->index == n)
730  break;
731  }
732 
733  spin_unlock(&devices_lock);
734 
735  if (device && device->index == n) {
736  printk(ERR "Device %d already configured\n", n);
737  return 1;
738  }
739 
740  if ((new = alloc_bootmem(sizeof new)) == NULL) {
741  printk("Alloc_bootmem failed\n");
742  return 1;
743  }
744 
745  INIT_LIST_HEAD(&new->list);
746  new->index = n;
747  new->init = str + 1;
748 
749  list_add_tail(&new->list, &eth_cmd_line);
750  return 1;
751 }
752 
753 #undef ERR
754 
755 __setup("eth=", iss_net_setup);
756 
757 /*
758  * Initialize all ISS Ethernet devices previously registered in iss_net_setup.
759  */
760 
761 static int iss_net_init(void)
762 {
763  struct list_head *ele, *next;
764 
765  /* Walk through all Ethernet devices specified in the command line. */
766 
767  list_for_each_safe(ele, next, &eth_cmd_line) {
768  struct iss_net_init *eth;
769  eth = list_entry(ele, struct iss_net_init, list);
770  iss_net_configure(eth->index, eth->init);
771  }
772 
773  return 1;
774 }
775 
777