]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: rtw89: warn unexpected polling value of XTAL SI
authorPing-Ke Shih <pkshih@realtek.com>
Tue, 23 Dec 2025 03:06:49 +0000 (11:06 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Fri, 26 Dec 2025 03:02:57 +0000 (11:02 +0800)
XTAL SI is an indirect serial interface to access registers in another
hardware domain. When BT driver initializes UART interface, firmware might
rarely control XTAL SI at the same time causing access racing.

Current is to adjust initialization flow to avoid the racing. To make
the racing visible if it still presents, add a message to address this.

USB adapters might be unplugged suddenly, causing flooding messages. Check
RTW89_FLAG_UNPLUGGED flag to avoid them.

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

index 637fbf15a85090be72f6b02cc0fff62a89c0c71b..7cbe3ffd5dc86f7728b37546521ebbb5745725be 100644 (file)
@@ -1483,6 +1483,15 @@ static void rtw89_mac_power_switch_boot_mode(struct rtw89_dev *rtwdev)
        rtw89_write32_clr(rtwdev, R_AX_RSV_CTRL, B_AX_R_DIS_PRST);
 }
 
+static int rtw89_mac_pwr_off_func_for_unplugged(struct rtw89_dev *rtwdev)
+{
+       /*
+        * Avoid accessing IO for unplugged power-off to prevent warnings,
+        * especially XTAL SI.
+        */
+       return 0;
+}
+
 static int rtw89_mac_power_switch(struct rtw89_dev *rtwdev, bool on)
 {
        const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
@@ -1497,8 +1506,13 @@ static int rtw89_mac_power_switch(struct rtw89_dev *rtwdev, bool on)
                cfg_seq = chip->pwr_on_seq;
                cfg_func = chip->ops->pwr_on_func;
        } else {
-               cfg_seq = chip->pwr_off_seq;
-               cfg_func = chip->ops->pwr_off_func;
+               if (test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags)) {
+                       cfg_seq = NULL;
+                       cfg_func = rtw89_mac_pwr_off_func_for_unplugged;
+               } else {
+                       cfg_seq = chip->pwr_off_seq;
+                       cfg_func = chip->ops->pwr_off_func;
+               }
        }
 
        if (test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags))
@@ -6969,6 +6983,12 @@ int rtw89_mac_write_xtal_si_ax(struct rtw89_dev *rtwdev, u8 offset, u8 val, u8 m
                return ret;
        }
 
+       if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags) &&
+           (u32_get_bits(val32, B_AX_WL_XTAL_SI_ADDR_MASK) != offset ||
+            u32_get_bits(val32, B_AX_WL_XTAL_SI_DATA_MASK) != val))
+               rtw89_warn(rtwdev, "xtal si write: offset=%x val=%x poll=%x\n",
+                          offset, val, val32);
+
        return 0;
 }
 
@@ -6992,7 +7012,12 @@ int rtw89_mac_read_xtal_si_ax(struct rtw89_dev *rtwdev, u8 offset, u8 *val)
                return ret;
        }
 
-       *val = rtw89_read8(rtwdev, R_AX_WLAN_XTAL_SI_CTRL + 1);
+       if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags) &&
+           u32_get_bits(val32, B_AX_WL_XTAL_SI_ADDR_MASK) != offset)
+               rtw89_warn(rtwdev, "xtal si read: offset=%x poll=%x\n",
+                          offset, val32);
+
+       *val = u32_get_bits(val32, B_AX_WL_XTAL_SI_DATA_MASK);
 
        return 0;
 }
index 2bc329c134433bf1cecf57cb5f1999b472b1832d..c0204e68c17232dd200fbe54ba20dc0b005e59fe 100644 (file)
@@ -396,6 +396,12 @@ int rtw89_mac_write_xtal_si_be(struct rtw89_dev *rtwdev, u8 offset, u8 val, u8 m
                return ret;
        }
 
+       if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags) &&
+           (u32_get_bits(val32, B_BE_WL_XTAL_SI_ADDR_MASK) != offset ||
+            u32_get_bits(val32, B_BE_WL_XTAL_SI_DATA_MASK) != val))
+               rtw89_warn(rtwdev, "xtal si write: offset=%x val=%x poll=%x\n",
+                          offset, val, val32);
+
        return 0;
 }
 
@@ -420,7 +426,12 @@ int rtw89_mac_read_xtal_si_be(struct rtw89_dev *rtwdev, u8 offset, u8 *val)
                return ret;
        }
 
-       *val = rtw89_read8(rtwdev, R_BE_WLAN_XTAL_SI_CTRL + 1);
+       if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags) &&
+           u32_get_bits(val32, B_BE_WL_XTAL_SI_ADDR_MASK) != offset)
+               rtw89_warn(rtwdev, "xtal si read: offset=%x poll=%x\n",
+                          offset, val32);
+
+       *val = u32_get_bits(val32, B_BE_WL_XTAL_SI_DATA_MASK);
 
        return 0;
 }