Skip to contentSkip to conversation

wcn36xx: scan related patches

PATCH In review Daniel Mack 2 participants 7 messages Apr 17, 2018 – Apr 24, 2018 Qualcomm WCN36XX wireless driver

lore
Share & tools
lore
#0 lore raw

v2 cover wcn36xx: scan related patches

Here's another series of 5 patches for wcn36xx that address some issues with scanning. The first one is the most important one.

Daniel

v1 → v2:

* Moved one hunk from 5/5 to 4/5 so the series becomes bisectable
* Add more commit log context to 5/5

Daniel Mack (5):
wcn36xx: abort scan request when 'dequeued' indicator is sent
wcn36xx: cancel pending scan request when interface goes down
wcn36xx: handle scan cancellation when firmware support is missing
wcn36xx: send bss_type in scan requests
wcn36xx: pass information elements in scan requests

 drivers/net/wireless/ath/wcn36xx/hal.h     |  8 +++++++-
 drivers/net/wireless/ath/wcn36xx/main.c    | 29 +++++++++++++++++++++++++----
 drivers/net/wireless/ath/wcn36xx/smd.c     | 20 +++++++++++++++++---
 drivers/net/wireless/ath/wcn36xx/wcn36xx.h |  7 +------
 4 files changed, 50 insertions(+), 14 deletions(-)
Signature · 1 line
2.14.3
#1 lore raw

PATCH v2 1/5 wcn36xx: abort scan request when 'dequeued' indicator is sent

When the firmware sends a WCN36XX_HAL_SCAN_IND_DEQUEUED indication, the request is apparently no longer valid. Attempts to stop the hardware scan request subsequently will lead to the following error message, and the hardware is no longer able to communicate with any AP:

[   57.917186] wcn36xx: ERROR hal_stop_scan_offload response failed err=5

Interpreting this indicator message as scan abortion fixes this.

While at it, add a newline to a debug print.

---
 drivers/net/wireless/ath/wcn36xx/smd.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/wcn36xx/smd.c +2 -2
index 297a785d0785..b7964f79d837 100644
@@ -2140,10 +2140,11 @@ static int wcn36xx_smd_hw_scan_ind(struct wcn36xx *wcn, void *buf, size_t len)
 		return -EIO;
 	}
 
-	wcn36xx_dbg(WCN36XX_DBG_HAL, "scan indication (type %x)", rsp->type);
+	wcn36xx_dbg(WCN36XX_DBG_HAL, "scan indication (type %x)\n", rsp->type);
 
 	switch (rsp->type) {
 	case WCN36XX_HAL_SCAN_IND_FAILED:
+	case WCN36XX_HAL_SCAN_IND_DEQUEUED:
 		scan_info.aborted = true;
 		/* fall through */
 	case WCN36XX_HAL_SCAN_IND_COMPLETED:
@@ -2156,7 +2157,6 @@ static int wcn36xx_smd_hw_scan_ind(struct wcn36xx *wcn, void *buf, size_t len)
 		break;
 	case WCN36XX_HAL_SCAN_IND_STARTED:
 	case WCN36XX_HAL_SCAN_IND_FOREIGN_CHANNEL:
-	case WCN36XX_HAL_SCAN_IND_DEQUEUED:
 	case WCN36XX_HAL_SCAN_IND_PREEMPTED:
 	case WCN36XX_HAL_SCAN_IND_RESTARTED:
 		break;
Signature · 1 line
2.14.3
#2 lore raw

Re: [v2, 1/5] wcn36xx: abort scan request when 'dequeued' indicator is sent

Quoted 5 lines · Daniel Mack

When the firmware sends a WCN36XX_HAL_SCAN_IND_DEQUEUED indication, the request is apparently no longer valid. Attempts to stop the hardware scan request subsequently will lead to the following error message, and the hardware is no longer able to communicate with any AP:

Quoted 8 lines
[   57.917186] wcn36xx: ERROR hal_stop_scan_offload response failed err=5

Interpreting this indicator message as scan abortion fixes this.

While at it, add a newline to a debug print.

5 patches applied to ath-next branch of ath.git, thanks.

14ca3c98aa12 wcn36xx: abort scan request when 'dequeued' indicator is sent 80c764d32122 wcn36xx: cancel pending scan request when interface goes down 89722f5767ac wcn36xx: handle scan cancellation when firmware support is missing 5a425c8b78e5 wcn36xx: send bss_type in scan requests
4836ec42b074 wcn36xx: pass information elements in scan requests

Signature · 3 lines
https://patchwork.kernel.org/patch/10345025/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
#3 lore raw

PATCH v2 2/5 wcn36xx: cancel pending scan request when interface goes down

In reply to Daniel Mack

When the network interface goes down while a scan request is still pending that can't be stopped due to firmware hickups, wcn->scan_req remains set, even though the hardware is deinitialized. This results in -EBUSY for all scan requests after the interface was brought up again.

Fix this by explicitly completing pending scan requests in wcn36xx_stop().

---
 drivers/net/wireless/ath/wcn36xx/main.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)
drivers/net/wireless/ath/wcn36xx/main.c +13 -0
index 749aef3e2b85..08b6939d3f57 100644
@@ -353,6 +353,19 @@ static void wcn36xx_stop(struct ieee80211_hw *hw)
 
 	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac stop\n");
 
+	cancel_work_sync(&wcn->scan_work);
+
+	mutex_lock(&wcn->scan_lock);
+	if (wcn->scan_req) {
+		struct cfg80211_scan_info scan_info = {
+			.aborted = true,
+		};
+
+		ieee80211_scan_completed(wcn->hw, &scan_info);
+	}
+	wcn->scan_req = NULL;
+	mutex_unlock(&wcn->scan_lock);
+
 	wcn36xx_debugfs_exit(wcn);
 	wcn36xx_smd_stop(wcn);
 	wcn36xx_dxe_deinit(wcn);
Signature · 1 line
2.14.3
#4 lore raw

PATCH v2 3/5 wcn36xx: handle scan cancellation when firmware support is missing

In reply to Daniel Mack

For firmwares that don't have the SCAN_OFFLOAD feature bit set, do not call into wcn36xx_smd_stop_hw_scan(). Instead, stop the asynchronous work and call into ieee80211_scan_completed() immediately.

---
 drivers/net/wireless/ath/wcn36xx/main.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)
drivers/net/wireless/ath/wcn36xx/main.c +11 -3
index 08b6939d3f57..e3b91b3b38ef 100644
@@ -687,10 +687,18 @@ static void wcn36xx_cancel_hw_scan(struct ieee80211_hw *hw,
 	wcn->scan_aborted = true;
 	mutex_unlock(&wcn->scan_lock);
 
-	/* ieee80211_scan_completed will be called on FW scan indication */
-	wcn36xx_smd_stop_hw_scan(wcn);
+	if (get_feat_caps(wcn->fw_feat_caps, SCAN_OFFLOAD)) {
+		/* ieee80211_scan_completed will be called on FW scan
+		 * indication */
+		wcn36xx_smd_stop_hw_scan(wcn);
+	} else {
+		struct cfg80211_scan_info scan_info = {
+			.aborted = true,
+		};
 
-	cancel_work_sync(&wcn->scan_work);
+		cancel_work_sync(&wcn->scan_work);
+		ieee80211_scan_completed(wcn->hw, &scan_info);
+	}
 }
 
 static void wcn36xx_update_allowed_rates(struct ieee80211_sta *sta,
Signature · 1 line
2.14.3
#5 lore raw

PATCH v2 4/5 wcn36xx: send bss_type in scan requests

In reply to Daniel Mack

Pass the bss_type of the currently configured BSS in the message for the scan request. Therefore, that setting needs to be kept in struct wcn36xx_vif.

This seems to be only interesting when scanning for a specific SSID and doesn't matter for regular wildcard scans.

---
 drivers/net/wireless/ath/wcn36xx/smd.c     | 5 ++++-
 drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 1 +
 2 files changed, 5 insertions(+), 1 deletion(-)
drivers/net/wireless/ath/wcn36xx/smd.c +4 -1
index b7964f79d837..9c8ce5e0454f 100644
@@ -620,6 +620,7 @@ int wcn36xx_smd_finish_scan(struct wcn36xx *wcn,
 int wcn36xx_smd_start_hw_scan(struct wcn36xx *wcn, struct ieee80211_vif *vif,
 			      struct cfg80211_scan_request *req)
 {
+	struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
 	struct wcn36xx_hal_start_scan_offload_req_msg msg_body;
 	int ret, i;
 
@@ -631,6 +632,7 @@ int wcn36xx_smd_start_hw_scan(struct wcn36xx *wcn, struct ieee80211_vif *vif,
 	msg_body.max_ch_time = 100;
 	msg_body.scan_hidden = 1;
 	memcpy(msg_body.mac, vif->addr, ETH_ALEN);
+	msg_body.bss_type = vif_priv->bss_type;
 	msg_body.p2p_search = vif->p2p;
 
 	msg_body.num_ssid = min_t(u8, req->n_ssids, ARRAY_SIZE(msg_body.ssids));
@@ -1399,9 +1401,10 @@ int wcn36xx_smd_config_bss(struct wcn36xx *wcn, struct ieee80211_vif *vif,
 	bss->spectrum_mgt_enable = 0;
 	bss->tx_mgmt_power = 0;
 	bss->max_tx_power = WCN36XX_MAX_POWER(wcn);
-
 	bss->action = update;
 
+	vif_priv->bss_type = bss->bss_type;
+
 	wcn36xx_dbg(WCN36XX_DBG_HAL,
 		    "hal config bss bssid %pM self_mac_addr %pM bss_type %d oper_mode %d nw_type %d\n",
 		    bss->bssid, bss->self_mac_addr, bss->bss_type,
drivers/net/wireless/ath/wcn36xx/wcn36xx.h +1 -0
index 5854adf43f3a..22e05cb4eb98 100644
@@ -123,6 +123,7 @@ struct wcn36xx_vif {
 	bool is_joining;
 	bool sta_assoc;
 	struct wcn36xx_hal_mac_ssid ssid;
+	enum wcn36xx_hal_bss_type bss_type;
 
 	/* Power management */
 	enum wcn36xx_power_state pw_state;
Signature · 1 line
2.14.3
#6 lore raw

PATCH v2 5/5 wcn36xx: pass information elements in scan requests

In reply to Daniel Mack

When the wifi driver core passes IE elements in the scan request, append them to the firmware message. The driver currently tells the core that it is capable of attaching up to WCN36XX_MAX_SCAN_IE_LEN octets, but doesn't actually pass them to the the hardware.

Note that this patch doesn't fix a bug that was observed. The change is merely done for the sake of completeness as the hardware supports appending IEs in scans. Tests show that network scans work fine with this patch applied.

Some defines were moved around to avoid cyclic include dependencies.

---
 drivers/net/wireless/ath/wcn36xx/hal.h     |  8 +++++++-
 drivers/net/wireless/ath/wcn36xx/smd.c     | 11 +++++++++++
 drivers/net/wireless/ath/wcn36xx/wcn36xx.h |  6 ------
 3 files changed, 18 insertions(+), 7 deletions(-)
drivers/net/wireless/ath/wcn36xx/hal.h +7 -1
index 182963522941..2aed6c233508 100644
@@ -88,6 +88,12 @@
 /* version string max length (including NULL) */
 #define WCN36XX_HAL_VERSION_LENGTH  64
 
+/* How many frames until we start a-mpdu TX session */
+#define WCN36XX_AMPDU_START_THRESH	20
+
+#define WCN36XX_MAX_SCAN_SSIDS		9
+#define WCN36XX_MAX_SCAN_IE_LEN		500
+
 /* message types for messages exchanged between WDI and HAL */
 enum wcn36xx_hal_host_msg_type {
 	/* Init/De-Init */
@@ -1170,7 +1176,7 @@ struct wcn36xx_hal_start_scan_offload_req_msg {
 
 	/* IE field */
 	u16 ie_len;
-	u8 ie[0];
+	u8 ie[WCN36XX_MAX_SCAN_IE_LEN];
 } __packed;
 
 struct wcn36xx_hal_start_scan_offload_rsp_msg {
drivers/net/wireless/ath/wcn36xx/smd.c +11 -0
index 9c8ce5e0454f..ea74f2b92df5 100644
@@ -624,6 +624,9 @@ int wcn36xx_smd_start_hw_scan(struct wcn36xx *wcn, struct ieee80211_vif *vif,
 	struct wcn36xx_hal_start_scan_offload_req_msg msg_body;
 	int ret, i;
 
+	if (req->ie_len > WCN36XX_MAX_SCAN_IE_LEN)
+		return -EINVAL;
+
 	mutex_lock(&wcn->hal_mutex);
 	INIT_HAL_MSG(msg_body, WCN36XX_HAL_START_SCAN_OFFLOAD_REQ);
 
@@ -648,6 +651,14 @@ int wcn36xx_smd_start_hw_scan(struct wcn36xx *wcn, struct ieee80211_vif *vif,
 	for (i = 0; i < msg_body.num_channel; i++)
 		msg_body.channels[i] = req->channels[i]->hw_value;
 
+	msg_body.header.len -= WCN36XX_MAX_SCAN_IE_LEN;
+
+	if (req->ie_len > 0) {
+		msg_body.ie_len = req->ie_len;
+		msg_body.header.len += req->ie_len;
+		memcpy(msg_body.ie, req->ie, req->ie_len);
+	}
+
 	PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
 
 	wcn36xx_dbg(WCN36XX_DBG_HAL,
drivers/net/wireless/ath/wcn36xx/wcn36xx.h +0 -6
index 22e05cb4eb98..9343989d1169 100644
@@ -32,12 +32,6 @@
 #define WLAN_NV_FILE               "wlan/prima/WCNSS_qcom_wlan_nv.bin"
 #define WCN36XX_AGGR_BUFFER_SIZE 64
 
-/* How many frames until we start a-mpdu TX session */
-#define WCN36XX_AMPDU_START_THRESH	20
-
-#define WCN36XX_MAX_SCAN_SSIDS		9
-#define WCN36XX_MAX_SCAN_IE_LEN		500
-
 extern unsigned int wcn36xx_dbg_mask;
 
 enum wcn36xx_debug_mask {
Signature · 1 line
2.14.3