diff options
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r-- | net/mac80211/cfg.c | 28 |
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 | ||
954 | static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) | 954 | static 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; |