c2eef26dbb8b1afc4a38ea2621ba791aec1cfdcc
[dpdk.git] / drivers / net / bnxt / tf_core / tf_tcam.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.h"
10 #include "tf_common.h"
11 #include "tf_util.h"
12 #include "tf_rm.h"
13 #include "tf_device.h"
14 #include "tfp.h"
15 #include "tf_session.h"
16 #include "tf_msg.h"
17 #include "tf_shadow_tcam.h"
18
19 struct tf;
20
21 /**
22  * TCAM Shadow DBs
23  */
24 static void *shadow_tcam_db[TF_DIR_MAX];
25
26 /**
27  * Init flag, set on bind and cleared on unbind
28  */
29 static uint8_t init;
30
31 /**
32  * Shadow init flag, set on bind and cleared on unbind
33  */
34 static uint8_t shadow_init;
35
36 int
37 tf_tcam_bind(struct tf *tfp,
38              struct tf_tcam_cfg_parms *parms)
39 {
40         int rc;
41         int i, d;
42         struct tf_rm_alloc_info info;
43         struct tf_rm_free_db_parms fparms;
44         struct tf_rm_create_db_parms db_cfg;
45         struct tf_tcam_resources *tcam_cnt;
46         struct tf_rm_get_alloc_info_parms ainfo;
47         struct tf_shadow_tcam_free_db_parms fshadow;
48         struct tf_shadow_tcam_cfg_parms shadow_cfg;
49         struct tf_shadow_tcam_create_db_parms shadow_cdb;
50         uint16_t num_slices = 1;
51         struct tf_session *tfs;
52         struct tf_dev_info *dev;
53         struct tcam_rm_db *tcam_db;
54         struct tfp_calloc_parms cparms;
55
56         TF_CHECK_PARMS2(tfp, parms);
57
58         if (init) {
59                 TFP_DRV_LOG(ERR,
60                             "TCAM DB already initialized\n");
61                 return -EINVAL;
62         }
63
64         /* Retrieve the session information */
65         rc = tf_session_get_session_internal(tfp, &tfs);
66         if (rc)
67                 return rc;
68
69         /* Retrieve the device information */
70         rc = tf_session_get_device(tfs, &dev);
71         if (rc)
72                 return rc;
73
74         if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
75                 rc = -EOPNOTSUPP;
76                 TFP_DRV_LOG(ERR,
77                             "Operation not supported, rc:%s\n",
78                             strerror(-rc));
79                 return rc;
80         }
81
82         rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
83                                                   TF_TCAM_TBL_TYPE_WC_TCAM,
84                                                   0,
85                                                   &num_slices);
86         if (rc)
87                 return rc;
88
89         tcam_cnt = parms->resources->tcam_cnt;
90         if ((tcam_cnt[TF_DIR_RX].cnt[TF_TCAM_TBL_TYPE_WC_TCAM] % num_slices) ||
91             (tcam_cnt[TF_DIR_TX].cnt[TF_TCAM_TBL_TYPE_WC_TCAM] % num_slices)) {
92                 TFP_DRV_LOG(ERR,
93                             "Requested num of WC TCAM entries has to be multiple %d\n",
94                             num_slices);
95                 return -EINVAL;
96         }
97
98         memset(&db_cfg, 0, sizeof(db_cfg));
99         cparms.nitems = 1;
100         cparms.size = sizeof(struct tcam_rm_db);
101         cparms.alignment = 0;
102         if (tfp_calloc(&cparms) != 0) {
103                 TFP_DRV_LOG(ERR, "tcam_rm_db alloc error %s\n",
104                             strerror(ENOMEM));
105                 return -ENOMEM;
106         }
107
108         tcam_db = cparms.mem_va;
109         for (i = 0; i < TF_DIR_MAX; i++)
110                 tcam_db->tcam_db[i] = NULL;
111         tf_session_set_db(tfp, TF_MODULE_TYPE_TCAM, tcam_db);
112
113         db_cfg.module = TF_MODULE_TYPE_TCAM;
114         db_cfg.num_elements = parms->num_elements;
115         db_cfg.cfg = parms->cfg;
116
117         for (d = 0; d < TF_DIR_MAX; d++) {
118                 db_cfg.dir = d;
119                 db_cfg.alloc_cnt = parms->resources->tcam_cnt[d].cnt;
120                 db_cfg.rm_db = (void *)&tcam_db->tcam_db[d];
121                 rc = tf_rm_create_db(tfp, &db_cfg);
122                 if (rc) {
123                         TFP_DRV_LOG(ERR,
124                                     "%s: TCAM DB creation failed\n",
125                                     tf_dir_2_str(d));
126                         return rc;
127                 }
128         }
129
130         /* check if reserved resource for WC is multiple of num_slices */
131         for (d = 0; d < TF_DIR_MAX; d++) {
132                 memset(&info, 0, sizeof(info));
133                 ainfo.rm_db = tcam_db->tcam_db[d];
134                 ainfo.subtype = TF_TCAM_TBL_TYPE_WC_TCAM;
135                 ainfo.info = &info;
136                 rc = tf_rm_get_info(&ainfo);
137                 if (rc)
138                         goto error;
139
140                 if (info.entry.start % num_slices != 0 ||
141                     info.entry.stride % num_slices != 0) {
142                         TFP_DRV_LOG(ERR,
143                                     "%s: TCAM reserved resource is not multiple of %d\n",
144                                     tf_dir_2_str(d),
145                                     num_slices);
146                         return -EINVAL;
147                 }
148         }
149
150         /* Initialize the TCAM manager. */
151         if (parms->shadow_copy) {
152                 for (d = 0; d < TF_DIR_MAX; d++) {
153                         memset(&shadow_cfg, 0, sizeof(shadow_cfg));
154                         memset(&shadow_cdb, 0, sizeof(shadow_cdb));
155                         /* Get the base addresses of the tcams for tcam mgr */
156                         for (i = 0; i < TF_TCAM_TBL_TYPE_MAX; i++) {
157                                 memset(&info, 0, sizeof(info));
158
159                                 if (!parms->resources->tcam_cnt[d].cnt[i])
160                                         continue;
161                                 ainfo.rm_db = tcam_db->tcam_db[d];
162                                 ainfo.subtype = i;
163                                 ainfo.info = &info;
164                                 rc = tf_rm_get_info(&ainfo);
165                                 if (rc)
166                                         goto error;
167
168                                 shadow_cfg.base_addr[i] = info.entry.start;
169                         }
170
171                         /* Create the shadow db */
172                         shadow_cfg.alloc_cnt =
173                                 parms->resources->tcam_cnt[d].cnt;
174                         shadow_cfg.num_entries = parms->num_elements;
175
176                         shadow_cdb.shadow_db = &shadow_tcam_db[d];
177                         shadow_cdb.cfg = &shadow_cfg;
178                         rc = tf_shadow_tcam_create_db(&shadow_cdb);
179                         if (rc) {
180                                 TFP_DRV_LOG(ERR,
181                                             "TCAM MGR DB creation failed "
182                                             "rc=%d\n", rc);
183                                 goto error;
184                         }
185                 }
186                 shadow_init = 1;
187         }
188
189         init = 1;
190
191         TFP_DRV_LOG(INFO,
192                     "TCAM - initialized\n");
193
194         return 0;
195 error:
196         for (i = 0; i < TF_DIR_MAX; i++) {
197                 memset(&fparms, 0, sizeof(fparms));
198                 fparms.dir = i;
199                 fparms.rm_db = tcam_db->tcam_db[i];
200                 /* Ignoring return here since we are in the error case */
201                 (void)tf_rm_free_db(tfp, &fparms);
202
203                 if (parms->shadow_copy) {
204                         fshadow.shadow_db = shadow_tcam_db[i];
205                         tf_shadow_tcam_free_db(&fshadow);
206                         shadow_tcam_db[i] = NULL;
207                 }
208
209                 tcam_db->tcam_db[i] = NULL;
210                 tf_session_set_db(tfp, TF_MODULE_TYPE_TCAM, NULL);
211         }
212
213         shadow_init = 0;
214         init = 0;
215
216         return rc;
217 }
218
219 int
220 tf_tcam_unbind(struct tf *tfp)
221 {
222         int rc;
223         int i;
224         struct tf_rm_free_db_parms fparms;
225         struct tcam_rm_db *tcam_db;
226         void *tcam_db_ptr = NULL;
227         struct tf_shadow_tcam_free_db_parms fshadow;
228         TF_CHECK_PARMS1(tfp);
229
230         /* Bail if nothing has been initialized */
231         if (!init) {
232                 TFP_DRV_LOG(INFO,
233                             "No TCAM DBs created\n");
234                 return 0;
235         }
236
237         rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
238         if (rc) {
239                 TFP_DRV_LOG(ERR,
240                             "Failed to get em_ext_db from session, rc:%s\n",
241                             strerror(-rc));
242                 return rc;
243         }
244         tcam_db = (struct tcam_rm_db *)tcam_db_ptr;
245
246         for (i = 0; i < TF_DIR_MAX; i++) {
247                 memset(&fparms, 0, sizeof(fparms));
248                 fparms.dir = i;
249                 fparms.rm_db = tcam_db->tcam_db[i];
250                 rc = tf_rm_free_db(tfp, &fparms);
251                 if (rc)
252                         return rc;
253
254                 tcam_db->tcam_db[i] = NULL;
255
256                 if (shadow_init) {
257                         memset(&fshadow, 0, sizeof(fshadow));
258
259                         fshadow.shadow_db = shadow_tcam_db[i];
260                         tf_shadow_tcam_free_db(&fshadow);
261                         shadow_tcam_db[i] = NULL;
262                 }
263         }
264
265         shadow_init = 0;
266         init = 0;
267
268         return 0;
269 }
270
271 int
272 tf_tcam_alloc(struct tf *tfp,
273               struct tf_tcam_alloc_parms *parms)
274 {
275         int rc, i;
276         struct tf_session *tfs;
277         struct tf_dev_info *dev;
278         struct tf_rm_allocate_parms aparms;
279         uint16_t num_slices = 1;
280         uint32_t index;
281         struct tcam_rm_db *tcam_db;
282         void *tcam_db_ptr = NULL;
283
284         TF_CHECK_PARMS2(tfp, parms);
285
286         if (!init) {
287                 TFP_DRV_LOG(ERR,
288                             "%s: No TCAM DBs created\n",
289                             tf_dir_2_str(parms->dir));
290                 return -EINVAL;
291         }
292
293         /* Retrieve the session information */
294         rc = tf_session_get_session_internal(tfp, &tfs);
295         if (rc)
296                 return rc;
297
298         /* Retrieve the device information */
299         rc = tf_session_get_device(tfs, &dev);
300         if (rc)
301                 return rc;
302
303         if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
304                 rc = -EOPNOTSUPP;
305                 TFP_DRV_LOG(ERR,
306                             "%s: Operation not supported, rc:%s\n",
307                             tf_dir_2_str(parms->dir),
308                             strerror(-rc));
309                 return rc;
310         }
311
312         /* Need to retrieve number of slices based on the key_size */
313         rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
314                                                   parms->type,
315                                                   parms->key_size,
316                                                   &num_slices);
317         if (rc)
318                 return rc;
319
320         rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
321         if (rc) {
322                 TFP_DRV_LOG(ERR,
323                             "Failed to get em_ext_db from session, rc:%s\n",
324                             strerror(-rc));
325                 return rc;
326         }
327         tcam_db = (struct tcam_rm_db *)tcam_db_ptr;
328
329         /*
330          * For WC TCAM, number of slices could be 4, 2, 1 based on
331          * the key_size. For other TCAM, it is always 1
332          */
333         for (i = 0; i < num_slices; i++) {
334                 memset(&aparms, 0, sizeof(aparms));
335                 aparms.rm_db = tcam_db->tcam_db[parms->dir];
336                 aparms.subtype = parms->type;
337                 aparms.priority = parms->priority;
338                 aparms.index = &index;
339                 rc = tf_rm_allocate(&aparms);
340                 if (rc) {
341                         TFP_DRV_LOG(ERR,
342                                     "%s: Failed tcam, type:%d\n",
343                                     tf_dir_2_str(parms->dir),
344                                     parms->type);
345                         return rc;
346                 }
347
348                 /* return the start index of each row */
349                 if (i == 0)
350                         parms->idx = index;
351         }
352
353         return 0;
354 }
355
356 int
357 tf_tcam_free(struct tf *tfp,
358              struct tf_tcam_free_parms *parms)
359 {
360         int rc;
361         struct tf_session *tfs;
362         struct tf_dev_info *dev;
363         struct tf_rm_is_allocated_parms aparms;
364         struct tf_rm_free_parms fparms;
365         struct tf_rm_get_hcapi_parms hparms;
366         uint16_t num_slices = 1;
367         int allocated = 0;
368         struct tf_shadow_tcam_remove_parms shparms;
369         int i;
370         struct tcam_rm_db *tcam_db;
371         void *tcam_db_ptr = NULL;
372
373         TF_CHECK_PARMS2(tfp, parms);
374
375         if (!init) {
376                 TFP_DRV_LOG(ERR,
377                             "%s: No TCAM DBs created\n",
378                             tf_dir_2_str(parms->dir));
379                 return -EINVAL;
380         }
381
382         /* Retrieve the session information */
383         rc = tf_session_get_session_internal(tfp, &tfs);
384         if (rc)
385                 return rc;
386
387         /* Retrieve the device information */
388         rc = tf_session_get_device(tfs, &dev);
389         if (rc)
390                 return rc;
391
392         if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
393                 rc = -EOPNOTSUPP;
394                 TFP_DRV_LOG(ERR,
395                             "%s: Operation not supported, rc:%s\n",
396                             tf_dir_2_str(parms->dir),
397                             strerror(-rc));
398                 return rc;
399         }
400
401         /* Need to retrieve row size etc */
402         rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
403                                                   parms->type,
404                                                   0,
405                                                   &num_slices);
406         if (rc)
407                 return rc;
408
409         if (parms->idx % num_slices) {
410                 TFP_DRV_LOG(ERR,
411                             "%s: TCAM reserved resource is not multiple of %d\n",
412                             tf_dir_2_str(parms->dir),
413                             num_slices);
414                 return -EINVAL;
415         }
416
417         rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
418         if (rc) {
419                 TFP_DRV_LOG(ERR,
420                             "Failed to get em_ext_db from session, rc:%s\n",
421                             strerror(-rc));
422                 return rc;
423         }
424         tcam_db = (struct tcam_rm_db *)tcam_db_ptr;
425
426         /* Check if element is in use */
427         memset(&aparms, 0, sizeof(aparms));
428         aparms.rm_db = tcam_db->tcam_db[parms->dir];
429         aparms.subtype = parms->type;
430         aparms.index = parms->idx;
431         aparms.allocated = &allocated;
432         rc = tf_rm_is_allocated(&aparms);
433         if (rc)
434                 return rc;
435
436         if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
437                 TFP_DRV_LOG(ERR,
438                             "%s: Entry already free, type:%d, index:%d\n",
439                             tf_dir_2_str(parms->dir),
440                             parms->type,
441                             parms->idx);
442                 return -EINVAL;
443         }
444
445         /*
446          * The Shadow mgmt, if enabled, determines if the entry needs
447          * to be deleted.
448          */
449         if (shadow_init) {
450                 shparms.shadow_db = shadow_tcam_db[parms->dir];
451                 shparms.fparms = parms;
452                 rc = tf_shadow_tcam_remove(&shparms);
453                 if (rc) {
454                         /*
455                          * Should not get here, log it and let the entry be
456                          * deleted.
457                          */
458                         TFP_DRV_LOG(ERR, "%s: Shadow free fail, "
459                                     "type:%d index:%d deleting the entry.\n",
460                                     tf_dir_2_str(parms->dir),
461                                     parms->type,
462                                     parms->idx);
463                 } else {
464                         /*
465                          * If the entry still has references, just return the
466                          * ref count to the caller.  No need to remove entry
467                          * from rm or hw
468                          */
469                         if (parms->ref_cnt >= 1)
470                                 return rc;
471                 }
472         }
473
474         for (i = 0; i < num_slices; i++) {
475                 /* Free requested element */
476                 memset(&fparms, 0, sizeof(fparms));
477                 fparms.rm_db = tcam_db->tcam_db[parms->dir];
478                 fparms.subtype = parms->type;
479                 fparms.index = parms->idx + i;
480                 rc = tf_rm_free(&fparms);
481                 if (rc) {
482                         TFP_DRV_LOG(ERR,
483                                     "%s: Free failed, type:%d, index:%d\n",
484                                     tf_dir_2_str(parms->dir),
485                                     parms->type,
486                                     parms->idx);
487                         return rc;
488                 }
489         }
490
491         /* Convert TF type to HCAPI RM type */
492         memset(&hparms, 0, sizeof(hparms));
493
494         hparms.rm_db = tcam_db->tcam_db[parms->dir];
495         hparms.subtype = parms->type;
496         hparms.hcapi_type = &parms->hcapi_type;
497
498         rc = tf_rm_get_hcapi_type(&hparms);
499         if (rc)
500                 return rc;
501
502         rc = tf_msg_tcam_entry_free(tfp, dev, parms);
503         if (rc) {
504                 /* Log error */
505                 TFP_DRV_LOG(ERR,
506                             "%s: %s: Entry %d free failed, rc:%s\n",
507                             tf_dir_2_str(parms->dir),
508                             tf_tcam_tbl_2_str(parms->type),
509                             parms->idx,
510                             strerror(-rc));
511                 return rc;
512         }
513
514         return 0;
515 }
516
517 int
518 tf_tcam_alloc_search(struct tf *tfp,
519                      struct tf_tcam_alloc_search_parms *parms)
520 {
521         struct tf_shadow_tcam_search_parms sparms;
522         struct tf_shadow_tcam_bind_index_parms bparms;
523         struct tf_tcam_free_parms fparms;
524         struct tf_tcam_alloc_parms aparms;
525         uint16_t num_slice_per_row = 1;
526         struct tf_session *tfs;
527         struct tf_dev_info *dev;
528         int rc;
529
530         TF_CHECK_PARMS2(tfp, parms);
531
532         if (!init) {
533                 TFP_DRV_LOG(ERR,
534                             "%s: No TCAM DBs created\n",
535                             tf_dir_2_str(parms->dir));
536                 return -EINVAL;
537         }
538
539         if (!shadow_init || !shadow_tcam_db[parms->dir]) {
540                 TFP_DRV_LOG(ERR, "%s: TCAM Shadow not initialized for %s\n",
541                             tf_dir_2_str(parms->dir),
542                             tf_tcam_tbl_2_str(parms->type));
543                 return -EINVAL;
544         }
545
546         /* Retrieve the session information */
547         rc = tf_session_get_session_internal(tfp, &tfs);
548         if (rc)
549                 return rc;
550
551         /* Retrieve the device information */
552         rc = tf_session_get_device(tfs, &dev);
553         if (rc)
554                 return rc;
555
556         if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
557                 rc = -EOPNOTSUPP;
558                 TFP_DRV_LOG(ERR,
559                             "%s: Operation not supported, rc:%s\n",
560                             tf_dir_2_str(parms->dir),
561                             strerror(-rc));
562                 return rc;
563         }
564
565         /* Need to retrieve row size etc */
566         rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
567                                                   parms->type,
568                                                   parms->key_size,
569                                                   &num_slice_per_row);
570         if (rc)
571                 return rc;
572
573         /*
574          * Prep the shadow search, reusing the parms from original search
575          * instead of copying them.  Shadow will update output in there.
576          */
577         memset(&sparms, 0, sizeof(sparms));
578         sparms.sparms = parms;
579         sparms.shadow_db = shadow_tcam_db[parms->dir];
580
581         rc = tf_shadow_tcam_search(&sparms);
582         if (rc)
583                 return rc;
584
585         /*
586          * The app didn't request us to alloc the entry, so return now.
587          * The hit should have been updated in the original search parm.
588          */
589         if (!parms->alloc || parms->search_status != MISS)
590                 return rc;
591
592         /* Caller desires an allocate on miss */
593         if (dev->ops->tf_dev_alloc_tcam == NULL) {
594                 rc = -EOPNOTSUPP;
595                 TFP_DRV_LOG(ERR,
596                             "%s: Operation not supported, rc:%s\n",
597                             tf_dir_2_str(parms->dir),
598                             strerror(-rc));
599                 return rc;
600         }
601         memset(&aparms, 0, sizeof(aparms));
602         aparms.dir = parms->dir;
603         aparms.type = parms->type;
604         aparms.key_size = parms->key_size;
605         aparms.priority = parms->priority;
606         rc = dev->ops->tf_dev_alloc_tcam(tfp, &aparms);
607         if (rc)
608                 return rc;
609
610         /* Successful allocation, attempt to add it to the shadow */
611         memset(&bparms, 0, sizeof(bparms));
612         bparms.dir = parms->dir;
613         bparms.shadow_db = shadow_tcam_db[parms->dir];
614         bparms.type = parms->type;
615         bparms.key = parms->key;
616         bparms.mask = parms->mask;
617         bparms.key_size = parms->key_size;
618         bparms.idx = aparms.idx;
619         bparms.hb_handle = sparms.hb_handle;
620         rc = tf_shadow_tcam_bind_index(&bparms);
621         if (rc) {
622                 /* Error binding entry, need to free the allocated idx */
623                 if (dev->ops->tf_dev_free_tcam == NULL) {
624                         rc = -EOPNOTSUPP;
625                         TFP_DRV_LOG(ERR,
626                                     "%s: Operation not supported, rc:%s\n",
627                                     tf_dir_2_str(parms->dir),
628                                     strerror(-rc));
629                         return rc;
630                 }
631
632                 fparms.dir = parms->dir;
633                 fparms.type = parms->type;
634                 fparms.idx = aparms.idx;
635                 rc = dev->ops->tf_dev_free_tcam(tfp, &fparms);
636                 if (rc)
637                         return rc;
638         }
639
640         /* Add the allocated index to output and done */
641         parms->idx = aparms.idx;
642
643         return 0;
644 }
645
646 int
647 tf_tcam_set(struct tf *tfp __rte_unused,
648             struct tf_tcam_set_parms *parms __rte_unused)
649 {
650         int rc;
651         struct tf_session *tfs;
652         struct tf_dev_info *dev;
653         struct tf_rm_is_allocated_parms aparms;
654         struct tf_rm_get_hcapi_parms hparms;
655         struct tf_shadow_tcam_insert_parms iparms;
656         uint16_t num_slice_per_row = 1;
657         int allocated = 0;
658         struct tcam_rm_db *tcam_db;
659         void *tcam_db_ptr = NULL;
660
661         TF_CHECK_PARMS2(tfp, parms);
662
663         if (!init) {
664                 TFP_DRV_LOG(ERR,
665                             "%s: No TCAM DBs created\n",
666                             tf_dir_2_str(parms->dir));
667                 return -EINVAL;
668         }
669
670         /* Retrieve the session information */
671         rc = tf_session_get_session_internal(tfp, &tfs);
672         if (rc)
673                 return rc;
674
675         /* Retrieve the device information */
676         rc = tf_session_get_device(tfs, &dev);
677         if (rc)
678                 return rc;
679
680         if (dev->ops->tf_dev_get_tcam_slice_info == NULL) {
681                 rc = -EOPNOTSUPP;
682                 TFP_DRV_LOG(ERR,
683                             "%s: Operation not supported, rc:%s\n",
684                             tf_dir_2_str(parms->dir),
685                             strerror(-rc));
686                 return rc;
687         }
688
689         /* Need to retrieve row size etc */
690         rc = dev->ops->tf_dev_get_tcam_slice_info(tfp,
691                                                   parms->type,
692                                                   parms->key_size,
693                                                   &num_slice_per_row);
694         if (rc)
695                 return rc;
696
697         rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
698         if (rc) {
699                 TFP_DRV_LOG(ERR,
700                             "Failed to get em_ext_db from session, rc:%s\n",
701                             strerror(-rc));
702                 return rc;
703         }
704         tcam_db = (struct tcam_rm_db *)tcam_db_ptr;
705
706         /* Check if element is in use */
707         memset(&aparms, 0, sizeof(aparms));
708
709         aparms.rm_db = tcam_db->tcam_db[parms->dir];
710         aparms.subtype = parms->type;
711         aparms.index = parms->idx;
712         aparms.allocated = &allocated;
713         rc = tf_rm_is_allocated(&aparms);
714         if (rc)
715                 return rc;
716
717         if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
718                 TFP_DRV_LOG(ERR,
719                             "%s: Entry is not allocated, type:%d, index:%d\n",
720                             tf_dir_2_str(parms->dir),
721                             parms->type,
722                             parms->idx);
723                 return -EINVAL;
724         }
725
726         /* Convert TF type to HCAPI RM type */
727         memset(&hparms, 0, sizeof(hparms));
728
729         hparms.rm_db = tcam_db->tcam_db[parms->dir];
730         hparms.subtype = parms->type;
731         hparms.hcapi_type = &parms->hcapi_type;
732
733         rc = tf_rm_get_hcapi_type(&hparms);
734         if (rc)
735                 return rc;
736
737         rc = tf_msg_tcam_entry_set(tfp, dev, parms);
738         if (rc) {
739                 /* Log error */
740                 TFP_DRV_LOG(ERR,
741                             "%s: %s: Entry %d set failed, rc:%s",
742                             tf_dir_2_str(parms->dir),
743                             tf_tcam_tbl_2_str(parms->type),
744                             parms->idx,
745                             strerror(-rc));
746                 return rc;
747         }
748
749         /* Successfully added to hw, now for shadow if enabled. */
750         if (!shadow_init || !shadow_tcam_db[parms->dir])
751                 return 0;
752
753         iparms.shadow_db = shadow_tcam_db[parms->dir];
754         iparms.sparms = parms;
755         rc = tf_shadow_tcam_insert(&iparms);
756         if (rc) {
757                 TFP_DRV_LOG(ERR,
758                             "%s: %s: Entry %d set failed, rc:%s",
759                             tf_dir_2_str(parms->dir),
760                             tf_tcam_tbl_2_str(parms->type),
761                             parms->idx,
762                             strerror(-rc));
763                 return rc;
764         }
765
766         return 0;
767 }
768
769 int
770 tf_tcam_get(struct tf *tfp __rte_unused,
771             struct tf_tcam_get_parms *parms)
772 {
773         int rc;
774         struct tf_session *tfs;
775         struct tf_dev_info *dev;
776         struct tf_rm_is_allocated_parms aparms;
777         struct tf_rm_get_hcapi_parms hparms;
778         int allocated = 0;
779         struct tcam_rm_db *tcam_db;
780         void *tcam_db_ptr = NULL;
781
782         TF_CHECK_PARMS2(tfp, parms);
783
784         if (!init) {
785                 TFP_DRV_LOG(ERR,
786                             "%s: No TCAM DBs created\n",
787                             tf_dir_2_str(parms->dir));
788                 return -EINVAL;
789         }
790
791         /* Retrieve the session information */
792         rc = tf_session_get_session_internal(tfp, &tfs);
793         if (rc)
794                 return rc;
795
796         /* Retrieve the device information */
797         rc = tf_session_get_device(tfs, &dev);
798         if (rc)
799                 return rc;
800
801         rc = tf_session_get_db(tfp, TF_MODULE_TYPE_TCAM, &tcam_db_ptr);
802         if (rc) {
803                 TFP_DRV_LOG(ERR,
804                             "Failed to get em_ext_db from session, rc:%s\n",
805                             strerror(-rc));
806                 return rc;
807         }
808         tcam_db = (struct tcam_rm_db *)tcam_db_ptr;
809
810         /* Check if element is in use */
811         memset(&aparms, 0, sizeof(aparms));
812
813         aparms.rm_db = tcam_db->tcam_db[parms->dir];
814         aparms.subtype = parms->type;
815         aparms.index = parms->idx;
816         aparms.allocated = &allocated;
817         rc = tf_rm_is_allocated(&aparms);
818         if (rc)
819                 return rc;
820
821         if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
822                 TFP_DRV_LOG(ERR,
823                             "%s: Entry is not allocated, type:%d, index:%d\n",
824                             tf_dir_2_str(parms->dir),
825                             parms->type,
826                             parms->idx);
827                 return -EINVAL;
828         }
829
830         /* Convert TF type to HCAPI RM type */
831         memset(&hparms, 0, sizeof(hparms));
832
833         hparms.rm_db = tcam_db->tcam_db[parms->dir];
834         hparms.subtype = parms->type;
835         hparms.hcapi_type = &parms->hcapi_type;
836
837         rc = tf_rm_get_hcapi_type(&hparms);
838         if (rc)
839                 return rc;
840
841         rc = tf_msg_tcam_entry_get(tfp, dev, parms);
842         if (rc) {
843                 /* Log error */
844                 TFP_DRV_LOG(ERR,
845                             "%s: %s: Entry %d set failed, rc:%s",
846                             tf_dir_2_str(parms->dir),
847                             tf_tcam_tbl_2_str(parms->type),
848                             parms->idx,
849                             strerror(-rc));
850                 return rc;
851         }
852
853         return 0;
854 }