Commit e308a5d8 authored by David S. Miller's avatar David S. Miller

netdev: Add netdev->addr_list_lock protection.

Add netif_addr_{lock,unlock}{,_bh}() helpers.

Use them to protect operations that operate on or read
the network device unicast and multicast address lists.

Also use them in cases where the code simply wants to
block calls into the driver's ->set_rx_mode() and
->set_multicast_list() methods.
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f1f28aa3
...@@ -775,6 +775,7 @@ void ipoib_mcast_restart_task(struct work_struct *work) ...@@ -775,6 +775,7 @@ void ipoib_mcast_restart_task(struct work_struct *work)
local_irq_save(flags); local_irq_save(flags);
netif_tx_lock(dev); netif_tx_lock(dev);
netif_addr_lock(dev);
spin_lock(&priv->lock); spin_lock(&priv->lock);
/* /*
...@@ -851,6 +852,7 @@ void ipoib_mcast_restart_task(struct work_struct *work) ...@@ -851,6 +852,7 @@ void ipoib_mcast_restart_task(struct work_struct *work)
} }
spin_unlock(&priv->lock); spin_unlock(&priv->lock);
netif_addr_unlock(dev);
netif_tx_unlock(dev); netif_tx_unlock(dev);
local_irq_restore(flags); local_irq_restore(flags);
......
...@@ -1134,6 +1134,7 @@ static void wq_set_multicast_list (struct work_struct *work) ...@@ -1134,6 +1134,7 @@ static void wq_set_multicast_list (struct work_struct *work)
dvb_net_feed_stop(dev); dvb_net_feed_stop(dev);
priv->rx_mode = RX_MODE_UNI; priv->rx_mode = RX_MODE_UNI;
netif_tx_lock_bh(dev); netif_tx_lock_bh(dev);
netif_addr_lock(dev);
if (dev->flags & IFF_PROMISC) { if (dev->flags & IFF_PROMISC) {
dprintk("%s: promiscuous mode\n", dev->name); dprintk("%s: promiscuous mode\n", dev->name);
...@@ -1158,6 +1159,7 @@ static void wq_set_multicast_list (struct work_struct *work) ...@@ -1158,6 +1159,7 @@ static void wq_set_multicast_list (struct work_struct *work)
} }
} }
netif_addr_unlock(dev);
netif_tx_unlock_bh(dev); netif_tx_unlock_bh(dev);
dvb_net_feed_start(dev); dvb_net_feed_start(dev);
} }
......
...@@ -1568,10 +1568,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) ...@@ -1568,10 +1568,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
} }
netif_tx_lock_bh(bond_dev); netif_tx_lock_bh(bond_dev);
netif_addr_lock(bond_dev);
/* upload master's mc_list to new slave */ /* upload master's mc_list to new slave */
for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) { for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) {
dev_mc_add (slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0); dev_mc_add (slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
} }
netif_addr_unlock(bond_dev);
netif_tx_unlock_bh(bond_dev); netif_tx_unlock_bh(bond_dev);
} }
...@@ -1937,7 +1939,9 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) ...@@ -1937,7 +1939,9 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
/* flush master's mc_list from slave */ /* flush master's mc_list from slave */
netif_tx_lock_bh(bond_dev); netif_tx_lock_bh(bond_dev);
netif_addr_lock(bond_dev);
bond_mc_list_flush(bond_dev, slave_dev); bond_mc_list_flush(bond_dev, slave_dev);
netif_addr_unlock(bond_dev);
netif_tx_unlock_bh(bond_dev); netif_tx_unlock_bh(bond_dev);
} }
...@@ -2060,7 +2064,9 @@ static int bond_release_all(struct net_device *bond_dev) ...@@ -2060,7 +2064,9 @@ static int bond_release_all(struct net_device *bond_dev)
/* flush master's mc_list from slave */ /* flush master's mc_list from slave */
netif_tx_lock_bh(bond_dev); netif_tx_lock_bh(bond_dev);
netif_addr_lock(bond_dev);
bond_mc_list_flush(bond_dev, slave_dev); bond_mc_list_flush(bond_dev, slave_dev);
netif_addr_unlock(bond_dev);
netif_tx_unlock_bh(bond_dev); netif_tx_unlock_bh(bond_dev);
} }
...@@ -4674,7 +4680,9 @@ static void bond_free_all(void) ...@@ -4674,7 +4680,9 @@ static void bond_free_all(void)
bond_work_cancel_all(bond); bond_work_cancel_all(bond);
netif_tx_lock_bh(bond_dev); netif_tx_lock_bh(bond_dev);
netif_addr_lock(bond_dev);
bond_mc_list_destroy(bond); bond_mc_list_destroy(bond);
netif_addr_unlock(bond_dev);
netif_tx_unlock_bh(bond_dev); netif_tx_unlock_bh(bond_dev);
/* Release the bonded slaves */ /* Release the bonded slaves */
bond_release_all(bond_dev); bond_release_all(bond_dev);
......
...@@ -2831,6 +2831,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu) ...@@ -2831,6 +2831,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu)
*/ */
nv_disable_irq(dev); nv_disable_irq(dev);
netif_tx_lock_bh(dev); netif_tx_lock_bh(dev);
netif_addr_lock(dev);
spin_lock(&np->lock); spin_lock(&np->lock);
/* stop engines */ /* stop engines */
nv_stop_rxtx(dev); nv_stop_rxtx(dev);
...@@ -2855,6 +2856,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu) ...@@ -2855,6 +2856,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu)
/* restart rx engine */ /* restart rx engine */
nv_start_rxtx(dev); nv_start_rxtx(dev);
spin_unlock(&np->lock); spin_unlock(&np->lock);
netif_addr_unlock(dev);
netif_tx_unlock_bh(dev); netif_tx_unlock_bh(dev);
nv_enable_irq(dev); nv_enable_irq(dev);
} }
...@@ -2891,6 +2893,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr) ...@@ -2891,6 +2893,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr)
if (netif_running(dev)) { if (netif_running(dev)) {
netif_tx_lock_bh(dev); netif_tx_lock_bh(dev);
netif_addr_lock(dev);
spin_lock_irq(&np->lock); spin_lock_irq(&np->lock);
/* stop rx engine */ /* stop rx engine */
...@@ -2902,6 +2905,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr) ...@@ -2902,6 +2905,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr)
/* restart rx engine */ /* restart rx engine */
nv_start_rx(dev); nv_start_rx(dev);
spin_unlock_irq(&np->lock); spin_unlock_irq(&np->lock);
netif_addr_unlock(dev);
netif_tx_unlock_bh(dev); netif_tx_unlock_bh(dev);
} else { } else {
nv_copy_mac_to_hw(dev); nv_copy_mac_to_hw(dev);
...@@ -3971,6 +3975,7 @@ static void nv_do_nic_poll(unsigned long data) ...@@ -3971,6 +3975,7 @@ static void nv_do_nic_poll(unsigned long data)
printk(KERN_INFO "forcedeth: MAC in recoverable error state\n"); printk(KERN_INFO "forcedeth: MAC in recoverable error state\n");
if (netif_running(dev)) { if (netif_running(dev)) {
netif_tx_lock_bh(dev); netif_tx_lock_bh(dev);
netif_addr_lock(dev);
spin_lock(&np->lock); spin_lock(&np->lock);
/* stop engines */ /* stop engines */
nv_stop_rxtx(dev); nv_stop_rxtx(dev);
...@@ -3995,6 +4000,7 @@ static void nv_do_nic_poll(unsigned long data) ...@@ -3995,6 +4000,7 @@ static void nv_do_nic_poll(unsigned long data)
/* restart rx engine */ /* restart rx engine */
nv_start_rxtx(dev); nv_start_rxtx(dev);
spin_unlock(&np->lock); spin_unlock(&np->lock);
netif_addr_unlock(dev);
netif_tx_unlock_bh(dev); netif_tx_unlock_bh(dev);
} }
} }
...@@ -4202,6 +4208,7 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ...@@ -4202,6 +4208,7 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
nv_disable_irq(dev); nv_disable_irq(dev);
netif_tx_lock_bh(dev); netif_tx_lock_bh(dev);
netif_addr_lock(dev);
/* with plain spinlock lockdep complains */ /* with plain spinlock lockdep complains */
spin_lock_irqsave(&np->lock, flags); spin_lock_irqsave(&np->lock, flags);
/* stop engines */ /* stop engines */
...@@ -4215,6 +4222,7 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ...@@ -4215,6 +4222,7 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
*/ */
nv_stop_rxtx(dev); nv_stop_rxtx(dev);
spin_unlock_irqrestore(&np->lock, flags); spin_unlock_irqrestore(&np->lock, flags);
netif_addr_unlock(dev);
netif_tx_unlock_bh(dev); netif_tx_unlock_bh(dev);
} }
...@@ -4360,10 +4368,12 @@ static int nv_nway_reset(struct net_device *dev) ...@@ -4360,10 +4368,12 @@ static int nv_nway_reset(struct net_device *dev)
if (netif_running(dev)) { if (netif_running(dev)) {
nv_disable_irq(dev); nv_disable_irq(dev);
netif_tx_lock_bh(dev); netif_tx_lock_bh(dev);
netif_addr_lock(dev);
spin_lock(&np->lock); spin_lock(&np->lock);
/* stop engines */ /* stop engines */
nv_stop_rxtx(dev); nv_stop_rxtx(dev);
spin_unlock(&np->lock); spin_unlock(&np->lock);
netif_addr_unlock(dev);
netif_tx_unlock_bh(dev); netif_tx_unlock_bh(dev);
printk(KERN_INFO "%s: link down.\n", dev->name); printk(KERN_INFO "%s: link down.\n", dev->name);
} }
...@@ -4471,6 +4481,7 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri ...@@ -4471,6 +4481,7 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri
if (netif_running(dev)) { if (netif_running(dev)) {
nv_disable_irq(dev); nv_disable_irq(dev);
netif_tx_lock_bh(dev); netif_tx_lock_bh(dev);
netif_addr_lock(dev);
spin_lock(&np->lock); spin_lock(&np->lock);
/* stop engines */ /* stop engines */
nv_stop_rxtx(dev); nv_stop_rxtx(dev);
...@@ -4519,6 +4530,7 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri ...@@ -4519,6 +4530,7 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri
/* restart engines */ /* restart engines */
nv_start_rxtx(dev); nv_start_rxtx(dev);
spin_unlock(&np->lock); spin_unlock(&np->lock);
netif_addr_unlock(dev);
netif_tx_unlock_bh(dev); netif_tx_unlock_bh(dev);
nv_enable_irq(dev); nv_enable_irq(dev);
} }
...@@ -4556,10 +4568,12 @@ static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam* ...@@ -4556,10 +4568,12 @@ static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam*
if (netif_running(dev)) { if (netif_running(dev)) {
nv_disable_irq(dev); nv_disable_irq(dev);
netif_tx_lock_bh(dev); netif_tx_lock_bh(dev);
netif_addr_lock(dev);
spin_lock(&np->lock); spin_lock(&np->lock);
/* stop engines */ /* stop engines */
nv_stop_rxtx(dev); nv_stop_rxtx(dev);
spin_unlock(&np->lock); spin_unlock(&np->lock);
netif_addr_unlock(dev);
netif_tx_unlock_bh(dev); netif_tx_unlock_bh(dev);
} }
...@@ -4946,6 +4960,7 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64 ...@@ -4946,6 +4960,7 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64
napi_disable(&np->napi); napi_disable(&np->napi);
#endif #endif
netif_tx_lock_bh(dev); netif_tx_lock_bh(dev);
netif_addr_lock(dev);
spin_lock_irq(&np->lock); spin_lock_irq(&np->lock);
nv_disable_hw_interrupts(dev, np->irqmask); nv_disable_hw_interrupts(dev, np->irqmask);
if (!(np->msi_flags & NV_MSI_X_ENABLED)) { if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
...@@ -4959,6 +4974,7 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64 ...@@ -4959,6 +4974,7 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64
/* drain rx queue */ /* drain rx queue */
nv_drain_rxtx(dev); nv_drain_rxtx(dev);
spin_unlock_irq(&np->lock); spin_unlock_irq(&np->lock);
netif_addr_unlock(dev);
netif_tx_unlock_bh(dev); netif_tx_unlock_bh(dev);
} }
......
...@@ -300,7 +300,9 @@ static int sp_set_mac_address(struct net_device *dev, void *addr) ...@@ -300,7 +300,9 @@ static int sp_set_mac_address(struct net_device *dev, void *addr)
struct sockaddr_ax25 *sa = addr; struct sockaddr_ax25 *sa = addr;
netif_tx_lock_bh(dev); netif_tx_lock_bh(dev);
netif_addr_lock(dev);
memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN); memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
netif_addr_unlock(dev);
netif_tx_unlock_bh(dev); netif_tx_unlock_bh(dev);
return 0; return 0;
......
...@@ -356,7 +356,9 @@ static int ax_set_mac_address(struct net_device *dev, void *addr) ...@@ -356,7 +356,9 @@ static int ax_set_mac_address(struct net_device *dev, void *addr)
struct sockaddr_ax25 *sa = addr; struct sockaddr_ax25 *sa = addr;
netif_tx_lock_bh(dev); netif_tx_lock_bh(dev);
netif_addr_lock(dev);
memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN); memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
netif_addr_unlock(dev);
netif_tx_unlock_bh(dev); netif_tx_unlock_bh(dev);
return 0; return 0;
......
...@@ -295,7 +295,9 @@ static void emac_rx_disable(struct emac_instance *dev) ...@@ -295,7 +295,9 @@ static void emac_rx_disable(struct emac_instance *dev)
static inline void emac_netif_stop(struct emac_instance *dev) static inline void emac_netif_stop(struct emac_instance *dev)
{ {
netif_tx_lock_bh(dev->ndev); netif_tx_lock_bh(dev->ndev);
netif_addr_lock(dev->ndev);
dev->no_mcast = 1; dev->no_mcast = 1;
netif_addr_unlock(dev->ndev);
netif_tx_unlock_bh(dev->ndev); netif_tx_unlock_bh(dev->ndev);
dev->ndev->trans_start = jiffies; /* prevent tx timeout */ dev->ndev->trans_start = jiffies; /* prevent tx timeout */
mal_poll_disable(dev->mal, &dev->commac); mal_poll_disable(dev->mal, &dev->commac);
...@@ -305,9 +307,11 @@ static inline void emac_netif_stop(struct emac_instance *dev) ...@@ -305,9 +307,11 @@ static inline void emac_netif_stop(struct emac_instance *dev)
static inline void emac_netif_start(struct emac_instance *dev) static inline void emac_netif_start(struct emac_instance *dev)
{ {
netif_tx_lock_bh(dev->ndev); netif_tx_lock_bh(dev->ndev);
netif_addr_lock(dev->ndev);
dev->no_mcast = 0; dev->no_mcast = 0;
if (dev->mcast_pending && netif_running(dev->ndev)) if (dev->mcast_pending && netif_running(dev->ndev))
__emac_set_multicast_list(dev); __emac_set_multicast_list(dev);
netif_addr_unlock(dev->ndev);
netif_tx_unlock_bh(dev->ndev); netif_tx_unlock_bh(dev->ndev);
netif_wake_queue(dev->ndev); netif_wake_queue(dev->ndev);
......
...@@ -697,6 +697,8 @@ static void efx_stop_port(struct efx_nic *efx) ...@@ -697,6 +697,8 @@ static void efx_stop_port(struct efx_nic *efx)
/* Serialise against efx_set_multicast_list() */ /* Serialise against efx_set_multicast_list() */
if (efx_dev_registered(efx)) { if (efx_dev_registered(efx)) {
netif_tx_lock_bh(efx->net_dev); netif_tx_lock_bh(efx->net_dev);
netif_addr_lock(efx->net_dev);
netif_addr_unlock(efx->net_dev);
netif_tx_unlock_bh(efx->net_dev); netif_tx_unlock_bh(efx->net_dev);
} }
} }
......
...@@ -594,6 +594,7 @@ static int lbs_add_mcast_addrs(struct cmd_ds_mac_multicast_adr *cmd, ...@@ -594,6 +594,7 @@ static int lbs_add_mcast_addrs(struct cmd_ds_mac_multicast_adr *cmd,
return nr_addrs; return nr_addrs;
netif_tx_lock_bh(dev); netif_tx_lock_bh(dev);
netif_addr_lock(dev);
for (mc_list = dev->mc_list; mc_list; mc_list = mc_list->next) { for (mc_list = dev->mc_list; mc_list; mc_list = mc_list->next) {
if (mac_in_list(cmd->maclist, nr_addrs, mc_list->dmi_addr)) { if (mac_in_list(cmd->maclist, nr_addrs, mc_list->dmi_addr)) {
lbs_deb_net("mcast address %s:%s skipped\n", dev->name, lbs_deb_net("mcast address %s:%s skipped\n", dev->name,
...@@ -608,6 +609,7 @@ static int lbs_add_mcast_addrs(struct cmd_ds_mac_multicast_adr *cmd, ...@@ -608,6 +609,7 @@ static int lbs_add_mcast_addrs(struct cmd_ds_mac_multicast_adr *cmd,
print_mac(mac, mc_list->dmi_addr)); print_mac(mac, mc_list->dmi_addr));
i++; i++;
} }
netif_addr_unlock(dev);
netif_tx_unlock_bh(dev); netif_tx_unlock_bh(dev);
if (mc_list) if (mc_list)
return -EOVERFLOW; return -EOVERFLOW;
......
...@@ -1498,6 +1498,26 @@ static inline void netif_tx_disable(struct net_device *dev) ...@@ -1498,6 +1498,26 @@ static inline void netif_tx_disable(struct net_device *dev)
netif_tx_unlock_bh(dev); netif_tx_unlock_bh(dev);
} }
static inline void netif_addr_lock(struct net_device *dev)
{
spin_lock(&dev->addr_list_lock);
}
static inline void netif_addr_lock_bh(struct net_device *dev)
{
spin_lock_bh(&dev->addr_list_lock);
}
static inline void netif_addr_unlock(struct net_device *dev)
{
spin_unlock(&dev->addr_list_lock);
}
static inline void netif_addr_unlock_bh(struct net_device *dev)
{
spin_unlock_bh(&dev->addr_list_lock);
}
/* These functions live elsewhere (drivers/net/net_init.c, but related) */ /* These functions live elsewhere (drivers/net/net_init.c, but related) */
extern void ether_setup(struct net_device *dev); extern void ether_setup(struct net_device *dev);
......
...@@ -2982,7 +2982,9 @@ void __dev_set_rx_mode(struct net_device *dev) ...@@ -2982,7 +2982,9 @@ void __dev_set_rx_mode(struct net_device *dev)
void dev_set_rx_mode(struct net_device *dev) void dev_set_rx_mode(struct net_device *dev)
{ {
netif_tx_lock_bh(dev); netif_tx_lock_bh(dev);
netif_addr_lock(dev);
__dev_set_rx_mode(dev); __dev_set_rx_mode(dev);
netif_addr_unlock(dev);
netif_tx_unlock_bh(dev); netif_tx_unlock_bh(dev);
} }
...@@ -3062,9 +3064,11 @@ int dev_unicast_delete(struct net_device *dev, void *addr, int alen) ...@@ -3062,9 +3064,11 @@ int dev_unicast_delete(struct net_device *dev, void *addr, int alen)
ASSERT_RTNL(); ASSERT_RTNL();
netif_tx_lock_bh(dev); netif_tx_lock_bh(dev);
netif_addr_lock(dev);
err = __dev_addr_delete(&dev->uc_list, &dev->uc_count, addr, alen, 0); err = __dev_addr_delete(&dev->uc_list, &dev->uc_count, addr, alen, 0);
if (!err) if (!err)
__dev_set_rx_mode(dev); __dev_set_rx_mode(dev);
netif_addr_unlock(dev);
netif_tx_unlock_bh(dev); netif_tx_unlock_bh(dev);
return err; return err;
} }
...@@ -3088,9 +3092,11 @@ int dev_unicast_add(struct net_device *dev, void *addr, int alen) ...@@ -3088,9 +3092,11 @@ int dev_unicast_add(struct net_device *dev, void *addr, int alen)
ASSERT_RTNL(); ASSERT_RTNL();
netif_tx_lock_bh(dev); netif_tx_lock_bh(dev);
netif_addr_lock(dev);
err = __dev_addr_add(&dev->uc_list, &dev->uc_count, addr, alen, 0); err = __dev_addr_add(&dev->uc_list, &dev->uc_count, addr, alen, 0);
if (!err) if (!err)
__dev_set_rx_mode(dev); __dev_set_rx_mode(dev);
netif_addr_unlock(dev);
netif_tx_unlock_bh(dev); netif_tx_unlock_bh(dev);
return err; return err;
} }
...@@ -3159,10 +3165,12 @@ int dev_unicast_sync(struct net_device *to, struct net_device *from) ...@@ -3159,10 +3165,12 @@ int dev_unicast_sync(struct net_device *to, struct net_device *from)
int err = 0; int err = 0;
netif_tx_lock_bh(to); netif_tx_lock_bh(to);
netif_addr_lock(to);
err = __dev_addr_sync(&to->uc_list, &to->uc_count, err = __dev_addr_sync(&to->uc_list, &to->uc_count,
&from->uc_list, &from->uc_count); &from->uc_list, &from->uc_count);
if (!err) if (!err)
__dev_set_rx_mode(to); __dev_set_rx_mode(to);
netif_addr_unlock(to);
netif_tx_unlock_bh(to); netif_tx_unlock_bh(to);
return err; return err;
} }
...@@ -3180,13 +3188,17 @@ EXPORT_SYMBOL(dev_unicast_sync); ...@@ -3180,13 +3188,17 @@ EXPORT_SYMBOL(dev_unicast_sync);
void dev_unicast_unsync(struct net_device *to, struct net_device *from) void dev_unicast_unsync(struct net_device *to, struct net_device *from)
{ {
netif_tx_lock_bh(from); netif_tx_lock_bh(from);
netif_addr_lock(from);
netif_tx_lock_bh(to); netif_tx_lock_bh(to);
netif_addr_lock(to);
__dev_addr_unsync(&to->uc_list, &to->uc_count, __dev_addr_unsync(&to->uc_list, &to->uc_count,
&from->uc_list, &from->uc_count); &from->uc_list, &from->uc_count);
__dev_set_rx_mode(to); __dev_set_rx_mode(to);
netif_addr_unlock(to);
netif_tx_unlock_bh(to); netif_tx_unlock_bh(to);
netif_addr_unlock(from);
netif_tx_unlock_bh(from); netif_tx_unlock_bh(from);
} }
EXPORT_SYMBOL(dev_unicast_unsync); EXPORT_SYMBOL(dev_unicast_unsync);
...@@ -3208,6 +3220,7 @@ static void __dev_addr_discard(struct dev_addr_list **list) ...@@ -3208,6 +3220,7 @@ static void __dev_addr_discard(struct dev_addr_list **list)
static void dev_addr_discard(struct net_device *dev) static void dev_addr_discard(struct net_device *dev)
{ {
netif_tx_lock_bh(dev); netif_tx_lock_bh(dev);
netif_addr_lock(dev);
__dev_addr_discard(&dev->uc_list); __dev_addr_discard(&dev->uc_list);
dev->uc_count = 0; dev->uc_count = 0;
...@@ -3215,6 +3228,7 @@ static void dev_addr_discard(struct net_device *dev) ...@@ -3215,6 +3228,7 @@ static void dev_addr_discard(struct net_device *dev)
__dev_addr_discard(&dev->mc_list); __dev_addr_discard(&dev->mc_list);
dev->mc_count = 0; dev->mc_count = 0;
netif_addr_unlock(dev);
netif_tx_unlock_bh(dev); netif_tx_unlock_bh(dev);
} }
......
...@@ -73,6 +73,7 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl) ...@@ -73,6 +73,7 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl)
int err; int err;
netif_tx_lock_bh(dev); netif_tx_lock_bh(dev);
netif_addr_lock(dev);
err = __dev_addr_delete(&dev->mc_list, &dev->mc_count, err = __dev_addr_delete(&dev->mc_list, &dev->mc_count,
addr, alen, glbl); addr, alen, glbl);
if (!err) { if (!err) {
...@@ -83,6 +84,7 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl) ...@@ -83,6 +84,7 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl)
__dev_set_rx_mode(dev); __dev_set_rx_mode(dev);
} }
netif_addr_unlock(dev);
netif_tx_unlock_bh(dev); netif_tx_unlock_bh(dev);
return err; return err;
} }
...@@ -96,9 +98,11 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl) ...@@ -96,9 +98,11 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
int err; int err;
netif_tx_lock_bh(dev); netif_tx_lock_bh(dev);
netif_addr_lock(dev);
err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl); err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl);
if (!err) if (!err)
__dev_set_rx_mode(dev); __dev_set_rx_mode(dev);
netif_addr_unlock(dev);
netif_tx_unlock_bh(dev); netif_tx_unlock_bh(dev);
return err; return err;
} }
...@@ -120,10 +124,12 @@ int dev_mc_sync(struct net_device *to, struct net_device *from) ...@@ -120,10 +124,12 @@ int dev_mc_sync(struct net_device *to, struct net_device *from)
int err = 0; int err = 0;
netif_tx_lock_bh(to); netif_tx_lock_bh(to);
netif_addr_lock(to);
err = __dev_addr_sync(&to->mc_list, &to->mc_count, err = __dev_addr_sync(&to->mc_list, &to->mc_count,
&from->mc_list, &from->mc_count); &from->mc_list, &from->mc_count);
if (!err) if (!err)
__dev_set_rx_mode(to); __dev_set_rx_mode(to);
netif_addr_unlock(to);
netif_tx_unlock_bh(to); netif_tx_unlock_bh(to);
return err; return err;
...@@ -144,13 +150,17 @@ EXPORT_SYMBOL(dev_mc_sync); ...@@ -144,13 +150,17 @@ EXPORT_SYMBOL(dev_mc_sync);
void dev_mc_unsync(struct net_device *to, struct net_device *from) void dev_mc_unsync(struct net_device *to, struct net_device *from)
{ {
netif_tx_lock_bh(from); netif_tx_lock_bh(from);
netif_addr_lock(from);
netif_tx_lock_bh(to); netif_tx_lock_bh(to);
netif_addr_lock(to);
__dev_addr_unsync(&to->mc_list, &to->mc_count, __dev_addr_unsync(&to->mc_list, &to->mc_count,
&from->mc_list, &from->mc_count); &from->mc_list, &from->mc_count);
__dev_set_rx_mode(to); __dev_set_rx_mode(to);
netif_addr_unlock(to);
netif_tx_unlock_bh(to); netif_tx_unlock_bh(to);
netif_addr_unlock(from);
netif_tx_unlock_bh(from); netif_tx_unlock_bh(from);
} }
EXPORT_SYMBOL(dev_mc_unsync); EXPORT_SYMBOL(dev_mc_unsync);
...@@ -165,6 +175,7 @@ static int dev_mc_seq_show(struct seq_file *seq, void *v) ...@@ -165,6 +175,7 @@ static int dev_mc_seq_show(struct seq_file *seq, void *v)
return 0; return 0;
netif_tx_lock_bh(dev); netif_tx_lock_bh(dev);
netif_addr_lock(dev);
for (m = dev->mc_list; m; m = m->next) { for (m = dev->mc_list; m; m = m->next) {
int i; int i;
...@@ -176,6 +187,7 @@ static int dev_mc_seq_show(struct seq_file *seq, void *v) ...@@ -176,6 +187,7 @@ static int dev_mc_seq_show(struct seq_file *seq, void *v)
seq_putc(seq, '\n'); seq_putc(seq, '\n');
} }
netif_addr_unlock(dev);
netif_tx_unlock_bh(dev); netif_tx_unlock_bh(dev);
return 0; return 0;
} }
......
...@@ -292,7 +292,9 @@ static int ieee80211_open(struct net_device *dev) ...@@ -292,7 +292,9 @@ static int ieee80211_open(struct net_device *dev)
local->fif_other_bss++; local->fif_other_bss++;
netif_tx_lock_bh(local->mdev); netif_tx_lock_bh(local->mdev);
netif_addr_lock(local->mdev);
ieee80211_configure_filter(local); ieee80211_configure_filter(local);
netif_addr_unlock(local->mdev);
netif_tx_unlock_bh(local->mdev); netif_tx_unlock_bh(local->mdev);
break; break;
case IEEE80211_IF_TYPE_STA: case IEEE80211_IF_TYPE_STA:
...@@ -491,7 +493,9 @@ static int ieee80211_stop(struct net_device *dev) ...@@ -491,7 +493,9 @@ static int ieee80211_stop(struct net_device *dev)
local->fif_other_bss--; local->fif_other_bss--;
netif_tx_lock_bh(local->mdev); netif_tx_lock_bh(local->mdev);
netif_addr_lock(local->mdev);
ieee80211_configure_filter(local); ieee80211_configure_filter(local);
netif_addr_unlock(local->mdev);
netif_tx_unlock_bh(local->mdev); netif_tx_unlock_bh(local->mdev);
break; break;
case IEEE80211_IF_TYPE_MESH_POINT: case IEEE80211_IF_TYPE_MESH_POINT:
......
...@@ -3869,6 +3869,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw) ...@@ -3869,6 +3869,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw)
netif_tx_lock_bh(local->mdev); netif_tx_lock_bh(local->mdev);
netif_addr_lock(local->mdev);
local->filter_flags &= ~FIF_BCN_PRBRESP_PROMISC; local->filter_flags &= ~FIF_BCN_PRBRESP_PROMISC;
local->ops->configure_filter(local_to_hw(local), local->ops->configure_filter(local_to_hw(local),
FIF_BCN_PRBRESP_PROMISC, FIF_BCN_PRBRESP_PROMISC,
...@@ -3876,6 +3877,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw) ...@@ -3876,6 +3877,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw)
local->mdev->mc_count, local->mdev->mc_count,
local->mdev->mc_list); local->mdev->mc_list);
netif_addr_unlock(local->mdev);
netif_tx_unlock_bh(local->mdev); netif_tx_unlock_bh(local->mdev);
rcu_read_lock(); rcu_read_lock();
...@@ -4063,12 +4065,14 @@ static int ieee80211_sta_start_scan(struct net_device *dev, ...@@ -4063,12 +4065,14 @@ static int ieee80211_sta_start_scan(struct net_device *dev,
local->scan_dev = dev; local->scan_dev = dev;
netif_tx_lock_bh(local->mdev); netif_tx_lock_bh(local->mdev);
netif_addr_lock(local->mdev);
local->filter_flags |= FIF_BCN_PRBRESP_PROMISC; local->filter_flags |= FIF_BCN_PRBRESP_PROMISC;
local->ops->configure_filter(local_to_hw(local), local->ops->configure_filter(local_to_hw(local),
FIF_BCN_PRBRESP_PROMISC, FIF_BCN_PRBRESP_PROMISC,
&local->filter_flags, &local->filter_flags,
local->mdev->mc_count, local->mdev->mc_count,
local->mdev->mc_list); local->mdev->mc_list);
netif_addr_unlock(local->mdev);
netif_tx_unlock_bh(local->mdev); netif_tx_unlock_bh(local->mdev);
/* TODO: start scan as soon as all nullfunc frames are ACKed */ /* TODO: start scan as soon as all nullfunc frames are ACKed */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment