diff options
Diffstat (limited to 'drivers/net/dummy.c')
| -rw-r--r-- | drivers/net/dummy.c | 46 |
1 files changed, 26 insertions, 20 deletions
diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index 087648ea1ed..0932ffbf381 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -40,17 +40,6 @@ static int numdummies = 1; -static int dummy_set_address(struct net_device *dev, void *p) -{ - struct sockaddr *sa = p; - - if (!is_valid_ether_addr(sa->sa_data)) - return -EADDRNOTAVAIL; - - memcpy(dev->dev_addr, sa->sa_data, ETH_ALEN); - return 0; -} - /* fake multicast ability */ static void set_multicast_list(struct net_device *dev) { @@ -74,10 +63,10 @@ static struct rtnl_link_stats64 *dummy_get_stats64(struct net_device *dev, dstats = per_cpu_ptr(dev->dstats, i); do { - start = u64_stats_fetch_begin(&dstats->syncp); + start = u64_stats_fetch_begin_irq(&dstats->syncp); tbytes = dstats->tx_bytes; tpackets = dstats->tx_packets; - } while (u64_stats_fetch_retry(&dstats->syncp, start)); + } while (u64_stats_fetch_retry_irq(&dstats->syncp, start)); stats->tx_bytes += tbytes; stats->tx_packets += tpackets; } @@ -99,26 +88,36 @@ static netdev_tx_t dummy_xmit(struct sk_buff *skb, struct net_device *dev) static int dummy_dev_init(struct net_device *dev) { - dev->dstats = alloc_percpu(struct pcpu_dstats); + dev->dstats = netdev_alloc_pcpu_stats(struct pcpu_dstats); if (!dev->dstats) return -ENOMEM; return 0; } -static void dummy_dev_free(struct net_device *dev) +static void dummy_dev_uninit(struct net_device *dev) { free_percpu(dev->dstats); - free_netdev(dev); +} + +static int dummy_change_carrier(struct net_device *dev, bool new_carrier) +{ + if (new_carrier) + netif_carrier_on(dev); + else + netif_carrier_off(dev); + return 0; } static const struct net_device_ops dummy_netdev_ops = { .ndo_init = dummy_dev_init, + .ndo_uninit = dummy_dev_uninit, .ndo_start_xmit = dummy_xmit, .ndo_validate_addr = eth_validate_addr, .ndo_set_rx_mode = set_multicast_list, - .ndo_set_mac_address = dummy_set_address, + .ndo_set_mac_address = eth_mac_addr, .ndo_get_stats64 = dummy_get_stats64, + .ndo_change_carrier = dummy_change_carrier, }; static void dummy_setup(struct net_device *dev) @@ -127,15 +126,16 @@ static void dummy_setup(struct net_device *dev) /* Initialize the device structure. */ dev->netdev_ops = &dummy_netdev_ops; - dev->destructor = dummy_dev_free; + dev->destructor = free_netdev; /* Fill in device structure with ethernet-generic values. */ dev->tx_queue_len = 0; dev->flags |= IFF_NOARP; dev->flags &= ~IFF_MULTICAST; + dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; dev->features |= NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO; dev->features |= NETIF_F_HW_CSUM | NETIF_F_HIGHDMA | NETIF_F_LLTX; - random_ether_addr(dev->dev_addr); + eth_hw_addr_random(dev); } static int dummy_validate(struct nlattr *tb[], struct nlattr *data[]) @@ -185,11 +185,17 @@ static int __init dummy_init_module(void) rtnl_lock(); err = __rtnl_link_register(&dummy_link_ops); + if (err < 0) + goto out; - for (i = 0; i < numdummies && !err; i++) + for (i = 0; i < numdummies && !err; i++) { err = dummy_init_one(); + cond_resched(); + } if (err < 0) __rtnl_link_unregister(&dummy_link_ops); + +out: rtnl_unlock(); return err; |
