aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-10-25 13:02:42 -0400
committerJohannes Berg <johannes.berg@intel.com>2012-10-26 06:57:01 -0400
commit7b20b8e8d70a0f4f18c254b42e5b157f93731e9f (patch)
tree1f719c47aeba588532580ce1663e1cf9c1f0c336 /net
parent1df332e82d0facc6b236957f1a5691b550b4e1f1 (diff)
mac80211: move AP teardown code to correct place
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>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/cfg.c28
-rw-r--r--net/mac80211/iface.c19
2 files changed, 19 insertions, 28 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;
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index c50cf6b9e28d..944c6cf53eb7 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -744,31 +744,12 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
744 /* APs need special treatment */ 744 /* APs need special treatment */
745 if (sdata->vif.type == NL80211_IFTYPE_AP) { 745 if (sdata->vif.type == NL80211_IFTYPE_AP) {
746 struct ieee80211_sub_if_data *vlan, *tmpsdata; 746 struct ieee80211_sub_if_data *vlan, *tmpsdata;
747 struct beacon_data *old_beacon =
748 rtnl_dereference(sdata->u.ap.beacon);
749 struct probe_resp *old_probe_resp =
750 rtnl_dereference(sdata->u.ap.probe_resp);
751
752 /* sdata_running will return false, so this will disable */
753 ieee80211_bss_info_change_notify(sdata,
754 BSS_CHANGED_BEACON_ENABLED);
755
756 /* remove beacon and probe response */
757 RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
758 RCU_INIT_POINTER(sdata->u.ap.probe_resp, NULL);
759 synchronize_rcu();
760 kfree(old_beacon);
761 kfree(old_probe_resp);
762 747
763 /* down all dependent devices, that is VLANs */ 748 /* down all dependent devices, that is VLANs */
764 list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, 749 list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans,
765 u.vlan.list) 750 u.vlan.list)
766 dev_close(vlan->dev); 751 dev_close(vlan->dev);
767 WARN_ON(!list_empty(&sdata->u.ap.vlans)); 752 WARN_ON(!list_empty(&sdata->u.ap.vlans));
768
769 /* free all potentially still buffered bcast frames */
770 local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps.bc_buf);
771 skb_queue_purge(&sdata->u.ap.ps.bc_buf);
772 } else if (sdata->vif.type == NL80211_IFTYPE_STATION) { 753 } else if (sdata->vif.type == NL80211_IFTYPE_STATION) {
773 ieee80211_mgd_stop(sdata); 754 ieee80211_mgd_stop(sdata);
774 } 755 }