From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id B8717A0588; Tue, 21 Apr 2020 10:58:05 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 616661D95D; Tue, 21 Apr 2020 10:57:05 +0200 (CEST) Received: from relay.smtp.broadcom.com (relay.smtp.broadcom.com [192.19.232.149]) by dpdk.org (Postfix) with ESMTP id D321D1D94A for ; Tue, 21 Apr 2020 10:56:59 +0200 (CEST) Received: from dhcp-10-123-153-22.dhcp.broadcom.net (bgccx-dev-host-lnx2.bec.broadcom.net [10.123.153.22]) by relay.smtp.broadcom.com (Postfix) with ESMTP id 136F51BC653; Tue, 21 Apr 2020 01:56:58 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.10.3 relay.smtp.broadcom.com 136F51BC653 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=broadcom.com; s=dkimrelay; t=1587459420; bh=tWHn4QsbkB2Y3FHwmmDm7zHGR+7UF4IpCobQ+HD/JxU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gWjqMdtGCQUKay965QFCRAAdefT9kdrXRktYL1dW2ytYm1HZhnWeZrZEJI8DZ5ktd Umlabk1s+9wIPkoMuwsiusIZvnW9+qWSJfYXq834hUTO0PGW/CQ9EnMuVZ6a/hBgp4 OQwjeO4kUHXS/sQty2YI7GvGxa65SzkvCeckbE9M= From: Kalesh A P To: dev@dpdk.org Cc: ferruh.yigit@intel.com, ajit.khaparde@broadcom.com Date: Tue, 21 Apr 2020 14:42:56 +0530 Message-Id: <20200421091257.8089-9-kalesh-anakkur.purayil@broadcom.com> X-Mailer: git-send-email 2.10.1 In-Reply-To: <20200421091257.8089-1-kalesh-anakkur.purayil@broadcom.com> References: <20200421091257.8089-1-kalesh-anakkur.purayil@broadcom.com> Subject: [dpdk-dev] [PATCH 8/9] net/bnxt: log firmware status on early init failure X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Kalesh AP Firmware reports any fatal error (either ASIC or Firmware related) via a new status register. This status register can provide more detailed information about the firmware errors, especially if error occurs before HWRM_VER_GET is issued. Attempt to map this register if it is present and check for firmware status when VER_GET command fails. Refactored the code to allocate the "bp->recovery_info" structure in bnxt_init_fw() instead of doing in bnxt_hwrm_error_recovery_qcfg(). Signed-off-by: Kalesh AP Reviewed-by: Ajit Kumar Khaparde --- drivers/net/bnxt/bnxt.h | 5 ++ drivers/net/bnxt/bnxt_ethdev.c | 107 ++++++++++++++++++++++++++++++++++++++--- drivers/net/bnxt/bnxt_hwrm.c | 10 ---- 3 files changed, 106 insertions(+), 16 deletions(-) diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h index d55a570..586d3f5 100644 --- a/drivers/net/bnxt/bnxt.h +++ b/drivers/net/bnxt/bnxt.h @@ -507,6 +507,10 @@ struct bnxt_mark_info { #define BNXT_GRCP_WINDOW_2_BASE 0x2000 #define BNXT_GRCP_WINDOW_3_BASE 0x3000 +#define BNXT_GRCP_BASE_MASK 0xfffff000 +#define BNXT_GRCP_OFFSET_MASK 0x00000ffc + +#define BNXT_FW_STATUS_HEALTHY 0x8000 #define BNXT_FW_STATUS_SHUTDOWN 0x100000 #define BNXT_HWRM_SHORT_REQ_LEN sizeof(struct hwrm_short_input) @@ -564,6 +568,7 @@ struct bnxt { #define BNXT_FW_CAP_ERR_RECOVER_RELOAD BIT(3) #define BNXT_FW_CAP_ADV_FLOW_MGMT BIT(5) #define BNXT_FW_CAP_ADV_FLOW_COUNTERS BIT(6) +#define BNXT_FW_CAP_HCOMM_FW_STATUS BIT(7) uint32_t flow_flags; #define BNXT_FLOW_FLAG_L2_HDR_SRC_FILTER_EN BIT(0) diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c index 589190b..1a3c7e6 100644 --- a/drivers/net/bnxt/bnxt_ethdev.c +++ b/drivers/net/bnxt/bnxt_ethdev.c @@ -155,6 +155,7 @@ static int bnxt_uninit_resources(struct bnxt *bp, bool reconfig_dev); static void bnxt_cancel_fw_health_check(struct bnxt *bp); static int bnxt_restore_vlan_filters(struct bnxt *bp); static void bnxt_dev_recover(void *arg); +static void bnxt_free_error_recovery_info(struct bnxt *bp); int is_bnxt_in_error(struct bnxt *bp) { @@ -4967,6 +4968,89 @@ bnxt_get_fw_func_id(uint16_t port) return bp->fw_fid; } +static void bnxt_alloc_error_recovery_info(struct bnxt *bp) +{ + struct bnxt_error_recovery_info *info = bp->recovery_info; + + if (info) { + if (!(bp->fw_cap & BNXT_FW_CAP_HCOMM_FW_STATUS)) + memset(info, 0, sizeof(*info)); + return; + } + + if (!(bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY)) + return; + + info = rte_zmalloc("bnxt_hwrm_error_recovery_qcfg", + sizeof(*info), 0); + if (!info) + bp->fw_cap &= ~BNXT_FW_CAP_ERROR_RECOVERY; + + bp->recovery_info = info; +} + +static void bnxt_check_fw_status(struct bnxt *bp) +{ + uint32_t fw_status; + + if (!(bp->recovery_info && + (bp->fw_cap & BNXT_FW_CAP_HCOMM_FW_STATUS))) + return; + + fw_status = bnxt_read_fw_status_reg(bp, BNXT_FW_STATUS_REG); + if (fw_status != BNXT_FW_STATUS_HEALTHY) + PMD_DRV_LOG(ERR, "Firmware not responding, status: %#x\n", + fw_status); +} + +static int bnxt_map_hcomm_fw_status_reg(struct bnxt *bp) +{ + struct bnxt_error_recovery_info *info = bp->recovery_info; + uint32_t status_loc; + uint32_t sig_ver; + + rte_write32(HCOMM_STATUS_STRUCT_LOC, (uint8_t *)bp->bar0 + + BNXT_GRCPF_REG_WINDOW_BASE_OUT + 4); + sig_ver = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + + BNXT_GRCP_WINDOW_2_BASE + + offsetof(struct hcomm_status, + sig_ver))); + /* If the signature is absent, then FW does not support this feature */ + if ((sig_ver & HCOMM_STATUS_SIGNATURE_MASK) != + HCOMM_STATUS_SIGNATURE_VAL) + return 0; + + if (!info) { + info = rte_zmalloc("bnxt_hwrm_error_recovery_qcfg", + sizeof(*info), 0); + if (!info) + return -ENOMEM; + bp->recovery_info = info; + } else { + memset(info, 0, sizeof(*info)); + } + + status_loc = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + + BNXT_GRCP_WINDOW_2_BASE + + offsetof(struct hcomm_status, + fw_status_loc))); + + /* Only pre-map the FW health status GRC register */ + if (BNXT_FW_STATUS_REG_TYPE(status_loc) != BNXT_FW_STATUS_REG_TYPE_GRC) + return 0; + + info->status_regs[BNXT_FW_STATUS_REG] = status_loc; + info->mapped_status_regs[BNXT_FW_STATUS_REG] = + BNXT_GRCP_WINDOW_2_BASE + (status_loc & BNXT_GRCP_OFFSET_MASK); + + rte_write32((status_loc & BNXT_GRCP_BASE_MASK), (uint8_t *)bp->bar0 + + BNXT_GRCPF_REG_WINDOW_BASE_OUT + 4); + + bp->fw_cap |= BNXT_FW_CAP_HCOMM_FW_STATUS; + + return 0; +} + static int bnxt_init_fw(struct bnxt *bp) { uint16_t mtu; @@ -4974,10 +5058,16 @@ static int bnxt_init_fw(struct bnxt *bp) bp->fw_cap = 0; - rc = bnxt_hwrm_ver_get(bp, DFLT_HWRM_CMD_TIMEOUT); + rc = bnxt_map_hcomm_fw_status_reg(bp); if (rc) return rc; + rc = bnxt_hwrm_ver_get(bp, DFLT_HWRM_CMD_TIMEOUT); + if (rc) { + bnxt_check_fw_status(bp); + return rc; + } + rc = bnxt_hwrm_func_reset(bp); if (rc) return -EIO; @@ -5008,6 +5098,7 @@ static int bnxt_init_fw(struct bnxt *bp) if (rc) return rc; + bnxt_alloc_error_recovery_info(bp); /* Get the adapter error recovery support info */ rc = bnxt_hwrm_error_recovery_qcfg(bp); if (rc) @@ -5344,6 +5435,14 @@ static void bnxt_uninit_ctx_mem(struct bnxt *bp) } static void +bnxt_free_error_recovery_info(struct bnxt *bp) +{ + rte_free(bp->recovery_info); + bp->recovery_info = NULL; + bp->fw_cap &= ~BNXT_FW_CAP_ERROR_RECOVERY; +} + +static void bnxt_uninit_locks(struct bnxt *bp) { pthread_mutex_destroy(&bp->flow_lock); @@ -5363,11 +5462,7 @@ bnxt_uninit_resources(struct bnxt *bp, bool reconfig_dev) bnxt_free_ctx_mem(bp); if (!reconfig_dev) { bnxt_free_hwrm_resources(bp); - - if (bp->recovery_info != NULL) { - rte_free(bp->recovery_info); - bp->recovery_info = NULL; - } + bnxt_free_error_recovery_info(bp); } bnxt_uninit_ctx_mem(bp); diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c index dc0b405..666056a 100644 --- a/drivers/net/bnxt/bnxt_hwrm.c +++ b/drivers/net/bnxt/bnxt_hwrm.c @@ -5076,16 +5076,6 @@ int bnxt_hwrm_error_recovery_qcfg(struct bnxt *bp) if (!(bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY)) return 0; - if (!info) { - info = rte_zmalloc("bnxt_hwrm_error_recovery_qcfg", - sizeof(*info), 0); - bp->recovery_info = info; - if (info == NULL) - return -ENOMEM; - } else { - memset(info, 0, sizeof(*info)); - } - HWRM_PREP(&req, HWRM_ERROR_RECOVERY_QCFG, BNXT_USE_CHIMP_MB); rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB); -- 2.10.1