aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-07-15 03:13:44 -0400
committerDavid S. Miller <davem@davemloft.net>2008-07-15 03:13:44 -0400
commite308a5d806c852f56590ffdd3834d0df0cbed8d7 (patch)
tree294ff654e90950f5162737c26f4799b0b710b748
parentf1f28aa3510ddb84c966bac65611bb866c77a092 (diff)
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: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.c2
-rw-r--r--drivers/net/bonding/bond_main.c8
-rw-r--r--drivers/net/forcedeth.c16
-rw-r--r--drivers/net/hamradio/6pack.c2
-rw-r--r--drivers/net/hamradio/mkiss.c2
-rw-r--r--drivers/net/ibm_newemac/core.c4
-rw-r--r--drivers/net/sfc/efx.c2
-rw-r--r--drivers/net/wireless/libertas/main.c2
-rw-r--r--include/linux/netdevice.h20
-rw-r--r--net/core/dev.c14
-rw-r--r--net/core/dev_mcast.c12
-rw-r--r--net/mac80211/main.c4
-rw-r--r--net/mac80211/mlme.c4
14 files changed, 94 insertions, 0 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 3f663fb852c1..261ab7150431 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -775,6 +775,7 @@ void ipoib_mcast_restart_task(struct work_struct *work)
775 775
776 local_irq_save(flags); 776 local_irq_save(flags);
777 netif_tx_lock(dev); 777 netif_tx_lock(dev);
778 netif_addr_lock(dev);
778 spin_lock(&priv->lock); 779 spin_lock(&priv->lock);
779 780
780 /* 781 /*
@@ -851,6 +852,7 @@ void ipoib_mcast_restart_task(struct work_struct *work)
851 } 852 }
852 853
853 spin_unlock(&priv->lock); 854 spin_unlock(&priv->lock);
855 netif_addr_unlock(dev);
854 netif_tx_unlock(dev); 856 netif_tx_unlock(dev);
855 local_irq_restore(flags); 857 local_irq_restore(flags);
856 858
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
index c2334aef4143..809d18c663bc 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -1134,6 +1134,7 @@ static void wq_set_multicast_list (struct work_struct *work)
1134 dvb_net_feed_stop(dev); 1134 dvb_net_feed_stop(dev);
1135 priv->rx_mode = RX_MODE_UNI; 1135 priv->rx_mode = RX_MODE_UNI;
1136 netif_tx_lock_bh(dev); 1136 netif_tx_lock_bh(dev);
1137 netif_addr_lock(dev);
1137 1138
1138 if (dev->flags & IFF_PROMISC) { 1139 if (dev->flags & IFF_PROMISC) {
1139 dprintk("%s: promiscuous mode\n", dev->name); 1140 dprintk("%s: promiscuous mode\n", dev->name);
@@ -1158,6 +1159,7 @@ static void wq_set_multicast_list (struct work_struct *work)
1158 } 1159 }
1159 } 1160 }
1160 1161
1162 netif_addr_unlock(dev);
1161 netif_tx_unlock_bh(dev); 1163 netif_tx_unlock_bh(dev);
1162 dvb_net_feed_start(dev); 1164 dvb_net_feed_start(dev);
1163} 1165}
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 8ae7ff313218..ea71abd6f728 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1568,10 +1568,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1568 } 1568 }
1569 1569
1570 netif_tx_lock_bh(bond_dev); 1570 netif_tx_lock_bh(bond_dev);
1571 netif_addr_lock(bond_dev);
1571 /* upload master's mc_list to new slave */ 1572 /* upload master's mc_list to new slave */
1572 for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) { 1573 for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) {
1573 dev_mc_add (slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0); 1574 dev_mc_add (slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
1574 } 1575 }
1576 netif_addr_unlock(bond_dev);
1575 netif_tx_unlock_bh(bond_dev); 1577 netif_tx_unlock_bh(bond_dev);
1576 } 1578 }
1577 1579
@@ -1937,7 +1939,9 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
1937 1939
1938 /* flush master's mc_list from slave */ 1940 /* flush master's mc_list from slave */
1939 netif_tx_lock_bh(bond_dev); 1941 netif_tx_lock_bh(bond_dev);
1942 netif_addr_lock(bond_dev);
1940 bond_mc_list_flush(bond_dev, slave_dev); 1943 bond_mc_list_flush(bond_dev, slave_dev);
1944 netif_addr_unlock(bond_dev);
1941 netif_tx_unlock_bh(bond_dev); 1945 netif_tx_unlock_bh(bond_dev);
1942 } 1946 }
1943 1947
@@ -2060,7 +2064,9 @@ static int bond_release_all(struct net_device *bond_dev)
2060 2064
2061 /* flush master's mc_list from slave */ 2065 /* flush master's mc_list from slave */
2062 netif_tx_lock_bh(bond_dev); 2066 netif_tx_lock_bh(bond_dev);
2067 netif_addr_lock(bond_dev);
2063 bond_mc_list_flush(bond_dev, slave_dev); 2068 bond_mc_list_flush(bond_dev, slave_dev);
2069 netif_addr_unlock(bond_dev);
2064 netif_tx_unlock_bh(bond_dev); 2070 netif_tx_unlock_bh(bond_dev);
2065 } 2071 }
2066 2072
@@ -4674,7 +4680,9 @@ static void bond_free_all(void)
4674 4680
4675 bond_work_cancel_all(bond); 4681 bond_work_cancel_all(bond);
4676 netif_tx_lock_bh(bond_dev); 4682 netif_tx_lock_bh(bond_dev);
4683 netif_addr_lock(bond_dev);
4677 bond_mc_list_destroy(bond); 4684 bond_mc_list_destroy(bond);
4685 netif_addr_unlock(bond_dev);
4678 netif_tx_unlock_bh(bond_dev); 4686 netif_tx_unlock_bh(bond_dev);
4679 /* Release the bonded slaves */ 4687 /* Release the bonded slaves */
4680 bond_release_all(bond_dev); 4688 bond_release_all(bond_dev);
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 786d668c612e..4ed89fa9ae46 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -2831,6 +2831,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu)
2831 */ 2831 */
2832 nv_disable_irq(dev); 2832 nv_disable_irq(dev);
2833 netif_tx_lock_bh(dev); 2833 netif_tx_lock_bh(dev);
2834 netif_addr_lock(dev);
2834 spin_lock(&np->lock); 2835 spin_lock(&np->lock);
2835 /* stop engines */ 2836 /* stop engines */
2836 nv_stop_rxtx(dev); 2837 nv_stop_rxtx(dev);
@@ -2855,6 +2856,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu)
2855 /* restart rx engine */ 2856 /* restart rx engine */
2856 nv_start_rxtx(dev); 2857 nv_start_rxtx(dev);
2857 spin_unlock(&np->lock); 2858 spin_unlock(&np->lock);
2859 netif_addr_unlock(dev);
2858 netif_tx_unlock_bh(dev); 2860 netif_tx_unlock_bh(dev);
2859 nv_enable_irq(dev); 2861 nv_enable_irq(dev);
2860 } 2862 }
@@ -2891,6 +2893,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr)
2891 2893
2892 if (netif_running(dev)) { 2894 if (netif_running(dev)) {
2893 netif_tx_lock_bh(dev); 2895 netif_tx_lock_bh(dev);
2896 netif_addr_lock(dev);
2894 spin_lock_irq(&np->lock); 2897 spin_lock_irq(&np->lock);
2895 2898
2896 /* stop rx engine */ 2899 /* stop rx engine */
@@ -2902,6 +2905,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr)
2902 /* restart rx engine */ 2905 /* restart rx engine */
2903 nv_start_rx(dev); 2906 nv_start_rx(dev);
2904 spin_unlock_irq(&np->lock); 2907 spin_unlock_irq(&np->lock);
2908 netif_addr_unlock(dev);
2905 netif_tx_unlock_bh(dev); 2909 netif_tx_unlock_bh(dev);
2906 } else { 2910 } else {
2907 nv_copy_mac_to_hw(dev); 2911 nv_copy_mac_to_hw(dev);
@@ -3971,6 +3975,7 @@ static void nv_do_nic_poll(unsigned long data)
3971 printk(KERN_INFO "forcedeth: MAC in recoverable error state\n"); 3975 printk(KERN_INFO "forcedeth: MAC in recoverable error state\n");
3972 if (netif_running(dev)) { 3976 if (netif_running(dev)) {
3973 netif_tx_lock_bh(dev); 3977 netif_tx_lock_bh(dev);
3978 netif_addr_lock(dev);
3974 spin_lock(&np->lock); 3979 spin_lock(&np->lock);
3975 /* stop engines */ 3980 /* stop engines */
3976 nv_stop_rxtx(dev); 3981 nv_stop_rxtx(dev);
@@ -3995,6 +4000,7 @@ static void nv_do_nic_poll(unsigned long data)
3995 /* restart rx engine */ 4000 /* restart rx engine */
3996 nv_start_rxtx(dev); 4001 nv_start_rxtx(dev);
3997 spin_unlock(&np->lock); 4002 spin_unlock(&np->lock);
4003 netif_addr_unlock(dev);
3998 netif_tx_unlock_bh(dev); 4004 netif_tx_unlock_bh(dev);
3999 } 4005 }
4000 } 4006 }
@@ -4202,6 +4208,7 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
4202 4208
4203 nv_disable_irq(dev); 4209 nv_disable_irq(dev);
4204 netif_tx_lock_bh(dev); 4210 netif_tx_lock_bh(dev);
4211 netif_addr_lock(dev);
4205 /* with plain spinlock lockdep complains */ 4212 /* with plain spinlock lockdep complains */
4206 spin_lock_irqsave(&np->lock, flags); 4213 spin_lock_irqsave(&np->lock, flags);
4207 /* stop engines */ 4214 /* stop engines */
@@ -4215,6 +4222,7 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
4215 */ 4222 */
4216 nv_stop_rxtx(dev); 4223 nv_stop_rxtx(dev);
4217 spin_unlock_irqrestore(&np->lock, flags); 4224 spin_unlock_irqrestore(&np->lock, flags);
4225 netif_addr_unlock(dev);
4218 netif_tx_unlock_bh(dev); 4226 netif_tx_unlock_bh(dev);
4219 } 4227 }
4220 4228
@@ -4360,10 +4368,12 @@ static int nv_nway_reset(struct net_device *dev)
4360 if (netif_running(dev)) { 4368 if (netif_running(dev)) {
4361 nv_disable_irq(dev); 4369 nv_disable_irq(dev);
4362 netif_tx_lock_bh(dev); 4370 netif_tx_lock_bh(dev);
4371 netif_addr_lock(dev);
4363 spin_lock(&np->lock); 4372 spin_lock(&np->lock);
4364 /* stop engines */ 4373 /* stop engines */
4365 nv_stop_rxtx(dev); 4374 nv_stop_rxtx(dev);
4366 spin_unlock(&np->lock); 4375 spin_unlock(&np->lock);
4376 netif_addr_unlock(dev);
4367 netif_tx_unlock_bh(dev); 4377 netif_tx_unlock_bh(dev);
4368 printk(KERN_INFO "%s: link down.\n", dev->name); 4378 printk(KERN_INFO "%s: link down.\n", dev->name);
4369 } 4379 }
@@ -4471,6 +4481,7 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri
4471 if (netif_running(dev)) { 4481 if (netif_running(dev)) {
4472 nv_disable_irq(dev); 4482 nv_disable_irq(dev);
4473 netif_tx_lock_bh(dev); 4483 netif_tx_lock_bh(dev);
4484 netif_addr_lock(dev);
4474 spin_lock(&np->lock); 4485 spin_lock(&np->lock);
4475 /* stop engines */ 4486 /* stop engines */
4476 nv_stop_rxtx(dev); 4487 nv_stop_rxtx(dev);
@@ -4519,6 +4530,7 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri
4519 /* restart engines */ 4530 /* restart engines */
4520 nv_start_rxtx(dev); 4531 nv_start_rxtx(dev);
4521 spin_unlock(&np->lock); 4532 spin_unlock(&np->lock);
4533 netif_addr_unlock(dev);
4522 netif_tx_unlock_bh(dev); 4534 netif_tx_unlock_bh(dev);
4523 nv_enable_irq(dev); 4535 nv_enable_irq(dev);
4524 } 4536 }
@@ -4556,10 +4568,12 @@ static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam*
4556 if (netif_running(dev)) { 4568 if (netif_running(dev)) {
4557 nv_disable_irq(dev); 4569 nv_disable_irq(dev);
4558 netif_tx_lock_bh(dev); 4570 netif_tx_lock_bh(dev);
4571 netif_addr_lock(dev);
4559 spin_lock(&np->lock); 4572 spin_lock(&np->lock);
4560 /* stop engines */ 4573 /* stop engines */
4561 nv_stop_rxtx(dev); 4574 nv_stop_rxtx(dev);
4562 spin_unlock(&np->lock); 4575 spin_unlock(&np->lock);
4576 netif_addr_unlock(dev);
4563 netif_tx_unlock_bh(dev); 4577 netif_tx_unlock_bh(dev);
4564 } 4578 }
4565 4579
@@ -4946,6 +4960,7 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64
4946 napi_disable(&np->napi); 4960 napi_disable(&np->napi);
4947#endif 4961#endif
4948 netif_tx_lock_bh(dev); 4962 netif_tx_lock_bh(dev);
4963 netif_addr_lock(dev);
4949 spin_lock_irq(&np->lock); 4964 spin_lock_irq(&np->lock);
4950 nv_disable_hw_interrupts(dev, np->irqmask); 4965 nv_disable_hw_interrupts(dev, np->irqmask);
4951 if (!(np->msi_flags & NV_MSI_X_ENABLED)) { 4966 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 /* drain rx queue */ 4974 /* drain rx queue */
4960 nv_drain_rxtx(dev); 4975 nv_drain_rxtx(dev);
4961 spin_unlock_irq(&np->lock); 4976 spin_unlock_irq(&np->lock);
4977 netif_addr_unlock(dev);
4962 netif_tx_unlock_bh(dev); 4978 netif_tx_unlock_bh(dev);
4963 } 4979 }
4964 4980
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 06ad9f302b5a..ffc937f5d15d 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -300,7 +300,9 @@ static int sp_set_mac_address(struct net_device *dev, void *addr)
300 struct sockaddr_ax25 *sa = addr; 300 struct sockaddr_ax25 *sa = addr;
301 301
302 netif_tx_lock_bh(dev); 302 netif_tx_lock_bh(dev);
303 netif_addr_lock(dev);
303 memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN); 304 memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
305 netif_addr_unlock(dev);
304 netif_tx_unlock_bh(dev); 306 netif_tx_unlock_bh(dev);
305 307
306 return 0; 308 return 0;
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 65166035aca0..b8740e6a5cec 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -356,7 +356,9 @@ static int ax_set_mac_address(struct net_device *dev, void *addr)
356 struct sockaddr_ax25 *sa = addr; 356 struct sockaddr_ax25 *sa = addr;
357 357
358 netif_tx_lock_bh(dev); 358 netif_tx_lock_bh(dev);
359 netif_addr_lock(dev);
359 memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN); 360 memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
361 netif_addr_unlock(dev);
360 netif_tx_unlock_bh(dev); 362 netif_tx_unlock_bh(dev);
361 363
362 return 0; 364 return 0;
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index babc79ad490b..9ca57d365599 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -295,7 +295,9 @@ static void emac_rx_disable(struct emac_instance *dev)
295static inline void emac_netif_stop(struct emac_instance *dev) 295static inline void emac_netif_stop(struct emac_instance *dev)
296{ 296{
297 netif_tx_lock_bh(dev->ndev); 297 netif_tx_lock_bh(dev->ndev);
298 netif_addr_lock(dev->ndev);
298 dev->no_mcast = 1; 299 dev->no_mcast = 1;
300 netif_addr_unlock(dev->ndev);
299 netif_tx_unlock_bh(dev->ndev); 301 netif_tx_unlock_bh(dev->ndev);
300 dev->ndev->trans_start = jiffies; /* prevent tx timeout */ 302 dev->ndev->trans_start = jiffies; /* prevent tx timeout */
301 mal_poll_disable(dev->mal, &dev->commac); 303 mal_poll_disable(dev->mal, &dev->commac);
@@ -305,9 +307,11 @@ static inline void emac_netif_stop(struct emac_instance *dev)
305static inline void emac_netif_start(struct emac_instance *dev) 307static inline void emac_netif_start(struct emac_instance *dev)
306{ 308{
307 netif_tx_lock_bh(dev->ndev); 309 netif_tx_lock_bh(dev->ndev);
310 netif_addr_lock(dev->ndev);
308 dev->no_mcast = 0; 311 dev->no_mcast = 0;
309 if (dev->mcast_pending && netif_running(dev->ndev)) 312 if (dev->mcast_pending && netif_running(dev->ndev))
310 __emac_set_multicast_list(dev); 313 __emac_set_multicast_list(dev);
314 netif_addr_unlock(dev->ndev);
311 netif_tx_unlock_bh(dev->ndev); 315 netif_tx_unlock_bh(dev->ndev);
312 316
313 netif_wake_queue(dev->ndev); 317 netif_wake_queue(dev->ndev);
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 74265d8553b8..e1257e556e48 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -697,6 +697,8 @@ static void efx_stop_port(struct efx_nic *efx)
697 /* Serialise against efx_set_multicast_list() */ 697 /* Serialise against efx_set_multicast_list() */
698 if (efx_dev_registered(efx)) { 698 if (efx_dev_registered(efx)) {
699 netif_tx_lock_bh(efx->net_dev); 699 netif_tx_lock_bh(efx->net_dev);
700 netif_addr_lock(efx->net_dev);
701 netif_addr_unlock(efx->net_dev);
700 netif_tx_unlock_bh(efx->net_dev); 702 netif_tx_unlock_bh(efx->net_dev);
701 } 703 }
702} 704}
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index abd6d9ed8f4b..42e9b2771eab 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -594,6 +594,7 @@ static int lbs_add_mcast_addrs(struct cmd_ds_mac_multicast_adr *cmd,
594 return nr_addrs; 594 return nr_addrs;
595 595
596 netif_tx_lock_bh(dev); 596 netif_tx_lock_bh(dev);
597 netif_addr_lock(dev);
597 for (mc_list = dev->mc_list; mc_list; mc_list = mc_list->next) { 598 for (mc_list = dev->mc_list; mc_list; mc_list = mc_list->next) {
598 if (mac_in_list(cmd->maclist, nr_addrs, mc_list->dmi_addr)) { 599 if (mac_in_list(cmd->maclist, nr_addrs, mc_list->dmi_addr)) {
599 lbs_deb_net("mcast address %s:%s skipped\n", dev->name, 600 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 print_mac(mac, mc_list->dmi_addr)); 609 print_mac(mac, mc_list->dmi_addr));
609 i++; 610 i++;
610 } 611 }
612 netif_addr_unlock(dev);
611 netif_tx_unlock_bh(dev); 613 netif_tx_unlock_bh(dev);
612 if (mc_list) 614 if (mc_list)
613 return -EOVERFLOW; 615 return -EOVERFLOW;
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index fd0365219181..570cf7affa72 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1498,6 +1498,26 @@ static inline void netif_tx_disable(struct net_device *dev)
1498 netif_tx_unlock_bh(dev); 1498 netif_tx_unlock_bh(dev);
1499} 1499}
1500 1500
1501static inline void netif_addr_lock(struct net_device *dev)
1502{
1503 spin_lock(&dev->addr_list_lock);
1504}
1505
1506static inline void netif_addr_lock_bh(struct net_device *dev)
1507{
1508 spin_lock_bh(&dev->addr_list_lock);
1509}
1510
1511static inline void netif_addr_unlock(struct net_device *dev)
1512{
1513 spin_unlock(&dev->addr_list_lock);
1514}
1515
1516static inline void netif_addr_unlock_bh(struct net_device *dev)
1517{
1518 spin_unlock_bh(&dev->addr_list_lock);
1519}
1520
1501/* These functions live elsewhere (drivers/net/net_init.c, but related) */ 1521/* These functions live elsewhere (drivers/net/net_init.c, but related) */
1502 1522
1503extern void ether_setup(struct net_device *dev); 1523extern void ether_setup(struct net_device *dev);
diff --git a/net/core/dev.c b/net/core/dev.c
index d933d1bfa6fa..ef1502d71f25 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2982,7 +2982,9 @@ void __dev_set_rx_mode(struct net_device *dev)
2982void dev_set_rx_mode(struct net_device *dev) 2982void dev_set_rx_mode(struct net_device *dev)
2983{ 2983{
2984 netif_tx_lock_bh(dev); 2984 netif_tx_lock_bh(dev);
2985 netif_addr_lock(dev);
2985 __dev_set_rx_mode(dev); 2986 __dev_set_rx_mode(dev);
2987 netif_addr_unlock(dev);
2986 netif_tx_unlock_bh(dev); 2988 netif_tx_unlock_bh(dev);
2987} 2989}
2988 2990
@@ -3062,9 +3064,11 @@ int dev_unicast_delete(struct net_device *dev, void *addr, int alen)
3062 ASSERT_RTNL(); 3064 ASSERT_RTNL();
3063 3065
3064 netif_tx_lock_bh(dev); 3066 netif_tx_lock_bh(dev);
3067 netif_addr_lock(dev);
3065 err = __dev_addr_delete(&dev->uc_list, &dev->uc_count, addr, alen, 0); 3068 err = __dev_addr_delete(&dev->uc_list, &dev->uc_count, addr, alen, 0);
3066 if (!err) 3069 if (!err)
3067 __dev_set_rx_mode(dev); 3070 __dev_set_rx_mode(dev);
3071 netif_addr_unlock(dev);
3068 netif_tx_unlock_bh(dev); 3072 netif_tx_unlock_bh(dev);
3069 return err; 3073 return err;
3070} 3074}
@@ -3088,9 +3092,11 @@ int dev_unicast_add(struct net_device *dev, void *addr, int alen)
3088 ASSERT_RTNL(); 3092 ASSERT_RTNL();
3089 3093
3090 netif_tx_lock_bh(dev); 3094 netif_tx_lock_bh(dev);
3095 netif_addr_lock(dev);
3091 err = __dev_addr_add(&dev->uc_list, &dev->uc_count, addr, alen, 0); 3096 err = __dev_addr_add(&dev->uc_list, &dev->uc_count, addr, alen, 0);
3092 if (!err) 3097 if (!err)
3093 __dev_set_rx_mode(dev); 3098 __dev_set_rx_mode(dev);
3099 netif_addr_unlock(dev);
3094 netif_tx_unlock_bh(dev); 3100 netif_tx_unlock_bh(dev);
3095 return err; 3101 return err;
3096} 3102}
@@ -3159,10 +3165,12 @@ int dev_unicast_sync(struct net_device *to, struct net_device *from)
3159 int err = 0; 3165 int err = 0;
3160 3166
3161 netif_tx_lock_bh(to); 3167 netif_tx_lock_bh(to);
3168 netif_addr_lock(to);
3162 err = __dev_addr_sync(&to->uc_list, &to->uc_count, 3169 err = __dev_addr_sync(&to->uc_list, &to->uc_count,
3163 &from->uc_list, &from->uc_count); 3170 &from->uc_list, &from->uc_count);
3164 if (!err) 3171 if (!err)
3165 __dev_set_rx_mode(to); 3172 __dev_set_rx_mode(to);
3173 netif_addr_unlock(to);
3166 netif_tx_unlock_bh(to); 3174 netif_tx_unlock_bh(to);
3167 return err; 3175 return err;
3168} 3176}
@@ -3180,13 +3188,17 @@ EXPORT_SYMBOL(dev_unicast_sync);
3180void dev_unicast_unsync(struct net_device *to, struct net_device *from) 3188void dev_unicast_unsync(struct net_device *to, struct net_device *from)
3181{ 3189{
3182 netif_tx_lock_bh(from); 3190 netif_tx_lock_bh(from);
3191 netif_addr_lock(from);
3183 netif_tx_lock_bh(to); 3192 netif_tx_lock_bh(to);
3193 netif_addr_lock(to);
3184 3194
3185 __dev_addr_unsync(&to->uc_list, &to->uc_count, 3195 __dev_addr_unsync(&to->uc_list, &to->uc_count,
3186 &from->uc_list, &from->uc_count); 3196 &from->uc_list, &from->uc_count);
3187 __dev_set_rx_mode(to); 3197 __dev_set_rx_mode(to);
3188 3198
3199 netif_addr_unlock(to);
3189 netif_tx_unlock_bh(to); 3200 netif_tx_unlock_bh(to);
3201 netif_addr_unlock(from);
3190 netif_tx_unlock_bh(from); 3202 netif_tx_unlock_bh(from);
3191} 3203}
3192EXPORT_SYMBOL(dev_unicast_unsync); 3204EXPORT_SYMBOL(dev_unicast_unsync);
@@ -3208,6 +3220,7 @@ static void __dev_addr_discard(struct dev_addr_list **list)
3208static void dev_addr_discard(struct net_device *dev) 3220static void dev_addr_discard(struct net_device *dev)
3209{ 3221{
3210 netif_tx_lock_bh(dev); 3222 netif_tx_lock_bh(dev);
3223 netif_addr_lock(dev);
3211 3224
3212 __dev_addr_discard(&dev->uc_list); 3225 __dev_addr_discard(&dev->uc_list);
3213 dev->uc_count = 0; 3226 dev->uc_count = 0;
@@ -3215,6 +3228,7 @@ static void dev_addr_discard(struct net_device *dev)
3215 __dev_addr_discard(&dev->mc_list); 3228 __dev_addr_discard(&dev->mc_list);
3216 dev->mc_count = 0; 3229 dev->mc_count = 0;
3217 3230
3231 netif_addr_unlock(dev);
3218 netif_tx_unlock_bh(dev); 3232 netif_tx_unlock_bh(dev);
3219} 3233}
3220 3234
diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c
index f8a3455f4493..b6b2a129971a 100644
--- a/net/core/dev_mcast.c
+++ b/net/core/dev_mcast.c
@@ -73,6 +73,7 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl)
73 int err; 73 int err;
74 74
75 netif_tx_lock_bh(dev); 75 netif_tx_lock_bh(dev);
76 netif_addr_lock(dev);
76 err = __dev_addr_delete(&dev->mc_list, &dev->mc_count, 77 err = __dev_addr_delete(&dev->mc_list, &dev->mc_count,
77 addr, alen, glbl); 78 addr, alen, glbl);
78 if (!err) { 79 if (!err) {
@@ -83,6 +84,7 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl)
83 84
84 __dev_set_rx_mode(dev); 85 __dev_set_rx_mode(dev);
85 } 86 }
87 netif_addr_unlock(dev);
86 netif_tx_unlock_bh(dev); 88 netif_tx_unlock_bh(dev);
87 return err; 89 return err;
88} 90}
@@ -96,9 +98,11 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
96 int err; 98 int err;
97 99
98 netif_tx_lock_bh(dev); 100 netif_tx_lock_bh(dev);
101 netif_addr_lock(dev);
99 err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl); 102 err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl);
100 if (!err) 103 if (!err)
101 __dev_set_rx_mode(dev); 104 __dev_set_rx_mode(dev);
105 netif_addr_unlock(dev);
102 netif_tx_unlock_bh(dev); 106 netif_tx_unlock_bh(dev);
103 return err; 107 return err;
104} 108}
@@ -120,10 +124,12 @@ int dev_mc_sync(struct net_device *to, struct net_device *from)
120 int err = 0; 124 int err = 0;
121 125
122 netif_tx_lock_bh(to); 126 netif_tx_lock_bh(to);
127 netif_addr_lock(to);
123 err = __dev_addr_sync(&to->mc_list, &to->mc_count, 128 err = __dev_addr_sync(&to->mc_list, &to->mc_count,
124 &from->mc_list, &from->mc_count); 129 &from->mc_list, &from->mc_count);
125 if (!err) 130 if (!err)
126 __dev_set_rx_mode(to); 131 __dev_set_rx_mode(to);
132 netif_addr_unlock(to);
127 netif_tx_unlock_bh(to); 133 netif_tx_unlock_bh(to);
128 134
129 return err; 135 return err;
@@ -144,13 +150,17 @@ EXPORT_SYMBOL(dev_mc_sync);
144void dev_mc_unsync(struct net_device *to, struct net_device *from) 150void dev_mc_unsync(struct net_device *to, struct net_device *from)
145{ 151{
146 netif_tx_lock_bh(from); 152 netif_tx_lock_bh(from);
153 netif_addr_lock(from);
147 netif_tx_lock_bh(to); 154 netif_tx_lock_bh(to);
155 netif_addr_lock(to);
148 156
149 __dev_addr_unsync(&to->mc_list, &to->mc_count, 157 __dev_addr_unsync(&to->mc_list, &to->mc_count,
150 &from->mc_list, &from->mc_count); 158 &from->mc_list, &from->mc_count);
151 __dev_set_rx_mode(to); 159 __dev_set_rx_mode(to);
152 160
161 netif_addr_unlock(to);
153 netif_tx_unlock_bh(to); 162 netif_tx_unlock_bh(to);
163 netif_addr_unlock(from);
154 netif_tx_unlock_bh(from); 164 netif_tx_unlock_bh(from);
155} 165}
156EXPORT_SYMBOL(dev_mc_unsync); 166EXPORT_SYMBOL(dev_mc_unsync);
@@ -165,6 +175,7 @@ static int dev_mc_seq_show(struct seq_file *seq, void *v)
165 return 0; 175 return 0;
166 176
167 netif_tx_lock_bh(dev); 177 netif_tx_lock_bh(dev);
178 netif_addr_lock(dev);
168 for (m = dev->mc_list; m; m = m->next) { 179 for (m = dev->mc_list; m; m = m->next) {
169 int i; 180 int i;
170 181
@@ -176,6 +187,7 @@ static int dev_mc_seq_show(struct seq_file *seq, void *v)
176 187
177 seq_putc(seq, '\n'); 188 seq_putc(seq, '\n');
178 } 189 }
190 netif_addr_unlock(dev);
179 netif_tx_unlock_bh(dev); 191 netif_tx_unlock_bh(dev);
180 return 0; 192 return 0;
181} 193}
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 36859e794928..095b7d928d64 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -292,7 +292,9 @@ static int ieee80211_open(struct net_device *dev)
292 local->fif_other_bss++; 292 local->fif_other_bss++;
293 293
294 netif_tx_lock_bh(local->mdev); 294 netif_tx_lock_bh(local->mdev);
295 netif_addr_lock(local->mdev);
295 ieee80211_configure_filter(local); 296 ieee80211_configure_filter(local);
297 netif_addr_unlock(local->mdev);
296 netif_tx_unlock_bh(local->mdev); 298 netif_tx_unlock_bh(local->mdev);
297 break; 299 break;
298 case IEEE80211_IF_TYPE_STA: 300 case IEEE80211_IF_TYPE_STA:
@@ -491,7 +493,9 @@ static int ieee80211_stop(struct net_device *dev)
491 local->fif_other_bss--; 493 local->fif_other_bss--;
492 494
493 netif_tx_lock_bh(local->mdev); 495 netif_tx_lock_bh(local->mdev);
496 netif_addr_lock(local->mdev);
494 ieee80211_configure_filter(local); 497 ieee80211_configure_filter(local);
498 netif_addr_unlock(local->mdev);
495 netif_tx_unlock_bh(local->mdev); 499 netif_tx_unlock_bh(local->mdev);
496 break; 500 break;
497 case IEEE80211_IF_TYPE_MESH_POINT: 501 case IEEE80211_IF_TYPE_MESH_POINT:
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 8f51375317dd..1232ba25e1e9 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3869,6 +3869,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw)
3869 3869
3870 3870
3871 netif_tx_lock_bh(local->mdev); 3871 netif_tx_lock_bh(local->mdev);
3872 netif_addr_lock(local->mdev);
3872 local->filter_flags &= ~FIF_BCN_PRBRESP_PROMISC; 3873 local->filter_flags &= ~FIF_BCN_PRBRESP_PROMISC;
3873 local->ops->configure_filter(local_to_hw(local), 3874 local->ops->configure_filter(local_to_hw(local),
3874 FIF_BCN_PRBRESP_PROMISC, 3875 FIF_BCN_PRBRESP_PROMISC,
@@ -3876,6 +3877,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw)
3876 local->mdev->mc_count, 3877 local->mdev->mc_count,
3877 local->mdev->mc_list); 3878 local->mdev->mc_list);
3878 3879
3880 netif_addr_unlock(local->mdev);
3879 netif_tx_unlock_bh(local->mdev); 3881 netif_tx_unlock_bh(local->mdev);
3880 3882
3881 rcu_read_lock(); 3883 rcu_read_lock();
@@ -4063,12 +4065,14 @@ static int ieee80211_sta_start_scan(struct net_device *dev,
4063 local->scan_dev = dev; 4065 local->scan_dev = dev;
4064 4066
4065 netif_tx_lock_bh(local->mdev); 4067 netif_tx_lock_bh(local->mdev);
4068 netif_addr_lock(local->mdev);
4066 local->filter_flags |= FIF_BCN_PRBRESP_PROMISC; 4069 local->filter_flags |= FIF_BCN_PRBRESP_PROMISC;
4067 local->ops->configure_filter(local_to_hw(local), 4070 local->ops->configure_filter(local_to_hw(local),
4068 FIF_BCN_PRBRESP_PROMISC, 4071 FIF_BCN_PRBRESP_PROMISC,
4069 &local->filter_flags, 4072 &local->filter_flags,
4070 local->mdev->mc_count, 4073 local->mdev->mc_count,
4071 local->mdev->mc_list); 4074 local->mdev->mc_list);
4075 netif_addr_unlock(local->mdev);
4072 netif_tx_unlock_bh(local->mdev); 4076 netif_tx_unlock_bh(local->mdev);
4073 4077
4074 /* TODO: start scan as soon as all nullfunc frames are ACKed */ 4078 /* TODO: start scan as soon as all nullfunc frames are ACKed */