xref: /dpdk/drivers/net/mlx5/hws/mlx5dr_cmd.c (revision 2acdf09bac28360f73f7aadab82428079d0880e2)
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);
37393ee3bd8SAlex Vesker 	MLX5_SET(rtc, attr, ste_format_0, rtc_attr->is_frst_jumbo ?
374365cdf5fSErez Shitrit 		MLX5_IFC_RTC_STE_FORMAT_11DW :
375365cdf5fSErez Shitrit 		MLX5_IFC_RTC_STE_FORMAT_8DW);
37693ee3bd8SAlex Vesker 
37793ee3bd8SAlex Vesker 	if (rtc_attr->is_scnd_range) {
37893ee3bd8SAlex Vesker 		MLX5_SET(rtc, attr, ste_format_1, MLX5_IFC_RTC_STE_FORMAT_RANGE);
37993ee3bd8SAlex Vesker 		MLX5_SET(rtc, attr, num_match_ste, 2);
38093ee3bd8SAlex Vesker 	}
38193ee3bd8SAlex Vesker 
382365cdf5fSErez Shitrit 	MLX5_SET(rtc, attr, pd, rtc_attr->pd);
38393ee3bd8SAlex Vesker 	MLX5_SET(rtc, attr, update_method, rtc_attr->fw_gen_wqe);
384365cdf5fSErez Shitrit 	MLX5_SET(rtc, attr, update_index_mode, rtc_attr->update_index_mode);
38507f35716SYevgeny Kliteynik 	MLX5_SET(rtc, attr, access_index_mode, rtc_attr->access_index_mode);
38607f35716SYevgeny Kliteynik 	MLX5_SET(rtc, attr, num_hash_definer, rtc_attr->num_hash_definer);
387365cdf5fSErez Shitrit 	MLX5_SET(rtc, attr, log_depth, rtc_attr->log_depth);
388365cdf5fSErez Shitrit 	MLX5_SET(rtc, attr, log_hash_size, rtc_attr->log_size);
389365cdf5fSErez Shitrit 	MLX5_SET(rtc, attr, table_type, rtc_attr->table_type);
39093ee3bd8SAlex Vesker 	MLX5_SET(rtc, attr, num_hash_definer, rtc_attr->num_hash_definer);
39193ee3bd8SAlex Vesker 	MLX5_SET(rtc, attr, match_definer_0, rtc_attr->match_definer_0);
39293ee3bd8SAlex Vesker 	MLX5_SET(rtc, attr, match_definer_1, rtc_attr->match_definer_1);
393365cdf5fSErez Shitrit 	MLX5_SET(rtc, attr, stc_id, rtc_attr->stc_base);
394365cdf5fSErez Shitrit 	MLX5_SET(rtc, attr, ste_table_base_id, rtc_attr->ste_base);
395365cdf5fSErez Shitrit 	MLX5_SET(rtc, attr, ste_table_offset, rtc_attr->ste_offset);
396365cdf5fSErez Shitrit 	MLX5_SET(rtc, attr, miss_flow_table_id, rtc_attr->miss_ft_id);
397bbddd062SAlex Vesker 	MLX5_SET(rtc, attr, reparse_mode, rtc_attr->reparse_mode);
398365cdf5fSErez Shitrit 
399365cdf5fSErez Shitrit 	devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
400365cdf5fSErez Shitrit 	if (!devx_obj->obj) {
40175226c96SErez Shitrit 		DR_LOG(ERR, "Failed to create RTC (syndrome: %#x)",
40275226c96SErez Shitrit 		       mlx5dr_cmd_get_syndrome(out));
403365cdf5fSErez Shitrit 		simple_free(devx_obj);
404365cdf5fSErez Shitrit 		rte_errno = errno;
405365cdf5fSErez Shitrit 		return NULL;
406365cdf5fSErez Shitrit 	}
407365cdf5fSErez Shitrit 
408365cdf5fSErez Shitrit 	devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
409365cdf5fSErez Shitrit 
410365cdf5fSErez Shitrit 	return devx_obj;
411365cdf5fSErez Shitrit }
412365cdf5fSErez Shitrit 
413365cdf5fSErez Shitrit struct mlx5dr_devx_obj *
414365cdf5fSErez Shitrit mlx5dr_cmd_stc_create(struct ibv_context *ctx,
415365cdf5fSErez Shitrit 		      struct mlx5dr_cmd_stc_create_attr *stc_attr)
416365cdf5fSErez Shitrit {
417365cdf5fSErez Shitrit 	uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
418365cdf5fSErez Shitrit 	uint32_t in[MLX5_ST_SZ_DW(create_stc_in)] = {0};
419365cdf5fSErez Shitrit 	struct mlx5dr_devx_obj *devx_obj;
420365cdf5fSErez Shitrit 	void *attr;
421365cdf5fSErez Shitrit 
422365cdf5fSErez Shitrit 	devx_obj = simple_malloc(sizeof(*devx_obj));
423365cdf5fSErez Shitrit 	if (!devx_obj) {
424365cdf5fSErez Shitrit 		DR_LOG(ERR, "Failed to allocate memory for STC object");
425365cdf5fSErez Shitrit 		rte_errno = ENOMEM;
426365cdf5fSErez Shitrit 		return NULL;
427365cdf5fSErez Shitrit 	}
428365cdf5fSErez Shitrit 
429365cdf5fSErez Shitrit 	attr = MLX5_ADDR_OF(create_stc_in, in, hdr);
430365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
431365cdf5fSErez Shitrit 		 attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
432365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
433365cdf5fSErez Shitrit 		 attr, obj_type, MLX5_GENERAL_OBJ_TYPE_STC);
434365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
435365cdf5fSErez Shitrit 		 attr, log_obj_range, stc_attr->log_obj_range);
436365cdf5fSErez Shitrit 
437365cdf5fSErez Shitrit 	attr = MLX5_ADDR_OF(create_stc_in, in, stc);
438365cdf5fSErez Shitrit 	MLX5_SET(stc, attr, table_type, stc_attr->table_type);
439365cdf5fSErez Shitrit 
440365cdf5fSErez Shitrit 	devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
441365cdf5fSErez Shitrit 	if (!devx_obj->obj) {
44275226c96SErez Shitrit 		DR_LOG(ERR, "Failed to create STC (syndrome: %#x)",
44375226c96SErez Shitrit 		       mlx5dr_cmd_get_syndrome(out));
444365cdf5fSErez Shitrit 		simple_free(devx_obj);
445365cdf5fSErez Shitrit 		rte_errno = errno;
446365cdf5fSErez Shitrit 		return NULL;
447365cdf5fSErez Shitrit 	}
448365cdf5fSErez Shitrit 
449365cdf5fSErez Shitrit 	devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
450365cdf5fSErez Shitrit 
451365cdf5fSErez Shitrit 	return devx_obj;
452365cdf5fSErez Shitrit }
453365cdf5fSErez Shitrit 
454365cdf5fSErez Shitrit static int
455365cdf5fSErez Shitrit mlx5dr_cmd_stc_modify_set_stc_param(struct mlx5dr_cmd_stc_modify_attr *stc_attr,
456365cdf5fSErez Shitrit 				    void *stc_parm)
457365cdf5fSErez Shitrit {
458365cdf5fSErez Shitrit 	switch (stc_attr->action_type) {
459365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_COUNTER:
460365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_flow_counter, stc_parm, flow_counter_id, stc_attr->id);
461365cdf5fSErez Shitrit 		break;
462365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_TIR:
463365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_tir, stc_parm, tirn, stc_attr->dest_tir_num);
464365cdf5fSErez Shitrit 		break;
465365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_FT:
466365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_table, stc_parm, table_id, stc_attr->dest_table_id);
467365cdf5fSErez Shitrit 		break;
468365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_ACC_MODIFY_LIST:
469365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_header_modify_list, stc_parm,
470365cdf5fSErez Shitrit 			 header_modify_pattern_id, stc_attr->modify_header.pattern_id);
471365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_header_modify_list, stc_parm,
472365cdf5fSErez Shitrit 			 header_modify_argument_id, stc_attr->modify_header.arg_id);
473365cdf5fSErez Shitrit 		break;
474365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_HEADER_REMOVE:
475365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_remove, stc_parm, action_type,
476365cdf5fSErez Shitrit 			 MLX5_MODIFICATION_TYPE_REMOVE);
477365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_remove, stc_parm, decap,
478365cdf5fSErez Shitrit 			 stc_attr->remove_header.decap);
479365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_remove, stc_parm, remove_start_anchor,
480365cdf5fSErez Shitrit 			 stc_attr->remove_header.start_anchor);
481365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_remove, stc_parm, remove_end_anchor,
482365cdf5fSErez Shitrit 			 stc_attr->remove_header.end_anchor);
483365cdf5fSErez Shitrit 		break;
484365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_HEADER_INSERT:
485365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_insert, stc_parm, action_type,
486365cdf5fSErez Shitrit 			 MLX5_MODIFICATION_TYPE_INSERT);
487365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_insert, stc_parm, encap,
488365cdf5fSErez Shitrit 			 stc_attr->insert_header.encap);
489365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_insert, stc_parm, inline_data,
490365cdf5fSErez Shitrit 			 stc_attr->insert_header.is_inline);
491365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_insert, stc_parm, insert_anchor,
492365cdf5fSErez Shitrit 			 stc_attr->insert_header.insert_anchor);
493365cdf5fSErez Shitrit 		/* HW gets the next 2 sizes in words */
494365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_insert, stc_parm, insert_size,
49513769225SHamdan Igbaria 			 stc_attr->insert_header.header_size / W_SIZE);
496365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_insert, stc_parm, insert_offset,
49713769225SHamdan Igbaria 			 stc_attr->insert_header.insert_offset / W_SIZE);
498365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_insert, stc_parm, insert_argument,
499365cdf5fSErez Shitrit 			 stc_attr->insert_header.arg_id);
500365cdf5fSErez Shitrit 		break;
501365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_COPY:
502365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_SET:
503365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_ADD:
5041667b1d7SItamar Gozlan 	case MLX5_IFC_STC_ACTION_TYPE_ADD_FIELD:
505365cdf5fSErez Shitrit 		*(__be64 *)stc_parm = stc_attr->modify_action.data;
506365cdf5fSErez Shitrit 		break;
507365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_VPORT:
508365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_UPLINK:
509365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_vport, stc_parm, vport_number,
510365cdf5fSErez Shitrit 			 stc_attr->vport.vport_num);
511365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_vport, stc_parm, eswitch_owner_vhca_id,
512365cdf5fSErez Shitrit 			 stc_attr->vport.esw_owner_vhca_id);
513365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_vport, stc_parm, eswitch_owner_vhca_id_valid, 1);
514365cdf5fSErez Shitrit 		break;
515365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_DROP:
516365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_NOP:
517365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_TAG:
518365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_ALLOW:
519365cdf5fSErez Shitrit 		break;
520365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_ASO:
521365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_execute_aso, stc_parm, aso_object_id,
522365cdf5fSErez Shitrit 			 stc_attr->aso.devx_obj_id);
523365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_execute_aso, stc_parm, return_reg_id,
524365cdf5fSErez Shitrit 			 stc_attr->aso.return_reg_id);
525365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_execute_aso, stc_parm, aso_type,
526365cdf5fSErez Shitrit 			 stc_attr->aso.aso_type);
527365cdf5fSErez Shitrit 		break;
528365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_STE_TABLE:
529365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_ste_table, stc_parm, ste_obj_id,
530365cdf5fSErez Shitrit 			 stc_attr->ste_table.ste_obj_id);
531365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_ste_table, stc_parm, match_definer_id,
532365cdf5fSErez Shitrit 			 stc_attr->ste_table.match_definer_id);
533365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_ste_table, stc_parm, log_hash_size,
534365cdf5fSErez Shitrit 			 stc_attr->ste_table.log_hash_size);
535365cdf5fSErez Shitrit 		break;
536365cdf5fSErez Shitrit 	case MLX5_IFC_STC_ACTION_TYPE_REMOVE_WORDS:
537365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_remove_words, stc_parm, action_type,
538365cdf5fSErez Shitrit 			 MLX5_MODIFICATION_TYPE_REMOVE_WORDS);
539365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_remove_words, stc_parm, remove_start_anchor,
540365cdf5fSErez Shitrit 			 stc_attr->remove_words.start_anchor);
541365cdf5fSErez Shitrit 		MLX5_SET(stc_ste_param_remove_words, stc_parm,
542365cdf5fSErez Shitrit 			 remove_size, stc_attr->remove_words.num_of_words);
543365cdf5fSErez Shitrit 		break;
544365cdf5fSErez Shitrit 	default:
545365cdf5fSErez Shitrit 		DR_LOG(ERR, "Not supported type %d", stc_attr->action_type);
546365cdf5fSErez Shitrit 		rte_errno = EINVAL;
547365cdf5fSErez Shitrit 		return rte_errno;
548365cdf5fSErez Shitrit 	}
549365cdf5fSErez Shitrit 	return 0;
550365cdf5fSErez Shitrit }
551365cdf5fSErez Shitrit 
552365cdf5fSErez Shitrit int
553365cdf5fSErez Shitrit mlx5dr_cmd_stc_modify(struct mlx5dr_devx_obj *devx_obj,
554365cdf5fSErez Shitrit 		      struct mlx5dr_cmd_stc_modify_attr *stc_attr)
555365cdf5fSErez Shitrit {
556365cdf5fSErez Shitrit 	uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
557365cdf5fSErez Shitrit 	uint32_t in[MLX5_ST_SZ_DW(create_stc_in)] = {0};
558365cdf5fSErez Shitrit 	void *stc_parm;
559365cdf5fSErez Shitrit 	void *attr;
560365cdf5fSErez Shitrit 	int ret;
561365cdf5fSErez Shitrit 
562365cdf5fSErez Shitrit 	attr = MLX5_ADDR_OF(create_stc_in, in, hdr);
563365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
564365cdf5fSErez Shitrit 		 attr, opcode, MLX5_CMD_OP_MODIFY_GENERAL_OBJECT);
565365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
566365cdf5fSErez Shitrit 		 attr, obj_type, MLX5_GENERAL_OBJ_TYPE_STC);
567365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr, in, obj_id, devx_obj->id);
568365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr, in, obj_offset, stc_attr->stc_offset);
569365cdf5fSErez Shitrit 
570365cdf5fSErez Shitrit 	attr = MLX5_ADDR_OF(create_stc_in, in, stc);
571365cdf5fSErez Shitrit 	MLX5_SET(stc, attr, ste_action_offset, stc_attr->action_offset);
572365cdf5fSErez Shitrit 	MLX5_SET(stc, attr, action_type, stc_attr->action_type);
573bbddd062SAlex Vesker 	MLX5_SET(stc, attr, reparse_mode, stc_attr->reparse_mode);
574365cdf5fSErez Shitrit 	MLX5_SET64(stc, attr, modify_field_select,
575365cdf5fSErez Shitrit 		   MLX5_IFC_MODIFY_STC_FIELD_SELECT_NEW_STC);
576365cdf5fSErez Shitrit 
577365cdf5fSErez Shitrit 	/* Set destination TIRN, TAG, FT ID, STE ID */
578365cdf5fSErez Shitrit 	stc_parm = MLX5_ADDR_OF(stc, attr, stc_param);
579365cdf5fSErez Shitrit 	ret = mlx5dr_cmd_stc_modify_set_stc_param(stc_attr, stc_parm);
580365cdf5fSErez Shitrit 	if (ret)
581365cdf5fSErez Shitrit 		return ret;
582365cdf5fSErez Shitrit 
583365cdf5fSErez Shitrit 	ret = mlx5_glue->devx_obj_modify(devx_obj->obj, in, sizeof(in), out, sizeof(out));
584365cdf5fSErez Shitrit 	if (ret) {
58575226c96SErez Shitrit 		DR_LOG(ERR, "Failed to modify STC FW action_type %d (syndrome: %#x)",
58675226c96SErez Shitrit 		       stc_attr->action_type, mlx5dr_cmd_get_syndrome(out));
587365cdf5fSErez Shitrit 		rte_errno = errno;
588365cdf5fSErez Shitrit 	}
589365cdf5fSErez Shitrit 
590365cdf5fSErez Shitrit 	return ret;
591365cdf5fSErez Shitrit }
592365cdf5fSErez Shitrit 
593365cdf5fSErez Shitrit struct mlx5dr_devx_obj *
594365cdf5fSErez Shitrit mlx5dr_cmd_arg_create(struct ibv_context *ctx,
595365cdf5fSErez Shitrit 		      uint16_t log_obj_range,
596365cdf5fSErez Shitrit 		      uint32_t pd)
597365cdf5fSErez Shitrit {
598365cdf5fSErez Shitrit 	uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
599365cdf5fSErez Shitrit 	uint32_t in[MLX5_ST_SZ_DW(create_arg_in)] = {0};
600365cdf5fSErez Shitrit 	struct mlx5dr_devx_obj *devx_obj;
601365cdf5fSErez Shitrit 	void *attr;
602365cdf5fSErez Shitrit 
603365cdf5fSErez Shitrit 	devx_obj = simple_malloc(sizeof(*devx_obj));
604365cdf5fSErez Shitrit 	if (!devx_obj) {
605365cdf5fSErez Shitrit 		DR_LOG(ERR, "Failed to allocate memory for ARG object");
606365cdf5fSErez Shitrit 		rte_errno = ENOMEM;
607365cdf5fSErez Shitrit 		return NULL;
608365cdf5fSErez Shitrit 	}
609365cdf5fSErez Shitrit 
610365cdf5fSErez Shitrit 	attr = MLX5_ADDR_OF(create_arg_in, in, hdr);
611365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
612365cdf5fSErez Shitrit 		 attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
613365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
614365cdf5fSErez Shitrit 		 attr, obj_type, MLX5_GENERAL_OBJ_TYPE_ARG);
615365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
616365cdf5fSErez Shitrit 		 attr, log_obj_range, log_obj_range);
617365cdf5fSErez Shitrit 
618365cdf5fSErez Shitrit 	attr = MLX5_ADDR_OF(create_arg_in, in, arg);
619365cdf5fSErez Shitrit 	MLX5_SET(arg, attr, access_pd, pd);
620365cdf5fSErez Shitrit 
621365cdf5fSErez Shitrit 	devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
622365cdf5fSErez Shitrit 	if (!devx_obj->obj) {
62375226c96SErez Shitrit 		DR_LOG(ERR, "Failed to create ARG (syndrome: %#x)",
62475226c96SErez Shitrit 		       mlx5dr_cmd_get_syndrome(out));
625365cdf5fSErez Shitrit 		simple_free(devx_obj);
626365cdf5fSErez Shitrit 		rte_errno = errno;
627365cdf5fSErez Shitrit 		return NULL;
628365cdf5fSErez Shitrit 	}
629365cdf5fSErez Shitrit 
630365cdf5fSErez Shitrit 	devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
631365cdf5fSErez Shitrit 
632365cdf5fSErez Shitrit 	return devx_obj;
633365cdf5fSErez Shitrit }
634365cdf5fSErez Shitrit 
635365cdf5fSErez Shitrit struct mlx5dr_devx_obj *
636365cdf5fSErez Shitrit mlx5dr_cmd_header_modify_pattern_create(struct ibv_context *ctx,
637365cdf5fSErez Shitrit 					uint32_t pattern_length,
638365cdf5fSErez Shitrit 					uint8_t *actions)
639365cdf5fSErez Shitrit {
640365cdf5fSErez Shitrit 	uint32_t in[MLX5_ST_SZ_DW(create_header_modify_pattern_in)] = {0};
641365cdf5fSErez Shitrit 	uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
642365cdf5fSErez Shitrit 	struct mlx5dr_devx_obj *devx_obj;
64397e1a2ffSErez Shitrit 	uint64_t *pattern_data;
64497e1a2ffSErez Shitrit 	int num_of_actions;
645365cdf5fSErez Shitrit 	void *pattern;
646365cdf5fSErez Shitrit 	void *attr;
64797e1a2ffSErez Shitrit 	int i;
648365cdf5fSErez Shitrit 
649365cdf5fSErez Shitrit 	if (pattern_length > MAX_ACTIONS_DATA_IN_HEADER_MODIFY) {
650365cdf5fSErez Shitrit 		DR_LOG(ERR, "Pattern length %d exceeds limit %d",
651365cdf5fSErez Shitrit 			pattern_length, MAX_ACTIONS_DATA_IN_HEADER_MODIFY);
652365cdf5fSErez Shitrit 		rte_errno = EINVAL;
653365cdf5fSErez Shitrit 		return NULL;
654365cdf5fSErez Shitrit 	}
655365cdf5fSErez Shitrit 
656365cdf5fSErez Shitrit 	devx_obj = simple_malloc(sizeof(*devx_obj));
657365cdf5fSErez Shitrit 	if (!devx_obj) {
658365cdf5fSErez Shitrit 		DR_LOG(ERR, "Failed to allocate memory for header_modify_pattern object");
659365cdf5fSErez Shitrit 		rte_errno = ENOMEM;
660365cdf5fSErez Shitrit 		return NULL;
661365cdf5fSErez Shitrit 	}
662365cdf5fSErez Shitrit 	attr = MLX5_ADDR_OF(create_header_modify_pattern_in, in, hdr);
663365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
664365cdf5fSErez Shitrit 		 attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
665365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
666365cdf5fSErez Shitrit 		 attr, obj_type, MLX5_GENERAL_OBJ_TYPE_MODIFY_HEADER_PATTERN);
667365cdf5fSErez Shitrit 
668365cdf5fSErez Shitrit 	pattern = MLX5_ADDR_OF(create_header_modify_pattern_in, in, pattern);
669365cdf5fSErez Shitrit 	/* Pattern_length is in ddwords */
670365cdf5fSErez Shitrit 	MLX5_SET(header_modify_pattern_in, pattern, pattern_length, pattern_length / (2 * DW_SIZE));
671365cdf5fSErez Shitrit 
67297e1a2ffSErez Shitrit 	pattern_data = (uint64_t *)MLX5_ADDR_OF(header_modify_pattern_in, pattern, pattern_data);
673365cdf5fSErez Shitrit 	memcpy(pattern_data, actions, pattern_length);
674365cdf5fSErez Shitrit 
67597e1a2ffSErez Shitrit 	num_of_actions = pattern_length / MLX5DR_MODIFY_ACTION_SIZE;
67697e1a2ffSErez Shitrit 	for (i = 0; i < num_of_actions; i++) {
67797e1a2ffSErez Shitrit 		int type;
67897e1a2ffSErez Shitrit 
67997e1a2ffSErez Shitrit 		type = MLX5_GET(set_action_in, &pattern_data[i], action_type);
6801667b1d7SItamar Gozlan 		if (type != MLX5_MODIFICATION_TYPE_COPY &&
6811667b1d7SItamar Gozlan 		    type != MLX5_MODIFICATION_TYPE_ADD_FIELD)
68297e1a2ffSErez Shitrit 			/* Action typ-copy use all bytes for control */
68397e1a2ffSErez Shitrit 			MLX5_SET(set_action_in, &pattern_data[i], data, 0);
68497e1a2ffSErez Shitrit 	}
68597e1a2ffSErez Shitrit 
686365cdf5fSErez Shitrit 	devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
687365cdf5fSErez Shitrit 	if (!devx_obj->obj) {
68875226c96SErez Shitrit 		DR_LOG(ERR, "Failed to create header_modify_pattern (syndrome: %#x)",
68975226c96SErez Shitrit 		       mlx5dr_cmd_get_syndrome(out));
690365cdf5fSErez Shitrit 		rte_errno = errno;
691365cdf5fSErez Shitrit 		goto free_obj;
692365cdf5fSErez Shitrit 	}
693365cdf5fSErez Shitrit 
694365cdf5fSErez Shitrit 	devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
695365cdf5fSErez Shitrit 
696365cdf5fSErez Shitrit 	return devx_obj;
697365cdf5fSErez Shitrit 
698365cdf5fSErez Shitrit free_obj:
699365cdf5fSErez Shitrit 	simple_free(devx_obj);
700365cdf5fSErez Shitrit 	return NULL;
701365cdf5fSErez Shitrit }
702365cdf5fSErez Shitrit 
703365cdf5fSErez Shitrit struct mlx5dr_devx_obj *
704365cdf5fSErez Shitrit mlx5dr_cmd_ste_create(struct ibv_context *ctx,
705365cdf5fSErez Shitrit 		      struct mlx5dr_cmd_ste_create_attr *ste_attr)
706365cdf5fSErez Shitrit {
707365cdf5fSErez Shitrit 	uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
708365cdf5fSErez Shitrit 	uint32_t in[MLX5_ST_SZ_DW(create_ste_in)] = {0};
709365cdf5fSErez Shitrit 	struct mlx5dr_devx_obj *devx_obj;
710365cdf5fSErez Shitrit 	void *attr;
711365cdf5fSErez Shitrit 
712365cdf5fSErez Shitrit 	devx_obj = simple_malloc(sizeof(*devx_obj));
713365cdf5fSErez Shitrit 	if (!devx_obj) {
714365cdf5fSErez Shitrit 		DR_LOG(ERR, "Failed to allocate memory for STE object");
715365cdf5fSErez Shitrit 		rte_errno = ENOMEM;
716365cdf5fSErez Shitrit 		return NULL;
717365cdf5fSErez Shitrit 	}
718365cdf5fSErez Shitrit 
719365cdf5fSErez Shitrit 	attr = MLX5_ADDR_OF(create_ste_in, in, hdr);
720365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
721365cdf5fSErez Shitrit 		 attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
722365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
723365cdf5fSErez Shitrit 		 attr, obj_type, MLX5_GENERAL_OBJ_TYPE_STE);
724365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
725365cdf5fSErez Shitrit 		 attr, log_obj_range, ste_attr->log_obj_range);
726365cdf5fSErez Shitrit 
727365cdf5fSErez Shitrit 	attr = MLX5_ADDR_OF(create_ste_in, in, ste);
728365cdf5fSErez Shitrit 	MLX5_SET(ste, attr, table_type, ste_attr->table_type);
729365cdf5fSErez Shitrit 
730365cdf5fSErez Shitrit 	devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
731365cdf5fSErez Shitrit 	if (!devx_obj->obj) {
73275226c96SErez Shitrit 		DR_LOG(ERR, "Failed to create STE (syndrome: %#x)",
73375226c96SErez Shitrit 		       mlx5dr_cmd_get_syndrome(out));
734365cdf5fSErez Shitrit 		simple_free(devx_obj);
735365cdf5fSErez Shitrit 		rte_errno = errno;
736365cdf5fSErez Shitrit 		return NULL;
737365cdf5fSErez Shitrit 	}
738365cdf5fSErez Shitrit 
739365cdf5fSErez Shitrit 	devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
740365cdf5fSErez Shitrit 
741365cdf5fSErez Shitrit 	return devx_obj;
742365cdf5fSErez Shitrit }
743365cdf5fSErez Shitrit 
744365cdf5fSErez Shitrit struct mlx5dr_devx_obj *
745365cdf5fSErez Shitrit mlx5dr_cmd_definer_create(struct ibv_context *ctx,
746365cdf5fSErez Shitrit 			  struct mlx5dr_cmd_definer_create_attr *def_attr)
747365cdf5fSErez Shitrit {
748365cdf5fSErez Shitrit 	uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
749365cdf5fSErez Shitrit 	uint32_t in[MLX5_ST_SZ_DW(create_definer_in)] = {0};
750365cdf5fSErez Shitrit 	struct mlx5dr_devx_obj *devx_obj;
751365cdf5fSErez Shitrit 	void *ptr;
752365cdf5fSErez Shitrit 
753365cdf5fSErez Shitrit 	devx_obj = simple_malloc(sizeof(*devx_obj));
754365cdf5fSErez Shitrit 	if (!devx_obj) {
755365cdf5fSErez Shitrit 		DR_LOG(ERR, "Failed to allocate memory for definer object");
756365cdf5fSErez Shitrit 		rte_errno = ENOMEM;
757365cdf5fSErez Shitrit 		return NULL;
758365cdf5fSErez Shitrit 	}
759365cdf5fSErez Shitrit 
760365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
761365cdf5fSErez Shitrit 		 in, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
762365cdf5fSErez Shitrit 	MLX5_SET(general_obj_in_cmd_hdr,
763365cdf5fSErez Shitrit 		 in, obj_type, MLX5_GENERAL_OBJ_TYPE_DEFINER);
764365cdf5fSErez Shitrit 
765365cdf5fSErez Shitrit 	ptr = MLX5_ADDR_OF(create_definer_in, in, definer);
766365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_id, MLX5_IFC_DEFINER_FORMAT_ID_SELECT);
767365cdf5fSErez Shitrit 
768365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_dw0, def_attr->dw_selector[0]);
769365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_dw1, def_attr->dw_selector[1]);
770365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_dw2, def_attr->dw_selector[2]);
771365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_dw3, def_attr->dw_selector[3]);
772365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_dw4, def_attr->dw_selector[4]);
773365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_dw5, def_attr->dw_selector[5]);
774365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_dw6, def_attr->dw_selector[6]);
775365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_dw7, def_attr->dw_selector[7]);
776365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_dw8, def_attr->dw_selector[8]);
777365cdf5fSErez Shitrit 
778365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_byte0, def_attr->byte_selector[0]);
779365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_byte1, def_attr->byte_selector[1]);
780365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_byte2, def_attr->byte_selector[2]);
781365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_byte3, def_attr->byte_selector[3]);
782365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_byte4, def_attr->byte_selector[4]);
783365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_byte5, def_attr->byte_selector[5]);
784365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_byte6, def_attr->byte_selector[6]);
785365cdf5fSErez Shitrit 	MLX5_SET(definer, ptr, format_select_byte7, def_attr->byte_selector[7]);
786365cdf5fSErez Shitrit 
787365cdf5fSErez Shitrit 	ptr = MLX5_ADDR_OF(definer, ptr, match_mask);
788365cdf5fSErez Shitrit 	memcpy(ptr, def_attr->match_mask, MLX5_FLD_SZ_BYTES(definer, match_mask));
789365cdf5fSErez Shitrit 
790365cdf5fSErez Shitrit 	devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
791365cdf5fSErez Shitrit 	if (!devx_obj->obj) {
79275226c96SErez Shitrit 		DR_LOG(ERR, "Failed to create Definer (syndrome: %#x)",
79375226c96SErez Shitrit 		       mlx5dr_cmd_get_syndrome(out));
794365cdf5fSErez Shitrit 		simple_free(devx_obj);
795365cdf5fSErez Shitrit 		rte_errno = errno;
796365cdf5fSErez Shitrit 		return NULL;
797365cdf5fSErez Shitrit 	}
798365cdf5fSErez Shitrit 
799365cdf5fSErez Shitrit 	devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
800365cdf5fSErez Shitrit 
801365cdf5fSErez Shitrit 	return devx_obj;
802365cdf5fSErez Shitrit }
803365cdf5fSErez Shitrit 
804365cdf5fSErez Shitrit struct mlx5dr_devx_obj *
805365cdf5fSErez Shitrit mlx5dr_cmd_sq_create(struct ibv_context *ctx,
806365cdf5fSErez Shitrit 		     struct mlx5dr_cmd_sq_create_attr *attr)
807365cdf5fSErez Shitrit {
808365cdf5fSErez Shitrit 	uint32_t out[MLX5_ST_SZ_DW(create_sq_out)] = {0};
809365cdf5fSErez Shitrit 	uint32_t in[MLX5_ST_SZ_DW(create_sq_in)] = {0};
810365cdf5fSErez Shitrit 	void *sqc = MLX5_ADDR_OF(create_sq_in, in, ctx);
811365cdf5fSErez Shitrit 	void *wqc = MLX5_ADDR_OF(sqc, sqc, wq);
812365cdf5fSErez Shitrit 	struct mlx5dr_devx_obj *devx_obj;
813365cdf5fSErez Shitrit 
814365cdf5fSErez Shitrit 	devx_obj = simple_malloc(sizeof(*devx_obj));
815365cdf5fSErez Shitrit 	if (!devx_obj) {
816365cdf5fSErez Shitrit 		DR_LOG(ERR, "Failed to create SQ");
817365cdf5fSErez Shitrit 		rte_errno = ENOMEM;
818365cdf5fSErez Shitrit 		return NULL;
819365cdf5fSErez Shitrit 	}
820365cdf5fSErez Shitrit 
821365cdf5fSErez Shitrit 	MLX5_SET(create_sq_in, in, opcode, MLX5_CMD_OP_CREATE_SQ);
822365cdf5fSErez Shitrit 	MLX5_SET(sqc, sqc, cqn, attr->cqn);
823365cdf5fSErez Shitrit 	MLX5_SET(sqc, sqc, flush_in_error_en, 1);
824365cdf5fSErez Shitrit 	MLX5_SET(sqc, sqc, non_wire, 1);
825d4444de8SViacheslav Ovsiienko 	MLX5_SET(sqc, sqc, ts_format, attr->ts_format);
826365cdf5fSErez Shitrit 	MLX5_SET(wq, wqc, wq_type, MLX5_WQ_TYPE_CYCLIC);
827365cdf5fSErez Shitrit 	MLX5_SET(wq, wqc, pd, attr->pdn);
828365cdf5fSErez Shitrit 	MLX5_SET(wq, wqc, uar_page, attr->page_id);
829365cdf5fSErez Shitrit 	MLX5_SET(wq, wqc, log_wq_stride, log2above(MLX5_SEND_WQE_BB));
830365cdf5fSErez Shitrit 	MLX5_SET(wq, wqc, log_wq_sz, attr->log_wq_sz);
831365cdf5fSErez Shitrit 	MLX5_SET(wq, wqc, dbr_umem_id, attr->dbr_id);
832365cdf5fSErez Shitrit 	MLX5_SET(wq, wqc, wq_umem_id, attr->wq_id);
833365cdf5fSErez Shitrit 
834365cdf5fSErez Shitrit 	devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
835365cdf5fSErez Shitrit 	if (!devx_obj->obj) {
836365cdf5fSErez Shitrit 		simple_free(devx_obj);
837365cdf5fSErez Shitrit 		rte_errno = errno;
838365cdf5fSErez Shitrit 		return NULL;
839365cdf5fSErez Shitrit 	}
840365cdf5fSErez Shitrit 
841365cdf5fSErez Shitrit 	devx_obj->id = MLX5_GET(create_sq_out, out, sqn);
842365cdf5fSErez Shitrit 
843365cdf5fSErez Shitrit 	return devx_obj;
844365cdf5fSErez Shitrit }
845365cdf5fSErez Shitrit 
84625cb2d2aSHamdan Igbaria struct mlx5dr_devx_obj *
84725cb2d2aSHamdan Igbaria mlx5dr_cmd_packet_reformat_create(struct ibv_context *ctx,
84825cb2d2aSHamdan Igbaria 				  struct mlx5dr_cmd_packet_reformat_create_attr *attr)
84925cb2d2aSHamdan Igbaria {
85025cb2d2aSHamdan Igbaria 	uint32_t out[MLX5_ST_SZ_DW(alloc_packet_reformat_out)] = {0};
85125cb2d2aSHamdan Igbaria 	size_t insz, cmd_data_sz, cmd_total_sz;
85225cb2d2aSHamdan Igbaria 	struct mlx5dr_devx_obj *devx_obj;
85325cb2d2aSHamdan Igbaria 	void *prctx;
85425cb2d2aSHamdan Igbaria 	void *pdata;
85525cb2d2aSHamdan Igbaria 	void *in;
85625cb2d2aSHamdan Igbaria 
85725cb2d2aSHamdan Igbaria 	cmd_total_sz = MLX5_ST_SZ_BYTES(alloc_packet_reformat_context_in);
85825cb2d2aSHamdan Igbaria 	cmd_total_sz += MLX5_ST_SZ_BYTES(packet_reformat_context_in);
85925cb2d2aSHamdan Igbaria 	cmd_data_sz = MLX5_FLD_SZ_BYTES(packet_reformat_context_in, reformat_data);
86025cb2d2aSHamdan Igbaria 	insz = align(cmd_total_sz + attr->data_sz - cmd_data_sz, DW_SIZE);
86125cb2d2aSHamdan Igbaria 	in = simple_calloc(1, insz);
86225cb2d2aSHamdan Igbaria 	if (!in) {
86325cb2d2aSHamdan Igbaria 		rte_errno = ENOMEM;
86425cb2d2aSHamdan Igbaria 		return NULL;
86525cb2d2aSHamdan Igbaria 	}
86625cb2d2aSHamdan Igbaria 
86725cb2d2aSHamdan Igbaria 	MLX5_SET(alloc_packet_reformat_context_in, in, opcode,
86825cb2d2aSHamdan Igbaria 		 MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT);
86925cb2d2aSHamdan Igbaria 
87025cb2d2aSHamdan Igbaria 	prctx = MLX5_ADDR_OF(alloc_packet_reformat_context_in, in,
87125cb2d2aSHamdan Igbaria 			     packet_reformat_context);
87225cb2d2aSHamdan Igbaria 	pdata = MLX5_ADDR_OF(packet_reformat_context_in, prctx, reformat_data);
87325cb2d2aSHamdan Igbaria 
87425cb2d2aSHamdan Igbaria 	MLX5_SET(packet_reformat_context_in, prctx, reformat_type, attr->type);
87525cb2d2aSHamdan Igbaria 	MLX5_SET(packet_reformat_context_in, prctx, reformat_param_0, attr->reformat_param_0);
87625cb2d2aSHamdan Igbaria 	MLX5_SET(packet_reformat_context_in, prctx, reformat_data_size, attr->data_sz);
87725cb2d2aSHamdan Igbaria 	memcpy(pdata, attr->data, attr->data_sz);
87825cb2d2aSHamdan Igbaria 
87925cb2d2aSHamdan Igbaria 	devx_obj = simple_malloc(sizeof(*devx_obj));
88025cb2d2aSHamdan Igbaria 	if (!devx_obj) {
88125cb2d2aSHamdan Igbaria 		DR_LOG(ERR, "Failed to allocate memory for packet reformat object");
88225cb2d2aSHamdan Igbaria 		rte_errno = ENOMEM;
88325cb2d2aSHamdan Igbaria 		goto out_free_in;
88425cb2d2aSHamdan Igbaria 	}
88525cb2d2aSHamdan Igbaria 
88625cb2d2aSHamdan Igbaria 	devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, insz, out, sizeof(out));
88725cb2d2aSHamdan Igbaria 	if (!devx_obj->obj) {
88825cb2d2aSHamdan Igbaria 		DR_LOG(ERR, "Failed to create packet reformat");
88925cb2d2aSHamdan Igbaria 		rte_errno = errno;
89025cb2d2aSHamdan Igbaria 		goto out_free_devx;
89125cb2d2aSHamdan Igbaria 	}
89225cb2d2aSHamdan Igbaria 
89325cb2d2aSHamdan Igbaria 	devx_obj->id = MLX5_GET(alloc_packet_reformat_out, out, packet_reformat_id);
89425cb2d2aSHamdan Igbaria 
89525cb2d2aSHamdan Igbaria 	simple_free(in);
89625cb2d2aSHamdan Igbaria 
89725cb2d2aSHamdan Igbaria 	return devx_obj;
89825cb2d2aSHamdan Igbaria 
89925cb2d2aSHamdan Igbaria out_free_devx:
90025cb2d2aSHamdan Igbaria 	simple_free(devx_obj);
90125cb2d2aSHamdan Igbaria out_free_in:
90225cb2d2aSHamdan Igbaria 	simple_free(in);
90325cb2d2aSHamdan Igbaria 	return NULL;
90425cb2d2aSHamdan Igbaria }
90525cb2d2aSHamdan Igbaria 
906365cdf5fSErez Shitrit int mlx5dr_cmd_sq_modify_rdy(struct mlx5dr_devx_obj *devx_obj)
907365cdf5fSErez Shitrit {
908365cdf5fSErez Shitrit 	uint32_t out[MLX5_ST_SZ_DW(modify_sq_out)] = {0};
909365cdf5fSErez Shitrit 	uint32_t in[MLX5_ST_SZ_DW(modify_sq_in)] = {0};
910365cdf5fSErez Shitrit 	void *sqc = MLX5_ADDR_OF(modify_sq_in, in, ctx);
911365cdf5fSErez Shitrit 	int ret;
912365cdf5fSErez Shitrit 
913365cdf5fSErez Shitrit 	MLX5_SET(modify_sq_in, in, opcode, MLX5_CMD_OP_MODIFY_SQ);
914365cdf5fSErez Shitrit 	MLX5_SET(modify_sq_in, in, sqn, devx_obj->id);
915365cdf5fSErez Shitrit 	MLX5_SET(modify_sq_in, in, sq_state, MLX5_SQC_STATE_RST);
916365cdf5fSErez Shitrit 	MLX5_SET(sqc, sqc, state, MLX5_SQC_STATE_RDY);
917365cdf5fSErez Shitrit 
918365cdf5fSErez Shitrit 	ret = mlx5_glue->devx_obj_modify(devx_obj->obj, in, sizeof(in), out, sizeof(out));
919365cdf5fSErez Shitrit 	if (ret) {
92075226c96SErez Shitrit 		DR_LOG(ERR, "Failed to modify SQ (syndrome: %#x)",
92175226c96SErez Shitrit 		       mlx5dr_cmd_get_syndrome(out));
922365cdf5fSErez Shitrit 		rte_errno = errno;
923365cdf5fSErez Shitrit 	}
924365cdf5fSErez Shitrit 
925365cdf5fSErez Shitrit 	return ret;
926365cdf5fSErez Shitrit }
927365cdf5fSErez Shitrit 
928720439d8SYevgeny Kliteynik int mlx5dr_cmd_allow_other_vhca_access(struct ibv_context *ctx,
929720439d8SYevgeny Kliteynik 				       struct mlx5dr_cmd_allow_other_vhca_access_attr *attr)
930720439d8SYevgeny Kliteynik {
931720439d8SYevgeny Kliteynik 	uint32_t out[MLX5_ST_SZ_DW(allow_other_vhca_access_out)] = {0};
932720439d8SYevgeny Kliteynik 	uint32_t in[MLX5_ST_SZ_DW(allow_other_vhca_access_in)] = {0};
933720439d8SYevgeny Kliteynik 	void *key;
934720439d8SYevgeny Kliteynik 	int ret;
935720439d8SYevgeny Kliteynik 
936720439d8SYevgeny Kliteynik 	MLX5_SET(allow_other_vhca_access_in,
937720439d8SYevgeny Kliteynik 		 in, opcode, MLX5_CMD_OP_ALLOW_OTHER_VHCA_ACCESS);
938720439d8SYevgeny Kliteynik 	MLX5_SET(allow_other_vhca_access_in,
939720439d8SYevgeny Kliteynik 		 in, object_type_to_be_accessed, attr->obj_type);
940720439d8SYevgeny Kliteynik 	MLX5_SET(allow_other_vhca_access_in,
941720439d8SYevgeny Kliteynik 		 in, object_id_to_be_accessed, attr->obj_id);
942720439d8SYevgeny Kliteynik 
943720439d8SYevgeny Kliteynik 	key = MLX5_ADDR_OF(allow_other_vhca_access_in, in, access_key);
944720439d8SYevgeny Kliteynik 	memcpy(key, attr->access_key, sizeof(attr->access_key));
945720439d8SYevgeny Kliteynik 
946720439d8SYevgeny Kliteynik 	ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
947720439d8SYevgeny Kliteynik 	if (ret) {
948720439d8SYevgeny Kliteynik 		DR_LOG(ERR, "Failed to execute ALLOW_OTHER_VHCA_ACCESS command");
949720439d8SYevgeny Kliteynik 		rte_errno = errno;
950720439d8SYevgeny Kliteynik 		return rte_errno;
951720439d8SYevgeny Kliteynik 	}
952720439d8SYevgeny Kliteynik 
953720439d8SYevgeny Kliteynik 	return 0;
954720439d8SYevgeny Kliteynik }
955720439d8SYevgeny Kliteynik 
956ed695274SYevgeny Kliteynik struct mlx5dr_devx_obj *
957ed695274SYevgeny Kliteynik mlx5dr_cmd_alias_obj_create(struct ibv_context *ctx,
958ed695274SYevgeny Kliteynik 			    struct mlx5dr_cmd_alias_obj_create_attr *alias_attr)
959ed695274SYevgeny Kliteynik {
960ed695274SYevgeny Kliteynik 	uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
961ed695274SYevgeny Kliteynik 	uint32_t in[MLX5_ST_SZ_DW(create_alias_obj_in)] = {0};
962ed695274SYevgeny Kliteynik 	struct mlx5dr_devx_obj *devx_obj;
963ed695274SYevgeny Kliteynik 	void *attr;
964ed695274SYevgeny Kliteynik 	void *key;
965ed695274SYevgeny Kliteynik 
966ed695274SYevgeny Kliteynik 	devx_obj = simple_malloc(sizeof(*devx_obj));
967ed695274SYevgeny Kliteynik 	if (!devx_obj) {
968ed695274SYevgeny Kliteynik 		DR_LOG(ERR, "Failed to allocate memory for ALIAS general object");
969ed695274SYevgeny Kliteynik 		rte_errno = ENOMEM;
970ed695274SYevgeny Kliteynik 		return NULL;
971ed695274SYevgeny Kliteynik 	}
972ed695274SYevgeny Kliteynik 
973ed695274SYevgeny Kliteynik 	attr = MLX5_ADDR_OF(create_alias_obj_in, in, hdr);
974ed695274SYevgeny Kliteynik 	MLX5_SET(general_obj_in_cmd_hdr,
975ed695274SYevgeny Kliteynik 		 attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
976ed695274SYevgeny Kliteynik 	MLX5_SET(general_obj_in_cmd_hdr,
977ed695274SYevgeny Kliteynik 		 attr, obj_type, alias_attr->obj_type);
978ed695274SYevgeny Kliteynik 	MLX5_SET(general_obj_in_cmd_hdr, attr, alias_object, 1);
979ed695274SYevgeny Kliteynik 
980ed695274SYevgeny Kliteynik 	attr = MLX5_ADDR_OF(create_alias_obj_in, in, alias_ctx);
981ed695274SYevgeny Kliteynik 	MLX5_SET(alias_context, attr, vhca_id_to_be_accessed, alias_attr->vhca_id);
982ed695274SYevgeny Kliteynik 	MLX5_SET(alias_context, attr, object_id_to_be_accessed, alias_attr->obj_id);
983ed695274SYevgeny Kliteynik 
984ed695274SYevgeny Kliteynik 	key = MLX5_ADDR_OF(alias_context, attr, access_key);
985ed695274SYevgeny Kliteynik 	memcpy(key, alias_attr->access_key, sizeof(alias_attr->access_key));
986ed695274SYevgeny Kliteynik 
987ed695274SYevgeny Kliteynik 	devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out));
988ed695274SYevgeny Kliteynik 	if (!devx_obj->obj) {
98975226c96SErez Shitrit 		DR_LOG(ERR, "Failed to create ALIAS OBJ (syndrome: %#x)",
99075226c96SErez Shitrit 		       mlx5dr_cmd_get_syndrome(out));
991ed695274SYevgeny Kliteynik 		simple_free(devx_obj);
992ed695274SYevgeny Kliteynik 		rte_errno = errno;
993ed695274SYevgeny Kliteynik 		return NULL;
994ed695274SYevgeny Kliteynik 	}
995ed695274SYevgeny Kliteynik 
996ed695274SYevgeny Kliteynik 	devx_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
997ed695274SYevgeny Kliteynik 
998ed695274SYevgeny Kliteynik 	return devx_obj;
999ed695274SYevgeny Kliteynik }
1000ed695274SYevgeny Kliteynik 
100112802ab2SAlex Vesker int mlx5dr_cmd_generate_wqe(struct ibv_context *ctx,
100212802ab2SAlex Vesker 			    struct mlx5dr_cmd_generate_wqe_attr *attr,
100312802ab2SAlex Vesker 			    struct mlx5_cqe64 *ret_cqe)
100412802ab2SAlex Vesker {
100512802ab2SAlex Vesker 	uint32_t out[MLX5_ST_SZ_DW(generate_wqe_out)] = {0};
100612802ab2SAlex Vesker 	uint32_t in[MLX5_ST_SZ_DW(generate_wqe_in)] = {0};
100712802ab2SAlex Vesker 	uint8_t status;
100812802ab2SAlex Vesker 	void *ptr;
100912802ab2SAlex Vesker 	int ret;
101012802ab2SAlex Vesker 
101112802ab2SAlex Vesker 	MLX5_SET(generate_wqe_in, in, opcode, MLX5_CMD_OP_GENERATE_WQE);
101212802ab2SAlex Vesker 	MLX5_SET(generate_wqe_in, in, pdn, attr->pdn);
101312802ab2SAlex Vesker 
101412802ab2SAlex Vesker 	ptr = MLX5_ADDR_OF(generate_wqe_in, in, wqe_ctrl);
101512802ab2SAlex Vesker 	memcpy(ptr, attr->wqe_ctrl, MLX5_FLD_SZ_BYTES(generate_wqe_in, wqe_ctrl));
101612802ab2SAlex Vesker 
101712802ab2SAlex Vesker 	ptr = MLX5_ADDR_OF(generate_wqe_in, in, wqe_gta_ctrl);
101812802ab2SAlex Vesker 	memcpy(ptr, attr->gta_ctrl, MLX5_FLD_SZ_BYTES(generate_wqe_in, wqe_gta_ctrl));
101912802ab2SAlex Vesker 
102012802ab2SAlex Vesker 	ptr = MLX5_ADDR_OF(generate_wqe_in, in, wqe_gta_data_0);
102112802ab2SAlex Vesker 	memcpy(ptr, attr->gta_data_0, MLX5_FLD_SZ_BYTES(generate_wqe_in, wqe_gta_data_0));
102212802ab2SAlex Vesker 
102312802ab2SAlex Vesker 	if (attr->gta_data_1) {
102412802ab2SAlex Vesker 		ptr = MLX5_ADDR_OF(generate_wqe_in, in, wqe_gta_data_1);
102512802ab2SAlex Vesker 		memcpy(ptr, attr->gta_data_1, MLX5_FLD_SZ_BYTES(generate_wqe_in, wqe_gta_data_1));
102612802ab2SAlex Vesker 	}
102712802ab2SAlex Vesker 
102812802ab2SAlex Vesker 	ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
102912802ab2SAlex Vesker 	if (ret) {
103012802ab2SAlex Vesker 		DR_LOG(ERR, "Failed to write GTA WQE using FW");
103112802ab2SAlex Vesker 		rte_errno = errno;
103212802ab2SAlex Vesker 		return rte_errno;
103312802ab2SAlex Vesker 	}
103412802ab2SAlex Vesker 
103512802ab2SAlex Vesker 	status = MLX5_GET(generate_wqe_out, out, status);
103612802ab2SAlex Vesker 	if (status) {
103712802ab2SAlex Vesker 		DR_LOG(ERR, "Invalid FW CQE status %d", status);
103812802ab2SAlex Vesker 		rte_errno = EINVAL;
103912802ab2SAlex Vesker 		return rte_errno;
104012802ab2SAlex Vesker 	}
104112802ab2SAlex Vesker 
104212802ab2SAlex Vesker 	ptr = MLX5_ADDR_OF(generate_wqe_out, out, cqe_data);
104312802ab2SAlex Vesker 	memcpy(ret_cqe, ptr, sizeof(*ret_cqe));
104412802ab2SAlex Vesker 
104512802ab2SAlex Vesker 	return 0;
104612802ab2SAlex Vesker }
104712802ab2SAlex Vesker 
1048365cdf5fSErez Shitrit int mlx5dr_cmd_query_caps(struct ibv_context *ctx,
1049365cdf5fSErez Shitrit 			  struct mlx5dr_cmd_query_caps *caps)
1050365cdf5fSErez Shitrit {
1051365cdf5fSErez Shitrit 	uint32_t out[MLX5_ST_SZ_DW(query_hca_cap_out)] = {0};
1052365cdf5fSErez Shitrit 	uint32_t in[MLX5_ST_SZ_DW(query_hca_cap_in)] = {0};
1053365cdf5fSErez Shitrit 	const struct flow_hw_port_info *port_info;
1054365cdf5fSErez Shitrit 	struct ibv_device_attr_ex attr_ex;
1055b2300900SYevgeny Kliteynik 	u32 res;
1056365cdf5fSErez Shitrit 	int ret;
1057365cdf5fSErez Shitrit 
1058365cdf5fSErez Shitrit 	MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP);
1059365cdf5fSErez Shitrit 	MLX5_SET(query_hca_cap_in, in, op_mod,
1060365cdf5fSErez Shitrit 		 MLX5_GET_HCA_CAP_OP_MOD_GENERAL_DEVICE |
1061365cdf5fSErez Shitrit 		 MLX5_HCA_CAP_OPMOD_GET_CUR);
1062365cdf5fSErez Shitrit 
1063365cdf5fSErez Shitrit 	ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
1064365cdf5fSErez Shitrit 	if (ret) {
1065365cdf5fSErez Shitrit 		DR_LOG(ERR, "Failed to query device caps");
1066365cdf5fSErez Shitrit 		rte_errno = errno;
1067365cdf5fSErez Shitrit 		return rte_errno;
1068365cdf5fSErez Shitrit 	}
1069365cdf5fSErez Shitrit 
1070365cdf5fSErez Shitrit 	caps->wqe_based_update =
1071365cdf5fSErez Shitrit 		MLX5_GET(query_hca_cap_out, out,
1072365cdf5fSErez Shitrit 			 capability.cmd_hca_cap.wqe_based_flow_table_update_cap);
1073365cdf5fSErez Shitrit 
1074365cdf5fSErez Shitrit 	caps->eswitch_manager = MLX5_GET(query_hca_cap_out, out,
1075365cdf5fSErez Shitrit 					 capability.cmd_hca_cap.eswitch_manager);
1076365cdf5fSErez Shitrit 
1077365cdf5fSErez Shitrit 	caps->flex_protocols = MLX5_GET(query_hca_cap_out, out,
1078365cdf5fSErez Shitrit 					capability.cmd_hca_cap.flex_parser_protocols);
1079365cdf5fSErez Shitrit 
1080365cdf5fSErez Shitrit 	caps->log_header_modify_argument_granularity =
1081365cdf5fSErez Shitrit 		MLX5_GET(query_hca_cap_out, out,
1082365cdf5fSErez Shitrit 			 capability.cmd_hca_cap.log_header_modify_argument_granularity);
1083365cdf5fSErez Shitrit 
1084365cdf5fSErez Shitrit 	caps->log_header_modify_argument_granularity -=
1085365cdf5fSErez Shitrit 			MLX5_GET(query_hca_cap_out, out,
1086365cdf5fSErez Shitrit 				 capability.cmd_hca_cap.
1087365cdf5fSErez Shitrit 				 log_header_modify_argument_granularity_offset);
1088365cdf5fSErez Shitrit 
1089365cdf5fSErez Shitrit 	caps->log_header_modify_argument_max_alloc =
1090365cdf5fSErez Shitrit 		MLX5_GET(query_hca_cap_out, out,
1091365cdf5fSErez Shitrit 			 capability.cmd_hca_cap.log_header_modify_argument_max_alloc);
1092365cdf5fSErez Shitrit 
1093365cdf5fSErez Shitrit 	caps->definer_format_sup =
1094365cdf5fSErez Shitrit 		MLX5_GET64(query_hca_cap_out, out,
1095365cdf5fSErez Shitrit 			   capability.cmd_hca_cap.match_definer_format_supported);
1096365cdf5fSErez Shitrit 
10977ab100f6SErez Shitrit 	caps->vhca_id = MLX5_GET(query_hca_cap_out, out,
10987ab100f6SErez Shitrit 				 capability.cmd_hca_cap.vhca_id);
10997ab100f6SErez Shitrit 
1100d4444de8SViacheslav Ovsiienko 	caps->sq_ts_format = MLX5_GET(query_hca_cap_out, out,
1101d4444de8SViacheslav Ovsiienko 				      capability.cmd_hca_cap.sq_ts_format);
1102d4444de8SViacheslav Ovsiienko 
110381cf20a2SHamdan Igbaria 	caps->ipsec_offload = MLX5_GET(query_hca_cap_out, out,
110481cf20a2SHamdan Igbaria 				      capability.cmd_hca_cap.ipsec_offload);
110581cf20a2SHamdan Igbaria 
1106*2acdf09bSHamdan Igbaria 	caps->roce = MLX5_GET(query_hca_cap_out, out, capability.cmd_hca_cap.roce);
1107*2acdf09bSHamdan Igbaria 
1108365cdf5fSErez Shitrit 	MLX5_SET(query_hca_cap_in, in, op_mod,
1109365cdf5fSErez Shitrit 		 MLX5_GET_HCA_CAP_OP_MOD_GENERAL_DEVICE_2 |
1110365cdf5fSErez Shitrit 		 MLX5_HCA_CAP_OPMOD_GET_CUR);
1111365cdf5fSErez Shitrit 
1112365cdf5fSErez Shitrit 	ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
1113365cdf5fSErez Shitrit 	if (ret) {
1114365cdf5fSErez Shitrit 		DR_LOG(ERR, "Failed to query device caps");
1115365cdf5fSErez Shitrit 		rte_errno = errno;
1116365cdf5fSErez Shitrit 		return rte_errno;
1117365cdf5fSErez Shitrit 	}
1118365cdf5fSErez Shitrit 
1119365cdf5fSErez Shitrit 	caps->full_dw_jumbo_support = MLX5_GET(query_hca_cap_out, out,
1120365cdf5fSErez Shitrit 					       capability.cmd_hca_cap_2.
1121365cdf5fSErez Shitrit 					       format_select_dw_8_6_ext);
1122365cdf5fSErez Shitrit 
1123365cdf5fSErez Shitrit 	caps->format_select_gtpu_dw_0 = MLX5_GET(query_hca_cap_out, out,
1124365cdf5fSErez Shitrit 						 capability.cmd_hca_cap_2.
1125365cdf5fSErez Shitrit 						 format_select_dw_gtpu_dw_0);
1126365cdf5fSErez Shitrit 
1127365cdf5fSErez Shitrit 	caps->format_select_gtpu_dw_1 = MLX5_GET(query_hca_cap_out, out,
1128365cdf5fSErez Shitrit 						 capability.cmd_hca_cap_2.
1129365cdf5fSErez Shitrit 						 format_select_dw_gtpu_dw_1);
1130365cdf5fSErez Shitrit 
1131365cdf5fSErez Shitrit 	caps->format_select_gtpu_dw_2 = MLX5_GET(query_hca_cap_out, out,
1132365cdf5fSErez Shitrit 						 capability.cmd_hca_cap_2.
1133365cdf5fSErez Shitrit 						 format_select_dw_gtpu_dw_2);
1134365cdf5fSErez Shitrit 
1135365cdf5fSErez Shitrit 	caps->format_select_gtpu_ext_dw_0 = MLX5_GET(query_hca_cap_out, out,
1136365cdf5fSErez Shitrit 						     capability.cmd_hca_cap_2.
1137365cdf5fSErez Shitrit 						     format_select_dw_gtpu_first_ext_dw_0);
1138365cdf5fSErez Shitrit 
113967acee3aSAlex Vesker 	caps->supp_type_gen_wqe = MLX5_GET(query_hca_cap_out, out,
114067acee3aSAlex Vesker 					   capability.cmd_hca_cap_2.
114167acee3aSAlex Vesker 					   generate_wqe_type);
114267acee3aSAlex Vesker 
1143b2300900SYevgeny Kliteynik 	/* check cross-VHCA support in cap2 */
1144b2300900SYevgeny Kliteynik 	res =
1145b2300900SYevgeny Kliteynik 	MLX5_GET(query_hca_cap_out, out,
1146b2300900SYevgeny Kliteynik 		capability.cmd_hca_cap_2.cross_vhca_object_to_object_supported);
1147b2300900SYevgeny Kliteynik 
1148b2300900SYevgeny Kliteynik 	caps->cross_vhca_resources = (res & MLX5_CROSS_VHCA_OBJ_TO_OBJ_TYPE_STC_TO_TIR) &&
1149b2300900SYevgeny Kliteynik 				     (res & MLX5_CROSS_VHCA_OBJ_TO_OBJ_TYPE_STC_TO_FT) &&
1150b2300900SYevgeny Kliteynik 				     (res & MLX5_CROSS_VHCA_OBJ_TO_OBJ_TYPE_FT_TO_RTC);
1151b2300900SYevgeny Kliteynik 
1152b2300900SYevgeny Kliteynik 	res =
1153b2300900SYevgeny Kliteynik 	MLX5_GET(query_hca_cap_out, out,
1154b2300900SYevgeny Kliteynik 		capability.cmd_hca_cap_2.allowed_object_for_other_vhca_access);
1155b2300900SYevgeny Kliteynik 
1156b2300900SYevgeny Kliteynik 	caps->cross_vhca_resources &= (res & MLX5_CROSS_VHCA_ALLOWED_OBJS_TIR) &&
1157b2300900SYevgeny Kliteynik 				      (res & MLX5_CROSS_VHCA_ALLOWED_OBJS_FT) &&
1158b2300900SYevgeny Kliteynik 				      (res & MLX5_CROSS_VHCA_ALLOWED_OBJS_RTC);
1159b2300900SYevgeny Kliteynik 
11607f5e6de5SItamar Gozlan 	caps->flow_table_hash_type = MLX5_GET(query_hca_cap_out, out,
11617f5e6de5SItamar Gozlan 					      capability.cmd_hca_cap_2.flow_table_hash_type);
11627f5e6de5SItamar Gozlan 
1163*2acdf09bSHamdan Igbaria 	caps->encap_entropy_hash_type = MLX5_GET(query_hca_cap_out, out,
1164*2acdf09bSHamdan Igbaria 						 capability.cmd_hca_cap_2.encap_entropy_hash_type);
1165*2acdf09bSHamdan Igbaria 
1166365cdf5fSErez Shitrit 	MLX5_SET(query_hca_cap_in, in, op_mod,
1167365cdf5fSErez Shitrit 		 MLX5_GET_HCA_CAP_OP_MOD_NIC_FLOW_TABLE |
1168365cdf5fSErez Shitrit 		 MLX5_HCA_CAP_OPMOD_GET_CUR);
1169365cdf5fSErez Shitrit 
1170365cdf5fSErez Shitrit 	ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
1171365cdf5fSErez Shitrit 	if (ret) {
1172365cdf5fSErez Shitrit 		DR_LOG(ERR, "Failed to query flow table caps");
1173365cdf5fSErez Shitrit 		rte_errno = errno;
1174365cdf5fSErez Shitrit 		return rte_errno;
1175365cdf5fSErez Shitrit 	}
1176365cdf5fSErez Shitrit 
1177365cdf5fSErez Shitrit 	caps->nic_ft.max_level = MLX5_GET(query_hca_cap_out, out,
1178365cdf5fSErez Shitrit 					  capability.flow_table_nic_cap.
1179365cdf5fSErez Shitrit 					  flow_table_properties_nic_receive.max_ft_level);
1180365cdf5fSErez Shitrit 
1181365cdf5fSErez Shitrit 	caps->nic_ft.reparse = MLX5_GET(query_hca_cap_out, out,
1182365cdf5fSErez Shitrit 					capability.flow_table_nic_cap.
1183365cdf5fSErez Shitrit 					flow_table_properties_nic_receive.reparse);
1184365cdf5fSErez Shitrit 
1185b81f95caSItamar Gozlan 	caps->nic_ft.ignore_flow_level_rtc_valid =
1186b81f95caSItamar Gozlan 		MLX5_GET(query_hca_cap_out,
1187b81f95caSItamar Gozlan 			 out,
1188b81f95caSItamar Gozlan 			 capability.flow_table_nic_cap.
1189b81f95caSItamar Gozlan 			 flow_table_properties_nic_receive.ignore_flow_level_rtc_valid);
1190b81f95caSItamar Gozlan 
1191b2300900SYevgeny Kliteynik 	/* check cross-VHCA support in flow table properties */
1192b2300900SYevgeny Kliteynik 	res =
1193b2300900SYevgeny Kliteynik 	MLX5_GET(query_hca_cap_out, out,
1194b2300900SYevgeny Kliteynik 		capability.flow_table_nic_cap.flow_table_properties_nic_receive.cross_vhca_object);
1195b2300900SYevgeny Kliteynik 	caps->cross_vhca_resources &= res;
1196b2300900SYevgeny Kliteynik 
1197365cdf5fSErez Shitrit 	if (caps->wqe_based_update) {
1198365cdf5fSErez Shitrit 		MLX5_SET(query_hca_cap_in, in, op_mod,
1199365cdf5fSErez Shitrit 			 MLX5_GET_HCA_CAP_OP_MOD_WQE_BASED_FLOW_TABLE |
1200365cdf5fSErez Shitrit 			 MLX5_HCA_CAP_OPMOD_GET_CUR);
1201365cdf5fSErez Shitrit 
1202365cdf5fSErez Shitrit 		ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
1203365cdf5fSErez Shitrit 		if (ret) {
1204365cdf5fSErez Shitrit 			DR_LOG(ERR, "Failed to query WQE based FT caps");
1205365cdf5fSErez Shitrit 			rte_errno = errno;
1206365cdf5fSErez Shitrit 			return rte_errno;
1207365cdf5fSErez Shitrit 		}
1208365cdf5fSErez Shitrit 
1209365cdf5fSErez Shitrit 		caps->rtc_reparse_mode = MLX5_GET(query_hca_cap_out, out,
1210365cdf5fSErez Shitrit 						  capability.wqe_based_flow_table_cap.
1211365cdf5fSErez Shitrit 						  rtc_reparse_mode);
1212365cdf5fSErez Shitrit 
1213365cdf5fSErez Shitrit 		caps->ste_format = MLX5_GET(query_hca_cap_out, out,
1214365cdf5fSErez Shitrit 					    capability.wqe_based_flow_table_cap.
1215365cdf5fSErez Shitrit 					    ste_format);
1216365cdf5fSErez Shitrit 
1217365cdf5fSErez Shitrit 		caps->rtc_index_mode = MLX5_GET(query_hca_cap_out, out,
1218365cdf5fSErez Shitrit 						capability.wqe_based_flow_table_cap.
1219365cdf5fSErez Shitrit 						rtc_index_mode);
1220365cdf5fSErez Shitrit 
1221365cdf5fSErez Shitrit 		caps->rtc_log_depth_max = MLX5_GET(query_hca_cap_out, out,
1222365cdf5fSErez Shitrit 						   capability.wqe_based_flow_table_cap.
1223365cdf5fSErez Shitrit 						   rtc_log_depth_max);
1224365cdf5fSErez Shitrit 
1225365cdf5fSErez Shitrit 		caps->ste_alloc_log_max = MLX5_GET(query_hca_cap_out, out,
1226365cdf5fSErez Shitrit 						   capability.wqe_based_flow_table_cap.
1227365cdf5fSErez Shitrit 						   ste_alloc_log_max);
1228365cdf5fSErez Shitrit 
1229365cdf5fSErez Shitrit 		caps->ste_alloc_log_gran = MLX5_GET(query_hca_cap_out, out,
1230365cdf5fSErez Shitrit 						    capability.wqe_based_flow_table_cap.
1231365cdf5fSErez Shitrit 						    ste_alloc_log_granularity);
1232365cdf5fSErez Shitrit 
1233365cdf5fSErez Shitrit 		caps->trivial_match_definer = MLX5_GET(query_hca_cap_out, out,
1234365cdf5fSErez Shitrit 						       capability.wqe_based_flow_table_cap.
1235365cdf5fSErez Shitrit 						       trivial_match_definer);
1236365cdf5fSErez Shitrit 
1237365cdf5fSErez Shitrit 		caps->stc_alloc_log_max = MLX5_GET(query_hca_cap_out, out,
1238365cdf5fSErez Shitrit 						   capability.wqe_based_flow_table_cap.
1239365cdf5fSErez Shitrit 						   stc_alloc_log_max);
1240365cdf5fSErez Shitrit 
1241365cdf5fSErez Shitrit 		caps->stc_alloc_log_gran = MLX5_GET(query_hca_cap_out, out,
1242365cdf5fSErez Shitrit 						    capability.wqe_based_flow_table_cap.
1243365cdf5fSErez Shitrit 						    stc_alloc_log_granularity);
124451f68dbaSYevgeny Kliteynik 
124551f68dbaSYevgeny Kliteynik 		caps->rtc_hash_split_table = MLX5_GET(query_hca_cap_out, out,
124651f68dbaSYevgeny Kliteynik 						      capability.wqe_based_flow_table_cap.
124751f68dbaSYevgeny Kliteynik 						      rtc_hash_split_table);
124851f68dbaSYevgeny Kliteynik 
124951f68dbaSYevgeny Kliteynik 		caps->rtc_linear_lookup_table = MLX5_GET(query_hca_cap_out, out,
125051f68dbaSYevgeny Kliteynik 							 capability.wqe_based_flow_table_cap.
125151f68dbaSYevgeny Kliteynik 							 rtc_linear_lookup_table);
125251f68dbaSYevgeny Kliteynik 
125351f68dbaSYevgeny Kliteynik 		caps->access_index_mode = MLX5_GET(query_hca_cap_out, out,
125451f68dbaSYevgeny Kliteynik 						   capability.wqe_based_flow_table_cap.
125551f68dbaSYevgeny Kliteynik 						   access_index_mode);
125651f68dbaSYevgeny Kliteynik 
125751f68dbaSYevgeny Kliteynik 		caps->linear_match_definer = MLX5_GET(query_hca_cap_out, out,
125851f68dbaSYevgeny Kliteynik 						      capability.wqe_based_flow_table_cap.
125951f68dbaSYevgeny Kliteynik 						      linear_match_definer_reg_c3);
126067acee3aSAlex Vesker 
126167acee3aSAlex Vesker 		caps->rtc_max_hash_def_gen_wqe = MLX5_GET(query_hca_cap_out, out,
126267acee3aSAlex Vesker 							  capability.wqe_based_flow_table_cap.
126367acee3aSAlex Vesker 							  rtc_max_num_hash_definer_gen_wqe);
126467acee3aSAlex Vesker 
126567acee3aSAlex Vesker 		caps->supp_ste_format_gen_wqe = MLX5_GET(query_hca_cap_out, out,
126667acee3aSAlex Vesker 							 capability.wqe_based_flow_table_cap.
126767acee3aSAlex Vesker 							 ste_format_gen_wqe);
12681f8fc88dSAlex Vesker 
12691f8fc88dSAlex Vesker 		caps->fdb_tir_stc = MLX5_GET(query_hca_cap_out, out,
12701f8fc88dSAlex Vesker 					     capability.wqe_based_flow_table_cap.
12711f8fc88dSAlex Vesker 					     fdb_jump_to_tir_stc);
1272365cdf5fSErez Shitrit 	}
1273365cdf5fSErez Shitrit 
1274365cdf5fSErez Shitrit 	if (caps->eswitch_manager) {
1275365cdf5fSErez Shitrit 		MLX5_SET(query_hca_cap_in, in, op_mod,
1276365cdf5fSErez Shitrit 			 MLX5_GET_HCA_CAP_OP_MOD_ESW_FLOW_TABLE |
1277365cdf5fSErez Shitrit 			 MLX5_HCA_CAP_OPMOD_GET_CUR);
1278365cdf5fSErez Shitrit 
1279365cdf5fSErez Shitrit 		ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
1280365cdf5fSErez Shitrit 		if (ret) {
1281365cdf5fSErez Shitrit 			DR_LOG(ERR, "Failed to query flow table esw caps");
1282365cdf5fSErez Shitrit 			rte_errno = errno;
1283365cdf5fSErez Shitrit 			return rte_errno;
1284365cdf5fSErez Shitrit 		}
1285365cdf5fSErez Shitrit 
1286365cdf5fSErez Shitrit 		caps->fdb_ft.max_level = MLX5_GET(query_hca_cap_out, out,
1287365cdf5fSErez Shitrit 						  capability.flow_table_nic_cap.
1288365cdf5fSErez Shitrit 						  flow_table_properties_nic_receive.max_ft_level);
1289365cdf5fSErez Shitrit 
1290365cdf5fSErez Shitrit 		caps->fdb_ft.reparse = MLX5_GET(query_hca_cap_out, out,
1291365cdf5fSErez Shitrit 						capability.flow_table_nic_cap.
1292365cdf5fSErez Shitrit 						flow_table_properties_nic_receive.reparse);
1293365cdf5fSErez Shitrit 
1294365cdf5fSErez Shitrit 		MLX5_SET(query_hca_cap_in, in, op_mod,
1295365cdf5fSErez Shitrit 			 MLX5_SET_HCA_CAP_OP_MOD_ESW | MLX5_HCA_CAP_OPMOD_GET_CUR);
1296365cdf5fSErez Shitrit 
1297365cdf5fSErez Shitrit 		ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
1298365cdf5fSErez Shitrit 		if (ret) {
12996524f0c8SAlex Vesker 			DR_LOG(ERR, "Query eswitch capabilities failed %d", ret);
1300365cdf5fSErez Shitrit 			rte_errno = errno;
1301365cdf5fSErez Shitrit 			return rte_errno;
1302365cdf5fSErez Shitrit 		}
1303365cdf5fSErez Shitrit 
1304365cdf5fSErez Shitrit 		if (MLX5_GET(query_hca_cap_out, out,
1305365cdf5fSErez Shitrit 			     capability.esw_cap.esw_manager_vport_number_valid))
1306365cdf5fSErez Shitrit 			caps->eswitch_manager_vport_number =
1307365cdf5fSErez Shitrit 			MLX5_GET(query_hca_cap_out, out,
1308365cdf5fSErez Shitrit 				 capability.esw_cap.esw_manager_vport_number);
1309eefaf43dSShun Hao 
1310eefaf43dSShun Hao 		caps->merged_eswitch = MLX5_GET(query_hca_cap_out, out,
1311eefaf43dSShun Hao 						capability.esw_cap.merged_eswitch);
1312365cdf5fSErez Shitrit 	}
1313365cdf5fSErez Shitrit 
1314*2acdf09bSHamdan Igbaria 	if (caps->roce) {
1315*2acdf09bSHamdan Igbaria 		MLX5_SET(query_hca_cap_in, in, op_mod,
1316*2acdf09bSHamdan Igbaria 			 MLX5_GET_HCA_CAP_OP_MOD_ROCE |
1317*2acdf09bSHamdan Igbaria 			 MLX5_HCA_CAP_OPMOD_GET_CUR);
1318*2acdf09bSHamdan Igbaria 
1319*2acdf09bSHamdan Igbaria 		ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
1320*2acdf09bSHamdan Igbaria 		if (ret) {
1321*2acdf09bSHamdan Igbaria 			DR_LOG(ERR, "Failed to query roce caps");
1322*2acdf09bSHamdan Igbaria 			rte_errno = errno;
1323*2acdf09bSHamdan Igbaria 			return rte_errno;
1324*2acdf09bSHamdan Igbaria 		}
1325*2acdf09bSHamdan Igbaria 
1326*2acdf09bSHamdan Igbaria 		caps->roce_max_src_udp_port = MLX5_GET(query_hca_cap_out, out,
1327*2acdf09bSHamdan Igbaria 						capability.roce_caps.r_roce_max_src_udp_port);
1328*2acdf09bSHamdan Igbaria 		caps->roce_min_src_udp_port = MLX5_GET(query_hca_cap_out, out,
1329*2acdf09bSHamdan Igbaria 						capability.roce_caps.r_roce_min_src_udp_port);
1330*2acdf09bSHamdan Igbaria 	}
1331*2acdf09bSHamdan Igbaria 
1332365cdf5fSErez Shitrit 	ret = mlx5_glue->query_device_ex(ctx, NULL, &attr_ex);
1333365cdf5fSErez Shitrit 	if (ret) {
1334365cdf5fSErez Shitrit 		DR_LOG(ERR, "Failed to query device attributes");
1335365cdf5fSErez Shitrit 		rte_errno = ret;
1336365cdf5fSErez Shitrit 		return rte_errno;
1337365cdf5fSErez Shitrit 	}
1338365cdf5fSErez Shitrit 
1339365cdf5fSErez Shitrit 	strlcpy(caps->fw_ver, attr_ex.orig_attr.fw_ver, sizeof(caps->fw_ver));
1340365cdf5fSErez Shitrit 
1341365cdf5fSErez Shitrit 	port_info = flow_hw_get_wire_port(ctx);
1342365cdf5fSErez Shitrit 	if (port_info) {
1343365cdf5fSErez Shitrit 		caps->wire_regc = port_info->regc_value;
1344365cdf5fSErez Shitrit 		caps->wire_regc_mask = port_info->regc_mask;
1345365cdf5fSErez Shitrit 	} else {
1346365cdf5fSErez Shitrit 		DR_LOG(INFO, "Failed to query wire port regc value");
1347365cdf5fSErez Shitrit 	}
1348365cdf5fSErez Shitrit 
1349365cdf5fSErez Shitrit 	return ret;
1350365cdf5fSErez Shitrit }
1351365cdf5fSErez Shitrit 
1352365cdf5fSErez Shitrit int mlx5dr_cmd_query_ib_port(struct ibv_context *ctx,
1353365cdf5fSErez Shitrit 			     struct mlx5dr_cmd_query_vport_caps *vport_caps,
1354365cdf5fSErez Shitrit 			     uint32_t port_num)
1355365cdf5fSErez Shitrit {
1356365cdf5fSErez Shitrit 	struct mlx5_port_info port_info = {0};
1357365cdf5fSErez Shitrit 	uint32_t flags;
1358365cdf5fSErez Shitrit 	int ret;
1359365cdf5fSErez Shitrit 
1360365cdf5fSErez Shitrit 	flags = MLX5_PORT_QUERY_VPORT | MLX5_PORT_QUERY_ESW_OWNER_VHCA_ID;
1361365cdf5fSErez Shitrit 
1362365cdf5fSErez Shitrit 	ret = mlx5_glue->devx_port_query(ctx, port_num, &port_info);
1363365cdf5fSErez Shitrit 	/* Check if query succeed and vport is enabled */
1364365cdf5fSErez Shitrit 	if (ret || (port_info.query_flags & flags) != flags) {
1365365cdf5fSErez Shitrit 		rte_errno = ENOTSUP;
1366365cdf5fSErez Shitrit 		return rte_errno;
1367365cdf5fSErez Shitrit 	}
1368365cdf5fSErez Shitrit 
1369365cdf5fSErez Shitrit 	vport_caps->vport_num = port_info.vport_id;
1370365cdf5fSErez Shitrit 	vport_caps->esw_owner_vhca_id = port_info.esw_owner_vhca_id;
1371365cdf5fSErez Shitrit 
1372365cdf5fSErez Shitrit 	if (port_info.query_flags & MLX5_PORT_QUERY_REG_C0) {
1373365cdf5fSErez Shitrit 		vport_caps->metadata_c = port_info.vport_meta_tag;
1374365cdf5fSErez Shitrit 		vport_caps->metadata_c_mask = port_info.vport_meta_mask;
1375365cdf5fSErez Shitrit 	}
1376365cdf5fSErez Shitrit 
1377365cdf5fSErez Shitrit 	return 0;
1378365cdf5fSErez Shitrit }
1379