diff options
| author | Maya Erez <qca_merez@qca.qualcomm.com> | 2016-12-06 12:23:04 +0200 |
|---|---|---|
| committer | Maya Erez <merez@codeaurora.org> | 2016-12-08 13:19:32 +0200 |
| commit | 726ec1257623d52cef2fc0ada9890dd60f7d14a4 (patch) | |
| tree | 17690df553e30019ab25574a73c2df0abb980a08 /drivers/net/wireless | |
| parent | d91c63950e459e112068b711a425e946ebdd3c25 (diff) | |
wil6210: add support for abort scan
Implement cfg80211 abort_scan op to allow the upper layer to
abort an ongoing scan request.
In addition, notify wil6210 device on scan abort request instead
of just ignoring the scan response.
Change-Id: Iddd8c0658ded28b07c618ca09d59150238b190a0
Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Git-commit: 035859a5117bc609132c3586b6c6bf4aba72425c
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
Signed-off-by: Maya Erez <merez@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless')
| -rw-r--r-- | drivers/net/wireless/ath/wil6210/cfg80211.c | 31 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/wil6210/main.c | 44 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/wil6210/p2p.c | 10 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/wil6210/wil6210.h | 3 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/wil6210/wmi.c | 17 |
5 files changed, 81 insertions, 24 deletions
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index a629415a81ac..56c7696c2f32 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -554,6 +554,34 @@ out: return rc; } +static void wil_cfg80211_abort_scan(struct wiphy *wiphy, + struct wireless_dev *wdev) +{ + struct wil6210_priv *wil = wiphy_to_wil(wiphy); + + wil_dbg_misc(wil, "wdev=0x%p iftype=%d\n", wdev, wdev->iftype); + + mutex_lock(&wil->mutex); + mutex_lock(&wil->p2p_wdev_mutex); + + if (!wil->scan_request) + goto out; + + if (wdev != wil->scan_request->wdev) { + wil_dbg_misc(wil, "abort scan was called on the wrong iface\n"); + goto out; + } + + if (wil->radio_wdev == wil->p2p_wdev) + wil_p2p_stop_radio_operations(wil); + else + wil_abort_scan(wil, true); + +out: + mutex_unlock(&wil->p2p_wdev_mutex); + mutex_unlock(&wil->mutex); +} + static void wil_print_crypto(struct wil6210_priv *wil, struct cfg80211_crypto_settings *c) { @@ -1504,8 +1532,10 @@ static void wil_cfg80211_stop_p2p_device(struct wiphy *wiphy, wil_dbg_misc(wil, "%s: entered\n", __func__); mutex_lock(&wil->mutex); + mutex_lock(&wil->p2p_wdev_mutex); wil_p2p_stop_radio_operations(wil); p2p->p2p_dev_started = 0; + mutex_unlock(&wil->p2p_wdev_mutex); mutex_unlock(&wil->mutex); } @@ -1541,6 +1571,7 @@ static struct cfg80211_ops wil_cfg80211_ops = { .add_virtual_intf = wil_cfg80211_add_iface, .del_virtual_intf = wil_cfg80211_del_iface, .scan = wil_cfg80211_scan, + .abort_scan = wil_cfg80211_abort_scan, .connect = wil_cfg80211_connect, .disconnect = wil_cfg80211_disconnect, .change_virtual_intf = wil_cfg80211_change_iface, diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index 6ae3c8ce3e99..e7f40032f58c 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -24,6 +24,7 @@ #include "boot_loader.h" #define WAIT_FOR_HALP_VOTE_MS 100 +#define WAIT_FOR_SCAN_ABORT_MS 1000 bool debug_fw; /* = false; */ module_param(debug_fw, bool, S_IRUGO); @@ -814,6 +815,31 @@ static int wil_wait_for_fw_ready(struct wil6210_priv *wil) return 0; } +void wil_abort_scan(struct wil6210_priv *wil, bool sync) +{ + int rc; + + lockdep_assert_held(&wil->p2p_wdev_mutex); + + if (!wil->scan_request) + return; + + wil_dbg_misc(wil, "Abort scan_request 0x%p\n", wil->scan_request); + del_timer_sync(&wil->scan_timer); + mutex_unlock(&wil->p2p_wdev_mutex); + rc = wmi_abort_scan(wil); + if (!rc && sync) + wait_event_interruptible_timeout(wil->wq, !wil->scan_request, + msecs_to_jiffies( + WAIT_FOR_SCAN_ABORT_MS)); + + mutex_lock(&wil->p2p_wdev_mutex); + if (wil->scan_request) { + cfg80211_scan_done(wil->scan_request, true); + wil->scan_request = NULL; + } +} + /* * We reset all the structures, and we reset the UMAC. * After calling this routine, you're expected to reload @@ -866,13 +892,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) mutex_unlock(&wil->wmi_mutex); mutex_lock(&wil->p2p_wdev_mutex); - if (wil->scan_request) { - wil_dbg_misc(wil, "Abort scan_request 0x%p\n", - wil->scan_request); - del_timer_sync(&wil->scan_timer); - cfg80211_scan_done(wil->scan_request, true); - wil->scan_request = NULL; - } + wil_abort_scan(wil, false); mutex_unlock(&wil->p2p_wdev_mutex); wil_mask_irq(wil); @@ -1065,17 +1085,11 @@ int __wil_down(struct wil6210_priv *wil) } wil_enable_irq(wil); - wil_p2p_stop_radio_operations(wil); wil_ftm_stop_operations(wil); mutex_lock(&wil->p2p_wdev_mutex); - if (wil->scan_request) { - wil_dbg_misc(wil, "Abort scan_request 0x%p\n", - wil->scan_request); - del_timer_sync(&wil->scan_timer); - cfg80211_scan_done(wil->scan_request, true); - wil->scan_request = NULL; - } + wil_p2p_stop_radio_operations(wil); + wil_abort_scan(wil, false); mutex_unlock(&wil->p2p_wdev_mutex); wil_reset(wil, false); diff --git a/drivers/net/wireless/ath/wil6210/p2p.c b/drivers/net/wireless/ath/wil6210/p2p.c index 42148da111f1..52d4356349d0 100644 --- a/drivers/net/wireless/ath/wil6210/p2p.c +++ b/drivers/net/wireless/ath/wil6210/p2p.c @@ -265,8 +265,7 @@ void wil_p2p_stop_radio_operations(struct wil6210_priv *wil) struct wil_p2p_info *p2p = &wil->p2p; lockdep_assert_held(&wil->mutex); - - mutex_lock(&wil->p2p_wdev_mutex); + lockdep_assert_held(&wil->p2p_wdev_mutex); if (wil->radio_wdev != wil->p2p_wdev) goto out; @@ -274,10 +273,8 @@ void wil_p2p_stop_radio_operations(struct wil6210_priv *wil) if (!p2p->discovery_started) { /* Regular scan on the p2p device */ if (wil->scan_request && - wil->scan_request->wdev == wil->p2p_wdev) { - cfg80211_scan_done(wil->scan_request, 1); - wil->scan_request = NULL; - } + wil->scan_request->wdev == wil->p2p_wdev) + wil_abort_scan(wil, true); goto out; } @@ -300,5 +297,4 @@ void wil_p2p_stop_radio_operations(struct wil6210_priv *wil) out: wil->radio_wdev = wil->wdev; - mutex_unlock(&wil->p2p_wdev_mutex); } diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index 4a86a077edf4..d4bae99139c4 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -881,6 +881,9 @@ int wmi_pcp_stop(struct wil6210_priv *wil); int wmi_led_cfg(struct wil6210_priv *wil, bool enable); int wmi_aoa_meas(struct wil6210_priv *wil, const void *mac_addr, u8 chan, u8 type); +int wmi_abort_scan(struct wil6210_priv *wil); +void wil_abort_scan(struct wil6210_priv *wil, bool sync); + void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid, u16 reason_code, bool from_event); void wil_probe_client_flush(struct wil6210_priv *wil); diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index 5decc54c4399..977899809fce 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -428,9 +428,11 @@ static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id, mutex_lock(&wil->p2p_wdev_mutex); if (wil->scan_request) { struct wmi_scan_complete_event *data = d; - bool aborted = (data->status != WMI_SCAN_SUCCESS); + int status = le32_to_cpu(data->status); + bool aborted = (status != WMI_SCAN_SUCCESS) && + (status != WMI_SCAN_ABORT_REJECTED); - wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", data->status); + wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", status); wil_dbg_misc(wil, "Complete scan_request 0x%p aborted %d\n", wil->scan_request, aborted); @@ -438,6 +440,7 @@ static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id, cfg80211_scan_done(wil->scan_request, aborted); wil->radio_wdev = wil->wdev; wil->scan_request = NULL; + wake_up_interruptible(&wil->wq); } else { wil_err(wil, "SCAN_COMPLETE while not scanning\n"); } @@ -1624,6 +1627,16 @@ int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil, rc = -EINVAL; } +int wmi_abort_scan(struct wil6210_priv *wil) +{ + int rc; + + wil_dbg_wmi(wil, "sending WMI_ABORT_SCAN_CMDID\n"); + + rc = wmi_send(wil, WMI_ABORT_SCAN_CMDID, NULL, 0); + if (rc) + wil_err(wil, "Failed to abort scan (%d)\n", rc); + return rc; } |
