Merge branches 'nes', 'cxgb4' and 'iwpm' into k.o/for-4.6
[cascardo/linux.git] / drivers / infiniband / hw / cxgb4 / qp.c
index e99345e..e17fb5d 100644 (file)
@@ -606,7 +606,7 @@ static int build_rdma_recv(struct c4iw_qp *qhp, union t4_recv_wr *wqe,
 }
 
 static int build_memreg(struct t4_sq *sq, union t4_wr *wqe,
-                       struct ib_reg_wr *wr, u8 *len16, u8 t5dev)
+                       struct ib_reg_wr *wr, u8 *len16, bool dsgl_supported)
 {
        struct c4iw_mr *mhp = to_c4iw_mr(wr->mr);
        struct fw_ri_immd *imdp;
@@ -615,7 +615,7 @@ static int build_memreg(struct t4_sq *sq, union t4_wr *wqe,
        int pbllen = roundup(mhp->mpl_len * sizeof(u64), 32);
        int rem;
 
-       if (mhp->mpl_len > t4_max_fr_depth(use_dsgl))
+       if (mhp->mpl_len > t4_max_fr_depth(dsgl_supported && use_dsgl))
                return -EINVAL;
 
        wqe->fr.qpbinde_to_dcacpu = 0;
@@ -629,7 +629,7 @@ static int build_memreg(struct t4_sq *sq, union t4_wr *wqe,
        wqe->fr.va_lo_fbo = cpu_to_be32(mhp->ibmr.iova &
                                        0xffffffff);
 
-       if (t5dev && use_dsgl && (pbllen > max_fr_immd)) {
+       if (dsgl_supported && use_dsgl && (pbllen > max_fr_immd)) {
                struct fw_ri_dsgl *sglp;
 
                for (i = 0; i < mhp->mpl_len; i++)
@@ -808,9 +808,7 @@ int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
                        fw_opcode = FW_RI_FR_NSMR_WR;
                        swsqe->opcode = FW_RI_FAST_REGISTER;
                        err = build_memreg(&qhp->wq.sq, wqe, reg_wr(wr), &len16,
-                                          is_t5(
-                                          qhp->rhp->rdev.lldi.adapter_type) ?
-                                          1 : 0);
+                               qhp->rhp->rdev.lldi.ulptx_memwrite_dsgl);
                        break;
                case IB_WR_LOCAL_INV:
                        if (wr->send_flags & IB_SEND_FENCE)
@@ -1621,7 +1619,8 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs,
        unsigned int sqsize, rqsize;
        struct c4iw_ucontext *ucontext;
        int ret;
-       struct c4iw_mm_entry *mm1, *mm2, *mm3, *mm4, *mm5 = NULL;
+       struct c4iw_mm_entry *sq_key_mm, *rq_key_mm = NULL, *sq_db_key_mm;
+       struct c4iw_mm_entry *rq_db_key_mm = NULL, *ma_sync_key_mm = NULL;
 
        PDBG("%s ib_pd %p\n", __func__, pd);
 
@@ -1697,6 +1696,8 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs,
        qhp->attr.max_ird = 0;
        qhp->sq_sig_all = attrs->sq_sig_type == IB_SIGNAL_ALL_WR;
        spin_lock_init(&qhp->lock);
+       init_completion(&qhp->sq_drained);
+       init_completion(&qhp->rq_drained);
        mutex_init(&qhp->mutex);
        init_waitqueue_head(&qhp->wait);
        atomic_set(&qhp->refcnt, 1);
@@ -1706,29 +1707,30 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs,
                goto err2;
 
        if (udata) {
-               mm1 = kmalloc(sizeof *mm1, GFP_KERNEL);
-               if (!mm1) {
+               sq_key_mm = kmalloc(sizeof(*sq_key_mm), GFP_KERNEL);
+               if (!sq_key_mm) {
                        ret = -ENOMEM;
                        goto err3;
                }
-               mm2 = kmalloc(sizeof *mm2, GFP_KERNEL);
-               if (!mm2) {
+               rq_key_mm = kmalloc(sizeof(*rq_key_mm), GFP_KERNEL);
+               if (!rq_key_mm) {
                        ret = -ENOMEM;
                        goto err4;
                }
-               mm3 = kmalloc(sizeof *mm3, GFP_KERNEL);
-               if (!mm3) {
+               sq_db_key_mm = kmalloc(sizeof(*sq_db_key_mm), GFP_KERNEL);
+               if (!sq_db_key_mm) {
                        ret = -ENOMEM;
                        goto err5;
                }
-               mm4 = kmalloc(sizeof *mm4, GFP_KERNEL);
-               if (!mm4) {
+               rq_db_key_mm = kmalloc(sizeof(*rq_db_key_mm), GFP_KERNEL);
+               if (!rq_db_key_mm) {
                        ret = -ENOMEM;
                        goto err6;
                }
                if (t4_sq_onchip(&qhp->wq.sq)) {
-                       mm5 = kmalloc(sizeof *mm5, GFP_KERNEL);
-                       if (!mm5) {
+                       ma_sync_key_mm = kmalloc(sizeof(*ma_sync_key_mm),
+                                                GFP_KERNEL);
+                       if (!ma_sync_key_mm) {
                                ret = -ENOMEM;
                                goto err7;
                        }
@@ -1743,7 +1745,7 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs,
                uresp.rq_size = qhp->wq.rq.size;
                uresp.rq_memsize = qhp->wq.rq.memsize;
                spin_lock(&ucontext->mmap_lock);
-               if (mm5) {
+               if (ma_sync_key_mm) {
                        uresp.ma_sync_key = ucontext->key;
                        ucontext->key += PAGE_SIZE;
                } else {
@@ -1761,28 +1763,29 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs,
                ret = ib_copy_to_udata(udata, &uresp, sizeof uresp);
                if (ret)
                        goto err8;
-               mm1->key = uresp.sq_key;
-               mm1->addr = qhp->wq.sq.phys_addr;
-               mm1->len = PAGE_ALIGN(qhp->wq.sq.memsize);
-               insert_mmap(ucontext, mm1);
-               mm2->key = uresp.rq_key;
-               mm2->addr = virt_to_phys(qhp->wq.rq.queue);
-               mm2->len = PAGE_ALIGN(qhp->wq.rq.memsize);
-               insert_mmap(ucontext, mm2);
-               mm3->key = uresp.sq_db_gts_key;
-               mm3->addr = (__force unsigned long)qhp->wq.sq.bar2_pa;
-               mm3->len = PAGE_SIZE;
-               insert_mmap(ucontext, mm3);
-               mm4->key = uresp.rq_db_gts_key;
-               mm4->addr = (__force unsigned long)qhp->wq.rq.bar2_pa;
-               mm4->len = PAGE_SIZE;
-               insert_mmap(ucontext, mm4);
-               if (mm5) {
-                       mm5->key = uresp.ma_sync_key;
-                       mm5->addr = (pci_resource_start(rhp->rdev.lldi.pdev, 0)
-                                   + PCIE_MA_SYNC_A) & PAGE_MASK;
-                       mm5->len = PAGE_SIZE;
-                       insert_mmap(ucontext, mm5);
+               sq_key_mm->key = uresp.sq_key;
+               sq_key_mm->addr = qhp->wq.sq.phys_addr;
+               sq_key_mm->len = PAGE_ALIGN(qhp->wq.sq.memsize);
+               insert_mmap(ucontext, sq_key_mm);
+               rq_key_mm->key = uresp.rq_key;
+               rq_key_mm->addr = virt_to_phys(qhp->wq.rq.queue);
+               rq_key_mm->len = PAGE_ALIGN(qhp->wq.rq.memsize);
+               insert_mmap(ucontext, rq_key_mm);
+               sq_db_key_mm->key = uresp.sq_db_gts_key;
+               sq_db_key_mm->addr = (u64)(unsigned long)qhp->wq.sq.bar2_pa;
+               sq_db_key_mm->len = PAGE_SIZE;
+               insert_mmap(ucontext, sq_db_key_mm);
+               rq_db_key_mm->key = uresp.rq_db_gts_key;
+               rq_db_key_mm->addr = (u64)(unsigned long)qhp->wq.rq.bar2_pa;
+               rq_db_key_mm->len = PAGE_SIZE;
+               insert_mmap(ucontext, rq_db_key_mm);
+               if (ma_sync_key_mm) {
+                       ma_sync_key_mm->key = uresp.ma_sync_key;
+                       ma_sync_key_mm->addr =
+                               (pci_resource_start(rhp->rdev.lldi.pdev, 0) +
+                               PCIE_MA_SYNC_A) & PAGE_MASK;
+                       ma_sync_key_mm->len = PAGE_SIZE;
+                       insert_mmap(ucontext, ma_sync_key_mm);
                }
        }
        qhp->ibqp.qp_num = qhp->wq.sq.qid;
@@ -1795,15 +1798,15 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs,
             qhp->wq.rq.memsize, attrs->cap.max_recv_wr);
        return &qhp->ibqp;
 err8:
-       kfree(mm5);
+       kfree(ma_sync_key_mm);
 err7:
-       kfree(mm4);
+       kfree(rq_db_key_mm);
 err6:
-       kfree(mm3);
+       kfree(sq_db_key_mm);
 err5:
-       kfree(mm2);
+       kfree(rq_key_mm);
 err4:
-       kfree(mm1);
+       kfree(sq_key_mm);
 err3:
        remove_handle(rhp, &rhp->qpidr, qhp->wq.sq.qid);
 err2:
@@ -1888,3 +1891,17 @@ int c4iw_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
        init_attr->sq_sig_type = qhp->sq_sig_all ? IB_SIGNAL_ALL_WR : 0;
        return 0;
 }
+
+void c4iw_drain_sq(struct ib_qp *ibqp)
+{
+       struct c4iw_qp *qp = to_c4iw_qp(ibqp);
+
+       wait_for_completion(&qp->sq_drained);
+}
+
+void c4iw_drain_rq(struct ib_qp *ibqp)
+{
+       struct c4iw_qp *qp = to_c4iw_qp(ibqp);
+
+       wait_for_completion(&qp->rq_drained);
+}