mlx5_srq.c revision 331580
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/11/sys/dev/mlx5/mlx5_core/mlx5_srq.c 331580 2018-03-26 20:33:31Z hselasky $ 26290650Shselasky */ 27290650Shselasky 28290650Shselasky#include <linux/kernel.h> 29290650Shselasky#include <linux/module.h> 30290650Shselasky#include <dev/mlx5/driver.h> 31290650Shselasky#include <dev/mlx5/srq.h> 32290650Shselasky#include <rdma/ib_verbs.h> 33290650Shselasky#include "mlx5_core.h" 34290650Shselasky#include "transobj.h" 35290650Shselasky 36290650Shselaskyvoid mlx5_srq_event(struct mlx5_core_dev *dev, u32 srqn, int event_type) 37290650Shselasky{ 38290650Shselasky struct mlx5_srq_table *table = &dev->priv.srq_table; 39290650Shselasky struct mlx5_core_srq *srq; 40290650Shselasky 41290650Shselasky spin_lock(&table->lock); 42290650Shselasky 43290650Shselasky srq = radix_tree_lookup(&table->tree, srqn); 44290650Shselasky if (srq) 45290650Shselasky atomic_inc(&srq->refcount); 46290650Shselasky 47290650Shselasky spin_unlock(&table->lock); 48290650Shselasky 49290650Shselasky if (!srq) { 50290650Shselasky mlx5_core_warn(dev, "Async event for bogus SRQ 0x%08x\n", srqn); 51290650Shselasky return; 52290650Shselasky } 53290650Shselasky 54290650Shselasky srq->event(srq, event_type); 55290650Shselasky 56290650Shselasky if (atomic_dec_and_test(&srq->refcount)) 57290650Shselasky complete(&srq->free); 58290650Shselasky} 59290650Shselasky 60290650Shselaskystatic void rmpc_srqc_reformat(void *srqc, void *rmpc, bool srqc_to_rmpc) 61290650Shselasky{ 62290650Shselasky void *wq = MLX5_ADDR_OF(rmpc, rmpc, wq); 63290650Shselasky 64290650Shselasky if (srqc_to_rmpc) { 65290650Shselasky switch (MLX5_GET(srqc, srqc, state)) { 66290650Shselasky case MLX5_SRQC_STATE_GOOD: 67290650Shselasky MLX5_SET(rmpc, rmpc, state, MLX5_RMPC_STATE_RDY); 68290650Shselasky break; 69290650Shselasky case MLX5_SRQC_STATE_ERROR: 70290650Shselasky MLX5_SET(rmpc, rmpc, state, MLX5_RMPC_STATE_ERR); 71290650Shselasky break; 72290650Shselasky default: 73290650Shselasky printf("mlx5_core: WARN: ""%s: %d: Unknown srq state = 0x%x\n", __func__, __LINE__, MLX5_GET(srqc, srqc, state)); 74290650Shselasky } 75290650Shselasky 76290650Shselasky MLX5_SET(wq, wq, wq_signature, MLX5_GET(srqc, srqc, wq_signature)); 77290650Shselasky MLX5_SET(wq, wq, log_wq_pg_sz, MLX5_GET(srqc, srqc, log_page_size)); 78290650Shselasky MLX5_SET(wq, wq, log_wq_stride, MLX5_GET(srqc, srqc, log_rq_stride) + 4); 79290650Shselasky MLX5_SET(wq, wq, log_wq_sz, MLX5_GET(srqc, srqc, log_srq_size)); 80290650Shselasky MLX5_SET(wq, wq, page_offset, MLX5_GET(srqc, srqc, page_offset)); 81290650Shselasky MLX5_SET(wq, wq, lwm, MLX5_GET(srqc, srqc, lwm)); 82290650Shselasky MLX5_SET(wq, wq, pd, MLX5_GET(srqc, srqc, pd)); 83290650Shselasky MLX5_SET64(wq, wq, dbr_addr, 84290650Shselasky ((u64)MLX5_GET(srqc, srqc, db_record_addr_h)) << 32 | 85290650Shselasky ((u64)MLX5_GET(srqc, srqc, db_record_addr_l)) << 2); 86290650Shselasky } else { 87290650Shselasky switch (MLX5_GET(rmpc, rmpc, state)) { 88290650Shselasky case MLX5_RMPC_STATE_RDY: 89290650Shselasky MLX5_SET(srqc, srqc, state, MLX5_SRQC_STATE_GOOD); 90290650Shselasky break; 91290650Shselasky case MLX5_RMPC_STATE_ERR: 92290650Shselasky MLX5_SET(srqc, srqc, state, MLX5_SRQC_STATE_ERROR); 93290650Shselasky break; 94290650Shselasky default: 95290650Shselasky printf("mlx5_core: WARN: ""%s: %d: Unknown rmp state = 0x%x\n", __func__, __LINE__, MLX5_GET(rmpc, rmpc, state)); 96290650Shselasky } 97290650Shselasky 98290650Shselasky MLX5_SET(srqc, srqc, wq_signature, MLX5_GET(wq, wq, wq_signature)); 99290650Shselasky MLX5_SET(srqc, srqc, log_page_size, MLX5_GET(wq, wq, log_wq_pg_sz)); 100290650Shselasky MLX5_SET(srqc, srqc, log_rq_stride, MLX5_GET(wq, wq, log_wq_stride) - 4); 101290650Shselasky MLX5_SET(srqc, srqc, log_srq_size, MLX5_GET(wq, wq, log_wq_sz)); 102290650Shselasky MLX5_SET(srqc, srqc, page_offset, MLX5_GET(wq, wq, page_offset)); 103290650Shselasky MLX5_SET(srqc, srqc, lwm, MLX5_GET(wq, wq, lwm)); 104290650Shselasky MLX5_SET(srqc, srqc, pd, MLX5_GET(wq, wq, pd)); 105290650Shselasky MLX5_SET(srqc, srqc, db_record_addr_h, MLX5_GET64(wq, wq, dbr_addr) >> 32); 106290650Shselasky MLX5_SET(srqc, srqc, db_record_addr_l, (MLX5_GET64(wq, wq, dbr_addr) >> 2) & 0x3fffffff); 107290650Shselasky } 108290650Shselasky} 109290650Shselasky 110290650Shselaskystruct mlx5_core_srq *mlx5_core_get_srq(struct mlx5_core_dev *dev, u32 srqn) 111290650Shselasky{ 112290650Shselasky struct mlx5_srq_table *table = &dev->priv.srq_table; 113290650Shselasky struct mlx5_core_srq *srq; 114290650Shselasky 115290650Shselasky spin_lock(&table->lock); 116290650Shselasky 117290650Shselasky srq = radix_tree_lookup(&table->tree, srqn); 118290650Shselasky if (srq) 119290650Shselasky atomic_inc(&srq->refcount); 120290650Shselasky 121290650Shselasky spin_unlock(&table->lock); 122290650Shselasky 123290650Shselasky return srq; 124290650Shselasky} 125290650ShselaskyEXPORT_SYMBOL(mlx5_core_get_srq); 126290650Shselasky 127290650Shselaskystatic int get_pas_size(void *srqc) 128290650Shselasky{ 129290650Shselasky u32 log_page_size = MLX5_GET(srqc, srqc, log_page_size) + 12; 130290650Shselasky u32 log_srq_size = MLX5_GET(srqc, srqc, log_srq_size); 131290650Shselasky u32 log_rq_stride = MLX5_GET(srqc, srqc, log_rq_stride); 132290650Shselasky u32 page_offset = MLX5_GET(srqc, srqc, page_offset); 133290650Shselasky u32 po_quanta = 1 << (log_page_size - 6); 134290650Shselasky u32 rq_sz = 1 << (log_srq_size + 4 + log_rq_stride); 135290650Shselasky u32 page_size = 1 << log_page_size; 136290650Shselasky u32 rq_sz_po = rq_sz + (page_offset * po_quanta); 137290650Shselasky u32 rq_num_pas = (rq_sz_po + page_size - 1) / page_size; 138290650Shselasky 139290650Shselasky return rq_num_pas * sizeof(u64); 140290650Shselasky 141290650Shselasky} 142290650Shselasky 143290650Shselaskystatic int create_rmp_cmd(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq, 144290650Shselasky struct mlx5_create_srq_mbox_in *in, int srq_inlen) 145290650Shselasky{ 146290650Shselasky void *create_in; 147290650Shselasky void *rmpc; 148290650Shselasky void *srqc; 149290650Shselasky int pas_size; 150290650Shselasky int inlen; 151290650Shselasky int err; 152290650Shselasky 153290650Shselasky srqc = MLX5_ADDR_OF(create_srq_in, in, srq_context_entry); 154290650Shselasky pas_size = get_pas_size(srqc); 155290650Shselasky inlen = MLX5_ST_SZ_BYTES(create_rmp_in) + pas_size; 156290650Shselasky create_in = mlx5_vzalloc(inlen); 157290650Shselasky if (!create_in) 158290650Shselasky return -ENOMEM; 159290650Shselasky 160290650Shselasky rmpc = MLX5_ADDR_OF(create_rmp_in, create_in, ctx); 161290650Shselasky 162290650Shselasky memcpy(MLX5_ADDR_OF(rmpc, rmpc, wq.pas), in->pas, pas_size); 163290650Shselasky rmpc_srqc_reformat(srqc, rmpc, true); 164290650Shselasky 165290650Shselasky err = mlx5_core_create_rmp(dev, create_in, inlen, &srq->srqn); 166290650Shselasky 167290650Shselasky kvfree(create_in); 168290650Shselasky return err; 169290650Shselasky} 170290650Shselasky 171290650Shselaskystatic int destroy_rmp_cmd(struct mlx5_core_dev *dev, 172290650Shselasky struct mlx5_core_srq *srq) 173290650Shselasky{ 174290650Shselasky return mlx5_core_destroy_rmp(dev, srq->srqn); 175290650Shselasky} 176290650Shselasky 177290650Shselaskystatic int query_rmp_cmd(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq, 178290650Shselasky struct mlx5_query_srq_mbox_out *out) 179290650Shselasky{ 180290650Shselasky u32 *rmp_out; 181290650Shselasky void *rmpc; 182290650Shselasky void *srqc; 183290650Shselasky int err; 184290650Shselasky 185290650Shselasky rmp_out = mlx5_vzalloc(MLX5_ST_SZ_BYTES(query_rmp_out)); 186290650Shselasky if (!rmp_out) 187290650Shselasky return -ENOMEM; 188290650Shselasky 189290650Shselasky err = mlx5_core_query_rmp(dev, srq->srqn, rmp_out); 190290650Shselasky if (err) 191290650Shselasky goto out; 192290650Shselasky 193290650Shselasky srqc = MLX5_ADDR_OF(query_srq_out, out, srq_context_entry); 194290650Shselasky rmpc = MLX5_ADDR_OF(query_rmp_out, rmp_out, rmp_context); 195290650Shselasky rmpc_srqc_reformat(srqc, rmpc, false); 196290650Shselasky 197290650Shselaskyout: 198290650Shselasky kvfree(rmp_out); 199290650Shselasky return 0; 200290650Shselasky} 201290650Shselasky 202290650Shselaskystatic int arm_rmp_cmd(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq, u16 lwm) 203290650Shselasky{ 204290650Shselasky return mlx5_core_arm_rmp(dev, srq->srqn, lwm); 205290650Shselasky} 206290650Shselasky 207290650Shselaskystatic int create_xrc_srq_cmd(struct mlx5_core_dev *dev, 208290650Shselasky struct mlx5_core_srq *srq, 209290650Shselasky struct mlx5_create_srq_mbox_in *in, 210290650Shselasky int srq_inlen) 211290650Shselasky{ 212290650Shselasky void *create_in; 213290650Shselasky void *srqc; 214290650Shselasky void *xrc_srqc; 215290650Shselasky void *pas; 216290650Shselasky int pas_size; 217290650Shselasky int inlen; 218290650Shselasky int err; 219290650Shselasky 220290650Shselasky srqc = MLX5_ADDR_OF(create_srq_in, in, srq_context_entry); 221290650Shselasky pas_size = get_pas_size(srqc); 222290650Shselasky inlen = MLX5_ST_SZ_BYTES(create_xrc_srq_in) + pas_size; 223290650Shselasky create_in = mlx5_vzalloc(inlen); 224290650Shselasky if (!create_in) 225290650Shselasky return -ENOMEM; 226290650Shselasky 227290650Shselasky xrc_srqc = MLX5_ADDR_OF(create_xrc_srq_in, create_in, xrc_srq_context_entry); 228290650Shselasky pas = MLX5_ADDR_OF(create_xrc_srq_in, create_in, pas); 229290650Shselasky 230290650Shselasky memcpy(xrc_srqc, srqc, MLX5_ST_SZ_BYTES(srqc)); 231290650Shselasky memcpy(pas, in->pas, pas_size); 232290650Shselasky 233290650Shselasky err = mlx5_core_create_xsrq(dev, create_in, inlen, &srq->srqn); 234290650Shselasky if (err) 235290650Shselasky goto out; 236290650Shselasky 237290650Shselaskyout: 238290650Shselasky kvfree(create_in); 239290650Shselasky return err; 240290650Shselasky} 241290650Shselasky 242290650Shselaskystatic int destroy_xrc_srq_cmd(struct mlx5_core_dev *dev, 243290650Shselasky struct mlx5_core_srq *srq) 244290650Shselasky{ 245290650Shselasky return mlx5_core_destroy_xsrq(dev, srq->srqn); 246290650Shselasky} 247290650Shselasky 248290650Shselaskystatic int query_xrc_srq_cmd(struct mlx5_core_dev *dev, 249290650Shselasky struct mlx5_core_srq *srq, 250290650Shselasky struct mlx5_query_srq_mbox_out *out) 251290650Shselasky{ 252290650Shselasky u32 *xrcsrq_out; 253290650Shselasky int err; 254290650Shselasky 255290650Shselasky xrcsrq_out = mlx5_vzalloc(MLX5_ST_SZ_BYTES(query_xrc_srq_out)); 256290650Shselasky if (!xrcsrq_out) 257290650Shselasky return -ENOMEM; 258290650Shselasky 259290650Shselasky err = mlx5_core_query_xsrq(dev, srq->srqn, xrcsrq_out); 260290650Shselasky if (err) 261290650Shselasky goto out; 262290650Shselasky 263290650Shselaskyout: 264290650Shselasky kvfree(xrcsrq_out); 265290650Shselasky return err; 266290650Shselasky} 267290650Shselasky 268290650Shselaskystatic int arm_xrc_srq_cmd(struct mlx5_core_dev *dev, 269290650Shselasky struct mlx5_core_srq *srq, u16 lwm) 270290650Shselasky{ 271290650Shselasky return mlx5_core_arm_xsrq(dev, srq->srqn, lwm); 272290650Shselasky} 273290650Shselasky 274290650Shselaskystatic int create_srq_cmd(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq, 275290650Shselasky struct mlx5_create_srq_mbox_in *in, int inlen) 276290650Shselasky{ 277290650Shselasky struct mlx5_create_srq_mbox_out out; 278290650Shselasky int err; 279290650Shselasky 280290650Shselasky memset(&out, 0, sizeof(out)); 281290650Shselasky 282290650Shselasky in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_CREATE_SRQ); 283290650Shselasky 284290650Shselasky err = mlx5_cmd_exec_check_status(dev, (u32 *)in, inlen, (u32 *)(&out), sizeof(out)); 285290650Shselasky 286290650Shselasky srq->srqn = be32_to_cpu(out.srqn) & 0xffffff; 287290650Shselasky 288290650Shselasky return err; 289290650Shselasky} 290290650Shselasky 291290650Shselaskystatic int destroy_srq_cmd(struct mlx5_core_dev *dev, 292290650Shselasky struct mlx5_core_srq *srq) 293290650Shselasky{ 294290650Shselasky struct mlx5_destroy_srq_mbox_in in; 295290650Shselasky struct mlx5_destroy_srq_mbox_out out; 296290650Shselasky 297290650Shselasky memset(&in, 0, sizeof(in)); 298290650Shselasky memset(&out, 0, sizeof(out)); 299290650Shselasky in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DESTROY_SRQ); 300290650Shselasky in.srqn = cpu_to_be32(srq->srqn); 301290650Shselasky 302290650Shselasky return mlx5_cmd_exec_check_status(dev, (u32 *)(&in), sizeof(in), (u32 *)(&out), sizeof(out)); 303290650Shselasky} 304290650Shselasky 305290650Shselaskystatic int query_srq_cmd(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq, 306290650Shselasky struct mlx5_query_srq_mbox_out *out) 307290650Shselasky{ 308290650Shselasky struct mlx5_query_srq_mbox_in in; 309290650Shselasky 310290650Shselasky memset(&in, 0, sizeof(in)); 311290650Shselasky 312290650Shselasky in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_SRQ); 313290650Shselasky in.srqn = cpu_to_be32(srq->srqn); 314290650Shselasky 315290650Shselasky return mlx5_cmd_exec_check_status(dev, (u32 *)(&in), sizeof(in), (u32 *)out, sizeof(*out)); 316290650Shselasky} 317290650Shselasky 318290650Shselaskystatic int arm_srq_cmd(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq, 319290650Shselasky u16 lwm, int is_srq) 320290650Shselasky{ 321290650Shselasky struct mlx5_arm_srq_mbox_in in; 322290650Shselasky struct mlx5_arm_srq_mbox_out out; 323290650Shselasky 324290650Shselasky memset(&in, 0, sizeof(in)); 325290650Shselasky memset(&out, 0, sizeof(out)); 326290650Shselasky 327290650Shselasky in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_ARM_RQ); 328290650Shselasky in.hdr.opmod = cpu_to_be16(!!is_srq); 329290650Shselasky in.srqn = cpu_to_be32(srq->srqn); 330290650Shselasky in.lwm = cpu_to_be16(lwm); 331290650Shselasky 332290650Shselasky return mlx5_cmd_exec_check_status(dev, (u32 *)(&in), sizeof(in), (u32 *)(&out), sizeof(out)); 333290650Shselasky} 334290650Shselasky 335290650Shselaskystatic int create_srq_split(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq, 336290650Shselasky struct mlx5_create_srq_mbox_in *in, int inlen, 337290650Shselasky int is_xrc) 338290650Shselasky{ 339290650Shselasky if (!dev->issi) 340290650Shselasky return create_srq_cmd(dev, srq, in, inlen); 341290650Shselasky else if (srq->common.res == MLX5_RES_XSRQ) 342290650Shselasky return create_xrc_srq_cmd(dev, srq, in, inlen); 343290650Shselasky else 344290650Shselasky return create_rmp_cmd(dev, srq, in, inlen); 345290650Shselasky} 346290650Shselasky 347290650Shselaskystatic int destroy_srq_split(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq) 348290650Shselasky{ 349290650Shselasky if (!dev->issi) 350290650Shselasky return destroy_srq_cmd(dev, srq); 351290650Shselasky else if (srq->common.res == MLX5_RES_XSRQ) 352290650Shselasky return destroy_xrc_srq_cmd(dev, srq); 353290650Shselasky else 354290650Shselasky return destroy_rmp_cmd(dev, srq); 355290650Shselasky} 356290650Shselasky 357290650Shselaskyint mlx5_core_create_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq, 358290650Shselasky struct mlx5_create_srq_mbox_in *in, int inlen, 359290650Shselasky int is_xrc) 360290650Shselasky{ 361290650Shselasky int err; 362290650Shselasky struct mlx5_srq_table *table = &dev->priv.srq_table; 363290650Shselasky 364290650Shselasky srq->common.res = is_xrc ? MLX5_RES_XSRQ : MLX5_RES_SRQ; 365290650Shselasky 366290650Shselasky err = create_srq_split(dev, srq, in, inlen, is_xrc); 367290650Shselasky if (err) 368290650Shselasky return err; 369290650Shselasky 370290650Shselasky atomic_set(&srq->refcount, 1); 371290650Shselasky init_completion(&srq->free); 372290650Shselasky 373290650Shselasky spin_lock_irq(&table->lock); 374290650Shselasky err = radix_tree_insert(&table->tree, srq->srqn, srq); 375290650Shselasky spin_unlock_irq(&table->lock); 376290650Shselasky if (err) { 377290650Shselasky mlx5_core_warn(dev, "err %d, srqn 0x%x\n", err, srq->srqn); 378290650Shselasky goto err_destroy_srq_split; 379290650Shselasky } 380290650Shselasky 381290650Shselasky return 0; 382290650Shselasky 383290650Shselaskyerr_destroy_srq_split: 384290650Shselasky destroy_srq_split(dev, srq); 385290650Shselasky 386290650Shselasky return err; 387290650Shselasky} 388290650ShselaskyEXPORT_SYMBOL(mlx5_core_create_srq); 389290650Shselasky 390290650Shselaskyint mlx5_core_destroy_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq) 391290650Shselasky{ 392290650Shselasky struct mlx5_srq_table *table = &dev->priv.srq_table; 393290650Shselasky struct mlx5_core_srq *tmp; 394290650Shselasky int err; 395290650Shselasky 396290650Shselasky spin_lock_irq(&table->lock); 397290650Shselasky tmp = radix_tree_delete(&table->tree, srq->srqn); 398290650Shselasky spin_unlock_irq(&table->lock); 399290650Shselasky if (!tmp) { 400290650Shselasky mlx5_core_warn(dev, "srq 0x%x not found in tree\n", srq->srqn); 401290650Shselasky return -EINVAL; 402290650Shselasky } 403290650Shselasky if (tmp != srq) { 404290650Shselasky mlx5_core_warn(dev, "corruption on srqn 0x%x\n", srq->srqn); 405290650Shselasky return -EINVAL; 406290650Shselasky } 407290650Shselasky 408290650Shselasky err = destroy_srq_split(dev, srq); 409290650Shselasky if (err) 410290650Shselasky return err; 411290650Shselasky 412290650Shselasky if (atomic_dec_and_test(&srq->refcount)) 413290650Shselasky complete(&srq->free); 414290650Shselasky wait_for_completion(&srq->free); 415290650Shselasky 416290650Shselasky return 0; 417290650Shselasky} 418290650ShselaskyEXPORT_SYMBOL(mlx5_core_destroy_srq); 419290650Shselasky 420290650Shselaskyint mlx5_core_query_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq, 421290650Shselasky struct mlx5_query_srq_mbox_out *out) 422290650Shselasky{ 423290650Shselasky if (!dev->issi) 424290650Shselasky return query_srq_cmd(dev, srq, out); 425290650Shselasky else if (srq->common.res == MLX5_RES_XSRQ) 426290650Shselasky return query_xrc_srq_cmd(dev, srq, out); 427290650Shselasky else 428290650Shselasky return query_rmp_cmd(dev, srq, out); 429290650Shselasky} 430290650ShselaskyEXPORT_SYMBOL(mlx5_core_query_srq); 431290650Shselasky 432290650Shselaskyint mlx5_core_arm_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq, 433290650Shselasky u16 lwm, int is_srq) 434290650Shselasky{ 435290650Shselasky if (!dev->issi) 436290650Shselasky return arm_srq_cmd(dev, srq, lwm, is_srq); 437290650Shselasky else if (srq->common.res == MLX5_RES_XSRQ) 438290650Shselasky return arm_xrc_srq_cmd(dev, srq, lwm); 439290650Shselasky else 440290650Shselasky return arm_rmp_cmd(dev, srq, lwm); 441290650Shselasky} 442290650ShselaskyEXPORT_SYMBOL(mlx5_core_arm_srq); 443290650Shselasky 444290650Shselaskyvoid mlx5_init_srq_table(struct mlx5_core_dev *dev) 445290650Shselasky{ 446290650Shselasky struct mlx5_srq_table *table = &dev->priv.srq_table; 447290650Shselasky 448331580Shselasky memset(table, 0, sizeof(*table)); 449290650Shselasky spin_lock_init(&table->lock); 450290650Shselasky INIT_RADIX_TREE(&table->tree, GFP_ATOMIC); 451290650Shselasky} 452290650Shselasky 453290650Shselaskyvoid mlx5_cleanup_srq_table(struct mlx5_core_dev *dev) 454290650Shselasky{ 455290650Shselasky /* nothing */ 456290650Shselasky} 457