bnxt_en: Fix possible unintended driver initiated error recovery
authorMichael Chan <michael.chan@broadcom.com>
Sun, 5 Sep 2021 18:10:59 +0000 (14:10 -0400)
committerDavid S. Miller <davem@davemloft.net>
Sun, 5 Sep 2021 19:43:04 +0000 (20:43 +0100)
commit1b2b91831983aeac3adcbb469aa8b0dc71453f89
tree0da193066e0637452ce161f8cc738dc106b8f02b
parent7ae9dc356f247ad9f9634b3da61a45eb72968b2e
bnxt_en: Fix possible unintended driver initiated error recovery

If error recovery is already enabled, bnxt_timer() will periodically
check the heartbeat register and the reset counter.  If we get an
error recovery async. notification from the firmware (e.g. change in
primary/secondary role), we will immediately read and update the
heartbeat register and the reset counter.  If the timer for the next
health check expires soon after this, we may read the heartbeat register
again in quick succession and find that it hasn't changed.  This will
trigger error recovery unintentionally.

The likelihood is small because we also reset fw_health->tmr_counter
which will reset the interval for the next health check.  But the
update is not protected and bnxt_timer() can miss the update and
perform the health check without waiting for the full interval.

Fix it by only reading the heartbeat register and reset counter in
bnxt_async_event_process() if error recovery is trasitioning to the
enabled state.  Also add proper memory barriers so that when enabling
for the first time, bnxt_timer() will see the tmr_counter interval and
perform the health check after the full interval has elapsed.

Fixes: 7e914027f757 ("bnxt_en: Enable health monitoring.")
Reviewed-by: Edwin Peer <edwin.peer@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnxt/bnxt.c