1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2014-2020 Broadcom
6 #include <rte_malloc.h>
8 #include "bnxt_tf_common.h"
10 #include "ulp_template_struct.h"
11 #include "ulp_mapper.h"
12 #include "ulp_flow_db.h"
13 #include "ulp_fc_mgr.h"
15 #define ULP_FLOW_DB_RES_DIR_BIT 31
16 #define ULP_FLOW_DB_RES_DIR_MASK 0x80000000
17 #define ULP_FLOW_DB_RES_FUNC_BITS 28
18 #define ULP_FLOW_DB_RES_FUNC_MASK 0x70000000
19 #define ULP_FLOW_DB_RES_NXT_MASK 0x0FFFFFFF
20 #define ULP_FLOW_DB_RES_FUNC_UPPER 5
21 #define ULP_FLOW_DB_RES_FUNC_NEED_LOWER 0x80
22 #define ULP_FLOW_DB_RES_FUNC_LOWER_MASK 0x1F
24 /* Macro to copy the nxt_resource_idx */
25 #define ULP_FLOW_DB_RES_NXT_SET(dst, src) {(dst) |= ((src) &\
26 ULP_FLOW_DB_RES_NXT_MASK); }
27 #define ULP_FLOW_DB_RES_NXT_RESET(dst) ((dst) &= ~(ULP_FLOW_DB_RES_NXT_MASK))
30 * Helper function to set the bit in the active flows
31 * No validation is done in this function.
33 * flow_db [in] Ptr to flow database
34 * flow_type [in] - specify default or regular
35 * idx [in] The index to bit to be set or reset.
36 * flag [in] 1 to set and 0 to reset.
41 ulp_flow_db_active_flows_bit_set(struct bnxt_ulp_flow_db *flow_db,
42 enum bnxt_ulp_fdb_type flow_type,
46 struct bnxt_ulp_flow_tbl *f_tbl = &flow_db->flow_tbl;
47 uint32_t a_idx = idx / ULP_INDEX_BITMAP_SIZE;
50 if (flow_type == BNXT_ULP_FDB_TYPE_REGULAR)
51 ULP_INDEX_BITMAP_SET(f_tbl->active_reg_flows[a_idx],
54 ULP_INDEX_BITMAP_SET(f_tbl->active_dflt_flows[a_idx],
57 if (flow_type == BNXT_ULP_FDB_TYPE_REGULAR)
58 ULP_INDEX_BITMAP_RESET(f_tbl->active_reg_flows[a_idx],
61 ULP_INDEX_BITMAP_RESET(f_tbl->active_dflt_flows[a_idx],
67 * Helper function to check if given fid is active flow.
68 * No validation being done in this function.
70 * flow_db [in] Ptr to flow database
71 * flow_type [in] - specify default or regular
72 * idx [in] The index to bit to be set or reset.
74 * returns 1 on set or 0 if not set.
77 ulp_flow_db_active_flows_bit_is_set(struct bnxt_ulp_flow_db *flow_db,
78 enum bnxt_ulp_fdb_type flow_type,
81 struct bnxt_ulp_flow_tbl *f_tbl = &flow_db->flow_tbl;
82 uint32_t a_idx = idx / ULP_INDEX_BITMAP_SIZE;
84 if (flow_type == BNXT_ULP_FDB_TYPE_REGULAR)
85 return ULP_INDEX_BITMAP_GET(f_tbl->active_reg_flows[a_idx],
88 return ULP_INDEX_BITMAP_GET(f_tbl->active_dflt_flows[a_idx],
92 static inline enum tf_dir
93 ulp_flow_db_resource_dir_get(struct ulp_fdb_resource_info *res_info)
95 return ((res_info->nxt_resource_idx & ULP_FLOW_DB_RES_DIR_MASK) >>
96 ULP_FLOW_DB_RES_DIR_BIT);
100 ulp_flow_db_resource_func_get(struct ulp_fdb_resource_info *res_info)
104 func = (((res_info->nxt_resource_idx & ULP_FLOW_DB_RES_FUNC_MASK) >>
105 ULP_FLOW_DB_RES_FUNC_BITS) << ULP_FLOW_DB_RES_FUNC_UPPER);
106 /* The reource func is split into upper and lower */
107 if (func & ULP_FLOW_DB_RES_FUNC_NEED_LOWER)
108 return (func | res_info->resource_func_lower);
113 * Helper function to copy the resource params to resource info
114 * No validation being done in this function.
116 * resource_info [out] Ptr to resource information
117 * params [in] The input params from the caller
121 ulp_flow_db_res_params_to_info(struct ulp_fdb_resource_info *resource_info,
122 struct ulp_flow_db_res_params *params)
124 uint32_t resource_func;
126 resource_info->nxt_resource_idx |= ((params->direction <<
127 ULP_FLOW_DB_RES_DIR_BIT) &
128 ULP_FLOW_DB_RES_DIR_MASK);
129 resource_func = (params->resource_func >> ULP_FLOW_DB_RES_FUNC_UPPER);
130 resource_info->nxt_resource_idx |= ((resource_func <<
131 ULP_FLOW_DB_RES_FUNC_BITS) &
132 ULP_FLOW_DB_RES_FUNC_MASK);
134 if (params->resource_func & ULP_FLOW_DB_RES_FUNC_NEED_LOWER) {
135 /* Break the resource func into two parts */
136 resource_func = (params->resource_func &
137 ULP_FLOW_DB_RES_FUNC_LOWER_MASK);
138 resource_info->resource_func_lower = resource_func;
141 /* Store the handle as 64bit only for EM table entries */
142 if (params->resource_func != BNXT_ULP_RESOURCE_FUNC_EXT_EM_TABLE &&
143 params->resource_func != BNXT_ULP_RESOURCE_FUNC_INT_EM_TABLE) {
144 resource_info->resource_hndl = (uint32_t)params->resource_hndl;
145 resource_info->resource_type = params->resource_type;
146 resource_info->resource_sub_type = params->resource_sub_type;
147 resource_info->reserved = params->reserved;
149 resource_info->resource_em_handle = params->resource_hndl;
154 * Helper function to copy the resource params to resource info
155 * No validation being done in this function.
157 * resource_info [in] Ptr to resource information
158 * params [out] The output params to the caller
163 ulp_flow_db_res_info_to_params(struct ulp_fdb_resource_info *resource_info,
164 struct ulp_flow_db_res_params *params)
166 memset(params, 0, sizeof(struct ulp_flow_db_res_params));
168 /* use the helper function to get the resource func */
169 params->direction = ulp_flow_db_resource_dir_get(resource_info);
170 params->resource_func = ulp_flow_db_resource_func_get(resource_info);
172 if (params->resource_func == BNXT_ULP_RESOURCE_FUNC_EXT_EM_TABLE ||
173 params->resource_func == BNXT_ULP_RESOURCE_FUNC_INT_EM_TABLE) {
174 params->resource_hndl = resource_info->resource_em_handle;
175 } else if (params->resource_func & ULP_FLOW_DB_RES_FUNC_NEED_LOWER) {
176 params->resource_hndl = resource_info->resource_hndl;
177 params->resource_type = resource_info->resource_type;
178 params->resource_sub_type = resource_info->resource_sub_type;
179 params->reserved = resource_info->reserved;
184 * Helper function to allocate the flow table and initialize
185 * the stack for allocation operations.
187 * flow_db [in] Ptr to flow database structure
189 * Returns 0 on success or negative number on failure.
192 ulp_flow_db_alloc_resource(struct bnxt_ulp_flow_db *flow_db)
195 struct bnxt_ulp_flow_tbl *flow_tbl;
198 flow_tbl = &flow_db->flow_tbl;
200 size = sizeof(struct ulp_fdb_resource_info) * flow_tbl->num_resources;
201 flow_tbl->flow_resources =
202 rte_zmalloc("ulp_fdb_resource_info", size, 0);
204 if (!flow_tbl->flow_resources) {
205 BNXT_TF_DBG(ERR, "Failed to alloc memory for flow table\n");
208 size = sizeof(uint32_t) * flow_tbl->num_resources;
209 flow_tbl->flow_tbl_stack = rte_zmalloc("flow_tbl_stack", size, 0);
210 if (!flow_tbl->flow_tbl_stack) {
211 BNXT_TF_DBG(ERR, "Failed to alloc memory flow tbl stack\n");
214 size = (flow_tbl->num_flows / sizeof(uint64_t)) + 1;
215 size = ULP_BYTE_ROUND_OFF_8(size);
216 flow_tbl->active_reg_flows = rte_zmalloc("active reg flows", size,
217 ULP_BUFFER_ALIGN_64_BYTE);
218 if (!flow_tbl->active_reg_flows) {
219 BNXT_TF_DBG(ERR, "Failed to alloc memory active reg flows\n");
223 flow_tbl->active_dflt_flows = rte_zmalloc("active dflt flows", size,
224 ULP_BUFFER_ALIGN_64_BYTE);
225 if (!flow_tbl->active_dflt_flows) {
226 BNXT_TF_DBG(ERR, "Failed to alloc memory active dflt flows\n");
230 /* Initialize the stack table. */
231 for (idx = 0; idx < flow_tbl->num_resources; idx++)
232 flow_tbl->flow_tbl_stack[idx] = idx;
234 /* Ignore the first element in the list. */
235 flow_tbl->head_index = 1;
236 /* Tail points to the last entry in the list. */
237 flow_tbl->tail_index = flow_tbl->num_resources - 1;
242 * Helper function to deallocate the flow table.
244 * flow_db [in] Ptr to flow database structure
249 ulp_flow_db_dealloc_resource(struct bnxt_ulp_flow_db *flow_db)
251 struct bnxt_ulp_flow_tbl *flow_tbl = &flow_db->flow_tbl;
253 /* Free all the allocated tables in the flow table. */
254 if (flow_tbl->active_reg_flows) {
255 rte_free(flow_tbl->active_reg_flows);
256 flow_tbl->active_reg_flows = NULL;
258 if (flow_tbl->active_dflt_flows) {
259 rte_free(flow_tbl->active_dflt_flows);
260 flow_tbl->active_dflt_flows = NULL;
263 if (flow_tbl->flow_tbl_stack) {
264 rte_free(flow_tbl->flow_tbl_stack);
265 flow_tbl->flow_tbl_stack = NULL;
268 if (flow_tbl->flow_resources) {
269 rte_free(flow_tbl->flow_resources);
270 flow_tbl->flow_resources = NULL;
275 * Helper function to add function id to the flow table
277 * flow_db [in] Ptr to flow table
278 * flow_id [in] The flow id of the flow
279 * func_id [in] The func_id to be set, for reset pass zero
284 ulp_flow_db_func_id_set(struct bnxt_ulp_flow_db *flow_db,
288 /* set the function id in the function table */
289 if (flow_id < flow_db->func_id_tbl_size)
290 flow_db->func_id_tbl[flow_id] = func_id;
291 else /* This should never happen */
292 BNXT_TF_DBG(ERR, "Invalid flow id, flowdb corrupt\n");
296 * Initialize the parent-child database. Memory is allocated in this
297 * call and assigned to the database
299 * flow_db [in] Ptr to flow table
300 * num_entries[in] - number of entries to allocate
302 * Returns 0 on success or negative number on failure.
305 ulp_flow_db_parent_tbl_init(struct bnxt_ulp_flow_db *flow_db,
306 uint32_t num_entries)
308 struct ulp_fdb_parent_child_db *p_db;
314 /* update the sizes for the allocation */
315 p_db = &flow_db->parent_child_db;
316 p_db->child_bitset_size = (flow_db->flow_tbl.num_flows /
317 sizeof(uint64_t)) + 1; /* size in bytes */
318 p_db->child_bitset_size = ULP_BYTE_ROUND_OFF_8(p_db->child_bitset_size);
319 p_db->entries_count = num_entries;
321 /* allocate the memory */
322 p_db->parent_flow_tbl = rte_zmalloc("fdb parent flow tbl",
323 sizeof(struct ulp_fdb_parent_info) *
324 p_db->entries_count, 0);
325 if (!p_db->parent_flow_tbl) {
327 "Failed to allocate memory fdb parent flow tbl\n");
330 size = p_db->child_bitset_size * p_db->entries_count;
333 * allocate the big chunk of memory to be statically carved into
334 * child_fid_bitset pointer.
336 p_db->parent_flow_tbl_mem = rte_zmalloc("fdb parent flow tbl mem",
338 ULP_BUFFER_ALIGN_64_BYTE);
339 if (!p_db->parent_flow_tbl_mem) {
341 "Failed to allocate memory fdb parent flow mem\n");
345 /* set the pointers in parent table to their offsets */
346 for (idx = 0 ; idx < p_db->entries_count; idx++) {
347 p_db->parent_flow_tbl[idx].child_fid_bitset =
348 (uint64_t *)&p_db->parent_flow_tbl_mem[idx *
349 p_db->child_bitset_size];
356 * Deinitialize the parent-child database. Memory is deallocated in
357 * this call and all flows should have been purged before this
360 * flow_db [in] Ptr to flow table
365 ulp_flow_db_parent_tbl_deinit(struct bnxt_ulp_flow_db *flow_db)
367 /* free the memory related to parent child database */
368 if (flow_db->parent_child_db.parent_flow_tbl_mem) {
369 rte_free(flow_db->parent_child_db.parent_flow_tbl_mem);
370 flow_db->parent_child_db.parent_flow_tbl_mem = NULL;
372 if (flow_db->parent_child_db.parent_flow_tbl) {
373 rte_free(flow_db->parent_child_db.parent_flow_tbl);
374 flow_db->parent_child_db.parent_flow_tbl = NULL;
379 * Initialize the flow database. Memory is allocated in this
380 * call and assigned to the flow database.
382 * ulp_ctxt [in] Ptr to ulp context
384 * Returns 0 on success or negative number on failure.
387 ulp_flow_db_init(struct bnxt_ulp_context *ulp_ctxt)
389 struct bnxt_ulp_device_params *dparms;
390 struct bnxt_ulp_flow_tbl *flow_tbl;
391 struct bnxt_ulp_flow_db *flow_db;
392 uint32_t dev_id, num_flows;
393 enum bnxt_ulp_flow_mem_type mtype;
395 /* Get the dev specific number of flows that needed to be supported. */
396 if (bnxt_ulp_cntxt_dev_id_get(ulp_ctxt, &dev_id)) {
397 BNXT_TF_DBG(ERR, "Invalid device id\n");
401 dparms = bnxt_ulp_device_params_get(dev_id);
403 BNXT_TF_DBG(ERR, "could not fetch the device params\n");
407 flow_db = rte_zmalloc("bnxt_ulp_flow_db",
408 sizeof(struct bnxt_ulp_flow_db), 0);
411 "Failed to allocate memory for flow table ptr\n");
415 /* Attach the flow database to the ulp context. */
416 bnxt_ulp_cntxt_ptr2_flow_db_set(ulp_ctxt, flow_db);
418 /* Determine the number of flows based on EM type */
419 bnxt_ulp_cntxt_mem_type_get(ulp_ctxt, &mtype);
420 if (mtype == BNXT_ULP_FLOW_MEM_TYPE_INT)
421 num_flows = dparms->int_flow_db_num_entries;
423 num_flows = dparms->ext_flow_db_num_entries;
425 /* Populate the regular flow table limits. */
426 flow_tbl = &flow_db->flow_tbl;
427 flow_tbl->num_flows = num_flows + 1;
428 flow_tbl->num_resources = ((num_flows + 1) *
429 dparms->num_resources_per_flow);
431 /* Include the default flow table limits. */
432 flow_tbl->num_flows += (BNXT_FLOW_DB_DEFAULT_NUM_FLOWS + 1);
433 flow_tbl->num_resources += ((BNXT_FLOW_DB_DEFAULT_NUM_FLOWS + 1) *
434 BNXT_FLOW_DB_DEFAULT_NUM_RESOURCES);
436 /* Allocate the resource for the flow table. */
437 if (ulp_flow_db_alloc_resource(flow_db))
440 /* add 1 since we are not using index 0 for flow id */
441 flow_db->func_id_tbl_size = flow_tbl->num_flows + 1;
442 /* Allocate the function Id table */
443 flow_db->func_id_tbl = rte_zmalloc("bnxt_ulp_flow_db_func_id_table",
444 flow_db->func_id_tbl_size *
445 sizeof(uint16_t), 0);
446 if (!flow_db->func_id_tbl) {
448 "Failed to allocate mem for flow table func id\n");
451 /* initialize the parent child database */
452 if (ulp_flow_db_parent_tbl_init(flow_db,
453 dparms->fdb_parent_flow_entries)) {
455 "Failed to allocate mem for parent child db\n");
459 /* All good so return. */
460 BNXT_TF_DBG(INFO, "FlowDB initialized with %d flows.\n",
461 flow_tbl->num_flows);
464 ulp_flow_db_deinit(ulp_ctxt);
469 * Deinitialize the flow database. Memory is deallocated in
470 * this call and all flows should have been purged before this
473 * ulp_ctxt [in] Ptr to ulp context
475 * Returns 0 on success.
478 ulp_flow_db_deinit(struct bnxt_ulp_context *ulp_ctxt)
480 struct bnxt_ulp_flow_db *flow_db;
482 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
486 /* Detach the flow database from the ulp context. */
487 bnxt_ulp_cntxt_ptr2_flow_db_set(ulp_ctxt, NULL);
489 /* Free up all the memory. */
490 ulp_flow_db_parent_tbl_deinit(flow_db);
491 ulp_flow_db_dealloc_resource(flow_db);
492 rte_free(flow_db->func_id_tbl);
499 * Allocate the flow database entry
501 * ulp_ctxt [in] Ptr to ulp_context
502 * flow_type [in] - specify default or regular
503 * func_id [in].function id of the ingress port
504 * fid [out] The index to the flow entry
506 * returns 0 on success and negative on failure.
509 ulp_flow_db_fid_alloc(struct bnxt_ulp_context *ulp_ctxt,
510 enum bnxt_ulp_fdb_type flow_type,
514 struct bnxt_ulp_flow_db *flow_db;
515 struct bnxt_ulp_flow_tbl *flow_tbl;
517 *fid = 0; /* Initialize fid to invalid value */
518 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
520 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
524 if (flow_type > BNXT_ULP_FDB_TYPE_DEFAULT) {
525 BNXT_TF_DBG(ERR, "Invalid flow type\n");
529 flow_tbl = &flow_db->flow_tbl;
530 /* check for max flows */
531 if (flow_tbl->num_flows <= flow_tbl->head_index) {
532 BNXT_TF_DBG(ERR, "Flow database has reached max flows\n");
535 if (flow_tbl->tail_index <= (flow_tbl->head_index + 1)) {
536 BNXT_TF_DBG(ERR, "Flow database has reached max resources\n");
539 *fid = flow_tbl->flow_tbl_stack[flow_tbl->head_index];
540 flow_tbl->head_index++;
542 /* Set the flow type */
543 ulp_flow_db_active_flows_bit_set(flow_db, flow_type, *fid, 1);
545 /* function id update is only valid for regular flow table */
546 if (flow_type == BNXT_ULP_FDB_TYPE_REGULAR)
547 ulp_flow_db_func_id_set(flow_db, *fid, func_id);
554 * Allocate the flow database entry.
555 * The params->critical_resource has to be set to 0 to allocate a new resource.
557 * ulp_ctxt [in] Ptr to ulp_context
558 * flow_type [in] Specify it is regular or default flow
559 * fid [in] The index to the flow entry
560 * params [in] The contents to be copied into resource
562 * returns 0 on success and negative on failure.
565 ulp_flow_db_resource_add(struct bnxt_ulp_context *ulp_ctxt,
566 enum bnxt_ulp_fdb_type flow_type,
568 struct ulp_flow_db_res_params *params)
570 struct bnxt_ulp_flow_db *flow_db;
571 struct bnxt_ulp_flow_tbl *flow_tbl;
572 struct ulp_fdb_resource_info *resource, *fid_resource;
575 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
577 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
581 if (flow_type > BNXT_ULP_FDB_TYPE_DEFAULT) {
582 BNXT_TF_DBG(ERR, "Invalid flow type\n");
586 flow_tbl = &flow_db->flow_tbl;
587 /* check for max flows */
588 if (fid >= flow_tbl->num_flows || !fid) {
589 BNXT_TF_DBG(ERR, "Invalid flow index\n");
593 /* check if the flow is active or not */
594 if (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type, fid)) {
595 BNXT_TF_DBG(ERR, "flow does not exist\n");
599 /* check for max resource */
600 if ((flow_tbl->head_index + 1) >= flow_tbl->tail_index) {
601 BNXT_TF_DBG(ERR, "Flow db has reached max resources\n");
604 fid_resource = &flow_tbl->flow_resources[fid];
606 if (!params->critical_resource) {
607 /* Not the critical_resource so allocate a resource */
608 idx = flow_tbl->flow_tbl_stack[flow_tbl->tail_index];
609 resource = &flow_tbl->flow_resources[idx];
610 flow_tbl->tail_index--;
612 /* Update the chain list of resource*/
613 ULP_FLOW_DB_RES_NXT_SET(resource->nxt_resource_idx,
614 fid_resource->nxt_resource_idx);
615 /* update the contents */
616 ulp_flow_db_res_params_to_info(resource, params);
617 ULP_FLOW_DB_RES_NXT_RESET(fid_resource->nxt_resource_idx);
618 ULP_FLOW_DB_RES_NXT_SET(fid_resource->nxt_resource_idx,
621 /* critical resource. Just update the fid resource */
622 ulp_flow_db_res_params_to_info(fid_resource, params);
625 if (params->resource_type == TF_TBL_TYPE_ACT_STATS_64 &&
626 params->resource_sub_type ==
627 BNXT_ULP_RESOURCE_SUB_TYPE_INDEX_TYPE_INT_COUNT) {
628 /* Store the first HW counter ID for this table */
629 if (!ulp_fc_mgr_start_idx_isset(ulp_ctxt, params->direction))
630 ulp_fc_mgr_start_idx_set(ulp_ctxt, params->direction,
631 params->resource_hndl);
633 ulp_fc_mgr_cntr_set(ulp_ctxt, params->direction,
634 params->resource_hndl);
636 if (!ulp_fc_mgr_thread_isstarted(ulp_ctxt))
637 ulp_fc_mgr_thread_start(ulp_ctxt);
640 /* all good, return success */
645 * Free the flow database entry.
646 * The params->critical_resource has to be set to 1 to free the first resource.
648 * ulp_ctxt [in] Ptr to ulp_context
649 * flow_type [in] Specify it is regular or default flow
650 * fid [in] The index to the flow entry
651 * params [in/out] The contents to be copied into params.
652 * Onlythe critical_resource needs to be set by the caller.
654 * Returns 0 on success and negative on failure.
657 ulp_flow_db_resource_del(struct bnxt_ulp_context *ulp_ctxt,
658 enum bnxt_ulp_fdb_type flow_type,
660 struct ulp_flow_db_res_params *params)
662 struct bnxt_ulp_flow_db *flow_db;
663 struct bnxt_ulp_flow_tbl *flow_tbl;
664 struct ulp_fdb_resource_info *nxt_resource, *fid_resource;
665 uint32_t nxt_idx = 0;
667 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
669 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
673 if (flow_type > BNXT_ULP_FDB_TYPE_DEFAULT) {
674 BNXT_TF_DBG(ERR, "Invalid flow type\n");
678 flow_tbl = &flow_db->flow_tbl;
679 /* check for max flows */
680 if (fid >= flow_tbl->num_flows || !fid) {
681 BNXT_TF_DBG(ERR, "Invalid flow index %x\n", fid);
685 /* check if the flow is active or not */
686 if (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type, fid)) {
687 BNXT_TF_DBG(ERR, "flow does not exist\n");
691 fid_resource = &flow_tbl->flow_resources[fid];
692 if (!params->critical_resource) {
693 /* Not the critical resource so free the resource */
694 ULP_FLOW_DB_RES_NXT_SET(nxt_idx,
695 fid_resource->nxt_resource_idx);
697 /* reached end of resources */
700 nxt_resource = &flow_tbl->flow_resources[nxt_idx];
702 /* connect the fid resource to the next resource */
703 ULP_FLOW_DB_RES_NXT_RESET(fid_resource->nxt_resource_idx);
704 ULP_FLOW_DB_RES_NXT_SET(fid_resource->nxt_resource_idx,
705 nxt_resource->nxt_resource_idx);
707 /* update the contents to be given to caller */
708 ulp_flow_db_res_info_to_params(nxt_resource, params);
710 /* Delete the nxt_resource */
711 memset(nxt_resource, 0, sizeof(struct ulp_fdb_resource_info));
713 /* add it to the free list */
714 flow_tbl->tail_index++;
715 if (flow_tbl->tail_index >= flow_tbl->num_resources) {
716 BNXT_TF_DBG(ERR, "FlowDB:Tail reached max\n");
719 flow_tbl->flow_tbl_stack[flow_tbl->tail_index] = nxt_idx;
722 /* Critical resource. copy the contents and exit */
723 ulp_flow_db_res_info_to_params(fid_resource, params);
724 ULP_FLOW_DB_RES_NXT_SET(nxt_idx,
725 fid_resource->nxt_resource_idx);
726 memset(fid_resource, 0, sizeof(struct ulp_fdb_resource_info));
727 ULP_FLOW_DB_RES_NXT_SET(fid_resource->nxt_resource_idx,
731 /* Now that the HW Flow counter resource is deleted, reset it's
732 * corresponding slot in the SW accumulation table in the Flow Counter
735 if (params->resource_type == TF_TBL_TYPE_ACT_STATS_64 &&
736 params->resource_sub_type ==
737 BNXT_ULP_RESOURCE_SUB_TYPE_INDEX_TYPE_INT_COUNT) {
738 ulp_fc_mgr_cntr_reset(ulp_ctxt, params->direction,
739 params->resource_hndl);
742 /* all good, return success */
747 * Free the flow database entry
749 * ulp_ctxt [in] Ptr to ulp_context
750 * flow_type [in] - specify default or regular
751 * fid [in] The index to the flow entry
753 * returns 0 on success and negative on failure.
756 ulp_flow_db_fid_free(struct bnxt_ulp_context *ulp_ctxt,
757 enum bnxt_ulp_fdb_type flow_type,
760 struct bnxt_ulp_flow_db *flow_db;
761 struct bnxt_ulp_flow_tbl *flow_tbl;
763 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
765 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
769 if (flow_type > BNXT_ULP_FDB_TYPE_DEFAULT) {
770 BNXT_TF_DBG(ERR, "Invalid flow type\n");
774 flow_tbl = &flow_db->flow_tbl;
776 /* check for limits of fid */
777 if (fid >= flow_tbl->num_flows || !fid) {
778 BNXT_TF_DBG(ERR, "Invalid flow index\n");
782 /* check if the flow is active or not */
783 if (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type, fid)) {
784 BNXT_TF_DBG(ERR, "flow does not exist\n");
787 flow_tbl->head_index--;
788 if (!flow_tbl->head_index) {
789 BNXT_TF_DBG(ERR, "FlowDB: Head Ptr is zero\n");
792 flow_tbl->flow_tbl_stack[flow_tbl->head_index] = fid;
794 /* Clear the flows bitmap */
795 ulp_flow_db_active_flows_bit_set(flow_db, flow_type, fid, 0);
797 if (flow_type == BNXT_ULP_FDB_TYPE_REGULAR)
798 ulp_flow_db_func_id_set(flow_db, fid, 0);
800 /* all good, return success */
805 * Get the flow database entry details
807 * ulp_ctxt [in] Ptr to ulp_context
808 * flow_type [in] - specify default or regular
809 * fid [in] The index to the flow entry
810 * nxt_idx [in/out] the index to the next entry
811 * params [out] The contents to be copied into params.
813 * returns 0 on success and negative on failure.
816 ulp_flow_db_resource_get(struct bnxt_ulp_context *ulp_ctxt,
817 enum bnxt_ulp_fdb_type flow_type,
820 struct ulp_flow_db_res_params *params)
822 struct bnxt_ulp_flow_db *flow_db;
823 struct bnxt_ulp_flow_tbl *flow_tbl;
824 struct ulp_fdb_resource_info *nxt_resource, *fid_resource;
826 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
828 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
832 if (flow_type > BNXT_ULP_FDB_TYPE_DEFAULT) {
833 BNXT_TF_DBG(ERR, "Invalid flow type\n");
837 flow_tbl = &flow_db->flow_tbl;
839 /* check for limits of fid */
840 if (fid >= flow_tbl->num_flows || !fid) {
841 BNXT_TF_DBG(ERR, "Invalid flow index\n");
845 /* check if the flow is active or not */
846 if (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type, fid)) {
847 BNXT_TF_DBG(ERR, "flow does not exist\n");
852 fid_resource = &flow_tbl->flow_resources[fid];
853 ulp_flow_db_res_info_to_params(fid_resource, params);
854 ULP_FLOW_DB_RES_NXT_SET(*nxt_idx,
855 fid_resource->nxt_resource_idx);
857 nxt_resource = &flow_tbl->flow_resources[*nxt_idx];
858 ulp_flow_db_res_info_to_params(nxt_resource, params);
860 ULP_FLOW_DB_RES_NXT_SET(*nxt_idx,
861 nxt_resource->nxt_resource_idx);
864 /* all good, return success */
869 * Get the flow database entry iteratively
871 * flow_tbl [in] Ptr to flow table
872 * flow_type [in] - specify default or regular
873 * fid [in/out] The index to the flow entry
875 * returns 0 on success and negative on failure.
878 ulp_flow_db_next_entry_get(struct bnxt_ulp_flow_db *flow_db,
879 enum bnxt_ulp_fdb_type flow_type,
882 uint32_t lfid = *fid;
883 uint32_t idx, s_idx, mod_fid;
885 uint64_t *active_flows;
886 struct bnxt_ulp_flow_tbl *flowtbl = &flow_db->flow_tbl;
888 if (flow_type == BNXT_ULP_FDB_TYPE_REGULAR)
889 active_flows = flowtbl->active_reg_flows;
891 active_flows = flowtbl->active_dflt_flows;
894 /* increment the flow id to find the next valid flow id */
896 if (lfid >= flowtbl->num_flows)
898 idx = lfid / ULP_INDEX_BITMAP_SIZE;
899 mod_fid = lfid % ULP_INDEX_BITMAP_SIZE;
901 while (!(bs = active_flows[idx])) {
903 if ((idx * ULP_INDEX_BITMAP_SIZE) >= flowtbl->num_flows)
907 * remove the previous bits in the bitset bs to find the
908 * next non zero bit in the bitset. This needs to be done
909 * only if the idx is same as he one you started.
912 bs &= (-1UL >> mod_fid);
913 lfid = (idx * ULP_INDEX_BITMAP_SIZE) + __builtin_clzl(bs);
915 BNXT_TF_DBG(ERR, "Flow Database is corrupt\n");
918 } while (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type,
921 /* all good, return success */
927 * Flush all flows in the flow database.
929 * ulp_ctxt [in] Ptr to ulp context
930 * flow_type [in] - specify default or regular
932 * returns 0 on success or negative number on failure
935 ulp_flow_db_flush_flows(struct bnxt_ulp_context *ulp_ctx,
936 enum bnxt_ulp_fdb_type flow_type)
939 struct bnxt_ulp_flow_db *flow_db;
942 BNXT_TF_DBG(ERR, "Invalid Argument\n");
946 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctx);
948 BNXT_TF_DBG(ERR, "Flow database not found\n");
951 if (bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx)) {
952 BNXT_TF_DBG(ERR, "Flow db lock acquire failed\n");
956 while (!ulp_flow_db_next_entry_get(flow_db, flow_type, &fid))
957 ulp_mapper_resources_free(ulp_ctx, flow_type, fid);
959 bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);
965 * Flush all flows in the flow database that belong to a device function.
967 * ulp_ctxt [in] Ptr to ulp context
968 * func_id [in] - The port function id
970 * returns 0 on success or negative number on failure
973 ulp_flow_db_function_flow_flush(struct bnxt_ulp_context *ulp_ctx,
976 uint32_t flow_id = 0;
977 struct bnxt_ulp_flow_db *flow_db;
979 if (!ulp_ctx || !func_id) {
980 BNXT_TF_DBG(ERR, "Invalid Argument\n");
984 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctx);
986 BNXT_TF_DBG(ERR, "Flow database not found\n");
989 if (bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx)) {
990 BNXT_TF_DBG(ERR, "Flow db lock acquire failed\n");
994 while (!ulp_flow_db_next_entry_get(flow_db, BNXT_ULP_FDB_TYPE_REGULAR,
996 if (flow_db->func_id_tbl[flow_id] == func_id)
997 ulp_mapper_resources_free(ulp_ctx,
998 BNXT_ULP_FDB_TYPE_REGULAR,
1001 bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);
1006 * Flush all flows in the flow database that are associated with the session.
1008 * ulp_ctxt [in] Ptr to ulp context
1010 * returns 0 on success or negative number on failure
1013 ulp_flow_db_session_flow_flush(struct bnxt_ulp_context *ulp_ctx)
1016 * TBD: Tf core implementation of FW session flush shall change this
1019 return ulp_flow_db_flush_flows(ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR);
1023 * Check that flow id matches the function id or not
1025 * ulp_ctxt [in] Ptr to ulp context
1026 * flow_db [in] Ptr to flow table
1027 * func_id [in] The func_id to be set, for reset pass zero.
1029 * returns true on success or false on failure
1032 ulp_flow_db_validate_flow_func(struct bnxt_ulp_context *ulp_ctx,
1036 struct bnxt_ulp_flow_db *flow_db;
1038 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctx);
1040 BNXT_TF_DBG(ERR, "Flow database not found\n");
1044 /* set the function id in the function table */
1045 if (flow_id < flow_db->func_id_tbl_size && func_id &&
1046 flow_db->func_id_tbl[flow_id] == func_id)
1053 * Internal api to traverse the resource list within a flow
1054 * and match a resource based on resource func and resource
1055 * sub type. This api should be used only for resources that
1056 * are unique and do not have multiple instances of resource
1057 * func and sub type combination since it will return only
1061 ulp_flow_db_resource_hndl_get(struct bnxt_ulp_context *ulp_ctx,
1062 enum bnxt_ulp_fdb_type flow_type,
1064 uint32_t resource_func,
1065 uint32_t res_subtype,
1068 struct bnxt_ulp_flow_db *flow_db;
1069 struct bnxt_ulp_flow_tbl *flow_tbl;
1070 struct ulp_fdb_resource_info *fid_res;
1073 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctx);
1075 BNXT_TF_DBG(ERR, "Flow database not found\n");
1079 if (flow_type > BNXT_ULP_FDB_TYPE_DEFAULT) {
1080 BNXT_TF_DBG(ERR, "Invalid flow type\n");
1084 flow_tbl = &flow_db->flow_tbl;
1086 /* check for limits of fid */
1087 if (flow_id >= flow_tbl->num_flows || !flow_id) {
1088 BNXT_TF_DBG(ERR, "Invalid flow index\n");
1092 /* check if the flow is active or not */
1093 if (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type, flow_id)) {
1094 BNXT_TF_DBG(ERR, "flow does not exist\n");
1097 /* Iterate the resource to get the resource handle */
1100 fid_res = &flow_tbl->flow_resources[res_id];
1101 if (ulp_flow_db_resource_func_get(fid_res) == resource_func) {
1102 if (resource_func & ULP_FLOW_DB_RES_FUNC_NEED_LOWER) {
1103 if (res_subtype == fid_res->resource_sub_type) {
1104 *res_hndl = fid_res->resource_hndl;
1108 } else if (resource_func ==
1109 BNXT_ULP_RESOURCE_FUNC_EXT_EM_TABLE ||
1111 BNXT_ULP_RESOURCE_FUNC_INT_EM_TABLE) {
1112 *res_hndl = fid_res->resource_em_handle;
1117 ULP_FLOW_DB_RES_NXT_SET(res_id, fid_res->nxt_resource_idx);
1123 * Api to get the cfa action pointer from a flow.
1125 * ulp_ctxt [in] Ptr to ulp context
1126 * flow_id [in] flow id
1127 * cfa_action [out] The resource handle stored in the flow database
1129 * returns 0 on success
1132 ulp_default_flow_db_cfa_action_get(struct bnxt_ulp_context *ulp_ctx,
1134 uint16_t *cfa_action)
1136 uint8_t sub_type = BNXT_ULP_RESOURCE_SUB_TYPE_INDEX_TYPE_VFR_CFA_ACTION;
1140 rc = ulp_flow_db_resource_hndl_get(ulp_ctx,
1141 BNXT_ULP_FDB_TYPE_DEFAULT,
1143 BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE,
1146 BNXT_TF_DBG(ERR, "CFA Action ptr not found for flow id %u\n",
1155 * Allocate the entry in the parent-child database
1157 * ulp_ctxt [in] Ptr to ulp_context
1158 * fid [in] The flow id to the flow entry
1160 * returns index on success and negative on failure.
1163 ulp_flow_db_parent_flow_alloc(struct bnxt_ulp_context *ulp_ctxt,
1166 struct bnxt_ulp_flow_db *flow_db;
1167 struct ulp_fdb_parent_child_db *p_pdb;
1168 uint32_t idx, free_idx = 0;
1170 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
1172 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
1176 /* check for max flows */
1177 if (fid >= flow_db->flow_tbl.num_flows || !fid) {
1178 BNXT_TF_DBG(ERR, "Invalid flow index\n");
1182 /* No support for parent child db then just exit */
1183 if (!flow_db->parent_child_db.entries_count) {
1184 BNXT_TF_DBG(ERR, "parent child db not supported\n");
1188 p_pdb = &flow_db->parent_child_db;
1189 for (idx = 0; idx <= p_pdb->entries_count; idx++) {
1190 if (p_pdb->parent_flow_tbl[idx].parent_fid == fid) {
1191 BNXT_TF_DBG(ERR, "fid is already allocated\n");
1194 if (!p_pdb->parent_flow_tbl[idx].parent_fid && !free_idx)
1199 BNXT_TF_DBG(ERR, "parent child db is full\n");
1204 /* set the Fid in the parent child */
1205 p_pdb->parent_flow_tbl[free_idx].parent_fid = fid;
1210 * Free the entry in the parent-child database
1212 * ulp_ctxt [in] Ptr to ulp_context
1213 * fid [in] The flow id to the flow entry
1215 * returns 0 on success and negative on failure.
1218 ulp_flow_db_parent_flow_free(struct bnxt_ulp_context *ulp_ctxt,
1221 struct bnxt_ulp_flow_db *flow_db;
1222 struct ulp_fdb_parent_child_db *p_pdb;
1225 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
1227 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
1231 /* check for max flows */
1232 if (fid >= flow_db->flow_tbl.num_flows || !fid) {
1233 BNXT_TF_DBG(ERR, "Invalid flow index\n");
1237 /* No support for parent child db then just exit */
1238 if (!flow_db->parent_child_db.entries_count) {
1239 BNXT_TF_DBG(ERR, "parent child db not supported\n");
1243 p_pdb = &flow_db->parent_child_db;
1244 for (idx = 0; idx <= p_pdb->entries_count; idx++) {
1245 if (p_pdb->parent_flow_tbl[idx].parent_fid == fid) {
1246 /* free the contents */
1247 p_pdb->parent_flow_tbl[idx].parent_fid = 0;
1248 memset(p_pdb->parent_flow_tbl[idx].child_fid_bitset,
1249 0, p_pdb->child_bitset_size);
1253 BNXT_TF_DBG(ERR, "parent entry not found = %x\n", fid);
1258 * Set or reset the child flow in the parent-child database
1260 * ulp_ctxt [in] Ptr to ulp_context
1261 * parent_fid [in] The flow id of the parent flow entry
1262 * child_fid [in] The flow id of the child flow entry
1263 * set_flag [in] Use 1 for setting child, 0 to reset
1265 * returns zero on success and negative on failure.
1268 ulp_flow_db_parent_child_flow_set(struct bnxt_ulp_context *ulp_ctxt,
1269 uint32_t parent_fid,
1273 struct bnxt_ulp_flow_db *flow_db;
1274 struct ulp_fdb_parent_child_db *p_pdb;
1275 uint32_t idx, a_idx;
1278 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
1280 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
1284 /* check for fid validity */
1285 if (parent_fid >= flow_db->flow_tbl.num_flows || !parent_fid) {
1286 BNXT_TF_DBG(ERR, "Invalid parent flow index %x\n", parent_fid);
1290 /* check for fid validity */
1291 if (child_fid >= flow_db->flow_tbl.num_flows || !child_fid) {
1292 BNXT_TF_DBG(ERR, "Invalid child flow index %x\n", child_fid);
1296 /* No support for parent child db then just exit */
1297 if (!flow_db->parent_child_db.entries_count) {
1298 BNXT_TF_DBG(ERR, "parent child db not supported\n");
1302 p_pdb = &flow_db->parent_child_db;
1303 a_idx = child_fid / ULP_INDEX_BITMAP_SIZE;
1304 for (idx = 0; idx <= p_pdb->entries_count; idx++) {
1305 if (p_pdb->parent_flow_tbl[idx].parent_fid == parent_fid) {
1306 t = p_pdb->parent_flow_tbl[idx].child_fid_bitset;
1308 ULP_INDEX_BITMAP_SET(t[a_idx], child_fid);
1310 ULP_INDEX_BITMAP_RESET(t[a_idx], child_fid);
1314 BNXT_TF_DBG(ERR, "Unable to set the parent-child flow %x:%x\n",
1315 parent_fid, child_fid);
1320 * Get the parent index from the parent-child database
1322 * ulp_ctxt [in] Ptr to ulp_context
1323 * parent_fid [in] The flow id of the parent flow entry
1324 * parent_idx [out] The parent index of parent flow entry
1326 * returns zero on success and negative on failure.
1329 ulp_flow_db_parent_flow_idx_get(struct bnxt_ulp_context *ulp_ctxt,
1330 uint32_t parent_fid,
1331 uint32_t *parent_idx)
1333 struct bnxt_ulp_flow_db *flow_db;
1334 struct ulp_fdb_parent_child_db *p_pdb;
1337 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
1339 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
1343 /* check for fid validity */
1344 if (parent_fid >= flow_db->flow_tbl.num_flows || !parent_fid) {
1345 BNXT_TF_DBG(ERR, "Invalid parent flow index %x\n", parent_fid);
1349 /* No support for parent child db then just exit */
1350 if (!flow_db->parent_child_db.entries_count) {
1351 BNXT_TF_DBG(ERR, "parent child db not supported\n");
1355 p_pdb = &flow_db->parent_child_db;
1356 for (idx = 0; idx <= p_pdb->entries_count; idx++) {
1357 if (p_pdb->parent_flow_tbl[idx].parent_fid == parent_fid) {
1362 BNXT_TF_DBG(ERR, "Unable to get the parent flow %x\n", parent_fid);
1367 * Get the next child flow in the parent-child database
1369 * ulp_ctxt [in] Ptr to ulp_context
1370 * parent_fid [in] The flow id of the parent flow entry
1371 * child_fid [in/out] The flow id of the child flow entry
1373 * returns zero on success and negative on failure.
1374 * Pass child_fid as zero for first entry.
1377 ulp_flow_db_parent_child_flow_next_entry_get(struct bnxt_ulp_flow_db *flow_db,
1378 uint32_t parent_idx,
1379 uint32_t *child_fid)
1381 struct ulp_fdb_parent_child_db *p_pdb;
1382 uint32_t idx, s_idx, mod_fid;
1383 uint32_t next_fid = *child_fid;
1384 uint64_t *child_bitset;
1387 /* check for fid validity */
1388 p_pdb = &flow_db->parent_child_db;
1389 if (parent_idx >= p_pdb->entries_count ||
1390 !p_pdb->parent_flow_tbl[parent_idx].parent_fid) {
1391 BNXT_TF_DBG(ERR, "Invalid parent flow index %x\n", parent_idx);
1395 child_bitset = p_pdb->parent_flow_tbl[parent_idx].child_fid_bitset;
1397 /* increment the flow id to find the next valid flow id */
1399 if (next_fid >= flow_db->flow_tbl.num_flows)
1401 idx = next_fid / ULP_INDEX_BITMAP_SIZE;
1402 mod_fid = next_fid % ULP_INDEX_BITMAP_SIZE;
1404 while (!(bs = child_bitset[idx])) {
1406 if ((idx * ULP_INDEX_BITMAP_SIZE) >=
1407 flow_db->flow_tbl.num_flows)
1411 * remove the previous bits in the bitset bs to find the
1412 * next non zero bit in the bitset. This needs to be done
1413 * only if the idx is same as he one you started.
1416 bs &= (-1UL >> mod_fid);
1417 next_fid = (idx * ULP_INDEX_BITMAP_SIZE) + __builtin_clzl(bs);
1418 if (*child_fid >= next_fid) {
1419 BNXT_TF_DBG(ERR, "Parent Child Database is corrupt\n");
1422 idx = next_fid / ULP_INDEX_BITMAP_SIZE;
1423 } while (!ULP_INDEX_BITMAP_GET(child_bitset[idx], next_fid));
1424 *child_fid = next_fid;
1429 * Orphan the child flow entry
1430 * This is called only for child flows that have
1431 * BNXT_ULP_RESOURCE_FUNC_CHILD_FLOW resource
1433 * ulp_ctxt [in] Ptr to ulp_context
1434 * flow_type [in] Specify it is regular or default flow
1435 * fid [in] The index to the flow entry
1437 * Returns 0 on success and negative on failure.
1440 ulp_flow_db_child_flow_reset(struct bnxt_ulp_context *ulp_ctxt,
1441 enum bnxt_ulp_fdb_type flow_type,
1444 struct bnxt_ulp_flow_db *flow_db;
1445 struct bnxt_ulp_flow_tbl *flow_tbl;
1446 struct ulp_fdb_resource_info *fid_res;
1447 uint32_t res_id = 0;
1449 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
1451 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
1455 if (flow_type > BNXT_ULP_FDB_TYPE_DEFAULT) {
1456 BNXT_TF_DBG(ERR, "Invalid flow type\n");
1460 flow_tbl = &flow_db->flow_tbl;
1461 /* check for max flows */
1462 if (fid >= flow_tbl->num_flows || !fid) {
1463 BNXT_TF_DBG(ERR, "Invalid flow index %x\n", fid);
1467 /* check if the flow is active or not */
1468 if (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type, fid)) {
1469 BNXT_TF_DBG(ERR, "flow does not exist\n");
1473 /* Iterate the resource to get the resource handle */
1476 fid_res = &flow_tbl->flow_resources[res_id];
1477 if (ulp_flow_db_resource_func_get(fid_res) ==
1478 BNXT_ULP_RESOURCE_FUNC_CHILD_FLOW) {
1479 /* invalidate the resource details */
1480 fid_res->resource_hndl = 0;
1484 ULP_FLOW_DB_RES_NXT_SET(res_id, fid_res->nxt_resource_idx);
1491 * Create parent flow in the parent flow tbl
1493 * parms [in] Ptr to mapper params
1495 * Returns 0 on success and negative on failure.
1498 ulp_flow_db_parent_flow_create(struct bnxt_ulp_mapper_parms *parms)
1500 struct ulp_flow_db_res_params fid_parms;
1503 /* create the child flow entry in parent flow table */
1504 fid_idx = ulp_flow_db_parent_flow_alloc(parms->ulp_ctx, parms->fid);
1506 BNXT_TF_DBG(ERR, "Error in creating parent flow fid %x\n",
1511 /* Add the parent details in the resource list of the flow */
1512 memset(&fid_parms, 0, sizeof(fid_parms));
1513 fid_parms.resource_func = BNXT_ULP_RESOURCE_FUNC_PARENT_FLOW;
1514 fid_parms.resource_hndl = fid_idx;
1515 fid_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO;
1516 if (ulp_flow_db_resource_add(parms->ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR,
1517 parms->fid, &fid_parms)) {
1518 BNXT_TF_DBG(ERR, "Error in adding flow res for fid %x\n",
1526 * Create child flow in the parent flow tbl
1528 * parms [in] Ptr to mapper params
1530 * Returns 0 on success and negative on failure.
1533 ulp_flow_db_child_flow_create(struct bnxt_ulp_mapper_parms *parms)
1535 struct ulp_flow_db_res_params fid_parms;
1538 /* create the parent flow entry in parent flow table */
1539 rc = ulp_flow_db_parent_child_flow_set(parms->ulp_ctx,
1543 BNXT_TF_DBG(ERR, "Error in setting child fid %x\n", parms->fid);
1547 /* Add the parent details in the resource list of the flow */
1548 memset(&fid_parms, 0, sizeof(fid_parms));
1549 fid_parms.resource_func = BNXT_ULP_RESOURCE_FUNC_CHILD_FLOW;
1550 fid_parms.resource_hndl = parms->parent_fid;
1551 fid_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO;
1552 if (ulp_flow_db_resource_add(parms->ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR,
1553 parms->fid, &fid_parms)) {
1554 BNXT_TF_DBG(ERR, "Error in adding flow res for fid %x\n",