1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2019-2021 Broadcom
7 #include <rte_common.h>
9 #include "tf_tcam_shared.h"
11 #include "tf_common.h"
14 #include "tf_device.h"
16 #include "tf_session.h"
23 /** Shared WC TCAM pool identifiers
25 enum tf_tcam_shared_wc_pool_id {
26 TF_TCAM_SHARED_WC_POOL_HI = 0,
27 TF_TCAM_SHARED_WC_POOL_LO = 1,
28 TF_TCAM_SHARED_WC_POOL_MAX = 2
31 /** Get string representation of a WC TCAM shared pool id
34 tf_pool_2_str(enum tf_tcam_shared_wc_pool_id id)
37 case TF_TCAM_SHARED_WC_POOL_HI:
38 return "TCAM_SHARED_WC_POOL_HI";
39 case TF_TCAM_SHARED_WC_POOL_LO:
40 return "TCAM_SHARED_WC_POOL_LO";
42 return "Invalid TCAM_SHARED_WC_POOL";
46 /** The WC TCAM shared pool datastructure
48 struct tf_tcam_shared_wc_pool {
49 /** Start and stride data */
50 struct tf_resource_info info;
52 struct bitalloc *pool;
55 struct tf_tcam_shared_wc_pools {
56 struct tf_tcam_shared_wc_pool db[TF_DIR_MAX][TF_TCAM_SHARED_WC_POOL_MAX];
59 /** The WC TCAM shared pool declarations
61 /* struct tf_tcam_shared_wc_pool tcam_shared_wc[TF_DIR_MAX][TF_TCAM_SHARED_WC_POOL_MAX]; */
64 tf_tcam_shared_create_db(struct tf_tcam_shared_wc_pools **db)
66 struct tfp_calloc_parms cparms;
71 cparms.size = sizeof(struct tf_tcam_shared_wc_pools);
72 rc = tfp_calloc(&cparms);
75 "TCAM shared db allocation failed (%s)\n",
84 /** Create a WC TCAM shared pool
87 tf_tcam_shared_create_wc_pool(int dir,
88 enum tf_tcam_shared_wc_pool_id id,
91 struct tf_tcam_shared_wc_pools *tcam_shared_wc)
95 struct tfp_calloc_parms cparms;
99 pool_size = (BITALLOC_SIZEOF(stride) / sizeof(struct bitalloc));
100 cparms.nitems = pool_size;
101 cparms.alignment = 0;
102 cparms.size = sizeof(struct bitalloc);
103 rc = tfp_calloc(&cparms);
106 "%s: pool memory alloc failed %s:%s\n",
107 tf_dir_2_str(dir), tf_pool_2_str(id),
111 tcam_shared_wc->db[dir][id].pool = (struct bitalloc *)cparms.mem_va;
113 rc = ba_init(tcam_shared_wc->db[dir][id].pool,
119 "%s: pool bitalloc failed %s\n",
120 tf_dir_2_str(dir), tf_pool_2_str(id));
124 tcam_shared_wc->db[dir][id].info.start = start;
125 tcam_shared_wc->db[dir][id].info.stride = stride;
129 /** Free a WC TCAM shared pool
132 tf_tcam_shared_free_wc_pool(int dir,
133 enum tf_tcam_shared_wc_pool_id id,
134 struct tf_tcam_shared_wc_pools *tcam_shared_wc)
137 TF_CHECK_PARMS1(tcam_shared_wc);
139 tcam_shared_wc->db[dir][id].info.start = 0;
140 tcam_shared_wc->db[dir][id].info.stride = 0;
142 if (tcam_shared_wc->db[dir][id].pool)
143 tfp_free((void *)tcam_shared_wc->db[dir][id].pool);
147 /** Get the number of WC TCAM slices allocated during 1 allocation/free
150 tf_tcam_shared_get_slices(struct tf *tfp,
151 struct tf_dev_info *dev,
152 uint16_t *num_slices)
156 if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
159 "Operation not supported, rc:%s\n", strerror(-rc));
162 rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
163 TF_TCAM_TBL_TYPE_WC_TCAM,
170 tf_tcam_db_valid(struct tf *tfp,
173 struct tcam_rm_db *tcam_db;
174 void *tcam_db_ptr = NULL;
177 TF_CHECK_PARMS1(tfp);
179 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
183 tcam_db = (struct tcam_rm_db *)tcam_db_ptr;
185 if (tcam_db->tcam_db[dir])
192 tf_tcam_shared_get_rm_info(struct tf *tfp,
194 uint16_t *hcapi_type,
195 struct tf_rm_alloc_info *info)
198 struct tcam_rm_db *tcam_db;
199 void *tcam_db_ptr = NULL;
200 struct tf_rm_get_alloc_info_parms ainfo;
201 struct tf_rm_get_hcapi_parms hparms;
203 TF_CHECK_PARMS3(tfp, hcapi_type, info);
205 rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
208 "Tcam_db is not initialized, rc:%s\n",
212 tcam_db = (struct tcam_rm_db *)tcam_db_ptr;
214 /* Convert TF type to HCAPI RM type */
215 memset(&hparms, 0, sizeof(hparms));
216 hparms.rm_db = tcam_db->tcam_db[dir];
217 hparms.subtype = TF_TCAM_TBL_TYPE_WC_TCAM;
218 hparms.hcapi_type = hcapi_type;
220 rc = tf_rm_get_hcapi_type(&hparms);
223 "%s: Get RM hcapi type failed %s\n",
229 memset(info, 0, sizeof(struct tf_rm_alloc_info));
230 ainfo.rm_db = tcam_db->tcam_db[dir];
231 ainfo.subtype = TF_TCAM_TBL_TYPE_WC_TCAM;
234 rc = tf_rm_get_info(&ainfo);
237 "%s: TCAM rm info get failed %s\n",
246 * tf_tcam_shared_bind
249 tf_tcam_shared_bind(struct tf *tfp,
250 struct tf_tcam_cfg_parms *parms)
253 struct tf_session *tfs;
254 struct tf_dev_info *dev;
255 struct tf_rm_alloc_info info;
256 uint16_t start, stride;
259 struct tf_tcam_shared_wc_pools *tcam_shared_wc = NULL;
261 TF_CHECK_PARMS2(tfp, parms);
263 /* Perform normal bind
265 rc = tf_tcam_bind(tfp, parms);
269 /* After the normal TCAM bind, if this is a shared session
270 * create all required databases for the WC_HI and WC_LO pools
272 rc = tf_session_get_session_internal(tfp, &tfs);
275 "Session access failure: %s\n", strerror(-rc));
278 if (tf_session_is_shared_session(tfs)) {
279 /* Retrieve the device information */
280 rc = tf_session_get_device(tfs, &dev);
284 rc = tf_tcam_shared_get_slices(tfp,
290 tf_tcam_shared_create_db(&tcam_shared_wc);
293 /* If there are WC TCAM entries, create 2 pools each with 1/2
294 * the total number of entries
296 for (dir = 0; dir < TF_DIR_MAX; dir++) {
297 if (!tf_tcam_db_valid(tfp, dir))
300 rc = tf_tcam_shared_get_rm_info(tfp,
306 "%s: TCAM rm info get failed\n",
311 start = info.entry.start;
312 stride = info.entry.stride / 2;
314 tf_tcam_shared_create_wc_pool(dir,
315 TF_TCAM_SHARED_WC_POOL_HI,
321 tf_tcam_shared_create_wc_pool(dir,
322 TF_TCAM_SHARED_WC_POOL_LO,
327 tf_session_set_tcam_shared_db(tfp, (void *)tcam_shared_wc);
334 * tf_tcam_shared_unbind
337 tf_tcam_shared_unbind(struct tf *tfp)
340 struct tf_session *tfs;
341 void *tcam_shared_db_ptr = NULL;
342 struct tf_tcam_shared_wc_pools *tcam_shared_wc;
344 TF_CHECK_PARMS1(tfp);
346 /* Perform normal unbind, this will write all the
347 * allocated TCAM entries in the shared session.
349 rc = tf_tcam_unbind(tfp);
353 /* Retrieve the session information */
354 rc = tf_session_get_session_internal(tfp, &tfs);
358 rc = tf_session_get_tcam_shared_db(tfp, (void *)&tcam_shared_db_ptr);
361 "Failed to get tcam_shared_db from session, rc:%s\n",
365 tcam_shared_wc = (struct tf_tcam_shared_wc_pools *)tcam_shared_db_ptr;
367 /* If we are the shared session
369 if (tf_session_is_shared_session(tfs)) {
370 /* If there are WC TCAM entries allocated, free them
372 for (dir = 0; dir < TF_DIR_MAX; dir++) {
373 tf_tcam_shared_free_wc_pool(dir,
374 TF_TCAM_SHARED_WC_POOL_HI,
376 tf_tcam_shared_free_wc_pool(dir,
377 TF_TCAM_SHARED_WC_POOL_LO,
384 * tf_tcam_shared_alloc
387 tf_tcam_shared_alloc(struct tf *tfp,
388 struct tf_tcam_alloc_parms *parms)
391 struct tf_session *tfs;
392 struct tf_dev_info *dev;
394 struct bitalloc *pool;
395 enum tf_tcam_shared_wc_pool_id id;
397 struct tf_tcam_shared_wc_pools *tcam_shared_wc;
398 void *tcam_shared_db_ptr = NULL;
400 TF_CHECK_PARMS2(tfp, parms);
402 /* Retrieve the session information */
403 rc = tf_session_get_session_internal(tfp, &tfs);
407 /* If we aren't the shared session or the type is
408 * not one of the special WC TCAM types, call the normal
411 if (!tf_session_is_shared_session(tfs) ||
412 (parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_HIGH &&
413 parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_LOW)) {
414 /* Perform normal alloc
416 rc = tf_tcam_alloc(tfp, parms);
420 if (!tf_tcam_db_valid(tfp, parms->dir)) {
422 "%s: tcam shared pool doesn't exist\n",
423 tf_dir_2_str(parms->dir));
427 rc = tf_session_get_tcam_shared_db(tfp, (void *)&tcam_shared_db_ptr);
430 "Failed to get tcam_shared_db from session, rc:%s\n",
434 tcam_shared_wc = (struct tf_tcam_shared_wc_pools *)tcam_shared_db_ptr;
436 if (parms->type == TF_TCAM_TBL_TYPE_WC_TCAM_HIGH)
437 id = TF_TCAM_SHARED_WC_POOL_HI;
439 id = TF_TCAM_SHARED_WC_POOL_LO;
441 /* Retrieve the device information */
442 rc = tf_session_get_device(tfs, &dev);
446 rc = tf_tcam_shared_get_slices(tfp, dev, &num_slices);
450 pool = tcam_shared_wc->db[parms->dir][id].pool;
452 for (i = 0; i < num_slices; i++) {
454 * priority 0: allocate from top of the tcam i.e. high
455 * priority !0: allocate index from bottom i.e lowest
458 log_idx = ba_alloc_reverse(pool);
460 log_idx = ba_alloc(pool);
461 if (log_idx == BA_FAIL) {
463 "%s: Allocation failed, rc:%s\n",
464 tf_dir_2_str(parms->dir),
468 /* return the index without the start of each row */
470 parms->idx = log_idx;
476 tf_tcam_shared_free(struct tf *tfp,
477 struct tf_tcam_free_parms *parms)
480 struct tf_session *tfs;
481 struct tf_dev_info *dev;
486 struct bitalloc *pool;
487 enum tf_tcam_shared_wc_pool_id id;
488 struct tf_tcam_free_parms nparms;
491 struct tf_rm_alloc_info info;
492 void *tcam_shared_db_ptr = NULL;
493 struct tf_tcam_shared_wc_pools *tcam_shared_wc;
495 TF_CHECK_PARMS2(tfp, parms);
497 /* Retrieve the session information */
498 rc = tf_session_get_session_internal(tfp, &tfs);
502 /* If we aren't the shared session or the type is
503 * not one of the special WC TCAM types, call the normal
506 if (!tf_session_is_shared_session(tfs) ||
507 (parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_HIGH &&
508 parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_LOW)) {
509 /* Perform normal free
511 rc = tf_tcam_free(tfp, parms);
515 if (!tf_tcam_db_valid(tfp, parms->dir)) {
517 "%s: tcam shared pool doesn't exist\n",
518 tf_dir_2_str(parms->dir));
522 rc = tf_session_get_tcam_shared_db(tfp, (void *)&tcam_shared_db_ptr);
525 "Failed to get tcam_shared_db from session, rc:%s\n",
529 tcam_shared_wc = (struct tf_tcam_shared_wc_pools *)tcam_shared_db_ptr;
532 if (parms->type == TF_TCAM_TBL_TYPE_WC_TCAM_HIGH)
533 id = TF_TCAM_SHARED_WC_POOL_HI;
535 id = TF_TCAM_SHARED_WC_POOL_LO;
537 /* Retrieve the device information */
538 rc = tf_session_get_device(tfs, &dev);
542 rc = tf_tcam_shared_get_slices(tfp, dev, &num_slices);
546 rc = tf_tcam_shared_get_rm_info(tfp,
552 "%s: TCAM rm info get failed\n",
553 tf_dir_2_str(parms->dir));
557 pool = tcam_shared_wc->db[parms->dir][id].pool;
558 start = tcam_shared_wc->db[parms->dir][id].info.start;
560 if (parms->idx % num_slices) {
562 "%s: TCAM reserved resource is not multiple of %d\n",
563 tf_dir_2_str(parms->dir), num_slices);
567 phy_idx = parms->idx + start;
568 allocated = ba_inuse(pool, parms->idx);
570 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
572 "%s: Entry already free, type:%d, idx:%d\n",
573 tf_dir_2_str(parms->dir), parms->type, parms->idx);
577 for (i = 0; i < num_slices; i++) {
578 rc = ba_free(pool, parms->idx + i);
581 "%s: Free failed, type:%s, idx:%d\n",
582 tf_dir_2_str(parms->dir),
583 tf_tcam_tbl_2_str(parms->type),
589 /* Override HI/LO type with parent WC TCAM type */
591 nparms.type = TF_TCAM_TBL_TYPE_WC_TCAM;
592 nparms.hcapi_type = hcapi_type;
593 nparms.idx = phy_idx;
595 rc = tf_msg_tcam_entry_free(tfp, dev, &nparms);
599 "%s: %s: log%d free failed, rc:%s\n",
600 tf_dir_2_str(nparms.dir),
601 tf_tcam_tbl_2_str(nparms.type),
610 tf_tcam_shared_set(struct tf *tfp __rte_unused,
611 struct tf_tcam_set_parms *parms __rte_unused)
614 struct tf_session *tfs;
615 struct tf_dev_info *dev;
617 int phy_idx, log_idx;
619 struct tf_tcam_set_parms nparms;
620 struct bitalloc *pool;
622 enum tf_tcam_shared_wc_pool_id id;
624 struct tf_rm_alloc_info info;
625 struct tf_tcam_shared_wc_pools *tcam_shared_wc;
626 void *tcam_shared_db_ptr = NULL;
629 TF_CHECK_PARMS2(tfp, parms);
631 /* Retrieve the session information */
632 rc = tf_session_get_session_internal(tfp, &tfs);
636 /* If we aren't the shared session or one of our
639 if (!tf_session_is_shared_session(tfs) ||
640 (parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_HIGH &&
641 parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_LOW)) {
642 /* Perform normal set and exit
644 rc = tf_tcam_set(tfp, parms);
648 if (!tf_tcam_db_valid(tfp, parms->dir)) {
650 "%s: tcam shared pool doesn't exist\n",
651 tf_dir_2_str(parms->dir));
655 /* Retrieve the device information */
656 rc = tf_session_get_device(tfs, &dev);
660 if (parms->type == TF_TCAM_TBL_TYPE_WC_TCAM_HIGH)
661 id = TF_TCAM_SHARED_WC_POOL_HI;
663 id = TF_TCAM_SHARED_WC_POOL_LO;
665 rc = tf_session_get_tcam_shared_db(tfp, (void *)&tcam_shared_db_ptr);
668 "Failed to get tcam_shared_db from session, rc:%s\n",
672 tcam_shared_wc = (struct tf_tcam_shared_wc_pools *)tcam_shared_db_ptr;
674 pool = tcam_shared_wc->db[parms->dir][id].pool;
675 start = tcam_shared_wc->db[parms->dir][id].info.start;
677 log_idx = parms->idx;
678 phy_idx = parms->idx + start;
679 allocated = ba_inuse(pool, parms->idx);
681 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
683 "%s: Entry is not allocated, type:%d, logid:%d\n",
684 tf_dir_2_str(parms->dir), parms->type, log_idx);
687 rc = tf_tcam_shared_get_slices(tfp, dev, &num_slices);
691 if (parms->idx % num_slices) {
693 "%s: TCAM reserved resource is not multiple of %d\n",
694 tf_dir_2_str(parms->dir), num_slices);
697 rc = tf_tcam_shared_get_rm_info(tfp,
704 /* Override HI/LO type with parent WC TCAM type */
705 nparms.hcapi_type = hcapi_type;
706 nparms.dir = parms->dir;
707 nparms.type = TF_TCAM_TBL_TYPE_WC_TCAM;
708 nparms.idx = phy_idx;
709 nparms.key = parms->key;
710 nparms.mask = parms->mask;
711 nparms.key_size = parms->key_size;
712 nparms.result = parms->result;
713 nparms.result_size = parms->result_size;
715 rc = tf_msg_tcam_entry_set(tfp, dev, &nparms);
719 "%s: %s: phy entry %d set failed, rc:%s",
720 tf_dir_2_str(parms->dir),
721 tf_tcam_tbl_2_str(nparms.type),
730 tf_tcam_shared_get(struct tf *tfp __rte_unused,
731 struct tf_tcam_get_parms *parms)
734 struct tf_session *tfs;
735 struct tf_dev_info *dev;
737 int phy_idx, log_idx;
739 struct tf_tcam_get_parms nparms;
740 struct bitalloc *pool;
742 enum tf_tcam_shared_wc_pool_id id;
744 struct tf_rm_alloc_info info;
745 struct tf_tcam_shared_wc_pools *tcam_shared_wc;
746 void *tcam_shared_db_ptr = NULL;
748 TF_CHECK_PARMS2(tfp, parms);
750 /* Retrieve the session information */
751 rc = tf_session_get_session_internal(tfp, &tfs);
755 /* If we aren't the shared session or one of our
758 if (!tf_session_is_shared_session(tfs) ||
759 (parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_HIGH &&
760 parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_LOW)) {
761 /* Perform normal get and exit
763 rc = tf_tcam_get(tfp, parms);
767 if (!tf_tcam_db_valid(tfp, parms->dir)) {
769 "%s: tcam shared pool doesn't exist\n",
770 tf_dir_2_str(parms->dir));
774 /* Retrieve the device information */
775 rc = tf_session_get_device(tfs, &dev);
778 if (parms->type == TF_TCAM_TBL_TYPE_WC_TCAM_HIGH)
779 id = TF_TCAM_SHARED_WC_POOL_HI;
781 id = TF_TCAM_SHARED_WC_POOL_LO;
784 rc = tf_session_get_tcam_shared_db(tfp, (void *)&tcam_shared_db_ptr);
787 "Failed to get tcam_shared_db from session, rc:%s\n",
791 tcam_shared_wc = (struct tf_tcam_shared_wc_pools *)tcam_shared_db_ptr;
793 pool = tcam_shared_wc->db[parms->dir][id].pool;
794 start = tcam_shared_wc->db[parms->dir][id].info.start;
796 rc = tf_tcam_shared_get_slices(tfp, dev, &num_slices);
800 if (parms->idx % num_slices) {
802 "%s: TCAM reserved resource is not multiple of %d\n",
803 tf_dir_2_str(parms->dir), num_slices);
806 log_idx = parms->idx;
807 phy_idx = parms->idx + start;
808 allocated = ba_inuse(pool, parms->idx);
810 if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
812 "%s: Entry is not allocated, type:%d, logid:%d\n",
813 tf_dir_2_str(parms->dir), parms->type, log_idx);
817 rc = tf_tcam_shared_get_rm_info(tfp,
824 /* Override HI/LO type with parent WC TCAM type */
826 nparms.type = TF_TCAM_TBL_TYPE_WC_TCAM;
827 nparms.hcapi_type = hcapi_type;
828 nparms.idx = phy_idx;
830 rc = tf_msg_tcam_entry_get(tfp, dev, &nparms);
834 "%s: %s: Entry %d set failed, rc:%s",
835 tf_dir_2_str(nparms.dir),
836 tf_tcam_tbl_2_str(nparms.type),
844 /* Normally, device specific code wouldn't reside here, it belongs
845 * in a separate device specific function in tf_device_pxx.c.
846 * But this code is placed here as it is not a long term solution
847 * and we would like to have this code centrally located for easy
850 #define TF_TCAM_SHARED_KEY_SLICE_SZ_BYTES_P4 12
851 #define TF_TCAM_SHARED_REMAP_SZ_BYTES_P4 4
852 #define TF_TCAM_SHARED_KEY_SLICE_SZ_BYTES_P58 24
853 #define TF_TCAM_SHARED_REMAP_SZ_BYTES_P58 8
855 /* Temporary builder defines pulled in here and adjusted
856 * for max WC TCAM values
858 union tf_tmp_field_obj {
859 uint32_t words[(TF_TCAM_SHARED_REMAP_SZ_BYTES_P58 + 3) / 4];
860 uint8_t bytes[TF_TCAM_SHARED_REMAP_SZ_BYTES_P58];
864 uint32_t words[(TF_TCAM_SHARED_KEY_SLICE_SZ_BYTES_P58 + 3) / 4];
865 uint8_t bytes[TF_TCAM_SHARED_KEY_SLICE_SZ_BYTES_P58];
868 /** p58 has an enable bit, p4 does not
870 #define TF_TCAM_SHARED_ENTRY_ENABLE 0x8
872 /** Move a WC TCAM entry from the high offset to the same low offset
875 tf_tcam_shared_move_entry(struct tf *tfp,
876 struct tf_dev_info *dev,
887 struct tf_tcam_get_parms gparms;
888 struct tf_tcam_set_parms sparms;
889 struct tf_tcam_free_parms fparms;
890 union tf_tmp_key tcam_key_obj;
891 union tf_tmp_key tcam_key_msk_obj;
892 union tf_tmp_field_obj tcam_remap_obj;
894 memset(&tcam_key_obj, 0, sizeof(tcam_key_obj));
895 memset(&tcam_key_msk_obj, 0, sizeof(tcam_key_msk_obj));
896 memset(&tcam_remap_obj, 0, sizeof(tcam_remap_obj));
897 memset(&gparms, 0, sizeof(gparms));
899 if (num_slices > 1) {
901 "Only single slice supported");
905 gparms.hcapi_type = hcapi_type;
907 gparms.type = TF_TCAM_TBL_TYPE_WC_TCAM;
908 gparms.idx = sphy_idx;
909 gparms.key = (uint8_t *)&tcam_key_obj;
910 gparms.key_size = key_sz_bytes;
911 gparms.mask = (uint8_t *)&tcam_key_msk_obj;
912 gparms.result = (uint8_t *)&tcam_remap_obj;
913 gparms.result_size = remap_sz_bytes;
915 rc = tf_msg_tcam_entry_get(tfp, dev, &gparms);
919 "%s: WC_TCAM_HIGH: phyid(%d) get failed, rc:%s",
927 tcam_key_obj.bytes[0] |= TF_TCAM_SHARED_ENTRY_ENABLE;
929 /* Override HI/LO type with parent WC TCAM type */
930 sparms.hcapi_type = hcapi_type;
932 sparms.type = TF_TCAM_TBL_TYPE_WC_TCAM;
933 sparms.idx = dphy_idx;
934 sparms.key = gparms.key;
935 sparms.mask = gparms.mask;
936 sparms.key_size = gparms.key_size;
937 sparms.result = gparms.result;
938 sparms.result_size = gparms.result_size;
940 rc = tf_msg_tcam_entry_set(tfp, dev, &sparms);
944 "%s: WC_TCAM_LOW phyid(%d/0x%x) set failed, rc:%s",
952 /* Override HI/LO type with parent WC TCAM type */
954 fparms.type = TF_TCAM_TBL_TYPE_WC_TCAM;
955 fparms.hcapi_type = hcapi_type;
956 fparms.idx = sphy_idx;
958 rc = tf_msg_tcam_entry_free(tfp, dev, &fparms);
962 "%s: %s: phyid(%d/0x%x) free failed, rc:%s\n",
964 tf_tcam_tbl_2_str(fparms.type),
973 /** Move all shared WC TCAM entries from the high pool into the low pool
974 * and clear out the high pool entries.
977 int tf_tcam_shared_move(struct tf *tfp,
978 struct tf_move_tcam_shared_entries_parms *parms,
984 struct tf_session *tfs;
985 struct tf_dev_info *dev;
988 struct bitalloc *hi_pool, *lo_pool;
989 uint16_t hi_start, lo_start;
990 enum tf_tcam_shared_wc_pool_id hi_id, lo_id;
992 struct tf_rm_alloc_info info;
994 struct tf_tcam_shared_wc_pools *tcam_shared_wc;
995 void *tcam_shared_db_ptr = NULL;
997 TF_CHECK_PARMS2(tfp, parms);
999 /* Retrieve the session information */
1000 rc = tf_session_get_session_internal(tfp, &tfs);
1004 /* If we aren't the shared session or one of our
1007 if (!tf_session_is_shared_session(tfs) ||
1008 (parms->tcam_tbl_type != TF_TCAM_TBL_TYPE_WC_TCAM_HIGH &&
1009 parms->tcam_tbl_type != TF_TCAM_TBL_TYPE_WC_TCAM_LOW)) {
1011 "%s: Session must be shared with HI/LO type\n",
1012 tf_dir_2_str(parms->dir));
1016 if (!tf_tcam_db_valid(tfp, parms->dir)) {
1018 "%s: tcam shared pool doesn't exist\n",
1019 tf_dir_2_str(parms->dir));
1023 /* Retrieve the device information */
1024 rc = tf_session_get_device(tfs, &dev);
1026 /* TODO print amazing error */
1029 rc = tf_tcam_shared_get_slices(tfp, dev, &num_slices);
1033 rc = tf_tcam_shared_get_rm_info(tfp,
1039 "%s: TCAM rm info get failed\n",
1040 tf_dir_2_str(parms->dir));
1044 rc = tf_session_get_tcam_shared_db(tfp, (void *)&tcam_shared_db_ptr);
1047 "Failed to get tcam_shared_db from session, rc:%s\n",
1051 tcam_shared_wc = (struct tf_tcam_shared_wc_pools *)tcam_shared_db_ptr;
1053 hi_id = TF_TCAM_SHARED_WC_POOL_HI;
1054 hi_pool = tcam_shared_wc->db[parms->dir][hi_id].pool;
1055 hi_start = tcam_shared_wc->db[parms->dir][hi_id].info.start;
1057 lo_id = TF_TCAM_SHARED_WC_POOL_LO;
1058 lo_pool = tcam_shared_wc->db[parms->dir][lo_id].pool;
1059 lo_start = tcam_shared_wc->db[parms->dir][lo_id].info.start;
1061 if (hi_pool == NULL || lo_pool == NULL)
1064 /* Get the total count of in use entries in the high pool
1066 hi_cnt = ba_inuse_count(hi_pool);
1068 /* Copy each valid entry to the same low pool logical offset
1070 for (i = 0; i < hi_cnt; i++) {
1071 /* Go through all the slices
1073 for (j = 0; j < num_slices; j++) {
1074 /* Find next free starting from where we left off
1076 log_idx = ba_find_next_inuse(hi_pool, i);
1080 "Expected a found %s entry %d\n",
1081 tf_pool_2_str(hi_id),
1085 /* The user should have never allocated from the low
1086 * pool because the move only happens when switching
1087 * from the high to the low pool
1089 if (ba_alloc_index(lo_pool, log_idx) < 0) {
1091 "Cannot allocate %s index %d\n",
1092 tf_pool_2_str(lo_id),
1098 rc = tf_tcam_shared_move_entry(tfp, dev,
1109 "Cannot allocate %s index %d\n",
1110 tf_pool_2_str(hi_id),
1114 ba_free(hi_pool, log_idx);
1116 "%s: TCAM shared move pool(%s) phyid(%d)\n",
1117 tf_dir_2_str(parms->dir),
1118 tf_pool_2_str(hi_id),
1119 hi_start + log_idx);
1121 "to pool(%s) phyid(%d)\n",
1122 tf_pool_2_str(lo_id),
1123 lo_start + log_idx);
1131 int tf_tcam_shared_move_p4(struct tf *tfp,
1132 struct tf_move_tcam_shared_entries_parms *parms)
1135 rc = tf_tcam_shared_move(tfp,
1137 TF_TCAM_SHARED_KEY_SLICE_SZ_BYTES_P4,
1138 TF_TCAM_SHARED_REMAP_SZ_BYTES_P4,
1139 false); /* no enable bit */
1144 int tf_tcam_shared_move_p58(struct tf *tfp,
1145 struct tf_move_tcam_shared_entries_parms *parms)
1148 rc = tf_tcam_shared_move(tfp,
1150 TF_TCAM_SHARED_KEY_SLICE_SZ_BYTES_P58,
1151 TF_TCAM_SHARED_REMAP_SZ_BYTES_P58,
1152 true); /* set enable bit */