sfc: commonise PCI error handlers
authorEdward Cree <ecree@solarflare.com>
Mon, 29 Jun 2020 13:35:41 +0000 (14:35 +0100)
committerDavid S. Miller <davem@davemloft.net>
Tue, 30 Jun 2020 00:37:49 +0000 (17:37 -0700)
EF100 will use the same mechanisms for PCI error recovery.

Signed-off-by: Edward Cree <ecree@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/sfc/efx.c
drivers/net/ethernet/sfc/efx_common.c
drivers/net/ethernet/sfc/efx_common.h

index 86639b1..4c2d305 100644 (file)
@@ -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,
index 36c0ab5..88ade7f 100644 (file)
@@ -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,
+};
index 93a017a..68af2af 100644 (file)
@@ -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