1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2014-2020 Broadcom
6 #include <rte_malloc.h>
8 #include "bnxt_tf_common.h"
9 #include "ulp_flow_db.h"
10 #include "ulp_utils.h"
11 #include "ulp_template_struct.h"
12 #include "ulp_mapper.h"
14 #define ULP_FLOW_DB_RES_DIR_BIT 31
15 #define ULP_FLOW_DB_RES_DIR_MASK 0x80000000
16 #define ULP_FLOW_DB_RES_FUNC_BITS 28
17 #define ULP_FLOW_DB_RES_FUNC_MASK 0x70000000
18 #define ULP_FLOW_DB_RES_NXT_MASK 0x0FFFFFFF
19 #define ULP_FLOW_DB_RES_FUNC_UPPER 5
20 #define ULP_FLOW_DB_RES_FUNC_NEED_LOWER 0x80
21 #define ULP_FLOW_DB_RES_FUNC_LOWER_MASK 0x1F
23 /* Macro to copy the nxt_resource_idx */
24 #define ULP_FLOW_DB_RES_NXT_SET(dst, src) {(dst) |= ((src) &\
25 ULP_FLOW_DB_RES_NXT_MASK); }
26 #define ULP_FLOW_DB_RES_NXT_RESET(dst) ((dst) &= ~(ULP_FLOW_DB_RES_NXT_MASK))
29 * Helper function to set the bit in the active flow table
30 * No validation is done in this function.
32 * flow_tbl [in] Ptr to flow table
33 * idx [in] The index to bit to be set or reset.
34 * flag [in] 1 to set and 0 to reset.
39 ulp_flow_db_active_flow_set(struct bnxt_ulp_flow_tbl *flow_tbl,
43 uint32_t active_index;
45 active_index = idx / ULP_INDEX_BITMAP_SIZE;
47 ULP_INDEX_BITMAP_SET(flow_tbl->active_flow_tbl[active_index],
50 ULP_INDEX_BITMAP_RESET(flow_tbl->active_flow_tbl[active_index],
55 * Helper function to allocate the flow table and initialize
56 * is set.No validation being done in this function.
58 * flow_tbl [in] Ptr to flow table
59 * idx [in] The index to bit to be set or reset.
61 * returns 1 on set or 0 if not set.
64 ulp_flow_db_active_flow_is_set(struct bnxt_ulp_flow_tbl *flow_tbl,
67 uint32_t active_index;
69 active_index = idx / ULP_INDEX_BITMAP_SIZE;
70 return ULP_INDEX_BITMAP_GET(flow_tbl->active_flow_tbl[active_index],
75 * Helper function to copy the resource params to resource info
76 * No validation being done in this function.
78 * resource_info [out] Ptr to resource information
79 * params [in] The input params from the caller
83 ulp_flow_db_res_params_to_info(struct ulp_fdb_resource_info *resource_info,
84 struct ulp_flow_db_res_params *params)
86 uint32_t resource_func;
88 resource_info->nxt_resource_idx |= ((params->direction <<
89 ULP_FLOW_DB_RES_DIR_BIT) &
90 ULP_FLOW_DB_RES_DIR_MASK);
91 resource_func = (params->resource_func >> ULP_FLOW_DB_RES_FUNC_UPPER);
92 resource_info->nxt_resource_idx |= ((resource_func <<
93 ULP_FLOW_DB_RES_FUNC_BITS) &
94 ULP_FLOW_DB_RES_FUNC_MASK);
96 if (params->resource_func & ULP_FLOW_DB_RES_FUNC_NEED_LOWER) {
97 /* Break the resource func into two parts */
98 resource_func = (params->resource_func &
99 ULP_FLOW_DB_RES_FUNC_LOWER_MASK);
100 resource_info->resource_func_lower = resource_func;
103 /* Store the handle as 64bit only for EM table entries */
104 if (params->resource_func != BNXT_ULP_RESOURCE_FUNC_EM_TABLE) {
105 resource_info->resource_hndl = (uint32_t)params->resource_hndl;
106 resource_info->resource_type = params->resource_type;
107 resource_info->resource_sub_type = params->resource_sub_type;
108 resource_info->reserved = params->reserved;
110 resource_info->resource_em_handle = params->resource_hndl;
115 * Helper function to copy the resource params to resource info
116 * No validation being done in this function.
118 * resource_info [in] Ptr to resource information
119 * params [out] The output params to the caller
124 ulp_flow_db_res_info_to_params(struct ulp_fdb_resource_info *resource_info,
125 struct ulp_flow_db_res_params *params)
127 uint8_t resource_func_upper;
129 memset(params, 0, sizeof(struct ulp_flow_db_res_params));
130 params->direction = ((resource_info->nxt_resource_idx &
131 ULP_FLOW_DB_RES_DIR_MASK) >>
132 ULP_FLOW_DB_RES_DIR_BIT);
133 resource_func_upper = (((resource_info->nxt_resource_idx &
134 ULP_FLOW_DB_RES_FUNC_MASK) >>
135 ULP_FLOW_DB_RES_FUNC_BITS) <<
136 ULP_FLOW_DB_RES_FUNC_UPPER);
138 /* The reource func is split into upper and lower */
139 if (resource_func_upper & ULP_FLOW_DB_RES_FUNC_NEED_LOWER)
140 params->resource_func = (resource_func_upper |
141 resource_info->resource_func_lower);
143 params->resource_func = resource_func_upper;
145 if (params->resource_func == BNXT_ULP_RESOURCE_FUNC_EM_TABLE) {
146 params->resource_hndl = resource_info->resource_em_handle;
147 } else if (params->resource_func & ULP_FLOW_DB_RES_FUNC_NEED_LOWER) {
148 params->resource_hndl = resource_info->resource_hndl;
149 params->resource_type = resource_info->resource_type;
150 params->resource_sub_type = resource_info->resource_sub_type;
151 params->reserved = resource_info->reserved;
156 * Helper function to allocate the flow table and initialize
157 * the stack for allocation operations.
159 * flow_db [in] Ptr to flow database structure
160 * tbl_idx [in] The index to table creation.
162 * Returns 0 on success or negative number on failure.
165 ulp_flow_db_alloc_resource(struct bnxt_ulp_flow_db *flow_db,
166 enum bnxt_ulp_flow_db_tables tbl_idx)
169 struct bnxt_ulp_flow_tbl *flow_tbl;
172 flow_tbl = &flow_db->flow_tbl[tbl_idx];
174 size = sizeof(struct ulp_fdb_resource_info) * flow_tbl->num_resources;
175 flow_tbl->flow_resources =
176 rte_zmalloc("ulp_fdb_resource_info", size, 0);
178 if (!flow_tbl->flow_resources) {
179 BNXT_TF_DBG(ERR, "Failed to alloc memory for flow table\n");
182 size = sizeof(uint32_t) * flow_tbl->num_resources;
183 flow_tbl->flow_tbl_stack = rte_zmalloc("flow_tbl_stack", size, 0);
184 if (!flow_tbl->flow_tbl_stack) {
185 BNXT_TF_DBG(ERR, "Failed to alloc memory flow tbl stack\n");
188 size = (flow_tbl->num_flows / sizeof(uint64_t)) + 1;
189 flow_tbl->active_flow_tbl = rte_zmalloc("active flow tbl", size, 0);
190 if (!flow_tbl->active_flow_tbl) {
191 BNXT_TF_DBG(ERR, "Failed to alloc memory active tbl\n");
195 /* Initialize the stack table. */
196 for (idx = 0; idx < flow_tbl->num_resources; idx++)
197 flow_tbl->flow_tbl_stack[idx] = idx;
199 /* Ignore the first element in the list. */
200 flow_tbl->head_index = 1;
201 /* Tail points to the last entry in the list. */
202 flow_tbl->tail_index = flow_tbl->num_resources - 1;
207 * Helper function to deallocate the flow table.
209 * flow_db [in] Ptr to flow database structure
210 * tbl_idx [in] The index to table creation.
215 ulp_flow_db_dealloc_resource(struct bnxt_ulp_flow_db *flow_db,
216 enum bnxt_ulp_flow_db_tables tbl_idx)
218 struct bnxt_ulp_flow_tbl *flow_tbl;
220 flow_tbl = &flow_db->flow_tbl[tbl_idx];
222 /* Free all the allocated tables in the flow table. */
223 if (flow_tbl->active_flow_tbl) {
224 rte_free(flow_tbl->active_flow_tbl);
225 flow_tbl->active_flow_tbl = NULL;
228 if (flow_tbl->flow_tbl_stack) {
229 rte_free(flow_tbl->flow_tbl_stack);
230 flow_tbl->flow_tbl_stack = NULL;
233 if (flow_tbl->flow_resources) {
234 rte_free(flow_tbl->flow_resources);
235 flow_tbl->flow_resources = NULL;
240 * Helper function to add function id to the flow table
242 * flow_db [in] Ptr to flow table
243 * flow_id [in] The flow id of the flow
244 * func_id [in] The func_id to be set, for reset pass zero
249 ulp_flow_db_func_id_set(struct bnxt_ulp_flow_db *flow_db,
253 /* set the function id in the function table */
254 if (flow_id < flow_db->func_id_tbl_size)
255 flow_db->func_id_tbl[flow_id] = func_id;
256 else /* This should never happen */
257 BNXT_TF_DBG(ERR, "Invalid flow id, flowdb corrupt\n");
261 * Initialize the flow database. Memory is allocated in this
262 * call and assigned to the flow database.
264 * ulp_ctxt [in] Ptr to ulp context
266 * Returns 0 on success or negative number on failure.
268 int32_t ulp_flow_db_init(struct bnxt_ulp_context *ulp_ctxt)
270 struct bnxt_ulp_device_params *dparms;
271 struct bnxt_ulp_flow_tbl *flow_tbl;
272 struct bnxt_ulp_flow_db *flow_db;
275 /* Get the dev specific number of flows that needed to be supported. */
276 if (bnxt_ulp_cntxt_dev_id_get(ulp_ctxt, &dev_id)) {
277 BNXT_TF_DBG(ERR, "Invalid device id\n");
281 dparms = bnxt_ulp_device_params_get(dev_id);
283 BNXT_TF_DBG(ERR, "could not fetch the device params\n");
287 flow_db = rte_zmalloc("bnxt_ulp_flow_db",
288 sizeof(struct bnxt_ulp_flow_db), 0);
291 "Failed to allocate memory for flow table ptr\n");
295 /* Attach the flow database to the ulp context. */
296 bnxt_ulp_cntxt_ptr2_flow_db_set(ulp_ctxt, flow_db);
298 /* Populate the regular flow table limits. */
299 flow_tbl = &flow_db->flow_tbl[BNXT_ULP_REGULAR_FLOW_TABLE];
300 flow_tbl->num_flows = dparms->num_flows + 1;
301 flow_tbl->num_resources = (flow_tbl->num_flows *
302 dparms->num_resources_per_flow);
304 /* Populate the default flow table limits. */
305 flow_tbl = &flow_db->flow_tbl[BNXT_ULP_DEFAULT_FLOW_TABLE];
306 flow_tbl->num_flows = BNXT_FLOW_DB_DEFAULT_NUM_FLOWS + 1;
307 flow_tbl->num_resources = (flow_tbl->num_flows *
308 BNXT_FLOW_DB_DEFAULT_NUM_RESOURCES);
310 /* Allocate the resource for the regular flow table. */
311 if (ulp_flow_db_alloc_resource(flow_db, BNXT_ULP_REGULAR_FLOW_TABLE))
313 if (ulp_flow_db_alloc_resource(flow_db, BNXT_ULP_DEFAULT_FLOW_TABLE))
316 /* add 1 since we are not using index 0 for flow id */
317 flow_db->func_id_tbl_size = dparms->num_flows + 1;
318 /* Allocate the function Id table */
319 flow_db->func_id_tbl = rte_zmalloc("bnxt_ulp_flow_db_func_id_table",
320 flow_db->func_id_tbl_size *
321 sizeof(uint16_t), 0);
322 if (!flow_db->func_id_tbl) {
324 "Failed to allocate mem for flow table func id\n");
327 /* All good so return. */
330 ulp_flow_db_deinit(ulp_ctxt);
335 * Deinitialize the flow database. Memory is deallocated in
336 * this call and all flows should have been purged before this
339 * ulp_ctxt [in] Ptr to ulp context
341 * Returns 0 on success.
343 int32_t ulp_flow_db_deinit(struct bnxt_ulp_context *ulp_ctxt)
345 struct bnxt_ulp_flow_db *flow_db;
347 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
349 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
353 /* Detach the flow database from the ulp context. */
354 bnxt_ulp_cntxt_ptr2_flow_db_set(ulp_ctxt, NULL);
356 /* Free up all the memory. */
357 ulp_flow_db_dealloc_resource(flow_db, BNXT_ULP_REGULAR_FLOW_TABLE);
358 ulp_flow_db_dealloc_resource(flow_db, BNXT_ULP_DEFAULT_FLOW_TABLE);
359 rte_free(flow_db->func_id_tbl);
366 * Allocate the flow database entry
368 * ulp_ctxt [in] Ptr to ulp_context
369 * tbl_idx [in] Specify it is regular or default flow
370 * fid [out] The index to the flow entry
372 * returns 0 on success and negative on failure.
374 int32_t ulp_flow_db_fid_alloc(struct bnxt_ulp_context *ulp_ctxt,
375 enum bnxt_ulp_flow_db_tables tbl_idx,
379 struct bnxt_ulp_flow_db *flow_db;
380 struct bnxt_ulp_flow_tbl *flow_tbl;
382 *fid = 0; /* Initialize fid to invalid value */
383 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
385 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
389 flow_tbl = &flow_db->flow_tbl[tbl_idx];
390 /* check for max flows */
391 if (flow_tbl->num_flows <= flow_tbl->head_index) {
392 BNXT_TF_DBG(ERR, "Flow database has reached max flows\n");
395 if (flow_tbl->tail_index <= (flow_tbl->head_index + 1)) {
396 BNXT_TF_DBG(ERR, "Flow database has reached max resources\n");
399 *fid = flow_tbl->flow_tbl_stack[flow_tbl->head_index];
400 flow_tbl->head_index++;
401 ulp_flow_db_active_flow_set(flow_tbl, *fid, 1);
403 /* The function id update is only valid for regular flow table */
404 if (tbl_idx == BNXT_ULP_REGULAR_FLOW_TABLE)
405 ulp_flow_db_func_id_set(flow_db, *fid, func_id);
407 /* all good, return success */
412 * Allocate the flow database entry.
413 * The params->critical_resource has to be set to 0 to allocate a new resource.
415 * ulp_ctxt [in] Ptr to ulp_context
416 * tbl_idx [in] Specify it is regular or default flow
417 * fid [in] The index to the flow entry
418 * params [in] The contents to be copied into resource
420 * returns 0 on success and negative on failure.
422 int32_t ulp_flow_db_resource_add(struct bnxt_ulp_context *ulp_ctxt,
423 enum bnxt_ulp_flow_db_tables tbl_idx,
425 struct ulp_flow_db_res_params *params)
427 struct bnxt_ulp_flow_db *flow_db;
428 struct bnxt_ulp_flow_tbl *flow_tbl;
429 struct ulp_fdb_resource_info *resource, *fid_resource;
432 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
434 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
438 if (tbl_idx >= BNXT_ULP_FLOW_TABLE_MAX) {
439 BNXT_TF_DBG(ERR, "Invalid table index\n");
442 flow_tbl = &flow_db->flow_tbl[tbl_idx];
444 /* check for max flows */
445 if (fid >= flow_tbl->num_flows || !fid) {
446 BNXT_TF_DBG(ERR, "Invalid flow index\n");
450 /* check if the flow is active or not */
451 if (!ulp_flow_db_active_flow_is_set(flow_tbl, fid)) {
452 BNXT_TF_DBG(ERR, "flow does not exist\n");
456 /* check for max resource */
457 if ((flow_tbl->head_index + 1) >= flow_tbl->tail_index) {
458 BNXT_TF_DBG(ERR, "Flow db has reached max resources\n");
461 fid_resource = &flow_tbl->flow_resources[fid];
463 if (!params->critical_resource) {
464 /* Not the critical_resource so allocate a resource */
465 idx = flow_tbl->flow_tbl_stack[flow_tbl->tail_index];
466 resource = &flow_tbl->flow_resources[idx];
467 flow_tbl->tail_index--;
469 /* Update the chain list of resource*/
470 ULP_FLOW_DB_RES_NXT_SET(resource->nxt_resource_idx,
471 fid_resource->nxt_resource_idx);
472 /* update the contents */
473 ulp_flow_db_res_params_to_info(resource, params);
474 ULP_FLOW_DB_RES_NXT_RESET(fid_resource->nxt_resource_idx);
475 ULP_FLOW_DB_RES_NXT_SET(fid_resource->nxt_resource_idx,
478 /* critical resource. Just update the fid resource */
479 ulp_flow_db_res_params_to_info(fid_resource, params);
482 /* all good, return success */
487 * Free the flow database entry.
488 * The params->critical_resource has to be set to 1 to free the first resource.
490 * ulp_ctxt [in] Ptr to ulp_context
491 * tbl_idx [in] Specify it is regular or default flow
492 * fid [in] The index to the flow entry
493 * params [in/out] The contents to be copied into params.
494 * Onlythe critical_resource needs to be set by the caller.
496 * Returns 0 on success and negative on failure.
498 int32_t ulp_flow_db_resource_del(struct bnxt_ulp_context *ulp_ctxt,
499 enum bnxt_ulp_flow_db_tables tbl_idx,
501 struct ulp_flow_db_res_params *params)
503 struct bnxt_ulp_flow_db *flow_db;
504 struct bnxt_ulp_flow_tbl *flow_tbl;
505 struct ulp_fdb_resource_info *nxt_resource, *fid_resource;
506 uint32_t nxt_idx = 0;
508 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
510 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
514 if (tbl_idx >= BNXT_ULP_FLOW_TABLE_MAX) {
515 BNXT_TF_DBG(ERR, "Invalid table index\n");
518 flow_tbl = &flow_db->flow_tbl[tbl_idx];
520 /* check for max flows */
521 if (fid >= flow_tbl->num_flows || !fid) {
522 BNXT_TF_DBG(ERR, "Invalid flow index\n");
526 /* check if the flow is active or not */
527 if (!ulp_flow_db_active_flow_is_set(flow_tbl, fid)) {
528 BNXT_TF_DBG(ERR, "flow does not exist\n");
532 fid_resource = &flow_tbl->flow_resources[fid];
533 if (!params->critical_resource) {
534 /* Not the critical resource so free the resource */
535 ULP_FLOW_DB_RES_NXT_SET(nxt_idx,
536 fid_resource->nxt_resource_idx);
538 /* reached end of resources */
541 nxt_resource = &flow_tbl->flow_resources[nxt_idx];
543 /* connect the fid resource to the next resource */
544 ULP_FLOW_DB_RES_NXT_RESET(fid_resource->nxt_resource_idx);
545 ULP_FLOW_DB_RES_NXT_SET(fid_resource->nxt_resource_idx,
546 nxt_resource->nxt_resource_idx);
548 /* update the contents to be given to caller */
549 ulp_flow_db_res_info_to_params(nxt_resource, params);
551 /* Delete the nxt_resource */
552 memset(nxt_resource, 0, sizeof(struct ulp_fdb_resource_info));
554 /* add it to the free list */
555 flow_tbl->tail_index++;
556 if (flow_tbl->tail_index >= flow_tbl->num_resources) {
557 BNXT_TF_DBG(ERR, "FlowDB:Tail reached max\n");
560 flow_tbl->flow_tbl_stack[flow_tbl->tail_index] = nxt_idx;
563 /* Critical resource. copy the contents and exit */
564 ulp_flow_db_res_info_to_params(fid_resource, params);
565 ULP_FLOW_DB_RES_NXT_SET(nxt_idx,
566 fid_resource->nxt_resource_idx);
567 memset(fid_resource, 0, sizeof(struct ulp_fdb_resource_info));
568 ULP_FLOW_DB_RES_NXT_SET(fid_resource->nxt_resource_idx,
572 /* all good, return success */
577 * Free the flow database entry
579 * ulp_ctxt [in] Ptr to ulp_context
580 * tbl_idx [in] Specify it is regular or default flow
581 * fid [in] The index to the flow entry
583 * returns 0 on success and negative on failure.
585 int32_t ulp_flow_db_fid_free(struct bnxt_ulp_context *ulp_ctxt,
586 enum bnxt_ulp_flow_db_tables tbl_idx,
589 struct bnxt_ulp_flow_db *flow_db;
590 struct bnxt_ulp_flow_tbl *flow_tbl;
592 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
594 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
598 if (tbl_idx >= BNXT_ULP_FLOW_TABLE_MAX) {
599 BNXT_TF_DBG(ERR, "Invalid table index\n");
603 flow_tbl = &flow_db->flow_tbl[tbl_idx];
605 /* check for limits of fid */
606 if (fid >= flow_tbl->num_flows || !fid) {
607 BNXT_TF_DBG(ERR, "Invalid flow index\n");
611 /* check if the flow is active or not */
612 if (!ulp_flow_db_active_flow_is_set(flow_tbl, fid)) {
613 BNXT_TF_DBG(ERR, "flow does not exist\n");
616 flow_tbl->head_index--;
617 if (!flow_tbl->head_index) {
618 BNXT_TF_DBG(ERR, "FlowDB: Head Ptr is zero\n");
621 flow_tbl->flow_tbl_stack[flow_tbl->head_index] = fid;
622 ulp_flow_db_active_flow_set(flow_tbl, fid, 0);
623 if (tbl_idx == BNXT_ULP_REGULAR_FLOW_TABLE)
624 ulp_flow_db_func_id_set(flow_db, fid, 0);
626 /* all good, return success */
631 * Get the flow database entry details
633 * ulp_ctxt [in] Ptr to ulp_context
634 * tbl_idx [in] Specify it is regular or default flow
635 * fid [in] The index to the flow entry
636 * nxt_idx [in/out] the index to the next entry
637 * params [out] The contents to be copied into params.
639 * returns 0 on success and negative on failure.
641 int32_t ulp_flow_db_resource_get(struct bnxt_ulp_context *ulp_ctxt,
642 enum bnxt_ulp_flow_db_tables tbl_idx,
645 struct ulp_flow_db_res_params *params)
647 struct bnxt_ulp_flow_db *flow_db;
648 struct bnxt_ulp_flow_tbl *flow_tbl;
649 struct ulp_fdb_resource_info *nxt_resource, *fid_resource;
651 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
653 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
657 if (tbl_idx >= BNXT_ULP_FLOW_TABLE_MAX) {
658 BNXT_TF_DBG(ERR, "Invalid table index\n");
662 flow_tbl = &flow_db->flow_tbl[tbl_idx];
664 /* check for limits of fid */
665 if (fid >= flow_tbl->num_flows || !fid) {
666 BNXT_TF_DBG(ERR, "Invalid flow index\n");
670 /* check if the flow is active or not */
671 if (!ulp_flow_db_active_flow_is_set(flow_tbl, fid)) {
672 BNXT_TF_DBG(ERR, "flow does not exist\n");
677 fid_resource = &flow_tbl->flow_resources[fid];
678 ulp_flow_db_res_info_to_params(fid_resource, params);
679 ULP_FLOW_DB_RES_NXT_SET(*nxt_idx,
680 fid_resource->nxt_resource_idx);
682 nxt_resource = &flow_tbl->flow_resources[*nxt_idx];
683 ulp_flow_db_res_info_to_params(nxt_resource, params);
685 ULP_FLOW_DB_RES_NXT_SET(*nxt_idx,
686 nxt_resource->nxt_resource_idx);
689 /* all good, return success */
694 * Get the flow database entry iteratively
696 * flow_tbl [in] Ptr to flow table
697 * fid [in/out] The index to the flow entry
699 * returns 0 on success and negative on failure.
702 ulp_flow_db_next_entry_get(struct bnxt_ulp_flow_tbl *flowtbl,
705 uint32_t lfid = *fid;
706 uint32_t idx, s_idx, mod_fid;
710 /* increment the flow id to find the next valid flow id */
712 if (lfid >= flowtbl->num_flows)
714 idx = lfid / ULP_INDEX_BITMAP_SIZE;
715 mod_fid = lfid % ULP_INDEX_BITMAP_SIZE;
717 while (!(bs = flowtbl->active_flow_tbl[idx])) {
719 if ((idx * ULP_INDEX_BITMAP_SIZE) >= flowtbl->num_flows)
723 * remove the previous bits in the bitset bs to find the
724 * next non zero bit in the bitset. This needs to be done
725 * only if the idx is same as he one you started.
728 bs &= (-1UL >> mod_fid);
729 lfid = (idx * ULP_INDEX_BITMAP_SIZE) + __builtin_clzl(bs);
731 BNXT_TF_DBG(ERR, "Flow Database is corrupt\n");
734 } while (!ulp_flow_db_active_flow_is_set(flowtbl, lfid));
736 /* all good, return success */
742 * Flush all flows in the flow database.
744 * ulp_ctxt [in] Ptr to ulp context
745 * tbl_idx [in] The index to table
747 * returns 0 on success or negative number on failure
749 int32_t ulp_flow_db_flush_flows(struct bnxt_ulp_context *ulp_ctx,
753 struct bnxt_ulp_flow_db *flow_db;
754 struct bnxt_ulp_flow_tbl *flow_tbl;
757 BNXT_TF_DBG(ERR, "Invalid Argument\n");
761 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctx);
763 BNXT_TF_DBG(ERR, "Flow database not found\n");
766 flow_tbl = &flow_db->flow_tbl[idx];
767 while (!ulp_flow_db_next_entry_get(flow_tbl, &fid))
768 ulp_mapper_resources_free(ulp_ctx, fid, idx);
774 * Flush all flows in the flow database that belong to a device function.
776 * ulp_ctxt [in] Ptr to ulp context
777 * tbl_idx [in] The index to table
779 * returns 0 on success or negative number on failure
782 ulp_flow_db_function_flow_flush(struct bnxt_ulp_context *ulp_ctx,
785 uint32_t flow_id = 0;
786 struct bnxt_ulp_flow_db *flow_db;
787 struct bnxt_ulp_flow_tbl *flow_tbl;
789 if (!ulp_ctx || !func_id) {
790 BNXT_TF_DBG(ERR, "Invalid Argument\n");
794 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctx);
796 BNXT_TF_DBG(ERR, "Flow database not found\n");
799 flow_tbl = &flow_db->flow_tbl[BNXT_ULP_REGULAR_FLOW_TABLE];
800 while (!ulp_flow_db_next_entry_get(flow_tbl, &flow_id)) {
801 if (flow_db->func_id_tbl[flow_id] == func_id)
802 ulp_mapper_resources_free(ulp_ctx, flow_id,
803 BNXT_ULP_REGULAR_FLOW_TABLE);
810 * Flush all flows in the flow database that are associated with the session.
812 * ulp_ctxt [in] Ptr to ulp context
814 * returns 0 on success or negative number on failure
817 ulp_flow_db_session_flow_flush(struct bnxt_ulp_context *ulp_ctx)
820 * TBD: Tf core implementation of FW session flush shall change this
823 return ulp_flow_db_flush_flows(ulp_ctx, BNXT_ULP_REGULAR_FLOW_TABLE);
827 * Check that flow id matches the function id or not
829 * ulp_ctxt [in] Ptr to ulp context
830 * flow_db [in] Ptr to flow table
831 * func_id [in] The func_id to be set, for reset pass zero.
833 * returns true on success or false on failure
836 ulp_flow_db_validate_flow_func(struct bnxt_ulp_context *ulp_ctx,
840 struct bnxt_ulp_flow_db *flow_db;
842 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctx);
844 BNXT_TF_DBG(ERR, "Flow database not found\n");
848 /* set the function id in the function table */
849 if (flow_id < flow_db->func_id_tbl_size && func_id &&
850 flow_db->func_id_tbl[flow_id] == func_id)