2 * Copyright (c) 2013-2015, Mellanox Technologies, Ltd. All rights reserved.
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:
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
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.
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
33 #include <linux/mlx5/driver.h>
34 #include "mlx5_core.h"
35 #include <linux/mlx5/transobj.h>
37 int mlx5_core_alloc_transport_domain(struct mlx5_core_dev
*dev
, u32
*tdn
)
39 u32 in
[MLX5_ST_SZ_DW(alloc_transport_domain_in
)] = {0};
40 u32 out
[MLX5_ST_SZ_DW(alloc_transport_domain_out
)] = {0};
43 MLX5_SET(alloc_transport_domain_in
, in
, opcode
,
44 MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN
);
46 err
= mlx5_cmd_exec(dev
, in
, sizeof(in
), out
, sizeof(out
));
48 *tdn
= MLX5_GET(alloc_transport_domain_out
, out
,
53 EXPORT_SYMBOL(mlx5_core_alloc_transport_domain
);
55 void mlx5_core_dealloc_transport_domain(struct mlx5_core_dev
*dev
, u32 tdn
)
57 u32 in
[MLX5_ST_SZ_DW(dealloc_transport_domain_in
)] = {0};
58 u32 out
[MLX5_ST_SZ_DW(dealloc_transport_domain_out
)] = {0};
60 MLX5_SET(dealloc_transport_domain_in
, in
, opcode
,
61 MLX5_CMD_OP_DEALLOC_TRANSPORT_DOMAIN
);
62 MLX5_SET(dealloc_transport_domain_in
, in
, transport_domain
, tdn
);
63 mlx5_cmd_exec(dev
, in
, sizeof(in
), out
, sizeof(out
));
65 EXPORT_SYMBOL(mlx5_core_dealloc_transport_domain
);
67 int mlx5_core_create_rq(struct mlx5_core_dev
*dev
, u32
*in
, int inlen
, u32
*rqn
)
69 u32 out
[MLX5_ST_SZ_DW(create_rq_out
)] = {0};
72 MLX5_SET(create_rq_in
, in
, opcode
, MLX5_CMD_OP_CREATE_RQ
);
73 err
= mlx5_cmd_exec(dev
, in
, inlen
, out
, sizeof(out
));
75 *rqn
= MLX5_GET(create_rq_out
, out
, rqn
);
79 EXPORT_SYMBOL(mlx5_core_create_rq
);
81 int mlx5_core_modify_rq(struct mlx5_core_dev
*dev
, u32 rqn
, u32
*in
, int inlen
)
83 u32 out
[MLX5_ST_SZ_DW(modify_rq_out
)];
85 MLX5_SET(modify_rq_in
, in
, rqn
, rqn
);
86 MLX5_SET(modify_rq_in
, in
, opcode
, MLX5_CMD_OP_MODIFY_RQ
);
88 memset(out
, 0, sizeof(out
));
89 return mlx5_cmd_exec(dev
, in
, inlen
, out
, sizeof(out
));
91 EXPORT_SYMBOL(mlx5_core_modify_rq
);
93 void mlx5_core_destroy_rq(struct mlx5_core_dev
*dev
, u32 rqn
)
95 u32 in
[MLX5_ST_SZ_DW(destroy_rq_in
)] = {0};
96 u32 out
[MLX5_ST_SZ_DW(destroy_rq_out
)] = {0};
98 MLX5_SET(destroy_rq_in
, in
, opcode
, MLX5_CMD_OP_DESTROY_RQ
);
99 MLX5_SET(destroy_rq_in
, in
, rqn
, rqn
);
100 mlx5_cmd_exec(dev
, in
, sizeof(in
), out
, sizeof(out
));
102 EXPORT_SYMBOL(mlx5_core_destroy_rq
);
104 int mlx5_core_query_rq(struct mlx5_core_dev
*dev
, u32 rqn
, u32
*out
)
106 u32 in
[MLX5_ST_SZ_DW(query_rq_in
)] = {0};
107 int outlen
= MLX5_ST_SZ_BYTES(query_rq_out
);
109 MLX5_SET(query_rq_in
, in
, opcode
, MLX5_CMD_OP_QUERY_RQ
);
110 MLX5_SET(query_rq_in
, in
, rqn
, rqn
);
112 return mlx5_cmd_exec(dev
, in
, sizeof(in
), out
, outlen
);
114 EXPORT_SYMBOL(mlx5_core_query_rq
);
116 int mlx5_core_create_sq(struct mlx5_core_dev
*dev
, u32
*in
, int inlen
, u32
*sqn
)
118 u32 out
[MLX5_ST_SZ_DW(create_sq_out
)] = {0};
121 MLX5_SET(create_sq_in
, in
, opcode
, MLX5_CMD_OP_CREATE_SQ
);
122 err
= mlx5_cmd_exec(dev
, in
, inlen
, out
, sizeof(out
));
124 *sqn
= MLX5_GET(create_sq_out
, out
, sqn
);
129 int mlx5_core_modify_sq(struct mlx5_core_dev
*dev
, u32 sqn
, u32
*in
, int inlen
)
131 u32 out
[MLX5_ST_SZ_DW(modify_sq_out
)] = {0};
133 MLX5_SET(modify_sq_in
, in
, sqn
, sqn
);
134 MLX5_SET(modify_sq_in
, in
, opcode
, MLX5_CMD_OP_MODIFY_SQ
);
135 return mlx5_cmd_exec(dev
, in
, inlen
, out
, sizeof(out
));
137 EXPORT_SYMBOL(mlx5_core_modify_sq
);
139 void mlx5_core_destroy_sq(struct mlx5_core_dev
*dev
, u32 sqn
)
141 u32 in
[MLX5_ST_SZ_DW(destroy_sq_in
)] = {0};
142 u32 out
[MLX5_ST_SZ_DW(destroy_sq_out
)] = {0};
144 MLX5_SET(destroy_sq_in
, in
, opcode
, MLX5_CMD_OP_DESTROY_SQ
);
145 MLX5_SET(destroy_sq_in
, in
, sqn
, sqn
);
146 mlx5_cmd_exec(dev
, in
, sizeof(in
), out
, sizeof(out
));
149 int mlx5_core_query_sq(struct mlx5_core_dev
*dev
, u32 sqn
, u32
*out
)
151 u32 in
[MLX5_ST_SZ_DW(query_sq_in
)] = {0};
152 int outlen
= MLX5_ST_SZ_BYTES(query_sq_out
);
154 MLX5_SET(query_sq_in
, in
, opcode
, MLX5_CMD_OP_QUERY_SQ
);
155 MLX5_SET(query_sq_in
, in
, sqn
, sqn
);
156 return mlx5_cmd_exec(dev
, in
, sizeof(in
), out
, outlen
);
158 EXPORT_SYMBOL(mlx5_core_query_sq
);
160 int mlx5_core_create_tir(struct mlx5_core_dev
*dev
, u32
*in
, int inlen
,
163 u32 out
[MLX5_ST_SZ_DW(create_tir_out
)] = {0};
166 MLX5_SET(create_tir_in
, in
, opcode
, MLX5_CMD_OP_CREATE_TIR
);
168 memset(out
, 0, sizeof(out
));
169 err
= mlx5_cmd_exec(dev
, in
, inlen
, out
, sizeof(out
));
171 *tirn
= MLX5_GET(create_tir_out
, out
, tirn
);
175 EXPORT_SYMBOL(mlx5_core_create_tir
);
177 int mlx5_core_modify_tir(struct mlx5_core_dev
*dev
, u32 tirn
, u32
*in
,
180 u32 out
[MLX5_ST_SZ_DW(modify_tir_out
)] = {0};
182 MLX5_SET(modify_tir_in
, in
, tirn
, tirn
);
183 MLX5_SET(modify_tir_in
, in
, opcode
, MLX5_CMD_OP_MODIFY_TIR
);
184 return mlx5_cmd_exec(dev
, in
, inlen
, out
, sizeof(out
));
187 void mlx5_core_destroy_tir(struct mlx5_core_dev
*dev
, u32 tirn
)
189 u32 in
[MLX5_ST_SZ_DW(destroy_tir_in
)] = {0};
190 u32 out
[MLX5_ST_SZ_DW(destroy_tir_out
)] = {0};
192 MLX5_SET(destroy_tir_in
, in
, opcode
, MLX5_CMD_OP_DESTROY_TIR
);
193 MLX5_SET(destroy_tir_in
, in
, tirn
, tirn
);
194 mlx5_cmd_exec(dev
, in
, sizeof(in
), out
, sizeof(out
));
196 EXPORT_SYMBOL(mlx5_core_destroy_tir
);
198 int mlx5_core_create_tis(struct mlx5_core_dev
*dev
, u32
*in
, int inlen
,
201 u32 out
[MLX5_ST_SZ_DW(create_tis_out
)] = {0};
204 MLX5_SET(create_tis_in
, in
, opcode
, MLX5_CMD_OP_CREATE_TIS
);
205 err
= mlx5_cmd_exec(dev
, in
, inlen
, out
, sizeof(out
));
207 *tisn
= MLX5_GET(create_tis_out
, out
, tisn
);
211 EXPORT_SYMBOL(mlx5_core_create_tis
);
213 int mlx5_core_modify_tis(struct mlx5_core_dev
*dev
, u32 tisn
, u32
*in
,
216 u32 out
[MLX5_ST_SZ_DW(modify_tis_out
)] = {0};
218 MLX5_SET(modify_tis_in
, in
, tisn
, tisn
);
219 MLX5_SET(modify_tis_in
, in
, opcode
, MLX5_CMD_OP_MODIFY_TIS
);
221 return mlx5_cmd_exec(dev
, in
, inlen
, out
, sizeof(out
));
223 EXPORT_SYMBOL(mlx5_core_modify_tis
);
225 void mlx5_core_destroy_tis(struct mlx5_core_dev
*dev
, u32 tisn
)
227 u32 in
[MLX5_ST_SZ_DW(destroy_tis_in
)] = {0};
228 u32 out
[MLX5_ST_SZ_DW(destroy_tis_out
)] = {0};
230 MLX5_SET(destroy_tis_in
, in
, opcode
, MLX5_CMD_OP_DESTROY_TIS
);
231 MLX5_SET(destroy_tis_in
, in
, tisn
, tisn
);
232 mlx5_cmd_exec(dev
, in
, sizeof(in
), out
, sizeof(out
));
234 EXPORT_SYMBOL(mlx5_core_destroy_tis
);
236 int mlx5_core_create_rmp(struct mlx5_core_dev
*dev
, u32
*in
, int inlen
,
239 u32 out
[MLX5_ST_SZ_DW(create_rmp_out
)] = {0};
242 MLX5_SET(create_rmp_in
, in
, opcode
, MLX5_CMD_OP_CREATE_RMP
);
243 err
= mlx5_cmd_exec(dev
, in
, inlen
, out
, sizeof(out
));
245 *rmpn
= MLX5_GET(create_rmp_out
, out
, rmpn
);
250 int mlx5_core_modify_rmp(struct mlx5_core_dev
*dev
, u32
*in
, int inlen
)
252 u32 out
[MLX5_ST_SZ_DW(modify_rmp_out
)] = {0};
254 MLX5_SET(modify_rmp_in
, in
, opcode
, MLX5_CMD_OP_MODIFY_RMP
);
255 return mlx5_cmd_exec(dev
, in
, inlen
, out
, sizeof(out
));
258 int mlx5_core_destroy_rmp(struct mlx5_core_dev
*dev
, u32 rmpn
)
260 u32 in
[MLX5_ST_SZ_DW(destroy_rmp_in
)] = {0};
261 u32 out
[MLX5_ST_SZ_DW(destroy_rmp_out
)] = {0};
263 MLX5_SET(destroy_rmp_in
, in
, opcode
, MLX5_CMD_OP_DESTROY_RMP
);
264 MLX5_SET(destroy_rmp_in
, in
, rmpn
, rmpn
);
265 return mlx5_cmd_exec(dev
, in
, sizeof(in
), out
,
269 int mlx5_core_query_rmp(struct mlx5_core_dev
*dev
, u32 rmpn
, u32
*out
)
271 u32 in
[MLX5_ST_SZ_DW(query_rmp_in
)] = {0};
272 int outlen
= MLX5_ST_SZ_BYTES(query_rmp_out
);
274 MLX5_SET(query_rmp_in
, in
, opcode
, MLX5_CMD_OP_QUERY_RMP
);
275 MLX5_SET(query_rmp_in
, in
, rmpn
, rmpn
);
276 return mlx5_cmd_exec(dev
, in
, sizeof(in
), out
, outlen
);
279 int mlx5_core_arm_rmp(struct mlx5_core_dev
*dev
, u32 rmpn
, u16 lwm
)
287 in
= kvzalloc(MLX5_ST_SZ_BYTES(modify_rmp_in
), GFP_KERNEL
);
291 rmpc
= MLX5_ADDR_OF(modify_rmp_in
, in
, ctx
);
292 bitmask
= MLX5_ADDR_OF(modify_rmp_in
, in
, bitmask
);
293 wq
= MLX5_ADDR_OF(rmpc
, rmpc
, wq
);
295 MLX5_SET(modify_rmp_in
, in
, rmp_state
, MLX5_RMPC_STATE_RDY
);
296 MLX5_SET(modify_rmp_in
, in
, rmpn
, rmpn
);
297 MLX5_SET(wq
, wq
, lwm
, lwm
);
298 MLX5_SET(rmp_bitmask
, bitmask
, lwm
, 1);
299 MLX5_SET(rmpc
, rmpc
, state
, MLX5_RMPC_STATE_RDY
);
301 err
= mlx5_core_modify_rmp(dev
, in
, MLX5_ST_SZ_BYTES(modify_rmp_in
));
308 int mlx5_core_create_xsrq(struct mlx5_core_dev
*dev
, u32
*in
, int inlen
,
311 u32 out
[MLX5_ST_SZ_DW(create_xrc_srq_out
)] = {0};
314 MLX5_SET(create_xrc_srq_in
, in
, opcode
, MLX5_CMD_OP_CREATE_XRC_SRQ
);
315 err
= mlx5_cmd_exec(dev
, in
, inlen
, out
, sizeof(out
));
317 *xsrqn
= MLX5_GET(create_xrc_srq_out
, out
, xrc_srqn
);
322 int mlx5_core_destroy_xsrq(struct mlx5_core_dev
*dev
, u32 xsrqn
)
324 u32 in
[MLX5_ST_SZ_DW(destroy_xrc_srq_in
)] = {0};
325 u32 out
[MLX5_ST_SZ_DW(destroy_xrc_srq_out
)] = {0};
327 MLX5_SET(destroy_xrc_srq_in
, in
, opcode
, MLX5_CMD_OP_DESTROY_XRC_SRQ
);
328 MLX5_SET(destroy_xrc_srq_in
, in
, xrc_srqn
, xsrqn
);
329 return mlx5_cmd_exec(dev
, in
, sizeof(in
), out
, sizeof(out
));
332 int mlx5_core_query_xsrq(struct mlx5_core_dev
*dev
, u32 xsrqn
, u32
*out
)
334 u32 in
[MLX5_ST_SZ_DW(query_xrc_srq_in
)] = {0};
339 MLX5_SET(query_xrc_srq_in
, in
, opcode
, MLX5_CMD_OP_QUERY_XRC_SRQ
);
340 MLX5_SET(query_xrc_srq_in
, in
, xrc_srqn
, xsrqn
);
341 err
= mlx5_cmd_exec(dev
, in
, sizeof(in
), out
,
342 MLX5_ST_SZ_BYTES(query_xrc_srq_out
));
344 xrc_srqc
= MLX5_ADDR_OF(query_xrc_srq_out
, out
,
345 xrc_srq_context_entry
);
346 srqc
= MLX5_ADDR_OF(query_srq_out
, out
, srq_context_entry
);
347 memcpy(srqc
, xrc_srqc
, MLX5_ST_SZ_BYTES(srqc
));
353 int mlx5_core_arm_xsrq(struct mlx5_core_dev
*dev
, u32 xsrqn
, u16 lwm
)
355 u32 in
[MLX5_ST_SZ_DW(arm_xrc_srq_in
)] = {0};
356 u32 out
[MLX5_ST_SZ_DW(arm_xrc_srq_out
)] = {0};
358 MLX5_SET(arm_xrc_srq_in
, in
, opcode
, MLX5_CMD_OP_ARM_XRC_SRQ
);
359 MLX5_SET(arm_xrc_srq_in
, in
, xrc_srqn
, xsrqn
);
360 MLX5_SET(arm_xrc_srq_in
, in
, lwm
, lwm
);
361 MLX5_SET(arm_xrc_srq_in
, in
, op_mod
,
362 MLX5_ARM_XRC_SRQ_IN_OP_MOD_XRC_SRQ
);
363 return mlx5_cmd_exec(dev
, in
, sizeof(in
), out
, sizeof(out
));
366 int mlx5_core_create_rqt(struct mlx5_core_dev
*dev
, u32
*in
, int inlen
,
369 u32 out
[MLX5_ST_SZ_DW(create_rqt_out
)] = {0};
372 MLX5_SET(create_rqt_in
, in
, opcode
, MLX5_CMD_OP_CREATE_RQT
);
373 err
= mlx5_cmd_exec(dev
, in
, inlen
, out
, sizeof(out
));
375 *rqtn
= MLX5_GET(create_rqt_out
, out
, rqtn
);
379 EXPORT_SYMBOL(mlx5_core_create_rqt
);
381 int mlx5_core_modify_rqt(struct mlx5_core_dev
*dev
, u32 rqtn
, u32
*in
,
384 u32 out
[MLX5_ST_SZ_DW(modify_rqt_out
)] = {0};
386 MLX5_SET(modify_rqt_in
, in
, rqtn
, rqtn
);
387 MLX5_SET(modify_rqt_in
, in
, opcode
, MLX5_CMD_OP_MODIFY_RQT
);
388 return mlx5_cmd_exec(dev
, in
, inlen
, out
, sizeof(out
));
391 void mlx5_core_destroy_rqt(struct mlx5_core_dev
*dev
, u32 rqtn
)
393 u32 in
[MLX5_ST_SZ_DW(destroy_rqt_in
)] = {0};
394 u32 out
[MLX5_ST_SZ_DW(destroy_rqt_out
)] = {0};
396 MLX5_SET(destroy_rqt_in
, in
, opcode
, MLX5_CMD_OP_DESTROY_RQT
);
397 MLX5_SET(destroy_rqt_in
, in
, rqtn
, rqtn
);
398 mlx5_cmd_exec(dev
, in
, sizeof(in
), out
, sizeof(out
));
400 EXPORT_SYMBOL(mlx5_core_destroy_rqt
);
402 static int mlx5_hairpin_create_rq(struct mlx5_core_dev
*mdev
,
403 struct mlx5_hairpin_params
*params
, u32
*rqn
)
405 u32 in
[MLX5_ST_SZ_DW(create_rq_in
)] = {0};
408 rqc
= MLX5_ADDR_OF(create_rq_in
, in
, ctx
);
409 wq
= MLX5_ADDR_OF(rqc
, rqc
, wq
);
411 MLX5_SET(rqc
, rqc
, hairpin
, 1);
412 MLX5_SET(rqc
, rqc
, state
, MLX5_RQC_STATE_RST
);
413 MLX5_SET(rqc
, rqc
, counter_set_id
, params
->q_counter
);
415 MLX5_SET(wq
, wq
, log_hairpin_data_sz
, params
->log_data_size
);
416 MLX5_SET(wq
, wq
, log_hairpin_num_packets
, params
->log_num_packets
);
418 return mlx5_core_create_rq(mdev
, in
, MLX5_ST_SZ_BYTES(create_rq_in
), rqn
);
421 static int mlx5_hairpin_create_sq(struct mlx5_core_dev
*mdev
,
422 struct mlx5_hairpin_params
*params
, u32
*sqn
)
424 u32 in
[MLX5_ST_SZ_DW(create_sq_in
)] = {0};
427 sqc
= MLX5_ADDR_OF(create_sq_in
, in
, ctx
);
428 wq
= MLX5_ADDR_OF(sqc
, sqc
, wq
);
430 MLX5_SET(sqc
, sqc
, hairpin
, 1);
431 MLX5_SET(sqc
, sqc
, state
, MLX5_SQC_STATE_RST
);
433 MLX5_SET(wq
, wq
, log_hairpin_data_sz
, params
->log_data_size
);
434 MLX5_SET(wq
, wq
, log_hairpin_num_packets
, params
->log_num_packets
);
436 return mlx5_core_create_sq(mdev
, in
, MLX5_ST_SZ_BYTES(create_sq_in
), sqn
);
439 static int mlx5_hairpin_create_queues(struct mlx5_hairpin
*hp
,
440 struct mlx5_hairpin_params
*params
)
444 for (i
= 0; i
< hp
->num_channels
; i
++) {
445 err
= mlx5_hairpin_create_rq(hp
->func_mdev
, params
, &hp
->rqn
[i
]);
450 for (i
= 0; i
< hp
->num_channels
; i
++) {
451 err
= mlx5_hairpin_create_sq(hp
->peer_mdev
, params
, &hp
->sqn
[i
]);
459 for (j
= 0; j
< i
; j
++)
460 mlx5_core_destroy_sq(hp
->peer_mdev
, hp
->sqn
[j
]);
461 i
= hp
->num_channels
;
463 for (j
= 0; j
< i
; j
++)
464 mlx5_core_destroy_rq(hp
->func_mdev
, hp
->rqn
[j
]);
468 static void mlx5_hairpin_destroy_queues(struct mlx5_hairpin
*hp
)
472 for (i
= 0; i
< hp
->num_channels
; i
++) {
473 mlx5_core_destroy_rq(hp
->func_mdev
, hp
->rqn
[i
]);
474 mlx5_core_destroy_sq(hp
->peer_mdev
, hp
->sqn
[i
]);
478 static int mlx5_hairpin_modify_rq(struct mlx5_core_dev
*func_mdev
, u32 rqn
,
479 int curr_state
, int next_state
,
480 u16 peer_vhca
, u32 peer_sq
)
482 u32 in
[MLX5_ST_SZ_DW(modify_rq_in
)] = {0};
485 rqc
= MLX5_ADDR_OF(modify_rq_in
, in
, ctx
);
487 if (next_state
== MLX5_RQC_STATE_RDY
) {
488 MLX5_SET(rqc
, rqc
, hairpin_peer_sq
, peer_sq
);
489 MLX5_SET(rqc
, rqc
, hairpin_peer_vhca
, peer_vhca
);
492 MLX5_SET(modify_rq_in
, in
, rq_state
, curr_state
);
493 MLX5_SET(rqc
, rqc
, state
, next_state
);
495 return mlx5_core_modify_rq(func_mdev
, rqn
,
496 in
, MLX5_ST_SZ_BYTES(modify_rq_in
));
499 static int mlx5_hairpin_modify_sq(struct mlx5_core_dev
*peer_mdev
, u32 sqn
,
500 int curr_state
, int next_state
,
501 u16 peer_vhca
, u32 peer_rq
)
503 u32 in
[MLX5_ST_SZ_DW(modify_sq_in
)] = {0};
506 sqc
= MLX5_ADDR_OF(modify_sq_in
, in
, ctx
);
508 if (next_state
== MLX5_RQC_STATE_RDY
) {
509 MLX5_SET(sqc
, sqc
, hairpin_peer_rq
, peer_rq
);
510 MLX5_SET(sqc
, sqc
, hairpin_peer_vhca
, peer_vhca
);
513 MLX5_SET(modify_sq_in
, in
, sq_state
, curr_state
);
514 MLX5_SET(sqc
, sqc
, state
, next_state
);
516 return mlx5_core_modify_sq(peer_mdev
, sqn
,
517 in
, MLX5_ST_SZ_BYTES(modify_sq_in
));
520 static int mlx5_hairpin_pair_queues(struct mlx5_hairpin
*hp
)
525 for (i
= 0; i
< hp
->num_channels
; i
++) {
526 err
= mlx5_hairpin_modify_sq(hp
->peer_mdev
, hp
->sqn
[i
],
527 MLX5_SQC_STATE_RST
, MLX5_SQC_STATE_RDY
,
528 MLX5_CAP_GEN(hp
->func_mdev
, vhca_id
), hp
->rqn
[i
]);
534 for (i
= 0; i
< hp
->num_channels
; i
++) {
535 err
= mlx5_hairpin_modify_rq(hp
->func_mdev
, hp
->rqn
[i
],
536 MLX5_RQC_STATE_RST
, MLX5_RQC_STATE_RDY
,
537 MLX5_CAP_GEN(hp
->peer_mdev
, vhca_id
), hp
->sqn
[i
]);
545 for (j
= 0; j
< i
; j
++)
546 mlx5_hairpin_modify_rq(hp
->func_mdev
, hp
->rqn
[j
], MLX5_RQC_STATE_RDY
,
547 MLX5_RQC_STATE_RST
, 0, 0);
548 i
= hp
->num_channels
;
550 for (j
= 0; j
< i
; j
++)
551 mlx5_hairpin_modify_sq(hp
->peer_mdev
, hp
->sqn
[j
], MLX5_SQC_STATE_RDY
,
552 MLX5_SQC_STATE_RST
, 0, 0);
556 static void mlx5_hairpin_unpair_queues(struct mlx5_hairpin
*hp
)
561 for (i
= 0; i
< hp
->num_channels
; i
++)
562 mlx5_hairpin_modify_rq(hp
->func_mdev
, hp
->rqn
[i
], MLX5_RQC_STATE_RDY
,
563 MLX5_RQC_STATE_RST
, 0, 0);
566 for (i
= 0; i
< hp
->num_channels
; i
++)
567 mlx5_hairpin_modify_sq(hp
->peer_mdev
, hp
->sqn
[i
], MLX5_SQC_STATE_RDY
,
568 MLX5_SQC_STATE_RST
, 0, 0);
571 struct mlx5_hairpin
*
572 mlx5_core_hairpin_create(struct mlx5_core_dev
*func_mdev
,
573 struct mlx5_core_dev
*peer_mdev
,
574 struct mlx5_hairpin_params
*params
)
576 struct mlx5_hairpin
*hp
;
579 size
= sizeof(*hp
) + params
->num_channels
* 2 * sizeof(u32
);
580 hp
= kzalloc(size
, GFP_KERNEL
);
582 return ERR_PTR(-ENOMEM
);
584 hp
->func_mdev
= func_mdev
;
585 hp
->peer_mdev
= peer_mdev
;
586 hp
->num_channels
= params
->num_channels
;
588 hp
->rqn
= (void *)hp
+ sizeof(*hp
);
589 hp
->sqn
= hp
->rqn
+ params
->num_channels
;
591 /* alloc and pair func --> peer hairpin */
592 err
= mlx5_hairpin_create_queues(hp
, params
);
594 goto err_create_queues
;
596 err
= mlx5_hairpin_pair_queues(hp
);
598 goto err_pair_queues
;
603 mlx5_hairpin_destroy_queues(hp
);
609 void mlx5_core_hairpin_destroy(struct mlx5_hairpin
*hp
)
611 mlx5_hairpin_unpair_queues(hp
);
612 mlx5_hairpin_destroy_queues(hp
);