LCOV - code coverage report
Current view: top level - drivers/net/bnxt/tf_ulp - ulp_flow_db.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 644 0.0 %
Date: 2024-04-01 19:00:53 Functions: 0 39 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 378 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2014-2023 Broadcom
       3                 :            :  * All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include <rte_malloc.h>
       7                 :            : #include "bnxt.h"
       8                 :            : #include "bnxt_tf_common.h"
       9                 :            : #include "ulp_utils.h"
      10                 :            : #include "ulp_template_struct.h"
      11                 :            : #include "ulp_mapper.h"
      12                 :            : #include "ulp_flow_db.h"
      13                 :            : #include "ulp_fc_mgr.h"
      14                 :            : #include "ulp_tun.h"
      15                 :            : 
      16                 :            : #define ULP_FLOW_DB_RES_DIR_BIT         31
      17                 :            : #define ULP_FLOW_DB_RES_DIR_MASK        0x80000000
      18                 :            : #define ULP_FLOW_DB_RES_FUNC_BITS       28
      19                 :            : #define ULP_FLOW_DB_RES_FUNC_MASK       0x70000000
      20                 :            : #define ULP_FLOW_DB_RES_NXT_MASK        0x0FFFFFFF
      21                 :            : #define ULP_FLOW_DB_RES_FUNC_UPPER      5
      22                 :            : #define ULP_FLOW_DB_RES_FUNC_NEED_LOWER 0x80
      23                 :            : #define ULP_FLOW_DB_RES_FUNC_LOWER_MASK 0x1F
      24                 :            : 
      25                 :            : /* Macro to copy the nxt_resource_idx */
      26                 :            : #define ULP_FLOW_DB_RES_NXT_SET(dst, src)       {(dst) |= ((src) &\
      27                 :            :                                          ULP_FLOW_DB_RES_NXT_MASK); }
      28                 :            : #define ULP_FLOW_DB_RES_NXT_RESET(dst)  ((dst) &= ~(ULP_FLOW_DB_RES_NXT_MASK))
      29                 :            : 
      30                 :            : /*
      31                 :            :  * Helper function to set the bit in the active flows
      32                 :            :  * No validation is done in this function.
      33                 :            :  *
      34                 :            :  * flow_db [in] Ptr to flow database
      35                 :            :  * flow_type [in] - specify default or regular
      36                 :            :  * idx [in] The index to bit to be set or reset.
      37                 :            :  * flag [in] 1 to set and 0 to reset.
      38                 :            :  *
      39                 :            :  * returns none
      40                 :            :  */
      41                 :            : static void
      42                 :          0 : ulp_flow_db_active_flows_bit_set(struct bnxt_ulp_flow_db *flow_db,
      43                 :            :                                  enum bnxt_ulp_fdb_type flow_type,
      44                 :            :                                  uint32_t idx,
      45                 :            :                                  uint32_t flag)
      46                 :            : {
      47                 :            :         struct bnxt_ulp_flow_tbl *f_tbl = &flow_db->flow_tbl;
      48                 :          0 :         uint32_t a_idx = idx / ULP_INDEX_BITMAP_SIZE;
      49                 :            : 
      50         [ #  # ]:          0 :         if (flag) {
      51         [ #  # ]:          0 :                 if (flow_type == BNXT_ULP_FDB_TYPE_REGULAR || flow_type ==
      52                 :            :                     BNXT_ULP_FDB_TYPE_RID)
      53                 :          0 :                         ULP_INDEX_BITMAP_SET(f_tbl->active_reg_flows[a_idx],
      54                 :            :                                              idx);
      55         [ #  # ]:          0 :                 if (flow_type == BNXT_ULP_FDB_TYPE_DEFAULT || flow_type ==
      56                 :            :                     BNXT_ULP_FDB_TYPE_RID)
      57                 :          0 :                         ULP_INDEX_BITMAP_SET(f_tbl->active_dflt_flows[a_idx],
      58                 :            :                                              idx);
      59                 :            :         } else {
      60         [ #  # ]:          0 :                 if (flow_type == BNXT_ULP_FDB_TYPE_REGULAR || flow_type ==
      61                 :            :                     BNXT_ULP_FDB_TYPE_RID)
      62                 :          0 :                         ULP_INDEX_BITMAP_RESET(f_tbl->active_reg_flows[a_idx],
      63                 :            :                                                idx);
      64         [ #  # ]:          0 :                 if (flow_type == BNXT_ULP_FDB_TYPE_DEFAULT || flow_type ==
      65                 :            :                     BNXT_ULP_FDB_TYPE_RID)
      66                 :          0 :                         ULP_INDEX_BITMAP_RESET(f_tbl->active_dflt_flows[a_idx],
      67                 :            :                                                idx);
      68                 :            :         }
      69                 :          0 : }
      70                 :            : 
      71                 :            : /*
      72                 :            :  * Helper function to check if given fid is active flow.
      73                 :            :  * No validation being done in this function.
      74                 :            :  *
      75                 :            :  * flow_db [in] Ptr to flow database
      76                 :            :  * flow_type [in] - specify default or regular
      77                 :            :  * idx [in] The index to bit to be set or reset.
      78                 :            :  *
      79                 :            :  * returns 1 on set or 0 if not set.
      80                 :            :  */
      81                 :            : static int32_t
      82                 :          0 : ulp_flow_db_active_flows_bit_is_set(struct bnxt_ulp_flow_db *flow_db,
      83                 :            :                                     enum bnxt_ulp_fdb_type flow_type,
      84                 :            :                                     uint32_t idx)
      85                 :            : {
      86                 :            :         struct bnxt_ulp_flow_tbl *f_tbl = &flow_db->flow_tbl;
      87                 :          0 :         uint32_t a_idx = idx / ULP_INDEX_BITMAP_SIZE;
      88                 :            :         uint32_t reg, dflt;
      89                 :            : 
      90                 :          0 :         reg = ULP_INDEX_BITMAP_GET(f_tbl->active_reg_flows[a_idx], idx);
      91                 :          0 :         dflt = ULP_INDEX_BITMAP_GET(f_tbl->active_dflt_flows[a_idx], idx);
      92                 :            : 
      93   [ #  #  #  # ]:          0 :         switch (flow_type) {
      94                 :          0 :         case BNXT_ULP_FDB_TYPE_REGULAR:
      95                 :          0 :                 return (reg && !dflt);
      96                 :          0 :         case BNXT_ULP_FDB_TYPE_DEFAULT:
      97                 :          0 :                 return (!reg && dflt);
      98                 :          0 :         case BNXT_ULP_FDB_TYPE_RID:
      99                 :          0 :                 return (reg && dflt);
     100                 :            :         default:
     101                 :            :                 return 0;
     102                 :            :         }
     103                 :            : }
     104                 :            : 
     105                 :            : static inline enum tf_dir
     106                 :            : ulp_flow_db_resource_dir_get(struct ulp_fdb_resource_info *res_info)
     107                 :            : {
     108                 :          0 :         return ((res_info->nxt_resource_idx & ULP_FLOW_DB_RES_DIR_MASK) >>
     109                 :            :                 ULP_FLOW_DB_RES_DIR_BIT);
     110                 :            : }
     111                 :            : 
     112                 :            : static uint8_t
     113                 :            : ulp_flow_db_resource_func_get(struct ulp_fdb_resource_info *res_info)
     114                 :            : {
     115                 :            :         uint8_t func;
     116                 :            : 
     117                 :          0 :         func = (((res_info->nxt_resource_idx & ULP_FLOW_DB_RES_FUNC_MASK) >>
     118                 :          0 :                  ULP_FLOW_DB_RES_FUNC_BITS) << ULP_FLOW_DB_RES_FUNC_UPPER);
     119                 :            :         /* The resource func is split into upper and lower */
     120                 :          0 :         if (func & ULP_FLOW_DB_RES_FUNC_NEED_LOWER)
     121                 :          0 :                 return (func | res_info->resource_func_lower);
     122                 :            :         return func;
     123                 :            : }
     124                 :            : 
     125                 :            : /*
     126                 :            :  * Helper function to copy the resource params to resource info
     127                 :            :  *  No validation being done in this function.
     128                 :            :  *
     129                 :            :  * resource_info [out] Ptr to resource information
     130                 :            :  * params [in] The input params from the caller
     131                 :            :  * returns none
     132                 :            :  */
     133                 :            : static void
     134                 :          0 : ulp_flow_db_res_params_to_info(struct ulp_fdb_resource_info *resource_info,
     135                 :            :                                struct ulp_flow_db_res_params *params)
     136                 :            : {
     137                 :            :         uint32_t resource_func;
     138                 :            : 
     139                 :          0 :         resource_info->nxt_resource_idx |= ((params->direction <<
     140                 :            :                                       ULP_FLOW_DB_RES_DIR_BIT) &
     141                 :            :                                      ULP_FLOW_DB_RES_DIR_MASK);
     142                 :          0 :         resource_func = (params->resource_func >> ULP_FLOW_DB_RES_FUNC_UPPER);
     143                 :          0 :         resource_info->nxt_resource_idx |= ((resource_func <<
     144                 :          0 :                                              ULP_FLOW_DB_RES_FUNC_BITS) &
     145                 :            :                                             ULP_FLOW_DB_RES_FUNC_MASK);
     146                 :            : 
     147         [ #  # ]:          0 :         if (params->resource_func & ULP_FLOW_DB_RES_FUNC_NEED_LOWER) {
     148                 :            :                 /* Break the resource func into two parts */
     149                 :          0 :                 resource_func = (params->resource_func &
     150                 :            :                                  ULP_FLOW_DB_RES_FUNC_LOWER_MASK);
     151                 :          0 :                 resource_info->resource_func_lower = resource_func;
     152                 :            :         }
     153                 :            : 
     154                 :            :         /* Store the handle as 64bit only for EM table entries */
     155         [ #  # ]:          0 :         if (params->resource_func != BNXT_ULP_RESOURCE_FUNC_EM_TABLE) {
     156                 :          0 :                 resource_info->resource_hndl = (uint32_t)params->resource_hndl;
     157                 :          0 :                 resource_info->resource_type = params->resource_type;
     158                 :          0 :                 resource_info->resource_sub_type = params->resource_sub_type;
     159                 :          0 :                 resource_info->fdb_flags = params->fdb_flags;
     160                 :            :         } else {
     161                 :          0 :                 resource_info->resource_em_handle = params->resource_hndl;
     162                 :            :         }
     163                 :          0 : }
     164                 :            : 
     165                 :            : /*
     166                 :            :  * Helper function to copy the resource params to resource info
     167                 :            :  *  No validation being done in this function.
     168                 :            :  *
     169                 :            :  * resource_info [in] Ptr to resource information
     170                 :            :  * params [out] The output params to the caller
     171                 :            :  *
     172                 :            :  * returns none
     173                 :            :  */
     174                 :            : static void
     175         [ #  # ]:          0 : ulp_flow_db_res_info_to_params(struct ulp_fdb_resource_info *resource_info,
     176                 :            :                                struct ulp_flow_db_res_params *params)
     177                 :            : {
     178                 :            :         memset(params, 0, sizeof(struct ulp_flow_db_res_params));
     179                 :            : 
     180                 :            :         /* use the helper function to get the resource func */
     181         [ #  # ]:          0 :         params->direction = ulp_flow_db_resource_dir_get(resource_info);
     182                 :          0 :         params->resource_func = ulp_flow_db_resource_func_get(resource_info);
     183                 :            : 
     184         [ #  # ]:          0 :         if (params->resource_func == BNXT_ULP_RESOURCE_FUNC_EM_TABLE) {
     185                 :          0 :                 params->resource_hndl = resource_info->resource_em_handle;
     186         [ #  # ]:          0 :         } else if (params->resource_func & ULP_FLOW_DB_RES_FUNC_NEED_LOWER) {
     187                 :          0 :                 params->resource_hndl = resource_info->resource_hndl;
     188                 :          0 :                 params->resource_type = resource_info->resource_type;
     189                 :          0 :                 params->resource_sub_type = resource_info->resource_sub_type;
     190                 :          0 :                 params->fdb_flags = resource_info->fdb_flags;
     191                 :            :         }
     192                 :          0 : }
     193                 :            : 
     194                 :            : /*
     195                 :            :  * Helper function to allocate the flow table and initialize
     196                 :            :  * the stack for allocation operations.
     197                 :            :  *
     198                 :            :  * flow_db [in] Ptr to flow database structure
     199                 :            :  *
     200                 :            :  * Returns 0 on success or negative number on failure.
     201                 :            :  */
     202                 :            : static int32_t
     203                 :          0 : ulp_flow_db_alloc_resource(struct bnxt_ulp_flow_db *flow_db)
     204                 :            : {
     205                 :            :         uint32_t                        idx = 0;
     206                 :            :         struct bnxt_ulp_flow_tbl        *flow_tbl;
     207                 :            :         uint32_t                        size;
     208                 :            : 
     209                 :            :         flow_tbl = &flow_db->flow_tbl;
     210                 :            : 
     211                 :          0 :         size = sizeof(struct ulp_fdb_resource_info) * flow_tbl->num_resources;
     212                 :          0 :         flow_tbl->flow_resources =
     213                 :          0 :                         rte_zmalloc("ulp_fdb_resource_info", size, 0);
     214                 :            : 
     215         [ #  # ]:          0 :         if (!flow_tbl->flow_resources) {
     216                 :          0 :                 BNXT_TF_DBG(ERR, "Failed to alloc memory for flow table\n");
     217                 :          0 :                 return -ENOMEM;
     218                 :            :         }
     219                 :          0 :         size = sizeof(uint32_t) * flow_tbl->num_resources;
     220                 :          0 :         flow_tbl->flow_tbl_stack = rte_zmalloc("flow_tbl_stack", size, 0);
     221         [ #  # ]:          0 :         if (!flow_tbl->flow_tbl_stack) {
     222                 :          0 :                 BNXT_TF_DBG(ERR, "Failed to alloc memory flow tbl stack\n");
     223                 :          0 :                 return -ENOMEM;
     224                 :            :         }
     225                 :          0 :         size = (flow_tbl->num_flows / sizeof(uint64_t)) + 1;
     226                 :          0 :         size = ULP_BYTE_ROUND_OFF_8(size);
     227                 :          0 :         flow_tbl->active_reg_flows = rte_zmalloc("active reg flows", size,
     228                 :            :                                                  ULP_BUFFER_ALIGN_64_BYTE);
     229         [ #  # ]:          0 :         if (!flow_tbl->active_reg_flows) {
     230                 :          0 :                 BNXT_TF_DBG(ERR, "Failed to alloc memory active reg flows\n");
     231                 :          0 :                 return -ENOMEM;
     232                 :            :         }
     233                 :            : 
     234                 :          0 :         flow_tbl->active_dflt_flows = rte_zmalloc("active dflt flows", size,
     235                 :            :                                                   ULP_BUFFER_ALIGN_64_BYTE);
     236         [ #  # ]:          0 :         if (!flow_tbl->active_dflt_flows) {
     237                 :          0 :                 BNXT_TF_DBG(ERR, "Failed to alloc memory active dflt flows\n");
     238                 :          0 :                 return -ENOMEM;
     239                 :            :         }
     240                 :            : 
     241                 :            :         /* Initialize the stack table. */
     242         [ #  # ]:          0 :         for (idx = 0; idx < flow_tbl->num_resources; idx++)
     243                 :          0 :                 flow_tbl->flow_tbl_stack[idx] = idx;
     244                 :            : 
     245                 :            :         /* Ignore the first element in the list. */
     246                 :          0 :         flow_tbl->head_index = 1;
     247                 :            :         /* Tail points to the last entry in the list. */
     248                 :          0 :         flow_tbl->tail_index = flow_tbl->num_resources - 1;
     249                 :          0 :         return 0;
     250                 :            : }
     251                 :            : 
     252                 :            : /*
     253                 :            :  * Helper function to deallocate the flow table.
     254                 :            :  *
     255                 :            :  * flow_db [in] Ptr to flow database structure
     256                 :            :  *
     257                 :            :  * Returns none.
     258                 :            :  */
     259                 :            : static void
     260                 :          0 : ulp_flow_db_dealloc_resource(struct bnxt_ulp_flow_db *flow_db)
     261                 :            : {
     262                 :            :         struct bnxt_ulp_flow_tbl *flow_tbl = &flow_db->flow_tbl;
     263                 :            : 
     264                 :            :         /* Free all the allocated tables in the flow table. */
     265         [ #  # ]:          0 :         if (flow_tbl->active_reg_flows) {
     266                 :          0 :                 rte_free(flow_tbl->active_reg_flows);
     267                 :          0 :                 flow_tbl->active_reg_flows = NULL;
     268                 :            :         }
     269         [ #  # ]:          0 :         if (flow_tbl->active_dflt_flows) {
     270                 :          0 :                 rte_free(flow_tbl->active_dflt_flows);
     271                 :          0 :                 flow_tbl->active_dflt_flows = NULL;
     272                 :            :         }
     273                 :            : 
     274         [ #  # ]:          0 :         if (flow_tbl->flow_tbl_stack) {
     275                 :          0 :                 rte_free(flow_tbl->flow_tbl_stack);
     276                 :          0 :                 flow_tbl->flow_tbl_stack = NULL;
     277                 :            :         }
     278                 :            : 
     279         [ #  # ]:          0 :         if (flow_tbl->flow_resources) {
     280                 :          0 :                 rte_free(flow_tbl->flow_resources);
     281                 :          0 :                 flow_tbl->flow_resources = NULL;
     282                 :            :         }
     283                 :          0 : }
     284                 :            : 
     285                 :            : /*
     286                 :            :  * Helper function to add function id to the flow table
     287                 :            :  *
     288                 :            :  * flow_db [in] Ptr to flow table
     289                 :            :  * flow_id [in] The flow id of the flow
     290                 :            :  * func_id [in] The func_id to be set, for reset pass zero
     291                 :            :  *
     292                 :            :  * returns none
     293                 :            :  */
     294                 :            : static void
     295                 :          0 : ulp_flow_db_func_id_set(struct bnxt_ulp_flow_db *flow_db,
     296                 :            :                         uint32_t flow_id,
     297                 :            :                         uint32_t func_id)
     298                 :            : {
     299                 :            :         /* set the function id in the function table */
     300         [ #  # ]:          0 :         if (flow_id < flow_db->func_id_tbl_size)
     301                 :          0 :                 flow_db->func_id_tbl[flow_id] = func_id;
     302                 :            :         else /* This should never happen */
     303                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid flow id, flowdb corrupt\n");
     304                 :          0 : }
     305                 :            : 
     306                 :            : /*
     307                 :            :  * Initialize the parent-child database. Memory is allocated in this
     308                 :            :  * call and assigned to the database
     309                 :            :  *
     310                 :            :  * flow_db [in] Ptr to flow table
     311                 :            :  * num_entries[in] - number of entries to allocate
     312                 :            :  *
     313                 :            :  * Returns 0 on success or negative number on failure.
     314                 :            :  */
     315                 :            : static int32_t
     316                 :          0 : ulp_flow_db_parent_tbl_init(struct bnxt_ulp_flow_db *flow_db,
     317                 :            :                             uint32_t num_entries)
     318                 :            : {
     319                 :            :         struct ulp_fdb_parent_child_db *p_db;
     320                 :            :         uint32_t size, idx;
     321                 :            : 
     322         [ #  # ]:          0 :         if (!num_entries)
     323                 :            :                 return 0;
     324                 :            : 
     325                 :            :         /* update the sizes for the allocation */
     326                 :            :         p_db = &flow_db->parent_child_db;
     327                 :          0 :         p_db->child_bitset_size = (flow_db->flow_tbl.num_flows /
     328                 :          0 :                                    sizeof(uint64_t)) + 1; /* size in bytes */
     329                 :          0 :         p_db->child_bitset_size = ULP_BYTE_ROUND_OFF_8(p_db->child_bitset_size);
     330                 :          0 :         p_db->entries_count = num_entries;
     331                 :            : 
     332                 :            :         /* allocate the memory */
     333                 :          0 :         p_db->parent_flow_tbl = rte_zmalloc("fdb parent flow tbl",
     334                 :            :                                             sizeof(struct ulp_fdb_parent_info) *
     335                 :          0 :                                             p_db->entries_count, 0);
     336         [ #  # ]:          0 :         if (!p_db->parent_flow_tbl) {
     337                 :          0 :                 BNXT_TF_DBG(ERR,
     338                 :            :                             "Failed to allocate memory fdb parent flow tbl\n");
     339                 :          0 :                 return -ENOMEM;
     340                 :            :         }
     341                 :          0 :         size = p_db->child_bitset_size * p_db->entries_count;
     342                 :            : 
     343                 :            :         /*
     344                 :            :          * allocate the big chunk of memory to be statically carved into
     345                 :            :          * child_fid_bitset pointer.
     346                 :            :          */
     347                 :          0 :         p_db->parent_flow_tbl_mem = rte_zmalloc("fdb parent flow tbl mem",
     348                 :            :                                                 size,
     349                 :            :                                                 ULP_BUFFER_ALIGN_64_BYTE);
     350         [ #  # ]:          0 :         if (!p_db->parent_flow_tbl_mem) {
     351                 :          0 :                 BNXT_TF_DBG(ERR,
     352                 :            :                             "Failed to allocate memory fdb parent flow mem\n");
     353                 :          0 :                 return -ENOMEM;
     354                 :            :         }
     355                 :            : 
     356                 :            :         /* set the pointers in parent table to their offsets */
     357         [ #  # ]:          0 :         for (idx = 0 ; idx < p_db->entries_count; idx++) {
     358                 :          0 :                 p_db->parent_flow_tbl[idx].child_fid_bitset =
     359                 :          0 :                         (uint64_t *)&p_db->parent_flow_tbl_mem[idx *
     360                 :          0 :                         p_db->child_bitset_size];
     361                 :            :         }
     362                 :            :         /* success */
     363                 :            :         return 0;
     364                 :            : }
     365                 :            : 
     366                 :            : /*
     367                 :            :  * Deinitialize the parent-child database. Memory is deallocated in
     368                 :            :  * this call and all flows should have been purged before this
     369                 :            :  * call.
     370                 :            :  *
     371                 :            :  * flow_db [in] Ptr to flow table
     372                 :            :  *
     373                 :            :  * Returns none
     374                 :            :  */
     375                 :            : static void
     376                 :          0 : ulp_flow_db_parent_tbl_deinit(struct bnxt_ulp_flow_db *flow_db)
     377                 :            : {
     378                 :            :         /* free the memory related to parent child database */
     379         [ #  # ]:          0 :         if (flow_db->parent_child_db.parent_flow_tbl_mem) {
     380                 :          0 :                 rte_free(flow_db->parent_child_db.parent_flow_tbl_mem);
     381                 :          0 :                 flow_db->parent_child_db.parent_flow_tbl_mem = NULL;
     382                 :            :         }
     383         [ #  # ]:          0 :         if (flow_db->parent_child_db.parent_flow_tbl) {
     384                 :          0 :                 rte_free(flow_db->parent_child_db.parent_flow_tbl);
     385                 :          0 :                 flow_db->parent_child_db.parent_flow_tbl = NULL;
     386                 :            :         }
     387                 :          0 : }
     388                 :            : 
     389                 :            : /*
     390                 :            :  * Initialize the flow database. Memory is allocated in this
     391                 :            :  * call and assigned to the flow database.
     392                 :            :  *
     393                 :            :  * ulp_ctxt [in] Ptr to ulp context
     394                 :            :  *
     395                 :            :  * Returns 0 on success or negative number on failure.
     396                 :            :  */
     397                 :            : int32_t
     398                 :          0 : ulp_flow_db_init(struct bnxt_ulp_context *ulp_ctxt)
     399                 :            : {
     400                 :            :         struct bnxt_ulp_device_params *dparms;
     401                 :            :         struct bnxt_ulp_flow_tbl *flow_tbl;
     402                 :            :         struct bnxt_ulp_flow_db *flow_db;
     403                 :            :         uint32_t dev_id, num_flows;
     404                 :            :         enum bnxt_ulp_flow_mem_type mtype;
     405                 :            : 
     406                 :            :         /* Get the dev specific number of flows that needed to be supported. */
     407         [ #  # ]:          0 :         if (bnxt_ulp_cntxt_dev_id_get(ulp_ctxt, &dev_id)) {
     408                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid device id\n");
     409                 :          0 :                 return -EINVAL;
     410                 :            :         }
     411                 :            : 
     412                 :          0 :         dparms = bnxt_ulp_device_params_get(dev_id);
     413         [ #  # ]:          0 :         if (!dparms) {
     414                 :          0 :                 BNXT_TF_DBG(ERR, "could not fetch the device params\n");
     415                 :          0 :                 return -ENODEV;
     416                 :            :         }
     417                 :            : 
     418                 :          0 :         flow_db = rte_zmalloc("bnxt_ulp_flow_db",
     419                 :            :                               sizeof(struct bnxt_ulp_flow_db), 0);
     420         [ #  # ]:          0 :         if (!flow_db) {
     421                 :          0 :                 BNXT_TF_DBG(ERR,
     422                 :            :                             "Failed to allocate memory for flow table ptr\n");
     423                 :          0 :                 return -ENOMEM;
     424                 :            :         }
     425                 :            : 
     426                 :            :         /* Attach the flow database to the ulp context. */
     427                 :          0 :         bnxt_ulp_cntxt_ptr2_flow_db_set(ulp_ctxt, flow_db);
     428                 :            : 
     429                 :            :         /* Determine the number of flows based on EM type */
     430         [ #  # ]:          0 :         if (bnxt_ulp_cntxt_mem_type_get(ulp_ctxt, &mtype))
     431                 :          0 :                 goto error_free;
     432                 :            : 
     433         [ #  # ]:          0 :         if (mtype == BNXT_ULP_FLOW_MEM_TYPE_INT)
     434                 :          0 :                 num_flows = dparms->int_flow_db_num_entries;
     435                 :            :         else
     436                 :          0 :                 num_flows = dparms->ext_flow_db_num_entries;
     437                 :            : 
     438                 :            :         /* Populate the regular flow table limits. */
     439                 :            :         flow_tbl = &flow_db->flow_tbl;
     440                 :          0 :         flow_tbl->num_flows = num_flows + 1;
     441                 :          0 :         flow_tbl->num_resources = ((num_flows + 1) *
     442                 :          0 :                                    dparms->num_resources_per_flow);
     443                 :            : 
     444                 :            :         /* Include the default flow table limits. */
     445                 :          0 :         flow_tbl->num_flows += (BNXT_FLOW_DB_DEFAULT_NUM_FLOWS + 1);
     446                 :          0 :         flow_tbl->num_resources += ((BNXT_FLOW_DB_DEFAULT_NUM_FLOWS + 1) *
     447                 :            :                                     BNXT_FLOW_DB_DEFAULT_NUM_RESOURCES);
     448                 :            : 
     449                 :            :         /* Allocate the resource for the flow table. */
     450         [ #  # ]:          0 :         if (ulp_flow_db_alloc_resource(flow_db))
     451                 :          0 :                 goto error_free;
     452                 :            : 
     453                 :            :         /* add 1 since we are not using index 0 for flow id */
     454                 :          0 :         flow_db->func_id_tbl_size = flow_tbl->num_flows + 1;
     455                 :            :         /* Allocate the function Id table */
     456                 :          0 :         flow_db->func_id_tbl = rte_zmalloc("bnxt_ulp_flow_db_func_id_table",
     457                 :          0 :                                            flow_db->func_id_tbl_size *
     458                 :            :                                            sizeof(uint16_t), 0);
     459         [ #  # ]:          0 :         if (!flow_db->func_id_tbl) {
     460                 :          0 :                 BNXT_TF_DBG(ERR,
     461                 :            :                             "Failed to allocate mem for flow table func id\n");
     462                 :          0 :                 goto error_free;
     463                 :            :         }
     464                 :            :         /* initialize the parent child database */
     465         [ #  # ]:          0 :         if (ulp_flow_db_parent_tbl_init(flow_db,
     466                 :            :                                         dparms->fdb_parent_flow_entries)) {
     467                 :          0 :                 BNXT_TF_DBG(ERR,
     468                 :            :                             "Failed to allocate mem for parent child db\n");
     469                 :          0 :                 goto error_free;
     470                 :            :         }
     471                 :            : 
     472                 :            :         /* All good so return. */
     473                 :          0 :         BNXT_TF_DBG(DEBUG, "FlowDB initialized with %d flows.\n",
     474                 :            :                     flow_tbl->num_flows);
     475                 :          0 :         return 0;
     476                 :          0 : error_free:
     477                 :          0 :         ulp_flow_db_deinit(ulp_ctxt);
     478                 :          0 :         return -ENOMEM;
     479                 :            : }
     480                 :            : 
     481                 :            : /*
     482                 :            :  * Deinitialize the flow database. Memory is deallocated in
     483                 :            :  * this call and all flows should have been purged before this
     484                 :            :  * call.
     485                 :            :  *
     486                 :            :  * ulp_ctxt [in] Ptr to ulp context
     487                 :            :  *
     488                 :            :  * Returns 0 on success.
     489                 :            :  */
     490                 :            : int32_t
     491                 :          0 : ulp_flow_db_deinit(struct bnxt_ulp_context *ulp_ctxt)
     492                 :            : {
     493                 :            :         struct bnxt_ulp_flow_db *flow_db;
     494                 :            : 
     495                 :          0 :         flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
     496         [ #  # ]:          0 :         if (!flow_db)
     497                 :            :                 return -EINVAL;
     498                 :            : 
     499                 :            :         /* Detach the flow database from the ulp context. */
     500                 :          0 :         bnxt_ulp_cntxt_ptr2_flow_db_set(ulp_ctxt, NULL);
     501                 :            : 
     502                 :            :         /* Free up all the memory. */
     503                 :          0 :         ulp_flow_db_parent_tbl_deinit(flow_db);
     504                 :          0 :         ulp_flow_db_dealloc_resource(flow_db);
     505                 :          0 :         rte_free(flow_db->func_id_tbl);
     506                 :          0 :         rte_free(flow_db);
     507                 :            : 
     508                 :          0 :         return 0;
     509                 :            : }
     510                 :            : 
     511                 :            : /*
     512                 :            :  * Allocate the flow database entry
     513                 :            :  *
     514                 :            :  * ulp_ctxt [in] Ptr to ulp_context
     515                 :            :  * flow_type [in] - specify default or regular
     516                 :            :  * func_id [in].function id of the ingress port
     517                 :            :  * fid [out] The index to the flow entry
     518                 :            :  *
     519                 :            :  * returns 0 on success and negative on failure.
     520                 :            :  */
     521                 :            : int32_t
     522                 :          0 : ulp_flow_db_fid_alloc(struct bnxt_ulp_context *ulp_ctxt,
     523                 :            :                       enum bnxt_ulp_fdb_type flow_type,
     524                 :            :                       uint16_t func_id,
     525                 :            :                       uint32_t *fid)
     526                 :            : {
     527                 :            :         struct bnxt_ulp_flow_db *flow_db;
     528                 :            :         struct bnxt_ulp_flow_tbl *flow_tbl;
     529                 :            : 
     530                 :          0 :         *fid = 0; /* Initialize fid to invalid value */
     531                 :          0 :         flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
     532         [ #  # ]:          0 :         if (!flow_db) {
     533                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
     534                 :          0 :                 return -EINVAL;
     535                 :            :         }
     536                 :            : 
     537         [ #  # ]:          0 :         if (flow_type >= BNXT_ULP_FDB_TYPE_LAST) {
     538                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid flow type\n");
     539                 :          0 :                 return -EINVAL;
     540                 :            :         }
     541                 :            : 
     542                 :            :         flow_tbl = &flow_db->flow_tbl;
     543                 :            :         /* check for max flows */
     544         [ #  # ]:          0 :         if (flow_tbl->num_flows <= flow_tbl->head_index) {
     545                 :          0 :                 BNXT_TF_DBG(ERR, "Flow database has reached max flows\n");
     546                 :          0 :                 return -ENOMEM;
     547                 :            :         }
     548         [ #  # ]:          0 :         if (flow_tbl->tail_index <= (flow_tbl->head_index + 1)) {
     549                 :          0 :                 BNXT_TF_DBG(ERR, "Flow database has reached max resources\n");
     550                 :          0 :                 return -ENOMEM;
     551                 :            :         }
     552                 :          0 :         *fid = flow_tbl->flow_tbl_stack[flow_tbl->head_index];
     553                 :          0 :         flow_tbl->head_index++;
     554                 :            : 
     555                 :            :         /* Set the flow type */
     556                 :          0 :         ulp_flow_db_active_flows_bit_set(flow_db, flow_type, *fid, 1);
     557                 :            : 
     558                 :            :         /* function id update is only valid for regular flow table */
     559         [ #  # ]:          0 :         if (flow_type == BNXT_ULP_FDB_TYPE_REGULAR)
     560                 :          0 :                 ulp_flow_db_func_id_set(flow_db, *fid, func_id);
     561                 :            : 
     562                 :            :         /* return success */
     563                 :            :         return 0;
     564                 :            : }
     565                 :            : 
     566                 :            : /*
     567                 :            :  * Allocate the flow database entry.
     568                 :            :  * The params->critical_resource has to be set to 0 to allocate a new resource.
     569                 :            :  *
     570                 :            :  * ulp_ctxt [in] Ptr to ulp_context
     571                 :            :  * flow_type [in] Specify it is regular or default flow
     572                 :            :  * fid [in] The index to the flow entry
     573                 :            :  * params [in] The contents to be copied into resource
     574                 :            :  *
     575                 :            :  * returns 0 on success and negative on failure.
     576                 :            :  */
     577                 :            : int32_t
     578                 :          0 : ulp_flow_db_resource_add(struct bnxt_ulp_context *ulp_ctxt,
     579                 :            :                          enum bnxt_ulp_fdb_type flow_type,
     580                 :            :                          uint32_t fid,
     581                 :            :                          struct ulp_flow_db_res_params *params)
     582                 :            : {
     583                 :            :         struct bnxt_ulp_flow_db *flow_db;
     584                 :            :         struct bnxt_ulp_flow_tbl *flow_tbl;
     585                 :            :         struct ulp_fdb_resource_info *resource, *fid_resource;
     586                 :            :         struct bnxt_ulp_fc_info *ulp_fc_info;
     587                 :            :         uint32_t idx;
     588                 :            : 
     589                 :          0 :         flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
     590         [ #  # ]:          0 :         if (!flow_db) {
     591                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
     592                 :          0 :                 return -EINVAL;
     593                 :            :         }
     594                 :            : 
     595         [ #  # ]:          0 :         if (flow_type >= BNXT_ULP_FDB_TYPE_LAST) {
     596                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid flow type\n");
     597                 :          0 :                 return -EINVAL;
     598                 :            :         }
     599                 :            : 
     600                 :            :         flow_tbl = &flow_db->flow_tbl;
     601                 :            :         /* check for max flows */
     602   [ #  #  #  # ]:          0 :         if (fid >= flow_tbl->num_flows || !fid) {
     603                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid flow index\n");
     604                 :          0 :                 return -EINVAL;
     605                 :            :         }
     606                 :            : 
     607                 :            :         /* check if the flow is active or not */
     608         [ #  # ]:          0 :         if (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type, fid)) {
     609                 :          0 :                 BNXT_TF_DBG(ERR, "flow does not exist %x:%x\n", flow_type, fid);
     610                 :          0 :                 return -EINVAL;
     611                 :            :         }
     612                 :            : 
     613                 :            :         /* check for max resource */
     614         [ #  # ]:          0 :         if ((flow_tbl->head_index + 1) >= flow_tbl->tail_index) {
     615                 :          0 :                 BNXT_TF_DBG(ERR, "Flow db has reached max resources\n");
     616                 :          0 :                 return -ENOMEM;
     617                 :            :         }
     618                 :          0 :         fid_resource = &flow_tbl->flow_resources[fid];
     619                 :            : 
     620   [ #  #  #  # ]:          0 :         if (params->critical_resource && fid_resource->resource_em_handle) {
     621                 :          0 :                 BNXT_TF_DBG(DEBUG, "Ignore multiple critical resources\n");
     622                 :            :                 /* Ignore the multiple critical resources */
     623                 :          0 :                 params->critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO;
     624                 :            :         }
     625                 :            : 
     626         [ #  # ]:          0 :         if (!params->critical_resource) {
     627                 :            :                 /* Not the critical_resource so allocate a resource */
     628                 :          0 :                 idx = flow_tbl->flow_tbl_stack[flow_tbl->tail_index];
     629                 :          0 :                 resource = &flow_tbl->flow_resources[idx];
     630                 :          0 :                 flow_tbl->tail_index--;
     631                 :            : 
     632                 :            :                 /* Update the chain list of resource*/
     633                 :          0 :                 ULP_FLOW_DB_RES_NXT_SET(resource->nxt_resource_idx,
     634                 :            :                                         fid_resource->nxt_resource_idx);
     635                 :            :                 /* update the contents */
     636                 :          0 :                 ulp_flow_db_res_params_to_info(resource, params);
     637                 :          0 :                 ULP_FLOW_DB_RES_NXT_RESET(fid_resource->nxt_resource_idx);
     638                 :          0 :                 ULP_FLOW_DB_RES_NXT_SET(fid_resource->nxt_resource_idx,
     639                 :            :                                         idx);
     640                 :            :         } else {
     641                 :            :                 /* critical resource. Just update the fid resource */
     642                 :          0 :                 ulp_flow_db_res_params_to_info(fid_resource, params);
     643                 :            :         }
     644                 :            : 
     645                 :          0 :         ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ulp_ctxt);
     646         [ #  # ]:          0 :         if (params->resource_type == TF_TBL_TYPE_ACT_STATS_64 &&
     647                 :            :             params->resource_sub_type ==
     648         [ #  # ]:          0 :             BNXT_ULP_RESOURCE_SUB_TYPE_INDEX_TABLE_INT_COUNT &&
     649         [ #  # ]:          0 :             ulp_fc_info && ulp_fc_info->num_counters) {
     650                 :            :                 /* Store the first HW counter ID for this table */
     651         [ #  # ]:          0 :                 if (!ulp_fc_mgr_start_idx_isset(ulp_ctxt, params->direction))
     652                 :          0 :                         ulp_fc_mgr_start_idx_set(ulp_ctxt, params->direction,
     653                 :          0 :                                                  params->resource_hndl);
     654                 :            : 
     655                 :          0 :                 ulp_fc_mgr_cntr_set(ulp_ctxt, params->direction,
     656                 :          0 :                                     params->resource_hndl,
     657                 :            :                                     ulp_flow_db_shared_session_get(params));
     658                 :            : 
     659         [ #  # ]:          0 :                 if (!ulp_fc_mgr_thread_isstarted(ulp_ctxt))
     660                 :          0 :                         ulp_fc_mgr_thread_start(ulp_ctxt);
     661                 :            :         }
     662                 :            : 
     663                 :            :         /* all good, return success */
     664                 :            :         return 0;
     665                 :            : }
     666                 :            : 
     667                 :            : /*
     668                 :            :  * Free the flow database entry.
     669                 :            :  * The params->critical_resource has to be set to 1 to free the first resource.
     670                 :            :  *
     671                 :            :  * ulp_ctxt [in] Ptr to ulp_context
     672                 :            :  * flow_type [in] Specify it is regular or default flow
     673                 :            :  * fid [in] The index to the flow entry
     674                 :            :  * params [in/out] The contents to be copied into params.
     675                 :            :  * Only the critical_resource needs to be set by the caller.
     676                 :            :  *
     677                 :            :  * Returns 0 on success and negative on failure.
     678                 :            :  */
     679                 :            : int32_t
     680                 :          0 : ulp_flow_db_resource_del(struct bnxt_ulp_context *ulp_ctxt,
     681                 :            :                          enum bnxt_ulp_fdb_type flow_type,
     682                 :            :                          uint32_t fid,
     683                 :            :                          struct ulp_flow_db_res_params *params)
     684                 :            : {
     685                 :            :         struct bnxt_ulp_flow_db *flow_db;
     686                 :            :         struct bnxt_ulp_flow_tbl *flow_tbl;
     687                 :            :         struct ulp_fdb_resource_info *nxt_resource, *fid_resource;
     688                 :            :         uint32_t nxt_idx = 0;
     689                 :            : 
     690                 :          0 :         flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
     691         [ #  # ]:          0 :         if (!flow_db) {
     692                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
     693                 :          0 :                 return -EINVAL;
     694                 :            :         }
     695                 :            : 
     696         [ #  # ]:          0 :         if (flow_type >= BNXT_ULP_FDB_TYPE_LAST) {
     697                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid flow type\n");
     698                 :          0 :                 return -EINVAL;
     699                 :            :         }
     700                 :            : 
     701                 :            :         flow_tbl = &flow_db->flow_tbl;
     702                 :            :         /* check for max flows */
     703   [ #  #  #  # ]:          0 :         if (fid >= flow_tbl->num_flows || !fid) {
     704                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid flow index %x\n", fid);
     705                 :          0 :                 return -EINVAL;
     706                 :            :         }
     707                 :            : 
     708                 :            :         /* check if the flow is active or not */
     709         [ #  # ]:          0 :         if (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type, fid)) {
     710                 :          0 :                 BNXT_TF_DBG(ERR, "flow does not exist %x:%x\n", flow_type, fid);
     711                 :          0 :                 return -EINVAL;
     712                 :            :         }
     713                 :            : 
     714                 :          0 :         fid_resource = &flow_tbl->flow_resources[fid];
     715         [ #  # ]:          0 :         if (!params->critical_resource) {
     716                 :            :                 /* Not the critical resource so free the resource */
     717                 :          0 :                 ULP_FLOW_DB_RES_NXT_SET(nxt_idx,
     718                 :            :                                         fid_resource->nxt_resource_idx);
     719         [ #  # ]:          0 :                 if (!nxt_idx) {
     720                 :            :                         /* reached end of resources */
     721                 :            :                         return -ENOENT;
     722                 :            :                 }
     723                 :          0 :                 nxt_resource = &flow_tbl->flow_resources[nxt_idx];
     724                 :            : 
     725                 :            :                 /* connect the fid resource to the next resource */
     726                 :          0 :                 ULP_FLOW_DB_RES_NXT_RESET(fid_resource->nxt_resource_idx);
     727                 :          0 :                 ULP_FLOW_DB_RES_NXT_SET(fid_resource->nxt_resource_idx,
     728                 :            :                                         nxt_resource->nxt_resource_idx);
     729                 :            : 
     730                 :            :                 /* update the contents to be given to caller */
     731                 :          0 :                 ulp_flow_db_res_info_to_params(nxt_resource, params);
     732                 :            : 
     733                 :            :                 /* Delete the nxt_resource */
     734                 :            :                 memset(nxt_resource, 0, sizeof(struct ulp_fdb_resource_info));
     735                 :            : 
     736                 :            :                 /* add it to the free list */
     737                 :          0 :                 flow_tbl->tail_index++;
     738         [ #  # ]:          0 :                 if (flow_tbl->tail_index >= flow_tbl->num_resources) {
     739                 :          0 :                         BNXT_TF_DBG(ERR, "FlowDB:Tail reached max\n");
     740                 :          0 :                         return -ENOENT;
     741                 :            :                 }
     742                 :          0 :                 flow_tbl->flow_tbl_stack[flow_tbl->tail_index] = nxt_idx;
     743                 :            : 
     744                 :            :         } else {
     745                 :            :                 /* Critical resource. copy the contents and exit */
     746                 :          0 :                 ulp_flow_db_res_info_to_params(fid_resource, params);
     747                 :          0 :                 ULP_FLOW_DB_RES_NXT_SET(nxt_idx,
     748                 :            :                                         fid_resource->nxt_resource_idx);
     749                 :            :                 memset(fid_resource, 0, sizeof(struct ulp_fdb_resource_info));
     750                 :          0 :                 ULP_FLOW_DB_RES_NXT_SET(fid_resource->nxt_resource_idx,
     751                 :            :                                         nxt_idx);
     752                 :            :         }
     753                 :            : 
     754                 :            :         /* Now that the HW Flow counter resource is deleted, reset it's
     755                 :            :          * corresponding slot in the SW accumulation table in the Flow Counter
     756                 :            :          * manager
     757                 :            :          */
     758         [ #  # ]:          0 :         if (params->resource_type == TF_TBL_TYPE_ACT_STATS_64 &&
     759                 :            :             params->resource_sub_type ==
     760                 :            :             BNXT_ULP_RESOURCE_SUB_TYPE_INDEX_TABLE_INT_COUNT) {
     761                 :          0 :                 ulp_fc_mgr_cntr_reset(ulp_ctxt, params->direction,
     762                 :          0 :                                       params->resource_hndl);
     763                 :            :         }
     764                 :            : 
     765                 :            :         /* all good, return success */
     766                 :            :         return 0;
     767                 :            : }
     768                 :            : 
     769                 :            : /*
     770                 :            :  * Free the flow database entry
     771                 :            :  *
     772                 :            :  * ulp_ctxt [in] Ptr to ulp_context
     773                 :            :  * flow_type [in] - specify default or regular
     774                 :            :  * fid [in] The index to the flow entry
     775                 :            :  *
     776                 :            :  * returns 0 on success and negative on failure.
     777                 :            :  */
     778                 :            : int32_t
     779                 :          0 : ulp_flow_db_fid_free(struct bnxt_ulp_context *ulp_ctxt,
     780                 :            :                      enum bnxt_ulp_fdb_type flow_type,
     781                 :            :                      uint32_t fid)
     782                 :            : {
     783                 :            :         struct bnxt_ulp_flow_tbl *flow_tbl;
     784                 :            :         struct bnxt_ulp_flow_db *flow_db;
     785                 :            : 
     786                 :          0 :         flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
     787         [ #  # ]:          0 :         if (!flow_db) {
     788                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
     789                 :          0 :                 return -EINVAL;
     790                 :            :         }
     791                 :            : 
     792         [ #  # ]:          0 :         if (flow_type >= BNXT_ULP_FDB_TYPE_LAST) {
     793                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid flow type\n");
     794                 :          0 :                 return -EINVAL;
     795                 :            :         }
     796                 :            : 
     797                 :            :         flow_tbl = &flow_db->flow_tbl;
     798                 :            : 
     799                 :            :         /* check for limits of fid */
     800   [ #  #  #  # ]:          0 :         if (fid >= flow_tbl->num_flows || !fid) {
     801                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid flow index\n");
     802                 :          0 :                 return -EINVAL;
     803                 :            :         }
     804                 :            : 
     805                 :            :         /* check if the flow is active or not */
     806         [ #  # ]:          0 :         if (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type, fid)) {
     807                 :          0 :                 BNXT_TF_DBG(ERR, "flow does not exist %x:%x\n", flow_type, fid);
     808                 :          0 :                 return -EINVAL;
     809                 :            :         }
     810                 :          0 :         flow_tbl->head_index--;
     811         [ #  # ]:          0 :         if (!flow_tbl->head_index) {
     812                 :          0 :                 BNXT_TF_DBG(ERR, "FlowDB: Head Ptr is zero\n");
     813                 :          0 :                 return -ENOENT;
     814                 :            :         }
     815                 :            : 
     816                 :          0 :         flow_tbl->flow_tbl_stack[flow_tbl->head_index] = fid;
     817                 :            : 
     818                 :            :         /* Clear the flows bitmap */
     819                 :          0 :         ulp_flow_db_active_flows_bit_set(flow_db, flow_type, fid, 0);
     820                 :            : 
     821         [ #  # ]:          0 :         if (flow_type == BNXT_ULP_FDB_TYPE_REGULAR)
     822                 :          0 :                 ulp_flow_db_func_id_set(flow_db, fid, 0);
     823                 :            : 
     824                 :            :         /* all good, return success */
     825                 :            :         return 0;
     826                 :            : }
     827                 :            : 
     828                 :            : /*
     829                 :            :  *Get the flow database entry details
     830                 :            :  *
     831                 :            :  * ulp_ctxt [in] Ptr to ulp_context
     832                 :            :  * flow_type [in] - specify default or regular
     833                 :            :  * fid [in] The index to the flow entry
     834                 :            :  * nxt_idx [in/out] the index to the next entry
     835                 :            :  * params [out] The contents to be copied into params.
     836                 :            :  *
     837                 :            :  * returns 0 on success and negative on failure.
     838                 :            :  */
     839                 :            : int32_t
     840                 :          0 : ulp_flow_db_resource_get(struct bnxt_ulp_context *ulp_ctxt,
     841                 :            :                          enum bnxt_ulp_fdb_type flow_type,
     842                 :            :                          uint32_t fid,
     843                 :            :                          uint32_t *nxt_idx,
     844                 :            :                          struct ulp_flow_db_res_params *params)
     845                 :            : {
     846                 :            :         struct bnxt_ulp_flow_db *flow_db;
     847                 :            :         struct bnxt_ulp_flow_tbl *flow_tbl;
     848                 :            :         struct ulp_fdb_resource_info *nxt_resource, *fid_resource;
     849                 :            : 
     850                 :          0 :         flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
     851         [ #  # ]:          0 :         if (!flow_db) {
     852                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
     853                 :          0 :                 return -EINVAL;
     854                 :            :         }
     855                 :            : 
     856         [ #  # ]:          0 :         if (flow_type >= BNXT_ULP_FDB_TYPE_LAST) {
     857                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid flow type\n");
     858                 :          0 :                 return -EINVAL;
     859                 :            :         }
     860                 :            : 
     861                 :            :         flow_tbl = &flow_db->flow_tbl;
     862                 :            : 
     863                 :            :         /* check for limits of fid */
     864   [ #  #  #  # ]:          0 :         if (fid >= flow_tbl->num_flows || !fid) {
     865                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid flow index\n");
     866                 :          0 :                 return -EINVAL;
     867                 :            :         }
     868                 :            : 
     869                 :            :         /* check if the flow is active or not */
     870         [ #  # ]:          0 :         if (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type, fid)) {
     871                 :          0 :                 BNXT_TF_DBG(ERR, "flow does not exist\n");
     872                 :          0 :                 return -EINVAL;
     873                 :            :         }
     874                 :            : 
     875         [ #  # ]:          0 :         if (!*nxt_idx) {
     876                 :          0 :                 fid_resource = &flow_tbl->flow_resources[fid];
     877                 :          0 :                 ulp_flow_db_res_info_to_params(fid_resource, params);
     878                 :          0 :                 ULP_FLOW_DB_RES_NXT_SET(*nxt_idx,
     879                 :            :                                         fid_resource->nxt_resource_idx);
     880                 :            :         } else {
     881                 :          0 :                 nxt_resource = &flow_tbl->flow_resources[*nxt_idx];
     882                 :          0 :                 ulp_flow_db_res_info_to_params(nxt_resource, params);
     883                 :          0 :                 *nxt_idx = 0;
     884                 :          0 :                 ULP_FLOW_DB_RES_NXT_SET(*nxt_idx,
     885                 :            :                                         nxt_resource->nxt_resource_idx);
     886                 :            :         }
     887                 :            : 
     888                 :            :         /* all good, return success */
     889                 :            :         return 0;
     890                 :            : }
     891                 :            : 
     892                 :            : /*
     893                 :            :  * Get the flow database entry iteratively
     894                 :            :  *
     895                 :            :  * flow_tbl [in] Ptr to flow table
     896                 :            :  * flow_type [in] - specify default or regular
     897                 :            :  * fid [in/out] The index to the flow entry
     898                 :            :  *
     899                 :            :  * returns 0 on success and negative on failure.
     900                 :            :  */
     901                 :            : static int32_t
     902                 :          0 : ulp_flow_db_next_entry_get(struct bnxt_ulp_flow_db *flow_db,
     903                 :            :                            enum bnxt_ulp_fdb_type flow_type,
     904                 :            :                            uint32_t *fid)
     905                 :            : {
     906                 :          0 :         uint32_t lfid = *fid;
     907                 :            :         uint32_t idx, s_idx, mod_fid;
     908                 :            :         uint64_t bs;
     909                 :            :         uint64_t *active_flows;
     910                 :            :         struct bnxt_ulp_flow_tbl *flowtbl = &flow_db->flow_tbl;
     911                 :            : 
     912         [ #  # ]:          0 :         if (flow_type == BNXT_ULP_FDB_TYPE_REGULAR) {
     913                 :          0 :                 active_flows = flowtbl->active_reg_flows;
     914         [ #  # ]:          0 :         } else if (flow_type == BNXT_ULP_FDB_TYPE_DEFAULT) {
     915                 :          0 :                 active_flows = flowtbl->active_dflt_flows;
     916                 :            :         } else {
     917                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid flow type %x\n", flow_type);
     918                 :          0 :                         return -EINVAL;
     919                 :            :         }
     920                 :            : 
     921                 :            :         do {
     922                 :            :                 /* increment the flow id to find the next valid flow id */
     923                 :          0 :                 lfid++;
     924         [ #  # ]:          0 :                 if (lfid >= flowtbl->num_flows)
     925                 :            :                         return -ENOENT;
     926                 :          0 :                 idx = lfid / ULP_INDEX_BITMAP_SIZE;
     927                 :          0 :                 mod_fid = lfid % ULP_INDEX_BITMAP_SIZE;
     928                 :            :                 s_idx = idx;
     929         [ #  # ]:          0 :                 while (!(bs = active_flows[idx])) {
     930                 :          0 :                         idx++;
     931         [ #  # ]:          0 :                         if ((idx * ULP_INDEX_BITMAP_SIZE) >= flowtbl->num_flows)
     932                 :            :                                 return -ENOENT;
     933                 :            :                 }
     934                 :            :                 /*
     935                 :            :                  * remove the previous bits in the bitset bs to find the
     936                 :            :                  * next non zero bit in the bitset. This needs to be done
     937                 :            :                  * only if the idx is same as he one you started.
     938                 :            :                  */
     939         [ #  # ]:          0 :                 if (s_idx == idx)
     940                 :          0 :                         bs &= (-1UL >> mod_fid);
     941                 :          0 :                 lfid = (idx * ULP_INDEX_BITMAP_SIZE) + __builtin_clzl(bs);
     942         [ #  # ]:          0 :                 if (*fid >= lfid) {
     943                 :          0 :                         BNXT_TF_DBG(ERR, "Flow Database is corrupt\n");
     944                 :          0 :                         return -ENOENT;
     945                 :            :                 }
     946         [ #  # ]:          0 :         } while (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type,
     947                 :            :                                                       lfid));
     948                 :            : 
     949                 :            :         /* all good, return success */
     950                 :          0 :         *fid = lfid;
     951                 :          0 :         return 0;
     952                 :            : }
     953                 :            : 
     954                 :            : /*
     955                 :            :  * Flush all flows in the flow database.
     956                 :            :  *
     957                 :            :  * ulp_ctxt [in] Ptr to ulp context
     958                 :            :  * flow_type [in] - specify default or regular
     959                 :            :  *
     960                 :            :  * returns 0 on success or negative number on failure
     961                 :            :  */
     962                 :            : int32_t
     963                 :          0 : ulp_flow_db_flush_flows(struct bnxt_ulp_context *ulp_ctx,
     964                 :            :                         enum bnxt_ulp_fdb_type flow_type)
     965                 :            : {
     966                 :          0 :         uint32_t fid = 0;
     967                 :            :         struct bnxt_ulp_flow_db *flow_db;
     968                 :            : 
     969         [ #  # ]:          0 :         if (!ulp_ctx) {
     970                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid Argument\n");
     971                 :          0 :                 return -EINVAL;
     972                 :            :         }
     973                 :            : 
     974                 :          0 :         flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctx);
     975         [ #  # ]:          0 :         if (!flow_db) {
     976                 :          0 :                 BNXT_TF_DBG(ERR, "Flow database not found\n");
     977                 :          0 :                 return -EINVAL;
     978                 :            :         }
     979         [ #  # ]:          0 :         if (bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx)) {
     980                 :          0 :                 BNXT_TF_DBG(ERR, "Flow db lock acquire failed\n");
     981                 :          0 :                 return -EINVAL;
     982                 :            :         }
     983                 :            : 
     984         [ #  # ]:          0 :         while (!ulp_flow_db_next_entry_get(flow_db, flow_type, &fid))
     985                 :          0 :                 ulp_mapper_resources_free(ulp_ctx, flow_type, fid);
     986                 :            : 
     987                 :          0 :         bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);
     988                 :            : 
     989                 :          0 :         return 0;
     990                 :            : }
     991                 :            : 
     992                 :            : /*
     993                 :            :  * Flush all flows in the flow database that belong to a device function.
     994                 :            :  *
     995                 :            :  * ulp_ctxt [in] Ptr to ulp context
     996                 :            :  * func_id [in] - The port function id
     997                 :            :  *
     998                 :            :  * returns 0 on success or negative number on failure
     999                 :            :  */
    1000                 :            : int32_t
    1001                 :          0 : ulp_flow_db_function_flow_flush(struct bnxt_ulp_context *ulp_ctx,
    1002                 :            :                                 uint16_t func_id)
    1003                 :            : {
    1004                 :          0 :         uint32_t flow_id = 0;
    1005                 :            :         struct bnxt_ulp_flow_db *flow_db;
    1006                 :            : 
    1007         [ #  # ]:          0 :         if (!ulp_ctx || !func_id) {
    1008                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid Argument\n");
    1009                 :          0 :                 return -EINVAL;
    1010                 :            :         }
    1011                 :            : 
    1012                 :          0 :         flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctx);
    1013         [ #  # ]:          0 :         if (!flow_db) {
    1014                 :          0 :                 BNXT_TF_DBG(ERR, "Flow database not found\n");
    1015                 :          0 :                 return -EINVAL;
    1016                 :            :         }
    1017         [ #  # ]:          0 :         if (bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx)) {
    1018                 :          0 :                 BNXT_TF_DBG(ERR, "Flow db lock acquire failed\n");
    1019                 :          0 :                 return -EINVAL;
    1020                 :            :         }
    1021                 :            : 
    1022         [ #  # ]:          0 :         while (!ulp_flow_db_next_entry_get(flow_db, BNXT_ULP_FDB_TYPE_REGULAR,
    1023                 :            :                                            &flow_id)) {
    1024         [ #  # ]:          0 :                 if (flow_db->func_id_tbl[flow_id] == func_id)
    1025                 :          0 :                         ulp_mapper_resources_free(ulp_ctx,
    1026                 :            :                                                   BNXT_ULP_FDB_TYPE_REGULAR,
    1027                 :            :                                                   flow_id);
    1028                 :            :         }
    1029                 :          0 :         bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);
    1030                 :          0 :         return 0;
    1031                 :            : }
    1032                 :            : 
    1033                 :            : /*
    1034                 :            :  * Flush all flows in the flow database that are associated with the session.
    1035                 :            :  *
    1036                 :            :  * ulp_ctxt [in] Ptr to ulp context
    1037                 :            :  *
    1038                 :            :  * returns 0 on success or negative number on failure
    1039                 :            :  */
    1040                 :            : int32_t
    1041                 :          0 : ulp_flow_db_session_flow_flush(struct bnxt_ulp_context *ulp_ctx)
    1042                 :            : {
    1043                 :            :         /*
    1044                 :            :          * TBD: Tf core implementation of FW session flush shall change this
    1045                 :            :          * implementation.
    1046                 :            :          */
    1047                 :          0 :         return ulp_flow_db_flush_flows(ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR);
    1048                 :            : }
    1049                 :            : 
    1050                 :            : /*
    1051                 :            :  * Check that flow id matches the function id or not
    1052                 :            :  *
    1053                 :            :  * ulp_ctxt [in] Ptr to ulp context
    1054                 :            :  * flow_db [in] Ptr to flow table
    1055                 :            :  * func_id [in] The func_id to be set, for reset pass zero.
    1056                 :            :  *
    1057                 :            :  * returns true on success or false on failure
    1058                 :            :  */
    1059                 :            : bool
    1060                 :          0 : ulp_flow_db_validate_flow_func(struct bnxt_ulp_context *ulp_ctx,
    1061                 :            :                                uint32_t flow_id,
    1062                 :            :                                uint32_t func_id)
    1063                 :            : {
    1064                 :            :         struct bnxt_ulp_flow_db *flow_db;
    1065                 :            : 
    1066                 :          0 :         flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctx);
    1067         [ #  # ]:          0 :         if (!flow_db) {
    1068                 :          0 :                 BNXT_TF_DBG(ERR, "Flow database not found\n");
    1069                 :          0 :                 return false;
    1070                 :            :         }
    1071                 :            : 
    1072                 :            :         /* set the function id in the function table */
    1073   [ #  #  #  # ]:          0 :         if (flow_id < flow_db->func_id_tbl_size && func_id &&
    1074         [ #  # ]:          0 :             flow_db->func_id_tbl[flow_id] == func_id)
    1075                 :          0 :                 return true;
    1076                 :            : 
    1077                 :            :         return false;
    1078                 :            : }
    1079                 :            : 
    1080                 :            : /*
    1081                 :            :  * Internal api to traverse the resource list within a flow
    1082                 :            :  * and match a resource based on resource func and resource
    1083                 :            :  * sub type. This api should be used only for resources that
    1084                 :            :  * are unique and do not have multiple instances of resource
    1085                 :            :  * func and sub type combination since it will return only
    1086                 :            :  * the first match.
    1087                 :            :  */
    1088                 :            : static int32_t
    1089                 :          0 : ulp_flow_db_resource_params_get(struct bnxt_ulp_context *ulp_ctx,
    1090                 :            :                                 enum bnxt_ulp_fdb_type flow_type,
    1091                 :            :                                 uint32_t flow_id,
    1092                 :            :                                 uint32_t resource_func,
    1093                 :            :                                 uint32_t res_subtype,
    1094                 :            :                                 struct ulp_flow_db_res_params *params)
    1095                 :            : {
    1096                 :            :         struct bnxt_ulp_flow_db *flow_db;
    1097                 :            :         struct bnxt_ulp_flow_tbl *flow_tbl;
    1098                 :            :         struct ulp_fdb_resource_info *fid_res;
    1099                 :            :         uint32_t res_id;
    1100                 :            : 
    1101                 :          0 :         flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctx);
    1102         [ #  # ]:          0 :         if (!flow_db) {
    1103                 :          0 :                 BNXT_TF_DBG(ERR, "Flow database not found\n");
    1104                 :          0 :                 return -EINVAL;
    1105                 :            :         }
    1106                 :            : 
    1107         [ #  # ]:          0 :         if (!params) {
    1108                 :          0 :                 BNXT_TF_DBG(ERR, "invalid argument\n");
    1109                 :          0 :                 return -EINVAL;
    1110                 :            :         }
    1111                 :            : 
    1112         [ #  # ]:          0 :         if (flow_type >= BNXT_ULP_FDB_TYPE_LAST) {
    1113                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid flow type\n");
    1114                 :          0 :                 return -EINVAL;
    1115                 :            :         }
    1116                 :            : 
    1117                 :            :         flow_tbl = &flow_db->flow_tbl;
    1118                 :            : 
    1119                 :            :         /* check for limits of fid */
    1120   [ #  #  #  # ]:          0 :         if (flow_id >= flow_tbl->num_flows || !flow_id) {
    1121                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid flow index\n");
    1122                 :          0 :                 return -EINVAL;
    1123                 :            :         }
    1124                 :            : 
    1125                 :            :         /* check if the flow is active or not */
    1126         [ #  # ]:          0 :         if (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type, flow_id)) {
    1127                 :          0 :                 BNXT_TF_DBG(ERR, "flow does not exist\n");
    1128                 :          0 :                 return -EINVAL;
    1129                 :            :         }
    1130                 :            :         /* Iterate the resource to get the resource handle */
    1131                 :            :         res_id =  flow_id;
    1132                 :            :         memset(params, 0, sizeof(struct ulp_flow_db_res_params));
    1133         [ #  # ]:          0 :         while (res_id) {
    1134         [ #  # ]:          0 :                 fid_res = &flow_tbl->flow_resources[res_id];
    1135         [ #  # ]:          0 :                 if (ulp_flow_db_resource_func_get(fid_res) == resource_func) {
    1136         [ #  # ]:          0 :                         if (resource_func & ULP_FLOW_DB_RES_FUNC_NEED_LOWER) {
    1137         [ #  # ]:          0 :                                 if (res_subtype == fid_res->resource_sub_type) {
    1138                 :          0 :                                         ulp_flow_db_res_info_to_params(fid_res,
    1139                 :            :                                                                        params);
    1140                 :          0 :                                         return 0;
    1141                 :            :                                 }
    1142                 :            : 
    1143         [ #  # ]:          0 :                         } else if (resource_func ==
    1144                 :            :                                    BNXT_ULP_RESOURCE_FUNC_EM_TABLE) {
    1145                 :          0 :                                 ulp_flow_db_res_info_to_params(fid_res,
    1146                 :            :                                                                params);
    1147                 :          0 :                                 return 0;
    1148                 :            :                         }
    1149                 :            :                 }
    1150                 :            :                 res_id = 0;
    1151                 :          0 :                 ULP_FLOW_DB_RES_NXT_SET(res_id, fid_res->nxt_resource_idx);
    1152                 :            :         }
    1153                 :            :         return -ENOENT;
    1154                 :            : }
    1155                 :            : 
    1156                 :            : /*
    1157                 :            :  * Api to get the cfa action pointer from a flow.
    1158                 :            :  *
    1159                 :            :  * ulp_ctxt [in] Ptr to ulp context
    1160                 :            :  * flow_id [in] flow id
    1161                 :            :  * cfa_action [out] The resource handle stored in the flow database
    1162                 :            :  *
    1163                 :            :  * returns 0 on success
    1164                 :            :  */
    1165                 :            : int32_t
    1166                 :          0 : ulp_default_flow_db_cfa_action_get(struct bnxt_ulp_context *ulp_ctx,
    1167                 :            :                                    uint32_t flow_id,
    1168                 :            :                                    uint16_t *cfa_action)
    1169                 :            : {
    1170                 :            :         uint8_t sub_typ = BNXT_ULP_RESOURCE_SUB_TYPE_INDEX_TABLE_VFR_CFA_ACTION;
    1171                 :            :         struct ulp_flow_db_res_params params;
    1172                 :            :         int32_t rc;
    1173                 :            : 
    1174                 :          0 :         rc = ulp_flow_db_resource_params_get(ulp_ctx,
    1175                 :            :                                              BNXT_ULP_FDB_TYPE_DEFAULT,
    1176                 :            :                                              flow_id,
    1177                 :            :                                              BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE,
    1178                 :            :                                              sub_typ, &params);
    1179         [ #  # ]:          0 :         if (rc) {
    1180                 :          0 :                 BNXT_TF_DBG(INFO, "CFA Action ptr not found for flow id %u\n",
    1181                 :            :                             flow_id);
    1182                 :          0 :                 return -ENOENT;
    1183                 :            :         }
    1184                 :          0 :         *cfa_action = params.resource_hndl;
    1185                 :          0 :         return 0;
    1186                 :            : }
    1187                 :            : 
    1188                 :            : /* internal validation function for parent flow tbl */
    1189                 :            : static struct ulp_fdb_parent_info *
    1190                 :          0 : ulp_flow_db_pc_db_entry_get(struct bnxt_ulp_context *ulp_ctxt,
    1191                 :            :                             uint32_t pc_idx)
    1192                 :            : {
    1193                 :            :         struct bnxt_ulp_flow_db *flow_db;
    1194                 :            : 
    1195                 :          0 :         flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
    1196         [ #  # ]:          0 :         if (!flow_db) {
    1197                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
    1198                 :          0 :                 return NULL;
    1199                 :            :         }
    1200                 :            : 
    1201                 :            :         /* check for max flows */
    1202         [ #  # ]:          0 :         if (pc_idx >= BNXT_ULP_MAX_TUN_CACHE_ENTRIES) {
    1203                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid tunnel index\n");
    1204                 :          0 :                 return NULL;
    1205                 :            :         }
    1206                 :            : 
    1207                 :            :         /* No support for parent child db then just exit */
    1208         [ #  # ]:          0 :         if (!flow_db->parent_child_db.entries_count) {
    1209                 :          0 :                 BNXT_TF_DBG(ERR, "parent child db not supported\n");
    1210                 :          0 :                 return NULL;
    1211                 :            :         }
    1212         [ #  # ]:          0 :         if (!flow_db->parent_child_db.parent_flow_tbl[pc_idx].valid) {
    1213                 :          0 :                 BNXT_TF_DBG(ERR, "Not a valid tunnel index\n");
    1214                 :          0 :                 return NULL;
    1215                 :            :         }
    1216                 :            : 
    1217                 :            :         return &flow_db->parent_child_db.parent_flow_tbl[pc_idx];
    1218                 :            : }
    1219                 :            : 
    1220                 :            : /* internal validation function for parent flow tbl */
    1221                 :            : static struct bnxt_ulp_flow_db *
    1222                 :          0 : ulp_flow_db_parent_arg_validation(struct bnxt_ulp_context *ulp_ctxt,
    1223                 :            :                                   uint32_t tun_idx)
    1224                 :            : {
    1225                 :            :         struct bnxt_ulp_flow_db *flow_db;
    1226                 :            : 
    1227                 :          0 :         flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
    1228         [ #  # ]:          0 :         if (!flow_db) {
    1229                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
    1230                 :          0 :                 return NULL;
    1231                 :            :         }
    1232                 :            : 
    1233                 :            :         /* check for max flows */
    1234         [ #  # ]:          0 :         if (tun_idx >= BNXT_ULP_MAX_TUN_CACHE_ENTRIES) {
    1235                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid tunnel index\n");
    1236                 :          0 :                 return NULL;
    1237                 :            :         }
    1238                 :            : 
    1239                 :            :         /* No support for parent child db then just exit */
    1240         [ #  # ]:          0 :         if (!flow_db->parent_child_db.entries_count) {
    1241                 :          0 :                 BNXT_TF_DBG(ERR, "parent child db not supported\n");
    1242                 :          0 :                 return NULL;
    1243                 :            :         }
    1244                 :            : 
    1245                 :            :         return flow_db;
    1246                 :            : }
    1247                 :            : 
    1248                 :            : /*
    1249                 :            :  * Allocate the entry in the parent-child database
    1250                 :            :  *
    1251                 :            :  * ulp_ctxt [in] Ptr to ulp_context
    1252                 :            :  * tun_idx [in] The tunnel index of the flow entry
    1253                 :            :  *
    1254                 :            :  * returns index on success and negative on failure.
    1255                 :            :  */
    1256                 :            : static int32_t
    1257                 :          0 : ulp_flow_db_pc_db_idx_alloc(struct bnxt_ulp_context *ulp_ctxt,
    1258                 :            :                             uint32_t tun_idx)
    1259                 :            : {
    1260                 :            :         struct bnxt_ulp_flow_db *flow_db;
    1261                 :            :         struct ulp_fdb_parent_child_db *p_pdb;
    1262                 :            :         uint32_t idx, free_idx = 0;
    1263                 :            : 
    1264                 :            :         /* validate the arguments */
    1265                 :          0 :         flow_db = ulp_flow_db_parent_arg_validation(ulp_ctxt, tun_idx);
    1266         [ #  # ]:          0 :         if (!flow_db) {
    1267                 :          0 :                 BNXT_TF_DBG(ERR, "parent child db validation failed\n");
    1268                 :          0 :                 return -EINVAL;
    1269                 :            :         }
    1270                 :            : 
    1271                 :            :         p_pdb = &flow_db->parent_child_db;
    1272         [ #  # ]:          0 :         for (idx = 0; idx < p_pdb->entries_count; idx++) {
    1273         [ #  # ]:          0 :                 if (p_pdb->parent_flow_tbl[idx].valid &&
    1274         [ #  # ]:          0 :                     p_pdb->parent_flow_tbl[idx].tun_idx == tun_idx) {
    1275                 :          0 :                         return idx;
    1276                 :            :                 }
    1277         [ #  # ]:          0 :                 if (!p_pdb->parent_flow_tbl[idx].valid && !free_idx)
    1278                 :          0 :                         free_idx = idx + 1;
    1279                 :            :         }
    1280                 :            :         /* no free slots */
    1281         [ #  # ]:          0 :         if (!free_idx) {
    1282                 :          0 :                 BNXT_TF_DBG(ERR, "parent child db is full\n");
    1283                 :          0 :                 return -ENOMEM;
    1284                 :            :         }
    1285                 :            : 
    1286                 :          0 :         free_idx -= 1;
    1287                 :            :         /* set the Fid in the parent child */
    1288                 :          0 :         p_pdb->parent_flow_tbl[free_idx].tun_idx = tun_idx;
    1289                 :          0 :         p_pdb->parent_flow_tbl[free_idx].valid = 1;
    1290                 :          0 :         return free_idx;
    1291                 :            : }
    1292                 :            : 
    1293                 :            : /*
    1294                 :            :  * Free the entry in the parent-child database
    1295                 :            :  *
    1296                 :            :  * pc_entry [in] Ptr to parent child db entry
    1297                 :            :  *
    1298                 :            :  * returns none.
    1299                 :            :  */
    1300                 :            : static void
    1301                 :          0 : ulp_flow_db_pc_db_entry_free(struct bnxt_ulp_context *ulp_ctxt,
    1302                 :            :                              struct ulp_fdb_parent_info *pc_entry)
    1303                 :            : {
    1304                 :            :         struct bnxt_tun_cache_entry *tun_tbl;
    1305                 :            :         struct bnxt_ulp_flow_db *flow_db;
    1306                 :            :         uint64_t *tmp_bitset;
    1307                 :            : 
    1308                 :            :         /* free the tunnel entry */
    1309                 :          0 :         tun_tbl = bnxt_ulp_cntxt_ptr2_tun_tbl_get(ulp_ctxt);
    1310         [ #  # ]:          0 :         if (tun_tbl)
    1311                 :          0 :                 ulp_tunnel_offload_entry_clear(tun_tbl, pc_entry->tun_idx);
    1312                 :            : 
    1313                 :            :         /* free the child bitset*/
    1314                 :          0 :         flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
    1315         [ #  # ]:          0 :         if (flow_db)
    1316                 :          0 :                 memset(pc_entry->child_fid_bitset, 0,
    1317                 :          0 :                        flow_db->parent_child_db.child_bitset_size);
    1318                 :            : 
    1319                 :            :         /* free the contents */
    1320                 :          0 :         tmp_bitset = pc_entry->child_fid_bitset;
    1321                 :            :         memset(pc_entry, 0, sizeof(struct ulp_fdb_parent_info));
    1322                 :          0 :         pc_entry->child_fid_bitset = tmp_bitset;
    1323                 :          0 : }
    1324                 :            : 
    1325                 :            : /*
    1326                 :            :  * Set or reset the parent flow in the parent-child database
    1327                 :            :  *
    1328                 :            :  * ulp_ctxt [in] Ptr to ulp_context
    1329                 :            :  * pc_idx [in] The index to parent child db
    1330                 :            :  * parent_fid [in] The flow id of the parent flow entry
    1331                 :            :  * set_flag [in] Use 1 for setting child, 0 to reset
    1332                 :            :  *
    1333                 :            :  * returns zero on success and negative on failure.
    1334                 :            :  */
    1335                 :            : int32_t
    1336                 :          0 : ulp_flow_db_pc_db_parent_flow_set(struct bnxt_ulp_context *ulp_ctxt,
    1337                 :            :                                   uint32_t pc_idx,
    1338                 :            :                                   uint32_t parent_fid,
    1339                 :            :                                   uint32_t set_flag)
    1340                 :            : {
    1341                 :            :         struct ulp_fdb_parent_info *pc_entry;
    1342                 :            :         struct bnxt_ulp_flow_db *flow_db;
    1343                 :            : 
    1344                 :          0 :         flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
    1345         [ #  # ]:          0 :         if (!flow_db) {
    1346                 :          0 :                 BNXT_TF_DBG(ERR, "parent child db validation failed\n");
    1347                 :          0 :                 return -EINVAL;
    1348                 :            :         }
    1349                 :            : 
    1350                 :            :         /* check for fid validity */
    1351   [ #  #  #  # ]:          0 :         if (parent_fid >= flow_db->flow_tbl.num_flows || !parent_fid) {
    1352                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid parent flow index %x\n", parent_fid);
    1353                 :          0 :                 return -EINVAL;
    1354                 :            :         }
    1355                 :            : 
    1356                 :            :         /* validate the arguments and parent child entry */
    1357                 :          0 :         pc_entry = ulp_flow_db_pc_db_entry_get(ulp_ctxt, pc_idx);
    1358         [ #  # ]:          0 :         if (!pc_entry) {
    1359                 :          0 :                 BNXT_TF_DBG(ERR, "failed to get the parent child entry\n");
    1360                 :          0 :                 return -EINVAL;
    1361                 :            :         }
    1362                 :            : 
    1363         [ #  # ]:          0 :         if (set_flag) {
    1364                 :          0 :                 pc_entry->parent_fid = parent_fid;
    1365                 :            :         } else {
    1366         [ #  # ]:          0 :                 if (pc_entry->parent_fid != parent_fid)
    1367                 :          0 :                         BNXT_TF_DBG(ERR, "Panic: invalid parent id\n");
    1368                 :          0 :                 pc_entry->parent_fid = 0;
    1369                 :            : 
    1370                 :            :                 /* Free the parent child db entry if no user present */
    1371         [ #  # ]:          0 :                 if (!pc_entry->f2_cnt)
    1372                 :          0 :                         ulp_flow_db_pc_db_entry_free(ulp_ctxt, pc_entry);
    1373                 :            :         }
    1374                 :            :         return 0;
    1375                 :            : }
    1376                 :            : 
    1377                 :            : /*
    1378                 :            :  * Set or reset the child flow in the parent-child database
    1379                 :            :  *
    1380                 :            :  * ulp_ctxt [in] Ptr to ulp_context
    1381                 :            :  * pc_idx [in] The index to parent child db
    1382                 :            :  * child_fid [in] The flow id of the child flow entry
    1383                 :            :  * set_flag [in] Use 1 for setting child, 0 to reset
    1384                 :            :  *
    1385                 :            :  * returns zero on success and negative on failure.
    1386                 :            :  */
    1387                 :            : int32_t
    1388                 :          0 : ulp_flow_db_pc_db_child_flow_set(struct bnxt_ulp_context *ulp_ctxt,
    1389                 :            :                                  uint32_t pc_idx,
    1390                 :            :                                  uint32_t child_fid,
    1391                 :            :                                  uint32_t set_flag)
    1392                 :            : {
    1393                 :            :         struct ulp_fdb_parent_info *pc_entry;
    1394                 :            :         struct bnxt_ulp_flow_db *flow_db;
    1395                 :            :         uint32_t a_idx;
    1396                 :            :         uint64_t *t;
    1397                 :            : 
    1398                 :          0 :         flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
    1399         [ #  # ]:          0 :         if (!flow_db) {
    1400                 :          0 :                 BNXT_TF_DBG(ERR, "parent child db validation failed\n");
    1401                 :          0 :                 return -EINVAL;
    1402                 :            :         }
    1403                 :            : 
    1404                 :            :         /* check for fid validity */
    1405   [ #  #  #  # ]:          0 :         if (child_fid >= flow_db->flow_tbl.num_flows || !child_fid) {
    1406                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid child flow index %x\n", child_fid);
    1407                 :          0 :                 return -EINVAL;
    1408                 :            :         }
    1409                 :            : 
    1410                 :            :         /* validate the arguments and parent child entry */
    1411                 :          0 :         pc_entry = ulp_flow_db_pc_db_entry_get(ulp_ctxt, pc_idx);
    1412         [ #  # ]:          0 :         if (!pc_entry) {
    1413                 :          0 :                 BNXT_TF_DBG(ERR, "failed to get the parent child entry\n");
    1414                 :          0 :                 return -EINVAL;
    1415                 :            :         }
    1416                 :            : 
    1417                 :          0 :         a_idx = child_fid / ULP_INDEX_BITMAP_SIZE;
    1418                 :          0 :         t = pc_entry->child_fid_bitset;
    1419         [ #  # ]:          0 :         if (set_flag) {
    1420                 :          0 :                 ULP_INDEX_BITMAP_SET(t[a_idx], child_fid);
    1421                 :          0 :                 pc_entry->f2_cnt++;
    1422                 :            :         } else {
    1423                 :          0 :                 ULP_INDEX_BITMAP_RESET(t[a_idx], child_fid);
    1424         [ #  # ]:          0 :                 if (pc_entry->f2_cnt)
    1425                 :          0 :                         pc_entry->f2_cnt--;
    1426   [ #  #  #  # ]:          0 :                 if (!pc_entry->f2_cnt && !pc_entry->parent_fid)
    1427                 :          0 :                         ulp_flow_db_pc_db_entry_free(ulp_ctxt, pc_entry);
    1428                 :            :         }
    1429                 :            :         return 0;
    1430                 :            : }
    1431                 :            : 
    1432                 :            : /*
    1433                 :            :  * Get the next child flow in the parent-child database
    1434                 :            :  *
    1435                 :            :  * ulp_ctxt [in] Ptr to ulp_context
    1436                 :            :  * parent_fid [in] The flow id of the parent flow entry
    1437                 :            :  * child_fid [in/out] The flow id of the child flow entry
    1438                 :            :  *
    1439                 :            :  * returns zero on success and negative on failure.
    1440                 :            :  * Pass child_fid as zero for first entry.
    1441                 :            :  */
    1442                 :            : int32_t
    1443                 :          0 : ulp_flow_db_parent_child_flow_next_entry_get(struct bnxt_ulp_flow_db *flow_db,
    1444                 :            :                                              uint32_t parent_idx,
    1445                 :            :                                              uint32_t *child_fid)
    1446                 :            : {
    1447                 :            :         struct ulp_fdb_parent_child_db *p_pdb;
    1448                 :            :         uint32_t idx, s_idx, mod_fid;
    1449                 :          0 :         uint32_t next_fid = *child_fid;
    1450                 :            :         uint64_t *child_bitset;
    1451                 :            :         uint64_t bs;
    1452                 :            : 
    1453                 :            :         /* check for fid validity */
    1454                 :            :         p_pdb = &flow_db->parent_child_db;
    1455         [ #  # ]:          0 :         if (parent_idx >= p_pdb->entries_count ||
    1456         [ #  # ]:          0 :             !p_pdb->parent_flow_tbl[parent_idx].parent_fid) {
    1457                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid parent flow index %x\n", parent_idx);
    1458                 :          0 :                 return -EINVAL;
    1459                 :            :         }
    1460                 :            : 
    1461                 :          0 :         child_bitset = p_pdb->parent_flow_tbl[parent_idx].child_fid_bitset;
    1462                 :            :         do {
    1463                 :            :                 /* increment the flow id to find the next valid flow id */
    1464                 :          0 :                 next_fid++;
    1465         [ #  # ]:          0 :                 if (next_fid >= flow_db->flow_tbl.num_flows)
    1466                 :            :                         return -ENOENT;
    1467                 :          0 :                 idx = next_fid / ULP_INDEX_BITMAP_SIZE;
    1468                 :          0 :                 mod_fid = next_fid % ULP_INDEX_BITMAP_SIZE;
    1469                 :            :                 s_idx = idx;
    1470         [ #  # ]:          0 :                 while (!(bs = child_bitset[idx])) {
    1471                 :          0 :                         idx++;
    1472                 :          0 :                         if ((idx * ULP_INDEX_BITMAP_SIZE) >=
    1473         [ #  # ]:          0 :                             flow_db->flow_tbl.num_flows)
    1474                 :            :                                 return -ENOENT;
    1475                 :            :                 }
    1476                 :            :                 /*
    1477                 :            :                  * remove the previous bits in the bitset bs to find the
    1478                 :            :                  * next non zero bit in the bitset. This needs to be done
    1479                 :            :                  * only if the idx is same as he one you started.
    1480                 :            :                  */
    1481         [ #  # ]:          0 :                 if (s_idx == idx)
    1482                 :          0 :                         bs &= (-1UL >> mod_fid);
    1483                 :          0 :                 next_fid = (idx * ULP_INDEX_BITMAP_SIZE) + __builtin_clzl(bs);
    1484         [ #  # ]:          0 :                 if (*child_fid >= next_fid) {
    1485                 :          0 :                         BNXT_TF_DBG(ERR, "Parent Child Database is corrupt\n");
    1486                 :          0 :                         return -ENOENT;
    1487                 :            :                 }
    1488                 :          0 :                 idx = next_fid / ULP_INDEX_BITMAP_SIZE;
    1489         [ #  # ]:          0 :         } while (!ULP_INDEX_BITMAP_GET(child_bitset[idx], next_fid));
    1490                 :          0 :         *child_fid = next_fid;
    1491                 :          0 :         return 0;
    1492                 :            : }
    1493                 :            : 
    1494                 :            : /*
    1495                 :            :  * Set the counter accumulation in the parent flow
    1496                 :            :  *
    1497                 :            :  * ulp_ctxt [in] Ptr to ulp_context
    1498                 :            :  * pc_idx [in] The parent child index of the parent flow entry
    1499                 :            :  *
    1500                 :            :  * returns index on success and negative on failure.
    1501                 :            :  */
    1502                 :            : static int32_t
    1503                 :          0 : ulp_flow_db_parent_flow_count_accum_set(struct bnxt_ulp_context *ulp_ctxt,
    1504                 :            :                                         uint32_t pc_idx)
    1505                 :            : {
    1506                 :            :         struct bnxt_ulp_flow_db *flow_db;
    1507                 :            :         struct ulp_fdb_parent_child_db *p_pdb;
    1508                 :            : 
    1509                 :          0 :         flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
    1510         [ #  # ]:          0 :         if (!flow_db) {
    1511                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
    1512                 :          0 :                 return -EINVAL;
    1513                 :            :         }
    1514                 :            : 
    1515                 :            :         /* check for parent idx validity */
    1516                 :            :         p_pdb = &flow_db->parent_child_db;
    1517         [ #  # ]:          0 :         if (pc_idx >= p_pdb->entries_count ||
    1518         [ #  # ]:          0 :             !p_pdb->parent_flow_tbl[pc_idx].parent_fid) {
    1519                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid parent child index %x\n", pc_idx);
    1520                 :          0 :                 return -EINVAL;
    1521                 :            :         }
    1522                 :            : 
    1523                 :          0 :         p_pdb->parent_flow_tbl[pc_idx].counter_acc = 1;
    1524                 :          0 :         return 0;
    1525                 :            : }
    1526                 :            : 
    1527                 :            : /*
    1528                 :            :  * Orphan the child flow entry
    1529                 :            :  * This is called only for child flows that have
    1530                 :            :  * BNXT_ULP_RESOURCE_FUNC_CHILD_FLOW resource
    1531                 :            :  *
    1532                 :            :  * ulp_ctxt [in] Ptr to ulp_context
    1533                 :            :  * flow_type [in] Specify it is regular or default flow
    1534                 :            :  * fid [in] The index to the flow entry
    1535                 :            :  *
    1536                 :            :  * Returns 0 on success and negative on failure.
    1537                 :            :  */
    1538                 :            : int32_t
    1539                 :          0 : ulp_flow_db_child_flow_reset(struct bnxt_ulp_context *ulp_ctxt,
    1540                 :            :                              enum bnxt_ulp_fdb_type flow_type,
    1541                 :            :                              uint32_t fid)
    1542                 :            : {
    1543                 :            :         struct bnxt_ulp_flow_db *flow_db;
    1544                 :            :         struct bnxt_ulp_flow_tbl *flow_tbl;
    1545                 :            :         struct ulp_fdb_resource_info *fid_res;
    1546                 :            :         uint32_t res_id = 0;
    1547                 :            : 
    1548                 :          0 :         flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
    1549         [ #  # ]:          0 :         if (!flow_db) {
    1550                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
    1551                 :          0 :                 return -EINVAL;
    1552                 :            :         }
    1553                 :            : 
    1554         [ #  # ]:          0 :         if (flow_type >= BNXT_ULP_FDB_TYPE_LAST) {
    1555                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid flow type\n");
    1556                 :          0 :                 return -EINVAL;
    1557                 :            :         }
    1558                 :            : 
    1559                 :            :         flow_tbl = &flow_db->flow_tbl;
    1560                 :            :         /* check for max flows */
    1561   [ #  #  #  # ]:          0 :         if (fid >= flow_tbl->num_flows || !fid) {
    1562                 :          0 :                 BNXT_TF_DBG(ERR, "Invalid flow index %x\n", fid);
    1563                 :          0 :                 return -EINVAL;
    1564                 :            :         }
    1565                 :            : 
    1566                 :            :         /* check if the flow is active or not */
    1567         [ #  # ]:          0 :         if (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type, fid)) {
    1568                 :          0 :                 BNXT_TF_DBG(ERR, "flow does not exist\n");
    1569                 :          0 :                 return -EINVAL;
    1570                 :            :         }
    1571                 :            : 
    1572                 :            :         /* Iterate the resource to get the resource handle */
    1573                 :            :         res_id =  fid;
    1574         [ #  # ]:          0 :         while (res_id) {
    1575         [ #  # ]:          0 :                 fid_res = &flow_tbl->flow_resources[res_id];
    1576         [ #  # ]:          0 :                 if (ulp_flow_db_resource_func_get(fid_res) ==
    1577                 :            :                     BNXT_ULP_RESOURCE_FUNC_CHILD_FLOW) {
    1578                 :            :                         /* invalidate the resource details */
    1579                 :          0 :                         fid_res->resource_hndl = 0;
    1580                 :          0 :                         return 0;
    1581                 :            :                 }
    1582                 :            :                 res_id = 0;
    1583                 :          0 :                 ULP_FLOW_DB_RES_NXT_SET(res_id, fid_res->nxt_resource_idx);
    1584                 :            :         }
    1585                 :            :         /* failed */
    1586                 :            :         return -1;
    1587                 :            : }
    1588                 :            : 
    1589                 :            : /*
    1590                 :            :  * Create parent flow in the parent flow tbl
    1591                 :            :  *
    1592                 :            :  * parms [in] Ptr to mapper params
    1593                 :            :  *
    1594                 :            :  * Returns 0 on success and negative on failure.
    1595                 :            :  */
    1596                 :            : int32_t
    1597                 :          0 : ulp_flow_db_parent_flow_create(struct bnxt_ulp_mapper_parms *parms)
    1598                 :            : {
    1599                 :            :         struct ulp_flow_db_res_params fid_parms;
    1600                 :            :         uint32_t sub_typ = BNXT_ULP_RESOURCE_SUB_TYPE_INDEX_TABLE_INT_COUNT;
    1601                 :            :         struct ulp_flow_db_res_params res_params;
    1602                 :            :         int32_t pc_idx;
    1603                 :            : 
    1604                 :            :         /* create or get the parent child database */
    1605                 :          0 :         pc_idx = ulp_flow_db_pc_db_idx_alloc(parms->ulp_ctx, parms->tun_idx);
    1606         [ #  # ]:          0 :         if (pc_idx < 0) {
    1607                 :          0 :                 BNXT_TF_DBG(ERR, "Error in getting parent child db %x\n",
    1608                 :            :                             parms->tun_idx);
    1609                 :          0 :                 return -EINVAL;
    1610                 :            :         }
    1611                 :            : 
    1612                 :            :         /* Update the parent fid */
    1613         [ #  # ]:          0 :         if (ulp_flow_db_pc_db_parent_flow_set(parms->ulp_ctx, pc_idx,
    1614                 :            :                                               parms->fid, 1)) {
    1615                 :          0 :                 BNXT_TF_DBG(ERR, "Error in setting parent fid %x\n",
    1616                 :            :                             parms->tun_idx);
    1617                 :          0 :                 return -EINVAL;
    1618                 :            :         }
    1619                 :            : 
    1620                 :            :         /* Add the parent details in the resource list of the flow */
    1621                 :            :         memset(&fid_parms, 0, sizeof(fid_parms));
    1622                 :          0 :         fid_parms.resource_func = BNXT_ULP_RESOURCE_FUNC_PARENT_FLOW;
    1623                 :          0 :         fid_parms.resource_hndl = pc_idx;
    1624                 :            :         fid_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO;
    1625         [ #  # ]:          0 :         if (ulp_flow_db_resource_add(parms->ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR,
    1626                 :            :                                      parms->fid, &fid_parms)) {
    1627                 :          0 :                 BNXT_TF_DBG(ERR, "Error in adding flow res for fid %x\n",
    1628                 :            :                             parms->fid);
    1629                 :          0 :                 return -1;
    1630                 :            :         }
    1631                 :            : 
    1632                 :            :         /* check of the flow has internal counter accumulation enabled */
    1633         [ #  # ]:          0 :         if (!ulp_flow_db_resource_params_get(parms->ulp_ctx,
    1634                 :            :                                              BNXT_ULP_FDB_TYPE_REGULAR,
    1635                 :            :                                              parms->fid,
    1636                 :            :                                              BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE,
    1637                 :            :                                              sub_typ,
    1638                 :            :                                              &res_params)) {
    1639                 :            :                 /* Enable the counter accumulation in parent entry */
    1640         [ #  # ]:          0 :                 if (ulp_flow_db_parent_flow_count_accum_set(parms->ulp_ctx,
    1641                 :            :                                                             pc_idx)) {
    1642                 :          0 :                         BNXT_TF_DBG(ERR, "Error in setting counter acc %x\n",
    1643                 :            :                                     parms->fid);
    1644                 :          0 :                         return -1;
    1645                 :            :                 }
    1646                 :            :         }
    1647                 :            : 
    1648                 :            :         return 0;
    1649                 :            : }
    1650                 :            : 
    1651                 :            : /*
    1652                 :            :  * Create child flow in the parent flow tbl
    1653                 :            :  *
    1654                 :            :  * parms [in] Ptr to mapper params
    1655                 :            :  *
    1656                 :            :  * Returns 0 on success and negative on failure.
    1657                 :            :  */
    1658                 :            : int32_t
    1659                 :          0 : ulp_flow_db_child_flow_create(struct bnxt_ulp_mapper_parms *parms)
    1660                 :            : {
    1661                 :            :         struct ulp_flow_db_res_params fid_parms;
    1662                 :            :         uint32_t sub_type = BNXT_ULP_RESOURCE_SUB_TYPE_INDEX_TABLE_INT_COUNT;
    1663                 :            :         enum bnxt_ulp_resource_func res_fun;
    1664                 :            :         struct ulp_flow_db_res_params res_p;
    1665                 :            :         int32_t rc, pc_idx;
    1666                 :            : 
    1667                 :            :         /* create or get the parent child database */
    1668                 :          0 :         pc_idx = ulp_flow_db_pc_db_idx_alloc(parms->ulp_ctx, parms->tun_idx);
    1669         [ #  # ]:          0 :         if (pc_idx < 0) {
    1670                 :          0 :                 BNXT_TF_DBG(ERR, "Error in getting parent child db %x\n",
    1671                 :            :                             parms->tun_idx);
    1672                 :          0 :                 return -1;
    1673                 :            :         }
    1674                 :            : 
    1675                 :            :         /* create the parent flow entry in parent flow table */
    1676                 :          0 :         rc = ulp_flow_db_pc_db_child_flow_set(parms->ulp_ctx, pc_idx,
    1677                 :            :                                               parms->fid, 1);
    1678         [ #  # ]:          0 :         if (rc) {
    1679                 :          0 :                 BNXT_TF_DBG(ERR, "Error in setting child fid %x\n", parms->fid);
    1680                 :          0 :                 return rc;
    1681                 :            :         }
    1682                 :            : 
    1683                 :            :         /* Add the parent details in the resource list of the flow */
    1684                 :            :         memset(&fid_parms, 0, sizeof(fid_parms));
    1685                 :          0 :         fid_parms.resource_func = BNXT_ULP_RESOURCE_FUNC_CHILD_FLOW;
    1686                 :          0 :         fid_parms.resource_hndl = pc_idx;
    1687                 :            :         fid_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO;
    1688                 :          0 :         rc  = ulp_flow_db_resource_add(parms->ulp_ctx,
    1689                 :            :                                        BNXT_ULP_FDB_TYPE_REGULAR,
    1690                 :            :                                        parms->fid, &fid_parms);
    1691         [ #  # ]:          0 :         if (rc) {
    1692                 :          0 :                 BNXT_TF_DBG(ERR, "Error in adding flow res for fid %x\n",
    1693                 :            :                             parms->fid);
    1694                 :          0 :                 return rc;
    1695                 :            :         }
    1696                 :            : 
    1697                 :            :         /* check if internal count action included for this flow.*/
    1698                 :            :         res_fun = BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE;
    1699                 :          0 :         rc = ulp_flow_db_resource_params_get(parms->ulp_ctx,
    1700                 :            :                                              BNXT_ULP_FDB_TYPE_REGULAR,
    1701                 :            :                                              parms->fid,
    1702                 :            :                                              res_fun,
    1703                 :            :                                              sub_type,
    1704                 :            :                                              &res_p);
    1705         [ #  # ]:          0 :         if (!rc) {
    1706                 :            :                 /* update the counter manager to include parent fid */
    1707         [ #  # ]:          0 :                 if (ulp_fc_mgr_cntr_parent_flow_set(parms->ulp_ctx,
    1708                 :            :                                                     res_p.direction,
    1709                 :          0 :                                                     res_p.resource_hndl,
    1710                 :            :                                                     pc_idx)) {
    1711                 :          0 :                         BNXT_TF_DBG(ERR, "Error in setting child %x\n",
    1712                 :            :                                     parms->fid);
    1713                 :          0 :                         return -1;
    1714                 :            :                 }
    1715                 :            :         }
    1716                 :            : 
    1717                 :            :         /* return success */
    1718                 :            :         return 0;
    1719                 :            : }
    1720                 :            : 
    1721                 :            : /*
    1722                 :            :  * Update the parent counters
    1723                 :            :  *
    1724                 :            :  * ulp_ctxt [in] Ptr to ulp_context
    1725                 :            :  * pc_idx [in] The parent flow entry idx
    1726                 :            :  * packet_count [in] - packet count
    1727                 :            :  * byte_count [in] - byte count
    1728                 :            :  *
    1729                 :            :  * returns 0 on success
    1730                 :            :  */
    1731                 :            : int32_t
    1732                 :          0 : ulp_flow_db_parent_flow_count_update(struct bnxt_ulp_context *ulp_ctxt,
    1733                 :            :                                      uint32_t pc_idx,
    1734                 :            :                                      uint64_t packet_count,
    1735                 :            :                                      uint64_t byte_count)
    1736                 :            : {
    1737                 :            :         struct ulp_fdb_parent_info *pc_entry;
    1738                 :            : 
    1739                 :            :         /* validate the arguments and get parent child entry */
    1740                 :          0 :         pc_entry = ulp_flow_db_pc_db_entry_get(ulp_ctxt, pc_idx);
    1741         [ #  # ]:          0 :         if (!pc_entry) {
    1742                 :          0 :                 BNXT_TF_DBG(ERR, "failed to get the parent child entry\n");
    1743                 :          0 :                 return -EINVAL;
    1744                 :            :         }
    1745                 :            : 
    1746         [ #  # ]:          0 :         if (pc_entry->counter_acc) {
    1747                 :          0 :                 pc_entry->pkt_count += packet_count;
    1748                 :          0 :                 pc_entry->byte_count += byte_count;
    1749                 :            :         }
    1750                 :            :         return 0;
    1751                 :            : }
    1752                 :            : 
    1753                 :            : /*
    1754                 :            :  * Get the parent accumulation counters
    1755                 :            :  *
    1756                 :            :  * ulp_ctxt [in] Ptr to ulp_context
    1757                 :            :  * pc_idx [in] The parent flow entry idx
    1758                 :            :  * packet_count [out] - packet count
    1759                 :            :  * byte_count [out] - byte count
    1760                 :            :  *
    1761                 :            :  * returns 0 on success
    1762                 :            :  */
    1763                 :            : int32_t
    1764                 :          0 : ulp_flow_db_parent_flow_count_get(struct bnxt_ulp_context *ulp_ctxt,
    1765                 :            :                                   uint32_t pc_idx, uint64_t *packet_count,
    1766                 :            :                                   uint64_t *byte_count, uint8_t count_reset)
    1767                 :            : {
    1768                 :            :         struct ulp_fdb_parent_info *pc_entry;
    1769                 :            : 
    1770                 :            :         /* validate the arguments and get parent child entry */
    1771                 :          0 :         pc_entry = ulp_flow_db_pc_db_entry_get(ulp_ctxt, pc_idx);
    1772         [ #  # ]:          0 :         if (!pc_entry) {
    1773                 :          0 :                 BNXT_TF_DBG(ERR, "failed to get the parent child entry\n");
    1774                 :          0 :                 return -EINVAL;
    1775                 :            :         }
    1776                 :            : 
    1777         [ #  # ]:          0 :         if (pc_entry->counter_acc) {
    1778                 :          0 :                 *packet_count = pc_entry->pkt_count;
    1779                 :          0 :                 *byte_count = pc_entry->byte_count;
    1780         [ #  # ]:          0 :                 if (count_reset) {
    1781                 :          0 :                         pc_entry->pkt_count = 0;
    1782                 :          0 :                         pc_entry->byte_count = 0;
    1783                 :            :                 }
    1784                 :            :         }
    1785                 :            :         return 0;
    1786                 :            : }
    1787                 :            : 
    1788                 :            : /*
    1789                 :            :  * reset the parent accumulation counters
    1790                 :            :  *
    1791                 :            :  * ulp_ctxt [in] Ptr to ulp_context
    1792                 :            :  *
    1793                 :            :  * returns none
    1794                 :            :  */
    1795                 :            : void
    1796                 :          0 : ulp_flow_db_parent_flow_count_reset(struct bnxt_ulp_context *ulp_ctxt)
    1797                 :            : {
    1798                 :            :         struct bnxt_ulp_flow_db *flow_db;
    1799                 :            :         struct ulp_fdb_parent_child_db *p_pdb;
    1800                 :            :         uint32_t idx;
    1801                 :            : 
    1802                 :            :         /* validate the arguments */
    1803                 :          0 :         flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
    1804         [ #  # ]:          0 :         if (!flow_db) {
    1805                 :          0 :                 BNXT_TF_DBG(ERR, "parent child db validation failed\n");
    1806                 :          0 :                 return;
    1807                 :            :         }
    1808                 :            : 
    1809                 :            :         p_pdb = &flow_db->parent_child_db;
    1810         [ #  # ]:          0 :         for (idx = 0; idx < p_pdb->entries_count; idx++) {
    1811         [ #  # ]:          0 :                 if (p_pdb->parent_flow_tbl[idx].valid &&
    1812         [ #  # ]:          0 :                     p_pdb->parent_flow_tbl[idx].counter_acc) {
    1813                 :          0 :                         p_pdb->parent_flow_tbl[idx].pkt_count = 0;
    1814                 :          0 :                         p_pdb->parent_flow_tbl[idx].byte_count = 0;
    1815                 :            :                 }
    1816                 :            :         }
    1817                 :            : }
    1818                 :            : 
    1819                 :            : /*
    1820                 :            :  * Set the shared bit for the flow db entry
    1821                 :            :  *
    1822                 :            :  * res [in] Ptr to fdb entry
    1823                 :            :  * shared [in] shared flag
    1824                 :            :  *
    1825                 :            :  * returns none
    1826                 :            :  */
    1827                 :          0 : void ulp_flow_db_shared_session_set(struct ulp_flow_db_res_params *res,
    1828                 :            :                                     enum bnxt_ulp_session_type s_type)
    1829                 :            : {
    1830   [ #  #  #  # ]:          0 :         if (res && (s_type & BNXT_ULP_SESSION_TYPE_SHARED))
    1831                 :          0 :                 res->fdb_flags |= ULP_FDB_FLAG_SHARED_SESSION;
    1832   [ #  #  #  # ]:          0 :         else if (res && (s_type & BNXT_ULP_SESSION_TYPE_SHARED_WC))
    1833                 :          0 :                 res->fdb_flags |= ULP_FDB_FLAG_SHARED_WC_SESSION;
    1834                 :          0 : }
    1835                 :            : 
    1836                 :            : /*
    1837                 :            :  * Get the shared bit for the flow db entry
    1838                 :            :  *
    1839                 :            :  * res [out] shared session type
    1840                 :            :  */
    1841                 :            : enum bnxt_ulp_session_type
    1842                 :          0 : ulp_flow_db_shared_session_get(struct ulp_flow_db_res_params *res)
    1843                 :            : {
    1844                 :            :         enum bnxt_ulp_session_type stype = BNXT_ULP_SESSION_TYPE_DEFAULT;
    1845                 :            : 
    1846   [ #  #  #  # ]:          0 :         if (res && (res->fdb_flags & ULP_FDB_FLAG_SHARED_SESSION))
    1847                 :            :                 stype = BNXT_ULP_SESSION_TYPE_SHARED;
    1848   [ #  #  #  # ]:          0 :         else if (res && (res->fdb_flags & ULP_FDB_FLAG_SHARED_WC_SESSION))
    1849                 :            :                 stype = BNXT_ULP_SESSION_TYPE_SHARED_WC;
    1850                 :            : 
    1851                 :          0 :         return stype;
    1852                 :            : }

Generated by: LCOV version 1.14