From: Rasesh Mody Date: Mon, 9 Apr 2018 04:48:04 +0000 (-0700) Subject: net/qede/base: support MFW for driver load timeout X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=2d52085e4da8bb4ee6adf0dbdc61a834956e2068;p=dpdk.git net/qede/base: support MFW for driver load timeout Add SPQ timeout base driver parameter support management FW timeout values other than default and none. Have fallback mechanism for old MFWs. Reduce the default timeout to 1 sec. Signed-off-by: Rasesh Mody --- diff --git a/drivers/net/qede/base/ecore_dev.c b/drivers/net/qede/base/ecore_dev.c index a3269f4b11..1b01bba288 100644 --- a/drivers/net/qede/base/ecore_dev.c +++ b/drivers/net/qede/base/ecore_dev.c @@ -2289,14 +2289,15 @@ static void ecore_reset_mb_shadow(struct ecore_hwfn *p_hwfn, } static void ecore_pglueb_clear_err(struct ecore_hwfn *p_hwfn, - struct ecore_ptt *p_ptt) + struct ecore_ptt *p_ptt) { ecore_wr(p_hwfn, p_ptt, PGLUE_B_REG_WAS_ERROR_PF_31_0_CLR, 1 << p_hwfn->abs_pf_id); } -static void -ecore_fill_load_req_params(struct ecore_load_req_params *p_load_req, +static enum _ecore_status_t +ecore_fill_load_req_params(struct ecore_hwfn *p_hwfn, + struct ecore_load_req_params *p_load_req, struct ecore_drv_load_params *p_drv_load) { /* Make sure that if ecore-client didn't provide inputs, all the @@ -2308,15 +2309,51 @@ ecore_fill_load_req_params(struct ecore_load_req_params *p_load_req, OSAL_MEM_ZERO(p_load_req, sizeof(*p_load_req)); - if (p_drv_load != OSAL_NULL) { - p_load_req->drv_role = p_drv_load->is_crash_kernel ? - ECORE_DRV_ROLE_KDUMP : - ECORE_DRV_ROLE_OS; + if (p_drv_load == OSAL_NULL) + goto out; + + p_load_req->drv_role = p_drv_load->is_crash_kernel ? + ECORE_DRV_ROLE_KDUMP : + ECORE_DRV_ROLE_OS; + p_load_req->avoid_eng_reset = p_drv_load->avoid_eng_reset; + p_load_req->override_force_load = p_drv_load->override_force_load; + + /* Old MFW versions don't support timeout values other than default and + * none, so these values are replaced according to the fall-back action. + */ + + if (p_drv_load->mfw_timeout_val == ECORE_LOAD_REQ_LOCK_TO_DEFAULT || + p_drv_load->mfw_timeout_val == ECORE_LOAD_REQ_LOCK_TO_NONE || + (p_hwfn->mcp_info->capabilities & + FW_MB_PARAM_FEATURE_SUPPORT_DRV_LOAD_TO)) { p_load_req->timeout_val = p_drv_load->mfw_timeout_val; - p_load_req->avoid_eng_reset = p_drv_load->avoid_eng_reset; - p_load_req->override_force_load = - p_drv_load->override_force_load; + goto out; } + + switch (p_drv_load->mfw_timeout_fallback) { + case ECORE_TO_FALLBACK_TO_NONE: + p_load_req->timeout_val = ECORE_LOAD_REQ_LOCK_TO_NONE; + break; + case ECORE_TO_FALLBACK_TO_DEFAULT: + p_load_req->timeout_val = ECORE_LOAD_REQ_LOCK_TO_DEFAULT; + break; + case ECORE_TO_FALLBACK_FAIL_LOAD: + DP_NOTICE(p_hwfn, false, + "Received %d as a value for MFW timeout while the MFW supports only default [%d] or none [%d]. Abort.\n", + p_drv_load->mfw_timeout_val, + ECORE_LOAD_REQ_LOCK_TO_DEFAULT, + ECORE_LOAD_REQ_LOCK_TO_NONE); + return ECORE_ABORTED; + } + + DP_INFO(p_hwfn, + "Modified the MFW timeout value from %d to %s [%d] due to lack of MFW support\n", + p_drv_load->mfw_timeout_val, + (p_load_req->timeout_val == ECORE_LOAD_REQ_LOCK_TO_DEFAULT) ? + "default" : "none", + p_load_req->timeout_val); +out: + return ECORE_SUCCESS; } enum _ecore_status_t ecore_vf_start(struct ecore_hwfn *p_hwfn, @@ -2372,8 +2409,13 @@ enum _ecore_status_t ecore_hw_init(struct ecore_dev *p_dev, if (rc != ECORE_SUCCESS) return rc; - ecore_fill_load_req_params(&load_req_params, - p_params->p_drv_load_params); + ecore_set_spq_block_timeout(p_hwfn, p_params->spq_timeout_ms); + + rc = ecore_fill_load_req_params(p_hwfn, &load_req_params, + p_params->p_drv_load_params); + if (rc != ECORE_SUCCESS) + return rc; + rc = ecore_mcp_load_req(p_hwfn, p_hwfn->p_main_ptt, &load_req_params); if (rc != ECORE_SUCCESS) { diff --git a/drivers/net/qede/base/ecore_dev_api.h b/drivers/net/qede/base/ecore_dev_api.h index 98bcabe878..1d3fc5619a 100644 --- a/drivers/net/qede/base/ecore_dev_api.h +++ b/drivers/net/qede/base/ecore_dev_api.h @@ -57,6 +57,12 @@ enum _ecore_status_t ecore_resc_alloc(struct ecore_dev *p_dev); */ void ecore_resc_setup(struct ecore_dev *p_dev); +enum ecore_mfw_timeout_fallback { + ECORE_TO_FALLBACK_TO_NONE, + ECORE_TO_FALLBACK_TO_DEFAULT, + ECORE_TO_FALLBACK_FAIL_LOAD, +}; + enum ecore_override_force_load { ECORE_OVERRIDE_FORCE_LOAD_NONE, ECORE_OVERRIDE_FORCE_LOAD_ALWAYS, @@ -79,6 +85,11 @@ struct ecore_drv_load_params { #define ECORE_LOAD_REQ_LOCK_TO_DEFAULT 0 #define ECORE_LOAD_REQ_LOCK_TO_NONE 255 + /* Action to take in case the MFW doesn't support timeout values other + * than default and none. + */ + enum ecore_mfw_timeout_fallback mfw_timeout_fallback; + /* Avoid engine reset when first PF loads on it */ bool avoid_eng_reset; @@ -104,6 +115,9 @@ struct ecore_hw_init_params { /* Driver load parameters */ struct ecore_drv_load_params *p_drv_load_params; + + /* SPQ block timeout in msec */ + u32 spq_timeout_ms; }; /** diff --git a/drivers/net/qede/base/ecore_spq.c b/drivers/net/qede/base/ecore_spq.c index 70ffa8cd1c..a213bb8813 100644 --- a/drivers/net/qede/base/ecore_spq.c +++ b/drivers/net/qede/base/ecore_spq.c @@ -30,7 +30,7 @@ #define SPQ_BLOCK_DELAY_MAX_ITER (10) #define SPQ_BLOCK_DELAY_US (10) -#define SPQ_BLOCK_SLEEP_MAX_ITER (1000) +#define SPQ_BLOCK_SLEEP_MAX_ITER (200) #define SPQ_BLOCK_SLEEP_MS (5) /*************************************************************************** @@ -60,8 +60,12 @@ static enum _ecore_status_t __ecore_spq_block(struct ecore_hwfn *p_hwfn, u32 iter_cnt; comp_done = (struct ecore_spq_comp_done *)p_ent->comp_cb.cookie; - iter_cnt = sleep_between_iter ? SPQ_BLOCK_SLEEP_MAX_ITER + iter_cnt = sleep_between_iter ? p_hwfn->p_spq->block_sleep_max_iter : SPQ_BLOCK_DELAY_MAX_ITER; +#ifndef ASIC_ONLY + if (CHIP_REV_IS_EMUL(p_hwfn->p_dev) && sleep_between_iter) + iter_cnt *= 5; +#endif while (iter_cnt--) { OSAL_POLL_MODE_DPC(p_hwfn); @@ -138,6 +142,14 @@ err: return ECORE_BUSY; } +void ecore_set_spq_block_timeout(struct ecore_hwfn *p_hwfn, + u32 spq_timeout_ms) +{ + p_hwfn->p_spq->block_sleep_max_iter = spq_timeout_ms ? + spq_timeout_ms / SPQ_BLOCK_SLEEP_MS : + SPQ_BLOCK_SLEEP_MAX_ITER; +} + /*************************************************************************** * SPQ entries inner API ***************************************************************************/ diff --git a/drivers/net/qede/base/ecore_spq.h b/drivers/net/qede/base/ecore_spq.h index 526cff08f7..94ae9a68a2 100644 --- a/drivers/net/qede/base/ecore_spq.h +++ b/drivers/net/qede/base/ecore_spq.h @@ -116,6 +116,9 @@ struct ecore_spq { dma_addr_t p_phys; struct ecore_spq_entry *p_virt; + /* SPQ max sleep iterations used in __ecore_spq_block() */ + u32 block_sleep_max_iter; + /* Bitmap for handling out-of-order completions */ #define SPQ_RING_SIZE \ (CORE_SPQE_PAGE_SIZE_BYTES / sizeof(struct slow_path_element)) @@ -149,6 +152,16 @@ struct ecore_spq { struct ecore_port; struct ecore_hwfn; +/** + * @brief ecore_set_spq_block_timeout - calculates the maximum sleep + * iterations used in __ecore_spq_block(); + * + * @param p_hwfn + * @param spq_timeout_ms + */ +void ecore_set_spq_block_timeout(struct ecore_hwfn *p_hwfn, + u32 spq_timeout_ms); + /** * @brief ecore_spq_post - Posts a Slow hwfn request to FW, or lacking that * Pends it to the future list. diff --git a/drivers/net/qede/base/mcp_public.h b/drivers/net/qede/base/mcp_public.h index 81ca66348d..d3666a7069 100644 --- a/drivers/net/qede/base/mcp_public.h +++ b/drivers/net/qede/base/mcp_public.h @@ -1777,6 +1777,8 @@ struct public_drv_mb { #define FW_MB_PARAM_FEATURE_SUPPORT_SMARTLINQ 0x00000001 /* MFW supports EEE */ #define FW_MB_PARAM_FEATURE_SUPPORT_EEE 0x00000002 +/* MFW supports DRV_LOAD Timeout */ +#define FW_MB_PARAM_FEATURE_SUPPORT_DRV_LOAD_TO 0x00000004 /* MFW supports virtual link */ #define FW_MB_PARAM_FEATURE_SUPPORT_VLINK 0x00010000