Commit a79b559e authored by Shannon Nelson's avatar Shannon Nelson Committed by David S. Miller
Browse files

ionic: add FLR recovery support



Add support for the PCI reset handlers in order to manage an FLR event.

Signed-off-by: default avatarShannon Nelson <shannon.nelson@amd.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 30d2e073
Loading
Loading
Loading
Loading
+53 −0
Original line number Diff line number Diff line
@@ -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)
+4 −4
Original line number Diff line number Diff line
@@ -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;
+5 −0
Original line number Diff line number Diff line
@@ -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,