xref: /dpdk/drivers/net/mlx5/hws/mlx5dr_cmd.c (revision ed69527423b3ef985d8fc6acd0829f78b1fced1c)
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