From f8da0cd69bb0dfa00a3e733da795c4629ed846bb Mon Sep 17 00:00:00 2001 From: Rasesh Mody Date: Wed, 4 Jan 2017 23:03:59 -0800 Subject: [PATCH] net/qede/base: retrieve FW crash dump info As part of device probe, check if management FW crash dump logs are available. If available, then log an warning message and update the epoch value too. A new struct ecore_mdump_info is added to populate dump info including the new "reason" field by reading shared memory region. Signed-off-by: Rasesh Mody --- drivers/net/qede/base/ecore_dev.c | 18 ++++++-- drivers/net/qede/base/ecore_dev_api.h | 4 +- drivers/net/qede/base/ecore_mcp.c | 66 +++++++++++++++++---------- drivers/net/qede/base/ecore_mcp.h | 22 --------- drivers/net/qede/base/ecore_mcp_api.h | 33 ++++++++++++-- drivers/net/qede/qede_main.c | 2 +- 6 files changed, 87 insertions(+), 58 deletions(-) diff --git a/drivers/net/qede/base/ecore_dev.c b/drivers/net/qede/base/ecore_dev.c index 0da95c65d6..86b4bffc63 100644 --- a/drivers/net/qede/base/ecore_dev.c +++ b/drivers/net/qede/base/ecore_dev.c @@ -1761,10 +1761,6 @@ enum _ecore_status_t ecore_hw_init(struct ecore_dev *p_dev, return mfw_rc; } - ecore_mcp_mdump_get_info(p_hwfn, p_hwfn->p_main_ptt); - ecore_mcp_mdump_set_values(p_hwfn, p_hwfn->p_main_ptt, - p_params->epoch); - /* send DCBX attention request command */ DP_VERBOSE(p_hwfn, ECORE_MSG_DCB, "sending phony dcbx set command to trigger DCBx attention handling\n"); @@ -2962,6 +2958,7 @@ ecore_hw_prepare_single(struct ecore_hwfn *p_hwfn, void OSAL_IOMEM *p_regview, struct ecore_hw_prepare_params *p_params) { struct ecore_dev *p_dev = p_hwfn->p_dev; + struct ecore_mdump_info mdump_info; enum _ecore_status_t rc = ECORE_SUCCESS; /* Split PCI bars evenly between hwfns */ @@ -3024,6 +3021,19 @@ ecore_hw_prepare_single(struct ecore_hwfn *p_hwfn, void OSAL_IOMEM *p_regview, DP_NOTICE(p_hwfn, false, "Failed to initiate PF FLR\n"); } + /* Check if mdump logs are present and update the epoch value */ + if (p_hwfn == ECORE_LEADING_HWFN(p_hwfn->p_dev)) { + rc = ecore_mcp_mdump_get_info(p_hwfn, p_hwfn->p_main_ptt, + &mdump_info); + if (rc == ECORE_SUCCESS && mdump_info.num_of_logs > 0) { + DP_NOTICE(p_hwfn, false, + "* * * IMPORTANT - HW ERROR register dump captured by device * * *\n"); + } + + ecore_mcp_mdump_set_values(p_hwfn, p_hwfn->p_main_ptt, + p_params->epoch); + } + /* Allocate the init RT array and initialize the init-ops engine */ rc = ecore_init_alloc(p_hwfn); if (rc) { diff --git a/drivers/net/qede/base/ecore_dev_api.h b/drivers/net/qede/base/ecore_dev_api.h index 0ec02b5b26..0dee68a9b2 100644 --- a/drivers/net/qede/base/ecore_dev_api.h +++ b/drivers/net/qede/base/ecore_dev_api.h @@ -68,8 +68,6 @@ struct ecore_hw_init_params { bool allow_npar_tx_switch; /* binary fw data pointer in binary fw file */ const u8 *bin_fw_data; - /* the OS Epoch time in seconds */ - u32 epoch; }; /** @@ -149,6 +147,8 @@ struct ecore_hw_prepare_params { bool chk_reg_fifo; /* request the MFW to initiate PF FLR */ bool initiate_pf_flr; + /* the OS Epoch time in seconds */ + u32 epoch; }; /** diff --git a/drivers/net/qede/base/ecore_mcp.c b/drivers/net/qede/base/ecore_mcp.c index a5d707b2d1..5d40c1ed46 100644 --- a/drivers/net/qede/base/ecore_mcp.c +++ b/drivers/net/qede/base/ecore_mcp.c @@ -1098,16 +1098,9 @@ enum _ecore_status_t ecore_mcp_mdump_trigger(struct ecore_hwfn *p_hwfn, { u32 mcp_resp; - return ecore_mcp_mdump_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_MDUMP_TRIGGER, - OSAL_NULL, OSAL_NULL, &mcp_resp); -} - -enum _ecore_status_t ecore_mcp_mdump_clear_logs(struct ecore_hwfn *p_hwfn, - struct ecore_ptt *p_ptt) -{ - u32 mcp_resp; + p_hwfn->p_dev->mdump_en = true; - return ecore_mcp_mdump_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_MDUMP_CLEAR_LOGS, + return ecore_mcp_mdump_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_MDUMP_TRIGGER, OSAL_NULL, OSAL_NULL, &mcp_resp); } @@ -1141,32 +1134,56 @@ ecore_mcp_mdump_get_config(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt, return rc; } -enum _ecore_status_t ecore_mcp_mdump_get_info(struct ecore_hwfn *p_hwfn, - struct ecore_ptt *p_ptt) +enum _ecore_status_t +ecore_mcp_mdump_get_info(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt, + struct ecore_mdump_info *p_mdump_info) { + u32 addr, global_offsize, global_addr; struct mdump_config_stc mdump_config; enum _ecore_status_t rc; - rc = ecore_mcp_mdump_get_config(p_hwfn, p_ptt, &mdump_config); - if (rc != ECORE_SUCCESS) - return rc; + OSAL_MEMSET(p_mdump_info, 0, sizeof(*p_mdump_info)); - DP_VERBOSE(p_hwfn, ECORE_MSG_SP, - "MFW mdump_config: version 0x%x, config 0x%x, epoch 0x%x, num_of_logs 0x%x, valid_logs 0x%x\n", - mdump_config.version, mdump_config.config, mdump_config.epoc, - mdump_config.num_of_logs, mdump_config.valid_logs); + addr = SECTION_OFFSIZE_ADDR(p_hwfn->mcp_info->public_base, + PUBLIC_GLOBAL); + global_offsize = ecore_rd(p_hwfn, p_ptt, addr); + global_addr = SECTION_ADDR(global_offsize, 0); + p_mdump_info->reason = ecore_rd(p_hwfn, p_ptt, + global_addr + + OFFSETOF(struct public_global, + mdump_reason)); - if (mdump_config.valid_logs > 0) { - DP_NOTICE(p_hwfn, false, - "* * * IMPORTANT - HW ERROR register dump captured by device * * *\n"); + if (p_mdump_info->reason) { + rc = ecore_mcp_mdump_get_config(p_hwfn, p_ptt, &mdump_config); + if (rc != ECORE_SUCCESS) + return rc; + + p_mdump_info->version = mdump_config.version; + p_mdump_info->config = mdump_config.config; + p_mdump_info->epoch = mdump_config.epoc; + p_mdump_info->num_of_logs = mdump_config.num_of_logs; + p_mdump_info->valid_logs = mdump_config.valid_logs; + + DP_VERBOSE(p_hwfn, ECORE_MSG_SP, + "MFW mdump info: reason %d, version 0x%x, config 0x%x, epoch 0x%x, num_of_logs 0x%x, valid_logs 0x%x\n", + p_mdump_info->reason, p_mdump_info->version, + p_mdump_info->config, p_mdump_info->epoch, + p_mdump_info->num_of_logs, p_mdump_info->valid_logs); + } else { + DP_VERBOSE(p_hwfn, ECORE_MSG_SP, + "MFW mdump info: reason %d\n", p_mdump_info->reason); } - return rc; + return ECORE_SUCCESS; } -void ecore_mcp_mdump_enable(struct ecore_dev *p_dev, bool mdump_enable) +enum _ecore_status_t ecore_mcp_mdump_clear_logs(struct ecore_hwfn *p_hwfn, + struct ecore_ptt *p_ptt) { - p_dev->mdump_en = mdump_enable; + u32 mcp_resp; + + return ecore_mcp_mdump_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_MDUMP_CLEAR_LOGS, + OSAL_NULL, OSAL_NULL, &mcp_resp); } static void ecore_mcp_handle_critical_error(struct ecore_hwfn *p_hwfn, @@ -1184,6 +1201,7 @@ static void ecore_mcp_handle_critical_error(struct ecore_hwfn *p_hwfn, if (p_hwfn->p_dev->mdump_en) { DP_NOTICE(p_hwfn, false, "Not acknowledging the notification to allow the MFW crash dump\n"); + p_hwfn->p_dev->mdump_en = false; return; } diff --git a/drivers/net/qede/base/ecore_mcp.h b/drivers/net/qede/base/ecore_mcp.h index ae33e84dbc..d77b5df9dd 100644 --- a/drivers/net/qede/base/ecore_mcp.h +++ b/drivers/net/qede/base/ecore_mcp.h @@ -326,28 +326,6 @@ enum _ecore_status_t ecore_mcp_mdump_set_values(struct ecore_hwfn *p_hwfn, enum _ecore_status_t ecore_mcp_mdump_trigger(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt); -/** - * @brief - Clears the MFW crash dump logs. - * - * @param p_hwfn - * @param p_ptt - * - * @param return ECORE_SUCCESS upon success. - */ -enum _ecore_status_t ecore_mcp_mdump_clear_logs(struct ecore_hwfn *p_hwfn, - struct ecore_ptt *p_ptt); - -/** - * @brief - Gets the MFW crash dump configuration and logs info. - * - * @param p_hwfn - * @param p_ptt - * - * @param return ECORE_SUCCESS upon success. - */ -enum _ecore_status_t ecore_mcp_mdump_get_info(struct ecore_hwfn *p_hwfn, - struct ecore_ptt *p_ptt); - /** * @brief - Gets the MFW allocation info for the given resource * diff --git a/drivers/net/qede/base/ecore_mcp_api.h b/drivers/net/qede/base/ecore_mcp_api.h index c26b4943a0..4e954bd82a 100644 --- a/drivers/net/qede/base/ecore_mcp_api.h +++ b/drivers/net/qede/base/ecore_mcp_api.h @@ -792,14 +792,37 @@ enum _ecore_status_t ecore_mcp_mem_ecc_events(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt, u64 *num_events); +struct ecore_mdump_info { + u32 reason; + u32 version; + u32 config; + u32 epoch; + u32 num_of_logs; + u32 valid_logs; +}; + +/** + * @brief - Gets the MFW crash dump configuration and logs info. + * + * @param p_hwfn + * @param p_ptt + * @param p_mdump_info + * + * @param return ECORE_SUCCESS upon success. + */ +enum _ecore_status_t +ecore_mcp_mdump_get_info(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt, + struct ecore_mdump_info *p_mdump_info); + /** - * @brief Sets whether a critical error notification from the MFW is acked, or - * is it being ignored and thus allowing the MFW crash dump. + * @brief - Clears the MFW crash dump logs. * - * @param p_dev - * @param mdump_enable + * @param p_hwfn + * @param p_ptt * + * @param return ECORE_SUCCESS upon success. */ -void ecore_mcp_mdump_enable(struct ecore_dev *p_dev, bool mdump_enable); +enum _ecore_status_t ecore_mcp_mdump_clear_logs(struct ecore_hwfn *p_hwfn, + struct ecore_ptt *p_ptt); #endif diff --git a/drivers/net/qede/qede_main.c b/drivers/net/qede/qede_main.c index e827200a92..92ed404940 100644 --- a/drivers/net/qede/qede_main.c +++ b/drivers/net/qede/qede_main.c @@ -62,6 +62,7 @@ qed_probe(struct ecore_dev *edev, struct rte_pci_device *pci_dev, hw_prepare_params.drv_resc_alloc = false; hw_prepare_params.chk_reg_fifo = false; hw_prepare_params.initiate_pf_flr = true; + hw_prepare_params.epoch = (u32)time(NULL); rc = ecore_hw_prepare(edev, &hw_prepare_params); if (rc) { DP_ERR(edev, "hw prepare failed\n"); @@ -274,7 +275,6 @@ static int qed_slowpath_start(struct ecore_dev *edev, hw_init_params.int_mode = ECORE_INT_MODE_MSIX; hw_init_params.allow_npar_tx_switch = allow_npar_tx_switching; hw_init_params.bin_fw_data = data; - hw_init_params.epoch = (u32)time(NULL); rc = ecore_hw_init(edev, &hw_init_params); if (rc) { DP_ERR(edev, "ecore_hw_init failed\n"); -- 2.20.1