]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
wifi: rtw89: Parse channel from IE to correct invalid hardware reports during scanning
authorChih-Kang Chang <gary.chang@realtek.com>
Thu, 20 Feb 2025 06:43:57 +0000 (14:43 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 May 2025 09:13:05 +0000 (11:13 +0200)
[ Upstream commit e16acf907a3c66b9996a5df43e177a5edec8e0a5 ]

For some packets, we could not get channel information from PPDU status.
And this causes wrong frequencies being reported. Parse the channel
information from IE if provided by AP to fix this.

Signed-off-by: Chih-Kang Chang <gary.chang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20250220064357.17962-1-pkshih@realtek.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/wireless/realtek/rtw89/core.c
drivers/net/wireless/realtek/rtw89/core.h
drivers/net/wireless/realtek/rtw89/rtw8851b.c
drivers/net/wireless/realtek/rtw89/rtw8852a.c
drivers/net/wireless/realtek/rtw89/rtw8852b.c
drivers/net/wireless/realtek/rtw89/rtw8852bt.c
drivers/net/wireless/realtek/rtw89/rtw8852c.c
drivers/net/wireless/realtek/rtw89/rtw8922a.c

index 85f739f1173d8d1607362800b58291404cbfd7fc..c84446ec9e4f4b27ed8b8841ad58661bec12c163 100644 (file)
@@ -2381,6 +2381,49 @@ static void rtw89_core_validate_rx_signal(struct ieee80211_rx_status *rx_status)
                rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
 }
 
+static void rtw89_core_update_rx_freq_from_ie(struct rtw89_dev *rtwdev,
+                                             struct sk_buff *skb,
+                                             struct ieee80211_rx_status *rx_status)
+{
+       struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
+       size_t hdr_len, ielen;
+       u8 *variable;
+       int chan;
+
+       if (!rtwdev->chip->rx_freq_frome_ie)
+               return;
+
+       if (!rtwdev->scanning)
+               return;
+
+       if (ieee80211_is_beacon(mgmt->frame_control)) {
+               variable = mgmt->u.beacon.variable;
+               hdr_len = offsetof(struct ieee80211_mgmt,
+                                  u.beacon.variable);
+       } else if (ieee80211_is_probe_resp(mgmt->frame_control)) {
+               variable = mgmt->u.probe_resp.variable;
+               hdr_len = offsetof(struct ieee80211_mgmt,
+                                  u.probe_resp.variable);
+       } else {
+               return;
+       }
+
+       if (skb->len > hdr_len)
+               ielen = skb->len - hdr_len;
+       else
+               return;
+
+       /* The parsing code for both 2GHz and 5GHz bands is the same in this
+        * function.
+        */
+       chan = cfg80211_get_ies_channel_number(variable, ielen, NL80211_BAND_2GHZ);
+       if (chan == -1)
+               return;
+
+       rx_status->band = chan > 14 ? RTW89_BAND_5G : RTW89_BAND_2G;
+       rx_status->freq = ieee80211_channel_to_frequency(chan, rx_status->band);
+}
+
 static void rtw89_core_rx_to_mac80211(struct rtw89_dev *rtwdev,
                                      struct rtw89_rx_phy_ppdu *phy_ppdu,
                                      struct rtw89_rx_desc_info *desc_info,
@@ -2398,6 +2441,7 @@ static void rtw89_core_rx_to_mac80211(struct rtw89_dev *rtwdev,
        rtw89_core_update_rx_status_by_ppdu(rtwdev, rx_status, phy_ppdu);
        rtw89_core_update_radiotap(rtwdev, skb_ppdu, rx_status);
        rtw89_core_validate_rx_signal(rx_status);
+       rtw89_core_update_rx_freq_from_ie(rtwdev, skb_ppdu, rx_status);
 
        /* In low power mode, it does RX in thread context. */
        local_bh_disable();
index 93e41def81b4093074ea8fb468db74f10076b6f2..979587e92c8492587100d89eefde5bd6c50ff97d 100644 (file)
@@ -4273,6 +4273,7 @@ struct rtw89_chip_info {
        bool support_ant_gain;
        bool ul_tb_waveform_ctrl;
        bool ul_tb_pwr_diff;
+       bool rx_freq_frome_ie;
        bool hw_sec_hdr;
        bool hw_mgmt_tx_encrypt;
        u8 rf_path_num;
index c56f70267882a63a3a45306b4a79a5b812cf72d2..24d48aced57ac51cecbd510bf7ade559702fd202 100644 (file)
@@ -2485,6 +2485,7 @@ const struct rtw89_chip_info rtw8851b_chip_info = {
        .support_ant_gain       = false,
        .ul_tb_waveform_ctrl    = true,
        .ul_tb_pwr_diff         = false,
+       .rx_freq_frome_ie       = true,
        .hw_sec_hdr             = false,
        .hw_mgmt_tx_encrypt     = false,
        .rf_path_num            = 1,
index 9bd2842c27d50f6a79f324eeb95962bdde95e2e3..eeb40a60c2b987eb8d53b54575050c1263dcda6d 100644 (file)
@@ -2203,6 +2203,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
        .support_ant_gain       = false,
        .ul_tb_waveform_ctrl    = false,
        .ul_tb_pwr_diff         = false,
+       .rx_freq_frome_ie       = true,
        .hw_sec_hdr             = false,
        .hw_mgmt_tx_encrypt     = false,
        .rf_path_num            = 2,
index dfb2bf61b0b834adeadc845f86d0ddecaeef3132..4335fa85c334b4294d013ac6abd7852bda751648 100644 (file)
@@ -839,6 +839,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
        .support_ant_gain       = true,
        .ul_tb_waveform_ctrl    = true,
        .ul_tb_pwr_diff         = false,
+       .rx_freq_frome_ie       = true,
        .hw_sec_hdr             = false,
        .hw_mgmt_tx_encrypt     = false,
        .rf_path_num            = 2,
index bde3e1fb7ca62857ce29241a10eaa0ef72daf7f9..7f64a5695486b6343583c1a610bede6ab0319f03 100644 (file)
@@ -772,6 +772,7 @@ const struct rtw89_chip_info rtw8852bt_chip_info = {
        .support_ant_gain       = true,
        .ul_tb_waveform_ctrl    = true,
        .ul_tb_pwr_diff         = false,
+       .rx_freq_frome_ie       = true,
        .hw_sec_hdr             = false,
        .hw_mgmt_tx_encrypt     = false,
        .rf_path_num            = 2,
index bc84b15e7826dd173aab2bc8ade663a084e79a55..9778621d9bc4156bd33a38ebe51b3208e8254ff6 100644 (file)
@@ -2998,6 +2998,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
        .support_ant_gain       = true,
        .ul_tb_waveform_ctrl    = false,
        .ul_tb_pwr_diff         = true,
+       .rx_freq_frome_ie       = false,
        .hw_sec_hdr             = true,
        .hw_mgmt_tx_encrypt     = true,
        .rf_path_num            = 2,
index 11d66bfceb15f135a5b2c63b670cf60e0a5af841..731bc6f18d38b8fcfc59d6e80fff9a9680efea93 100644 (file)
@@ -2763,6 +2763,7 @@ const struct rtw89_chip_info rtw8922a_chip_info = {
        .support_ant_gain       = false,
        .ul_tb_waveform_ctrl    = false,
        .ul_tb_pwr_diff         = false,
+       .rx_freq_frome_ie       = false,
        .hw_sec_hdr             = true,
        .hw_mgmt_tx_encrypt     = true,
        .rf_path_num            = 2,