Skip to content

Commit 5322a27

Browse files
committed
Merge branch 'ionic-FLR-support'
Shannon Nelson says: ==================== ionic: add FLR support Add support for handing and recovering from a PCI FLR event. This patchset first moves some code around to make it usable from multiple paths, then adds the PCI error handler callbacks for reset_prepare and reset_done. Example test: echo 1 > /sys/bus/pci/devices/0000:2a:00.0/reset v4: - don't remove ionic_dev_teardown() in ionic_probe() in patch 2/4 - remove clear_bit() change from patch 3/4 v3: Link: https://lore.kernel.org/netdev/[email protected]/ - removed first patch, it is already merged into net v2: Link: https://lore.kernel.org/netdev/[email protected]/ - removed redundant pci_save/restore_state() calls ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 67a8976 + a79b559 commit 5322a27

File tree

3 files changed

+164
-71
lines changed

3 files changed

+164
-71
lines changed

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

Lines changed: 114 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -213,29 +213,18 @@ static int ionic_sriov_configure(struct pci_dev *pdev, int num_vfs)
213213
return ret;
214214
}
215215

216-
static int ionic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
216+
static void ionic_clear_pci(struct ionic *ionic)
217217
{
218-
struct device *dev = &pdev->dev;
219-
struct ionic *ionic;
220-
int num_vfs;
221-
int err;
222-
223-
ionic = ionic_devlink_alloc(dev);
224-
if (!ionic)
225-
return -ENOMEM;
226-
227-
ionic->pdev = pdev;
228-
ionic->dev = dev;
229-
pci_set_drvdata(pdev, ionic);
230-
mutex_init(&ionic->dev_cmd_lock);
218+
ionic_unmap_bars(ionic);
219+
pci_release_regions(ionic->pdev);
220+
pci_disable_device(ionic->pdev);
221+
}
231222

232-
/* Query system for DMA addressing limitation for the device. */
233-
err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(IONIC_ADDR_LEN));
234-
if (err) {
235-
dev_err(dev, "Unable to obtain 64-bit DMA for consistent allocations, aborting. err=%d\n",
236-
err);
237-
goto err_out_clear_drvdata;
238-
}
223+
static int ionic_setup_one(struct ionic *ionic)
224+
{
225+
struct pci_dev *pdev = ionic->pdev;
226+
struct device *dev = ionic->dev;
227+
int err;
239228

240229
ionic_debugfs_add_dev(ionic);
241230

@@ -249,20 +238,19 @@ static int ionic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
249238
err = pci_request_regions(pdev, IONIC_DRV_NAME);
250239
if (err) {
251240
dev_err(dev, "Cannot request PCI regions: %d, aborting\n", err);
252-
goto err_out_pci_disable_device;
241+
goto err_out_clear_pci;
253242
}
254-
255243
pcie_print_link_status(pdev);
256244

257245
err = ionic_map_bars(ionic);
258246
if (err)
259-
goto err_out_pci_release_regions;
247+
goto err_out_clear_pci;
260248

261249
/* Configure the device */
262250
err = ionic_setup(ionic);
263251
if (err) {
264252
dev_err(dev, "Cannot setup device: %d, aborting\n", err);
265-
goto err_out_unmap_bars;
253+
goto err_out_clear_pci;
266254
}
267255
pci_set_master(pdev);
268256

@@ -279,24 +267,64 @@ static int ionic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
279267
goto err_out_teardown;
280268
}
281269

282-
/* Configure the ports */
270+
/* Configure the port */
283271
err = ionic_port_identify(ionic);
284272
if (err) {
285273
dev_err(dev, "Cannot identify port: %d, aborting\n", err);
286-
goto err_out_reset;
274+
goto err_out_teardown;
287275
}
288276

289277
err = ionic_port_init(ionic);
290278
if (err) {
291279
dev_err(dev, "Cannot init port: %d, aborting\n", err);
292-
goto err_out_reset;
280+
goto err_out_teardown;
281+
}
282+
283+
return 0;
284+
285+
err_out_teardown:
286+
ionic_dev_teardown(ionic);
287+
err_out_clear_pci:
288+
ionic_clear_pci(ionic);
289+
err_out_debugfs_del_dev:
290+
ionic_debugfs_del_dev(ionic);
291+
292+
return err;
293+
}
294+
295+
static int ionic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
296+
{
297+
struct device *dev = &pdev->dev;
298+
struct ionic *ionic;
299+
int num_vfs;
300+
int err;
301+
302+
ionic = ionic_devlink_alloc(dev);
303+
if (!ionic)
304+
return -ENOMEM;
305+
306+
ionic->pdev = pdev;
307+
ionic->dev = dev;
308+
pci_set_drvdata(pdev, ionic);
309+
mutex_init(&ionic->dev_cmd_lock);
310+
311+
/* Query system for DMA addressing limitation for the device. */
312+
err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(IONIC_ADDR_LEN));
313+
if (err) {
314+
dev_err(dev, "Unable to obtain 64-bit DMA for consistent allocations, aborting. err=%d\n",
315+
err);
316+
goto err_out;
293317
}
294318

319+
err = ionic_setup_one(ionic);
320+
if (err)
321+
goto err_out;
322+
295323
/* Allocate and init the LIF */
296324
err = ionic_lif_size(ionic);
297325
if (err) {
298326
dev_err(dev, "Cannot size LIF: %d, aborting\n", err);
299-
goto err_out_port_reset;
327+
goto err_out_pci;
300328
}
301329

302330
err = ionic_lif_alloc(ionic);
@@ -347,21 +375,10 @@ static int ionic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
347375
ionic->lif = NULL;
348376
err_out_free_irqs:
349377
ionic_bus_free_irq_vectors(ionic);
350-
err_out_port_reset:
351-
ionic_port_reset(ionic);
352-
err_out_reset:
353-
ionic_reset(ionic);
354-
err_out_teardown:
378+
err_out_pci:
355379
ionic_dev_teardown(ionic);
356-
err_out_unmap_bars:
357-
ionic_unmap_bars(ionic);
358-
err_out_pci_release_regions:
359-
pci_release_regions(pdev);
360-
err_out_pci_disable_device:
361-
pci_disable_device(pdev);
362-
err_out_debugfs_del_dev:
363-
ionic_debugfs_del_dev(ionic);
364-
err_out_clear_drvdata:
380+
ionic_clear_pci(ionic);
381+
err_out:
365382
mutex_destroy(&ionic->dev_cmd_lock);
366383
ionic_devlink_free(ionic);
367384

@@ -386,20 +403,71 @@ static void ionic_remove(struct pci_dev *pdev)
386403
ionic_port_reset(ionic);
387404
ionic_reset(ionic);
388405
ionic_dev_teardown(ionic);
389-
ionic_unmap_bars(ionic);
390-
pci_release_regions(pdev);
391-
pci_disable_device(pdev);
406+
ionic_clear_pci(ionic);
392407
ionic_debugfs_del_dev(ionic);
393408
mutex_destroy(&ionic->dev_cmd_lock);
394409
ionic_devlink_free(ionic);
395410
}
396411

412+
static void ionic_reset_prepare(struct pci_dev *pdev)
413+
{
414+
struct ionic *ionic = pci_get_drvdata(pdev);
415+
struct ionic_lif *lif = ionic->lif;
416+
417+
dev_dbg(ionic->dev, "%s: device stopping\n", __func__);
418+
419+
del_timer_sync(&ionic->watchdog_timer);
420+
cancel_work_sync(&lif->deferred.work);
421+
422+
mutex_lock(&lif->queue_lock);
423+
ionic_stop_queues_reconfig(lif);
424+
ionic_txrx_free(lif);
425+
ionic_lif_deinit(lif);
426+
ionic_qcqs_free(lif);
427+
mutex_unlock(&lif->queue_lock);
428+
429+
ionic_dev_teardown(ionic);
430+
ionic_clear_pci(ionic);
431+
ionic_debugfs_del_dev(ionic);
432+
}
433+
434+
static void ionic_reset_done(struct pci_dev *pdev)
435+
{
436+
struct ionic *ionic = pci_get_drvdata(pdev);
437+
struct ionic_lif *lif = ionic->lif;
438+
int err;
439+
440+
err = ionic_setup_one(ionic);
441+
if (err)
442+
goto err_out;
443+
444+
ionic_debugfs_add_sizes(ionic);
445+
ionic_debugfs_add_lif(ionic->lif);
446+
447+
err = ionic_restart_lif(lif);
448+
if (err)
449+
goto err_out;
450+
451+
mod_timer(&ionic->watchdog_timer, jiffies + 1);
452+
453+
err_out:
454+
dev_dbg(ionic->dev, "%s: device recovery %s\n",
455+
__func__, err ? "failed" : "done");
456+
}
457+
458+
static const struct pci_error_handlers ionic_err_handler = {
459+
/* FLR handling */
460+
.reset_prepare = ionic_reset_prepare,
461+
.reset_done = ionic_reset_done,
462+
};
463+
397464
static struct pci_driver ionic_driver = {
398465
.name = IONIC_DRV_NAME,
399466
.id_table = ionic_id_table,
400467
.probe = ionic_probe,
401468
.remove = ionic_remove,
402469
.sriov_configure = ionic_sriov_configure,
470+
.err_handler = &ionic_err_handler
403471
};
404472

405473
int ionic_bus_register_driver(void)

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

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ static void ionic_qcq_free(struct ionic_lif *lif, struct ionic_qcq *qcq)
434434
}
435435
}
436436

437-
static void ionic_qcqs_free(struct ionic_lif *lif)
437+
void ionic_qcqs_free(struct ionic_lif *lif)
438438
{
439439
struct device *dev = lif->ionic->dev;
440440
struct ionic_qcq *adminqcq;
@@ -1754,7 +1754,7 @@ static int ionic_set_mac_address(struct net_device *netdev, void *sa)
17541754
return ionic_lif_addr_add(netdev_priv(netdev), mac);
17551755
}
17561756

1757-
static void ionic_stop_queues_reconfig(struct ionic_lif *lif)
1757+
void ionic_stop_queues_reconfig(struct ionic_lif *lif)
17581758
{
17591759
/* Stop and clean the queues before reconfiguration */
17601760
netif_device_detach(lif->netdev);
@@ -2009,7 +2009,7 @@ static void ionic_txrx_deinit(struct ionic_lif *lif)
20092009
}
20102010
}
20112011

2012-
static void ionic_txrx_free(struct ionic_lif *lif)
2012+
void ionic_txrx_free(struct ionic_lif *lif)
20132013
{
20142014
unsigned int i;
20152015

@@ -3266,27 +3266,11 @@ static void ionic_lif_handle_fw_down(struct ionic_lif *lif)
32663266
dev_info(ionic->dev, "FW Down: LIFs stopped\n");
32673267
}
32683268

3269-
static void ionic_lif_handle_fw_up(struct ionic_lif *lif)
3269+
int ionic_restart_lif(struct ionic_lif *lif)
32703270
{
32713271
struct ionic *ionic = lif->ionic;
32723272
int err;
32733273

3274-
if (!test_bit(IONIC_LIF_F_FW_RESET, lif->state))
3275-
return;
3276-
3277-
dev_info(ionic->dev, "FW Up: restarting LIFs\n");
3278-
3279-
ionic_init_devinfo(ionic);
3280-
err = ionic_identify(ionic);
3281-
if (err)
3282-
goto err_out;
3283-
err = ionic_port_identify(ionic);
3284-
if (err)
3285-
goto err_out;
3286-
err = ionic_port_init(ionic);
3287-
if (err)
3288-
goto err_out;
3289-
32903274
mutex_lock(&lif->queue_lock);
32913275

32923276
if (test_and_clear_bit(IONIC_LIF_F_BROKEN, lif->state))
@@ -3322,12 +3306,8 @@ static void ionic_lif_handle_fw_up(struct ionic_lif *lif)
33223306
clear_bit(IONIC_LIF_F_FW_RESET, lif->state);
33233307
ionic_link_status_check_request(lif, CAN_SLEEP);
33243308
netif_device_attach(lif->netdev);
3325-
dev_info(ionic->dev, "FW Up: LIFs restarted\n");
3326-
3327-
/* restore the hardware timestamping queues */
3328-
ionic_lif_hwstamp_replay(lif);
33293309

3330-
return;
3310+
return 0;
33313311

33323312
err_txrx_free:
33333313
ionic_txrx_free(lif);
@@ -3337,6 +3317,46 @@ static void ionic_lif_handle_fw_up(struct ionic_lif *lif)
33373317
ionic_qcqs_free(lif);
33383318
err_unlock:
33393319
mutex_unlock(&lif->queue_lock);
3320+
3321+
return err;
3322+
}
3323+
3324+
static void ionic_lif_handle_fw_up(struct ionic_lif *lif)
3325+
{
3326+
struct ionic *ionic = lif->ionic;
3327+
int err;
3328+
3329+
if (!test_bit(IONIC_LIF_F_FW_RESET, lif->state))
3330+
return;
3331+
3332+
dev_info(ionic->dev, "FW Up: restarting LIFs\n");
3333+
3334+
/* This is a little different from what happens at
3335+
* probe time because the LIF already exists so we
3336+
* just need to reanimate it.
3337+
*/
3338+
ionic_init_devinfo(ionic);
3339+
err = ionic_identify(ionic);
3340+
if (err)
3341+
goto err_out;
3342+
err = ionic_port_identify(ionic);
3343+
if (err)
3344+
goto err_out;
3345+
err = ionic_port_init(ionic);
3346+
if (err)
3347+
goto err_out;
3348+
3349+
err = ionic_restart_lif(lif);
3350+
if (err)
3351+
goto err_out;
3352+
3353+
dev_info(ionic->dev, "FW Up: LIFs restarted\n");
3354+
3355+
/* restore the hardware timestamping queues */
3356+
ionic_lif_hwstamp_replay(lif);
3357+
3358+
return;
3359+
33403360
err_out:
33413361
dev_err(ionic->dev, "FW Up: LIFs restart failed - err %d\n", err);
33423362
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,11 @@ void ionic_lif_deinit(struct ionic_lif *lif);
325325
int ionic_lif_addr_add(struct ionic_lif *lif, const u8 *addr);
326326
int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr);
327327

328+
void ionic_stop_queues_reconfig(struct ionic_lif *lif);
329+
void ionic_txrx_free(struct ionic_lif *lif);
330+
void ionic_qcqs_free(struct ionic_lif *lif);
331+
int ionic_restart_lif(struct ionic_lif *lif);
332+
328333
int ionic_lif_register(struct ionic_lif *lif);
329334
void ionic_lif_unregister(struct ionic_lif *lif);
330335
int ionic_lif_identify(struct ionic *ionic, u8 lif_type,

0 commit comments

Comments
 (0)