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 6c655b6..6614d4f 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 9dd8d25..5e76dd1 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 5e3d476..3320f7d 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;