net/bnxt: support shared TCAM region
[dpdk.git] / drivers / net / bnxt / tf_core / tf_tcam_shared.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2021 Broadcom
3  * All rights reserved.
4  */
5
6 #include <string.h>
7 #include <rte_common.h>
8
9 #include "tf_tcam_shared.h"
10 #include "tf_tcam.h"
11 #include "tf_common.h"
12 #include "tf_util.h"
13 #include "tf_rm.h"
14 #include "tf_device.h"
15 #include "tfp.h"
16 #include "tf_session.h"
17 #include "tf_msg.h"
18 #include "bitalloc.h"
19 #include "tf_core.h"
20
21 struct tf;
22
23 /** Shared WC TCAM pool identifiers
24  */
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
29 };
30
31 /** Get string representation of a WC TCAM shared pool id
32  */
33 static const char *
34 tf_pool_2_str(enum tf_tcam_shared_wc_pool_id id)
35 {
36         switch (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";
41         default:
42                 return "Invalid TCAM_SHARED_WC_POOL";
43         }
44 }
45
46 /** The WC TCAM shared pool datastructure
47  */
48 struct tf_tcam_shared_wc_pool {
49         /** Start and stride data */
50         struct tf_resource_info info;
51         /** bitalloc pool */
52         struct bitalloc *pool;
53 };
54
55 /** The WC TCAM shared pool declarations
56  * TODO: add tcam_shared_wc_db
57  */
58 struct tf_tcam_shared_wc_pool tcam_shared_wc[TF_DIR_MAX][TF_TCAM_SHARED_WC_POOL_MAX];
59
60 /** Create a WC TCAM shared pool
61  */
62 static int
63 tf_tcam_shared_create_wc_pool(int dir,
64                               enum tf_tcam_shared_wc_pool_id id,
65                               int start,
66                               int stride)
67 {
68         int rc = 0;
69         bool free = true;
70         struct tfp_calloc_parms cparms;
71         uint32_t pool_size;
72
73         /* Create pool */
74         pool_size = (BITALLOC_SIZEOF(stride) / sizeof(struct bitalloc));
75         cparms.nitems = pool_size;
76         cparms.alignment = 0;
77         cparms.size = sizeof(struct bitalloc);
78         rc = tfp_calloc(&cparms);
79         if (rc) {
80                 TFP_DRV_LOG(ERR,
81                             "%s: pool memory alloc failed %s:%s\n",
82                             tf_dir_2_str(dir), tf_pool_2_str(id),
83                             strerror(-rc));
84                 return rc;
85         }
86         tcam_shared_wc[dir][id].pool = (struct bitalloc *)cparms.mem_va;
87
88         rc = ba_init(tcam_shared_wc[dir][id].pool,
89                      stride,
90                      free);
91
92         if (rc) {
93                 TFP_DRV_LOG(ERR,
94                             "%s: pool bitalloc failed %s\n",
95                             tf_dir_2_str(dir), tf_pool_2_str(id));
96                 return rc;
97         }
98
99         tcam_shared_wc[dir][id].info.start = start;
100         tcam_shared_wc[dir][id].info.stride = stride;
101         return rc;
102 }
103 /** Free a WC TCAM shared pool
104  */
105 static void
106 tf_tcam_shared_free_wc_pool(int dir,
107                             enum tf_tcam_shared_wc_pool_id id)
108 {
109         tcam_shared_wc[dir][id].info.start = 0;
110         tcam_shared_wc[dir][id].info.stride = 0;
111
112         if (tcam_shared_wc[dir][id].pool)
113                 tfp_free((void *)tcam_shared_wc[dir][id].pool);
114 }
115
116 /** Get the number of WC TCAM slices allocated during 1 allocation/free
117  */
118 static int
119 tf_tcam_shared_get_slices(struct tf *tfp,
120                           struct tf_dev_info *dev,
121                           uint16_t *num_slices)
122 {
123         int rc;
124
125         if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
126                 rc = -EOPNOTSUPP;
127                 TFP_DRV_LOG(ERR,
128                             "Operation not supported, rc:%s\n", strerror(-rc));
129                 return rc;
130         }
131         rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
132                                                   TF_TCAM_TBL_TYPE_WC_TCAM,
133                                                   0,
134                                                   num_slices);
135         return rc;
136 }
137
138 static bool
139 tf_tcam_shared_db_valid(struct tf *tfp,
140                         enum tf_dir dir)
141 {
142         struct tcam_rm_db *tcam_db;
143         void *tcam_db_ptr = NULL;
144         int rc;
145
146         TF_CHECK_PARMS1(tfp);
147
148         rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
149         if (rc)
150                 return false;
151
152         tcam_db = (struct tcam_rm_db *)tcam_db_ptr;
153
154         if (tcam_db->tcam_db[dir])
155                 return true;
156
157         return false;
158 }
159
160 static int
161 tf_tcam_shared_get_rm_info(struct tf *tfp,
162                            enum tf_dir dir,
163                            uint16_t *hcapi_type,
164                            struct tf_rm_alloc_info *info)
165 {
166         int rc;
167         struct tcam_rm_db *tcam_db;
168         void *tcam_db_ptr = NULL;
169         struct tf_rm_get_alloc_info_parms ainfo;
170         struct tf_rm_get_hcapi_parms hparms;
171
172         TF_CHECK_PARMS3(tfp, hcapi_type, info);
173
174         rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
175         if (rc) {
176                 TFP_DRV_LOG(INFO,
177                             "Tcam_db is not initialized, rc:%s\n",
178                             strerror(-rc));
179                 return 0;
180         }
181         tcam_db = (struct tcam_rm_db *)tcam_db_ptr;
182
183         /* Convert TF type to HCAPI RM type */
184         memset(&hparms, 0, sizeof(hparms));
185         hparms.rm_db = tcam_db->tcam_db[dir];
186         hparms.subtype = TF_TCAM_TBL_TYPE_WC_TCAM;
187         hparms.hcapi_type = hcapi_type;
188
189         rc = tf_rm_get_hcapi_type(&hparms);
190         if (rc) {
191                 TFP_DRV_LOG(ERR,
192                             "%s: Get RM hcapi type failed %s\n",
193                             tf_dir_2_str(dir),
194                             strerror(-rc));
195                 return rc;
196         }
197
198         memset(info, 0, sizeof(struct tf_rm_alloc_info));
199         ainfo.rm_db = tcam_db->tcam_db[dir];
200         ainfo.subtype = TF_TCAM_TBL_TYPE_WC_TCAM;
201         ainfo.info = info;
202
203         rc = tf_rm_get_info(&ainfo);
204         if (rc) {
205                 TFP_DRV_LOG(ERR,
206                             "%s: TCAM rm info get failed %s\n",
207                             tf_dir_2_str(dir),
208                             strerror(-rc));
209                 return rc;
210         }
211         return rc;
212 }
213
214 /**
215  * tf_tcam_shared_bind
216  */
217 int
218 tf_tcam_shared_bind(struct tf *tfp,
219                     struct tf_tcam_cfg_parms *parms)
220 {
221         int rc, dir;
222         struct tf_session *tfs;
223         struct tf_dev_info *dev;
224         struct tf_rm_alloc_info info;
225         uint16_t start, stride;
226         uint16_t num_slices;
227         uint16_t hcapi_type;
228
229         TF_CHECK_PARMS2(tfp, parms);
230
231         /* Perform normal bind
232          */
233         rc = tf_tcam_bind(tfp, parms);
234         if (rc)
235                 return rc;
236
237         /* After the normal TCAM bind, if this is a shared session
238          * create all required databases for the WC_HI and WC_LO pools
239          */
240         rc = tf_session_get_session_internal(tfp, &tfs);
241         if (rc) {
242                 TFP_DRV_LOG(ERR,
243                             "Session access failure: %s\n", strerror(-rc));
244                 return rc;
245         }
246         if (tf_session_is_shared_session(tfs)) {
247                 /* Retrieve the device information */
248                 rc = tf_session_get_device(tfs, &dev);
249                 if (rc)
250                         return rc;
251
252                 rc = tf_tcam_shared_get_slices(tfp,
253                                                dev,
254                                                &num_slices);
255                 if (rc)
256                         return rc;
257
258                 /* If there are WC TCAM entries, create 2 pools each with 1/2
259                  * the total number of entries
260                  */
261                 for (dir = 0; dir < TF_DIR_MAX; dir++) {
262                         if (!tf_tcam_shared_db_valid(tfp, dir))
263                                 continue;
264
265                         rc = tf_tcam_shared_get_rm_info(tfp,
266                                                         dir,
267                                                         &hcapi_type,
268                                                         &info);
269                         if (rc) {
270                                 TFP_DRV_LOG(ERR,
271                                             "%s: TCAM rm info get failed\n",
272                                             tf_dir_2_str(dir));
273                                 goto done;
274                         }
275
276                         start = info.entry.start;
277                         stride = info.entry.stride / 2;
278
279                         tf_tcam_shared_create_wc_pool(dir,
280                                                 TF_TCAM_SHARED_WC_POOL_HI,
281                                                 start,
282                                                 stride);
283
284                         start += stride;
285                         tf_tcam_shared_create_wc_pool(dir,
286                                                 TF_TCAM_SHARED_WC_POOL_LO,
287                                                 start,
288                                                 stride);
289                 }
290         }
291 done:
292         return rc;
293 }
294 /**
295  * tf_tcam_shared_unbind
296  */
297 int
298 tf_tcam_shared_unbind(struct tf *tfp)
299 {
300         int rc, dir;
301         struct tf_session *tfs;
302
303         TF_CHECK_PARMS1(tfp);
304
305         /* Perform normal unbind, this will write all the
306          * allocated TCAM entries in the shared session.
307          */
308         rc = tf_tcam_unbind(tfp);
309         if (rc)
310                 return rc;
311
312         /* Retrieve the session information */
313         rc = tf_session_get_session_internal(tfp, &tfs);
314         if (rc)
315                 return rc;
316
317         /* If we are the shared session
318          */
319         if (tf_session_is_shared_session(tfs)) {
320                 /* If there are WC TCAM entries allocated, free them
321                  */
322                 for (dir = 0; dir < TF_DIR_MAX; dir++) {
323                         tf_tcam_shared_free_wc_pool(dir,
324                                                     TF_TCAM_SHARED_WC_POOL_HI);
325                         tf_tcam_shared_free_wc_pool(dir,
326                                                     TF_TCAM_SHARED_WC_POOL_LO);
327                 }
328         }
329         return 0;
330 }
331 /**
332  * tf_tcam_shared_alloc
333  */
334 int
335 tf_tcam_shared_alloc(struct tf *tfp,
336                      struct tf_tcam_alloc_parms *parms)
337 {
338         int rc, i;
339         struct tf_session *tfs;
340         struct tf_dev_info *dev;
341         int log_idx;
342         struct bitalloc *pool;
343         enum tf_tcam_shared_wc_pool_id id;
344         uint16_t num_slices;
345
346         TF_CHECK_PARMS2(tfp, parms);
347
348         /* Retrieve the session information */
349         rc = tf_session_get_session_internal(tfp, &tfs);
350         if (rc)
351                 return rc;
352
353         /* If we aren't the shared session or the type is
354          * not one of the special WC TCAM types, call the normal
355          * allocation.
356          */
357         if (!tf_session_is_shared_session(tfs) ||
358             (parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_HIGH &&
359              parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_LOW)) {
360                 /* Perform normal alloc
361                  */
362                 rc = tf_tcam_alloc(tfp, parms);
363                 return rc;
364         }
365
366         if (!tf_tcam_shared_db_valid(tfp, parms->dir)) {
367                 TFP_DRV_LOG(ERR,
368                             "%s: tcam shared pool doesn't exist\n",
369                             tf_dir_2_str(parms->dir));
370                 return -ENOMEM;
371         }
372
373         if (parms->type == TF_TCAM_TBL_TYPE_WC_TCAM_HIGH)
374                 id = TF_TCAM_SHARED_WC_POOL_HI;
375         else
376                 id = TF_TCAM_SHARED_WC_POOL_LO;
377
378         /* Retrieve the device information */
379         rc = tf_session_get_device(tfs, &dev);
380         if (rc)
381                 return rc;
382
383         rc = tf_tcam_shared_get_slices(tfp, dev, &num_slices);
384         if (rc)
385                 return rc;
386
387         pool = tcam_shared_wc[parms->dir][id].pool;
388
389         for (i = 0; i < num_slices; i++) {
390                 /*
391                  * priority  0: allocate from top of the tcam i.e. high
392                  * priority !0: allocate index from bottom i.e lowest
393                  */
394                 if (parms->priority)
395                         log_idx = ba_alloc_reverse(pool);
396                 else
397                         log_idx = ba_alloc(pool);
398                 if (log_idx == BA_FAIL) {
399                         TFP_DRV_LOG(ERR,
400                                     "%s: Allocation failed, rc:%s\n",
401                                     tf_dir_2_str(parms->dir),
402                                     strerror(ENOMEM));
403                         return -ENOMEM;
404                 }
405                 /* return the index without the start of each row */
406                 if (i == 0)
407                         parms->idx = log_idx;
408         }
409         return 0;
410 }
411
412 int
413 tf_tcam_shared_free(struct tf *tfp,
414                     struct tf_tcam_free_parms *parms)
415 {
416         int rc;
417         struct tf_session *tfs;
418         struct tf_dev_info *dev;
419         int allocated = 0;
420         int i;
421         uint16_t start;
422         int phy_idx;
423         struct bitalloc *pool;
424         enum tf_tcam_shared_wc_pool_id id;
425         struct tf_tcam_free_parms nparms;
426         uint16_t num_slices;
427         uint16_t hcapi_type;
428         struct tf_rm_alloc_info info;
429
430         TF_CHECK_PARMS2(tfp, parms);
431
432         /* Retrieve the session information */
433         rc = tf_session_get_session_internal(tfp, &tfs);
434         if (rc)
435                 return rc;
436
437         /* If we aren't the shared session or the type is
438          * not one of the special WC TCAM types, call the normal
439          * allocation.
440          */
441         if (!tf_session_is_shared_session(tfs) ||
442             (parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_HIGH &&
443              parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_LOW)) {
444                 /* Perform normal free
445                  */
446                 rc = tf_tcam_free(tfp, parms);
447                 return rc;
448         }
449
450         if (!tf_tcam_shared_db_valid(tfp, parms->dir)) {
451                 TFP_DRV_LOG(ERR,
452                             "%s: tcam shared pool doesn't exist\n",
453                             tf_dir_2_str(parms->dir));
454                 return -ENOMEM;
455         }
456
457         if (parms->type == TF_TCAM_TBL_TYPE_WC_TCAM_HIGH)
458                 id = TF_TCAM_SHARED_WC_POOL_HI;
459         else
460                 id = TF_TCAM_SHARED_WC_POOL_LO;
461
462         /* Retrieve the device information */
463         rc = tf_session_get_device(tfs, &dev);
464         if (rc)
465                 return rc;
466
467         rc = tf_tcam_shared_get_slices(tfp, dev, &num_slices);
468         if (rc)
469                 return rc;
470
471         rc = tf_tcam_shared_get_rm_info(tfp,
472                                         parms->dir,
473                                         &hcapi_type,
474                                         &info);
475         if (rc) {
476                 TFP_DRV_LOG(ERR,
477                             "%s: TCAM rm info get failed\n",
478                             tf_dir_2_str(parms->dir));
479                 return rc;
480         }
481
482         pool = tcam_shared_wc[parms->dir][id].pool;
483         start = tcam_shared_wc[parms->dir][id].info.start;
484
485         if (parms->idx % num_slices) {
486                 TFP_DRV_LOG(ERR,
487                             "%s: TCAM reserved resource is not multiple of %d\n",
488                             tf_dir_2_str(parms->dir), num_slices);
489                 return -EINVAL;
490         }
491
492         phy_idx = parms->idx + start;
493         allocated = ba_inuse(pool, parms->idx);
494
495         if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
496                 TFP_DRV_LOG(ERR,
497                             "%s: Entry already free, type:%d, idx:%d\n",
498                             tf_dir_2_str(parms->dir), parms->type, parms->idx);
499                 return -EINVAL;
500         }
501
502         for (i = 0; i < num_slices; i++) {
503                 rc = ba_free(pool, parms->idx + i);
504                 if (rc) {
505                         TFP_DRV_LOG(ERR,
506                                     "%s: Free failed, type:%s, idx:%d\n",
507                                     tf_dir_2_str(parms->dir),
508                                     tf_tcam_tbl_2_str(parms->type),
509                                     parms->idx);
510                         return rc;
511                 }
512         }
513
514         /* Override HI/LO type with parent WC TCAM type */
515         nparms = *parms;
516         nparms.type = TF_TCAM_TBL_TYPE_WC_TCAM;
517         nparms.hcapi_type = hcapi_type;
518         nparms.idx = phy_idx;
519
520         rc = tf_msg_tcam_entry_free(tfp, dev, &nparms);
521         if (rc) {
522                 /* Log error */
523                 TFP_DRV_LOG(ERR,
524                             "%s: %s: log%d free failed, rc:%s\n",
525                             tf_dir_2_str(nparms.dir),
526                             tf_tcam_tbl_2_str(nparms.type),
527                             phy_idx,
528                             strerror(-rc));
529                 return rc;
530         }
531         return 0;
532 }
533
534 int
535 tf_tcam_shared_set(struct tf *tfp __rte_unused,
536                    struct tf_tcam_set_parms *parms __rte_unused)
537 {
538         int rc;
539         struct tf_session *tfs;
540         struct tf_dev_info *dev;
541         int allocated = 0;
542         int phy_idx, log_idx;
543         uint16_t num_slices;
544         struct tf_tcam_set_parms nparms;
545         struct bitalloc *pool;
546         uint16_t start;
547         enum tf_tcam_shared_wc_pool_id id;
548         uint16_t hcapi_type;
549         struct tf_rm_alloc_info info;
550
551         TF_CHECK_PARMS2(tfp, parms);
552
553         /* Retrieve the session information */
554         rc = tf_session_get_session_internal(tfp, &tfs);
555         if (rc)
556                 return rc;
557
558         /* If we aren't the shared session or one of our
559          * special types
560          */
561         if (!tf_session_is_shared_session(tfs) ||
562             (parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_HIGH &&
563              parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_LOW)) {
564                 /* Perform normal set and exit
565                  */
566                 rc = tf_tcam_set(tfp, parms);
567                 return rc;
568         }
569
570         if (!tf_tcam_shared_db_valid(tfp, parms->dir)) {
571                 TFP_DRV_LOG(ERR,
572                             "%s: tcam shared pool doesn't exist\n",
573                             tf_dir_2_str(parms->dir));
574                 return -ENOMEM;
575         }
576
577         /* Retrieve the device information */
578         rc = tf_session_get_device(tfs, &dev);
579         if (rc)
580                 return rc;
581
582         if (parms->type == TF_TCAM_TBL_TYPE_WC_TCAM_HIGH)
583                 id = TF_TCAM_SHARED_WC_POOL_HI;
584         else
585                 id = TF_TCAM_SHARED_WC_POOL_LO;
586
587         pool = tcam_shared_wc[parms->dir][id].pool;
588         start = tcam_shared_wc[parms->dir][id].info.start;
589
590         log_idx = parms->idx;
591         phy_idx = parms->idx + start;
592         allocated = ba_inuse(pool, parms->idx);
593
594         if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
595                 TFP_DRV_LOG(ERR,
596                             "%s: Entry is not allocated, type:%d, logid:%d\n",
597                             tf_dir_2_str(parms->dir), parms->type, log_idx);
598                 return -EINVAL;
599         }
600         rc = tf_tcam_shared_get_slices(tfp, dev, &num_slices);
601         if (rc)
602                 return rc;
603
604         if (parms->idx % num_slices) {
605                 TFP_DRV_LOG(ERR,
606                             "%s: TCAM reserved resource is not multiple of %d\n",
607                             tf_dir_2_str(parms->dir), num_slices);
608                 return -EINVAL;
609         }
610         rc = tf_tcam_shared_get_rm_info(tfp,
611                                         parms->dir,
612                                         &hcapi_type,
613                                         &info);
614         if (rc)
615                 return rc;
616
617         /* Override HI/LO type with parent WC TCAM type */
618         nparms.hcapi_type = hcapi_type;
619         nparms.dir = parms->dir;
620         nparms.type = TF_TCAM_TBL_TYPE_WC_TCAM;
621         nparms.idx = phy_idx;
622         nparms.key = parms->key;
623         nparms.mask = parms->mask;
624         nparms.key_size = parms->key_size;
625         nparms.result = parms->result;
626         nparms.result_size = parms->result_size;
627
628         rc = tf_msg_tcam_entry_set(tfp, dev, &nparms);
629         if (rc) {
630                 /* Log error */
631                 TFP_DRV_LOG(ERR,
632                             "%s: %s: phy entry %d set failed, rc:%s",
633                             tf_dir_2_str(parms->dir),
634                             tf_tcam_tbl_2_str(nparms.type),
635                             phy_idx,
636                             strerror(-rc));
637                 return rc;
638         }
639         return 0;
640 }
641
642 int
643 tf_tcam_shared_get(struct tf *tfp __rte_unused,
644                    struct tf_tcam_get_parms *parms)
645 {
646         int rc;
647         struct tf_session *tfs;
648         struct tf_dev_info *dev;
649         int allocated = 0;
650         int phy_idx, log_idx;
651         uint16_t num_slices;
652         struct tf_tcam_get_parms nparms;
653         struct bitalloc *pool;
654         uint16_t start;
655         enum tf_tcam_shared_wc_pool_id id;
656         uint16_t hcapi_type;
657         struct tf_rm_alloc_info info;
658
659         TF_CHECK_PARMS2(tfp, parms);
660
661         /* Retrieve the session information */
662         rc = tf_session_get_session_internal(tfp, &tfs);
663         if (rc)
664                 return rc;
665
666         /* If we aren't the shared session or one of our
667          * special types
668          */
669         if (!tf_session_is_shared_session(tfs) ||
670             (parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_HIGH &&
671              parms->type != TF_TCAM_TBL_TYPE_WC_TCAM_LOW)) {
672                 /* Perform normal get and exit
673                  */
674                 rc = tf_tcam_get(tfp, parms);
675                 return rc;
676         }
677
678         if (!tf_tcam_shared_db_valid(tfp, parms->dir)) {
679                 TFP_DRV_LOG(ERR,
680                             "%s: tcam shared pool doesn't exist\n",
681                             tf_dir_2_str(parms->dir));
682                 return -ENOMEM;
683         }
684
685         /* Retrieve the device information */
686         rc = tf_session_get_device(tfs, &dev);
687         if (rc)
688                 return rc;
689         if (parms->type == TF_TCAM_TBL_TYPE_WC_TCAM_HIGH)
690                 id = TF_TCAM_SHARED_WC_POOL_HI;
691         else
692                 id = TF_TCAM_SHARED_WC_POOL_LO;
693
694         pool = tcam_shared_wc[parms->dir][id].pool;
695         start = tcam_shared_wc[parms->dir][id].info.start;
696
697         rc = tf_tcam_shared_get_slices(tfp, dev, &num_slices);
698         if (rc)
699                 return rc;
700
701         if (parms->idx % num_slices) {
702                 TFP_DRV_LOG(ERR,
703                             "%s: TCAM reserved resource is not multiple of %d\n",
704                             tf_dir_2_str(parms->dir), num_slices);
705                 return -EINVAL;
706         }
707         log_idx = parms->idx;
708         phy_idx = parms->idx + start;
709         allocated = ba_inuse(pool, parms->idx);
710
711         if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
712                 TFP_DRV_LOG(ERR,
713                             "%s: Entry is not allocated, type:%d, logid:%d\n",
714                             tf_dir_2_str(parms->dir), parms->type, log_idx);
715                 return -EINVAL;
716         }
717
718         rc = tf_tcam_shared_get_rm_info(tfp,
719                                         parms->dir,
720                                         &hcapi_type,
721                                         &info);
722         if (rc)
723                 return rc;
724
725         /* Override HI/LO type with parent WC TCAM type */
726         nparms = *parms;
727         nparms.type = TF_TCAM_TBL_TYPE_WC_TCAM;
728         nparms.hcapi_type = hcapi_type;
729         nparms.idx = phy_idx;
730
731         rc = tf_msg_tcam_entry_get(tfp, dev, &nparms);
732         if (rc) {
733                 /* Log error */
734                 TFP_DRV_LOG(ERR,
735                             "%s: %s: Entry %d set failed, rc:%s",
736                             tf_dir_2_str(nparms.dir),
737                             tf_tcam_tbl_2_str(nparms.type),
738                             nparms.idx,
739                             strerror(-rc));
740                 return rc;
741         }
742         return 0;
743 }