Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2014-2023 Broadcom
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include <rte_log.h>
7 : : #include <rte_malloc.h>
8 : : #include "tf_core.h"
9 : : #include "tfp.h"
10 : : #include "ulp_mapper.h"
11 : : #include "ulp_flow_db.h"
12 : :
13 : : /* Retrieve the generic table initialization parameters for the tbl_idx */
14 : : static struct bnxt_ulp_generic_tbl_params*
15 : : ulp_mapper_gen_tbl_params_get(uint32_t tbl_idx)
16 : : {
17 : : if (tbl_idx >= BNXT_ULP_GEN_TBL_MAX_SZ)
18 : : return NULL;
19 : :
20 : 0 : return &ulp_generic_tbl_params[tbl_idx];
21 : : }
22 : :
23 : : /*
24 : : * Initialize the generic table list
25 : : *
26 : : * mapper_data [in] Pointer to the mapper data and the generic table is
27 : : * part of it
28 : : *
29 : : * returns 0 on success
30 : : */
31 : : int32_t
32 : 0 : ulp_mapper_generic_tbl_list_init(struct bnxt_ulp_mapper_data *mapper_data)
33 : : {
34 : : struct bnxt_ulp_generic_tbl_params *tbl;
35 : : struct ulp_mapper_gen_tbl_list *entry;
36 : : struct ulp_hash_create_params cparams;
37 : : uint32_t idx, size;
38 : :
39 : : /* Allocate the generic tables. */
40 [ # # ]: 0 : for (idx = 0; idx < BNXT_ULP_GEN_TBL_MAX_SZ; idx++) {
41 : : tbl = ulp_mapper_gen_tbl_params_get(idx);
42 : : if (!tbl) {
43 : : BNXT_TF_DBG(ERR, "Failed to get gen table parms %d\n",
44 : : idx);
45 : : return -EINVAL;
46 : : }
47 : : entry = &mapper_data->gen_tbl_list[idx];
48 [ # # ]: 0 : if (tbl->result_num_entries != 0) {
49 : : /* assign the name */
50 : 0 : entry->gen_tbl_name = tbl->name;
51 : : /* add 4 bytes for reference count */
52 : 0 : entry->mem_data_size = (tbl->result_num_entries + 1) *
53 : 0 : (tbl->result_num_bytes + sizeof(uint32_t));
54 : :
55 : : /* allocate the big chunk of memory */
56 : 0 : entry->mem_data = rte_zmalloc("ulp mapper gen tbl",
57 : : entry->mem_data_size, 0);
58 [ # # ]: 0 : if (!entry->mem_data) {
59 : 0 : BNXT_TF_DBG(ERR,
60 : : "%s:Failed to alloc gen table %d\n",
61 : : tbl->name, idx);
62 : 0 : return -ENOMEM;
63 : : }
64 : : /* Populate the generic table container */
65 : 0 : entry->container.num_elem = tbl->result_num_entries;
66 : 0 : entry->container.byte_data_size = tbl->result_num_bytes;
67 : 0 : entry->container.ref_count =
68 : : (uint32_t *)entry->mem_data;
69 : 0 : size = sizeof(uint32_t) * (tbl->result_num_entries + 1);
70 : 0 : entry->container.byte_data = &entry->mem_data[size];
71 : 0 : entry->container.byte_order = tbl->result_byte_order;
72 : : } else {
73 : 0 : BNXT_TF_DBG(DEBUG, "%s: Unused Gen tbl entry is %d\n",
74 : : tbl->name, idx);
75 : : /* return -EINVAL; */
76 : : }
77 [ # # ]: 0 : if (tbl->hash_tbl_entries) {
78 : 0 : cparams.key_size = tbl->key_num_bytes;
79 : 0 : cparams.num_buckets = tbl->num_buckets;
80 : 0 : cparams.num_hash_tbl_entries = tbl->hash_tbl_entries;
81 : 0 : cparams.num_key_entries = tbl->result_num_entries;
82 [ # # ]: 0 : if (ulp_gen_hash_tbl_list_init(&cparams,
83 : : &entry->hash_tbl)) {
84 : 0 : BNXT_TF_DBG(ERR,
85 : : "%s: Failed to alloc hash tbl %d\n",
86 : : tbl->name, idx);
87 : 0 : return -ENOMEM;
88 : : }
89 : : }
90 : : }
91 : : /* success */
92 : : return 0;
93 : : }
94 : :
95 : : /*
96 : : * Free the generic table list
97 : : *
98 : : * mapper_data [in] Pointer to the mapper data and the generic table is
99 : : * part of it
100 : : *
101 : : * returns 0 on success
102 : : */
103 : : int32_t
104 : 0 : ulp_mapper_generic_tbl_list_deinit(struct bnxt_ulp_mapper_data *mapper_data)
105 : : {
106 : : struct ulp_mapper_gen_tbl_list *tbl_list;
107 : : uint32_t idx;
108 : :
109 : : /* iterate the generic table. */
110 [ # # ]: 0 : for (idx = 0; idx < BNXT_ULP_GEN_TBL_MAX_SZ; idx++) {
111 : : tbl_list = &mapper_data->gen_tbl_list[idx];
112 [ # # ]: 0 : if (tbl_list->mem_data) {
113 : 0 : rte_free(tbl_list->mem_data);
114 : 0 : tbl_list->mem_data = NULL;
115 : : }
116 [ # # ]: 0 : if (tbl_list->hash_tbl) {
117 : 0 : ulp_gen_hash_tbl_list_deinit(tbl_list->hash_tbl);
118 : 0 : tbl_list->hash_tbl = NULL;
119 : : }
120 : : }
121 : : /* success */
122 : 0 : return 0;
123 : : }
124 : :
125 : : /*
126 : : * Get the generic table list entry
127 : : *
128 : : * tbl_list [in] - Ptr to generic table
129 : : * key [in] - Key index to the table
130 : : * entry [out] - output will include the entry if found
131 : : *
132 : : * returns 0 on success.
133 : : */
134 : : int32_t
135 : 0 : ulp_mapper_gen_tbl_entry_get(struct ulp_mapper_gen_tbl_list *tbl_list,
136 : : uint32_t key,
137 : : struct ulp_mapper_gen_tbl_entry *entry)
138 : : {
139 : : /* populate the output and return the values */
140 [ # # ]: 0 : if (key > tbl_list->container.num_elem) {
141 : 0 : BNXT_TF_DBG(ERR, "%s: invalid key %x:%x\n",
142 : : tbl_list->gen_tbl_name, key,
143 : : tbl_list->container.num_elem);
144 : 0 : return -EINVAL;
145 : : }
146 : 0 : entry->ref_count = &tbl_list->container.ref_count[key];
147 : 0 : entry->byte_data_size = tbl_list->container.byte_data_size;
148 : 0 : entry->byte_data = &tbl_list->container.byte_data[key *
149 : : entry->byte_data_size];
150 : 0 : entry->byte_order = tbl_list->container.byte_order;
151 : 0 : return 0;
152 : : }
153 : :
154 : : /*
155 : : * utility function to calculate the table idx
156 : : *
157 : : * res_sub_type [in] - Resource sub type
158 : : * dir [in] - Direction
159 : : *
160 : : * returns None
161 : : */
162 : : int32_t
163 : 0 : ulp_mapper_gen_tbl_idx_calculate(uint32_t res_sub_type, uint32_t dir)
164 : : {
165 : : int32_t tbl_idx;
166 : :
167 : : /* Validate for direction */
168 [ # # ]: 0 : if (dir >= TF_DIR_MAX) {
169 : 0 : BNXT_TF_DBG(ERR, "invalid argument %x\n", dir);
170 : 0 : return -EINVAL;
171 : : }
172 : 0 : tbl_idx = (res_sub_type << 1) | (dir & 0x1);
173 [ # # ]: 0 : if (tbl_idx >= BNXT_ULP_GEN_TBL_MAX_SZ) {
174 : 0 : BNXT_TF_DBG(ERR, "invalid table index %x\n", tbl_idx);
175 : 0 : return -EINVAL;
176 : : }
177 : : return tbl_idx;
178 : : }
179 : :
180 : : /*
181 : : * Set the data in the generic table entry, Data is in Big endian format
182 : : *
183 : : * entry [in] - generic table entry
184 : : * len [in] - The length of the data in bits to be set
185 : : * data [in] - pointer to the data to be used for setting the value.
186 : : * data_size [in] - length of the data pointer in bytes.
187 : : *
188 : : * returns 0 on success
189 : : */
190 : : int32_t
191 : 0 : ulp_mapper_gen_tbl_entry_data_set(struct ulp_mapper_gen_tbl_entry *entry,
192 : : uint32_t len, uint8_t *data,
193 : : uint32_t data_size)
194 : : {
195 : : /* validate the null arguments */
196 [ # # ]: 0 : if (!entry || !data) {
197 : 0 : BNXT_TF_DBG(ERR, "invalid argument\n");
198 : 0 : return -EINVAL;
199 : : }
200 : :
201 : : /* check the size of the buffer for validation */
202 [ # # ]: 0 : if (len > ULP_BYTE_2_BITS(entry->byte_data_size) ||
203 [ # # ]: 0 : data_size < ULP_BITS_2_BYTE(len)) {
204 : 0 : BNXT_TF_DBG(ERR, "invalid offset or length %x:%x\n",
205 : : len, entry->byte_data_size);
206 : 0 : return -EINVAL;
207 : : }
208 : 0 : memcpy(entry->byte_data, data, ULP_BITS_2_BYTE(len));
209 : 0 : return 0;
210 : : }
211 : :
212 : : /*
213 : : * Get the data in the generic table entry, Data is in Big endian format
214 : : *
215 : : * entry [in] - generic table entry
216 : : * offset [in] - The offset in bits where the data has to get
217 : : * len [in] - The length of the data in bits to be get
218 : : * data [out] - pointer to the data to be used for setting the value.
219 : : * data_size [in] - The size of data in bytes
220 : : *
221 : : * returns 0 on success
222 : : */
223 : : int32_t
224 : 0 : ulp_mapper_gen_tbl_entry_data_get(struct ulp_mapper_gen_tbl_entry *entry,
225 : : uint32_t offset, uint32_t len, uint8_t *data,
226 : : uint32_t data_size)
227 : : {
228 : : /* validate the null arguments */
229 [ # # ]: 0 : if (!entry || !data) {
230 : 0 : BNXT_TF_DBG(ERR, "invalid argument\n");
231 : 0 : return -EINVAL;
232 : : }
233 : :
234 : : /* check the size of the buffer for validation */
235 [ # # ]: 0 : if ((offset + len) > ULP_BYTE_2_BITS(entry->byte_data_size) ||
236 [ # # ]: 0 : len > ULP_BYTE_2_BITS(data_size)) {
237 : 0 : BNXT_TF_DBG(ERR, "invalid offset or length %x:%x:%x\n",
238 : : offset, len, entry->byte_data_size);
239 : 0 : return -EINVAL;
240 : : }
241 [ # # ]: 0 : if (entry->byte_order == BNXT_ULP_BYTE_ORDER_LE)
242 : 0 : ulp_bs_pull_lsb(entry->byte_data, data, data_size, offset, len);
243 : : else
244 : 0 : ulp_bs_pull_msb(entry->byte_data, data, offset, len);
245 : :
246 : : return 0;
247 : : }
248 : :
249 : : /* Free the generic table list entry
250 : : *
251 : : * ulp_ctx [in] - Pointer to the ulp context
252 : : * tbl_idx [in] - Index of the generic table
253 : : * ckey [in] - Key for the entry in the table
254 : : *
255 : : * returns 0 on success
256 : : */
257 : : int32_t
258 : 0 : ulp_mapper_gen_tbl_entry_free(struct bnxt_ulp_context *ulp_ctx,
259 : : uint32_t tbl_idx, uint32_t ckey)
260 : : {
261 : : struct ulp_flow_db_res_params res;
262 : : uint32_t fid = 0; /* not using for this case */
263 : :
264 : 0 : res.direction = tbl_idx & 0x1;
265 : 0 : res.resource_sub_type = tbl_idx >> 1;
266 : 0 : res.resource_hndl = ckey;
267 : :
268 : 0 : return ulp_mapper_gen_tbl_res_free(ulp_ctx, fid, &res);
269 : : }
270 : :
271 : : /* Free the generic table list resource
272 : : *
273 : : * ulp_ctx [in] - Pointer to the ulp context
274 : : * fid [in] - The fid the generic table is associated with
275 : : * res [in] - Pointer to flow db resource entry
276 : : *
277 : : * returns 0 on success
278 : : */
279 : : int32_t
280 : 0 : ulp_mapper_gen_tbl_res_free(struct bnxt_ulp_context *ulp_ctx,
281 : : uint32_t fid,
282 : : struct ulp_flow_db_res_params *res)
283 : : {
284 : : struct bnxt_ulp_mapper_data *mapper_data;
285 : : struct ulp_mapper_gen_tbl_list *gen_tbl_list;
286 : : struct ulp_mapper_gen_tbl_entry entry;
287 : : struct ulp_gen_hash_entry_params hash_entry;
288 : : int32_t tbl_idx;
289 : 0 : uint32_t rid = 0;
290 : : uint32_t key_idx;
291 : :
292 : : /* Extract the resource sub type and direction */
293 : 0 : tbl_idx = ulp_mapper_gen_tbl_idx_calculate(res->resource_sub_type,
294 : 0 : res->direction);
295 [ # # ]: 0 : if (tbl_idx < 0) {
296 : 0 : BNXT_TF_DBG(ERR, "invalid argument %x:%x\n",
297 : : res->resource_sub_type, res->direction);
298 : 0 : return -EINVAL;
299 : : }
300 : :
301 : 0 : mapper_data = bnxt_ulp_cntxt_ptr2_mapper_data_get(ulp_ctx);
302 [ # # ]: 0 : if (!mapper_data) {
303 : 0 : BNXT_TF_DBG(ERR, "invalid ulp context %x\n", tbl_idx);
304 : 0 : return -EINVAL;
305 : : }
306 : : /* get the generic table */
307 : 0 : gen_tbl_list = &mapper_data->gen_tbl_list[tbl_idx];
308 : :
309 : : /* Get the generic table entry*/
310 [ # # ]: 0 : if (gen_tbl_list->hash_tbl) {
311 : : /* use the hash index to get the value */
312 : 0 : hash_entry.hash_index = (uint32_t)res->resource_hndl;
313 [ # # ]: 0 : if (ulp_gen_hash_tbl_list_index_search(gen_tbl_list->hash_tbl,
314 : : &hash_entry)) {
315 : 0 : BNXT_TF_DBG(ERR, "Unable to find has entry %x:%x\n",
316 : : tbl_idx, hash_entry.hash_index);
317 : 0 : return -EINVAL;
318 : : }
319 : 0 : key_idx = hash_entry.key_idx;
320 : :
321 : : } else {
322 : 0 : key_idx = (uint32_t)res->resource_hndl;
323 : : }
324 [ # # ]: 0 : if (ulp_mapper_gen_tbl_entry_get(gen_tbl_list, key_idx, &entry)) {
325 : 0 : BNXT_TF_DBG(ERR, "Gen tbl entry get failed %x:%" PRIX64 "\n",
326 : : tbl_idx, res->resource_hndl);
327 : 0 : return -EINVAL;
328 : : }
329 : :
330 : : /* Decrement the reference count */
331 [ # # ]: 0 : if (!ULP_GEN_TBL_REF_CNT(&entry)) {
332 : 0 : BNXT_TF_DBG(DEBUG,
333 : : "generic table entry already free %x:%" PRIX64 "\n",
334 : : tbl_idx, res->resource_hndl);
335 : 0 : return 0;
336 : : }
337 : 0 : ULP_GEN_TBL_REF_CNT_DEC(&entry);
338 : :
339 : : /* retain the details since there are other users */
340 [ # # ]: 0 : if (ULP_GEN_TBL_REF_CNT(&entry))
341 : : return 0;
342 : :
343 : : /* Delete the generic table entry. First extract the rid */
344 [ # # ]: 0 : if (ulp_mapper_gen_tbl_entry_data_get(&entry, ULP_GEN_TBL_FID_OFFSET,
345 : : ULP_GEN_TBL_FID_SIZE_BITS,
346 : : (uint8_t *)&rid,
347 : : sizeof(rid))) {
348 : 0 : BNXT_TF_DBG(ERR, "Unable to get rid %x:%" PRIX64 "\n",
349 : : tbl_idx, res->resource_hndl);
350 : 0 : return -EINVAL;
351 : : }
352 [ # # ]: 0 : rid = tfp_be_to_cpu_32(rid);
353 : : /* no need to del if rid is 0 since there is no associated resource
354 : : * if rid from the entry is equal to the incoming fid, then we have a
355 : : * recursive delete, so don't follow the rid.
356 : : */
357 [ # # # # ]: 0 : if (rid && rid != fid) {
358 : : /* Destroy the flow associated with the shared flow id */
359 [ # # ]: 0 : if (ulp_mapper_flow_destroy(ulp_ctx, BNXT_ULP_FDB_TYPE_RID,
360 : : rid))
361 : 0 : BNXT_TF_DBG(ERR,
362 : : "Error in deleting shared resource id %x\n",
363 : : rid);
364 : : }
365 : :
366 : : /* Delete the entry from the hash table */
367 [ # # ]: 0 : if (gen_tbl_list->hash_tbl)
368 : 0 : ulp_gen_hash_tbl_list_del(gen_tbl_list->hash_tbl, &hash_entry);
369 : :
370 : : /* clear the byte data of the generic table entry */
371 : 0 : memset(entry.byte_data, 0, entry.byte_data_size);
372 : :
373 : 0 : return 0;
374 : : }
375 : :
376 : : /*
377 : : * Write the generic table list hash entry
378 : : *
379 : : * tbl_list [in] - pointer to the generic table list
380 : : * hash_entry [in] - Hash table entry
381 : : * gen_tbl_ent [out] - generic table entry
382 : : *
383 : : * returns 0 on success.
384 : : */
385 : : int32_t
386 : 0 : ulp_mapper_gen_tbl_hash_entry_add(struct ulp_mapper_gen_tbl_list *tbl_list,
387 : : struct ulp_gen_hash_entry_params *hash_entry,
388 : : struct ulp_mapper_gen_tbl_entry *gen_tbl_ent)
389 : : {
390 : : uint32_t key;
391 : : int32_t rc = 0;
392 : :
393 [ # # # # ]: 0 : switch (hash_entry->search_flag) {
394 : 0 : case ULP_GEN_HASH_SEARCH_FOUND:
395 : 0 : BNXT_TF_DBG(ERR, "%s: gen hash entry already present\n",
396 : : tbl_list->gen_tbl_name);
397 : 0 : return -EINVAL;
398 : 0 : case ULP_GEN_HASH_SEARCH_FULL:
399 : 0 : BNXT_TF_DBG(ERR, "%s: gen hash table is full\n",
400 : : tbl_list->gen_tbl_name);
401 : 0 : return -EINVAL;
402 : 0 : case ULP_GEN_HASH_SEARCH_MISSED:
403 : 0 : rc = ulp_gen_hash_tbl_list_add(tbl_list->hash_tbl, hash_entry);
404 [ # # ]: 0 : if (rc) {
405 : 0 : BNXT_TF_DBG(ERR, "%s: gen hash table add failed\n",
406 : : tbl_list->gen_tbl_name);
407 : 0 : return -EINVAL;
408 : : }
409 : 0 : key = hash_entry->key_idx;
410 : 0 : gen_tbl_ent->ref_count = &tbl_list->container.ref_count[key];
411 : 0 : gen_tbl_ent->byte_data_size =
412 : 0 : tbl_list->container.byte_data_size;
413 : 0 : gen_tbl_ent->byte_data = &tbl_list->container.byte_data[key *
414 : : gen_tbl_ent->byte_data_size];
415 : 0 : gen_tbl_ent->byte_order = tbl_list->container.byte_order;
416 : : break;
417 : 0 : default:
418 : 0 : BNXT_TF_DBG(ERR, "%s: invalid search flag\n",
419 : : tbl_list->gen_tbl_name);
420 : 0 : return -EINVAL;
421 : : }
422 : :
423 : 0 : return rc;
424 : : }
|