]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: rtw89: mac: separate functions of CMAC power and function enable
authorPing-Ke Shih <pkshih@realtek.com>
Thu, 8 Jan 2026 12:03:18 +0000 (20:03 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Tue, 13 Jan 2026 02:31:58 +0000 (10:31 +0800)
To enable/disable CMAC function somewhere, separate controls of CMAC power
and function into individual functions. Also correct the hardware settings
by the way.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260108120320.2217402-12-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/core.h
drivers/net/wireless/realtek/rtw89/mac.c
drivers/net/wireless/realtek/rtw89/mac_be.c
drivers/net/wireless/realtek/rtw89/reg.h

index c008931ccb0591b02f3ec2eb2bd3b37cc7c1cf45..8d5655138ded82ce069705b55a60276d5e70e988 100644 (file)
@@ -5160,6 +5160,8 @@ enum rtw89_flags {
        RTW89_FLAG_DMAC_FUNC,
        RTW89_FLAG_CMAC0_FUNC,
        RTW89_FLAG_CMAC1_FUNC,
+       RTW89_FLAG_CMAC0_PWR,
+       RTW89_FLAG_CMAC1_PWR,
        RTW89_FLAG_FW_RDY,
        RTW89_FLAG_RUNNING,
        RTW89_FLAG_PROBE_DONE,
index 5bf81ef0313bb0da078b3f189b5d6291efcadbf3..f142d3f80e957c274f2f57547bbc17e9b66ce93e 100644 (file)
@@ -1559,6 +1559,8 @@ static int rtw89_mac_power_switch(struct rtw89_dev *rtwdev, bool on)
                clear_bit(RTW89_FLAG_DMAC_FUNC, rtwdev->flags);
                clear_bit(RTW89_FLAG_CMAC0_FUNC, rtwdev->flags);
                clear_bit(RTW89_FLAG_CMAC1_FUNC, rtwdev->flags);
+               clear_bit(RTW89_FLAG_CMAC0_PWR, rtwdev->flags);
+               clear_bit(RTW89_FLAG_CMAC1_PWR, rtwdev->flags);
                clear_bit(RTW89_FLAG_FW_RDY, rtwdev->flags);
 
                rtw89_mac_update_scoreboard(rtwdev, MAC_AX_NOTIFY_PWR_MAJOR);
index a0e5c99abb17e062efc44c47cf8d6f9f1d38f674..ef4de64d8661b7db64c0320c77d7cb362ef01cc0 100644 (file)
@@ -754,28 +754,91 @@ static int dmac_func_en_be(struct rtw89_dev *rtwdev)
        return 0;
 }
 
+static int cmac_pwr_en_be(struct rtw89_dev *rtwdev, u8 mac_idx, bool en)
+{
+       if (mac_idx > RTW89_MAC_1)
+               return -EINVAL;
+
+       if (mac_idx == RTW89_MAC_0) {
+               if (en == test_bit(RTW89_FLAG_CMAC0_PWR, rtwdev->flags))
+                       return 0;
+
+               if (en) {
+                       rtw89_write32_set(rtwdev, R_BE_AFE_CTRL1,
+                                         B_BE_R_SYM_WLCMAC0_ALL_EN);
+                       rtw89_write32_clr(rtwdev, R_BE_FEN_RST_ENABLE,
+                                         B_BE_R_SYM_ISO_CMAC02PP);
+                       rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE,
+                                         B_BE_CMAC0_FEN);
+
+                       set_bit(RTW89_FLAG_CMAC0_PWR, rtwdev->flags);
+               } else {
+                       rtw89_write32_clr(rtwdev, R_BE_FEN_RST_ENABLE,
+                                         B_BE_CMAC0_FEN);
+                       rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE,
+                                         B_BE_R_SYM_ISO_CMAC02PP);
+                       rtw89_write32_clr(rtwdev, R_BE_AFE_CTRL1,
+                                         B_BE_R_SYM_WLCMAC0_ALL_EN);
+
+                       clear_bit(RTW89_FLAG_CMAC0_PWR, rtwdev->flags);
+               }
+       } else {
+               if (en == test_bit(RTW89_FLAG_CMAC1_PWR, rtwdev->flags))
+                       return 0;
+
+               if (en) {
+                       rtw89_write32_set(rtwdev, R_BE_AFE_CTRL1,
+                                         B_BE_R_SYM_WLCMAC1_ALL_EN);
+                       rtw89_write32_clr(rtwdev, R_BE_FEN_RST_ENABLE,
+                                         B_BE_R_SYM_ISO_CMAC12PP);
+                       rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE,
+                                         B_BE_CMAC1_FEN);
+
+                       set_bit(RTW89_FLAG_CMAC1_PWR, rtwdev->flags);
+               } else {
+                       rtw89_write32_clr(rtwdev, R_BE_FEN_RST_ENABLE,
+                                         B_BE_CMAC1_FEN);
+                       rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE,
+                                         B_BE_R_SYM_ISO_CMAC12PP);
+                       rtw89_write32_clr(rtwdev, R_BE_AFE_CTRL1,
+                                         B_BE_R_SYM_WLCMAC1_ALL_EN);
+
+                       clear_bit(RTW89_FLAG_CMAC1_PWR, rtwdev->flags);
+               }
+       }
+
+       return 0;
+}
+
 static int cmac_func_en_be(struct rtw89_dev *rtwdev, u8 mac_idx, bool en)
 {
+       enum rtw89_flags pwr_flag, func_flag;
        u32 reg;
 
        if (mac_idx > RTW89_MAC_1)
                return -EINVAL;
 
-       if (mac_idx == RTW89_MAC_0)
+       if (mac_idx == RTW89_MAC_0) {
+               pwr_flag = RTW89_FLAG_CMAC0_PWR;
+               func_flag = RTW89_FLAG_CMAC0_FUNC;
+       } else {
+               pwr_flag = RTW89_FLAG_CMAC1_PWR;
+               func_flag = RTW89_FLAG_CMAC1_FUNC;
+       }
+
+       if (!test_bit(pwr_flag, rtwdev->flags)) {
+               rtw89_warn(rtwdev, "CMAC %u power cut did not release\n", mac_idx);
                return 0;
+       }
 
        if (en) {
-               rtw89_write32_set(rtwdev, R_BE_AFE_CTRL1, B_BE_AFE_CTRL1_SET);
-               rtw89_write32_clr(rtwdev, R_BE_SYS_ISO_CTRL_EXTEND, B_BE_R_SYM_ISO_CMAC12PP);
-               rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_CMAC1_FEN);
-
                reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CK_EN, mac_idx);
                rtw89_write32_set(rtwdev, reg, B_BE_CK_EN_SET);
 
                reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CMAC_FUNC_EN, mac_idx);
                rtw89_write32_set(rtwdev, reg, B_BE_CMAC_FUNC_EN_SET);
 
-               set_bit(RTW89_FLAG_CMAC1_FUNC, rtwdev->flags);
+               set_bit(func_flag, rtwdev->flags);
        } else {
                reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CMAC_FUNC_EN, mac_idx);
                rtw89_write32_clr(rtwdev, reg, B_BE_CMAC_FUNC_EN_SET);
@@ -783,11 +846,7 @@ static int cmac_func_en_be(struct rtw89_dev *rtwdev, u8 mac_idx, bool en)
                reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CK_EN, mac_idx);
                rtw89_write32_clr(rtwdev, reg, B_BE_CK_EN_SET);
 
-               rtw89_write32_clr(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_CMAC1_FEN);
-               rtw89_write32_set(rtwdev, R_BE_SYS_ISO_CTRL_EXTEND, B_BE_R_SYM_ISO_CMAC12PP);
-               rtw89_write32_clr(rtwdev, R_BE_AFE_CTRL1, B_BE_AFE_CTRL1_SET);
-
-               clear_bit(RTW89_FLAG_CMAC1_FUNC, rtwdev->flags);
+               clear_bit(func_flag, rtwdev->flags);
        }
 
        return 0;
@@ -806,6 +865,10 @@ static int sys_init_be(struct rtw89_dev *rtwdev)
        if (ret)
                return ret;
 
+       ret = cmac_pwr_en_be(rtwdev, RTW89_MAC_0, true);
+       if (ret)
+               return ret;
+
        ret = cmac_func_en_be(rtwdev, RTW89_MAC_0, true);
        if (ret)
                return ret;
@@ -1814,6 +1877,12 @@ static int band1_enable_be(struct rtw89_dev *rtwdev)
                return ret;
        }
 
+       ret = cmac_pwr_en_be(rtwdev, RTW89_MAC_1, true);
+       if (ret) {
+               rtw89_err(rtwdev, "[ERR]CMAC%d pwr en %d\n", RTW89_MAC_1, ret);
+               return ret;
+       }
+
        ret = cmac_func_en_be(rtwdev, RTW89_MAC_1, true);
        if (ret) {
                rtw89_err(rtwdev, "[ERR]CMAC%d func en %d\n", RTW89_MAC_1, ret);
@@ -1857,6 +1926,12 @@ static int band1_disable_be(struct rtw89_dev *rtwdev)
                return ret;
        }
 
+       ret = cmac_pwr_en_be(rtwdev, RTW89_MAC_1, false);
+       if (ret) {
+               rtw89_err(rtwdev, "[ERR]CMAC%d pwr dis %d\n", RTW89_MAC_1, ret);
+               return ret;
+       }
+
        ret = rtw89_mac_dle_quota_change(rtwdev, rtwdev->mac.qta_mode, false);
        if (ret) {
                rtw89_err(rtwdev, "[ERR]DLE quota change %d\n", ret);
index bfb1ebcc9fc20affcb38bd9ca3ee34472652f845..8233841bb8ffd7b3da583e0de3151d4330808e10 100644 (file)
 #define B_BE_R_SYM_WLCMAC0_P2_PC_EN BIT(26)
 #define B_BE_R_SYM_WLCMAC0_P1_PC_EN BIT(25)
 #define B_BE_R_SYM_WLCMAC0_PC_EN BIT(24)
+#define B_BE_R_SYM_WLCMAC0_ALL_EN (B_BE_R_SYM_WLCMAC0_PC_EN | \
+                                  B_BE_R_SYM_WLCMAC0_P1_PC_EN | \
+                                  B_BE_R_SYM_WLCMAC0_P2_PC_EN | \
+                                  B_BE_R_SYM_WLCMAC0_P3_PC_EN | \
+                                  B_BE_R_SYM_WLCMAC0_P4_PC_EN)
 #define B_BE_DATAMEM_PC3_EN BIT(23)
 #define B_BE_DATAMEM_PC2_EN BIT(22)
 #define B_BE_DATAMEM_PC1_EN BIT(21)
 #define B_BE_R_SYM_WLCMAC1_P2_PC_EN BIT(2)
 #define B_BE_R_SYM_WLCMAC1_P1_PC_EN BIT(1)
 #define B_BE_R_SYM_WLCMAC1_PC_EN BIT(0)
-#define B_BE_AFE_CTRL1_SET (B_BE_R_SYM_WLCMAC1_PC_EN | \
-                           B_BE_R_SYM_WLCMAC1_P1_PC_EN | \
-                           B_BE_R_SYM_WLCMAC1_P2_PC_EN | \
-                           B_BE_R_SYM_WLCMAC1_P3_PC_EN | \
-                           B_BE_R_SYM_WLCMAC1_P4_PC_EN)
+#define B_BE_R_SYM_WLCMAC1_ALL_EN (B_BE_R_SYM_WLCMAC1_PC_EN | \
+                                  B_BE_R_SYM_WLCMAC1_P1_PC_EN | \
+                                  B_BE_R_SYM_WLCMAC1_P2_PC_EN | \
+                                  B_BE_R_SYM_WLCMAC1_P3_PC_EN | \
+                                  B_BE_R_SYM_WLCMAC1_P4_PC_EN)
 
 #define R_BE_EFUSE_CTRL 0x0030
 #define B_BE_EF_MODE_SEL_MASK GENMASK(31, 30)