@@ -6947,6 +6947,8 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp)
6947
6947
bp -> fw_cap |= BNXT_FW_CAP_EXT_STATS_SUPPORTED ;
6948
6948
if (flags & FUNC_QCAPS_RESP_FLAGS_ERROR_RECOVERY_CAPABLE )
6949
6949
bp -> fw_cap |= BNXT_FW_CAP_ERROR_RECOVERY ;
6950
+ if (flags & FUNC_QCAPS_RESP_FLAGS_ERR_RECOVER_RELOAD )
6951
+ bp -> fw_cap |= BNXT_FW_CAP_ERR_RECOVER_RELOAD ;
6950
6952
6951
6953
bp -> tx_push_thresh = 0 ;
6952
6954
if (flags & FUNC_QCAPS_RESP_FLAGS_PUSH_MODE_SUPPORTED )
@@ -10097,6 +10099,8 @@ static void bnxt_force_fw_reset(struct bnxt *bp)
10097
10099
wait_dsecs = fw_health -> normal_func_wait_dsecs ;
10098
10100
bp -> fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV ;
10099
10101
}
10102
+
10103
+ bp -> fw_reset_min_dsecs = fw_health -> post_reset_wait_dsecs ;
10100
10104
bp -> fw_reset_max_dsecs = fw_health -> post_reset_max_wait_dsecs ;
10101
10105
bnxt_queue_fw_reset_work (bp , wait_dsecs * HZ / 10 );
10102
10106
}
@@ -10138,7 +10142,7 @@ void bnxt_fw_reset(struct bnxt *bp)
10138
10142
bnxt_rtnl_lock_sp (bp );
10139
10143
if (test_bit (BNXT_STATE_OPEN , & bp -> state ) &&
10140
10144
!test_bit (BNXT_STATE_IN_FW_RESET , & bp -> state )) {
10141
- int n = 0 ;
10145
+ int n = 0 , tmo ;
10142
10146
10143
10147
set_bit (BNXT_STATE_IN_FW_RESET , & bp -> state );
10144
10148
if (bp -> pf .active_vfs &&
@@ -10161,8 +10165,14 @@ void bnxt_fw_reset(struct bnxt *bp)
10161
10165
goto fw_reset_exit ;
10162
10166
}
10163
10167
bnxt_fw_reset_close (bp );
10164
- bp -> fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV ;
10165
- bnxt_queue_fw_reset_work (bp , bp -> fw_reset_min_dsecs * HZ / 10 );
10168
+ if (bp -> fw_cap & BNXT_FW_CAP_ERR_RECOVER_RELOAD ) {
10169
+ bp -> fw_reset_state = BNXT_FW_RESET_STATE_POLL_FW_DOWN ;
10170
+ tmo = HZ / 10 ;
10171
+ } else {
10172
+ bp -> fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV ;
10173
+ tmo = bp -> fw_reset_min_dsecs * HZ / 10 ;
10174
+ }
10175
+ bnxt_queue_fw_reset_work (bp , tmo );
10166
10176
}
10167
10177
fw_reset_exit :
10168
10178
bnxt_rtnl_unlock_sp (bp );
@@ -10605,6 +10615,7 @@ static void bnxt_fw_reset_task(struct work_struct *work)
10605
10615
switch (bp -> fw_reset_state ) {
10606
10616
case BNXT_FW_RESET_STATE_POLL_VF : {
10607
10617
int n = bnxt_get_registered_vfs (bp );
10618
+ int tmo ;
10608
10619
10609
10620
if (n < 0 ) {
10610
10621
netdev_err (bp -> dev , "Firmware reset aborted, subsequent func_qcfg cmd failed, rc = %d, %d msecs since reset timestamp\n" ,
@@ -10626,11 +10637,38 @@ static void bnxt_fw_reset_task(struct work_struct *work)
10626
10637
bp -> fw_reset_timestamp = jiffies ;
10627
10638
rtnl_lock ();
10628
10639
bnxt_fw_reset_close (bp );
10629
- bp -> fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV ;
10640
+ if (bp -> fw_cap & BNXT_FW_CAP_ERR_RECOVER_RELOAD ) {
10641
+ bp -> fw_reset_state = BNXT_FW_RESET_STATE_POLL_FW_DOWN ;
10642
+ tmo = HZ / 10 ;
10643
+ } else {
10644
+ bp -> fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV ;
10645
+ tmo = bp -> fw_reset_min_dsecs * HZ / 10 ;
10646
+ }
10630
10647
rtnl_unlock ();
10631
- bnxt_queue_fw_reset_work (bp , bp -> fw_reset_min_dsecs * HZ / 10 );
10648
+ bnxt_queue_fw_reset_work (bp , tmo );
10632
10649
return ;
10633
10650
}
10651
+ case BNXT_FW_RESET_STATE_POLL_FW_DOWN : {
10652
+ u32 val ;
10653
+
10654
+ val = bnxt_fw_health_readl (bp , BNXT_FW_HEALTH_REG );
10655
+ if (!(val & BNXT_FW_STATUS_SHUTDOWN ) &&
10656
+ !time_after (jiffies , bp -> fw_reset_timestamp +
10657
+ (bp -> fw_reset_max_dsecs * HZ / 10 ))) {
10658
+ bnxt_queue_fw_reset_work (bp , HZ / 5 );
10659
+ return ;
10660
+ }
10661
+
10662
+ if (!bp -> fw_health -> master ) {
10663
+ u32 wait_dsecs = bp -> fw_health -> normal_func_wait_dsecs ;
10664
+
10665
+ bp -> fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV ;
10666
+ bnxt_queue_fw_reset_work (bp , wait_dsecs * HZ / 10 );
10667
+ return ;
10668
+ }
10669
+ bp -> fw_reset_state = BNXT_FW_RESET_STATE_RESET_FW ;
10670
+ }
10671
+ /* fall through */
10634
10672
case BNXT_FW_RESET_STATE_RESET_FW : {
10635
10673
u32 wait_dsecs = bp -> fw_health -> post_reset_wait_dsecs ;
10636
10674
0 commit comments