aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorStanislaw Gruszka <sgruszka@redhat.com>2010-10-06 05:22:10 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-10-06 16:30:42 -0400
commit4136c4224ccf1907d309e1cdfaefef9da97dbc5e (patch)
treebe65af6057850d068b7858f5679a00b64fb2e92d /net/mac80211
parente229f844d7223b7063bea1e649203ac521a58fe1 (diff)
mac80211: assure we also cancel deferred scan request
This is partial revert and fix for commit 85f72bc839705294b32b6c16b491c0422f0a71b3 "mac80211: only cancel software-based scans on suspend" When cfg80211 request the scan and mac80211 perform some management work, we defer the scan request. We do not canceling such requests when calling ieee80211_scan_cancel(), because of SCAN_SW_SCANNING bit check just before the call. So fix that problem. Another problem, which commit 85f72bc839705294b32b6c16b491c0422f0a71b3 tries to solve, is we can not cancel HW scan. Hence patch make ieee80211_scan_cancel() ignore HW scan (see code comments). Keeping local->mtx lock assures that the deferred scan will not become "working" HW scan. Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com> Acked-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/main.c3
-rw-r--r--net/mac80211/pm.c3
-rw-r--r--net/mac80211/scan.c35
3 files changed, 27 insertions, 14 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index e3717092115f..915ecf87e4ac 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -307,8 +307,7 @@ static void ieee80211_restart_work(struct work_struct *work)
307 mutex_unlock(&local->mtx); 307 mutex_unlock(&local->mtx);
308 308
309 rtnl_lock(); 309 rtnl_lock();
310 if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning))) 310 ieee80211_scan_cancel(local);
311 ieee80211_scan_cancel(local);
312 ieee80211_reconfig(local); 311 ieee80211_reconfig(local);
313 rtnl_unlock(); 312 rtnl_unlock();
314} 313}
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index e3e2bce3bb41..e37355193ed1 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -12,8 +12,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
12 struct ieee80211_sub_if_data *sdata; 12 struct ieee80211_sub_if_data *sdata;
13 struct sta_info *sta; 13 struct sta_info *sta;
14 14
15 if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning))) 15 ieee80211_scan_cancel(local);
16 ieee80211_scan_cancel(local);
17 16
18 ieee80211_stop_queues_by_reason(hw, 17 ieee80211_stop_queues_by_reason(hw,
19 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 18 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 6964a4598176..4dbef714d946 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -793,24 +793,39 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
793 return ret; 793 return ret;
794} 794}
795 795
796/*
797 * Only call this function when a scan can't be queued -- under RTNL.
798 */
796void ieee80211_scan_cancel(struct ieee80211_local *local) 799void ieee80211_scan_cancel(struct ieee80211_local *local)
797{ 800{
798 bool abortscan; 801 bool abortscan, finish;
799 bool finish = false;
800
801 cancel_delayed_work_sync(&local->scan_work);
802 802
803 /* 803 /*
804 * Only call this function when a scan can't be 804 * We are only canceling software scan, or deferred scan that was not
805 * queued -- mostly at suspend under RTNL. 805 * yet really started (see __ieee80211_start_scan ).
806 *
807 * Regarding hardware scan:
808 * - we can not call __ieee80211_scan_completed() as when
809 * SCAN_HW_SCANNING bit is set this function change
810 * local->hw_scan_req to operate on 5G band, what race with
811 * driver which can use local->hw_scan_req
812 *
813 * - we can not cancel scan_work since driver can schedule it
814 * by ieee80211_scan_completed(..., true) to finish scan
815 *
816 * Hence low lever driver is responsible for canceling HW scan.
806 */ 817 */
818
807 mutex_lock(&local->mtx); 819 mutex_lock(&local->mtx);
808 abortscan = test_bit(SCAN_SW_SCANNING, &local->scanning) || 820 abortscan = local->scan_req && !test_bit(SCAN_HW_SCANNING, &local->scanning);
809 (!local->scanning && local->scan_req);
810 if (abortscan) 821 if (abortscan)
811 finish = __ieee80211_scan_completed(&local->hw, true, false); 822 finish = __ieee80211_scan_completed(&local->hw, true, false);
812 mutex_unlock(&local->mtx); 823 mutex_unlock(&local->mtx);
813 824
814 if (finish) 825 if (abortscan) {
815 __ieee80211_scan_completed_finish(&local->hw, false); 826 /* The scan is canceled, but stop work from being pending */
827 cancel_delayed_work_sync(&local->scan_work);
828 if (finish)
829 __ieee80211_scan_completed_finish(&local->hw, false);
830 }
816} 831}