]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: rtw89: pci: add PCI Express error handling
authorChin-Yen Lee <timlee@realtek.com>
Fri, 23 May 2025 06:27:11 +0000 (14:27 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Tue, 10 Jun 2025 01:23:06 +0000 (09:23 +0800)
Sometimes PCIe Advanced Error Reporting(AER), like bad TLP or
Data link protocol error, happens due to unstable pci signal or
no response from PCI host.

  pcieport 0000:00:1c.0: AER: Uncorrected (Non-Fatal) error message received from 0000:01:00.0
  rtw89_8852be 0000:01:00.0: PCIe Bus Error: severity=Uncorrected (Non-Fatal), type=Transaction Layer, (Requester ID)
  rtw89_8852be 0000:01:00.0:   device [10ec:b852] error status/mask=00004000/00400000
  rtw89_8852be 0000:01:00.0:    [14] CmpltTO                (First)
  rtw89_8852be 0000:01:00.0: SER catches error: 0x4000
  pcieport 0000:00:1c.0: AER: device recovery successful
  rtw89_8852be 0000:01:00.0: FW backtrace invalid key: 0xbb6c3214
  ieee80211 phy0: Hardware restart was requested

Setup callback function to call SER function to reset driver to recover
from these states.

Signed-off-by: Chin-Yen Lee <timlee@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20250523062711.27213-3-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/pci.c
drivers/net/wireless/realtek/rtw89/pci.h
drivers/net/wireless/realtek/rtw89/rtw8851be.c
drivers/net/wireless/realtek/rtw89/rtw8852ae.c
drivers/net/wireless/realtek/rtw89/rtw8852be.c
drivers/net/wireless/realtek/rtw89/rtw8852bte.c
drivers/net/wireless/realtek/rtw89/rtw8852ce.c
drivers/net/wireless/realtek/rtw89/rtw8922ae.c

index 064f6a9401073136e7c385d87c8f009147421dfb..204a3748d913541c8f1e68f0662219c4d927ce17 100644 (file)
@@ -4353,6 +4353,43 @@ static int __maybe_unused rtw89_pci_resume(struct device *dev)
 SIMPLE_DEV_PM_OPS(rtw89_pm_ops, rtw89_pci_suspend, rtw89_pci_resume);
 EXPORT_SYMBOL(rtw89_pm_ops);
 
+static pci_ers_result_t rtw89_pci_io_error_detected(struct pci_dev *pdev,
+                                                   pci_channel_state_t state)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+
+       netif_device_detach(netdev);
+
+       return PCI_ERS_RESULT_NEED_RESET;
+}
+
+static pci_ers_result_t rtw89_pci_io_slot_reset(struct pci_dev *pdev)
+{
+       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+       struct rtw89_dev *rtwdev = hw->priv;
+
+       rtw89_ser_notify(rtwdev, MAC_AX_ERR_ASSERTION);
+
+       return PCI_ERS_RESULT_RECOVERED;
+}
+
+static void rtw89_pci_io_resume(struct pci_dev *pdev)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+
+       /* ack any pending wake events, disable PME */
+       pci_enable_wake(pdev, PCI_D0, 0);
+
+       netif_device_attach(netdev);
+}
+
+const struct pci_error_handlers rtw89_pci_err_handler = {
+       .error_detected = rtw89_pci_io_error_detected,
+       .slot_reset = rtw89_pci_io_slot_reset,
+       .resume = rtw89_pci_io_resume,
+};
+EXPORT_SYMBOL(rtw89_pci_err_handler);
+
 const struct rtw89_pci_gen_def rtw89_pci_gen_ax = {
        .isr_rdu = B_AX_RDU_INT,
        .isr_halt_c2h = B_AX_HALT_C2H_INT_EN,
index 79fef5f9014080bc4869ba524e70d6cea882e8cd..52f527069da647d57a471560a8e241f37940dc31 100644 (file)
@@ -1622,6 +1622,7 @@ static inline bool rtw89_pci_ltr_is_err_reg_val(u32 val)
 
 extern const struct dev_pm_ops rtw89_pm_ops;
 extern const struct dev_pm_ops rtw89_pm_ops_be;
+extern const struct pci_error_handlers rtw89_pci_err_handler;
 extern const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set;
 extern const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set_v1;
 extern const struct rtw89_pci_ch_dma_addr_set rtw89_pci_ch_dma_addr_set_be;
index 5810af8252425c289ff8f676a0d87fbdedc8c0ec..59873083170752833f8d9f65e8261532d3fd86fe 100644 (file)
@@ -89,6 +89,7 @@ static struct pci_driver rtw89_8851be_driver = {
        .probe          = rtw89_pci_probe,
        .remove         = rtw89_pci_remove,
        .driver.pm      = &rtw89_pm_ops,
+       .err_handler    = &rtw89_pci_err_handler,
 };
 module_pci_driver(rtw89_8851be_driver);
 
index 2037713e3952e94794214581d4c3986a9c358448..90ffaf9f4f6afc2cd6d190cb24304e6ed9ebf9fe 100644 (file)
@@ -91,6 +91,7 @@ static struct pci_driver rtw89_8852ae_driver = {
        .probe          = rtw89_pci_probe,
        .remove         = rtw89_pci_remove,
        .driver.pm      = &rtw89_pm_ops,
+       .err_handler    = &rtw89_pci_err_handler,
 };
 module_pci_driver(rtw89_8852ae_driver);
 
index abdeafc14b0b9e95636439e8a187669148b9e54e..b0726f590ca2d8a0e311df39ff7c30e931e2ac17 100644 (file)
@@ -93,6 +93,7 @@ static struct pci_driver rtw89_8852be_driver = {
        .probe          = rtw89_pci_probe,
        .remove         = rtw89_pci_remove,
        .driver.pm      = &rtw89_pm_ops,
+       .err_handler    = &rtw89_pci_err_handler,
 };
 module_pci_driver(rtw89_8852be_driver);
 
index b69fa17beb33dbd9a05b3fe8c15d327a4c2b4900..a584c75b801d1452db2832d51b40f1815a9512ec 100644 (file)
@@ -95,6 +95,7 @@ static struct pci_driver rtw89_8852bte_driver = {
        .probe          = rtw89_pci_probe,
        .remove         = rtw89_pci_remove,
        .driver.pm      = &rtw89_pm_ops,
+       .err_handler    = &rtw89_pci_err_handler,
 };
 module_pci_driver(rtw89_8852bte_driver);
 
index 5d864fd5974e15163090a0da0369f1a131af8ed1..db01d3966c275a8d3b9e887a5f44b5244abaadda 100644 (file)
@@ -118,6 +118,7 @@ static struct pci_driver rtw89_8852ce_driver = {
        .probe          = rtw89_pci_probe,
        .remove         = rtw89_pci_remove,
        .driver.pm      = &rtw89_pm_ops,
+       .err_handler    = &rtw89_pci_err_handler,
 };
 module_pci_driver(rtw89_8852ce_driver);
 
index 0ea8d5281c10728337b30f2b207d5bc476c41c64..b730d79edd10ad6e3b3fb751dc9c3951056260b0 100644 (file)
@@ -106,6 +106,7 @@ static struct pci_driver rtw89_8922ae_driver = {
        .probe          = rtw89_pci_probe,
        .remove         = rtw89_pci_remove,
        .driver.pm      = &rtw89_pm_ops_be,
+       .err_handler    = &rtw89_pci_err_handler,
 };
 module_pci_driver(rtw89_8922ae_driver);