aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/main.c3
-rw-r--r--net/mac80211/rx.c4
-rw-r--r--net/mac80211/scan.c20
4 files changed, 15 insertions, 14 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 9f2534a41243..e973a8f96c9b 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -965,9 +965,9 @@ struct ieee80211_local {
965 int scan_channel_idx; 965 int scan_channel_idx;
966 int scan_ies_len; 966 int scan_ies_len;
967 967
968 bool sched_scanning;
969 struct ieee80211_sched_scan_ies sched_scan_ies; 968 struct ieee80211_sched_scan_ies sched_scan_ies;
970 struct work_struct sched_scan_stopped_work; 969 struct work_struct sched_scan_stopped_work;
970 struct ieee80211_sub_if_data __rcu *sched_scan_sdata;
971 971
972 unsigned long leave_oper_channel_time; 972 unsigned long leave_oper_channel_time;
973 enum mac80211_scan_state next_scan_state; 973 enum mac80211_scan_state next_scan_state;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index c794101f8987..c26e231c733a 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -322,7 +322,8 @@ static void ieee80211_restart_work(struct work_struct *work)
322 322
323 mutex_lock(&local->mtx); 323 mutex_lock(&local->mtx);
324 WARN(test_bit(SCAN_HW_SCANNING, &local->scanning) || 324 WARN(test_bit(SCAN_HW_SCANNING, &local->scanning) ||
325 local->sched_scanning, 325 rcu_dereference_protected(local->sched_scan_sdata,
326 lockdep_is_held(&local->mtx)),
326 "%s called with hardware scan in progress\n", __func__); 327 "%s called with hardware scan in progress\n", __func__);
327 mutex_unlock(&local->mtx); 328 mutex_unlock(&local->mtx);
328 329
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index f8cf9e7477a3..17a56151be7f 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -421,13 +421,13 @@ ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx)
421 struct sk_buff *skb = rx->skb; 421 struct sk_buff *skb = rx->skb;
422 422
423 if (likely(!(status->rx_flags & IEEE80211_RX_IN_SCAN) && 423 if (likely(!(status->rx_flags & IEEE80211_RX_IN_SCAN) &&
424 !local->sched_scanning)) 424 !rcu_access_pointer(local->sched_scan_sdata)))
425 return RX_CONTINUE; 425 return RX_CONTINUE;
426 426
427 if (test_bit(SCAN_HW_SCANNING, &local->scanning) || 427 if (test_bit(SCAN_HW_SCANNING, &local->scanning) ||
428 test_bit(SCAN_SW_SCANNING, &local->scanning) || 428 test_bit(SCAN_SW_SCANNING, &local->scanning) ||
429 test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) || 429 test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) ||
430 local->sched_scanning) 430 rcu_access_pointer(local->sched_scan_sdata))
431 return ieee80211_scan_rx(rx->sdata, skb); 431 return ieee80211_scan_rx(rx->sdata, skb);
432 432
433 /* scanning finished during invoking of handlers */ 433 /* scanning finished during invoking of handlers */
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 704dcf847761..a619c1ea9bd5 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -930,9 +930,9 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
930 struct ieee80211_local *local = sdata->local; 930 struct ieee80211_local *local = sdata->local;
931 int ret, i; 931 int ret, i;
932 932
933 mutex_lock(&sdata->local->mtx); 933 mutex_lock(&local->mtx);
934 934
935 if (local->sched_scanning) { 935 if (rcu_access_pointer(local->sched_scan_sdata)) {
936 ret = -EBUSY; 936 ret = -EBUSY;
937 goto out; 937 goto out;
938 } 938 }
@@ -966,7 +966,7 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
966 ret = drv_sched_scan_start(local, sdata, req, 966 ret = drv_sched_scan_start(local, sdata, req,
967 &local->sched_scan_ies); 967 &local->sched_scan_ies);
968 if (ret == 0) { 968 if (ret == 0) {
969 local->sched_scanning = true; 969 rcu_assign_pointer(local->sched_scan_sdata, sdata);
970 goto out; 970 goto out;
971 } 971 }
972 972
@@ -974,7 +974,7 @@ out_free:
974 while (i > 0) 974 while (i > 0)
975 kfree(local->sched_scan_ies.ie[--i]); 975 kfree(local->sched_scan_ies.ie[--i]);
976out: 976out:
977 mutex_unlock(&sdata->local->mtx); 977 mutex_unlock(&local->mtx);
978 return ret; 978 return ret;
979} 979}
980 980
@@ -983,22 +983,22 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata)
983 struct ieee80211_local *local = sdata->local; 983 struct ieee80211_local *local = sdata->local;
984 int ret = 0, i; 984 int ret = 0, i;
985 985
986 mutex_lock(&sdata->local->mtx); 986 mutex_lock(&local->mtx);
987 987
988 if (!local->ops->sched_scan_stop) { 988 if (!local->ops->sched_scan_stop) {
989 ret = -ENOTSUPP; 989 ret = -ENOTSUPP;
990 goto out; 990 goto out;
991 } 991 }
992 992
993 if (local->sched_scanning) { 993 if (rcu_access_pointer(local->sched_scan_sdata)) {
994 for (i = 0; i < IEEE80211_NUM_BANDS; i++) 994 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
995 kfree(local->sched_scan_ies.ie[i]); 995 kfree(local->sched_scan_ies.ie[i]);
996 996
997 drv_sched_scan_stop(local, sdata); 997 drv_sched_scan_stop(local, sdata);
998 local->sched_scanning = false; 998 rcu_assign_pointer(local->sched_scan_sdata, NULL);
999 } 999 }
1000out: 1000out:
1001 mutex_unlock(&sdata->local->mtx); 1001 mutex_unlock(&local->mtx);
1002 1002
1003 return ret; 1003 return ret;
1004} 1004}
@@ -1022,7 +1022,7 @@ void ieee80211_sched_scan_stopped_work(struct work_struct *work)
1022 1022
1023 mutex_lock(&local->mtx); 1023 mutex_lock(&local->mtx);
1024 1024
1025 if (!local->sched_scanning) { 1025 if (!rcu_access_pointer(local->sched_scan_sdata)) {
1026 mutex_unlock(&local->mtx); 1026 mutex_unlock(&local->mtx);
1027 return; 1027 return;
1028 } 1028 }
@@ -1030,7 +1030,7 @@ void ieee80211_sched_scan_stopped_work(struct work_struct *work)
1030 for (i = 0; i < IEEE80211_NUM_BANDS; i++) 1030 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
1031 kfree(local->sched_scan_ies.ie[i]); 1031 kfree(local->sched_scan_ies.ie[i]);
1032 1032
1033 local->sched_scanning = false; 1033 rcu_assign_pointer(local->sched_scan_sdata, NULL);
1034 1034
1035 mutex_unlock(&local->mtx); 1035 mutex_unlock(&local->mtx);
1036 1036