net/qede/base: get pre-negotiated OEM values
[dpdk.git] / drivers / net / qede / base / ecore_dev.c
index fdb62f2..30e12e9 100644 (file)
@@ -456,6 +456,12 @@ static void ecore_qm_info_free(struct ecore_hwfn *p_hwfn)
        OSAL_FREE(p_hwfn->p_dev, qm_info->wfq_data);
 }
 
+static void ecore_dbg_user_data_free(struct ecore_hwfn *p_hwfn)
+{
+       OSAL_FREE(p_hwfn->p_dev, p_hwfn->dbg_user_info);
+       p_hwfn->dbg_user_info = OSAL_NULL;
+}
+
 void ecore_resc_free(struct ecore_dev *p_dev)
 {
        int i;
@@ -483,6 +489,7 @@ void ecore_resc_free(struct ecore_dev *p_dev)
                ecore_l2_free(p_hwfn);
                ecore_dmae_info_free(p_hwfn);
                ecore_dcbx_info_free(p_hwfn);
+               ecore_dbg_user_data_free(p_hwfn);
                /* @@@TBD Flush work-queue ? */
 
                /* destroy doorbell recovery mechanism */
@@ -562,12 +569,11 @@ u16 ecore_init_qm_get_num_pf_rls(struct ecore_hwfn *p_hwfn)
 {
        u16 num_pf_rls, num_vfs = ecore_init_qm_get_num_vfs(p_hwfn);
 
-       /* @DPDK */
        /* num RLs can't exceed resource amount of rls or vports or the
         * dcqcn qps
         */
        num_pf_rls = (u16)OSAL_MIN_T(u32, RESC_NUM(p_hwfn, ECORE_RL),
-                                    (u16)RESC_NUM(p_hwfn, ECORE_VPORT));
+                                    RESC_NUM(p_hwfn, ECORE_VPORT));
 
        /* make sure after we reserve the default and VF rls we'll have
         * something left
@@ -828,7 +834,7 @@ u16 ecore_get_cm_pq_idx_mcos(struct ecore_hwfn *p_hwfn, u8 tc)
        if (tc > max_tc)
                DP_ERR(p_hwfn, "tc %d must be smaller than %d\n", tc, max_tc);
 
-       return ecore_get_cm_pq_idx(p_hwfn, PQ_FLAGS_MCOS) + tc;
+       return ecore_get_cm_pq_idx(p_hwfn, PQ_FLAGS_MCOS) + (tc % max_tc);
 }
 
 u16 ecore_get_cm_pq_idx_vf(struct ecore_hwfn *p_hwfn, u16 vf)
@@ -838,17 +844,17 @@ u16 ecore_get_cm_pq_idx_vf(struct ecore_hwfn *p_hwfn, u16 vf)
        if (vf > max_vf)
                DP_ERR(p_hwfn, "vf %d must be smaller than %d\n", vf, max_vf);
 
-       return ecore_get_cm_pq_idx(p_hwfn, PQ_FLAGS_VFS) + vf;
+       return ecore_get_cm_pq_idx(p_hwfn, PQ_FLAGS_VFS) + (vf % max_vf);
 }
 
 u16 ecore_get_cm_pq_idx_rl(struct ecore_hwfn *p_hwfn, u16 rl)
 {
        u16 max_rl = ecore_init_qm_get_num_pf_rls(p_hwfn);
 
-       if (rl > max_rl)
-               DP_ERR(p_hwfn, "rl %d must be smaller than %d\n", rl, max_rl);
-
-       return ecore_get_cm_pq_idx(p_hwfn, PQ_FLAGS_RLS) + rl;
+       /* for rate limiters, it is okay to use the modulo behavior - no
+        * DP_ERR
+        */
+       return ecore_get_cm_pq_idx(p_hwfn, PQ_FLAGS_RLS) + (rl % max_rl);
 }
 
 u16 ecore_get_qm_vport_idx_rl(struct ecore_hwfn *p_hwfn, u16 rl)
@@ -1334,7 +1340,14 @@ enum _ecore_status_t ecore_resc_alloc(struct ecore_dev *p_dev)
                                  "Failed to allocate memory for dcbx structure\n");
                        goto alloc_err;
                }
-       }
+
+               rc = OSAL_DBG_ALLOC_USER_DATA(p_hwfn, &p_hwfn->dbg_user_info);
+               if (rc) {
+                       DP_NOTICE(p_hwfn, false,
+                                 "Failed to allocate dbg user info structure\n");
+                       goto alloc_err;
+               }
+       } /* hwfn loop */
 
        p_dev->reset_stats = OSAL_ZALLOC(p_dev, GFP_KERNEL,
                                         sizeof(*p_dev->reset_stats));
@@ -1960,6 +1973,14 @@ enum ECORE_ROCE_EDPM_MODE {
        ECORE_ROCE_EDPM_MODE_DISABLE = 2,
 };
 
+bool ecore_edpm_enabled(struct ecore_hwfn *p_hwfn)
+{
+       if (p_hwfn->dcbx_no_edpm || p_hwfn->db_bar_no_edpm)
+               return false;
+
+       return true;
+}
+
 static enum _ecore_status_t
 ecore_hw_init_pf_doorbell_bar(struct ecore_hwfn *p_hwfn,
                              struct ecore_ptt *p_ptt)
@@ -2047,7 +2068,7 @@ ecore_hw_init_pf_doorbell_bar(struct ecore_hwfn *p_hwfn,
        DP_INFO(p_hwfn,
                " dpi_size=%d, dpi_count=%d, roce_edpm=%s\n",
                p_hwfn->dpi_size, p_hwfn->dpi_count,
-               ((p_hwfn->dcbx_no_edpm) || (p_hwfn->db_bar_no_edpm)) ?
+               (!ecore_edpm_enabled(p_hwfn)) ?
                "disabled" : "enabled");
 
        /* Check return codes from above calls */
@@ -2624,6 +2645,20 @@ enum _ecore_status_t ecore_hw_init(struct ecore_dev *p_dev,
                                  "Failed to send GET_OEM_UPDATES attention request\n");
        }
 
+       if (IS_PF(p_dev)) {
+               /* Get pre-negotiated values for stag, bandwidth etc. */
+               p_hwfn = ECORE_LEADING_HWFN(p_dev);
+               DP_VERBOSE(p_hwfn, ECORE_MSG_SPQ,
+                          "Sending GET_OEM_UPDATES command to trigger stag/bandwidth attention handling\n");
+               rc = ecore_mcp_cmd(p_hwfn, p_hwfn->p_main_ptt,
+                                  DRV_MSG_CODE_GET_OEM_UPDATES,
+                                  1 << DRV_MB_PARAM_DUMMY_OEM_UPDATES_OFFSET,
+                                  &resp, &param);
+               if (rc != ECORE_SUCCESS)
+                       DP_NOTICE(p_hwfn, false,
+                                 "Failed to send GET_OEM_UPDATES attention request\n");
+       }
+
        if (IS_PF(p_dev)) {
                p_hwfn = ECORE_LEADING_HWFN(p_dev);
                drv_mb_param = STORM_FW_VERSION;
@@ -2782,6 +2817,12 @@ enum _ecore_status_t ecore_hw_stop(struct ecore_dev *p_dev)
                        rc2 = ECORE_UNKNOWN_ERROR;
                }
 
+               OSAL_DPC_SYNC(p_hwfn);
+
+               /* After this point we don't expect the FW to send us async
+                * events
+                */
+
                /* perform debug action after PF stop was sent */
                OSAL_AFTER_PF_STOP((void *)p_dev, p_hwfn->my_id);
 
@@ -3676,7 +3717,8 @@ ecore_hw_get_nvm_info(struct ecore_hwfn *p_hwfn,
        case NVM_CFG1_GLOB_MF_MODE_BD:
                p_hwfn->p_dev->mf_bits = 1 << ECORE_MF_OVLAN_CLSS |
                                         1 << ECORE_MF_LLH_PROTO_CLSS |
-                                        1 << ECORE_MF_8021AD_TAGGING;
+                                        1 << ECORE_MF_8021AD_TAGGING |
+                                        1 << ECORE_MF_FIP_SPECIAL;
                break;
        case NVM_CFG1_GLOB_MF_MODE_NPAR1_0:
                p_hwfn->p_dev->mf_bits = 1 << ECORE_MF_LLH_MAC_CLSS |
@@ -4272,6 +4314,13 @@ ecore_hw_prepare_single(struct ecore_hwfn *p_hwfn,
                rc = ecore_mcp_initiate_pf_flr(p_hwfn, p_hwfn->p_main_ptt);
                if (rc != ECORE_SUCCESS)
                        DP_NOTICE(p_hwfn, false, "Failed to initiate PF FLR\n");
+
+               /* Workaround for MFW issue where PF FLR does not cleanup
+                * IGU block
+                */
+               if (!(p_hwfn->mcp_info->capabilities &
+                     FW_MB_PARAM_FEATURE_SUPPORT_IGU_CLEANUP))
+                       ecore_pf_flr_igu_cleanup(p_hwfn);
        }
 
        /* Check if mdump logs/data are present and update the epoch value */
@@ -5769,3 +5818,8 @@ void ecore_set_fw_mac_addr(__le16 *fw_msb,
        ((u8 *)fw_lsb)[0] = mac[5];
        ((u8 *)fw_lsb)[1] = mac[4];
 }
+
+bool ecore_is_mf_fip_special(struct ecore_dev *p_dev)
+{
+       return !!OSAL_TEST_BIT(ECORE_MF_FIP_SPECIAL, &p_dev->mf_bits);
+}