aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorEliad Peller <eliad@wizery.com>2011-06-13 05:47:30 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-06-17 14:22:18 -0400
commitb856439b1b54358e580aaee5dbe683af5ada9403 (patch)
treedc38beee0a1585693fa228e33646dee5a37f456d /net/mac80211
parenteb40e3e8bb453519ae17d42e7cab6bdd2b4b9fc5 (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.h10
-rw-r--r--net/mac80211/driver-trace.h6
-rw-r--r--net/mac80211/scan.c37
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
221static 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
221static inline int 231static inline int
222drv_sched_scan_start(struct ieee80211_local *local, 232drv_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
463DEFINE_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
463DEFINE_EVENT(local_sdata_evt, drv_sched_scan_start, 469DEFINE_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 */
822void ieee80211_scan_cancel(struct ieee80211_local *local) 822void 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);
860out:
856 mutex_unlock(&local->mtx); 861 mutex_unlock(&local->mtx);
857} 862}
858 863