28274a6fbafe62e45baf8639d05c216fe2d8e61b
[cascardo/linux.git] / drivers / net / ethernet / mellanox / mlx5 / core / transobj.c
1 /*
2  * Copyright (c) 2013-2015, Mellanox Technologies, Ltd.  All rights reserved.
3  *
4  * This software is available to you under a choice of one of two
5  * licenses.  You may choose to be licensed under the terms of the GNU
6  * General Public License (GPL) Version 2, available from the file
7  * COPYING in the main directory of this source tree, or the
8  * OpenIB.org BSD license below:
9  *
10  *     Redistribution and use in source and binary forms, with or
11  *     without modification, are permitted provided that the following
12  *     conditions are met:
13  *
14  *      - Redistributions of source code must retain the above
15  *        copyright notice, this list of conditions and the following
16  *        disclaimer.
17  *
18  *      - Redistributions in binary form must reproduce the above
19  *        copyright notice, this list of conditions and the following
20  *        disclaimer in the documentation and/or other materials
21  *        provided with the distribution.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30  * SOFTWARE.
31  */
32
33 #include <linux/mlx5/driver.h>
34 #include "mlx5_core.h"
35 #include <linux/mlx5/transobj.h>
36
37 int mlx5_core_alloc_transport_domain(struct mlx5_core_dev *dev, u32 *tdn)
38 {
39         u32 in[MLX5_ST_SZ_DW(alloc_transport_domain_in)];
40         u32 out[MLX5_ST_SZ_DW(alloc_transport_domain_out)];
41         int err;
42
43         memset(in, 0, sizeof(in));
44         memset(out, 0, sizeof(out));
45
46         MLX5_SET(alloc_transport_domain_in, in, opcode,
47                  MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN);
48
49         err = mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
50         if (!err)
51                 *tdn = MLX5_GET(alloc_transport_domain_out, out,
52                                 transport_domain);
53
54         return err;
55 }
56 EXPORT_SYMBOL(mlx5_core_alloc_transport_domain);
57
58 void mlx5_core_dealloc_transport_domain(struct mlx5_core_dev *dev, u32 tdn)
59 {
60         u32 in[MLX5_ST_SZ_DW(dealloc_transport_domain_in)];
61         u32 out[MLX5_ST_SZ_DW(dealloc_transport_domain_out)];
62
63         memset(in, 0, sizeof(in));
64         memset(out, 0, sizeof(out));
65
66         MLX5_SET(dealloc_transport_domain_in, in, opcode,
67                  MLX5_CMD_OP_DEALLOC_TRANSPORT_DOMAIN);
68         MLX5_SET(dealloc_transport_domain_in, in, transport_domain, tdn);
69
70         mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
71 }
72 EXPORT_SYMBOL(mlx5_core_dealloc_transport_domain);
73
74 int mlx5_core_create_rq(struct mlx5_core_dev *dev, u32 *in, int inlen, u32 *rqn)
75 {
76         u32 out[MLX5_ST_SZ_DW(create_rq_out)];
77         int err;
78
79         MLX5_SET(create_rq_in, in, opcode, MLX5_CMD_OP_CREATE_RQ);
80
81         memset(out, 0, sizeof(out));
82         err = mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out));
83         if (!err)
84                 *rqn = MLX5_GET(create_rq_out, out, rqn);
85
86         return err;
87 }
88 EXPORT_SYMBOL(mlx5_core_create_rq);
89
90 int mlx5_core_modify_rq(struct mlx5_core_dev *dev, u32 rqn, u32 *in, int inlen)
91 {
92         u32 out[MLX5_ST_SZ_DW(modify_rq_out)];
93
94         MLX5_SET(modify_rq_in, in, rqn, rqn);
95         MLX5_SET(modify_rq_in, in, opcode, MLX5_CMD_OP_MODIFY_RQ);
96
97         memset(out, 0, sizeof(out));
98         return mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out));
99 }
100 EXPORT_SYMBOL(mlx5_core_modify_rq);
101
102 void mlx5_core_destroy_rq(struct mlx5_core_dev *dev, u32 rqn)
103 {
104         u32 in[MLX5_ST_SZ_DW(destroy_rq_in)];
105         u32 out[MLX5_ST_SZ_DW(destroy_rq_out)];
106
107         memset(in, 0, sizeof(in));
108
109         MLX5_SET(destroy_rq_in, in, opcode, MLX5_CMD_OP_DESTROY_RQ);
110         MLX5_SET(destroy_rq_in, in, rqn, rqn);
111
112         mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
113 }
114 EXPORT_SYMBOL(mlx5_core_destroy_rq);
115
116 int mlx5_core_query_rq(struct mlx5_core_dev *dev, u32 rqn, u32 *out)
117 {
118         u32 in[MLX5_ST_SZ_DW(query_rq_in)] = {0};
119         int outlen = MLX5_ST_SZ_BYTES(query_rq_out);
120
121         MLX5_SET(query_rq_in, in, opcode, MLX5_CMD_OP_QUERY_RQ);
122         MLX5_SET(query_rq_in, in, rqn, rqn);
123
124         return mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, outlen);
125 }
126 EXPORT_SYMBOL(mlx5_core_query_rq);
127
128 int mlx5_core_create_sq(struct mlx5_core_dev *dev, u32 *in, int inlen, u32 *sqn)
129 {
130         u32 out[MLX5_ST_SZ_DW(create_sq_out)];
131         int err;
132
133         MLX5_SET(create_sq_in, in, opcode, MLX5_CMD_OP_CREATE_SQ);
134
135         memset(out, 0, sizeof(out));
136         err = mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out));
137         if (!err)
138                 *sqn = MLX5_GET(create_sq_out, out, sqn);
139
140         return err;
141 }
142
143 int mlx5_core_modify_sq(struct mlx5_core_dev *dev, u32 sqn, u32 *in, int inlen)
144 {
145         u32 out[MLX5_ST_SZ_DW(modify_sq_out)];
146
147         MLX5_SET(modify_sq_in, in, sqn, sqn);
148         MLX5_SET(modify_sq_in, in, opcode, MLX5_CMD_OP_MODIFY_SQ);
149
150         memset(out, 0, sizeof(out));
151         return mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out));
152 }
153 EXPORT_SYMBOL(mlx5_core_modify_sq);
154
155 void mlx5_core_destroy_sq(struct mlx5_core_dev *dev, u32 sqn)
156 {
157         u32 in[MLX5_ST_SZ_DW(destroy_sq_in)];
158         u32 out[MLX5_ST_SZ_DW(destroy_sq_out)];
159
160         memset(in, 0, sizeof(in));
161
162         MLX5_SET(destroy_sq_in, in, opcode, MLX5_CMD_OP_DESTROY_SQ);
163         MLX5_SET(destroy_sq_in, in, sqn, sqn);
164
165         mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
166 }
167
168 int mlx5_core_query_sq(struct mlx5_core_dev *dev, u32 sqn, u32 *out)
169 {
170         u32 in[MLX5_ST_SZ_DW(query_sq_in)] = {0};
171         int outlen = MLX5_ST_SZ_BYTES(query_sq_out);
172
173         MLX5_SET(query_sq_in, in, opcode, MLX5_CMD_OP_QUERY_SQ);
174         MLX5_SET(query_sq_in, in, sqn, sqn);
175
176         return mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, outlen);
177 }
178 EXPORT_SYMBOL(mlx5_core_query_sq);
179
180 int mlx5_core_create_tir(struct mlx5_core_dev *dev, u32 *in, int inlen,
181                          u32 *tirn)
182 {
183         u32 out[MLX5_ST_SZ_DW(create_tir_out)];
184         int err;
185
186         MLX5_SET(create_tir_in, in, opcode, MLX5_CMD_OP_CREATE_TIR);
187
188         memset(out, 0, sizeof(out));
189         err = mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out));
190         if (!err)
191                 *tirn = MLX5_GET(create_tir_out, out, tirn);
192
193         return err;
194 }
195 EXPORT_SYMBOL(mlx5_core_create_tir);
196
197 int mlx5_core_modify_tir(struct mlx5_core_dev *dev, u32 tirn, u32 *in,
198                          int inlen)
199 {
200         u32 out[MLX5_ST_SZ_DW(modify_tir_out)];
201
202         MLX5_SET(modify_tir_in, in, tirn, tirn);
203         MLX5_SET(modify_tir_in, in, opcode, MLX5_CMD_OP_MODIFY_TIR);
204
205         memset(out, 0, sizeof(out));
206         return mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out));
207 }
208
209 void mlx5_core_destroy_tir(struct mlx5_core_dev *dev, u32 tirn)
210 {
211         u32 in[MLX5_ST_SZ_DW(destroy_tir_in)];
212         u32 out[MLX5_ST_SZ_DW(destroy_tir_out)];
213
214         memset(in, 0, sizeof(in));
215
216         MLX5_SET(destroy_tir_in, in, opcode, MLX5_CMD_OP_DESTROY_TIR);
217         MLX5_SET(destroy_tir_in, in, tirn, tirn);
218
219         mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
220 }
221 EXPORT_SYMBOL(mlx5_core_destroy_tir);
222
223 int mlx5_core_create_tis(struct mlx5_core_dev *dev, u32 *in, int inlen,
224                          u32 *tisn)
225 {
226         u32 out[MLX5_ST_SZ_DW(create_tis_out)];
227         int err;
228
229         MLX5_SET(create_tis_in, in, opcode, MLX5_CMD_OP_CREATE_TIS);
230
231         memset(out, 0, sizeof(out));
232         err = mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out));
233         if (!err)
234                 *tisn = MLX5_GET(create_tis_out, out, tisn);
235
236         return err;
237 }
238 EXPORT_SYMBOL(mlx5_core_create_tis);
239
240 int mlx5_core_modify_tis(struct mlx5_core_dev *dev, u32 tisn, u32 *in,
241                          int inlen)
242 {
243         u32 out[MLX5_ST_SZ_DW(modify_tis_out)] = {0};
244
245         MLX5_SET(modify_tis_in, in, tisn, tisn);
246         MLX5_SET(modify_tis_in, in, opcode, MLX5_CMD_OP_MODIFY_TIS);
247
248         return mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out));
249 }
250 EXPORT_SYMBOL(mlx5_core_modify_tis);
251
252 void mlx5_core_destroy_tis(struct mlx5_core_dev *dev, u32 tisn)
253 {
254         u32 in[MLX5_ST_SZ_DW(destroy_tis_in)];
255         u32 out[MLX5_ST_SZ_DW(destroy_tis_out)];
256
257         memset(in, 0, sizeof(in));
258
259         MLX5_SET(destroy_tis_in, in, opcode, MLX5_CMD_OP_DESTROY_TIS);
260         MLX5_SET(destroy_tis_in, in, tisn, tisn);
261
262         mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
263 }
264 EXPORT_SYMBOL(mlx5_core_destroy_tis);
265
266 int mlx5_core_create_rmp(struct mlx5_core_dev *dev, u32 *in, int inlen,
267                          u32 *rmpn)
268 {
269         u32 out[MLX5_ST_SZ_DW(create_rmp_out)];
270         int err;
271
272         MLX5_SET(create_rmp_in, in, opcode, MLX5_CMD_OP_CREATE_RMP);
273
274         memset(out, 0, sizeof(out));
275         err = mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out));
276         if (!err)
277                 *rmpn = MLX5_GET(create_rmp_out, out, rmpn);
278
279         return err;
280 }
281
282 int mlx5_core_modify_rmp(struct mlx5_core_dev *dev, u32 *in, int inlen)
283 {
284         u32 out[MLX5_ST_SZ_DW(modify_rmp_out)];
285
286         MLX5_SET(modify_rmp_in, in, opcode, MLX5_CMD_OP_MODIFY_RMP);
287
288         memset(out, 0, sizeof(out));
289         return mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out));
290 }
291
292 int mlx5_core_destroy_rmp(struct mlx5_core_dev *dev, u32 rmpn)
293 {
294         u32 in[MLX5_ST_SZ_DW(destroy_rmp_in)];
295         u32 out[MLX5_ST_SZ_DW(destroy_rmp_out)];
296
297         memset(in, 0, sizeof(in));
298
299         MLX5_SET(destroy_rmp_in, in, opcode, MLX5_CMD_OP_DESTROY_RMP);
300         MLX5_SET(destroy_rmp_in, in, rmpn, rmpn);
301
302         return mlx5_cmd_exec_check_status(dev, in, sizeof(in), out,
303                                           sizeof(out));
304 }
305
306 int mlx5_core_query_rmp(struct mlx5_core_dev *dev, u32 rmpn, u32 *out)
307 {
308         u32 in[MLX5_ST_SZ_DW(query_rmp_in)];
309         int outlen = MLX5_ST_SZ_BYTES(query_rmp_out);
310
311         memset(in, 0, sizeof(in));
312         MLX5_SET(query_rmp_in, in, opcode, MLX5_CMD_OP_QUERY_RMP);
313         MLX5_SET(query_rmp_in, in, rmpn,   rmpn);
314
315         return mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, outlen);
316 }
317
318 int mlx5_core_arm_rmp(struct mlx5_core_dev *dev, u32 rmpn, u16 lwm)
319 {
320         void *in;
321         void *rmpc;
322         void *wq;
323         void *bitmask;
324         int  err;
325
326         in = mlx5_vzalloc(MLX5_ST_SZ_BYTES(modify_rmp_in));
327         if (!in)
328                 return -ENOMEM;
329
330         rmpc    = MLX5_ADDR_OF(modify_rmp_in,   in,   ctx);
331         bitmask = MLX5_ADDR_OF(modify_rmp_in,   in,   bitmask);
332         wq      = MLX5_ADDR_OF(rmpc,            rmpc, wq);
333
334         MLX5_SET(modify_rmp_in, in,      rmp_state, MLX5_RMPC_STATE_RDY);
335         MLX5_SET(modify_rmp_in, in,      rmpn,      rmpn);
336         MLX5_SET(wq,            wq,      lwm,       lwm);
337         MLX5_SET(rmp_bitmask,   bitmask, lwm,       1);
338         MLX5_SET(rmpc,          rmpc,    state,     MLX5_RMPC_STATE_RDY);
339
340         err =  mlx5_core_modify_rmp(dev, in, MLX5_ST_SZ_BYTES(modify_rmp_in));
341
342         kvfree(in);
343
344         return err;
345 }
346
347 int mlx5_core_create_xsrq(struct mlx5_core_dev *dev, u32 *in, int inlen,
348                           u32 *xsrqn)
349 {
350         u32 out[MLX5_ST_SZ_DW(create_xrc_srq_out)];
351         int err;
352
353         MLX5_SET(create_xrc_srq_in, in, opcode,     MLX5_CMD_OP_CREATE_XRC_SRQ);
354
355         memset(out, 0, sizeof(out));
356         err = mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out));
357         if (!err)
358                 *xsrqn = MLX5_GET(create_xrc_srq_out, out, xrc_srqn);
359
360         return err;
361 }
362
363 int mlx5_core_destroy_xsrq(struct mlx5_core_dev *dev, u32 xsrqn)
364 {
365         u32 in[MLX5_ST_SZ_DW(destroy_xrc_srq_in)];
366         u32 out[MLX5_ST_SZ_DW(destroy_xrc_srq_out)];
367
368         memset(in, 0, sizeof(in));
369         memset(out, 0, sizeof(out));
370
371         MLX5_SET(destroy_xrc_srq_in, in, opcode,   MLX5_CMD_OP_DESTROY_XRC_SRQ);
372         MLX5_SET(destroy_xrc_srq_in, in, xrc_srqn, xsrqn);
373
374         return mlx5_cmd_exec_check_status(dev, in, sizeof(in), out,
375                                           sizeof(out));
376 }
377
378 int mlx5_core_query_xsrq(struct mlx5_core_dev *dev, u32 xsrqn, u32 *out)
379 {
380         u32 in[MLX5_ST_SZ_DW(query_xrc_srq_in)];
381         void *srqc;
382         void *xrc_srqc;
383         int err;
384
385         memset(in, 0, sizeof(in));
386         MLX5_SET(query_xrc_srq_in, in, opcode,   MLX5_CMD_OP_QUERY_XRC_SRQ);
387         MLX5_SET(query_xrc_srq_in, in, xrc_srqn, xsrqn);
388
389         err =  mlx5_cmd_exec_check_status(dev, in, sizeof(in),
390                                           out,
391                                           MLX5_ST_SZ_BYTES(query_xrc_srq_out));
392         if (!err) {
393                 xrc_srqc = MLX5_ADDR_OF(query_xrc_srq_out, out,
394                                         xrc_srq_context_entry);
395                 srqc = MLX5_ADDR_OF(query_srq_out, out, srq_context_entry);
396                 memcpy(srqc, xrc_srqc, MLX5_ST_SZ_BYTES(srqc));
397         }
398
399         return err;
400 }
401
402 int mlx5_core_arm_xsrq(struct mlx5_core_dev *dev, u32 xsrqn, u16 lwm)
403 {
404         u32 in[MLX5_ST_SZ_DW(arm_xrc_srq_in)];
405         u32 out[MLX5_ST_SZ_DW(arm_xrc_srq_out)];
406
407         memset(in, 0, sizeof(in));
408         memset(out, 0, sizeof(out));
409
410         MLX5_SET(arm_xrc_srq_in, in, opcode,   MLX5_CMD_OP_ARM_XRC_SRQ);
411         MLX5_SET(arm_xrc_srq_in, in, xrc_srqn, xsrqn);
412         MLX5_SET(arm_xrc_srq_in, in, lwm,      lwm);
413         MLX5_SET(arm_xrc_srq_in, in, op_mod,
414                  MLX5_ARM_XRC_SRQ_IN_OP_MOD_XRC_SRQ);
415
416         return  mlx5_cmd_exec_check_status(dev, in, sizeof(in), out,
417                                            sizeof(out));
418 }
419
420 int mlx5_core_create_rqt(struct mlx5_core_dev *dev, u32 *in, int inlen,
421                          u32 *rqtn)
422 {
423         u32 out[MLX5_ST_SZ_DW(create_rqt_out)];
424         int err;
425
426         MLX5_SET(create_rqt_in, in, opcode, MLX5_CMD_OP_CREATE_RQT);
427
428         memset(out, 0, sizeof(out));
429         err = mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out));
430         if (!err)
431                 *rqtn = MLX5_GET(create_rqt_out, out, rqtn);
432
433         return err;
434 }
435 EXPORT_SYMBOL(mlx5_core_create_rqt);
436
437 int mlx5_core_modify_rqt(struct mlx5_core_dev *dev, u32 rqtn, u32 *in,
438                          int inlen)
439 {
440         u32 out[MLX5_ST_SZ_DW(modify_rqt_out)];
441
442         MLX5_SET(modify_rqt_in, in, rqtn, rqtn);
443         MLX5_SET(modify_rqt_in, in, opcode, MLX5_CMD_OP_MODIFY_RQT);
444
445         memset(out, 0, sizeof(out));
446         return mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out));
447 }
448
449 void mlx5_core_destroy_rqt(struct mlx5_core_dev *dev, u32 rqtn)
450 {
451         u32 in[MLX5_ST_SZ_DW(destroy_rqt_in)];
452         u32 out[MLX5_ST_SZ_DW(destroy_rqt_out)];
453
454         memset(in, 0, sizeof(in));
455
456         MLX5_SET(destroy_rqt_in, in, opcode, MLX5_CMD_OP_DESTROY_RQT);
457         MLX5_SET(destroy_rqt_in, in, rqtn, rqtn);
458
459         mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
460 }
461 EXPORT_SYMBOL(mlx5_core_destroy_rqt);