summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ath/wil6210/cfg80211.c
diff options
context:
space:
mode:
authorLior David <qca_liord@qca.qualcomm.com>2016-11-28 13:49:00 +0200
committerKalle Valo <kvalo@qca.qualcomm.com>2016-12-01 13:20:26 +0200
commitbb6743f7c2ffc467002dfe24bea5dedc96c7da04 (patch)
tree48cd38ddcd12c62556c958ecbe10f5226dd22937 /drivers/net/wireless/ath/wil6210/cfg80211.c
parent982a6151f6f1296725de241a17932a3ecdd359d2 (diff)
wil6210: delay remain on channel when scan is active
Currently it was possible to call remain_on_channel(ROC) while scan was active and this caused a crash in the FW. In order to fix this problem and make the behavior consistent with other drivers, queue the ROC in case a scan is active and try it again when scan is done. As part of the fix, clean up some locking issues and return error if scan is called while ROC is active. Signed-off-by: Lior David <qca_liord@qca.qualcomm.com> Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net/wireless/ath/wil6210/cfg80211.c')
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c45
1 files changed, 21 insertions, 24 deletions
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 22078b0ffc8c..6aa3ff4240a9 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -354,14 +354,6 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
wil_dbg_misc(wil, "%s(), wdev=0x%p iftype=%d\n",
__func__, wdev, wdev->iftype);
- mutex_lock(&wil->p2p_wdev_mutex);
- if (wil->scan_request) {
- wil_err(wil, "Already scanning\n");
- mutex_unlock(&wil->p2p_wdev_mutex);
- return -EAGAIN;
- }
- mutex_unlock(&wil->p2p_wdev_mutex);
-
/* check we are client side */
switch (wdev->iftype) {
case NL80211_IFTYPE_STATION:
@@ -378,12 +370,24 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
return -EBUSY;
}
+ mutex_lock(&wil->mutex);
+
+ mutex_lock(&wil->p2p_wdev_mutex);
+ if (wil->scan_request || wil->p2p.discovery_started) {
+ wil_err(wil, "Already scanning\n");
+ mutex_unlock(&wil->p2p_wdev_mutex);
+ rc = -EAGAIN;
+ goto out;
+ }
+ mutex_unlock(&wil->p2p_wdev_mutex);
+
/* social scan on P2P_DEVICE is handled as p2p search */
if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE &&
wil_p2p_is_social_scan(request)) {
if (!wil->p2p.p2p_dev_started) {
wil_err(wil, "P2P search requested on stopped P2P device\n");
- return -EIO;
+ rc = -EIO;
+ goto out;
}
wil->scan_request = request;
wil->radio_wdev = wdev;
@@ -392,7 +396,7 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
wil->radio_wdev = wil_to_wdev(wil);
wil->scan_request = NULL;
}
- return rc;
+ goto out;
}
(void)wil_p2p_stop_discovery(wil);
@@ -415,7 +419,7 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
if (rc) {
wil_err(wil, "set SSID for scan request failed: %d\n", rc);
- return rc;
+ goto out;
}
wil->scan_request = request;
@@ -448,7 +452,7 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
rc = wmi_set_ie(wil, WMI_FRAME_PROBE_REQ, request->ie_len, request->ie);
if (rc)
- goto out;
+ goto out_restore;
if (wil->discovery_mode && cmd.cmd.scan_type == WMI_ACTIVE_SCAN) {
cmd.cmd.discovery_mode = 1;
@@ -459,13 +463,14 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
rc = wmi_send(wil, WMI_START_SCAN_CMDID, &cmd, sizeof(cmd.cmd) +
cmd.cmd.num_channels * sizeof(cmd.cmd.channel_list[0]));
-out:
+out_restore:
if (rc) {
del_timer_sync(&wil->scan_timer);
wil->radio_wdev = wil_to_wdev(wil);
wil->scan_request = NULL;
}
-
+out:
+ mutex_unlock(&wil->mutex);
return rc;
}
@@ -988,16 +993,8 @@ static int wil_remain_on_channel(struct wiphy *wiphy,
wil_dbg_misc(wil, "%s() center_freq=%d, duration=%d iftype=%d\n",
__func__, chan->center_freq, duration, wdev->iftype);
- rc = wil_p2p_listen(wil, duration, chan, cookie);
- if (rc)
- return rc;
-
- wil->radio_wdev = wdev;
-
- cfg80211_ready_on_channel(wdev, *cookie, chan, duration,
- GFP_KERNEL);
-
- return 0;
+ rc = wil_p2p_listen(wil, wdev, duration, chan, cookie);
+ return rc;
}
static int wil_cancel_remain_on_channel(struct wiphy *wiphy,