@@ -2529,38 +2529,31 @@ static int ena_enable_msix_and_set_admin_interrupts(struct ena_adapter *adapter,
2529
2529
return rc ;
2530
2530
}
2531
2531
2532
- static void ena_fw_reset_device (struct work_struct * work )
2532
+ static void ena_destroy_device (struct ena_adapter * adapter )
2533
2533
{
2534
- struct ena_com_dev_get_features_ctx get_feat_ctx ;
2535
- struct ena_adapter * adapter =
2536
- container_of (work , struct ena_adapter , reset_task );
2537
2534
struct net_device * netdev = adapter -> netdev ;
2538
2535
struct ena_com_dev * ena_dev = adapter -> ena_dev ;
2539
- struct pci_dev * pdev = adapter -> pdev ;
2540
- bool dev_up , wd_state ;
2541
- int rc ;
2542
-
2543
- if (unlikely (!test_bit (ENA_FLAG_TRIGGER_RESET , & adapter -> flags ))) {
2544
- dev_err (& pdev -> dev ,
2545
- "device reset schedule while reset bit is off\n" );
2546
- return ;
2547
- }
2536
+ bool dev_up ;
2548
2537
2549
2538
netif_carrier_off (netdev );
2550
2539
2551
2540
del_timer_sync (& adapter -> timer_service );
2552
2541
2553
- rtnl_lock ();
2554
-
2555
2542
dev_up = test_bit (ENA_FLAG_DEV_UP , & adapter -> flags );
2543
+ adapter -> dev_up_before_reset = dev_up ;
2544
+
2556
2545
ena_com_set_admin_running_state (ena_dev , false);
2557
2546
2558
- /* After calling ena_close the tx queues and the napi
2559
- * are disabled so no one can interfere or touch the
2560
- * data structures
2561
- */
2562
2547
ena_close (netdev );
2563
2548
2549
+ /* Before releasing the ENA resources, a device reset is required.
2550
+ * (to prevent the device from accessing them).
2551
+ * In case the reset flag is set and the device is up, ena_close
2552
+ * already perform the reset, so it can be skipped.
2553
+ */
2554
+ if (!(test_bit (ENA_FLAG_TRIGGER_RESET , & adapter -> flags ) && dev_up ))
2555
+ ena_com_dev_reset (adapter -> ena_dev , adapter -> reset_reason );
2556
+
2564
2557
ena_free_mgmnt_irq (adapter );
2565
2558
2566
2559
ena_disable_msix (adapter );
@@ -2574,9 +2567,17 @@ static void ena_fw_reset_device(struct work_struct *work)
2574
2567
ena_com_mmio_reg_read_request_destroy (ena_dev );
2575
2568
2576
2569
adapter -> reset_reason = ENA_REGS_RESET_NORMAL ;
2570
+
2577
2571
clear_bit (ENA_FLAG_TRIGGER_RESET , & adapter -> flags );
2572
+ }
2578
2573
2579
- /* Finish with the destroy part. Start the init part */
2574
+ static int ena_restore_device (struct ena_adapter * adapter )
2575
+ {
2576
+ struct ena_com_dev_get_features_ctx get_feat_ctx ;
2577
+ struct ena_com_dev * ena_dev = adapter -> ena_dev ;
2578
+ struct pci_dev * pdev = adapter -> pdev ;
2579
+ bool wd_state ;
2580
+ int rc ;
2580
2581
2581
2582
rc = ena_device_init (ena_dev , adapter -> pdev , & get_feat_ctx , & wd_state );
2582
2583
if (rc ) {
@@ -2598,7 +2599,7 @@ static void ena_fw_reset_device(struct work_struct *work)
2598
2599
goto err_device_destroy ;
2599
2600
}
2600
2601
/* If the interface was up before the reset bring it up */
2601
- if (dev_up ) {
2602
+ if (adapter -> dev_up_before_reset ) {
2602
2603
rc = ena_up (adapter );
2603
2604
if (rc ) {
2604
2605
dev_err (& pdev -> dev , "Failed to create I/O queues\n" );
@@ -2607,24 +2608,38 @@ static void ena_fw_reset_device(struct work_struct *work)
2607
2608
}
2608
2609
2609
2610
mod_timer (& adapter -> timer_service , round_jiffies (jiffies + HZ ));
2610
-
2611
- rtnl_unlock ();
2612
-
2613
2611
dev_err (& pdev -> dev , "Device reset completed successfully\n" );
2614
2612
2615
- return ;
2613
+ return rc ;
2616
2614
err_disable_msix :
2617
2615
ena_free_mgmnt_irq (adapter );
2618
2616
ena_disable_msix (adapter );
2619
2617
err_device_destroy :
2620
2618
ena_com_admin_destroy (ena_dev );
2621
2619
err :
2622
- rtnl_unlock ();
2623
-
2624
2620
clear_bit (ENA_FLAG_DEVICE_RUNNING , & adapter -> flags );
2625
2621
2626
2622
dev_err (& pdev -> dev ,
2627
2623
"Reset attempt failed. Can not reset the device\n" );
2624
+
2625
+ return rc ;
2626
+ }
2627
+
2628
+ static void ena_fw_reset_device (struct work_struct * work )
2629
+ {
2630
+ struct ena_adapter * adapter =
2631
+ container_of (work , struct ena_adapter , reset_task );
2632
+ struct pci_dev * pdev = adapter -> pdev ;
2633
+
2634
+ if (unlikely (!test_bit (ENA_FLAG_TRIGGER_RESET , & adapter -> flags ))) {
2635
+ dev_err (& pdev -> dev ,
2636
+ "device reset schedule while reset bit is off\n" );
2637
+ return ;
2638
+ }
2639
+ rtnl_lock ();
2640
+ ena_destroy_device (adapter );
2641
+ ena_restore_device (adapter );
2642
+ rtnl_unlock ();
2628
2643
}
2629
2644
2630
2645
static int check_missing_comp_in_queue (struct ena_adapter * adapter ,
@@ -3378,11 +3393,59 @@ static void ena_remove(struct pci_dev *pdev)
3378
3393
vfree (ena_dev );
3379
3394
}
3380
3395
3396
+ #ifdef CONFIG_PM
3397
+ /* ena_suspend - PM suspend callback
3398
+ * @pdev: PCI device information struct
3399
+ * @state:power state
3400
+ */
3401
+ static int ena_suspend (struct pci_dev * pdev , pm_message_t state )
3402
+ {
3403
+ struct ena_adapter * adapter = pci_get_drvdata (pdev );
3404
+
3405
+ u64_stats_update_begin (& adapter -> syncp );
3406
+ adapter -> dev_stats .suspend ++ ;
3407
+ u64_stats_update_end (& adapter -> syncp );
3408
+
3409
+ rtnl_lock ();
3410
+ if (unlikely (test_bit (ENA_FLAG_TRIGGER_RESET , & adapter -> flags ))) {
3411
+ dev_err (& pdev -> dev ,
3412
+ "ignoring device reset request as the device is being suspended\n" );
3413
+ clear_bit (ENA_FLAG_TRIGGER_RESET , & adapter -> flags );
3414
+ }
3415
+ ena_destroy_device (adapter );
3416
+ rtnl_unlock ();
3417
+ return 0 ;
3418
+ }
3419
+
3420
+ /* ena_resume - PM resume callback
3421
+ * @pdev: PCI device information struct
3422
+ *
3423
+ */
3424
+ static int ena_resume (struct pci_dev * pdev )
3425
+ {
3426
+ struct ena_adapter * adapter = pci_get_drvdata (pdev );
3427
+ int rc ;
3428
+
3429
+ u64_stats_update_begin (& adapter -> syncp );
3430
+ adapter -> dev_stats .resume ++ ;
3431
+ u64_stats_update_end (& adapter -> syncp );
3432
+
3433
+ rtnl_lock ();
3434
+ rc = ena_restore_device (adapter );
3435
+ rtnl_unlock ();
3436
+ return rc ;
3437
+ }
3438
+ #endif
3439
+
3381
3440
static struct pci_driver ena_pci_driver = {
3382
3441
.name = DRV_MODULE_NAME ,
3383
3442
.id_table = ena_pci_tbl ,
3384
3443
.probe = ena_probe ,
3385
3444
.remove = ena_remove ,
3445
+ #ifdef CONFIG_PM
3446
+ .suspend = ena_suspend ,
3447
+ .resume = ena_resume ,
3448
+ #endif
3386
3449
.sriov_configure = ena_sriov_configure ,
3387
3450
};
3388
3451
0 commit comments