@@ -1140,6 +1140,14 @@ static int bnxt_discard_rx(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
1140
1140
return 0 ;
1141
1141
}
1142
1142
1143
+ static void bnxt_queue_fw_reset_work (struct bnxt * bp , unsigned long delay )
1144
+ {
1145
+ if (BNXT_PF (bp ))
1146
+ queue_delayed_work (bnxt_pf_wq , & bp -> fw_reset_task , delay );
1147
+ else
1148
+ schedule_delayed_work (& bp -> fw_reset_task , delay );
1149
+ }
1150
+
1143
1151
static void bnxt_queue_sp_work (struct bnxt * bp )
1144
1152
{
1145
1153
if (BNXT_PF (bp ))
@@ -6355,6 +6363,8 @@ static int bnxt_hwrm_func_qcfg(struct bnxt *bp)
6355
6363
struct bnxt_vf_info * vf = & bp -> vf ;
6356
6364
6357
6365
vf -> vlan = le16_to_cpu (resp -> vlan ) & VLAN_VID_MASK ;
6366
+ } else {
6367
+ bp -> pf .registered_vfs = le16_to_cpu (resp -> registered_vfs );
6358
6368
}
6359
6369
#endif
6360
6370
flags = le16_to_cpu (resp -> flags );
@@ -9980,6 +9990,53 @@ static void bnxt_reset(struct bnxt *bp, bool silent)
9980
9990
bnxt_rtnl_unlock_sp (bp );
9981
9991
}
9982
9992
9993
+ static void bnxt_fw_reset_close (struct bnxt * bp )
9994
+ {
9995
+ __bnxt_close_nic (bp , true, false);
9996
+ bnxt_ulp_irq_stop (bp );
9997
+ bnxt_clear_int_mode (bp );
9998
+ bnxt_hwrm_func_drv_unrgtr (bp );
9999
+ bnxt_free_ctx_mem (bp );
10000
+ kfree (bp -> ctx );
10001
+ bp -> ctx = NULL ;
10002
+ }
10003
+
10004
+ void bnxt_fw_reset (struct bnxt * bp )
10005
+ {
10006
+ int rc ;
10007
+
10008
+ bnxt_rtnl_lock_sp (bp );
10009
+ if (test_bit (BNXT_STATE_OPEN , & bp -> state ) &&
10010
+ !test_bit (BNXT_STATE_IN_FW_RESET , & bp -> state )) {
10011
+ set_bit (BNXT_STATE_IN_FW_RESET , & bp -> state );
10012
+ if (BNXT_PF (bp ) && bp -> pf .active_vfs ) {
10013
+ rc = bnxt_hwrm_func_qcfg (bp );
10014
+ if (rc ) {
10015
+ netdev_err (bp -> dev , "Firmware reset aborted, first func_qcfg cmd failed, rc = %d\n" ,
10016
+ rc );
10017
+ clear_bit (BNXT_STATE_IN_FW_RESET , & bp -> state );
10018
+ dev_close (bp -> dev );
10019
+ goto fw_reset_exit ;
10020
+ }
10021
+ if (bp -> pf .registered_vfs || bp -> sriov_cfg ) {
10022
+ u16 vf_tmo_dsecs = bp -> pf .registered_vfs * 10 ;
10023
+
10024
+ if (bp -> fw_reset_max_dsecs < vf_tmo_dsecs )
10025
+ bp -> fw_reset_max_dsecs = vf_tmo_dsecs ;
10026
+ bp -> fw_reset_state =
10027
+ BNXT_FW_RESET_STATE_POLL_VF ;
10028
+ bnxt_queue_fw_reset_work (bp , HZ / 10 );
10029
+ goto fw_reset_exit ;
10030
+ }
10031
+ }
10032
+ bnxt_fw_reset_close (bp );
10033
+ bp -> fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV ;
10034
+ bnxt_queue_fw_reset_work (bp , bp -> fw_reset_min_dsecs * HZ / 10 );
10035
+ }
10036
+ fw_reset_exit :
10037
+ bnxt_rtnl_unlock_sp (bp );
10038
+ }
10039
+
9983
10040
static void bnxt_chk_missed_irq (struct bnxt * bp )
9984
10041
{
9985
10042
int i ;
@@ -10339,6 +10396,98 @@ static int bnxt_fw_init_one(struct bnxt *bp)
10339
10396
return 0 ;
10340
10397
}
10341
10398
10399
+ static void bnxt_fw_reset_task (struct work_struct * work )
10400
+ {
10401
+ struct bnxt * bp = container_of (work , struct bnxt , fw_reset_task .work );
10402
+ int rc ;
10403
+
10404
+ if (!test_bit (BNXT_STATE_IN_FW_RESET , & bp -> state )) {
10405
+ netdev_err (bp -> dev , "bnxt_fw_reset_task() called when not in fw reset mode!\n" );
10406
+ return ;
10407
+ }
10408
+
10409
+ switch (bp -> fw_reset_state ) {
10410
+ case BNXT_FW_RESET_STATE_POLL_VF :
10411
+ rc = bnxt_hwrm_func_qcfg (bp );
10412
+ if (rc ) {
10413
+ netdev_err (bp -> dev , "Firmware reset aborted, subsequent func_qcfg cmd failed, rc = %d, %d msecs since reset timestamp\n" ,
10414
+ rc , jiffies_to_msecs (jiffies -
10415
+ bp -> fw_reset_timestamp ));
10416
+ goto fw_reset_abort ;
10417
+ }
10418
+ if (bp -> pf .registered_vfs || bp -> sriov_cfg ) {
10419
+ if (time_after (jiffies , bp -> fw_reset_timestamp +
10420
+ (bp -> fw_reset_max_dsecs * HZ / 10 ))) {
10421
+ clear_bit (BNXT_STATE_IN_FW_RESET , & bp -> state );
10422
+ bp -> fw_reset_state = 0 ;
10423
+ netdev_err (bp -> dev , "Firmware reset aborted, %d VFs still registered, sriov_cfg %d\n" ,
10424
+ bp -> pf .registered_vfs ,
10425
+ bp -> sriov_cfg );
10426
+ return ;
10427
+ }
10428
+ bnxt_queue_fw_reset_work (bp , HZ / 10 );
10429
+ return ;
10430
+ }
10431
+ bp -> fw_reset_timestamp = jiffies ;
10432
+ rtnl_lock ();
10433
+ bnxt_fw_reset_close (bp );
10434
+ bp -> fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV ;
10435
+ rtnl_unlock ();
10436
+ bnxt_queue_fw_reset_work (bp , bp -> fw_reset_min_dsecs * HZ / 10 );
10437
+ return ;
10438
+ case BNXT_FW_RESET_STATE_ENABLE_DEV :
10439
+ if (pci_enable_device (bp -> pdev )) {
10440
+ netdev_err (bp -> dev , "Cannot re-enable PCI device\n" );
10441
+ goto fw_reset_abort ;
10442
+ }
10443
+ pci_set_master (bp -> pdev );
10444
+ bp -> fw_reset_state = BNXT_FW_RESET_STATE_POLL_FW ;
10445
+ /* fall through */
10446
+ case BNXT_FW_RESET_STATE_POLL_FW :
10447
+ bp -> hwrm_cmd_timeout = SHORT_HWRM_CMD_TIMEOUT ;
10448
+ rc = __bnxt_hwrm_ver_get (bp , true);
10449
+ if (rc ) {
10450
+ if (time_after (jiffies , bp -> fw_reset_timestamp +
10451
+ (bp -> fw_reset_max_dsecs * HZ / 10 ))) {
10452
+ netdev_err (bp -> dev , "Firmware reset aborted\n" );
10453
+ goto fw_reset_abort ;
10454
+ }
10455
+ bnxt_queue_fw_reset_work (bp , HZ / 5 );
10456
+ return ;
10457
+ }
10458
+ bp -> hwrm_cmd_timeout = DFLT_HWRM_CMD_TIMEOUT ;
10459
+ bp -> fw_reset_state = BNXT_FW_RESET_STATE_OPENING ;
10460
+ /* fall through */
10461
+ case BNXT_FW_RESET_STATE_OPENING :
10462
+ while (!rtnl_trylock ()) {
10463
+ bnxt_queue_fw_reset_work (bp , HZ / 10 );
10464
+ return ;
10465
+ }
10466
+ rc = bnxt_open (bp -> dev );
10467
+ if (rc ) {
10468
+ netdev_err (bp -> dev , "bnxt_open_nic() failed\n" );
10469
+ clear_bit (BNXT_STATE_IN_FW_RESET , & bp -> state );
10470
+ dev_close (bp -> dev );
10471
+ }
10472
+ bnxt_ulp_irq_restart (bp , rc );
10473
+ rtnl_unlock ();
10474
+
10475
+ bp -> fw_reset_state = 0 ;
10476
+ /* Make sure fw_reset_state is 0 before clearing the flag */
10477
+ smp_mb__before_atomic ();
10478
+ clear_bit (BNXT_STATE_IN_FW_RESET , & bp -> state );
10479
+ break ;
10480
+ }
10481
+ return ;
10482
+
10483
+ fw_reset_abort :
10484
+ clear_bit (BNXT_STATE_IN_FW_RESET , & bp -> state );
10485
+ bp -> fw_reset_state = 0 ;
10486
+ rtnl_lock ();
10487
+ dev_close (bp -> dev );
10488
+ rtnl_unlock ();
10489
+ }
10490
+
10342
10491
static int bnxt_init_board (struct pci_dev * pdev , struct net_device * dev )
10343
10492
{
10344
10493
int rc ;
@@ -10401,6 +10550,7 @@ static int bnxt_init_board(struct pci_dev *pdev, struct net_device *dev)
10401
10550
pci_enable_pcie_error_reporting (pdev );
10402
10551
10403
10552
INIT_WORK (& bp -> sp_task , bnxt_sp_task );
10553
+ INIT_DELAYED_WORK (& bp -> fw_reset_task , bnxt_fw_reset_task );
10404
10554
10405
10555
spin_lock_init (& bp -> ntp_fltr_lock );
10406
10556
#if BITS_PER_LONG == 32
0 commit comments