diff options
author | Johannes Berg <johannes.berg@intel.com> | 2012-07-06 15:55:11 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2012-07-12 06:10:43 -0400 |
commit | 5260a5b2c3524f198ea062fe0a6a4faa724e6a9d (patch) | |
tree | 9524bf3dbcb65b6a0125e6a276e313527fd4d4d2 /net | |
parent | e2fd5dbc1c7031be5b5de043bcc0a18c7a59a68a (diff) |
mac80211: track scheduled scan virtual interface
Instead of tracking whether or not we're in a
scheduled scan, track the virtual interface
(sdata) in an RCU-protected pointer to make it
usable from RX to check the MAC address.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/main.c | 3 | ||||
-rw-r--r-- | net/mac80211/rx.c | 4 | ||||
-rw-r--r-- | net/mac80211/scan.c | 20 |
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]); |
976 | out: | 976 | out: |
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 | } |
1000 | out: | 1000 | out: |
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 | ||