aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2013-09-16 04:12:07 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-11-12 22:05:30 -0500
commit715a606d73f63e94259e6251565e6e12e3271d0f (patch)
tree2d8dd2d9ff41caf6aa7820b60605bc3aa592baec /net
parent5be794dc4bb66266acc91eb589ace48e82a6c77e (diff)
mac80211: correctly close cancelled scans
commit a754055a1296fcbe6f32de3a5eaca6efb2fd1865 upstream. __ieee80211_scan_completed is called from a worker. This means that the following flow is possible. * driver calls ieee80211_scan_completed * mac80211 cancels the scan (that is already complete) * __ieee80211_scan_completed runs When scan_work will finally run, it will see that the scan hasn't been aborted and might even trigger another scan on another band. This leads to a situation where cfg80211's scan is not done and no further scan can be issued. Fix this by setting a new flag when a HW scan is being cancelled so that no other scan will be triggered. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/ieee80211_i.h3
-rw-r--r--net/mac80211/scan.c19
2 files changed, 22 insertions, 0 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 9ca8e3278cc0..92ef04c72c51 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -842,6 +842,8 @@ struct tpt_led_trigger {
842 * that the scan completed. 842 * that the scan completed.
843 * @SCAN_ABORTED: Set for our scan work function when the driver reported 843 * @SCAN_ABORTED: Set for our scan work function when the driver reported
844 * a scan complete for an aborted scan. 844 * a scan complete for an aborted scan.
845 * @SCAN_HW_CANCELLED: Set for our scan work function when the scan is being
846 * cancelled.
845 */ 847 */
846enum { 848enum {
847 SCAN_SW_SCANNING, 849 SCAN_SW_SCANNING,
@@ -849,6 +851,7 @@ enum {
849 SCAN_ONCHANNEL_SCANNING, 851 SCAN_ONCHANNEL_SCANNING,
850 SCAN_COMPLETED, 852 SCAN_COMPLETED,
851 SCAN_ABORTED, 853 SCAN_ABORTED,
854 SCAN_HW_CANCELLED,
852}; 855};
853 856
854/** 857/**
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 99b103921a4b..eb03337b6545 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -202,6 +202,9 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
202 enum ieee80211_band band; 202 enum ieee80211_band band;
203 int i, ielen, n_chans; 203 int i, ielen, n_chans;
204 204
205 if (test_bit(SCAN_HW_CANCELLED, &local->scanning))
206 return false;
207
205 do { 208 do {
206 if (local->hw_scan_band == IEEE80211_NUM_BANDS) 209 if (local->hw_scan_band == IEEE80211_NUM_BANDS)
207 return false; 210 return false;
@@ -878,7 +881,23 @@ void ieee80211_scan_cancel(struct ieee80211_local *local)
878 if (!local->scan_req) 881 if (!local->scan_req)
879 goto out; 882 goto out;
880 883
884 /*
885 * We have a scan running and the driver already reported completion,
886 * but the worker hasn't run yet or is stuck on the mutex - mark it as
887 * cancelled.
888 */
889 if (test_bit(SCAN_HW_SCANNING, &local->scanning) &&
890 test_bit(SCAN_COMPLETED, &local->scanning)) {
891 set_bit(SCAN_HW_CANCELLED, &local->scanning);
892 goto out;
893 }
894
881 if (test_bit(SCAN_HW_SCANNING, &local->scanning)) { 895 if (test_bit(SCAN_HW_SCANNING, &local->scanning)) {
896 /*
897 * Make sure that __ieee80211_scan_completed doesn't trigger a
898 * scan on another band.
899 */
900 set_bit(SCAN_HW_CANCELLED, &local->scanning);
882 if (local->ops->cancel_hw_scan) 901 if (local->ops->cancel_hw_scan)
883 drv_cancel_hw_scan(local, 902 drv_cancel_hw_scan(local,
884 rcu_dereference_protected(local->scan_sdata, 903 rcu_dereference_protected(local->scan_sdata,