diff --git a/drivers/crypto/caam_jr/Makefile b/drivers/crypto/caam_jr/Makefile
index b1f3ecee7..e22943749 100644
--- a/drivers/crypto/caam_jr/Makefile
+++ b/drivers/crypto/caam_jr/Makefile
@@ -16,7 +16,10 @@ CFLAGS += -D _GNU_SOURCE
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 
+CFLAGS += -I$(RTE_SDK)/drivers/bus/dpaa/include
 CFLAGS += -I$(RTE_SDK)/drivers/crypto/caam_jr
+#sharing the hw flib headers from dpaa2_sec pmd
+CFLAGS += -I$(RTE_SDK)/drivers/crypto/dpaa2_sec/
 CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common/include
 CFLAGS += -I$(RTE_SDK)/lib/librte_eal/linuxapp/eal
 
@@ -28,10 +31,12 @@ LIBABIVER := 1
 
 # library source files
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_CAAM_JR) += caam_jr.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_CAAM_JR) += caam_jr_hw.c
 # library dependencies
 
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_cryptodev
+LDLIBS += -lrte_bus_dpaa
 LDLIBS += -lrte_bus_vdev
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/crypto/caam_jr/caam_jr_hw.c b/drivers/crypto/caam_jr/caam_jr_hw.c
new file mode 100644
index 000000000..b4d486633
--- /dev/null
+++ b/drivers/crypto/caam_jr/caam_jr_hw.c
@@ -0,0 +1,378 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017-2018 NXP
+ */
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <rte_common.h>
+#include <rte_memory.h>
+#include <rte_malloc.h>
+#include <rte_crypto.h>
+
+#include <caam_jr_config.h>
+#include <caam_jr_hw_specific.h>
+#include <caam_jr_pvt.h>
+#include <caam_jr_log.h>
+
+/* RTA header files */
+#include <hw/desc/common.h>
+#include <hw/desc/algo.h>
+#include <hw/desc/ipsec.h>
+
+/* Used to retry resetting a job ring in SEC hardware. */
+#define SEC_TIMEOUT 100000
+
+/* @brief Process Jump Halt Condition related errors
+ *
+ * @param [in]  error_code        The error code in the descriptor status word
+ */
+static inline void
+hw_handle_jmp_halt_cond_err(union hw_error_code error_code)
+{
+	CAAM_JR_DEBUG("JMP: %d, Descriptor Index: 0x%x, Condition: 0x%x",
+			error_code.error_desc.jmp_halt_cond_src.jmp,
+			error_code.error_desc.jmp_halt_cond_src.desc_idx,
+			error_code.error_desc.jmp_halt_cond_src.cond);
+	(void)error_code;
+}
+
+/* @brief Process DECO related errors
+ *
+ * @param [in]  error_code        The error code in the descriptor status word
+ */
+static inline void
+hw_handle_deco_err(union hw_error_code error_code)
+{
+	CAAM_JR_DEBUG("JMP: %d, Descriptor Index: 0x%x",
+			error_code.error_desc.deco_src.jmp,
+			error_code.error_desc.deco_src.desc_idx);
+
+	switch (error_code.error_desc.deco_src.desc_err) {
+	case SEC_HW_ERR_DECO_HFN_THRESHOLD:
+		CAAM_JR_DEBUG(" Warning: Descriptor completed normally,"
+			"but 3GPP HFN matches or exceeds the Threshold ");
+		break;
+	default:
+		CAAM_JR_DEBUG("Error 0x%04x not implemented",
+				error_code.error_desc.deco_src.desc_err);
+		break;
+	}
+}
+
+/* @brief Process  Jump Halt User Status related errors
+ *
+ * @param [in]  error_code        The error code in the descriptor status word
+ */
+static inline void
+hw_handle_jmp_halt_user_err(union hw_error_code error_code __rte_unused)
+{
+	CAAM_JR_DEBUG(" Not implemented");
+}
+
+/* @brief Process CCB related errors
+ *
+ * @param [in]  error_code        The error code in the descriptor status word
+ */
+static inline void
+hw_handle_ccb_err(union hw_error_code hw_error_code __rte_unused)
+{
+	CAAM_JR_DEBUG(" Not implemented");
+}
+
+/* @brief Process Job Ring related errors
+ *
+ * @param [in]  error_code        The error code in the descriptor status word
+ */
+static inline void
+hw_handle_jr_err(union hw_error_code hw_error_code __rte_unused)
+{
+	CAAM_JR_DEBUG(" Not implemented");
+}
+
+uint32_t
+caam_jr_enable_irqs(uint32_t uio_fd __rte_unused)
+{
+	return 0;
+}
+
+uint32_t
+caam_jr_disable_irqs(uint32_t uio_fd __rte_unused)
+{
+	return 0;
+}
+
+int
+hw_reset_job_ring(struct sec_job_ring_t *job_ring)
+{
+	int ret = 0;
+
+	ASSERT(job_ring->register_base_addr != NULL);
+
+	/* First reset the job ring in hw */
+	ret = hw_shutdown_job_ring(job_ring);
+	SEC_ASSERT(ret == 0, ret, "Failed resetting job ring in hardware");
+
+	/* In order to have the HW JR in a workable state
+	 * after a reset, I need to re-write the input
+	 * queue size, input start address, output queue
+	 * size and output start address
+	 */
+	/* Write the JR input queue size to the HW register */
+	hw_set_input_ring_size(job_ring, SEC_JOB_RING_SIZE);
+
+	/* Write the JR output queue size to the HW register */
+	hw_set_output_ring_size(job_ring, SEC_JOB_RING_SIZE);
+
+	/* Write the JR input queue start address */
+	hw_set_input_ring_start_addr(job_ring,
+			caam_jr_dma_vtop(job_ring->input_ring));
+	CAAM_JR_DEBUG(" Set input ring base address to : Virtual: 0x%" PRIx64
+		      ",Physical: 0x%" PRIx64 ", Read from HW: 0x%" PRIx64,
+		      (uint64_t)(uintptr_t)job_ring->input_ring,
+		      caam_jr_dma_vtop(job_ring->input_ring),
+		      hw_get_inp_queue_base(job_ring));
+
+	/* Write the JR output queue start address */
+	hw_set_output_ring_start_addr(job_ring,
+			caam_jr_dma_vtop(job_ring->output_ring));
+	CAAM_JR_DEBUG(" Set output ring base address to: Virtual: 0x%" PRIx64
+		      ",Physical: 0x%" PRIx64 ", Read from HW: 0x%" PRIx64,
+		      (uint64_t)(uintptr_t)job_ring->output_ring,
+		      caam_jr_dma_vtop(job_ring->output_ring),
+		      hw_get_out_queue_base(job_ring));
+	return ret;
+}
+
+int
+hw_shutdown_job_ring(struct sec_job_ring_t *job_ring)
+{
+	unsigned int timeout = SEC_TIMEOUT;
+	uint32_t tmp = 0;
+	int usleep_interval = 10;
+
+	if (job_ring->register_base_addr == NULL) {
+		CAAM_JR_ERR("Jr[%p] has reg base addr as NULL.driver not init",
+			job_ring);
+		return 0;
+	}
+
+	CAAM_JR_INFO("Resetting Job ring %p", job_ring);
+
+	/*
+	 * Mask interrupts since we are going to poll
+	 * for reset completion status
+	 * Also, at POR, interrupts are ENABLED on a JR, thus
+	 * this is the point where I can disable them without
+	 * changing the code logic too much
+	 */
+	caam_jr_disable_irqs(job_ring->irq_fd);
+
+	/* initiate flush (required prior to reset) */
+	SET_JR_REG(JRCR, job_ring, JR_REG_JRCR_VAL_RESET);
+
+	/* dummy read */
+	tmp = GET_JR_REG(JRCR, job_ring);
+
+	do {
+		tmp = GET_JR_REG(JRINT, job_ring);
+		usleep(usleep_interval);
+	} while (((tmp & JRINT_ERR_HALT_MASK) ==
+			JRINT_ERR_HALT_INPROGRESS) && --timeout);
+
+	CAAM_JR_INFO("JRINT is %x", tmp);
+	if ((tmp & JRINT_ERR_HALT_MASK) != JRINT_ERR_HALT_COMPLETE ||
+		timeout == 0) {
+		CAAM_JR_ERR("0x%x, %d", tmp, timeout);
+		/* unmask interrupts */
+		if (job_ring->jr_mode != SEC_NOTIFICATION_TYPE_POLL)
+			caam_jr_enable_irqs(job_ring->irq_fd);
+		return -1;
+	}
+
+	/* Initiate reset */
+	timeout = SEC_TIMEOUT;
+	SET_JR_REG(JRCR, job_ring, JR_REG_JRCR_VAL_RESET);
+
+	do {
+		tmp = GET_JR_REG(JRCR, job_ring);
+		usleep(usleep_interval);
+	} while ((tmp & JR_REG_JRCR_VAL_RESET) && --timeout);
+
+	CAAM_JR_DEBUG("JRCR is %x", tmp);
+	if (timeout == 0) {
+		CAAM_JR_ERR("Failed to reset hw job ring %p", job_ring);
+		/* unmask interrupts */
+		if (job_ring->jr_mode != SEC_NOTIFICATION_TYPE_POLL)
+			caam_jr_enable_irqs(job_ring->irq_fd);
+		return -1;
+	}
+	/* unmask interrupts */
+	if (job_ring->jr_mode != SEC_NOTIFICATION_TYPE_POLL)
+		caam_jr_enable_irqs(job_ring->irq_fd);
+	return 0;
+
+}
+
+void
+hw_handle_job_ring_error(struct sec_job_ring_t *job_ring __rte_unused,
+			 uint32_t error_code)
+{
+	union hw_error_code hw_err_code;
+
+	hw_err_code.error = error_code;
+	switch (hw_err_code.error_desc.value.ssrc) {
+	case SEC_HW_ERR_SSRC_NO_SRC:
+		ASSERT(hw_err_code.error_desc.no_status_src.res == 0);
+		CAAM_JR_ERR("No Status Source ");
+		break;
+	case SEC_HW_ERR_SSRC_CCB_ERR:
+		CAAM_JR_ERR("CCB Status Source");
+		hw_handle_ccb_err(hw_err_code);
+		break;
+	case SEC_HW_ERR_SSRC_JMP_HALT_U:
+		CAAM_JR_ERR("Jump Halt User Status Source");
+		hw_handle_jmp_halt_user_err(hw_err_code);
+		break;
+	case SEC_HW_ERR_SSRC_DECO:
+		CAAM_JR_ERR("DECO Status Source");
+		hw_handle_deco_err(hw_err_code);
+		break;
+	case SEC_HW_ERR_SSRC_JR:
+		CAAM_JR_ERR("Job Ring Status Source");
+		hw_handle_jr_err(hw_err_code);
+		break;
+	case SEC_HW_ERR_SSRC_JMP_HALT_COND:
+		CAAM_JR_ERR("Jump Halt Condition Codes");
+		hw_handle_jmp_halt_cond_err(hw_err_code);
+		break;
+	default:
+		ASSERT(0);
+		CAAM_JR_ERR("Unknown SSRC");
+		break;
+	}
+}
+
+void
+hw_job_ring_error_print(struct sec_job_ring_t *job_ring, int code)
+{
+	switch (code) {
+	case JRINT_ERR_WRITE_STATUS:
+		CAAM_JR_ERR("Error writing status to Output Ring ");
+		break;
+	case JRINT_ERR_BAD_INPUT_BASE:
+		CAAM_JR_ERR(
+		"Bad Input Ring Base (%p) (not on a 4-byte boundary) ",
+		(void *)job_ring);
+		break;
+	case JRINT_ERR_BAD_OUTPUT_BASE:
+		CAAM_JR_ERR(
+		"Bad Output Ring Base (%p) (not on a 4-byte boundary) ",
+		(void *)job_ring);
+		break;
+	case JRINT_ERR_WRITE_2_IRBA:
+		CAAM_JR_ERR(
+		"Invalid write to Input Ring Base Address Register ");
+		break;
+	case JRINT_ERR_WRITE_2_ORBA:
+		CAAM_JR_ERR(
+		"Invalid write to Output Ring Base Address Register ");
+		break;
+	case JRINT_ERR_RES_B4_HALT:
+		CAAM_JR_ERR(
+		"Job Ring [%p] released before Job Ring is halted",
+		(void *)job_ring);
+		break;
+	case JRINT_ERR_REM_TOO_MANY:
+		CAAM_JR_ERR("Removed too many jobs from job ring [%p]",
+			(void *)job_ring);
+		break;
+	case JRINT_ERR_ADD_TOO_MANY:
+		CAAM_JR_ERR("Added too many jobs on job ring [%p]", job_ring);
+		break;
+	default:
+		CAAM_JR_ERR(" Unknown SEC JR Error :%d",
+				code);
+		break;
+	}
+}
+
+int
+hw_job_ring_set_coalescing_param(struct sec_job_ring_t *job_ring,
+				 uint16_t irq_coalescing_timer,
+				 uint8_t irq_coalescing_count)
+{
+	uint32_t reg_val = 0;
+
+	ASSERT(job_ring != NULL);
+	if (job_ring->register_base_addr == NULL) {
+		CAAM_JR_ERR("Jr[%p] has reg base addr as NULL.driver not init",
+			job_ring);
+		return -1;
+	}
+	/* Set descriptor count coalescing */
+	reg_val |= (irq_coalescing_count << JR_REG_JRCFG_LO_ICDCT_SHIFT);
+
+	/* Set coalescing timer value */
+	reg_val |= (irq_coalescing_timer << JR_REG_JRCFG_LO_ICTT_SHIFT);
+
+	/* Update parameters in HW */
+	SET_JR_REG_LO(JRCFG, job_ring, reg_val);
+	CAAM_JR_DEBUG("Set coalescing params on jr %p timer:%d, desc count: %d",
+			job_ring, irq_coalescing_timer, irq_coalescing_timer);
+
+	return 0;
+}
+
+int
+hw_job_ring_enable_coalescing(struct sec_job_ring_t *job_ring)
+{
+	uint32_t reg_val = 0;
+
+	ASSERT(job_ring != NULL);
+	if (job_ring->register_base_addr == NULL) {
+		CAAM_JR_ERR("Jr[%p] has reg base addr as NULL.driver not init",
+			job_ring);
+		return -1;
+	}
+
+	/* Get the current value of the register */
+	reg_val = GET_JR_REG_LO(JRCFG, job_ring);
+
+	/* Enable coalescing */
+	reg_val |= JR_REG_JRCFG_LO_ICEN_EN;
+
+	/* Write in hw */
+	SET_JR_REG_LO(JRCFG, job_ring, reg_val);
+
+	CAAM_JR_DEBUG("Enabled coalescing on jr %p ",
+			job_ring);
+
+	return 0;
+}
+
+int
+hw_job_ring_disable_coalescing(struct sec_job_ring_t *job_ring)
+{
+	uint32_t reg_val = 0;
+
+	ASSERT(job_ring != NULL);
+
+	if (job_ring->register_base_addr == NULL) {
+		CAAM_JR_ERR("Jr[%p] has reg base addr as NULL.driver not init",
+			job_ring);
+		return -1;
+	}
+
+	/* Get the current value of the register */
+	reg_val = GET_JR_REG_LO(JRCFG, job_ring);
+
+	/* Disable coalescing */
+	reg_val &= ~JR_REG_JRCFG_LO_ICEN_EN;
+
+	/* Write in hw */
+	SET_JR_REG_LO(JRCFG, job_ring, reg_val);
+	CAAM_JR_DEBUG("Disabled coalescing on jr %p ", job_ring);
+
+	return 0;
+}
diff --git a/drivers/crypto/caam_jr/caam_jr_hw_specific.h b/drivers/crypto/caam_jr/caam_jr_hw_specific.h
new file mode 100644
index 000000000..5f58a585d
--- /dev/null
+++ b/drivers/crypto/caam_jr/caam_jr_hw_specific.h
@@ -0,0 +1,503 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017 NXP
+ */
+
+#ifndef CAAM_JR_HW_SPECIFIC_H
+#define CAAM_JR_HW_SPECIFIC_H
+
+#include <caam_jr_config.h>
+
+/*
+ * Offset to the registers of a job ring.
+ * Is different for each job ring.
+ */
+#define CHAN_BASE(jr)   ((size_t)(jr)->register_base_addr)
+
+#define SEC_JOB_RING_IS_FULL(pi, ci, ring_max_size, ring_threshold) \
+		((((pi) + 1 + ((ring_max_size) - (ring_threshold))) & \
+		  (ring_max_size - 1))  == ((ci)))
+
+#define SEC_CIRCULAR_COUNTER(x, max)   (((x) + 1) & (max - 1))
+
+/*
+ * Assert that cond is true. If !cond is true, display str and the vararg list
+ * in a printf-like syntax. also, if !cond is true, return altRet.
+ *
+ * \param cond          A boolean expression to be asserted true
+ * \param altRet        The value to be returned if cond doesn't hold true
+ * \param str           A quoted char string
+ *
+ * E.g.:
+ *      SEC_ASSERT(ret > 0, 0, "ERROR initializing app: code = %d\n", ret);
+ */
+#define SEC_ASSERT(cond, altRet, ...) do {\
+	if (unlikely(!(cond))) {\
+		CAAM_JR_ERR(__VA_ARGS__); \
+		return altRet; \
+	} \
+} while (0)
+
+#define SEC_DP_ASSERT(cond, altRet, ...) do {\
+	if (unlikely(!(cond))) {\
+		CAAM_JR_DP_ERR(__VA_ARGS__); \
+		return altRet; \
+	} \
+} while (0)
+
+#define ASSERT(x)
+
+/*
+ * Constants representing various job ring registers
+ */
+#if CAAM_BYTE_ORDER == __BIG_ENDIAN
+#define JR_REG_IRBA_OFFSET		0x0000
+#define JR_REG_IRBA_OFFSET_LO		0x0004
+#else
+#define JR_REG_IRBA_OFFSET		0x0004
+#define JR_REG_IRBA_OFFSET_LO		0x0000
+#endif
+
+#define JR_REG_IRSR_OFFSET		0x000C
+#define JR_REG_IRSA_OFFSET		0x0014
+#define JR_REG_IRJA_OFFSET		0x001C
+
+#if CAAM_BYTE_ORDER == __BIG_ENDIAN
+#define JR_REG_ORBA_OFFSET		0x0020
+#define JR_REG_ORBA_OFFSET_LO		0x0024
+#else
+#define JR_REG_ORBA_OFFSET		0x0024
+#define JR_REG_ORBA_OFFSET_LO		0x0020
+#endif
+
+#define JR_REG_ORSR_OFFSET		0x002C
+#define JR_REG_ORJR_OFFSET		0x0034
+#define JR_REG_ORSFR_OFFSET		0x003C
+#define JR_REG_JROSR_OFFSET		0x0044
+#define JR_REG_JRINT_OFFSET		0x004C
+
+#define JR_REG_JRCFG_OFFSET		0x0050
+#define JR_REG_JRCFG_OFFSET_LO		0x0054
+
+#define JR_REG_IRRI_OFFSET		0x005C
+#define JR_REG_ORWI_OFFSET		0x0064
+#define JR_REG_JRCR_OFFSET		0x006C
+
+/*
+ * Constants for error handling on job ring
+ */
+#define JR_REG_JRINT_ERR_TYPE_SHIFT	8
+#define JR_REG_JRINT_ERR_ORWI_SHIFT	16
+#define JR_REG_JRINIT_JRE_SHIFT		1
+
+#define JRINT_JRE			(1 << JR_REG_JRINIT_JRE_SHIFT)
+#define JRINT_ERR_WRITE_STATUS		(1 << JR_REG_JRINT_ERR_TYPE_SHIFT)
+#define JRINT_ERR_BAD_INPUT_BASE	(3 << JR_REG_JRINT_ERR_TYPE_SHIFT)
+#define JRINT_ERR_BAD_OUTPUT_BASE	(4 << JR_REG_JRINT_ERR_TYPE_SHIFT)
+#define JRINT_ERR_WRITE_2_IRBA		(5 << JR_REG_JRINT_ERR_TYPE_SHIFT)
+#define JRINT_ERR_WRITE_2_ORBA		(6 << JR_REG_JRINT_ERR_TYPE_SHIFT)
+#define JRINT_ERR_RES_B4_HALT		(7 << JR_REG_JRINT_ERR_TYPE_SHIFT)
+#define JRINT_ERR_REM_TOO_MANY		(8 << JR_REG_JRINT_ERR_TYPE_SHIFT)
+#define JRINT_ERR_ADD_TOO_MANY		(9 << JR_REG_JRINT_ERR_TYPE_SHIFT)
+#define JRINT_ERR_HALT_MASK		0x0C
+#define JRINT_ERR_HALT_INPROGRESS	0x04
+#define JRINT_ERR_HALT_COMPLETE		0x08
+
+#define JR_REG_JRCR_VAL_RESET		0x00000001
+
+#define JR_REG_JRCFG_LO_ICTT_SHIFT	0x10
+#define JR_REG_JRCFG_LO_ICDCT_SHIFT	0x08
+#define JR_REG_JRCFG_LO_ICEN_EN		0x02
+
+/*
+ * Constants for Descriptor Processing errors
+ */
+#define SEC_HW_ERR_SSRC_NO_SRC		0x00
+#define SEC_HW_ERR_SSRC_CCB_ERR		0x02
+#define SEC_HW_ERR_SSRC_JMP_HALT_U	0x03
+#define SEC_HW_ERR_SSRC_DECO		0x04
+#define SEC_HW_ERR_SSRC_JR		0x06
+#define SEC_HW_ERR_SSRC_JMP_HALT_COND   0x07
+
+#define SEC_HW_ERR_DECO_HFN_THRESHOLD   0xF1
+#define SEC_HW_ERR_CCB_ICV_CHECK_FAIL   0x0A
+
+/*
+ * Constants for descriptors
+ */
+/* Return higher 32 bits of physical address */
+#define PHYS_ADDR_HI(phys_addr) \
+	    (uint32_t)(((uint64_t)phys_addr) >> 32)
+
+/* Return lower 32 bits of physical address */
+#define PHYS_ADDR_LO(phys_addr) \
+	    (uint32_t)(((uint64_t)phys_addr) & 0xFFFFFFFF)
+
+/*
+ * Macros for extracting error codes for the job ring
+ */
+#define JR_REG_JRINT_ERR_TYPE_EXTRACT(value)      ((value) & 0x00000F00)
+#define JR_REG_JRINT_ERR_ORWI_EXTRACT(value)     \
+	(((value) & 0x3FFF0000) >> JR_REG_JRINT_ERR_ORWI_SHIFT)
+#define JR_REG_JRINT_JRE_EXTRACT(value)	   ((value) & JRINT_JRE)
+
+/*
+ * Macros for managing the job ring
+ */
+/* Read pointer to job ring input ring start address */
+#if defined(RTE_ARCH_ARM64)
+#define hw_get_inp_queue_base(jr) ((((dma_addr_t)GET_JR_REG(IRBA, \
+				      (jr))) << 32) | \
+				      (GET_JR_REG_LO(IRBA, (jr))))
+
+/* Read pointer to job ring output ring start address */
+#define hw_get_out_queue_base(jr) (((dma_addr_t)(GET_JR_REG(ORBA, \
+				     (jr))) << 32) | \
+				     (GET_JR_REG_LO(ORBA, (jr))))
+#else
+#define hw_get_inp_queue_base(jr)   ((dma_addr_t)(GET_JR_REG_LO(IRBA, (jr))))
+
+#define hw_get_out_queue_base(jr)   ((dma_addr_t)(GET_JR_REG_LO(ORBA, (jr))))
+#endif
+
+/*
+ * IRJA - Input Ring Jobs Added Register shows
+ * how many new jobs were added to the Input Ring.
+ */
+#define hw_enqueue_desc_on_job_ring(job_ring) SET_JR_REG(IRJA, (job_ring), 1)
+
+#define hw_set_input_ring_size(job_ring, size) SET_JR_REG(IRSR, job_ring, \
+							 (size))
+
+#define hw_set_output_ring_size(job_ring, size) SET_JR_REG(ORSR, job_ring, \
+							  (size))
+
+#if defined(RTE_ARCH_ARM64)
+#define hw_set_input_ring_start_addr(job_ring, start_addr)	\
+{								\
+	SET_JR_REG(IRBA, job_ring, PHYS_ADDR_HI(start_addr));	\
+	SET_JR_REG_LO(IRBA, job_ring, PHYS_ADDR_LO(start_addr));\
+}
+
+#define hw_set_output_ring_start_addr(job_ring, start_addr) \
+{								\
+	SET_JR_REG(ORBA, job_ring, PHYS_ADDR_HI(start_addr));	\
+	SET_JR_REG_LO(ORBA, job_ring, PHYS_ADDR_LO(start_addr));\
+}
+
+#else
+#define hw_set_input_ring_start_addr(job_ring, start_addr)	\
+{								\
+	SET_JR_REG(IRBA, job_ring, 0);	\
+	SET_JR_REG_LO(IRBA, job_ring, PHYS_ADDR_LO(start_addr));\
+}
+
+#define hw_set_output_ring_start_addr(job_ring, start_addr) \
+{								\
+	SET_JR_REG(ORBA, job_ring, 0);	\
+	SET_JR_REG_LO(ORBA, job_ring, PHYS_ADDR_LO(start_addr));\
+}
+#endif
+
+/* ORJR - Output Ring Jobs Removed Register shows how many jobs were
+ * removed from the Output Ring for processing by software. This is done after
+ * the software has processed the entries.
+ */
+#define hw_remove_entries(jr, no_entries) SET_JR_REG(ORJR, (jr), (no_entries))
+
+/* IRSA - Input Ring Slots Available register holds the number of entries in
+ * the Job Ring's input ring. Once a job is enqueued, the value returned is
+ * decremented by the hardware by the number of jobs enqueued.
+ */
+#define hw_get_available_slots(jr)		GET_JR_REG(IRSA, jr)
+
+/* ORSFR - Output Ring Slots Full register holds the number of jobs which were
+ * processed by the SEC and can be retrieved by the software. Once a job has
+ * been processed by software, the user will call hw_remove_one_entry in order
+ * to notify the SEC that the entry was processed.
+ */
+#define hw_get_no_finished_jobs(jr)		GET_JR_REG(ORSFR, jr)
+
+/*
+ * Macros for manipulating JR registers
+ */
+#if CORE_BYTE_ORDER == CAAM_BYTE_ORDER
+#define sec_read_32(addr)	(*(volatile unsigned int *)(addr))
+#define sec_write_32(addr, val)	(*(volatile unsigned int *)(addr) = (val))
+
+#else
+#define sec_read_32(addr)	rte_bswap32((*(volatile unsigned int *)(addr)))
+#define sec_write_32(addr, val) \
+			(*(volatile unsigned int *)(addr) = rte_bswap32(val))
+#endif
+
+#if CAAM_BYTE_ORDER == __LITTLE_ENDIAN
+#define sec_read_64(addr)	(((u64)sec_read_32((u32 *)(addr) + 1) << 32) | \
+				(sec_read_32((u32 *)(addr))))
+
+#define sec_write_64(addr, val) {				\
+	sec_write_32((u32 *)(addr) + 1, (u32)((val) >> 32));	\
+	sec_write_32((u32 *)(addr), (u32)(val));		\
+}
+#else /* CAAM_BYTE_ORDER == __BIG_ENDIAN */
+#define sec_read_64(addr)	(((u64)sec_read_32((u32 *)(addr)) << 32) | \
+				(sec_read_32((u32 *)(addr) + 1)))
+
+#define sec_write_64(addr, val) {				\
+	sec_write_32((u32 *)(addr), (u32)((val) >> 32));	\
+	sec_write_32((u32 *)(addr) + 1, (u32)(val));		\
+}
+#endif
+
+#if defined(RTE_ARCH_ARM64)
+#define sec_read_addr(a)	sec_read_64((a))
+#define sec_write_addr(a, v)	sec_write_64((a), (v))
+#else
+#define sec_read_addr(a)	sec_read_32((a))
+#define sec_write_addr(a, v)	sec_write_32((a), (v))
+#endif
+
+#define JR_REG(name, jr)	(CHAN_BASE(jr) + JR_REG_##name##_OFFSET)
+#define JR_REG_LO(name, jr)	(CHAN_BASE(jr) + JR_REG_##name##_OFFSET_LO)
+
+#define GET_JR_REG(name, jr)	(sec_read_32(JR_REG(name, (jr))))
+#define GET_JR_REG_LO(name, jr)	(sec_read_32(JR_REG_LO(name, (jr))))
+
+#define SET_JR_REG(name, jr, value) \
+				(sec_write_32(JR_REG(name, (jr)), value))
+#define SET_JR_REG_LO(name, jr, value) \
+				(sec_write_32(JR_REG_LO(name, (jr)), value))
+
+/* Lists the possible states for a job ring. */
+typedef enum sec_job_ring_state_e {
+	SEC_JOB_RING_STATE_STARTED,	/* Job ring is initialized */
+	SEC_JOB_RING_STATE_RESET,	/* Job ring reset is in progress */
+} sec_job_ring_state_t;
+
+/* code or cmd block to caam */
+struct sec_cdb {
+	struct {
+		union {
+			uint32_t word;
+			struct {
+#if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+				uint16_t rsvd63_48;
+				unsigned int rsvd47_39:9;
+				unsigned int idlen:7;
+#else
+				unsigned int idlen:7;
+				unsigned int rsvd47_39:9;
+				uint16_t rsvd63_48;
+#endif
+			} field;
+		} __rte_packed hi;
+
+		union {
+			uint32_t word;
+			struct {
+#if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+				unsigned int rsvd31_30:2;
+				unsigned int fsgt:1;
+				unsigned int lng:1;
+				unsigned int offset:2;
+				unsigned int abs:1;
+				unsigned int add_buf:1;
+				uint8_t pool_id;
+				uint16_t pool_buffer_size;
+#else
+				uint16_t pool_buffer_size;
+				uint8_t pool_id;
+				unsigned int add_buf:1;
+				unsigned int abs:1;
+				unsigned int offset:2;
+				unsigned int lng:1;
+				unsigned int fsgt:1;
+				unsigned int rsvd31_30:2;
+#endif
+			} field;
+		} __rte_packed lo;
+	} __rte_packed sh_hdr;
+
+	uint32_t sh_desc[SEC_JOB_DESCRIPTOR_SIZE];
+};
+
+struct caam_jr_qp {
+	struct sec_job_ring_t *ring;
+	uint64_t rx_pkts;
+	uint64_t rx_errs;
+	uint64_t rx_poll_err;
+	uint64_t tx_pkts;
+	uint64_t tx_errs;
+	uint64_t tx_ring_full;
+};
+
+struct sec_job_ring_t {
+	/* TODO: Add wrapper macro to make it obvious this is the consumer index
+	 * on the output ring
+	 */
+	uint32_t cidx;		/* Consumer index for job ring (jobs array).
+				 * @note: cidx and pidx are accessed from
+				 * different threads. Place the cidx and pidx
+				 * inside the structure so that they lay on
+				 * different cachelines, to avoid false sharing
+				 * between threads when the threads run on
+				 * different cores!
+				 */
+	/* TODO: Add wrapper macro to make it obvious this is the producer index
+	 * on the input ring
+	 */
+	uint32_t pidx;		/* Producer index for job ring (jobs array) */
+
+	phys_addr_t *input_ring;/* Ring of output descriptors received from SEC.
+				 * Size of array is power of 2 to allow fast
+				 * update of producer/consumer indexes with
+				 * bitwise operations.
+				 */
+
+	struct sec_outring_entry *output_ring;
+				/* Ring of output descriptors received from SEC.
+				 * Size of array is power of 2 to allow fast
+				 * update of producer/consumer indexes with
+				 * bitwise operations.
+				 */
+
+	uint32_t irq_fd;	/* The file descriptor used for polling from
+				 * user space for interrupts notifications
+				 */
+	uint32_t jr_mode;	/* Model used by SEC Driver to receive
+				 * notifications from SEC.  Can be either
+				 * of the three: #SEC_NOTIFICATION_TYPE_NAPI
+				 * #SEC_NOTIFICATION_TYPE_IRQ or
+				 * #SEC_NOTIFICATION_TYPE_POLL
+				 */
+	uint32_t napi_mode;	/* Job ring mode if NAPI mode is chosen
+				 * Used only when jr_mode is set to
+				 * #SEC_NOTIFICATION_TYPE_NAPI
+				 */
+	void *register_base_addr;	/* Base address for SEC's
+					 * register memory for this job ring.
+					 */
+	uint8_t coalescing_en;		/* notifies if coelescing is
+					 * enabled for the job ring
+					 */
+	sec_job_ring_state_t jr_state;	/* The state of this job ring */
+
+	struct rte_mempool *ctx_pool;   /* per dev mempool for caam_jr_op_ctx */
+	unsigned int max_nb_queue_pairs;
+	unsigned int max_nb_sessions;
+	struct caam_jr_qp qps[RTE_CAAM_MAX_NB_SEC_QPS]; /* i/o queue for sec */
+};
+
+/* Union describing the possible error codes that
+ * can be set in the descriptor status word
+ */
+union hw_error_code {
+	uint32_t error;
+	union {
+		struct {
+			uint32_t ssrc:4;
+			uint32_t ssed_val:28;
+		} __rte_packed value;
+		struct {
+			uint32_t ssrc:4;
+			uint32_t res:28;
+		} __rte_packed no_status_src;
+		struct {
+			uint32_t ssrc:4;
+			uint32_t jmp:1;
+			uint32_t res:11;
+			uint32_t desc_idx:8;
+			uint32_t cha_id:4;
+			uint32_t err_id:4;
+		} __rte_packed ccb_status_src;
+		struct {
+			uint32_t ssrc:4;
+			uint32_t jmp:1;
+			uint32_t res:11;
+			uint32_t desc_idx:8;
+			uint32_t offset:8;
+		} __rte_packed jmp_halt_user_src;
+		struct {
+			uint32_t ssrc:4;
+			uint32_t jmp:1;
+			uint32_t res:11;
+			uint32_t desc_idx:8;
+			uint32_t desc_err:8;
+		} __rte_packed deco_src;
+		struct {
+			uint32_t ssrc:4;
+			uint32_t res:17;
+			uint32_t naddr:3;
+			uint32_t desc_err:8;
+		} __rte_packed jr_src;
+		struct {
+			uint32_t ssrc:4;
+			uint32_t jmp:1;
+			uint32_t res:11;
+			uint32_t desc_idx:8;
+			uint32_t cond:8;
+		} __rte_packed jmp_halt_cond_src;
+	} __rte_packed error_desc;
+} __rte_packed;
+
+/* @brief Initialize a job ring/channel in SEC device.
+ * Write configuration register/s to properly initialize a job ring.
+ *
+ * @param [in] job_ring     The job ring
+ *
+ * @retval 0 for success
+ * @retval other for error
+ */
+int hw_reset_job_ring(struct sec_job_ring_t *job_ring);
+
+/* @brief Reset a job ring/channel in SEC device.
+ * Write configuration register/s to reset a job ring.
+ *
+ * @param [in] job_ring     The job ring
+ *
+ * @retval 0 for success
+ * @retval -1 in case job ring reset failed
+ */
+int hw_shutdown_job_ring(struct sec_job_ring_t *job_ring);
+
+/* @brief Handle a job ring/channel error in SEC device.
+ * Identify the error type and clear error bits if required.
+ *
+ * @param [in]  job_ring	The job ring
+ * @param [in]  sec_error_code  The job ring's error code
+ */
+void hw_handle_job_ring_error(struct sec_job_ring_t *job_ring,
+			      uint32_t sec_error_code);
+
+/* @brief Handle a job ring error in the device.
+ * Identify the error type and printout a explanatory
+ * messages.
+ *
+ * @param [in]  job_ring	The job ring
+ *
+ */
+void hw_job_ring_error_print(struct sec_job_ring_t *job_ring, int code);
+
+/* @brief Set interrupt coalescing parameters on the Job Ring.
+ * @param [in]  job_ring		The job ring
+ * @param [in]  irq_coalesing_timer     Interrupt coalescing timer threshold.
+ *					This value determines the maximum
+ *					amount of time after processing a
+ *					descriptor before raising an interrupt.
+ * @param [in]  irq_coalescing_count    Interrupt coalescing descriptor count
+ *					threshold.
+ */
+int hw_job_ring_set_coalescing_param(struct sec_job_ring_t *job_ring,
+				     uint16_t irq_coalescing_timer,
+				     uint8_t irq_coalescing_count);
+
+/* @brief Enable interrupt coalescing on a job ring
+ * @param [in]  job_ring		The job ring
+ */
+int hw_job_ring_enable_coalescing(struct sec_job_ring_t *job_ring);
+
+/* @brief Disable interrupt coalescing on a job ring
+ * @param [in]  job_ring		The job ring
+ */
+int hw_job_ring_disable_coalescing(struct sec_job_ring_t *job_ring);
+
+#endif /* CAAM_JR_HW_SPECIFIC_H */
diff --git a/drivers/crypto/caam_jr/caam_jr_pvt.h b/drivers/crypto/caam_jr/caam_jr_pvt.h
new file mode 100644
index 000000000..333a192d9
--- /dev/null
+++ b/drivers/crypto/caam_jr/caam_jr_pvt.h
@@ -0,0 +1,285 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017-2018 NXP
+ */
+
+#ifndef CAAM_JR_PVT_H
+#define CAAM_JR_PVT_H
+
+/* NXP CAAM JR PMD device name */
+
+#define CAAM_JR_ALG_UNSUPPORT	(-1)
+
+/* Minimum job descriptor consists of a oneword job descriptor HEADER and
+ * a pointer to the shared descriptor.
+ */
+#define MIN_JOB_DESC_SIZE	(CAAM_CMD_SZ + CAAM_PTR_SZ)
+#define CAAM_JOB_DESC_SIZE	13
+
+/* CTX_POOL_NUM_BUFS is set as per the ipsec-secgw application */
+#define CTX_POOL_NUM_BUFS	32000
+#define CTX_POOL_CACHE_SIZE	512
+
+#define DIR_ENC                 1
+#define DIR_DEC                 0
+
+#define JR_MAX_NB_MAX_DIGEST	32
+
+#define RTE_CAAM_JR_PMD_MAX_NB_SESSIONS 2048
+
+
+/* Return codes for SEC user space driver APIs */
+enum sec_return_code_e {
+	SEC_SUCCESS = 0,	       /* Operation executed successfully.*/
+	SEC_INVALID_INPUT_PARAM,       /* API received an invalid input
+					* parameter
+					*/
+	SEC_OUT_OF_MEMORY,	       /* Memory allocation failed. */
+	SEC_DESCRIPTOR_IN_FLIGHT,      /* API function indicates there are
+					* descriptors in flight
+					* for SEC to process.
+					*/
+	SEC_LAST_DESCRIPTOR_IN_FLIGHT, /* API function indicates there is one
+					* last descriptor in flight
+					* for SEC to process that.
+					*/
+	SEC_PROCESSING_ERROR,	       /* Indicates a SEC processing error
+					* occurred on a Job Ring which requires
+					* a SEC user space driver shutdown. Can
+					* be returned from sec_poll_job_ring().
+					* Then the only other API that can be
+					* called after this error is
+					* sec_release().
+					*/
+	SEC_DESC_PROCESSING_ERROR,     /* Indicates a SEC descriptor processing
+					* error occurred on a Job Ring. Can be
+					* returned from sec_poll_job_ring().
+					* The driver was able to reset job ring
+					* and job ring can be used like in a
+					* normal case.
+					*/
+	SEC_JR_IS_FULL,			/* Job Ring is full. There is no more
+					 * room in the JR for new descriptors.
+					 * This can happen if the descriptor RX
+					 * rate is higher than SEC's capacity.
+					 */
+	SEC_DRIVER_RELEASE_IN_PROGRESS, /* SEC driver shutdown is in progress,
+					 * descriptors processing or polling is
+					 * allowed.
+					 */
+	SEC_DRIVER_ALREADY_INITIALIZED, /* SEC driver is already initialized.*/
+	SEC_DRIVER_NOT_INITIALIZED,	/* SEC driver is NOT initialized. */
+	SEC_JOB_RING_RESET_IN_PROGRESS, /* Job ring is resetting due to a
+					 * per-descriptor SEC processing error
+					 * ::SEC_desc_PROCESSING_ERROR. Reset is
+					 * finished when sec_poll_job_ring()
+					 * return. Then the job ring can be used
+					 * again.
+					 */
+	SEC_RESET_ENGINE_FAILED,	/* Resetting of SEC Engine by SEC Kernel
+					 * Driver Failed
+					 */
+	SEC_ENABLE_IRQS_FAILED,		/* Enabling of IRQs in SEC Kernel Driver
+					 * Failed
+					 */
+	SEC_DISABLE_IRQS_FAILED,	/* Disabling of IRQs in SEC Kernel
+					 * Driver Failed
+					 */
+	/* END OF VALID VALUES */
+
+	SEC_RETURN_CODE_MAX_VALUE,	/* Invalid value for return code. It is
+					 * used to mark the end of the return
+					 * code values. @note ALL new return
+					 * code values MUST be added before
+					 * ::SEC_RETURN_CODE_MAX_VALUE!
+					 */
+};
+
+enum caam_jr_op_type {
+	CAAM_JR_NONE,  /* No Cipher operations*/
+	CAAM_JR_CIPHER,/* CIPHER operations */
+	CAAM_JR_AUTH,  /* Authentication Operations */
+	CAAM_JR_AEAD,  /* Authenticated Encryption with associated data */
+	CAAM_JR_IPSEC, /* IPSEC protocol operations*/
+	CAAM_JR_PDCP,  /* PDCP protocol operations*/
+	CAAM_JR_PKC,   /* Public Key Cryptographic Operations */
+	CAAM_JR_MAX
+};
+
+struct caam_jr_session {
+	uint8_t dir;         /* Operation Direction */
+	enum rte_crypto_cipher_algorithm cipher_alg; /* Cipher Algorithm*/
+	enum rte_crypto_auth_algorithm auth_alg; /* Authentication Algorithm*/
+	enum rte_crypto_aead_algorithm aead_alg; /* AEAD Algorithm*/
+	union {
+		struct {
+			uint8_t *data;	/* pointer to key data */
+			size_t length;	/* key length in bytes */
+		} aead_key;
+		struct {
+			struct {
+				uint8_t *data;	/* pointer to key data */
+				size_t length;	/* key length in bytes */
+			} cipher_key;
+			struct {
+				uint8_t *data;	/* pointer to key data */
+				size_t length;	/* key length in bytes */
+			} auth_key;
+		};
+	};
+	struct {
+		uint16_t length;
+		uint16_t offset;
+	} iv;	/* Initialisation vector parameters */
+	uint16_t auth_only_len; /* Length of data for Auth only */
+	uint32_t digest_length;
+	struct caam_jr_qp *qp;
+	struct sec_cdb *cdb;	/* cmd block associated with qp */
+	struct rte_mempool *ctx_pool; /* session mempool for caam_jr_op_ctx */
+};
+
+/*
+ * 16-byte hardware scatter/gather table
+ */
+
+#define SEC4_SG_LEN_EXT		0x80000000	/* Entry points to table */
+#define SEC4_SG_LEN_FIN		0x40000000	/* Last ent in table */
+#define SEC4_SG_BPID_MASK	0x000000ff
+#define SEC4_SG_BPID_SHIFT	16
+#define SEC4_SG_LEN_MASK	0x3fffffff	/* Excludes EXT and FINAL */
+#define SEC4_SG_OFFSET_MASK	0x00001fff
+
+struct sec4_sg_entry {
+	uint64_t ptr;
+	uint32_t len;
+	uint32_t bpid_offset;
+};
+
+#define MAX_SG_ENTRIES		16
+#define SG_CACHELINE_0		0
+#define SG_CACHELINE_1		4
+#define SG_CACHELINE_2		8
+#define SG_CACHELINE_3		12
+
+/* Structure encompassing a job descriptor which is to be processed
+ * by SEC. User should also initialise this structure with the callback
+ * function pointer which will be called by driver after recieving proccessed
+ * descriptor from SEC. User data is also passed in this data structure which
+ * will be sent as an argument to the user callback function.
+ */
+struct job_descriptor {
+	uint32_t desc[CAAM_JOB_DESC_SIZE];
+};
+
+struct caam_jr_op_ctx {
+	struct job_descriptor jobdes;
+	/* sg[0] output, sg[1] input, others are possible sub frames */
+	struct sec4_sg_entry sg[MAX_SG_ENTRIES];
+	struct rte_crypto_op *op;
+	struct rte_mempool *ctx_pool; /* mempool pointer for caam_jr_op_ctx */
+	int64_t vtop_offset;
+	uint8_t digest[JR_MAX_NB_MAX_DIGEST];
+};
+
+/**
+ * Checksum
+ *
+ * @param buffer calculate chksum for buffer
+ * @param len    buffer length
+ *
+ * @return checksum value in host cpu order
+ */
+static inline uint16_t
+calc_chksum(void *buffer, int len)
+{
+	uint16_t *buf = (uint16_t *)buffer;
+	uint32_t sum = 0;
+	uint16_t result;
+
+	for (sum = 0; len > 1; len -= 2)
+		sum += *buf++;
+
+	if (len == 1)
+		sum += *(unsigned char *)buf;
+
+	sum = (sum >> 16) + (sum & 0xFFFF);
+	sum += (sum >> 16);
+	result = ~sum;
+
+	return  result;
+}
+struct uio_job_ring {
+	uint32_t jr_id;
+	uint32_t uio_fd;
+	void *register_base_addr;
+	int map_size;
+	int uio_minor_number;
+};
+
+int sec_cleanup(void);
+int sec_configure(void);
+struct uio_job_ring *config_job_ring(void);
+void free_job_ring(uint32_t uio_fd);
+
+/* For Dma memory allocation of specified length and alignment */
+static inline void *
+caam_jr_dma_mem_alloc(size_t align, size_t len)
+{
+	return rte_malloc("mem_alloc", len, align);
+}
+
+/* For freeing dma memory */
+static inline void
+caam_jr_dma_free(void *ptr)
+{
+	rte_free(ptr);
+}
+
+static inline rte_iova_t
+caam_jr_mem_vtop(void *vaddr)
+{
+	const struct rte_memseg *ms;
+
+	ms = rte_mem_virt2memseg(vaddr, NULL);
+	if (ms)
+		return ms->iova + RTE_PTR_DIFF(vaddr, ms->addr);
+	return (size_t)NULL;
+}
+
+static inline void *
+caam_jr_dma_ptov(rte_iova_t paddr)
+{
+	return rte_mem_iova2virt(paddr);
+}
+
+/* Virtual to physical address conversion */
+static inline rte_iova_t caam_jr_dma_vtop(void *ptr)
+{
+	return caam_jr_mem_vtop(ptr);
+}
+
+/** @brief Request to SEC kernel driver to enable interrupts for
+ *         descriptor finished processing
+ *  Use UIO to communicate with SEC kernel driver: write command
+ *  value that indicates an IRQ enable action into UIO file descriptor
+ *  of this job ring.
+ *
+ * @param [in]  uio_fd     Job Ring UIO File descriptor
+ * @retval 0 for success
+ * @retval -1 value for error
+ */
+uint32_t caam_jr_enable_irqs(uint32_t uio_fd);
+
+/** @brief Request to SEC kernel driver to disable interrupts for descriptor
+ *  finished processing
+ *  Use UIO to communicate with SEC kernel driver: write command
+ *  value that indicates an IRQ disable action into UIO file descriptor
+ *  of this job ring.
+ *
+ * @param [in]  uio_fd    UIO File descripto
+ * @retval 0 for success
+ * @retval -1 value for error
+ *
+ */
+uint32_t caam_jr_disable_irqs(uint32_t uio_fd);
+
+#endif
diff --git a/drivers/crypto/caam_jr/meson.build b/drivers/crypto/caam_jr/meson.build
index 3edd0a212..c282eb4dc 100644
--- a/drivers/crypto/caam_jr/meson.build
+++ b/drivers/crypto/caam_jr/meson.build
@@ -6,6 +6,9 @@ if host_machine.system() != 'linux'
 endif
 
 deps += ['bus_vdev', 'bus_dpaa', 'security']
-sources = files('caam_jr.c')
+sources = files('caam_jr_hw.c', 'caam_jr.c')
 
 allow_experimental_apis = true
+
+includes += include_directories('../dpaa2_sec/')
+includes += include_directories('../../bus/dpaa/include/')
