You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
114 lines
4.3 KiB
114 lines
4.3 KiB
5 years ago
|
From bc6e952463a8ff739d2c19e2bf244b2fc20333e5 Mon Sep 17 00:00:00 2001
|
||
|
From: Jonathan Toppins <jtoppins@redhat.com>
|
||
|
Date: Wed, 2 Oct 2019 18:23:33 -0400
|
||
|
Subject: [PATCH 78/96] [netdrv] bnxt_en: Add bnxt_fw_exception() to handle
|
||
|
fatal firmware errors
|
||
|
|
||
|
Message-id: <7d2820df47f74feb4d96b3892f2ac534344a8293.1570027456.git.jtoppins@redhat.com>
|
||
|
Patchwork-id: 276501
|
||
|
O-Subject: [RHEL-8.2 PATCH 71/78] bnxt_en: Add bnxt_fw_exception() to handle fatal firmware errors.
|
||
|
Bugzilla: 1724766
|
||
|
RH-Acked-by: John Linville <linville@redhat.com>
|
||
|
RH-Acked-by: Jarod Wilson <jarod@redhat.com>
|
||
|
|
||
|
This call will handle fatal firmware errors by forcing a reset on the
|
||
|
firmware. The master function driver will carry out the forced reset.
|
||
|
The sequence will go through the same bnxt_fw_reset_task() workqueue.
|
||
|
This fatal reset differs from the non-fatal reset at the beginning
|
||
|
stages. From the BNXT_FW_RESET_STATE_ENABLE_DEV state onwards where
|
||
|
the firmware is coming out of reset, it is practically identical to the
|
||
|
non-fatal reset.
|
||
|
|
||
|
The next patch will add the periodic heartbeat check and the devlink
|
||
|
reporter to report the fatal event and to initiate the bnxt_fw_exception()
|
||
|
call.
|
||
|
|
||
|
Signed-off-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
|
||
|
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
|
||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||
|
(cherry picked from commit d1db9e166bf6a50e1e6713f3fd3b4de6007e3671)
|
||
|
Bugzilla: 1724766
|
||
|
Build Info: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=23809532
|
||
|
Tested: build, boot, basic ping
|
||
|
Signed-off-by: Jonathan Toppins <jtoppins@redhat.com>
|
||
|
Signed-off-by: Bruno Meneguele <bmeneg@redhat.com>
|
||
|
---
|
||
|
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 44 +++++++++++++++++++++++++++++++
|
||
|
drivers/net/ethernet/broadcom/bnxt/bnxt.h | 1 +
|
||
|
2 files changed, 45 insertions(+)
|
||
|
|
||
|
Index: src/drivers/net/ethernet/broadcom/bnxt/bnxt.c
|
||
|
===================================================================
|
||
|
--- src.orig/drivers/net/ethernet/broadcom/bnxt/bnxt.c 2020-02-06 16:23:20.736467018 +0100
|
||
|
+++ src/drivers/net/ethernet/broadcom/bnxt/bnxt.c 2020-02-06 16:23:20.864465843 +0100
|
||
|
@@ -10008,6 +10008,40 @@
|
||
|
bp->ctx = NULL;
|
||
|
}
|
||
|
|
||
|
+/* rtnl_lock is acquired before calling this function */
|
||
|
+static void bnxt_force_fw_reset(struct bnxt *bp)
|
||
|
+{
|
||
|
+ struct bnxt_fw_health *fw_health = bp->fw_health;
|
||
|
+ u32 wait_dsecs;
|
||
|
+
|
||
|
+ if (!test_bit(BNXT_STATE_OPEN, &bp->state) ||
|
||
|
+ test_bit(BNXT_STATE_IN_FW_RESET, &bp->state))
|
||
|
+ return;
|
||
|
+
|
||
|
+ set_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
|
||
|
+ bnxt_fw_reset_close(bp);
|
||
|
+ wait_dsecs = fw_health->master_func_wait_dsecs;
|
||
|
+ if (fw_health->master) {
|
||
|
+ if (fw_health->flags & ERROR_RECOVERY_QCFG_RESP_FLAGS_CO_CPU)
|
||
|
+ wait_dsecs = 0;
|
||
|
+ bp->fw_reset_state = BNXT_FW_RESET_STATE_RESET_FW;
|
||
|
+ } else {
|
||
|
+ bp->fw_reset_timestamp = jiffies + wait_dsecs * HZ / 10;
|
||
|
+ wait_dsecs = fw_health->normal_func_wait_dsecs;
|
||
|
+ bp->fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV;
|
||
|
+ }
|
||
|
+ bp->fw_reset_max_dsecs = fw_health->post_reset_max_wait_dsecs;
|
||
|
+ bnxt_queue_fw_reset_work(bp, wait_dsecs * HZ / 10);
|
||
|
+}
|
||
|
+
|
||
|
+void bnxt_fw_exception(struct bnxt *bp)
|
||
|
+{
|
||
|
+ set_bit(BNXT_STATE_FW_FATAL_COND, &bp->state);
|
||
|
+ bnxt_rtnl_lock_sp(bp);
|
||
|
+ bnxt_force_fw_reset(bp);
|
||
|
+ bnxt_rtnl_unlock_sp(bp);
|
||
|
+}
|
||
|
+
|
||
|
void bnxt_fw_reset(struct bnxt *bp)
|
||
|
{
|
||
|
int rc;
|
||
|
@@ -10511,6 +10545,16 @@
|
||
|
return;
|
||
|
}
|
||
|
case BNXT_FW_RESET_STATE_ENABLE_DEV:
|
||
|
+ if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state) &&
|
||
|
+ bp->fw_health) {
|
||
|
+ u32 val;
|
||
|
+
|
||
|
+ val = bnxt_fw_health_readl(bp,
|
||
|
+ BNXT_FW_RESET_INPROG_REG);
|
||
|
+ if (val)
|
||
|
+ netdev_warn(bp->dev, "FW reset inprog %x after min wait time.\n",
|
||
|
+ val);
|
||
|
+ }
|
||
|
clear_bit(BNXT_STATE_FW_FATAL_COND, &bp->state);
|
||
|
if (pci_enable_device(bp->pdev)) {
|
||
|
netdev_err(bp->dev, "Cannot re-enable PCI device\n");
|
||
|
Index: src/drivers/net/ethernet/broadcom/bnxt/bnxt.h
|
||
|
===================================================================
|
||
|
--- src.orig/drivers/net/ethernet/broadcom/bnxt/bnxt.h 2020-02-06 16:23:20.602468248 +0100
|
||
|
+++ src/drivers/net/ethernet/broadcom/bnxt/bnxt.h 2020-02-06 16:23:20.864465843 +0100
|
||
|
@@ -1982,6 +1982,7 @@
|
||
|
int bnxt_half_open_nic(struct bnxt *bp);
|
||
|
void bnxt_half_close_nic(struct bnxt *bp);
|
||
|
int bnxt_close_nic(struct bnxt *, bool, bool);
|
||
|
+void bnxt_fw_exception(struct bnxt *bp);
|
||
|
void bnxt_fw_reset(struct bnxt *bp);
|
||
|
int bnxt_check_rings(struct bnxt *bp, int tx, int rx, bool sh, int tcs,
|
||
|
int tx_xdp);
|