1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2014-2021 Broadcom
7 #include <rte_malloc.h>
10 #include "ulp_mapper.h"
11 #include "ulp_flow_db.h"
13 #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG
14 #include "ulp_template_debug_proto.h"
15 #include "ulp_tf_debug.h"
18 /* Retrieve the generic table initialization parameters for the tbl_idx */
19 static struct bnxt_ulp_generic_tbl_params*
20 ulp_mapper_gen_tbl_params_get(uint32_t tbl_idx)
22 if (tbl_idx >= BNXT_ULP_GEN_TBL_MAX_SZ)
25 return &ulp_generic_tbl_params[tbl_idx];
29 * Initialize the generic table list
31 * mapper_data [in] Pointer to the mapper data and the generic table is
34 * returns 0 on success
37 ulp_mapper_generic_tbl_list_init(struct bnxt_ulp_mapper_data *mapper_data)
39 struct bnxt_ulp_generic_tbl_params *tbl;
40 struct ulp_mapper_gen_tbl_list *entry;
41 struct ulp_hash_create_params cparams;
44 /* Allocate the generic tables. */
45 for (idx = 0; idx < BNXT_ULP_GEN_TBL_MAX_SZ; idx++) {
46 tbl = ulp_mapper_gen_tbl_params_get(idx);
48 BNXT_TF_DBG(ERR, "Failed to get gen table parms %d\n",
52 entry = &mapper_data->gen_tbl_list[idx];
53 if (tbl->result_num_entries != 0) {
55 entry->gen_tbl_name = tbl->name;
56 /* add 4 bytes for reference count */
57 entry->mem_data_size = (tbl->result_num_entries + 1) *
58 (tbl->result_num_bytes + sizeof(uint32_t));
60 /* allocate the big chunk of memory */
61 entry->mem_data = rte_zmalloc("ulp mapper gen tbl",
62 entry->mem_data_size, 0);
63 if (!entry->mem_data) {
65 "%s:Failed to alloc gen table %d\n",
69 /* Populate the generic table container */
70 entry->container.num_elem = tbl->result_num_entries;
71 entry->container.byte_data_size = tbl->result_num_bytes;
72 entry->container.ref_count =
73 (uint32_t *)entry->mem_data;
74 size = sizeof(uint32_t) * (tbl->result_num_entries + 1);
75 entry->container.byte_data = &entry->mem_data[size];
76 entry->container.byte_order = tbl->result_byte_order;
78 BNXT_TF_DBG(DEBUG, "%s: Unused Gen tbl entry is %d\n",
82 if (tbl->hash_tbl_entries) {
83 cparams.key_size = tbl->key_num_bytes;
84 cparams.num_buckets = tbl->num_buckets;
85 cparams.num_hash_tbl_entries = tbl->hash_tbl_entries;
86 cparams.num_key_entries = tbl->result_num_entries;
87 if (ulp_gen_hash_tbl_list_init(&cparams,
90 "%s: Failed to alloc hash tbl %d\n",
101 * Free the generic table list
103 * mapper_data [in] Pointer to the mapper data and the generic table is
106 * returns 0 on success
109 ulp_mapper_generic_tbl_list_deinit(struct bnxt_ulp_mapper_data *mapper_data)
111 struct ulp_mapper_gen_tbl_list *tbl_list;
114 /* iterate the generic table. */
115 for (idx = 0; idx < BNXT_ULP_GEN_TBL_MAX_SZ; idx++) {
116 tbl_list = &mapper_data->gen_tbl_list[idx];
117 if (tbl_list->mem_data) {
118 rte_free(tbl_list->mem_data);
119 tbl_list->mem_data = NULL;
121 if (tbl_list->hash_tbl) {
122 ulp_gen_hash_tbl_list_deinit(tbl_list->hash_tbl);
123 tbl_list->hash_tbl = NULL;
131 * Get the generic table list entry
133 * tbl_list [in] - Ptr to generic table
134 * key [in] - Key index to the table
135 * entry [out] - output will include the entry if found
137 * returns 0 on success.
140 ulp_mapper_gen_tbl_entry_get(struct ulp_mapper_gen_tbl_list *tbl_list,
142 struct ulp_mapper_gen_tbl_entry *entry)
144 /* populate the output and return the values */
145 if (key > tbl_list->container.num_elem) {
146 BNXT_TF_DBG(ERR, "%s: invalid key %x:%x\n",
147 tbl_list->gen_tbl_name, key,
148 tbl_list->container.num_elem);
151 entry->ref_count = &tbl_list->container.ref_count[key];
152 entry->byte_data_size = tbl_list->container.byte_data_size;
153 entry->byte_data = &tbl_list->container.byte_data[key *
154 entry->byte_data_size];
155 entry->byte_order = tbl_list->container.byte_order;
160 * utility function to calculate the table idx
162 * res_sub_type [in] - Resource sub type
163 * dir [in] - Direction
168 ulp_mapper_gen_tbl_idx_calculate(uint32_t res_sub_type, uint32_t dir)
172 /* Validate for direction */
173 if (dir >= TF_DIR_MAX) {
174 BNXT_TF_DBG(ERR, "invalid argument %x\n", dir);
177 tbl_idx = (res_sub_type << 1) | (dir & 0x1);
178 if (tbl_idx >= BNXT_ULP_GEN_TBL_MAX_SZ) {
179 BNXT_TF_DBG(ERR, "invalid table index %x\n", tbl_idx);
186 * Set the data in the generic table entry, Data is in Big endian format
188 * entry [in] - generic table entry
189 * len [in] - The length of the data in bits to be set
190 * data [in] - pointer to the data to be used for setting the value.
191 * data_size [in] - length of the data pointer in bytes.
193 * returns 0 on success
196 ulp_mapper_gen_tbl_entry_data_set(struct ulp_mapper_gen_tbl_entry *entry,
197 uint32_t len, uint8_t *data,
200 /* validate the null arguments */
201 if (!entry || !data) {
202 BNXT_TF_DBG(ERR, "invalid argument\n");
206 /* check the size of the buffer for validation */
207 if (len > ULP_BYTE_2_BITS(entry->byte_data_size) ||
208 data_size < ULP_BITS_2_BYTE(len)) {
209 BNXT_TF_DBG(ERR, "invalid offset or length %x:%x\n",
210 len, entry->byte_data_size);
213 memcpy(entry->byte_data, data, ULP_BITS_2_BYTE(len));
218 * Get the data in the generic table entry, Data is in Big endian format
220 * entry [in] - generic table entry
221 * offset [in] - The offset in bits where the data has to get
222 * len [in] - The length of the data in bits to be get
223 * data [out] - pointer to the data to be used for setting the value.
224 * data_size [in] - The size of data in bytes
226 * returns 0 on success
229 ulp_mapper_gen_tbl_entry_data_get(struct ulp_mapper_gen_tbl_entry *entry,
230 uint32_t offset, uint32_t len, uint8_t *data,
233 /* validate the null arguments */
234 if (!entry || !data) {
235 BNXT_TF_DBG(ERR, "invalid argument\n");
239 /* check the size of the buffer for validation */
240 if ((offset + len) > ULP_BYTE_2_BITS(entry->byte_data_size) ||
241 len > ULP_BYTE_2_BITS(data_size)) {
242 BNXT_TF_DBG(ERR, "invalid offset or length %x:%x:%x\n",
243 offset, len, entry->byte_data_size);
246 if (entry->byte_order == BNXT_ULP_BYTE_ORDER_LE)
247 ulp_bs_pull_lsb(entry->byte_data, data, data_size, offset, len);
249 ulp_bs_pull_msb(entry->byte_data, data, offset, len);
254 /* Free the generic table list entry
256 * ulp_ctx [in] - Pointer to the ulp context
257 * tbl_idx [in] - Index of the generic table
258 * ckey [in] - Key for the entry in the table
260 * returns 0 on success
263 ulp_mapper_gen_tbl_entry_free(struct bnxt_ulp_context *ulp_ctx,
264 uint32_t tbl_idx, uint32_t ckey)
266 struct ulp_flow_db_res_params res;
268 res.direction = tbl_idx & 0x1;
269 res.resource_sub_type = tbl_idx >> 1;
270 res.resource_hndl = ckey;
272 return ulp_mapper_gen_tbl_res_free(ulp_ctx, &res);
275 /* Free the generic table list resource
277 * ulp_ctx [in] - Pointer to the ulp context
278 * res [in] - Pointer to flow db resource entry
280 * returns 0 on success
283 ulp_mapper_gen_tbl_res_free(struct bnxt_ulp_context *ulp_ctx,
284 struct ulp_flow_db_res_params *res)
286 struct bnxt_ulp_mapper_data *mapper_data;
287 struct ulp_mapper_gen_tbl_list *gen_tbl_list;
288 struct ulp_mapper_gen_tbl_entry entry;
289 struct ulp_gen_hash_entry_params hash_entry;
294 /* Extract the resource sub type and direction */
295 tbl_idx = ulp_mapper_gen_tbl_idx_calculate(res->resource_sub_type,
298 BNXT_TF_DBG(ERR, "invalid argument %x:%x\n",
299 res->resource_sub_type, res->direction);
303 mapper_data = bnxt_ulp_cntxt_ptr2_mapper_data_get(ulp_ctx);
305 BNXT_TF_DBG(ERR, "invalid ulp context %x\n", tbl_idx);
308 /* get the generic table */
309 gen_tbl_list = &mapper_data->gen_tbl_list[tbl_idx];
311 /* Get the generic table entry*/
312 if (gen_tbl_list->hash_tbl) {
313 /* use the hash index to get the value */
314 hash_entry.hash_index = (uint32_t)res->resource_hndl;
315 if (ulp_gen_hash_tbl_list_index_search(gen_tbl_list->hash_tbl,
317 BNXT_TF_DBG(ERR, "Unable to find has entry %x:%x\n",
318 tbl_idx, hash_entry.hash_index);
321 key_idx = hash_entry.key_idx;
324 key_idx = (uint32_t)res->resource_hndl;
326 if (ulp_mapper_gen_tbl_entry_get(gen_tbl_list, key_idx, &entry)) {
327 BNXT_TF_DBG(ERR, "Gen tbl entry get failed %x:%" PRIX64 "\n",
328 tbl_idx, res->resource_hndl);
332 /* Decrement the reference count */
333 if (!ULP_GEN_TBL_REF_CNT(&entry)) {
334 BNXT_TF_DBG(ERR, "generic table corrupt %x:%" PRIX64 "\n",
335 tbl_idx, res->resource_hndl);
338 ULP_GEN_TBL_REF_CNT_DEC(&entry);
340 /* retain the details since there are other users */
341 if (ULP_GEN_TBL_REF_CNT(&entry))
344 /* Delete the generic table entry. First extract the fid */
345 if (ulp_mapper_gen_tbl_entry_data_get(&entry, ULP_GEN_TBL_FID_OFFSET,
346 ULP_GEN_TBL_FID_SIZE_BITS,
349 BNXT_TF_DBG(ERR, "Unable to get fid %x:%" PRIX64 "\n",
350 tbl_idx, res->resource_hndl);
353 fid = tfp_be_to_cpu_32(fid);
354 /* no need to del if fid is 0 since there is no associated resource */
356 /* Destroy the flow associated with the shared flow id */
357 if (ulp_mapper_flow_destroy(ulp_ctx, BNXT_ULP_FDB_TYPE_RID,
360 "Error in deleting shared flow id %x\n",
364 /* Delete the entry from the hash table */
365 if (gen_tbl_list->hash_tbl)
366 ulp_gen_hash_tbl_list_del(gen_tbl_list->hash_tbl, &hash_entry);
368 /* clear the byte data of the generic table entry */
369 memset(entry.byte_data, 0, entry.byte_data_size);
375 * Write the generic table list hash entry
377 * tbl_list [in] - pointer to the generic table list
378 * hash_entry [in] - Hash table entry
379 * gen_tbl_ent [out] - generic table entry
381 * returns 0 on success.
384 ulp_mapper_gen_tbl_hash_entry_add(struct ulp_mapper_gen_tbl_list *tbl_list,
385 struct ulp_gen_hash_entry_params *hash_entry,
386 struct ulp_mapper_gen_tbl_entry *gen_tbl_ent)
391 switch (hash_entry->search_flag) {
392 case ULP_GEN_HASH_SEARCH_FOUND:
393 BNXT_TF_DBG(ERR, "%s: gen hash entry already present\n",
394 tbl_list->gen_tbl_name);
396 case ULP_GEN_HASH_SEARCH_FULL:
397 BNXT_TF_DBG(ERR, "%s: gen hash table is full\n",
398 tbl_list->gen_tbl_name);
400 case ULP_GEN_HASH_SEARCH_MISSED:
401 rc = ulp_gen_hash_tbl_list_add(tbl_list->hash_tbl, hash_entry);
403 BNXT_TF_DBG(ERR, "%s: gen hash table add failed\n",
404 tbl_list->gen_tbl_name);
407 key = hash_entry->key_idx;
408 gen_tbl_ent->ref_count = &tbl_list->container.ref_count[key];
409 gen_tbl_ent->byte_data_size =
410 tbl_list->container.byte_data_size;
411 gen_tbl_ent->byte_data = &tbl_list->container.byte_data[key *
412 gen_tbl_ent->byte_data_size];
413 gen_tbl_ent->byte_order = tbl_list->container.byte_order;
416 BNXT_TF_DBG(ERR, "%s: invalid search flag\n",
417 tbl_list->gen_tbl_name);