Blame SOURCES/0022-rtw89-fix-incorrect-channel-info-during-scan.patch

56e3f4
From 7de840de78a263730688f5f298f8dea0e954b980 Mon Sep 17 00:00:00 2001
56e3f4
From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= <ihuguet@redhat.com>
56e3f4
Date: Fri, 21 Jan 2022 08:49:03 +0100
56e3f4
Subject: [PATCH 22/36] rtw89: fix incorrect channel info during scan
56e3f4
MIME-Version: 1.0
56e3f4
Content-Type: text/plain; charset=UTF-8
56e3f4
Content-Transfer-Encoding: 8bit
56e3f4
56e3f4
Bugzilla: http://bugzilla.redhat.com/2033291
56e3f4
56e3f4
commit eb4e52b3f38dfd08a89e1084f5980a2bb93456fb
56e3f4
Author: Po Hao Huang <phhuang@realtek.com>
56e3f4
Date:   Thu Nov 11 10:37:06 2021 +0800
56e3f4
56e3f4
    rtw89: fix incorrect channel info during scan
56e3f4
56e3f4
    We used to fill in rx skbs' frequency field by mac80211's current
56e3f4
    channel value. In some cases, mac80211 switches channel before all
56e3f4
    rx packets have been processed. This results in incorrect bss info.
56e3f4
    We fix this by filling in frequency field with channel index obtained
56e3f4
    from hardware, then fix potential cck missing issue by skb's original
56e3f4
    hw rate. After all fix is done, convert hw rate back to the supported
56e3f4
    band rate index.
56e3f4
56e3f4
    Signed-off-by: Po Hao Huang <phhuang@realtek.com>
56e3f4
    Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
56e3f4
    Signed-off-by: Kalle Valo <kvalo@kernel.org>
56e3f4
    Link: https://lore.kernel.org/r/20211111023706.14154-3-pkshih@realtek.com
56e3f4
56e3f4
Signed-off-by: Íñigo Huguet <ihuguet@redhat.com>
56e3f4
---
56e3f4
 drivers/net/wireless/realtek/rtw89/core.c     |  53 +++++++++---
56e3f4
 drivers/net/wireless/realtek/rtw89/core.h     |   4 +
56e3f4
 drivers/net/wireless/realtek/rtw89/debug.c    |   2 +-
56e3f4
 drivers/net/wireless/realtek/rtw89/phy.c      | 111 ++++++++++++++++++++++++++
56e3f4
 drivers/net/wireless/realtek/rtw89/phy.h      |  60 ++++++++++++++
56e3f4
 drivers/net/wireless/realtek/rtw89/reg.h      |  23 ++++++
56e3f4
 drivers/net/wireless/realtek/rtw89/rtw8852a.c |  19 +++++
56e3f4
 drivers/net/wireless/realtek/rtw89/txrx.h     |  45 ++---------
56e3f4
 8 files changed, 264 insertions(+), 53 deletions(-)
56e3f4
56e3f4
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
56e3f4
index 6c91e99fd28f..2c079388a664 100644
56e3f4
--- a/drivers/net/wireless/realtek/rtw89/core.c
56e3f4
+++ b/drivers/net/wireless/realtek/rtw89/core.c
56e3f4
@@ -242,6 +242,7 @@ void rtw89_set_channel(struct rtw89_dev *rtwdev)
56e3f4
 
56e3f4
 	hal->current_band_width = bandwidth;
56e3f4
 	hal->current_channel = center_chan;
56e3f4
+	hal->prev_primary_channel = hal->current_primary_channel;
56e3f4
 	hal->current_primary_channel = ch_param.primary_chan;
56e3f4
 	hal->current_band_type = band_type;
56e3f4
 
56e3f4
@@ -881,8 +882,11 @@ static void rtw89_core_parse_phy_status_ie01(struct rtw89_dev *rtwdev, u8 *addr,
56e3f4
 {
56e3f4
 	s16 cfo;
56e3f4
 
56e3f4
+	phy_ppdu->chan_idx = RTW89_GET_PHY_STS_IE01_CH_IDX(addr);
56e3f4
+	if (phy_ppdu->rate < RTW89_HW_RATE_OFDM6)
56e3f4
+		return;
56e3f4
 	/* sign conversion for S(12,2) */
56e3f4
-	cfo = sign_extend32(RTW89_GET_PHY_STS_IE0_CFO(addr), 11);
56e3f4
+	cfo = sign_extend32(RTW89_GET_PHY_STS_IE01_CFO(addr), 11);
56e3f4
 	rtw89_phy_cfo_parse(rtwdev, cfo, phy_ppdu);
56e3f4
 }
56e3f4
 
56e3f4
@@ -908,6 +912,7 @@ static void rtw89_core_update_phy_ppdu(struct rtw89_rx_phy_ppdu *phy_ppdu)
56e3f4
 	s8 *rssi = phy_ppdu->rssi;
56e3f4
 	u8 *buf = phy_ppdu->buf;
56e3f4
 
56e3f4
+	phy_ppdu->ie = RTW89_GET_PHY_STS_IE_MAP(buf);
56e3f4
 	phy_ppdu->rssi_avg = RTW89_GET_PHY_STS_RSSI_AVG(buf);
56e3f4
 	rssi[RF_PATH_A] = RTW89_RSSI_RAW_TO_DBM(RTW89_GET_PHY_STS_RSSI_A(buf));
56e3f4
 	rssi[RF_PATH_B] = RTW89_RSSI_RAW_TO_DBM(RTW89_GET_PHY_STS_RSSI_B(buf));
56e3f4
@@ -936,8 +941,9 @@ static int rtw89_core_rx_parse_phy_sts(struct rtw89_dev *rtwdev,
56e3f4
 	u16 ie_len;
56e3f4
 	u8 *pos, *end;
56e3f4
 
56e3f4
-	if (!phy_ppdu->to_self)
56e3f4
-		return 0;
56e3f4
+	/* mark invalid reports and bypass them */
56e3f4
+	if (phy_ppdu->ie < RTW89_CCK_PKT)
56e3f4
+		return -EINVAL;
56e3f4
 
56e3f4
 	pos = (u8 *)phy_ppdu->buf + PHY_STS_HDR_LEN;
56e3f4
 	end = (u8 *)phy_ppdu->buf + phy_ppdu->len;
56e3f4
@@ -1000,9 +1006,7 @@ static bool rtw89_core_rx_ppdu_match(struct rtw89_dev *rtwdev,
56e3f4
 	data_rate_mode = GET_DATA_RATE_MODE(data_rate);
56e3f4
 	if (data_rate_mode == DATA_RATE_MODE_NON_HT) {
56e3f4
 		rate_idx = GET_DATA_RATE_NOT_HT_IDX(data_rate);
56e3f4
-		/* No 4 CCK rates for 5G */
56e3f4
-		if (status->band == NL80211_BAND_5GHZ)
56e3f4
-			rate_idx -= 4;
56e3f4
+		/* rate_idx is still hardware value here */
56e3f4
 	} else if (data_rate_mode == DATA_RATE_MODE_HT) {
56e3f4
 		rate_idx = GET_DATA_RATE_HT_IDX(data_rate);
56e3f4
 	} else if (data_rate_mode == DATA_RATE_MODE_VHT) {
56e3f4
@@ -1081,6 +1085,29 @@ static void rtw89_core_rx_stats(struct rtw89_dev *rtwdev,
56e3f4
 	rtw89_iterate_vifs_bh(rtwdev, rtw89_vif_rx_stats_iter, &iter_data);
56e3f4
 }
56e3f4
 
56e3f4
+static void rtw89_correct_cck_chan(struct rtw89_dev *rtwdev,
56e3f4
+				   struct ieee80211_rx_status *status)
56e3f4
+{
56e3f4
+	u16 chan = rtwdev->hal.prev_primary_channel;
56e3f4
+	u8 band = chan <= 14 ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
56e3f4
+
56e3f4
+	if (status->band != NL80211_BAND_2GHZ &&
56e3f4
+	    status->encoding == RX_ENC_LEGACY &&
56e3f4
+	    status->rate_idx < RTW89_HW_RATE_OFDM6) {
56e3f4
+		status->freq = ieee80211_channel_to_frequency(chan, band);
56e3f4
+		status->band = band;
56e3f4
+	}
56e3f4
+}
56e3f4
+
56e3f4
+static void rtw89_core_hw_to_sband_rate(struct ieee80211_rx_status *rx_status)
56e3f4
+{
56e3f4
+	if (rx_status->band == NL80211_BAND_2GHZ ||
56e3f4
+	    rx_status->encoding != RX_ENC_LEGACY)
56e3f4
+		return;
56e3f4
+	/* No 4 CCK rates for non-2G */
56e3f4
+	rx_status->rate_idx -= 4;
56e3f4
+}
56e3f4
+
56e3f4
 static void rtw89_core_rx_pending_skb(struct rtw89_dev *rtwdev,
56e3f4
 				      struct rtw89_rx_phy_ppdu *phy_ppdu,
56e3f4
 				      struct rtw89_rx_desc_info *desc_info,
56e3f4
@@ -1099,6 +1126,8 @@ static void rtw89_core_rx_pending_skb(struct rtw89_dev *rtwdev,
56e3f4
 		rx_status = IEEE80211_SKB_RXCB(skb_ppdu);
56e3f4
 		if (rtw89_core_rx_ppdu_match(rtwdev, desc_info, rx_status))
56e3f4
 			rtw89_chip_query_ppdu(rtwdev, phy_ppdu, rx_status);
56e3f4
+		rtw89_correct_cck_chan(rtwdev, rx_status);
56e3f4
+		rtw89_core_hw_to_sband_rate(rx_status);
56e3f4
 		rtw89_core_rx_stats(rtwdev, phy_ppdu, desc_info, skb_ppdu);
56e3f4
 		ieee80211_rx_napi(rtwdev->hw, NULL, skb_ppdu, &rtwdev->napi);
56e3f4
 		rtwdev->napi_budget_countdown--;
56e3f4
@@ -1112,6 +1141,7 @@ static void rtw89_core_rx_process_ppdu_sts(struct rtw89_dev *rtwdev,
56e3f4
 	struct rtw89_rx_phy_ppdu phy_ppdu = {.buf = skb->data, .valid = false,
56e3f4
 					     .len = skb->len,
56e3f4
 					     .to_self = desc_info->addr1_match,
56e3f4
+					     .rate = desc_info->data_rate,
56e3f4
 					     .mac_id = desc_info->mac_id};
56e3f4
 	int ret;
56e3f4
 
56e3f4
@@ -1267,12 +1297,7 @@ static void rtw89_core_update_rx_status(struct rtw89_dev *rtwdev,
56e3f4
 	if (data_rate_mode == DATA_RATE_MODE_NON_HT) {
56e3f4
 		rx_status->encoding = RX_ENC_LEGACY;
56e3f4
 		rx_status->rate_idx = GET_DATA_RATE_NOT_HT_IDX(data_rate);
56e3f4
-		/* No 4 CCK rates for 5G */
56e3f4
-		if (rx_status->band == NL80211_BAND_5GHZ)
56e3f4
-			rx_status->rate_idx -= 4;
56e3f4
-		if (rtwdev->scanning)
56e3f4
-			rx_status->rate_idx = min_t(u8, rx_status->rate_idx,
56e3f4
-						    ARRAY_SIZE(rtw89_bitrates) - 5);
56e3f4
+		/* convert rate_idx after we get the correct band */
56e3f4
 	} else if (data_rate_mode == DATA_RATE_MODE_HT) {
56e3f4
 		rx_status->encoding = RX_ENC_HT;
56e3f4
 		rx_status->rate_idx = GET_DATA_RATE_HT_IDX(data_rate);
56e3f4
@@ -1324,10 +1349,13 @@ static void rtw89_core_flush_ppdu_rx_queue(struct rtw89_dev *rtwdev,
56e3f4
 {
56e3f4
 	struct rtw89_ppdu_sts_info *ppdu_sts = &rtwdev->ppdu_sts;
56e3f4
 	u8 band = desc_info->bb_sel ? RTW89_PHY_1 : RTW89_PHY_0;
56e3f4
+	struct ieee80211_rx_status *rx_status;
56e3f4
 	struct sk_buff *skb_ppdu, *tmp;
56e3f4
 
56e3f4
 	skb_queue_walk_safe(&ppdu_sts->rx_queue[band], skb_ppdu, tmp) {
56e3f4
 		skb_unlink(skb_ppdu, &ppdu_sts->rx_queue[band]);
56e3f4
+		rx_status = IEEE80211_SKB_RXCB(skb_ppdu);
56e3f4
+		rtw89_core_hw_to_sband_rate(rx_status);
56e3f4
 		rtw89_core_rx_stats(rtwdev, NULL, desc_info, skb_ppdu);
56e3f4
 		ieee80211_rx_napi(rtwdev->hw, NULL, skb_ppdu, &rtwdev->napi);
56e3f4
 		rtwdev->napi_budget_countdown--;
56e3f4
@@ -1360,6 +1388,7 @@ void rtw89_core_rx(struct rtw89_dev *rtwdev,
56e3f4
 	    BIT(desc_info->frame_type) & PPDU_FILTER_BITMAP) {
56e3f4
 		skb_queue_tail(&ppdu_sts->rx_queue[band], skb);
56e3f4
 	} else {
56e3f4
+		rtw89_core_hw_to_sband_rate(rx_status);
56e3f4
 		rtw89_core_rx_stats(rtwdev, NULL, desc_info, skb);
56e3f4
 		ieee80211_rx_napi(rtwdev->hw, NULL, skb, &rtwdev->napi);
56e3f4
 		rtwdev->napi_budget_countdown--;
56e3f4
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
56e3f4
index 3729abda04f9..ef3f5de26f13 100644
56e3f4
--- a/drivers/net/wireless/realtek/rtw89/core.h
56e3f4
+++ b/drivers/net/wireless/realtek/rtw89/core.h
56e3f4
@@ -473,6 +473,9 @@ struct rtw89_rx_phy_ppdu {
56e3f4
 	u8 rssi_avg;
56e3f4
 	s8 rssi[RF_PATH_MAX];
56e3f4
 	u8 mac_id;
56e3f4
+	u8 chan_idx;
56e3f4
+	u8 ie;
56e3f4
+	u16 rate;
56e3f4
 	bool to_self;
56e3f4
 	bool valid;
56e3f4
 };
56e3f4
@@ -2355,6 +2358,7 @@ struct rtw89_hal {
56e3f4
 	u32 rx_fltr;
56e3f4
 	u8 cv;
56e3f4
 	u8 current_channel;
56e3f4
+	u8 prev_primary_channel;
56e3f4
 	u8 current_primary_channel;
56e3f4
 	enum rtw89_subband current_subband;
56e3f4
 	u8 current_band_width;
56e3f4
diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c
56e3f4
index 1e85808aaf4b..9756d75ef24e 100644
56e3f4
--- a/drivers/net/wireless/realtek/rtw89/debug.c
56e3f4
+++ b/drivers/net/wireless/realtek/rtw89/debug.c
56e3f4
@@ -2285,7 +2285,7 @@ static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta)
56e3f4
 	switch (status->encoding) {
56e3f4
 	case RX_ENC_LEGACY:
56e3f4
 		seq_printf(m, "Legacy %d", status->rate_idx +
56e3f4
-			   (status->band == NL80211_BAND_5GHZ ? 4 : 0));
56e3f4
+			   (status->band != NL80211_BAND_2GHZ ? 4 : 0));
56e3f4
 		break;
56e3f4
 	case RX_ENC_HT:
56e3f4
 		seq_printf(m, "HT MCS-%d%s", status->rate_idx,
56e3f4
diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c
56e3f4
index 312d9a07599d..147009888de0 100644
56e3f4
--- a/drivers/net/wireless/realtek/rtw89/phy.c
56e3f4
+++ b/drivers/net/wireless/realtek/rtw89/phy.c
56e3f4
@@ -2421,6 +2421,116 @@ void rtw89_phy_env_monitor_track(struct rtw89_dev *rtwdev)
56e3f4
 		    env->ccx_watchdog_result, chk_result);
56e3f4
 }
56e3f4
 
56e3f4
+static bool rtw89_physts_ie_page_valid(enum rtw89_phy_status_bitmap *ie_page)
56e3f4
+{
56e3f4
+	if (*ie_page > RTW89_PHYSTS_BITMAP_NUM ||
56e3f4
+	    *ie_page == RTW89_RSVD_9)
56e3f4
+		return false;
56e3f4
+	else if (*ie_page > RTW89_RSVD_9)
56e3f4
+		*ie_page -= 1;
56e3f4
+
56e3f4
+	return true;
56e3f4
+}
56e3f4
+
56e3f4
+static u32 rtw89_phy_get_ie_bitmap_addr(enum rtw89_phy_status_bitmap ie_page)
56e3f4
+{
56e3f4
+	static const u8 ie_page_shift = 2;
56e3f4
+
56e3f4
+	return R_PHY_STS_BITMAP_ADDR_START + (ie_page << ie_page_shift);
56e3f4
+}
56e3f4
+
56e3f4
+static u32 rtw89_physts_get_ie_bitmap(struct rtw89_dev *rtwdev,
56e3f4
+				      enum rtw89_phy_status_bitmap ie_page)
56e3f4
+{
56e3f4
+	u32 addr;
56e3f4
+
56e3f4
+	if (!rtw89_physts_ie_page_valid(&ie_page))
56e3f4
+		return 0;
56e3f4
+
56e3f4
+	addr = rtw89_phy_get_ie_bitmap_addr(ie_page);
56e3f4
+
56e3f4
+	return rtw89_phy_read32(rtwdev, addr);
56e3f4
+}
56e3f4
+
56e3f4
+static void rtw89_physts_set_ie_bitmap(struct rtw89_dev *rtwdev,
56e3f4
+				       enum rtw89_phy_status_bitmap ie_page,
56e3f4
+				       u32 val)
56e3f4
+{
56e3f4
+	const struct rtw89_chip_info *chip = rtwdev->chip;
56e3f4
+	u32 addr;
56e3f4
+
56e3f4
+	if (!rtw89_physts_ie_page_valid(&ie_page))
56e3f4
+		return;
56e3f4
+
56e3f4
+	if (chip->chip_id == RTL8852A)
56e3f4
+		val &= B_PHY_STS_BITMAP_MSK_52A;
56e3f4
+
56e3f4
+	addr = rtw89_phy_get_ie_bitmap_addr(ie_page);
56e3f4
+	rtw89_phy_write32(rtwdev, addr, val);
56e3f4
+}
56e3f4
+
56e3f4
+static void rtw89_physts_enable_ie_bitmap(struct rtw89_dev *rtwdev,
56e3f4
+					  enum rtw89_phy_status_bitmap bitmap,
56e3f4
+					  enum rtw89_phy_status_ie_type ie,
56e3f4
+					  bool enable)
56e3f4
+{
56e3f4
+	u32 val = rtw89_physts_get_ie_bitmap(rtwdev, bitmap);
56e3f4
+
56e3f4
+	if (enable)
56e3f4
+		val |= BIT(ie);
56e3f4
+	else
56e3f4
+		val &= ~BIT(ie);
56e3f4
+
56e3f4
+	rtw89_physts_set_ie_bitmap(rtwdev, bitmap, val);
56e3f4
+}
56e3f4
+
56e3f4
+static void rtw89_physts_enable_fail_report(struct rtw89_dev *rtwdev,
56e3f4
+					    bool enable,
56e3f4
+					    enum rtw89_phy_idx phy_idx)
56e3f4
+{
56e3f4
+	if (enable) {
56e3f4
+		rtw89_phy_write32_clr(rtwdev, R_PLCP_HISTOGRAM,
56e3f4
+				      B_STS_DIS_TRIG_BY_FAIL);
56e3f4
+		rtw89_phy_write32_clr(rtwdev, R_PLCP_HISTOGRAM,
56e3f4
+				      B_STS_DIS_TRIG_BY_BRK);
56e3f4
+	} else {
56e3f4
+		rtw89_phy_write32_set(rtwdev, R_PLCP_HISTOGRAM,
56e3f4
+				      B_STS_DIS_TRIG_BY_FAIL);
56e3f4
+		rtw89_phy_write32_set(rtwdev, R_PLCP_HISTOGRAM,
56e3f4
+				      B_STS_DIS_TRIG_BY_BRK);
56e3f4
+	}
56e3f4
+}
56e3f4
+
56e3f4
+static void rtw89_physts_parsing_init(struct rtw89_dev *rtwdev)
56e3f4
+{
56e3f4
+	const struct rtw89_chip_info *chip = rtwdev->chip;
56e3f4
+	u8 i;
56e3f4
+
56e3f4
+	if (chip->chip_id == RTL8852A && rtwdev->hal.cv == CHIP_CBV)
56e3f4
+		rtw89_physts_enable_fail_report(rtwdev, false, RTW89_PHY_0);
56e3f4
+
56e3f4
+	for (i = 0; i < RTW89_PHYSTS_BITMAP_NUM; i++) {
56e3f4
+		if (i >= RTW89_CCK_PKT)
56e3f4
+			rtw89_physts_enable_ie_bitmap(rtwdev, i,
56e3f4
+						      RTW89_PHYSTS_IE09_FTR_0,
56e3f4
+						      true);
56e3f4
+		if ((i >= RTW89_CCK_BRK && i <= RTW89_VHT_MU) ||
56e3f4
+		    (i >= RTW89_RSVD_9 && i <= RTW89_CCK_PKT))
56e3f4
+			continue;
56e3f4
+		rtw89_physts_enable_ie_bitmap(rtwdev, i,
56e3f4
+					      RTW89_PHYSTS_IE24_OFDM_TD_PATH_A,
56e3f4
+					      true);
56e3f4
+	}
56e3f4
+	rtw89_physts_enable_ie_bitmap(rtwdev, RTW89_VHT_PKT,
56e3f4
+				      RTW89_PHYSTS_IE13_DL_MU_DEF, true);
56e3f4
+	rtw89_physts_enable_ie_bitmap(rtwdev, RTW89_HE_PKT,
56e3f4
+				      RTW89_PHYSTS_IE13_DL_MU_DEF, true);
56e3f4
+
56e3f4
+	/* force IE01 for channel index, only channel field is valid */
56e3f4
+	rtw89_physts_enable_ie_bitmap(rtwdev, RTW89_CCK_PKT,
56e3f4
+				      RTW89_PHYSTS_IE01_CMN_OFDM, true);
56e3f4
+}
56e3f4
+
56e3f4
 static void rtw89_phy_dig_read_gain_table(struct rtw89_dev *rtwdev, int type)
56e3f4
 {
56e3f4
 	const struct rtw89_chip_info *chip = rtwdev->chip;
56e3f4
@@ -2856,6 +2966,7 @@ void rtw89_phy_dm_init(struct rtw89_dev *rtwdev)
56e3f4
 	rtw89_chip_bb_sethw(rtwdev);
56e3f4
 
56e3f4
 	rtw89_phy_env_monitor_init(rtwdev);
56e3f4
+	rtw89_physts_parsing_init(rtwdev);
56e3f4
 	rtw89_phy_dig_init(rtwdev);
56e3f4
 	rtw89_phy_cfo_init(rtwdev);
56e3f4
 
56e3f4
diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h
56e3f4
index 370129345e0f..b1f059b725a1 100644
56e3f4
--- a/drivers/net/wireless/realtek/rtw89/phy.h
56e3f4
+++ b/drivers/net/wireless/realtek/rtw89/phy.h
56e3f4
@@ -134,6 +134,66 @@ enum rtw89_ccx_unit {
56e3f4
 	RTW89_CCX_32_US = 3
56e3f4
 };
56e3f4
 
56e3f4
+enum rtw89_phy_status_ie_type {
56e3f4
+	RTW89_PHYSTS_IE00_CMN_CCK			= 0,
56e3f4
+	RTW89_PHYSTS_IE01_CMN_OFDM			= 1,
56e3f4
+	RTW89_PHYSTS_IE02_CMN_EXT_AX			= 2,
56e3f4
+	RTW89_PHYSTS_IE03_CMN_EXT_SEG_1			= 3,
56e3f4
+	RTW89_PHYSTS_IE04_CMN_EXT_PATH_A		= 4,
56e3f4
+	RTW89_PHYSTS_IE05_CMN_EXT_PATH_B		= 5,
56e3f4
+	RTW89_PHYSTS_IE06_CMN_EXT_PATH_C		= 6,
56e3f4
+	RTW89_PHYSTS_IE07_CMN_EXT_PATH_D		= 7,
56e3f4
+	RTW89_PHYSTS_IE08_FTR_CH			= 8,
56e3f4
+	RTW89_PHYSTS_IE09_FTR_0				= 9,
56e3f4
+	RTW89_PHYSTS_IE10_FTR_PLCP_EXT			= 10,
56e3f4
+	RTW89_PHYSTS_IE11_FTR_PLCP_HISTOGRAM		= 11,
56e3f4
+	RTW89_PHYSTS_IE12_MU_EIGEN_INFO			= 12,
56e3f4
+	RTW89_PHYSTS_IE13_DL_MU_DEF			= 13,
56e3f4
+	RTW89_PHYSTS_IE14_TB_UL_CQI			= 14,
56e3f4
+	RTW89_PHYSTS_IE15_TB_UL_DEF			= 15,
56e3f4
+	RTW89_PHYSTS_IE16_RSVD16			= 16,
56e3f4
+	RTW89_PHYSTS_IE17_TB_UL_CTRL			= 17,
56e3f4
+	RTW89_PHYSTS_IE18_DBG_OFDM_FD_CMN		= 18,
56e3f4
+	RTW89_PHYSTS_IE19_DBG_OFDM_TD_CMN		= 19,
56e3f4
+	RTW89_PHYSTS_IE20_DBG_OFDM_FD_USER_SEG_0	= 20,
56e3f4
+	RTW89_PHYSTS_IE21_DBG_OFDM_FD_USER_SEG_1	= 21,
56e3f4
+	RTW89_PHYSTS_IE22_DBG_OFDM_FD_USER_AGC		= 22,
56e3f4
+	RTW89_PHYSTS_IE23_RSVD23			= 23,
56e3f4
+	RTW89_PHYSTS_IE24_OFDM_TD_PATH_A		= 24,
56e3f4
+	RTW89_PHYSTS_IE25_OFDM_TD_PATH_B		= 25,
56e3f4
+	RTW89_PHYSTS_IE26_OFDM_TD_PATH_C		= 26,
56e3f4
+	RTW89_PHYSTS_IE27_OFDM_TD_PATH_D		= 27,
56e3f4
+	RTW89_PHYSTS_IE28_DBG_CCK_PATH_A		= 28,
56e3f4
+	RTW89_PHYSTS_IE29_DBG_CCK_PATH_B		= 29,
56e3f4
+	RTW89_PHYSTS_IE30_DBG_CCK_PATH_C		= 30,
56e3f4
+	RTW89_PHYSTS_IE31_DBG_CCK_PATH_D		= 31,
56e3f4
+
56e3f4
+	/* keep last */
56e3f4
+	RTW89_PHYSTS_IE_NUM,
56e3f4
+	RTW89_PHYSTS_IE_MAX = RTW89_PHYSTS_IE_NUM - 1
56e3f4
+};
56e3f4
+
56e3f4
+enum rtw89_phy_status_bitmap {
56e3f4
+	RTW89_TD_SEARCH_FAIL  = 0,
56e3f4
+	RTW89_BRK_BY_TX_PKT   = 1,
56e3f4
+	RTW89_CCA_SPOOF       = 2,
56e3f4
+	RTW89_OFDM_BRK        = 3,
56e3f4
+	RTW89_CCK_BRK         = 4,
56e3f4
+	RTW89_DL_MU_SPOOFING  = 5,
56e3f4
+	RTW89_HE_MU           = 6,
56e3f4
+	RTW89_VHT_MU          = 7,
56e3f4
+	RTW89_UL_TB_SPOOFING  = 8,
56e3f4
+	RTW89_RSVD_9          = 9,
56e3f4
+	RTW89_TRIG_BASE_PPDU  = 10,
56e3f4
+	RTW89_CCK_PKT         = 11,
56e3f4
+	RTW89_LEGACY_OFDM_PKT = 12,
56e3f4
+	RTW89_HT_PKT          = 13,
56e3f4
+	RTW89_VHT_PKT         = 14,
56e3f4
+	RTW89_HE_PKT          = 15,
56e3f4
+
56e3f4
+	RTW89_PHYSTS_BITMAP_NUM
56e3f4
+};
56e3f4
+
56e3f4
 enum rtw89_dig_gain_type {
56e3f4
 	RTW89_DIG_GAIN_LNA_G = 0,
56e3f4
 	RTW89_DIG_GAIN_TIA_G = 1,
56e3f4
diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h
56e3f4
index 365d8c8ce57b..b6049009f183 100644
56e3f4
--- a/drivers/net/wireless/realtek/rtw89/reg.h
56e3f4
+++ b/drivers/net/wireless/realtek/rtw89/reg.h
56e3f4
@@ -1674,6 +1674,29 @@
56e3f4
 #define B_UPD_CLK_ADC_VAL GENMASK(26, 25)
56e3f4
 #define R_RSTB_ASYNC 0x0704
56e3f4
 #define B_RSTB_ASYNC_ALL BIT(1)
56e3f4
+#define R_MAC_PIN_SEL 0x0734
56e3f4
+#define B_CH_IDX_SEG0 GENMASK(23, 16)
56e3f4
+#define R_PLCP_HISTOGRAM 0x0738
56e3f4
+#define B_STS_DIS_TRIG_BY_BRK BIT(2)
56e3f4
+#define B_STS_DIS_TRIG_BY_FAIL BIT(3)
56e3f4
+#define R_PHY_STS_BITMAP_ADDR_START R_PHY_STS_BITMAP_SEARCH_FAIL
56e3f4
+#define B_PHY_STS_BITMAP_ADDR_MASK GENMASK(6, 2)
56e3f4
+#define R_PHY_STS_BITMAP_SEARCH_FAIL 0x073C
56e3f4
+#define B_PHY_STS_BITMAP_MSK_52A 0x337cff3f
56e3f4
+#define R_PHY_STS_BITMAP_R2T 0x0740
56e3f4
+#define R_PHY_STS_BITMAP_CCA_SPOOF 0x0744
56e3f4
+#define R_PHY_STS_BITMAP_OFDM_BRK 0x0748
56e3f4
+#define R_PHY_STS_BITMAP_CCK_BRK 0x074C
56e3f4
+#define R_PHY_STS_BITMAP_DL_MU_SPOOF 0x0750
56e3f4
+#define R_PHY_STS_BITMAP_HE_MU 0x0754
56e3f4
+#define R_PHY_STS_BITMAP_VHT_MU 0x0758
56e3f4
+#define R_PHY_STS_BITMAP_UL_TB_SPOOF 0x075C
56e3f4
+#define R_PHY_STS_BITMAP_TRIGBASE 0x0760
56e3f4
+#define R_PHY_STS_BITMAP_CCK 0x0764
56e3f4
+#define R_PHY_STS_BITMAP_LEGACY 0x0768
56e3f4
+#define R_PHY_STS_BITMAP_HT 0x076C
56e3f4
+#define R_PHY_STS_BITMAP_VHT 0x0770
56e3f4
+#define R_PHY_STS_BITMAP_HE 0x0774
56e3f4
 #define R_PMAC_GNT 0x0980
56e3f4
 #define B_PMAC_GNT_TXEN BIT(0)
56e3f4
 #define B_PMAC_GNT_RXEN BIT(16)
56e3f4
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
56e3f4
index 9e25e53f6c4a..5ec13ae0abcd 100644
56e3f4
--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c
56e3f4
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
56e3f4
@@ -1069,6 +1069,8 @@ static void rtw8852a_set_channel_bb(struct rtw89_dev *rtwdev,
56e3f4
 		rtw8852a_bbrst_for_rfk(rtwdev, phy_idx);
56e3f4
 	}
56e3f4
 	rtw8852a_spur_elimination(rtwdev, param->center_chan);
56e3f4
+	rtw89_phy_write32_mask(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0,
56e3f4
+			       param->primary_chan);
56e3f4
 	rtw8852a_bb_reset_all(rtwdev, phy_idx);
56e3f4
 }
56e3f4
 
56e3f4
@@ -1927,6 +1929,21 @@ void rtw8852a_btc_wl_s1_standby(struct rtw89_dev *rtwdev, bool state)
56e3f4
 	rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0);
56e3f4
 }
56e3f4
 
56e3f4
+static void rtw8852a_fill_freq_with_ppdu(struct rtw89_dev *rtwdev,
56e3f4
+					 struct rtw89_rx_phy_ppdu *phy_ppdu,
56e3f4
+					 struct ieee80211_rx_status *status)
56e3f4
+{
56e3f4
+	u16 chan = phy_ppdu->chan_idx;
56e3f4
+	u8 band;
56e3f4
+
56e3f4
+	if (chan == 0)
56e3f4
+		return;
56e3f4
+
56e3f4
+	band = chan <= 14 ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
56e3f4
+	status->freq = ieee80211_channel_to_frequency(chan, band);
56e3f4
+	status->band = band;
56e3f4
+}
56e3f4
+
56e3f4
 static void rtw8852a_query_ppdu(struct rtw89_dev *rtwdev,
56e3f4
 				struct rtw89_rx_phy_ppdu *phy_ppdu,
56e3f4
 				struct ieee80211_rx_status *status)
56e3f4
@@ -1939,6 +1956,8 @@ static void rtw8852a_query_ppdu(struct rtw89_dev *rtwdev,
56e3f4
 		status->chains |= BIT(path);
56e3f4
 		status->chain_signal[path] = rx_power[path];
56e3f4
 	}
56e3f4
+	if (phy_ppdu->valid)
56e3f4
+		rtw8852a_fill_freq_with_ppdu(rtwdev, phy_ppdu, status);
56e3f4
 }
56e3f4
 
56e3f4
 static const struct rtw89_chip_ops rtw8852a_chip_ops = {
56e3f4
diff --git a/drivers/net/wireless/realtek/rtw89/txrx.h b/drivers/net/wireless/realtek/rtw89/txrx.h
56e3f4
index 5570d8ccf136..75b11249f306 100644
56e3f4
--- a/drivers/net/wireless/realtek/rtw89/txrx.h
56e3f4
+++ b/drivers/net/wireless/realtek/rtw89/txrx.h
56e3f4
@@ -168,6 +168,8 @@
56e3f4
 #define RTW89_GET_RXINFO_MACID(rpt, usr) \
56e3f4
 	le32_get_bits(*((const __le32 *)(rpt) + (usr) + 2), GENMASK(15, 8))
56e3f4
 
56e3f4
+#define RTW89_GET_PHY_STS_IE_MAP(sts) \
56e3f4
+	le32_get_bits(*((const __le32 *)(sts)), GENMASK(4, 0))
56e3f4
 #define RTW89_GET_PHY_STS_RSSI_A(sts) \
56e3f4
 	le32_get_bits(*((const __le32 *)(sts) + 1), GENMASK(7, 0))
56e3f4
 #define RTW89_GET_PHY_STS_RSSI_B(sts) \
56e3f4
@@ -184,7 +186,9 @@
56e3f4
 	le32_get_bits(*((const __le32 *)ie), GENMASK(4, 0))
56e3f4
 #define RTW89_GET_PHY_STS_IE_LEN(ie) \
56e3f4
 	le32_get_bits(*((const __le32 *)ie), GENMASK(11, 5))
56e3f4
-#define RTW89_GET_PHY_STS_IE0_CFO(ie) \
56e3f4
+#define RTW89_GET_PHY_STS_IE01_CH_IDX(ie) \
56e3f4
+	le32_get_bits(*((const __le32 *)ie), GENMASK(23, 16))
56e3f4
+#define RTW89_GET_PHY_STS_IE01_CFO(ie) \
56e3f4
 	le32_get_bits(*((const __le32 *)(ie) + 1), GENMASK(31, 20))
56e3f4
 
56e3f4
 enum rtw89_tx_channel {
56e3f4
@@ -251,45 +255,6 @@ enum rtw89_tx_qsel {
56e3f4
 	/* reserved */
56e3f4
 };
56e3f4
 
56e3f4
-enum rtw89_phy_status_ie_type {
56e3f4
-	RTW89_PHYSTS_IE00_CMN_CCK			= 0,
56e3f4
-	RTW89_PHYSTS_IE01_CMN_OFDM			= 1,
56e3f4
-	RTW89_PHYSTS_IE02_CMN_EXT_AX			= 2,
56e3f4
-	RTW89_PHYSTS_IE03_CMN_EXT_SEG_1			= 3,
56e3f4
-	RTW89_PHYSTS_IE04_CMN_EXT_PATH_A		= 4,
56e3f4
-	RTW89_PHYSTS_IE05_CMN_EXT_PATH_B		= 5,
56e3f4
-	RTW89_PHYSTS_IE06_CMN_EXT_PATH_C		= 6,
56e3f4
-	RTW89_PHYSTS_IE07_CMN_EXT_PATH_D		= 7,
56e3f4
-	RTW89_PHYSTS_IE08_FTR_CH			= 8,
56e3f4
-	RTW89_PHYSTS_IE09_FTR_PLCP_0			= 9,
56e3f4
-	RTW89_PHYSTS_IE10_FTR_PLCP_EXT			= 10,
56e3f4
-	RTW89_PHYSTS_IE11_FTR_PLCP_HISTOGRAM		= 11,
56e3f4
-	RTW89_PHYSTS_IE12_MU_EIGEN_INFO			= 12,
56e3f4
-	RTW89_PHYSTS_IE13_DL_MU_DEF			= 13,
56e3f4
-	RTW89_PHYSTS_IE14_TB_UL_CQI			= 14,
56e3f4
-	RTW89_PHYSTS_IE15_TB_UL_DEF			= 15,
56e3f4
-	RTW89_PHYSTS_IE16_RSVD16			= 16,
56e3f4
-	RTW89_PHYSTS_IE17_TB_UL_CTRL			= 17,
56e3f4
-	RTW89_PHYSTS_IE18_DBG_OFDM_FD_CMN		= 18,
56e3f4
-	RTW89_PHYSTS_IE19_DBG_OFDM_TD_CMN		= 19,
56e3f4
-	RTW89_PHYSTS_IE20_DBG_OFDM_FD_USER_SEG_0	= 20,
56e3f4
-	RTW89_PHYSTS_IE21_DBG_OFDM_FD_USER_SEG_1	= 21,
56e3f4
-	RTW89_PHYSTS_IE22_DBG_OFDM_FD_USER_AGC		= 22,
56e3f4
-	RTW89_PHYSTS_IE23_RSVD23			= 23,
56e3f4
-	RTW89_PHYSTS_IE24_DBG_OFDM_TD_PATH_A		= 24,
56e3f4
-	RTW89_PHYSTS_IE25_DBG_OFDM_TD_PATH_B		= 25,
56e3f4
-	RTW89_PHYSTS_IE26_DBG_OFDM_TD_PATH_C		= 26,
56e3f4
-	RTW89_PHYSTS_IE27_DBG_OFDM_TD_PATH_D		= 27,
56e3f4
-	RTW89_PHYSTS_IE28_DBG_CCK_PATH_A		= 28,
56e3f4
-	RTW89_PHYSTS_IE29_DBG_CCK_PATH_B		= 29,
56e3f4
-	RTW89_PHYSTS_IE30_DBG_CCK_PATH_C		= 30,
56e3f4
-	RTW89_PHYSTS_IE31_DBG_CCK_PATH_D		= 31,
56e3f4
-
56e3f4
-	/* keep last */
56e3f4
-	RTW89_PHYSTS_IE_NUM,
56e3f4
-	RTW89_PHYSTS_IE_MAX = RTW89_PHYSTS_IE_NUM - 1
56e3f4
-};
56e3f4
-
56e3f4
 static inline u8 rtw89_core_get_qsel(struct rtw89_dev *rtwdev, u8 tid)
56e3f4
 {
56e3f4
 	switch (tid) {
56e3f4
-- 
56e3f4
2.13.6
56e3f4