1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2014-2020 Broadcom
6 #include <rte_common.h>
7 #include <rte_malloc.h>
11 #include "tf_ext_flow_handle.h"
12 #include "ulp_mark_mgr.h"
13 #include "bnxt_tf_common.h"
14 #include "ulp_template_db_enum.h"
15 #include "ulp_template_struct.h"
17 #define ULP_MARK_DB_ENTRY_SET_VALID(mark_info) ((mark_info)->flags |=\
19 #define ULP_MARK_DB_ENTRY_IS_INVALID(mark_info) (!((mark_info)->flags &\
21 #define ULP_MARK_DB_ENTRY_SET_VFR_ID(mark_info) ((mark_info)->flags |=\
23 #define ULP_MARK_DB_ENTRY_IS_VFR_ID(mark_info) ((mark_info)->flags &\
25 #define ULP_MARK_DB_ENTRY_IS_GLOBAL_HW_FID(mark_info) ((mark_info)->flags &\
26 BNXT_ULP_MARK_GLOBAL_HW_FID)
28 static inline uint32_t
29 ulp_mark_db_idx_get(bool is_gfid, uint32_t fid, struct bnxt_ulp_mark_tbl *mtbl)
31 uint32_t idx = 0, hashtype = 0;
34 TF_GET_HASH_TYPE_FROM_GFID(fid, hashtype);
35 TF_GET_HASH_INDEX_FROM_GFID(fid, idx);
37 /* Need to truncate anything beyond supported flows */
38 idx &= mtbl->gfid_mask;
40 idx |= mtbl->gfid_type_bit;
48 * Allocate and Initialize all Mark Manager resources for this ulp context.
50 * ctxt [in] The ulp context for the mark manager.
54 ulp_mark_db_init(struct bnxt_ulp_context *ctxt)
56 struct bnxt_ulp_device_params *dparms;
57 struct bnxt_ulp_mark_tbl *mark_tbl = NULL;
61 BNXT_TF_DBG(DEBUG, "Invalid ULP CTXT\n");
65 if (bnxt_ulp_cntxt_dev_id_get(ctxt, &dev_id)) {
66 BNXT_TF_DBG(DEBUG, "Failed to get device id\n");
70 dparms = bnxt_ulp_device_params_get(dev_id);
72 BNXT_TF_DBG(DEBUG, "Failed to device parms\n");
76 mark_tbl = rte_zmalloc("ulp_rx_mark_tbl_ptr",
77 sizeof(struct bnxt_ulp_mark_tbl), 0);
81 /* Need to allocate 2 * Num flows to account for hash type bit.*/
82 mark_tbl->lfid_num_entries = dparms->mark_db_lfid_entries;
83 mark_tbl->lfid_tbl = rte_zmalloc("ulp_rx_em_flow_mark_table",
84 mark_tbl->lfid_num_entries *
85 sizeof(struct bnxt_lfid_mark_info),
87 if (!mark_tbl->lfid_tbl)
90 /* Need to allocate 2 * Num flows to account for hash type bit */
91 mark_tbl->gfid_num_entries = dparms->mark_db_gfid_entries;
92 if (!mark_tbl->gfid_num_entries)
93 goto gfid_not_required;
95 mark_tbl->gfid_tbl = rte_zmalloc("ulp_rx_eem_flow_mark_table",
96 mark_tbl->gfid_num_entries *
97 sizeof(struct bnxt_gfid_mark_info),
99 if (!mark_tbl->gfid_tbl)
103 * These values are used to compress the FID to the allowable index
104 * space. The FID from hw may be the full hash which may be a big
105 * value to allocate and so allocate only needed hash values.
106 * gfid mask is the number of flow entries for the each left/right
107 * hash The gfid type bit is used to get to the higher or lower hash
110 mark_tbl->gfid_mask = (mark_tbl->gfid_num_entries / 2) - 1;
111 mark_tbl->gfid_type_bit = (mark_tbl->gfid_num_entries / 2);
113 BNXT_TF_DBG(DEBUG, "GFID Max = 0x%08x\nGFID MASK = 0x%08x\n",
114 mark_tbl->gfid_num_entries - 1,
115 mark_tbl->gfid_mask);
118 /* Add the mark tbl to the ulp context. */
119 bnxt_ulp_cntxt_ptr2_mark_db_set(ctxt, mark_tbl);
123 rte_free(mark_tbl->gfid_tbl);
124 rte_free(mark_tbl->lfid_tbl);
126 BNXT_TF_DBG(DEBUG, "Failed to allocate memory for mark mgr\n");
131 * Release all resources in the Mark Manager for this ulp context
133 * ctxt [in] The ulp context for the mark manager
137 ulp_mark_db_deinit(struct bnxt_ulp_context *ctxt)
139 struct bnxt_ulp_mark_tbl *mtbl;
141 mtbl = bnxt_ulp_cntxt_ptr2_mark_db_get(ctxt);
144 rte_free(mtbl->gfid_tbl);
145 rte_free(mtbl->lfid_tbl);
148 /* Safe to ignore on deinit */
149 (void)bnxt_ulp_cntxt_ptr2_mark_db_set(ctxt, NULL);
156 * Get a Mark from the Mark Manager
158 * ctxt [in] The ulp context for the mark manager
160 * is_gfid [in] The type of fid (GFID or LFID)
162 * fid [in] The flow id that is returned by HW in BD
164 * vfr_flag [out].it indicatesif mark is vfr_id or mark id
166 * mark [out] The mark that is associated with the FID
170 ulp_mark_db_mark_get(struct bnxt_ulp_context *ctxt,
176 struct bnxt_ulp_mark_tbl *mtbl;
182 mtbl = bnxt_ulp_cntxt_ptr2_mark_db_get(ctxt);
184 BNXT_TF_DBG(ERR, "Unable to get Mark Table\n");
188 idx = ulp_mark_db_idx_get(is_gfid, fid, mtbl);
191 if (idx >= mtbl->gfid_num_entries ||
192 ULP_MARK_DB_ENTRY_IS_INVALID(&mtbl->gfid_tbl[idx]))
195 BNXT_TF_DBG(DEBUG, "Get GFID[0x%0x] = 0x%0x\n",
196 idx, mtbl->gfid_tbl[idx].mark_id);
198 *vfr_flag = ULP_MARK_DB_ENTRY_IS_VFR_ID(&mtbl->gfid_tbl[idx]);
199 *mark = mtbl->gfid_tbl[idx].mark_id;
201 if (idx >= mtbl->lfid_num_entries ||
202 ULP_MARK_DB_ENTRY_IS_INVALID(&mtbl->lfid_tbl[idx]))
205 BNXT_TF_DBG(DEBUG, "Get LFID[0x%0x] = 0x%0x\n",
206 idx, mtbl->lfid_tbl[idx].mark_id);
208 *vfr_flag = ULP_MARK_DB_ENTRY_IS_VFR_ID(&mtbl->lfid_tbl[idx]);
209 *mark = mtbl->lfid_tbl[idx].mark_id;
216 * Adds a Mark to the Mark Manager
218 * ctxt [in] The ulp context for the mark manager
220 * mark_flag [in] mark flags.
222 * fid [in] The flow id that is returned by HW in BD
224 * mark [in] The mark to be associated with the FID
228 ulp_mark_db_mark_add(struct bnxt_ulp_context *ctxt,
233 struct bnxt_ulp_mark_tbl *mtbl;
238 BNXT_TF_DBG(ERR, "Invalid ulp context\n");
242 mtbl = bnxt_ulp_cntxt_ptr2_mark_db_get(ctxt);
244 BNXT_TF_DBG(ERR, "Unable to get Mark DB\n");
248 is_gfid = (mark_flag & BNXT_ULP_MARK_GLOBAL_HW_FID);
250 idx = ulp_mark_db_idx_get(is_gfid, fid, mtbl);
251 if (idx >= mtbl->gfid_num_entries) {
252 BNXT_TF_DBG(ERR, "Mark index greater than allocated\n");
255 BNXT_TF_DBG(DEBUG, "Set GFID[0x%0x] = 0x%0x\n", idx, mark);
256 mtbl->gfid_tbl[idx].mark_id = mark;
257 ULP_MARK_DB_ENTRY_SET_VALID(&mtbl->gfid_tbl[idx]);
260 /* For the LFID, the FID is used as the index */
261 if (fid >= mtbl->lfid_num_entries) {
262 BNXT_TF_DBG(ERR, "Mark index greater than allocated\n");
265 BNXT_TF_DBG(DEBUG, "Set LFID[0x%0x] = 0x%0x\n", fid, mark);
266 mtbl->lfid_tbl[fid].mark_id = mark;
267 ULP_MARK_DB_ENTRY_SET_VALID(&mtbl->lfid_tbl[fid]);
269 if (mark_flag & BNXT_ULP_MARK_VFR_ID)
270 ULP_MARK_DB_ENTRY_SET_VFR_ID(&mtbl->lfid_tbl[fid]);
277 * Removes a Mark from the Mark Manager
279 * ctxt [in] The ulp context for the mark manager
281 * mark_flag [in] mark flags.
283 * fid [in] The flow id that is returned by HW in BD
287 ulp_mark_db_mark_del(struct bnxt_ulp_context *ctxt,
291 struct bnxt_ulp_mark_tbl *mtbl;
296 BNXT_TF_DBG(ERR, "Invalid ulp context\n");
300 mtbl = bnxt_ulp_cntxt_ptr2_mark_db_get(ctxt);
302 BNXT_TF_DBG(ERR, "Unable to get Mark DB\n");
306 is_gfid = (mark_flag & BNXT_ULP_MARK_GLOBAL_HW_FID);
308 idx = ulp_mark_db_idx_get(is_gfid, fid, mtbl);
309 if (idx >= mtbl->gfid_num_entries) {
310 BNXT_TF_DBG(ERR, "Mark index greater than allocated\n");
313 BNXT_TF_DBG(DEBUG, "Reset GFID[0x%0x]\n", idx);
314 memset(&mtbl->gfid_tbl[idx], 0,
315 sizeof(struct bnxt_gfid_mark_info));
318 /* For the LFID, the FID is used as the index */
319 if (fid >= mtbl->lfid_num_entries) {
320 BNXT_TF_DBG(ERR, "Mark index greater than allocated\n");
323 memset(&mtbl->lfid_tbl[fid], 0,
324 sizeof(struct bnxt_lfid_mark_info));