Skip to content

Commit d2e9464

Browse files
committed
Merge branch 'ionic-pci-errors'
Shannon Nelson says: ==================== ionic: updates to PCI error handling These are improvements to our PCI error handling, including FLR and AER events. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents e5bc1f4 + c3a910e commit d2e9464

File tree

6 files changed

+81
-15
lines changed

6 files changed

+81
-15
lines changed

drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,9 +215,16 @@ static int ionic_sriov_configure(struct pci_dev *pdev, int num_vfs)
215215

216216
static void ionic_clear_pci(struct ionic *ionic)
217217
{
218+
ionic->idev.dev_info_regs = NULL;
219+
ionic->idev.dev_cmd_regs = NULL;
220+
ionic->idev.intr_status = NULL;
221+
ionic->idev.intr_ctrl = NULL;
222+
218223
ionic_unmap_bars(ionic);
219224
pci_release_regions(ionic->pdev);
220-
pci_disable_device(ionic->pdev);
225+
226+
if (atomic_read(&ionic->pdev->enable_cnt) > 0)
227+
pci_disable_device(ionic->pdev);
221228
}
222229

223230
static int ionic_setup_one(struct ionic *ionic)
@@ -389,9 +396,13 @@ static void ionic_remove(struct pci_dev *pdev)
389396
{
390397
struct ionic *ionic = pci_get_drvdata(pdev);
391398

392-
del_timer_sync(&ionic->watchdog_timer);
399+
timer_shutdown_sync(&ionic->watchdog_timer);
393400

394401
if (ionic->lif) {
402+
/* prevent adminq cmds if already known as down */
403+
if (test_and_clear_bit(IONIC_LIF_F_FW_RESET, ionic->lif->state))
404+
set_bit(IONIC_LIF_F_FW_STOPPING, ionic->lif->state);
405+
395406
ionic_lif_unregister(ionic->lif);
396407
ionic_devlink_unregister(ionic);
397408
ionic_lif_deinit(ionic->lif);
@@ -416,6 +427,8 @@ static void ionic_reset_prepare(struct pci_dev *pdev)
416427

417428
dev_dbg(ionic->dev, "%s: device stopping\n", __func__);
418429

430+
set_bit(IONIC_LIF_F_FW_RESET, lif->state);
431+
419432
del_timer_sync(&ionic->watchdog_timer);
420433
cancel_work_sync(&lif->deferred.work);
421434

@@ -424,6 +437,7 @@ static void ionic_reset_prepare(struct pci_dev *pdev)
424437
ionic_txrx_free(lif);
425438
ionic_lif_deinit(lif);
426439
ionic_qcqs_free(lif);
440+
ionic_debugfs_del_lif(lif);
427441
mutex_unlock(&lif->queue_lock);
428442

429443
ionic_dev_teardown(ionic);
@@ -455,10 +469,35 @@ static void ionic_reset_done(struct pci_dev *pdev)
455469
__func__, err ? "failed" : "done");
456470
}
457471

472+
static pci_ers_result_t ionic_pci_error_detected(struct pci_dev *pdev,
473+
pci_channel_state_t error)
474+
{
475+
if (error == pci_channel_io_frozen) {
476+
ionic_reset_prepare(pdev);
477+
return PCI_ERS_RESULT_NEED_RESET;
478+
}
479+
480+
return PCI_ERS_RESULT_NONE;
481+
}
482+
483+
static void ionic_pci_error_resume(struct pci_dev *pdev)
484+
{
485+
struct ionic *ionic = pci_get_drvdata(pdev);
486+
struct ionic_lif *lif = ionic->lif;
487+
488+
if (lif && test_bit(IONIC_LIF_F_FW_RESET, lif->state))
489+
pci_reset_function_locked(pdev);
490+
}
491+
458492
static const struct pci_error_handlers ionic_err_handler = {
459493
/* FLR handling */
460494
.reset_prepare = ionic_reset_prepare,
461495
.reset_done = ionic_reset_done,
496+
497+
/* PCI bus error detected on this device */
498+
.error_detected = ionic_pci_error_detected,
499+
.resume = ionic_pci_error_resume,
500+
462501
};
463502

464503
static struct pci_driver ionic_driver = {

drivers/net/ethernet/pensando/ionic/ionic_debugfs.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,9 @@ void ionic_debugfs_add_lif(struct ionic_lif *lif)
287287

288288
void ionic_debugfs_del_lif(struct ionic_lif *lif)
289289
{
290+
if (!lif->dentry)
291+
return;
292+
290293
debugfs_remove_recursive(lif->dentry);
291294
lif->dentry = NULL;
292295
}

drivers/net/ethernet/pensando/ionic/ionic_dev.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -165,16 +165,31 @@ void ionic_dev_teardown(struct ionic *ionic)
165165
}
166166

167167
/* Devcmd Interface */
168-
bool ionic_is_fw_running(struct ionic_dev *idev)
168+
static bool __ionic_is_fw_running(struct ionic_dev *idev, u8 *status_ptr)
169169
{
170-
u8 fw_status = ioread8(&idev->dev_info_regs->fw_status);
170+
u8 fw_status;
171+
172+
if (!idev->dev_info_regs) {
173+
if (status_ptr)
174+
*status_ptr = 0xff;
175+
return false;
176+
}
177+
178+
fw_status = ioread8(&idev->dev_info_regs->fw_status);
179+
if (status_ptr)
180+
*status_ptr = fw_status;
171181

172182
/* firmware is useful only if the running bit is set and
173183
* fw_status != 0xff (bad PCI read)
174184
*/
175185
return (fw_status != 0xff) && (fw_status & IONIC_FW_STS_F_RUNNING);
176186
}
177187

188+
bool ionic_is_fw_running(struct ionic_dev *idev)
189+
{
190+
return __ionic_is_fw_running(idev, NULL);
191+
}
192+
178193
int ionic_heartbeat_check(struct ionic *ionic)
179194
{
180195
unsigned long check_time, last_check_time;
@@ -199,10 +214,8 @@ int ionic_heartbeat_check(struct ionic *ionic)
199214
goto do_check_time;
200215
}
201216

202-
fw_status = ioread8(&idev->dev_info_regs->fw_status);
203-
204217
/* If fw_status is not ready don't bother with the generation */
205-
if (!ionic_is_fw_running(idev)) {
218+
if (!__ionic_is_fw_running(idev, &fw_status)) {
206219
fw_status_ready = false;
207220
} else {
208221
fw_generation = fw_status & IONIC_FW_STS_F_GENERATION;
@@ -321,6 +334,7 @@ void ionic_dev_cmd_comp(struct ionic_dev *idev, union ionic_dev_cmd_comp *comp)
321334

322335
void ionic_dev_cmd_go(struct ionic_dev *idev, union ionic_dev_cmd *cmd)
323336
{
337+
idev->opcode = cmd->cmd.opcode;
324338
memcpy_toio(&idev->dev_cmd_regs->cmd, cmd, sizeof(*cmd));
325339
iowrite32(0, &idev->dev_cmd_regs->done);
326340
iowrite32(1, &idev->dev_cmd_regs->doorbell);

drivers/net/ethernet/pensando/ionic/ionic_dev.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ struct ionic_dev {
153153
bool fw_hb_ready;
154154
bool fw_status_ready;
155155
u8 fw_generation;
156+
u8 opcode;
156157

157158
u64 __iomem *db_pages;
158159
dma_addr_t phy_db_pages;

drivers/net/ethernet/pensando/ionic/ionic_lif.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3161,6 +3161,9 @@ static void ionic_lif_reset(struct ionic_lif *lif)
31613161
{
31623162
struct ionic_dev *idev = &lif->ionic->idev;
31633163

3164+
if (!ionic_is_fw_running(idev))
3165+
return;
3166+
31643167
mutex_lock(&lif->ionic->dev_cmd_lock);
31653168
ionic_dev_cmd_lif_reset(idev, lif->index);
31663169
ionic_dev_cmd_wait(lif->ionic, DEVCMD_TIMEOUT);

drivers/net/ethernet/pensando/ionic/ionic_main.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -388,22 +388,28 @@ int ionic_adminq_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx,
388388
do_msg);
389389
}
390390

391-
int ionic_adminq_post_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
391+
static int __ionic_adminq_post_wait(struct ionic_lif *lif,
392+
struct ionic_admin_ctx *ctx,
393+
const bool do_msg)
392394
{
393395
int err;
394396

397+
if (!ionic_is_fw_running(&lif->ionic->idev))
398+
return 0;
399+
395400
err = ionic_adminq_post(lif, ctx);
396401

397-
return ionic_adminq_wait(lif, ctx, err, true);
402+
return ionic_adminq_wait(lif, ctx, err, do_msg);
398403
}
399404

400-
int ionic_adminq_post_wait_nomsg(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
405+
int ionic_adminq_post_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
401406
{
402-
int err;
403-
404-
err = ionic_adminq_post(lif, ctx);
407+
return __ionic_adminq_post_wait(lif, ctx, true);
408+
}
405409

406-
return ionic_adminq_wait(lif, ctx, err, false);
410+
int ionic_adminq_post_wait_nomsg(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
411+
{
412+
return __ionic_adminq_post_wait(lif, ctx, false);
407413
}
408414

409415
static void ionic_dev_cmd_clean(struct ionic *ionic)
@@ -443,7 +449,7 @@ static int __ionic_dev_cmd_wait(struct ionic *ionic, unsigned long max_seconds,
443449
*/
444450
max_wait = jiffies + (max_seconds * HZ);
445451
try_again:
446-
opcode = readb(&idev->dev_cmd_regs->cmd.cmd.opcode);
452+
opcode = idev->opcode;
447453
start_time = jiffies;
448454
for (fw_up = ionic_is_fw_running(idev);
449455
!done && fw_up && time_before(jiffies, max_wait);

0 commit comments

Comments
 (0)