@@ -197,9 +197,9 @@ struct qelr_qp_hwq_info {
};
struct qelr_rdma_ext {
- uint64_t remote_va;
- uint32_t remote_key;
- uint32_t dma_length;
+ __be64 remote_va;
+ __be32 remote_key;
+ __be32 dma_length;
};
/* rdma extension, invalidate / immediate data + padding, inline data... */
@@ -44,6 +44,7 @@
#include <malloc.h>
#include <sys/mman.h>
#include <unistd.h>
+#include <stdbool.h>
#include "qelr.h"
#include "qelr_abi.h"
@@ -856,10 +857,11 @@ static int sge_data_len(struct ibv_sge *sg_list, int num_sge)
static void swap_wqe_data64(uint64_t *p)
{
+ __be64 *bep=(__be64 *)p;
int i;
for (i = 0; i < ROCE_WQE_ELEM_SIZE / sizeof(uint64_t); i++, p++)
- *p = htobe64(htole64(*p));
+ *bep = htobe64(*p);
}
static inline void qelr_init_dpm_info(struct qelr_devctx *cxt,
@@ -893,32 +895,26 @@ static inline void qelr_edpm_set_msg_data(struct qelr_qp *qp,
uint8_t se,
uint8_t comp)
{
- uint32_t wqe_size, dpm_size;
+ uint32_t wqe_size, dpm_size, params;
+
+ params = 0;
wqe_size = length + (QELR_IS_IMM(opcode)? sizeof(uint32_t) : 0);
dpm_size = wqe_size + sizeof(struct db_roce_dpm_data);
- SET_FIELD(dpm->msg.data.params.params, DB_ROCE_DPM_PARAMS_SIZE,
+ SET_FIELD(params, DB_ROCE_DPM_PARAMS_DPM_TYPE, DPM_ROCE);
+ SET_FIELD(params, DB_ROCE_DPM_PARAMS_OPCODE, opcode);
+ SET_FIELD(params, DB_ROCE_DPM_PARAMS_WQE_SIZE, wqe_size);
+ SET_FIELD(params, DB_ROCE_DPM_PARAMS_COMPLETION_FLG, comp ? 1 : 0);
+ SET_FIELD(params, DB_ROCE_DPM_PARAMS_S_FLG, se ? 1 : 0);
+ SET_FIELD(params, DB_ROCE_DPM_PARAMS_SIZE,
(dpm_size + sizeof(uint64_t) - 1) / sizeof(uint64_t));
- SET_FIELD(dpm->msg.data.params.params, DB_ROCE_DPM_PARAMS_DPM_TYPE,
- DPM_ROCE);
-
- SET_FIELD(dpm->msg.data.params.params, DB_ROCE_DPM_PARAMS_OPCODE,
- opcode);
-
- SET_FIELD(dpm->msg.data.params.params, DB_ROCE_DPM_PARAMS_WQE_SIZE,
- wqe_size);
-
- SET_FIELD(dpm->msg.data.params.params,
- DB_ROCE_DPM_PARAMS_COMPLETION_FLG, comp ? 1 : 0);
-
- SET_FIELD(dpm->msg.data.params.params, DB_ROCE_DPM_PARAMS_S_FLG,
- se ? 1 : 0);
+ dpm->msg.data.params.params = htole32(params);
}
static inline void qelr_edpm_set_inv_imm(struct qelr_qp *qp,
struct qelr_dpm *dpm,
- uint32_t data)
+ __be32 data)
{
memcpy(&dpm->payload[dpm->payload_offset], &data, sizeof(data));
@@ -1036,16 +1032,19 @@ static void qelr_prepare_sq_sges(struct qelr_qp *qp,
*wqe_size += wr->num_sge;
}
-static void qelr_prepare_sq_rdma_data(struct qelr_qp *qp,
- struct qelr_dpm *dpm,
- int data_size,
- struct rdma_sq_rdma_wqe_1st *rwqe,
- struct rdma_sq_rdma_wqe_2nd *rwqe2,
- struct ibv_send_wr *wr)
+static uint32_t qelr_prepare_sq_rdma_data(struct qelr_qp *qp,
+ struct qelr_dpm *dpm,
+ int data_size,
+ uint8_t wqe_size,
+ struct rdma_sq_rdma_wqe_1st *rwqe,
+ struct rdma_sq_rdma_wqe_2nd *rwqe2,
+ struct ibv_send_wr *wr,
+ bool is_imm)
{
memset(rwqe2, 0, sizeof(*rwqe2));
rwqe2->r_key = htole32(wr->wr.rdma.rkey);
TYPEPTR_ADDR_SET(rwqe2, remote_va, wr->wr.rdma.remote_addr);
+ rwqe->wqe_size = wqe_size;
if (wr->send_flags & IBV_SEND_INLINE &&
(wr->opcode == IBV_WR_RDMA_WRITE_WITH_IMM ||
@@ -1059,17 +1058,27 @@ static void qelr_prepare_sq_rdma_data(struct qelr_qp *qp,
} else {
qelr_prepare_sq_sges(qp, dpm, &rwqe->wqe_size, wr);
}
+
rwqe->length = htole32(data_size);
+
+ if (is_imm)
+ rwqe->imm_data = htole32(be32toh(wr->imm_data));
+
+ return data_size;
}
-static void qelr_prepare_sq_send_data(struct qelr_qp *qp,
- struct qelr_dpm *dpm,
- int data_size,
- struct rdma_sq_send_wqe_1st *swqe,
- struct rdma_sq_send_wqe_2st *swqe2,
- struct ibv_send_wr *wr)
+static uint32_t qelr_prepare_sq_send_data(struct qelr_qp *qp,
+ struct qelr_dpm *dpm,
+ int data_size,
+ uint8_t wqe_size,
+ struct rdma_sq_send_wqe_1st *swqe,
+ struct rdma_sq_send_wqe_2st *swqe2,
+ struct ibv_send_wr *wr,
+ bool is_imm)
{
memset(swqe2, 0, sizeof(*swqe2));
+ swqe->wqe_size = wqe_size;
+
if (wr->send_flags & IBV_SEND_INLINE) {
uint8_t flags = 0;
@@ -1082,6 +1091,11 @@ static void qelr_prepare_sq_send_data(struct qelr_qp *qp,
}
swqe->length = htole32(data_size);
+
+ if (is_imm)
+ swqe->inv_key_or_imm_data = htole32(be32toh(wr->imm_data));
+
+ return data_size;
}
static enum ibv_wc_opcode qelr_ibv_to_wc_opcode(enum ibv_wr_opcode opcode)
@@ -1218,6 +1232,8 @@ static int __qelr_post_send(struct qelr_devctx *cxt, struct qelr_qp *qp,
struct rdma_sq_atomic_wqe_2nd *awqe2;
struct rdma_sq_atomic_wqe_3rd *awqe3;
struct qelr_dpm dpm;
+ uint32_t wqe_length;
+ uint8_t wqe_size;
uint16_t db_val;
int rc = 0;
@@ -1245,45 +1261,51 @@ static int __qelr_post_send(struct qelr_devctx *cxt, struct qelr_qp *qp,
wqe->req_type = RDMA_SQ_REQ_TYPE_SEND_WITH_IMM;
swqe = (struct rdma_sq_send_wqe_1st *)wqe;
- swqe->wqe_size = 2;
+ wqe_size = sizeof(struct rdma_sq_send_wqe) / sizeof(uint64_t);
swqe2 = (struct rdma_sq_send_wqe_2st *)qelr_chain_produce(&qp->sq.chain);
- swqe->inv_key_or_imm_data = htobe32(htole32(wr->imm_data));
+
if (dpm.is_edpm)
qelr_edpm_set_inv_imm(qp, &dpm, wr->imm_data);
- qelr_prepare_sq_send_data(qp, &dpm, data_size, swqe, swqe2, wr);
+ wqe_length = qelr_prepare_sq_send_data(qp, &dpm, data_size,
+ wqe_size, swqe, swqe2,
+ wr, 1 /* Imm */);
+
if (dpm.is_edpm)
qelr_edpm_set_msg_data(qp, &dpm,
QELR_IB_OPCODE_SEND_ONLY_WITH_IMMEDIATE,
- swqe->length, se, comp);
- qp->wqe_wr_id[qp->sq.prod].wqe_size = swqe->wqe_size;
- qp->prev_wqe_size = swqe->wqe_size;
- qp->wqe_wr_id[qp->sq.prod].bytes_len = swqe->length;
+ wqe_length, se, comp);
+
+ qp->wqe_wr_id[qp->sq.prod].wqe_size = wqe_size;
+ qp->prev_wqe_size = wqe_size;
+ qp->wqe_wr_id[qp->sq.prod].bytes_len = wqe_length;
break;
case IBV_WR_SEND:
wqe->req_type = RDMA_SQ_REQ_TYPE_SEND;
swqe = (struct rdma_sq_send_wqe_1st *)wqe;
- swqe->wqe_size = 2;
+ wqe_size = sizeof(struct rdma_sq_send_wqe) / sizeof(uint64_t);
swqe2 = (struct rdma_sq_send_wqe_2st *)qelr_chain_produce(&qp->sq.chain);
- qelr_prepare_sq_send_data(qp, &dpm, data_size, swqe, swqe2, wr);
+ wqe_length = qelr_prepare_sq_send_data(qp, &dpm, data_size,
+ wqe_size, swqe, swqe2,
+ wr, 0);
if (dpm.is_edpm)
qelr_edpm_set_msg_data(qp, &dpm,
QELR_IB_OPCODE_SEND_ONLY,
- swqe->length, se, comp);
- qp->wqe_wr_id[qp->sq.prod].wqe_size = swqe->wqe_size;
- qp->prev_wqe_size = swqe->wqe_size;
- qp->wqe_wr_id[qp->sq.prod].bytes_len = swqe->length;
+ wqe_length, se, comp);
+
+ qp->wqe_wr_id[qp->sq.prod].wqe_size = wqe_size;
+ qp->prev_wqe_size = wqe_size;
+ qp->wqe_wr_id[qp->sq.prod].bytes_len = wqe_length;
break;
case IBV_WR_RDMA_WRITE_WITH_IMM:
wqe->req_type = RDMA_SQ_REQ_TYPE_RDMA_WR_WITH_IMM;
rwqe = (struct rdma_sq_rdma_wqe_1st *)wqe;
- rwqe->wqe_size = 2;
- rwqe->imm_data = htobe32(htole32(wr->imm_data));
+ wqe_size = sizeof(struct rdma_sq_rdma_wqe) / sizeof(uint64_t);
rwqe2 = (struct rdma_sq_rdma_wqe_2nd *)qelr_chain_produce(&qp->sq.chain);
if (dpm.is_edpm) {
qelr_edpm_set_rdma_ext(qp, &dpm, wr->wr.rdma.remote_addr,
@@ -1291,50 +1313,50 @@ static int __qelr_post_send(struct qelr_devctx *cxt, struct qelr_qp *qp,
qelr_edpm_set_inv_imm(qp, &dpm, wr->imm_data);
}
- qelr_prepare_sq_rdma_data(qp, &dpm, data_size, rwqe, rwqe2, wr);
+ wqe_length = qelr_prepare_sq_rdma_data(qp, &dpm, data_size, wqe_size, rwqe, rwqe2, wr, 1 /* Imm */);
if (dpm.is_edpm)
qelr_edpm_set_msg_data(qp, &dpm,
QELR_IB_OPCODE_RDMA_WRITE_ONLY_WITH_IMMEDIATE,
- rwqe->length + sizeof(*dpm.rdma_ext),
+ wqe_length + sizeof(*dpm.rdma_ext),
se, comp);
- qp->wqe_wr_id[qp->sq.prod].wqe_size = rwqe->wqe_size;
- qp->prev_wqe_size = rwqe->wqe_size;
- qp->wqe_wr_id[qp->sq.prod].bytes_len = rwqe->length;
+ qp->wqe_wr_id[qp->sq.prod].wqe_size = wqe_size;
+ qp->prev_wqe_size = wqe_size;
+ qp->wqe_wr_id[qp->sq.prod].bytes_len = wqe_length;
break;
case IBV_WR_RDMA_WRITE:
wqe->req_type = RDMA_SQ_REQ_TYPE_RDMA_WR;
rwqe = (struct rdma_sq_rdma_wqe_1st *)wqe;
- rwqe->wqe_size = 2;
+ wqe_size = sizeof(struct rdma_sq_rdma_wqe) / sizeof(uint64_t);
rwqe2 = (struct rdma_sq_rdma_wqe_2nd *)qelr_chain_produce(&qp->sq.chain);
if (dpm.is_edpm)
qelr_edpm_set_rdma_ext(qp, &dpm,
wr->wr.rdma.remote_addr,
wr->wr.rdma.rkey);
- qelr_prepare_sq_rdma_data(qp, &dpm, data_size, rwqe, rwqe2, wr);
+ wqe_length = qelr_prepare_sq_rdma_data(qp, &dpm, data_size, wqe_size, rwqe, rwqe2, wr, 0);
if (dpm.is_edpm)
qelr_edpm_set_msg_data(qp, &dpm,
QELR_IB_OPCODE_RDMA_WRITE_ONLY,
- rwqe->length +
+ wqe_length +
sizeof(*dpm.rdma_ext),
se, comp);
- qp->wqe_wr_id[qp->sq.prod].wqe_size = rwqe->wqe_size;
- qp->prev_wqe_size = rwqe->wqe_size;
- qp->wqe_wr_id[qp->sq.prod].bytes_len = rwqe->length;
+ qp->wqe_wr_id[qp->sq.prod].wqe_size = wqe_size;
+ qp->prev_wqe_size = wqe_size;
+ qp->wqe_wr_id[qp->sq.prod].bytes_len = wqe_length;
break;
case IBV_WR_RDMA_READ:
wqe->req_type = RDMA_SQ_REQ_TYPE_RDMA_RD;
rwqe = (struct rdma_sq_rdma_wqe_1st *)wqe;
- rwqe->wqe_size = 2;
+ wqe_size = sizeof(struct rdma_sq_rdma_wqe) / sizeof(uint64_t);
rwqe2 = (struct rdma_sq_rdma_wqe_2nd *)qelr_chain_produce(&qp->sq.chain);
- qelr_prepare_sq_rdma_data(qp, &dpm, data_size, rwqe, rwqe2, wr);
- qp->wqe_wr_id[qp->sq.prod].wqe_size = rwqe->wqe_size;
- qp->prev_wqe_size = rwqe->wqe_size;
- qp->wqe_wr_id[qp->sq.prod].bytes_len = rwqe->length;
+ wqe_length = qelr_prepare_sq_rdma_data(qp, &dpm, data_size, wqe_size, rwqe, rwqe2, wr, 0);
+ qp->wqe_wr_id[qp->sq.prod].wqe_size = wqe_size;
+ qp->prev_wqe_size = wqe_size;
+ qp->wqe_wr_id[qp->sq.prod].bytes_len = wqe_length;
break;
case IBV_WR_ATOMIC_CMP_AND_SWP:
@@ -1548,7 +1570,7 @@ static struct qelr_qp *cqe_get_qp(union rdma_cqe *cqe)
{
struct regpair *qph = &cqe->req.qp_handle;
- return (struct qelr_qp *)HILO_U64(qph->hi, qph->lo);
+ return (struct qelr_qp *)HILO_U64(le32toh(qph->hi), le32toh(qph->lo));
}
static int process_req(struct qelr_qp *qp, struct qelr_cq *cq, int num_entries,
@@ -1612,24 +1634,25 @@ static int qelr_poll_cq_req(struct qelr_qp *qp, struct qelr_cq *cq,
struct rdma_cqe_requester *req)
{
struct qelr_devctx *cxt = get_qelr_ctx(qp->ibv_qp.context);
+ uint16_t sq_cons = le16toh(req->sq_cons);
int cnt = 0;
switch (req->status) {
case RDMA_CQE_REQ_STS_OK:
- cnt = process_req(qp, cq, num_entries, wc, req->sq_cons,
+ cnt = process_req(qp, cq, num_entries, wc, sq_cons,
IBV_WC_SUCCESS, 0);
break;
case RDMA_CQE_REQ_STS_WORK_REQUEST_FLUSHED_ERR:
DP_ERR(cxt->dbg_fp,
"Error: POLL CQ with ROCE_CQE_REQ_STS_WORK_REQUEST_FLUSHED_ERR. QP icid=0x%x\n",
qp->sq.icid);
- cnt = process_req(qp, cq, num_entries, wc, req->sq_cons,
+ cnt = process_req(qp, cq, num_entries, wc, sq_cons,
IBV_WC_WR_FLUSH_ERR, 0);
break;
default: /* other errors case */
/* process all WQE before the consumer */
qp->state = QELR_QPS_ERR;
- cnt = process_req(qp, cq, num_entries, wc, req->sq_cons - 1,
+ cnt = process_req(qp, cq, num_entries, wc, sq_cons - 1,
IBV_WC_SUCCESS, 0);
wc += cnt;
/* if we have extra WC fill it with actual error info */
@@ -1704,8 +1727,8 @@ static int qelr_poll_cq_req(struct qelr_qp *qp, struct qelr_cq *cq,
wc_status = IBV_WC_GENERAL_ERR;
}
- cnt += process_req(qp, cq, 1, wc, req->sq_cons,
- wc_status, 1 /* force use of WC */);
+ cnt += process_req(qp, cq, 1, wc, sq_cons, wc_status,
+ 1 /* force use of WC */);
}
}
@@ -1754,8 +1777,7 @@ static void __process_resp_one(struct qelr_qp *qp, struct qelr_cq *cq,
wc->opcode = IBV_WC_RECV_RDMA_WITH_IMM;
SWITCH_FALLTHROUGH;
case QELR_RESP_IMM:
- wc->imm_data =
- be32toh(le32toh(resp->imm_data_or_inv_r_Key));
+ wc->imm_data = htobe32(le32toh(resp->imm_data_or_inv_r_Key));
wc->wc_flags |= IBV_WC_WITH_IMM;
break;
case QELR_RESP_RDMA:
@@ -1825,7 +1847,9 @@ static union rdma_cqe *get_cqe(struct qelr_cq *cq)
static void try_consume_req_cqe(struct qelr_cq *cq, struct qelr_qp *qp,
struct rdma_cqe_requester *req, int *update)
{
- if (le16toh(req->sq_cons) == qp->sq.wqe_cons) {
+ uint16_t sq_cons = le16toh(req->sq_cons);
+
+ if (sq_cons == qp->sq.wqe_cons) {
consume_cqe(cq);
*update |= 1;
}
@@ -1833,9 +1857,9 @@ static void try_consume_req_cqe(struct qelr_cq *cq, struct qelr_qp *qp,
/* used with flush only, when resp->rq_cons is valid */
static void try_consume_resp_cqe(struct qelr_cq *cq, struct qelr_qp *qp,
- struct rdma_cqe_responder *resp, int *update)
+ uint16_t rq_cons, int *update)
{
- if (le16toh(resp->rq_cons) == qp->rq.wqe_cons) {
+ if (rq_cons == qp->rq.wqe_cons) {
consume_cqe(cq);
*update |= 1;
}
@@ -1845,12 +1869,12 @@ static int qelr_poll_cq_resp(struct qelr_qp *qp, struct qelr_cq *cq,
int num_entries, struct ibv_wc *wc,
struct rdma_cqe_responder *resp, int *update)
{
+ uint16_t rq_cons = le16toh(resp->rq_cons);
int cnt;
if (resp->status == RDMA_CQE_RESP_STS_WORK_REQUEST_FLUSHED_ERR) {
- cnt = process_resp_flush(qp, cq, num_entries, wc,
- resp->rq_cons);
- try_consume_resp_cqe(cq, qp, resp, update);
+ cnt = process_resp_flush(qp, cq, num_entries, wc, rq_cons);
+ try_consume_resp_cqe(cq, qp, rq_cons, update);
} else {
cnt = process_resp_one(qp, cq, wc, resp);
consume_cqe(cq);