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.
196 lines
5.9 KiB
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;
|