diff options
-rw-r--r-- | drivers/infiniband/hw/nes/nes_verbs.c | 61 |
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 | ||