@@ -764,12 +764,27 @@ static int c4iw_poll_cq_one(struct c4iw_cq *chp, struct ibv_wc *wc)
wc->byte_len = CQE_LEN(com);
else
wc->byte_len = 0;
- if (CQE_OPCODE(com) == FW_RI_WRITE_IMMEDIATE) {
+
+ switch (CQE_OPCODE(com)) {
+ case FW_RI_SEND:
+ wc->opcode = IBV_WC_RECV;
+ break;
+ case FW_RI_SEND_WITH_INV:
+ case FW_RI_SEND_WITH_SE_INV:
+ wc->opcode = IBV_WC_RECV;
+ wc->wc_flags |= IBV_WC_WITH_INV;
+ wc->invalidated_rkey = CQE_WRID_STAG(com);
+ break;
+ case FW_RI_WRITE_IMMEDIATE:
wc->opcode = IBV_WC_RECV_RDMA_WITH_IMM;
wc->imm_data = CQE_IMM_DATA(&cqe.b64);
wc->wc_flags |= IBV_WC_WITH_IMM;
- } else {
- wc->opcode = IBV_WC_RECV;
+ break;
+ default:
+ PDBG("Unexpected opcode %d in the CQE received for QPID=0x%0x\n",
+ CQE_OPCODE(com), CQE_QPID(com));
+ ret = -EINVAL;
+ goto out;
}
} else {
switch (CQE_OPCODE(com)) {
@@ -783,8 +798,11 @@ static int c4iw_poll_cq_one(struct c4iw_cq *chp, struct ibv_wc *wc)
break;
case FW_RI_SEND:
case FW_RI_SEND_WITH_SE:
+ wc->opcode = IBV_WC_SEND;
+ break;
case FW_RI_SEND_WITH_INV:
case FW_RI_SEND_WITH_SE_INV:
+ wc->wc_flags |= IBV_WC_WITH_INV;
wc->opcode = IBV_WC_SEND;
break;
case FW_RI_BIND_MW:
@@ -182,13 +182,24 @@ static int build_rdma_send(struct t4_sq *sq, union t4_wr *wqe,
if (wr->num_sge > T4_MAX_SEND_SGE)
return -EINVAL;
- if (wr->send_flags & IBV_SEND_SOLICITED)
- wqe->send.sendop_pkd = htobe32(
- FW_RI_SEND_WR_SENDOP_V(FW_RI_SEND_WITH_SE));
- else
- wqe->send.sendop_pkd = htobe32(
- FW_RI_SEND_WR_SENDOP_V(FW_RI_SEND));
- wqe->send.stag_inv = 0;
+ switch (wr->opcode) {
+ case IBV_WR_SEND:
+ if (wr->send_flags & IBV_SEND_SOLICITED)
+ wqe->send.sendop_pkd = htobe32(FW_RI_SEND_WR_SENDOP_V(FW_RI_SEND_WITH_SE));
+ else
+ wqe->send.sendop_pkd = htobe32(FW_RI_SEND_WR_SENDOP_V(FW_RI_SEND));
+ wqe->send.stag_inv = 0;
+ break;
+ case IBV_WR_SEND_WITH_INV:
+ if (wr->send_flags & IBV_SEND_SOLICITED)
+ wqe->send.sendop_pkd = htobe32(FW_RI_SEND_WR_SENDOP_V(FW_RI_SEND_WITH_SE_INV));
+ else
+ wqe->send.sendop_pkd = htobe32(FW_RI_SEND_WR_SENDOP_V(FW_RI_SEND_WITH_INV));
+ wqe->send.stag_inv = htobe32(wr->invalidate_rkey);
+ break;
+ default:
+ return -EINVAL;
+ }
wqe->send.r3 = 0;
wqe->send.r4 = 0;
@@ -518,12 +529,16 @@ int c4iw_post_send(struct ibv_qp *ibqp, struct ibv_send_wr *wr,
fw_flags |= FW_RI_COMPLETION_FLAG;
swsqe = &qhp->wq.sq.sw_sq[qhp->wq.sq.pidx];
switch (wr->opcode) {
+ case IBV_WR_SEND_WITH_INV:
case IBV_WR_SEND:
INC_STAT(send);
if (wr->send_flags & IBV_SEND_FENCE)
fw_flags |= FW_RI_READ_FENCE_FLAG;
fw_opcode = FW_RI_SEND_WR;
- swsqe->opcode = FW_RI_SEND;
+ if (wr->opcode == IBV_WR_SEND)
+ swsqe->opcode = FW_RI_SEND;
+ else
+ swsqe->opcode = FW_RI_SEND_WITH_INV;
err = build_rdma_send(&qhp->wq.sq, wqe, wr, &len16);
break;
case IBV_WR_RDMA_WRITE_WITH_IMM: