LCOV - code coverage report
Current view: top level - drivers/net/mlx5/hws - mlx5dr_cmd.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 641 0.0 %
Date: 2025-04-03 19:37:06 Functions: 0 25 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 581 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                 :            : static uint32_t mlx5dr_cmd_get_syndrome(uint32_t *out)
       8                 :            : {
       9                 :            :         /* Assumption: syndrome is always the second u32 */
      10                 :          0 :         return be32toh(out[1]);
      11                 :            : }
      12                 :            : 
      13                 :          0 : int mlx5dr_cmd_destroy_obj(struct mlx5dr_devx_obj *devx_obj)
      14                 :            : {
      15                 :            :         int ret;
      16                 :            : 
      17                 :          0 :         ret = mlx5_glue->devx_obj_destroy(devx_obj->obj);
      18                 :            :         simple_free(devx_obj);
      19                 :            : 
      20                 :          0 :         return ret;
      21                 :            : }
      22                 :            : 
      23                 :            : struct mlx5dr_devx_obj *
      24                 :          0 : mlx5dr_cmd_flow_table_create(struct ibv_context *ctx,
      25                 :            :                              struct mlx5dr_cmd_ft_create_attr *ft_attr)
      26                 :            : {
      27                 :          0 :         uint32_t out[MLX5_ST_SZ_DW(create_flow_table_out)] = {0};
      28                 :          0 :         uint32_t in[MLX5_ST_SZ_DW(create_flow_table_in)] = {0};
      29                 :            :         struct mlx5dr_devx_obj *devx_obj;
      30                 :            :         void *ft_ctx;
      31                 :            : 
      32                 :            :         devx_obj = simple_malloc(sizeof(*devx_obj));
      33         [ #  # ]:          0 :         if (!devx_obj) {
      34                 :          0 :                 DR_LOG(ERR, "Failed to allocate memory for flow table object");
      35                 :          0 :                 rte_errno = ENOMEM;
      36                 :          0 :                 return NULL;
      37                 :            :         }
      38                 :            : 
      39         [ #  # ]:          0 :         MLX5_SET(create_flow_table_in, in, opcode, MLX5_CMD_OP_CREATE_FLOW_TABLE);
      40         [ #  # ]:          0 :         MLX5_SET(create_flow_table_in, in, table_type, ft_attr->type);
      41                 :            : 
      42                 :            :         ft_ctx = MLX5_ADDR_OF(create_flow_table_in, in, flow_table_context);
      43         [ #  # ]:          0 :         MLX5_SET(flow_table_context, ft_ctx, level, ft_attr->level);
      44         [ #  # ]:          0 :         MLX5_SET(flow_table_context, ft_ctx, rtc_valid, ft_attr->rtc_valid);
      45         [ #  # ]:          0 :         MLX5_SET(flow_table_context, ft_ctx, reformat_en, ft_attr->reformat_en);
      46                 :            : 
      47                 :          0 :         devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
      48         [ #  # ]:          0 :         if (!devx_obj->obj) {
      49                 :          0 :                 DR_LOG(ERR, "Failed to create FT (syndrome: %#x)",
      50                 :            :                        mlx5dr_cmd_get_syndrome(out));
      51                 :            :                 simple_free(devx_obj);
      52                 :          0 :                 rte_errno = errno;
      53                 :          0 :                 return NULL;
      54                 :            :         }
      55                 :            : 
      56         [ #  # ]:          0 :         devx_obj->id = MLX5_GET(create_flow_table_out, out, table_id);
      57                 :            : 
      58                 :          0 :         return devx_obj;
      59                 :            : }
      60                 :            : 
      61                 :            : int
      62                 :          0 : mlx5dr_cmd_flow_table_modify(struct mlx5dr_devx_obj *devx_obj,
      63                 :            :                              struct mlx5dr_cmd_ft_modify_attr *ft_attr)
      64                 :            : {
      65                 :          0 :         uint32_t out[MLX5_ST_SZ_DW(modify_flow_table_out)] = {0};
      66                 :          0 :         uint32_t in[MLX5_ST_SZ_DW(modify_flow_table_in)] = {0};
      67                 :            :         void *ft_ctx;
      68                 :            :         int ret;
      69                 :            : 
      70                 :          0 :         MLX5_SET(modify_flow_table_in, in, opcode, MLX5_CMD_OP_MODIFY_FLOW_TABLE);
      71                 :          0 :         MLX5_SET(modify_flow_table_in, in, table_type, ft_attr->type);
      72                 :          0 :         MLX5_SET(modify_flow_table_in, in, modify_field_select, ft_attr->modify_fs);
      73                 :          0 :         MLX5_SET(modify_flow_table_in, in, table_id, devx_obj->id);
      74                 :            : 
      75                 :            :         ft_ctx = MLX5_ADDR_OF(modify_flow_table_in, in, flow_table_context);
      76                 :            : 
      77                 :          0 :         MLX5_SET(flow_table_context, ft_ctx, table_miss_action, ft_attr->table_miss_action);
      78                 :          0 :         MLX5_SET(flow_table_context, ft_ctx, table_miss_id, ft_attr->table_miss_id);
      79                 :          0 :         MLX5_SET(flow_table_context, ft_ctx, rtc_id_0, ft_attr->rtc_id_0);
      80                 :          0 :         MLX5_SET(flow_table_context, ft_ctx, rtc_id_1, ft_attr->rtc_id_1);
      81                 :            : 
      82                 :          0 :         ret = mlx5_glue->devx_obj_modify(devx_obj->obj, in, sizeof(in), out, sizeof(out));
      83         [ #  # ]:          0 :         if (ret) {
      84                 :          0 :                 DR_LOG(ERR, "Failed to modify FT (syndrome: %#x)",
      85                 :            :                        mlx5dr_cmd_get_syndrome(out));
      86                 :          0 :                 rte_errno = errno;
      87                 :            :         }
      88                 :            : 
      89                 :          0 :         return ret;
      90                 :            : }
      91                 :            : 
      92                 :            : int
      93                 :          0 : mlx5dr_cmd_flow_table_query(struct mlx5dr_devx_obj *devx_obj,
      94                 :            :                             struct mlx5dr_cmd_ft_query_attr *ft_attr,
      95                 :            :                             uint64_t *icm_addr_0, uint64_t *icm_addr_1)
      96                 :            : {
      97                 :          0 :         uint32_t out[MLX5_ST_SZ_DW(query_flow_table_out)] = {0};
      98                 :          0 :         uint32_t in[MLX5_ST_SZ_DW(query_flow_table_in)] = {0};
      99                 :            :         void *ft_ctx;
     100                 :            :         int ret;
     101                 :            : 
     102                 :          0 :         MLX5_SET(query_flow_table_in, in, opcode, MLX5_CMD_OP_QUERY_FLOW_TABLE);
     103                 :          0 :         MLX5_SET(query_flow_table_in, in, table_type, ft_attr->type);
     104                 :          0 :         MLX5_SET(query_flow_table_in, in, table_id, devx_obj->id);
     105                 :            : 
     106                 :          0 :         ret = mlx5_glue->devx_obj_query(devx_obj->obj, in, sizeof(in), out, sizeof(out));
     107         [ #  # ]:          0 :         if (ret) {
     108                 :          0 :                 DR_LOG(ERR, "Failed to query FT (syndrome: %#x)",
     109                 :            :                        mlx5dr_cmd_get_syndrome(out));
     110                 :          0 :                 rte_errno = errno;
     111                 :          0 :                 return ret;
     112                 :            :         }
     113                 :            : 
     114                 :            :         ft_ctx = MLX5_ADDR_OF(query_flow_table_out, out, flow_table_context);
     115         [ #  # ]:          0 :         *icm_addr_0 = MLX5_GET64(flow_table_context, ft_ctx, sw_owner_icm_root_0);
     116         [ #  # ]:          0 :         *icm_addr_1 = MLX5_GET64(flow_table_context, ft_ctx, sw_owner_icm_root_1);
     117                 :            : 
     118                 :          0 :         return ret;
     119                 :            : }
     120                 :            : 
     121                 :            : static struct mlx5dr_devx_obj *
     122                 :          0 : mlx5dr_cmd_flow_group_create(struct ibv_context *ctx,
     123                 :            :                              struct mlx5dr_cmd_fg_attr *fg_attr)
     124                 :            : {
     125                 :          0 :         uint32_t out[MLX5_ST_SZ_DW(create_flow_group_out)] = {0};
     126                 :          0 :         uint32_t in[MLX5_ST_SZ_DW(create_flow_group_in)] = {0};
     127                 :            :         struct mlx5dr_devx_obj *devx_obj;
     128                 :            : 
     129                 :            :         devx_obj = simple_malloc(sizeof(*devx_obj));
     130         [ #  # ]:          0 :         if (!devx_obj) {
     131                 :          0 :                 DR_LOG(ERR, "Failed to allocate memory for flow group object");
     132                 :          0 :                 rte_errno = ENOMEM;
     133                 :          0 :                 return NULL;
     134                 :            :         }
     135                 :            : 
     136         [ #  # ]:          0 :         MLX5_SET(create_flow_group_in, in, opcode, MLX5_CMD_OP_CREATE_FLOW_GROUP);
     137         [ #  # ]:          0 :         MLX5_SET(create_flow_group_in, in, table_type, fg_attr->table_type);
     138         [ #  # ]:          0 :         MLX5_SET(create_flow_group_in, in, table_id, fg_attr->table_id);
     139                 :            : 
     140                 :          0 :         devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
     141         [ #  # ]:          0 :         if (!devx_obj->obj) {
     142                 :          0 :                 DR_LOG(ERR, "Failed to create Flow group(syndrome: %#x)",
     143                 :            :                        mlx5dr_cmd_get_syndrome(out));
     144                 :            :                 simple_free(devx_obj);
     145                 :          0 :                 rte_errno = errno;
     146                 :          0 :                 return NULL;
     147                 :            :         }
     148                 :            : 
     149         [ #  # ]:          0 :         devx_obj->id = MLX5_GET(create_flow_group_out, out, group_id);
     150                 :            : 
     151                 :          0 :         return devx_obj;
     152                 :            : }
     153                 :            : 
     154                 :            : struct mlx5dr_devx_obj *
     155                 :          0 : mlx5dr_cmd_set_fte(struct ibv_context *ctx,
     156                 :            :                    uint32_t table_type,
     157                 :            :                    uint32_t table_id,
     158                 :            :                    uint32_t group_id,
     159                 :            :                    struct mlx5dr_cmd_set_fte_attr *fte_attr)
     160                 :            : {
     161                 :          0 :         uint32_t out[MLX5_ST_SZ_DW(set_fte_out)] = {0};
     162                 :            :         struct mlx5dr_devx_obj *devx_obj;
     163                 :            :         uint32_t dest_entry_sz;
     164                 :            :         uint32_t total_dest_sz;
     165                 :            :         void *in_flow_context;
     166                 :            :         uint32_t action_flags;
     167                 :            :         uint8_t *in_dests;
     168                 :            :         uint32_t inlen;
     169                 :            :         uint32_t *in;
     170                 :            :         uint32_t i;
     171                 :            : 
     172         [ #  # ]:          0 :         dest_entry_sz = fte_attr->extended_dest ?
     173                 :            :                         MLX5_ST_SZ_BYTES(extended_dest_format) :
     174                 :            :                         MLX5_ST_SZ_BYTES(dest_format);
     175                 :          0 :         total_dest_sz = dest_entry_sz * fte_attr->dests_num;
     176                 :          0 :         inlen = align((MLX5_ST_SZ_BYTES(set_fte_in) + total_dest_sz), DW_SIZE);
     177                 :            :         in = simple_calloc(1, inlen);
     178         [ #  # ]:          0 :         if (!in) {
     179                 :          0 :                 rte_errno = ENOMEM;
     180                 :          0 :                 return NULL;
     181                 :            :         }
     182                 :            : 
     183                 :            :         devx_obj = simple_malloc(sizeof(*devx_obj));
     184         [ #  # ]:          0 :         if (!devx_obj) {
     185                 :          0 :                 DR_LOG(ERR, "Failed to allocate memory for fte object");
     186                 :          0 :                 rte_errno = ENOMEM;
     187                 :          0 :                 goto free_in;
     188                 :            :         }
     189                 :            : 
     190         [ #  # ]:          0 :         MLX5_SET(set_fte_in, in, opcode, MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY);
     191         [ #  # ]:          0 :         MLX5_SET(set_fte_in, in, table_type, table_type);
     192         [ #  # ]:          0 :         MLX5_SET(set_fte_in, in, table_id, table_id);
     193                 :            : 
     194                 :            :         in_flow_context = MLX5_ADDR_OF(set_fte_in, in, flow_context);
     195         [ #  # ]:          0 :         MLX5_SET(flow_context, in_flow_context, group_id, group_id);
     196         [ #  # ]:          0 :         MLX5_SET(flow_context, in_flow_context, flow_source, fte_attr->flow_source);
     197         [ #  # ]:          0 :         MLX5_SET(flow_context, in_flow_context, extended_destination, fte_attr->extended_dest);
     198         [ #  # ]:          0 :         MLX5_SET(set_fte_in, in, ignore_flow_level, fte_attr->ignore_flow_level);
     199                 :            : 
     200                 :          0 :         action_flags = fte_attr->action_flags;
     201         [ #  # ]:          0 :         MLX5_SET(flow_context, in_flow_context, action, action_flags);
     202                 :            : 
     203         [ #  # ]:          0 :         if (action_flags & MLX5_FLOW_CONTEXT_ACTION_REFORMAT)
     204         [ #  # ]:          0 :                 MLX5_SET(flow_context, in_flow_context,
     205                 :            :                          packet_reformat_id, fte_attr->packet_reformat_id);
     206                 :            : 
     207         [ #  # ]:          0 :         if (action_flags & (MLX5_FLOW_CONTEXT_ACTION_DECRYPT | MLX5_FLOW_CONTEXT_ACTION_ENCRYPT)) {
     208         [ #  # ]:          0 :                 MLX5_SET(flow_context, in_flow_context,
     209                 :            :                          encrypt_decrypt_type, fte_attr->encrypt_decrypt_type);
     210         [ #  # ]:          0 :                 MLX5_SET(flow_context, in_flow_context,
     211                 :            :                          encrypt_decrypt_obj_id, fte_attr->encrypt_decrypt_obj_id);
     212                 :            :         }
     213                 :            : 
     214         [ #  # ]:          0 :         if (action_flags & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) {
     215                 :          0 :                 in_dests = (uint8_t *)MLX5_ADDR_OF(flow_context, in_flow_context, destination);
     216                 :            : 
     217         [ #  # ]:          0 :                 for (i = 0; i < fte_attr->dests_num; i++) {
     218                 :          0 :                         struct mlx5dr_cmd_set_fte_dest *dest = &fte_attr->dests[i];
     219                 :            : 
     220   [ #  #  #  # ]:          0 :                         switch (dest->destination_type) {
     221                 :          0 :                         case MLX5_FLOW_DESTINATION_TYPE_VPORT:
     222         [ #  # ]:          0 :                                 if (dest->ext_flags & MLX5DR_CMD_EXT_DEST_ESW_OWNER_VHCA_ID) {
     223         [ #  # ]:          0 :                                         MLX5_SET(dest_format, in_dests,
     224                 :            :                                                  destination_eswitch_owner_vhca_id_valid, 1);
     225         [ #  # ]:          0 :                                         MLX5_SET(dest_format, in_dests,
     226                 :            :                                                  destination_eswitch_owner_vhca_id,
     227                 :            :                                                  dest->esw_owner_vhca_id);
     228                 :            :                                 }
     229                 :            :                                 /* Fall through */
     230                 :            :                         case MLX5_FLOW_DESTINATION_TYPE_TIR:
     231                 :            :                         case MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE:
     232         [ #  # ]:          0 :                                 MLX5_SET(dest_format, in_dests, destination_type,
     233                 :            :                                          dest->destination_type);
     234         [ #  # ]:          0 :                                 MLX5_SET(dest_format, in_dests, destination_id,
     235                 :            :                                          dest->destination_id);
     236         [ #  # ]:          0 :                                 if (dest->ext_flags & MLX5DR_CMD_EXT_DEST_REFORMAT) {
     237         [ #  # ]:          0 :                                         MLX5_SET(dest_format, in_dests, packet_reformat, 1);
     238         [ #  # ]:          0 :                                         MLX5_SET(extended_dest_format, in_dests, packet_reformat_id,
     239                 :            :                                                  dest->ext_reformat->id);
     240                 :            :                                 }
     241                 :            :                                 break;
     242                 :          0 :                         case MLX5_FLOW_DESTINATION_TYPE_NOP:
     243         [ #  # ]:          0 :                                 MLX5_SET(dest_format, in_dests, destination_type,
     244                 :            :                                          dest->destination_type);
     245                 :          0 :                                 break;
     246                 :          0 :                         default:
     247                 :          0 :                                 rte_errno = EOPNOTSUPP;
     248                 :          0 :                                 goto free_devx;
     249                 :            :                         }
     250                 :            : 
     251                 :          0 :                         in_dests = in_dests + dest_entry_sz;
     252                 :            :                 }
     253         [ #  # ]:          0 :                 MLX5_SET(flow_context, in_flow_context, destination_list_size, fte_attr->dests_num);
     254                 :            :         }
     255                 :            : 
     256                 :          0 :         devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, inlen, out, sizeof(out));
     257         [ #  # ]:          0 :         if (!devx_obj->obj) {
     258                 :          0 :                 DR_LOG(ERR, "Failed to create FTE (syndrome: %#x)",
     259                 :            :                        mlx5dr_cmd_get_syndrome(out));
     260                 :          0 :                 rte_errno = errno;
     261                 :          0 :                 goto free_devx;
     262                 :            :         }
     263                 :            : 
     264                 :            :         simple_free(in);
     265                 :          0 :         return devx_obj;
     266                 :            : 
     267                 :          0 : free_devx:
     268                 :            :         simple_free(devx_obj);
     269                 :          0 : free_in:
     270                 :            :         simple_free(in);
     271                 :          0 :         return NULL;
     272                 :            : }
     273                 :            : 
     274                 :            : struct mlx5dr_cmd_forward_tbl *
     275                 :          0 : mlx5dr_cmd_forward_tbl_create(struct ibv_context *ctx,
     276                 :            :                               struct mlx5dr_cmd_ft_create_attr *ft_attr,
     277                 :            :                               struct mlx5dr_cmd_set_fte_attr *fte_attr)
     278                 :            : {
     279                 :          0 :         struct mlx5dr_cmd_fg_attr fg_attr = {0};
     280                 :            :         struct mlx5dr_cmd_forward_tbl *tbl;
     281                 :            : 
     282                 :            :         tbl = simple_calloc(1, sizeof(*tbl));
     283         [ #  # ]:          0 :         if (!tbl) {
     284                 :          0 :                 DR_LOG(ERR, "Failed to allocate memory");
     285                 :          0 :                 rte_errno = ENOMEM;
     286                 :          0 :                 return NULL;
     287                 :            :         }
     288                 :            : 
     289                 :          0 :         tbl->ft = mlx5dr_cmd_flow_table_create(ctx, ft_attr);
     290         [ #  # ]:          0 :         if (!tbl->ft) {
     291                 :          0 :                 DR_LOG(ERR, "Failed to create FT");
     292                 :          0 :                 goto free_tbl;
     293                 :            :         }
     294                 :            : 
     295                 :          0 :         fg_attr.table_id = tbl->ft->id;
     296                 :          0 :         fg_attr.table_type = ft_attr->type;
     297                 :            : 
     298                 :          0 :         tbl->fg = mlx5dr_cmd_flow_group_create(ctx, &fg_attr);
     299         [ #  # ]:          0 :         if (!tbl->fg) {
     300                 :          0 :                 DR_LOG(ERR, "Failed to create FG");
     301                 :          0 :                 goto free_ft;
     302                 :            :         }
     303                 :            : 
     304                 :          0 :         tbl->fte = mlx5dr_cmd_set_fte(ctx, ft_attr->type, tbl->ft->id, tbl->fg->id, fte_attr);
     305         [ #  # ]:          0 :         if (!tbl->fte) {
     306                 :          0 :                 DR_LOG(ERR, "Failed to create FTE");
     307                 :          0 :                 goto free_fg;
     308                 :            :         }
     309                 :            :         return tbl;
     310                 :            : 
     311                 :            : free_fg:
     312                 :          0 :         mlx5dr_cmd_destroy_obj(tbl->fg);
     313                 :          0 : free_ft:
     314                 :          0 :         mlx5dr_cmd_destroy_obj(tbl->ft);
     315                 :          0 : free_tbl:
     316                 :            :         simple_free(tbl);
     317                 :          0 :         return NULL;
     318                 :            : }
     319                 :            : 
     320                 :          0 : void mlx5dr_cmd_forward_tbl_destroy(struct mlx5dr_cmd_forward_tbl *tbl)
     321                 :            : {
     322                 :          0 :         mlx5dr_cmd_destroy_obj(tbl->fte);
     323                 :          0 :         mlx5dr_cmd_destroy_obj(tbl->fg);
     324                 :          0 :         mlx5dr_cmd_destroy_obj(tbl->ft);
     325                 :            :         simple_free(tbl);
     326                 :          0 : }
     327                 :            : 
     328         [ #  # ]:          0 : void mlx5dr_cmd_set_attr_connect_miss_tbl(struct mlx5dr_context *ctx,
     329                 :            :                                           uint32_t fw_ft_type,
     330                 :            :                                           enum mlx5dr_table_type type,
     331                 :            :                                           struct mlx5dr_cmd_ft_modify_attr *ft_attr)
     332                 :            : {
     333                 :            :         struct mlx5dr_devx_obj *default_miss_tbl;
     334                 :            : 
     335         [ #  # ]:          0 :         if (!mlx5dr_table_is_fdb_any(type) && !mlx5dr_context_shared_gvmi_used(ctx))
     336                 :            :                 return;
     337                 :            : 
     338                 :          0 :         ft_attr->modify_fs = MLX5_IFC_MODIFY_FLOW_TABLE_MISS_ACTION;
     339                 :          0 :         ft_attr->type = fw_ft_type;
     340         [ #  # ]:          0 :         ft_attr->table_miss_action = MLX5_IFC_MODIFY_FLOW_TABLE_MISS_ACTION_GOTO_TBL;
     341                 :            : 
     342                 :            :         if (mlx5dr_table_is_fdb_any(type)) {
     343                 :          0 :                 default_miss_tbl = ctx->common_res[type].default_miss->ft;
     344         [ #  # ]:          0 :                 if (!default_miss_tbl) {
     345                 :          0 :                         assert(false);
     346                 :            :                         return;
     347                 :            :                 }
     348                 :          0 :                 ft_attr->table_miss_id = default_miss_tbl->id;
     349                 :            :         } else {
     350                 :          0 :                 ft_attr->table_miss_id = ctx->gvmi_res[type].aliased_end_ft->id;
     351                 :            :         }
     352                 :            : }
     353                 :            : 
     354                 :            : struct mlx5dr_devx_obj *
     355                 :          0 : mlx5dr_cmd_rtc_create(struct ibv_context *ctx,
     356                 :            :                       struct mlx5dr_cmd_rtc_create_attr *rtc_attr)
     357                 :            : {
     358                 :          0 :         uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
     359                 :          0 :         uint32_t in[MLX5_ST_SZ_DW(create_rtc_in)] = {0};
     360                 :            :         struct mlx5dr_devx_obj *devx_obj;
     361                 :            :         void *attr;
     362                 :            : 
     363                 :            :         devx_obj = simple_malloc(sizeof(*devx_obj));
     364         [ #  # ]:          0 :         if (!devx_obj) {
     365                 :          0 :                 DR_LOG(ERR, "Failed to allocate memory for RTC object");
     366                 :          0 :                 rte_errno = ENOMEM;
     367                 :          0 :                 return NULL;
     368                 :            :         }
     369                 :            : 
     370                 :            :         attr = MLX5_ADDR_OF(create_rtc_in, in, hdr);
     371         [ #  # ]:          0 :         MLX5_SET(general_obj_in_cmd_hdr,
     372                 :            :                  attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
     373         [ #  # ]:          0 :         MLX5_SET(general_obj_in_cmd_hdr,
     374                 :            :                  attr, obj_type, MLX5_GENERAL_OBJ_TYPE_RTC);
     375                 :            : 
     376                 :            :         attr = MLX5_ADDR_OF(create_rtc_in, in, rtc);
     377         [ #  # ]:          0 :         if (rtc_attr->is_compare) {
     378         [ #  # ]:          0 :                 MLX5_SET(rtc, attr, ste_format_0, MLX5_IFC_RTC_STE_FORMAT_4DW_RANGE);
     379                 :            :         } else {
     380   [ #  #  #  # ]:          0 :                 MLX5_SET(rtc, attr, ste_format_0, rtc_attr->is_frst_jumbo ?
     381                 :            :                          MLX5_IFC_RTC_STE_FORMAT_11DW : MLX5_IFC_RTC_STE_FORMAT_8DW);
     382                 :            :         }
     383                 :            : 
     384         [ #  # ]:          0 :         if (rtc_attr->is_scnd_range) {
     385         [ #  # ]:          0 :                 MLX5_SET(rtc, attr, ste_format_1, MLX5_IFC_RTC_STE_FORMAT_RANGE);
     386         [ #  # ]:          0 :                 MLX5_SET(rtc, attr, num_match_ste, 2);
     387                 :            :         }
     388                 :            : 
     389         [ #  # ]:          0 :         MLX5_SET(rtc, attr, pd, rtc_attr->pd);
     390         [ #  # ]:          0 :         MLX5_SET(rtc, attr, update_method, rtc_attr->fw_gen_wqe);
     391         [ #  # ]:          0 :         MLX5_SET(rtc, attr, update_index_mode, rtc_attr->update_index_mode);
     392         [ #  # ]:          0 :         MLX5_SET(rtc, attr, access_index_mode, rtc_attr->access_index_mode);
     393         [ #  # ]:          0 :         MLX5_SET(rtc, attr, num_hash_definer, rtc_attr->num_hash_definer);
     394         [ #  # ]:          0 :         MLX5_SET(rtc, attr, log_depth, rtc_attr->log_depth);
     395         [ #  # ]:          0 :         MLX5_SET(rtc, attr, log_hash_size, rtc_attr->log_size);
     396         [ #  # ]:          0 :         MLX5_SET(rtc, attr, table_type, rtc_attr->table_type);
     397         [ #  # ]:          0 :         MLX5_SET(rtc, attr, num_hash_definer, rtc_attr->num_hash_definer);
     398         [ #  # ]:          0 :         MLX5_SET(rtc, attr, match_definer_0, rtc_attr->match_definer_0);
     399         [ #  # ]:          0 :         MLX5_SET(rtc, attr, match_definer_1, rtc_attr->match_definer_1);
     400         [ #  # ]:          0 :         MLX5_SET(rtc, attr, stc_id, rtc_attr->stc_base);
     401         [ #  # ]:          0 :         MLX5_SET(rtc, attr, ste_table_base_id, rtc_attr->ste_base);
     402         [ #  # ]:          0 :         MLX5_SET(rtc, attr, ste_table_offset, rtc_attr->ste_offset);
     403         [ #  # ]:          0 :         MLX5_SET(rtc, attr, miss_flow_table_id, rtc_attr->miss_ft_id);
     404         [ #  # ]:          0 :         MLX5_SET(rtc, attr, reparse_mode, rtc_attr->reparse_mode);
     405                 :            : 
     406                 :          0 :         devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
     407         [ #  # ]:          0 :         if (!devx_obj->obj) {
     408                 :          0 :                 DR_LOG(ERR, "Failed to create RTC (syndrome: %#x)",
     409                 :            :                        mlx5dr_cmd_get_syndrome(out));
     410                 :            :                 simple_free(devx_obj);
     411                 :          0 :                 rte_errno = errno;
     412                 :          0 :                 return NULL;
     413                 :            :         }
     414                 :            : 
     415         [ #  # ]:          0 :         devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
     416                 :            : 
     417                 :          0 :         return devx_obj;
     418                 :            : }
     419                 :            : 
     420                 :            : struct mlx5dr_devx_obj *
     421                 :          0 : mlx5dr_cmd_stc_create(struct ibv_context *ctx,
     422                 :            :                       struct mlx5dr_cmd_stc_create_attr *stc_attr)
     423                 :            : {
     424                 :          0 :         uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
     425                 :          0 :         uint32_t in[MLX5_ST_SZ_DW(create_stc_in)] = {0};
     426                 :            :         struct mlx5dr_devx_obj *devx_obj;
     427                 :            :         void *attr;
     428                 :            : 
     429                 :            :         devx_obj = simple_malloc(sizeof(*devx_obj));
     430         [ #  # ]:          0 :         if (!devx_obj) {
     431                 :          0 :                 DR_LOG(ERR, "Failed to allocate memory for STC object");
     432                 :          0 :                 rte_errno = ENOMEM;
     433                 :          0 :                 return NULL;
     434                 :            :         }
     435                 :            : 
     436                 :            :         attr = MLX5_ADDR_OF(create_stc_in, in, hdr);
     437         [ #  # ]:          0 :         MLX5_SET(general_obj_in_cmd_hdr,
     438                 :            :                  attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
     439         [ #  # ]:          0 :         MLX5_SET(general_obj_in_cmd_hdr,
     440                 :            :                  attr, obj_type, MLX5_GENERAL_OBJ_TYPE_STC);
     441         [ #  # ]:          0 :         MLX5_SET(general_obj_in_cmd_hdr,
     442                 :            :                  attr, log_obj_range, stc_attr->log_obj_range);
     443                 :            : 
     444                 :            :         attr = MLX5_ADDR_OF(create_stc_in, in, stc);
     445         [ #  # ]:          0 :         MLX5_SET(stc, attr, table_type, stc_attr->table_type);
     446                 :            : 
     447                 :          0 :         devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
     448         [ #  # ]:          0 :         if (!devx_obj->obj) {
     449                 :          0 :                 DR_LOG(ERR, "Failed to create STC (syndrome: %#x)",
     450                 :            :                        mlx5dr_cmd_get_syndrome(out));
     451                 :            :                 simple_free(devx_obj);
     452                 :          0 :                 rte_errno = errno;
     453                 :          0 :                 return NULL;
     454                 :            :         }
     455                 :            : 
     456         [ #  # ]:          0 :         devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
     457                 :            : 
     458                 :          0 :         return devx_obj;
     459                 :            : }
     460                 :            : 
     461                 :            : static int
     462                 :          0 : mlx5dr_cmd_stc_modify_set_stc_param(struct mlx5dr_cmd_stc_modify_attr *stc_attr,
     463                 :            :                                     void *stc_param)
     464                 :            : {
     465   [ #  #  #  #  :          0 :         switch (stc_attr->action_type) {
          #  #  #  #  #  
             #  #  #  # ]
     466                 :          0 :         case MLX5_IFC_STC_ACTION_TYPE_COUNTER:
     467         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_flow_counter, stc_param, flow_counter_id, stc_attr->id);
     468                 :          0 :                 break;
     469                 :          0 :         case MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_TIR:
     470         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_tir, stc_param, tirn, stc_attr->dest_tir_num);
     471                 :          0 :                 break;
     472                 :          0 :         case MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_FT:
     473                 :            :         case MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_FLOW_TABLE_FDB_RX:
     474         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_table, stc_param, table_id, stc_attr->dest_table_id);
     475                 :          0 :                 break;
     476                 :          0 :         case MLX5_IFC_STC_ACTION_TYPE_ACC_MODIFY_LIST:
     477         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_header_modify_list, stc_param,
     478                 :            :                          header_modify_pattern_id, stc_attr->modify_header.pattern_id);
     479         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_header_modify_list, stc_param,
     480                 :            :                          header_modify_argument_id, stc_attr->modify_header.arg_id);
     481                 :          0 :                 break;
     482                 :          0 :         case MLX5_IFC_STC_ACTION_TYPE_HEADER_REMOVE:
     483         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_remove, stc_param, action_type,
     484                 :            :                          MLX5_MODIFICATION_TYPE_REMOVE);
     485         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_remove, stc_param, decap,
     486                 :            :                          stc_attr->remove_header.decap);
     487         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_remove, stc_param, remove_start_anchor,
     488                 :            :                          stc_attr->remove_header.start_anchor);
     489         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_remove, stc_param, remove_end_anchor,
     490                 :            :                          stc_attr->remove_header.end_anchor);
     491                 :          0 :                 break;
     492                 :          0 :         case MLX5_IFC_STC_ACTION_TYPE_HEADER_INSERT:
     493         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_insert, stc_param, action_type,
     494                 :            :                          MLX5_MODIFICATION_TYPE_INSERT);
     495         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_insert, stc_param, encap,
     496                 :            :                          stc_attr->insert_header.encap);
     497         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_insert, stc_param, push_esp,
     498                 :            :                          stc_attr->insert_header.push_esp);
     499         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_insert, stc_param, inline_data,
     500                 :            :                          stc_attr->insert_header.is_inline);
     501         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_insert, stc_param, insert_anchor,
     502                 :            :                          stc_attr->insert_header.insert_anchor);
     503                 :            :                 /* HW gets the next 2 sizes in words */
     504         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_insert, stc_param, insert_size,
     505                 :            :                          stc_attr->insert_header.header_size / W_SIZE);
     506         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_insert, stc_param, insert_offset,
     507                 :            :                          stc_attr->insert_header.insert_offset / W_SIZE);
     508         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_insert, stc_param, insert_argument,
     509                 :            :                          stc_attr->insert_header.arg_id);
     510                 :          0 :                 break;
     511                 :          0 :         case MLX5_IFC_STC_ACTION_TYPE_COPY:
     512                 :            :         case MLX5_IFC_STC_ACTION_TYPE_SET:
     513                 :            :         case MLX5_IFC_STC_ACTION_TYPE_ADD:
     514                 :            :         case MLX5_IFC_STC_ACTION_TYPE_ADD_FIELD:
     515                 :          0 :                 *(__be64 *)stc_param = stc_attr->modify_action.data;
     516                 :          0 :                 break;
     517                 :          0 :         case MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_VPORT:
     518                 :            :         case MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_UPLINK:
     519         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_vport, stc_param, vport_number,
     520                 :            :                          stc_attr->vport.vport_num);
     521         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_vport, stc_param, eswitch_owner_vhca_id,
     522                 :            :                          stc_attr->vport.esw_owner_vhca_id);
     523         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_vport, stc_param, eswitch_owner_vhca_id_valid,
     524                 :            :                          stc_attr->vport.eswitch_owner_vhca_id_valid);
     525                 :          0 :                 break;
     526                 :            :         case MLX5_IFC_STC_ACTION_TYPE_DROP:
     527                 :            :         case MLX5_IFC_STC_ACTION_TYPE_NOP:
     528                 :            :         case MLX5_IFC_STC_ACTION_TYPE_TAG:
     529                 :            :         case MLX5_IFC_STC_ACTION_TYPE_ALLOW:
     530                 :            :                 break;
     531                 :          0 :         case MLX5_IFC_STC_ACTION_TYPE_ASO:
     532         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_execute_aso, stc_param, aso_object_id,
     533                 :            :                          stc_attr->aso.devx_obj_id);
     534         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_execute_aso, stc_param, return_reg_id,
     535                 :            :                          stc_attr->aso.return_reg_id);
     536         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_execute_aso, stc_param, aso_type,
     537                 :            :                          stc_attr->aso.aso_type);
     538                 :          0 :                 break;
     539                 :          0 :         case MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_STE_TABLE:
     540         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_ste_table, stc_param, ste_obj_id,
     541                 :            :                          stc_attr->ste_table.ste_obj_id);
     542         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_ste_table, stc_param, match_definer_id,
     543                 :            :                          stc_attr->ste_table.match_definer_id);
     544         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_ste_table, stc_param, log_hash_size,
     545                 :            :                          stc_attr->ste_table.log_hash_size);
     546                 :          0 :                 break;
     547                 :          0 :         case MLX5_IFC_STC_ACTION_TYPE_REMOVE_WORDS:
     548         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_remove_words, stc_param, action_type,
     549                 :            :                          MLX5_MODIFICATION_TYPE_REMOVE_WORDS);
     550         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_remove_words, stc_param, remove_start_anchor,
     551                 :            :                          stc_attr->remove_words.start_anchor);
     552         [ #  # ]:          0 :                 MLX5_SET(stc_ste_param_remove_words, stc_param,
     553                 :            :                          remove_size, stc_attr->remove_words.num_of_words);
     554                 :          0 :                 break;
     555                 :          0 :         default:
     556                 :          0 :                 DR_LOG(ERR, "Not supported type %d", stc_attr->action_type);
     557                 :          0 :                 rte_errno = EINVAL;
     558                 :          0 :                 return rte_errno;
     559                 :            :         }
     560                 :            :         return 0;
     561                 :            : }
     562                 :            : 
     563                 :            : int
     564                 :          0 : mlx5dr_cmd_stc_modify(struct mlx5dr_devx_obj *devx_obj,
     565                 :            :                       struct mlx5dr_cmd_stc_modify_attr *stc_attr)
     566                 :            : {
     567                 :          0 :         uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
     568                 :          0 :         uint32_t in[MLX5_ST_SZ_DW(create_stc_in)] = {0};
     569                 :            :         void *stc_param;
     570                 :            :         void *attr;
     571                 :            :         int ret;
     572                 :            : 
     573                 :            :         attr = MLX5_ADDR_OF(create_stc_in, in, hdr);
     574                 :          0 :         MLX5_SET(general_obj_in_cmd_hdr,
     575                 :            :                  attr, opcode, MLX5_CMD_OP_MODIFY_GENERAL_OBJECT);
     576                 :          0 :         MLX5_SET(general_obj_in_cmd_hdr,
     577                 :            :                  attr, obj_type, MLX5_GENERAL_OBJ_TYPE_STC);
     578                 :          0 :         MLX5_SET(general_obj_in_cmd_hdr, in, obj_id, devx_obj->id);
     579                 :          0 :         MLX5_SET(general_obj_in_cmd_hdr, in, obj_offset, stc_attr->stc_offset);
     580                 :            : 
     581                 :            :         attr = MLX5_ADDR_OF(create_stc_in, in, stc);
     582                 :          0 :         MLX5_SET(stc, attr, ste_action_offset, stc_attr->action_offset);
     583         [ #  # ]:          0 :         MLX5_SET(stc, attr, action_type, stc_attr->action_type);
     584         [ #  # ]:          0 :         MLX5_SET(stc, attr, reparse_mode, stc_attr->reparse_mode);
     585                 :          0 :         MLX5_SET64(stc, attr, modify_field_select,
     586                 :            :                    MLX5_IFC_MODIFY_STC_FIELD_SELECT_NEW_STC);
     587                 :            : 
     588                 :            :         /* Set destination TIRN, TAG, FT ID, STE ID */
     589                 :            :         stc_param = MLX5_ADDR_OF(stc, attr, stc_param);
     590                 :          0 :         ret = mlx5dr_cmd_stc_modify_set_stc_param(stc_attr, stc_param);
     591         [ #  # ]:          0 :         if (ret)
     592                 :            :                 return ret;
     593                 :            : 
     594                 :          0 :         ret = mlx5_glue->devx_obj_modify(devx_obj->obj, in, sizeof(in), out, sizeof(out));
     595         [ #  # ]:          0 :         if (ret) {
     596                 :          0 :                 DR_LOG(ERR, "Failed to modify STC FW action_type %d (syndrome: %#x)",
     597                 :            :                        stc_attr->action_type, mlx5dr_cmd_get_syndrome(out));
     598                 :          0 :                 rte_errno = errno;
     599                 :            :         }
     600                 :            : 
     601                 :            :         return ret;
     602                 :            : }
     603                 :            : 
     604                 :            : struct mlx5dr_devx_obj *
     605                 :          0 : mlx5dr_cmd_arg_create(struct ibv_context *ctx,
     606                 :            :                       uint16_t log_obj_range,
     607                 :            :                       uint32_t pd)
     608                 :            : {
     609                 :          0 :         uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
     610                 :          0 :         uint32_t in[MLX5_ST_SZ_DW(create_arg_in)] = {0};
     611                 :            :         struct mlx5dr_devx_obj *devx_obj;
     612                 :            :         void *attr;
     613                 :            : 
     614                 :            :         devx_obj = simple_malloc(sizeof(*devx_obj));
     615         [ #  # ]:          0 :         if (!devx_obj) {
     616                 :          0 :                 DR_LOG(ERR, "Failed to allocate memory for ARG object");
     617                 :          0 :                 rte_errno = ENOMEM;
     618                 :          0 :                 return NULL;
     619                 :            :         }
     620                 :            : 
     621                 :            :         attr = MLX5_ADDR_OF(create_arg_in, in, hdr);
     622         [ #  # ]:          0 :         MLX5_SET(general_obj_in_cmd_hdr,
     623                 :            :                  attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
     624         [ #  # ]:          0 :         MLX5_SET(general_obj_in_cmd_hdr,
     625                 :            :                  attr, obj_type, MLX5_GENERAL_OBJ_TYPE_ARG);
     626         [ #  # ]:          0 :         MLX5_SET(general_obj_in_cmd_hdr,
     627                 :            :                  attr, log_obj_range, log_obj_range);
     628                 :            : 
     629                 :            :         attr = MLX5_ADDR_OF(create_arg_in, in, arg);
     630         [ #  # ]:          0 :         MLX5_SET(arg, attr, access_pd, pd);
     631                 :            : 
     632                 :          0 :         devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
     633         [ #  # ]:          0 :         if (!devx_obj->obj) {
     634                 :          0 :                 DR_LOG(ERR, "Failed to create ARG (syndrome: %#x)",
     635                 :            :                        mlx5dr_cmd_get_syndrome(out));
     636                 :            :                 simple_free(devx_obj);
     637                 :          0 :                 rte_errno = errno;
     638                 :          0 :                 return NULL;
     639                 :            :         }
     640                 :            : 
     641         [ #  # ]:          0 :         devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
     642                 :            : 
     643                 :          0 :         return devx_obj;
     644                 :            : }
     645                 :            : 
     646                 :            : struct mlx5dr_devx_obj *
     647                 :          0 : mlx5dr_cmd_header_modify_pattern_create(struct ibv_context *ctx,
     648                 :            :                                         uint32_t pattern_length,
     649                 :            :                                         uint8_t *actions)
     650                 :            : {
     651                 :          0 :         uint32_t in[MLX5_ST_SZ_DW(create_header_modify_pattern_in)] = {0};
     652                 :          0 :         uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
     653                 :            :         struct mlx5dr_devx_obj *devx_obj;
     654                 :            :         uint64_t *pattern_data;
     655                 :            :         int num_of_actions;
     656                 :            :         void *pattern;
     657                 :            :         void *attr;
     658                 :            :         int i;
     659                 :            : 
     660         [ #  # ]:          0 :         if (pattern_length > MAX_ACTIONS_DATA_IN_HEADER_MODIFY) {
     661                 :          0 :                 DR_LOG(ERR, "Pattern length %d exceeds limit %d",
     662                 :            :                         pattern_length, MAX_ACTIONS_DATA_IN_HEADER_MODIFY);
     663                 :          0 :                 rte_errno = EINVAL;
     664                 :          0 :                 return NULL;
     665                 :            :         }
     666                 :            : 
     667                 :            :         devx_obj = simple_malloc(sizeof(*devx_obj));
     668         [ #  # ]:          0 :         if (!devx_obj) {
     669                 :          0 :                 DR_LOG(ERR, "Failed to allocate memory for header_modify_pattern object");
     670                 :          0 :                 rte_errno = ENOMEM;
     671                 :          0 :                 return NULL;
     672                 :            :         }
     673                 :            :         attr = MLX5_ADDR_OF(create_header_modify_pattern_in, in, hdr);
     674         [ #  # ]:          0 :         MLX5_SET(general_obj_in_cmd_hdr,
     675                 :            :                  attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
     676         [ #  # ]:          0 :         MLX5_SET(general_obj_in_cmd_hdr,
     677                 :            :                  attr, obj_type, MLX5_GENERAL_OBJ_TYPE_MODIFY_HEADER_PATTERN);
     678                 :            : 
     679                 :            :         pattern = MLX5_ADDR_OF(create_header_modify_pattern_in, in, pattern);
     680                 :            :         /* Pattern_length is in ddwords */
     681         [ #  # ]:          0 :         MLX5_SET(header_modify_pattern_in, pattern, pattern_length, pattern_length / (2 * DW_SIZE));
     682                 :            : 
     683                 :            :         pattern_data = (uint64_t *)MLX5_ADDR_OF(header_modify_pattern_in, pattern, pattern_data);
     684                 :          0 :         memcpy(pattern_data, actions, pattern_length);
     685                 :            : 
     686                 :          0 :         num_of_actions = pattern_length / MLX5DR_MODIFY_ACTION_SIZE;
     687         [ #  # ]:          0 :         for (i = 0; i < num_of_actions; i++) {
     688                 :            :                 int type;
     689                 :            : 
     690         [ #  # ]:          0 :                 type = MLX5_GET(set_action_in, &pattern_data[i], action_type);
     691                 :          0 :                 if (type != MLX5_MODIFICATION_TYPE_COPY &&
     692         [ #  # ]:          0 :                     type != MLX5_MODIFICATION_TYPE_ADD_FIELD)
     693                 :            :                         /* Action typ-copy use all bytes for control */
     694         [ #  # ]:          0 :                         MLX5_SET(set_action_in, &pattern_data[i], data, 0);
     695                 :            :         }
     696                 :            : 
     697                 :          0 :         devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
     698         [ #  # ]:          0 :         if (!devx_obj->obj) {
     699                 :          0 :                 DR_LOG(ERR, "Failed to create header_modify_pattern (syndrome: %#x)",
     700                 :            :                        mlx5dr_cmd_get_syndrome(out));
     701                 :          0 :                 rte_errno = errno;
     702                 :          0 :                 goto free_obj;
     703                 :            :         }
     704                 :            : 
     705         [ #  # ]:          0 :         devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
     706                 :            : 
     707                 :          0 :         return devx_obj;
     708                 :            : 
     709                 :            : free_obj:
     710                 :            :         simple_free(devx_obj);
     711                 :          0 :         return NULL;
     712                 :            : }
     713                 :            : 
     714                 :            : struct mlx5dr_devx_obj *
     715                 :          0 : mlx5dr_cmd_ste_create(struct ibv_context *ctx,
     716                 :            :                       struct mlx5dr_cmd_ste_create_attr *ste_attr)
     717                 :            : {
     718                 :          0 :         uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
     719                 :          0 :         uint32_t in[MLX5_ST_SZ_DW(create_ste_in)] = {0};
     720                 :            :         struct mlx5dr_devx_obj *devx_obj;
     721                 :            :         void *attr;
     722                 :            : 
     723                 :            :         devx_obj = simple_malloc(sizeof(*devx_obj));
     724         [ #  # ]:          0 :         if (!devx_obj) {
     725                 :          0 :                 DR_LOG(ERR, "Failed to allocate memory for STE object");
     726                 :          0 :                 rte_errno = ENOMEM;
     727                 :          0 :                 return NULL;
     728                 :            :         }
     729                 :            : 
     730                 :            :         attr = MLX5_ADDR_OF(create_ste_in, in, hdr);
     731         [ #  # ]:          0 :         MLX5_SET(general_obj_in_cmd_hdr,
     732                 :            :                  attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
     733         [ #  # ]:          0 :         MLX5_SET(general_obj_in_cmd_hdr,
     734                 :            :                  attr, obj_type, MLX5_GENERAL_OBJ_TYPE_STE);
     735         [ #  # ]:          0 :         MLX5_SET(general_obj_in_cmd_hdr,
     736                 :            :                  attr, log_obj_range, ste_attr->log_obj_range);
     737                 :            : 
     738                 :            :         attr = MLX5_ADDR_OF(create_ste_in, in, ste);
     739         [ #  # ]:          0 :         MLX5_SET(ste, attr, table_type, ste_attr->table_type);
     740                 :            : 
     741                 :          0 :         devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
     742         [ #  # ]:          0 :         if (!devx_obj->obj) {
     743                 :          0 :                 DR_LOG(ERR, "Failed to create STE (syndrome: %#x)",
     744                 :            :                        mlx5dr_cmd_get_syndrome(out));
     745                 :            :                 simple_free(devx_obj);
     746                 :          0 :                 rte_errno = errno;
     747                 :          0 :                 return NULL;
     748                 :            :         }
     749                 :            : 
     750         [ #  # ]:          0 :         devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
     751                 :            : 
     752                 :          0 :         return devx_obj;
     753                 :            : }
     754                 :            : 
     755                 :            : struct mlx5dr_devx_obj *
     756                 :          0 : mlx5dr_cmd_definer_create(struct ibv_context *ctx,
     757                 :            :                           struct mlx5dr_cmd_definer_create_attr *def_attr)
     758                 :            : {
     759                 :          0 :         uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
     760                 :          0 :         uint32_t in[MLX5_ST_SZ_DW(create_definer_in)] = {0};
     761                 :            :         struct mlx5dr_devx_obj *devx_obj;
     762                 :            :         void *ptr;
     763                 :            : 
     764                 :            :         devx_obj = simple_malloc(sizeof(*devx_obj));
     765         [ #  # ]:          0 :         if (!devx_obj) {
     766                 :          0 :                 DR_LOG(ERR, "Failed to allocate memory for definer object");
     767                 :          0 :                 rte_errno = ENOMEM;
     768                 :          0 :                 return NULL;
     769                 :            :         }
     770                 :            : 
     771         [ #  # ]:          0 :         MLX5_SET(general_obj_in_cmd_hdr,
     772                 :            :                  in, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
     773         [ #  # ]:          0 :         MLX5_SET(general_obj_in_cmd_hdr,
     774                 :            :                  in, obj_type, MLX5_GENERAL_OBJ_TYPE_DEFINER);
     775                 :            : 
     776                 :            :         ptr = MLX5_ADDR_OF(create_definer_in, in, definer);
     777         [ #  # ]:          0 :         MLX5_SET(definer, ptr, format_id, MLX5_IFC_DEFINER_FORMAT_ID_SELECT);
     778                 :            : 
     779         [ #  # ]:          0 :         MLX5_SET(definer, ptr, format_select_dw0, def_attr->dw_selector[0]);
     780         [ #  # ]:          0 :         MLX5_SET(definer, ptr, format_select_dw1, def_attr->dw_selector[1]);
     781         [ #  # ]:          0 :         MLX5_SET(definer, ptr, format_select_dw2, def_attr->dw_selector[2]);
     782         [ #  # ]:          0 :         MLX5_SET(definer, ptr, format_select_dw3, def_attr->dw_selector[3]);
     783         [ #  # ]:          0 :         MLX5_SET(definer, ptr, format_select_dw4, def_attr->dw_selector[4]);
     784         [ #  # ]:          0 :         MLX5_SET(definer, ptr, format_select_dw5, def_attr->dw_selector[5]);
     785         [ #  # ]:          0 :         MLX5_SET(definer, ptr, format_select_dw6, def_attr->dw_selector[6]);
     786         [ #  # ]:          0 :         MLX5_SET(definer, ptr, format_select_dw7, def_attr->dw_selector[7]);
     787         [ #  # ]:          0 :         MLX5_SET(definer, ptr, format_select_dw8, def_attr->dw_selector[8]);
     788                 :            : 
     789         [ #  # ]:          0 :         MLX5_SET(definer, ptr, format_select_byte0, def_attr->byte_selector[0]);
     790         [ #  # ]:          0 :         MLX5_SET(definer, ptr, format_select_byte1, def_attr->byte_selector[1]);
     791         [ #  # ]:          0 :         MLX5_SET(definer, ptr, format_select_byte2, def_attr->byte_selector[2]);
     792         [ #  # ]:          0 :         MLX5_SET(definer, ptr, format_select_byte3, def_attr->byte_selector[3]);
     793         [ #  # ]:          0 :         MLX5_SET(definer, ptr, format_select_byte4, def_attr->byte_selector[4]);
     794         [ #  # ]:          0 :         MLX5_SET(definer, ptr, format_select_byte5, def_attr->byte_selector[5]);
     795         [ #  # ]:          0 :         MLX5_SET(definer, ptr, format_select_byte6, def_attr->byte_selector[6]);
     796         [ #  # ]:          0 :         MLX5_SET(definer, ptr, format_select_byte7, def_attr->byte_selector[7]);
     797                 :            : 
     798                 :            :         ptr = MLX5_ADDR_OF(definer, ptr, match_mask);
     799                 :          0 :         memcpy(ptr, def_attr->match_mask, MLX5_FLD_SZ_BYTES(definer, match_mask));
     800                 :            : 
     801                 :          0 :         devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
     802         [ #  # ]:          0 :         if (!devx_obj->obj) {
     803                 :          0 :                 DR_LOG(ERR, "Failed to create Definer (syndrome: %#x)",
     804                 :            :                        mlx5dr_cmd_get_syndrome(out));
     805                 :            :                 simple_free(devx_obj);
     806                 :          0 :                 rte_errno = errno;
     807                 :          0 :                 return NULL;
     808                 :            :         }
     809                 :            : 
     810         [ #  # ]:          0 :         devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
     811                 :            : 
     812                 :          0 :         return devx_obj;
     813                 :            : }
     814                 :            : 
     815                 :            : struct mlx5dr_devx_obj *
     816                 :          0 : mlx5dr_cmd_sq_create(struct ibv_context *ctx,
     817                 :            :                      struct mlx5dr_cmd_sq_create_attr *attr)
     818                 :            : {
     819                 :          0 :         uint32_t out[MLX5_ST_SZ_DW(create_sq_out)] = {0};
     820                 :          0 :         uint32_t in[MLX5_ST_SZ_DW(create_sq_in)] = {0};
     821                 :            :         void *sqc = MLX5_ADDR_OF(create_sq_in, in, ctx);
     822                 :            :         void *wqc = MLX5_ADDR_OF(sqc, sqc, wq);
     823                 :            :         struct mlx5dr_devx_obj *devx_obj;
     824                 :            : 
     825                 :            :         devx_obj = simple_malloc(sizeof(*devx_obj));
     826         [ #  # ]:          0 :         if (!devx_obj) {
     827                 :          0 :                 DR_LOG(ERR, "Failed to create SQ");
     828                 :          0 :                 rte_errno = ENOMEM;
     829                 :          0 :                 return NULL;
     830                 :            :         }
     831                 :            : 
     832         [ #  # ]:          0 :         MLX5_SET(create_sq_in, in, opcode, MLX5_CMD_OP_CREATE_SQ);
     833         [ #  # ]:          0 :         MLX5_SET(sqc, sqc, cqn, attr->cqn);
     834         [ #  # ]:          0 :         MLX5_SET(sqc, sqc, flush_in_error_en, 1);
     835         [ #  # ]:          0 :         MLX5_SET(sqc, sqc, non_wire, 1);
     836         [ #  # ]:          0 :         MLX5_SET(sqc, sqc, ts_format, attr->ts_format);
     837         [ #  # ]:          0 :         MLX5_SET(wq, wqc, wq_type, MLX5_WQ_TYPE_CYCLIC);
     838         [ #  # ]:          0 :         MLX5_SET(wq, wqc, pd, attr->pdn);
     839         [ #  # ]:          0 :         MLX5_SET(wq, wqc, uar_page, attr->page_id);
     840         [ #  # ]:          0 :         MLX5_SET(wq, wqc, log_wq_stride, log2above(MLX5_SEND_WQE_BB));
     841         [ #  # ]:          0 :         MLX5_SET(wq, wqc, log_wq_sz, attr->log_wq_sz);
     842         [ #  # ]:          0 :         MLX5_SET(wq, wqc, dbr_umem_id, attr->dbr_id);
     843         [ #  # ]:          0 :         MLX5_SET(wq, wqc, wq_umem_id, attr->wq_id);
     844                 :            : 
     845                 :          0 :         devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
     846         [ #  # ]:          0 :         if (!devx_obj->obj) {
     847                 :            :                 simple_free(devx_obj);
     848                 :          0 :                 rte_errno = errno;
     849                 :          0 :                 return NULL;
     850                 :            :         }
     851                 :            : 
     852         [ #  # ]:          0 :         devx_obj->id = MLX5_GET(create_sq_out, out, sqn);
     853                 :            : 
     854                 :          0 :         return devx_obj;
     855                 :            : }
     856                 :            : 
     857                 :            : struct mlx5dr_devx_obj *
     858                 :          0 : mlx5dr_cmd_packet_reformat_create(struct ibv_context *ctx,
     859                 :            :                                   struct mlx5dr_cmd_packet_reformat_create_attr *attr)
     860                 :            : {
     861                 :          0 :         uint32_t out[MLX5_ST_SZ_DW(alloc_packet_reformat_out)] = {0};
     862                 :            :         size_t insz, cmd_data_sz, cmd_total_sz;
     863                 :            :         struct mlx5dr_devx_obj *devx_obj;
     864                 :            :         void *prctx;
     865                 :            :         void *pdata;
     866                 :            :         void *in;
     867                 :            : 
     868                 :            :         cmd_total_sz = MLX5_ST_SZ_BYTES(alloc_packet_reformat_context_in);
     869                 :            :         cmd_total_sz += MLX5_ST_SZ_BYTES(packet_reformat_context_in);
     870                 :            :         cmd_data_sz = MLX5_FLD_SZ_BYTES(packet_reformat_context_in, reformat_data);
     871                 :          0 :         insz = align(cmd_total_sz + attr->data_sz - cmd_data_sz, DW_SIZE);
     872                 :            :         in = simple_calloc(1, insz);
     873         [ #  # ]:          0 :         if (!in) {
     874                 :          0 :                 rte_errno = ENOMEM;
     875                 :          0 :                 return NULL;
     876                 :            :         }
     877                 :            : 
     878         [ #  # ]:          0 :         MLX5_SET(alloc_packet_reformat_context_in, in, opcode,
     879                 :            :                  MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT);
     880                 :            : 
     881                 :            :         prctx = MLX5_ADDR_OF(alloc_packet_reformat_context_in, in,
     882                 :            :                              packet_reformat_context);
     883                 :          0 :         pdata = MLX5_ADDR_OF(packet_reformat_context_in, prctx, reformat_data);
     884                 :            : 
     885         [ #  # ]:          0 :         MLX5_SET(packet_reformat_context_in, prctx, reformat_type, attr->type);
     886         [ #  # ]:          0 :         MLX5_SET(packet_reformat_context_in, prctx, reformat_param_0, attr->reformat_param_0);
     887         [ #  # ]:          0 :         MLX5_SET(packet_reformat_context_in, prctx, reformat_data_size, attr->data_sz);
     888                 :          0 :         memcpy(pdata, attr->data, attr->data_sz);
     889                 :            : 
     890                 :            :         devx_obj = simple_malloc(sizeof(*devx_obj));
     891         [ #  # ]:          0 :         if (!devx_obj) {
     892                 :          0 :                 DR_LOG(ERR, "Failed to allocate memory for packet reformat object");
     893                 :          0 :                 rte_errno = ENOMEM;
     894                 :          0 :                 goto out_free_in;
     895                 :            :         }
     896                 :            : 
     897                 :          0 :         devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, insz, out, sizeof(out));
     898         [ #  # ]:          0 :         if (!devx_obj->obj) {
     899                 :          0 :                 DR_LOG(ERR, "Failed to create packet reformat");
     900                 :          0 :                 rte_errno = errno;
     901                 :          0 :                 goto out_free_devx;
     902                 :            :         }
     903                 :            : 
     904         [ #  # ]:          0 :         devx_obj->id = MLX5_GET(alloc_packet_reformat_out, out, packet_reformat_id);
     905                 :            : 
     906                 :            :         simple_free(in);
     907                 :            : 
     908                 :          0 :         return devx_obj;
     909                 :            : 
     910                 :            : out_free_devx:
     911                 :            :         simple_free(devx_obj);
     912                 :          0 : out_free_in:
     913                 :            :         simple_free(in);
     914                 :          0 :         return NULL;
     915                 :            : }
     916                 :            : 
     917                 :          0 : int mlx5dr_cmd_sq_modify_rdy(struct mlx5dr_devx_obj *devx_obj)
     918                 :            : {
     919                 :          0 :         uint32_t out[MLX5_ST_SZ_DW(modify_sq_out)] = {0};
     920                 :          0 :         uint32_t in[MLX5_ST_SZ_DW(modify_sq_in)] = {0};
     921                 :            :         void *sqc = MLX5_ADDR_OF(modify_sq_in, in, ctx);
     922                 :            :         int ret;
     923                 :            : 
     924                 :          0 :         MLX5_SET(modify_sq_in, in, opcode, MLX5_CMD_OP_MODIFY_SQ);
     925                 :          0 :         MLX5_SET(modify_sq_in, in, sqn, devx_obj->id);
     926         [ #  # ]:          0 :         MLX5_SET(modify_sq_in, in, sq_state, MLX5_SQC_STATE_RST);
     927                 :          0 :         MLX5_SET(sqc, sqc, state, MLX5_SQC_STATE_RDY);
     928                 :            : 
     929                 :          0 :         ret = mlx5_glue->devx_obj_modify(devx_obj->obj, in, sizeof(in), out, sizeof(out));
     930         [ #  # ]:          0 :         if (ret) {
     931                 :          0 :                 DR_LOG(ERR, "Failed to modify SQ (syndrome: %#x)",
     932                 :            :                        mlx5dr_cmd_get_syndrome(out));
     933                 :          0 :                 rte_errno = errno;
     934                 :            :         }
     935                 :            : 
     936                 :          0 :         return ret;
     937                 :            : }
     938                 :            : 
     939                 :          0 : int mlx5dr_cmd_allow_other_vhca_access(struct ibv_context *ctx,
     940                 :            :                                        struct mlx5dr_cmd_allow_other_vhca_access_attr *attr)
     941                 :            : {
     942                 :          0 :         uint32_t out[MLX5_ST_SZ_DW(allow_other_vhca_access_out)] = {0};
     943                 :          0 :         uint32_t in[MLX5_ST_SZ_DW(allow_other_vhca_access_in)] = {0};
     944                 :            :         void *key;
     945                 :            :         int ret;
     946                 :            : 
     947                 :          0 :         MLX5_SET(allow_other_vhca_access_in,
     948                 :            :                  in, opcode, MLX5_CMD_OP_ALLOW_OTHER_VHCA_ACCESS);
     949                 :          0 :         MLX5_SET(allow_other_vhca_access_in,
     950                 :            :                  in, object_type_to_be_accessed, attr->obj_type);
     951                 :          0 :         MLX5_SET(allow_other_vhca_access_in,
     952                 :            :                  in, object_id_to_be_accessed, attr->obj_id);
     953                 :            : 
     954                 :            :         key = MLX5_ADDR_OF(allow_other_vhca_access_in, in, access_key);
     955                 :          0 :         memcpy(key, attr->access_key, sizeof(attr->access_key));
     956                 :            : 
     957                 :          0 :         ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
     958         [ #  # ]:          0 :         if (ret) {
     959                 :          0 :                 DR_LOG(ERR, "Failed to execute ALLOW_OTHER_VHCA_ACCESS command");
     960                 :          0 :                 rte_errno = errno;
     961                 :          0 :                 return rte_errno;
     962                 :            :         }
     963                 :            : 
     964                 :            :         return 0;
     965                 :            : }
     966                 :            : 
     967                 :            : struct mlx5dr_devx_obj *
     968                 :          0 : mlx5dr_cmd_alias_obj_create(struct ibv_context *ctx,
     969                 :            :                             struct mlx5dr_cmd_alias_obj_create_attr *alias_attr)
     970                 :            : {
     971                 :          0 :         uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
     972                 :          0 :         uint32_t in[MLX5_ST_SZ_DW(create_alias_obj_in)] = {0};
     973                 :            :         struct mlx5dr_devx_obj *devx_obj;
     974                 :            :         void *attr;
     975                 :            :         void *key;
     976                 :            : 
     977                 :            :         devx_obj = simple_malloc(sizeof(*devx_obj));
     978         [ #  # ]:          0 :         if (!devx_obj) {
     979                 :          0 :                 DR_LOG(ERR, "Failed to allocate memory for ALIAS general object");
     980                 :          0 :                 rte_errno = ENOMEM;
     981                 :          0 :                 return NULL;
     982                 :            :         }
     983                 :            : 
     984                 :            :         attr = MLX5_ADDR_OF(create_alias_obj_in, in, hdr);
     985         [ #  # ]:          0 :         MLX5_SET(general_obj_in_cmd_hdr,
     986                 :            :                  attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
     987         [ #  # ]:          0 :         MLX5_SET(general_obj_in_cmd_hdr,
     988                 :            :                  attr, obj_type, alias_attr->obj_type);
     989         [ #  # ]:          0 :         MLX5_SET(general_obj_in_cmd_hdr, attr, alias_object, 1);
     990                 :            : 
     991                 :            :         attr = MLX5_ADDR_OF(create_alias_obj_in, in, alias_ctx);
     992         [ #  # ]:          0 :         MLX5_SET(alias_context, attr, vhca_id_to_be_accessed, alias_attr->vhca_id);
     993         [ #  # ]:          0 :         MLX5_SET(alias_context, attr, object_id_to_be_accessed, alias_attr->obj_id);
     994                 :            : 
     995                 :            :         key = MLX5_ADDR_OF(alias_context, attr, access_key);
     996                 :          0 :         memcpy(key, alias_attr->access_key, sizeof(alias_attr->access_key));
     997                 :            : 
     998                 :          0 :         devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
     999         [ #  # ]:          0 :         if (!devx_obj->obj) {
    1000                 :          0 :                 DR_LOG(ERR, "Failed to create ALIAS OBJ (syndrome: %#x)",
    1001                 :            :                        mlx5dr_cmd_get_syndrome(out));
    1002                 :            :                 simple_free(devx_obj);
    1003                 :          0 :                 rte_errno = errno;
    1004                 :          0 :                 return NULL;
    1005                 :            :         }
    1006                 :            : 
    1007         [ #  # ]:          0 :         devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
    1008                 :            : 
    1009                 :          0 :         return devx_obj;
    1010                 :            : }
    1011                 :            : 
    1012                 :          0 : int mlx5dr_cmd_generate_wqe(struct ibv_context *ctx,
    1013                 :            :                             struct mlx5dr_cmd_generate_wqe_attr *attr,
    1014                 :            :                             struct mlx5_cqe64 *ret_cqe)
    1015                 :            : {
    1016                 :          0 :         uint32_t out[MLX5_ST_SZ_DW(generate_wqe_out)] = {0};
    1017                 :          0 :         uint32_t in[MLX5_ST_SZ_DW(generate_wqe_in)] = {0};
    1018                 :            :         uint8_t status;
    1019                 :            :         void *ptr;
    1020                 :            :         int ret;
    1021                 :            : 
    1022                 :          0 :         MLX5_SET(generate_wqe_in, in, opcode, MLX5_CMD_OP_GENERATE_WQE);
    1023                 :          0 :         MLX5_SET(generate_wqe_in, in, pdn, attr->pdn);
    1024                 :            : 
    1025                 :            :         ptr = MLX5_ADDR_OF(generate_wqe_in, in, wqe_ctrl);
    1026                 :          0 :         memcpy(ptr, attr->wqe_ctrl, MLX5_FLD_SZ_BYTES(generate_wqe_in, wqe_ctrl));
    1027                 :            : 
    1028                 :            :         ptr = MLX5_ADDR_OF(generate_wqe_in, in, wqe_gta_ctrl);
    1029         [ #  # ]:          0 :         memcpy(ptr, attr->gta_ctrl, MLX5_FLD_SZ_BYTES(generate_wqe_in, wqe_gta_ctrl));
    1030                 :            : 
    1031                 :            :         ptr = MLX5_ADDR_OF(generate_wqe_in, in, wqe_gta_data_0);
    1032                 :          0 :         memcpy(ptr, attr->gta_data_0, MLX5_FLD_SZ_BYTES(generate_wqe_in, wqe_gta_data_0));
    1033                 :            : 
    1034         [ #  # ]:          0 :         if (attr->gta_data_1) {
    1035                 :            :                 ptr = MLX5_ADDR_OF(generate_wqe_in, in, wqe_gta_data_1);
    1036                 :            :                 memcpy(ptr, attr->gta_data_1, MLX5_FLD_SZ_BYTES(generate_wqe_in, wqe_gta_data_1));
    1037                 :            :         }
    1038                 :            : 
    1039                 :          0 :         ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
    1040         [ #  # ]:          0 :         if (ret) {
    1041                 :          0 :                 DR_LOG(ERR, "Failed to write GTA WQE using FW (syndrome: %#x)",
    1042                 :            :                        mlx5dr_cmd_get_syndrome(out));
    1043                 :          0 :                 rte_errno = errno;
    1044                 :          0 :                 return rte_errno;
    1045                 :            :         }
    1046                 :            : 
    1047         [ #  # ]:          0 :         status = MLX5_GET(generate_wqe_out, out, status);
    1048         [ #  # ]:          0 :         if (status) {
    1049                 :          0 :                 DR_LOG(ERR, "Invalid FW CQE status %d", status);
    1050                 :          0 :                 rte_errno = EINVAL;
    1051                 :          0 :                 return rte_errno;
    1052                 :            :         }
    1053                 :            : 
    1054                 :            :         ptr = MLX5_ADDR_OF(generate_wqe_out, out, cqe_data);
    1055                 :            :         memcpy(ret_cqe, ptr, sizeof(*ret_cqe));
    1056                 :            : 
    1057                 :          0 :         return 0;
    1058                 :            : }
    1059                 :            : 
    1060                 :          0 : int mlx5dr_cmd_query_caps(struct ibv_context *ctx,
    1061                 :            :                           struct mlx5dr_cmd_query_caps *caps)
    1062                 :            : {
    1063                 :          0 :         uint32_t out[MLX5_ST_SZ_DW(query_hca_cap_out)] = {0};
    1064                 :          0 :         uint32_t in[MLX5_ST_SZ_DW(query_hca_cap_in)] = {0};
    1065                 :            :         const struct flow_hw_port_info *port_info;
    1066                 :            :         struct ibv_device_attr_ex attr_ex;
    1067                 :            :         u32 res;
    1068                 :            :         int ret;
    1069                 :            : 
    1070                 :          0 :         MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP);
    1071                 :          0 :         MLX5_SET(query_hca_cap_in, in, op_mod,
    1072                 :            :                  MLX5_GET_HCA_CAP_OP_MOD_GENERAL_DEVICE |
    1073                 :            :                  MLX5_HCA_CAP_OPMOD_GET_CUR);
    1074                 :            : 
    1075                 :          0 :         ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
    1076         [ #  # ]:          0 :         if (ret) {
    1077                 :          0 :                 DR_LOG(ERR, "Failed to query device caps");
    1078                 :          0 :                 rte_errno = errno;
    1079                 :          0 :                 return rte_errno;
    1080                 :            :         }
    1081                 :            : 
    1082                 :          0 :         caps->wqe_based_update =
    1083         [ #  # ]:          0 :                 MLX5_GET(query_hca_cap_out, out,
    1084                 :            :                          capability.cmd_hca_cap.wqe_based_flow_table_update_cap);
    1085                 :            : 
    1086         [ #  # ]:          0 :         caps->eswitch_manager = MLX5_GET(query_hca_cap_out, out,
    1087                 :            :                                          capability.cmd_hca_cap.eswitch_manager);
    1088                 :            : 
    1089         [ #  # ]:          0 :         caps->flex_protocols = MLX5_GET(query_hca_cap_out, out,
    1090                 :            :                                         capability.cmd_hca_cap.flex_parser_protocols);
    1091                 :            : 
    1092                 :          0 :         caps->log_header_modify_argument_granularity =
    1093         [ #  # ]:          0 :                 MLX5_GET(query_hca_cap_out, out,
    1094                 :            :                          capability.cmd_hca_cap.log_header_modify_argument_granularity);
    1095                 :            : 
    1096                 :          0 :         caps->log_header_modify_argument_granularity -=
    1097         [ #  # ]:          0 :                         MLX5_GET(query_hca_cap_out, out,
    1098                 :            :                                  capability.cmd_hca_cap.
    1099                 :            :                                  log_header_modify_argument_granularity_offset);
    1100                 :            : 
    1101         [ #  # ]:          0 :         caps->log_header_modify_argument_max_alloc =
    1102                 :          0 :                 MLX5_GET(query_hca_cap_out, out,
    1103                 :            :                          capability.cmd_hca_cap.log_header_modify_argument_max_alloc);
    1104                 :            : 
    1105                 :          0 :         caps->definer_format_sup =
    1106         [ #  # ]:          0 :                 MLX5_GET64(query_hca_cap_out, out,
    1107                 :            :                            capability.cmd_hca_cap.match_definer_format_supported);
    1108                 :            : 
    1109         [ #  # ]:          0 :         caps->vhca_id = MLX5_GET(query_hca_cap_out, out,
    1110                 :            :                                  capability.cmd_hca_cap.vhca_id);
    1111                 :            : 
    1112         [ #  # ]:          0 :         caps->sq_ts_format = MLX5_GET(query_hca_cap_out, out,
    1113                 :            :                                       capability.cmd_hca_cap.sq_ts_format);
    1114                 :            : 
    1115         [ #  # ]:          0 :         caps->ipsec_offload = MLX5_GET(query_hca_cap_out, out,
    1116                 :            :                                       capability.cmd_hca_cap.ipsec_offload);
    1117                 :            : 
    1118         [ #  # ]:          0 :         caps->roce = MLX5_GET(query_hca_cap_out, out, capability.cmd_hca_cap.roce);
    1119                 :            : 
    1120         [ #  # ]:          0 :         MLX5_SET(query_hca_cap_in, in, op_mod,
    1121                 :            :                  MLX5_GET_HCA_CAP_OP_MOD_GENERAL_DEVICE_2 |
    1122                 :            :                  MLX5_HCA_CAP_OPMOD_GET_CUR);
    1123                 :            : 
    1124                 :          0 :         ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
    1125         [ #  # ]:          0 :         if (ret) {
    1126                 :          0 :                 DR_LOG(ERR, "Failed to query device caps");
    1127                 :          0 :                 rte_errno = errno;
    1128                 :          0 :                 return rte_errno;
    1129                 :            :         }
    1130                 :            : 
    1131         [ #  # ]:          0 :         caps->full_dw_jumbo_support = MLX5_GET(query_hca_cap_out, out,
    1132                 :            :                                                capability.cmd_hca_cap_2.
    1133                 :            :                                                format_select_dw_8_6_ext);
    1134                 :            : 
    1135         [ #  # ]:          0 :         caps->format_select_gtpu_dw_0 = MLX5_GET(query_hca_cap_out, out,
    1136                 :            :                                                  capability.cmd_hca_cap_2.
    1137                 :            :                                                  format_select_dw_gtpu_dw_0);
    1138                 :            : 
    1139         [ #  # ]:          0 :         caps->format_select_gtpu_dw_1 = MLX5_GET(query_hca_cap_out, out,
    1140                 :            :                                                  capability.cmd_hca_cap_2.
    1141                 :            :                                                  format_select_dw_gtpu_dw_1);
    1142                 :            : 
    1143         [ #  # ]:          0 :         caps->format_select_gtpu_dw_2 = MLX5_GET(query_hca_cap_out, out,
    1144                 :            :                                                  capability.cmd_hca_cap_2.
    1145                 :            :                                                  format_select_dw_gtpu_dw_2);
    1146                 :            : 
    1147         [ #  # ]:          0 :         caps->format_select_gtpu_ext_dw_0 = MLX5_GET(query_hca_cap_out, out,
    1148                 :            :                                                      capability.cmd_hca_cap_2.
    1149                 :            :                                                      format_select_dw_gtpu_first_ext_dw_0);
    1150                 :            : 
    1151         [ #  # ]:          0 :         caps->supp_type_gen_wqe = MLX5_GET(query_hca_cap_out, out,
    1152                 :            :                                            capability.cmd_hca_cap_2.
    1153                 :            :                                            generate_wqe_type);
    1154                 :            : 
    1155                 :            :         /* check cross-VHCA support in cap2 */
    1156                 :            :         res =
    1157         [ #  # ]:          0 :         MLX5_GET(query_hca_cap_out, out,
    1158                 :            :                 capability.cmd_hca_cap_2.cross_vhca_object_to_object_supported);
    1159                 :            : 
    1160                 :            :         caps->cross_vhca_resources = (res & MLX5_CROSS_VHCA_OBJ_TO_OBJ_TYPE_STC_TO_TIR) &&
    1161                 :          0 :                                      (res & MLX5_CROSS_VHCA_OBJ_TO_OBJ_TYPE_STC_TO_FT) &&
    1162                 :            :                                      (res & MLX5_CROSS_VHCA_OBJ_TO_OBJ_TYPE_FT_TO_RTC);
    1163                 :            : 
    1164                 :            :         res =
    1165         [ #  # ]:          0 :         MLX5_GET(query_hca_cap_out, out,
    1166                 :            :                 capability.cmd_hca_cap_2.allowed_object_for_other_vhca_access);
    1167                 :            : 
    1168                 :          0 :         caps->cross_vhca_resources &= (res & MLX5_CROSS_VHCA_ALLOWED_OBJS_TIR) &&
    1169                 :          0 :                                       (res & MLX5_CROSS_VHCA_ALLOWED_OBJS_FT) &&
    1170                 :            :                                       (res & MLX5_CROSS_VHCA_ALLOWED_OBJS_RTC);
    1171                 :            : 
    1172         [ #  # ]:          0 :         caps->flow_table_hash_type = MLX5_GET(query_hca_cap_out, out,
    1173                 :            :                                               capability.cmd_hca_cap_2.flow_table_hash_type);
    1174                 :            : 
    1175         [ #  # ]:          0 :         caps->encap_entropy_hash_type = MLX5_GET(query_hca_cap_out, out,
    1176                 :            :                                                  capability.cmd_hca_cap_2.encap_entropy_hash_type);
    1177                 :            : 
    1178         [ #  # ]:          0 :         MLX5_SET(query_hca_cap_in, in, op_mod,
    1179                 :            :                  MLX5_GET_HCA_CAP_OP_MOD_NIC_FLOW_TABLE |
    1180                 :            :                  MLX5_HCA_CAP_OPMOD_GET_CUR);
    1181                 :            : 
    1182                 :          0 :         ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
    1183         [ #  # ]:          0 :         if (ret) {
    1184                 :          0 :                 DR_LOG(ERR, "Failed to query flow table caps");
    1185                 :          0 :                 rte_errno = errno;
    1186                 :          0 :                 return rte_errno;
    1187                 :            :         }
    1188                 :            : 
    1189         [ #  # ]:          0 :         caps->nic_ft.max_level = MLX5_GET(query_hca_cap_out, out,
    1190                 :            :                                           capability.flow_table_nic_cap.
    1191                 :            :                                           flow_table_properties_nic_receive.max_ft_level);
    1192                 :            : 
    1193         [ #  # ]:          0 :         caps->nic_ft.reparse = MLX5_GET(query_hca_cap_out, out,
    1194                 :            :                                         capability.flow_table_nic_cap.
    1195                 :            :                                         flow_table_properties_nic_receive.reparse);
    1196                 :            : 
    1197         [ #  # ]:          0 :         caps->nic_ft.ignore_flow_level_rtc_valid =
    1198                 :          0 :                 MLX5_GET(query_hca_cap_out,
    1199                 :            :                          out,
    1200                 :            :                          capability.flow_table_nic_cap.
    1201                 :            :                          flow_table_properties_nic_receive.ignore_flow_level_rtc_valid);
    1202                 :            : 
    1203                 :            :         /* check cross-VHCA support in flow table properties */
    1204                 :            :         res =
    1205         [ #  # ]:          0 :         MLX5_GET(query_hca_cap_out, out,
    1206                 :            :                 capability.flow_table_nic_cap.flow_table_properties_nic_receive.cross_vhca_object);
    1207                 :          0 :         caps->cross_vhca_resources &= res;
    1208                 :            : 
    1209         [ #  # ]:          0 :         if (caps->wqe_based_update) {
    1210         [ #  # ]:          0 :                 MLX5_SET(query_hca_cap_in, in, op_mod,
    1211                 :            :                          MLX5_GET_HCA_CAP_OP_MOD_WQE_BASED_FLOW_TABLE |
    1212                 :            :                          MLX5_HCA_CAP_OPMOD_GET_CUR);
    1213                 :            : 
    1214                 :          0 :                 ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
    1215         [ #  # ]:          0 :                 if (ret) {
    1216                 :          0 :                         DR_LOG(ERR, "Failed to query WQE based FT caps");
    1217                 :          0 :                         rte_errno = errno;
    1218                 :          0 :                         return rte_errno;
    1219                 :            :                 }
    1220                 :            : 
    1221         [ #  # ]:          0 :                 caps->rtc_reparse_mode = MLX5_GET(query_hca_cap_out, out,
    1222                 :            :                                                   capability.wqe_based_flow_table_cap.
    1223                 :            :                                                   rtc_reparse_mode);
    1224                 :            : 
    1225         [ #  # ]:          0 :                 caps->ste_format = MLX5_GET(query_hca_cap_out, out,
    1226                 :            :                                             capability.wqe_based_flow_table_cap.
    1227                 :            :                                             ste_format);
    1228                 :            : 
    1229         [ #  # ]:          0 :                 caps->rtc_index_mode = MLX5_GET(query_hca_cap_out, out,
    1230                 :            :                                                 capability.wqe_based_flow_table_cap.
    1231                 :            :                                                 rtc_index_mode);
    1232                 :            : 
    1233         [ #  # ]:          0 :                 caps->rtc_log_depth_max = MLX5_GET(query_hca_cap_out, out,
    1234                 :            :                                                    capability.wqe_based_flow_table_cap.
    1235                 :            :                                                    rtc_log_depth_max);
    1236                 :            : 
    1237         [ #  # ]:          0 :                 caps->ste_alloc_log_max = MLX5_GET(query_hca_cap_out, out,
    1238                 :            :                                                    capability.wqe_based_flow_table_cap.
    1239                 :            :                                                    ste_alloc_log_max);
    1240                 :            : 
    1241         [ #  # ]:          0 :                 caps->ste_alloc_log_gran = MLX5_GET(query_hca_cap_out, out,
    1242                 :            :                                                     capability.wqe_based_flow_table_cap.
    1243                 :            :                                                     ste_alloc_log_granularity);
    1244                 :            : 
    1245         [ #  # ]:          0 :                 caps->trivial_match_definer = MLX5_GET(query_hca_cap_out, out,
    1246                 :            :                                                        capability.wqe_based_flow_table_cap.
    1247                 :            :                                                        trivial_match_definer);
    1248                 :            : 
    1249         [ #  # ]:          0 :                 caps->stc_alloc_log_max = MLX5_GET(query_hca_cap_out, out,
    1250                 :            :                                                    capability.wqe_based_flow_table_cap.
    1251                 :            :                                                    stc_alloc_log_max);
    1252                 :            : 
    1253         [ #  # ]:          0 :                 caps->stc_alloc_log_gran = MLX5_GET(query_hca_cap_out, out,
    1254                 :            :                                                     capability.wqe_based_flow_table_cap.
    1255                 :            :                                                     stc_alloc_log_granularity);
    1256                 :            : 
    1257         [ #  # ]:          0 :                 caps->rtc_hash_split_table = MLX5_GET(query_hca_cap_out, out,
    1258                 :            :                                                       capability.wqe_based_flow_table_cap.
    1259                 :            :                                                       rtc_hash_split_table);
    1260                 :            : 
    1261         [ #  # ]:          0 :                 caps->rtc_linear_lookup_table = MLX5_GET(query_hca_cap_out, out,
    1262                 :            :                                                          capability.wqe_based_flow_table_cap.
    1263                 :            :                                                          rtc_linear_lookup_table);
    1264                 :            : 
    1265         [ #  # ]:          0 :                 caps->access_index_mode = MLX5_GET(query_hca_cap_out, out,
    1266                 :            :                                                    capability.wqe_based_flow_table_cap.
    1267                 :            :                                                    access_index_mode);
    1268                 :            : 
    1269         [ #  # ]:          0 :                 caps->linear_match_definer = MLX5_GET(query_hca_cap_out, out,
    1270                 :            :                                                       capability.wqe_based_flow_table_cap.
    1271                 :            :                                                       linear_match_definer_reg_c3);
    1272                 :            : 
    1273         [ #  # ]:          0 :                 caps->rtc_max_hash_def_gen_wqe = MLX5_GET(query_hca_cap_out, out,
    1274                 :            :                                                           capability.wqe_based_flow_table_cap.
    1275                 :            :                                                           rtc_max_num_hash_definer_gen_wqe);
    1276                 :            : 
    1277         [ #  # ]:          0 :                 caps->supp_ste_format_gen_wqe = MLX5_GET(query_hca_cap_out, out,
    1278                 :            :                                                          capability.wqe_based_flow_table_cap.
    1279                 :            :                                                          ste_format_gen_wqe);
    1280                 :            : 
    1281         [ #  # ]:          0 :                 caps->fdb_tir_stc = MLX5_GET(query_hca_cap_out, out,
    1282                 :            :                                              capability.wqe_based_flow_table_cap.
    1283                 :            :                                              fdb_jump_to_tir_stc);
    1284                 :            : 
    1285         [ #  # ]:          0 :                 caps->fdb_unified_en = MLX5_GET(query_hca_cap_out, out,
    1286                 :            :                                                 capability.wqe_based_flow_table_cap.
    1287                 :            :                                                 fdb_unified_en);
    1288                 :            : 
    1289         [ #  # ]:          0 :                 caps->stc_action_type_63_0 = MLX5_GET64(query_hca_cap_out,
    1290                 :            :                                                         out,
    1291                 :            :                                         capability.wqe_based_flow_table_cap.stc_action_type_63_0);
    1292                 :            : 
    1293         [ #  # ]:          0 :                 caps->stc_action_type_127_64 = MLX5_GET64(query_hca_cap_out,
    1294                 :            :                                                           out,
    1295                 :            :                                         capability.wqe_based_flow_table_cap.stc_action_type_127_64);
    1296                 :            :         }
    1297                 :            : 
    1298         [ #  # ]:          0 :         if (caps->eswitch_manager) {
    1299         [ #  # ]:          0 :                 MLX5_SET(query_hca_cap_in, in, op_mod,
    1300                 :            :                          MLX5_GET_HCA_CAP_OP_MOD_ESW_FLOW_TABLE |
    1301                 :            :                          MLX5_HCA_CAP_OPMOD_GET_CUR);
    1302                 :            : 
    1303                 :          0 :                 ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
    1304         [ #  # ]:          0 :                 if (ret) {
    1305                 :          0 :                         DR_LOG(ERR, "Failed to query flow table esw caps");
    1306                 :          0 :                         rte_errno = errno;
    1307                 :          0 :                         return rte_errno;
    1308                 :            :                 }
    1309                 :            : 
    1310         [ #  # ]:          0 :                 caps->fdb_ft.max_level = MLX5_GET(query_hca_cap_out, out,
    1311                 :            :                                                   capability.flow_table_nic_cap.
    1312                 :            :                                                   flow_table_properties_nic_receive.max_ft_level);
    1313                 :            : 
    1314         [ #  # ]:          0 :                 caps->fdb_ft.reparse = MLX5_GET(query_hca_cap_out, out,
    1315                 :            :                                                 capability.flow_table_nic_cap.
    1316                 :            :                                                 flow_table_properties_nic_receive.reparse);
    1317                 :            : 
    1318         [ #  # ]:          0 :                 MLX5_SET(query_hca_cap_in, in, op_mod,
    1319                 :            :                          MLX5_SET_HCA_CAP_OP_MOD_ESW | MLX5_HCA_CAP_OPMOD_GET_CUR);
    1320                 :            : 
    1321                 :          0 :                 ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
    1322         [ #  # ]:          0 :                 if (ret) {
    1323                 :          0 :                         DR_LOG(ERR, "Query eswitch capabilities failed %d", ret);
    1324                 :          0 :                         rte_errno = errno;
    1325                 :          0 :                         return rte_errno;
    1326                 :            :                 }
    1327                 :            : 
    1328   [ #  #  #  # ]:          0 :                 if (MLX5_GET(query_hca_cap_out, out,
    1329                 :            :                              capability.esw_cap.esw_manager_vport_number_valid))
    1330                 :          0 :                         caps->eswitch_manager_vport_number =
    1331         [ #  # ]:          0 :                         MLX5_GET(query_hca_cap_out, out,
    1332                 :            :                                  capability.esw_cap.esw_manager_vport_number);
    1333                 :            : 
    1334         [ #  # ]:          0 :                 caps->merged_eswitch = MLX5_GET(query_hca_cap_out, out,
    1335                 :            :                                                 capability.esw_cap.merged_eswitch);
    1336                 :            :         }
    1337                 :            : 
    1338         [ #  # ]:          0 :         if (caps->roce) {
    1339         [ #  # ]:          0 :                 MLX5_SET(query_hca_cap_in, in, op_mod,
    1340                 :            :                          MLX5_GET_HCA_CAP_OP_MOD_ROCE |
    1341                 :            :                          MLX5_HCA_CAP_OPMOD_GET_CUR);
    1342                 :            : 
    1343                 :          0 :                 ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
    1344         [ #  # ]:          0 :                 if (ret) {
    1345                 :          0 :                         DR_LOG(ERR, "Failed to query roce caps");
    1346                 :          0 :                         rte_errno = errno;
    1347                 :          0 :                         return rte_errno;
    1348                 :            :                 }
    1349                 :            : 
    1350         [ #  # ]:          0 :                 caps->roce_max_src_udp_port = MLX5_GET(query_hca_cap_out, out,
    1351                 :            :                                                 capability.roce_caps.r_roce_max_src_udp_port);
    1352         [ #  # ]:          0 :                 caps->roce_min_src_udp_port = MLX5_GET(query_hca_cap_out, out,
    1353                 :            :                                                 capability.roce_caps.r_roce_min_src_udp_port);
    1354                 :            :         }
    1355                 :            : 
    1356                 :          0 :         ret = mlx5_glue->query_device_ex(ctx, NULL, &attr_ex);
    1357         [ #  # ]:          0 :         if (ret) {
    1358                 :          0 :                 DR_LOG(ERR, "Failed to query device attributes");
    1359                 :          0 :                 rte_errno = ret;
    1360                 :          0 :                 return rte_errno;
    1361                 :            :         }
    1362                 :            : 
    1363                 :          0 :         strlcpy(caps->fw_ver, attr_ex.orig_attr.fw_ver, sizeof(caps->fw_ver));
    1364                 :            : 
    1365                 :            :         port_info = flow_hw_get_wire_port(ctx);
    1366         [ #  # ]:          0 :         if (port_info)
    1367                 :          0 :                 caps->wire_regc_mask = port_info->regc_mask;
    1368                 :            :         else
    1369                 :          0 :                 DR_LOG(INFO, "Failed to query wire port regc value");
    1370                 :            : 
    1371                 :            :         return ret;
    1372                 :            : }
    1373                 :            : 
    1374                 :          0 : int mlx5dr_cmd_query_ib_port(struct ibv_context *ctx,
    1375                 :            :                              struct mlx5dr_cmd_query_vport_caps *vport_caps,
    1376                 :            :                              uint32_t port_num)
    1377                 :            : {
    1378                 :          0 :         struct mlx5_port_info port_info = {0};
    1379                 :            :         uint32_t flags;
    1380                 :            :         int ret;
    1381                 :            : 
    1382                 :            :         flags = MLX5_PORT_QUERY_VPORT | MLX5_PORT_QUERY_ESW_OWNER_VHCA_ID;
    1383                 :            : 
    1384                 :          0 :         ret = mlx5_glue->devx_port_query(ctx, port_num, &port_info);
    1385                 :            :         /* Check if query succeed and vport is enabled */
    1386   [ #  #  #  # ]:          0 :         if (ret || (port_info.query_flags & flags) != flags) {
    1387                 :          0 :                 rte_errno = ENOTSUP;
    1388                 :          0 :                 return rte_errno;
    1389                 :            :         }
    1390                 :            : 
    1391                 :          0 :         vport_caps->vport_num = port_info.vport_id;
    1392                 :          0 :         vport_caps->esw_owner_vhca_id = port_info.esw_owner_vhca_id;
    1393                 :            : 
    1394                 :          0 :         return 0;
    1395                 :            : }

Generated by: LCOV version 1.14