summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorZong-Zhe Yang <kevin_yang@realtek.com>2024-10-22 10:31:06 +0200
committerPing-Ke Shih <pkshih@realtek.com>2024-10-29 04:28:30 +0100
commit94318a40033ee04ed2f59716d27d97bd9b03a62e (patch)
treedba1d70edda2a0e6c79240ea232058db38b63c20 /drivers/net/wireless
parentwifi: rtw89: tweak setting of channel and TX power for MLO (diff)
downloadlinux-94318a40033ee04ed2f59716d27d97bd9b03a62e.tar.xz
linux-94318a40033ee04ed2f59716d27d97bd9b03a62e.zip
wifi: rtw89: 8922a: extend RFK handling and consider MLO
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@realtek.com> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com> Link: https://patch.msgid.link/20241022083106.149252-6-pkshih@realtek.com
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/realtek/rtw89/core.h6
-rw-r--r--drivers/net/wireless/realtek/rtw89/fw.c23
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c6
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8922a.c18
-rw-r--r--drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c61
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 c2458f122812..5fa59cd138c1 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -4828,13 +4828,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 f504d1681fa3..1fc1ee46b3a3 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -5306,7 +5306,7 @@ fail:
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;
@@ -5353,7 +5353,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;
@@ -5377,19 +5377,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);
@@ -5397,9 +5402,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 a07534df2eb2..27069a55e368 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);