aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/cfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r--net/mac80211/cfg.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 5eab1325a0f6..95bf3d5d009f 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -953,26 +953,36 @@ static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev,
953 953
954static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) 954static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
955{ 955{
956 struct ieee80211_sub_if_data *sdata, *vlan; 956 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
957 struct beacon_data *old; 957 struct ieee80211_sub_if_data *vlan;
958 958 struct ieee80211_local *local = sdata->local;
959 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 959 struct beacon_data *old_beacon;
960 struct probe_resp *old_probe_resp;
960 961
961 old = rtnl_dereference(sdata->u.ap.beacon); 962 old_beacon = rtnl_dereference(sdata->u.ap.beacon);
962 if (!old) 963 if (!old_beacon)
963 return -ENOENT; 964 return -ENOENT;
965 old_probe_resp = rtnl_dereference(sdata->u.ap.probe_resp);
964 966
967 /* turn off carrier for this interface and dependent VLANs */
965 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) 968 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
966 netif_carrier_off(vlan->dev); 969 netif_carrier_off(vlan->dev);
967 netif_carrier_off(dev); 970 netif_carrier_off(dev);
968 971
972 /* remove beacon and probe response */
969 RCU_INIT_POINTER(sdata->u.ap.beacon, NULL); 973 RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
974 RCU_INIT_POINTER(sdata->u.ap.probe_resp, NULL);
975 kfree_rcu(old_beacon, rcu_head);
976 if (old_probe_resp)
977 kfree_rcu(old_probe_resp, rcu_head);
970 978
971 kfree_rcu(old, rcu_head); 979 sta_info_flush(local, sdata);
972
973 sta_info_flush(sdata->local, sdata);
974 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); 980 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
975 981
982 /* free all potentially still buffered bcast frames */
983 local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps.bc_buf);
984 skb_queue_purge(&sdata->u.ap.ps.bc_buf);
985
976 ieee80211_vif_release_channel(sdata); 986 ieee80211_vif_release_channel(sdata);
977 987
978 return 0; 988 return 0;