From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtpbguseast3.qq.com (smtpbguseast3.qq.com [54.243.244.52]) (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 BC2AB39F16B for ; Sat, 9 May 2026 10:06:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.243.244.52 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778321197; cv=none; b=TrF2DmLkfxVPtOvEvhubvW9FXq82HO4PGyP8icD+u22K2SBo5gk5+ql27W7b9sTklIJFtglic1Xja/Pa9uQjPp2Hc+BlHugc6HTP8uaFhNR9BckognTn+w/XBTmxdG6tukgRv8MzLGroH1dy8waDaZ1O0URiH0aJY2LkylIpgco= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778321197; c=relaxed/simple; bh=QQAFBOl8xg6+kZL/BhWbnRk8BZ5BpFkiyuBLCtXfzxw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=RDc1Fv8JfL/Tddgr9KX15t4c65ti3I+7Zavi3kyZ96mYEJSmlh/4ceyv2xclhaMVh6MROMV70yv+fbPRuYwha26T1ZzAdrTM+EFjddDEHAHJk4ItnW++mMyd7o7ZunQgTZvV5PZWjjimoKpw/UTJcxTIseC2ZCvo0wnBpDT8XaE= 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=54.243.244.52 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: esmtpsz17t1778321162t778454ea X-QQ-Originating-IP: 7Fc8txjcZfea5u4+4cUaw04QSp/i00oFCj2mIBV0zIg= Received: from lap-jiawenwu.trustnetic.com ( [115.204.251.157]) by bizesmtp.qq.com (ESMTP) with id ; Sat, 09 May 2026 18:06:00 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 7184285776851020265 EX-QQ-RecipientCnt: 17 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 , Kees Cook , Larysa Zaremba , Breno Leitao , Joe Damato , Jacob Keller , Fabio Baltieri , Jiawen Wu Subject: [PATCH net-next v3 5/5] net: wangxun: implement pci_error_handlers ops Date: Sat, 9 May 2026 18:05:40 +0800 Message-Id: <20260509100540.32612-6-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.21.0.windows.1 In-Reply-To: <20260509100540.32612-1-jiawenwu@trustnetic.com> References: <20260509100540.32612-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: NC/J3CrDtaBbc/FFO9edvP3dTY+skoQ2jQhWterE85AvDyDfgGZ5I68R S1CKz5HziPazYAnOQYsI8dhjw1zZx174CsZSoZBTG/7s0nX61WTfjLdMooC0dKangFx6k9C cF7axoG20Tpxkg7szKvBcJPdOIeAQTQTNWbN/dR9zlkaRwO2zGufnqi/tE/xtEX76rBFXax 7zQm/w8cjB8xCcc8ygGyaCsJ0VHSL4D7n0ynaqQldUa2sMa9mCdbseh538dUmjLx+oV48+t El7uLzzLZVmPwNXl8Oa0TLiTtOwHXDVCBLjQa/K7KoRoMTreAIrxOhgCyAurZQp3EXyK4/s ZHTkZ3VsC/4xYuU6A3dFTHbfAJAt9N4K7TicKEKS/VLIWU47GdsVUatDFmBgpQ7UjNCFd/h QVhqFbokAvq27jeWLTO4pmIeVBJP5Ay39Z6zlnZmrI0CAd1t9jGLujNIBYiJsacMRPV3CnY JZ0dN13xwBgUu16zwFzK2ynY9nFYZNDf0X5mtV8/pk4MpET4MGjQP8tPY/zSsxN9hQJwZLt QbqH5O642HbNfJlu5kf2cujr0e7mT91dHOnHHUDoHcEwiWgvpUnM3+5TBS/xMsgdAZhxE+P o19coY1kmB6PdcR81GRsFy8wS5E61+TWkjrLpduWaSr7oUjjEfABSkD0yuIqNWdy2dG2sy6 wDT+Hbyw0ck52SOCD0+v/J9rS8zflgt12lvRMyfNM8pHNd6r8B1+HmcB855hcNUDoAKP6sk zW728Yu5uroMWCCQHEyn3s9Bcm5Q24eCX5RX+ICwh8o2Kt9OGxQdpzbGESUdGpVECvTrO5T UaJIDgXp/HswMT9eoVBahqI7XVuaSAFNj4cvGggHnZ70L41IpNlKsLZu7eoDCwHLp8JXetj /kHXbQMsc2bIfJyoUmAwjESn4RiAN9ux9qSmOI9o0BeQELhaBew/gccrrMM78HYeZ4OK8H0 8Me20FhbYGDxAHCii25dF3GxnwJSQP7Pz8lplmFeZECVOYeWfRl9t3s+Ky0ve8qRFUOCGGi FWsZAmwDKAnUMntNhbjpduzPBKt/RxGhtFoGFq7Mgdwb39UEp5Co1EBWG3nQwMeknxjQNrz w== X-QQ-XMRINFO: MSVp+SPm3vtSI1QTLgDHQqIV1w2oNKDqfg== 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 | 108 ++++++++++++++++++ drivers/net/ethernet/wangxun/libwx/wx_err.h | 2 + drivers/net/ethernet/wangxun/libwx/wx_type.h | 1 + drivers/net/ethernet/wangxun/ngbe/ngbe_main.c | 9 +- .../net/ethernet/wangxun/txgbe/txgbe_main.c | 8 +- 5 files changed, 124 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/wangxun/libwx/wx_err.c b/drivers/net/ethernet/wangxun/libwx/wx_err.c index deb9fac2e1a9..64d43bf6e9da 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_err.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_err.c @@ -4,11 +4,119 @@ #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; + + if (!wx) + return PCI_ERS_RESULT_DISCONNECT; + + netdev = wx->netdev; + if (!netif_device_present(netdev)) + return PCI_ERS_RESULT_DISCONNECT; + + if (state == pci_channel_io_perm_failure) + return PCI_ERS_RESULT_DISCONNECT; + + rtnl_lock(); + netif_device_detach(netdev); + + if (netif_running(netdev)) + wx->close_suspend(wx); + + 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_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; + int err; + + netdev = wx->netdev; + rtnl_lock(); + if (netif_running(netdev)) { + err = netdev->netdev_ops->ndo_open(netdev); + if (err) { + wx_err(wx, "Failed to open netdev after reset\n"); + goto out; + } + } + netif_device_attach(netdev); +out: + 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); + 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 594e70bce229..9b086f597d8e 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_reset_subtask(struct wx *wx); void wx_check_tx_hang_subtask(struct wx *wx); void wx_tx_timeout(struct net_device *netdev, unsigned int txqueue); diff --git a/drivers/net/ethernet/wangxun/libwx/wx_type.h b/drivers/net/ethernet/wangxun/libwx/wx_type.h index c3befb272274..2dc2bdba74bb 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_type.h +++ b/drivers/net/ethernet/wangxun/libwx/wx_type.h @@ -1220,6 +1220,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 891f057470d4..0921d5815a26 100644 --- a/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c +++ b/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c @@ -571,7 +571,8 @@ static void ngbe_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); } static void ngbe_shutdown(struct pci_dev *pdev) @@ -857,6 +858,7 @@ static int ngbe_probe(struct pci_dev *pdev, goto err_register; pci_set_drvdata(pdev, wx); + pci_save_state(pdev); return 0; @@ -908,7 +910,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 int ngbe_suspend(struct pci_dev *pdev, pm_message_t state) @@ -935,6 +938,7 @@ static int ngbe_resume(struct pci_dev *pdev) wx_err(wx, "Cannot enable PCI device from suspend\n"); return err; } + clear_bit(WX_STATE_DISABLED, wx->state); pci_set_master(pdev); device_wakeup_disable(&pdev->dev); @@ -959,6 +963,7 @@ static struct pci_driver ngbe_driver = { .resume = ngbe_resume, .shutdown = ngbe_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 ae91379d847d..df0534a875a9 100644 --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c @@ -553,7 +553,8 @@ static void txgbe_dev_shutdown(struct pci_dev *pdev) wx_control_hw(wx, false); - pci_disable_device(pdev); + if (!test_and_set_bit(WX_STATE_DISABLED, wx->state)) + pci_disable_device(pdev); } static void txgbe_shutdown(struct pci_dev *pdev) @@ -901,6 +902,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); @@ -971,7 +973,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 = { @@ -981,6 +984,7 @@ static struct pci_driver txgbe_driver = { .remove = txgbe_remove, .shutdown = txgbe_shutdown, .sriov_configure = wx_pci_sriov_configure, + .err_handler = &wx_err_handler, }; module_pci_driver(txgbe_driver); -- 2.51.0