The RTL8922DE has a RTL8922DE-VS variant which uses different firmware name and format version, and the rule to select firmware type will be needed to extend. Prepare for coming patches. Signed-off-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/core.c | 3 ++- drivers/net/wireless/realtek/rtw89/core.h | 25 +++++++++++++++++-- drivers/net/wireless/realtek/rtw89/fw.c | 10 +++++--- drivers/net/wireless/realtek/rtw89/fw.h | 1 + drivers/net/wireless/realtek/rtw89/rtw8851b.c | 6 +++-- drivers/net/wireless/realtek/rtw89/rtw8852a.c | 6 +++-- drivers/net/wireless/realtek/rtw89/rtw8852b.c | 6 +++-- .../net/wireless/realtek/rtw89/rtw8852bt.c | 6 +++-- drivers/net/wireless/realtek/rtw89/rtw8852c.c | 6 +++-- drivers/net/wireless/realtek/rtw89/rtw8922a.c | 7 ++++-- 10 files changed, 57 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index 6e77522bcd8f..bba5e7669b1b 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -6753,7 +6753,8 @@ struct rtw89_dev *rtw89_alloc_ieee80211_hw(struct device *device, bool support_mlo; bool no_chanctx; - firmware = rtw89_early_fw_feature_recognize(device, chip, &early_fw, &fw_format); + firmware = rtw89_early_fw_feature_recognize(device, chip, variant, + &early_fw, &fw_format); ops = kmemdup(&rtw89_ops, sizeof(rtw89_ops), GFP_KERNEL); if (!ops) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 4778957d6b2d..5cb8aacf7644 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -4152,6 +4152,11 @@ struct rtw89_reg_imr { u32 set; }; +struct rtw89_fw_def { + const char *fw_basename; + u8 fw_format_max; +}; + struct rtw89_phy_table { const struct rtw89_reg2_def *regs; u32 n_regs; @@ -4494,8 +4499,7 @@ struct rtw89_chip_info { const struct rtw89_chip_ops *ops; const struct rtw89_mac_gen_def *mac_def; const struct rtw89_phy_gen_def *phy_def; - const char *fw_basename; - u8 fw_format_max; + struct rtw89_fw_def fw_def; bool try_ce_fw; u8 bbmcu_nr; u32 needed_fw_elms; @@ -4633,6 +4637,7 @@ struct rtw89_chip_info { struct rtw89_chip_variant { bool no_mcs_12_13: 1; u32 fw_min_ver_code; + const struct rtw89_fw_def *fw_def_override; }; union rtw89_bus_info { @@ -7379,6 +7384,22 @@ void rtw89_chip_calc_rx_gain_normal(struct rtw89_dev *rtwdev, chip->ops->calc_rx_gain_normal(rtwdev, chan, path, phy_idx, calc); } +static inline const struct rtw89_fw_def * +__rtw89_chip_get_fw_def(const struct rtw89_chip_info *chip, + const struct rtw89_chip_variant *variant) +{ + if (variant && variant->fw_def_override) + return variant->fw_def_override; + + return &chip->fw_def; +} + +static inline +const struct rtw89_fw_def *rtw89_chip_get_fw_def(struct rtw89_dev *rtwdev) +{ + return __rtw89_chip_get_fw_def(rtwdev->chip, rtwdev->variant); +} + static inline void rtw89_load_txpwr_table(struct rtw89_dev *rtwdev, const struct rtw89_txpwr_table *tbl) { diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index f84726f04669..638af4ebf628 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -965,18 +965,20 @@ static void rtw89_fw_recognize_features(struct rtw89_dev *rtwdev) const struct firmware * rtw89_early_fw_feature_recognize(struct device *device, const struct rtw89_chip_info *chip, + const struct rtw89_chip_variant *variant, struct rtw89_fw_info *early_fw, int *used_fw_format) { + const struct rtw89_fw_def *fw_def = __rtw89_chip_get_fw_def(chip, variant); const struct firmware *firmware; char fw_name[64]; int fw_format; u32 ver_code; int ret; - for (fw_format = chip->fw_format_max; fw_format >= 0; fw_format--) { + for (fw_format = fw_def->fw_format_max; fw_format >= 0; fw_format--) { rtw89_fw_get_filename(fw_name, sizeof(fw_name), - chip->fw_basename, fw_format); + fw_def->fw_basename, fw_format); ret = request_firmware(&firmware, fw_name, device); if (!ret) { @@ -2024,11 +2026,11 @@ void rtw89_load_firmware_work(struct work_struct *work) { struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, load_firmware_work); - const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_fw_def *fw_def = rtw89_chip_get_fw_def(rtwdev); char fw_name[64]; rtw89_fw_get_filename(fw_name, sizeof(fw_name), - chip->fw_basename, rtwdev->fw.fw_format); + fw_def->fw_basename, rtwdev->fw.fw_format); rtw89_load_firmware_req(rtwdev, &rtwdev->fw.req, fw_name, false); } diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index d45b6ea6ea1b..c60d419616d6 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -5171,6 +5171,7 @@ int rtw89_fw_recognize_elements(struct rtw89_dev *rtwdev); const struct firmware * rtw89_early_fw_feature_recognize(struct device *device, const struct rtw89_chip_info *chip, + const struct rtw89_chip_variant *variant, struct rtw89_fw_info *early_fw, int *used_fw_format); int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b.c b/drivers/net/wireless/realtek/rtw89/rtw8851b.c index d6deb44a685b..171749f5002d 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c @@ -2580,8 +2580,10 @@ const struct rtw89_chip_info rtw8851b_chip_info = { .ops = &rtw8851b_chip_ops, .mac_def = &rtw89_mac_gen_ax, .phy_def = &rtw89_phy_gen_ax, - .fw_basename = RTW8851B_FW_BASENAME, - .fw_format_max = RTW8851B_FW_FORMAT_MAX, + .fw_def = { + .fw_basename = RTW8851B_FW_BASENAME, + .fw_format_max = RTW8851B_FW_FORMAT_MAX, + }, .try_ce_fw = true, .bbmcu_nr = 0, .needed_fw_elms = 0, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index 5ea7a36ab5ab..36d66f4e2dd0 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -2265,8 +2265,10 @@ const struct rtw89_chip_info rtw8852a_chip_info = { .ops = &rtw8852a_chip_ops, .mac_def = &rtw89_mac_gen_ax, .phy_def = &rtw89_phy_gen_ax, - .fw_basename = RTW8852A_FW_BASENAME, - .fw_format_max = RTW8852A_FW_FORMAT_MAX, + .fw_def = { + .fw_basename = RTW8852A_FW_BASENAME, + .fw_format_max = RTW8852A_FW_FORMAT_MAX, + }, .try_ce_fw = false, .bbmcu_nr = 0, .needed_fw_elms = 0, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c index 197e3f5fb21b..602432c47ea3 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c @@ -911,8 +911,10 @@ const struct rtw89_chip_info rtw8852b_chip_info = { .ops = &rtw8852b_chip_ops, .mac_def = &rtw89_mac_gen_ax, .phy_def = &rtw89_phy_gen_ax, - .fw_basename = RTW8852B_FW_BASENAME, - .fw_format_max = RTW8852B_FW_FORMAT_MAX, + .fw_def = { + .fw_basename = RTW8852B_FW_BASENAME, + .fw_format_max = RTW8852B_FW_FORMAT_MAX, + }, .try_ce_fw = true, .bbmcu_nr = 0, .needed_fw_elms = 0, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c index 92bbd6e5d699..514861e48c25 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c @@ -757,8 +757,10 @@ const struct rtw89_chip_info rtw8852bt_chip_info = { .ops = &rtw8852bt_chip_ops, .mac_def = &rtw89_mac_gen_ax, .phy_def = &rtw89_phy_gen_ax, - .fw_basename = RTW8852BT_FW_BASENAME, - .fw_format_max = RTW8852BT_FW_FORMAT_MAX, + .fw_def = { + .fw_basename = RTW8852BT_FW_BASENAME, + .fw_format_max = RTW8852BT_FW_FORMAT_MAX, + }, .try_ce_fw = true, .bbmcu_nr = 0, .needed_fw_elms = RTW89_AX_GEN_DEF_NEEDED_FW_ELEMENTS_NO_6GHZ, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index de5d343f80a5..70ca8c3950d9 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -3106,8 +3106,10 @@ const struct rtw89_chip_info rtw8852c_chip_info = { .ops = &rtw8852c_chip_ops, .mac_def = &rtw89_mac_gen_ax, .phy_def = &rtw89_phy_gen_ax, - .fw_basename = RTW8852C_FW_BASENAME, - .fw_format_max = RTW8852C_FW_FORMAT_MAX, + .fw_def = { + .fw_basename = RTW8852C_FW_BASENAME, + .fw_format_max = RTW8852C_FW_FORMAT_MAX, + }, .try_ce_fw = false, .bbmcu_nr = 0, .needed_fw_elms = 0, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.c b/drivers/net/wireless/realtek/rtw89/rtw8922a.c index f41b66b362c4..fd1b171b106c 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8922a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.c @@ -2916,8 +2916,10 @@ const struct rtw89_chip_info rtw8922a_chip_info = { .ops = &rtw8922a_chip_ops, .mac_def = &rtw89_mac_gen_be, .phy_def = &rtw89_phy_gen_be, - .fw_basename = RTW8922A_FW_BASENAME, - .fw_format_max = RTW8922A_FW_FORMAT_MAX, + .fw_def = { + .fw_basename = RTW8922A_FW_BASENAME, + .fw_format_max = RTW8922A_FW_FORMAT_MAX, + }, .try_ce_fw = false, .bbmcu_nr = 1, .needed_fw_elms = RTW89_BE_GEN_DEF_NEEDED_FW_ELEMENTS, @@ -3057,6 +3059,7 @@ EXPORT_SYMBOL(rtw8922a_chip_info); const struct rtw89_chip_variant rtw8922ae_vs_variant = { .no_mcs_12_13 = true, .fw_min_ver_code = RTW89_FW_VER_CODE(0, 35, 54, 0), + .fw_def_override = NULL, }; EXPORT_SYMBOL(rtw8922ae_vs_variant); -- 2.25.1 Select a firmware suit including normal and WoWLAN firmware by chip AID from multiple firmware, because coming RTL8922D has variant hardware with different chip AID. Signed-off-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/core.h | 4 ++++ drivers/net/wireless/realtek/rtw89/fw.c | 13 +++++++++++-- drivers/net/wireless/realtek/rtw89/rtw8851b.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852bt.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8922a.c | 1 + 8 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 5cb8aacf7644..d1f58bf953a9 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -4155,6 +4155,7 @@ struct rtw89_reg_imr { struct rtw89_fw_def { const char *fw_basename; u8 fw_format_max; + u16 fw_b_aid; }; struct rtw89_phy_table { @@ -4729,6 +4730,8 @@ enum rtw89_fw_type { RTW89_FW_NORMAL = 1, RTW89_FW_WOWLAN = 3, RTW89_FW_NORMAL_CE = 5, + RTW89_FW_NORMAL_B = 14, + RTW89_FW_WOWLAN_B = 15, RTW89_FW_BBMCU0 = 64, RTW89_FW_BBMCU1 = 65, RTW89_FW_LOGFMT = 255, @@ -7562,6 +7565,7 @@ static inline struct rtw89_fw_suit *rtw89_fw_suit_get(struct rtw89_dev *rtwdev, switch (type) { case RTW89_FW_WOWLAN: + case RTW89_FW_WOWLAN_B: return &fw_info->wowlan; case RTW89_FW_LOGFMT: return &fw_info->log.suit; diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 638af4ebf628..ff27f00ec6d2 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -1027,16 +1027,25 @@ static int rtw89_fw_validate_ver_required(struct rtw89_dev *rtwdev) int rtw89_fw_recognize(struct rtw89_dev *rtwdev) { + const struct rtw89_fw_def *fw_def = rtw89_chip_get_fw_def(rtwdev); const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_hal *hal = &rtwdev->hal; + enum rtw89_fw_type normal_fw_type = RTW89_FW_NORMAL; + enum rtw89_fw_type wowlan_fw_type = RTW89_FW_WOWLAN; int ret; + if (fw_def->fw_b_aid && fw_def->fw_b_aid == hal->aid) { + normal_fw_type = RTW89_FW_NORMAL_B; + wowlan_fw_type = RTW89_FW_WOWLAN_B; + } + if (chip->try_ce_fw) { ret = __rtw89_fw_recognize(rtwdev, RTW89_FW_NORMAL_CE, true); if (!ret) goto normal_done; } - ret = __rtw89_fw_recognize(rtwdev, RTW89_FW_NORMAL, false); + ret = __rtw89_fw_recognize(rtwdev, normal_fw_type, false); if (ret) return ret; @@ -1046,7 +1055,7 @@ int rtw89_fw_recognize(struct rtw89_dev *rtwdev) return ret; /* It still works if wowlan firmware isn't existing. */ - __rtw89_fw_recognize(rtwdev, RTW89_FW_WOWLAN, false); + __rtw89_fw_recognize(rtwdev, wowlan_fw_type, false); /* It still works if log format file isn't existing. */ __rtw89_fw_recognize(rtwdev, RTW89_FW_LOGFMT, true); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b.c b/drivers/net/wireless/realtek/rtw89/rtw8851b.c index 171749f5002d..89c759a2b5f4 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c @@ -2583,6 +2583,7 @@ const struct rtw89_chip_info rtw8851b_chip_info = { .fw_def = { .fw_basename = RTW8851B_FW_BASENAME, .fw_format_max = RTW8851B_FW_FORMAT_MAX, + .fw_b_aid = 0, }, .try_ce_fw = true, .bbmcu_nr = 0, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index 36d66f4e2dd0..32644c40ae28 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -2268,6 +2268,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = { .fw_def = { .fw_basename = RTW8852A_FW_BASENAME, .fw_format_max = RTW8852A_FW_FORMAT_MAX, + .fw_b_aid = 0, }, .try_ce_fw = false, .bbmcu_nr = 0, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c index 602432c47ea3..c2e14a9dfc73 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c @@ -914,6 +914,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = { .fw_def = { .fw_basename = RTW8852B_FW_BASENAME, .fw_format_max = RTW8852B_FW_FORMAT_MAX, + .fw_b_aid = 0, }, .try_ce_fw = true, .bbmcu_nr = 0, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c index 514861e48c25..0acdf64395f0 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c @@ -760,6 +760,7 @@ const struct rtw89_chip_info rtw8852bt_chip_info = { .fw_def = { .fw_basename = RTW8852BT_FW_BASENAME, .fw_format_max = RTW8852BT_FW_FORMAT_MAX, + .fw_b_aid = 0, }, .try_ce_fw = true, .bbmcu_nr = 0, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 70ca8c3950d9..9f0dd6a3956f 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -3109,6 +3109,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = { .fw_def = { .fw_basename = RTW8852C_FW_BASENAME, .fw_format_max = RTW8852C_FW_FORMAT_MAX, + .fw_b_aid = 0, }, .try_ce_fw = false, .bbmcu_nr = 0, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.c b/drivers/net/wireless/realtek/rtw89/rtw8922a.c index fd1b171b106c..1c9db283cff9 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8922a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.c @@ -2919,6 +2919,7 @@ const struct rtw89_chip_info rtw8922a_chip_info = { .fw_def = { .fw_basename = RTW8922A_FW_BASENAME, .fw_format_max = RTW8922A_FW_FORMAT_MAX, + .fw_b_aid = 0, }, .try_ce_fw = false, .bbmcu_nr = 1, -- 2.25.1 From: Zong-Zhe Yang Module firmware string depends on max format of the firmware. When max format is 0, the module firmware string will be like XYZ.bin. However, when max format N > 0, the module firmware string will become XYZ-N.bin. Originally, when one chip updated its max firmware format from 0 to 1, the module firmware string also needed to be changed. However, did not need to do for other cases, e.g. from 1 to 2. It's a bit inconvenient to always remember that from 0 to 1 is a special case. So, add a general macro to generate the corresponding module firmware string based on max firmware format. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/core.h | 9 +++++++++ drivers/net/wireless/realtek/rtw89/rtw8851b.c | 2 +- drivers/net/wireless/realtek/rtw89/rtw8852a.c | 2 +- drivers/net/wireless/realtek/rtw89/rtw8852b.c | 2 +- drivers/net/wireless/realtek/rtw89/rtw8852bt.c | 2 +- drivers/net/wireless/realtek/rtw89/rtw8852c.c | 2 +- drivers/net/wireless/realtek/rtw89/rtw8922a.c | 2 +- 7 files changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index d1f58bf953a9..1ad1fd2a1f6f 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -4152,6 +4152,15 @@ struct rtw89_reg_imr { u32 set; }; +#define RTW89_MODULE_FWNAME_PLACEHOLDER_0 0, +#define __RTW89_GEN_MODULE_FWNAME_FMT(placeholder_or_ignored, strfmt) \ + __take_second_arg(placeholder_or_ignored, strfmt) +#define RTW89_GEN_MODULE_FWNAME_FMT(maxfmt) \ + __RTW89_GEN_MODULE_FWNAME_FMT(RTW89_MODULE_FWNAME_PLACEHOLDER_ ## maxfmt, \ + "-" __stringify(maxfmt)) +#define RTW89_GEN_MODULE_FWNAME(basename, maxformat) \ + basename RTW89_GEN_MODULE_FWNAME_FMT(maxformat) ".bin" + struct rtw89_fw_def { const char *fw_basename; u8 fw_format_max; diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b.c b/drivers/net/wireless/realtek/rtw89/rtw8851b.c index 89c759a2b5f4..0ea125ef21fa 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c @@ -18,7 +18,7 @@ #define RTW8851B_FW_FORMAT_MAX 0 #define RTW8851B_FW_BASENAME "rtw89/rtw8851b_fw" #define RTW8851B_MODULE_FIRMWARE \ - RTW8851B_FW_BASENAME ".bin" + RTW89_GEN_MODULE_FWNAME(RTW8851B_FW_BASENAME, RTW8851B_FW_FORMAT_MAX) static const struct rtw89_hfc_ch_cfg rtw8851b_hfc_chcfg_pcie[] = { {5, 343, grp_0}, /* ACH 0 */ diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index 32644c40ae28..0d5ec9755783 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -15,7 +15,7 @@ #define RTW8852A_FW_FORMAT_MAX 0 #define RTW8852A_FW_BASENAME "rtw89/rtw8852a_fw" #define RTW8852A_MODULE_FIRMWARE \ - RTW8852A_FW_BASENAME ".bin" + RTW89_GEN_MODULE_FWNAME(RTW8852A_FW_BASENAME, RTW8852A_FW_FORMAT_MAX) static const struct rtw89_hfc_ch_cfg rtw8852a_hfc_chcfg_pcie[] = { {128, 1896, grp_0}, /* ACH 0 */ diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c index c2e14a9dfc73..b687ddaa839e 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c @@ -16,7 +16,7 @@ #define RTW8852B_FW_FORMAT_MAX 1 #define RTW8852B_FW_BASENAME "rtw89/rtw8852b_fw" #define RTW8852B_MODULE_FIRMWARE \ - RTW8852B_FW_BASENAME "-" __stringify(RTW8852B_FW_FORMAT_MAX) ".bin" + RTW89_GEN_MODULE_FWNAME(RTW8852B_FW_BASENAME, RTW8852B_FW_FORMAT_MAX) static const struct rtw89_hfc_ch_cfg rtw8852b_hfc_chcfg_pcie[] = { {5, 341, grp_0}, /* ACH 0 */ diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c index 0acdf64395f0..c86b995a7cb1 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c @@ -14,7 +14,7 @@ #define RTW8852BT_FW_FORMAT_MAX 0 #define RTW8852BT_FW_BASENAME "rtw89/rtw8852bt_fw" #define RTW8852BT_MODULE_FIRMWARE \ - RTW8852BT_FW_BASENAME ".bin" + RTW89_GEN_MODULE_FWNAME(RTW8852BT_FW_BASENAME, RTW8852BT_FW_FORMAT_MAX) static const struct rtw89_hfc_ch_cfg rtw8852bt_hfc_chcfg_pcie[] = { {16, 742, grp_0}, /* ACH 0 */ diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 9f0dd6a3956f..e62a7288c8aa 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -18,7 +18,7 @@ #define RTW8852C_FW_FORMAT_MAX 2 #define RTW8852C_FW_BASENAME "rtw89/rtw8852c_fw" #define RTW8852C_MODULE_FIRMWARE \ - RTW8852C_FW_BASENAME "-" __stringify(RTW8852C_FW_FORMAT_MAX) ".bin" + RTW89_GEN_MODULE_FWNAME(RTW8852C_FW_BASENAME, RTW8852C_FW_FORMAT_MAX) static const struct rtw89_hfc_ch_cfg rtw8852c_hfc_chcfg_pcie[] = { {13, 1614, grp_0}, /* ACH 0 */ diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.c b/drivers/net/wireless/realtek/rtw89/rtw8922a.c index 1c9db283cff9..36ef36110602 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8922a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.c @@ -18,7 +18,7 @@ #define RTW8922A_FW_FORMAT_MAX 4 #define RTW8922A_FW_BASENAME "rtw89/rtw8922a_fw" #define RTW8922A_MODULE_FIRMWARE \ - RTW8922A_FW_BASENAME "-" __stringify(RTW8922A_FW_FORMAT_MAX) ".bin" + RTW89_GEN_MODULE_FWNAME(RTW8922A_FW_BASENAME, RTW8922A_FW_FORMAT_MAX) #define HE_N_USER_MAX_8922A 4 -- 2.25.1 After firmware version 0.29.29.15, more data are included in firmware file. Increase format to 2 to prevent old driver failed to load the new firmware. Signed-off-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/rtw8852b.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c index b687ddaa839e..f4fb5f76298c 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c @@ -13,7 +13,7 @@ #include "rtw8852b_table.h" #include "txrx.h" -#define RTW8852B_FW_FORMAT_MAX 1 +#define RTW8852B_FW_FORMAT_MAX 2 #define RTW8852B_FW_BASENAME "rtw89/rtw8852b_fw" #define RTW8852B_MODULE_FIRMWARE \ RTW89_GEN_MODULE_FWNAME(RTW8852B_FW_BASENAME, RTW8852B_FW_FORMAT_MAX) -- 2.25.1 From: Zong-Zhe Yang Now, most of PHY parameter tables in driver can be loaded via FW elements. Plan to generate the corresponding FW elements for 8852A PHY tables. Then, after FW elements work for a enough time, rtw8852a_table.c can be cleaned up. However, DIG (dynamic initial gain) tables are legacy for 8852A only, so FW element doesn't support. Their sizes are not very big, so move them to rtw8852a.c and keep rtw8852a_table.c for PHY tables which are supported by FW elements. No logic is changed. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/rtw8852a.c | 51 +++++++++++++++++++ .../wireless/realtek/rtw89/rtw8852a_table.c | 51 ------------------- .../wireless/realtek/rtw89/rtw8852a_table.h | 1 - 3 files changed, 51 insertions(+), 52 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index 0d5ec9755783..6089cf9e1d54 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -2179,6 +2179,57 @@ static void rtw8852a_query_ppdu(struct rtw89_dev *rtwdev, rtw8852a_fill_freq_with_ppdu(rtwdev, phy_ppdu, status); } +#define DECLARE_DIG_TABLE(name) \ +static const struct rtw89_phy_dig_gain_cfg name##_table = { \ + .table = name, \ + .size = ARRAY_SIZE(name) \ +} + +static const struct rtw89_reg_def rtw89_8852a_lna_gain_g[] = { + {R_PATH0_LNA_ERR1, B_PATH0_LNA_ERR_G0_G_MSK}, + {R_PATH0_LNA_ERR2, B_PATH0_LNA_ERR_G1_G_MSK}, + {R_PATH0_LNA_ERR2, B_PATH0_LNA_ERR_G2_G_MSK}, + {R_PATH0_LNA_ERR3, B_PATH0_LNA_ERR_G3_G_MSK}, + {R_PATH0_LNA_ERR3, B_PATH0_LNA_ERR_G4_G_MSK}, + {R_PATH0_LNA_ERR4, B_PATH0_LNA_ERR_G5_G_MSK}, + {R_PATH0_LNA_ERR5, B_PATH0_LNA_ERR_G6_G_MSK}, +}; + +DECLARE_DIG_TABLE(rtw89_8852a_lna_gain_g); + +static const struct rtw89_reg_def rtw89_8852a_tia_gain_g[] = { + {R_PATH0_TIA_ERR_G0, B_PATH0_TIA_ERR_G0_G_MSK}, + {R_PATH0_TIA_ERR_G1, B_PATH0_TIA_ERR_G1_G_MSK}, +}; + +DECLARE_DIG_TABLE(rtw89_8852a_tia_gain_g); + +static const struct rtw89_reg_def rtw89_8852a_lna_gain_a[] = { + {R_PATH0_LNA_ERR1, B_PATH0_LNA_ERR_G0_A_MSK}, + {R_PATH0_LNA_ERR1, B_PATH0_LNA_ERR_G1_A_MSK}, + {R_PATH0_LNA_ERR2, B_PATH0_LNA_ERR_G2_A_MSK}, + {R_PATH0_LNA_ERR3, B_PATH0_LNA_ERR_G3_A_MSK}, + {R_PATH0_LNA_ERR3, B_PATH0_LNA_ERR_G4_A_MSK}, + {R_PATH0_LNA_ERR4, B_PATH0_LNA_ERR_G5_A_MSK}, + {R_PATH0_LNA_ERR4, B_PATH0_LNA_ERR_G6_A_MSK}, +}; + +DECLARE_DIG_TABLE(rtw89_8852a_lna_gain_a); + +static const struct rtw89_reg_def rtw89_8852a_tia_gain_a[] = { + {R_PATH0_TIA_ERR_G0, B_PATH0_TIA_ERR_G0_A_MSK}, + {R_PATH0_TIA_ERR_G1, B_PATH0_TIA_ERR_G1_A_MSK}, +}; + +DECLARE_DIG_TABLE(rtw89_8852a_tia_gain_a); + +static const struct rtw89_phy_dig_gain_table rtw89_8852a_phy_dig_table = { + .cfg_lna_g = &rtw89_8852a_lna_gain_g_table, + .cfg_tia_g = &rtw89_8852a_tia_gain_g_table, + .cfg_lna_a = &rtw89_8852a_lna_gain_a_table, + .cfg_tia_a = &rtw89_8852a_tia_gain_a_table +}; + #ifdef CONFIG_PM static const struct wiphy_wowlan_support rtw_wowlan_stub_8852a = { .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_table.c b/drivers/net/wireless/realtek/rtw89/rtw8852a_table.c index 495890c180ef..ffdeb3801991 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a_table.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_table.c @@ -50952,50 +50952,6 @@ const s8 rtw89_8852a_txpwr_lmt_ru_5g[RTW89_RU_NUM][RTW89_NTX_NUM] [2][1][RTW89_UK][46] = 32, }; -#define DECLARE_DIG_TABLE(name) \ -static const struct rtw89_phy_dig_gain_cfg name##_table = { \ - .table = name, \ - .size = ARRAY_SIZE(name) \ -} - -static const struct rtw89_reg_def rtw89_8852a_lna_gain_g[] = { - {R_PATH0_LNA_ERR1, B_PATH0_LNA_ERR_G0_G_MSK}, - {R_PATH0_LNA_ERR2, B_PATH0_LNA_ERR_G1_G_MSK}, - {R_PATH0_LNA_ERR2, B_PATH0_LNA_ERR_G2_G_MSK}, - {R_PATH0_LNA_ERR3, B_PATH0_LNA_ERR_G3_G_MSK}, - {R_PATH0_LNA_ERR3, B_PATH0_LNA_ERR_G4_G_MSK}, - {R_PATH0_LNA_ERR4, B_PATH0_LNA_ERR_G5_G_MSK}, - {R_PATH0_LNA_ERR5, B_PATH0_LNA_ERR_G6_G_MSK}, -}; - -DECLARE_DIG_TABLE(rtw89_8852a_lna_gain_g); - -static const struct rtw89_reg_def rtw89_8852a_tia_gain_g[] = { - {R_PATH0_TIA_ERR_G0, B_PATH0_TIA_ERR_G0_G_MSK}, - {R_PATH0_TIA_ERR_G1, B_PATH0_TIA_ERR_G1_G_MSK}, -}; - -DECLARE_DIG_TABLE(rtw89_8852a_tia_gain_g); - -static const struct rtw89_reg_def rtw89_8852a_lna_gain_a[] = { - {R_PATH0_LNA_ERR1, B_PATH0_LNA_ERR_G0_A_MSK}, - {R_PATH0_LNA_ERR1, B_PATH0_LNA_ERR_G1_A_MSK}, - {R_PATH0_LNA_ERR2, B_PATH0_LNA_ERR_G2_A_MSK}, - {R_PATH0_LNA_ERR3, B_PATH0_LNA_ERR_G3_A_MSK}, - {R_PATH0_LNA_ERR3, B_PATH0_LNA_ERR_G4_A_MSK}, - {R_PATH0_LNA_ERR4, B_PATH0_LNA_ERR_G5_A_MSK}, - {R_PATH0_LNA_ERR4, B_PATH0_LNA_ERR_G6_A_MSK}, -}; - -DECLARE_DIG_TABLE(rtw89_8852a_lna_gain_a); - -static const struct rtw89_reg_def rtw89_8852a_tia_gain_a[] = { - {R_PATH0_TIA_ERR_G0, B_PATH0_TIA_ERR_G0_A_MSK}, - {R_PATH0_TIA_ERR_G1, B_PATH0_TIA_ERR_G1_A_MSK}, -}; - -DECLARE_DIG_TABLE(rtw89_8852a_tia_gain_a); - const struct rtw89_phy_table rtw89_8852a_phy_bb_table = { .regs = rtw89_8852a_phy_bb_regs, .n_regs = ARRAY_SIZE(rtw89_8852a_phy_bb_regs), @@ -51042,13 +50998,6 @@ const struct rtw89_txpwr_track_cfg rtw89_8852a_trk_cfg = { .delta_swingidx_2g_cck_a_p = _txpwr_track_delta_swingidx_2g_cck_a_p, }; -const struct rtw89_phy_dig_gain_table rtw89_8852a_phy_dig_table = { - .cfg_lna_g = &rtw89_8852a_lna_gain_g_table, - .cfg_tia_g = &rtw89_8852a_tia_gain_g_table, - .cfg_lna_a = &rtw89_8852a_lna_gain_a_table, - .cfg_tia_a = &rtw89_8852a_tia_gain_a_table -}; - const struct rtw89_rfe_parms rtw89_8852a_dflt_parms = { .byr_tbl = &rtw89_8852a_byr_table, .rule_2ghz = { diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_table.h b/drivers/net/wireless/realtek/rtw89/rtw8852a_table.h index 7463ae6ee3f9..58fe8575c1c9 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a_table.h +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_table.h @@ -11,7 +11,6 @@ extern const struct rtw89_phy_table rtw89_8852a_phy_bb_table; extern const struct rtw89_phy_table rtw89_8852a_phy_radioa_table; extern const struct rtw89_phy_table rtw89_8852a_phy_radiob_table; extern const struct rtw89_phy_table rtw89_8852a_phy_nctl_table; -extern const struct rtw89_phy_dig_gain_table rtw89_8852a_phy_dig_table; extern const struct rtw89_txpwr_track_cfg rtw89_8852a_trk_cfg; extern const struct rtw89_rfe_parms rtw89_8852a_dflt_parms; -- 2.25.1 From: Zong-Zhe Yang More data will be included in Firmware file and loaded via FW elements. Unlike other chips, for RF radio, RTL8852A uses rtw89_phy_config_rf_reg instead of v1, so update loading handling of corresponding FW element. And then, increase RTL8852A FW format to 1 to prevent old driver from misusing the data in FW elements. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/fw.c | 5 ++++- drivers/net/wireless/realtek/rtw89/phy.c | 8 ++++---- drivers/net/wireless/realtek/rtw89/phy.h | 4 ++++ drivers/net/wireless/realtek/rtw89/rtw8852a.c | 2 +- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index ff27f00ec6d2..64874907bfe0 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -1073,6 +1073,7 @@ int rtw89_build_phy_tbl_from_elm(struct rtw89_dev *rtwdev, const union rtw89_fw_element_arg arg) { struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; + const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_hal *hal = &rtwdev->hal; struct rtw89_phy_table *tbl, **pp; struct rtw89_reg2_def *regs; @@ -1129,7 +1130,9 @@ int rtw89_build_phy_tbl_from_elm(struct rtw89_dev *rtwdev, if (radio) { tbl->rf_path = arg.rf_path; - tbl->config = rtw89_phy_config_rf_reg_v1; + tbl->config = chip->chip_id == RTL8852A ? + rtw89_phy_config_rf_reg : + rtw89_phy_config_rf_reg_v1; } *pp = tbl; diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index 6c6d5f1da867..0e9925f43260 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -1659,10 +1659,10 @@ static void rtw89_phy_config_rf_reg_noio(struct rtw89_dev *rtwdev, (struct rtw89_fw_h2c_rf_reg_info *)extra_data); } -static void rtw89_phy_config_rf_reg(struct rtw89_dev *rtwdev, - const struct rtw89_reg2_def *reg, - enum rtw89_rf_path rf_path, - void *extra_data) +void rtw89_phy_config_rf_reg(struct rtw89_dev *rtwdev, + const struct rtw89_reg2_def *reg, + enum rtw89_rf_path rf_path, + void *extra_data) { if (reg->addr == 0xfe) { mdelay(50); diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h index ab263738d212..094c7e45f254 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.h +++ b/drivers/net/wireless/realtek/rtw89/phy.h @@ -852,6 +852,10 @@ bool rtw89_phy_write_rf_v3(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path, void rtw89_phy_init_bb_reg(struct rtw89_dev *rtwdev); void rtw89_phy_init_bb_afe(struct rtw89_dev *rtwdev); void rtw89_phy_init_rf_reg(struct rtw89_dev *rtwdev, bool noio); +void rtw89_phy_config_rf_reg(struct rtw89_dev *rtwdev, + const struct rtw89_reg2_def *reg, + enum rtw89_rf_path rf_path, + void *extra_data); void rtw89_phy_config_rf_reg_v1(struct rtw89_dev *rtwdev, const struct rtw89_reg2_def *reg, enum rtw89_rf_path rf_path, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index 6089cf9e1d54..898c534a5762 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -12,7 +12,7 @@ #include "rtw8852a_table.h" #include "txrx.h" -#define RTW8852A_FW_FORMAT_MAX 0 +#define RTW8852A_FW_FORMAT_MAX 1 #define RTW8852A_FW_BASENAME "rtw89/rtw8852a_fw" #define RTW8852A_MODULE_FIRMWARE \ RTW89_GEN_MODULE_FWNAME(RTW8852A_FW_BASENAME, RTW8852A_FW_FORMAT_MAX) -- 2.25.1 From: Zong-Zhe Yang More data will be included in Firmware file and loaded via FW elements. Increase RTL8851B FW format to 1 to prevent old driver from failing to recognize FW with FW elements. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/rtw8851b.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b.c b/drivers/net/wireless/realtek/rtw89/rtw8851b.c index 0ea125ef21fa..a0769cdd2352 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c @@ -15,7 +15,7 @@ #include "txrx.h" #include "util.h" -#define RTW8851B_FW_FORMAT_MAX 0 +#define RTW8851B_FW_FORMAT_MAX 1 #define RTW8851B_FW_BASENAME "rtw89/rtw8851b_fw" #define RTW8851B_MODULE_FIRMWARE \ RTW89_GEN_MODULE_FWNAME(RTW8851B_FW_BASENAME, RTW8851B_FW_FORMAT_MAX) -- 2.25.1 From: Kuan-Chung Chen For BE chips, the unused PHY should pause transmissions and receptions. This ensures that no unexpected packets are routed to an inactive PHY, which could otherwise trigger SER L0 and lead to TX hang. Signed-off-by: Kuan-Chung Chen Signed-off-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/fw.c | 87 +++++++++++++++++++ drivers/net/wireless/realtek/rtw89/fw.h | 51 +++++++++++ drivers/net/wireless/realtek/rtw89/mac.c | 3 + drivers/net/wireless/realtek/rtw89/mac80211.c | 5 ++ drivers/net/wireless/realtek/rtw89/ps.c | 2 + 5 files changed, 148 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 64874907bfe0..bfa5cac24d88 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -6871,6 +6871,93 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev, return 0; } +int rtw89_fw_h2c_trx_protect(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, bool enable) +{ + struct rtw89_wait_info *wait = &rtwdev->mac.fw_ofld_wait; + const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_h2c_trx_protect *h2c; + u32 len = sizeof(*h2c); + struct sk_buff *skb; + int ret; + + if (chip->chip_gen != RTW89_CHIP_BE) + return 0; + + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); + if (!skb) { + rtw89_err(rtwdev, "failed to alloc skb for h2c trx protect\n"); + return -ENOMEM; + } + + skb_put(skb, len); + h2c = (struct rtw89_h2c_trx_protect *)skb->data; + + h2c->c0 = le32_encode_bits(BIT(phy_idx), RTW89_H2C_TRX_PROTECT_C0_BAND_BITMAP) | + le32_encode_bits(0, RTW89_H2C_TRX_PROTECT_C0_OP_MODE); + h2c->c1 = le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_C1_RX_IN) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_C1_PPDU_STS) | + le32_encode_bits(1, RTW89_H2C_TRX_PROTECT_C1_MSK_RX_IN) | + le32_encode_bits(1, RTW89_H2C_TRX_PROTECT_C1_MSK_PPDU_STS); + h2c->w0 = le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_BE0) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_BK0) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_VI0) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_VO0) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_BE1) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_BK1) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_VI1) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_VO1) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_MG0) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_MG1) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_MG2) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_HI) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_BCN) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_UL) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT0) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT1) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT2) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT3) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_SPEQ0) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W0_TXEN_SPEQ1); + h2c->m0 = cpu_to_le32(RTW89_H2C_TRX_PROTECT_W0_TXEN_BE0 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_BK0 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_VI0 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_VO0 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_BE1 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_BK1 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_VI1 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_VO1 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_MG0 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_MG1 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_MG2 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_HI | + RTW89_H2C_TRX_PROTECT_W0_TXEN_BCN | + RTW89_H2C_TRX_PROTECT_W0_TXEN_UL | + RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT0 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT1 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT2 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT3 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_SPEQ0 | + RTW89_H2C_TRX_PROTECT_W0_TXEN_SPEQ1); + h2c->w1 = le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W1_CHINFO_EN) | + le32_encode_bits(enable, RTW89_H2C_TRX_PROTECT_W1_DFS_EN); + h2c->m1 = cpu_to_le32(RTW89_H2C_TRX_PROTECT_W1_CHINFO_EN | + RTW89_H2C_TRX_PROTECT_W1_DFS_EN); + + rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, + H2C_CAT_MAC, H2C_CL_MAC_FW_OFLD, + H2C_FUNC_TRX_PROTECT, 0, 1, len); + + ret = rtw89_h2c_tx_and_wait(rtwdev, skb, wait, + RTW89_FW_OFLD_WAIT_COND_TRX_PROTECT); + if (ret) { + rtw89_debug(rtwdev, RTW89_DBG_FW, "failed to trx protect\n"); + return ret; + } + + return 0; +} + int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev, struct rtw89_fw_h2c_rf_reg_info *info, u16 len, u8 page) diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index c60d419616d6..80d260eb08cd 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -3106,6 +3106,44 @@ struct rtw89_h2c_scanofld_be { #define RTW89_H2C_SCANOFLD_BE_W9_SIZE_MACC GENMASK(15, 8) #define RTW89_H2C_SCANOFLD_BE_W9_SIZE_OP GENMASK(23, 16) +struct rtw89_h2c_trx_protect { + __le32 c0; + __le32 c1; + __le32 w0; + __le32 m0; + __le32 w1; + __le32 m1; +} __packed; + +#define RTW89_H2C_TRX_PROTECT_C0_BAND_BITMAP GENMASK(2, 0) +#define RTW89_H2C_TRX_PROTECT_C0_OP_MODE GENMASK(4, 3) +#define RTW89_H2C_TRX_PROTECT_C1_RX_IN BIT(0) +#define RTW89_H2C_TRX_PROTECT_C1_PPDU_STS BIT(4) +#define RTW89_H2C_TRX_PROTECT_C1_MSK_RX_IN BIT(16) +#define RTW89_H2C_TRX_PROTECT_C1_MSK_PPDU_STS BIT(20) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_BE0 BIT(0) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_BK0 BIT(1) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_VI0 BIT(2) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_VO0 BIT(3) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_BE1 BIT(4) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_BK1 BIT(5) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_VI1 BIT(6) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_VO1 BIT(7) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_MG0 BIT(8) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_MG1 BIT(9) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_MG2 BIT(10) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_HI BIT(11) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_BCN BIT(12) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_UL BIT(13) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT0 BIT(14) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT1 BIT(15) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT2 BIT(16) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_TWT3 BIT(17) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_SPEQ0 BIT(18) +#define RTW89_H2C_TRX_PROTECT_W0_TXEN_SPEQ1 BIT(19) +#define RTW89_H2C_TRX_PROTECT_W1_CHINFO_EN BIT(0) +#define RTW89_H2C_TRX_PROTECT_W1_DFS_EN BIT(1) + struct rtw89_h2c_fwips { __le32 w0; } __packed; @@ -4598,6 +4636,7 @@ enum rtw89_fw_ofld_h2c_func { H2C_FUNC_OFLD_TP = 0x20, H2C_FUNC_MAC_MACID_PAUSE_SLEEP = 0x28, H2C_FUNC_SCANOFLD_BE = 0x2c, + H2C_FUNC_TRX_PROTECT = 0x34, NUM_OF_RTW89_FW_OFLD_H2C_FUNC, }; @@ -4608,6 +4647,7 @@ enum rtw89_fw_ofld_h2c_func { #define RTW89_FW_OFLD_WAIT_COND_PKT_OFLD(pkt_id, pkt_op) \ RTW89_FW_OFLD_WAIT_COND(RTW89_PKT_OFLD_WAIT_TAG(pkt_id, pkt_op), \ H2C_FUNC_PACKET_OFLD) +#define RTW89_FW_OFLD_WAIT_COND_TRX_PROTECT RTW89_FW_OFLD_WAIT_COND(0, H2C_FUNC_TRX_PROTECT) #define RTW89_SCANOFLD_WAIT_COND_ADD_CH RTW89_FW_OFLD_WAIT_COND(0, H2C_FUNC_ADD_SCANOFLD_CH) @@ -5294,6 +5334,8 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev, struct rtw89_scan_option *opt, struct rtw89_vif_link *vif, bool wowlan); +int rtw89_fw_h2c_trx_protect(struct rtw89_dev *rtwdev, + enum rtw89_phy_idx phy_idx, bool enable); int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev, struct rtw89_fw_h2c_rf_reg_info *info, u16 len, u8 page); @@ -5469,6 +5511,15 @@ static inline void rtw89_fw_h2c_init_ba_cam(struct rtw89_dev *rtwdev) rtw89_fw_h2c_init_dynamic_ba_cam_v0_ext(rtwdev); } +static inline void rtw89_fw_h2c_init_trx_protect(struct rtw89_dev *rtwdev) +{ + u8 active_bands = rtw89_get_active_phy_bitmap(rtwdev); + int i; + + for (i = 0; i < RTW89_PHY_NUM; i++) + rtw89_fw_h2c_trx_protect(rtwdev, i, active_bands & BIT(i)); +} + static inline int rtw89_chip_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, struct rtw89_sta_link *rtwsta_link) diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 8472f1a63951..4d507eccaa00 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -5412,6 +5412,9 @@ rtw89_mac_c2h_done_ack(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h, u32 le cond = RTW89_SCANOFLD_BE_WAIT_COND_START; h2c_return &= RTW89_C2H_SCAN_DONE_ACK_RETURN; break; + case H2C_FUNC_TRX_PROTECT: + cond = RTW89_FW_OFLD_WAIT_COND_TRX_PROTECT; + break; } data.err = !!h2c_return; diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c index 315bb0d0759f..6b8f8bf2234d 100644 --- a/drivers/net/wireless/realtek/rtw89/mac80211.c +++ b/drivers/net/wireless/realtek/rtw89/mac80211.c @@ -528,6 +528,8 @@ static int __rtw89_ops_sta_add(struct rtw89_dev *rtwdev, if (vif->type == NL80211_IFTYPE_AP || sta->tdls) rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_REMOTE_STA_CHANGE); + rtw89_fw_h2c_init_trx_protect(rtwdev); + return 0; unset_link: @@ -1584,6 +1586,8 @@ static void __rtw89_ops_clr_vif_links(struct rtw89_dev *rtwdev, if (unlikely(!rtwvif_link)) continue; + rtw89_fw_h2c_trx_protect(rtwdev, rtwvif_link->phy_idx, false); + __rtw89_ops_remove_iface_link(rtwdev, rtwvif_link); rtw89_vif_unset_link(rtwvif, link_id); @@ -1609,6 +1613,7 @@ static int __rtw89_ops_set_vif_links(struct rtw89_dev *rtwdev, __func__, link_id); return ret; } + rtw89_fw_h2c_trx_protect(rtwdev, rtwvif_link->phy_idx, true); } return 0; diff --git a/drivers/net/wireless/realtek/rtw89/ps.c b/drivers/net/wireless/realtek/rtw89/ps.c index aad2ee7926d6..125cf14fa581 100644 --- a/drivers/net/wireless/realtek/rtw89/ps.c +++ b/drivers/net/wireless/realtek/rtw89/ps.c @@ -226,6 +226,8 @@ void rtw89_leave_lps(struct rtw89_dev *rtwdev) rtw89_for_each_rtwvif(rtwdev, rtwvif) rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) rtw89_leave_lps_vif(rtwdev, rtwvif_link); + + rtw89_fw_h2c_init_trx_protect(rtwdev); } void rtw89_enter_ips(struct rtw89_dev *rtwdev) -- 2.25.1 The RF calibration in firmware needs proper hardware version to select corresponding logic, so add the field to H2C command accordingly. Signed-off-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/fw.c | 1 + drivers/net/wireless/realtek/rtw89/fw.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index bfa5cac24d88..67154e666ba2 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -7371,6 +7371,7 @@ int rtw89_fw_h2c_rf_pre_ntfy_mcc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx ph h2c = (struct rtw89_fw_h2c_rfk_pre_info_mcc *)skb->data; h2c->aid = cpu_to_le32(hal->aid); + h2c->acv = hal->acv; done: rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index 80d260eb08cd..57e3b464c0a2 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -4881,6 +4881,8 @@ struct rtw89_fw_h2c_rfk_pre_info_mcc { struct rtw89_fw_h2c_rfk_pre_info_mcc_v1 base; u8 rsvd[2]; __le32 aid; + u8 acv; + u8 rsvd2[3]; } __packed; struct rtw89_h2c_rf_tssi { -- 2.25.1 From: Zong-Zhe Yang Some chipsets, e.g. Wi-Fi 7, will not record SER (system error recovery), which are triggered by simulations, in the HW counters. Their HW counters only record the SER happen in field. However for verification, it's still needed to check if simulations are triggered. So, add SW counters to count any causes that SER happen. But, SW can only count L1 and L2. SW does not involve L0 SER, so SW cannot count it. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/core.h | 7 +++++++ drivers/net/wireless/realtek/rtw89/debug.c | 6 ++++++ drivers/net/wireless/realtek/rtw89/ser.c | 2 ++ 3 files changed, 15 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 1ad1fd2a1f6f..5d1cec20bc80 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -5753,11 +5753,18 @@ enum rtw89_ser_rcvy_step { RTW89_NUM_OF_SER_FLAGS }; +struct rtw89_ser_count { + unsigned int l1; + unsigned int l2; +}; + struct rtw89_ser { u8 state; u8 alarm_event; bool prehandle_l1; + struct rtw89_ser_count sw_cnt; + struct work_struct ser_hdl_work; struct delayed_work ser_alarm_work; const struct state_ent *st_tbl; diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c index d46691fa09bc..4cff3d927a69 100644 --- a/drivers/net/wireless/realtek/rtw89/debug.c +++ b/drivers/net/wireless/realtek/rtw89/debug.c @@ -3780,6 +3780,7 @@ static ssize_t rtw89_debug_priv_ser_counters_get(struct rtw89_dev *rtwdev, struct rtw89_debugfs_priv *debugfs_priv, char *buf, size_t bufsz) { + const struct rtw89_ser_count *sw_cnt = &rtwdev->ser.sw_cnt; const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_dbg_ser_counters cnt = {}; char *p = buf, *end = buf + bufsz; @@ -3797,6 +3798,11 @@ static ssize_t rtw89_debug_priv_ser_counters_get(struct rtw89_dev *rtwdev, return -EOPNOTSUPP; } + p += scnprintf(p, end - p, "SER L1 SW Count: %u\n", sw_cnt->l1); + p += scnprintf(p, end - p, "SER L2 SW Count: %u\n", sw_cnt->l2); + + /* Some chipsets won't record SER simulation in HW cnt. */ + p += scnprintf(p, end - p, "---\n"); p += scnprintf(p, end - p, "SER L0 Count: %d\n", cnt.l0); p += scnprintf(p, end - p, "SER L1 Count: %d\n", cnt.l1); p += scnprintf(p, end - p, "SER L0 promote event: %d\n", cnt.l0_to_l1); diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c index 7fdc69578da3..b2c910cf9587 100644 --- a/drivers/net/wireless/realtek/rtw89/ser.c +++ b/drivers/net/wireless/realtek/rtw89/ser.c @@ -498,6 +498,7 @@ static void ser_reset_trx_st_hdl(struct rtw89_ser *ser, u8 evt) switch (evt) { case SER_EV_STATE_IN: wiphy_lock(wiphy); + ser->sw_cnt.l1++; wiphy_delayed_work_cancel(wiphy, &rtwdev->track_work); wiphy_delayed_work_cancel(wiphy, &rtwdev->track_ps_work); wiphy_unlock(wiphy); @@ -730,6 +731,7 @@ static void ser_l2_reset_st_hdl(struct rtw89_ser *ser, u8 evt) switch (evt) { case SER_EV_STATE_IN: wiphy_lock(rtwdev->hw->wiphy); + ser->sw_cnt.l2++; ser_l2_reset_st_pre_hdl(ser); wiphy_unlock(rtwdev->hw->wiphy); -- 2.25.1 From: Zong-Zhe Yang When a SER (system error recovery) interrupt happens, driver reads HALT C2H register to get the error status via MAC. For Wi-Fi 7 chipset, driver needs to reset HALT C2H register after reading it to make FW aware that. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/mac.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 4d507eccaa00..243cc02ad24e 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -814,6 +814,7 @@ static bool rtw89_mac_suppress_log(struct rtw89_dev *rtwdev, u32 err) u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; + const struct rtw89_chip_info *chip = rtwdev->chip; u32 err, err_scnr; int ret; @@ -836,11 +837,15 @@ u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev) err = MAC_AX_ERR_RXI300; if (rtw89_mac_suppress_log(rtwdev, err)) - return err; + goto bottom; rtw89_fw_st_dbg_dump(rtwdev); mac->dump_err_status(rtwdev, err); +bottom: + if (chip->chip_gen != RTW89_CHIP_AX) + rtw89_write32(rtwdev, R_AX_HALT_C2H, 0); + return err; } EXPORT_SYMBOL(rtw89_mac_get_err_status); -- 2.25.1 From: Zong-Zhe Yang If entering LPS during SER (system error recovery), IMR might fail to be re-enabled after SER. Then, the next SER would not be noticed well. After FW v0.35.100.0, Wi-Fi 7 chipsets adjust the order in which SER recovers DMAC state to prevent LPS from being in the middle of SER. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/core.h | 1 + drivers/net/wireless/realtek/rtw89/fw.c | 1 + drivers/net/wireless/realtek/rtw89/mac.c | 7 ++++++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 5d1cec20bc80..cf0cc718f41c 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -4796,6 +4796,7 @@ enum rtw89_fw_feature { RTW89_FW_FEATURE_SER_L1_BY_EVENT, RTW89_FW_FEATURE_SIM_SER_L0L1_BY_HALT_H2C, RTW89_FW_FEATURE_LPS_ML_INFO_V1, + RTW89_FW_FEATURE_SER_POST_RECOVER_DMAC, NUM_OF_RTW89_FW_FEATURES, }; diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 67154e666ba2..c035e89e75dd 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -923,6 +923,7 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = { __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), __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 97, 0, SIM_SER_L0L1_BY_HALT_H2C), + __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 100, 0, SER_POST_RECOVER_DMAC), }; static void rtw89_fw_iterate_feature_cfg(struct rtw89_fw_info *fw, diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 243cc02ad24e..923f39e39a26 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -826,7 +826,9 @@ u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev) } err = rtw89_read32(rtwdev, R_AX_HALT_C2H); - rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0); + + if (!RTW89_CHK_FW_FEATURE(SER_POST_RECOVER_DMAC, &rtwdev->fw)) + rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0); err_scnr = RTW89_ERROR_SCENARIO(err); if (err_scnr == RTW89_WCPU_CPU_EXCEPTION) @@ -846,6 +848,9 @@ u32 rtw89_mac_get_err_status(struct rtw89_dev *rtwdev) if (chip->chip_gen != RTW89_CHIP_AX) rtw89_write32(rtwdev, R_AX_HALT_C2H, 0); + if (RTW89_CHK_FW_FEATURE(SER_POST_RECOVER_DMAC, &rtwdev->fw)) + rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0); + return err; } EXPORT_SYMBOL(rtw89_mac_get_err_status); -- 2.25.1