ionic: add FLR recovery support
authorShannon Nelson <shannon.nelson@amd.com>
Thu, 20 Jul 2023 19:08:16 +0000 (12:08 -0700)
committerDavid S. Miller <davem@davemloft.net>
Mon, 24 Jul 2023 09:42:34 +0000 (10:42 +0100)
Add support for the PCI reset handlers in order to manage an FLR event.

Signed-off-by: Shannon Nelson <shannon.nelson@amd.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c
drivers/net/ethernet/pensando/ionic/ionic_lif.c
drivers/net/ethernet/pensando/ionic/ionic_lif.h

index bcce613..d6ce113 100644 (file)
@@ -409,12 +409,65 @@ static void ionic_remove(struct pci_dev *pdev)
        ionic_devlink_free(ionic);
 }
 
+static void ionic_reset_prepare(struct pci_dev *pdev)
+{
+       struct ionic *ionic = pci_get_drvdata(pdev);
+       struct ionic_lif *lif = ionic->lif;
+
+       dev_dbg(ionic->dev, "%s: device stopping\n", __func__);
+
+       del_timer_sync(&ionic->watchdog_timer);
+       cancel_work_sync(&lif->deferred.work);
+
+       mutex_lock(&lif->queue_lock);
+       ionic_stop_queues_reconfig(lif);
+       ionic_txrx_free(lif);
+       ionic_lif_deinit(lif);
+       ionic_qcqs_free(lif);
+       mutex_unlock(&lif->queue_lock);
+
+       ionic_dev_teardown(ionic);
+       ionic_clear_pci(ionic);
+       ionic_debugfs_del_dev(ionic);
+}
+
+static void ionic_reset_done(struct pci_dev *pdev)
+{
+       struct ionic *ionic = pci_get_drvdata(pdev);
+       struct ionic_lif *lif = ionic->lif;
+       int err;
+
+       err = ionic_setup_one(ionic);
+       if (err)
+               goto err_out;
+
+       ionic_debugfs_add_sizes(ionic);
+       ionic_debugfs_add_lif(ionic->lif);
+
+       err = ionic_restart_lif(lif);
+       if (err)
+               goto err_out;
+
+       mod_timer(&ionic->watchdog_timer, jiffies + 1);
+
+err_out:
+       dev_dbg(ionic->dev, "%s: device recovery %s\n",
+               __func__, err ? "failed" : "done");
+}
+
+static const struct pci_error_handlers ionic_err_handler = {
+       /* FLR handling */
+       .reset_prepare      = ionic_reset_prepare,
+       .reset_done         = ionic_reset_done,
+};
+
 static struct pci_driver ionic_driver = {
        .name = IONIC_DRV_NAME,
        .id_table = ionic_id_table,
        .probe = ionic_probe,
        .remove = ionic_remove,
        .sriov_configure = ionic_sriov_configure,
+       .err_handler = &ionic_err_handler
 };
 
 int ionic_bus_register_driver(void)
index 2d03c1b..adc05f9 100644 (file)
@@ -434,7 +434,7 @@ static void ionic_qcq_free(struct ionic_lif *lif, struct ionic_qcq *qcq)
        }
 }
 
-static void ionic_qcqs_free(struct ionic_lif *lif)
+void ionic_qcqs_free(struct ionic_lif *lif)
 {
        struct device *dev = lif->ionic->dev;
        struct ionic_qcq *adminqcq;
@@ -1754,7 +1754,7 @@ static int ionic_set_mac_address(struct net_device *netdev, void *sa)
        return ionic_lif_addr_add(netdev_priv(netdev), mac);
 }
 
-static void ionic_stop_queues_reconfig(struct ionic_lif *lif)
+void ionic_stop_queues_reconfig(struct ionic_lif *lif)
 {
        /* Stop and clean the queues before reconfiguration */
        netif_device_detach(lif->netdev);
@@ -2009,7 +2009,7 @@ static void ionic_txrx_deinit(struct ionic_lif *lif)
        }
 }
 
-static void ionic_txrx_free(struct ionic_lif *lif)
+void ionic_txrx_free(struct ionic_lif *lif)
 {
        unsigned int i;
 
@@ -3266,7 +3266,7 @@ static void ionic_lif_handle_fw_down(struct ionic_lif *lif)
        dev_info(ionic->dev, "FW Down: LIFs stopped\n");
 }
 
-static int ionic_restart_lif(struct ionic_lif *lif)
+int ionic_restart_lif(struct ionic_lif *lif)
 {
        struct ionic *ionic = lif->ionic;
        int err;
index fd2ea67..457c241 100644 (file)
@@ -325,6 +325,11 @@ void ionic_lif_deinit(struct ionic_lif *lif);
 int ionic_lif_addr_add(struct ionic_lif *lif, const u8 *addr);
 int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr);
 
+void ionic_stop_queues_reconfig(struct ionic_lif *lif);
+void ionic_txrx_free(struct ionic_lif *lif);
+void ionic_qcqs_free(struct ionic_lif *lif);
+int ionic_restart_lif(struct ionic_lif *lif);
+
 int ionic_lif_register(struct ionic_lif *lif);
 void ionic_lif_unregister(struct ionic_lif *lif);
 int ionic_lif_identify(struct ionic *ionic, u8 lif_type,