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 : : }
|