diff options
Diffstat (limited to 'drivers/infiniband/hw/nes/nes_verbs.c')
-rw-r--r-- | drivers/infiniband/hw/nes/nes_verbs.c | 204 |
1 files changed, 156 insertions, 48 deletions
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 21e0fd336cf7..a680c42d6e8c 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c | |||
@@ -667,15 +667,32 @@ static int nes_query_device(struct ib_device *ibdev, struct ib_device_attr *prop | |||
667 | */ | 667 | */ |
668 | static int nes_query_port(struct ib_device *ibdev, u8 port, struct ib_port_attr *props) | 668 | static int nes_query_port(struct ib_device *ibdev, u8 port, struct ib_port_attr *props) |
669 | { | 669 | { |
670 | struct nes_vnic *nesvnic = to_nesvnic(ibdev); | ||
671 | struct net_device *netdev = nesvnic->netdev; | ||
672 | |||
670 | memset(props, 0, sizeof(*props)); | 673 | memset(props, 0, sizeof(*props)); |
671 | 674 | ||
672 | props->max_mtu = IB_MTU_2048; | 675 | props->max_mtu = IB_MTU_4096; |
673 | props->active_mtu = IB_MTU_2048; | 676 | |
677 | if (netdev->mtu >= 4096) | ||
678 | props->active_mtu = IB_MTU_4096; | ||
679 | else if (netdev->mtu >= 2048) | ||
680 | props->active_mtu = IB_MTU_2048; | ||
681 | else if (netdev->mtu >= 1024) | ||
682 | props->active_mtu = IB_MTU_1024; | ||
683 | else if (netdev->mtu >= 512) | ||
684 | props->active_mtu = IB_MTU_512; | ||
685 | else | ||
686 | props->active_mtu = IB_MTU_256; | ||
687 | |||
674 | props->lid = 1; | 688 | props->lid = 1; |
675 | props->lmc = 0; | 689 | props->lmc = 0; |
676 | props->sm_lid = 0; | 690 | props->sm_lid = 0; |
677 | props->sm_sl = 0; | 691 | props->sm_sl = 0; |
678 | props->state = IB_PORT_ACTIVE; | 692 | if (nesvnic->linkup) |
693 | props->state = IB_PORT_ACTIVE; | ||
694 | else | ||
695 | props->state = IB_PORT_DOWN; | ||
679 | props->phys_state = 0; | 696 | props->phys_state = 0; |
680 | props->port_cap_flags = IB_PORT_CM_SUP | IB_PORT_REINIT_SUP | | 697 | props->port_cap_flags = IB_PORT_CM_SUP | IB_PORT_REINIT_SUP | |
681 | IB_PORT_VENDOR_CLASS_SUP | IB_PORT_BOOT_MGMT_SUP; | 698 | IB_PORT_VENDOR_CLASS_SUP | IB_PORT_BOOT_MGMT_SUP; |
@@ -1506,12 +1523,45 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd, | |||
1506 | 1523 | ||
1507 | 1524 | ||
1508 | /** | 1525 | /** |
1526 | * nes_clean_cq | ||
1527 | */ | ||
1528 | static void nes_clean_cq(struct nes_qp *nesqp, struct nes_cq *nescq) | ||
1529 | { | ||
1530 | u32 cq_head; | ||
1531 | u32 lo; | ||
1532 | u32 hi; | ||
1533 | u64 u64temp; | ||
1534 | unsigned long flags = 0; | ||
1535 | |||
1536 | spin_lock_irqsave(&nescq->lock, flags); | ||
1537 | |||
1538 | cq_head = nescq->hw_cq.cq_head; | ||
1539 | while (le32_to_cpu(nescq->hw_cq.cq_vbase[cq_head].cqe_words[NES_CQE_OPCODE_IDX]) & NES_CQE_VALID) { | ||
1540 | rmb(); | ||
1541 | lo = le32_to_cpu(nescq->hw_cq.cq_vbase[cq_head].cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX]); | ||
1542 | hi = le32_to_cpu(nescq->hw_cq.cq_vbase[cq_head].cqe_words[NES_CQE_COMP_COMP_CTX_HIGH_IDX]); | ||
1543 | u64temp = (((u64)hi) << 32) | ((u64)lo); | ||
1544 | u64temp &= ~(NES_SW_CONTEXT_ALIGN-1); | ||
1545 | if (u64temp == (u64)(unsigned long)nesqp) { | ||
1546 | /* Zero the context value so cqe will be ignored */ | ||
1547 | nescq->hw_cq.cq_vbase[cq_head].cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX] = 0; | ||
1548 | nescq->hw_cq.cq_vbase[cq_head].cqe_words[NES_CQE_COMP_COMP_CTX_HIGH_IDX] = 0; | ||
1549 | } | ||
1550 | |||
1551 | if (++cq_head >= nescq->hw_cq.cq_size) | ||
1552 | cq_head = 0; | ||
1553 | } | ||
1554 | |||
1555 | spin_unlock_irqrestore(&nescq->lock, flags); | ||
1556 | } | ||
1557 | |||
1558 | |||
1559 | /** | ||
1509 | * nes_destroy_qp | 1560 | * nes_destroy_qp |
1510 | */ | 1561 | */ |
1511 | static int nes_destroy_qp(struct ib_qp *ibqp) | 1562 | static int nes_destroy_qp(struct ib_qp *ibqp) |
1512 | { | 1563 | { |
1513 | struct nes_qp *nesqp = to_nesqp(ibqp); | 1564 | struct nes_qp *nesqp = to_nesqp(ibqp); |
1514 | /* struct nes_vnic *nesvnic = to_nesvnic(ibqp->device); */ | ||
1515 | struct nes_ucontext *nes_ucontext; | 1565 | struct nes_ucontext *nes_ucontext; |
1516 | struct ib_qp_attr attr; | 1566 | struct ib_qp_attr attr; |
1517 | struct iw_cm_id *cm_id; | 1567 | struct iw_cm_id *cm_id; |
@@ -1548,7 +1598,6 @@ static int nes_destroy_qp(struct ib_qp *ibqp) | |||
1548 | nes_debug(NES_DBG_QP, "OFA CM event_handler returned, ret=%d\n", ret); | 1598 | nes_debug(NES_DBG_QP, "OFA CM event_handler returned, ret=%d\n", ret); |
1549 | } | 1599 | } |
1550 | 1600 | ||
1551 | |||
1552 | if (nesqp->user_mode) { | 1601 | if (nesqp->user_mode) { |
1553 | if ((ibqp->uobject)&&(ibqp->uobject->context)) { | 1602 | if ((ibqp->uobject)&&(ibqp->uobject->context)) { |
1554 | nes_ucontext = to_nesucontext(ibqp->uobject->context); | 1603 | nes_ucontext = to_nesucontext(ibqp->uobject->context); |
@@ -1560,6 +1609,13 @@ static int nes_destroy_qp(struct ib_qp *ibqp) | |||
1560 | } | 1609 | } |
1561 | if (nesqp->pbl_pbase) | 1610 | if (nesqp->pbl_pbase) |
1562 | kunmap(nesqp->page); | 1611 | kunmap(nesqp->page); |
1612 | } else { | ||
1613 | /* Clean any pending completions from the cq(s) */ | ||
1614 | if (nesqp->nesscq) | ||
1615 | nes_clean_cq(nesqp, nesqp->nesscq); | ||
1616 | |||
1617 | if ((nesqp->nesrcq) && (nesqp->nesrcq != nesqp->nesscq)) | ||
1618 | nes_clean_cq(nesqp, nesqp->nesrcq); | ||
1563 | } | 1619 | } |
1564 | 1620 | ||
1565 | nes_rem_ref(&nesqp->ibqp); | 1621 | nes_rem_ref(&nesqp->ibqp); |
@@ -2884,7 +2940,7 @@ static int nes_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, | |||
2884 | * nes_hw_modify_qp | 2940 | * nes_hw_modify_qp |
2885 | */ | 2941 | */ |
2886 | int nes_hw_modify_qp(struct nes_device *nesdev, struct nes_qp *nesqp, | 2942 | int nes_hw_modify_qp(struct nes_device *nesdev, struct nes_qp *nesqp, |
2887 | u32 next_iwarp_state, u32 wait_completion) | 2943 | u32 next_iwarp_state, u32 termlen, u32 wait_completion) |
2888 | { | 2944 | { |
2889 | struct nes_hw_cqp_wqe *cqp_wqe; | 2945 | struct nes_hw_cqp_wqe *cqp_wqe; |
2890 | /* struct iw_cm_id *cm_id = nesqp->cm_id; */ | 2946 | /* struct iw_cm_id *cm_id = nesqp->cm_id; */ |
@@ -2916,6 +2972,13 @@ int nes_hw_modify_qp(struct nes_device *nesdev, struct nes_qp *nesqp, | |||
2916 | set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_ID_IDX, nesqp->hwqp.qp_id); | 2972 | set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_ID_IDX, nesqp->hwqp.qp_id); |
2917 | set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_QP_WQE_CONTEXT_LOW_IDX, (u64)nesqp->nesqp_context_pbase); | 2973 | set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_QP_WQE_CONTEXT_LOW_IDX, (u64)nesqp->nesqp_context_pbase); |
2918 | 2974 | ||
2975 | /* If sending a terminate message, fill in the length (in words) */ | ||
2976 | if (((next_iwarp_state & NES_CQP_QP_IWARP_STATE_MASK) == NES_CQP_QP_IWARP_STATE_TERMINATE) && | ||
2977 | !(next_iwarp_state & NES_CQP_QP_TERM_DONT_SEND_TERM_MSG)) { | ||
2978 | termlen = ((termlen + 3) >> 2) << NES_CQP_OP_TERMLEN_SHIFT; | ||
2979 | set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_QP_WQE_NEW_MSS_IDX, termlen); | ||
2980 | } | ||
2981 | |||
2919 | atomic_set(&cqp_request->refcount, 2); | 2982 | atomic_set(&cqp_request->refcount, 2); |
2920 | nes_post_cqp_request(nesdev, cqp_request); | 2983 | nes_post_cqp_request(nesdev, cqp_request); |
2921 | 2984 | ||
@@ -3086,6 +3149,9 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, | |||
3086 | } | 3149 | } |
3087 | nes_debug(NES_DBG_MOD_QP, "QP%u: new state = error\n", | 3150 | nes_debug(NES_DBG_MOD_QP, "QP%u: new state = error\n", |
3088 | nesqp->hwqp.qp_id); | 3151 | nesqp->hwqp.qp_id); |
3152 | if (nesqp->term_flags) | ||
3153 | del_timer(&nesqp->terminate_timer); | ||
3154 | |||
3089 | next_iwarp_state = NES_CQP_QP_IWARP_STATE_ERROR; | 3155 | next_iwarp_state = NES_CQP_QP_IWARP_STATE_ERROR; |
3090 | /* next_iwarp_state = (NES_CQP_QP_IWARP_STATE_TERMINATE | 0x02000000); */ | 3156 | /* next_iwarp_state = (NES_CQP_QP_IWARP_STATE_TERMINATE | 0x02000000); */ |
3091 | if (nesqp->hte_added) { | 3157 | if (nesqp->hte_added) { |
@@ -3163,7 +3229,7 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, | |||
3163 | 3229 | ||
3164 | if (issue_modify_qp) { | 3230 | if (issue_modify_qp) { |
3165 | nes_debug(NES_DBG_MOD_QP, "call nes_hw_modify_qp\n"); | 3231 | nes_debug(NES_DBG_MOD_QP, "call nes_hw_modify_qp\n"); |
3166 | ret = nes_hw_modify_qp(nesdev, nesqp, next_iwarp_state, 1); | 3232 | ret = nes_hw_modify_qp(nesdev, nesqp, next_iwarp_state, 0, 1); |
3167 | if (ret) | 3233 | if (ret) |
3168 | nes_debug(NES_DBG_MOD_QP, "nes_hw_modify_qp (next_iwarp_state = 0x%08X)" | 3234 | nes_debug(NES_DBG_MOD_QP, "nes_hw_modify_qp (next_iwarp_state = 0x%08X)" |
3169 | " failed for QP%u.\n", | 3235 | " failed for QP%u.\n", |
@@ -3328,6 +3394,12 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, | |||
3328 | head = nesqp->hwqp.sq_head; | 3394 | head = nesqp->hwqp.sq_head; |
3329 | 3395 | ||
3330 | while (ib_wr) { | 3396 | while (ib_wr) { |
3397 | /* Check for QP error */ | ||
3398 | if (nesqp->term_flags) { | ||
3399 | err = -EINVAL; | ||
3400 | break; | ||
3401 | } | ||
3402 | |||
3331 | /* Check for SQ overflow */ | 3403 | /* Check for SQ overflow */ |
3332 | if (((head + (2 * qsize) - nesqp->hwqp.sq_tail) % qsize) == (qsize - 1)) { | 3404 | if (((head + (2 * qsize) - nesqp->hwqp.sq_tail) % qsize) == (qsize - 1)) { |
3333 | err = -EINVAL; | 3405 | err = -EINVAL; |
@@ -3484,6 +3556,12 @@ static int nes_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr, | |||
3484 | head = nesqp->hwqp.rq_head; | 3556 | head = nesqp->hwqp.rq_head; |
3485 | 3557 | ||
3486 | while (ib_wr) { | 3558 | while (ib_wr) { |
3559 | /* Check for QP error */ | ||
3560 | if (nesqp->term_flags) { | ||
3561 | err = -EINVAL; | ||
3562 | break; | ||
3563 | } | ||
3564 | |||
3487 | if (ib_wr->num_sge > nesdev->nesadapter->max_sge) { | 3565 | if (ib_wr->num_sge > nesdev->nesadapter->max_sge) { |
3488 | err = -EINVAL; | 3566 | err = -EINVAL; |
3489 | break; | 3567 | break; |
@@ -3547,7 +3625,6 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry) | |||
3547 | { | 3625 | { |
3548 | u64 u64temp; | 3626 | u64 u64temp; |
3549 | u64 wrid; | 3627 | u64 wrid; |
3550 | /* u64 u64temp; */ | ||
3551 | unsigned long flags = 0; | 3628 | unsigned long flags = 0; |
3552 | struct nes_vnic *nesvnic = to_nesvnic(ibcq->device); | 3629 | struct nes_vnic *nesvnic = to_nesvnic(ibcq->device); |
3553 | struct nes_device *nesdev = nesvnic->nesdev; | 3630 | struct nes_device *nesdev = nesvnic->nesdev; |
@@ -3555,12 +3632,13 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry) | |||
3555 | struct nes_qp *nesqp; | 3632 | struct nes_qp *nesqp; |
3556 | struct nes_hw_cqe cqe; | 3633 | struct nes_hw_cqe cqe; |
3557 | u32 head; | 3634 | u32 head; |
3558 | u32 wq_tail; | 3635 | u32 wq_tail = 0; |
3559 | u32 cq_size; | 3636 | u32 cq_size; |
3560 | u32 cqe_count = 0; | 3637 | u32 cqe_count = 0; |
3561 | u32 wqe_index; | 3638 | u32 wqe_index; |
3562 | u32 u32temp; | 3639 | u32 u32temp; |
3563 | /* u32 counter; */ | 3640 | u32 move_cq_head = 1; |
3641 | u32 err_code; | ||
3564 | 3642 | ||
3565 | nes_debug(NES_DBG_CQ, "\n"); | 3643 | nes_debug(NES_DBG_CQ, "\n"); |
3566 | 3644 | ||
@@ -3570,29 +3648,40 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry) | |||
3570 | cq_size = nescq->hw_cq.cq_size; | 3648 | cq_size = nescq->hw_cq.cq_size; |
3571 | 3649 | ||
3572 | while (cqe_count < num_entries) { | 3650 | while (cqe_count < num_entries) { |
3573 | if (le32_to_cpu(nescq->hw_cq.cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX]) & | 3651 | if ((le32_to_cpu(nescq->hw_cq.cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX]) & |
3574 | NES_CQE_VALID) { | 3652 | NES_CQE_VALID) == 0) |
3575 | /* | 3653 | break; |
3576 | * Make sure we read CQ entry contents *after* | 3654 | |
3577 | * we've checked the valid bit. | 3655 | /* |
3578 | */ | 3656 | * Make sure we read CQ entry contents *after* |
3579 | rmb(); | 3657 | * we've checked the valid bit. |
3580 | 3658 | */ | |
3581 | cqe = nescq->hw_cq.cq_vbase[head]; | 3659 | rmb(); |
3582 | nescq->hw_cq.cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX] = 0; | 3660 | |
3583 | u32temp = le32_to_cpu(cqe.cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX]); | 3661 | cqe = nescq->hw_cq.cq_vbase[head]; |
3584 | wqe_index = u32temp & | 3662 | u32temp = le32_to_cpu(cqe.cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX]); |
3585 | (nesdev->nesadapter->max_qp_wr - 1); | 3663 | wqe_index = u32temp & (nesdev->nesadapter->max_qp_wr - 1); |
3586 | u32temp &= ~(NES_SW_CONTEXT_ALIGN-1); | 3664 | u32temp &= ~(NES_SW_CONTEXT_ALIGN-1); |
3587 | /* parse CQE, get completion context from WQE (either rq or sq */ | 3665 | /* parse CQE, get completion context from WQE (either rq or sq) */ |
3588 | u64temp = (((u64)(le32_to_cpu(cqe.cqe_words[NES_CQE_COMP_COMP_CTX_HIGH_IDX])))<<32) | | 3666 | u64temp = (((u64)(le32_to_cpu(cqe.cqe_words[NES_CQE_COMP_COMP_CTX_HIGH_IDX])))<<32) | |
3589 | ((u64)u32temp); | 3667 | ((u64)u32temp); |
3590 | nesqp = *((struct nes_qp **)&u64temp); | 3668 | |
3669 | if (u64temp) { | ||
3670 | nesqp = (struct nes_qp *)(unsigned long)u64temp; | ||
3591 | memset(entry, 0, sizeof *entry); | 3671 | memset(entry, 0, sizeof *entry); |
3592 | if (cqe.cqe_words[NES_CQE_ERROR_CODE_IDX] == 0) { | 3672 | if (cqe.cqe_words[NES_CQE_ERROR_CODE_IDX] == 0) { |
3593 | entry->status = IB_WC_SUCCESS; | 3673 | entry->status = IB_WC_SUCCESS; |
3594 | } else { | 3674 | } else { |
3595 | entry->status = IB_WC_WR_FLUSH_ERR; | 3675 | err_code = le32_to_cpu(cqe.cqe_words[NES_CQE_ERROR_CODE_IDX]); |
3676 | if (NES_IWARP_CQE_MAJOR_DRV == (err_code >> 16)) { | ||
3677 | entry->status = err_code & 0x0000ffff; | ||
3678 | |||
3679 | /* The rest of the cqe's will be marked as flushed */ | ||
3680 | nescq->hw_cq.cq_vbase[head].cqe_words[NES_CQE_ERROR_CODE_IDX] = | ||
3681 | cpu_to_le32((NES_IWARP_CQE_MAJOR_FLUSH << 16) | | ||
3682 | NES_IWARP_CQE_MINOR_FLUSH); | ||
3683 | } else | ||
3684 | entry->status = IB_WC_WR_FLUSH_ERR; | ||
3596 | } | 3685 | } |
3597 | 3686 | ||
3598 | entry->qp = &nesqp->ibqp; | 3687 | entry->qp = &nesqp->ibqp; |
@@ -3601,20 +3690,18 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry) | |||
3601 | if (le32_to_cpu(cqe.cqe_words[NES_CQE_OPCODE_IDX]) & NES_CQE_SQ) { | 3690 | if (le32_to_cpu(cqe.cqe_words[NES_CQE_OPCODE_IDX]) & NES_CQE_SQ) { |
3602 | if (nesqp->skip_lsmm) { | 3691 | if (nesqp->skip_lsmm) { |
3603 | nesqp->skip_lsmm = 0; | 3692 | nesqp->skip_lsmm = 0; |
3604 | wq_tail = nesqp->hwqp.sq_tail++; | 3693 | nesqp->hwqp.sq_tail++; |
3605 | } | 3694 | } |
3606 | 3695 | ||
3607 | /* Working on a SQ Completion*/ | 3696 | /* Working on a SQ Completion*/ |
3608 | wq_tail = wqe_index; | 3697 | wrid = (((u64)(cpu_to_le32((u32)nesqp->hwqp.sq_vbase[wqe_index]. |
3609 | nesqp->hwqp.sq_tail = (wqe_index+1)&(nesqp->hwqp.sq_size - 1); | ||
3610 | wrid = (((u64)(cpu_to_le32((u32)nesqp->hwqp.sq_vbase[wq_tail]. | ||
3611 | wqe_words[NES_IWARP_SQ_WQE_COMP_SCRATCH_HIGH_IDX]))) << 32) | | 3698 | wqe_words[NES_IWARP_SQ_WQE_COMP_SCRATCH_HIGH_IDX]))) << 32) | |
3612 | ((u64)(cpu_to_le32((u32)nesqp->hwqp.sq_vbase[wq_tail]. | 3699 | ((u64)(cpu_to_le32((u32)nesqp->hwqp.sq_vbase[wqe_index]. |
3613 | wqe_words[NES_IWARP_SQ_WQE_COMP_SCRATCH_LOW_IDX]))); | 3700 | wqe_words[NES_IWARP_SQ_WQE_COMP_SCRATCH_LOW_IDX]))); |
3614 | entry->byte_len = le32_to_cpu(nesqp->hwqp.sq_vbase[wq_tail]. | 3701 | entry->byte_len = le32_to_cpu(nesqp->hwqp.sq_vbase[wqe_index]. |
3615 | wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX]); | 3702 | wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX]); |
3616 | 3703 | ||
3617 | switch (le32_to_cpu(nesqp->hwqp.sq_vbase[wq_tail]. | 3704 | switch (le32_to_cpu(nesqp->hwqp.sq_vbase[wqe_index]. |
3618 | wqe_words[NES_IWARP_SQ_WQE_MISC_IDX]) & 0x3f) { | 3705 | wqe_words[NES_IWARP_SQ_WQE_MISC_IDX]) & 0x3f) { |
3619 | case NES_IWARP_SQ_OP_RDMAW: | 3706 | case NES_IWARP_SQ_OP_RDMAW: |
3620 | nes_debug(NES_DBG_CQ, "Operation = RDMA WRITE.\n"); | 3707 | nes_debug(NES_DBG_CQ, "Operation = RDMA WRITE.\n"); |
@@ -3623,7 +3710,7 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry) | |||
3623 | case NES_IWARP_SQ_OP_RDMAR: | 3710 | case NES_IWARP_SQ_OP_RDMAR: |
3624 | nes_debug(NES_DBG_CQ, "Operation = RDMA READ.\n"); | 3711 | nes_debug(NES_DBG_CQ, "Operation = RDMA READ.\n"); |
3625 | entry->opcode = IB_WC_RDMA_READ; | 3712 | entry->opcode = IB_WC_RDMA_READ; |
3626 | entry->byte_len = le32_to_cpu(nesqp->hwqp.sq_vbase[wq_tail]. | 3713 | entry->byte_len = le32_to_cpu(nesqp->hwqp.sq_vbase[wqe_index]. |
3627 | wqe_words[NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX]); | 3714 | wqe_words[NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX]); |
3628 | break; | 3715 | break; |
3629 | case NES_IWARP_SQ_OP_SENDINV: | 3716 | case NES_IWARP_SQ_OP_SENDINV: |
@@ -3634,33 +3721,54 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry) | |||
3634 | entry->opcode = IB_WC_SEND; | 3721 | entry->opcode = IB_WC_SEND; |
3635 | break; | 3722 | break; |
3636 | } | 3723 | } |
3724 | |||
3725 | nesqp->hwqp.sq_tail = (wqe_index+1)&(nesqp->hwqp.sq_size - 1); | ||
3726 | if ((entry->status != IB_WC_SUCCESS) && (nesqp->hwqp.sq_tail != nesqp->hwqp.sq_head)) { | ||
3727 | move_cq_head = 0; | ||
3728 | wq_tail = nesqp->hwqp.sq_tail; | ||
3729 | } | ||
3637 | } else { | 3730 | } else { |
3638 | /* Working on a RQ Completion*/ | 3731 | /* Working on a RQ Completion*/ |
3639 | wq_tail = wqe_index; | ||
3640 | nesqp->hwqp.rq_tail = (wqe_index+1)&(nesqp->hwqp.rq_size - 1); | ||
3641 | entry->byte_len = le32_to_cpu(cqe.cqe_words[NES_CQE_PAYLOAD_LENGTH_IDX]); | 3732 | entry->byte_len = le32_to_cpu(cqe.cqe_words[NES_CQE_PAYLOAD_LENGTH_IDX]); |
3642 | wrid = ((u64)(le32_to_cpu(nesqp->hwqp.rq_vbase[wq_tail].wqe_words[NES_IWARP_RQ_WQE_COMP_SCRATCH_LOW_IDX]))) | | 3733 | wrid = ((u64)(le32_to_cpu(nesqp->hwqp.rq_vbase[wqe_index].wqe_words[NES_IWARP_RQ_WQE_COMP_SCRATCH_LOW_IDX]))) | |
3643 | ((u64)(le32_to_cpu(nesqp->hwqp.rq_vbase[wq_tail].wqe_words[NES_IWARP_RQ_WQE_COMP_SCRATCH_HIGH_IDX]))<<32); | 3734 | ((u64)(le32_to_cpu(nesqp->hwqp.rq_vbase[wqe_index].wqe_words[NES_IWARP_RQ_WQE_COMP_SCRATCH_HIGH_IDX]))<<32); |
3644 | entry->opcode = IB_WC_RECV; | 3735 | entry->opcode = IB_WC_RECV; |
3736 | |||
3737 | nesqp->hwqp.rq_tail = (wqe_index+1)&(nesqp->hwqp.rq_size - 1); | ||
3738 | if ((entry->status != IB_WC_SUCCESS) && (nesqp->hwqp.rq_tail != nesqp->hwqp.rq_head)) { | ||
3739 | move_cq_head = 0; | ||
3740 | wq_tail = nesqp->hwqp.rq_tail; | ||
3741 | } | ||
3645 | } | 3742 | } |
3743 | |||
3646 | entry->wr_id = wrid; | 3744 | entry->wr_id = wrid; |
3745 | entry++; | ||
3746 | cqe_count++; | ||
3747 | } | ||
3647 | 3748 | ||
3749 | if (move_cq_head) { | ||
3750 | nescq->hw_cq.cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX] = 0; | ||
3648 | if (++head >= cq_size) | 3751 | if (++head >= cq_size) |
3649 | head = 0; | 3752 | head = 0; |
3650 | cqe_count++; | ||
3651 | nescq->polled_completions++; | 3753 | nescq->polled_completions++; |
3754 | |||
3652 | if ((nescq->polled_completions > (cq_size / 2)) || | 3755 | if ((nescq->polled_completions > (cq_size / 2)) || |
3653 | (nescq->polled_completions == 255)) { | 3756 | (nescq->polled_completions == 255)) { |
3654 | nes_debug(NES_DBG_CQ, "CQ%u Issuing CQE Allocate since more than half of cqes" | 3757 | nes_debug(NES_DBG_CQ, "CQ%u Issuing CQE Allocate since more than half of cqes" |
3655 | " are pending %u of %u.\n", | 3758 | " are pending %u of %u.\n", |
3656 | nescq->hw_cq.cq_number, nescq->polled_completions, cq_size); | 3759 | nescq->hw_cq.cq_number, nescq->polled_completions, cq_size); |
3657 | nes_write32(nesdev->regs+NES_CQE_ALLOC, | 3760 | nes_write32(nesdev->regs+NES_CQE_ALLOC, |
3658 | nescq->hw_cq.cq_number | (nescq->polled_completions << 16)); | 3761 | nescq->hw_cq.cq_number | (nescq->polled_completions << 16)); |
3659 | nescq->polled_completions = 0; | 3762 | nescq->polled_completions = 0; |
3660 | } | 3763 | } |
3661 | entry++; | 3764 | } else { |
3662 | } else | 3765 | /* Update the wqe index and set status to flush */ |
3663 | break; | 3766 | wqe_index = le32_to_cpu(cqe.cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX]); |
3767 | wqe_index = (wqe_index & (~(nesdev->nesadapter->max_qp_wr - 1))) | wq_tail; | ||
3768 | nescq->hw_cq.cq_vbase[head].cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX] = | ||
3769 | cpu_to_le32(wqe_index); | ||
3770 | move_cq_head = 1; /* ready for next pass */ | ||
3771 | } | ||
3664 | } | 3772 | } |
3665 | 3773 | ||
3666 | if (nescq->polled_completions) { | 3774 | if (nescq->polled_completions) { |