diff --git a/drivers/crypto/cpt/Makefile b/drivers/crypto/cpt/Makefile
index 40ec9e2..bf22c2b 100644
--- a/drivers/crypto/cpt/Makefile
+++ b/drivers/crypto/cpt/Makefile
@@ -25,6 +25,7 @@ CFLAGS += -O3
 
 # PMD code
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_CPT) += cpt_pmd_cryptodev.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_CPT) += cpt_pmd_ops.c
 
 # Base code
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_CPT) += cpt_device.c
diff --git a/drivers/crypto/cpt/cpt_pmd_cryptodev.c b/drivers/crypto/cpt/cpt_pmd_cryptodev.c
index addddd8..3939b5e 100644
--- a/drivers/crypto/cpt/cpt_pmd_cryptodev.c
+++ b/drivers/crypto/cpt/cpt_pmd_cryptodev.c
@@ -13,6 +13,7 @@
 
 #include "base/cpt_device.h"
 #include "cpt_pmd_logs.h"
+#include "cpt_pmd_ops.h"
 
 #define CSP_INTR_POLL_INTERVAL_MS 50
 
@@ -38,7 +39,7 @@
 				 cpt_pmd_alarm_cb, arg);
 }
 
-static int
+int
 cpt_pmd_periodic_alarm_stop(void *arg)
 {
 	return rte_eal_alarm_cancel(cpt_pmd_alarm_cb, arg);
@@ -46,11 +47,11 @@
 
 static struct rte_cryptodev_ops cptvf_ops = {
 	/* Device related operations */
-	.dev_configure = NULL,
-	.dev_start = NULL,
-	.dev_stop = NULL,
-	.dev_close = NULL,
-	.dev_infos_get = NULL,
+	.dev_configure = cpt_pmd_dev_config,
+	.dev_start = cpt_pmd_dev_start,
+	.dev_stop = cpt_pmd_dev_stop,
+	.dev_close = cpt_pmd_dev_close,
+	.dev_infos_get = cptvf_dev_info_get,
 
 	.stats_get = NULL,
 	.stats_reset = NULL,
diff --git a/drivers/crypto/cpt/cpt_pmd_ops.c b/drivers/crypto/cpt/cpt_pmd_ops.c
new file mode 100644
index 0000000..2f066cb
--- /dev/null
+++ b/drivers/crypto/cpt/cpt_pmd_ops.c
@@ -0,0 +1,544 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017 Cavium, Inc
+ */
+
+#include <rte_cryptodev_pmd.h>
+#include <rte_crypto.h>
+#include <rte_bus_pci.h>
+
+#include "cpt_pmd_logs.h"
+#include "cpt_pmd_ops.h"
+#include "base/cpt.h"
+#include "base/cpt_device.h"
+
+struct cpt_sess_misc {
+	uint16_t cpt_op:4;
+	uint16_t zsk_flag:4;
+	uint16_t aes_gcm:1;
+	uint16_t aes_ctr:1;
+	uint16_t dir_dma_supp:1; /* Single frag DMA supported? */
+	uint16_t is_gmac:1;
+	uint16_t aad_length;
+	uint8_t mac_len;
+	uint8_t iv_length; /**< IV length in bytes */
+	uint8_t auth_iv_length; /**< Auth IV length in bytes */
+	uint8_t rsvd1;
+	uint16_t iv_offset; /**< IV offset in bytes */
+	uint16_t auth_iv_offset; /**< Auth IV offset in bytes */
+	uint32_t salt;
+	phys_addr_t ctx_dma_addr;
+};
+
+/* Helper macros */
+
+#define SRC_IOV_SIZE \
+	(sizeof(iov_ptr_t) + (sizeof(buf_ptr_t) * MAX_SG_CNT))
+#define DST_IOV_SIZE \
+	(sizeof(iov_ptr_t) + (sizeof(buf_ptr_t) * MAX_SG_CNT))
+
+#define SESS_PRIV(__sess) \
+	(void *)((uint8_t *)__sess + sizeof(struct cpt_sess_misc))
+
+#define BYTE_LEN 8
+
+/* #define CPT_ALWAYS_USE_SG_MODE */
+#define CPT_ALWAYS_USE_SEPARATE_BUF
+
+/* TODO: Add all other capabilities */
+static const struct rte_cryptodev_capabilities cpt_capabilities[] = {
+	{	/* SHA1 HMAC */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
+				.block_size = 64,
+				.key_size = {
+					.min = 64,
+					.max = 64,
+					.increment = 0
+				},
+				.digest_size = {
+					.min = 1,
+					.max = 20,
+					.increment = 1
+				},
+				.aad_size = { 0 }
+			}, }
+		}, }
+	},
+	{	/* SHA224 HMAC */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_SHA224_HMAC,
+				.block_size = 64,
+					.key_size = {
+					.min = 64,
+					.max = 64,
+					.increment = 0
+				},
+				.digest_size = {
+					.min = 1,
+					.max = 28,
+					.increment = 1
+				},
+				.aad_size = { 0 }
+			}, }
+		}, }
+	},
+	{	/* SHA256 HMAC */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_SHA256_HMAC,
+				.block_size = 64,
+				.key_size = {
+					.min = 64,
+					.max = 64,
+					.increment = 0
+				},
+				.digest_size = {
+					.min = 1,
+					.max = 32,
+					.increment = 1
+				},
+				.aad_size = { 0 }
+			}, }
+		}, }
+	},
+	{	/* SHA384 HMAC */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_SHA384_HMAC,
+				.block_size = 64,
+				.key_size = {
+					.min = 64,
+					.max = 64,
+					.increment = 0
+				},
+				.digest_size = {
+					.min = 1,
+					.max = 48,
+					.increment = 1
+					},
+				.aad_size = { 0 }
+			}, }
+		}, }
+	},
+	{	/* SHA512 HMAC */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_SHA512_HMAC,
+				.block_size = 128,
+				.key_size = {
+					.min = 64,
+					.max = 64,
+					.increment = 0
+				},
+				.digest_size = {
+					.min = 1,
+					.max = 64,
+					.increment = 1
+				},
+				.aad_size = { 0 }
+			}, }
+		}, }
+	},
+	{	/* MD5 HMAC */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_MD5_HMAC,
+				.block_size = 64,
+				.key_size = {
+					.min = 8,
+					.max = 64,
+					.increment = 8
+				},
+				.digest_size = {
+					.min = 1,
+					.max = 16,
+					.increment = 1
+				},
+				.aad_size = { 0 }
+			}, }
+		}, }
+	},
+	{	/* AES GCM */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AEAD,
+			{.aead = {
+				.algo = RTE_CRYPTO_AEAD_AES_GCM,
+				.block_size = 16,
+				.key_size = {
+					.min = 16,
+					.max = 32,
+					.increment = 8
+				},
+				.digest_size = {
+					.min = 8,
+					.max = 16,
+					.increment = 4
+				},
+				.aad_size = {
+					.min = 0,
+					.max = 1024,
+					.increment = 1
+				},
+				.iv_size = {
+					.min = 12,
+					.max = 12,
+					.increment = 0
+				}
+			}, }
+		}, }
+	},
+	{	/* AES GMAC (AUTH) */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_AES_GMAC,
+				.block_size = 16,
+				.key_size = {
+					.min = 16,
+					.max = 32,
+					.increment = 8
+				},
+				.digest_size = {
+					.min = 8,
+					.max = 16,
+					.increment = 4
+				},
+				.aad_size = {
+					.min = 1,
+					.max = 65535,
+					.increment = 1
+				}
+			}, }
+		}, }
+	},
+	{	/* SNOW 3G (UIA2) */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_SNOW3G_UIA2,
+				.block_size = 16,
+				.key_size = {
+					.min = 16,
+					.max = 16,
+					.increment = 0
+				},
+				.digest_size = {
+					.min = 4,
+					.max = 4,
+					.increment = 0
+				},
+				.aad_size = {
+					.min = 16,
+					.max = 16,
+					.increment = 0
+				}
+			}, }
+		}, }
+	},
+	{	/* AES CBC */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
+			{.cipher = {
+				.algo = RTE_CRYPTO_CIPHER_AES_CBC,
+				.block_size = 16,
+				.key_size = {
+					.min = 16,
+					.max = 32,
+					.increment = 8
+				},
+				.iv_size = {
+					.min = 16,
+					.max = 16,
+					.increment = 0
+				}
+			}, }
+		}, }
+	},
+	{	/* SNOW 3G (UEA2) */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
+			{.cipher = {
+				.algo = RTE_CRYPTO_CIPHER_SNOW3G_UEA2,
+				.block_size = 16,
+				.key_size = {
+					.min = 16,
+					.max = 16,
+					.increment = 0
+				},
+				.iv_size = {
+					.min = 16,
+					.max = 16,
+					.increment = 0
+				}
+			}, }
+		}, }
+	},
+	{	/* AES CTR */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
+			{.cipher = {
+				.algo = RTE_CRYPTO_CIPHER_AES_CTR,
+				.block_size = 16,
+				.key_size = {
+					.min = 16,
+					.max = 32,
+					.increment = 8
+				},
+				.iv_size = {
+					.min = 16,
+					.max = 16,
+					.increment = 0
+				}
+			}, }
+		}, }
+	},
+	{	/* NULL (AUTH) */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_NULL,
+				.block_size = 1,
+				.key_size = {
+					.min = 0,
+					.max = 0,
+					.increment = 0
+				},
+				.digest_size = {
+					.min = 0,
+					.max = 0,
+					.increment = 0
+				},
+				.aad_size = { 0 }
+			}, },
+		}, },
+	},
+	{	/* NULL (CIPHER) */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
+			{.cipher = {
+				.algo = RTE_CRYPTO_CIPHER_NULL,
+				.block_size = 1,
+				.key_size = {
+					.min = 0,
+					.max = 0,
+					.increment = 0
+				},
+				.iv_size = {
+					.min = 0,
+					.max = 0,
+					.increment = 0
+				}
+			}, },
+		}, }
+	},
+	{       /* KASUMI (F8) */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
+			{.cipher = {
+				.algo = RTE_CRYPTO_CIPHER_KASUMI_F8,
+				.block_size = 8,
+				.key_size = {
+					.min = 16,
+					.max = 16,
+					.increment = 0
+				},
+				.iv_size = {
+					.min = 8,
+					.max = 8,
+					.increment = 0
+				}
+			}, }
+		}, }
+	},
+	{	/* ZUC (EIA3) */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_ZUC_EIA3,
+				.block_size = 16,
+				.key_size = {
+					.min = 16,
+					.max = 16,
+					.increment = 0
+				},
+				.digest_size = {
+					.min = 4,
+					.max = 4,
+					.increment = 0
+				},
+				.aad_size = {
+					.min = 16,
+					.max = 16,
+					.increment = 0
+				}
+			}, }
+		}, }
+	},
+	{	/* ZUC (EEA3) */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
+			{.cipher = {
+				.algo = RTE_CRYPTO_CIPHER_ZUC_EEA3,
+				.block_size = 16,
+				.key_size = {
+					.min = 16,
+					.max = 16,
+					.increment = 0
+				},
+				.iv_size = {
+					.min = 16,
+					.max = 16,
+					.increment = 0
+				}
+			}, }
+		}, }
+	},
+	{       /* KASUMI (F9) */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_KASUMI_F9,
+				.block_size = 8,
+				.key_size = {
+					.min = 16,
+					.max = 16,
+					.increment = 0
+				},
+				.digest_size = {
+					.min = 4,
+					.max = 4,
+					.increment = 0
+				},
+				.aad_size = {
+					.min = 8,
+					.max = 8,
+					.increment = 0
+				}
+			}, }
+		}, }
+	},
+	{	/* 3DES CBC */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
+			{.cipher = {
+				.algo = RTE_CRYPTO_CIPHER_3DES_CBC,
+				.block_size = 8,
+				.key_size = {
+					.min = 24,
+					.max = 24,
+					.increment = 0
+				},
+				.iv_size = {
+					.min = 8,
+					.max = 16,
+					.increment = 8
+				}
+			}, }
+		}, }
+	},
+	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
+};
+
+int cpt_pmd_dev_config(struct rte_cryptodev *dev __rte_unused,
+		   struct rte_cryptodev_config *config __rte_unused)
+{
+	PMD_INIT_FUNC_TRACE();
+	return 0;
+}
+
+int cpt_pmd_dev_start(struct rte_cryptodev *c_dev __rte_unused)
+{
+	struct cpt_vf *cptvf = c_dev->data->dev_private;
+
+	PMD_INIT_FUNC_TRACE();
+
+	return cptvf_start_device(cptvf);
+}
+
+void cpt_pmd_dev_stop(struct rte_cryptodev *c_dev __rte_unused)
+{
+	struct cpt_vf *cptvf = c_dev->data->dev_private;
+
+	PMD_INIT_FUNC_TRACE();
+
+	cptvf_stop_device(cptvf);
+}
+
+int cpt_pmd_dev_close(struct rte_cryptodev *c_dev)
+{
+	struct cpt_vf *cptvf = c_dev->data->dev_private;
+	int i, ret;
+
+	PMD_INIT_FUNC_TRACE();
+
+	for (i = 0; i < c_dev->data->nb_queue_pairs; i++) {
+		ret = cpt_pmd_que_pair_release(c_dev, i);
+		if (ret)
+			return ret;
+	}
+	cpt_pmd_periodic_alarm_stop(cptvf);
+	cptvf_deinit_device(cptvf);
+
+	return 0;
+}
+
+void
+cptvf_dev_info_get(struct rte_cryptodev *dev, struct rte_cryptodev_info *info)
+{
+	PMD_INIT_FUNC_TRACE();
+	if (info != NULL) {
+		info->max_nb_queue_pairs = CPT_NUM_QS_PER_VF;
+		info->feature_flags = dev->feature_flags;
+		info->capabilities = cpt_capabilities;
+		/* TODO: Hardcoding as of now */
+		info->sym.max_nb_sessions = 128;
+		info->driver_id = cryptodev_cpt_driver_id;
+	}
+}
+
+int
+cpt_pmd_que_pair_release(struct rte_cryptodev *dev, uint16_t que_pair_id)
+{
+	cpt_instance_t *instance = dev->data->queue_pairs[que_pair_id];
+	int ret;
+
+	PMD_INIT_FUNC_TRACE();
+
+	ret = cptvf_put_resource(instance);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "Error putting instance handle"
+			    " of device %s : ret = %d\n", dev->data->name, ret);
+		return ret;
+	}
+
+	dev->data->queue_pairs[que_pair_id] = NULL;
+
+	return 0;
+}
diff --git a/drivers/crypto/cpt/cpt_pmd_ops.h b/drivers/crypto/cpt/cpt_pmd_ops.h
new file mode 100644
index 0000000..015b4a2
--- /dev/null
+++ b/drivers/crypto/cpt/cpt_pmd_ops.h
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017 Cavium, Inc
+ */
+
+#ifndef __CPT_PMD_OPS_H_
+#define __CPT_PMD_OPS_H_
+
+#include "base/cpt.h"
+
+#define CAVIUM_VENDOR_ID       0x177d
+#define NITROXIII_DEV_ID       0x11
+
+#define CSP_OP_CIPHER_ENCRYPT	0x1
+#define CSP_OP_CIPHER_DECRYPT	0x2
+#define CSP_OP_CIPHER_MASK	0x3
+
+#define CSP_OP_AUTH_VERIFY	0x4
+#define CSP_OP_AUTH_GENERATE	0x8
+#define CSP_OP_AUTH_MASK	0xC
+
+#define CSP_OP_ENCODE	(CSP_OP_CIPHER_ENCRYPT | CSP_OP_AUTH_GENERATE)
+#define CSP_OP_DECODE	(CSP_OP_CIPHER_DECRYPT | CSP_OP_AUTH_VERIFY)
+
+#define MAX_CIPHER_KEY_LEN  32
+#define MAX_AUTH_KEY_LEN    32
+#define DEFAULT_BLOCK_SIZE      64
+
+#define CSP_DDMA_AUTH		(1 << 1)
+#define CSP_DDMA_ENC		(1 << 2)
+#define CSP_DDMA_SUPPORTED	(CSP_DDMA_AUTH | CSP_DDMA_ENC)
+
+/*
+ * Space needed in packet for direct-dma operation.
+ * UCODE result & padding - 16 bytes max
+ * Result -  16 bytes
+ * struct cb_info size
+ */
+#define CSP_DDMA_EXTRA_SPACE (32 + sizeof(struct cpt_cb_info))
+
+#define ZS_EA 0x1
+#define ZS_IA 0x2
+#define K_F8 0x4
+#define K_F9 0x8
+
+extern uint8_t cryptodev_cpt_driver_id;
+extern int cpt_pmd_periodic_alarm_stop(void *arg);
+extern struct rte_mempool *cpt_meta_pool;
+extern int cpt_op_mlen;
+extern int cpt_op_sb_mlen;
+
+int cpt_pmd_dev_config(struct rte_cryptodev *dev __rte_unused,
+		   struct rte_cryptodev_config *config __rte_unused);
+int cpt_pmd_dev_start(struct rte_cryptodev *dev);
+
+void cpt_pmd_dev_stop(struct rte_cryptodev *dev);
+
+int cpt_pmd_dev_close(struct rte_cryptodev *dev);
+
+void cptvf_dev_info_get(struct rte_cryptodev *dev,
+			  struct rte_cryptodev_info *inf);
+
+int cpt_pmd_que_pair_release(struct rte_cryptodev *dev, uint16_t que_pair_id);
+
+#endif
