]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: rtw88: pci: add PCI Express error handling
authorChin-Yen Lee <timlee@realtek.com>
Fri, 23 May 2025 06:27:10 +0000 (14:27 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Tue, 10 Jun 2025 01:22:44 +0000 (09:22 +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:00.0: AER: Multiple Corrected error message received from 0000:00:00.0
  pcieport 0000:00:00.0: AER: PCIe Bus Error: severity=Corrected, type=Physical Layer, (Receiver ID)
  pcieport 0000:00:00.0: AER:   device [14c3:6786] error status/mask=000000c1/00006000
  pcieport 0000:00:00.0: AER:    [ 0] RxErr                  (First)
  pcieport 0000:00:00.0: AER:    [ 6] BadTLP
  pcieport 0000:00:00.0: AER:    [ 7] BadDLLP
  pcieport 0000:00:00.0: AER: Corrected error message received from 0000:00:00.0
  pcieport 0000:00:00.0: AER: found no error details for 0000:00:00.0
  pcieport 0000:00:00.0: AER: Multiple Corrected error message received from 0000:00:00.0
  pcieport 0000:00:00.0: AER: found no error details for 0000:00:00.0
  pcieport 0000:00:00.0: AER: Multiple Corrected error message received from 0000:00:00.0
  pcieport 0000:00:00.0: AER: found no error details for 0000:00:00.0

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-2-pkshih@realtek.com
drivers/net/wireless/realtek/rtw88/main.c
drivers/net/wireless/realtek/rtw88/pci.c
drivers/net/wireless/realtek/rtw88/pci.h
drivers/net/wireless/realtek/rtw88/rtw8723de.c
drivers/net/wireless/realtek/rtw88/rtw8821ce.c
drivers/net/wireless/realtek/rtw88/rtw8822be.c
drivers/net/wireless/realtek/rtw88/rtw8822ce.c

index c4de5d114eda1db785e0999d952510806da21604..26b1479d3521319b7b8542c632d6de1674129b90 100644 (file)
@@ -636,6 +636,7 @@ void rtw_fw_recovery(struct rtw_dev *rtwdev)
        if (!test_bit(RTW_FLAG_RESTARTING, rtwdev->flags))
                ieee80211_queue_work(rtwdev->hw, &rtwdev->fw_recovery_work);
 }
+EXPORT_SYMBOL(rtw_fw_recovery);
 
 static void __fw_recovery_work(struct rtw_dev *rtwdev)
 {
index 7f2b6dc21f566b6796625aa3e393be40300edd94..6655de2b9726ec72f237dac02e4289de11da53e6 100644 (file)
@@ -1707,6 +1707,43 @@ static void rtw_pci_napi_deinit(struct rtw_dev *rtwdev)
        free_netdev(rtwpci->netdev);
 }
 
+static pci_ers_result_t rtw_pci_io_err_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 rtw_pci_io_slot_reset(struct pci_dev *pdev)
+{
+       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+       struct rtw_dev *rtwdev = hw->priv;
+
+       rtw_fw_recovery(rtwdev);
+
+       return PCI_ERS_RESULT_RECOVERED;
+}
+
+static void rtw_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 rtw_pci_err_handler = {
+       .error_detected = rtw_pci_io_err_detected,
+       .slot_reset = rtw_pci_io_slot_reset,
+       .resume = rtw_pci_io_resume,
+};
+EXPORT_SYMBOL(rtw_pci_err_handler);
+
 int rtw_pci_probe(struct pci_dev *pdev,
                  const struct pci_device_id *id)
 {
index 13988db1cb4c4e3a3d9080223c3fd286312cae3c..8ffdea11378f0189b3f85d0254c954e049d4b360 100644 (file)
@@ -231,6 +231,7 @@ struct rtw_pci {
 };
 
 extern const struct dev_pm_ops rtw_pm_ops;
+extern const struct pci_error_handlers rtw_pci_err_handler;
 
 int rtw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id);
 void rtw_pci_remove(struct pci_dev *pdev);
index 87c8bc9d18a97c1bca417dddaf9b63fb26bfa3a5..c6d0c88e5d81ea966b57df40f20a997f0211a336 100644 (file)
@@ -23,6 +23,7 @@ static struct pci_driver rtw_8723de_driver = {
        .remove = rtw_pci_remove,
        .driver.pm = &rtw_pm_ops,
        .shutdown = rtw_pci_shutdown,
+       .err_handler  = &rtw_pci_err_handler,
 };
 module_pci_driver(rtw_8723de_driver);
 
index 40637c079d9962212d5ba10c51eeb453528545bd..52a19cb17daa91b4d037440351da0cea142f5cc0 100644 (file)
@@ -27,6 +27,7 @@ static struct pci_driver rtw_8821ce_driver = {
        .remove = rtw_pci_remove,
        .driver.pm = &rtw_pm_ops,
        .shutdown = rtw_pci_shutdown,
+       .err_handler  = &rtw_pci_err_handler,
 };
 module_pci_driver(rtw_8821ce_driver);
 
index 0bb9f70e79209bfcc139d2fd414a218267772806..dda597d73219554591f531dfbc9156c2e0881d45 100644 (file)
@@ -23,6 +23,7 @@ static struct pci_driver rtw_8822be_driver = {
        .remove = rtw_pci_remove,
        .driver.pm = &rtw_pm_ops,
        .shutdown = rtw_pci_shutdown,
+       .err_handler  = &rtw_pci_err_handler,
 };
 module_pci_driver(rtw_8822be_driver);
 
index 9def732480af273c1ca598c4d2bbcbb822d4ebd2..7ae95415c224dfd9d4bec7222f030f1e11bf34e5 100644 (file)
@@ -27,6 +27,7 @@ static struct pci_driver rtw_8822ce_driver = {
        .remove = rtw_pci_remove,
        .driver.pm = &rtw_pm_ops,
        .shutdown = rtw_pci_shutdown,
+       .err_handler  = &rtw_pci_err_handler,
 };
 module_pci_driver(rtw_8822ce_driver);