LCOV - code coverage report
Current view: top level - drivers/net/bnxt/tf_core - cfa_tcam_mgr_session.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 128 0.0 %
Date: 2024-01-22 15:55:54 Functions: 0 14 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 75 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2021-2023 Broadcom
       3                 :            :  * All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include <inttypes.h>
       7                 :            : #include "hcapi_cfa_defs.h"
       8                 :            : #include "tf_util.h"
       9                 :            : #include "cfa_tcam_mgr.h"
      10                 :            : #include "cfa_tcam_mgr_device.h"
      11                 :            : #include "cfa_tcam_mgr_session.h"
      12                 :            : #include "cfa_tcam_mgr_sbmp.h"
      13                 :            : #include "tfp.h"
      14                 :            : #include "cfa_tcam_mgr_p58.h"
      15                 :            : #include "cfa_tcam_mgr_p4.h"
      16                 :            : 
      17                 :            : struct cfa_tcam_mgr_session_data {
      18                 :            :         uint32_t session_id;
      19                 :            :         /* The following are per-session values */
      20                 :            :         uint16_t max_entries[TF_DIR_MAX][CFA_TCAM_MGR_TBL_TYPE_MAX];
      21                 :            :         uint16_t used_entries[TF_DIR_MAX][CFA_TCAM_MGR_TBL_TYPE_MAX];
      22                 :            : };
      23                 :            : 
      24                 :            : static struct cfa_tcam_mgr_session_data session_data[TF_TCAM_MAX_SESSIONS];
      25                 :            : 
      26                 :            : static uint16_t last_entry_id;
      27                 :            : 
      28                 :            : static struct sbmp *session_bmp[TF_TCAM_MAX_SESSIONS];
      29                 :            : 
      30                 :            : int
      31                 :          0 : cfa_tcam_mgr_session_init(int sess_idx, enum cfa_tcam_mgr_device_type type)
      32                 :            : {
      33                 :            :         int rc;
      34                 :            : 
      35      [ #  #  # ]:          0 :         switch (type) {
      36                 :          0 :         case CFA_TCAM_MGR_DEVICE_TYPE_P4:
      37                 :            :         case CFA_TCAM_MGR_DEVICE_TYPE_SR:
      38                 :          0 :                 rc = cfa_tcam_mgr_sess_table_get_p4(sess_idx, &session_bmp[sess_idx]);
      39                 :          0 :                 break;
      40                 :          0 :         case CFA_TCAM_MGR_DEVICE_TYPE_P5:
      41                 :          0 :                 rc = cfa_tcam_mgr_sess_table_get_p58(sess_idx, &session_bmp[sess_idx]);
      42                 :          0 :                 break;
      43                 :          0 :         default:
      44                 :          0 :                 CFA_TCAM_MGR_LOG(ERR, "No such device %d\n", type);
      45                 :            :                 rc = -CFA_TCAM_MGR_ERR_CODE(NODEV);
      46                 :            :         }
      47                 :            : 
      48                 :          0 :         return rc;
      49                 :            : }
      50                 :            : 
      51                 :            : int
      52                 :          0 : cfa_tcam_mgr_get_session_from_context(struct cfa_tcam_mgr_context *context,
      53                 :            :                                       uint32_t *session_id)
      54                 :            : {
      55         [ #  # ]:          0 :         if (context == NULL) {
      56                 :          0 :                 CFA_TCAM_MGR_LOG_0(ERR, "context passed as NULL pointer.\n");
      57                 :          0 :                 return -CFA_TCAM_MGR_ERR_CODE(INVAL);
      58                 :            :         }
      59                 :            : 
      60                 :          0 :         *session_id = context->tfp->session->session_id.id;
      61                 :          0 :         return 0;
      62                 :            : }
      63                 :            : 
      64                 :            : int
      65                 :          0 : cfa_tcam_mgr_session_find(unsigned int session_id)
      66                 :            : {
      67                 :            :         unsigned int sess_idx;
      68                 :            : 
      69         [ #  # ]:          0 :         for (sess_idx = 0; sess_idx < ARRAY_SIZE(session_data); sess_idx++) {
      70         [ #  # ]:          0 :                 if (session_data[sess_idx].session_id == session_id)
      71                 :          0 :                         return sess_idx;
      72                 :            :         }
      73                 :            : 
      74                 :            :         return -CFA_TCAM_MGR_ERR_CODE(INVAL);
      75                 :            : }
      76                 :            : 
      77                 :            : int
      78                 :          0 : cfa_tcam_mgr_session_add(unsigned int session_id)
      79                 :            : {
      80                 :            :         int sess_idx;
      81                 :            : 
      82                 :          0 :         sess_idx = cfa_tcam_mgr_session_find(session_id);
      83         [ #  # ]:          0 :         if (sess_idx >= 0) {
      84                 :          0 :                 CFA_TCAM_MGR_LOG_0(ERR, "Session is already bound.\n");
      85                 :          0 :                 return -CFA_TCAM_MGR_ERR_CODE(BUSY);
      86                 :            :         }
      87                 :            : 
      88                 :            :         /* Session not found in table, find first empty entry. */
      89                 :            :         for (sess_idx = 0;
      90         [ #  # ]:          0 :              sess_idx < (signed int)ARRAY_SIZE(session_data);
      91                 :          0 :              sess_idx++) {
      92         [ #  # ]:          0 :                 if (session_data[sess_idx].session_id == 0)
      93                 :            :                         break;
      94                 :            :         }
      95                 :            : 
      96         [ #  # ]:          0 :         if (sess_idx >= (signed int)ARRAY_SIZE(session_data)) {
      97                 :            :                 /* No room in the session table */
      98                 :          0 :                 CFA_TCAM_MGR_LOG_0(ERR, "Session table is full.\n");
      99                 :          0 :                 return -CFA_TCAM_MGR_ERR_CODE(NOMEM);
     100                 :            :         }
     101                 :            : 
     102                 :          0 :         session_data[sess_idx].session_id = session_id;
     103                 :            : 
     104                 :          0 :         return sess_idx;
     105                 :            : }
     106                 :            : 
     107                 :            : int
     108                 :          0 : cfa_tcam_mgr_session_free(unsigned int session_id,
     109                 :            :                 struct cfa_tcam_mgr_context *context)
     110                 :            : {
     111                 :            :         struct cfa_tcam_mgr_free_parms free_parms;
     112                 :            :         int entry_id;
     113                 :          0 :         int sess_idx = cfa_tcam_mgr_session_find(session_id);
     114                 :            : 
     115         [ #  # ]:          0 :         if (sess_idx < 0)
     116                 :            :                 return sess_idx;
     117                 :            : 
     118                 :            :         memset(&free_parms, 0, sizeof(free_parms));
     119                 :            :         /* Since we are freeing all pending TCAM entries (which is typically
     120                 :            :          * done during tcam_unbind), we don't know the type of each entry.
     121                 :            :          * So we set the type to MAX as a hint to cfa_tcam_mgr_free() to
     122                 :            :          * figure out the actual type. We need to set it through each
     123                 :            :          * iteration in the loop below; otherwise, the type determined for
     124                 :            :          * the first entry would be used for subsequent entries that may or
     125                 :            :          * may not be of the same type, resulting in errors.
     126                 :            :          */
     127         [ #  # ]:          0 :         for (entry_id = 0; entry_id < cfa_tcam_mgr_max_entries[sess_idx]; entry_id++) {
     128         [ #  # ]:          0 :                 if (SBMP_MEMBER(session_bmp[sess_idx][entry_id], sess_idx)) {
     129                 :          0 :                         SBMP_SESSION_REMOVE(session_bmp[sess_idx][entry_id], sess_idx);
     130                 :            : 
     131                 :          0 :                         free_parms.id = entry_id;
     132                 :          0 :                         free_parms.type = CFA_TCAM_MGR_TBL_TYPE_MAX;
     133                 :          0 :                         cfa_tcam_mgr_free(context, &free_parms);
     134                 :            :                 }
     135                 :            :         }
     136                 :            : 
     137                 :          0 :         memset(&session_data[sess_idx], 0, sizeof(session_data[sess_idx]));
     138                 :          0 :         return 0;
     139                 :            : }
     140                 :            : 
     141                 :            : int
     142                 :          0 : cfa_tcam_mgr_session_cfg(unsigned int session_id,
     143                 :            :                          uint16_t tcam_cnt[][CFA_TCAM_MGR_TBL_TYPE_MAX])
     144                 :            : {
     145                 :            :         struct cfa_tcam_mgr_table_data *table_data;
     146                 :            :         struct cfa_tcam_mgr_session_data *session_entry;
     147                 :            :         unsigned int dir, type;
     148                 :          0 :         int sess_idx = cfa_tcam_mgr_session_find(session_id);
     149                 :            :         uint16_t requested_cnt;
     150                 :            : 
     151         [ #  # ]:          0 :         if (sess_idx < 0)
     152                 :            :                 return sess_idx;
     153                 :            : 
     154                 :            :         session_entry = &session_data[sess_idx];
     155                 :            : 
     156                 :            :         /* Validate session request */
     157         [ #  # ]:          0 :         for (dir = 0; dir < ARRAY_SIZE(cfa_tcam_mgr_tables[sess_idx]); dir++) {
     158                 :            :                 for (type = 0;
     159         [ #  # ]:          0 :                      type < ARRAY_SIZE(cfa_tcam_mgr_tables[sess_idx][dir]);
     160                 :          0 :                      type++) {
     161                 :            :                         table_data = &cfa_tcam_mgr_tables[sess_idx][dir][type];
     162                 :          0 :                         requested_cnt = tcam_cnt[dir][type];
     163                 :            :                         /*
     164                 :            :                          * Only check if table supported (max_entries > 0).
     165                 :            :                          */
     166   [ #  #  #  # ]:          0 :                         if (table_data->max_entries > 0 &&
     167                 :            :                             requested_cnt > table_data->max_entries) {
     168                 :          0 :                                 CFA_TCAM_MGR_LOG_DIR_TYPE(ERR, dir, type,
     169                 :            :                                                 "Requested %d, available %d.\n",
     170                 :            :                                                 requested_cnt,
     171                 :            :                                                 table_data->max_entries);
     172                 :          0 :                                 return -CFA_TCAM_MGR_ERR_CODE(NOSPC);
     173                 :            :                         }
     174                 :            :                 }
     175                 :            :         }
     176                 :            : 
     177                 :          0 :         memcpy(session_entry->max_entries, tcam_cnt,
     178                 :            :                sizeof(session_entry->max_entries));
     179                 :          0 :         return 0;
     180                 :            : }
     181                 :            : 
     182                 :            : void
     183                 :          0 : cfa_tcam_mgr_mv_session_used_entries_cnt(int sess_idx, enum tf_dir dir,
     184                 :            :                                          enum cfa_tcam_mgr_tbl_type dst_type,
     185                 :            :                                          enum cfa_tcam_mgr_tbl_type src_type)
     186                 :            : {
     187                 :          0 :         session_data[sess_idx].used_entries[dir][dst_type]++;
     188                 :          0 :         session_data[sess_idx].used_entries[dir][src_type]--;
     189                 :          0 : }
     190                 :            : 
     191                 :            : int
     192                 :          0 : cfa_tcam_mgr_session_entry_alloc(unsigned int session_id,
     193                 :            :                                  enum tf_dir dir,
     194                 :            :                                  enum cfa_tcam_mgr_tbl_type type)
     195                 :            : {
     196                 :            :         int sess_idx;
     197                 :            : 
     198                 :          0 :         sess_idx = cfa_tcam_mgr_session_find(session_id);
     199         [ #  # ]:          0 :         if (sess_idx < 0) {
     200                 :          0 :                 CFA_TCAM_MGR_LOG_0(ERR, "Session not found.\n");
     201                 :          0 :                 return -CFA_TCAM_MGR_ERR_CODE(NODEV);
     202                 :            :         }
     203                 :            : 
     204                 :          0 :         if (session_data[sess_idx].used_entries[dir][type] >=
     205         [ #  # ]:          0 :             session_data[sess_idx].max_entries[dir][type]) {
     206                 :          0 :                 CFA_TCAM_MGR_LOG_0(ERR, "Table full (session).\n");
     207                 :          0 :                 return -CFA_TCAM_MGR_ERR_CODE(NOSPC);
     208                 :            :         }
     209                 :            : 
     210                 :            :         do {
     211                 :          0 :                 last_entry_id++;
     212         [ #  # ]:          0 :                 if (cfa_tcam_mgr_max_entries[sess_idx] <= last_entry_id)
     213                 :          0 :                         last_entry_id = 0;
     214         [ #  # ]:          0 :         } while (!SBMP_IS_NULL(session_bmp[sess_idx][last_entry_id]));
     215                 :            : 
     216                 :          0 :         SBMP_SESSION_ADD(session_bmp[sess_idx][last_entry_id], sess_idx);
     217                 :            : 
     218                 :          0 :         session_data[sess_idx].used_entries[dir][type] += 1;
     219                 :            : 
     220                 :          0 :         return last_entry_id;
     221                 :            : }
     222                 :            : 
     223                 :            : int
     224                 :          0 : cfa_tcam_mgr_session_entry_free(unsigned int session_id,
     225                 :            :                                 unsigned int entry_id,
     226                 :            :                                 enum tf_dir dir,
     227                 :            :                                 enum cfa_tcam_mgr_tbl_type type)
     228                 :            : {
     229                 :            :         int sess_idx;
     230                 :            : 
     231                 :          0 :         sess_idx = cfa_tcam_mgr_session_find(session_id);
     232         [ #  # ]:          0 :         if (sess_idx < 0) {
     233                 :          0 :                 CFA_TCAM_MGR_LOG_0(ERR, "Session not found.\n");
     234                 :          0 :                 return -CFA_TCAM_MGR_ERR_CODE(NODEV);
     235                 :            :         }
     236                 :            : 
     237                 :          0 :         SBMP_SESSION_REMOVE(session_bmp[sess_idx][entry_id], sess_idx);
     238                 :          0 :         session_data[sess_idx].used_entries[dir][type] -= 1;
     239                 :            : 
     240                 :          0 :         return 0;
     241                 :            : }
     242                 :            : 
     243                 :            : #if SBMP_WORD_WIDTH == 16
     244                 :            : #define SBMP_FORMAT PRIX16
     245                 :            : #define SBMP_PRECISION "4"
     246                 :            : #elif SBMP_WORD_WIDTH == 32
     247                 :            : #define SBMP_FORMAT PRIX32
     248                 :            : #define SBMP_PRECISION "8"
     249                 :            : #elif SBMP_WORD_WIDTH == 64
     250                 :            : #define SBMP_FORMAT PRIX64
     251                 :            : #define SBMP_PRECISION "16"
     252                 :            : #else
     253                 :            : #error "Invalid value for SBMP_WORD_WIDTH."
     254                 :            : #endif
     255                 :            : 
     256                 :            : static void
     257                 :          0 : cfa_tcam_mgr_session_bitmap_print(struct sbmp *session_bmp)
     258                 :            : {
     259                 :            :         unsigned int i;
     260                 :            : 
     261                 :            :         printf("0x");
     262                 :          0 :         for (i = 0;
     263         [ #  # ]:          0 :              i < ARRAY_SIZE(session_bmp->bits);
     264                 :            :              i++) {
     265                 :          0 :                 printf("%0" SBMP_PRECISION SBMP_FORMAT,
     266                 :          0 :                        session_bmp->bits[i]);
     267                 :            :         }
     268                 :          0 : }
     269                 :            : 
     270                 :            : #define SESSION_DUMP_HEADER_1 "                             RX          TX\n"
     271                 :            : #define SESSION_DUMP_HEADER_2 \
     272                 :            :         "                         Max   Used  Max   Used\n"
     273                 :            : 
     274                 :            : static void
     275                 :          0 : cfa_tcam_mgr_session_printf(struct cfa_tcam_mgr_session_data *session,
     276                 :            :                             enum cfa_tcam_mgr_tbl_type tbl_type)
     277                 :            : {
     278                 :          0 :         printf("%-22s: %5u %5u %5u %5u\n",
     279                 :            :                cfa_tcam_mgr_tbl_2_str(tbl_type),
     280                 :          0 :                session->max_entries[TF_DIR_RX][tbl_type],
     281                 :          0 :                session->used_entries[TF_DIR_RX][tbl_type],
     282                 :          0 :                session->max_entries[TF_DIR_TX][tbl_type],
     283                 :          0 :                session->used_entries[TF_DIR_TX][tbl_type]);
     284                 :          0 : }
     285                 :            : 
     286                 :            : void
     287                 :          0 : cfa_tcam_mgr_sessions_dump(void)
     288                 :            : {
     289                 :            :         struct cfa_tcam_mgr_session_data *session;
     290                 :            :         unsigned int sess_idx;
     291                 :            :         bool sess_found = false;
     292                 :            :         enum cfa_tcam_mgr_tbl_type tbl_type;
     293                 :            : 
     294                 :            :         printf("\nTCAM Sessions Table:\n");
     295         [ #  # ]:          0 :         for (sess_idx = 0; sess_idx < ARRAY_SIZE(session_data); sess_idx++) {
     296         [ #  # ]:          0 :                 if (session_data[sess_idx].session_id != 0) {
     297                 :          0 :                         session = &session_data[sess_idx];
     298         [ #  # ]:          0 :                         if (!sess_found) {
     299                 :            :                                 printf(SESSION_DUMP_HEADER_1);
     300                 :            :                                 printf(SESSION_DUMP_HEADER_2);
     301                 :            :                         }
     302                 :          0 :                         printf("Session 0x%08x:\n",
     303                 :            :                                session->session_id);
     304                 :          0 :                         for (tbl_type = CFA_TCAM_MGR_TBL_TYPE_START;
     305         [ #  # ]:          0 :                              tbl_type < CFA_TCAM_MGR_TBL_TYPE_MAX;
     306                 :          0 :                              tbl_type++) {
     307                 :          0 :                                 cfa_tcam_mgr_session_printf(session, tbl_type);
     308                 :            :                         }
     309                 :            :                         sess_found = true;
     310                 :            :                 }
     311                 :            :         }
     312                 :            : 
     313         [ #  # ]:          0 :         if (!sess_found)
     314                 :            :                 printf("No sessions found.\n");
     315                 :          0 : }
     316                 :            : 
     317                 :            : /* This dumps all the sessions using an entry */
     318                 :            : void
     319                 :          0 : cfa_tcam_mgr_entry_sessions_dump(int sess_idx, uint16_t id)
     320                 :            : {
     321                 :            :         bool session_found = false;
     322                 :            : 
     323         [ #  # ]:          0 :         if (id >= cfa_tcam_mgr_max_entries[sess_idx]) {
     324                 :          0 :                 printf("Entry ID %u out of range for sess_idx %d.  Max ID %u.\n",
     325                 :            :                        id, sess_idx, cfa_tcam_mgr_max_entries[sess_idx] - 1);
     326                 :          0 :                 return;
     327                 :            :         }
     328                 :            : 
     329         [ #  # ]:          0 :         if (!SBMP_IS_NULL(session_bmp[sess_idx][id])) {
     330                 :            :                 printf("Sessions using entry ID %u:\n", id);
     331         [ #  # ]:          0 :                 for (sess_idx = 0; sess_idx < SBMP_SESSION_MAX; sess_idx++)
     332         [ #  # ]:          0 :                         if (SBMP_MEMBER(session_bmp[sess_idx][id], (sess_idx))) {
     333         [ #  # ]:          0 :                                 if (session_data[sess_idx].session_id != 0) {
     334                 :            :                                         printf("0x%08x (index %d)\n",
     335                 :            :                                           session_data[sess_idx].session_id,
     336                 :            :                                           sess_idx);
     337                 :            :                                         session_found = true;
     338                 :            :                                 } else {
     339                 :            :                                         printf("Error! Entry ID %u used by "
     340                 :            :                                                "session index %d which is not "
     341                 :            :                                                "in use.\n",
     342                 :            :                                                id, sess_idx);
     343                 :            :                                 }
     344                 :            :                         }
     345         [ #  # ]:          0 :                 if (!session_found)
     346                 :            :                         printf("No sessions using entry ID %u.\n", id);
     347                 :            :         } else {
     348                 :            :                 printf("Entry ID %u not in use.\n",
     349                 :            :                        id);
     350                 :          0 :                 return;
     351                 :            :         }
     352                 :            : }
     353                 :            : 
     354                 :            : /* This dumps all the entries in use by any session */
     355                 :            : void
     356                 :          0 : cfa_tcam_mgr_session_entries_dump(int sess_idx)
     357                 :            : {
     358                 :            :         bool entry_found = false;
     359                 :            :         uint16_t id;
     360                 :            : 
     361                 :          0 :         printf("\nGlobal Maximum Entries for sess_idx %d: %d\n\n",
     362                 :            :                sess_idx, cfa_tcam_mgr_max_entries[sess_idx]);
     363                 :            :         printf("TCAM Session Entry Table:\n");
     364         [ #  # ]:          0 :         for (id = 0; id < cfa_tcam_mgr_max_entries[sess_idx]; id++) {
     365         [ #  # ]:          0 :                 if (!SBMP_IS_NULL(session_bmp[sess_idx][id])) {
     366         [ #  # ]:          0 :                         if (!entry_found)
     367                 :            :                                 printf("  EID Session bitmap\n");
     368                 :            :                         printf("%5u ", id);
     369                 :          0 :                         cfa_tcam_mgr_session_bitmap_print(&session_bmp[sess_idx][id]);
     370                 :            :                         printf("\n");
     371                 :            :                         entry_found = true;
     372                 :            :                 }
     373                 :            :         }
     374                 :            : 
     375         [ #  # ]:          0 :         if (!entry_found)
     376                 :            :                 printf("No entries found.\n");
     377                 :          0 : }

Generated by: LCOV version 1.14