@@ -192,6 +192,8 @@ struct qelr_qp_hwq_info {
void *db; /* Doorbell address */
void *edpm_db;
union db_prod32 db_data; /* Doorbell data */
+ void *iwarp_db2; /* iWARP RQ Doorbell address */
+ union db_prod32 iwarp_db2_data; /* iWARP RQ Doorbell data */
uint16_t icid;
};
@@ -59,6 +59,9 @@
#define QELR_RQE_ELEMENT_SIZE (sizeof(struct rdma_rq_sge))
#define QELR_CQE_SIZE (sizeof(union rdma_cqe))
+#define IS_IWARP(_dev) (_dev->node_type == IBV_NODE_RNIC)
+#define IS_ROCE(_dev) (_dev->node_type == IBV_NODE_CA)
+
static void qelr_inc_sw_cons_u16(struct qelr_qp_hwq_info *info)
{
info->cons = (info->cons + 1) % info->max_wr;
@@ -434,6 +437,9 @@ static inline int qelr_configure_qp_rq(struct qelr_devctx *cxt,
qp->rq.icid = resp->rq_icid;
qp->rq.db_data.data.icid = htole16(resp->rq_icid);
qp->rq.db = cxt->db_addr + resp->rq_db_offset;
+ qp->rq.iwarp_db2 = cxt->db_addr + resp->rq_db2_offset;
+ qp->rq.iwarp_db2_data.data.icid = qp->rq.icid;
+ qp->rq.iwarp_db2_data.data.value = DQ_TCM_IWARP_POST_RQ_CF_CMD;
qp->rq.prod = 0;
/* shadow RQ */
@@ -648,6 +654,12 @@ static int qelr_update_qp_state(struct qelr_qp *qp,
int status = 0;
enum qelr_qp_state new_state;
+ /* iWARP states are updated implicitely by driver and don't have a
+ * real purpose in user-lib.
+ */
+ if (IS_IWARP(qp->ibv_qp.context->device))
+ return 0;
+
new_state = get_qelr_qp_state(new_ib_state);
pthread_spin_lock(&qp->q_lock);
@@ -677,9 +689,11 @@ static int qelr_update_qp_state(struct qelr_qp *qp,
/* Update doorbell (in case post_recv was done before
* move to RTR)
*/
- mmio_wc_start();
- writel(qp->rq.db_data.raw, qp->rq.db);
- mmio_flush_writes();
+ if (IS_ROCE(qp->ibv_qp.context->device)) {
+ mmio_wc_start();
+ writel(qp->rq.db_data.raw, qp->rq.db);
+ mmio_flush_writes();
+ }
break;
case QELR_QPS_ERR:
break;
@@ -870,6 +884,10 @@ static inline void qelr_init_edpm_info(struct qelr_devctx *cxt,
{
edpm->is_edpm = 0;
+ /* Currently dpm is not supported for iWARP */
+ if (IS_IWARP(cxt->ibv_ctx.device))
+ return;
+
if (qelr_chain_is_full(&qp->sq.chain) &&
wr->send_flags & IBV_SEND_INLINE && !qp->edpm_disabled) {
memset(edpm, 0, sizeof(*edpm));
@@ -1405,7 +1423,8 @@ int qelr_post_send(struct ibv_qp *ib_qp, struct ibv_send_wr *wr,
pthread_spin_lock(&qp->q_lock);
- if ((qp->state != QELR_QPS_RTS && qp->state != QELR_QPS_ERR &&
+ if (IS_ROCE(ib_qp->context->device) &&
+ (qp->state != QELR_QPS_RTS && qp->state != QELR_QPS_ERR &&
qp->state != QELR_QPS_SQD)) {
pthread_spin_unlock(&qp->q_lock);
*bad_wr = wr;
@@ -1445,10 +1464,11 @@ int qelr_post_recv(struct ibv_qp *ibqp, struct ibv_recv_wr *wr,
struct qelr_qp *qp = get_qelr_qp(ibqp);
struct qelr_devctx *cxt = get_qelr_ctx(ibqp->context);
uint16_t db_val;
+ uint8_t iwarp = IS_IWARP(ibqp->context->device);
pthread_spin_lock(&qp->q_lock);
- if (qp->state == QELR_QPS_RST) {
+ if (!iwarp && qp->state == QELR_QPS_RST) {
pthread_spin_unlock(&qp->q_lock);
*bad_wr = wr;
return -EINVAL;
@@ -1517,6 +1537,10 @@ int qelr_post_recv(struct ibv_qp *ibqp, struct ibv_recv_wr *wr,
writel(qp->rq.db_data.raw, qp->rq.db);
mmio_flush_writes();
+ if (iwarp) {
+ writel(qp->rq.iwarp_db2_data.raw, qp->rq.iwarp_db2);
+ mmio_flush_writes();
+ }
wr = wr->next;
}