net/bnxt: support multi device
[dpdk.git] / drivers / net / bnxt / tf_core / tf_core.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2020 Broadcom
3  * All rights reserved.
4  */
5
6 #include <stdio.h>
7
8 #include "tf_core.h"
9 #include "tf_util.h"
10 #include "tf_session.h"
11 #include "tf_tbl.h"
12 #include "tf_em.h"
13 #include "tf_rm.h"
14 #include "tf_msg.h"
15 #include "tfp.h"
16 #include "bitalloc.h"
17 #include "bnxt.h"
18 #include "rand.h"
19
20 static inline uint32_t SWAP_WORDS32(uint32_t val32)
21 {
22         return (((val32 & 0x0000ffff) << 16) |
23                 ((val32 & 0xffff0000) >> 16));
24 }
25
26 static void tf_seeds_init(struct tf_session *session)
27 {
28         int i;
29         uint32_t r;
30
31         /* Initialize the lfsr */
32         rand_init();
33
34         /* RX and TX use the same seed values */
35         session->lkup_lkup3_init_cfg[TF_DIR_RX] =
36                 session->lkup_lkup3_init_cfg[TF_DIR_TX] =
37                                                 SWAP_WORDS32(rand32());
38
39         for (i = 0; i < TF_LKUP_SEED_MEM_SIZE / 2; i++) {
40                 r = SWAP_WORDS32(rand32());
41                 session->lkup_em_seed_mem[TF_DIR_RX][i * 2] = r;
42                 session->lkup_em_seed_mem[TF_DIR_TX][i * 2] = r;
43                 r = SWAP_WORDS32(rand32());
44                 session->lkup_em_seed_mem[TF_DIR_RX][i * 2 + 1] = (r & 0x1);
45                 session->lkup_em_seed_mem[TF_DIR_TX][i * 2 + 1] = (r & 0x1);
46         }
47 }
48
49 /**
50  * Create EM Tbl pool of memory indexes.
51  *
52  * [in] session
53  *   Pointer to session
54  * [in] dir
55  *   direction
56  * [in] num_entries
57  *   number of entries to write
58  *
59  * Return:
60  *  0       - Success, entry allocated - no search support
61  *  -ENOMEM -EINVAL -EOPNOTSUPP
62  *          - Failure, entry not allocated, out of resources
63  */
64 static int
65 tf_create_em_pool(struct tf_session *session,
66                   enum tf_dir dir,
67                   uint32_t num_entries)
68 {
69         struct tfp_calloc_parms parms;
70         uint32_t i, j;
71         int rc = 0;
72         struct stack *pool = &session->em_pool[dir];
73
74         parms.nitems = num_entries;
75         parms.size = sizeof(uint32_t);
76         parms.alignment = 0;
77
78         if (tfp_calloc(&parms) != 0) {
79                 TFP_DRV_LOG(ERR, "EM pool allocation failure %s\n",
80                             strerror(-ENOMEM));
81                 return -ENOMEM;
82         }
83
84         /* Create empty stack
85          */
86         rc = stack_init(num_entries, parms.mem_va, pool);
87
88         if (rc != 0) {
89                 TFP_DRV_LOG(ERR, "EM pool stack init failure %s\n",
90                             strerror(-rc));
91                 goto cleanup;
92         }
93
94         /* Fill pool with indexes
95          */
96         j = num_entries - 1;
97
98         for (i = 0; i < num_entries; i++) {
99                 rc = stack_push(pool, j);
100                 if (rc != 0) {
101                         TFP_DRV_LOG(ERR, "EM pool stack push failure %s\n",
102                                     strerror(-rc));
103                         goto cleanup;
104                 }
105                 j--;
106         }
107
108         if (!stack_is_full(pool)) {
109                 rc = -EINVAL;
110                 TFP_DRV_LOG(ERR, "EM pool stack failure %s\n",
111                             strerror(-rc));
112                 goto cleanup;
113         }
114
115         return 0;
116 cleanup:
117         tfp_free((void *)parms.mem_va);
118         return rc;
119 }
120
121 /**
122  * Create EM Tbl pool of memory indexes.
123  *
124  * [in] session
125  *   Pointer to session
126  * [in] dir
127  *   direction
128  *
129  * Return:
130  */
131 static void
132 tf_free_em_pool(struct tf_session *session,
133                 enum tf_dir dir)
134 {
135         struct stack *pool = &session->em_pool[dir];
136         uint32_t *ptr;
137
138         ptr = stack_items(pool);
139
140         tfp_free(ptr);
141 }
142
143 int
144 tf_open_session(struct tf                    *tfp,
145                 struct tf_open_session_parms *parms)
146 {
147         int rc;
148         struct tf_session *session;
149         struct tfp_calloc_parms alloc_parms;
150         unsigned int domain, bus, slot, device;
151         uint8_t fw_session_id;
152         int dir;
153
154         if (tfp == NULL || parms == NULL)
155                 return -EINVAL;
156
157         /* Filter out any non-supported device types on the Core
158          * side. It is assumed that the Firmware will be supported if
159          * firmware open session succeeds.
160          */
161         if (parms->device_type != TF_DEVICE_TYPE_WH)
162                 return -ENOTSUP;
163
164         /* Build the beginning of session_id */
165         rc = sscanf(parms->ctrl_chan_name,
166                     "%x:%x:%x.%d",
167                     &domain,
168                     &bus,
169                     &slot,
170                     &device);
171         if (rc != 4) {
172                 PMD_DRV_LOG(ERR,
173                             "Failed to scan device ctrl_chan_name\n");
174                 return -EINVAL;
175         }
176
177         /* open FW session and get a new session_id */
178         rc = tf_msg_session_open(tfp,
179                                  parms->ctrl_chan_name,
180                                  &fw_session_id);
181         if (rc) {
182                 /* Log error */
183                 if (rc == -EEXIST)
184                         PMD_DRV_LOG(ERR,
185                                     "Session is already open, rc:%d\n",
186                                     rc);
187                 else
188                         PMD_DRV_LOG(ERR,
189                                     "Open message send failed, rc:%d\n",
190                                     rc);
191
192                 parms->session_id.id = TF_FW_SESSION_ID_INVALID;
193                 return rc;
194         }
195
196         /* Allocate session */
197         alloc_parms.nitems = 1;
198         alloc_parms.size = sizeof(struct tf_session_info);
199         alloc_parms.alignment = 0;
200         rc = tfp_calloc(&alloc_parms);
201         if (rc) {
202                 /* Log error */
203                 PMD_DRV_LOG(ERR,
204                             "Failed to allocate session info, rc:%d\n",
205                             rc);
206                 goto cleanup;
207         }
208
209         tfp->session = alloc_parms.mem_va;
210
211         /* Allocate core data for the session */
212         alloc_parms.nitems = 1;
213         alloc_parms.size = sizeof(struct tf_session);
214         alloc_parms.alignment = 0;
215         rc = tfp_calloc(&alloc_parms);
216         if (rc) {
217                 /* Log error */
218                 PMD_DRV_LOG(ERR,
219                             "Failed to allocate session data, rc:%d\n",
220                             rc);
221                 goto cleanup;
222         }
223
224         tfp->session->core_data = alloc_parms.mem_va;
225
226         session = (struct tf_session *)tfp->session->core_data;
227         tfp_memcpy(session->ctrl_chan_name,
228                    parms->ctrl_chan_name,
229                    TF_SESSION_NAME_MAX);
230
231         /* Initialize Session */
232         session->device_type = parms->device_type;
233         session->dev = NULL;
234         tf_rm_init(tfp);
235
236         /* Construct the Session ID */
237         session->session_id.internal.domain = domain;
238         session->session_id.internal.bus = bus;
239         session->session_id.internal.device = device;
240         session->session_id.internal.fw_session_id = fw_session_id;
241
242         rc = tf_msg_session_qcfg(tfp);
243         if (rc) {
244                 /* Log error */
245                 PMD_DRV_LOG(ERR,
246                             "Query config message send failed, rc:%d\n",
247                             rc);
248                 goto cleanup_close;
249         }
250
251         /* Shadow DB configuration */
252         if (parms->shadow_copy) {
253                 /* Ignore shadow_copy setting */
254                 session->shadow_copy = 0;/* parms->shadow_copy; */
255 #if (TF_SHADOW == 1)
256                 rc = tf_rm_shadow_db_init(tfs);
257                 if (rc)
258                         PMD_DRV_LOG(ERR,
259                                     "Shadow DB Initialization failed\n, rc:%d",
260                                     rc);
261                 /* Add additional processing */
262 #endif /* TF_SHADOW */
263         }
264
265         /* Adjust the Session with what firmware allowed us to get */
266         rc = tf_rm_allocate_validate(tfp);
267         if (rc) {
268                 /* Log error */
269                 goto cleanup_close;
270         }
271
272         /* Setup hash seeds */
273         tf_seeds_init(session);
274
275         /* Initialize EM pool */
276         for (dir = 0; dir < TF_DIR_MAX; dir++) {
277                 rc = tf_create_em_pool(session, dir, TF_SESSION_EM_POOL_SIZE);
278                 if (rc) {
279                         TFP_DRV_LOG(ERR,
280                                     "EM Pool initialization failed\n");
281                         goto cleanup_close;
282                 }
283         }
284
285         session->ref_count++;
286
287         /* Return session ID */
288         parms->session_id = session->session_id;
289
290         PMD_DRV_LOG(INFO,
291                     "Session created, session_id:%d\n",
292                     parms->session_id.id);
293
294         PMD_DRV_LOG(INFO,
295                     "domain:%d, bus:%d, device:%d, fw_session_id:%d\n",
296                     parms->session_id.internal.domain,
297                     parms->session_id.internal.bus,
298                     parms->session_id.internal.device,
299                     parms->session_id.internal.fw_session_id);
300
301         return 0;
302
303  cleanup:
304         tfp_free(tfp->session->core_data);
305         tfp_free(tfp->session);
306         tfp->session = NULL;
307         return rc;
308
309  cleanup_close:
310         tf_close_session(tfp);
311         return -EINVAL;
312 }
313
314 int
315 tf_attach_session(struct tf *tfp __rte_unused,
316                   struct tf_attach_session_parms *parms __rte_unused)
317 {
318 #if (TF_SHARED == 1)
319         int rc;
320
321         if (tfp == NULL)
322                 return -EINVAL;
323
324         /* - Open the shared memory for the attach_chan_name
325          * - Point to the shared session for this Device instance
326          * - Check that session is valid
327          * - Attach to the firmware so it can record there is more
328          *   than one client of the session.
329          */
330
331         if (tfp->session) {
332                 if (tfp->session->session_id.id != TF_SESSION_ID_INVALID) {
333                         rc = tf_msg_session_attach(tfp,
334                                                    parms->ctrl_chan_name,
335                                                    parms->session_id);
336                 }
337         }
338 #endif /* TF_SHARED */
339         return -1;
340 }
341
342 int
343 tf_close_session(struct tf *tfp)
344 {
345         int rc;
346         int rc_close = 0;
347         struct tf_session *tfs;
348         union tf_session_id session_id;
349         int dir;
350
351         if (tfp == NULL || tfp->session == NULL)
352                 return -EINVAL;
353
354         tfs = (struct tf_session *)(tfp->session->core_data);
355
356         /* Cleanup if we're last user of the session */
357         if (tfs->ref_count == 1) {
358                 /* Cleanup any outstanding resources */
359                 rc_close = tf_rm_close(tfp);
360         }
361
362         if (tfs->session_id.id != TF_SESSION_ID_INVALID) {
363                 rc = tf_msg_session_close(tfp);
364                 if (rc) {
365                         /* Log error */
366                         PMD_DRV_LOG(ERR,
367                                     "Message send failed, rc:%d\n",
368                                     rc);
369                 }
370
371                 /* Update the ref_count */
372                 tfs->ref_count--;
373         }
374
375         session_id = tfs->session_id;
376
377         /* Final cleanup as we're last user of the session */
378         if (tfs->ref_count == 0) {
379                 /* Free EM pool */
380                 for (dir = 0; dir < TF_DIR_MAX; dir++)
381                         tf_free_em_pool(tfs, dir);
382
383                 tfp_free(tfp->session->core_data);
384                 tfp_free(tfp->session);
385                 tfp->session = NULL;
386         }
387
388         PMD_DRV_LOG(INFO,
389                     "Session closed, session_id:%d\n",
390                     session_id.id);
391
392         PMD_DRV_LOG(INFO,
393                     "domain:%d, bus:%d, device:%d, fw_session_id:%d\n",
394                     session_id.internal.domain,
395                     session_id.internal.bus,
396                     session_id.internal.device,
397                     session_id.internal.fw_session_id);
398
399         return rc_close;
400 }
401
402 /** insert EM hash entry API
403  *
404  *    returns:
405  *    0       - Success
406  *    -EINVAL - Error
407  */
408 int tf_insert_em_entry(struct tf *tfp,
409                        struct tf_insert_em_entry_parms *parms)
410 {
411         struct tf_tbl_scope_cb     *tbl_scope_cb;
412
413         if (tfp == NULL || parms == NULL)
414                 return -EINVAL;
415
416         tbl_scope_cb = tbl_scope_cb_find((struct tf_session *)
417                                          (tfp->session->core_data),
418                                          parms->tbl_scope_id);
419         if (tbl_scope_cb == NULL)
420                 return -EINVAL;
421
422         /* Process the EM entry per Table Scope type */
423         if (parms->mem == TF_MEM_EXTERNAL) {
424                 /* External EEM */
425                 return tf_insert_eem_entry((struct tf_session *)
426                                            (tfp->session->core_data),
427                                            tbl_scope_cb,
428                                            parms);
429         } else if (parms->mem == TF_MEM_INTERNAL) {
430                 /* Internal EM */
431                 return tf_insert_em_internal_entry(tfp, parms);
432         }
433
434         return -EINVAL;
435 }
436
437 /** Delete EM hash entry API
438  *
439  *    returns:
440  *    0       - Success
441  *    -EINVAL - Error
442  */
443 int tf_delete_em_entry(struct tf *tfp,
444                        struct tf_delete_em_entry_parms *parms)
445 {
446         struct tf_tbl_scope_cb     *tbl_scope_cb;
447
448         if (tfp == NULL || parms == NULL)
449                 return -EINVAL;
450
451         tbl_scope_cb = tbl_scope_cb_find((struct tf_session *)
452                                          (tfp->session->core_data),
453                                          parms->tbl_scope_id);
454         if (tbl_scope_cb == NULL)
455                 return -EINVAL;
456
457         if (parms->mem == TF_MEM_EXTERNAL)
458                 return tf_delete_eem_entry(tfp, parms);
459         else
460                 return tf_delete_em_internal_entry(tfp, parms);
461 }
462
463 /** allocate identifier resource
464  *
465  * Returns success or failure code.
466  */
467 int tf_alloc_identifier(struct tf *tfp,
468                         struct tf_alloc_identifier_parms *parms)
469 {
470         struct bitalloc *session_pool;
471         struct tf_session *tfs;
472         int id;
473         int rc;
474
475         if (parms == NULL || tfp == NULL)
476                 return -EINVAL;
477
478         if (tfp->session == NULL || tfp->session->core_data == NULL) {
479                 PMD_DRV_LOG(ERR, "%s: session error\n",
480                             tf_dir_2_str(parms->dir));
481                 return -EINVAL;
482         }
483
484         tfs = (struct tf_session *)(tfp->session->core_data);
485
486         switch (parms->ident_type) {
487         case TF_IDENT_TYPE_L2_CTXT:
488                 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
489                                 TF_L2_CTXT_REMAP_POOL_NAME,
490                                 rc);
491                 break;
492         case TF_IDENT_TYPE_PROF_FUNC:
493                 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
494                                 TF_PROF_FUNC_POOL_NAME,
495                                 rc);
496                 break;
497         case TF_IDENT_TYPE_EM_PROF:
498                 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
499                                 TF_EM_PROF_ID_POOL_NAME,
500                                 rc);
501                 break;
502         case TF_IDENT_TYPE_WC_PROF:
503                 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
504                                 TF_WC_TCAM_PROF_ID_POOL_NAME,
505                                 rc);
506                 break;
507         case TF_IDENT_TYPE_L2_FUNC:
508                 PMD_DRV_LOG(ERR, "%s: unsupported %s\n",
509                             tf_dir_2_str(parms->dir),
510                             tf_ident_2_str(parms->ident_type));
511                 rc = -EOPNOTSUPP;
512                 break;
513         default:
514                 PMD_DRV_LOG(ERR, "%s: %s\n",
515                             tf_dir_2_str(parms->dir),
516                             tf_ident_2_str(parms->ident_type));
517                 rc = -EINVAL;
518                 break;
519         }
520
521         if (rc) {
522                 PMD_DRV_LOG(ERR, "%s: identifier pool %s failure\n",
523                             tf_dir_2_str(parms->dir),
524                             tf_ident_2_str(parms->ident_type));
525                 return rc;
526         }
527
528         id = ba_alloc(session_pool);
529
530         if (id == BA_FAIL) {
531                 PMD_DRV_LOG(ERR, "%s: %s: No resource available\n",
532                             tf_dir_2_str(parms->dir),
533                             tf_ident_2_str(parms->ident_type));
534                 return -ENOMEM;
535         }
536         parms->id = id;
537         return 0;
538 }
539
540 /** free identifier resource
541  *
542  * Returns success or failure code.
543  */
544 int tf_free_identifier(struct tf *tfp,
545                        struct tf_free_identifier_parms *parms)
546 {
547         struct bitalloc *session_pool;
548         int rc;
549         int ba_rc;
550         struct tf_session *tfs;
551
552         if (parms == NULL || tfp == NULL)
553                 return -EINVAL;
554
555         if (tfp->session == NULL || tfp->session->core_data == NULL) {
556                 PMD_DRV_LOG(ERR, "%s: Session error\n",
557                             tf_dir_2_str(parms->dir));
558                 return -EINVAL;
559         }
560
561         tfs = (struct tf_session *)(tfp->session->core_data);
562
563         switch (parms->ident_type) {
564         case TF_IDENT_TYPE_L2_CTXT:
565                 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
566                                 TF_L2_CTXT_REMAP_POOL_NAME,
567                                 rc);
568                 break;
569         case TF_IDENT_TYPE_PROF_FUNC:
570                 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
571                                 TF_PROF_FUNC_POOL_NAME,
572                                 rc);
573                 break;
574         case TF_IDENT_TYPE_EM_PROF:
575                 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
576                                 TF_EM_PROF_ID_POOL_NAME,
577                                 rc);
578                 break;
579         case TF_IDENT_TYPE_WC_PROF:
580                 TF_RM_GET_POOLS(tfs, parms->dir, &session_pool,
581                                 TF_WC_TCAM_PROF_ID_POOL_NAME,
582                                 rc);
583                 break;
584         case TF_IDENT_TYPE_L2_FUNC:
585                 PMD_DRV_LOG(ERR, "%s: unsupported %s\n",
586                             tf_dir_2_str(parms->dir),
587                             tf_ident_2_str(parms->ident_type));
588                 rc = -EOPNOTSUPP;
589                 break;
590         default:
591                 PMD_DRV_LOG(ERR, "%s: invalid %s\n",
592                             tf_dir_2_str(parms->dir),
593                             tf_ident_2_str(parms->ident_type));
594                 rc = -EINVAL;
595                 break;
596         }
597         if (rc) {
598                 PMD_DRV_LOG(ERR, "%s: %s Identifier pool access failed\n",
599                             tf_dir_2_str(parms->dir),
600                             tf_ident_2_str(parms->ident_type));
601                 return rc;
602         }
603
604         ba_rc = ba_inuse(session_pool, (int)parms->id);
605
606         if (ba_rc == BA_FAIL || ba_rc == BA_ENTRY_FREE) {
607                 PMD_DRV_LOG(ERR, "%s: %s: Entry %d already free",
608                             tf_dir_2_str(parms->dir),
609                             tf_ident_2_str(parms->ident_type),
610                             parms->id);
611                 return -EINVAL;
612         }
613
614         ba_free(session_pool, (int)parms->id);
615
616         return 0;
617 }
618
619 int
620 tf_alloc_tcam_entry(struct tf *tfp,
621                     struct tf_alloc_tcam_entry_parms *parms)
622 {
623         int rc;
624         int index;
625         struct tf_session *tfs;
626         struct bitalloc *session_pool;
627
628         if (parms == NULL || tfp == NULL)
629                 return -EINVAL;
630
631         if (tfp->session == NULL || tfp->session->core_data == NULL) {
632                 PMD_DRV_LOG(ERR, "%s: session error\n",
633                             tf_dir_2_str(parms->dir));
634                 return -EINVAL;
635         }
636
637         tfs = (struct tf_session *)(tfp->session->core_data);
638
639         rc = tf_rm_lookup_tcam_type_pool(tfs,
640                                          parms->dir,
641                                          parms->tcam_tbl_type,
642                                          &session_pool);
643         /* Error logging handled by tf_rm_lookup_tcam_type_pool */
644         if (rc)
645                 return rc;
646
647         index = ba_alloc(session_pool);
648         if (index == BA_FAIL) {
649                 PMD_DRV_LOG(ERR, "%s: %s: No resource available\n",
650                             tf_dir_2_str(parms->dir),
651                             tf_tcam_tbl_2_str(parms->tcam_tbl_type));
652                 return -ENOMEM;
653         }
654
655         parms->idx = index;
656         return 0;
657 }
658
659 int
660 tf_set_tcam_entry(struct tf *tfp,
661                   struct tf_set_tcam_entry_parms *parms)
662 {
663         int rc;
664         int id;
665         struct tf_session *tfs;
666         struct bitalloc *session_pool;
667
668         if (tfp == NULL || parms == NULL) {
669                 PMD_DRV_LOG(ERR, "Invalid parameters\n");
670                 return -EINVAL;
671         }
672
673         if (tfp->session == NULL || tfp->session->core_data == NULL) {
674                 PMD_DRV_LOG(ERR,
675                             "%s, Session info invalid\n",
676                             tf_dir_2_str(parms->dir));
677                 return -EINVAL;
678         }
679
680         tfs = (struct tf_session *)(tfp->session->core_data);
681
682         /*
683          * Each tcam send msg function should check for key sizes range
684          */
685
686         rc = tf_rm_lookup_tcam_type_pool(tfs,
687                                          parms->dir,
688                                          parms->tcam_tbl_type,
689                                          &session_pool);
690         /* Error logging handled by tf_rm_lookup_tcam_type_pool */
691         if (rc)
692                 return rc;
693
694
695         /* Verify that the entry has been previously allocated */
696         id = ba_inuse(session_pool, parms->idx);
697         if (id != 1) {
698                 PMD_DRV_LOG(ERR,
699                    "%s: %s: Invalid or not allocated index, idx:%d\n",
700                    tf_dir_2_str(parms->dir),
701                    tf_tcam_tbl_2_str(parms->tcam_tbl_type),
702                    parms->idx);
703                 return -EINVAL;
704         }
705
706         rc = tf_msg_tcam_entry_set(tfp, parms);
707
708         return rc;
709 }
710
711 int
712 tf_get_tcam_entry(struct tf *tfp __rte_unused,
713                   struct tf_get_tcam_entry_parms *parms __rte_unused)
714 {
715         int rc = -EOPNOTSUPP;
716
717         if (tfp == NULL || parms == NULL) {
718                 PMD_DRV_LOG(ERR, "Invalid parameters\n");
719                 return -EINVAL;
720         }
721
722         if (tfp->session == NULL || tfp->session->core_data == NULL) {
723                 PMD_DRV_LOG(ERR,
724                             "%s, Session info invalid\n",
725                             tf_dir_2_str(parms->dir));
726                 return -EINVAL;
727         }
728
729         return rc;
730 }
731
732 int
733 tf_free_tcam_entry(struct tf *tfp,
734                    struct tf_free_tcam_entry_parms *parms)
735 {
736         int rc;
737         struct tf_session *tfs;
738         struct bitalloc *session_pool;
739
740         if (parms == NULL || tfp == NULL)
741                 return -EINVAL;
742
743         if (tfp->session == NULL || tfp->session->core_data == NULL) {
744                 PMD_DRV_LOG(ERR, "%s: Session error\n",
745                             tf_dir_2_str(parms->dir));
746                 return -EINVAL;
747         }
748
749         tfs = (struct tf_session *)(tfp->session->core_data);
750
751         rc = tf_rm_lookup_tcam_type_pool(tfs,
752                                          parms->dir,
753                                          parms->tcam_tbl_type,
754                                          &session_pool);
755         /* Error logging handled by tf_rm_lookup_tcam_type_pool */
756         if (rc)
757                 return rc;
758
759         rc = ba_inuse(session_pool, (int)parms->idx);
760         if (rc == BA_FAIL || rc == BA_ENTRY_FREE) {
761                 PMD_DRV_LOG(ERR, "%s: %s: Entry %d already free",
762                             tf_dir_2_str(parms->dir),
763                             tf_tcam_tbl_2_str(parms->tcam_tbl_type),
764                             parms->idx);
765                 return -EINVAL;
766         }
767
768         ba_free(session_pool, (int)parms->idx);
769
770         rc = tf_msg_tcam_entry_free(tfp, parms);
771         if (rc) {
772                 /* Log error */
773                 PMD_DRV_LOG(ERR, "%s: %s: Entry %d free failed",
774                             tf_dir_2_str(parms->dir),
775                             tf_tcam_tbl_2_str(parms->tcam_tbl_type),
776                             parms->idx);
777         }
778
779         return rc;
780 }