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