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.
kmod-redhat-bnxt_en/SOURCES/0066-netdrv-bnxt_en-Handle-...

196 lines
5.9 KiB

From 2e673311338d1e2e27a2fe9aabe8fbfcb81c3718 Mon Sep 17 00:00:00 2001
From: Jonathan Toppins <jtoppins@redhat.com>
Date: Wed, 2 Oct 2019 18:23:21 -0400
Subject: [PATCH 66/96] [netdrv] bnxt_en: Handle firmware reset status during
IF_UP
Message-id: <46b898742e8a2f4726a84ce5492cd5e31b5fcfae.1570027456.git.jtoppins@redhat.com>
Patchwork-id: 276486
O-Subject: [RHEL-8.2 PATCH 59/78] bnxt_en: Handle firmware reset status during IF_UP.
Bugzilla: 1724766
RH-Acked-by: John Linville <linville@redhat.com>
RH-Acked-by: Jarod Wilson <jarod@redhat.com>
During IF_UP, newer firmware has a new status flag that indicates that
firmware has reset. Add new function bnxt_fw_init_one() to re-probe the
firmware and re-setup VF resources on the PF if necessary. If the
re-probe fails, set a flag to prevent bnxt_open() from proceeding again.
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 ec5d31e3c15d5233b491400133c67f78a320062c)
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 | 107 ++++++++++++++++++++++++------
drivers/net/ethernet/broadcom/bnxt/bnxt.h | 2 +
2 files changed, 89 insertions(+), 20 deletions(-)
Index: src/drivers/net/ethernet/broadcom/bnxt/bnxt.c
===================================================================
--- src.orig/drivers/net/ethernet/broadcom/bnxt/bnxt.c 2020-02-06 16:23:18.730485431 +0100
+++ src/drivers/net/ethernet/broadcom/bnxt/bnxt.c 2020-02-06 16:23:19.143481640 +0100
@@ -8528,11 +8528,14 @@
return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
}
+static int bnxt_fw_init_one(struct bnxt *bp);
+
static int bnxt_hwrm_if_change(struct bnxt *bp, bool up)
{
struct hwrm_func_drv_if_change_output *resp = bp->hwrm_cmd_resp_addr;
struct hwrm_func_drv_if_change_input req = {0};
- bool resc_reinit = false;
+ bool resc_reinit = false, fw_reset = false;
+ u32 flags = 0;
int rc;
if (!(bp->fw_cap & BNXT_FW_CAP_IF_CHANGE))
@@ -8543,26 +8546,53 @@
req.flags = cpu_to_le32(FUNC_DRV_IF_CHANGE_REQ_FLAGS_UP);
mutex_lock(&bp->hwrm_cmd_lock);
rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
- if (!rc && (resp->flags &
- cpu_to_le32(FUNC_DRV_IF_CHANGE_RESP_FLAGS_RESC_CHANGE)))
- resc_reinit = true;
+ if (!rc)
+ flags = le32_to_cpu(resp->flags);
mutex_unlock(&bp->hwrm_cmd_lock);
+ if (rc)
+ return rc;
- if (up && resc_reinit && BNXT_NEW_RM(bp)) {
- struct bnxt_hw_resc *hw_resc = &bp->hw_resc;
+ if (!up)
+ return 0;
+
+ if (flags & FUNC_DRV_IF_CHANGE_RESP_FLAGS_RESC_CHANGE)
+ resc_reinit = true;
+ if (flags & FUNC_DRV_IF_CHANGE_RESP_FLAGS_HOT_FW_RESET_DONE)
+ fw_reset = true;
- rc = bnxt_hwrm_func_resc_qcaps(bp, true);
- hw_resc->resv_cp_rings = 0;
- hw_resc->resv_stat_ctxs = 0;
- hw_resc->resv_irqs = 0;
- hw_resc->resv_tx_rings = 0;
- hw_resc->resv_rx_rings = 0;
- hw_resc->resv_hw_ring_grps = 0;
- hw_resc->resv_vnics = 0;
- bp->tx_nr_rings = 0;
- bp->rx_nr_rings = 0;
+ if (resc_reinit || fw_reset) {
+ if (fw_reset) {
+ rc = bnxt_fw_init_one(bp);
+ if (rc) {
+ set_bit(BNXT_STATE_ABORT_ERR, &bp->state);
+ return rc;
+ }
+ bnxt_clear_int_mode(bp);
+ rc = bnxt_init_int_mode(bp);
+ if (rc) {
+ netdev_err(bp->dev, "init int mode failed\n");
+ return rc;
+ }
+ set_bit(BNXT_STATE_FW_RESET_DET, &bp->state);
+ }
+ if (BNXT_NEW_RM(bp)) {
+ struct bnxt_hw_resc *hw_resc = &bp->hw_resc;
+
+ rc = bnxt_hwrm_func_resc_qcaps(bp, true);
+ hw_resc->resv_cp_rings = 0;
+ hw_resc->resv_stat_ctxs = 0;
+ hw_resc->resv_irqs = 0;
+ hw_resc->resv_tx_rings = 0;
+ hw_resc->resv_rx_rings = 0;
+ hw_resc->resv_hw_ring_grps = 0;
+ hw_resc->resv_vnics = 0;
+ if (!fw_reset) {
+ bp->tx_nr_rings = 0;
+ bp->rx_nr_rings = 0;
+ }
+ }
}
- return rc;
+ return 0;
}
static int bnxt_hwrm_port_led_qcaps(struct bnxt *bp)
@@ -8982,12 +9012,28 @@
struct bnxt *bp = netdev_priv(dev);
int rc;
- bnxt_hwrm_if_change(bp, true);
- rc = __bnxt_open_nic(bp, true, true);
+ if (test_bit(BNXT_STATE_ABORT_ERR, &bp->state)) {
+ netdev_err(bp->dev, "A previous firmware reset did not complete, aborting\n");
+ return -ENODEV;
+ }
+
+ rc = bnxt_hwrm_if_change(bp, true);
if (rc)
+ return rc;
+ rc = __bnxt_open_nic(bp, true, true);
+ if (rc) {
bnxt_hwrm_if_change(bp, false);
+ } else {
+ if (test_and_clear_bit(BNXT_STATE_FW_RESET_DET, &bp->state) &&
+ BNXT_PF(bp)) {
+ struct bnxt_pf_info *pf = &bp->pf;
+ int n = pf->active_vfs;
- bnxt_hwmon_open(bp);
+ if (n)
+ bnxt_cfg_hw_sriov(bp, &n);
+ }
+ bnxt_hwmon_open(bp);
+ }
return rc;
}
@@ -10080,6 +10126,27 @@
bnxt_hwrm_coal_params_qcaps(bp);
}
+static int bnxt_fw_init_one(struct bnxt *bp)
+{
+ int rc;
+
+ rc = bnxt_fw_init_one_p1(bp);
+ if (rc) {
+ netdev_err(bp->dev, "Firmware init phase 1 failed\n");
+ return rc;
+ }
+ rc = bnxt_fw_init_one_p2(bp);
+ if (rc) {
+ netdev_err(bp->dev, "Firmware init phase 2 failed\n");
+ return rc;
+ }
+ rc = bnxt_approve_mac(bp, bp->dev->dev_addr, false);
+ if (rc)
+ return rc;
+ bnxt_fw_init_one_p3(bp);
+ return 0;
+}
+
static int bnxt_init_board(struct pci_dev *pdev, struct net_device *dev)
{
int rc;
Index: src/drivers/net/ethernet/broadcom/bnxt/bnxt.h
===================================================================
--- src.orig/drivers/net/ethernet/broadcom/bnxt/bnxt.h 2020-02-06 16:23:17.788494078 +0100
+++ src/drivers/net/ethernet/broadcom/bnxt/bnxt.h 2020-02-06 16:23:19.143481640 +0100
@@ -1555,6 +1555,8 @@
#define BNXT_STATE_OPEN 0
#define BNXT_STATE_IN_SP_TASK 1
#define BNXT_STATE_READ_STATS 2
+#define BNXT_STATE_FW_RESET_DET 3
+#define BNXT_STATE_ABORT_ERR 5
struct bnxt_irq *irq_tbl;
int total_irqs;