2 * Copyright (c) 2016, Mellanox Technologies. 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
35 struct mlx5_ib_gsi_wr
{
42 struct mlx5_ib_gsi_qp
{
47 enum ib_sig_type sq_sig_type
;
48 /* Serialize qp state modifications */
51 struct mlx5_ib_gsi_wr
*outstanding_wrs
;
52 u32 outstanding_pi
, outstanding_ci
;
54 /* Protects access to the tx_qps. Post send operations synchronize
55 * with tx_qp creation in setup_qp(). Also protects the
56 * outstanding_wrs array and indices.
59 struct ib_qp
**tx_qps
;
62 static struct mlx5_ib_gsi_qp
*gsi_qp(struct ib_qp
*qp
)
64 return container_of(qp
, struct mlx5_ib_gsi_qp
, ibqp
);
67 static bool mlx5_ib_deth_sqpn_cap(struct mlx5_ib_dev
*dev
)
69 return MLX5_CAP_GEN(dev
->mdev
, set_deth_sqpn
);
72 static u32
next_outstanding(struct mlx5_ib_gsi_qp
*gsi
, u32 index
)
74 return ++index
% gsi
->cap
.max_send_wr
;
77 #define for_each_outstanding_wr(gsi, index) \
78 for (index = gsi->outstanding_ci; index != gsi->outstanding_pi; \
79 index = next_outstanding(gsi, index))
81 /* Call with gsi->lock locked */
82 static void generate_completions(struct mlx5_ib_gsi_qp
*gsi
)
84 struct ib_cq
*gsi_cq
= gsi
->ibqp
.send_cq
;
85 struct mlx5_ib_gsi_wr
*wr
;
88 for_each_outstanding_wr(gsi
, index
) {
89 wr
= &gsi
->outstanding_wrs
[index
];
94 if (gsi
->sq_sig_type
== IB_SIGNAL_ALL_WR
||
95 wr
->send_flags
& IB_SEND_SIGNALED
)
96 WARN_ON_ONCE(mlx5_ib_generate_wc(gsi_cq
, &wr
->wc
));
98 wr
->completed
= false;
101 gsi
->outstanding_ci
= index
;
104 static void handle_single_completion(struct ib_cq
*cq
, struct ib_wc
*wc
)
106 struct mlx5_ib_gsi_qp
*gsi
= cq
->cq_context
;
107 struct mlx5_ib_gsi_wr
*wr
=
108 container_of(wc
->wr_cqe
, struct mlx5_ib_gsi_wr
, cqe
);
112 spin_lock_irqsave(&gsi
->lock
, flags
);
113 wr
->completed
= true;
114 wr_id
= wr
->wc
.wr_id
;
116 wr
->wc
.wr_id
= wr_id
;
117 wr
->wc
.qp
= &gsi
->ibqp
;
119 generate_completions(gsi
);
120 spin_unlock_irqrestore(&gsi
->lock
, flags
);
123 struct ib_qp
*mlx5_ib_gsi_create_qp(struct ib_pd
*pd
,
124 struct ib_qp_init_attr
*init_attr
)
126 struct mlx5_ib_dev
*dev
= to_mdev(pd
->device
);
127 struct mlx5_ib_gsi_qp
*gsi
;
128 struct ib_qp_init_attr hw_init_attr
= *init_attr
;
129 const u8 port_num
= init_attr
->port_num
;
130 const int num_pkeys
= pd
->device
->attrs
.max_pkeys
;
131 const int num_qps
= mlx5_ib_deth_sqpn_cap(dev
) ? num_pkeys
: 0;
134 mlx5_ib_dbg(dev
, "creating GSI QP\n");
136 if (port_num
> ARRAY_SIZE(dev
->devr
.ports
) || port_num
< 1) {
138 "invalid port number %d during GSI QP creation\n",
140 return ERR_PTR(-EINVAL
);
143 gsi
= kzalloc(sizeof(*gsi
), GFP_KERNEL
);
145 return ERR_PTR(-ENOMEM
);
147 gsi
->tx_qps
= kcalloc(num_qps
, sizeof(*gsi
->tx_qps
), GFP_KERNEL
);
153 gsi
->outstanding_wrs
= kcalloc(init_attr
->cap
.max_send_wr
,
154 sizeof(*gsi
->outstanding_wrs
),
156 if (!gsi
->outstanding_wrs
) {
161 mutex_init(&gsi
->mutex
);
163 mutex_lock(&dev
->devr
.mutex
);
165 if (dev
->devr
.ports
[port_num
- 1].gsi
) {
166 mlx5_ib_warn(dev
, "GSI QP already exists on port %d\n",
171 gsi
->num_qps
= num_qps
;
172 spin_lock_init(&gsi
->lock
);
174 gsi
->cap
= init_attr
->cap
;
175 gsi
->sq_sig_type
= init_attr
->sq_sig_type
;
176 gsi
->ibqp
.qp_num
= 1;
177 gsi
->port_num
= port_num
;
179 gsi
->cq
= ib_alloc_cq(pd
->device
, gsi
, init_attr
->cap
.max_send_wr
, 0,
181 if (IS_ERR(gsi
->cq
)) {
182 mlx5_ib_warn(dev
, "unable to create send CQ for GSI QP. error %ld\n",
184 ret
= PTR_ERR(gsi
->cq
);
188 hw_init_attr
.qp_type
= MLX5_IB_QPT_HW_GSI
;
189 hw_init_attr
.send_cq
= gsi
->cq
;
191 hw_init_attr
.cap
.max_send_wr
= 0;
192 hw_init_attr
.cap
.max_send_sge
= 0;
193 hw_init_attr
.cap
.max_inline_data
= 0;
195 gsi
->rx_qp
= ib_create_qp(pd
, &hw_init_attr
);
196 if (IS_ERR(gsi
->rx_qp
)) {
197 mlx5_ib_warn(dev
, "unable to create hardware GSI QP. error %ld\n",
198 PTR_ERR(gsi
->rx_qp
));
199 ret
= PTR_ERR(gsi
->rx_qp
);
203 dev
->devr
.ports
[init_attr
->port_num
- 1].gsi
= gsi
;
205 mutex_unlock(&dev
->devr
.mutex
);
212 mutex_unlock(&dev
->devr
.mutex
);
213 kfree(gsi
->outstanding_wrs
);
221 int mlx5_ib_gsi_destroy_qp(struct ib_qp
*qp
)
223 struct mlx5_ib_dev
*dev
= to_mdev(qp
->device
);
224 struct mlx5_ib_gsi_qp
*gsi
= gsi_qp(qp
);
225 const int port_num
= gsi
->port_num
;
229 mlx5_ib_dbg(dev
, "destroying GSI QP\n");
231 mutex_lock(&dev
->devr
.mutex
);
232 ret
= ib_destroy_qp(gsi
->rx_qp
);
234 mlx5_ib_warn(dev
, "unable to destroy hardware GSI QP. error %d\n",
236 mutex_unlock(&dev
->devr
.mutex
);
239 dev
->devr
.ports
[port_num
- 1].gsi
= NULL
;
240 mutex_unlock(&dev
->devr
.mutex
);
243 for (qp_index
= 0; qp_index
< gsi
->num_qps
; ++qp_index
) {
244 if (!gsi
->tx_qps
[qp_index
])
246 WARN_ON_ONCE(ib_destroy_qp(gsi
->tx_qps
[qp_index
]));
247 gsi
->tx_qps
[qp_index
] = NULL
;
252 kfree(gsi
->outstanding_wrs
);
259 static struct ib_qp
*create_gsi_ud_qp(struct mlx5_ib_gsi_qp
*gsi
)
261 struct ib_pd
*pd
= gsi
->rx_qp
->pd
;
262 struct ib_qp_init_attr init_attr
= {
263 .event_handler
= gsi
->rx_qp
->event_handler
,
264 .qp_context
= gsi
->rx_qp
->qp_context
,
266 .recv_cq
= gsi
->rx_qp
->recv_cq
,
268 .max_send_wr
= gsi
->cap
.max_send_wr
,
269 .max_send_sge
= gsi
->cap
.max_send_sge
,
270 .max_inline_data
= gsi
->cap
.max_inline_data
,
272 .sq_sig_type
= gsi
->sq_sig_type
,
273 .qp_type
= IB_QPT_UD
,
274 .create_flags
= mlx5_ib_create_qp_sqpn_qp1(),
277 return ib_create_qp(pd
, &init_attr
);
280 static int modify_to_rts(struct mlx5_ib_gsi_qp
*gsi
, struct ib_qp
*qp
,
283 struct mlx5_ib_dev
*dev
= to_mdev(qp
->device
);
284 struct ib_qp_attr attr
;
288 mask
= IB_QP_STATE
| IB_QP_PKEY_INDEX
| IB_QP_QKEY
| IB_QP_PORT
;
289 attr
.qp_state
= IB_QPS_INIT
;
290 attr
.pkey_index
= qp_index
;
291 attr
.qkey
= IB_QP1_QKEY
;
292 attr
.port_num
= gsi
->port_num
;
293 ret
= ib_modify_qp(qp
, &attr
, mask
);
295 mlx5_ib_err(dev
, "could not change QP%d state to INIT: %d\n",
300 attr
.qp_state
= IB_QPS_RTR
;
301 ret
= ib_modify_qp(qp
, &attr
, IB_QP_STATE
);
303 mlx5_ib_err(dev
, "could not change QP%d state to RTR: %d\n",
308 attr
.qp_state
= IB_QPS_RTS
;
310 ret
= ib_modify_qp(qp
, &attr
, IB_QP_STATE
| IB_QP_SQ_PSN
);
312 mlx5_ib_err(dev
, "could not change QP%d state to RTS: %d\n",
320 static void setup_qp(struct mlx5_ib_gsi_qp
*gsi
, u16 qp_index
)
322 struct ib_device
*device
= gsi
->rx_qp
->device
;
323 struct mlx5_ib_dev
*dev
= to_mdev(device
);
329 ret
= ib_query_pkey(device
, gsi
->port_num
, qp_index
, &pkey
);
331 mlx5_ib_warn(dev
, "unable to read P_Key at port %d, index %d\n",
332 gsi
->port_num
, qp_index
);
337 mlx5_ib_dbg(dev
, "invalid P_Key at port %d, index %d. Skipping.\n",
338 gsi
->port_num
, qp_index
);
342 spin_lock_irqsave(&gsi
->lock
, flags
);
343 qp
= gsi
->tx_qps
[qp_index
];
344 spin_unlock_irqrestore(&gsi
->lock
, flags
);
346 mlx5_ib_dbg(dev
, "already existing GSI TX QP at port %d, index %d. Skipping\n",
347 gsi
->port_num
, qp_index
);
351 qp
= create_gsi_ud_qp(gsi
);
353 mlx5_ib_warn(dev
, "unable to create hardware UD QP for GSI: %ld\n",
358 ret
= modify_to_rts(gsi
, qp
, qp_index
);
362 spin_lock_irqsave(&gsi
->lock
, flags
);
363 WARN_ON_ONCE(gsi
->tx_qps
[qp_index
]);
364 gsi
->tx_qps
[qp_index
] = qp
;
365 spin_unlock_irqrestore(&gsi
->lock
, flags
);
373 static void setup_qps(struct mlx5_ib_gsi_qp
*gsi
)
377 for (qp_index
= 0; qp_index
< gsi
->num_qps
; ++qp_index
)
378 setup_qp(gsi
, qp_index
);
381 int mlx5_ib_gsi_modify_qp(struct ib_qp
*qp
, struct ib_qp_attr
*attr
,
384 struct mlx5_ib_dev
*dev
= to_mdev(qp
->device
);
385 struct mlx5_ib_gsi_qp
*gsi
= gsi_qp(qp
);
388 mlx5_ib_dbg(dev
, "modifying GSI QP to state %d\n", attr
->qp_state
);
390 mutex_lock(&gsi
->mutex
);
391 ret
= ib_modify_qp(gsi
->rx_qp
, attr
, attr_mask
);
393 mlx5_ib_warn(dev
, "unable to modify GSI rx QP: %d\n", ret
);
397 if (to_mqp(gsi
->rx_qp
)->state
== IB_QPS_RTS
)
401 mutex_unlock(&gsi
->mutex
);
406 int mlx5_ib_gsi_query_qp(struct ib_qp
*qp
, struct ib_qp_attr
*qp_attr
,
408 struct ib_qp_init_attr
*qp_init_attr
)
410 struct mlx5_ib_gsi_qp
*gsi
= gsi_qp(qp
);
413 mutex_lock(&gsi
->mutex
);
414 ret
= ib_query_qp(gsi
->rx_qp
, qp_attr
, qp_attr_mask
, qp_init_attr
);
415 qp_init_attr
->cap
= gsi
->cap
;
416 mutex_unlock(&gsi
->mutex
);
421 /* Call with gsi->lock locked */
422 static int mlx5_ib_add_outstanding_wr(struct mlx5_ib_gsi_qp
*gsi
,
423 struct ib_ud_wr
*wr
, struct ib_wc
*wc
)
425 struct mlx5_ib_dev
*dev
= to_mdev(gsi
->rx_qp
->device
);
426 struct mlx5_ib_gsi_wr
*gsi_wr
;
428 if (gsi
->outstanding_pi
== gsi
->outstanding_ci
+ gsi
->cap
.max_send_wr
) {
429 mlx5_ib_warn(dev
, "no available GSI work request.\n");
433 gsi_wr
= &gsi
->outstanding_wrs
[gsi
->outstanding_pi
];
434 gsi
->outstanding_pi
= next_outstanding(gsi
, gsi
->outstanding_pi
);
437 memset(&gsi_wr
->wc
, 0, sizeof(gsi_wr
->wc
));
438 gsi_wr
->wc
.pkey_index
= wr
->pkey_index
;
439 gsi_wr
->wc
.wr_id
= wr
->wr
.wr_id
;
442 gsi_wr
->completed
= true;
445 gsi_wr
->cqe
.done
= &handle_single_completion
;
446 wr
->wr
.wr_cqe
= &gsi_wr
->cqe
;
451 /* Call with gsi->lock locked */
452 static int mlx5_ib_gsi_silent_drop(struct mlx5_ib_gsi_qp
*gsi
,
456 { .wr_id
= wr
->wr
.wr_id
},
457 .status
= IB_WC_SUCCESS
,
458 .opcode
= IB_WC_SEND
,
463 ret
= mlx5_ib_add_outstanding_wr(gsi
, wr
, &wc
);
467 generate_completions(gsi
);
472 /* Call with gsi->lock locked */
473 static struct ib_qp
*get_tx_qp(struct mlx5_ib_gsi_qp
*gsi
, struct ib_ud_wr
*wr
)
475 struct mlx5_ib_dev
*dev
= to_mdev(gsi
->rx_qp
->device
);
476 int qp_index
= wr
->pkey_index
;
478 if (!mlx5_ib_deth_sqpn_cap(dev
))
481 if (qp_index
>= gsi
->num_qps
)
484 return gsi
->tx_qps
[qp_index
];
487 int mlx5_ib_gsi_post_send(struct ib_qp
*qp
, struct ib_send_wr
*wr
,
488 struct ib_send_wr
**bad_wr
)
490 struct mlx5_ib_gsi_qp
*gsi
= gsi_qp(qp
);
495 for (; wr
; wr
= wr
->next
) {
496 struct ib_ud_wr cur_wr
= *ud_wr(wr
);
498 cur_wr
.wr
.next
= NULL
;
500 spin_lock_irqsave(&gsi
->lock
, flags
);
501 tx_qp
= get_tx_qp(gsi
, &cur_wr
);
503 ret
= mlx5_ib_gsi_silent_drop(gsi
, &cur_wr
);
506 spin_unlock_irqrestore(&gsi
->lock
, flags
);
510 ret
= mlx5_ib_add_outstanding_wr(gsi
, &cur_wr
, NULL
);
514 ret
= ib_post_send(tx_qp
, &cur_wr
.wr
, bad_wr
);
516 /* Undo the effect of adding the outstanding wr */
517 gsi
->outstanding_pi
= (gsi
->outstanding_pi
- 1) %
518 gsi
->cap
.max_send_wr
;
521 spin_unlock_irqrestore(&gsi
->lock
, flags
);
527 spin_unlock_irqrestore(&gsi
->lock
, flags
);
532 int mlx5_ib_gsi_post_recv(struct ib_qp
*qp
, struct ib_recv_wr
*wr
,
533 struct ib_recv_wr
**bad_wr
)
535 struct mlx5_ib_gsi_qp
*gsi
= gsi_qp(qp
);
537 return ib_post_recv(gsi
->rx_qp
, wr
, bad_wr
);
540 void mlx5_ib_gsi_pkey_change(struct mlx5_ib_gsi_qp
*gsi
)
545 mutex_lock(&gsi
->mutex
);
547 mutex_unlock(&gsi
->mutex
);