diff options
author | Eliad Peller <eliad@wizery.com> | 2011-06-13 05:47:30 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-06-17 14:22:18 -0400 |
commit | b856439b1b54358e580aaee5dbe683af5ada9403 (patch) | |
tree | dc38beee0a1585693fa228e33646dee5a37f456d /net/mac80211 | |
parent | eb40e3e8bb453519ae17d42e7cab6bdd2b4b9fc5 (diff) |
mac80211: add cancel_hw_scan() callback
When suspending, __ieee80211_suspend() calls ieee80211_scan_cancel(),
which will only cancel sw scan. In order to cancel hw scan, the
low-level driver has to cancel it in the suspend() callback. however,
this is too late, as a new scan_work will be enqueued (while the driver
is going into suspend).
Add a new cancel_hw_scan() callback, asking the driver to cancel an
active hw scan, and call it in ieee80211_scan_cancel().
Signed-off-by: Eliad Peller <eliad@wizery.com>
Reviewed-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/driver-ops.h | 10 | ||||
-rw-r--r-- | net/mac80211/driver-trace.h | 6 | ||||
-rw-r--r-- | net/mac80211/scan.c | 37 |
3 files changed, 37 insertions, 16 deletions
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index eebf7a67daf7..0e7e4268ddf6 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -218,6 +218,16 @@ static inline int drv_hw_scan(struct ieee80211_local *local, | |||
218 | return ret; | 218 | return ret; |
219 | } | 219 | } |
220 | 220 | ||
221 | static inline void drv_cancel_hw_scan(struct ieee80211_local *local, | ||
222 | struct ieee80211_sub_if_data *sdata) | ||
223 | { | ||
224 | might_sleep(); | ||
225 | |||
226 | trace_drv_cancel_hw_scan(local, sdata); | ||
227 | local->ops->cancel_hw_scan(&local->hw, &sdata->vif); | ||
228 | trace_drv_return_void(local); | ||
229 | } | ||
230 | |||
221 | static inline int | 231 | static inline int |
222 | drv_sched_scan_start(struct ieee80211_local *local, | 232 | drv_sched_scan_start(struct ieee80211_local *local, |
223 | struct ieee80211_sub_if_data *sdata, | 233 | struct ieee80211_sub_if_data *sdata, |
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index ed9edcbd9aa5..3cb6795e926d 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h | |||
@@ -460,6 +460,12 @@ DEFINE_EVENT(local_sdata_evt, drv_hw_scan, | |||
460 | TP_ARGS(local, sdata) | 460 | TP_ARGS(local, sdata) |
461 | ); | 461 | ); |
462 | 462 | ||
463 | DEFINE_EVENT(local_sdata_evt, drv_cancel_hw_scan, | ||
464 | TP_PROTO(struct ieee80211_local *local, | ||
465 | struct ieee80211_sub_if_data *sdata), | ||
466 | TP_ARGS(local, sdata) | ||
467 | ); | ||
468 | |||
463 | DEFINE_EVENT(local_sdata_evt, drv_sched_scan_start, | 469 | DEFINE_EVENT(local_sdata_evt, drv_sched_scan_start, |
464 | TP_PROTO(struct ieee80211_local *local, | 470 | TP_PROTO(struct ieee80211_local *local, |
465 | struct ieee80211_sub_if_data *sdata), | 471 | struct ieee80211_sub_if_data *sdata), |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 58ffa7d069c7..1758b463c583 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -821,10 +821,8 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, | |||
821 | */ | 821 | */ |
822 | void ieee80211_scan_cancel(struct ieee80211_local *local) | 822 | void ieee80211_scan_cancel(struct ieee80211_local *local) |
823 | { | 823 | { |
824 | bool abortscan; | ||
825 | |||
826 | /* | 824 | /* |
827 | * We are only canceling software scan, or deferred scan that was not | 825 | * We are canceling software scan, or deferred scan that was not |
828 | * yet really started (see __ieee80211_start_scan ). | 826 | * yet really started (see __ieee80211_start_scan ). |
829 | * | 827 | * |
830 | * Regarding hardware scan: | 828 | * Regarding hardware scan: |
@@ -836,23 +834,30 @@ void ieee80211_scan_cancel(struct ieee80211_local *local) | |||
836 | * - we can not cancel scan_work since driver can schedule it | 834 | * - we can not cancel scan_work since driver can schedule it |
837 | * by ieee80211_scan_completed(..., true) to finish scan | 835 | * by ieee80211_scan_completed(..., true) to finish scan |
838 | * | 836 | * |
839 | * Hence low lever driver is responsible for canceling HW scan. | 837 | * Hence we only call the cancel_hw_scan() callback, but the low-level |
838 | * driver is still responsible for calling ieee80211_scan_completed() | ||
839 | * after the scan was completed/aborted. | ||
840 | */ | 840 | */ |
841 | 841 | ||
842 | mutex_lock(&local->mtx); | 842 | mutex_lock(&local->mtx); |
843 | abortscan = local->scan_req && !test_bit(SCAN_HW_SCANNING, &local->scanning); | 843 | if (!local->scan_req) |
844 | if (abortscan) { | 844 | goto out; |
845 | /* | 845 | |
846 | * The scan is canceled, but stop work from being pending. | 846 | if (test_bit(SCAN_HW_SCANNING, &local->scanning)) { |
847 | * | 847 | if (local->ops->cancel_hw_scan) |
848 | * If the work is currently running, it must be blocked on | 848 | drv_cancel_hw_scan(local, local->scan_sdata); |
849 | * the mutex, but we'll set scan_sdata = NULL and it'll | 849 | goto out; |
850 | * simply exit once it acquires the mutex. | ||
851 | */ | ||
852 | cancel_delayed_work(&local->scan_work); | ||
853 | /* and clean up */ | ||
854 | __ieee80211_scan_completed(&local->hw, true, false); | ||
855 | } | 850 | } |
851 | |||
852 | /* | ||
853 | * If the work is currently running, it must be blocked on | ||
854 | * the mutex, but we'll set scan_sdata = NULL and it'll | ||
855 | * simply exit once it acquires the mutex. | ||
856 | */ | ||
857 | cancel_delayed_work(&local->scan_work); | ||
858 | /* and clean up */ | ||
859 | __ieee80211_scan_completed(&local->hw, true, false); | ||
860 | out: | ||
856 | mutex_unlock(&local->mtx); | 861 | mutex_unlock(&local->mtx); |
857 | } | 862 | } |
858 | 863 | ||