Commit 237274fa authored by Paolo Abeni's avatar Paolo Abeni

Merge branch 'ionic-pci-error-handling-fixes'

Shannon Nelson says:

====================
ionic: PCI error handling fixes

These are a few things to make our PCI reset handling better.
====================

Link: https://lore.kernel.org/r/20240223222742.13923-1-shannon.nelson@amd.comSigned-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents 3980cf16 155a1efc
...@@ -93,6 +93,7 @@ static void ionic_unmap_bars(struct ionic *ionic) ...@@ -93,6 +93,7 @@ static void ionic_unmap_bars(struct ionic *ionic)
bars[i].len = 0; bars[i].len = 0;
} }
} }
ionic->num_bars = 0;
} }
void __iomem *ionic_bus_map_dbpage(struct ionic *ionic, int page_num) void __iomem *ionic_bus_map_dbpage(struct ionic *ionic, int page_num)
...@@ -215,13 +216,15 @@ static int ionic_sriov_configure(struct pci_dev *pdev, int num_vfs) ...@@ -215,13 +216,15 @@ static int ionic_sriov_configure(struct pci_dev *pdev, int num_vfs)
static void ionic_clear_pci(struct ionic *ionic) static void ionic_clear_pci(struct ionic *ionic)
{ {
ionic->idev.dev_info_regs = NULL; if (ionic->num_bars) {
ionic->idev.dev_cmd_regs = NULL; ionic->idev.dev_info_regs = NULL;
ionic->idev.intr_status = NULL; ionic->idev.dev_cmd_regs = NULL;
ionic->idev.intr_ctrl = NULL; ionic->idev.intr_status = NULL;
ionic->idev.intr_ctrl = NULL;
ionic_unmap_bars(ionic);
pci_release_regions(ionic->pdev); ionic_unmap_bars(ionic);
pci_release_regions(ionic->pdev);
}
if (pci_is_enabled(ionic->pdev)) if (pci_is_enabled(ionic->pdev))
pci_disable_device(ionic->pdev); pci_disable_device(ionic->pdev);
......
...@@ -319,22 +319,32 @@ int ionic_heartbeat_check(struct ionic *ionic) ...@@ -319,22 +319,32 @@ int ionic_heartbeat_check(struct ionic *ionic)
u8 ionic_dev_cmd_status(struct ionic_dev *idev) u8 ionic_dev_cmd_status(struct ionic_dev *idev)
{ {
if (!idev->dev_cmd_regs)
return (u8)PCI_ERROR_RESPONSE;
return ioread8(&idev->dev_cmd_regs->comp.comp.status); return ioread8(&idev->dev_cmd_regs->comp.comp.status);
} }
bool ionic_dev_cmd_done(struct ionic_dev *idev) bool ionic_dev_cmd_done(struct ionic_dev *idev)
{ {
if (!idev->dev_cmd_regs)
return false;
return ioread32(&idev->dev_cmd_regs->done) & IONIC_DEV_CMD_DONE; return ioread32(&idev->dev_cmd_regs->done) & IONIC_DEV_CMD_DONE;
} }
void ionic_dev_cmd_comp(struct ionic_dev *idev, union ionic_dev_cmd_comp *comp) void ionic_dev_cmd_comp(struct ionic_dev *idev, union ionic_dev_cmd_comp *comp)
{ {
if (!idev->dev_cmd_regs)
return;
memcpy_fromio(comp, &idev->dev_cmd_regs->comp, sizeof(*comp)); memcpy_fromio(comp, &idev->dev_cmd_regs->comp, sizeof(*comp));
} }
void ionic_dev_cmd_go(struct ionic_dev *idev, union ionic_dev_cmd *cmd) void ionic_dev_cmd_go(struct ionic_dev *idev, union ionic_dev_cmd *cmd)
{ {
idev->opcode = cmd->cmd.opcode; idev->opcode = cmd->cmd.opcode;
if (!idev->dev_cmd_regs)
return;
memcpy_toio(&idev->dev_cmd_regs->cmd, cmd, sizeof(*cmd)); memcpy_toio(&idev->dev_cmd_regs->cmd, cmd, sizeof(*cmd));
iowrite32(0, &idev->dev_cmd_regs->done); iowrite32(0, &idev->dev_cmd_regs->done);
iowrite32(1, &idev->dev_cmd_regs->doorbell); iowrite32(1, &idev->dev_cmd_regs->doorbell);
......
...@@ -90,18 +90,23 @@ static void ionic_get_regs(struct net_device *netdev, struct ethtool_regs *regs, ...@@ -90,18 +90,23 @@ static void ionic_get_regs(struct net_device *netdev, struct ethtool_regs *regs,
void *p) void *p)
{ {
struct ionic_lif *lif = netdev_priv(netdev); struct ionic_lif *lif = netdev_priv(netdev);
struct ionic_dev *idev;
unsigned int offset; unsigned int offset;
unsigned int size; unsigned int size;
regs->version = IONIC_DEV_CMD_REG_VERSION; regs->version = IONIC_DEV_CMD_REG_VERSION;
idev = &lif->ionic->idev;
if (!idev->dev_info_regs)
return;
offset = 0; offset = 0;
size = IONIC_DEV_INFO_REG_COUNT * sizeof(u32); size = IONIC_DEV_INFO_REG_COUNT * sizeof(u32);
memcpy_fromio(p + offset, lif->ionic->idev.dev_info_regs->words, size); memcpy_fromio(p + offset, lif->ionic->idev.dev_info_regs->words, size);
offset += size; offset += size;
size = IONIC_DEV_CMD_REG_COUNT * sizeof(u32); size = IONIC_DEV_CMD_REG_COUNT * sizeof(u32);
memcpy_fromio(p + offset, lif->ionic->idev.dev_cmd_regs->words, size); memcpy_fromio(p + offset, idev->dev_cmd_regs->words, size);
} }
static void ionic_get_link_ext_stats(struct net_device *netdev, static void ionic_get_link_ext_stats(struct net_device *netdev,
......
...@@ -109,6 +109,11 @@ int ionic_firmware_update(struct ionic_lif *lif, const struct firmware *fw, ...@@ -109,6 +109,11 @@ int ionic_firmware_update(struct ionic_lif *lif, const struct firmware *fw,
dl = priv_to_devlink(ionic); dl = priv_to_devlink(ionic);
devlink_flash_update_status_notify(dl, "Preparing to flash", NULL, 0, 0); devlink_flash_update_status_notify(dl, "Preparing to flash", NULL, 0, 0);
if (!idev->dev_cmd_regs) {
err = -ENXIO;
goto err_out;
}
buf_sz = sizeof(idev->dev_cmd_regs->data); buf_sz = sizeof(idev->dev_cmd_regs->data);
netdev_dbg(netdev, netdev_dbg(netdev,
......
...@@ -3559,7 +3559,10 @@ int ionic_lif_init(struct ionic_lif *lif) ...@@ -3559,7 +3559,10 @@ int ionic_lif_init(struct ionic_lif *lif)
goto err_out_notifyq_deinit; goto err_out_notifyq_deinit;
} }
err = ionic_init_nic_features(lif); if (test_bit(IONIC_LIF_F_FW_RESET, lif->state))
err = ionic_set_nic_features(lif, lif->netdev->features);
else
err = ionic_init_nic_features(lif);
if (err) if (err)
goto err_out_notifyq_deinit; goto err_out_notifyq_deinit;
......
...@@ -416,6 +416,9 @@ static void ionic_dev_cmd_clean(struct ionic *ionic) ...@@ -416,6 +416,9 @@ static void ionic_dev_cmd_clean(struct ionic *ionic)
{ {
struct ionic_dev *idev = &ionic->idev; struct ionic_dev *idev = &ionic->idev;
if (!idev->dev_cmd_regs)
return;
iowrite32(0, &idev->dev_cmd_regs->doorbell); iowrite32(0, &idev->dev_cmd_regs->doorbell);
memset_io(&idev->dev_cmd_regs->cmd, 0, sizeof(idev->dev_cmd_regs->cmd)); memset_io(&idev->dev_cmd_regs->cmd, 0, sizeof(idev->dev_cmd_regs->cmd));
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment