xref: /dpdk/drivers/net/mlx5/hws/mlx5dr_cmd.c (revision 29cd96c98dd999756f43715c7f3e85c44044b115)
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 
775226c96SErez Shitrit static uint32_t mlx5dr_cmd_get_syndrome(uint32_t *out)
875226c96SErez Shitrit {
975226c96SErez Shitrit 	/* Assumption: syndrome is always the second u32 */
1075226c96SErez Shitrit 	return be32toh(out[1]);
1175226c96SErez Shitrit }
1275226c96SErez Shitrit 
13365cdf5fSErez Shitrit int mlx5dr_cmd_destroy_obj(struct mlx5dr_devx_obj *devx_obj)
14365cdf5fSErez Shitrit {
15365cdf5fSErez Shitrit 	int ret;
16365cdf5fSErez Shitrit 
17365cdf5fSErez Shitrit 	ret = mlx5_glue->devx_obj_destroy(devx_obj->obj);
18365cdf5fSErez Shitrit 	simple_free(devx_obj);
19365cdf5fSErez Shitrit 
20365cdf5fSErez Shitrit 	return ret;
21365cdf5fSErez Shitrit }
22365cdf5fSErez Shitrit 
23365cdf5fSErez Shitrit struct mlx5dr_devx_obj *
24365cdf5fSErez Shitrit mlx5dr_cmd_flow_table_create(struct ibv_context *ctx,
25365cdf5fSErez Shitrit 			     struct mlx5dr_cmd_ft_create_attr *ft_attr)
26365cdf5fSErez Shitrit {
27365cdf5fSErez Shitrit 	uint32_t out[MLX5_ST_SZ_DW(create_flow_table_out)] = {0};
28365cdf5fSErez Shitrit 	uint32_t in[MLX5_ST_SZ_DW(create_flow_table_in)] = {0};
29365cdf5fSErez Shitrit 	struct mlx5dr_devx_obj *devx_obj;
30365cdf5fSErez Shitrit 	void *ft_ctx;
31365cdf5fSErez Shitrit 
32365cdf5fSErez Shitrit 	devx_obj = simple_malloc(sizeof(*devx_obj));
33365cdf5fSErez Shitrit 	if (!devx_obj) {
34365cdf5fSErez Shitrit 		DR_LOG(ERR, "Failed to allocate memory for flow table object");
35365cdf5fSErez Shitrit 		rte_errno = ENOMEM;
36365cdf5fSErez Shitrit 		return NULL;
37365cdf5fSErez Shitrit 	}
38365cdf5fSErez Shitrit 
39365cdf5fSErez Shitrit 	MLX5_SET(create_flow_table_in, in, opcode, MLX5_CMD_OP_CREATE_FLOW_TABLE);
40365cdf5fSErez Shitrit 	MLX5_SET(create_flow_table_in, in, table_type, ft_attr->type);
41365cdf5fSErez Shitrit 
42365cdf5fSErez Shitrit 	ft_ctx = MLX5_ADDR_OF(create_flow_table_in, in, flow_table_context);
43365cdf5fSErez Shitrit 	MLX5_SET(flow_table_context, ft_ctx, level, ft_attr->level);
44365cdf5fSErez Shitrit 	MLX5_SET(flow_table_context, ft_ctx, rtc_valid, ft_attr->rtc_valid);
452b2ce5ddSHamdan Igbaria 	MLX5_SET(flow_table_context, ft_ctx, reformat_en, ft_attr->reformat_en);
46365cdf5fSErez Shitrit 
47365cdf5fSErez Shitrit 	devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
48365cdf5fSErez Shitrit 	if (!devx_obj->obj) {
4975226c96SErez Shitrit 		DR_LOG(ERR, "Failed to create FT (syndrome: %#x)",
5075226c96SErez Shitrit 		       mlx5dr_cmd_get_syndrome(out));
51365cdf5fSErez Shitrit 		simple_free(devx_obj);
52365cdf5fSErez Shitrit 		rte_errno = errno;
53365cdf5fSErez Shitrit 		return NULL;
54365cdf5fSErez Shitrit 	}
55365cdf5fSErez Shitrit 
56365cdf5fSErez Shitrit 	devx_obj->id = MLX5_GET(create_flow_table_out, out, table_id);
57365cdf5fSErez Shitrit 
58365cdf5fSErez Shitrit 	return devx_obj;
59365cdf5fSErez Shitrit }
60365cdf5fSErez Shitrit 
61365cdf5fSErez Shitrit int
62365cdf5fSErez Shitrit mlx5dr_cmd_flow_table_modify(struct mlx5dr_devx_obj *devx_obj,
63365cdf5fSErez Shitrit 			     struct mlx5dr_cmd_ft_modify_attr *ft_attr)
64365cdf5fSErez Shitrit {
65365cdf5fSErez Shitrit 	uint32_t out[MLX5_ST_SZ_DW(modify_flow_table_out)] = {0};
66365cdf5fSErez Shitrit 	uint32_t in[MLX5_ST_SZ_DW(modify_flow_table_in)] = {0};
67365cdf5fSErez Shitrit 	void *ft_ctx;
68365cdf5fSErez Shitrit 	int ret;
69365cdf5fSErez Shitrit 
70365cdf5fSErez Shitrit 	MLX5_SET(modify_flow_table_in, in, opcode, MLX5_CMD_OP_MODIFY_FLOW_TABLE);
71365cdf5fSErez Shitrit 	MLX5_SET(modify_flow_table_in, in, table_type, ft_attr->type);
72365cdf5fSErez Shitrit 	MLX5_SET(modify_flow_table_in, in, modify_field_select, ft_attr->modify_fs);
73365cdf5fSErez Shitrit 	MLX5_SET(modify_flow_table_in, in, table_id, devx_obj->id);
74365cdf5fSErez Shitrit 
75365cdf5fSErez Shitrit 	ft_ctx = MLX5_ADDR_OF(modify_flow_table_in, in, flow_table_context);
76365cdf5fSErez Shitrit 
77365cdf5fSErez Shitrit 	MLX5_SET(flow_table_context, ft_ctx, table_miss_action, ft_attr->table_miss_action);
78365cdf5fSErez Shitrit 	MLX5_SET(flow_table_context, ft_ctx, table_miss_id, ft_attr->table_miss_id);
79365cdf5fSErez Shitrit 	MLX5_SET(flow_table_context, ft_ctx, rtc_id_0, ft_attr->rtc_id_0);
80365cdf5fSErez Shitrit 	MLX5_SET(flow_table_context, ft_ctx, rtc_id_1, ft_attr->rtc_id_1);
81365cdf5fSErez Shitrit 
82365cdf5fSErez Shitrit 	ret = mlx5_glue->devx_obj_modify(devx_obj->obj, in, sizeof(in), out, sizeof(out));
83365cdf5fSErez Shitrit 	if (ret) {
8475226c96SErez Shitrit 		DR_LOG(ERR, "Failed to modify FT (syndrome: %#x)",
8575226c96SErez Shitrit 		       mlx5dr_cmd_get_syndrome(out));
86365cdf5fSErez Shitrit 		rte_errno = errno;
87365cdf5fSErez Shitrit 	}
88365cdf5fSErez Shitrit 
89365cdf5fSErez Shitrit 	return ret;
90365cdf5fSErez Shitrit }
91365cdf5fSErez Shitrit 
92004edb48SHamdan Igbaria int
93004edb48SHamdan Igbaria mlx5dr_cmd_flow_table_query(struct mlx5dr_devx_obj *devx_obj,
94004edb48SHamdan Igbaria 			    struct mlx5dr_cmd_ft_query_attr *ft_attr,
95004edb48SHamdan Igbaria 			    uint64_t *icm_addr_0, uint64_t *icm_addr_1)
96004edb48SHamdan Igbaria {
97004edb48SHamdan Igbaria 	uint32_t out[MLX5_ST_SZ_DW(query_flow_table_out)] = {0};
98004edb48SHamdan Igbaria 	uint32_t in[MLX5_ST_SZ_DW(query_flow_table_in)] = {0};
99004edb48SHamdan Igbaria 	void *ft_ctx;
100004edb48SHamdan Igbaria 	int ret;
101004edb48SHamdan Igbaria 
102004edb48SHamdan Igbaria 	MLX5_SET(query_flow_table_in, in, opcode, MLX5_CMD_OP_QUERY_FLOW_TABLE);
103004edb48SHamdan Igbaria 	MLX5_SET(query_flow_table_in, in, table_type, ft_attr->type);
104004edb48SHamdan Igbaria 	MLX5_SET(query_flow_table_in, in, table_id, devx_obj->id);
105004edb48SHamdan Igbaria 
106004edb48SHamdan Igbaria 	ret = mlx5_glue->devx_obj_query(devx_obj->obj, in, sizeof(in), out, sizeof(out));
107004edb48SHamdan Igbaria 	if (ret) {
10875226c96SErez Shitrit 		DR_LOG(ERR, "Failed to query FT (syndrome: %#x)",
10975226c96SErez Shitrit 		       mlx5dr_cmd_get_syndrome(out));
110004edb48SHamdan Igbaria 		rte_errno = errno;
111004edb48SHamdan Igbaria 		return ret;
112004edb48SHamdan Igbaria 	}
113004edb48SHamdan Igbaria 
114004edb48SHamdan Igbaria 	ft_ctx = MLX5_ADDR_OF(query_flow_table_out, out, flow_table_context);
115004edb48SHamdan Igbaria 	*icm_addr_0 = MLX5_GET64(flow_table_context, ft_ctx, sw_owner_icm_root_0);
116004edb48SHamdan Igbaria 	*icm_addr_1 = MLX5_GET64(flow_table_context, ft_ctx, sw_owner_icm_root_1);
117004edb48SHamdan Igbaria 
118004edb48SHamdan Igbaria 	return ret;
119004edb48SHamdan Igbaria }
120004edb48SHamdan Igbaria 
121365cdf5fSErez Shitrit static struct mlx5dr_devx_obj *
122365cdf5fSErez Shitrit mlx5dr_cmd_flow_group_create(struct ibv_context *ctx,
123365cdf5fSErez Shitrit 			     struct mlx5dr_cmd_fg_attr *fg_attr)
124365cdf5fSErez Shitrit {
125365cdf5fSErez Shitrit 	uint32_t out[MLX5_ST_SZ_DW(create_flow_group_out)] = {0};
126365cdf5fSErez Shitrit 	uint32_t in[MLX5_ST_SZ_DW(create_flow_group_in)] = {0};
127365cdf5fSErez Shitrit 	struct mlx5dr_devx_obj *devx_obj;
128365cdf5fSErez Shitrit 
129365cdf5fSErez Shitrit 	devx_obj = simple_malloc(sizeof(*devx_obj));
130365cdf5fSErez Shitrit 	if (!devx_obj) {
131365cdf5fSErez Shitrit 		DR_LOG(ERR, "Failed to allocate memory for flow group object");
132365cdf5fSErez Shitrit 		rte_errno = ENOMEM;
133365cdf5fSErez Shitrit 		return NULL;
134365cdf5fSErez Shitrit 	}
135365cdf5fSErez Shitrit 
136365cdf5fSErez Shitrit 	MLX5_SET(create_flow_group_in, in, opcode, MLX5_CMD_OP_CREATE_FLOW_GROUP);
137365cdf5fSErez Shitrit 	MLX5_SET(create_flow_group_in, in, table_type, fg_attr->table_type);
138365cdf5fSErez Shitrit 	MLX5_SET(create_flow_group_in, in, table_id, fg_attr->table_id);
139365cdf5fSErez Shitrit 
140365cdf5fSErez Shitrit 	devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
141365cdf5fSErez Shitrit 	if (!devx_obj->obj) {
14275226c96SErez Shitrit 		DR_LOG(ERR, "Failed to create Flow group(syndrome: %#x)",
14375226c96SErez Shitrit 		       mlx5dr_cmd_get_syndrome(out));
144365cdf5fSErez Shitrit 		simple_free(devx_obj);
145365cdf5fSErez Shitrit 		rte_errno = errno;
146365cdf5fSErez Shitrit 		return NULL;
147365cdf5fSErez Shitrit 	}
148365cdf5fSErez Shitrit 
149365cdf5fSErez Shitrit 	devx_obj->id = MLX5_GET(create_flow_group_out, out, group_id);
150365cdf5fSErez Shitrit 
151365cdf5fSErez Shitrit 	return devx_obj;
152365cdf5fSErez Shitrit }
153365cdf5fSErez Shitrit 
154e1df1578SHamdan Igbaria struct mlx5dr_devx_obj *
155e1df1578SHamdan Igbaria mlx5dr_cmd_set_fte(struct ibv_context *ctx,
156365cdf5fSErez Shitrit 		   uint32_t table_type,
157365cdf5fSErez Shitrit 		   uint32_t table_id,
158365cdf5fSErez Shitrit 		   uint32_t group_id,
159e1df1578SHamdan Igbaria 		   struct mlx5dr_cmd_set_fte_attr *fte_attr)
160365cdf5fSErez Shitrit {
161365cdf5fSErez Shitrit 	uint32_t out[MLX5_ST_SZ_DW(set_fte_out)] = {0};
162365cdf5fSErez Shitrit 	struct mlx5dr_devx_obj *devx_obj;
163eefaf43dSShun Hao 	uint32_t dest_entry_sz;
164eefaf43dSShun Hao 	uint32_t total_dest_sz;
165365cdf5fSErez Shitrit 	void *in_flow_context;
166e1df1578SHamdan Igbaria 	uint32_t action_flags;
167eefaf43dSShun Hao 	uint8_t *in_dests;
168eefaf43dSShun Hao 	uint32_t inlen;
169eefaf43dSShun Hao 	uint32_t *in;
170eefaf43dSShun Hao 	uint32_t i;
171eefaf43dSShun Hao 
17271ad5095SHaifei Luo 	dest_entry_sz = fte_attr->extended_dest ?
17371ad5095SHaifei Luo 			MLX5_ST_SZ_BYTES(extended_dest_format) :
17471ad5095SHaifei Luo 			MLX5_ST_SZ_BYTES(dest_format);
175eefaf43dSShun Hao 	total_dest_sz = dest_entry_sz * fte_attr->dests_num;
176eefaf43dSShun Hao 	inlen = align((MLX5_ST_SZ_BYTES(set_fte_in) + total_dest_sz), DW_SIZE);
177eefaf43dSShun Hao 	in = simple_calloc(1, inlen);
178eefaf43dSShun Hao 	if (!in) {
179eefaf43dSShun Hao 		rte_errno = ENOMEM;
180eefaf43dSShun Hao 		return NULL;
181eefaf43dSShun Hao 	}
182365cdf5fSErez Shitrit 
183365cdf5fSErez Shitrit 	devx_obj = simple_malloc(sizeof(*devx_obj));
184365cdf5fSErez Shitrit 	if (!devx_obj) {
185365cdf5fSErez Shitrit 		DR_LOG(ERR, "Failed to allocate memory for fte object");
186365cdf5fSErez Shitrit 		rte_errno = ENOMEM;
187eefaf43dSShun Hao 		goto free_in;
188365cdf5fSErez Shitrit 	}
189365cdf5fSErez Shitrit 
190365cdf5fSErez Shitrit 	MLX5_SET(set_fte_in, in, opcode, MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY);
191365cdf5fSErez Shitrit 	MLX5_SET(set_fte_in, in, table_type, table_type);
192365cdf5fSErez Shitrit 	MLX5_SET(set_fte_in, in, table_id, table_id);
193365cdf5fSErez Shitrit 
194365cdf5fSErez Shitrit 	in_flow_context = MLX5_ADDR_OF(set_fte_in, in, flow_context);
195365cdf5fSErez Shitrit 	MLX5_SET(flow_context, in_flow_context, group_id, group_id);
196e1df1578SHamdan Igbaria 	MLX5_SET(flow_context, in_flow_context, flow_source, fte_attr->flow_source);
19771ad5095SHaifei Luo 	MLX5_SET(flow_context, in_flow_context, extended_destination, fte_attr->extended_dest);
198eefaf43dSShun Hao 	MLX5_SET(set_fte_in, in, ignore_flow_level, fte_attr->ignore_flow_level);
199365cdf5fSErez Shitrit 
200e1df1578SHamdan Igbaria 	action_flags = fte_attr->action_flags;
201e1df1578SHamdan Igbaria 	MLX5_SET(flow_context, in_flow_context, action, action_flags);
202e1df1578SHamdan Igbaria 
2032b2ce5ddSHamdan Igbaria 	if (action_flags & MLX5_FLOW_CONTEXT_ACTION_REFORMAT)
2042b2ce5ddSHamdan Igbaria 		MLX5_SET(flow_context, in_flow_context,
2052b2ce5ddSHamdan Igbaria 			 packet_reformat_id, fte_attr->packet_reformat_id);
2062b2ce5ddSHamdan Igbaria 
2072b2ce5ddSHamdan Igbaria 	if (action_flags & (MLX5_FLOW_CONTEXT_ACTION_DECRYPT | MLX5_FLOW_CONTEXT_ACTION_ENCRYPT)) {
2082b2ce5ddSHamdan Igbaria 		MLX5_SET(flow_context, in_flow_context,
2092b2ce5ddSHamdan Igbaria 			 encrypt_decrypt_type, fte_attr->encrypt_decrypt_type);
2102b2ce5ddSHamdan Igbaria 		MLX5_SET(flow_context, in_flow_context,
2112b2ce5ddSHamdan Igbaria 			 encrypt_decrypt_obj_id, fte_attr->encrypt_decrypt_obj_id);
2122b2ce5ddSHamdan Igbaria 	}
2132b2ce5ddSHamdan Igbaria 
214e1df1578SHamdan Igbaria 	if (action_flags & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) {
215eefaf43dSShun Hao 		in_dests = (uint8_t *)MLX5_ADDR_OF(flow_context, in_flow_context, destination);
216eefaf43dSShun Hao 
217eefaf43dSShun Hao 		for (i = 0; i < fte_attr->dests_num; i++) {
218eefaf43dSShun Hao 			struct mlx5dr_cmd_set_fte_dest *dest = &fte_attr->dests[i];
219eefaf43dSShun Hao 
220eefaf43dSShun Hao 			switch (dest->destination_type) {
221eefaf43dSShun Hao 			case MLX5_FLOW_DESTINATION_TYPE_VPORT:
222eefaf43dSShun Hao 				if (dest->ext_flags & MLX5DR_CMD_EXT_DEST_ESW_OWNER_VHCA_ID) {
223eefaf43dSShun Hao 					MLX5_SET(dest_format, in_dests,
224eefaf43dSShun Hao 						 destination_eswitch_owner_vhca_id_valid, 1);
225eefaf43dSShun Hao 					MLX5_SET(dest_format, in_dests,
226eefaf43dSShun Hao 						 destination_eswitch_owner_vhca_id,
227eefaf43dSShun Hao 						 dest->esw_owner_vhca_id);
228eefaf43dSShun Hao 				}
229eefaf43dSShun Hao 				/* Fall through */
230eefaf43dSShun Hao 			case MLX5_FLOW_DESTINATION_TYPE_TIR:
231eefaf43dSShun Hao 			case MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE:
232eefaf43dSShun Hao 				MLX5_SET(dest_format, in_dests, destination_type,
233eefaf43dSShun Hao 					 dest->destination_type);
234eefaf43dSShun Hao 				MLX5_SET(dest_format, in_dests, destination_id,
235eefaf43dSShun Hao 					 dest->destination_id);
23671ad5095SHaifei Luo 				if (dest->ext_flags & MLX5DR_CMD_EXT_DEST_REFORMAT) {
23771ad5095SHaifei Luo 					MLX5_SET(dest_format, in_dests, packet_reformat, 1);
23871ad5095SHaifei Luo 					MLX5_SET(extended_dest_format, in_dests, packet_reformat_id,
23971ad5095SHaifei Luo 						 dest->ext_reformat->id);
24071ad5095SHaifei Luo 				}
241eefaf43dSShun Hao 				break;
242eefaf43dSShun Hao 			default:
243eefaf43dSShun Hao 				rte_errno = EOPNOTSUPP;
244eefaf43dSShun Hao 				goto free_devx;
245e1df1578SHamdan Igbaria 			}
246365cdf5fSErez Shitrit 
247eefaf43dSShun Hao 			in_dests = in_dests + dest_entry_sz;
248eefaf43dSShun Hao 		}
249eefaf43dSShun Hao 		MLX5_SET(flow_context, in_flow_context, destination_list_size, fte_attr->dests_num);
250eefaf43dSShun Hao 	}
251eefaf43dSShun Hao 
252eefaf43dSShun Hao 	devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, inlen, out, sizeof(out));
253365cdf5fSErez Shitrit 	if (!devx_obj->obj) {
25475226c96SErez Shitrit 		DR_LOG(ERR, "Failed to create FTE (syndrome: %#x)",
25575226c96SErez Shitrit 		       mlx5dr_cmd_get_syndrome(out));
256365cdf5fSErez Shitrit 		rte_errno = errno;
257e1df1578SHamdan Igbaria 		goto free_devx;
258365cdf5fSErez Shitrit 	}
259365cdf5fSErez Shitrit 
260eefaf43dSShun Hao 	simple_free(in);
261365cdf5fSErez Shitrit 	return devx_obj;
262365cdf5fSErez Shitrit 
263e1df1578SHamdan Igbaria free_devx:
264e1df1578SHamdan Igbaria 	simple_free(devx_obj);
265eefaf43dSShun Hao free_in:
266eefaf43dSShun Hao 	simple_free(in);
267e1df1578SHamdan Igbaria 	return NULL;
268365cdf5fSErez Shitrit }
269365cdf5fSErez Shitrit 
270365cdf5fSErez Shitrit struct mlx5dr_cmd_forward_tbl *
271e1df1578SHamdan Igbaria mlx5dr_cmd_forward_tbl_create(struct ibv_context *ctx,
272365cdf5fSErez Shitrit 			      struct mlx5dr_cmd_ft_create_attr *ft_attr,
273e1df1578SHamdan Igbaria 			      struct mlx5dr_cmd_set_fte_attr *fte_attr)
274365cdf5fSErez Shitrit {
275365cdf5fSErez Shitrit 	struct mlx5dr_cmd_fg_attr fg_attr = {0};
276365cdf5fSErez Shitrit 	struct mlx5dr_cmd_forward_tbl *tbl;
277365cdf5fSErez Shitrit 
278365cdf5fSErez Shitrit 	tbl = simple_calloc(1, sizeof(*tbl));
279365cdf5fSErez Shitrit 	if (!tbl) {
280e1df1578SHamdan Igbaria 		DR_LOG(ERR, "Failed to allocate memory");
281365cdf5fSErez Shitrit 		rte_errno = ENOMEM;
282365cdf5fSErez Shitrit 		return NULL;
283365cdf5fSErez Shitrit 	}
284365cdf5fSErez Shitrit 
285365cdf5fSErez Shitrit 	tbl->ft = mlx5dr_cmd_flow_table_create(ctx, ft_attr);
286365cdf5fSErez Shitrit 	if (!tbl->ft) {
287e1df1578SHamdan Igbaria 		DR_LOG(ERR, "Failed to create FT");
288365cdf5fSErez Shitrit 		goto free_tbl;
289365cdf5fSErez Shitrit 	}
290365cdf5fSErez Shitrit 
291365cdf5fSErez Shitrit 	fg_attr.table_id = tbl->ft->id;
292365cdf5fSErez Shitrit 	fg_attr.table_type = ft_attr->type;
293365cdf5fSErez Shitrit 
294365cdf5fSErez Shitrit 	tbl->fg = mlx5dr_cmd_flow_group_create(ctx, &fg_attr);
295365cdf5fSErez Shitrit 	if (!tbl->fg) {
296e1df1578SHamdan Igbaria 		DR_LOG(ERR, "Failed to create FG");
297365cdf5fSErez Shitrit 		goto free_ft;
298365cdf5fSErez Shitrit 	}
299365cdf5fSErez Shitrit 
300e1df1578SHamdan Igbaria 	tbl->fte = mlx5dr_cmd_set_fte(ctx, ft_attr->type, tbl->ft->id, tbl->fg->id, fte_attr);
301365cdf5fSErez Shitrit 	if (!tbl->fte) {
302e1df1578SHamdan Igbaria 		DR_LOG(ERR, "Failed to create FTE");
303365cdf5fSErez Shitrit 		goto free_fg;
304365cdf5fSErez Shitrit 	}
305365cdf5fSErez Shitrit 	return tbl;
306365cdf5fSErez Shitrit 
307365cdf5fSErez Shitrit free_fg:
308365cdf5fSErez Shitrit 	mlx5dr_cmd_destroy_obj(tbl->fg);
309365cdf5fSErez Shitrit free_ft:
310365cdf5fSErez Shitrit 	mlx5dr_cmd_destroy_obj(tbl->ft);
311365cdf5fSErez Shitrit free_tbl:
312365cdf5fSErez Shitrit 	simple_free(tbl);
313365cdf5fSErez Shitrit 	return NULL;
314365cdf5fSErez Shitrit }
315365cdf5fSErez Shitrit 
316e1df1578SHamdan Igbaria void mlx5dr_cmd_forward_tbl_destroy(struct mlx5dr_cmd_forward_tbl *tbl)
317e1df1578SHamdan Igbaria {
318e1df1578SHamdan Igbaria 	mlx5dr_cmd_destroy_obj(tbl->fte);
319e1df1578SHamdan Igbaria 	mlx5dr_cmd_destroy_obj(tbl->fg);
320e1df1578SHamdan Igbaria 	mlx5dr_cmd_destroy_obj(tbl->ft);
321e1df1578SHamdan Igbaria 	simple_free(tbl);
322e1df1578SHamdan Igbaria }
323e1df1578SHamdan Igbaria 
324365cdf5fSErez Shitrit void mlx5dr_cmd_set_attr_connect_miss_tbl(struct mlx5dr_context *ctx,
325365cdf5fSErez Shitrit 					  uint32_t fw_ft_type,
326365cdf5fSErez Shitrit 					  enum mlx5dr_table_type type,
327365cdf5fSErez Shitrit 					  struct mlx5dr_cmd_ft_modify_attr *ft_attr)
328365cdf5fSErez Shitrit {
329365cdf5fSErez Shitrit 	struct mlx5dr_devx_obj *default_miss_tbl;
330365cdf5fSErez Shitrit 
331ce946c7dSErez Shitrit 	if (type != MLX5DR_TABLE_TYPE_FDB && !mlx5dr_context_shared_gvmi_used(ctx))
332365cdf5fSErez Shitrit 		return;
333365cdf5fSErez Shitrit 
334ce946c7dSErez Shitrit 	ft_attr->modify_fs = MLX5_IFC_MODIFY_FLOW_TABLE_MISS_ACTION;
335ce946c7dSErez Shitrit 	ft_attr->type = fw_ft_type;
336ce946c7dSErez Shitrit 	ft_attr->table_miss_action = MLX5_IFC_MODIFY_FLOW_TABLE_MISS_ACTION_GOTO_TBL;
337ce946c7dSErez Shitrit 
338ce946c7dSErez Shitrit 	if (type == MLX5DR_TABLE_TYPE_FDB) {
339365cdf5fSErez Shitrit 		default_miss_tbl = ctx->common_res[type].default_miss->ft;
340365cdf5fSErez Shitrit 		if (!default_miss_tbl) {
341365cdf5fSErez Shitrit 			assert(false);
342365cdf5fSErez Shitrit 			return;
343365cdf5fSErez Shitrit 		}
344365cdf5fSErez Shitrit 		ft_attr->table_miss_id = default_miss_tbl->id;
345ce946c7dSErez Shitrit 	} else {
346ce946c7dSErez Shitrit 		ft_attr->table_miss_id = ctx->gvmi_res[type].aliased_end_ft->id;
347ce946c7dSErez Shitrit 	}
348365cdf5fSErez Shitrit }
349365cdf5fSErez Shitrit 
350365cdf5fSErez Shitrit struct mlx5dr_devx_obj *
351365cdf5fSErez Shitrit mlx5dr_cmd_rtc_create(struct ibv_context *ctx,
352365cdf5fSErez Shitrit 		      struct mlx5dr_cmd_rtc_create_attr *rtc_attr)
353365cdf5fSErez Shitrit {
354365cdf5fSErez Shitrit 	uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
355365cdf5fSErez Shitrit 	uint32_t in[MLX5_ST_SZ_DW(create_rtc_in)] = {0};
356365cdf5fSErez Shitrit 	struct mlx5dr_devx_obj *devx_obj;
357365cdf5fSErez Shitrit 	void *attr;
358365cdf5fSErez Shitrit 
359365cdf5fSErez Shitrit 	devx_obj = simple_malloc(sizeof(*devx_obj));
360365cdf5fSErez Shitrit 	if (!devx_obj) {
361365cdf5fSErez Shitrit 		DR_LOG(ERR, "Failed to allocate memory for RTC object");
362365cdf5fSErez Shitrit 		rte_errno = ENOMEM;
363365cdf5fSErez Shitrit 		return NULL;
364365cdf5fSErez Shitrit 	}
365365cdf5fSErez Shitrit 
366365cdf5fSErez Shitrit 	attr = MLX5_ADDR_OF(create_rtc_in, in, hdr);
367365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
368365cdf5fSErez Shitrit 		 attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
369365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
370365cdf5fSErez Shitrit 		 attr, obj_type, MLX5_GENERAL_OBJ_TYPE_RTC);
371365cdf5fSErez Shitrit 
372365cdf5fSErez Shitrit 	attr = MLX5_ADDR_OF(create_rtc_in, in, rtc);
373a5230507SHamdan Igbaria 	if (rtc_attr->is_compare) {
374a5230507SHamdan Igbaria 		MLX5_SET(rtc, attr, ste_format_0, MLX5_IFC_RTC_STE_FORMAT_4DW_RANGE);
375a5230507SHamdan Igbaria 	} else {
37693ee3bd8SAlex Vesker 		MLX5_SET(rtc, attr, ste_format_0, rtc_attr->is_frst_jumbo ?
377a5230507SHamdan Igbaria 			 MLX5_IFC_RTC_STE_FORMAT_11DW : MLX5_IFC_RTC_STE_FORMAT_8DW);
378a5230507SHamdan Igbaria 	}
37993ee3bd8SAlex Vesker 
38093ee3bd8SAlex Vesker 	if (rtc_attr->is_scnd_range) {
38193ee3bd8SAlex Vesker 		MLX5_SET(rtc, attr, ste_format_1, MLX5_IFC_RTC_STE_FORMAT_RANGE);
38293ee3bd8SAlex Vesker 		MLX5_SET(rtc, attr, num_match_ste, 2);
38393ee3bd8SAlex Vesker 	}
38493ee3bd8SAlex Vesker 
385365cdf5fSErez Shitrit 	MLX5_SET(rtc, attr, pd, rtc_attr->pd);
38693ee3bd8SAlex Vesker 	MLX5_SET(rtc, attr, update_method, rtc_attr->fw_gen_wqe);
387365cdf5fSErez Shitrit 	MLX5_SET(rtc, attr, update_index_mode, rtc_attr->update_index_mode);
38807f35716SYevgeny Kliteynik 	MLX5_SET(rtc, attr, access_index_mode, rtc_attr->access_index_mode);
38907f35716SYevgeny Kliteynik 	MLX5_SET(rtc, attr, num_hash_definer, rtc_attr->num_hash_definer);
390365cdf5fSErez Shitrit 	MLX5_SET(rtc, attr, log_depth, rtc_attr->log_depth);
391365cdf5fSErez Shitrit 	MLX5_SET(rtc, attr, log_hash_size, rtc_attr->log_size);
392365cdf5fSErez Shitrit 	MLX5_SET(rtc, attr, table_type, rtc_attr->table_type);
39393ee3bd8SAlex Vesker 	MLX5_SET(rtc, attr, num_hash_definer, rtc_attr->num_hash_definer);
39493ee3bd8SAlex Vesker 	MLX5_SET(rtc, attr, match_definer_0, rtc_attr->match_definer_0);
39593ee3bd8SAlex Vesker 	MLX5_SET(rtc, attr, match_definer_1, rtc_attr->match_definer_1);
396365cdf5fSErez Shitrit 	MLX5_SET(rtc, attr, stc_id, rtc_attr->stc_base);
397365cdf5fSErez Shitrit 	MLX5_SET(rtc, attr, ste_table_base_id, rtc_attr->ste_base);
398365cdf5fSErez Shitrit 	MLX5_SET(rtc, attr, ste_table_offset, rtc_attr->ste_offset);
399365cdf5fSErez Shitrit 	MLX5_SET(rtc, attr, miss_flow_table_id, rtc_attr->miss_ft_id);
400bbddd062SAlex Vesker 	MLX5_SET(rtc, attr, reparse_mode, rtc_attr->reparse_mode);
401365cdf5fSErez Shitrit 
402365cdf5fSErez Shitrit 	devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
403365cdf5fSErez Shitrit 	if (!devx_obj->obj) {
40475226c96SErez Shitrit 		DR_LOG(ERR, "Failed to create RTC (syndrome: %#x)",
40575226c96SErez Shitrit 		       mlx5dr_cmd_get_syndrome(out));
406365cdf5fSErez Shitrit 		simple_free(devx_obj);
407365cdf5fSErez Shitrit 		rte_errno = errno;
408365cdf5fSErez Shitrit 		return NULL;
409365cdf5fSErez Shitrit 	}
410365cdf5fSErez Shitrit 
411365cdf5fSErez Shitrit 	devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
412365cdf5fSErez Shitrit 
413365cdf5fSErez Shitrit 	return devx_obj;
414365cdf5fSErez Shitrit }
415365cdf5fSErez Shitrit 
416365cdf5fSErez Shitrit struct mlx5dr_devx_obj *
417365cdf5fSErez Shitrit mlx5dr_cmd_stc_create(struct ibv_context *ctx,
418365cdf5fSErez Shitrit 		      struct mlx5dr_cmd_stc_create_attr *stc_attr)
419365cdf5fSErez Shitrit {
420365cdf5fSErez Shitrit 	uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
421365cdf5fSErez Shitrit 	uint32_t in[MLX5_ST_SZ_DW(create_stc_in)] = {0};
422365cdf5fSErez Shitrit 	struct mlx5dr_devx_obj *devx_obj;
423365cdf5fSErez Shitrit 	void *attr;
424365cdf5fSErez Shitrit 
425365cdf5fSErez Shitrit 	devx_obj = simple_malloc(sizeof(*devx_obj));
426365cdf5fSErez Shitrit 	if (!devx_obj) {
427365cdf5fSErez Shitrit 		DR_LOG(ERR, "Failed to allocate memory for STC object");
428365cdf5fSErez Shitrit 		rte_errno = ENOMEM;
429365cdf5fSErez Shitrit 		return NULL;
430365cdf5fSErez Shitrit 	}
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_CREATE_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,
438365cdf5fSErez Shitrit 		 attr, log_obj_range, stc_attr->log_obj_range);
439365cdf5fSErez Shitrit 
440365cdf5fSErez Shitrit 	attr = MLX5_ADDR_OF(create_stc_in, in, stc);
441365cdf5fSErez Shitrit 	MLX5_SET(stc, attr, table_type, stc_attr->table_type);
442365cdf5fSErez Shitrit 
443365cdf5fSErez Shitrit 	devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
444365cdf5fSErez Shitrit 	if (!devx_obj->obj) {
44575226c96SErez Shitrit 		DR_LOG(ERR, "Failed to create STC (syndrome: %#x)",
44675226c96SErez Shitrit 		       mlx5dr_cmd_get_syndrome(out));
447365cdf5fSErez Shitrit 		simple_free(devx_obj);
448365cdf5fSErez Shitrit 		rte_errno = errno;
449365cdf5fSErez Shitrit 		return NULL;
450365cdf5fSErez Shitrit 	}
451365cdf5fSErez Shitrit 
452365cdf5fSErez Shitrit 	devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
453365cdf5fSErez Shitrit 
454365cdf5fSErez Shitrit 	return devx_obj;
455365cdf5fSErez Shitrit }
456365cdf5fSErez Shitrit 
457365cdf5fSErez Shitrit static int
458365cdf5fSErez Shitrit mlx5dr_cmd_stc_modify_set_stc_param(struct mlx5dr_cmd_stc_modify_attr *stc_attr,
45953fc80acSItamar Gozlan 				    void *stc_param)
460365cdf5fSErez Shitrit {
461365cdf5fSErez Shitrit 	switch (stc_attr->action_type) {
462365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_COUNTER:
46353fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_flow_counter, stc_param, flow_counter_id, stc_attr->id);
464365cdf5fSErez Shitrit 		break;
465365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_TIR:
46653fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_tir, stc_param, tirn, stc_attr->dest_tir_num);
467365cdf5fSErez Shitrit 		break;
468365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_FT:
46953fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_table, stc_param, table_id, stc_attr->dest_table_id);
470365cdf5fSErez Shitrit 		break;
471365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_ACC_MODIFY_LIST:
47253fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_header_modify_list, stc_param,
473365cdf5fSErez Shitrit 			 header_modify_pattern_id, stc_attr->modify_header.pattern_id);
47453fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_header_modify_list, stc_param,
475365cdf5fSErez Shitrit 			 header_modify_argument_id, stc_attr->modify_header.arg_id);
476365cdf5fSErez Shitrit 		break;
477365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_HEADER_REMOVE:
47853fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_remove, stc_param, action_type,
479365cdf5fSErez Shitrit 			 MLX5_MODIFICATION_TYPE_REMOVE);
48053fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_remove, stc_param, decap,
481365cdf5fSErez Shitrit 			 stc_attr->remove_header.decap);
48253fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_remove, stc_param, remove_start_anchor,
483365cdf5fSErez Shitrit 			 stc_attr->remove_header.start_anchor);
48453fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_remove, stc_param, remove_end_anchor,
485365cdf5fSErez Shitrit 			 stc_attr->remove_header.end_anchor);
486365cdf5fSErez Shitrit 		break;
487365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_HEADER_INSERT:
48853fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_insert, stc_param, action_type,
489365cdf5fSErez Shitrit 			 MLX5_MODIFICATION_TYPE_INSERT);
49053fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_insert, stc_param, encap,
491365cdf5fSErez Shitrit 			 stc_attr->insert_header.encap);
49253fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_insert, stc_param, push_esp,
493525ac5efSHamdan Igbaria 			 stc_attr->insert_header.push_esp);
49453fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_insert, stc_param, inline_data,
495365cdf5fSErez Shitrit 			 stc_attr->insert_header.is_inline);
49653fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_insert, stc_param, insert_anchor,
497365cdf5fSErez Shitrit 			 stc_attr->insert_header.insert_anchor);
498365cdf5fSErez Shitrit 		/* HW gets the next 2 sizes in words */
49953fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_insert, stc_param, insert_size,
50013769225SHamdan Igbaria 			 stc_attr->insert_header.header_size / W_SIZE);
50153fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_insert, stc_param, insert_offset,
50213769225SHamdan Igbaria 			 stc_attr->insert_header.insert_offset / W_SIZE);
50353fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_insert, stc_param, insert_argument,
504365cdf5fSErez Shitrit 			 stc_attr->insert_header.arg_id);
505365cdf5fSErez Shitrit 		break;
506365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_COPY:
507365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_SET:
508365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_ADD:
5091667b1d7SItamar Gozlan 	case MLX5_IFC_STC_ACTION_TYPE_ADD_FIELD:
51053fc80acSItamar Gozlan 		*(__be64 *)stc_param = stc_attr->modify_action.data;
511365cdf5fSErez Shitrit 		break;
512365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_VPORT:
513365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_UPLINK:
51453fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_vport, stc_param, vport_number,
515365cdf5fSErez Shitrit 			 stc_attr->vport.vport_num);
51653fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_vport, stc_param, eswitch_owner_vhca_id,
517365cdf5fSErez Shitrit 			 stc_attr->vport.esw_owner_vhca_id);
518ac8415cfSErez Shitrit 		MLX5_SET(stc_ste_param_vport, stc_param, eswitch_owner_vhca_id_valid,
519ac8415cfSErez Shitrit 			 stc_attr->vport.eswitch_owner_vhca_id_valid);
520365cdf5fSErez Shitrit 		break;
521365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_DROP:
522365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_NOP:
523365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_TAG:
524365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_ALLOW:
525365cdf5fSErez Shitrit 		break;
526365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_ASO:
52753fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_execute_aso, stc_param, aso_object_id,
528365cdf5fSErez Shitrit 			 stc_attr->aso.devx_obj_id);
52953fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_execute_aso, stc_param, return_reg_id,
530365cdf5fSErez Shitrit 			 stc_attr->aso.return_reg_id);
53153fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_execute_aso, stc_param, aso_type,
532365cdf5fSErez Shitrit 			 stc_attr->aso.aso_type);
533365cdf5fSErez Shitrit 		break;
534365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_STE_TABLE:
53553fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_ste_table, stc_param, ste_obj_id,
536365cdf5fSErez Shitrit 			 stc_attr->ste_table.ste_obj_id);
53753fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_ste_table, stc_param, match_definer_id,
538365cdf5fSErez Shitrit 			 stc_attr->ste_table.match_definer_id);
53953fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_ste_table, stc_param, log_hash_size,
540365cdf5fSErez Shitrit 			 stc_attr->ste_table.log_hash_size);
541365cdf5fSErez Shitrit 		break;
542365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_REMOVE_WORDS:
54353fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_remove_words, stc_param, action_type,
544365cdf5fSErez Shitrit 			 MLX5_MODIFICATION_TYPE_REMOVE_WORDS);
54553fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_remove_words, stc_param, remove_start_anchor,
546365cdf5fSErez Shitrit 			 stc_attr->remove_words.start_anchor);
54753fc80acSItamar Gozlan 		MLX5_SET(stc_ste_param_remove_words, stc_param,
548365cdf5fSErez Shitrit 			 remove_size, stc_attr->remove_words.num_of_words);
549365cdf5fSErez Shitrit 		break;
550365cdf5fSErez Shitrit 	default:
551365cdf5fSErez Shitrit 		DR_LOG(ERR, "Not supported type %d", stc_attr->action_type);
552365cdf5fSErez Shitrit 		rte_errno = EINVAL;
553365cdf5fSErez Shitrit 		return rte_errno;
554365cdf5fSErez Shitrit 	}
555365cdf5fSErez Shitrit 	return 0;
556365cdf5fSErez Shitrit }
557365cdf5fSErez Shitrit 
558365cdf5fSErez Shitrit int
559365cdf5fSErez Shitrit mlx5dr_cmd_stc_modify(struct mlx5dr_devx_obj *devx_obj,
560365cdf5fSErez Shitrit 		      struct mlx5dr_cmd_stc_modify_attr *stc_attr)
561365cdf5fSErez Shitrit {
562365cdf5fSErez Shitrit 	uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
563365cdf5fSErez Shitrit 	uint32_t in[MLX5_ST_SZ_DW(create_stc_in)] = {0};
56453fc80acSItamar Gozlan 	void *stc_param;
565365cdf5fSErez Shitrit 	void *attr;
566365cdf5fSErez Shitrit 	int ret;
567365cdf5fSErez Shitrit 
568365cdf5fSErez Shitrit 	attr = MLX5_ADDR_OF(create_stc_in, in, hdr);
569365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
570365cdf5fSErez Shitrit 		 attr, opcode, MLX5_CMD_OP_MODIFY_GENERAL_OBJECT);
571365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
572365cdf5fSErez Shitrit 		 attr, obj_type, MLX5_GENERAL_OBJ_TYPE_STC);
573365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr, in, obj_id, devx_obj->id);
574365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr, in, obj_offset, stc_attr->stc_offset);
575365cdf5fSErez Shitrit 
576365cdf5fSErez Shitrit 	attr = MLX5_ADDR_OF(create_stc_in, in, stc);
577365cdf5fSErez Shitrit 	MLX5_SET(stc, attr, ste_action_offset, stc_attr->action_offset);
578365cdf5fSErez Shitrit 	MLX5_SET(stc, attr, action_type, stc_attr->action_type);
579bbddd062SAlex Vesker 	MLX5_SET(stc, attr, reparse_mode, stc_attr->reparse_mode);
580365cdf5fSErez Shitrit 	MLX5_SET64(stc, attr, modify_field_select,
581365cdf5fSErez Shitrit 		   MLX5_IFC_MODIFY_STC_FIELD_SELECT_NEW_STC);
582365cdf5fSErez Shitrit 
583365cdf5fSErez Shitrit 	/* Set destination TIRN, TAG, FT ID, STE ID */
58453fc80acSItamar Gozlan 	stc_param = MLX5_ADDR_OF(stc, attr, stc_param);
58553fc80acSItamar Gozlan 	ret = mlx5dr_cmd_stc_modify_set_stc_param(stc_attr, stc_param);
586365cdf5fSErez Shitrit 	if (ret)
587365cdf5fSErez Shitrit 		return ret;
588365cdf5fSErez Shitrit 
589365cdf5fSErez Shitrit 	ret = mlx5_glue->devx_obj_modify(devx_obj->obj, in, sizeof(in), out, sizeof(out));
590365cdf5fSErez Shitrit 	if (ret) {
59175226c96SErez Shitrit 		DR_LOG(ERR, "Failed to modify STC FW action_type %d (syndrome: %#x)",
59275226c96SErez Shitrit 		       stc_attr->action_type, mlx5dr_cmd_get_syndrome(out));
593365cdf5fSErez Shitrit 		rte_errno = errno;
594365cdf5fSErez Shitrit 	}
595365cdf5fSErez Shitrit 
596365cdf5fSErez Shitrit 	return ret;
597365cdf5fSErez Shitrit }
598365cdf5fSErez Shitrit 
599365cdf5fSErez Shitrit struct mlx5dr_devx_obj *
600365cdf5fSErez Shitrit mlx5dr_cmd_arg_create(struct ibv_context *ctx,
601365cdf5fSErez Shitrit 		      uint16_t log_obj_range,
602365cdf5fSErez Shitrit 		      uint32_t pd)
603365cdf5fSErez Shitrit {
604365cdf5fSErez Shitrit 	uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
605365cdf5fSErez Shitrit 	uint32_t in[MLX5_ST_SZ_DW(create_arg_in)] = {0};
606365cdf5fSErez Shitrit 	struct mlx5dr_devx_obj *devx_obj;
607365cdf5fSErez Shitrit 	void *attr;
608365cdf5fSErez Shitrit 
609365cdf5fSErez Shitrit 	devx_obj = simple_malloc(sizeof(*devx_obj));
610365cdf5fSErez Shitrit 	if (!devx_obj) {
611365cdf5fSErez Shitrit 		DR_LOG(ERR, "Failed to allocate memory for ARG object");
612365cdf5fSErez Shitrit 		rte_errno = ENOMEM;
613365cdf5fSErez Shitrit 		return NULL;
614365cdf5fSErez Shitrit 	}
615365cdf5fSErez Shitrit 
616365cdf5fSErez Shitrit 	attr = MLX5_ADDR_OF(create_arg_in, in, hdr);
617365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
618365cdf5fSErez Shitrit 		 attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
619365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
620365cdf5fSErez Shitrit 		 attr, obj_type, MLX5_GENERAL_OBJ_TYPE_ARG);
621365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
622365cdf5fSErez Shitrit 		 attr, log_obj_range, log_obj_range);
623365cdf5fSErez Shitrit 
624365cdf5fSErez Shitrit 	attr = MLX5_ADDR_OF(create_arg_in, in, arg);
625365cdf5fSErez Shitrit 	MLX5_SET(arg, attr, access_pd, pd);
626365cdf5fSErez Shitrit 
627365cdf5fSErez Shitrit 	devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
628365cdf5fSErez Shitrit 	if (!devx_obj->obj) {
62975226c96SErez Shitrit 		DR_LOG(ERR, "Failed to create ARG (syndrome: %#x)",
63075226c96SErez Shitrit 		       mlx5dr_cmd_get_syndrome(out));
631365cdf5fSErez Shitrit 		simple_free(devx_obj);
632365cdf5fSErez Shitrit 		rte_errno = errno;
633365cdf5fSErez Shitrit 		return NULL;
634365cdf5fSErez Shitrit 	}
635365cdf5fSErez Shitrit 
636365cdf5fSErez Shitrit 	devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
637365cdf5fSErez Shitrit 
638365cdf5fSErez Shitrit 	return devx_obj;
639365cdf5fSErez Shitrit }
640365cdf5fSErez Shitrit 
641365cdf5fSErez Shitrit struct mlx5dr_devx_obj *
642365cdf5fSErez Shitrit mlx5dr_cmd_header_modify_pattern_create(struct ibv_context *ctx,
643365cdf5fSErez Shitrit 					uint32_t pattern_length,
644365cdf5fSErez Shitrit 					uint8_t *actions)
645365cdf5fSErez Shitrit {
646365cdf5fSErez Shitrit 	uint32_t in[MLX5_ST_SZ_DW(create_header_modify_pattern_in)] = {0};
647365cdf5fSErez Shitrit 	uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
648365cdf5fSErez Shitrit 	struct mlx5dr_devx_obj *devx_obj;
64997e1a2ffSErez Shitrit 	uint64_t *pattern_data;
65097e1a2ffSErez Shitrit 	int num_of_actions;
651365cdf5fSErez Shitrit 	void *pattern;
652365cdf5fSErez Shitrit 	void *attr;
65397e1a2ffSErez Shitrit 	int i;
654365cdf5fSErez Shitrit 
655365cdf5fSErez Shitrit 	if (pattern_length > MAX_ACTIONS_DATA_IN_HEADER_MODIFY) {
656365cdf5fSErez Shitrit 		DR_LOG(ERR, "Pattern length %d exceeds limit %d",
657365cdf5fSErez Shitrit 			pattern_length, MAX_ACTIONS_DATA_IN_HEADER_MODIFY);
658365cdf5fSErez Shitrit 		rte_errno = EINVAL;
659365cdf5fSErez Shitrit 		return NULL;
660365cdf5fSErez Shitrit 	}
661365cdf5fSErez Shitrit 
662365cdf5fSErez Shitrit 	devx_obj = simple_malloc(sizeof(*devx_obj));
663365cdf5fSErez Shitrit 	if (!devx_obj) {
664365cdf5fSErez Shitrit 		DR_LOG(ERR, "Failed to allocate memory for header_modify_pattern object");
665365cdf5fSErez Shitrit 		rte_errno = ENOMEM;
666365cdf5fSErez Shitrit 		return NULL;
667365cdf5fSErez Shitrit 	}
668365cdf5fSErez Shitrit 	attr = MLX5_ADDR_OF(create_header_modify_pattern_in, in, hdr);
669365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
670365cdf5fSErez Shitrit 		 attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
671365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
672365cdf5fSErez Shitrit 		 attr, obj_type, MLX5_GENERAL_OBJ_TYPE_MODIFY_HEADER_PATTERN);
673365cdf5fSErez Shitrit 
674365cdf5fSErez Shitrit 	pattern = MLX5_ADDR_OF(create_header_modify_pattern_in, in, pattern);
675365cdf5fSErez Shitrit 	/* Pattern_length is in ddwords */
676365cdf5fSErez Shitrit 	MLX5_SET(header_modify_pattern_in, pattern, pattern_length, pattern_length / (2 * DW_SIZE));
677365cdf5fSErez Shitrit 
67897e1a2ffSErez Shitrit 	pattern_data = (uint64_t *)MLX5_ADDR_OF(header_modify_pattern_in, pattern, pattern_data);
679365cdf5fSErez Shitrit 	memcpy(pattern_data, actions, pattern_length);
680365cdf5fSErez Shitrit 
68197e1a2ffSErez Shitrit 	num_of_actions = pattern_length / MLX5DR_MODIFY_ACTION_SIZE;
68297e1a2ffSErez Shitrit 	for (i = 0; i < num_of_actions; i++) {
68397e1a2ffSErez Shitrit 		int type;
68497e1a2ffSErez Shitrit 
68597e1a2ffSErez Shitrit 		type = MLX5_GET(set_action_in, &pattern_data[i], action_type);
6861667b1d7SItamar Gozlan 		if (type != MLX5_MODIFICATION_TYPE_COPY &&
6871667b1d7SItamar Gozlan 		    type != MLX5_MODIFICATION_TYPE_ADD_FIELD)
68897e1a2ffSErez Shitrit 			/* Action typ-copy use all bytes for control */
68997e1a2ffSErez Shitrit 			MLX5_SET(set_action_in, &pattern_data[i], data, 0);
69097e1a2ffSErez Shitrit 	}
69197e1a2ffSErez Shitrit 
692365cdf5fSErez Shitrit 	devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
693365cdf5fSErez Shitrit 	if (!devx_obj->obj) {
69475226c96SErez Shitrit 		DR_LOG(ERR, "Failed to create header_modify_pattern (syndrome: %#x)",
69575226c96SErez Shitrit 		       mlx5dr_cmd_get_syndrome(out));
696365cdf5fSErez Shitrit 		rte_errno = errno;
697365cdf5fSErez Shitrit 		goto free_obj;
698365cdf5fSErez Shitrit 	}
699365cdf5fSErez Shitrit 
700365cdf5fSErez Shitrit 	devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
701365cdf5fSErez Shitrit 
702365cdf5fSErez Shitrit 	return devx_obj;
703365cdf5fSErez Shitrit 
704365cdf5fSErez Shitrit free_obj:
705365cdf5fSErez Shitrit 	simple_free(devx_obj);
706365cdf5fSErez Shitrit 	return NULL;
707365cdf5fSErez Shitrit }
708365cdf5fSErez Shitrit 
709365cdf5fSErez Shitrit struct mlx5dr_devx_obj *
710365cdf5fSErez Shitrit mlx5dr_cmd_ste_create(struct ibv_context *ctx,
711365cdf5fSErez Shitrit 		      struct mlx5dr_cmd_ste_create_attr *ste_attr)
712365cdf5fSErez Shitrit {
713365cdf5fSErez Shitrit 	uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
714365cdf5fSErez Shitrit 	uint32_t in[MLX5_ST_SZ_DW(create_ste_in)] = {0};
715365cdf5fSErez Shitrit 	struct mlx5dr_devx_obj *devx_obj;
716365cdf5fSErez Shitrit 	void *attr;
717365cdf5fSErez Shitrit 
718365cdf5fSErez Shitrit 	devx_obj = simple_malloc(sizeof(*devx_obj));
719365cdf5fSErez Shitrit 	if (!devx_obj) {
720365cdf5fSErez Shitrit 		DR_LOG(ERR, "Failed to allocate memory for STE object");
721365cdf5fSErez Shitrit 		rte_errno = ENOMEM;
722365cdf5fSErez Shitrit 		return NULL;
723365cdf5fSErez Shitrit 	}
724365cdf5fSErez Shitrit 
725365cdf5fSErez Shitrit 	attr = MLX5_ADDR_OF(create_ste_in, in, hdr);
726365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
727365cdf5fSErez Shitrit 		 attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
728365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
729365cdf5fSErez Shitrit 		 attr, obj_type, MLX5_GENERAL_OBJ_TYPE_STE);
730365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
731365cdf5fSErez Shitrit 		 attr, log_obj_range, ste_attr->log_obj_range);
732365cdf5fSErez Shitrit 
733365cdf5fSErez Shitrit 	attr = MLX5_ADDR_OF(create_ste_in, in, ste);
734365cdf5fSErez Shitrit 	MLX5_SET(ste, attr, table_type, ste_attr->table_type);
735365cdf5fSErez Shitrit 
736365cdf5fSErez Shitrit 	devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
737365cdf5fSErez Shitrit 	if (!devx_obj->obj) {
73875226c96SErez Shitrit 		DR_LOG(ERR, "Failed to create STE (syndrome: %#x)",
73975226c96SErez Shitrit 		       mlx5dr_cmd_get_syndrome(out));
740365cdf5fSErez Shitrit 		simple_free(devx_obj);
741365cdf5fSErez Shitrit 		rte_errno = errno;
742365cdf5fSErez Shitrit 		return NULL;
743365cdf5fSErez Shitrit 	}
744365cdf5fSErez Shitrit 
745365cdf5fSErez Shitrit 	devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
746365cdf5fSErez Shitrit 
747365cdf5fSErez Shitrit 	return devx_obj;
748365cdf5fSErez Shitrit }
749365cdf5fSErez Shitrit 
750365cdf5fSErez Shitrit struct mlx5dr_devx_obj *
751365cdf5fSErez Shitrit mlx5dr_cmd_definer_create(struct ibv_context *ctx,
752365cdf5fSErez Shitrit 			  struct mlx5dr_cmd_definer_create_attr *def_attr)
753365cdf5fSErez Shitrit {
754365cdf5fSErez Shitrit 	uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
755365cdf5fSErez Shitrit 	uint32_t in[MLX5_ST_SZ_DW(create_definer_in)] = {0};
756365cdf5fSErez Shitrit 	struct mlx5dr_devx_obj *devx_obj;
757365cdf5fSErez Shitrit 	void *ptr;
758365cdf5fSErez Shitrit 
759365cdf5fSErez Shitrit 	devx_obj = simple_malloc(sizeof(*devx_obj));
760365cdf5fSErez Shitrit 	if (!devx_obj) {
761365cdf5fSErez Shitrit 		DR_LOG(ERR, "Failed to allocate memory for definer object");
762365cdf5fSErez Shitrit 		rte_errno = ENOMEM;
763365cdf5fSErez Shitrit 		return NULL;
764365cdf5fSErez Shitrit 	}
765365cdf5fSErez Shitrit 
766365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
767365cdf5fSErez Shitrit 		 in, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
768365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
769365cdf5fSErez Shitrit 		 in, obj_type, MLX5_GENERAL_OBJ_TYPE_DEFINER);
770365cdf5fSErez Shitrit 
771365cdf5fSErez Shitrit 	ptr = MLX5_ADDR_OF(create_definer_in, in, definer);
772365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_id, MLX5_IFC_DEFINER_FORMAT_ID_SELECT);
773365cdf5fSErez Shitrit 
774365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_dw0, def_attr->dw_selector[0]);
775365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_dw1, def_attr->dw_selector[1]);
776365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_dw2, def_attr->dw_selector[2]);
777365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_dw3, def_attr->dw_selector[3]);
778365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_dw4, def_attr->dw_selector[4]);
779365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_dw5, def_attr->dw_selector[5]);
780365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_dw6, def_attr->dw_selector[6]);
781365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_dw7, def_attr->dw_selector[7]);
782365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_dw8, def_attr->dw_selector[8]);
783365cdf5fSErez Shitrit 
784365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_byte0, def_attr->byte_selector[0]);
785365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_byte1, def_attr->byte_selector[1]);
786365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_byte2, def_attr->byte_selector[2]);
787365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_byte3, def_attr->byte_selector[3]);
788365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_byte4, def_attr->byte_selector[4]);
789365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_byte5, def_attr->byte_selector[5]);
790365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_byte6, def_attr->byte_selector[6]);
791365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_byte7, def_attr->byte_selector[7]);
792365cdf5fSErez Shitrit 
793365cdf5fSErez Shitrit 	ptr = MLX5_ADDR_OF(definer, ptr, match_mask);
794365cdf5fSErez Shitrit 	memcpy(ptr, def_attr->match_mask, MLX5_FLD_SZ_BYTES(definer, match_mask));
795365cdf5fSErez Shitrit 
796365cdf5fSErez Shitrit 	devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
797365cdf5fSErez Shitrit 	if (!devx_obj->obj) {
79875226c96SErez Shitrit 		DR_LOG(ERR, "Failed to create Definer (syndrome: %#x)",
79975226c96SErez Shitrit 		       mlx5dr_cmd_get_syndrome(out));
800365cdf5fSErez Shitrit 		simple_free(devx_obj);
801365cdf5fSErez Shitrit 		rte_errno = errno;
802365cdf5fSErez Shitrit 		return NULL;
803365cdf5fSErez Shitrit 	}
804365cdf5fSErez Shitrit 
805365cdf5fSErez Shitrit 	devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
806365cdf5fSErez Shitrit 
807365cdf5fSErez Shitrit 	return devx_obj;
808365cdf5fSErez Shitrit }
809365cdf5fSErez Shitrit 
810365cdf5fSErez Shitrit struct mlx5dr_devx_obj *
811365cdf5fSErez Shitrit mlx5dr_cmd_sq_create(struct ibv_context *ctx,
812365cdf5fSErez Shitrit 		     struct mlx5dr_cmd_sq_create_attr *attr)
813365cdf5fSErez Shitrit {
814365cdf5fSErez Shitrit 	uint32_t out[MLX5_ST_SZ_DW(create_sq_out)] = {0};
815365cdf5fSErez Shitrit 	uint32_t in[MLX5_ST_SZ_DW(create_sq_in)] = {0};
816365cdf5fSErez Shitrit 	void *sqc = MLX5_ADDR_OF(create_sq_in, in, ctx);
817365cdf5fSErez Shitrit 	void *wqc = MLX5_ADDR_OF(sqc, sqc, wq);
818365cdf5fSErez Shitrit 	struct mlx5dr_devx_obj *devx_obj;
819365cdf5fSErez Shitrit 
820365cdf5fSErez Shitrit 	devx_obj = simple_malloc(sizeof(*devx_obj));
821365cdf5fSErez Shitrit 	if (!devx_obj) {
822365cdf5fSErez Shitrit 		DR_LOG(ERR, "Failed to create SQ");
823365cdf5fSErez Shitrit 		rte_errno = ENOMEM;
824365cdf5fSErez Shitrit 		return NULL;
825365cdf5fSErez Shitrit 	}
826365cdf5fSErez Shitrit 
827365cdf5fSErez Shitrit 	MLX5_SET(create_sq_in, in, opcode, MLX5_CMD_OP_CREATE_SQ);
828365cdf5fSErez Shitrit 	MLX5_SET(sqc, sqc, cqn, attr->cqn);
829365cdf5fSErez Shitrit 	MLX5_SET(sqc, sqc, flush_in_error_en, 1);
830365cdf5fSErez Shitrit 	MLX5_SET(sqc, sqc, non_wire, 1);
831d4444de8SViacheslav Ovsiienko 	MLX5_SET(sqc, sqc, ts_format, attr->ts_format);
832365cdf5fSErez Shitrit 	MLX5_SET(wq, wqc, wq_type, MLX5_WQ_TYPE_CYCLIC);
833365cdf5fSErez Shitrit 	MLX5_SET(wq, wqc, pd, attr->pdn);
834365cdf5fSErez Shitrit 	MLX5_SET(wq, wqc, uar_page, attr->page_id);
835365cdf5fSErez Shitrit 	MLX5_SET(wq, wqc, log_wq_stride, log2above(MLX5_SEND_WQE_BB));
836365cdf5fSErez Shitrit 	MLX5_SET(wq, wqc, log_wq_sz, attr->log_wq_sz);
837365cdf5fSErez Shitrit 	MLX5_SET(wq, wqc, dbr_umem_id, attr->dbr_id);
838365cdf5fSErez Shitrit 	MLX5_SET(wq, wqc, wq_umem_id, attr->wq_id);
839365cdf5fSErez Shitrit 
840365cdf5fSErez Shitrit 	devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
841365cdf5fSErez Shitrit 	if (!devx_obj->obj) {
842365cdf5fSErez Shitrit 		simple_free(devx_obj);
843365cdf5fSErez Shitrit 		rte_errno = errno;
844365cdf5fSErez Shitrit 		return NULL;
845365cdf5fSErez Shitrit 	}
846365cdf5fSErez Shitrit 
847365cdf5fSErez Shitrit 	devx_obj->id = MLX5_GET(create_sq_out, out, sqn);
848365cdf5fSErez Shitrit 
849365cdf5fSErez Shitrit 	return devx_obj;
850365cdf5fSErez Shitrit }
851365cdf5fSErez Shitrit 
85225cb2d2aSHamdan Igbaria struct mlx5dr_devx_obj *
85325cb2d2aSHamdan Igbaria mlx5dr_cmd_packet_reformat_create(struct ibv_context *ctx,
85425cb2d2aSHamdan Igbaria 				  struct mlx5dr_cmd_packet_reformat_create_attr *attr)
85525cb2d2aSHamdan Igbaria {
85625cb2d2aSHamdan Igbaria 	uint32_t out[MLX5_ST_SZ_DW(alloc_packet_reformat_out)] = {0};
85725cb2d2aSHamdan Igbaria 	size_t insz, cmd_data_sz, cmd_total_sz;
85825cb2d2aSHamdan Igbaria 	struct mlx5dr_devx_obj *devx_obj;
85925cb2d2aSHamdan Igbaria 	void *prctx;
86025cb2d2aSHamdan Igbaria 	void *pdata;
86125cb2d2aSHamdan Igbaria 	void *in;
86225cb2d2aSHamdan Igbaria 
86325cb2d2aSHamdan Igbaria 	cmd_total_sz = MLX5_ST_SZ_BYTES(alloc_packet_reformat_context_in);
86425cb2d2aSHamdan Igbaria 	cmd_total_sz += MLX5_ST_SZ_BYTES(packet_reformat_context_in);
86525cb2d2aSHamdan Igbaria 	cmd_data_sz = MLX5_FLD_SZ_BYTES(packet_reformat_context_in, reformat_data);
86625cb2d2aSHamdan Igbaria 	insz = align(cmd_total_sz + attr->data_sz - cmd_data_sz, DW_SIZE);
86725cb2d2aSHamdan Igbaria 	in = simple_calloc(1, insz);
86825cb2d2aSHamdan Igbaria 	if (!in) {
86925cb2d2aSHamdan Igbaria 		rte_errno = ENOMEM;
87025cb2d2aSHamdan Igbaria 		return NULL;
87125cb2d2aSHamdan Igbaria 	}
87225cb2d2aSHamdan Igbaria 
87325cb2d2aSHamdan Igbaria 	MLX5_SET(alloc_packet_reformat_context_in, in, opcode,
87425cb2d2aSHamdan Igbaria 		 MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT);
87525cb2d2aSHamdan Igbaria 
87625cb2d2aSHamdan Igbaria 	prctx = MLX5_ADDR_OF(alloc_packet_reformat_context_in, in,
87725cb2d2aSHamdan Igbaria 			     packet_reformat_context);
87825cb2d2aSHamdan Igbaria 	pdata = MLX5_ADDR_OF(packet_reformat_context_in, prctx, reformat_data);
87925cb2d2aSHamdan Igbaria 
88025cb2d2aSHamdan Igbaria 	MLX5_SET(packet_reformat_context_in, prctx, reformat_type, attr->type);
88125cb2d2aSHamdan Igbaria 	MLX5_SET(packet_reformat_context_in, prctx, reformat_param_0, attr->reformat_param_0);
88225cb2d2aSHamdan Igbaria 	MLX5_SET(packet_reformat_context_in, prctx, reformat_data_size, attr->data_sz);
88325cb2d2aSHamdan Igbaria 	memcpy(pdata, attr->data, attr->data_sz);
88425cb2d2aSHamdan Igbaria 
88525cb2d2aSHamdan Igbaria 	devx_obj = simple_malloc(sizeof(*devx_obj));
88625cb2d2aSHamdan Igbaria 	if (!devx_obj) {
88725cb2d2aSHamdan Igbaria 		DR_LOG(ERR, "Failed to allocate memory for packet reformat object");
88825cb2d2aSHamdan Igbaria 		rte_errno = ENOMEM;
88925cb2d2aSHamdan Igbaria 		goto out_free_in;
89025cb2d2aSHamdan Igbaria 	}
89125cb2d2aSHamdan Igbaria 
89225cb2d2aSHamdan Igbaria 	devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, insz, out, sizeof(out));
89325cb2d2aSHamdan Igbaria 	if (!devx_obj->obj) {
89425cb2d2aSHamdan Igbaria 		DR_LOG(ERR, "Failed to create packet reformat");
89525cb2d2aSHamdan Igbaria 		rte_errno = errno;
89625cb2d2aSHamdan Igbaria 		goto out_free_devx;
89725cb2d2aSHamdan Igbaria 	}
89825cb2d2aSHamdan Igbaria 
89925cb2d2aSHamdan Igbaria 	devx_obj->id = MLX5_GET(alloc_packet_reformat_out, out, packet_reformat_id);
90025cb2d2aSHamdan Igbaria 
90125cb2d2aSHamdan Igbaria 	simple_free(in);
90225cb2d2aSHamdan Igbaria 
90325cb2d2aSHamdan Igbaria 	return devx_obj;
90425cb2d2aSHamdan Igbaria 
90525cb2d2aSHamdan Igbaria out_free_devx:
90625cb2d2aSHamdan Igbaria 	simple_free(devx_obj);
90725cb2d2aSHamdan Igbaria out_free_in:
90825cb2d2aSHamdan Igbaria 	simple_free(in);
90925cb2d2aSHamdan Igbaria 	return NULL;
91025cb2d2aSHamdan Igbaria }
91125cb2d2aSHamdan Igbaria 
912365cdf5fSErez Shitrit int mlx5dr_cmd_sq_modify_rdy(struct mlx5dr_devx_obj *devx_obj)
913365cdf5fSErez Shitrit {
914365cdf5fSErez Shitrit 	uint32_t out[MLX5_ST_SZ_DW(modify_sq_out)] = {0};
915365cdf5fSErez Shitrit 	uint32_t in[MLX5_ST_SZ_DW(modify_sq_in)] = {0};
916365cdf5fSErez Shitrit 	void *sqc = MLX5_ADDR_OF(modify_sq_in, in, ctx);
917365cdf5fSErez Shitrit 	int ret;
918365cdf5fSErez Shitrit 
919365cdf5fSErez Shitrit 	MLX5_SET(modify_sq_in, in, opcode, MLX5_CMD_OP_MODIFY_SQ);
920365cdf5fSErez Shitrit 	MLX5_SET(modify_sq_in, in, sqn, devx_obj->id);
921365cdf5fSErez Shitrit 	MLX5_SET(modify_sq_in, in, sq_state, MLX5_SQC_STATE_RST);
922365cdf5fSErez Shitrit 	MLX5_SET(sqc, sqc, state, MLX5_SQC_STATE_RDY);
923365cdf5fSErez Shitrit 
924365cdf5fSErez Shitrit 	ret = mlx5_glue->devx_obj_modify(devx_obj->obj, in, sizeof(in), out, sizeof(out));
925365cdf5fSErez Shitrit 	if (ret) {
92675226c96SErez Shitrit 		DR_LOG(ERR, "Failed to modify SQ (syndrome: %#x)",
92775226c96SErez Shitrit 		       mlx5dr_cmd_get_syndrome(out));
928365cdf5fSErez Shitrit 		rte_errno = errno;
929365cdf5fSErez Shitrit 	}
930365cdf5fSErez Shitrit 
931365cdf5fSErez Shitrit 	return ret;
932365cdf5fSErez Shitrit }
933365cdf5fSErez Shitrit 
934720439d8SYevgeny Kliteynik int mlx5dr_cmd_allow_other_vhca_access(struct ibv_context *ctx,
935720439d8SYevgeny Kliteynik 				       struct mlx5dr_cmd_allow_other_vhca_access_attr *attr)
936720439d8SYevgeny Kliteynik {
937720439d8SYevgeny Kliteynik 	uint32_t out[MLX5_ST_SZ_DW(allow_other_vhca_access_out)] = {0};
938720439d8SYevgeny Kliteynik 	uint32_t in[MLX5_ST_SZ_DW(allow_other_vhca_access_in)] = {0};
939720439d8SYevgeny Kliteynik 	void *key;
940720439d8SYevgeny Kliteynik 	int ret;
941720439d8SYevgeny Kliteynik 
942720439d8SYevgeny Kliteynik 	MLX5_SET(allow_other_vhca_access_in,
943720439d8SYevgeny Kliteynik 		 in, opcode, MLX5_CMD_OP_ALLOW_OTHER_VHCA_ACCESS);
944720439d8SYevgeny Kliteynik 	MLX5_SET(allow_other_vhca_access_in,
945720439d8SYevgeny Kliteynik 		 in, object_type_to_be_accessed, attr->obj_type);
946720439d8SYevgeny Kliteynik 	MLX5_SET(allow_other_vhca_access_in,
947720439d8SYevgeny Kliteynik 		 in, object_id_to_be_accessed, attr->obj_id);
948720439d8SYevgeny Kliteynik 
949720439d8SYevgeny Kliteynik 	key = MLX5_ADDR_OF(allow_other_vhca_access_in, in, access_key);
950720439d8SYevgeny Kliteynik 	memcpy(key, attr->access_key, sizeof(attr->access_key));
951720439d8SYevgeny Kliteynik 
952720439d8SYevgeny Kliteynik 	ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
953720439d8SYevgeny Kliteynik 	if (ret) {
954720439d8SYevgeny Kliteynik 		DR_LOG(ERR, "Failed to execute ALLOW_OTHER_VHCA_ACCESS command");
955720439d8SYevgeny Kliteynik 		rte_errno = errno;
956720439d8SYevgeny Kliteynik 		return rte_errno;
957720439d8SYevgeny Kliteynik 	}
958720439d8SYevgeny Kliteynik 
959720439d8SYevgeny Kliteynik 	return 0;
960720439d8SYevgeny Kliteynik }
961720439d8SYevgeny Kliteynik 
962ed695274SYevgeny Kliteynik struct mlx5dr_devx_obj *
963ed695274SYevgeny Kliteynik mlx5dr_cmd_alias_obj_create(struct ibv_context *ctx,
964ed695274SYevgeny Kliteynik 			    struct mlx5dr_cmd_alias_obj_create_attr *alias_attr)
965ed695274SYevgeny Kliteynik {
966ed695274SYevgeny Kliteynik 	uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
967ed695274SYevgeny Kliteynik 	uint32_t in[MLX5_ST_SZ_DW(create_alias_obj_in)] = {0};
968ed695274SYevgeny Kliteynik 	struct mlx5dr_devx_obj *devx_obj;
969ed695274SYevgeny Kliteynik 	void *attr;
970ed695274SYevgeny Kliteynik 	void *key;
971ed695274SYevgeny Kliteynik 
972ed695274SYevgeny Kliteynik 	devx_obj = simple_malloc(sizeof(*devx_obj));
973ed695274SYevgeny Kliteynik 	if (!devx_obj) {
974ed695274SYevgeny Kliteynik 		DR_LOG(ERR, "Failed to allocate memory for ALIAS general object");
975ed695274SYevgeny Kliteynik 		rte_errno = ENOMEM;
976ed695274SYevgeny Kliteynik 		return NULL;
977ed695274SYevgeny Kliteynik 	}
978ed695274SYevgeny Kliteynik 
979ed695274SYevgeny Kliteynik 	attr = MLX5_ADDR_OF(create_alias_obj_in, in, hdr);
980ed695274SYevgeny Kliteynik 	MLX5_SET(general_obj_in_cmd_hdr,
981ed695274SYevgeny Kliteynik 		 attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
982ed695274SYevgeny Kliteynik 	MLX5_SET(general_obj_in_cmd_hdr,
983ed695274SYevgeny Kliteynik 		 attr, obj_type, alias_attr->obj_type);
984ed695274SYevgeny Kliteynik 	MLX5_SET(general_obj_in_cmd_hdr, attr, alias_object, 1);
985ed695274SYevgeny Kliteynik 
986ed695274SYevgeny Kliteynik 	attr = MLX5_ADDR_OF(create_alias_obj_in, in, alias_ctx);
987ed695274SYevgeny Kliteynik 	MLX5_SET(alias_context, attr, vhca_id_to_be_accessed, alias_attr->vhca_id);
988ed695274SYevgeny Kliteynik 	MLX5_SET(alias_context, attr, object_id_to_be_accessed, alias_attr->obj_id);
989ed695274SYevgeny Kliteynik 
990ed695274SYevgeny Kliteynik 	key = MLX5_ADDR_OF(alias_context, attr, access_key);
991ed695274SYevgeny Kliteynik 	memcpy(key, alias_attr->access_key, sizeof(alias_attr->access_key));
992ed695274SYevgeny Kliteynik 
993ed695274SYevgeny Kliteynik 	devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
994ed695274SYevgeny Kliteynik 	if (!devx_obj->obj) {
99575226c96SErez Shitrit 		DR_LOG(ERR, "Failed to create ALIAS OBJ (syndrome: %#x)",
99675226c96SErez Shitrit 		       mlx5dr_cmd_get_syndrome(out));
997ed695274SYevgeny Kliteynik 		simple_free(devx_obj);
998ed695274SYevgeny Kliteynik 		rte_errno = errno;
999ed695274SYevgeny Kliteynik 		return NULL;
1000ed695274SYevgeny Kliteynik 	}
1001ed695274SYevgeny Kliteynik 
1002ed695274SYevgeny Kliteynik 	devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
1003ed695274SYevgeny Kliteynik 
1004ed695274SYevgeny Kliteynik 	return devx_obj;
1005ed695274SYevgeny Kliteynik }
1006ed695274SYevgeny Kliteynik 
100712802ab2SAlex Vesker int mlx5dr_cmd_generate_wqe(struct ibv_context *ctx,
100812802ab2SAlex Vesker 			    struct mlx5dr_cmd_generate_wqe_attr *attr,
100912802ab2SAlex Vesker 			    struct mlx5_cqe64 *ret_cqe)
101012802ab2SAlex Vesker {
101112802ab2SAlex Vesker 	uint32_t out[MLX5_ST_SZ_DW(generate_wqe_out)] = {0};
101212802ab2SAlex Vesker 	uint32_t in[MLX5_ST_SZ_DW(generate_wqe_in)] = {0};
101312802ab2SAlex Vesker 	uint8_t status;
101412802ab2SAlex Vesker 	void *ptr;
101512802ab2SAlex Vesker 	int ret;
101612802ab2SAlex Vesker 
101712802ab2SAlex Vesker 	MLX5_SET(generate_wqe_in, in, opcode, MLX5_CMD_OP_GENERATE_WQE);
101812802ab2SAlex Vesker 	MLX5_SET(generate_wqe_in, in, pdn, attr->pdn);
101912802ab2SAlex Vesker 
102012802ab2SAlex Vesker 	ptr = MLX5_ADDR_OF(generate_wqe_in, in, wqe_ctrl);
102112802ab2SAlex Vesker 	memcpy(ptr, attr->wqe_ctrl, MLX5_FLD_SZ_BYTES(generate_wqe_in, wqe_ctrl));
102212802ab2SAlex Vesker 
102312802ab2SAlex Vesker 	ptr = MLX5_ADDR_OF(generate_wqe_in, in, wqe_gta_ctrl);
102412802ab2SAlex Vesker 	memcpy(ptr, attr->gta_ctrl, MLX5_FLD_SZ_BYTES(generate_wqe_in, wqe_gta_ctrl));
102512802ab2SAlex Vesker 
102612802ab2SAlex Vesker 	ptr = MLX5_ADDR_OF(generate_wqe_in, in, wqe_gta_data_0);
102712802ab2SAlex Vesker 	memcpy(ptr, attr->gta_data_0, MLX5_FLD_SZ_BYTES(generate_wqe_in, wqe_gta_data_0));
102812802ab2SAlex Vesker 
102912802ab2SAlex Vesker 	if (attr->gta_data_1) {
103012802ab2SAlex Vesker 		ptr = MLX5_ADDR_OF(generate_wqe_in, in, wqe_gta_data_1);
103112802ab2SAlex Vesker 		memcpy(ptr, attr->gta_data_1, MLX5_FLD_SZ_BYTES(generate_wqe_in, wqe_gta_data_1));
103212802ab2SAlex Vesker 	}
103312802ab2SAlex Vesker 
103412802ab2SAlex Vesker 	ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
103512802ab2SAlex Vesker 	if (ret) {
1036*29cd96c9SErez Shitrit 		DR_LOG(ERR, "Failed to write GTA WQE using FW (syndrome: %#x)",
1037*29cd96c9SErez Shitrit 		       mlx5dr_cmd_get_syndrome(out));
103812802ab2SAlex Vesker 		rte_errno = errno;
103912802ab2SAlex Vesker 		return rte_errno;
104012802ab2SAlex Vesker 	}
104112802ab2SAlex Vesker 
104212802ab2SAlex Vesker 	status = MLX5_GET(generate_wqe_out, out, status);
104312802ab2SAlex Vesker 	if (status) {
104412802ab2SAlex Vesker 		DR_LOG(ERR, "Invalid FW CQE status %d", status);
104512802ab2SAlex Vesker 		rte_errno = EINVAL;
104612802ab2SAlex Vesker 		return rte_errno;
104712802ab2SAlex Vesker 	}
104812802ab2SAlex Vesker 
104912802ab2SAlex Vesker 	ptr = MLX5_ADDR_OF(generate_wqe_out, out, cqe_data);
105012802ab2SAlex Vesker 	memcpy(ret_cqe, ptr, sizeof(*ret_cqe));
105112802ab2SAlex Vesker 
105212802ab2SAlex Vesker 	return 0;
105312802ab2SAlex Vesker }
105412802ab2SAlex Vesker 
1055365cdf5fSErez Shitrit int mlx5dr_cmd_query_caps(struct ibv_context *ctx,
1056365cdf5fSErez Shitrit 			  struct mlx5dr_cmd_query_caps *caps)
1057365cdf5fSErez Shitrit {
1058365cdf5fSErez Shitrit 	uint32_t out[MLX5_ST_SZ_DW(query_hca_cap_out)] = {0};
1059365cdf5fSErez Shitrit 	uint32_t in[MLX5_ST_SZ_DW(query_hca_cap_in)] = {0};
1060365cdf5fSErez Shitrit 	const struct flow_hw_port_info *port_info;
1061365cdf5fSErez Shitrit 	struct ibv_device_attr_ex attr_ex;
1062b2300900SYevgeny Kliteynik 	u32 res;
1063365cdf5fSErez Shitrit 	int ret;
1064365cdf5fSErez Shitrit 
1065365cdf5fSErez Shitrit 	MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP);
1066365cdf5fSErez Shitrit 	MLX5_SET(query_hca_cap_in, in, op_mod,
1067365cdf5fSErez Shitrit 		 MLX5_GET_HCA_CAP_OP_MOD_GENERAL_DEVICE |
1068365cdf5fSErez Shitrit 		 MLX5_HCA_CAP_OPMOD_GET_CUR);
1069365cdf5fSErez Shitrit 
1070365cdf5fSErez Shitrit 	ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
1071365cdf5fSErez Shitrit 	if (ret) {
1072365cdf5fSErez Shitrit 		DR_LOG(ERR, "Failed to query device caps");
1073365cdf5fSErez Shitrit 		rte_errno = errno;
1074365cdf5fSErez Shitrit 		return rte_errno;
1075365cdf5fSErez Shitrit 	}
1076365cdf5fSErez Shitrit 
1077365cdf5fSErez Shitrit 	caps->wqe_based_update =
1078365cdf5fSErez Shitrit 		MLX5_GET(query_hca_cap_out, out,
1079365cdf5fSErez Shitrit 			 capability.cmd_hca_cap.wqe_based_flow_table_update_cap);
1080365cdf5fSErez Shitrit 
1081365cdf5fSErez Shitrit 	caps->eswitch_manager = MLX5_GET(query_hca_cap_out, out,
1082365cdf5fSErez Shitrit 					 capability.cmd_hca_cap.eswitch_manager);
1083365cdf5fSErez Shitrit 
1084365cdf5fSErez Shitrit 	caps->flex_protocols = MLX5_GET(query_hca_cap_out, out,
1085365cdf5fSErez Shitrit 					capability.cmd_hca_cap.flex_parser_protocols);
1086365cdf5fSErez Shitrit 
1087365cdf5fSErez Shitrit 	caps->log_header_modify_argument_granularity =
1088365cdf5fSErez Shitrit 		MLX5_GET(query_hca_cap_out, out,
1089365cdf5fSErez Shitrit 			 capability.cmd_hca_cap.log_header_modify_argument_granularity);
1090365cdf5fSErez Shitrit 
1091365cdf5fSErez Shitrit 	caps->log_header_modify_argument_granularity -=
1092365cdf5fSErez Shitrit 			MLX5_GET(query_hca_cap_out, out,
1093365cdf5fSErez Shitrit 				 capability.cmd_hca_cap.
1094365cdf5fSErez Shitrit 				 log_header_modify_argument_granularity_offset);
1095365cdf5fSErez Shitrit 
1096365cdf5fSErez Shitrit 	caps->log_header_modify_argument_max_alloc =
1097365cdf5fSErez Shitrit 		MLX5_GET(query_hca_cap_out, out,
1098365cdf5fSErez Shitrit 			 capability.cmd_hca_cap.log_header_modify_argument_max_alloc);
1099365cdf5fSErez Shitrit 
1100365cdf5fSErez Shitrit 	caps->definer_format_sup =
1101365cdf5fSErez Shitrit 		MLX5_GET64(query_hca_cap_out, out,
1102365cdf5fSErez Shitrit 			   capability.cmd_hca_cap.match_definer_format_supported);
1103365cdf5fSErez Shitrit 
11047ab100f6SErez Shitrit 	caps->vhca_id = MLX5_GET(query_hca_cap_out, out,
11057ab100f6SErez Shitrit 				 capability.cmd_hca_cap.vhca_id);
11067ab100f6SErez Shitrit 
1107d4444de8SViacheslav Ovsiienko 	caps->sq_ts_format = MLX5_GET(query_hca_cap_out, out,
1108d4444de8SViacheslav Ovsiienko 				      capability.cmd_hca_cap.sq_ts_format);
1109d4444de8SViacheslav Ovsiienko 
111081cf20a2SHamdan Igbaria 	caps->ipsec_offload = MLX5_GET(query_hca_cap_out, out,
111181cf20a2SHamdan Igbaria 				      capability.cmd_hca_cap.ipsec_offload);
111281cf20a2SHamdan Igbaria 
11132acdf09bSHamdan Igbaria 	caps->roce = MLX5_GET(query_hca_cap_out, out, capability.cmd_hca_cap.roce);
11142acdf09bSHamdan Igbaria 
1115365cdf5fSErez Shitrit 	MLX5_SET(query_hca_cap_in, in, op_mod,
1116365cdf5fSErez Shitrit 		 MLX5_GET_HCA_CAP_OP_MOD_GENERAL_DEVICE_2 |
1117365cdf5fSErez Shitrit 		 MLX5_HCA_CAP_OPMOD_GET_CUR);
1118365cdf5fSErez Shitrit 
1119365cdf5fSErez Shitrit 	ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
1120365cdf5fSErez Shitrit 	if (ret) {
1121365cdf5fSErez Shitrit 		DR_LOG(ERR, "Failed to query device caps");
1122365cdf5fSErez Shitrit 		rte_errno = errno;
1123365cdf5fSErez Shitrit 		return rte_errno;
1124365cdf5fSErez Shitrit 	}
1125365cdf5fSErez Shitrit 
1126365cdf5fSErez Shitrit 	caps->full_dw_jumbo_support = MLX5_GET(query_hca_cap_out, out,
1127365cdf5fSErez Shitrit 					       capability.cmd_hca_cap_2.
1128365cdf5fSErez Shitrit 					       format_select_dw_8_6_ext);
1129365cdf5fSErez Shitrit 
1130365cdf5fSErez Shitrit 	caps->format_select_gtpu_dw_0 = MLX5_GET(query_hca_cap_out, out,
1131365cdf5fSErez Shitrit 						 capability.cmd_hca_cap_2.
1132365cdf5fSErez Shitrit 						 format_select_dw_gtpu_dw_0);
1133365cdf5fSErez Shitrit 
1134365cdf5fSErez Shitrit 	caps->format_select_gtpu_dw_1 = MLX5_GET(query_hca_cap_out, out,
1135365cdf5fSErez Shitrit 						 capability.cmd_hca_cap_2.
1136365cdf5fSErez Shitrit 						 format_select_dw_gtpu_dw_1);
1137365cdf5fSErez Shitrit 
1138365cdf5fSErez Shitrit 	caps->format_select_gtpu_dw_2 = MLX5_GET(query_hca_cap_out, out,
1139365cdf5fSErez Shitrit 						 capability.cmd_hca_cap_2.
1140365cdf5fSErez Shitrit 						 format_select_dw_gtpu_dw_2);
1141365cdf5fSErez Shitrit 
1142365cdf5fSErez Shitrit 	caps->format_select_gtpu_ext_dw_0 = MLX5_GET(query_hca_cap_out, out,
1143365cdf5fSErez Shitrit 						     capability.cmd_hca_cap_2.
1144365cdf5fSErez Shitrit 						     format_select_dw_gtpu_first_ext_dw_0);
1145365cdf5fSErez Shitrit 
114667acee3aSAlex Vesker 	caps->supp_type_gen_wqe = MLX5_GET(query_hca_cap_out, out,
114767acee3aSAlex Vesker 					   capability.cmd_hca_cap_2.
114867acee3aSAlex Vesker 					   generate_wqe_type);
114967acee3aSAlex Vesker 
1150b2300900SYevgeny Kliteynik 	/* check cross-VHCA support in cap2 */
1151b2300900SYevgeny Kliteynik 	res =
1152b2300900SYevgeny Kliteynik 	MLX5_GET(query_hca_cap_out, out,
1153b2300900SYevgeny Kliteynik 		capability.cmd_hca_cap_2.cross_vhca_object_to_object_supported);
1154b2300900SYevgeny Kliteynik 
1155b2300900SYevgeny Kliteynik 	caps->cross_vhca_resources = (res & MLX5_CROSS_VHCA_OBJ_TO_OBJ_TYPE_STC_TO_TIR) &&
1156b2300900SYevgeny Kliteynik 				     (res & MLX5_CROSS_VHCA_OBJ_TO_OBJ_TYPE_STC_TO_FT) &&
1157b2300900SYevgeny Kliteynik 				     (res & MLX5_CROSS_VHCA_OBJ_TO_OBJ_TYPE_FT_TO_RTC);
1158b2300900SYevgeny Kliteynik 
1159b2300900SYevgeny Kliteynik 	res =
1160b2300900SYevgeny Kliteynik 	MLX5_GET(query_hca_cap_out, out,
1161b2300900SYevgeny Kliteynik 		capability.cmd_hca_cap_2.allowed_object_for_other_vhca_access);
1162b2300900SYevgeny Kliteynik 
1163b2300900SYevgeny Kliteynik 	caps->cross_vhca_resources &= (res & MLX5_CROSS_VHCA_ALLOWED_OBJS_TIR) &&
1164b2300900SYevgeny Kliteynik 				      (res & MLX5_CROSS_VHCA_ALLOWED_OBJS_FT) &&
1165b2300900SYevgeny Kliteynik 				      (res & MLX5_CROSS_VHCA_ALLOWED_OBJS_RTC);
1166b2300900SYevgeny Kliteynik 
11677f5e6de5SItamar Gozlan 	caps->flow_table_hash_type = MLX5_GET(query_hca_cap_out, out,
11687f5e6de5SItamar Gozlan 					      capability.cmd_hca_cap_2.flow_table_hash_type);
11697f5e6de5SItamar Gozlan 
11702acdf09bSHamdan Igbaria 	caps->encap_entropy_hash_type = MLX5_GET(query_hca_cap_out, out,
11712acdf09bSHamdan Igbaria 						 capability.cmd_hca_cap_2.encap_entropy_hash_type);
11722acdf09bSHamdan Igbaria 
1173365cdf5fSErez Shitrit 	MLX5_SET(query_hca_cap_in, in, op_mod,
1174365cdf5fSErez Shitrit 		 MLX5_GET_HCA_CAP_OP_MOD_NIC_FLOW_TABLE |
1175365cdf5fSErez Shitrit 		 MLX5_HCA_CAP_OPMOD_GET_CUR);
1176365cdf5fSErez Shitrit 
1177365cdf5fSErez Shitrit 	ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
1178365cdf5fSErez Shitrit 	if (ret) {
1179365cdf5fSErez Shitrit 		DR_LOG(ERR, "Failed to query flow table caps");
1180365cdf5fSErez Shitrit 		rte_errno = errno;
1181365cdf5fSErez Shitrit 		return rte_errno;
1182365cdf5fSErez Shitrit 	}
1183365cdf5fSErez Shitrit 
1184365cdf5fSErez Shitrit 	caps->nic_ft.max_level = MLX5_GET(query_hca_cap_out, out,
1185365cdf5fSErez Shitrit 					  capability.flow_table_nic_cap.
1186365cdf5fSErez Shitrit 					  flow_table_properties_nic_receive.max_ft_level);
1187365cdf5fSErez Shitrit 
1188365cdf5fSErez Shitrit 	caps->nic_ft.reparse = MLX5_GET(query_hca_cap_out, out,
1189365cdf5fSErez Shitrit 					capability.flow_table_nic_cap.
1190365cdf5fSErez Shitrit 					flow_table_properties_nic_receive.reparse);
1191365cdf5fSErez Shitrit 
1192b81f95caSItamar Gozlan 	caps->nic_ft.ignore_flow_level_rtc_valid =
1193b81f95caSItamar Gozlan 		MLX5_GET(query_hca_cap_out,
1194b81f95caSItamar Gozlan 			 out,
1195b81f95caSItamar Gozlan 			 capability.flow_table_nic_cap.
1196b81f95caSItamar Gozlan 			 flow_table_properties_nic_receive.ignore_flow_level_rtc_valid);
1197b81f95caSItamar Gozlan 
1198b2300900SYevgeny Kliteynik 	/* check cross-VHCA support in flow table properties */
1199b2300900SYevgeny Kliteynik 	res =
1200b2300900SYevgeny Kliteynik 	MLX5_GET(query_hca_cap_out, out,
1201b2300900SYevgeny Kliteynik 		capability.flow_table_nic_cap.flow_table_properties_nic_receive.cross_vhca_object);
1202b2300900SYevgeny Kliteynik 	caps->cross_vhca_resources &= res;
1203b2300900SYevgeny Kliteynik 
1204365cdf5fSErez Shitrit 	if (caps->wqe_based_update) {
1205365cdf5fSErez Shitrit 		MLX5_SET(query_hca_cap_in, in, op_mod,
1206365cdf5fSErez Shitrit 			 MLX5_GET_HCA_CAP_OP_MOD_WQE_BASED_FLOW_TABLE |
1207365cdf5fSErez Shitrit 			 MLX5_HCA_CAP_OPMOD_GET_CUR);
1208365cdf5fSErez Shitrit 
1209365cdf5fSErez Shitrit 		ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
1210365cdf5fSErez Shitrit 		if (ret) {
1211365cdf5fSErez Shitrit 			DR_LOG(ERR, "Failed to query WQE based FT caps");
1212365cdf5fSErez Shitrit 			rte_errno = errno;
1213365cdf5fSErez Shitrit 			return rte_errno;
1214365cdf5fSErez Shitrit 		}
1215365cdf5fSErez Shitrit 
1216365cdf5fSErez Shitrit 		caps->rtc_reparse_mode = MLX5_GET(query_hca_cap_out, out,
1217365cdf5fSErez Shitrit 						  capability.wqe_based_flow_table_cap.
1218365cdf5fSErez Shitrit 						  rtc_reparse_mode);
1219365cdf5fSErez Shitrit 
1220365cdf5fSErez Shitrit 		caps->ste_format = MLX5_GET(query_hca_cap_out, out,
1221365cdf5fSErez Shitrit 					    capability.wqe_based_flow_table_cap.
1222365cdf5fSErez Shitrit 					    ste_format);
1223365cdf5fSErez Shitrit 
1224365cdf5fSErez Shitrit 		caps->rtc_index_mode = MLX5_GET(query_hca_cap_out, out,
1225365cdf5fSErez Shitrit 						capability.wqe_based_flow_table_cap.
1226365cdf5fSErez Shitrit 						rtc_index_mode);
1227365cdf5fSErez Shitrit 
1228365cdf5fSErez Shitrit 		caps->rtc_log_depth_max = MLX5_GET(query_hca_cap_out, out,
1229365cdf5fSErez Shitrit 						   capability.wqe_based_flow_table_cap.
1230365cdf5fSErez Shitrit 						   rtc_log_depth_max);
1231365cdf5fSErez Shitrit 
1232365cdf5fSErez Shitrit 		caps->ste_alloc_log_max = MLX5_GET(query_hca_cap_out, out,
1233365cdf5fSErez Shitrit 						   capability.wqe_based_flow_table_cap.
1234365cdf5fSErez Shitrit 						   ste_alloc_log_max);
1235365cdf5fSErez Shitrit 
1236365cdf5fSErez Shitrit 		caps->ste_alloc_log_gran = MLX5_GET(query_hca_cap_out, out,
1237365cdf5fSErez Shitrit 						    capability.wqe_based_flow_table_cap.
1238365cdf5fSErez Shitrit 						    ste_alloc_log_granularity);
1239365cdf5fSErez Shitrit 
1240365cdf5fSErez Shitrit 		caps->trivial_match_definer = MLX5_GET(query_hca_cap_out, out,
1241365cdf5fSErez Shitrit 						       capability.wqe_based_flow_table_cap.
1242365cdf5fSErez Shitrit 						       trivial_match_definer);
1243365cdf5fSErez Shitrit 
1244365cdf5fSErez Shitrit 		caps->stc_alloc_log_max = MLX5_GET(query_hca_cap_out, out,
1245365cdf5fSErez Shitrit 						   capability.wqe_based_flow_table_cap.
1246365cdf5fSErez Shitrit 						   stc_alloc_log_max);
1247365cdf5fSErez Shitrit 
1248365cdf5fSErez Shitrit 		caps->stc_alloc_log_gran = MLX5_GET(query_hca_cap_out, out,
1249365cdf5fSErez Shitrit 						    capability.wqe_based_flow_table_cap.
1250365cdf5fSErez Shitrit 						    stc_alloc_log_granularity);
125151f68dbaSYevgeny Kliteynik 
125251f68dbaSYevgeny Kliteynik 		caps->rtc_hash_split_table = MLX5_GET(query_hca_cap_out, out,
125351f68dbaSYevgeny Kliteynik 						      capability.wqe_based_flow_table_cap.
125451f68dbaSYevgeny Kliteynik 						      rtc_hash_split_table);
125551f68dbaSYevgeny Kliteynik 
125651f68dbaSYevgeny Kliteynik 		caps->rtc_linear_lookup_table = MLX5_GET(query_hca_cap_out, out,
125751f68dbaSYevgeny Kliteynik 							 capability.wqe_based_flow_table_cap.
125851f68dbaSYevgeny Kliteynik 							 rtc_linear_lookup_table);
125951f68dbaSYevgeny Kliteynik 
126051f68dbaSYevgeny Kliteynik 		caps->access_index_mode = MLX5_GET(query_hca_cap_out, out,
126151f68dbaSYevgeny Kliteynik 						   capability.wqe_based_flow_table_cap.
126251f68dbaSYevgeny Kliteynik 						   access_index_mode);
126351f68dbaSYevgeny Kliteynik 
126451f68dbaSYevgeny Kliteynik 		caps->linear_match_definer = MLX5_GET(query_hca_cap_out, out,
126551f68dbaSYevgeny Kliteynik 						      capability.wqe_based_flow_table_cap.
126651f68dbaSYevgeny Kliteynik 						      linear_match_definer_reg_c3);
126767acee3aSAlex Vesker 
126867acee3aSAlex Vesker 		caps->rtc_max_hash_def_gen_wqe = MLX5_GET(query_hca_cap_out, out,
126967acee3aSAlex Vesker 							  capability.wqe_based_flow_table_cap.
127067acee3aSAlex Vesker 							  rtc_max_num_hash_definer_gen_wqe);
127167acee3aSAlex Vesker 
127267acee3aSAlex Vesker 		caps->supp_ste_format_gen_wqe = MLX5_GET(query_hca_cap_out, out,
127367acee3aSAlex Vesker 							 capability.wqe_based_flow_table_cap.
127467acee3aSAlex Vesker 							 ste_format_gen_wqe);
12751f8fc88dSAlex Vesker 
12761f8fc88dSAlex Vesker 		caps->fdb_tir_stc = MLX5_GET(query_hca_cap_out, out,
12771f8fc88dSAlex Vesker 					     capability.wqe_based_flow_table_cap.
12781f8fc88dSAlex Vesker 					     fdb_jump_to_tir_stc);
1279365cdf5fSErez Shitrit 	}
1280365cdf5fSErez Shitrit 
1281365cdf5fSErez Shitrit 	if (caps->eswitch_manager) {
1282365cdf5fSErez Shitrit 		MLX5_SET(query_hca_cap_in, in, op_mod,
1283365cdf5fSErez Shitrit 			 MLX5_GET_HCA_CAP_OP_MOD_ESW_FLOW_TABLE |
1284365cdf5fSErez Shitrit 			 MLX5_HCA_CAP_OPMOD_GET_CUR);
1285365cdf5fSErez Shitrit 
1286365cdf5fSErez Shitrit 		ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
1287365cdf5fSErez Shitrit 		if (ret) {
1288365cdf5fSErez Shitrit 			DR_LOG(ERR, "Failed to query flow table esw caps");
1289365cdf5fSErez Shitrit 			rte_errno = errno;
1290365cdf5fSErez Shitrit 			return rte_errno;
1291365cdf5fSErez Shitrit 		}
1292365cdf5fSErez Shitrit 
1293365cdf5fSErez Shitrit 		caps->fdb_ft.max_level = MLX5_GET(query_hca_cap_out, out,
1294365cdf5fSErez Shitrit 						  capability.flow_table_nic_cap.
1295365cdf5fSErez Shitrit 						  flow_table_properties_nic_receive.max_ft_level);
1296365cdf5fSErez Shitrit 
1297365cdf5fSErez Shitrit 		caps->fdb_ft.reparse = MLX5_GET(query_hca_cap_out, out,
1298365cdf5fSErez Shitrit 						capability.flow_table_nic_cap.
1299365cdf5fSErez Shitrit 						flow_table_properties_nic_receive.reparse);
1300365cdf5fSErez Shitrit 
1301365cdf5fSErez Shitrit 		MLX5_SET(query_hca_cap_in, in, op_mod,
1302365cdf5fSErez Shitrit 			 MLX5_SET_HCA_CAP_OP_MOD_ESW | MLX5_HCA_CAP_OPMOD_GET_CUR);
1303365cdf5fSErez Shitrit 
1304365cdf5fSErez Shitrit 		ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
1305365cdf5fSErez Shitrit 		if (ret) {
13066524f0c8SAlex Vesker 			DR_LOG(ERR, "Query eswitch capabilities failed %d", ret);
1307365cdf5fSErez Shitrit 			rte_errno = errno;
1308365cdf5fSErez Shitrit 			return rte_errno;
1309365cdf5fSErez Shitrit 		}
1310365cdf5fSErez Shitrit 
1311365cdf5fSErez Shitrit 		if (MLX5_GET(query_hca_cap_out, out,
1312365cdf5fSErez Shitrit 			     capability.esw_cap.esw_manager_vport_number_valid))
1313365cdf5fSErez Shitrit 			caps->eswitch_manager_vport_number =
1314365cdf5fSErez Shitrit 			MLX5_GET(query_hca_cap_out, out,
1315365cdf5fSErez Shitrit 				 capability.esw_cap.esw_manager_vport_number);
1316eefaf43dSShun Hao 
1317eefaf43dSShun Hao 		caps->merged_eswitch = MLX5_GET(query_hca_cap_out, out,
1318eefaf43dSShun Hao 						capability.esw_cap.merged_eswitch);
1319365cdf5fSErez Shitrit 	}
1320365cdf5fSErez Shitrit 
13212acdf09bSHamdan Igbaria 	if (caps->roce) {
13222acdf09bSHamdan Igbaria 		MLX5_SET(query_hca_cap_in, in, op_mod,
13232acdf09bSHamdan Igbaria 			 MLX5_GET_HCA_CAP_OP_MOD_ROCE |
13242acdf09bSHamdan Igbaria 			 MLX5_HCA_CAP_OPMOD_GET_CUR);
13252acdf09bSHamdan Igbaria 
13262acdf09bSHamdan Igbaria 		ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
13272acdf09bSHamdan Igbaria 		if (ret) {
13282acdf09bSHamdan Igbaria 			DR_LOG(ERR, "Failed to query roce caps");
13292acdf09bSHamdan Igbaria 			rte_errno = errno;
13302acdf09bSHamdan Igbaria 			return rte_errno;
13312acdf09bSHamdan Igbaria 		}
13322acdf09bSHamdan Igbaria 
13332acdf09bSHamdan Igbaria 		caps->roce_max_src_udp_port = MLX5_GET(query_hca_cap_out, out,
13342acdf09bSHamdan Igbaria 						capability.roce_caps.r_roce_max_src_udp_port);
13352acdf09bSHamdan Igbaria 		caps->roce_min_src_udp_port = MLX5_GET(query_hca_cap_out, out,
13362acdf09bSHamdan Igbaria 						capability.roce_caps.r_roce_min_src_udp_port);
13372acdf09bSHamdan Igbaria 	}
13382acdf09bSHamdan Igbaria 
1339365cdf5fSErez Shitrit 	ret = mlx5_glue->query_device_ex(ctx, NULL, &attr_ex);
1340365cdf5fSErez Shitrit 	if (ret) {
1341365cdf5fSErez Shitrit 		DR_LOG(ERR, "Failed to query device attributes");
1342365cdf5fSErez Shitrit 		rte_errno = ret;
1343365cdf5fSErez Shitrit 		return rte_errno;
1344365cdf5fSErez Shitrit 	}
1345365cdf5fSErez Shitrit 
1346365cdf5fSErez Shitrit 	strlcpy(caps->fw_ver, attr_ex.orig_attr.fw_ver, sizeof(caps->fw_ver));
1347365cdf5fSErez Shitrit 
1348365cdf5fSErez Shitrit 	port_info = flow_hw_get_wire_port(ctx);
13492e3fa232SYevgeny Kliteynik 	if (port_info)
1350365cdf5fSErez Shitrit 		caps->wire_regc_mask = port_info->regc_mask;
13512e3fa232SYevgeny Kliteynik 	else
1352365cdf5fSErez Shitrit 		DR_LOG(INFO, "Failed to query wire port regc value");
1353365cdf5fSErez Shitrit 
1354365cdf5fSErez Shitrit 	return ret;
1355365cdf5fSErez Shitrit }
1356365cdf5fSErez Shitrit 
1357365cdf5fSErez Shitrit int mlx5dr_cmd_query_ib_port(struct ibv_context *ctx,
1358365cdf5fSErez Shitrit 			     struct mlx5dr_cmd_query_vport_caps *vport_caps,
1359365cdf5fSErez Shitrit 			     uint32_t port_num)
1360365cdf5fSErez Shitrit {
1361365cdf5fSErez Shitrit 	struct mlx5_port_info port_info = {0};
1362365cdf5fSErez Shitrit 	uint32_t flags;
1363365cdf5fSErez Shitrit 	int ret;
1364365cdf5fSErez Shitrit 
1365365cdf5fSErez Shitrit 	flags = MLX5_PORT_QUERY_VPORT | MLX5_PORT_QUERY_ESW_OWNER_VHCA_ID;
1366365cdf5fSErez Shitrit 
1367365cdf5fSErez Shitrit 	ret = mlx5_glue->devx_port_query(ctx, port_num, &port_info);
1368365cdf5fSErez Shitrit 	/* Check if query succeed and vport is enabled */
1369365cdf5fSErez Shitrit 	if (ret || (port_info.query_flags & flags) != flags) {
1370365cdf5fSErez Shitrit 		rte_errno = ENOTSUP;
1371365cdf5fSErez Shitrit 		return rte_errno;
1372365cdf5fSErez Shitrit 	}
1373365cdf5fSErez Shitrit 
1374365cdf5fSErez Shitrit 	vport_caps->vport_num = port_info.vport_id;
1375365cdf5fSErez Shitrit 	vport_caps->esw_owner_vhca_id = port_info.esw_owner_vhca_id;
1376365cdf5fSErez Shitrit 
1377365cdf5fSErez Shitrit 	return 0;
1378365cdf5fSErez Shitrit }
1379