]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bnxt_en: delay pci_alloc_irq_vectors() in the AER path
authorKashyap Desai <kashyap.desai@broadcom.com>
Mon, 28 Apr 2025 22:59:00 +0000 (15:59 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 30 Apr 2025 12:03:21 +0000 (13:03 +0100)
This patch is similar to the last patch to delay the
pci_alloc_irq_vectors() call in the AER path until after calling
bnxt_reserve_rings().  bnxt_reserve_rings() needs to properly map
the MSIX table first before we call pci_alloc_irq_vectors() which
may immediately write to the MSIX table in some architectures.

Move the bnxt_init_int_mode() call from bnxt_io_slot_reset() to
bnxt_io_resume() after calling bnxt_reserve_rings().

With this change, the AER path may call bnxt_open() ->
bnxt_hwrm_if_change() with bp->irq_tbl set to NULL.  bp->irq_tbl is
cleared when we call bnxt_clear_int_mode() in bnxt_io_slot_reset().
So we cannot use !bp->irq_tbl to detect aborted FW reset.  Add a
new BNXT_FW_RESET_STATE_ABORT to detect aborted FW reset in
bnxt_hwrm_if_change().

Signed-off-by: Kashyap Desai <kashyap.desai@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
drivers/net/ethernet/broadcom/bnxt/bnxt.h

index 3b2ea36f25a2a7c651b1db0ee95e8c44e584dd16..78e496b0ec2625a8086d05e69a647d1345d5fff3 100644 (file)
@@ -12325,12 +12325,15 @@ static int bnxt_hwrm_if_change(struct bnxt *bp, bool up)
 {
        struct hwrm_func_drv_if_change_output *resp;
        struct hwrm_func_drv_if_change_input *req;
-       bool fw_reset = !bp->irq_tbl;
        bool resc_reinit = false;
        bool caps_change = false;
        int rc, retry = 0;
+       bool fw_reset;
        u32 flags = 0;
 
+       fw_reset = (bp->fw_reset_state == BNXT_FW_RESET_STATE_ABORT);
+       bp->fw_reset_state = 0;
+
        if (!(bp->fw_cap & BNXT_FW_CAP_IF_CHANGE))
                return 0;
 
@@ -14833,7 +14836,7 @@ static void bnxt_fw_reset_abort(struct bnxt *bp, int rc)
        clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
        if (bp->fw_reset_state != BNXT_FW_RESET_STATE_POLL_VF)
                bnxt_dl_health_fw_status_update(bp, false);
-       bp->fw_reset_state = 0;
+       bp->fw_reset_state = BNXT_FW_RESET_STATE_ABORT;
        netif_close(bp->dev);
 }
 
@@ -16931,10 +16934,9 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev)
                if (!err)
                        result = PCI_ERS_RESULT_RECOVERED;
 
+               /* IRQ will be initialized later in bnxt_io_resume */
                bnxt_ulp_irq_stop(bp);
                bnxt_clear_int_mode(bp);
-               err = bnxt_init_int_mode(bp);
-               bnxt_ulp_irq_restart(bp, err);
        }
 
 reset_exit:
@@ -16963,10 +16965,13 @@ static void bnxt_io_resume(struct pci_dev *pdev)
 
        err = bnxt_hwrm_func_qcaps(bp);
        if (!err) {
-               if (netif_running(netdev))
+               if (netif_running(netdev)) {
                        err = bnxt_open(netdev);
-               else
+               } else {
                        err = bnxt_reserve_rings(bp, true);
+                       if (!err)
+                               err = bnxt_init_int_mode(bp);
+               }
        }
 
        if (!err)
index 21726cf565866d58a907dd3263abcf7a43fc17c2..bc8b3b7e915d3b6bee25d15b7c4b211073007dd1 100644 (file)
@@ -2614,6 +2614,7 @@ struct bnxt {
 #define BNXT_FW_RESET_STATE_POLL_FW    4
 #define BNXT_FW_RESET_STATE_OPENING    5
 #define BNXT_FW_RESET_STATE_POLL_FW_DOWN       6
+#define BNXT_FW_RESET_STATE_ABORT      7
 
        u16                     fw_reset_min_dsecs;
 #define BNXT_DFLT_FW_RST_MIN_DSECS     20