net/qede/base: allow probe to succeed with minor HW-issues
authorRasesh Mody <rasesh.mody@cavium.com>
Wed, 29 Mar 2017 20:36:17 +0000 (13:36 -0700)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 4 Apr 2017 17:02:51 +0000 (19:02 +0200)
Allow probe to succeed with various 'minor' HW-issues [if requested]

Signed-off-by: Rasesh Mody <rasesh.mody@cavium.com>
drivers/net/qede/base/ecore_dev.c
drivers/net/qede/base/ecore_dev_api.h

index 1b033b7..907566c 100644 (file)
@@ -2445,12 +2445,15 @@ static enum _ecore_status_t ecore_hw_get_resc(struct ecore_hwfn *p_hwfn,
        return ECORE_SUCCESS;
 }
 
-static enum _ecore_status_t ecore_hw_get_nvm_info(struct ecore_hwfn *p_hwfn,
-                                                 struct ecore_ptt *p_ptt)
+static enum _ecore_status_t
+ecore_hw_get_nvm_info(struct ecore_hwfn *p_hwfn,
+                     struct ecore_ptt *p_ptt,
+                     struct ecore_hw_prepare_params *p_params)
 {
        u32 nvm_cfg1_offset, mf_mode, addr, generic_cont0, core_cfg, dcbx_mode;
        u32 port_cfg_addr, link_temp, nvm_cfg_addr, device_capabilities;
        struct ecore_mcp_link_params *link;
+       enum _ecore_status_t rc;
 
        /* Read global nvm_cfg address */
        nvm_cfg_addr = ecore_rd(p_hwfn, p_ptt, MISC_REG_GEN_PURP_CR0);
@@ -2458,6 +2461,8 @@ static enum _ecore_status_t ecore_hw_get_nvm_info(struct ecore_hwfn *p_hwfn,
        /* Verify MCP has initialized it */
        if (!nvm_cfg_addr) {
                DP_NOTICE(p_hwfn, false, "Shared memory not initialized\n");
+               if (p_params->b_relaxed_probe)
+                       p_params->p_relaxed_res = ECORE_HW_PREPARE_FAILED_NVM;
                return ECORE_INVAL;
        }
 
@@ -2643,7 +2648,13 @@ static enum _ecore_status_t ecore_hw_get_nvm_info(struct ecore_hwfn *p_hwfn,
                OSAL_SET_BIT(ECORE_DEV_CAP_IWARP,
                             &p_hwfn->hw_info.device_capabilities);
 
-       return ecore_mcp_fill_shmem_func_info(p_hwfn, p_ptt);
+       rc = ecore_mcp_fill_shmem_func_info(p_hwfn, p_ptt);
+       if (rc != ECORE_SUCCESS && p_params->b_relaxed_probe) {
+               rc = ECORE_SUCCESS;
+               p_params->p_relaxed_res = ECORE_HW_PREPARE_BAD_MCP;
+       }
+
+       return rc;
 }
 
 static void ecore_get_num_funcs(struct ecore_hwfn *p_hwfn,
@@ -2797,15 +2808,22 @@ static void ecore_hw_info_port_num(struct ecore_hwfn *p_hwfn,
 
 static enum _ecore_status_t
 ecore_get_hw_info(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
-                 enum ecore_pci_personality personality, bool drv_resc_alloc)
+                 enum ecore_pci_personality personality,
+                 struct ecore_hw_prepare_params *p_params)
 {
+       bool drv_resc_alloc = p_params->drv_resc_alloc;
        enum _ecore_status_t rc;
 
        /* Since all information is common, only first hwfns should do this */
        if (IS_LEAD_HWFN(p_hwfn)) {
                rc = ecore_iov_hw_info(p_hwfn);
-               if (rc != ECORE_SUCCESS)
-                       return rc;
+               if (rc != ECORE_SUCCESS) {
+                       if (p_params->b_relaxed_probe)
+                               p_params->p_relaxed_res =
+                                               ECORE_HW_PREPARE_BAD_IOV;
+                       else
+                               return rc;
+               }
        }
 
        /* TODO In get_hw_info, amoungst others:
@@ -2820,7 +2838,7 @@ ecore_get_hw_info(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
 #ifndef ASIC_ONLY
        if (CHIP_REV_IS_ASIC(p_hwfn->p_dev)) {
 #endif
-       rc = ecore_hw_get_nvm_info(p_hwfn, p_ptt);
+       rc = ecore_hw_get_nvm_info(p_hwfn, p_ptt, p_params);
        if (rc != ECORE_SUCCESS)
                return rc;
 #ifndef ASIC_ONLY
@@ -2828,8 +2846,12 @@ ecore_get_hw_info(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
 #endif
 
        rc = ecore_int_igu_read_cam(p_hwfn, p_ptt);
-       if (rc != ECORE_SUCCESS)
-               return rc;
+       if (rc != ECORE_SUCCESS) {
+               if (p_params->b_relaxed_probe)
+                       p_params->p_relaxed_res = ECORE_HW_PREPARE_BAD_IGU;
+               else
+                       return rc;
+       }
 
 #ifndef ASIC_ONLY
        if (CHIP_REV_IS_ASIC(p_hwfn->p_dev) && ecore_mcp_is_init(p_hwfn)) {
@@ -2896,7 +2918,13 @@ ecore_get_hw_info(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
         * the resources/features depends on them.
         * This order is not harmful if not forcing.
         */
-       return ecore_hw_get_resc(p_hwfn, drv_resc_alloc);
+       rc = ecore_hw_get_resc(p_hwfn, drv_resc_alloc);
+       if (rc != ECORE_SUCCESS && p_params->b_relaxed_probe) {
+               rc = ECORE_SUCCESS;
+               p_params->p_relaxed_res = ECORE_HW_PREPARE_BAD_MCP;
+       }
+
+       return rc;
 }
 
 static enum _ecore_status_t ecore_get_dev_info(struct ecore_dev *p_dev)
@@ -3028,6 +3056,8 @@ ecore_hw_prepare_single(struct ecore_hwfn *p_hwfn,
        if (REG_RD(p_hwfn, PXP_PF_ME_OPAQUE_ADDR) == 0xffffffff) {
                DP_ERR(p_hwfn,
                       "Reading the ME register returns all Fs; Preventing further chip access\n");
+               if (p_params->b_relaxed_probe)
+                       p_params->p_relaxed_res = ECORE_HW_PREPARE_FAILED_ME;
                return ECORE_INVAL;
        }
 
@@ -3037,6 +3067,8 @@ ecore_hw_prepare_single(struct ecore_hwfn *p_hwfn,
        rc = ecore_ptt_pool_alloc(p_hwfn);
        if (rc) {
                DP_NOTICE(p_hwfn, true, "Failed to prepare hwfn's hw\n");
+               if (p_params->b_relaxed_probe)
+                       p_params->p_relaxed_res = ECORE_HW_PREPARE_FAILED_MEM;
                goto err0;
        }
 
@@ -3046,8 +3078,12 @@ ecore_hw_prepare_single(struct ecore_hwfn *p_hwfn,
        /* First hwfn learns basic information, e.g., number of hwfns */
        if (!p_hwfn->my_id) {
                rc = ecore_get_dev_info(p_dev);
-               if (rc != ECORE_SUCCESS)
+               if (rc != ECORE_SUCCESS) {
+                       if (p_params->b_relaxed_probe)
+                               p_params->p_relaxed_res =
+                                       ECORE_HW_PREPARE_FAILED_DEV;
                        goto err1;
+               }
        }
 
        ecore_hw_hwfn_prepare(p_hwfn);
@@ -3056,12 +3092,14 @@ ecore_hw_prepare_single(struct ecore_hwfn *p_hwfn,
        rc = ecore_mcp_cmd_init(p_hwfn, p_hwfn->p_main_ptt);
        if (rc) {
                DP_NOTICE(p_hwfn, true, "Failed initializing mcp command\n");
+               if (p_params->b_relaxed_probe)
+                       p_params->p_relaxed_res = ECORE_HW_PREPARE_FAILED_MEM;
                goto err1;
        }
 
        /* Read the device configuration information from the HW and SHMEM */
        rc = ecore_get_hw_info(p_hwfn, p_hwfn->p_main_ptt,
-                              p_params->personality, p_params->drv_resc_alloc);
+                              p_params->personality, p_params);
        if (rc) {
                DP_NOTICE(p_hwfn, true, "Failed to get HW information\n");
                goto err2;
@@ -3094,6 +3132,8 @@ ecore_hw_prepare_single(struct ecore_hwfn *p_hwfn,
        rc = ecore_init_alloc(p_hwfn);
        if (rc) {
                DP_NOTICE(p_hwfn, true, "Failed to allocate the init array\n");
+               if (p_params->b_relaxed_probe)
+                       p_params->p_relaxed_res = ECORE_HW_PREPARE_FAILED_MEM;
                goto err2;
        }
 #ifndef ASIC_ONLY
@@ -3129,6 +3169,9 @@ enum _ecore_status_t ecore_hw_prepare(struct ecore_dev *p_dev,
 
        p_dev->chk_reg_fifo = p_params->chk_reg_fifo;
 
+       if (p_params->b_relaxed_probe)
+               p_params->p_relaxed_res = ECORE_HW_PREPARE_SUCCESS;
+
        /* Store the precompiled init data ptrs */
        if (IS_PF(p_dev))
                ecore_init_iro_array(p_dev);
@@ -3164,6 +3207,10 @@ enum _ecore_status_t ecore_hw_prepare(struct ecore_dev *p_dev,
                 * initiliazed hwfn 0.
                 */
                if (rc != ECORE_SUCCESS) {
+                       if (p_params->b_relaxed_probe)
+                               p_params->p_relaxed_res =
+                                               ECORE_HW_PREPARE_FAILED_ENG2;
+
                        if (IS_PF(p_dev)) {
                                ecore_init_free(p_hwfn);
                                ecore_mcp_free(p_hwfn);
index e7332ac..74a15ef 100644 (file)
@@ -138,17 +138,47 @@ void ecore_hw_start_fastpath(struct ecore_hwfn *p_hwfn);
  */
 enum _ecore_status_t ecore_hw_reset(struct ecore_dev *p_dev);
 
+enum ecore_hw_prepare_result {
+       ECORE_HW_PREPARE_SUCCESS,
+
+       /* FAILED results indicate probe has failed & cleaned up */
+       ECORE_HW_PREPARE_FAILED_ENG2,
+       ECORE_HW_PREPARE_FAILED_ME,
+       ECORE_HW_PREPARE_FAILED_MEM,
+       ECORE_HW_PREPARE_FAILED_DEV,
+       ECORE_HW_PREPARE_FAILED_NVM,
+
+       /* BAD results indicate probe is passed even though some wrongness
+        * has occurred; Trying to actually use [I.e., hw_init()] might have
+        * dire reprecautions.
+        */
+       ECORE_HW_PREPARE_BAD_IOV,
+       ECORE_HW_PREPARE_BAD_MCP,
+       ECORE_HW_PREPARE_BAD_IGU,
+};
+
 struct ecore_hw_prepare_params {
-       /* personality to initialize */
+       /* Personality to initialize */
        int personality;
-       /* force the driver's default resource allocation */
+
+       /* Force the driver's default resource allocation */
        bool drv_resc_alloc;
-       /* check the reg_fifo after any register access */
+
+       /* Check the reg_fifo after any register access */
        bool chk_reg_fifo;
-       /* request the MFW to initiate PF FLR */
+
+       /* Request the MFW to initiate PF FLR */
        bool initiate_pf_flr;
-       /* the OS Epoch time in seconds */
+
+       /* The OS Epoch time in seconds */
        u32 epoch;
+
+       /* Allow prepare to pass even if some initializations are failing.
+        * If set, the `p_prepare_res' field would be set with the return,
+        * and might allow probe to pass even if there are certain issues.
+        */
+       bool b_relaxed_probe;
+       enum ecore_hw_prepare_result p_relaxed_res;
 };
 
 /**