Commit 4136c4224ccf1907d309e1cdfaefef9da97dbc5e

Authored by Stanislaw Gruszka
Committed by John W. Linville
1 parent e229f844d7

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>

Showing 3 changed files with 27 additions and 14 deletions Side-by-side Diff

... ... @@ -307,8 +307,7 @@
307 307 mutex_unlock(&local->mtx);
308 308  
309 309 rtnl_lock();
310   - if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)))
311   - ieee80211_scan_cancel(local);
  310 + ieee80211_scan_cancel(local);
312 311 ieee80211_reconfig(local);
313 312 rtnl_unlock();
314 313 }
... ... @@ -12,8 +12,7 @@
12 12 struct ieee80211_sub_if_data *sdata;
13 13 struct sta_info *sta;
14 14  
15   - if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)))
16   - ieee80211_scan_cancel(local);
  15 + ieee80211_scan_cancel(local);
17 16  
18 17 ieee80211_stop_queues_by_reason(hw,
19 18 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
... ... @@ -793,25 +793,40 @@
793 793 return ret;
794 794 }
795 795  
  796 +/*
  797 + * Only call this function when a scan can't be queued -- under RTNL.
  798 + */
796 799 void ieee80211_scan_cancel(struct ieee80211_local *local)
797 800 {
798   - bool abortscan;
799   - bool finish = false;
  801 + bool abortscan, finish;
800 802  
801   - cancel_delayed_work_sync(&local->scan_work);
802   -
803 803 /*
804   - * Only call this function when a scan can't be
805   - * queued -- mostly at suspend under RTNL.
  804 + * We are only canceling software scan, or deferred scan that was not
  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 819 mutex_lock(&local->mtx);
808   - abortscan = test_bit(SCAN_SW_SCANNING, &local->scanning) ||
809   - (!local->scanning && local->scan_req);
  820 + abortscan = local->scan_req && !test_bit(SCAN_HW_SCANNING, &local->scanning);
810 821 if (abortscan)
811 822 finish = __ieee80211_scan_completed(&local->hw, true, false);
812 823 mutex_unlock(&local->mtx);
813 824  
814   - if (finish)
815   - __ieee80211_scan_completed_finish(&local->hw, false);
  825 + if (abortscan) {
  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 }