From 99ffc3e74fb0d9d321d2f19c6021e0dbaff2f4b2 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 13 Jun 2013 10:07:29 +0300 Subject: macvlan: don't touch promisc without passthrough commit df8ef8f3aaa6692970a436204c4429210addb23a "macvlan: add FDB bridge ops and macvlan flags" added a way to control NOPROMISC macvlan flag through netlink. However, with a non passthrough device we never set promisc on open, even if NOPROMISC is off. As a result: If userspace clears NOPROMISC on open, then does not clear it on a netlink command, promisc counter is not decremented on stop and there will be no way to clear it once macvlan is detached. If userspace does not clear NOPROMISC on open, then sets NOPROMISC on a netlink command, promisc counter will be decremented from 0 and overflow to fffffffff with no way to clear promisc. To fix, simply ignore NOPROMISC flag in a netlink command for non-passthrough devices, same as we do at open/close. Since we touch this code anyway - check dev_set_promiscuity return code and pass it to users (though an error here is unlikely). Cc: "David S. Miller" Reviewed-by: John Fastabend Signed-off-by: Michael S. Tsirkin Signed-off-by: David S. Miller --- drivers/net/macvlan.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 1c502bb0c916..6e91931a1c2c 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -853,18 +853,24 @@ static int macvlan_changelink(struct net_device *dev, struct nlattr *tb[], struct nlattr *data[]) { struct macvlan_dev *vlan = netdev_priv(dev); - if (data && data[IFLA_MACVLAN_MODE]) - vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]); + if (data && data[IFLA_MACVLAN_FLAGS]) { __u16 flags = nla_get_u16(data[IFLA_MACVLAN_FLAGS]); bool promisc = (flags ^ vlan->flags) & MACVLAN_FLAG_NOPROMISC; - - if (promisc && (flags & MACVLAN_FLAG_NOPROMISC)) - dev_set_promiscuity(vlan->lowerdev, -1); - else if (promisc && !(flags & MACVLAN_FLAG_NOPROMISC)) - dev_set_promiscuity(vlan->lowerdev, 1); + if (vlan->port->passthru && promisc) { + int err; + + if (flags & MACVLAN_FLAG_NOPROMISC) + err = dev_set_promiscuity(vlan->lowerdev, -1); + else + err = dev_set_promiscuity(vlan->lowerdev, 1); + if (err < 0) + return err; + } vlan->flags = flags; } + if (data && data[IFLA_MACVLAN_MODE]) + vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]); return 0; } -- cgit v1.2.3 From 94f950c4060cd9b1989c565284beb159b9705a50 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Tue, 11 Jun 2013 11:00:34 +0100 Subject: xen-netback: don't de-reference vif pointer after having called xenvif_put() When putting vif-s on the rx notify list, calling xenvif_put() must be deferred until after the removal from the list and the issuing of the notification, as both operations dereference the pointer. Changing this got me to notice that the "irq" variable was effectively unused (and was of too narrow type anyway). Signed-off-by: Jan Beulich Acked-by: Ian Campbell Signed-off-by: David S. Miller --- drivers/net/xen-netback/netback.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 37984e6d4e99..8c20935d72c9 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -662,7 +662,7 @@ static void xen_netbk_rx_action(struct xen_netbk *netbk) { struct xenvif *vif = NULL, *tmp; s8 status; - u16 irq, flags; + u16 flags; struct xen_netif_rx_response *resp; struct sk_buff_head rxq; struct sk_buff *skb; @@ -771,13 +771,13 @@ static void xen_netbk_rx_action(struct xen_netbk *netbk) sco->meta_slots_used); RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&vif->rx, ret); - irq = vif->irq; - if (ret && list_empty(&vif->notify_list)) - list_add_tail(&vif->notify_list, ¬ify); xenvif_notify_tx_completion(vif); - xenvif_put(vif); + if (ret && list_empty(&vif->notify_list)) + list_add_tail(&vif->notify_list, ¬ify); + else + xenvif_put(vif); npo.meta_cons += sco->meta_slots_used; dev_kfree_skb(skb); } @@ -785,6 +785,7 @@ static void xen_netbk_rx_action(struct xen_netbk *netbk) list_for_each_entry_safe(vif, tmp, ¬ify, notify_list) { notify_remote_via_irq(vif->irq); list_del_init(&vif->notify_list); + xenvif_put(vif); } /* More work to do? */ -- cgit v1.2.3 From 0c5fed09ab0feedd43c362b1c7fff67fdbf9548f Mon Sep 17 00:00:00 2001 From: Somnath Kotur Date: Tue, 11 Jun 2013 17:18:22 +0530 Subject: be2net: Fix 32-bit DMA Mask handling Fix to set the coherent DMA mask only if dma_set_mask() succeeded, and to error out if either fails. Signed-off-by: Somnath Kotur Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_main.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 8bc1b21b1c79..a0b4be51f0d1 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -4262,6 +4262,9 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id) netdev->features |= NETIF_F_HIGHDMA; } else { status = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); + if (!status) + status = dma_set_coherent_mask(&pdev->dev, + DMA_BIT_MASK(32)); if (status) { dev_err(&pdev->dev, "Could not set PCI DMA Mask\n"); goto free_netdev; -- cgit v1.2.3 From 631f24a2febb228f82604dc5330091e8080cd8ae Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Wed, 12 Jun 2013 11:05:03 -0500 Subject: net: ethernet: stmicro: stmmac: Fix compile error when STMMAC_XMIT_DEBUG used drivers/net/ethernet/stmicro/stmmac/stmmac_main.c: In function: stmmac_xmit drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:1902:74: error: expected ) before __func__ Signed-off-by: Dinh Nguyen Cc: Giuseppe Cavallaro CC: David S. Miller Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 618446ae1ec1..ee919ca8b8a0 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1899,7 +1899,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) #ifdef STMMAC_XMIT_DEBUG if (netif_msg_pktdata(priv)) { - pr_info("%s: curr %d dirty=%d entry=%d, first=%p, nfrags=%d" + pr_info("%s: curr %d dirty=%d entry=%d, first=%p, nfrags=%d", __func__, (priv->cur_tx % txsize), (priv->dirty_tx % txsize), entry, first, nfrags); if (priv->extend_desc) -- cgit v1.2.3 From b8fad459f9cc8417b74f71c6c229eef7412163d1 Mon Sep 17 00:00:00 2001 From: Nikolay Aleksandrov Date: Wed, 12 Jun 2013 00:07:01 +0200 Subject: bonding: reset master mac on first enslave failure If the bond device is supposed to get the first slave's MAC address and the first enslavement fails then we need to reset the master's MAC otherwise it will stay the same as the failed slave device. We do it after err_undo_flags since that is the first place where the MAC can be changed and we check if it should've been the first slave and if the bond's MAC was set to it because that err place is used by multiple locations prior to changing the master's MAC address. Signed-off-by: Nikolay Aleksandrov Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 29b846cbfb48..473633ab5f56 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1957,6 +1957,10 @@ err_free: err_undo_flags: bond_compute_features(bond); + /* Enslave of first slave has failed and we need to fix master's mac */ + if (bond->slave_cnt == 0 && + ether_addr_equal(bond_dev->dev_addr, slave_dev->dev_addr)) + eth_hw_addr_random(bond_dev); return res; } -- cgit v1.2.3 From 4f5474e7fd68988cb11373fc698bf10b35b49e31 Mon Sep 17 00:00:00 2001 From: Nikolay Aleksandrov Date: Wed, 12 Jun 2013 00:07:02 +0200 Subject: bonding: fix igmp_retrans type and two related races First the type of igmp_retrans (which is the actual counter of igmp_resend parameter) is changed to u8 to be able to store values up to 255 (as per documentation). There are two races that were hidden there and which are easy to trigger after the previous fix, the first is between bond_resend_igmp_join_requests and bond_change_active_slave where igmp_retrans is set and can be altered by the periodic. The second race condition is between multiple running instances of the periodic (upon execution it can be scheduled again for immediate execution which can cause the counter to go < 0 which in the unsigned case leads to unnecessary igmp retransmissions). Since in bond_change_active_slave bond->lock is held for reading and curr_slave_lock for writing, we use curr_slave_lock for mutual exclusion. We can't drop them as there're cases where RTNL is not held when bond_change_active_slave is called. RCU is unlocked in bond_resend_igmp_join_requests before getting curr_slave_lock since we don't need it there and it's pointless to delay. The decrement is moved inside the "if" block because if we decrement unconditionally there's still a possibility for a race condition although it is much more difficult to hit (many changes have to happen in a very short period in order to trigger) which in the case of 3 parallel running instances of this function and igmp_retrans == 1 (with check bond->igmp_retrans-- > 1) is: f1 passes, doesn't re-schedule, but decrements - igmp_retrans = 0 f2 then passes, doesn't re-schedule, but decrements - igmp_retrans = 255 f3 does the unnecessary retransmissions. Signed-off-by: Nikolay Aleksandrov Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 15 +++++++++++---- drivers/net/bonding/bonding.h | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 473633ab5f56..02d9ae7d527e 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -764,8 +764,8 @@ static void bond_resend_igmp_join_requests(struct bonding *bond) struct net_device *bond_dev, *vlan_dev, *upper_dev; struct vlan_entry *vlan; - rcu_read_lock(); read_lock(&bond->lock); + rcu_read_lock(); bond_dev = bond->dev; @@ -787,12 +787,19 @@ static void bond_resend_igmp_join_requests(struct bonding *bond) if (vlan_dev) __bond_resend_igmp_join_requests(vlan_dev); } + rcu_read_unlock(); - if (--bond->igmp_retrans > 0) + /* We use curr_slave_lock to protect against concurrent access to + * igmp_retrans from multiple running instances of this function and + * bond_change_active_slave + */ + write_lock_bh(&bond->curr_slave_lock); + if (bond->igmp_retrans > 1) { + bond->igmp_retrans--; queue_delayed_work(bond->wq, &bond->mcast_work, HZ/5); - + } + write_unlock_bh(&bond->curr_slave_lock); read_unlock(&bond->lock); - rcu_read_unlock(); } static void bond_resend_igmp_join_requests_delayed(struct work_struct *work) diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 2baec24388b1..f989e1529a29 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -225,7 +225,7 @@ struct bonding { rwlock_t curr_slave_lock; u8 send_peer_notif; s8 setup_by_slave; - s8 igmp_retrans; + u8 igmp_retrans; #ifdef CONFIG_PROC_FS struct proc_dir_entry *proc_entry; char proc_file_name[IFNAMSIZ]; -- cgit v1.2.3 From df465abfe06f7dc4f33f4a96d17f096e9e8ac917 Mon Sep 17 00:00:00 2001 From: Nithin Sujir Date: Wed, 12 Jun 2013 11:08:59 -0700 Subject: tg3: Wait for boot code to finish after power on Some systems that don't need wake-on-lan may choose to power down the chip on system standby. Upon resume, the power on causes the boot code to startup and initialize the hardware. On one new platform, this is causing the device to go into a bad state due to a race between the driver and boot code, once every several hundred resumes. The same race exists on open since we come up from a power on. This patch adds a wait for boot code signature at the beginning of tg3_init_hw() which is common to both cases. If there has not been a power-off or the boot code has already completed, the signature will be present and poll_fw() returns immediately. Also return immediately if the device does not have firmware. Cc: stable@vger.kernel.org Signed-off-by: Nithin Nayak Sujir Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/tg3.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 0f493c8dc28b..c777b9013164 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -1800,6 +1800,9 @@ static int tg3_poll_fw(struct tg3 *tp) int i; u32 val; + if (tg3_flag(tp, NO_FWARE_REPORTED)) + return 0; + if (tg3_flag(tp, IS_SSB_CORE)) { /* We don't use firmware. */ return 0; @@ -10404,6 +10407,13 @@ static int tg3_reset_hw(struct tg3 *tp, bool reset_phy) */ static int tg3_init_hw(struct tg3 *tp, bool reset_phy) { + /* Chip may have been just powered on. If so, the boot code may still + * be running initialization. Wait for it to finish to avoid races in + * accessing the hardware. + */ + tg3_enable_register_access(tp); + tg3_poll_fw(tp); + tg3_switch_clocks(tp); tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0); -- cgit v1.2.3 From 5033ec3e3f923a371c28f0c3df45905a9dd9c457 Mon Sep 17 00:00:00 2001 From: Mugunthan V N Date: Tue, 11 Jun 2013 15:32:04 +0530 Subject: drivers: net: davinci_mdio: moving mdio resume earlier than cpsw ethernet driver MDIO driver should resume before CPSW ethernet driver so that CPSW connect to the phy and start tx/rx ethernet packets, changing the suspend/resume apis with suspend_late/resume_early. Signed-off-by: Mugunthan V N Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/davinci_mdio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c index b2275d1b19b3..74e56b3fba11 100644 --- a/drivers/net/ethernet/ti/davinci_mdio.c +++ b/drivers/net/ethernet/ti/davinci_mdio.c @@ -476,8 +476,8 @@ static int davinci_mdio_resume(struct device *dev) } static const struct dev_pm_ops davinci_mdio_pm_ops = { - .suspend = davinci_mdio_suspend, - .resume = davinci_mdio_resume, + .suspend_late = davinci_mdio_suspend, + .resume_early = davinci_mdio_resume, }; static const struct of_device_id davinci_mdio_of_mtable[] = { -- cgit v1.2.3 From cc60ab0a8b5b62ea6b5cc1c6397adb5b4bd41271 Mon Sep 17 00:00:00 2001 From: Mugunthan V N Date: Tue, 11 Jun 2013 15:32:05 +0530 Subject: drivers: net: davinci_mdio: restore mdio clk divider in mdio resume During suspend resume cycle all the register data is lost, so MDIO clock divier value gets reset. This patch restores the clock divider value. Signed-off-by: Mugunthan V N Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/davinci_mdio.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c index 74e56b3fba11..c47f0dbcebb5 100644 --- a/drivers/net/ethernet/ti/davinci_mdio.c +++ b/drivers/net/ethernet/ti/davinci_mdio.c @@ -459,15 +459,12 @@ static int davinci_mdio_suspend(struct device *dev) static int davinci_mdio_resume(struct device *dev) { struct davinci_mdio_data *data = dev_get_drvdata(dev); - u32 ctrl; pm_runtime_get_sync(data->dev); spin_lock(&data->lock); /* restart the scan state machine */ - ctrl = __raw_readl(&data->regs->control); - ctrl |= CONTROL_ENABLE; - __raw_writel(ctrl, &data->regs->control); + __davinci_mdio_reset(data); data->suspended = false; spin_unlock(&data->lock); -- cgit v1.2.3 From dd019897358b815f7828dab90b51d51df4d3658d Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Thu, 13 Jun 2013 10:15:45 +0900 Subject: net: sh_eth: fix incorrect RX length error if R8A7740 This patch fixes an issue that the driver increments the "RX length error" on every buffer in sh_eth_rx() if the R8A7740. This patch also adds a description about the Receive Frame Status bits. Signed-off-by: Yoshihiro Shimoda Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index b4479b5aaee4..5e3982fc5398 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1401,16 +1401,23 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status) desc_status = edmac_to_cpu(mdp, rxdesc->status); pkt_len = rxdesc->frame_length; -#if defined(CONFIG_ARCH_R8A7740) - desc_status >>= 16; -#endif - if (--boguscnt < 0) break; if (!(desc_status & RDFEND)) ndev->stats.rx_length_errors++; +#if defined(CONFIG_ARCH_R8A7740) + /* + * In case of almost all GETHER/ETHERs, the Receive Frame State + * (RFS) bits in the Receive Descriptor 0 are from bit 9 to + * bit 0. However, in case of the R8A7740's GETHER, the RFS + * bits are from bit 25 to bit 16. So, the driver needs right + * shifting by 16. + */ + desc_status >>= 16; +#endif + if (desc_status & (RD_RFS1 | RD_RFS2 | RD_RFS3 | RD_RFS4 | RD_RFS5 | RD_RFS6 | RD_RFS10)) { ndev->stats.rx_errors++; -- cgit v1.2.3 From c9bfbb31af7c8428267b34eb9706a621ac219a28 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Thu, 13 Jun 2013 15:31:28 -0400 Subject: tulip: Properly check dma mapping result Tulip throws an error when dma debugging is enabled, as it doesn't properly check dma mapping results with dma_mapping_error() durring tx ring refills. Easy fix, just add it in, and drop the frame if the mapping is bad Signed-off-by: Neil Horman CC: Grant Grundler CC: "David S. Miller" Reviewed-by: Grant Grundler Signed-off-by: David S. Miller --- drivers/net/ethernet/dec/tulip/interrupt.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/dec/tulip/interrupt.c b/drivers/net/ethernet/dec/tulip/interrupt.c index 28a5e425fecf..92306b320840 100644 --- a/drivers/net/ethernet/dec/tulip/interrupt.c +++ b/drivers/net/ethernet/dec/tulip/interrupt.c @@ -76,6 +76,12 @@ int tulip_refill_rx(struct net_device *dev) mapping = pci_map_single(tp->pdev, skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); + if (dma_mapping_error(&tp->pdev->dev, mapping)) { + dev_kfree_skb(skb); + tp->rx_buffers[entry].skb = NULL; + break; + } + tp->rx_buffers[entry].mapping = mapping; tp->rx_ring[entry].buffer1 = cpu_to_le32(mapping); -- cgit v1.2.3 From aaf9522d62d18626a60f7f2080671d853d9e8681 Mon Sep 17 00:00:00 2001 From: Benjamin Poirier Date: Thu, 13 Jun 2013 09:09:47 -0400 Subject: netiucv: Hold rtnl between name allocation and device registration. fixes a race condition between concurrent initializations of netiucv devices that try to use the same name. sysfs: cannot create duplicate filename '/devices/iucv/netiucv2' [...] Call Trace: ([<00000000002edea4>] sysfs_add_one+0xb0/0xdc) [<00000000002eecd4>] create_dir+0x80/0xfc [<00000000002eee38>] sysfs_create_dir+0xe8/0x118 [<00000000003835a8>] kobject_add_internal+0x120/0x2d0 [<00000000003839d6>] kobject_add+0x62/0x9c [<00000000003d9564>] device_add+0xcc/0x510 [<000003e00212c7b4>] netiucv_register_device+0xc0/0x1ec [netiucv] Signed-off-by: Benjamin Poirier Tested-by: Ursula Braun Signed-off-by: David S. Miller --- drivers/s390/net/netiucv.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index 4ffa66c87ea5..9ca3996f65b2 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c @@ -2040,6 +2040,7 @@ static struct net_device *netiucv_init_netdevice(char *username, char *userdata) netiucv_setup_netdevice); if (!dev) return NULL; + rtnl_lock(); if (dev_alloc_name(dev, dev->name) < 0) goto out_netdev; @@ -2061,6 +2062,7 @@ static struct net_device *netiucv_init_netdevice(char *username, char *userdata) out_fsm: kfree_fsm(privptr->fsm); out_netdev: + rtnl_unlock(); free_netdev(dev); return NULL; } @@ -2100,6 +2102,7 @@ static ssize_t conn_write(struct device_driver *drv, rc = netiucv_register_device(dev); if (rc) { + rtnl_unlock(); IUCV_DBF_TEXT_(setup, 2, "ret %d from netiucv_register_device\n", rc); goto out_free_ndev; @@ -2109,7 +2112,8 @@ static ssize_t conn_write(struct device_driver *drv, priv = netdev_priv(dev); SET_NETDEV_DEV(dev, priv->dev); - rc = register_netdev(dev); + rc = register_netdevice(dev); + rtnl_unlock(); if (rc) goto out_unreg; -- cgit v1.2.3