Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/qlnx/qlnxr/qlnxr_verbs.c
Show First 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | |||||
#define NIPQUAD(addr) \ | #define NIPQUAD(addr) \ | ||||
((unsigned char *)&addr)[0], \ | ((unsigned char *)&addr)[0], \ | ||||
((unsigned char *)&addr)[1], \ | ((unsigned char *)&addr)[1], \ | ||||
((unsigned char *)&addr)[2], \ | ((unsigned char *)&addr)[2], \ | ||||
((unsigned char *)&addr)[3] | ((unsigned char *)&addr)[3] | ||||
static int | static int | ||||
qlnxr_check_srq_params(struct ib_pd *ibpd, | qlnxr_check_srq_params(struct qlnxr_dev *dev, | ||||
struct qlnxr_dev *dev, | |||||
struct ib_srq_init_attr *attrs); | struct ib_srq_init_attr *attrs); | ||||
static int | static int | ||||
qlnxr_init_srq_user_params(struct ib_ucontext *ib_ctx, | qlnxr_init_srq_user_params(struct ib_ucontext *ib_ctx, | ||||
struct qlnxr_srq *srq, | struct qlnxr_srq *srq, | ||||
struct qlnxr_create_srq_ureq *ureq, | struct qlnxr_create_srq_ureq *ureq, | ||||
int access, int dmasync); | int access, int dmasync); | ||||
▲ Show 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | #endif | ||||
} | } | ||||
memcpy(sgid, &dev->sgid_tbl[index], sizeof(*sgid)); | memcpy(sgid, &dev->sgid_tbl[index], sizeof(*sgid)); | ||||
QL_DPRINT12(ha, "exit : %p\n", sgid); | QL_DPRINT12(ha, "exit : %p\n", sgid); | ||||
return 0; | return 0; | ||||
} | } | ||||
struct ib_srq * | int | ||||
qlnxr_create_srq(struct ib_pd *ibpd, struct ib_srq_init_attr *init_attr, | qlnxr_create_srq(struct ib_srq *ibsrq, | ||||
struct ib_srq_init_attr *init_attr, | |||||
struct ib_udata *udata) | struct ib_udata *udata) | ||||
{ | { | ||||
struct qlnxr_dev *dev; | struct qlnxr_dev *dev; | ||||
qlnx_host_t *ha; | qlnx_host_t *ha; | ||||
struct ecore_rdma_destroy_srq_in_params destroy_in_params; | struct ecore_rdma_destroy_srq_in_params destroy_in_params; | ||||
struct ecore_rdma_create_srq_out_params out_params; | struct ecore_rdma_create_srq_out_params out_params; | ||||
struct ecore_rdma_create_srq_in_params in_params; | struct ecore_rdma_create_srq_in_params in_params; | ||||
u64 pbl_base_addr, phy_prod_pair_addr; | u64 pbl_base_addr, phy_prod_pair_addr; | ||||
struct qlnxr_pd *pd = get_qlnxr_pd(ibpd); | |||||
struct ib_ucontext *ib_ctx = NULL; | |||||
struct qlnxr_srq_hwq_info *hw_srq; | struct qlnxr_srq_hwq_info *hw_srq; | ||||
struct qlnxr_ucontext *ctx = NULL; | struct qlnxr_ucontext *ctx; | ||||
struct qlnxr_create_srq_ureq ureq; | struct qlnxr_create_srq_ureq ureq; | ||||
u32 page_cnt, page_size; | u32 page_cnt, page_size; | ||||
struct qlnxr_srq *srq; | struct qlnxr_srq *srq = get_qlnxr_srq(ibsrq); | ||||
int ret = 0; | int ret = 0; | ||||
dev = get_qlnxr_dev((ibpd->device)); | dev = get_qlnxr_dev(ibsrq->device); | ||||
ha = dev->ha; | ha = dev->ha; | ||||
QL_DPRINT12(ha, "enter\n"); | QL_DPRINT12(ha, "enter\n"); | ||||
ret = qlnxr_check_srq_params(ibpd, dev, init_attr); | ret = qlnxr_check_srq_params(dev, init_attr); | ||||
srq = kzalloc(sizeof(*srq), GFP_KERNEL); | |||||
if (!srq) { | |||||
QL_DPRINT11(ha, "cannot allocate memory for srq\n"); | |||||
return NULL; //@@@ : TODO what to return here? | |||||
} | |||||
srq->dev = dev; | srq->dev = dev; | ||||
hw_srq = &srq->hw_srq; | hw_srq = &srq->hw_srq; | ||||
spin_lock_init(&srq->lock); | spin_lock_init(&srq->lock); | ||||
memset(&in_params, 0, sizeof(in_params)); | memset(&in_params, 0, sizeof(in_params)); | ||||
if (udata && ibpd->uobject && ibpd->uobject->context) { | if (udata) { | ||||
ib_ctx = ibpd->uobject->context; | ctx = rdma_udata_to_drv_context( | ||||
ctx = get_qlnxr_ucontext(ib_ctx); | udata, struct qlnxr_ucontext, ibucontext); | ||||
memset(&ureq, 0, sizeof(ureq)); | memset(&ureq, 0, sizeof(ureq)); | ||||
if (ib_copy_from_udata(&ureq, udata, min(sizeof(ureq), | if (ib_copy_from_udata(&ureq, udata, min(sizeof(ureq), | ||||
udata->inlen))) { | udata->inlen))) { | ||||
QL_DPRINT11(ha, "problem" | QL_DPRINT11(ha, "problem" | ||||
" copying data from user space\n"); | " copying data from user space\n"); | ||||
goto err0; | goto err0; | ||||
} | } | ||||
ret = qlnxr_init_srq_user_params(ib_ctx, srq, &ureq, 0, 0); | ret = qlnxr_init_srq_user_params(&ctx->ibucontext, srq, &ureq, 0, 0); | ||||
if (ret) | if (ret) | ||||
goto err0; | goto err0; | ||||
page_cnt = srq->usrq.pbl_info.num_pbes; | page_cnt = srq->usrq.pbl_info.num_pbes; | ||||
pbl_base_addr = srq->usrq.pbl_tbl->pa; | pbl_base_addr = srq->usrq.pbl_tbl->pa; | ||||
phy_prod_pair_addr = hw_srq->phy_prod_pair_addr; | phy_prod_pair_addr = hw_srq->phy_prod_pair_addr; | ||||
// @@@ : if DEFINE_IB_UMEM_PAGE_SHIFT | // @@@ : if DEFINE_IB_UMEM_PAGE_SHIFT | ||||
// page_size = BIT(srq->usrq.umem->page_shift); | // page_size = BIT(srq->usrq.umem->page_shift); | ||||
// else | // else | ||||
page_size = srq->usrq.umem->page_size; | page_size = srq->usrq.umem->page_size; | ||||
} else { | } else { | ||||
struct ecore_chain *pbl; | struct ecore_chain *pbl; | ||||
ret = qlnxr_alloc_srq_kernel_params(srq, dev, init_attr); | ret = qlnxr_alloc_srq_kernel_params(srq, dev, init_attr); | ||||
if (ret) | if (ret) | ||||
goto err0; | goto err0; | ||||
pbl = &hw_srq->pbl; | pbl = &hw_srq->pbl; | ||||
page_cnt = ecore_chain_get_page_cnt(pbl); | page_cnt = ecore_chain_get_page_cnt(pbl); | ||||
pbl_base_addr = ecore_chain_get_pbl_phys(pbl); | pbl_base_addr = ecore_chain_get_pbl_phys(pbl); | ||||
phy_prod_pair_addr = hw_srq->phy_prod_pair_addr; | phy_prod_pair_addr = hw_srq->phy_prod_pair_addr; | ||||
page_size = pbl->elem_per_page << 4; | page_size = pbl->elem_per_page << 4; | ||||
} | } | ||||
in_params.pd_id = pd->pd_id; | in_params.pd_id = get_qlnxr_pd(ibsrq->pd)->pd_id; | ||||
in_params.pbl_base_addr = pbl_base_addr; | in_params.pbl_base_addr = pbl_base_addr; | ||||
in_params.prod_pair_addr = phy_prod_pair_addr; | in_params.prod_pair_addr = phy_prod_pair_addr; | ||||
in_params.num_pages = page_cnt; | in_params.num_pages = page_cnt; | ||||
in_params.page_size = page_size; | in_params.page_size = page_size; | ||||
ret = ecore_rdma_create_srq(dev->rdma_ctx, &in_params, &out_params); | ret = ecore_rdma_create_srq(dev->rdma_ctx, &in_params, &out_params); | ||||
if (ret) | if (ret) | ||||
goto err1; | goto err1; | ||||
srq->srq_id = out_params.srq_id; | srq->srq_id = out_params.srq_id; | ||||
if (udata) { | if (udata) { | ||||
ret = qlnxr_copy_srq_uresp(dev, srq, udata); | ret = qlnxr_copy_srq_uresp(dev, srq, udata); | ||||
if (ret) | if (ret) | ||||
goto err2; | goto err2; | ||||
} | } | ||||
QL_DPRINT12(ha, "created srq with srq_id = 0x%0x\n", srq->srq_id); | QL_DPRINT12(ha, "created srq with srq_id = 0x%0x\n", srq->srq_id); | ||||
return &srq->ibsrq; | return (0); | ||||
err2: | err2: | ||||
memset(&in_params, 0, sizeof(in_params)); | memset(&in_params, 0, sizeof(in_params)); | ||||
destroy_in_params.srq_id = srq->srq_id; | destroy_in_params.srq_id = srq->srq_id; | ||||
ecore_rdma_destroy_srq(dev->rdma_ctx, &destroy_in_params); | ecore_rdma_destroy_srq(dev->rdma_ctx, &destroy_in_params); | ||||
err1: | err1: | ||||
if (udata) | if (udata) | ||||
qlnxr_free_srq_user_params(srq); | qlnxr_free_srq_user_params(srq); | ||||
else | else | ||||
qlnxr_free_srq_kernel_params(srq); | qlnxr_free_srq_kernel_params(srq); | ||||
err0: | err0: | ||||
kfree(srq); | return (-EFAULT); | ||||
return ERR_PTR(-EFAULT); | |||||
} | } | ||||
int | void | ||||
qlnxr_destroy_srq(struct ib_srq *ibsrq) | qlnxr_destroy_srq(struct ib_srq *ibsrq, struct ib_udata *udata) | ||||
{ | { | ||||
struct qlnxr_dev *dev; | struct qlnxr_dev *dev; | ||||
struct qlnxr_srq *srq; | struct qlnxr_srq *srq; | ||||
qlnx_host_t *ha; | qlnx_host_t *ha; | ||||
struct ecore_rdma_destroy_srq_in_params in_params; | struct ecore_rdma_destroy_srq_in_params in_params; | ||||
srq = get_qlnxr_srq(ibsrq); | srq = get_qlnxr_srq(ibsrq); | ||||
dev = srq->dev; | dev = srq->dev; | ||||
ha = dev->ha; | ha = dev->ha; | ||||
memset(&in_params, 0, sizeof(in_params)); | memset(&in_params, 0, sizeof(in_params)); | ||||
in_params.srq_id = srq->srq_id; | in_params.srq_id = srq->srq_id; | ||||
ecore_rdma_destroy_srq(dev->rdma_ctx, &in_params); | ecore_rdma_destroy_srq(dev->rdma_ctx, &in_params); | ||||
if (ibsrq->pd->uobject && ibsrq->pd->uobject->context) | if (ibsrq->pd->uobject && ibsrq->pd->uobject->context) | ||||
qlnxr_free_srq_user_params(srq); | qlnxr_free_srq_user_params(srq); | ||||
else | else | ||||
qlnxr_free_srq_kernel_params(srq); | qlnxr_free_srq_kernel_params(srq); | ||||
QL_DPRINT12(ha, "destroyed srq_id=0x%0x\n", srq->srq_id); | QL_DPRINT12(ha, "destroyed srq_id=0x%0x\n", srq->srq_id); | ||||
kfree(srq); | |||||
return 0; | |||||
} | } | ||||
int | int | ||||
qlnxr_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, | qlnxr_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, | ||||
enum ib_srq_attr_mask attr_mask, struct ib_udata *udata) | enum ib_srq_attr_mask attr_mask, struct ib_udata *udata) | ||||
{ | { | ||||
struct qlnxr_dev *dev; | struct qlnxr_dev *dev; | ||||
struct qlnxr_srq *srq; | struct qlnxr_srq *srq; | ||||
▲ Show 20 Lines • Show All 409 Lines • ▼ Show 20 Lines | qlnxr_link_layer(struct ib_device *ibdev, uint8_t port_num) | ||||
dev = get_qlnxr_dev(ibdev); | dev = get_qlnxr_dev(ibdev); | ||||
ha = dev->ha; | ha = dev->ha; | ||||
QL_DPRINT12(ha, "ibdev = %p port_num = 0x%x\n", ibdev, port_num); | QL_DPRINT12(ha, "ibdev = %p port_num = 0x%x\n", ibdev, port_num); | ||||
return IB_LINK_LAYER_ETHERNET; | return IB_LINK_LAYER_ETHERNET; | ||||
} | } | ||||
struct ib_pd * | int | ||||
qlnxr_alloc_pd(struct ib_device *ibdev, struct ib_ucontext *context, | qlnxr_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata) | ||||
struct ib_udata *udata) | |||||
{ | { | ||||
struct qlnxr_pd *pd = NULL; | struct ib_device *ibdev = ibpd->device; | ||||
struct qlnxr_pd *pd = get_qlnxr_pd(ibpd); | |||||
u16 pd_id; | u16 pd_id; | ||||
int rc; | int rc; | ||||
struct qlnxr_dev *dev; | struct qlnxr_dev *dev; | ||||
qlnx_host_t *ha; | qlnx_host_t *ha; | ||||
dev = get_qlnxr_dev(ibdev); | dev = get_qlnxr_dev(ibdev); | ||||
ha = dev->ha; | ha = dev->ha; | ||||
QL_DPRINT12(ha, "ibdev = %p context = %p" | QL_DPRINT12(ha, "ibdev = %p udata = %p enter\n", ibdev, udata); | ||||
" udata = %p enter\n", ibdev, context, udata); | |||||
if (dev->rdma_ctx == NULL) { | if (dev->rdma_ctx == NULL) { | ||||
QL_DPRINT11(ha, "dev->rdma_ctx = NULL\n"); | QL_DPRINT11(ha, "dev->rdma_ctx = NULL\n"); | ||||
rc = -1; | rc = -1; | ||||
goto err; | goto err; | ||||
} | } | ||||
pd = kzalloc(sizeof(*pd), GFP_KERNEL); | |||||
if (!pd) { | |||||
rc = -ENOMEM; | |||||
QL_DPRINT11(ha, "kzalloc(pd) = NULL\n"); | |||||
goto err; | |||||
} | |||||
rc = ecore_rdma_alloc_pd(dev->rdma_ctx, &pd_id); | rc = ecore_rdma_alloc_pd(dev->rdma_ctx, &pd_id); | ||||
if (rc) { | if (rc) { | ||||
QL_DPRINT11(ha, "ecore_rdma_alloc_pd failed\n"); | QL_DPRINT11(ha, "ecore_rdma_alloc_pd failed\n"); | ||||
goto err; | goto err; | ||||
} | } | ||||
pd->pd_id = pd_id; | pd->pd_id = pd_id; | ||||
if (udata && context) { | if (udata) { | ||||
rc = ib_copy_to_udata(udata, &pd->pd_id, sizeof(pd->pd_id)); | rc = ib_copy_to_udata(udata, &pd->pd_id, sizeof(pd->pd_id)); | ||||
if (rc) { | if (rc) { | ||||
QL_DPRINT11(ha, "ib_copy_to_udata failed\n"); | QL_DPRINT11(ha, "ib_copy_to_udata failed\n"); | ||||
ecore_rdma_free_pd(dev->rdma_ctx, pd_id); | ecore_rdma_free_pd(dev->rdma_ctx, pd_id); | ||||
goto err; | goto err; | ||||
} | } | ||||
pd->uctx = get_qlnxr_ucontext(context); | pd->uctx = rdma_udata_to_drv_context( | ||||
udata, struct qlnxr_ucontext, ibucontext); | |||||
pd->uctx->pd = pd; | pd->uctx->pd = pd; | ||||
} | } | ||||
atomic_add_rel_32(&dev->pd_count, 1); | atomic_add_rel_32(&dev->pd_count, 1); | ||||
QL_DPRINT12(ha, "exit [pd, pd_id, pd_count] = [%p, 0x%x, %d]\n", | QL_DPRINT12(ha, "exit [pd, pd_id, pd_count] = [%p, 0x%x, %d]\n", | ||||
pd, pd_id, dev->pd_count); | pd, pd_id, dev->pd_count); | ||||
return &pd->ibpd; | return (0); | ||||
err: | err: | ||||
kfree(pd); | |||||
QL_DPRINT12(ha, "exit -1\n"); | QL_DPRINT12(ha, "exit -1\n"); | ||||
return ERR_PTR(rc); | return (rc); | ||||
} | } | ||||
int | void | ||||
qlnxr_dealloc_pd(struct ib_pd *ibpd) | qlnxr_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata) | ||||
{ | { | ||||
struct qlnxr_pd *pd; | struct qlnxr_pd *pd; | ||||
struct qlnxr_dev *dev; | struct qlnxr_dev *dev; | ||||
qlnx_host_t *ha; | qlnx_host_t *ha; | ||||
pd = get_qlnxr_pd(ibpd); | pd = get_qlnxr_pd(ibpd); | ||||
dev = get_qlnxr_dev((ibpd->device)); | dev = get_qlnxr_dev((ibpd->device)); | ||||
ha = dev->ha; | ha = dev->ha; | ||||
QL_DPRINT12(ha, "enter\n"); | QL_DPRINT12(ha, "enter\n"); | ||||
if (pd == NULL) { | if (pd == NULL) { | ||||
QL_DPRINT11(ha, "pd = NULL\n"); | QL_DPRINT11(ha, "pd = NULL\n"); | ||||
} else { | } else { | ||||
ecore_rdma_free_pd(dev->rdma_ctx, pd->pd_id); | ecore_rdma_free_pd(dev->rdma_ctx, pd->pd_id); | ||||
kfree(pd); | |||||
atomic_subtract_rel_32(&dev->pd_count, 1); | atomic_subtract_rel_32(&dev->pd_count, 1); | ||||
QL_DPRINT12(ha, "exit [pd, pd_id, pd_count] = [%p, 0x%x, %d]\n", | QL_DPRINT12(ha, "exit [pd, pd_id, pd_count] = [%p, 0x%x, %d]\n", | ||||
pd, pd->pd_id, dev->pd_count); | pd, pd->pd_id, dev->pd_count); | ||||
} | } | ||||
QL_DPRINT12(ha, "exit\n"); | QL_DPRINT12(ha, "exit\n"); | ||||
return 0; | |||||
} | } | ||||
#define ROCE_WQE_ELEM_SIZE sizeof(struct rdma_sq_sge) | #define ROCE_WQE_ELEM_SIZE sizeof(struct rdma_sq_sge) | ||||
#define RDMA_MAX_SGE_PER_SRQ (4) /* Should be part of HSI */ | #define RDMA_MAX_SGE_PER_SRQ (4) /* Should be part of HSI */ | ||||
/* Should be part of HSI */ | /* Should be part of HSI */ | ||||
#define RDMA_MAX_SRQ_WQE_SIZE (RDMA_MAX_SGE_PER_SRQ + 1) /* +1 for header */ | #define RDMA_MAX_SRQ_WQE_SIZE (RDMA_MAX_SGE_PER_SRQ + 1) /* +1 for header */ | ||||
#define DB_ADDR_SHIFT(addr) ((addr) << DB_PWM_ADDR_OFFSET_SHIFT) | #define DB_ADDR_SHIFT(addr) ((addr) << DB_PWM_ADDR_OFFSET_SHIFT) | ||||
▲ Show 20 Lines • Show All 157 Lines • ▼ Show 20 Lines | qlnxr_search_mmap(struct qlnxr_ucontext *uctx, u64 phy_addr, unsigned long len) | ||||
QL_DPRINT12(ha, | QL_DPRINT12(ha, | ||||
"searched for (addr=0x%llx,len=0x%lx) for ctx=%p, found=%d\n", | "searched for (addr=0x%llx,len=0x%lx) for ctx=%p, found=%d\n", | ||||
mm->key.phy_addr, mm->key.len, uctx, found); | mm->key.phy_addr, mm->key.len, uctx, found); | ||||
return found; | return found; | ||||
} | } | ||||
struct | int | ||||
ib_ucontext *qlnxr_alloc_ucontext(struct ib_device *ibdev, | qlnxr_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata) | ||||
struct ib_udata *udata) | |||||
{ | { | ||||
int rc; | int rc; | ||||
struct qlnxr_ucontext *ctx; | struct qlnxr_ucontext *ctx = get_qlnxr_ucontext(uctx); | ||||
struct qlnxr_alloc_ucontext_resp uresp; | struct qlnxr_alloc_ucontext_resp uresp; | ||||
struct qlnxr_dev *dev = get_qlnxr_dev(ibdev); | struct qlnxr_dev *dev = get_qlnxr_dev(uctx->device); | ||||
qlnx_host_t *ha = dev->ha; | qlnx_host_t *ha = dev->ha; | ||||
struct ecore_rdma_add_user_out_params oparams; | struct ecore_rdma_add_user_out_params oparams; | ||||
if (!udata) { | if (!udata) | ||||
return ERR_PTR(-EFAULT); | return -EFAULT; | ||||
} | |||||
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | |||||
if (!ctx) | |||||
return ERR_PTR(-ENOMEM); | |||||
rc = ecore_rdma_add_user(dev->rdma_ctx, &oparams); | rc = ecore_rdma_add_user(dev->rdma_ctx, &oparams); | ||||
if (rc) { | if (rc) { | ||||
QL_DPRINT12(ha, | QL_DPRINT12(ha, | ||||
"Failed to allocate a DPI for a new RoCE application " | "Failed to allocate a DPI for a new RoCE application " | ||||
",rc = %d. To overcome this, consider to increase " | ",rc = %d. To overcome this, consider to increase " | ||||
"the number of DPIs, increase the doorbell BAR size " | "the number of DPIs, increase the doorbell BAR size " | ||||
"or just close unnecessary RoCE applications. In " | "or just close unnecessary RoCE applications. In " | ||||
"order to increase the number of DPIs consult the " | "order to increase the number of DPIs consult the " | ||||
Show All 32 Lines | qlnxr_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata) | ||||
ctx->dev = dev; | ctx->dev = dev; | ||||
rc = qlnxr_add_mmap(ctx, ctx->dpi_phys_addr, ctx->dpi_size); | rc = qlnxr_add_mmap(ctx, ctx->dpi_phys_addr, ctx->dpi_size); | ||||
if (rc) | if (rc) | ||||
goto err; | goto err; | ||||
QL_DPRINT12(ha, "Allocated user context %p\n", | QL_DPRINT12(ha, "Allocated user context %p\n", | ||||
&ctx->ibucontext); | &ctx->ibucontext); | ||||
return &ctx->ibucontext; | return (0); | ||||
err: | err: | ||||
kfree(ctx); | return (rc); | ||||
return ERR_PTR(rc); | |||||
} | } | ||||
int | void | ||||
qlnxr_dealloc_ucontext(struct ib_ucontext *ibctx) | qlnxr_dealloc_ucontext(struct ib_ucontext *ibctx) | ||||
{ | { | ||||
struct qlnxr_ucontext *uctx = get_qlnxr_ucontext(ibctx); | struct qlnxr_ucontext *uctx = get_qlnxr_ucontext(ibctx); | ||||
struct qlnxr_dev *dev = uctx->dev; | struct qlnxr_dev *dev = uctx->dev; | ||||
qlnx_host_t *ha = dev->ha; | qlnx_host_t *ha = dev->ha; | ||||
struct qlnxr_mm *mm, *tmp; | struct qlnxr_mm *mm, *tmp; | ||||
int status = 0; | |||||
QL_DPRINT12(ha, "Deallocating user context %p\n", | QL_DPRINT12(ha, "Deallocating user context %p\n", | ||||
uctx); | uctx); | ||||
if (dev) { | if (dev) { | ||||
ecore_rdma_remove_user(uctx->dev->rdma_ctx, uctx->dpi); | ecore_rdma_remove_user(uctx->dev->rdma_ctx, uctx->dpi); | ||||
} | } | ||||
list_for_each_entry_safe(mm, tmp, &uctx->mm_head, entry) { | list_for_each_entry_safe(mm, tmp, &uctx->mm_head, entry) { | ||||
QL_DPRINT12(ha, "deleted addr= 0x%llx, len = 0x%lx for" | QL_DPRINT12(ha, "deleted addr= 0x%llx, len = 0x%lx for" | ||||
" ctx=%p\n", | " ctx=%p\n", | ||||
mm->key.phy_addr, mm->key.len, uctx); | mm->key.phy_addr, mm->key.len, uctx); | ||||
list_del(&mm->entry); | list_del(&mm->entry); | ||||
kfree(mm); | kfree(mm); | ||||
} | } | ||||
kfree(uctx); | |||||
return status; | |||||
} | } | ||||
int | int | ||||
qlnxr_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) | qlnxr_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) | ||||
{ | { | ||||
struct qlnxr_ucontext *ucontext = get_qlnxr_ucontext(context); | struct qlnxr_ucontext *ucontext = get_qlnxr_ucontext(context); | ||||
struct qlnxr_dev *dev = get_qlnxr_dev((context->device)); | struct qlnxr_dev *dev = get_qlnxr_dev((context->device)); | ||||
unsigned long vm_page = vma->vm_pgoff << PAGE_SHIFT; | unsigned long vm_page = vma->vm_pgoff << PAGE_SHIFT; | ||||
▲ Show 20 Lines • Show All 571 Lines • ▼ Show 20 Lines | |||||
err0: | err0: | ||||
kfree(mr); | kfree(mr); | ||||
QL_DPRINT12(ha, "exit [%d]\n", rc); | QL_DPRINT12(ha, "exit [%d]\n", rc); | ||||
return (ERR_PTR(rc)); | return (ERR_PTR(rc)); | ||||
} | } | ||||
int | int | ||||
qlnxr_dereg_mr(struct ib_mr *ib_mr) | qlnxr_dereg_mr(struct ib_mr *ib_mr, struct ib_udata *udata) | ||||
{ | { | ||||
struct qlnxr_mr *mr = get_qlnxr_mr(ib_mr); | struct qlnxr_mr *mr = get_qlnxr_mr(ib_mr); | ||||
struct qlnxr_dev *dev = get_qlnxr_dev((ib_mr->device)); | struct qlnxr_dev *dev = get_qlnxr_dev((ib_mr->device)); | ||||
int rc = 0; | int rc = 0; | ||||
qlnx_host_t *ha; | qlnx_host_t *ha; | ||||
ha = dev->ha; | ha = dev->ha; | ||||
▲ Show 20 Lines • Show All 143 Lines • ▼ Show 20 Lines | |||||
err: | err: | ||||
ib_umem_release(q->umem); | ib_umem_release(q->umem); | ||||
q->umem = NULL; | q->umem = NULL; | ||||
QL_DPRINT12(ha, "exit [%d]\n", rc); | QL_DPRINT12(ha, "exit [%d]\n", rc); | ||||
return rc; | return rc; | ||||
} | } | ||||
#if __FreeBSD_version >= 1102000 | int | ||||
qlnxr_create_cq(struct ib_cq *ibcq, | |||||
struct ib_cq * | |||||
qlnxr_create_cq(struct ib_device *ibdev, | |||||
const struct ib_cq_init_attr *attr, | const struct ib_cq_init_attr *attr, | ||||
struct ib_ucontext *ib_ctx, | |||||
struct ib_udata *udata) | struct ib_udata *udata) | ||||
#else | |||||
#if __FreeBSD_version >= 1100000 | |||||
struct ib_cq * | |||||
qlnxr_create_cq(struct ib_device *ibdev, | |||||
struct ib_cq_init_attr *attr, | |||||
struct ib_ucontext *ib_ctx, | |||||
struct ib_udata *udata) | |||||
#else | |||||
struct ib_cq * | |||||
qlnxr_create_cq(struct ib_device *ibdev, | |||||
int entries, | |||||
int vector, | |||||
struct ib_ucontext *ib_ctx, | |||||
struct ib_udata *udata) | |||||
#endif /* #if __FreeBSD_version >= 1100000 */ | |||||
#endif /* #if __FreeBSD_version >= 1102000 */ | |||||
{ | { | ||||
struct qlnxr_ucontext *ctx; | struct qlnxr_ucontext *ctx; | ||||
struct ecore_rdma_destroy_cq_out_params destroy_oparams; | struct ecore_rdma_destroy_cq_out_params destroy_oparams; | ||||
struct ecore_rdma_destroy_cq_in_params destroy_iparams; | struct ecore_rdma_destroy_cq_in_params destroy_iparams; | ||||
struct qlnxr_dev *dev; | struct qlnxr_dev *dev; | ||||
struct ecore_rdma_create_cq_in_params params; | struct ecore_rdma_create_cq_in_params params; | ||||
struct qlnxr_create_cq_ureq ureq; | struct qlnxr_create_cq_ureq ureq; | ||||
#if __FreeBSD_version >= 1100000 | #if __FreeBSD_version >= 1100000 | ||||
int vector = attr->comp_vector; | int vector = attr->comp_vector; | ||||
int entries = attr->cqe; | int entries = attr->cqe; | ||||
#endif | #endif | ||||
struct qlnxr_cq *cq; | struct qlnxr_cq *cq = get_qlnxr_cq(ibcq); | ||||
int chain_entries, rc, page_cnt; | int chain_entries, rc, page_cnt; | ||||
u64 pbl_ptr; | u64 pbl_ptr; | ||||
u16 icid; | u16 icid; | ||||
qlnx_host_t *ha; | qlnx_host_t *ha; | ||||
dev = get_qlnxr_dev(ibdev); | dev = get_qlnxr_dev(ibcq->device); | ||||
ha = dev->ha; | ha = dev->ha; | ||||
QL_DPRINT12(ha, "called from %s. entries = %d, " | QL_DPRINT12(ha, "called from %s. entries = %d, " | ||||
"vector = %d\n", | "vector = %d\n", | ||||
(udata ? "User Lib" : "Kernel"), entries, vector); | (udata ? "User Lib" : "Kernel"), entries, vector); | ||||
memset(¶ms, 0, sizeof(struct ecore_rdma_create_cq_in_params)); | memset(¶ms, 0, sizeof(struct ecore_rdma_create_cq_in_params)); | ||||
memset(&destroy_iparams, 0, sizeof(struct ecore_rdma_destroy_cq_in_params)); | memset(&destroy_iparams, 0, sizeof(struct ecore_rdma_destroy_cq_in_params)); | ||||
memset(&destroy_oparams, 0, sizeof(struct ecore_rdma_destroy_cq_out_params)); | memset(&destroy_oparams, 0, sizeof(struct ecore_rdma_destroy_cq_out_params)); | ||||
if (entries > QLNXR_MAX_CQES) { | if (entries > QLNXR_MAX_CQES) { | ||||
QL_DPRINT11(ha, | QL_DPRINT11(ha, | ||||
"the number of entries %d is too high. " | "the number of entries %d is too high. " | ||||
"Must be equal or below %d.\n", | "Must be equal or below %d.\n", | ||||
entries, QLNXR_MAX_CQES); | entries, QLNXR_MAX_CQES); | ||||
return ERR_PTR(-EINVAL); | return -EINVAL; | ||||
} | } | ||||
chain_entries = qlnxr_align_cq_entries(entries); | chain_entries = qlnxr_align_cq_entries(entries); | ||||
chain_entries = min_t(int, chain_entries, QLNXR_MAX_CQES); | chain_entries = min_t(int, chain_entries, QLNXR_MAX_CQES); | ||||
cq = qlnx_zalloc((sizeof(struct qlnxr_cq))); | |||||
if (!cq) | |||||
return ERR_PTR(-ENOMEM); | |||||
if (udata) { | if (udata) { | ||||
ctx = rdma_udata_to_drv_context( | |||||
udata, struct qlnxr_ucontext, ibucontext); | |||||
memset(&ureq, 0, sizeof(ureq)); | memset(&ureq, 0, sizeof(ureq)); | ||||
if (ib_copy_from_udata(&ureq, udata, | if (ib_copy_from_udata(&ureq, udata, | ||||
min(sizeof(ureq), udata->inlen))) { | min(sizeof(ureq), udata->inlen))) { | ||||
QL_DPRINT11(ha, "ib_copy_from_udata failed\n"); | QL_DPRINT11(ha, "ib_copy_from_udata failed\n"); | ||||
goto err0; | goto err0; | ||||
} | } | ||||
if (!ureq.len) { | if (!ureq.len) { | ||||
QL_DPRINT11(ha, "ureq.len == 0\n"); | QL_DPRINT11(ha, "ureq.len == 0\n"); | ||||
goto err0; | goto err0; | ||||
} | } | ||||
cq->cq_type = QLNXR_CQ_TYPE_USER; | cq->cq_type = QLNXR_CQ_TYPE_USER; | ||||
qlnxr_init_user_queue(ib_ctx, dev, &cq->q, ureq.addr, ureq.len, | qlnxr_init_user_queue(&ctx->ibucontext, dev, &cq->q, ureq.addr, ureq.len, | ||||
IB_ACCESS_LOCAL_WRITE, 1, 1); | IB_ACCESS_LOCAL_WRITE, 1, 1); | ||||
pbl_ptr = cq->q.pbl_tbl->pa; | pbl_ptr = cq->q.pbl_tbl->pa; | ||||
page_cnt = cq->q.pbl_info.num_pbes; | page_cnt = cq->q.pbl_info.num_pbes; | ||||
cq->ibcq.cqe = chain_entries; | cq->ibcq.cqe = chain_entries; | ||||
} else { | } else { | ||||
ctx = NULL; | |||||
cq->cq_type = QLNXR_CQ_TYPE_KERNEL; | cq->cq_type = QLNXR_CQ_TYPE_KERNEL; | ||||
rc = ecore_chain_alloc(&dev->ha->cdev, | rc = ecore_chain_alloc(&dev->ha->cdev, | ||||
ECORE_CHAIN_USE_TO_CONSUME, | ECORE_CHAIN_USE_TO_CONSUME, | ||||
ECORE_CHAIN_MODE_PBL, | ECORE_CHAIN_MODE_PBL, | ||||
ECORE_CHAIN_CNT_TYPE_U32, | ECORE_CHAIN_CNT_TYPE_U32, | ||||
chain_entries, | chain_entries, | ||||
sizeof(union roce_cqe), | sizeof(union roce_cqe), | ||||
Show All 10 Lines | cq->ibcq.cqe = cq->pbl.capacity; | ||||
params.cq_handle_hi = upper_32_bits((uintptr_t)cq); | params.cq_handle_hi = upper_32_bits((uintptr_t)cq); | ||||
params.cq_handle_lo = lower_32_bits((uintptr_t)cq); | params.cq_handle_lo = lower_32_bits((uintptr_t)cq); | ||||
params.cnq_id = vector; | params.cnq_id = vector; | ||||
params.cq_size = chain_entries - 1; | params.cq_size = chain_entries - 1; | ||||
params.pbl_num_pages = page_cnt; | params.pbl_num_pages = page_cnt; | ||||
params.pbl_ptr = pbl_ptr; | params.pbl_ptr = pbl_ptr; | ||||
params.pbl_two_level = 0; | params.pbl_two_level = 0; | ||||
if (ib_ctx != NULL) { | if (udata) { | ||||
ctx = get_qlnxr_ucontext(ib_ctx); | |||||
params.dpi = ctx->dpi; | params.dpi = ctx->dpi; | ||||
} else { | } else { | ||||
params.dpi = dev->dpi; | params.dpi = dev->dpi; | ||||
} | } | ||||
rc = ecore_rdma_create_cq(dev->rdma_ctx, ¶ms, &icid); | rc = ecore_rdma_create_cq(dev->rdma_ctx, ¶ms, &icid); | ||||
if (rc) | if (rc) | ||||
goto err2; | goto err2; | ||||
cq->icid = icid; | cq->icid = icid; | ||||
cq->sig = QLNXR_CQ_MAGIC_NUMBER; | cq->sig = QLNXR_CQ_MAGIC_NUMBER; | ||||
spin_lock_init(&cq->cq_lock); | spin_lock_init(&cq->cq_lock); | ||||
if (ib_ctx) { | if (udata) { | ||||
rc = qlnxr_copy_cq_uresp(dev, cq, udata); | rc = qlnxr_copy_cq_uresp(dev, cq, udata); | ||||
if (rc) | if (rc) | ||||
goto err3; | goto err3; | ||||
} else { | } else { | ||||
/* Generate doorbell address. | /* Generate doorbell address. | ||||
* Configure bits 3-9 with DQ_PWM_OFFSET_UCM_RDMA_CQ_CONS_32BIT. | * Configure bits 3-9 with DQ_PWM_OFFSET_UCM_RDMA_CQ_CONS_32BIT. | ||||
* TODO: consider moving to device scope as it is a function of | * TODO: consider moving to device scope as it is a function of | ||||
* the device. | * the device. | ||||
Show All 14 Lines | if (udata) { | ||||
consume_cqe(cq); | consume_cqe(cq); | ||||
cq->cq_cons = ecore_chain_get_cons_idx_u32(&cq->pbl); | cq->cq_cons = ecore_chain_get_cons_idx_u32(&cq->pbl); | ||||
} | } | ||||
QL_DPRINT12(ha, "exit icid = 0x%0x, addr = %p," | QL_DPRINT12(ha, "exit icid = 0x%0x, addr = %p," | ||||
" number of entries = 0x%x\n", | " number of entries = 0x%x\n", | ||||
cq->icid, cq, params.cq_size); | cq->icid, cq, params.cq_size); | ||||
QL_DPRINT12(ha,"cq_addr = %p\n", cq); | QL_DPRINT12(ha,"cq_addr = %p\n", cq); | ||||
return &cq->ibcq; | return (0); | ||||
err3: | err3: | ||||
destroy_iparams.icid = cq->icid; | destroy_iparams.icid = cq->icid; | ||||
ecore_rdma_destroy_cq(dev->rdma_ctx, &destroy_iparams, &destroy_oparams); | ecore_rdma_destroy_cq(dev->rdma_ctx, &destroy_iparams, &destroy_oparams); | ||||
err2: | err2: | ||||
if (udata) | if (udata) | ||||
qlnxr_free_pbl(dev, &cq->q.pbl_info, cq->q.pbl_tbl); | qlnxr_free_pbl(dev, &cq->q.pbl_info, cq->q.pbl_tbl); | ||||
else | else | ||||
ecore_chain_free(&dev->ha->cdev, &cq->pbl); | ecore_chain_free(&dev->ha->cdev, &cq->pbl); | ||||
err1: | err1: | ||||
if (udata) | if (udata) | ||||
ib_umem_release(cq->q.umem); | ib_umem_release(cq->q.umem); | ||||
err0: | err0: | ||||
kfree(cq); | |||||
QL_DPRINT12(ha, "exit error\n"); | QL_DPRINT12(ha, "exit error\n"); | ||||
return ERR_PTR(-EINVAL); | return (-EINVAL); | ||||
} | } | ||||
int qlnxr_resize_cq(struct ib_cq *ibcq, int new_cnt, struct ib_udata *udata) | int qlnxr_resize_cq(struct ib_cq *ibcq, int new_cnt, struct ib_udata *udata) | ||||
{ | { | ||||
int status = 0; | int status = 0; | ||||
struct qlnxr_dev *dev = get_qlnxr_dev((ibcq->device)); | struct qlnxr_dev *dev = get_qlnxr_dev((ibcq->device)); | ||||
qlnx_host_t *ha; | qlnx_host_t *ha; | ||||
ha = dev->ha; | ha = dev->ha; | ||||
QL_DPRINT12(ha, "enter/exit\n"); | QL_DPRINT12(ha, "enter/exit\n"); | ||||
return status; | return status; | ||||
} | } | ||||
int | void | ||||
qlnxr_destroy_cq(struct ib_cq *ibcq) | qlnxr_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata) | ||||
{ | { | ||||
struct qlnxr_dev *dev = get_qlnxr_dev((ibcq->device)); | struct qlnxr_dev *dev = get_qlnxr_dev((ibcq->device)); | ||||
struct ecore_rdma_destroy_cq_out_params oparams; | struct ecore_rdma_destroy_cq_out_params oparams; | ||||
struct ecore_rdma_destroy_cq_in_params iparams; | struct ecore_rdma_destroy_cq_in_params iparams; | ||||
struct qlnxr_cq *cq = get_qlnxr_cq(ibcq); | struct qlnxr_cq *cq = get_qlnxr_cq(ibcq); | ||||
int rc = 0; | int rc = 0; | ||||
qlnx_host_t *ha; | qlnx_host_t *ha; | ||||
Show All 13 Lines | qlnxr_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata) | ||||
if (cq->cq_type != QLNXR_CQ_TYPE_GSI) { | if (cq->cq_type != QLNXR_CQ_TYPE_GSI) { | ||||
iparams.icid = cq->icid; | iparams.icid = cq->icid; | ||||
rc = ecore_rdma_destroy_cq(dev->rdma_ctx, &iparams, &oparams); | rc = ecore_rdma_destroy_cq(dev->rdma_ctx, &iparams, &oparams); | ||||
if (rc) { | if (rc) { | ||||
QL_DPRINT12(ha, "ecore_rdma_destroy_cq failed cq_id = %d\n", | QL_DPRINT12(ha, "ecore_rdma_destroy_cq failed cq_id = %d\n", | ||||
cq->icid); | cq->icid); | ||||
return rc; | return; | ||||
} | } | ||||
QL_DPRINT12(ha, "free cq->pbl cq_id = %d\n", cq->icid); | QL_DPRINT12(ha, "free cq->pbl cq_id = %d\n", cq->icid); | ||||
ecore_chain_free(&dev->ha->cdev, &cq->pbl); | ecore_chain_free(&dev->ha->cdev, &cq->pbl); | ||||
} | } | ||||
if (ibcq->uobject && ibcq->uobject->context) { | if (udata) { | ||||
qlnxr_free_pbl(dev, &cq->q.pbl_info, cq->q.pbl_tbl); | qlnxr_free_pbl(dev, &cq->q.pbl_info, cq->q.pbl_tbl); | ||||
ib_umem_release(cq->q.umem); | ib_umem_release(cq->q.umem); | ||||
} | } | ||||
cq->sig = ~cq->sig; | cq->sig = ~cq->sig; | ||||
kfree(cq); | |||||
QL_DPRINT12(ha, "exit cq_id = %d\n", cq->icid); | QL_DPRINT12(ha, "exit cq_id = %d\n", cq->icid); | ||||
return rc; | |||||
} | } | ||||
static int | static int | ||||
qlnxr_check_qp_attrs(struct ib_pd *ibpd, | qlnxr_check_qp_attrs(struct ib_pd *ibpd, | ||||
struct qlnxr_dev *dev, | struct qlnxr_dev *dev, | ||||
struct ib_qp_init_attr *attrs, | struct ib_qp_init_attr *attrs, | ||||
struct ib_udata *udata) | struct ib_udata *udata) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 303 Lines • ▼ Show 20 Lines | QL_DPRINT12(ha, | ||||
pd->pd_id, qp->qp_type, qp->max_inline_data, | pd->pd_id, qp->qp_type, qp->max_inline_data, | ||||
qp->state, qp->signaled, ((attrs->srq) ? 1 : 0)); | qp->state, qp->signaled, ((attrs->srq) ? 1 : 0)); | ||||
QL_DPRINT12(ha, "SQ params:\tsq_max_sges = %d, sq_cq_id = %d\n", | QL_DPRINT12(ha, "SQ params:\tsq_max_sges = %d, sq_cq_id = %d\n", | ||||
qp->sq.max_sges, qp->sq_cq->icid); | qp->sq.max_sges, qp->sq_cq->icid); | ||||
return; | return; | ||||
} | } | ||||
static int | static int | ||||
qlnxr_check_srq_params(struct ib_pd *ibpd, | qlnxr_check_srq_params(struct qlnxr_dev *dev, | ||||
struct qlnxr_dev *dev, | |||||
struct ib_srq_init_attr *attrs) | struct ib_srq_init_attr *attrs) | ||||
{ | { | ||||
struct ecore_rdma_device *qattr; | struct ecore_rdma_device *qattr; | ||||
qlnx_host_t *ha; | qlnx_host_t *ha; | ||||
ha = dev->ha; | ha = dev->ha; | ||||
qattr = ecore_rdma_query_device(dev->rdma_ctx); | qattr = ecore_rdma_query_device(dev->rdma_ctx); | ||||
▲ Show 20 Lines • Show All 870 Lines • ▼ Show 20 Lines | if (rc) { | ||||
QL_DPRINT11(ha, "qlnxr_idr_add failed\n"); | QL_DPRINT11(ha, "qlnxr_idr_add failed\n"); | ||||
goto err; | goto err; | ||||
} | } | ||||
QL_DPRINT12(ha, "exit [%p]\n", &qp->ibqp); | QL_DPRINT12(ha, "exit [%p]\n", &qp->ibqp); | ||||
return &qp->ibqp; | return &qp->ibqp; | ||||
err: | err: | ||||
kfree(qp); | |||||
QL_DPRINT12(ha, "failed exit\n"); | QL_DPRINT12(ha, "failed exit\n"); | ||||
return ERR_PTR(-EFAULT); | return ERR_PTR(-EFAULT); | ||||
} | } | ||||
static enum ib_qp_state | static enum ib_qp_state | ||||
qlnxr_get_ibqp_state(enum ecore_roce_qp_state qp_state) | qlnxr_get_ibqp_state(enum ecore_roce_qp_state qp_state) | ||||
{ | { | ||||
enum ib_qp_state state = IB_QPS_ERR; | enum ib_qp_state state = IB_QPS_ERR; | ||||
▲ Show 20 Lines • Show All 688 Lines • ▼ Show 20 Lines | // ecore_chain_free(dev->cdev, &qp->rq.pbl); | ||||
ha->qlnxr_debug = 0; | ha->qlnxr_debug = 0; | ||||
kfree(qp->rqe_wr_id); | kfree(qp->rqe_wr_id); | ||||
} | } | ||||
QL_DPRINT12(ha, "exit\n"); | QL_DPRINT12(ha, "exit\n"); | ||||
return; | return; | ||||
} | } | ||||
int | static int | ||||
qlnxr_free_qp_resources(struct qlnxr_dev *dev, | qlnxr_free_qp_resources(struct qlnxr_dev *dev, | ||||
struct qlnxr_qp *qp) | struct qlnxr_qp *qp, struct ib_udata *udata) | ||||
{ | { | ||||
int rc = 0; | int rc = 0; | ||||
qlnx_host_t *ha; | qlnx_host_t *ha; | ||||
struct ecore_rdma_destroy_qp_out_params d_out_params; | struct ecore_rdma_destroy_qp_out_params d_out_params; | ||||
ha = dev->ha; | ha = dev->ha; | ||||
QL_DPRINT12(ha, "enter\n"); | QL_DPRINT12(ha, "enter\n"); | ||||
#if 0 | #if 0 | ||||
if (qp->qp_type != IB_QPT_GSI) { | if (qp->qp_type != IB_QPT_GSI) { | ||||
rc = ecore_rdma_destroy_qp(dev->rdma_ctx, qp->ecore_qp, | rc = ecore_rdma_destroy_qp(dev->rdma_ctx, qp->ecore_qp, | ||||
&d_out_params); | &d_out_params); | ||||
if (rc) | if (rc) | ||||
return rc; | return rc; | ||||
} | } | ||||
if (qp->ibqp.uobject && qp->ibqp.uobject->context) | if (udata) | ||||
qlnxr_cleanup_user(dev, qp); | qlnxr_cleanup_user(dev, qp); | ||||
else | else | ||||
qlnxr_cleanup_kernel(dev, qp); | qlnxr_cleanup_kernel(dev, qp); | ||||
#endif | #endif | ||||
if (qp->ibqp.uobject && qp->ibqp.uobject->context) | if (udata) | ||||
qlnxr_cleanup_user(dev, qp); | qlnxr_cleanup_user(dev, qp); | ||||
else | else | ||||
qlnxr_cleanup_kernel(dev, qp); | qlnxr_cleanup_kernel(dev, qp); | ||||
if (qp->qp_type != IB_QPT_GSI) { | if (qp->qp_type != IB_QPT_GSI) { | ||||
rc = ecore_rdma_destroy_qp(dev->rdma_ctx, qp->ecore_qp, | rc = ecore_rdma_destroy_qp(dev->rdma_ctx, qp->ecore_qp, | ||||
&d_out_params); | &d_out_params); | ||||
if (rc) | if (rc) | ||||
return rc; | return rc; | ||||
} | } | ||||
QL_DPRINT12(ha, "exit\n"); | QL_DPRINT12(ha, "exit\n"); | ||||
return 0; | return 0; | ||||
} | } | ||||
int | int | ||||
qlnxr_destroy_qp(struct ib_qp *ibqp) | qlnxr_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata) | ||||
{ | { | ||||
struct qlnxr_qp *qp = get_qlnxr_qp(ibqp); | struct qlnxr_qp *qp = get_qlnxr_qp(ibqp); | ||||
struct qlnxr_dev *dev = qp->dev; | struct qlnxr_dev *dev = qp->dev; | ||||
int rc = 0; | int rc = 0; | ||||
struct ib_qp_attr attr; | struct ib_qp_attr attr; | ||||
int attr_mask = 0; | int attr_mask = 0; | ||||
qlnx_host_t *ha; | qlnx_host_t *ha; | ||||
Show All 13 Lines | if (QLNX_IS_ROCE(dev) && (qp->state != (ECORE_ROCE_QP_STATE_RESET | | ||||
qlnxr_modify_qp(ibqp, &attr, attr_mask, NULL); | qlnxr_modify_qp(ibqp, &attr, attr_mask, NULL); | ||||
} | } | ||||
if (qp->qp_type == IB_QPT_GSI) | if (qp->qp_type == IB_QPT_GSI) | ||||
qlnxr_destroy_gsi_qp(dev); | qlnxr_destroy_gsi_qp(dev); | ||||
qp->sig = ~qp->sig; | qp->sig = ~qp->sig; | ||||
qlnxr_free_qp_resources(dev, qp); | qlnxr_free_qp_resources(dev, qp, udata); | ||||
if (atomic_dec_and_test(&qp->refcnt)) { | if (atomic_dec_and_test(&qp->refcnt)) { | ||||
/* TODO: only for iWARP? */ | /* TODO: only for iWARP? */ | ||||
qlnxr_idr_remove(dev, qp->qp_id); | qlnxr_idr_remove(dev, qp->qp_id); | ||||
kfree(qp); | |||||
} | } | ||||
QL_DPRINT12(ha, "exit\n"); | QL_DPRINT12(ha, "exit\n"); | ||||
return rc; | return rc; | ||||
} | } | ||||
static inline int | static inline int | ||||
qlnxr_wq_is_full(struct qlnxr_qp_hwq_info *wq) | qlnxr_wq_is_full(struct qlnxr_qp_hwq_info *wq) | ||||
▲ Show 20 Lines • Show All 1,755 Lines • ▼ Show 20 Lines | err0: | ||||
QL_DPRINT12(ha, "exit\n"); | QL_DPRINT12(ha, "exit\n"); | ||||
return ERR_PTR(rc); | return ERR_PTR(rc); | ||||
} | } | ||||
#if __FreeBSD_version >= 1102000 | #if __FreeBSD_version >= 1102000 | ||||
struct ib_mr * | struct ib_mr * | ||||
qlnxr_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type, u32 max_num_sg) | qlnxr_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type, | ||||
u32 max_num_sg, struct ib_udata *udata) | |||||
{ | { | ||||
struct qlnxr_dev *dev; | struct qlnxr_dev *dev; | ||||
struct qlnxr_mr *mr; | struct qlnxr_mr *mr; | ||||
qlnx_host_t *ha; | qlnx_host_t *ha; | ||||
dev = get_qlnxr_dev(ibpd->device); | dev = get_qlnxr_dev(ibpd->device); | ||||
ha = dev->ha; | ha = dev->ha; | ||||
▲ Show 20 Lines • Show All 412 Lines • ▼ Show 20 Lines | err0: | ||||
kfree(mr); | kfree(mr); | ||||
QL_DPRINT12(ha, "exit [%d]\n", rc); | QL_DPRINT12(ha, "exit [%d]\n", rc); | ||||
return (ERR_PTR(rc)); | return (ERR_PTR(rc)); | ||||
} | } | ||||
#endif /* #if __FreeBSD_version >= 1102000 */ | #endif /* #if __FreeBSD_version >= 1102000 */ | ||||
struct ib_ah * | int | ||||
#if __FreeBSD_version >= 1102000 | qlnxr_create_ah(struct ib_ah *ibah, | ||||
qlnxr_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr, | struct ib_ah_attr *attr, u32 flags, | ||||
struct ib_udata *udata) | struct ib_udata *udata) | ||||
#else | |||||
qlnxr_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr) | |||||
#endif /* #if __FreeBSD_version >= 1102000 */ | |||||
{ | { | ||||
struct qlnxr_dev *dev; | struct qlnxr_dev *dev; | ||||
qlnx_host_t *ha; | qlnx_host_t *ha; | ||||
struct qlnxr_ah *ah; | struct qlnxr_ah *ah = get_qlnxr_ah(ibah); | ||||
dev = get_qlnxr_dev((ibpd->device)); | dev = get_qlnxr_dev(ibah->device); | ||||
ha = dev->ha; | ha = dev->ha; | ||||
QL_DPRINT12(ha, "in create_ah\n"); | QL_DPRINT12(ha, "in create_ah\n"); | ||||
ah = kzalloc(sizeof(*ah), GFP_ATOMIC); | |||||
if (!ah) { | |||||
QL_DPRINT12(ha, "no address handle can be allocated\n"); | |||||
return ERR_PTR(-ENOMEM); | |||||
} | |||||
ah->attr = *attr; | ah->attr = *attr; | ||||
return &ah->ibah; | return (0); | ||||
} | } | ||||
int | void | ||||
qlnxr_destroy_ah(struct ib_ah *ibah) | qlnxr_destroy_ah(struct ib_ah *ibah, u32 flags) | ||||
{ | { | ||||
struct qlnxr_dev *dev; | |||||
qlnx_host_t *ha; | |||||
struct qlnxr_ah *ah = get_qlnxr_ah(ibah); | |||||
dev = get_qlnxr_dev((ibah->device)); | |||||
ha = dev->ha; | |||||
QL_DPRINT12(ha, "in destroy_ah\n"); | |||||
kfree(ah); | |||||
return 0; | |||||
} | } | ||||
int | int | ||||
qlnxr_query_ah(struct ib_ah *ibah, struct ib_ah_attr *attr) | qlnxr_query_ah(struct ib_ah *ibah, struct ib_ah_attr *attr) | ||||
{ | { | ||||
struct qlnxr_dev *dev; | struct qlnxr_dev *dev; | ||||
qlnx_host_t *ha; | qlnx_host_t *ha; | ||||
▲ Show 20 Lines • Show All 863 Lines • ▼ Show 20 Lines | qlnxr_iw_qp_rem_ref(struct ib_qp *ibqp) | ||||
qlnx_host_t *ha; | qlnx_host_t *ha; | ||||
ha = qp->dev->ha; | ha = qp->dev->ha; | ||||
QL_DPRINT12(ha, "enter ibqp = %p qp = %p\n", ibqp, qp); | QL_DPRINT12(ha, "enter ibqp = %p qp = %p\n", ibqp, qp); | ||||
if (atomic_dec_and_test(&qp->refcnt)) { | if (atomic_dec_and_test(&qp->refcnt)) { | ||||
qlnxr_idr_remove(qp->dev, qp->qp_id); | qlnxr_idr_remove(qp->dev, qp->qp_id); | ||||
kfree(qp); | |||||
} | } | ||||
QL_DPRINT12(ha, "exit \n"); | QL_DPRINT12(ha, "exit \n"); | ||||
return; | return; | ||||
} | } | ||||
struct ib_qp * | struct ib_qp * | ||||
qlnxr_iw_get_qp(struct ib_device *ibdev, int qpn) | qlnxr_iw_get_qp(struct ib_device *ibdev, int qpn) | ||||
Show All 15 Lines |