]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: rtw89: pci: enable LTR based on pcie control register
authorDian-Syuan Yang <dian_syuan0116@realtek.com>
Fri, 15 May 2026 01:44:24 +0000 (09:44 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Mon, 25 May 2026 05:55:58 +0000 (13:55 +0800)
Originally, driver always transmits LTR (Latency Tolerance Reporting) to
pcie host, but it may cause pcie link down on some platforms because
LTR is not supported. As a result, driver will check the control
register of LTR setting to decide whether to enable LTR feature.

This applies to Wi-Fi 6 chips only. For Wi-Fi 7 chips, although the
driver still issues LTR, the hardware has its own internal logic
to determine whether to actually transmit it to pcie host.

Signed-off-by: Dian-Syuan Yang <dian_syuan0116@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260515014433.16168-5-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/pci.c

index 64554eb35a72cff22b6405775ce50aeb0bee34c5..f7107dc05b71aec184cc36d9124d786c61303c1d 100644 (file)
@@ -3039,6 +3039,17 @@ static int rtw89_pci_mode_op(struct rtw89_dev *rtwdev)
        return 0;
 }
 
+static bool rtw89_pci_dev_ltr_enabled(struct rtw89_dev *rtwdev)
+{
+       struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
+       struct pci_dev *pdev = rtwpci->pdev;
+       u16 cap;
+
+       pcie_capability_read_word(pdev, PCI_EXP_DEVCTL2, &cap);
+
+       return !!(cap & PCI_EXP_DEVCTL2_LTR_EN);
+}
+
 static int rtw89_pci_ops_deinit(struct rtw89_dev *rtwdev)
 {
        const struct rtw89_pci_info *info = rtwdev->pci_info;
@@ -3143,7 +3154,7 @@ int rtw89_pci_ltr_set(struct rtw89_dev *rtwdev, bool en)
 {
        u32 val;
 
-       if (!en)
+       if (!en || !rtw89_pci_dev_ltr_enabled(rtwdev))
                return 0;
 
        val = rtw89_read32(rtwdev, R_AX_LTR_CTRL_0);
@@ -3179,6 +3190,9 @@ int rtw89_pci_ltr_set_v1(struct rtw89_dev *rtwdev, bool en)
        u32 dec_ctrl;
        u32 val32;
 
+       if (!rtw89_pci_dev_ltr_enabled(rtwdev))
+               return 0;
+
        val32 = rtw89_read32(rtwdev, R_AX_LTR_CTRL_0);
        if (rtw89_pci_ltr_is_err_reg_val(val32))
                return -EINVAL;