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"
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],
93 ulp_flow_db_resource_func_get(struct ulp_fdb_resource_info *res_info)
97 func = (((res_info->nxt_resource_idx & ULP_FLOW_DB_RES_FUNC_MASK) >>
98 ULP_FLOW_DB_RES_FUNC_BITS) << ULP_FLOW_DB_RES_FUNC_UPPER);
99 /* The reource func is split into upper and lower */
100 if (func & ULP_FLOW_DB_RES_FUNC_NEED_LOWER)
101 return (func | res_info->resource_func_lower);
106 * Helper function to copy the resource params to resource info
107 * No validation being done in this function.
109 * resource_info [out] Ptr to resource information
110 * params [in] The input params from the caller
114 ulp_flow_db_res_params_to_info(struct ulp_fdb_resource_info *resource_info,
115 struct ulp_flow_db_res_params *params)
117 uint32_t resource_func;
119 resource_info->nxt_resource_idx |= ((params->direction <<
120 ULP_FLOW_DB_RES_DIR_BIT) &
121 ULP_FLOW_DB_RES_DIR_MASK);
122 resource_func = (params->resource_func >> ULP_FLOW_DB_RES_FUNC_UPPER);
123 resource_info->nxt_resource_idx |= ((resource_func <<
124 ULP_FLOW_DB_RES_FUNC_BITS) &
125 ULP_FLOW_DB_RES_FUNC_MASK);
127 if (params->resource_func & ULP_FLOW_DB_RES_FUNC_NEED_LOWER) {
128 /* Break the resource func into two parts */
129 resource_func = (params->resource_func &
130 ULP_FLOW_DB_RES_FUNC_LOWER_MASK);
131 resource_info->resource_func_lower = resource_func;
134 /* Store the handle as 64bit only for EM table entries */
135 if (params->resource_func != BNXT_ULP_RESOURCE_FUNC_EXT_EM_TABLE &&
136 params->resource_func != BNXT_ULP_RESOURCE_FUNC_INT_EM_TABLE) {
137 resource_info->resource_hndl = (uint32_t)params->resource_hndl;
138 resource_info->resource_type = params->resource_type;
139 resource_info->resource_sub_type = params->resource_sub_type;
140 resource_info->reserved = params->reserved;
142 resource_info->resource_em_handle = params->resource_hndl;
147 * Helper function to copy the resource params to resource info
148 * No validation being done in this function.
150 * resource_info [in] Ptr to resource information
151 * params [out] The output params to the caller
156 ulp_flow_db_res_info_to_params(struct ulp_fdb_resource_info *resource_info,
157 struct ulp_flow_db_res_params *params)
159 memset(params, 0, sizeof(struct ulp_flow_db_res_params));
160 params->direction = ((resource_info->nxt_resource_idx &
161 ULP_FLOW_DB_RES_DIR_MASK) >>
162 ULP_FLOW_DB_RES_DIR_BIT);
164 /* use the helper function to get the resource func */
165 params->resource_func = ulp_flow_db_resource_func_get(resource_info);
167 if (params->resource_func == BNXT_ULP_RESOURCE_FUNC_EXT_EM_TABLE ||
168 params->resource_func == BNXT_ULP_RESOURCE_FUNC_INT_EM_TABLE) {
169 params->resource_hndl = resource_info->resource_em_handle;
170 } else if (params->resource_func & ULP_FLOW_DB_RES_FUNC_NEED_LOWER) {
171 params->resource_hndl = resource_info->resource_hndl;
172 params->resource_type = resource_info->resource_type;
173 params->resource_sub_type = resource_info->resource_sub_type;
174 params->reserved = resource_info->reserved;
179 * Helper function to allocate the flow table and initialize
180 * the stack for allocation operations.
182 * flow_db [in] Ptr to flow database structure
184 * Returns 0 on success or negative number on failure.
187 ulp_flow_db_alloc_resource(struct bnxt_ulp_flow_db *flow_db)
190 struct bnxt_ulp_flow_tbl *flow_tbl;
193 flow_tbl = &flow_db->flow_tbl;
195 size = sizeof(struct ulp_fdb_resource_info) * flow_tbl->num_resources;
196 flow_tbl->flow_resources =
197 rte_zmalloc("ulp_fdb_resource_info", size, 0);
199 if (!flow_tbl->flow_resources) {
200 BNXT_TF_DBG(ERR, "Failed to alloc memory for flow table\n");
203 size = sizeof(uint32_t) * flow_tbl->num_resources;
204 flow_tbl->flow_tbl_stack = rte_zmalloc("flow_tbl_stack", size, 0);
205 if (!flow_tbl->flow_tbl_stack) {
206 BNXT_TF_DBG(ERR, "Failed to alloc memory flow tbl stack\n");
209 size = (flow_tbl->num_flows / sizeof(uint64_t)) + 1;
210 flow_tbl->active_reg_flows = rte_zmalloc("active reg flows", size, 0);
211 if (!flow_tbl->active_reg_flows) {
212 BNXT_TF_DBG(ERR, "Failed to alloc memory active reg flows\n");
216 flow_tbl->active_dflt_flows = rte_zmalloc("active dflt flows", size, 0);
217 if (!flow_tbl->active_dflt_flows) {
218 BNXT_TF_DBG(ERR, "Failed to alloc memory active dflt flows\n");
222 /* Initialize the stack table. */
223 for (idx = 0; idx < flow_tbl->num_resources; idx++)
224 flow_tbl->flow_tbl_stack[idx] = idx;
226 /* Ignore the first element in the list. */
227 flow_tbl->head_index = 1;
228 /* Tail points to the last entry in the list. */
229 flow_tbl->tail_index = flow_tbl->num_resources - 1;
234 * Helper function to deallocate the flow table.
236 * flow_db [in] Ptr to flow database structure
241 ulp_flow_db_dealloc_resource(struct bnxt_ulp_flow_db *flow_db)
243 struct bnxt_ulp_flow_tbl *flow_tbl = &flow_db->flow_tbl;
245 /* Free all the allocated tables in the flow table. */
246 if (flow_tbl->active_reg_flows) {
247 rte_free(flow_tbl->active_reg_flows);
248 flow_tbl->active_reg_flows = NULL;
250 if (flow_tbl->active_dflt_flows) {
251 rte_free(flow_tbl->active_dflt_flows);
252 flow_tbl->active_dflt_flows = NULL;
255 if (flow_tbl->flow_tbl_stack) {
256 rte_free(flow_tbl->flow_tbl_stack);
257 flow_tbl->flow_tbl_stack = NULL;
260 if (flow_tbl->flow_resources) {
261 rte_free(flow_tbl->flow_resources);
262 flow_tbl->flow_resources = NULL;
267 * Helper function to add function id to the flow table
269 * flow_db [in] Ptr to flow table
270 * flow_id [in] The flow id of the flow
271 * func_id [in] The func_id to be set, for reset pass zero
276 ulp_flow_db_func_id_set(struct bnxt_ulp_flow_db *flow_db,
280 /* set the function id in the function table */
281 if (flow_id < flow_db->func_id_tbl_size)
282 flow_db->func_id_tbl[flow_id] = func_id;
283 else /* This should never happen */
284 BNXT_TF_DBG(ERR, "Invalid flow id, flowdb corrupt\n");
288 * Initialize the flow database. Memory is allocated in this
289 * call and assigned to the flow database.
291 * ulp_ctxt [in] Ptr to ulp context
293 * Returns 0 on success or negative number on failure.
296 ulp_flow_db_init(struct bnxt_ulp_context *ulp_ctxt)
298 struct bnxt_ulp_device_params *dparms;
299 struct bnxt_ulp_flow_tbl *flow_tbl;
300 struct bnxt_ulp_flow_db *flow_db;
303 /* Get the dev specific number of flows that needed to be supported. */
304 if (bnxt_ulp_cntxt_dev_id_get(ulp_ctxt, &dev_id)) {
305 BNXT_TF_DBG(ERR, "Invalid device id\n");
309 dparms = bnxt_ulp_device_params_get(dev_id);
311 BNXT_TF_DBG(ERR, "could not fetch the device params\n");
315 flow_db = rte_zmalloc("bnxt_ulp_flow_db",
316 sizeof(struct bnxt_ulp_flow_db), 0);
319 "Failed to allocate memory for flow table ptr\n");
323 /* Attach the flow database to the ulp context. */
324 bnxt_ulp_cntxt_ptr2_flow_db_set(ulp_ctxt, flow_db);
326 /* Populate the regular flow table limits. */
327 flow_tbl = &flow_db->flow_tbl;
328 flow_tbl->num_flows = dparms->flow_db_num_entries + 1;
329 flow_tbl->num_resources = ((dparms->flow_db_num_entries + 1) *
330 dparms->num_resources_per_flow);
332 /* Include the default flow table limits. */
333 flow_tbl->num_flows += (BNXT_FLOW_DB_DEFAULT_NUM_FLOWS + 1);
334 flow_tbl->num_resources += ((BNXT_FLOW_DB_DEFAULT_NUM_FLOWS + 1) *
335 BNXT_FLOW_DB_DEFAULT_NUM_RESOURCES);
337 /* Allocate the resource for the flow table. */
338 if (ulp_flow_db_alloc_resource(flow_db))
341 /* add 1 since we are not using index 0 for flow id */
342 flow_db->func_id_tbl_size = flow_tbl->num_flows + 1;
343 /* Allocate the function Id table */
344 flow_db->func_id_tbl = rte_zmalloc("bnxt_ulp_flow_db_func_id_table",
345 flow_db->func_id_tbl_size *
346 sizeof(uint16_t), 0);
347 if (!flow_db->func_id_tbl) {
349 "Failed to allocate mem for flow table func id\n");
352 /* All good so return. */
355 ulp_flow_db_deinit(ulp_ctxt);
360 * Deinitialize the flow database. Memory is deallocated in
361 * this call and all flows should have been purged before this
364 * ulp_ctxt [in] Ptr to ulp context
366 * Returns 0 on success.
369 ulp_flow_db_deinit(struct bnxt_ulp_context *ulp_ctxt)
371 struct bnxt_ulp_flow_db *flow_db;
373 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
377 /* Detach the flow database from the ulp context. */
378 bnxt_ulp_cntxt_ptr2_flow_db_set(ulp_ctxt, NULL);
380 /* Free up all the memory. */
381 ulp_flow_db_dealloc_resource(flow_db);
382 rte_free(flow_db->func_id_tbl);
389 * Allocate the flow database entry
391 * ulp_ctxt [in] Ptr to ulp_context
392 * flow_type [in] - specify default or regular
393 * func_id [in].function id of the ingress port
394 * fid [out] The index to the flow entry
396 * returns 0 on success and negative on failure.
399 ulp_flow_db_fid_alloc(struct bnxt_ulp_context *ulp_ctxt,
400 enum bnxt_ulp_fdb_type flow_type,
404 struct bnxt_ulp_flow_db *flow_db;
405 struct bnxt_ulp_flow_tbl *flow_tbl;
407 *fid = 0; /* Initialize fid to invalid value */
408 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
410 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
414 if (flow_type > BNXT_ULP_FDB_TYPE_DEFAULT) {
415 BNXT_TF_DBG(ERR, "Invalid flow type\n");
419 flow_tbl = &flow_db->flow_tbl;
420 /* check for max flows */
421 if (flow_tbl->num_flows <= flow_tbl->head_index) {
422 BNXT_TF_DBG(ERR, "Flow database has reached max flows\n");
425 if (flow_tbl->tail_index <= (flow_tbl->head_index + 1)) {
426 BNXT_TF_DBG(ERR, "Flow database has reached max resources\n");
429 *fid = flow_tbl->flow_tbl_stack[flow_tbl->head_index];
430 flow_tbl->head_index++;
432 /* Set the flow type */
433 ulp_flow_db_active_flows_bit_set(flow_db, flow_type, *fid, 1);
435 /* function id update is only valid for regular flow table */
436 if (flow_type == BNXT_ULP_FDB_TYPE_REGULAR)
437 ulp_flow_db_func_id_set(flow_db, *fid, func_id);
444 * Allocate the flow database entry.
445 * The params->critical_resource has to be set to 0 to allocate a new resource.
447 * ulp_ctxt [in] Ptr to ulp_context
448 * flow_type [in] Specify it is regular or default flow
449 * fid [in] The index to the flow entry
450 * params [in] The contents to be copied into resource
452 * returns 0 on success and negative on failure.
455 ulp_flow_db_resource_add(struct bnxt_ulp_context *ulp_ctxt,
456 enum bnxt_ulp_fdb_type flow_type,
458 struct ulp_flow_db_res_params *params)
460 struct bnxt_ulp_flow_db *flow_db;
461 struct bnxt_ulp_flow_tbl *flow_tbl;
462 struct ulp_fdb_resource_info *resource, *fid_resource;
465 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
467 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
471 if (flow_type > BNXT_ULP_FDB_TYPE_DEFAULT) {
472 BNXT_TF_DBG(ERR, "Invalid flow type\n");
476 flow_tbl = &flow_db->flow_tbl;
477 /* check for max flows */
478 if (fid >= flow_tbl->num_flows || !fid) {
479 BNXT_TF_DBG(ERR, "Invalid flow index\n");
483 /* check if the flow is active or not */
484 if (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type, fid)) {
485 BNXT_TF_DBG(ERR, "flow does not exist\n");
489 /* check for max resource */
490 if ((flow_tbl->head_index + 1) >= flow_tbl->tail_index) {
491 BNXT_TF_DBG(ERR, "Flow db has reached max resources\n");
494 fid_resource = &flow_tbl->flow_resources[fid];
496 if (!params->critical_resource) {
497 /* Not the critical_resource so allocate a resource */
498 idx = flow_tbl->flow_tbl_stack[flow_tbl->tail_index];
499 resource = &flow_tbl->flow_resources[idx];
500 flow_tbl->tail_index--;
502 /* Update the chain list of resource*/
503 ULP_FLOW_DB_RES_NXT_SET(resource->nxt_resource_idx,
504 fid_resource->nxt_resource_idx);
505 /* update the contents */
506 ulp_flow_db_res_params_to_info(resource, params);
507 ULP_FLOW_DB_RES_NXT_RESET(fid_resource->nxt_resource_idx);
508 ULP_FLOW_DB_RES_NXT_SET(fid_resource->nxt_resource_idx,
511 /* critical resource. Just update the fid resource */
512 ulp_flow_db_res_params_to_info(fid_resource, params);
515 if (params->resource_type == TF_TBL_TYPE_ACT_STATS_64 &&
516 params->resource_sub_type ==
517 BNXT_ULP_RESOURCE_SUB_TYPE_INDEX_TYPE_INT_COUNT) {
518 /* Store the first HW counter ID for this table */
519 if (!ulp_fc_mgr_start_idx_isset(ulp_ctxt, params->direction))
520 ulp_fc_mgr_start_idx_set(ulp_ctxt, params->direction,
521 params->resource_hndl);
523 ulp_fc_mgr_cntr_set(ulp_ctxt, params->direction,
524 params->resource_hndl);
526 if (!ulp_fc_mgr_thread_isstarted(ulp_ctxt))
527 ulp_fc_mgr_thread_start(ulp_ctxt);
530 /* all good, return success */
535 * Free the flow database entry.
536 * The params->critical_resource has to be set to 1 to free the first resource.
538 * ulp_ctxt [in] Ptr to ulp_context
539 * flow_type [in] Specify it is regular or default flow
540 * fid [in] The index to the flow entry
541 * params [in/out] The contents to be copied into params.
542 * Onlythe critical_resource needs to be set by the caller.
544 * Returns 0 on success and negative on failure.
547 ulp_flow_db_resource_del(struct bnxt_ulp_context *ulp_ctxt,
548 enum bnxt_ulp_fdb_type flow_type,
550 struct ulp_flow_db_res_params *params)
552 struct bnxt_ulp_flow_db *flow_db;
553 struct bnxt_ulp_flow_tbl *flow_tbl;
554 struct ulp_fdb_resource_info *nxt_resource, *fid_resource;
555 uint32_t nxt_idx = 0;
557 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
559 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
563 if (flow_type > BNXT_ULP_FDB_TYPE_DEFAULT) {
564 BNXT_TF_DBG(ERR, "Invalid flow type\n");
568 flow_tbl = &flow_db->flow_tbl;
569 /* check for max flows */
570 if (fid >= flow_tbl->num_flows || !fid) {
571 BNXT_TF_DBG(ERR, "Invalid flow index\n");
575 /* check if the flow is active or not */
576 if (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type, fid)) {
577 BNXT_TF_DBG(ERR, "flow does not exist\n");
581 fid_resource = &flow_tbl->flow_resources[fid];
582 if (!params->critical_resource) {
583 /* Not the critical resource so free the resource */
584 ULP_FLOW_DB_RES_NXT_SET(nxt_idx,
585 fid_resource->nxt_resource_idx);
587 /* reached end of resources */
590 nxt_resource = &flow_tbl->flow_resources[nxt_idx];
592 /* connect the fid resource to the next resource */
593 ULP_FLOW_DB_RES_NXT_RESET(fid_resource->nxt_resource_idx);
594 ULP_FLOW_DB_RES_NXT_SET(fid_resource->nxt_resource_idx,
595 nxt_resource->nxt_resource_idx);
597 /* update the contents to be given to caller */
598 ulp_flow_db_res_info_to_params(nxt_resource, params);
600 /* Delete the nxt_resource */
601 memset(nxt_resource, 0, sizeof(struct ulp_fdb_resource_info));
603 /* add it to the free list */
604 flow_tbl->tail_index++;
605 if (flow_tbl->tail_index >= flow_tbl->num_resources) {
606 BNXT_TF_DBG(ERR, "FlowDB:Tail reached max\n");
609 flow_tbl->flow_tbl_stack[flow_tbl->tail_index] = nxt_idx;
612 /* Critical resource. copy the contents and exit */
613 ulp_flow_db_res_info_to_params(fid_resource, params);
614 ULP_FLOW_DB_RES_NXT_SET(nxt_idx,
615 fid_resource->nxt_resource_idx);
616 memset(fid_resource, 0, sizeof(struct ulp_fdb_resource_info));
617 ULP_FLOW_DB_RES_NXT_SET(fid_resource->nxt_resource_idx,
621 /* Now that the HW Flow counter resource is deleted, reset it's
622 * corresponding slot in the SW accumulation table in the Flow Counter
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 ulp_fc_mgr_cntr_reset(ulp_ctxt, params->direction,
629 params->resource_hndl);
632 /* all good, return success */
637 * Free the flow database entry
639 * ulp_ctxt [in] Ptr to ulp_context
640 * flow_type [in] - specify default or regular
641 * fid [in] The index to the flow entry
643 * returns 0 on success and negative on failure.
646 ulp_flow_db_fid_free(struct bnxt_ulp_context *ulp_ctxt,
647 enum bnxt_ulp_fdb_type flow_type,
650 struct bnxt_ulp_flow_db *flow_db;
651 struct bnxt_ulp_flow_tbl *flow_tbl;
653 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
655 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
659 if (flow_type > BNXT_ULP_FDB_TYPE_DEFAULT) {
660 BNXT_TF_DBG(ERR, "Invalid flow type\n");
664 flow_tbl = &flow_db->flow_tbl;
666 /* check for limits of fid */
667 if (fid >= flow_tbl->num_flows || !fid) {
668 BNXT_TF_DBG(ERR, "Invalid flow index\n");
672 /* check if the flow is active or not */
673 if (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type, fid)) {
674 BNXT_TF_DBG(ERR, "flow does not exist\n");
677 flow_tbl->head_index--;
678 if (!flow_tbl->head_index) {
679 BNXT_TF_DBG(ERR, "FlowDB: Head Ptr is zero\n");
682 flow_tbl->flow_tbl_stack[flow_tbl->head_index] = fid;
684 /* Clear the flows bitmap */
685 ulp_flow_db_active_flows_bit_set(flow_db, flow_type, fid, 0);
687 if (flow_type == BNXT_ULP_FDB_TYPE_REGULAR)
688 ulp_flow_db_func_id_set(flow_db, fid, 0);
690 /* all good, return success */
695 * Get the flow database entry details
697 * ulp_ctxt [in] Ptr to ulp_context
698 * flow_type [in] - specify default or regular
699 * fid [in] The index to the flow entry
700 * nxt_idx [in/out] the index to the next entry
701 * params [out] The contents to be copied into params.
703 * returns 0 on success and negative on failure.
706 ulp_flow_db_resource_get(struct bnxt_ulp_context *ulp_ctxt,
707 enum bnxt_ulp_fdb_type flow_type,
710 struct ulp_flow_db_res_params *params)
712 struct bnxt_ulp_flow_db *flow_db;
713 struct bnxt_ulp_flow_tbl *flow_tbl;
714 struct ulp_fdb_resource_info *nxt_resource, *fid_resource;
716 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
718 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
722 if (flow_type > BNXT_ULP_FDB_TYPE_DEFAULT) {
723 BNXT_TF_DBG(ERR, "Invalid flow type\n");
727 flow_tbl = &flow_db->flow_tbl;
729 /* check for limits of fid */
730 if (fid >= flow_tbl->num_flows || !fid) {
731 BNXT_TF_DBG(ERR, "Invalid flow index\n");
735 /* check if the flow is active or not */
736 if (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type, fid)) {
737 BNXT_TF_DBG(ERR, "flow does not exist\n");
742 fid_resource = &flow_tbl->flow_resources[fid];
743 ulp_flow_db_res_info_to_params(fid_resource, params);
744 ULP_FLOW_DB_RES_NXT_SET(*nxt_idx,
745 fid_resource->nxt_resource_idx);
747 nxt_resource = &flow_tbl->flow_resources[*nxt_idx];
748 ulp_flow_db_res_info_to_params(nxt_resource, params);
750 ULP_FLOW_DB_RES_NXT_SET(*nxt_idx,
751 nxt_resource->nxt_resource_idx);
754 /* all good, return success */
759 * Get the flow database entry iteratively
761 * flow_tbl [in] Ptr to flow table
762 * flow_type [in] - specify default or regular
763 * fid [in/out] The index to the flow entry
765 * returns 0 on success and negative on failure.
768 ulp_flow_db_next_entry_get(struct bnxt_ulp_flow_db *flow_db,
769 enum bnxt_ulp_fdb_type flow_type,
772 uint32_t lfid = *fid;
773 uint32_t idx, s_idx, mod_fid;
775 uint64_t *active_flows;
776 struct bnxt_ulp_flow_tbl *flowtbl = &flow_db->flow_tbl;
778 if (flow_type == BNXT_ULP_FDB_TYPE_REGULAR)
779 active_flows = flowtbl->active_reg_flows;
781 active_flows = flowtbl->active_dflt_flows;
784 /* increment the flow id to find the next valid flow id */
786 if (lfid >= flowtbl->num_flows)
788 idx = lfid / ULP_INDEX_BITMAP_SIZE;
789 mod_fid = lfid % ULP_INDEX_BITMAP_SIZE;
791 while (!(bs = active_flows[idx])) {
793 if ((idx * ULP_INDEX_BITMAP_SIZE) >= flowtbl->num_flows)
797 * remove the previous bits in the bitset bs to find the
798 * next non zero bit in the bitset. This needs to be done
799 * only if the idx is same as he one you started.
802 bs &= (-1UL >> mod_fid);
803 lfid = (idx * ULP_INDEX_BITMAP_SIZE) + __builtin_clzl(bs);
805 BNXT_TF_DBG(ERR, "Flow Database is corrupt\n");
808 } while (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type,
811 /* all good, return success */
817 * Flush all flows in the flow database.
819 * ulp_ctxt [in] Ptr to ulp context
820 * flow_type [in] - specify default or regular
822 * returns 0 on success or negative number on failure
825 ulp_flow_db_flush_flows(struct bnxt_ulp_context *ulp_ctx,
826 enum bnxt_ulp_fdb_type flow_type)
829 struct bnxt_ulp_flow_db *flow_db;
832 BNXT_TF_DBG(ERR, "Invalid Argument\n");
836 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctx);
838 BNXT_TF_DBG(ERR, "Flow database not found\n");
841 if (bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx)) {
842 BNXT_TF_DBG(ERR, "Flow db lock acquire failed\n");
846 while (!ulp_flow_db_next_entry_get(flow_db, flow_type, &fid))
847 ulp_mapper_resources_free(ulp_ctx, flow_type, fid);
849 bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);
855 * Flush all flows in the flow database that belong to a device function.
857 * ulp_ctxt [in] Ptr to ulp context
858 * func_id [in] - The port function id
860 * returns 0 on success or negative number on failure
863 ulp_flow_db_function_flow_flush(struct bnxt_ulp_context *ulp_ctx,
866 uint32_t flow_id = 0;
867 struct bnxt_ulp_flow_db *flow_db;
869 if (!ulp_ctx || !func_id) {
870 BNXT_TF_DBG(ERR, "Invalid Argument\n");
874 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctx);
876 BNXT_TF_DBG(ERR, "Flow database not found\n");
879 if (bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx)) {
880 BNXT_TF_DBG(ERR, "Flow db lock acquire failed\n");
884 while (!ulp_flow_db_next_entry_get(flow_db, BNXT_ULP_FDB_TYPE_REGULAR,
886 if (flow_db->func_id_tbl[flow_id] == func_id)
887 ulp_mapper_resources_free(ulp_ctx,
888 BNXT_ULP_FDB_TYPE_REGULAR,
891 bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);
896 * Flush all flows in the flow database that are associated with the session.
898 * ulp_ctxt [in] Ptr to ulp context
900 * returns 0 on success or negative number on failure
903 ulp_flow_db_session_flow_flush(struct bnxt_ulp_context *ulp_ctx)
906 * TBD: Tf core implementation of FW session flush shall change this
909 return ulp_flow_db_flush_flows(ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR);
913 * Check that flow id matches the function id or not
915 * ulp_ctxt [in] Ptr to ulp context
916 * flow_db [in] Ptr to flow table
917 * func_id [in] The func_id to be set, for reset pass zero.
919 * returns true on success or false on failure
922 ulp_flow_db_validate_flow_func(struct bnxt_ulp_context *ulp_ctx,
926 struct bnxt_ulp_flow_db *flow_db;
928 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctx);
930 BNXT_TF_DBG(ERR, "Flow database not found\n");
934 /* set the function id in the function table */
935 if (flow_id < flow_db->func_id_tbl_size && func_id &&
936 flow_db->func_id_tbl[flow_id] == func_id)
943 * Internal api to traverse the resource list within a flow
944 * and match a resource based on resource func and resource
945 * sub type. This api should be used only for resources that
946 * are unique and do not have multiple instances of resource
947 * func and sub type combination since it will return only
951 ulp_flow_db_resource_hndl_get(struct bnxt_ulp_context *ulp_ctx,
952 enum bnxt_ulp_fdb_type flow_type,
954 uint32_t resource_func,
955 uint32_t res_subtype,
958 struct bnxt_ulp_flow_db *flow_db;
959 struct bnxt_ulp_flow_tbl *flow_tbl;
960 struct ulp_fdb_resource_info *fid_res;
963 flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctx);
965 BNXT_TF_DBG(ERR, "Flow database not found\n");
969 if (flow_type > BNXT_ULP_FDB_TYPE_DEFAULT) {
970 BNXT_TF_DBG(ERR, "Invalid flow type\n");
974 flow_tbl = &flow_db->flow_tbl;
976 /* check for limits of fid */
977 if (flow_id >= flow_tbl->num_flows || !flow_id) {
978 BNXT_TF_DBG(ERR, "Invalid flow index\n");
982 /* check if the flow is active or not */
983 if (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type, flow_id)) {
984 BNXT_TF_DBG(ERR, "flow does not exist\n");
987 /* Iterate the resource to get the resource handle */
990 fid_res = &flow_tbl->flow_resources[res_id];
991 if (ulp_flow_db_resource_func_get(fid_res) == resource_func) {
992 if (resource_func & ULP_FLOW_DB_RES_FUNC_NEED_LOWER) {
993 if (res_subtype == fid_res->resource_sub_type) {
994 *res_hndl = fid_res->resource_hndl;
998 } else if (resource_func ==
999 BNXT_ULP_RESOURCE_FUNC_EXT_EM_TABLE ||
1001 BNXT_ULP_RESOURCE_FUNC_INT_EM_TABLE) {
1002 *res_hndl = fid_res->resource_em_handle;
1007 ULP_FLOW_DB_RES_NXT_SET(res_id, fid_res->nxt_resource_idx);
1013 * Api to get the cfa action pointer from a flow.
1015 * ulp_ctxt [in] Ptr to ulp context
1016 * flow_id [in] flow id
1017 * cfa_action [out] The resource handle stored in the flow database
1019 * returns 0 on success
1022 ulp_default_flow_db_cfa_action_get(struct bnxt_ulp_context *ulp_ctx,
1024 uint16_t *cfa_action)
1026 uint8_t sub_type = BNXT_ULP_RESOURCE_SUB_TYPE_INDEX_TYPE_VFR_CFA_ACTION;
1030 rc = ulp_flow_db_resource_hndl_get(ulp_ctx,
1031 BNXT_ULP_FDB_TYPE_DEFAULT,
1033 BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE,
1036 BNXT_TF_DBG(ERR, "CFA Action ptr not found for flow id %u\n",