xref: /dpdk/drivers/net/bnxt/tf_ulp/bnxt_ulp.c (revision 7d32c003ac175d7ac8669dc11684c75cc7eb56b8)
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