mac80211: move AP teardown code to correct place
authorJohannes Berg <johannes.berg@intel.com>
Thu, 25 Oct 2012 17:02:42 +0000 (19:02 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 26 Oct 2012 10:57:01 +0000 (12:57 +0200)
Since cfg80211 will now call the explicit stop_ap
operation when an AP interface goes down, move all
teardown code there and remove it from interface
handling. The only thing that needs to stay is the
code to dev_close() all dependent VLANs.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/cfg.c
net/mac80211/iface.c

index 5eab1325a0f6fc3ff2e53df503fc26e366dec14f..95bf3d5d009fdfb1b5dcbc539e8ca0c5b2b4ac41 100644 (file)
@@ -953,26 +953,36 @@ static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev,
 
 static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
 {
-       struct ieee80211_sub_if_data *sdata, *vlan;
-       struct beacon_data *old;
-
-       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       struct ieee80211_sub_if_data *vlan;
+       struct ieee80211_local *local = sdata->local;
+       struct beacon_data *old_beacon;
+       struct probe_resp *old_probe_resp;
 
-       old = rtnl_dereference(sdata->u.ap.beacon);
-       if (!old)
+       old_beacon = rtnl_dereference(sdata->u.ap.beacon);
+       if (!old_beacon)
                return -ENOENT;
+       old_probe_resp = rtnl_dereference(sdata->u.ap.probe_resp);
 
+       /* turn off carrier for this interface and dependent VLANs */
        list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
                netif_carrier_off(vlan->dev);
        netif_carrier_off(dev);
 
+       /* remove beacon and probe response */
        RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
+       RCU_INIT_POINTER(sdata->u.ap.probe_resp, NULL);
+       kfree_rcu(old_beacon, rcu_head);
+       if (old_probe_resp)
+               kfree_rcu(old_probe_resp, rcu_head);
 
-       kfree_rcu(old, rcu_head);
-
-       sta_info_flush(sdata->local, sdata);
+       sta_info_flush(local, sdata);
        ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
 
+       /* free all potentially still buffered bcast frames */
+       local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps.bc_buf);
+       skb_queue_purge(&sdata->u.ap.ps.bc_buf);
+
        ieee80211_vif_release_channel(sdata);
 
        return 0;
index c50cf6b9e28df025a25d56f453633e4f320c8929..944c6cf53eb771f5fa2f8efe554325ed925a193c 100644 (file)
@@ -744,31 +744,12 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
        /* APs need special treatment */
        if (sdata->vif.type == NL80211_IFTYPE_AP) {
                struct ieee80211_sub_if_data *vlan, *tmpsdata;
-               struct beacon_data *old_beacon =
-                       rtnl_dereference(sdata->u.ap.beacon);
-               struct probe_resp *old_probe_resp =
-                       rtnl_dereference(sdata->u.ap.probe_resp);
-
-               /* sdata_running will return false, so this will disable */
-               ieee80211_bss_info_change_notify(sdata,
-                                                BSS_CHANGED_BEACON_ENABLED);
-
-               /* remove beacon and probe response */
-               RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
-               RCU_INIT_POINTER(sdata->u.ap.probe_resp, NULL);
-               synchronize_rcu();
-               kfree(old_beacon);
-               kfree(old_probe_resp);
 
                /* down all dependent devices, that is VLANs */
                list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans,
                                         u.vlan.list)
                        dev_close(vlan->dev);
                WARN_ON(!list_empty(&sdata->u.ap.vlans));
-
-               /* free all potentially still buffered bcast frames */
-               local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps.bc_buf);
-               skb_queue_purge(&sdata->u.ap.ps.bc_buf);
        } else if (sdata->vif.type == NL80211_IFTYPE_STATION) {
                ieee80211_mgd_stop(sdata);
        }