Commit 4136c4224ccf1907d309e1cdfaefef9da97dbc5e
Committed by
John W. Linville
1 parent
e229f844d7
Exists in
master
and in
7 other branches
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
net/mac80211/main.c
net/mac80211/pm.c
... | ... | @@ -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); |
net/mac80211/scan.c
... | ... | @@ -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 | } |