Commit eca4cf12 authored by Michael Chan's avatar Michael Chan Committed by David S. Miller

bnxt_en: Fix error recovery regression

The recent patch has introduced a regression by not reading the reset
count in the ERROR_RECOVERY async event handler.  We may have just
gone through a reset and the reset count has just incremented.  If
we don't update the reset count in the ERROR_RECOVERY event handler,
the health check timer will see that the reset count has changed and
will initiate an unintended reset.

Restore the unconditional update of the reset count in
bnxt_async_event_process() if error recovery watchdog is enabled.
Also, update the reset count at the end of the reset sequence to
make it even more robust.

Fixes: 1b2b9183 ("bnxt_en: Fix possible unintended driver initiated error recovery")
Reviewed-by: default avatarEdwin Peer <edwin.peer@broadcom.com>
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f11ee2ad
...@@ -2213,12 +2213,11 @@ static int bnxt_async_event_process(struct bnxt *bp, ...@@ -2213,12 +2213,11 @@ static int bnxt_async_event_process(struct bnxt *bp,
DIV_ROUND_UP(fw_health->polling_dsecs * HZ, DIV_ROUND_UP(fw_health->polling_dsecs * HZ,
bp->current_interval * 10); bp->current_interval * 10);
fw_health->tmr_counter = fw_health->tmr_multiplier; fw_health->tmr_counter = fw_health->tmr_multiplier;
if (!fw_health->enabled) { if (!fw_health->enabled)
fw_health->last_fw_heartbeat = fw_health->last_fw_heartbeat =
bnxt_fw_health_readl(bp, BNXT_FW_HEARTBEAT_REG); bnxt_fw_health_readl(bp, BNXT_FW_HEARTBEAT_REG);
fw_health->last_fw_reset_cnt = fw_health->last_fw_reset_cnt =
bnxt_fw_health_readl(bp, BNXT_FW_RESET_CNT_REG); bnxt_fw_health_readl(bp, BNXT_FW_RESET_CNT_REG);
}
netif_info(bp, drv, bp->dev, netif_info(bp, drv, bp->dev,
"Error recovery info: error recovery[1], master[%d], reset count[%u], health status: 0x%x\n", "Error recovery info: error recovery[1], master[%d], reset count[%u], health status: 0x%x\n",
fw_health->master, fw_health->last_fw_reset_cnt, fw_health->master, fw_health->last_fw_reset_cnt,
...@@ -12207,6 +12206,11 @@ static void bnxt_fw_reset_task(struct work_struct *work) ...@@ -12207,6 +12206,11 @@ static void bnxt_fw_reset_task(struct work_struct *work)
return; return;
} }
if ((bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY) &&
bp->fw_health->enabled) {
bp->fw_health->last_fw_reset_cnt =
bnxt_fw_health_readl(bp, BNXT_FW_RESET_CNT_REG);
}
bp->fw_reset_state = 0; bp->fw_reset_state = 0;
/* Make sure fw_reset_state is 0 before clearing the flag */ /* Make sure fw_reset_state is 0 before clearing the flag */
smp_mb__before_atomic(); smp_mb__before_atomic();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment