aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/ehca/ehca_reqs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/ehca/ehca_reqs.c')
-rw-r--r--drivers/infiniband/hw/ehca/ehca_reqs.c54
1 files changed, 43 insertions, 11 deletions
diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c b/drivers/infiniband/hw/ehca/ehca_reqs.c
index cea3eba9c83e..4426d82fe798 100644
--- a/drivers/infiniband/hw/ehca/ehca_reqs.c
+++ b/drivers/infiniband/hw/ehca/ehca_reqs.c
@@ -139,6 +139,7 @@ static void trace_send_wr_ud(const struct ib_send_wr *send_wr)
139static inline int ehca_write_swqe(struct ehca_qp *qp, 139static inline int ehca_write_swqe(struct ehca_qp *qp,
140 struct ehca_wqe *wqe_p, 140 struct ehca_wqe *wqe_p,
141 const struct ib_send_wr *send_wr, 141 const struct ib_send_wr *send_wr,
142 u32 sq_map_idx,
142 int hidden) 143 int hidden)
143{ 144{
144 u32 idx; 145 u32 idx;
@@ -157,7 +158,11 @@ static inline int ehca_write_swqe(struct ehca_qp *qp,
157 /* clear wqe header until sglist */ 158 /* clear wqe header until sglist */
158 memset(wqe_p, 0, offsetof(struct ehca_wqe, u.ud_av.sg_list)); 159 memset(wqe_p, 0, offsetof(struct ehca_wqe, u.ud_av.sg_list));
159 160
160 wqe_p->work_request_id = send_wr->wr_id; 161 wqe_p->work_request_id = send_wr->wr_id & ~QMAP_IDX_MASK;
162 wqe_p->work_request_id |= sq_map_idx & QMAP_IDX_MASK;
163
164 qp->sq_map[sq_map_idx].app_wr_id = send_wr->wr_id & QMAP_IDX_MASK;
165 qp->sq_map[sq_map_idx].reported = 0;
161 166
162 switch (send_wr->opcode) { 167 switch (send_wr->opcode) {
163 case IB_WR_SEND: 168 case IB_WR_SEND:
@@ -381,6 +386,7 @@ static inline int post_one_send(struct ehca_qp *my_qp,
381{ 386{
382 struct ehca_wqe *wqe_p; 387 struct ehca_wqe *wqe_p;
383 int ret; 388 int ret;
389 u32 sq_map_idx;
384 u64 start_offset = my_qp->ipz_squeue.current_q_offset; 390 u64 start_offset = my_qp->ipz_squeue.current_q_offset;
385 391
386 /* get pointer next to free WQE */ 392 /* get pointer next to free WQE */
@@ -393,8 +399,15 @@ static inline int post_one_send(struct ehca_qp *my_qp,
393 "qp_num=%x", my_qp->ib_qp.qp_num); 399 "qp_num=%x", my_qp->ib_qp.qp_num);
394 return -ENOMEM; 400 return -ENOMEM;
395 } 401 }
402
403 /*
404 * Get the index of the WQE in the send queue. The same index is used
405 * for writing into the sq_map.
406 */
407 sq_map_idx = start_offset / my_qp->ipz_squeue.qe_size;
408
396 /* write a SEND WQE into the QUEUE */ 409 /* write a SEND WQE into the QUEUE */
397 ret = ehca_write_swqe(my_qp, wqe_p, cur_send_wr, hidden); 410 ret = ehca_write_swqe(my_qp, wqe_p, cur_send_wr, sq_map_idx, hidden);
398 /* 411 /*
399 * if something failed, 412 * if something failed,
400 * reset the free entry pointer to the start value 413 * reset the free entry pointer to the start value
@@ -654,8 +667,34 @@ repoll:
654 my_cq, my_cq->cq_number); 667 my_cq, my_cq->cq_number);
655 } 668 }
656 669
657 /* we got a completion! */ 670 read_lock(&ehca_qp_idr_lock);
658 wc->wr_id = cqe->work_request_id; 671 my_qp = idr_find(&ehca_qp_idr, cqe->qp_token);
672 read_unlock(&ehca_qp_idr_lock);
673 if (!my_qp)
674 goto repoll;
675 wc->qp = &my_qp->ib_qp;
676
677 if (!(cqe->w_completion_flags & WC_SEND_RECEIVE_BIT)) {
678 struct ehca_qmap_entry *qmap_entry;
679 /*
680 * We got a send completion and need to restore the original
681 * wr_id.
682 */
683 qmap_entry = &my_qp->sq_map[cqe->work_request_id &
684 QMAP_IDX_MASK];
685
686 if (qmap_entry->reported) {
687 ehca_warn(cq->device, "Double cqe on qp_num=%#x",
688 my_qp->real_qp_num);
689 /* found a double cqe, discard it and read next one */
690 goto repoll;
691 }
692 wc->wr_id = cqe->work_request_id & ~QMAP_IDX_MASK;
693 wc->wr_id |= qmap_entry->app_wr_id;
694 qmap_entry->reported = 1;
695 } else
696 /* We got a receive completion. */
697 wc->wr_id = cqe->work_request_id;
659 698
660 /* eval ib_wc_opcode */ 699 /* eval ib_wc_opcode */
661 wc->opcode = ib_wc_opcode[cqe->optype]-1; 700 wc->opcode = ib_wc_opcode[cqe->optype]-1;
@@ -678,13 +717,6 @@ repoll:
678 } else 717 } else
679 wc->status = IB_WC_SUCCESS; 718 wc->status = IB_WC_SUCCESS;
680 719
681 read_lock(&ehca_qp_idr_lock);
682 my_qp = idr_find(&ehca_qp_idr, cqe->qp_token);
683 read_unlock(&ehca_qp_idr_lock);
684 if (!my_qp)
685 goto repoll;
686 wc->qp = &my_qp->ib_qp;
687
688 wc->byte_len = cqe->nr_bytes_transferred; 720 wc->byte_len = cqe->nr_bytes_transferred;
689 wc->pkey_index = cqe->pkey_index; 721 wc->pkey_index = cqe->pkey_index;
690 wc->slid = cqe->rlid; 722 wc->slid = cqe->rlid;