aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/iface.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/iface.c')
-rw-r--r--net/mac80211/iface.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 6b631c049eba..9df26adb864a 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -777,10 +777,12 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
777 int i, flushed; 777 int i, flushed;
778 struct ps_data *ps; 778 struct ps_data *ps;
779 struct cfg80211_chan_def chandef; 779 struct cfg80211_chan_def chandef;
780 bool cancel_scan;
780 781
781 clear_bit(SDATA_STATE_RUNNING, &sdata->state); 782 clear_bit(SDATA_STATE_RUNNING, &sdata->state);
782 783
783 if (rcu_access_pointer(local->scan_sdata) == sdata) 784 cancel_scan = rcu_access_pointer(local->scan_sdata) == sdata;
785 if (cancel_scan)
784 ieee80211_scan_cancel(local); 786 ieee80211_scan_cancel(local);
785 787
786 /* 788 /*
@@ -911,6 +913,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
911 list_del(&sdata->u.vlan.list); 913 list_del(&sdata->u.vlan.list);
912 mutex_unlock(&local->mtx); 914 mutex_unlock(&local->mtx);
913 RCU_INIT_POINTER(sdata->vif.chanctx_conf, NULL); 915 RCU_INIT_POINTER(sdata->vif.chanctx_conf, NULL);
916 /* see comment in the default case below */
917 ieee80211_free_keys(sdata, true);
914 /* no need to tell driver */ 918 /* no need to tell driver */
915 break; 919 break;
916 case NL80211_IFTYPE_MONITOR: 920 case NL80211_IFTYPE_MONITOR:
@@ -936,17 +940,16 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
936 /* 940 /*
937 * When we get here, the interface is marked down. 941 * When we get here, the interface is marked down.
938 * Free the remaining keys, if there are any 942 * Free the remaining keys, if there are any
939 * (shouldn't be, except maybe in WDS mode?) 943 * (which can happen in AP mode if userspace sets
944 * keys before the interface is operating, and maybe
945 * also in WDS mode)
940 * 946 *
941 * Force the key freeing to always synchronize_net() 947 * Force the key freeing to always synchronize_net()
942 * to wait for the RX path in case it is using this 948 * to wait for the RX path in case it is using this
943 * interface enqueuing frames * at this very time on 949 * interface enqueuing frames at this very time on
944 * another CPU. 950 * another CPU.
945 */ 951 */
946 ieee80211_free_keys(sdata, true); 952 ieee80211_free_keys(sdata, true);
947
948 /* fall through */
949 case NL80211_IFTYPE_AP:
950 skb_queue_purge(&sdata->skb_queue); 953 skb_queue_purge(&sdata->skb_queue);
951 } 954 }
952 955
@@ -1004,6 +1007,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
1004 1007
1005 ieee80211_recalc_ps(local, -1); 1008 ieee80211_recalc_ps(local, -1);
1006 1009
1010 if (cancel_scan)
1011 flush_delayed_work(&local->scan_work);
1012
1007 if (local->open_count == 0) { 1013 if (local->open_count == 0) {
1008 ieee80211_stop_device(local); 1014 ieee80211_stop_device(local);
1009 1015