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 *shadow_tbl_db[TF_DIR_MAX];
35 * Init flag, set on bind and cleared on unbind
40 * Shadow init flag, set on bind and cleared on unbind
42 static uint8_t shadow_init;
45 tf_tbl_bind(struct tf *tfp,
46 struct tf_tbl_cfg_parms *parms)
49 struct tf_rm_create_db_parms db_cfg = { 0 };
50 struct tbl_rm_db *tbl_db;
51 struct tfp_calloc_parms cparms;
53 TF_CHECK_PARMS2(tfp, parms);
57 "Table DB already initialized\n");
61 memset(&db_cfg, 0, sizeof(db_cfg));
63 cparms.size = sizeof(struct tbl_rm_db);
65 if (tfp_calloc(&cparms) != 0) {
66 TFP_DRV_LOG(ERR, "tbl_rm_db alloc error %s\n",
71 tbl_db = cparms.mem_va;
72 for (i = 0; i < TF_DIR_MAX; i++)
73 tbl_db->tbl_db[i] = NULL;
74 tf_session_set_db(tfp, TF_MODULE_TYPE_TABLE, tbl_db);
76 db_cfg.num_elements = parms->num_elements;
77 db_cfg.module = TF_MODULE_TYPE_TABLE;
78 db_cfg.num_elements = parms->num_elements;
79 db_cfg.cfg = parms->cfg;
81 for (d = 0; d < TF_DIR_MAX; d++) {
83 db_cfg.alloc_cnt = parms->resources->tbl_cnt[d].cnt;
84 db_cfg.rm_db = (void *)&tbl_db->tbl_db[d];
86 rc = tf_rm_create_db(tfp, &db_cfg);
89 "%s: Table DB creation failed\n",
98 "Table Type - initialized\n");
104 tf_tbl_unbind(struct tf *tfp)
108 struct tf_rm_free_db_parms fparms = { 0 };
109 struct tbl_rm_db *tbl_db;
110 void *tbl_db_ptr = NULL;
111 TF_CHECK_PARMS1(tfp);
113 /* Bail if nothing has been initialized */
116 "No Table DBs created\n");
120 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
123 "Failed to get em_ext_db from session, rc:%s\n",
127 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
129 for (i = 0; i < TF_DIR_MAX; i++) {
131 fparms.rm_db = tbl_db->tbl_db[i];
132 rc = tf_rm_free_db(tfp, &fparms);
136 tbl_db->tbl_db[i] = NULL;
146 tf_tbl_alloc(struct tf *tfp __rte_unused,
147 struct tf_tbl_alloc_parms *parms)
151 struct tf_rm_allocate_parms aparms = { 0 };
152 struct tf_session *tfs;
153 struct tf_dev_info *dev;
154 uint16_t base = 0, shift = 0;
155 struct tbl_rm_db *tbl_db;
156 void *tbl_db_ptr = NULL;
158 TF_CHECK_PARMS2(tfp, parms);
162 "%s: No Table DBs created\n",
163 tf_dir_2_str(parms->dir));
167 /* Retrieve the session information */
168 rc = tf_session_get_session_internal(tfp, &tfs);
172 /* Retrieve the device information */
173 rc = tf_session_get_device(tfs, &dev);
177 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
180 "Failed to get em_ext_db from session, rc:%s\n",
184 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
186 /* Only get table info if required for the device */
187 if (dev->ops->tf_dev_get_tbl_info) {
188 rc = dev->ops->tf_dev_get_tbl_info(tfp,
189 tbl_db->tbl_db[parms->dir],
195 "%s: Failed to get table info:%d\n",
196 tf_dir_2_str(parms->dir),
202 /* Allocate requested element */
203 aparms.rm_db = tbl_db->tbl_db[parms->dir];
204 aparms.subtype = parms->type;
206 rc = tf_rm_allocate(&aparms);
209 "%s: Failed allocate, type:%d\n",
210 tf_dir_2_str(parms->dir),
215 TF_TBL_RM_TO_PTR(&idx, idx, base, shift);
222 tf_tbl_free(struct tf *tfp __rte_unused,
223 struct tf_tbl_free_parms *parms)
226 struct tf_rm_is_allocated_parms aparms = { 0 };
227 struct tf_rm_free_parms fparms = { 0 };
229 struct tf_session *tfs;
230 struct tf_dev_info *dev;
231 uint16_t base = 0, shift = 0;
232 struct tbl_rm_db *tbl_db;
233 void *tbl_db_ptr = NULL;
235 TF_CHECK_PARMS2(tfp, parms);
239 "%s: No Table DBs created\n",
240 tf_dir_2_str(parms->dir));
243 /* Retrieve the session information */
244 rc = tf_session_get_session_internal(tfp, &tfs);
248 /* Retrieve the device information */
249 rc = tf_session_get_device(tfs, &dev);
253 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
256 "Failed to get em_ext_db from session, rc:%s\n",
260 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
262 /* Only get table info if required for the device */
263 if (dev->ops->tf_dev_get_tbl_info) {
264 rc = dev->ops->tf_dev_get_tbl_info(tfp,
265 tbl_db->tbl_db[parms->dir],
271 "%s: Failed to get table info:%d\n",
272 tf_dir_2_str(parms->dir),
278 /* Check if element is in use */
279 aparms.rm_db = tbl_db->tbl_db[parms->dir];
280 aparms.subtype = parms->type;
282 TF_TBL_PTR_TO_RM(&aparms.index, parms->idx, base, shift);
284 aparms.allocated = &allocated;
285 rc = tf_rm_is_allocated(&aparms);
289 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
291 "%s: Entry already free, type:%d, index:%d\n",
292 tf_dir_2_str(parms->dir),
297 /* Free requested element */
298 fparms.rm_db = tbl_db->tbl_db[parms->dir];
299 fparms.subtype = parms->type;
301 TF_TBL_PTR_TO_RM(&fparms.index, parms->idx, base, shift);
303 rc = tf_rm_free(&fparms);
306 "%s: Free failed, type:%d, index:%d\n",
307 tf_dir_2_str(parms->dir),
317 tf_tbl_alloc_search(struct tf *tfp,
318 struct tf_tbl_alloc_search_parms *parms)
321 TF_CHECK_PARMS2(tfp, parms);
323 if (!shadow_init || !shadow_tbl_db[parms->dir]) {
324 TFP_DRV_LOG(ERR, "%s: Shadow TBL not initialized.\n",
325 tf_dir_2_str(parms->dir));
333 tf_tbl_set(struct tf *tfp,
334 struct tf_tbl_set_parms *parms)
339 struct tf_rm_is_allocated_parms aparms = { 0 };
340 struct tf_rm_get_hcapi_parms hparms = { 0 };
341 struct tf_session *tfs;
342 struct tf_dev_info *dev;
343 uint16_t base = 0, shift = 0;
344 struct tbl_rm_db *tbl_db;
345 void *tbl_db_ptr = NULL;
347 TF_CHECK_PARMS3(tfp, parms, parms->data);
351 "%s: No Table DBs created\n",
352 tf_dir_2_str(parms->dir));
356 /* Retrieve the session information */
357 rc = tf_session_get_session_internal(tfp, &tfs);
361 /* Retrieve the device information */
362 rc = tf_session_get_device(tfs, &dev);
366 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
369 "Failed to get em_ext_db from session, rc:%s\n",
373 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
375 /* Only get table info if required for the device */
376 if (dev->ops->tf_dev_get_tbl_info) {
377 rc = dev->ops->tf_dev_get_tbl_info(tfp,
378 tbl_db->tbl_db[parms->dir],
384 "%s: Failed to get table info:%d\n",
385 tf_dir_2_str(parms->dir),
391 /* Verify that the entry has been previously allocated */
392 aparms.rm_db = tbl_db->tbl_db[parms->dir];
393 aparms.subtype = parms->type;
394 TF_TBL_PTR_TO_RM(&aparms.index, parms->idx, base, shift);
396 aparms.allocated = &allocated;
397 rc = tf_rm_is_allocated(&aparms);
401 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
403 "%s, Invalid or not allocated index, type:%d, idx:%d\n",
404 tf_dir_2_str(parms->dir),
411 hparms.rm_db = tbl_db->tbl_db[parms->dir];
412 hparms.subtype = parms->type;
413 hparms.hcapi_type = &hcapi_type;
414 rc = tf_rm_get_hcapi_type(&hparms);
417 "%s, Failed type lookup, type:%d, rc:%s\n",
418 tf_dir_2_str(parms->dir),
424 rc = tf_msg_set_tbl_entry(tfp,
427 parms->data_sz_in_bytes,
432 "%s, Set failed, type:%d, rc:%s\n",
433 tf_dir_2_str(parms->dir),
443 tf_tbl_get(struct tf *tfp,
444 struct tf_tbl_get_parms *parms)
449 struct tf_rm_is_allocated_parms aparms = { 0 };
450 struct tf_rm_get_hcapi_parms hparms = { 0 };
451 struct tf_session *tfs;
452 struct tf_dev_info *dev;
453 uint16_t base = 0, shift = 0;
454 struct tbl_rm_db *tbl_db;
455 void *tbl_db_ptr = NULL;
457 TF_CHECK_PARMS3(tfp, parms, parms->data);
461 "%s: No Table DBs created\n",
462 tf_dir_2_str(parms->dir));
467 /* Retrieve the session information */
468 rc = tf_session_get_session_internal(tfp, &tfs);
472 /* Retrieve the device information */
473 rc = tf_session_get_device(tfs, &dev);
477 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
480 "Failed to get em_ext_db from session, rc:%s\n",
484 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
486 /* Only get table info if required for the device */
487 if (dev->ops->tf_dev_get_tbl_info) {
488 rc = dev->ops->tf_dev_get_tbl_info(tfp,
489 tbl_db->tbl_db[parms->dir],
495 "%s: Failed to get table info:%d\n",
496 tf_dir_2_str(parms->dir),
502 /* Verify that the entry has been previously allocated */
503 aparms.rm_db = tbl_db->tbl_db[parms->dir];
504 aparms.subtype = parms->type;
505 TF_TBL_PTR_TO_RM(&aparms.index, parms->idx, base, shift);
507 aparms.allocated = &allocated;
508 rc = tf_rm_is_allocated(&aparms);
512 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
514 "%s, Invalid or not allocated index, type:%d, idx:%d\n",
515 tf_dir_2_str(parms->dir),
522 hparms.rm_db = tbl_db->tbl_db[parms->dir];
523 hparms.subtype = parms->type;
524 hparms.hcapi_type = &hcapi_type;
525 rc = tf_rm_get_hcapi_type(&hparms);
528 "%s, Failed type lookup, type:%d, rc:%s\n",
529 tf_dir_2_str(parms->dir),
536 rc = tf_msg_get_tbl_entry(tfp,
539 parms->data_sz_in_bytes,
544 "%s, Get failed, type:%d, rc:%s\n",
545 tf_dir_2_str(parms->dir),
555 tf_tbl_bulk_get(struct tf *tfp,
556 struct tf_tbl_get_bulk_parms *parms)
560 struct tf_rm_get_hcapi_parms hparms = { 0 };
561 struct tf_rm_check_indexes_in_range_parms cparms = { 0 };
562 struct tf_session *tfs;
563 struct tf_dev_info *dev;
564 uint16_t base = 0, shift = 0;
565 struct tbl_rm_db *tbl_db;
566 void *tbl_db_ptr = NULL;
568 TF_CHECK_PARMS2(tfp, parms);
572 "%s: No Table DBs created\n",
573 tf_dir_2_str(parms->dir));
578 /* Retrieve the session information */
579 rc = tf_session_get_session_internal(tfp, &tfs);
583 /* Retrieve the device information */
584 rc = tf_session_get_device(tfs, &dev);
588 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TABLE, &tbl_db_ptr);
591 "Failed to get em_ext_db from session, rc:%s\n",
595 tbl_db = (struct tbl_rm_db *)tbl_db_ptr;
597 /* Only get table info if required for the device */
598 if (dev->ops->tf_dev_get_tbl_info) {
599 rc = dev->ops->tf_dev_get_tbl_info(tfp,
600 tbl_db->tbl_db[parms->dir],
606 "%s: Failed to get table info:%d\n",
607 tf_dir_2_str(parms->dir),
613 /* Verify that the entries are in the range of reserved resources. */
614 cparms.rm_db = tbl_db->tbl_db[parms->dir];
615 cparms.subtype = parms->type;
617 TF_TBL_PTR_TO_RM(&cparms.starting_index, parms->starting_idx,
620 cparms.num_entries = parms->num_entries;
622 rc = tf_rm_check_indexes_in_range(&cparms);
625 "%s, Invalid or %d index starting from %d"
626 " not in range, type:%d",
627 tf_dir_2_str(parms->dir),
634 hparms.rm_db = tbl_db->tbl_db[parms->dir];
635 hparms.subtype = parms->type;
636 hparms.hcapi_type = &hcapi_type;
637 rc = tf_rm_get_hcapi_type(&hparms);
640 "%s, Failed type lookup, type:%d, rc:%s\n",
641 tf_dir_2_str(parms->dir),
647 /* Get the entries */
648 rc = tf_msg_bulk_get_tbl_entry(tfp,
653 parms->entry_sz_in_bytes,
654 parms->physical_mem_addr);
657 "%s, Bulk get failed, type:%d, rc:%s\n",
658 tf_dir_2_str(parms->dir),