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_shadow_tbl.h"
17 #include "tf_session.h"
18 #include "tf_device.h"
26 static void *tbl_db[TF_DIR_MAX];
31 static void *shadow_tbl_db[TF_DIR_MAX];
34 * Init flag, set on bind and cleared on unbind
39 * Shadow init flag, set on bind and cleared on unbind
41 static uint8_t shadow_init;
44 tf_tbl_bind(struct tf *tfp,
45 struct tf_tbl_cfg_parms *parms)
48 struct tf_rm_alloc_info info;
49 struct tf_rm_free_db_parms fparms;
50 struct tf_shadow_tbl_free_db_parms fshadow;
51 struct tf_rm_get_alloc_info_parms ainfo;
52 struct tf_shadow_tbl_cfg_parms shadow_cfg;
53 struct tf_shadow_tbl_create_db_parms shadow_cdb;
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.type = TF_DEVICE_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",
83 /* Initialize the Shadow Table. */
84 if (parms->shadow_copy) {
85 for (d = 0; d < TF_DIR_MAX; d++) {
86 memset(&shadow_cfg, 0, sizeof(shadow_cfg));
87 memset(&shadow_cdb, 0, sizeof(shadow_cdb));
88 /* Get the base addresses of the tables */
89 for (i = 0; i < TF_TBL_TYPE_MAX; i++) {
90 memset(&info, 0, sizeof(info));
92 if (!parms->resources->tbl_cnt[d].cnt[i])
94 ainfo.rm_db = tbl_db[d];
97 rc = tf_rm_get_info(&ainfo);
101 shadow_cfg.base_addr[i] = info.entry.start;
104 /* Create the shadow db */
105 shadow_cfg.alloc_cnt =
106 parms->resources->tbl_cnt[d].cnt;
107 shadow_cfg.num_entries = parms->num_elements;
109 shadow_cdb.shadow_db = &shadow_tbl_db[d];
110 shadow_cdb.cfg = &shadow_cfg;
111 rc = tf_shadow_tbl_create_db(&shadow_cdb);
114 "Shadow TBL DB creation failed "
125 "Table Type - initialized\n");
129 for (d = 0; d < TF_DIR_MAX; d++) {
130 memset(&fparms, 0, sizeof(fparms));
132 fparms.rm_db = tbl_db[d];
133 /* Ignoring return here since we are in the error case */
134 (void)tf_rm_free_db(tfp, &fparms);
136 if (parms->shadow_copy) {
137 fshadow.shadow_db = shadow_tbl_db[d];
138 tf_shadow_tbl_free_db(&fshadow);
139 shadow_tbl_db[d] = NULL;
152 tf_tbl_unbind(struct tf *tfp)
156 struct tf_rm_free_db_parms fparms = { 0 };
157 struct tf_shadow_tbl_free_db_parms fshadow;
159 TF_CHECK_PARMS1(tfp);
161 /* Bail if nothing has been initialized */
164 "No Table DBs created\n");
168 for (i = 0; i < TF_DIR_MAX; i++) {
170 fparms.rm_db = tbl_db[i];
171 rc = tf_rm_free_db(tfp, &fparms);
178 memset(&fshadow, 0, sizeof(fshadow));
179 fshadow.shadow_db = shadow_tbl_db[i];
180 tf_shadow_tbl_free_db(&fshadow);
181 shadow_tbl_db[i] = NULL;
192 tf_tbl_alloc(struct tf *tfp __rte_unused,
193 struct tf_tbl_alloc_parms *parms)
197 struct tf_rm_allocate_parms aparms = { 0 };
199 TF_CHECK_PARMS2(tfp, parms);
203 "%s: No Table DBs created\n",
204 tf_dir_2_str(parms->dir));
208 /* Allocate requested element */
209 aparms.rm_db = tbl_db[parms->dir];
210 aparms.db_index = parms->type;
212 rc = tf_rm_allocate(&aparms);
215 "%s: Failed allocate, type:%d\n",
216 tf_dir_2_str(parms->dir),
227 tf_tbl_free(struct tf *tfp __rte_unused,
228 struct tf_tbl_free_parms *parms)
231 struct tf_rm_is_allocated_parms aparms = { 0 };
232 struct tf_rm_free_parms fparms = { 0 };
233 struct tf_shadow_tbl_remove_parms shparms;
236 TF_CHECK_PARMS2(tfp, parms);
240 "%s: No Table DBs created\n",
241 tf_dir_2_str(parms->dir));
245 /* Check if element is in use */
246 aparms.rm_db = tbl_db[parms->dir];
247 aparms.db_index = parms->type;
248 aparms.index = parms->idx;
249 aparms.allocated = &allocated;
250 rc = tf_rm_is_allocated(&aparms);
254 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
256 "%s: Entry already free, type:%d, index:%d\n",
257 tf_dir_2_str(parms->dir),
264 * The Shadow mgmt, if enabled, determines if the entry needs
268 memset(&shparms, 0, sizeof(shparms));
269 shparms.shadow_db = shadow_tbl_db[parms->dir];
270 shparms.fparms = parms;
271 rc = tf_shadow_tbl_remove(&shparms);
274 * Should not get here, log it and let the entry be
277 TFP_DRV_LOG(ERR, "%s: Shadow free fail, "
278 "type:%d index:%d deleting the entry.\n",
279 tf_dir_2_str(parms->dir),
284 * If the entry still has references, just return the
285 * ref count to the caller. No need to remove entry
288 if (parms->ref_cnt >= 1)
293 /* Free requested element */
294 fparms.rm_db = tbl_db[parms->dir];
295 fparms.db_index = parms->type;
296 fparms.index = parms->idx;
297 rc = tf_rm_free(&fparms);
300 "%s: Free failed, type:%d, index:%d\n",
301 tf_dir_2_str(parms->dir),
311 tf_tbl_alloc_search(struct tf *tfp,
312 struct tf_tbl_alloc_search_parms *parms)
316 struct tf_session *tfs;
317 struct tf_dev_info *dev;
318 struct tf_tbl_alloc_parms aparms;
319 struct tf_shadow_tbl_search_parms sparms;
320 struct tf_shadow_tbl_bind_index_parms bparms;
321 struct tf_tbl_free_parms fparms;
323 TF_CHECK_PARMS2(tfp, parms);
325 if (!shadow_init || !shadow_tbl_db[parms->dir]) {
326 TFP_DRV_LOG(ERR, "%s: Shadow TBL not initialized.\n",
327 tf_dir_2_str(parms->dir));
331 memset(&sparms, 0, sizeof(sparms));
332 sparms.sparms = parms;
333 sparms.shadow_db = shadow_tbl_db[parms->dir];
334 rc = tf_shadow_tbl_search(&sparms);
339 * The app didn't request us to alloc the entry, so return now.
340 * The hit should have been updated in the original search parm.
342 if (!parms->alloc || parms->search_status != MISS)
345 /* Retrieve the session information */
346 rc = tf_session_get_session(tfp, &tfs);
349 "%s: Failed to lookup session, rc:%s\n",
350 tf_dir_2_str(parms->dir),
355 /* Retrieve the device information */
356 rc = tf_session_get_device(tfs, &dev);
359 "%s: Failed to lookup device, rc:%s\n",
360 tf_dir_2_str(parms->dir),
365 /* Allocate the index */
366 if (dev->ops->tf_dev_alloc_tbl == NULL) {
369 "%s: Operation not supported, rc:%s\n",
370 tf_dir_2_str(parms->dir),
375 memset(&aparms, 0, sizeof(aparms));
376 aparms.dir = parms->dir;
377 aparms.type = parms->type;
378 aparms.tbl_scope_id = parms->tbl_scope_id;
380 rc = dev->ops->tf_dev_alloc_tbl(tfp, &aparms);
383 "%s: Table allocation failed, rc:%s\n",
384 tf_dir_2_str(parms->dir),
389 /* Bind the allocated index to the data */
390 memset(&bparms, 0, sizeof(bparms));
391 bparms.shadow_db = shadow_tbl_db[parms->dir];
392 bparms.dir = parms->dir;
393 bparms.type = parms->type;
395 bparms.data = parms->result;
396 bparms.data_sz_in_bytes = parms->result_sz_in_bytes;
397 bparms.hb_handle = sparms.hb_handle;
398 rc = tf_shadow_tbl_bind_index(&bparms);
400 /* Error binding entry, need to free the allocated idx */
401 if (dev->ops->tf_dev_free_tbl == NULL) {
404 "%s: Operation not supported, rc:%s\n",
405 tf_dir_2_str(parms->dir),
410 memset(&fparms, 0, sizeof(fparms));
411 fparms.dir = parms->dir;
412 fparms.type = parms->type;
414 frc = dev->ops->tf_dev_free_tbl(tfp, &fparms);
417 "%s: Failed free index allocated during "
419 tf_dir_2_str(parms->dir),
421 /* return the original failure. */
432 tf_tbl_set(struct tf *tfp,
433 struct tf_tbl_set_parms *parms)
438 struct tf_rm_is_allocated_parms aparms = { 0 };
439 struct tf_rm_get_hcapi_parms hparms = { 0 };
441 TF_CHECK_PARMS3(tfp, parms, parms->data);
445 "%s: No Table DBs created\n",
446 tf_dir_2_str(parms->dir));
450 /* Verify that the entry has been previously allocated */
451 aparms.rm_db = tbl_db[parms->dir];
452 aparms.db_index = parms->type;
453 aparms.index = parms->idx;
454 aparms.allocated = &allocated;
455 rc = tf_rm_is_allocated(&aparms);
459 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
461 "%s, Invalid or not allocated index, type:%d, idx:%d\n",
462 tf_dir_2_str(parms->dir),
469 hparms.rm_db = tbl_db[parms->dir];
470 hparms.db_index = parms->type;
471 hparms.hcapi_type = &hcapi_type;
472 rc = tf_rm_get_hcapi_type(&hparms);
475 "%s, Failed type lookup, type:%d, rc:%s\n",
476 tf_dir_2_str(parms->dir),
482 rc = tf_msg_set_tbl_entry(tfp,
485 parms->data_sz_in_bytes,
490 "%s, Set failed, type:%d, rc:%s\n",
491 tf_dir_2_str(parms->dir),
501 tf_tbl_get(struct tf *tfp,
502 struct tf_tbl_get_parms *parms)
507 struct tf_rm_is_allocated_parms aparms = { 0 };
508 struct tf_rm_get_hcapi_parms hparms = { 0 };
510 TF_CHECK_PARMS3(tfp, parms, parms->data);
514 "%s: No Table DBs created\n",
515 tf_dir_2_str(parms->dir));
519 /* Verify that the entry has been previously allocated */
520 aparms.rm_db = tbl_db[parms->dir];
521 aparms.db_index = parms->type;
522 aparms.index = parms->idx;
523 aparms.allocated = &allocated;
524 rc = tf_rm_is_allocated(&aparms);
528 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
530 "%s, Invalid or not allocated index, type:%d, idx:%d\n",
531 tf_dir_2_str(parms->dir),
538 hparms.rm_db = tbl_db[parms->dir];
539 hparms.db_index = parms->type;
540 hparms.hcapi_type = &hcapi_type;
541 rc = tf_rm_get_hcapi_type(&hparms);
544 "%s, Failed type lookup, type:%d, rc:%s\n",
545 tf_dir_2_str(parms->dir),
552 rc = tf_msg_get_tbl_entry(tfp,
555 parms->data_sz_in_bytes,
560 "%s, Get failed, type:%d, rc:%s\n",
561 tf_dir_2_str(parms->dir),
571 tf_tbl_bulk_get(struct tf *tfp,
572 struct tf_tbl_get_bulk_parms *parms)
576 struct tf_rm_get_hcapi_parms hparms = { 0 };
577 struct tf_rm_check_indexes_in_range_parms cparms = { 0 };
579 TF_CHECK_PARMS2(tfp, parms);
583 "%s: No Table DBs created\n",
584 tf_dir_2_str(parms->dir));
589 /* Verify that the entries are in the range of reserved resources. */
590 cparms.rm_db = tbl_db[parms->dir];
591 cparms.db_index = parms->type;
592 cparms.starting_index = parms->starting_idx;
593 cparms.num_entries = parms->num_entries;
595 rc = tf_rm_check_indexes_in_range(&cparms);
598 "%s, Invalid or %d index starting from %d"
599 " not in range, type:%d",
600 tf_dir_2_str(parms->dir),
607 hparms.rm_db = tbl_db[parms->dir];
608 hparms.db_index = parms->type;
609 hparms.hcapi_type = &hcapi_type;
610 rc = tf_rm_get_hcapi_type(&hparms);
613 "%s, Failed type lookup, type:%d, rc:%s\n",
614 tf_dir_2_str(parms->dir),
620 /* Get the entries */
621 rc = tf_msg_bulk_get_tbl_entry(tfp,
626 parms->entry_sz_in_bytes,
627 parms->physical_mem_addr);
630 "%s, Bulk get failed, type:%d, rc:%s\n",
631 tf_dir_2_str(parms->dir),