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