| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * |
|---|
| 3 | 4 | * arch/xtensa/platforms/iss/network.c |
|---|
| .. | .. |
|---|
| 8 | 9 | * Based on work form the UML team. |
|---|
| 9 | 10 | * |
|---|
| 10 | 11 | * 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 | 12 | */ |
|---|
| 18 | 13 | |
|---|
| 19 | 14 | #define pr_fmt(fmt) "%s: " fmt, __func__ |
|---|
| .. | .. |
|---|
| 30 | 25 | #include <linux/etherdevice.h> |
|---|
| 31 | 26 | #include <linux/interrupt.h> |
|---|
| 32 | 27 | #include <linux/ioctl.h> |
|---|
| 33 | | -#include <linux/bootmem.h> |
|---|
| 28 | +#include <linux/memblock.h> |
|---|
| 34 | 29 | #include <linux/ethtool.h> |
|---|
| 35 | 30 | #include <linux/rtnetlink.h> |
|---|
| 36 | 31 | #include <linux/platform_device.h> |
|---|
| .. | .. |
|---|
| 209 | 204 | return simc_write(lp->tp.info.tuntap.fd, (*skb)->data, (*skb)->len); |
|---|
| 210 | 205 | } |
|---|
| 211 | 206 | |
|---|
| 212 | | -unsigned short tuntap_protocol(struct sk_buff *skb) |
|---|
| 207 | +static unsigned short tuntap_protocol(struct sk_buff *skb) |
|---|
| 213 | 208 | { |
|---|
| 214 | 209 | return eth_type_trans(skb, skb->dev); |
|---|
| 215 | 210 | } |
|---|
| .. | .. |
|---|
| 236 | 231 | |
|---|
| 237 | 232 | init += sizeof(TRANSPORT_TUNTAP_NAME) - 1; |
|---|
| 238 | 233 | if (*init == ',') { |
|---|
| 239 | | - rem = split_if_spec(init + 1, &mac_str, &dev_name); |
|---|
| 234 | + rem = split_if_spec(init + 1, &mac_str, &dev_name, NULL); |
|---|
| 240 | 235 | if (rem != NULL) { |
|---|
| 241 | 236 | pr_err("%s: extra garbage on specification : '%s'\n", |
|---|
| 242 | 237 | dev->name, rem); |
|---|
| .. | .. |
|---|
| 460 | 455 | { |
|---|
| 461 | 456 | } |
|---|
| 462 | 457 | |
|---|
| 463 | | -static void iss_net_tx_timeout(struct net_device *dev) |
|---|
| 458 | +static void iss_net_tx_timeout(struct net_device *dev, unsigned int txqueue) |
|---|
| 464 | 459 | { |
|---|
| 465 | 460 | } |
|---|
| 466 | 461 | |
|---|
| .. | .. |
|---|
| 482 | 477 | return -EINVAL; |
|---|
| 483 | 478 | } |
|---|
| 484 | 479 | |
|---|
| 485 | | -void iss_net_user_timer_expire(struct timer_list *unused) |
|---|
| 480 | +static void iss_net_user_timer_expire(struct timer_list *unused) |
|---|
| 486 | 481 | { |
|---|
| 487 | 482 | } |
|---|
| 488 | 483 | |
|---|
| .. | .. |
|---|
| 507 | 502 | .ndo_set_rx_mode = iss_net_set_multicast_list, |
|---|
| 508 | 503 | }; |
|---|
| 509 | 504 | |
|---|
| 510 | | -static int iss_net_configure(int index, char *init) |
|---|
| 505 | +static void iss_net_pdev_release(struct device *dev) |
|---|
| 506 | +{ |
|---|
| 507 | + struct platform_device *pdev = to_platform_device(dev); |
|---|
| 508 | + struct iss_net_private *lp = |
|---|
| 509 | + container_of(pdev, struct iss_net_private, pdev); |
|---|
| 510 | + |
|---|
| 511 | + free_netdev(lp->dev); |
|---|
| 512 | +} |
|---|
| 513 | + |
|---|
| 514 | +static void iss_net_configure(int index, char *init) |
|---|
| 511 | 515 | { |
|---|
| 512 | 516 | struct net_device *dev; |
|---|
| 513 | 517 | struct iss_net_private *lp; |
|---|
| 514 | | - int err; |
|---|
| 515 | 518 | |
|---|
| 516 | 519 | dev = alloc_etherdev(sizeof(*lp)); |
|---|
| 517 | 520 | if (dev == NULL) { |
|---|
| 518 | 521 | pr_err("eth_configure: failed to allocate device\n"); |
|---|
| 519 | | - return 1; |
|---|
| 522 | + return; |
|---|
| 520 | 523 | } |
|---|
| 521 | 524 | |
|---|
| 522 | 525 | /* Initialize private element. */ |
|---|
| .. | .. |
|---|
| 545 | 548 | if (!tuntap_probe(lp, index, init)) { |
|---|
| 546 | 549 | pr_err("%s: invalid arguments. Skipping device!\n", |
|---|
| 547 | 550 | dev->name); |
|---|
| 548 | | - goto errout; |
|---|
| 551 | + goto err_free_netdev; |
|---|
| 549 | 552 | } |
|---|
| 550 | 553 | |
|---|
| 551 | 554 | pr_info("Netdevice %d (%pM)\n", index, dev->dev_addr); |
|---|
| .. | .. |
|---|
| 553 | 556 | /* sysfs register */ |
|---|
| 554 | 557 | |
|---|
| 555 | 558 | if (!driver_registered) { |
|---|
| 556 | | - platform_driver_register(&iss_net_driver); |
|---|
| 559 | + if (platform_driver_register(&iss_net_driver)) |
|---|
| 560 | + goto err_free_netdev; |
|---|
| 557 | 561 | driver_registered = 1; |
|---|
| 558 | 562 | } |
|---|
| 559 | 563 | |
|---|
| .. | .. |
|---|
| 563 | 567 | |
|---|
| 564 | 568 | lp->pdev.id = index; |
|---|
| 565 | 569 | lp->pdev.name = DRIVER_NAME; |
|---|
| 566 | | - platform_device_register(&lp->pdev); |
|---|
| 570 | + lp->pdev.dev.release = iss_net_pdev_release; |
|---|
| 571 | + if (platform_device_register(&lp->pdev)) |
|---|
| 572 | + goto err_free_netdev; |
|---|
| 567 | 573 | SET_NETDEV_DEV(dev, &lp->pdev.dev); |
|---|
| 568 | 574 | |
|---|
| 569 | 575 | dev->netdev_ops = &iss_netdev_ops; |
|---|
| .. | .. |
|---|
| 572 | 578 | dev->irq = -1; |
|---|
| 573 | 579 | |
|---|
| 574 | 580 | rtnl_lock(); |
|---|
| 575 | | - err = register_netdevice(dev); |
|---|
| 576 | | - rtnl_unlock(); |
|---|
| 577 | | - |
|---|
| 578 | | - if (err) { |
|---|
| 581 | + if (register_netdevice(dev)) { |
|---|
| 582 | + rtnl_unlock(); |
|---|
| 579 | 583 | pr_err("%s: error registering net device!\n", dev->name); |
|---|
| 580 | | - /* XXX: should we call ->remove() here? */ |
|---|
| 581 | | - free_netdev(dev); |
|---|
| 582 | | - return 1; |
|---|
| 584 | + platform_device_unregister(&lp->pdev); |
|---|
| 585 | + return; |
|---|
| 583 | 586 | } |
|---|
| 587 | + rtnl_unlock(); |
|---|
| 584 | 588 | |
|---|
| 585 | 589 | timer_setup(&lp->tl, iss_net_user_timer_expire, 0); |
|---|
| 586 | 590 | |
|---|
| 587 | | - return 0; |
|---|
| 591 | + return; |
|---|
| 588 | 592 | |
|---|
| 589 | | -errout: |
|---|
| 590 | | - /* FIXME: unregister; free, etc.. */ |
|---|
| 591 | | - return -EIO; |
|---|
| 593 | +err_free_netdev: |
|---|
| 594 | + free_netdev(dev); |
|---|
| 592 | 595 | } |
|---|
| 593 | 596 | |
|---|
| 594 | 597 | /* ------------------------------------------------------------------------- */ |
|---|
| .. | .. |
|---|
| 646 | 649 | return 1; |
|---|
| 647 | 650 | } |
|---|
| 648 | 651 | |
|---|
| 649 | | - new = alloc_bootmem(sizeof(*new)); |
|---|
| 652 | + new = memblock_alloc(sizeof(*new), SMP_CACHE_BYTES); |
|---|
| 650 | 653 | if (new == NULL) { |
|---|
| 651 | 654 | pr_err("Alloc_bootmem failed\n"); |
|---|
| 652 | 655 | return 1; |
|---|