diff --git a/drivers/common/cnxk/meson.build b/drivers/common/cnxk/meson.build
index 178bce7..739e0e4 100644
--- a/drivers/common/cnxk/meson.build
+++ b/drivers/common/cnxk/meson.build
@@ -11,6 +11,7 @@ endif
 config_flag_fmt = 'RTE_LIBRTE_@0@_COMMON'
 deps = ['eal', 'pci', 'bus_pci', 'mbuf']
 sources = files(
+        'roc_cpt.c',
         'roc_dev.c',
         'roc_idev.c',
         'roc_irq.c',
diff --git a/drivers/common/cnxk/roc_api.h b/drivers/common/cnxk/roc_api.h
index 049854d..88a5611 100644
--- a/drivers/common/cnxk/roc_api.h
+++ b/drivers/common/cnxk/roc_api.h
@@ -106,4 +106,7 @@
 /* Idev */
 #include "roc_idev.h"
 
+/* CPT */
+#include "roc_cpt.h"
+
 #endif /* _ROC_API_H_ */
diff --git a/drivers/common/cnxk/roc_cpt.c b/drivers/common/cnxk/roc_cpt.c
new file mode 100644
index 0000000..3c0683c
--- /dev/null
+++ b/drivers/common/cnxk/roc_cpt.c
@@ -0,0 +1,273 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2021 Marvell.
+ */
+
+#include "roc_api.h"
+#include "roc_priv.h"
+
+static int
+cpt_get_msix_offset(struct dev *dev, struct msix_offset_rsp **msix_rsp)
+{
+	struct mbox *mbox = dev->mbox;
+	int rc;
+
+	/* Get MSIX vector offsets */
+	mbox_alloc_msg_msix_offset(mbox);
+	rc = mbox_process_msg(mbox, (void *)msix_rsp);
+
+	return rc;
+}
+
+static int
+cpt_lfs_attach(struct dev *dev, int nb_lf)
+{
+	struct mbox *mbox;
+	struct rsrc_attach_req *req;
+
+	mbox = dev->mbox;
+	/* Attach CPT(lf) */
+	req = mbox_alloc_msg_attach_resources(mbox);
+	if (req == NULL)
+		return -ENOSPC;
+
+	req->cptlfs = nb_lf;
+
+	return mbox_process(mbox);
+}
+
+static int
+cpt_lfs_detach(struct dev *dev)
+{
+	struct mbox *mbox = dev->mbox;
+	struct rsrc_detach_req *req;
+
+	req = mbox_alloc_msg_detach_resources(mbox);
+	if (req == NULL)
+		return -ENOSPC;
+
+	req->cptlfs = 1;
+	req->partial = 1;
+
+	return mbox_process(mbox);
+}
+
+static int
+cpt_available_lfs_get(struct dev *dev, uint16_t *nb_lf)
+{
+	struct mbox *mbox = dev->mbox;
+	struct free_rsrcs_rsp *rsp;
+	int rc;
+
+	mbox_alloc_msg_free_rsrc_cnt(mbox);
+
+	rc = mbox_process_msg(mbox, (void *)&rsp);
+	if (rc)
+		return -EIO;
+
+	*nb_lf = rsp->cpt;
+	return 0;
+}
+
+static int
+cpt_lfs_alloc(struct dev *dev, uint8_t eng_grpmsk)
+{
+	struct cpt_lf_alloc_req_msg *req;
+	struct mbox *mbox = dev->mbox;
+
+	req = mbox_alloc_msg_cpt_lf_alloc(mbox);
+	req->nix_pf_func = 0;
+	req->sso_pf_func = idev_sso_pffunc_get();
+	req->eng_grpmsk = eng_grpmsk;
+
+	return mbox_process(mbox);
+}
+
+static int
+cpt_lfs_free(struct dev *dev)
+{
+	mbox_alloc_msg_cpt_lf_free(dev->mbox);
+
+	return mbox_process(dev->mbox);
+}
+
+static int
+cpt_hardware_caps_get(struct dev *dev, union cpt_eng_caps *hw_caps)
+{
+	struct cpt_caps_rsp_msg *rsp;
+	int ret;
+
+	mbox_alloc_msg_cpt_caps_get(dev->mbox);
+
+	ret = mbox_process_msg(dev->mbox, (void *)&rsp);
+	if (ret)
+		return -EIO;
+
+	mbox_memcpy(hw_caps, rsp->eng_caps,
+		    sizeof(union cpt_eng_caps) * CPT_MAX_ENG_TYPES);
+
+	return 0;
+}
+
+int
+roc_cpt_dev_configure(struct roc_cpt *roc_cpt, int nb_lf)
+{
+	struct cpt *cpt = roc_cpt_to_cpt_priv(roc_cpt);
+	struct msix_offset_rsp *rsp;
+	uint8_t eng_grpmsk;
+	int rc, i;
+
+	/* Request LF resources */
+	rc = cpt_lfs_attach(&cpt->dev, nb_lf);
+	if (rc)
+		return rc;
+
+	eng_grpmsk = (1 << roc_cpt->eng_grp[CPT_ENG_TYPE_AE]) |
+		     (1 << roc_cpt->eng_grp[CPT_ENG_TYPE_SE]) |
+		     (1 << roc_cpt->eng_grp[CPT_ENG_TYPE_IE]);
+
+	rc = cpt_lfs_alloc(&cpt->dev, eng_grpmsk);
+	if (rc)
+		goto lfs_detach;
+
+	rc = cpt_get_msix_offset(&cpt->dev, &rsp);
+	if (rc)
+		goto lfs_free;
+
+	for (i = 0; i < nb_lf; i++)
+		cpt->lf_msix_off[i] =
+			(cpt->lf_blkaddr[i] == RVU_BLOCK_ADDR_CPT1) ?
+				rsp->cpt1_lf_msixoff[i] :
+				rsp->cptlf_msixoff[i];
+
+	roc_cpt->nb_lf = nb_lf;
+
+	return 0;
+
+lfs_free:
+	cpt_lfs_free(&cpt->dev);
+lfs_detach:
+	cpt_lfs_detach(&cpt->dev);
+	return rc;
+}
+
+int
+roc_cpt_dev_init(struct roc_cpt *roc_cpt)
+{
+	struct plt_pci_device *pci_dev;
+	uint16_t nb_lf_avail;
+	struct dev *dev;
+	struct cpt *cpt;
+	int rc;
+
+	if (roc_cpt == NULL || roc_cpt->pci_dev == NULL)
+		return -EINVAL;
+
+	PLT_STATIC_ASSERT(sizeof(struct cpt) <= ROC_CPT_MEM_SZ);
+
+	cpt = roc_cpt_to_cpt_priv(roc_cpt);
+	memset(cpt, 0, sizeof(*cpt));
+	pci_dev = roc_cpt->pci_dev;
+	dev = &cpt->dev;
+
+	/* Initialize device  */
+	rc = dev_init(dev, pci_dev);
+	if (rc) {
+		plt_err("Failed to init roc device");
+		goto fail;
+	}
+
+	cpt->pci_dev = pci_dev;
+	roc_cpt->lmt_base = dev->lmt_base;
+
+	rc = cpt_hardware_caps_get(dev, roc_cpt->hw_caps);
+	if (rc) {
+		plt_err("Could not determine hardware capabilities");
+		goto fail;
+	}
+
+	rc = cpt_available_lfs_get(&cpt->dev, &nb_lf_avail);
+	if (rc) {
+		plt_err("Could not get available lfs");
+		goto fail;
+	}
+
+	roc_cpt->nb_lf_avail = nb_lf_avail;
+
+	dev->roc_cpt = roc_cpt;
+
+	return 0;
+
+fail:
+	return rc;
+}
+
+int
+roc_cpt_dev_fini(struct roc_cpt *roc_cpt)
+{
+	struct cpt *cpt = roc_cpt_to_cpt_priv(roc_cpt);
+
+	if (cpt == NULL)
+		return -EINVAL;
+
+	roc_cpt->nb_lf_avail = 0;
+
+	roc_cpt->lmt_base = 0;
+
+	return dev_fini(&cpt->dev, cpt->pci_dev);
+}
+
+void
+roc_cpt_dev_clear(struct roc_cpt *roc_cpt)
+{
+	struct cpt *cpt = roc_cpt_to_cpt_priv(roc_cpt);
+	int i;
+
+	if (cpt == NULL)
+		return;
+
+	for (i = 0; i < roc_cpt->nb_lf; i++)
+		cpt->lf_msix_off[i] = 0;
+
+	roc_cpt->nb_lf = 0;
+
+	cpt_lfs_free(&cpt->dev);
+
+	cpt_lfs_detach(&cpt->dev);
+}
+
+int
+roc_cpt_eng_grp_add(struct roc_cpt *roc_cpt, enum cpt_eng_type eng_type)
+{
+	struct cpt *cpt = roc_cpt_to_cpt_priv(roc_cpt);
+	struct dev *dev = &cpt->dev;
+	struct cpt_eng_grp_req *req;
+	struct cpt_eng_grp_rsp *rsp;
+	int ret;
+
+	req = mbox_alloc_msg_cpt_eng_grp_get(dev->mbox);
+	if (req == NULL)
+		return -EIO;
+
+	switch (eng_type) {
+	case CPT_ENG_TYPE_AE:
+	case CPT_ENG_TYPE_SE:
+	case CPT_ENG_TYPE_IE:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	req->eng_type = eng_type;
+	ret = mbox_process_msg(dev->mbox, (void *)&rsp);
+	if (ret)
+		return -EIO;
+
+	if (rsp->eng_grp_num > 8) {
+		plt_err("Invalid CPT engine group");
+		return -ENOTSUP;
+	}
+
+	roc_cpt->eng_grp[eng_type] = rsp->eng_grp_num;
+
+	return rsp->eng_grp_num;
+}
diff --git a/drivers/common/cnxk/roc_cpt.h b/drivers/common/cnxk/roc_cpt.h
new file mode 100644
index 0000000..2630955
--- /dev/null
+++ b/drivers/common/cnxk/roc_cpt.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2021 Marvell.
+ */
+
+#ifndef _ROC_CPT_H_
+#define _ROC_CPT_H_
+
+#include "roc_api.h"
+
+#define ROC_CPT_MAX_LFS 64
+
+struct roc_cpt {
+	struct plt_pci_device *pci_dev;
+	struct roc_cpt_lf *lf[ROC_CPT_MAX_LFS];
+	uint16_t nb_lf;
+	uint16_t nb_lf_avail;
+	uintptr_t lmt_base;
+	/**< CPT device capabilities */
+	union cpt_eng_caps hw_caps[CPT_MAX_ENG_TYPES];
+	uint8_t eng_grp[CPT_MAX_ENG_TYPES];
+
+#define ROC_CPT_MEM_SZ (6 * 1024)
+	uint8_t reserved[ROC_CPT_MEM_SZ] __plt_cache_aligned;
+} __plt_cache_aligned;
+
+int __roc_api roc_cpt_dev_init(struct roc_cpt *roc_cpt);
+int __roc_api roc_cpt_dev_fini(struct roc_cpt *roc_cpt);
+int __roc_api roc_cpt_eng_grp_add(struct roc_cpt *roc_cpt,
+				  enum cpt_eng_type eng_type);
+int __roc_api roc_cpt_dev_configure(struct roc_cpt *roc_cpt, int nb_lf);
+void __roc_api roc_cpt_dev_clear(struct roc_cpt *roc_cpt);
+#endif /* _ROC_CPT_H_ */
diff --git a/drivers/common/cnxk/roc_cpt_priv.h b/drivers/common/cnxk/roc_cpt_priv.h
new file mode 100644
index 0000000..8cb2dbd
--- /dev/null
+++ b/drivers/common/cnxk/roc_cpt_priv.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2021 Marvell.
+ */
+
+#ifndef _ROC_CPT_PRIV_H_
+#define _ROC_CPT_PRIV_H_
+
+/* Set number of number of hystbits to 6.
+ * This will trigger the FC writes whenever
+ * number of outstanding commands in the queue
+ * becomes multiple of 32.
+ */
+#define CPT_FC_NUM_HYST_BITS 6
+
+struct cpt {
+	struct plt_pci_device *pci_dev;
+	struct dev dev;
+	uint16_t lf_msix_off[ROC_CPT_MAX_LFS];
+	uint8_t lf_blkaddr[ROC_CPT_MAX_LFS];
+} __plt_cache_aligned;
+
+static inline struct cpt *
+roc_cpt_to_cpt_priv(struct roc_cpt *roc_cpt)
+{
+	return (struct cpt *)&roc_cpt->reserved[0];
+}
+
+#endif /* _ROC_CPT_PRIV_H_ */
diff --git a/drivers/common/cnxk/roc_dev.c b/drivers/common/cnxk/roc_dev.c
index a39acc9..052ebe0 100644
--- a/drivers/common/cnxk/roc_dev.c
+++ b/drivers/common/cnxk/roc_dev.c
@@ -870,6 +870,8 @@ dev_vf_hwcap_update(struct plt_pci_device *pci_dev, struct dev *dev)
 		break;
 	case PCI_DEVID_CNXK_RVU_SSO_TIM_VF:
 	case PCI_DEVID_CNXK_RVU_NPA_VF:
+	case PCI_DEVID_CN10K_RVU_CPT_VF:
+	case PCI_DEVID_CN9K_RVU_CPT_VF:
 	case PCI_DEVID_CNXK_RVU_AF_VF:
 	case PCI_DEVID_CNXK_RVU_VF:
 	case PCI_DEVID_CNXK_RVU_SDP_VF:
diff --git a/drivers/common/cnxk/roc_dev_priv.h b/drivers/common/cnxk/roc_dev_priv.h
index 910cfb6..f8277fb 100644
--- a/drivers/common/cnxk/roc_dev_priv.h
+++ b/drivers/common/cnxk/roc_dev_priv.h
@@ -83,6 +83,7 @@ struct dev {
 	uint16_t maxvf;
 	struct dev_ops *ops;
 	void *roc_nix;
+	void *roc_cpt;
 	bool disable_shared_lmt; /* false(default): shared lmt mode enabled */
 } __plt_cache_aligned;
 
diff --git a/drivers/common/cnxk/roc_platform.c b/drivers/common/cnxk/roc_platform.c
index 3999fce..74dbdec 100644
--- a/drivers/common/cnxk/roc_platform.c
+++ b/drivers/common/cnxk/roc_platform.c
@@ -58,6 +58,7 @@ roc_plt_init(void)
 
 RTE_LOG_REGISTER(cnxk_logtype_base, pmd.cnxk.base, NOTICE);
 RTE_LOG_REGISTER(cnxk_logtype_mbox, pmd.cnxk.mbox, NOTICE);
+RTE_LOG_REGISTER(cnxk_logtype_cpt, pmd.crypto.cnxk, NOTICE);
 RTE_LOG_REGISTER(cnxk_logtype_npa, pmd.mempool.cnxk, NOTICE);
 RTE_LOG_REGISTER(cnxk_logtype_nix, pmd.net.cnxk, NOTICE);
 RTE_LOG_REGISTER(cnxk_logtype_npc, pmd.net.cnxk.flow, NOTICE);
diff --git a/drivers/common/cnxk/roc_platform.h b/drivers/common/cnxk/roc_platform.h
index 7864fa4..524585f 100644
--- a/drivers/common/cnxk/roc_platform.h
+++ b/drivers/common/cnxk/roc_platform.h
@@ -139,6 +139,7 @@
 /* Log */
 extern int cnxk_logtype_base;
 extern int cnxk_logtype_mbox;
+extern int cnxk_logtype_cpt;
 extern int cnxk_logtype_npa;
 extern int cnxk_logtype_nix;
 extern int cnxk_logtype_npc;
@@ -161,6 +162,7 @@ extern int cnxk_logtype_tm;
 		##args)
 
 #define plt_base_dbg(fmt, ...)	plt_dbg(base, fmt, ##__VA_ARGS__)
+#define plt_cpt_dbg(fmt, ...)	plt_dbg(cpt, fmt, ##__VA_ARGS__)
 #define plt_mbox_dbg(fmt, ...)	plt_dbg(mbox, fmt, ##__VA_ARGS__)
 #define plt_npa_dbg(fmt, ...)	plt_dbg(npa, fmt, ##__VA_ARGS__)
 #define plt_nix_dbg(fmt, ...)	plt_dbg(nix, fmt, ##__VA_ARGS__)
diff --git a/drivers/common/cnxk/roc_priv.h b/drivers/common/cnxk/roc_priv.h
index 5e7564c..54c28fc 100644
--- a/drivers/common/cnxk/roc_priv.h
+++ b/drivers/common/cnxk/roc_priv.h
@@ -32,4 +32,7 @@
 /* TIM */
 #include "roc_tim_priv.h"
 
+/* CPT */
+#include "roc_cpt_priv.h"
+
 #endif /* _ROC_PRIV_H_ */
diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map
index 8e67c83..f8e286e 100644
--- a/drivers/common/cnxk/version.map
+++ b/drivers/common/cnxk/version.map
@@ -2,6 +2,7 @@ INTERNAL {
 	global:
 
 	cnxk_logtype_base;
+	cnxk_logtype_cpt;
 	cnxk_logtype_mbox;
 	cnxk_logtype_nix;
 	cnxk_logtype_npa;
@@ -10,6 +11,11 @@ INTERNAL {
 	cnxk_logtype_tim;
 	cnxk_logtype_tm;
 	roc_clk_freq_get;
+	roc_cpt_dev_clear;
+	roc_cpt_dev_configure;
+	roc_cpt_dev_fini;
+	roc_cpt_dev_init;
+	roc_cpt_eng_grp_add;
 	roc_error_msg_get;
 	roc_idev_lmt_base_addr_get;
 	roc_idev_npa_maxpools_get;
