aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/hw/nes/nes_verbs.c61
1 files changed, 40 insertions, 21 deletions
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
index 36666ac2f546..ad3c891d0f65 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.c
+++ b/drivers/infiniband/hw/nes/nes_verbs.c
@@ -3615,11 +3615,13 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry)
3615 struct nes_qp *nesqp; 3615 struct nes_qp *nesqp;
3616 struct nes_hw_cqe cqe; 3616 struct nes_hw_cqe cqe;
3617 u32 head; 3617 u32 head;
3618 u32 wq_tail; 3618 u32 wq_tail = 0;
3619 u32 cq_size; 3619 u32 cq_size;
3620 u32 cqe_count = 0; 3620 u32 cqe_count = 0;
3621 u32 wqe_index; 3621 u32 wqe_index;
3622 u32 u32temp; 3622 u32 u32temp;
3623 u32 move_cq_head = 1;
3624 u32 err_code;
3623 3625
3624 nes_debug(NES_DBG_CQ, "\n"); 3626 nes_debug(NES_DBG_CQ, "\n");
3625 3627
@@ -3640,7 +3642,6 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry)
3640 rmb(); 3642 rmb();
3641 3643
3642 cqe = nescq->hw_cq.cq_vbase[head]; 3644 cqe = nescq->hw_cq.cq_vbase[head];
3643 nescq->hw_cq.cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX] = 0;
3644 u32temp = le32_to_cpu(cqe.cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX]); 3645 u32temp = le32_to_cpu(cqe.cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX]);
3645 wqe_index = u32temp & (nesdev->nesadapter->max_qp_wr - 1); 3646 wqe_index = u32temp & (nesdev->nesadapter->max_qp_wr - 1);
3646 u32temp &= ~(NES_SW_CONTEXT_ALIGN-1); 3647 u32temp &= ~(NES_SW_CONTEXT_ALIGN-1);
@@ -3667,16 +3668,14 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry)
3667 } 3668 }
3668 3669
3669 /* Working on a SQ Completion*/ 3670 /* Working on a SQ Completion*/
3670 wq_tail = wqe_index; 3671 wrid = (((u64)(cpu_to_le32((u32)nesqp->hwqp.sq_vbase[wqe_index].
3671 nesqp->hwqp.sq_tail = (wqe_index+1)&(nesqp->hwqp.sq_size - 1);
3672 wrid = (((u64)(cpu_to_le32((u32)nesqp->hwqp.sq_vbase[wq_tail].
3673 wqe_words[NES_IWARP_SQ_WQE_COMP_SCRATCH_HIGH_IDX]))) << 32) | 3672 wqe_words[NES_IWARP_SQ_WQE_COMP_SCRATCH_HIGH_IDX]))) << 32) |
3674 ((u64)(cpu_to_le32((u32)nesqp->hwqp.sq_vbase[wq_tail]. 3673 ((u64)(cpu_to_le32((u32)nesqp->hwqp.sq_vbase[wqe_index].
3675 wqe_words[NES_IWARP_SQ_WQE_COMP_SCRATCH_LOW_IDX]))); 3674 wqe_words[NES_IWARP_SQ_WQE_COMP_SCRATCH_LOW_IDX])));
3676 entry->byte_len = le32_to_cpu(nesqp->hwqp.sq_vbase[wq_tail]. 3675 entry->byte_len = le32_to_cpu(nesqp->hwqp.sq_vbase[wqe_index].
3677 wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX]); 3676 wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX]);
3678 3677
3679 switch (le32_to_cpu(nesqp->hwqp.sq_vbase[wq_tail]. 3678 switch (le32_to_cpu(nesqp->hwqp.sq_vbase[wqe_index].
3680 wqe_words[NES_IWARP_SQ_WQE_MISC_IDX]) & 0x3f) { 3679 wqe_words[NES_IWARP_SQ_WQE_MISC_IDX]) & 0x3f) {
3681 case NES_IWARP_SQ_OP_RDMAW: 3680 case NES_IWARP_SQ_OP_RDMAW:
3682 nes_debug(NES_DBG_CQ, "Operation = RDMA WRITE.\n"); 3681 nes_debug(NES_DBG_CQ, "Operation = RDMA WRITE.\n");
@@ -3685,7 +3684,7 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry)
3685 case NES_IWARP_SQ_OP_RDMAR: 3684 case NES_IWARP_SQ_OP_RDMAR:
3686 nes_debug(NES_DBG_CQ, "Operation = RDMA READ.\n"); 3685 nes_debug(NES_DBG_CQ, "Operation = RDMA READ.\n");
3687 entry->opcode = IB_WC_RDMA_READ; 3686 entry->opcode = IB_WC_RDMA_READ;
3688 entry->byte_len = le32_to_cpu(nesqp->hwqp.sq_vbase[wq_tail]. 3687 entry->byte_len = le32_to_cpu(nesqp->hwqp.sq_vbase[wqe_index].
3689 wqe_words[NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX]); 3688 wqe_words[NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX]);
3690 break; 3689 break;
3691 case NES_IWARP_SQ_OP_SENDINV: 3690 case NES_IWARP_SQ_OP_SENDINV:
@@ -3696,14 +3695,24 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry)
3696 entry->opcode = IB_WC_SEND; 3695 entry->opcode = IB_WC_SEND;
3697 break; 3696 break;
3698 } 3697 }
3698
3699 nesqp->hwqp.sq_tail = (wqe_index+1)&(nesqp->hwqp.sq_size - 1);
3700 if ((entry->status != IB_WC_SUCCESS) && (nesqp->hwqp.sq_tail != nesqp->hwqp.sq_head)) {
3701 move_cq_head = 0;
3702 wq_tail = nesqp->hwqp.sq_tail;
3703 }
3699 } else { 3704 } else {
3700 /* Working on a RQ Completion*/ 3705 /* Working on a RQ Completion*/
3701 wq_tail = wqe_index;
3702 nesqp->hwqp.rq_tail = (wqe_index+1)&(nesqp->hwqp.rq_size - 1);
3703 entry->byte_len = le32_to_cpu(cqe.cqe_words[NES_CQE_PAYLOAD_LENGTH_IDX]); 3706 entry->byte_len = le32_to_cpu(cqe.cqe_words[NES_CQE_PAYLOAD_LENGTH_IDX]);
3704 wrid = ((u64)(le32_to_cpu(nesqp->hwqp.rq_vbase[wq_tail].wqe_words[NES_IWARP_RQ_WQE_COMP_SCRATCH_LOW_IDX]))) | 3707 wrid = ((u64)(le32_to_cpu(nesqp->hwqp.rq_vbase[wqe_index].wqe_words[NES_IWARP_RQ_WQE_COMP_SCRATCH_LOW_IDX]))) |
3705 ((u64)(le32_to_cpu(nesqp->hwqp.rq_vbase[wq_tail].wqe_words[NES_IWARP_RQ_WQE_COMP_SCRATCH_HIGH_IDX]))<<32); 3708 ((u64)(le32_to_cpu(nesqp->hwqp.rq_vbase[wqe_index].wqe_words[NES_IWARP_RQ_WQE_COMP_SCRATCH_HIGH_IDX]))<<32);
3706 entry->opcode = IB_WC_RECV; 3709 entry->opcode = IB_WC_RECV;
3710
3711 nesqp->hwqp.rq_tail = (wqe_index+1)&(nesqp->hwqp.rq_size - 1);
3712 if ((entry->status != IB_WC_SUCCESS) && (nesqp->hwqp.rq_tail != nesqp->hwqp.rq_head)) {
3713 move_cq_head = 0;
3714 wq_tail = nesqp->hwqp.rq_tail;
3715 }
3707 } 3716 }
3708 3717
3709 entry->wr_id = wrid; 3718 entry->wr_id = wrid;
@@ -3711,18 +3720,28 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry)
3711 cqe_count++; 3720 cqe_count++;
3712 } 3721 }
3713 3722
3714 if (++head >= cq_size) 3723 if (move_cq_head) {
3715 head = 0; 3724 nescq->hw_cq.cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX] = 0;
3716 nescq->polled_completions++; 3725 if (++head >= cq_size)
3726 head = 0;
3727 nescq->polled_completions++;
3717 3728
3718 if ((nescq->polled_completions > (cq_size / 2)) || 3729 if ((nescq->polled_completions > (cq_size / 2)) ||
3719 (nescq->polled_completions == 255)) { 3730 (nescq->polled_completions == 255)) {
3720 nes_debug(NES_DBG_CQ, "CQ%u Issuing CQE Allocate since more than half of cqes" 3731 nes_debug(NES_DBG_CQ, "CQ%u Issuing CQE Allocate since more than half of cqes"
3721 " are pending %u of %u.\n", 3732 " are pending %u of %u.\n",
3722 nescq->hw_cq.cq_number, nescq->polled_completions, cq_size); 3733 nescq->hw_cq.cq_number, nescq->polled_completions, cq_size);
3723 nes_write32(nesdev->regs+NES_CQE_ALLOC, 3734 nes_write32(nesdev->regs+NES_CQE_ALLOC,
3724 nescq->hw_cq.cq_number | (nescq->polled_completions << 16)); 3735 nescq->hw_cq.cq_number | (nescq->polled_completions << 16));
3725 nescq->polled_completions = 0; 3736 nescq->polled_completions = 0;
3737 }
3738 } else {
3739 /* Update the wqe index and set status to flush */
3740 wqe_index = le32_to_cpu(cqe.cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX]);
3741 wqe_index = (wqe_index & (~(nesdev->nesadapter->max_qp_wr - 1))) | wq_tail;
3742 nescq->hw_cq.cq_vbase[head].cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX] =
3743 cpu_to_le32(wqe_index);
3744 move_cq_head = 1; /* ready for next pass */
3726 } 3745 }
3727 } 3746 }
3728 3747