1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2019-2021 Broadcom
6 /* Truflow Table APIs and supporting code */
8 #include <rte_common.h>
11 #include "tf_common.h"
16 #include "tf_session.h"
17 #include "tf_device.h"
19 #define TF_TBL_RM_TO_PTR(new_idx, idx, base, shift) { \
20 *(new_idx) = (((idx) + (base)) << (shift)); \
23 #define TF_TBL_PTR_TO_RM(new_idx, idx, base, shift) { \
24 *(new_idx) = (((idx) >> (shift)) - (base)); \
32 static void *tbl_db[TF_DIR_MAX];
37 static void *shadow_tbl_db[TF_DIR_MAX];
40 * Init flag, set on bind and cleared on unbind
45 * Shadow init flag, set on bind and cleared on unbind
47 static uint8_t shadow_init;
50 tf_tbl_bind(struct tf *tfp,
51 struct tf_tbl_cfg_parms *parms)
54 struct tf_rm_create_db_parms db_cfg = { 0 };
56 TF_CHECK_PARMS2(tfp, parms);
60 "Table DB already initialized\n");
64 db_cfg.num_elements = parms->num_elements;
65 db_cfg.module = TF_MODULE_TYPE_TABLE;
66 db_cfg.num_elements = parms->num_elements;
67 db_cfg.cfg = parms->cfg;
69 for (d = 0; d < TF_DIR_MAX; d++) {
71 db_cfg.alloc_cnt = parms->resources->tbl_cnt[d].cnt;
72 db_cfg.rm_db = &tbl_db[d];
73 rc = tf_rm_create_db(tfp, &db_cfg);
76 "%s: Table DB creation failed\n",
86 "Table Type - initialized\n");
92 tf_tbl_unbind(struct tf *tfp)
96 struct tf_rm_free_db_parms fparms = { 0 };
99 /* Bail if nothing has been initialized */
102 "No Table DBs created\n");
106 for (i = 0; i < TF_DIR_MAX; i++) {
108 fparms.rm_db = tbl_db[i];
109 rc = tf_rm_free_db(tfp, &fparms);
123 tf_tbl_alloc(struct tf *tfp __rte_unused,
124 struct tf_tbl_alloc_parms *parms)
128 struct tf_rm_allocate_parms aparms = { 0 };
129 struct tf_session *tfs;
130 struct tf_dev_info *dev;
131 uint16_t base = 0, shift = 0;
133 TF_CHECK_PARMS2(tfp, parms);
137 "%s: No Table DBs created\n",
138 tf_dir_2_str(parms->dir));
142 /* Retrieve the session information */
143 rc = tf_session_get_session_internal(tfp, &tfs);
147 /* Retrieve the device information */
148 rc = tf_session_get_device(tfs, &dev);
152 /* Only get table info if required for the device */
153 if (dev->ops->tf_dev_get_tbl_info) {
154 rc = dev->ops->tf_dev_get_tbl_info(tfp, tbl_db[parms->dir],
155 parms->type, &base, &shift);
158 "%s: Failed to get table info:%d\n",
159 tf_dir_2_str(parms->dir),
165 /* Allocate requested element */
166 aparms.rm_db = tbl_db[parms->dir];
167 aparms.subtype = parms->type;
169 rc = tf_rm_allocate(&aparms);
172 "%s: Failed allocate, type:%d\n",
173 tf_dir_2_str(parms->dir),
178 TF_TBL_RM_TO_PTR(&idx, idx, base, shift);
185 tf_tbl_free(struct tf *tfp __rte_unused,
186 struct tf_tbl_free_parms *parms)
189 struct tf_rm_is_allocated_parms aparms = { 0 };
190 struct tf_rm_free_parms fparms = { 0 };
192 struct tf_session *tfs;
193 struct tf_dev_info *dev;
194 uint16_t base = 0, shift = 0;
196 TF_CHECK_PARMS2(tfp, parms);
200 "%s: No Table DBs created\n",
201 tf_dir_2_str(parms->dir));
204 /* Retrieve the session information */
205 rc = tf_session_get_session_internal(tfp, &tfs);
209 /* Retrieve the device information */
210 rc = tf_session_get_device(tfs, &dev);
214 /* Only get table info if required for the device */
215 if (dev->ops->tf_dev_get_tbl_info) {
216 rc = dev->ops->tf_dev_get_tbl_info(tfp, tbl_db[parms->dir],
217 parms->type, &base, &shift);
220 "%s: Failed to get table info:%d\n",
221 tf_dir_2_str(parms->dir),
227 /* Check if element is in use */
228 aparms.rm_db = tbl_db[parms->dir];
229 aparms.subtype = parms->type;
231 TF_TBL_PTR_TO_RM(&aparms.index, parms->idx, base, shift);
233 aparms.allocated = &allocated;
234 rc = tf_rm_is_allocated(&aparms);
238 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
240 "%s: Entry already free, type:%d, index:%d\n",
241 tf_dir_2_str(parms->dir),
246 /* Free requested element */
247 fparms.rm_db = tbl_db[parms->dir];
248 fparms.subtype = parms->type;
250 TF_TBL_PTR_TO_RM(&fparms.index, parms->idx, base, shift);
252 rc = tf_rm_free(&fparms);
255 "%s: Free failed, type:%d, index:%d\n",
256 tf_dir_2_str(parms->dir),
266 tf_tbl_alloc_search(struct tf *tfp,
267 struct tf_tbl_alloc_search_parms *parms)
270 TF_CHECK_PARMS2(tfp, parms);
272 if (!shadow_init || !shadow_tbl_db[parms->dir]) {
273 TFP_DRV_LOG(ERR, "%s: Shadow TBL not initialized.\n",
274 tf_dir_2_str(parms->dir));
282 tf_tbl_set(struct tf *tfp,
283 struct tf_tbl_set_parms *parms)
288 struct tf_rm_is_allocated_parms aparms = { 0 };
289 struct tf_rm_get_hcapi_parms hparms = { 0 };
290 struct tf_session *tfs;
291 struct tf_dev_info *dev;
292 uint16_t base = 0, shift = 0;
294 TF_CHECK_PARMS3(tfp, parms, parms->data);
298 "%s: No Table DBs created\n",
299 tf_dir_2_str(parms->dir));
303 /* Retrieve the session information */
304 rc = tf_session_get_session_internal(tfp, &tfs);
308 /* Retrieve the device information */
309 rc = tf_session_get_device(tfs, &dev);
313 /* Only get table info if required for the device */
314 if (dev->ops->tf_dev_get_tbl_info) {
315 rc = dev->ops->tf_dev_get_tbl_info(tfp, tbl_db[parms->dir],
316 parms->type, &base, &shift);
319 "%s: Failed to get table info:%d\n",
320 tf_dir_2_str(parms->dir),
326 /* Verify that the entry has been previously allocated */
327 aparms.rm_db = tbl_db[parms->dir];
328 aparms.subtype = parms->type;
329 TF_TBL_PTR_TO_RM(&aparms.index, parms->idx, base, shift);
331 aparms.allocated = &allocated;
332 rc = tf_rm_is_allocated(&aparms);
336 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
338 "%s, Invalid or not allocated index, type:%d, idx:%d\n",
339 tf_dir_2_str(parms->dir),
346 hparms.rm_db = tbl_db[parms->dir];
347 hparms.subtype = parms->type;
348 hparms.hcapi_type = &hcapi_type;
349 rc = tf_rm_get_hcapi_type(&hparms);
352 "%s, Failed type lookup, type:%d, rc:%s\n",
353 tf_dir_2_str(parms->dir),
359 rc = tf_msg_set_tbl_entry(tfp,
362 parms->data_sz_in_bytes,
367 "%s, Set failed, type:%d, rc:%s\n",
368 tf_dir_2_str(parms->dir),
378 tf_tbl_get(struct tf *tfp,
379 struct tf_tbl_get_parms *parms)
384 struct tf_rm_is_allocated_parms aparms = { 0 };
385 struct tf_rm_get_hcapi_parms hparms = { 0 };
386 struct tf_session *tfs;
387 struct tf_dev_info *dev;
388 uint16_t base = 0, shift = 0;
390 TF_CHECK_PARMS3(tfp, parms, parms->data);
394 "%s: No Table DBs created\n",
395 tf_dir_2_str(parms->dir));
400 /* Retrieve the session information */
401 rc = tf_session_get_session_internal(tfp, &tfs);
405 /* Retrieve the device information */
406 rc = tf_session_get_device(tfs, &dev);
410 /* Only get table info if required for the device */
411 if (dev->ops->tf_dev_get_tbl_info) {
412 rc = dev->ops->tf_dev_get_tbl_info(tfp, tbl_db[parms->dir],
413 parms->type, &base, &shift);
416 "%s: Failed to get table info:%d\n",
417 tf_dir_2_str(parms->dir),
423 /* Verify that the entry has been previously allocated */
424 aparms.rm_db = tbl_db[parms->dir];
425 aparms.subtype = parms->type;
426 TF_TBL_PTR_TO_RM(&aparms.index, parms->idx, base, shift);
428 aparms.allocated = &allocated;
429 rc = tf_rm_is_allocated(&aparms);
433 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
435 "%s, Invalid or not allocated index, type:%d, idx:%d\n",
436 tf_dir_2_str(parms->dir),
443 hparms.rm_db = tbl_db[parms->dir];
444 hparms.subtype = parms->type;
445 hparms.hcapi_type = &hcapi_type;
446 rc = tf_rm_get_hcapi_type(&hparms);
449 "%s, Failed type lookup, type:%d, rc:%s\n",
450 tf_dir_2_str(parms->dir),
457 rc = tf_msg_get_tbl_entry(tfp,
460 parms->data_sz_in_bytes,
465 "%s, Get failed, type:%d, rc:%s\n",
466 tf_dir_2_str(parms->dir),
476 tf_tbl_bulk_get(struct tf *tfp,
477 struct tf_tbl_get_bulk_parms *parms)
481 struct tf_rm_get_hcapi_parms hparms = { 0 };
482 struct tf_rm_check_indexes_in_range_parms cparms = { 0 };
483 struct tf_session *tfs;
484 struct tf_dev_info *dev;
485 uint16_t base = 0, shift = 0;
487 TF_CHECK_PARMS2(tfp, parms);
491 "%s: No Table DBs created\n",
492 tf_dir_2_str(parms->dir));
497 /* Retrieve the session information */
498 rc = tf_session_get_session_internal(tfp, &tfs);
502 /* Retrieve the device information */
503 rc = tf_session_get_device(tfs, &dev);
507 /* Only get table info if required for the device */
508 if (dev->ops->tf_dev_get_tbl_info) {
509 rc = dev->ops->tf_dev_get_tbl_info(tfp, tbl_db[parms->dir],
510 parms->type, &base, &shift);
513 "%s: Failed to get table info:%d\n",
514 tf_dir_2_str(parms->dir),
520 /* Verify that the entries are in the range of reserved resources. */
521 cparms.rm_db = tbl_db[parms->dir];
522 cparms.subtype = parms->type;
524 TF_TBL_PTR_TO_RM(&cparms.starting_index, parms->starting_idx,
527 cparms.num_entries = parms->num_entries;
529 rc = tf_rm_check_indexes_in_range(&cparms);
532 "%s, Invalid or %d index starting from %d"
533 " not in range, type:%d",
534 tf_dir_2_str(parms->dir),
541 hparms.rm_db = tbl_db[parms->dir];
542 hparms.subtype = parms->type;
543 hparms.hcapi_type = &hcapi_type;
544 rc = tf_rm_get_hcapi_type(&hparms);
547 "%s, Failed type lookup, type:%d, rc:%s\n",
548 tf_dir_2_str(parms->dir),
554 /* Get the entries */
555 rc = tf_msg_bulk_get_tbl_entry(tfp,
560 parms->entry_sz_in_bytes,
561 parms->physical_mem_addr);
564 "%s, Bulk get failed, type:%d, rc:%s\n",
565 tf_dir_2_str(parms->dir),