Skip to content

Commit 4037eb7

Browse files
Vasundhara Volamdavem330
authored andcommitted
bnxt_en: Add a new BNXT_FW_RESET_STATE_POLL_FW_DOWN state.
This new state is required when firmware indicates that the error recovery process requires polling for firmware state to be completely down before initiating reset. For example, firmware may take some time to collect the crash dump before it is down and ready to be reset. Signed-off-by: Vasundhara Volam <[email protected]> Signed-off-by: Michael Chan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 72e0c9f commit 4037eb7

File tree

2 files changed

+46
-5
lines changed

2 files changed

+46
-5
lines changed

drivers/net/ethernet/broadcom/bnxt/bnxt.c

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6947,6 +6947,8 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp)
69476947
bp->fw_cap |= BNXT_FW_CAP_EXT_STATS_SUPPORTED;
69486948
if (flags & FUNC_QCAPS_RESP_FLAGS_ERROR_RECOVERY_CAPABLE)
69496949
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;
69506952

69516953
bp->tx_push_thresh = 0;
69526954
if (flags & FUNC_QCAPS_RESP_FLAGS_PUSH_MODE_SUPPORTED)
@@ -10097,6 +10099,8 @@ static void bnxt_force_fw_reset(struct bnxt *bp)
1009710099
wait_dsecs = fw_health->normal_func_wait_dsecs;
1009810100
bp->fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV;
1009910101
}
10102+
10103+
bp->fw_reset_min_dsecs = fw_health->post_reset_wait_dsecs;
1010010104
bp->fw_reset_max_dsecs = fw_health->post_reset_max_wait_dsecs;
1010110105
bnxt_queue_fw_reset_work(bp, wait_dsecs * HZ / 10);
1010210106
}
@@ -10138,7 +10142,7 @@ void bnxt_fw_reset(struct bnxt *bp)
1013810142
bnxt_rtnl_lock_sp(bp);
1013910143
if (test_bit(BNXT_STATE_OPEN, &bp->state) &&
1014010144
!test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) {
10141-
int n = 0;
10145+
int n = 0, tmo;
1014210146

1014310147
set_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
1014410148
if (bp->pf.active_vfs &&
@@ -10161,8 +10165,14 @@ void bnxt_fw_reset(struct bnxt *bp)
1016110165
goto fw_reset_exit;
1016210166
}
1016310167
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);
1016610176
}
1016710177
fw_reset_exit:
1016810178
bnxt_rtnl_unlock_sp(bp);
@@ -10605,6 +10615,7 @@ static void bnxt_fw_reset_task(struct work_struct *work)
1060510615
switch (bp->fw_reset_state) {
1060610616
case BNXT_FW_RESET_STATE_POLL_VF: {
1060710617
int n = bnxt_get_registered_vfs(bp);
10618+
int tmo;
1060810619

1060910620
if (n < 0) {
1061010621
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)
1062610637
bp->fw_reset_timestamp = jiffies;
1062710638
rtnl_lock();
1062810639
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+
}
1063010647
rtnl_unlock();
10631-
bnxt_queue_fw_reset_work(bp, bp->fw_reset_min_dsecs * HZ / 10);
10648+
bnxt_queue_fw_reset_work(bp, tmo);
1063210649
return;
1063310650
}
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 */
1063410672
case BNXT_FW_RESET_STATE_RESET_FW: {
1063510673
u32 wait_dsecs = bp->fw_health->post_reset_wait_dsecs;
1063610674

drivers/net/ethernet/broadcom/bnxt/bnxt.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1398,6 +1398,7 @@ struct bnxt_fw_reporter_ctx {
13981398
#define BNXT_FW_HEALTH_WIN_MAP_OFF 8
13991399

14001400
#define BNXT_FW_STATUS_HEALTHY 0x8000
1401+
#define BNXT_FW_STATUS_SHUTDOWN 0x100000
14011402

14021403
struct bnxt {
14031404
void __iomem *bar0;
@@ -1655,6 +1656,7 @@ struct bnxt {
16551656
#define BNXT_FW_CAP_CFA_RFS_RING_TBL_IDX 0x00010000
16561657
#define BNXT_FW_CAP_PCIE_STATS_SUPPORTED 0x00020000
16571658
#define BNXT_FW_CAP_EXT_STATS_SUPPORTED 0x00040000
1659+
#define BNXT_FW_CAP_ERR_RECOVER_RELOAD 0x00100000
16581660

16591661
#define BNXT_NEW_RM(bp) ((bp)->fw_cap & BNXT_FW_CAP_NEW_RM)
16601662
u32 hwrm_spec_code;
@@ -1744,6 +1746,7 @@ struct bnxt {
17441746
#define BNXT_FW_RESET_STATE_ENABLE_DEV 3
17451747
#define BNXT_FW_RESET_STATE_POLL_FW 4
17461748
#define BNXT_FW_RESET_STATE_OPENING 5
1749+
#define BNXT_FW_RESET_STATE_POLL_FW_DOWN 6
17471750

17481751
u16 fw_reset_min_dsecs;
17491752
#define BNXT_DFLT_FW_RST_MIN_DSECS 20

0 commit comments

Comments
 (0)