diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c
index 56407cc332..347ae75d37 100644
--- a/drivers/common/mlx5/mlx5_devx_cmds.c
+++ b/drivers/common/mlx5/mlx5_devx_cmds.c
@@ -858,9 +858,12 @@ mlx5_devx_cmd_query_hca_attr(void *ctx,
 	attr->log_max_srq_sz = MLX5_GET(cmd_hca_cap, hcattr, log_max_srq_sz);
 	attr->reg_c_preserve =
 		MLX5_GET(cmd_hca_cap, hcattr, reg_c_preserve);
-	attr->mmo_dma_en = MLX5_GET(cmd_hca_cap, hcattr, dma_mmo);
-	attr->mmo_compress_en = MLX5_GET(cmd_hca_cap, hcattr, compress);
-	attr->mmo_decompress_en = MLX5_GET(cmd_hca_cap, hcattr, decompress);
+	attr->mmo_dma_sq_en = MLX5_GET(cmd_hca_cap, hcattr, dma_mmo_sq);
+	attr->mmo_compress_sq_en = MLX5_GET(cmd_hca_cap, hcattr, compress_mmo_sq);
+	attr->mmo_decompress_sq_en = MLX5_GET(cmd_hca_cap, hcattr, decompress_mmo_sq);
+	attr->mmo_dma_qp_en = MLX5_GET(cmd_hca_cap, hcattr, dma_mmo_qp);
+	attr->mmo_compress_qp_en = MLX5_GET(cmd_hca_cap, hcattr, compress_mmo_qp);
+	attr->mmo_decompress_qp_en = MLX5_GET(cmd_hca_cap, hcattr, decompress_mmo_qp);
 	attr->compress_min_block_size = MLX5_GET(cmd_hca_cap, hcattr,
 						 compress_min_block_size);
 	attr->log_max_mmo_dma = MLX5_GET(cmd_hca_cap, hcattr, log_dma_mmo_size);
@@ -2022,6 +2025,11 @@ mlx5_devx_cmd_create_qp(void *ctx,
 	MLX5_SET(qpc, qpc, pd, attr->pd);
 	MLX5_SET(qpc, qpc, ts_format, attr->ts_format);
 	if (attr->uar_index) {
+		if(attr->mmo) {
+			void *qpc_ext_and_pas_list = MLX5_ADDR_OF(create_qp_in, in, qpc_extension_and_pas_list);
+			void* qpc_ext = MLX5_ADDR_OF(qpc_extension_and_pas_list, qpc_ext_and_pas_list, qpc_data_extension);
+			MLX5_SET(qpc_extension, qpc_ext, mmo, 1);
+		}
 		MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);
 		MLX5_SET(qpc, qpc, uar_page, attr->uar_index);
 		if (attr->log_page_size > MLX5_ADAPTER_PAGE_SHIFT)
diff --git a/drivers/common/mlx5/mlx5_devx_cmds.h b/drivers/common/mlx5/mlx5_devx_cmds.h
index e576e30f24..f993b511dc 100644
--- a/drivers/common/mlx5/mlx5_devx_cmds.h
+++ b/drivers/common/mlx5/mlx5_devx_cmds.h
@@ -173,9 +173,12 @@ struct mlx5_hca_attr {
 	uint32_t log_max_srq;
 	uint32_t log_max_srq_sz;
 	uint32_t rss_ind_tbl_cap;
-	uint32_t mmo_dma_en:1;
-	uint32_t mmo_compress_en:1;
-	uint32_t mmo_decompress_en:1;
+	uint32_t mmo_dma_sq_en:1;
+	uint32_t mmo_compress_sq_en:1;
+	uint32_t mmo_decompress_sq_en:1;
+	uint32_t mmo_dma_qp_en:1;
+	uint32_t mmo_compress_qp_en:1;
+	uint32_t mmo_decompress_qp_en:1;
 	uint32_t compress_min_block_size:4;
 	uint32_t log_max_mmo_dma:5;
 	uint32_t log_max_mmo_compress:5;
@@ -397,6 +400,7 @@ struct mlx5_devx_qp_attr {
 	uint64_t dbr_address;
 	uint32_t wq_umem_id;
 	uint64_t wq_umem_offset;
+	uint32_t mmo;
 };
 
 struct mlx5_devx_virtio_q_couners_attr {
diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index fdb20f5d49..d0c75b97df 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -1385,10 +1385,10 @@ struct mlx5_ifc_cmd_hca_cap_bits {
 	u8 rtr2rts_qp_counters_set_id[0x1];
 	u8 rts2rts_udp_sport[0x1];
 	u8 rts2rts_lag_tx_port_affinity[0x1];
-	u8 dma_mmo[0x1];
+	u8 dma_mmo_sq[0x1];
 	u8 compress_min_block_size[0x4];
-	u8 compress[0x1];
-	u8 decompress[0x1];
+	u8 compress_mmo_sq[0x1];
+	u8 decompress_mmo_sq[0x1];
 	u8 log_max_ra_res_qp[0x6];
 	u8 end_pad[0x1];
 	u8 cc_query_allowed[0x1];
@@ -1631,7 +1631,12 @@ struct mlx5_ifc_cmd_hca_cap_bits {
 	u8 num_vhca_ports[0x8];
 	u8 reserved_at_618[0x6];
 	u8 sw_owner_id[0x1];
-	u8 reserved_at_61f[0x1e1];
+	u8 reserved_at_61f[0x109];
+	u8 dma_mmo_qp[0x1];
+	u8 reserved_at_621[0x1];
+	u8 compress_mmo_qp[0x1];
+	u8 decompress_mmo_qp[0x1];
+	u8 reserved_at_624[0xd4];
 };
 
 struct mlx5_ifc_qos_cap_bits {
@@ -3235,6 +3240,27 @@ struct mlx5_ifc_create_qp_out_bits {
 	u8 reserved_at_60[0x20];
 };
 
+struct mlx5_ifc_qpc_extension_bits {
+	u8 reserved_at_0[0x2];
+	u8 mmo[0x1];
+	u8 reserved_at_3[0x5fd];
+};
+
+#ifdef PEDANTIC
+#pragma GCC diagnostic ignored "-Wpedantic"
+#endif
+struct mlx5_ifc_qpc_pas_list_bits {
+	u8 pas[0][0x40];
+};
+
+#ifdef PEDANTIC
+#pragma GCC diagnostic ignored "-Wpedantic"
+#endif
+struct mlx5_ifc_qpc_extension_and_pas_list_bits {
+	struct mlx5_ifc_qpc_extension_bits qpc_data_extension;
+	u8 pas[0][0x40];
+};
+
 #ifdef PEDANTIC
 #pragma GCC diagnostic ignored "-Wpedantic"
 #endif
@@ -3243,7 +3269,8 @@ struct mlx5_ifc_create_qp_in_bits {
 	u8 uid[0x10];
 	u8 reserved_at_20[0x10];
 	u8 op_mod[0x10];
-	u8 reserved_at_40[0x40];
+	u8 qpc_ext[0x1];
+	u8 reserved_at_41[0x3f];
 	u8 opt_param_mask[0x20];
 	u8 reserved_at_a0[0x20];
 	struct mlx5_ifc_qpc_bits qpc;
@@ -3251,7 +3278,10 @@ struct mlx5_ifc_create_qp_in_bits {
 	u8 wq_umem_id[0x20];
 	u8 wq_umem_valid[0x1];
 	u8 reserved_at_861[0x1f];
-	u8 pas[0][0x40];
+	union {
+		struct mlx5_ifc_qpc_pas_list_bits qpc_pas_list;
+		struct mlx5_ifc_qpc_extension_and_pas_list_bits qpc_extension_and_pas_list;
+	};
 };
 #ifdef PEDANTIC
 #pragma GCC diagnostic error "-Wpedantic"
diff --git a/drivers/compress/mlx5/mlx5_compress.c b/drivers/compress/mlx5/mlx5_compress.c
index 883e720ec1..05e75adb1c 100644
--- a/drivers/compress/mlx5/mlx5_compress.c
+++ b/drivers/compress/mlx5/mlx5_compress.c
@@ -48,6 +48,7 @@ struct mlx5_compress_priv {
 	rte_spinlock_t xform_sl;
 	struct mlx5_mr_share_cache mr_scache; /* Global shared MR cache. */
 	volatile uint64_t *uar_addr;
+	uint8_t mmo_caps; /* bitmap 0->5: decomp_sq, decomp_qp, comp_sq, comp_qp, dma_sq, dma_qp */
 #ifndef RTE_ARCH_64
 	rte_spinlock_t uar32_sl;
 #endif /* RTE_ARCH_64 */
@@ -61,7 +62,7 @@ struct mlx5_compress_qp {
 	struct mlx5_mr_ctrl mr_ctrl;
 	int socket_id;
 	struct mlx5_devx_cq cq;
-	struct mlx5_devx_sq sq;
+	struct mlx5_devx_qp qp;
 	struct mlx5_pmd_mr opaque_mr;
 	struct rte_comp_op **ops;
 	struct mlx5_compress_priv *priv;
@@ -134,8 +135,8 @@ mlx5_compress_qp_release(struct rte_compressdev *dev, uint16_t qp_id)
 {
 	struct mlx5_compress_qp *qp = dev->data->queue_pairs[qp_id];
 
-	if (qp->sq.sq != NULL)
-		mlx5_devx_sq_destroy(&qp->sq);
+	if (qp->qp.qp != NULL)
+		mlx5_devx_qp_destroy(&qp->qp);
 	if (qp->cq.cq != NULL)
 		mlx5_devx_cq_destroy(&qp->cq);
 	if (qp->opaque_mr.obj != NULL) {
@@ -152,12 +153,12 @@ mlx5_compress_qp_release(struct rte_compressdev *dev, uint16_t qp_id)
 }
 
 static void
-mlx5_compress_init_sq(struct mlx5_compress_qp *qp)
+mlx5_compress_init_qp(struct mlx5_compress_qp *qp)
 {
 	volatile struct mlx5_gga_wqe *restrict wqe =
-				    (volatile struct mlx5_gga_wqe *)qp->sq.wqes;
+				    (volatile struct mlx5_gga_wqe *)qp->qp.wqes;
 	volatile struct mlx5_gga_compress_opaque *opaq = qp->opaque_mr.addr;
-	const uint32_t sq_ds = rte_cpu_to_be_32((qp->sq.sq->id << 8) | 4u);
+	const uint32_t sq_ds = rte_cpu_to_be_32((qp->qp.qp->id << 8) | 4u);
 	const uint32_t flags = RTE_BE32(MLX5_COMP_ALWAYS <<
 					MLX5_COMP_MODE_OFFSET);
 	const uint32_t opaq_lkey = rte_cpu_to_be_32(qp->opaque_mr.lkey);
@@ -173,6 +174,35 @@ mlx5_compress_init_sq(struct mlx5_compress_qp *qp)
 	}
 }
 
+static int
+mlx5_compress_qp2rts(struct mlx5_compress_qp *qp)
+{
+	/*
+	 * In Order to configure self loopback, when calling these functions the
+	 * remote QP id that is used is the id of the same QP.
+	 */
+	if (mlx5_devx_cmd_modify_qp_state(qp->qp.qp, MLX5_CMD_OP_RST2INIT_QP,
+					  qp->qp.qp->id)) {
+		DRV_LOG(ERR, "Failed to modify QP to INIT state(%u).",
+			rte_errno);
+		return -1;
+	}
+	if (mlx5_devx_cmd_modify_qp_state(qp->qp.qp, MLX5_CMD_OP_INIT2RTR_QP,
+					  qp->qp.qp->id)) {
+		DRV_LOG(ERR, "Failed to modify QP to RTR state(%u).",
+			rte_errno);
+		return -1;
+	}
+	if (mlx5_devx_cmd_modify_qp_state(qp->qp.qp, MLX5_CMD_OP_RTR2RTS_QP,
+					  qp->qp.qp->id)) {
+		DRV_LOG(ERR, "Failed to modify QP to RTS state(%u).",
+			rte_errno);
+		return -1;
+	}
+	return 0;
+}
+
+
 static int
 mlx5_compress_qp_setup(struct rte_compressdev *dev, uint16_t qp_id,
 		       uint32_t max_inflight_ops, int socket_id)
@@ -182,15 +212,9 @@ mlx5_compress_qp_setup(struct rte_compressdev *dev, uint16_t qp_id,
 	struct mlx5_devx_cq_attr cq_attr = {
 		.uar_page_id = mlx5_os_get_devx_uar_page_id(priv->uar),
 	};
-	struct mlx5_devx_create_sq_attr sq_attr = {
-		.user_index = qp_id,
-		.wq_attr = (struct mlx5_devx_wq_attr){
-			.pd = priv->pdn,
-			.uar_page = mlx5_os_get_devx_uar_page_id(priv->uar),
-		},
-	};
-	struct mlx5_devx_modify_sq_attr modify_attr = {
-		.state = MLX5_SQC_STATE_RDY,
+	struct mlx5_devx_qp_attr qp_attr = {
+		.pd = priv->pdn,
+		.uar_index = mlx5_os_get_devx_uar_page_id(priv->uar),
 	};
 	uint32_t log_ops_n = rte_log2_u32(max_inflight_ops);
 	uint32_t alloc_size = sizeof(*qp);
@@ -242,24 +266,26 @@ mlx5_compress_qp_setup(struct rte_compressdev *dev, uint16_t qp_id,
 		DRV_LOG(ERR, "Failed to create CQ.");
 		goto err;
 	}
-	sq_attr.cqn = qp->cq.cq->id;
-	sq_attr.ts_format = mlx5_ts_format_conv(priv->sq_ts_format);
-	ret = mlx5_devx_sq_create(priv->ctx, &qp->sq, log_ops_n, &sq_attr,
+	qp_attr.cqn = qp->cq.cq->id;
+	qp_attr.ts_format = mlx5_ts_format_conv(priv->sq_ts_format);
+	qp_attr.rq_size = 0;
+	qp_attr.sq_size = 1 << log_ops_n;
+	qp_attr.mmo = (priv->mmo_caps & (1<<1)) && (priv->mmo_caps & (1<<3)) && (priv->mmo_caps & (1<<5));
+	ret = mlx5_devx_qp_create(priv->ctx, &qp->qp, log_ops_n, &qp_attr,
 				  socket_id);
 	if (ret != 0) {
-		DRV_LOG(ERR, "Failed to create SQ.");
+		DRV_LOG(ERR, "Failed to create QP.");
 		goto err;
 	}
-	mlx5_compress_init_sq(qp);
-	ret = mlx5_devx_cmd_modify_sq(qp->sq.sq, &modify_attr);
-	if (ret != 0) {
-		DRV_LOG(ERR, "Can't change SQ state to ready.");
+	ret = mlx5_compress_qp2rts(qp);
+	if(ret) {
 		goto err;
 	}
+	mlx5_compress_init_qp(qp);
 	/* Save pointer of global generation number to check memory event. */
 	qp->mr_ctrl.dev_gen_ptr = &priv->mr_scache.dev_gen;
 	DRV_LOG(INFO, "QP %u: SQN=0x%X CQN=0x%X entries num = %u",
-		(uint32_t)qp_id, qp->sq.sq->id, qp->cq.cq->id, qp->entries_n);
+		(uint32_t)qp_id, qp->qp.qp->id, qp->cq.cq->id, qp->entries_n);
 	return 0;
 err:
 	mlx5_compress_qp_release(dev, qp_id);
@@ -508,7 +534,7 @@ mlx5_compress_enqueue_burst(void *queue_pair, struct rte_comp_op **ops,
 {
 	struct mlx5_compress_qp *qp = queue_pair;
 	volatile struct mlx5_gga_wqe *wqes = (volatile struct mlx5_gga_wqe *)
-							      qp->sq.wqes, *wqe;
+							      qp->qp.wqes, *wqe;
 	struct mlx5_compress_xform *xform;
 	struct rte_comp_op *op;
 	uint16_t mask = qp->entries_n - 1;
@@ -563,7 +589,7 @@ mlx5_compress_enqueue_burst(void *queue_pair, struct rte_comp_op **ops,
 	} while (--remain);
 	qp->stats.enqueued_count += nb_ops;
 	rte_io_wmb();
-	qp->sq.db_rec[MLX5_SND_DBR] = rte_cpu_to_be_32(qp->pi);
+	qp->qp.db_rec[MLX5_SND_DBR] = rte_cpu_to_be_32(qp->pi);
 	rte_wmb();
 	mlx5_compress_uar_write(*(volatile uint64_t *)wqe, qp->priv);
 	rte_wmb();
@@ -598,7 +624,7 @@ mlx5_compress_cqe_err_handle(struct mlx5_compress_qp *qp,
 	volatile struct mlx5_err_cqe *cqe = (volatile struct mlx5_err_cqe *)
 							      &qp->cq.cqes[idx];
 	volatile struct mlx5_gga_wqe *wqes = (volatile struct mlx5_gga_wqe *)
-								    qp->sq.wqes;
+								    qp->qp.wqes;
 	volatile struct mlx5_gga_compress_opaque *opaq = qp->opaque_mr.addr;
 
 	op->status = RTE_COMP_OP_STATUS_ERROR;
@@ -813,8 +839,9 @@ mlx5_compress_dev_probe(struct rte_device *dev)
 		return -rte_errno;
 	}
 	if (mlx5_devx_cmd_query_hca_attr(ctx, &att) != 0 ||
-	    att.mmo_compress_en == 0 || att.mmo_decompress_en == 0 ||
-	    att.mmo_dma_en == 0) {
+	    ((att.mmo_compress_sq_en == 0 || att.mmo_decompress_sq_en == 0 ||
+	    	att.mmo_dma_sq_en == 0) && (att.mmo_compress_qp_en == 0 || 
+				att.mmo_decompress_qp_en == 0 || att.mmo_dma_qp_en == 0))) {
 		DRV_LOG(ERR, "Not enough capabilities to support compress "
 			"operations, maybe old FW/OFED version?");
 		claim_zero(mlx5_glue->close_device(ctx));
@@ -835,6 +862,12 @@ mlx5_compress_dev_probe(struct rte_device *dev)
 	cdev->enqueue_burst = mlx5_compress_enqueue_burst;
 	cdev->feature_flags = RTE_COMPDEV_FF_HW_ACCELERATED;
 	priv = cdev->data->dev_private;
+	priv->mmo_caps = 0 | att.mmo_decompress_sq_en;
+	priv->mmo_caps |= att.mmo_decompress_qp_en << 1;
+	priv->mmo_caps |= att.mmo_compress_sq_en << 2;
+	priv->mmo_caps |= att.mmo_compress_qp_en << 3;
+	priv->mmo_caps |= att.mmo_dma_sq_en << 4;
+	priv->mmo_caps |= att.mmo_dma_qp_en << 5;
 	priv->ctx = ctx;
 	priv->cdev = cdev;
 	priv->min_block_size = att.compress_min_block_size;
