From: Zong-Zhe Yang Date: Tue, 27 Jan 2026 08:50:32 +0000 (+0800) Subject: wifi: rtw89: debug: tweak Wi-Fi 7 SER L0/L1 simulation methods X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6792fcf6a69128be0ee4aec51f08e9e960a3fc70;p=thirdparty%2Fkernel%2Flinux.git wifi: rtw89: debug: tweak Wi-Fi 7 SER L0/L1 simulation methods SER (system error recovery) L0/L1 simulation has two kinds of methods. How to choose them depends on FW features. But, Wi-Fi 7 misused them. Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20260127085036.44060-3-pkshih@realtek.com --- diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c index 56b52e780daca..d46691fa09bc6 100644 --- a/drivers/net/wireless/realtek/rtw89/debug.c +++ b/drivers/net/wireless/realtek/rtw89/debug.c @@ -3538,7 +3538,7 @@ out: return count; } -static int rtw89_dbg_trigger_l1_error_by_halt_h2c(struct rtw89_dev *rtwdev) +static int rtw89_dbg_trigger_l1_error_by_halt_h2c_ax(struct rtw89_dev *rtwdev) { if (!test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)) return -EBUSY; @@ -3546,6 +3546,31 @@ static int rtw89_dbg_trigger_l1_error_by_halt_h2c(struct rtw89_dev *rtwdev) return rtw89_mac_set_err_status(rtwdev, MAC_AX_ERR_L1_RESET_FORCE); } +static int rtw89_dbg_trigger_l1_error_by_halt_h2c_be(struct rtw89_dev *rtwdev) +{ + if (!test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)) + return -EBUSY; + + rtw89_write32_set(rtwdev, R_BE_FW_TRIGGER_IDCT_ISR, + B_BE_DMAC_FW_TRIG_IDCT | B_BE_DMAC_FW_ERR_IDCT_IMR); + + return 0; +} + +static int rtw89_dbg_trigger_l1_error_by_halt_h2c(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + switch (chip->chip_gen) { + case RTW89_CHIP_AX: + return rtw89_dbg_trigger_l1_error_by_halt_h2c_ax(rtwdev); + case RTW89_CHIP_BE: + return rtw89_dbg_trigger_l1_error_by_halt_h2c_be(rtwdev); + default: + return -EOPNOTSUPP; + } +} + static int rtw89_dbg_trigger_l1_error(struct rtw89_dev *rtwdev) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; @@ -3600,19 +3625,22 @@ static int rtw89_dbg_trigger_l0_error_ax(struct rtw89_dev *rtwdev) static int rtw89_dbg_trigger_l0_error_be(struct rtw89_dev *rtwdev) { + u8 val8; int ret; ret = rtw89_mac_check_mac_en(rtwdev, RTW89_MAC_0, RTW89_CMAC_SEL); if (ret) return ret; - rtw89_write32_set(rtwdev, R_BE_CMAC_FW_TRIGGER_IDCT_ISR, - B_BE_CMAC_FW_TRIG_IDCT | B_BE_CMAC_FW_ERR_IDCT_IMR); + val8 = rtw89_read8(rtwdev, R_BE_CMAC_FUNC_EN); + rtw89_write8(rtwdev, R_BE_CMAC_FUNC_EN, val8 & ~B_BE_TMAC_EN); + mdelay(1); + rtw89_write8(rtwdev, R_BE_CMAC_FUNC_EN, val8); return 0; } -static int rtw89_dbg_trigger_l0_error_by_halt_h2c(struct rtw89_dev *rtwdev) +static int rtw89_dbg_trigger_l0_error_by_halt_h2c_ax(struct rtw89_dev *rtwdev) { if (!test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)) return -EBUSY; @@ -3620,23 +3648,42 @@ static int rtw89_dbg_trigger_l0_error_by_halt_h2c(struct rtw89_dev *rtwdev) return rtw89_mac_set_err_status(rtwdev, MAC_AX_ERR_L0_RESET_FORCE); } -static int rtw89_dbg_trigger_l0_error(struct rtw89_dev *rtwdev) +static int rtw89_dbg_trigger_l0_error_by_halt_h2c_be(struct rtw89_dev *rtwdev) { - const struct rtw89_chip_info *chip = rtwdev->chip; + if (!test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags)) + return -EBUSY; - if (RTW89_CHK_FW_FEATURE(SIM_SER_L0L1_BY_HALT_H2C, &rtwdev->fw)) - return rtw89_dbg_trigger_l0_error_by_halt_h2c(rtwdev); + rtw89_write32_set(rtwdev, R_BE_CMAC_FW_TRIGGER_IDCT_ISR, + B_BE_CMAC_FW_TRIG_IDCT | B_BE_CMAC_FW_ERR_IDCT_IMR); - rtw89_leave_ps_mode(rtwdev); + return 0; +} + +static int rtw89_dbg_trigger_l0_error(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + int (*sim_l0_by_halt_h2c)(struct rtw89_dev *rtwdev); + int (*sim_l0)(struct rtw89_dev *rtwdev); switch (chip->chip_gen) { case RTW89_CHIP_AX: - return rtw89_dbg_trigger_l0_error_ax(rtwdev); + sim_l0_by_halt_h2c = rtw89_dbg_trigger_l0_error_by_halt_h2c_ax; + sim_l0 = rtw89_dbg_trigger_l0_error_ax; + break; case RTW89_CHIP_BE: - return rtw89_dbg_trigger_l0_error_be(rtwdev); + sim_l0_by_halt_h2c = rtw89_dbg_trigger_l0_error_by_halt_h2c_be; + sim_l0 = rtw89_dbg_trigger_l0_error_be; + break; default: return -EOPNOTSUPP; } + + if (RTW89_CHK_FW_FEATURE(SIM_SER_L0L1_BY_HALT_H2C, &rtwdev->fw)) + return sim_l0_by_halt_h2c(rtwdev); + + rtw89_leave_ps_mode(rtwdev); + + return sim_l0(rtwdev); } static ssize_t diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index 3239f358aafcd..9b2e97ed5c7d6 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -4960,6 +4960,10 @@ #define R_BE_SER_L1_DBG_CNT_7 0x845C #define B_BE_SER_L1_DBG_2_MASK GENMASK(31, 0) +#define R_BE_FW_TRIGGER_IDCT_ISR 0x8508 +#define B_BE_DMAC_FW_ERR_IDCT_IMR BIT(31) +#define B_BE_DMAC_FW_TRIG_IDCT BIT(0) + #define R_BE_DMAC_ERR_IMR 0x8520 #define B_BE_DMAC_NOTX_ERR_INT_EN BIT(21) #define B_BE_DMAC_NORX_ERR_INT_EN BIT(20)