[v3,16/25] common/mlx5: add support for DevX QP operations
diff mbox series

Message ID 1580228860-10665-17-git-send-email-matan@mellanox.com
State Superseded
Delegated to: Raslan Darawsheh
Headers show
Series
  • Introduce mlx5 common library
Related show

Checks

Context Check Description
ci/Intel-compilation fail apply issues
ci/checkpatch warning coding style issues

Commit Message

Matan Azrad Jan. 28, 2020, 4:27 p.m. UTC
QP creation is needed for vDPA virtq support.

Add 2 DevX commands to create QP and to modify QP state.

The support is for RC QP only in force loopback address mode.

By this way, the packets can be sent to other inernal destinations in
the nic. For example: other QPs or virtqs.

Signed-off-by: Matan Azrad <matan@mellanox.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
---
 drivers/common/mlx5/mlx5_devx_cmds.c            | 167 ++++++++++-
 drivers/common/mlx5/mlx5_devx_cmds.h            |  20 ++
 drivers/common/mlx5/mlx5_prm.h                  | 376 ++++++++++++++++++++++++
 drivers/common/mlx5/rte_common_mlx5_version.map |   2 +
 4 files changed, 564 insertions(+), 1 deletion(-)

Patch
diff mbox series

diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c
index 2425513..e7288c8 100644
--- a/drivers/common/mlx5/mlx5_devx_cmds.c
+++ b/drivers/common/mlx5/mlx5_devx_cmds.c
@@ -1124,7 +1124,8 @@  struct mlx5_devx_obj *
 	MLX5_SET(cqc, cqctx, cc, attr->use_first_only);
 	MLX5_SET(cqc, cqctx, oi, attr->overrun_ignore);
 	MLX5_SET(cqc, cqctx, log_cq_size, attr->log_cq_size);
-	MLX5_SET(cqc, cqctx, log_page_size, attr->log_page_size);
+	MLX5_SET(cqc, cqctx, log_page_size, attr->log_page_size -
+		 MLX5_ADAPTER_PAGE_SHIFT);
 	MLX5_SET(cqc, cqctx, c_eqn, attr->eqn);
 	MLX5_SET(cqc, cqctx, uar_page, attr->uar_page_id);
 	if (attr->q_umem_valid) {
@@ -1313,3 +1314,167 @@  struct mlx5_devx_obj *
 	attr->hw_used_index = MLX5_GET16(virtio_net_q, virtq, hw_used_index);
 	return ret;
 }
+
+/**
+ * Create QP using DevX API.
+ *
+ * @param[in] ctx
+ *   ibv_context returned from mlx5dv_open_device.
+ * @param [in] attr
+ *   Pointer to QP attributes structure.
+ *
+ * @return
+ *   The DevX object created, NULL otherwise and rte_errno is set.
+ */
+struct mlx5_devx_obj *
+mlx5_devx_cmd_create_qp(struct ibv_context *ctx,
+			struct mlx5_devx_qp_attr *attr)
+{
+	uint32_t in[MLX5_ST_SZ_DW(create_qp_in)] = {0};
+	uint32_t out[MLX5_ST_SZ_DW(create_qp_out)] = {0};
+	struct mlx5_devx_obj *qp_obj = rte_zmalloc(__func__, sizeof(*qp_obj),
+						   0);
+	void *qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
+
+	if (!qp_obj) {
+		DRV_LOG(ERR, "Failed to allocate QP data.");
+		rte_errno = ENOMEM;
+		return NULL;
+	}
+	MLX5_SET(create_qp_in, in, opcode, MLX5_CMD_OP_CREATE_QP);
+	MLX5_SET(qpc, qpc, st, MLX5_QP_ST_RC);
+	MLX5_SET(qpc, qpc, pd, attr->pd);
+	if (attr->uar_index) {
+		MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);
+		MLX5_SET(qpc, qpc, uar_page, attr->uar_index);
+		MLX5_SET(qpc, qpc, log_page_size, attr->log_page_size -
+			 MLX5_ADAPTER_PAGE_SHIFT);
+		if (attr->sq_size) {
+			RTE_ASSERT(RTE_IS_POWER_OF_2(attr->sq_size));
+			MLX5_SET(qpc, qpc, cqn_snd, attr->cqn);
+			MLX5_SET(qpc, qpc, log_sq_size,
+				 rte_log2_u32(attr->sq_size));
+		} else {
+			MLX5_SET(qpc, qpc, no_sq, 1);
+		}
+		if (attr->rq_size) {
+			RTE_ASSERT(RTE_IS_POWER_OF_2(attr->rq_size));
+			MLX5_SET(qpc, qpc, cqn_rcv, attr->cqn);
+			MLX5_SET(qpc, qpc, log_rq_stride, attr->log_rq_stride -
+				 MLX5_LOG_RQ_STRIDE_SHIFT);
+			MLX5_SET(qpc, qpc, log_rq_size,
+				 rte_log2_u32(attr->rq_size));
+			MLX5_SET(qpc, qpc, rq_type, MLX5_NON_ZERO_RQ);
+		} else {
+			MLX5_SET(qpc, qpc, rq_type, MLX5_ZERO_LEN_RQ);
+		}
+		if (attr->dbr_umem_valid) {
+			MLX5_SET(qpc, qpc, dbr_umem_valid,
+				 attr->dbr_umem_valid);
+			MLX5_SET(qpc, qpc, dbr_umem_id, attr->dbr_umem_id);
+		}
+		MLX5_SET64(qpc, qpc, dbr_addr, attr->dbr_address);
+		MLX5_SET64(create_qp_in, in, wq_umem_offset,
+			   attr->wq_umem_offset);
+		MLX5_SET(create_qp_in, in, wq_umem_id, attr->wq_umem_id);
+		MLX5_SET(create_qp_in, in, wq_umem_valid, 1);
+	} else {
+		/* Special QP to be managed by FW - no SQ\RQ\CQ\UAR\DB rec. */
+		MLX5_SET(qpc, qpc, rq_type, MLX5_ZERO_LEN_RQ);
+		MLX5_SET(qpc, qpc, no_sq, 1);
+	}
+	qp_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out,
+						 sizeof(out));
+	if (!qp_obj->obj) {
+		rte_errno = errno;
+		DRV_LOG(ERR, "Failed to create QP Obj using DevX.");
+		rte_free(qp_obj);
+		return NULL;
+	}
+	qp_obj->id = MLX5_GET(create_qp_out, out, qpn);
+	return qp_obj;
+}
+
+/**
+ * Modify QP using DevX API.
+ * Currently supports only force loop-back QP.
+ *
+ * @param[in] qp
+ *   Pointer to QP object structure.
+ * @param [in] qp_st_mod_op
+ *   The QP state modification operation.
+ * @param [in] remote_qp_id
+ *   The remote QP ID for MLX5_CMD_OP_INIT2RTR_QP operation.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx5_devx_cmd_modify_qp_state(struct mlx5_devx_obj *qp, uint32_t qp_st_mod_op,
+			      uint32_t remote_qp_id)
+{
+	union {
+		uint32_t rst2init[MLX5_ST_SZ_DW(rst2init_qp_in)];
+		uint32_t init2rtr[MLX5_ST_SZ_DW(init2rtr_qp_in)];
+		uint32_t rtr2rts[MLX5_ST_SZ_DW(rtr2rts_qp_in)];
+	} in;
+	union {
+		uint32_t rst2init[MLX5_ST_SZ_DW(rst2init_qp_out)];
+		uint32_t init2rtr[MLX5_ST_SZ_DW(init2rtr_qp_out)];
+		uint32_t rtr2rts[MLX5_ST_SZ_DW(rtr2rts_qp_out)];
+	} out;
+	void *qpc;
+	int ret;
+	unsigned int inlen;
+	unsigned int outlen;
+
+	memset(&in, 0, sizeof(in));
+	memset(&out, 0, sizeof(out));
+	MLX5_SET(rst2init_qp_in, &in, opcode, qp_st_mod_op);
+	switch (qp_st_mod_op) {
+	case MLX5_CMD_OP_RST2INIT_QP:
+		MLX5_SET(rst2init_qp_in, &in, qpn, qp->id);
+		qpc = MLX5_ADDR_OF(rst2init_qp_in, &in, qpc);
+		MLX5_SET(qpc, qpc, primary_address_path.vhca_port_num, 1);
+		MLX5_SET(qpc, qpc, rre, 1);
+		MLX5_SET(qpc, qpc, rwe, 1);
+		MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);
+		inlen = sizeof(in.rst2init);
+		outlen = sizeof(out.rst2init);
+		break;
+	case MLX5_CMD_OP_INIT2RTR_QP:
+		MLX5_SET(init2rtr_qp_in, &in, qpn, qp->id);
+		qpc = MLX5_ADDR_OF(init2rtr_qp_in, &in, qpc);
+		MLX5_SET(qpc, qpc, primary_address_path.fl, 1);
+		MLX5_SET(qpc, qpc, primary_address_path.vhca_port_num, 1);
+		MLX5_SET(qpc, qpc, mtu, 1);
+		MLX5_SET(qpc, qpc, log_msg_max, 30);
+		MLX5_SET(qpc, qpc, remote_qpn, remote_qp_id);
+		MLX5_SET(qpc, qpc, min_rnr_nak, 0);
+		inlen = sizeof(in.init2rtr);
+		outlen = sizeof(out.init2rtr);
+		break;
+	case MLX5_CMD_OP_RTR2RTS_QP:
+		qpc = MLX5_ADDR_OF(rtr2rts_qp_in, &in, qpc);
+		MLX5_SET(rtr2rts_qp_in, &in, qpn, qp->id);
+		MLX5_SET(qpc, qpc, primary_address_path.ack_timeout, 14);
+		MLX5_SET(qpc, qpc, log_ack_req_freq, 0);
+		MLX5_SET(qpc, qpc, retry_count, 7);
+		MLX5_SET(qpc, qpc, rnr_retry, 7);
+		inlen = sizeof(in.rtr2rts);
+		outlen = sizeof(out.rtr2rts);
+		break;
+	default:
+		DRV_LOG(ERR, "Invalid or unsupported QP modify op %u.",
+			qp_st_mod_op);
+		rte_errno = EINVAL;
+		return -rte_errno;
+	}
+	ret = mlx5_glue->devx_obj_modify(qp->obj, &in, inlen, &out, outlen);
+	if (ret) {
+		DRV_LOG(ERR, "Failed to modify QP using DevX.");
+		rte_errno = errno;
+		return -errno;
+	}
+	return ret;
+}
diff --git a/drivers/common/mlx5/mlx5_devx_cmds.h b/drivers/common/mlx5/mlx5_devx_cmds.h
index 1631c08..d1a21b8 100644
--- a/drivers/common/mlx5/mlx5_devx_cmds.h
+++ b/drivers/common/mlx5/mlx5_devx_cmds.h
@@ -279,6 +279,22 @@  struct mlx5_devx_virtq_attr {
 	} umems[3];
 };
 
+
+struct mlx5_devx_qp_attr {
+	uint32_t pd:24;
+	uint32_t uar_index:24;
+	uint32_t cqn:24;
+	uint32_t log_page_size:5;
+	uint32_t rq_size:17; /* Must be power of 2. */
+	uint32_t log_rq_stride:3;
+	uint32_t sq_size:17; /* Must be power of 2. */
+	uint32_t dbr_umem_valid:1;
+	uint32_t dbr_umem_id;
+	uint64_t dbr_address;
+	uint32_t wq_umem_id;
+	uint64_t wq_umem_offset;
+};
+
 /* mlx5_devx_cmds.c */
 
 struct mlx5_devx_obj *mlx5_devx_cmd_flow_counter_alloc(struct ibv_context *ctx,
@@ -323,5 +339,9 @@  int mlx5_devx_cmd_modify_virtq(struct mlx5_devx_obj *virtq_obj,
 			       struct mlx5_devx_virtq_attr *attr);
 int mlx5_devx_cmd_query_virtq(struct mlx5_devx_obj *virtq_obj,
 			      struct mlx5_devx_virtq_attr *attr);
+struct mlx5_devx_obj *mlx5_devx_cmd_create_qp(struct ibv_context *ctx,
+					      struct mlx5_devx_qp_attr *attr);
+int mlx5_devx_cmd_modify_qp_state(struct mlx5_devx_obj *qp,
+				  uint32_t qp_st_mod_op, uint32_t remote_qp_id);
 
 #endif /* RTE_PMD_MLX5_DEVX_CMDS_H_ */
diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index 4b8a34c..e53dd61 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -724,6 +724,19 @@  enum {
 	MLX5_CMD_OP_QUERY_HCA_CAP = 0x100,
 	MLX5_CMD_OP_CREATE_MKEY = 0x200,
 	MLX5_CMD_OP_CREATE_CQ = 0x400,
+	MLX5_CMD_OP_CREATE_QP = 0x500,
+	MLX5_CMD_OP_RST2INIT_QP = 0x502,
+	MLX5_CMD_OP_INIT2RTR_QP = 0x503,
+	MLX5_CMD_OP_RTR2RTS_QP = 0x504,
+	MLX5_CMD_OP_RTS2RTS_QP = 0x505,
+	MLX5_CMD_OP_SQERR2RTS_QP = 0x506,
+	MLX5_CMD_OP_QP_2ERR = 0x507,
+	MLX5_CMD_OP_QP_2RST = 0x50A,
+	MLX5_CMD_OP_QUERY_QP = 0x50B,
+	MLX5_CMD_OP_SQD2RTS_QP = 0x50C,
+	MLX5_CMD_OP_INIT2INIT_QP = 0x50E,
+	MLX5_CMD_OP_SUSPEND_QP = 0x50F,
+	MLX5_CMD_OP_RESUME_QP = 0x510,
 	MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT = 0x754,
 	MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN = 0x816,
 	MLX5_CMD_OP_CREATE_TIR = 0x900,
@@ -747,6 +760,9 @@  enum {
 	MLX5_MKC_ACCESS_MODE_KLM_FBS = 0x3,
 };
 
+#define MLX5_ADAPTER_PAGE_SHIFT 12
+#define MLX5_LOG_RQ_STRIDE_SHIFT 4
+
 /* Flow counters. */
 struct mlx5_ifc_alloc_flow_counter_out_bits {
 	u8         status[0x8];
@@ -2034,6 +2050,366 @@  struct mlx5_ifc_query_virtq_out_bits {
 	struct mlx5_ifc_virtio_net_q_bits virtq;
 };
 
+enum {
+	MLX5_QP_ST_RC = 0x0,
+};
+
+enum {
+	MLX5_QP_PM_MIGRATED = 0x3,
+};
+
+enum {
+	MLX5_NON_ZERO_RQ = 0x0,
+	MLX5_SRQ_RQ = 0x1,
+	MLX5_CRQ_RQ = 0x2,
+	MLX5_ZERO_LEN_RQ = 0x3,
+};
+
+struct mlx5_ifc_ads_bits {
+	u8 fl[0x1];
+	u8 free_ar[0x1];
+	u8 reserved_at_2[0xe];
+	u8 pkey_index[0x10];
+	u8 reserved_at_20[0x8];
+	u8 grh[0x1];
+	u8 mlid[0x7];
+	u8 rlid[0x10];
+	u8 ack_timeout[0x5];
+	u8 reserved_at_45[0x3];
+	u8 src_addr_index[0x8];
+	u8 reserved_at_50[0x4];
+	u8 stat_rate[0x4];
+	u8 hop_limit[0x8];
+	u8 reserved_at_60[0x4];
+	u8 tclass[0x8];
+	u8 flow_label[0x14];
+	u8 rgid_rip[16][0x8];
+	u8 reserved_at_100[0x4];
+	u8 f_dscp[0x1];
+	u8 f_ecn[0x1];
+	u8 reserved_at_106[0x1];
+	u8 f_eth_prio[0x1];
+	u8 ecn[0x2];
+	u8 dscp[0x6];
+	u8 udp_sport[0x10];
+	u8 dei_cfi[0x1];
+	u8 eth_prio[0x3];
+	u8 sl[0x4];
+	u8 vhca_port_num[0x8];
+	u8 rmac_47_32[0x10];
+	u8 rmac_31_0[0x20];
+};
+
+struct mlx5_ifc_qpc_bits {
+	u8 state[0x4];
+	u8 lag_tx_port_affinity[0x4];
+	u8 st[0x8];
+	u8 reserved_at_10[0x3];
+	u8 pm_state[0x2];
+	u8 reserved_at_15[0x1];
+	u8 req_e2e_credit_mode[0x2];
+	u8 offload_type[0x4];
+	u8 end_padding_mode[0x2];
+	u8 reserved_at_1e[0x2];
+	u8 wq_signature[0x1];
+	u8 block_lb_mc[0x1];
+	u8 atomic_like_write_en[0x1];
+	u8 latency_sensitive[0x1];
+	u8 reserved_at_24[0x1];
+	u8 drain_sigerr[0x1];
+	u8 reserved_at_26[0x2];
+	u8 pd[0x18];
+	u8 mtu[0x3];
+	u8 log_msg_max[0x5];
+	u8 reserved_at_48[0x1];
+	u8 log_rq_size[0x4];
+	u8 log_rq_stride[0x3];
+	u8 no_sq[0x1];
+	u8 log_sq_size[0x4];
+	u8 reserved_at_55[0x6];
+	u8 rlky[0x1];
+	u8 ulp_stateless_offload_mode[0x4];
+	u8 counter_set_id[0x8];
+	u8 uar_page[0x18];
+	u8 reserved_at_80[0x8];
+	u8 user_index[0x18];
+	u8 reserved_at_a0[0x3];
+	u8 log_page_size[0x5];
+	u8 remote_qpn[0x18];
+	struct mlx5_ifc_ads_bits primary_address_path;
+	struct mlx5_ifc_ads_bits secondary_address_path;
+	u8 log_ack_req_freq[0x4];
+	u8 reserved_at_384[0x4];
+	u8 log_sra_max[0x3];
+	u8 reserved_at_38b[0x2];
+	u8 retry_count[0x3];
+	u8 rnr_retry[0x3];
+	u8 reserved_at_393[0x1];
+	u8 fre[0x1];
+	u8 cur_rnr_retry[0x3];
+	u8 cur_retry_count[0x3];
+	u8 reserved_at_39b[0x5];
+	u8 reserved_at_3a0[0x20];
+	u8 reserved_at_3c0[0x8];
+	u8 next_send_psn[0x18];
+	u8 reserved_at_3e0[0x8];
+	u8 cqn_snd[0x18];
+	u8 reserved_at_400[0x8];
+	u8 deth_sqpn[0x18];
+	u8 reserved_at_420[0x20];
+	u8 reserved_at_440[0x8];
+	u8 last_acked_psn[0x18];
+	u8 reserved_at_460[0x8];
+	u8 ssn[0x18];
+	u8 reserved_at_480[0x8];
+	u8 log_rra_max[0x3];
+	u8 reserved_at_48b[0x1];
+	u8 atomic_mode[0x4];
+	u8 rre[0x1];
+	u8 rwe[0x1];
+	u8 rae[0x1];
+	u8 reserved_at_493[0x1];
+	u8 page_offset[0x6];
+	u8 reserved_at_49a[0x3];
+	u8 cd_slave_receive[0x1];
+	u8 cd_slave_send[0x1];
+	u8 cd_master[0x1];
+	u8 reserved_at_4a0[0x3];
+	u8 min_rnr_nak[0x5];
+	u8 next_rcv_psn[0x18];
+	u8 reserved_at_4c0[0x8];
+	u8 xrcd[0x18];
+	u8 reserved_at_4e0[0x8];
+	u8 cqn_rcv[0x18];
+	u8 dbr_addr[0x40];
+	u8 q_key[0x20];
+	u8 reserved_at_560[0x5];
+	u8 rq_type[0x3];
+	u8 srqn_rmpn_xrqn[0x18];
+	u8 reserved_at_580[0x8];
+	u8 rmsn[0x18];
+	u8 hw_sq_wqebb_counter[0x10];
+	u8 sw_sq_wqebb_counter[0x10];
+	u8 hw_rq_counter[0x20];
+	u8 sw_rq_counter[0x20];
+	u8 reserved_at_600[0x20];
+	u8 reserved_at_620[0xf];
+	u8 cgs[0x1];
+	u8 cs_req[0x8];
+	u8 cs_res[0x8];
+	u8 dc_access_key[0x40];
+	u8 reserved_at_680[0x3];
+	u8 dbr_umem_valid[0x1];
+	u8 reserved_at_684[0x9c];
+	u8 dbr_umem_id[0x20];
+};
+
+struct mlx5_ifc_create_qp_out_bits {
+	u8 status[0x8];
+	u8 reserved_at_8[0x18];
+	u8 syndrome[0x20];
+	u8 reserved_at_40[0x8];
+	u8 qpn[0x18];
+	u8 reserved_at_60[0x20];
+};
+
+#ifdef PEDANTIC
+#pragma GCC diagnostic ignored "-Wpedantic"
+#endif
+struct mlx5_ifc_create_qp_in_bits {
+	u8 opcode[0x10];
+	u8 uid[0x10];
+	u8 reserved_at_20[0x10];
+	u8 op_mod[0x10];
+	u8 reserved_at_40[0x40];
+	u8 opt_param_mask[0x20];
+	u8 reserved_at_a0[0x20];
+	struct mlx5_ifc_qpc_bits qpc;
+	u8 wq_umem_offset[0x40];
+	u8 wq_umem_id[0x20];
+	u8 wq_umem_valid[0x1];
+	u8 reserved_at_861[0x1f];
+	u8 pas[0][0x40];
+};
+#ifdef PEDANTIC
+#pragma GCC diagnostic error "-Wpedantic"
+#endif
+
+struct mlx5_ifc_sqerr2rts_qp_out_bits {
+	u8 status[0x8];
+	u8 reserved_at_8[0x18];
+	u8 syndrome[0x20];
+	u8 reserved_at_40[0x40];
+};
+
+struct mlx5_ifc_sqerr2rts_qp_in_bits {
+	u8 opcode[0x10];
+	u8 uid[0x10];
+	u8 reserved_at_20[0x10];
+	u8 op_mod[0x10];
+	u8 reserved_at_40[0x8];
+	u8 qpn[0x18];
+	u8 reserved_at_60[0x20];
+	u8 opt_param_mask[0x20];
+	u8 reserved_at_a0[0x20];
+	struct mlx5_ifc_qpc_bits qpc;
+	u8 reserved_at_800[0x80];
+};
+
+struct mlx5_ifc_sqd2rts_qp_out_bits {
+	u8 status[0x8];
+	u8 reserved_at_8[0x18];
+	u8 syndrome[0x20];
+	u8 reserved_at_40[0x40];
+};
+
+struct mlx5_ifc_sqd2rts_qp_in_bits {
+	u8 opcode[0x10];
+	u8 uid[0x10];
+	u8 reserved_at_20[0x10];
+	u8 op_mod[0x10];
+	u8 reserved_at_40[0x8];
+	u8 qpn[0x18];
+	u8 reserved_at_60[0x20];
+	u8 opt_param_mask[0x20];
+	u8 reserved_at_a0[0x20];
+	struct mlx5_ifc_qpc_bits qpc;
+	u8 reserved_at_800[0x80];
+};
+
+struct mlx5_ifc_rts2rts_qp_out_bits {
+	u8 status[0x8];
+	u8 reserved_at_8[0x18];
+	u8 syndrome[0x20];
+	u8 reserved_at_40[0x40];
+};
+
+struct mlx5_ifc_rts2rts_qp_in_bits {
+	u8 opcode[0x10];
+	u8 uid[0x10];
+	u8 reserved_at_20[0x10];
+	u8 op_mod[0x10];
+	u8 reserved_at_40[0x8];
+	u8 qpn[0x18];
+	u8 reserved_at_60[0x20];
+	u8 opt_param_mask[0x20];
+	u8 reserved_at_a0[0x20];
+	struct mlx5_ifc_qpc_bits qpc;
+	u8 reserved_at_800[0x80];
+};
+
+struct mlx5_ifc_rtr2rts_qp_out_bits {
+	u8 status[0x8];
+	u8 reserved_at_8[0x18];
+	u8 syndrome[0x20];
+	u8 reserved_at_40[0x40];
+};
+
+struct mlx5_ifc_rtr2rts_qp_in_bits {
+	u8 opcode[0x10];
+	u8 uid[0x10];
+	u8 reserved_at_20[0x10];
+	u8 op_mod[0x10];
+	u8 reserved_at_40[0x8];
+	u8 qpn[0x18];
+	u8 reserved_at_60[0x20];
+	u8 opt_param_mask[0x20];
+	u8 reserved_at_a0[0x20];
+	struct mlx5_ifc_qpc_bits qpc;
+	u8 reserved_at_800[0x80];
+};
+
+struct mlx5_ifc_rst2init_qp_out_bits {
+	u8 status[0x8];
+	u8 reserved_at_8[0x18];
+	u8 syndrome[0x20];
+	u8 reserved_at_40[0x40];
+};
+
+struct mlx5_ifc_rst2init_qp_in_bits {
+	u8 opcode[0x10];
+	u8 uid[0x10];
+	u8 reserved_at_20[0x10];
+	u8 op_mod[0x10];
+	u8 reserved_at_40[0x8];
+	u8 qpn[0x18];
+	u8 reserved_at_60[0x20];
+	u8 opt_param_mask[0x20];
+	u8 reserved_at_a0[0x20];
+	struct mlx5_ifc_qpc_bits qpc;
+	u8 reserved_at_800[0x80];
+};
+
+struct mlx5_ifc_init2rtr_qp_out_bits {
+	u8 status[0x8];
+	u8 reserved_at_8[0x18];
+	u8 syndrome[0x20];
+	u8 reserved_at_40[0x40];
+};
+
+struct mlx5_ifc_init2rtr_qp_in_bits {
+	u8 opcode[0x10];
+	u8 uid[0x10];
+	u8 reserved_at_20[0x10];
+	u8 op_mod[0x10];
+	u8 reserved_at_40[0x8];
+	u8 qpn[0x18];
+	u8 reserved_at_60[0x20];
+	u8 opt_param_mask[0x20];
+	u8 reserved_at_a0[0x20];
+	struct mlx5_ifc_qpc_bits qpc;
+	u8 reserved_at_800[0x80];
+};
+
+struct mlx5_ifc_init2init_qp_out_bits {
+	u8 status[0x8];
+	u8 reserved_at_8[0x18];
+	u8 syndrome[0x20];
+	u8 reserved_at_40[0x40];
+};
+
+struct mlx5_ifc_init2init_qp_in_bits {
+	u8 opcode[0x10];
+	u8 uid[0x10];
+	u8 reserved_at_20[0x10];
+	u8 op_mod[0x10];
+	u8 reserved_at_40[0x8];
+	u8 qpn[0x18];
+	u8 reserved_at_60[0x20];
+	u8 opt_param_mask[0x20];
+	u8 reserved_at_a0[0x20];
+	struct mlx5_ifc_qpc_bits qpc;
+	u8 reserved_at_800[0x80];
+};
+
+#ifdef PEDANTIC
+#pragma GCC diagnostic ignored "-Wpedantic"
+#endif
+struct mlx5_ifc_query_qp_out_bits {
+	u8 status[0x8];
+	u8 reserved_at_8[0x18];
+	u8 syndrome[0x20];
+	u8 reserved_at_40[0x40];
+	u8 opt_param_mask[0x20];
+	u8 reserved_at_a0[0x20];
+	struct mlx5_ifc_qpc_bits qpc;
+	u8 reserved_at_800[0x80];
+	u8 pas[0][0x40];
+};
+#ifdef PEDANTIC
+#pragma GCC diagnostic error "-Wpedantic"
+#endif
+
+struct mlx5_ifc_query_qp_in_bits {
+	u8 opcode[0x10];
+	u8 reserved_at_10[0x10];
+	u8 reserved_at_20[0x10];
+	u8 op_mod[0x10];
+	u8 reserved_at_40[0x8];
+	u8 qpn[0x18];
+	u8 reserved_at_60[0x20];
+};
+
 /* CQE format mask. */
 #define MLX5E_CQE_FORMAT_MASK 0xc
 
diff --git a/drivers/common/mlx5/rte_common_mlx5_version.map b/drivers/common/mlx5/rte_common_mlx5_version.map
index f3082ce..df8e064 100644
--- a/drivers/common/mlx5/rte_common_mlx5_version.map
+++ b/drivers/common/mlx5/rte_common_mlx5_version.map
@@ -2,6 +2,7 @@  DPDK_20.02 {
 	global:
 
 	mlx5_devx_cmd_create_cq;
+	mlx5_devx_cmd_create_qp;
 	mlx5_devx_cmd_create_rq;
 	mlx5_devx_cmd_create_rqt;
 	mlx5_devx_cmd_create_sq;
@@ -14,6 +15,7 @@  DPDK_20.02 {
 	mlx5_devx_cmd_flow_counter_query;
 	mlx5_devx_cmd_flow_dump;
 	mlx5_devx_cmd_mkey_create;
+	mlx5_devx_cmd_modify_qp_state;
 	mlx5_devx_cmd_modify_rq;
 	mlx5_devx_cmd_modify_sq;
 	mlx5_devx_cmd_modify_virtq;