wcn36xx: Correct band/freq reporting on RX
authorLoic Poulain <loic.poulain@linaro.org>
Mon, 18 Oct 2021 10:57:57 +0000 (12:57 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 18 Nov 2021 18:16:20 +0000 (19:16 +0100)
[ Upstream commit 8a27ca39478270e07baf9c09aa0c99709769ba03 ]

For packets originating from hardware scan, the channel and band is
included in the buffer descriptor (bd->rf_band & bd->rx_ch).

For 2Ghz band the channel value is directly reported in the 4-bit
rx_ch field. For 5Ghz band, the rx_ch field contains a mapping
index (given the 4-bit limitation).

The reserved0 value field is also used to extend 4-bit mapping to
5-bit mapping to support more than 16 5Ghz channels.

This change adds correct reporting of the frequency/band, that is
used in scan mechanism. And is required for 5Ghz hardware scan
support.

Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/1634554678-7993-1-git-send-email-loic.poulain@linaro.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/wireless/ath/wcn36xx/txrx.c
drivers/net/wireless/ath/wcn36xx/txrx.h

index eaf2410..c0f51fa 100644 (file)
@@ -31,6 +31,13 @@ struct wcn36xx_rate {
        enum rate_info_bw bw;
 };
 
+/* Buffer descriptor rx_ch field is limited to 5-bit (4+1), a mapping is used
+ * for 11A Channels.
+ */
+static const u8 ab_rx_ch_map[] = { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104,
+                                  108, 112, 116, 120, 124, 128, 132, 136, 140,
+                                  149, 153, 157, 161, 165, 144 };
+
 static const struct wcn36xx_rate wcn36xx_rate_table[] = {
        /* 11b rates */
        {  10, 0, RX_ENC_LEGACY, 0, RATE_INFO_BW_20 },
@@ -291,6 +298,22 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb)
            ieee80211_is_probe_resp(hdr->frame_control))
                status.boottime_ns = ktime_get_boottime_ns();
 
+       if (bd->scan_learn) {
+               /* If packet originates from hardware scanning, extract the
+                * band/channel from bd descriptor.
+                */
+               u8 hwch = (bd->reserved0 << 4) + bd->rx_ch;
+
+               if (bd->rf_band != 1 && hwch <= sizeof(ab_rx_ch_map) && hwch >= 1) {
+                       status.band = NL80211_BAND_5GHZ;
+                       status.freq = ieee80211_channel_to_frequency(ab_rx_ch_map[hwch - 1],
+                                                                    status.band);
+               } else {
+                       status.band = NL80211_BAND_2GHZ;
+                       status.freq = ieee80211_channel_to_frequency(hwch, status.band);
+               }
+       }
+
        memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
 
        if (ieee80211_is_beacon(hdr->frame_control)) {
index 032216e..b54311f 100644 (file)
@@ -110,7 +110,8 @@ struct wcn36xx_rx_bd {
        /* 0x44 */
        u32     exp_seq_num:12;
        u32     cur_seq_num:12;
-       u32     fr_type_subtype:8;
+       u32     rf_band:2;
+       u32     fr_type_subtype:6;
 
        /* 0x48 */
        u32     msdu_size:16;