1*303ae1cdSBernard Metzler // SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause 2*303ae1cdSBernard Metzler 3*303ae1cdSBernard Metzler /* Authors: Bernard Metzler <bmt@zurich.ibm.com> */ 4*303ae1cdSBernard Metzler /* Copyright (c) 2008-2019, IBM Corporation */ 5*303ae1cdSBernard Metzler 6*303ae1cdSBernard Metzler #include <linux/errno.h> 7*303ae1cdSBernard Metzler #include <linux/types.h> 8*303ae1cdSBernard Metzler #include <linux/uaccess.h> 9*303ae1cdSBernard Metzler #include <linux/vmalloc.h> 10*303ae1cdSBernard Metzler #include <linux/xarray.h> 11*303ae1cdSBernard Metzler 12*303ae1cdSBernard Metzler #include <rdma/iw_cm.h> 13*303ae1cdSBernard Metzler #include <rdma/ib_verbs.h> 14*303ae1cdSBernard Metzler #include <rdma/ib_user_verbs.h> 15*303ae1cdSBernard Metzler #include <rdma/uverbs_ioctl.h> 16*303ae1cdSBernard Metzler 17*303ae1cdSBernard Metzler #include "siw.h" 18*303ae1cdSBernard Metzler #include "siw_verbs.h" 19*303ae1cdSBernard Metzler #include "siw_mem.h" 20*303ae1cdSBernard Metzler 21*303ae1cdSBernard Metzler static int ib_qp_state_to_siw_qp_state[IB_QPS_ERR + 1] = { 22*303ae1cdSBernard Metzler [IB_QPS_RESET] = SIW_QP_STATE_IDLE, 23*303ae1cdSBernard Metzler [IB_QPS_INIT] = SIW_QP_STATE_IDLE, 24*303ae1cdSBernard Metzler [IB_QPS_RTR] = SIW_QP_STATE_RTR, 25*303ae1cdSBernard Metzler [IB_QPS_RTS] = SIW_QP_STATE_RTS, 26*303ae1cdSBernard Metzler [IB_QPS_SQD] = SIW_QP_STATE_CLOSING, 27*303ae1cdSBernard Metzler [IB_QPS_SQE] = SIW_QP_STATE_TERMINATE, 28*303ae1cdSBernard Metzler [IB_QPS_ERR] = SIW_QP_STATE_ERROR 29*303ae1cdSBernard Metzler }; 30*303ae1cdSBernard Metzler 31*303ae1cdSBernard Metzler static char ib_qp_state_to_string[IB_QPS_ERR + 1][sizeof("RESET")] = { 32*303ae1cdSBernard Metzler [IB_QPS_RESET] = "RESET", [IB_QPS_INIT] = "INIT", [IB_QPS_RTR] = "RTR", 33*303ae1cdSBernard Metzler [IB_QPS_RTS] = "RTS", [IB_QPS_SQD] = "SQD", [IB_QPS_SQE] = "SQE", 34*303ae1cdSBernard Metzler [IB_QPS_ERR] = "ERR" 35*303ae1cdSBernard Metzler }; 36*303ae1cdSBernard Metzler 37*303ae1cdSBernard Metzler static u32 siw_create_uobj(struct siw_ucontext *uctx, void *vaddr, u32 size) 38*303ae1cdSBernard Metzler { 39*303ae1cdSBernard Metzler struct siw_uobj *uobj; 40*303ae1cdSBernard Metzler struct xa_limit limit = XA_LIMIT(0, SIW_UOBJ_MAX_KEY); 41*303ae1cdSBernard Metzler u32 key; 42*303ae1cdSBernard Metzler 43*303ae1cdSBernard Metzler uobj = kzalloc(sizeof(*uobj), GFP_KERNEL); 44*303ae1cdSBernard Metzler if (!uobj) 45*303ae1cdSBernard Metzler return SIW_INVAL_UOBJ_KEY; 46*303ae1cdSBernard Metzler 47*303ae1cdSBernard Metzler if (xa_alloc_cyclic(&uctx->xa, &key, uobj, limit, &uctx->uobj_nextkey, 48*303ae1cdSBernard Metzler GFP_KERNEL) < 0) { 49*303ae1cdSBernard Metzler kfree(uobj); 50*303ae1cdSBernard Metzler return SIW_INVAL_UOBJ_KEY; 51*303ae1cdSBernard Metzler } 52*303ae1cdSBernard Metzler uobj->size = PAGE_ALIGN(size); 53*303ae1cdSBernard Metzler uobj->addr = vaddr; 54*303ae1cdSBernard Metzler 55*303ae1cdSBernard Metzler return key; 56*303ae1cdSBernard Metzler } 57*303ae1cdSBernard Metzler 58*303ae1cdSBernard Metzler static struct siw_uobj *siw_get_uobj(struct siw_ucontext *uctx, 59*303ae1cdSBernard Metzler unsigned long off, u32 size) 60*303ae1cdSBernard Metzler { 61*303ae1cdSBernard Metzler struct siw_uobj *uobj = xa_load(&uctx->xa, off); 62*303ae1cdSBernard Metzler 63*303ae1cdSBernard Metzler if (uobj && uobj->size == size) 64*303ae1cdSBernard Metzler return uobj; 65*303ae1cdSBernard Metzler 66*303ae1cdSBernard Metzler return NULL; 67*303ae1cdSBernard Metzler } 68*303ae1cdSBernard Metzler 69*303ae1cdSBernard Metzler int siw_mmap(struct ib_ucontext *ctx, struct vm_area_struct *vma) 70*303ae1cdSBernard Metzler { 71*303ae1cdSBernard Metzler struct siw_ucontext *uctx = to_siw_ctx(ctx); 72*303ae1cdSBernard Metzler struct siw_uobj *uobj; 73*303ae1cdSBernard Metzler unsigned long off = vma->vm_pgoff; 74*303ae1cdSBernard Metzler int size = vma->vm_end - vma->vm_start; 75*303ae1cdSBernard Metzler int rv = -EINVAL; 76*303ae1cdSBernard Metzler 77*303ae1cdSBernard Metzler /* 78*303ae1cdSBernard Metzler * Must be page aligned 79*303ae1cdSBernard Metzler */ 80*303ae1cdSBernard Metzler if (vma->vm_start & (PAGE_SIZE - 1)) { 81*303ae1cdSBernard Metzler pr_warn("siw: mmap not page aligned\n"); 82*303ae1cdSBernard Metzler goto out; 83*303ae1cdSBernard Metzler } 84*303ae1cdSBernard Metzler uobj = siw_get_uobj(uctx, off, size); 85*303ae1cdSBernard Metzler if (!uobj) { 86*303ae1cdSBernard Metzler siw_dbg(&uctx->sdev->base_dev, "mmap lookup failed: %lu, %u\n", 87*303ae1cdSBernard Metzler off, size); 88*303ae1cdSBernard Metzler goto out; 89*303ae1cdSBernard Metzler } 90*303ae1cdSBernard Metzler rv = remap_vmalloc_range(vma, uobj->addr, 0); 91*303ae1cdSBernard Metzler if (rv) 92*303ae1cdSBernard Metzler pr_warn("remap_vmalloc_range failed: %lu, %u\n", off, size); 93*303ae1cdSBernard Metzler out: 94*303ae1cdSBernard Metzler return rv; 95*303ae1cdSBernard Metzler } 96*303ae1cdSBernard Metzler 97*303ae1cdSBernard Metzler int siw_alloc_ucontext(struct ib_ucontext *base_ctx, struct ib_udata *udata) 98*303ae1cdSBernard Metzler { 99*303ae1cdSBernard Metzler struct siw_device *sdev = to_siw_dev(base_ctx->device); 100*303ae1cdSBernard Metzler struct siw_ucontext *ctx = to_siw_ctx(base_ctx); 101*303ae1cdSBernard Metzler struct siw_uresp_alloc_ctx uresp = {}; 102*303ae1cdSBernard Metzler int rv; 103*303ae1cdSBernard Metzler 104*303ae1cdSBernard Metzler if (atomic_inc_return(&sdev->num_ctx) > SIW_MAX_CONTEXT) { 105*303ae1cdSBernard Metzler rv = -ENOMEM; 106*303ae1cdSBernard Metzler goto err_out; 107*303ae1cdSBernard Metzler } 108*303ae1cdSBernard Metzler xa_init_flags(&ctx->xa, XA_FLAGS_ALLOC); 109*303ae1cdSBernard Metzler ctx->uobj_nextkey = 0; 110*303ae1cdSBernard Metzler ctx->sdev = sdev; 111*303ae1cdSBernard Metzler 112*303ae1cdSBernard Metzler uresp.dev_id = sdev->vendor_part_id; 113*303ae1cdSBernard Metzler 114*303ae1cdSBernard Metzler if (udata->outlen < sizeof(uresp)) { 115*303ae1cdSBernard Metzler rv = -EINVAL; 116*303ae1cdSBernard Metzler goto err_out; 117*303ae1cdSBernard Metzler } 118*303ae1cdSBernard Metzler rv = ib_copy_to_udata(udata, &uresp, sizeof(uresp)); 119*303ae1cdSBernard Metzler if (rv) 120*303ae1cdSBernard Metzler goto err_out; 121*303ae1cdSBernard Metzler 122*303ae1cdSBernard Metzler siw_dbg(base_ctx->device, "success. now %d context(s)\n", 123*303ae1cdSBernard Metzler atomic_read(&sdev->num_ctx)); 124*303ae1cdSBernard Metzler 125*303ae1cdSBernard Metzler return 0; 126*303ae1cdSBernard Metzler 127*303ae1cdSBernard Metzler err_out: 128*303ae1cdSBernard Metzler atomic_dec(&sdev->num_ctx); 129*303ae1cdSBernard Metzler siw_dbg(base_ctx->device, "failure %d. now %d context(s)\n", rv, 130*303ae1cdSBernard Metzler atomic_read(&sdev->num_ctx)); 131*303ae1cdSBernard Metzler 132*303ae1cdSBernard Metzler return rv; 133*303ae1cdSBernard Metzler } 134*303ae1cdSBernard Metzler 135*303ae1cdSBernard Metzler void siw_dealloc_ucontext(struct ib_ucontext *base_ctx) 136*303ae1cdSBernard Metzler { 137*303ae1cdSBernard Metzler struct siw_ucontext *uctx = to_siw_ctx(base_ctx); 138*303ae1cdSBernard Metzler void *entry; 139*303ae1cdSBernard Metzler unsigned long index; 140*303ae1cdSBernard Metzler 141*303ae1cdSBernard Metzler /* 142*303ae1cdSBernard Metzler * Make sure all user mmap objects are gone. Since QP, CQ 143*303ae1cdSBernard Metzler * and SRQ destroy routines destroy related objects, nothing 144*303ae1cdSBernard Metzler * should be found here. 145*303ae1cdSBernard Metzler */ 146*303ae1cdSBernard Metzler xa_for_each(&uctx->xa, index, entry) { 147*303ae1cdSBernard Metzler kfree(xa_erase(&uctx->xa, index)); 148*303ae1cdSBernard Metzler pr_warn("siw: dropping orphaned uobj at %lu\n", index); 149*303ae1cdSBernard Metzler } 150*303ae1cdSBernard Metzler xa_destroy(&uctx->xa); 151*303ae1cdSBernard Metzler atomic_dec(&uctx->sdev->num_ctx); 152*303ae1cdSBernard Metzler } 153*303ae1cdSBernard Metzler 154*303ae1cdSBernard Metzler int siw_query_device(struct ib_device *base_dev, struct ib_device_attr *attr, 155*303ae1cdSBernard Metzler struct ib_udata *udata) 156*303ae1cdSBernard Metzler { 157*303ae1cdSBernard Metzler struct siw_device *sdev = to_siw_dev(base_dev); 158*303ae1cdSBernard Metzler 159*303ae1cdSBernard Metzler if (udata->inlen || udata->outlen) 160*303ae1cdSBernard Metzler return -EINVAL; 161*303ae1cdSBernard Metzler 162*303ae1cdSBernard Metzler memset(attr, 0, sizeof(*attr)); 163*303ae1cdSBernard Metzler 164*303ae1cdSBernard Metzler /* Revisit atomic caps if RFC 7306 gets supported */ 165*303ae1cdSBernard Metzler attr->atomic_cap = 0; 166*303ae1cdSBernard Metzler attr->device_cap_flags = 167*303ae1cdSBernard Metzler IB_DEVICE_MEM_MGT_EXTENSIONS | IB_DEVICE_ALLOW_USER_UNREG; 168*303ae1cdSBernard Metzler attr->max_cq = sdev->attrs.max_cq; 169*303ae1cdSBernard Metzler attr->max_cqe = sdev->attrs.max_cqe; 170*303ae1cdSBernard Metzler attr->max_fast_reg_page_list_len = SIW_MAX_SGE_PBL; 171*303ae1cdSBernard Metzler attr->max_fmr = sdev->attrs.max_fmr; 172*303ae1cdSBernard Metzler attr->max_mr = sdev->attrs.max_mr; 173*303ae1cdSBernard Metzler attr->max_mw = sdev->attrs.max_mw; 174*303ae1cdSBernard Metzler attr->max_mr_size = ~0ull; 175*303ae1cdSBernard Metzler attr->max_pd = sdev->attrs.max_pd; 176*303ae1cdSBernard Metzler attr->max_qp = sdev->attrs.max_qp; 177*303ae1cdSBernard Metzler attr->max_qp_init_rd_atom = sdev->attrs.max_ird; 178*303ae1cdSBernard Metzler attr->max_qp_rd_atom = sdev->attrs.max_ord; 179*303ae1cdSBernard Metzler attr->max_qp_wr = sdev->attrs.max_qp_wr; 180*303ae1cdSBernard Metzler attr->max_recv_sge = sdev->attrs.max_sge; 181*303ae1cdSBernard Metzler attr->max_res_rd_atom = sdev->attrs.max_qp * sdev->attrs.max_ird; 182*303ae1cdSBernard Metzler attr->max_send_sge = sdev->attrs.max_sge; 183*303ae1cdSBernard Metzler attr->max_sge_rd = sdev->attrs.max_sge_rd; 184*303ae1cdSBernard Metzler attr->max_srq = sdev->attrs.max_srq; 185*303ae1cdSBernard Metzler attr->max_srq_sge = sdev->attrs.max_srq_sge; 186*303ae1cdSBernard Metzler attr->max_srq_wr = sdev->attrs.max_srq_wr; 187*303ae1cdSBernard Metzler attr->page_size_cap = PAGE_SIZE; 188*303ae1cdSBernard Metzler attr->vendor_id = SIW_VENDOR_ID; 189*303ae1cdSBernard Metzler attr->vendor_part_id = sdev->vendor_part_id; 190*303ae1cdSBernard Metzler 191*303ae1cdSBernard Metzler memcpy(&attr->sys_image_guid, sdev->netdev->dev_addr, 6); 192*303ae1cdSBernard Metzler 193*303ae1cdSBernard Metzler return 0; 194*303ae1cdSBernard Metzler } 195*303ae1cdSBernard Metzler 196*303ae1cdSBernard Metzler int siw_query_port(struct ib_device *base_dev, u8 port, 197*303ae1cdSBernard Metzler struct ib_port_attr *attr) 198*303ae1cdSBernard Metzler { 199*303ae1cdSBernard Metzler struct siw_device *sdev = to_siw_dev(base_dev); 200*303ae1cdSBernard Metzler 201*303ae1cdSBernard Metzler memset(attr, 0, sizeof(*attr)); 202*303ae1cdSBernard Metzler 203*303ae1cdSBernard Metzler attr->active_mtu = attr->max_mtu; 204*303ae1cdSBernard Metzler attr->active_speed = 2; 205*303ae1cdSBernard Metzler attr->active_width = 2; 206*303ae1cdSBernard Metzler attr->gid_tbl_len = 1; 207*303ae1cdSBernard Metzler attr->max_msg_sz = -1; 208*303ae1cdSBernard Metzler attr->max_mtu = ib_mtu_int_to_enum(sdev->netdev->mtu); 209*303ae1cdSBernard Metzler attr->phys_state = sdev->state == IB_PORT_ACTIVE ? 5 : 3; 210*303ae1cdSBernard Metzler attr->pkey_tbl_len = 1; 211*303ae1cdSBernard Metzler attr->port_cap_flags = IB_PORT_CM_SUP | IB_PORT_DEVICE_MGMT_SUP; 212*303ae1cdSBernard Metzler attr->state = sdev->state; 213*303ae1cdSBernard Metzler /* 214*303ae1cdSBernard Metzler * All zero 215*303ae1cdSBernard Metzler * 216*303ae1cdSBernard Metzler * attr->lid = 0; 217*303ae1cdSBernard Metzler * attr->bad_pkey_cntr = 0; 218*303ae1cdSBernard Metzler * attr->qkey_viol_cntr = 0; 219*303ae1cdSBernard Metzler * attr->sm_lid = 0; 220*303ae1cdSBernard Metzler * attr->lmc = 0; 221*303ae1cdSBernard Metzler * attr->max_vl_num = 0; 222*303ae1cdSBernard Metzler * attr->sm_sl = 0; 223*303ae1cdSBernard Metzler * attr->subnet_timeout = 0; 224*303ae1cdSBernard Metzler * attr->init_type_repy = 0; 225*303ae1cdSBernard Metzler */ 226*303ae1cdSBernard Metzler return 0; 227*303ae1cdSBernard Metzler } 228*303ae1cdSBernard Metzler 229*303ae1cdSBernard Metzler int siw_get_port_immutable(struct ib_device *base_dev, u8 port, 230*303ae1cdSBernard Metzler struct ib_port_immutable *port_immutable) 231*303ae1cdSBernard Metzler { 232*303ae1cdSBernard Metzler struct ib_port_attr attr; 233*303ae1cdSBernard Metzler int rv = siw_query_port(base_dev, port, &attr); 234*303ae1cdSBernard Metzler 235*303ae1cdSBernard Metzler if (rv) 236*303ae1cdSBernard Metzler return rv; 237*303ae1cdSBernard Metzler 238*303ae1cdSBernard Metzler port_immutable->pkey_tbl_len = attr.pkey_tbl_len; 239*303ae1cdSBernard Metzler port_immutable->gid_tbl_len = attr.gid_tbl_len; 240*303ae1cdSBernard Metzler port_immutable->core_cap_flags = RDMA_CORE_PORT_IWARP; 241*303ae1cdSBernard Metzler 242*303ae1cdSBernard Metzler return 0; 243*303ae1cdSBernard Metzler } 244*303ae1cdSBernard Metzler 245*303ae1cdSBernard Metzler int siw_query_pkey(struct ib_device *base_dev, u8 port, u16 idx, u16 *pkey) 246*303ae1cdSBernard Metzler { 247*303ae1cdSBernard Metzler /* Report the default pkey */ 248*303ae1cdSBernard Metzler *pkey = 0xffff; 249*303ae1cdSBernard Metzler return 0; 250*303ae1cdSBernard Metzler } 251*303ae1cdSBernard Metzler 252*303ae1cdSBernard Metzler int siw_query_gid(struct ib_device *base_dev, u8 port, int idx, 253*303ae1cdSBernard Metzler union ib_gid *gid) 254*303ae1cdSBernard Metzler { 255*303ae1cdSBernard Metzler struct siw_device *sdev = to_siw_dev(base_dev); 256*303ae1cdSBernard Metzler 257*303ae1cdSBernard Metzler /* subnet_prefix == interface_id == 0; */ 258*303ae1cdSBernard Metzler memset(gid, 0, sizeof(*gid)); 259*303ae1cdSBernard Metzler memcpy(&gid->raw[0], sdev->netdev->dev_addr, 6); 260*303ae1cdSBernard Metzler 261*303ae1cdSBernard Metzler return 0; 262*303ae1cdSBernard Metzler } 263*303ae1cdSBernard Metzler 264*303ae1cdSBernard Metzler int siw_alloc_pd(struct ib_pd *pd, struct ib_udata *udata) 265*303ae1cdSBernard Metzler { 266*303ae1cdSBernard Metzler struct siw_device *sdev = to_siw_dev(pd->device); 267*303ae1cdSBernard Metzler 268*303ae1cdSBernard Metzler if (atomic_inc_return(&sdev->num_pd) > SIW_MAX_PD) { 269*303ae1cdSBernard Metzler atomic_dec(&sdev->num_pd); 270*303ae1cdSBernard Metzler return -ENOMEM; 271*303ae1cdSBernard Metzler } 272*303ae1cdSBernard Metzler siw_dbg_pd(pd, "now %d PD's(s)\n", atomic_read(&sdev->num_pd)); 273*303ae1cdSBernard Metzler 274*303ae1cdSBernard Metzler return 0; 275*303ae1cdSBernard Metzler } 276*303ae1cdSBernard Metzler 277*303ae1cdSBernard Metzler void siw_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata) 278*303ae1cdSBernard Metzler { 279*303ae1cdSBernard Metzler struct siw_device *sdev = to_siw_dev(pd->device); 280*303ae1cdSBernard Metzler 281*303ae1cdSBernard Metzler siw_dbg_pd(pd, "free PD\n"); 282*303ae1cdSBernard Metzler atomic_dec(&sdev->num_pd); 283*303ae1cdSBernard Metzler } 284*303ae1cdSBernard Metzler 285*303ae1cdSBernard Metzler void siw_qp_get_ref(struct ib_qp *base_qp) 286*303ae1cdSBernard Metzler { 287*303ae1cdSBernard Metzler siw_qp_get(to_siw_qp(base_qp)); 288*303ae1cdSBernard Metzler } 289*303ae1cdSBernard Metzler 290*303ae1cdSBernard Metzler void siw_qp_put_ref(struct ib_qp *base_qp) 291*303ae1cdSBernard Metzler { 292*303ae1cdSBernard Metzler siw_qp_put(to_siw_qp(base_qp)); 293*303ae1cdSBernard Metzler } 294*303ae1cdSBernard Metzler 295*303ae1cdSBernard Metzler /* 296*303ae1cdSBernard Metzler * siw_create_qp() 297*303ae1cdSBernard Metzler * 298*303ae1cdSBernard Metzler * Create QP of requested size on given device. 299*303ae1cdSBernard Metzler * 300*303ae1cdSBernard Metzler * @pd: Protection Domain 301*303ae1cdSBernard Metzler * @attrs: Initial QP attributes. 302*303ae1cdSBernard Metzler * @udata: used to provide QP ID, SQ and RQ size back to user. 303*303ae1cdSBernard Metzler */ 304*303ae1cdSBernard Metzler 305*303ae1cdSBernard Metzler struct ib_qp *siw_create_qp(struct ib_pd *pd, 306*303ae1cdSBernard Metzler struct ib_qp_init_attr *attrs, 307*303ae1cdSBernard Metzler struct ib_udata *udata) 308*303ae1cdSBernard Metzler { 309*303ae1cdSBernard Metzler struct siw_qp *qp = NULL; 310*303ae1cdSBernard Metzler struct siw_base_qp *siw_base_qp = NULL; 311*303ae1cdSBernard Metzler struct ib_device *base_dev = pd->device; 312*303ae1cdSBernard Metzler struct siw_device *sdev = to_siw_dev(base_dev); 313*303ae1cdSBernard Metzler struct siw_ucontext *uctx = 314*303ae1cdSBernard Metzler rdma_udata_to_drv_context(udata, struct siw_ucontext, 315*303ae1cdSBernard Metzler base_ucontext); 316*303ae1cdSBernard Metzler struct siw_cq *scq = NULL, *rcq = NULL; 317*303ae1cdSBernard Metzler unsigned long flags; 318*303ae1cdSBernard Metzler int num_sqe, num_rqe, rv = 0; 319*303ae1cdSBernard Metzler 320*303ae1cdSBernard Metzler siw_dbg(base_dev, "create new QP\n"); 321*303ae1cdSBernard Metzler 322*303ae1cdSBernard Metzler if (atomic_inc_return(&sdev->num_qp) > SIW_MAX_QP) { 323*303ae1cdSBernard Metzler siw_dbg(base_dev, "too many QP's\n"); 324*303ae1cdSBernard Metzler rv = -ENOMEM; 325*303ae1cdSBernard Metzler goto err_out; 326*303ae1cdSBernard Metzler } 327*303ae1cdSBernard Metzler if (attrs->qp_type != IB_QPT_RC) { 328*303ae1cdSBernard Metzler siw_dbg(base_dev, "only RC QP's supported\n"); 329*303ae1cdSBernard Metzler rv = -EINVAL; 330*303ae1cdSBernard Metzler goto err_out; 331*303ae1cdSBernard Metzler } 332*303ae1cdSBernard Metzler if ((attrs->cap.max_send_wr > SIW_MAX_QP_WR) || 333*303ae1cdSBernard Metzler (attrs->cap.max_recv_wr > SIW_MAX_QP_WR) || 334*303ae1cdSBernard Metzler (attrs->cap.max_send_sge > SIW_MAX_SGE) || 335*303ae1cdSBernard Metzler (attrs->cap.max_recv_sge > SIW_MAX_SGE)) { 336*303ae1cdSBernard Metzler siw_dbg(base_dev, "QP size error\n"); 337*303ae1cdSBernard Metzler rv = -EINVAL; 338*303ae1cdSBernard Metzler goto err_out; 339*303ae1cdSBernard Metzler } 340*303ae1cdSBernard Metzler if (attrs->cap.max_inline_data > SIW_MAX_INLINE) { 341*303ae1cdSBernard Metzler siw_dbg(base_dev, "max inline send: %d > %d\n", 342*303ae1cdSBernard Metzler attrs->cap.max_inline_data, (int)SIW_MAX_INLINE); 343*303ae1cdSBernard Metzler rv = -EINVAL; 344*303ae1cdSBernard Metzler goto err_out; 345*303ae1cdSBernard Metzler } 346*303ae1cdSBernard Metzler /* 347*303ae1cdSBernard Metzler * NOTE: we allow for zero element SQ and RQ WQE's SGL's 348*303ae1cdSBernard Metzler * but not for a QP unable to hold any WQE (SQ + RQ) 349*303ae1cdSBernard Metzler */ 350*303ae1cdSBernard Metzler if (attrs->cap.max_send_wr + attrs->cap.max_recv_wr == 0) { 351*303ae1cdSBernard Metzler siw_dbg(base_dev, "QP must have send or receive queue\n"); 352*303ae1cdSBernard Metzler rv = -EINVAL; 353*303ae1cdSBernard Metzler goto err_out; 354*303ae1cdSBernard Metzler } 355*303ae1cdSBernard Metzler scq = to_siw_cq(attrs->send_cq); 356*303ae1cdSBernard Metzler rcq = to_siw_cq(attrs->recv_cq); 357*303ae1cdSBernard Metzler 358*303ae1cdSBernard Metzler if (!scq || (!rcq && !attrs->srq)) { 359*303ae1cdSBernard Metzler siw_dbg(base_dev, "send CQ or receive CQ invalid\n"); 360*303ae1cdSBernard Metzler rv = -EINVAL; 361*303ae1cdSBernard Metzler goto err_out; 362*303ae1cdSBernard Metzler } 363*303ae1cdSBernard Metzler siw_base_qp = kzalloc(sizeof(*siw_base_qp), GFP_KERNEL); 364*303ae1cdSBernard Metzler if (!siw_base_qp) { 365*303ae1cdSBernard Metzler rv = -ENOMEM; 366*303ae1cdSBernard Metzler goto err_out; 367*303ae1cdSBernard Metzler } 368*303ae1cdSBernard Metzler qp = kzalloc(sizeof(*qp), GFP_KERNEL); 369*303ae1cdSBernard Metzler if (!qp) { 370*303ae1cdSBernard Metzler rv = -ENOMEM; 371*303ae1cdSBernard Metzler goto err_out; 372*303ae1cdSBernard Metzler } 373*303ae1cdSBernard Metzler siw_base_qp->qp = qp; 374*303ae1cdSBernard Metzler qp->ib_qp = &siw_base_qp->base_qp; 375*303ae1cdSBernard Metzler 376*303ae1cdSBernard Metzler init_rwsem(&qp->state_lock); 377*303ae1cdSBernard Metzler spin_lock_init(&qp->sq_lock); 378*303ae1cdSBernard Metzler spin_lock_init(&qp->rq_lock); 379*303ae1cdSBernard Metzler spin_lock_init(&qp->orq_lock); 380*303ae1cdSBernard Metzler 381*303ae1cdSBernard Metzler qp->kernel_verbs = !udata; 382*303ae1cdSBernard Metzler qp->xa_sq_index = SIW_INVAL_UOBJ_KEY; 383*303ae1cdSBernard Metzler qp->xa_rq_index = SIW_INVAL_UOBJ_KEY; 384*303ae1cdSBernard Metzler 385*303ae1cdSBernard Metzler rv = siw_qp_add(sdev, qp); 386*303ae1cdSBernard Metzler if (rv) 387*303ae1cdSBernard Metzler goto err_out; 388*303ae1cdSBernard Metzler 389*303ae1cdSBernard Metzler /* All queue indices are derived from modulo operations 390*303ae1cdSBernard Metzler * on a free running 'get' (consumer) and 'put' (producer) 391*303ae1cdSBernard Metzler * unsigned counter. Having queue sizes at power of two 392*303ae1cdSBernard Metzler * avoids handling counter wrap around. 393*303ae1cdSBernard Metzler */ 394*303ae1cdSBernard Metzler num_sqe = roundup_pow_of_two(attrs->cap.max_send_wr); 395*303ae1cdSBernard Metzler num_rqe = roundup_pow_of_two(attrs->cap.max_recv_wr); 396*303ae1cdSBernard Metzler 397*303ae1cdSBernard Metzler if (qp->kernel_verbs) 398*303ae1cdSBernard Metzler qp->sendq = vzalloc(num_sqe * sizeof(struct siw_sqe)); 399*303ae1cdSBernard Metzler else 400*303ae1cdSBernard Metzler qp->sendq = vmalloc_user(num_sqe * sizeof(struct siw_sqe)); 401*303ae1cdSBernard Metzler 402*303ae1cdSBernard Metzler if (qp->sendq == NULL) { 403*303ae1cdSBernard Metzler siw_dbg(base_dev, "SQ size %d alloc failed\n", num_sqe); 404*303ae1cdSBernard Metzler rv = -ENOMEM; 405*303ae1cdSBernard Metzler goto err_out_xa; 406*303ae1cdSBernard Metzler } 407*303ae1cdSBernard Metzler if (attrs->sq_sig_type != IB_SIGNAL_REQ_WR) { 408*303ae1cdSBernard Metzler if (attrs->sq_sig_type == IB_SIGNAL_ALL_WR) 409*303ae1cdSBernard Metzler qp->attrs.flags |= SIW_SIGNAL_ALL_WR; 410*303ae1cdSBernard Metzler else { 411*303ae1cdSBernard Metzler rv = -EINVAL; 412*303ae1cdSBernard Metzler goto err_out_xa; 413*303ae1cdSBernard Metzler } 414*303ae1cdSBernard Metzler } 415*303ae1cdSBernard Metzler qp->pd = pd; 416*303ae1cdSBernard Metzler qp->scq = scq; 417*303ae1cdSBernard Metzler qp->rcq = rcq; 418*303ae1cdSBernard Metzler 419*303ae1cdSBernard Metzler if (attrs->srq) { 420*303ae1cdSBernard Metzler /* 421*303ae1cdSBernard Metzler * SRQ support. 422*303ae1cdSBernard Metzler * Verbs 6.3.7: ignore RQ size, if SRQ present 423*303ae1cdSBernard Metzler * Verbs 6.3.5: do not check PD of SRQ against PD of QP 424*303ae1cdSBernard Metzler */ 425*303ae1cdSBernard Metzler qp->srq = to_siw_srq(attrs->srq); 426*303ae1cdSBernard Metzler qp->attrs.rq_size = 0; 427*303ae1cdSBernard Metzler siw_dbg(base_dev, "QP [%u]: [SRQ 0x%p] attached\n", 428*303ae1cdSBernard Metzler qp->qp_num, qp->srq); 429*303ae1cdSBernard Metzler } else if (num_rqe) { 430*303ae1cdSBernard Metzler if (qp->kernel_verbs) 431*303ae1cdSBernard Metzler qp->recvq = vzalloc(num_rqe * sizeof(struct siw_rqe)); 432*303ae1cdSBernard Metzler else 433*303ae1cdSBernard Metzler qp->recvq = 434*303ae1cdSBernard Metzler vmalloc_user(num_rqe * sizeof(struct siw_rqe)); 435*303ae1cdSBernard Metzler 436*303ae1cdSBernard Metzler if (qp->recvq == NULL) { 437*303ae1cdSBernard Metzler siw_dbg(base_dev, "RQ size %d alloc failed\n", num_rqe); 438*303ae1cdSBernard Metzler rv = -ENOMEM; 439*303ae1cdSBernard Metzler goto err_out_xa; 440*303ae1cdSBernard Metzler } 441*303ae1cdSBernard Metzler qp->attrs.rq_size = num_rqe; 442*303ae1cdSBernard Metzler } 443*303ae1cdSBernard Metzler qp->attrs.sq_size = num_sqe; 444*303ae1cdSBernard Metzler qp->attrs.sq_max_sges = attrs->cap.max_send_sge; 445*303ae1cdSBernard Metzler qp->attrs.rq_max_sges = attrs->cap.max_recv_sge; 446*303ae1cdSBernard Metzler 447*303ae1cdSBernard Metzler /* Make those two tunables fixed for now. */ 448*303ae1cdSBernard Metzler qp->tx_ctx.gso_seg_limit = 1; 449*303ae1cdSBernard Metzler qp->tx_ctx.zcopy_tx = zcopy_tx; 450*303ae1cdSBernard Metzler 451*303ae1cdSBernard Metzler qp->attrs.state = SIW_QP_STATE_IDLE; 452*303ae1cdSBernard Metzler 453*303ae1cdSBernard Metzler if (udata) { 454*303ae1cdSBernard Metzler struct siw_uresp_create_qp uresp = {}; 455*303ae1cdSBernard Metzler 456*303ae1cdSBernard Metzler uresp.num_sqe = num_sqe; 457*303ae1cdSBernard Metzler uresp.num_rqe = num_rqe; 458*303ae1cdSBernard Metzler uresp.qp_id = qp_id(qp); 459*303ae1cdSBernard Metzler 460*303ae1cdSBernard Metzler if (qp->sendq) { 461*303ae1cdSBernard Metzler qp->xa_sq_index = 462*303ae1cdSBernard Metzler siw_create_uobj(uctx, qp->sendq, 463*303ae1cdSBernard Metzler num_sqe * sizeof(struct siw_sqe)); 464*303ae1cdSBernard Metzler } 465*303ae1cdSBernard Metzler if (qp->recvq) { 466*303ae1cdSBernard Metzler qp->xa_rq_index = 467*303ae1cdSBernard Metzler siw_create_uobj(uctx, qp->recvq, 468*303ae1cdSBernard Metzler num_rqe * sizeof(struct siw_rqe)); 469*303ae1cdSBernard Metzler } 470*303ae1cdSBernard Metzler if (qp->xa_sq_index == SIW_INVAL_UOBJ_KEY || 471*303ae1cdSBernard Metzler qp->xa_rq_index == SIW_INVAL_UOBJ_KEY) { 472*303ae1cdSBernard Metzler rv = -ENOMEM; 473*303ae1cdSBernard Metzler goto err_out_xa; 474*303ae1cdSBernard Metzler } 475*303ae1cdSBernard Metzler uresp.sq_key = qp->xa_sq_index << PAGE_SHIFT; 476*303ae1cdSBernard Metzler uresp.rq_key = qp->xa_rq_index << PAGE_SHIFT; 477*303ae1cdSBernard Metzler 478*303ae1cdSBernard Metzler if (udata->outlen < sizeof(uresp)) { 479*303ae1cdSBernard Metzler rv = -EINVAL; 480*303ae1cdSBernard Metzler goto err_out_xa; 481*303ae1cdSBernard Metzler } 482*303ae1cdSBernard Metzler rv = ib_copy_to_udata(udata, &uresp, sizeof(uresp)); 483*303ae1cdSBernard Metzler if (rv) 484*303ae1cdSBernard Metzler goto err_out_xa; 485*303ae1cdSBernard Metzler } 486*303ae1cdSBernard Metzler qp->tx_cpu = siw_get_tx_cpu(sdev); 487*303ae1cdSBernard Metzler if (qp->tx_cpu < 0) { 488*303ae1cdSBernard Metzler rv = -EINVAL; 489*303ae1cdSBernard Metzler goto err_out_xa; 490*303ae1cdSBernard Metzler } 491*303ae1cdSBernard Metzler INIT_LIST_HEAD(&qp->devq); 492*303ae1cdSBernard Metzler spin_lock_irqsave(&sdev->lock, flags); 493*303ae1cdSBernard Metzler list_add_tail(&qp->devq, &sdev->qp_list); 494*303ae1cdSBernard Metzler spin_unlock_irqrestore(&sdev->lock, flags); 495*303ae1cdSBernard Metzler 496*303ae1cdSBernard Metzler return qp->ib_qp; 497*303ae1cdSBernard Metzler 498*303ae1cdSBernard Metzler err_out_xa: 499*303ae1cdSBernard Metzler xa_erase(&sdev->qp_xa, qp_id(qp)); 500*303ae1cdSBernard Metzler err_out: 501*303ae1cdSBernard Metzler kfree(siw_base_qp); 502*303ae1cdSBernard Metzler 503*303ae1cdSBernard Metzler if (qp) { 504*303ae1cdSBernard Metzler if (qp->xa_sq_index != SIW_INVAL_UOBJ_KEY) 505*303ae1cdSBernard Metzler kfree(xa_erase(&uctx->xa, qp->xa_sq_index)); 506*303ae1cdSBernard Metzler if (qp->xa_rq_index != SIW_INVAL_UOBJ_KEY) 507*303ae1cdSBernard Metzler kfree(xa_erase(&uctx->xa, qp->xa_rq_index)); 508*303ae1cdSBernard Metzler 509*303ae1cdSBernard Metzler vfree(qp->sendq); 510*303ae1cdSBernard Metzler vfree(qp->recvq); 511*303ae1cdSBernard Metzler kfree(qp); 512*303ae1cdSBernard Metzler } 513*303ae1cdSBernard Metzler atomic_dec(&sdev->num_qp); 514*303ae1cdSBernard Metzler 515*303ae1cdSBernard Metzler return ERR_PTR(rv); 516*303ae1cdSBernard Metzler } 517*303ae1cdSBernard Metzler 518*303ae1cdSBernard Metzler /* 519*303ae1cdSBernard Metzler * Minimum siw_query_qp() verb interface. 520*303ae1cdSBernard Metzler * 521*303ae1cdSBernard Metzler * @qp_attr_mask is not used but all available information is provided 522*303ae1cdSBernard Metzler */ 523*303ae1cdSBernard Metzler int siw_query_qp(struct ib_qp *base_qp, struct ib_qp_attr *qp_attr, 524*303ae1cdSBernard Metzler int qp_attr_mask, struct ib_qp_init_attr *qp_init_attr) 525*303ae1cdSBernard Metzler { 526*303ae1cdSBernard Metzler struct siw_qp *qp; 527*303ae1cdSBernard Metzler struct siw_device *sdev; 528*303ae1cdSBernard Metzler 529*303ae1cdSBernard Metzler if (base_qp && qp_attr && qp_init_attr) { 530*303ae1cdSBernard Metzler qp = to_siw_qp(base_qp); 531*303ae1cdSBernard Metzler sdev = to_siw_dev(base_qp->device); 532*303ae1cdSBernard Metzler } else { 533*303ae1cdSBernard Metzler return -EINVAL; 534*303ae1cdSBernard Metzler } 535*303ae1cdSBernard Metzler qp_attr->cap.max_inline_data = SIW_MAX_INLINE; 536*303ae1cdSBernard Metzler qp_attr->cap.max_send_wr = qp->attrs.sq_size; 537*303ae1cdSBernard Metzler qp_attr->cap.max_send_sge = qp->attrs.sq_max_sges; 538*303ae1cdSBernard Metzler qp_attr->cap.max_recv_wr = qp->attrs.rq_size; 539*303ae1cdSBernard Metzler qp_attr->cap.max_recv_sge = qp->attrs.rq_max_sges; 540*303ae1cdSBernard Metzler qp_attr->path_mtu = ib_mtu_int_to_enum(sdev->netdev->mtu); 541*303ae1cdSBernard Metzler qp_attr->max_rd_atomic = qp->attrs.irq_size; 542*303ae1cdSBernard Metzler qp_attr->max_dest_rd_atomic = qp->attrs.orq_size; 543*303ae1cdSBernard Metzler 544*303ae1cdSBernard Metzler qp_attr->qp_access_flags = IB_ACCESS_LOCAL_WRITE | 545*303ae1cdSBernard Metzler IB_ACCESS_REMOTE_WRITE | 546*303ae1cdSBernard Metzler IB_ACCESS_REMOTE_READ; 547*303ae1cdSBernard Metzler 548*303ae1cdSBernard Metzler qp_init_attr->qp_type = base_qp->qp_type; 549*303ae1cdSBernard Metzler qp_init_attr->send_cq = base_qp->send_cq; 550*303ae1cdSBernard Metzler qp_init_attr->recv_cq = base_qp->recv_cq; 551*303ae1cdSBernard Metzler qp_init_attr->srq = base_qp->srq; 552*303ae1cdSBernard Metzler 553*303ae1cdSBernard Metzler qp_init_attr->cap = qp_attr->cap; 554*303ae1cdSBernard Metzler 555*303ae1cdSBernard Metzler return 0; 556*303ae1cdSBernard Metzler } 557*303ae1cdSBernard Metzler 558*303ae1cdSBernard Metzler int siw_verbs_modify_qp(struct ib_qp *base_qp, struct ib_qp_attr *attr, 559*303ae1cdSBernard Metzler int attr_mask, struct ib_udata *udata) 560*303ae1cdSBernard Metzler { 561*303ae1cdSBernard Metzler struct siw_qp_attrs new_attrs; 562*303ae1cdSBernard Metzler enum siw_qp_attr_mask siw_attr_mask = 0; 563*303ae1cdSBernard Metzler struct siw_qp *qp = to_siw_qp(base_qp); 564*303ae1cdSBernard Metzler int rv = 0; 565*303ae1cdSBernard Metzler 566*303ae1cdSBernard Metzler if (!attr_mask) 567*303ae1cdSBernard Metzler return 0; 568*303ae1cdSBernard Metzler 569*303ae1cdSBernard Metzler memset(&new_attrs, 0, sizeof(new_attrs)); 570*303ae1cdSBernard Metzler 571*303ae1cdSBernard Metzler if (attr_mask & IB_QP_ACCESS_FLAGS) { 572*303ae1cdSBernard Metzler siw_attr_mask = SIW_QP_ATTR_ACCESS_FLAGS; 573*303ae1cdSBernard Metzler 574*303ae1cdSBernard Metzler if (attr->qp_access_flags & IB_ACCESS_REMOTE_READ) 575*303ae1cdSBernard Metzler new_attrs.flags |= SIW_RDMA_READ_ENABLED; 576*303ae1cdSBernard Metzler if (attr->qp_access_flags & IB_ACCESS_REMOTE_WRITE) 577*303ae1cdSBernard Metzler new_attrs.flags |= SIW_RDMA_WRITE_ENABLED; 578*303ae1cdSBernard Metzler if (attr->qp_access_flags & IB_ACCESS_MW_BIND) 579*303ae1cdSBernard Metzler new_attrs.flags |= SIW_RDMA_BIND_ENABLED; 580*303ae1cdSBernard Metzler } 581*303ae1cdSBernard Metzler if (attr_mask & IB_QP_STATE) { 582*303ae1cdSBernard Metzler siw_dbg_qp(qp, "desired IB QP state: %s\n", 583*303ae1cdSBernard Metzler ib_qp_state_to_string[attr->qp_state]); 584*303ae1cdSBernard Metzler 585*303ae1cdSBernard Metzler new_attrs.state = ib_qp_state_to_siw_qp_state[attr->qp_state]; 586*303ae1cdSBernard Metzler 587*303ae1cdSBernard Metzler if (new_attrs.state > SIW_QP_STATE_RTS) 588*303ae1cdSBernard Metzler qp->tx_ctx.tx_suspend = 1; 589*303ae1cdSBernard Metzler 590*303ae1cdSBernard Metzler siw_attr_mask |= SIW_QP_ATTR_STATE; 591*303ae1cdSBernard Metzler } 592*303ae1cdSBernard Metzler if (!siw_attr_mask) 593*303ae1cdSBernard Metzler goto out; 594*303ae1cdSBernard Metzler 595*303ae1cdSBernard Metzler down_write(&qp->state_lock); 596*303ae1cdSBernard Metzler 597*303ae1cdSBernard Metzler rv = siw_qp_modify(qp, &new_attrs, siw_attr_mask); 598*303ae1cdSBernard Metzler 599*303ae1cdSBernard Metzler up_write(&qp->state_lock); 600*303ae1cdSBernard Metzler out: 601*303ae1cdSBernard Metzler return rv; 602*303ae1cdSBernard Metzler } 603*303ae1cdSBernard Metzler 604*303ae1cdSBernard Metzler int siw_destroy_qp(struct ib_qp *base_qp, struct ib_udata *udata) 605*303ae1cdSBernard Metzler { 606*303ae1cdSBernard Metzler struct siw_qp *qp = to_siw_qp(base_qp); 607*303ae1cdSBernard Metzler struct siw_base_qp *siw_base_qp = to_siw_base_qp(base_qp); 608*303ae1cdSBernard Metzler struct siw_ucontext *uctx = 609*303ae1cdSBernard Metzler rdma_udata_to_drv_context(udata, struct siw_ucontext, 610*303ae1cdSBernard Metzler base_ucontext); 611*303ae1cdSBernard Metzler struct siw_qp_attrs qp_attrs; 612*303ae1cdSBernard Metzler 613*303ae1cdSBernard Metzler siw_dbg_qp(qp, "state %d, cep 0x%p\n", qp->attrs.state, qp->cep); 614*303ae1cdSBernard Metzler 615*303ae1cdSBernard Metzler /* 616*303ae1cdSBernard Metzler * Mark QP as in process of destruction to prevent from 617*303ae1cdSBernard Metzler * any async callbacks to RDMA core 618*303ae1cdSBernard Metzler */ 619*303ae1cdSBernard Metzler qp->attrs.flags |= SIW_QP_IN_DESTROY; 620*303ae1cdSBernard Metzler qp->rx_stream.rx_suspend = 1; 621*303ae1cdSBernard Metzler 622*303ae1cdSBernard Metzler if (uctx && qp->xa_sq_index != SIW_INVAL_UOBJ_KEY) 623*303ae1cdSBernard Metzler kfree(xa_erase(&uctx->xa, qp->xa_sq_index)); 624*303ae1cdSBernard Metzler if (uctx && qp->xa_rq_index != SIW_INVAL_UOBJ_KEY) 625*303ae1cdSBernard Metzler kfree(xa_erase(&uctx->xa, qp->xa_rq_index)); 626*303ae1cdSBernard Metzler 627*303ae1cdSBernard Metzler down_write(&qp->state_lock); 628*303ae1cdSBernard Metzler 629*303ae1cdSBernard Metzler qp_attrs.state = SIW_QP_STATE_ERROR; 630*303ae1cdSBernard Metzler siw_qp_modify(qp, &qp_attrs, SIW_QP_ATTR_STATE); 631*303ae1cdSBernard Metzler 632*303ae1cdSBernard Metzler if (qp->cep) { 633*303ae1cdSBernard Metzler siw_cep_put(qp->cep); 634*303ae1cdSBernard Metzler qp->cep = NULL; 635*303ae1cdSBernard Metzler } 636*303ae1cdSBernard Metzler up_write(&qp->state_lock); 637*303ae1cdSBernard Metzler 638*303ae1cdSBernard Metzler kfree(qp->tx_ctx.mpa_crc_hd); 639*303ae1cdSBernard Metzler kfree(qp->rx_stream.mpa_crc_hd); 640*303ae1cdSBernard Metzler 641*303ae1cdSBernard Metzler qp->scq = qp->rcq = NULL; 642*303ae1cdSBernard Metzler 643*303ae1cdSBernard Metzler siw_qp_put(qp); 644*303ae1cdSBernard Metzler kfree(siw_base_qp); 645*303ae1cdSBernard Metzler 646*303ae1cdSBernard Metzler return 0; 647*303ae1cdSBernard Metzler } 648*303ae1cdSBernard Metzler 649*303ae1cdSBernard Metzler /* 650*303ae1cdSBernard Metzler * siw_copy_inline_sgl() 651*303ae1cdSBernard Metzler * 652*303ae1cdSBernard Metzler * Prepare sgl of inlined data for sending. For userland callers 653*303ae1cdSBernard Metzler * function checks if given buffer addresses and len's are within 654*303ae1cdSBernard Metzler * process context bounds. 655*303ae1cdSBernard Metzler * Data from all provided sge's are copied together into the wqe, 656*303ae1cdSBernard Metzler * referenced by a single sge. 657*303ae1cdSBernard Metzler */ 658*303ae1cdSBernard Metzler static int siw_copy_inline_sgl(const struct ib_send_wr *core_wr, 659*303ae1cdSBernard Metzler struct siw_sqe *sqe) 660*303ae1cdSBernard Metzler { 661*303ae1cdSBernard Metzler struct ib_sge *core_sge = core_wr->sg_list; 662*303ae1cdSBernard Metzler void *kbuf = &sqe->sge[1]; 663*303ae1cdSBernard Metzler int num_sge = core_wr->num_sge, bytes = 0; 664*303ae1cdSBernard Metzler 665*303ae1cdSBernard Metzler sqe->sge[0].laddr = (u64)kbuf; 666*303ae1cdSBernard Metzler sqe->sge[0].lkey = 0; 667*303ae1cdSBernard Metzler 668*303ae1cdSBernard Metzler while (num_sge--) { 669*303ae1cdSBernard Metzler if (!core_sge->length) { 670*303ae1cdSBernard Metzler core_sge++; 671*303ae1cdSBernard Metzler continue; 672*303ae1cdSBernard Metzler } 673*303ae1cdSBernard Metzler bytes += core_sge->length; 674*303ae1cdSBernard Metzler if (bytes > SIW_MAX_INLINE) { 675*303ae1cdSBernard Metzler bytes = -EINVAL; 676*303ae1cdSBernard Metzler break; 677*303ae1cdSBernard Metzler } 678*303ae1cdSBernard Metzler memcpy(kbuf, (void *)(uintptr_t)core_sge->addr, 679*303ae1cdSBernard Metzler core_sge->length); 680*303ae1cdSBernard Metzler 681*303ae1cdSBernard Metzler kbuf += core_sge->length; 682*303ae1cdSBernard Metzler core_sge++; 683*303ae1cdSBernard Metzler } 684*303ae1cdSBernard Metzler sqe->sge[0].length = bytes > 0 ? bytes : 0; 685*303ae1cdSBernard Metzler sqe->num_sge = bytes > 0 ? 1 : 0; 686*303ae1cdSBernard Metzler 687*303ae1cdSBernard Metzler return bytes; 688*303ae1cdSBernard Metzler } 689*303ae1cdSBernard Metzler 690*303ae1cdSBernard Metzler /* 691*303ae1cdSBernard Metzler * siw_post_send() 692*303ae1cdSBernard Metzler * 693*303ae1cdSBernard Metzler * Post a list of S-WR's to a SQ. 694*303ae1cdSBernard Metzler * 695*303ae1cdSBernard Metzler * @base_qp: Base QP contained in siw QP 696*303ae1cdSBernard Metzler * @wr: Null terminated list of user WR's 697*303ae1cdSBernard Metzler * @bad_wr: Points to failing WR in case of synchronous failure. 698*303ae1cdSBernard Metzler */ 699*303ae1cdSBernard Metzler int siw_post_send(struct ib_qp *base_qp, const struct ib_send_wr *wr, 700*303ae1cdSBernard Metzler const struct ib_send_wr **bad_wr) 701*303ae1cdSBernard Metzler { 702*303ae1cdSBernard Metzler struct siw_qp *qp = to_siw_qp(base_qp); 703*303ae1cdSBernard Metzler struct siw_wqe *wqe = tx_wqe(qp); 704*303ae1cdSBernard Metzler 705*303ae1cdSBernard Metzler unsigned long flags; 706*303ae1cdSBernard Metzler int rv = 0; 707*303ae1cdSBernard Metzler 708*303ae1cdSBernard Metzler /* 709*303ae1cdSBernard Metzler * Try to acquire QP state lock. Must be non-blocking 710*303ae1cdSBernard Metzler * to accommodate kernel clients needs. 711*303ae1cdSBernard Metzler */ 712*303ae1cdSBernard Metzler if (!down_read_trylock(&qp->state_lock)) { 713*303ae1cdSBernard Metzler *bad_wr = wr; 714*303ae1cdSBernard Metzler siw_dbg_qp(qp, "QP locked, state %d\n", qp->attrs.state); 715*303ae1cdSBernard Metzler return -ENOTCONN; 716*303ae1cdSBernard Metzler } 717*303ae1cdSBernard Metzler if (unlikely(qp->attrs.state != SIW_QP_STATE_RTS)) { 718*303ae1cdSBernard Metzler up_read(&qp->state_lock); 719*303ae1cdSBernard Metzler *bad_wr = wr; 720*303ae1cdSBernard Metzler siw_dbg_qp(qp, "QP out of state %d\n", qp->attrs.state); 721*303ae1cdSBernard Metzler return -ENOTCONN; 722*303ae1cdSBernard Metzler } 723*303ae1cdSBernard Metzler if (wr && !qp->kernel_verbs) { 724*303ae1cdSBernard Metzler siw_dbg_qp(qp, "wr must be empty for user mapped sq\n"); 725*303ae1cdSBernard Metzler up_read(&qp->state_lock); 726*303ae1cdSBernard Metzler *bad_wr = wr; 727*303ae1cdSBernard Metzler return -EINVAL; 728*303ae1cdSBernard Metzler } 729*303ae1cdSBernard Metzler spin_lock_irqsave(&qp->sq_lock, flags); 730*303ae1cdSBernard Metzler 731*303ae1cdSBernard Metzler while (wr) { 732*303ae1cdSBernard Metzler u32 idx = qp->sq_put % qp->attrs.sq_size; 733*303ae1cdSBernard Metzler struct siw_sqe *sqe = &qp->sendq[idx]; 734*303ae1cdSBernard Metzler 735*303ae1cdSBernard Metzler if (sqe->flags) { 736*303ae1cdSBernard Metzler siw_dbg_qp(qp, "sq full\n"); 737*303ae1cdSBernard Metzler rv = -ENOMEM; 738*303ae1cdSBernard Metzler break; 739*303ae1cdSBernard Metzler } 740*303ae1cdSBernard Metzler if (wr->num_sge > qp->attrs.sq_max_sges) { 741*303ae1cdSBernard Metzler siw_dbg_qp(qp, "too many sge's: %d\n", wr->num_sge); 742*303ae1cdSBernard Metzler rv = -EINVAL; 743*303ae1cdSBernard Metzler break; 744*303ae1cdSBernard Metzler } 745*303ae1cdSBernard Metzler sqe->id = wr->wr_id; 746*303ae1cdSBernard Metzler 747*303ae1cdSBernard Metzler if ((wr->send_flags & IB_SEND_SIGNALED) || 748*303ae1cdSBernard Metzler (qp->attrs.flags & SIW_SIGNAL_ALL_WR)) 749*303ae1cdSBernard Metzler sqe->flags |= SIW_WQE_SIGNALLED; 750*303ae1cdSBernard Metzler 751*303ae1cdSBernard Metzler if (wr->send_flags & IB_SEND_FENCE) 752*303ae1cdSBernard Metzler sqe->flags |= SIW_WQE_READ_FENCE; 753*303ae1cdSBernard Metzler 754*303ae1cdSBernard Metzler switch (wr->opcode) { 755*303ae1cdSBernard Metzler case IB_WR_SEND: 756*303ae1cdSBernard Metzler case IB_WR_SEND_WITH_INV: 757*303ae1cdSBernard Metzler if (wr->send_flags & IB_SEND_SOLICITED) 758*303ae1cdSBernard Metzler sqe->flags |= SIW_WQE_SOLICITED; 759*303ae1cdSBernard Metzler 760*303ae1cdSBernard Metzler if (!(wr->send_flags & IB_SEND_INLINE)) { 761*303ae1cdSBernard Metzler siw_copy_sgl(wr->sg_list, sqe->sge, 762*303ae1cdSBernard Metzler wr->num_sge); 763*303ae1cdSBernard Metzler sqe->num_sge = wr->num_sge; 764*303ae1cdSBernard Metzler } else { 765*303ae1cdSBernard Metzler rv = siw_copy_inline_sgl(wr, sqe); 766*303ae1cdSBernard Metzler if (rv <= 0) { 767*303ae1cdSBernard Metzler rv = -EINVAL; 768*303ae1cdSBernard Metzler break; 769*303ae1cdSBernard Metzler } 770*303ae1cdSBernard Metzler sqe->flags |= SIW_WQE_INLINE; 771*303ae1cdSBernard Metzler sqe->num_sge = 1; 772*303ae1cdSBernard Metzler } 773*303ae1cdSBernard Metzler if (wr->opcode == IB_WR_SEND) 774*303ae1cdSBernard Metzler sqe->opcode = SIW_OP_SEND; 775*303ae1cdSBernard Metzler else { 776*303ae1cdSBernard Metzler sqe->opcode = SIW_OP_SEND_REMOTE_INV; 777*303ae1cdSBernard Metzler sqe->rkey = wr->ex.invalidate_rkey; 778*303ae1cdSBernard Metzler } 779*303ae1cdSBernard Metzler break; 780*303ae1cdSBernard Metzler 781*303ae1cdSBernard Metzler case IB_WR_RDMA_READ_WITH_INV: 782*303ae1cdSBernard Metzler case IB_WR_RDMA_READ: 783*303ae1cdSBernard Metzler /* 784*303ae1cdSBernard Metzler * iWarp restricts RREAD sink to SGL containing 785*303ae1cdSBernard Metzler * 1 SGE only. we could relax to SGL with multiple 786*303ae1cdSBernard Metzler * elements referring the SAME ltag or even sending 787*303ae1cdSBernard Metzler * a private per-rreq tag referring to a checked 788*303ae1cdSBernard Metzler * local sgl with MULTIPLE ltag's. 789*303ae1cdSBernard Metzler */ 790*303ae1cdSBernard Metzler if (unlikely(wr->num_sge != 1)) { 791*303ae1cdSBernard Metzler rv = -EINVAL; 792*303ae1cdSBernard Metzler break; 793*303ae1cdSBernard Metzler } 794*303ae1cdSBernard Metzler siw_copy_sgl(wr->sg_list, &sqe->sge[0], 1); 795*303ae1cdSBernard Metzler /* 796*303ae1cdSBernard Metzler * NOTE: zero length RREAD is allowed! 797*303ae1cdSBernard Metzler */ 798*303ae1cdSBernard Metzler sqe->raddr = rdma_wr(wr)->remote_addr; 799*303ae1cdSBernard Metzler sqe->rkey = rdma_wr(wr)->rkey; 800*303ae1cdSBernard Metzler sqe->num_sge = 1; 801*303ae1cdSBernard Metzler 802*303ae1cdSBernard Metzler if (wr->opcode == IB_WR_RDMA_READ) 803*303ae1cdSBernard Metzler sqe->opcode = SIW_OP_READ; 804*303ae1cdSBernard Metzler else 805*303ae1cdSBernard Metzler sqe->opcode = SIW_OP_READ_LOCAL_INV; 806*303ae1cdSBernard Metzler break; 807*303ae1cdSBernard Metzler 808*303ae1cdSBernard Metzler case IB_WR_RDMA_WRITE: 809*303ae1cdSBernard Metzler if (!(wr->send_flags & IB_SEND_INLINE)) { 810*303ae1cdSBernard Metzler siw_copy_sgl(wr->sg_list, &sqe->sge[0], 811*303ae1cdSBernard Metzler wr->num_sge); 812*303ae1cdSBernard Metzler sqe->num_sge = wr->num_sge; 813*303ae1cdSBernard Metzler } else { 814*303ae1cdSBernard Metzler rv = siw_copy_inline_sgl(wr, sqe); 815*303ae1cdSBernard Metzler if (unlikely(rv < 0)) { 816*303ae1cdSBernard Metzler rv = -EINVAL; 817*303ae1cdSBernard Metzler break; 818*303ae1cdSBernard Metzler } 819*303ae1cdSBernard Metzler sqe->flags |= SIW_WQE_INLINE; 820*303ae1cdSBernard Metzler sqe->num_sge = 1; 821*303ae1cdSBernard Metzler } 822*303ae1cdSBernard Metzler sqe->raddr = rdma_wr(wr)->remote_addr; 823*303ae1cdSBernard Metzler sqe->rkey = rdma_wr(wr)->rkey; 824*303ae1cdSBernard Metzler sqe->opcode = SIW_OP_WRITE; 825*303ae1cdSBernard Metzler break; 826*303ae1cdSBernard Metzler 827*303ae1cdSBernard Metzler case IB_WR_REG_MR: 828*303ae1cdSBernard Metzler sqe->base_mr = (uint64_t)reg_wr(wr)->mr; 829*303ae1cdSBernard Metzler sqe->rkey = reg_wr(wr)->key; 830*303ae1cdSBernard Metzler sqe->access = reg_wr(wr)->access & IWARP_ACCESS_MASK; 831*303ae1cdSBernard Metzler sqe->opcode = SIW_OP_REG_MR; 832*303ae1cdSBernard Metzler break; 833*303ae1cdSBernard Metzler 834*303ae1cdSBernard Metzler case IB_WR_LOCAL_INV: 835*303ae1cdSBernard Metzler sqe->rkey = wr->ex.invalidate_rkey; 836*303ae1cdSBernard Metzler sqe->opcode = SIW_OP_INVAL_STAG; 837*303ae1cdSBernard Metzler break; 838*303ae1cdSBernard Metzler 839*303ae1cdSBernard Metzler default: 840*303ae1cdSBernard Metzler siw_dbg_qp(qp, "ib wr type %d unsupported\n", 841*303ae1cdSBernard Metzler wr->opcode); 842*303ae1cdSBernard Metzler rv = -EINVAL; 843*303ae1cdSBernard Metzler break; 844*303ae1cdSBernard Metzler } 845*303ae1cdSBernard Metzler siw_dbg_qp(qp, "opcode %d, flags 0x%x, wr_id 0x%p\n", 846*303ae1cdSBernard Metzler sqe->opcode, sqe->flags, (void *)sqe->id); 847*303ae1cdSBernard Metzler 848*303ae1cdSBernard Metzler if (unlikely(rv < 0)) 849*303ae1cdSBernard Metzler break; 850*303ae1cdSBernard Metzler 851*303ae1cdSBernard Metzler /* make SQE only valid after completely written */ 852*303ae1cdSBernard Metzler smp_wmb(); 853*303ae1cdSBernard Metzler sqe->flags |= SIW_WQE_VALID; 854*303ae1cdSBernard Metzler 855*303ae1cdSBernard Metzler qp->sq_put++; 856*303ae1cdSBernard Metzler wr = wr->next; 857*303ae1cdSBernard Metzler } 858*303ae1cdSBernard Metzler 859*303ae1cdSBernard Metzler /* 860*303ae1cdSBernard Metzler * Send directly if SQ processing is not in progress. 861*303ae1cdSBernard Metzler * Eventual immediate errors (rv < 0) do not affect the involved 862*303ae1cdSBernard Metzler * RI resources (Verbs, 8.3.1) and thus do not prevent from SQ 863*303ae1cdSBernard Metzler * processing, if new work is already pending. But rv must be passed 864*303ae1cdSBernard Metzler * to caller. 865*303ae1cdSBernard Metzler */ 866*303ae1cdSBernard Metzler if (wqe->wr_status != SIW_WR_IDLE) { 867*303ae1cdSBernard Metzler spin_unlock_irqrestore(&qp->sq_lock, flags); 868*303ae1cdSBernard Metzler goto skip_direct_sending; 869*303ae1cdSBernard Metzler } 870*303ae1cdSBernard Metzler rv = siw_activate_tx(qp); 871*303ae1cdSBernard Metzler spin_unlock_irqrestore(&qp->sq_lock, flags); 872*303ae1cdSBernard Metzler 873*303ae1cdSBernard Metzler if (rv <= 0) 874*303ae1cdSBernard Metzler goto skip_direct_sending; 875*303ae1cdSBernard Metzler 876*303ae1cdSBernard Metzler if (qp->kernel_verbs) { 877*303ae1cdSBernard Metzler rv = siw_sq_start(qp); 878*303ae1cdSBernard Metzler } else { 879*303ae1cdSBernard Metzler qp->tx_ctx.in_syscall = 1; 880*303ae1cdSBernard Metzler 881*303ae1cdSBernard Metzler if (siw_qp_sq_process(qp) != 0 && !(qp->tx_ctx.tx_suspend)) 882*303ae1cdSBernard Metzler siw_qp_cm_drop(qp, 0); 883*303ae1cdSBernard Metzler 884*303ae1cdSBernard Metzler qp->tx_ctx.in_syscall = 0; 885*303ae1cdSBernard Metzler } 886*303ae1cdSBernard Metzler skip_direct_sending: 887*303ae1cdSBernard Metzler 888*303ae1cdSBernard Metzler up_read(&qp->state_lock); 889*303ae1cdSBernard Metzler 890*303ae1cdSBernard Metzler if (rv >= 0) 891*303ae1cdSBernard Metzler return 0; 892*303ae1cdSBernard Metzler /* 893*303ae1cdSBernard Metzler * Immediate error 894*303ae1cdSBernard Metzler */ 895*303ae1cdSBernard Metzler siw_dbg_qp(qp, "error %d\n", rv); 896*303ae1cdSBernard Metzler 897*303ae1cdSBernard Metzler *bad_wr = wr; 898*303ae1cdSBernard Metzler return rv; 899*303ae1cdSBernard Metzler } 900*303ae1cdSBernard Metzler 901*303ae1cdSBernard Metzler /* 902*303ae1cdSBernard Metzler * siw_post_receive() 903*303ae1cdSBernard Metzler * 904*303ae1cdSBernard Metzler * Post a list of R-WR's to a RQ. 905*303ae1cdSBernard Metzler * 906*303ae1cdSBernard Metzler * @base_qp: Base QP contained in siw QP 907*303ae1cdSBernard Metzler * @wr: Null terminated list of user WR's 908*303ae1cdSBernard Metzler * @bad_wr: Points to failing WR in case of synchronous failure. 909*303ae1cdSBernard Metzler */ 910*303ae1cdSBernard Metzler int siw_post_receive(struct ib_qp *base_qp, const struct ib_recv_wr *wr, 911*303ae1cdSBernard Metzler const struct ib_recv_wr **bad_wr) 912*303ae1cdSBernard Metzler { 913*303ae1cdSBernard Metzler struct siw_qp *qp = to_siw_qp(base_qp); 914*303ae1cdSBernard Metzler unsigned long flags; 915*303ae1cdSBernard Metzler int rv = 0; 916*303ae1cdSBernard Metzler 917*303ae1cdSBernard Metzler if (qp->srq) { 918*303ae1cdSBernard Metzler *bad_wr = wr; 919*303ae1cdSBernard Metzler return -EOPNOTSUPP; /* what else from errno.h? */ 920*303ae1cdSBernard Metzler } 921*303ae1cdSBernard Metzler /* 922*303ae1cdSBernard Metzler * Try to acquire QP state lock. Must be non-blocking 923*303ae1cdSBernard Metzler * to accommodate kernel clients needs. 924*303ae1cdSBernard Metzler */ 925*303ae1cdSBernard Metzler if (!down_read_trylock(&qp->state_lock)) { 926*303ae1cdSBernard Metzler *bad_wr = wr; 927*303ae1cdSBernard Metzler return -ENOTCONN; 928*303ae1cdSBernard Metzler } 929*303ae1cdSBernard Metzler if (!qp->kernel_verbs) { 930*303ae1cdSBernard Metzler siw_dbg_qp(qp, "no kernel post_recv for user mapped sq\n"); 931*303ae1cdSBernard Metzler up_read(&qp->state_lock); 932*303ae1cdSBernard Metzler *bad_wr = wr; 933*303ae1cdSBernard Metzler return -EINVAL; 934*303ae1cdSBernard Metzler } 935*303ae1cdSBernard Metzler if (qp->attrs.state > SIW_QP_STATE_RTS) { 936*303ae1cdSBernard Metzler up_read(&qp->state_lock); 937*303ae1cdSBernard Metzler *bad_wr = wr; 938*303ae1cdSBernard Metzler return -EINVAL; 939*303ae1cdSBernard Metzler } 940*303ae1cdSBernard Metzler /* 941*303ae1cdSBernard Metzler * Serialize potentially multiple producers. 942*303ae1cdSBernard Metzler * Not needed for single threaded consumer side. 943*303ae1cdSBernard Metzler */ 944*303ae1cdSBernard Metzler spin_lock_irqsave(&qp->rq_lock, flags); 945*303ae1cdSBernard Metzler 946*303ae1cdSBernard Metzler while (wr) { 947*303ae1cdSBernard Metzler u32 idx = qp->rq_put % qp->attrs.rq_size; 948*303ae1cdSBernard Metzler struct siw_rqe *rqe = &qp->recvq[idx]; 949*303ae1cdSBernard Metzler 950*303ae1cdSBernard Metzler if (rqe->flags) { 951*303ae1cdSBernard Metzler siw_dbg_qp(qp, "RQ full\n"); 952*303ae1cdSBernard Metzler rv = -ENOMEM; 953*303ae1cdSBernard Metzler break; 954*303ae1cdSBernard Metzler } 955*303ae1cdSBernard Metzler if (wr->num_sge > qp->attrs.rq_max_sges) { 956*303ae1cdSBernard Metzler siw_dbg_qp(qp, "too many sge's: %d\n", wr->num_sge); 957*303ae1cdSBernard Metzler rv = -EINVAL; 958*303ae1cdSBernard Metzler break; 959*303ae1cdSBernard Metzler } 960*303ae1cdSBernard Metzler rqe->id = wr->wr_id; 961*303ae1cdSBernard Metzler rqe->num_sge = wr->num_sge; 962*303ae1cdSBernard Metzler siw_copy_sgl(wr->sg_list, rqe->sge, wr->num_sge); 963*303ae1cdSBernard Metzler 964*303ae1cdSBernard Metzler /* make sure RQE is completely written before valid */ 965*303ae1cdSBernard Metzler smp_wmb(); 966*303ae1cdSBernard Metzler 967*303ae1cdSBernard Metzler rqe->flags = SIW_WQE_VALID; 968*303ae1cdSBernard Metzler 969*303ae1cdSBernard Metzler qp->rq_put++; 970*303ae1cdSBernard Metzler wr = wr->next; 971*303ae1cdSBernard Metzler } 972*303ae1cdSBernard Metzler spin_unlock_irqrestore(&qp->rq_lock, flags); 973*303ae1cdSBernard Metzler 974*303ae1cdSBernard Metzler up_read(&qp->state_lock); 975*303ae1cdSBernard Metzler 976*303ae1cdSBernard Metzler if (rv < 0) { 977*303ae1cdSBernard Metzler siw_dbg_qp(qp, "error %d\n", rv); 978*303ae1cdSBernard Metzler *bad_wr = wr; 979*303ae1cdSBernard Metzler } 980*303ae1cdSBernard Metzler return rv > 0 ? 0 : rv; 981*303ae1cdSBernard Metzler } 982*303ae1cdSBernard Metzler 983*303ae1cdSBernard Metzler void siw_destroy_cq(struct ib_cq *base_cq, struct ib_udata *udata) 984*303ae1cdSBernard Metzler { 985*303ae1cdSBernard Metzler struct siw_cq *cq = to_siw_cq(base_cq); 986*303ae1cdSBernard Metzler struct siw_device *sdev = to_siw_dev(base_cq->device); 987*303ae1cdSBernard Metzler struct siw_ucontext *ctx = 988*303ae1cdSBernard Metzler rdma_udata_to_drv_context(udata, struct siw_ucontext, 989*303ae1cdSBernard Metzler base_ucontext); 990*303ae1cdSBernard Metzler 991*303ae1cdSBernard Metzler siw_dbg_cq(cq, "free CQ resources\n"); 992*303ae1cdSBernard Metzler 993*303ae1cdSBernard Metzler siw_cq_flush(cq); 994*303ae1cdSBernard Metzler 995*303ae1cdSBernard Metzler if (ctx && cq->xa_cq_index != SIW_INVAL_UOBJ_KEY) 996*303ae1cdSBernard Metzler kfree(xa_erase(&ctx->xa, cq->xa_cq_index)); 997*303ae1cdSBernard Metzler 998*303ae1cdSBernard Metzler atomic_dec(&sdev->num_cq); 999*303ae1cdSBernard Metzler 1000*303ae1cdSBernard Metzler vfree(cq->queue); 1001*303ae1cdSBernard Metzler } 1002*303ae1cdSBernard Metzler 1003*303ae1cdSBernard Metzler /* 1004*303ae1cdSBernard Metzler * siw_create_cq() 1005*303ae1cdSBernard Metzler * 1006*303ae1cdSBernard Metzler * Populate CQ of requested size 1007*303ae1cdSBernard Metzler * 1008*303ae1cdSBernard Metzler * @base_cq: CQ as allocated by RDMA midlayer 1009*303ae1cdSBernard Metzler * @attr: Initial CQ attributes 1010*303ae1cdSBernard Metzler * @udata: relates to user context 1011*303ae1cdSBernard Metzler */ 1012*303ae1cdSBernard Metzler 1013*303ae1cdSBernard Metzler int siw_create_cq(struct ib_cq *base_cq, const struct ib_cq_init_attr *attr, 1014*303ae1cdSBernard Metzler struct ib_udata *udata) 1015*303ae1cdSBernard Metzler { 1016*303ae1cdSBernard Metzler struct siw_device *sdev = to_siw_dev(base_cq->device); 1017*303ae1cdSBernard Metzler struct siw_cq *cq = to_siw_cq(base_cq); 1018*303ae1cdSBernard Metzler int rv, size = attr->cqe; 1019*303ae1cdSBernard Metzler 1020*303ae1cdSBernard Metzler if (atomic_inc_return(&sdev->num_cq) > SIW_MAX_CQ) { 1021*303ae1cdSBernard Metzler siw_dbg(base_cq->device, "too many CQ's\n"); 1022*303ae1cdSBernard Metzler rv = -ENOMEM; 1023*303ae1cdSBernard Metzler goto err_out; 1024*303ae1cdSBernard Metzler } 1025*303ae1cdSBernard Metzler if (size < 1 || size > sdev->attrs.max_cqe) { 1026*303ae1cdSBernard Metzler siw_dbg(base_cq->device, "CQ size error: %d\n", size); 1027*303ae1cdSBernard Metzler rv = -EINVAL; 1028*303ae1cdSBernard Metzler goto err_out; 1029*303ae1cdSBernard Metzler } 1030*303ae1cdSBernard Metzler size = roundup_pow_of_two(size); 1031*303ae1cdSBernard Metzler cq->base_cq.cqe = size; 1032*303ae1cdSBernard Metzler cq->num_cqe = size; 1033*303ae1cdSBernard Metzler cq->xa_cq_index = SIW_INVAL_UOBJ_KEY; 1034*303ae1cdSBernard Metzler 1035*303ae1cdSBernard Metzler if (!udata) { 1036*303ae1cdSBernard Metzler cq->kernel_verbs = 1; 1037*303ae1cdSBernard Metzler cq->queue = vzalloc(size * sizeof(struct siw_cqe) + 1038*303ae1cdSBernard Metzler sizeof(struct siw_cq_ctrl)); 1039*303ae1cdSBernard Metzler } else { 1040*303ae1cdSBernard Metzler cq->queue = vmalloc_user(size * sizeof(struct siw_cqe) + 1041*303ae1cdSBernard Metzler sizeof(struct siw_cq_ctrl)); 1042*303ae1cdSBernard Metzler } 1043*303ae1cdSBernard Metzler if (cq->queue == NULL) { 1044*303ae1cdSBernard Metzler rv = -ENOMEM; 1045*303ae1cdSBernard Metzler goto err_out; 1046*303ae1cdSBernard Metzler } 1047*303ae1cdSBernard Metzler get_random_bytes(&cq->id, 4); 1048*303ae1cdSBernard Metzler siw_dbg(base_cq->device, "new CQ [%u]\n", cq->id); 1049*303ae1cdSBernard Metzler 1050*303ae1cdSBernard Metzler spin_lock_init(&cq->lock); 1051*303ae1cdSBernard Metzler 1052*303ae1cdSBernard Metzler cq->notify = &((struct siw_cq_ctrl *)&cq->queue[size])->notify; 1053*303ae1cdSBernard Metzler 1054*303ae1cdSBernard Metzler if (udata) { 1055*303ae1cdSBernard Metzler struct siw_uresp_create_cq uresp = {}; 1056*303ae1cdSBernard Metzler struct siw_ucontext *ctx = 1057*303ae1cdSBernard Metzler rdma_udata_to_drv_context(udata, struct siw_ucontext, 1058*303ae1cdSBernard Metzler base_ucontext); 1059*303ae1cdSBernard Metzler 1060*303ae1cdSBernard Metzler cq->xa_cq_index = 1061*303ae1cdSBernard Metzler siw_create_uobj(ctx, cq->queue, 1062*303ae1cdSBernard Metzler size * sizeof(struct siw_cqe) + 1063*303ae1cdSBernard Metzler sizeof(struct siw_cq_ctrl)); 1064*303ae1cdSBernard Metzler if (cq->xa_cq_index == SIW_INVAL_UOBJ_KEY) { 1065*303ae1cdSBernard Metzler rv = -ENOMEM; 1066*303ae1cdSBernard Metzler goto err_out; 1067*303ae1cdSBernard Metzler } 1068*303ae1cdSBernard Metzler uresp.cq_key = cq->xa_cq_index << PAGE_SHIFT; 1069*303ae1cdSBernard Metzler uresp.cq_id = cq->id; 1070*303ae1cdSBernard Metzler uresp.num_cqe = size; 1071*303ae1cdSBernard Metzler 1072*303ae1cdSBernard Metzler if (udata->outlen < sizeof(uresp)) { 1073*303ae1cdSBernard Metzler rv = -EINVAL; 1074*303ae1cdSBernard Metzler goto err_out; 1075*303ae1cdSBernard Metzler } 1076*303ae1cdSBernard Metzler rv = ib_copy_to_udata(udata, &uresp, sizeof(uresp)); 1077*303ae1cdSBernard Metzler if (rv) 1078*303ae1cdSBernard Metzler goto err_out; 1079*303ae1cdSBernard Metzler } 1080*303ae1cdSBernard Metzler return 0; 1081*303ae1cdSBernard Metzler 1082*303ae1cdSBernard Metzler err_out: 1083*303ae1cdSBernard Metzler siw_dbg(base_cq->device, "CQ creation failed: %d", rv); 1084*303ae1cdSBernard Metzler 1085*303ae1cdSBernard Metzler if (cq && cq->queue) { 1086*303ae1cdSBernard Metzler struct siw_ucontext *ctx = 1087*303ae1cdSBernard Metzler rdma_udata_to_drv_context(udata, struct siw_ucontext, 1088*303ae1cdSBernard Metzler base_ucontext); 1089*303ae1cdSBernard Metzler if (cq->xa_cq_index != SIW_INVAL_UOBJ_KEY) 1090*303ae1cdSBernard Metzler kfree(xa_erase(&ctx->xa, cq->xa_cq_index)); 1091*303ae1cdSBernard Metzler vfree(cq->queue); 1092*303ae1cdSBernard Metzler } 1093*303ae1cdSBernard Metzler atomic_dec(&sdev->num_cq); 1094*303ae1cdSBernard Metzler 1095*303ae1cdSBernard Metzler return rv; 1096*303ae1cdSBernard Metzler } 1097*303ae1cdSBernard Metzler 1098*303ae1cdSBernard Metzler /* 1099*303ae1cdSBernard Metzler * siw_poll_cq() 1100*303ae1cdSBernard Metzler * 1101*303ae1cdSBernard Metzler * Reap CQ entries if available and copy work completion status into 1102*303ae1cdSBernard Metzler * array of WC's provided by caller. Returns number of reaped CQE's. 1103*303ae1cdSBernard Metzler * 1104*303ae1cdSBernard Metzler * @base_cq: Base CQ contained in siw CQ. 1105*303ae1cdSBernard Metzler * @num_cqe: Maximum number of CQE's to reap. 1106*303ae1cdSBernard Metzler * @wc: Array of work completions to be filled by siw. 1107*303ae1cdSBernard Metzler */ 1108*303ae1cdSBernard Metzler int siw_poll_cq(struct ib_cq *base_cq, int num_cqe, struct ib_wc *wc) 1109*303ae1cdSBernard Metzler { 1110*303ae1cdSBernard Metzler struct siw_cq *cq = to_siw_cq(base_cq); 1111*303ae1cdSBernard Metzler int i; 1112*303ae1cdSBernard Metzler 1113*303ae1cdSBernard Metzler for (i = 0; i < num_cqe; i++) { 1114*303ae1cdSBernard Metzler if (!siw_reap_cqe(cq, wc)) 1115*303ae1cdSBernard Metzler break; 1116*303ae1cdSBernard Metzler wc++; 1117*303ae1cdSBernard Metzler } 1118*303ae1cdSBernard Metzler return i; 1119*303ae1cdSBernard Metzler } 1120*303ae1cdSBernard Metzler 1121*303ae1cdSBernard Metzler /* 1122*303ae1cdSBernard Metzler * siw_req_notify_cq() 1123*303ae1cdSBernard Metzler * 1124*303ae1cdSBernard Metzler * Request notification for new CQE's added to that CQ. 1125*303ae1cdSBernard Metzler * Defined flags: 1126*303ae1cdSBernard Metzler * o SIW_CQ_NOTIFY_SOLICITED lets siw trigger a notification 1127*303ae1cdSBernard Metzler * event if a WQE with notification flag set enters the CQ 1128*303ae1cdSBernard Metzler * o SIW_CQ_NOTIFY_NEXT_COMP lets siw trigger a notification 1129*303ae1cdSBernard Metzler * event if a WQE enters the CQ. 1130*303ae1cdSBernard Metzler * o IB_CQ_REPORT_MISSED_EVENTS: return value will provide the 1131*303ae1cdSBernard Metzler * number of not reaped CQE's regardless of its notification 1132*303ae1cdSBernard Metzler * type and current or new CQ notification settings. 1133*303ae1cdSBernard Metzler * 1134*303ae1cdSBernard Metzler * @base_cq: Base CQ contained in siw CQ. 1135*303ae1cdSBernard Metzler * @flags: Requested notification flags. 1136*303ae1cdSBernard Metzler */ 1137*303ae1cdSBernard Metzler int siw_req_notify_cq(struct ib_cq *base_cq, enum ib_cq_notify_flags flags) 1138*303ae1cdSBernard Metzler { 1139*303ae1cdSBernard Metzler struct siw_cq *cq = to_siw_cq(base_cq); 1140*303ae1cdSBernard Metzler 1141*303ae1cdSBernard Metzler siw_dbg_cq(cq, "flags: 0x%02x\n", flags); 1142*303ae1cdSBernard Metzler 1143*303ae1cdSBernard Metzler if ((flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED) 1144*303ae1cdSBernard Metzler /* CQ event for next solicited completion */ 1145*303ae1cdSBernard Metzler smp_store_mb(*cq->notify, SIW_NOTIFY_SOLICITED); 1146*303ae1cdSBernard Metzler else 1147*303ae1cdSBernard Metzler /* CQ event for any signalled completion */ 1148*303ae1cdSBernard Metzler smp_store_mb(*cq->notify, SIW_NOTIFY_ALL); 1149*303ae1cdSBernard Metzler 1150*303ae1cdSBernard Metzler if (flags & IB_CQ_REPORT_MISSED_EVENTS) 1151*303ae1cdSBernard Metzler return cq->cq_put - cq->cq_get; 1152*303ae1cdSBernard Metzler 1153*303ae1cdSBernard Metzler return 0; 1154*303ae1cdSBernard Metzler } 1155*303ae1cdSBernard Metzler 1156*303ae1cdSBernard Metzler /* 1157*303ae1cdSBernard Metzler * siw_dereg_mr() 1158*303ae1cdSBernard Metzler * 1159*303ae1cdSBernard Metzler * Release Memory Region. 1160*303ae1cdSBernard Metzler * 1161*303ae1cdSBernard Metzler * @base_mr: Base MR contained in siw MR. 1162*303ae1cdSBernard Metzler * @udata: points to user context, unused. 1163*303ae1cdSBernard Metzler */ 1164*303ae1cdSBernard Metzler int siw_dereg_mr(struct ib_mr *base_mr, struct ib_udata *udata) 1165*303ae1cdSBernard Metzler { 1166*303ae1cdSBernard Metzler struct siw_mr *mr = to_siw_mr(base_mr); 1167*303ae1cdSBernard Metzler struct siw_device *sdev = to_siw_dev(base_mr->device); 1168*303ae1cdSBernard Metzler 1169*303ae1cdSBernard Metzler siw_dbg_mem(mr->mem, "deregister MR\n"); 1170*303ae1cdSBernard Metzler 1171*303ae1cdSBernard Metzler atomic_dec(&sdev->num_mr); 1172*303ae1cdSBernard Metzler 1173*303ae1cdSBernard Metzler siw_mr_drop_mem(mr); 1174*303ae1cdSBernard Metzler kfree_rcu(mr, rcu); 1175*303ae1cdSBernard Metzler 1176*303ae1cdSBernard Metzler return 0; 1177*303ae1cdSBernard Metzler } 1178*303ae1cdSBernard Metzler 1179*303ae1cdSBernard Metzler /* 1180*303ae1cdSBernard Metzler * siw_reg_user_mr() 1181*303ae1cdSBernard Metzler * 1182*303ae1cdSBernard Metzler * Register Memory Region. 1183*303ae1cdSBernard Metzler * 1184*303ae1cdSBernard Metzler * @pd: Protection Domain 1185*303ae1cdSBernard Metzler * @start: starting address of MR (virtual address) 1186*303ae1cdSBernard Metzler * @len: len of MR 1187*303ae1cdSBernard Metzler * @rnic_va: not used by siw 1188*303ae1cdSBernard Metzler * @rights: MR access rights 1189*303ae1cdSBernard Metzler * @udata: user buffer to communicate STag and Key. 1190*303ae1cdSBernard Metzler */ 1191*303ae1cdSBernard Metzler struct ib_mr *siw_reg_user_mr(struct ib_pd *pd, u64 start, u64 len, 1192*303ae1cdSBernard Metzler u64 rnic_va, int rights, struct ib_udata *udata) 1193*303ae1cdSBernard Metzler { 1194*303ae1cdSBernard Metzler struct siw_mr *mr = NULL; 1195*303ae1cdSBernard Metzler struct siw_umem *umem = NULL; 1196*303ae1cdSBernard Metzler struct siw_ureq_reg_mr ureq; 1197*303ae1cdSBernard Metzler struct siw_device *sdev = to_siw_dev(pd->device); 1198*303ae1cdSBernard Metzler 1199*303ae1cdSBernard Metzler unsigned long mem_limit = rlimit(RLIMIT_MEMLOCK); 1200*303ae1cdSBernard Metzler int rv; 1201*303ae1cdSBernard Metzler 1202*303ae1cdSBernard Metzler siw_dbg_pd(pd, "start: 0x%016llx, va: 0x%016llx, len: %llu\n", 1203*303ae1cdSBernard Metzler (unsigned long long)start, (unsigned long long)rnic_va, 1204*303ae1cdSBernard Metzler (unsigned long long)len); 1205*303ae1cdSBernard Metzler 1206*303ae1cdSBernard Metzler if (atomic_inc_return(&sdev->num_mr) > SIW_MAX_MR) { 1207*303ae1cdSBernard Metzler siw_dbg_pd(pd, "too many mr's\n"); 1208*303ae1cdSBernard Metzler rv = -ENOMEM; 1209*303ae1cdSBernard Metzler goto err_out; 1210*303ae1cdSBernard Metzler } 1211*303ae1cdSBernard Metzler if (!len) { 1212*303ae1cdSBernard Metzler rv = -EINVAL; 1213*303ae1cdSBernard Metzler goto err_out; 1214*303ae1cdSBernard Metzler } 1215*303ae1cdSBernard Metzler if (mem_limit != RLIM_INFINITY) { 1216*303ae1cdSBernard Metzler unsigned long num_pages = 1217*303ae1cdSBernard Metzler (PAGE_ALIGN(len + (start & ~PAGE_MASK))) >> PAGE_SHIFT; 1218*303ae1cdSBernard Metzler mem_limit >>= PAGE_SHIFT; 1219*303ae1cdSBernard Metzler 1220*303ae1cdSBernard Metzler if (num_pages > mem_limit - current->mm->locked_vm) { 1221*303ae1cdSBernard Metzler siw_dbg_pd(pd, "pages req %lu, max %lu, lock %lu\n", 1222*303ae1cdSBernard Metzler num_pages, mem_limit, 1223*303ae1cdSBernard Metzler current->mm->locked_vm); 1224*303ae1cdSBernard Metzler rv = -ENOMEM; 1225*303ae1cdSBernard Metzler goto err_out; 1226*303ae1cdSBernard Metzler } 1227*303ae1cdSBernard Metzler } 1228*303ae1cdSBernard Metzler umem = siw_umem_get(start, len, ib_access_writable(rights)); 1229*303ae1cdSBernard Metzler if (IS_ERR(umem)) { 1230*303ae1cdSBernard Metzler rv = PTR_ERR(umem); 1231*303ae1cdSBernard Metzler siw_dbg_pd(pd, "getting user memory failed: %d\n", rv); 1232*303ae1cdSBernard Metzler umem = NULL; 1233*303ae1cdSBernard Metzler goto err_out; 1234*303ae1cdSBernard Metzler } 1235*303ae1cdSBernard Metzler mr = kzalloc(sizeof(*mr), GFP_KERNEL); 1236*303ae1cdSBernard Metzler if (!mr) { 1237*303ae1cdSBernard Metzler rv = -ENOMEM; 1238*303ae1cdSBernard Metzler goto err_out; 1239*303ae1cdSBernard Metzler } 1240*303ae1cdSBernard Metzler rv = siw_mr_add_mem(mr, pd, umem, start, len, rights); 1241*303ae1cdSBernard Metzler if (rv) 1242*303ae1cdSBernard Metzler goto err_out; 1243*303ae1cdSBernard Metzler 1244*303ae1cdSBernard Metzler if (udata) { 1245*303ae1cdSBernard Metzler struct siw_uresp_reg_mr uresp = {}; 1246*303ae1cdSBernard Metzler struct siw_mem *mem = mr->mem; 1247*303ae1cdSBernard Metzler 1248*303ae1cdSBernard Metzler if (udata->inlen < sizeof(ureq)) { 1249*303ae1cdSBernard Metzler rv = -EINVAL; 1250*303ae1cdSBernard Metzler goto err_out; 1251*303ae1cdSBernard Metzler } 1252*303ae1cdSBernard Metzler rv = ib_copy_from_udata(&ureq, udata, sizeof(ureq)); 1253*303ae1cdSBernard Metzler if (rv) 1254*303ae1cdSBernard Metzler goto err_out; 1255*303ae1cdSBernard Metzler 1256*303ae1cdSBernard Metzler mr->base_mr.lkey |= ureq.stag_key; 1257*303ae1cdSBernard Metzler mr->base_mr.rkey |= ureq.stag_key; 1258*303ae1cdSBernard Metzler mem->stag |= ureq.stag_key; 1259*303ae1cdSBernard Metzler uresp.stag = mem->stag; 1260*303ae1cdSBernard Metzler 1261*303ae1cdSBernard Metzler if (udata->outlen < sizeof(uresp)) { 1262*303ae1cdSBernard Metzler rv = -EINVAL; 1263*303ae1cdSBernard Metzler goto err_out; 1264*303ae1cdSBernard Metzler } 1265*303ae1cdSBernard Metzler rv = ib_copy_to_udata(udata, &uresp, sizeof(uresp)); 1266*303ae1cdSBernard Metzler if (rv) 1267*303ae1cdSBernard Metzler goto err_out; 1268*303ae1cdSBernard Metzler } 1269*303ae1cdSBernard Metzler mr->mem->stag_valid = 1; 1270*303ae1cdSBernard Metzler 1271*303ae1cdSBernard Metzler return &mr->base_mr; 1272*303ae1cdSBernard Metzler 1273*303ae1cdSBernard Metzler err_out: 1274*303ae1cdSBernard Metzler atomic_dec(&sdev->num_mr); 1275*303ae1cdSBernard Metzler if (mr) { 1276*303ae1cdSBernard Metzler if (mr->mem) 1277*303ae1cdSBernard Metzler siw_mr_drop_mem(mr); 1278*303ae1cdSBernard Metzler kfree_rcu(mr, rcu); 1279*303ae1cdSBernard Metzler } else { 1280*303ae1cdSBernard Metzler if (umem) 1281*303ae1cdSBernard Metzler siw_umem_release(umem, false); 1282*303ae1cdSBernard Metzler } 1283*303ae1cdSBernard Metzler return ERR_PTR(rv); 1284*303ae1cdSBernard Metzler } 1285*303ae1cdSBernard Metzler 1286*303ae1cdSBernard Metzler struct ib_mr *siw_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type, 1287*303ae1cdSBernard Metzler u32 max_sge, struct ib_udata *udata) 1288*303ae1cdSBernard Metzler { 1289*303ae1cdSBernard Metzler struct siw_device *sdev = to_siw_dev(pd->device); 1290*303ae1cdSBernard Metzler struct siw_mr *mr = NULL; 1291*303ae1cdSBernard Metzler struct siw_pbl *pbl = NULL; 1292*303ae1cdSBernard Metzler int rv; 1293*303ae1cdSBernard Metzler 1294*303ae1cdSBernard Metzler if (atomic_inc_return(&sdev->num_mr) > SIW_MAX_MR) { 1295*303ae1cdSBernard Metzler siw_dbg_pd(pd, "too many mr's\n"); 1296*303ae1cdSBernard Metzler rv = -ENOMEM; 1297*303ae1cdSBernard Metzler goto err_out; 1298*303ae1cdSBernard Metzler } 1299*303ae1cdSBernard Metzler if (mr_type != IB_MR_TYPE_MEM_REG) { 1300*303ae1cdSBernard Metzler siw_dbg_pd(pd, "mr type %d unsupported\n", mr_type); 1301*303ae1cdSBernard Metzler rv = -EOPNOTSUPP; 1302*303ae1cdSBernard Metzler goto err_out; 1303*303ae1cdSBernard Metzler } 1304*303ae1cdSBernard Metzler if (max_sge > SIW_MAX_SGE_PBL) { 1305*303ae1cdSBernard Metzler siw_dbg_pd(pd, "too many sge's: %d\n", max_sge); 1306*303ae1cdSBernard Metzler rv = -ENOMEM; 1307*303ae1cdSBernard Metzler goto err_out; 1308*303ae1cdSBernard Metzler } 1309*303ae1cdSBernard Metzler pbl = siw_pbl_alloc(max_sge); 1310*303ae1cdSBernard Metzler if (IS_ERR(pbl)) { 1311*303ae1cdSBernard Metzler rv = PTR_ERR(pbl); 1312*303ae1cdSBernard Metzler siw_dbg_pd(pd, "pbl allocation failed: %d\n", rv); 1313*303ae1cdSBernard Metzler pbl = NULL; 1314*303ae1cdSBernard Metzler goto err_out; 1315*303ae1cdSBernard Metzler } 1316*303ae1cdSBernard Metzler mr = kzalloc(sizeof(*mr), GFP_KERNEL); 1317*303ae1cdSBernard Metzler if (!mr) { 1318*303ae1cdSBernard Metzler rv = -ENOMEM; 1319*303ae1cdSBernard Metzler goto err_out; 1320*303ae1cdSBernard Metzler } 1321*303ae1cdSBernard Metzler rv = siw_mr_add_mem(mr, pd, pbl, 0, max_sge * PAGE_SIZE, 0); 1322*303ae1cdSBernard Metzler if (rv) 1323*303ae1cdSBernard Metzler goto err_out; 1324*303ae1cdSBernard Metzler 1325*303ae1cdSBernard Metzler mr->mem->is_pbl = 1; 1326*303ae1cdSBernard Metzler 1327*303ae1cdSBernard Metzler siw_dbg_pd(pd, "[MEM %u]: success\n", mr->mem->stag); 1328*303ae1cdSBernard Metzler 1329*303ae1cdSBernard Metzler return &mr->base_mr; 1330*303ae1cdSBernard Metzler 1331*303ae1cdSBernard Metzler err_out: 1332*303ae1cdSBernard Metzler atomic_dec(&sdev->num_mr); 1333*303ae1cdSBernard Metzler 1334*303ae1cdSBernard Metzler if (!mr) { 1335*303ae1cdSBernard Metzler kfree(pbl); 1336*303ae1cdSBernard Metzler } else { 1337*303ae1cdSBernard Metzler if (mr->mem) 1338*303ae1cdSBernard Metzler siw_mr_drop_mem(mr); 1339*303ae1cdSBernard Metzler kfree_rcu(mr, rcu); 1340*303ae1cdSBernard Metzler } 1341*303ae1cdSBernard Metzler siw_dbg_pd(pd, "failed: %d\n", rv); 1342*303ae1cdSBernard Metzler 1343*303ae1cdSBernard Metzler return ERR_PTR(rv); 1344*303ae1cdSBernard Metzler } 1345*303ae1cdSBernard Metzler 1346*303ae1cdSBernard Metzler /* Just used to count number of pages being mapped */ 1347*303ae1cdSBernard Metzler static int siw_set_pbl_page(struct ib_mr *base_mr, u64 buf_addr) 1348*303ae1cdSBernard Metzler { 1349*303ae1cdSBernard Metzler return 0; 1350*303ae1cdSBernard Metzler } 1351*303ae1cdSBernard Metzler 1352*303ae1cdSBernard Metzler int siw_map_mr_sg(struct ib_mr *base_mr, struct scatterlist *sl, int num_sle, 1353*303ae1cdSBernard Metzler unsigned int *sg_off) 1354*303ae1cdSBernard Metzler { 1355*303ae1cdSBernard Metzler struct scatterlist *slp; 1356*303ae1cdSBernard Metzler struct siw_mr *mr = to_siw_mr(base_mr); 1357*303ae1cdSBernard Metzler struct siw_mem *mem = mr->mem; 1358*303ae1cdSBernard Metzler struct siw_pbl *pbl = mem->pbl; 1359*303ae1cdSBernard Metzler struct siw_pble *pble; 1360*303ae1cdSBernard Metzler u64 pbl_size; 1361*303ae1cdSBernard Metzler int i, rv; 1362*303ae1cdSBernard Metzler 1363*303ae1cdSBernard Metzler if (!pbl) { 1364*303ae1cdSBernard Metzler siw_dbg_mem(mem, "no PBL allocated\n"); 1365*303ae1cdSBernard Metzler return -EINVAL; 1366*303ae1cdSBernard Metzler } 1367*303ae1cdSBernard Metzler pble = pbl->pbe; 1368*303ae1cdSBernard Metzler 1369*303ae1cdSBernard Metzler if (pbl->max_buf < num_sle) { 1370*303ae1cdSBernard Metzler siw_dbg_mem(mem, "too many SGE's: %d > %d\n", 1371*303ae1cdSBernard Metzler mem->pbl->max_buf, num_sle); 1372*303ae1cdSBernard Metzler return -ENOMEM; 1373*303ae1cdSBernard Metzler } 1374*303ae1cdSBernard Metzler for_each_sg(sl, slp, num_sle, i) { 1375*303ae1cdSBernard Metzler if (sg_dma_len(slp) == 0) { 1376*303ae1cdSBernard Metzler siw_dbg_mem(mem, "empty SGE\n"); 1377*303ae1cdSBernard Metzler return -EINVAL; 1378*303ae1cdSBernard Metzler } 1379*303ae1cdSBernard Metzler if (i == 0) { 1380*303ae1cdSBernard Metzler pble->addr = sg_dma_address(slp); 1381*303ae1cdSBernard Metzler pble->size = sg_dma_len(slp); 1382*303ae1cdSBernard Metzler pble->pbl_off = 0; 1383*303ae1cdSBernard Metzler pbl_size = pble->size; 1384*303ae1cdSBernard Metzler pbl->num_buf = 1; 1385*303ae1cdSBernard Metzler } else { 1386*303ae1cdSBernard Metzler /* Merge PBL entries if adjacent */ 1387*303ae1cdSBernard Metzler if (pble->addr + pble->size == sg_dma_address(slp)) { 1388*303ae1cdSBernard Metzler pble->size += sg_dma_len(slp); 1389*303ae1cdSBernard Metzler } else { 1390*303ae1cdSBernard Metzler pble++; 1391*303ae1cdSBernard Metzler pbl->num_buf++; 1392*303ae1cdSBernard Metzler pble->addr = sg_dma_address(slp); 1393*303ae1cdSBernard Metzler pble->size = sg_dma_len(slp); 1394*303ae1cdSBernard Metzler pble->pbl_off = pbl_size; 1395*303ae1cdSBernard Metzler } 1396*303ae1cdSBernard Metzler pbl_size += sg_dma_len(slp); 1397*303ae1cdSBernard Metzler } 1398*303ae1cdSBernard Metzler siw_dbg_mem(mem, 1399*303ae1cdSBernard Metzler "sge[%d], size %llu, addr 0x%016llx, total %llu\n", 1400*303ae1cdSBernard Metzler i, pble->size, pble->addr, pbl_size); 1401*303ae1cdSBernard Metzler } 1402*303ae1cdSBernard Metzler rv = ib_sg_to_pages(base_mr, sl, num_sle, sg_off, siw_set_pbl_page); 1403*303ae1cdSBernard Metzler if (rv > 0) { 1404*303ae1cdSBernard Metzler mem->len = base_mr->length; 1405*303ae1cdSBernard Metzler mem->va = base_mr->iova; 1406*303ae1cdSBernard Metzler siw_dbg_mem(mem, 1407*303ae1cdSBernard Metzler "%llu bytes, start 0x%016llx, %u SLE to %u entries\n", 1408*303ae1cdSBernard Metzler mem->len, mem->va, num_sle, pbl->num_buf); 1409*303ae1cdSBernard Metzler } 1410*303ae1cdSBernard Metzler return rv; 1411*303ae1cdSBernard Metzler } 1412*303ae1cdSBernard Metzler 1413*303ae1cdSBernard Metzler /* 1414*303ae1cdSBernard Metzler * siw_get_dma_mr() 1415*303ae1cdSBernard Metzler * 1416*303ae1cdSBernard Metzler * Create a (empty) DMA memory region, where no umem is attached. 1417*303ae1cdSBernard Metzler */ 1418*303ae1cdSBernard Metzler struct ib_mr *siw_get_dma_mr(struct ib_pd *pd, int rights) 1419*303ae1cdSBernard Metzler { 1420*303ae1cdSBernard Metzler struct siw_device *sdev = to_siw_dev(pd->device); 1421*303ae1cdSBernard Metzler struct siw_mr *mr = NULL; 1422*303ae1cdSBernard Metzler int rv; 1423*303ae1cdSBernard Metzler 1424*303ae1cdSBernard Metzler if (atomic_inc_return(&sdev->num_mr) > SIW_MAX_MR) { 1425*303ae1cdSBernard Metzler siw_dbg_pd(pd, "too many mr's\n"); 1426*303ae1cdSBernard Metzler rv = -ENOMEM; 1427*303ae1cdSBernard Metzler goto err_out; 1428*303ae1cdSBernard Metzler } 1429*303ae1cdSBernard Metzler mr = kzalloc(sizeof(*mr), GFP_KERNEL); 1430*303ae1cdSBernard Metzler if (!mr) { 1431*303ae1cdSBernard Metzler rv = -ENOMEM; 1432*303ae1cdSBernard Metzler goto err_out; 1433*303ae1cdSBernard Metzler } 1434*303ae1cdSBernard Metzler rv = siw_mr_add_mem(mr, pd, NULL, 0, ULONG_MAX, rights); 1435*303ae1cdSBernard Metzler if (rv) 1436*303ae1cdSBernard Metzler goto err_out; 1437*303ae1cdSBernard Metzler 1438*303ae1cdSBernard Metzler mr->mem->stag_valid = 1; 1439*303ae1cdSBernard Metzler 1440*303ae1cdSBernard Metzler siw_dbg_pd(pd, "[MEM %u]: success\n", mr->mem->stag); 1441*303ae1cdSBernard Metzler 1442*303ae1cdSBernard Metzler return &mr->base_mr; 1443*303ae1cdSBernard Metzler 1444*303ae1cdSBernard Metzler err_out: 1445*303ae1cdSBernard Metzler if (rv) 1446*303ae1cdSBernard Metzler kfree(mr); 1447*303ae1cdSBernard Metzler 1448*303ae1cdSBernard Metzler atomic_dec(&sdev->num_mr); 1449*303ae1cdSBernard Metzler 1450*303ae1cdSBernard Metzler return ERR_PTR(rv); 1451*303ae1cdSBernard Metzler } 1452*303ae1cdSBernard Metzler 1453*303ae1cdSBernard Metzler /* 1454*303ae1cdSBernard Metzler * siw_create_srq() 1455*303ae1cdSBernard Metzler * 1456*303ae1cdSBernard Metzler * Create Shared Receive Queue of attributes @init_attrs 1457*303ae1cdSBernard Metzler * within protection domain given by @pd. 1458*303ae1cdSBernard Metzler * 1459*303ae1cdSBernard Metzler * @base_srq: Base SRQ contained in siw SRQ. 1460*303ae1cdSBernard Metzler * @init_attrs: SRQ init attributes. 1461*303ae1cdSBernard Metzler * @udata: points to user context 1462*303ae1cdSBernard Metzler */ 1463*303ae1cdSBernard Metzler int siw_create_srq(struct ib_srq *base_srq, 1464*303ae1cdSBernard Metzler struct ib_srq_init_attr *init_attrs, struct ib_udata *udata) 1465*303ae1cdSBernard Metzler { 1466*303ae1cdSBernard Metzler struct siw_srq *srq = to_siw_srq(base_srq); 1467*303ae1cdSBernard Metzler struct ib_srq_attr *attrs = &init_attrs->attr; 1468*303ae1cdSBernard Metzler struct siw_device *sdev = to_siw_dev(base_srq->device); 1469*303ae1cdSBernard Metzler struct siw_ucontext *ctx = 1470*303ae1cdSBernard Metzler rdma_udata_to_drv_context(udata, struct siw_ucontext, 1471*303ae1cdSBernard Metzler base_ucontext); 1472*303ae1cdSBernard Metzler int rv; 1473*303ae1cdSBernard Metzler 1474*303ae1cdSBernard Metzler if (atomic_inc_return(&sdev->num_srq) > SIW_MAX_SRQ) { 1475*303ae1cdSBernard Metzler siw_dbg_pd(base_srq->pd, "too many SRQ's\n"); 1476*303ae1cdSBernard Metzler rv = -ENOMEM; 1477*303ae1cdSBernard Metzler goto err_out; 1478*303ae1cdSBernard Metzler } 1479*303ae1cdSBernard Metzler if (attrs->max_wr == 0 || attrs->max_wr > SIW_MAX_SRQ_WR || 1480*303ae1cdSBernard Metzler attrs->max_sge > SIW_MAX_SGE || attrs->srq_limit > attrs->max_wr) { 1481*303ae1cdSBernard Metzler rv = -EINVAL; 1482*303ae1cdSBernard Metzler goto err_out; 1483*303ae1cdSBernard Metzler } 1484*303ae1cdSBernard Metzler srq->max_sge = attrs->max_sge; 1485*303ae1cdSBernard Metzler srq->num_rqe = roundup_pow_of_two(attrs->max_wr); 1486*303ae1cdSBernard Metzler srq->xa_srq_index = SIW_INVAL_UOBJ_KEY; 1487*303ae1cdSBernard Metzler srq->limit = attrs->srq_limit; 1488*303ae1cdSBernard Metzler if (srq->limit) 1489*303ae1cdSBernard Metzler srq->armed = 1; 1490*303ae1cdSBernard Metzler 1491*303ae1cdSBernard Metzler srq->kernel_verbs = !udata; 1492*303ae1cdSBernard Metzler 1493*303ae1cdSBernard Metzler if (udata) 1494*303ae1cdSBernard Metzler srq->recvq = 1495*303ae1cdSBernard Metzler vmalloc_user(srq->num_rqe * sizeof(struct siw_rqe)); 1496*303ae1cdSBernard Metzler else 1497*303ae1cdSBernard Metzler srq->recvq = vzalloc(srq->num_rqe * sizeof(struct siw_rqe)); 1498*303ae1cdSBernard Metzler 1499*303ae1cdSBernard Metzler if (srq->recvq == NULL) { 1500*303ae1cdSBernard Metzler rv = -ENOMEM; 1501*303ae1cdSBernard Metzler goto err_out; 1502*303ae1cdSBernard Metzler } 1503*303ae1cdSBernard Metzler if (udata) { 1504*303ae1cdSBernard Metzler struct siw_uresp_create_srq uresp = {}; 1505*303ae1cdSBernard Metzler 1506*303ae1cdSBernard Metzler srq->xa_srq_index = siw_create_uobj( 1507*303ae1cdSBernard Metzler ctx, srq->recvq, srq->num_rqe * sizeof(struct siw_rqe)); 1508*303ae1cdSBernard Metzler 1509*303ae1cdSBernard Metzler if (srq->xa_srq_index == SIW_INVAL_UOBJ_KEY) { 1510*303ae1cdSBernard Metzler rv = -ENOMEM; 1511*303ae1cdSBernard Metzler goto err_out; 1512*303ae1cdSBernard Metzler } 1513*303ae1cdSBernard Metzler uresp.srq_key = srq->xa_srq_index; 1514*303ae1cdSBernard Metzler uresp.num_rqe = srq->num_rqe; 1515*303ae1cdSBernard Metzler 1516*303ae1cdSBernard Metzler if (udata->outlen < sizeof(uresp)) { 1517*303ae1cdSBernard Metzler rv = -EINVAL; 1518*303ae1cdSBernard Metzler goto err_out; 1519*303ae1cdSBernard Metzler } 1520*303ae1cdSBernard Metzler rv = ib_copy_to_udata(udata, &uresp, sizeof(uresp)); 1521*303ae1cdSBernard Metzler if (rv) 1522*303ae1cdSBernard Metzler goto err_out; 1523*303ae1cdSBernard Metzler } 1524*303ae1cdSBernard Metzler spin_lock_init(&srq->lock); 1525*303ae1cdSBernard Metzler 1526*303ae1cdSBernard Metzler siw_dbg_pd(base_srq->pd, "[SRQ 0x%p]: success\n", srq); 1527*303ae1cdSBernard Metzler 1528*303ae1cdSBernard Metzler return 0; 1529*303ae1cdSBernard Metzler 1530*303ae1cdSBernard Metzler err_out: 1531*303ae1cdSBernard Metzler if (srq->recvq) { 1532*303ae1cdSBernard Metzler if (ctx && srq->xa_srq_index != SIW_INVAL_UOBJ_KEY) 1533*303ae1cdSBernard Metzler kfree(xa_erase(&ctx->xa, srq->xa_srq_index)); 1534*303ae1cdSBernard Metzler vfree(srq->recvq); 1535*303ae1cdSBernard Metzler } 1536*303ae1cdSBernard Metzler atomic_dec(&sdev->num_srq); 1537*303ae1cdSBernard Metzler 1538*303ae1cdSBernard Metzler return rv; 1539*303ae1cdSBernard Metzler } 1540*303ae1cdSBernard Metzler 1541*303ae1cdSBernard Metzler /* 1542*303ae1cdSBernard Metzler * siw_modify_srq() 1543*303ae1cdSBernard Metzler * 1544*303ae1cdSBernard Metzler * Modify SRQ. The caller may resize SRQ and/or set/reset notification 1545*303ae1cdSBernard Metzler * limit and (re)arm IB_EVENT_SRQ_LIMIT_REACHED notification. 1546*303ae1cdSBernard Metzler * 1547*303ae1cdSBernard Metzler * NOTE: it is unclear if RDMA core allows for changing the MAX_SGE 1548*303ae1cdSBernard Metzler * parameter. siw_modify_srq() does not check the attrs->max_sge param. 1549*303ae1cdSBernard Metzler */ 1550*303ae1cdSBernard Metzler int siw_modify_srq(struct ib_srq *base_srq, struct ib_srq_attr *attrs, 1551*303ae1cdSBernard Metzler enum ib_srq_attr_mask attr_mask, struct ib_udata *udata) 1552*303ae1cdSBernard Metzler { 1553*303ae1cdSBernard Metzler struct siw_srq *srq = to_siw_srq(base_srq); 1554*303ae1cdSBernard Metzler unsigned long flags; 1555*303ae1cdSBernard Metzler int rv = 0; 1556*303ae1cdSBernard Metzler 1557*303ae1cdSBernard Metzler spin_lock_irqsave(&srq->lock, flags); 1558*303ae1cdSBernard Metzler 1559*303ae1cdSBernard Metzler if (attr_mask & IB_SRQ_MAX_WR) { 1560*303ae1cdSBernard Metzler /* resize request not yet supported */ 1561*303ae1cdSBernard Metzler rv = -EOPNOTSUPP; 1562*303ae1cdSBernard Metzler goto out; 1563*303ae1cdSBernard Metzler } 1564*303ae1cdSBernard Metzler if (attr_mask & IB_SRQ_LIMIT) { 1565*303ae1cdSBernard Metzler if (attrs->srq_limit) { 1566*303ae1cdSBernard Metzler if (unlikely(attrs->srq_limit > srq->num_rqe)) { 1567*303ae1cdSBernard Metzler rv = -EINVAL; 1568*303ae1cdSBernard Metzler goto out; 1569*303ae1cdSBernard Metzler } 1570*303ae1cdSBernard Metzler srq->armed = 1; 1571*303ae1cdSBernard Metzler } else { 1572*303ae1cdSBernard Metzler srq->armed = 0; 1573*303ae1cdSBernard Metzler } 1574*303ae1cdSBernard Metzler srq->limit = attrs->srq_limit; 1575*303ae1cdSBernard Metzler } 1576*303ae1cdSBernard Metzler out: 1577*303ae1cdSBernard Metzler spin_unlock_irqrestore(&srq->lock, flags); 1578*303ae1cdSBernard Metzler 1579*303ae1cdSBernard Metzler return rv; 1580*303ae1cdSBernard Metzler } 1581*303ae1cdSBernard Metzler 1582*303ae1cdSBernard Metzler /* 1583*303ae1cdSBernard Metzler * siw_query_srq() 1584*303ae1cdSBernard Metzler * 1585*303ae1cdSBernard Metzler * Query SRQ attributes. 1586*303ae1cdSBernard Metzler */ 1587*303ae1cdSBernard Metzler int siw_query_srq(struct ib_srq *base_srq, struct ib_srq_attr *attrs) 1588*303ae1cdSBernard Metzler { 1589*303ae1cdSBernard Metzler struct siw_srq *srq = to_siw_srq(base_srq); 1590*303ae1cdSBernard Metzler unsigned long flags; 1591*303ae1cdSBernard Metzler 1592*303ae1cdSBernard Metzler spin_lock_irqsave(&srq->lock, flags); 1593*303ae1cdSBernard Metzler 1594*303ae1cdSBernard Metzler attrs->max_wr = srq->num_rqe; 1595*303ae1cdSBernard Metzler attrs->max_sge = srq->max_sge; 1596*303ae1cdSBernard Metzler attrs->srq_limit = srq->limit; 1597*303ae1cdSBernard Metzler 1598*303ae1cdSBernard Metzler spin_unlock_irqrestore(&srq->lock, flags); 1599*303ae1cdSBernard Metzler 1600*303ae1cdSBernard Metzler return 0; 1601*303ae1cdSBernard Metzler } 1602*303ae1cdSBernard Metzler 1603*303ae1cdSBernard Metzler /* 1604*303ae1cdSBernard Metzler * siw_destroy_srq() 1605*303ae1cdSBernard Metzler * 1606*303ae1cdSBernard Metzler * Destroy SRQ. 1607*303ae1cdSBernard Metzler * It is assumed that the SRQ is not referenced by any 1608*303ae1cdSBernard Metzler * QP anymore - the code trusts the RDMA core environment to keep track 1609*303ae1cdSBernard Metzler * of QP references. 1610*303ae1cdSBernard Metzler */ 1611*303ae1cdSBernard Metzler void siw_destroy_srq(struct ib_srq *base_srq, struct ib_udata *udata) 1612*303ae1cdSBernard Metzler { 1613*303ae1cdSBernard Metzler struct siw_srq *srq = to_siw_srq(base_srq); 1614*303ae1cdSBernard Metzler struct siw_device *sdev = to_siw_dev(base_srq->device); 1615*303ae1cdSBernard Metzler struct siw_ucontext *ctx = 1616*303ae1cdSBernard Metzler rdma_udata_to_drv_context(udata, struct siw_ucontext, 1617*303ae1cdSBernard Metzler base_ucontext); 1618*303ae1cdSBernard Metzler 1619*303ae1cdSBernard Metzler if (ctx && srq->xa_srq_index != SIW_INVAL_UOBJ_KEY) 1620*303ae1cdSBernard Metzler kfree(xa_erase(&ctx->xa, srq->xa_srq_index)); 1621*303ae1cdSBernard Metzler 1622*303ae1cdSBernard Metzler vfree(srq->recvq); 1623*303ae1cdSBernard Metzler atomic_dec(&sdev->num_srq); 1624*303ae1cdSBernard Metzler } 1625*303ae1cdSBernard Metzler 1626*303ae1cdSBernard Metzler /* 1627*303ae1cdSBernard Metzler * siw_post_srq_recv() 1628*303ae1cdSBernard Metzler * 1629*303ae1cdSBernard Metzler * Post a list of receive queue elements to SRQ. 1630*303ae1cdSBernard Metzler * NOTE: The function does not check or lock a certain SRQ state 1631*303ae1cdSBernard Metzler * during the post operation. The code simply trusts the 1632*303ae1cdSBernard Metzler * RDMA core environment. 1633*303ae1cdSBernard Metzler * 1634*303ae1cdSBernard Metzler * @base_srq: Base SRQ contained in siw SRQ 1635*303ae1cdSBernard Metzler * @wr: List of R-WR's 1636*303ae1cdSBernard Metzler * @bad_wr: Updated to failing WR if posting fails. 1637*303ae1cdSBernard Metzler */ 1638*303ae1cdSBernard Metzler int siw_post_srq_recv(struct ib_srq *base_srq, const struct ib_recv_wr *wr, 1639*303ae1cdSBernard Metzler const struct ib_recv_wr **bad_wr) 1640*303ae1cdSBernard Metzler { 1641*303ae1cdSBernard Metzler struct siw_srq *srq = to_siw_srq(base_srq); 1642*303ae1cdSBernard Metzler unsigned long flags; 1643*303ae1cdSBernard Metzler int rv = 0; 1644*303ae1cdSBernard Metzler 1645*303ae1cdSBernard Metzler if (unlikely(!srq->kernel_verbs)) { 1646*303ae1cdSBernard Metzler siw_dbg_pd(base_srq->pd, 1647*303ae1cdSBernard Metzler "[SRQ 0x%p]: no kernel post_recv for mapped srq\n", 1648*303ae1cdSBernard Metzler srq); 1649*303ae1cdSBernard Metzler rv = -EINVAL; 1650*303ae1cdSBernard Metzler goto out; 1651*303ae1cdSBernard Metzler } 1652*303ae1cdSBernard Metzler /* 1653*303ae1cdSBernard Metzler * Serialize potentially multiple producers. 1654*303ae1cdSBernard Metzler * Also needed to serialize potentially multiple 1655*303ae1cdSBernard Metzler * consumers. 1656*303ae1cdSBernard Metzler */ 1657*303ae1cdSBernard Metzler spin_lock_irqsave(&srq->lock, flags); 1658*303ae1cdSBernard Metzler 1659*303ae1cdSBernard Metzler while (wr) { 1660*303ae1cdSBernard Metzler u32 idx = srq->rq_put % srq->num_rqe; 1661*303ae1cdSBernard Metzler struct siw_rqe *rqe = &srq->recvq[idx]; 1662*303ae1cdSBernard Metzler 1663*303ae1cdSBernard Metzler if (rqe->flags) { 1664*303ae1cdSBernard Metzler siw_dbg_pd(base_srq->pd, "SRQ full\n"); 1665*303ae1cdSBernard Metzler rv = -ENOMEM; 1666*303ae1cdSBernard Metzler break; 1667*303ae1cdSBernard Metzler } 1668*303ae1cdSBernard Metzler if (unlikely(wr->num_sge > srq->max_sge)) { 1669*303ae1cdSBernard Metzler siw_dbg_pd(base_srq->pd, 1670*303ae1cdSBernard Metzler "[SRQ 0x%p]: too many sge's: %d\n", srq, 1671*303ae1cdSBernard Metzler wr->num_sge); 1672*303ae1cdSBernard Metzler rv = -EINVAL; 1673*303ae1cdSBernard Metzler break; 1674*303ae1cdSBernard Metzler } 1675*303ae1cdSBernard Metzler rqe->id = wr->wr_id; 1676*303ae1cdSBernard Metzler rqe->num_sge = wr->num_sge; 1677*303ae1cdSBernard Metzler siw_copy_sgl(wr->sg_list, rqe->sge, wr->num_sge); 1678*303ae1cdSBernard Metzler 1679*303ae1cdSBernard Metzler /* Make sure S-RQE is completely written before valid */ 1680*303ae1cdSBernard Metzler smp_wmb(); 1681*303ae1cdSBernard Metzler 1682*303ae1cdSBernard Metzler rqe->flags = SIW_WQE_VALID; 1683*303ae1cdSBernard Metzler 1684*303ae1cdSBernard Metzler srq->rq_put++; 1685*303ae1cdSBernard Metzler wr = wr->next; 1686*303ae1cdSBernard Metzler } 1687*303ae1cdSBernard Metzler spin_unlock_irqrestore(&srq->lock, flags); 1688*303ae1cdSBernard Metzler out: 1689*303ae1cdSBernard Metzler if (unlikely(rv < 0)) { 1690*303ae1cdSBernard Metzler siw_dbg_pd(base_srq->pd, "[SRQ 0x%p]: error %d\n", srq, rv); 1691*303ae1cdSBernard Metzler *bad_wr = wr; 1692*303ae1cdSBernard Metzler } 1693*303ae1cdSBernard Metzler return rv; 1694*303ae1cdSBernard Metzler } 1695*303ae1cdSBernard Metzler 1696*303ae1cdSBernard Metzler void siw_qp_event(struct siw_qp *qp, enum ib_event_type etype) 1697*303ae1cdSBernard Metzler { 1698*303ae1cdSBernard Metzler struct ib_event event; 1699*303ae1cdSBernard Metzler struct ib_qp *base_qp = qp->ib_qp; 1700*303ae1cdSBernard Metzler 1701*303ae1cdSBernard Metzler /* 1702*303ae1cdSBernard Metzler * Do not report asynchronous errors on QP which gets 1703*303ae1cdSBernard Metzler * destroyed via verbs interface (siw_destroy_qp()) 1704*303ae1cdSBernard Metzler */ 1705*303ae1cdSBernard Metzler if (qp->attrs.flags & SIW_QP_IN_DESTROY) 1706*303ae1cdSBernard Metzler return; 1707*303ae1cdSBernard Metzler 1708*303ae1cdSBernard Metzler event.event = etype; 1709*303ae1cdSBernard Metzler event.device = base_qp->device; 1710*303ae1cdSBernard Metzler event.element.qp = base_qp; 1711*303ae1cdSBernard Metzler 1712*303ae1cdSBernard Metzler if (base_qp->event_handler) { 1713*303ae1cdSBernard Metzler siw_dbg_qp(qp, "reporting event %d\n", etype); 1714*303ae1cdSBernard Metzler base_qp->event_handler(&event, base_qp->qp_context); 1715*303ae1cdSBernard Metzler } 1716*303ae1cdSBernard Metzler } 1717*303ae1cdSBernard Metzler 1718*303ae1cdSBernard Metzler void siw_cq_event(struct siw_cq *cq, enum ib_event_type etype) 1719*303ae1cdSBernard Metzler { 1720*303ae1cdSBernard Metzler struct ib_event event; 1721*303ae1cdSBernard Metzler struct ib_cq *base_cq = &cq->base_cq; 1722*303ae1cdSBernard Metzler 1723*303ae1cdSBernard Metzler event.event = etype; 1724*303ae1cdSBernard Metzler event.device = base_cq->device; 1725*303ae1cdSBernard Metzler event.element.cq = base_cq; 1726*303ae1cdSBernard Metzler 1727*303ae1cdSBernard Metzler if (base_cq->event_handler) { 1728*303ae1cdSBernard Metzler siw_dbg_cq(cq, "reporting CQ event %d\n", etype); 1729*303ae1cdSBernard Metzler base_cq->event_handler(&event, base_cq->cq_context); 1730*303ae1cdSBernard Metzler } 1731*303ae1cdSBernard Metzler } 1732*303ae1cdSBernard Metzler 1733*303ae1cdSBernard Metzler void siw_srq_event(struct siw_srq *srq, enum ib_event_type etype) 1734*303ae1cdSBernard Metzler { 1735*303ae1cdSBernard Metzler struct ib_event event; 1736*303ae1cdSBernard Metzler struct ib_srq *base_srq = &srq->base_srq; 1737*303ae1cdSBernard Metzler 1738*303ae1cdSBernard Metzler event.event = etype; 1739*303ae1cdSBernard Metzler event.device = base_srq->device; 1740*303ae1cdSBernard Metzler event.element.srq = base_srq; 1741*303ae1cdSBernard Metzler 1742*303ae1cdSBernard Metzler if (base_srq->event_handler) { 1743*303ae1cdSBernard Metzler siw_dbg_pd(srq->base_srq.pd, 1744*303ae1cdSBernard Metzler "reporting SRQ event %d\n", etype); 1745*303ae1cdSBernard Metzler base_srq->event_handler(&event, base_srq->srq_context); 1746*303ae1cdSBernard Metzler } 1747*303ae1cdSBernard Metzler } 1748*303ae1cdSBernard Metzler 1749*303ae1cdSBernard Metzler void siw_port_event(struct siw_device *sdev, u8 port, enum ib_event_type etype) 1750*303ae1cdSBernard Metzler { 1751*303ae1cdSBernard Metzler struct ib_event event; 1752*303ae1cdSBernard Metzler 1753*303ae1cdSBernard Metzler event.event = etype; 1754*303ae1cdSBernard Metzler event.device = &sdev->base_dev; 1755*303ae1cdSBernard Metzler event.element.port_num = port; 1756*303ae1cdSBernard Metzler 1757*303ae1cdSBernard Metzler siw_dbg(&sdev->base_dev, "reporting port event %d\n", etype); 1758*303ae1cdSBernard Metzler 1759*303ae1cdSBernard Metzler ib_dispatch_event(&event); 1760*303ae1cdSBernard Metzler } 1761