diff mbox series

[10/12] rtw89: 8852c: set channel of MAC part

Message ID 20220414062027.62638-11-pkshih@realtek.com
State New
Headers show
Series rtw89: 8852c: add 8852c tables, TX power and set channel functions | expand

Commit Message

Ping-Ke Shih April 14, 2022, 6:20 a.m. UTC
Configure channel and bandwidth of MAC registers to work properly.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/reg.h      |  4 ++
 drivers/net/wireless/realtek/rtw89/rtw8852c.c | 71 +++++++++++++++++++
 2 files changed, 75 insertions(+)
diff mbox series

Patch

diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h
index d666c6e2a9dec..44a2d984ebe19 100644
--- a/drivers/net/wireless/realtek/rtw89/reg.h
+++ b/drivers/net/wireless/realtek/rtw89/reg.h
@@ -1802,6 +1802,10 @@ 
 #define R_AX_WMAC_RFMOD 0xC010
 #define R_AX_WMAC_RFMOD_C1 0xE010
 #define B_AX_WMAC_RFMOD_MASK GENMASK(1, 0)
+#define AX_WMAC_RFMOD_20M 0
+#define AX_WMAC_RFMOD_40M 1
+#define AX_WMAC_RFMOD_80M 2
+#define AX_WMAC_RFMOD_160M 3
 
 #define R_AX_GID_POSITION0 0xC070
 #define R_AX_GID_POSITION0_C1 0xE070
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
index 8be3cb22eb110..07ff3bd50f62b 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
@@ -562,6 +562,77 @@  static void rtw8852c_power_trim(struct rtw89_dev *rtwdev)
 	rtw8852c_pa_bias_trim(rtwdev);
 }
 
+static void rtw8852c_set_channel_mac(struct rtw89_dev *rtwdev,
+				     struct rtw89_channel_params *param,
+				     u8 mac_idx)
+{
+	u32 rf_mod = rtw89_mac_reg_by_idx(R_AX_WMAC_RFMOD, mac_idx);
+	u32 sub_carr = rtw89_mac_reg_by_idx(R_AX_TX_SUB_CARRIER_VALUE,
+					     mac_idx);
+	u32 chk_rate = rtw89_mac_reg_by_idx(R_AX_TXRATE_CHK, mac_idx);
+	u8 txsc20 = 0, txsc40 = 0, txsc80 = 0;
+	u8 rf_mod_val = 0, chk_rate_mask = 0;
+	u32 txsc;
+
+	switch (param->bandwidth) {
+	case RTW89_CHANNEL_WIDTH_160:
+		txsc80 = rtw89_phy_get_txsc(rtwdev, param,
+					    RTW89_CHANNEL_WIDTH_80);
+		fallthrough;
+	case RTW89_CHANNEL_WIDTH_80:
+		txsc40 = rtw89_phy_get_txsc(rtwdev, param,
+					    RTW89_CHANNEL_WIDTH_40);
+		fallthrough;
+	case RTW89_CHANNEL_WIDTH_40:
+		txsc20 = rtw89_phy_get_txsc(rtwdev, param,
+					    RTW89_CHANNEL_WIDTH_20);
+		break;
+	default:
+		break;
+	}
+
+	switch (param->bandwidth) {
+	case RTW89_CHANNEL_WIDTH_160:
+		rf_mod_val = AX_WMAC_RFMOD_160M;
+		txsc = FIELD_PREP(B_AX_TXSC_20M_MASK, txsc20) |
+		       FIELD_PREP(B_AX_TXSC_40M_MASK, txsc40) |
+		       FIELD_PREP(B_AX_TXSC_80M_MASK, txsc80);
+		break;
+	case RTW89_CHANNEL_WIDTH_80:
+		rf_mod_val = AX_WMAC_RFMOD_80M;
+		txsc = FIELD_PREP(B_AX_TXSC_20M_MASK, txsc20) |
+		       FIELD_PREP(B_AX_TXSC_40M_MASK, txsc40);
+		break;
+	case RTW89_CHANNEL_WIDTH_40:
+		rf_mod_val = AX_WMAC_RFMOD_40M;
+		txsc = FIELD_PREP(B_AX_TXSC_20M_MASK, txsc20);
+		break;
+	case RTW89_CHANNEL_WIDTH_20:
+	default:
+		rf_mod_val = AX_WMAC_RFMOD_20M;
+		txsc = 0;
+		break;
+	}
+	rtw89_write8_mask(rtwdev, rf_mod, B_AX_WMAC_RFMOD_MASK, rf_mod_val);
+	rtw89_write32(rtwdev, sub_carr, txsc);
+
+	switch (param->band_type) {
+	case RTW89_BAND_2G:
+		chk_rate_mask = B_AX_BAND_MODE;
+		break;
+	case RTW89_BAND_5G:
+	case RTW89_BAND_6G:
+		chk_rate_mask = B_AX_CHECK_CCK_EN | B_AX_RTS_LIMIT_IN_OFDM6;
+		break;
+	default:
+		rtw89_warn(rtwdev, "Invalid band_type:%d\n", param->band_type);
+		return;
+	}
+	rtw89_write8_clr(rtwdev, chk_rate, B_AX_BAND_MODE | B_AX_CHECK_CCK_EN |
+					   B_AX_RTS_LIMIT_IN_OFDM6);
+	rtw89_write8_set(rtwdev, chk_rate, chk_rate_mask);
+}
+
 struct rtw8852c_bb_gain {
 	u32 gain_g[BB_PATH_NUM_8852C];
 	u32 gain_a[BB_PATH_NUM_8852C];