LCOV - code coverage report
Current view: top level - drivers/net/mlx5/hws - mlx5dr_context.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 158 0.0 %
Date: 2025-04-03 19:37:06 Functions: 0 13 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 87 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright (c) 2022 NVIDIA Corporation & Affiliates
       3                 :            :  */
       4                 :            : 
       5                 :            : #include "mlx5dr_internal.h"
       6                 :            : 
       7                 :          0 : bool mlx5dr_context_cap_dynamic_reparse(struct mlx5dr_context *ctx)
       8                 :            : {
       9                 :          0 :         return IS_BIT_SET(ctx->caps->rtc_reparse_mode, MLX5_IFC_RTC_REPARSE_BY_STC);
      10                 :            : }
      11                 :            : 
      12                 :          0 : uint8_t mlx5dr_context_get_reparse_mode(struct mlx5dr_context *ctx)
      13                 :            : {
      14                 :            :         /* Prefer to use dynamic reparse, reparse only specific actions */
      15         [ #  # ]:          0 :         if (mlx5dr_context_cap_dynamic_reparse(ctx))
      16                 :          0 :                 return MLX5_IFC_RTC_REPARSE_NEVER;
      17                 :            : 
      18                 :            :         /* Otherwise use less efficient static */
      19                 :            :         return MLX5_IFC_RTC_REPARSE_ALWAYS;
      20                 :            : }
      21                 :            : 
      22                 :          0 : void mlx5dr_context_set_pool_tbl_attr(struct mlx5dr_pool_attr *attr,
      23                 :            :                                       enum mlx5dr_table_type table_type)
      24                 :            : {
      25                 :          0 :         attr->table_type = table_type;
      26                 :            : 
      27      [ #  #  # ]:          0 :         switch (table_type) {
      28                 :          0 :         case MLX5DR_TABLE_TYPE_FDB_TX:
      29                 :          0 :                 attr->opt_type = MLX5DR_POOL_OPTIMIZE_ORIG;
      30                 :          0 :                 break;
      31                 :          0 :         case MLX5DR_TABLE_TYPE_FDB_RX:
      32                 :          0 :                 attr->opt_type = MLX5DR_POOL_OPTIMIZE_MIRROR;
      33                 :          0 :                 break;
      34                 :          0 :         default:
      35                 :          0 :                 attr->opt_type = MLX5DR_POOL_OPTIMIZE_NONE;
      36                 :          0 :                 break;
      37                 :            :         }
      38                 :          0 : }
      39                 :            : 
      40                 :          0 : static int mlx5dr_context_pools_init(struct mlx5dr_context *ctx,
      41                 :            :                                      struct mlx5dr_context_attr *attr)
      42                 :            : {
      43                 :          0 :         struct mlx5dr_pool_attr pool_attr = {0};
      44                 :            :         uint8_t max_log_sz;
      45                 :            :         int i;
      46                 :            : 
      47         [ #  # ]:          0 :         if (mlx5dr_pat_init_pattern_cache(&ctx->pattern_cache))
      48                 :          0 :                 return rte_errno;
      49                 :            : 
      50         [ #  # ]:          0 :         if (mlx5dr_definer_init_cache(&ctx->definer_cache))
      51                 :          0 :                 goto uninit_pat_cache;
      52                 :            : 
      53                 :            :         /* Create an STC pool per FT type */
      54                 :          0 :         pool_attr.pool_type = MLX5DR_POOL_TYPE_STC;
      55                 :          0 :         pool_attr.flags = MLX5DR_POOL_FLAGS_FOR_STC_POOL;
      56         [ #  # ]:          0 :         if (!attr->initial_log_stc_memory)
      57                 :          0 :                 attr->initial_log_stc_memory = MLX5DR_POOL_STC_LOG_SZ;
      58                 :          0 :         max_log_sz = RTE_MIN(attr->initial_log_stc_memory, ctx->caps->stc_alloc_log_max);
      59                 :          0 :         pool_attr.alloc_log_sz = RTE_MAX(max_log_sz, ctx->caps->stc_alloc_log_gran);
      60                 :            : 
      61         [ #  # ]:          0 :         for (i = 0; i < MLX5DR_TABLE_TYPE_MAX; i++) {
      62                 :          0 :                 mlx5dr_context_set_pool_tbl_attr(&pool_attr,
      63                 :            :                                                  (enum mlx5dr_table_type)i);
      64                 :          0 :                 ctx->stc_pool[i] = mlx5dr_pool_create(ctx, &pool_attr);
      65         [ #  # ]:          0 :                 if (!ctx->stc_pool[i]) {
      66                 :          0 :                         DR_LOG(ERR, "Failed to allocate STC pool [%d]", i);
      67                 :          0 :                         goto free_stc_pools;
      68                 :            :                 }
      69                 :            :         }
      70                 :            : 
      71                 :            :         return 0;
      72                 :            : 
      73                 :            : free_stc_pools:
      74         [ #  # ]:          0 :         for (i = 0; i < MLX5DR_TABLE_TYPE_MAX; i++)
      75         [ #  # ]:          0 :                 if (ctx->stc_pool[i])
      76                 :          0 :                         mlx5dr_pool_destroy(ctx->stc_pool[i]);
      77                 :            : 
      78                 :          0 :         mlx5dr_definer_uninit_cache(ctx->definer_cache);
      79                 :            : 
      80                 :          0 : uninit_pat_cache:
      81                 :          0 :         mlx5dr_pat_uninit_pattern_cache(ctx->pattern_cache);
      82                 :          0 :         return rte_errno;
      83                 :            : }
      84                 :            : 
      85                 :          0 : static void mlx5dr_context_pools_uninit(struct mlx5dr_context *ctx)
      86                 :            : {
      87                 :            :         int i;
      88                 :            : 
      89         [ #  # ]:          0 :         for (i = 0; i < MLX5DR_TABLE_TYPE_MAX; i++) {
      90         [ #  # ]:          0 :                 if (ctx->stc_pool[i])
      91                 :          0 :                         mlx5dr_pool_destroy(ctx->stc_pool[i]);
      92                 :            :         }
      93                 :            : 
      94                 :          0 :         mlx5dr_definer_uninit_cache(ctx->definer_cache);
      95                 :          0 :         mlx5dr_pat_uninit_pattern_cache(ctx->pattern_cache);
      96                 :          0 : }
      97                 :            : 
      98                 :          0 : static int mlx5dr_context_init_pd(struct mlx5dr_context *ctx,
      99                 :            :                                   struct ibv_pd *pd)
     100                 :            : {
     101                 :          0 :         struct mlx5dv_pd mlx5_pd = {0};
     102                 :            :         struct mlx5dv_obj obj;
     103                 :            :         int ret;
     104                 :            : 
     105         [ #  # ]:          0 :         if (pd) {
     106                 :          0 :                 ctx->pd = pd;
     107                 :            :         } else {
     108                 :          0 :                 ctx->pd = mlx5_glue->alloc_pd(ctx->ibv_ctx);
     109         [ #  # ]:          0 :                 if (!ctx->pd) {
     110                 :          0 :                         DR_LOG(ERR, "Failed to allocate PD");
     111                 :          0 :                         rte_errno = errno;
     112                 :          0 :                         return rte_errno;
     113                 :            :                 }
     114                 :          0 :                 ctx->flags |= MLX5DR_CONTEXT_FLAG_PRIVATE_PD;
     115                 :            :         }
     116                 :            : 
     117                 :          0 :         obj.pd.in = ctx->pd;
     118                 :          0 :         obj.pd.out = &mlx5_pd;
     119                 :            : 
     120                 :          0 :         ret = mlx5_glue->dv_init_obj(&obj, MLX5DV_OBJ_PD);
     121         [ #  # ]:          0 :         if (ret)
     122                 :          0 :                 goto free_private_pd;
     123                 :            : 
     124                 :          0 :         ctx->pd_num = mlx5_pd.pdn;
     125                 :            : 
     126                 :          0 :         return 0;
     127                 :            : 
     128                 :            : free_private_pd:
     129         [ #  # ]:          0 :         if (ctx->flags & MLX5DR_CONTEXT_FLAG_PRIVATE_PD)
     130                 :          0 :                 mlx5_glue->dealloc_pd(ctx->pd);
     131                 :            : 
     132                 :            :         return ret;
     133                 :            : }
     134                 :            : 
     135                 :            : static int mlx5dr_context_uninit_pd(struct mlx5dr_context *ctx)
     136                 :            : {
     137         [ #  # ]:          0 :         if (ctx->flags & MLX5DR_CONTEXT_FLAG_PRIVATE_PD)
     138                 :          0 :                 return mlx5_glue->dealloc_pd(ctx->pd);
     139                 :            : 
     140                 :            :         return 0;
     141                 :            : }
     142                 :            : 
     143                 :          0 : bool mlx5dr_context_cap_stc(struct mlx5dr_context *ctx, uint32_t bit)
     144                 :            : {
     145                 :            :         uint32_t test_bit = bit;
     146                 :            : 
     147         [ #  # ]:          0 :         if (bit >= MLX5_IFC_STC_ACTION_TYPE_BIT_64_INDEX)
     148                 :          0 :                 test_bit -= MLX5_IFC_STC_ACTION_TYPE_BIT_64_INDEX;
     149                 :            : 
     150         [ #  # ]:          0 :         switch (bit) {
     151                 :          0 :         case MLX5_IFC_STC_ACTION_TYPE_JUMP_FLOW_TABLE_FDB_RX_BIT_INDEX:
     152                 :          0 :                 return ctx->caps->stc_action_type_127_64 & (0x1ull << test_bit);
     153                 :            :         default:
     154                 :            :                 break;
     155                 :            :         }
     156                 :            : 
     157                 :            :         return false;
     158                 :            : }
     159                 :            : 
     160                 :          0 : static void mlx5dr_context_check_hws_supp(struct mlx5dr_context *ctx)
     161                 :            : {
     162                 :          0 :         struct mlx5dr_cmd_query_caps *caps = ctx->caps;
     163                 :            : 
     164                 :            :         /* HWS not supported on device / FW */
     165         [ #  # ]:          0 :         if (!caps->wqe_based_update) {
     166                 :          0 :                 DR_LOG(INFO, "Required HWS WQE based insertion cap not supported");
     167                 :          0 :                 return;
     168                 :            :         }
     169                 :            : 
     170                 :            :         /* Current solution requires all rules to set reparse bit */
     171         [ #  # ]:          0 :         if ((!caps->nic_ft.reparse ||
     172   [ #  #  #  # ]:          0 :              (!caps->fdb_ft.reparse && caps->eswitch_manager)) ||
     173         [ #  # ]:          0 :             !IS_BIT_SET(caps->rtc_reparse_mode, MLX5_IFC_RTC_REPARSE_ALWAYS)) {
     174                 :          0 :                 DR_LOG(INFO, "Required HWS reparse cap not supported");
     175                 :          0 :                 return;
     176                 :            :         }
     177                 :            : 
     178                 :            :         /* FW/HW must support 8DW STE */
     179         [ #  # ]:          0 :         if (!IS_BIT_SET(caps->ste_format, MLX5_IFC_RTC_STE_FORMAT_8DW)) {
     180                 :          0 :                 DR_LOG(INFO, "Required HWS STE format not supported");
     181                 :          0 :                 return;
     182                 :            :         }
     183                 :            : 
     184                 :            :         /* Adding rules by hash and by offset are requirements */
     185         [ #  # ]:          0 :         if (!IS_BIT_SET(caps->rtc_index_mode, MLX5_IFC_RTC_STE_UPDATE_MODE_BY_HASH) ||
     186                 :            :             !IS_BIT_SET(caps->rtc_index_mode, MLX5_IFC_RTC_STE_UPDATE_MODE_BY_OFFSET)) {
     187                 :          0 :                 DR_LOG(INFO, "Required HWS RTC update mode not supported");
     188                 :          0 :                 return;
     189                 :            :         }
     190                 :            : 
     191                 :            :         /* Support for SELECT definer ID is required */
     192         [ #  # ]:          0 :         if (!IS_BIT_SET(caps->definer_format_sup, MLX5_IFC_DEFINER_FORMAT_ID_SELECT)) {
     193                 :          0 :                 DR_LOG(INFO, "Required HWS Dynamic definer not supported");
     194                 :          0 :                 return;
     195                 :            :         }
     196                 :            : 
     197                 :          0 :         ctx->flags |= MLX5DR_CONTEXT_FLAG_HWS_SUPPORT;
     198                 :            : }
     199                 :            : 
     200                 :          0 : static int mlx5dr_context_init_hws(struct mlx5dr_context *ctx,
     201                 :            :                                    struct mlx5dr_context_attr *attr)
     202                 :            : {
     203                 :            :         int ret;
     204                 :            : 
     205                 :          0 :         mlx5dr_context_check_hws_supp(ctx);
     206                 :            : 
     207         [ #  # ]:          0 :         if (!(ctx->flags & MLX5DR_CONTEXT_FLAG_HWS_SUPPORT))
     208                 :            :                 return 0;
     209                 :            : 
     210                 :          0 :         ret = mlx5dr_context_init_pd(ctx, attr->pd);
     211         [ #  # ]:          0 :         if (ret)
     212                 :            :                 return ret;
     213                 :            : 
     214                 :          0 :         ret = mlx5dr_context_pools_init(ctx, attr);
     215         [ #  # ]:          0 :         if (ret)
     216                 :          0 :                 goto uninit_pd;
     217                 :            : 
     218         [ #  # ]:          0 :         if (attr->bwc)
     219                 :          0 :                 ctx->flags |= MLX5DR_CONTEXT_FLAG_BWC_SUPPORT;
     220                 :            : 
     221                 :          0 :         ret = mlx5dr_send_queues_open(ctx, attr->queues, attr->queue_size);
     222         [ #  # ]:          0 :         if (ret)
     223                 :          0 :                 goto pools_uninit;
     224                 :            : 
     225                 :            :         return 0;
     226                 :            : 
     227                 :            : pools_uninit:
     228                 :          0 :         mlx5dr_context_pools_uninit(ctx);
     229         [ #  # ]:          0 : uninit_pd:
     230                 :            :         mlx5dr_context_uninit_pd(ctx);
     231                 :            :         return ret;
     232                 :            : }
     233                 :            : 
     234                 :          0 : static void mlx5dr_context_uninit_hws(struct mlx5dr_context *ctx)
     235                 :            : {
     236         [ #  # ]:          0 :         if (!(ctx->flags & MLX5DR_CONTEXT_FLAG_HWS_SUPPORT))
     237                 :            :                 return;
     238                 :            : 
     239                 :          0 :         mlx5dr_send_queues_close(ctx);
     240                 :          0 :         mlx5dr_context_pools_uninit(ctx);
     241                 :            :         mlx5dr_context_uninit_pd(ctx);
     242                 :            : }
     243                 :            : 
     244                 :          0 : static int mlx5dr_context_init_shared_ctx(struct mlx5dr_context *ctx,
     245                 :            :                                           struct ibv_context *ibv_ctx,
     246                 :            :                                           struct mlx5dr_context_attr *attr)
     247                 :            : {
     248                 :          0 :         struct mlx5dr_cmd_query_caps shared_caps = {0};
     249                 :            :         int ret;
     250                 :            : 
     251         [ #  # ]:          0 :         if (!attr->shared_ibv_ctx) {
     252                 :          0 :                 ctx->ibv_ctx = ibv_ctx;
     253                 :            :         } else {
     254                 :          0 :                 ctx->ibv_ctx = attr->shared_ibv_ctx;
     255                 :          0 :                 ctx->local_ibv_ctx = ibv_ctx;
     256                 :          0 :                 ret = mlx5dr_cmd_query_caps(attr->shared_ibv_ctx, &shared_caps);
     257   [ #  #  #  # ]:          0 :                 if (ret || !shared_caps.cross_vhca_resources) {
     258                 :          0 :                         DR_LOG(INFO, "No cross_vhca_resources cap for shared ibv");
     259                 :          0 :                         rte_errno = ENOTSUP;
     260                 :          0 :                         return rte_errno;
     261                 :            :                 }
     262                 :          0 :                 ctx->caps->shared_vhca_id = shared_caps.vhca_id;
     263                 :            :         }
     264                 :            : 
     265   [ #  #  #  # ]:          0 :         if (ctx->local_ibv_ctx && !ctx->caps->cross_vhca_resources) {
     266                 :          0 :                 DR_LOG(INFO, "No cross_vhca_resources cap for local ibv");
     267                 :          0 :                 rte_errno = ENOTSUP;
     268                 :          0 :                 return rte_errno;
     269                 :            :         }
     270                 :            : 
     271                 :            :         return 0;
     272                 :            : }
     273                 :            : 
     274                 :          0 : struct mlx5dr_context *mlx5dr_context_open(struct ibv_context *ibv_ctx,
     275                 :            :                                            struct mlx5dr_context_attr *attr)
     276                 :            : {
     277                 :            :         struct mlx5dr_context *ctx;
     278                 :            :         int ret;
     279                 :            : 
     280                 :            :         ctx = simple_calloc(1, sizeof(*ctx));
     281         [ #  # ]:          0 :         if (!ctx) {
     282                 :          0 :                 rte_errno = ENOMEM;
     283                 :          0 :                 return NULL;
     284                 :            :         }
     285                 :            : 
     286                 :          0 :         pthread_spin_init(&ctx->ctrl_lock, PTHREAD_PROCESS_PRIVATE);
     287                 :            : 
     288                 :          0 :         ctx->caps = simple_calloc(1, sizeof(*ctx->caps));
     289         [ #  # ]:          0 :         if (!ctx->caps)
     290                 :          0 :                 goto free_ctx;
     291                 :            : 
     292                 :          0 :         ret = mlx5dr_cmd_query_caps(ibv_ctx, ctx->caps);
     293         [ #  # ]:          0 :         if (ret)
     294                 :          0 :                 goto free_caps;
     295                 :            : 
     296         [ #  # ]:          0 :         if (mlx5dr_context_init_shared_ctx(ctx, ibv_ctx, attr))
     297                 :          0 :                 goto free_caps;
     298                 :            : 
     299                 :          0 :         ret = mlx5dr_context_init_hws(ctx, attr);
     300         [ #  # ]:          0 :         if (ret)
     301                 :          0 :                 goto free_caps;
     302                 :            : 
     303                 :            :         return ctx;
     304                 :            : 
     305                 :          0 : free_caps:
     306                 :          0 :         simple_free(ctx->caps);
     307                 :          0 : free_ctx:
     308                 :          0 :         pthread_spin_destroy(&ctx->ctrl_lock);
     309                 :            :         simple_free(ctx);
     310                 :          0 :         return NULL;
     311                 :            : }
     312                 :            : 
     313                 :          0 : int mlx5dr_context_close(struct mlx5dr_context *ctx)
     314                 :            : {
     315                 :          0 :         mlx5dr_context_uninit_hws(ctx);
     316                 :          0 :         simple_free(ctx->caps);
     317                 :          0 :         pthread_spin_destroy(&ctx->ctrl_lock);
     318                 :            :         simple_free(ctx);
     319                 :          0 :         return 0;
     320                 :            : }

Generated by: LCOV version 1.14