]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
bnxt_en: Fix RDMA driver failure with SRIOV after firmware reset.
authorMichael Chan <michael.chan@broadcom.com>
Sun, 2 Feb 2020 07:41:36 +0000 (02:41 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 11 Feb 2020 12:36:37 +0000 (04:36 -0800)
[ Upstream commit 12de2eadf87825c3990c1aa68b5e93101ca2f043 ]

bnxt_ulp_start() needs to be called before SRIOV is re-enabled after
firmware reset.  Re-enabling SRIOV may consume all the resources and
may cause the RDMA driver to fail to get MSIX and other resources.
Fix it by calling bnxt_ulp_start() first before calling
bnxt_reenable_sriov().

We re-arrange the logic so that we call bnxt_ulp_start() and
bnxt_reenable_sriov() in proper sequence in bnxt_fw_reset_task() and
bnxt_open().  The former is the normal coordinated firmware reset sequence
and the latter is firmware reset while the function is down.  This new
logic is now more straight forward and will now fix both scenarios.

Fixes: f3a6d206c25a ("bnxt_en: Call bnxt_ulp_stop()/bnxt_ulp_start() during error recovery.")
Reported-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/ethernet/broadcom/bnxt/bnxt.c

index 6c5825475a73ed9b29e09e56afbd4626d38738d3..5a779d949716e6a570e763022c0711e5e0c5bb88 100644 (file)
@@ -9269,9 +9269,10 @@ static int bnxt_open(struct net_device *dev)
                bnxt_hwrm_if_change(bp, false);
        } else {
                if (test_and_clear_bit(BNXT_STATE_FW_RESET_DET, &bp->state)) {
-                       bnxt_reenable_sriov(bp);
-                       if (!test_bit(BNXT_STATE_IN_FW_RESET, &bp->state))
+                       if (!test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) {
                                bnxt_ulp_start(bp, 0);
+                               bnxt_reenable_sriov(bp);
+                       }
                }
                bnxt_hwmon_open(bp);
        }
@@ -10827,6 +10828,8 @@ static void bnxt_fw_reset_task(struct work_struct *work)
                smp_mb__before_atomic();
                clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
                bnxt_ulp_start(bp, rc);
+               if (!rc)
+                       bnxt_reenable_sriov(bp);
                bnxt_dl_health_status_update(bp, true);
                rtnl_unlock();
                break;