diff mbox series

[10/14] rtw89: 8852c: configure default BB TX/RX path

Message ID 20220421120903.73715-11-pkshih@realtek.com
State New
Headers show
Series rtw89: 8852c: extend PCI code to support 8852ce and add 8852c chip_ops | expand

Commit Message

Ping-Ke Shih April 21, 2022, 12:08 p.m. UTC
8852c propose new API to configure BB TX/RX path. Without fix patch, it
can't transmit any packet.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/core.h     |   9 +
 drivers/net/wireless/realtek/rtw89/phy.c      |   1 +
 drivers/net/wireless/realtek/rtw89/reg.h      |  76 ++++++-
 drivers/net/wireless/realtek/rtw89/rtw8852a.c |   1 +
 drivers/net/wireless/realtek/rtw89/rtw8852c.c | 194 ++++++++++++++++++
 5 files changed, 279 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 9be74d8673cfd..d544cf29e588a 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -2104,6 +2104,7 @@  struct rtw89_chip_ops {
 			   struct rtw89_rx_phy_ppdu *phy_ppdu,
 			   struct ieee80211_rx_status *status);
 	void (*bb_ctrl_btc_preagc)(struct rtw89_dev *rtwdev, bool bt_en);
+	void (*cfg_txrx_path)(struct rtw89_dev *rtwdev);
 	void (*set_txpwr_ul_tb_offset)(struct rtw89_dev *rtwdev,
 				       s8 pw_ofst, enum rtw89_mac_idx mac_idx);
 	int (*pwr_on_func)(struct rtw89_dev *rtwdev);
@@ -3633,6 +3634,14 @@  static inline void rtw89_chip_bb_ctrl_btc_preagc(struct rtw89_dev *rtwdev,
 		chip->ops->bb_ctrl_btc_preagc(rtwdev, bt_en);
 }
 
+static inline void rtw89_chip_cfg_txrx_path(struct rtw89_dev *rtwdev)
+{
+	const struct rtw89_chip_info *chip = rtwdev->chip;
+
+	if (chip->ops->cfg_txrx_path)
+		chip->ops->cfg_txrx_path(rtwdev);
+}
+
 static inline
 void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
 				       struct ieee80211_vif *vif)
diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c
index 7d0593d8fafe9..33494e8451cf3 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.c
+++ b/drivers/net/wireless/realtek/rtw89/phy.c
@@ -3592,6 +3592,7 @@  void rtw89_phy_dm_init(struct rtw89_dev *rtwdev)
 	rtw89_load_txpwr_table(rtwdev, chip->byr_table);
 	rtw89_chip_set_txpwr_ctrl(rtwdev);
 	rtw89_chip_power_trim(rtwdev);
+	rtw89_chip_cfg_txrx_path(rtwdev);
 }
 
 void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h
index 0f08b25817976..6dc11e8e2a839 100644
--- a/drivers/net/wireless/realtek/rtw89/reg.h
+++ b/drivers/net/wireless/realtek/rtw89/reg.h
@@ -2962,6 +2962,45 @@ 
 #define R_AX_PWR_MACID_LMT_TABLE0 0xD36C
 #define R_AX_PWR_MACID_LMT_TABLE127 0xD568
 
+#define R_AX_PATH_COM0 0xD800
+#define AX_PATH_COM0_DFVAL 0x00000000
+#define AX_PATH_COM0_PATHA 0x08888880
+#define AX_PATH_COM0_PATHB 0x11111100
+#define AX_PATH_COM0_PATHAB 0x19999980
+#define R_AX_PATH_COM1 0xD804
+#define AX_PATH_COM1_DFVAL 0x00000000
+#define AX_PATH_COM1_PATHA 0x11111111
+#define AX_PATH_COM1_PATHB 0x22222222
+#define AX_PATH_COM1_PATHAB 0x33333333
+#define R_AX_PATH_COM2 0xD808
+#define AX_PATH_COM2_DFVAL 0x00000000
+#define AX_PATH_COM2_PATHA 0x01209111
+#define AX_PATH_COM2_PATHB 0x01209222
+#define AX_PATH_COM2_PATHAB 0x01209333
+#define R_AX_PATH_COM3 0xD80C
+#define AX_PATH_COM3_DFVAL 0x49249249
+#define R_AX_PATH_COM4 0xD810
+#define AX_PATH_COM4_DFVAL 0x1C9C9C49
+#define R_AX_PATH_COM5 0xD814
+#define AX_PATH_COM5_DFVAL 0x39393939
+#define R_AX_PATH_COM6 0xD818
+#define AX_PATH_COM6_DFVAL 0x39393939
+#define R_AX_PATH_COM7 0xD81C
+#define AX_PATH_COM7_DFVAL 0x39393939
+#define AX_PATH_COM7_PATHA 0x39393939
+#define AX_PATH_COM7_PATHB 0x39383939
+#define AX_PATH_COM7_PATHAB 0x39393939
+#define R_AX_PATH_COM8 0xD820
+#define AX_PATH_COM8_DFVAL 0x00000000
+#define AX_PATH_COM8_PATHA 0x00003939
+#define AX_PATH_COM8_PATHB 0x00003938
+#define AX_PATH_COM8_PATHAB 0x00003939
+#define R_AX_PATH_COM9 0xD824
+#define AX_PATH_COM9_DFVAL 0x000007C0
+#define R_AX_PATH_COM10 0xD828
+#define AX_PATH_COM10_DFVAL 0xE0000000
+#define R_AX_PATH_COM11 0xD82C
+#define AX_PATH_COM11_DFVAL 0x00000000
 #define R_P80_AT_HIGH_FREQ_BB_WRP 0xD848
 #define B_P80_AT_HIGH_FREQ_BB_WRP BIT(28)
 #define R_AX_TSSI_CTRL_HEAD 0xD908
@@ -3097,6 +3136,9 @@ 
 #define R_AX_LTE_WDATA 0xDAF4
 #define R_AX_LTE_RDATA 0xDAF8
 
+#define R_AX_MACID_ANT_TABLE 0xDC00
+#define R_AX_MACID_ANT_TABLE_LAST 0xDDFC
+
 #define CMAC1_START_ADDR 0xE000
 #define CMAC1_END_ADDR 0xFFFF
 #define R_AX_CMAC_REG_END 0xFFFF
@@ -3360,9 +3402,10 @@ 
 #define R_PMAC_RXMOD 0x0994
 #define B_PMAC_RXMOD_MSK GENMASK(7, 4)
 #define R_MAC_SEL 0x09A4
-#define B_MAC_SEL_MOD GENMASK(4, 2)
-#define B_MAC_SEL_DPD_EN BIT(10)
+#define B_MAC_SEL_OFDM_TRI_FILTER BIT(31)
 #define B_MAC_SEL_PWR_EN BIT(16)
+#define B_MAC_SEL_DPD_EN BIT(10)
+#define B_MAC_SEL_MOD GENMASK(4, 2)
 #define R_PMAC_TX_CTRL 0x09C0
 #define B_PMAC_TXEN_DIS BIT(0)
 #define R_PMAC_TX_PRD 0x09C4
@@ -3413,8 +3456,16 @@ 
 #define B_SNDCCA_A1_EN GENMASK(19, 12)
 #define R_SNDCCA_A2 0x0CA0
 #define B_SNDCCA_A2_VAL GENMASK(19, 12)
+#define R_RXHT_MCS_LIMIT 0x0D18
+#define B_RXHT_MCS_LIMIT GENMASK(9, 8)
+#define R_RXVHT_MCS_LIMIT 0x0D18
+#define B_RXVHT_MCS_LIMIT GENMASK(22, 21)
 #define R_P0_EN_SOUND_WO_NDP 0x0D7C
 #define B_P0_EN_SOUND_WO_NDP BIT(1)
+#define R_RXHE 0x0D80
+#define B_RXHETB_MAX_NSS GENMASK(25, 23)
+#define B_RXHE_MAX_NSS GENMASK(16, 14)
+#define B_RXHE_USER_MAX GENMASK(13, 6)
 #define R_SPOOF_ASYNC_RST 0x0D84
 #define B_SPOOF_ASYNC_RST BIT(15)
 #define R_NDP_BRK0 0xDA0
@@ -3634,6 +3685,8 @@ 
 #define B_PATH0_P20_FOLLOW_BY_PAGCUGC_EN_MSK BIT(5)
 #define R_PATH0_S20_FOLLOW_BY_PAGCUGC 0x46A4
 #define B_PATH0_S20_FOLLOW_BY_PAGCUGC_EN_MSK BIT(5)
+#define R_PATH0_G_LNA6_OP1DB_V1 0x4688
+#define B_PATH0_G_LNA6_OP1DB_V1 GENMASK(31, 24)
 #define R_PATH0_G_TIA0_LNA6_OP1DB_V1 0x4694
 #define B_PATH0_G_TIA0_LNA6_OP1DB_V1 GENMASK(7, 0)
 #define R_PATH0_G_TIA1_LNA6_OP1DB_V1 0x4694
@@ -3650,6 +3703,9 @@ 
 #define R_P0_NBIIDX 0x469C
 #define B_P0_NBIIDX_VAL GENMASK(11, 0)
 #define B_P0_NBIIDX_NOTCH_EN BIT(12)
+#define R_P0_BACKOFF_IBADC_V1 0x469C
+#define B_P0_BACKOFF_IBADC_V1 GENMASK(31, 26)
+#define B_P0_NBIIDX_NOTCH_EN_V1 BIT(12)
 #define R_P1_MODE 0x4718
 #define B_P1_MODE_SEL GENMASK(31, 30)
 #define R_PATH1_LNA_INIT 0x473C
@@ -3668,6 +3724,8 @@ 
 #define B_PATH1_S20_FOLLOW_BY_PAGCUGC_EN_MSK BIT(5)
 #define R_PATH1_G_TIA0_LNA6_OP1DB_V1 0x4778
 #define B_PATH1_G_TIA0_LNA6_OP1DB_V1 GENMASK(7, 0)
+#define R_PATH1_G_TIA1_LNA6_OP1DB_V1 0x4778
+#define B_PATH1_G_TIA1_LNA6_OP1DB_V1 GENMASK(15, 8)
 #define R_PATH1_BAND_SEL_V1 0x4AA4
 #define B_PATH1_BAND_SEL_MSK_V1 BIT(17)
 #define R_PATH1_BT_SHARE_V1 0x4AA4
@@ -3693,15 +3751,29 @@ 
 #define B_CHBW_MOD_SBW GENMASK(13, 12)
 #define B_CHBW_MOD_PRICH GENMASK(11, 8)
 #define B_ANT_RX_SEG0 GENMASK(3, 0)
+#define R_P1_BACKOFF_IBADC_V1 0x49F0
+#define B_P1_BACKOFF_IBADC_V1 GENMASK(31, 26)
 #define R_BK_FC0_INV_V1 0x4A1C
 #define B_BK_FC0_INV_MSK_V1 GENMASK(18, 0)
 #define R_CCK_FC0_INV_V1 0x4A20
 #define B_CCK_FC0_INV_MSK_V1 GENMASK(18, 0)
+#define R_PATH0_RXBB_V1 0x4AD4
+#define B_PATH0_RXBB_MSK_V1 GENMASK(31, 0)
+#define R_PATH1_RXBB_V1 0x4AE0
+#define B_PATH1_RXBB_MSK_V1 GENMASK(31, 0)
+#define R_PATH0_BT_BACKOFF_V1 0x4AE4
+#define B_PATH0_BT_BACKOFF_V1 GENMASK(23, 0)
+#define R_PATH1_BT_BACKOFF_V1 0x4AEC
+#define B_PATH1_BT_BACKOFF_V1 GENMASK(23, 0)
+#define R_PATH0_FRC_FIR_TYPE_V1 0x4C00
+#define B_PATH0_FRC_FIR_TYPE_MSK_V1 GENMASK(1, 0)
 #define R_PATH0_5MDET 0x4C4C
 #define B_PATH0_5MDET_EN BIT(12)
 #define B_PATH0_5MDET_SB2 BIT(8)
 #define B_PATH0_5MDET_SB0 BIT(6)
 #define B_PATH0_5MDET_TH GENMASK(5, 0)
+#define R_PATH1_FRC_FIR_TYPE_V1 0x4CC4
+#define B_PATH1_FRC_FIR_TYPE_MSK_V1 GENMASK(1, 0)
 #define R_PATH1_5MDET 0x4D10
 #define B_PATH1_5MDET_EN BIT(12)
 #define B_PATH1_5MDET_SB2 BIT(8)
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
index 5af618709dedd..81bd0c4fe21bc 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
@@ -2066,6 +2066,7 @@  static const struct rtw89_chip_ops rtw8852a_chip_ops = {
 	.ctrl_btg		= rtw8852a_ctrl_btg,
 	.query_ppdu		= rtw8852a_query_ppdu,
 	.bb_ctrl_btc_preagc	= rtw8852a_bb_ctrl_btc_preagc,
+	.cfg_txrx_path		= NULL,
 	.set_txpwr_ul_tb_offset	= rtw8852a_set_txpwr_ul_tb_offset,
 	.pwr_on_func		= NULL,
 	.pwr_off_func		= NULL,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
index 3ee57df0a6396..290c453d8c23a 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
@@ -1813,6 +1813,199 @@  void rtw8852c_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
 	}
 }
 
+static void rtw8852c_bb_cfg_rx_path(struct rtw89_dev *rtwdev, u8 rx_path)
+{
+	struct rtw89_hal *hal = &rtwdev->hal;
+	u32 rst_mask0 = B_P0_TXPW_RSTB_MANON | B_P0_TXPW_RSTB_TSSI;
+	u32 rst_mask1 = B_P1_TXPW_RSTB_MANON | B_P1_TXPW_RSTB_TSSI;
+
+	if (rtwdev->dbcc_en) {
+		rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD, B_ANT_RX_SEG0, 1);
+		rtw89_phy_write32_idx(rtwdev, R_CHBW_MOD, B_ANT_RX_SEG0, 2,
+				      RTW89_PHY_1);
+
+		rtw89_phy_write32_mask(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG0,
+				       1);
+		rtw89_phy_write32_mask(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG1,
+				       1);
+		rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG0, 2,
+				      RTW89_PHY_1);
+		rtw89_phy_write32_idx(rtwdev, R_FC0_BW, B_ANT_RX_1RCCA_SEG1, 2,
+				      RTW89_PHY_1);
+
+		rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT,
+				       B_RXHT_MCS_LIMIT, 0);
+		rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT,
+				       B_RXVHT_MCS_LIMIT, 0);
+		rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, 8);
+		rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0);
+		rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0);
+
+		rtw89_phy_write32_idx(rtwdev, R_RXHT_MCS_LIMIT,
+				      B_RXHT_MCS_LIMIT, 0, RTW89_PHY_1);
+		rtw89_phy_write32_idx(rtwdev, R_RXVHT_MCS_LIMIT,
+				      B_RXVHT_MCS_LIMIT, 0, RTW89_PHY_1);
+		rtw89_phy_write32_idx(rtwdev, R_RXHE, B_RXHE_USER_MAX, 1,
+				      RTW89_PHY_1);
+		rtw89_phy_write32_idx(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0,
+				      RTW89_PHY_1);
+		rtw89_phy_write32_idx(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0,
+				      RTW89_PHY_1);
+		rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 1);
+		rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB, rst_mask0, 3);
+		rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, rst_mask1, 1);
+		rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB, rst_mask1, 3);
+	} else {
+		if (rx_path == RF_PATH_A) {
+			rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD,
+					       B_ANT_RX_SEG0, 1);
+			rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
+					       B_ANT_RX_1RCCA_SEG0, 1);
+			rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
+					       B_ANT_RX_1RCCA_SEG1, 1);
+			rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT,
+					       B_RXHT_MCS_LIMIT, 0);
+			rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT,
+					       B_RXVHT_MCS_LIMIT, 0);
+			rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS,
+					       0);
+			rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS,
+					       0);
+			rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB,
+					       rst_mask0, 1);
+			rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB,
+					       rst_mask0, 3);
+		} else if (rx_path == RF_PATH_B) {
+			rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD,
+					       B_ANT_RX_SEG0, 2);
+			rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
+					       B_ANT_RX_1RCCA_SEG0, 2);
+			rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
+					       B_ANT_RX_1RCCA_SEG1, 2);
+			rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT,
+					       B_RXHT_MCS_LIMIT, 0);
+			rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT,
+					       B_RXVHT_MCS_LIMIT, 0);
+			rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS,
+					       0);
+			rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS,
+					       0);
+			rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB,
+					       rst_mask1, 1);
+			rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB,
+					       rst_mask1, 3);
+		} else {
+			rtw89_phy_write32_mask(rtwdev, R_CHBW_MOD,
+					       B_ANT_RX_SEG0, 3);
+			rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
+					       B_ANT_RX_1RCCA_SEG0, 3);
+			rtw89_phy_write32_mask(rtwdev, R_FC0_BW,
+					       B_ANT_RX_1RCCA_SEG1, 3);
+			rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT,
+					       B_RXHT_MCS_LIMIT, 1);
+			rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT,
+					       B_RXVHT_MCS_LIMIT, 1);
+			rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS,
+					       1);
+			rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS,
+					       1);
+			rtw8852c_ctrl_btg(rtwdev, hal->current_band_type == RTW89_BAND_2G);
+			rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB,
+					       rst_mask0, 1);
+			rtw89_phy_write32_mask(rtwdev, R_P0_TXPW_RSTB,
+					       rst_mask0, 3);
+			rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB,
+					       rst_mask1, 1);
+			rtw89_phy_write32_mask(rtwdev, R_P1_TXPW_RSTB,
+					       rst_mask1, 3);
+		}
+		rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_USER_MAX, 8);
+	}
+}
+
+static void rtw8852c_ctrl_tx_path_tmac(struct rtw89_dev *rtwdev, u8 tx_path,
+				       enum rtw89_mac_idx mac_idx)
+{
+	struct rtw89_reg2_def path_com[] = {
+		{R_AX_PATH_COM0, AX_PATH_COM0_DFVAL},
+		{R_AX_PATH_COM1, AX_PATH_COM1_DFVAL},
+		{R_AX_PATH_COM2, AX_PATH_COM2_DFVAL},
+		{R_AX_PATH_COM3, AX_PATH_COM3_DFVAL},
+		{R_AX_PATH_COM4, AX_PATH_COM4_DFVAL},
+		{R_AX_PATH_COM5, AX_PATH_COM5_DFVAL},
+		{R_AX_PATH_COM6, AX_PATH_COM6_DFVAL},
+		{R_AX_PATH_COM7, AX_PATH_COM7_DFVAL},
+		{R_AX_PATH_COM8, AX_PATH_COM8_DFVAL},
+		{R_AX_PATH_COM9, AX_PATH_COM9_DFVAL},
+		{R_AX_PATH_COM10, AX_PATH_COM10_DFVAL},
+		{R_AX_PATH_COM11, AX_PATH_COM11_DFVAL},
+	};
+	u32 addr;
+	u32 reg;
+	u8 cr_size = ARRAY_SIZE(path_com);
+	u8 i = 0;
+
+	rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0, RTW89_PHY_0);
+	rtw89_phy_write32_idx(rtwdev, R_MAC_SEL, B_MAC_SEL_MOD, 0, RTW89_PHY_1);
+
+	for (addr = R_AX_MACID_ANT_TABLE;
+	     addr <= R_AX_MACID_ANT_TABLE_LAST; addr += 4) {
+		reg = rtw89_mac_reg_by_idx(addr, mac_idx);
+		rtw89_write32(rtwdev, reg, 0);
+	}
+
+	if (tx_path == RF_PATH_A) {
+		path_com[0].data = AX_PATH_COM0_PATHA;
+		path_com[1].data = AX_PATH_COM1_PATHA;
+		path_com[2].data = AX_PATH_COM2_PATHA;
+		path_com[7].data = AX_PATH_COM7_PATHA;
+		path_com[8].data = AX_PATH_COM8_PATHA;
+	} else if (tx_path == RF_PATH_B) {
+		path_com[0].data = AX_PATH_COM0_PATHB;
+		path_com[1].data = AX_PATH_COM1_PATHB;
+		path_com[2].data = AX_PATH_COM2_PATHB;
+		path_com[7].data = AX_PATH_COM7_PATHB;
+		path_com[8].data = AX_PATH_COM8_PATHB;
+	} else if (tx_path == RF_PATH_AB) {
+		path_com[0].data = AX_PATH_COM0_PATHAB;
+		path_com[1].data = AX_PATH_COM1_PATHAB;
+		path_com[2].data = AX_PATH_COM2_PATHAB;
+		path_com[7].data = AX_PATH_COM7_PATHAB;
+		path_com[8].data = AX_PATH_COM8_PATHAB;
+	} else {
+		rtw89_warn(rtwdev, "[Invalid Tx Path]Tx Path: %d\n", tx_path);
+		return;
+	}
+
+	for (i = 0; i < cr_size; i++) {
+		rtw89_debug(rtwdev, RTW89_DBG_TSSI, "0x%x = 0x%x\n",
+			    path_com[i].addr, path_com[i].data);
+		reg = rtw89_mac_reg_by_idx(path_com[i].addr, mac_idx);
+		rtw89_write32(rtwdev, reg, path_com[i].data);
+	}
+}
+
+static void rtw8852c_bb_cfg_txrx_path(struct rtw89_dev *rtwdev)
+{
+	struct rtw89_hal *hal = &rtwdev->hal;
+
+	rtw8852c_bb_cfg_rx_path(rtwdev, RF_PATH_AB);
+
+	if (hal->rx_nss == 1) {
+		rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 0);
+		rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 0);
+		rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0);
+		rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 0);
+	} else {
+		rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 1);
+		rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 1);
+		rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 1);
+		rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHETB_MAX_NSS, 1);
+	}
+
+	rtw8852c_ctrl_tx_path_tmac(rtwdev, RF_PATH_AB, RTW89_MAC_0);
+}
+
 static void rtw8852c_ctrl_btg(struct rtw89_dev *rtwdev, bool btg)
 {
 	if (btg) {
@@ -1973,6 +2166,7 @@  static const struct rtw89_chip_ops rtw8852c_chip_ops = {
 	.read_rf		= rtw89_phy_read_rf_v1,
 	.write_rf		= rtw89_phy_write_rf_v1,
 	.set_txpwr_ul_tb_offset	= rtw8852c_set_txpwr_ul_tb_offset,
+	.cfg_txrx_path		= rtw8852c_bb_cfg_txrx_path,
 	.pwr_on_func		= rtw8852c_pwr_on_func,
 	.pwr_off_func		= rtw8852c_pwr_off_func,
 	.fill_txdesc		= rtw89_core_fill_txdesc_v1,