Blame SOURCES/0077-netdrv-bnxt_en-Add-RESET_FW-state-logic-to-bnxt_fw_r.patch

f95c89
From c587c80cd46091f35a6d063dd4c515f600cc91b9 Mon Sep 17 00:00:00 2001
f95c89
From: Jonathan Toppins <jtoppins@redhat.com>
f95c89
Date: Wed, 2 Oct 2019 18:23:32 -0400
f95c89
Subject: [PATCH 77/96] [netdrv] bnxt_en: Add RESET_FW state logic to
f95c89
 bnxt_fw_reset_task()
f95c89
f95c89
Message-id: <4dcd528def5dab7e4524d88a3aa5306d1e6d561f.1570027456.git.jtoppins@redhat.com>
f95c89
Patchwork-id: 276490
f95c89
O-Subject: [RHEL-8.2 PATCH 70/78] bnxt_en: Add RESET_FW state logic to bnxt_fw_reset_task().
f95c89
Bugzilla: 1724766
f95c89
RH-Acked-by: John Linville <linville@redhat.com>
f95c89
RH-Acked-by: Jarod Wilson <jarod@redhat.com>
f95c89
f95c89
This state handles driver initiated chip reset during error recovery.
f95c89
Only the master function will perform this step during error recovery.
f95c89
The next patch will add code to initiate this reset from the master
f95c89
function.
f95c89
f95c89
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
f95c89
Signed-off-by: David S. Miller <davem@davemloft.net>
f95c89
(cherry picked from commit cbb51067a5f5fbae733283b67fc8013881eb4bb1)
f95c89
Bugzilla: 1724766
f95c89
Build Info: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=23809532
f95c89
Tested: build, boot, basic ping
f95c89
Signed-off-by: Jonathan Toppins <jtoppins@redhat.com>
f95c89
Signed-off-by: Bruno Meneguele <bmeneg@redhat.com>
f95c89
---
f95c89
 drivers/net/ethernet/broadcom/bnxt/bnxt.c | 64 +++++++++++++++++++++++++++++++
f95c89
 1 file changed, 64 insertions(+)
f95c89
f95c89
Index: src/drivers/net/ethernet/broadcom/bnxt/bnxt.c
f95c89
===================================================================
f95c89
--- src.orig/drivers/net/ethernet/broadcom/bnxt/bnxt.c	2020-02-06 16:23:20.602468248 +0100
f95c89
+++ src/drivers/net/ethernet/broadcom/bnxt/bnxt.c	2020-02-06 16:23:20.736467018 +0100
f95c89
@@ -10407,6 +10407,62 @@
f95c89
 	return 0;
f95c89
 }
f95c89
 
f95c89
+static void bnxt_fw_reset_writel(struct bnxt *bp, int reg_idx)
f95c89
+{
f95c89
+	struct bnxt_fw_health *fw_health = bp->fw_health;
f95c89
+	u32 reg = fw_health->fw_reset_seq_regs[reg_idx];
f95c89
+	u32 val = fw_health->fw_reset_seq_vals[reg_idx];
f95c89
+	u32 reg_type, reg_off, delay_msecs;
f95c89
+
f95c89
+	delay_msecs = fw_health->fw_reset_seq_delay_msec[reg_idx];
f95c89
+	reg_type = BNXT_FW_HEALTH_REG_TYPE(reg);
f95c89
+	reg_off = BNXT_FW_HEALTH_REG_OFF(reg);
f95c89
+	switch (reg_type) {
f95c89
+	case BNXT_FW_HEALTH_REG_TYPE_CFG:
f95c89
+		pci_write_config_dword(bp->pdev, reg_off, val);
f95c89
+		break;
f95c89
+	case BNXT_FW_HEALTH_REG_TYPE_GRC:
f95c89
+		writel(reg_off & BNXT_GRC_BASE_MASK,
f95c89
+		       bp->bar0 + BNXT_GRCPF_REG_WINDOW_BASE_OUT + 4);
f95c89
+		reg_off = (reg_off & BNXT_GRC_OFFSET_MASK) + 0x2000;
f95c89
+		/* fall through */
f95c89
+	case BNXT_FW_HEALTH_REG_TYPE_BAR0:
f95c89
+		writel(val, bp->bar0 + reg_off);
f95c89
+		break;
f95c89
+	case BNXT_FW_HEALTH_REG_TYPE_BAR1:
f95c89
+		writel(val, bp->bar1 + reg_off);
f95c89
+		break;
f95c89
+	}
f95c89
+	if (delay_msecs) {
f95c89
+		pci_read_config_dword(bp->pdev, 0, &val;;
f95c89
+		msleep(delay_msecs);
f95c89
+	}
f95c89
+}
f95c89
+
f95c89
+static void bnxt_reset_all(struct bnxt *bp)
f95c89
+{
f95c89
+	struct bnxt_fw_health *fw_health = bp->fw_health;
f95c89
+	int i;
f95c89
+
f95c89
+	if (fw_health->flags & ERROR_RECOVERY_QCFG_RESP_FLAGS_HOST) {
f95c89
+		for (i = 0; i < fw_health->fw_reset_seq_cnt; i++)
f95c89
+			bnxt_fw_reset_writel(bp, i);
f95c89
+	} else if (fw_health->flags & ERROR_RECOVERY_QCFG_RESP_FLAGS_CO_CPU) {
f95c89
+		struct hwrm_fw_reset_input req = {0};
f95c89
+		int rc;
f95c89
+
f95c89
+		bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FW_RESET, -1, -1);
f95c89
+		req.resp_addr = cpu_to_le64(bp->hwrm_cmd_kong_resp_dma_addr);
f95c89
+		req.embedded_proc_type = FW_RESET_REQ_EMBEDDED_PROC_TYPE_CHIP;
f95c89
+		req.selfrst_status = FW_RESET_REQ_SELFRST_STATUS_SELFRSTASAP;
f95c89
+		req.flags = FW_RESET_REQ_FLAGS_RESET_GRACEFUL;
f95c89
+		rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
f95c89
+		if (rc)
f95c89
+			netdev_warn(bp->dev, "Unable to reset FW rc=%d\n", rc);
f95c89
+	}
f95c89
+	bp->fw_reset_timestamp = jiffies;
f95c89
+}
f95c89
+
f95c89
 static void bnxt_fw_reset_task(struct work_struct *work)
f95c89
 {
f95c89
 	struct bnxt *bp = container_of(work, struct bnxt, fw_reset_task.work);
f95c89
@@ -10446,6 +10502,14 @@
f95c89
 		rtnl_unlock();
f95c89
 		bnxt_queue_fw_reset_work(bp, bp->fw_reset_min_dsecs * HZ / 10);
f95c89
 		return;
f95c89
+	case BNXT_FW_RESET_STATE_RESET_FW: {
f95c89
+		u32 wait_dsecs = bp->fw_health->post_reset_wait_dsecs;
f95c89
+
f95c89
+		bnxt_reset_all(bp);
f95c89
+		bp->fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV;
f95c89
+		bnxt_queue_fw_reset_work(bp, wait_dsecs * HZ / 10);
f95c89
+		return;
f95c89
+	}
f95c89
 	case BNXT_FW_RESET_STATE_ENABLE_DEV:
f95c89
 		clear_bit(BNXT_STATE_FW_FATAL_COND, &bp->state);
f95c89
 		if (pci_enable_device(bp->pdev)) {