diff options
Diffstat (limited to 'drivers/infiniband/hw/cxgb4/qp.c')
-rw-r--r-- | drivers/infiniband/hw/cxgb4/qp.c | 283 |
1 files changed, 162 insertions, 121 deletions
diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 93f6e5bf0ec5..057cb2505ea1 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c | |||
@@ -31,6 +31,63 @@ | |||
31 | */ | 31 | */ |
32 | #include "iw_cxgb4.h" | 32 | #include "iw_cxgb4.h" |
33 | 33 | ||
34 | static int ocqp_support; | ||
35 | module_param(ocqp_support, int, 0644); | ||
36 | MODULE_PARM_DESC(ocqp_support, "Support on-chip SQs (default=0)"); | ||
37 | |||
38 | static void set_state(struct c4iw_qp *qhp, enum c4iw_qp_state state) | ||
39 | { | ||
40 | unsigned long flag; | ||
41 | spin_lock_irqsave(&qhp->lock, flag); | ||
42 | qhp->attr.state = state; | ||
43 | spin_unlock_irqrestore(&qhp->lock, flag); | ||
44 | } | ||
45 | |||
46 | static void dealloc_oc_sq(struct c4iw_rdev *rdev, struct t4_sq *sq) | ||
47 | { | ||
48 | c4iw_ocqp_pool_free(rdev, sq->dma_addr, sq->memsize); | ||
49 | } | ||
50 | |||
51 | static void dealloc_host_sq(struct c4iw_rdev *rdev, struct t4_sq *sq) | ||
52 | { | ||
53 | dma_free_coherent(&(rdev->lldi.pdev->dev), sq->memsize, sq->queue, | ||
54 | pci_unmap_addr(sq, mapping)); | ||
55 | } | ||
56 | |||
57 | static void dealloc_sq(struct c4iw_rdev *rdev, struct t4_sq *sq) | ||
58 | { | ||
59 | if (t4_sq_onchip(sq)) | ||
60 | dealloc_oc_sq(rdev, sq); | ||
61 | else | ||
62 | dealloc_host_sq(rdev, sq); | ||
63 | } | ||
64 | |||
65 | static int alloc_oc_sq(struct c4iw_rdev *rdev, struct t4_sq *sq) | ||
66 | { | ||
67 | if (!ocqp_support || !t4_ocqp_supported()) | ||
68 | return -ENOSYS; | ||
69 | sq->dma_addr = c4iw_ocqp_pool_alloc(rdev, sq->memsize); | ||
70 | if (!sq->dma_addr) | ||
71 | return -ENOMEM; | ||
72 | sq->phys_addr = rdev->oc_mw_pa + sq->dma_addr - | ||
73 | rdev->lldi.vr->ocq.start; | ||
74 | sq->queue = (__force union t4_wr *)(rdev->oc_mw_kva + sq->dma_addr - | ||
75 | rdev->lldi.vr->ocq.start); | ||
76 | sq->flags |= T4_SQ_ONCHIP; | ||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | static int alloc_host_sq(struct c4iw_rdev *rdev, struct t4_sq *sq) | ||
81 | { | ||
82 | sq->queue = dma_alloc_coherent(&(rdev->lldi.pdev->dev), sq->memsize, | ||
83 | &(sq->dma_addr), GFP_KERNEL); | ||
84 | if (!sq->queue) | ||
85 | return -ENOMEM; | ||
86 | sq->phys_addr = virt_to_phys(sq->queue); | ||
87 | pci_unmap_addr_set(sq, mapping, sq->dma_addr); | ||
88 | return 0; | ||
89 | } | ||
90 | |||
34 | static int destroy_qp(struct c4iw_rdev *rdev, struct t4_wq *wq, | 91 | static int destroy_qp(struct c4iw_rdev *rdev, struct t4_wq *wq, |
35 | struct c4iw_dev_ucontext *uctx) | 92 | struct c4iw_dev_ucontext *uctx) |
36 | { | 93 | { |
@@ -41,9 +98,7 @@ static int destroy_qp(struct c4iw_rdev *rdev, struct t4_wq *wq, | |||
41 | dma_free_coherent(&(rdev->lldi.pdev->dev), | 98 | dma_free_coherent(&(rdev->lldi.pdev->dev), |
42 | wq->rq.memsize, wq->rq.queue, | 99 | wq->rq.memsize, wq->rq.queue, |
43 | dma_unmap_addr(&wq->rq, mapping)); | 100 | dma_unmap_addr(&wq->rq, mapping)); |
44 | dma_free_coherent(&(rdev->lldi.pdev->dev), | 101 | dealloc_sq(rdev, &wq->sq); |
45 | wq->sq.memsize, wq->sq.queue, | ||
46 | dma_unmap_addr(&wq->sq, mapping)); | ||
47 | c4iw_rqtpool_free(rdev, wq->rq.rqt_hwaddr, wq->rq.rqt_size); | 102 | c4iw_rqtpool_free(rdev, wq->rq.rqt_hwaddr, wq->rq.rqt_size); |
48 | kfree(wq->rq.sw_rq); | 103 | kfree(wq->rq.sw_rq); |
49 | kfree(wq->sq.sw_sq); | 104 | kfree(wq->sq.sw_sq); |
@@ -93,11 +148,12 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq, | |||
93 | if (!wq->rq.rqt_hwaddr) | 148 | if (!wq->rq.rqt_hwaddr) |
94 | goto err4; | 149 | goto err4; |
95 | 150 | ||
96 | wq->sq.queue = dma_alloc_coherent(&(rdev->lldi.pdev->dev), | 151 | if (user) { |
97 | wq->sq.memsize, &(wq->sq.dma_addr), | 152 | if (alloc_oc_sq(rdev, &wq->sq) && alloc_host_sq(rdev, &wq->sq)) |
98 | GFP_KERNEL); | 153 | goto err5; |
99 | if (!wq->sq.queue) | 154 | } else |
100 | goto err5; | 155 | if (alloc_host_sq(rdev, &wq->sq)) |
156 | goto err5; | ||
101 | memset(wq->sq.queue, 0, wq->sq.memsize); | 157 | memset(wq->sq.queue, 0, wq->sq.memsize); |
102 | dma_unmap_addr_set(&wq->sq, mapping, wq->sq.dma_addr); | 158 | dma_unmap_addr_set(&wq->sq, mapping, wq->sq.dma_addr); |
103 | 159 | ||
@@ -144,7 +200,7 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq, | |||
144 | V_FW_RI_RES_WR_NRES(2) | | 200 | V_FW_RI_RES_WR_NRES(2) | |
145 | FW_WR_COMPL(1)); | 201 | FW_WR_COMPL(1)); |
146 | res_wr->len16_pkd = cpu_to_be32(DIV_ROUND_UP(wr_len, 16)); | 202 | res_wr->len16_pkd = cpu_to_be32(DIV_ROUND_UP(wr_len, 16)); |
147 | res_wr->cookie = (u64)&wr_wait; | 203 | res_wr->cookie = (unsigned long) &wr_wait; |
148 | res = res_wr->res; | 204 | res = res_wr->res; |
149 | res->u.sqrq.restype = FW_RI_RES_TYPE_SQ; | 205 | res->u.sqrq.restype = FW_RI_RES_TYPE_SQ; |
150 | res->u.sqrq.op = FW_RI_RES_OP_WRITE; | 206 | res->u.sqrq.op = FW_RI_RES_OP_WRITE; |
@@ -158,6 +214,7 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq, | |||
158 | V_FW_RI_RES_WR_HOSTFCMODE(0) | /* no host cidx updates */ | 214 | V_FW_RI_RES_WR_HOSTFCMODE(0) | /* no host cidx updates */ |
159 | V_FW_RI_RES_WR_CPRIO(0) | /* don't keep in chip cache */ | 215 | V_FW_RI_RES_WR_CPRIO(0) | /* don't keep in chip cache */ |
160 | V_FW_RI_RES_WR_PCIECHN(0) | /* set by uP at ri_init time */ | 216 | V_FW_RI_RES_WR_PCIECHN(0) | /* set by uP at ri_init time */ |
217 | t4_sq_onchip(&wq->sq) ? F_FW_RI_RES_WR_ONCHIP : 0 | | ||
161 | V_FW_RI_RES_WR_IQID(scq->cqid)); | 218 | V_FW_RI_RES_WR_IQID(scq->cqid)); |
162 | res->u.sqrq.dcaen_to_eqsize = cpu_to_be32( | 219 | res->u.sqrq.dcaen_to_eqsize = cpu_to_be32( |
163 | V_FW_RI_RES_WR_DCAEN(0) | | 220 | V_FW_RI_RES_WR_DCAEN(0) | |
@@ -198,14 +255,7 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq, | |||
198 | ret = c4iw_ofld_send(rdev, skb); | 255 | ret = c4iw_ofld_send(rdev, skb); |
199 | if (ret) | 256 | if (ret) |
200 | goto err7; | 257 | goto err7; |
201 | wait_event_timeout(wr_wait.wait, wr_wait.done, C4IW_WR_TO); | 258 | ret = c4iw_wait_for_reply(rdev, &wr_wait, 0, wq->sq.qid, __func__); |
202 | if (!wr_wait.done) { | ||
203 | printk(KERN_ERR MOD "Device %s not responding!\n", | ||
204 | pci_name(rdev->lldi.pdev)); | ||
205 | rdev->flags = T4_FATAL_ERROR; | ||
206 | ret = -EIO; | ||
207 | } else | ||
208 | ret = wr_wait.ret; | ||
209 | if (ret) | 259 | if (ret) |
210 | goto err7; | 260 | goto err7; |
211 | 261 | ||
@@ -219,9 +269,7 @@ err7: | |||
219 | wq->rq.memsize, wq->rq.queue, | 269 | wq->rq.memsize, wq->rq.queue, |
220 | dma_unmap_addr(&wq->rq, mapping)); | 270 | dma_unmap_addr(&wq->rq, mapping)); |
221 | err6: | 271 | err6: |
222 | dma_free_coherent(&(rdev->lldi.pdev->dev), | 272 | dealloc_sq(rdev, &wq->sq); |
223 | wq->sq.memsize, wq->sq.queue, | ||
224 | dma_unmap_addr(&wq->sq, mapping)); | ||
225 | err5: | 273 | err5: |
226 | c4iw_rqtpool_free(rdev, wq->rq.rqt_hwaddr, wq->rq.rqt_size); | 274 | c4iw_rqtpool_free(rdev, wq->rq.rqt_hwaddr, wq->rq.rqt_size); |
227 | err4: | 275 | err4: |
@@ -263,6 +311,9 @@ static int build_immd(struct t4_sq *sq, struct fw_ri_immd *immdp, | |||
263 | rem -= len; | 311 | rem -= len; |
264 | } | 312 | } |
265 | } | 313 | } |
314 | len = roundup(plen + sizeof *immdp, 16) - (plen + sizeof *immdp); | ||
315 | if (len) | ||
316 | memset(dstp, 0, len); | ||
266 | immdp->op = FW_RI_DATA_IMMD; | 317 | immdp->op = FW_RI_DATA_IMMD; |
267 | immdp->r1 = 0; | 318 | immdp->r1 = 0; |
268 | immdp->r2 = 0; | 319 | immdp->r2 = 0; |
@@ -292,6 +343,7 @@ static int build_isgl(__be64 *queue_start, __be64 *queue_end, | |||
292 | if (++flitp == queue_end) | 343 | if (++flitp == queue_end) |
293 | flitp = queue_start; | 344 | flitp = queue_start; |
294 | } | 345 | } |
346 | *flitp = (__force __be64)0; | ||
295 | isglp->op = FW_RI_DATA_ISGL; | 347 | isglp->op = FW_RI_DATA_ISGL; |
296 | isglp->r1 = 0; | 348 | isglp->r1 = 0; |
297 | isglp->nsge = cpu_to_be16(num_sge); | 349 | isglp->nsge = cpu_to_be16(num_sge); |
@@ -453,13 +505,15 @@ static int build_rdma_recv(struct c4iw_qp *qhp, union t4_recv_wr *wqe, | |||
453 | return 0; | 505 | return 0; |
454 | } | 506 | } |
455 | 507 | ||
456 | static int build_fastreg(union t4_wr *wqe, struct ib_send_wr *wr, u8 *len16) | 508 | static int build_fastreg(struct t4_sq *sq, union t4_wr *wqe, |
509 | struct ib_send_wr *wr, u8 *len16) | ||
457 | { | 510 | { |
458 | 511 | ||
459 | struct fw_ri_immd *imdp; | 512 | struct fw_ri_immd *imdp; |
460 | __be64 *p; | 513 | __be64 *p; |
461 | int i; | 514 | int i; |
462 | int pbllen = roundup(wr->wr.fast_reg.page_list_len * sizeof(u64), 32); | 515 | int pbllen = roundup(wr->wr.fast_reg.page_list_len * sizeof(u64), 32); |
516 | int rem; | ||
463 | 517 | ||
464 | if (wr->wr.fast_reg.page_list_len > T4_MAX_FR_DEPTH) | 518 | if (wr->wr.fast_reg.page_list_len > T4_MAX_FR_DEPTH) |
465 | return -EINVAL; | 519 | return -EINVAL; |
@@ -474,32 +528,28 @@ static int build_fastreg(union t4_wr *wqe, struct ib_send_wr *wr, u8 *len16) | |||
474 | wqe->fr.va_hi = cpu_to_be32(wr->wr.fast_reg.iova_start >> 32); | 528 | wqe->fr.va_hi = cpu_to_be32(wr->wr.fast_reg.iova_start >> 32); |
475 | wqe->fr.va_lo_fbo = cpu_to_be32(wr->wr.fast_reg.iova_start & | 529 | wqe->fr.va_lo_fbo = cpu_to_be32(wr->wr.fast_reg.iova_start & |
476 | 0xffffffff); | 530 | 0xffffffff); |
477 | if (pbllen > T4_MAX_FR_IMMD) { | 531 | WARN_ON(pbllen > T4_MAX_FR_IMMD); |
478 | struct c4iw_fr_page_list *c4pl = | 532 | imdp = (struct fw_ri_immd *)(&wqe->fr + 1); |
479 | to_c4iw_fr_page_list(wr->wr.fast_reg.page_list); | 533 | imdp->op = FW_RI_DATA_IMMD; |
480 | struct fw_ri_dsgl *sglp; | 534 | imdp->r1 = 0; |
481 | 535 | imdp->r2 = 0; | |
482 | sglp = (struct fw_ri_dsgl *)(&wqe->fr + 1); | 536 | imdp->immdlen = cpu_to_be32(pbllen); |
483 | sglp->op = FW_RI_DATA_DSGL; | 537 | p = (__be64 *)(imdp + 1); |
484 | sglp->r1 = 0; | 538 | rem = pbllen; |
485 | sglp->nsge = cpu_to_be16(1); | 539 | for (i = 0; i < wr->wr.fast_reg.page_list_len; i++) { |
486 | sglp->addr0 = cpu_to_be64(c4pl->dma_addr); | 540 | *p = cpu_to_be64((u64)wr->wr.fast_reg.page_list->page_list[i]); |
487 | sglp->len0 = cpu_to_be32(pbllen); | 541 | rem -= sizeof *p; |
488 | 542 | if (++p == (__be64 *)&sq->queue[sq->size]) | |
489 | *len16 = DIV_ROUND_UP(sizeof wqe->fr + sizeof *sglp, 16); | 543 | p = (__be64 *)sq->queue; |
490 | } else { | ||
491 | imdp = (struct fw_ri_immd *)(&wqe->fr + 1); | ||
492 | imdp->op = FW_RI_DATA_IMMD; | ||
493 | imdp->r1 = 0; | ||
494 | imdp->r2 = 0; | ||
495 | imdp->immdlen = cpu_to_be32(pbllen); | ||
496 | p = (__be64 *)(imdp + 1); | ||
497 | for (i = 0; i < wr->wr.fast_reg.page_list_len; i++, p++) | ||
498 | *p = cpu_to_be64( | ||
499 | (u64)wr->wr.fast_reg.page_list->page_list[i]); | ||
500 | *len16 = DIV_ROUND_UP(sizeof wqe->fr + sizeof *imdp + pbllen, | ||
501 | 16); | ||
502 | } | 544 | } |
545 | BUG_ON(rem < 0); | ||
546 | while (rem) { | ||
547 | *p = 0; | ||
548 | rem -= sizeof *p; | ||
549 | if (++p == (__be64 *)&sq->queue[sq->size]) | ||
550 | p = (__be64 *)sq->queue; | ||
551 | } | ||
552 | *len16 = DIV_ROUND_UP(sizeof wqe->fr + sizeof *imdp + pbllen, 16); | ||
503 | return 0; | 553 | return 0; |
504 | } | 554 | } |
505 | 555 | ||
@@ -587,7 +637,7 @@ int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
587 | fw_opcode = FW_RI_RDMA_READ_WR; | 637 | fw_opcode = FW_RI_RDMA_READ_WR; |
588 | swsqe->opcode = FW_RI_READ_REQ; | 638 | swsqe->opcode = FW_RI_READ_REQ; |
589 | if (wr->opcode == IB_WR_RDMA_READ_WITH_INV) | 639 | if (wr->opcode == IB_WR_RDMA_READ_WITH_INV) |
590 | fw_flags |= FW_RI_RDMA_READ_INVALIDATE; | 640 | fw_flags = FW_RI_RDMA_READ_INVALIDATE; |
591 | else | 641 | else |
592 | fw_flags = 0; | 642 | fw_flags = 0; |
593 | err = build_rdma_read(wqe, wr, &len16); | 643 | err = build_rdma_read(wqe, wr, &len16); |
@@ -600,7 +650,7 @@ int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
600 | case IB_WR_FAST_REG_MR: | 650 | case IB_WR_FAST_REG_MR: |
601 | fw_opcode = FW_RI_FR_NSMR_WR; | 651 | fw_opcode = FW_RI_FR_NSMR_WR; |
602 | swsqe->opcode = FW_RI_FAST_REGISTER; | 652 | swsqe->opcode = FW_RI_FAST_REGISTER; |
603 | err = build_fastreg(wqe, wr, &len16); | 653 | err = build_fastreg(&qhp->wq.sq, wqe, wr, &len16); |
604 | break; | 654 | break; |
605 | case IB_WR_LOCAL_INV: | 655 | case IB_WR_LOCAL_INV: |
606 | if (wr->send_flags & IB_SEND_FENCE) | 656 | if (wr->send_flags & IB_SEND_FENCE) |
@@ -905,46 +955,38 @@ static void post_terminate(struct c4iw_qp *qhp, struct t4_cqe *err_cqe, | |||
905 | * Assumes qhp lock is held. | 955 | * Assumes qhp lock is held. |
906 | */ | 956 | */ |
907 | static void __flush_qp(struct c4iw_qp *qhp, struct c4iw_cq *rchp, | 957 | static void __flush_qp(struct c4iw_qp *qhp, struct c4iw_cq *rchp, |
908 | struct c4iw_cq *schp, unsigned long *flag) | 958 | struct c4iw_cq *schp) |
909 | { | 959 | { |
910 | int count; | 960 | int count; |
911 | int flushed; | 961 | int flushed; |
962 | unsigned long flag; | ||
912 | 963 | ||
913 | PDBG("%s qhp %p rchp %p schp %p\n", __func__, qhp, rchp, schp); | 964 | PDBG("%s qhp %p rchp %p schp %p\n", __func__, qhp, rchp, schp); |
914 | /* take a ref on the qhp since we must release the lock */ | ||
915 | atomic_inc(&qhp->refcnt); | ||
916 | spin_unlock_irqrestore(&qhp->lock, *flag); | ||
917 | 965 | ||
918 | /* locking hierarchy: cq lock first, then qp lock. */ | 966 | /* locking hierarchy: cq lock first, then qp lock. */ |
919 | spin_lock_irqsave(&rchp->lock, *flag); | 967 | spin_lock_irqsave(&rchp->lock, flag); |
920 | spin_lock(&qhp->lock); | 968 | spin_lock(&qhp->lock); |
921 | c4iw_flush_hw_cq(&rchp->cq); | 969 | c4iw_flush_hw_cq(&rchp->cq); |
922 | c4iw_count_rcqes(&rchp->cq, &qhp->wq, &count); | 970 | c4iw_count_rcqes(&rchp->cq, &qhp->wq, &count); |
923 | flushed = c4iw_flush_rq(&qhp->wq, &rchp->cq, count); | 971 | flushed = c4iw_flush_rq(&qhp->wq, &rchp->cq, count); |
924 | spin_unlock(&qhp->lock); | 972 | spin_unlock(&qhp->lock); |
925 | spin_unlock_irqrestore(&rchp->lock, *flag); | 973 | spin_unlock_irqrestore(&rchp->lock, flag); |
926 | if (flushed) | 974 | if (flushed) |
927 | (*rchp->ibcq.comp_handler)(&rchp->ibcq, rchp->ibcq.cq_context); | 975 | (*rchp->ibcq.comp_handler)(&rchp->ibcq, rchp->ibcq.cq_context); |
928 | 976 | ||
929 | /* locking hierarchy: cq lock first, then qp lock. */ | 977 | /* locking hierarchy: cq lock first, then qp lock. */ |
930 | spin_lock_irqsave(&schp->lock, *flag); | 978 | spin_lock_irqsave(&schp->lock, flag); |
931 | spin_lock(&qhp->lock); | 979 | spin_lock(&qhp->lock); |
932 | c4iw_flush_hw_cq(&schp->cq); | 980 | c4iw_flush_hw_cq(&schp->cq); |
933 | c4iw_count_scqes(&schp->cq, &qhp->wq, &count); | 981 | c4iw_count_scqes(&schp->cq, &qhp->wq, &count); |
934 | flushed = c4iw_flush_sq(&qhp->wq, &schp->cq, count); | 982 | flushed = c4iw_flush_sq(&qhp->wq, &schp->cq, count); |
935 | spin_unlock(&qhp->lock); | 983 | spin_unlock(&qhp->lock); |
936 | spin_unlock_irqrestore(&schp->lock, *flag); | 984 | spin_unlock_irqrestore(&schp->lock, flag); |
937 | if (flushed) | 985 | if (flushed) |
938 | (*schp->ibcq.comp_handler)(&schp->ibcq, schp->ibcq.cq_context); | 986 | (*schp->ibcq.comp_handler)(&schp->ibcq, schp->ibcq.cq_context); |
939 | |||
940 | /* deref */ | ||
941 | if (atomic_dec_and_test(&qhp->refcnt)) | ||
942 | wake_up(&qhp->wait); | ||
943 | |||
944 | spin_lock_irqsave(&qhp->lock, *flag); | ||
945 | } | 987 | } |
946 | 988 | ||
947 | static void flush_qp(struct c4iw_qp *qhp, unsigned long *flag) | 989 | static void flush_qp(struct c4iw_qp *qhp) |
948 | { | 990 | { |
949 | struct c4iw_cq *rchp, *schp; | 991 | struct c4iw_cq *rchp, *schp; |
950 | 992 | ||
@@ -958,7 +1000,7 @@ static void flush_qp(struct c4iw_qp *qhp, unsigned long *flag) | |||
958 | t4_set_cq_in_error(&schp->cq); | 1000 | t4_set_cq_in_error(&schp->cq); |
959 | return; | 1001 | return; |
960 | } | 1002 | } |
961 | __flush_qp(qhp, rchp, schp, flag); | 1003 | __flush_qp(qhp, rchp, schp); |
962 | } | 1004 | } |
963 | 1005 | ||
964 | static int rdma_fini(struct c4iw_dev *rhp, struct c4iw_qp *qhp, | 1006 | static int rdma_fini(struct c4iw_dev *rhp, struct c4iw_qp *qhp, |
@@ -966,7 +1008,6 @@ static int rdma_fini(struct c4iw_dev *rhp, struct c4iw_qp *qhp, | |||
966 | { | 1008 | { |
967 | struct fw_ri_wr *wqe; | 1009 | struct fw_ri_wr *wqe; |
968 | int ret; | 1010 | int ret; |
969 | struct c4iw_wr_wait wr_wait; | ||
970 | struct sk_buff *skb; | 1011 | struct sk_buff *skb; |
971 | 1012 | ||
972 | PDBG("%s qhp %p qid 0x%x tid %u\n", __func__, qhp, qhp->wq.sq.qid, | 1013 | PDBG("%s qhp %p qid 0x%x tid %u\n", __func__, qhp, qhp->wq.sq.qid, |
@@ -985,28 +1026,16 @@ static int rdma_fini(struct c4iw_dev *rhp, struct c4iw_qp *qhp, | |||
985 | wqe->flowid_len16 = cpu_to_be32( | 1026 | wqe->flowid_len16 = cpu_to_be32( |
986 | FW_WR_FLOWID(ep->hwtid) | | 1027 | FW_WR_FLOWID(ep->hwtid) | |
987 | FW_WR_LEN16(DIV_ROUND_UP(sizeof *wqe, 16))); | 1028 | FW_WR_LEN16(DIV_ROUND_UP(sizeof *wqe, 16))); |
988 | wqe->cookie = (u64)&wr_wait; | 1029 | wqe->cookie = (unsigned long) &ep->com.wr_wait; |
989 | 1030 | ||
990 | wqe->u.fini.type = FW_RI_TYPE_FINI; | 1031 | wqe->u.fini.type = FW_RI_TYPE_FINI; |
991 | c4iw_init_wr_wait(&wr_wait); | 1032 | c4iw_init_wr_wait(&ep->com.wr_wait); |
992 | ret = c4iw_ofld_send(&rhp->rdev, skb); | 1033 | ret = c4iw_ofld_send(&rhp->rdev, skb); |
993 | if (ret) | 1034 | if (ret) |
994 | goto out; | 1035 | goto out; |
995 | 1036 | ||
996 | wait_event_timeout(wr_wait.wait, wr_wait.done, C4IW_WR_TO); | 1037 | ret = c4iw_wait_for_reply(&rhp->rdev, &ep->com.wr_wait, qhp->ep->hwtid, |
997 | if (!wr_wait.done) { | 1038 | qhp->wq.sq.qid, __func__); |
998 | printk(KERN_ERR MOD "Device %s not responding!\n", | ||
999 | pci_name(rhp->rdev.lldi.pdev)); | ||
1000 | rhp->rdev.flags = T4_FATAL_ERROR; | ||
1001 | ret = -EIO; | ||
1002 | } else { | ||
1003 | ret = wr_wait.ret; | ||
1004 | if (ret) | ||
1005 | printk(KERN_WARNING MOD | ||
1006 | "%s: Abnormal close qpid %d ret %u\n", | ||
1007 | pci_name(rhp->rdev.lldi.pdev), qhp->wq.sq.qid, | ||
1008 | ret); | ||
1009 | } | ||
1010 | out: | 1039 | out: |
1011 | PDBG("%s ret %d\n", __func__, ret); | 1040 | PDBG("%s ret %d\n", __func__, ret); |
1012 | return ret; | 1041 | return ret; |
@@ -1040,7 +1069,6 @@ static int rdma_init(struct c4iw_dev *rhp, struct c4iw_qp *qhp) | |||
1040 | { | 1069 | { |
1041 | struct fw_ri_wr *wqe; | 1070 | struct fw_ri_wr *wqe; |
1042 | int ret; | 1071 | int ret; |
1043 | struct c4iw_wr_wait wr_wait; | ||
1044 | struct sk_buff *skb; | 1072 | struct sk_buff *skb; |
1045 | 1073 | ||
1046 | PDBG("%s qhp %p qid 0x%x tid %u\n", __func__, qhp, qhp->wq.sq.qid, | 1074 | PDBG("%s qhp %p qid 0x%x tid %u\n", __func__, qhp, qhp->wq.sq.qid, |
@@ -1060,7 +1088,7 @@ static int rdma_init(struct c4iw_dev *rhp, struct c4iw_qp *qhp) | |||
1060 | FW_WR_FLOWID(qhp->ep->hwtid) | | 1088 | FW_WR_FLOWID(qhp->ep->hwtid) | |
1061 | FW_WR_LEN16(DIV_ROUND_UP(sizeof *wqe, 16))); | 1089 | FW_WR_LEN16(DIV_ROUND_UP(sizeof *wqe, 16))); |
1062 | 1090 | ||
1063 | wqe->cookie = (u64)&wr_wait; | 1091 | wqe->cookie = (unsigned long) &qhp->ep->com.wr_wait; |
1064 | 1092 | ||
1065 | wqe->u.init.type = FW_RI_TYPE_INIT; | 1093 | wqe->u.init.type = FW_RI_TYPE_INIT; |
1066 | wqe->u.init.mpareqbit_p2ptype = | 1094 | wqe->u.init.mpareqbit_p2ptype = |
@@ -1097,19 +1125,13 @@ static int rdma_init(struct c4iw_dev *rhp, struct c4iw_qp *qhp) | |||
1097 | if (qhp->attr.mpa_attr.initiator) | 1125 | if (qhp->attr.mpa_attr.initiator) |
1098 | build_rtr_msg(qhp->attr.mpa_attr.p2p_type, &wqe->u.init); | 1126 | build_rtr_msg(qhp->attr.mpa_attr.p2p_type, &wqe->u.init); |
1099 | 1127 | ||
1100 | c4iw_init_wr_wait(&wr_wait); | 1128 | c4iw_init_wr_wait(&qhp->ep->com.wr_wait); |
1101 | ret = c4iw_ofld_send(&rhp->rdev, skb); | 1129 | ret = c4iw_ofld_send(&rhp->rdev, skb); |
1102 | if (ret) | 1130 | if (ret) |
1103 | goto out; | 1131 | goto out; |
1104 | 1132 | ||
1105 | wait_event_timeout(wr_wait.wait, wr_wait.done, C4IW_WR_TO); | 1133 | ret = c4iw_wait_for_reply(&rhp->rdev, &qhp->ep->com.wr_wait, |
1106 | if (!wr_wait.done) { | 1134 | qhp->ep->hwtid, qhp->wq.sq.qid, __func__); |
1107 | printk(KERN_ERR MOD "Device %s not responding!\n", | ||
1108 | pci_name(rhp->rdev.lldi.pdev)); | ||
1109 | rhp->rdev.flags = T4_FATAL_ERROR; | ||
1110 | ret = -EIO; | ||
1111 | } else | ||
1112 | ret = wr_wait.ret; | ||
1113 | out: | 1135 | out: |
1114 | PDBG("%s ret %d\n", __func__, ret); | 1136 | PDBG("%s ret %d\n", __func__, ret); |
1115 | return ret; | 1137 | return ret; |
@@ -1122,7 +1144,6 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, | |||
1122 | { | 1144 | { |
1123 | int ret = 0; | 1145 | int ret = 0; |
1124 | struct c4iw_qp_attributes newattr = qhp->attr; | 1146 | struct c4iw_qp_attributes newattr = qhp->attr; |
1125 | unsigned long flag; | ||
1126 | int disconnect = 0; | 1147 | int disconnect = 0; |
1127 | int terminate = 0; | 1148 | int terminate = 0; |
1128 | int abort = 0; | 1149 | int abort = 0; |
@@ -1133,7 +1154,7 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, | |||
1133 | qhp, qhp->wq.sq.qid, qhp->wq.rq.qid, qhp->ep, qhp->attr.state, | 1154 | qhp, qhp->wq.sq.qid, qhp->wq.rq.qid, qhp->ep, qhp->attr.state, |
1134 | (mask & C4IW_QP_ATTR_NEXT_STATE) ? attrs->next_state : -1); | 1155 | (mask & C4IW_QP_ATTR_NEXT_STATE) ? attrs->next_state : -1); |
1135 | 1156 | ||
1136 | spin_lock_irqsave(&qhp->lock, flag); | 1157 | mutex_lock(&qhp->mutex); |
1137 | 1158 | ||
1138 | /* Process attr changes if in IDLE */ | 1159 | /* Process attr changes if in IDLE */ |
1139 | if (mask & C4IW_QP_ATTR_VALID_MODIFY) { | 1160 | if (mask & C4IW_QP_ATTR_VALID_MODIFY) { |
@@ -1184,7 +1205,7 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, | |||
1184 | qhp->attr.mpa_attr = attrs->mpa_attr; | 1205 | qhp->attr.mpa_attr = attrs->mpa_attr; |
1185 | qhp->attr.llp_stream_handle = attrs->llp_stream_handle; | 1206 | qhp->attr.llp_stream_handle = attrs->llp_stream_handle; |
1186 | qhp->ep = qhp->attr.llp_stream_handle; | 1207 | qhp->ep = qhp->attr.llp_stream_handle; |
1187 | qhp->attr.state = C4IW_QP_STATE_RTS; | 1208 | set_state(qhp, C4IW_QP_STATE_RTS); |
1188 | 1209 | ||
1189 | /* | 1210 | /* |
1190 | * Ref the endpoint here and deref when we | 1211 | * Ref the endpoint here and deref when we |
@@ -1193,15 +1214,13 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, | |||
1193 | * transition. | 1214 | * transition. |
1194 | */ | 1215 | */ |
1195 | c4iw_get_ep(&qhp->ep->com); | 1216 | c4iw_get_ep(&qhp->ep->com); |
1196 | spin_unlock_irqrestore(&qhp->lock, flag); | ||
1197 | ret = rdma_init(rhp, qhp); | 1217 | ret = rdma_init(rhp, qhp); |
1198 | spin_lock_irqsave(&qhp->lock, flag); | ||
1199 | if (ret) | 1218 | if (ret) |
1200 | goto err; | 1219 | goto err; |
1201 | break; | 1220 | break; |
1202 | case C4IW_QP_STATE_ERROR: | 1221 | case C4IW_QP_STATE_ERROR: |
1203 | qhp->attr.state = C4IW_QP_STATE_ERROR; | 1222 | set_state(qhp, C4IW_QP_STATE_ERROR); |
1204 | flush_qp(qhp, &flag); | 1223 | flush_qp(qhp); |
1205 | break; | 1224 | break; |
1206 | default: | 1225 | default: |
1207 | ret = -EINVAL; | 1226 | ret = -EINVAL; |
@@ -1212,38 +1231,38 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, | |||
1212 | switch (attrs->next_state) { | 1231 | switch (attrs->next_state) { |
1213 | case C4IW_QP_STATE_CLOSING: | 1232 | case C4IW_QP_STATE_CLOSING: |
1214 | BUG_ON(atomic_read(&qhp->ep->com.kref.refcount) < 2); | 1233 | BUG_ON(atomic_read(&qhp->ep->com.kref.refcount) < 2); |
1215 | qhp->attr.state = C4IW_QP_STATE_CLOSING; | 1234 | set_state(qhp, C4IW_QP_STATE_CLOSING); |
1216 | ep = qhp->ep; | 1235 | ep = qhp->ep; |
1217 | if (!internal) { | 1236 | if (!internal) { |
1218 | abort = 0; | 1237 | abort = 0; |
1219 | disconnect = 1; | 1238 | disconnect = 1; |
1220 | c4iw_get_ep(&ep->com); | 1239 | c4iw_get_ep(&qhp->ep->com); |
1221 | } | 1240 | } |
1222 | spin_unlock_irqrestore(&qhp->lock, flag); | ||
1223 | ret = rdma_fini(rhp, qhp, ep); | 1241 | ret = rdma_fini(rhp, qhp, ep); |
1224 | spin_lock_irqsave(&qhp->lock, flag); | ||
1225 | if (ret) { | 1242 | if (ret) { |
1226 | c4iw_get_ep(&ep->com); | 1243 | if (internal) |
1244 | c4iw_get_ep(&qhp->ep->com); | ||
1227 | disconnect = abort = 1; | 1245 | disconnect = abort = 1; |
1228 | goto err; | 1246 | goto err; |
1229 | } | 1247 | } |
1230 | break; | 1248 | break; |
1231 | case C4IW_QP_STATE_TERMINATE: | 1249 | case C4IW_QP_STATE_TERMINATE: |
1232 | qhp->attr.state = C4IW_QP_STATE_TERMINATE; | 1250 | set_state(qhp, C4IW_QP_STATE_TERMINATE); |
1233 | if (qhp->ibqp.uobject) | 1251 | if (qhp->ibqp.uobject) |
1234 | t4_set_wq_in_error(&qhp->wq); | 1252 | t4_set_wq_in_error(&qhp->wq); |
1235 | ep = qhp->ep; | 1253 | ep = qhp->ep; |
1236 | c4iw_get_ep(&ep->com); | 1254 | if (!internal) |
1237 | terminate = 1; | 1255 | terminate = 1; |
1238 | disconnect = 1; | 1256 | disconnect = 1; |
1257 | c4iw_get_ep(&qhp->ep->com); | ||
1239 | break; | 1258 | break; |
1240 | case C4IW_QP_STATE_ERROR: | 1259 | case C4IW_QP_STATE_ERROR: |
1241 | qhp->attr.state = C4IW_QP_STATE_ERROR; | 1260 | set_state(qhp, C4IW_QP_STATE_ERROR); |
1242 | if (!internal) { | 1261 | if (!internal) { |
1243 | abort = 1; | 1262 | abort = 1; |
1244 | disconnect = 1; | 1263 | disconnect = 1; |
1245 | ep = qhp->ep; | 1264 | ep = qhp->ep; |
1246 | c4iw_get_ep(&ep->com); | 1265 | c4iw_get_ep(&qhp->ep->com); |
1247 | } | 1266 | } |
1248 | goto err; | 1267 | goto err; |
1249 | break; | 1268 | break; |
@@ -1259,8 +1278,8 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, | |||
1259 | } | 1278 | } |
1260 | switch (attrs->next_state) { | 1279 | switch (attrs->next_state) { |
1261 | case C4IW_QP_STATE_IDLE: | 1280 | case C4IW_QP_STATE_IDLE: |
1262 | flush_qp(qhp, &flag); | 1281 | flush_qp(qhp); |
1263 | qhp->attr.state = C4IW_QP_STATE_IDLE; | 1282 | set_state(qhp, C4IW_QP_STATE_IDLE); |
1264 | qhp->attr.llp_stream_handle = NULL; | 1283 | qhp->attr.llp_stream_handle = NULL; |
1265 | c4iw_put_ep(&qhp->ep->com); | 1284 | c4iw_put_ep(&qhp->ep->com); |
1266 | qhp->ep = NULL; | 1285 | qhp->ep = NULL; |
@@ -1282,7 +1301,7 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, | |||
1282 | ret = -EINVAL; | 1301 | ret = -EINVAL; |
1283 | goto out; | 1302 | goto out; |
1284 | } | 1303 | } |
1285 | qhp->attr.state = C4IW_QP_STATE_IDLE; | 1304 | set_state(qhp, C4IW_QP_STATE_IDLE); |
1286 | break; | 1305 | break; |
1287 | case C4IW_QP_STATE_TERMINATE: | 1306 | case C4IW_QP_STATE_TERMINATE: |
1288 | if (!internal) { | 1307 | if (!internal) { |
@@ -1305,15 +1324,16 @@ err: | |||
1305 | 1324 | ||
1306 | /* disassociate the LLP connection */ | 1325 | /* disassociate the LLP connection */ |
1307 | qhp->attr.llp_stream_handle = NULL; | 1326 | qhp->attr.llp_stream_handle = NULL; |
1308 | ep = qhp->ep; | 1327 | if (!ep) |
1328 | ep = qhp->ep; | ||
1309 | qhp->ep = NULL; | 1329 | qhp->ep = NULL; |
1310 | qhp->attr.state = C4IW_QP_STATE_ERROR; | 1330 | set_state(qhp, C4IW_QP_STATE_ERROR); |
1311 | free = 1; | 1331 | free = 1; |
1312 | wake_up(&qhp->wait); | 1332 | wake_up(&qhp->wait); |
1313 | BUG_ON(!ep); | 1333 | BUG_ON(!ep); |
1314 | flush_qp(qhp, &flag); | 1334 | flush_qp(qhp); |
1315 | out: | 1335 | out: |
1316 | spin_unlock_irqrestore(&qhp->lock, flag); | 1336 | mutex_unlock(&qhp->mutex); |
1317 | 1337 | ||
1318 | if (terminate) | 1338 | if (terminate) |
1319 | post_terminate(qhp, NULL, internal ? GFP_ATOMIC : GFP_KERNEL); | 1339 | post_terminate(qhp, NULL, internal ? GFP_ATOMIC : GFP_KERNEL); |
@@ -1335,7 +1355,6 @@ out: | |||
1335 | */ | 1355 | */ |
1336 | if (free) | 1356 | if (free) |
1337 | c4iw_put_ep(&ep->com); | 1357 | c4iw_put_ep(&ep->com); |
1338 | |||
1339 | PDBG("%s exit state %d\n", __func__, qhp->attr.state); | 1358 | PDBG("%s exit state %d\n", __func__, qhp->attr.state); |
1340 | return ret; | 1359 | return ret; |
1341 | } | 1360 | } |
@@ -1380,7 +1399,7 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs, | |||
1380 | int sqsize, rqsize; | 1399 | int sqsize, rqsize; |
1381 | struct c4iw_ucontext *ucontext; | 1400 | struct c4iw_ucontext *ucontext; |
1382 | int ret; | 1401 | int ret; |
1383 | struct c4iw_mm_entry *mm1, *mm2, *mm3, *mm4; | 1402 | struct c4iw_mm_entry *mm1, *mm2, *mm3, *mm4, *mm5 = NULL; |
1384 | 1403 | ||
1385 | PDBG("%s ib_pd %p\n", __func__, pd); | 1404 | PDBG("%s ib_pd %p\n", __func__, pd); |
1386 | 1405 | ||
@@ -1450,6 +1469,7 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs, | |||
1450 | qhp->attr.max_ord = 1; | 1469 | qhp->attr.max_ord = 1; |
1451 | qhp->attr.max_ird = 1; | 1470 | qhp->attr.max_ird = 1; |
1452 | spin_lock_init(&qhp->lock); | 1471 | spin_lock_init(&qhp->lock); |
1472 | mutex_init(&qhp->mutex); | ||
1453 | init_waitqueue_head(&qhp->wait); | 1473 | init_waitqueue_head(&qhp->wait); |
1454 | atomic_set(&qhp->refcnt, 1); | 1474 | atomic_set(&qhp->refcnt, 1); |
1455 | 1475 | ||
@@ -1478,7 +1498,15 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs, | |||
1478 | ret = -ENOMEM; | 1498 | ret = -ENOMEM; |
1479 | goto err6; | 1499 | goto err6; |
1480 | } | 1500 | } |
1481 | 1501 | if (t4_sq_onchip(&qhp->wq.sq)) { | |
1502 | mm5 = kmalloc(sizeof *mm5, GFP_KERNEL); | ||
1503 | if (!mm5) { | ||
1504 | ret = -ENOMEM; | ||
1505 | goto err7; | ||
1506 | } | ||
1507 | uresp.flags = C4IW_QPF_ONCHIP; | ||
1508 | } else | ||
1509 | uresp.flags = 0; | ||
1482 | uresp.qid_mask = rhp->rdev.qpmask; | 1510 | uresp.qid_mask = rhp->rdev.qpmask; |
1483 | uresp.sqid = qhp->wq.sq.qid; | 1511 | uresp.sqid = qhp->wq.sq.qid; |
1484 | uresp.sq_size = qhp->wq.sq.size; | 1512 | uresp.sq_size = qhp->wq.sq.size; |
@@ -1487,6 +1515,10 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs, | |||
1487 | uresp.rq_size = qhp->wq.rq.size; | 1515 | uresp.rq_size = qhp->wq.rq.size; |
1488 | uresp.rq_memsize = qhp->wq.rq.memsize; | 1516 | uresp.rq_memsize = qhp->wq.rq.memsize; |
1489 | spin_lock(&ucontext->mmap_lock); | 1517 | spin_lock(&ucontext->mmap_lock); |
1518 | if (mm5) { | ||
1519 | uresp.ma_sync_key = ucontext->key; | ||
1520 | ucontext->key += PAGE_SIZE; | ||
1521 | } | ||
1490 | uresp.sq_key = ucontext->key; | 1522 | uresp.sq_key = ucontext->key; |
1491 | ucontext->key += PAGE_SIZE; | 1523 | ucontext->key += PAGE_SIZE; |
1492 | uresp.rq_key = ucontext->key; | 1524 | uresp.rq_key = ucontext->key; |
@@ -1498,9 +1530,9 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs, | |||
1498 | spin_unlock(&ucontext->mmap_lock); | 1530 | spin_unlock(&ucontext->mmap_lock); |
1499 | ret = ib_copy_to_udata(udata, &uresp, sizeof uresp); | 1531 | ret = ib_copy_to_udata(udata, &uresp, sizeof uresp); |
1500 | if (ret) | 1532 | if (ret) |
1501 | goto err7; | 1533 | goto err8; |
1502 | mm1->key = uresp.sq_key; | 1534 | mm1->key = uresp.sq_key; |
1503 | mm1->addr = virt_to_phys(qhp->wq.sq.queue); | 1535 | mm1->addr = qhp->wq.sq.phys_addr; |
1504 | mm1->len = PAGE_ALIGN(qhp->wq.sq.memsize); | 1536 | mm1->len = PAGE_ALIGN(qhp->wq.sq.memsize); |
1505 | insert_mmap(ucontext, mm1); | 1537 | insert_mmap(ucontext, mm1); |
1506 | mm2->key = uresp.rq_key; | 1538 | mm2->key = uresp.rq_key; |
@@ -1515,6 +1547,13 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs, | |||
1515 | mm4->addr = qhp->wq.rq.udb; | 1547 | mm4->addr = qhp->wq.rq.udb; |
1516 | mm4->len = PAGE_SIZE; | 1548 | mm4->len = PAGE_SIZE; |
1517 | insert_mmap(ucontext, mm4); | 1549 | insert_mmap(ucontext, mm4); |
1550 | if (mm5) { | ||
1551 | mm5->key = uresp.ma_sync_key; | ||
1552 | mm5->addr = (pci_resource_start(rhp->rdev.lldi.pdev, 0) | ||
1553 | + A_PCIE_MA_SYNC) & PAGE_MASK; | ||
1554 | mm5->len = PAGE_SIZE; | ||
1555 | insert_mmap(ucontext, mm5); | ||
1556 | } | ||
1518 | } | 1557 | } |
1519 | qhp->ibqp.qp_num = qhp->wq.sq.qid; | 1558 | qhp->ibqp.qp_num = qhp->wq.sq.qid; |
1520 | init_timer(&(qhp->timer)); | 1559 | init_timer(&(qhp->timer)); |
@@ -1522,6 +1561,8 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs, | |||
1522 | __func__, qhp, qhp->attr.sq_num_entries, qhp->attr.rq_num_entries, | 1561 | __func__, qhp, qhp->attr.sq_num_entries, qhp->attr.rq_num_entries, |
1523 | qhp->wq.sq.qid); | 1562 | qhp->wq.sq.qid); |
1524 | return &qhp->ibqp; | 1563 | return &qhp->ibqp; |
1564 | err8: | ||
1565 | kfree(mm5); | ||
1525 | err7: | 1566 | err7: |
1526 | kfree(mm4); | 1567 | kfree(mm4); |
1527 | err6: | 1568 | err6: |