diff --git a/drivers/common/cpt/cpt_common.h b/drivers/common/cpt/cpt_common.h
index 32f23ac..7ef6b29 100644
--- a/drivers/common/cpt/cpt_common.h
+++ b/drivers/common/cpt/cpt_common.h
@@ -19,9 +19,6 @@
 #define CPT_COUNT_THOLD		32
 #define CPT_TIMER_THOLD		0x3F
 
-#define AE_TYPE 1
-#define SE_TYPE 2
-
 #ifndef ROUNDUP4
 #define ROUNDUP4(val)	(((val) + 3) & 0xfffffffc)
 #endif
diff --git a/drivers/crypto/octeontx/otx_cryptodev_hw_access.c b/drivers/crypto/octeontx/otx_cryptodev_hw_access.c
index eba6293..ad64bf4 100644
--- a/drivers/crypto/octeontx/otx_cryptodev_hw_access.c
+++ b/drivers/crypto/octeontx/otx_cryptodev_hw_access.c
@@ -386,6 +386,12 @@ otx_cpt_hw_init(struct cpt_vf *cptvf, void *pdev, void *reg_base, char *name)
 		return -1;
 	}
 
+	/* Gets device type */
+	if (otx_cpt_get_dev_type(cptvf)) {
+		CPT_LOG_ERR("Failed to get device type");
+		return -1;
+	}
+
 	return 0;
 }
 
@@ -653,12 +659,6 @@ otx_cpt_start_device(void *dev)
 		return -EFAULT;
 	}
 
-	if ((cptvf->vftype != SE_TYPE) && (cptvf->vftype != AE_TYPE)) {
-		CPT_LOG_ERR("Fatal error, unexpected vf type %u, for CPT VF "
-			    "device %s", cptvf->vftype, cptvf->dev_name);
-		return -ENOENT;
-	}
-
 	return 0;
 }
 
diff --git a/drivers/crypto/octeontx/otx_cryptodev_mbox.c b/drivers/crypto/octeontx/otx_cryptodev_mbox.c
index daba776..a884ad6 100644
--- a/drivers/crypto/octeontx/otx_cryptodev_mbox.c
+++ b/drivers/crypto/octeontx/otx_cryptodev_mbox.c
@@ -42,11 +42,19 @@ otx_cpt_handle_mbox_intr(struct cpt_vf *cptvf)
 	case OTX_CPT_MSG_QBIND_GRP:
 		cptvf->pf_acked = true;
 		cptvf->vftype = mbx.data;
-		CPT_LOG_DP_DEBUG("%s: VF %d type %s group %d",
+		CPT_LOG_DP_DEBUG("%s: VF %d group %d",
 				 cptvf->dev_name, cptvf->vfid,
-				 ((mbx.data == SE_TYPE) ? "SE" : "AE"),
 				 cptvf->vfgrp);
 		break;
+	case OTX_CPT_MSG_PF_TYPE:
+		cptvf->pf_acked = true;
+		if (mbx.data == OTX_CPT_PF_TYPE_AE)
+			cptvf->vftype = OTX_CPT_VF_TYPE_AE;
+		else if (mbx.data == OTX_CPT_PF_TYPE_SE)
+			cptvf->vftype = OTX_CPT_VF_TYPE_SE;
+		else
+			cptvf->vftype = OTX_CPT_VF_TYPE_INVALID;
+		break;
 	case OTX_CPT_MBOX_MSG_TYPE_ACK:
 		cptvf->pf_acked = true;
 		break;
@@ -120,6 +128,20 @@ otx_cpt_check_pf_ready(struct cpt_vf *cptvf)
 }
 
 int
+otx_cpt_get_dev_type(struct cpt_vf *cptvf)
+{
+	struct cpt_mbox mbx = {0, 0};
+
+	mbx.msg = OTX_CPT_MSG_PF_TYPE;
+	if (otx_cpt_send_msg_to_pf_timeout(cptvf, &mbx)) {
+		CPT_LOG_ERR("%s: PF didn't respond to query msg",
+			    cptvf->dev_name);
+		return 1;
+	}
+	return 0;
+}
+
+int
 otx_cpt_send_vq_size_msg(struct cpt_vf *cptvf)
 {
 	struct cpt_mbox mbx = {0, 0};
diff --git a/drivers/crypto/octeontx/otx_cryptodev_mbox.h b/drivers/crypto/octeontx/otx_cryptodev_mbox.h
index 2d2e0e6..508f3af 100644
--- a/drivers/crypto/octeontx/otx_cryptodev_mbox.h
+++ b/drivers/crypto/octeontx/otx_cryptodev_mbox.h
@@ -23,6 +23,20 @@ struct cpt_mbox {
 	uint64_t data;
 };
 
+/* CPT PF types */
+enum otx_cpt_pf_type {
+	OTX_CPT_PF_TYPE_INVALID = 0,
+	OTX_CPT_PF_TYPE_AE = 2,
+	OTX_CPT_PF_TYPE_SE,
+};
+
+/* CPT VF types */
+enum otx_cpt_vf_type {
+	OTX_CPT_VF_TYPE_AE = 1,
+	OTX_CPT_VF_TYPE_SE,
+	OTX_CPT_VF_TYPE_INVALID,
+};
+
 /* PF-VF message opcodes */
 enum otx_cpt_mbox_opcode {
 	OTX_CPT_MSG_VF_UP = 1,
@@ -63,6 +77,12 @@ int
 otx_cpt_check_pf_ready(struct cpt_vf *cptvf);
 
 /*
+ * Communicate to PF to get VF type
+ */
+int
+otx_cpt_get_dev_type(struct cpt_vf *cptvf);
+
+/*
  * Communicate VQs size to PF to program CPT(0)_PF_Q(0-15)_CTL of the VF.
  * Must be ACKed.
  */
diff --git a/drivers/crypto/octeontx/otx_cryptodev_ops.c b/drivers/crypto/octeontx/otx_cryptodev_ops.c
index 9628ffa..88efed3 100644
--- a/drivers/crypto/octeontx/otx_cryptodev_ops.c
+++ b/drivers/crypto/octeontx/otx_cryptodev_ops.c
@@ -16,6 +16,7 @@
 #include "otx_cryptodev.h"
 #include "otx_cryptodev_capabilities.h"
 #include "otx_cryptodev_hw_access.h"
+#include "otx_cryptodev_mbox.h"
 #include "otx_cryptodev_ops.h"
 
 /* Forward declarations */
@@ -630,6 +631,28 @@ otx_cpt_dev_create(struct rte_cryptodev *c_dev)
 		goto fail;
 	}
 
+	switch (cptvf->vftype) {
+	case OTX_CPT_VF_TYPE_AE:
+		/* Set asymmetric cpt feature flags */
+		c_dev->feature_flags = RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO |
+				RTE_CRYPTODEV_FF_HW_ACCELERATED;
+		break;
+	case OTX_CPT_VF_TYPE_SE:
+		/* Set symmetric cpt feature flags */
+		c_dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
+				RTE_CRYPTODEV_FF_HW_ACCELERATED |
+				RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
+				RTE_CRYPTODEV_FF_IN_PLACE_SGL |
+				RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT |
+				RTE_CRYPTODEV_FF_OOP_SGL_IN_SGL_OUT;
+		break;
+	default:
+		/* Feature not supported. Abort */
+		CPT_LOG_ERR("VF type not supported by %s", dev_name);
+		ret = -EIO;
+		goto deinit_dev;
+	}
+
 	/* Start off timer for mailbox interrupts */
 	otx_cpt_periodic_alarm_start(cptvf);
 
@@ -638,18 +661,14 @@ otx_cpt_dev_create(struct rte_cryptodev *c_dev)
 	c_dev->enqueue_burst = otx_cpt_pkt_enqueue;
 	c_dev->dequeue_burst = otx_cpt_pkt_dequeue;
 
-	c_dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
-			RTE_CRYPTODEV_FF_HW_ACCELERATED |
-			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
-			RTE_CRYPTODEV_FF_IN_PLACE_SGL |
-			RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT |
-			RTE_CRYPTODEV_FF_OOP_SGL_IN_SGL_OUT;
-
 	/* Save dev private data */
 	c_dev->data->dev_private = cptvf;
 
 	return 0;
 
+deinit_dev:
+	otx_cpt_deinit_device(cptvf);
+
 fail:
 	if (cptvf) {
 		/* Free private data allocated */
diff --git a/drivers/crypto/octeontx/otx_cryptodev_ops.h b/drivers/crypto/octeontx/otx_cryptodev_ops.h
index 768ec4f..fac8a3c 100644
--- a/drivers/crypto/octeontx/otx_cryptodev_ops.h
+++ b/drivers/crypto/octeontx/otx_cryptodev_ops.h
@@ -5,6 +5,8 @@
 #ifndef _OTX_CRYPTODEV_OPS_H_
 #define _OTX_CRYPTODEV_OPS_H_
 
+#include <rte_cryptodev.h>
+
 #define OTX_CPT_MIN_HEADROOM_REQ	(24)
 #define OTX_CPT_MIN_TAILROOM_REQ	(8)
 #define CPT_NUM_QS_PER_VF		(1)
