Commit d4073028 authored by Vasundhara Volam's avatar Vasundhara Volam Committed by Jakub Kicinski

bnxt_en: Fix logic that disables Bus Master during firmware reset.

The current logic that calls pci_disable_device() in __bnxt_close_nic()
during firmware reset is flawed.  If firmware is still alive, we're
disabling the device too early, causing some firmware commands to
not reach the firmware.

Fix it by moving the logic to bnxt_reset_close().  If firmware is
in fatal condition, we call pci_disable_device() before we free
any of the rings to prevent DMA corruption of the freed rings.  If
firmware is still alive, we call pci_disable_device() after the
last firmware message has been sent.

Fixes: 3bc7d4a3 ("bnxt_en: Add BNXT_STATE_IN_FW_RESET state.")
Signed-off-by: default avatarVasundhara Volam <vasundhara-v.volam@broadcom.com>
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 12de2ead
...@@ -9313,10 +9313,6 @@ static void __bnxt_close_nic(struct bnxt *bp, bool irq_re_init, ...@@ -9313,10 +9313,6 @@ static void __bnxt_close_nic(struct bnxt *bp, bool irq_re_init,
bnxt_debug_dev_exit(bp); bnxt_debug_dev_exit(bp);
bnxt_disable_napi(bp); bnxt_disable_napi(bp);
del_timer_sync(&bp->timer); del_timer_sync(&bp->timer);
if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state) &&
pci_is_enabled(bp->pdev))
pci_disable_device(bp->pdev);
bnxt_free_skbs(bp); bnxt_free_skbs(bp);
/* Save ring stats before shutdown */ /* Save ring stats before shutdown */
...@@ -10102,9 +10098,16 @@ static void bnxt_reset(struct bnxt *bp, bool silent) ...@@ -10102,9 +10098,16 @@ static void bnxt_reset(struct bnxt *bp, bool silent)
static void bnxt_fw_reset_close(struct bnxt *bp) static void bnxt_fw_reset_close(struct bnxt *bp)
{ {
bnxt_ulp_stop(bp); bnxt_ulp_stop(bp);
/* When firmware is fatal state, disable PCI device to prevent
* any potential bad DMAs before freeing kernel memory.
*/
if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state))
pci_disable_device(bp->pdev);
__bnxt_close_nic(bp, true, false); __bnxt_close_nic(bp, true, false);
bnxt_clear_int_mode(bp); bnxt_clear_int_mode(bp);
bnxt_hwrm_func_drv_unrgtr(bp); bnxt_hwrm_func_drv_unrgtr(bp);
if (pci_is_enabled(bp->pdev))
pci_disable_device(bp->pdev);
bnxt_free_ctx_mem(bp); bnxt_free_ctx_mem(bp);
kfree(bp->ctx); kfree(bp->ctx);
bp->ctx = NULL; bp->ctx = NULL;
......
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