1*2d9fd380Sjfb8856606 // SPDX-License-Identifier: BSD-3-Clause
2*2d9fd380Sjfb8856606 /* Copyright 2018 Mellanox Technologies, Ltd */
3*2d9fd380Sjfb8856606 
4*2d9fd380Sjfb8856606 #include <unistd.h>
5*2d9fd380Sjfb8856606 
6*2d9fd380Sjfb8856606 #include <rte_errno.h>
7*2d9fd380Sjfb8856606 #include <rte_malloc.h>
8*2d9fd380Sjfb8856606 #include <rte_eal_paging.h>
9*2d9fd380Sjfb8856606 
10*2d9fd380Sjfb8856606 #include "mlx5_prm.h"
11*2d9fd380Sjfb8856606 #include "mlx5_devx_cmds.h"
12*2d9fd380Sjfb8856606 #include "mlx5_common_utils.h"
13*2d9fd380Sjfb8856606 #include "mlx5_malloc.h"
14*2d9fd380Sjfb8856606 
15*2d9fd380Sjfb8856606 
16*2d9fd380Sjfb8856606 /**
17*2d9fd380Sjfb8856606  * Perform read access to the registers. Reads data from register
18*2d9fd380Sjfb8856606  * and writes ones to the specified buffer.
19*2d9fd380Sjfb8856606  *
20*2d9fd380Sjfb8856606  * @param[in] ctx
21*2d9fd380Sjfb8856606  *   Context returned from mlx5 open_device() glue function.
22*2d9fd380Sjfb8856606  * @param[in] reg_id
23*2d9fd380Sjfb8856606  *   Register identifier according to the PRM.
24*2d9fd380Sjfb8856606  * @param[in] arg
25*2d9fd380Sjfb8856606  *   Register access auxiliary parameter according to the PRM.
26*2d9fd380Sjfb8856606  * @param[out] data
27*2d9fd380Sjfb8856606  *   Pointer to the buffer to store read data.
28*2d9fd380Sjfb8856606  * @param[in] dw_cnt
29*2d9fd380Sjfb8856606  *   Buffer size in double words.
30*2d9fd380Sjfb8856606  *
31*2d9fd380Sjfb8856606  * @return
32*2d9fd380Sjfb8856606  *   0 on success, a negative value otherwise.
33*2d9fd380Sjfb8856606  */
34*2d9fd380Sjfb8856606 int
mlx5_devx_cmd_register_read(void * ctx,uint16_t reg_id,uint32_t arg,uint32_t * data,uint32_t dw_cnt)35*2d9fd380Sjfb8856606 mlx5_devx_cmd_register_read(void *ctx, uint16_t reg_id, uint32_t arg,
36*2d9fd380Sjfb8856606 			    uint32_t *data, uint32_t dw_cnt)
37*2d9fd380Sjfb8856606 {
38*2d9fd380Sjfb8856606 	uint32_t in[MLX5_ST_SZ_DW(access_register_in)]   = {0};
39*2d9fd380Sjfb8856606 	uint32_t out[MLX5_ST_SZ_DW(access_register_out) +
40*2d9fd380Sjfb8856606 		     MLX5_ACCESS_REGISTER_DATA_DWORD_MAX] = {0};
41*2d9fd380Sjfb8856606 	int status, rc;
42*2d9fd380Sjfb8856606 
43*2d9fd380Sjfb8856606 	MLX5_ASSERT(data && dw_cnt);
44*2d9fd380Sjfb8856606 	MLX5_ASSERT(dw_cnt <= MLX5_ACCESS_REGISTER_DATA_DWORD_MAX);
45*2d9fd380Sjfb8856606 	if (dw_cnt  > MLX5_ACCESS_REGISTER_DATA_DWORD_MAX) {
46*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Not enough  buffer for register read data");
47*2d9fd380Sjfb8856606 		return -1;
48*2d9fd380Sjfb8856606 	}
49*2d9fd380Sjfb8856606 	MLX5_SET(access_register_in, in, opcode,
50*2d9fd380Sjfb8856606 		 MLX5_CMD_OP_ACCESS_REGISTER_USER);
51*2d9fd380Sjfb8856606 	MLX5_SET(access_register_in, in, op_mod,
52*2d9fd380Sjfb8856606 					MLX5_ACCESS_REGISTER_IN_OP_MOD_READ);
53*2d9fd380Sjfb8856606 	MLX5_SET(access_register_in, in, register_id, reg_id);
54*2d9fd380Sjfb8856606 	MLX5_SET(access_register_in, in, argument, arg);
55*2d9fd380Sjfb8856606 	rc = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out,
56*2d9fd380Sjfb8856606 					 MLX5_ST_SZ_DW(access_register_out) *
57*2d9fd380Sjfb8856606 					 sizeof(uint32_t) + dw_cnt);
58*2d9fd380Sjfb8856606 	if (rc)
59*2d9fd380Sjfb8856606 		goto error;
60*2d9fd380Sjfb8856606 	status = MLX5_GET(access_register_out, out, status);
61*2d9fd380Sjfb8856606 	if (status) {
62*2d9fd380Sjfb8856606 		int syndrome = MLX5_GET(access_register_out, out, syndrome);
63*2d9fd380Sjfb8856606 
64*2d9fd380Sjfb8856606 		DRV_LOG(DEBUG, "Failed to access NIC register 0x%X, "
65*2d9fd380Sjfb8856606 			       "status %x, syndrome = %x",
66*2d9fd380Sjfb8856606 			       reg_id, status, syndrome);
67*2d9fd380Sjfb8856606 		return -1;
68*2d9fd380Sjfb8856606 	}
69*2d9fd380Sjfb8856606 	memcpy(data, &out[MLX5_ST_SZ_DW(access_register_out)],
70*2d9fd380Sjfb8856606 	       dw_cnt * sizeof(uint32_t));
71*2d9fd380Sjfb8856606 	return 0;
72*2d9fd380Sjfb8856606 error:
73*2d9fd380Sjfb8856606 	rc = (rc > 0) ? -rc : rc;
74*2d9fd380Sjfb8856606 	return rc;
75*2d9fd380Sjfb8856606 }
76*2d9fd380Sjfb8856606 
77*2d9fd380Sjfb8856606 /**
78*2d9fd380Sjfb8856606  * Allocate flow counters via devx interface.
79*2d9fd380Sjfb8856606  *
80*2d9fd380Sjfb8856606  * @param[in] ctx
81*2d9fd380Sjfb8856606  *   Context returned from mlx5 open_device() glue function.
82*2d9fd380Sjfb8856606  * @param dcs
83*2d9fd380Sjfb8856606  *   Pointer to counters properties structure to be filled by the routine.
84*2d9fd380Sjfb8856606  * @param bulk_n_128
85*2d9fd380Sjfb8856606  *   Bulk counter numbers in 128 counters units.
86*2d9fd380Sjfb8856606  *
87*2d9fd380Sjfb8856606  * @return
88*2d9fd380Sjfb8856606  *   Pointer to counter object on success, a negative value otherwise and
89*2d9fd380Sjfb8856606  *   rte_errno is set.
90*2d9fd380Sjfb8856606  */
91*2d9fd380Sjfb8856606 struct mlx5_devx_obj *
mlx5_devx_cmd_flow_counter_alloc(void * ctx,uint32_t bulk_n_128)92*2d9fd380Sjfb8856606 mlx5_devx_cmd_flow_counter_alloc(void *ctx, uint32_t bulk_n_128)
93*2d9fd380Sjfb8856606 {
94*2d9fd380Sjfb8856606 	struct mlx5_devx_obj *dcs = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*dcs),
95*2d9fd380Sjfb8856606 						0, SOCKET_ID_ANY);
96*2d9fd380Sjfb8856606 	uint32_t in[MLX5_ST_SZ_DW(alloc_flow_counter_in)]   = {0};
97*2d9fd380Sjfb8856606 	uint32_t out[MLX5_ST_SZ_DW(alloc_flow_counter_out)] = {0};
98*2d9fd380Sjfb8856606 
99*2d9fd380Sjfb8856606 	if (!dcs) {
100*2d9fd380Sjfb8856606 		rte_errno = ENOMEM;
101*2d9fd380Sjfb8856606 		return NULL;
102*2d9fd380Sjfb8856606 	}
103*2d9fd380Sjfb8856606 	MLX5_SET(alloc_flow_counter_in, in, opcode,
104*2d9fd380Sjfb8856606 		 MLX5_CMD_OP_ALLOC_FLOW_COUNTER);
105*2d9fd380Sjfb8856606 	MLX5_SET(alloc_flow_counter_in, in, flow_counter_bulk, bulk_n_128);
106*2d9fd380Sjfb8856606 	dcs->obj = mlx5_glue->devx_obj_create(ctx, in,
107*2d9fd380Sjfb8856606 					      sizeof(in), out, sizeof(out));
108*2d9fd380Sjfb8856606 	if (!dcs->obj) {
109*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Can't allocate counters - error %d", errno);
110*2d9fd380Sjfb8856606 		rte_errno = errno;
111*2d9fd380Sjfb8856606 		mlx5_free(dcs);
112*2d9fd380Sjfb8856606 		return NULL;
113*2d9fd380Sjfb8856606 	}
114*2d9fd380Sjfb8856606 	dcs->id = MLX5_GET(alloc_flow_counter_out, out, flow_counter_id);
115*2d9fd380Sjfb8856606 	return dcs;
116*2d9fd380Sjfb8856606 }
117*2d9fd380Sjfb8856606 
118*2d9fd380Sjfb8856606 /**
119*2d9fd380Sjfb8856606  * Query flow counters values.
120*2d9fd380Sjfb8856606  *
121*2d9fd380Sjfb8856606  * @param[in] dcs
122*2d9fd380Sjfb8856606  *   devx object that was obtained from mlx5_devx_cmd_fc_alloc.
123*2d9fd380Sjfb8856606  * @param[in] clear
124*2d9fd380Sjfb8856606  *   Whether hardware should clear the counters after the query or not.
125*2d9fd380Sjfb8856606  * @param[in] n_counters
126*2d9fd380Sjfb8856606  *   0 in case of 1 counter to read, otherwise the counter number to read.
127*2d9fd380Sjfb8856606  *  @param pkts
128*2d9fd380Sjfb8856606  *   The number of packets that matched the flow.
129*2d9fd380Sjfb8856606  *  @param bytes
130*2d9fd380Sjfb8856606  *    The number of bytes that matched the flow.
131*2d9fd380Sjfb8856606  *  @param mkey
132*2d9fd380Sjfb8856606  *   The mkey key for batch query.
133*2d9fd380Sjfb8856606  *  @param addr
134*2d9fd380Sjfb8856606  *    The address in the mkey range for batch query.
135*2d9fd380Sjfb8856606  *  @param cmd_comp
136*2d9fd380Sjfb8856606  *   The completion object for asynchronous batch query.
137*2d9fd380Sjfb8856606  *  @param async_id
138*2d9fd380Sjfb8856606  *    The ID to be returned in the asynchronous batch query response.
139*2d9fd380Sjfb8856606  *
140*2d9fd380Sjfb8856606  * @return
141*2d9fd380Sjfb8856606  *   0 on success, a negative value otherwise.
142*2d9fd380Sjfb8856606  */
143*2d9fd380Sjfb8856606 int
mlx5_devx_cmd_flow_counter_query(struct mlx5_devx_obj * dcs,int clear,uint32_t n_counters,uint64_t * pkts,uint64_t * bytes,uint32_t mkey,void * addr,void * cmd_comp,uint64_t async_id)144*2d9fd380Sjfb8856606 mlx5_devx_cmd_flow_counter_query(struct mlx5_devx_obj *dcs,
145*2d9fd380Sjfb8856606 				 int clear, uint32_t n_counters,
146*2d9fd380Sjfb8856606 				 uint64_t *pkts, uint64_t *bytes,
147*2d9fd380Sjfb8856606 				 uint32_t mkey, void *addr,
148*2d9fd380Sjfb8856606 				 void *cmd_comp,
149*2d9fd380Sjfb8856606 				 uint64_t async_id)
150*2d9fd380Sjfb8856606 {
151*2d9fd380Sjfb8856606 	int out_len = MLX5_ST_SZ_BYTES(query_flow_counter_out) +
152*2d9fd380Sjfb8856606 			MLX5_ST_SZ_BYTES(traffic_counter);
153*2d9fd380Sjfb8856606 	uint32_t out[out_len];
154*2d9fd380Sjfb8856606 	uint32_t in[MLX5_ST_SZ_DW(query_flow_counter_in)] = {0};
155*2d9fd380Sjfb8856606 	void *stats;
156*2d9fd380Sjfb8856606 	int rc;
157*2d9fd380Sjfb8856606 
158*2d9fd380Sjfb8856606 	MLX5_SET(query_flow_counter_in, in, opcode,
159*2d9fd380Sjfb8856606 		 MLX5_CMD_OP_QUERY_FLOW_COUNTER);
160*2d9fd380Sjfb8856606 	MLX5_SET(query_flow_counter_in, in, op_mod, 0);
161*2d9fd380Sjfb8856606 	MLX5_SET(query_flow_counter_in, in, flow_counter_id, dcs->id);
162*2d9fd380Sjfb8856606 	MLX5_SET(query_flow_counter_in, in, clear, !!clear);
163*2d9fd380Sjfb8856606 
164*2d9fd380Sjfb8856606 	if (n_counters) {
165*2d9fd380Sjfb8856606 		MLX5_SET(query_flow_counter_in, in, num_of_counters,
166*2d9fd380Sjfb8856606 			 n_counters);
167*2d9fd380Sjfb8856606 		MLX5_SET(query_flow_counter_in, in, dump_to_memory, 1);
168*2d9fd380Sjfb8856606 		MLX5_SET(query_flow_counter_in, in, mkey, mkey);
169*2d9fd380Sjfb8856606 		MLX5_SET64(query_flow_counter_in, in, address,
170*2d9fd380Sjfb8856606 			   (uint64_t)(uintptr_t)addr);
171*2d9fd380Sjfb8856606 	}
172*2d9fd380Sjfb8856606 	if (!cmd_comp)
173*2d9fd380Sjfb8856606 		rc = mlx5_glue->devx_obj_query(dcs->obj, in, sizeof(in), out,
174*2d9fd380Sjfb8856606 					       out_len);
175*2d9fd380Sjfb8856606 	else
176*2d9fd380Sjfb8856606 		rc = mlx5_glue->devx_obj_query_async(dcs->obj, in, sizeof(in),
177*2d9fd380Sjfb8856606 						     out_len, async_id,
178*2d9fd380Sjfb8856606 						     cmd_comp);
179*2d9fd380Sjfb8856606 	if (rc) {
180*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to query devx counters with rc %d", rc);
181*2d9fd380Sjfb8856606 		rte_errno = rc;
182*2d9fd380Sjfb8856606 		return -rc;
183*2d9fd380Sjfb8856606 	}
184*2d9fd380Sjfb8856606 	if (!n_counters) {
185*2d9fd380Sjfb8856606 		stats = MLX5_ADDR_OF(query_flow_counter_out,
186*2d9fd380Sjfb8856606 				     out, flow_statistics);
187*2d9fd380Sjfb8856606 		*pkts = MLX5_GET64(traffic_counter, stats, packets);
188*2d9fd380Sjfb8856606 		*bytes = MLX5_GET64(traffic_counter, stats, octets);
189*2d9fd380Sjfb8856606 	}
190*2d9fd380Sjfb8856606 	return 0;
191*2d9fd380Sjfb8856606 }
192*2d9fd380Sjfb8856606 
193*2d9fd380Sjfb8856606 /**
194*2d9fd380Sjfb8856606  * Create a new mkey.
195*2d9fd380Sjfb8856606  *
196*2d9fd380Sjfb8856606  * @param[in] ctx
197*2d9fd380Sjfb8856606  *   Context returned from mlx5 open_device() glue function.
198*2d9fd380Sjfb8856606  * @param[in] attr
199*2d9fd380Sjfb8856606  *   Attributes of the requested mkey.
200*2d9fd380Sjfb8856606  *
201*2d9fd380Sjfb8856606  * @return
202*2d9fd380Sjfb8856606  *   Pointer to Devx mkey on success, a negative value otherwise and rte_errno
203*2d9fd380Sjfb8856606  *   is set.
204*2d9fd380Sjfb8856606  */
205*2d9fd380Sjfb8856606 struct mlx5_devx_obj *
mlx5_devx_cmd_mkey_create(void * ctx,struct mlx5_devx_mkey_attr * attr)206*2d9fd380Sjfb8856606 mlx5_devx_cmd_mkey_create(void *ctx,
207*2d9fd380Sjfb8856606 			  struct mlx5_devx_mkey_attr *attr)
208*2d9fd380Sjfb8856606 {
209*2d9fd380Sjfb8856606 	struct mlx5_klm *klm_array = attr->klm_array;
210*2d9fd380Sjfb8856606 	int klm_num = attr->klm_num;
211*2d9fd380Sjfb8856606 	int in_size_dw = MLX5_ST_SZ_DW(create_mkey_in) +
212*2d9fd380Sjfb8856606 		     (klm_num ? RTE_ALIGN(klm_num, 4) : 0) * MLX5_ST_SZ_DW(klm);
213*2d9fd380Sjfb8856606 	uint32_t in[in_size_dw];
214*2d9fd380Sjfb8856606 	uint32_t out[MLX5_ST_SZ_DW(create_mkey_out)] = {0};
215*2d9fd380Sjfb8856606 	void *mkc;
216*2d9fd380Sjfb8856606 	struct mlx5_devx_obj *mkey = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*mkey),
217*2d9fd380Sjfb8856606 						 0, SOCKET_ID_ANY);
218*2d9fd380Sjfb8856606 	size_t pgsize;
219*2d9fd380Sjfb8856606 	uint32_t translation_size;
220*2d9fd380Sjfb8856606 
221*2d9fd380Sjfb8856606 	if (!mkey) {
222*2d9fd380Sjfb8856606 		rte_errno = ENOMEM;
223*2d9fd380Sjfb8856606 		return NULL;
224*2d9fd380Sjfb8856606 	}
225*2d9fd380Sjfb8856606 	memset(in, 0, in_size_dw * 4);
226*2d9fd380Sjfb8856606 	pgsize = rte_mem_page_size();
227*2d9fd380Sjfb8856606 	if (pgsize == (size_t)-1) {
228*2d9fd380Sjfb8856606 		mlx5_free(mkey);
229*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to get page size");
230*2d9fd380Sjfb8856606 		rte_errno = ENOMEM;
231*2d9fd380Sjfb8856606 		return NULL;
232*2d9fd380Sjfb8856606 	}
233*2d9fd380Sjfb8856606 	MLX5_SET(create_mkey_in, in, opcode, MLX5_CMD_OP_CREATE_MKEY);
234*2d9fd380Sjfb8856606 	mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry);
235*2d9fd380Sjfb8856606 	if (klm_num > 0) {
236*2d9fd380Sjfb8856606 		int i;
237*2d9fd380Sjfb8856606 		uint8_t *klm = (uint8_t *)MLX5_ADDR_OF(create_mkey_in, in,
238*2d9fd380Sjfb8856606 						       klm_pas_mtt);
239*2d9fd380Sjfb8856606 		translation_size = RTE_ALIGN(klm_num, 4);
240*2d9fd380Sjfb8856606 		for (i = 0; i < klm_num; i++) {
241*2d9fd380Sjfb8856606 			MLX5_SET(klm, klm, byte_count, klm_array[i].byte_count);
242*2d9fd380Sjfb8856606 			MLX5_SET(klm, klm, mkey, klm_array[i].mkey);
243*2d9fd380Sjfb8856606 			MLX5_SET64(klm, klm, address, klm_array[i].address);
244*2d9fd380Sjfb8856606 			klm += MLX5_ST_SZ_BYTES(klm);
245*2d9fd380Sjfb8856606 		}
246*2d9fd380Sjfb8856606 		for (; i < (int)translation_size; i++) {
247*2d9fd380Sjfb8856606 			MLX5_SET(klm, klm, mkey, 0x0);
248*2d9fd380Sjfb8856606 			MLX5_SET64(klm, klm, address, 0x0);
249*2d9fd380Sjfb8856606 			klm += MLX5_ST_SZ_BYTES(klm);
250*2d9fd380Sjfb8856606 		}
251*2d9fd380Sjfb8856606 		MLX5_SET(mkc, mkc, access_mode_1_0, attr->log_entity_size ?
252*2d9fd380Sjfb8856606 			 MLX5_MKC_ACCESS_MODE_KLM_FBS :
253*2d9fd380Sjfb8856606 			 MLX5_MKC_ACCESS_MODE_KLM);
254*2d9fd380Sjfb8856606 		MLX5_SET(mkc, mkc, log_page_size, attr->log_entity_size);
255*2d9fd380Sjfb8856606 	} else {
256*2d9fd380Sjfb8856606 		translation_size = (RTE_ALIGN(attr->size, pgsize) * 8) / 16;
257*2d9fd380Sjfb8856606 		MLX5_SET(mkc, mkc, access_mode_1_0, MLX5_MKC_ACCESS_MODE_MTT);
258*2d9fd380Sjfb8856606 		MLX5_SET(mkc, mkc, log_page_size, rte_log2_u32(pgsize));
259*2d9fd380Sjfb8856606 	}
260*2d9fd380Sjfb8856606 	MLX5_SET(create_mkey_in, in, translations_octword_actual_size,
261*2d9fd380Sjfb8856606 		 translation_size);
262*2d9fd380Sjfb8856606 	MLX5_SET(create_mkey_in, in, mkey_umem_id, attr->umem_id);
263*2d9fd380Sjfb8856606 	MLX5_SET(create_mkey_in, in, pg_access, attr->pg_access);
264*2d9fd380Sjfb8856606 	MLX5_SET(mkc, mkc, lw, 0x1);
265*2d9fd380Sjfb8856606 	MLX5_SET(mkc, mkc, lr, 0x1);
266*2d9fd380Sjfb8856606 	MLX5_SET(mkc, mkc, qpn, 0xffffff);
267*2d9fd380Sjfb8856606 	MLX5_SET(mkc, mkc, pd, attr->pd);
268*2d9fd380Sjfb8856606 	MLX5_SET(mkc, mkc, mkey_7_0, attr->umem_id & 0xFF);
269*2d9fd380Sjfb8856606 	MLX5_SET(mkc, mkc, translations_octword_size, translation_size);
270*2d9fd380Sjfb8856606 	MLX5_SET(mkc, mkc, relaxed_ordering_write,
271*2d9fd380Sjfb8856606 		attr->relaxed_ordering_write);
272*2d9fd380Sjfb8856606 	MLX5_SET(mkc, mkc, relaxed_ordering_read,
273*2d9fd380Sjfb8856606 		attr->relaxed_ordering_read);
274*2d9fd380Sjfb8856606 	MLX5_SET64(mkc, mkc, start_addr, attr->addr);
275*2d9fd380Sjfb8856606 	MLX5_SET64(mkc, mkc, len, attr->size);
276*2d9fd380Sjfb8856606 	mkey->obj = mlx5_glue->devx_obj_create(ctx, in, in_size_dw * 4, out,
277*2d9fd380Sjfb8856606 					       sizeof(out));
278*2d9fd380Sjfb8856606 	if (!mkey->obj) {
279*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Can't create %sdirect mkey - error %d\n",
280*2d9fd380Sjfb8856606 			klm_num ? "an in" : "a ", errno);
281*2d9fd380Sjfb8856606 		rte_errno = errno;
282*2d9fd380Sjfb8856606 		mlx5_free(mkey);
283*2d9fd380Sjfb8856606 		return NULL;
284*2d9fd380Sjfb8856606 	}
285*2d9fd380Sjfb8856606 	mkey->id = MLX5_GET(create_mkey_out, out, mkey_index);
286*2d9fd380Sjfb8856606 	mkey->id = (mkey->id << 8) | (attr->umem_id & 0xFF);
287*2d9fd380Sjfb8856606 	return mkey;
288*2d9fd380Sjfb8856606 }
289*2d9fd380Sjfb8856606 
290*2d9fd380Sjfb8856606 /**
291*2d9fd380Sjfb8856606  * Get status of devx command response.
292*2d9fd380Sjfb8856606  * Mainly used for asynchronous commands.
293*2d9fd380Sjfb8856606  *
294*2d9fd380Sjfb8856606  * @param[in] out
295*2d9fd380Sjfb8856606  *   The out response buffer.
296*2d9fd380Sjfb8856606  *
297*2d9fd380Sjfb8856606  * @return
298*2d9fd380Sjfb8856606  *   0 on success, non-zero value otherwise.
299*2d9fd380Sjfb8856606  */
300*2d9fd380Sjfb8856606 int
mlx5_devx_get_out_command_status(void * out)301*2d9fd380Sjfb8856606 mlx5_devx_get_out_command_status(void *out)
302*2d9fd380Sjfb8856606 {
303*2d9fd380Sjfb8856606 	int status;
304*2d9fd380Sjfb8856606 
305*2d9fd380Sjfb8856606 	if (!out)
306*2d9fd380Sjfb8856606 		return -EINVAL;
307*2d9fd380Sjfb8856606 	status = MLX5_GET(query_flow_counter_out, out, status);
308*2d9fd380Sjfb8856606 	if (status) {
309*2d9fd380Sjfb8856606 		int syndrome = MLX5_GET(query_flow_counter_out, out, syndrome);
310*2d9fd380Sjfb8856606 
311*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Bad devX status %x, syndrome = %x", status,
312*2d9fd380Sjfb8856606 			syndrome);
313*2d9fd380Sjfb8856606 	}
314*2d9fd380Sjfb8856606 	return status;
315*2d9fd380Sjfb8856606 }
316*2d9fd380Sjfb8856606 
317*2d9fd380Sjfb8856606 /**
318*2d9fd380Sjfb8856606  * Destroy any object allocated by a Devx API.
319*2d9fd380Sjfb8856606  *
320*2d9fd380Sjfb8856606  * @param[in] obj
321*2d9fd380Sjfb8856606  *   Pointer to a general object.
322*2d9fd380Sjfb8856606  *
323*2d9fd380Sjfb8856606  * @return
324*2d9fd380Sjfb8856606  *   0 on success, a negative value otherwise.
325*2d9fd380Sjfb8856606  */
326*2d9fd380Sjfb8856606 int
mlx5_devx_cmd_destroy(struct mlx5_devx_obj * obj)327*2d9fd380Sjfb8856606 mlx5_devx_cmd_destroy(struct mlx5_devx_obj *obj)
328*2d9fd380Sjfb8856606 {
329*2d9fd380Sjfb8856606 	int ret;
330*2d9fd380Sjfb8856606 
331*2d9fd380Sjfb8856606 	if (!obj)
332*2d9fd380Sjfb8856606 		return 0;
333*2d9fd380Sjfb8856606 	ret =  mlx5_glue->devx_obj_destroy(obj->obj);
334*2d9fd380Sjfb8856606 	mlx5_free(obj);
335*2d9fd380Sjfb8856606 	return ret;
336*2d9fd380Sjfb8856606 }
337*2d9fd380Sjfb8856606 
338*2d9fd380Sjfb8856606 /**
339*2d9fd380Sjfb8856606  * Query NIC vport context.
340*2d9fd380Sjfb8856606  * Fills minimal inline attribute.
341*2d9fd380Sjfb8856606  *
342*2d9fd380Sjfb8856606  * @param[in] ctx
343*2d9fd380Sjfb8856606  *   ibv contexts returned from mlx5dv_open_device.
344*2d9fd380Sjfb8856606  * @param[in] vport
345*2d9fd380Sjfb8856606  *   vport index
346*2d9fd380Sjfb8856606  * @param[out] attr
347*2d9fd380Sjfb8856606  *   Attributes device values.
348*2d9fd380Sjfb8856606  *
349*2d9fd380Sjfb8856606  * @return
350*2d9fd380Sjfb8856606  *   0 on success, a negative value otherwise.
351*2d9fd380Sjfb8856606  */
352*2d9fd380Sjfb8856606 static int
mlx5_devx_cmd_query_nic_vport_context(void * ctx,unsigned int vport,struct mlx5_hca_attr * attr)353*2d9fd380Sjfb8856606 mlx5_devx_cmd_query_nic_vport_context(void *ctx,
354*2d9fd380Sjfb8856606 				      unsigned int vport,
355*2d9fd380Sjfb8856606 				      struct mlx5_hca_attr *attr)
356*2d9fd380Sjfb8856606 {
357*2d9fd380Sjfb8856606 	uint32_t in[MLX5_ST_SZ_DW(query_nic_vport_context_in)] = {0};
358*2d9fd380Sjfb8856606 	uint32_t out[MLX5_ST_SZ_DW(query_nic_vport_context_out)] = {0};
359*2d9fd380Sjfb8856606 	void *vctx;
360*2d9fd380Sjfb8856606 	int status, syndrome, rc;
361*2d9fd380Sjfb8856606 
362*2d9fd380Sjfb8856606 	/* Query NIC vport context to determine inline mode. */
363*2d9fd380Sjfb8856606 	MLX5_SET(query_nic_vport_context_in, in, opcode,
364*2d9fd380Sjfb8856606 		 MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT);
365*2d9fd380Sjfb8856606 	MLX5_SET(query_nic_vport_context_in, in, vport_number, vport);
366*2d9fd380Sjfb8856606 	if (vport)
367*2d9fd380Sjfb8856606 		MLX5_SET(query_nic_vport_context_in, in, other_vport, 1);
368*2d9fd380Sjfb8856606 	rc = mlx5_glue->devx_general_cmd(ctx,
369*2d9fd380Sjfb8856606 					 in, sizeof(in),
370*2d9fd380Sjfb8856606 					 out, sizeof(out));
371*2d9fd380Sjfb8856606 	if (rc)
372*2d9fd380Sjfb8856606 		goto error;
373*2d9fd380Sjfb8856606 	status = MLX5_GET(query_nic_vport_context_out, out, status);
374*2d9fd380Sjfb8856606 	syndrome = MLX5_GET(query_nic_vport_context_out, out, syndrome);
375*2d9fd380Sjfb8856606 	if (status) {
376*2d9fd380Sjfb8856606 		DRV_LOG(DEBUG, "Failed to query NIC vport context, "
377*2d9fd380Sjfb8856606 			"status %x, syndrome = %x",
378*2d9fd380Sjfb8856606 			status, syndrome);
379*2d9fd380Sjfb8856606 		return -1;
380*2d9fd380Sjfb8856606 	}
381*2d9fd380Sjfb8856606 	vctx = MLX5_ADDR_OF(query_nic_vport_context_out, out,
382*2d9fd380Sjfb8856606 			    nic_vport_context);
383*2d9fd380Sjfb8856606 	attr->vport_inline_mode = MLX5_GET(nic_vport_context, vctx,
384*2d9fd380Sjfb8856606 					   min_wqe_inline_mode);
385*2d9fd380Sjfb8856606 	return 0;
386*2d9fd380Sjfb8856606 error:
387*2d9fd380Sjfb8856606 	rc = (rc > 0) ? -rc : rc;
388*2d9fd380Sjfb8856606 	return rc;
389*2d9fd380Sjfb8856606 }
390*2d9fd380Sjfb8856606 
391*2d9fd380Sjfb8856606 /**
392*2d9fd380Sjfb8856606  * Query NIC vDPA attributes.
393*2d9fd380Sjfb8856606  *
394*2d9fd380Sjfb8856606  * @param[in] ctx
395*2d9fd380Sjfb8856606  *   Context returned from mlx5 open_device() glue function.
396*2d9fd380Sjfb8856606  * @param[out] vdpa_attr
397*2d9fd380Sjfb8856606  *   vDPA Attributes structure to fill.
398*2d9fd380Sjfb8856606  */
399*2d9fd380Sjfb8856606 static void
mlx5_devx_cmd_query_hca_vdpa_attr(void * ctx,struct mlx5_hca_vdpa_attr * vdpa_attr)400*2d9fd380Sjfb8856606 mlx5_devx_cmd_query_hca_vdpa_attr(void *ctx,
401*2d9fd380Sjfb8856606 				  struct mlx5_hca_vdpa_attr *vdpa_attr)
402*2d9fd380Sjfb8856606 {
403*2d9fd380Sjfb8856606 	uint32_t in[MLX5_ST_SZ_DW(query_hca_cap_in)] = {0};
404*2d9fd380Sjfb8856606 	uint32_t out[MLX5_ST_SZ_DW(query_hca_cap_out)] = {0};
405*2d9fd380Sjfb8856606 	void *hcattr = MLX5_ADDR_OF(query_hca_cap_out, out, capability);
406*2d9fd380Sjfb8856606 	int status, syndrome, rc;
407*2d9fd380Sjfb8856606 
408*2d9fd380Sjfb8856606 	MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP);
409*2d9fd380Sjfb8856606 	MLX5_SET(query_hca_cap_in, in, op_mod,
410*2d9fd380Sjfb8856606 		 MLX5_GET_HCA_CAP_OP_MOD_VDPA_EMULATION |
411*2d9fd380Sjfb8856606 		 MLX5_HCA_CAP_OPMOD_GET_CUR);
412*2d9fd380Sjfb8856606 	rc = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
413*2d9fd380Sjfb8856606 	status = MLX5_GET(query_hca_cap_out, out, status);
414*2d9fd380Sjfb8856606 	syndrome = MLX5_GET(query_hca_cap_out, out, syndrome);
415*2d9fd380Sjfb8856606 	if (rc || status) {
416*2d9fd380Sjfb8856606 		RTE_LOG(DEBUG, PMD, "Failed to query devx VDPA capabilities,"
417*2d9fd380Sjfb8856606 			" status %x, syndrome = %x", status, syndrome);
418*2d9fd380Sjfb8856606 		vdpa_attr->valid = 0;
419*2d9fd380Sjfb8856606 	} else {
420*2d9fd380Sjfb8856606 		vdpa_attr->valid = 1;
421*2d9fd380Sjfb8856606 		vdpa_attr->desc_tunnel_offload_type =
422*2d9fd380Sjfb8856606 			MLX5_GET(virtio_emulation_cap, hcattr,
423*2d9fd380Sjfb8856606 				 desc_tunnel_offload_type);
424*2d9fd380Sjfb8856606 		vdpa_attr->eth_frame_offload_type =
425*2d9fd380Sjfb8856606 			MLX5_GET(virtio_emulation_cap, hcattr,
426*2d9fd380Sjfb8856606 				 eth_frame_offload_type);
427*2d9fd380Sjfb8856606 		vdpa_attr->virtio_version_1_0 =
428*2d9fd380Sjfb8856606 			MLX5_GET(virtio_emulation_cap, hcattr,
429*2d9fd380Sjfb8856606 				 virtio_version_1_0);
430*2d9fd380Sjfb8856606 		vdpa_attr->tso_ipv4 = MLX5_GET(virtio_emulation_cap, hcattr,
431*2d9fd380Sjfb8856606 					       tso_ipv4);
432*2d9fd380Sjfb8856606 		vdpa_attr->tso_ipv6 = MLX5_GET(virtio_emulation_cap, hcattr,
433*2d9fd380Sjfb8856606 					       tso_ipv6);
434*2d9fd380Sjfb8856606 		vdpa_attr->tx_csum = MLX5_GET(virtio_emulation_cap, hcattr,
435*2d9fd380Sjfb8856606 					      tx_csum);
436*2d9fd380Sjfb8856606 		vdpa_attr->rx_csum = MLX5_GET(virtio_emulation_cap, hcattr,
437*2d9fd380Sjfb8856606 					      rx_csum);
438*2d9fd380Sjfb8856606 		vdpa_attr->event_mode = MLX5_GET(virtio_emulation_cap, hcattr,
439*2d9fd380Sjfb8856606 						 event_mode);
440*2d9fd380Sjfb8856606 		vdpa_attr->virtio_queue_type =
441*2d9fd380Sjfb8856606 			MLX5_GET(virtio_emulation_cap, hcattr,
442*2d9fd380Sjfb8856606 				 virtio_queue_type);
443*2d9fd380Sjfb8856606 		vdpa_attr->log_doorbell_stride =
444*2d9fd380Sjfb8856606 			MLX5_GET(virtio_emulation_cap, hcattr,
445*2d9fd380Sjfb8856606 				 log_doorbell_stride);
446*2d9fd380Sjfb8856606 		vdpa_attr->log_doorbell_bar_size =
447*2d9fd380Sjfb8856606 			MLX5_GET(virtio_emulation_cap, hcattr,
448*2d9fd380Sjfb8856606 				 log_doorbell_bar_size);
449*2d9fd380Sjfb8856606 		vdpa_attr->doorbell_bar_offset =
450*2d9fd380Sjfb8856606 			MLX5_GET64(virtio_emulation_cap, hcattr,
451*2d9fd380Sjfb8856606 				   doorbell_bar_offset);
452*2d9fd380Sjfb8856606 		vdpa_attr->max_num_virtio_queues =
453*2d9fd380Sjfb8856606 			MLX5_GET(virtio_emulation_cap, hcattr,
454*2d9fd380Sjfb8856606 				 max_num_virtio_queues);
455*2d9fd380Sjfb8856606 		vdpa_attr->umems[0].a = MLX5_GET(virtio_emulation_cap, hcattr,
456*2d9fd380Sjfb8856606 						 umem_1_buffer_param_a);
457*2d9fd380Sjfb8856606 		vdpa_attr->umems[0].b = MLX5_GET(virtio_emulation_cap, hcattr,
458*2d9fd380Sjfb8856606 						 umem_1_buffer_param_b);
459*2d9fd380Sjfb8856606 		vdpa_attr->umems[1].a = MLX5_GET(virtio_emulation_cap, hcattr,
460*2d9fd380Sjfb8856606 						 umem_2_buffer_param_a);
461*2d9fd380Sjfb8856606 		vdpa_attr->umems[1].b = MLX5_GET(virtio_emulation_cap, hcattr,
462*2d9fd380Sjfb8856606 						 umem_2_buffer_param_b);
463*2d9fd380Sjfb8856606 		vdpa_attr->umems[2].a = MLX5_GET(virtio_emulation_cap, hcattr,
464*2d9fd380Sjfb8856606 						 umem_3_buffer_param_a);
465*2d9fd380Sjfb8856606 		vdpa_attr->umems[2].b = MLX5_GET(virtio_emulation_cap, hcattr,
466*2d9fd380Sjfb8856606 						 umem_3_buffer_param_b);
467*2d9fd380Sjfb8856606 	}
468*2d9fd380Sjfb8856606 }
469*2d9fd380Sjfb8856606 
470*2d9fd380Sjfb8856606 int
mlx5_devx_cmd_query_parse_samples(struct mlx5_devx_obj * flex_obj,uint32_t ids[],uint32_t num)471*2d9fd380Sjfb8856606 mlx5_devx_cmd_query_parse_samples(struct mlx5_devx_obj *flex_obj,
472*2d9fd380Sjfb8856606 				  uint32_t ids[], uint32_t num)
473*2d9fd380Sjfb8856606 {
474*2d9fd380Sjfb8856606 	uint32_t in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {0};
475*2d9fd380Sjfb8856606 	uint32_t out[MLX5_ST_SZ_DW(create_flex_parser_out)] = {0};
476*2d9fd380Sjfb8856606 	void *hdr = MLX5_ADDR_OF(create_flex_parser_out, in, hdr);
477*2d9fd380Sjfb8856606 	void *flex = MLX5_ADDR_OF(create_flex_parser_out, out, flex);
478*2d9fd380Sjfb8856606 	void *sample = MLX5_ADDR_OF(parse_graph_flex, flex, sample_table);
479*2d9fd380Sjfb8856606 	int ret;
480*2d9fd380Sjfb8856606 	uint32_t idx = 0;
481*2d9fd380Sjfb8856606 	uint32_t i;
482*2d9fd380Sjfb8856606 
483*2d9fd380Sjfb8856606 	if (num > MLX5_GRAPH_NODE_SAMPLE_NUM) {
484*2d9fd380Sjfb8856606 		rte_errno = EINVAL;
485*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Too many sample IDs to be fetched.");
486*2d9fd380Sjfb8856606 		return -rte_errno;
487*2d9fd380Sjfb8856606 	}
488*2d9fd380Sjfb8856606 	MLX5_SET(general_obj_in_cmd_hdr, hdr, opcode,
489*2d9fd380Sjfb8856606 		 MLX5_CMD_OP_QUERY_GENERAL_OBJECT);
490*2d9fd380Sjfb8856606 	MLX5_SET(general_obj_in_cmd_hdr, hdr, obj_type,
491*2d9fd380Sjfb8856606 		 MLX5_GENERAL_OBJ_TYPE_FLEX_PARSE_GRAPH);
492*2d9fd380Sjfb8856606 	MLX5_SET(general_obj_in_cmd_hdr, hdr, obj_id, flex_obj->id);
493*2d9fd380Sjfb8856606 	ret = mlx5_glue->devx_obj_query(flex_obj->obj, in, sizeof(in),
494*2d9fd380Sjfb8856606 					out, sizeof(out));
495*2d9fd380Sjfb8856606 	if (ret) {
496*2d9fd380Sjfb8856606 		rte_errno = ret;
497*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to query sample IDs with object %p.",
498*2d9fd380Sjfb8856606 			(void *)flex_obj);
499*2d9fd380Sjfb8856606 		return -rte_errno;
500*2d9fd380Sjfb8856606 	}
501*2d9fd380Sjfb8856606 	for (i = 0; i < MLX5_GRAPH_NODE_SAMPLE_NUM; i++) {
502*2d9fd380Sjfb8856606 		void *s_off = (void *)((char *)sample + i *
503*2d9fd380Sjfb8856606 			      MLX5_ST_SZ_BYTES(parse_graph_flow_match_sample));
504*2d9fd380Sjfb8856606 		uint32_t en;
505*2d9fd380Sjfb8856606 
506*2d9fd380Sjfb8856606 		en = MLX5_GET(parse_graph_flow_match_sample, s_off,
507*2d9fd380Sjfb8856606 			      flow_match_sample_en);
508*2d9fd380Sjfb8856606 		if (!en)
509*2d9fd380Sjfb8856606 			continue;
510*2d9fd380Sjfb8856606 		ids[idx++] = MLX5_GET(parse_graph_flow_match_sample, s_off,
511*2d9fd380Sjfb8856606 				  flow_match_sample_field_id);
512*2d9fd380Sjfb8856606 	}
513*2d9fd380Sjfb8856606 	if (num != idx) {
514*2d9fd380Sjfb8856606 		rte_errno = EINVAL;
515*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Number of sample IDs are not as expected.");
516*2d9fd380Sjfb8856606 		return -rte_errno;
517*2d9fd380Sjfb8856606 	}
518*2d9fd380Sjfb8856606 	return ret;
519*2d9fd380Sjfb8856606 }
520*2d9fd380Sjfb8856606 
521*2d9fd380Sjfb8856606 
522*2d9fd380Sjfb8856606 struct mlx5_devx_obj *
mlx5_devx_cmd_create_flex_parser(void * ctx,struct mlx5_devx_graph_node_attr * data)523*2d9fd380Sjfb8856606 mlx5_devx_cmd_create_flex_parser(void *ctx,
524*2d9fd380Sjfb8856606 			      struct mlx5_devx_graph_node_attr *data)
525*2d9fd380Sjfb8856606 {
526*2d9fd380Sjfb8856606 	uint32_t in[MLX5_ST_SZ_DW(create_flex_parser_in)] = {0};
527*2d9fd380Sjfb8856606 	uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
528*2d9fd380Sjfb8856606 	void *hdr = MLX5_ADDR_OF(create_flex_parser_in, in, hdr);
529*2d9fd380Sjfb8856606 	void *flex = MLX5_ADDR_OF(create_flex_parser_in, in, flex);
530*2d9fd380Sjfb8856606 	void *sample = MLX5_ADDR_OF(parse_graph_flex, flex, sample_table);
531*2d9fd380Sjfb8856606 	void *in_arc = MLX5_ADDR_OF(parse_graph_flex, flex, input_arc);
532*2d9fd380Sjfb8856606 	void *out_arc = MLX5_ADDR_OF(parse_graph_flex, flex, output_arc);
533*2d9fd380Sjfb8856606 	struct mlx5_devx_obj *parse_flex_obj = mlx5_malloc
534*2d9fd380Sjfb8856606 		     (MLX5_MEM_ZERO, sizeof(*parse_flex_obj), 0, SOCKET_ID_ANY);
535*2d9fd380Sjfb8856606 	uint32_t i;
536*2d9fd380Sjfb8856606 
537*2d9fd380Sjfb8856606 	if (!parse_flex_obj) {
538*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to allocate flex parser data.");
539*2d9fd380Sjfb8856606 		rte_errno = ENOMEM;
540*2d9fd380Sjfb8856606 		return NULL;
541*2d9fd380Sjfb8856606 	}
542*2d9fd380Sjfb8856606 	MLX5_SET(general_obj_in_cmd_hdr, hdr, opcode,
543*2d9fd380Sjfb8856606 		 MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
544*2d9fd380Sjfb8856606 	MLX5_SET(general_obj_in_cmd_hdr, hdr, obj_type,
545*2d9fd380Sjfb8856606 		 MLX5_GENERAL_OBJ_TYPE_FLEX_PARSE_GRAPH);
546*2d9fd380Sjfb8856606 	MLX5_SET(parse_graph_flex, flex, header_length_mode,
547*2d9fd380Sjfb8856606 		 data->header_length_mode);
548*2d9fd380Sjfb8856606 	MLX5_SET(parse_graph_flex, flex, header_length_base_value,
549*2d9fd380Sjfb8856606 		 data->header_length_base_value);
550*2d9fd380Sjfb8856606 	MLX5_SET(parse_graph_flex, flex, header_length_field_offset,
551*2d9fd380Sjfb8856606 		 data->header_length_field_offset);
552*2d9fd380Sjfb8856606 	MLX5_SET(parse_graph_flex, flex, header_length_field_shift,
553*2d9fd380Sjfb8856606 		 data->header_length_field_shift);
554*2d9fd380Sjfb8856606 	MLX5_SET(parse_graph_flex, flex, header_length_field_mask,
555*2d9fd380Sjfb8856606 		 data->header_length_field_mask);
556*2d9fd380Sjfb8856606 	for (i = 0; i < MLX5_GRAPH_NODE_SAMPLE_NUM; i++) {
557*2d9fd380Sjfb8856606 		struct mlx5_devx_match_sample_attr *s = &data->sample[i];
558*2d9fd380Sjfb8856606 		void *s_off = (void *)((char *)sample + i *
559*2d9fd380Sjfb8856606 			      MLX5_ST_SZ_BYTES(parse_graph_flow_match_sample));
560*2d9fd380Sjfb8856606 
561*2d9fd380Sjfb8856606 		if (!s->flow_match_sample_en)
562*2d9fd380Sjfb8856606 			continue;
563*2d9fd380Sjfb8856606 		MLX5_SET(parse_graph_flow_match_sample, s_off,
564*2d9fd380Sjfb8856606 			 flow_match_sample_en, !!s->flow_match_sample_en);
565*2d9fd380Sjfb8856606 		MLX5_SET(parse_graph_flow_match_sample, s_off,
566*2d9fd380Sjfb8856606 			 flow_match_sample_field_offset,
567*2d9fd380Sjfb8856606 			 s->flow_match_sample_field_offset);
568*2d9fd380Sjfb8856606 		MLX5_SET(parse_graph_flow_match_sample, s_off,
569*2d9fd380Sjfb8856606 			 flow_match_sample_offset_mode,
570*2d9fd380Sjfb8856606 			 s->flow_match_sample_offset_mode);
571*2d9fd380Sjfb8856606 		MLX5_SET(parse_graph_flow_match_sample, s_off,
572*2d9fd380Sjfb8856606 			 flow_match_sample_field_offset_mask,
573*2d9fd380Sjfb8856606 			 s->flow_match_sample_field_offset_mask);
574*2d9fd380Sjfb8856606 		MLX5_SET(parse_graph_flow_match_sample, s_off,
575*2d9fd380Sjfb8856606 			 flow_match_sample_field_offset_shift,
576*2d9fd380Sjfb8856606 			 s->flow_match_sample_field_offset_shift);
577*2d9fd380Sjfb8856606 		MLX5_SET(parse_graph_flow_match_sample, s_off,
578*2d9fd380Sjfb8856606 			 flow_match_sample_field_base_offset,
579*2d9fd380Sjfb8856606 			 s->flow_match_sample_field_base_offset);
580*2d9fd380Sjfb8856606 		MLX5_SET(parse_graph_flow_match_sample, s_off,
581*2d9fd380Sjfb8856606 			 flow_match_sample_tunnel_mode,
582*2d9fd380Sjfb8856606 			 s->flow_match_sample_tunnel_mode);
583*2d9fd380Sjfb8856606 	}
584*2d9fd380Sjfb8856606 	for (i = 0; i < MLX5_GRAPH_NODE_ARC_NUM; i++) {
585*2d9fd380Sjfb8856606 		struct mlx5_devx_graph_arc_attr *ia = &data->in[i];
586*2d9fd380Sjfb8856606 		struct mlx5_devx_graph_arc_attr *oa = &data->out[i];
587*2d9fd380Sjfb8856606 		void *in_off = (void *)((char *)in_arc + i *
588*2d9fd380Sjfb8856606 			      MLX5_ST_SZ_BYTES(parse_graph_arc));
589*2d9fd380Sjfb8856606 		void *out_off = (void *)((char *)out_arc + i *
590*2d9fd380Sjfb8856606 			      MLX5_ST_SZ_BYTES(parse_graph_arc));
591*2d9fd380Sjfb8856606 
592*2d9fd380Sjfb8856606 		if (ia->arc_parse_graph_node != 0) {
593*2d9fd380Sjfb8856606 			MLX5_SET(parse_graph_arc, in_off,
594*2d9fd380Sjfb8856606 				 compare_condition_value,
595*2d9fd380Sjfb8856606 				 ia->compare_condition_value);
596*2d9fd380Sjfb8856606 			MLX5_SET(parse_graph_arc, in_off, start_inner_tunnel,
597*2d9fd380Sjfb8856606 				 ia->start_inner_tunnel);
598*2d9fd380Sjfb8856606 			MLX5_SET(parse_graph_arc, in_off, arc_parse_graph_node,
599*2d9fd380Sjfb8856606 				 ia->arc_parse_graph_node);
600*2d9fd380Sjfb8856606 			MLX5_SET(parse_graph_arc, in_off,
601*2d9fd380Sjfb8856606 				 parse_graph_node_handle,
602*2d9fd380Sjfb8856606 				 ia->parse_graph_node_handle);
603*2d9fd380Sjfb8856606 		}
604*2d9fd380Sjfb8856606 		if (oa->arc_parse_graph_node != 0) {
605*2d9fd380Sjfb8856606 			MLX5_SET(parse_graph_arc, out_off,
606*2d9fd380Sjfb8856606 				 compare_condition_value,
607*2d9fd380Sjfb8856606 				 oa->compare_condition_value);
608*2d9fd380Sjfb8856606 			MLX5_SET(parse_graph_arc, out_off, start_inner_tunnel,
609*2d9fd380Sjfb8856606 				 oa->start_inner_tunnel);
610*2d9fd380Sjfb8856606 			MLX5_SET(parse_graph_arc, out_off, arc_parse_graph_node,
611*2d9fd380Sjfb8856606 				 oa->arc_parse_graph_node);
612*2d9fd380Sjfb8856606 			MLX5_SET(parse_graph_arc, out_off,
613*2d9fd380Sjfb8856606 				 parse_graph_node_handle,
614*2d9fd380Sjfb8856606 				 oa->parse_graph_node_handle);
615*2d9fd380Sjfb8856606 		}
616*2d9fd380Sjfb8856606 	}
617*2d9fd380Sjfb8856606 	parse_flex_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in),
618*2d9fd380Sjfb8856606 							 out, sizeof(out));
619*2d9fd380Sjfb8856606 	if (!parse_flex_obj->obj) {
620*2d9fd380Sjfb8856606 		rte_errno = errno;
621*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to create FLEX PARSE GRAPH object "
622*2d9fd380Sjfb8856606 			"by using DevX.");
623*2d9fd380Sjfb8856606 		mlx5_free(parse_flex_obj);
624*2d9fd380Sjfb8856606 		return NULL;
625*2d9fd380Sjfb8856606 	}
626*2d9fd380Sjfb8856606 	parse_flex_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
627*2d9fd380Sjfb8856606 	return parse_flex_obj;
628*2d9fd380Sjfb8856606 }
629*2d9fd380Sjfb8856606 
630*2d9fd380Sjfb8856606 /**
631*2d9fd380Sjfb8856606  * Query HCA attributes.
632*2d9fd380Sjfb8856606  * Using those attributes we can check on run time if the device
633*2d9fd380Sjfb8856606  * is having the required capabilities.
634*2d9fd380Sjfb8856606  *
635*2d9fd380Sjfb8856606  * @param[in] ctx
636*2d9fd380Sjfb8856606  *   Context returned from mlx5 open_device() glue function.
637*2d9fd380Sjfb8856606  * @param[out] attr
638*2d9fd380Sjfb8856606  *   Attributes device values.
639*2d9fd380Sjfb8856606  *
640*2d9fd380Sjfb8856606  * @return
641*2d9fd380Sjfb8856606  *   0 on success, a negative value otherwise.
642*2d9fd380Sjfb8856606  */
643*2d9fd380Sjfb8856606 int
mlx5_devx_cmd_query_hca_attr(void * ctx,struct mlx5_hca_attr * attr)644*2d9fd380Sjfb8856606 mlx5_devx_cmd_query_hca_attr(void *ctx,
645*2d9fd380Sjfb8856606 			     struct mlx5_hca_attr *attr)
646*2d9fd380Sjfb8856606 {
647*2d9fd380Sjfb8856606 	uint32_t in[MLX5_ST_SZ_DW(query_hca_cap_in)] = {0};
648*2d9fd380Sjfb8856606 	uint32_t out[MLX5_ST_SZ_DW(query_hca_cap_out)] = {0};
649*2d9fd380Sjfb8856606 	void *hcattr;
650*2d9fd380Sjfb8856606 	int status, syndrome, rc, i;
651*2d9fd380Sjfb8856606 
652*2d9fd380Sjfb8856606 	MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP);
653*2d9fd380Sjfb8856606 	MLX5_SET(query_hca_cap_in, in, op_mod,
654*2d9fd380Sjfb8856606 		 MLX5_GET_HCA_CAP_OP_MOD_GENERAL_DEVICE |
655*2d9fd380Sjfb8856606 		 MLX5_HCA_CAP_OPMOD_GET_CUR);
656*2d9fd380Sjfb8856606 
657*2d9fd380Sjfb8856606 	rc = mlx5_glue->devx_general_cmd(ctx,
658*2d9fd380Sjfb8856606 					 in, sizeof(in), out, sizeof(out));
659*2d9fd380Sjfb8856606 	if (rc)
660*2d9fd380Sjfb8856606 		goto error;
661*2d9fd380Sjfb8856606 	status = MLX5_GET(query_hca_cap_out, out, status);
662*2d9fd380Sjfb8856606 	syndrome = MLX5_GET(query_hca_cap_out, out, syndrome);
663*2d9fd380Sjfb8856606 	if (status) {
664*2d9fd380Sjfb8856606 		DRV_LOG(DEBUG, "Failed to query devx HCA capabilities, "
665*2d9fd380Sjfb8856606 			"status %x, syndrome = %x",
666*2d9fd380Sjfb8856606 			status, syndrome);
667*2d9fd380Sjfb8856606 		return -1;
668*2d9fd380Sjfb8856606 	}
669*2d9fd380Sjfb8856606 	hcattr = MLX5_ADDR_OF(query_hca_cap_out, out, capability);
670*2d9fd380Sjfb8856606 	attr->flow_counter_bulk_alloc_bitmap =
671*2d9fd380Sjfb8856606 			MLX5_GET(cmd_hca_cap, hcattr, flow_counter_bulk_alloc);
672*2d9fd380Sjfb8856606 	attr->flow_counters_dump = MLX5_GET(cmd_hca_cap, hcattr,
673*2d9fd380Sjfb8856606 					    flow_counters_dump);
674*2d9fd380Sjfb8856606 	attr->log_max_rqt_size = MLX5_GET(cmd_hca_cap, hcattr,
675*2d9fd380Sjfb8856606 					  log_max_rqt_size);
676*2d9fd380Sjfb8856606 	attr->eswitch_manager = MLX5_GET(cmd_hca_cap, hcattr, eswitch_manager);
677*2d9fd380Sjfb8856606 	attr->hairpin = MLX5_GET(cmd_hca_cap, hcattr, hairpin);
678*2d9fd380Sjfb8856606 	attr->log_max_hairpin_queues = MLX5_GET(cmd_hca_cap, hcattr,
679*2d9fd380Sjfb8856606 						log_max_hairpin_queues);
680*2d9fd380Sjfb8856606 	attr->log_max_hairpin_wq_data_sz = MLX5_GET(cmd_hca_cap, hcattr,
681*2d9fd380Sjfb8856606 						    log_max_hairpin_wq_data_sz);
682*2d9fd380Sjfb8856606 	attr->log_max_hairpin_num_packets = MLX5_GET
683*2d9fd380Sjfb8856606 		(cmd_hca_cap, hcattr, log_min_hairpin_wq_data_sz);
684*2d9fd380Sjfb8856606 	attr->vhca_id = MLX5_GET(cmd_hca_cap, hcattr, vhca_id);
685*2d9fd380Sjfb8856606 	attr->relaxed_ordering_write = MLX5_GET(cmd_hca_cap, hcattr,
686*2d9fd380Sjfb8856606 			relaxed_ordering_write);
687*2d9fd380Sjfb8856606 	attr->relaxed_ordering_read = MLX5_GET(cmd_hca_cap, hcattr,
688*2d9fd380Sjfb8856606 			relaxed_ordering_read);
689*2d9fd380Sjfb8856606 	attr->access_register_user = MLX5_GET(cmd_hca_cap, hcattr,
690*2d9fd380Sjfb8856606 			access_register_user);
691*2d9fd380Sjfb8856606 	attr->eth_net_offloads = MLX5_GET(cmd_hca_cap, hcattr,
692*2d9fd380Sjfb8856606 					  eth_net_offloads);
693*2d9fd380Sjfb8856606 	attr->eth_virt = MLX5_GET(cmd_hca_cap, hcattr, eth_virt);
694*2d9fd380Sjfb8856606 	attr->flex_parser_protocols = MLX5_GET(cmd_hca_cap, hcattr,
695*2d9fd380Sjfb8856606 					       flex_parser_protocols);
696*2d9fd380Sjfb8856606 	attr->qos.sup = MLX5_GET(cmd_hca_cap, hcattr, qos);
697*2d9fd380Sjfb8856606 	attr->vdpa.valid = !!(MLX5_GET64(cmd_hca_cap, hcattr,
698*2d9fd380Sjfb8856606 					 general_obj_types) &
699*2d9fd380Sjfb8856606 			      MLX5_GENERAL_OBJ_TYPES_CAP_VIRTQ_NET_Q);
700*2d9fd380Sjfb8856606 	attr->vdpa.queue_counters_valid = !!(MLX5_GET64(cmd_hca_cap, hcattr,
701*2d9fd380Sjfb8856606 							general_obj_types) &
702*2d9fd380Sjfb8856606 				  MLX5_GENERAL_OBJ_TYPES_CAP_VIRTIO_Q_COUNTERS);
703*2d9fd380Sjfb8856606 	attr->parse_graph_flex_node = !!(MLX5_GET64(cmd_hca_cap, hcattr,
704*2d9fd380Sjfb8856606 					 general_obj_types) &
705*2d9fd380Sjfb8856606 			      MLX5_GENERAL_OBJ_TYPES_CAP_PARSE_GRAPH_FLEX_NODE);
706*2d9fd380Sjfb8856606 	attr->wqe_index_ignore = MLX5_GET(cmd_hca_cap, hcattr,
707*2d9fd380Sjfb8856606 					  wqe_index_ignore_cap);
708*2d9fd380Sjfb8856606 	attr->cross_channel = MLX5_GET(cmd_hca_cap, hcattr, cd);
709*2d9fd380Sjfb8856606 	attr->non_wire_sq = MLX5_GET(cmd_hca_cap, hcattr, non_wire_sq);
710*2d9fd380Sjfb8856606 	attr->log_max_static_sq_wq = MLX5_GET(cmd_hca_cap, hcattr,
711*2d9fd380Sjfb8856606 					      log_max_static_sq_wq);
712*2d9fd380Sjfb8856606 	attr->num_lag_ports = MLX5_GET(cmd_hca_cap, hcattr, num_lag_ports);
713*2d9fd380Sjfb8856606 	attr->dev_freq_khz = MLX5_GET(cmd_hca_cap, hcattr,
714*2d9fd380Sjfb8856606 				      device_frequency_khz);
715*2d9fd380Sjfb8856606 	attr->scatter_fcs_w_decap_disable =
716*2d9fd380Sjfb8856606 		MLX5_GET(cmd_hca_cap, hcattr, scatter_fcs_w_decap_disable);
717*2d9fd380Sjfb8856606 	attr->regex = MLX5_GET(cmd_hca_cap, hcattr, regexp);
718*2d9fd380Sjfb8856606 	attr->regexp_num_of_engines = MLX5_GET(cmd_hca_cap, hcattr,
719*2d9fd380Sjfb8856606 					       regexp_num_of_engines);
720*2d9fd380Sjfb8856606 	attr->flow_hit_aso = !!(MLX5_GET64(cmd_hca_cap, hcattr,
721*2d9fd380Sjfb8856606 					   general_obj_types) &
722*2d9fd380Sjfb8856606 				MLX5_GENERAL_OBJ_TYPES_CAP_FLOW_HIT_ASO);
723*2d9fd380Sjfb8856606 	if (attr->qos.sup) {
724*2d9fd380Sjfb8856606 		MLX5_SET(query_hca_cap_in, in, op_mod,
725*2d9fd380Sjfb8856606 			 MLX5_GET_HCA_CAP_OP_MOD_QOS_CAP |
726*2d9fd380Sjfb8856606 			 MLX5_HCA_CAP_OPMOD_GET_CUR);
727*2d9fd380Sjfb8856606 		rc = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in),
728*2d9fd380Sjfb8856606 						 out, sizeof(out));
729*2d9fd380Sjfb8856606 		if (rc)
730*2d9fd380Sjfb8856606 			goto error;
731*2d9fd380Sjfb8856606 		if (status) {
732*2d9fd380Sjfb8856606 			DRV_LOG(DEBUG, "Failed to query devx QOS capabilities,"
733*2d9fd380Sjfb8856606 				" status %x, syndrome = %x",
734*2d9fd380Sjfb8856606 				status, syndrome);
735*2d9fd380Sjfb8856606 			return -1;
736*2d9fd380Sjfb8856606 		}
737*2d9fd380Sjfb8856606 		hcattr = MLX5_ADDR_OF(query_hca_cap_out, out, capability);
738*2d9fd380Sjfb8856606 		attr->qos.srtcm_sup =
739*2d9fd380Sjfb8856606 				MLX5_GET(qos_cap, hcattr, flow_meter_srtcm);
740*2d9fd380Sjfb8856606 		attr->qos.log_max_flow_meter =
741*2d9fd380Sjfb8856606 				MLX5_GET(qos_cap, hcattr, log_max_flow_meter);
742*2d9fd380Sjfb8856606 		attr->qos.flow_meter_reg_c_ids =
743*2d9fd380Sjfb8856606 				MLX5_GET(qos_cap, hcattr, flow_meter_reg_id);
744*2d9fd380Sjfb8856606 		attr->qos.flow_meter_reg_share =
745*2d9fd380Sjfb8856606 				MLX5_GET(qos_cap, hcattr, flow_meter_reg_share);
746*2d9fd380Sjfb8856606 		attr->qos.packet_pacing =
747*2d9fd380Sjfb8856606 				MLX5_GET(qos_cap, hcattr, packet_pacing);
748*2d9fd380Sjfb8856606 		attr->qos.wqe_rate_pp =
749*2d9fd380Sjfb8856606 				MLX5_GET(qos_cap, hcattr, wqe_rate_pp);
750*2d9fd380Sjfb8856606 	}
751*2d9fd380Sjfb8856606 	if (attr->vdpa.valid)
752*2d9fd380Sjfb8856606 		mlx5_devx_cmd_query_hca_vdpa_attr(ctx, &attr->vdpa);
753*2d9fd380Sjfb8856606 	if (!attr->eth_net_offloads)
754*2d9fd380Sjfb8856606 		return 0;
755*2d9fd380Sjfb8856606 
756*2d9fd380Sjfb8856606 	/* Query Flow Sampler Capability From FLow Table Properties Layout. */
757*2d9fd380Sjfb8856606 	memset(in, 0, sizeof(in));
758*2d9fd380Sjfb8856606 	memset(out, 0, sizeof(out));
759*2d9fd380Sjfb8856606 	MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP);
760*2d9fd380Sjfb8856606 	MLX5_SET(query_hca_cap_in, in, op_mod,
761*2d9fd380Sjfb8856606 		 MLX5_GET_HCA_CAP_OP_MOD_NIC_FLOW_TABLE |
762*2d9fd380Sjfb8856606 		 MLX5_HCA_CAP_OPMOD_GET_CUR);
763*2d9fd380Sjfb8856606 
764*2d9fd380Sjfb8856606 	rc = mlx5_glue->devx_general_cmd(ctx,
765*2d9fd380Sjfb8856606 					 in, sizeof(in),
766*2d9fd380Sjfb8856606 					 out, sizeof(out));
767*2d9fd380Sjfb8856606 	if (rc)
768*2d9fd380Sjfb8856606 		goto error;
769*2d9fd380Sjfb8856606 	status = MLX5_GET(query_hca_cap_out, out, status);
770*2d9fd380Sjfb8856606 	syndrome = MLX5_GET(query_hca_cap_out, out, syndrome);
771*2d9fd380Sjfb8856606 	if (status) {
772*2d9fd380Sjfb8856606 		DRV_LOG(DEBUG, "Failed to query devx HCA capabilities, "
773*2d9fd380Sjfb8856606 			"status %x, syndrome = %x",
774*2d9fd380Sjfb8856606 			status, syndrome);
775*2d9fd380Sjfb8856606 		attr->log_max_ft_sampler_num = 0;
776*2d9fd380Sjfb8856606 		return -1;
777*2d9fd380Sjfb8856606 	}
778*2d9fd380Sjfb8856606 	hcattr = MLX5_ADDR_OF(query_hca_cap_out, out, capability);
779*2d9fd380Sjfb8856606 	attr->log_max_ft_sampler_num =
780*2d9fd380Sjfb8856606 			MLX5_GET(flow_table_nic_cap,
781*2d9fd380Sjfb8856606 			hcattr, flow_table_properties.log_max_ft_sampler_num);
782*2d9fd380Sjfb8856606 
783*2d9fd380Sjfb8856606 	/* Query HCA offloads for Ethernet protocol. */
784*2d9fd380Sjfb8856606 	memset(in, 0, sizeof(in));
785*2d9fd380Sjfb8856606 	memset(out, 0, sizeof(out));
786*2d9fd380Sjfb8856606 	MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP);
787*2d9fd380Sjfb8856606 	MLX5_SET(query_hca_cap_in, in, op_mod,
788*2d9fd380Sjfb8856606 		 MLX5_GET_HCA_CAP_OP_MOD_ETHERNET_OFFLOAD_CAPS |
789*2d9fd380Sjfb8856606 		 MLX5_HCA_CAP_OPMOD_GET_CUR);
790*2d9fd380Sjfb8856606 
791*2d9fd380Sjfb8856606 	rc = mlx5_glue->devx_general_cmd(ctx,
792*2d9fd380Sjfb8856606 					 in, sizeof(in),
793*2d9fd380Sjfb8856606 					 out, sizeof(out));
794*2d9fd380Sjfb8856606 	if (rc) {
795*2d9fd380Sjfb8856606 		attr->eth_net_offloads = 0;
796*2d9fd380Sjfb8856606 		goto error;
797*2d9fd380Sjfb8856606 	}
798*2d9fd380Sjfb8856606 	status = MLX5_GET(query_hca_cap_out, out, status);
799*2d9fd380Sjfb8856606 	syndrome = MLX5_GET(query_hca_cap_out, out, syndrome);
800*2d9fd380Sjfb8856606 	if (status) {
801*2d9fd380Sjfb8856606 		DRV_LOG(DEBUG, "Failed to query devx HCA capabilities, "
802*2d9fd380Sjfb8856606 			"status %x, syndrome = %x",
803*2d9fd380Sjfb8856606 			status, syndrome);
804*2d9fd380Sjfb8856606 		attr->eth_net_offloads = 0;
805*2d9fd380Sjfb8856606 		return -1;
806*2d9fd380Sjfb8856606 	}
807*2d9fd380Sjfb8856606 	hcattr = MLX5_ADDR_OF(query_hca_cap_out, out, capability);
808*2d9fd380Sjfb8856606 	attr->wqe_vlan_insert = MLX5_GET(per_protocol_networking_offload_caps,
809*2d9fd380Sjfb8856606 					 hcattr, wqe_vlan_insert);
810*2d9fd380Sjfb8856606 	attr->lro_cap = MLX5_GET(per_protocol_networking_offload_caps, hcattr,
811*2d9fd380Sjfb8856606 				 lro_cap);
812*2d9fd380Sjfb8856606 	attr->tunnel_lro_gre = MLX5_GET(per_protocol_networking_offload_caps,
813*2d9fd380Sjfb8856606 					hcattr, tunnel_lro_gre);
814*2d9fd380Sjfb8856606 	attr->tunnel_lro_vxlan = MLX5_GET(per_protocol_networking_offload_caps,
815*2d9fd380Sjfb8856606 					  hcattr, tunnel_lro_vxlan);
816*2d9fd380Sjfb8856606 	attr->lro_max_msg_sz_mode = MLX5_GET
817*2d9fd380Sjfb8856606 					(per_protocol_networking_offload_caps,
818*2d9fd380Sjfb8856606 					 hcattr, lro_max_msg_sz_mode);
819*2d9fd380Sjfb8856606 	for (i = 0 ; i < MLX5_LRO_NUM_SUPP_PERIODS ; i++) {
820*2d9fd380Sjfb8856606 		attr->lro_timer_supported_periods[i] =
821*2d9fd380Sjfb8856606 			MLX5_GET(per_protocol_networking_offload_caps, hcattr,
822*2d9fd380Sjfb8856606 				 lro_timer_supported_periods[i]);
823*2d9fd380Sjfb8856606 	}
824*2d9fd380Sjfb8856606 	attr->lro_min_mss_size = MLX5_GET(per_protocol_networking_offload_caps,
825*2d9fd380Sjfb8856606 					  hcattr, lro_min_mss_size);
826*2d9fd380Sjfb8856606 	attr->tunnel_stateless_geneve_rx =
827*2d9fd380Sjfb8856606 			    MLX5_GET(per_protocol_networking_offload_caps,
828*2d9fd380Sjfb8856606 				     hcattr, tunnel_stateless_geneve_rx);
829*2d9fd380Sjfb8856606 	attr->geneve_max_opt_len =
830*2d9fd380Sjfb8856606 		    MLX5_GET(per_protocol_networking_offload_caps,
831*2d9fd380Sjfb8856606 			     hcattr, max_geneve_opt_len);
832*2d9fd380Sjfb8856606 	attr->wqe_inline_mode = MLX5_GET(per_protocol_networking_offload_caps,
833*2d9fd380Sjfb8856606 					 hcattr, wqe_inline_mode);
834*2d9fd380Sjfb8856606 	attr->tunnel_stateless_gtp = MLX5_GET
835*2d9fd380Sjfb8856606 					(per_protocol_networking_offload_caps,
836*2d9fd380Sjfb8856606 					 hcattr, tunnel_stateless_gtp);
837*2d9fd380Sjfb8856606 	if (attr->wqe_inline_mode != MLX5_CAP_INLINE_MODE_VPORT_CONTEXT)
838*2d9fd380Sjfb8856606 		return 0;
839*2d9fd380Sjfb8856606 	if (attr->eth_virt) {
840*2d9fd380Sjfb8856606 		rc = mlx5_devx_cmd_query_nic_vport_context(ctx, 0, attr);
841*2d9fd380Sjfb8856606 		if (rc) {
842*2d9fd380Sjfb8856606 			attr->eth_virt = 0;
843*2d9fd380Sjfb8856606 			goto error;
844*2d9fd380Sjfb8856606 		}
845*2d9fd380Sjfb8856606 	}
846*2d9fd380Sjfb8856606 	return 0;
847*2d9fd380Sjfb8856606 error:
848*2d9fd380Sjfb8856606 	rc = (rc > 0) ? -rc : rc;
849*2d9fd380Sjfb8856606 	return rc;
850*2d9fd380Sjfb8856606 }
851*2d9fd380Sjfb8856606 
852*2d9fd380Sjfb8856606 /**
853*2d9fd380Sjfb8856606  * Query TIS transport domain from QP verbs object using DevX API.
854*2d9fd380Sjfb8856606  *
855*2d9fd380Sjfb8856606  * @param[in] qp
856*2d9fd380Sjfb8856606  *   Pointer to verbs QP returned by ibv_create_qp .
857*2d9fd380Sjfb8856606  * @param[in] tis_num
858*2d9fd380Sjfb8856606  *   TIS number of TIS to query.
859*2d9fd380Sjfb8856606  * @param[out] tis_td
860*2d9fd380Sjfb8856606  *   Pointer to TIS transport domain variable, to be set by the routine.
861*2d9fd380Sjfb8856606  *
862*2d9fd380Sjfb8856606  * @return
863*2d9fd380Sjfb8856606  *   0 on success, a negative value otherwise.
864*2d9fd380Sjfb8856606  */
865*2d9fd380Sjfb8856606 int
mlx5_devx_cmd_qp_query_tis_td(void * qp,uint32_t tis_num,uint32_t * tis_td)866*2d9fd380Sjfb8856606 mlx5_devx_cmd_qp_query_tis_td(void *qp, uint32_t tis_num,
867*2d9fd380Sjfb8856606 			      uint32_t *tis_td)
868*2d9fd380Sjfb8856606 {
869*2d9fd380Sjfb8856606 #ifdef HAVE_IBV_FLOW_DV_SUPPORT
870*2d9fd380Sjfb8856606 	uint32_t in[MLX5_ST_SZ_DW(query_tis_in)] = {0};
871*2d9fd380Sjfb8856606 	uint32_t out[MLX5_ST_SZ_DW(query_tis_out)] = {0};
872*2d9fd380Sjfb8856606 	int rc;
873*2d9fd380Sjfb8856606 	void *tis_ctx;
874*2d9fd380Sjfb8856606 
875*2d9fd380Sjfb8856606 	MLX5_SET(query_tis_in, in, opcode, MLX5_CMD_OP_QUERY_TIS);
876*2d9fd380Sjfb8856606 	MLX5_SET(query_tis_in, in, tisn, tis_num);
877*2d9fd380Sjfb8856606 	rc = mlx5_glue->devx_qp_query(qp, in, sizeof(in), out, sizeof(out));
878*2d9fd380Sjfb8856606 	if (rc) {
879*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to query QP using DevX");
880*2d9fd380Sjfb8856606 		return -rc;
881*2d9fd380Sjfb8856606 	};
882*2d9fd380Sjfb8856606 	tis_ctx = MLX5_ADDR_OF(query_tis_out, out, tis_context);
883*2d9fd380Sjfb8856606 	*tis_td = MLX5_GET(tisc, tis_ctx, transport_domain);
884*2d9fd380Sjfb8856606 	return 0;
885*2d9fd380Sjfb8856606 #else
886*2d9fd380Sjfb8856606 	(void)qp;
887*2d9fd380Sjfb8856606 	(void)tis_num;
888*2d9fd380Sjfb8856606 	(void)tis_td;
889*2d9fd380Sjfb8856606 	return -ENOTSUP;
890*2d9fd380Sjfb8856606 #endif
891*2d9fd380Sjfb8856606 }
892*2d9fd380Sjfb8856606 
893*2d9fd380Sjfb8856606 /**
894*2d9fd380Sjfb8856606  * Fill WQ data for DevX API command.
895*2d9fd380Sjfb8856606  * Utility function for use when creating DevX objects containing a WQ.
896*2d9fd380Sjfb8856606  *
897*2d9fd380Sjfb8856606  * @param[in] wq_ctx
898*2d9fd380Sjfb8856606  *   Pointer to WQ context to fill with data.
899*2d9fd380Sjfb8856606  * @param [in] wq_attr
900*2d9fd380Sjfb8856606  *   Pointer to WQ attributes structure to fill in WQ context.
901*2d9fd380Sjfb8856606  */
902*2d9fd380Sjfb8856606 static void
devx_cmd_fill_wq_data(void * wq_ctx,struct mlx5_devx_wq_attr * wq_attr)903*2d9fd380Sjfb8856606 devx_cmd_fill_wq_data(void *wq_ctx, struct mlx5_devx_wq_attr *wq_attr)
904*2d9fd380Sjfb8856606 {
905*2d9fd380Sjfb8856606 	MLX5_SET(wq, wq_ctx, wq_type, wq_attr->wq_type);
906*2d9fd380Sjfb8856606 	MLX5_SET(wq, wq_ctx, wq_signature, wq_attr->wq_signature);
907*2d9fd380Sjfb8856606 	MLX5_SET(wq, wq_ctx, end_padding_mode, wq_attr->end_padding_mode);
908*2d9fd380Sjfb8856606 	MLX5_SET(wq, wq_ctx, cd_slave, wq_attr->cd_slave);
909*2d9fd380Sjfb8856606 	MLX5_SET(wq, wq_ctx, hds_skip_first_sge, wq_attr->hds_skip_first_sge);
910*2d9fd380Sjfb8856606 	MLX5_SET(wq, wq_ctx, log2_hds_buf_size, wq_attr->log2_hds_buf_size);
911*2d9fd380Sjfb8856606 	MLX5_SET(wq, wq_ctx, page_offset, wq_attr->page_offset);
912*2d9fd380Sjfb8856606 	MLX5_SET(wq, wq_ctx, lwm, wq_attr->lwm);
913*2d9fd380Sjfb8856606 	MLX5_SET(wq, wq_ctx, pd, wq_attr->pd);
914*2d9fd380Sjfb8856606 	MLX5_SET(wq, wq_ctx, uar_page, wq_attr->uar_page);
915*2d9fd380Sjfb8856606 	MLX5_SET64(wq, wq_ctx, dbr_addr, wq_attr->dbr_addr);
916*2d9fd380Sjfb8856606 	MLX5_SET(wq, wq_ctx, hw_counter, wq_attr->hw_counter);
917*2d9fd380Sjfb8856606 	MLX5_SET(wq, wq_ctx, sw_counter, wq_attr->sw_counter);
918*2d9fd380Sjfb8856606 	MLX5_SET(wq, wq_ctx, log_wq_stride, wq_attr->log_wq_stride);
919*2d9fd380Sjfb8856606 	MLX5_SET(wq, wq_ctx, log_wq_pg_sz, wq_attr->log_wq_pg_sz);
920*2d9fd380Sjfb8856606 	MLX5_SET(wq, wq_ctx, log_wq_sz, wq_attr->log_wq_sz);
921*2d9fd380Sjfb8856606 	MLX5_SET(wq, wq_ctx, dbr_umem_valid, wq_attr->dbr_umem_valid);
922*2d9fd380Sjfb8856606 	MLX5_SET(wq, wq_ctx, wq_umem_valid, wq_attr->wq_umem_valid);
923*2d9fd380Sjfb8856606 	MLX5_SET(wq, wq_ctx, log_hairpin_num_packets,
924*2d9fd380Sjfb8856606 		 wq_attr->log_hairpin_num_packets);
925*2d9fd380Sjfb8856606 	MLX5_SET(wq, wq_ctx, log_hairpin_data_sz, wq_attr->log_hairpin_data_sz);
926*2d9fd380Sjfb8856606 	MLX5_SET(wq, wq_ctx, single_wqe_log_num_of_strides,
927*2d9fd380Sjfb8856606 		 wq_attr->single_wqe_log_num_of_strides);
928*2d9fd380Sjfb8856606 	MLX5_SET(wq, wq_ctx, two_byte_shift_en, wq_attr->two_byte_shift_en);
929*2d9fd380Sjfb8856606 	MLX5_SET(wq, wq_ctx, single_stride_log_num_of_bytes,
930*2d9fd380Sjfb8856606 		 wq_attr->single_stride_log_num_of_bytes);
931*2d9fd380Sjfb8856606 	MLX5_SET(wq, wq_ctx, dbr_umem_id, wq_attr->dbr_umem_id);
932*2d9fd380Sjfb8856606 	MLX5_SET(wq, wq_ctx, wq_umem_id, wq_attr->wq_umem_id);
933*2d9fd380Sjfb8856606 	MLX5_SET64(wq, wq_ctx, wq_umem_offset, wq_attr->wq_umem_offset);
934*2d9fd380Sjfb8856606 }
935*2d9fd380Sjfb8856606 
936*2d9fd380Sjfb8856606 /**
937*2d9fd380Sjfb8856606  * Create RQ using DevX API.
938*2d9fd380Sjfb8856606  *
939*2d9fd380Sjfb8856606  * @param[in] ctx
940*2d9fd380Sjfb8856606  *   Context returned from mlx5 open_device() glue function.
941*2d9fd380Sjfb8856606  * @param [in] rq_attr
942*2d9fd380Sjfb8856606  *   Pointer to create RQ attributes structure.
943*2d9fd380Sjfb8856606  * @param [in] socket
944*2d9fd380Sjfb8856606  *   CPU socket ID for allocations.
945*2d9fd380Sjfb8856606  *
946*2d9fd380Sjfb8856606  * @return
947*2d9fd380Sjfb8856606  *   The DevX object created, NULL otherwise and rte_errno is set.
948*2d9fd380Sjfb8856606  */
949*2d9fd380Sjfb8856606 struct mlx5_devx_obj *
mlx5_devx_cmd_create_rq(void * ctx,struct mlx5_devx_create_rq_attr * rq_attr,int socket)950*2d9fd380Sjfb8856606 mlx5_devx_cmd_create_rq(void *ctx,
951*2d9fd380Sjfb8856606 			struct mlx5_devx_create_rq_attr *rq_attr,
952*2d9fd380Sjfb8856606 			int socket)
953*2d9fd380Sjfb8856606 {
954*2d9fd380Sjfb8856606 	uint32_t in[MLX5_ST_SZ_DW(create_rq_in)] = {0};
955*2d9fd380Sjfb8856606 	uint32_t out[MLX5_ST_SZ_DW(create_rq_out)] = {0};
956*2d9fd380Sjfb8856606 	void *rq_ctx, *wq_ctx;
957*2d9fd380Sjfb8856606 	struct mlx5_devx_wq_attr *wq_attr;
958*2d9fd380Sjfb8856606 	struct mlx5_devx_obj *rq = NULL;
959*2d9fd380Sjfb8856606 
960*2d9fd380Sjfb8856606 	rq = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*rq), 0, socket);
961*2d9fd380Sjfb8856606 	if (!rq) {
962*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to allocate RQ data");
963*2d9fd380Sjfb8856606 		rte_errno = ENOMEM;
964*2d9fd380Sjfb8856606 		return NULL;
965*2d9fd380Sjfb8856606 	}
966*2d9fd380Sjfb8856606 	MLX5_SET(create_rq_in, in, opcode, MLX5_CMD_OP_CREATE_RQ);
967*2d9fd380Sjfb8856606 	rq_ctx = MLX5_ADDR_OF(create_rq_in, in, ctx);
968*2d9fd380Sjfb8856606 	MLX5_SET(rqc, rq_ctx, rlky, rq_attr->rlky);
969*2d9fd380Sjfb8856606 	MLX5_SET(rqc, rq_ctx, delay_drop_en, rq_attr->delay_drop_en);
970*2d9fd380Sjfb8856606 	MLX5_SET(rqc, rq_ctx, scatter_fcs, rq_attr->scatter_fcs);
971*2d9fd380Sjfb8856606 	MLX5_SET(rqc, rq_ctx, vsd, rq_attr->vsd);
972*2d9fd380Sjfb8856606 	MLX5_SET(rqc, rq_ctx, mem_rq_type, rq_attr->mem_rq_type);
973*2d9fd380Sjfb8856606 	MLX5_SET(rqc, rq_ctx, state, rq_attr->state);
974*2d9fd380Sjfb8856606 	MLX5_SET(rqc, rq_ctx, flush_in_error_en, rq_attr->flush_in_error_en);
975*2d9fd380Sjfb8856606 	MLX5_SET(rqc, rq_ctx, hairpin, rq_attr->hairpin);
976*2d9fd380Sjfb8856606 	MLX5_SET(rqc, rq_ctx, user_index, rq_attr->user_index);
977*2d9fd380Sjfb8856606 	MLX5_SET(rqc, rq_ctx, cqn, rq_attr->cqn);
978*2d9fd380Sjfb8856606 	MLX5_SET(rqc, rq_ctx, counter_set_id, rq_attr->counter_set_id);
979*2d9fd380Sjfb8856606 	MLX5_SET(rqc, rq_ctx, rmpn, rq_attr->rmpn);
980*2d9fd380Sjfb8856606 	wq_ctx = MLX5_ADDR_OF(rqc, rq_ctx, wq);
981*2d9fd380Sjfb8856606 	wq_attr = &rq_attr->wq_attr;
982*2d9fd380Sjfb8856606 	devx_cmd_fill_wq_data(wq_ctx, wq_attr);
983*2d9fd380Sjfb8856606 	rq->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in),
984*2d9fd380Sjfb8856606 						  out, sizeof(out));
985*2d9fd380Sjfb8856606 	if (!rq->obj) {
986*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to create RQ using DevX");
987*2d9fd380Sjfb8856606 		rte_errno = errno;
988*2d9fd380Sjfb8856606 		mlx5_free(rq);
989*2d9fd380Sjfb8856606 		return NULL;
990*2d9fd380Sjfb8856606 	}
991*2d9fd380Sjfb8856606 	rq->id = MLX5_GET(create_rq_out, out, rqn);
992*2d9fd380Sjfb8856606 	return rq;
993*2d9fd380Sjfb8856606 }
994*2d9fd380Sjfb8856606 
995*2d9fd380Sjfb8856606 /**
996*2d9fd380Sjfb8856606  * Modify RQ using DevX API.
997*2d9fd380Sjfb8856606  *
998*2d9fd380Sjfb8856606  * @param[in] rq
999*2d9fd380Sjfb8856606  *   Pointer to RQ object structure.
1000*2d9fd380Sjfb8856606  * @param [in] rq_attr
1001*2d9fd380Sjfb8856606  *   Pointer to modify RQ attributes structure.
1002*2d9fd380Sjfb8856606  *
1003*2d9fd380Sjfb8856606  * @return
1004*2d9fd380Sjfb8856606  *   0 on success, a negative errno value otherwise and rte_errno is set.
1005*2d9fd380Sjfb8856606  */
1006*2d9fd380Sjfb8856606 int
mlx5_devx_cmd_modify_rq(struct mlx5_devx_obj * rq,struct mlx5_devx_modify_rq_attr * rq_attr)1007*2d9fd380Sjfb8856606 mlx5_devx_cmd_modify_rq(struct mlx5_devx_obj *rq,
1008*2d9fd380Sjfb8856606 			struct mlx5_devx_modify_rq_attr *rq_attr)
1009*2d9fd380Sjfb8856606 {
1010*2d9fd380Sjfb8856606 	uint32_t in[MLX5_ST_SZ_DW(modify_rq_in)] = {0};
1011*2d9fd380Sjfb8856606 	uint32_t out[MLX5_ST_SZ_DW(modify_rq_out)] = {0};
1012*2d9fd380Sjfb8856606 	void *rq_ctx, *wq_ctx;
1013*2d9fd380Sjfb8856606 	int ret;
1014*2d9fd380Sjfb8856606 
1015*2d9fd380Sjfb8856606 	MLX5_SET(modify_rq_in, in, opcode, MLX5_CMD_OP_MODIFY_RQ);
1016*2d9fd380Sjfb8856606 	MLX5_SET(modify_rq_in, in, rq_state, rq_attr->rq_state);
1017*2d9fd380Sjfb8856606 	MLX5_SET(modify_rq_in, in, rqn, rq->id);
1018*2d9fd380Sjfb8856606 	MLX5_SET64(modify_rq_in, in, modify_bitmask, rq_attr->modify_bitmask);
1019*2d9fd380Sjfb8856606 	rq_ctx = MLX5_ADDR_OF(modify_rq_in, in, ctx);
1020*2d9fd380Sjfb8856606 	MLX5_SET(rqc, rq_ctx, state, rq_attr->state);
1021*2d9fd380Sjfb8856606 	if (rq_attr->modify_bitmask &
1022*2d9fd380Sjfb8856606 			MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_SCATTER_FCS)
1023*2d9fd380Sjfb8856606 		MLX5_SET(rqc, rq_ctx, scatter_fcs, rq_attr->scatter_fcs);
1024*2d9fd380Sjfb8856606 	if (rq_attr->modify_bitmask & MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_VSD)
1025*2d9fd380Sjfb8856606 		MLX5_SET(rqc, rq_ctx, vsd, rq_attr->vsd);
1026*2d9fd380Sjfb8856606 	if (rq_attr->modify_bitmask &
1027*2d9fd380Sjfb8856606 			MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_RQ_COUNTER_SET_ID)
1028*2d9fd380Sjfb8856606 		MLX5_SET(rqc, rq_ctx, counter_set_id, rq_attr->counter_set_id);
1029*2d9fd380Sjfb8856606 	MLX5_SET(rqc, rq_ctx, hairpin_peer_sq, rq_attr->hairpin_peer_sq);
1030*2d9fd380Sjfb8856606 	MLX5_SET(rqc, rq_ctx, hairpin_peer_vhca, rq_attr->hairpin_peer_vhca);
1031*2d9fd380Sjfb8856606 	if (rq_attr->modify_bitmask & MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_WQ_LWM) {
1032*2d9fd380Sjfb8856606 		wq_ctx = MLX5_ADDR_OF(rqc, rq_ctx, wq);
1033*2d9fd380Sjfb8856606 		MLX5_SET(wq, wq_ctx, lwm, rq_attr->lwm);
1034*2d9fd380Sjfb8856606 	}
1035*2d9fd380Sjfb8856606 	ret = mlx5_glue->devx_obj_modify(rq->obj, in, sizeof(in),
1036*2d9fd380Sjfb8856606 					 out, sizeof(out));
1037*2d9fd380Sjfb8856606 	if (ret) {
1038*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to modify RQ using DevX");
1039*2d9fd380Sjfb8856606 		rte_errno = errno;
1040*2d9fd380Sjfb8856606 		return -errno;
1041*2d9fd380Sjfb8856606 	}
1042*2d9fd380Sjfb8856606 	return ret;
1043*2d9fd380Sjfb8856606 }
1044*2d9fd380Sjfb8856606 
1045*2d9fd380Sjfb8856606 /**
1046*2d9fd380Sjfb8856606  * Create TIR using DevX API.
1047*2d9fd380Sjfb8856606  *
1048*2d9fd380Sjfb8856606  * @param[in] ctx
1049*2d9fd380Sjfb8856606  *  Context returned from mlx5 open_device() glue function.
1050*2d9fd380Sjfb8856606  * @param [in] tir_attr
1051*2d9fd380Sjfb8856606  *   Pointer to TIR attributes structure.
1052*2d9fd380Sjfb8856606  *
1053*2d9fd380Sjfb8856606  * @return
1054*2d9fd380Sjfb8856606  *   The DevX object created, NULL otherwise and rte_errno is set.
1055*2d9fd380Sjfb8856606  */
1056*2d9fd380Sjfb8856606 struct mlx5_devx_obj *
mlx5_devx_cmd_create_tir(void * ctx,struct mlx5_devx_tir_attr * tir_attr)1057*2d9fd380Sjfb8856606 mlx5_devx_cmd_create_tir(void *ctx,
1058*2d9fd380Sjfb8856606 			 struct mlx5_devx_tir_attr *tir_attr)
1059*2d9fd380Sjfb8856606 {
1060*2d9fd380Sjfb8856606 	uint32_t in[MLX5_ST_SZ_DW(create_tir_in)] = {0};
1061*2d9fd380Sjfb8856606 	uint32_t out[MLX5_ST_SZ_DW(create_tir_out)] = {0};
1062*2d9fd380Sjfb8856606 	void *tir_ctx, *outer, *inner, *rss_key;
1063*2d9fd380Sjfb8856606 	struct mlx5_devx_obj *tir = NULL;
1064*2d9fd380Sjfb8856606 
1065*2d9fd380Sjfb8856606 	tir = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*tir), 0, SOCKET_ID_ANY);
1066*2d9fd380Sjfb8856606 	if (!tir) {
1067*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to allocate TIR data");
1068*2d9fd380Sjfb8856606 		rte_errno = ENOMEM;
1069*2d9fd380Sjfb8856606 		return NULL;
1070*2d9fd380Sjfb8856606 	}
1071*2d9fd380Sjfb8856606 	MLX5_SET(create_tir_in, in, opcode, MLX5_CMD_OP_CREATE_TIR);
1072*2d9fd380Sjfb8856606 	tir_ctx = MLX5_ADDR_OF(create_tir_in, in, ctx);
1073*2d9fd380Sjfb8856606 	MLX5_SET(tirc, tir_ctx, disp_type, tir_attr->disp_type);
1074*2d9fd380Sjfb8856606 	MLX5_SET(tirc, tir_ctx, lro_timeout_period_usecs,
1075*2d9fd380Sjfb8856606 		 tir_attr->lro_timeout_period_usecs);
1076*2d9fd380Sjfb8856606 	MLX5_SET(tirc, tir_ctx, lro_enable_mask, tir_attr->lro_enable_mask);
1077*2d9fd380Sjfb8856606 	MLX5_SET(tirc, tir_ctx, lro_max_msg_sz, tir_attr->lro_max_msg_sz);
1078*2d9fd380Sjfb8856606 	MLX5_SET(tirc, tir_ctx, inline_rqn, tir_attr->inline_rqn);
1079*2d9fd380Sjfb8856606 	MLX5_SET(tirc, tir_ctx, rx_hash_symmetric, tir_attr->rx_hash_symmetric);
1080*2d9fd380Sjfb8856606 	MLX5_SET(tirc, tir_ctx, tunneled_offload_en,
1081*2d9fd380Sjfb8856606 		 tir_attr->tunneled_offload_en);
1082*2d9fd380Sjfb8856606 	MLX5_SET(tirc, tir_ctx, indirect_table, tir_attr->indirect_table);
1083*2d9fd380Sjfb8856606 	MLX5_SET(tirc, tir_ctx, rx_hash_fn, tir_attr->rx_hash_fn);
1084*2d9fd380Sjfb8856606 	MLX5_SET(tirc, tir_ctx, self_lb_block, tir_attr->self_lb_block);
1085*2d9fd380Sjfb8856606 	MLX5_SET(tirc, tir_ctx, transport_domain, tir_attr->transport_domain);
1086*2d9fd380Sjfb8856606 	rss_key = MLX5_ADDR_OF(tirc, tir_ctx, rx_hash_toeplitz_key);
1087*2d9fd380Sjfb8856606 	memcpy(rss_key, tir_attr->rx_hash_toeplitz_key, MLX5_RSS_HASH_KEY_LEN);
1088*2d9fd380Sjfb8856606 	outer = MLX5_ADDR_OF(tirc, tir_ctx, rx_hash_field_selector_outer);
1089*2d9fd380Sjfb8856606 	MLX5_SET(rx_hash_field_select, outer, l3_prot_type,
1090*2d9fd380Sjfb8856606 		 tir_attr->rx_hash_field_selector_outer.l3_prot_type);
1091*2d9fd380Sjfb8856606 	MLX5_SET(rx_hash_field_select, outer, l4_prot_type,
1092*2d9fd380Sjfb8856606 		 tir_attr->rx_hash_field_selector_outer.l4_prot_type);
1093*2d9fd380Sjfb8856606 	MLX5_SET(rx_hash_field_select, outer, selected_fields,
1094*2d9fd380Sjfb8856606 		 tir_attr->rx_hash_field_selector_outer.selected_fields);
1095*2d9fd380Sjfb8856606 	inner = MLX5_ADDR_OF(tirc, tir_ctx, rx_hash_field_selector_inner);
1096*2d9fd380Sjfb8856606 	MLX5_SET(rx_hash_field_select, inner, l3_prot_type,
1097*2d9fd380Sjfb8856606 		 tir_attr->rx_hash_field_selector_inner.l3_prot_type);
1098*2d9fd380Sjfb8856606 	MLX5_SET(rx_hash_field_select, inner, l4_prot_type,
1099*2d9fd380Sjfb8856606 		 tir_attr->rx_hash_field_selector_inner.l4_prot_type);
1100*2d9fd380Sjfb8856606 	MLX5_SET(rx_hash_field_select, inner, selected_fields,
1101*2d9fd380Sjfb8856606 		 tir_attr->rx_hash_field_selector_inner.selected_fields);
1102*2d9fd380Sjfb8856606 	tir->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in),
1103*2d9fd380Sjfb8856606 						   out, sizeof(out));
1104*2d9fd380Sjfb8856606 	if (!tir->obj) {
1105*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to create TIR using DevX");
1106*2d9fd380Sjfb8856606 		rte_errno = errno;
1107*2d9fd380Sjfb8856606 		mlx5_free(tir);
1108*2d9fd380Sjfb8856606 		return NULL;
1109*2d9fd380Sjfb8856606 	}
1110*2d9fd380Sjfb8856606 	tir->id = MLX5_GET(create_tir_out, out, tirn);
1111*2d9fd380Sjfb8856606 	return tir;
1112*2d9fd380Sjfb8856606 }
1113*2d9fd380Sjfb8856606 
1114*2d9fd380Sjfb8856606 /**
1115*2d9fd380Sjfb8856606  * Modify TIR using DevX API.
1116*2d9fd380Sjfb8856606  *
1117*2d9fd380Sjfb8856606  * @param[in] tir
1118*2d9fd380Sjfb8856606  *   Pointer to TIR DevX object structure.
1119*2d9fd380Sjfb8856606  * @param [in] modify_tir_attr
1120*2d9fd380Sjfb8856606  *   Pointer to TIR modification attributes structure.
1121*2d9fd380Sjfb8856606  *
1122*2d9fd380Sjfb8856606  * @return
1123*2d9fd380Sjfb8856606  *   0 on success, a negative errno value otherwise and rte_errno is set.
1124*2d9fd380Sjfb8856606  */
1125*2d9fd380Sjfb8856606 int
mlx5_devx_cmd_modify_tir(struct mlx5_devx_obj * tir,struct mlx5_devx_modify_tir_attr * modify_tir_attr)1126*2d9fd380Sjfb8856606 mlx5_devx_cmd_modify_tir(struct mlx5_devx_obj *tir,
1127*2d9fd380Sjfb8856606 			 struct mlx5_devx_modify_tir_attr *modify_tir_attr)
1128*2d9fd380Sjfb8856606 {
1129*2d9fd380Sjfb8856606 	struct mlx5_devx_tir_attr *tir_attr = &modify_tir_attr->tir;
1130*2d9fd380Sjfb8856606 	uint32_t in[MLX5_ST_SZ_DW(modify_tir_in)] = {0};
1131*2d9fd380Sjfb8856606 	uint32_t out[MLX5_ST_SZ_DW(modify_tir_out)] = {0};
1132*2d9fd380Sjfb8856606 	void *tir_ctx;
1133*2d9fd380Sjfb8856606 	int ret;
1134*2d9fd380Sjfb8856606 
1135*2d9fd380Sjfb8856606 	MLX5_SET(modify_tir_in, in, opcode, MLX5_CMD_OP_MODIFY_TIR);
1136*2d9fd380Sjfb8856606 	MLX5_SET(modify_tir_in, in, tirn, modify_tir_attr->tirn);
1137*2d9fd380Sjfb8856606 	MLX5_SET64(modify_tir_in, in, modify_bitmask,
1138*2d9fd380Sjfb8856606 		   modify_tir_attr->modify_bitmask);
1139*2d9fd380Sjfb8856606 	tir_ctx = MLX5_ADDR_OF(modify_rq_in, in, ctx);
1140*2d9fd380Sjfb8856606 	if (modify_tir_attr->modify_bitmask &
1141*2d9fd380Sjfb8856606 			MLX5_MODIFY_TIR_IN_MODIFY_BITMASK_LRO) {
1142*2d9fd380Sjfb8856606 		MLX5_SET(tirc, tir_ctx, lro_timeout_period_usecs,
1143*2d9fd380Sjfb8856606 			 tir_attr->lro_timeout_period_usecs);
1144*2d9fd380Sjfb8856606 		MLX5_SET(tirc, tir_ctx, lro_enable_mask,
1145*2d9fd380Sjfb8856606 			 tir_attr->lro_enable_mask);
1146*2d9fd380Sjfb8856606 		MLX5_SET(tirc, tir_ctx, lro_max_msg_sz,
1147*2d9fd380Sjfb8856606 			 tir_attr->lro_max_msg_sz);
1148*2d9fd380Sjfb8856606 	}
1149*2d9fd380Sjfb8856606 	if (modify_tir_attr->modify_bitmask &
1150*2d9fd380Sjfb8856606 			MLX5_MODIFY_TIR_IN_MODIFY_BITMASK_INDIRECT_TABLE)
1151*2d9fd380Sjfb8856606 		MLX5_SET(tirc, tir_ctx, indirect_table,
1152*2d9fd380Sjfb8856606 			 tir_attr->indirect_table);
1153*2d9fd380Sjfb8856606 	if (modify_tir_attr->modify_bitmask &
1154*2d9fd380Sjfb8856606 			MLX5_MODIFY_TIR_IN_MODIFY_BITMASK_HASH) {
1155*2d9fd380Sjfb8856606 		int i;
1156*2d9fd380Sjfb8856606 		void *outer, *inner;
1157*2d9fd380Sjfb8856606 
1158*2d9fd380Sjfb8856606 		MLX5_SET(tirc, tir_ctx, rx_hash_symmetric,
1159*2d9fd380Sjfb8856606 			 tir_attr->rx_hash_symmetric);
1160*2d9fd380Sjfb8856606 		MLX5_SET(tirc, tir_ctx, rx_hash_fn, tir_attr->rx_hash_fn);
1161*2d9fd380Sjfb8856606 		for (i = 0; i < 10; i++) {
1162*2d9fd380Sjfb8856606 			MLX5_SET(tirc, tir_ctx, rx_hash_toeplitz_key[i],
1163*2d9fd380Sjfb8856606 				 tir_attr->rx_hash_toeplitz_key[i]);
1164*2d9fd380Sjfb8856606 		}
1165*2d9fd380Sjfb8856606 		outer = MLX5_ADDR_OF(tirc, tir_ctx,
1166*2d9fd380Sjfb8856606 				     rx_hash_field_selector_outer);
1167*2d9fd380Sjfb8856606 		MLX5_SET(rx_hash_field_select, outer, l3_prot_type,
1168*2d9fd380Sjfb8856606 			 tir_attr->rx_hash_field_selector_outer.l3_prot_type);
1169*2d9fd380Sjfb8856606 		MLX5_SET(rx_hash_field_select, outer, l4_prot_type,
1170*2d9fd380Sjfb8856606 			 tir_attr->rx_hash_field_selector_outer.l4_prot_type);
1171*2d9fd380Sjfb8856606 		MLX5_SET
1172*2d9fd380Sjfb8856606 		(rx_hash_field_select, outer, selected_fields,
1173*2d9fd380Sjfb8856606 		 tir_attr->rx_hash_field_selector_outer.selected_fields);
1174*2d9fd380Sjfb8856606 		inner = MLX5_ADDR_OF(tirc, tir_ctx,
1175*2d9fd380Sjfb8856606 				     rx_hash_field_selector_inner);
1176*2d9fd380Sjfb8856606 		MLX5_SET(rx_hash_field_select, inner, l3_prot_type,
1177*2d9fd380Sjfb8856606 			 tir_attr->rx_hash_field_selector_inner.l3_prot_type);
1178*2d9fd380Sjfb8856606 		MLX5_SET(rx_hash_field_select, inner, l4_prot_type,
1179*2d9fd380Sjfb8856606 			 tir_attr->rx_hash_field_selector_inner.l4_prot_type);
1180*2d9fd380Sjfb8856606 		MLX5_SET
1181*2d9fd380Sjfb8856606 		(rx_hash_field_select, inner, selected_fields,
1182*2d9fd380Sjfb8856606 		 tir_attr->rx_hash_field_selector_inner.selected_fields);
1183*2d9fd380Sjfb8856606 	}
1184*2d9fd380Sjfb8856606 	if (modify_tir_attr->modify_bitmask &
1185*2d9fd380Sjfb8856606 	    MLX5_MODIFY_TIR_IN_MODIFY_BITMASK_SELF_LB_EN) {
1186*2d9fd380Sjfb8856606 		MLX5_SET(tirc, tir_ctx, self_lb_block, tir_attr->self_lb_block);
1187*2d9fd380Sjfb8856606 	}
1188*2d9fd380Sjfb8856606 	ret = mlx5_glue->devx_obj_modify(tir->obj, in, sizeof(in),
1189*2d9fd380Sjfb8856606 					 out, sizeof(out));
1190*2d9fd380Sjfb8856606 	if (ret) {
1191*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to modify TIR using DevX");
1192*2d9fd380Sjfb8856606 		rte_errno = errno;
1193*2d9fd380Sjfb8856606 		return -errno;
1194*2d9fd380Sjfb8856606 	}
1195*2d9fd380Sjfb8856606 	return ret;
1196*2d9fd380Sjfb8856606 }
1197*2d9fd380Sjfb8856606 
1198*2d9fd380Sjfb8856606 /**
1199*2d9fd380Sjfb8856606  * Create RQT using DevX API.
1200*2d9fd380Sjfb8856606  *
1201*2d9fd380Sjfb8856606  * @param[in] ctx
1202*2d9fd380Sjfb8856606  *   Context returned from mlx5 open_device() glue function.
1203*2d9fd380Sjfb8856606  * @param [in] rqt_attr
1204*2d9fd380Sjfb8856606  *   Pointer to RQT attributes structure.
1205*2d9fd380Sjfb8856606  *
1206*2d9fd380Sjfb8856606  * @return
1207*2d9fd380Sjfb8856606  *   The DevX object created, NULL otherwise and rte_errno is set.
1208*2d9fd380Sjfb8856606  */
1209*2d9fd380Sjfb8856606 struct mlx5_devx_obj *
mlx5_devx_cmd_create_rqt(void * ctx,struct mlx5_devx_rqt_attr * rqt_attr)1210*2d9fd380Sjfb8856606 mlx5_devx_cmd_create_rqt(void *ctx,
1211*2d9fd380Sjfb8856606 			 struct mlx5_devx_rqt_attr *rqt_attr)
1212*2d9fd380Sjfb8856606 {
1213*2d9fd380Sjfb8856606 	uint32_t *in = NULL;
1214*2d9fd380Sjfb8856606 	uint32_t inlen = MLX5_ST_SZ_BYTES(create_rqt_in) +
1215*2d9fd380Sjfb8856606 			 rqt_attr->rqt_actual_size * sizeof(uint32_t);
1216*2d9fd380Sjfb8856606 	uint32_t out[MLX5_ST_SZ_DW(create_rqt_out)] = {0};
1217*2d9fd380Sjfb8856606 	void *rqt_ctx;
1218*2d9fd380Sjfb8856606 	struct mlx5_devx_obj *rqt = NULL;
1219*2d9fd380Sjfb8856606 	int i;
1220*2d9fd380Sjfb8856606 
1221*2d9fd380Sjfb8856606 	in = mlx5_malloc(MLX5_MEM_ZERO, inlen, 0, SOCKET_ID_ANY);
1222*2d9fd380Sjfb8856606 	if (!in) {
1223*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to allocate RQT IN data");
1224*2d9fd380Sjfb8856606 		rte_errno = ENOMEM;
1225*2d9fd380Sjfb8856606 		return NULL;
1226*2d9fd380Sjfb8856606 	}
1227*2d9fd380Sjfb8856606 	rqt = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*rqt), 0, SOCKET_ID_ANY);
1228*2d9fd380Sjfb8856606 	if (!rqt) {
1229*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to allocate RQT data");
1230*2d9fd380Sjfb8856606 		rte_errno = ENOMEM;
1231*2d9fd380Sjfb8856606 		mlx5_free(in);
1232*2d9fd380Sjfb8856606 		return NULL;
1233*2d9fd380Sjfb8856606 	}
1234*2d9fd380Sjfb8856606 	MLX5_SET(create_rqt_in, in, opcode, MLX5_CMD_OP_CREATE_RQT);
1235*2d9fd380Sjfb8856606 	rqt_ctx = MLX5_ADDR_OF(create_rqt_in, in, rqt_context);
1236*2d9fd380Sjfb8856606 	MLX5_SET(rqtc, rqt_ctx, list_q_type, rqt_attr->rq_type);
1237*2d9fd380Sjfb8856606 	MLX5_SET(rqtc, rqt_ctx, rqt_max_size, rqt_attr->rqt_max_size);
1238*2d9fd380Sjfb8856606 	MLX5_SET(rqtc, rqt_ctx, rqt_actual_size, rqt_attr->rqt_actual_size);
1239*2d9fd380Sjfb8856606 	for (i = 0; i < rqt_attr->rqt_actual_size; i++)
1240*2d9fd380Sjfb8856606 		MLX5_SET(rqtc, rqt_ctx, rq_num[i], rqt_attr->rq_list[i]);
1241*2d9fd380Sjfb8856606 	rqt->obj = mlx5_glue->devx_obj_create(ctx, in, inlen, out, sizeof(out));
1242*2d9fd380Sjfb8856606 	mlx5_free(in);
1243*2d9fd380Sjfb8856606 	if (!rqt->obj) {
1244*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to create RQT using DevX");
1245*2d9fd380Sjfb8856606 		rte_errno = errno;
1246*2d9fd380Sjfb8856606 		mlx5_free(rqt);
1247*2d9fd380Sjfb8856606 		return NULL;
1248*2d9fd380Sjfb8856606 	}
1249*2d9fd380Sjfb8856606 	rqt->id = MLX5_GET(create_rqt_out, out, rqtn);
1250*2d9fd380Sjfb8856606 	return rqt;
1251*2d9fd380Sjfb8856606 }
1252*2d9fd380Sjfb8856606 
1253*2d9fd380Sjfb8856606 /**
1254*2d9fd380Sjfb8856606  * Modify RQT using DevX API.
1255*2d9fd380Sjfb8856606  *
1256*2d9fd380Sjfb8856606  * @param[in] rqt
1257*2d9fd380Sjfb8856606  *   Pointer to RQT DevX object structure.
1258*2d9fd380Sjfb8856606  * @param [in] rqt_attr
1259*2d9fd380Sjfb8856606  *   Pointer to RQT attributes structure.
1260*2d9fd380Sjfb8856606  *
1261*2d9fd380Sjfb8856606  * @return
1262*2d9fd380Sjfb8856606  *   0 on success, a negative errno value otherwise and rte_errno is set.
1263*2d9fd380Sjfb8856606  */
1264*2d9fd380Sjfb8856606 int
mlx5_devx_cmd_modify_rqt(struct mlx5_devx_obj * rqt,struct mlx5_devx_rqt_attr * rqt_attr)1265*2d9fd380Sjfb8856606 mlx5_devx_cmd_modify_rqt(struct mlx5_devx_obj *rqt,
1266*2d9fd380Sjfb8856606 			 struct mlx5_devx_rqt_attr *rqt_attr)
1267*2d9fd380Sjfb8856606 {
1268*2d9fd380Sjfb8856606 	uint32_t inlen = MLX5_ST_SZ_BYTES(modify_rqt_in) +
1269*2d9fd380Sjfb8856606 			 rqt_attr->rqt_actual_size * sizeof(uint32_t);
1270*2d9fd380Sjfb8856606 	uint32_t out[MLX5_ST_SZ_DW(modify_rqt_out)] = {0};
1271*2d9fd380Sjfb8856606 	uint32_t *in = mlx5_malloc(MLX5_MEM_ZERO, inlen, 0, SOCKET_ID_ANY);
1272*2d9fd380Sjfb8856606 	void *rqt_ctx;
1273*2d9fd380Sjfb8856606 	int i;
1274*2d9fd380Sjfb8856606 	int ret;
1275*2d9fd380Sjfb8856606 
1276*2d9fd380Sjfb8856606 	if (!in) {
1277*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to allocate RQT modify IN data.");
1278*2d9fd380Sjfb8856606 		rte_errno = ENOMEM;
1279*2d9fd380Sjfb8856606 		return -ENOMEM;
1280*2d9fd380Sjfb8856606 	}
1281*2d9fd380Sjfb8856606 	MLX5_SET(modify_rqt_in, in, opcode, MLX5_CMD_OP_MODIFY_RQT);
1282*2d9fd380Sjfb8856606 	MLX5_SET(modify_rqt_in, in, rqtn, rqt->id);
1283*2d9fd380Sjfb8856606 	MLX5_SET64(modify_rqt_in, in, modify_bitmask, 0x1);
1284*2d9fd380Sjfb8856606 	rqt_ctx = MLX5_ADDR_OF(modify_rqt_in, in, rqt_context);
1285*2d9fd380Sjfb8856606 	MLX5_SET(rqtc, rqt_ctx, list_q_type, rqt_attr->rq_type);
1286*2d9fd380Sjfb8856606 	MLX5_SET(rqtc, rqt_ctx, rqt_max_size, rqt_attr->rqt_max_size);
1287*2d9fd380Sjfb8856606 	MLX5_SET(rqtc, rqt_ctx, rqt_actual_size, rqt_attr->rqt_actual_size);
1288*2d9fd380Sjfb8856606 	for (i = 0; i < rqt_attr->rqt_actual_size; i++)
1289*2d9fd380Sjfb8856606 		MLX5_SET(rqtc, rqt_ctx, rq_num[i], rqt_attr->rq_list[i]);
1290*2d9fd380Sjfb8856606 	ret = mlx5_glue->devx_obj_modify(rqt->obj, in, inlen, out, sizeof(out));
1291*2d9fd380Sjfb8856606 	mlx5_free(in);
1292*2d9fd380Sjfb8856606 	if (ret) {
1293*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to modify RQT using DevX.");
1294*2d9fd380Sjfb8856606 		rte_errno = errno;
1295*2d9fd380Sjfb8856606 		return -rte_errno;
1296*2d9fd380Sjfb8856606 	}
1297*2d9fd380Sjfb8856606 	return ret;
1298*2d9fd380Sjfb8856606 }
1299*2d9fd380Sjfb8856606 
1300*2d9fd380Sjfb8856606 /**
1301*2d9fd380Sjfb8856606  * Create SQ using DevX API.
1302*2d9fd380Sjfb8856606  *
1303*2d9fd380Sjfb8856606  * @param[in] ctx
1304*2d9fd380Sjfb8856606  *   Context returned from mlx5 open_device() glue function.
1305*2d9fd380Sjfb8856606  * @param [in] sq_attr
1306*2d9fd380Sjfb8856606  *   Pointer to SQ attributes structure.
1307*2d9fd380Sjfb8856606  * @param [in] socket
1308*2d9fd380Sjfb8856606  *   CPU socket ID for allocations.
1309*2d9fd380Sjfb8856606  *
1310*2d9fd380Sjfb8856606  * @return
1311*2d9fd380Sjfb8856606  *   The DevX object created, NULL otherwise and rte_errno is set.
1312*2d9fd380Sjfb8856606  **/
1313*2d9fd380Sjfb8856606 struct mlx5_devx_obj *
mlx5_devx_cmd_create_sq(void * ctx,struct mlx5_devx_create_sq_attr * sq_attr)1314*2d9fd380Sjfb8856606 mlx5_devx_cmd_create_sq(void *ctx,
1315*2d9fd380Sjfb8856606 			struct mlx5_devx_create_sq_attr *sq_attr)
1316*2d9fd380Sjfb8856606 {
1317*2d9fd380Sjfb8856606 	uint32_t in[MLX5_ST_SZ_DW(create_sq_in)] = {0};
1318*2d9fd380Sjfb8856606 	uint32_t out[MLX5_ST_SZ_DW(create_sq_out)] = {0};
1319*2d9fd380Sjfb8856606 	void *sq_ctx;
1320*2d9fd380Sjfb8856606 	void *wq_ctx;
1321*2d9fd380Sjfb8856606 	struct mlx5_devx_wq_attr *wq_attr;
1322*2d9fd380Sjfb8856606 	struct mlx5_devx_obj *sq = NULL;
1323*2d9fd380Sjfb8856606 
1324*2d9fd380Sjfb8856606 	sq = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*sq), 0, SOCKET_ID_ANY);
1325*2d9fd380Sjfb8856606 	if (!sq) {
1326*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to allocate SQ data");
1327*2d9fd380Sjfb8856606 		rte_errno = ENOMEM;
1328*2d9fd380Sjfb8856606 		return NULL;
1329*2d9fd380Sjfb8856606 	}
1330*2d9fd380Sjfb8856606 	MLX5_SET(create_sq_in, in, opcode, MLX5_CMD_OP_CREATE_SQ);
1331*2d9fd380Sjfb8856606 	sq_ctx = MLX5_ADDR_OF(create_sq_in, in, ctx);
1332*2d9fd380Sjfb8856606 	MLX5_SET(sqc, sq_ctx, rlky, sq_attr->rlky);
1333*2d9fd380Sjfb8856606 	MLX5_SET(sqc, sq_ctx, cd_master, sq_attr->cd_master);
1334*2d9fd380Sjfb8856606 	MLX5_SET(sqc, sq_ctx, fre, sq_attr->fre);
1335*2d9fd380Sjfb8856606 	MLX5_SET(sqc, sq_ctx, flush_in_error_en, sq_attr->flush_in_error_en);
1336*2d9fd380Sjfb8856606 	MLX5_SET(sqc, sq_ctx, allow_multi_pkt_send_wqe,
1337*2d9fd380Sjfb8856606 		 sq_attr->allow_multi_pkt_send_wqe);
1338*2d9fd380Sjfb8856606 	MLX5_SET(sqc, sq_ctx, min_wqe_inline_mode,
1339*2d9fd380Sjfb8856606 		 sq_attr->min_wqe_inline_mode);
1340*2d9fd380Sjfb8856606 	MLX5_SET(sqc, sq_ctx, state, sq_attr->state);
1341*2d9fd380Sjfb8856606 	MLX5_SET(sqc, sq_ctx, reg_umr, sq_attr->reg_umr);
1342*2d9fd380Sjfb8856606 	MLX5_SET(sqc, sq_ctx, allow_swp, sq_attr->allow_swp);
1343*2d9fd380Sjfb8856606 	MLX5_SET(sqc, sq_ctx, hairpin, sq_attr->hairpin);
1344*2d9fd380Sjfb8856606 	MLX5_SET(sqc, sq_ctx, non_wire, sq_attr->non_wire);
1345*2d9fd380Sjfb8856606 	MLX5_SET(sqc, sq_ctx, static_sq_wq, sq_attr->static_sq_wq);
1346*2d9fd380Sjfb8856606 	MLX5_SET(sqc, sq_ctx, user_index, sq_attr->user_index);
1347*2d9fd380Sjfb8856606 	MLX5_SET(sqc, sq_ctx, cqn, sq_attr->cqn);
1348*2d9fd380Sjfb8856606 	MLX5_SET(sqc, sq_ctx, packet_pacing_rate_limit_index,
1349*2d9fd380Sjfb8856606 		 sq_attr->packet_pacing_rate_limit_index);
1350*2d9fd380Sjfb8856606 	MLX5_SET(sqc, sq_ctx, tis_lst_sz, sq_attr->tis_lst_sz);
1351*2d9fd380Sjfb8856606 	MLX5_SET(sqc, sq_ctx, tis_num_0, sq_attr->tis_num);
1352*2d9fd380Sjfb8856606 	wq_ctx = MLX5_ADDR_OF(sqc, sq_ctx, wq);
1353*2d9fd380Sjfb8856606 	wq_attr = &sq_attr->wq_attr;
1354*2d9fd380Sjfb8856606 	devx_cmd_fill_wq_data(wq_ctx, wq_attr);
1355*2d9fd380Sjfb8856606 	sq->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in),
1356*2d9fd380Sjfb8856606 					     out, sizeof(out));
1357*2d9fd380Sjfb8856606 	if (!sq->obj) {
1358*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to create SQ using DevX");
1359*2d9fd380Sjfb8856606 		rte_errno = errno;
1360*2d9fd380Sjfb8856606 		mlx5_free(sq);
1361*2d9fd380Sjfb8856606 		return NULL;
1362*2d9fd380Sjfb8856606 	}
1363*2d9fd380Sjfb8856606 	sq->id = MLX5_GET(create_sq_out, out, sqn);
1364*2d9fd380Sjfb8856606 	return sq;
1365*2d9fd380Sjfb8856606 }
1366*2d9fd380Sjfb8856606 
1367*2d9fd380Sjfb8856606 /**
1368*2d9fd380Sjfb8856606  * Modify SQ using DevX API.
1369*2d9fd380Sjfb8856606  *
1370*2d9fd380Sjfb8856606  * @param[in] sq
1371*2d9fd380Sjfb8856606  *   Pointer to SQ object structure.
1372*2d9fd380Sjfb8856606  * @param [in] sq_attr
1373*2d9fd380Sjfb8856606  *   Pointer to SQ attributes structure.
1374*2d9fd380Sjfb8856606  *
1375*2d9fd380Sjfb8856606  * @return
1376*2d9fd380Sjfb8856606  *   0 on success, a negative errno value otherwise and rte_errno is set.
1377*2d9fd380Sjfb8856606  */
1378*2d9fd380Sjfb8856606 int
mlx5_devx_cmd_modify_sq(struct mlx5_devx_obj * sq,struct mlx5_devx_modify_sq_attr * sq_attr)1379*2d9fd380Sjfb8856606 mlx5_devx_cmd_modify_sq(struct mlx5_devx_obj *sq,
1380*2d9fd380Sjfb8856606 			struct mlx5_devx_modify_sq_attr *sq_attr)
1381*2d9fd380Sjfb8856606 {
1382*2d9fd380Sjfb8856606 	uint32_t in[MLX5_ST_SZ_DW(modify_sq_in)] = {0};
1383*2d9fd380Sjfb8856606 	uint32_t out[MLX5_ST_SZ_DW(modify_sq_out)] = {0};
1384*2d9fd380Sjfb8856606 	void *sq_ctx;
1385*2d9fd380Sjfb8856606 	int ret;
1386*2d9fd380Sjfb8856606 
1387*2d9fd380Sjfb8856606 	MLX5_SET(modify_sq_in, in, opcode, MLX5_CMD_OP_MODIFY_SQ);
1388*2d9fd380Sjfb8856606 	MLX5_SET(modify_sq_in, in, sq_state, sq_attr->sq_state);
1389*2d9fd380Sjfb8856606 	MLX5_SET(modify_sq_in, in, sqn, sq->id);
1390*2d9fd380Sjfb8856606 	sq_ctx = MLX5_ADDR_OF(modify_sq_in, in, ctx);
1391*2d9fd380Sjfb8856606 	MLX5_SET(sqc, sq_ctx, state, sq_attr->state);
1392*2d9fd380Sjfb8856606 	MLX5_SET(sqc, sq_ctx, hairpin_peer_rq, sq_attr->hairpin_peer_rq);
1393*2d9fd380Sjfb8856606 	MLX5_SET(sqc, sq_ctx, hairpin_peer_vhca, sq_attr->hairpin_peer_vhca);
1394*2d9fd380Sjfb8856606 	ret = mlx5_glue->devx_obj_modify(sq->obj, in, sizeof(in),
1395*2d9fd380Sjfb8856606 					 out, sizeof(out));
1396*2d9fd380Sjfb8856606 	if (ret) {
1397*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to modify SQ using DevX");
1398*2d9fd380Sjfb8856606 		rte_errno = errno;
1399*2d9fd380Sjfb8856606 		return -rte_errno;
1400*2d9fd380Sjfb8856606 	}
1401*2d9fd380Sjfb8856606 	return ret;
1402*2d9fd380Sjfb8856606 }
1403*2d9fd380Sjfb8856606 
1404*2d9fd380Sjfb8856606 /**
1405*2d9fd380Sjfb8856606  * Create TIS using DevX API.
1406*2d9fd380Sjfb8856606  *
1407*2d9fd380Sjfb8856606  * @param[in] ctx
1408*2d9fd380Sjfb8856606  *   Context returned from mlx5 open_device() glue function.
1409*2d9fd380Sjfb8856606  * @param [in] tis_attr
1410*2d9fd380Sjfb8856606  *   Pointer to TIS attributes structure.
1411*2d9fd380Sjfb8856606  *
1412*2d9fd380Sjfb8856606  * @return
1413*2d9fd380Sjfb8856606  *   The DevX object created, NULL otherwise and rte_errno is set.
1414*2d9fd380Sjfb8856606  */
1415*2d9fd380Sjfb8856606 struct mlx5_devx_obj *
mlx5_devx_cmd_create_tis(void * ctx,struct mlx5_devx_tis_attr * tis_attr)1416*2d9fd380Sjfb8856606 mlx5_devx_cmd_create_tis(void *ctx,
1417*2d9fd380Sjfb8856606 			 struct mlx5_devx_tis_attr *tis_attr)
1418*2d9fd380Sjfb8856606 {
1419*2d9fd380Sjfb8856606 	uint32_t in[MLX5_ST_SZ_DW(create_tis_in)] = {0};
1420*2d9fd380Sjfb8856606 	uint32_t out[MLX5_ST_SZ_DW(create_tis_out)] = {0};
1421*2d9fd380Sjfb8856606 	struct mlx5_devx_obj *tis = NULL;
1422*2d9fd380Sjfb8856606 	void *tis_ctx;
1423*2d9fd380Sjfb8856606 
1424*2d9fd380Sjfb8856606 	tis = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*tis), 0, SOCKET_ID_ANY);
1425*2d9fd380Sjfb8856606 	if (!tis) {
1426*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to allocate TIS object");
1427*2d9fd380Sjfb8856606 		rte_errno = ENOMEM;
1428*2d9fd380Sjfb8856606 		return NULL;
1429*2d9fd380Sjfb8856606 	}
1430*2d9fd380Sjfb8856606 	MLX5_SET(create_tis_in, in, opcode, MLX5_CMD_OP_CREATE_TIS);
1431*2d9fd380Sjfb8856606 	tis_ctx = MLX5_ADDR_OF(create_tis_in, in, ctx);
1432*2d9fd380Sjfb8856606 	MLX5_SET(tisc, tis_ctx, strict_lag_tx_port_affinity,
1433*2d9fd380Sjfb8856606 		 tis_attr->strict_lag_tx_port_affinity);
1434*2d9fd380Sjfb8856606 	MLX5_SET(tisc, tis_ctx, lag_tx_port_affinity,
1435*2d9fd380Sjfb8856606 		 tis_attr->lag_tx_port_affinity);
1436*2d9fd380Sjfb8856606 	MLX5_SET(tisc, tis_ctx, prio, tis_attr->prio);
1437*2d9fd380Sjfb8856606 	MLX5_SET(tisc, tis_ctx, transport_domain,
1438*2d9fd380Sjfb8856606 		 tis_attr->transport_domain);
1439*2d9fd380Sjfb8856606 	tis->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in),
1440*2d9fd380Sjfb8856606 					      out, sizeof(out));
1441*2d9fd380Sjfb8856606 	if (!tis->obj) {
1442*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to create TIS using DevX");
1443*2d9fd380Sjfb8856606 		rte_errno = errno;
1444*2d9fd380Sjfb8856606 		mlx5_free(tis);
1445*2d9fd380Sjfb8856606 		return NULL;
1446*2d9fd380Sjfb8856606 	}
1447*2d9fd380Sjfb8856606 	tis->id = MLX5_GET(create_tis_out, out, tisn);
1448*2d9fd380Sjfb8856606 	return tis;
1449*2d9fd380Sjfb8856606 }
1450*2d9fd380Sjfb8856606 
1451*2d9fd380Sjfb8856606 /**
1452*2d9fd380Sjfb8856606  * Create transport domain using DevX API.
1453*2d9fd380Sjfb8856606  *
1454*2d9fd380Sjfb8856606  * @param[in] ctx
1455*2d9fd380Sjfb8856606  *   Context returned from mlx5 open_device() glue function.
1456*2d9fd380Sjfb8856606  * @return
1457*2d9fd380Sjfb8856606  *   The DevX object created, NULL otherwise and rte_errno is set.
1458*2d9fd380Sjfb8856606  */
1459*2d9fd380Sjfb8856606 struct mlx5_devx_obj *
mlx5_devx_cmd_create_td(void * ctx)1460*2d9fd380Sjfb8856606 mlx5_devx_cmd_create_td(void *ctx)
1461*2d9fd380Sjfb8856606 {
1462*2d9fd380Sjfb8856606 	uint32_t in[MLX5_ST_SZ_DW(alloc_transport_domain_in)] = {0};
1463*2d9fd380Sjfb8856606 	uint32_t out[MLX5_ST_SZ_DW(alloc_transport_domain_out)] = {0};
1464*2d9fd380Sjfb8856606 	struct mlx5_devx_obj *td = NULL;
1465*2d9fd380Sjfb8856606 
1466*2d9fd380Sjfb8856606 	td = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*td), 0, SOCKET_ID_ANY);
1467*2d9fd380Sjfb8856606 	if (!td) {
1468*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to allocate TD object");
1469*2d9fd380Sjfb8856606 		rte_errno = ENOMEM;
1470*2d9fd380Sjfb8856606 		return NULL;
1471*2d9fd380Sjfb8856606 	}
1472*2d9fd380Sjfb8856606 	MLX5_SET(alloc_transport_domain_in, in, opcode,
1473*2d9fd380Sjfb8856606 		 MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN);
1474*2d9fd380Sjfb8856606 	td->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in),
1475*2d9fd380Sjfb8856606 					     out, sizeof(out));
1476*2d9fd380Sjfb8856606 	if (!td->obj) {
1477*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to create TIS using DevX");
1478*2d9fd380Sjfb8856606 		rte_errno = errno;
1479*2d9fd380Sjfb8856606 		mlx5_free(td);
1480*2d9fd380Sjfb8856606 		return NULL;
1481*2d9fd380Sjfb8856606 	}
1482*2d9fd380Sjfb8856606 	td->id = MLX5_GET(alloc_transport_domain_out, out,
1483*2d9fd380Sjfb8856606 			   transport_domain);
1484*2d9fd380Sjfb8856606 	return td;
1485*2d9fd380Sjfb8856606 }
1486*2d9fd380Sjfb8856606 
1487*2d9fd380Sjfb8856606 /**
1488*2d9fd380Sjfb8856606  * Dump all flows to file.
1489*2d9fd380Sjfb8856606  *
1490*2d9fd380Sjfb8856606  * @param[in] fdb_domain
1491*2d9fd380Sjfb8856606  *   FDB domain.
1492*2d9fd380Sjfb8856606  * @param[in] rx_domain
1493*2d9fd380Sjfb8856606  *   RX domain.
1494*2d9fd380Sjfb8856606  * @param[in] tx_domain
1495*2d9fd380Sjfb8856606  *   TX domain.
1496*2d9fd380Sjfb8856606  * @param[out] file
1497*2d9fd380Sjfb8856606  *   Pointer to file stream.
1498*2d9fd380Sjfb8856606  *
1499*2d9fd380Sjfb8856606  * @return
1500*2d9fd380Sjfb8856606  *   0 on success, a nagative value otherwise.
1501*2d9fd380Sjfb8856606  */
1502*2d9fd380Sjfb8856606 int
mlx5_devx_cmd_flow_dump(void * fdb_domain __rte_unused,void * rx_domain __rte_unused,void * tx_domain __rte_unused,FILE * file __rte_unused)1503*2d9fd380Sjfb8856606 mlx5_devx_cmd_flow_dump(void *fdb_domain __rte_unused,
1504*2d9fd380Sjfb8856606 			void *rx_domain __rte_unused,
1505*2d9fd380Sjfb8856606 			void *tx_domain __rte_unused, FILE *file __rte_unused)
1506*2d9fd380Sjfb8856606 {
1507*2d9fd380Sjfb8856606 	int ret = 0;
1508*2d9fd380Sjfb8856606 
1509*2d9fd380Sjfb8856606 #ifdef HAVE_MLX5_DR_FLOW_DUMP
1510*2d9fd380Sjfb8856606 	if (fdb_domain) {
1511*2d9fd380Sjfb8856606 		ret = mlx5_glue->dr_dump_domain(file, fdb_domain);
1512*2d9fd380Sjfb8856606 		if (ret)
1513*2d9fd380Sjfb8856606 			return ret;
1514*2d9fd380Sjfb8856606 	}
1515*2d9fd380Sjfb8856606 	MLX5_ASSERT(rx_domain);
1516*2d9fd380Sjfb8856606 	ret = mlx5_glue->dr_dump_domain(file, rx_domain);
1517*2d9fd380Sjfb8856606 	if (ret)
1518*2d9fd380Sjfb8856606 		return ret;
1519*2d9fd380Sjfb8856606 	MLX5_ASSERT(tx_domain);
1520*2d9fd380Sjfb8856606 	ret = mlx5_glue->dr_dump_domain(file, tx_domain);
1521*2d9fd380Sjfb8856606 #else
1522*2d9fd380Sjfb8856606 	ret = ENOTSUP;
1523*2d9fd380Sjfb8856606 #endif
1524*2d9fd380Sjfb8856606 	return -ret;
1525*2d9fd380Sjfb8856606 }
1526*2d9fd380Sjfb8856606 
1527*2d9fd380Sjfb8856606 /*
1528*2d9fd380Sjfb8856606  * Create CQ using DevX API.
1529*2d9fd380Sjfb8856606  *
1530*2d9fd380Sjfb8856606  * @param[in] ctx
1531*2d9fd380Sjfb8856606  *   Context returned from mlx5 open_device() glue function.
1532*2d9fd380Sjfb8856606  * @param [in] attr
1533*2d9fd380Sjfb8856606  *   Pointer to CQ attributes structure.
1534*2d9fd380Sjfb8856606  *
1535*2d9fd380Sjfb8856606  * @return
1536*2d9fd380Sjfb8856606  *   The DevX object created, NULL otherwise and rte_errno is set.
1537*2d9fd380Sjfb8856606  */
1538*2d9fd380Sjfb8856606 struct mlx5_devx_obj *
mlx5_devx_cmd_create_cq(void * ctx,struct mlx5_devx_cq_attr * attr)1539*2d9fd380Sjfb8856606 mlx5_devx_cmd_create_cq(void *ctx, struct mlx5_devx_cq_attr *attr)
1540*2d9fd380Sjfb8856606 {
1541*2d9fd380Sjfb8856606 	uint32_t in[MLX5_ST_SZ_DW(create_cq_in)] = {0};
1542*2d9fd380Sjfb8856606 	uint32_t out[MLX5_ST_SZ_DW(create_cq_out)] = {0};
1543*2d9fd380Sjfb8856606 	struct mlx5_devx_obj *cq_obj = mlx5_malloc(MLX5_MEM_ZERO,
1544*2d9fd380Sjfb8856606 						   sizeof(*cq_obj),
1545*2d9fd380Sjfb8856606 						   0, SOCKET_ID_ANY);
1546*2d9fd380Sjfb8856606 	void *cqctx = MLX5_ADDR_OF(create_cq_in, in, cq_context);
1547*2d9fd380Sjfb8856606 
1548*2d9fd380Sjfb8856606 	if (!cq_obj) {
1549*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to allocate CQ object memory.");
1550*2d9fd380Sjfb8856606 		rte_errno = ENOMEM;
1551*2d9fd380Sjfb8856606 		return NULL;
1552*2d9fd380Sjfb8856606 	}
1553*2d9fd380Sjfb8856606 	MLX5_SET(create_cq_in, in, opcode, MLX5_CMD_OP_CREATE_CQ);
1554*2d9fd380Sjfb8856606 	if (attr->db_umem_valid) {
1555*2d9fd380Sjfb8856606 		MLX5_SET(cqc, cqctx, dbr_umem_valid, attr->db_umem_valid);
1556*2d9fd380Sjfb8856606 		MLX5_SET(cqc, cqctx, dbr_umem_id, attr->db_umem_id);
1557*2d9fd380Sjfb8856606 		MLX5_SET64(cqc, cqctx, dbr_addr, attr->db_umem_offset);
1558*2d9fd380Sjfb8856606 	} else {
1559*2d9fd380Sjfb8856606 		MLX5_SET64(cqc, cqctx, dbr_addr, attr->db_addr);
1560*2d9fd380Sjfb8856606 	}
1561*2d9fd380Sjfb8856606 	MLX5_SET(cqc, cqctx, cqe_sz, attr->cqe_size);
1562*2d9fd380Sjfb8856606 	MLX5_SET(cqc, cqctx, cc, attr->use_first_only);
1563*2d9fd380Sjfb8856606 	MLX5_SET(cqc, cqctx, oi, attr->overrun_ignore);
1564*2d9fd380Sjfb8856606 	MLX5_SET(cqc, cqctx, log_cq_size, attr->log_cq_size);
1565*2d9fd380Sjfb8856606 	MLX5_SET(cqc, cqctx, log_page_size, attr->log_page_size -
1566*2d9fd380Sjfb8856606 		 MLX5_ADAPTER_PAGE_SHIFT);
1567*2d9fd380Sjfb8856606 	MLX5_SET(cqc, cqctx, c_eqn, attr->eqn);
1568*2d9fd380Sjfb8856606 	MLX5_SET(cqc, cqctx, uar_page, attr->uar_page_id);
1569*2d9fd380Sjfb8856606 	MLX5_SET(cqc, cqctx, cqe_comp_en, !!attr->cqe_comp_en);
1570*2d9fd380Sjfb8856606 	MLX5_SET(cqc, cqctx, mini_cqe_res_format,
1571*2d9fd380Sjfb8856606 		 attr->mini_cqe_res_format);
1572*2d9fd380Sjfb8856606 	MLX5_SET(cqc, cqctx, mini_cqe_res_format_ext,
1573*2d9fd380Sjfb8856606 		 attr->mini_cqe_res_format_ext);
1574*2d9fd380Sjfb8856606 	MLX5_SET(cqc, cqctx, cqe_sz, attr->cqe_size);
1575*2d9fd380Sjfb8856606 	if (attr->q_umem_valid) {
1576*2d9fd380Sjfb8856606 		MLX5_SET(create_cq_in, in, cq_umem_valid, attr->q_umem_valid);
1577*2d9fd380Sjfb8856606 		MLX5_SET(create_cq_in, in, cq_umem_id, attr->q_umem_id);
1578*2d9fd380Sjfb8856606 		MLX5_SET64(create_cq_in, in, cq_umem_offset,
1579*2d9fd380Sjfb8856606 			   attr->q_umem_offset);
1580*2d9fd380Sjfb8856606 	}
1581*2d9fd380Sjfb8856606 	cq_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out,
1582*2d9fd380Sjfb8856606 						 sizeof(out));
1583*2d9fd380Sjfb8856606 	if (!cq_obj->obj) {
1584*2d9fd380Sjfb8856606 		rte_errno = errno;
1585*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to create CQ using DevX errno=%d.", errno);
1586*2d9fd380Sjfb8856606 		mlx5_free(cq_obj);
1587*2d9fd380Sjfb8856606 		return NULL;
1588*2d9fd380Sjfb8856606 	}
1589*2d9fd380Sjfb8856606 	cq_obj->id = MLX5_GET(create_cq_out, out, cqn);
1590*2d9fd380Sjfb8856606 	return cq_obj;
1591*2d9fd380Sjfb8856606 }
1592*2d9fd380Sjfb8856606 
1593*2d9fd380Sjfb8856606 /**
1594*2d9fd380Sjfb8856606  * Create VIRTQ using DevX API.
1595*2d9fd380Sjfb8856606  *
1596*2d9fd380Sjfb8856606  * @param[in] ctx
1597*2d9fd380Sjfb8856606  *   Context returned from mlx5 open_device() glue function.
1598*2d9fd380Sjfb8856606  * @param [in] attr
1599*2d9fd380Sjfb8856606  *   Pointer to VIRTQ attributes structure.
1600*2d9fd380Sjfb8856606  *
1601*2d9fd380Sjfb8856606  * @return
1602*2d9fd380Sjfb8856606  *   The DevX object created, NULL otherwise and rte_errno is set.
1603*2d9fd380Sjfb8856606  */
1604*2d9fd380Sjfb8856606 struct mlx5_devx_obj *
mlx5_devx_cmd_create_virtq(void * ctx,struct mlx5_devx_virtq_attr * attr)1605*2d9fd380Sjfb8856606 mlx5_devx_cmd_create_virtq(void *ctx,
1606*2d9fd380Sjfb8856606 			   struct mlx5_devx_virtq_attr *attr)
1607*2d9fd380Sjfb8856606 {
1608*2d9fd380Sjfb8856606 	uint32_t in[MLX5_ST_SZ_DW(create_virtq_in)] = {0};
1609*2d9fd380Sjfb8856606 	uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
1610*2d9fd380Sjfb8856606 	struct mlx5_devx_obj *virtq_obj = mlx5_malloc(MLX5_MEM_ZERO,
1611*2d9fd380Sjfb8856606 						     sizeof(*virtq_obj),
1612*2d9fd380Sjfb8856606 						     0, SOCKET_ID_ANY);
1613*2d9fd380Sjfb8856606 	void *virtq = MLX5_ADDR_OF(create_virtq_in, in, virtq);
1614*2d9fd380Sjfb8856606 	void *hdr = MLX5_ADDR_OF(create_virtq_in, in, hdr);
1615*2d9fd380Sjfb8856606 	void *virtctx = MLX5_ADDR_OF(virtio_net_q, virtq, virtio_q_context);
1616*2d9fd380Sjfb8856606 
1617*2d9fd380Sjfb8856606 	if (!virtq_obj) {
1618*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to allocate virtq data.");
1619*2d9fd380Sjfb8856606 		rte_errno = ENOMEM;
1620*2d9fd380Sjfb8856606 		return NULL;
1621*2d9fd380Sjfb8856606 	}
1622*2d9fd380Sjfb8856606 	MLX5_SET(general_obj_in_cmd_hdr, hdr, opcode,
1623*2d9fd380Sjfb8856606 		 MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
1624*2d9fd380Sjfb8856606 	MLX5_SET(general_obj_in_cmd_hdr, hdr, obj_type,
1625*2d9fd380Sjfb8856606 		 MLX5_GENERAL_OBJ_TYPE_VIRTQ);
1626*2d9fd380Sjfb8856606 	MLX5_SET16(virtio_net_q, virtq, hw_available_index,
1627*2d9fd380Sjfb8856606 		   attr->hw_available_index);
1628*2d9fd380Sjfb8856606 	MLX5_SET16(virtio_net_q, virtq, hw_used_index, attr->hw_used_index);
1629*2d9fd380Sjfb8856606 	MLX5_SET16(virtio_net_q, virtq, tso_ipv4, attr->tso_ipv4);
1630*2d9fd380Sjfb8856606 	MLX5_SET16(virtio_net_q, virtq, tso_ipv6, attr->tso_ipv6);
1631*2d9fd380Sjfb8856606 	MLX5_SET16(virtio_net_q, virtq, tx_csum, attr->tx_csum);
1632*2d9fd380Sjfb8856606 	MLX5_SET16(virtio_net_q, virtq, rx_csum, attr->rx_csum);
1633*2d9fd380Sjfb8856606 	MLX5_SET16(virtio_q, virtctx, virtio_version_1_0,
1634*2d9fd380Sjfb8856606 		   attr->virtio_version_1_0);
1635*2d9fd380Sjfb8856606 	MLX5_SET16(virtio_q, virtctx, event_mode, attr->event_mode);
1636*2d9fd380Sjfb8856606 	MLX5_SET(virtio_q, virtctx, event_qpn_or_msix, attr->qp_id);
1637*2d9fd380Sjfb8856606 	MLX5_SET64(virtio_q, virtctx, desc_addr, attr->desc_addr);
1638*2d9fd380Sjfb8856606 	MLX5_SET64(virtio_q, virtctx, used_addr, attr->used_addr);
1639*2d9fd380Sjfb8856606 	MLX5_SET64(virtio_q, virtctx, available_addr, attr->available_addr);
1640*2d9fd380Sjfb8856606 	MLX5_SET16(virtio_q, virtctx, queue_index, attr->queue_index);
1641*2d9fd380Sjfb8856606 	MLX5_SET16(virtio_q, virtctx, queue_size, attr->q_size);
1642*2d9fd380Sjfb8856606 	MLX5_SET(virtio_q, virtctx, virtio_q_mkey, attr->mkey);
1643*2d9fd380Sjfb8856606 	MLX5_SET(virtio_q, virtctx, umem_1_id, attr->umems[0].id);
1644*2d9fd380Sjfb8856606 	MLX5_SET(virtio_q, virtctx, umem_1_size, attr->umems[0].size);
1645*2d9fd380Sjfb8856606 	MLX5_SET64(virtio_q, virtctx, umem_1_offset, attr->umems[0].offset);
1646*2d9fd380Sjfb8856606 	MLX5_SET(virtio_q, virtctx, umem_2_id, attr->umems[1].id);
1647*2d9fd380Sjfb8856606 	MLX5_SET(virtio_q, virtctx, umem_2_size, attr->umems[1].size);
1648*2d9fd380Sjfb8856606 	MLX5_SET64(virtio_q, virtctx, umem_2_offset, attr->umems[1].offset);
1649*2d9fd380Sjfb8856606 	MLX5_SET(virtio_q, virtctx, umem_3_id, attr->umems[2].id);
1650*2d9fd380Sjfb8856606 	MLX5_SET(virtio_q, virtctx, umem_3_size, attr->umems[2].size);
1651*2d9fd380Sjfb8856606 	MLX5_SET64(virtio_q, virtctx, umem_3_offset, attr->umems[2].offset);
1652*2d9fd380Sjfb8856606 	MLX5_SET(virtio_q, virtctx, counter_set_id, attr->counters_obj_id);
1653*2d9fd380Sjfb8856606 	MLX5_SET(virtio_q, virtctx, pd, attr->pd);
1654*2d9fd380Sjfb8856606 	MLX5_SET(virtio_net_q, virtq, tisn_or_qpn, attr->tis_id);
1655*2d9fd380Sjfb8856606 	virtq_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out,
1656*2d9fd380Sjfb8856606 						    sizeof(out));
1657*2d9fd380Sjfb8856606 	if (!virtq_obj->obj) {
1658*2d9fd380Sjfb8856606 		rte_errno = errno;
1659*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to create VIRTQ Obj using DevX.");
1660*2d9fd380Sjfb8856606 		mlx5_free(virtq_obj);
1661*2d9fd380Sjfb8856606 		return NULL;
1662*2d9fd380Sjfb8856606 	}
1663*2d9fd380Sjfb8856606 	virtq_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
1664*2d9fd380Sjfb8856606 	return virtq_obj;
1665*2d9fd380Sjfb8856606 }
1666*2d9fd380Sjfb8856606 
1667*2d9fd380Sjfb8856606 /**
1668*2d9fd380Sjfb8856606  * Modify VIRTQ using DevX API.
1669*2d9fd380Sjfb8856606  *
1670*2d9fd380Sjfb8856606  * @param[in] virtq_obj
1671*2d9fd380Sjfb8856606  *   Pointer to virtq object structure.
1672*2d9fd380Sjfb8856606  * @param [in] attr
1673*2d9fd380Sjfb8856606  *   Pointer to modify virtq attributes structure.
1674*2d9fd380Sjfb8856606  *
1675*2d9fd380Sjfb8856606  * @return
1676*2d9fd380Sjfb8856606  *   0 on success, a negative errno value otherwise and rte_errno is set.
1677*2d9fd380Sjfb8856606  */
1678*2d9fd380Sjfb8856606 int
mlx5_devx_cmd_modify_virtq(struct mlx5_devx_obj * virtq_obj,struct mlx5_devx_virtq_attr * attr)1679*2d9fd380Sjfb8856606 mlx5_devx_cmd_modify_virtq(struct mlx5_devx_obj *virtq_obj,
1680*2d9fd380Sjfb8856606 			   struct mlx5_devx_virtq_attr *attr)
1681*2d9fd380Sjfb8856606 {
1682*2d9fd380Sjfb8856606 	uint32_t in[MLX5_ST_SZ_DW(create_virtq_in)] = {0};
1683*2d9fd380Sjfb8856606 	uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
1684*2d9fd380Sjfb8856606 	void *virtq = MLX5_ADDR_OF(create_virtq_in, in, virtq);
1685*2d9fd380Sjfb8856606 	void *hdr = MLX5_ADDR_OF(create_virtq_in, in, hdr);
1686*2d9fd380Sjfb8856606 	void *virtctx = MLX5_ADDR_OF(virtio_net_q, virtq, virtio_q_context);
1687*2d9fd380Sjfb8856606 	int ret;
1688*2d9fd380Sjfb8856606 
1689*2d9fd380Sjfb8856606 	MLX5_SET(general_obj_in_cmd_hdr, hdr, opcode,
1690*2d9fd380Sjfb8856606 		 MLX5_CMD_OP_MODIFY_GENERAL_OBJECT);
1691*2d9fd380Sjfb8856606 	MLX5_SET(general_obj_in_cmd_hdr, hdr, obj_type,
1692*2d9fd380Sjfb8856606 		 MLX5_GENERAL_OBJ_TYPE_VIRTQ);
1693*2d9fd380Sjfb8856606 	MLX5_SET(general_obj_in_cmd_hdr, hdr, obj_id, virtq_obj->id);
1694*2d9fd380Sjfb8856606 	MLX5_SET64(virtio_net_q, virtq, modify_field_select, attr->type);
1695*2d9fd380Sjfb8856606 	MLX5_SET16(virtio_q, virtctx, queue_index, attr->queue_index);
1696*2d9fd380Sjfb8856606 	switch (attr->type) {
1697*2d9fd380Sjfb8856606 	case MLX5_VIRTQ_MODIFY_TYPE_STATE:
1698*2d9fd380Sjfb8856606 		MLX5_SET16(virtio_net_q, virtq, state, attr->state);
1699*2d9fd380Sjfb8856606 		break;
1700*2d9fd380Sjfb8856606 	case MLX5_VIRTQ_MODIFY_TYPE_DIRTY_BITMAP_PARAMS:
1701*2d9fd380Sjfb8856606 		MLX5_SET(virtio_net_q, virtq, dirty_bitmap_mkey,
1702*2d9fd380Sjfb8856606 			 attr->dirty_bitmap_mkey);
1703*2d9fd380Sjfb8856606 		MLX5_SET64(virtio_net_q, virtq, dirty_bitmap_addr,
1704*2d9fd380Sjfb8856606 			 attr->dirty_bitmap_addr);
1705*2d9fd380Sjfb8856606 		MLX5_SET(virtio_net_q, virtq, dirty_bitmap_size,
1706*2d9fd380Sjfb8856606 			 attr->dirty_bitmap_size);
1707*2d9fd380Sjfb8856606 		break;
1708*2d9fd380Sjfb8856606 	case MLX5_VIRTQ_MODIFY_TYPE_DIRTY_BITMAP_DUMP_ENABLE:
1709*2d9fd380Sjfb8856606 		MLX5_SET(virtio_net_q, virtq, dirty_bitmap_dump_enable,
1710*2d9fd380Sjfb8856606 			 attr->dirty_bitmap_dump_enable);
1711*2d9fd380Sjfb8856606 		break;
1712*2d9fd380Sjfb8856606 	default:
1713*2d9fd380Sjfb8856606 		rte_errno = EINVAL;
1714*2d9fd380Sjfb8856606 		return -rte_errno;
1715*2d9fd380Sjfb8856606 	}
1716*2d9fd380Sjfb8856606 	ret = mlx5_glue->devx_obj_modify(virtq_obj->obj, in, sizeof(in),
1717*2d9fd380Sjfb8856606 					 out, sizeof(out));
1718*2d9fd380Sjfb8856606 	if (ret) {
1719*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to modify VIRTQ using DevX.");
1720*2d9fd380Sjfb8856606 		rte_errno = errno;
1721*2d9fd380Sjfb8856606 		return -rte_errno;
1722*2d9fd380Sjfb8856606 	}
1723*2d9fd380Sjfb8856606 	return ret;
1724*2d9fd380Sjfb8856606 }
1725*2d9fd380Sjfb8856606 
1726*2d9fd380Sjfb8856606 /**
1727*2d9fd380Sjfb8856606  * Query VIRTQ using DevX API.
1728*2d9fd380Sjfb8856606  *
1729*2d9fd380Sjfb8856606  * @param[in] virtq_obj
1730*2d9fd380Sjfb8856606  *   Pointer to virtq object structure.
1731*2d9fd380Sjfb8856606  * @param [in/out] attr
1732*2d9fd380Sjfb8856606  *   Pointer to virtq attributes structure.
1733*2d9fd380Sjfb8856606  *
1734*2d9fd380Sjfb8856606  * @return
1735*2d9fd380Sjfb8856606  *   0 on success, a negative errno value otherwise and rte_errno is set.
1736*2d9fd380Sjfb8856606  */
1737*2d9fd380Sjfb8856606 int
mlx5_devx_cmd_query_virtq(struct mlx5_devx_obj * virtq_obj,struct mlx5_devx_virtq_attr * attr)1738*2d9fd380Sjfb8856606 mlx5_devx_cmd_query_virtq(struct mlx5_devx_obj *virtq_obj,
1739*2d9fd380Sjfb8856606 			   struct mlx5_devx_virtq_attr *attr)
1740*2d9fd380Sjfb8856606 {
1741*2d9fd380Sjfb8856606 	uint32_t in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {0};
1742*2d9fd380Sjfb8856606 	uint32_t out[MLX5_ST_SZ_DW(query_virtq_out)] = {0};
1743*2d9fd380Sjfb8856606 	void *hdr = MLX5_ADDR_OF(query_virtq_out, in, hdr);
1744*2d9fd380Sjfb8856606 	void *virtq = MLX5_ADDR_OF(query_virtq_out, out, virtq);
1745*2d9fd380Sjfb8856606 	int ret;
1746*2d9fd380Sjfb8856606 
1747*2d9fd380Sjfb8856606 	MLX5_SET(general_obj_in_cmd_hdr, hdr, opcode,
1748*2d9fd380Sjfb8856606 		 MLX5_CMD_OP_QUERY_GENERAL_OBJECT);
1749*2d9fd380Sjfb8856606 	MLX5_SET(general_obj_in_cmd_hdr, hdr, obj_type,
1750*2d9fd380Sjfb8856606 		 MLX5_GENERAL_OBJ_TYPE_VIRTQ);
1751*2d9fd380Sjfb8856606 	MLX5_SET(general_obj_in_cmd_hdr, hdr, obj_id, virtq_obj->id);
1752*2d9fd380Sjfb8856606 	ret = mlx5_glue->devx_obj_query(virtq_obj->obj, in, sizeof(in),
1753*2d9fd380Sjfb8856606 					 out, sizeof(out));
1754*2d9fd380Sjfb8856606 	if (ret) {
1755*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to modify VIRTQ using DevX.");
1756*2d9fd380Sjfb8856606 		rte_errno = errno;
1757*2d9fd380Sjfb8856606 		return -errno;
1758*2d9fd380Sjfb8856606 	}
1759*2d9fd380Sjfb8856606 	attr->hw_available_index = MLX5_GET16(virtio_net_q, virtq,
1760*2d9fd380Sjfb8856606 					      hw_available_index);
1761*2d9fd380Sjfb8856606 	attr->hw_used_index = MLX5_GET16(virtio_net_q, virtq, hw_used_index);
1762*2d9fd380Sjfb8856606 	attr->state = MLX5_GET16(virtio_net_q, virtq, state);
1763*2d9fd380Sjfb8856606 	attr->error_type = MLX5_GET16(virtio_net_q, virtq,
1764*2d9fd380Sjfb8856606 				      virtio_q_context.error_type);
1765*2d9fd380Sjfb8856606 	return ret;
1766*2d9fd380Sjfb8856606 }
1767*2d9fd380Sjfb8856606 
1768*2d9fd380Sjfb8856606 /**
1769*2d9fd380Sjfb8856606  * Create QP using DevX API.
1770*2d9fd380Sjfb8856606  *
1771*2d9fd380Sjfb8856606  * @param[in] ctx
1772*2d9fd380Sjfb8856606  *   Context returned from mlx5 open_device() glue function.
1773*2d9fd380Sjfb8856606  * @param [in] attr
1774*2d9fd380Sjfb8856606  *   Pointer to QP attributes structure.
1775*2d9fd380Sjfb8856606  *
1776*2d9fd380Sjfb8856606  * @return
1777*2d9fd380Sjfb8856606  *   The DevX object created, NULL otherwise and rte_errno is set.
1778*2d9fd380Sjfb8856606  */
1779*2d9fd380Sjfb8856606 struct mlx5_devx_obj *
mlx5_devx_cmd_create_qp(void * ctx,struct mlx5_devx_qp_attr * attr)1780*2d9fd380Sjfb8856606 mlx5_devx_cmd_create_qp(void *ctx,
1781*2d9fd380Sjfb8856606 			struct mlx5_devx_qp_attr *attr)
1782*2d9fd380Sjfb8856606 {
1783*2d9fd380Sjfb8856606 	uint32_t in[MLX5_ST_SZ_DW(create_qp_in)] = {0};
1784*2d9fd380Sjfb8856606 	uint32_t out[MLX5_ST_SZ_DW(create_qp_out)] = {0};
1785*2d9fd380Sjfb8856606 	struct mlx5_devx_obj *qp_obj = mlx5_malloc(MLX5_MEM_ZERO,
1786*2d9fd380Sjfb8856606 						   sizeof(*qp_obj),
1787*2d9fd380Sjfb8856606 						   0, SOCKET_ID_ANY);
1788*2d9fd380Sjfb8856606 	void *qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
1789*2d9fd380Sjfb8856606 
1790*2d9fd380Sjfb8856606 	if (!qp_obj) {
1791*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to allocate QP data.");
1792*2d9fd380Sjfb8856606 		rte_errno = ENOMEM;
1793*2d9fd380Sjfb8856606 		return NULL;
1794*2d9fd380Sjfb8856606 	}
1795*2d9fd380Sjfb8856606 	MLX5_SET(create_qp_in, in, opcode, MLX5_CMD_OP_CREATE_QP);
1796*2d9fd380Sjfb8856606 	MLX5_SET(qpc, qpc, st, MLX5_QP_ST_RC);
1797*2d9fd380Sjfb8856606 	MLX5_SET(qpc, qpc, pd, attr->pd);
1798*2d9fd380Sjfb8856606 	if (attr->uar_index) {
1799*2d9fd380Sjfb8856606 		MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);
1800*2d9fd380Sjfb8856606 		MLX5_SET(qpc, qpc, uar_page, attr->uar_index);
1801*2d9fd380Sjfb8856606 		MLX5_SET(qpc, qpc, log_page_size, attr->log_page_size -
1802*2d9fd380Sjfb8856606 			 MLX5_ADAPTER_PAGE_SHIFT);
1803*2d9fd380Sjfb8856606 		if (attr->sq_size) {
1804*2d9fd380Sjfb8856606 			MLX5_ASSERT(RTE_IS_POWER_OF_2(attr->sq_size));
1805*2d9fd380Sjfb8856606 			MLX5_SET(qpc, qpc, cqn_snd, attr->cqn);
1806*2d9fd380Sjfb8856606 			MLX5_SET(qpc, qpc, log_sq_size,
1807*2d9fd380Sjfb8856606 				 rte_log2_u32(attr->sq_size));
1808*2d9fd380Sjfb8856606 		} else {
1809*2d9fd380Sjfb8856606 			MLX5_SET(qpc, qpc, no_sq, 1);
1810*2d9fd380Sjfb8856606 		}
1811*2d9fd380Sjfb8856606 		if (attr->rq_size) {
1812*2d9fd380Sjfb8856606 			MLX5_ASSERT(RTE_IS_POWER_OF_2(attr->rq_size));
1813*2d9fd380Sjfb8856606 			MLX5_SET(qpc, qpc, cqn_rcv, attr->cqn);
1814*2d9fd380Sjfb8856606 			MLX5_SET(qpc, qpc, log_rq_stride, attr->log_rq_stride -
1815*2d9fd380Sjfb8856606 				 MLX5_LOG_RQ_STRIDE_SHIFT);
1816*2d9fd380Sjfb8856606 			MLX5_SET(qpc, qpc, log_rq_size,
1817*2d9fd380Sjfb8856606 				 rte_log2_u32(attr->rq_size));
1818*2d9fd380Sjfb8856606 			MLX5_SET(qpc, qpc, rq_type, MLX5_NON_ZERO_RQ);
1819*2d9fd380Sjfb8856606 		} else {
1820*2d9fd380Sjfb8856606 			MLX5_SET(qpc, qpc, rq_type, MLX5_ZERO_LEN_RQ);
1821*2d9fd380Sjfb8856606 		}
1822*2d9fd380Sjfb8856606 		if (attr->dbr_umem_valid) {
1823*2d9fd380Sjfb8856606 			MLX5_SET(qpc, qpc, dbr_umem_valid,
1824*2d9fd380Sjfb8856606 				 attr->dbr_umem_valid);
1825*2d9fd380Sjfb8856606 			MLX5_SET(qpc, qpc, dbr_umem_id, attr->dbr_umem_id);
1826*2d9fd380Sjfb8856606 		}
1827*2d9fd380Sjfb8856606 		MLX5_SET64(qpc, qpc, dbr_addr, attr->dbr_address);
1828*2d9fd380Sjfb8856606 		MLX5_SET64(create_qp_in, in, wq_umem_offset,
1829*2d9fd380Sjfb8856606 			   attr->wq_umem_offset);
1830*2d9fd380Sjfb8856606 		MLX5_SET(create_qp_in, in, wq_umem_id, attr->wq_umem_id);
1831*2d9fd380Sjfb8856606 		MLX5_SET(create_qp_in, in, wq_umem_valid, 1);
1832*2d9fd380Sjfb8856606 	} else {
1833*2d9fd380Sjfb8856606 		/* Special QP to be managed by FW - no SQ\RQ\CQ\UAR\DB rec. */
1834*2d9fd380Sjfb8856606 		MLX5_SET(qpc, qpc, rq_type, MLX5_ZERO_LEN_RQ);
1835*2d9fd380Sjfb8856606 		MLX5_SET(qpc, qpc, no_sq, 1);
1836*2d9fd380Sjfb8856606 	}
1837*2d9fd380Sjfb8856606 	qp_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out,
1838*2d9fd380Sjfb8856606 						 sizeof(out));
1839*2d9fd380Sjfb8856606 	if (!qp_obj->obj) {
1840*2d9fd380Sjfb8856606 		rte_errno = errno;
1841*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to create QP Obj using DevX.");
1842*2d9fd380Sjfb8856606 		mlx5_free(qp_obj);
1843*2d9fd380Sjfb8856606 		return NULL;
1844*2d9fd380Sjfb8856606 	}
1845*2d9fd380Sjfb8856606 	qp_obj->id = MLX5_GET(create_qp_out, out, qpn);
1846*2d9fd380Sjfb8856606 	return qp_obj;
1847*2d9fd380Sjfb8856606 }
1848*2d9fd380Sjfb8856606 
1849*2d9fd380Sjfb8856606 /**
1850*2d9fd380Sjfb8856606  * Modify QP using DevX API.
1851*2d9fd380Sjfb8856606  * Currently supports only force loop-back QP.
1852*2d9fd380Sjfb8856606  *
1853*2d9fd380Sjfb8856606  * @param[in] qp
1854*2d9fd380Sjfb8856606  *   Pointer to QP object structure.
1855*2d9fd380Sjfb8856606  * @param [in] qp_st_mod_op
1856*2d9fd380Sjfb8856606  *   The QP state modification operation.
1857*2d9fd380Sjfb8856606  * @param [in] remote_qp_id
1858*2d9fd380Sjfb8856606  *   The remote QP ID for MLX5_CMD_OP_INIT2RTR_QP operation.
1859*2d9fd380Sjfb8856606  *
1860*2d9fd380Sjfb8856606  * @return
1861*2d9fd380Sjfb8856606  *   0 on success, a negative errno value otherwise and rte_errno is set.
1862*2d9fd380Sjfb8856606  */
1863*2d9fd380Sjfb8856606 int
mlx5_devx_cmd_modify_qp_state(struct mlx5_devx_obj * qp,uint32_t qp_st_mod_op,uint32_t remote_qp_id)1864*2d9fd380Sjfb8856606 mlx5_devx_cmd_modify_qp_state(struct mlx5_devx_obj *qp, uint32_t qp_st_mod_op,
1865*2d9fd380Sjfb8856606 			      uint32_t remote_qp_id)
1866*2d9fd380Sjfb8856606 {
1867*2d9fd380Sjfb8856606 	union {
1868*2d9fd380Sjfb8856606 		uint32_t rst2init[MLX5_ST_SZ_DW(rst2init_qp_in)];
1869*2d9fd380Sjfb8856606 		uint32_t init2rtr[MLX5_ST_SZ_DW(init2rtr_qp_in)];
1870*2d9fd380Sjfb8856606 		uint32_t rtr2rts[MLX5_ST_SZ_DW(rtr2rts_qp_in)];
1871*2d9fd380Sjfb8856606 	} in;
1872*2d9fd380Sjfb8856606 	union {
1873*2d9fd380Sjfb8856606 		uint32_t rst2init[MLX5_ST_SZ_DW(rst2init_qp_out)];
1874*2d9fd380Sjfb8856606 		uint32_t init2rtr[MLX5_ST_SZ_DW(init2rtr_qp_out)];
1875*2d9fd380Sjfb8856606 		uint32_t rtr2rts[MLX5_ST_SZ_DW(rtr2rts_qp_out)];
1876*2d9fd380Sjfb8856606 	} out;
1877*2d9fd380Sjfb8856606 	void *qpc;
1878*2d9fd380Sjfb8856606 	int ret;
1879*2d9fd380Sjfb8856606 	unsigned int inlen;
1880*2d9fd380Sjfb8856606 	unsigned int outlen;
1881*2d9fd380Sjfb8856606 
1882*2d9fd380Sjfb8856606 	memset(&in, 0, sizeof(in));
1883*2d9fd380Sjfb8856606 	memset(&out, 0, sizeof(out));
1884*2d9fd380Sjfb8856606 	MLX5_SET(rst2init_qp_in, &in, opcode, qp_st_mod_op);
1885*2d9fd380Sjfb8856606 	switch (qp_st_mod_op) {
1886*2d9fd380Sjfb8856606 	case MLX5_CMD_OP_RST2INIT_QP:
1887*2d9fd380Sjfb8856606 		MLX5_SET(rst2init_qp_in, &in, qpn, qp->id);
1888*2d9fd380Sjfb8856606 		qpc = MLX5_ADDR_OF(rst2init_qp_in, &in, qpc);
1889*2d9fd380Sjfb8856606 		MLX5_SET(qpc, qpc, primary_address_path.vhca_port_num, 1);
1890*2d9fd380Sjfb8856606 		MLX5_SET(qpc, qpc, rre, 1);
1891*2d9fd380Sjfb8856606 		MLX5_SET(qpc, qpc, rwe, 1);
1892*2d9fd380Sjfb8856606 		MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);
1893*2d9fd380Sjfb8856606 		inlen = sizeof(in.rst2init);
1894*2d9fd380Sjfb8856606 		outlen = sizeof(out.rst2init);
1895*2d9fd380Sjfb8856606 		break;
1896*2d9fd380Sjfb8856606 	case MLX5_CMD_OP_INIT2RTR_QP:
1897*2d9fd380Sjfb8856606 		MLX5_SET(init2rtr_qp_in, &in, qpn, qp->id);
1898*2d9fd380Sjfb8856606 		qpc = MLX5_ADDR_OF(init2rtr_qp_in, &in, qpc);
1899*2d9fd380Sjfb8856606 		MLX5_SET(qpc, qpc, primary_address_path.fl, 1);
1900*2d9fd380Sjfb8856606 		MLX5_SET(qpc, qpc, primary_address_path.vhca_port_num, 1);
1901*2d9fd380Sjfb8856606 		MLX5_SET(qpc, qpc, mtu, 1);
1902*2d9fd380Sjfb8856606 		MLX5_SET(qpc, qpc, log_msg_max, 30);
1903*2d9fd380Sjfb8856606 		MLX5_SET(qpc, qpc, remote_qpn, remote_qp_id);
1904*2d9fd380Sjfb8856606 		MLX5_SET(qpc, qpc, min_rnr_nak, 0);
1905*2d9fd380Sjfb8856606 		inlen = sizeof(in.init2rtr);
1906*2d9fd380Sjfb8856606 		outlen = sizeof(out.init2rtr);
1907*2d9fd380Sjfb8856606 		break;
1908*2d9fd380Sjfb8856606 	case MLX5_CMD_OP_RTR2RTS_QP:
1909*2d9fd380Sjfb8856606 		qpc = MLX5_ADDR_OF(rtr2rts_qp_in, &in, qpc);
1910*2d9fd380Sjfb8856606 		MLX5_SET(rtr2rts_qp_in, &in, qpn, qp->id);
1911*2d9fd380Sjfb8856606 		MLX5_SET(qpc, qpc, primary_address_path.ack_timeout, 14);
1912*2d9fd380Sjfb8856606 		MLX5_SET(qpc, qpc, log_ack_req_freq, 0);
1913*2d9fd380Sjfb8856606 		MLX5_SET(qpc, qpc, retry_count, 7);
1914*2d9fd380Sjfb8856606 		MLX5_SET(qpc, qpc, rnr_retry, 7);
1915*2d9fd380Sjfb8856606 		inlen = sizeof(in.rtr2rts);
1916*2d9fd380Sjfb8856606 		outlen = sizeof(out.rtr2rts);
1917*2d9fd380Sjfb8856606 		break;
1918*2d9fd380Sjfb8856606 	default:
1919*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Invalid or unsupported QP modify op %u.",
1920*2d9fd380Sjfb8856606 			qp_st_mod_op);
1921*2d9fd380Sjfb8856606 		rte_errno = EINVAL;
1922*2d9fd380Sjfb8856606 		return -rte_errno;
1923*2d9fd380Sjfb8856606 	}
1924*2d9fd380Sjfb8856606 	ret = mlx5_glue->devx_obj_modify(qp->obj, &in, inlen, &out, outlen);
1925*2d9fd380Sjfb8856606 	if (ret) {
1926*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to modify QP using DevX.");
1927*2d9fd380Sjfb8856606 		rte_errno = errno;
1928*2d9fd380Sjfb8856606 		return -rte_errno;
1929*2d9fd380Sjfb8856606 	}
1930*2d9fd380Sjfb8856606 	return ret;
1931*2d9fd380Sjfb8856606 }
1932*2d9fd380Sjfb8856606 
1933*2d9fd380Sjfb8856606 struct mlx5_devx_obj *
mlx5_devx_cmd_create_virtio_q_counters(void * ctx)1934*2d9fd380Sjfb8856606 mlx5_devx_cmd_create_virtio_q_counters(void *ctx)
1935*2d9fd380Sjfb8856606 {
1936*2d9fd380Sjfb8856606 	uint32_t in[MLX5_ST_SZ_DW(create_virtio_q_counters_in)] = {0};
1937*2d9fd380Sjfb8856606 	uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
1938*2d9fd380Sjfb8856606 	struct mlx5_devx_obj *couners_obj = mlx5_malloc(MLX5_MEM_ZERO,
1939*2d9fd380Sjfb8856606 						       sizeof(*couners_obj), 0,
1940*2d9fd380Sjfb8856606 						       SOCKET_ID_ANY);
1941*2d9fd380Sjfb8856606 	void *hdr = MLX5_ADDR_OF(create_virtio_q_counters_in, in, hdr);
1942*2d9fd380Sjfb8856606 
1943*2d9fd380Sjfb8856606 	if (!couners_obj) {
1944*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to allocate virtio queue counters data.");
1945*2d9fd380Sjfb8856606 		rte_errno = ENOMEM;
1946*2d9fd380Sjfb8856606 		return NULL;
1947*2d9fd380Sjfb8856606 	}
1948*2d9fd380Sjfb8856606 	MLX5_SET(general_obj_in_cmd_hdr, hdr, opcode,
1949*2d9fd380Sjfb8856606 		 MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
1950*2d9fd380Sjfb8856606 	MLX5_SET(general_obj_in_cmd_hdr, hdr, obj_type,
1951*2d9fd380Sjfb8856606 		 MLX5_GENERAL_OBJ_TYPE_VIRTIO_Q_COUNTERS);
1952*2d9fd380Sjfb8856606 	couners_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out,
1953*2d9fd380Sjfb8856606 						      sizeof(out));
1954*2d9fd380Sjfb8856606 	if (!couners_obj->obj) {
1955*2d9fd380Sjfb8856606 		rte_errno = errno;
1956*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to create virtio queue counters Obj using"
1957*2d9fd380Sjfb8856606 			" DevX.");
1958*2d9fd380Sjfb8856606 		mlx5_free(couners_obj);
1959*2d9fd380Sjfb8856606 		return NULL;
1960*2d9fd380Sjfb8856606 	}
1961*2d9fd380Sjfb8856606 	couners_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
1962*2d9fd380Sjfb8856606 	return couners_obj;
1963*2d9fd380Sjfb8856606 }
1964*2d9fd380Sjfb8856606 
1965*2d9fd380Sjfb8856606 int
mlx5_devx_cmd_query_virtio_q_counters(struct mlx5_devx_obj * couners_obj,struct mlx5_devx_virtio_q_couners_attr * attr)1966*2d9fd380Sjfb8856606 mlx5_devx_cmd_query_virtio_q_counters(struct mlx5_devx_obj *couners_obj,
1967*2d9fd380Sjfb8856606 				   struct mlx5_devx_virtio_q_couners_attr *attr)
1968*2d9fd380Sjfb8856606 {
1969*2d9fd380Sjfb8856606 	uint32_t in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {0};
1970*2d9fd380Sjfb8856606 	uint32_t out[MLX5_ST_SZ_DW(query_virtio_q_counters_out)] = {0};
1971*2d9fd380Sjfb8856606 	void *hdr = MLX5_ADDR_OF(query_virtio_q_counters_out, in, hdr);
1972*2d9fd380Sjfb8856606 	void *virtio_q_counters = MLX5_ADDR_OF(query_virtio_q_counters_out, out,
1973*2d9fd380Sjfb8856606 					       virtio_q_counters);
1974*2d9fd380Sjfb8856606 	int ret;
1975*2d9fd380Sjfb8856606 
1976*2d9fd380Sjfb8856606 	MLX5_SET(general_obj_in_cmd_hdr, hdr, opcode,
1977*2d9fd380Sjfb8856606 		 MLX5_CMD_OP_QUERY_GENERAL_OBJECT);
1978*2d9fd380Sjfb8856606 	MLX5_SET(general_obj_in_cmd_hdr, hdr, obj_type,
1979*2d9fd380Sjfb8856606 		 MLX5_GENERAL_OBJ_TYPE_VIRTIO_Q_COUNTERS);
1980*2d9fd380Sjfb8856606 	MLX5_SET(general_obj_in_cmd_hdr, hdr, obj_id, couners_obj->id);
1981*2d9fd380Sjfb8856606 	ret = mlx5_glue->devx_obj_query(couners_obj->obj, in, sizeof(in), out,
1982*2d9fd380Sjfb8856606 					sizeof(out));
1983*2d9fd380Sjfb8856606 	if (ret) {
1984*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to query virtio q counters using DevX.");
1985*2d9fd380Sjfb8856606 		rte_errno = errno;
1986*2d9fd380Sjfb8856606 		return -errno;
1987*2d9fd380Sjfb8856606 	}
1988*2d9fd380Sjfb8856606 	attr->received_desc = MLX5_GET64(virtio_q_counters, virtio_q_counters,
1989*2d9fd380Sjfb8856606 					 received_desc);
1990*2d9fd380Sjfb8856606 	attr->completed_desc = MLX5_GET64(virtio_q_counters, virtio_q_counters,
1991*2d9fd380Sjfb8856606 					  completed_desc);
1992*2d9fd380Sjfb8856606 	attr->error_cqes = MLX5_GET(virtio_q_counters, virtio_q_counters,
1993*2d9fd380Sjfb8856606 				    error_cqes);
1994*2d9fd380Sjfb8856606 	attr->bad_desc_errors = MLX5_GET(virtio_q_counters, virtio_q_counters,
1995*2d9fd380Sjfb8856606 					 bad_desc_errors);
1996*2d9fd380Sjfb8856606 	attr->exceed_max_chain = MLX5_GET(virtio_q_counters, virtio_q_counters,
1997*2d9fd380Sjfb8856606 					  exceed_max_chain);
1998*2d9fd380Sjfb8856606 	attr->invalid_buffer = MLX5_GET(virtio_q_counters, virtio_q_counters,
1999*2d9fd380Sjfb8856606 					invalid_buffer);
2000*2d9fd380Sjfb8856606 	return ret;
2001*2d9fd380Sjfb8856606 }
2002*2d9fd380Sjfb8856606 
2003*2d9fd380Sjfb8856606 /**
2004*2d9fd380Sjfb8856606  * Create general object of type FLOW_HIT_ASO using DevX API.
2005*2d9fd380Sjfb8856606  *
2006*2d9fd380Sjfb8856606  * @param[in] ctx
2007*2d9fd380Sjfb8856606  *   Context returned from mlx5 open_device() glue function.
2008*2d9fd380Sjfb8856606  * @param [in] pd
2009*2d9fd380Sjfb8856606  *   PD value to associate the FLOW_HIT_ASO object with.
2010*2d9fd380Sjfb8856606  *
2011*2d9fd380Sjfb8856606  * @return
2012*2d9fd380Sjfb8856606  *   The DevX object created, NULL otherwise and rte_errno is set.
2013*2d9fd380Sjfb8856606  */
2014*2d9fd380Sjfb8856606 struct mlx5_devx_obj *
mlx5_devx_cmd_create_flow_hit_aso_obj(void * ctx,uint32_t pd)2015*2d9fd380Sjfb8856606 mlx5_devx_cmd_create_flow_hit_aso_obj(void *ctx, uint32_t pd)
2016*2d9fd380Sjfb8856606 {
2017*2d9fd380Sjfb8856606 	uint32_t in[MLX5_ST_SZ_DW(create_flow_hit_aso_in)] = {0};
2018*2d9fd380Sjfb8856606 	uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
2019*2d9fd380Sjfb8856606 	struct mlx5_devx_obj *flow_hit_aso_obj = NULL;
2020*2d9fd380Sjfb8856606 	void *ptr = NULL;
2021*2d9fd380Sjfb8856606 
2022*2d9fd380Sjfb8856606 	flow_hit_aso_obj = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*flow_hit_aso_obj),
2023*2d9fd380Sjfb8856606 				       0, SOCKET_ID_ANY);
2024*2d9fd380Sjfb8856606 	if (!flow_hit_aso_obj) {
2025*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to allocate FLOW_HIT_ASO object data");
2026*2d9fd380Sjfb8856606 		rte_errno = ENOMEM;
2027*2d9fd380Sjfb8856606 		return NULL;
2028*2d9fd380Sjfb8856606 	}
2029*2d9fd380Sjfb8856606 	ptr = MLX5_ADDR_OF(create_flow_hit_aso_in, in, hdr);
2030*2d9fd380Sjfb8856606 	MLX5_SET(general_obj_in_cmd_hdr, ptr, opcode,
2031*2d9fd380Sjfb8856606 		 MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
2032*2d9fd380Sjfb8856606 	MLX5_SET(general_obj_in_cmd_hdr, ptr, obj_type,
2033*2d9fd380Sjfb8856606 		 MLX5_GENERAL_OBJ_TYPE_FLOW_HIT_ASO);
2034*2d9fd380Sjfb8856606 	ptr = MLX5_ADDR_OF(create_flow_hit_aso_in, in, flow_hit_aso);
2035*2d9fd380Sjfb8856606 	MLX5_SET(flow_hit_aso, ptr, access_pd, pd);
2036*2d9fd380Sjfb8856606 	flow_hit_aso_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in),
2037*2d9fd380Sjfb8856606 							   out, sizeof(out));
2038*2d9fd380Sjfb8856606 	if (!flow_hit_aso_obj->obj) {
2039*2d9fd380Sjfb8856606 		rte_errno = errno;
2040*2d9fd380Sjfb8856606 		DRV_LOG(ERR, "Failed to create FLOW_HIT_ASO obj using DevX.");
2041*2d9fd380Sjfb8856606 		mlx5_free(flow_hit_aso_obj);
2042*2d9fd380Sjfb8856606 		return NULL;
2043*2d9fd380Sjfb8856606 	}
2044*2d9fd380Sjfb8856606 	flow_hit_aso_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
2045*2d9fd380Sjfb8856606 	return flow_hit_aso_obj;
2046*2d9fd380Sjfb8856606 }
2047