aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 e3717092115..915ecf87e4a 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 e3e2bce3bb4..e37355193ed 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 6964a459817..4dbef714d94 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}