]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: rtw89: pci: clear SER ISR when initial and leaving WoWLAN for WiFi 7 chips
authorPing-Ke Shih <pkshih@realtek.com>
Wed, 25 Mar 2026 07:21:25 +0000 (15:21 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Mon, 30 Mar 2026 02:26:15 +0000 (10:26 +0800)
The PCIE SER is to diagnose PCIE becomes abnormal, relying on IMR settings
to trigger interrupt when status is weird. Update settings to disable
PHY error flag 9, and clear ISR when initial and leaving WoWLAN.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260325072130.41751-4-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/pci.h
drivers/net/wireless/realtek/rtw89/pci_be.c

index dc488d9a8884f73819806c878ded42d6ad0ea64f..c7cd34e99349527ce82edd73d7c2fcdcefaec4eb 100644 (file)
@@ -55,6 +55,8 @@
 #define B_AX_CALIB_EN                  BIT(13)
 #define B_AX_DIV                       GENMASK(15, 14)
 #define RAC_SET_PPR_V1                 0x31
+#define RAC_ANA40                      0x40
+#define PHY_ERR_IMR_DIS                        (BIT(9) | BIT(0))
 #define RAC_ANA41                      0x41
 #define PHY_ERR_FLAG_EN                        BIT(6)
 
 #define B_BE_SER_PMU_IMR BIT(0)
 
 #define R_BE_REG_PL1_ISR 0x34B4
+#define B_PCIE_SER_ALL_ISR 0x7F
 
 #define R_BE_RX_APPEND_MODE 0x8920
 #define B_BE_APPEND_OFFSET_MASK GENMASK(23, 16)
index dea01d9e57fd3c09c5a8cafb7d73fae8bed58788..dfffec1ff3c78ea6ec44b8c6aba882b0e0860d5b 100644 (file)
@@ -351,14 +351,41 @@ static void rtw89_pci_ser_setting_be(struct rtw89_dev *rtwdev)
                return;
 
        rtw89_write32(rtwdev, R_BE_PL1_DBG_INFO, 0x0);
-       rtw89_write32_set(rtwdev, R_BE_FWS1IMR, B_BE_PCIE_SER_TIMEOUT_INDIC_EN);
-       rtw89_write32_set(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_SER_PL1_EN);
-       rtw89_write32_mask(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_TIMER_UNIT_MASK, 1);
 
-       val32 = rtw89_read32(rtwdev, R_BE_REG_PL1_MASK);
-       val32 |= B_BE_SER_PMU_IMR | B_BE_SER_L1SUB_IMR | B_BE_SER_PM_MASTER_IMR |
-                B_BE_SER_LTSSM_IMR | B_BE_SER_PM_CLK_MASK | B_BE_SER_PCLKREQ_ACK_MASK;
-       rtw89_write32(rtwdev, R_BE_REG_PL1_MASK, val32);
+       switch (hal->cv) {
+       case CHIP_CAV:
+       case CHIP_CBV:
+               rtw89_write32_clr(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_SER_PL1_EN);
+               rtw89_write32_mask(rtwdev, R_BE_SER_PL1_CTRL,
+                                  B_BE_PL1_TIMER_UNIT_MASK, PCIE_SER_TIMER_UNIT);
+
+               val32 = rtw89_read32(rtwdev, R_BE_REG_PL1_MASK);
+               val32 &= ~(B_BE_SER_PMU_IMR | B_BE_SER_L1SUB_IMR |
+                          B_BE_SER_PM_MASTER_IMR | B_BE_SER_LTSSM_IMR |
+                          B_BE_SER_PM_CLK_MASK | B_BE_SER_PCLKREQ_ACK_MASK);
+               rtw89_write32(rtwdev, R_BE_REG_PL1_MASK, val32);
+               break;
+       case CHIP_CCV:
+       default:
+               rtw89_write32_clr(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_SER_PL1_EN);
+
+               ret = read_poll_timeout_atomic(rtw89_read32, val32, !val32,
+                                              1, 1000, false, rtwdev, R_BE_REG_PL1_ISR);
+               if (ret)
+                       rtw89_warn(rtwdev, "[ERR] PCIE SER clear poll fail\n");
+
+               rtw89_write32_mask(rtwdev, R_BE_SER_PL1_CTRL,
+                                  B_BE_PL1_TIMER_UNIT_MASK, PCIE_SER_TIMER_UNIT);
+               rtw89_write32_set(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_SER_PL1_EN);
+
+               val32 = rtw89_read32(rtwdev, R_BE_REG_PL1_MASK);
+               val32 |= (B_BE_SER_PMU_IMR | B_BE_SER_PM_MASTER_IMR |
+                         B_BE_SER_LTSSM_IMR | B_BE_SER_PM_CLK_MASK |
+                         B_BE_SER_PCLKREQ_ACK_MASK);
+               val32 &= ~B_BE_SER_L1SUB_IMR;
+               rtw89_write32(rtwdev, R_BE_REG_PL1_MASK, val32);
+               break;
+       }
 
        return;
 
@@ -366,6 +393,11 @@ be2_chips:
        rtw89_write32_clr(rtwdev, R_BE_PCIE_SER_DBG, B_BE_PCIE_SER_FLUSH_RSTB);
        rtw89_write32_set(rtwdev, R_BE_PCIE_SER_DBG, B_BE_PCIE_SER_FLUSH_RSTB);
 
+       rtw89_write16_clr(rtwdev, RAC_DIRECT_OFFESET_L0_G1 +
+                                 RAC_ANA40 * RAC_MULT, PHY_ERR_IMR_DIS);
+       rtw89_write16_clr(rtwdev, RAC_DIRECT_OFFESET_L0_G2 +
+                                 RAC_ANA40 * RAC_MULT, PHY_ERR_IMR_DIS);
+
        rtw89_write16_clr(rtwdev, RAC_DIRECT_OFFESET_L0_G1 +
                                  RAC_ANA41 * RAC_MULT, PHY_ERR_FLAG_EN);
        rtw89_write16_clr(rtwdev, RAC_DIRECT_OFFESET_L0_G2 +
@@ -378,6 +410,7 @@ be2_chips:
        val32 = rtw89_read32(rtwdev, R_BE_SER_PL1_CTRL);
        val32 &= ~B_BE_PL1_SER_PL1_EN;
        rtw89_write32(rtwdev, R_BE_SER_PL1_CTRL, val32);
+       rtw89_write32(rtwdev, R_BE_REG_PL1_ISR, B_PCIE_SER_ALL_ISR);
 
        ret = read_poll_timeout_atomic(rtw89_read32, val32, !val32,
                                       1, 1000, false, rtwdev, R_BE_REG_PL1_ISR);
@@ -385,9 +418,10 @@ be2_chips:
                rtw89_warn(rtwdev, "[ERR] PCIE SER clear poll fail\n");
 
        val32 = rtw89_read32(rtwdev, R_BE_REG_PL1_MASK);
-       val32 |= B_BE_SER_PMU_IMR | B_BE_SER_L1SUB_IMR | B_BE_SER_PM_MASTER_IMR |
+       val32 |= B_BE_SER_PMU_IMR | B_BE_SER_PM_MASTER_IMR |
                 B_BE_SER_LTSSM_IMR | B_BE_SER_PM_CLK_MASK | B_BE_SER_PCLKREQ_ACK_MASK |
                 B_BE_SER_LTSSM_UNSTABLE_MASK;
+       val32 &= ~B_BE_SER_L1SUB_IMR;
        rtw89_write32(rtwdev, R_BE_REG_PL1_MASK, val32);
 
        rtw89_write32_mask(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_TIMER_UNIT_MASK,
@@ -761,6 +795,8 @@ static int __maybe_unused rtw89_pci_resume_be(struct device *dev)
                goto clear_phy_isr;
 
        rtw89_write32_clr(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_SER_PL1_EN);
+       if (rtwdev->chip->chip_id == RTL8922D)
+               rtw89_write32(rtwdev, R_BE_REG_PL1_ISR, B_PCIE_SER_ALL_ISR);
 
        ret = read_poll_timeout_atomic(rtw89_read32, polling, !polling, 1, 1000,
                                       false, rtwdev, R_BE_REG_PL1_ISR);