Takashi Iwai 017dfe
From 478d239fea122292f3196a304289213d44d93a20 Mon Sep 17 00:00:00 2001
Takashi Iwai 017dfe
From: Loic Poulain <loic.poulain@linaro.org>
Takashi Iwai 017dfe
Date: Mon, 18 Oct 2021 12:57:57 +0200
Takashi Iwai 017dfe
Subject: [PATCH] wcn36xx: Correct band/freq reporting on RX
Takashi Iwai 017dfe
Git-commit: 8a27ca39478270e07baf9c09aa0c99709769ba03
Takashi Iwai 017dfe
Patch-mainline: v5.16-rc1
Takashi Iwai 017dfe
References: stable-5.14.19
Takashi Iwai 017dfe
Takashi Iwai 017dfe
[ Upstream commit 8a27ca39478270e07baf9c09aa0c99709769ba03 ]
Takashi Iwai 017dfe
Takashi Iwai 017dfe
For packets originating from hardware scan, the channel and band is
Takashi Iwai 017dfe
included in the buffer descriptor (bd->rf_band & bd->rx_ch).
Takashi Iwai 017dfe
Takashi Iwai 017dfe
For 2Ghz band the channel value is directly reported in the 4-bit
Takashi Iwai 017dfe
rx_ch field. For 5Ghz band, the rx_ch field contains a mapping
Takashi Iwai 017dfe
index (given the 4-bit limitation).
Takashi Iwai 017dfe
Takashi Iwai 017dfe
The reserved0 value field is also used to extend 4-bit mapping to
Takashi Iwai 017dfe
5-bit mapping to support more than 16 5Ghz channels.
Takashi Iwai 017dfe
Takashi Iwai 017dfe
This change adds correct reporting of the frequency/band, that is
Takashi Iwai 017dfe
used in scan mechanism. And is required for 5Ghz hardware scan
Takashi Iwai 017dfe
support.
Takashi Iwai 017dfe
Takashi Iwai 017dfe
Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
Takashi Iwai 017dfe
Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Takashi Iwai 017dfe
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Takashi Iwai 017dfe
Link: https://lore.kernel.org/r/1634554678-7993-1-git-send-email-loic.poulain@linaro.org
Takashi Iwai 017dfe
Signed-off-by: Sasha Levin <sashal@kernel.org>
Takashi Iwai 017dfe
Acked-by: Takashi Iwai <tiwai@suse.de>
Takashi Iwai 017dfe
Takashi Iwai 017dfe
---
Takashi Iwai 017dfe
 drivers/net/wireless/ath/wcn36xx/txrx.c | 23 +++++++++++++++++++++++
Takashi Iwai 017dfe
 drivers/net/wireless/ath/wcn36xx/txrx.h |  3 ++-
Takashi Iwai 017dfe
 2 files changed, 25 insertions(+), 1 deletion(-)
Takashi Iwai 017dfe
Takashi Iwai 017dfe
diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.c b/drivers/net/wireless/ath/wcn36xx/txrx.c
Takashi Iwai 017dfe
index eaf2410e3964..c0f51fa13dfa 100644
Takashi Iwai 017dfe
--- a/drivers/net/wireless/ath/wcn36xx/txrx.c
Takashi Iwai 017dfe
+++ b/drivers/net/wireless/ath/wcn36xx/txrx.c
Takashi Iwai 017dfe
@@ -31,6 +31,13 @@ struct wcn36xx_rate {
Takashi Iwai 017dfe
 	enum rate_info_bw bw;
Takashi Iwai 017dfe
 };
Takashi Iwai 017dfe
 
Takashi Iwai 017dfe
+/* Buffer descriptor rx_ch field is limited to 5-bit (4+1), a mapping is used
Takashi Iwai 017dfe
+ * for 11A Channels.
Takashi Iwai 017dfe
+ */
Takashi Iwai 017dfe
+static const u8 ab_rx_ch_map[] = { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104,
Takashi Iwai 017dfe
+				   108, 112, 116, 120, 124, 128, 132, 136, 140,
Takashi Iwai 017dfe
+				   149, 153, 157, 161, 165, 144 };
Takashi Iwai 017dfe
+
Takashi Iwai 017dfe
 static const struct wcn36xx_rate wcn36xx_rate_table[] = {
Takashi Iwai 017dfe
 	/* 11b rates */
Takashi Iwai 017dfe
 	{  10, 0, RX_ENC_LEGACY, 0, RATE_INFO_BW_20 },
Takashi Iwai 017dfe
@@ -291,6 +298,22 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb)
Takashi Iwai 017dfe
 	    ieee80211_is_probe_resp(hdr->frame_control))
Takashi Iwai 017dfe
 		status.boottime_ns = ktime_get_boottime_ns();
Takashi Iwai 017dfe
 
Takashi Iwai 017dfe
+	if (bd->scan_learn) {
Takashi Iwai 017dfe
+		/* If packet originates from hardware scanning, extract the
Takashi Iwai 017dfe
+		 * band/channel from bd descriptor.
Takashi Iwai 017dfe
+		 */
Takashi Iwai 017dfe
+		u8 hwch = (bd->reserved0 << 4) + bd->rx_ch;
Takashi Iwai 017dfe
+
Takashi Iwai 017dfe
+		if (bd->rf_band != 1 && hwch <= sizeof(ab_rx_ch_map) && hwch >= 1) {
Takashi Iwai 017dfe
+			status.band = NL80211_BAND_5GHZ;
Takashi Iwai 017dfe
+			status.freq = ieee80211_channel_to_frequency(ab_rx_ch_map[hwch - 1],
Takashi Iwai 017dfe
+								     status.band);
Takashi Iwai 017dfe
+		} else {
Takashi Iwai 017dfe
+			status.band = NL80211_BAND_2GHZ;
Takashi Iwai 017dfe
+			status.freq = ieee80211_channel_to_frequency(hwch, status.band);
Takashi Iwai 017dfe
+		}
Takashi Iwai 017dfe
+	}
Takashi Iwai 017dfe
+
Takashi Iwai 017dfe
 	memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
Takashi Iwai 017dfe
 
Takashi Iwai 017dfe
 	if (ieee80211_is_beacon(hdr->frame_control)) {
Takashi Iwai 017dfe
diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.h b/drivers/net/wireless/ath/wcn36xx/txrx.h
Takashi Iwai 017dfe
index 032216e82b2b..b54311ffde9c 100644
Takashi Iwai 017dfe
--- a/drivers/net/wireless/ath/wcn36xx/txrx.h
Takashi Iwai 017dfe
+++ b/drivers/net/wireless/ath/wcn36xx/txrx.h
Takashi Iwai 017dfe
@@ -110,7 +110,8 @@ struct wcn36xx_rx_bd {
Takashi Iwai 017dfe
 	/* 0x44 */
Takashi Iwai 017dfe
 	u32	exp_seq_num:12;
Takashi Iwai 017dfe
 	u32	cur_seq_num:12;
Takashi Iwai 017dfe
-	u32	fr_type_subtype:8;
Takashi Iwai 017dfe
+	u32	rf_band:2;
Takashi Iwai 017dfe
+	u32	fr_type_subtype:6;
Takashi Iwai 017dfe
 
Takashi Iwai 017dfe
 	/* 0x48 */
Takashi Iwai 017dfe
 	u32	msdu_size:16;
Takashi Iwai 017dfe
-- 
Takashi Iwai 017dfe
2.26.2
Takashi Iwai 017dfe