|
@@ -1735,7 +1735,6 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,
|
|
|
}
|
|
|
/* flush any remaining work */
|
|
|
wl1271_debug(DEBUG_MAC80211, "flushing remaining works");
|
|
|
- flush_delayed_work(&wl->scan_complete_work);
|
|
|
|
|
|
/*
|
|
|
* disable and re-enable interrupts in order to flush
|
|
@@ -2786,6 +2785,44 @@ out:
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+static void wl1271_op_cancel_hw_scan(struct ieee80211_hw *hw,
|
|
|
+ struct ieee80211_vif *vif)
|
|
|
+{
|
|
|
+ struct wl1271 *wl = hw->priv;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ wl1271_debug(DEBUG_MAC80211, "mac80211 cancel hw scan");
|
|
|
+
|
|
|
+ mutex_lock(&wl->mutex);
|
|
|
+
|
|
|
+ if (wl->state == WL1271_STATE_OFF)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ if (wl->scan.state == WL1271_SCAN_STATE_IDLE)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ ret = wl1271_ps_elp_wakeup(wl);
|
|
|
+ if (ret < 0)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ if (wl->scan.state != WL1271_SCAN_STATE_DONE) {
|
|
|
+ ret = wl1271_scan_stop(wl);
|
|
|
+ if (ret < 0)
|
|
|
+ goto out_sleep;
|
|
|
+ }
|
|
|
+ wl->scan.state = WL1271_SCAN_STATE_IDLE;
|
|
|
+ memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
|
|
|
+ wl->scan.req = NULL;
|
|
|
+ ieee80211_scan_completed(wl->hw, true);
|
|
|
+
|
|
|
+out_sleep:
|
|
|
+ wl1271_ps_elp_sleep(wl);
|
|
|
+out:
|
|
|
+ mutex_unlock(&wl->mutex);
|
|
|
+
|
|
|
+ cancel_delayed_work_sync(&wl->scan_complete_work);
|
|
|
+}
|
|
|
+
|
|
|
static int wl1271_op_sched_scan_start(struct ieee80211_hw *hw,
|
|
|
struct ieee80211_vif *vif,
|
|
|
struct cfg80211_sched_scan_request *req,
|
|
@@ -3969,6 +4006,7 @@ static const struct ieee80211_ops wl1271_ops = {
|
|
|
.tx = wl1271_op_tx,
|
|
|
.set_key = wl1271_op_set_key,
|
|
|
.hw_scan = wl1271_op_hw_scan,
|
|
|
+ .cancel_hw_scan = wl1271_op_cancel_hw_scan,
|
|
|
.sched_scan_start = wl1271_op_sched_scan_start,
|
|
|
.sched_scan_stop = wl1271_op_sched_scan_stop,
|
|
|
.bss_info_changed = wl1271_op_bss_info_changed,
|