1dd0191d5SShuanglin Wang /* SPDX-License-Identifier: BSD-3-Clause 2dd0191d5SShuanglin Wang * Copyright(c) 2019-2021 Broadcom 3dd0191d5SShuanglin Wang * All rights reserved. 4dd0191d5SShuanglin Wang */ 5dd0191d5SShuanglin Wang 6dd0191d5SShuanglin Wang #include <rte_log.h> 7dd0191d5SShuanglin Wang #include <rte_malloc.h> 8dd0191d5SShuanglin Wang #include <rte_flow.h> 9dd0191d5SShuanglin Wang #include <rte_flow_driver.h> 10dd0191d5SShuanglin Wang #include <rte_tailq.h> 11dd0191d5SShuanglin Wang #include <rte_spinlock.h> 1280d760e1SJay Ding #include <rte_mtr.h> 1380d760e1SJay Ding #include <rte_version.h> 14b14da654SPeter Spreadborough #include <rte_hash_crc.h> 15dd0191d5SShuanglin Wang 16dd0191d5SShuanglin Wang #include "bnxt.h" 17dd0191d5SShuanglin Wang #include "bnxt_ulp.h" 180c036a14SPeter Spreadborough #include "bnxt_ulp_utils.h" 19dd0191d5SShuanglin Wang #include "bnxt_ulp_tf.h" 20dd0191d5SShuanglin Wang #include "bnxt_tf_common.h" 21dd0191d5SShuanglin Wang #include "hsi_struct_def_dpdk.h" 22dd0191d5SShuanglin Wang #include "tf_core.h" 23dd0191d5SShuanglin Wang #include "tf_ext_flow_handle.h" 24dd0191d5SShuanglin Wang 25dd0191d5SShuanglin Wang #include "ulp_template_db_enum.h" 26dd0191d5SShuanglin Wang #include "ulp_template_struct.h" 27dd0191d5SShuanglin Wang #include "ulp_mark_mgr.h" 28dd0191d5SShuanglin Wang #include "ulp_fc_mgr.h" 29dd0191d5SShuanglin Wang #include "ulp_flow_db.h" 30dd0191d5SShuanglin Wang #include "ulp_mapper.h" 31dd0191d5SShuanglin Wang #include "ulp_matcher.h" 32dd0191d5SShuanglin Wang #include "ulp_port_db.h" 33dd0191d5SShuanglin Wang #include "ulp_tun.h" 34dd0191d5SShuanglin Wang #include "ulp_ha_mgr.h" 35dd0191d5SShuanglin Wang #include "bnxt_tf_pmd_shim.h" 36dd0191d5SShuanglin Wang #include "ulp_template_db_tbl.h" 37dd0191d5SShuanglin Wang 38dd0191d5SShuanglin Wang /* Function to set the tfp session details from the ulp context. */ 39dd0191d5SShuanglin Wang int32_t 40dd0191d5SShuanglin Wang bnxt_ulp_cntxt_tfp_set(struct bnxt_ulp_context *ulp, 41dd0191d5SShuanglin Wang enum bnxt_ulp_session_type s_type, 42dd0191d5SShuanglin Wang struct tf *tfp) 43dd0191d5SShuanglin Wang { 44dd0191d5SShuanglin Wang uint32_t idx = 0; 45dd0191d5SShuanglin Wang enum bnxt_ulp_tfo_type tfo_type = BNXT_ULP_TFO_TYPE_TF; 46dd0191d5SShuanglin Wang 47dd0191d5SShuanglin Wang if (ulp == NULL) 48dd0191d5SShuanglin Wang return -EINVAL; 49dd0191d5SShuanglin Wang 50dd0191d5SShuanglin Wang if (ULP_MULTI_SHARED_IS_SUPPORTED(ulp)) { 51dd0191d5SShuanglin Wang if (s_type & BNXT_ULP_SESSION_TYPE_SHARED) 52dd0191d5SShuanglin Wang idx = 1; 53dd0191d5SShuanglin Wang else if (s_type & BNXT_ULP_SESSION_TYPE_SHARED_WC) 54dd0191d5SShuanglin Wang idx = 2; 55dd0191d5SShuanglin Wang 56dd0191d5SShuanglin Wang } else { 57dd0191d5SShuanglin Wang if ((s_type & BNXT_ULP_SESSION_TYPE_SHARED) || 58dd0191d5SShuanglin Wang (s_type & BNXT_ULP_SESSION_TYPE_SHARED_WC)) 59dd0191d5SShuanglin Wang idx = 1; 60dd0191d5SShuanglin Wang } 61dd0191d5SShuanglin Wang 62dd0191d5SShuanglin Wang ulp->g_tfp[idx] = tfp; 63dd0191d5SShuanglin Wang 64dd0191d5SShuanglin Wang if (tfp == NULL) { 65dd0191d5SShuanglin Wang uint32_t i = 0; 66dd0191d5SShuanglin Wang while (i < BNXT_ULP_SESSION_MAX && ulp->g_tfp[i] == NULL) 67dd0191d5SShuanglin Wang i++; 68dd0191d5SShuanglin Wang if (i == BNXT_ULP_SESSION_MAX) 69dd0191d5SShuanglin Wang ulp->tfo_type = BNXT_ULP_TFO_TYPE_INVALID; 70dd0191d5SShuanglin Wang } else { 71dd0191d5SShuanglin Wang ulp->tfo_type = tfo_type; 72dd0191d5SShuanglin Wang } 73dd0191d5SShuanglin Wang return 0; 74dd0191d5SShuanglin Wang } 75dd0191d5SShuanglin Wang 76dd0191d5SShuanglin Wang /* Function to get the tfp session details from the ulp context. */ 77dd0191d5SShuanglin Wang struct tf * 78dd0191d5SShuanglin Wang bnxt_ulp_cntxt_tfp_get(struct bnxt_ulp_context *ulp, 79dd0191d5SShuanglin Wang enum bnxt_ulp_session_type s_type) 80dd0191d5SShuanglin Wang { 81dd0191d5SShuanglin Wang uint32_t idx = 0; 82dd0191d5SShuanglin Wang 83dd0191d5SShuanglin Wang if (ulp == NULL) 84dd0191d5SShuanglin Wang return NULL; 85dd0191d5SShuanglin Wang 86dd0191d5SShuanglin Wang if (ulp->tfo_type != BNXT_ULP_TFO_TYPE_TF) { 87dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Wrong tf type %d != %d\n", 88dd0191d5SShuanglin Wang ulp->tfo_type, BNXT_ULP_TFO_TYPE_TF); 89dd0191d5SShuanglin Wang return NULL; 90dd0191d5SShuanglin Wang } 91dd0191d5SShuanglin Wang 92dd0191d5SShuanglin Wang if (ULP_MULTI_SHARED_IS_SUPPORTED(ulp)) { 93dd0191d5SShuanglin Wang if (s_type & BNXT_ULP_SESSION_TYPE_SHARED) 94dd0191d5SShuanglin Wang idx = 1; 95dd0191d5SShuanglin Wang else if (s_type & BNXT_ULP_SESSION_TYPE_SHARED_WC) 96dd0191d5SShuanglin Wang idx = 2; 97dd0191d5SShuanglin Wang } else { 98dd0191d5SShuanglin Wang if ((s_type & BNXT_ULP_SESSION_TYPE_SHARED) || 99dd0191d5SShuanglin Wang (s_type & BNXT_ULP_SESSION_TYPE_SHARED_WC)) 100dd0191d5SShuanglin Wang idx = 1; 101dd0191d5SShuanglin Wang } 102dd0191d5SShuanglin Wang return (struct tf *)ulp->g_tfp[idx]; 103dd0191d5SShuanglin Wang } 104dd0191d5SShuanglin Wang 105dd0191d5SShuanglin Wang struct tf *bnxt_get_tfp_session(struct bnxt *bp, enum bnxt_session_type type) 106dd0191d5SShuanglin Wang { 107dd0191d5SShuanglin Wang return (type >= BNXT_SESSION_TYPE_LAST) ? 108dd0191d5SShuanglin Wang &bp->tfp[BNXT_SESSION_TYPE_REGULAR] : &bp->tfp[type]; 109dd0191d5SShuanglin Wang } 110dd0191d5SShuanglin Wang 111dd0191d5SShuanglin Wang struct tf * 112dd0191d5SShuanglin Wang bnxt_ulp_bp_tfp_get(struct bnxt *bp, enum bnxt_ulp_session_type type) 113dd0191d5SShuanglin Wang { 114dd0191d5SShuanglin Wang enum bnxt_session_type btype; 115dd0191d5SShuanglin Wang 116dd0191d5SShuanglin Wang if (type & BNXT_ULP_SESSION_TYPE_SHARED) 117dd0191d5SShuanglin Wang btype = BNXT_SESSION_TYPE_SHARED_COMMON; 118dd0191d5SShuanglin Wang else if (type & BNXT_ULP_SESSION_TYPE_SHARED_WC) 119dd0191d5SShuanglin Wang btype = BNXT_SESSION_TYPE_SHARED_WC; 120dd0191d5SShuanglin Wang else 121dd0191d5SShuanglin Wang btype = BNXT_SESSION_TYPE_REGULAR; 122dd0191d5SShuanglin Wang 123dd0191d5SShuanglin Wang return bnxt_get_tfp_session(bp, btype); 124dd0191d5SShuanglin Wang } 125dd0191d5SShuanglin Wang 126dd0191d5SShuanglin Wang static int32_t 127dd0191d5SShuanglin Wang ulp_tf_named_resources_calc(struct bnxt_ulp_context *ulp_ctx, 128dd0191d5SShuanglin Wang struct bnxt_ulp_glb_resource_info *info, 129dd0191d5SShuanglin Wang uint32_t num, 130dd0191d5SShuanglin Wang enum bnxt_ulp_session_type stype, 131dd0191d5SShuanglin Wang struct tf_session_resources *res) 132dd0191d5SShuanglin Wang { 133dd0191d5SShuanglin Wang uint32_t dev_id = BNXT_ULP_DEVICE_ID_LAST, res_type, i; 134dd0191d5SShuanglin Wang enum tf_dir dir; 135dd0191d5SShuanglin Wang uint8_t app_id; 136dd0191d5SShuanglin Wang int32_t rc = 0; 137dd0191d5SShuanglin Wang 138dd0191d5SShuanglin Wang if (ulp_ctx == NULL || info == NULL || res == NULL || num == 0) { 139dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid parms to named resources calc.\n"); 140dd0191d5SShuanglin Wang return -EINVAL; 141dd0191d5SShuanglin Wang } 142dd0191d5SShuanglin Wang 143dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_app_id_get(ulp_ctx, &app_id); 144dd0191d5SShuanglin Wang if (rc) { 145dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to get the app id from ulp.\n"); 146dd0191d5SShuanglin Wang return -EINVAL; 147dd0191d5SShuanglin Wang } 148dd0191d5SShuanglin Wang 149dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id); 150dd0191d5SShuanglin Wang if (rc) { 151dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to get the dev id from ulp.\n"); 152dd0191d5SShuanglin Wang return -EINVAL; 153dd0191d5SShuanglin Wang } 154dd0191d5SShuanglin Wang 155dd0191d5SShuanglin Wang for (i = 0; i < num; i++) { 156dd0191d5SShuanglin Wang if (dev_id != info[i].device_id || app_id != info[i].app_id) 157dd0191d5SShuanglin Wang continue; 158dd0191d5SShuanglin Wang /* check to see if the session type matches only then include */ 159dd0191d5SShuanglin Wang if ((stype || info[i].session_type) && 160dd0191d5SShuanglin Wang !(info[i].session_type & stype)) 161dd0191d5SShuanglin Wang continue; 162dd0191d5SShuanglin Wang 163dd0191d5SShuanglin Wang dir = info[i].direction; 164dd0191d5SShuanglin Wang res_type = info[i].resource_type; 165dd0191d5SShuanglin Wang 166dd0191d5SShuanglin Wang switch (info[i].resource_func) { 167dd0191d5SShuanglin Wang case BNXT_ULP_RESOURCE_FUNC_IDENTIFIER: 168dd0191d5SShuanglin Wang res->ident_cnt[dir].cnt[res_type]++; 169dd0191d5SShuanglin Wang break; 170dd0191d5SShuanglin Wang case BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE: 171dd0191d5SShuanglin Wang res->tbl_cnt[dir].cnt[res_type]++; 172dd0191d5SShuanglin Wang break; 173dd0191d5SShuanglin Wang case BNXT_ULP_RESOURCE_FUNC_TCAM_TABLE: 174dd0191d5SShuanglin Wang res->tcam_cnt[dir].cnt[res_type]++; 175dd0191d5SShuanglin Wang break; 176dd0191d5SShuanglin Wang case BNXT_ULP_RESOURCE_FUNC_EM_TABLE: 177dd0191d5SShuanglin Wang res->em_cnt[dir].cnt[res_type]++; 178dd0191d5SShuanglin Wang break; 179dd0191d5SShuanglin Wang default: 180dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unknown resource func (0x%x)\n,", 181dd0191d5SShuanglin Wang info[i].resource_func); 182dd0191d5SShuanglin Wang continue; 183dd0191d5SShuanglin Wang } 184dd0191d5SShuanglin Wang } 185dd0191d5SShuanglin Wang 186dd0191d5SShuanglin Wang return 0; 187dd0191d5SShuanglin Wang } 188dd0191d5SShuanglin Wang 189dd0191d5SShuanglin Wang static int32_t 190dd0191d5SShuanglin Wang ulp_tf_unnamed_resources_calc(struct bnxt_ulp_context *ulp_ctx, 191dd0191d5SShuanglin Wang struct bnxt_ulp_resource_resv_info *info, 192dd0191d5SShuanglin Wang uint32_t num, 193dd0191d5SShuanglin Wang enum bnxt_ulp_session_type stype, 194dd0191d5SShuanglin Wang struct tf_session_resources *res) 195dd0191d5SShuanglin Wang { 196dd0191d5SShuanglin Wang uint32_t dev_id, res_type, i; 197dd0191d5SShuanglin Wang enum tf_dir dir; 198dd0191d5SShuanglin Wang uint8_t app_id; 199dd0191d5SShuanglin Wang int32_t rc = 0; 200dd0191d5SShuanglin Wang 201dd0191d5SShuanglin Wang if (ulp_ctx == NULL || res == NULL || info == NULL || num == 0) { 202dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid arguments to get resources.\n"); 203dd0191d5SShuanglin Wang return -EINVAL; 204dd0191d5SShuanglin Wang } 205dd0191d5SShuanglin Wang 206dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_app_id_get(ulp_ctx, &app_id); 207dd0191d5SShuanglin Wang if (rc) { 208dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to get the app id from ulp.\n"); 209dd0191d5SShuanglin Wang return -EINVAL; 210dd0191d5SShuanglin Wang } 211dd0191d5SShuanglin Wang 212dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id); 213dd0191d5SShuanglin Wang if (rc) { 214dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to get the dev id from ulp.\n"); 215dd0191d5SShuanglin Wang return -EINVAL; 216dd0191d5SShuanglin Wang } 217dd0191d5SShuanglin Wang 218dd0191d5SShuanglin Wang for (i = 0; i < num; i++) { 219dd0191d5SShuanglin Wang if (app_id != info[i].app_id || dev_id != info[i].device_id) 220dd0191d5SShuanglin Wang continue; 221dd0191d5SShuanglin Wang 222dd0191d5SShuanglin Wang /* check to see if the session type matches only then include */ 223dd0191d5SShuanglin Wang if ((stype || info[i].session_type) && 224dd0191d5SShuanglin Wang !(info[i].session_type & stype)) 225dd0191d5SShuanglin Wang continue; 226dd0191d5SShuanglin Wang 227dd0191d5SShuanglin Wang dir = info[i].direction; 228dd0191d5SShuanglin Wang res_type = info[i].resource_type; 229dd0191d5SShuanglin Wang 230dd0191d5SShuanglin Wang switch (info[i].resource_func) { 231dd0191d5SShuanglin Wang case BNXT_ULP_RESOURCE_FUNC_IDENTIFIER: 232dd0191d5SShuanglin Wang res->ident_cnt[dir].cnt[res_type] = info[i].count; 233dd0191d5SShuanglin Wang break; 234dd0191d5SShuanglin Wang case BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE: 235dd0191d5SShuanglin Wang res->tbl_cnt[dir].cnt[res_type] = info[i].count; 236dd0191d5SShuanglin Wang break; 237dd0191d5SShuanglin Wang case BNXT_ULP_RESOURCE_FUNC_TCAM_TABLE: 238dd0191d5SShuanglin Wang res->tcam_cnt[dir].cnt[res_type] = info[i].count; 239dd0191d5SShuanglin Wang break; 240dd0191d5SShuanglin Wang case BNXT_ULP_RESOURCE_FUNC_EM_TABLE: 241dd0191d5SShuanglin Wang res->em_cnt[dir].cnt[res_type] = info[i].count; 242dd0191d5SShuanglin Wang break; 243dd0191d5SShuanglin Wang default: 244dd0191d5SShuanglin Wang break; 245dd0191d5SShuanglin Wang } 246dd0191d5SShuanglin Wang } 247dd0191d5SShuanglin Wang return 0; 248dd0191d5SShuanglin Wang } 249dd0191d5SShuanglin Wang 250dd0191d5SShuanglin Wang static int32_t 251dd0191d5SShuanglin Wang ulp_tf_resources_get(struct bnxt_ulp_context *ulp_ctx, 252dd0191d5SShuanglin Wang enum bnxt_ulp_session_type stype, 253dd0191d5SShuanglin Wang struct tf_session_resources *res) 254dd0191d5SShuanglin Wang { 255dd0191d5SShuanglin Wang struct bnxt_ulp_resource_resv_info *unnamed = NULL; 256dd0191d5SShuanglin Wang uint32_t unum; 257dd0191d5SShuanglin Wang int32_t rc = 0; 258dd0191d5SShuanglin Wang 259dd0191d5SShuanglin Wang if (ulp_ctx == NULL || res == NULL) { 260dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid arguments to get resources.\n"); 261dd0191d5SShuanglin Wang return -EINVAL; 262dd0191d5SShuanglin Wang } 263dd0191d5SShuanglin Wang 26461a7ca1fSKishore Padmanabha /* use DEFAULT_NON_HA instead of DEFAULT resources if HA is disabled */ 26561a7ca1fSKishore Padmanabha if (ULP_APP_HA_IS_DYNAMIC(ulp_ctx)) 26661a7ca1fSKishore Padmanabha stype = ulp_ctx->cfg_data->def_session_type; 26761a7ca1fSKishore Padmanabha 268dd0191d5SShuanglin Wang unnamed = bnxt_ulp_resource_resv_list_get(&unum); 269dd0191d5SShuanglin Wang if (unnamed == NULL) { 270dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to get resource resv list.\n"); 271dd0191d5SShuanglin Wang return -EINVAL; 272dd0191d5SShuanglin Wang } 273dd0191d5SShuanglin Wang 274dd0191d5SShuanglin Wang rc = ulp_tf_unnamed_resources_calc(ulp_ctx, unnamed, unum, stype, res); 275dd0191d5SShuanglin Wang if (rc) 276dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to calc resources for session.\n"); 277dd0191d5SShuanglin Wang 278dd0191d5SShuanglin Wang return rc; 279dd0191d5SShuanglin Wang } 280dd0191d5SShuanglin Wang 281dd0191d5SShuanglin Wang static int32_t 282dd0191d5SShuanglin Wang ulp_tf_shared_session_resources_get(struct bnxt_ulp_context *ulp_ctx, 283dd0191d5SShuanglin Wang enum bnxt_ulp_session_type stype, 284dd0191d5SShuanglin Wang struct tf_session_resources *res) 285dd0191d5SShuanglin Wang { 286dd0191d5SShuanglin Wang struct bnxt_ulp_resource_resv_info *unnamed; 287dd0191d5SShuanglin Wang struct bnxt_ulp_glb_resource_info *named; 288dd0191d5SShuanglin Wang uint32_t unum = 0, nnum = 0; 289dd0191d5SShuanglin Wang int32_t rc; 290dd0191d5SShuanglin Wang 291dd0191d5SShuanglin Wang if (ulp_ctx == NULL || res == NULL) { 292dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid arguments to get resources.\n"); 293dd0191d5SShuanglin Wang return -EINVAL; 294dd0191d5SShuanglin Wang } 295dd0191d5SShuanglin Wang 296dd0191d5SShuanglin Wang /* Make sure the resources are zero before accumulating. */ 297dd0191d5SShuanglin Wang memset(res, 0, sizeof(struct tf_session_resources)); 298dd0191d5SShuanglin Wang 299dd0191d5SShuanglin Wang if (bnxt_ulp_cntxt_ha_enabled(ulp_ctx) && 300dd0191d5SShuanglin Wang stype == BNXT_ULP_SESSION_TYPE_SHARED) 301dd0191d5SShuanglin Wang stype = ulp_ctx->cfg_data->hu_session_type; 302dd0191d5SShuanglin Wang 303dd0191d5SShuanglin Wang /* 304dd0191d5SShuanglin Wang * Shared resources are comprised of both named and unnamed resources. 305dd0191d5SShuanglin Wang * First get the unnamed counts, and then add the named to the result. 306dd0191d5SShuanglin Wang */ 307dd0191d5SShuanglin Wang /* Get the baseline counts */ 308dd0191d5SShuanglin Wang unnamed = bnxt_ulp_app_resource_resv_list_get(&unum); 309dd0191d5SShuanglin Wang if (unum) { 310dd0191d5SShuanglin Wang rc = ulp_tf_unnamed_resources_calc(ulp_ctx, unnamed, 311dd0191d5SShuanglin Wang unum, stype, res); 312dd0191d5SShuanglin Wang if (rc) { 313dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 314dd0191d5SShuanglin Wang "Unable to calc resources for shared session.\n"); 315dd0191d5SShuanglin Wang return -EINVAL; 316dd0191d5SShuanglin Wang } 317dd0191d5SShuanglin Wang } 318dd0191d5SShuanglin Wang 319dd0191d5SShuanglin Wang /* Get the named list and add the totals */ 320dd0191d5SShuanglin Wang named = bnxt_ulp_app_glb_resource_info_list_get(&nnum); 321dd0191d5SShuanglin Wang /* No need to calc resources, none to calculate */ 322dd0191d5SShuanglin Wang if (!nnum) 323dd0191d5SShuanglin Wang return 0; 324dd0191d5SShuanglin Wang 325dd0191d5SShuanglin Wang rc = ulp_tf_named_resources_calc(ulp_ctx, named, nnum, stype, res); 326dd0191d5SShuanglin Wang if (rc) 327dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to calc named resources\n"); 328dd0191d5SShuanglin Wang 329dd0191d5SShuanglin Wang return rc; 330dd0191d5SShuanglin Wang } 331dd0191d5SShuanglin Wang 332dd0191d5SShuanglin Wang /* Function to set the hot upgrade support into the context */ 333dd0191d5SShuanglin Wang static int 334dd0191d5SShuanglin Wang ulp_tf_multi_shared_session_support_set(struct bnxt *bp, 335dd0191d5SShuanglin Wang enum bnxt_ulp_device_id devid, 336dd0191d5SShuanglin Wang uint32_t fw_hu_update) 337dd0191d5SShuanglin Wang { 338dd0191d5SShuanglin Wang struct bnxt_ulp_context *ulp_ctx = bp->ulp_ctx; 339dd0191d5SShuanglin Wang struct tf_get_version_parms v_params = { 0 }; 340dd0191d5SShuanglin Wang struct tf *tfp; 341dd0191d5SShuanglin Wang int32_t rc = 0; 342dd0191d5SShuanglin Wang int32_t new_fw = 0; 343dd0191d5SShuanglin Wang 344dd0191d5SShuanglin Wang v_params.device_type = bnxt_ulp_cntxt_convert_dev_id(devid); 345dd0191d5SShuanglin Wang v_params.bp = bp; 346dd0191d5SShuanglin Wang 347dd0191d5SShuanglin Wang tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT); 348dd0191d5SShuanglin Wang rc = tf_get_version(tfp, &v_params); 349dd0191d5SShuanglin Wang if (rc) { 350dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to get tf version.\n"); 351dd0191d5SShuanglin Wang return rc; 352dd0191d5SShuanglin Wang } 353dd0191d5SShuanglin Wang 354dd0191d5SShuanglin Wang if (v_params.major == 1 && v_params.minor == 0 && 355dd0191d5SShuanglin Wang v_params.update == 1) { 356dd0191d5SShuanglin Wang new_fw = 1; 357dd0191d5SShuanglin Wang } 358dd0191d5SShuanglin Wang /* if the version update is greater than 0 then set support for 359dd0191d5SShuanglin Wang * multiple version 360dd0191d5SShuanglin Wang */ 361dd0191d5SShuanglin Wang if (new_fw) { 362dd0191d5SShuanglin Wang ulp_ctx->cfg_data->ulp_flags |= BNXT_ULP_MULTI_SHARED_SUPPORT; 363dd0191d5SShuanglin Wang ulp_ctx->cfg_data->hu_session_type = 364dd0191d5SShuanglin Wang BNXT_ULP_SESSION_TYPE_SHARED; 365dd0191d5SShuanglin Wang } 366dd0191d5SShuanglin Wang if (!new_fw && fw_hu_update) { 367dd0191d5SShuanglin Wang ulp_ctx->cfg_data->ulp_flags &= ~BNXT_ULP_HIGH_AVAIL_ENABLED; 368dd0191d5SShuanglin Wang ulp_ctx->cfg_data->hu_session_type = 369dd0191d5SShuanglin Wang BNXT_ULP_SESSION_TYPE_SHARED | 370dd0191d5SShuanglin Wang BNXT_ULP_SESSION_TYPE_SHARED_OWC; 371dd0191d5SShuanglin Wang } 372dd0191d5SShuanglin Wang 373dd0191d5SShuanglin Wang if (!new_fw && !fw_hu_update) { 374dd0191d5SShuanglin Wang ulp_ctx->cfg_data->hu_session_type = 375dd0191d5SShuanglin Wang BNXT_ULP_SESSION_TYPE_SHARED | 376dd0191d5SShuanglin Wang BNXT_ULP_SESSION_TYPE_SHARED_OWC; 377dd0191d5SShuanglin Wang } 378dd0191d5SShuanglin Wang 379dd0191d5SShuanglin Wang return rc; 380dd0191d5SShuanglin Wang } 381dd0191d5SShuanglin Wang 382dd0191d5SShuanglin Wang static int32_t 383dd0191d5SShuanglin Wang ulp_tf_cntxt_app_caps_init(struct bnxt *bp, 384dd0191d5SShuanglin Wang uint8_t app_id, uint32_t dev_id) 385dd0191d5SShuanglin Wang { 386dd0191d5SShuanglin Wang struct bnxt_ulp_app_capabilities_info *info; 387dd0191d5SShuanglin Wang uint32_t num = 0, fw = 0; 388dd0191d5SShuanglin Wang uint16_t i; 389dd0191d5SShuanglin Wang bool found = false; 390dd0191d5SShuanglin Wang struct bnxt_ulp_context *ulp_ctx = bp->ulp_ctx; 391dd0191d5SShuanglin Wang 392dd0191d5SShuanglin Wang if (ULP_APP_DEV_UNSUPPORTED_ENABLED(ulp_ctx->cfg_data->ulp_flags)) { 393dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "APP ID %d, Device ID: 0x%x not supported.\n", 394dd0191d5SShuanglin Wang app_id, dev_id); 395dd0191d5SShuanglin Wang return -EINVAL; 396dd0191d5SShuanglin Wang } 397dd0191d5SShuanglin Wang 398dd0191d5SShuanglin Wang info = bnxt_ulp_app_cap_list_get(&num); 399dd0191d5SShuanglin Wang if (!info || !num) { 400dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get app capabilities.\n"); 401dd0191d5SShuanglin Wang return -EINVAL; 402dd0191d5SShuanglin Wang } 403dd0191d5SShuanglin Wang 404dd0191d5SShuanglin Wang for (i = 0; i < num; i++) { 405dd0191d5SShuanglin Wang if (info[i].app_id != app_id || info[i].device_id != dev_id) 406dd0191d5SShuanglin Wang continue; 407dd0191d5SShuanglin Wang found = true; 408dd0191d5SShuanglin Wang if (info[i].flags & BNXT_ULP_APP_CAP_SHARED_EN) 409dd0191d5SShuanglin Wang ulp_ctx->cfg_data->ulp_flags |= 410dd0191d5SShuanglin Wang BNXT_ULP_SHARED_SESSION_ENABLED; 411dd0191d5SShuanglin Wang if (info[i].flags & BNXT_ULP_APP_CAP_HOT_UPGRADE_EN) 412dd0191d5SShuanglin Wang ulp_ctx->cfg_data->ulp_flags |= 413dd0191d5SShuanglin Wang BNXT_ULP_HIGH_AVAIL_ENABLED; 414dd0191d5SShuanglin Wang if (info[i].flags & BNXT_ULP_APP_CAP_UNICAST_ONLY) 415dd0191d5SShuanglin Wang ulp_ctx->cfg_data->ulp_flags |= 416dd0191d5SShuanglin Wang BNXT_ULP_APP_UNICAST_ONLY; 417dd0191d5SShuanglin Wang if (info[i].flags & BNXT_ULP_APP_CAP_IP_TOS_PROTO_SUPPORT) 418dd0191d5SShuanglin Wang ulp_ctx->cfg_data->ulp_flags |= 419dd0191d5SShuanglin Wang BNXT_ULP_APP_TOS_PROTO_SUPPORT; 420dd0191d5SShuanglin Wang if (info[i].flags & BNXT_ULP_APP_CAP_BC_MC_SUPPORT) 421dd0191d5SShuanglin Wang ulp_ctx->cfg_data->ulp_flags |= 422dd0191d5SShuanglin Wang BNXT_ULP_APP_BC_MC_SUPPORT; 423dd0191d5SShuanglin Wang if (info[i].flags & BNXT_ULP_APP_CAP_SOCKET_DIRECT) { 424dd0191d5SShuanglin Wang /* Enable socket direction only if MR is enabled in fw*/ 425dd0191d5SShuanglin Wang if (BNXT_MULTIROOT_EN(bp)) { 426dd0191d5SShuanglin Wang ulp_ctx->cfg_data->ulp_flags |= 427dd0191d5SShuanglin Wang BNXT_ULP_APP_SOCKET_DIRECT; 428dd0191d5SShuanglin Wang BNXT_DRV_DBG(INFO, 429dd0191d5SShuanglin Wang "Socket Direct feature is enabled\n"); 430dd0191d5SShuanglin Wang } 431dd0191d5SShuanglin Wang } 432dd0191d5SShuanglin Wang if (info[i].flags & BNXT_ULP_APP_CAP_HA_DYNAMIC) { 433dd0191d5SShuanglin Wang /* Read the environment variable to determine hot up */ 434dd0191d5SShuanglin Wang if (!bnxt_pmd_get_hot_up_config()) { 435dd0191d5SShuanglin Wang ulp_ctx->cfg_data->ulp_flags |= 436dd0191d5SShuanglin Wang BNXT_ULP_APP_HA_DYNAMIC; 437dd0191d5SShuanglin Wang /* reset Hot upgrade, dynamically disabled */ 438dd0191d5SShuanglin Wang ulp_ctx->cfg_data->ulp_flags &= 439dd0191d5SShuanglin Wang ~BNXT_ULP_HIGH_AVAIL_ENABLED; 440dd0191d5SShuanglin Wang ulp_ctx->cfg_data->def_session_type = 441dd0191d5SShuanglin Wang BNXT_ULP_SESSION_TYPE_DEFAULT_NON_HA; 442dd0191d5SShuanglin Wang BNXT_DRV_DBG(INFO, "Hot upgrade disabled.\n"); 443dd0191d5SShuanglin Wang } 444dd0191d5SShuanglin Wang } 445dd0191d5SShuanglin Wang if (info[i].flags & BNXT_ULP_APP_CAP_SRV6) 446dd0191d5SShuanglin Wang ulp_ctx->cfg_data->ulp_flags |= 447dd0191d5SShuanglin Wang BNXT_ULP_APP_SRV6; 448dd0191d5SShuanglin Wang 449dd0191d5SShuanglin Wang if (info[i].flags & BNXT_ULP_APP_CAP_L2_ETYPE) 450dd0191d5SShuanglin Wang ulp_ctx->cfg_data->ulp_flags |= 451dd0191d5SShuanglin Wang BNXT_ULP_APP_L2_ETYPE; 452dd0191d5SShuanglin Wang 453dd0191d5SShuanglin Wang bnxt_ulp_cntxt_vxlan_ip_port_set(ulp_ctx, info[i].vxlan_ip_port); 454dd0191d5SShuanglin Wang bnxt_ulp_cntxt_vxlan_port_set(ulp_ctx, info[i].vxlan_port); 455dd0191d5SShuanglin Wang bnxt_ulp_cntxt_ecpri_udp_port_set(ulp_ctx, info[i].ecpri_udp_port); 456dd0191d5SShuanglin Wang bnxt_ulp_vxlan_gpe_next_proto_set(ulp_ctx, info[i].tunnel_next_proto); 457dd0191d5SShuanglin Wang bnxt_ulp_num_key_recipes_set(ulp_ctx, 458dd0191d5SShuanglin Wang info[i].num_key_recipes_per_dir); 459dd0191d5SShuanglin Wang 460dd0191d5SShuanglin Wang /* set the shared session support from firmware */ 461dd0191d5SShuanglin Wang fw = info[i].upgrade_fw_update; 462dd0191d5SShuanglin Wang if (ULP_HIGH_AVAIL_IS_ENABLED(ulp_ctx->cfg_data->ulp_flags) && 463dd0191d5SShuanglin Wang ulp_tf_multi_shared_session_support_set(bp, dev_id, fw)) { 464dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 465dd0191d5SShuanglin Wang "Unable to get shared session support\n"); 466dd0191d5SShuanglin Wang return -EINVAL; 467dd0191d5SShuanglin Wang } 468dd0191d5SShuanglin Wang bnxt_ulp_cntxt_ha_reg_set(ulp_ctx, info[i].ha_reg_state, 469dd0191d5SShuanglin Wang info[i].ha_reg_cnt); 470dd0191d5SShuanglin Wang ulp_ctx->cfg_data->ha_pool_id = info[i].ha_pool_id; 47122b65613SKishore Padmanabha bnxt_ulp_default_app_priority_set(ulp_ctx, 47222b65613SKishore Padmanabha info[i].default_priority); 47322b65613SKishore Padmanabha bnxt_ulp_max_def_priority_set(ulp_ctx, 47422b65613SKishore Padmanabha info[i].max_def_priority); 47522b65613SKishore Padmanabha bnxt_ulp_min_flow_priority_set(ulp_ctx, 47622b65613SKishore Padmanabha info[i].min_flow_priority); 47722b65613SKishore Padmanabha bnxt_ulp_max_flow_priority_set(ulp_ctx, 47822b65613SKishore Padmanabha info[i].max_flow_priority); 479b413ab0aSKishore Padmanabha /* Update the capability feature bits*/ 480b413ab0aSKishore Padmanabha if (bnxt_ulp_cap_feat_process(info[i].feature_bits, 481b413ab0aSKishore Padmanabha &ulp_ctx->cfg_data->feature_bits)) 482b413ab0aSKishore Padmanabha return -EINVAL; 483b413ab0aSKishore Padmanabha 4842aa70990SKishore Padmanabha bnxt_ulp_cntxt_ptr2_default_class_bits_set(ulp_ctx, 4852aa70990SKishore Padmanabha info[i].default_class_bits); 4862aa70990SKishore Padmanabha bnxt_ulp_cntxt_ptr2_default_act_bits_set(ulp_ctx, 4872aa70990SKishore Padmanabha info[i].default_act_bits); 488dd0191d5SShuanglin Wang } 489dd0191d5SShuanglin Wang if (!found) { 490dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "APP ID %d, Device ID: 0x%x not supported.\n", 491dd0191d5SShuanglin Wang app_id, dev_id); 492dd0191d5SShuanglin Wang ulp_ctx->cfg_data->ulp_flags |= BNXT_ULP_APP_DEV_UNSUPPORTED; 493dd0191d5SShuanglin Wang return -EINVAL; 494dd0191d5SShuanglin Wang } 495dd0191d5SShuanglin Wang 496dd0191d5SShuanglin Wang return 0; 497dd0191d5SShuanglin Wang } 498dd0191d5SShuanglin Wang 499dd0191d5SShuanglin Wang static inline uint32_t 500dd0191d5SShuanglin Wang ulp_tf_session_idx_get(enum bnxt_ulp_session_type session_type) { 501dd0191d5SShuanglin Wang if (session_type & BNXT_ULP_SESSION_TYPE_SHARED) 502dd0191d5SShuanglin Wang return 1; 503dd0191d5SShuanglin Wang else if (session_type & BNXT_ULP_SESSION_TYPE_SHARED_WC) 504dd0191d5SShuanglin Wang return 2; 505dd0191d5SShuanglin Wang return 0; 506dd0191d5SShuanglin Wang } 507dd0191d5SShuanglin Wang 508dd0191d5SShuanglin Wang /* Function to set the tfp session details in session */ 509dd0191d5SShuanglin Wang static int32_t 510dd0191d5SShuanglin Wang ulp_tf_session_tfp_set(struct bnxt_ulp_session_state *session, 511dd0191d5SShuanglin Wang enum bnxt_ulp_session_type session_type, 512dd0191d5SShuanglin Wang struct tf *tfp) 513dd0191d5SShuanglin Wang { 514dd0191d5SShuanglin Wang uint32_t idx = ulp_tf_session_idx_get(session_type); 515dd0191d5SShuanglin Wang struct tf *local_tfp; 516dd0191d5SShuanglin Wang int32_t rc = 0; 517dd0191d5SShuanglin Wang 518dd0191d5SShuanglin Wang if (!session->session_opened[idx]) { 519dd0191d5SShuanglin Wang local_tfp = rte_zmalloc("bnxt_ulp_session_tfp", 520dd0191d5SShuanglin Wang sizeof(struct tf), 0); 521dd0191d5SShuanglin Wang 522dd0191d5SShuanglin Wang if (local_tfp == NULL) { 523dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "Failed to alloc session tfp\n"); 524dd0191d5SShuanglin Wang return -ENOMEM; 525dd0191d5SShuanglin Wang } 526dd0191d5SShuanglin Wang local_tfp->session = tfp->session; 527dd0191d5SShuanglin Wang session->g_tfp[idx] = local_tfp; 528dd0191d5SShuanglin Wang session->session_opened[idx] = 1; 529dd0191d5SShuanglin Wang } 530dd0191d5SShuanglin Wang return rc; 531dd0191d5SShuanglin Wang } 532dd0191d5SShuanglin Wang 533dd0191d5SShuanglin Wang /* Function to get the tfp session details in session */ 534dd0191d5SShuanglin Wang static struct tf_session_info * 535dd0191d5SShuanglin Wang ulp_tf_session_tfp_get(struct bnxt_ulp_session_state *session, 536dd0191d5SShuanglin Wang enum bnxt_ulp_session_type session_type) 537dd0191d5SShuanglin Wang { 538dd0191d5SShuanglin Wang uint32_t idx = ulp_tf_session_idx_get(session_type); 539dd0191d5SShuanglin Wang struct tf *local_tfp = session->g_tfp[idx]; 540dd0191d5SShuanglin Wang 541dd0191d5SShuanglin Wang if (session->session_opened[idx]) 542dd0191d5SShuanglin Wang return local_tfp->session; 543dd0191d5SShuanglin Wang return NULL; 544dd0191d5SShuanglin Wang } 545dd0191d5SShuanglin Wang 546dd0191d5SShuanglin Wang static uint32_t 547dd0191d5SShuanglin Wang ulp_tf_session_is_open(struct bnxt_ulp_session_state *session, 548dd0191d5SShuanglin Wang enum bnxt_ulp_session_type session_type) 549dd0191d5SShuanglin Wang { 550dd0191d5SShuanglin Wang uint32_t idx = ulp_tf_session_idx_get(session_type); 551dd0191d5SShuanglin Wang 552dd0191d5SShuanglin Wang return session->session_opened[idx]; 553dd0191d5SShuanglin Wang } 554dd0191d5SShuanglin Wang 555dd0191d5SShuanglin Wang /* Function to reset the tfp session details in session */ 556dd0191d5SShuanglin Wang static void 557dd0191d5SShuanglin Wang ulp_tf_session_tfp_reset(struct bnxt_ulp_session_state *session, 558dd0191d5SShuanglin Wang enum bnxt_ulp_session_type session_type) 559dd0191d5SShuanglin Wang { 560dd0191d5SShuanglin Wang uint32_t idx = ulp_tf_session_idx_get(session_type); 561dd0191d5SShuanglin Wang 562dd0191d5SShuanglin Wang if (session->session_opened[idx]) { 563dd0191d5SShuanglin Wang session->session_opened[idx] = 0; 564dd0191d5SShuanglin Wang rte_free(session->g_tfp[idx]); 565dd0191d5SShuanglin Wang session->g_tfp[idx] = NULL; 566dd0191d5SShuanglin Wang } 567dd0191d5SShuanglin Wang } 568dd0191d5SShuanglin Wang 569dd0191d5SShuanglin Wang static void 570dd0191d5SShuanglin Wang ulp_tf_ctx_shared_session_close(struct bnxt *bp, 571dd0191d5SShuanglin Wang enum bnxt_ulp_session_type session_type, 572dd0191d5SShuanglin Wang struct bnxt_ulp_session_state *session) 573dd0191d5SShuanglin Wang { 574dd0191d5SShuanglin Wang struct tf *tfp; 575dd0191d5SShuanglin Wang int32_t rc; 576dd0191d5SShuanglin Wang 577dd0191d5SShuanglin Wang tfp = bnxt_ulp_cntxt_tfp_get(bp->ulp_ctx, session_type); 578dd0191d5SShuanglin Wang if (!tfp) { 579dd0191d5SShuanglin Wang /* 580dd0191d5SShuanglin Wang * Log it under debug since this is likely a case of the 581dd0191d5SShuanglin Wang * shared session not being created. For example, a failed 582dd0191d5SShuanglin Wang * initialization. 583dd0191d5SShuanglin Wang */ 584dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "Failed to get shared tfp on close.\n"); 585dd0191d5SShuanglin Wang return; 586dd0191d5SShuanglin Wang } 587dd0191d5SShuanglin Wang rc = tf_close_session(tfp); 588dd0191d5SShuanglin Wang if (rc) 589dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to close the shared session rc=%d.\n", 590dd0191d5SShuanglin Wang rc); 591dd0191d5SShuanglin Wang (void)bnxt_ulp_cntxt_tfp_set(bp->ulp_ctx, session_type, NULL); 592dd0191d5SShuanglin Wang ulp_tf_session_tfp_reset(session, session_type); 593dd0191d5SShuanglin Wang } 594dd0191d5SShuanglin Wang 595dd0191d5SShuanglin Wang static int32_t 596dd0191d5SShuanglin Wang ulp_tf_ctx_shared_session_open(struct bnxt *bp, 597dd0191d5SShuanglin Wang enum bnxt_ulp_session_type session_type, 598dd0191d5SShuanglin Wang struct bnxt_ulp_session_state *session) 599dd0191d5SShuanglin Wang { 600dd0191d5SShuanglin Wang struct rte_eth_dev *ethdev = bp->eth_dev; 601dd0191d5SShuanglin Wang struct tf_session_resources *resources; 602dd0191d5SShuanglin Wang struct tf_open_session_parms parms; 603dd0191d5SShuanglin Wang size_t nb; 604dd0191d5SShuanglin Wang uint32_t ulp_dev_id = BNXT_ULP_DEVICE_ID_LAST; 605dd0191d5SShuanglin Wang int32_t rc = 0; 606dd0191d5SShuanglin Wang uint8_t app_id; 607dd0191d5SShuanglin Wang struct tf *tfp; 608dd0191d5SShuanglin Wang uint8_t pool_id; 609dd0191d5SShuanglin Wang 610dd0191d5SShuanglin Wang memset(&parms, 0, sizeof(parms)); 611dd0191d5SShuanglin Wang rc = rte_eth_dev_get_name_by_port(ethdev->data->port_id, 612dd0191d5SShuanglin Wang parms.ctrl_chan_name); 613dd0191d5SShuanglin Wang if (rc) { 614dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid port %d, rc = %d\n", 615dd0191d5SShuanglin Wang ethdev->data->port_id, rc); 616dd0191d5SShuanglin Wang return rc; 617dd0191d5SShuanglin Wang } 618dd0191d5SShuanglin Wang 619dd0191d5SShuanglin Wang /* On multi-host system, adjust ctrl_chan_name to avoid confliction */ 620dd0191d5SShuanglin Wang if (BNXT_MH(bp)) { 621dd0191d5SShuanglin Wang rc = ulp_ctx_mh_get_session_name(bp, &parms); 622dd0191d5SShuanglin Wang if (rc) 623dd0191d5SShuanglin Wang return rc; 624dd0191d5SShuanglin Wang } 625dd0191d5SShuanglin Wang 626dd0191d5SShuanglin Wang resources = &parms.resources; 627dd0191d5SShuanglin Wang 628dd0191d5SShuanglin Wang /* 629dd0191d5SShuanglin Wang * Need to account for size of ctrl_chan_name and 1 extra for Null 630dd0191d5SShuanglin Wang * terminator 631dd0191d5SShuanglin Wang */ 632dd0191d5SShuanglin Wang nb = sizeof(parms.ctrl_chan_name) - strlen(parms.ctrl_chan_name) - 1; 633dd0191d5SShuanglin Wang 634dd0191d5SShuanglin Wang /* 635dd0191d5SShuanglin Wang * Build the ctrl_chan_name with shared token. 636dd0191d5SShuanglin Wang * When HA is enabled, the WC TCAM needs extra management by the core, 637dd0191d5SShuanglin Wang * so add the wc_tcam string to the control channel. 638dd0191d5SShuanglin Wang */ 639dd0191d5SShuanglin Wang pool_id = bp->ulp_ctx->cfg_data->ha_pool_id; 640dd0191d5SShuanglin Wang if (!bnxt_ulp_cntxt_multi_shared_session_enabled(bp->ulp_ctx)) { 641dd0191d5SShuanglin Wang if (bnxt_ulp_cntxt_ha_enabled(bp->ulp_ctx)) 642dd0191d5SShuanglin Wang strncat(parms.ctrl_chan_name, "-tf_shared-wc_tcam", nb); 643dd0191d5SShuanglin Wang else 644dd0191d5SShuanglin Wang strncat(parms.ctrl_chan_name, "-tf_shared", nb); 645dd0191d5SShuanglin Wang } else if (bnxt_ulp_cntxt_multi_shared_session_enabled(bp->ulp_ctx)) { 646dd0191d5SShuanglin Wang if (session_type == BNXT_ULP_SESSION_TYPE_SHARED) { 647dd0191d5SShuanglin Wang strncat(parms.ctrl_chan_name, "-tf_shared", nb); 648dd0191d5SShuanglin Wang } else if (session_type == BNXT_ULP_SESSION_TYPE_SHARED_WC) { 649dd0191d5SShuanglin Wang char session_pool_name[64]; 650dd0191d5SShuanglin Wang 651dd0191d5SShuanglin Wang sprintf(session_pool_name, "-tf_shared-pool%d", 652dd0191d5SShuanglin Wang pool_id); 653dd0191d5SShuanglin Wang 654dd0191d5SShuanglin Wang if (nb >= strlen(session_pool_name)) { 655dd0191d5SShuanglin Wang strncat(parms.ctrl_chan_name, session_pool_name, nb); 656dd0191d5SShuanglin Wang } else { 657dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "No space left for session_name\n"); 658dd0191d5SShuanglin Wang return -EINVAL; 659dd0191d5SShuanglin Wang } 660dd0191d5SShuanglin Wang } 661dd0191d5SShuanglin Wang } 662dd0191d5SShuanglin Wang 663dd0191d5SShuanglin Wang rc = ulp_tf_shared_session_resources_get(bp->ulp_ctx, session_type, 664dd0191d5SShuanglin Wang resources); 665dd0191d5SShuanglin Wang if (rc) 666dd0191d5SShuanglin Wang return rc; 667dd0191d5SShuanglin Wang 668dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_app_id_get(bp->ulp_ctx, &app_id); 669dd0191d5SShuanglin Wang if (rc) { 670dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to get the app id from ulp.\n"); 671dd0191d5SShuanglin Wang return -EINVAL; 672dd0191d5SShuanglin Wang } 673dd0191d5SShuanglin Wang 674dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &ulp_dev_id); 675dd0191d5SShuanglin Wang if (rc) { 676dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to get device id from ulp.\n"); 677dd0191d5SShuanglin Wang return rc; 678dd0191d5SShuanglin Wang } 679dd0191d5SShuanglin Wang 680dd0191d5SShuanglin Wang tfp = bnxt_ulp_bp_tfp_get(bp, session_type); 681dd0191d5SShuanglin Wang parms.device_type = bnxt_ulp_cntxt_convert_dev_id(ulp_dev_id); 682dd0191d5SShuanglin Wang parms.bp = bp; 683dd0191d5SShuanglin Wang 684dd0191d5SShuanglin Wang /* 685dd0191d5SShuanglin Wang * Open the session here, but the collect the resources during the 686dd0191d5SShuanglin Wang * mapper initialization. 687dd0191d5SShuanglin Wang */ 688dd0191d5SShuanglin Wang rc = tf_open_session(tfp, &parms); 689dd0191d5SShuanglin Wang if (rc) 690dd0191d5SShuanglin Wang return rc; 691dd0191d5SShuanglin Wang 692dd0191d5SShuanglin Wang if (parms.shared_session_creator) 693dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "Shared session creator.\n"); 694dd0191d5SShuanglin Wang else 695dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "Shared session attached.\n"); 696dd0191d5SShuanglin Wang 697dd0191d5SShuanglin Wang /* Save the shared session in global data */ 698dd0191d5SShuanglin Wang rc = ulp_tf_session_tfp_set(session, session_type, tfp); 699dd0191d5SShuanglin Wang if (rc) { 700dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to add shared tfp to session\n"); 701dd0191d5SShuanglin Wang return rc; 702dd0191d5SShuanglin Wang } 703dd0191d5SShuanglin Wang 704dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_tfp_set(bp->ulp_ctx, session_type, tfp); 705dd0191d5SShuanglin Wang if (rc) { 706dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to add shared tfp to ulp (%d)\n", rc); 707dd0191d5SShuanglin Wang return rc; 708dd0191d5SShuanglin Wang } 709dd0191d5SShuanglin Wang 710dd0191d5SShuanglin Wang return rc; 711dd0191d5SShuanglin Wang } 712dd0191d5SShuanglin Wang 713dd0191d5SShuanglin Wang static int32_t 714dd0191d5SShuanglin Wang ulp_tf_ctx_shared_session_attach(struct bnxt *bp, 715dd0191d5SShuanglin Wang struct bnxt_ulp_session_state *ses) 716dd0191d5SShuanglin Wang { 717dd0191d5SShuanglin Wang enum bnxt_ulp_session_type type; 718dd0191d5SShuanglin Wang struct tf *tfp; 719dd0191d5SShuanglin Wang int32_t rc = 0; 720dd0191d5SShuanglin Wang 721dd0191d5SShuanglin Wang /* Simply return success if shared session not enabled */ 722dd0191d5SShuanglin Wang if (bnxt_ulp_cntxt_shared_session_enabled(bp->ulp_ctx)) { 723dd0191d5SShuanglin Wang type = BNXT_ULP_SESSION_TYPE_SHARED; 724dd0191d5SShuanglin Wang tfp = bnxt_ulp_bp_tfp_get(bp, type); 725dd0191d5SShuanglin Wang tfp->session = ulp_tf_session_tfp_get(ses, type); 726dd0191d5SShuanglin Wang rc = ulp_tf_ctx_shared_session_open(bp, type, ses); 727dd0191d5SShuanglin Wang } 728dd0191d5SShuanglin Wang 729dd0191d5SShuanglin Wang if (bnxt_ulp_cntxt_multi_shared_session_enabled(bp->ulp_ctx)) { 730dd0191d5SShuanglin Wang type = BNXT_ULP_SESSION_TYPE_SHARED_WC; 731dd0191d5SShuanglin Wang tfp = bnxt_ulp_bp_tfp_get(bp, type); 732dd0191d5SShuanglin Wang tfp->session = ulp_tf_session_tfp_get(ses, type); 733dd0191d5SShuanglin Wang rc = ulp_tf_ctx_shared_session_open(bp, type, ses); 734dd0191d5SShuanglin Wang } 735dd0191d5SShuanglin Wang 736dd0191d5SShuanglin Wang if (!rc) 737dd0191d5SShuanglin Wang bnxt_ulp_cntxt_num_shared_clients_set(bp->ulp_ctx, true); 738dd0191d5SShuanglin Wang 739dd0191d5SShuanglin Wang return rc; 740dd0191d5SShuanglin Wang } 741dd0191d5SShuanglin Wang 742dd0191d5SShuanglin Wang static void 743dd0191d5SShuanglin Wang ulp_tf_ctx_shared_session_detach(struct bnxt *bp) 744dd0191d5SShuanglin Wang { 745dd0191d5SShuanglin Wang struct tf *tfp; 746dd0191d5SShuanglin Wang 747dd0191d5SShuanglin Wang if (bnxt_ulp_cntxt_shared_session_enabled(bp->ulp_ctx)) { 748dd0191d5SShuanglin Wang tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_SHARED); 749dd0191d5SShuanglin Wang if (tfp->session) { 750dd0191d5SShuanglin Wang tf_close_session(tfp); 751dd0191d5SShuanglin Wang tfp->session = NULL; 752dd0191d5SShuanglin Wang } 753dd0191d5SShuanglin Wang } 754dd0191d5SShuanglin Wang if (bnxt_ulp_cntxt_multi_shared_session_enabled(bp->ulp_ctx)) { 755dd0191d5SShuanglin Wang tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_SHARED_WC); 756dd0191d5SShuanglin Wang if (tfp->session) { 757dd0191d5SShuanglin Wang tf_close_session(tfp); 758dd0191d5SShuanglin Wang tfp->session = NULL; 759dd0191d5SShuanglin Wang } 760dd0191d5SShuanglin Wang } 761dd0191d5SShuanglin Wang bnxt_ulp_cntxt_num_shared_clients_set(bp->ulp_ctx, false); 762dd0191d5SShuanglin Wang } 763dd0191d5SShuanglin Wang 764dd0191d5SShuanglin Wang /* 765dd0191d5SShuanglin Wang * Initialize an ULP session. 766dd0191d5SShuanglin Wang * An ULP session will contain all the resources needed to support rte flow 767dd0191d5SShuanglin Wang * offloads. A session is initialized as part of rte_eth_device start. 768dd0191d5SShuanglin Wang * A single vswitch instance can have multiple uplinks which means 769dd0191d5SShuanglin Wang * rte_eth_device start will be called for each of these devices. 770dd0191d5SShuanglin Wang * ULP session manager will make sure that a single ULP session is only 771dd0191d5SShuanglin Wang * initialized once. Apart from this, it also initializes MARK database, 772dd0191d5SShuanglin Wang * EEM table & flow database. ULP session manager also manages a list of 773dd0191d5SShuanglin Wang * all opened ULP sessions. 774dd0191d5SShuanglin Wang */ 775dd0191d5SShuanglin Wang static int32_t 776dd0191d5SShuanglin Wang ulp_tf_ctx_session_open(struct bnxt *bp, 777dd0191d5SShuanglin Wang struct bnxt_ulp_session_state *session) 778dd0191d5SShuanglin Wang { 779dd0191d5SShuanglin Wang struct rte_eth_dev *ethdev = bp->eth_dev; 780dd0191d5SShuanglin Wang int32_t rc = 0; 781dd0191d5SShuanglin Wang struct tf_open_session_parms params; 782dd0191d5SShuanglin Wang struct tf_session_resources *resources; 783dd0191d5SShuanglin Wang uint32_t ulp_dev_id = BNXT_ULP_DEVICE_ID_LAST; 784dd0191d5SShuanglin Wang uint8_t app_id; 785dd0191d5SShuanglin Wang struct tf *tfp; 786dd0191d5SShuanglin Wang 787dd0191d5SShuanglin Wang memset(¶ms, 0, sizeof(params)); 788dd0191d5SShuanglin Wang 789dd0191d5SShuanglin Wang rc = rte_eth_dev_get_name_by_port(ethdev->data->port_id, 790dd0191d5SShuanglin Wang params.ctrl_chan_name); 791dd0191d5SShuanglin Wang if (rc) { 792dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid port %d, rc = %d\n", 793dd0191d5SShuanglin Wang ethdev->data->port_id, rc); 794dd0191d5SShuanglin Wang return rc; 795dd0191d5SShuanglin Wang } 796dd0191d5SShuanglin Wang 797dd0191d5SShuanglin Wang /* On multi-host system, adjust ctrl_chan_name to avoid confliction */ 798dd0191d5SShuanglin Wang if (BNXT_MH(bp)) { 799dd0191d5SShuanglin Wang rc = ulp_ctx_mh_get_session_name(bp, ¶ms); 800dd0191d5SShuanglin Wang if (rc) 801dd0191d5SShuanglin Wang return rc; 802dd0191d5SShuanglin Wang } 803dd0191d5SShuanglin Wang 804dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_app_id_get(bp->ulp_ctx, &app_id); 805dd0191d5SShuanglin Wang if (rc) { 806dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to get the app id from ulp.\n"); 807dd0191d5SShuanglin Wang return -EINVAL; 808dd0191d5SShuanglin Wang } 809dd0191d5SShuanglin Wang 810dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &ulp_dev_id); 811dd0191d5SShuanglin Wang if (rc) { 812dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to get device id from ulp.\n"); 813dd0191d5SShuanglin Wang return rc; 814dd0191d5SShuanglin Wang } 815dd0191d5SShuanglin Wang 816dd0191d5SShuanglin Wang params.device_type = bnxt_ulp_cntxt_convert_dev_id(ulp_dev_id); 817dd0191d5SShuanglin Wang resources = ¶ms.resources; 818dd0191d5SShuanglin Wang rc = ulp_tf_resources_get(bp->ulp_ctx, 819dd0191d5SShuanglin Wang BNXT_ULP_SESSION_TYPE_DEFAULT, 820dd0191d5SShuanglin Wang resources); 821dd0191d5SShuanglin Wang if (rc) 822dd0191d5SShuanglin Wang return rc; 823dd0191d5SShuanglin Wang 824dd0191d5SShuanglin Wang params.bp = bp; 825dd0191d5SShuanglin Wang 826dd0191d5SShuanglin Wang tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT); 827dd0191d5SShuanglin Wang rc = tf_open_session(tfp, ¶ms); 828dd0191d5SShuanglin Wang if (rc) { 829dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to open TF session - %s, rc = %d\n", 830dd0191d5SShuanglin Wang params.ctrl_chan_name, rc); 831dd0191d5SShuanglin Wang return -EINVAL; 832dd0191d5SShuanglin Wang } 833dd0191d5SShuanglin Wang rc = ulp_tf_session_tfp_set(session, BNXT_ULP_SESSION_TYPE_DEFAULT, tfp); 834dd0191d5SShuanglin Wang if (rc) { 835dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to set TF session - %s, rc = %d\n", 836dd0191d5SShuanglin Wang params.ctrl_chan_name, rc); 837dd0191d5SShuanglin Wang return -EINVAL; 838dd0191d5SShuanglin Wang } 839dd0191d5SShuanglin Wang return rc; 840dd0191d5SShuanglin Wang } 841dd0191d5SShuanglin Wang 842dd0191d5SShuanglin Wang /* 843dd0191d5SShuanglin Wang * Close the ULP session. 844dd0191d5SShuanglin Wang * It takes the ulp context pointer. 845dd0191d5SShuanglin Wang */ 846dd0191d5SShuanglin Wang static void 847dd0191d5SShuanglin Wang ulp_tf_ctx_session_close(struct bnxt *bp, 848dd0191d5SShuanglin Wang struct bnxt_ulp_session_state *session) 849dd0191d5SShuanglin Wang { 850dd0191d5SShuanglin Wang struct tf *tfp; 851dd0191d5SShuanglin Wang 852dd0191d5SShuanglin Wang /* close the session in the hardware */ 853dd0191d5SShuanglin Wang if (ulp_tf_session_is_open(session, BNXT_ULP_SESSION_TYPE_DEFAULT)) { 854dd0191d5SShuanglin Wang tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT); 855dd0191d5SShuanglin Wang tf_close_session(tfp); 856dd0191d5SShuanglin Wang } 857dd0191d5SShuanglin Wang ulp_tf_session_tfp_reset(session, BNXT_ULP_SESSION_TYPE_DEFAULT); 858dd0191d5SShuanglin Wang } 859dd0191d5SShuanglin Wang 860dd0191d5SShuanglin Wang static void 861dd0191d5SShuanglin Wang ulp_tf_init_tbl_scope_parms(struct bnxt *bp, 862dd0191d5SShuanglin Wang struct tf_alloc_tbl_scope_parms *params) 863dd0191d5SShuanglin Wang { 864dd0191d5SShuanglin Wang struct bnxt_ulp_device_params *dparms; 865dd0191d5SShuanglin Wang uint32_t dev_id; 866dd0191d5SShuanglin Wang int rc; 867dd0191d5SShuanglin Wang 868dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id); 869dd0191d5SShuanglin Wang if (rc) 870dd0191d5SShuanglin Wang /* TBD: For now, just use default. */ 871dd0191d5SShuanglin Wang dparms = 0; 872dd0191d5SShuanglin Wang else 873dd0191d5SShuanglin Wang dparms = bnxt_ulp_device_params_get(dev_id); 874dd0191d5SShuanglin Wang 875dd0191d5SShuanglin Wang /* 876dd0191d5SShuanglin Wang * Set the flush timer for EEM entries. The value is in 100ms intervals, 877dd0191d5SShuanglin Wang * so 100 is 10s. 878dd0191d5SShuanglin Wang */ 879dd0191d5SShuanglin Wang params->hw_flow_cache_flush_timer = 100; 880dd0191d5SShuanglin Wang 881dd0191d5SShuanglin Wang if (!dparms) { 882dd0191d5SShuanglin Wang params->rx_max_key_sz_in_bits = BNXT_ULP_DFLT_RX_MAX_KEY; 883dd0191d5SShuanglin Wang params->rx_max_action_entry_sz_in_bits = 884dd0191d5SShuanglin Wang BNXT_ULP_DFLT_RX_MAX_ACTN_ENTRY; 885dd0191d5SShuanglin Wang params->rx_mem_size_in_mb = BNXT_ULP_DFLT_RX_MEM; 886dd0191d5SShuanglin Wang params->rx_num_flows_in_k = BNXT_ULP_RX_NUM_FLOWS; 887dd0191d5SShuanglin Wang 888dd0191d5SShuanglin Wang params->tx_max_key_sz_in_bits = BNXT_ULP_DFLT_TX_MAX_KEY; 889dd0191d5SShuanglin Wang params->tx_max_action_entry_sz_in_bits = 890dd0191d5SShuanglin Wang BNXT_ULP_DFLT_TX_MAX_ACTN_ENTRY; 891dd0191d5SShuanglin Wang params->tx_mem_size_in_mb = BNXT_ULP_DFLT_TX_MEM; 892dd0191d5SShuanglin Wang params->tx_num_flows_in_k = BNXT_ULP_TX_NUM_FLOWS; 893dd0191d5SShuanglin Wang } else { 894dd0191d5SShuanglin Wang params->rx_max_key_sz_in_bits = BNXT_ULP_DFLT_RX_MAX_KEY; 895dd0191d5SShuanglin Wang params->rx_max_action_entry_sz_in_bits = 896dd0191d5SShuanglin Wang BNXT_ULP_DFLT_RX_MAX_ACTN_ENTRY; 897dd0191d5SShuanglin Wang params->rx_mem_size_in_mb = BNXT_ULP_DFLT_RX_MEM; 898dd0191d5SShuanglin Wang params->rx_num_flows_in_k = 899dd0191d5SShuanglin Wang dparms->ext_flow_db_num_entries / 1024; 900dd0191d5SShuanglin Wang 901dd0191d5SShuanglin Wang params->tx_max_key_sz_in_bits = BNXT_ULP_DFLT_TX_MAX_KEY; 902dd0191d5SShuanglin Wang params->tx_max_action_entry_sz_in_bits = 903dd0191d5SShuanglin Wang BNXT_ULP_DFLT_TX_MAX_ACTN_ENTRY; 904dd0191d5SShuanglin Wang params->tx_mem_size_in_mb = BNXT_ULP_DFLT_TX_MEM; 905dd0191d5SShuanglin Wang params->tx_num_flows_in_k = 906dd0191d5SShuanglin Wang dparms->ext_flow_db_num_entries / 1024; 907dd0191d5SShuanglin Wang } 908dd0191d5SShuanglin Wang BNXT_DRV_DBG(INFO, "Table Scope initialized with %uK flows.\n", 909dd0191d5SShuanglin Wang params->rx_num_flows_in_k); 910dd0191d5SShuanglin Wang } 911dd0191d5SShuanglin Wang 912dd0191d5SShuanglin Wang /* Initialize Extended Exact Match host memory. */ 913dd0191d5SShuanglin Wang static int32_t 914dd0191d5SShuanglin Wang ulp_tf_eem_tbl_scope_init(struct bnxt *bp) 915dd0191d5SShuanglin Wang { 916dd0191d5SShuanglin Wang struct tf_alloc_tbl_scope_parms params = {0}; 917dd0191d5SShuanglin Wang struct bnxt_ulp_device_params *dparms; 918dd0191d5SShuanglin Wang enum bnxt_ulp_flow_mem_type mtype; 919dd0191d5SShuanglin Wang uint32_t dev_id; 920dd0191d5SShuanglin Wang struct tf *tfp; 921dd0191d5SShuanglin Wang int rc; 922dd0191d5SShuanglin Wang 923dd0191d5SShuanglin Wang /* Get the dev specific number of flows that needed to be supported. */ 924dd0191d5SShuanglin Wang if (bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id)) { 925dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid device id\n"); 926dd0191d5SShuanglin Wang return -EINVAL; 927dd0191d5SShuanglin Wang } 928dd0191d5SShuanglin Wang 929dd0191d5SShuanglin Wang dparms = bnxt_ulp_device_params_get(dev_id); 930dd0191d5SShuanglin Wang if (!dparms) { 931dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "could not fetch the device params\n"); 932dd0191d5SShuanglin Wang return -ENODEV; 933dd0191d5SShuanglin Wang } 934dd0191d5SShuanglin Wang 935dd0191d5SShuanglin Wang if (bnxt_ulp_cntxt_mem_type_get(bp->ulp_ctx, &mtype)) 936dd0191d5SShuanglin Wang return -EINVAL; 937dd0191d5SShuanglin Wang if (mtype != BNXT_ULP_FLOW_MEM_TYPE_EXT) { 938dd0191d5SShuanglin Wang BNXT_DRV_DBG(INFO, "Table Scope alloc is not required\n"); 939dd0191d5SShuanglin Wang return 0; 940dd0191d5SShuanglin Wang } 941dd0191d5SShuanglin Wang 942dd0191d5SShuanglin Wang ulp_tf_init_tbl_scope_parms(bp, ¶ms); 943dd0191d5SShuanglin Wang tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT); 944dd0191d5SShuanglin Wang rc = tf_alloc_tbl_scope(tfp, ¶ms); 945dd0191d5SShuanglin Wang if (rc) { 946dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 947dd0191d5SShuanglin Wang "Unable to allocate eem table scope rc = %d\n", 948dd0191d5SShuanglin Wang rc); 949dd0191d5SShuanglin Wang return rc; 950dd0191d5SShuanglin Wang } 951dd0191d5SShuanglin Wang 952dd0191d5SShuanglin Wang #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG 953dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "TableScope=0x%0x %d\n", 954dd0191d5SShuanglin Wang params.tbl_scope_id, 955dd0191d5SShuanglin Wang params.tbl_scope_id); 956dd0191d5SShuanglin Wang #endif 957dd0191d5SShuanglin Wang 958dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_tbl_scope_id_set(bp->ulp_ctx, params.tbl_scope_id); 959dd0191d5SShuanglin Wang if (rc) { 960dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to set table scope id\n"); 961dd0191d5SShuanglin Wang return rc; 962dd0191d5SShuanglin Wang } 963dd0191d5SShuanglin Wang 964dd0191d5SShuanglin Wang return 0; 965dd0191d5SShuanglin Wang } 966dd0191d5SShuanglin Wang 967dd0191d5SShuanglin Wang /* Free Extended Exact Match host memory */ 968dd0191d5SShuanglin Wang static int32_t 969dd0191d5SShuanglin Wang ulp_tf_eem_tbl_scope_deinit(struct bnxt *bp, struct bnxt_ulp_context *ulp_ctx) 970dd0191d5SShuanglin Wang { 971dd0191d5SShuanglin Wang struct tf_free_tbl_scope_parms params = {0}; 972dd0191d5SShuanglin Wang struct tf *tfp; 973dd0191d5SShuanglin Wang int32_t rc = 0; 974dd0191d5SShuanglin Wang struct bnxt_ulp_device_params *dparms; 975dd0191d5SShuanglin Wang enum bnxt_ulp_flow_mem_type mtype; 976dd0191d5SShuanglin Wang uint32_t dev_id; 977dd0191d5SShuanglin Wang 978dd0191d5SShuanglin Wang if (!ulp_ctx || !ulp_ctx->cfg_data) 979dd0191d5SShuanglin Wang return -EINVAL; 980dd0191d5SShuanglin Wang 981dd0191d5SShuanglin Wang tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx, BNXT_ULP_SESSION_TYPE_DEFAULT); 982dd0191d5SShuanglin Wang if (!tfp) { 983dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get the truflow pointer\n"); 984dd0191d5SShuanglin Wang return -EINVAL; 985dd0191d5SShuanglin Wang } 986dd0191d5SShuanglin Wang 987dd0191d5SShuanglin Wang /* Get the dev specific number of flows that needed to be supported. */ 988dd0191d5SShuanglin Wang if (bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id)) { 989dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid device id\n"); 990dd0191d5SShuanglin Wang return -EINVAL; 991dd0191d5SShuanglin Wang } 992dd0191d5SShuanglin Wang 993dd0191d5SShuanglin Wang dparms = bnxt_ulp_device_params_get(dev_id); 994dd0191d5SShuanglin Wang if (!dparms) { 995dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "could not fetch the device params\n"); 996dd0191d5SShuanglin Wang return -ENODEV; 997dd0191d5SShuanglin Wang } 998dd0191d5SShuanglin Wang 999dd0191d5SShuanglin Wang if (bnxt_ulp_cntxt_mem_type_get(ulp_ctx, &mtype)) 1000dd0191d5SShuanglin Wang return -EINVAL; 1001dd0191d5SShuanglin Wang if (mtype != BNXT_ULP_FLOW_MEM_TYPE_EXT) { 1002dd0191d5SShuanglin Wang BNXT_DRV_DBG(INFO, "Table Scope free is not required\n"); 1003dd0191d5SShuanglin Wang return 0; 1004dd0191d5SShuanglin Wang } 1005dd0191d5SShuanglin Wang 1006dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_tbl_scope_id_get(ulp_ctx, ¶ms.tbl_scope_id); 1007dd0191d5SShuanglin Wang if (rc) { 1008dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get the table scope id\n"); 1009dd0191d5SShuanglin Wang return -EINVAL; 1010dd0191d5SShuanglin Wang } 1011dd0191d5SShuanglin Wang 1012dd0191d5SShuanglin Wang rc = tf_free_tbl_scope(tfp, ¶ms); 1013dd0191d5SShuanglin Wang if (rc) { 1014dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to free table scope\n"); 1015dd0191d5SShuanglin Wang return -EINVAL; 1016dd0191d5SShuanglin Wang } 1017dd0191d5SShuanglin Wang return rc; 1018dd0191d5SShuanglin Wang } 1019dd0191d5SShuanglin Wang 1020dd0191d5SShuanglin Wang /* The function to free and deinit the ulp context data. */ 1021dd0191d5SShuanglin Wang static int32_t 1022dd0191d5SShuanglin Wang ulp_tf_ctx_deinit(struct bnxt *bp, 1023dd0191d5SShuanglin Wang struct bnxt_ulp_session_state *session) 1024dd0191d5SShuanglin Wang { 1025dd0191d5SShuanglin Wang /* close the tf session */ 1026dd0191d5SShuanglin Wang ulp_tf_ctx_session_close(bp, session); 1027dd0191d5SShuanglin Wang 1028dd0191d5SShuanglin Wang /* The shared session must be closed last. */ 1029dd0191d5SShuanglin Wang if (bnxt_ulp_cntxt_shared_session_enabled(bp->ulp_ctx)) 1030dd0191d5SShuanglin Wang ulp_tf_ctx_shared_session_close(bp, BNXT_ULP_SESSION_TYPE_SHARED, 1031dd0191d5SShuanglin Wang session); 1032dd0191d5SShuanglin Wang 1033dd0191d5SShuanglin Wang if (bnxt_ulp_cntxt_multi_shared_session_enabled(bp->ulp_ctx)) 1034dd0191d5SShuanglin Wang ulp_tf_ctx_shared_session_close(bp, 1035dd0191d5SShuanglin Wang BNXT_ULP_SESSION_TYPE_SHARED_WC, 1036dd0191d5SShuanglin Wang session); 1037dd0191d5SShuanglin Wang 1038dd0191d5SShuanglin Wang bnxt_ulp_cntxt_num_shared_clients_set(bp->ulp_ctx, false); 1039dd0191d5SShuanglin Wang 1040dd0191d5SShuanglin Wang /* Free the contents */ 1041dd0191d5SShuanglin Wang if (session->cfg_data) { 1042dd0191d5SShuanglin Wang rte_free(session->cfg_data); 1043dd0191d5SShuanglin Wang bp->ulp_ctx->cfg_data = NULL; 1044dd0191d5SShuanglin Wang session->cfg_data = NULL; 1045dd0191d5SShuanglin Wang } 1046dd0191d5SShuanglin Wang return 0; 1047dd0191d5SShuanglin Wang } 1048dd0191d5SShuanglin Wang 1049dd0191d5SShuanglin Wang /* The function to allocate and initialize the ulp context data. */ 1050dd0191d5SShuanglin Wang static int32_t 1051dd0191d5SShuanglin Wang ulp_tf_ctx_init(struct bnxt *bp, 1052dd0191d5SShuanglin Wang struct bnxt_ulp_session_state *session) 1053dd0191d5SShuanglin Wang { 1054dd0191d5SShuanglin Wang struct bnxt_ulp_data *ulp_data; 1055dd0191d5SShuanglin Wang int32_t rc = 0; 1056dd0191d5SShuanglin Wang enum bnxt_ulp_device_id devid; 1057dd0191d5SShuanglin Wang enum bnxt_ulp_session_type stype; 1058dd0191d5SShuanglin Wang struct tf *tfp; 1059dd0191d5SShuanglin Wang 1060dd0191d5SShuanglin Wang /* Initialize the context entries list */ 1061dd0191d5SShuanglin Wang bnxt_ulp_cntxt_list_init(); 1062dd0191d5SShuanglin Wang 1063dd0191d5SShuanglin Wang /* Allocate memory to hold ulp context data. */ 1064dd0191d5SShuanglin Wang ulp_data = rte_zmalloc("bnxt_ulp_data", 1065dd0191d5SShuanglin Wang sizeof(struct bnxt_ulp_data), 0); 1066dd0191d5SShuanglin Wang if (!ulp_data) { 1067dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to allocate memory for ulp data\n"); 1068dd0191d5SShuanglin Wang return -ENOMEM; 1069dd0191d5SShuanglin Wang } 1070dd0191d5SShuanglin Wang 1071dd0191d5SShuanglin Wang /* Increment the ulp context data reference count usage. */ 1072dd0191d5SShuanglin Wang bp->ulp_ctx->cfg_data = ulp_data; 1073dd0191d5SShuanglin Wang session->cfg_data = ulp_data; 1074dd0191d5SShuanglin Wang ulp_data->ref_cnt++; 1075dd0191d5SShuanglin Wang ulp_data->ulp_flags |= BNXT_ULP_VF_REP_ENABLED; 1076dd0191d5SShuanglin Wang 107794dbd6cfSKishore Padmanabha /* Add the context to the context entries list */ 107894dbd6cfSKishore Padmanabha rc = bnxt_ulp_cntxt_list_add(bp->ulp_ctx); 107994dbd6cfSKishore Padmanabha if (rc) { 108094dbd6cfSKishore Padmanabha BNXT_DRV_DBG(ERR, "Failed to add the context list entry\n"); 108194dbd6cfSKishore Padmanabha goto error_deinit; 108294dbd6cfSKishore Padmanabha } 108394dbd6cfSKishore Padmanabha 1084dd0191d5SShuanglin Wang rc = bnxt_ulp_devid_get(bp, &devid); 1085dd0191d5SShuanglin Wang if (rc) { 1086dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to determine device for ULP init.\n"); 1087dd0191d5SShuanglin Wang goto error_deinit; 1088dd0191d5SShuanglin Wang } 1089dd0191d5SShuanglin Wang 1090dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_dev_id_set(bp->ulp_ctx, devid); 1091dd0191d5SShuanglin Wang if (rc) { 1092dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to set device for ULP init.\n"); 1093dd0191d5SShuanglin Wang goto error_deinit; 1094dd0191d5SShuanglin Wang } 1095dd0191d5SShuanglin Wang 1096dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_app_id_set(bp->ulp_ctx, bp->app_id); 1097dd0191d5SShuanglin Wang if (rc) { 1098dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to set app_id for ULP init.\n"); 1099dd0191d5SShuanglin Wang goto error_deinit; 1100dd0191d5SShuanglin Wang } 1101dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "Ulp initialized with app id %d\n", bp->app_id); 1102dd0191d5SShuanglin Wang 1103dd0191d5SShuanglin Wang rc = ulp_tf_cntxt_app_caps_init(bp, bp->app_id, devid); 1104dd0191d5SShuanglin Wang if (rc) { 1105dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to set caps for app(%x)/dev(%x)\n", 1106dd0191d5SShuanglin Wang bp->app_id, devid); 1107dd0191d5SShuanglin Wang goto error_deinit; 1108dd0191d5SShuanglin Wang } 1109dd0191d5SShuanglin Wang 1110dd0191d5SShuanglin Wang if (BNXT_TESTPMD_EN(bp)) { 1111dd0191d5SShuanglin Wang ulp_data->ulp_flags &= ~BNXT_ULP_VF_REP_ENABLED; 1112dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Enabled Testpmd forward mode\n"); 1113dd0191d5SShuanglin Wang } 1114dd0191d5SShuanglin Wang 1115dd0191d5SShuanglin Wang /* 1116dd0191d5SShuanglin Wang * Shared session must be created before first regular session but after 1117dd0191d5SShuanglin Wang * the ulp_ctx is valid. 1118dd0191d5SShuanglin Wang */ 1119dd0191d5SShuanglin Wang if (bnxt_ulp_cntxt_shared_session_enabled(bp->ulp_ctx)) { 1120dd0191d5SShuanglin Wang rc = ulp_tf_ctx_shared_session_open(bp, 1121dd0191d5SShuanglin Wang BNXT_ULP_SESSION_TYPE_SHARED, 1122dd0191d5SShuanglin Wang session); 1123dd0191d5SShuanglin Wang if (rc) { 1124dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to open shared session (%d)\n", 1125dd0191d5SShuanglin Wang rc); 1126dd0191d5SShuanglin Wang goto error_deinit; 1127dd0191d5SShuanglin Wang } 1128dd0191d5SShuanglin Wang } 1129dd0191d5SShuanglin Wang 1130dd0191d5SShuanglin Wang /* Multiple session support */ 1131dd0191d5SShuanglin Wang if (bnxt_ulp_cntxt_multi_shared_session_enabled(bp->ulp_ctx)) { 1132dd0191d5SShuanglin Wang stype = BNXT_ULP_SESSION_TYPE_SHARED_WC; 1133dd0191d5SShuanglin Wang rc = ulp_tf_ctx_shared_session_open(bp, stype, session); 1134dd0191d5SShuanglin Wang if (rc) { 1135dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 1136dd0191d5SShuanglin Wang "Unable to open shared wc session (%d)\n", 1137dd0191d5SShuanglin Wang rc); 1138dd0191d5SShuanglin Wang goto error_deinit; 1139dd0191d5SShuanglin Wang } 1140dd0191d5SShuanglin Wang } 1141dd0191d5SShuanglin Wang bnxt_ulp_cntxt_num_shared_clients_set(bp->ulp_ctx, true); 1142dd0191d5SShuanglin Wang 1143dd0191d5SShuanglin Wang /* Open the ulp session. */ 1144dd0191d5SShuanglin Wang rc = ulp_tf_ctx_session_open(bp, session); 1145dd0191d5SShuanglin Wang if (rc) 1146dd0191d5SShuanglin Wang goto error_deinit; 1147dd0191d5SShuanglin Wang 1148dd0191d5SShuanglin Wang tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT); 1149dd0191d5SShuanglin Wang bnxt_ulp_cntxt_tfp_set(bp->ulp_ctx, BNXT_ULP_SESSION_TYPE_DEFAULT, tfp); 1150dd0191d5SShuanglin Wang return rc; 1151dd0191d5SShuanglin Wang 1152dd0191d5SShuanglin Wang error_deinit: 1153dd0191d5SShuanglin Wang session->session_opened[BNXT_ULP_SESSION_TYPE_DEFAULT] = 1; 1154dd0191d5SShuanglin Wang (void)ulp_tf_ctx_deinit(bp, session); 1155dd0191d5SShuanglin Wang return rc; 1156dd0191d5SShuanglin Wang } 1157dd0191d5SShuanglin Wang 1158dd0191d5SShuanglin Wang /* The function to initialize ulp dparms with devargs */ 1159dd0191d5SShuanglin Wang static int32_t 1160dd0191d5SShuanglin Wang ulp_tf_dparms_init(struct bnxt *bp, struct bnxt_ulp_context *ulp_ctx) 1161dd0191d5SShuanglin Wang { 1162dd0191d5SShuanglin Wang struct bnxt_ulp_device_params *dparms; 1163dd0191d5SShuanglin Wang uint32_t dev_id = BNXT_ULP_DEVICE_ID_LAST; 1164dd0191d5SShuanglin Wang 1165dd0191d5SShuanglin Wang if (!bp->max_num_kflows) { 1166dd0191d5SShuanglin Wang /* Defaults to Internal */ 1167dd0191d5SShuanglin Wang bnxt_ulp_cntxt_mem_type_set(ulp_ctx, 1168dd0191d5SShuanglin Wang BNXT_ULP_FLOW_MEM_TYPE_INT); 1169dd0191d5SShuanglin Wang return 0; 1170dd0191d5SShuanglin Wang } 1171dd0191d5SShuanglin Wang 1172dd0191d5SShuanglin Wang /* The max_num_kflows were set, so move to external */ 1173dd0191d5SShuanglin Wang if (bnxt_ulp_cntxt_mem_type_set(ulp_ctx, BNXT_ULP_FLOW_MEM_TYPE_EXT)) 1174dd0191d5SShuanglin Wang return -EINVAL; 1175dd0191d5SShuanglin Wang 1176dd0191d5SShuanglin Wang if (bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &dev_id)) { 1177dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "Failed to get device id\n"); 1178dd0191d5SShuanglin Wang return -EINVAL; 1179dd0191d5SShuanglin Wang } 1180dd0191d5SShuanglin Wang 1181dd0191d5SShuanglin Wang dparms = bnxt_ulp_device_params_get(dev_id); 1182dd0191d5SShuanglin Wang if (!dparms) { 1183dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "Failed to get device parms\n"); 1184dd0191d5SShuanglin Wang return -EINVAL; 1185dd0191d5SShuanglin Wang } 1186dd0191d5SShuanglin Wang 1187dd0191d5SShuanglin Wang /* num_flows = max_num_kflows * 1024 */ 1188dd0191d5SShuanglin Wang dparms->ext_flow_db_num_entries = bp->max_num_kflows * 1024; 1189dd0191d5SShuanglin Wang /* GFID = 2 * num_flows */ 1190dd0191d5SShuanglin Wang dparms->mark_db_gfid_entries = dparms->ext_flow_db_num_entries * 2; 1191dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "Set the number of flows = %" PRIu64 "\n", 1192dd0191d5SShuanglin Wang dparms->ext_flow_db_num_entries); 1193dd0191d5SShuanglin Wang 1194dd0191d5SShuanglin Wang return 0; 1195dd0191d5SShuanglin Wang } 1196dd0191d5SShuanglin Wang 1197dd0191d5SShuanglin Wang static int32_t 1198dd0191d5SShuanglin Wang ulp_tf_ctx_attach(struct bnxt *bp, 1199dd0191d5SShuanglin Wang struct bnxt_ulp_session_state *session) 1200dd0191d5SShuanglin Wang { 1201dd0191d5SShuanglin Wang int32_t rc = 0; 1202dd0191d5SShuanglin Wang uint32_t flags, dev_id = BNXT_ULP_DEVICE_ID_LAST; 1203dd0191d5SShuanglin Wang struct tf *tfp; 1204dd0191d5SShuanglin Wang uint8_t app_id; 1205dd0191d5SShuanglin Wang 1206dd0191d5SShuanglin Wang /* Increment the ulp context data reference count usage. */ 1207dd0191d5SShuanglin Wang bp->ulp_ctx->cfg_data = session->cfg_data; 1208dd0191d5SShuanglin Wang bp->ulp_ctx->cfg_data->ref_cnt++; 1209dd0191d5SShuanglin Wang 1210dd0191d5SShuanglin Wang /* update the session details in bnxt tfp */ 1211dd0191d5SShuanglin Wang tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT); 1212dd0191d5SShuanglin Wang tfp->session = ulp_tf_session_tfp_get(session, 1213dd0191d5SShuanglin Wang BNXT_ULP_SESSION_TYPE_DEFAULT); 1214dd0191d5SShuanglin Wang 1215dd0191d5SShuanglin Wang /* Add the context to the context entries list */ 1216dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_list_add(bp->ulp_ctx); 1217dd0191d5SShuanglin Wang if (rc) { 1218dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to add the context list entry\n"); 1219dd0191d5SShuanglin Wang return -EINVAL; 1220dd0191d5SShuanglin Wang } 1221dd0191d5SShuanglin Wang 1222dd0191d5SShuanglin Wang /* 1223dd0191d5SShuanglin Wang * The supported flag will be set during the init. Use it now to 1224dd0191d5SShuanglin Wang * know if we should go through the attach. 1225dd0191d5SShuanglin Wang */ 1226dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_app_id_get(bp->ulp_ctx, &app_id); 1227dd0191d5SShuanglin Wang if (rc) { 1228dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to get the app id from ulp.\n"); 1229dd0191d5SShuanglin Wang return -EINVAL; 1230dd0191d5SShuanglin Wang } 1231dd0191d5SShuanglin Wang 1232dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &dev_id); 1233dd0191d5SShuanglin Wang if (rc) { 1234dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable do get the dev_id.\n"); 1235dd0191d5SShuanglin Wang return -EINVAL; 1236dd0191d5SShuanglin Wang } 1237dd0191d5SShuanglin Wang 1238dd0191d5SShuanglin Wang flags = bp->ulp_ctx->cfg_data->ulp_flags; 1239dd0191d5SShuanglin Wang if (ULP_APP_DEV_UNSUPPORTED_ENABLED(flags)) { 1240dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "APP ID %d, Device ID: 0x%x not supported.\n", 1241dd0191d5SShuanglin Wang app_id, dev_id); 1242dd0191d5SShuanglin Wang return -EINVAL; 1243dd0191d5SShuanglin Wang } 1244dd0191d5SShuanglin Wang 1245dd0191d5SShuanglin Wang /* Create a TF Client */ 1246dd0191d5SShuanglin Wang rc = ulp_tf_ctx_session_open(bp, session); 1247dd0191d5SShuanglin Wang if (rc) { 1248dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to open ctxt session, rc:%d\n", rc); 1249dd0191d5SShuanglin Wang tfp->session = NULL; 1250dd0191d5SShuanglin Wang return rc; 1251dd0191d5SShuanglin Wang } 1252dd0191d5SShuanglin Wang tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT); 1253dd0191d5SShuanglin Wang bnxt_ulp_cntxt_tfp_set(bp->ulp_ctx, BNXT_ULP_SESSION_TYPE_DEFAULT, tfp); 1254dd0191d5SShuanglin Wang 1255dd0191d5SShuanglin Wang /* 1256dd0191d5SShuanglin Wang * Attach to the shared session, must be called after the 1257dd0191d5SShuanglin Wang * ulp_ctx_attach in order to ensure that ulp data is available 1258dd0191d5SShuanglin Wang * for attaching. 1259dd0191d5SShuanglin Wang */ 1260dd0191d5SShuanglin Wang rc = ulp_tf_ctx_shared_session_attach(bp, session); 1261dd0191d5SShuanglin Wang if (rc) 1262dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed attach to shared session (%d)", rc); 1263dd0191d5SShuanglin Wang 1264dd0191d5SShuanglin Wang return rc; 1265dd0191d5SShuanglin Wang } 1266dd0191d5SShuanglin Wang 1267dd0191d5SShuanglin Wang static void 1268dd0191d5SShuanglin Wang ulp_tf_ctx_detach(struct bnxt *bp, 1269dd0191d5SShuanglin Wang struct bnxt_ulp_session_state *session __rte_unused) 1270dd0191d5SShuanglin Wang { 1271dd0191d5SShuanglin Wang struct tf *tfp; 1272dd0191d5SShuanglin Wang 1273dd0191d5SShuanglin Wang tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT); 1274dd0191d5SShuanglin Wang if (tfp->session) { 1275dd0191d5SShuanglin Wang tf_close_session(tfp); 1276dd0191d5SShuanglin Wang tfp->session = NULL; 1277dd0191d5SShuanglin Wang } 1278dd0191d5SShuanglin Wang 1279dd0191d5SShuanglin Wang /* always detach/close shared after the session. */ 1280dd0191d5SShuanglin Wang ulp_tf_ctx_shared_session_detach(bp); 1281dd0191d5SShuanglin Wang } 1282dd0191d5SShuanglin Wang 1283dd0191d5SShuanglin Wang /* 1284dd0191d5SShuanglin Wang * Internal api to enable NAT feature. 1285dd0191d5SShuanglin Wang * Set set_flag to 1 to set the value or zero to reset the value. 1286dd0191d5SShuanglin Wang * returns 0 on success. 1287dd0191d5SShuanglin Wang */ 1288dd0191d5SShuanglin Wang static int32_t 1289dd0191d5SShuanglin Wang ulp_tf_global_cfg_update(struct bnxt *bp, 1290dd0191d5SShuanglin Wang enum tf_dir dir, 1291dd0191d5SShuanglin Wang enum tf_global_config_type type, 1292dd0191d5SShuanglin Wang uint32_t offset, 1293dd0191d5SShuanglin Wang uint32_t value, 1294dd0191d5SShuanglin Wang uint32_t set_flag) 1295dd0191d5SShuanglin Wang { 1296dd0191d5SShuanglin Wang uint32_t global_cfg = 0; 1297dd0191d5SShuanglin Wang int rc; 1298dd0191d5SShuanglin Wang struct tf_global_cfg_parms parms = { 0 }; 1299dd0191d5SShuanglin Wang struct tf *tfp; 1300dd0191d5SShuanglin Wang 1301dd0191d5SShuanglin Wang /* Initialize the params */ 1302dd0191d5SShuanglin Wang parms.dir = dir, 1303dd0191d5SShuanglin Wang parms.type = type, 1304dd0191d5SShuanglin Wang parms.offset = offset, 1305dd0191d5SShuanglin Wang parms.config = (uint8_t *)&global_cfg, 1306dd0191d5SShuanglin Wang parms.config_sz_in_bytes = sizeof(global_cfg); 1307dd0191d5SShuanglin Wang 1308dd0191d5SShuanglin Wang tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT); 1309dd0191d5SShuanglin Wang rc = tf_get_global_cfg(tfp, &parms); 1310dd0191d5SShuanglin Wang if (rc) { 1311dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get global cfg 0x%x rc:%d\n", 1312dd0191d5SShuanglin Wang type, rc); 1313dd0191d5SShuanglin Wang return rc; 1314dd0191d5SShuanglin Wang } 1315dd0191d5SShuanglin Wang 1316dd0191d5SShuanglin Wang if (set_flag) 1317dd0191d5SShuanglin Wang global_cfg |= value; 1318dd0191d5SShuanglin Wang else 1319dd0191d5SShuanglin Wang global_cfg &= ~value; 1320dd0191d5SShuanglin Wang 1321dd0191d5SShuanglin Wang /* SET the register RE_CFA_REG_ACT_TECT */ 1322dd0191d5SShuanglin Wang rc = tf_set_global_cfg(tfp, &parms); 1323dd0191d5SShuanglin Wang if (rc) { 1324dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to set global cfg 0x%x rc:%d\n", 1325dd0191d5SShuanglin Wang type, rc); 1326dd0191d5SShuanglin Wang return rc; 1327dd0191d5SShuanglin Wang } 1328dd0191d5SShuanglin Wang return rc; 1329dd0191d5SShuanglin Wang } 1330dd0191d5SShuanglin Wang 133180d760e1SJay Ding /** 133280d760e1SJay Ding * When a port is initialized by dpdk. This functions is called 133380d760e1SJay Ding * to enable the meter and initializes the meter global configurations. 133480d760e1SJay Ding */ 133580d760e1SJay Ding #define BNXT_THOR_FMTCR_NUM_MET_MET_1K (0x7UL << 20) 133680d760e1SJay Ding #define BNXT_THOR_FMTCR_CNTRS_ENABLE (0x1UL << 25) 133780d760e1SJay Ding #define BNXT_THOR_FMTCR_INTERVAL_1K (1024) 133880d760e1SJay Ding static int32_t 133980d760e1SJay Ding ulp_tf_flow_mtr_init(struct bnxt *bp) 134080d760e1SJay Ding { 134180d760e1SJay Ding int rc = 0; 134280d760e1SJay Ding 134380d760e1SJay Ding /* 134480d760e1SJay Ding * Enable metering. Set the meter global configuration register. 134580d760e1SJay Ding * Set number of meter to 1K. Disable the drop counter for now. 134680d760e1SJay Ding */ 134780d760e1SJay Ding rc = ulp_tf_global_cfg_update(bp, TF_DIR_RX, TF_METER_CFG, 134880d760e1SJay Ding 0, 134980d760e1SJay Ding BNXT_THOR_FMTCR_NUM_MET_MET_1K, 135080d760e1SJay Ding 1); 135180d760e1SJay Ding if (rc) { 135280d760e1SJay Ding BNXT_DRV_DBG(ERR, "Failed to set rx meter configuration\n"); 135380d760e1SJay Ding goto jump_to_error; 135480d760e1SJay Ding } 135580d760e1SJay Ding 135680d760e1SJay Ding rc = ulp_tf_global_cfg_update(bp, TF_DIR_TX, TF_METER_CFG, 135780d760e1SJay Ding 0, 135880d760e1SJay Ding BNXT_THOR_FMTCR_NUM_MET_MET_1K, 135980d760e1SJay Ding 1); 136080d760e1SJay Ding if (rc) { 136180d760e1SJay Ding BNXT_DRV_DBG(ERR, "Failed to set tx meter configuration\n"); 136280d760e1SJay Ding goto jump_to_error; 136380d760e1SJay Ding } 136480d760e1SJay Ding 136580d760e1SJay Ding /* 136680d760e1SJay Ding * Set meter refresh rate to 1024 clock cycle. This value works for 136780d760e1SJay Ding * most bit rates especially for high rates. 136880d760e1SJay Ding */ 136980d760e1SJay Ding rc = ulp_tf_global_cfg_update(bp, TF_DIR_RX, TF_METER_INTERVAL_CFG, 137080d760e1SJay Ding 0, 137180d760e1SJay Ding BNXT_THOR_FMTCR_INTERVAL_1K, 137280d760e1SJay Ding 1); 137380d760e1SJay Ding if (rc) { 137480d760e1SJay Ding BNXT_DRV_DBG(ERR, "Failed to set rx meter interval\n"); 137580d760e1SJay Ding goto jump_to_error; 137680d760e1SJay Ding } 137780d760e1SJay Ding 137880d760e1SJay Ding rc = bnxt_flow_mtr_init(bp); 137980d760e1SJay Ding if (rc) { 138080d760e1SJay Ding BNXT_DRV_DBG(ERR, "Failed to config meter\n"); 138180d760e1SJay Ding goto jump_to_error; 138280d760e1SJay Ding } 138380d760e1SJay Ding 138480d760e1SJay Ding return rc; 138580d760e1SJay Ding 138680d760e1SJay Ding jump_to_error: 138780d760e1SJay Ding return rc; 138880d760e1SJay Ding } 138980d760e1SJay Ding 1390dd0191d5SShuanglin Wang /* 1391dd0191d5SShuanglin Wang * When a port is deinit'ed by dpdk. This function is called 1392dd0191d5SShuanglin Wang * and this function clears the ULP context and rest of the 1393dd0191d5SShuanglin Wang * infrastructure associated with it. 1394dd0191d5SShuanglin Wang */ 1395dd0191d5SShuanglin Wang static void 1396dd0191d5SShuanglin Wang ulp_tf_deinit(struct bnxt *bp, 1397dd0191d5SShuanglin Wang struct bnxt_ulp_session_state *session) 1398dd0191d5SShuanglin Wang { 1399dd0191d5SShuanglin Wang bool ha_enabled; 1400dd0191d5SShuanglin Wang 1401dd0191d5SShuanglin Wang if (!bp->ulp_ctx || !bp->ulp_ctx->cfg_data) 1402dd0191d5SShuanglin Wang return; 1403dd0191d5SShuanglin Wang 1404dd0191d5SShuanglin Wang ha_enabled = bnxt_ulp_cntxt_ha_enabled(bp->ulp_ctx); 1405dd0191d5SShuanglin Wang if (ha_enabled && 1406dd0191d5SShuanglin Wang ulp_tf_session_is_open(session, BNXT_ULP_SESSION_TYPE_DEFAULT)) { 1407dd0191d5SShuanglin Wang int32_t rc = ulp_ha_mgr_close(bp->ulp_ctx); 1408dd0191d5SShuanglin Wang if (rc) 1409dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to close HA (%d)\n", rc); 1410dd0191d5SShuanglin Wang } 1411dd0191d5SShuanglin Wang 1412dd0191d5SShuanglin Wang /* cleanup the eem table scope */ 1413dd0191d5SShuanglin Wang ulp_tf_eem_tbl_scope_deinit(bp, bp->ulp_ctx); 1414dd0191d5SShuanglin Wang 1415dd0191d5SShuanglin Wang /* cleanup the flow database */ 1416dd0191d5SShuanglin Wang ulp_flow_db_deinit(bp->ulp_ctx); 1417dd0191d5SShuanglin Wang 1418dd0191d5SShuanglin Wang /* Delete the Mark database */ 1419dd0191d5SShuanglin Wang ulp_mark_db_deinit(bp->ulp_ctx); 1420dd0191d5SShuanglin Wang 1421dd0191d5SShuanglin Wang /* cleanup the ulp mapper */ 1422dd0191d5SShuanglin Wang ulp_mapper_deinit(bp->ulp_ctx); 1423dd0191d5SShuanglin Wang 1424dd0191d5SShuanglin Wang /* cleanup the ulp matcher */ 1425dd0191d5SShuanglin Wang ulp_matcher_deinit(bp->ulp_ctx); 1426dd0191d5SShuanglin Wang 1427dd0191d5SShuanglin Wang /* Delete the Flow Counter Manager */ 1428dd0191d5SShuanglin Wang ulp_fc_mgr_deinit(bp->ulp_ctx); 1429dd0191d5SShuanglin Wang 1430dd0191d5SShuanglin Wang /* Delete the Port database */ 1431dd0191d5SShuanglin Wang ulp_port_db_deinit(bp->ulp_ctx); 1432dd0191d5SShuanglin Wang 1433dd0191d5SShuanglin Wang /* Disable NAT feature */ 1434dd0191d5SShuanglin Wang (void)ulp_tf_global_cfg_update(bp, TF_DIR_RX, TF_TUNNEL_ENCAP, 1435dd0191d5SShuanglin Wang TF_TUNNEL_ENCAP_NAT, 1436dd0191d5SShuanglin Wang BNXT_ULP_NAT_OUTER_MOST_FLAGS, 0); 1437dd0191d5SShuanglin Wang 1438dd0191d5SShuanglin Wang (void)ulp_tf_global_cfg_update(bp, TF_DIR_TX, TF_TUNNEL_ENCAP, 1439dd0191d5SShuanglin Wang TF_TUNNEL_ENCAP_NAT, 1440dd0191d5SShuanglin Wang BNXT_ULP_NAT_OUTER_MOST_FLAGS, 0); 1441dd0191d5SShuanglin Wang 1442dd0191d5SShuanglin Wang /* free the flow db lock */ 1443dd0191d5SShuanglin Wang pthread_mutex_destroy(&bp->ulp_ctx->cfg_data->flow_db_lock); 1444dd0191d5SShuanglin Wang 1445dd0191d5SShuanglin Wang if (ha_enabled) 1446dd0191d5SShuanglin Wang ulp_ha_mgr_deinit(bp->ulp_ctx); 1447dd0191d5SShuanglin Wang 1448dd0191d5SShuanglin Wang /* Delete the ulp context and tf session and free the ulp context */ 1449dd0191d5SShuanglin Wang ulp_tf_ctx_deinit(bp, session); 1450dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "ulp ctx has been deinitialized\n"); 1451dd0191d5SShuanglin Wang } 1452dd0191d5SShuanglin Wang 1453dd0191d5SShuanglin Wang /* 1454dd0191d5SShuanglin Wang * When a port is initialized by dpdk. This functions is called 1455dd0191d5SShuanglin Wang * and this function initializes the ULP context and rest of the 1456dd0191d5SShuanglin Wang * infrastructure associated with it. 1457dd0191d5SShuanglin Wang */ 1458dd0191d5SShuanglin Wang static int32_t 1459dd0191d5SShuanglin Wang ulp_tf_init(struct bnxt *bp, 1460dd0191d5SShuanglin Wang struct bnxt_ulp_session_state *session) 1461dd0191d5SShuanglin Wang { 1462dd0191d5SShuanglin Wang int rc; 1463dd0191d5SShuanglin Wang uint32_t ulp_dev_id = BNXT_ULP_DEVICE_ID_LAST; 1464dd0191d5SShuanglin Wang 1465b14da654SPeter Spreadborough /* Select 64bit SSE4.2 intrinsic if available */ 1466b14da654SPeter Spreadborough rte_hash_crc_set_alg(CRC32_SSE42_x64); 1467b14da654SPeter Spreadborough 1468dd0191d5SShuanglin Wang /* Allocate and Initialize the ulp context. */ 1469dd0191d5SShuanglin Wang rc = ulp_tf_ctx_init(bp, session); 1470dd0191d5SShuanglin Wang if (rc) { 1471dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to create the ulp context\n"); 1472dd0191d5SShuanglin Wang goto jump_to_error; 1473dd0191d5SShuanglin Wang } 1474dd0191d5SShuanglin Wang 1475*7d32c003SAriel Otilibili pthread_mutex_init(&bp->ulp_ctx->cfg_data->flow_db_lock, NULL); 1476dd0191d5SShuanglin Wang 1477dd0191d5SShuanglin Wang /* Initialize ulp dparms with values devargs passed */ 1478dd0191d5SShuanglin Wang rc = ulp_tf_dparms_init(bp, bp->ulp_ctx); 1479dd0191d5SShuanglin Wang if (rc) { 1480dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to initialize the dparms\n"); 1481dd0191d5SShuanglin Wang goto jump_to_error; 1482dd0191d5SShuanglin Wang } 1483dd0191d5SShuanglin Wang 1484dd0191d5SShuanglin Wang /* create the port database */ 1485dd0191d5SShuanglin Wang rc = ulp_port_db_init(bp->ulp_ctx, bp->port_cnt); 1486dd0191d5SShuanglin Wang if (rc) { 1487dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to create the port database\n"); 1488dd0191d5SShuanglin Wang goto jump_to_error; 1489dd0191d5SShuanglin Wang } 1490dd0191d5SShuanglin Wang 1491dd0191d5SShuanglin Wang /* Create the Mark database. */ 1492dd0191d5SShuanglin Wang rc = ulp_mark_db_init(bp->ulp_ctx); 1493dd0191d5SShuanglin Wang if (rc) { 1494dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to create the mark database\n"); 1495dd0191d5SShuanglin Wang goto jump_to_error; 1496dd0191d5SShuanglin Wang } 1497dd0191d5SShuanglin Wang 1498dd0191d5SShuanglin Wang /* Create the flow database. */ 1499dd0191d5SShuanglin Wang rc = ulp_flow_db_init(bp->ulp_ctx); 1500dd0191d5SShuanglin Wang if (rc) { 1501dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to create the flow database\n"); 1502dd0191d5SShuanglin Wang goto jump_to_error; 1503dd0191d5SShuanglin Wang } 1504dd0191d5SShuanglin Wang 1505dd0191d5SShuanglin Wang /* Create the eem table scope. */ 1506dd0191d5SShuanglin Wang rc = ulp_tf_eem_tbl_scope_init(bp); 1507dd0191d5SShuanglin Wang if (rc) { 1508dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to create the eem scope table\n"); 1509dd0191d5SShuanglin Wang goto jump_to_error; 1510dd0191d5SShuanglin Wang } 1511dd0191d5SShuanglin Wang 1512dd0191d5SShuanglin Wang rc = ulp_matcher_init(bp->ulp_ctx); 1513dd0191d5SShuanglin Wang if (rc) { 1514dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to initialize ulp matcher\n"); 1515dd0191d5SShuanglin Wang goto jump_to_error; 1516dd0191d5SShuanglin Wang } 1517dd0191d5SShuanglin Wang 1518dd0191d5SShuanglin Wang rc = ulp_mapper_init(bp->ulp_ctx); 1519dd0191d5SShuanglin Wang if (rc) { 1520dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to initialize ulp mapper\n"); 1521dd0191d5SShuanglin Wang goto jump_to_error; 1522dd0191d5SShuanglin Wang } 1523dd0191d5SShuanglin Wang 1524dd0191d5SShuanglin Wang rc = ulp_fc_mgr_init(bp->ulp_ctx); 1525dd0191d5SShuanglin Wang if (rc) { 1526dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to initialize ulp flow counter mgr\n"); 1527dd0191d5SShuanglin Wang goto jump_to_error; 1528dd0191d5SShuanglin Wang } 1529dd0191d5SShuanglin Wang 1530dd0191d5SShuanglin Wang /* 1531dd0191d5SShuanglin Wang * Enable NAT feature. Set the global configuration register 1532dd0191d5SShuanglin Wang * Tunnel encap to enable NAT with the reuse of existing inner 1533dd0191d5SShuanglin Wang * L2 header smac and dmac 1534dd0191d5SShuanglin Wang */ 1535dd0191d5SShuanglin Wang rc = ulp_tf_global_cfg_update(bp, TF_DIR_RX, TF_TUNNEL_ENCAP, 1536dd0191d5SShuanglin Wang TF_TUNNEL_ENCAP_NAT, 1537dd0191d5SShuanglin Wang BNXT_ULP_NAT_OUTER_MOST_FLAGS, 1); 1538dd0191d5SShuanglin Wang if (rc) { 1539dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to set rx global configuration\n"); 1540dd0191d5SShuanglin Wang goto jump_to_error; 1541dd0191d5SShuanglin Wang } 1542dd0191d5SShuanglin Wang 1543dd0191d5SShuanglin Wang rc = ulp_tf_global_cfg_update(bp, TF_DIR_TX, TF_TUNNEL_ENCAP, 1544dd0191d5SShuanglin Wang TF_TUNNEL_ENCAP_NAT, 1545dd0191d5SShuanglin Wang BNXT_ULP_NAT_OUTER_MOST_FLAGS, 1); 1546dd0191d5SShuanglin Wang if (rc) { 1547dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to set tx global configuration\n"); 1548dd0191d5SShuanglin Wang goto jump_to_error; 1549dd0191d5SShuanglin Wang } 1550dd0191d5SShuanglin Wang 1551dd0191d5SShuanglin Wang if (bnxt_ulp_cntxt_ha_enabled(bp->ulp_ctx)) { 1552dd0191d5SShuanglin Wang rc = ulp_ha_mgr_init(bp->ulp_ctx); 1553dd0191d5SShuanglin Wang if (rc) { 1554dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to initialize HA %d\n", rc); 1555dd0191d5SShuanglin Wang goto jump_to_error; 1556dd0191d5SShuanglin Wang } 1557dd0191d5SShuanglin Wang rc = ulp_ha_mgr_open(bp->ulp_ctx); 1558dd0191d5SShuanglin Wang if (rc) { 1559dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to Process HA Open %d\n", rc); 1560dd0191d5SShuanglin Wang goto jump_to_error; 1561dd0191d5SShuanglin Wang } 1562dd0191d5SShuanglin Wang } 1563dd0191d5SShuanglin Wang 1564dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &ulp_dev_id); 1565dd0191d5SShuanglin Wang if (rc) { 1566dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Unable to get device id from ulp.\n"); 1567dd0191d5SShuanglin Wang return rc; 1568dd0191d5SShuanglin Wang } 1569dd0191d5SShuanglin Wang 1570dd0191d5SShuanglin Wang if (ulp_dev_id == BNXT_ULP_DEVICE_ID_THOR) { 157180d760e1SJay Ding rc = ulp_tf_flow_mtr_init(bp); 1572dd0191d5SShuanglin Wang if (rc) { 1573dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to config meter\n"); 1574dd0191d5SShuanglin Wang goto jump_to_error; 1575dd0191d5SShuanglin Wang } 1576dd0191d5SShuanglin Wang } 1577dd0191d5SShuanglin Wang 1578dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "ulp ctx has been initialized\n"); 1579dd0191d5SShuanglin Wang return rc; 1580dd0191d5SShuanglin Wang 1581dd0191d5SShuanglin Wang jump_to_error: 1582dd0191d5SShuanglin Wang bp->ulp_ctx->ops->ulp_deinit(bp, session); 1583dd0191d5SShuanglin Wang return rc; 1584dd0191d5SShuanglin Wang } 1585dd0191d5SShuanglin Wang 158680d760e1SJay Ding /** 158780d760e1SJay Ding * Get meter capabilities. 158880d760e1SJay Ding */ 158980d760e1SJay Ding #define MAX_FLOW_PER_METER 1024 159080d760e1SJay Ding #define MAX_METER_RATE_100GBPS ((1ULL << 30) * 100 / 8) 159180d760e1SJay Ding static int 159280d760e1SJay Ding ulp_tf_mtr_cap_get(struct bnxt *bp, 159380d760e1SJay Ding struct rte_mtr_capabilities *cap) 159480d760e1SJay Ding { 159580d760e1SJay Ding struct tf_get_session_info_parms iparms; 159680d760e1SJay Ding struct tf *tfp; 159780d760e1SJay Ding int32_t rc = 0; 159880d760e1SJay Ding 159980d760e1SJay Ding /* Get number of meter reserved for this session */ 160080d760e1SJay Ding memset(&iparms, 0, sizeof(iparms)); 160180d760e1SJay Ding tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT); 160280d760e1SJay Ding rc = tf_get_session_info(tfp, &iparms); 160380d760e1SJay Ding if (rc != 0) { 160480d760e1SJay Ding BNXT_DRV_DBG(ERR, "Failed to get session resource info\n"); 160580d760e1SJay Ding return rc; 160680d760e1SJay Ding } 160780d760e1SJay Ding 160880d760e1SJay Ding memset(cap, 0, sizeof(struct rte_mtr_capabilities)); 160980d760e1SJay Ding 161080d760e1SJay Ding cap->n_max = iparms.session_info.tbl[TF_DIR_RX].info[TF_TBL_TYPE_METER_INST].stride; 161180d760e1SJay Ding if (!cap->n_max) { 161280d760e1SJay Ding BNXT_DRV_DBG(ERR, "Meter is not supported\n"); 161380d760e1SJay Ding return -EINVAL; 161480d760e1SJay Ding } 161580d760e1SJay Ding 161680d760e1SJay Ding #if (RTE_VERSION_NUM(21, 05, 0, 0) <= RTE_VERSION) 161780d760e1SJay Ding cap->srtcm_rfc2697_byte_mode_supported = 1; 161880d760e1SJay Ding #endif 161980d760e1SJay Ding cap->n_shared_max = cap->n_max; 162080d760e1SJay Ding /* No meter is identical */ 162180d760e1SJay Ding cap->identical = 1; 162280d760e1SJay Ding cap->shared_identical = 1; 162380d760e1SJay Ding cap->shared_n_flows_per_mtr_max = MAX_FLOW_PER_METER; 162480d760e1SJay Ding cap->chaining_n_mtrs_per_flow_max = 1; /* Chaining is not supported. */ 162580d760e1SJay Ding cap->meter_srtcm_rfc2697_n_max = cap->n_max; 162680d760e1SJay Ding cap->meter_rate_max = MAX_METER_RATE_100GBPS; 162780d760e1SJay Ding /* No stats supported now */ 162880d760e1SJay Ding cap->stats_mask = 0; 162980d760e1SJay Ding 163080d760e1SJay Ding return 0; 163180d760e1SJay Ding } 163280d760e1SJay Ding 1633dd0191d5SShuanglin Wang const struct bnxt_ulp_core_ops bnxt_ulp_tf_core_ops = { 1634dd0191d5SShuanglin Wang .ulp_ctx_attach = ulp_tf_ctx_attach, 1635dd0191d5SShuanglin Wang .ulp_ctx_detach = ulp_tf_ctx_detach, 1636dd0191d5SShuanglin Wang .ulp_deinit = ulp_tf_deinit, 1637dd0191d5SShuanglin Wang .ulp_init = ulp_tf_init, 1638be4732e8SMike Baucom .ulp_vfr_session_fid_add = NULL, 163980d760e1SJay Ding .ulp_vfr_session_fid_rem = NULL, 164080d760e1SJay Ding .ulp_mtr_cap_get = ulp_tf_mtr_cap_get 1641dd0191d5SShuanglin Wang }; 1642