1365cdf5fSErez Shitrit /* SPDX-License-Identifier: BSD-3-Clause 2365cdf5fSErez Shitrit * Copyright (c) 2022 NVIDIA Corporation & Affiliates 3365cdf5fSErez Shitrit */ 4365cdf5fSErez Shitrit 5365cdf5fSErez Shitrit #include "mlx5dr_internal.h" 6365cdf5fSErez Shitrit 7365cdf5fSErez Shitrit int mlx5dr_cmd_destroy_obj(struct mlx5dr_devx_obj *devx_obj) 8365cdf5fSErez Shitrit { 9365cdf5fSErez Shitrit int ret; 10365cdf5fSErez Shitrit 11365cdf5fSErez Shitrit ret = mlx5_glue->devx_obj_destroy(devx_obj->obj); 12365cdf5fSErez Shitrit simple_free(devx_obj); 13365cdf5fSErez Shitrit 14365cdf5fSErez Shitrit return ret; 15365cdf5fSErez Shitrit } 16365cdf5fSErez Shitrit 17365cdf5fSErez Shitrit struct mlx5dr_devx_obj * 18365cdf5fSErez Shitrit mlx5dr_cmd_flow_table_create(struct ibv_context *ctx, 19365cdf5fSErez Shitrit struct mlx5dr_cmd_ft_create_attr *ft_attr) 20365cdf5fSErez Shitrit { 21365cdf5fSErez Shitrit uint32_t out[MLX5_ST_SZ_DW(create_flow_table_out)] = {0}; 22365cdf5fSErez Shitrit uint32_t in[MLX5_ST_SZ_DW(create_flow_table_in)] = {0}; 23365cdf5fSErez Shitrit struct mlx5dr_devx_obj *devx_obj; 24365cdf5fSErez Shitrit void *ft_ctx; 25365cdf5fSErez Shitrit 26365cdf5fSErez Shitrit devx_obj = simple_malloc(sizeof(*devx_obj)); 27365cdf5fSErez Shitrit if (!devx_obj) { 28365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to allocate memory for flow table object"); 29365cdf5fSErez Shitrit rte_errno = ENOMEM; 30365cdf5fSErez Shitrit return NULL; 31365cdf5fSErez Shitrit } 32365cdf5fSErez Shitrit 33365cdf5fSErez Shitrit MLX5_SET(create_flow_table_in, in, opcode, MLX5_CMD_OP_CREATE_FLOW_TABLE); 34365cdf5fSErez Shitrit MLX5_SET(create_flow_table_in, in, table_type, ft_attr->type); 35365cdf5fSErez Shitrit 36365cdf5fSErez Shitrit ft_ctx = MLX5_ADDR_OF(create_flow_table_in, in, flow_table_context); 37365cdf5fSErez Shitrit MLX5_SET(flow_table_context, ft_ctx, level, ft_attr->level); 38365cdf5fSErez Shitrit MLX5_SET(flow_table_context, ft_ctx, rtc_valid, ft_attr->rtc_valid); 39365cdf5fSErez Shitrit 40365cdf5fSErez Shitrit devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out)); 41365cdf5fSErez Shitrit if (!devx_obj->obj) { 42365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to create FT"); 43365cdf5fSErez Shitrit simple_free(devx_obj); 44365cdf5fSErez Shitrit rte_errno = errno; 45365cdf5fSErez Shitrit return NULL; 46365cdf5fSErez Shitrit } 47365cdf5fSErez Shitrit 48365cdf5fSErez Shitrit devx_obj->id = MLX5_GET(create_flow_table_out, out, table_id); 49365cdf5fSErez Shitrit 50365cdf5fSErez Shitrit return devx_obj; 51365cdf5fSErez Shitrit } 52365cdf5fSErez Shitrit 53365cdf5fSErez Shitrit int 54365cdf5fSErez Shitrit mlx5dr_cmd_flow_table_modify(struct mlx5dr_devx_obj *devx_obj, 55365cdf5fSErez Shitrit struct mlx5dr_cmd_ft_modify_attr *ft_attr) 56365cdf5fSErez Shitrit { 57365cdf5fSErez Shitrit uint32_t out[MLX5_ST_SZ_DW(modify_flow_table_out)] = {0}; 58365cdf5fSErez Shitrit uint32_t in[MLX5_ST_SZ_DW(modify_flow_table_in)] = {0}; 59365cdf5fSErez Shitrit void *ft_ctx; 60365cdf5fSErez Shitrit int ret; 61365cdf5fSErez Shitrit 62365cdf5fSErez Shitrit MLX5_SET(modify_flow_table_in, in, opcode, MLX5_CMD_OP_MODIFY_FLOW_TABLE); 63365cdf5fSErez Shitrit MLX5_SET(modify_flow_table_in, in, table_type, ft_attr->type); 64365cdf5fSErez Shitrit MLX5_SET(modify_flow_table_in, in, modify_field_select, ft_attr->modify_fs); 65365cdf5fSErez Shitrit MLX5_SET(modify_flow_table_in, in, table_id, devx_obj->id); 66365cdf5fSErez Shitrit 67365cdf5fSErez Shitrit ft_ctx = MLX5_ADDR_OF(modify_flow_table_in, in, flow_table_context); 68365cdf5fSErez Shitrit 69365cdf5fSErez Shitrit MLX5_SET(flow_table_context, ft_ctx, table_miss_action, ft_attr->table_miss_action); 70365cdf5fSErez Shitrit MLX5_SET(flow_table_context, ft_ctx, table_miss_id, ft_attr->table_miss_id); 71365cdf5fSErez Shitrit MLX5_SET(flow_table_context, ft_ctx, rtc_id_0, ft_attr->rtc_id_0); 72365cdf5fSErez Shitrit MLX5_SET(flow_table_context, ft_ctx, rtc_id_1, ft_attr->rtc_id_1); 73365cdf5fSErez Shitrit 74365cdf5fSErez Shitrit ret = mlx5_glue->devx_obj_modify(devx_obj->obj, in, sizeof(in), out, sizeof(out)); 75365cdf5fSErez Shitrit if (ret) { 76365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to modify FT"); 77365cdf5fSErez Shitrit rte_errno = errno; 78365cdf5fSErez Shitrit } 79365cdf5fSErez Shitrit 80365cdf5fSErez Shitrit return ret; 81365cdf5fSErez Shitrit } 82365cdf5fSErez Shitrit 83365cdf5fSErez Shitrit static struct mlx5dr_devx_obj * 84365cdf5fSErez Shitrit mlx5dr_cmd_flow_group_create(struct ibv_context *ctx, 85365cdf5fSErez Shitrit struct mlx5dr_cmd_fg_attr *fg_attr) 86365cdf5fSErez Shitrit { 87365cdf5fSErez Shitrit uint32_t out[MLX5_ST_SZ_DW(create_flow_group_out)] = {0}; 88365cdf5fSErez Shitrit uint32_t in[MLX5_ST_SZ_DW(create_flow_group_in)] = {0}; 89365cdf5fSErez Shitrit struct mlx5dr_devx_obj *devx_obj; 90365cdf5fSErez Shitrit 91365cdf5fSErez Shitrit devx_obj = simple_malloc(sizeof(*devx_obj)); 92365cdf5fSErez Shitrit if (!devx_obj) { 93365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to allocate memory for flow group object"); 94365cdf5fSErez Shitrit rte_errno = ENOMEM; 95365cdf5fSErez Shitrit return NULL; 96365cdf5fSErez Shitrit } 97365cdf5fSErez Shitrit 98365cdf5fSErez Shitrit MLX5_SET(create_flow_group_in, in, opcode, MLX5_CMD_OP_CREATE_FLOW_GROUP); 99365cdf5fSErez Shitrit MLX5_SET(create_flow_group_in, in, table_type, fg_attr->table_type); 100365cdf5fSErez Shitrit MLX5_SET(create_flow_group_in, in, table_id, fg_attr->table_id); 101365cdf5fSErez Shitrit 102365cdf5fSErez Shitrit devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out)); 103365cdf5fSErez Shitrit if (!devx_obj->obj) { 104365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to create Flow group"); 105365cdf5fSErez Shitrit simple_free(devx_obj); 106365cdf5fSErez Shitrit rte_errno = errno; 107365cdf5fSErez Shitrit return NULL; 108365cdf5fSErez Shitrit } 109365cdf5fSErez Shitrit 110365cdf5fSErez Shitrit devx_obj->id = MLX5_GET(create_flow_group_out, out, group_id); 111365cdf5fSErez Shitrit 112365cdf5fSErez Shitrit return devx_obj; 113365cdf5fSErez Shitrit } 114365cdf5fSErez Shitrit 115365cdf5fSErez Shitrit static struct mlx5dr_devx_obj * 116365cdf5fSErez Shitrit mlx5dr_cmd_set_vport_fte(struct ibv_context *ctx, 117365cdf5fSErez Shitrit uint32_t table_type, 118365cdf5fSErez Shitrit uint32_t table_id, 119365cdf5fSErez Shitrit uint32_t group_id, 120365cdf5fSErez Shitrit uint32_t vport_id) 121365cdf5fSErez Shitrit { 122365cdf5fSErez Shitrit uint32_t in[MLX5_ST_SZ_DW(set_fte_in) + MLX5_ST_SZ_DW(dest_format)] = {0}; 123365cdf5fSErez Shitrit uint32_t out[MLX5_ST_SZ_DW(set_fte_out)] = {0}; 124365cdf5fSErez Shitrit struct mlx5dr_devx_obj *devx_obj; 125365cdf5fSErez Shitrit void *in_flow_context; 126365cdf5fSErez Shitrit void *in_dests; 127365cdf5fSErez Shitrit 128365cdf5fSErez Shitrit devx_obj = simple_malloc(sizeof(*devx_obj)); 129365cdf5fSErez Shitrit if (!devx_obj) { 130365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to allocate memory for fte object"); 131365cdf5fSErez Shitrit rte_errno = ENOMEM; 132365cdf5fSErez Shitrit return NULL; 133365cdf5fSErez Shitrit } 134365cdf5fSErez Shitrit 135365cdf5fSErez Shitrit MLX5_SET(set_fte_in, in, opcode, MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY); 136365cdf5fSErez Shitrit MLX5_SET(set_fte_in, in, table_type, table_type); 137365cdf5fSErez Shitrit MLX5_SET(set_fte_in, in, table_id, table_id); 138365cdf5fSErez Shitrit 139365cdf5fSErez Shitrit in_flow_context = MLX5_ADDR_OF(set_fte_in, in, flow_context); 140365cdf5fSErez Shitrit MLX5_SET(flow_context, in_flow_context, group_id, group_id); 141365cdf5fSErez Shitrit MLX5_SET(flow_context, in_flow_context, destination_list_size, 1); 142365cdf5fSErez Shitrit MLX5_SET(flow_context, in_flow_context, action, MLX5_FLOW_CONTEXT_ACTION_FWD_DEST); 143365cdf5fSErez Shitrit 144365cdf5fSErez Shitrit in_dests = MLX5_ADDR_OF(flow_context, in_flow_context, destination); 145365cdf5fSErez Shitrit MLX5_SET(dest_format, in_dests, destination_type, 146365cdf5fSErez Shitrit MLX5_FLOW_DESTINATION_TYPE_VPORT); 147365cdf5fSErez Shitrit MLX5_SET(dest_format, in_dests, destination_id, vport_id); 148365cdf5fSErez Shitrit 149365cdf5fSErez Shitrit devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out)); 150365cdf5fSErez Shitrit if (!devx_obj->obj) { 151365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to create FTE"); 152365cdf5fSErez Shitrit simple_free(devx_obj); 153365cdf5fSErez Shitrit rte_errno = errno; 154365cdf5fSErez Shitrit return NULL; 155365cdf5fSErez Shitrit } 156365cdf5fSErez Shitrit 157365cdf5fSErez Shitrit return devx_obj; 158365cdf5fSErez Shitrit } 159365cdf5fSErez Shitrit 160365cdf5fSErez Shitrit void mlx5dr_cmd_miss_ft_destroy(struct mlx5dr_cmd_forward_tbl *tbl) 161365cdf5fSErez Shitrit { 162365cdf5fSErez Shitrit mlx5dr_cmd_destroy_obj(tbl->fte); 163365cdf5fSErez Shitrit mlx5dr_cmd_destroy_obj(tbl->fg); 164365cdf5fSErez Shitrit mlx5dr_cmd_destroy_obj(tbl->ft); 165365cdf5fSErez Shitrit } 166365cdf5fSErez Shitrit 167365cdf5fSErez Shitrit struct mlx5dr_cmd_forward_tbl * 168365cdf5fSErez Shitrit mlx5dr_cmd_miss_ft_create(struct ibv_context *ctx, 169365cdf5fSErez Shitrit struct mlx5dr_cmd_ft_create_attr *ft_attr, 170365cdf5fSErez Shitrit uint32_t vport) 171365cdf5fSErez Shitrit { 172365cdf5fSErez Shitrit struct mlx5dr_cmd_fg_attr fg_attr = {0}; 173365cdf5fSErez Shitrit struct mlx5dr_cmd_forward_tbl *tbl; 174365cdf5fSErez Shitrit 175365cdf5fSErez Shitrit tbl = simple_calloc(1, sizeof(*tbl)); 176365cdf5fSErez Shitrit if (!tbl) { 177365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to allocate memory for forward default"); 178365cdf5fSErez Shitrit rte_errno = ENOMEM; 179365cdf5fSErez Shitrit return NULL; 180365cdf5fSErez Shitrit } 181365cdf5fSErez Shitrit 182365cdf5fSErez Shitrit tbl->ft = mlx5dr_cmd_flow_table_create(ctx, ft_attr); 183365cdf5fSErez Shitrit if (!tbl->ft) { 184365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to create FT for miss-table"); 185365cdf5fSErez Shitrit goto free_tbl; 186365cdf5fSErez Shitrit } 187365cdf5fSErez Shitrit 188365cdf5fSErez Shitrit fg_attr.table_id = tbl->ft->id; 189365cdf5fSErez Shitrit fg_attr.table_type = ft_attr->type; 190365cdf5fSErez Shitrit 191365cdf5fSErez Shitrit tbl->fg = mlx5dr_cmd_flow_group_create(ctx, &fg_attr); 192365cdf5fSErez Shitrit if (!tbl->fg) { 193365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to create FG for miss-table"); 194365cdf5fSErez Shitrit goto free_ft; 195365cdf5fSErez Shitrit } 196365cdf5fSErez Shitrit 197365cdf5fSErez Shitrit tbl->fte = mlx5dr_cmd_set_vport_fte(ctx, ft_attr->type, tbl->ft->id, tbl->fg->id, vport); 198365cdf5fSErez Shitrit if (!tbl->fte) { 199365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to create FTE for miss-table"); 200365cdf5fSErez Shitrit goto free_fg; 201365cdf5fSErez Shitrit } 202365cdf5fSErez Shitrit return tbl; 203365cdf5fSErez Shitrit 204365cdf5fSErez Shitrit free_fg: 205365cdf5fSErez Shitrit mlx5dr_cmd_destroy_obj(tbl->fg); 206365cdf5fSErez Shitrit free_ft: 207365cdf5fSErez Shitrit mlx5dr_cmd_destroy_obj(tbl->ft); 208365cdf5fSErez Shitrit free_tbl: 209365cdf5fSErez Shitrit simple_free(tbl); 210365cdf5fSErez Shitrit return NULL; 211365cdf5fSErez Shitrit } 212365cdf5fSErez Shitrit 213365cdf5fSErez Shitrit void mlx5dr_cmd_set_attr_connect_miss_tbl(struct mlx5dr_context *ctx, 214365cdf5fSErez Shitrit uint32_t fw_ft_type, 215365cdf5fSErez Shitrit enum mlx5dr_table_type type, 216365cdf5fSErez Shitrit struct mlx5dr_cmd_ft_modify_attr *ft_attr) 217365cdf5fSErez Shitrit { 218365cdf5fSErez Shitrit struct mlx5dr_devx_obj *default_miss_tbl; 219365cdf5fSErez Shitrit 220365cdf5fSErez Shitrit if (type != MLX5DR_TABLE_TYPE_FDB) 221365cdf5fSErez Shitrit return; 222365cdf5fSErez Shitrit 223365cdf5fSErez Shitrit default_miss_tbl = ctx->common_res[type].default_miss->ft; 224365cdf5fSErez Shitrit if (!default_miss_tbl) { 225365cdf5fSErez Shitrit assert(false); 226365cdf5fSErez Shitrit return; 227365cdf5fSErez Shitrit } 228365cdf5fSErez Shitrit ft_attr->modify_fs = MLX5_IFC_MODIFY_FLOW_TABLE_MISS_ACTION; 229365cdf5fSErez Shitrit ft_attr->type = fw_ft_type; 230365cdf5fSErez Shitrit ft_attr->table_miss_action = MLX5_IFC_MODIFY_FLOW_TABLE_MISS_ACTION_GOTO_TBL; 231365cdf5fSErez Shitrit ft_attr->table_miss_id = default_miss_tbl->id; 232365cdf5fSErez Shitrit } 233365cdf5fSErez Shitrit 234365cdf5fSErez Shitrit struct mlx5dr_devx_obj * 235365cdf5fSErez Shitrit mlx5dr_cmd_rtc_create(struct ibv_context *ctx, 236365cdf5fSErez Shitrit struct mlx5dr_cmd_rtc_create_attr *rtc_attr) 237365cdf5fSErez Shitrit { 238365cdf5fSErez Shitrit uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; 239365cdf5fSErez Shitrit uint32_t in[MLX5_ST_SZ_DW(create_rtc_in)] = {0}; 240365cdf5fSErez Shitrit struct mlx5dr_devx_obj *devx_obj; 241365cdf5fSErez Shitrit void *attr; 242365cdf5fSErez Shitrit 243365cdf5fSErez Shitrit devx_obj = simple_malloc(sizeof(*devx_obj)); 244365cdf5fSErez Shitrit if (!devx_obj) { 245365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to allocate memory for RTC object"); 246365cdf5fSErez Shitrit rte_errno = ENOMEM; 247365cdf5fSErez Shitrit return NULL; 248365cdf5fSErez Shitrit } 249365cdf5fSErez Shitrit 250365cdf5fSErez Shitrit attr = MLX5_ADDR_OF(create_rtc_in, in, hdr); 251365cdf5fSErez Shitrit MLX5_SET(general_obj_in_cmd_hdr, 252365cdf5fSErez Shitrit attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT); 253365cdf5fSErez Shitrit MLX5_SET(general_obj_in_cmd_hdr, 254365cdf5fSErez Shitrit attr, obj_type, MLX5_GENERAL_OBJ_TYPE_RTC); 255365cdf5fSErez Shitrit 256365cdf5fSErez Shitrit attr = MLX5_ADDR_OF(create_rtc_in, in, rtc); 257365cdf5fSErez Shitrit MLX5_SET(rtc, attr, ste_format, rtc_attr->is_jumbo ? 258365cdf5fSErez Shitrit MLX5_IFC_RTC_STE_FORMAT_11DW : 259365cdf5fSErez Shitrit MLX5_IFC_RTC_STE_FORMAT_8DW); 260365cdf5fSErez Shitrit MLX5_SET(rtc, attr, pd, rtc_attr->pd); 261365cdf5fSErez Shitrit MLX5_SET(rtc, attr, update_index_mode, rtc_attr->update_index_mode); 262365cdf5fSErez Shitrit MLX5_SET(rtc, attr, log_depth, rtc_attr->log_depth); 263365cdf5fSErez Shitrit MLX5_SET(rtc, attr, log_hash_size, rtc_attr->log_size); 264365cdf5fSErez Shitrit MLX5_SET(rtc, attr, table_type, rtc_attr->table_type); 265365cdf5fSErez Shitrit MLX5_SET(rtc, attr, match_definer_id, rtc_attr->definer_id); 266365cdf5fSErez Shitrit MLX5_SET(rtc, attr, stc_id, rtc_attr->stc_base); 267365cdf5fSErez Shitrit MLX5_SET(rtc, attr, ste_table_base_id, rtc_attr->ste_base); 268365cdf5fSErez Shitrit MLX5_SET(rtc, attr, ste_table_offset, rtc_attr->ste_offset); 269365cdf5fSErez Shitrit MLX5_SET(rtc, attr, miss_flow_table_id, rtc_attr->miss_ft_id); 270365cdf5fSErez Shitrit MLX5_SET(rtc, attr, reparse_mode, MLX5_IFC_RTC_REPARSE_ALWAYS); 271365cdf5fSErez Shitrit 272365cdf5fSErez Shitrit devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out)); 273365cdf5fSErez Shitrit if (!devx_obj->obj) { 274365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to create RTC"); 275365cdf5fSErez Shitrit simple_free(devx_obj); 276365cdf5fSErez Shitrit rte_errno = errno; 277365cdf5fSErez Shitrit return NULL; 278365cdf5fSErez Shitrit } 279365cdf5fSErez Shitrit 280365cdf5fSErez Shitrit devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); 281365cdf5fSErez Shitrit 282365cdf5fSErez Shitrit return devx_obj; 283365cdf5fSErez Shitrit } 284365cdf5fSErez Shitrit 285365cdf5fSErez Shitrit struct mlx5dr_devx_obj * 286365cdf5fSErez Shitrit mlx5dr_cmd_stc_create(struct ibv_context *ctx, 287365cdf5fSErez Shitrit struct mlx5dr_cmd_stc_create_attr *stc_attr) 288365cdf5fSErez Shitrit { 289365cdf5fSErez Shitrit uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; 290365cdf5fSErez Shitrit uint32_t in[MLX5_ST_SZ_DW(create_stc_in)] = {0}; 291365cdf5fSErez Shitrit struct mlx5dr_devx_obj *devx_obj; 292365cdf5fSErez Shitrit void *attr; 293365cdf5fSErez Shitrit 294365cdf5fSErez Shitrit devx_obj = simple_malloc(sizeof(*devx_obj)); 295365cdf5fSErez Shitrit if (!devx_obj) { 296365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to allocate memory for STC object"); 297365cdf5fSErez Shitrit rte_errno = ENOMEM; 298365cdf5fSErez Shitrit return NULL; 299365cdf5fSErez Shitrit } 300365cdf5fSErez Shitrit 301365cdf5fSErez Shitrit attr = MLX5_ADDR_OF(create_stc_in, in, hdr); 302365cdf5fSErez Shitrit MLX5_SET(general_obj_in_cmd_hdr, 303365cdf5fSErez Shitrit attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT); 304365cdf5fSErez Shitrit MLX5_SET(general_obj_in_cmd_hdr, 305365cdf5fSErez Shitrit attr, obj_type, MLX5_GENERAL_OBJ_TYPE_STC); 306365cdf5fSErez Shitrit MLX5_SET(general_obj_in_cmd_hdr, 307365cdf5fSErez Shitrit attr, log_obj_range, stc_attr->log_obj_range); 308365cdf5fSErez Shitrit 309365cdf5fSErez Shitrit attr = MLX5_ADDR_OF(create_stc_in, in, stc); 310365cdf5fSErez Shitrit MLX5_SET(stc, attr, table_type, stc_attr->table_type); 311365cdf5fSErez Shitrit 312365cdf5fSErez Shitrit devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out)); 313365cdf5fSErez Shitrit if (!devx_obj->obj) { 314365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to create STC"); 315365cdf5fSErez Shitrit simple_free(devx_obj); 316365cdf5fSErez Shitrit rte_errno = errno; 317365cdf5fSErez Shitrit return NULL; 318365cdf5fSErez Shitrit } 319365cdf5fSErez Shitrit 320365cdf5fSErez Shitrit devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); 321365cdf5fSErez Shitrit 322365cdf5fSErez Shitrit return devx_obj; 323365cdf5fSErez Shitrit } 324365cdf5fSErez Shitrit 325365cdf5fSErez Shitrit static int 326365cdf5fSErez Shitrit mlx5dr_cmd_stc_modify_set_stc_param(struct mlx5dr_cmd_stc_modify_attr *stc_attr, 327365cdf5fSErez Shitrit void *stc_parm) 328365cdf5fSErez Shitrit { 329365cdf5fSErez Shitrit switch (stc_attr->action_type) { 330365cdf5fSErez Shitrit case MLX5_IFC_STC_ACTION_TYPE_COUNTER: 331365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_flow_counter, stc_parm, flow_counter_id, stc_attr->id); 332365cdf5fSErez Shitrit break; 333365cdf5fSErez Shitrit case MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_TIR: 334365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_tir, stc_parm, tirn, stc_attr->dest_tir_num); 335365cdf5fSErez Shitrit break; 336365cdf5fSErez Shitrit case MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_FT: 337365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_table, stc_parm, table_id, stc_attr->dest_table_id); 338365cdf5fSErez Shitrit break; 339365cdf5fSErez Shitrit case MLX5_IFC_STC_ACTION_TYPE_ACC_MODIFY_LIST: 340365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_header_modify_list, stc_parm, 341365cdf5fSErez Shitrit header_modify_pattern_id, stc_attr->modify_header.pattern_id); 342365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_header_modify_list, stc_parm, 343365cdf5fSErez Shitrit header_modify_argument_id, stc_attr->modify_header.arg_id); 344365cdf5fSErez Shitrit break; 345365cdf5fSErez Shitrit case MLX5_IFC_STC_ACTION_TYPE_HEADER_REMOVE: 346365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_remove, stc_parm, action_type, 347365cdf5fSErez Shitrit MLX5_MODIFICATION_TYPE_REMOVE); 348365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_remove, stc_parm, decap, 349365cdf5fSErez Shitrit stc_attr->remove_header.decap); 350365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_remove, stc_parm, remove_start_anchor, 351365cdf5fSErez Shitrit stc_attr->remove_header.start_anchor); 352365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_remove, stc_parm, remove_end_anchor, 353365cdf5fSErez Shitrit stc_attr->remove_header.end_anchor); 354365cdf5fSErez Shitrit break; 355365cdf5fSErez Shitrit case MLX5_IFC_STC_ACTION_TYPE_HEADER_INSERT: 356365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_insert, stc_parm, action_type, 357365cdf5fSErez Shitrit MLX5_MODIFICATION_TYPE_INSERT); 358365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_insert, stc_parm, encap, 359365cdf5fSErez Shitrit stc_attr->insert_header.encap); 360365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_insert, stc_parm, inline_data, 361365cdf5fSErez Shitrit stc_attr->insert_header.is_inline); 362365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_insert, stc_parm, insert_anchor, 363365cdf5fSErez Shitrit stc_attr->insert_header.insert_anchor); 364365cdf5fSErez Shitrit /* HW gets the next 2 sizes in words */ 365365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_insert, stc_parm, insert_size, 366365cdf5fSErez Shitrit stc_attr->insert_header.header_size / 2); 367365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_insert, stc_parm, insert_offset, 368365cdf5fSErez Shitrit stc_attr->insert_header.insert_offset / 2); 369365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_insert, stc_parm, insert_argument, 370365cdf5fSErez Shitrit stc_attr->insert_header.arg_id); 371365cdf5fSErez Shitrit break; 372365cdf5fSErez Shitrit case MLX5_IFC_STC_ACTION_TYPE_COPY: 373365cdf5fSErez Shitrit case MLX5_IFC_STC_ACTION_TYPE_SET: 374365cdf5fSErez Shitrit case MLX5_IFC_STC_ACTION_TYPE_ADD: 375365cdf5fSErez Shitrit *(__be64 *)stc_parm = stc_attr->modify_action.data; 376365cdf5fSErez Shitrit break; 377365cdf5fSErez Shitrit case MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_VPORT: 378365cdf5fSErez Shitrit case MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_UPLINK: 379365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_vport, stc_parm, vport_number, 380365cdf5fSErez Shitrit stc_attr->vport.vport_num); 381365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_vport, stc_parm, eswitch_owner_vhca_id, 382365cdf5fSErez Shitrit stc_attr->vport.esw_owner_vhca_id); 383365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_vport, stc_parm, eswitch_owner_vhca_id_valid, 1); 384365cdf5fSErez Shitrit break; 385365cdf5fSErez Shitrit case MLX5_IFC_STC_ACTION_TYPE_DROP: 386365cdf5fSErez Shitrit case MLX5_IFC_STC_ACTION_TYPE_NOP: 387365cdf5fSErez Shitrit case MLX5_IFC_STC_ACTION_TYPE_TAG: 388365cdf5fSErez Shitrit case MLX5_IFC_STC_ACTION_TYPE_ALLOW: 389365cdf5fSErez Shitrit break; 390365cdf5fSErez Shitrit case MLX5_IFC_STC_ACTION_TYPE_ASO: 391365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_execute_aso, stc_parm, aso_object_id, 392365cdf5fSErez Shitrit stc_attr->aso.devx_obj_id); 393365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_execute_aso, stc_parm, return_reg_id, 394365cdf5fSErez Shitrit stc_attr->aso.return_reg_id); 395365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_execute_aso, stc_parm, aso_type, 396365cdf5fSErez Shitrit stc_attr->aso.aso_type); 397365cdf5fSErez Shitrit break; 398365cdf5fSErez Shitrit case MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_STE_TABLE: 399365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_ste_table, stc_parm, ste_obj_id, 400365cdf5fSErez Shitrit stc_attr->ste_table.ste_obj_id); 401365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_ste_table, stc_parm, match_definer_id, 402365cdf5fSErez Shitrit stc_attr->ste_table.match_definer_id); 403365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_ste_table, stc_parm, log_hash_size, 404365cdf5fSErez Shitrit stc_attr->ste_table.log_hash_size); 405365cdf5fSErez Shitrit break; 406365cdf5fSErez Shitrit case MLX5_IFC_STC_ACTION_TYPE_REMOVE_WORDS: 407365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_remove_words, stc_parm, action_type, 408365cdf5fSErez Shitrit MLX5_MODIFICATION_TYPE_REMOVE_WORDS); 409365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_remove_words, stc_parm, remove_start_anchor, 410365cdf5fSErez Shitrit stc_attr->remove_words.start_anchor); 411365cdf5fSErez Shitrit MLX5_SET(stc_ste_param_remove_words, stc_parm, 412365cdf5fSErez Shitrit remove_size, stc_attr->remove_words.num_of_words); 413365cdf5fSErez Shitrit break; 414365cdf5fSErez Shitrit default: 415365cdf5fSErez Shitrit DR_LOG(ERR, "Not supported type %d", stc_attr->action_type); 416365cdf5fSErez Shitrit rte_errno = EINVAL; 417365cdf5fSErez Shitrit return rte_errno; 418365cdf5fSErez Shitrit } 419365cdf5fSErez Shitrit return 0; 420365cdf5fSErez Shitrit } 421365cdf5fSErez Shitrit 422365cdf5fSErez Shitrit int 423365cdf5fSErez Shitrit mlx5dr_cmd_stc_modify(struct mlx5dr_devx_obj *devx_obj, 424365cdf5fSErez Shitrit struct mlx5dr_cmd_stc_modify_attr *stc_attr) 425365cdf5fSErez Shitrit { 426365cdf5fSErez Shitrit uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; 427365cdf5fSErez Shitrit uint32_t in[MLX5_ST_SZ_DW(create_stc_in)] = {0}; 428365cdf5fSErez Shitrit void *stc_parm; 429365cdf5fSErez Shitrit void *attr; 430365cdf5fSErez Shitrit int ret; 431365cdf5fSErez Shitrit 432365cdf5fSErez Shitrit attr = MLX5_ADDR_OF(create_stc_in, in, hdr); 433365cdf5fSErez Shitrit MLX5_SET(general_obj_in_cmd_hdr, 434365cdf5fSErez Shitrit attr, opcode, MLX5_CMD_OP_MODIFY_GENERAL_OBJECT); 435365cdf5fSErez Shitrit MLX5_SET(general_obj_in_cmd_hdr, 436365cdf5fSErez Shitrit attr, obj_type, MLX5_GENERAL_OBJ_TYPE_STC); 437365cdf5fSErez Shitrit MLX5_SET(general_obj_in_cmd_hdr, in, obj_id, devx_obj->id); 438365cdf5fSErez Shitrit MLX5_SET(general_obj_in_cmd_hdr, in, obj_offset, stc_attr->stc_offset); 439365cdf5fSErez Shitrit 440365cdf5fSErez Shitrit attr = MLX5_ADDR_OF(create_stc_in, in, stc); 441365cdf5fSErez Shitrit MLX5_SET(stc, attr, ste_action_offset, stc_attr->action_offset); 442365cdf5fSErez Shitrit MLX5_SET(stc, attr, action_type, stc_attr->action_type); 443365cdf5fSErez Shitrit MLX5_SET64(stc, attr, modify_field_select, 444365cdf5fSErez Shitrit MLX5_IFC_MODIFY_STC_FIELD_SELECT_NEW_STC); 445365cdf5fSErez Shitrit 446365cdf5fSErez Shitrit /* Set destination TIRN, TAG, FT ID, STE ID */ 447365cdf5fSErez Shitrit stc_parm = MLX5_ADDR_OF(stc, attr, stc_param); 448365cdf5fSErez Shitrit ret = mlx5dr_cmd_stc_modify_set_stc_param(stc_attr, stc_parm); 449365cdf5fSErez Shitrit if (ret) 450365cdf5fSErez Shitrit return ret; 451365cdf5fSErez Shitrit 452365cdf5fSErez Shitrit ret = mlx5_glue->devx_obj_modify(devx_obj->obj, in, sizeof(in), out, sizeof(out)); 453365cdf5fSErez Shitrit if (ret) { 454365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to modify STC FW action_type %d", stc_attr->action_type); 455365cdf5fSErez Shitrit rte_errno = errno; 456365cdf5fSErez Shitrit } 457365cdf5fSErez Shitrit 458365cdf5fSErez Shitrit return ret; 459365cdf5fSErez Shitrit } 460365cdf5fSErez Shitrit 461365cdf5fSErez Shitrit struct mlx5dr_devx_obj * 462365cdf5fSErez Shitrit mlx5dr_cmd_arg_create(struct ibv_context *ctx, 463365cdf5fSErez Shitrit uint16_t log_obj_range, 464365cdf5fSErez Shitrit uint32_t pd) 465365cdf5fSErez Shitrit { 466365cdf5fSErez Shitrit uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; 467365cdf5fSErez Shitrit uint32_t in[MLX5_ST_SZ_DW(create_arg_in)] = {0}; 468365cdf5fSErez Shitrit struct mlx5dr_devx_obj *devx_obj; 469365cdf5fSErez Shitrit void *attr; 470365cdf5fSErez Shitrit 471365cdf5fSErez Shitrit devx_obj = simple_malloc(sizeof(*devx_obj)); 472365cdf5fSErez Shitrit if (!devx_obj) { 473365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to allocate memory for ARG object"); 474365cdf5fSErez Shitrit rte_errno = ENOMEM; 475365cdf5fSErez Shitrit return NULL; 476365cdf5fSErez Shitrit } 477365cdf5fSErez Shitrit 478365cdf5fSErez Shitrit attr = MLX5_ADDR_OF(create_arg_in, in, hdr); 479365cdf5fSErez Shitrit MLX5_SET(general_obj_in_cmd_hdr, 480365cdf5fSErez Shitrit attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT); 481365cdf5fSErez Shitrit MLX5_SET(general_obj_in_cmd_hdr, 482365cdf5fSErez Shitrit attr, obj_type, MLX5_GENERAL_OBJ_TYPE_ARG); 483365cdf5fSErez Shitrit MLX5_SET(general_obj_in_cmd_hdr, 484365cdf5fSErez Shitrit attr, log_obj_range, log_obj_range); 485365cdf5fSErez Shitrit 486365cdf5fSErez Shitrit attr = MLX5_ADDR_OF(create_arg_in, in, arg); 487365cdf5fSErez Shitrit MLX5_SET(arg, attr, access_pd, pd); 488365cdf5fSErez Shitrit 489365cdf5fSErez Shitrit devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out)); 490365cdf5fSErez Shitrit if (!devx_obj->obj) { 491365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to create ARG"); 492365cdf5fSErez Shitrit simple_free(devx_obj); 493365cdf5fSErez Shitrit rte_errno = errno; 494365cdf5fSErez Shitrit return NULL; 495365cdf5fSErez Shitrit } 496365cdf5fSErez Shitrit 497365cdf5fSErez Shitrit devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); 498365cdf5fSErez Shitrit 499365cdf5fSErez Shitrit return devx_obj; 500365cdf5fSErez Shitrit } 501365cdf5fSErez Shitrit 502365cdf5fSErez Shitrit struct mlx5dr_devx_obj * 503365cdf5fSErez Shitrit mlx5dr_cmd_header_modify_pattern_create(struct ibv_context *ctx, 504365cdf5fSErez Shitrit uint32_t pattern_length, 505365cdf5fSErez Shitrit uint8_t *actions) 506365cdf5fSErez Shitrit { 507365cdf5fSErez Shitrit uint32_t in[MLX5_ST_SZ_DW(create_header_modify_pattern_in)] = {0}; 508365cdf5fSErez Shitrit uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; 509365cdf5fSErez Shitrit struct mlx5dr_devx_obj *devx_obj; 510365cdf5fSErez Shitrit void *pattern_data; 511365cdf5fSErez Shitrit void *pattern; 512365cdf5fSErez Shitrit void *attr; 513365cdf5fSErez Shitrit 514365cdf5fSErez Shitrit if (pattern_length > MAX_ACTIONS_DATA_IN_HEADER_MODIFY) { 515365cdf5fSErez Shitrit DR_LOG(ERR, "Pattern length %d exceeds limit %d", 516365cdf5fSErez Shitrit pattern_length, MAX_ACTIONS_DATA_IN_HEADER_MODIFY); 517365cdf5fSErez Shitrit rte_errno = EINVAL; 518365cdf5fSErez Shitrit return NULL; 519365cdf5fSErez Shitrit } 520365cdf5fSErez Shitrit 521365cdf5fSErez Shitrit devx_obj = simple_malloc(sizeof(*devx_obj)); 522365cdf5fSErez Shitrit if (!devx_obj) { 523365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to allocate memory for header_modify_pattern object"); 524365cdf5fSErez Shitrit rte_errno = ENOMEM; 525365cdf5fSErez Shitrit return NULL; 526365cdf5fSErez Shitrit } 527365cdf5fSErez Shitrit 528365cdf5fSErez Shitrit attr = MLX5_ADDR_OF(create_header_modify_pattern_in, in, hdr); 529365cdf5fSErez Shitrit MLX5_SET(general_obj_in_cmd_hdr, 530365cdf5fSErez Shitrit attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT); 531365cdf5fSErez Shitrit MLX5_SET(general_obj_in_cmd_hdr, 532365cdf5fSErez Shitrit attr, obj_type, MLX5_GENERAL_OBJ_TYPE_MODIFY_HEADER_PATTERN); 533365cdf5fSErez Shitrit 534365cdf5fSErez Shitrit pattern = MLX5_ADDR_OF(create_header_modify_pattern_in, in, pattern); 535365cdf5fSErez Shitrit /* Pattern_length is in ddwords */ 536365cdf5fSErez Shitrit MLX5_SET(header_modify_pattern_in, pattern, pattern_length, pattern_length / (2 * DW_SIZE)); 537365cdf5fSErez Shitrit 538365cdf5fSErez Shitrit pattern_data = MLX5_ADDR_OF(header_modify_pattern_in, pattern, pattern_data); 539365cdf5fSErez Shitrit memcpy(pattern_data, actions, pattern_length); 540365cdf5fSErez Shitrit 541365cdf5fSErez Shitrit devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out)); 542365cdf5fSErez Shitrit if (!devx_obj->obj) { 543365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to create header_modify_pattern"); 544365cdf5fSErez Shitrit rte_errno = errno; 545365cdf5fSErez Shitrit goto free_obj; 546365cdf5fSErez Shitrit } 547365cdf5fSErez Shitrit 548365cdf5fSErez Shitrit devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); 549365cdf5fSErez Shitrit 550365cdf5fSErez Shitrit return devx_obj; 551365cdf5fSErez Shitrit 552365cdf5fSErez Shitrit free_obj: 553365cdf5fSErez Shitrit simple_free(devx_obj); 554365cdf5fSErez Shitrit return NULL; 555365cdf5fSErez Shitrit } 556365cdf5fSErez Shitrit 557365cdf5fSErez Shitrit struct mlx5dr_devx_obj * 558365cdf5fSErez Shitrit mlx5dr_cmd_ste_create(struct ibv_context *ctx, 559365cdf5fSErez Shitrit struct mlx5dr_cmd_ste_create_attr *ste_attr) 560365cdf5fSErez Shitrit { 561365cdf5fSErez Shitrit uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; 562365cdf5fSErez Shitrit uint32_t in[MLX5_ST_SZ_DW(create_ste_in)] = {0}; 563365cdf5fSErez Shitrit struct mlx5dr_devx_obj *devx_obj; 564365cdf5fSErez Shitrit void *attr; 565365cdf5fSErez Shitrit 566365cdf5fSErez Shitrit devx_obj = simple_malloc(sizeof(*devx_obj)); 567365cdf5fSErez Shitrit if (!devx_obj) { 568365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to allocate memory for STE object"); 569365cdf5fSErez Shitrit rte_errno = ENOMEM; 570365cdf5fSErez Shitrit return NULL; 571365cdf5fSErez Shitrit } 572365cdf5fSErez Shitrit 573365cdf5fSErez Shitrit attr = MLX5_ADDR_OF(create_ste_in, in, hdr); 574365cdf5fSErez Shitrit MLX5_SET(general_obj_in_cmd_hdr, 575365cdf5fSErez Shitrit attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT); 576365cdf5fSErez Shitrit MLX5_SET(general_obj_in_cmd_hdr, 577365cdf5fSErez Shitrit attr, obj_type, MLX5_GENERAL_OBJ_TYPE_STE); 578365cdf5fSErez Shitrit MLX5_SET(general_obj_in_cmd_hdr, 579365cdf5fSErez Shitrit attr, log_obj_range, ste_attr->log_obj_range); 580365cdf5fSErez Shitrit 581365cdf5fSErez Shitrit attr = MLX5_ADDR_OF(create_ste_in, in, ste); 582365cdf5fSErez Shitrit MLX5_SET(ste, attr, table_type, ste_attr->table_type); 583365cdf5fSErez Shitrit 584365cdf5fSErez Shitrit devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out)); 585365cdf5fSErez Shitrit if (!devx_obj->obj) { 586365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to create STE"); 587365cdf5fSErez Shitrit simple_free(devx_obj); 588365cdf5fSErez Shitrit rte_errno = errno; 589365cdf5fSErez Shitrit return NULL; 590365cdf5fSErez Shitrit } 591365cdf5fSErez Shitrit 592365cdf5fSErez Shitrit devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); 593365cdf5fSErez Shitrit 594365cdf5fSErez Shitrit return devx_obj; 595365cdf5fSErez Shitrit } 596365cdf5fSErez Shitrit 597365cdf5fSErez Shitrit struct mlx5dr_devx_obj * 598365cdf5fSErez Shitrit mlx5dr_cmd_definer_create(struct ibv_context *ctx, 599365cdf5fSErez Shitrit struct mlx5dr_cmd_definer_create_attr *def_attr) 600365cdf5fSErez Shitrit { 601365cdf5fSErez Shitrit uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; 602365cdf5fSErez Shitrit uint32_t in[MLX5_ST_SZ_DW(create_definer_in)] = {0}; 603365cdf5fSErez Shitrit struct mlx5dr_devx_obj *devx_obj; 604365cdf5fSErez Shitrit void *ptr; 605365cdf5fSErez Shitrit 606365cdf5fSErez Shitrit devx_obj = simple_malloc(sizeof(*devx_obj)); 607365cdf5fSErez Shitrit if (!devx_obj) { 608365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to allocate memory for definer object"); 609365cdf5fSErez Shitrit rte_errno = ENOMEM; 610365cdf5fSErez Shitrit return NULL; 611365cdf5fSErez Shitrit } 612365cdf5fSErez Shitrit 613365cdf5fSErez Shitrit MLX5_SET(general_obj_in_cmd_hdr, 614365cdf5fSErez Shitrit in, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT); 615365cdf5fSErez Shitrit MLX5_SET(general_obj_in_cmd_hdr, 616365cdf5fSErez Shitrit in, obj_type, MLX5_GENERAL_OBJ_TYPE_DEFINER); 617365cdf5fSErez Shitrit 618365cdf5fSErez Shitrit ptr = MLX5_ADDR_OF(create_definer_in, in, definer); 619365cdf5fSErez Shitrit MLX5_SET(definer, ptr, format_id, MLX5_IFC_DEFINER_FORMAT_ID_SELECT); 620365cdf5fSErez Shitrit 621365cdf5fSErez Shitrit MLX5_SET(definer, ptr, format_select_dw0, def_attr->dw_selector[0]); 622365cdf5fSErez Shitrit MLX5_SET(definer, ptr, format_select_dw1, def_attr->dw_selector[1]); 623365cdf5fSErez Shitrit MLX5_SET(definer, ptr, format_select_dw2, def_attr->dw_selector[2]); 624365cdf5fSErez Shitrit MLX5_SET(definer, ptr, format_select_dw3, def_attr->dw_selector[3]); 625365cdf5fSErez Shitrit MLX5_SET(definer, ptr, format_select_dw4, def_attr->dw_selector[4]); 626365cdf5fSErez Shitrit MLX5_SET(definer, ptr, format_select_dw5, def_attr->dw_selector[5]); 627365cdf5fSErez Shitrit MLX5_SET(definer, ptr, format_select_dw6, def_attr->dw_selector[6]); 628365cdf5fSErez Shitrit MLX5_SET(definer, ptr, format_select_dw7, def_attr->dw_selector[7]); 629365cdf5fSErez Shitrit MLX5_SET(definer, ptr, format_select_dw8, def_attr->dw_selector[8]); 630365cdf5fSErez Shitrit 631365cdf5fSErez Shitrit MLX5_SET(definer, ptr, format_select_byte0, def_attr->byte_selector[0]); 632365cdf5fSErez Shitrit MLX5_SET(definer, ptr, format_select_byte1, def_attr->byte_selector[1]); 633365cdf5fSErez Shitrit MLX5_SET(definer, ptr, format_select_byte2, def_attr->byte_selector[2]); 634365cdf5fSErez Shitrit MLX5_SET(definer, ptr, format_select_byte3, def_attr->byte_selector[3]); 635365cdf5fSErez Shitrit MLX5_SET(definer, ptr, format_select_byte4, def_attr->byte_selector[4]); 636365cdf5fSErez Shitrit MLX5_SET(definer, ptr, format_select_byte5, def_attr->byte_selector[5]); 637365cdf5fSErez Shitrit MLX5_SET(definer, ptr, format_select_byte6, def_attr->byte_selector[6]); 638365cdf5fSErez Shitrit MLX5_SET(definer, ptr, format_select_byte7, def_attr->byte_selector[7]); 639365cdf5fSErez Shitrit 640365cdf5fSErez Shitrit ptr = MLX5_ADDR_OF(definer, ptr, match_mask); 641365cdf5fSErez Shitrit memcpy(ptr, def_attr->match_mask, MLX5_FLD_SZ_BYTES(definer, match_mask)); 642365cdf5fSErez Shitrit 643365cdf5fSErez Shitrit devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out)); 644365cdf5fSErez Shitrit if (!devx_obj->obj) { 645365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to create Definer"); 646365cdf5fSErez Shitrit simple_free(devx_obj); 647365cdf5fSErez Shitrit rte_errno = errno; 648365cdf5fSErez Shitrit return NULL; 649365cdf5fSErez Shitrit } 650365cdf5fSErez Shitrit 651365cdf5fSErez Shitrit devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); 652365cdf5fSErez Shitrit 653365cdf5fSErez Shitrit return devx_obj; 654365cdf5fSErez Shitrit } 655365cdf5fSErez Shitrit 656365cdf5fSErez Shitrit struct mlx5dr_devx_obj * 657365cdf5fSErez Shitrit mlx5dr_cmd_sq_create(struct ibv_context *ctx, 658365cdf5fSErez Shitrit struct mlx5dr_cmd_sq_create_attr *attr) 659365cdf5fSErez Shitrit { 660365cdf5fSErez Shitrit uint32_t out[MLX5_ST_SZ_DW(create_sq_out)] = {0}; 661365cdf5fSErez Shitrit uint32_t in[MLX5_ST_SZ_DW(create_sq_in)] = {0}; 662365cdf5fSErez Shitrit void *sqc = MLX5_ADDR_OF(create_sq_in, in, ctx); 663365cdf5fSErez Shitrit void *wqc = MLX5_ADDR_OF(sqc, sqc, wq); 664365cdf5fSErez Shitrit struct mlx5dr_devx_obj *devx_obj; 665365cdf5fSErez Shitrit 666365cdf5fSErez Shitrit devx_obj = simple_malloc(sizeof(*devx_obj)); 667365cdf5fSErez Shitrit if (!devx_obj) { 668365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to create SQ"); 669365cdf5fSErez Shitrit rte_errno = ENOMEM; 670365cdf5fSErez Shitrit return NULL; 671365cdf5fSErez Shitrit } 672365cdf5fSErez Shitrit 673365cdf5fSErez Shitrit MLX5_SET(create_sq_in, in, opcode, MLX5_CMD_OP_CREATE_SQ); 674365cdf5fSErez Shitrit MLX5_SET(sqc, sqc, cqn, attr->cqn); 675365cdf5fSErez Shitrit MLX5_SET(sqc, sqc, flush_in_error_en, 1); 676365cdf5fSErez Shitrit MLX5_SET(sqc, sqc, non_wire, 1); 677d4444de8SViacheslav Ovsiienko MLX5_SET(sqc, sqc, ts_format, attr->ts_format); 678365cdf5fSErez Shitrit MLX5_SET(wq, wqc, wq_type, MLX5_WQ_TYPE_CYCLIC); 679365cdf5fSErez Shitrit MLX5_SET(wq, wqc, pd, attr->pdn); 680365cdf5fSErez Shitrit MLX5_SET(wq, wqc, uar_page, attr->page_id); 681365cdf5fSErez Shitrit MLX5_SET(wq, wqc, log_wq_stride, log2above(MLX5_SEND_WQE_BB)); 682365cdf5fSErez Shitrit MLX5_SET(wq, wqc, log_wq_sz, attr->log_wq_sz); 683365cdf5fSErez Shitrit MLX5_SET(wq, wqc, dbr_umem_id, attr->dbr_id); 684365cdf5fSErez Shitrit MLX5_SET(wq, wqc, wq_umem_id, attr->wq_id); 685365cdf5fSErez Shitrit 686365cdf5fSErez Shitrit devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out)); 687365cdf5fSErez Shitrit if (!devx_obj->obj) { 688365cdf5fSErez Shitrit simple_free(devx_obj); 689365cdf5fSErez Shitrit rte_errno = errno; 690365cdf5fSErez Shitrit return NULL; 691365cdf5fSErez Shitrit } 692365cdf5fSErez Shitrit 693365cdf5fSErez Shitrit devx_obj->id = MLX5_GET(create_sq_out, out, sqn); 694365cdf5fSErez Shitrit 695365cdf5fSErez Shitrit return devx_obj; 696365cdf5fSErez Shitrit } 697365cdf5fSErez Shitrit 698365cdf5fSErez Shitrit int mlx5dr_cmd_sq_modify_rdy(struct mlx5dr_devx_obj *devx_obj) 699365cdf5fSErez Shitrit { 700365cdf5fSErez Shitrit uint32_t out[MLX5_ST_SZ_DW(modify_sq_out)] = {0}; 701365cdf5fSErez Shitrit uint32_t in[MLX5_ST_SZ_DW(modify_sq_in)] = {0}; 702365cdf5fSErez Shitrit void *sqc = MLX5_ADDR_OF(modify_sq_in, in, ctx); 703365cdf5fSErez Shitrit int ret; 704365cdf5fSErez Shitrit 705365cdf5fSErez Shitrit MLX5_SET(modify_sq_in, in, opcode, MLX5_CMD_OP_MODIFY_SQ); 706365cdf5fSErez Shitrit MLX5_SET(modify_sq_in, in, sqn, devx_obj->id); 707365cdf5fSErez Shitrit MLX5_SET(modify_sq_in, in, sq_state, MLX5_SQC_STATE_RST); 708365cdf5fSErez Shitrit MLX5_SET(sqc, sqc, state, MLX5_SQC_STATE_RDY); 709365cdf5fSErez Shitrit 710365cdf5fSErez Shitrit ret = mlx5_glue->devx_obj_modify(devx_obj->obj, in, sizeof(in), out, sizeof(out)); 711365cdf5fSErez Shitrit if (ret) { 712365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to modify SQ"); 713365cdf5fSErez Shitrit rte_errno = errno; 714365cdf5fSErez Shitrit } 715365cdf5fSErez Shitrit 716365cdf5fSErez Shitrit return ret; 717365cdf5fSErez Shitrit } 718365cdf5fSErez Shitrit 719720439d8SYevgeny Kliteynik int mlx5dr_cmd_allow_other_vhca_access(struct ibv_context *ctx, 720720439d8SYevgeny Kliteynik struct mlx5dr_cmd_allow_other_vhca_access_attr *attr) 721720439d8SYevgeny Kliteynik { 722720439d8SYevgeny Kliteynik uint32_t out[MLX5_ST_SZ_DW(allow_other_vhca_access_out)] = {0}; 723720439d8SYevgeny Kliteynik uint32_t in[MLX5_ST_SZ_DW(allow_other_vhca_access_in)] = {0}; 724720439d8SYevgeny Kliteynik void *key; 725720439d8SYevgeny Kliteynik int ret; 726720439d8SYevgeny Kliteynik 727720439d8SYevgeny Kliteynik MLX5_SET(allow_other_vhca_access_in, 728720439d8SYevgeny Kliteynik in, opcode, MLX5_CMD_OP_ALLOW_OTHER_VHCA_ACCESS); 729720439d8SYevgeny Kliteynik MLX5_SET(allow_other_vhca_access_in, 730720439d8SYevgeny Kliteynik in, object_type_to_be_accessed, attr->obj_type); 731720439d8SYevgeny Kliteynik MLX5_SET(allow_other_vhca_access_in, 732720439d8SYevgeny Kliteynik in, object_id_to_be_accessed, attr->obj_id); 733720439d8SYevgeny Kliteynik 734720439d8SYevgeny Kliteynik key = MLX5_ADDR_OF(allow_other_vhca_access_in, in, access_key); 735720439d8SYevgeny Kliteynik memcpy(key, attr->access_key, sizeof(attr->access_key)); 736720439d8SYevgeny Kliteynik 737720439d8SYevgeny Kliteynik ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out)); 738720439d8SYevgeny Kliteynik if (ret) { 739720439d8SYevgeny Kliteynik DR_LOG(ERR, "Failed to execute ALLOW_OTHER_VHCA_ACCESS command"); 740720439d8SYevgeny Kliteynik rte_errno = errno; 741720439d8SYevgeny Kliteynik return rte_errno; 742720439d8SYevgeny Kliteynik } 743720439d8SYevgeny Kliteynik 744720439d8SYevgeny Kliteynik return 0; 745720439d8SYevgeny Kliteynik } 746720439d8SYevgeny Kliteynik 747*ed695274SYevgeny Kliteynik struct mlx5dr_devx_obj * 748*ed695274SYevgeny Kliteynik mlx5dr_cmd_alias_obj_create(struct ibv_context *ctx, 749*ed695274SYevgeny Kliteynik struct mlx5dr_cmd_alias_obj_create_attr *alias_attr) 750*ed695274SYevgeny Kliteynik { 751*ed695274SYevgeny Kliteynik uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; 752*ed695274SYevgeny Kliteynik uint32_t in[MLX5_ST_SZ_DW(create_alias_obj_in)] = {0}; 753*ed695274SYevgeny Kliteynik struct mlx5dr_devx_obj *devx_obj; 754*ed695274SYevgeny Kliteynik void *attr; 755*ed695274SYevgeny Kliteynik void *key; 756*ed695274SYevgeny Kliteynik 757*ed695274SYevgeny Kliteynik devx_obj = simple_malloc(sizeof(*devx_obj)); 758*ed695274SYevgeny Kliteynik if (!devx_obj) { 759*ed695274SYevgeny Kliteynik DR_LOG(ERR, "Failed to allocate memory for ALIAS general object"); 760*ed695274SYevgeny Kliteynik rte_errno = ENOMEM; 761*ed695274SYevgeny Kliteynik return NULL; 762*ed695274SYevgeny Kliteynik } 763*ed695274SYevgeny Kliteynik 764*ed695274SYevgeny Kliteynik attr = MLX5_ADDR_OF(create_alias_obj_in, in, hdr); 765*ed695274SYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, 766*ed695274SYevgeny Kliteynik attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT); 767*ed695274SYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, 768*ed695274SYevgeny Kliteynik attr, obj_type, alias_attr->obj_type); 769*ed695274SYevgeny Kliteynik MLX5_SET(general_obj_in_cmd_hdr, attr, alias_object, 1); 770*ed695274SYevgeny Kliteynik 771*ed695274SYevgeny Kliteynik attr = MLX5_ADDR_OF(create_alias_obj_in, in, alias_ctx); 772*ed695274SYevgeny Kliteynik MLX5_SET(alias_context, attr, vhca_id_to_be_accessed, alias_attr->vhca_id); 773*ed695274SYevgeny Kliteynik MLX5_SET(alias_context, attr, object_id_to_be_accessed, alias_attr->obj_id); 774*ed695274SYevgeny Kliteynik 775*ed695274SYevgeny Kliteynik key = MLX5_ADDR_OF(alias_context, attr, access_key); 776*ed695274SYevgeny Kliteynik memcpy(key, alias_attr->access_key, sizeof(alias_attr->access_key)); 777*ed695274SYevgeny Kliteynik 778*ed695274SYevgeny Kliteynik devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out)); 779*ed695274SYevgeny Kliteynik if (!devx_obj->obj) { 780*ed695274SYevgeny Kliteynik DR_LOG(ERR, "Failed to create ALIAS OBJ"); 781*ed695274SYevgeny Kliteynik simple_free(devx_obj); 782*ed695274SYevgeny Kliteynik rte_errno = errno; 783*ed695274SYevgeny Kliteynik return NULL; 784*ed695274SYevgeny Kliteynik } 785*ed695274SYevgeny Kliteynik 786*ed695274SYevgeny Kliteynik devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); 787*ed695274SYevgeny Kliteynik 788*ed695274SYevgeny Kliteynik return devx_obj; 789*ed695274SYevgeny Kliteynik } 790*ed695274SYevgeny Kliteynik 791365cdf5fSErez Shitrit int mlx5dr_cmd_query_caps(struct ibv_context *ctx, 792365cdf5fSErez Shitrit struct mlx5dr_cmd_query_caps *caps) 793365cdf5fSErez Shitrit { 794365cdf5fSErez Shitrit uint32_t out[MLX5_ST_SZ_DW(query_hca_cap_out)] = {0}; 795365cdf5fSErez Shitrit uint32_t in[MLX5_ST_SZ_DW(query_hca_cap_in)] = {0}; 796365cdf5fSErez Shitrit const struct flow_hw_port_info *port_info; 797365cdf5fSErez Shitrit struct ibv_device_attr_ex attr_ex; 798b2300900SYevgeny Kliteynik u32 res; 799365cdf5fSErez Shitrit int ret; 800365cdf5fSErez Shitrit 801365cdf5fSErez Shitrit MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP); 802365cdf5fSErez Shitrit MLX5_SET(query_hca_cap_in, in, op_mod, 803365cdf5fSErez Shitrit MLX5_GET_HCA_CAP_OP_MOD_GENERAL_DEVICE | 804365cdf5fSErez Shitrit MLX5_HCA_CAP_OPMOD_GET_CUR); 805365cdf5fSErez Shitrit 806365cdf5fSErez Shitrit ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out)); 807365cdf5fSErez Shitrit if (ret) { 808365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to query device caps"); 809365cdf5fSErez Shitrit rte_errno = errno; 810365cdf5fSErez Shitrit return rte_errno; 811365cdf5fSErez Shitrit } 812365cdf5fSErez Shitrit 813365cdf5fSErez Shitrit caps->wqe_based_update = 814365cdf5fSErez Shitrit MLX5_GET(query_hca_cap_out, out, 815365cdf5fSErez Shitrit capability.cmd_hca_cap.wqe_based_flow_table_update_cap); 816365cdf5fSErez Shitrit 817365cdf5fSErez Shitrit caps->eswitch_manager = MLX5_GET(query_hca_cap_out, out, 818365cdf5fSErez Shitrit capability.cmd_hca_cap.eswitch_manager); 819365cdf5fSErez Shitrit 820365cdf5fSErez Shitrit caps->flex_protocols = MLX5_GET(query_hca_cap_out, out, 821365cdf5fSErez Shitrit capability.cmd_hca_cap.flex_parser_protocols); 822365cdf5fSErez Shitrit 823365cdf5fSErez Shitrit caps->log_header_modify_argument_granularity = 824365cdf5fSErez Shitrit MLX5_GET(query_hca_cap_out, out, 825365cdf5fSErez Shitrit capability.cmd_hca_cap.log_header_modify_argument_granularity); 826365cdf5fSErez Shitrit 827365cdf5fSErez Shitrit caps->log_header_modify_argument_granularity -= 828365cdf5fSErez Shitrit MLX5_GET(query_hca_cap_out, out, 829365cdf5fSErez Shitrit capability.cmd_hca_cap. 830365cdf5fSErez Shitrit log_header_modify_argument_granularity_offset); 831365cdf5fSErez Shitrit 832365cdf5fSErez Shitrit caps->log_header_modify_argument_max_alloc = 833365cdf5fSErez Shitrit MLX5_GET(query_hca_cap_out, out, 834365cdf5fSErez Shitrit capability.cmd_hca_cap.log_header_modify_argument_max_alloc); 835365cdf5fSErez Shitrit 836365cdf5fSErez Shitrit caps->definer_format_sup = 837365cdf5fSErez Shitrit MLX5_GET64(query_hca_cap_out, out, 838365cdf5fSErez Shitrit capability.cmd_hca_cap.match_definer_format_supported); 839365cdf5fSErez Shitrit 840d4444de8SViacheslav Ovsiienko caps->sq_ts_format = MLX5_GET(query_hca_cap_out, out, 841d4444de8SViacheslav Ovsiienko capability.cmd_hca_cap.sq_ts_format); 842d4444de8SViacheslav Ovsiienko 843365cdf5fSErez Shitrit MLX5_SET(query_hca_cap_in, in, op_mod, 844365cdf5fSErez Shitrit MLX5_GET_HCA_CAP_OP_MOD_GENERAL_DEVICE_2 | 845365cdf5fSErez Shitrit MLX5_HCA_CAP_OPMOD_GET_CUR); 846365cdf5fSErez Shitrit 847365cdf5fSErez Shitrit ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out)); 848365cdf5fSErez Shitrit if (ret) { 849365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to query device caps"); 850365cdf5fSErez Shitrit rte_errno = errno; 851365cdf5fSErez Shitrit return rte_errno; 852365cdf5fSErez Shitrit } 853365cdf5fSErez Shitrit 854365cdf5fSErez Shitrit caps->full_dw_jumbo_support = MLX5_GET(query_hca_cap_out, out, 855365cdf5fSErez Shitrit capability.cmd_hca_cap_2. 856365cdf5fSErez Shitrit format_select_dw_8_6_ext); 857365cdf5fSErez Shitrit 858365cdf5fSErez Shitrit caps->format_select_gtpu_dw_0 = MLX5_GET(query_hca_cap_out, out, 859365cdf5fSErez Shitrit capability.cmd_hca_cap_2. 860365cdf5fSErez Shitrit format_select_dw_gtpu_dw_0); 861365cdf5fSErez Shitrit 862365cdf5fSErez Shitrit caps->format_select_gtpu_dw_1 = MLX5_GET(query_hca_cap_out, out, 863365cdf5fSErez Shitrit capability.cmd_hca_cap_2. 864365cdf5fSErez Shitrit format_select_dw_gtpu_dw_1); 865365cdf5fSErez Shitrit 866365cdf5fSErez Shitrit caps->format_select_gtpu_dw_2 = MLX5_GET(query_hca_cap_out, out, 867365cdf5fSErez Shitrit capability.cmd_hca_cap_2. 868365cdf5fSErez Shitrit format_select_dw_gtpu_dw_2); 869365cdf5fSErez Shitrit 870365cdf5fSErez Shitrit caps->format_select_gtpu_ext_dw_0 = MLX5_GET(query_hca_cap_out, out, 871365cdf5fSErez Shitrit capability.cmd_hca_cap_2. 872365cdf5fSErez Shitrit format_select_dw_gtpu_first_ext_dw_0); 873365cdf5fSErez Shitrit 874b2300900SYevgeny Kliteynik /* check cross-VHCA support in cap2 */ 875b2300900SYevgeny Kliteynik res = 876b2300900SYevgeny Kliteynik MLX5_GET(query_hca_cap_out, out, 877b2300900SYevgeny Kliteynik capability.cmd_hca_cap_2.cross_vhca_object_to_object_supported); 878b2300900SYevgeny Kliteynik 879b2300900SYevgeny Kliteynik caps->cross_vhca_resources = (res & MLX5_CROSS_VHCA_OBJ_TO_OBJ_TYPE_STC_TO_TIR) && 880b2300900SYevgeny Kliteynik (res & MLX5_CROSS_VHCA_OBJ_TO_OBJ_TYPE_STC_TO_FT) && 881b2300900SYevgeny Kliteynik (res & MLX5_CROSS_VHCA_OBJ_TO_OBJ_TYPE_FT_TO_RTC); 882b2300900SYevgeny Kliteynik 883b2300900SYevgeny Kliteynik res = 884b2300900SYevgeny Kliteynik MLX5_GET(query_hca_cap_out, out, 885b2300900SYevgeny Kliteynik capability.cmd_hca_cap_2.allowed_object_for_other_vhca_access); 886b2300900SYevgeny Kliteynik 887b2300900SYevgeny Kliteynik caps->cross_vhca_resources &= (res & MLX5_CROSS_VHCA_ALLOWED_OBJS_TIR) && 888b2300900SYevgeny Kliteynik (res & MLX5_CROSS_VHCA_ALLOWED_OBJS_FT) && 889b2300900SYevgeny Kliteynik (res & MLX5_CROSS_VHCA_ALLOWED_OBJS_RTC); 890b2300900SYevgeny Kliteynik 891365cdf5fSErez Shitrit MLX5_SET(query_hca_cap_in, in, op_mod, 892365cdf5fSErez Shitrit MLX5_GET_HCA_CAP_OP_MOD_NIC_FLOW_TABLE | 893365cdf5fSErez Shitrit MLX5_HCA_CAP_OPMOD_GET_CUR); 894365cdf5fSErez Shitrit 895365cdf5fSErez Shitrit ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out)); 896365cdf5fSErez Shitrit if (ret) { 897365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to query flow table caps"); 898365cdf5fSErez Shitrit rte_errno = errno; 899365cdf5fSErez Shitrit return rte_errno; 900365cdf5fSErez Shitrit } 901365cdf5fSErez Shitrit 902365cdf5fSErez Shitrit caps->nic_ft.max_level = MLX5_GET(query_hca_cap_out, out, 903365cdf5fSErez Shitrit capability.flow_table_nic_cap. 904365cdf5fSErez Shitrit flow_table_properties_nic_receive.max_ft_level); 905365cdf5fSErez Shitrit 906365cdf5fSErez Shitrit caps->nic_ft.reparse = MLX5_GET(query_hca_cap_out, out, 907365cdf5fSErez Shitrit capability.flow_table_nic_cap. 908365cdf5fSErez Shitrit flow_table_properties_nic_receive.reparse); 909365cdf5fSErez Shitrit 910b2300900SYevgeny Kliteynik /* check cross-VHCA support in flow table properties */ 911b2300900SYevgeny Kliteynik res = 912b2300900SYevgeny Kliteynik MLX5_GET(query_hca_cap_out, out, 913b2300900SYevgeny Kliteynik capability.flow_table_nic_cap.flow_table_properties_nic_receive.cross_vhca_object); 914b2300900SYevgeny Kliteynik caps->cross_vhca_resources &= res; 915b2300900SYevgeny Kliteynik 916365cdf5fSErez Shitrit if (caps->wqe_based_update) { 917365cdf5fSErez Shitrit MLX5_SET(query_hca_cap_in, in, op_mod, 918365cdf5fSErez Shitrit MLX5_GET_HCA_CAP_OP_MOD_WQE_BASED_FLOW_TABLE | 919365cdf5fSErez Shitrit MLX5_HCA_CAP_OPMOD_GET_CUR); 920365cdf5fSErez Shitrit 921365cdf5fSErez Shitrit ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out)); 922365cdf5fSErez Shitrit if (ret) { 923365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to query WQE based FT caps"); 924365cdf5fSErez Shitrit rte_errno = errno; 925365cdf5fSErez Shitrit return rte_errno; 926365cdf5fSErez Shitrit } 927365cdf5fSErez Shitrit 928365cdf5fSErez Shitrit caps->rtc_reparse_mode = MLX5_GET(query_hca_cap_out, out, 929365cdf5fSErez Shitrit capability.wqe_based_flow_table_cap. 930365cdf5fSErez Shitrit rtc_reparse_mode); 931365cdf5fSErez Shitrit 932365cdf5fSErez Shitrit caps->ste_format = MLX5_GET(query_hca_cap_out, out, 933365cdf5fSErez Shitrit capability.wqe_based_flow_table_cap. 934365cdf5fSErez Shitrit ste_format); 935365cdf5fSErez Shitrit 936365cdf5fSErez Shitrit caps->rtc_index_mode = MLX5_GET(query_hca_cap_out, out, 937365cdf5fSErez Shitrit capability.wqe_based_flow_table_cap. 938365cdf5fSErez Shitrit rtc_index_mode); 939365cdf5fSErez Shitrit 940365cdf5fSErez Shitrit caps->rtc_log_depth_max = MLX5_GET(query_hca_cap_out, out, 941365cdf5fSErez Shitrit capability.wqe_based_flow_table_cap. 942365cdf5fSErez Shitrit rtc_log_depth_max); 943365cdf5fSErez Shitrit 944365cdf5fSErez Shitrit caps->ste_alloc_log_max = MLX5_GET(query_hca_cap_out, out, 945365cdf5fSErez Shitrit capability.wqe_based_flow_table_cap. 946365cdf5fSErez Shitrit ste_alloc_log_max); 947365cdf5fSErez Shitrit 948365cdf5fSErez Shitrit caps->ste_alloc_log_gran = MLX5_GET(query_hca_cap_out, out, 949365cdf5fSErez Shitrit capability.wqe_based_flow_table_cap. 950365cdf5fSErez Shitrit ste_alloc_log_granularity); 951365cdf5fSErez Shitrit 952365cdf5fSErez Shitrit caps->trivial_match_definer = MLX5_GET(query_hca_cap_out, out, 953365cdf5fSErez Shitrit capability.wqe_based_flow_table_cap. 954365cdf5fSErez Shitrit trivial_match_definer); 955365cdf5fSErez Shitrit 956365cdf5fSErez Shitrit caps->stc_alloc_log_max = MLX5_GET(query_hca_cap_out, out, 957365cdf5fSErez Shitrit capability.wqe_based_flow_table_cap. 958365cdf5fSErez Shitrit stc_alloc_log_max); 959365cdf5fSErez Shitrit 960365cdf5fSErez Shitrit caps->stc_alloc_log_gran = MLX5_GET(query_hca_cap_out, out, 961365cdf5fSErez Shitrit capability.wqe_based_flow_table_cap. 962365cdf5fSErez Shitrit stc_alloc_log_granularity); 963365cdf5fSErez Shitrit } 964365cdf5fSErez Shitrit 965365cdf5fSErez Shitrit if (caps->eswitch_manager) { 966365cdf5fSErez Shitrit MLX5_SET(query_hca_cap_in, in, op_mod, 967365cdf5fSErez Shitrit MLX5_GET_HCA_CAP_OP_MOD_ESW_FLOW_TABLE | 968365cdf5fSErez Shitrit MLX5_HCA_CAP_OPMOD_GET_CUR); 969365cdf5fSErez Shitrit 970365cdf5fSErez Shitrit ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out)); 971365cdf5fSErez Shitrit if (ret) { 972365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to query flow table esw caps"); 973365cdf5fSErez Shitrit rte_errno = errno; 974365cdf5fSErez Shitrit return rte_errno; 975365cdf5fSErez Shitrit } 976365cdf5fSErez Shitrit 977365cdf5fSErez Shitrit caps->fdb_ft.max_level = MLX5_GET(query_hca_cap_out, out, 978365cdf5fSErez Shitrit capability.flow_table_nic_cap. 979365cdf5fSErez Shitrit flow_table_properties_nic_receive.max_ft_level); 980365cdf5fSErez Shitrit 981365cdf5fSErez Shitrit caps->fdb_ft.reparse = MLX5_GET(query_hca_cap_out, out, 982365cdf5fSErez Shitrit capability.flow_table_nic_cap. 983365cdf5fSErez Shitrit flow_table_properties_nic_receive.reparse); 984365cdf5fSErez Shitrit 985365cdf5fSErez Shitrit MLX5_SET(query_hca_cap_in, in, op_mod, 986365cdf5fSErez Shitrit MLX5_SET_HCA_CAP_OP_MOD_ESW | MLX5_HCA_CAP_OPMOD_GET_CUR); 987365cdf5fSErez Shitrit 988365cdf5fSErez Shitrit ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out)); 989365cdf5fSErez Shitrit if (ret) { 990365cdf5fSErez Shitrit DR_LOG(ERR, "Query eswitch capabilities failed %d\n", ret); 991365cdf5fSErez Shitrit rte_errno = errno; 992365cdf5fSErez Shitrit return rte_errno; 993365cdf5fSErez Shitrit } 994365cdf5fSErez Shitrit 995365cdf5fSErez Shitrit if (MLX5_GET(query_hca_cap_out, out, 996365cdf5fSErez Shitrit capability.esw_cap.esw_manager_vport_number_valid)) 997365cdf5fSErez Shitrit caps->eswitch_manager_vport_number = 998365cdf5fSErez Shitrit MLX5_GET(query_hca_cap_out, out, 999365cdf5fSErez Shitrit capability.esw_cap.esw_manager_vport_number); 1000365cdf5fSErez Shitrit } 1001365cdf5fSErez Shitrit 1002365cdf5fSErez Shitrit ret = mlx5_glue->query_device_ex(ctx, NULL, &attr_ex); 1003365cdf5fSErez Shitrit if (ret) { 1004365cdf5fSErez Shitrit DR_LOG(ERR, "Failed to query device attributes"); 1005365cdf5fSErez Shitrit rte_errno = ret; 1006365cdf5fSErez Shitrit return rte_errno; 1007365cdf5fSErez Shitrit } 1008365cdf5fSErez Shitrit 1009365cdf5fSErez Shitrit strlcpy(caps->fw_ver, attr_ex.orig_attr.fw_ver, sizeof(caps->fw_ver)); 1010365cdf5fSErez Shitrit 1011365cdf5fSErez Shitrit port_info = flow_hw_get_wire_port(ctx); 1012365cdf5fSErez Shitrit if (port_info) { 1013365cdf5fSErez Shitrit caps->wire_regc = port_info->regc_value; 1014365cdf5fSErez Shitrit caps->wire_regc_mask = port_info->regc_mask; 1015365cdf5fSErez Shitrit } else { 1016365cdf5fSErez Shitrit DR_LOG(INFO, "Failed to query wire port regc value"); 1017365cdf5fSErez Shitrit } 1018365cdf5fSErez Shitrit 1019365cdf5fSErez Shitrit return ret; 1020365cdf5fSErez Shitrit } 1021365cdf5fSErez Shitrit 1022365cdf5fSErez Shitrit int mlx5dr_cmd_query_ib_port(struct ibv_context *ctx, 1023365cdf5fSErez Shitrit struct mlx5dr_cmd_query_vport_caps *vport_caps, 1024365cdf5fSErez Shitrit uint32_t port_num) 1025365cdf5fSErez Shitrit { 1026365cdf5fSErez Shitrit struct mlx5_port_info port_info = {0}; 1027365cdf5fSErez Shitrit uint32_t flags; 1028365cdf5fSErez Shitrit int ret; 1029365cdf5fSErez Shitrit 1030365cdf5fSErez Shitrit flags = MLX5_PORT_QUERY_VPORT | MLX5_PORT_QUERY_ESW_OWNER_VHCA_ID; 1031365cdf5fSErez Shitrit 1032365cdf5fSErez Shitrit ret = mlx5_glue->devx_port_query(ctx, port_num, &port_info); 1033365cdf5fSErez Shitrit /* Check if query succeed and vport is enabled */ 1034365cdf5fSErez Shitrit if (ret || (port_info.query_flags & flags) != flags) { 1035365cdf5fSErez Shitrit rte_errno = ENOTSUP; 1036365cdf5fSErez Shitrit return rte_errno; 1037365cdf5fSErez Shitrit } 1038365cdf5fSErez Shitrit 1039365cdf5fSErez Shitrit vport_caps->vport_num = port_info.vport_id; 1040365cdf5fSErez Shitrit vport_caps->esw_owner_vhca_id = port_info.esw_owner_vhca_id; 1041365cdf5fSErez Shitrit 1042365cdf5fSErez Shitrit if (port_info.query_flags & MLX5_PORT_QUERY_REG_C0) { 1043365cdf5fSErez Shitrit vport_caps->metadata_c = port_info.vport_meta_tag; 1044365cdf5fSErez Shitrit vport_caps->metadata_c_mask = port_info.vport_meta_mask; 1045365cdf5fSErez Shitrit } 1046365cdf5fSErez Shitrit 1047365cdf5fSErez Shitrit return 0; 1048365cdf5fSErez Shitrit } 1049