xref: /dpdk/drivers/net/bnxt/tf_ulp/ulp_fc_mgr.c (revision 7d32c003ac175d7ac8669dc11684c75cc7eb56b8)
19cf9c838SSomnath Kotur /* SPDX-License-Identifier: BSD-3-Clause
2d9e70b1dSRandy Schacher  * Copyright(c) 2014-2023 Broadcom
39cf9c838SSomnath Kotur  * All rights reserved.
49cf9c838SSomnath Kotur  */
59cf9c838SSomnath Kotur 
69cf9c838SSomnath Kotur #include <rte_common.h>
749b8d40bSSomnath Kotur #include <rte_cycles.h>
89cf9c838SSomnath Kotur #include <rte_malloc.h>
99cf9c838SSomnath Kotur #include <rte_log.h>
109cf9c838SSomnath Kotur #include <rte_alarm.h>
119cf9c838SSomnath Kotur #include "bnxt.h"
129cf9c838SSomnath Kotur #include "bnxt_ulp.h"
130c036a14SPeter Spreadborough #include "bnxt_ulp_utils.h"
14dd0191d5SShuanglin Wang #include "bnxt_ulp_tf.h"
159cf9c838SSomnath Kotur #include "bnxt_tf_common.h"
169cf9c838SSomnath Kotur #include "ulp_fc_mgr.h"
17306c2d28SSomnath Kotur #include "ulp_flow_db.h"
189cf9c838SSomnath Kotur #include "ulp_template_db_enum.h"
199cf9c838SSomnath Kotur #include "ulp_template_struct.h"
20dd0191d5SShuanglin Wang 
21dd0191d5SShuanglin Wang static const struct bnxt_ulp_fc_core_ops *
22dd0191d5SShuanglin Wang bnxt_ulp_fc_ops_get(struct bnxt_ulp_context *ctxt)
23dd0191d5SShuanglin Wang {
24dd0191d5SShuanglin Wang 	int32_t rc;
25dd0191d5SShuanglin Wang 	enum bnxt_ulp_device_id  dev_id;
26dd0191d5SShuanglin Wang 	const struct bnxt_ulp_fc_core_ops *func_ops;
27dd0191d5SShuanglin Wang 
28dd0191d5SShuanglin Wang 	rc = bnxt_ulp_cntxt_dev_id_get(ctxt, &dev_id);
29dd0191d5SShuanglin Wang 	if (rc)
30dd0191d5SShuanglin Wang 		return NULL;
31dd0191d5SShuanglin Wang 
32dd0191d5SShuanglin Wang 	switch (dev_id) {
33dd0191d5SShuanglin Wang 	case BNXT_ULP_DEVICE_ID_THOR2:
34dd0191d5SShuanglin Wang 		func_ops = &ulp_fc_tfc_core_ops;
35dd0191d5SShuanglin Wang 		break;
36dd0191d5SShuanglin Wang 	case BNXT_ULP_DEVICE_ID_THOR:
37dd0191d5SShuanglin Wang 	case BNXT_ULP_DEVICE_ID_STINGRAY:
38dd0191d5SShuanglin Wang 	case BNXT_ULP_DEVICE_ID_WH_PLUS:
39dd0191d5SShuanglin Wang 		func_ops = &ulp_fc_tf_core_ops;
40dd0191d5SShuanglin Wang 		break;
41dd0191d5SShuanglin Wang 	default:
42dd0191d5SShuanglin Wang 		func_ops = NULL;
43dd0191d5SShuanglin Wang 		break;
44dd0191d5SShuanglin Wang 	}
45dd0191d5SShuanglin Wang 	return func_ops;
46dd0191d5SShuanglin Wang }
479cf9c838SSomnath Kotur 
489cf9c838SSomnath Kotur static int
499cf9c838SSomnath Kotur ulp_fc_mgr_shadow_mem_alloc(struct hw_fc_mem_info *parms, int size)
509cf9c838SSomnath Kotur {
519cf9c838SSomnath Kotur 	/* Allocate memory*/
52640bfd23SKishore Padmanabha 	if (!parms)
539cf9c838SSomnath Kotur 		return -EINVAL;
549cf9c838SSomnath Kotur 
559cf9c838SSomnath Kotur 	parms->mem_va = rte_zmalloc("ulp_fc_info",
569cf9c838SSomnath Kotur 				    RTE_CACHE_LINE_ROUNDUP(size),
579cf9c838SSomnath Kotur 				    4096);
58640bfd23SKishore Padmanabha 	if (!parms->mem_va) {
59dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Allocate failed mem_va\n");
609cf9c838SSomnath Kotur 		return -ENOMEM;
619cf9c838SSomnath Kotur 	}
629cf9c838SSomnath Kotur 
639cf9c838SSomnath Kotur 	rte_mem_lock_page(parms->mem_va);
649cf9c838SSomnath Kotur 
659cf9c838SSomnath Kotur 	parms->mem_pa = (void *)(uintptr_t)rte_mem_virt2phy(parms->mem_va);
66ad9eed02SKishore Padmanabha 	if (parms->mem_pa == (void *)RTE_BAD_IOVA) {
67dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Allocate failed mem_pa\n");
689cf9c838SSomnath Kotur 		return -ENOMEM;
699cf9c838SSomnath Kotur 	}
709cf9c838SSomnath Kotur 
719cf9c838SSomnath Kotur 	return 0;
729cf9c838SSomnath Kotur }
739cf9c838SSomnath Kotur 
749cf9c838SSomnath Kotur static void
759cf9c838SSomnath Kotur ulp_fc_mgr_shadow_mem_free(struct hw_fc_mem_info *parms)
769cf9c838SSomnath Kotur {
779cf9c838SSomnath Kotur 	rte_free(parms->mem_va);
789cf9c838SSomnath Kotur }
799cf9c838SSomnath Kotur 
809cf9c838SSomnath Kotur /*
819cf9c838SSomnath Kotur  * Allocate and Initialize all Flow Counter Manager resources for this ulp
829cf9c838SSomnath Kotur  * context.
839cf9c838SSomnath Kotur  *
849cf9c838SSomnath Kotur  * ctxt [in] The ulp context for the Flow Counter manager.
859cf9c838SSomnath Kotur  *
869cf9c838SSomnath Kotur  */
879cf9c838SSomnath Kotur int32_t
889cf9c838SSomnath Kotur ulp_fc_mgr_init(struct bnxt_ulp_context *ctxt)
899cf9c838SSomnath Kotur {
909cf9c838SSomnath Kotur 	struct bnxt_ulp_device_params *dparms;
919cf9c838SSomnath Kotur 	uint32_t dev_id, sw_acc_cntr_tbl_sz, hw_fc_mem_info_sz;
929cf9c838SSomnath Kotur 	struct bnxt_ulp_fc_info *ulp_fc_info;
93dd0191d5SShuanglin Wang 	const struct bnxt_ulp_fc_core_ops *fc_ops;
9449cdf043SKishore Padmanabha 	uint32_t flags = 0;
959cf9c838SSomnath Kotur 	int i, rc;
969cf9c838SSomnath Kotur 
979cf9c838SSomnath Kotur 	if (!ctxt) {
98dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(DEBUG, "Invalid ULP CTXT\n");
999cf9c838SSomnath Kotur 		return -EINVAL;
1009cf9c838SSomnath Kotur 	}
1019cf9c838SSomnath Kotur 
1029cf9c838SSomnath Kotur 	if (bnxt_ulp_cntxt_dev_id_get(ctxt, &dev_id)) {
103dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(DEBUG, "Failed to get device id\n");
1049cf9c838SSomnath Kotur 		return -EINVAL;
1059cf9c838SSomnath Kotur 	}
1069cf9c838SSomnath Kotur 
1079cf9c838SSomnath Kotur 	dparms = bnxt_ulp_device_params_get(dev_id);
1089cf9c838SSomnath Kotur 	if (!dparms) {
109dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(DEBUG, "Failed to device parms\n");
110dd0191d5SShuanglin Wang 		return -EINVAL;
111dd0191d5SShuanglin Wang 	}
112dd0191d5SShuanglin Wang 
11349cdf043SKishore Padmanabha 	/* update the features list */
11449cdf043SKishore Padmanabha 	if (dparms->dev_features & BNXT_ULP_DEV_FT_STAT_SW_AGG)
11549cdf043SKishore Padmanabha 		flags = ULP_FLAG_FC_SW_AGG_EN;
11649cdf043SKishore Padmanabha 	if (dparms->dev_features & BNXT_ULP_DEV_FT_STAT_PARENT_AGG)
11749cdf043SKishore Padmanabha 		flags |= ULP_FLAG_FC_PARENT_AGG_EN;
11849cdf043SKishore Padmanabha 
119dd0191d5SShuanglin Wang 	fc_ops = bnxt_ulp_fc_ops_get(ctxt);
120dd0191d5SShuanglin Wang 	if (fc_ops == NULL) {
121dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(DEBUG, "Failed to get the counter ops\n");
1229cf9c838SSomnath Kotur 		return -EINVAL;
1239cf9c838SSomnath Kotur 	}
1249cf9c838SSomnath Kotur 
1259cf9c838SSomnath Kotur 	ulp_fc_info = rte_zmalloc("ulp_fc_info", sizeof(*ulp_fc_info), 0);
1269cf9c838SSomnath Kotur 	if (!ulp_fc_info)
1279cf9c838SSomnath Kotur 		goto error;
1289cf9c838SSomnath Kotur 
129dd0191d5SShuanglin Wang 	ulp_fc_info->fc_ops = fc_ops;
13049cdf043SKishore Padmanabha 	ulp_fc_info->flags = flags;
131dd0191d5SShuanglin Wang 
132*7d32c003SAriel Otilibili 	pthread_mutex_init(&ulp_fc_info->fc_lock, NULL);
1339cf9c838SSomnath Kotur 
1349cf9c838SSomnath Kotur 	/* Add the FC info tbl to the ulp context. */
1359cf9c838SSomnath Kotur 	bnxt_ulp_cntxt_ptr2_fc_info_set(ctxt, ulp_fc_info);
1369cf9c838SSomnath Kotur 
1371993b267SShahaji Bhosle 	ulp_fc_info->num_counters = dparms->flow_count_db_entries;
1381993b267SShahaji Bhosle 	if (!ulp_fc_info->num_counters) {
1391993b267SShahaji Bhosle 		/* No need for software counters, call fw directly */
140dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(DEBUG, "Sw flow counter support not enabled\n");
1411993b267SShahaji Bhosle 		return 0;
1421993b267SShahaji Bhosle 	}
1431993b267SShahaji Bhosle 
14449cdf043SKishore Padmanabha 	/* no need to allocate sw aggregation memory if agg is disabled */
14549cdf043SKishore Padmanabha 	if (!(ulp_fc_info->flags & ULP_FLAG_FC_SW_AGG_EN))
14649cdf043SKishore Padmanabha 		return 0;
14749cdf043SKishore Padmanabha 
1489cf9c838SSomnath Kotur 	sw_acc_cntr_tbl_sz = sizeof(struct sw_acc_counter) *
1499cf9c838SSomnath Kotur 				dparms->flow_count_db_entries;
1509cf9c838SSomnath Kotur 
1519cf9c838SSomnath Kotur 	for (i = 0; i < TF_DIR_MAX; i++) {
1529cf9c838SSomnath Kotur 		ulp_fc_info->sw_acc_tbl[i] = rte_zmalloc("ulp_sw_acc_cntr_tbl",
1539cf9c838SSomnath Kotur 							 sw_acc_cntr_tbl_sz, 0);
1549cf9c838SSomnath Kotur 		if (!ulp_fc_info->sw_acc_tbl[i])
1559cf9c838SSomnath Kotur 			goto error;
1569cf9c838SSomnath Kotur 	}
1579cf9c838SSomnath Kotur 
1589cf9c838SSomnath Kotur 	hw_fc_mem_info_sz = sizeof(uint64_t) * dparms->flow_count_db_entries;
1599cf9c838SSomnath Kotur 
1609cf9c838SSomnath Kotur 	for (i = 0; i < TF_DIR_MAX; i++) {
1619cf9c838SSomnath Kotur 		rc = ulp_fc_mgr_shadow_mem_alloc(&ulp_fc_info->shadow_hw_tbl[i],
1629cf9c838SSomnath Kotur 						 hw_fc_mem_info_sz);
1639cf9c838SSomnath Kotur 		if (rc)
1649cf9c838SSomnath Kotur 			goto error;
1659cf9c838SSomnath Kotur 	}
1669cf9c838SSomnath Kotur 
1679cf9c838SSomnath Kotur 	return 0;
1689cf9c838SSomnath Kotur 
1699cf9c838SSomnath Kotur error:
1709cf9c838SSomnath Kotur 	ulp_fc_mgr_deinit(ctxt);
171dd0191d5SShuanglin Wang 	BNXT_DRV_DBG(DEBUG, "Failed to allocate memory for fc mgr\n");
1729cf9c838SSomnath Kotur 
1739cf9c838SSomnath Kotur 	return -ENOMEM;
1749cf9c838SSomnath Kotur }
1759cf9c838SSomnath Kotur 
1769cf9c838SSomnath Kotur /*
1779cf9c838SSomnath Kotur  * Release all resources in the Flow Counter Manager for this ulp context
1789cf9c838SSomnath Kotur  *
1799cf9c838SSomnath Kotur  * ctxt [in] The ulp context for the Flow Counter manager
1809cf9c838SSomnath Kotur  *
1819cf9c838SSomnath Kotur  */
1829cf9c838SSomnath Kotur int32_t
1839cf9c838SSomnath Kotur ulp_fc_mgr_deinit(struct bnxt_ulp_context *ctxt)
1849cf9c838SSomnath Kotur {
1859cf9c838SSomnath Kotur 	struct bnxt_ulp_fc_info *ulp_fc_info;
1861993b267SShahaji Bhosle 	struct hw_fc_mem_info *shd_info;
1879cf9c838SSomnath Kotur 	int i;
1889cf9c838SSomnath Kotur 
1899cf9c838SSomnath Kotur 	ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ctxt);
1909cf9c838SSomnath Kotur 
1919cf9c838SSomnath Kotur 	if (!ulp_fc_info)
1929cf9c838SSomnath Kotur 		return -EINVAL;
1939cf9c838SSomnath Kotur 
19449cdf043SKishore Padmanabha 	if (ulp_fc_info->flags & ULP_FLAG_FC_SW_AGG_EN)
1959cf9c838SSomnath Kotur 		ulp_fc_mgr_thread_cancel(ctxt);
1969cf9c838SSomnath Kotur 
1979cf9c838SSomnath Kotur 	pthread_mutex_destroy(&ulp_fc_info->fc_lock);
1989cf9c838SSomnath Kotur 
19949cdf043SKishore Padmanabha 	if (ulp_fc_info->flags & ULP_FLAG_FC_SW_AGG_EN) {
2009cf9c838SSomnath Kotur 		for (i = 0; i < TF_DIR_MAX; i++)
2019cf9c838SSomnath Kotur 			rte_free(ulp_fc_info->sw_acc_tbl[i]);
2029cf9c838SSomnath Kotur 
2031993b267SShahaji Bhosle 		for (i = 0; i < TF_DIR_MAX; i++) {
2041993b267SShahaji Bhosle 			shd_info = &ulp_fc_info->shadow_hw_tbl[i];
2051993b267SShahaji Bhosle 			ulp_fc_mgr_shadow_mem_free(shd_info);
2061993b267SShahaji Bhosle 		}
2071993b267SShahaji Bhosle 	}
2089cf9c838SSomnath Kotur 
2099cf9c838SSomnath Kotur 	rte_free(ulp_fc_info);
2109cf9c838SSomnath Kotur 
2119cf9c838SSomnath Kotur 	/* Safe to ignore on deinit */
2129cf9c838SSomnath Kotur 	(void)bnxt_ulp_cntxt_ptr2_fc_info_set(ctxt, NULL);
2139cf9c838SSomnath Kotur 
2149cf9c838SSomnath Kotur 	return 0;
2159cf9c838SSomnath Kotur }
2169cf9c838SSomnath Kotur 
2179cf9c838SSomnath Kotur /*
2189cf9c838SSomnath Kotur  * Check if the alarm thread that walks through the flows is started
2199cf9c838SSomnath Kotur  *
2209cf9c838SSomnath Kotur  * ctxt [in] The ulp context for the flow counter manager
2219cf9c838SSomnath Kotur  *
2229cf9c838SSomnath Kotur  */
2239cf9c838SSomnath Kotur bool ulp_fc_mgr_thread_isstarted(struct bnxt_ulp_context *ctxt)
2249cf9c838SSomnath Kotur {
2259cf9c838SSomnath Kotur 	struct bnxt_ulp_fc_info *ulp_fc_info;
2269cf9c838SSomnath Kotur 
2279cf9c838SSomnath Kotur 	ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ctxt);
2289cf9c838SSomnath Kotur 
2293fe124d2SKishore Padmanabha 	if (ulp_fc_info)
2309cf9c838SSomnath Kotur 		return !!(ulp_fc_info->flags & ULP_FLAG_FC_THREAD);
2313fe124d2SKishore Padmanabha 
2323fe124d2SKishore Padmanabha 	return false;
2339cf9c838SSomnath Kotur }
2349cf9c838SSomnath Kotur 
2359cf9c838SSomnath Kotur /*
2369cf9c838SSomnath Kotur  * Setup the Flow counter timer thread that will fetch/accumulate raw counter
2379cf9c838SSomnath Kotur  * data from the chip's internal flow counters
2389cf9c838SSomnath Kotur  *
2399cf9c838SSomnath Kotur  * ctxt [in] The ulp context for the flow counter manager
2409cf9c838SSomnath Kotur  *
2419cf9c838SSomnath Kotur  */
2429cf9c838SSomnath Kotur int32_t
2439cf9c838SSomnath Kotur ulp_fc_mgr_thread_start(struct bnxt_ulp_context *ctxt)
2449cf9c838SSomnath Kotur {
2459cf9c838SSomnath Kotur 	struct bnxt_ulp_fc_info *ulp_fc_info;
2469cf9c838SSomnath Kotur 
2479cf9c838SSomnath Kotur 	ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ctxt);
2489cf9c838SSomnath Kotur 
2493fe124d2SKishore Padmanabha 	if (ulp_fc_info && !(ulp_fc_info->flags & ULP_FLAG_FC_THREAD)) {
2509cf9c838SSomnath Kotur 		rte_eal_alarm_set(US_PER_S * ULP_FC_TIMER,
251bf598786SKishore Padmanabha 				  ulp_fc_mgr_alarm_cb, (void *)ctxt->cfg_data);
2529cf9c838SSomnath Kotur 		ulp_fc_info->flags |= ULP_FLAG_FC_THREAD;
2539cf9c838SSomnath Kotur 	}
2549cf9c838SSomnath Kotur 
2559cf9c838SSomnath Kotur 	return 0;
2569cf9c838SSomnath Kotur }
2579cf9c838SSomnath Kotur 
2589cf9c838SSomnath Kotur /*
2599cf9c838SSomnath Kotur  * Cancel the alarm handler
2609cf9c838SSomnath Kotur  *
2619cf9c838SSomnath Kotur  * ctxt [in] The ulp context for the flow counter manager
2629cf9c838SSomnath Kotur  *
2639cf9c838SSomnath Kotur  */
2649cf9c838SSomnath Kotur void ulp_fc_mgr_thread_cancel(struct bnxt_ulp_context *ctxt)
2659cf9c838SSomnath Kotur {
2669cf9c838SSomnath Kotur 	struct bnxt_ulp_fc_info *ulp_fc_info;
2679cf9c838SSomnath Kotur 
2689cf9c838SSomnath Kotur 	ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ctxt);
2699cf9c838SSomnath Kotur 	if (!ulp_fc_info)
2709cf9c838SSomnath Kotur 		return;
2719cf9c838SSomnath Kotur 
2729cf9c838SSomnath Kotur 	ulp_fc_info->flags &= ~ULP_FLAG_FC_THREAD;
273bf598786SKishore Padmanabha 	rte_eal_alarm_cancel(ulp_fc_mgr_alarm_cb, ctxt->cfg_data);
2749cf9c838SSomnath Kotur }
2759cf9c838SSomnath Kotur 
2769cf9c838SSomnath Kotur /*
2779cf9c838SSomnath Kotur  * Alarm handler that will issue the TF-Core API to fetch
2789cf9c838SSomnath Kotur  * data from the chip's internal flow counters
2799cf9c838SSomnath Kotur  *
2809cf9c838SSomnath Kotur  * ctxt [in] The ulp context for the flow counter manager
2819cf9c838SSomnath Kotur  *
2829cf9c838SSomnath Kotur  */
283306c2d28SSomnath Kotur 
2849cf9c838SSomnath Kotur void
285bf598786SKishore Padmanabha ulp_fc_mgr_alarm_cb(void *arg)
2869cf9c838SSomnath Kotur {
287dd0191d5SShuanglin Wang 	const struct bnxt_ulp_fc_core_ops *fc_ops;
2889cf9c838SSomnath Kotur 	struct bnxt_ulp_device_params *dparms;
289dd0191d5SShuanglin Wang 	struct bnxt_ulp_fc_info *ulp_fc_info;
290dd0191d5SShuanglin Wang 	struct bnxt_ulp_context *ctxt;
291dd0191d5SShuanglin Wang 	uint32_t dev_id;
292dd0191d5SShuanglin Wang 	int rc = 0;
2939cf9c838SSomnath Kotur 
294bf598786SKishore Padmanabha 	ctxt = bnxt_ulp_cntxt_entry_acquire(arg);
295d75b5512SKishore Padmanabha 	if (ctxt == NULL) {
296dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(INFO, "could not get the ulp context lock\n");
297d75b5512SKishore Padmanabha 		rte_eal_alarm_set(US_PER_S * ULP_FC_TIMER,
298bf598786SKishore Padmanabha 				  ulp_fc_mgr_alarm_cb, arg);
2999cf9c838SSomnath Kotur 		return;
300d75b5512SKishore Padmanabha 	}
301d75b5512SKishore Padmanabha 
302d75b5512SKishore Padmanabha 	ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ctxt);
303d75b5512SKishore Padmanabha 	if (!ulp_fc_info) {
304d75b5512SKishore Padmanabha 		bnxt_ulp_cntxt_entry_release();
305d75b5512SKishore Padmanabha 		return;
306d75b5512SKishore Padmanabha 	}
3079cf9c838SSomnath Kotur 
308dd0191d5SShuanglin Wang 	fc_ops = ulp_fc_info->fc_ops;
309dd0191d5SShuanglin Wang 
3109cf9c838SSomnath Kotur 	if (bnxt_ulp_cntxt_dev_id_get(ctxt, &dev_id)) {
311dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(DEBUG, "Failed to get device id\n");
312d75b5512SKishore Padmanabha 		bnxt_ulp_cntxt_entry_release();
3139cf9c838SSomnath Kotur 		return;
3149cf9c838SSomnath Kotur 	}
3159cf9c838SSomnath Kotur 
3169cf9c838SSomnath Kotur 	dparms = bnxt_ulp_device_params_get(dev_id);
3179cf9c838SSomnath Kotur 	if (!dparms) {
318dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(DEBUG, "Failed to device parms\n");
319d75b5512SKishore Padmanabha 		bnxt_ulp_cntxt_entry_release();
3209cf9c838SSomnath Kotur 		return;
3219cf9c838SSomnath Kotur 	}
3229cf9c838SSomnath Kotur 
3239cf9c838SSomnath Kotur 	/*
3249cf9c838SSomnath Kotur 	 * Take the fc_lock to ensure no flow is destroyed
3259cf9c838SSomnath Kotur 	 * during the bulk get
3269cf9c838SSomnath Kotur 	 */
3279cf9c838SSomnath Kotur 	if (pthread_mutex_trylock(&ulp_fc_info->fc_lock))
3289cf9c838SSomnath Kotur 		goto out;
3299cf9c838SSomnath Kotur 
3309cf9c838SSomnath Kotur 	if (!ulp_fc_info->num_entries) {
3319cf9c838SSomnath Kotur 		pthread_mutex_unlock(&ulp_fc_info->fc_lock);
3329cf9c838SSomnath Kotur 		ulp_fc_mgr_thread_cancel(ctxt);
333d75b5512SKishore Padmanabha 		bnxt_ulp_cntxt_entry_release();
3349cf9c838SSomnath Kotur 		return;
3359cf9c838SSomnath Kotur 	}
336306c2d28SSomnath Kotur 	/*
337306c2d28SSomnath Kotur 	 * Commented for now till GET_BULK is resolved, just get the first flow
338306c2d28SSomnath Kotur 	 * stat for now
3399cf9c838SSomnath Kotur 	 for (i = 0; i < TF_DIR_MAX; i++) {
3409cf9c838SSomnath Kotur 		rc = ulp_bulk_get_flow_stats(tfp, ulp_fc_info, i,
3419cf9c838SSomnath Kotur 					     dparms->flow_count_db_entries);
3429cf9c838SSomnath Kotur 		if (rc)
3439cf9c838SSomnath Kotur 			break;
3449cf9c838SSomnath Kotur 	}
345306c2d28SSomnath Kotur 	*/
346640bfd23SKishore Padmanabha 
347640bfd23SKishore Padmanabha 	/* reset the parent accumulation counters before accumulation if any */
348640bfd23SKishore Padmanabha 	ulp_flow_db_parent_flow_count_reset(ctxt);
349640bfd23SKishore Padmanabha 
350dd0191d5SShuanglin Wang 	rc = fc_ops->ulp_flow_stats_accum_update(ctxt, ulp_fc_info, dparms);
3519cf9c838SSomnath Kotur 
3529cf9c838SSomnath Kotur 	pthread_mutex_unlock(&ulp_fc_info->fc_lock);
3539cf9c838SSomnath Kotur 
3549cf9c838SSomnath Kotur 	/*
3559cf9c838SSomnath Kotur 	 * If cmd fails once, no need of
3569cf9c838SSomnath Kotur 	 * invoking again every second
3579cf9c838SSomnath Kotur 	 */
3589cf9c838SSomnath Kotur 
3599cf9c838SSomnath Kotur 	if (rc) {
3609cf9c838SSomnath Kotur 		ulp_fc_mgr_thread_cancel(ctxt);
361d75b5512SKishore Padmanabha 		bnxt_ulp_cntxt_entry_release();
3629cf9c838SSomnath Kotur 		return;
3639cf9c838SSomnath Kotur 	}
3649cf9c838SSomnath Kotur out:
365d75b5512SKishore Padmanabha 	bnxt_ulp_cntxt_entry_release();
3669cf9c838SSomnath Kotur 	rte_eal_alarm_set(US_PER_S * ULP_FC_TIMER,
367bf598786SKishore Padmanabha 			  ulp_fc_mgr_alarm_cb, arg);
3689cf9c838SSomnath Kotur }
3699cf9c838SSomnath Kotur 
3709cf9c838SSomnath Kotur /*
3719cf9c838SSomnath Kotur  * Set the starting index that indicates the first HW flow
3729cf9c838SSomnath Kotur  * counter ID
3739cf9c838SSomnath Kotur  *
3749cf9c838SSomnath Kotur  * ctxt [in] The ulp context for the flow counter manager
3759cf9c838SSomnath Kotur  *
3769cf9c838SSomnath Kotur  * dir [in] The direction of the flow
3779cf9c838SSomnath Kotur  *
3789cf9c838SSomnath Kotur  * start_idx [in] The HW flow counter ID
3799cf9c838SSomnath Kotur  *
3809cf9c838SSomnath Kotur  */
381dd0191d5SShuanglin Wang bool ulp_fc_mgr_start_idx_isset(struct bnxt_ulp_context *ctxt, uint8_t dir)
3829cf9c838SSomnath Kotur {
3839cf9c838SSomnath Kotur 	struct bnxt_ulp_fc_info *ulp_fc_info;
3849cf9c838SSomnath Kotur 
3859cf9c838SSomnath Kotur 	ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ctxt);
3869cf9c838SSomnath Kotur 
3873fe124d2SKishore Padmanabha 	if (ulp_fc_info)
388811229d4SSomnath Kotur 		return ulp_fc_info->shadow_hw_tbl[dir].start_idx_is_set;
3893fe124d2SKishore Padmanabha 
3903fe124d2SKishore Padmanabha 	return false;
3919cf9c838SSomnath Kotur }
3929cf9c838SSomnath Kotur 
3939cf9c838SSomnath Kotur /*
3949cf9c838SSomnath Kotur  * Set the starting index that indicates the first HW flow
3959cf9c838SSomnath Kotur  * counter ID
3969cf9c838SSomnath Kotur  *
3979cf9c838SSomnath Kotur  * ctxt [in] The ulp context for the flow counter manager
3989cf9c838SSomnath Kotur  *
3999cf9c838SSomnath Kotur  * dir [in] The direction of the flow
4009cf9c838SSomnath Kotur  *
4019cf9c838SSomnath Kotur  * start_idx [in] The HW flow counter ID
4029cf9c838SSomnath Kotur  *
4039cf9c838SSomnath Kotur  */
404dd0191d5SShuanglin Wang int32_t ulp_fc_mgr_start_idx_set(struct bnxt_ulp_context *ctxt, uint8_t dir,
4059cf9c838SSomnath Kotur 				 uint32_t start_idx)
4069cf9c838SSomnath Kotur {
4079cf9c838SSomnath Kotur 	struct bnxt_ulp_fc_info *ulp_fc_info;
4089cf9c838SSomnath Kotur 
4099cf9c838SSomnath Kotur 	ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ctxt);
4109cf9c838SSomnath Kotur 
4119cf9c838SSomnath Kotur 	if (!ulp_fc_info)
4129cf9c838SSomnath Kotur 		return -EIO;
4139cf9c838SSomnath Kotur 
414811229d4SSomnath Kotur 	if (!ulp_fc_info->shadow_hw_tbl[dir].start_idx_is_set) {
4159cf9c838SSomnath Kotur 		ulp_fc_info->shadow_hw_tbl[dir].start_idx = start_idx;
416811229d4SSomnath Kotur 		ulp_fc_info->shadow_hw_tbl[dir].start_idx_is_set = true;
417811229d4SSomnath Kotur 	}
4189cf9c838SSomnath Kotur 
4199cf9c838SSomnath Kotur 	return 0;
4209cf9c838SSomnath Kotur }
4219cf9c838SSomnath Kotur 
4229cf9c838SSomnath Kotur /*
4239cf9c838SSomnath Kotur  * Set the corresponding SW accumulator table entry based on
4249cf9c838SSomnath Kotur  * the difference between this counter ID and the starting
4259cf9c838SSomnath Kotur  * counter ID. Also, keep track of num of active counter enabled
4269cf9c838SSomnath Kotur  * flows.
4279cf9c838SSomnath Kotur  *
4289cf9c838SSomnath Kotur  * ctxt [in] The ulp context for the flow counter manager
4299cf9c838SSomnath Kotur  *
4309cf9c838SSomnath Kotur  * dir [in] The direction of the flow
4319cf9c838SSomnath Kotur  *
4329cf9c838SSomnath Kotur  * hw_cntr_id [in] The HW flow counter ID
4339cf9c838SSomnath Kotur  *
4349cf9c838SSomnath Kotur  */
4359cf9c838SSomnath Kotur int32_t ulp_fc_mgr_cntr_set(struct bnxt_ulp_context *ctxt, enum tf_dir dir,
436d9e70b1dSRandy Schacher 			    uint32_t hw_cntr_id,
437d9e70b1dSRandy Schacher 			    enum bnxt_ulp_session_type session_type)
4389cf9c838SSomnath Kotur {
4399cf9c838SSomnath Kotur 	struct bnxt_ulp_fc_info *ulp_fc_info;
4409cf9c838SSomnath Kotur 	uint32_t sw_cntr_idx;
4419cf9c838SSomnath Kotur 
4429cf9c838SSomnath Kotur 	ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ctxt);
4439cf9c838SSomnath Kotur 	if (!ulp_fc_info)
4449cf9c838SSomnath Kotur 		return -EIO;
4459cf9c838SSomnath Kotur 
4461993b267SShahaji Bhosle 	if (!ulp_fc_info->num_counters)
4471993b267SShahaji Bhosle 		return 0;
4481993b267SShahaji Bhosle 
4499cf9c838SSomnath Kotur 	pthread_mutex_lock(&ulp_fc_info->fc_lock);
4509cf9c838SSomnath Kotur 	sw_cntr_idx = hw_cntr_id - ulp_fc_info->shadow_hw_tbl[dir].start_idx;
4519cf9c838SSomnath Kotur 	ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].valid = true;
452306c2d28SSomnath Kotur 	ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].hw_cntr_id = hw_cntr_id;
453d9e70b1dSRandy Schacher 	ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].session_type = session_type;
4549cf9c838SSomnath Kotur 	ulp_fc_info->num_entries++;
4559cf9c838SSomnath Kotur 	pthread_mutex_unlock(&ulp_fc_info->fc_lock);
4569cf9c838SSomnath Kotur 
4579cf9c838SSomnath Kotur 	return 0;
4589cf9c838SSomnath Kotur }
4599cf9c838SSomnath Kotur 
4609cf9c838SSomnath Kotur /*
4619cf9c838SSomnath Kotur  * Reset the corresponding SW accumulator table entry based on
4629cf9c838SSomnath Kotur  * the difference between this counter ID and the starting
4639cf9c838SSomnath Kotur  * counter ID.
4649cf9c838SSomnath Kotur  *
4659cf9c838SSomnath Kotur  * ctxt [in] The ulp context for the flow counter manager
4669cf9c838SSomnath Kotur  *
4679cf9c838SSomnath Kotur  * dir [in] The direction of the flow
4689cf9c838SSomnath Kotur  *
4699cf9c838SSomnath Kotur  * hw_cntr_id [in] The HW flow counter ID
4709cf9c838SSomnath Kotur  *
4719cf9c838SSomnath Kotur  */
472dd0191d5SShuanglin Wang int32_t ulp_fc_mgr_cntr_reset(struct bnxt_ulp_context *ctxt, uint8_t dir,
4739cf9c838SSomnath Kotur 			      uint32_t hw_cntr_id)
4749cf9c838SSomnath Kotur {
4759cf9c838SSomnath Kotur 	struct bnxt_ulp_fc_info *ulp_fc_info;
4769cf9c838SSomnath Kotur 	uint32_t sw_cntr_idx;
4779cf9c838SSomnath Kotur 
4789cf9c838SSomnath Kotur 	ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ctxt);
4799cf9c838SSomnath Kotur 	if (!ulp_fc_info)
4809cf9c838SSomnath Kotur 		return -EIO;
4819cf9c838SSomnath Kotur 
4821993b267SShahaji Bhosle 	if (!ulp_fc_info->num_counters)
4831993b267SShahaji Bhosle 		return 0;
4841993b267SShahaji Bhosle 
4859cf9c838SSomnath Kotur 	pthread_mutex_lock(&ulp_fc_info->fc_lock);
4869cf9c838SSomnath Kotur 	sw_cntr_idx = hw_cntr_id - ulp_fc_info->shadow_hw_tbl[dir].start_idx;
4879cf9c838SSomnath Kotur 	ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].valid = false;
488306c2d28SSomnath Kotur 	ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].hw_cntr_id = 0;
4896d160d77SRandy Schacher 	ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].session_type = 0;
4909cf9c838SSomnath Kotur 	ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].pkt_count = 0;
4919cf9c838SSomnath Kotur 	ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].byte_count = 0;
492bdf4a3c6SKishore Padmanabha 	ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].pc_flow_idx = 0;
4939cf9c838SSomnath Kotur 	ulp_fc_info->num_entries--;
4949cf9c838SSomnath Kotur 	pthread_mutex_unlock(&ulp_fc_info->fc_lock);
4959cf9c838SSomnath Kotur 
4969cf9c838SSomnath Kotur 	return 0;
4979cf9c838SSomnath Kotur }
498306c2d28SSomnath Kotur 
499306c2d28SSomnath Kotur /*
500306c2d28SSomnath Kotur  * Fill the rte_flow_query_count 'data' argument passed
501306c2d28SSomnath Kotur  * in the rte_flow_query() with the values obtained and
502306c2d28SSomnath Kotur  * accumulated locally.
503306c2d28SSomnath Kotur  *
504306c2d28SSomnath Kotur  * ctxt [in] The ulp context for the flow counter manager
505306c2d28SSomnath Kotur  *
506306c2d28SSomnath Kotur  * flow_id [in] The HW flow ID
507306c2d28SSomnath Kotur  *
508306c2d28SSomnath Kotur  * count [out] The rte_flow_query_count 'data' that is set
509306c2d28SSomnath Kotur  *
510306c2d28SSomnath Kotur  */
511306c2d28SSomnath Kotur int ulp_fc_mgr_query_count_get(struct bnxt_ulp_context *ctxt,
512306c2d28SSomnath Kotur 			       uint32_t flow_id,
513306c2d28SSomnath Kotur 			       struct rte_flow_query_count *count)
514306c2d28SSomnath Kotur {
515306c2d28SSomnath Kotur 	int rc = 0;
516306c2d28SSomnath Kotur 	uint32_t nxt_resource_index = 0;
517306c2d28SSomnath Kotur 	struct bnxt_ulp_fc_info *ulp_fc_info;
518dd0191d5SShuanglin Wang 	const struct bnxt_ulp_fc_core_ops *fc_ops;
519306c2d28SSomnath Kotur 	struct ulp_flow_db_res_params params;
520306c2d28SSomnath Kotur 	uint32_t hw_cntr_id = 0, sw_cntr_idx = 0;
52148d1c589SSomnath Kotur 	struct sw_acc_counter *sw_acc_tbl_entry;
522306c2d28SSomnath Kotur 	bool found_cntr_resource = false;
523bdf4a3c6SKishore Padmanabha 	bool found_parent_flow = false;
524bdf4a3c6SKishore Padmanabha 	uint32_t pc_idx = 0;
525f6e12015SKishore Padmanabha 	uint32_t session_type = 0;
526dd0191d5SShuanglin Wang 	uint8_t dir;
527306c2d28SSomnath Kotur 
528306c2d28SSomnath Kotur 	ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ctxt);
529306c2d28SSomnath Kotur 	if (!ulp_fc_info)
530306c2d28SSomnath Kotur 		return -ENODEV;
531306c2d28SSomnath Kotur 
532dd0191d5SShuanglin Wang 	fc_ops = ulp_fc_info->fc_ops;
533dd0191d5SShuanglin Wang 
5341f3106d4SSomnath Kotur 	if (bnxt_ulp_cntxt_acquire_fdb_lock(ctxt))
5351f3106d4SSomnath Kotur 		return -EIO;
5361f3106d4SSomnath Kotur 
537306c2d28SSomnath Kotur 	do {
538306c2d28SSomnath Kotur 		rc = ulp_flow_db_resource_get(ctxt,
53930683082SKishore Padmanabha 					      BNXT_ULP_FDB_TYPE_REGULAR,
540306c2d28SSomnath Kotur 					      flow_id,
541306c2d28SSomnath Kotur 					      &nxt_resource_index,
542306c2d28SSomnath Kotur 					      &params);
543306c2d28SSomnath Kotur 		if (params.resource_func ==
544306c2d28SSomnath Kotur 		     BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE &&
545306c2d28SSomnath Kotur 		     (params.resource_sub_type ==
5469cbfa4cfSKishore Padmanabha 		      BNXT_ULP_RESOURCE_SUB_TYPE_INDEX_TABLE_INT_COUNT ||
547306c2d28SSomnath Kotur 		      params.resource_sub_type ==
548bdf4a3c6SKishore Padmanabha 		      BNXT_ULP_RESOURCE_SUB_TYPE_INDEX_TABLE_EXT_COUNT)) {
549306c2d28SSomnath Kotur 			found_cntr_resource = true;
550306c2d28SSomnath Kotur 			break;
551306c2d28SSomnath Kotur 		}
552dd0191d5SShuanglin Wang 		if (params.resource_func == BNXT_ULP_RESOURCE_FUNC_CMM_STAT) {
553dd0191d5SShuanglin Wang 			found_cntr_resource = true;
554dd0191d5SShuanglin Wang 			break;
555dd0191d5SShuanglin Wang 		}
556bdf4a3c6SKishore Padmanabha 		if (params.resource_func ==
557bdf4a3c6SKishore Padmanabha 		    BNXT_ULP_RESOURCE_FUNC_PARENT_FLOW) {
558bdf4a3c6SKishore Padmanabha 			found_parent_flow = true;
559bdf4a3c6SKishore Padmanabha 			pc_idx = params.resource_hndl;
560bdf4a3c6SKishore Padmanabha 		}
561bdf4a3c6SKishore Padmanabha 
5621f3106d4SSomnath Kotur 	} while (!rc && nxt_resource_index);
563306c2d28SSomnath Kotur 
5648782e4deSKishore Padmanabha 	if (rc || !found_cntr_resource) {
5651f3106d4SSomnath Kotur 		bnxt_ulp_cntxt_release_fdb_lock(ctxt);
566306c2d28SSomnath Kotur 		return rc;
5678782e4deSKishore Padmanabha 	}
568306c2d28SSomnath Kotur 
569306c2d28SSomnath Kotur 	dir = params.direction;
570f6e12015SKishore Padmanabha 	session_type = ulp_flow_db_shared_session_get(&params);
5718782e4deSKishore Padmanabha 	if (!(ulp_fc_info->flags & ULP_FLAG_FC_SW_AGG_EN)) {
572f6e12015SKishore Padmanabha 		rc = fc_ops->ulp_flow_stat_get(ctxt, dir, session_type,
57349cdf043SKishore Padmanabha 					       params.resource_hndl, count);
5748782e4deSKishore Padmanabha 		bnxt_ulp_cntxt_release_fdb_lock(ctxt);
5758782e4deSKishore Padmanabha 		return rc;
5768782e4deSKishore Padmanabha 	}
57749cdf043SKishore Padmanabha 
578bdf4a3c6SKishore Padmanabha 	if (!found_parent_flow &&
579bdf4a3c6SKishore Padmanabha 	    params.resource_sub_type ==
5809cbfa4cfSKishore Padmanabha 			BNXT_ULP_RESOURCE_SUB_TYPE_INDEX_TABLE_INT_COUNT) {
581dd0191d5SShuanglin Wang 		hw_cntr_id = params.resource_hndl;
5828782e4deSKishore Padmanabha 		if (!ulp_fc_info->num_counters) {
583f6e12015SKishore Padmanabha 			rc = fc_ops->ulp_flow_stat_get(ctxt, dir, session_type,
584dd0191d5SShuanglin Wang 						       hw_cntr_id, count);
5858782e4deSKishore Padmanabha 			bnxt_ulp_cntxt_release_fdb_lock(ctxt);
5868782e4deSKishore Padmanabha 			return rc;
5878782e4deSKishore Padmanabha 		}
5881993b267SShahaji Bhosle 
5899cbfa4cfSKishore Padmanabha 		/* TODO:
5909cbfa4cfSKishore Padmanabha 		 * Think about optimizing with try_lock later
5919cbfa4cfSKishore Padmanabha 		 */
59248d1c589SSomnath Kotur 		pthread_mutex_lock(&ulp_fc_info->fc_lock);
593640bfd23SKishore Padmanabha 		sw_cntr_idx = hw_cntr_id -
594640bfd23SKishore Padmanabha 			ulp_fc_info->shadow_hw_tbl[dir].start_idx;
595640bfd23SKishore Padmanabha 		sw_acc_tbl_entry = &ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx];
59648d1c589SSomnath Kotur 		if (sw_acc_tbl_entry->pkt_count) {
597306c2d28SSomnath Kotur 			count->hits_set = 1;
598306c2d28SSomnath Kotur 			count->bytes_set = 1;
59948d1c589SSomnath Kotur 			count->hits = sw_acc_tbl_entry->pkt_count;
60048d1c589SSomnath Kotur 			count->bytes = sw_acc_tbl_entry->byte_count;
60148d1c589SSomnath Kotur 		}
60248d1c589SSomnath Kotur 		if (count->reset) {
60348d1c589SSomnath Kotur 			sw_acc_tbl_entry->pkt_count = 0;
60448d1c589SSomnath Kotur 			sw_acc_tbl_entry->byte_count = 0;
60548d1c589SSomnath Kotur 		}
60648d1c589SSomnath Kotur 		pthread_mutex_unlock(&ulp_fc_info->fc_lock);
607bdf4a3c6SKishore Padmanabha 	} else if (found_parent_flow &&
608bdf4a3c6SKishore Padmanabha 		   params.resource_sub_type ==
609bdf4a3c6SKishore Padmanabha 			BNXT_ULP_RESOURCE_SUB_TYPE_INDEX_TABLE_INT_COUNT) {
610ddaf0afaSKishore Padmanabha 		/* Get stats from the parent child table */
6118782e4deSKishore Padmanabha 		if (ulp_flow_db_parent_flow_count_get(ctxt, flow_id,
6128782e4deSKishore Padmanabha 						      pc_idx,
6138782e4deSKishore Padmanabha 						      &count->hits,
6148782e4deSKishore Padmanabha 						      &count->bytes,
6158782e4deSKishore Padmanabha 						      count->reset)) {
6168782e4deSKishore Padmanabha 			bnxt_ulp_cntxt_release_fdb_lock(ctxt);
6178782e4deSKishore Padmanabha 			return -EIO;
6188782e4deSKishore Padmanabha 		}
619bdf4a3c6SKishore Padmanabha 		if (count->hits)
620640bfd23SKishore Padmanabha 			count->hits_set = 1;
621bdf4a3c6SKishore Padmanabha 		if (count->bytes)
622640bfd23SKishore Padmanabha 			count->bytes_set = 1;
623306c2d28SSomnath Kotur 	} else {
624306c2d28SSomnath Kotur 		rc = -EINVAL;
625306c2d28SSomnath Kotur 	}
6268782e4deSKishore Padmanabha 	bnxt_ulp_cntxt_release_fdb_lock(ctxt);
627306c2d28SSomnath Kotur 	return rc;
628306c2d28SSomnath Kotur }
629640bfd23SKishore Padmanabha 
630640bfd23SKishore Padmanabha /*
631640bfd23SKishore Padmanabha  * Set the parent flow if it is SW accumulation counter entry.
632640bfd23SKishore Padmanabha  *
633640bfd23SKishore Padmanabha  * ctxt [in] The ulp context for the flow counter manager
634640bfd23SKishore Padmanabha  *
635640bfd23SKishore Padmanabha  * dir [in] The direction of the flow
636640bfd23SKishore Padmanabha  *
637640bfd23SKishore Padmanabha  * hw_cntr_id [in] The HW flow counter ID
638640bfd23SKishore Padmanabha  *
639bdf4a3c6SKishore Padmanabha  * pc_idx [in] parent child db index
640640bfd23SKishore Padmanabha  *
641640bfd23SKishore Padmanabha  */
642640bfd23SKishore Padmanabha int32_t ulp_fc_mgr_cntr_parent_flow_set(struct bnxt_ulp_context *ctxt,
643dd0191d5SShuanglin Wang 					uint8_t dir,
644640bfd23SKishore Padmanabha 					uint32_t hw_cntr_id,
645bdf4a3c6SKishore Padmanabha 					uint32_t pc_idx)
646640bfd23SKishore Padmanabha {
647640bfd23SKishore Padmanabha 	struct bnxt_ulp_fc_info *ulp_fc_info;
648640bfd23SKishore Padmanabha 	uint32_t sw_cntr_idx;
649640bfd23SKishore Padmanabha 	int32_t rc = 0;
650640bfd23SKishore Padmanabha 
651640bfd23SKishore Padmanabha 	ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ctxt);
652640bfd23SKishore Padmanabha 	if (!ulp_fc_info)
653640bfd23SKishore Padmanabha 		return -EIO;
654640bfd23SKishore Padmanabha 
655640bfd23SKishore Padmanabha 	pthread_mutex_lock(&ulp_fc_info->fc_lock);
656640bfd23SKishore Padmanabha 	sw_cntr_idx = hw_cntr_id - ulp_fc_info->shadow_hw_tbl[dir].start_idx;
657640bfd23SKishore Padmanabha 	if (ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].valid) {
658bdf4a3c6SKishore Padmanabha 		pc_idx |= FLOW_CNTR_PC_FLOW_VALID;
659bdf4a3c6SKishore Padmanabha 		ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].pc_flow_idx = pc_idx;
660640bfd23SKishore Padmanabha 	} else {
661dd0191d5SShuanglin Wang 		BNXT_DRV_DBG(ERR, "Failed to set parent flow id %x:%x\n",
662bdf4a3c6SKishore Padmanabha 			     hw_cntr_id, pc_idx);
663640bfd23SKishore Padmanabha 		rc = -ENOENT;
664640bfd23SKishore Padmanabha 	}
665640bfd23SKishore Padmanabha 	pthread_mutex_unlock(&ulp_fc_info->fc_lock);
666640bfd23SKishore Padmanabha 
667640bfd23SKishore Padmanabha 	return rc;
668640bfd23SKishore Padmanabha }
669