1/*-
2 * Copyright (c) 2013-2017, Mellanox Technologies, Ltd.  All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 *
25 * $FreeBSD$
26 */
27
28#include <dev/mlx5/driver.h>
29
30#include "mlx5_core.h"
31#include "transobj.h"
32
33int mlx5_alloc_transport_domain(struct mlx5_core_dev *dev, u32 *tdn)
34{
35	u32 in[MLX5_ST_SZ_DW(alloc_transport_domain_in)] = {0};
36	u32 out[MLX5_ST_SZ_DW(alloc_transport_domain_out)] = {0};
37	int err;
38
39	MLX5_SET(alloc_transport_domain_in, in, opcode,
40		 MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN);
41
42	err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
43	if (!err)
44		*tdn = MLX5_GET(alloc_transport_domain_out, out,
45				transport_domain);
46
47	return err;
48}
49
50void mlx5_dealloc_transport_domain(struct mlx5_core_dev *dev, u32 tdn)
51{
52	u32 in[MLX5_ST_SZ_DW(dealloc_transport_domain_in)] = {0};
53	u32 out[MLX5_ST_SZ_DW(dealloc_transport_domain_out)] = {0};
54
55	MLX5_SET(dealloc_transport_domain_in, in, opcode,
56		 MLX5_CMD_OP_DEALLOC_TRANSPORT_DOMAIN);
57	MLX5_SET(dealloc_transport_domain_in, in, transport_domain, tdn);
58
59	mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
60}
61
62int mlx5_core_create_rq(struct mlx5_core_dev *dev, u32 *in, int inlen, u32 *rqn)
63{
64	u32 out[MLX5_ST_SZ_DW(create_rq_out)] = {0};
65	int err;
66
67	MLX5_SET(create_rq_in, in, opcode, MLX5_CMD_OP_CREATE_RQ);
68
69	err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
70	if (!err)
71		*rqn = MLX5_GET(create_rq_out, out, rqn);
72
73	return err;
74}
75
76int mlx5_core_modify_rq(struct mlx5_core_dev *dev, u32 *in, int inlen)
77{
78	u32 out[MLX5_ST_SZ_DW(modify_rq_out)] = {0};
79
80	MLX5_SET(modify_rq_in, in, opcode, MLX5_CMD_OP_MODIFY_RQ);
81
82	return mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
83}
84
85void mlx5_core_destroy_rq(struct mlx5_core_dev *dev, u32 rqn)
86{
87	u32 in[MLX5_ST_SZ_DW(destroy_rq_in)] = {0};
88	u32 out[MLX5_ST_SZ_DW(destroy_rq_out)] = {0};
89
90	MLX5_SET(destroy_rq_in, in, opcode, MLX5_CMD_OP_DESTROY_RQ);
91	MLX5_SET(destroy_rq_in, in, rqn, rqn);
92
93	mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
94}
95
96int mlx5_core_query_rq(struct mlx5_core_dev *dev, u32 rqn, u32 *out)
97{
98	u32 in[MLX5_ST_SZ_DW(query_rq_in)] = {0};
99	int outlen = MLX5_ST_SZ_BYTES(query_rq_out);
100
101	MLX5_SET(query_rq_in, in, opcode, MLX5_CMD_OP_QUERY_RQ);
102	MLX5_SET(query_rq_in, in, rqn, rqn);
103
104	return mlx5_cmd_exec(dev, in, sizeof(in), out, outlen);
105}
106
107int mlx5_core_create_sq(struct mlx5_core_dev *dev, u32 *in, int inlen, u32 *sqn)
108{
109	u32 out[MLX5_ST_SZ_DW(create_sq_out)] = {0};
110	int err;
111
112	MLX5_SET(create_sq_in, in, opcode, MLX5_CMD_OP_CREATE_SQ);
113
114	err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
115	if (!err)
116		*sqn = MLX5_GET(create_sq_out, out, sqn);
117
118	return err;
119}
120
121int mlx5_core_modify_sq(struct mlx5_core_dev *dev, u32 *in, int inlen)
122{
123	u32 out[MLX5_ST_SZ_DW(modify_sq_out)] = {0};
124
125	MLX5_SET(modify_sq_in, in, opcode, MLX5_CMD_OP_MODIFY_SQ);
126
127	return mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
128}
129
130void mlx5_core_destroy_sq(struct mlx5_core_dev *dev, u32 sqn)
131{
132	u32 in[MLX5_ST_SZ_DW(destroy_sq_in)] = {0};
133	u32 out[MLX5_ST_SZ_DW(destroy_sq_out)] = {0};
134
135	MLX5_SET(destroy_sq_in, in, opcode, MLX5_CMD_OP_DESTROY_SQ);
136	MLX5_SET(destroy_sq_in, in, sqn, sqn);
137
138	mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
139}
140
141int mlx5_core_query_sq(struct mlx5_core_dev *dev, u32 sqn, u32 *out)
142{
143	u32 in[MLX5_ST_SZ_DW(query_sq_in)] = {0};
144	int outlen = MLX5_ST_SZ_BYTES(query_sq_out);
145
146	MLX5_SET(query_sq_in, in, opcode, MLX5_CMD_OP_QUERY_SQ);
147	MLX5_SET(query_sq_in, in, sqn, sqn);
148
149	return mlx5_cmd_exec(dev, in, sizeof(in), out, outlen);
150}
151
152int mlx5_core_create_tir(struct mlx5_core_dev *dev, u32 *in, int inlen,
153			 u32 *tirn)
154{
155	u32 out[MLX5_ST_SZ_DW(create_tir_out)] = {0};
156	int err;
157
158	MLX5_SET(create_tir_in, in, opcode, MLX5_CMD_OP_CREATE_TIR);
159
160	err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
161	if (!err)
162		*tirn = MLX5_GET(create_tir_out, out, tirn);
163
164	return err;
165}
166
167void mlx5_core_destroy_tir(struct mlx5_core_dev *dev, u32 tirn)
168{
169	u32 in[MLX5_ST_SZ_DW(destroy_tir_in)] = {0};
170	u32 out[MLX5_ST_SZ_DW(destroy_tir_out)] = {0};
171
172	MLX5_SET(destroy_tir_in, in, opcode, MLX5_CMD_OP_DESTROY_TIR);
173	MLX5_SET(destroy_tir_in, in, tirn, tirn);
174
175	mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
176}
177
178int mlx5_core_create_tis(struct mlx5_core_dev *dev, u32 *in, int inlen,
179			 u32 *tisn)
180{
181	u32 out[MLX5_ST_SZ_DW(create_tis_out)] = {0};
182	int err;
183
184	MLX5_SET(create_tis_in, in, opcode, MLX5_CMD_OP_CREATE_TIS);
185
186	err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
187	if (!err)
188		*tisn = MLX5_GET(create_tis_out, out, tisn);
189
190	return err;
191}
192
193int mlx5_core_modify_tis(struct mlx5_core_dev *dev, u32 tisn, u32 *in,
194			 int inlen)
195{
196	u32 out[MLX5_ST_SZ_DW(modify_tis_out)] = {0};
197
198	MLX5_SET(modify_tis_in, in, tisn, tisn);
199	MLX5_SET(modify_tis_in, in, opcode, MLX5_CMD_OP_MODIFY_TIS);
200
201	return mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
202}
203
204void mlx5_core_destroy_tis(struct mlx5_core_dev *dev, u32 tisn)
205{
206	u32 in[MLX5_ST_SZ_DW(destroy_tis_in)] = {0};
207	u32 out[MLX5_ST_SZ_DW(destroy_tis_out)] = {0};
208
209	MLX5_SET(destroy_tis_in, in, opcode, MLX5_CMD_OP_DESTROY_TIS);
210	MLX5_SET(destroy_tis_in, in, tisn, tisn);
211
212	mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
213}
214
215int mlx5_core_create_rmp(struct mlx5_core_dev *dev, u32 *in, int inlen, u32 *rmpn)
216{
217	u32 out[MLX5_ST_SZ_DW(create_rmp_out)] = {0};
218	int err;
219
220	MLX5_SET(create_rmp_in, in, opcode, MLX5_CMD_OP_CREATE_RMP);
221
222	err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
223	if (!err)
224		*rmpn = MLX5_GET(create_rmp_out, out, rmpn);
225
226	return err;
227}
228
229int mlx5_core_modify_rmp(struct mlx5_core_dev *dev, u32 *in, int inlen)
230{
231	u32 out[MLX5_ST_SZ_DW(modify_rmp_out)] = {0};
232
233	MLX5_SET(modify_rmp_in, in, opcode, MLX5_CMD_OP_MODIFY_RMP);
234
235	return mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
236}
237
238int mlx5_core_destroy_rmp(struct mlx5_core_dev *dev, u32 rmpn)
239{
240	u32 in[MLX5_ST_SZ_DW(destroy_rmp_in)] = {0};
241	u32 out[MLX5_ST_SZ_DW(destroy_rmp_out)] = {0};
242
243	MLX5_SET(destroy_rmp_in, in, opcode, MLX5_CMD_OP_DESTROY_RMP);
244	MLX5_SET(destroy_rmp_in, in, rmpn, rmpn);
245
246	return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
247}
248
249int mlx5_core_query_rmp(struct mlx5_core_dev *dev, u32 rmpn, u32 *out)
250{
251	u32 in[MLX5_ST_SZ_DW(query_rmp_in)] = {0};
252	int outlen = MLX5_ST_SZ_BYTES(query_rmp_out);
253
254	MLX5_SET(query_rmp_in, in, opcode, MLX5_CMD_OP_QUERY_RMP);
255	MLX5_SET(query_rmp_in, in, rmpn,   rmpn);
256
257	return mlx5_cmd_exec(dev, in, sizeof(in), out, outlen);
258}
259
260int mlx5_core_arm_rmp(struct mlx5_core_dev *dev, u32 rmpn, u16 lwm)
261{
262	void *in;
263	void *rmpc;
264	void *wq;
265	void *bitmask;
266	int  err;
267
268	in = mlx5_vzalloc(MLX5_ST_SZ_BYTES(modify_rmp_in));
269	if (!in)
270		return -ENOMEM;
271
272	rmpc    = MLX5_ADDR_OF(modify_rmp_in,   in,   ctx);
273	bitmask = MLX5_ADDR_OF(modify_rmp_in,   in,   bitmask);
274	wq      = MLX5_ADDR_OF(rmpc,	        rmpc, wq);
275
276	MLX5_SET(modify_rmp_in, in,	 rmp_state, MLX5_RMPC_STATE_RDY);
277	MLX5_SET(modify_rmp_in, in,	 rmpn,      rmpn);
278	MLX5_SET(wq,		wq,	 lwm,	    lwm);
279	MLX5_SET(rmp_bitmask,	bitmask, lwm,	    1);
280	MLX5_SET(rmpc,		rmpc,	 state,	    MLX5_RMPC_STATE_RDY);
281
282	err =  mlx5_core_modify_rmp(dev, in, MLX5_ST_SZ_BYTES(modify_rmp_in));
283
284	kvfree(in);
285
286	return err;
287}
288
289int mlx5_core_create_xsrq(struct mlx5_core_dev *dev, u32 *in, int inlen, u32 *xsrqn)
290{
291	u32 out[MLX5_ST_SZ_DW(create_xrc_srq_out)] = {0};
292	int err;
293
294	MLX5_SET(create_xrc_srq_in, in, opcode,     MLX5_CMD_OP_CREATE_XRC_SRQ);
295
296	err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
297	if (!err)
298		*xsrqn = MLX5_GET(create_xrc_srq_out, out, xrc_srqn);
299
300	return err;
301}
302
303int mlx5_core_destroy_xsrq(struct mlx5_core_dev *dev, u32 xsrqn)
304{
305	u32 in[MLX5_ST_SZ_DW(destroy_xrc_srq_in)] = {0};
306	u32 out[MLX5_ST_SZ_DW(destroy_xrc_srq_out)] = {0};
307
308	MLX5_SET(destroy_xrc_srq_in, in, opcode,   MLX5_CMD_OP_DESTROY_XRC_SRQ);
309	MLX5_SET(destroy_xrc_srq_in, in, xrc_srqn, xsrqn);
310
311	return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
312}
313
314int mlx5_core_query_xsrq(struct mlx5_core_dev *dev, u32 xsrqn, u32 *out)
315{
316	int outlen = MLX5_ST_SZ_BYTES(query_xrc_srq_out);
317	u32 in[MLX5_ST_SZ_DW(query_xrc_srq_in)] = {0};
318	void *xrc_srqc;
319	void *srqc;
320	int err;
321
322	MLX5_SET(query_xrc_srq_in, in, opcode,   MLX5_CMD_OP_QUERY_XRC_SRQ);
323	MLX5_SET(query_xrc_srq_in, in, xrc_srqn, xsrqn);
324
325	err =  mlx5_cmd_exec(dev, in, sizeof(in), out, outlen);
326	if (!err) {
327		xrc_srqc = MLX5_ADDR_OF(query_xrc_srq_out, out,
328					xrc_srq_context_entry);
329		srqc = MLX5_ADDR_OF(query_srq_out, out, srq_context_entry);
330		memcpy(srqc, xrc_srqc, MLX5_ST_SZ_BYTES(srqc));
331	}
332
333	return err;
334}
335
336int mlx5_core_arm_xsrq(struct mlx5_core_dev *dev, u32 xsrqn, u16 lwm)
337{
338	u32 in[MLX5_ST_SZ_DW(arm_xrc_srq_in)] = {0};
339	u32 out[MLX5_ST_SZ_DW(arm_xrc_srq_out)] = {0};
340
341	MLX5_SET(arm_xrc_srq_in, in, opcode,   MLX5_CMD_OP_ARM_XRC_SRQ);
342	MLX5_SET(arm_xrc_srq_in, in, xrc_srqn, xsrqn);
343	MLX5_SET(arm_xrc_srq_in, in, lwm,      lwm);
344	MLX5_SET(arm_xrc_srq_in, in, op_mod,
345		 MLX5_ARM_XRC_SRQ_IN_OP_MOD_XRC_SRQ);
346
347	return	mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
348
349}
350
351int mlx5_core_create_rqt(struct mlx5_core_dev *dev, u32 *in, int inlen,
352			 u32 *rqtn)
353{
354	u32 out[MLX5_ST_SZ_DW(create_rqt_out)] = {0};
355	int err;
356
357	MLX5_SET(create_rqt_in, in, opcode, MLX5_CMD_OP_CREATE_RQT);
358
359	err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
360	if (!err)
361		*rqtn = MLX5_GET(create_rqt_out, out, rqtn);
362
363	return err;
364}
365
366int mlx5_core_modify_rqt(struct mlx5_core_dev *dev, u32 rqtn, u32 *in,
367			 int inlen)
368{
369	u32 out[MLX5_ST_SZ_DW(modify_rqt_out)] = {0};
370
371	MLX5_SET(modify_rqt_in, in, rqtn, rqtn);
372	MLX5_SET(modify_rqt_in, in, opcode, MLX5_CMD_OP_MODIFY_RQT);
373
374	return mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
375}
376
377void mlx5_core_destroy_rqt(struct mlx5_core_dev *dev, u32 rqtn)
378{
379	u32 in[MLX5_ST_SZ_DW(destroy_rqt_in)] = {0};
380	u32 out[MLX5_ST_SZ_DW(destroy_rqt_out)] = {0};
381
382	MLX5_SET(destroy_rqt_in, in, opcode, MLX5_CMD_OP_DESTROY_RQT);
383	MLX5_SET(destroy_rqt_in, in, rqtn, rqtn);
384
385	mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
386}
387