1290650Shselasky/*-
2290650Shselasky * Copyright (c) 2013-2015, Mellanox Technologies, Ltd.  All rights reserved.
3290650Shselasky *
4290650Shselasky * Redistribution and use in source and binary forms, with or without
5290650Shselasky * modification, are permitted provided that the following conditions
6290650Shselasky * are met:
7290650Shselasky * 1. Redistributions of source code must retain the above copyright
8290650Shselasky *    notice, this list of conditions and the following disclaimer.
9290650Shselasky * 2. Redistributions in binary form must reproduce the above copyright
10290650Shselasky *    notice, this list of conditions and the following disclaimer in the
11290650Shselasky *    documentation and/or other materials provided with the distribution.
12290650Shselasky *
13290650Shselasky * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND
14290650Shselasky * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15290650Shselasky * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16290650Shselasky * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
17290650Shselasky * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18290650Shselasky * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19290650Shselasky * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20290650Shselasky * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21290650Shselasky * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22290650Shselasky * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23290650Shselasky * SUCH DAMAGE.
24290650Shselasky *
25290650Shselasky * $FreeBSD: stable/10/sys/dev/mlx5/mlx5_core/mlx5_qp.c 306244 2016-09-23 08:28:44Z hselasky $
26290650Shselasky */
27290650Shselasky
28290650Shselasky
29290650Shselasky#include <linux/gfp.h>
30290650Shselasky#include <dev/mlx5/qp.h>
31290650Shselasky#include <dev/mlx5/driver.h>
32290650Shselasky
33290650Shselasky#include "mlx5_core.h"
34290650Shselasky
35306244Shselasky#include "transobj.h"
36306244Shselasky
37290650Shselaskystatic struct mlx5_core_rsc_common *mlx5_get_rsc(struct mlx5_core_dev *dev,
38290650Shselasky						 u32 rsn)
39290650Shselasky{
40290650Shselasky	struct mlx5_qp_table *table = &dev->priv.qp_table;
41290650Shselasky	struct mlx5_core_rsc_common *common;
42290650Shselasky
43290650Shselasky	spin_lock(&table->lock);
44290650Shselasky
45290650Shselasky	common = radix_tree_lookup(&table->tree, rsn);
46290650Shselasky	if (common)
47290650Shselasky		atomic_inc(&common->refcount);
48290650Shselasky
49290650Shselasky	spin_unlock(&table->lock);
50290650Shselasky
51290650Shselasky	if (!common) {
52290650Shselasky		mlx5_core_warn(dev, "Async event for bogus resource 0x%x\n",
53290650Shselasky			       rsn);
54290650Shselasky		return NULL;
55290650Shselasky	}
56290650Shselasky	return common;
57290650Shselasky}
58290650Shselasky
59290650Shselaskyvoid mlx5_core_put_rsc(struct mlx5_core_rsc_common *common)
60290650Shselasky{
61290650Shselasky	if (atomic_dec_and_test(&common->refcount))
62290650Shselasky		complete(&common->free);
63290650Shselasky}
64290650Shselasky
65290650Shselaskyvoid mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type)
66290650Shselasky{
67290650Shselasky	struct mlx5_core_rsc_common *common = mlx5_get_rsc(dev, rsn);
68290650Shselasky	struct mlx5_core_qp *qp;
69290650Shselasky
70290650Shselasky	if (!common)
71290650Shselasky		return;
72290650Shselasky
73290650Shselasky	switch (common->res) {
74290650Shselasky	case MLX5_RES_QP:
75290650Shselasky		qp = (struct mlx5_core_qp *)common;
76290650Shselasky		qp->event(qp, event_type);
77290650Shselasky		break;
78290650Shselasky
79290650Shselasky	default:
80290650Shselasky		mlx5_core_warn(dev, "invalid resource type for 0x%x\n", rsn);
81290650Shselasky	}
82290650Shselasky
83290650Shselasky	mlx5_core_put_rsc(common);
84290650Shselasky}
85290650Shselasky
86306244Shselaskystatic int create_qprqsq_common(struct mlx5_core_dev *dev,
87306244Shselasky				struct mlx5_core_qp *qp, int rsc_type)
88306244Shselasky{
89306244Shselasky	struct mlx5_qp_table *table = &dev->priv.qp_table;
90306244Shselasky	int err;
91306244Shselasky
92306244Shselasky	qp->common.res = rsc_type;
93306244Shselasky
94306244Shselasky	spin_lock_irq(&table->lock);
95306244Shselasky	err = radix_tree_insert(&table->tree, qp->qpn | (rsc_type << 24), qp);
96306244Shselasky	spin_unlock_irq(&table->lock);
97306244Shselasky	if (err)
98306244Shselasky		return err;
99306244Shselasky
100306244Shselasky	atomic_set(&qp->common.refcount, 1);
101306244Shselasky	init_completion(&qp->common.free);
102306244Shselasky	qp->pid = curthread->td_proc->p_pid;
103306244Shselasky
104306244Shselasky	return 0;
105306244Shselasky}
106306244Shselasky
107306244Shselaskystatic void destroy_qprqsq_common(struct mlx5_core_dev *dev,
108306244Shselasky				  struct mlx5_core_qp *qp, int rsc_type)
109306244Shselasky{
110306244Shselasky	struct mlx5_qp_table *table = &dev->priv.qp_table;
111306244Shselasky	unsigned long flags;
112306244Shselasky
113306244Shselasky	spin_lock_irqsave(&table->lock, flags);
114306244Shselasky	radix_tree_delete(&table->tree, qp->qpn | (rsc_type << 24));
115306244Shselasky	spin_unlock_irqrestore(&table->lock, flags);
116306244Shselasky
117306244Shselasky	mlx5_core_put_rsc((struct mlx5_core_rsc_common *)qp);
118306244Shselasky	wait_for_completion(&qp->common.free);
119306244Shselasky}
120306244Shselasky
121290650Shselaskyint mlx5_core_create_qp(struct mlx5_core_dev *dev,
122290650Shselasky			struct mlx5_core_qp *qp,
123290650Shselasky			struct mlx5_create_qp_mbox_in *in,
124290650Shselasky			int inlen)
125290650Shselasky{
126290650Shselasky	struct mlx5_create_qp_mbox_out out;
127290650Shselasky	struct mlx5_destroy_qp_mbox_in din;
128290650Shselasky	struct mlx5_destroy_qp_mbox_out dout;
129290650Shselasky	int err;
130290650Shselasky
131290650Shselasky	memset(&out, 0, sizeof(out));
132290650Shselasky	in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_CREATE_QP);
133290650Shselasky
134290650Shselasky	err = mlx5_cmd_exec(dev, in, inlen, &out, sizeof(out));
135290650Shselasky	if (err) {
136290650Shselasky		mlx5_core_warn(dev, "ret %d\n", err);
137290650Shselasky		return err;
138290650Shselasky	}
139290650Shselasky
140290650Shselasky	if (out.hdr.status) {
141290650Shselasky		mlx5_core_warn(dev, "current num of QPs 0x%x\n",
142290650Shselasky			       atomic_read(&dev->num_qps));
143290650Shselasky		return mlx5_cmd_status_to_err(&out.hdr);
144290650Shselasky	}
145290650Shselasky
146290650Shselasky	qp->qpn = be32_to_cpu(out.qpn) & 0xffffff;
147290650Shselasky	mlx5_core_dbg(dev, "qpn = 0x%x\n", qp->qpn);
148290650Shselasky
149306244Shselasky	err = create_qprqsq_common(dev, qp, MLX5_RES_QP);
150306244Shselasky	if (err)
151290650Shselasky		goto err_cmd;
152290650Shselasky
153290650Shselasky	atomic_inc(&dev->num_qps);
154290650Shselasky
155290650Shselasky	return 0;
156290650Shselasky
157290650Shselaskyerr_cmd:
158290650Shselasky	memset(&din, 0, sizeof(din));
159290650Shselasky	memset(&dout, 0, sizeof(dout));
160290650Shselasky	din.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DESTROY_QP);
161290650Shselasky	din.qpn = cpu_to_be32(qp->qpn);
162290650Shselasky	mlx5_cmd_exec(dev, &din, sizeof(din), &out, sizeof(dout));
163290650Shselasky
164290650Shselasky	return err;
165290650Shselasky}
166290650ShselaskyEXPORT_SYMBOL_GPL(mlx5_core_create_qp);
167290650Shselasky
168290650Shselaskyint mlx5_core_destroy_qp(struct mlx5_core_dev *dev,
169290650Shselasky			 struct mlx5_core_qp *qp)
170290650Shselasky{
171290650Shselasky	struct mlx5_destroy_qp_mbox_in in;
172290650Shselasky	struct mlx5_destroy_qp_mbox_out out;
173290650Shselasky	int err;
174290650Shselasky
175290650Shselasky
176306244Shselasky	destroy_qprqsq_common(dev, qp, MLX5_RES_QP);
177290650Shselasky
178290650Shselasky	memset(&in, 0, sizeof(in));
179290650Shselasky	memset(&out, 0, sizeof(out));
180290650Shselasky	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DESTROY_QP);
181290650Shselasky	in.qpn = cpu_to_be32(qp->qpn);
182290650Shselasky	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
183290650Shselasky	if (err)
184290650Shselasky		return err;
185290650Shselasky
186290650Shselasky	if (out.hdr.status)
187290650Shselasky		return mlx5_cmd_status_to_err(&out.hdr);
188290650Shselasky
189290650Shselasky	atomic_dec(&dev->num_qps);
190290650Shselasky	return 0;
191290650Shselasky}
192290650ShselaskyEXPORT_SYMBOL_GPL(mlx5_core_destroy_qp);
193290650Shselasky
194306244Shselaskyint mlx5_core_qp_modify(struct mlx5_core_dev *dev, u16 operation,
195290650Shselasky			struct mlx5_modify_qp_mbox_in *in, int sqd_event,
196290650Shselasky			struct mlx5_core_qp *qp)
197290650Shselasky{
198290650Shselasky	struct mlx5_modify_qp_mbox_out out;
199290650Shselasky	int err = 0;
200290650Shselasky
201290650Shselasky	memset(&out, 0, sizeof(out));
202306244Shselasky	in->hdr.opcode = cpu_to_be16(operation);
203290650Shselasky	in->qpn = cpu_to_be32(qp->qpn);
204290650Shselasky	err = mlx5_cmd_exec(dev, in, sizeof(*in), &out, sizeof(out));
205290650Shselasky	if (err)
206290650Shselasky		return err;
207290650Shselasky
208290650Shselasky	return mlx5_cmd_status_to_err(&out.hdr);
209290650Shselasky}
210290650ShselaskyEXPORT_SYMBOL_GPL(mlx5_core_qp_modify);
211290650Shselasky
212290650Shselaskyvoid mlx5_init_qp_table(struct mlx5_core_dev *dev)
213290650Shselasky{
214290650Shselasky	struct mlx5_qp_table *table = &dev->priv.qp_table;
215290650Shselasky
216290650Shselasky	spin_lock_init(&table->lock);
217290650Shselasky	INIT_RADIX_TREE(&table->tree, GFP_ATOMIC);
218290650Shselasky}
219290650Shselasky
220290650Shselaskyvoid mlx5_cleanup_qp_table(struct mlx5_core_dev *dev)
221290650Shselasky{
222290650Shselasky}
223290650Shselasky
224290650Shselaskyint mlx5_core_qp_query(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp,
225290650Shselasky		       struct mlx5_query_qp_mbox_out *out, int outlen)
226290650Shselasky{
227290650Shselasky	struct mlx5_query_qp_mbox_in in;
228290650Shselasky	int err;
229290650Shselasky
230290650Shselasky	memset(&in, 0, sizeof(in));
231290650Shselasky	memset(out, 0, outlen);
232290650Shselasky	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_QP);
233290650Shselasky	in.qpn = cpu_to_be32(qp->qpn);
234290650Shselasky	err = mlx5_cmd_exec(dev, &in, sizeof(in), out, outlen);
235290650Shselasky	if (err)
236290650Shselasky		return err;
237290650Shselasky
238290650Shselasky	if (out->hdr.status)
239290650Shselasky		return mlx5_cmd_status_to_err(&out->hdr);
240290650Shselasky
241290650Shselasky	return err;
242290650Shselasky}
243290650ShselaskyEXPORT_SYMBOL_GPL(mlx5_core_qp_query);
244290650Shselasky
245290650Shselaskyint mlx5_core_xrcd_alloc(struct mlx5_core_dev *dev, u32 *xrcdn)
246290650Shselasky{
247290650Shselasky	u32 in[MLX5_ST_SZ_DW(alloc_xrcd_in)];
248290650Shselasky	u32 out[MLX5_ST_SZ_DW(alloc_xrcd_out)];
249290650Shselasky	int err;
250290650Shselasky
251290650Shselasky	memset(in, 0, sizeof(in));
252290650Shselasky
253290650Shselasky	MLX5_SET(alloc_xrcd_in, in, opcode, MLX5_CMD_OP_ALLOC_XRCD);
254290650Shselasky
255290650Shselasky	memset(out, 0, sizeof(out));
256290650Shselasky	err = mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
257290650Shselasky	if (err)
258290650Shselasky		return err;
259290650Shselasky
260290650Shselasky	*xrcdn = MLX5_GET(alloc_xrcd_out, out, xrcd);
261290650Shselasky	return 0;
262290650Shselasky}
263290650ShselaskyEXPORT_SYMBOL_GPL(mlx5_core_xrcd_alloc);
264290650Shselasky
265290650Shselaskyint mlx5_core_xrcd_dealloc(struct mlx5_core_dev *dev, u32 xrcdn)
266290650Shselasky{
267290650Shselasky	u32 in[MLX5_ST_SZ_DW(dealloc_xrcd_in)];
268290650Shselasky	u32 out[MLX5_ST_SZ_DW(dealloc_xrcd_out)];
269290650Shselasky
270290650Shselasky	memset(in, 0, sizeof(in));
271290650Shselasky
272290650Shselasky	MLX5_SET(dealloc_xrcd_in, in, opcode, MLX5_CMD_OP_DEALLOC_XRCD);
273290650Shselasky	MLX5_SET(dealloc_xrcd_in, in, xrcd, xrcdn);
274290650Shselasky
275290650Shselasky	memset(out, 0, sizeof(out));
276290650Shselasky	return mlx5_cmd_exec_check_status(dev, in,  sizeof(in),
277290650Shselasky					       out, sizeof(out));
278290650Shselasky}
279290650ShselaskyEXPORT_SYMBOL_GPL(mlx5_core_xrcd_dealloc);
280306244Shselasky
281306244Shselaskyint mlx5_core_create_dct(struct mlx5_core_dev *dev,
282306244Shselasky			 struct mlx5_core_dct *dct,
283306244Shselasky			 struct mlx5_create_dct_mbox_in *in)
284306244Shselasky{
285306244Shselasky	struct mlx5_qp_table *table = &dev->priv.qp_table;
286306244Shselasky	struct mlx5_create_dct_mbox_out out;
287306244Shselasky	struct mlx5_destroy_dct_mbox_in din;
288306244Shselasky	struct mlx5_destroy_dct_mbox_out dout;
289306244Shselasky	int err;
290306244Shselasky
291306244Shselasky	init_completion(&dct->drained);
292306244Shselasky	memset(&out, 0, sizeof(out));
293306244Shselasky	in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_CREATE_DCT);
294306244Shselasky
295306244Shselasky	err = mlx5_cmd_exec(dev, in, sizeof(*in), &out, sizeof(out));
296306244Shselasky	if (err) {
297306244Shselasky		mlx5_core_warn(dev, "create DCT failed, ret %d", err);
298306244Shselasky		return err;
299306244Shselasky	}
300306244Shselasky
301306244Shselasky	if (out.hdr.status)
302306244Shselasky		return mlx5_cmd_status_to_err(&out.hdr);
303306244Shselasky
304306244Shselasky	dct->dctn = be32_to_cpu(out.dctn) & 0xffffff;
305306244Shselasky
306306244Shselasky	dct->common.res = MLX5_RES_DCT;
307306244Shselasky	spin_lock_irq(&table->lock);
308306244Shselasky	err = radix_tree_insert(&table->tree, dct->dctn, dct);
309306244Shselasky	spin_unlock_irq(&table->lock);
310306244Shselasky	if (err) {
311306244Shselasky		mlx5_core_warn(dev, "err %d", err);
312306244Shselasky		goto err_cmd;
313306244Shselasky	}
314306244Shselasky
315306244Shselasky	dct->pid = curthread->td_proc->p_pid;
316306244Shselasky	atomic_set(&dct->common.refcount, 1);
317306244Shselasky	init_completion(&dct->common.free);
318306244Shselasky
319306244Shselasky	return 0;
320306244Shselasky
321306244Shselaskyerr_cmd:
322306244Shselasky	memset(&din, 0, sizeof(din));
323306244Shselasky	memset(&dout, 0, sizeof(dout));
324306244Shselasky	din.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DESTROY_DCT);
325306244Shselasky	din.dctn = cpu_to_be32(dct->dctn);
326306244Shselasky	mlx5_cmd_exec(dev, &din, sizeof(din), &out, sizeof(dout));
327306244Shselasky
328306244Shselasky	return err;
329306244Shselasky}
330306244ShselaskyEXPORT_SYMBOL_GPL(mlx5_core_create_dct);
331306244Shselasky
332306244Shselaskystatic int mlx5_core_drain_dct(struct mlx5_core_dev *dev,
333306244Shselasky			       struct mlx5_core_dct *dct)
334306244Shselasky{
335306244Shselasky	struct mlx5_drain_dct_mbox_out out;
336306244Shselasky	struct mlx5_drain_dct_mbox_in in;
337306244Shselasky	int err;
338306244Shselasky
339306244Shselasky	memset(&in, 0, sizeof(in));
340306244Shselasky	memset(&out, 0, sizeof(out));
341306244Shselasky	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DRAIN_DCT);
342306244Shselasky	in.dctn = cpu_to_be32(dct->dctn);
343306244Shselasky	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
344306244Shselasky	if (err)
345306244Shselasky		return err;
346306244Shselasky
347306244Shselasky	if (out.hdr.status)
348306244Shselasky		return mlx5_cmd_status_to_err(&out.hdr);
349306244Shselasky
350306244Shselasky	return 0;
351306244Shselasky}
352306244Shselasky
353306244Shselaskyint mlx5_core_destroy_dct(struct mlx5_core_dev *dev,
354306244Shselasky			  struct mlx5_core_dct *dct)
355306244Shselasky{
356306244Shselasky	struct mlx5_qp_table *table = &dev->priv.qp_table;
357306244Shselasky	struct mlx5_destroy_dct_mbox_out out;
358306244Shselasky	struct mlx5_destroy_dct_mbox_in in;
359306244Shselasky	unsigned long flags;
360306244Shselasky	int err;
361306244Shselasky
362306244Shselasky	err = mlx5_core_drain_dct(dev, dct);
363306244Shselasky	if (err) {
364306244Shselasky		mlx5_core_warn(dev, "failed drain DCT 0x%x\n", dct->dctn);
365306244Shselasky		return err;
366306244Shselasky	}
367306244Shselasky
368306244Shselasky	wait_for_completion(&dct->drained);
369306244Shselasky
370306244Shselasky	spin_lock_irqsave(&table->lock, flags);
371306244Shselasky	if (radix_tree_delete(&table->tree, dct->dctn) != dct)
372306244Shselasky		mlx5_core_warn(dev, "dct delete differs\n");
373306244Shselasky	spin_unlock_irqrestore(&table->lock, flags);
374306244Shselasky
375306244Shselasky	if (atomic_dec_and_test(&dct->common.refcount))
376306244Shselasky		complete(&dct->common.free);
377306244Shselasky	wait_for_completion(&dct->common.free);
378306244Shselasky
379306244Shselasky	memset(&in, 0, sizeof(in));
380306244Shselasky	memset(&out, 0, sizeof(out));
381306244Shselasky	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DESTROY_DCT);
382306244Shselasky	in.dctn = cpu_to_be32(dct->dctn);
383306244Shselasky	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
384306244Shselasky	if (err)
385306244Shselasky		return err;
386306244Shselasky
387306244Shselasky	if (out.hdr.status)
388306244Shselasky		return mlx5_cmd_status_to_err(&out.hdr);
389306244Shselasky
390306244Shselasky	return 0;
391306244Shselasky}
392306244ShselaskyEXPORT_SYMBOL_GPL(mlx5_core_destroy_dct);
393306244Shselasky
394306244Shselaskyint mlx5_core_dct_query(struct mlx5_core_dev *dev, struct mlx5_core_dct *dct,
395306244Shselasky			struct mlx5_query_dct_mbox_out *out)
396306244Shselasky{
397306244Shselasky	struct mlx5_query_dct_mbox_in in;
398306244Shselasky	int err;
399306244Shselasky
400306244Shselasky	memset(&in, 0, sizeof(in));
401306244Shselasky	memset(out, 0, sizeof(*out));
402306244Shselasky	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_DCT);
403306244Shselasky	in.dctn = cpu_to_be32(dct->dctn);
404306244Shselasky	err = mlx5_cmd_exec(dev, &in, sizeof(in), out, sizeof(*out));
405306244Shselasky	if (err)
406306244Shselasky		return err;
407306244Shselasky
408306244Shselasky	if (out->hdr.status)
409306244Shselasky		return mlx5_cmd_status_to_err(&out->hdr);
410306244Shselasky
411306244Shselasky	return err;
412306244Shselasky}
413306244ShselaskyEXPORT_SYMBOL_GPL(mlx5_core_dct_query);
414306244Shselasky
415306244Shselaskyint mlx5_core_arm_dct(struct mlx5_core_dev *dev, struct mlx5_core_dct *dct)
416306244Shselasky{
417306244Shselasky	struct mlx5_arm_dct_mbox_out out;
418306244Shselasky	struct mlx5_arm_dct_mbox_in in;
419306244Shselasky	int err;
420306244Shselasky
421306244Shselasky	memset(&in, 0, sizeof(in));
422306244Shselasky	memset(&out, 0, sizeof(out));
423306244Shselasky
424306244Shselasky	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_ARM_DCT_FOR_KEY_VIOLATION);
425306244Shselasky	in.dctn = cpu_to_be32(dct->dctn);
426306244Shselasky	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
427306244Shselasky	if (err)
428306244Shselasky		return err;
429306244Shselasky
430306244Shselasky	if (out.hdr.status)
431306244Shselasky		return mlx5_cmd_status_to_err(&out.hdr);
432306244Shselasky
433306244Shselasky	return err;
434306244Shselasky}
435306244ShselaskyEXPORT_SYMBOL_GPL(mlx5_core_arm_dct);
436306244Shselasky
437306244Shselaskyint mlx5_core_create_rq_tracked(struct mlx5_core_dev *dev, u32 *in, int inlen,
438306244Shselasky				struct mlx5_core_qp *rq)
439306244Shselasky{
440306244Shselasky	int err;
441306244Shselasky
442306244Shselasky	err = mlx5_core_create_rq(dev, in, inlen, &rq->qpn);
443306244Shselasky	if (err)
444306244Shselasky		return err;
445306244Shselasky
446306244Shselasky	err = create_qprqsq_common(dev, rq, MLX5_RES_RQ);
447306244Shselasky	if (err)
448306244Shselasky		mlx5_core_destroy_rq(dev, rq->qpn);
449306244Shselasky
450306244Shselasky	return err;
451306244Shselasky}
452306244ShselaskyEXPORT_SYMBOL(mlx5_core_create_rq_tracked);
453306244Shselasky
454306244Shselaskyvoid mlx5_core_destroy_rq_tracked(struct mlx5_core_dev *dev,
455306244Shselasky				  struct mlx5_core_qp *rq)
456306244Shselasky{
457306244Shselasky	destroy_qprqsq_common(dev, rq, MLX5_RES_RQ);
458306244Shselasky	mlx5_core_destroy_rq(dev, rq->qpn);
459306244Shselasky}
460306244ShselaskyEXPORT_SYMBOL(mlx5_core_destroy_rq_tracked);
461306244Shselasky
462306244Shselaskyint mlx5_core_create_sq_tracked(struct mlx5_core_dev *dev, u32 *in, int inlen,
463306244Shselasky				struct mlx5_core_qp *sq)
464306244Shselasky{
465306244Shselasky	int err;
466306244Shselasky
467306244Shselasky	err = mlx5_core_create_sq(dev, in, inlen, &sq->qpn);
468306244Shselasky	if (err)
469306244Shselasky		return err;
470306244Shselasky
471306244Shselasky	err = create_qprqsq_common(dev, sq, MLX5_RES_SQ);
472306244Shselasky	if (err)
473306244Shselasky		mlx5_core_destroy_sq(dev, sq->qpn);
474306244Shselasky
475306244Shselasky	return err;
476306244Shselasky}
477306244ShselaskyEXPORT_SYMBOL(mlx5_core_create_sq_tracked);
478306244Shselasky
479306244Shselaskyvoid mlx5_core_destroy_sq_tracked(struct mlx5_core_dev *dev,
480306244Shselasky				  struct mlx5_core_qp *sq)
481306244Shselasky{
482306244Shselasky	destroy_qprqsq_common(dev, sq, MLX5_RES_SQ);
483306244Shselasky	mlx5_core_destroy_sq(dev, sq->qpn);
484306244Shselasky}
485306244ShselaskyEXPORT_SYMBOL(mlx5_core_destroy_sq_tracked);
486