Skip to content

Commit

Permalink
RDMA/qedr: add support for send+invalidate in poll CQ
Browse files Browse the repository at this point in the history
Split the poll responder CQ into two functions.
Add support for send+invalidate in poll CQ.

Signed-off-by: Ram Amrani <Ram.Amrani@cavium.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
  • Loading branch information
Amrani, Ram authored and Doug Ledford committed Apr 28, 2017
1 parent 4dd7263 commit b6acd71
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 38 deletions.
3 changes: 2 additions & 1 deletion drivers/infiniband/hw/qedr/qedr.h
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,8 @@ struct qedr_mr {
RDMA_CQE_RESPONDER_IMM_FLG_SHIFT)
#define QEDR_RESP_RDMA (RDMA_CQE_RESPONDER_RDMA_FLG_MASK << \
RDMA_CQE_RESPONDER_RDMA_FLG_SHIFT)
#define QEDR_RESP_RDMA_IMM (QEDR_RESP_IMM | QEDR_RESP_RDMA)
#define QEDR_RESP_INV (RDMA_CQE_RESPONDER_INV_FLG_MASK << \
RDMA_CQE_RESPONDER_INV_FLG_SHIFT)

static inline void qedr_inc_sw_cons(struct qedr_qp_hwq_info *info)
{
Expand Down
98 changes: 61 additions & 37 deletions drivers/infiniband/hw/qedr/verbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -3331,57 +3331,81 @@ static int qedr_poll_cq_req(struct qedr_dev *dev,
return cnt;
}

static void __process_resp_one(struct qedr_dev *dev, struct qedr_qp *qp,
struct qedr_cq *cq, struct ib_wc *wc,
struct rdma_cqe_responder *resp, u64 wr_id)
static inline int qedr_cqe_resp_status_to_ib(u8 status)
{
enum ib_wc_status wc_status = IB_WC_SUCCESS;
u8 flags;

wc->opcode = IB_WC_RECV;
wc->wc_flags = 0;

switch (resp->status) {
switch (status) {
case RDMA_CQE_RESP_STS_LOCAL_ACCESS_ERR:
wc_status = IB_WC_LOC_ACCESS_ERR;
break;
return IB_WC_LOC_ACCESS_ERR;
case RDMA_CQE_RESP_STS_LOCAL_LENGTH_ERR:
wc_status = IB_WC_LOC_LEN_ERR;
break;
return IB_WC_LOC_LEN_ERR;
case RDMA_CQE_RESP_STS_LOCAL_QP_OPERATION_ERR:
wc_status = IB_WC_LOC_QP_OP_ERR;
break;
return IB_WC_LOC_QP_OP_ERR;
case RDMA_CQE_RESP_STS_LOCAL_PROTECTION_ERR:
wc_status = IB_WC_LOC_PROT_ERR;
break;
return IB_WC_LOC_PROT_ERR;
case RDMA_CQE_RESP_STS_MEMORY_MGT_OPERATION_ERR:
wc_status = IB_WC_MW_BIND_ERR;
break;
return IB_WC_MW_BIND_ERR;
case RDMA_CQE_RESP_STS_REMOTE_INVALID_REQUEST_ERR:
wc_status = IB_WC_REM_INV_RD_REQ_ERR;
break;
return IB_WC_REM_INV_RD_REQ_ERR;
case RDMA_CQE_RESP_STS_OK:
wc_status = IB_WC_SUCCESS;
wc->byte_len = le32_to_cpu(resp->length);
return IB_WC_SUCCESS;
default:
return IB_WC_GENERAL_ERR;
}
}

flags = resp->flags & QEDR_RESP_RDMA_IMM;
static inline int qedr_set_ok_cqe_resp_wc(struct rdma_cqe_responder *resp,
struct ib_wc *wc)
{
wc->status = IB_WC_SUCCESS;
wc->byte_len = le32_to_cpu(resp->length);

if (flags == QEDR_RESP_RDMA_IMM)
if (resp->flags & QEDR_RESP_IMM) {
wc->ex.imm_data = le32_to_cpu(resp->imm_data_or_inv_r_Key);
wc->wc_flags |= IB_WC_WITH_IMM;

if (resp->flags & QEDR_RESP_RDMA)
wc->opcode = IB_WC_RECV_RDMA_WITH_IMM;

if (flags == QEDR_RESP_RDMA_IMM || flags == QEDR_RESP_IMM) {
wc->ex.imm_data =
le32_to_cpu(resp->imm_data_or_inv_r_Key);
wc->wc_flags |= IB_WC_WITH_IMM;
}
break;
default:
wc->status = IB_WC_GENERAL_ERR;
DP_ERR(dev, "Invalid CQE status detected\n");
if (resp->flags & QEDR_RESP_INV)
return -EINVAL;

} else if (resp->flags & QEDR_RESP_INV) {
wc->ex.imm_data = le32_to_cpu(resp->imm_data_or_inv_r_Key);
wc->wc_flags |= IB_WC_WITH_INVALIDATE;

if (resp->flags & QEDR_RESP_RDMA)
return -EINVAL;

} else if (resp->flags & QEDR_RESP_RDMA) {
return -EINVAL;
}

return 0;
}

static void __process_resp_one(struct qedr_dev *dev, struct qedr_qp *qp,
struct qedr_cq *cq, struct ib_wc *wc,
struct rdma_cqe_responder *resp, u64 wr_id)
{
/* Must fill fields before qedr_set_ok_cqe_resp_wc() */
wc->opcode = IB_WC_RECV;
wc->wc_flags = 0;

if (likely(resp->status == RDMA_CQE_RESP_STS_OK)) {
if (qedr_set_ok_cqe_resp_wc(resp, wc))
DP_ERR(dev,
"CQ %p (icid=%d) has invalid CQE responder flags=0x%x\n",
cq, cq->icid, resp->flags);

} else {
wc->status = qedr_cqe_resp_status_to_ib(resp->status);
if (wc->status == IB_WC_GENERAL_ERR)
DP_ERR(dev,
"CQ %p (icid=%d) contains an invalid CQE status %d\n",
cq, cq->icid, resp->status);
}

/* fill WC */
wc->status = wc_status;
/* Fill the rest of the WC */
wc->vendor_err = 0;
wc->src_qp = qp->id;
wc->qp = &qp->ibqp;
Expand Down

0 comments on commit b6acd71

Please sign in to comment.