Commit 035859a5 authored by Maya Erez's avatar Maya Erez Committed by Kalle Valo

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.
Signed-off-by: default avatarMaya Erez <qca_merez@qca.qualcomm.com>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent dfb5b098
...@@ -469,6 +469,34 @@ static int wil_cfg80211_scan(struct wiphy *wiphy, ...@@ -469,6 +469,34 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
return rc; 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, static void wil_print_crypto(struct wil6210_priv *wil,
struct cfg80211_crypto_settings *c) struct cfg80211_crypto_settings *c)
{ {
...@@ -1419,8 +1447,10 @@ static void wil_cfg80211_stop_p2p_device(struct wiphy *wiphy, ...@@ -1419,8 +1447,10 @@ static void wil_cfg80211_stop_p2p_device(struct wiphy *wiphy,
wil_dbg_misc(wil, "%s: entered\n", __func__); wil_dbg_misc(wil, "%s: entered\n", __func__);
mutex_lock(&wil->mutex); mutex_lock(&wil->mutex);
mutex_lock(&wil->p2p_wdev_mutex);
wil_p2p_stop_radio_operations(wil); wil_p2p_stop_radio_operations(wil);
p2p->p2p_dev_started = 0; p2p->p2p_dev_started = 0;
mutex_unlock(&wil->p2p_wdev_mutex);
mutex_unlock(&wil->mutex); mutex_unlock(&wil->mutex);
} }
...@@ -1456,6 +1486,7 @@ static struct cfg80211_ops wil_cfg80211_ops = { ...@@ -1456,6 +1486,7 @@ static struct cfg80211_ops wil_cfg80211_ops = {
.add_virtual_intf = wil_cfg80211_add_iface, .add_virtual_intf = wil_cfg80211_add_iface,
.del_virtual_intf = wil_cfg80211_del_iface, .del_virtual_intf = wil_cfg80211_del_iface,
.scan = wil_cfg80211_scan, .scan = wil_cfg80211_scan,
.abort_scan = wil_cfg80211_abort_scan,
.connect = wil_cfg80211_connect, .connect = wil_cfg80211_connect,
.disconnect = wil_cfg80211_disconnect, .disconnect = wil_cfg80211_disconnect,
.change_virtual_intf = wil_cfg80211_change_iface, .change_virtual_intf = wil_cfg80211_change_iface,
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "boot_loader.h" #include "boot_loader.h"
#define WAIT_FOR_HALP_VOTE_MS 100 #define WAIT_FOR_HALP_VOTE_MS 100
#define WAIT_FOR_SCAN_ABORT_MS 1000
bool debug_fw; /* = false; */ bool debug_fw; /* = false; */
module_param(debug_fw, bool, S_IRUGO); module_param(debug_fw, bool, S_IRUGO);
...@@ -808,6 +809,34 @@ static int wil_wait_for_fw_ready(struct wil6210_priv *wil) ...@@ -808,6 +809,34 @@ static int wil_wait_for_fw_ready(struct wil6210_priv *wil)
return 0; return 0;
} }
void wil_abort_scan(struct wil6210_priv *wil, bool sync)
{
int rc;
struct cfg80211_scan_info info = {
.aborted = true,
};
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, &info);
wil->scan_request = NULL;
}
}
/* /*
* We reset all the structures, and we reset the UMAC. * We reset all the structures, and we reset the UMAC.
* After calling this routine, you're expected to reload * After calling this routine, you're expected to reload
...@@ -860,17 +889,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) ...@@ -860,17 +889,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
mutex_unlock(&wil->wmi_mutex); mutex_unlock(&wil->wmi_mutex);
mutex_lock(&wil->p2p_wdev_mutex); mutex_lock(&wil->p2p_wdev_mutex);
if (wil->scan_request) { wil_abort_scan(wil, false);
struct cfg80211_scan_info info = {
.aborted = true,
};
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, &info);
wil->scan_request = NULL;
}
mutex_unlock(&wil->p2p_wdev_mutex); mutex_unlock(&wil->p2p_wdev_mutex);
wil_mask_irq(wil); wil_mask_irq(wil);
...@@ -1063,20 +1082,9 @@ int __wil_down(struct wil6210_priv *wil) ...@@ -1063,20 +1082,9 @@ int __wil_down(struct wil6210_priv *wil)
} }
wil_enable_irq(wil); wil_enable_irq(wil);
wil_p2p_stop_radio_operations(wil);
mutex_lock(&wil->p2p_wdev_mutex); mutex_lock(&wil->p2p_wdev_mutex);
if (wil->scan_request) { wil_p2p_stop_radio_operations(wil);
struct cfg80211_scan_info info = { wil_abort_scan(wil, false);
.aborted = true,
};
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, &info);
wil->scan_request = NULL;
}
mutex_unlock(&wil->p2p_wdev_mutex); mutex_unlock(&wil->p2p_wdev_mutex);
wil_reset(wil, false); wil_reset(wil, false);
......
...@@ -272,8 +272,7 @@ void wil_p2p_stop_radio_operations(struct wil6210_priv *wil) ...@@ -272,8 +272,7 @@ void wil_p2p_stop_radio_operations(struct wil6210_priv *wil)
}; };
lockdep_assert_held(&wil->mutex); lockdep_assert_held(&wil->mutex);
lockdep_assert_held(&wil->p2p_wdev_mutex);
mutex_lock(&wil->p2p_wdev_mutex);
if (wil->radio_wdev != wil->p2p_wdev) if (wil->radio_wdev != wil->p2p_wdev)
goto out; goto out;
...@@ -281,10 +280,8 @@ void wil_p2p_stop_radio_operations(struct wil6210_priv *wil) ...@@ -281,10 +280,8 @@ void wil_p2p_stop_radio_operations(struct wil6210_priv *wil)
if (!p2p->discovery_started) { if (!p2p->discovery_started) {
/* Regular scan on the p2p device */ /* Regular scan on the p2p device */
if (wil->scan_request && if (wil->scan_request &&
wil->scan_request->wdev == wil->p2p_wdev) { wil->scan_request->wdev == wil->p2p_wdev)
cfg80211_scan_done(wil->scan_request, &info); wil_abort_scan(wil, true);
wil->scan_request = NULL;
}
goto out; goto out;
} }
...@@ -307,5 +304,4 @@ void wil_p2p_stop_radio_operations(struct wil6210_priv *wil) ...@@ -307,5 +304,4 @@ void wil_p2p_stop_radio_operations(struct wil6210_priv *wil)
out: out:
wil->radio_wdev = wil->wdev; wil->radio_wdev = wil->wdev;
mutex_unlock(&wil->p2p_wdev_mutex);
} }
...@@ -873,6 +873,9 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, ...@@ -873,6 +873,9 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype,
u8 chan, u8 hidden_ssid, u8 is_go); u8 chan, u8 hidden_ssid, u8 is_go);
int wmi_pcp_stop(struct wil6210_priv *wil); int wmi_pcp_stop(struct wil6210_priv *wil);
int wmi_led_cfg(struct wil6210_priv *wil, bool enable); int wmi_led_cfg(struct wil6210_priv *wil, bool enable);
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, void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
u16 reason_code, bool from_event); u16 reason_code, bool from_event);
void wil_probe_client_flush(struct wil6210_priv *wil); void wil_probe_client_flush(struct wil6210_priv *wil);
......
...@@ -427,18 +427,20 @@ static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id, ...@@ -427,18 +427,20 @@ static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id,
mutex_lock(&wil->p2p_wdev_mutex); mutex_lock(&wil->p2p_wdev_mutex);
if (wil->scan_request) { if (wil->scan_request) {
struct wmi_scan_complete_event *data = d; struct wmi_scan_complete_event *data = d;
int status = le32_to_cpu(data->status);
struct cfg80211_scan_info info = { struct cfg80211_scan_info info = {
.aborted = (data->status != WMI_SCAN_SUCCESS), .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_dbg_misc(wil, "Complete scan_request 0x%p aborted %d\n",
wil->scan_request, info.aborted); wil->scan_request, info.aborted);
del_timer_sync(&wil->scan_timer); del_timer_sync(&wil->scan_timer);
cfg80211_scan_done(wil->scan_request, &info); cfg80211_scan_done(wil->scan_request, &info);
wil->radio_wdev = wil->wdev; wil->radio_wdev = wil->wdev;
wil->scan_request = NULL; wil->scan_request = NULL;
wake_up_interruptible(&wil->wq);
} else { } else {
wil_err(wil, "SCAN_COMPLETE while not scanning\n"); wil_err(wil, "SCAN_COMPLETE while not scanning\n");
} }
...@@ -1597,6 +1599,19 @@ int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil, ...@@ -1597,6 +1599,19 @@ int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil,
return rc; return rc;
} }
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;
}
void wmi_event_flush(struct wil6210_priv *wil) void wmi_event_flush(struct wil6210_priv *wil)
{ {
struct pending_wmi_event *evt, *t; struct pending_wmi_event *evt, *t;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment