1 /* 2 * 3 * arch/xtensa/platforms/iss/network.c 4 * 5 * Platform specific initialization. 6 * 7 * Authors: Chris Zankel <chris@zankel.net> 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 #define pr_fmt(fmt) "%s: " fmt, __func__ 20 21 #include <linux/list.h> 22 #include <linux/irq.h> 23 #include <linux/spinlock.h> 24 #include <linux/slab.h> 25 #include <linux/timer.h> 26 #include <linux/if_ether.h> 27 #include <linux/inetdevice.h> 28 #include <linux/init.h> 29 #include <linux/if_tun.h> 30 #include <linux/etherdevice.h> 31 #include <linux/interrupt.h> 32 #include <linux/ioctl.h> 33 #include <linux/bootmem.h> 34 #include <linux/ethtool.h> 35 #include <linux/rtnetlink.h> 36 #include <linux/platform_device.h> 37 38 #include <platform/simcall.h> 39 40 #define DRIVER_NAME "iss-netdev" 41 #define ETH_MAX_PACKET 1500 42 #define ETH_HEADER_OTHER 14 43 #define ISS_NET_TIMER_VALUE (HZ / 10) 44 45 46 static DEFINE_SPINLOCK(opened_lock); 47 static LIST_HEAD(opened); 48 49 static DEFINE_SPINLOCK(devices_lock); 50 static LIST_HEAD(devices); 51 52 /* ------------------------------------------------------------------------- */ 53 54 /* We currently only support the TUNTAP transport protocol. */ 55 56 #define TRANSPORT_TUNTAP_NAME "tuntap" 57 #define TRANSPORT_TUNTAP_MTU ETH_MAX_PACKET 58 59 struct tuntap_info { 60 char dev_name[IFNAMSIZ]; 61 int fd; 62 }; 63 64 /* ------------------------------------------------------------------------- */ 65 66 67 /* This structure contains out private information for the driver. */ 68 69 struct iss_net_private { 70 struct list_head device_list; 71 struct list_head opened_list; 72 73 spinlock_t lock; 74 struct net_device *dev; 75 struct platform_device pdev; 76 struct timer_list tl; 77 struct net_device_stats stats; 78 79 struct timer_list timer; 80 unsigned int timer_val; 81 82 int index; 83 int mtu; 84 85 struct { 86 union { 87 struct tuntap_info tuntap; 88 } info; 89 90 int (*open)(struct iss_net_private *lp); 91 void (*close)(struct iss_net_private *lp); 92 int (*read)(struct iss_net_private *lp, struct sk_buff **skb); 93 int (*write)(struct iss_net_private *lp, struct sk_buff **skb); 94 unsigned short (*protocol)(struct sk_buff *skb); 95 int (*poll)(struct iss_net_private *lp); 96 } tp; 97 98 }; 99 100 /* ================================ HELPERS ================================ */ 101 102 103 static char *split_if_spec(char *str, ...) 104 { 105 char **arg, *end; 106 va_list ap; 107 108 va_start(ap, str); 109 while ((arg = va_arg(ap, char**)) != NULL) { 110 if (*str == '\0') { 111 va_end(ap); 112 return NULL; 113 } 114 end = strchr(str, ','); 115 if (end != str) 116 *arg = str; 117 if (end == NULL) { 118 va_end(ap); 119 return NULL; 120 } 121 *end++ = '\0'; 122 str = end; 123 } 124 va_end(ap); 125 return str; 126 } 127 128 /* Set Ethernet address of the specified device. */ 129 130 static void setup_etheraddr(struct net_device *dev, char *str) 131 { 132 unsigned char *addr = dev->dev_addr; 133 134 if (str == NULL) 135 goto random; 136 137 if (!mac_pton(str, addr)) { 138 pr_err("%s: failed to parse '%s' as an ethernet address\n", 139 dev->name, str); 140 goto random; 141 } 142 if (is_multicast_ether_addr(addr)) { 143 pr_err("%s: attempt to assign a multicast ethernet address\n", 144 dev->name); 145 goto random; 146 } 147 if (!is_valid_ether_addr(addr)) { 148 pr_err("%s: attempt to assign an invalid ethernet address\n", 149 dev->name); 150 goto random; 151 } 152 if (!is_local_ether_addr(addr)) 153 pr_warn("%s: assigning a globally valid ethernet address\n", 154 dev->name); 155 return; 156 157 random: 158 pr_info("%s: choosing a random ethernet address\n", 159 dev->name); 160 eth_hw_addr_random(dev); 161 } 162 163 /* ======================= TUNTAP TRANSPORT INTERFACE ====================== */ 164 165 static int tuntap_open(struct iss_net_private *lp) 166 { 167 struct ifreq ifr; 168 char *dev_name = lp->tp.info.tuntap.dev_name; 169 int err = -EINVAL; 170 int fd; 171 172 fd = simc_open("/dev/net/tun", 02, 0); /* O_RDWR */ 173 if (fd < 0) { 174 pr_err("%s: failed to open /dev/net/tun, returned %d (errno = %d)\n", 175 lp->dev->name, fd, errno); 176 return fd; 177 } 178 179 memset(&ifr, 0, sizeof(ifr)); 180 ifr.ifr_flags = IFF_TAP | IFF_NO_PI; 181 strlcpy(ifr.ifr_name, dev_name, sizeof(ifr.ifr_name)); 182 183 err = simc_ioctl(fd, TUNSETIFF, &ifr); 184 if (err < 0) { 185 pr_err("%s: failed to set interface %s, returned %d (errno = %d)\n", 186 lp->dev->name, dev_name, err, errno); 187 simc_close(fd); 188 return err; 189 } 190 191 lp->tp.info.tuntap.fd = fd; 192 return err; 193 } 194 195 static void tuntap_close(struct iss_net_private *lp) 196 { 197 simc_close(lp->tp.info.tuntap.fd); 198 lp->tp.info.tuntap.fd = -1; 199 } 200 201 static int tuntap_read(struct iss_net_private *lp, struct sk_buff **skb) 202 { 203 return simc_read(lp->tp.info.tuntap.fd, 204 (*skb)->data, (*skb)->dev->mtu + ETH_HEADER_OTHER); 205 } 206 207 static int tuntap_write(struct iss_net_private *lp, struct sk_buff **skb) 208 { 209 return simc_write(lp->tp.info.tuntap.fd, (*skb)->data, (*skb)->len); 210 } 211 212 unsigned short tuntap_protocol(struct sk_buff *skb) 213 { 214 return eth_type_trans(skb, skb->dev); 215 } 216 217 static int tuntap_poll(struct iss_net_private *lp) 218 { 219 return simc_poll(lp->tp.info.tuntap.fd); 220 } 221 222 /* 223 * ethX=tuntap,[mac address],device name 224 */ 225 226 static int tuntap_probe(struct iss_net_private *lp, int index, char *init) 227 { 228 struct net_device *dev = lp->dev; 229 char *dev_name = NULL, *mac_str = NULL, *rem = NULL; 230 231 /* Transport should be 'tuntap': ethX=tuntap,mac,dev_name */ 232 233 if (strncmp(init, TRANSPORT_TUNTAP_NAME, 234 sizeof(TRANSPORT_TUNTAP_NAME) - 1)) 235 return 0; 236 237 init += sizeof(TRANSPORT_TUNTAP_NAME) - 1; 238 if (*init == ',') { 239 rem = split_if_spec(init + 1, &mac_str, &dev_name); 240 if (rem != NULL) { 241 pr_err("%s: extra garbage on specification : '%s'\n", 242 dev->name, rem); 243 return 0; 244 } 245 } else if (*init != '\0') { 246 pr_err("%s: invalid argument: %s. Skipping device!\n", 247 dev->name, init); 248 return 0; 249 } 250 251 if (!dev_name) { 252 pr_err("%s: missing tuntap device name\n", dev->name); 253 return 0; 254 } 255 256 strlcpy(lp->tp.info.tuntap.dev_name, dev_name, 257 sizeof(lp->tp.info.tuntap.dev_name)); 258 259 setup_etheraddr(dev, mac_str); 260 261 lp->mtu = TRANSPORT_TUNTAP_MTU; 262 263 lp->tp.info.tuntap.fd = -1; 264 265 lp->tp.open = tuntap_open; 266 lp->tp.close = tuntap_close; 267 lp->tp.read = tuntap_read; 268 lp->tp.write = tuntap_write; 269 lp->tp.protocol = tuntap_protocol; 270 lp->tp.poll = tuntap_poll; 271 272 return 1; 273 } 274 275 /* ================================ ISS NET ================================ */ 276 277 static int iss_net_rx(struct net_device *dev) 278 { 279 struct iss_net_private *lp = netdev_priv(dev); 280 int pkt_len; 281 struct sk_buff *skb; 282 283 /* Check if there is any new data. */ 284 285 if (lp->tp.poll(lp) == 0) 286 return 0; 287 288 /* Try to allocate memory, if it fails, try again next round. */ 289 290 skb = dev_alloc_skb(dev->mtu + 2 + ETH_HEADER_OTHER); 291 if (skb == NULL) { 292 lp->stats.rx_dropped++; 293 return 0; 294 } 295 296 skb_reserve(skb, 2); 297 298 /* Setup skb */ 299 300 skb->dev = dev; 301 skb_reset_mac_header(skb); 302 pkt_len = lp->tp.read(lp, &skb); 303 skb_put(skb, pkt_len); 304 305 if (pkt_len > 0) { 306 skb_trim(skb, pkt_len); 307 skb->protocol = lp->tp.protocol(skb); 308 309 lp->stats.rx_bytes += skb->len; 310 lp->stats.rx_packets++; 311 netif_rx_ni(skb); 312 return pkt_len; 313 } 314 kfree_skb(skb); 315 return pkt_len; 316 } 317 318 static int iss_net_poll(void) 319 { 320 struct list_head *ele; 321 int err, ret = 0; 322 323 spin_lock(&opened_lock); 324 325 list_for_each(ele, &opened) { 326 struct iss_net_private *lp; 327 328 lp = list_entry(ele, struct iss_net_private, opened_list); 329 330 if (!netif_running(lp->dev)) 331 break; 332 333 spin_lock(&lp->lock); 334 335 while ((err = iss_net_rx(lp->dev)) > 0) 336 ret++; 337 338 spin_unlock(&lp->lock); 339 340 if (err < 0) { 341 pr_err("Device '%s' read returned %d, shutting it down\n", 342 lp->dev->name, err); 343 dev_close(lp->dev); 344 } else { 345 /* FIXME reactivate_fd(lp->fd, ISS_ETH_IRQ); */ 346 } 347 } 348 349 spin_unlock(&opened_lock); 350 return ret; 351 } 352 353 354 static void iss_net_timer(struct timer_list *t) 355 { 356 struct iss_net_private *lp = from_timer(lp, t, timer); 357 358 iss_net_poll(); 359 spin_lock(&lp->lock); 360 mod_timer(&lp->timer, jiffies + lp->timer_val); 361 spin_unlock(&lp->lock); 362 } 363 364 365 static int iss_net_open(struct net_device *dev) 366 { 367 struct iss_net_private *lp = netdev_priv(dev); 368 int err; 369 370 spin_lock_bh(&lp->lock); 371 372 err = lp->tp.open(lp); 373 if (err < 0) 374 goto out; 375 376 netif_start_queue(dev); 377 378 /* clear buffer - it can happen that the host side of the interface 379 * is full when we get here. In this case, new data is never queued, 380 * SIGIOs never arrive, and the net never works. 381 */ 382 while ((err = iss_net_rx(dev)) > 0) 383 ; 384 385 spin_unlock_bh(&lp->lock); 386 spin_lock_bh(&opened_lock); 387 list_add(&lp->opened_list, &opened); 388 spin_unlock_bh(&opened_lock); 389 spin_lock_bh(&lp->lock); 390 391 timer_setup(&lp->timer, iss_net_timer, 0); 392 lp->timer_val = ISS_NET_TIMER_VALUE; 393 mod_timer(&lp->timer, jiffies + lp->timer_val); 394 395 out: 396 spin_unlock_bh(&lp->lock); 397 return err; 398 } 399 400 static int iss_net_close(struct net_device *dev) 401 { 402 struct iss_net_private *lp = netdev_priv(dev); 403 netif_stop_queue(dev); 404 spin_lock_bh(&lp->lock); 405 406 spin_lock(&opened_lock); 407 list_del(&opened); 408 spin_unlock(&opened_lock); 409 410 del_timer_sync(&lp->timer); 411 412 lp->tp.close(lp); 413 414 spin_unlock_bh(&lp->lock); 415 return 0; 416 } 417 418 static int iss_net_start_xmit(struct sk_buff *skb, struct net_device *dev) 419 { 420 struct iss_net_private *lp = netdev_priv(dev); 421 int len; 422 423 netif_stop_queue(dev); 424 spin_lock_bh(&lp->lock); 425 426 len = lp->tp.write(lp, &skb); 427 428 if (len == skb->len) { 429 lp->stats.tx_packets++; 430 lp->stats.tx_bytes += skb->len; 431 netif_trans_update(dev); 432 netif_start_queue(dev); 433 434 /* this is normally done in the interrupt when tx finishes */ 435 netif_wake_queue(dev); 436 437 } else if (len == 0) { 438 netif_start_queue(dev); 439 lp->stats.tx_dropped++; 440 441 } else { 442 netif_start_queue(dev); 443 pr_err("%s: %s failed(%d)\n", dev->name, __func__, len); 444 } 445 446 spin_unlock_bh(&lp->lock); 447 448 dev_kfree_skb(skb); 449 return NETDEV_TX_OK; 450 } 451 452 453 static struct net_device_stats *iss_net_get_stats(struct net_device *dev) 454 { 455 struct iss_net_private *lp = netdev_priv(dev); 456 return &lp->stats; 457 } 458 459 static void iss_net_set_multicast_list(struct net_device *dev) 460 { 461 } 462 463 static void iss_net_tx_timeout(struct net_device *dev) 464 { 465 } 466 467 static int iss_net_set_mac(struct net_device *dev, void *addr) 468 { 469 struct iss_net_private *lp = netdev_priv(dev); 470 struct sockaddr *hwaddr = addr; 471 472 if (!is_valid_ether_addr(hwaddr->sa_data)) 473 return -EADDRNOTAVAIL; 474 spin_lock_bh(&lp->lock); 475 memcpy(dev->dev_addr, hwaddr->sa_data, ETH_ALEN); 476 spin_unlock_bh(&lp->lock); 477 return 0; 478 } 479 480 static int iss_net_change_mtu(struct net_device *dev, int new_mtu) 481 { 482 return -EINVAL; 483 } 484 485 void iss_net_user_timer_expire(struct timer_list *unused) 486 { 487 } 488 489 490 static struct platform_driver iss_net_driver = { 491 .driver = { 492 .name = DRIVER_NAME, 493 }, 494 }; 495 496 static int driver_registered; 497 498 static const struct net_device_ops iss_netdev_ops = { 499 .ndo_open = iss_net_open, 500 .ndo_stop = iss_net_close, 501 .ndo_get_stats = iss_net_get_stats, 502 .ndo_start_xmit = iss_net_start_xmit, 503 .ndo_validate_addr = eth_validate_addr, 504 .ndo_change_mtu = iss_net_change_mtu, 505 .ndo_set_mac_address = iss_net_set_mac, 506 .ndo_tx_timeout = iss_net_tx_timeout, 507 .ndo_set_rx_mode = iss_net_set_multicast_list, 508 }; 509 510 static int iss_net_configure(int index, char *init) 511 { 512 struct net_device *dev; 513 struct iss_net_private *lp; 514 int err; 515 516 dev = alloc_etherdev(sizeof(*lp)); 517 if (dev == NULL) { 518 pr_err("eth_configure: failed to allocate device\n"); 519 return 1; 520 } 521 522 /* Initialize private element. */ 523 524 lp = netdev_priv(dev); 525 *lp = (struct iss_net_private) { 526 .device_list = LIST_HEAD_INIT(lp->device_list), 527 .opened_list = LIST_HEAD_INIT(lp->opened_list), 528 .dev = dev, 529 .index = index, 530 }; 531 532 spin_lock_init(&lp->lock); 533 /* 534 * If this name ends up conflicting with an existing registered 535 * netdevice, that is OK, register_netdev{,ice}() will notice this 536 * and fail. 537 */ 538 snprintf(dev->name, sizeof(dev->name), "eth%d", index); 539 540 /* 541 * Try all transport protocols. 542 * Note: more protocols can be added by adding '&& !X_init(lp, eth)'. 543 */ 544 545 if (!tuntap_probe(lp, index, init)) { 546 pr_err("%s: invalid arguments. Skipping device!\n", 547 dev->name); 548 goto errout; 549 } 550 551 pr_info("Netdevice %d (%pM)\n", index, dev->dev_addr); 552 553 /* sysfs register */ 554 555 if (!driver_registered) { 556 platform_driver_register(&iss_net_driver); 557 driver_registered = 1; 558 } 559 560 spin_lock(&devices_lock); 561 list_add(&lp->device_list, &devices); 562 spin_unlock(&devices_lock); 563 564 lp->pdev.id = index; 565 lp->pdev.name = DRIVER_NAME; 566 platform_device_register(&lp->pdev); 567 SET_NETDEV_DEV(dev, &lp->pdev.dev); 568 569 dev->netdev_ops = &iss_netdev_ops; 570 dev->mtu = lp->mtu; 571 dev->watchdog_timeo = (HZ >> 1); 572 dev->irq = -1; 573 574 rtnl_lock(); 575 err = register_netdevice(dev); 576 rtnl_unlock(); 577 578 if (err) { 579 pr_err("%s: error registering net device!\n", dev->name); 580 /* XXX: should we call ->remove() here? */ 581 free_netdev(dev); 582 return 1; 583 } 584 585 timer_setup(&lp->tl, iss_net_user_timer_expire, 0); 586 587 return 0; 588 589 errout: 590 /* FIXME: unregister; free, etc.. */ 591 return -EIO; 592 } 593 594 /* ------------------------------------------------------------------------- */ 595 596 /* Filled in during early boot */ 597 598 struct list_head eth_cmd_line = LIST_HEAD_INIT(eth_cmd_line); 599 600 struct iss_net_init { 601 struct list_head list; 602 char *init; /* init string */ 603 int index; 604 }; 605 606 /* 607 * Parse the command line and look for 'ethX=...' fields, and register all 608 * those fields. They will be later initialized in iss_net_init. 609 */ 610 611 static int __init iss_net_setup(char *str) 612 { 613 struct iss_net_private *device = NULL; 614 struct iss_net_init *new; 615 struct list_head *ele; 616 char *end; 617 int rc; 618 unsigned n; 619 620 end = strchr(str, '='); 621 if (!end) { 622 pr_err("Expected '=' after device number\n"); 623 return 1; 624 } 625 *end = 0; 626 rc = kstrtouint(str, 0, &n); 627 *end = '='; 628 if (rc < 0) { 629 pr_err("Failed to parse '%s'\n", str); 630 return 1; 631 } 632 str = end; 633 634 spin_lock(&devices_lock); 635 636 list_for_each(ele, &devices) { 637 device = list_entry(ele, struct iss_net_private, device_list); 638 if (device->index == n) 639 break; 640 } 641 642 spin_unlock(&devices_lock); 643 644 if (device && device->index == n) { 645 pr_err("Device %u already configured\n", n); 646 return 1; 647 } 648 649 new = alloc_bootmem(sizeof(*new)); 650 if (new == NULL) { 651 pr_err("Alloc_bootmem failed\n"); 652 return 1; 653 } 654 655 INIT_LIST_HEAD(&new->list); 656 new->index = n; 657 new->init = str + 1; 658 659 list_add_tail(&new->list, ð_cmd_line); 660 return 1; 661 } 662 663 __setup("eth", iss_net_setup); 664 665 /* 666 * Initialize all ISS Ethernet devices previously registered in iss_net_setup. 667 */ 668 669 static int iss_net_init(void) 670 { 671 struct list_head *ele, *next; 672 673 /* Walk through all Ethernet devices specified in the command line. */ 674 675 list_for_each_safe(ele, next, ð_cmd_line) { 676 struct iss_net_init *eth; 677 eth = list_entry(ele, struct iss_net_init, list); 678 iss_net_configure(eth->index, eth->init); 679 } 680 681 return 1; 682 } 683 device_initcall(iss_net_init); 684