mac80211: disable beacons before removing the associated interface
authorBob Copeland <me@bobcopeland.com>
Wed, 29 Jul 2009 08:13:03 +0000 (10:13 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 4 Aug 2009 20:43:23 +0000 (16:43 -0400)
When downing interfaces, it's a good idea to tell the driver to
stop sending beacons; that way the driver doesn't need special
code in ops->remove_interface() when it should already handle the
case in bss_info_changed().

This fixes a potential crash with at least ath5k since the vif
pointer will be nullified while beacon interrupts are still active.

Signed-off-by: Bob Copeland <me@bobcopeland.com>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
net/mac80211/iface.c
net/mac80211/main.c
net/mac80211/pm.c

index 6c655b6547fb7ec5eb71a7cb933eca5a545bab93..6614d4ff273d2ea9228a9c15c28f833f984c893c 100644 (file)
@@ -522,6 +522,16 @@ static int ieee80211_stop(struct net_device *dev)
                                ieee80211_scan_completed(&local->hw, true);
                }
 
+               /*
+                * Disable beaconing for AP and mesh, IBSS can't
+                * still be joined to a network at this point.
+                */
+               if (sdata->vif.type == NL80211_IFTYPE_AP ||
+                   sdata->vif.type == NL80211_IFTYPE_MESH_POINT) {
+                       ieee80211_bss_info_change_notify(sdata,
+                               BSS_CHANGED_BEACON_ENABLED);
+               }
+
                conf.vif = &sdata->vif;
                conf.type = sdata->vif.type;
                conf.mac_addr = dev->dev_addr;
index 9dd8d25611e0e67a63eb65609b0682db23894080..5e76dd1daf712aaf6b9914ffa5fd12302d1eff6e 100644 (file)
@@ -198,7 +198,8 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
        }
 
        if (changed & BSS_CHANGED_BEACON_ENABLED) {
-               if (test_bit(SCAN_SW_SCANNING, &local->scanning)) {
+               if (local->quiescing || !netif_running(sdata->dev) ||
+                   test_bit(SCAN_SW_SCANNING, &local->scanning)) {
                        sdata->vif.bss_conf.enable_beacon = false;
                } else {
                        /*
index 5e3d476972f916f741ea44d5c1d62fb60acf83dc..3320f7daaf257aa031a16f8894e26eb8697554c6 100644 (file)
@@ -96,6 +96,10 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
                if (!netif_running(sdata->dev))
                        continue;
 
+               /* disable beaconing */
+               ieee80211_bss_info_change_notify(sdata,
+                       BSS_CHANGED_BEACON_ENABLED);
+
                conf.vif = &sdata->vif;
                conf.type = sdata->vif.type;
                conf.mac_addr = sdata->dev->dev_addr;