From: Zong-Zhe Yang <kevin_yang@xxxxxxxxxxx> Extend FW and driver handling on RFK to support it on both HW bands. Then, according to MLO cases, do the corresponding RF settings. Signed-off-by: Zong-Zhe Yang <kevin_yang@xxxxxxxxxxx> Signed-off-by: Ping-Ke Shih <pkshih@xxxxxxxxxxx> --- drivers/net/wireless/realtek/rtw89/core.h | 6 +- drivers/net/wireless/realtek/rtw89/fw.c | 23 ++++--- .../net/wireless/realtek/rtw89/rtw8852c_rfk.c | 6 +- drivers/net/wireless/realtek/rtw89/rtw8922a.c | 18 ++++-- .../net/wireless/realtek/rtw89/rtw8922a_rfk.c | 61 +++++++++++-------- 5 files changed, 70 insertions(+), 44 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 10a5144fd425..31972c9ee5a7 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -4807,13 +4807,17 @@ enum rtw89_rfk_chs_nrs { RTW89_RFK_CHS_NR = __RTW89_RFK_CHS_NR_V1, }; -struct rtw89_rfk_mcc_info { +struct rtw89_rfk_mcc_info_data { u8 ch[RTW89_RFK_CHS_NR]; u8 band[RTW89_RFK_CHS_NR]; u8 bw[RTW89_RFK_CHS_NR]; u8 table_idx; }; +struct rtw89_rfk_mcc_info { + struct rtw89_rfk_mcc_info_data data[2]; +}; + #define RTW89_IQK_CHS_NR 2 #define RTW89_IQK_PATH_NR 4 diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 744a8d277cfc..d75e1d969881 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -5260,7 +5260,7 @@ int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev, int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev) { - struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; + struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data; struct rtw89_fw_h2c_rf_get_mccch *mccch; struct sk_buff *skb; int ret; @@ -5307,7 +5307,7 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev, struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; struct rtw89_fw_h2c_rfk_pre_info_v0 *h2c_v0; struct rtw89_fw_h2c_rfk_pre_info *h2c; - u8 tbl_sel = rfk_mcc->table_idx; + u8 tbl_sel[NUM_OF_RTW89_FW_RFK_PATH]; u32 len = sizeof(*h2c); struct sk_buff *skb; u8 ver = U8_MAX; @@ -5331,19 +5331,24 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev, h2c->common.mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode); BUILD_BUG_ON(NUM_OF_RTW89_FW_RFK_TBL > RTW89_RFK_CHS_NR); + BUILD_BUG_ON(ARRAY_SIZE(rfk_mcc->data) < NUM_OF_RTW89_FW_RFK_PATH); for (tbl = 0; tbl < NUM_OF_RTW89_FW_RFK_TBL; tbl++) { for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) { h2c->common.dbcc.ch[path][tbl] = - cpu_to_le32(rfk_mcc->ch[tbl]); + cpu_to_le32(rfk_mcc->data[path].ch[tbl]); h2c->common.dbcc.band[path][tbl] = - cpu_to_le32(rfk_mcc->band[tbl]); + cpu_to_le32(rfk_mcc->data[path].band[tbl]); } } for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) { - h2c->common.tbl.cur_ch[path] = cpu_to_le32(rfk_mcc->ch[tbl_sel]); - h2c->common.tbl.cur_band[path] = cpu_to_le32(rfk_mcc->band[tbl_sel]); + tbl_sel[path] = rfk_mcc->data[path].table_idx; + + h2c->common.tbl.cur_ch[path] = + cpu_to_le32(rfk_mcc->data[path].ch[tbl_sel[path]]); + h2c->common.tbl.cur_band[path] = + cpu_to_le32(rfk_mcc->data[path].band[tbl_sel[path]]); } h2c->common.phy_idx = cpu_to_le32(phy_idx); @@ -5351,9 +5356,9 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev, if (ver == 0) { /* RFK_PRE_NOTIFY_V0 */ h2c_v0 = (struct rtw89_fw_h2c_rfk_pre_info_v0 *)skb->data; - h2c_v0->cur_band = cpu_to_le32(rfk_mcc->band[tbl_sel]); - h2c_v0->cur_bw = cpu_to_le32(rfk_mcc->bw[tbl_sel]); - h2c_v0->cur_center_ch = cpu_to_le32(rfk_mcc->ch[tbl_sel]); + h2c_v0->cur_band = cpu_to_le32(rfk_mcc->data[0].band[tbl_sel[0]]); + h2c_v0->cur_bw = cpu_to_le32(rfk_mcc->data[0].bw[tbl_sel[0]]); + h2c_v0->cur_center_ch = cpu_to_le32(rfk_mcc->data[0].ch[tbl_sel[0]]); val32 = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL, B_COEF_SEL_IQC_V1); h2c_v0->ktbl_sel0 = cpu_to_le32(val32); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c index 3281ee9d7523..bd17c0a1c684 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c @@ -1065,7 +1065,7 @@ static bool _iqk_nbtxk(struct rtw89_dev *rtwdev, static bool _lok_finetune_check(struct rtw89_dev *rtwdev, u8 path) { - struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; + struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data; struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; u8 idx = rfk_mcc->table_idx; bool is_fail1, is_fail2; @@ -1408,7 +1408,7 @@ static void _iqk_afebb_restore(struct rtw89_dev *rtwdev, static void _iqk_preset(struct rtw89_dev *rtwdev, u8 path) { - struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; + struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data; u8 idx = 0; idx = rfk_mcc->table_idx; @@ -4105,7 +4105,7 @@ void rtw8852c_set_channel_rf(struct rtw89_dev *rtwdev, void rtw8852c_mcc_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) { - struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; + struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data; struct rtw89_rfk_chan_desc desc[__RTW89_RFK_CHS_NR_V0] = {}; const struct rtw89_chan *chan; enum rtw89_entity_mode mode; diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.c b/drivers/net/wireless/realtek/rtw89/rtw8922a.c index 58c9721ac3ab..7da73a9737f2 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8922a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.c @@ -2,6 +2,7 @@ /* Copyright(c) 2023 Realtek Corporation */ +#include "chan.h" #include "coex.h" #include "debug.h" #include "efuse.h" @@ -1745,7 +1746,7 @@ static void rtw8922a_digital_pwr_comp(struct rtw89_dev *rtwdev, static int rtw8922a_ctrl_mlo(struct rtw89_dev *rtwdev, enum rtw89_mlo_dbcc_mode mode) { - const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); + const struct rtw89_chan *chan0, *chan1; if (mode == MLO_1_PLUS_1_1RF || mode == DBCC_LEGACY) { rtw89_phy_write32_mask(rtwdev, R_DBCC, B_DBCC_EN, 0x1); @@ -1758,13 +1759,20 @@ static int rtw8922a_ctrl_mlo(struct rtw89_dev *rtwdev, enum rtw89_mlo_dbcc_mode return -EOPNOTSUPP; } - if (mode == MLO_2_PLUS_0_1RF) { - rtw8922a_ctrl_afe_dac(rtwdev, chan->band_width, RF_PATH_A); - rtw8922a_ctrl_afe_dac(rtwdev, chan->band_width, RF_PATH_B); + if (mode == MLO_1_PLUS_1_1RF) { + chan0 = rtw89_mgnt_chan_get(rtwdev, 0); + chan1 = rtw89_mgnt_chan_get(rtwdev, 1); + } else if (mode == MLO_0_PLUS_2_1RF) { + chan1 = rtw89_mgnt_chan_get(rtwdev, 1); + chan0 = chan1; } else { - rtw89_warn(rtwdev, "unsupported MLO mode %d\n", mode); + chan0 = rtw89_mgnt_chan_get(rtwdev, 0); + chan1 = chan0; } + rtw8922a_ctrl_afe_dac(rtwdev, chan0->band_width, RF_PATH_A); + rtw8922a_ctrl_afe_dac(rtwdev, chan1->band_width, RF_PATH_B); + rtw89_phy_write32_mask(rtwdev, R_EMLSR, B_EMLSR_PARM, 0x6180); if (mode == MLO_2_PLUS_0_1RF) { diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c index 28907df7407d..c4c93f836a2f 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c @@ -252,49 +252,58 @@ static void rtw8922a_chlk_ktbl_sel(struct rtw89_dev *rtwdev, u8 kpath, u8 idx) } } -static void rtw8922a_chlk_reload(struct rtw89_dev *rtwdev) +static u8 rtw8922a_chlk_reload_sel_tbl(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, u8 path) { struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; struct rtw89_rfk_chan_desc desc[__RTW89_RFK_CHS_NR_V1] = {}; - enum rtw89_chanctx_idx chanctx_idx; - const struct rtw89_chan *chan; - enum rtw89_entity_mode mode; - u8 s0_tbl, s1_tbl; u8 tbl_sel; - mode = rtw89_get_entity_mode(rtwdev); - switch (mode) { - case RTW89_ENTITY_MODE_MCC_PREPARE: - chanctx_idx = RTW89_CHANCTX_1; - break; - default: - chanctx_idx = RTW89_CHANCTX_0; - break; - } - - chan = rtw89_chan_get(rtwdev, chanctx_idx); - for (tbl_sel = 0; tbl_sel < ARRAY_SIZE(desc); tbl_sel++) { struct rtw89_rfk_chan_desc *p = &desc[tbl_sel]; - p->ch = rfk_mcc->ch[tbl_sel]; + p->ch = rfk_mcc->data[path].ch[tbl_sel]; p->has_band = true; - p->band = rfk_mcc->band[tbl_sel]; + p->band = rfk_mcc->data[path].band[tbl_sel]; p->has_bw = true; - p->bw = rfk_mcc->bw[tbl_sel]; + p->bw = rfk_mcc->data[path].bw[tbl_sel]; } tbl_sel = rtw89_rfk_chan_lookup(rtwdev, desc, ARRAY_SIZE(desc), chan); - rfk_mcc->ch[tbl_sel] = chan->channel; - rfk_mcc->band[tbl_sel] = chan->band_type; - rfk_mcc->bw[tbl_sel] = chan->band_width; - rfk_mcc->table_idx = tbl_sel; + rfk_mcc->data[path].ch[tbl_sel] = chan->channel; + rfk_mcc->data[path].band[tbl_sel] = chan->band_type; + rfk_mcc->data[path].bw[tbl_sel] = chan->band_width; + rfk_mcc->data[path].table_idx = tbl_sel; + + return tbl_sel; +} + +static void rtw8922a_chlk_reload(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chan *chan0, *chan1; + u8 s0_tbl, s1_tbl; + + switch (rtwdev->mlo_dbcc_mode) { + default: + case MLO_2_PLUS_0_1RF: + chan0 = rtw89_mgnt_chan_get(rtwdev, 0); + chan1 = chan0; + break; + case MLO_0_PLUS_2_1RF: + chan1 = rtw89_mgnt_chan_get(rtwdev, 1); + chan0 = chan1; + break; + case MLO_1_PLUS_1_1RF: + chan0 = rtw89_mgnt_chan_get(rtwdev, 0); + chan1 = rtw89_mgnt_chan_get(rtwdev, 1); + break; + } - s0_tbl = tbl_sel; - s1_tbl = tbl_sel; + s0_tbl = rtw8922a_chlk_reload_sel_tbl(rtwdev, chan0, 0); + s1_tbl = rtw8922a_chlk_reload_sel_tbl(rtwdev, chan1, 1); rtw8922a_chlk_ktbl_sel(rtwdev, RF_A, s0_tbl); rtw8922a_chlk_ktbl_sel(rtwdev, RF_B, s1_tbl); -- 2.25.1