* [PATCH rtw-next 01/11] wifi: rtw89: rfk: update RFK pre info V2 for RTL8922D
2025-12-31 9:06 [PATCH rtw-next 00/11] wifi: rtw89: handle changes of RFK pre-notify Ping-Ke Shih
@ 2025-12-31 9:06 ` Ping-Ke Shih
2025-12-31 9:06 ` [PATCH rtw-next 02/11] wifi: rtw89: rfk: add rtw89_fw_h2c_rf_pre_ntfy_mcc for new WiFi 7 firmware Ping-Ke Shih
` (9 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Ping-Ke Shih @ 2025-12-31 9:06 UTC (permalink / raw)
To: linux-wireless; +Cc: gary.chang, dian_syuan0116, damon.chen, kevin_yang
The H2C command of RFK pre info is to tell current operating channels to
firmware, so RF calibrations can rely on these information as arguments
to configure hardware.
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/core.h | 1 +
drivers/net/wireless/realtek/rtw89/fw.c | 26 +++++++++++++++++++----
drivers/net/wireless/realtek/rtw89/fw.h | 8 ++++++-
3 files changed, 30 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 93b633d39e47..b42d3a4df4bf 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -4684,6 +4684,7 @@ enum rtw89_fw_feature {
RTW89_FW_FEATURE_WOW_REASON_V1,
RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V0,
RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V1,
+ RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V2,
RTW89_FW_FEATURE_RFK_RXDCK_V0,
RTW89_FW_FEATURE_RFK_IQK_V0,
RTW89_FW_FEATURE_NO_WOW_CPU_IO_RX,
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 40e5d5fab651..d05b15ea022a 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -885,6 +885,7 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = {
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 46, 0, NOTIFY_AP_INFO),
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 47, 0, CH_INFO_BE_V0),
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 49, 0, RFK_PRE_NOTIFY_V1),
+ __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 49, 0, RFK_PRE_NOTIFY_V2),
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 51, 0, NO_PHYCAP_P1),
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 64, 0, NO_POWER_DIFFERENCE),
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 71, 0, BEACON_LOSS_COUNT_V1),
@@ -6368,6 +6369,7 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
struct rtw89_fw_h2c_rfk_pre_info_common *common;
struct rtw89_fw_h2c_rfk_pre_info_v0 *h2c_v0;
struct rtw89_fw_h2c_rfk_pre_info_v1 *h2c_v1;
+ struct rtw89_fw_h2c_rfk_pre_info_v2 *h2c_v2;
struct rtw89_fw_h2c_rfk_pre_info *h2c;
u8 tbl_sel[NUM_OF_RTW89_FW_RFK_PATH];
u32 len = sizeof(*h2c);
@@ -6377,7 +6379,10 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
u32 val32;
int ret;
- if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_V1, &rtwdev->fw)) {
+ if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_V2, &rtwdev->fw)) {
+ len = sizeof(*h2c_v2);
+ ver = 2;
+ } else if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_V1, &rtwdev->fw)) {
len = sizeof(*h2c_v1);
ver = 1;
} else if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_V0, &rtwdev->fw)) {
@@ -6391,8 +6396,21 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
return -ENOMEM;
}
skb_put(skb, len);
+
+ if (ver <= 2)
+ goto old_format;
+
h2c = (struct rtw89_fw_h2c_rfk_pre_info *)skb->data;
- common = &h2c->base_v1.common;
+
+ h2c->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode);
+ h2c->phy_idx = cpu_to_le32(phy_idx);
+ h2c->mlo_1_1 = cpu_to_le32(rtw89_is_mlo_1_1(rtwdev));
+
+ goto done;
+
+old_format:
+ h2c_v2 = (struct rtw89_fw_h2c_rfk_pre_info_v2 *)skb->data;
+ common = &h2c_v2->base_v1.common;
common->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode);
@@ -6419,7 +6437,7 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
if (ver <= 1)
continue;
- h2c->cur_bandwidth[path] =
+ h2c_v2->cur_bandwidth[path] =
cpu_to_le32(rfk_mcc->data[path].bw[tbl_sel[path]]);
}
@@ -6450,7 +6468,7 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
}
if (rtw89_is_mlo_1_1(rtwdev)) {
- h2c_v1 = &h2c->base_v1;
+ h2c_v1 = &h2c_v2->base_v1;
h2c_v1->mlo_1_1 = cpu_to_le32(1);
}
done:
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index 6a297fad148b..f12728ccb31f 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -4574,11 +4574,17 @@ struct rtw89_fw_h2c_rfk_pre_info_v1 {
__le32 mlo_1_1;
} __packed;
-struct rtw89_fw_h2c_rfk_pre_info {
+struct rtw89_fw_h2c_rfk_pre_info_v2 {
struct rtw89_fw_h2c_rfk_pre_info_v1 base_v1;
__le32 cur_bandwidth[NUM_OF_RTW89_FW_RFK_PATH];
} __packed;
+struct rtw89_fw_h2c_rfk_pre_info {
+ __le32 mlo_mode;
+ __le32 phy_idx;
+ __le32 mlo_1_1;
+} __packed;
+
struct rtw89_h2c_rf_tssi {
__le16 len;
u8 phy;
--
2.25.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH rtw-next 02/11] wifi: rtw89: rfk: add rtw89_fw_h2c_rf_pre_ntfy_mcc for new WiFi 7 firmware
2025-12-31 9:06 [PATCH rtw-next 00/11] wifi: rtw89: handle changes of RFK pre-notify Ping-Ke Shih
2025-12-31 9:06 ` [PATCH rtw-next 01/11] wifi: rtw89: rfk: update RFK pre info V2 for RTL8922D Ping-Ke Shih
@ 2025-12-31 9:06 ` Ping-Ke Shih
2025-12-31 9:06 ` [PATCH rtw-next 03/11] wifi: rtw89: pre-handle RF calibration on link when needed Ping-Ke Shih
` (8 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Ping-Ke Shih @ 2025-12-31 9:06 UTC (permalink / raw)
To: linux-wireless; +Cc: gary.chang, dian_syuan0116, damon.chen, kevin_yang
From: Chih-Kang Chang <gary.chang@realtek.com>
The pre-notify is to notify firmware the configured channels, and then
RF calibration in firmware can use these values to calibrate RF properly.
Since we need more information, change and add the new H2C command format.
Signed-off-by: Chih-Kang Chang <gary.chang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/core.h | 2 +
drivers/net/wireless/realtek/rtw89/fw.c | 60 +++++++++++++++++++++++
drivers/net/wireless/realtek/rtw89/fw.h | 13 +++++
drivers/net/wireless/realtek/rtw89/phy.c | 6 +++
4 files changed, 81 insertions(+)
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index b42d3a4df4bf..b7d5eb25ef74 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -4685,6 +4685,7 @@ enum rtw89_fw_feature {
RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V0,
RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V1,
RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V2,
+ RTW89_FW_FEATURE_WITH_RFK_PRE_NOTIFY,
RTW89_FW_FEATURE_RFK_RXDCK_V0,
RTW89_FW_FEATURE_RFK_IQK_V0,
RTW89_FW_FEATURE_NO_WOW_CPU_IO_RX,
@@ -5239,6 +5240,7 @@ struct rtw89_rfk_mcc_info_data {
u8 ch[RTW89_RFK_CHS_NR];
u8 band[RTW89_RFK_CHS_NR];
u8 bw[RTW89_RFK_CHS_NR];
+ u32 rf18[RTW89_RFK_CHS_NR];
u8 table_idx;
};
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index d05b15ea022a..d13c93fafb34 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -892,6 +892,7 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = {
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 76, 0, LPS_DACK_BY_C2H_REG),
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 79, 0, CRASH_TRIGGER_TYPE_1),
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 80, 0, BEACON_TRACKING),
+ __CFG_FW_FEAT(RTL8922A, le, 0, 35, 80, 0, WITH_RFK_PRE_NOTIFY),
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 84, 0, ADDR_CAM_V0),
};
@@ -6490,6 +6491,65 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
return ret;
}
+int rtw89_fw_h2c_rf_pre_ntfy_mcc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+{
+ struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
+ struct rtw89_fw_h2c_rfk_pre_info_mcc *h2c;
+ struct rtw89_hal *hal = &rtwdev->hal;
+ u32 len = sizeof(*h2c);
+ struct sk_buff *skb;
+ u8 tbl, path;
+ int ret;
+
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+ if (!skb) {
+ rtw89_err(rtwdev, "failed to alloc skb for h2c rfk_pre_ntfy_mcc\n");
+ return -ENOMEM;
+ }
+ skb_put(skb, len);
+ h2c = (struct rtw89_fw_h2c_rfk_pre_info_mcc *)skb->data;
+
+ BUILD_BUG_ON(NUM_OF_RTW89_FW_RFK_TBL > RTW89_RFK_CHS_NR);
+
+ for (tbl = 0; tbl < NUM_OF_RTW89_FW_RFK_TBL; tbl++)
+ h2c->tbl_18[tbl] = cpu_to_le32(rfk_mcc->rf18[tbl]);
+
+ BUILD_BUG_ON(ARRAY_SIZE(rtwdev->rfk_mcc.data) < NUM_OF_RTW89_FW_RFK_PATH);
+
+ /* shared table array, but tbl_sel can be independent by path */
+ for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) {
+ tbl = rfk_mcc[path].table_idx;
+ h2c->cur_18[path] = cpu_to_le32(rfk_mcc->rf18[tbl]);
+
+ if (path == phy_idx)
+ h2c->tbl_idx = tbl;
+ }
+
+ h2c->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode);
+
+ if (rtw89_is_mlo_1_1(rtwdev))
+ h2c->mlo_1_1 = cpu_to_le32(1);
+
+ h2c->phy_idx = phy_idx;
+ h2c->aid = cpu_to_le32(hal->aid);
+
+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+ H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY,
+ H2C_FUNC_OUTSRC_RF_MCC_INFO, 0, 0, len);
+
+ ret = rtw89_h2c_tx(rtwdev, skb, false);
+ if (ret) {
+ rtw89_err(rtwdev, "failed to send h2c\n");
+ goto fail;
+ }
+
+ return 0;
+fail:
+ dev_kfree_skb_any(skb);
+
+ return ret;
+}
+
int rtw89_fw_h2c_rf_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
const struct rtw89_chan *chan, enum rtw89_tssi_mode tssi_mode)
{
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index f12728ccb31f..5292b568e2bf 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -4471,6 +4471,7 @@ enum rtw89_mrc_h2c_func {
#define H2C_CL_OUTSRC_RF_REG_B 0x9
#define H2C_CL_OUTSRC_RF_FW_NOTIFY 0xa
#define H2C_FUNC_OUTSRC_RF_GET_MCCCH 0x2
+#define H2C_FUNC_OUTSRC_RF_MCC_INFO 0xf
#define H2C_FUNC_OUTSRC_RF_PS_INFO 0x10
#define H2C_CL_OUTSRC_RF_FW_RFK 0xb
@@ -4585,6 +4586,17 @@ struct rtw89_fw_h2c_rfk_pre_info {
__le32 mlo_1_1;
} __packed;
+struct rtw89_fw_h2c_rfk_pre_info_mcc {
+ __le32 tbl_18[NUM_OF_RTW89_FW_RFK_TBL];
+ __le32 cur_18[NUM_OF_RTW89_FW_RFK_PATH];
+ __le32 mlo_mode;
+ __le32 mlo_1_1;
+ u8 phy_idx;
+ u8 tbl_idx;
+ u8 rsvd[2];
+ __le32 aid;
+} __packed;
+
struct rtw89_h2c_rf_tssi {
__le16 len;
u8 phy;
@@ -4942,6 +4954,7 @@ int rtw89_fw_h2c_rf_ntfy_mcc(struct rtw89_dev *rtwdev);
int rtw89_fw_h2c_rf_ps_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx);
+int rtw89_fw_h2c_rf_pre_ntfy_mcc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
int rtw89_fw_h2c_mcc_dig(struct rtw89_dev *rtwdev,
enum rtw89_chanctx_idx chanctx_idx,
u8 mcc_role_idx, u8 pd_val, bool en);
diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c
index 9f418b1fb7ed..d0e5d52964de 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.c
+++ b/drivers/net/wireless/realtek/rtw89/phy.c
@@ -3808,6 +3808,12 @@ int rtw89_phy_rfk_pre_ntfy_and_wait(struct rtw89_dev *rtwdev,
{
int ret;
+ if (RTW89_CHK_FW_FEATURE(WITH_RFK_PRE_NOTIFY, &rtwdev->fw))
+ goto pre_ntfy;
+
+ return rtw89_fw_h2c_rf_pre_ntfy_mcc(rtwdev, phy_idx);
+
+pre_ntfy:
rtw89_phy_rfk_report_prep(rtwdev);
ret = rtw89_fw_h2c_rf_pre_ntfy(rtwdev, phy_idx);
--
2.25.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH rtw-next 03/11] wifi: rtw89: pre-handle RF calibration on link when needed
2025-12-31 9:06 [PATCH rtw-next 00/11] wifi: rtw89: handle changes of RFK pre-notify Ping-Ke Shih
2025-12-31 9:06 ` [PATCH rtw-next 01/11] wifi: rtw89: rfk: update RFK pre info V2 for RTL8922D Ping-Ke Shih
2025-12-31 9:06 ` [PATCH rtw-next 02/11] wifi: rtw89: rfk: add rtw89_fw_h2c_rf_pre_ntfy_mcc for new WiFi 7 firmware Ping-Ke Shih
@ 2025-12-31 9:06 ` Ping-Ke Shih
2025-12-31 9:06 ` [PATCH rtw-next 04/11] wifi: rtw89: fw: change FW feature map to a BITMAP Ping-Ke Shih
` (7 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Ping-Ke Shih @ 2025-12-31 9:06 UTC (permalink / raw)
To: linux-wireless; +Cc: gary.chang, dian_syuan0116, damon.chen, kevin_yang
From: Zong-Zhe Yang <kevin_yang@realtek.com>
The Wi-Fi 7 RF calibration flow has a new design which mainly affect
MLO cases. Before, old RFK H2C command can just send the used channels
and MLO mode even if there are multiple active links. After, each RFK
H2C command should send one channel corresponding to one active link.
For example, connect MLD AP (channel X) and then activate second link
(channel X + channel Y)
Before:
RFK#1: channel X (path A + path B)
RFK#2: channel X (path A) + channel Y (path B)
After:
RFK#1: channel X (path A + path B)
[set MLO mode to focus on 2nd link/channel]
RFK#2: channel Y (path A + path B)
[set MLO mode back to target case]
Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/chan.c | 33 +++++++++++++++++++
drivers/net/wireless/realtek/rtw89/chan.h | 2 ++
drivers/net/wireless/realtek/rtw89/core.c | 29 +++++++++++++++-
drivers/net/wireless/realtek/rtw89/core.h | 13 +++-----
drivers/net/wireless/realtek/rtw89/mac80211.c | 3 +-
5 files changed, 69 insertions(+), 11 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c
index 8fe6a7ef738f..0b5509468582 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.c
+++ b/drivers/net/wireless/realtek/rtw89/chan.c
@@ -295,6 +295,8 @@ void rtw89_entity_init(struct rtw89_dev *rtwdev)
mgnt->chanctx_tbl[i][j] = RTW89_CHANCTX_IDLE;
}
+ hal->entity_force_hw = RTW89_PHY_NUM;
+
rtw89_config_default_chandef(rtwdev);
}
@@ -417,12 +419,43 @@ const struct rtw89_chan *__rtw89_mgnt_chan_get(struct rtw89_dev *rtwdev,
}
EXPORT_SYMBOL(__rtw89_mgnt_chan_get);
+bool rtw89_entity_check_hw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+{
+ switch (rtwdev->mlo_dbcc_mode) {
+ case MLO_2_PLUS_0_1RF:
+ return phy_idx == RTW89_PHY_0;
+ case MLO_0_PLUS_2_1RF:
+ return phy_idx == RTW89_PHY_1;
+ default:
+ return false;
+ }
+}
+
+void rtw89_entity_force_hw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
+{
+ rtwdev->hal.entity_force_hw = phy_idx;
+
+ if (phy_idx != RTW89_PHY_NUM)
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN, "%s: %d\n", __func__, phy_idx);
+ else
+ rtw89_debug(rtwdev, RTW89_DBG_CHAN, "%s: (none)\n", __func__);
+}
+
static enum rtw89_mlo_dbcc_mode
rtw89_entity_sel_mlo_dbcc_mode(struct rtw89_dev *rtwdev, u8 active_hws)
{
if (rtwdev->chip->chip_gen != RTW89_CHIP_BE)
return MLO_DBCC_NOT_SUPPORT;
+ switch (rtwdev->hal.entity_force_hw) {
+ case RTW89_PHY_0:
+ return MLO_2_PLUS_0_1RF;
+ case RTW89_PHY_1:
+ return MLO_0_PLUS_2_1RF;
+ default:
+ break;
+ }
+
switch (active_hws) {
case BIT(0):
return MLO_2_PLUS_0_1RF;
diff --git a/drivers/net/wireless/realtek/rtw89/chan.h b/drivers/net/wireless/realtek/rtw89/chan.h
index 5b22764d5329..c797cda2e763 100644
--- a/drivers/net/wireless/realtek/rtw89/chan.h
+++ b/drivers/net/wireless/realtek/rtw89/chan.h
@@ -166,6 +166,8 @@ void rtw89_config_roc_chandef(struct rtw89_dev *rtwdev,
const struct cfg80211_chan_def *chandef);
void rtw89_entity_init(struct rtw89_dev *rtwdev);
enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev);
+bool rtw89_entity_check_hw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
+void rtw89_entity_force_hw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx);
void rtw89_chanctx_work(struct wiphy *wiphy, struct wiphy_work *work);
void rtw89_queue_chanctx_work(struct rtw89_dev *rtwdev);
void rtw89_queue_chanctx_change(struct rtw89_dev *rtwdev,
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index e713422ebd7c..96fb2839379f 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -470,6 +470,32 @@ void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev)
__rtw89_core_set_chip_txpwr(rtwdev, chan, RTW89_PHY_1);
}
+void rtw89_chip_rfk_channel(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link)
+{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ bool mon = !!rtwdev->pure_monitor_mode_vif;
+ bool prehdl_link = false;
+
+ if (chip->chip_gen != RTW89_CHIP_AX &&
+ !RTW89_CHK_FW_FEATURE(WITH_RFK_PRE_NOTIFY, &rtwdev->fw) &&
+ !mon && !rtw89_entity_check_hw(rtwdev, rtwvif_link->phy_idx))
+ prehdl_link = true;
+
+ if (prehdl_link) {
+ rtw89_entity_force_hw(rtwdev, rtwvif_link->phy_idx);
+ rtw89_set_channel(rtwdev);
+ }
+
+ if (chip->ops->rfk_channel)
+ chip->ops->rfk_channel(rtwdev, rtwvif_link);
+
+ if (prehdl_link) {
+ rtw89_entity_force_hw(rtwdev, RTW89_PHY_NUM);
+ rtw89_set_channel(rtwdev);
+ }
+}
+
static void rtw89_chip_rfk_channel_for_pure_mon_vif(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx)
{
@@ -6218,7 +6244,8 @@ int rtw89_core_mlsr_switch(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
goto wake_queue;
}
- rtw89_chip_rfk_channel(rtwdev, target);
+ if (RTW89_CHK_FW_FEATURE(WITH_RFK_PRE_NOTIFY, &rtwdev->fw))
+ rtw89_chip_rfk_channel(rtwdev, target);
rtwvif->mlo_mode = RTW89_MLO_MODE_MLSR;
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index b7d5eb25ef74..52d6e5683d63 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -5075,6 +5075,8 @@ struct rtw89_hal {
enum rtw89_entity_mode entity_mode;
struct rtw89_entity_mgnt entity_mgnt;
+ enum rtw89_phy_idx entity_force_hw;
+
u32 disabled_dm_bitmap; /* bitmap of enum rtw89_dm_type */
u8 thermal_prot_th;
@@ -7125,15 +7127,6 @@ static inline void rtw89_chip_rfk_init_late(struct rtw89_dev *rtwdev)
chip->ops->rfk_init_late(rtwdev);
}
-static inline void rtw89_chip_rfk_channel(struct rtw89_dev *rtwdev,
- struct rtw89_vif_link *rtwvif_link)
-{
- const struct rtw89_chip_info *chip = rtwdev->chip;
-
- if (chip->ops->rfk_channel)
- chip->ops->rfk_channel(rtwdev, rtwvif_link);
-}
-
static inline void rtw89_chip_rfk_band_changed(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,
const struct rtw89_chan *chan)
@@ -7647,6 +7640,8 @@ struct rtw89_sta_link *rtw89_sta_set_link(struct rtw89_sta *rtwsta,
unsigned int link_id);
void rtw89_sta_unset_link(struct rtw89_sta *rtwsta, unsigned int link_id);
void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev);
+void rtw89_chip_rfk_channel(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link);
const struct rtw89_6ghz_span *
rtw89_get_6ghz_span(struct rtw89_dev *rtwdev, u32 center_freq);
void rtw89_get_default_chandef(struct cfg80211_chan_def *chandef);
diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c
index f80c847d1741..96dc94c1f556 100644
--- a/drivers/net/wireless/realtek/rtw89/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
@@ -720,7 +720,8 @@ static void rtw89_ops_vif_cfg_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_MLD_VALID_LINKS) {
struct rtw89_vif_link *cur = rtw89_get_designated_link(rtwvif);
- rtw89_chip_rfk_channel(rtwdev, cur);
+ if (RTW89_CHK_FW_FEATURE(WITH_RFK_PRE_NOTIFY, &rtwdev->fw))
+ rtw89_chip_rfk_channel(rtwdev, cur);
if (hweight16(vif->active_links) == 1)
rtwvif->mlo_mode = RTW89_MLO_MODE_MLSR;
--
2.25.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH rtw-next 04/11] wifi: rtw89: fw: change FW feature map to a BITMAP
2025-12-31 9:06 [PATCH rtw-next 00/11] wifi: rtw89: handle changes of RFK pre-notify Ping-Ke Shih
` (2 preceding siblings ...)
2025-12-31 9:06 ` [PATCH rtw-next 03/11] wifi: rtw89: pre-handle RF calibration on link when needed Ping-Ke Shih
@ 2025-12-31 9:06 ` Ping-Ke Shih
2025-12-31 9:06 ` [PATCH rtw-next 05/11] wifi: rtw89: fw: introduce helper for disabling FW feature configuration Ping-Ke Shih
` (6 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Ping-Ke Shih @ 2025-12-31 9:06 UTC (permalink / raw)
To: linux-wireless; +Cc: gary.chang, dian_syuan0116, damon.chen, kevin_yang
From: Zong-Zhe Yang <kevin_yang@realtek.com>
Originally, FW feature map was declared as a u32. But, the number of FW
feature flags is going to be over than 32. So, change it to a BITMAP and
update the corresponding macros.
Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/core.h | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 52d6e5683d63..7b6dfab8e56c 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -4702,6 +4702,8 @@ enum rtw89_fw_feature {
RTW89_FW_FEATURE_ADDR_CAM_V0,
RTW89_FW_FEATURE_SER_L1_BY_EVENT,
RTW89_FW_FEATURE_SIM_SER_L0L1_BY_HALT_H2C,
+
+ NUM_OF_RTW89_FW_FEATURES,
};
struct rtw89_fw_suit {
@@ -4793,20 +4795,25 @@ struct rtw89_fw_info {
struct rtw89_fw_suit bbmcu0;
struct rtw89_fw_suit bbmcu1;
struct rtw89_fw_log log;
- u32 feature_map;
struct rtw89_fw_elm_info elm_info;
struct rtw89_fw_secure sec;
+
+ DECLARE_BITMAP(feature_map, NUM_OF_RTW89_FW_FEATURES);
};
#define RTW89_CHK_FW_FEATURE(_feat, _fw) \
- (!!((_fw)->feature_map & BIT(RTW89_FW_FEATURE_ ## _feat)))
+ test_bit(RTW89_FW_FEATURE_ ## _feat, (_fw)->feature_map)
#define RTW89_CHK_FW_FEATURE_GROUP(_grp, _fw) \
- (!!((_fw)->feature_map & GENMASK(RTW89_FW_FEATURE_ ## _grp ## _MAX, \
- RTW89_FW_FEATURE_ ## _grp ## _MIN)))
+({ \
+ unsigned int bit = find_next_bit((_fw)->feature_map, \
+ NUM_OF_RTW89_FW_FEATURES, \
+ RTW89_FW_FEATURE_ ## _grp ## _MIN); \
+ bit <= RTW89_FW_FEATURE_ ## _grp ## _MAX; \
+})
#define RTW89_SET_FW_FEATURE(_fw_feature, _fw) \
- ((_fw)->feature_map |= BIT(_fw_feature))
+ set_bit(_fw_feature, (_fw)->feature_map)
struct rtw89_cam_info {
DECLARE_BITMAP(addr_cam_map, RTW89_MAX_ADDR_CAM_NUM);
--
2.25.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH rtw-next 05/11] wifi: rtw89: fw: introduce helper for disabling FW feature configuration
2025-12-31 9:06 [PATCH rtw-next 00/11] wifi: rtw89: handle changes of RFK pre-notify Ping-Ke Shih
` (3 preceding siblings ...)
2025-12-31 9:06 ` [PATCH rtw-next 04/11] wifi: rtw89: fw: change FW feature map to a BITMAP Ping-Ke Shih
@ 2025-12-31 9:06 ` Ping-Ke Shih
2025-12-31 9:06 ` [PATCH rtw-next 06/11] wifi: rtw89: 8922a: tweak RFK_PRE_NOTIFY FW feature configuration to align handling Ping-Ke Shih
` (5 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Ping-Ke Shih @ 2025-12-31 9:06 UTC (permalink / raw)
To: linux-wireless; +Cc: gary.chang, dian_syuan0116, damon.chen, kevin_yang
From: Zong-Zhe Yang <kevin_yang@realtek.com>
Some FW features (groups) may be valid only in a range of FW versions,
i.e. after some FW versions, they can no longer be used. So, introduce
some helper macros to configure this kind of things in FW feature table.
Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/core.h | 3 ++
drivers/net/wireless/realtek/rtw89/fw.c | 36 ++++++++++++++++++++++-
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 7b6dfab8e56c..8010ee070108 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -4815,6 +4815,9 @@ struct rtw89_fw_info {
#define RTW89_SET_FW_FEATURE(_fw_feature, _fw) \
set_bit(_fw_feature, (_fw)->feature_map)
+#define RTW89_CLR_FW_FEATURE(_fw_feature, _fw) \
+ clear_bit(_fw_feature, (_fw)->feature_map)
+
struct rtw89_cam_info {
DECLARE_BITMAP(addr_cam_map, RTW89_MAX_ADDR_CAM_NUM);
DECLARE_BITMAP(bssid_cam_map, RTW89_MAX_BSSID_CAM_NUM);
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index d13c93fafb34..8804f5da88b1 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -812,6 +812,8 @@ struct __fw_feat_cfg {
enum rtw89_fw_feature feature;
u32 ver_code;
bool (*cond)(u32 suit_ver_code, u32 comp_ver_code);
+ bool disable;
+ int size;
};
#define __CFG_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _feat) \
@@ -822,6 +824,30 @@ struct __fw_feat_cfg {
.cond = __fw_feat_cond_ ## _cond, \
}
+#define __S_DIS_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _feat) \
+ { \
+ .chip_id = _chip, \
+ .feature = RTW89_FW_FEATURE_ ## _feat, \
+ .ver_code = RTW89_FW_VER_CODE(_maj, _min, _sub, _idx), \
+ .cond = __fw_feat_cond_ ## _cond, \
+ .disable = true, \
+ .size = 1, \
+ }
+
+#define __G_DIS_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _grp) \
+ { \
+ .chip_id = _chip, \
+ .feature = RTW89_FW_FEATURE_ ## _grp ## _MIN, \
+ .ver_code = RTW89_FW_VER_CODE(_maj, _min, _sub, _idx), \
+ .cond = __fw_feat_cond_ ## _cond, \
+ .disable = true, \
+ .size = RTW89_FW_FEATURE_ ## _grp ## _MAX - \
+ RTW89_FW_FEATURE_ ## _grp ## _MIN + 1, \
+ }
+
+#define __DIS_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _feat, _type) \
+ __##_type##_DIS_FW_FEAT(_chip, _cond, _maj, _min, _sub, _idx, _feat)
+
static const struct __fw_feat_cfg fw_feat_tbl[] = {
__CFG_FW_FEAT(RTL8851B, ge, 0, 29, 37, 1, TX_WAKE),
__CFG_FW_FEAT(RTL8851B, ge, 0, 29, 37, 1, SCAN_OFFLOAD),
@@ -908,8 +934,16 @@ static void rtw89_fw_iterate_feature_cfg(struct rtw89_fw_info *fw,
if (chip->chip_id != ent->chip_id)
continue;
- if (ent->cond(ver_code, ent->ver_code))
+ if (!ent->cond(ver_code, ent->ver_code))
+ continue;
+
+ if (!ent->disable) {
RTW89_SET_FW_FEATURE(ent->feature, fw);
+ continue;
+ }
+
+ for (int n = 0; n < ent->size; n++)
+ RTW89_CLR_FW_FEATURE(ent->feature + n, fw);
}
}
--
2.25.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH rtw-next 06/11] wifi: rtw89: 8922a: tweak RFK_PRE_NOTIFY FW feature configuration to align handling
2025-12-31 9:06 [PATCH rtw-next 00/11] wifi: rtw89: handle changes of RFK pre-notify Ping-Ke Shih
` (4 preceding siblings ...)
2025-12-31 9:06 ` [PATCH rtw-next 05/11] wifi: rtw89: fw: introduce helper for disabling FW feature configuration Ping-Ke Shih
@ 2025-12-31 9:06 ` Ping-Ke Shih
2025-12-31 9:06 ` [PATCH rtw-next 07/11] wifi: rtw89: refine mis-ordered entries in FW feature table Ping-Ke Shih
` (4 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Ping-Ke Shih @ 2025-12-31 9:06 UTC (permalink / raw)
To: linux-wireless; +Cc: gary.chang, dian_syuan0116, damon.chen, kevin_yang
From: Zong-Zhe Yang <kevin_yang@realtek.com>
In the FW feature table, V0 and V1 was configured by lt, less than. So, V1
flag was also set in the range of V0. However, in RFK_PRE_NOTIFY handling,
rtw89_fw_h2c_rf_pre_ntfy, V1 is tested before V0. Things would process as
V1 even if V0 should be used.
Tweak FW feature configuration by ge, greater or equal, to align handling.
Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/fw.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 8804f5da88b1..067f6f0ea101 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -897,6 +897,7 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = {
__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 129, 1, BEACON_TRACKING),
__CFG_FW_FEAT(RTL8852C, ge, 0, 29, 94, 0, SER_L1_BY_EVENT),
__CFG_FW_FEAT(RTL8852C, ge, 0, 29, 130, 0, SIM_SER_L0L1_BY_HALT_H2C),
+ __CFG_FW_FEAT(RTL8922A, ge, 0, 0, 0, 0, RFK_PRE_NOTIFY_V0),
__CFG_FW_FEAT(RTL8922A, ge, 0, 34, 30, 0, CRASH_TRIGGER_TYPE_0),
__CFG_FW_FEAT(RTL8922A, ge, 0, 34, 11, 0, MACID_PAUSE_SLEEP),
__CFG_FW_FEAT(RTL8922A, ge, 0, 34, 35, 0, SCAN_OFFLOAD),
@@ -905,12 +906,11 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = {
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 12, 0, BEACON_FILTER),
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 22, 0, WOW_REASON_V1),
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 28, 0, RFK_IQK_V0),
- __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 31, 0, RFK_PRE_NOTIFY_V0),
+ __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 31, 0, RFK_PRE_NOTIFY_V1),
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 31, 0, LPS_CH_INFO),
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 42, 0, RFK_RXDCK_V0),
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 46, 0, NOTIFY_AP_INFO),
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 47, 0, CH_INFO_BE_V0),
- __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 49, 0, RFK_PRE_NOTIFY_V1),
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 49, 0, RFK_PRE_NOTIFY_V2),
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 51, 0, NO_PHYCAP_P1),
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 64, 0, NO_POWER_DIFFERENCE),
--
2.25.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH rtw-next 07/11] wifi: rtw89: refine mis-ordered entries in FW feature table
2025-12-31 9:06 [PATCH rtw-next 00/11] wifi: rtw89: handle changes of RFK pre-notify Ping-Ke Shih
` (5 preceding siblings ...)
2025-12-31 9:06 ` [PATCH rtw-next 06/11] wifi: rtw89: 8922a: tweak RFK_PRE_NOTIFY FW feature configuration to align handling Ping-Ke Shih
@ 2025-12-31 9:06 ` Ping-Ke Shih
2025-12-31 9:06 ` [PATCH rtw-next 08/11] wifi: rtw89: fw: change WITH_RFK_PRE_NOTIFY to be a FW feature group Ping-Ke Shih
` (3 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Ping-Ke Shih @ 2025-12-31 9:06 UTC (permalink / raw)
To: linux-wireless; +Cc: gary.chang, dian_syuan0116, damon.chen, kevin_yang
From: Zong-Zhe Yang <kevin_yang@realtek.com>
Make all entries in firmware feature table in increasing order of firmware
version.
Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/fw.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 067f6f0ea101..4ba99e7078fe 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -884,8 +884,8 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = {
__CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 127, 0, CRASH_TRIGGER_TYPE_1),
__CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 127, 0, SER_L1_BY_EVENT),
__CFG_FW_FEAT(RTL8852BT, ge, 0, 29, 130, 0, SIM_SER_L0L1_BY_HALT_H2C),
- __CFG_FW_FEAT(RTL8852C, le, 0, 27, 33, 0, NO_DEEP_PS),
__CFG_FW_FEAT(RTL8852C, ge, 0, 0, 0, 0, RFK_NTFY_MCC_V0),
+ __CFG_FW_FEAT(RTL8852C, le, 0, 27, 33, 0, NO_DEEP_PS),
__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 34, 0, TX_WAKE),
__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 36, 0, SCAN_OFFLOAD),
__CFG_FW_FEAT(RTL8852C, ge, 0, 27, 40, 0, CRASH_TRIGGER_TYPE_0),
@@ -898,12 +898,12 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = {
__CFG_FW_FEAT(RTL8852C, ge, 0, 29, 94, 0, SER_L1_BY_EVENT),
__CFG_FW_FEAT(RTL8852C, ge, 0, 29, 130, 0, SIM_SER_L0L1_BY_HALT_H2C),
__CFG_FW_FEAT(RTL8922A, ge, 0, 0, 0, 0, RFK_PRE_NOTIFY_V0),
- __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 30, 0, CRASH_TRIGGER_TYPE_0),
__CFG_FW_FEAT(RTL8922A, ge, 0, 34, 11, 0, MACID_PAUSE_SLEEP),
+ __CFG_FW_FEAT(RTL8922A, ge, 0, 34, 30, 0, CRASH_TRIGGER_TYPE_0),
__CFG_FW_FEAT(RTL8922A, ge, 0, 34, 35, 0, SCAN_OFFLOAD),
__CFG_FW_FEAT(RTL8922A, ge, 0, 34, 35, 0, SCAN_OFFLOAD_EXTRA_OP),
- __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 21, 0, SCAN_OFFLOAD_BE_V0),
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 12, 0, BEACON_FILTER),
+ __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 21, 0, SCAN_OFFLOAD_BE_V0),
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 22, 0, WOW_REASON_V1),
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 28, 0, RFK_IQK_V0),
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 31, 0, RFK_PRE_NOTIFY_V1),
--
2.25.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH rtw-next 08/11] wifi: rtw89: fw: change WITH_RFK_PRE_NOTIFY to be a FW feature group
2025-12-31 9:06 [PATCH rtw-next 00/11] wifi: rtw89: handle changes of RFK pre-notify Ping-Ke Shih
` (6 preceding siblings ...)
2025-12-31 9:06 ` [PATCH rtw-next 07/11] wifi: rtw89: refine mis-ordered entries in FW feature table Ping-Ke Shih
@ 2025-12-31 9:06 ` Ping-Ke Shih
2025-12-31 9:06 ` [PATCH rtw-next 09/11] wifi: rtw89: rfk: update rtw89_fw_h2c_rf_pre_ntfy_mcc format Ping-Ke Shih
` (2 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Ping-Ke Shih @ 2025-12-31 9:06 UTC (permalink / raw)
To: linux-wireless; +Cc: gary.chang, dian_syuan0116, damon.chen, kevin_yang
From: Zong-Zhe Yang <kevin_yang@realtek.com>
Actually, WITH_RFK_PRE_NOTIFY means supporting one of RFK_PRE_NOTIFY_Vx.
So, change it to be a FW feature group which contains RFK_PRE_NOTIFY_Vx.
Then, because WITH_RFK_PRE_NOTIFY is abandoned after some FW versions by
chip, disable WITH_RFK_PRE_NOTIFY correspondingly in FW feature table.
Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/core.c | 4 ++--
drivers/net/wireless/realtek/rtw89/core.h | 10 ++++++----
drivers/net/wireless/realtek/rtw89/fw.c | 5 +++--
drivers/net/wireless/realtek/rtw89/mac80211.c | 2 +-
drivers/net/wireless/realtek/rtw89/phy.c | 2 +-
5 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 96fb2839379f..191caafbd0fb 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -478,7 +478,7 @@ void rtw89_chip_rfk_channel(struct rtw89_dev *rtwdev,
bool prehdl_link = false;
if (chip->chip_gen != RTW89_CHIP_AX &&
- !RTW89_CHK_FW_FEATURE(WITH_RFK_PRE_NOTIFY, &rtwdev->fw) &&
+ !RTW89_CHK_FW_FEATURE_GROUP(WITH_RFK_PRE_NOTIFY, &rtwdev->fw) &&
!mon && !rtw89_entity_check_hw(rtwdev, rtwvif_link->phy_idx))
prehdl_link = true;
@@ -6244,7 +6244,7 @@ int rtw89_core_mlsr_switch(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
goto wake_queue;
}
- if (RTW89_CHK_FW_FEATURE(WITH_RFK_PRE_NOTIFY, &rtwdev->fw))
+ if (RTW89_CHK_FW_FEATURE_GROUP(WITH_RFK_PRE_NOTIFY, &rtwdev->fw))
rtw89_chip_rfk_channel(rtwdev, target);
rtwvif->mlo_mode = RTW89_MLO_MODE_MLSR;
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 8010ee070108..38a64b0bfb5c 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -4682,10 +4682,12 @@ enum rtw89_fw_feature {
RTW89_FW_FEATURE_MACID_PAUSE_SLEEP,
RTW89_FW_FEATURE_SCAN_OFFLOAD_BE_V0,
RTW89_FW_FEATURE_WOW_REASON_V1,
- RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V0,
- RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V1,
- RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V2,
- RTW89_FW_FEATURE_WITH_RFK_PRE_NOTIFY,
+ RTW89_FW_FEATURE_GROUP(WITH_RFK_PRE_NOTIFY,
+ RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V0,
+ RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V1,
+ RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V2,
+ RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V3,
+ ),
RTW89_FW_FEATURE_RFK_RXDCK_V0,
RTW89_FW_FEATURE_RFK_IQK_V0,
RTW89_FW_FEATURE_NO_WOW_CPU_IO_RX,
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 4ba99e7078fe..fed9b3db1543 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -918,7 +918,7 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = {
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 76, 0, LPS_DACK_BY_C2H_REG),
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 79, 0, CRASH_TRIGGER_TYPE_1),
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 80, 0, BEACON_TRACKING),
- __CFG_FW_FEAT(RTL8922A, le, 0, 35, 80, 0, WITH_RFK_PRE_NOTIFY),
+ __DIS_FW_FEAT(RTL8922A, ge, 0, 35, 84, 0, WITH_RFK_PRE_NOTIFY, G),
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 84, 0, ADDR_CAM_V0),
};
@@ -6414,7 +6414,8 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
u32 val32;
int ret;
- if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_V2, &rtwdev->fw)) {
+ if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_V3, &rtwdev->fw)) {
+ } else if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_V2, &rtwdev->fw)) {
len = sizeof(*h2c_v2);
ver = 2;
} else if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_V1, &rtwdev->fw)) {
diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c
index 96dc94c1f556..ba71709a9bc9 100644
--- a/drivers/net/wireless/realtek/rtw89/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
@@ -720,7 +720,7 @@ static void rtw89_ops_vif_cfg_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_MLD_VALID_LINKS) {
struct rtw89_vif_link *cur = rtw89_get_designated_link(rtwvif);
- if (RTW89_CHK_FW_FEATURE(WITH_RFK_PRE_NOTIFY, &rtwdev->fw))
+ if (RTW89_CHK_FW_FEATURE_GROUP(WITH_RFK_PRE_NOTIFY, &rtwdev->fw))
rtw89_chip_rfk_channel(rtwdev, cur);
if (hweight16(vif->active_links) == 1)
diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c
index d0e5d52964de..f56b433a1674 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.c
+++ b/drivers/net/wireless/realtek/rtw89/phy.c
@@ -3808,7 +3808,7 @@ int rtw89_phy_rfk_pre_ntfy_and_wait(struct rtw89_dev *rtwdev,
{
int ret;
- if (RTW89_CHK_FW_FEATURE(WITH_RFK_PRE_NOTIFY, &rtwdev->fw))
+ if (RTW89_CHK_FW_FEATURE_GROUP(WITH_RFK_PRE_NOTIFY, &rtwdev->fw))
goto pre_ntfy;
return rtw89_fw_h2c_rf_pre_ntfy_mcc(rtwdev, phy_idx);
--
2.25.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH rtw-next 09/11] wifi: rtw89: rfk: update rtw89_fw_h2c_rf_pre_ntfy_mcc format
2025-12-31 9:06 [PATCH rtw-next 00/11] wifi: rtw89: handle changes of RFK pre-notify Ping-Ke Shih
` (7 preceding siblings ...)
2025-12-31 9:06 ` [PATCH rtw-next 08/11] wifi: rtw89: fw: change WITH_RFK_PRE_NOTIFY to be a FW feature group Ping-Ke Shih
@ 2025-12-31 9:06 ` Ping-Ke Shih
2025-12-31 9:06 ` [PATCH rtw-next 10/11] wifi: rtw89: fix potential zero beacon interval in beacon tracking Ping-Ke Shih
2025-12-31 9:06 ` [PATCH rtw-next 11/11] wifi: rtw89: 8852b: refine hardware parameters for RFE type 5 Ping-Ke Shih
10 siblings, 0 replies; 12+ messages in thread
From: Ping-Ke Shih @ 2025-12-31 9:06 UTC (permalink / raw)
To: linux-wireless; +Cc: gary.chang, dian_syuan0116, damon.chen, kevin_yang
From: Chih-Kang Chang <gary.chang@realtek.com>
The H2C command rtw89_fw_h2c_rf_pre_ntfy_mcc have different format.
8922A after FW 0.35.49.0 use v0, after FW 0.35.84.0 use v1. The coming
8922D will use v2.
Signed-off-by: Chih-Kang Chang <gary.chang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/core.h | 5 ++
drivers/net/wireless/realtek/rtw89/fw.c | 55 ++++++++++++++++---
drivers/net/wireless/realtek/rtw89/fw.h | 12 +++-
drivers/net/wireless/realtek/rtw89/phy.c | 23 ++++----
.../net/wireless/realtek/rtw89/rtw8922a_rfk.c | 48 +++++++++++++++-
5 files changed, 122 insertions(+), 21 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 38a64b0bfb5c..661b6a23082a 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -4688,6 +4688,11 @@ enum rtw89_fw_feature {
RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V2,
RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V3,
),
+ RTW89_FW_FEATURE_GROUP(WITH_RFK_PRE_NOTIFY_MCC,
+ RTW89_FW_FEATURE_RFK_PRE_NOTIFY_MCC_V0,
+ RTW89_FW_FEATURE_RFK_PRE_NOTIFY_MCC_V1,
+ RTW89_FW_FEATURE_RFK_PRE_NOTIFY_MCC_V2,
+ ),
RTW89_FW_FEATURE_RFK_RXDCK_V0,
RTW89_FW_FEATURE_RFK_IQK_V0,
RTW89_FW_FEATURE_NO_WOW_CPU_IO_RX,
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index fed9b3db1543..24077a8095c4 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -912,6 +912,7 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = {
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 46, 0, NOTIFY_AP_INFO),
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 47, 0, CH_INFO_BE_V0),
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 49, 0, RFK_PRE_NOTIFY_V2),
+ __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 49, 0, RFK_PRE_NOTIFY_MCC_V0),
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 51, 0, NO_PHYCAP_P1),
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 64, 0, NO_POWER_DIFFERENCE),
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 71, 0, BEACON_LOSS_COUNT_V1),
@@ -919,6 +920,7 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = {
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 79, 0, CRASH_TRIGGER_TYPE_1),
__CFG_FW_FEAT(RTL8922A, ge, 0, 35, 80, 0, BEACON_TRACKING),
__DIS_FW_FEAT(RTL8922A, ge, 0, 35, 84, 0, WITH_RFK_PRE_NOTIFY, G),
+ __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 84, 0, RFK_PRE_NOTIFY_MCC_V1),
__CFG_FW_FEAT(RTL8922A, lt, 0, 35, 84, 0, ADDR_CAM_V0),
};
@@ -6529,45 +6531,84 @@ int rtw89_fw_h2c_rf_pre_ntfy(struct rtw89_dev *rtwdev,
int rtw89_fw_h2c_rf_pre_ntfy_mcc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
{
struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
+ struct rtw89_rfk_mcc_info *rfk_mcc_v0 = &rtwdev->rfk_mcc;
+ struct rtw89_fw_h2c_rfk_pre_info_mcc_v0 *h2c_v0;
+ struct rtw89_fw_h2c_rfk_pre_info_mcc_v1 *h2c_v1;
struct rtw89_fw_h2c_rfk_pre_info_mcc *h2c;
struct rtw89_hal *hal = &rtwdev->hal;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
+ u8 ver = U8_MAX;
u8 tbl, path;
+ u8 tbl_sel;
int ret;
+ if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_MCC_V2, &rtwdev->fw)) {
+ } else if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_MCC_V1, &rtwdev->fw)) {
+ len = sizeof(*h2c_v1);
+ ver = 1;
+ } else if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_MCC_V0, &rtwdev->fw)) {
+ len = sizeof(*h2c_v0);
+ ver = 0;
+ }
+
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
rtw89_err(rtwdev, "failed to alloc skb for h2c rfk_pre_ntfy_mcc\n");
return -ENOMEM;
}
skb_put(skb, len);
- h2c = (struct rtw89_fw_h2c_rfk_pre_info_mcc *)skb->data;
+
+ if (ver != 0)
+ goto v1;
+
+ h2c_v0 = (struct rtw89_fw_h2c_rfk_pre_info_mcc_v0 *)skb->data;
+ for (tbl = 0; tbl < NUM_OF_RTW89_FW_RFK_TBL; tbl++) {
+ for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) {
+ h2c_v0->tbl_18[tbl][path] =
+ cpu_to_le32(rfk_mcc_v0->data[path].rf18[tbl]);
+ tbl_sel = rfk_mcc_v0->data[path].table_idx;
+ h2c_v0->cur_18[path] =
+ cpu_to_le32(rfk_mcc_v0->data[path].rf18[tbl_sel]);
+ }
+ }
+
+ h2c_v0->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode);
+ goto done;
+
+v1:
+ h2c_v1 = (struct rtw89_fw_h2c_rfk_pre_info_mcc_v1 *)skb->data;
BUILD_BUG_ON(NUM_OF_RTW89_FW_RFK_TBL > RTW89_RFK_CHS_NR);
for (tbl = 0; tbl < NUM_OF_RTW89_FW_RFK_TBL; tbl++)
- h2c->tbl_18[tbl] = cpu_to_le32(rfk_mcc->rf18[tbl]);
+ h2c_v1->tbl_18[tbl] = cpu_to_le32(rfk_mcc->rf18[tbl]);
BUILD_BUG_ON(ARRAY_SIZE(rtwdev->rfk_mcc.data) < NUM_OF_RTW89_FW_RFK_PATH);
/* shared table array, but tbl_sel can be independent by path */
for (path = 0; path < NUM_OF_RTW89_FW_RFK_PATH; path++) {
tbl = rfk_mcc[path].table_idx;
- h2c->cur_18[path] = cpu_to_le32(rfk_mcc->rf18[tbl]);
+ h2c_v1->cur_18[path] = cpu_to_le32(rfk_mcc->rf18[tbl]);
if (path == phy_idx)
- h2c->tbl_idx = tbl;
+ h2c_v1->tbl_idx = tbl;
}
- h2c->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode);
+ h2c_v1->mlo_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode);
+ h2c_v1->phy_idx = phy_idx;
if (rtw89_is_mlo_1_1(rtwdev))
- h2c->mlo_1_1 = cpu_to_le32(1);
+ h2c_v1->mlo_1_1 = cpu_to_le32(1);
+
+ if (ver == 1)
+ goto done;
+
+ h2c = (struct rtw89_fw_h2c_rfk_pre_info_mcc *)skb->data;
- h2c->phy_idx = phy_idx;
h2c->aid = cpu_to_le32(hal->aid);
+done:
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_OUTSRC, H2C_CL_OUTSRC_RF_FW_NOTIFY,
H2C_FUNC_OUTSRC_RF_MCC_INFO, 0, 0, len);
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index 5292b568e2bf..91eaf07f5824 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -4586,13 +4586,23 @@ struct rtw89_fw_h2c_rfk_pre_info {
__le32 mlo_1_1;
} __packed;
-struct rtw89_fw_h2c_rfk_pre_info_mcc {
+struct rtw89_fw_h2c_rfk_pre_info_mcc_v0 {
+ __le32 tbl_18[NUM_OF_RTW89_FW_RFK_TBL][NUM_OF_RTW89_FW_RFK_PATH];
+ __le32 cur_18[NUM_OF_RTW89_FW_RFK_PATH];
+ __le32 mlo_mode;
+} __packed;
+
+struct rtw89_fw_h2c_rfk_pre_info_mcc_v1 {
__le32 tbl_18[NUM_OF_RTW89_FW_RFK_TBL];
__le32 cur_18[NUM_OF_RTW89_FW_RFK_PATH];
__le32 mlo_mode;
__le32 mlo_1_1;
u8 phy_idx;
u8 tbl_idx;
+} __packed;
+
+struct rtw89_fw_h2c_rfk_pre_info_mcc {
+ struct rtw89_fw_h2c_rfk_pre_info_mcc_v1 base;
u8 rsvd[2];
__le32 aid;
} __packed;
diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c
index f56b433a1674..d29fbc9cb5ac 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.c
+++ b/drivers/net/wireless/realtek/rtw89/phy.c
@@ -3808,19 +3808,22 @@ int rtw89_phy_rfk_pre_ntfy_and_wait(struct rtw89_dev *rtwdev,
{
int ret;
- if (RTW89_CHK_FW_FEATURE_GROUP(WITH_RFK_PRE_NOTIFY, &rtwdev->fw))
- goto pre_ntfy;
-
- return rtw89_fw_h2c_rf_pre_ntfy_mcc(rtwdev, phy_idx);
+ if (RTW89_CHK_FW_FEATURE_GROUP(WITH_RFK_PRE_NOTIFY, &rtwdev->fw)) {
+ rtw89_phy_rfk_report_prep(rtwdev);
+ rtw89_fw_h2c_rf_pre_ntfy(rtwdev, phy_idx);
+ ret = rtw89_phy_rfk_report_wait(rtwdev, "PRE_NTFY", ms);
+ if (ret)
+ return ret;
+ }
-pre_ntfy:
- rtw89_phy_rfk_report_prep(rtwdev);
+ if (RTW89_CHK_FW_FEATURE_GROUP(WITH_RFK_PRE_NOTIFY_MCC, &rtwdev->fw)) {
+ ret = rtw89_fw_h2c_rf_pre_ntfy_mcc(rtwdev, phy_idx);
+ if (ret)
+ return ret;
+ }
- ret = rtw89_fw_h2c_rf_pre_ntfy(rtwdev, phy_idx);
- if (ret)
- return ret;
+ return 0;
- return rtw89_phy_rfk_report_wait(rtwdev, "PRE_NTFY", ms);
}
EXPORT_SYMBOL(rtw89_phy_rfk_pre_ntfy_and_wait);
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c
index fce094c7ce93..98f14b31cf52 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c
@@ -205,11 +205,11 @@ static void rtw8922a_chlk_ktbl_sel(struct rtw89_dev *rtwdev, u8 kpath, u8 idx)
}
}
-static u8 rtw8922a_chlk_reload_sel_tbl(struct rtw89_dev *rtwdev,
- const struct rtw89_chan *chan, u8 path)
+static u8 rtw8922a_chlk_reload_sel_tbl_v0(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] = {};
+ struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc;
u8 tbl_sel;
for (tbl_sel = 0; tbl_sel < ARRAY_SIZE(desc); tbl_sel++) {
@@ -229,11 +229,53 @@ static u8 rtw8922a_chlk_reload_sel_tbl(struct rtw89_dev *rtwdev,
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].rf18[tbl_sel] = rtw89_chip_chan_to_rf18_val(rtwdev, chan);
rfk_mcc->data[path].table_idx = tbl_sel;
return tbl_sel;
}
+static u8 rtw8922a_chlk_reload_sel_tbl_v1(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan, u8 path)
+{
+ struct rtw89_rfk_mcc_info_data *rfk_mcc = rtwdev->rfk_mcc.data;
+ struct rtw89_rfk_chan_desc desc[__RTW89_RFK_CHS_NR_V1] = {};
+ u8 tbl_sel;
+
+ 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->has_band = true;
+ p->band = rfk_mcc->band[tbl_sel];
+
+ p->has_bw = true;
+ p->bw = rfk_mcc->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->rf18[tbl_sel] = rtw89_chip_chan_to_rf18_val(rtwdev, chan);
+
+ /* shared table array, but tbl_sel can be independent by path */
+ rfk_mcc[path].table_idx = tbl_sel;
+
+ return tbl_sel;
+}
+
+static u8 rtw8922a_chlk_reload_sel_tbl(struct rtw89_dev *rtwdev,
+ const struct rtw89_chan *chan, u8 path)
+{
+ if (RTW89_CHK_FW_FEATURE(RFK_PRE_NOTIFY_MCC_V1, &rtwdev->fw))
+ return rtw8922a_chlk_reload_sel_tbl_v1(rtwdev, chan, path);
+ else
+ return rtw8922a_chlk_reload_sel_tbl_v0(rtwdev, chan, path);
+}
+
static void rtw8922a_chlk_reload(struct rtw89_dev *rtwdev)
{
const struct rtw89_chan *chan0, *chan1;
--
2.25.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH rtw-next 10/11] wifi: rtw89: fix potential zero beacon interval in beacon tracking
2025-12-31 9:06 [PATCH rtw-next 00/11] wifi: rtw89: handle changes of RFK pre-notify Ping-Ke Shih
` (8 preceding siblings ...)
2025-12-31 9:06 ` [PATCH rtw-next 09/11] wifi: rtw89: rfk: update rtw89_fw_h2c_rf_pre_ntfy_mcc format Ping-Ke Shih
@ 2025-12-31 9:06 ` Ping-Ke Shih
2025-12-31 9:06 ` [PATCH rtw-next 11/11] wifi: rtw89: 8852b: refine hardware parameters for RFE type 5 Ping-Ke Shih
10 siblings, 0 replies; 12+ messages in thread
From: Ping-Ke Shih @ 2025-12-31 9:06 UTC (permalink / raw)
To: linux-wireless; +Cc: gary.chang, dian_syuan0116, damon.chen, kevin_yang
From: Kuan-Chung Chen <damon.chen@realtek.com>
During fuzz testing, it was discovered that bss_conf->beacon_int
might be zero, which could result in a division by zero error in
subsequent calculations. Set a default value of 100 TU if the
interval is zero to ensure stability.
Signed-off-by: Kuan-Chung Chen <damon.chen@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/core.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 191caafbd0fb..6811a3970ddb 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -2813,7 +2813,7 @@ static void rtw89_core_bcn_track_assoc(struct rtw89_dev *rtwdev,
rcu_read_lock();
bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
- beacon_int = bss_conf->beacon_int;
+ beacon_int = bss_conf->beacon_int ?: 100;
dtim = bss_conf->dtim_period;
rcu_read_unlock();
@@ -2843,9 +2843,7 @@ static void rtw89_core_bcn_track_reset(struct rtw89_dev *rtwdev)
memset(&rtwdev->bcn_track, 0, sizeof(rtwdev->bcn_track));
}
-static void rtw89_vif_rx_bcn_stat(struct rtw89_dev *rtwdev,
- struct ieee80211_bss_conf *bss_conf,
- struct sk_buff *skb)
+static void rtw89_vif_rx_bcn_stat(struct rtw89_dev *rtwdev, struct sk_buff *skb)
{
#define RTW89_APPEND_TSF_2GHZ 384
#define RTW89_APPEND_TSF_5GHZ 52
@@ -2854,7 +2852,7 @@ static void rtw89_vif_rx_bcn_stat(struct rtw89_dev *rtwdev,
struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
struct rtw89_beacon_stat *bcn_stat = &rtwdev->phystat.bcn_stat;
struct rtw89_beacon_track_info *bcn_track = &rtwdev->bcn_track;
- u32 bcn_intvl_us = ieee80211_tu_to_usec(bss_conf->beacon_int);
+ u32 bcn_intvl_us = ieee80211_tu_to_usec(bcn_track->beacon_int);
u64 tsf = le64_to_cpu(mgmt->u.beacon.timestamp);
u8 wp, num = bcn_stat->num;
u16 append;
@@ -2862,6 +2860,10 @@ static void rtw89_vif_rx_bcn_stat(struct rtw89_dev *rtwdev,
if (!RTW89_CHK_FW_FEATURE(BEACON_TRACKING, &rtwdev->fw))
return;
+ /* Skip if not yet associated */
+ if (!bcn_intvl_us)
+ return;
+
switch (rx_status->band) {
default:
case NL80211_BAND_2GHZ:
@@ -2949,7 +2951,7 @@ static void rtw89_vif_rx_stats_iter(void *data, u8 *mac,
pkt_stat->beacon_rate = desc_info->data_rate;
pkt_stat->beacon_len = skb->len;
- rtw89_vif_rx_bcn_stat(rtwdev, bss_conf, skb);
+ rtw89_vif_rx_bcn_stat(rtwdev, skb);
}
if (!ether_addr_equal(bss_conf->addr, hdr->addr1))
--
2.25.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH rtw-next 11/11] wifi: rtw89: 8852b: refine hardware parameters for RFE type 5
2025-12-31 9:06 [PATCH rtw-next 00/11] wifi: rtw89: handle changes of RFK pre-notify Ping-Ke Shih
` (9 preceding siblings ...)
2025-12-31 9:06 ` [PATCH rtw-next 10/11] wifi: rtw89: fix potential zero beacon interval in beacon tracking Ping-Ke Shih
@ 2025-12-31 9:06 ` Ping-Ke Shih
10 siblings, 0 replies; 12+ messages in thread
From: Ping-Ke Shih @ 2025-12-31 9:06 UTC (permalink / raw)
To: linux-wireless; +Cc: gary.chang, dian_syuan0116, damon.chen, kevin_yang
From: Dian-Syuan Yang <dian_syuan0116@realtek.com>
The RFE type 5 should set different DSWR parameters when card power on.
Therefore, add the corresponding register settings for this type.
Signed-off-by: Dian-Syuan Yang <dian_syuan0116@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/reg.h | 2 ++
drivers/net/wireless/realtek/rtw89/rtw8852b.c | 24 +++++++++++++++++--
2 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h
index 081623f84dd9..9f963bd85f02 100644
--- a/drivers/net/wireless/realtek/rtw89/reg.h
+++ b/drivers/net/wireless/realtek/rtw89/reg.h
@@ -323,7 +323,9 @@
#define B_AX_PCIE_HCISYS_PWR_STE_MASK GENMASK(1, 0)
#define R_AX_SPS_DIG_OFF_CTRL0 0x0400
+#define B_AX_R1_L1_MASK GENMASK(7, 6)
#define B_AX_C3_L1_MASK GENMASK(5, 4)
+#define B_AX_C2_L1_MASK GENMASK(3, 2)
#define B_AX_C1_L1_MASK GENMASK(1, 0)
#define R_AX_AFE_OFF_CTRL1 0x0444
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c
index 0f18555e619b..a138d89bce84 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c
@@ -313,6 +313,27 @@ static void rtw8852b_pwr_sps_ana(struct rtw89_dev *rtwdev)
rtw89_write16(rtwdev, R_AX_SPS_ANA_ON_CTRL2, RTL8852B_RFE_05_SPS_ANA);
}
+static void rtw8852b_pwr_sps_dig_off(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_efuse *efuse = &rtwdev->efuse;
+
+ if (efuse->rfe_type == 0x5) {
+ rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_OFF_CTRL0,
+ B_AX_C1_L1_MASK, 0x1);
+ rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_OFF_CTRL0,
+ B_AX_C2_L1_MASK, 0x1);
+ rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_OFF_CTRL0,
+ B_AX_C3_L1_MASK, 0x2);
+ rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_OFF_CTRL0,
+ B_AX_R1_L1_MASK, 0x1);
+ } else {
+ rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_OFF_CTRL0,
+ B_AX_C1_L1_MASK, 0x1);
+ rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_OFF_CTRL0,
+ B_AX_C3_L1_MASK, 0x3);
+ }
+}
+
static int rtw8852b_pwr_on_func(struct rtw89_dev *rtwdev)
{
u32 val32;
@@ -338,8 +359,7 @@ static int rtw8852b_pwr_on_func(struct rtw89_dev *rtwdev)
if (ret)
return ret;
- rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_OFF_CTRL0, B_AX_C1_L1_MASK, 0x1);
- rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_OFF_CTRL0, B_AX_C3_L1_MASK, 0x3);
+ rtw8852b_pwr_sps_dig_off(rtwdev);
rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON);
rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFN_ONMAC);
--
2.25.1
^ permalink raw reply related [flat|nested] 12+ messages in thread