[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <976f1840-8c0c-9653-2703-9942916ead73@solarflare.com>
Date: Mon, 29 Jun 2020 14:35:41 +0100
From: Edward Cree <ecree@...arflare.com>
To: <linux-net-drivers@...arflare.com>, <davem@...emloft.net>
CC: <netdev@...r.kernel.org>
Subject: [PATCH v2 net-next 12/15] sfc: commonise PCI error handlers
EF100 will use the same mechanisms for PCI error recovery.
Signed-off-by: Edward Cree <ecree@...arflare.com>
---
drivers/net/ethernet/sfc/efx.c | 91 ---------------------------
drivers/net/ethernet/sfc/efx_common.c | 91 +++++++++++++++++++++++++++
drivers/net/ethernet/sfc/efx_common.h | 1 +
3 files changed, 92 insertions(+), 91 deletions(-)
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 86639b1e4e5c..4c2d305089ce 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -1490,97 +1490,6 @@ static const struct dev_pm_ops efx_pm_ops = {
.restore = efx_pm_resume,
};
-/* A PCI error affecting this device was detected.
- * At this point MMIO and DMA may be disabled.
- * Stop the software path and request a slot reset.
- */
-static pci_ers_result_t efx_io_error_detected(struct pci_dev *pdev,
- enum pci_channel_state state)
-{
- pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED;
- struct efx_nic *efx = pci_get_drvdata(pdev);
-
- if (state == pci_channel_io_perm_failure)
- return PCI_ERS_RESULT_DISCONNECT;
-
- rtnl_lock();
-
- if (efx->state != STATE_DISABLED) {
- efx->state = STATE_RECOVERY;
- efx->reset_pending = 0;
-
- efx_device_detach_sync(efx);
-
- efx_stop_all(efx);
- efx_disable_interrupts(efx);
-
- status = PCI_ERS_RESULT_NEED_RESET;
- } else {
- /* If the interface is disabled we don't want to do anything
- * with it.
- */
- status = PCI_ERS_RESULT_RECOVERED;
- }
-
- rtnl_unlock();
-
- pci_disable_device(pdev);
-
- return status;
-}
-
-/* Fake a successful reset, which will be performed later in efx_io_resume. */
-static pci_ers_result_t efx_io_slot_reset(struct pci_dev *pdev)
-{
- struct efx_nic *efx = pci_get_drvdata(pdev);
- pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED;
-
- if (pci_enable_device(pdev)) {
- netif_err(efx, hw, efx->net_dev,
- "Cannot re-enable PCI device after reset.\n");
- status = PCI_ERS_RESULT_DISCONNECT;
- }
-
- return status;
-}
-
-/* Perform the actual reset and resume I/O operations. */
-static void efx_io_resume(struct pci_dev *pdev)
-{
- struct efx_nic *efx = pci_get_drvdata(pdev);
- int rc;
-
- rtnl_lock();
-
- if (efx->state == STATE_DISABLED)
- goto out;
-
- rc = efx_reset(efx, RESET_TYPE_ALL);
- if (rc) {
- netif_err(efx, hw, efx->net_dev,
- "efx_reset failed after PCI error (%d)\n", rc);
- } else {
- efx->state = STATE_READY;
- netif_dbg(efx, hw, efx->net_dev,
- "Done resetting and resuming IO after PCI error.\n");
- }
-
-out:
- rtnl_unlock();
-}
-
-/* For simplicity and reliability, we always require a slot reset and try to
- * reset the hardware when a pci error affecting the device is detected.
- * We leave both the link_reset and mmio_enabled callback unimplemented:
- * with our request for slot reset the mmio_enabled callback will never be
- * called, and the link_reset callback is not used by AER or EEH mechanisms.
- */
-static const struct pci_error_handlers efx_err_handlers = {
- .error_detected = efx_io_error_detected,
- .slot_reset = efx_io_slot_reset,
- .resume = efx_io_resume,
-};
-
static struct pci_driver efx_pci_driver = {
.name = KBUILD_MODNAME,
.id_table = efx_pci_table,
diff --git a/drivers/net/ethernet/sfc/efx_common.c b/drivers/net/ethernet/sfc/efx_common.c
index 36c0ab57d3bd..88ade7f41819 100644
--- a/drivers/net/ethernet/sfc/efx_common.c
+++ b/drivers/net/ethernet/sfc/efx_common.c
@@ -1130,3 +1130,94 @@ void efx_fini_mcdi_logging(struct efx_nic *efx)
device_remove_file(&efx->pci_dev->dev, &dev_attr_mcdi_logging);
}
#endif
+
+/* A PCI error affecting this device was detected.
+ * At this point MMIO and DMA may be disabled.
+ * Stop the software path and request a slot reset.
+ */
+static pci_ers_result_t efx_io_error_detected(struct pci_dev *pdev,
+ enum pci_channel_state state)
+{
+ pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED;
+ struct efx_nic *efx = pci_get_drvdata(pdev);
+
+ if (state == pci_channel_io_perm_failure)
+ return PCI_ERS_RESULT_DISCONNECT;
+
+ rtnl_lock();
+
+ if (efx->state != STATE_DISABLED) {
+ efx->state = STATE_RECOVERY;
+ efx->reset_pending = 0;
+
+ efx_device_detach_sync(efx);
+
+ efx_stop_all(efx);
+ efx_disable_interrupts(efx);
+
+ status = PCI_ERS_RESULT_NEED_RESET;
+ } else {
+ /* If the interface is disabled we don't want to do anything
+ * with it.
+ */
+ status = PCI_ERS_RESULT_RECOVERED;
+ }
+
+ rtnl_unlock();
+
+ pci_disable_device(pdev);
+
+ return status;
+}
+
+/* Fake a successful reset, which will be performed later in efx_io_resume. */
+static pci_ers_result_t efx_io_slot_reset(struct pci_dev *pdev)
+{
+ struct efx_nic *efx = pci_get_drvdata(pdev);
+ pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED;
+
+ if (pci_enable_device(pdev)) {
+ netif_err(efx, hw, efx->net_dev,
+ "Cannot re-enable PCI device after reset.\n");
+ status = PCI_ERS_RESULT_DISCONNECT;
+ }
+
+ return status;
+}
+
+/* Perform the actual reset and resume I/O operations. */
+static void efx_io_resume(struct pci_dev *pdev)
+{
+ struct efx_nic *efx = pci_get_drvdata(pdev);
+ int rc;
+
+ rtnl_lock();
+
+ if (efx->state == STATE_DISABLED)
+ goto out;
+
+ rc = efx_reset(efx, RESET_TYPE_ALL);
+ if (rc) {
+ netif_err(efx, hw, efx->net_dev,
+ "efx_reset failed after PCI error (%d)\n", rc);
+ } else {
+ efx->state = STATE_READY;
+ netif_dbg(efx, hw, efx->net_dev,
+ "Done resetting and resuming IO after PCI error.\n");
+ }
+
+out:
+ rtnl_unlock();
+}
+
+/* For simplicity and reliability, we always require a slot reset and try to
+ * reset the hardware when a pci error affecting the device is detected.
+ * We leave both the link_reset and mmio_enabled callback unimplemented:
+ * with our request for slot reset the mmio_enabled callback will never be
+ * called, and the link_reset callback is not used by AER or EEH mechanisms.
+ */
+const struct pci_error_handlers efx_err_handlers = {
+ .error_detected = efx_io_error_detected,
+ .slot_reset = efx_io_slot_reset,
+ .resume = efx_io_resume,
+};
diff --git a/drivers/net/ethernet/sfc/efx_common.h b/drivers/net/ethernet/sfc/efx_common.h
index 93a017aafb9f..68af2af3b5da 100644
--- a/drivers/net/ethernet/sfc/efx_common.h
+++ b/drivers/net/ethernet/sfc/efx_common.h
@@ -73,4 +73,5 @@ void efx_link_status_changed(struct efx_nic *efx);
unsigned int efx_xdp_max_mtu(struct efx_nic *efx);
int efx_change_mtu(struct net_device *net_dev, int new_mtu);
+extern const struct pci_error_handlers efx_err_handlers;
#endif
Powered by blists - more mailing lists