openwrt-cghmn-mt300n/package/kernel/mac80211/patches/rtl/008-v6.12-wifi-rtw88-8822c-Parse-channel-from-IE-to-correct-in.patch
Marty Jones 8a4ce69eea mac80211: realtek: backport support for RTL8812AU/RTL8821AU
Backport support for RTL8812AU/RTL8821AU USB adapters
Manually backported patch:
045-v6.13-wifi-rtw88-Enable-the-new-RTL8821AU-RTL8812AU-driver
Patches from 046 to 051 are pending.

Signed-off-by: Marty Jones <mj8263788@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/17079
[Move BPAUTO_WANT_DEV_COREDUMP to original patch]
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
(cherry picked from commit 36f6d6ddcd67e7e32e2281baf5814ece81fad402)
2024-12-10 01:06:10 +01:00

152 lines
5.2 KiB
Diff

From 53ed4b25a79aeec5991c2dc579e635b136ef7676 Mon Sep 17 00:00:00 2001
From: Po-Hao Huang <phhuang@realtek.com>
Date: Wed, 24 Jul 2024 13:05:01 +0800
Subject: [PATCH] wifi: rtw88: 8822c: Parse channel from IE to correct invalid
hardware reports
For CCK packets we could get incorrect reports from hardware.
And this causes wrong frequencies being reported. Parse the channel
information from IE if provided by AP to fix this.
Signed-off-by: Po-Hao Huang <phhuang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20240724050501.7550-1-pkshih@realtek.com
---
drivers/net/wireless/realtek/rtw88/main.h | 1 +
drivers/net/wireless/realtek/rtw88/pci.c | 1 +
drivers/net/wireless/realtek/rtw88/rtw8822c.c | 7 ++--
drivers/net/wireless/realtek/rtw88/rx.c | 41 +++++++++++++++++++
drivers/net/wireless/realtek/rtw88/rx.h | 13 ++++++
drivers/net/wireless/realtek/rtw88/sdio.c | 1 +
drivers/net/wireless/realtek/rtw88/usb.c | 2 +
7 files changed, 63 insertions(+), 3 deletions(-)
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -623,6 +623,7 @@ struct rtw_rx_pkt_stat {
bool crc_err;
bool decrypted;
bool is_c2h;
+ bool channel_invalid;
s32 signal_power;
u16 pkt_len;
--- a/drivers/net/wireless/realtek/rtw88/pci.c
+++ b/drivers/net/wireless/realtek/rtw88/pci.c
@@ -1088,6 +1088,7 @@ static u32 rtw_pci_rx_napi(struct rtw_de
/* remove rx_desc */
skb_pull(new, pkt_offset);
+ rtw_update_rx_freq_for_invalid(rtwdev, new, &rx_status, &pkt_stat);
rtw_rx_stats(rtwdev, pkt_stat.vif, new);
memcpy(new->cb, &rx_status, sizeof(rx_status));
ieee80211_rx_napi(rtwdev->hw, NULL, new, napi);
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
@@ -2576,9 +2576,10 @@ static void query_phy_status_page0(struc
rx_power[RF_PATH_B] -= 110;
channel = GET_PHY_STAT_P0_CHANNEL(phy_status);
- if (channel == 0)
- channel = rtwdev->hal.current_channel;
- rtw_set_rx_freq_band(pkt_stat, channel);
+ if (channel != 0)
+ rtw_set_rx_freq_band(pkt_stat, channel);
+ else
+ pkt_stat->channel_invalid = true;
pkt_stat->rx_power[RF_PATH_A] = rx_power[RF_PATH_A];
pkt_stat->rx_power[RF_PATH_B] = rx_power[RF_PATH_B];
--- a/drivers/net/wireless/realtek/rtw88/rx.c
+++ b/drivers/net/wireless/realtek/rtw88/rx.c
@@ -146,6 +146,47 @@ static void rtw_set_rx_freq_by_pktstat(s
rx_status->band = pkt_stat->band;
}
+void rtw_update_rx_freq_from_ie(struct rtw_dev *rtwdev, struct sk_buff *skb,
+ struct ieee80211_rx_status *rx_status,
+ struct rtw_rx_pkt_stat *pkt_stat)
+{
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
+ int channel = rtwdev->hal.current_channel;
+ size_t hdr_len, ielen;
+ int channel_number;
+ u8 *variable;
+
+ if (!test_bit(RTW_FLAG_SCANNING, rtwdev->flags))
+ goto fill_rx_status;
+
+ 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 {
+ goto fill_rx_status;
+ }
+
+ if (skb->len > hdr_len)
+ ielen = skb->len - hdr_len;
+ else
+ goto fill_rx_status;
+
+ channel_number = cfg80211_get_ies_channel_number(variable, ielen,
+ NL80211_BAND_2GHZ);
+ if (channel_number != -1)
+ channel = channel_number;
+
+fill_rx_status:
+ rtw_set_rx_freq_band(pkt_stat, channel);
+ rtw_set_rx_freq_by_pktstat(pkt_stat, rx_status);
+}
+EXPORT_SYMBOL(rtw_update_rx_freq_from_ie);
+
void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
struct rtw_rx_pkt_stat *pkt_stat,
struct ieee80211_hdr *hdr,
--- a/drivers/net/wireless/realtek/rtw88/rx.h
+++ b/drivers/net/wireless/realtek/rtw88/rx.h
@@ -50,5 +50,18 @@ void rtw_rx_fill_rx_status(struct rtw_de
struct ieee80211_hdr *hdr,
struct ieee80211_rx_status *rx_status,
u8 *phy_status);
+void rtw_update_rx_freq_from_ie(struct rtw_dev *rtwdev, struct sk_buff *skb,
+ struct ieee80211_rx_status *rx_status,
+ struct rtw_rx_pkt_stat *pkt_stat);
+
+static inline
+void rtw_update_rx_freq_for_invalid(struct rtw_dev *rtwdev, struct sk_buff *skb,
+ struct ieee80211_rx_status *rx_status,
+ struct rtw_rx_pkt_stat *pkt_stat)
+{
+ if (pkt_stat->channel_invalid)
+ rtw_update_rx_freq_from_ie(rtwdev, skb, rx_status, pkt_stat);
+}
+
#endif
--- a/drivers/net/wireless/realtek/rtw88/sdio.c
+++ b/drivers/net/wireless/realtek/rtw88/sdio.c
@@ -948,6 +948,7 @@ static void rtw_sdio_rx_skb(struct rtw_d
skb_put(skb, pkt_stat->pkt_len);
skb_reserve(skb, pkt_offset);
+ rtw_update_rx_freq_for_invalid(rtwdev, skb, rx_status, pkt_stat);
rtw_rx_stats(rtwdev, pkt_stat->vif, skb);
ieee80211_rx_irqsafe(rtwdev->hw, skb);
--- a/drivers/net/wireless/realtek/rtw88/usb.c
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
@@ -579,6 +579,8 @@ static void rtw_usb_rx_handler(struct wo
skb_put(skb, pkt_stat.pkt_len);
skb_reserve(skb, pkt_offset);
+
+ rtw_update_rx_freq_for_invalid(rtwdev, skb, &rx_status, &pkt_stat);
memcpy(skb->cb, &rx_status, sizeof(rx_status));
ieee80211_rx_irqsafe(rtwdev->hw, skb);
}