1313ac35aSVenkat Duvvuru /* SPDX-License-Identifier: BSD-3-Clause 2d9e70b1dSRandy Schacher * Copyright(c) 2019-2023 Broadcom 3313ac35aSVenkat Duvvuru * All rights reserved. 4313ac35aSVenkat Duvvuru */ 5313ac35aSVenkat Duvvuru 6313ac35aSVenkat Duvvuru #include <rte_log.h> 7313ac35aSVenkat Duvvuru #include <rte_malloc.h> 8313ac35aSVenkat Duvvuru #include <rte_flow.h> 9313ac35aSVenkat Duvvuru #include <rte_flow_driver.h> 10313ac35aSVenkat Duvvuru #include <rte_tailq.h> 11d75b5512SKishore Padmanabha #include <rte_spinlock.h> 12313ac35aSVenkat Duvvuru 13769de168SVenkat Duvvuru #include "bnxt.h" 14313ac35aSVenkat Duvvuru #include "bnxt_ulp.h" 150c036a14SPeter Spreadborough #include "bnxt_ulp_utils.h" 16313ac35aSVenkat Duvvuru #include "bnxt_tf_common.h" 17dd0191d5SShuanglin Wang #include "bnxt_hwrm.h" 18d9e70b1dSRandy Schacher #include "hsi_struct_def_dpdk.h" 19313ac35aSVenkat Duvvuru #include "tf_core.h" 20313ac35aSVenkat Duvvuru #include "tf_ext_flow_handle.h" 21313ac35aSVenkat Duvvuru 228ce17d56SKishore Padmanabha #include "ulp_template_db_enum.h" 23313ac35aSVenkat Duvvuru #include "ulp_template_struct.h" 24313ac35aSVenkat Duvvuru #include "ulp_mark_mgr.h" 259cf9c838SSomnath Kotur #include "ulp_fc_mgr.h" 26313ac35aSVenkat Duvvuru #include "ulp_flow_db.h" 27072cb4a8SMike Baucom #include "ulp_mapper.h" 28dd0191d5SShuanglin Wang #include "ulp_matcher.h" 29dc8ee812SKishore Padmanabha #include "ulp_port_db.h" 303fe124d2SKishore Padmanabha #include "ulp_tun.h" 313184b1efSMike Baucom #include "ulp_ha_mgr.h" 321993b267SShahaji Bhosle #include "bnxt_tf_pmd_shim.h" 33d9e70b1dSRandy Schacher #include "ulp_template_db_tbl.h" 34313ac35aSVenkat Duvvuru 35313ac35aSVenkat Duvvuru /* Linked list of all TF sessions. */ 36313ac35aSVenkat Duvvuru STAILQ_HEAD(, bnxt_ulp_session_state) bnxt_ulp_session_list = 37313ac35aSVenkat Duvvuru STAILQ_HEAD_INITIALIZER(bnxt_ulp_session_list); 38313ac35aSVenkat Duvvuru 39313ac35aSVenkat Duvvuru /* Mutex to synchronize bnxt_ulp_session_list operations. */ 40313ac35aSVenkat Duvvuru static pthread_mutex_t bnxt_ulp_global_mutex = PTHREAD_MUTEX_INITIALIZER; 41313ac35aSVenkat Duvvuru 42d75b5512SKishore Padmanabha /* Spin lock to protect context global list */ 43bf598786SKishore Padmanabha uint32_t bnxt_ulp_ctxt_lock_created; 44d75b5512SKishore Padmanabha rte_spinlock_t bnxt_ulp_ctxt_lock; 45d75b5512SKishore Padmanabha TAILQ_HEAD(cntx_list_entry_list, ulp_context_list_entry); 46d75b5512SKishore Padmanabha static struct cntx_list_entry_list ulp_cntx_list = 47d75b5512SKishore Padmanabha TAILQ_HEAD_INITIALIZER(ulp_cntx_list); 48d75b5512SKishore Padmanabha 492921498cSMike Baucom bool 502921498cSMike Baucom ulp_is_default_session_active(struct bnxt_ulp_context *ulp_ctx) 512921498cSMike Baucom { 520c036a14SPeter Spreadborough if (unlikely(ulp_ctx == NULL || ulp_ctx->g_tfp[0] == NULL)) 532921498cSMike Baucom return false; 542921498cSMike Baucom 552921498cSMike Baucom return true; 562921498cSMike Baucom } 57dd0191d5SShuanglin Wang 58313ac35aSVenkat Duvvuru /* 5970e64b27SVenkat Duvvuru * Allow the deletion of context only for the bnxt device that 6009b23f8bSKishore Padmanabha * created the session. 6170e64b27SVenkat Duvvuru */ 6270e64b27SVenkat Duvvuru bool 63c53c2f43SKishore Padmanabha ulp_ctx_deinit_allowed(struct bnxt_ulp_context *ulp_ctx) 6470e64b27SVenkat Duvvuru { 650c036a14SPeter Spreadborough if (unlikely(!ulp_ctx || !ulp_ctx->cfg_data)) 6609b23f8bSKishore Padmanabha return false; 6770e64b27SVenkat Duvvuru 68c53c2f43SKishore Padmanabha if (!ulp_ctx->cfg_data->ref_cnt) { 69dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "ulp ctx shall initiate deinit\n"); 7009b23f8bSKishore Padmanabha return true; 7109b23f8bSKishore Padmanabha } 7270e64b27SVenkat Duvvuru 7309b23f8bSKishore Padmanabha return false; 7470e64b27SVenkat Duvvuru } 7570e64b27SVenkat Duvvuru 76dd0191d5SShuanglin Wang /* The function to initialize bp flags with truflow features */ 77dd0191d5SShuanglin Wang static int32_t 78dd0191d5SShuanglin Wang ulp_dparms_dev_port_intf_update(struct bnxt *bp, 79dd0191d5SShuanglin Wang struct bnxt_ulp_context *ulp_ctx) 80dd0191d5SShuanglin Wang { 81dd0191d5SShuanglin Wang enum bnxt_ulp_flow_mem_type mtype; 82dd0191d5SShuanglin Wang 830c036a14SPeter Spreadborough if (unlikely(bnxt_ulp_cntxt_mem_type_get(ulp_ctx, &mtype))) 84dd0191d5SShuanglin Wang return -EINVAL; 85dd0191d5SShuanglin Wang /* Update the bp flag with gfid flag */ 86dd0191d5SShuanglin Wang if (mtype == BNXT_ULP_FLOW_MEM_TYPE_EXT) 87dd0191d5SShuanglin Wang bp->flags |= BNXT_FLAG_GFID_ENABLE; 88dd0191d5SShuanglin Wang 89d9e70b1dSRandy Schacher return 0; 90d9e70b1dSRandy Schacher } 91d9e70b1dSRandy Schacher 92dd0191d5SShuanglin Wang int32_t 931531aeabSShuanglin Wang ulp_ctx_mh_get_session_name(struct bnxt *bp, 941531aeabSShuanglin Wang struct tf_open_session_parms *parms) 951531aeabSShuanglin Wang { 961531aeabSShuanglin Wang int32_t rc = 0; 971531aeabSShuanglin Wang unsigned int domain = 0, bus = 0, slot = 0, device = 0; 981531aeabSShuanglin Wang rc = sscanf(parms->ctrl_chan_name, 991531aeabSShuanglin Wang "%x:%x:%x.%u", 1001531aeabSShuanglin Wang &domain, 1011531aeabSShuanglin Wang &bus, 1021531aeabSShuanglin Wang &slot, 1031531aeabSShuanglin Wang &device); 1041531aeabSShuanglin Wang if (rc != 4) { 1051531aeabSShuanglin Wang /* PCI Domain not provided (optional in DPDK), thus we 1061531aeabSShuanglin Wang * force domain to 0 and recheck. 1071531aeabSShuanglin Wang */ 1081531aeabSShuanglin Wang domain = 0; 1091531aeabSShuanglin Wang /* Check parsing of bus/slot/device */ 1101531aeabSShuanglin Wang rc = sscanf(parms->ctrl_chan_name, 1111531aeabSShuanglin Wang "%x:%x.%u", 1121531aeabSShuanglin Wang &bus, 1131531aeabSShuanglin Wang &slot, 1141531aeabSShuanglin Wang &device); 1150c036a14SPeter Spreadborough if (unlikely(rc != 3)) { 116dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, 1171531aeabSShuanglin Wang "Failed to scan device ctrl_chan_name\n"); 1181531aeabSShuanglin Wang return -EINVAL; 1191531aeabSShuanglin Wang } 1201531aeabSShuanglin Wang } 1211531aeabSShuanglin Wang 1221531aeabSShuanglin Wang /* change domain name for multi-host system */ 1231531aeabSShuanglin Wang domain = domain + (0xf & bp->multi_host_pf_pci_id); 1241531aeabSShuanglin Wang sprintf(parms->ctrl_chan_name, 1251531aeabSShuanglin Wang "%x:%x:%x.%u", 1261531aeabSShuanglin Wang domain, 1271531aeabSShuanglin Wang bus, 1281531aeabSShuanglin Wang slot, 1291531aeabSShuanglin Wang device); 130dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, 1311531aeabSShuanglin Wang "Session name for Multi-Host: ctrl_chan_name:%s\n", parms->ctrl_chan_name); 1321531aeabSShuanglin Wang return 0; 1331531aeabSShuanglin Wang } 1341531aeabSShuanglin Wang 135313ac35aSVenkat Duvvuru /* 136313ac35aSVenkat Duvvuru * Initialize the state of an ULP session. 137313ac35aSVenkat Duvvuru * If the state of an ULP session is not initialized, set it's state to 138313ac35aSVenkat Duvvuru * initialized. If the state is already initialized, do nothing. 139313ac35aSVenkat Duvvuru */ 140313ac35aSVenkat Duvvuru static void 141313ac35aSVenkat Duvvuru ulp_context_initialized(struct bnxt_ulp_session_state *session, bool *init) 142313ac35aSVenkat Duvvuru { 143313ac35aSVenkat Duvvuru pthread_mutex_lock(&session->bnxt_ulp_mutex); 144313ac35aSVenkat Duvvuru 145313ac35aSVenkat Duvvuru if (!session->bnxt_ulp_init) { 146313ac35aSVenkat Duvvuru session->bnxt_ulp_init = true; 147313ac35aSVenkat Duvvuru *init = false; 148313ac35aSVenkat Duvvuru } else { 149313ac35aSVenkat Duvvuru *init = true; 150313ac35aSVenkat Duvvuru } 151313ac35aSVenkat Duvvuru 152313ac35aSVenkat Duvvuru pthread_mutex_unlock(&session->bnxt_ulp_mutex); 153313ac35aSVenkat Duvvuru } 154313ac35aSVenkat Duvvuru 155313ac35aSVenkat Duvvuru /* 156313ac35aSVenkat Duvvuru * Check if an ULP session is already allocated for a specific PCI 157313ac35aSVenkat Duvvuru * domain & bus. If it is already allocated simply return the session 158313ac35aSVenkat Duvvuru * pointer, otherwise allocate a new session. 159313ac35aSVenkat Duvvuru */ 160313ac35aSVenkat Duvvuru static struct bnxt_ulp_session_state * 16134a7ff5aSKishore Padmanabha ulp_get_session(struct bnxt *bp, struct rte_pci_addr *pci_addr) 162313ac35aSVenkat Duvvuru { 163313ac35aSVenkat Duvvuru struct bnxt_ulp_session_state *session; 164313ac35aSVenkat Duvvuru 16534a7ff5aSKishore Padmanabha /* if multi root capability is enabled, then ignore the pci bus id */ 166313ac35aSVenkat Duvvuru STAILQ_FOREACH(session, &bnxt_ulp_session_list, next) { 1678c047e82SKishore Padmanabha if (BNXT_MULTIROOT_EN(bp)) { 1688c047e82SKishore Padmanabha if (!memcmp(bp->dsn, session->dsn, 1698c047e82SKishore Padmanabha sizeof(session->dsn))) { 1708c047e82SKishore Padmanabha return session; 1718c047e82SKishore Padmanabha } 1728c047e82SKishore Padmanabha } else if (session->pci_info.domain == pci_addr->domain && 1738c047e82SKishore Padmanabha session->pci_info.bus == pci_addr->bus) { 174313ac35aSVenkat Duvvuru return session; 175313ac35aSVenkat Duvvuru } 176313ac35aSVenkat Duvvuru } 177313ac35aSVenkat Duvvuru return NULL; 178313ac35aSVenkat Duvvuru } 179313ac35aSVenkat Duvvuru 180313ac35aSVenkat Duvvuru /* 181313ac35aSVenkat Duvvuru * Allocate and Initialize an ULP session and set it's state to INITIALIZED. 182313ac35aSVenkat Duvvuru * If it's already initialized simply return the already existing session. 183313ac35aSVenkat Duvvuru */ 184313ac35aSVenkat Duvvuru static struct bnxt_ulp_session_state * 185313ac35aSVenkat Duvvuru ulp_session_init(struct bnxt *bp, 186313ac35aSVenkat Duvvuru bool *init) 187313ac35aSVenkat Duvvuru { 188313ac35aSVenkat Duvvuru struct rte_pci_device *pci_dev; 189313ac35aSVenkat Duvvuru struct rte_pci_addr *pci_addr; 190313ac35aSVenkat Duvvuru struct bnxt_ulp_session_state *session; 191313ac35aSVenkat Duvvuru 192313ac35aSVenkat Duvvuru if (!bp) 193313ac35aSVenkat Duvvuru return NULL; 194313ac35aSVenkat Duvvuru 195313ac35aSVenkat Duvvuru pci_dev = RTE_DEV_TO_PCI(bp->eth_dev->device); 196313ac35aSVenkat Duvvuru pci_addr = &pci_dev->addr; 197313ac35aSVenkat Duvvuru 198313ac35aSVenkat Duvvuru pthread_mutex_lock(&bnxt_ulp_global_mutex); 199313ac35aSVenkat Duvvuru 20034a7ff5aSKishore Padmanabha session = ulp_get_session(bp, pci_addr); 201313ac35aSVenkat Duvvuru if (!session) { 202313ac35aSVenkat Duvvuru /* Not Found the session Allocate a new one */ 203313ac35aSVenkat Duvvuru session = rte_zmalloc("bnxt_ulp_session", 204313ac35aSVenkat Duvvuru sizeof(struct bnxt_ulp_session_state), 205313ac35aSVenkat Duvvuru 0); 206313ac35aSVenkat Duvvuru if (!session) { 207dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 208313ac35aSVenkat Duvvuru "Allocation failed for bnxt_ulp_session\n"); 209313ac35aSVenkat Duvvuru pthread_mutex_unlock(&bnxt_ulp_global_mutex); 210313ac35aSVenkat Duvvuru return NULL; 211313ac35aSVenkat Duvvuru 212313ac35aSVenkat Duvvuru } else { 213313ac35aSVenkat Duvvuru /* Add it to the queue */ 214313ac35aSVenkat Duvvuru session->pci_info.domain = pci_addr->domain; 215313ac35aSVenkat Duvvuru session->pci_info.bus = pci_addr->bus; 2168c047e82SKishore Padmanabha memcpy(session->dsn, bp->dsn, sizeof(session->dsn)); 217*7d32c003SAriel Otilibili pthread_mutex_init(&session->bnxt_ulp_mutex, NULL); 218313ac35aSVenkat Duvvuru STAILQ_INSERT_TAIL(&bnxt_ulp_session_list, 219313ac35aSVenkat Duvvuru session, next); 220313ac35aSVenkat Duvvuru } 221313ac35aSVenkat Duvvuru } 222313ac35aSVenkat Duvvuru ulp_context_initialized(session, init); 223313ac35aSVenkat Duvvuru pthread_mutex_unlock(&bnxt_ulp_global_mutex); 224313ac35aSVenkat Duvvuru return session; 225313ac35aSVenkat Duvvuru } 226313ac35aSVenkat Duvvuru 227313ac35aSVenkat Duvvuru /* 22870e64b27SVenkat Duvvuru * When a device is closed, remove it's associated session from the global 22970e64b27SVenkat Duvvuru * session list. 23070e64b27SVenkat Duvvuru */ 23170e64b27SVenkat Duvvuru static void 23270e64b27SVenkat Duvvuru ulp_session_deinit(struct bnxt_ulp_session_state *session) 23370e64b27SVenkat Duvvuru { 23470e64b27SVenkat Duvvuru if (!session) 23570e64b27SVenkat Duvvuru return; 23670e64b27SVenkat Duvvuru 23770e64b27SVenkat Duvvuru if (!session->cfg_data) { 23870e64b27SVenkat Duvvuru pthread_mutex_lock(&bnxt_ulp_global_mutex); 23970e64b27SVenkat Duvvuru STAILQ_REMOVE(&bnxt_ulp_session_list, session, 24070e64b27SVenkat Duvvuru bnxt_ulp_session_state, next); 24170e64b27SVenkat Duvvuru pthread_mutex_destroy(&session->bnxt_ulp_mutex); 24270e64b27SVenkat Duvvuru rte_free(session); 24370e64b27SVenkat Duvvuru pthread_mutex_unlock(&bnxt_ulp_global_mutex); 24470e64b27SVenkat Duvvuru } 24570e64b27SVenkat Duvvuru } 24670e64b27SVenkat Duvvuru 24709b23f8bSKishore Padmanabha /* Internal function to delete all the flows belonging to the given port */ 24809b23f8bSKishore Padmanabha static void 24909b23f8bSKishore Padmanabha bnxt_ulp_flush_port_flows(struct bnxt *bp) 25009b23f8bSKishore Padmanabha { 25109b23f8bSKishore Padmanabha uint16_t func_id; 25209b23f8bSKishore Padmanabha 253c53c2f43SKishore Padmanabha /* it is assumed that port is either TVF or PF */ 2540c036a14SPeter Spreadborough if (unlikely(ulp_port_db_port_func_id_get(bp->ulp_ctx, 255c53c2f43SKishore Padmanabha bp->eth_dev->data->port_id, 2560c036a14SPeter Spreadborough &func_id))) { 257dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid argument\n"); 258c53c2f43SKishore Padmanabha return; 259c53c2f43SKishore Padmanabha } 260c53c2f43SKishore Padmanabha (void)ulp_flow_db_function_flow_flush(bp->ulp_ctx, func_id); 26109b23f8bSKishore Padmanabha } 26209b23f8bSKishore Padmanabha 26309b23f8bSKishore Padmanabha /* Internal function to delete the VFR default flows */ 264dd0191d5SShuanglin Wang void 26509b23f8bSKishore Padmanabha bnxt_ulp_destroy_vfr_default_rules(struct bnxt *bp, bool global) 26609b23f8bSKishore Padmanabha { 26709b23f8bSKishore Padmanabha struct bnxt_ulp_vfr_rule_info *info; 268fac8177aSChenbo Xia uint16_t port_id; 26909b23f8bSKishore Padmanabha struct rte_eth_dev *vfr_eth_dev; 270ce9875d7SSomnath Kotur struct bnxt_representor *vfr_bp; 27109b23f8bSKishore Padmanabha 2720c036a14SPeter Spreadborough if (unlikely(!BNXT_TRUFLOW_EN(bp) || 2730c036a14SPeter Spreadborough BNXT_ETH_DEV_IS_REPRESENTOR(bp->eth_dev))) 27409b23f8bSKishore Padmanabha return; 27509b23f8bSKishore Padmanabha 2760c036a14SPeter Spreadborough if (unlikely(!bp->ulp_ctx || !bp->ulp_ctx->cfg_data)) 27709b23f8bSKishore Padmanabha return; 27809b23f8bSKishore Padmanabha 27909b23f8bSKishore Padmanabha /* Delete default rules for all ports */ 28009b23f8bSKishore Padmanabha for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) { 28109b23f8bSKishore Padmanabha info = &bp->ulp_ctx->cfg_data->vfr_rule_info[port_id]; 28209b23f8bSKishore Padmanabha if (!info->valid) 28309b23f8bSKishore Padmanabha continue; 28409b23f8bSKishore Padmanabha 28509b23f8bSKishore Padmanabha if (!global && info->parent_port_id != 28609b23f8bSKishore Padmanabha bp->eth_dev->data->port_id) 28709b23f8bSKishore Padmanabha continue; 28809b23f8bSKishore Padmanabha 28909b23f8bSKishore Padmanabha /* Destroy the flows */ 2903fe124d2SKishore Padmanabha ulp_default_flow_destroy(bp->eth_dev, info->vfr_flow_id); 29109b23f8bSKishore Padmanabha /* Clean up the tx action pointer */ 29209b23f8bSKishore Padmanabha vfr_eth_dev = &rte_eth_devices[port_id]; 29309b23f8bSKishore Padmanabha if (vfr_eth_dev) { 29409b23f8bSKishore Padmanabha vfr_bp = vfr_eth_dev->data->dev_private; 29509b23f8bSKishore Padmanabha vfr_bp->vfr_tx_cfa_action = 0; 29609b23f8bSKishore Padmanabha } 29709b23f8bSKishore Padmanabha memset(info, 0, sizeof(struct bnxt_ulp_vfr_rule_info)); 29809b23f8bSKishore Padmanabha } 29909b23f8bSKishore Padmanabha } 30009b23f8bSKishore Padmanabha 301dd0191d5SShuanglin Wang static int 3025c275d61SShahaji Bhosle ulp_l2_etype_tunnel_alloc(struct bnxt *bp) 3035c275d61SShahaji Bhosle { 3045c275d61SShahaji Bhosle int rc = 0; 3055c275d61SShahaji Bhosle 3065c275d61SShahaji Bhosle if (!ULP_APP_L2_ETYPE_SUPPORT(bp->ulp_ctx)) 3075c275d61SShahaji Bhosle return rc; 3085c275d61SShahaji Bhosle 3095c275d61SShahaji Bhosle if (bp->l2_etype_tunnel_cnt) { 310dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "L2 ETYPE Custom Tunnel already allocated\n"); 3110c036a14SPeter Spreadborough return rc; 3125c275d61SShahaji Bhosle } 3135c275d61SShahaji Bhosle rc = bnxt_tunnel_dst_port_alloc(bp, 3145c275d61SShahaji Bhosle BNXT_L2_ETYPE_TUNNEL_ID, 3155c275d61SShahaji Bhosle HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_L2_ETYPE); 3160c036a14SPeter Spreadborough if (unlikely(rc)) 317dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to set global L2 ETYPE Custom Tunnel\n"); 3185c275d61SShahaji Bhosle else 3195c275d61SShahaji Bhosle bp->l2_etype_tunnel_cnt++; 3205c275d61SShahaji Bhosle 3215c275d61SShahaji Bhosle return rc; 3225c275d61SShahaji Bhosle } 3235c275d61SShahaji Bhosle 324dd0191d5SShuanglin Wang static const struct bnxt_ulp_core_ops * 325dd0191d5SShuanglin Wang bnxt_ulp_port_func_ops_get(struct bnxt *bp) 3266d160d77SRandy Schacher { 327dd0191d5SShuanglin Wang int32_t rc; 328dd0191d5SShuanglin Wang enum bnxt_ulp_device_id dev_id; 329dd0191d5SShuanglin Wang const struct bnxt_ulp_core_ops *func_ops; 3306d160d77SRandy Schacher 331dd0191d5SShuanglin Wang rc = bnxt_ulp_devid_get(bp, &dev_id); 3320c036a14SPeter Spreadborough if (unlikely(rc)) 333dd0191d5SShuanglin Wang return NULL; 3346d160d77SRandy Schacher 335dd0191d5SShuanglin Wang switch (dev_id) { 336dd0191d5SShuanglin Wang case BNXT_ULP_DEVICE_ID_THOR2: 337dd0191d5SShuanglin Wang func_ops = &bnxt_ulp_tfc_core_ops; 338dd0191d5SShuanglin Wang break; 339dd0191d5SShuanglin Wang case BNXT_ULP_DEVICE_ID_THOR: 340dd0191d5SShuanglin Wang case BNXT_ULP_DEVICE_ID_STINGRAY: 341dd0191d5SShuanglin Wang case BNXT_ULP_DEVICE_ID_WH_PLUS: 342dd0191d5SShuanglin Wang func_ops = &bnxt_ulp_tf_core_ops; 343dd0191d5SShuanglin Wang break; 344dd0191d5SShuanglin Wang default: 345dd0191d5SShuanglin Wang func_ops = NULL; 346dd0191d5SShuanglin Wang break; 3476d160d77SRandy Schacher } 348dd0191d5SShuanglin Wang return func_ops; 3496d160d77SRandy Schacher } 3506d160d77SRandy Schacher 35109b23f8bSKishore Padmanabha /* 35209b23f8bSKishore Padmanabha * When a port is initialized by dpdk. This functions sets up 35309b23f8bSKishore Padmanabha * the port specific details. 35409b23f8bSKishore Padmanabha */ 35509b23f8bSKishore Padmanabha int32_t 35609b23f8bSKishore Padmanabha bnxt_ulp_port_init(struct bnxt *bp) 35709b23f8bSKishore Padmanabha { 35809b23f8bSKishore Padmanabha struct bnxt_ulp_session_state *session; 35909b23f8bSKishore Padmanabha bool initialized; 3601993b267SShahaji Bhosle uint32_t ulp_flags; 36109b23f8bSKishore Padmanabha int32_t rc = 0; 362dd0191d5SShuanglin Wang enum bnxt_ulp_device_id dev_id; 36309b23f8bSKishore Padmanabha 3646639a8b6SKishore Padmanabha if (!BNXT_TRUFLOW_EN(bp)) { 365dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, 3666639a8b6SKishore Padmanabha "Skip ulp init for port: %d, TF is not enabled\n", 36709b23f8bSKishore Padmanabha bp->eth_dev->data->port_id); 36809b23f8bSKishore Padmanabha return rc; 36909b23f8bSKishore Padmanabha } 37009b23f8bSKishore Padmanabha 3716639a8b6SKishore Padmanabha if (!BNXT_PF(bp) && !BNXT_VF_IS_TRUSTED(bp)) { 372dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, 3736639a8b6SKishore Padmanabha "Skip ulp init for port: %d, not a TVF or PF\n", 374f63aa27dSKishore Padmanabha bp->eth_dev->data->port_id); 375f63aa27dSKishore Padmanabha return rc; 376f63aa27dSKishore Padmanabha } 377f63aa27dSKishore Padmanabha 378dd0191d5SShuanglin Wang rc = bnxt_ulp_devid_get(bp, &dev_id); 3790c036a14SPeter Spreadborough if (unlikely(rc)) { 380dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "Unsupported device %x\n", rc); 381dd0191d5SShuanglin Wang return rc; 382dd0191d5SShuanglin Wang } 383dd0191d5SShuanglin Wang 3840c036a14SPeter Spreadborough if (unlikely(bp->ulp_ctx)) { 385dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "ulp ctx already allocated\n"); 38609b23f8bSKishore Padmanabha return rc; 38709b23f8bSKishore Padmanabha } 38809b23f8bSKishore Padmanabha 38909b23f8bSKishore Padmanabha bp->ulp_ctx = rte_zmalloc("bnxt_ulp_ctx", 39009b23f8bSKishore Padmanabha sizeof(struct bnxt_ulp_context), 0); 3910c036a14SPeter Spreadborough if (unlikely(!bp->ulp_ctx)) { 392dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to allocate ulp ctx\n"); 393313ac35aSVenkat Duvvuru return -ENOMEM; 394313ac35aSVenkat Duvvuru } 395313ac35aSVenkat Duvvuru 396dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_bp_set(bp->ulp_ctx, bp); 3970c036a14SPeter Spreadborough if (unlikely(rc)) { 398dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to set bp in ulp_ctx\n"); 399dd0191d5SShuanglin Wang rte_free(bp->ulp_ctx); 400dd0191d5SShuanglin Wang return -EIO; 401dd0191d5SShuanglin Wang } 402dd0191d5SShuanglin Wang 403dd0191d5SShuanglin Wang /* This shouldn't fail, unless we have a unknown device */ 404dd0191d5SShuanglin Wang bp->ulp_ctx->ops = bnxt_ulp_port_func_ops_get(bp); 4050c036a14SPeter Spreadborough if (unlikely(!bp->ulp_ctx->ops)) { 406dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to get ulp ops\n"); 407dd0191d5SShuanglin Wang rte_free(bp->ulp_ctx); 408dd0191d5SShuanglin Wang return -EIO; 409dd0191d5SShuanglin Wang } 410dd0191d5SShuanglin Wang 41109b23f8bSKishore Padmanabha /* 41209b23f8bSKishore Padmanabha * Multiple uplink ports can be associated with a single vswitch. 41309b23f8bSKishore Padmanabha * Make sure only the port that is started first will initialize 41409b23f8bSKishore Padmanabha * the TF session. 41509b23f8bSKishore Padmanabha */ 41609b23f8bSKishore Padmanabha session = ulp_session_init(bp, &initialized); 4170c036a14SPeter Spreadborough if (unlikely(!session)) { 418dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to initialize the tf session\n"); 41909b23f8bSKishore Padmanabha rc = -EIO; 42009b23f8bSKishore Padmanabha goto jump_to_error; 42109b23f8bSKishore Padmanabha } 42209b23f8bSKishore Padmanabha 42309b23f8bSKishore Padmanabha if (initialized) { 42409b23f8bSKishore Padmanabha /* 42509b23f8bSKishore Padmanabha * If ULP is already initialized for a specific domain then 42609b23f8bSKishore Padmanabha * simply assign the ulp context to this rte_eth_dev. 42709b23f8bSKishore Padmanabha */ 428dd0191d5SShuanglin Wang rc = bp->ulp_ctx->ops->ulp_ctx_attach(bp, session); 4290c036a14SPeter Spreadborough if (unlikely(rc)) { 430dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to attach the ulp context\n"); 431c6062ec0SMike Baucom goto jump_to_error; 432c6062ec0SMike Baucom } 43309b23f8bSKishore Padmanabha } else { 434dd0191d5SShuanglin Wang rc = bp->ulp_ctx->ops->ulp_init(bp, session); 4350c036a14SPeter Spreadborough if (unlikely(rc)) { 436dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to initialize the ulp init\n"); 43709b23f8bSKishore Padmanabha goto jump_to_error; 43809b23f8bSKishore Padmanabha } 43909b23f8bSKishore Padmanabha } 44009b23f8bSKishore Padmanabha 441032d49efSKishore Padmanabha /* setup the l2 etype tunnel for custom l2 encap/decap */ 442032d49efSKishore Padmanabha rc = ulp_l2_etype_tunnel_alloc(bp); 4430c036a14SPeter Spreadborough if (unlikely(rc)) 444032d49efSKishore Padmanabha goto jump_to_error; 445032d49efSKishore Padmanabha 446dd0191d5SShuanglin Wang 44709b23f8bSKishore Padmanabha /* Update bnxt driver flags */ 44809b23f8bSKishore Padmanabha rc = ulp_dparms_dev_port_intf_update(bp, bp->ulp_ctx); 4490c036a14SPeter Spreadborough if (unlikely(rc)) { 450dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to update driver flags\n"); 45109b23f8bSKishore Padmanabha goto jump_to_error; 45209b23f8bSKishore Padmanabha } 45309b23f8bSKishore Padmanabha 45409b23f8bSKishore Padmanabha /* update the port database for the given interface */ 455d9e70b1dSRandy Schacher rc = ulp_port_db_port_update(bp->ulp_ctx, bp->eth_dev); 4560c036a14SPeter Spreadborough if (unlikely(rc)) { 457dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to update port database\n"); 45809b23f8bSKishore Padmanabha goto jump_to_error; 45909b23f8bSKishore Padmanabha } 4606d160d77SRandy Schacher 46109b23f8bSKishore Padmanabha /* create the default rules */ 4623fe124d2SKishore Padmanabha rc = bnxt_ulp_create_df_rules(bp); 4630c036a14SPeter Spreadborough if (unlikely(rc)) { 464dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to create default flow\n"); 4651993b267SShahaji Bhosle goto jump_to_error; 4661993b267SShahaji Bhosle } 4671993b267SShahaji Bhosle 4681993b267SShahaji Bhosle /* set the unicast mode */ 4690c036a14SPeter Spreadborough if (unlikely(bnxt_ulp_cntxt_ptr2_ulp_flags_get(bp->ulp_ctx, &ulp_flags))) { 470dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Error in getting ULP context flags\n"); 4711993b267SShahaji Bhosle goto jump_to_error; 4721993b267SShahaji Bhosle } 4731993b267SShahaji Bhosle if (ulp_flags & BNXT_ULP_APP_UNICAST_ONLY) { 4740c036a14SPeter Spreadborough if (unlikely(bnxt_pmd_set_unicast_rxmask(bp->eth_dev))) { 475dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Error in setting unicast rxmode\n"); 4761993b267SShahaji Bhosle goto jump_to_error; 4771993b267SShahaji Bhosle } 4781993b267SShahaji Bhosle } 4791993b267SShahaji Bhosle 480dd0191d5SShuanglin Wang /* Make sure that custom header data is selected */ 481dd0191d5SShuanglin Wang if (dev_id > BNXT_ULP_DEVICE_ID_WH_PLUS) { 482dd0191d5SShuanglin Wang struct bnxt_vnic_info *vnic = bp->vnic_info; 483dd0191d5SShuanglin Wang vnic->metadata_format = HWRM_VNIC_UPDATE_INPUT_METADATA_FORMAT_TYPE_3; 484dd0191d5SShuanglin Wang rc = bnxt_hwrm_vnic_update(bp, 485dd0191d5SShuanglin Wang vnic, 486dd0191d5SShuanglin Wang HWRM_VNIC_UPDATE_INPUT_ENABLES_METADATA_FORMAT_TYPE_VALID); 4870c036a14SPeter Spreadborough if (unlikely(rc)) { 488dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to set metadata format\n"); 489dd0191d5SShuanglin Wang goto jump_to_error; 490dd0191d5SShuanglin Wang } 491dd0191d5SShuanglin Wang } 492dd0191d5SShuanglin Wang 4935c275d61SShahaji Bhosle rc = ulp_l2_etype_tunnel_alloc(bp); 4940c036a14SPeter Spreadborough if (unlikely(rc)) 4955c275d61SShahaji Bhosle goto jump_to_error; 4965c275d61SShahaji Bhosle 49709b23f8bSKishore Padmanabha return rc; 49809b23f8bSKishore Padmanabha 49909b23f8bSKishore Padmanabha jump_to_error: 50009b23f8bSKishore Padmanabha bnxt_ulp_port_deinit(bp); 50109b23f8bSKishore Padmanabha return rc; 50209b23f8bSKishore Padmanabha } 503313ac35aSVenkat Duvvuru 5046d160d77SRandy Schacher static void 5055c275d61SShahaji Bhosle ulp_l2_etype_tunnel_free(struct bnxt *bp) 5065c275d61SShahaji Bhosle { 5075c275d61SShahaji Bhosle int rc; 5085c275d61SShahaji Bhosle 5095c275d61SShahaji Bhosle if (!ULP_APP_L2_ETYPE_SUPPORT(bp->ulp_ctx)) 5105c275d61SShahaji Bhosle return; 5115c275d61SShahaji Bhosle 5120c036a14SPeter Spreadborough if (unlikely(bp->l2_etype_tunnel_cnt == 0)) { 513dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "L2 ETYPE Custom Tunnel already freed\n"); 5145c275d61SShahaji Bhosle return; 5155c275d61SShahaji Bhosle } 5165c275d61SShahaji Bhosle rc = bnxt_tunnel_dst_port_free(bp, 5175c275d61SShahaji Bhosle BNXT_L2_ETYPE_TUNNEL_ID, 5185c275d61SShahaji Bhosle HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_L2_ETYPE); 5190c036a14SPeter Spreadborough if (unlikely(rc)) 520dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to clear L2 ETYPE Custom Tunnel\n"); 5215c275d61SShahaji Bhosle 5225c275d61SShahaji Bhosle bp->l2_etype_tunnel_cnt--; 5235c275d61SShahaji Bhosle } 5245c275d61SShahaji Bhosle 52570e64b27SVenkat Duvvuru /* 52609b23f8bSKishore Padmanabha * When a port is de-initialized by dpdk. This functions clears up 52709b23f8bSKishore Padmanabha * the port specific details. 52870e64b27SVenkat Duvvuru */ 52970e64b27SVenkat Duvvuru void 53009b23f8bSKishore Padmanabha bnxt_ulp_port_deinit(struct bnxt *bp) 53170e64b27SVenkat Duvvuru { 53270e64b27SVenkat Duvvuru struct bnxt_ulp_session_state *session; 53370e64b27SVenkat Duvvuru struct rte_pci_device *pci_dev; 53470e64b27SVenkat Duvvuru struct rte_pci_addr *pci_addr; 53570e64b27SVenkat Duvvuru 5360c036a14SPeter Spreadborough if (unlikely(!BNXT_TRUFLOW_EN(bp))) { 537dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, 5386639a8b6SKishore Padmanabha "Skip ULP deinit for port:%d, TF is not enabled\n", 53909b23f8bSKishore Padmanabha bp->eth_dev->data->port_id); 54009b23f8bSKishore Padmanabha return; 54109b23f8bSKishore Padmanabha } 54209b23f8bSKishore Padmanabha 5430c036a14SPeter Spreadborough if (unlikely(!BNXT_PF(bp) && !BNXT_VF_IS_TRUSTED(bp))) { 544dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, 5456639a8b6SKishore Padmanabha "Skip ULP deinit port:%d, not a TVF or PF\n", 546f63aa27dSKishore Padmanabha bp->eth_dev->data->port_id); 547f63aa27dSKishore Padmanabha return; 548f63aa27dSKishore Padmanabha } 549f63aa27dSKishore Padmanabha 5500c036a14SPeter Spreadborough if (unlikely(!bp->ulp_ctx)) { 551dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "ulp ctx already de-allocated\n"); 55209b23f8bSKishore Padmanabha return; 55309b23f8bSKishore Padmanabha } 55409b23f8bSKishore Padmanabha 555dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "BNXT Port:%d ULP port deinit\n", 55609b23f8bSKishore Padmanabha bp->eth_dev->data->port_id); 55709b23f8bSKishore Padmanabha 55809b23f8bSKishore Padmanabha /* Get the session details */ 55970e64b27SVenkat Duvvuru pci_dev = RTE_DEV_TO_PCI(bp->eth_dev->device); 56070e64b27SVenkat Duvvuru pci_addr = &pci_dev->addr; 56170e64b27SVenkat Duvvuru pthread_mutex_lock(&bnxt_ulp_global_mutex); 56234a7ff5aSKishore Padmanabha session = ulp_get_session(bp, pci_addr); 56370e64b27SVenkat Duvvuru pthread_mutex_unlock(&bnxt_ulp_global_mutex); 56470e64b27SVenkat Duvvuru 56570e64b27SVenkat Duvvuru /* session not found then just exit */ 5660c036a14SPeter Spreadborough if (unlikely(!session)) { 56709b23f8bSKishore Padmanabha /* Free the ulp context */ 56809b23f8bSKishore Padmanabha rte_free(bp->ulp_ctx); 56909b23f8bSKishore Padmanabha bp->ulp_ctx = NULL; 57070e64b27SVenkat Duvvuru return; 57109b23f8bSKishore Padmanabha } 57270e64b27SVenkat Duvvuru 57309b23f8bSKishore Padmanabha /* Check the reference count to deinit or deattach*/ 57409b23f8bSKishore Padmanabha if (bp->ulp_ctx->cfg_data && bp->ulp_ctx->cfg_data->ref_cnt) { 57509b23f8bSKishore Padmanabha bp->ulp_ctx->cfg_data->ref_cnt--; 5762921498cSMike Baucom /* Free tunnels for each port */ 5775c275d61SShahaji Bhosle ulp_l2_etype_tunnel_free(bp); 5782921498cSMike Baucom if (bp->ulp_ctx->cfg_data->ref_cnt) { 579dd0191d5SShuanglin Wang /* Free the ulp context in the context entry list */ 580dd0191d5SShuanglin Wang bnxt_ulp_cntxt_list_del(bp->ulp_ctx); 581dd0191d5SShuanglin Wang 58209b23f8bSKishore Padmanabha /* free the port details */ 58309b23f8bSKishore Padmanabha /* Free the default flow rule associated to this port */ 58409b23f8bSKishore Padmanabha bnxt_ulp_destroy_df_rules(bp, false); 58509b23f8bSKishore Padmanabha bnxt_ulp_destroy_vfr_default_rules(bp, false); 586769de168SVenkat Duvvuru 58709b23f8bSKishore Padmanabha /* free flows associated with this port */ 58809b23f8bSKishore Padmanabha bnxt_ulp_flush_port_flows(bp); 589edc6ca0cSKishore Padmanabha 59009b23f8bSKishore Padmanabha /* close the session associated with this port */ 591dd0191d5SShuanglin Wang bp->ulp_ctx->ops->ulp_ctx_detach(bp, session); 59209b23f8bSKishore Padmanabha } else { 59367ad4000SKishore Padmanabha /* Free the ulp context in the context entry list */ 59467ad4000SKishore Padmanabha bnxt_ulp_cntxt_list_del(bp->ulp_ctx); 59567ad4000SKishore Padmanabha 596dd0191d5SShuanglin Wang /* clean up default flows */ 597dd0191d5SShuanglin Wang bnxt_ulp_destroy_df_rules(bp, true); 598dd0191d5SShuanglin Wang 599dd0191d5SShuanglin Wang /* clean up default VFR flows */ 600dd0191d5SShuanglin Wang bnxt_ulp_destroy_vfr_default_rules(bp, true); 601dd0191d5SShuanglin Wang 602dd0191d5SShuanglin Wang /* clean up regular flows */ 603dd0191d5SShuanglin Wang ulp_flow_db_flush_flows(bp->ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR); 604dd0191d5SShuanglin Wang 60509b23f8bSKishore Padmanabha /* Perform ulp ctx deinit */ 606dd0191d5SShuanglin Wang bp->ulp_ctx->ops->ulp_deinit(bp, session); 60709b23f8bSKishore Padmanabha } 60809b23f8bSKishore Padmanabha } 60970e64b27SVenkat Duvvuru 61009b23f8bSKishore Padmanabha /* clean up the session */ 61170e64b27SVenkat Duvvuru ulp_session_deinit(session); 61286015ee3SMike Baucom 61309b23f8bSKishore Padmanabha /* Free the ulp context */ 61486015ee3SMike Baucom rte_free(bp->ulp_ctx); 615b308d5a2SSomnath Kotur bp->ulp_ctx = NULL; 61670e64b27SVenkat Duvvuru } 61770e64b27SVenkat Duvvuru 618dd0191d5SShuanglin Wang int32_t 619d75b5512SKishore Padmanabha bnxt_ulp_cntxt_list_init(void) 620d75b5512SKishore Padmanabha { 621bf598786SKishore Padmanabha /* Create the cntxt spin lock only once*/ 622bf598786SKishore Padmanabha if (!bnxt_ulp_ctxt_lock_created) 623d75b5512SKishore Padmanabha rte_spinlock_init(&bnxt_ulp_ctxt_lock); 624bf598786SKishore Padmanabha bnxt_ulp_ctxt_lock_created = 1; 625d75b5512SKishore Padmanabha return 0; 626d75b5512SKishore Padmanabha } 627d75b5512SKishore Padmanabha 628dd0191d5SShuanglin Wang int32_t 629d75b5512SKishore Padmanabha bnxt_ulp_cntxt_list_add(struct bnxt_ulp_context *ulp_ctx) 630d75b5512SKishore Padmanabha { 631d75b5512SKishore Padmanabha struct ulp_context_list_entry *entry; 632d75b5512SKishore Padmanabha 633d75b5512SKishore Padmanabha entry = rte_zmalloc(NULL, sizeof(struct ulp_context_list_entry), 0); 6340c036a14SPeter Spreadborough if (unlikely(entry == NULL)) { 635dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "unable to allocate memory\n"); 636d75b5512SKishore Padmanabha return -ENOMEM; 637d75b5512SKishore Padmanabha } 638d75b5512SKishore Padmanabha 639d75b5512SKishore Padmanabha rte_spinlock_lock(&bnxt_ulp_ctxt_lock); 640d75b5512SKishore Padmanabha entry->ulp_ctx = ulp_ctx; 641d75b5512SKishore Padmanabha TAILQ_INSERT_TAIL(&ulp_cntx_list, entry, next); 642d75b5512SKishore Padmanabha rte_spinlock_unlock(&bnxt_ulp_ctxt_lock); 643d75b5512SKishore Padmanabha return 0; 644d75b5512SKishore Padmanabha } 645d75b5512SKishore Padmanabha 646dd0191d5SShuanglin Wang void 647d75b5512SKishore Padmanabha bnxt_ulp_cntxt_list_del(struct bnxt_ulp_context *ulp_ctx) 648d75b5512SKishore Padmanabha { 649d75b5512SKishore Padmanabha struct ulp_context_list_entry *entry, *temp; 650d75b5512SKishore Padmanabha 651d75b5512SKishore Padmanabha rte_spinlock_lock(&bnxt_ulp_ctxt_lock); 652f1f6ebc0SWilliam Tu RTE_TAILQ_FOREACH_SAFE(entry, &ulp_cntx_list, next, temp) { 653d75b5512SKishore Padmanabha if (entry->ulp_ctx == ulp_ctx) { 654d75b5512SKishore Padmanabha TAILQ_REMOVE(&ulp_cntx_list, entry, next); 655d75b5512SKishore Padmanabha rte_free(entry); 656d75b5512SKishore Padmanabha break; 657d75b5512SKishore Padmanabha } 658d75b5512SKishore Padmanabha } 659d75b5512SKishore Padmanabha rte_spinlock_unlock(&bnxt_ulp_ctxt_lock); 660d75b5512SKishore Padmanabha } 661d75b5512SKishore Padmanabha 66267ad4000SKishore Padmanabha int 66367ad4000SKishore Padmanabha bnxt_ulp_cntxt_list_count(void) 66467ad4000SKishore Padmanabha { 66567ad4000SKishore Padmanabha struct ulp_context_list_entry *entry, *temp; 66667ad4000SKishore Padmanabha int count_1 = 0; 66767ad4000SKishore Padmanabha 66867ad4000SKishore Padmanabha rte_spinlock_lock(&bnxt_ulp_ctxt_lock); 66967ad4000SKishore Padmanabha RTE_TAILQ_FOREACH_SAFE(entry, &ulp_cntx_list, next, temp) { 67067ad4000SKishore Padmanabha count_1++; 67167ad4000SKishore Padmanabha } 67267ad4000SKishore Padmanabha rte_spinlock_unlock(&bnxt_ulp_ctxt_lock); 67367ad4000SKishore Padmanabha return count_1; 67467ad4000SKishore Padmanabha } 67567ad4000SKishore Padmanabha 676d75b5512SKishore Padmanabha struct bnxt_ulp_context * 677bf598786SKishore Padmanabha bnxt_ulp_cntxt_entry_acquire(void *arg) 678d75b5512SKishore Padmanabha { 679d75b5512SKishore Padmanabha struct ulp_context_list_entry *entry; 680d75b5512SKishore Padmanabha 681d75b5512SKishore Padmanabha /* take a lock and get the first ulp context available */ 682d75b5512SKishore Padmanabha if (rte_spinlock_trylock(&bnxt_ulp_ctxt_lock)) { 68394dbd6cfSKishore Padmanabha TAILQ_FOREACH(entry, &ulp_cntx_list, next) { 684bf598786SKishore Padmanabha if (entry->ulp_ctx->cfg_data == arg) 685d75b5512SKishore Padmanabha return entry->ulp_ctx; 68694dbd6cfSKishore Padmanabha } 687ba6fa50aSKishore Padmanabha rte_spinlock_unlock(&bnxt_ulp_ctxt_lock); 688d75b5512SKishore Padmanabha } 689d75b5512SKishore Padmanabha return NULL; 690d75b5512SKishore Padmanabha } 691d75b5512SKishore Padmanabha 692d75b5512SKishore Padmanabha void 693d75b5512SKishore Padmanabha bnxt_ulp_cntxt_entry_release(void) 694d75b5512SKishore Padmanabha { 695d75b5512SKishore Padmanabha rte_spinlock_unlock(&bnxt_ulp_ctxt_lock); 696d75b5512SKishore Padmanabha } 697