From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtpbg151.qq.com (smtpbg151.qq.com [18.169.211.239]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1142A37CD2C for ; Tue, 3 Mar 2026 03:04:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=18.169.211.239 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772507101; cv=none; b=H3c9fJdzahAPwQdThjp25SHGmJkuGZp9TKyKebe8y3aO7+zk1UiF8ZSbOsd5AXBUJMjeeYOjl0ShVeKVe65IFVeqGP5enOJWUNDsJhBSRT9lfci01IoP4tnM1WirVA/hXrFxYmh5iHpbUvJbgkR7Vynk4Mt0GNe5rSnpXu5s8VA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772507101; c=relaxed/simple; bh=RWkOU4XdLdTJ5pLHoCQYiR7O7fwS7XVhQxZA7Yn7hag=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=iYGBw9ThPjc9c6YoV4k2Kv/MTWckfVUe5bnWL2l+89amr9690EBpLN91NqUq0DceYoHDjQqqxXguPbvXvTYznQ9FGsemPmTOgesuc9+n+pdhzgvkMSFsglaipA4tFBW5kHM+CQEyHOrcH+MlkHGOu1KzGamdregPHvGvwATdQUg= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=trustnetic.com; spf=pass smtp.mailfrom=trustnetic.com; arc=none smtp.client-ip=18.169.211.239 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=trustnetic.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=trustnetic.com X-QQ-mid: esmtpsz19t1772507052t49a06210 X-QQ-Originating-IP: LJ05SJqAAEeg5JIKcOaR9zWBOhlsuZMJhz4oUNvGF9w= Received: from lap-jiawenwu.trustnetic.com ( [125.120.70.252]) by bizesmtp.qq.com (ESMTP) with id ; Tue, 03 Mar 2026 11:04:10 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 2608189590102710063 EX-QQ-RecipientCnt: 18 From: Jiawen Wu To: netdev@vger.kernel.org Cc: Mengyuan Lou , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Richard Cochran , Russell King , Simon Horman , Jacob Keller , Kees Cook , Michal Kubiak , Joe Damato , Larysa Zaremba , Abdun Nihaal , Breno Leitao , Jiawen Wu Subject: [PATCH net-next v3 9/9] net: wangxun: implement pci_error_handlers ops Date: Tue, 3 Mar 2026 11:03:31 +0800 Message-Id: <20260303030331.24076-10-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.21.0.windows.1 In-Reply-To: <20260303030331.24076-1-jiawenwu@trustnetic.com> References: <20260303030331.24076-1-jiawenwu@trustnetic.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-QQ-SENDSIZE: 520 Feedback-ID: esmtpsz:trustnetic.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: M6I+dON63j22W+vUurmqvFaqN/ebYAVP92915nGCvDKijZqfHIRKiv6c hqmFJXuJYfbmjjNM2lgwi/CO994PRFhIxhxqUze0s8DttoTd+FVD43U7TnfGt9ofoCB/rNo 01Z+KtN1t915qQfrwtidv377CDQEo93ADssTtgihoyrgfxtgKUGVgIFEdgSCKxwbuH02IGa rflqjWPpiaXum19p1/ltFFX0jz/PIyfmhWle1lmhmJ92YW+z7C00iGIg2xO4WYArnGE++SR clu++zcUpVKNf5bDejn8aGtcO0nDF/WwYE7hC82YTHOHeEOU40cFqkkczbkuZAo5eOOglpw 0mylTvCUK3hSEuegTI2qcjsYbh+h04Kh/iRU/FcavJlW7ymubm+i4klcyxt4l0H75RflV0U WN1phC0Zybhmd8zSL5B9KIdoTaASHXP+NZxE2ZKR3qQZS4zMQoQqbz41csQCHvcNyXKBrJX MKTaR6GhgjyhR7myMT2jBUhUb5PqVdiqDk7f/EGG8ivyATWt/vUQIWyhSFlEz463j1xsVfW fgRhdpLoQetvZ7nnVkfq9gswuDLV6s1klmov7NvT8sUVhoPpghmegNH3rbWFJBLKKBGpgW7 nutNWy04EFXOS5gREUfbSyWyeF4oqEeNm7RcvGI/uAm7HfC6D4S+fVSlGuQrJEohYdAoLFg 6FyfAnIc/1817M31JNbSKwZdvmHbF6NXWwMOS4vQBTebAL93ICtIhmdZNVnr3uq5iBgxpUA KW9aqa2PEMu5yUKpC/tnL3NAYOZ6fdYnoh0AGGgqsdSzAsQ5LR+pDJdO/th5bMWPM79o64/ ODtWu0iLQb0RWQ49KCV5ZVwzqVoTzwk5nkGpPxx8xy6vMq3nkQZ1hyikDo7amYMud2kXRzp 9cs58eVXp8+8XbcXUEpTpY1fAc2py3SguHCaurFWRfufoNWypeoUfvuwJqRIal7vpY5/Xva vJ05C+vuceyr830u5Y+fKdW91A04JJSiCauKXRiqF/AyLGBJCIVOhe9zTiSnQQtKV+hIgqC jy7gD/pRxMfCes4tgb+ynC8Bp2h2HykX6PwBasm3zmW3clncfunRcSVWYjDXv8CCMplL8gm 4d9fdU6LUjnKM6vvkZpb5Q= X-QQ-XMRINFO: OD9hHCdaPRBwH5bRRRw8tsiH4UAatJqXfg== X-QQ-RECHKSPAM: 0 Support AER driver to handle the PCIe errors. Signed-off-by: Jiawen Wu --- drivers/net/ethernet/wangxun/libwx/wx_err.c | 102 ++++++++++++++++++ drivers/net/ethernet/wangxun/libwx/wx_err.h | 2 + drivers/net/ethernet/wangxun/libwx/wx_lib.c | 3 +- drivers/net/ethernet/wangxun/libwx/wx_type.h | 1 + drivers/net/ethernet/wangxun/ngbe/ngbe_main.c | 5 +- .../net/ethernet/wangxun/txgbe/txgbe_main.c | 5 +- 6 files changed, 115 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/wangxun/libwx/wx_err.c b/drivers/net/ethernet/wangxun/libwx/wx_err.c index bb77bdce69d2..86b318647a3c 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_err.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_err.c @@ -3,11 +3,113 @@ #include #include +#include #include "wx_type.h" #include "wx_lib.h" #include "wx_err.h" +/** + * wx_io_error_detected - called when PCI error is detected + * @pdev: Pointer to PCI device + * @state: The current pci connection state + * + * Return: pci_ers_result_t. + * + * This function is called after a PCI bus error affecting + * this device has been detected. + */ +static pci_ers_result_t wx_io_error_detected(struct pci_dev *pdev, + pci_channel_state_t state) +{ + struct wx *wx = pci_get_drvdata(pdev); + struct net_device *netdev; + + netdev = wx->netdev; + if (!netif_device_present(netdev)) + return PCI_ERS_RESULT_DISCONNECT; + + rtnl_lock(); + netif_device_detach(netdev); + + if (netif_running(netdev)) + wx->close_suspend(wx); + + if (state == pci_channel_io_perm_failure) { + rtnl_unlock(); + return PCI_ERS_RESULT_DISCONNECT; + } + + if (!test_and_set_bit(WX_STATE_DISABLED, wx->state)) + pci_disable_device(pdev); + rtnl_unlock(); + + /* Request a slot reset. */ + return PCI_ERS_RESULT_NEED_RESET; +} + +/** + * wx_io_slot_reset - called after the pci bus has been reset. + * @pdev: Pointer to PCI device + * + * Return: pci_ers_result_t. + * + * Restart the card from scratch, as if from a cold-boot. + */ +static pci_ers_result_t wx_io_slot_reset(struct pci_dev *pdev) +{ + struct wx *wx = pci_get_drvdata(pdev); + pci_ers_result_t result; + + if (pci_enable_device_mem(pdev)) { + wx_err(wx, "Cannot re-enable PCI device after reset.\n"); + result = PCI_ERS_RESULT_DISCONNECT; + } else { + /* make all bar access done before reset. */ + smp_mb__before_atomic(); + clear_bit(WX_STATE_DISABLED, wx->state); + pci_set_master(pdev); + pci_restore_state(pdev); + pci_save_state(pdev); + pci_wake_from_d3(pdev, false); + + wx->do_reset(wx->netdev, false); + result = PCI_ERS_RESULT_RECOVERED; + } + + pci_aer_clear_nonfatal_status(pdev); + + return result; +} + +/** + * wx_io_resume - called when traffic can start flowing again. + * @pdev: Pointer to PCI device + * + * This callback is called when the error recovery driver tells us that + * its OK to resume normal operation. + */ +static void wx_io_resume(struct pci_dev *pdev) +{ + struct wx *wx = pci_get_drvdata(pdev); + struct net_device *netdev; + + netdev = wx->netdev; + rtnl_lock(); + if (netif_running(netdev)) + netdev->netdev_ops->ndo_open(netdev); + + netif_device_attach(netdev); + rtnl_unlock(); +} + +const struct pci_error_handlers wx_err_handler = { + .error_detected = wx_io_error_detected, + .slot_reset = wx_io_slot_reset, + .resume = wx_io_resume, +}; +EXPORT_SYMBOL(wx_err_handler); + static void wx_reset_subtask(struct wx *wx) { if (!test_bit(WX_FLAG_NEED_PF_RESET, wx->flags)) diff --git a/drivers/net/ethernet/wangxun/libwx/wx_err.h b/drivers/net/ethernet/wangxun/libwx/wx_err.h index e317e6c8d928..8b1a7863b5b1 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_err.h +++ b/drivers/net/ethernet/wangxun/libwx/wx_err.h @@ -7,6 +7,8 @@ #ifndef _WX_ERR_H_ #define _WX_ERR_H_ +extern const struct pci_error_handlers wx_err_handler; + void wx_handle_errors_subtask(struct wx *wx); void wx_tx_timeout(struct net_device *netdev, unsigned int txqueue); void wx_handle_tx_hang(struct wx_ring *tx_ring, unsigned int next); diff --git a/drivers/net/ethernet/wangxun/libwx/wx_lib.c b/drivers/net/ethernet/wangxun/libwx/wx_lib.c index 5a21478a592b..1cd73b424d7f 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_lib.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_lib.c @@ -3418,7 +3418,8 @@ static void wx_dev_shutdown(struct pci_dev *pdev, bool *enable_wake) *enable_wake = !!wufc; wx_control_hw(wx, false); - pci_disable_device(pdev); + if (!test_and_set_bit(WX_STATE_DISABLED, wx->state)) + pci_disable_device(pdev); } int wx_suspend(struct pci_dev *pdev, pm_message_t state) diff --git a/drivers/net/ethernet/wangxun/libwx/wx_type.h b/drivers/net/ethernet/wangxun/libwx/wx_type.h index 434a582393d7..142b166117fa 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_type.h +++ b/drivers/net/ethernet/wangxun/libwx/wx_type.h @@ -1196,6 +1196,7 @@ enum wx_state { WX_STATE_PTP_RUNNING, WX_STATE_PTP_TX_IN_PROGRESS, WX_STATE_SERVICE_SCHED, + WX_STATE_DISABLED, WX_STATE_NBITS /* must be last */ }; diff --git a/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c b/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c index e0f5d3b49db7..18bd627f63db 100644 --- a/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c +++ b/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c @@ -819,6 +819,7 @@ static int ngbe_probe(struct pci_dev *pdev, goto err_register; pci_set_drvdata(pdev, wx); + pci_save_state(pdev); return 0; @@ -869,7 +870,8 @@ static void ngbe_remove(struct pci_dev *pdev) kfree(wx->mac_table); wx_clear_interrupt_scheme(wx); - pci_disable_device(pdev); + if (!test_and_set_bit(WX_STATE_DISABLED, wx->state)) + pci_disable_device(pdev); } static struct pci_driver ngbe_driver = { @@ -881,6 +883,7 @@ static struct pci_driver ngbe_driver = { .resume = wx_resume, .shutdown = wx_shutdown, .sriov_configure = wx_pci_sriov_configure, + .err_handler = &wx_err_handler, }; module_pci_driver(ngbe_driver); diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c index d4f87fbb9565..c9fdad7f0df2 100644 --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c @@ -886,6 +886,7 @@ static int txgbe_probe(struct pci_dev *pdev, goto err_remove_phy; pci_set_drvdata(pdev, wx); + pci_save_state(pdev); netif_tx_stop_all_queues(netdev); @@ -956,7 +957,8 @@ static void txgbe_remove(struct pci_dev *pdev) kfree(wx->mac_table); wx_clear_interrupt_scheme(wx); - pci_disable_device(pdev); + if (!test_and_set_bit(WX_STATE_DISABLED, wx->state)) + pci_disable_device(pdev); } static struct pci_driver txgbe_driver = { @@ -968,6 +970,7 @@ static struct pci_driver txgbe_driver = { .resume = wx_resume, .shutdown = wx_shutdown, .sriov_configure = wx_pci_sriov_configure, + .err_handler = &wx_err_handler, }; module_pci_driver(txgbe_driver); -- 2.48.1