DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 0/4] Add Marvell OCTEON TX2 regex driver
@ 2020-09-01 12:24 guyk
  2020-09-01 12:24 ` [dpdk-dev] [PATCH 1/4] common/octeontx2: add REE definitions and logging support guyk
                   ` (6 more replies)
  0 siblings, 7 replies; 33+ messages in thread
From: guyk @ 2020-09-01 12:24 UTC (permalink / raw)
  To: jerinj, ndabilpuram, thomas, mdr, nhorman, bruce.richardson,
	anatoly.burakov, john.mcnamara, marko.kovacevic
  Cc: dev, smadarf, dovrat, guyk, orika

From: Guy Kaneti <guyk@marvell.com>

This patchset adds support for OCTEON TX2 regex driver as DPDK regexdev.
The driver implements the API defined in the regexdev lib.

Guy Kaneti (4):
  common/octeontx2: add REE definitions and logging support
  regex/octeontx2: add build infra and device support
  usertools: add octeontx2 REE device binding
  doc: add Marvell OCTEON TX2 regex guide

 MAINTAINERS                                   |    3 +
 config/common_base                            |    6 +
 doc/guides/platform/octeontx2.rst             |    5 +
 doc/guides/regexdevs/features/octeontx2.ini   |   10 +
 doc/guides/regexdevs/index.rst                |    1 +
 doc/guides/regexdevs/octeontx2.rst            |   49 +
 doc/guides/rel_notes/release_20_11.rst        |    5 +
 drivers/common/octeontx2/hw/otx2_ree.h        |   27 +
 drivers/common/octeontx2/hw/otx2_rvu.h        |    5 +
 drivers/common/octeontx2/otx2_common.c        |    1 +
 drivers/common/octeontx2/otx2_common.h        |    5 +
 drivers/common/octeontx2/otx2_mbox.h          |  103 ++
 .../rte_common_octeontx2_version.map          |    1 +
 drivers/regex/meson.build                     |    2 +-
 drivers/regex/octeontx2/meson.build           |   53 +
 drivers/regex/octeontx2/otx2_regexdev.c       | 1001 +++++++++++++++++
 drivers/regex/octeontx2/otx2_regexdev.h       |  109 ++
 .../regex/octeontx2/otx2_regexdev_compiler.c  |  229 ++++
 .../regex/octeontx2/otx2_regexdev_compiler.h  |   11 +
 .../regex/octeontx2/otx2_regexdev_hw_access.c |  167 +++
 .../regex/octeontx2/otx2_regexdev_hw_access.h |  202 ++++
 drivers/regex/octeontx2/otx2_regexdev_mbox.c  |  401 +++++++
 drivers/regex/octeontx2/otx2_regexdev_mbox.h  |   38 +
 .../rte_pmd_octeontx2_regex_version.map       |    3 +
 meson_options.txt                             |    2 +
 usertools/dpdk-devbind.py                     |    8 +
 26 files changed, 2446 insertions(+), 1 deletion(-)
 create mode 100644 doc/guides/regexdevs/features/octeontx2.ini
 create mode 100644 doc/guides/regexdevs/octeontx2.rst
 create mode 100644 drivers/common/octeontx2/hw/otx2_ree.h
 create mode 100644 drivers/regex/octeontx2/meson.build
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev.h
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_compiler.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_compiler.h
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_hw_access.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_hw_access.h
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_mbox.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_mbox.h
 create mode 100644 drivers/regex/octeontx2/rte_pmd_octeontx2_regex_version.map

-- 
2.28.0


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [dpdk-dev] [PATCH 1/4] common/octeontx2: add REE definitions and logging support
  2020-09-01 12:24 [dpdk-dev] [PATCH 0/4] Add Marvell OCTEON TX2 regex driver guyk
@ 2020-09-01 12:24 ` guyk
  2020-10-11  7:35   ` Liron Himi
  2020-09-01 12:24 ` [dpdk-dev] [PATCH 2/4] regex/octeontx2: add build infra and device support guyk
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 33+ messages in thread
From: guyk @ 2020-09-01 12:24 UTC (permalink / raw)
  To: jerinj, ndabilpuram, thomas, mdr, nhorman, bruce.richardson,
	anatoly.burakov, john.mcnamara, marko.kovacevic
  Cc: dev, smadarf, dovrat, guyk, orika

From: Guy Kaneti <guyk@marvell.com>

Add REE mbox msg definitions, RVU and REE HW definitions

Signed-off-by: Guy Kaneti <guyk@marvell.com>
---
 drivers/common/octeontx2/hw/otx2_ree.h        |  27 +++++
 drivers/common/octeontx2/hw/otx2_rvu.h        |   5 +
 drivers/common/octeontx2/otx2_common.c        |   1 +
 drivers/common/octeontx2/otx2_common.h        |   5 +
 drivers/common/octeontx2/otx2_mbox.h          | 103 ++++++++++++++++++
 .../rte_common_octeontx2_version.map          |   1 +
 6 files changed, 142 insertions(+)
 create mode 100644 drivers/common/octeontx2/hw/otx2_ree.h

diff --git a/drivers/common/octeontx2/hw/otx2_ree.h b/drivers/common/octeontx2/hw/otx2_ree.h
new file mode 100644
index 000000000..b7481f125
--- /dev/null
+++ b/drivers/common/octeontx2/hw/otx2_ree.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#ifndef __OTX2_REE_HW_H__
+#define __OTX2_REE_HW_H__
+
+/* REE BAR0*/
+#define REE_AF_REEXM_MAX_MATCH		(0x80c8)
+
+/* REE BAR02 */
+#define REE_LF_MISC_INT                 (0x300)
+#define REE_LF_DONE_INT                 (0x120)
+
+#define REE_AF_QUEX_GMCTL(a)            (0x800 | (a) << 3)
+
+#define REE_AF_INT_VEC_RAS          (0x0ull)
+#define REE_AF_INT_VEC_RVU          (0x1ull)
+#define REE_AF_INT_VEC_QUE_DONE     (0x2ull)
+#define REE_AF_INT_VEC_AQ           (0x3ull)
+
+/* ENUMS */
+
+#define REE_LF_INT_VEC_QUE_DONE	(0x0ull)
+#define REE_LF_INT_VEC_MISC		(0x1ull)
+
+#endif /* __OTX2_REE_HW_H__*/
diff --git a/drivers/common/octeontx2/hw/otx2_rvu.h b/drivers/common/octeontx2/hw/otx2_rvu.h
index 330bfb37f..072515207 100644
--- a/drivers/common/octeontx2/hw/otx2_rvu.h
+++ b/drivers/common/octeontx2/hw/otx2_rvu.h
@@ -130,6 +130,7 @@
 #define RVU_BLOCK_TYPE_RAD                  (0xdull)
 #define RVU_BLOCK_TYPE_DFA                  (0xeull)
 #define RVU_BLOCK_TYPE_HNA                  (0xfull)
+#define RVU_BLOCK_TYPE_REE                  (0xeull)
 
 #define RVU_BLOCK_ADDR_RVUM                 (0x0ull)
 #define RVU_BLOCK_ADDR_LMT                  (0x1ull)
@@ -146,6 +147,8 @@
 #define RVU_BLOCK_ADDR_NDC2                 (0xeull)
 #define RVU_BLOCK_ADDR_R_END                (0x1full)
 #define RVU_BLOCK_ADDR_R_START              (0x14ull)
+#define RVU_BLOCK_ADDR_REE0                 (0x14ull)
+#define RVU_BLOCK_ADDR_REE1                 (0x15ull)
 
 #define RVU_VF_INT_VEC_MBOX                 (0x0ull)
 
@@ -167,6 +170,7 @@
 #define NPA_AF_BAR2_SEL			(0x9000000ull)
 #define CPT_AF_BAR2_SEL			(0x9000000ull)
 #define RVU_AF_BAR2_SEL			(0x9000000ull)
+#define REE_AF_BAR2_SEL			(0x9000000ull)
 
 #define AF_BAR2_ALIASX(a, b) \
 	(0x9100000ull | (uint64_t)(a) << 12 | (uint64_t)(b))
@@ -177,6 +181,7 @@
 #define NPA_AF_BAR2_ALIASX(a, b)		AF_BAR2_ALIASX(0, b)
 #define CPT_AF_BAR2_ALIASX(a, b)		AF_BAR2_ALIASX(a, b)
 #define RVU_AF_BAR2_ALIASX(a, b)		AF_BAR2_ALIASX(a, b)
+#define REE_AF_BAR2_ALIASX(a, b)		AF_BAR2_ALIASX(a, b)
 
 /* Structures definitions */
 
diff --git a/drivers/common/octeontx2/otx2_common.c b/drivers/common/octeontx2/otx2_common.c
index b292e999a..d23c50242 100644
--- a/drivers/common/octeontx2/otx2_common.c
+++ b/drivers/common/octeontx2/otx2_common.c
@@ -213,3 +213,4 @@ RTE_LOG_REGISTER(otx2_logtype_sso, pmd.event.octeontx2, NOTICE);
 RTE_LOG_REGISTER(otx2_logtype_tim, pmd.event.octeontx2.timer, NOTICE);
 RTE_LOG_REGISTER(otx2_logtype_dpi, pmd.raw.octeontx2.dpi, NOTICE);
 RTE_LOG_REGISTER(otx2_logtype_ep, pmd.raw.octeontx2.ep, NOTICE);
+RTE_LOG_REGISTER(otx2_logtype_ree, pmd.regex.octeontx2, NOTICE);
diff --git a/drivers/common/octeontx2/otx2_common.h b/drivers/common/octeontx2/otx2_common.h
index 2168cde4d..b6779f710 100644
--- a/drivers/common/octeontx2/otx2_common.h
+++ b/drivers/common/octeontx2/otx2_common.h
@@ -21,6 +21,7 @@
 #include "hw/otx2_sso.h"
 #include "hw/otx2_ssow.h"
 #include "hw/otx2_tim.h"
+#include "hw/otx2_ree.h"
 
 /* Alignment */
 #define OTX2_ALIGN  128
@@ -96,6 +97,7 @@ extern int otx2_logtype_tm;
 extern int otx2_logtype_tim;
 extern int otx2_logtype_dpi;
 extern int otx2_logtype_ep;
+extern int otx2_logtype_ree;
 
 #define otx2_err(fmt, args...)			\
 	RTE_LOG(ERR, PMD, "%s():%u " fmt "\n",	\
@@ -119,6 +121,7 @@ extern int otx2_logtype_ep;
 #define otx2_tim_dbg(fmt, ...) otx2_dbg(tim, fmt, ##__VA_ARGS__)
 #define otx2_dpi_dbg(fmt, ...) otx2_dbg(dpi, fmt, ##__VA_ARGS__)
 #define otx2_sdp_dbg(fmt, ...) otx2_dbg(ep, fmt, ##__VA_ARGS__)
+#define otx2_ree_dbg(fmt, ...) otx2_dbg(ree, fmt, ##__VA_ARGS__)
 
 /* PCI IDs */
 #define PCI_VENDOR_ID_CAVIUM			0x177D
@@ -136,6 +139,8 @@ extern int otx2_logtype_ep;
 #define PCI_DEVID_OCTEONTX2_EP_VF		0xB203 /* OCTEON TX2 EP mode */
 #define PCI_DEVID_OCTEONTX2_RVU_SDP_PF		0xA0f6
 #define PCI_DEVID_OCTEONTX2_RVU_SDP_VF		0xA0f7
+#define PCI_DEVID_OCTEONTX2_RVU_REE_PF		0xA0f4
+#define PCI_DEVID_OCTEONTX2_RVU_REE_VF		0xA0f5
 
 /*
  * REVID for RVU PCIe devices.
diff --git a/drivers/common/octeontx2/otx2_mbox.h b/drivers/common/octeontx2/otx2_mbox.h
index 34b1d0663..b3c32e9a4 100644
--- a/drivers/common/octeontx2/otx2_mbox.h
+++ b/drivers/common/octeontx2/otx2_mbox.h
@@ -199,6 +199,19 @@ M(CPT_INLINE_IPSEC_CFG, 0xA04, cpt_inline_ipsec_cfg,			\
 M(CPT_RX_INLINE_LF_CFG, 0xBFE, cpt_rx_inline_lf_cfg,			\
 			       cpt_rx_inline_lf_cfg_msg, msg_rsp)	\
 M(CPT_GET_CAPS,		0xBFD, cpt_caps_get, msg_req, cpt_caps_rsp_msg)	\
+/* REE mbox IDs (range 0xE00 - 0xFFF) */				\
+M(REE_CONFIG_LF,	0xE01, ree_config_lf, ree_lf_req_msg,		\
+				msg_rsp)				\
+M(REE_RD_WR_REGISTER,	0xE02, ree_rd_wr_register, ree_rd_wr_reg_msg,	\
+				ree_rd_wr_reg_msg)			\
+M(REE_RULE_DB_PROG,	0xE03, ree_rule_db_prog,			\
+				ree_rule_db_prog_req_msg,		\
+				msg_rsp)				\
+M(REE_RULE_DB_LEN_GET,	0xE04, ree_rule_db_len_get, ree_req_msg,	\
+				ree_rule_db_len_rsp_msg)		\
+M(REE_RULE_DB_GET,	0xE05, ree_rule_db_get,				\
+				ree_rule_db_get_req_msg,		\
+				ree_rule_db_get_rsp_msg)		\
 /* NPC mbox IDs (range 0x6000 - 0x7FFF) */				\
 M(NPC_MCAM_ALLOC_ENTRY,	0x6000, npc_mcam_alloc_entry,			\
 				npc_mcam_alloc_entry_req,		\
@@ -1650,6 +1663,96 @@ struct tim_enable_rsp {
 	uint32_t __otx2_io currentbucket;
 };
 
+/* REE mailbox error codes
+ * Range 1001 - 1100.
+ */
+enum ree_af_status {
+	REE_AF_ERR_RULE_UNKNOWN_VALUE		= -1001,
+	REE_AF_ERR_LF_NO_MORE_RESOURCES		= -1002,
+	REE_AF_ERR_LF_INVALID			= -1003,
+	REE_AF_ERR_ACCESS_DENIED		= -1004,
+	REE_AF_ERR_RULE_DB_PARTIAL		= -1005,
+	REE_AF_ERR_RULE_DB_EQ_BAD_VALUE		= -1006,
+	REE_AF_ERR_RULE_DB_BLOCK_ALLOC_FAILED	= -1007,
+	REE_AF_ERR_BLOCK_NOT_IMPLEMENTED	= -1008,
+	REE_AF_ERR_RULE_DB_INC_OFFSET_TOO_BIG	= -1009,
+	REE_AF_ERR_RULE_DB_OFFSET_TOO_BIG	= -1010,
+	REE_AF_ERR_Q_IS_GRACEFUL_DIS		= -1011,
+	REE_AF_ERR_Q_NOT_GRACEFUL_DIS		= -1012,
+	REE_AF_ERR_RULE_DB_ALLOC_FAILED		= -1013,
+	REE_AF_ERR_RULE_DB_TOO_BIG		= -1014,
+	REE_AF_ERR_RULE_DB_GEQ_BAD_VALUE	= -1015,
+	REE_AF_ERR_RULE_DB_LEQ_BAD_VALUE	= -1016,
+	REE_AF_ERR_RULE_DB_WRONG_LENGTH		= -1017,
+	REE_AF_ERR_RULE_DB_WRONG_OFFSET		= -1018,
+	REE_AF_ERR_RULE_DB_BLOCK_TOO_BIG	= -1019,
+	REE_AF_ERR_RULE_DB_SHOULD_FILL_REQUEST	= -1020,
+	REE_AF_ERR_RULE_DBI_ALLOC_FAILED	= -1021,
+	REE_AF_ERR_LF_WRONG_PRIORITY		= -1022,
+	REE_AF_ERR_LF_SIZE_TOO_BIG		= -1023,
+};
+
+/* REE mbox message formats */
+
+struct ree_req_msg {
+	struct mbox_msghdr hdr;
+	uint32_t __otx2_io blkaddr;
+};
+
+struct ree_lf_req_msg {
+	struct mbox_msghdr hdr;
+	uint32_t __otx2_io blkaddr;
+	uint32_t __otx2_io size;
+	uint8_t __otx2_io lf;
+	uint8_t __otx2_io pri;
+};
+
+struct ree_rule_db_prog_req_msg {
+	struct mbox_msghdr hdr;
+#define REE_RULE_DB_REQ_BLOCK_SIZE (MBOX_SIZE >> 1)
+	uint8_t __otx2_io rule_db[REE_RULE_DB_REQ_BLOCK_SIZE];
+	uint32_t __otx2_io blkaddr; /* REE0 or REE1 */
+	uint32_t __otx2_io total_len; /* total len of rule db */
+	uint32_t __otx2_io offset; /* offset of current rule db block */
+	uint16_t __otx2_io len; /* length of rule db block */
+	uint8_t __otx2_io is_last; /* is this the last block */
+	uint8_t __otx2_io is_incremental; /* is incremental flow */
+	uint8_t __otx2_io is_dbi; /* is rule db incremental */
+};
+
+struct ree_rule_db_get_req_msg {
+	struct mbox_msghdr hdr;
+	uint32_t __otx2_io blkaddr;
+	uint32_t __otx2_io offset; /* retrieve db from this offset */
+	uint8_t __otx2_io is_dbi; /* is request for rule db incremental */
+};
+
+struct ree_rd_wr_reg_msg {
+	struct mbox_msghdr hdr;
+	uint64_t __otx2_io reg_offset;
+	uint64_t __otx2_io *ret_val;
+	uint64_t __otx2_io val;
+	uint32_t __otx2_io blkaddr;
+	uint8_t __otx2_io is_write;
+};
+
+struct ree_rule_db_len_rsp_msg {
+	struct mbox_msghdr hdr;
+	uint32_t __otx2_io blkaddr;
+	uint32_t __otx2_io len;
+	uint32_t __otx2_io inc_len;
+};
+
+struct ree_rule_db_get_rsp_msg {
+	struct mbox_msghdr hdr;
+#define REE_RULE_DB_RSP_BLOCK_SIZE (MBOX_DOWN_TX_SIZE - SZ_1K)
+	uint8_t __otx2_io rule_db[REE_RULE_DB_RSP_BLOCK_SIZE];
+	uint32_t __otx2_io total_len; /* total len of rule db */
+	uint32_t __otx2_io offset; /* offset of current rule db block */
+	uint16_t __otx2_io len; /* length of rule db block */
+	uint8_t __otx2_io is_last; /* is this the last block */
+};
+
 __rte_internal
 const char *otx2_mbox_id2name(uint16_t id);
 int otx2_mbox_id2size(uint16_t id);
diff --git a/drivers/common/octeontx2/rte_common_octeontx2_version.map b/drivers/common/octeontx2/rte_common_octeontx2_version.map
index 9a9969613..d269d70d8 100644
--- a/drivers/common/octeontx2/rte_common_octeontx2_version.map
+++ b/drivers/common/octeontx2/rte_common_octeontx2_version.map
@@ -38,6 +38,7 @@ INTERNAL {
 	otx2_sso_pf_func_get;
 	otx2_sso_pf_func_set;
 	otx2_unregister_irq;
+	otx2_logtype_ree;
 
 	local: *;
 };
-- 
2.28.0


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [dpdk-dev] [PATCH 2/4] regex/octeontx2: add build infra and device support
  2020-09-01 12:24 [dpdk-dev] [PATCH 0/4] Add Marvell OCTEON TX2 regex driver guyk
  2020-09-01 12:24 ` [dpdk-dev] [PATCH 1/4] common/octeontx2: add REE definitions and logging support guyk
@ 2020-09-01 12:24 ` guyk
  2020-10-11  7:36   ` Liron Himi
  2020-09-01 12:24 ` [dpdk-dev] [PATCH 3/4] usertools: add octeontx2 REE device binding guyk
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 33+ messages in thread
From: guyk @ 2020-09-01 12:24 UTC (permalink / raw)
  To: jerinj, ndabilpuram, thomas, mdr, nhorman, bruce.richardson,
	anatoly.burakov, john.mcnamara, marko.kovacevic
  Cc: dev, smadarf, dovrat, guyk, orika

From: Guy Kaneti <guyk@marvell.com>

Add meson based build infrastructure along with the
OTX2 regexdev (REE) device functions.

For regex rule compiler support build:
meson configure -Dree_compiler_sdk=<path-to-compiler-sdk>

Signed-off-by: Guy Kaneti <guyk@marvell.com>
---
 MAINTAINERS                                   |    3 +
 config/common_base                            |    6 +
 drivers/regex/meson.build                     |    2 +-
 drivers/regex/octeontx2/meson.build           |   53 +
 drivers/regex/octeontx2/otx2_regexdev.c       | 1001 +++++++++++++++++
 drivers/regex/octeontx2/otx2_regexdev.h       |  109 ++
 .../regex/octeontx2/otx2_regexdev_compiler.c  |  229 ++++
 .../regex/octeontx2/otx2_regexdev_compiler.h  |   11 +
 .../regex/octeontx2/otx2_regexdev_hw_access.c |  167 +++
 .../regex/octeontx2/otx2_regexdev_hw_access.h |  202 ++++
 drivers/regex/octeontx2/otx2_regexdev_mbox.c  |  401 +++++++
 drivers/regex/octeontx2/otx2_regexdev_mbox.h  |   38 +
 .../rte_pmd_octeontx2_regex_version.map       |    3 +
 meson_options.txt                             |    2 +
 14 files changed, 2226 insertions(+), 1 deletion(-)
 create mode 100644 drivers/regex/octeontx2/meson.build
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev.h
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_compiler.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_compiler.h
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_hw_access.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_hw_access.h
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_mbox.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_mbox.h
 create mode 100644 drivers/regex/octeontx2/rte_pmd_octeontx2_regex_version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index ed163f5d5..ab8a9313c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1137,6 +1137,9 @@ F: drivers/regex/mlx5/
 F: doc/guides/regexdevs/mlx5.rst
 F: doc/guides/regexdevs/features/mlx5.ini
 
+Marvell OCTEON TX2 regex
+M: Guy Kaneti <guyk@marvell.com>
+F: drivers/regex/octeontx2/
 
 vDPA Drivers
 ------------
diff --git a/config/common_base b/config/common_base
index fbf0ee70c..2cd687bf6 100644
--- a/config/common_base
+++ b/config/common_base
@@ -842,6 +842,12 @@ CONFIG_RTE_LIBRTE_PMD_OCTEONTX2_EP_RAWDEV=y
 #
 CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV=y
 
+#
+# Compile PMD for Octeontx2 REE regex device
+#
+CONFIG_RTE_LIBRTE_PMD_OCTEONTX2_REGEX=y
+CONFIG_RTE_LIBRTE_PMD_OCTEONTX2_REGEX_COMPILER=n
+
 #
 # Compile librte_ring
 #
diff --git a/drivers/regex/meson.build b/drivers/regex/meson.build
index 8edeba3a0..79bb5d5df 100644
--- a/drivers/regex/meson.build
+++ b/drivers/regex/meson.build
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright 2020 Mellanox Technologies, Ltd
 
-drivers = ['mlx5']
+drivers = ['mlx5', 'octeontx2']
 std_deps = ['ethdev', 'kvargs'] # 'ethdev' also pulls in mbuf, net, eal etc
 config_flag_fmt = 'RTE_LIBRTE_@0@_PMD'
 driver_name_fmt = 'rte_pmd_@0@'
diff --git a/drivers/regex/octeontx2/meson.build b/drivers/regex/octeontx2/meson.build
new file mode 100644
index 000000000..c212e3d43
--- /dev/null
+++ b/drivers/regex/octeontx2/meson.build
@@ -0,0 +1,53 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(C) 2020 Marvell International Ltd.
+#
+
+if not is_linux
+	build = false
+	reason = 'only supported on Linux'
+endif
+
+path = get_option('ree_compiler_sdk')
+lib_dir = path + '/lib'
+inc_dir = path + '/include'
+
+if dpdk_conf.has('RTE_LIBRTE_PMD_OCTEONTX2_REGEX_COMPILER')
+	lib = cc.find_library('librxp_compiler', dirs : [lib_dir], required: false)
+	if not lib.found()
+		build = false
+		reason = 'missing dependency, "librxp_compiler"'
+	else
+		ext_deps += lib
+		ext_deps += cc.find_library('libstdc++', required: true)
+		includes += include_directories(inc_dir)
+		cflags += ['-DREE_COMPILER_SDK']
+	endif
+endif
+
+sources = files('otx2_regexdev.c',
+		'otx2_regexdev_hw_access.c',
+		'otx2_regexdev_mbox.c',
+		'otx2_regexdev_compiler.c'
+		)
+
+extra_flags = []
+# This integrated controller runs only on a arm64 machine, remove 32bit warnings
+if not dpdk_conf.get('RTE_ARCH_64')
+	extra_flags += ['-Wno-int-to-pointer-cast', '-Wno-pointer-to-int-cast']
+endif
+
+# for clang 32-bit compiles we need libatomic for 64-bit atomic ops
+if cc.get_id() == 'clang' and dpdk_conf.get('RTE_ARCH_64') == false
+	ext_deps += cc.find_library('atomic')
+endif
+
+foreach flag: extra_flags
+	if cc.has_argument(flag)
+		cflags += flag
+	endif
+endforeach
+
+name = 'octeontx2_regex'
+deps += ['bus_pci', 'common_octeontx2', 'regexdev']
+
+includes += include_directories('../../common/octeontx2')
diff --git a/drivers/regex/octeontx2/otx2_regexdev.c b/drivers/regex/octeontx2/otx2_regexdev.c
new file mode 100644
index 000000000..2aebd0138
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev.c
@@ -0,0 +1,1001 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include <rte_malloc.h>
+#include <rte_memzone.h>
+#include <rte_regexdev.h>
+#include <rte_regexdev_core.h>
+#include <rte_regexdev_driver.h>
+
+/* REE common headers */
+#include "otx2_common.h"
+#include "otx2_dev.h"
+#include "otx2_regexdev.h"
+#include "otx2_regexdev_compiler.h"
+#include "otx2_regexdev_hw_access.h"
+#include "otx2_regexdev_mbox.h"
+
+
+/* HW matches are at offset 0x80 from RES_PTR_ADDR
+ * In op structure matches starts at W5 (0x28)
+ * There is a need to copy to 0x28 to 0x80 The matches that are at the tail
+ * Which are 88 B. Each match holds 8 B, so up to 11 matches can be copied
+ */
+#define REE_NUM_MATCHES_ALIGN	11
+/* The REE co-processor will write up to 254 job match structures
+ * (REE_MATCH_S) starting at address [RES_PTR_ADDR] + 0x80.
+ */
+#define REE_MATCH_OFFSET	0x80
+
+#define REE_MAX_RULES_PER_GROUP 0xFFFF
+#define REE_MAX_GROUPS 0xFFFF
+
+/* This is temporarily here */
+#define REE0_PF	19
+#define REE1_PF	20
+
+#define REE_RULE_DB_VERSION	2
+#define REE_RULE_DB_REVISION	0
+
+struct ree_rule_db_entry {
+	uint8_t		type;
+	uint32_t	addr;
+	uint64_t	value;
+};
+
+struct ree_rule_db {
+	uint32_t version;
+	uint32_t revision;
+	uint32_t number_of_entries;
+	struct ree_rule_db_entry entries[];
+} __rte_packed;
+
+static void
+qp_memzone_name_get(char *name, int size, int dev_id, int qp_id)
+{
+	snprintf(name, size, "otx2_ree_lf_mem_%u:%u", dev_id, qp_id);
+}
+
+static struct otx2_ree_qp *
+ree_qp_create(const struct rte_regexdev *dev, uint16_t qp_id)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	uint64_t pg_sz = sysconf(_SC_PAGESIZE);
+	struct otx2_ree_vf *vf = &data->vf;
+	const struct rte_memzone *lf_mem;
+	uint32_t len, iq_len, size_div2;
+	char name[RTE_MEMZONE_NAMESIZE];
+	uint64_t used_len, iova;
+	struct otx2_ree_qp *qp;
+	uint8_t *va;
+	int ret;
+
+	/* Allocate queue pair */
+	qp = rte_zmalloc("OCTEON TX2 Regex PMD Queue Pair", sizeof(*qp),
+				OTX2_ALIGN);
+	if (qp == NULL) {
+		otx2_err("Could not allocate queue pair");
+		return NULL;
+	}
+
+	iq_len = OTX2_REE_IQ_LEN;
+
+	/*
+	 * Queue size must be in units of 128B 2 * REE_INST_S (which is 64B),
+	 * and a power of 2.
+	 * effective queue size to software is (size - 1) * 128
+	 */
+	size_div2 = iq_len >> 1;
+
+	/* For pending queue */
+	len = iq_len * RTE_ALIGN(sizeof(struct otx2_ree_rid), 8);
+
+	/* So that instruction queues start as pg size aligned */
+	len = RTE_ALIGN(len, pg_sz);
+
+	/* For instruction queues */
+	len += OTX2_REE_IQ_LEN * sizeof(union otx2_ree_inst);
+
+	/* Waste after instruction queues */
+	len = RTE_ALIGN(len, pg_sz);
+
+	qp_memzone_name_get(name, RTE_MEMZONE_NAMESIZE, dev->data->dev_id,
+			    qp_id);
+
+	lf_mem = rte_memzone_reserve_aligned(name, len, vf->otx2_dev.node,
+			RTE_MEMZONE_SIZE_HINT_ONLY | RTE_MEMZONE_256MB,
+			RTE_CACHE_LINE_SIZE);
+	if (lf_mem == NULL) {
+		otx2_err("Could not allocate reserved memzone");
+		goto qp_free;
+	}
+
+	va = lf_mem->addr;
+	iova = lf_mem->iova;
+
+	memset(va, 0, len);
+
+	/* Initialize pending queue */
+	qp->pend_q.rid_queue = (struct otx2_ree_rid *)va;
+	qp->pend_q.enq_tail = 0;
+	qp->pend_q.deq_head = 0;
+	qp->pend_q.pending_count = 0;
+
+	used_len = iq_len * RTE_ALIGN(sizeof(struct otx2_ree_rid), 8);
+	used_len = RTE_ALIGN(used_len, pg_sz);
+	iova += used_len;
+
+	qp->iq_dma_addr = iova;
+	qp->id = qp_id;
+	qp->base = OTX2_REE_LF_BAR2(vf, qp_id);
+	qp->otx2_regexdev_jobid = 0;
+	qp->write_offset = 0;
+
+	ret = otx2_ree_iq_enable(dev, qp, OTX2_REE_QUEUE_HI_PRIO, size_div2);
+	if (ret) {
+		otx2_err("Could not enable instruction queue");
+		goto qp_free;
+	}
+
+	return qp;
+
+qp_free:
+	rte_free(qp);
+	return NULL;
+}
+
+static int
+ree_qp_destroy(const struct rte_regexdev *dev, struct otx2_ree_qp *qp)
+{
+	const struct rte_memzone *lf_mem;
+	char name[RTE_MEMZONE_NAMESIZE];
+	int ret;
+
+	otx2_ree_iq_disable(qp);
+
+	qp_memzone_name_get(name, RTE_MEMZONE_NAMESIZE, dev->data->dev_id,
+			    qp->id);
+
+	lf_mem = rte_memzone_lookup(name);
+
+	ret = rte_memzone_free(lf_mem);
+	if (ret)
+		return ret;
+
+	rte_free(qp);
+
+	return 0;
+}
+
+static int
+ree_queue_pair_release(struct rte_regexdev *dev, uint16_t qp_id)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_qp *qp = data->queue_pairs[qp_id];
+	int ret;
+
+	ree_func_trace("Queue=%d", qp_id);
+
+	if (qp == NULL)
+		return -EINVAL;
+
+	ret = ree_qp_destroy(dev, qp);
+	if (ret) {
+		otx2_err("Could not destroy queue pair %d", qp_id);
+		return ret;
+	}
+
+	data->queue_pairs[qp_id] = NULL;
+
+	return 0;
+}
+
+static struct rte_regexdev *
+ree_dev_register(const char *name)
+{
+	struct rte_regexdev *dev;
+
+	otx2_ree_dbg("Creating regexdev %s\n", name);
+
+	/* allocate device structure */
+	dev = rte_regexdev_register(name);
+	if (dev == NULL) {
+		otx2_err("Failed to allocate regex device for %s", name);
+		return NULL;
+	}
+
+	/* allocate private device structure */
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		dev->data->dev_private =
+				rte_zmalloc_socket("regexdev device private",
+						sizeof(struct otx2_ree_data),
+						RTE_CACHE_LINE_SIZE,
+						rte_socket_id());
+
+		if (dev->data->dev_private == NULL) {
+			otx2_err("Cannot allocate memory for dev %s private data",
+					name);
+
+			rte_regexdev_unregister(dev);
+			return NULL;
+		}
+	}
+
+	return dev;
+}
+
+static int
+ree_dev_unregister(struct rte_regexdev *dev)
+{
+	otx2_ree_dbg("Closing regex device %s", dev->device->name);
+
+	/* free regex device */
+	rte_regexdev_unregister(dev);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(dev->data->dev_private);
+
+	return 0;
+}
+
+static int
+ree_dev_fini(struct rte_regexdev *dev)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct rte_pci_device *pci_dev;
+	int i, ret;
+
+	ree_func_trace();
+
+	for (i = 0; i < data->nb_queue_pairs; i++) {
+		ret = ree_queue_pair_release(dev, i);
+		if (ret)
+			return ret;
+	}
+
+	ret = otx2_ree_queues_detach(dev);
+	if (ret)
+		otx2_err("Could not detach queues");
+
+	/* TEMP : should be in lib */
+	if (data->queue_pairs)
+		rte_free(data->queue_pairs);
+	if (data->rules)
+		rte_free(data->rules);
+
+	pci_dev = container_of(dev->device, struct rte_pci_device, device);
+	otx2_dev_fini(pci_dev, &(data->vf.otx2_dev));
+
+	ret = ree_dev_unregister(dev);
+	if (ret)
+		otx2_err("Could not destroy PMD");
+
+	return ret;
+}
+
+static inline int
+ree_enqueue(struct otx2_ree_qp *qp, struct rte_regex_ops *op,
+		 struct otx2_ree_pending_queue *pend_q)
+{
+	union otx2_ree_inst inst;
+	union otx2_ree_res *res;
+	uint32_t offset;
+
+	if (unlikely(pend_q->pending_count >= OTX2_REE_DEFAULT_CMD_QLEN)) {
+		otx2_err("Pending count %" PRIu64 " is greater than Q size %d",
+		pend_q->pending_count, OTX2_REE_DEFAULT_CMD_QLEN);
+		return -EAGAIN;
+	}
+	if (unlikely(op->mbuf->data_len > OTX2_REE_MAX_PAYLOAD_SIZE ||
+			op->mbuf->data_len == 0)) {
+		otx2_err("Packet length %d is greater than MAX payload %d",
+				op->mbuf->data_len, OTX2_REE_MAX_PAYLOAD_SIZE);
+		return -EAGAIN;
+	}
+
+	/* W 0 */
+	inst.cn98xx.ooj = 1;
+	inst.cn98xx.dg = 0;
+	inst.cn98xx.doneint = 0;
+	/* W 1 */
+	inst.cn98xx.inp_ptr_addr = rte_pktmbuf_mtod(op->mbuf, uint64_t);
+	/* W 2 */
+	inst.cn98xx.inp_ptr_ctl = op->mbuf->data_len & 0x7FFF;
+	inst.cn98xx.inp_ptr_ctl = inst.cn98xx.inp_ptr_ctl << 32;
+
+	/* W 3 */
+	inst.cn98xx.res_ptr_addr = (uint64_t)op;
+	/* W 4 */
+	inst.cn98xx.wq_ptr = 0;
+	/* W 5 */
+	inst.cn98xx.ggrp = 0;
+	inst.cn98xx.tt = 0;
+	inst.cn98xx.tag = 0;
+	/* W 6 */
+	inst.cn98xx.ree_job_length = op->mbuf->data_len & 0x7FFF;
+	if (op->req_flags & RTE_REGEX_OPS_REQ_STOP_ON_MATCH_F)
+		inst.cn98xx.ree_job_ctrl = (0x2 << 8);
+	else if (op->req_flags & RTE_REGEX_OPS_REQ_MATCH_HIGH_PRIORITY_F)
+		inst.cn98xx.ree_job_ctrl = (0x1 << 8);
+	else
+		inst.cn98xx.ree_job_ctrl = 0;
+	inst.cn98xx.ree_job_id = qp->otx2_regexdev_jobid;
+	/* W 7 */
+	inst.cn98xx.ree_job_subset_id_0 = op->group_id0;
+	if (op->req_flags & RTE_REGEX_OPS_REQ_GROUP_ID1_VALID_F)
+		inst.cn98xx.ree_job_subset_id_1 = op->group_id1;
+	else
+		inst.cn98xx.ree_job_subset_id_1 = op->group_id0;
+	if (op->req_flags & RTE_REGEX_OPS_REQ_GROUP_ID2_VALID_F)
+		inst.cn98xx.ree_job_subset_id_2 = op->group_id2;
+	else
+		inst.cn98xx.ree_job_subset_id_2 = op->group_id0;
+	if (op->req_flags & RTE_REGEX_OPS_REQ_GROUP_ID3_VALID_F)
+		inst.cn98xx.ree_job_subset_id_3 = op->group_id3;
+	else
+		inst.cn98xx.ree_job_subset_id_3 = op->group_id0;
+
+	/* Copy REE command to Q */
+	offset = qp->write_offset * sizeof(inst);
+	memcpy((void *)(qp->iq_dma_addr + offset), &inst, sizeof(inst));
+
+	pend_q->rid_queue[pend_q->enq_tail].rid = (uintptr_t)op;
+	pend_q->rid_queue[pend_q->enq_tail].user_id = op->user_id;
+
+	/* Mark result as not done */
+	res = (union otx2_ree_res *)(op);
+	res->s.done = 0;
+	res->s.ree_err = 0;
+
+	/* We will use soft queue length here to limit requests */
+	REE_MOD_INC(pend_q->enq_tail, OTX2_REE_DEFAULT_CMD_QLEN);
+	pend_q->pending_count += 1;
+	REE_MOD_INC(qp->otx2_regexdev_jobid, 0xFFFFFF);
+	REE_MOD_INC(qp->write_offset, OTX2_REE_IQ_LEN);
+
+	return 0;
+}
+
+static uint16_t
+otx2_ree_enqueue_burst(struct rte_regexdev *dev, uint16_t qp_id,
+		       struct rte_regex_ops **ops, uint16_t nb_ops)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_qp *qp = data->queue_pairs[qp_id];
+	struct otx2_ree_pending_queue *pend_q;
+	uint16_t nb_allowed, count = 0;
+	struct rte_regex_ops *op;
+	int ret;
+
+	pend_q = &qp->pend_q;
+
+	nb_allowed = OTX2_REE_DEFAULT_CMD_QLEN - pend_q->pending_count;
+	if (nb_ops > nb_allowed)
+		nb_ops = nb_allowed;
+
+	for (count = 0; count < nb_ops; count++) {
+		op = ops[count];
+		ret = ree_enqueue(qp, op, pend_q);
+
+		if (unlikely(ret))
+			break;
+	}
+
+	/*
+	 * Make sure all instructions are written before DOORBELL is activated
+	 */
+	rte_cio_wmb();
+
+	/* Update Doorbell */
+	otx2_write64(count, qp->base + OTX2_REE_LF_DOORBELL);
+
+	return count;
+}
+
+static inline void
+ree_dequeue_post_process(struct rte_regex_ops *ops)
+{
+	uint8_t ree_res_mcnt, ree_res_dmcnt;
+	int off = REE_MATCH_OFFSET;
+	struct ree_res_s_98 *res;
+	uint16_t ree_res_status;
+	uint64_t match;
+
+	res = (struct ree_res_s_98 *)ops;
+	/* store res values on stack since ops and res
+	 * are using the same memory
+	 */
+	ree_res_status = res->ree_res_status;
+	ree_res_mcnt = res->ree_res_mcnt;
+	ree_res_dmcnt = res->ree_res_dmcnt;
+	ops->rsp_flags = 0;
+	ops->nb_actual_matches = ree_res_dmcnt;
+	ops->nb_matches = ree_res_mcnt;
+	if (unlikely(res->ree_err)) {
+		ops->nb_actual_matches = 0;
+		ops->nb_matches = 0;
+	}
+
+	if (unlikely(ree_res_status != REE_TYPE_RESULT_DESC)) {
+		if (ree_res_status & OTX2_REE_STATUS_PMI_SOJ_BIT)
+			ops->rsp_flags |= RTE_REGEX_OPS_RSP_PMI_SOJ_F;
+		if (ree_res_status & OTX2_REE_STATUS_PMI_EOJ_BIT)
+			ops->rsp_flags |= RTE_REGEX_OPS_RSP_PMI_EOJ_F;
+		if (ree_res_status & OTX2_REE_STATUS_ML_CNT_DET_BIT)
+			ops->rsp_flags |= RTE_REGEX_OPS_RSP_MAX_SCAN_TIMEOUT_F;
+		if (ree_res_status & OTX2_REE_STATUS_MM_CNT_DET_BIT)
+			ops->rsp_flags |= RTE_REGEX_OPS_RSP_MAX_MATCH_F;
+		if (ree_res_status & OTX2_REE_STATUS_MP_CNT_DET_BIT)
+			ops->rsp_flags |= RTE_REGEX_OPS_RSP_MAX_PREFIX_F;
+	}
+	if (ops->nb_matches > 0) {
+		/* Move the matches to the correct offset */
+		off = ((ops->nb_matches < REE_NUM_MATCHES_ALIGN) ?
+			ops->nb_matches : REE_NUM_MATCHES_ALIGN);
+		match = (uint64_t)ops + REE_MATCH_OFFSET;
+		match += (ops->nb_matches - off) *
+			sizeof(union otx2_ree_match);
+		memcpy((void *)ops->matches, (void *)match,
+			off * sizeof(union otx2_ree_match));
+	}
+}
+
+static uint16_t
+otx2_ree_dequeue_burst(struct rte_regexdev *dev, uint16_t qp_id,
+		       struct rte_regex_ops **ops, uint16_t nb_ops)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_qp *qp = data->queue_pairs[qp_id];
+	struct otx2_ree_pending_queue *pend_q;
+	int i, nb_pending, nb_completed = 0;
+	volatile struct ree_res_s_98 *res;
+	struct otx2_ree_rid *rid;
+
+	pend_q = &qp->pend_q;
+
+	nb_pending = pend_q->pending_count;
+
+	if (nb_ops > nb_pending)
+		nb_ops = nb_pending;
+
+	for (i = 0; i < nb_ops; i++) {
+		rid = &pend_q->rid_queue[pend_q->deq_head];
+		res = (volatile struct ree_res_s_98 *)(rid->rid);
+
+		/* Check response header done bit if completed */
+		if (unlikely(!res->done))
+			break;
+
+		ops[i] = (struct rte_regex_ops *)(rid->rid);
+		ops[i]->user_id = rid->user_id;
+
+		REE_MOD_INC(pend_q->deq_head, OTX2_REE_DEFAULT_CMD_QLEN);
+		pend_q->pending_count -= 1;
+	}
+
+	nb_completed = i;
+
+	for (i = 0; i < nb_completed; i++)
+		ree_dequeue_post_process(ops[i]);
+
+	return nb_completed;
+}
+
+static int
+otx2_ree_dev_info_get(struct rte_regexdev *dev, struct rte_regexdev_info *info)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+
+	ree_func_trace();
+
+	if (info == NULL)
+		return -EINVAL;
+
+	info->driver_name = dev->device->driver->name;
+	info->dev = dev->device;
+
+	info->max_queue_pairs = vf->max_queues;
+	info->max_matches = vf->max_matches;
+	info->max_payload_size = OTX2_REE_MAX_PAYLOAD_SIZE;
+	info->max_rules_per_group = data->max_rules_per_group;
+	info->max_groups = data->max_groups;
+	info->regexdev_capa = data->regexdev_capa;
+	info->rule_flags = data->rule_flags;
+
+	return 0;
+}
+
+static int
+otx2_ree_dev_config(struct rte_regexdev *dev,
+		    const struct rte_regexdev_config *cfg)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	const struct ree_rule_db *rule_db;
+	uint32_t rule_db_len;
+	int ret;
+
+	ree_func_trace();
+
+	if (cfg->nb_queue_pairs > vf->max_queues) {
+		otx2_err("Invalid number of queue pairs requested");
+		return -EINVAL;
+	}
+
+	if (cfg->nb_max_matches != vf->max_matches) {
+		otx2_err("Invalid number of max matches requested");
+		return -EINVAL;
+	}
+
+	if (cfg->dev_cfg_flags != 0) {
+		otx2_err("Invalid device configuration flags requested");
+		return -EINVAL;
+	}
+
+	/* Unregister error interrupts */
+	if (vf->err_intr_registered)
+		otx2_ree_err_intr_unregister(dev);
+
+	/* Detach queues */
+	if (vf->nb_queues) {
+		ret = otx2_ree_queues_detach(dev);
+		if (ret) {
+			otx2_err("Could not detach REE queues");
+			return ret;
+		}
+	}
+
+	/* TEMP : should be in lib */
+	if (data->queue_pairs == NULL) { /* first time configuration */
+		data->queue_pairs = rte_zmalloc("regexdev->queue_pairs",
+				sizeof(data->queue_pairs[0]) *
+				cfg->nb_queue_pairs, RTE_CACHE_LINE_SIZE);
+
+		if (data->queue_pairs == NULL) {
+			data->nb_queue_pairs = 0;
+			otx2_err("Failed to get memory for qp meta data, nb_queues %u",
+					cfg->nb_queue_pairs);
+			return -ENOMEM;
+		}
+	} else { /* re-configure */
+		uint16_t old_nb_queues = data->nb_queue_pairs;
+		void **qp;
+		unsigned int i;
+
+		qp = data->queue_pairs;
+
+		for (i = cfg->nb_queue_pairs; i < old_nb_queues; i++) {
+			ret = ree_queue_pair_release(dev, i);
+			if (ret < 0)
+				return ret;
+		}
+
+		qp = rte_realloc(qp, sizeof(qp[0]) * cfg->nb_queue_pairs,
+				RTE_CACHE_LINE_SIZE);
+		if (qp == NULL) {
+			otx2_err("Failed to realloc qp meta data, nb_queues %u",
+					cfg->nb_queue_pairs);
+			return -ENOMEM;
+		}
+
+		if (cfg->nb_queue_pairs > old_nb_queues) {
+			uint16_t new_qs = cfg->nb_queue_pairs - old_nb_queues;
+			memset(qp + old_nb_queues, 0, sizeof(qp[0]) * new_qs);
+		}
+
+		data->queue_pairs = qp;
+	}
+	data->nb_queue_pairs = cfg->nb_queue_pairs;
+
+	/* Attach queues */
+	otx2_ree_dbg("Attach %d queues", cfg->nb_queue_pairs);
+	ret = otx2_ree_queues_attach(dev, cfg->nb_queue_pairs);
+	if (ret) {
+		otx2_err("Could not attach queues");
+		return -ENODEV;
+	}
+
+	ret = otx2_ree_msix_offsets_get(dev);
+	if (ret) {
+		otx2_err("Could not get MSI-X offsets");
+		goto queues_detach;
+	}
+
+	if (cfg->rule_db && cfg->rule_db_len) {
+		otx2_ree_dbg("rule_db length %d", cfg->rule_db_len);
+		rule_db = (const struct ree_rule_db *)cfg->rule_db;
+		rule_db_len = rule_db->number_of_entries *
+				sizeof(struct ree_rule_db_entry);
+		otx2_ree_dbg("rule_db number of entries %d",
+				rule_db->number_of_entries);
+		if (rule_db_len > cfg->rule_db_len) {
+			otx2_err("Could not program rule db");
+			ret = -EINVAL;
+			goto queues_detach;
+		}
+		ret = otx2_ree_rule_db_prog(dev, (const char *)rule_db->entries,
+				rule_db_len, NULL, OTX2_REE_NON_INC_PROG);
+		if (ret) {
+			otx2_err("Could not program rule db");
+			goto queues_detach;
+		}
+	}
+
+	dev->enqueue = otx2_ree_enqueue_burst;
+	dev->dequeue = otx2_ree_dequeue_burst;
+
+	rte_mb();
+	return 0;
+
+queues_detach:
+	otx2_ree_queues_detach(dev);
+	return ret;
+}
+
+static int
+otx2_ree_stop(struct rte_regexdev *dev)
+{
+	RTE_SET_USED(dev);
+
+	ree_func_trace();
+	return 0;
+}
+
+static int
+otx2_ree_start(struct rte_regexdev *dev)
+{
+	uint32_t rule_db_len = 0;
+	int ret;
+
+	ree_func_trace();
+
+	ret = otx2_ree_rule_db_len_get(dev, &rule_db_len, NULL);
+	if (ret)
+		return ret;
+	if (rule_db_len == 0) {
+		otx2_err("Rule db not programmed");
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+static int
+otx2_ree_close(struct rte_regexdev *dev)
+{
+	return ree_dev_fini(dev);
+}
+
+static int
+otx2_ree_queue_pair_setup(struct rte_regexdev *dev, uint16_t qp_id,
+		const struct rte_regexdev_qp_conf *qp_conf)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_qp *qp;
+
+	ree_func_trace("Queue=%d", qp_id);
+
+	if (data->queue_pairs[qp_id] != NULL)
+		ree_queue_pair_release(dev, qp_id);
+
+	if (qp_conf->nb_desc > OTX2_REE_DEFAULT_CMD_QLEN) {
+		otx2_err("Could not setup queue pair for %u descriptors",
+				qp_conf->nb_desc);
+		return -EINVAL;
+	}
+	if (qp_conf->qp_conf_flags != 0) {
+		otx2_err("Could not setup queue pair with configuration flags 0x%x",
+				qp_conf->qp_conf_flags);
+		return -EINVAL;
+	}
+
+	qp = ree_qp_create(dev, qp_id);
+	if (qp == NULL) {
+		otx2_err("Could not create queue pair %d", qp_id);
+		return -ENOMEM;
+	}
+	qp->cb = qp_conf->cb;
+	data->queue_pairs[qp_id] = qp;
+
+	return 0;
+}
+
+static int
+otx2_ree_rule_db_compile_activate(struct rte_regexdev *dev)
+{
+	return otx2_ree_rule_db_compile_prog(dev);
+}
+
+static int
+otx2_ree_rule_db_update(struct rte_regexdev *dev,
+		const struct rte_regexdev_rule *rules, uint16_t nb_rules)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct rte_regexdev_rule *old_ptr;
+	uint32_t i, sum_nb_rules;
+
+	ree_func_trace("nb_rules=%d", nb_rules);
+
+	for (i = 0; i < nb_rules; i++) {
+		if (rules[i].op == RTE_REGEX_RULE_OP_REMOVE)
+			break;
+		if (rules[i].group_id >= data->max_groups)
+			break;
+		if (rules[i].rule_id >= data->max_rules_per_group)
+			break;
+		/* logical implication
+		 * p    q    p -> q
+		 * 0    0      1
+		 * 0    1      1
+		 * 1    0      0
+		 * 1    1      1
+		 */
+		if ((~(rules[i].rule_flags) | data->rule_flags) == 0)
+			break;
+	}
+	nb_rules = i;
+
+	if (data->nb_rules == 0) {
+
+		data->rules = rte_malloc("rte_regexdev_rules",
+				nb_rules*sizeof(struct rte_regexdev_rule), 0);
+		if (data->rules == NULL)
+			return -ENOMEM;
+
+		memcpy(data->rules, rules,
+				nb_rules*sizeof(struct rte_regexdev_rule));
+		data->nb_rules = nb_rules;
+	} else {
+
+		old_ptr = data->rules;
+		sum_nb_rules = data->nb_rules + nb_rules;
+		data->rules = rte_realloc(data->rules,
+				sum_nb_rules * sizeof(struct rte_regexdev_rule),
+							0);
+		if (data->rules == NULL) {
+			data->rules = old_ptr;
+			return -ENOMEM;
+		}
+		memcpy(&data->rules[data->nb_rules], rules,
+				nb_rules*sizeof(struct rte_regexdev_rule));
+		data->nb_rules = sum_nb_rules;
+	}
+	return nb_rules;
+}
+
+static int
+otx2_ree_rule_db_import(struct rte_regexdev *dev, const char *rule_db,
+		uint32_t rule_db_len)
+{
+
+	const struct ree_rule_db *ree_rule_db;
+	uint32_t ree_rule_db_len;
+	int ret;
+
+	ree_func_trace("rule_db_len=%d", rule_db_len);
+
+	ree_rule_db = (const struct ree_rule_db *)rule_db;
+	ree_rule_db_len = ree_rule_db->number_of_entries *
+			sizeof(struct ree_rule_db_entry);
+	if (ree_rule_db_len > rule_db_len) {
+		otx2_err("Could not program rule db");
+		return -EINVAL;
+	}
+	ret = otx2_ree_rule_db_prog(dev, (const char *)ree_rule_db->entries,
+			ree_rule_db_len, NULL, OTX2_REE_NON_INC_PROG);
+	if (ret) {
+		otx2_err("Could not program rule db");
+		return -ENOSPC;
+	}
+	return 0;
+}
+
+static int
+otx2_ree_rule_db_export(struct rte_regexdev *dev, char *rule_db)
+{
+	struct ree_rule_db *ree_rule_db;
+	uint32_t rule_dbi_len;
+	uint32_t rule_db_len;
+	int ret;
+
+	ree_func_trace();
+
+	ret = otx2_ree_rule_db_len_get(dev, &rule_db_len, &rule_dbi_len);
+	if (ret)
+		return ret;
+
+	if (rule_db == NULL) {
+		rule_db_len += sizeof(struct ree_rule_db);
+		return rule_db_len;
+	}
+
+	ree_rule_db = (struct ree_rule_db *)rule_db;
+	ret = otx2_ree_rule_db_get(dev, (char *)ree_rule_db->entries,
+			rule_db_len, NULL, 0);
+	if (ret) {
+		otx2_err("Could not export rule db");
+		return -EFAULT;
+	}
+	ree_rule_db->number_of_entries =
+			rule_db_len/sizeof(struct ree_rule_db_entry);
+	ree_rule_db->revision = REE_RULE_DB_REVISION;
+	ree_rule_db->version = REE_RULE_DB_VERSION;
+
+	return 0;
+}
+
+static int
+ree_get_blkaddr(struct otx2_dev *dev)
+{
+	int pf;
+
+	pf = otx2_get_pf(dev->pf_func);
+	if (pf == REE0_PF)
+		return RVU_BLOCK_ADDR_REE0;
+	else if (pf == REE1_PF)
+		return RVU_BLOCK_ADDR_REE1;
+	else
+		return 0;
+}
+
+static struct rte_regexdev_ops otx2_ree_ops = {
+		.dev_info_get = otx2_ree_dev_info_get,
+		.dev_configure = otx2_ree_dev_config,
+		.dev_qp_setup = otx2_ree_queue_pair_setup,
+		.dev_start = otx2_ree_start,
+		.dev_stop = otx2_ree_stop,
+		.dev_close = otx2_ree_close,
+		.dev_attr_get = NULL,
+		.dev_attr_set = NULL,
+		.dev_rule_db_update = otx2_ree_rule_db_update,
+		.dev_rule_db_compile_activate =
+				otx2_ree_rule_db_compile_activate,
+		.dev_db_import = otx2_ree_rule_db_import,
+		.dev_db_export = otx2_ree_rule_db_export,
+		.dev_xstats_names_get = NULL,
+		.dev_xstats_get = NULL,
+		.dev_xstats_by_name_get = NULL,
+		.dev_xstats_reset = NULL,
+		.dev_selftest = NULL,
+		.dev_dump = NULL,
+};
+
+static int
+otx2_ree_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
+		   struct rte_pci_device *pci_dev)
+{
+	char name[RTE_REGEXDEV_NAME_MAX_LEN];
+	struct otx2_ree_data *data;
+	struct otx2_dev *otx2_dev;
+	struct rte_regexdev *dev;
+	uint8_t max_matches = 0;
+	struct otx2_ree_vf *vf;
+	uint16_t nb_queues = 0;
+	int ret;
+
+	rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
+
+	dev = ree_dev_register(name);
+	if (dev == NULL) {
+		ret = -ENODEV;
+		goto exit;
+	}
+
+	dev->dev_ops = &otx2_ree_ops;
+	dev->device = &pci_dev->device;
+
+	/* Get private data space allocated */
+	data = dev->data->dev_private;
+	vf = &data->vf;
+
+	otx2_dev = &vf->otx2_dev;
+
+	/* Initialize the base otx2_dev object */
+	ret = otx2_dev_init(pci_dev, otx2_dev);
+	if (ret) {
+		otx2_err("Could not initialize otx2_dev");
+		goto dev_unregister;
+	}
+	/* Get REE block address */
+	vf->block_address = ree_get_blkaddr(otx2_dev);
+	if (!vf->block_address) {
+		otx2_err("Could not determine block PF number");
+		goto otx2_dev_fini;
+	}
+
+	/* Get number of queues available on the device */
+	ret = otx2_ree_available_queues_get(dev, &nb_queues);
+	if (ret) {
+		otx2_err("Could not determine the number of queues available");
+		goto otx2_dev_fini;
+	}
+
+	/* Don't exceed the limits set per VF */
+	nb_queues = RTE_MIN(nb_queues, OTX2_REE_MAX_QUEUES_PER_VF);
+
+	if (nb_queues == 0) {
+		otx2_err("No free queues available on the device");
+		goto otx2_dev_fini;
+	}
+
+	vf->max_queues = nb_queues;
+
+	otx2_ree_dbg("Max queues supported by device: %d", vf->max_queues);
+
+	/* Get number of maximum matches supported on the device */
+	ret = otx2_ree_max_matches_get(dev, &max_matches);
+	if (ret) {
+		otx2_err("Could not determine the maximum matches supported");
+		goto otx2_dev_fini;
+	}
+	/* Don't exceed the limits set per VF */
+	max_matches = RTE_MIN(max_matches, OTX2_REE_MAX_MATCHES_PER_VF);
+	if (max_matches == 0) {
+		otx2_err("Could not determine the maximum matches supported");
+		goto otx2_dev_fini;
+	}
+
+	vf->max_matches = max_matches;
+
+	otx2_ree_dbg("Max matches supported by device: %d", vf->max_matches);
+	data->rule_flags = RTE_REGEX_PCRE_RULE_ALLOW_EMPTY_F |
+			RTE_REGEX_PCRE_RULE_ANCHORED_F;
+	data->regexdev_capa = 0;
+	data->max_groups = REE_MAX_GROUPS;
+	data->max_rules_per_group = REE_MAX_RULES_PER_GROUP;
+	data->nb_rules = 0;
+
+	dev->state = RTE_REGEXDEV_READY;
+	return 0;
+
+otx2_dev_fini:
+	otx2_dev_fini(pci_dev, otx2_dev);
+dev_unregister:
+	ree_dev_unregister(dev);
+exit:
+	otx2_err("Could not create device (vendor_id: 0x%x device_id: 0x%x)",
+		    pci_dev->id.vendor_id, pci_dev->id.device_id);
+	return ret;
+}
+
+static int
+otx2_ree_pci_remove(struct rte_pci_device *pci_dev)
+{
+	char name[RTE_REGEXDEV_NAME_MAX_LEN];
+	struct rte_regexdev *dev = NULL;
+
+	if (pci_dev == NULL)
+		return -EINVAL;
+
+	rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
+
+	dev = rte_regexdev_get_device_by_name(name);
+
+	if (dev == NULL)
+		return -ENODEV;
+
+	return ree_dev_fini(dev);
+}
+
+static struct rte_pci_id pci_id_ree_table[] = {
+	{
+		RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM,
+				PCI_DEVID_OCTEONTX2_RVU_REE_PF)
+	},
+};
+
+static struct rte_pci_driver otx2_regexdev_pmd = {
+	.id_table = pci_id_ree_table,
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING,
+	.probe = otx2_ree_pci_probe,
+	.remove = otx2_ree_pci_remove,
+};
+
+
+RTE_PMD_REGISTER_PCI(REGEXDEV_NAME_OCTEONTX2_PMD, otx2_regexdev_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(REGEXDEV_NAME_OCTEONTX2_PMD, pci_id_ree_table);
diff --git a/drivers/regex/octeontx2/otx2_regexdev.h b/drivers/regex/octeontx2/otx2_regexdev.h
new file mode 100644
index 000000000..d710535f5
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev.h
@@ -0,0 +1,109 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _OTX2_REGEXDEV_H_
+#define _OTX2_REGEXDEV_H_
+
+#include <rte_common.h>
+#include <rte_regexdev.h>
+
+#include "otx2_dev.h"
+
+#define ree_func_trace otx2_ree_dbg
+
+/* Marvell OCTEON TX2 Regex PMD device name */
+#define REGEXDEV_NAME_OCTEONTX2_PMD	regex_octeontx2
+
+#define OTX2_REE_MAX_LFS		36
+#define OTX2_REE_MAX_QUEUES_PER_VF	36
+#define OTX2_REE_MAX_MATCHES_PER_VF	254
+
+#define OTX2_REE_MAX_PAYLOAD_SIZE	(1 << 14)
+
+#define OTX2_REE_NON_INC_PROG 0
+#define OTX2_REE_INC_PROG 1
+
+#define REE_MOD_INC(i, l)   ((i) == (l - 1) ? (i) = 0 : (i)++)
+
+
+/**
+ * Device vf data
+ */
+struct otx2_ree_vf {
+	struct otx2_dev otx2_dev;
+	/**< Base class */
+	uint16_t max_queues;
+	/**< Max queues supported */
+	uint8_t nb_queues;
+	/**< Number of regex queues attached */
+	uint16_t max_matches;
+	/**<  Max matches supported*/
+	uint16_t lf_msixoff[OTX2_REE_MAX_LFS];
+	/**< MSI-X offsets */
+	uint8_t block_address;
+	/**< REE Block Address */
+	uint8_t err_intr_registered:1;
+	/**< Are error interrupts registered? */
+};
+
+/**
+ * Device private data
+ */
+struct otx2_ree_data {
+	uint32_t regexdev_capa;
+	uint64_t rule_flags;
+	/**< Feature flags exposes HW/SW features for the given device */
+	uint16_t max_rules_per_group;
+	/**< Maximum rules supported per subset by this device */
+	uint16_t max_groups;
+	/**< Maximum subset supported by this device */
+	void **queue_pairs;
+	/**< Array of pointers to queue pairs. */
+	uint16_t nb_queue_pairs;
+	/**< Number of device queue pairs. */
+	struct otx2_ree_vf vf;
+	/**< vf data */
+	struct rte_regexdev_rule *rules;
+	/**< rules to be compiled */
+	uint16_t nb_rules;
+	/**< number of rules */
+} __rte_cache_aligned;
+
+struct otx2_ree_rid {
+	uintptr_t rid;
+	/** Request id of a ree operation */
+	uint64_t user_id;
+	/* Client data */
+	/**< IOVA address of the pattern to be matched. */
+};
+
+struct otx2_ree_pending_queue {
+	uint64_t pending_count;
+	/** Pending requests count */
+	struct otx2_ree_rid *rid_queue;
+	/** Array of pending requests */
+	uint16_t enq_tail;
+	/** Tail of queue to be used for enqueue */
+	uint16_t deq_head;
+	/** Head of queue to be used for dequeue */
+};
+
+struct otx2_ree_qp {
+	uint32_t id;
+	/**< Queue pair id */
+	uintptr_t base;
+	/**< Base address where BAR is mapped */
+	struct otx2_ree_pending_queue pend_q;
+	/**< Pending queue */
+	rte_iova_t iq_dma_addr;
+	/**< Instruction queue address */
+	uint32_t otx2_regexdev_jobid;
+	/**< Job ID */
+	uint32_t write_offset;
+	/**< write offset */
+	regexdev_stop_flush_t cb;
+	/**< Callback function called during rte_regex_dev_stop()*/
+};
+
+#endif /* _OTX2_REGEXDEV_H_ */
diff --git a/drivers/regex/octeontx2/otx2_regexdev_compiler.c b/drivers/regex/octeontx2/otx2_regexdev_compiler.c
new file mode 100644
index 000000000..785459f74
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev_compiler.c
@@ -0,0 +1,229 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#include <rte_malloc.h>
+#include <rte_regexdev.h>
+
+#include "otx2_regexdev.h"
+#include "otx2_regexdev_compiler.h"
+#include "otx2_regexdev_mbox.h"
+
+#ifdef REE_COMPILER_SDK
+#include <rxp-compiler.h>
+
+static int
+ree_rule_db_compile(const struct rte_regexdev_rule *rules,
+		uint16_t nb_rules, struct rxp_rof **rof, struct rxp_rof **rofi,
+		struct rxp_rof *rof_for_incremental_compile,
+		struct rxp_rof *rofi_for_incremental_compile)
+{
+	/*INPUT*/
+	struct rxp_prefix_selection_control_list *prefix_selection_control_list
+		= NULL;
+	struct rxp_blacklist_data_sample *blacklist_sample_data = NULL;
+	struct rxp_rule_ids_to_remove *rule_ids_to_remove = NULL;
+	struct rxp_roff *roff_for_incremental_compile = NULL;
+
+	/*OPTIONS - setting default values*/
+	enum rxp_virtual_prefix_mode virtual_prefix_mode =
+			RXP_VIRTUAL_PREFIX_MODE_0;
+	enum rxp_prefix_capacity prefix_capacity = RXP_PREFIX_CAPACITY_32K;
+	/**< rxp_global_regex_options_flags*/
+	enum rxp_compiler_objective objective = RXP_COMPILER_OBJECTIVE_5;
+	enum rxp_tpe_data_width tpe_data_width = RXP_TPE_DATA_WIDTH_4;
+	uint32_t compiler_options = RXP_COMPILER_OPTIONS_FORCE;
+	/**< rxp_compiler_options_flags*/
+	enum rxp_verbose_level verbose = RXP_VERBOSE_LEVEL_3;
+	enum rxp_version set_rxp_version = RXP_VERSION_V5_8;
+	uint32_t compiler_output_flags = 0;
+	/**< rxp_compiler_output_flags*/
+	uint32_t global_regex_options = 0;
+	/**< rxp_global_regex_options_flags*/
+	float set_auto_blacklist = 0;
+	uint32_t max_rep_max = 65535;
+	uint32_t divide_ruleset = 1;
+	struct rxp_ruleset ruleset;
+	float ptpb_threshold = 0;
+	uint32_t set_max = 0;
+	uint32_t threads = 1;
+
+	/*OUTPUT*/
+	struct rxp_rule_direction_analysis *rule_direction_analysis = NULL;
+	struct rxp_compilation_statistics *compilation_statistics = NULL;
+	struct rxp_prefix_selection_control_list *generated_pscl = NULL;
+	struct rxp_uncompiled_rules_log *uncompiled_rules_log = NULL;
+	struct rxp_critical_rules_rank *critical_rules_rank = NULL;
+	struct rxp_compiled_rules_log *compiled_rules_log = NULL;
+	struct rxp_roff *roff = NULL;
+
+	uint16_t i;
+	int ret;
+
+	ruleset.number_of_entries = nb_rules;
+	ruleset.rules = rte_malloc("rxp_rule_entry",
+			nb_rules*sizeof(struct rxp_rule_entry), 0);
+
+	if (ruleset.rules == NULL) {
+		otx2_err("Could not allocate memory for rule compilation\n");
+		return -EFAULT;
+	}
+	if (rof_for_incremental_compile)
+		compiler_options |= RXP_COMPILER_OPTIONS_INCREMENTAL;
+	if (rofi_for_incremental_compile)
+		compiler_options |= RXP_COMPILER_OPTIONS_CHECKSUM;
+
+	for (i = 0; i < nb_rules; i++) {
+		ruleset.rules[i].number_of_prefix_entries = 0;
+		ruleset.rules[i].prefix = NULL;
+		ruleset.rules[i].rule = rules[i].pcre_rule;
+		ruleset.rules[i].rule_id = rules[i].rule_id;
+		ruleset.rules[i].subset_id = rules[i].group_id;
+		ruleset.rules[i].rule_direction_type =
+				RXP_RULE_DIRECTION_TYPE_NONE;
+	}
+
+	ret = rxp_compile_advanced(
+			/*INPUT*/
+			&ruleset,
+			prefix_selection_control_list,
+			rof_for_incremental_compile,
+			roff_for_incremental_compile,
+			rofi_for_incremental_compile,
+			rule_ids_to_remove,
+			blacklist_sample_data,
+
+			/*OPTIONS*/
+			compiler_options,
+			prefix_capacity,
+			global_regex_options,
+			set_auto_blacklist,
+			set_max,
+			objective,
+			ptpb_threshold,
+			max_rep_max,
+			threads,
+			set_rxp_version,
+			verbose,
+			tpe_data_width,
+			virtual_prefix_mode,
+			compiler_output_flags,
+			divide_ruleset,
+
+			/*OUTPUT*/
+			&compilation_statistics,
+			&compiled_rules_log,
+			&critical_rules_rank,
+			&rule_direction_analysis,
+			&uncompiled_rules_log,
+			rof,
+			&roff,
+			rofi,
+			&generated_pscl);
+	rte_free(ruleset.rules);
+
+	return ret;
+}
+
+int
+otx2_ree_rule_db_compile_prog(struct rte_regexdev *dev)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	char compiler_version[] = "20.5.2.eda0fa2";
+	char timestamp[] = "19700101_000001";
+	uint32_t rule_db_len, rule_dbi_len;
+	struct rxp_rof *rofi_inc_p = NULL;
+	struct rxp_rof_entry rule_dbi[6];
+	char *rofi_rof_entries = NULL;
+	struct rxp_rof *rofi = NULL;
+	struct rxp_rof *rof = NULL;
+	struct rxp_rof rofi_inc;
+	struct rxp_rof rof_inc;
+	char *rule_db = NULL;
+	int ret;
+
+	ree_func_trace();
+
+	ret = otx2_ree_rule_db_len_get(dev, &rule_db_len, &rule_dbi_len);
+	if (ret != 0) {
+		otx2_err("Could not get rule db length");
+		return ret;
+	}
+
+	if (rule_db_len > 0) {
+		otx2_ree_dbg("Incremental compile, rule db len %d rule dbi len %d",
+				rule_db_len, rule_dbi_len);
+		rule_db = rte_malloc("ree_rule_db", rule_db_len, 0);
+		if (!rule_db) {
+			otx2_err("Could not allocate memory for rule db");
+			return -EFAULT;
+		}
+
+		ret = otx2_ree_rule_db_get(dev, rule_db, rule_db_len,
+				(char *)rule_dbi, rule_dbi_len);
+		if (ret) {
+			otx2_err("Could not read rule db");
+			rte_free(rule_db);
+			return -EFAULT;
+		}
+		rof_inc.rof_revision = 0;
+		rof_inc.rof_version = 2;
+		rof_inc.rof_entries = (struct rxp_rof_entry *)rule_db;
+		rof_inc.rxp_compiler_version = compiler_version;
+		rof_inc.timestamp = timestamp;
+		rof_inc.number_of_entries =
+				(rule_db_len/sizeof(struct rxp_rof_entry));
+
+		if (rule_dbi_len > 0) {
+			/* incremental compilation not the first time */
+			rofi_inc.rof_revision = 0;
+			rofi_inc.rof_version = 2;
+			rofi_inc.rof_entries = rule_dbi;
+			rofi_inc.rxp_compiler_version = compiler_version;
+			rofi_inc.timestamp = timestamp;
+			rofi_inc.number_of_entries =
+				(rule_dbi_len/sizeof(struct rxp_rof_entry));
+			rofi_inc_p = &rofi_inc;
+		}
+		ret = ree_rule_db_compile(data->rules, data->nb_rules, &rof,
+				&rofi, &rof_inc, rofi_inc_p);
+		if (rofi->number_of_entries == 0) {
+			otx2_ree_dbg("No change to rule db");
+			ret = 0;
+			goto free_structs;
+		}
+		rule_dbi_len = rofi->number_of_entries *
+				sizeof(struct rxp_rof_entry);
+		rofi_rof_entries = (char *)rofi->rof_entries;
+	} else {
+		/* full compilation */
+		ret = ree_rule_db_compile(data->rules, data->nb_rules, &rof,
+				&rofi, NULL, NULL);
+	}
+	if (ret != 0) {
+		otx2_err("Could not compile rule db");
+		goto free_structs;
+	}
+	rule_db_len = rof->number_of_entries * sizeof(struct rxp_rof_entry);
+	ret = otx2_ree_rule_db_prog(dev, (char *)rof->rof_entries, rule_db_len,
+			rofi_rof_entries, rule_dbi_len);
+	if (ret)
+		otx2_err("Could not program rule db");
+
+free_structs:
+	rxp_free_structs(NULL, NULL, NULL, NULL, NULL, &rof, NULL, &rofi, NULL,
+			1);
+
+	if (rule_db)
+		rte_free(rule_db);
+
+	return ret;
+}
+#else
+int
+otx2_ree_rule_db_compile_prog(struct rte_regexdev *dev)
+{
+	RTE_SET_USED(dev);
+	return -ENOTSUP;
+}
+#endif
diff --git a/drivers/regex/octeontx2/otx2_regexdev_compiler.h b/drivers/regex/octeontx2/otx2_regexdev_compiler.h
new file mode 100644
index 000000000..8d2625bf7
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev_compiler.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _OTX2_REGEXDEV_COMPILER_H_
+#define _OTX2_REGEXDEV_COMPILER_H_
+
+int
+otx2_ree_rule_db_compile_prog(struct rte_regexdev *dev);
+
+#endif /* _OTX2_REGEXDEV_COMPILER_H_ */
diff --git a/drivers/regex/octeontx2/otx2_regexdev_hw_access.c b/drivers/regex/octeontx2/otx2_regexdev_hw_access.c
new file mode 100644
index 000000000..620d5c912
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev_hw_access.c
@@ -0,0 +1,167 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#include "otx2_common.h"
+#include "otx2_dev.h"
+#include "otx2_regexdev_hw_access.h"
+#include "otx2_regexdev_mbox.h"
+
+static void
+ree_lf_err_intr_handler(void *param)
+{
+	uintptr_t base = (uintptr_t)param;
+	uint8_t lf_id;
+	uint64_t intr;
+
+	lf_id = (base >> 12) & 0xFF;
+
+	intr = otx2_read64(base + OTX2_REE_LF_MISC_INT);
+	if (intr == 0)
+		return;
+
+	otx2_ree_dbg("LF %d MISC_INT: 0x%" PRIx64 "", lf_id, intr);
+
+	/* Clear interrupt */
+	otx2_write64(intr, base + OTX2_REE_LF_MISC_INT);
+}
+
+static void
+ree_lf_err_intr_unregister(const struct rte_regexdev *dev, uint16_t msix_off,
+			   uintptr_t base)
+{
+	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
+	struct rte_intr_handle *handle = &pci_dev->intr_handle;
+
+	/* Disable error interrupts */
+	otx2_write64(~0ull, base + OTX2_REE_LF_MISC_INT_ENA_W1C);
+
+	otx2_unregister_irq(handle, ree_lf_err_intr_handler, (void *)base,
+			    msix_off);
+}
+
+void
+otx2_ree_err_intr_unregister(const struct rte_regexdev *dev)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	uintptr_t base;
+	uint32_t i;
+
+	for (i = 0; i < vf->nb_queues; i++) {
+		base = OTX2_REE_LF_BAR2(vf, i);
+		ree_lf_err_intr_unregister(dev, vf->lf_msixoff[i], base);
+	}
+
+	vf->err_intr_registered = 0;
+}
+
+static int
+ree_lf_err_intr_register(const struct rte_regexdev *dev, uint16_t msix_off,
+			 uintptr_t base)
+{
+	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
+	struct rte_intr_handle *handle = &pci_dev->intr_handle;
+	int ret;
+
+	/* Disable error interrupts */
+	otx2_write64(~0ull, base + OTX2_REE_LF_MISC_INT_ENA_W1C);
+
+	/* Register error interrupt handler */
+	ret = otx2_register_irq(handle, ree_lf_err_intr_handler, (void *)base,
+				msix_off);
+	if (ret)
+		return ret;
+
+	/* Enable error interrupts */
+	otx2_write64(~0ull, base + OTX2_REE_LF_MISC_INT_ENA_W1S);
+
+	return 0;
+}
+
+int
+otx2_ree_err_intr_register(const struct rte_regexdev *dev)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	uint32_t i, j, ret;
+	uintptr_t base;
+
+	for (i = 0; i < vf->nb_queues; i++) {
+		if (vf->lf_msixoff[i] == MSIX_VECTOR_INVALID) {
+			otx2_err("Invalid REE LF MSI-X offset: 0x%x",
+				    vf->lf_msixoff[i]);
+			return -EINVAL;
+		}
+	}
+
+	for (i = 0; i < vf->nb_queues; i++) {
+		base = OTX2_REE_LF_BAR2(vf, i);
+		ret = ree_lf_err_intr_register(dev, vf->lf_msixoff[i], base);
+		if (ret)
+			goto intr_unregister;
+	}
+
+	vf->err_intr_registered = 1;
+	return 0;
+
+intr_unregister:
+	/* Unregister the ones already registered */
+	for (j = 0; j < i; j++) {
+		base = OTX2_REE_LF_BAR2(vf, j);
+		ree_lf_err_intr_unregister(dev, vf->lf_msixoff[j], base);
+	}
+	return ret;
+}
+
+int
+otx2_ree_iq_enable(const struct rte_regexdev *dev, const struct otx2_ree_qp *qp,
+		   uint8_t pri, uint32_t size_div2)
+{
+	union otx2_ree_lf_sbuf_addr base;
+	union otx2_ree_lf_ena lf_ena;
+
+	/* Set instruction queue size and priority */
+	otx2_ree_config_lf(dev, qp->id, pri, size_div2);
+
+	/* Set instruction queue base address */
+	/* Should be written after SBUF_CTL and before LF_ENA */
+
+	base.u = otx2_read64(qp->base + OTX2_REE_LF_SBUF_ADDR);
+	base.s.ptr = qp->iq_dma_addr >> 7;
+	otx2_write64(base.u, qp->base + OTX2_REE_LF_SBUF_ADDR);
+
+	/* Enable instruction queue */
+
+	lf_ena.u = otx2_read64(qp->base + OTX2_REE_LF_ENA);
+	lf_ena.s.ena = 1;
+	otx2_write64(lf_ena.u, qp->base + OTX2_REE_LF_ENA);
+
+	return 0;
+}
+
+void
+otx2_ree_iq_disable(struct otx2_ree_qp *qp)
+{
+	union otx2_ree_lf_ena lf_ena;
+
+	/* Stop instruction execution */
+	lf_ena.u = otx2_read64(qp->base + OTX2_REE_LF_ENA);
+	lf_ena.s.ena = 0x0;
+	otx2_write64(lf_ena.u, qp->base + OTX2_REE_LF_ENA);
+}
+
+int
+otx2_ree_max_matches_get(const struct rte_regexdev *dev, uint8_t *max_matches)
+{
+	union otx2_ree_af_reexm_max_match reexm_max_match;
+	int ret;
+
+	ret = otx2_ree_af_reg_read(dev, REE_AF_REEXM_MAX_MATCH,
+				   &reexm_max_match.u);
+	if (ret)
+		return ret;
+
+	*max_matches = reexm_max_match.s.max;
+	return 0;
+}
diff --git a/drivers/regex/octeontx2/otx2_regexdev_hw_access.h b/drivers/regex/octeontx2/otx2_regexdev_hw_access.h
new file mode 100644
index 000000000..dedf5f328
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev_hw_access.h
@@ -0,0 +1,202 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _OTX2_REGEXDEV_HW_ACCESS_H_
+#define _OTX2_REGEXDEV_HW_ACCESS_H_
+
+#include <stdint.h>
+
+#include "otx2_regexdev.h"
+
+/* REE instruction queue length */
+#define OTX2_REE_IQ_LEN			(1 << 13)
+
+#define OTX2_REE_DEFAULT_CMD_QLEN	OTX2_REE_IQ_LEN
+
+/* Status register bits */
+#define OTX2_REE_STATUS_PMI_EOJ_BIT		(1 << 14)
+#define OTX2_REE_STATUS_PMI_SOJ_BIT		(1 << 13)
+#define OTX2_REE_STATUS_MP_CNT_DET_BIT		(1 << 7)
+#define OTX2_REE_STATUS_MM_CNT_DET_BIT		(1 << 6)
+#define OTX2_REE_STATUS_ML_CNT_DET_BIT		(1 << 5)
+#define OTX2_REE_STATUS_MST_CNT_DET_BIT		(1 << 4)
+#define OTX2_REE_STATUS_MPT_CNT_DET_BIT		(1 << 3)
+
+/* Register offsets */
+/* REE LF registers */
+#define OTX2_REE_LF_DONE_INT		0x120ull
+#define OTX2_REE_LF_DONE_INT_W1S	0x130ull
+#define OTX2_REE_LF_DONE_INT_ENA_W1S	0x138ull
+#define OTX2_REE_LF_DONE_INT_ENA_W1C	0x140ull
+#define OTX2_REE_LF_MISC_INT		0x300ull
+#define OTX2_REE_LF_MISC_INT_W1S	0x310ull
+#define OTX2_REE_LF_MISC_INT_ENA_W1S	0x320ull
+#define OTX2_REE_LF_MISC_INT_ENA_W1C	0x330ull
+#define OTX2_REE_LF_ENA			0x10ull
+#define OTX2_REE_LF_SBUF_ADDR		0x20ull
+#define OTX2_REE_LF_DONE		0x100ull
+#define OTX2_REE_LF_DONE_ACK		0x110ull
+#define OTX2_REE_LF_DONE_WAIT		0x148ull
+#define OTX2_REE_LF_DOORBELL		0x400ull
+#define OTX2_REE_LF_OUTSTAND_JOB	0x410ull
+
+/* BAR 0 */
+#define OTX2_REE_AF_QUE_SBUF_CTL(a)	(0x1200ull | (uint64_t)(a) << 3)
+#define OTX2_REE_PRIV_LF_CFG(a)		(0x41000ull | (uint64_t)(a) << 3)
+
+#define OTX2_REE_LF_BAR2(vf, q_id) \
+		((vf)->otx2_dev.bar2 + \
+		 (((vf)->block_address << 20) | ((q_id) << 12)))
+
+
+#define OTX2_REE_QUEUE_HI_PRIO 0x1
+
+enum ree_desc_type_e {
+	REE_TYPE_JOB_DESC    = 0x0,
+	REE_TYPE_RESULT_DESC = 0x1,
+	REE_TYPE_ENUM_LAST   = 0x2
+};
+
+union otx2_ree_priv_lf_cfg {
+	uint64_t u;
+	struct {
+		uint64_t slot                        : 8;
+		uint64_t pf_func                     : 16;
+		uint64_t reserved_24_62              : 39;
+		uint64_t ena                         : 1;
+	} s;
+};
+
+
+union otx2_ree_lf_sbuf_addr {
+	uint64_t u;
+	struct {
+		uint64_t off                         : 7;
+		uint64_t ptr                         : 46;
+		uint64_t reserved_53_63              : 11;
+	} s;
+};
+
+union otx2_ree_lf_ena {
+	uint64_t u;
+	struct {
+		uint64_t ena                         : 1;
+		uint64_t reserved_1_63               : 63;
+	} s;
+};
+
+union otx2_ree_af_reexm_max_match {
+	uint64_t u;
+	struct {
+		uint64_t max                         : 8;
+		uint64_t reserved_8_63               : 56;
+	} s;
+};
+
+union otx2_ree_lf_done {
+	uint64_t u;
+	struct {
+		uint64_t done                        : 20;
+		uint64_t reserved_20_63              : 44;
+	} s;
+};
+
+union otx2_ree_inst {
+	uint64_t u[8];
+	struct  {
+		uint64_t doneint                     :  1;
+		uint64_t reserved_1_3                :  3;
+		uint64_t dg                          :  1;
+		uint64_t reserved_5_7                :  3;
+		uint64_t ooj                         :  1;
+		uint64_t reserved_9_15               :  7;
+		uint64_t reserved_16_63              : 48;
+		uint64_t inp_ptr_addr                : 64;
+		uint64_t inp_ptr_ctl                 : 64;
+		uint64_t res_ptr_addr                : 64;
+		uint64_t wq_ptr                      : 64;
+		uint64_t tag                         : 32;
+		uint64_t tt                          :  2;
+		uint64_t ggrp                        : 10;
+		uint64_t reserved_364_383            : 20;
+		uint64_t reserved_384_391            :  8;
+		uint64_t ree_job_id                  : 24;
+		uint64_t ree_job_ctrl                : 16;
+		uint64_t ree_job_length              : 15;
+		uint64_t reserved_447_447            :  1;
+		uint64_t ree_job_subset_id_0         : 16;
+		uint64_t ree_job_subset_id_1         : 16;
+		uint64_t ree_job_subset_id_2         : 16;
+		uint64_t ree_job_subset_id_3         : 16;
+	} cn98xx;
+};
+
+union otx2_ree_res_status {
+	uint64_t u;
+	struct {
+		uint64_t job_type                    :  3;
+		uint64_t mpt_cnt_det                 :  1;
+		uint64_t mst_cnt_det                 :  1;
+		uint64_t ml_cnt_det                  :  1;
+		uint64_t mm_cnt_det                  :  1;
+		uint64_t mp_cnt_det                  :  1;
+		uint64_t mode                        :  2;
+		uint64_t reserved_10_11              :  2;
+		uint64_t reserved_12_12              :  1;
+		uint64_t pmi_soj                     :  1;
+		uint64_t pmi_eoj                     :  1;
+		uint64_t reserved_15_15              :  1;
+		uint64_t reserved_16_63              : 48;
+	} s;
+};
+
+union otx2_ree_res {
+	uint64_t u[8];
+	struct ree_res_s_98 {
+		uint64_t done			:  1;
+		uint64_t hwjid			:  7;
+		uint64_t ree_res_job_id		: 24;
+		uint64_t ree_res_status		: 16;
+		uint64_t ree_res_dmcnt		:  8;
+		uint64_t ree_res_mcnt		:  8;
+		uint64_t ree_meta_ptcnt		: 16;
+		uint64_t ree_meta_icnt		: 16;
+		uint64_t ree_meta_lcnt		: 16;
+		uint64_t ree_pmi_min_byte_ptr	: 16;
+		uint64_t ree_err		:  1;
+		uint64_t reserved_129_190	: 62;
+		uint64_t doneint		:  1;
+		uint64_t reserved_192_255	: 64;
+		uint64_t reserved_256_319	: 64;
+		uint64_t reserved_320_383	: 64;
+		uint64_t reserved_384_447	: 64;
+		uint64_t reserved_448_511	: 64;
+	} s;
+};
+
+union otx2_ree_match {
+	uint64_t u;
+	struct {
+		uint64_t ree_rule_id                 : 32;
+		uint64_t start_ptr                   : 14;
+		uint64_t reserved_46_47              :  2;
+		uint64_t match_length                : 15;
+		uint64_t reserved_63_63              :  1;
+	} s;
+};
+
+void otx2_ree_err_intr_unregister(const struct rte_regexdev *dev);
+
+int otx2_ree_err_intr_register(const struct rte_regexdev *dev);
+
+int otx2_ree_iq_enable(const struct rte_regexdev *dev,
+		       const struct otx2_ree_qp *qp,
+		       uint8_t pri, uint32_t size_div128);
+
+void otx2_ree_iq_disable(struct otx2_ree_qp *qp);
+
+int otx2_ree_max_matches_get(const struct rte_regexdev *dev,
+			     uint8_t *max_matches);
+
+#endif /* _OTX2_REGEXDEV_HW_ACCESS_H_ */
diff --git a/drivers/regex/octeontx2/otx2_regexdev_mbox.c b/drivers/regex/octeontx2/otx2_regexdev_mbox.c
new file mode 100644
index 000000000..6d58d367d
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev_mbox.c
@@ -0,0 +1,401 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#include "otx2_common.h"
+#include "otx2_dev.h"
+#include "otx2_regexdev_mbox.h"
+#include "otx2_regexdev.h"
+
+int
+otx2_ree_available_queues_get(const struct rte_regexdev *dev,
+			      uint16_t *nb_queues)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct free_rsrcs_rsp *rsp;
+	struct otx2_dev *otx2_dev;
+	int ret;
+
+	otx2_dev = &vf->otx2_dev;
+	otx2_mbox_alloc_msg_free_rsrc_cnt(otx2_dev->mbox);
+
+	ret = otx2_mbox_process_msg(otx2_dev->mbox, (void *)&rsp);
+	if (ret)
+		return -EIO;
+
+	if (vf->block_address == RVU_BLOCK_ADDR_REE0)
+		*nb_queues = rsp->ree0;
+	else
+		*nb_queues = rsp->ree1;
+	return 0;
+}
+
+int
+otx2_ree_queues_attach(const struct rte_regexdev *dev, uint8_t nb_queues)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct rsrc_attach_req *req;
+	struct otx2_mbox *mbox;
+
+	/* Ask AF to attach required LFs */
+	mbox = vf->otx2_dev.mbox;
+	req = otx2_mbox_alloc_msg_attach_resources(mbox);
+
+	/* 1 LF = 1 queue */
+	req->reelfs = nb_queues;
+	req->ree_blkaddr = vf->block_address;
+
+	if (otx2_mbox_process(mbox) < 0)
+		return -EIO;
+
+	/* Update number of attached queues */
+	vf->nb_queues = nb_queues;
+
+	return 0;
+}
+
+int
+otx2_ree_queues_detach(const struct rte_regexdev *dev)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct rsrc_detach_req *req;
+	struct otx2_mbox *mbox;
+
+	mbox = vf->otx2_dev.mbox;
+	req = otx2_mbox_alloc_msg_detach_resources(mbox);
+	req->reelfs = true;
+	req->partial = true;
+	if (otx2_mbox_process(mbox) < 0)
+		return -EIO;
+
+	/* Queues have been detached */
+	vf->nb_queues = 0;
+
+	return 0;
+}
+
+int
+otx2_ree_msix_offsets_get(const struct rte_regexdev *dev)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct msix_offset_rsp *rsp;
+	struct otx2_mbox *mbox;
+	uint32_t i, ret;
+
+	/* Get REE MSI-X vector offsets */
+	mbox = vf->otx2_dev.mbox;
+	otx2_mbox_alloc_msg_msix_offset(mbox);
+
+	ret = otx2_mbox_process_msg(mbox, (void *)&rsp);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < vf->nb_queues; i++) {
+		if (vf->block_address == RVU_BLOCK_ADDR_REE0)
+			vf->lf_msixoff[i] = rsp->ree0_lf_msixoff[i];
+		else
+			vf->lf_msixoff[i] = rsp->ree1_lf_msixoff[i];
+		otx2_ree_dbg("lf_msixoff[%d]  0x%x", i, vf->lf_msixoff[i]);
+	}
+
+	return 0;
+}
+
+static int
+ree_send_mbox_msg(struct otx2_ree_vf *vf)
+{
+	struct otx2_mbox *mbox = vf->otx2_dev.mbox;
+	int ret;
+
+	otx2_mbox_msg_send(mbox, 0);
+
+	ret = otx2_mbox_wait_for_rsp(mbox, 0);
+	if (ret < 0) {
+		otx2_err("Could not get mailbox response");
+		return ret;
+	}
+
+	return 0;
+}
+
+int
+otx2_ree_config_lf(const struct rte_regexdev *dev, uint8_t lf, uint8_t pri,
+		   uint32_t size)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct ree_lf_req_msg *req;
+	struct otx2_mbox *mbox;
+	int ret;
+
+	mbox = vf->otx2_dev.mbox;
+	req = otx2_mbox_alloc_msg_ree_config_lf(mbox);
+
+	req->lf = lf;
+	req->pri =  pri ? 1 : 0;
+	req->size = size;
+	req->blkaddr = vf->block_address;
+
+	ret = otx2_mbox_process(mbox);
+	if (ret < 0) {
+		otx2_err("Could not get mailbox response");
+		return ret;
+	}
+	return 0;
+}
+
+int
+otx2_ree_af_reg_read(const struct rte_regexdev *dev, uint64_t reg,
+		     uint64_t *val)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct ree_rd_wr_reg_msg *msg;
+	struct otx2_mbox_dev *mdev;
+	struct otx2_mbox *mbox;
+	int ret, off;
+
+	mbox = vf->otx2_dev.mbox;
+	mdev = &mbox->dev[0];
+	msg = (struct ree_rd_wr_reg_msg *)otx2_mbox_alloc_msg_rsp(mbox, 0,
+						sizeof(*msg), sizeof(*msg));
+	if (msg == NULL) {
+		otx2_err("Could not allocate mailbox message");
+		return -EFAULT;
+	}
+
+	msg->hdr.id = MBOX_MSG_REE_RD_WR_REGISTER;
+	msg->hdr.sig = OTX2_MBOX_REQ_SIG;
+	msg->hdr.pcifunc = vf->otx2_dev.pf_func;
+	msg->is_write = 0;
+	msg->reg_offset = reg;
+	msg->ret_val = val;
+	msg->blkaddr = vf->block_address;
+
+	ret = ree_send_mbox_msg(vf);
+	if (ret < 0)
+		return ret;
+
+	off = mbox->rx_start +
+			RTE_ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
+	msg = (struct ree_rd_wr_reg_msg *) ((uintptr_t)mdev->mbase + off);
+
+	*val = msg->val;
+
+	return 0;
+}
+
+int
+otx2_ree_af_reg_write(const struct rte_regexdev *dev, uint64_t reg,
+		      uint64_t val)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct ree_rd_wr_reg_msg *msg;
+	struct otx2_mbox *mbox;
+
+	mbox = vf->otx2_dev.mbox;
+	msg = (struct ree_rd_wr_reg_msg *)otx2_mbox_alloc_msg_rsp(mbox, 0,
+						sizeof(*msg), sizeof(*msg));
+	if (msg == NULL) {
+		otx2_err("Could not allocate mailbox message");
+		return -EFAULT;
+	}
+
+	msg->hdr.id = MBOX_MSG_REE_RD_WR_REGISTER;
+	msg->hdr.sig = OTX2_MBOX_REQ_SIG;
+	msg->hdr.pcifunc = vf->otx2_dev.pf_func;
+	msg->is_write = 1;
+	msg->reg_offset = reg;
+	msg->val = val;
+	msg->blkaddr = vf->block_address;
+
+	return ree_send_mbox_msg(vf);
+}
+
+int
+otx2_ree_rule_db_get(const struct rte_regexdev *dev, char *rule_db,
+		uint32_t rule_db_len, char *rule_dbi, uint32_t rule_dbi_len)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct ree_rule_db_get_req_msg *req;
+	struct ree_rule_db_get_rsp_msg *rsp;
+	char *rule_db_ptr = (char *)rule_db;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct otx2_mbox *mbox;
+	int ret, last = 0;
+	uint32_t len = 0;
+
+	mbox = vf->otx2_dev.mbox;
+	if (!rule_db) {
+		otx2_err("Couldn't return rule db due to NULL pointer");
+		return -EFAULT;
+	}
+
+	while (!last) {
+		req = (struct ree_rule_db_get_req_msg *)
+			otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
+						sizeof(*rsp));
+		if (!req) {
+			otx2_err("Could not allocate mailbox message");
+			return -EFAULT;
+		}
+
+		req->hdr.id = MBOX_MSG_REE_RULE_DB_GET;
+		req->hdr.sig = OTX2_MBOX_REQ_SIG;
+		req->hdr.pcifunc = vf->otx2_dev.pf_func;
+		req->blkaddr = vf->block_address;
+		req->is_dbi = 0;
+		req->offset = len;
+		ret = otx2_mbox_process_msg(mbox, (void *)&rsp);
+		if (ret)
+			return ret;
+		if (rule_db_len < len + rsp->len) {
+			otx2_err("Rule db size is too small");
+			return -EFAULT;
+		}
+		otx2_mbox_memcpy(rule_db_ptr, rsp->rule_db, rsp->len);
+		len += rsp->len;
+		rule_db_ptr = rule_db_ptr + rsp->len;
+		last = rsp->is_last;
+	}
+
+	if (rule_dbi) {
+		req = (struct ree_rule_db_get_req_msg *)
+			otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
+						sizeof(*rsp));
+		if (!req) {
+			otx2_err("Could not allocate mailbox message");
+			return -EFAULT;
+		}
+
+		req->hdr.id = MBOX_MSG_REE_RULE_DB_GET;
+		req->hdr.sig = OTX2_MBOX_REQ_SIG;
+		req->hdr.pcifunc = vf->otx2_dev.pf_func;
+		req->blkaddr = vf->block_address;
+		req->is_dbi = 1;
+		req->offset = 0;
+
+		ret = otx2_mbox_process_msg(mbox, (void *)&rsp);
+		if (ret)
+			return ret;
+		if (rule_dbi_len < rsp->len) {
+			otx2_err("Rule dbi size is too small");
+			return -EFAULT;
+		}
+		otx2_mbox_memcpy(rule_dbi, rsp->rule_db, rsp->len);
+	}
+	return 0;
+}
+
+int
+otx2_ree_rule_db_len_get(const struct rte_regexdev *dev,
+		uint32_t *rule_db_len,
+		uint32_t *rule_dbi_len)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct ree_rule_db_len_rsp_msg *rsp;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct ree_req_msg *req;
+	struct otx2_mbox *mbox;
+	int ret;
+
+	mbox = vf->otx2_dev.mbox;
+	req = (struct ree_req_msg *)
+		otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req), sizeof(*rsp));
+	if (!req) {
+		otx2_err("Could not allocate mailbox message");
+		return -EFAULT;
+	}
+
+	req->hdr.id = MBOX_MSG_REE_RULE_DB_LEN_GET;
+	req->hdr.sig = OTX2_MBOX_REQ_SIG;
+	req->hdr.pcifunc = vf->otx2_dev.pf_func;
+	req->blkaddr = vf->block_address;
+	ret = otx2_mbox_process_msg(mbox, (void *)&rsp);
+	if (ret)
+		return ret;
+	if (rule_db_len != NULL)
+		*rule_db_len = rsp->len;
+	if (rule_dbi_len != NULL)
+		*rule_dbi_len = rsp->inc_len;
+
+	return 0;
+}
+
+static int
+ree_db_msg(const struct rte_regexdev *dev, const char *db, uint32_t db_len,
+		int inc, int dbi)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	uint32_t len_left = db_len, offset = 0;
+	struct ree_rule_db_prog_req_msg *req;
+	struct otx2_ree_vf *vf = &data->vf;
+	const char *rule_db_ptr = db;
+	struct otx2_mbox *mbox;
+	struct msg_rsp *rsp;
+	int ret;
+
+	mbox = vf->otx2_dev.mbox;
+	while (len_left) {
+		req = (struct ree_rule_db_prog_req_msg *)
+			otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
+						sizeof(*rsp));
+		if (!req) {
+			otx2_err("Could not allocate mailbox message");
+			return -EFAULT;
+		}
+		req->hdr.id = MBOX_MSG_REE_RULE_DB_PROG;
+		req->hdr.sig = OTX2_MBOX_REQ_SIG;
+		req->hdr.pcifunc = vf->otx2_dev.pf_func;
+		req->offset = offset;
+		req->total_len = db_len;
+		req->len = REE_RULE_DB_REQ_BLOCK_SIZE;
+		req->is_incremental = inc;
+		req->is_dbi = dbi;
+		req->blkaddr = vf->block_address;
+
+		if (len_left < REE_RULE_DB_REQ_BLOCK_SIZE) {
+			req->is_last = true;
+			req->len = len_left;
+		}
+		otx2_mbox_memcpy(req->rule_db, rule_db_ptr, req->len);
+		ret = otx2_mbox_process_msg(mbox, (void *)&rsp);
+		if (ret) {
+			otx2_err("Programming mailbox processing failed");
+			return ret;
+		}
+		len_left -= req->len;
+		offset += req->len;
+		rule_db_ptr = rule_db_ptr + req->len;
+	}
+	return 0;
+}
+
+int
+otx2_ree_rule_db_prog(const struct rte_regexdev *dev, const char *rule_db,
+		uint32_t rule_db_len, const char *rule_dbi,
+		uint32_t rule_dbi_len)
+{
+	int inc, ret;
+
+	if (rule_db_len == 0) {
+		otx2_err("Couldn't program empty rule db");
+		return -EFAULT;
+	}
+	inc = (rule_dbi_len != 0);
+	if ((rule_db == NULL) || (inc && (rule_dbi == NULL))) {
+		otx2_err("Couldn't program NULL rule db");
+		return -EFAULT;
+	}
+	if (inc) {
+		ret = ree_db_msg(dev, rule_dbi, rule_dbi_len, inc, 1);
+		if (ret)
+			return ret;
+	}
+	return ree_db_msg(dev, rule_db, rule_db_len, inc, 0);
+}
diff --git a/drivers/regex/octeontx2/otx2_regexdev_mbox.h b/drivers/regex/octeontx2/otx2_regexdev_mbox.h
new file mode 100644
index 000000000..953efa672
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev_mbox.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _OTX2_REGEXDEV_MBOX_H_
+#define _OTX2_REGEXDEV_MBOX_H_
+
+#include <rte_regexdev.h>
+
+int otx2_ree_available_queues_get(const struct rte_regexdev *dev,
+				  uint16_t *nb_queues);
+
+int otx2_ree_queues_attach(const struct rte_regexdev *dev, uint8_t nb_queues);
+
+int otx2_ree_queues_detach(const struct rte_regexdev *dev);
+
+int otx2_ree_msix_offsets_get(const struct rte_regexdev *dev);
+
+int otx2_ree_config_lf(const struct rte_regexdev *dev, uint8_t lf, uint8_t pri,
+		       uint32_t size);
+
+int otx2_ree_af_reg_read(const struct rte_regexdev *dev, uint64_t reg,
+			 uint64_t *val);
+
+int otx2_ree_af_reg_write(const struct rte_regexdev *dev, uint64_t reg,
+			  uint64_t val);
+
+int otx2_ree_rule_db_get(const struct rte_regexdev *dev, char *rule_db,
+		 uint32_t rule_db_len, char *rule_dbi, uint32_t rule_dbi_len);
+
+int otx2_ree_rule_db_len_get(const struct rte_regexdev *dev,
+			     uint32_t *rule_db_len, uint32_t *rule_dbi_len);
+
+int otx2_ree_rule_db_prog(const struct rte_regexdev *dev, const char *rule_db,
+		uint32_t rule_db_len, const char *rule_dbi,
+		uint32_t rule_dbi_len);
+
+#endif /* _OTX2_REGEXDEV_MBOX_H_ */
diff --git a/drivers/regex/octeontx2/rte_pmd_octeontx2_regex_version.map b/drivers/regex/octeontx2/rte_pmd_octeontx2_regex_version.map
new file mode 100644
index 000000000..34eb991c7
--- /dev/null
+++ b/drivers/regex/octeontx2/rte_pmd_octeontx2_regex_version.map
@@ -0,0 +1,3 @@
+DPDK_20.08 {
+	local: *;
+};
diff --git a/meson_options.txt b/meson_options.txt
index 9bf18ab6b..214b5f7f5 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -36,3 +36,5 @@ option('tests', type: 'boolean', value: true,
 	description: 'build unit tests')
 option('use_hpet', type: 'boolean', value: false,
 	description: 'use HPET timer in EAL')
+option('ree_compiler_sdk', type: 'string', value: '',
+	description: 'path to REE compiler SDK optional library for regex device')
\ No newline at end of file
-- 
2.28.0


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [dpdk-dev] [PATCH 3/4] usertools: add octeontx2 REE device binding
  2020-09-01 12:24 [dpdk-dev] [PATCH 0/4] Add Marvell OCTEON TX2 regex driver guyk
  2020-09-01 12:24 ` [dpdk-dev] [PATCH 1/4] common/octeontx2: add REE definitions and logging support guyk
  2020-09-01 12:24 ` [dpdk-dev] [PATCH 2/4] regex/octeontx2: add build infra and device support guyk
@ 2020-09-01 12:24 ` guyk
  2020-10-11  7:36   ` Liron Himi
  2020-09-01 12:24 ` [dpdk-dev] [PATCH 4/4] doc: add Marvell OCTEON TX2 regex guide guyk
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 33+ messages in thread
From: guyk @ 2020-09-01 12:24 UTC (permalink / raw)
  To: jerinj, ndabilpuram, thomas, mdr, nhorman, bruce.richardson,
	anatoly.burakov, john.mcnamara, marko.kovacevic
  Cc: dev, smadarf, dovrat, guyk, orika

From: Guy Kaneti <guyk@marvell.com>

Update the devbind script with new section of regex devices, also
added OCTEONTX2 REE device ID to regex device list

Signed-off-by: Guy Kaneti <guyk@marvell.com>
---
 usertools/dpdk-devbind.py | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py
index 86b6b53c4..51ee990db 100755
--- a/usertools/dpdk-devbind.py
+++ b/usertools/dpdk-devbind.py
@@ -44,6 +44,8 @@
               'SVendor': None, 'SDevice': None}
 octeontx2_dma = {'Class': '08', 'Vendor': '177d', 'Device': 'a081',
               'SVendor': None, 'SDevice': None}
+octeontx2_ree = {'Class': '08', 'Vendor': '177d', 'Device': 'a0f4',
+              'SVendor': None, 'SDevice': None}
 
 intel_ioat_bdw = {'Class': '08', 'Vendor': '8086', 'Device': '6f20,6f21,6f22,6f23,6f24,6f25,6f26,6f27,6f2e,6f2f',
               'SVendor': None, 'SDevice': None}
@@ -61,6 +63,7 @@
 mempool_devices = [cavium_fpa, octeontx2_npa]
 compress_devices = [cavium_zip]
 misc_devices = [intel_ioat_bdw, intel_ioat_skx, intel_ioat_icx, intel_ntb_skx, octeontx2_dma]
+regex_devices = [octeontx2_ree]
 
 # global dict ethernet devices present. Dictionary indexed by PCI address.
 # Each device within this is itself a dictionary of device properties
@@ -648,6 +651,9 @@ def show_status():
     if status_dev == "misc" or status_dev == "all":
         show_device_status(misc_devices, "Misc (rawdev)")
 
+    if status_dev == "regex" or status_dev == "all":
+        show_device_status(regex_devices, "Regex")
+
 def parse_args():
     '''Parses the command-line arguments given by the user and takes the
     appropriate action for each'''
@@ -723,6 +729,7 @@ def do_arg_actions():
             get_device_details(mempool_devices)
             get_device_details(compress_devices)
             get_device_details(misc_devices)
+            get_device_details(regex_devices)
         show_status()
 
 
@@ -744,6 +751,7 @@ def main():
     get_device_details(mempool_devices)
     get_device_details(compress_devices)
     get_device_details(misc_devices)
+    get_device_details(regex_devices)
     do_arg_actions()
 
 if __name__ == "__main__":
-- 
2.28.0


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [dpdk-dev] [PATCH 4/4] doc: add Marvell OCTEON TX2 regex guide
  2020-09-01 12:24 [dpdk-dev] [PATCH 0/4] Add Marvell OCTEON TX2 regex driver guyk
                   ` (2 preceding siblings ...)
  2020-09-01 12:24 ` [dpdk-dev] [PATCH 3/4] usertools: add octeontx2 REE device binding guyk
@ 2020-09-01 12:24 ` guyk
  2020-10-11  7:36   ` Liron Himi
  2020-10-08  6:31 ` [dpdk-dev] [PATCH 0/4] Add Marvell OCTEON TX2 regex driver Guy Kaneti
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 33+ messages in thread
From: guyk @ 2020-09-01 12:24 UTC (permalink / raw)
  To: jerinj, ndabilpuram, thomas, mdr, nhorman, bruce.richardson,
	anatoly.burakov, john.mcnamara, marko.kovacevic
  Cc: dev, smadarf, dovrat, guyk, orika

From: Guy Kaneti <guyk@marvell.com>

Signed-off-by: Guy Kaneti <guyk@marvell.com>
---
 doc/guides/platform/octeontx2.rst           |  5 +++
 doc/guides/regexdevs/features/octeontx2.ini | 10 +++++
 doc/guides/regexdevs/index.rst              |  1 +
 doc/guides/regexdevs/octeontx2.rst          | 49 +++++++++++++++++++++
 doc/guides/rel_notes/release_20_11.rst      |  5 +++
 5 files changed, 70 insertions(+)
 create mode 100644 doc/guides/regexdevs/features/octeontx2.ini
 create mode 100644 doc/guides/regexdevs/octeontx2.rst

diff --git a/doc/guides/platform/octeontx2.rst b/doc/guides/platform/octeontx2.rst
index 13255eec5..c4d64ab4b 100644
--- a/doc/guides/platform/octeontx2.rst
+++ b/doc/guides/platform/octeontx2.rst
@@ -67,6 +67,8 @@ DPDK subsystem.
    +---+-----+--------------------------------------------------------------+
    | 9 | SDP | rte_ethdev                                                   |
    +---+-----+--------------------------------------------------------------+
+   | 10| REE | rte_regexdev                                                 |
+   +---+-----+--------------------------------------------------------------+
 
 PF0 is called the administrative / admin function (AF) and has exclusive
 privileges to provision RVU functional block's LFs to each of the PF/VF.
@@ -156,6 +158,9 @@ This section lists dataplane H/W block(s) available in OCTEON TX2 SoC.
 #. **Crypto Device Driver**
    See :doc:`../cryptodevs/octeontx2` for CPT crypto device driver information.
 
+#. **Regex Device Driver**
+   See :doc:`../regexdevs/octeontx2` for REE regex device driver information.
+
 Procedure to Setup Platform
 ---------------------------
 
diff --git a/doc/guides/regexdevs/features/octeontx2.ini b/doc/guides/regexdevs/features/octeontx2.ini
new file mode 100644
index 000000000..c9b421a16
--- /dev/null
+++ b/doc/guides/regexdevs/features/octeontx2.ini
@@ -0,0 +1,10 @@
+;
+; Supported features of the 'octeontx2' regex driver.
+;
+; Refer to default.ini for the full list of available driver features.
+;
+[Features]
+PCRE back reference         = Y
+PCRE word boundary          = Y
+Run time compilation        = Y
+Armv8                       = Y
diff --git a/doc/guides/regexdevs/index.rst b/doc/guides/regexdevs/index.rst
index 49216a932..b1abc826b 100644
--- a/doc/guides/regexdevs/index.rst
+++ b/doc/guides/regexdevs/index.rst
@@ -13,3 +13,4 @@ which can be used from an application through RegEx API.
 
    features_overview
    mlx5
+   octeontx2
diff --git a/doc/guides/regexdevs/octeontx2.rst b/doc/guides/regexdevs/octeontx2.rst
new file mode 100644
index 000000000..859780da1
--- /dev/null
+++ b/doc/guides/regexdevs/octeontx2.rst
@@ -0,0 +1,49 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright(c) 2020 Marvell International Ltd.
+
+OCTEON TX2 REE Regexdev Driver
+===============================
+
+The OCTEON TX2 REE PMD (**librte_pmd_octeontx2_regex**) provides poll mode
+regexdev driver support for the inbuilt regex device found in the **Marvell OCTEON TX2**
+SoC family.
+
+More information about OCTEON TX2 SoC can be found at `Marvell Official Website
+<https://www.marvell.com/embedded-processors/infrastructure-processors/>`_.
+
+Features
+--------
+
+Features of the OCTEON TX2 REE PMD are:
+
+- 36 queues
+- Up to 254 matches for each regex operation
+
+Prerequisites and Compilation procedure
+---------------------------------------
+
+   See :doc:`../platform/octeontx2` for setup information.
+
+Device Setup
+------------
+
+The OCTEON TX2 REE devices will need to be bound to a user-space IO driver
+for use. The script ``dpdk-devbind.py`` script included with DPDK can be
+used to view the state of the devices and to bind them to a suitable
+DPDK-supported kernel driver. When querying the status of the devices,
+they will appear under the category of "REGEX devices", i.e. the command
+``dpdk-devbind.py --status-dev regex`` can be used to see the state of
+those devices alone.
+
+Debugging Options
+-----------------
+
+.. _table_octeontx2_regex_debug_options:
+
+.. table:: OCTEON TX2 regex device debug options
+
+   +---+------------+-------------------------------------------------------+
+   | # | Component  | EAL log command                                       |
+   +===+============+=======================================================+
+   | 1 | REE        | --log-level='pmd\.regex\.octeontx2,8'                 |
+   +---+------------+-------------------------------------------------------+
diff --git a/doc/guides/rel_notes/release_20_11.rst b/doc/guides/rel_notes/release_20_11.rst
index df227a177..05c0a8ba7 100644
--- a/doc/guides/rel_notes/release_20_11.rst
+++ b/doc/guides/rel_notes/release_20_11.rst
@@ -55,6 +55,11 @@ New Features
      Also, make sure to start the actual text at the margin.
      =======================================================
 
+* **Added Marvell OCTEON TX2 regex PMD.**
+
+  Added a new PMD driver for hardware regex offload block for OCTEON TX2 SoC.
+
+  See the :doc:`../regexdevs/octeontx2` for more details.
 
 Removed Items
 -------------
-- 
2.28.0


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [dpdk-dev] [PATCH 0/4] Add Marvell OCTEON TX2 regex driver
  2020-09-01 12:24 [dpdk-dev] [PATCH 0/4] Add Marvell OCTEON TX2 regex driver guyk
                   ` (3 preceding siblings ...)
  2020-09-01 12:24 ` [dpdk-dev] [PATCH 4/4] doc: add Marvell OCTEON TX2 regex guide guyk
@ 2020-10-08  6:31 ` Guy Kaneti
  2020-10-11 21:23   ` Thomas Monjalon
  2020-10-12 11:31 ` [dpdk-dev] [PATCH v2 " guyk
  2020-10-13 10:10 ` [dpdk-dev] [PATCH v3 0/3] Add Marvell OCTEON TX2 regex driver guyk
  6 siblings, 1 reply; 33+ messages in thread
From: Guy Kaneti @ 2020-10-08  6:31 UTC (permalink / raw)
  To: Jerin Jacob Kollanukkaran, Nithin Kumar Dabilpuram, thomas, mdr,
	nhorman, bruce.richardson, anatoly.burakov, john.mcnamara,
	marko.kovacevic, orika
  Cc: dev, Smadar Fuks, Dovrat Zifroni, Guy Kaneti

Kind reminder to all maintainers, please review and ack/comment.

> -----Original Message-----
> From: guyk@marvell.com <guyk@marvell.com>
> Sent: Tuesday, September 1, 2020 3:25 PM
> To: Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Nithin Kumar
> Dabilpuram <ndabilpuram@marvell.com>; thomas@monjalon.net;
> mdr@ashroe.eu; nhorman@tuxdriver.com; bruce.richardson@intel.com;
> anatoly.burakov@intel.com; john.mcnamara@intel.com;
> marko.kovacevic@intel.com
> Cc: dev@dpdk.org; Smadar Fuks <smadarf@marvell.com>; Dovrat Zifroni
> <dovrat@marvell.com>; Guy Kaneti <guyk@marvell.com>;
> orika@mellanox.com
> Subject: [PATCH 0/4] Add Marvell OCTEON TX2 regex driver
> 
> From: Guy Kaneti <guyk@marvell.com>
> 
> This patchset adds support for OCTEON TX2 regex driver as DPDK regexdev.
> The driver implements the API defined in the regexdev lib.
> 
> Guy Kaneti (4):
>   common/octeontx2: add REE definitions and logging support
>   regex/octeontx2: add build infra and device support
>   usertools: add octeontx2 REE device binding
>   doc: add Marvell OCTEON TX2 regex guide
> 
>  MAINTAINERS                                   |    3 +
>  config/common_base                            |    6 +
>  doc/guides/platform/octeontx2.rst             |    5 +
>  doc/guides/regexdevs/features/octeontx2.ini   |   10 +
>  doc/guides/regexdevs/index.rst                |    1 +
>  doc/guides/regexdevs/octeontx2.rst            |   49 +
>  doc/guides/rel_notes/release_20_11.rst        |    5 +
>  drivers/common/octeontx2/hw/otx2_ree.h        |   27 +
>  drivers/common/octeontx2/hw/otx2_rvu.h        |    5 +
>  drivers/common/octeontx2/otx2_common.c        |    1 +
>  drivers/common/octeontx2/otx2_common.h        |    5 +
>  drivers/common/octeontx2/otx2_mbox.h          |  103 ++
>  .../rte_common_octeontx2_version.map          |    1 +
>  drivers/regex/meson.build                     |    2 +-
>  drivers/regex/octeontx2/meson.build           |   53 +
>  drivers/regex/octeontx2/otx2_regexdev.c       | 1001 +++++++++++++++++
>  drivers/regex/octeontx2/otx2_regexdev.h       |  109 ++
>  .../regex/octeontx2/otx2_regexdev_compiler.c  |  229 ++++
>  .../regex/octeontx2/otx2_regexdev_compiler.h  |   11 +
>  .../regex/octeontx2/otx2_regexdev_hw_access.c |  167 +++
> .../regex/octeontx2/otx2_regexdev_hw_access.h |  202 ++++
> drivers/regex/octeontx2/otx2_regexdev_mbox.c  |  401 +++++++
>  drivers/regex/octeontx2/otx2_regexdev_mbox.h  |   38 +
>  .../rte_pmd_octeontx2_regex_version.map       |    3 +
>  meson_options.txt                             |    2 +
>  usertools/dpdk-devbind.py                     |    8 +
>  26 files changed, 2446 insertions(+), 1 deletion(-)  create mode 100644
> doc/guides/regexdevs/features/octeontx2.ini
>  create mode 100644 doc/guides/regexdevs/octeontx2.rst
>  create mode 100644 drivers/common/octeontx2/hw/otx2_ree.h
>  create mode 100644 drivers/regex/octeontx2/meson.build
>  create mode 100644 drivers/regex/octeontx2/otx2_regexdev.c
>  create mode 100644 drivers/regex/octeontx2/otx2_regexdev.h
>  create mode 100644 drivers/regex/octeontx2/otx2_regexdev_compiler.c
>  create mode 100644 drivers/regex/octeontx2/otx2_regexdev_compiler.h
>  create mode 100644 drivers/regex/octeontx2/otx2_regexdev_hw_access.c
>  create mode 100644 drivers/regex/octeontx2/otx2_regexdev_hw_access.h
>  create mode 100644 drivers/regex/octeontx2/otx2_regexdev_mbox.c
>  create mode 100644 drivers/regex/octeontx2/otx2_regexdev_mbox.h
>  create mode 100644
> drivers/regex/octeontx2/rte_pmd_octeontx2_regex_version.map
> 
> --
> 2.28.0


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [dpdk-dev] [PATCH 1/4] common/octeontx2: add REE definitions and logging support
  2020-09-01 12:24 ` [dpdk-dev] [PATCH 1/4] common/octeontx2: add REE definitions and logging support guyk
@ 2020-10-11  7:35   ` Liron Himi
  0 siblings, 0 replies; 33+ messages in thread
From: Liron Himi @ 2020-10-11  7:35 UTC (permalink / raw)
  To: Guy Kaneti, Jerin Jacob Kollanukkaran, Nithin Kumar Dabilpuram,
	thomas, mdr, nhorman, bruce.richardson, anatoly.burakov,
	john.mcnamara, marko.kovacevic
  Cc: dev, Smadar Fuks, Dovrat Zifroni, Guy Kaneti, orika, Liron Himi

Reviewed-by: Liron Himi <lironh@marvell.com>

-----Original Message-----
From: dev <dev-bounces@dpdk.org> On Behalf Of guyk@marvell.com
Sent: Tuesday, 1 September 2020 15:25
To: Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Nithin Kumar Dabilpuram <ndabilpuram@marvell.com>; thomas@monjalon.net; mdr@ashroe.eu; nhorman@tuxdriver.com; bruce.richardson@intel.com; anatoly.burakov@intel.com; john.mcnamara@intel.com; marko.kovacevic@intel.com
Cc: dev@dpdk.org; Smadar Fuks <smadarf@marvell.com>; Dovrat Zifroni <dovrat@marvell.com>; Guy Kaneti <guyk@marvell.com>; orika@mellanox.com
Subject: [dpdk-dev] [PATCH 1/4] common/octeontx2: add REE definitions and logging support

From: Guy Kaneti <guyk@marvell.com>

Add REE mbox msg definitions, RVU and REE HW definitions

Signed-off-by: Guy Kaneti <guyk@marvell.com>
---
 drivers/common/octeontx2/hw/otx2_ree.h        |  27 +++++
 drivers/common/octeontx2/hw/otx2_rvu.h        |   5 +
 drivers/common/octeontx2/otx2_common.c        |   1 +
 drivers/common/octeontx2/otx2_common.h        |   5 +
 drivers/common/octeontx2/otx2_mbox.h          | 103 ++++++++++++++++++
 .../rte_common_octeontx2_version.map          |   1 +
 6 files changed, 142 insertions(+)
 create mode 100644 drivers/common/octeontx2/hw/otx2_ree.h

diff --git a/drivers/common/octeontx2/hw/otx2_ree.h b/drivers/common/octeontx2/hw/otx2_ree.h
new file mode 100644
index 000000000..b7481f125
--- /dev/null
+++ b/drivers/common/octeontx2/hw/otx2_ree.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#ifndef __OTX2_REE_HW_H__
+#define __OTX2_REE_HW_H__
+
+/* REE BAR0*/
+#define REE_AF_REEXM_MAX_MATCH		(0x80c8)
+
+/* REE BAR02 */
+#define REE_LF_MISC_INT                 (0x300)
+#define REE_LF_DONE_INT                 (0x120)
+
+#define REE_AF_QUEX_GMCTL(a)            (0x800 | (a) << 3)
+
+#define REE_AF_INT_VEC_RAS          (0x0ull)
+#define REE_AF_INT_VEC_RVU          (0x1ull)
+#define REE_AF_INT_VEC_QUE_DONE     (0x2ull)
+#define REE_AF_INT_VEC_AQ           (0x3ull)
+
+/* ENUMS */
+
+#define REE_LF_INT_VEC_QUE_DONE	(0x0ull)
+#define REE_LF_INT_VEC_MISC		(0x1ull)
+
+#endif /* __OTX2_REE_HW_H__*/
diff --git a/drivers/common/octeontx2/hw/otx2_rvu.h b/drivers/common/octeontx2/hw/otx2_rvu.h
index 330bfb37f..072515207 100644
--- a/drivers/common/octeontx2/hw/otx2_rvu.h
+++ b/drivers/common/octeontx2/hw/otx2_rvu.h
@@ -130,6 +130,7 @@
 #define RVU_BLOCK_TYPE_RAD                  (0xdull)
 #define RVU_BLOCK_TYPE_DFA                  (0xeull)
 #define RVU_BLOCK_TYPE_HNA                  (0xfull)
+#define RVU_BLOCK_TYPE_REE                  (0xeull)
 
 #define RVU_BLOCK_ADDR_RVUM                 (0x0ull)
 #define RVU_BLOCK_ADDR_LMT                  (0x1ull)
@@ -146,6 +147,8 @@
 #define RVU_BLOCK_ADDR_NDC2                 (0xeull)
 #define RVU_BLOCK_ADDR_R_END                (0x1full)
 #define RVU_BLOCK_ADDR_R_START              (0x14ull)
+#define RVU_BLOCK_ADDR_REE0                 (0x14ull)
+#define RVU_BLOCK_ADDR_REE1                 (0x15ull)
 
 #define RVU_VF_INT_VEC_MBOX                 (0x0ull)
 
@@ -167,6 +170,7 @@
 #define NPA_AF_BAR2_SEL			(0x9000000ull)
 #define CPT_AF_BAR2_SEL			(0x9000000ull)
 #define RVU_AF_BAR2_SEL			(0x9000000ull)
+#define REE_AF_BAR2_SEL			(0x9000000ull)
 
 #define AF_BAR2_ALIASX(a, b) \
 	(0x9100000ull | (uint64_t)(a) << 12 | (uint64_t)(b)) @@ -177,6 +181,7 @@
 #define NPA_AF_BAR2_ALIASX(a, b)		AF_BAR2_ALIASX(0, b)
 #define CPT_AF_BAR2_ALIASX(a, b)		AF_BAR2_ALIASX(a, b)
 #define RVU_AF_BAR2_ALIASX(a, b)		AF_BAR2_ALIASX(a, b)
+#define REE_AF_BAR2_ALIASX(a, b)		AF_BAR2_ALIASX(a, b)
 
 /* Structures definitions */
 
diff --git a/drivers/common/octeontx2/otx2_common.c b/drivers/common/octeontx2/otx2_common.c
index b292e999a..d23c50242 100644
--- a/drivers/common/octeontx2/otx2_common.c
+++ b/drivers/common/octeontx2/otx2_common.c
@@ -213,3 +213,4 @@ RTE_LOG_REGISTER(otx2_logtype_sso, pmd.event.octeontx2, NOTICE);  RTE_LOG_REGISTER(otx2_logtype_tim, pmd.event.octeontx2.timer, NOTICE);  RTE_LOG_REGISTER(otx2_logtype_dpi, pmd.raw.octeontx2.dpi, NOTICE);  RTE_LOG_REGISTER(otx2_logtype_ep, pmd.raw.octeontx2.ep, NOTICE);
+RTE_LOG_REGISTER(otx2_logtype_ree, pmd.regex.octeontx2, NOTICE);
diff --git a/drivers/common/octeontx2/otx2_common.h b/drivers/common/octeontx2/otx2_common.h
index 2168cde4d..b6779f710 100644
--- a/drivers/common/octeontx2/otx2_common.h
+++ b/drivers/common/octeontx2/otx2_common.h
@@ -21,6 +21,7 @@
 #include "hw/otx2_sso.h"
 #include "hw/otx2_ssow.h"
 #include "hw/otx2_tim.h"
+#include "hw/otx2_ree.h"
 
 /* Alignment */
 #define OTX2_ALIGN  128
@@ -96,6 +97,7 @@ extern int otx2_logtype_tm;  extern int otx2_logtype_tim;  extern int otx2_logtype_dpi;  extern int otx2_logtype_ep;
+extern int otx2_logtype_ree;
 
 #define otx2_err(fmt, args...)			\
 	RTE_LOG(ERR, PMD, "%s():%u " fmt "\n",	\
@@ -119,6 +121,7 @@ extern int otx2_logtype_ep;  #define otx2_tim_dbg(fmt, ...) otx2_dbg(tim, fmt, ##__VA_ARGS__)  #define otx2_dpi_dbg(fmt, ...) otx2_dbg(dpi, fmt, ##__VA_ARGS__)  #define otx2_sdp_dbg(fmt, ...) otx2_dbg(ep, fmt, ##__VA_ARGS__)
+#define otx2_ree_dbg(fmt, ...) otx2_dbg(ree, fmt, ##__VA_ARGS__)
 
 /* PCI IDs */
 #define PCI_VENDOR_ID_CAVIUM			0x177D
@@ -136,6 +139,8 @@ extern int otx2_logtype_ep;
 #define PCI_DEVID_OCTEONTX2_EP_VF		0xB203 /* OCTEON TX2 EP mode */
 #define PCI_DEVID_OCTEONTX2_RVU_SDP_PF		0xA0f6
 #define PCI_DEVID_OCTEONTX2_RVU_SDP_VF		0xA0f7
+#define PCI_DEVID_OCTEONTX2_RVU_REE_PF		0xA0f4
+#define PCI_DEVID_OCTEONTX2_RVU_REE_VF		0xA0f5
 
 /*
  * REVID for RVU PCIe devices.
diff --git a/drivers/common/octeontx2/otx2_mbox.h b/drivers/common/octeontx2/otx2_mbox.h
index 34b1d0663..b3c32e9a4 100644
--- a/drivers/common/octeontx2/otx2_mbox.h
+++ b/drivers/common/octeontx2/otx2_mbox.h
@@ -199,6 +199,19 @@ M(CPT_INLINE_IPSEC_CFG, 0xA04, cpt_inline_ipsec_cfg,			\
 M(CPT_RX_INLINE_LF_CFG, 0xBFE, cpt_rx_inline_lf_cfg,			\
 			       cpt_rx_inline_lf_cfg_msg, msg_rsp)	\
 M(CPT_GET_CAPS,		0xBFD, cpt_caps_get, msg_req, cpt_caps_rsp_msg)	\
+/* REE mbox IDs (range 0xE00 - 0xFFF) */				\
+M(REE_CONFIG_LF,	0xE01, ree_config_lf, ree_lf_req_msg,		\
+				msg_rsp)				\
+M(REE_RD_WR_REGISTER,	0xE02, ree_rd_wr_register, ree_rd_wr_reg_msg,	\
+				ree_rd_wr_reg_msg)			\
+M(REE_RULE_DB_PROG,	0xE03, ree_rule_db_prog,			\
+				ree_rule_db_prog_req_msg,		\
+				msg_rsp)				\
+M(REE_RULE_DB_LEN_GET,	0xE04, ree_rule_db_len_get, ree_req_msg,	\
+				ree_rule_db_len_rsp_msg)		\
+M(REE_RULE_DB_GET,	0xE05, ree_rule_db_get,				\
+				ree_rule_db_get_req_msg,		\
+				ree_rule_db_get_rsp_msg)		\
 /* NPC mbox IDs (range 0x6000 - 0x7FFF) */				\
 M(NPC_MCAM_ALLOC_ENTRY,	0x6000, npc_mcam_alloc_entry,			\
 				npc_mcam_alloc_entry_req,		\
@@ -1650,6 +1663,96 @@ struct tim_enable_rsp {
 	uint32_t __otx2_io currentbucket;
 };
 
+/* REE mailbox error codes
+ * Range 1001 - 1100.
+ */
+enum ree_af_status {
+	REE_AF_ERR_RULE_UNKNOWN_VALUE		= -1001,
+	REE_AF_ERR_LF_NO_MORE_RESOURCES		= -1002,
+	REE_AF_ERR_LF_INVALID			= -1003,
+	REE_AF_ERR_ACCESS_DENIED		= -1004,
+	REE_AF_ERR_RULE_DB_PARTIAL		= -1005,
+	REE_AF_ERR_RULE_DB_EQ_BAD_VALUE		= -1006,
+	REE_AF_ERR_RULE_DB_BLOCK_ALLOC_FAILED	= -1007,
+	REE_AF_ERR_BLOCK_NOT_IMPLEMENTED	= -1008,
+	REE_AF_ERR_RULE_DB_INC_OFFSET_TOO_BIG	= -1009,
+	REE_AF_ERR_RULE_DB_OFFSET_TOO_BIG	= -1010,
+	REE_AF_ERR_Q_IS_GRACEFUL_DIS		= -1011,
+	REE_AF_ERR_Q_NOT_GRACEFUL_DIS		= -1012,
+	REE_AF_ERR_RULE_DB_ALLOC_FAILED		= -1013,
+	REE_AF_ERR_RULE_DB_TOO_BIG		= -1014,
+	REE_AF_ERR_RULE_DB_GEQ_BAD_VALUE	= -1015,
+	REE_AF_ERR_RULE_DB_LEQ_BAD_VALUE	= -1016,
+	REE_AF_ERR_RULE_DB_WRONG_LENGTH		= -1017,
+	REE_AF_ERR_RULE_DB_WRONG_OFFSET		= -1018,
+	REE_AF_ERR_RULE_DB_BLOCK_TOO_BIG	= -1019,
+	REE_AF_ERR_RULE_DB_SHOULD_FILL_REQUEST	= -1020,
+	REE_AF_ERR_RULE_DBI_ALLOC_FAILED	= -1021,
+	REE_AF_ERR_LF_WRONG_PRIORITY		= -1022,
+	REE_AF_ERR_LF_SIZE_TOO_BIG		= -1023,
+};
+
+/* REE mbox message formats */
+
+struct ree_req_msg {
+	struct mbox_msghdr hdr;
+	uint32_t __otx2_io blkaddr;
+};
+
+struct ree_lf_req_msg {
+	struct mbox_msghdr hdr;
+	uint32_t __otx2_io blkaddr;
+	uint32_t __otx2_io size;
+	uint8_t __otx2_io lf;
+	uint8_t __otx2_io pri;
+};
+
+struct ree_rule_db_prog_req_msg {
+	struct mbox_msghdr hdr;
+#define REE_RULE_DB_REQ_BLOCK_SIZE (MBOX_SIZE >> 1)
+	uint8_t __otx2_io rule_db[REE_RULE_DB_REQ_BLOCK_SIZE];
+	uint32_t __otx2_io blkaddr; /* REE0 or REE1 */
+	uint32_t __otx2_io total_len; /* total len of rule db */
+	uint32_t __otx2_io offset; /* offset of current rule db block */
+	uint16_t __otx2_io len; /* length of rule db block */
+	uint8_t __otx2_io is_last; /* is this the last block */
+	uint8_t __otx2_io is_incremental; /* is incremental flow */
+	uint8_t __otx2_io is_dbi; /* is rule db incremental */ };
+
+struct ree_rule_db_get_req_msg {
+	struct mbox_msghdr hdr;
+	uint32_t __otx2_io blkaddr;
+	uint32_t __otx2_io offset; /* retrieve db from this offset */
+	uint8_t __otx2_io is_dbi; /* is request for rule db incremental */ };
+
+struct ree_rd_wr_reg_msg {
+	struct mbox_msghdr hdr;
+	uint64_t __otx2_io reg_offset;
+	uint64_t __otx2_io *ret_val;
+	uint64_t __otx2_io val;
+	uint32_t __otx2_io blkaddr;
+	uint8_t __otx2_io is_write;
+};
+
+struct ree_rule_db_len_rsp_msg {
+	struct mbox_msghdr hdr;
+	uint32_t __otx2_io blkaddr;
+	uint32_t __otx2_io len;
+	uint32_t __otx2_io inc_len;
+};
+
+struct ree_rule_db_get_rsp_msg {
+	struct mbox_msghdr hdr;
+#define REE_RULE_DB_RSP_BLOCK_SIZE (MBOX_DOWN_TX_SIZE - SZ_1K)
+	uint8_t __otx2_io rule_db[REE_RULE_DB_RSP_BLOCK_SIZE];
+	uint32_t __otx2_io total_len; /* total len of rule db */
+	uint32_t __otx2_io offset; /* offset of current rule db block */
+	uint16_t __otx2_io len; /* length of rule db block */
+	uint8_t __otx2_io is_last; /* is this the last block */ };
+
 __rte_internal
 const char *otx2_mbox_id2name(uint16_t id);  int otx2_mbox_id2size(uint16_t id); diff --git a/drivers/common/octeontx2/rte_common_octeontx2_version.map b/drivers/common/octeontx2/rte_common_octeontx2_version.map
index 9a9969613..d269d70d8 100644
--- a/drivers/common/octeontx2/rte_common_octeontx2_version.map
+++ b/drivers/common/octeontx2/rte_common_octeontx2_version.map
@@ -38,6 +38,7 @@ INTERNAL {
 	otx2_sso_pf_func_get;
 	otx2_sso_pf_func_set;
 	otx2_unregister_irq;
+	otx2_logtype_ree;
 
 	local: *;
 };
--
2.28.0


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [dpdk-dev] [PATCH 2/4] regex/octeontx2: add build infra and device support
  2020-09-01 12:24 ` [dpdk-dev] [PATCH 2/4] regex/octeontx2: add build infra and device support guyk
@ 2020-10-11  7:36   ` Liron Himi
  0 siblings, 0 replies; 33+ messages in thread
From: Liron Himi @ 2020-10-11  7:36 UTC (permalink / raw)
  To: Guy Kaneti, Jerin Jacob Kollanukkaran, Nithin Kumar Dabilpuram,
	thomas, mdr, nhorman, bruce.richardson, anatoly.burakov,
	john.mcnamara, marko.kovacevic
  Cc: dev, Smadar Fuks, Dovrat Zifroni, Guy Kaneti, orika, Liron Himi

Reviewed-by: Liron Himi <lironh@marvell.com>

-----Original Message-----
From: dev <dev-bounces@dpdk.org> On Behalf Of guyk@marvell.com
Sent: Tuesday, 1 September 2020 15:25
To: Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Nithin Kumar Dabilpuram <ndabilpuram@marvell.com>; thomas@monjalon.net; mdr@ashroe.eu; nhorman@tuxdriver.com; bruce.richardson@intel.com; anatoly.burakov@intel.com; john.mcnamara@intel.com; marko.kovacevic@intel.com
Cc: dev@dpdk.org; Smadar Fuks <smadarf@marvell.com>; Dovrat Zifroni <dovrat@marvell.com>; Guy Kaneti <guyk@marvell.com>; orika@mellanox.com
Subject: [dpdk-dev] [PATCH 2/4] regex/octeontx2: add build infra and device support

From: Guy Kaneti <guyk@marvell.com>

Add meson based build infrastructure along with the
OTX2 regexdev (REE) device functions.

For regex rule compiler support build:
meson configure -Dree_compiler_sdk=<path-to-compiler-sdk>

Signed-off-by: Guy Kaneti <guyk@marvell.com>
---
 MAINTAINERS                                   |    3 +
 config/common_base                            |    6 +
 drivers/regex/meson.build                     |    2 +-
 drivers/regex/octeontx2/meson.build           |   53 +
 drivers/regex/octeontx2/otx2_regexdev.c       | 1001 +++++++++++++++++
 drivers/regex/octeontx2/otx2_regexdev.h       |  109 ++
 .../regex/octeontx2/otx2_regexdev_compiler.c  |  229 ++++
 .../regex/octeontx2/otx2_regexdev_compiler.h  |   11 +
 .../regex/octeontx2/otx2_regexdev_hw_access.c |  167 +++
 .../regex/octeontx2/otx2_regexdev_hw_access.h |  202 ++++
 drivers/regex/octeontx2/otx2_regexdev_mbox.c  |  401 +++++++
 drivers/regex/octeontx2/otx2_regexdev_mbox.h  |   38 +
 .../rte_pmd_octeontx2_regex_version.map       |    3 +
 meson_options.txt                             |    2 +
 14 files changed, 2226 insertions(+), 1 deletion(-)
 create mode 100644 drivers/regex/octeontx2/meson.build
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev.h
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_compiler.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_compiler.h
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_hw_access.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_hw_access.h
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_mbox.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_mbox.h
 create mode 100644 drivers/regex/octeontx2/rte_pmd_octeontx2_regex_version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index ed163f5d5..ab8a9313c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1137,6 +1137,9 @@ F: drivers/regex/mlx5/
 F: doc/guides/regexdevs/mlx5.rst
 F: doc/guides/regexdevs/features/mlx5.ini
 
+Marvell OCTEON TX2 regex
+M: Guy Kaneti <guyk@marvell.com>
+F: drivers/regex/octeontx2/
 
 vDPA Drivers
 ------------
diff --git a/config/common_base b/config/common_base
index fbf0ee70c..2cd687bf6 100644
--- a/config/common_base
+++ b/config/common_base
@@ -842,6 +842,12 @@ CONFIG_RTE_LIBRTE_PMD_OCTEONTX2_EP_RAWDEV=y
 #
 CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV=y
 
+#
+# Compile PMD for Octeontx2 REE regex device
+#
+CONFIG_RTE_LIBRTE_PMD_OCTEONTX2_REGEX=y
+CONFIG_RTE_LIBRTE_PMD_OCTEONTX2_REGEX_COMPILER=n
+
 #
 # Compile librte_ring
 #
diff --git a/drivers/regex/meson.build b/drivers/regex/meson.build
index 8edeba3a0..79bb5d5df 100644
--- a/drivers/regex/meson.build
+++ b/drivers/regex/meson.build
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright 2020 Mellanox Technologies, Ltd
 
-drivers = ['mlx5']
+drivers = ['mlx5', 'octeontx2']
 std_deps = ['ethdev', 'kvargs'] # 'ethdev' also pulls in mbuf, net, eal etc
 config_flag_fmt = 'RTE_LIBRTE_@0@_PMD'
 driver_name_fmt = 'rte_pmd_@0@'
diff --git a/drivers/regex/octeontx2/meson.build b/drivers/regex/octeontx2/meson.build
new file mode 100644
index 000000000..c212e3d43
--- /dev/null
+++ b/drivers/regex/octeontx2/meson.build
@@ -0,0 +1,53 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(C) 2020 Marvell International Ltd.
+#
+
+if not is_linux
+	build = false
+	reason = 'only supported on Linux'
+endif
+
+path = get_option('ree_compiler_sdk')
+lib_dir = path + '/lib'
+inc_dir = path + '/include'
+
+if dpdk_conf.has('RTE_LIBRTE_PMD_OCTEONTX2_REGEX_COMPILER')
+	lib = cc.find_library('librxp_compiler', dirs : [lib_dir], required: false)
+	if not lib.found()
+		build = false
+		reason = 'missing dependency, "librxp_compiler"'
+	else
+		ext_deps += lib
+		ext_deps += cc.find_library('libstdc++', required: true)
+		includes += include_directories(inc_dir)
+		cflags += ['-DREE_COMPILER_SDK']
+	endif
+endif
+
+sources = files('otx2_regexdev.c',
+		'otx2_regexdev_hw_access.c',
+		'otx2_regexdev_mbox.c',
+		'otx2_regexdev_compiler.c'
+		)
+
+extra_flags = []
+# This integrated controller runs only on a arm64 machine, remove 32bit warnings
+if not dpdk_conf.get('RTE_ARCH_64')
+	extra_flags += ['-Wno-int-to-pointer-cast', '-Wno-pointer-to-int-cast']
+endif
+
+# for clang 32-bit compiles we need libatomic for 64-bit atomic ops
+if cc.get_id() == 'clang' and dpdk_conf.get('RTE_ARCH_64') == false
+	ext_deps += cc.find_library('atomic')
+endif
+
+foreach flag: extra_flags
+	if cc.has_argument(flag)
+		cflags += flag
+	endif
+endforeach
+
+name = 'octeontx2_regex'
+deps += ['bus_pci', 'common_octeontx2', 'regexdev']
+
+includes += include_directories('../../common/octeontx2')
diff --git a/drivers/regex/octeontx2/otx2_regexdev.c b/drivers/regex/octeontx2/otx2_regexdev.c
new file mode 100644
index 000000000..2aebd0138
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev.c
@@ -0,0 +1,1001 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include <rte_malloc.h>
+#include <rte_memzone.h>
+#include <rte_regexdev.h>
+#include <rte_regexdev_core.h>
+#include <rte_regexdev_driver.h>
+
+/* REE common headers */
+#include "otx2_common.h"
+#include "otx2_dev.h"
+#include "otx2_regexdev.h"
+#include "otx2_regexdev_compiler.h"
+#include "otx2_regexdev_hw_access.h"
+#include "otx2_regexdev_mbox.h"
+
+
+/* HW matches are at offset 0x80 from RES_PTR_ADDR
+ * In op structure matches starts at W5 (0x28)
+ * There is a need to copy to 0x28 to 0x80 The matches that are at the tail
+ * Which are 88 B. Each match holds 8 B, so up to 11 matches can be copied
+ */
+#define REE_NUM_MATCHES_ALIGN	11
+/* The REE co-processor will write up to 254 job match structures
+ * (REE_MATCH_S) starting at address [RES_PTR_ADDR] + 0x80.
+ */
+#define REE_MATCH_OFFSET	0x80
+
+#define REE_MAX_RULES_PER_GROUP 0xFFFF
+#define REE_MAX_GROUPS 0xFFFF
+
+/* This is temporarily here */
+#define REE0_PF	19
+#define REE1_PF	20
+
+#define REE_RULE_DB_VERSION	2
+#define REE_RULE_DB_REVISION	0
+
+struct ree_rule_db_entry {
+	uint8_t		type;
+	uint32_t	addr;
+	uint64_t	value;
+};
+
+struct ree_rule_db {
+	uint32_t version;
+	uint32_t revision;
+	uint32_t number_of_entries;
+	struct ree_rule_db_entry entries[];
+} __rte_packed;
+
+static void
+qp_memzone_name_get(char *name, int size, int dev_id, int qp_id)
+{
+	snprintf(name, size, "otx2_ree_lf_mem_%u:%u", dev_id, qp_id);
+}
+
+static struct otx2_ree_qp *
+ree_qp_create(const struct rte_regexdev *dev, uint16_t qp_id)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	uint64_t pg_sz = sysconf(_SC_PAGESIZE);
+	struct otx2_ree_vf *vf = &data->vf;
+	const struct rte_memzone *lf_mem;
+	uint32_t len, iq_len, size_div2;
+	char name[RTE_MEMZONE_NAMESIZE];
+	uint64_t used_len, iova;
+	struct otx2_ree_qp *qp;
+	uint8_t *va;
+	int ret;
+
+	/* Allocate queue pair */
+	qp = rte_zmalloc("OCTEON TX2 Regex PMD Queue Pair", sizeof(*qp),
+				OTX2_ALIGN);
+	if (qp == NULL) {
+		otx2_err("Could not allocate queue pair");
+		return NULL;
+	}
+
+	iq_len = OTX2_REE_IQ_LEN;
+
+	/*
+	 * Queue size must be in units of 128B 2 * REE_INST_S (which is 64B),
+	 * and a power of 2.
+	 * effective queue size to software is (size - 1) * 128
+	 */
+	size_div2 = iq_len >> 1;
+
+	/* For pending queue */
+	len = iq_len * RTE_ALIGN(sizeof(struct otx2_ree_rid), 8);
+
+	/* So that instruction queues start as pg size aligned */
+	len = RTE_ALIGN(len, pg_sz);
+
+	/* For instruction queues */
+	len += OTX2_REE_IQ_LEN * sizeof(union otx2_ree_inst);
+
+	/* Waste after instruction queues */
+	len = RTE_ALIGN(len, pg_sz);
+
+	qp_memzone_name_get(name, RTE_MEMZONE_NAMESIZE, dev->data->dev_id,
+			    qp_id);
+
+	lf_mem = rte_memzone_reserve_aligned(name, len, vf->otx2_dev.node,
+			RTE_MEMZONE_SIZE_HINT_ONLY | RTE_MEMZONE_256MB,
+			RTE_CACHE_LINE_SIZE);
+	if (lf_mem == NULL) {
+		otx2_err("Could not allocate reserved memzone");
+		goto qp_free;
+	}
+
+	va = lf_mem->addr;
+	iova = lf_mem->iova;
+
+	memset(va, 0, len);
+
+	/* Initialize pending queue */
+	qp->pend_q.rid_queue = (struct otx2_ree_rid *)va;
+	qp->pend_q.enq_tail = 0;
+	qp->pend_q.deq_head = 0;
+	qp->pend_q.pending_count = 0;
+
+	used_len = iq_len * RTE_ALIGN(sizeof(struct otx2_ree_rid), 8);
+	used_len = RTE_ALIGN(used_len, pg_sz);
+	iova += used_len;
+
+	qp->iq_dma_addr = iova;
+	qp->id = qp_id;
+	qp->base = OTX2_REE_LF_BAR2(vf, qp_id);
+	qp->otx2_regexdev_jobid = 0;
+	qp->write_offset = 0;
+
+	ret = otx2_ree_iq_enable(dev, qp, OTX2_REE_QUEUE_HI_PRIO, size_div2);
+	if (ret) {
+		otx2_err("Could not enable instruction queue");
+		goto qp_free;
+	}
+
+	return qp;
+
+qp_free:
+	rte_free(qp);
+	return NULL;
+}
+
+static int
+ree_qp_destroy(const struct rte_regexdev *dev, struct otx2_ree_qp *qp)
+{
+	const struct rte_memzone *lf_mem;
+	char name[RTE_MEMZONE_NAMESIZE];
+	int ret;
+
+	otx2_ree_iq_disable(qp);
+
+	qp_memzone_name_get(name, RTE_MEMZONE_NAMESIZE, dev->data->dev_id,
+			    qp->id);
+
+	lf_mem = rte_memzone_lookup(name);
+
+	ret = rte_memzone_free(lf_mem);
+	if (ret)
+		return ret;
+
+	rte_free(qp);
+
+	return 0;
+}
+
+static int
+ree_queue_pair_release(struct rte_regexdev *dev, uint16_t qp_id)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_qp *qp = data->queue_pairs[qp_id];
+	int ret;
+
+	ree_func_trace("Queue=%d", qp_id);
+
+	if (qp == NULL)
+		return -EINVAL;
+
+	ret = ree_qp_destroy(dev, qp);
+	if (ret) {
+		otx2_err("Could not destroy queue pair %d", qp_id);
+		return ret;
+	}
+
+	data->queue_pairs[qp_id] = NULL;
+
+	return 0;
+}
+
+static struct rte_regexdev *
+ree_dev_register(const char *name)
+{
+	struct rte_regexdev *dev;
+
+	otx2_ree_dbg("Creating regexdev %s\n", name);
+
+	/* allocate device structure */
+	dev = rte_regexdev_register(name);
+	if (dev == NULL) {
+		otx2_err("Failed to allocate regex device for %s", name);
+		return NULL;
+	}
+
+	/* allocate private device structure */
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		dev->data->dev_private =
+				rte_zmalloc_socket("regexdev device private",
+						sizeof(struct otx2_ree_data),
+						RTE_CACHE_LINE_SIZE,
+						rte_socket_id());
+
+		if (dev->data->dev_private == NULL) {
+			otx2_err("Cannot allocate memory for dev %s private data",
+					name);
+
+			rte_regexdev_unregister(dev);
+			return NULL;
+		}
+	}
+
+	return dev;
+}
+
+static int
+ree_dev_unregister(struct rte_regexdev *dev)
+{
+	otx2_ree_dbg("Closing regex device %s", dev->device->name);
+
+	/* free regex device */
+	rte_regexdev_unregister(dev);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(dev->data->dev_private);
+
+	return 0;
+}
+
+static int
+ree_dev_fini(struct rte_regexdev *dev)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct rte_pci_device *pci_dev;
+	int i, ret;
+
+	ree_func_trace();
+
+	for (i = 0; i < data->nb_queue_pairs; i++) {
+		ret = ree_queue_pair_release(dev, i);
+		if (ret)
+			return ret;
+	}
+
+	ret = otx2_ree_queues_detach(dev);
+	if (ret)
+		otx2_err("Could not detach queues");
+
+	/* TEMP : should be in lib */
+	if (data->queue_pairs)
+		rte_free(data->queue_pairs);
+	if (data->rules)
+		rte_free(data->rules);
+
+	pci_dev = container_of(dev->device, struct rte_pci_device, device);
+	otx2_dev_fini(pci_dev, &(data->vf.otx2_dev));
+
+	ret = ree_dev_unregister(dev);
+	if (ret)
+		otx2_err("Could not destroy PMD");
+
+	return ret;
+}
+
+static inline int
+ree_enqueue(struct otx2_ree_qp *qp, struct rte_regex_ops *op,
+		 struct otx2_ree_pending_queue *pend_q)
+{
+	union otx2_ree_inst inst;
+	union otx2_ree_res *res;
+	uint32_t offset;
+
+	if (unlikely(pend_q->pending_count >= OTX2_REE_DEFAULT_CMD_QLEN)) {
+		otx2_err("Pending count %" PRIu64 " is greater than Q size %d",
+		pend_q->pending_count, OTX2_REE_DEFAULT_CMD_QLEN);
+		return -EAGAIN;
+	}
+	if (unlikely(op->mbuf->data_len > OTX2_REE_MAX_PAYLOAD_SIZE ||
+			op->mbuf->data_len == 0)) {
+		otx2_err("Packet length %d is greater than MAX payload %d",
+				op->mbuf->data_len, OTX2_REE_MAX_PAYLOAD_SIZE);
+		return -EAGAIN;
+	}
+
+	/* W 0 */
+	inst.cn98xx.ooj = 1;
+	inst.cn98xx.dg = 0;
+	inst.cn98xx.doneint = 0;
+	/* W 1 */
+	inst.cn98xx.inp_ptr_addr = rte_pktmbuf_mtod(op->mbuf, uint64_t);
+	/* W 2 */
+	inst.cn98xx.inp_ptr_ctl = op->mbuf->data_len & 0x7FFF;
+	inst.cn98xx.inp_ptr_ctl = inst.cn98xx.inp_ptr_ctl << 32;
+
+	/* W 3 */
+	inst.cn98xx.res_ptr_addr = (uint64_t)op;
+	/* W 4 */
+	inst.cn98xx.wq_ptr = 0;
+	/* W 5 */
+	inst.cn98xx.ggrp = 0;
+	inst.cn98xx.tt = 0;
+	inst.cn98xx.tag = 0;
+	/* W 6 */
+	inst.cn98xx.ree_job_length = op->mbuf->data_len & 0x7FFF;
+	if (op->req_flags & RTE_REGEX_OPS_REQ_STOP_ON_MATCH_F)
+		inst.cn98xx.ree_job_ctrl = (0x2 << 8);
+	else if (op->req_flags & RTE_REGEX_OPS_REQ_MATCH_HIGH_PRIORITY_F)
+		inst.cn98xx.ree_job_ctrl = (0x1 << 8);
+	else
+		inst.cn98xx.ree_job_ctrl = 0;
+	inst.cn98xx.ree_job_id = qp->otx2_regexdev_jobid;
+	/* W 7 */
+	inst.cn98xx.ree_job_subset_id_0 = op->group_id0;
+	if (op->req_flags & RTE_REGEX_OPS_REQ_GROUP_ID1_VALID_F)
+		inst.cn98xx.ree_job_subset_id_1 = op->group_id1;
+	else
+		inst.cn98xx.ree_job_subset_id_1 = op->group_id0;
+	if (op->req_flags & RTE_REGEX_OPS_REQ_GROUP_ID2_VALID_F)
+		inst.cn98xx.ree_job_subset_id_2 = op->group_id2;
+	else
+		inst.cn98xx.ree_job_subset_id_2 = op->group_id0;
+	if (op->req_flags & RTE_REGEX_OPS_REQ_GROUP_ID3_VALID_F)
+		inst.cn98xx.ree_job_subset_id_3 = op->group_id3;
+	else
+		inst.cn98xx.ree_job_subset_id_3 = op->group_id0;
+
+	/* Copy REE command to Q */
+	offset = qp->write_offset * sizeof(inst);
+	memcpy((void *)(qp->iq_dma_addr + offset), &inst, sizeof(inst));
+
+	pend_q->rid_queue[pend_q->enq_tail].rid = (uintptr_t)op;
+	pend_q->rid_queue[pend_q->enq_tail].user_id = op->user_id;
+
+	/* Mark result as not done */
+	res = (union otx2_ree_res *)(op);
+	res->s.done = 0;
+	res->s.ree_err = 0;
+
+	/* We will use soft queue length here to limit requests */
+	REE_MOD_INC(pend_q->enq_tail, OTX2_REE_DEFAULT_CMD_QLEN);
+	pend_q->pending_count += 1;
+	REE_MOD_INC(qp->otx2_regexdev_jobid, 0xFFFFFF);
+	REE_MOD_INC(qp->write_offset, OTX2_REE_IQ_LEN);
+
+	return 0;
+}
+
+static uint16_t
+otx2_ree_enqueue_burst(struct rte_regexdev *dev, uint16_t qp_id,
+		       struct rte_regex_ops **ops, uint16_t nb_ops)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_qp *qp = data->queue_pairs[qp_id];
+	struct otx2_ree_pending_queue *pend_q;
+	uint16_t nb_allowed, count = 0;
+	struct rte_regex_ops *op;
+	int ret;
+
+	pend_q = &qp->pend_q;
+
+	nb_allowed = OTX2_REE_DEFAULT_CMD_QLEN - pend_q->pending_count;
+	if (nb_ops > nb_allowed)
+		nb_ops = nb_allowed;
+
+	for (count = 0; count < nb_ops; count++) {
+		op = ops[count];
+		ret = ree_enqueue(qp, op, pend_q);
+
+		if (unlikely(ret))
+			break;
+	}
+
+	/*
+	 * Make sure all instructions are written before DOORBELL is activated
+	 */
+	rte_cio_wmb();
+
+	/* Update Doorbell */
+	otx2_write64(count, qp->base + OTX2_REE_LF_DOORBELL);
+
+	return count;
+}
+
+static inline void
+ree_dequeue_post_process(struct rte_regex_ops *ops)
+{
+	uint8_t ree_res_mcnt, ree_res_dmcnt;
+	int off = REE_MATCH_OFFSET;
+	struct ree_res_s_98 *res;
+	uint16_t ree_res_status;
+	uint64_t match;
+
+	res = (struct ree_res_s_98 *)ops;
+	/* store res values on stack since ops and res
+	 * are using the same memory
+	 */
+	ree_res_status = res->ree_res_status;
+	ree_res_mcnt = res->ree_res_mcnt;
+	ree_res_dmcnt = res->ree_res_dmcnt;
+	ops->rsp_flags = 0;
+	ops->nb_actual_matches = ree_res_dmcnt;
+	ops->nb_matches = ree_res_mcnt;
+	if (unlikely(res->ree_err)) {
+		ops->nb_actual_matches = 0;
+		ops->nb_matches = 0;
+	}
+
+	if (unlikely(ree_res_status != REE_TYPE_RESULT_DESC)) {
+		if (ree_res_status & OTX2_REE_STATUS_PMI_SOJ_BIT)
+			ops->rsp_flags |= RTE_REGEX_OPS_RSP_PMI_SOJ_F;
+		if (ree_res_status & OTX2_REE_STATUS_PMI_EOJ_BIT)
+			ops->rsp_flags |= RTE_REGEX_OPS_RSP_PMI_EOJ_F;
+		if (ree_res_status & OTX2_REE_STATUS_ML_CNT_DET_BIT)
+			ops->rsp_flags |= RTE_REGEX_OPS_RSP_MAX_SCAN_TIMEOUT_F;
+		if (ree_res_status & OTX2_REE_STATUS_MM_CNT_DET_BIT)
+			ops->rsp_flags |= RTE_REGEX_OPS_RSP_MAX_MATCH_F;
+		if (ree_res_status & OTX2_REE_STATUS_MP_CNT_DET_BIT)
+			ops->rsp_flags |= RTE_REGEX_OPS_RSP_MAX_PREFIX_F;
+	}
+	if (ops->nb_matches > 0) {
+		/* Move the matches to the correct offset */
+		off = ((ops->nb_matches < REE_NUM_MATCHES_ALIGN) ?
+			ops->nb_matches : REE_NUM_MATCHES_ALIGN);
+		match = (uint64_t)ops + REE_MATCH_OFFSET;
+		match += (ops->nb_matches - off) *
+			sizeof(union otx2_ree_match);
+		memcpy((void *)ops->matches, (void *)match,
+			off * sizeof(union otx2_ree_match));
+	}
+}
+
+static uint16_t
+otx2_ree_dequeue_burst(struct rte_regexdev *dev, uint16_t qp_id,
+		       struct rte_regex_ops **ops, uint16_t nb_ops)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_qp *qp = data->queue_pairs[qp_id];
+	struct otx2_ree_pending_queue *pend_q;
+	int i, nb_pending, nb_completed = 0;
+	volatile struct ree_res_s_98 *res;
+	struct otx2_ree_rid *rid;
+
+	pend_q = &qp->pend_q;
+
+	nb_pending = pend_q->pending_count;
+
+	if (nb_ops > nb_pending)
+		nb_ops = nb_pending;
+
+	for (i = 0; i < nb_ops; i++) {
+		rid = &pend_q->rid_queue[pend_q->deq_head];
+		res = (volatile struct ree_res_s_98 *)(rid->rid);
+
+		/* Check response header done bit if completed */
+		if (unlikely(!res->done))
+			break;
+
+		ops[i] = (struct rte_regex_ops *)(rid->rid);
+		ops[i]->user_id = rid->user_id;
+
+		REE_MOD_INC(pend_q->deq_head, OTX2_REE_DEFAULT_CMD_QLEN);
+		pend_q->pending_count -= 1;
+	}
+
+	nb_completed = i;
+
+	for (i = 0; i < nb_completed; i++)
+		ree_dequeue_post_process(ops[i]);
+
+	return nb_completed;
+}
+
+static int
+otx2_ree_dev_info_get(struct rte_regexdev *dev, struct rte_regexdev_info *info)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+
+	ree_func_trace();
+
+	if (info == NULL)
+		return -EINVAL;
+
+	info->driver_name = dev->device->driver->name;
+	info->dev = dev->device;
+
+	info->max_queue_pairs = vf->max_queues;
+	info->max_matches = vf->max_matches;
+	info->max_payload_size = OTX2_REE_MAX_PAYLOAD_SIZE;
+	info->max_rules_per_group = data->max_rules_per_group;
+	info->max_groups = data->max_groups;
+	info->regexdev_capa = data->regexdev_capa;
+	info->rule_flags = data->rule_flags;
+
+	return 0;
+}
+
+static int
+otx2_ree_dev_config(struct rte_regexdev *dev,
+		    const struct rte_regexdev_config *cfg)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	const struct ree_rule_db *rule_db;
+	uint32_t rule_db_len;
+	int ret;
+
+	ree_func_trace();
+
+	if (cfg->nb_queue_pairs > vf->max_queues) {
+		otx2_err("Invalid number of queue pairs requested");
+		return -EINVAL;
+	}
+
+	if (cfg->nb_max_matches != vf->max_matches) {
+		otx2_err("Invalid number of max matches requested");
+		return -EINVAL;
+	}
+
+	if (cfg->dev_cfg_flags != 0) {
+		otx2_err("Invalid device configuration flags requested");
+		return -EINVAL;
+	}
+
+	/* Unregister error interrupts */
+	if (vf->err_intr_registered)
+		otx2_ree_err_intr_unregister(dev);
+
+	/* Detach queues */
+	if (vf->nb_queues) {
+		ret = otx2_ree_queues_detach(dev);
+		if (ret) {
+			otx2_err("Could not detach REE queues");
+			return ret;
+		}
+	}
+
+	/* TEMP : should be in lib */
+	if (data->queue_pairs == NULL) { /* first time configuration */
+		data->queue_pairs = rte_zmalloc("regexdev->queue_pairs",
+				sizeof(data->queue_pairs[0]) *
+				cfg->nb_queue_pairs, RTE_CACHE_LINE_SIZE);
+
+		if (data->queue_pairs == NULL) {
+			data->nb_queue_pairs = 0;
+			otx2_err("Failed to get memory for qp meta data, nb_queues %u",
+					cfg->nb_queue_pairs);
+			return -ENOMEM;
+		}
+	} else { /* re-configure */
+		uint16_t old_nb_queues = data->nb_queue_pairs;
+		void **qp;
+		unsigned int i;
+
+		qp = data->queue_pairs;
+
+		for (i = cfg->nb_queue_pairs; i < old_nb_queues; i++) {
+			ret = ree_queue_pair_release(dev, i);
+			if (ret < 0)
+				return ret;
+		}
+
+		qp = rte_realloc(qp, sizeof(qp[0]) * cfg->nb_queue_pairs,
+				RTE_CACHE_LINE_SIZE);
+		if (qp == NULL) {
+			otx2_err("Failed to realloc qp meta data, nb_queues %u",
+					cfg->nb_queue_pairs);
+			return -ENOMEM;
+		}
+
+		if (cfg->nb_queue_pairs > old_nb_queues) {
+			uint16_t new_qs = cfg->nb_queue_pairs - old_nb_queues;
+			memset(qp + old_nb_queues, 0, sizeof(qp[0]) * new_qs);
+		}
+
+		data->queue_pairs = qp;
+	}
+	data->nb_queue_pairs = cfg->nb_queue_pairs;
+
+	/* Attach queues */
+	otx2_ree_dbg("Attach %d queues", cfg->nb_queue_pairs);
+	ret = otx2_ree_queues_attach(dev, cfg->nb_queue_pairs);
+	if (ret) {
+		otx2_err("Could not attach queues");
+		return -ENODEV;
+	}
+
+	ret = otx2_ree_msix_offsets_get(dev);
+	if (ret) {
+		otx2_err("Could not get MSI-X offsets");
+		goto queues_detach;
+	}
+
+	if (cfg->rule_db && cfg->rule_db_len) {
+		otx2_ree_dbg("rule_db length %d", cfg->rule_db_len);
+		rule_db = (const struct ree_rule_db *)cfg->rule_db;
+		rule_db_len = rule_db->number_of_entries *
+				sizeof(struct ree_rule_db_entry);
+		otx2_ree_dbg("rule_db number of entries %d",
+				rule_db->number_of_entries);
+		if (rule_db_len > cfg->rule_db_len) {
+			otx2_err("Could not program rule db");
+			ret = -EINVAL;
+			goto queues_detach;
+		}
+		ret = otx2_ree_rule_db_prog(dev, (const char *)rule_db->entries,
+				rule_db_len, NULL, OTX2_REE_NON_INC_PROG);
+		if (ret) {
+			otx2_err("Could not program rule db");
+			goto queues_detach;
+		}
+	}
+
+	dev->enqueue = otx2_ree_enqueue_burst;
+	dev->dequeue = otx2_ree_dequeue_burst;
+
+	rte_mb();
+	return 0;
+
+queues_detach:
+	otx2_ree_queues_detach(dev);
+	return ret;
+}
+
+static int
+otx2_ree_stop(struct rte_regexdev *dev)
+{
+	RTE_SET_USED(dev);
+
+	ree_func_trace();
+	return 0;
+}
+
+static int
+otx2_ree_start(struct rte_regexdev *dev)
+{
+	uint32_t rule_db_len = 0;
+	int ret;
+
+	ree_func_trace();
+
+	ret = otx2_ree_rule_db_len_get(dev, &rule_db_len, NULL);
+	if (ret)
+		return ret;
+	if (rule_db_len == 0) {
+		otx2_err("Rule db not programmed");
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+static int
+otx2_ree_close(struct rte_regexdev *dev)
+{
+	return ree_dev_fini(dev);
+}
+
+static int
+otx2_ree_queue_pair_setup(struct rte_regexdev *dev, uint16_t qp_id,
+		const struct rte_regexdev_qp_conf *qp_conf)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_qp *qp;
+
+	ree_func_trace("Queue=%d", qp_id);
+
+	if (data->queue_pairs[qp_id] != NULL)
+		ree_queue_pair_release(dev, qp_id);
+
+	if (qp_conf->nb_desc > OTX2_REE_DEFAULT_CMD_QLEN) {
+		otx2_err("Could not setup queue pair for %u descriptors",
+				qp_conf->nb_desc);
+		return -EINVAL;
+	}
+	if (qp_conf->qp_conf_flags != 0) {
+		otx2_err("Could not setup queue pair with configuration flags 0x%x",
+				qp_conf->qp_conf_flags);
+		return -EINVAL;
+	}
+
+	qp = ree_qp_create(dev, qp_id);
+	if (qp == NULL) {
+		otx2_err("Could not create queue pair %d", qp_id);
+		return -ENOMEM;
+	}
+	qp->cb = qp_conf->cb;
+	data->queue_pairs[qp_id] = qp;
+
+	return 0;
+}
+
+static int
+otx2_ree_rule_db_compile_activate(struct rte_regexdev *dev)
+{
+	return otx2_ree_rule_db_compile_prog(dev);
+}
+
+static int
+otx2_ree_rule_db_update(struct rte_regexdev *dev,
+		const struct rte_regexdev_rule *rules, uint16_t nb_rules)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct rte_regexdev_rule *old_ptr;
+	uint32_t i, sum_nb_rules;
+
+	ree_func_trace("nb_rules=%d", nb_rules);
+
+	for (i = 0; i < nb_rules; i++) {
+		if (rules[i].op == RTE_REGEX_RULE_OP_REMOVE)
+			break;
+		if (rules[i].group_id >= data->max_groups)
+			break;
+		if (rules[i].rule_id >= data->max_rules_per_group)
+			break;
+		/* logical implication
+		 * p    q    p -> q
+		 * 0    0      1
+		 * 0    1      1
+		 * 1    0      0
+		 * 1    1      1
+		 */
+		if ((~(rules[i].rule_flags) | data->rule_flags) == 0)
+			break;
+	}
+	nb_rules = i;
+
+	if (data->nb_rules == 0) {
+
+		data->rules = rte_malloc("rte_regexdev_rules",
+				nb_rules*sizeof(struct rte_regexdev_rule), 0);
+		if (data->rules == NULL)
+			return -ENOMEM;
+
+		memcpy(data->rules, rules,
+				nb_rules*sizeof(struct rte_regexdev_rule));
+		data->nb_rules = nb_rules;
+	} else {
+
+		old_ptr = data->rules;
+		sum_nb_rules = data->nb_rules + nb_rules;
+		data->rules = rte_realloc(data->rules,
+				sum_nb_rules * sizeof(struct rte_regexdev_rule),
+							0);
+		if (data->rules == NULL) {
+			data->rules = old_ptr;
+			return -ENOMEM;
+		}
+		memcpy(&data->rules[data->nb_rules], rules,
+				nb_rules*sizeof(struct rte_regexdev_rule));
+		data->nb_rules = sum_nb_rules;
+	}
+	return nb_rules;
+}
+
+static int
+otx2_ree_rule_db_import(struct rte_regexdev *dev, const char *rule_db,
+		uint32_t rule_db_len)
+{
+
+	const struct ree_rule_db *ree_rule_db;
+	uint32_t ree_rule_db_len;
+	int ret;
+
+	ree_func_trace("rule_db_len=%d", rule_db_len);
+
+	ree_rule_db = (const struct ree_rule_db *)rule_db;
+	ree_rule_db_len = ree_rule_db->number_of_entries *
+			sizeof(struct ree_rule_db_entry);
+	if (ree_rule_db_len > rule_db_len) {
+		otx2_err("Could not program rule db");
+		return -EINVAL;
+	}
+	ret = otx2_ree_rule_db_prog(dev, (const char *)ree_rule_db->entries,
+			ree_rule_db_len, NULL, OTX2_REE_NON_INC_PROG);
+	if (ret) {
+		otx2_err("Could not program rule db");
+		return -ENOSPC;
+	}
+	return 0;
+}
+
+static int
+otx2_ree_rule_db_export(struct rte_regexdev *dev, char *rule_db)
+{
+	struct ree_rule_db *ree_rule_db;
+	uint32_t rule_dbi_len;
+	uint32_t rule_db_len;
+	int ret;
+
+	ree_func_trace();
+
+	ret = otx2_ree_rule_db_len_get(dev, &rule_db_len, &rule_dbi_len);
+	if (ret)
+		return ret;
+
+	if (rule_db == NULL) {
+		rule_db_len += sizeof(struct ree_rule_db);
+		return rule_db_len;
+	}
+
+	ree_rule_db = (struct ree_rule_db *)rule_db;
+	ret = otx2_ree_rule_db_get(dev, (char *)ree_rule_db->entries,
+			rule_db_len, NULL, 0);
+	if (ret) {
+		otx2_err("Could not export rule db");
+		return -EFAULT;
+	}
+	ree_rule_db->number_of_entries =
+			rule_db_len/sizeof(struct ree_rule_db_entry);
+	ree_rule_db->revision = REE_RULE_DB_REVISION;
+	ree_rule_db->version = REE_RULE_DB_VERSION;
+
+	return 0;
+}
+
+static int
+ree_get_blkaddr(struct otx2_dev *dev)
+{
+	int pf;
+
+	pf = otx2_get_pf(dev->pf_func);
+	if (pf == REE0_PF)
+		return RVU_BLOCK_ADDR_REE0;
+	else if (pf == REE1_PF)
+		return RVU_BLOCK_ADDR_REE1;
+	else
+		return 0;
+}
+
+static struct rte_regexdev_ops otx2_ree_ops = {
+		.dev_info_get = otx2_ree_dev_info_get,
+		.dev_configure = otx2_ree_dev_config,
+		.dev_qp_setup = otx2_ree_queue_pair_setup,
+		.dev_start = otx2_ree_start,
+		.dev_stop = otx2_ree_stop,
+		.dev_close = otx2_ree_close,
+		.dev_attr_get = NULL,
+		.dev_attr_set = NULL,
+		.dev_rule_db_update = otx2_ree_rule_db_update,
+		.dev_rule_db_compile_activate =
+				otx2_ree_rule_db_compile_activate,
+		.dev_db_import = otx2_ree_rule_db_import,
+		.dev_db_export = otx2_ree_rule_db_export,
+		.dev_xstats_names_get = NULL,
+		.dev_xstats_get = NULL,
+		.dev_xstats_by_name_get = NULL,
+		.dev_xstats_reset = NULL,
+		.dev_selftest = NULL,
+		.dev_dump = NULL,
+};
+
+static int
+otx2_ree_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
+		   struct rte_pci_device *pci_dev)
+{
+	char name[RTE_REGEXDEV_NAME_MAX_LEN];
+	struct otx2_ree_data *data;
+	struct otx2_dev *otx2_dev;
+	struct rte_regexdev *dev;
+	uint8_t max_matches = 0;
+	struct otx2_ree_vf *vf;
+	uint16_t nb_queues = 0;
+	int ret;
+
+	rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
+
+	dev = ree_dev_register(name);
+	if (dev == NULL) {
+		ret = -ENODEV;
+		goto exit;
+	}
+
+	dev->dev_ops = &otx2_ree_ops;
+	dev->device = &pci_dev->device;
+
+	/* Get private data space allocated */
+	data = dev->data->dev_private;
+	vf = &data->vf;
+
+	otx2_dev = &vf->otx2_dev;
+
+	/* Initialize the base otx2_dev object */
+	ret = otx2_dev_init(pci_dev, otx2_dev);
+	if (ret) {
+		otx2_err("Could not initialize otx2_dev");
+		goto dev_unregister;
+	}
+	/* Get REE block address */
+	vf->block_address = ree_get_blkaddr(otx2_dev);
+	if (!vf->block_address) {
+		otx2_err("Could not determine block PF number");
+		goto otx2_dev_fini;
+	}
+
+	/* Get number of queues available on the device */
+	ret = otx2_ree_available_queues_get(dev, &nb_queues);
+	if (ret) {
+		otx2_err("Could not determine the number of queues available");
+		goto otx2_dev_fini;
+	}
+
+	/* Don't exceed the limits set per VF */
+	nb_queues = RTE_MIN(nb_queues, OTX2_REE_MAX_QUEUES_PER_VF);
+
+	if (nb_queues == 0) {
+		otx2_err("No free queues available on the device");
+		goto otx2_dev_fini;
+	}
+
+	vf->max_queues = nb_queues;
+
+	otx2_ree_dbg("Max queues supported by device: %d", vf->max_queues);
+
+	/* Get number of maximum matches supported on the device */
+	ret = otx2_ree_max_matches_get(dev, &max_matches);
+	if (ret) {
+		otx2_err("Could not determine the maximum matches supported");
+		goto otx2_dev_fini;
+	}
+	/* Don't exceed the limits set per VF */
+	max_matches = RTE_MIN(max_matches, OTX2_REE_MAX_MATCHES_PER_VF);
+	if (max_matches == 0) {
+		otx2_err("Could not determine the maximum matches supported");
+		goto otx2_dev_fini;
+	}
+
+	vf->max_matches = max_matches;
+
+	otx2_ree_dbg("Max matches supported by device: %d", vf->max_matches);
+	data->rule_flags = RTE_REGEX_PCRE_RULE_ALLOW_EMPTY_F |
+			RTE_REGEX_PCRE_RULE_ANCHORED_F;
+	data->regexdev_capa = 0;
+	data->max_groups = REE_MAX_GROUPS;
+	data->max_rules_per_group = REE_MAX_RULES_PER_GROUP;
+	data->nb_rules = 0;
+
+	dev->state = RTE_REGEXDEV_READY;
+	return 0;
+
+otx2_dev_fini:
+	otx2_dev_fini(pci_dev, otx2_dev);
+dev_unregister:
+	ree_dev_unregister(dev);
+exit:
+	otx2_err("Could not create device (vendor_id: 0x%x device_id: 0x%x)",
+		    pci_dev->id.vendor_id, pci_dev->id.device_id);
+	return ret;
+}
+
+static int
+otx2_ree_pci_remove(struct rte_pci_device *pci_dev)
+{
+	char name[RTE_REGEXDEV_NAME_MAX_LEN];
+	struct rte_regexdev *dev = NULL;
+
+	if (pci_dev == NULL)
+		return -EINVAL;
+
+	rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
+
+	dev = rte_regexdev_get_device_by_name(name);
+
+	if (dev == NULL)
+		return -ENODEV;
+
+	return ree_dev_fini(dev);
+}
+
+static struct rte_pci_id pci_id_ree_table[] = {
+	{
+		RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM,
+				PCI_DEVID_OCTEONTX2_RVU_REE_PF)
+	},
+};
+
+static struct rte_pci_driver otx2_regexdev_pmd = {
+	.id_table = pci_id_ree_table,
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING,
+	.probe = otx2_ree_pci_probe,
+	.remove = otx2_ree_pci_remove,
+};
+
+
+RTE_PMD_REGISTER_PCI(REGEXDEV_NAME_OCTEONTX2_PMD, otx2_regexdev_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(REGEXDEV_NAME_OCTEONTX2_PMD, pci_id_ree_table);
diff --git a/drivers/regex/octeontx2/otx2_regexdev.h b/drivers/regex/octeontx2/otx2_regexdev.h
new file mode 100644
index 000000000..d710535f5
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev.h
@@ -0,0 +1,109 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _OTX2_REGEXDEV_H_
+#define _OTX2_REGEXDEV_H_
+
+#include <rte_common.h>
+#include <rte_regexdev.h>
+
+#include "otx2_dev.h"
+
+#define ree_func_trace otx2_ree_dbg
+
+/* Marvell OCTEON TX2 Regex PMD device name */
+#define REGEXDEV_NAME_OCTEONTX2_PMD	regex_octeontx2
+
+#define OTX2_REE_MAX_LFS		36
+#define OTX2_REE_MAX_QUEUES_PER_VF	36
+#define OTX2_REE_MAX_MATCHES_PER_VF	254
+
+#define OTX2_REE_MAX_PAYLOAD_SIZE	(1 << 14)
+
+#define OTX2_REE_NON_INC_PROG 0
+#define OTX2_REE_INC_PROG 1
+
+#define REE_MOD_INC(i, l)   ((i) == (l - 1) ? (i) = 0 : (i)++)
+
+
+/**
+ * Device vf data
+ */
+struct otx2_ree_vf {
+	struct otx2_dev otx2_dev;
+	/**< Base class */
+	uint16_t max_queues;
+	/**< Max queues supported */
+	uint8_t nb_queues;
+	/**< Number of regex queues attached */
+	uint16_t max_matches;
+	/**<  Max matches supported*/
+	uint16_t lf_msixoff[OTX2_REE_MAX_LFS];
+	/**< MSI-X offsets */
+	uint8_t block_address;
+	/**< REE Block Address */
+	uint8_t err_intr_registered:1;
+	/**< Are error interrupts registered? */
+};
+
+/**
+ * Device private data
+ */
+struct otx2_ree_data {
+	uint32_t regexdev_capa;
+	uint64_t rule_flags;
+	/**< Feature flags exposes HW/SW features for the given device */
+	uint16_t max_rules_per_group;
+	/**< Maximum rules supported per subset by this device */
+	uint16_t max_groups;
+	/**< Maximum subset supported by this device */
+	void **queue_pairs;
+	/**< Array of pointers to queue pairs. */
+	uint16_t nb_queue_pairs;
+	/**< Number of device queue pairs. */
+	struct otx2_ree_vf vf;
+	/**< vf data */
+	struct rte_regexdev_rule *rules;
+	/**< rules to be compiled */
+	uint16_t nb_rules;
+	/**< number of rules */
+} __rte_cache_aligned;
+
+struct otx2_ree_rid {
+	uintptr_t rid;
+	/** Request id of a ree operation */
+	uint64_t user_id;
+	/* Client data */
+	/**< IOVA address of the pattern to be matched. */
+};
+
+struct otx2_ree_pending_queue {
+	uint64_t pending_count;
+	/** Pending requests count */
+	struct otx2_ree_rid *rid_queue;
+	/** Array of pending requests */
+	uint16_t enq_tail;
+	/** Tail of queue to be used for enqueue */
+	uint16_t deq_head;
+	/** Head of queue to be used for dequeue */
+};
+
+struct otx2_ree_qp {
+	uint32_t id;
+	/**< Queue pair id */
+	uintptr_t base;
+	/**< Base address where BAR is mapped */
+	struct otx2_ree_pending_queue pend_q;
+	/**< Pending queue */
+	rte_iova_t iq_dma_addr;
+	/**< Instruction queue address */
+	uint32_t otx2_regexdev_jobid;
+	/**< Job ID */
+	uint32_t write_offset;
+	/**< write offset */
+	regexdev_stop_flush_t cb;
+	/**< Callback function called during rte_regex_dev_stop()*/
+};
+
+#endif /* _OTX2_REGEXDEV_H_ */
diff --git a/drivers/regex/octeontx2/otx2_regexdev_compiler.c b/drivers/regex/octeontx2/otx2_regexdev_compiler.c
new file mode 100644
index 000000000..785459f74
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev_compiler.c
@@ -0,0 +1,229 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#include <rte_malloc.h>
+#include <rte_regexdev.h>
+
+#include "otx2_regexdev.h"
+#include "otx2_regexdev_compiler.h"
+#include "otx2_regexdev_mbox.h"
+
+#ifdef REE_COMPILER_SDK
+#include <rxp-compiler.h>
+
+static int
+ree_rule_db_compile(const struct rte_regexdev_rule *rules,
+		uint16_t nb_rules, struct rxp_rof **rof, struct rxp_rof **rofi,
+		struct rxp_rof *rof_for_incremental_compile,
+		struct rxp_rof *rofi_for_incremental_compile)
+{
+	/*INPUT*/
+	struct rxp_prefix_selection_control_list *prefix_selection_control_list
+		= NULL;
+	struct rxp_blacklist_data_sample *blacklist_sample_data = NULL;
+	struct rxp_rule_ids_to_remove *rule_ids_to_remove = NULL;
+	struct rxp_roff *roff_for_incremental_compile = NULL;
+
+	/*OPTIONS - setting default values*/
+	enum rxp_virtual_prefix_mode virtual_prefix_mode =
+			RXP_VIRTUAL_PREFIX_MODE_0;
+	enum rxp_prefix_capacity prefix_capacity = RXP_PREFIX_CAPACITY_32K;
+	/**< rxp_global_regex_options_flags*/
+	enum rxp_compiler_objective objective = RXP_COMPILER_OBJECTIVE_5;
+	enum rxp_tpe_data_width tpe_data_width = RXP_TPE_DATA_WIDTH_4;
+	uint32_t compiler_options = RXP_COMPILER_OPTIONS_FORCE;
+	/**< rxp_compiler_options_flags*/
+	enum rxp_verbose_level verbose = RXP_VERBOSE_LEVEL_3;
+	enum rxp_version set_rxp_version = RXP_VERSION_V5_8;
+	uint32_t compiler_output_flags = 0;
+	/**< rxp_compiler_output_flags*/
+	uint32_t global_regex_options = 0;
+	/**< rxp_global_regex_options_flags*/
+	float set_auto_blacklist = 0;
+	uint32_t max_rep_max = 65535;
+	uint32_t divide_ruleset = 1;
+	struct rxp_ruleset ruleset;
+	float ptpb_threshold = 0;
+	uint32_t set_max = 0;
+	uint32_t threads = 1;
+
+	/*OUTPUT*/
+	struct rxp_rule_direction_analysis *rule_direction_analysis = NULL;
+	struct rxp_compilation_statistics *compilation_statistics = NULL;
+	struct rxp_prefix_selection_control_list *generated_pscl = NULL;
+	struct rxp_uncompiled_rules_log *uncompiled_rules_log = NULL;
+	struct rxp_critical_rules_rank *critical_rules_rank = NULL;
+	struct rxp_compiled_rules_log *compiled_rules_log = NULL;
+	struct rxp_roff *roff = NULL;
+
+	uint16_t i;
+	int ret;
+
+	ruleset.number_of_entries = nb_rules;
+	ruleset.rules = rte_malloc("rxp_rule_entry",
+			nb_rules*sizeof(struct rxp_rule_entry), 0);
+
+	if (ruleset.rules == NULL) {
+		otx2_err("Could not allocate memory for rule compilation\n");
+		return -EFAULT;
+	}
+	if (rof_for_incremental_compile)
+		compiler_options |= RXP_COMPILER_OPTIONS_INCREMENTAL;
+	if (rofi_for_incremental_compile)
+		compiler_options |= RXP_COMPILER_OPTIONS_CHECKSUM;
+
+	for (i = 0; i < nb_rules; i++) {
+		ruleset.rules[i].number_of_prefix_entries = 0;
+		ruleset.rules[i].prefix = NULL;
+		ruleset.rules[i].rule = rules[i].pcre_rule;
+		ruleset.rules[i].rule_id = rules[i].rule_id;
+		ruleset.rules[i].subset_id = rules[i].group_id;
+		ruleset.rules[i].rule_direction_type =
+				RXP_RULE_DIRECTION_TYPE_NONE;
+	}
+
+	ret = rxp_compile_advanced(
+			/*INPUT*/
+			&ruleset,
+			prefix_selection_control_list,
+			rof_for_incremental_compile,
+			roff_for_incremental_compile,
+			rofi_for_incremental_compile,
+			rule_ids_to_remove,
+			blacklist_sample_data,
+
+			/*OPTIONS*/
+			compiler_options,
+			prefix_capacity,
+			global_regex_options,
+			set_auto_blacklist,
+			set_max,
+			objective,
+			ptpb_threshold,
+			max_rep_max,
+			threads,
+			set_rxp_version,
+			verbose,
+			tpe_data_width,
+			virtual_prefix_mode,
+			compiler_output_flags,
+			divide_ruleset,
+
+			/*OUTPUT*/
+			&compilation_statistics,
+			&compiled_rules_log,
+			&critical_rules_rank,
+			&rule_direction_analysis,
+			&uncompiled_rules_log,
+			rof,
+			&roff,
+			rofi,
+			&generated_pscl);
+	rte_free(ruleset.rules);
+
+	return ret;
+}
+
+int
+otx2_ree_rule_db_compile_prog(struct rte_regexdev *dev)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	char compiler_version[] = "20.5.2.eda0fa2";
+	char timestamp[] = "19700101_000001";
+	uint32_t rule_db_len, rule_dbi_len;
+	struct rxp_rof *rofi_inc_p = NULL;
+	struct rxp_rof_entry rule_dbi[6];
+	char *rofi_rof_entries = NULL;
+	struct rxp_rof *rofi = NULL;
+	struct rxp_rof *rof = NULL;
+	struct rxp_rof rofi_inc;
+	struct rxp_rof rof_inc;
+	char *rule_db = NULL;
+	int ret;
+
+	ree_func_trace();
+
+	ret = otx2_ree_rule_db_len_get(dev, &rule_db_len, &rule_dbi_len);
+	if (ret != 0) {
+		otx2_err("Could not get rule db length");
+		return ret;
+	}
+
+	if (rule_db_len > 0) {
+		otx2_ree_dbg("Incremental compile, rule db len %d rule dbi len %d",
+				rule_db_len, rule_dbi_len);
+		rule_db = rte_malloc("ree_rule_db", rule_db_len, 0);
+		if (!rule_db) {
+			otx2_err("Could not allocate memory for rule db");
+			return -EFAULT;
+		}
+
+		ret = otx2_ree_rule_db_get(dev, rule_db, rule_db_len,
+				(char *)rule_dbi, rule_dbi_len);
+		if (ret) {
+			otx2_err("Could not read rule db");
+			rte_free(rule_db);
+			return -EFAULT;
+		}
+		rof_inc.rof_revision = 0;
+		rof_inc.rof_version = 2;
+		rof_inc.rof_entries = (struct rxp_rof_entry *)rule_db;
+		rof_inc.rxp_compiler_version = compiler_version;
+		rof_inc.timestamp = timestamp;
+		rof_inc.number_of_entries =
+				(rule_db_len/sizeof(struct rxp_rof_entry));
+
+		if (rule_dbi_len > 0) {
+			/* incremental compilation not the first time */
+			rofi_inc.rof_revision = 0;
+			rofi_inc.rof_version = 2;
+			rofi_inc.rof_entries = rule_dbi;
+			rofi_inc.rxp_compiler_version = compiler_version;
+			rofi_inc.timestamp = timestamp;
+			rofi_inc.number_of_entries =
+				(rule_dbi_len/sizeof(struct rxp_rof_entry));
+			rofi_inc_p = &rofi_inc;
+		}
+		ret = ree_rule_db_compile(data->rules, data->nb_rules, &rof,
+				&rofi, &rof_inc, rofi_inc_p);
+		if (rofi->number_of_entries == 0) {
+			otx2_ree_dbg("No change to rule db");
+			ret = 0;
+			goto free_structs;
+		}
+		rule_dbi_len = rofi->number_of_entries *
+				sizeof(struct rxp_rof_entry);
+		rofi_rof_entries = (char *)rofi->rof_entries;
+	} else {
+		/* full compilation */
+		ret = ree_rule_db_compile(data->rules, data->nb_rules, &rof,
+				&rofi, NULL, NULL);
+	}
+	if (ret != 0) {
+		otx2_err("Could not compile rule db");
+		goto free_structs;
+	}
+	rule_db_len = rof->number_of_entries * sizeof(struct rxp_rof_entry);
+	ret = otx2_ree_rule_db_prog(dev, (char *)rof->rof_entries, rule_db_len,
+			rofi_rof_entries, rule_dbi_len);
+	if (ret)
+		otx2_err("Could not program rule db");
+
+free_structs:
+	rxp_free_structs(NULL, NULL, NULL, NULL, NULL, &rof, NULL, &rofi, NULL,
+			1);
+
+	if (rule_db)
+		rte_free(rule_db);
+
+	return ret;
+}
+#else
+int
+otx2_ree_rule_db_compile_prog(struct rte_regexdev *dev)
+{
+	RTE_SET_USED(dev);
+	return -ENOTSUP;
+}
+#endif
diff --git a/drivers/regex/octeontx2/otx2_regexdev_compiler.h b/drivers/regex/octeontx2/otx2_regexdev_compiler.h
new file mode 100644
index 000000000..8d2625bf7
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev_compiler.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _OTX2_REGEXDEV_COMPILER_H_
+#define _OTX2_REGEXDEV_COMPILER_H_
+
+int
+otx2_ree_rule_db_compile_prog(struct rte_regexdev *dev);
+
+#endif /* _OTX2_REGEXDEV_COMPILER_H_ */
diff --git a/drivers/regex/octeontx2/otx2_regexdev_hw_access.c b/drivers/regex/octeontx2/otx2_regexdev_hw_access.c
new file mode 100644
index 000000000..620d5c912
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev_hw_access.c
@@ -0,0 +1,167 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#include "otx2_common.h"
+#include "otx2_dev.h"
+#include "otx2_regexdev_hw_access.h"
+#include "otx2_regexdev_mbox.h"
+
+static void
+ree_lf_err_intr_handler(void *param)
+{
+	uintptr_t base = (uintptr_t)param;
+	uint8_t lf_id;
+	uint64_t intr;
+
+	lf_id = (base >> 12) & 0xFF;
+
+	intr = otx2_read64(base + OTX2_REE_LF_MISC_INT);
+	if (intr == 0)
+		return;
+
+	otx2_ree_dbg("LF %d MISC_INT: 0x%" PRIx64 "", lf_id, intr);
+
+	/* Clear interrupt */
+	otx2_write64(intr, base + OTX2_REE_LF_MISC_INT);
+}
+
+static void
+ree_lf_err_intr_unregister(const struct rte_regexdev *dev, uint16_t msix_off,
+			   uintptr_t base)
+{
+	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
+	struct rte_intr_handle *handle = &pci_dev->intr_handle;
+
+	/* Disable error interrupts */
+	otx2_write64(~0ull, base + OTX2_REE_LF_MISC_INT_ENA_W1C);
+
+	otx2_unregister_irq(handle, ree_lf_err_intr_handler, (void *)base,
+			    msix_off);
+}
+
+void
+otx2_ree_err_intr_unregister(const struct rte_regexdev *dev)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	uintptr_t base;
+	uint32_t i;
+
+	for (i = 0; i < vf->nb_queues; i++) {
+		base = OTX2_REE_LF_BAR2(vf, i);
+		ree_lf_err_intr_unregister(dev, vf->lf_msixoff[i], base);
+	}
+
+	vf->err_intr_registered = 0;
+}
+
+static int
+ree_lf_err_intr_register(const struct rte_regexdev *dev, uint16_t msix_off,
+			 uintptr_t base)
+{
+	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
+	struct rte_intr_handle *handle = &pci_dev->intr_handle;
+	int ret;
+
+	/* Disable error interrupts */
+	otx2_write64(~0ull, base + OTX2_REE_LF_MISC_INT_ENA_W1C);
+
+	/* Register error interrupt handler */
+	ret = otx2_register_irq(handle, ree_lf_err_intr_handler, (void *)base,
+				msix_off);
+	if (ret)
+		return ret;
+
+	/* Enable error interrupts */
+	otx2_write64(~0ull, base + OTX2_REE_LF_MISC_INT_ENA_W1S);
+
+	return 0;
+}
+
+int
+otx2_ree_err_intr_register(const struct rte_regexdev *dev)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	uint32_t i, j, ret;
+	uintptr_t base;
+
+	for (i = 0; i < vf->nb_queues; i++) {
+		if (vf->lf_msixoff[i] == MSIX_VECTOR_INVALID) {
+			otx2_err("Invalid REE LF MSI-X offset: 0x%x",
+				    vf->lf_msixoff[i]);
+			return -EINVAL;
+		}
+	}
+
+	for (i = 0; i < vf->nb_queues; i++) {
+		base = OTX2_REE_LF_BAR2(vf, i);
+		ret = ree_lf_err_intr_register(dev, vf->lf_msixoff[i], base);
+		if (ret)
+			goto intr_unregister;
+	}
+
+	vf->err_intr_registered = 1;
+	return 0;
+
+intr_unregister:
+	/* Unregister the ones already registered */
+	for (j = 0; j < i; j++) {
+		base = OTX2_REE_LF_BAR2(vf, j);
+		ree_lf_err_intr_unregister(dev, vf->lf_msixoff[j], base);
+	}
+	return ret;
+}
+
+int
+otx2_ree_iq_enable(const struct rte_regexdev *dev, const struct otx2_ree_qp *qp,
+		   uint8_t pri, uint32_t size_div2)
+{
+	union otx2_ree_lf_sbuf_addr base;
+	union otx2_ree_lf_ena lf_ena;
+
+	/* Set instruction queue size and priority */
+	otx2_ree_config_lf(dev, qp->id, pri, size_div2);
+
+	/* Set instruction queue base address */
+	/* Should be written after SBUF_CTL and before LF_ENA */
+
+	base.u = otx2_read64(qp->base + OTX2_REE_LF_SBUF_ADDR);
+	base.s.ptr = qp->iq_dma_addr >> 7;
+	otx2_write64(base.u, qp->base + OTX2_REE_LF_SBUF_ADDR);
+
+	/* Enable instruction queue */
+
+	lf_ena.u = otx2_read64(qp->base + OTX2_REE_LF_ENA);
+	lf_ena.s.ena = 1;
+	otx2_write64(lf_ena.u, qp->base + OTX2_REE_LF_ENA);
+
+	return 0;
+}
+
+void
+otx2_ree_iq_disable(struct otx2_ree_qp *qp)
+{
+	union otx2_ree_lf_ena lf_ena;
+
+	/* Stop instruction execution */
+	lf_ena.u = otx2_read64(qp->base + OTX2_REE_LF_ENA);
+	lf_ena.s.ena = 0x0;
+	otx2_write64(lf_ena.u, qp->base + OTX2_REE_LF_ENA);
+}
+
+int
+otx2_ree_max_matches_get(const struct rte_regexdev *dev, uint8_t *max_matches)
+{
+	union otx2_ree_af_reexm_max_match reexm_max_match;
+	int ret;
+
+	ret = otx2_ree_af_reg_read(dev, REE_AF_REEXM_MAX_MATCH,
+				   &reexm_max_match.u);
+	if (ret)
+		return ret;
+
+	*max_matches = reexm_max_match.s.max;
+	return 0;
+}
diff --git a/drivers/regex/octeontx2/otx2_regexdev_hw_access.h b/drivers/regex/octeontx2/otx2_regexdev_hw_access.h
new file mode 100644
index 000000000..dedf5f328
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev_hw_access.h
@@ -0,0 +1,202 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _OTX2_REGEXDEV_HW_ACCESS_H_
+#define _OTX2_REGEXDEV_HW_ACCESS_H_
+
+#include <stdint.h>
+
+#include "otx2_regexdev.h"
+
+/* REE instruction queue length */
+#define OTX2_REE_IQ_LEN			(1 << 13)
+
+#define OTX2_REE_DEFAULT_CMD_QLEN	OTX2_REE_IQ_LEN
+
+/* Status register bits */
+#define OTX2_REE_STATUS_PMI_EOJ_BIT		(1 << 14)
+#define OTX2_REE_STATUS_PMI_SOJ_BIT		(1 << 13)
+#define OTX2_REE_STATUS_MP_CNT_DET_BIT		(1 << 7)
+#define OTX2_REE_STATUS_MM_CNT_DET_BIT		(1 << 6)
+#define OTX2_REE_STATUS_ML_CNT_DET_BIT		(1 << 5)
+#define OTX2_REE_STATUS_MST_CNT_DET_BIT		(1 << 4)
+#define OTX2_REE_STATUS_MPT_CNT_DET_BIT		(1 << 3)
+
+/* Register offsets */
+/* REE LF registers */
+#define OTX2_REE_LF_DONE_INT		0x120ull
+#define OTX2_REE_LF_DONE_INT_W1S	0x130ull
+#define OTX2_REE_LF_DONE_INT_ENA_W1S	0x138ull
+#define OTX2_REE_LF_DONE_INT_ENA_W1C	0x140ull
+#define OTX2_REE_LF_MISC_INT		0x300ull
+#define OTX2_REE_LF_MISC_INT_W1S	0x310ull
+#define OTX2_REE_LF_MISC_INT_ENA_W1S	0x320ull
+#define OTX2_REE_LF_MISC_INT_ENA_W1C	0x330ull
+#define OTX2_REE_LF_ENA			0x10ull
+#define OTX2_REE_LF_SBUF_ADDR		0x20ull
+#define OTX2_REE_LF_DONE		0x100ull
+#define OTX2_REE_LF_DONE_ACK		0x110ull
+#define OTX2_REE_LF_DONE_WAIT		0x148ull
+#define OTX2_REE_LF_DOORBELL		0x400ull
+#define OTX2_REE_LF_OUTSTAND_JOB	0x410ull
+
+/* BAR 0 */
+#define OTX2_REE_AF_QUE_SBUF_CTL(a)	(0x1200ull | (uint64_t)(a) << 3)
+#define OTX2_REE_PRIV_LF_CFG(a)		(0x41000ull | (uint64_t)(a) << 3)
+
+#define OTX2_REE_LF_BAR2(vf, q_id) \
+		((vf)->otx2_dev.bar2 + \
+		 (((vf)->block_address << 20) | ((q_id) << 12)))
+
+
+#define OTX2_REE_QUEUE_HI_PRIO 0x1
+
+enum ree_desc_type_e {
+	REE_TYPE_JOB_DESC    = 0x0,
+	REE_TYPE_RESULT_DESC = 0x1,
+	REE_TYPE_ENUM_LAST   = 0x2
+};
+
+union otx2_ree_priv_lf_cfg {
+	uint64_t u;
+	struct {
+		uint64_t slot                        : 8;
+		uint64_t pf_func                     : 16;
+		uint64_t reserved_24_62              : 39;
+		uint64_t ena                         : 1;
+	} s;
+};
+
+
+union otx2_ree_lf_sbuf_addr {
+	uint64_t u;
+	struct {
+		uint64_t off                         : 7;
+		uint64_t ptr                         : 46;
+		uint64_t reserved_53_63              : 11;
+	} s;
+};
+
+union otx2_ree_lf_ena {
+	uint64_t u;
+	struct {
+		uint64_t ena                         : 1;
+		uint64_t reserved_1_63               : 63;
+	} s;
+};
+
+union otx2_ree_af_reexm_max_match {
+	uint64_t u;
+	struct {
+		uint64_t max                         : 8;
+		uint64_t reserved_8_63               : 56;
+	} s;
+};
+
+union otx2_ree_lf_done {
+	uint64_t u;
+	struct {
+		uint64_t done                        : 20;
+		uint64_t reserved_20_63              : 44;
+	} s;
+};
+
+union otx2_ree_inst {
+	uint64_t u[8];
+	struct  {
+		uint64_t doneint                     :  1;
+		uint64_t reserved_1_3                :  3;
+		uint64_t dg                          :  1;
+		uint64_t reserved_5_7                :  3;
+		uint64_t ooj                         :  1;
+		uint64_t reserved_9_15               :  7;
+		uint64_t reserved_16_63              : 48;
+		uint64_t inp_ptr_addr                : 64;
+		uint64_t inp_ptr_ctl                 : 64;
+		uint64_t res_ptr_addr                : 64;
+		uint64_t wq_ptr                      : 64;
+		uint64_t tag                         : 32;
+		uint64_t tt                          :  2;
+		uint64_t ggrp                        : 10;
+		uint64_t reserved_364_383            : 20;
+		uint64_t reserved_384_391            :  8;
+		uint64_t ree_job_id                  : 24;
+		uint64_t ree_job_ctrl                : 16;
+		uint64_t ree_job_length              : 15;
+		uint64_t reserved_447_447            :  1;
+		uint64_t ree_job_subset_id_0         : 16;
+		uint64_t ree_job_subset_id_1         : 16;
+		uint64_t ree_job_subset_id_2         : 16;
+		uint64_t ree_job_subset_id_3         : 16;
+	} cn98xx;
+};
+
+union otx2_ree_res_status {
+	uint64_t u;
+	struct {
+		uint64_t job_type                    :  3;
+		uint64_t mpt_cnt_det                 :  1;
+		uint64_t mst_cnt_det                 :  1;
+		uint64_t ml_cnt_det                  :  1;
+		uint64_t mm_cnt_det                  :  1;
+		uint64_t mp_cnt_det                  :  1;
+		uint64_t mode                        :  2;
+		uint64_t reserved_10_11              :  2;
+		uint64_t reserved_12_12              :  1;
+		uint64_t pmi_soj                     :  1;
+		uint64_t pmi_eoj                     :  1;
+		uint64_t reserved_15_15              :  1;
+		uint64_t reserved_16_63              : 48;
+	} s;
+};
+
+union otx2_ree_res {
+	uint64_t u[8];
+	struct ree_res_s_98 {
+		uint64_t done			:  1;
+		uint64_t hwjid			:  7;
+		uint64_t ree_res_job_id		: 24;
+		uint64_t ree_res_status		: 16;
+		uint64_t ree_res_dmcnt		:  8;
+		uint64_t ree_res_mcnt		:  8;
+		uint64_t ree_meta_ptcnt		: 16;
+		uint64_t ree_meta_icnt		: 16;
+		uint64_t ree_meta_lcnt		: 16;
+		uint64_t ree_pmi_min_byte_ptr	: 16;
+		uint64_t ree_err		:  1;
+		uint64_t reserved_129_190	: 62;
+		uint64_t doneint		:  1;
+		uint64_t reserved_192_255	: 64;
+		uint64_t reserved_256_319	: 64;
+		uint64_t reserved_320_383	: 64;
+		uint64_t reserved_384_447	: 64;
+		uint64_t reserved_448_511	: 64;
+	} s;
+};
+
+union otx2_ree_match {
+	uint64_t u;
+	struct {
+		uint64_t ree_rule_id                 : 32;
+		uint64_t start_ptr                   : 14;
+		uint64_t reserved_46_47              :  2;
+		uint64_t match_length                : 15;
+		uint64_t reserved_63_63              :  1;
+	} s;
+};
+
+void otx2_ree_err_intr_unregister(const struct rte_regexdev *dev);
+
+int otx2_ree_err_intr_register(const struct rte_regexdev *dev);
+
+int otx2_ree_iq_enable(const struct rte_regexdev *dev,
+		       const struct otx2_ree_qp *qp,
+		       uint8_t pri, uint32_t size_div128);
+
+void otx2_ree_iq_disable(struct otx2_ree_qp *qp);
+
+int otx2_ree_max_matches_get(const struct rte_regexdev *dev,
+			     uint8_t *max_matches);
+
+#endif /* _OTX2_REGEXDEV_HW_ACCESS_H_ */
diff --git a/drivers/regex/octeontx2/otx2_regexdev_mbox.c b/drivers/regex/octeontx2/otx2_regexdev_mbox.c
new file mode 100644
index 000000000..6d58d367d
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev_mbox.c
@@ -0,0 +1,401 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#include "otx2_common.h"
+#include "otx2_dev.h"
+#include "otx2_regexdev_mbox.h"
+#include "otx2_regexdev.h"
+
+int
+otx2_ree_available_queues_get(const struct rte_regexdev *dev,
+			      uint16_t *nb_queues)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct free_rsrcs_rsp *rsp;
+	struct otx2_dev *otx2_dev;
+	int ret;
+
+	otx2_dev = &vf->otx2_dev;
+	otx2_mbox_alloc_msg_free_rsrc_cnt(otx2_dev->mbox);
+
+	ret = otx2_mbox_process_msg(otx2_dev->mbox, (void *)&rsp);
+	if (ret)
+		return -EIO;
+
+	if (vf->block_address == RVU_BLOCK_ADDR_REE0)
+		*nb_queues = rsp->ree0;
+	else
+		*nb_queues = rsp->ree1;
+	return 0;
+}
+
+int
+otx2_ree_queues_attach(const struct rte_regexdev *dev, uint8_t nb_queues)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct rsrc_attach_req *req;
+	struct otx2_mbox *mbox;
+
+	/* Ask AF to attach required LFs */
+	mbox = vf->otx2_dev.mbox;
+	req = otx2_mbox_alloc_msg_attach_resources(mbox);
+
+	/* 1 LF = 1 queue */
+	req->reelfs = nb_queues;
+	req->ree_blkaddr = vf->block_address;
+
+	if (otx2_mbox_process(mbox) < 0)
+		return -EIO;
+
+	/* Update number of attached queues */
+	vf->nb_queues = nb_queues;
+
+	return 0;
+}
+
+int
+otx2_ree_queues_detach(const struct rte_regexdev *dev)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct rsrc_detach_req *req;
+	struct otx2_mbox *mbox;
+
+	mbox = vf->otx2_dev.mbox;
+	req = otx2_mbox_alloc_msg_detach_resources(mbox);
+	req->reelfs = true;
+	req->partial = true;
+	if (otx2_mbox_process(mbox) < 0)
+		return -EIO;
+
+	/* Queues have been detached */
+	vf->nb_queues = 0;
+
+	return 0;
+}
+
+int
+otx2_ree_msix_offsets_get(const struct rte_regexdev *dev)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct msix_offset_rsp *rsp;
+	struct otx2_mbox *mbox;
+	uint32_t i, ret;
+
+	/* Get REE MSI-X vector offsets */
+	mbox = vf->otx2_dev.mbox;
+	otx2_mbox_alloc_msg_msix_offset(mbox);
+
+	ret = otx2_mbox_process_msg(mbox, (void *)&rsp);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < vf->nb_queues; i++) {
+		if (vf->block_address == RVU_BLOCK_ADDR_REE0)
+			vf->lf_msixoff[i] = rsp->ree0_lf_msixoff[i];
+		else
+			vf->lf_msixoff[i] = rsp->ree1_lf_msixoff[i];
+		otx2_ree_dbg("lf_msixoff[%d]  0x%x", i, vf->lf_msixoff[i]);
+	}
+
+	return 0;
+}
+
+static int
+ree_send_mbox_msg(struct otx2_ree_vf *vf)
+{
+	struct otx2_mbox *mbox = vf->otx2_dev.mbox;
+	int ret;
+
+	otx2_mbox_msg_send(mbox, 0);
+
+	ret = otx2_mbox_wait_for_rsp(mbox, 0);
+	if (ret < 0) {
+		otx2_err("Could not get mailbox response");
+		return ret;
+	}
+
+	return 0;
+}
+
+int
+otx2_ree_config_lf(const struct rte_regexdev *dev, uint8_t lf, uint8_t pri,
+		   uint32_t size)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct ree_lf_req_msg *req;
+	struct otx2_mbox *mbox;
+	int ret;
+
+	mbox = vf->otx2_dev.mbox;
+	req = otx2_mbox_alloc_msg_ree_config_lf(mbox);
+
+	req->lf = lf;
+	req->pri =  pri ? 1 : 0;
+	req->size = size;
+	req->blkaddr = vf->block_address;
+
+	ret = otx2_mbox_process(mbox);
+	if (ret < 0) {
+		otx2_err("Could not get mailbox response");
+		return ret;
+	}
+	return 0;
+}
+
+int
+otx2_ree_af_reg_read(const struct rte_regexdev *dev, uint64_t reg,
+		     uint64_t *val)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct ree_rd_wr_reg_msg *msg;
+	struct otx2_mbox_dev *mdev;
+	struct otx2_mbox *mbox;
+	int ret, off;
+
+	mbox = vf->otx2_dev.mbox;
+	mdev = &mbox->dev[0];
+	msg = (struct ree_rd_wr_reg_msg *)otx2_mbox_alloc_msg_rsp(mbox, 0,
+						sizeof(*msg), sizeof(*msg));
+	if (msg == NULL) {
+		otx2_err("Could not allocate mailbox message");
+		return -EFAULT;
+	}
+
+	msg->hdr.id = MBOX_MSG_REE_RD_WR_REGISTER;
+	msg->hdr.sig = OTX2_MBOX_REQ_SIG;
+	msg->hdr.pcifunc = vf->otx2_dev.pf_func;
+	msg->is_write = 0;
+	msg->reg_offset = reg;
+	msg->ret_val = val;
+	msg->blkaddr = vf->block_address;
+
+	ret = ree_send_mbox_msg(vf);
+	if (ret < 0)
+		return ret;
+
+	off = mbox->rx_start +
+			RTE_ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
+	msg = (struct ree_rd_wr_reg_msg *) ((uintptr_t)mdev->mbase + off);
+
+	*val = msg->val;
+
+	return 0;
+}
+
+int
+otx2_ree_af_reg_write(const struct rte_regexdev *dev, uint64_t reg,
+		      uint64_t val)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct ree_rd_wr_reg_msg *msg;
+	struct otx2_mbox *mbox;
+
+	mbox = vf->otx2_dev.mbox;
+	msg = (struct ree_rd_wr_reg_msg *)otx2_mbox_alloc_msg_rsp(mbox, 0,
+						sizeof(*msg), sizeof(*msg));
+	if (msg == NULL) {
+		otx2_err("Could not allocate mailbox message");
+		return -EFAULT;
+	}
+
+	msg->hdr.id = MBOX_MSG_REE_RD_WR_REGISTER;
+	msg->hdr.sig = OTX2_MBOX_REQ_SIG;
+	msg->hdr.pcifunc = vf->otx2_dev.pf_func;
+	msg->is_write = 1;
+	msg->reg_offset = reg;
+	msg->val = val;
+	msg->blkaddr = vf->block_address;
+
+	return ree_send_mbox_msg(vf);
+}
+
+int
+otx2_ree_rule_db_get(const struct rte_regexdev *dev, char *rule_db,
+		uint32_t rule_db_len, char *rule_dbi, uint32_t rule_dbi_len)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct ree_rule_db_get_req_msg *req;
+	struct ree_rule_db_get_rsp_msg *rsp;
+	char *rule_db_ptr = (char *)rule_db;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct otx2_mbox *mbox;
+	int ret, last = 0;
+	uint32_t len = 0;
+
+	mbox = vf->otx2_dev.mbox;
+	if (!rule_db) {
+		otx2_err("Couldn't return rule db due to NULL pointer");
+		return -EFAULT;
+	}
+
+	while (!last) {
+		req = (struct ree_rule_db_get_req_msg *)
+			otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
+						sizeof(*rsp));
+		if (!req) {
+			otx2_err("Could not allocate mailbox message");
+			return -EFAULT;
+		}
+
+		req->hdr.id = MBOX_MSG_REE_RULE_DB_GET;
+		req->hdr.sig = OTX2_MBOX_REQ_SIG;
+		req->hdr.pcifunc = vf->otx2_dev.pf_func;
+		req->blkaddr = vf->block_address;
+		req->is_dbi = 0;
+		req->offset = len;
+		ret = otx2_mbox_process_msg(mbox, (void *)&rsp);
+		if (ret)
+			return ret;
+		if (rule_db_len < len + rsp->len) {
+			otx2_err("Rule db size is too small");
+			return -EFAULT;
+		}
+		otx2_mbox_memcpy(rule_db_ptr, rsp->rule_db, rsp->len);
+		len += rsp->len;
+		rule_db_ptr = rule_db_ptr + rsp->len;
+		last = rsp->is_last;
+	}
+
+	if (rule_dbi) {
+		req = (struct ree_rule_db_get_req_msg *)
+			otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
+						sizeof(*rsp));
+		if (!req) {
+			otx2_err("Could not allocate mailbox message");
+			return -EFAULT;
+		}
+
+		req->hdr.id = MBOX_MSG_REE_RULE_DB_GET;
+		req->hdr.sig = OTX2_MBOX_REQ_SIG;
+		req->hdr.pcifunc = vf->otx2_dev.pf_func;
+		req->blkaddr = vf->block_address;
+		req->is_dbi = 1;
+		req->offset = 0;
+
+		ret = otx2_mbox_process_msg(mbox, (void *)&rsp);
+		if (ret)
+			return ret;
+		if (rule_dbi_len < rsp->len) {
+			otx2_err("Rule dbi size is too small");
+			return -EFAULT;
+		}
+		otx2_mbox_memcpy(rule_dbi, rsp->rule_db, rsp->len);
+	}
+	return 0;
+}
+
+int
+otx2_ree_rule_db_len_get(const struct rte_regexdev *dev,
+		uint32_t *rule_db_len,
+		uint32_t *rule_dbi_len)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct ree_rule_db_len_rsp_msg *rsp;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct ree_req_msg *req;
+	struct otx2_mbox *mbox;
+	int ret;
+
+	mbox = vf->otx2_dev.mbox;
+	req = (struct ree_req_msg *)
+		otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req), sizeof(*rsp));
+	if (!req) {
+		otx2_err("Could not allocate mailbox message");
+		return -EFAULT;
+	}
+
+	req->hdr.id = MBOX_MSG_REE_RULE_DB_LEN_GET;
+	req->hdr.sig = OTX2_MBOX_REQ_SIG;
+	req->hdr.pcifunc = vf->otx2_dev.pf_func;
+	req->blkaddr = vf->block_address;
+	ret = otx2_mbox_process_msg(mbox, (void *)&rsp);
+	if (ret)
+		return ret;
+	if (rule_db_len != NULL)
+		*rule_db_len = rsp->len;
+	if (rule_dbi_len != NULL)
+		*rule_dbi_len = rsp->inc_len;
+
+	return 0;
+}
+
+static int
+ree_db_msg(const struct rte_regexdev *dev, const char *db, uint32_t db_len,
+		int inc, int dbi)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	uint32_t len_left = db_len, offset = 0;
+	struct ree_rule_db_prog_req_msg *req;
+	struct otx2_ree_vf *vf = &data->vf;
+	const char *rule_db_ptr = db;
+	struct otx2_mbox *mbox;
+	struct msg_rsp *rsp;
+	int ret;
+
+	mbox = vf->otx2_dev.mbox;
+	while (len_left) {
+		req = (struct ree_rule_db_prog_req_msg *)
+			otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
+						sizeof(*rsp));
+		if (!req) {
+			otx2_err("Could not allocate mailbox message");
+			return -EFAULT;
+		}
+		req->hdr.id = MBOX_MSG_REE_RULE_DB_PROG;
+		req->hdr.sig = OTX2_MBOX_REQ_SIG;
+		req->hdr.pcifunc = vf->otx2_dev.pf_func;
+		req->offset = offset;
+		req->total_len = db_len;
+		req->len = REE_RULE_DB_REQ_BLOCK_SIZE;
+		req->is_incremental = inc;
+		req->is_dbi = dbi;
+		req->blkaddr = vf->block_address;
+
+		if (len_left < REE_RULE_DB_REQ_BLOCK_SIZE) {
+			req->is_last = true;
+			req->len = len_left;
+		}
+		otx2_mbox_memcpy(req->rule_db, rule_db_ptr, req->len);
+		ret = otx2_mbox_process_msg(mbox, (void *)&rsp);
+		if (ret) {
+			otx2_err("Programming mailbox processing failed");
+			return ret;
+		}
+		len_left -= req->len;
+		offset += req->len;
+		rule_db_ptr = rule_db_ptr + req->len;
+	}
+	return 0;
+}
+
+int
+otx2_ree_rule_db_prog(const struct rte_regexdev *dev, const char *rule_db,
+		uint32_t rule_db_len, const char *rule_dbi,
+		uint32_t rule_dbi_len)
+{
+	int inc, ret;
+
+	if (rule_db_len == 0) {
+		otx2_err("Couldn't program empty rule db");
+		return -EFAULT;
+	}
+	inc = (rule_dbi_len != 0);
+	if ((rule_db == NULL) || (inc && (rule_dbi == NULL))) {
+		otx2_err("Couldn't program NULL rule db");
+		return -EFAULT;
+	}
+	if (inc) {
+		ret = ree_db_msg(dev, rule_dbi, rule_dbi_len, inc, 1);
+		if (ret)
+			return ret;
+	}
+	return ree_db_msg(dev, rule_db, rule_db_len, inc, 0);
+}
diff --git a/drivers/regex/octeontx2/otx2_regexdev_mbox.h b/drivers/regex/octeontx2/otx2_regexdev_mbox.h
new file mode 100644
index 000000000..953efa672
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev_mbox.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _OTX2_REGEXDEV_MBOX_H_
+#define _OTX2_REGEXDEV_MBOX_H_
+
+#include <rte_regexdev.h>
+
+int otx2_ree_available_queues_get(const struct rte_regexdev *dev,
+				  uint16_t *nb_queues);
+
+int otx2_ree_queues_attach(const struct rte_regexdev *dev, uint8_t nb_queues);
+
+int otx2_ree_queues_detach(const struct rte_regexdev *dev);
+
+int otx2_ree_msix_offsets_get(const struct rte_regexdev *dev);
+
+int otx2_ree_config_lf(const struct rte_regexdev *dev, uint8_t lf, uint8_t pri,
+		       uint32_t size);
+
+int otx2_ree_af_reg_read(const struct rte_regexdev *dev, uint64_t reg,
+			 uint64_t *val);
+
+int otx2_ree_af_reg_write(const struct rte_regexdev *dev, uint64_t reg,
+			  uint64_t val);
+
+int otx2_ree_rule_db_get(const struct rte_regexdev *dev, char *rule_db,
+		 uint32_t rule_db_len, char *rule_dbi, uint32_t rule_dbi_len);
+
+int otx2_ree_rule_db_len_get(const struct rte_regexdev *dev,
+			     uint32_t *rule_db_len, uint32_t *rule_dbi_len);
+
+int otx2_ree_rule_db_prog(const struct rte_regexdev *dev, const char *rule_db,
+		uint32_t rule_db_len, const char *rule_dbi,
+		uint32_t rule_dbi_len);
+
+#endif /* _OTX2_REGEXDEV_MBOX_H_ */
diff --git a/drivers/regex/octeontx2/rte_pmd_octeontx2_regex_version.map b/drivers/regex/octeontx2/rte_pmd_octeontx2_regex_version.map
new file mode 100644
index 000000000..34eb991c7
--- /dev/null
+++ b/drivers/regex/octeontx2/rte_pmd_octeontx2_regex_version.map
@@ -0,0 +1,3 @@
+DPDK_20.08 {
+	local: *;
+};
diff --git a/meson_options.txt b/meson_options.txt
index 9bf18ab6b..214b5f7f5 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -36,3 +36,5 @@ option('tests', type: 'boolean', value: true,
 	description: 'build unit tests')
 option('use_hpet', type: 'boolean', value: false,
 	description: 'use HPET timer in EAL')
+option('ree_compiler_sdk', type: 'string', value: '',
+	description: 'path to REE compiler SDK optional library for regex device')
\ No newline at end of file
-- 
2.28.0


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [dpdk-dev] [PATCH 3/4] usertools: add octeontx2 REE device binding
  2020-09-01 12:24 ` [dpdk-dev] [PATCH 3/4] usertools: add octeontx2 REE device binding guyk
@ 2020-10-11  7:36   ` Liron Himi
  0 siblings, 0 replies; 33+ messages in thread
From: Liron Himi @ 2020-10-11  7:36 UTC (permalink / raw)
  To: Guy Kaneti, Jerin Jacob Kollanukkaran, Nithin Kumar Dabilpuram,
	thomas, mdr, nhorman, bruce.richardson, anatoly.burakov,
	john.mcnamara, marko.kovacevic
  Cc: dev, Smadar Fuks, Dovrat Zifroni, Guy Kaneti, orika, Liron Himi

Reviewed-by: Liron Himi <lironh@marvell.com>

-----Original Message-----
From: dev <dev-bounces@dpdk.org> On Behalf Of guyk@marvell.com
Sent: Tuesday, 1 September 2020 15:25
To: Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Nithin Kumar Dabilpuram <ndabilpuram@marvell.com>; thomas@monjalon.net; mdr@ashroe.eu; nhorman@tuxdriver.com; bruce.richardson@intel.com; anatoly.burakov@intel.com; john.mcnamara@intel.com; marko.kovacevic@intel.com
Cc: dev@dpdk.org; Smadar Fuks <smadarf@marvell.com>; Dovrat Zifroni <dovrat@marvell.com>; Guy Kaneti <guyk@marvell.com>; orika@mellanox.com
Subject: [dpdk-dev] [PATCH 3/4] usertools: add octeontx2 REE device binding

From: Guy Kaneti <guyk@marvell.com>

Update the devbind script with new section of regex devices, also added OCTEONTX2 REE device ID to regex device list

Signed-off-by: Guy Kaneti <guyk@marvell.com>
---
 usertools/dpdk-devbind.py | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py index 86b6b53c4..51ee990db 100755
--- a/usertools/dpdk-devbind.py
+++ b/usertools/dpdk-devbind.py
@@ -44,6 +44,8 @@
               'SVendor': None, 'SDevice': None}  octeontx2_dma = {'Class': '08', 'Vendor': '177d', 'Device': 'a081',
               'SVendor': None, 'SDevice': None}
+octeontx2_ree = {'Class': '08', 'Vendor': '177d', 'Device': 'a0f4',
+              'SVendor': None, 'SDevice': None}
 
 intel_ioat_bdw = {'Class': '08', 'Vendor': '8086', 'Device': '6f20,6f21,6f22,6f23,6f24,6f25,6f26,6f27,6f2e,6f2f',
               'SVendor': None, 'SDevice': None} @@ -61,6 +63,7 @@  mempool_devices = [cavium_fpa, octeontx2_npa]  compress_devices = [cavium_zip]  misc_devices = [intel_ioat_bdw, intel_ioat_skx, intel_ioat_icx, intel_ntb_skx, octeontx2_dma]
+regex_devices = [octeontx2_ree]
 
 # global dict ethernet devices present. Dictionary indexed by PCI address.
 # Each device within this is itself a dictionary of device properties @@ -648,6 +651,9 @@ def show_status():
     if status_dev == "misc" or status_dev == "all":
         show_device_status(misc_devices, "Misc (rawdev)")
 
+    if status_dev == "regex" or status_dev == "all":
+        show_device_status(regex_devices, "Regex")
+
 def parse_args():
     '''Parses the command-line arguments given by the user and takes the
     appropriate action for each'''
@@ -723,6 +729,7 @@ def do_arg_actions():
             get_device_details(mempool_devices)
             get_device_details(compress_devices)
             get_device_details(misc_devices)
+            get_device_details(regex_devices)
         show_status()
 
 
@@ -744,6 +751,7 @@ def main():
     get_device_details(mempool_devices)
     get_device_details(compress_devices)
     get_device_details(misc_devices)
+    get_device_details(regex_devices)
     do_arg_actions()
 
 if __name__ == "__main__":
--
2.28.0


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [dpdk-dev] [PATCH 4/4] doc: add Marvell OCTEON TX2 regex guide
  2020-09-01 12:24 ` [dpdk-dev] [PATCH 4/4] doc: add Marvell OCTEON TX2 regex guide guyk
@ 2020-10-11  7:36   ` Liron Himi
  0 siblings, 0 replies; 33+ messages in thread
From: Liron Himi @ 2020-10-11  7:36 UTC (permalink / raw)
  To: Guy Kaneti, Jerin Jacob Kollanukkaran, Nithin Kumar Dabilpuram,
	thomas, mdr, nhorman, bruce.richardson, anatoly.burakov,
	john.mcnamara, marko.kovacevic
  Cc: dev, Smadar Fuks, Dovrat Zifroni, Guy Kaneti, orika, Liron Himi

Reviewed-by: Liron Himi <lironh@marvell.com>

-----Original Message-----
From: dev <dev-bounces@dpdk.org> On Behalf Of guyk@marvell.com
Sent: Tuesday, 1 September 2020 15:25
To: Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Nithin Kumar Dabilpuram <ndabilpuram@marvell.com>; thomas@monjalon.net; mdr@ashroe.eu; nhorman@tuxdriver.com; bruce.richardson@intel.com; anatoly.burakov@intel.com; john.mcnamara@intel.com; marko.kovacevic@intel.com
Cc: dev@dpdk.org; Smadar Fuks <smadarf@marvell.com>; Dovrat Zifroni <dovrat@marvell.com>; Guy Kaneti <guyk@marvell.com>; orika@mellanox.com
Subject: [dpdk-dev] [PATCH 4/4] doc: add Marvell OCTEON TX2 regex guide

From: Guy Kaneti <guyk@marvell.com>

Signed-off-by: Guy Kaneti <guyk@marvell.com>
---
 doc/guides/platform/octeontx2.rst           |  5 +++
 doc/guides/regexdevs/features/octeontx2.ini | 10 +++++
 doc/guides/regexdevs/index.rst              |  1 +
 doc/guides/regexdevs/octeontx2.rst          | 49 +++++++++++++++++++++
 doc/guides/rel_notes/release_20_11.rst      |  5 +++
 5 files changed, 70 insertions(+)
 create mode 100644 doc/guides/regexdevs/features/octeontx2.ini
 create mode 100644 doc/guides/regexdevs/octeontx2.rst

diff --git a/doc/guides/platform/octeontx2.rst b/doc/guides/platform/octeontx2.rst
index 13255eec5..c4d64ab4b 100644
--- a/doc/guides/platform/octeontx2.rst
+++ b/doc/guides/platform/octeontx2.rst
@@ -67,6 +67,8 @@ DPDK subsystem.
    +---+-----+--------------------------------------------------------------+
    | 9 | SDP | rte_ethdev                                                   |
    +---+-----+--------------------------------------------------------------+
+   | 10| REE | rte_regexdev                                                 |
+   
+ +---+-----+-----------------------------------------------------------
+ ---+
 
 PF0 is called the administrative / admin function (AF) and has exclusive  privileges to provision RVU functional block's LFs to each of the PF/VF.
@@ -156,6 +158,9 @@ This section lists dataplane H/W block(s) available in OCTEON TX2 SoC.
 #. **Crypto Device Driver**
    See :doc:`../cryptodevs/octeontx2` for CPT crypto device driver information.
 
+#. **Regex Device Driver**
+   See :doc:`../regexdevs/octeontx2` for REE regex device driver information.
+
 Procedure to Setup Platform
 ---------------------------
 
diff --git a/doc/guides/regexdevs/features/octeontx2.ini b/doc/guides/regexdevs/features/octeontx2.ini
new file mode 100644
index 000000000..c9b421a16
--- /dev/null
+++ b/doc/guides/regexdevs/features/octeontx2.ini
@@ -0,0 +1,10 @@
+;
+; Supported features of the 'octeontx2' regex driver.
+;
+; Refer to default.ini for the full list of available driver features.
+;
+[Features]
+PCRE back reference         = Y
+PCRE word boundary          = Y
+Run time compilation        = Y
+Armv8                       = Y
diff --git a/doc/guides/regexdevs/index.rst b/doc/guides/regexdevs/index.rst index 49216a932..b1abc826b 100644
--- a/doc/guides/regexdevs/index.rst
+++ b/doc/guides/regexdevs/index.rst
@@ -13,3 +13,4 @@ which can be used from an application through RegEx API.
 
    features_overview
    mlx5
+   octeontx2
diff --git a/doc/guides/regexdevs/octeontx2.rst b/doc/guides/regexdevs/octeontx2.rst
new file mode 100644
index 000000000..859780da1
--- /dev/null
+++ b/doc/guides/regexdevs/octeontx2.rst
@@ -0,0 +1,49 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright(c) 2020 Marvell International Ltd.
+
+OCTEON TX2 REE Regexdev Driver
+===============================
+
+The OCTEON TX2 REE PMD (**librte_pmd_octeontx2_regex**) provides poll 
+mode regexdev driver support for the inbuilt regex device found in the 
+**Marvell OCTEON TX2** SoC family.
+
+More information about OCTEON TX2 SoC can be found at `Marvell Official 
+Website <https://www.marvell.com/embedded-processors/infrastructure-processors/>`_.
+
+Features
+--------
+
+Features of the OCTEON TX2 REE PMD are:
+
+- 36 queues
+- Up to 254 matches for each regex operation
+
+Prerequisites and Compilation procedure
+---------------------------------------
+
+   See :doc:`../platform/octeontx2` for setup information.
+
+Device Setup
+------------
+
+The OCTEON TX2 REE devices will need to be bound to a user-space IO 
+driver for use. The script ``dpdk-devbind.py`` script included with 
+DPDK can be used to view the state of the devices and to bind them to a 
+suitable DPDK-supported kernel driver. When querying the status of the 
+devices, they will appear under the category of "REGEX devices", i.e. 
+the command ``dpdk-devbind.py --status-dev regex`` can be used to see 
+the state of those devices alone.
+
+Debugging Options
+-----------------
+
+.. _table_octeontx2_regex_debug_options:
+
+.. table:: OCTEON TX2 regex device debug options
+
+   +---+------------+-------------------------------------------------------+
+   | # | Component  | EAL log command                                       |
+   +===+============+=======================================================+
+   | 1 | REE        | --log-level='pmd\.regex\.octeontx2,8'                 |
+   
+ +---+------------+----------------------------------------------------
+ ---+
diff --git a/doc/guides/rel_notes/release_20_11.rst b/doc/guides/rel_notes/release_20_11.rst
index df227a177..05c0a8ba7 100644
--- a/doc/guides/rel_notes/release_20_11.rst
+++ b/doc/guides/rel_notes/release_20_11.rst
@@ -55,6 +55,11 @@ New Features
      Also, make sure to start the actual text at the margin.
      =======================================================
 
+* **Added Marvell OCTEON TX2 regex PMD.**
+
+  Added a new PMD driver for hardware regex offload block for OCTEON TX2 SoC.
+
+  See the :doc:`../regexdevs/octeontx2` for more details.
 
 Removed Items
 -------------
--
2.28.0


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [dpdk-dev] [PATCH 0/4] Add Marvell OCTEON TX2 regex driver
  2020-10-08  6:31 ` [dpdk-dev] [PATCH 0/4] Add Marvell OCTEON TX2 regex driver Guy Kaneti
@ 2020-10-11 21:23   ` Thomas Monjalon
  2020-10-12 11:34     ` [dpdk-dev] [EXT] " Guy Kaneti
  0 siblings, 1 reply; 33+ messages in thread
From: Thomas Monjalon @ 2020-10-11 21:23 UTC (permalink / raw)
  To: Guy Kaneti
  Cc: Jerin Jacob Kollanukkaran, Nithin Kumar Dabilpuram, mdr, nhorman,
	bruce.richardson, anatoly.burakov, john.mcnamara,
	marko.kovacevic, orika, dev, Smadar Fuks, Dovrat Zifroni

08/10/2020 08:31, Guy Kaneti:
> Kind reminder to all maintainers, please review and ack/comment.

Please could you rebase?

The 2 rebase issues I see are:
	- make is removed
	- rte_cio_wmb is removed




^ permalink raw reply	[flat|nested] 33+ messages in thread

* [dpdk-dev] [PATCH v2 0/4] Add Marvell OCTEON TX2 regex driver
  2020-09-01 12:24 [dpdk-dev] [PATCH 0/4] Add Marvell OCTEON TX2 regex driver guyk
                   ` (4 preceding siblings ...)
  2020-10-08  6:31 ` [dpdk-dev] [PATCH 0/4] Add Marvell OCTEON TX2 regex driver Guy Kaneti
@ 2020-10-12 11:31 ` guyk
  2020-10-12 11:31   ` [dpdk-dev] [PATCH v2 1/4] common/octeontx2: add REE definitions and logging support guyk
                     ` (3 more replies)
  2020-10-13 10:10 ` [dpdk-dev] [PATCH v3 0/3] Add Marvell OCTEON TX2 regex driver guyk
  6 siblings, 4 replies; 33+ messages in thread
From: guyk @ 2020-10-12 11:31 UTC (permalink / raw)
  To: orika, jerinj, ndabilpuram, thomas, mdr, nhorman,
	bruce.richardson, anatoly.burakov, john.mcnamara,
	marko.kovacevic
  Cc: dev, smadarf, dovrat, guyk, lironh

From: Guy Kaneti <guyk@marvell.com>

This patchset adds support for OCTEON TX2 regex driver as DPDK regexdev.
The driver implements the API defined in the regexdev lib.

v2:
* Rebase.
* Remove config/common_base from patch
* change rte_cio_wmb to rte_io_wmb

Guy Kaneti (4):
  common/octeontx2: add REE definitions and logging support
  regex/octeontx2: add build infra and device support
  usertools: add octeontx2 REE device binding
  doc: add Marvell OCTEON TX2 regex guide

 MAINTAINERS                                   |    3 +
 doc/guides/platform/octeontx2.rst             |    5 +
 doc/guides/regexdevs/features/octeontx2.ini   |   10 +
 doc/guides/regexdevs/index.rst                |    1 +
 doc/guides/regexdevs/octeontx2.rst            |   49 +
 doc/guides/rel_notes/release_20_11.rst        |    5 +
 drivers/common/octeontx2/hw/otx2_ree.h        |   27 +
 drivers/common/octeontx2/hw/otx2_rvu.h        |    5 +
 drivers/common/octeontx2/otx2_common.c        |    1 +
 drivers/common/octeontx2/otx2_common.h        |    5 +
 drivers/common/octeontx2/otx2_mbox.h          |  103 ++
 .../rte_common_octeontx2_version.map          |    1 +
 drivers/regex/meson.build                     |    2 +-
 drivers/regex/octeontx2/meson.build           |   53 +
 drivers/regex/octeontx2/otx2_regexdev.c       | 1002 +++++++++++++++++
 drivers/regex/octeontx2/otx2_regexdev.h       |  109 ++
 .../regex/octeontx2/otx2_regexdev_compiler.c  |  229 ++++
 .../regex/octeontx2/otx2_regexdev_compiler.h  |   11 +
 .../regex/octeontx2/otx2_regexdev_hw_access.c |  167 +++
 .../regex/octeontx2/otx2_regexdev_hw_access.h |  202 ++++
 drivers/regex/octeontx2/otx2_regexdev_mbox.c  |  401 +++++++
 drivers/regex/octeontx2/otx2_regexdev_mbox.h  |   38 +
 .../rte_pmd_octeontx2_regex_version.map       |    3 +
 meson_options.txt                             |    2 +
 usertools/dpdk-devbind.py                     |    8 +
 25 files changed, 2441 insertions(+), 1 deletion(-)
 create mode 100644 doc/guides/regexdevs/features/octeontx2.ini
 create mode 100644 doc/guides/regexdevs/octeontx2.rst
 create mode 100644 drivers/common/octeontx2/hw/otx2_ree.h
 create mode 100644 drivers/regex/octeontx2/meson.build
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev.h
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_compiler.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_compiler.h
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_hw_access.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_hw_access.h
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_mbox.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_mbox.h
 create mode 100644 drivers/regex/octeontx2/rte_pmd_octeontx2_regex_version.map

-- 
2.28.0


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [dpdk-dev] [PATCH v2 1/4] common/octeontx2: add REE definitions and logging support
  2020-10-12 11:31 ` [dpdk-dev] [PATCH v2 " guyk
@ 2020-10-12 11:31   ` guyk
  2020-10-12 11:31   ` [dpdk-dev] [PATCH v2 2/4] regex/octeontx2: add build infra and device support guyk
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 33+ messages in thread
From: guyk @ 2020-10-12 11:31 UTC (permalink / raw)
  To: orika, jerinj, ndabilpuram, thomas, mdr, nhorman,
	bruce.richardson, anatoly.burakov, john.mcnamara,
	marko.kovacevic
  Cc: dev, smadarf, dovrat, guyk, lironh

From: Guy Kaneti <guyk@marvell.com>

Add REE mbox msg definitions, RVU and REE HW definitions

Signed-off-by: Guy Kaneti <guyk@marvell.com>
---
 drivers/common/octeontx2/hw/otx2_ree.h        |  27 +++++
 drivers/common/octeontx2/hw/otx2_rvu.h        |   5 +
 drivers/common/octeontx2/otx2_common.c        |   1 +
 drivers/common/octeontx2/otx2_common.h        |   5 +
 drivers/common/octeontx2/otx2_mbox.h          | 103 ++++++++++++++++++
 .../rte_common_octeontx2_version.map          |   1 +
 6 files changed, 142 insertions(+)
 create mode 100644 drivers/common/octeontx2/hw/otx2_ree.h

diff --git a/drivers/common/octeontx2/hw/otx2_ree.h b/drivers/common/octeontx2/hw/otx2_ree.h
new file mode 100644
index 000000000..b7481f125
--- /dev/null
+++ b/drivers/common/octeontx2/hw/otx2_ree.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#ifndef __OTX2_REE_HW_H__
+#define __OTX2_REE_HW_H__
+
+/* REE BAR0*/
+#define REE_AF_REEXM_MAX_MATCH		(0x80c8)
+
+/* REE BAR02 */
+#define REE_LF_MISC_INT                 (0x300)
+#define REE_LF_DONE_INT                 (0x120)
+
+#define REE_AF_QUEX_GMCTL(a)            (0x800 | (a) << 3)
+
+#define REE_AF_INT_VEC_RAS          (0x0ull)
+#define REE_AF_INT_VEC_RVU          (0x1ull)
+#define REE_AF_INT_VEC_QUE_DONE     (0x2ull)
+#define REE_AF_INT_VEC_AQ           (0x3ull)
+
+/* ENUMS */
+
+#define REE_LF_INT_VEC_QUE_DONE	(0x0ull)
+#define REE_LF_INT_VEC_MISC		(0x1ull)
+
+#endif /* __OTX2_REE_HW_H__*/
diff --git a/drivers/common/octeontx2/hw/otx2_rvu.h b/drivers/common/octeontx2/hw/otx2_rvu.h
index 330bfb37f..072515207 100644
--- a/drivers/common/octeontx2/hw/otx2_rvu.h
+++ b/drivers/common/octeontx2/hw/otx2_rvu.h
@@ -130,6 +130,7 @@
 #define RVU_BLOCK_TYPE_RAD                  (0xdull)
 #define RVU_BLOCK_TYPE_DFA                  (0xeull)
 #define RVU_BLOCK_TYPE_HNA                  (0xfull)
+#define RVU_BLOCK_TYPE_REE                  (0xeull)
 
 #define RVU_BLOCK_ADDR_RVUM                 (0x0ull)
 #define RVU_BLOCK_ADDR_LMT                  (0x1ull)
@@ -146,6 +147,8 @@
 #define RVU_BLOCK_ADDR_NDC2                 (0xeull)
 #define RVU_BLOCK_ADDR_R_END                (0x1full)
 #define RVU_BLOCK_ADDR_R_START              (0x14ull)
+#define RVU_BLOCK_ADDR_REE0                 (0x14ull)
+#define RVU_BLOCK_ADDR_REE1                 (0x15ull)
 
 #define RVU_VF_INT_VEC_MBOX                 (0x0ull)
 
@@ -167,6 +170,7 @@
 #define NPA_AF_BAR2_SEL			(0x9000000ull)
 #define CPT_AF_BAR2_SEL			(0x9000000ull)
 #define RVU_AF_BAR2_SEL			(0x9000000ull)
+#define REE_AF_BAR2_SEL			(0x9000000ull)
 
 #define AF_BAR2_ALIASX(a, b) \
 	(0x9100000ull | (uint64_t)(a) << 12 | (uint64_t)(b))
@@ -177,6 +181,7 @@
 #define NPA_AF_BAR2_ALIASX(a, b)		AF_BAR2_ALIASX(0, b)
 #define CPT_AF_BAR2_ALIASX(a, b)		AF_BAR2_ALIASX(a, b)
 #define RVU_AF_BAR2_ALIASX(a, b)		AF_BAR2_ALIASX(a, b)
+#define REE_AF_BAR2_ALIASX(a, b)		AF_BAR2_ALIASX(a, b)
 
 /* Structures definitions */
 
diff --git a/drivers/common/octeontx2/otx2_common.c b/drivers/common/octeontx2/otx2_common.c
index b292e999a..d23c50242 100644
--- a/drivers/common/octeontx2/otx2_common.c
+++ b/drivers/common/octeontx2/otx2_common.c
@@ -213,3 +213,4 @@ RTE_LOG_REGISTER(otx2_logtype_sso, pmd.event.octeontx2, NOTICE);
 RTE_LOG_REGISTER(otx2_logtype_tim, pmd.event.octeontx2.timer, NOTICE);
 RTE_LOG_REGISTER(otx2_logtype_dpi, pmd.raw.octeontx2.dpi, NOTICE);
 RTE_LOG_REGISTER(otx2_logtype_ep, pmd.raw.octeontx2.ep, NOTICE);
+RTE_LOG_REGISTER(otx2_logtype_ree, pmd.regex.octeontx2, NOTICE);
diff --git a/drivers/common/octeontx2/otx2_common.h b/drivers/common/octeontx2/otx2_common.h
index 2168cde4d..b6779f710 100644
--- a/drivers/common/octeontx2/otx2_common.h
+++ b/drivers/common/octeontx2/otx2_common.h
@@ -21,6 +21,7 @@
 #include "hw/otx2_sso.h"
 #include "hw/otx2_ssow.h"
 #include "hw/otx2_tim.h"
+#include "hw/otx2_ree.h"
 
 /* Alignment */
 #define OTX2_ALIGN  128
@@ -96,6 +97,7 @@ extern int otx2_logtype_tm;
 extern int otx2_logtype_tim;
 extern int otx2_logtype_dpi;
 extern int otx2_logtype_ep;
+extern int otx2_logtype_ree;
 
 #define otx2_err(fmt, args...)			\
 	RTE_LOG(ERR, PMD, "%s():%u " fmt "\n",	\
@@ -119,6 +121,7 @@ extern int otx2_logtype_ep;
 #define otx2_tim_dbg(fmt, ...) otx2_dbg(tim, fmt, ##__VA_ARGS__)
 #define otx2_dpi_dbg(fmt, ...) otx2_dbg(dpi, fmt, ##__VA_ARGS__)
 #define otx2_sdp_dbg(fmt, ...) otx2_dbg(ep, fmt, ##__VA_ARGS__)
+#define otx2_ree_dbg(fmt, ...) otx2_dbg(ree, fmt, ##__VA_ARGS__)
 
 /* PCI IDs */
 #define PCI_VENDOR_ID_CAVIUM			0x177D
@@ -136,6 +139,8 @@ extern int otx2_logtype_ep;
 #define PCI_DEVID_OCTEONTX2_EP_VF		0xB203 /* OCTEON TX2 EP mode */
 #define PCI_DEVID_OCTEONTX2_RVU_SDP_PF		0xA0f6
 #define PCI_DEVID_OCTEONTX2_RVU_SDP_VF		0xA0f7
+#define PCI_DEVID_OCTEONTX2_RVU_REE_PF		0xA0f4
+#define PCI_DEVID_OCTEONTX2_RVU_REE_VF		0xA0f5
 
 /*
  * REVID for RVU PCIe devices.
diff --git a/drivers/common/octeontx2/otx2_mbox.h b/drivers/common/octeontx2/otx2_mbox.h
index 78de432e7..aebb217ec 100644
--- a/drivers/common/octeontx2/otx2_mbox.h
+++ b/drivers/common/octeontx2/otx2_mbox.h
@@ -199,6 +199,19 @@ M(CPT_INLINE_IPSEC_CFG, 0xA04, cpt_inline_ipsec_cfg,			\
 M(CPT_RX_INLINE_LF_CFG, 0xBFE, cpt_rx_inline_lf_cfg,			\
 			       cpt_rx_inline_lf_cfg_msg, msg_rsp)	\
 M(CPT_GET_CAPS,		0xBFD, cpt_caps_get, msg_req, cpt_caps_rsp_msg)	\
+/* REE mbox IDs (range 0xE00 - 0xFFF) */				\
+M(REE_CONFIG_LF,	0xE01, ree_config_lf, ree_lf_req_msg,		\
+				msg_rsp)				\
+M(REE_RD_WR_REGISTER,	0xE02, ree_rd_wr_register, ree_rd_wr_reg_msg,	\
+				ree_rd_wr_reg_msg)			\
+M(REE_RULE_DB_PROG,	0xE03, ree_rule_db_prog,			\
+				ree_rule_db_prog_req_msg,		\
+				msg_rsp)				\
+M(REE_RULE_DB_LEN_GET,	0xE04, ree_rule_db_len_get, ree_req_msg,	\
+				ree_rule_db_len_rsp_msg)		\
+M(REE_RULE_DB_GET,	0xE05, ree_rule_db_get,				\
+				ree_rule_db_get_req_msg,		\
+				ree_rule_db_get_rsp_msg)		\
 /* NPC mbox IDs (range 0x6000 - 0x7FFF) */				\
 M(NPC_MCAM_ALLOC_ENTRY,	0x6000, npc_mcam_alloc_entry,			\
 				npc_mcam_alloc_entry_req,		\
@@ -1660,6 +1673,96 @@ struct tim_enable_rsp {
 	uint32_t __otx2_io currentbucket;
 };
 
+/* REE mailbox error codes
+ * Range 1001 - 1100.
+ */
+enum ree_af_status {
+	REE_AF_ERR_RULE_UNKNOWN_VALUE		= -1001,
+	REE_AF_ERR_LF_NO_MORE_RESOURCES		= -1002,
+	REE_AF_ERR_LF_INVALID			= -1003,
+	REE_AF_ERR_ACCESS_DENIED		= -1004,
+	REE_AF_ERR_RULE_DB_PARTIAL		= -1005,
+	REE_AF_ERR_RULE_DB_EQ_BAD_VALUE		= -1006,
+	REE_AF_ERR_RULE_DB_BLOCK_ALLOC_FAILED	= -1007,
+	REE_AF_ERR_BLOCK_NOT_IMPLEMENTED	= -1008,
+	REE_AF_ERR_RULE_DB_INC_OFFSET_TOO_BIG	= -1009,
+	REE_AF_ERR_RULE_DB_OFFSET_TOO_BIG	= -1010,
+	REE_AF_ERR_Q_IS_GRACEFUL_DIS		= -1011,
+	REE_AF_ERR_Q_NOT_GRACEFUL_DIS		= -1012,
+	REE_AF_ERR_RULE_DB_ALLOC_FAILED		= -1013,
+	REE_AF_ERR_RULE_DB_TOO_BIG		= -1014,
+	REE_AF_ERR_RULE_DB_GEQ_BAD_VALUE	= -1015,
+	REE_AF_ERR_RULE_DB_LEQ_BAD_VALUE	= -1016,
+	REE_AF_ERR_RULE_DB_WRONG_LENGTH		= -1017,
+	REE_AF_ERR_RULE_DB_WRONG_OFFSET		= -1018,
+	REE_AF_ERR_RULE_DB_BLOCK_TOO_BIG	= -1019,
+	REE_AF_ERR_RULE_DB_SHOULD_FILL_REQUEST	= -1020,
+	REE_AF_ERR_RULE_DBI_ALLOC_FAILED	= -1021,
+	REE_AF_ERR_LF_WRONG_PRIORITY		= -1022,
+	REE_AF_ERR_LF_SIZE_TOO_BIG		= -1023,
+};
+
+/* REE mbox message formats */
+
+struct ree_req_msg {
+	struct mbox_msghdr hdr;
+	uint32_t __otx2_io blkaddr;
+};
+
+struct ree_lf_req_msg {
+	struct mbox_msghdr hdr;
+	uint32_t __otx2_io blkaddr;
+	uint32_t __otx2_io size;
+	uint8_t __otx2_io lf;
+	uint8_t __otx2_io pri;
+};
+
+struct ree_rule_db_prog_req_msg {
+	struct mbox_msghdr hdr;
+#define REE_RULE_DB_REQ_BLOCK_SIZE (MBOX_SIZE >> 1)
+	uint8_t __otx2_io rule_db[REE_RULE_DB_REQ_BLOCK_SIZE];
+	uint32_t __otx2_io blkaddr; /* REE0 or REE1 */
+	uint32_t __otx2_io total_len; /* total len of rule db */
+	uint32_t __otx2_io offset; /* offset of current rule db block */
+	uint16_t __otx2_io len; /* length of rule db block */
+	uint8_t __otx2_io is_last; /* is this the last block */
+	uint8_t __otx2_io is_incremental; /* is incremental flow */
+	uint8_t __otx2_io is_dbi; /* is rule db incremental */
+};
+
+struct ree_rule_db_get_req_msg {
+	struct mbox_msghdr hdr;
+	uint32_t __otx2_io blkaddr;
+	uint32_t __otx2_io offset; /* retrieve db from this offset */
+	uint8_t __otx2_io is_dbi; /* is request for rule db incremental */
+};
+
+struct ree_rd_wr_reg_msg {
+	struct mbox_msghdr hdr;
+	uint64_t __otx2_io reg_offset;
+	uint64_t __otx2_io *ret_val;
+	uint64_t __otx2_io val;
+	uint32_t __otx2_io blkaddr;
+	uint8_t __otx2_io is_write;
+};
+
+struct ree_rule_db_len_rsp_msg {
+	struct mbox_msghdr hdr;
+	uint32_t __otx2_io blkaddr;
+	uint32_t __otx2_io len;
+	uint32_t __otx2_io inc_len;
+};
+
+struct ree_rule_db_get_rsp_msg {
+	struct mbox_msghdr hdr;
+#define REE_RULE_DB_RSP_BLOCK_SIZE (MBOX_DOWN_TX_SIZE - SZ_1K)
+	uint8_t __otx2_io rule_db[REE_RULE_DB_RSP_BLOCK_SIZE];
+	uint32_t __otx2_io total_len; /* total len of rule db */
+	uint32_t __otx2_io offset; /* offset of current rule db block */
+	uint16_t __otx2_io len; /* length of rule db block */
+	uint8_t __otx2_io is_last; /* is this the last block */
+};
+
 __rte_internal
 const char *otx2_mbox_id2name(uint16_t id);
 int otx2_mbox_id2size(uint16_t id);
diff --git a/drivers/common/octeontx2/rte_common_octeontx2_version.map b/drivers/common/octeontx2/rte_common_octeontx2_version.map
index 9a9969613..d269d70d8 100644
--- a/drivers/common/octeontx2/rte_common_octeontx2_version.map
+++ b/drivers/common/octeontx2/rte_common_octeontx2_version.map
@@ -38,6 +38,7 @@ INTERNAL {
 	otx2_sso_pf_func_get;
 	otx2_sso_pf_func_set;
 	otx2_unregister_irq;
+	otx2_logtype_ree;
 
 	local: *;
 };
-- 
2.28.0


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [dpdk-dev] [PATCH v2 2/4] regex/octeontx2: add build infra and device support
  2020-10-12 11:31 ` [dpdk-dev] [PATCH v2 " guyk
  2020-10-12 11:31   ` [dpdk-dev] [PATCH v2 1/4] common/octeontx2: add REE definitions and logging support guyk
@ 2020-10-12 11:31   ` guyk
  2020-10-12 14:33     ` Thomas Monjalon
  2020-10-12 11:31   ` [dpdk-dev] [PATCH v2 3/4] usertools: add octeontx2 REE device binding guyk
  2020-10-12 11:31   ` [dpdk-dev] [PATCH v2 4/4] doc: add Marvell OCTEON TX2 regex guide guyk
  3 siblings, 1 reply; 33+ messages in thread
From: guyk @ 2020-10-12 11:31 UTC (permalink / raw)
  To: orika, jerinj, ndabilpuram, thomas, mdr, nhorman,
	bruce.richardson, anatoly.burakov, john.mcnamara,
	marko.kovacevic
  Cc: dev, smadarf, dovrat, guyk, lironh

From: Guy Kaneti <guyk@marvell.com>

Add meson based build infrastructure along with the
OTX2 regexdev (REE) device functions.

For regex rule compiler support build:
meson configure -Dree_compiler_sdk=<path-to-compiler-sdk>

Signed-off-by: Guy Kaneti <guyk@marvell.com>
---
 MAINTAINERS                                   |    3 +
 drivers/regex/meson.build                     |    2 +-
 drivers/regex/octeontx2/meson.build           |   53 +
 drivers/regex/octeontx2/otx2_regexdev.c       | 1002 +++++++++++++++++
 drivers/regex/octeontx2/otx2_regexdev.h       |  109 ++
 .../regex/octeontx2/otx2_regexdev_compiler.c  |  229 ++++
 .../regex/octeontx2/otx2_regexdev_compiler.h  |   11 +
 .../regex/octeontx2/otx2_regexdev_hw_access.c |  167 +++
 .../regex/octeontx2/otx2_regexdev_hw_access.h |  202 ++++
 drivers/regex/octeontx2/otx2_regexdev_mbox.c  |  401 +++++++
 drivers/regex/octeontx2/otx2_regexdev_mbox.h  |   38 +
 .../rte_pmd_octeontx2_regex_version.map       |    3 +
 meson_options.txt                             |    2 +
 13 files changed, 2221 insertions(+), 1 deletion(-)
 create mode 100644 drivers/regex/octeontx2/meson.build
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev.h
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_compiler.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_compiler.h
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_hw_access.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_hw_access.h
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_mbox.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_mbox.h
 create mode 100644 drivers/regex/octeontx2/rte_pmd_octeontx2_regex_version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index 2a18262d6..631893bb2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1118,6 +1118,9 @@ F: drivers/regex/mlx5/
 F: doc/guides/regexdevs/mlx5.rst
 F: doc/guides/regexdevs/features/mlx5.ini
 
+Marvell OCTEON TX2 regex
+M: Guy Kaneti <guyk@marvell.com>
+F: drivers/regex/octeontx2/
 
 vDPA Drivers
 ------------
diff --git a/drivers/regex/meson.build b/drivers/regex/meson.build
index 8edeba3a0..79bb5d5df 100644
--- a/drivers/regex/meson.build
+++ b/drivers/regex/meson.build
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright 2020 Mellanox Technologies, Ltd
 
-drivers = ['mlx5']
+drivers = ['mlx5', 'octeontx2']
 std_deps = ['ethdev', 'kvargs'] # 'ethdev' also pulls in mbuf, net, eal etc
 config_flag_fmt = 'RTE_LIBRTE_@0@_PMD'
 driver_name_fmt = 'rte_pmd_@0@'
diff --git a/drivers/regex/octeontx2/meson.build b/drivers/regex/octeontx2/meson.build
new file mode 100644
index 000000000..c212e3d43
--- /dev/null
+++ b/drivers/regex/octeontx2/meson.build
@@ -0,0 +1,53 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(C) 2020 Marvell International Ltd.
+#
+
+if not is_linux
+	build = false
+	reason = 'only supported on Linux'
+endif
+
+path = get_option('ree_compiler_sdk')
+lib_dir = path + '/lib'
+inc_dir = path + '/include'
+
+if dpdk_conf.has('RTE_LIBRTE_PMD_OCTEONTX2_REGEX_COMPILER')
+	lib = cc.find_library('librxp_compiler', dirs : [lib_dir], required: false)
+	if not lib.found()
+		build = false
+		reason = 'missing dependency, "librxp_compiler"'
+	else
+		ext_deps += lib
+		ext_deps += cc.find_library('libstdc++', required: true)
+		includes += include_directories(inc_dir)
+		cflags += ['-DREE_COMPILER_SDK']
+	endif
+endif
+
+sources = files('otx2_regexdev.c',
+		'otx2_regexdev_hw_access.c',
+		'otx2_regexdev_mbox.c',
+		'otx2_regexdev_compiler.c'
+		)
+
+extra_flags = []
+# This integrated controller runs only on a arm64 machine, remove 32bit warnings
+if not dpdk_conf.get('RTE_ARCH_64')
+	extra_flags += ['-Wno-int-to-pointer-cast', '-Wno-pointer-to-int-cast']
+endif
+
+# for clang 32-bit compiles we need libatomic for 64-bit atomic ops
+if cc.get_id() == 'clang' and dpdk_conf.get('RTE_ARCH_64') == false
+	ext_deps += cc.find_library('atomic')
+endif
+
+foreach flag: extra_flags
+	if cc.has_argument(flag)
+		cflags += flag
+	endif
+endforeach
+
+name = 'octeontx2_regex'
+deps += ['bus_pci', 'common_octeontx2', 'regexdev']
+
+includes += include_directories('../../common/octeontx2')
diff --git a/drivers/regex/octeontx2/otx2_regexdev.c b/drivers/regex/octeontx2/otx2_regexdev.c
new file mode 100644
index 000000000..39eed7a20
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev.c
@@ -0,0 +1,1002 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include <rte_malloc.h>
+#include <rte_memzone.h>
+#include <rte_regexdev.h>
+#include <rte_regexdev_core.h>
+#include <rte_regexdev_driver.h>
+
+
+/* REE common headers */
+#include "otx2_common.h"
+#include "otx2_dev.h"
+#include "otx2_regexdev.h"
+#include "otx2_regexdev_compiler.h"
+#include "otx2_regexdev_hw_access.h"
+#include "otx2_regexdev_mbox.h"
+
+
+/* HW matches are at offset 0x80 from RES_PTR_ADDR
+ * In op structure matches starts at W5 (0x28)
+ * There is a need to copy to 0x28 to 0x80 The matches that are at the tail
+ * Which are 88 B. Each match holds 8 B, so up to 11 matches can be copied
+ */
+#define REE_NUM_MATCHES_ALIGN	11
+/* The REE co-processor will write up to 254 job match structures
+ * (REE_MATCH_S) starting at address [RES_PTR_ADDR] + 0x80.
+ */
+#define REE_MATCH_OFFSET	0x80
+
+#define REE_MAX_RULES_PER_GROUP 0xFFFF
+#define REE_MAX_GROUPS 0xFFFF
+
+/* This is temporarily here */
+#define REE0_PF	19
+#define REE1_PF	20
+
+#define REE_RULE_DB_VERSION	2
+#define REE_RULE_DB_REVISION	0
+
+struct ree_rule_db_entry {
+	uint8_t		type;
+	uint32_t	addr;
+	uint64_t	value;
+};
+
+struct ree_rule_db {
+	uint32_t version;
+	uint32_t revision;
+	uint32_t number_of_entries;
+	struct ree_rule_db_entry entries[];
+} __rte_packed;
+
+static void
+qp_memzone_name_get(char *name, int size, int dev_id, int qp_id)
+{
+	snprintf(name, size, "otx2_ree_lf_mem_%u:%u", dev_id, qp_id);
+}
+
+static struct otx2_ree_qp *
+ree_qp_create(const struct rte_regexdev *dev, uint16_t qp_id)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	uint64_t pg_sz = sysconf(_SC_PAGESIZE);
+	struct otx2_ree_vf *vf = &data->vf;
+	const struct rte_memzone *lf_mem;
+	uint32_t len, iq_len, size_div2;
+	char name[RTE_MEMZONE_NAMESIZE];
+	uint64_t used_len, iova;
+	struct otx2_ree_qp *qp;
+	uint8_t *va;
+	int ret;
+
+	/* Allocate queue pair */
+	qp = rte_zmalloc("OCTEON TX2 Regex PMD Queue Pair", sizeof(*qp),
+				OTX2_ALIGN);
+	if (qp == NULL) {
+		otx2_err("Could not allocate queue pair");
+		return NULL;
+	}
+
+	iq_len = OTX2_REE_IQ_LEN;
+
+	/*
+	 * Queue size must be in units of 128B 2 * REE_INST_S (which is 64B),
+	 * and a power of 2.
+	 * effective queue size to software is (size - 1) * 128
+	 */
+	size_div2 = iq_len >> 1;
+
+	/* For pending queue */
+	len = iq_len * RTE_ALIGN(sizeof(struct otx2_ree_rid), 8);
+
+	/* So that instruction queues start as pg size aligned */
+	len = RTE_ALIGN(len, pg_sz);
+
+	/* For instruction queues */
+	len += OTX2_REE_IQ_LEN * sizeof(union otx2_ree_inst);
+
+	/* Waste after instruction queues */
+	len = RTE_ALIGN(len, pg_sz);
+
+	qp_memzone_name_get(name, RTE_MEMZONE_NAMESIZE, dev->data->dev_id,
+			    qp_id);
+
+	lf_mem = rte_memzone_reserve_aligned(name, len, vf->otx2_dev.node,
+			RTE_MEMZONE_SIZE_HINT_ONLY | RTE_MEMZONE_256MB,
+			RTE_CACHE_LINE_SIZE);
+	if (lf_mem == NULL) {
+		otx2_err("Could not allocate reserved memzone");
+		goto qp_free;
+	}
+
+	va = lf_mem->addr;
+	iova = lf_mem->iova;
+
+	memset(va, 0, len);
+
+	/* Initialize pending queue */
+	qp->pend_q.rid_queue = (struct otx2_ree_rid *)va;
+	qp->pend_q.enq_tail = 0;
+	qp->pend_q.deq_head = 0;
+	qp->pend_q.pending_count = 0;
+
+	used_len = iq_len * RTE_ALIGN(sizeof(struct otx2_ree_rid), 8);
+	used_len = RTE_ALIGN(used_len, pg_sz);
+	iova += used_len;
+
+	qp->iq_dma_addr = iova;
+	qp->id = qp_id;
+	qp->base = OTX2_REE_LF_BAR2(vf, qp_id);
+	qp->otx2_regexdev_jobid = 0;
+	qp->write_offset = 0;
+
+	ret = otx2_ree_iq_enable(dev, qp, OTX2_REE_QUEUE_HI_PRIO, size_div2);
+	if (ret) {
+		otx2_err("Could not enable instruction queue");
+		goto qp_free;
+	}
+
+	return qp;
+
+qp_free:
+	rte_free(qp);
+	return NULL;
+}
+
+static int
+ree_qp_destroy(const struct rte_regexdev *dev, struct otx2_ree_qp *qp)
+{
+	const struct rte_memzone *lf_mem;
+	char name[RTE_MEMZONE_NAMESIZE];
+	int ret;
+
+	otx2_ree_iq_disable(qp);
+
+	qp_memzone_name_get(name, RTE_MEMZONE_NAMESIZE, dev->data->dev_id,
+			    qp->id);
+
+	lf_mem = rte_memzone_lookup(name);
+
+	ret = rte_memzone_free(lf_mem);
+	if (ret)
+		return ret;
+
+	rte_free(qp);
+
+	return 0;
+}
+
+static int
+ree_queue_pair_release(struct rte_regexdev *dev, uint16_t qp_id)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_qp *qp = data->queue_pairs[qp_id];
+	int ret;
+
+	ree_func_trace("Queue=%d", qp_id);
+
+	if (qp == NULL)
+		return -EINVAL;
+
+	ret = ree_qp_destroy(dev, qp);
+	if (ret) {
+		otx2_err("Could not destroy queue pair %d", qp_id);
+		return ret;
+	}
+
+	data->queue_pairs[qp_id] = NULL;
+
+	return 0;
+}
+
+static struct rte_regexdev *
+ree_dev_register(const char *name)
+{
+	struct rte_regexdev *dev;
+
+	otx2_ree_dbg("Creating regexdev %s\n", name);
+
+	/* allocate device structure */
+	dev = rte_regexdev_register(name);
+	if (dev == NULL) {
+		otx2_err("Failed to allocate regex device for %s", name);
+		return NULL;
+	}
+
+	/* allocate private device structure */
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		dev->data->dev_private =
+				rte_zmalloc_socket("regexdev device private",
+						sizeof(struct otx2_ree_data),
+						RTE_CACHE_LINE_SIZE,
+						rte_socket_id());
+
+		if (dev->data->dev_private == NULL) {
+			otx2_err("Cannot allocate memory for dev %s private data",
+					name);
+
+			rte_regexdev_unregister(dev);
+			return NULL;
+		}
+	}
+
+	return dev;
+}
+
+static int
+ree_dev_unregister(struct rte_regexdev *dev)
+{
+	otx2_ree_dbg("Closing regex device %s", dev->device->name);
+
+	/* free regex device */
+	rte_regexdev_unregister(dev);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(dev->data->dev_private);
+
+	return 0;
+}
+
+static int
+ree_dev_fini(struct rte_regexdev *dev)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct rte_pci_device *pci_dev;
+	int i, ret;
+
+	ree_func_trace();
+
+	for (i = 0; i < data->nb_queue_pairs; i++) {
+		ret = ree_queue_pair_release(dev, i);
+		if (ret)
+			return ret;
+	}
+
+	ret = otx2_ree_queues_detach(dev);
+	if (ret)
+		otx2_err("Could not detach queues");
+
+	/* TEMP : should be in lib */
+	if (data->queue_pairs)
+		rte_free(data->queue_pairs);
+	if (data->rules)
+		rte_free(data->rules);
+
+	pci_dev = container_of(dev->device, struct rte_pci_device, device);
+	otx2_dev_fini(pci_dev, &(data->vf.otx2_dev));
+
+	ret = ree_dev_unregister(dev);
+	if (ret)
+		otx2_err("Could not destroy PMD");
+
+	return ret;
+}
+
+static inline int
+ree_enqueue(struct otx2_ree_qp *qp, struct rte_regex_ops *op,
+		 struct otx2_ree_pending_queue *pend_q)
+{
+	union otx2_ree_inst inst;
+	union otx2_ree_res *res;
+	uint32_t offset;
+
+	if (unlikely(pend_q->pending_count >= OTX2_REE_DEFAULT_CMD_QLEN)) {
+		otx2_err("Pending count %" PRIu64 " is greater than Q size %d",
+		pend_q->pending_count, OTX2_REE_DEFAULT_CMD_QLEN);
+		return -EAGAIN;
+	}
+	if (unlikely(op->mbuf->data_len > OTX2_REE_MAX_PAYLOAD_SIZE ||
+			op->mbuf->data_len == 0)) {
+		otx2_err("Packet length %d is greater than MAX payload %d",
+				op->mbuf->data_len, OTX2_REE_MAX_PAYLOAD_SIZE);
+		return -EAGAIN;
+	}
+
+	/* W 0 */
+	inst.cn98xx.ooj = 1;
+	inst.cn98xx.dg = 0;
+	inst.cn98xx.doneint = 0;
+	/* W 1 */
+	inst.cn98xx.inp_ptr_addr = rte_pktmbuf_mtod(op->mbuf, uint64_t);
+	/* W 2 */
+	inst.cn98xx.inp_ptr_ctl = op->mbuf->data_len & 0x7FFF;
+	inst.cn98xx.inp_ptr_ctl = inst.cn98xx.inp_ptr_ctl << 32;
+
+	/* W 3 */
+	inst.cn98xx.res_ptr_addr = (uint64_t)op;
+	/* W 4 */
+	inst.cn98xx.wq_ptr = 0;
+	/* W 5 */
+	inst.cn98xx.ggrp = 0;
+	inst.cn98xx.tt = 0;
+	inst.cn98xx.tag = 0;
+	/* W 6 */
+	inst.cn98xx.ree_job_length = op->mbuf->data_len & 0x7FFF;
+	if (op->req_flags & RTE_REGEX_OPS_REQ_STOP_ON_MATCH_F)
+		inst.cn98xx.ree_job_ctrl = (0x2 << 8);
+	else if (op->req_flags & RTE_REGEX_OPS_REQ_MATCH_HIGH_PRIORITY_F)
+		inst.cn98xx.ree_job_ctrl = (0x1 << 8);
+	else
+		inst.cn98xx.ree_job_ctrl = 0;
+	inst.cn98xx.ree_job_id = qp->otx2_regexdev_jobid;
+	/* W 7 */
+	inst.cn98xx.ree_job_subset_id_0 = op->group_id0;
+	if (op->req_flags & RTE_REGEX_OPS_REQ_GROUP_ID1_VALID_F)
+		inst.cn98xx.ree_job_subset_id_1 = op->group_id1;
+	else
+		inst.cn98xx.ree_job_subset_id_1 = op->group_id0;
+	if (op->req_flags & RTE_REGEX_OPS_REQ_GROUP_ID2_VALID_F)
+		inst.cn98xx.ree_job_subset_id_2 = op->group_id2;
+	else
+		inst.cn98xx.ree_job_subset_id_2 = op->group_id0;
+	if (op->req_flags & RTE_REGEX_OPS_REQ_GROUP_ID3_VALID_F)
+		inst.cn98xx.ree_job_subset_id_3 = op->group_id3;
+	else
+		inst.cn98xx.ree_job_subset_id_3 = op->group_id0;
+
+	/* Copy REE command to Q */
+	offset = qp->write_offset * sizeof(inst);
+	memcpy((void *)(qp->iq_dma_addr + offset), &inst, sizeof(inst));
+
+	pend_q->rid_queue[pend_q->enq_tail].rid = (uintptr_t)op;
+	pend_q->rid_queue[pend_q->enq_tail].user_id = op->user_id;
+
+	/* Mark result as not done */
+	res = (union otx2_ree_res *)(op);
+	res->s.done = 0;
+	res->s.ree_err = 0;
+
+	/* We will use soft queue length here to limit requests */
+	REE_MOD_INC(pend_q->enq_tail, OTX2_REE_DEFAULT_CMD_QLEN);
+	pend_q->pending_count += 1;
+	REE_MOD_INC(qp->otx2_regexdev_jobid, 0xFFFFFF);
+	REE_MOD_INC(qp->write_offset, OTX2_REE_IQ_LEN);
+
+	return 0;
+}
+
+static uint16_t
+otx2_ree_enqueue_burst(struct rte_regexdev *dev, uint16_t qp_id,
+		       struct rte_regex_ops **ops, uint16_t nb_ops)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_qp *qp = data->queue_pairs[qp_id];
+	struct otx2_ree_pending_queue *pend_q;
+	uint16_t nb_allowed, count = 0;
+	struct rte_regex_ops *op;
+	int ret;
+
+	pend_q = &qp->pend_q;
+
+	nb_allowed = OTX2_REE_DEFAULT_CMD_QLEN - pend_q->pending_count;
+	if (nb_ops > nb_allowed)
+		nb_ops = nb_allowed;
+
+	for (count = 0; count < nb_ops; count++) {
+		op = ops[count];
+		ret = ree_enqueue(qp, op, pend_q);
+
+		if (unlikely(ret))
+			break;
+	}
+
+	/*
+	 * Make sure all instructions are written before DOORBELL is activated
+	 */
+	rte_io_wmb();
+
+	/* Update Doorbell */
+	otx2_write64(count, qp->base + OTX2_REE_LF_DOORBELL);
+
+	return count;
+}
+
+static inline void
+ree_dequeue_post_process(struct rte_regex_ops *ops)
+{
+	uint8_t ree_res_mcnt, ree_res_dmcnt;
+	int off = REE_MATCH_OFFSET;
+	struct ree_res_s_98 *res;
+	uint16_t ree_res_status;
+	uint64_t match;
+
+	res = (struct ree_res_s_98 *)ops;
+	/* store res values on stack since ops and res
+	 * are using the same memory
+	 */
+	ree_res_status = res->ree_res_status;
+	ree_res_mcnt = res->ree_res_mcnt;
+	ree_res_dmcnt = res->ree_res_dmcnt;
+	ops->rsp_flags = 0;
+	ops->nb_actual_matches = ree_res_dmcnt;
+	ops->nb_matches = ree_res_mcnt;
+	if (unlikely(res->ree_err)) {
+		ops->nb_actual_matches = 0;
+		ops->nb_matches = 0;
+	}
+
+	if (unlikely(ree_res_status != REE_TYPE_RESULT_DESC)) {
+		if (ree_res_status & OTX2_REE_STATUS_PMI_SOJ_BIT)
+			ops->rsp_flags |= RTE_REGEX_OPS_RSP_PMI_SOJ_F;
+		if (ree_res_status & OTX2_REE_STATUS_PMI_EOJ_BIT)
+			ops->rsp_flags |= RTE_REGEX_OPS_RSP_PMI_EOJ_F;
+		if (ree_res_status & OTX2_REE_STATUS_ML_CNT_DET_BIT)
+			ops->rsp_flags |= RTE_REGEX_OPS_RSP_MAX_SCAN_TIMEOUT_F;
+		if (ree_res_status & OTX2_REE_STATUS_MM_CNT_DET_BIT)
+			ops->rsp_flags |= RTE_REGEX_OPS_RSP_MAX_MATCH_F;
+		if (ree_res_status & OTX2_REE_STATUS_MP_CNT_DET_BIT)
+			ops->rsp_flags |= RTE_REGEX_OPS_RSP_MAX_PREFIX_F;
+	}
+	if (ops->nb_matches > 0) {
+		/* Move the matches to the correct offset */
+		off = ((ops->nb_matches < REE_NUM_MATCHES_ALIGN) ?
+			ops->nb_matches : REE_NUM_MATCHES_ALIGN);
+		match = (uint64_t)ops + REE_MATCH_OFFSET;
+		match += (ops->nb_matches - off) *
+			sizeof(union otx2_ree_match);
+		memcpy((void *)ops->matches, (void *)match,
+			off * sizeof(union otx2_ree_match));
+	}
+}
+
+static uint16_t
+otx2_ree_dequeue_burst(struct rte_regexdev *dev, uint16_t qp_id,
+		       struct rte_regex_ops **ops, uint16_t nb_ops)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_qp *qp = data->queue_pairs[qp_id];
+	struct otx2_ree_pending_queue *pend_q;
+	int i, nb_pending, nb_completed = 0;
+	volatile struct ree_res_s_98 *res;
+	struct otx2_ree_rid *rid;
+
+	pend_q = &qp->pend_q;
+
+	nb_pending = pend_q->pending_count;
+
+	if (nb_ops > nb_pending)
+		nb_ops = nb_pending;
+
+	for (i = 0; i < nb_ops; i++) {
+		rid = &pend_q->rid_queue[pend_q->deq_head];
+		res = (volatile struct ree_res_s_98 *)(rid->rid);
+
+		/* Check response header done bit if completed */
+		if (unlikely(!res->done))
+			break;
+
+		ops[i] = (struct rte_regex_ops *)(rid->rid);
+		ops[i]->user_id = rid->user_id;
+
+		REE_MOD_INC(pend_q->deq_head, OTX2_REE_DEFAULT_CMD_QLEN);
+		pend_q->pending_count -= 1;
+	}
+
+	nb_completed = i;
+
+	for (i = 0; i < nb_completed; i++)
+		ree_dequeue_post_process(ops[i]);
+
+	return nb_completed;
+}
+
+static int
+otx2_ree_dev_info_get(struct rte_regexdev *dev, struct rte_regexdev_info *info)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+
+	ree_func_trace();
+
+	if (info == NULL)
+		return -EINVAL;
+
+	info->driver_name = dev->device->driver->name;
+	info->dev = dev->device;
+
+	info->max_queue_pairs = vf->max_queues;
+	info->max_matches = vf->max_matches;
+	info->max_payload_size = OTX2_REE_MAX_PAYLOAD_SIZE;
+	info->max_rules_per_group = data->max_rules_per_group;
+	info->max_groups = data->max_groups;
+	info->regexdev_capa = data->regexdev_capa;
+	info->rule_flags = data->rule_flags;
+
+	return 0;
+}
+
+static int
+otx2_ree_dev_config(struct rte_regexdev *dev,
+		    const struct rte_regexdev_config *cfg)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	const struct ree_rule_db *rule_db;
+	uint32_t rule_db_len;
+	int ret;
+
+	ree_func_trace();
+
+	if (cfg->nb_queue_pairs > vf->max_queues) {
+		otx2_err("Invalid number of queue pairs requested");
+		return -EINVAL;
+	}
+
+	if (cfg->nb_max_matches != vf->max_matches) {
+		otx2_err("Invalid number of max matches requested");
+		return -EINVAL;
+	}
+
+	if (cfg->dev_cfg_flags != 0) {
+		otx2_err("Invalid device configuration flags requested");
+		return -EINVAL;
+	}
+
+	/* Unregister error interrupts */
+	if (vf->err_intr_registered)
+		otx2_ree_err_intr_unregister(dev);
+
+	/* Detach queues */
+	if (vf->nb_queues) {
+		ret = otx2_ree_queues_detach(dev);
+		if (ret) {
+			otx2_err("Could not detach REE queues");
+			return ret;
+		}
+	}
+
+	/* TEMP : should be in lib */
+	if (data->queue_pairs == NULL) { /* first time configuration */
+		data->queue_pairs = rte_zmalloc("regexdev->queue_pairs",
+				sizeof(data->queue_pairs[0]) *
+				cfg->nb_queue_pairs, RTE_CACHE_LINE_SIZE);
+
+		if (data->queue_pairs == NULL) {
+			data->nb_queue_pairs = 0;
+			otx2_err("Failed to get memory for qp meta data, nb_queues %u",
+					cfg->nb_queue_pairs);
+			return -ENOMEM;
+		}
+	} else { /* re-configure */
+		uint16_t old_nb_queues = data->nb_queue_pairs;
+		void **qp;
+		unsigned int i;
+
+		qp = data->queue_pairs;
+
+		for (i = cfg->nb_queue_pairs; i < old_nb_queues; i++) {
+			ret = ree_queue_pair_release(dev, i);
+			if (ret < 0)
+				return ret;
+		}
+
+		qp = rte_realloc(qp, sizeof(qp[0]) * cfg->nb_queue_pairs,
+				RTE_CACHE_LINE_SIZE);
+		if (qp == NULL) {
+			otx2_err("Failed to realloc qp meta data, nb_queues %u",
+					cfg->nb_queue_pairs);
+			return -ENOMEM;
+		}
+
+		if (cfg->nb_queue_pairs > old_nb_queues) {
+			uint16_t new_qs = cfg->nb_queue_pairs - old_nb_queues;
+			memset(qp + old_nb_queues, 0, sizeof(qp[0]) * new_qs);
+		}
+
+		data->queue_pairs = qp;
+	}
+	data->nb_queue_pairs = cfg->nb_queue_pairs;
+
+	/* Attach queues */
+	otx2_ree_dbg("Attach %d queues", cfg->nb_queue_pairs);
+	ret = otx2_ree_queues_attach(dev, cfg->nb_queue_pairs);
+	if (ret) {
+		otx2_err("Could not attach queues");
+		return -ENODEV;
+	}
+
+	ret = otx2_ree_msix_offsets_get(dev);
+	if (ret) {
+		otx2_err("Could not get MSI-X offsets");
+		goto queues_detach;
+	}
+
+	if (cfg->rule_db && cfg->rule_db_len) {
+		otx2_ree_dbg("rule_db length %d", cfg->rule_db_len);
+		rule_db = (const struct ree_rule_db *)cfg->rule_db;
+		rule_db_len = rule_db->number_of_entries *
+				sizeof(struct ree_rule_db_entry);
+		otx2_ree_dbg("rule_db number of entries %d",
+				rule_db->number_of_entries);
+		if (rule_db_len > cfg->rule_db_len) {
+			otx2_err("Could not program rule db");
+			ret = -EINVAL;
+			goto queues_detach;
+		}
+		ret = otx2_ree_rule_db_prog(dev, (const char *)rule_db->entries,
+				rule_db_len, NULL, OTX2_REE_NON_INC_PROG);
+		if (ret) {
+			otx2_err("Could not program rule db");
+			goto queues_detach;
+		}
+	}
+
+	dev->enqueue = otx2_ree_enqueue_burst;
+	dev->dequeue = otx2_ree_dequeue_burst;
+
+	rte_mb();
+	return 0;
+
+queues_detach:
+	otx2_ree_queues_detach(dev);
+	return ret;
+}
+
+static int
+otx2_ree_stop(struct rte_regexdev *dev)
+{
+	RTE_SET_USED(dev);
+
+	ree_func_trace();
+	return 0;
+}
+
+static int
+otx2_ree_start(struct rte_regexdev *dev)
+{
+	uint32_t rule_db_len = 0;
+	int ret;
+
+	ree_func_trace();
+
+	ret = otx2_ree_rule_db_len_get(dev, &rule_db_len, NULL);
+	if (ret)
+		return ret;
+	if (rule_db_len == 0) {
+		otx2_err("Rule db not programmed");
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+static int
+otx2_ree_close(struct rte_regexdev *dev)
+{
+	return ree_dev_fini(dev);
+}
+
+static int
+otx2_ree_queue_pair_setup(struct rte_regexdev *dev, uint16_t qp_id,
+		const struct rte_regexdev_qp_conf *qp_conf)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_qp *qp;
+
+	ree_func_trace("Queue=%d", qp_id);
+
+	if (data->queue_pairs[qp_id] != NULL)
+		ree_queue_pair_release(dev, qp_id);
+
+	if (qp_conf->nb_desc > OTX2_REE_DEFAULT_CMD_QLEN) {
+		otx2_err("Could not setup queue pair for %u descriptors",
+				qp_conf->nb_desc);
+		return -EINVAL;
+	}
+	if (qp_conf->qp_conf_flags != 0) {
+		otx2_err("Could not setup queue pair with configuration flags 0x%x",
+				qp_conf->qp_conf_flags);
+		return -EINVAL;
+	}
+
+	qp = ree_qp_create(dev, qp_id);
+	if (qp == NULL) {
+		otx2_err("Could not create queue pair %d", qp_id);
+		return -ENOMEM;
+	}
+	qp->cb = qp_conf->cb;
+	data->queue_pairs[qp_id] = qp;
+
+	return 0;
+}
+
+static int
+otx2_ree_rule_db_compile_activate(struct rte_regexdev *dev)
+{
+	return otx2_ree_rule_db_compile_prog(dev);
+}
+
+static int
+otx2_ree_rule_db_update(struct rte_regexdev *dev,
+		const struct rte_regexdev_rule *rules, uint16_t nb_rules)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct rte_regexdev_rule *old_ptr;
+	uint32_t i, sum_nb_rules;
+
+	ree_func_trace("nb_rules=%d", nb_rules);
+
+	for (i = 0; i < nb_rules; i++) {
+		if (rules[i].op == RTE_REGEX_RULE_OP_REMOVE)
+			break;
+		if (rules[i].group_id >= data->max_groups)
+			break;
+		if (rules[i].rule_id >= data->max_rules_per_group)
+			break;
+		/* logical implication
+		 * p    q    p -> q
+		 * 0    0      1
+		 * 0    1      1
+		 * 1    0      0
+		 * 1    1      1
+		 */
+		if ((~(rules[i].rule_flags) | data->rule_flags) == 0)
+			break;
+	}
+	nb_rules = i;
+
+	if (data->nb_rules == 0) {
+
+		data->rules = rte_malloc("rte_regexdev_rules",
+				nb_rules*sizeof(struct rte_regexdev_rule), 0);
+		if (data->rules == NULL)
+			return -ENOMEM;
+
+		memcpy(data->rules, rules,
+				nb_rules*sizeof(struct rte_regexdev_rule));
+		data->nb_rules = nb_rules;
+	} else {
+
+		old_ptr = data->rules;
+		sum_nb_rules = data->nb_rules + nb_rules;
+		data->rules = rte_realloc(data->rules,
+				sum_nb_rules * sizeof(struct rte_regexdev_rule),
+							0);
+		if (data->rules == NULL) {
+			data->rules = old_ptr;
+			return -ENOMEM;
+		}
+		memcpy(&data->rules[data->nb_rules], rules,
+				nb_rules*sizeof(struct rte_regexdev_rule));
+		data->nb_rules = sum_nb_rules;
+	}
+	return nb_rules;
+}
+
+static int
+otx2_ree_rule_db_import(struct rte_regexdev *dev, const char *rule_db,
+		uint32_t rule_db_len)
+{
+
+	const struct ree_rule_db *ree_rule_db;
+	uint32_t ree_rule_db_len;
+	int ret;
+
+	ree_func_trace("rule_db_len=%d", rule_db_len);
+
+	ree_rule_db = (const struct ree_rule_db *)rule_db;
+	ree_rule_db_len = ree_rule_db->number_of_entries *
+			sizeof(struct ree_rule_db_entry);
+	if (ree_rule_db_len > rule_db_len) {
+		otx2_err("Could not program rule db");
+		return -EINVAL;
+	}
+	ret = otx2_ree_rule_db_prog(dev, (const char *)ree_rule_db->entries,
+			ree_rule_db_len, NULL, OTX2_REE_NON_INC_PROG);
+	if (ret) {
+		otx2_err("Could not program rule db");
+		return -ENOSPC;
+	}
+	return 0;
+}
+
+static int
+otx2_ree_rule_db_export(struct rte_regexdev *dev, char *rule_db)
+{
+	struct ree_rule_db *ree_rule_db;
+	uint32_t rule_dbi_len;
+	uint32_t rule_db_len;
+	int ret;
+
+	ree_func_trace();
+
+	ret = otx2_ree_rule_db_len_get(dev, &rule_db_len, &rule_dbi_len);
+	if (ret)
+		return ret;
+
+	if (rule_db == NULL) {
+		rule_db_len += sizeof(struct ree_rule_db);
+		return rule_db_len;
+	}
+
+	ree_rule_db = (struct ree_rule_db *)rule_db;
+	ret = otx2_ree_rule_db_get(dev, (char *)ree_rule_db->entries,
+			rule_db_len, NULL, 0);
+	if (ret) {
+		otx2_err("Could not export rule db");
+		return -EFAULT;
+	}
+	ree_rule_db->number_of_entries =
+			rule_db_len/sizeof(struct ree_rule_db_entry);
+	ree_rule_db->revision = REE_RULE_DB_REVISION;
+	ree_rule_db->version = REE_RULE_DB_VERSION;
+
+	return 0;
+}
+
+static int
+ree_get_blkaddr(struct otx2_dev *dev)
+{
+	int pf;
+
+	pf = otx2_get_pf(dev->pf_func);
+	if (pf == REE0_PF)
+		return RVU_BLOCK_ADDR_REE0;
+	else if (pf == REE1_PF)
+		return RVU_BLOCK_ADDR_REE1;
+	else
+		return 0;
+}
+
+static struct rte_regexdev_ops otx2_ree_ops = {
+		.dev_info_get = otx2_ree_dev_info_get,
+		.dev_configure = otx2_ree_dev_config,
+		.dev_qp_setup = otx2_ree_queue_pair_setup,
+		.dev_start = otx2_ree_start,
+		.dev_stop = otx2_ree_stop,
+		.dev_close = otx2_ree_close,
+		.dev_attr_get = NULL,
+		.dev_attr_set = NULL,
+		.dev_rule_db_update = otx2_ree_rule_db_update,
+		.dev_rule_db_compile_activate =
+				otx2_ree_rule_db_compile_activate,
+		.dev_db_import = otx2_ree_rule_db_import,
+		.dev_db_export = otx2_ree_rule_db_export,
+		.dev_xstats_names_get = NULL,
+		.dev_xstats_get = NULL,
+		.dev_xstats_by_name_get = NULL,
+		.dev_xstats_reset = NULL,
+		.dev_selftest = NULL,
+		.dev_dump = NULL,
+};
+
+static int
+otx2_ree_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
+		   struct rte_pci_device *pci_dev)
+{
+	char name[RTE_REGEXDEV_NAME_MAX_LEN];
+	struct otx2_ree_data *data;
+	struct otx2_dev *otx2_dev;
+	struct rte_regexdev *dev;
+	uint8_t max_matches = 0;
+	struct otx2_ree_vf *vf;
+	uint16_t nb_queues = 0;
+	int ret;
+
+	rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
+
+	dev = ree_dev_register(name);
+	if (dev == NULL) {
+		ret = -ENODEV;
+		goto exit;
+	}
+
+	dev->dev_ops = &otx2_ree_ops;
+	dev->device = &pci_dev->device;
+
+	/* Get private data space allocated */
+	data = dev->data->dev_private;
+	vf = &data->vf;
+
+	otx2_dev = &vf->otx2_dev;
+
+	/* Initialize the base otx2_dev object */
+	ret = otx2_dev_init(pci_dev, otx2_dev);
+	if (ret) {
+		otx2_err("Could not initialize otx2_dev");
+		goto dev_unregister;
+	}
+	/* Get REE block address */
+	vf->block_address = ree_get_blkaddr(otx2_dev);
+	if (!vf->block_address) {
+		otx2_err("Could not determine block PF number");
+		goto otx2_dev_fini;
+	}
+
+	/* Get number of queues available on the device */
+	ret = otx2_ree_available_queues_get(dev, &nb_queues);
+	if (ret) {
+		otx2_err("Could not determine the number of queues available");
+		goto otx2_dev_fini;
+	}
+
+	/* Don't exceed the limits set per VF */
+	nb_queues = RTE_MIN(nb_queues, OTX2_REE_MAX_QUEUES_PER_VF);
+
+	if (nb_queues == 0) {
+		otx2_err("No free queues available on the device");
+		goto otx2_dev_fini;
+	}
+
+	vf->max_queues = nb_queues;
+
+	otx2_ree_dbg("Max queues supported by device: %d", vf->max_queues);
+
+	/* Get number of maximum matches supported on the device */
+	ret = otx2_ree_max_matches_get(dev, &max_matches);
+	if (ret) {
+		otx2_err("Could not determine the maximum matches supported");
+		goto otx2_dev_fini;
+	}
+	/* Don't exceed the limits set per VF */
+	max_matches = RTE_MIN(max_matches, OTX2_REE_MAX_MATCHES_PER_VF);
+	if (max_matches == 0) {
+		otx2_err("Could not determine the maximum matches supported");
+		goto otx2_dev_fini;
+	}
+
+	vf->max_matches = max_matches;
+
+	otx2_ree_dbg("Max matches supported by device: %d", vf->max_matches);
+	data->rule_flags = RTE_REGEX_PCRE_RULE_ALLOW_EMPTY_F |
+			RTE_REGEX_PCRE_RULE_ANCHORED_F;
+	data->regexdev_capa = 0;
+	data->max_groups = REE_MAX_GROUPS;
+	data->max_rules_per_group = REE_MAX_RULES_PER_GROUP;
+	data->nb_rules = 0;
+
+	dev->state = RTE_REGEXDEV_READY;
+	return 0;
+
+otx2_dev_fini:
+	otx2_dev_fini(pci_dev, otx2_dev);
+dev_unregister:
+	ree_dev_unregister(dev);
+exit:
+	otx2_err("Could not create device (vendor_id: 0x%x device_id: 0x%x)",
+		    pci_dev->id.vendor_id, pci_dev->id.device_id);
+	return ret;
+}
+
+static int
+otx2_ree_pci_remove(struct rte_pci_device *pci_dev)
+{
+	char name[RTE_REGEXDEV_NAME_MAX_LEN];
+	struct rte_regexdev *dev = NULL;
+
+	if (pci_dev == NULL)
+		return -EINVAL;
+
+	rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
+
+	dev = rte_regexdev_get_device_by_name(name);
+
+	if (dev == NULL)
+		return -ENODEV;
+
+	return ree_dev_fini(dev);
+}
+
+static struct rte_pci_id pci_id_ree_table[] = {
+	{
+		RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM,
+				PCI_DEVID_OCTEONTX2_RVU_REE_PF)
+	},
+};
+
+static struct rte_pci_driver otx2_regexdev_pmd = {
+	.id_table = pci_id_ree_table,
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING,
+	.probe = otx2_ree_pci_probe,
+	.remove = otx2_ree_pci_remove,
+};
+
+
+RTE_PMD_REGISTER_PCI(REGEXDEV_NAME_OCTEONTX2_PMD, otx2_regexdev_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(REGEXDEV_NAME_OCTEONTX2_PMD, pci_id_ree_table);
diff --git a/drivers/regex/octeontx2/otx2_regexdev.h b/drivers/regex/octeontx2/otx2_regexdev.h
new file mode 100644
index 000000000..d710535f5
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev.h
@@ -0,0 +1,109 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _OTX2_REGEXDEV_H_
+#define _OTX2_REGEXDEV_H_
+
+#include <rte_common.h>
+#include <rte_regexdev.h>
+
+#include "otx2_dev.h"
+
+#define ree_func_trace otx2_ree_dbg
+
+/* Marvell OCTEON TX2 Regex PMD device name */
+#define REGEXDEV_NAME_OCTEONTX2_PMD	regex_octeontx2
+
+#define OTX2_REE_MAX_LFS		36
+#define OTX2_REE_MAX_QUEUES_PER_VF	36
+#define OTX2_REE_MAX_MATCHES_PER_VF	254
+
+#define OTX2_REE_MAX_PAYLOAD_SIZE	(1 << 14)
+
+#define OTX2_REE_NON_INC_PROG 0
+#define OTX2_REE_INC_PROG 1
+
+#define REE_MOD_INC(i, l)   ((i) == (l - 1) ? (i) = 0 : (i)++)
+
+
+/**
+ * Device vf data
+ */
+struct otx2_ree_vf {
+	struct otx2_dev otx2_dev;
+	/**< Base class */
+	uint16_t max_queues;
+	/**< Max queues supported */
+	uint8_t nb_queues;
+	/**< Number of regex queues attached */
+	uint16_t max_matches;
+	/**<  Max matches supported*/
+	uint16_t lf_msixoff[OTX2_REE_MAX_LFS];
+	/**< MSI-X offsets */
+	uint8_t block_address;
+	/**< REE Block Address */
+	uint8_t err_intr_registered:1;
+	/**< Are error interrupts registered? */
+};
+
+/**
+ * Device private data
+ */
+struct otx2_ree_data {
+	uint32_t regexdev_capa;
+	uint64_t rule_flags;
+	/**< Feature flags exposes HW/SW features for the given device */
+	uint16_t max_rules_per_group;
+	/**< Maximum rules supported per subset by this device */
+	uint16_t max_groups;
+	/**< Maximum subset supported by this device */
+	void **queue_pairs;
+	/**< Array of pointers to queue pairs. */
+	uint16_t nb_queue_pairs;
+	/**< Number of device queue pairs. */
+	struct otx2_ree_vf vf;
+	/**< vf data */
+	struct rte_regexdev_rule *rules;
+	/**< rules to be compiled */
+	uint16_t nb_rules;
+	/**< number of rules */
+} __rte_cache_aligned;
+
+struct otx2_ree_rid {
+	uintptr_t rid;
+	/** Request id of a ree operation */
+	uint64_t user_id;
+	/* Client data */
+	/**< IOVA address of the pattern to be matched. */
+};
+
+struct otx2_ree_pending_queue {
+	uint64_t pending_count;
+	/** Pending requests count */
+	struct otx2_ree_rid *rid_queue;
+	/** Array of pending requests */
+	uint16_t enq_tail;
+	/** Tail of queue to be used for enqueue */
+	uint16_t deq_head;
+	/** Head of queue to be used for dequeue */
+};
+
+struct otx2_ree_qp {
+	uint32_t id;
+	/**< Queue pair id */
+	uintptr_t base;
+	/**< Base address where BAR is mapped */
+	struct otx2_ree_pending_queue pend_q;
+	/**< Pending queue */
+	rte_iova_t iq_dma_addr;
+	/**< Instruction queue address */
+	uint32_t otx2_regexdev_jobid;
+	/**< Job ID */
+	uint32_t write_offset;
+	/**< write offset */
+	regexdev_stop_flush_t cb;
+	/**< Callback function called during rte_regex_dev_stop()*/
+};
+
+#endif /* _OTX2_REGEXDEV_H_ */
diff --git a/drivers/regex/octeontx2/otx2_regexdev_compiler.c b/drivers/regex/octeontx2/otx2_regexdev_compiler.c
new file mode 100644
index 000000000..785459f74
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev_compiler.c
@@ -0,0 +1,229 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#include <rte_malloc.h>
+#include <rte_regexdev.h>
+
+#include "otx2_regexdev.h"
+#include "otx2_regexdev_compiler.h"
+#include "otx2_regexdev_mbox.h"
+
+#ifdef REE_COMPILER_SDK
+#include <rxp-compiler.h>
+
+static int
+ree_rule_db_compile(const struct rte_regexdev_rule *rules,
+		uint16_t nb_rules, struct rxp_rof **rof, struct rxp_rof **rofi,
+		struct rxp_rof *rof_for_incremental_compile,
+		struct rxp_rof *rofi_for_incremental_compile)
+{
+	/*INPUT*/
+	struct rxp_prefix_selection_control_list *prefix_selection_control_list
+		= NULL;
+	struct rxp_blacklist_data_sample *blacklist_sample_data = NULL;
+	struct rxp_rule_ids_to_remove *rule_ids_to_remove = NULL;
+	struct rxp_roff *roff_for_incremental_compile = NULL;
+
+	/*OPTIONS - setting default values*/
+	enum rxp_virtual_prefix_mode virtual_prefix_mode =
+			RXP_VIRTUAL_PREFIX_MODE_0;
+	enum rxp_prefix_capacity prefix_capacity = RXP_PREFIX_CAPACITY_32K;
+	/**< rxp_global_regex_options_flags*/
+	enum rxp_compiler_objective objective = RXP_COMPILER_OBJECTIVE_5;
+	enum rxp_tpe_data_width tpe_data_width = RXP_TPE_DATA_WIDTH_4;
+	uint32_t compiler_options = RXP_COMPILER_OPTIONS_FORCE;
+	/**< rxp_compiler_options_flags*/
+	enum rxp_verbose_level verbose = RXP_VERBOSE_LEVEL_3;
+	enum rxp_version set_rxp_version = RXP_VERSION_V5_8;
+	uint32_t compiler_output_flags = 0;
+	/**< rxp_compiler_output_flags*/
+	uint32_t global_regex_options = 0;
+	/**< rxp_global_regex_options_flags*/
+	float set_auto_blacklist = 0;
+	uint32_t max_rep_max = 65535;
+	uint32_t divide_ruleset = 1;
+	struct rxp_ruleset ruleset;
+	float ptpb_threshold = 0;
+	uint32_t set_max = 0;
+	uint32_t threads = 1;
+
+	/*OUTPUT*/
+	struct rxp_rule_direction_analysis *rule_direction_analysis = NULL;
+	struct rxp_compilation_statistics *compilation_statistics = NULL;
+	struct rxp_prefix_selection_control_list *generated_pscl = NULL;
+	struct rxp_uncompiled_rules_log *uncompiled_rules_log = NULL;
+	struct rxp_critical_rules_rank *critical_rules_rank = NULL;
+	struct rxp_compiled_rules_log *compiled_rules_log = NULL;
+	struct rxp_roff *roff = NULL;
+
+	uint16_t i;
+	int ret;
+
+	ruleset.number_of_entries = nb_rules;
+	ruleset.rules = rte_malloc("rxp_rule_entry",
+			nb_rules*sizeof(struct rxp_rule_entry), 0);
+
+	if (ruleset.rules == NULL) {
+		otx2_err("Could not allocate memory for rule compilation\n");
+		return -EFAULT;
+	}
+	if (rof_for_incremental_compile)
+		compiler_options |= RXP_COMPILER_OPTIONS_INCREMENTAL;
+	if (rofi_for_incremental_compile)
+		compiler_options |= RXP_COMPILER_OPTIONS_CHECKSUM;
+
+	for (i = 0; i < nb_rules; i++) {
+		ruleset.rules[i].number_of_prefix_entries = 0;
+		ruleset.rules[i].prefix = NULL;
+		ruleset.rules[i].rule = rules[i].pcre_rule;
+		ruleset.rules[i].rule_id = rules[i].rule_id;
+		ruleset.rules[i].subset_id = rules[i].group_id;
+		ruleset.rules[i].rule_direction_type =
+				RXP_RULE_DIRECTION_TYPE_NONE;
+	}
+
+	ret = rxp_compile_advanced(
+			/*INPUT*/
+			&ruleset,
+			prefix_selection_control_list,
+			rof_for_incremental_compile,
+			roff_for_incremental_compile,
+			rofi_for_incremental_compile,
+			rule_ids_to_remove,
+			blacklist_sample_data,
+
+			/*OPTIONS*/
+			compiler_options,
+			prefix_capacity,
+			global_regex_options,
+			set_auto_blacklist,
+			set_max,
+			objective,
+			ptpb_threshold,
+			max_rep_max,
+			threads,
+			set_rxp_version,
+			verbose,
+			tpe_data_width,
+			virtual_prefix_mode,
+			compiler_output_flags,
+			divide_ruleset,
+
+			/*OUTPUT*/
+			&compilation_statistics,
+			&compiled_rules_log,
+			&critical_rules_rank,
+			&rule_direction_analysis,
+			&uncompiled_rules_log,
+			rof,
+			&roff,
+			rofi,
+			&generated_pscl);
+	rte_free(ruleset.rules);
+
+	return ret;
+}
+
+int
+otx2_ree_rule_db_compile_prog(struct rte_regexdev *dev)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	char compiler_version[] = "20.5.2.eda0fa2";
+	char timestamp[] = "19700101_000001";
+	uint32_t rule_db_len, rule_dbi_len;
+	struct rxp_rof *rofi_inc_p = NULL;
+	struct rxp_rof_entry rule_dbi[6];
+	char *rofi_rof_entries = NULL;
+	struct rxp_rof *rofi = NULL;
+	struct rxp_rof *rof = NULL;
+	struct rxp_rof rofi_inc;
+	struct rxp_rof rof_inc;
+	char *rule_db = NULL;
+	int ret;
+
+	ree_func_trace();
+
+	ret = otx2_ree_rule_db_len_get(dev, &rule_db_len, &rule_dbi_len);
+	if (ret != 0) {
+		otx2_err("Could not get rule db length");
+		return ret;
+	}
+
+	if (rule_db_len > 0) {
+		otx2_ree_dbg("Incremental compile, rule db len %d rule dbi len %d",
+				rule_db_len, rule_dbi_len);
+		rule_db = rte_malloc("ree_rule_db", rule_db_len, 0);
+		if (!rule_db) {
+			otx2_err("Could not allocate memory for rule db");
+			return -EFAULT;
+		}
+
+		ret = otx2_ree_rule_db_get(dev, rule_db, rule_db_len,
+				(char *)rule_dbi, rule_dbi_len);
+		if (ret) {
+			otx2_err("Could not read rule db");
+			rte_free(rule_db);
+			return -EFAULT;
+		}
+		rof_inc.rof_revision = 0;
+		rof_inc.rof_version = 2;
+		rof_inc.rof_entries = (struct rxp_rof_entry *)rule_db;
+		rof_inc.rxp_compiler_version = compiler_version;
+		rof_inc.timestamp = timestamp;
+		rof_inc.number_of_entries =
+				(rule_db_len/sizeof(struct rxp_rof_entry));
+
+		if (rule_dbi_len > 0) {
+			/* incremental compilation not the first time */
+			rofi_inc.rof_revision = 0;
+			rofi_inc.rof_version = 2;
+			rofi_inc.rof_entries = rule_dbi;
+			rofi_inc.rxp_compiler_version = compiler_version;
+			rofi_inc.timestamp = timestamp;
+			rofi_inc.number_of_entries =
+				(rule_dbi_len/sizeof(struct rxp_rof_entry));
+			rofi_inc_p = &rofi_inc;
+		}
+		ret = ree_rule_db_compile(data->rules, data->nb_rules, &rof,
+				&rofi, &rof_inc, rofi_inc_p);
+		if (rofi->number_of_entries == 0) {
+			otx2_ree_dbg("No change to rule db");
+			ret = 0;
+			goto free_structs;
+		}
+		rule_dbi_len = rofi->number_of_entries *
+				sizeof(struct rxp_rof_entry);
+		rofi_rof_entries = (char *)rofi->rof_entries;
+	} else {
+		/* full compilation */
+		ret = ree_rule_db_compile(data->rules, data->nb_rules, &rof,
+				&rofi, NULL, NULL);
+	}
+	if (ret != 0) {
+		otx2_err("Could not compile rule db");
+		goto free_structs;
+	}
+	rule_db_len = rof->number_of_entries * sizeof(struct rxp_rof_entry);
+	ret = otx2_ree_rule_db_prog(dev, (char *)rof->rof_entries, rule_db_len,
+			rofi_rof_entries, rule_dbi_len);
+	if (ret)
+		otx2_err("Could not program rule db");
+
+free_structs:
+	rxp_free_structs(NULL, NULL, NULL, NULL, NULL, &rof, NULL, &rofi, NULL,
+			1);
+
+	if (rule_db)
+		rte_free(rule_db);
+
+	return ret;
+}
+#else
+int
+otx2_ree_rule_db_compile_prog(struct rte_regexdev *dev)
+{
+	RTE_SET_USED(dev);
+	return -ENOTSUP;
+}
+#endif
diff --git a/drivers/regex/octeontx2/otx2_regexdev_compiler.h b/drivers/regex/octeontx2/otx2_regexdev_compiler.h
new file mode 100644
index 000000000..8d2625bf7
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev_compiler.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _OTX2_REGEXDEV_COMPILER_H_
+#define _OTX2_REGEXDEV_COMPILER_H_
+
+int
+otx2_ree_rule_db_compile_prog(struct rte_regexdev *dev);
+
+#endif /* _OTX2_REGEXDEV_COMPILER_H_ */
diff --git a/drivers/regex/octeontx2/otx2_regexdev_hw_access.c b/drivers/regex/octeontx2/otx2_regexdev_hw_access.c
new file mode 100644
index 000000000..620d5c912
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev_hw_access.c
@@ -0,0 +1,167 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#include "otx2_common.h"
+#include "otx2_dev.h"
+#include "otx2_regexdev_hw_access.h"
+#include "otx2_regexdev_mbox.h"
+
+static void
+ree_lf_err_intr_handler(void *param)
+{
+	uintptr_t base = (uintptr_t)param;
+	uint8_t lf_id;
+	uint64_t intr;
+
+	lf_id = (base >> 12) & 0xFF;
+
+	intr = otx2_read64(base + OTX2_REE_LF_MISC_INT);
+	if (intr == 0)
+		return;
+
+	otx2_ree_dbg("LF %d MISC_INT: 0x%" PRIx64 "", lf_id, intr);
+
+	/* Clear interrupt */
+	otx2_write64(intr, base + OTX2_REE_LF_MISC_INT);
+}
+
+static void
+ree_lf_err_intr_unregister(const struct rte_regexdev *dev, uint16_t msix_off,
+			   uintptr_t base)
+{
+	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
+	struct rte_intr_handle *handle = &pci_dev->intr_handle;
+
+	/* Disable error interrupts */
+	otx2_write64(~0ull, base + OTX2_REE_LF_MISC_INT_ENA_W1C);
+
+	otx2_unregister_irq(handle, ree_lf_err_intr_handler, (void *)base,
+			    msix_off);
+}
+
+void
+otx2_ree_err_intr_unregister(const struct rte_regexdev *dev)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	uintptr_t base;
+	uint32_t i;
+
+	for (i = 0; i < vf->nb_queues; i++) {
+		base = OTX2_REE_LF_BAR2(vf, i);
+		ree_lf_err_intr_unregister(dev, vf->lf_msixoff[i], base);
+	}
+
+	vf->err_intr_registered = 0;
+}
+
+static int
+ree_lf_err_intr_register(const struct rte_regexdev *dev, uint16_t msix_off,
+			 uintptr_t base)
+{
+	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
+	struct rte_intr_handle *handle = &pci_dev->intr_handle;
+	int ret;
+
+	/* Disable error interrupts */
+	otx2_write64(~0ull, base + OTX2_REE_LF_MISC_INT_ENA_W1C);
+
+	/* Register error interrupt handler */
+	ret = otx2_register_irq(handle, ree_lf_err_intr_handler, (void *)base,
+				msix_off);
+	if (ret)
+		return ret;
+
+	/* Enable error interrupts */
+	otx2_write64(~0ull, base + OTX2_REE_LF_MISC_INT_ENA_W1S);
+
+	return 0;
+}
+
+int
+otx2_ree_err_intr_register(const struct rte_regexdev *dev)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	uint32_t i, j, ret;
+	uintptr_t base;
+
+	for (i = 0; i < vf->nb_queues; i++) {
+		if (vf->lf_msixoff[i] == MSIX_VECTOR_INVALID) {
+			otx2_err("Invalid REE LF MSI-X offset: 0x%x",
+				    vf->lf_msixoff[i]);
+			return -EINVAL;
+		}
+	}
+
+	for (i = 0; i < vf->nb_queues; i++) {
+		base = OTX2_REE_LF_BAR2(vf, i);
+		ret = ree_lf_err_intr_register(dev, vf->lf_msixoff[i], base);
+		if (ret)
+			goto intr_unregister;
+	}
+
+	vf->err_intr_registered = 1;
+	return 0;
+
+intr_unregister:
+	/* Unregister the ones already registered */
+	for (j = 0; j < i; j++) {
+		base = OTX2_REE_LF_BAR2(vf, j);
+		ree_lf_err_intr_unregister(dev, vf->lf_msixoff[j], base);
+	}
+	return ret;
+}
+
+int
+otx2_ree_iq_enable(const struct rte_regexdev *dev, const struct otx2_ree_qp *qp,
+		   uint8_t pri, uint32_t size_div2)
+{
+	union otx2_ree_lf_sbuf_addr base;
+	union otx2_ree_lf_ena lf_ena;
+
+	/* Set instruction queue size and priority */
+	otx2_ree_config_lf(dev, qp->id, pri, size_div2);
+
+	/* Set instruction queue base address */
+	/* Should be written after SBUF_CTL and before LF_ENA */
+
+	base.u = otx2_read64(qp->base + OTX2_REE_LF_SBUF_ADDR);
+	base.s.ptr = qp->iq_dma_addr >> 7;
+	otx2_write64(base.u, qp->base + OTX2_REE_LF_SBUF_ADDR);
+
+	/* Enable instruction queue */
+
+	lf_ena.u = otx2_read64(qp->base + OTX2_REE_LF_ENA);
+	lf_ena.s.ena = 1;
+	otx2_write64(lf_ena.u, qp->base + OTX2_REE_LF_ENA);
+
+	return 0;
+}
+
+void
+otx2_ree_iq_disable(struct otx2_ree_qp *qp)
+{
+	union otx2_ree_lf_ena lf_ena;
+
+	/* Stop instruction execution */
+	lf_ena.u = otx2_read64(qp->base + OTX2_REE_LF_ENA);
+	lf_ena.s.ena = 0x0;
+	otx2_write64(lf_ena.u, qp->base + OTX2_REE_LF_ENA);
+}
+
+int
+otx2_ree_max_matches_get(const struct rte_regexdev *dev, uint8_t *max_matches)
+{
+	union otx2_ree_af_reexm_max_match reexm_max_match;
+	int ret;
+
+	ret = otx2_ree_af_reg_read(dev, REE_AF_REEXM_MAX_MATCH,
+				   &reexm_max_match.u);
+	if (ret)
+		return ret;
+
+	*max_matches = reexm_max_match.s.max;
+	return 0;
+}
diff --git a/drivers/regex/octeontx2/otx2_regexdev_hw_access.h b/drivers/regex/octeontx2/otx2_regexdev_hw_access.h
new file mode 100644
index 000000000..dedf5f328
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev_hw_access.h
@@ -0,0 +1,202 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _OTX2_REGEXDEV_HW_ACCESS_H_
+#define _OTX2_REGEXDEV_HW_ACCESS_H_
+
+#include <stdint.h>
+
+#include "otx2_regexdev.h"
+
+/* REE instruction queue length */
+#define OTX2_REE_IQ_LEN			(1 << 13)
+
+#define OTX2_REE_DEFAULT_CMD_QLEN	OTX2_REE_IQ_LEN
+
+/* Status register bits */
+#define OTX2_REE_STATUS_PMI_EOJ_BIT		(1 << 14)
+#define OTX2_REE_STATUS_PMI_SOJ_BIT		(1 << 13)
+#define OTX2_REE_STATUS_MP_CNT_DET_BIT		(1 << 7)
+#define OTX2_REE_STATUS_MM_CNT_DET_BIT		(1 << 6)
+#define OTX2_REE_STATUS_ML_CNT_DET_BIT		(1 << 5)
+#define OTX2_REE_STATUS_MST_CNT_DET_BIT		(1 << 4)
+#define OTX2_REE_STATUS_MPT_CNT_DET_BIT		(1 << 3)
+
+/* Register offsets */
+/* REE LF registers */
+#define OTX2_REE_LF_DONE_INT		0x120ull
+#define OTX2_REE_LF_DONE_INT_W1S	0x130ull
+#define OTX2_REE_LF_DONE_INT_ENA_W1S	0x138ull
+#define OTX2_REE_LF_DONE_INT_ENA_W1C	0x140ull
+#define OTX2_REE_LF_MISC_INT		0x300ull
+#define OTX2_REE_LF_MISC_INT_W1S	0x310ull
+#define OTX2_REE_LF_MISC_INT_ENA_W1S	0x320ull
+#define OTX2_REE_LF_MISC_INT_ENA_W1C	0x330ull
+#define OTX2_REE_LF_ENA			0x10ull
+#define OTX2_REE_LF_SBUF_ADDR		0x20ull
+#define OTX2_REE_LF_DONE		0x100ull
+#define OTX2_REE_LF_DONE_ACK		0x110ull
+#define OTX2_REE_LF_DONE_WAIT		0x148ull
+#define OTX2_REE_LF_DOORBELL		0x400ull
+#define OTX2_REE_LF_OUTSTAND_JOB	0x410ull
+
+/* BAR 0 */
+#define OTX2_REE_AF_QUE_SBUF_CTL(a)	(0x1200ull | (uint64_t)(a) << 3)
+#define OTX2_REE_PRIV_LF_CFG(a)		(0x41000ull | (uint64_t)(a) << 3)
+
+#define OTX2_REE_LF_BAR2(vf, q_id) \
+		((vf)->otx2_dev.bar2 + \
+		 (((vf)->block_address << 20) | ((q_id) << 12)))
+
+
+#define OTX2_REE_QUEUE_HI_PRIO 0x1
+
+enum ree_desc_type_e {
+	REE_TYPE_JOB_DESC    = 0x0,
+	REE_TYPE_RESULT_DESC = 0x1,
+	REE_TYPE_ENUM_LAST   = 0x2
+};
+
+union otx2_ree_priv_lf_cfg {
+	uint64_t u;
+	struct {
+		uint64_t slot                        : 8;
+		uint64_t pf_func                     : 16;
+		uint64_t reserved_24_62              : 39;
+		uint64_t ena                         : 1;
+	} s;
+};
+
+
+union otx2_ree_lf_sbuf_addr {
+	uint64_t u;
+	struct {
+		uint64_t off                         : 7;
+		uint64_t ptr                         : 46;
+		uint64_t reserved_53_63              : 11;
+	} s;
+};
+
+union otx2_ree_lf_ena {
+	uint64_t u;
+	struct {
+		uint64_t ena                         : 1;
+		uint64_t reserved_1_63               : 63;
+	} s;
+};
+
+union otx2_ree_af_reexm_max_match {
+	uint64_t u;
+	struct {
+		uint64_t max                         : 8;
+		uint64_t reserved_8_63               : 56;
+	} s;
+};
+
+union otx2_ree_lf_done {
+	uint64_t u;
+	struct {
+		uint64_t done                        : 20;
+		uint64_t reserved_20_63              : 44;
+	} s;
+};
+
+union otx2_ree_inst {
+	uint64_t u[8];
+	struct  {
+		uint64_t doneint                     :  1;
+		uint64_t reserved_1_3                :  3;
+		uint64_t dg                          :  1;
+		uint64_t reserved_5_7                :  3;
+		uint64_t ooj                         :  1;
+		uint64_t reserved_9_15               :  7;
+		uint64_t reserved_16_63              : 48;
+		uint64_t inp_ptr_addr                : 64;
+		uint64_t inp_ptr_ctl                 : 64;
+		uint64_t res_ptr_addr                : 64;
+		uint64_t wq_ptr                      : 64;
+		uint64_t tag                         : 32;
+		uint64_t tt                          :  2;
+		uint64_t ggrp                        : 10;
+		uint64_t reserved_364_383            : 20;
+		uint64_t reserved_384_391            :  8;
+		uint64_t ree_job_id                  : 24;
+		uint64_t ree_job_ctrl                : 16;
+		uint64_t ree_job_length              : 15;
+		uint64_t reserved_447_447            :  1;
+		uint64_t ree_job_subset_id_0         : 16;
+		uint64_t ree_job_subset_id_1         : 16;
+		uint64_t ree_job_subset_id_2         : 16;
+		uint64_t ree_job_subset_id_3         : 16;
+	} cn98xx;
+};
+
+union otx2_ree_res_status {
+	uint64_t u;
+	struct {
+		uint64_t job_type                    :  3;
+		uint64_t mpt_cnt_det                 :  1;
+		uint64_t mst_cnt_det                 :  1;
+		uint64_t ml_cnt_det                  :  1;
+		uint64_t mm_cnt_det                  :  1;
+		uint64_t mp_cnt_det                  :  1;
+		uint64_t mode                        :  2;
+		uint64_t reserved_10_11              :  2;
+		uint64_t reserved_12_12              :  1;
+		uint64_t pmi_soj                     :  1;
+		uint64_t pmi_eoj                     :  1;
+		uint64_t reserved_15_15              :  1;
+		uint64_t reserved_16_63              : 48;
+	} s;
+};
+
+union otx2_ree_res {
+	uint64_t u[8];
+	struct ree_res_s_98 {
+		uint64_t done			:  1;
+		uint64_t hwjid			:  7;
+		uint64_t ree_res_job_id		: 24;
+		uint64_t ree_res_status		: 16;
+		uint64_t ree_res_dmcnt		:  8;
+		uint64_t ree_res_mcnt		:  8;
+		uint64_t ree_meta_ptcnt		: 16;
+		uint64_t ree_meta_icnt		: 16;
+		uint64_t ree_meta_lcnt		: 16;
+		uint64_t ree_pmi_min_byte_ptr	: 16;
+		uint64_t ree_err		:  1;
+		uint64_t reserved_129_190	: 62;
+		uint64_t doneint		:  1;
+		uint64_t reserved_192_255	: 64;
+		uint64_t reserved_256_319	: 64;
+		uint64_t reserved_320_383	: 64;
+		uint64_t reserved_384_447	: 64;
+		uint64_t reserved_448_511	: 64;
+	} s;
+};
+
+union otx2_ree_match {
+	uint64_t u;
+	struct {
+		uint64_t ree_rule_id                 : 32;
+		uint64_t start_ptr                   : 14;
+		uint64_t reserved_46_47              :  2;
+		uint64_t match_length                : 15;
+		uint64_t reserved_63_63              :  1;
+	} s;
+};
+
+void otx2_ree_err_intr_unregister(const struct rte_regexdev *dev);
+
+int otx2_ree_err_intr_register(const struct rte_regexdev *dev);
+
+int otx2_ree_iq_enable(const struct rte_regexdev *dev,
+		       const struct otx2_ree_qp *qp,
+		       uint8_t pri, uint32_t size_div128);
+
+void otx2_ree_iq_disable(struct otx2_ree_qp *qp);
+
+int otx2_ree_max_matches_get(const struct rte_regexdev *dev,
+			     uint8_t *max_matches);
+
+#endif /* _OTX2_REGEXDEV_HW_ACCESS_H_ */
diff --git a/drivers/regex/octeontx2/otx2_regexdev_mbox.c b/drivers/regex/octeontx2/otx2_regexdev_mbox.c
new file mode 100644
index 000000000..6d58d367d
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev_mbox.c
@@ -0,0 +1,401 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#include "otx2_common.h"
+#include "otx2_dev.h"
+#include "otx2_regexdev_mbox.h"
+#include "otx2_regexdev.h"
+
+int
+otx2_ree_available_queues_get(const struct rte_regexdev *dev,
+			      uint16_t *nb_queues)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct free_rsrcs_rsp *rsp;
+	struct otx2_dev *otx2_dev;
+	int ret;
+
+	otx2_dev = &vf->otx2_dev;
+	otx2_mbox_alloc_msg_free_rsrc_cnt(otx2_dev->mbox);
+
+	ret = otx2_mbox_process_msg(otx2_dev->mbox, (void *)&rsp);
+	if (ret)
+		return -EIO;
+
+	if (vf->block_address == RVU_BLOCK_ADDR_REE0)
+		*nb_queues = rsp->ree0;
+	else
+		*nb_queues = rsp->ree1;
+	return 0;
+}
+
+int
+otx2_ree_queues_attach(const struct rte_regexdev *dev, uint8_t nb_queues)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct rsrc_attach_req *req;
+	struct otx2_mbox *mbox;
+
+	/* Ask AF to attach required LFs */
+	mbox = vf->otx2_dev.mbox;
+	req = otx2_mbox_alloc_msg_attach_resources(mbox);
+
+	/* 1 LF = 1 queue */
+	req->reelfs = nb_queues;
+	req->ree_blkaddr = vf->block_address;
+
+	if (otx2_mbox_process(mbox) < 0)
+		return -EIO;
+
+	/* Update number of attached queues */
+	vf->nb_queues = nb_queues;
+
+	return 0;
+}
+
+int
+otx2_ree_queues_detach(const struct rte_regexdev *dev)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct rsrc_detach_req *req;
+	struct otx2_mbox *mbox;
+
+	mbox = vf->otx2_dev.mbox;
+	req = otx2_mbox_alloc_msg_detach_resources(mbox);
+	req->reelfs = true;
+	req->partial = true;
+	if (otx2_mbox_process(mbox) < 0)
+		return -EIO;
+
+	/* Queues have been detached */
+	vf->nb_queues = 0;
+
+	return 0;
+}
+
+int
+otx2_ree_msix_offsets_get(const struct rte_regexdev *dev)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct msix_offset_rsp *rsp;
+	struct otx2_mbox *mbox;
+	uint32_t i, ret;
+
+	/* Get REE MSI-X vector offsets */
+	mbox = vf->otx2_dev.mbox;
+	otx2_mbox_alloc_msg_msix_offset(mbox);
+
+	ret = otx2_mbox_process_msg(mbox, (void *)&rsp);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < vf->nb_queues; i++) {
+		if (vf->block_address == RVU_BLOCK_ADDR_REE0)
+			vf->lf_msixoff[i] = rsp->ree0_lf_msixoff[i];
+		else
+			vf->lf_msixoff[i] = rsp->ree1_lf_msixoff[i];
+		otx2_ree_dbg("lf_msixoff[%d]  0x%x", i, vf->lf_msixoff[i]);
+	}
+
+	return 0;
+}
+
+static int
+ree_send_mbox_msg(struct otx2_ree_vf *vf)
+{
+	struct otx2_mbox *mbox = vf->otx2_dev.mbox;
+	int ret;
+
+	otx2_mbox_msg_send(mbox, 0);
+
+	ret = otx2_mbox_wait_for_rsp(mbox, 0);
+	if (ret < 0) {
+		otx2_err("Could not get mailbox response");
+		return ret;
+	}
+
+	return 0;
+}
+
+int
+otx2_ree_config_lf(const struct rte_regexdev *dev, uint8_t lf, uint8_t pri,
+		   uint32_t size)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct ree_lf_req_msg *req;
+	struct otx2_mbox *mbox;
+	int ret;
+
+	mbox = vf->otx2_dev.mbox;
+	req = otx2_mbox_alloc_msg_ree_config_lf(mbox);
+
+	req->lf = lf;
+	req->pri =  pri ? 1 : 0;
+	req->size = size;
+	req->blkaddr = vf->block_address;
+
+	ret = otx2_mbox_process(mbox);
+	if (ret < 0) {
+		otx2_err("Could not get mailbox response");
+		return ret;
+	}
+	return 0;
+}
+
+int
+otx2_ree_af_reg_read(const struct rte_regexdev *dev, uint64_t reg,
+		     uint64_t *val)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct ree_rd_wr_reg_msg *msg;
+	struct otx2_mbox_dev *mdev;
+	struct otx2_mbox *mbox;
+	int ret, off;
+
+	mbox = vf->otx2_dev.mbox;
+	mdev = &mbox->dev[0];
+	msg = (struct ree_rd_wr_reg_msg *)otx2_mbox_alloc_msg_rsp(mbox, 0,
+						sizeof(*msg), sizeof(*msg));
+	if (msg == NULL) {
+		otx2_err("Could not allocate mailbox message");
+		return -EFAULT;
+	}
+
+	msg->hdr.id = MBOX_MSG_REE_RD_WR_REGISTER;
+	msg->hdr.sig = OTX2_MBOX_REQ_SIG;
+	msg->hdr.pcifunc = vf->otx2_dev.pf_func;
+	msg->is_write = 0;
+	msg->reg_offset = reg;
+	msg->ret_val = val;
+	msg->blkaddr = vf->block_address;
+
+	ret = ree_send_mbox_msg(vf);
+	if (ret < 0)
+		return ret;
+
+	off = mbox->rx_start +
+			RTE_ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
+	msg = (struct ree_rd_wr_reg_msg *) ((uintptr_t)mdev->mbase + off);
+
+	*val = msg->val;
+
+	return 0;
+}
+
+int
+otx2_ree_af_reg_write(const struct rte_regexdev *dev, uint64_t reg,
+		      uint64_t val)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct ree_rd_wr_reg_msg *msg;
+	struct otx2_mbox *mbox;
+
+	mbox = vf->otx2_dev.mbox;
+	msg = (struct ree_rd_wr_reg_msg *)otx2_mbox_alloc_msg_rsp(mbox, 0,
+						sizeof(*msg), sizeof(*msg));
+	if (msg == NULL) {
+		otx2_err("Could not allocate mailbox message");
+		return -EFAULT;
+	}
+
+	msg->hdr.id = MBOX_MSG_REE_RD_WR_REGISTER;
+	msg->hdr.sig = OTX2_MBOX_REQ_SIG;
+	msg->hdr.pcifunc = vf->otx2_dev.pf_func;
+	msg->is_write = 1;
+	msg->reg_offset = reg;
+	msg->val = val;
+	msg->blkaddr = vf->block_address;
+
+	return ree_send_mbox_msg(vf);
+}
+
+int
+otx2_ree_rule_db_get(const struct rte_regexdev *dev, char *rule_db,
+		uint32_t rule_db_len, char *rule_dbi, uint32_t rule_dbi_len)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct ree_rule_db_get_req_msg *req;
+	struct ree_rule_db_get_rsp_msg *rsp;
+	char *rule_db_ptr = (char *)rule_db;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct otx2_mbox *mbox;
+	int ret, last = 0;
+	uint32_t len = 0;
+
+	mbox = vf->otx2_dev.mbox;
+	if (!rule_db) {
+		otx2_err("Couldn't return rule db due to NULL pointer");
+		return -EFAULT;
+	}
+
+	while (!last) {
+		req = (struct ree_rule_db_get_req_msg *)
+			otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
+						sizeof(*rsp));
+		if (!req) {
+			otx2_err("Could not allocate mailbox message");
+			return -EFAULT;
+		}
+
+		req->hdr.id = MBOX_MSG_REE_RULE_DB_GET;
+		req->hdr.sig = OTX2_MBOX_REQ_SIG;
+		req->hdr.pcifunc = vf->otx2_dev.pf_func;
+		req->blkaddr = vf->block_address;
+		req->is_dbi = 0;
+		req->offset = len;
+		ret = otx2_mbox_process_msg(mbox, (void *)&rsp);
+		if (ret)
+			return ret;
+		if (rule_db_len < len + rsp->len) {
+			otx2_err("Rule db size is too small");
+			return -EFAULT;
+		}
+		otx2_mbox_memcpy(rule_db_ptr, rsp->rule_db, rsp->len);
+		len += rsp->len;
+		rule_db_ptr = rule_db_ptr + rsp->len;
+		last = rsp->is_last;
+	}
+
+	if (rule_dbi) {
+		req = (struct ree_rule_db_get_req_msg *)
+			otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
+						sizeof(*rsp));
+		if (!req) {
+			otx2_err("Could not allocate mailbox message");
+			return -EFAULT;
+		}
+
+		req->hdr.id = MBOX_MSG_REE_RULE_DB_GET;
+		req->hdr.sig = OTX2_MBOX_REQ_SIG;
+		req->hdr.pcifunc = vf->otx2_dev.pf_func;
+		req->blkaddr = vf->block_address;
+		req->is_dbi = 1;
+		req->offset = 0;
+
+		ret = otx2_mbox_process_msg(mbox, (void *)&rsp);
+		if (ret)
+			return ret;
+		if (rule_dbi_len < rsp->len) {
+			otx2_err("Rule dbi size is too small");
+			return -EFAULT;
+		}
+		otx2_mbox_memcpy(rule_dbi, rsp->rule_db, rsp->len);
+	}
+	return 0;
+}
+
+int
+otx2_ree_rule_db_len_get(const struct rte_regexdev *dev,
+		uint32_t *rule_db_len,
+		uint32_t *rule_dbi_len)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct ree_rule_db_len_rsp_msg *rsp;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct ree_req_msg *req;
+	struct otx2_mbox *mbox;
+	int ret;
+
+	mbox = vf->otx2_dev.mbox;
+	req = (struct ree_req_msg *)
+		otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req), sizeof(*rsp));
+	if (!req) {
+		otx2_err("Could not allocate mailbox message");
+		return -EFAULT;
+	}
+
+	req->hdr.id = MBOX_MSG_REE_RULE_DB_LEN_GET;
+	req->hdr.sig = OTX2_MBOX_REQ_SIG;
+	req->hdr.pcifunc = vf->otx2_dev.pf_func;
+	req->blkaddr = vf->block_address;
+	ret = otx2_mbox_process_msg(mbox, (void *)&rsp);
+	if (ret)
+		return ret;
+	if (rule_db_len != NULL)
+		*rule_db_len = rsp->len;
+	if (rule_dbi_len != NULL)
+		*rule_dbi_len = rsp->inc_len;
+
+	return 0;
+}
+
+static int
+ree_db_msg(const struct rte_regexdev *dev, const char *db, uint32_t db_len,
+		int inc, int dbi)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	uint32_t len_left = db_len, offset = 0;
+	struct ree_rule_db_prog_req_msg *req;
+	struct otx2_ree_vf *vf = &data->vf;
+	const char *rule_db_ptr = db;
+	struct otx2_mbox *mbox;
+	struct msg_rsp *rsp;
+	int ret;
+
+	mbox = vf->otx2_dev.mbox;
+	while (len_left) {
+		req = (struct ree_rule_db_prog_req_msg *)
+			otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
+						sizeof(*rsp));
+		if (!req) {
+			otx2_err("Could not allocate mailbox message");
+			return -EFAULT;
+		}
+		req->hdr.id = MBOX_MSG_REE_RULE_DB_PROG;
+		req->hdr.sig = OTX2_MBOX_REQ_SIG;
+		req->hdr.pcifunc = vf->otx2_dev.pf_func;
+		req->offset = offset;
+		req->total_len = db_len;
+		req->len = REE_RULE_DB_REQ_BLOCK_SIZE;
+		req->is_incremental = inc;
+		req->is_dbi = dbi;
+		req->blkaddr = vf->block_address;
+
+		if (len_left < REE_RULE_DB_REQ_BLOCK_SIZE) {
+			req->is_last = true;
+			req->len = len_left;
+		}
+		otx2_mbox_memcpy(req->rule_db, rule_db_ptr, req->len);
+		ret = otx2_mbox_process_msg(mbox, (void *)&rsp);
+		if (ret) {
+			otx2_err("Programming mailbox processing failed");
+			return ret;
+		}
+		len_left -= req->len;
+		offset += req->len;
+		rule_db_ptr = rule_db_ptr + req->len;
+	}
+	return 0;
+}
+
+int
+otx2_ree_rule_db_prog(const struct rte_regexdev *dev, const char *rule_db,
+		uint32_t rule_db_len, const char *rule_dbi,
+		uint32_t rule_dbi_len)
+{
+	int inc, ret;
+
+	if (rule_db_len == 0) {
+		otx2_err("Couldn't program empty rule db");
+		return -EFAULT;
+	}
+	inc = (rule_dbi_len != 0);
+	if ((rule_db == NULL) || (inc && (rule_dbi == NULL))) {
+		otx2_err("Couldn't program NULL rule db");
+		return -EFAULT;
+	}
+	if (inc) {
+		ret = ree_db_msg(dev, rule_dbi, rule_dbi_len, inc, 1);
+		if (ret)
+			return ret;
+	}
+	return ree_db_msg(dev, rule_db, rule_db_len, inc, 0);
+}
diff --git a/drivers/regex/octeontx2/otx2_regexdev_mbox.h b/drivers/regex/octeontx2/otx2_regexdev_mbox.h
new file mode 100644
index 000000000..953efa672
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev_mbox.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _OTX2_REGEXDEV_MBOX_H_
+#define _OTX2_REGEXDEV_MBOX_H_
+
+#include <rte_regexdev.h>
+
+int otx2_ree_available_queues_get(const struct rte_regexdev *dev,
+				  uint16_t *nb_queues);
+
+int otx2_ree_queues_attach(const struct rte_regexdev *dev, uint8_t nb_queues);
+
+int otx2_ree_queues_detach(const struct rte_regexdev *dev);
+
+int otx2_ree_msix_offsets_get(const struct rte_regexdev *dev);
+
+int otx2_ree_config_lf(const struct rte_regexdev *dev, uint8_t lf, uint8_t pri,
+		       uint32_t size);
+
+int otx2_ree_af_reg_read(const struct rte_regexdev *dev, uint64_t reg,
+			 uint64_t *val);
+
+int otx2_ree_af_reg_write(const struct rte_regexdev *dev, uint64_t reg,
+			  uint64_t val);
+
+int otx2_ree_rule_db_get(const struct rte_regexdev *dev, char *rule_db,
+		 uint32_t rule_db_len, char *rule_dbi, uint32_t rule_dbi_len);
+
+int otx2_ree_rule_db_len_get(const struct rte_regexdev *dev,
+			     uint32_t *rule_db_len, uint32_t *rule_dbi_len);
+
+int otx2_ree_rule_db_prog(const struct rte_regexdev *dev, const char *rule_db,
+		uint32_t rule_db_len, const char *rule_dbi,
+		uint32_t rule_dbi_len);
+
+#endif /* _OTX2_REGEXDEV_MBOX_H_ */
diff --git a/drivers/regex/octeontx2/rte_pmd_octeontx2_regex_version.map b/drivers/regex/octeontx2/rte_pmd_octeontx2_regex_version.map
new file mode 100644
index 000000000..34eb991c7
--- /dev/null
+++ b/drivers/regex/octeontx2/rte_pmd_octeontx2_regex_version.map
@@ -0,0 +1,3 @@
+DPDK_20.08 {
+	local: *;
+};
diff --git a/meson_options.txt b/meson_options.txt
index 9bf18ab6b..214b5f7f5 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -36,3 +36,5 @@ option('tests', type: 'boolean', value: true,
 	description: 'build unit tests')
 option('use_hpet', type: 'boolean', value: false,
 	description: 'use HPET timer in EAL')
+option('ree_compiler_sdk', type: 'string', value: '',
+	description: 'path to REE compiler SDK optional library for regex device')
\ No newline at end of file
-- 
2.28.0


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [dpdk-dev] [PATCH v2 3/4] usertools: add octeontx2 REE device binding
  2020-10-12 11:31 ` [dpdk-dev] [PATCH v2 " guyk
  2020-10-12 11:31   ` [dpdk-dev] [PATCH v2 1/4] common/octeontx2: add REE definitions and logging support guyk
  2020-10-12 11:31   ` [dpdk-dev] [PATCH v2 2/4] regex/octeontx2: add build infra and device support guyk
@ 2020-10-12 11:31   ` guyk
  2020-10-12 14:35     ` Thomas Monjalon
  2020-10-12 11:31   ` [dpdk-dev] [PATCH v2 4/4] doc: add Marvell OCTEON TX2 regex guide guyk
  3 siblings, 1 reply; 33+ messages in thread
From: guyk @ 2020-10-12 11:31 UTC (permalink / raw)
  To: orika, jerinj, ndabilpuram, thomas, mdr, nhorman,
	bruce.richardson, anatoly.burakov, john.mcnamara,
	marko.kovacevic
  Cc: dev, smadarf, dovrat, guyk, lironh

From: Guy Kaneti <guyk@marvell.com>

Update the devbind script with new section of regex devices, also
added OCTEONTX2 REE device ID to regex device list

Signed-off-by: Guy Kaneti <guyk@marvell.com>
---
 usertools/dpdk-devbind.py | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py
index 1d1113a08..cb2fc6009 100755
--- a/usertools/dpdk-devbind.py
+++ b/usertools/dpdk-devbind.py
@@ -41,6 +41,8 @@
               'SVendor': None, 'SDevice': None}
 octeontx2_dma = {'Class': '08', 'Vendor': '177d', 'Device': 'a081',
               'SVendor': None, 'SDevice': None}
+octeontx2_ree = {'Class': '08', 'Vendor': '177d', 'Device': 'a0f4',
+              'SVendor': None, 'SDevice': None}
 
 intel_ioat_bdw = {'Class': '08', 'Vendor': '8086', 'Device': '6f20,6f21,6f22,6f23,6f24,6f25,6f26,6f27,6f2e,6f2f',
               'SVendor': None, 'SDevice': None}
@@ -64,6 +66,7 @@
 misc_devices = [intel_ioat_bdw, intel_ioat_skx, intel_ioat_icx, intel_idxd_spr,
                 intel_ntb_skx, intel_ntb_icx,
                 octeontx2_dma]
+regex_devices = [octeontx2_ree]
 
 # global dict ethernet devices present. Dictionary indexed by PCI address.
 # Each device within this is itself a dictionary of device properties
@@ -650,6 +653,9 @@ def show_status():
     if status_dev == "misc" or status_dev == "all":
         show_device_status(misc_devices, "Misc (rawdev)")
 
+    if status_dev == "regex" or status_dev == "all":
+        show_device_status(regex_devices, "Regex")
+
 
 def pci_glob(arg):
     '''Returns a list containing either:
@@ -743,6 +749,7 @@ def do_arg_actions():
             get_device_details(mempool_devices)
             get_device_details(compress_devices)
             get_device_details(misc_devices)
+            get_device_details(regex_devices)
         show_status()
 
 
@@ -764,6 +771,7 @@ def main():
     get_device_details(mempool_devices)
     get_device_details(compress_devices)
     get_device_details(misc_devices)
+    get_device_details(regex_devices)
     do_arg_actions()
 
 if __name__ == "__main__":
-- 
2.28.0


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [dpdk-dev] [PATCH v2 4/4] doc: add Marvell OCTEON TX2 regex guide
  2020-10-12 11:31 ` [dpdk-dev] [PATCH v2 " guyk
                     ` (2 preceding siblings ...)
  2020-10-12 11:31   ` [dpdk-dev] [PATCH v2 3/4] usertools: add octeontx2 REE device binding guyk
@ 2020-10-12 11:31   ` guyk
  2020-10-12 14:38     ` Thomas Monjalon
  3 siblings, 1 reply; 33+ messages in thread
From: guyk @ 2020-10-12 11:31 UTC (permalink / raw)
  To: orika, jerinj, ndabilpuram, thomas, mdr, nhorman,
	bruce.richardson, anatoly.burakov, john.mcnamara,
	marko.kovacevic
  Cc: dev, smadarf, dovrat, guyk, lironh

From: Guy Kaneti <guyk@marvell.com>

Added Marvell OCTEON TX2 regex guide, features
and updated release notes.

Signed-off-by: Guy Kaneti <guyk@marvell.com>
---
 doc/guides/platform/octeontx2.rst           |  5 +++
 doc/guides/regexdevs/features/octeontx2.ini | 10 +++++
 doc/guides/regexdevs/index.rst              |  1 +
 doc/guides/regexdevs/octeontx2.rst          | 49 +++++++++++++++++++++
 doc/guides/rel_notes/release_20_11.rst      |  5 +++
 5 files changed, 70 insertions(+)
 create mode 100644 doc/guides/regexdevs/features/octeontx2.ini
 create mode 100644 doc/guides/regexdevs/octeontx2.rst

diff --git a/doc/guides/platform/octeontx2.rst b/doc/guides/platform/octeontx2.rst
index 13255eec5..c4d64ab4b 100644
--- a/doc/guides/platform/octeontx2.rst
+++ b/doc/guides/platform/octeontx2.rst
@@ -67,6 +67,8 @@ DPDK subsystem.
    +---+-----+--------------------------------------------------------------+
    | 9 | SDP | rte_ethdev                                                   |
    +---+-----+--------------------------------------------------------------+
+   | 10| REE | rte_regexdev                                                 |
+   +---+-----+--------------------------------------------------------------+
 
 PF0 is called the administrative / admin function (AF) and has exclusive
 privileges to provision RVU functional block's LFs to each of the PF/VF.
@@ -156,6 +158,9 @@ This section lists dataplane H/W block(s) available in OCTEON TX2 SoC.
 #. **Crypto Device Driver**
    See :doc:`../cryptodevs/octeontx2` for CPT crypto device driver information.
 
+#. **Regex Device Driver**
+   See :doc:`../regexdevs/octeontx2` for REE regex device driver information.
+
 Procedure to Setup Platform
 ---------------------------
 
diff --git a/doc/guides/regexdevs/features/octeontx2.ini b/doc/guides/regexdevs/features/octeontx2.ini
new file mode 100644
index 000000000..c9b421a16
--- /dev/null
+++ b/doc/guides/regexdevs/features/octeontx2.ini
@@ -0,0 +1,10 @@
+;
+; Supported features of the 'octeontx2' regex driver.
+;
+; Refer to default.ini for the full list of available driver features.
+;
+[Features]
+PCRE back reference         = Y
+PCRE word boundary          = Y
+Run time compilation        = Y
+Armv8                       = Y
diff --git a/doc/guides/regexdevs/index.rst b/doc/guides/regexdevs/index.rst
index 49216a932..b1abc826b 100644
--- a/doc/guides/regexdevs/index.rst
+++ b/doc/guides/regexdevs/index.rst
@@ -13,3 +13,4 @@ which can be used from an application through RegEx API.
 
    features_overview
    mlx5
+   octeontx2
diff --git a/doc/guides/regexdevs/octeontx2.rst b/doc/guides/regexdevs/octeontx2.rst
new file mode 100644
index 000000000..859780da1
--- /dev/null
+++ b/doc/guides/regexdevs/octeontx2.rst
@@ -0,0 +1,49 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright(c) 2020 Marvell International Ltd.
+
+OCTEON TX2 REE Regexdev Driver
+===============================
+
+The OCTEON TX2 REE PMD (**librte_pmd_octeontx2_regex**) provides poll mode
+regexdev driver support for the inbuilt regex device found in the **Marvell OCTEON TX2**
+SoC family.
+
+More information about OCTEON TX2 SoC can be found at `Marvell Official Website
+<https://www.marvell.com/embedded-processors/infrastructure-processors/>`_.
+
+Features
+--------
+
+Features of the OCTEON TX2 REE PMD are:
+
+- 36 queues
+- Up to 254 matches for each regex operation
+
+Prerequisites and Compilation procedure
+---------------------------------------
+
+   See :doc:`../platform/octeontx2` for setup information.
+
+Device Setup
+------------
+
+The OCTEON TX2 REE devices will need to be bound to a user-space IO driver
+for use. The script ``dpdk-devbind.py`` script included with DPDK can be
+used to view the state of the devices and to bind them to a suitable
+DPDK-supported kernel driver. When querying the status of the devices,
+they will appear under the category of "REGEX devices", i.e. the command
+``dpdk-devbind.py --status-dev regex`` can be used to see the state of
+those devices alone.
+
+Debugging Options
+-----------------
+
+.. _table_octeontx2_regex_debug_options:
+
+.. table:: OCTEON TX2 regex device debug options
+
+   +---+------------+-------------------------------------------------------+
+   | # | Component  | EAL log command                                       |
+   +===+============+=======================================================+
+   | 1 | REE        | --log-level='pmd\.regex\.octeontx2,8'                 |
+   +---+------------+-------------------------------------------------------+
diff --git a/doc/guides/rel_notes/release_20_11.rst b/doc/guides/rel_notes/release_20_11.rst
index 57e3edcdd..90b32936f 100644
--- a/doc/guides/rel_notes/release_20_11.rst
+++ b/doc/guides/rel_notes/release_20_11.rst
@@ -148,6 +148,11 @@ New Features
   * Extern objects and functions can be plugged into the pipeline.
   * Transaction-oriented table updates.
 
+* **Added Marvell OCTEON TX2 regex PMD.**
+
+  Added a new PMD driver for hardware regex offload block for OCTEON TX2 SoC.
+
+  See the :doc:`../regexdevs/octeontx2` for more details.
 
 Removed Items
 -------------
-- 
2.28.0


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [dpdk-dev] [EXT] Re: [PATCH 0/4] Add Marvell OCTEON TX2 regex driver
  2020-10-11 21:23   ` Thomas Monjalon
@ 2020-10-12 11:34     ` Guy Kaneti
  0 siblings, 0 replies; 33+ messages in thread
From: Guy Kaneti @ 2020-10-12 11:34 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: Jerin Jacob Kollanukkaran, Nithin Kumar Dabilpuram, mdr, nhorman,
	bruce.richardson, anatoly.burakov, john.mcnamara,
	marko.kovacevic, orika, dev, Smadar Fuks, Dovrat Zifroni

Sure, I sent patch v2

-----Original Message-----
From: Thomas Monjalon <thomas@monjalon.net> 
Sent: Monday, October 12, 2020 12:23 AM
To: Guy Kaneti <guyk@marvell.com>
Cc: Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Nithin Kumar Dabilpuram <ndabilpuram@marvell.com>; mdr@ashroe.eu; nhorman@tuxdriver.com; bruce.richardson@intel.com; anatoly.burakov@intel.com; john.mcnamara@intel.com; marko.kovacevic@intel.com; orika@mellanox.com; dev@dpdk.org; Smadar Fuks <smadarf@marvell.com>; Dovrat Zifroni <dovrat@marvell.com>
Subject: [EXT] Re: [dpdk-dev] [PATCH 0/4] Add Marvell OCTEON TX2 regex driver

External Email

----------------------------------------------------------------------
08/10/2020 08:31, Guy Kaneti:
> Kind reminder to all maintainers, please review and ack/comment.

Please could you rebase?

The 2 rebase issues I see are:
	- make is removed
	- rte_cio_wmb is removed




^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [dpdk-dev] [PATCH v2 2/4] regex/octeontx2: add build infra and device support
  2020-10-12 11:31   ` [dpdk-dev] [PATCH v2 2/4] regex/octeontx2: add build infra and device support guyk
@ 2020-10-12 14:33     ` Thomas Monjalon
  2020-10-12 17:06       ` [dpdk-dev] [EXT] " Guy Kaneti
  0 siblings, 1 reply; 33+ messages in thread
From: Thomas Monjalon @ 2020-10-12 14:33 UTC (permalink / raw)
  To: guyk
  Cc: orika, jerinj, ndabilpuram, mdr, nhorman, bruce.richardson,
	anatoly.burakov, john.mcnamara, marko.kovacevic, dev, smadarf,
	dovrat, lironh

12/10/2020 13:31, guyk@marvell.com:
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1118,6 +1118,9 @@ F: drivers/regex/mlx5/
>  F: doc/guides/regexdevs/mlx5.rst
>  F: doc/guides/regexdevs/features/mlx5.ini
>  
> +Marvell OCTEON TX2 regex
> +M: Guy Kaneti <guyk@marvell.com>
> +F: drivers/regex/octeontx2/
>  

A blank line is missing.
Please sort in alphabetical order.

> --- /dev/null
> +++ b/drivers/regex/octeontx2/rte_pmd_octeontx2_regex_version.map
> @@ -0,0 +1,3 @@
> +DPDK_20.08 {
> +	local: *;
> +};

Should be DPDK_21

> --- a/meson_options.txt
> +++ b/meson_options.txt
> +option('ree_compiler_sdk', type: 'string', value: '',
> +	description: 'path to REE compiler SDK optional library for regex device')

Is this SDK specific to Marvell or octeontx2?
If yes, it should appear here.

Why this SDK requires setting the path manually?
Well designed libs should use pkg-config.




^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [dpdk-dev] [PATCH v2 3/4] usertools: add octeontx2 REE device binding
  2020-10-12 11:31   ` [dpdk-dev] [PATCH v2 3/4] usertools: add octeontx2 REE device binding guyk
@ 2020-10-12 14:35     ` Thomas Monjalon
  0 siblings, 0 replies; 33+ messages in thread
From: Thomas Monjalon @ 2020-10-12 14:35 UTC (permalink / raw)
  To: guyk
  Cc: orika, jerinj, ndabilpuram, mdr, nhorman, bruce.richardson,
	anatoly.burakov, john.mcnamara, marko.kovacevic, dev, smadarf,
	dovrat, lironh

12/10/2020 13:31, guyk@marvell.com:
> From: Guy Kaneti <guyk@marvell.com>
> 
> Update the devbind script with new section of regex devices, also
> added OCTEONTX2 REE device ID to regex device list
> 
> Signed-off-by: Guy Kaneti <guyk@marvell.com>
> ---
>  usertools/dpdk-devbind.py | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py
> index 1d1113a08..cb2fc6009 100755
> --- a/usertools/dpdk-devbind.py
> +++ b/usertools/dpdk-devbind.py
> @@ -41,6 +41,8 @@
>                'SVendor': None, 'SDevice': None}
>  octeontx2_dma = {'Class': '08', 'Vendor': '177d', 'Device': 'a081',
>                'SVendor': None, 'SDevice': None}
> +octeontx2_ree = {'Class': '08', 'Vendor': '177d', 'Device': 'a0f4',
> +              'SVendor': None, 'SDevice': None}
>  
>  intel_ioat_bdw = {'Class': '08', 'Vendor': '8086', 'Device': '6f20,6f21,6f22,6f23,6f24,6f25,6f26,6f27,6f2e,6f2f',
>                'SVendor': None, 'SDevice': None}
> @@ -64,6 +66,7 @@
>  misc_devices = [intel_ioat_bdw, intel_ioat_skx, intel_ioat_icx, intel_idxd_spr,
>                  intel_ntb_skx, intel_ntb_icx,
>                  octeontx2_dma]
> +regex_devices = [octeontx2_ree]

Please add regex befort misc devices.

[...]
>              get_device_details(mempool_devices)
>              get_device_details(compress_devices)
>              get_device_details(misc_devices)
> +            get_device_details(regex_devices)

Here as well, before misc.


> @@ -764,6 +771,7 @@ def main():
>      get_device_details(mempool_devices)
>      get_device_details(compress_devices)
>      get_device_details(misc_devices)
> +    get_device_details(regex_devices)

Same



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [dpdk-dev] [PATCH v2 4/4] doc: add Marvell OCTEON TX2 regex guide
  2020-10-12 11:31   ` [dpdk-dev] [PATCH v2 4/4] doc: add Marvell OCTEON TX2 regex guide guyk
@ 2020-10-12 14:38     ` Thomas Monjalon
  2020-10-12 17:09       ` [dpdk-dev] [EXT] " Guy Kaneti
  0 siblings, 1 reply; 33+ messages in thread
From: Thomas Monjalon @ 2020-10-12 14:38 UTC (permalink / raw)
  To: guyk
  Cc: orika, jerinj, ndabilpuram, mdr, nhorman, bruce.richardson,
	anatoly.burakov, john.mcnamara, marko.kovacevic, dev, smadarf,
	dovrat, lironh

12/10/2020 13:31, guyk@marvell.com:
> From: Guy Kaneti <guyk@marvell.com>
> 
> Added Marvell OCTEON TX2 regex guide, features
> and updated release notes.

I think this patch should be merged with doc changes:
	- almost all in patch 2 with driver code
	- the dpdk-devbind.py chapter in patch 3


> Signed-off-by: Guy Kaneti <guyk@marvell.com>
> ---
>  doc/guides/platform/octeontx2.rst           |  5 +++
>  doc/guides/regexdevs/features/octeontx2.ini | 10 +++++
>  doc/guides/regexdevs/index.rst              |  1 +
>  doc/guides/regexdevs/octeontx2.rst          | 49 +++++++++++++++++++++
>  doc/guides/rel_notes/release_20_11.rst      |  5 +++
>  5 files changed, 70 insertions(+)
>  create mode 100644 doc/guides/regexdevs/features/octeontx2.ini
>  create mode 100644 doc/guides/regexdevs/octeontx2.rst
> 
> diff --git a/doc/guides/platform/octeontx2.rst b/doc/guides/platform/octeontx2.rst
> index 13255eec5..c4d64ab4b 100644
> --- a/doc/guides/platform/octeontx2.rst
> +++ b/doc/guides/platform/octeontx2.rst
> @@ -67,6 +67,8 @@ DPDK subsystem.
>     +---+-----+--------------------------------------------------------------+
>     | 9 | SDP | rte_ethdev                                                   |
>     +---+-----+--------------------------------------------------------------+
> +   | 10| REE | rte_regexdev                                                 |
> +   +---+-----+--------------------------------------------------------------+
>  
>  PF0 is called the administrative / admin function (AF) and has exclusive
>  privileges to provision RVU functional block's LFs to each of the PF/VF.
> @@ -156,6 +158,9 @@ This section lists dataplane H/W block(s) available in OCTEON TX2 SoC.
>  #. **Crypto Device Driver**
>     See :doc:`../cryptodevs/octeontx2` for CPT crypto device driver information.
>  
> +#. **Regex Device Driver**
> +   See :doc:`../regexdevs/octeontx2` for REE regex device driver information.
> +
>  Procedure to Setup Platform
>  ---------------------------
>  
> diff --git a/doc/guides/regexdevs/features/octeontx2.ini b/doc/guides/regexdevs/features/octeontx2.ini
> new file mode 100644
> index 000000000..c9b421a16
> --- /dev/null
> +++ b/doc/guides/regexdevs/features/octeontx2.ini
> @@ -0,0 +1,10 @@
> +;
> +; Supported features of the 'octeontx2' regex driver.
> +;
> +; Refer to default.ini for the full list of available driver features.
> +;
> +[Features]
> +PCRE back reference         = Y
> +PCRE word boundary          = Y
> +Run time compilation        = Y
> +Armv8                       = Y
> diff --git a/doc/guides/regexdevs/index.rst b/doc/guides/regexdevs/index.rst
> index 49216a932..b1abc826b 100644
> --- a/doc/guides/regexdevs/index.rst
> +++ b/doc/guides/regexdevs/index.rst
> @@ -13,3 +13,4 @@ which can be used from an application through RegEx API.
>  
>     features_overview
>     mlx5
> +   octeontx2
> diff --git a/doc/guides/regexdevs/octeontx2.rst b/doc/guides/regexdevs/octeontx2.rst
> new file mode 100644
> index 000000000..859780da1
> --- /dev/null
> +++ b/doc/guides/regexdevs/octeontx2.rst
> @@ -0,0 +1,49 @@
> +..  SPDX-License-Identifier: BSD-3-Clause
> +    Copyright(c) 2020 Marvell International Ltd.
> +
> +OCTEON TX2 REE Regexdev Driver
> +===============================
> +
> +The OCTEON TX2 REE PMD (**librte_pmd_octeontx2_regex**) provides poll mode
> +regexdev driver support for the inbuilt regex device found in the **Marvell OCTEON TX2**
> +SoC family.
> +
> +More information about OCTEON TX2 SoC can be found at `Marvell Official Website
> +<https://www.marvell.com/embedded-processors/infrastructure-processors/>`_.
> +
> +Features
> +--------
> +
> +Features of the OCTEON TX2 REE PMD are:
> +
> +- 36 queues
> +- Up to 254 matches for each regex operation
> +
> +Prerequisites and Compilation procedure
> +---------------------------------------
> +
> +   See :doc:`../platform/octeontx2` for setup information.
> +
> +Device Setup
> +------------
> +
> +The OCTEON TX2 REE devices will need to be bound to a user-space IO driver
> +for use. The script ``dpdk-devbind.py`` script included with DPDK can be
> +used to view the state of the devices and to bind them to a suitable
> +DPDK-supported kernel driver. When querying the status of the devices,
> +they will appear under the category of "REGEX devices", i.e. the command
> +``dpdk-devbind.py --status-dev regex`` can be used to see the state of
> +those devices alone.
> +
> +Debugging Options
> +-----------------
> +
> +.. _table_octeontx2_regex_debug_options:
> +
> +.. table:: OCTEON TX2 regex device debug options
> +
> +   +---+------------+-------------------------------------------------------+
> +   | # | Component  | EAL log command                                       |
> +   +===+============+=======================================================+
> +   | 1 | REE        | --log-level='pmd\.regex\.octeontx2,8'                 |
> +   +---+------------+-------------------------------------------------------+
> diff --git a/doc/guides/rel_notes/release_20_11.rst b/doc/guides/rel_notes/release_20_11.rst
> index 57e3edcdd..90b32936f 100644
> --- a/doc/guides/rel_notes/release_20_11.rst
> +++ b/doc/guides/rel_notes/release_20_11.rst
> @@ -148,6 +148,11 @@ New Features
>    * Extern objects and functions can be plugged into the pipeline.
>    * Transaction-oriented table updates.
>  
> +* **Added Marvell OCTEON TX2 regex PMD.**
> +
> +  Added a new PMD driver for hardware regex offload block for OCTEON TX2 SoC.
> +
> +  See the :doc:`../regexdevs/octeontx2` for more details.

Missing blank line and should be sorted with other drivers (before rawdev).




^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [dpdk-dev] [EXT] Re: [PATCH v2 2/4] regex/octeontx2: add build infra and device support
  2020-10-12 14:33     ` Thomas Monjalon
@ 2020-10-12 17:06       ` Guy Kaneti
  2020-10-12 17:10         ` Thomas Monjalon
  0 siblings, 1 reply; 33+ messages in thread
From: Guy Kaneti @ 2020-10-12 17:06 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: orika, Jerin Jacob Kollanukkaran, Nithin Kumar Dabilpuram, mdr,
	nhorman, bruce.richardson, anatoly.burakov, john.mcnamara,
	marko.kovacevic, dev, Smadar Fuks, Dovrat Zifroni, Liron Himi

Hi

> -----Original Message-----
> From: Thomas Monjalon <thomas@monjalon.net>
> Sent: Monday, October 12, 2020 5:33 PM
> To: Guy Kaneti <guyk@marvell.com>
> Cc: orika@mellanox.com; Jerin Jacob Kollanukkaran <jerinj@marvell.com>;
> Nithin Kumar Dabilpuram <ndabilpuram@marvell.com>; mdr@ashroe.eu;
> nhorman@tuxdriver.com; bruce.richardson@intel.com;
> anatoly.burakov@intel.com; john.mcnamara@intel.com;
> marko.kovacevic@intel.com; dev@dpdk.org; Smadar Fuks
> <smadarf@marvell.com>; Dovrat Zifroni <dovrat@marvell.com>; Liron Himi
> <lironh@marvell.com>
> Subject: [EXT] Re: [dpdk-dev] [PATCH v2 2/4] regex/octeontx2: add build
> infra and device support
> 
> External Email
> 
> ----------------------------------------------------------------------
> 12/10/2020 13:31, guyk@marvell.com:
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -1118,6 +1118,9 @@ F: drivers/regex/mlx5/
> >  F: doc/guides/regexdevs/mlx5.rst
> >  F: doc/guides/regexdevs/features/mlx5.ini
> >
> > +Marvell OCTEON TX2 regex
> > +M: Guy Kaneti <guyk@marvell.com>
> > +F: drivers/regex/octeontx2/
> >
> 
> A blank line is missing.
> Please sort in alphabetical order.

Will fix

> 
> > --- /dev/null
> > +++ b/drivers/regex/octeontx2/rte_pmd_octeontx2_regex_version.map
> > @@ -0,0 +1,3 @@
> > +DPDK_20.08 {
> > +	local: *;
> > +};
> 
> Should be DPDK_21

Will fix

> 
> > --- a/meson_options.txt
> > +++ b/meson_options.txt
> > +option('ree_compiler_sdk', type: 'string', value: '',
> > +	description: 'path to REE compiler SDK optional library for regex
> device')
> 
> Is this SDK specific to Marvell or octeontx2?
> If yes, it should appear here.

Yes, it is specific to Marvell.

> 
> Why this SDK requires setting the path manually?
> Well designed libs should use pkg-config.
> 
> 


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [dpdk-dev] [EXT] Re: [PATCH v2 4/4] doc: add Marvell OCTEON TX2 regex guide
  2020-10-12 14:38     ` Thomas Monjalon
@ 2020-10-12 17:09       ` Guy Kaneti
  2020-10-12 17:12         ` Thomas Monjalon
  0 siblings, 1 reply; 33+ messages in thread
From: Guy Kaneti @ 2020-10-12 17:09 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: orika, Jerin Jacob Kollanukkaran, Nithin Kumar Dabilpuram, mdr,
	nhorman, bruce.richardson, anatoly.burakov, john.mcnamara,
	marko.kovacevic, dev, Smadar Fuks, Dovrat Zifroni, Liron Himi

Hi,

> -----Original Message-----
> From: Thomas Monjalon <thomas@monjalon.net>
> Sent: Monday, October 12, 2020 5:39 PM
> To: Guy Kaneti <guyk@marvell.com>
> Cc: orika@mellanox.com; Jerin Jacob Kollanukkaran <jerinj@marvell.com>;
> Nithin Kumar Dabilpuram <ndabilpuram@marvell.com>; mdr@ashroe.eu;
> nhorman@tuxdriver.com; bruce.richardson@intel.com;
> anatoly.burakov@intel.com; john.mcnamara@intel.com;
> marko.kovacevic@intel.com; dev@dpdk.org; Smadar Fuks
> <smadarf@marvell.com>; Dovrat Zifroni <dovrat@marvell.com>; Liron Himi
> <lironh@marvell.com>
> Subject: [EXT] Re: [dpdk-dev] [PATCH v2 4/4] doc: add Marvell OCTEON TX2
> regex guide
> 
> External Email
> 
> ----------------------------------------------------------------------
> 12/10/2020 13:31, guyk@marvell.com:
> > From: Guy Kaneti <guyk@marvell.com>
> >
> > Added Marvell OCTEON TX2 regex guide, features and updated release
> > notes.
> 
> I think this patch should be merged with doc changes:
> 	- almost all in patch 2 with driver code
> 	- the dpdk-devbind.py chapter in patch 3

Do you mean do merge this patch with patch 2?
 

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [dpdk-dev] [EXT] Re: [PATCH v2 2/4] regex/octeontx2: add build infra and device support
  2020-10-12 17:06       ` [dpdk-dev] [EXT] " Guy Kaneti
@ 2020-10-12 17:10         ` Thomas Monjalon
  2020-10-12 17:13           ` Guy Kaneti
  0 siblings, 1 reply; 33+ messages in thread
From: Thomas Monjalon @ 2020-10-12 17:10 UTC (permalink / raw)
  To: Guy Kaneti
  Cc: orika, Jerin Jacob Kollanukkaran, Nithin Kumar Dabilpuram, mdr,
	nhorman, bruce.richardson, anatoly.burakov, john.mcnamara,
	marko.kovacevic, dev, Smadar Fuks, Dovrat Zifroni, Liron Himi

12/10/2020 19:06, Guy Kaneti:
> From: Thomas Monjalon <thomas@monjalon.net>
> > 12/10/2020 13:31, guyk@marvell.com:
> > > --- a/meson_options.txt
> > > +++ b/meson_options.txt
> > > +option('ree_compiler_sdk', type: 'string', value: '',
> > > +	description: 'path to REE compiler SDK optional library for regex
> > device')
> > 
> > Is this SDK specific to Marvell or octeontx2?
> > If yes, it should appear here.
> 
> Yes, it is specific to Marvell.
> 
> > 
> > Why this SDK requires setting the path manually?
> > Well designed libs should use pkg-config.

You didn't reply this question.
Really I would prefer avoiding this ugly meson option.
Please rework the REE SDK to use pkg-config.



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [dpdk-dev] [EXT] Re: [PATCH v2 4/4] doc: add Marvell OCTEON TX2 regex guide
  2020-10-12 17:09       ` [dpdk-dev] [EXT] " Guy Kaneti
@ 2020-10-12 17:12         ` Thomas Monjalon
  0 siblings, 0 replies; 33+ messages in thread
From: Thomas Monjalon @ 2020-10-12 17:12 UTC (permalink / raw)
  To: Guy Kaneti
  Cc: orika, Jerin Jacob Kollanukkaran, Nithin Kumar Dabilpuram, mdr,
	nhorman, bruce.richardson, anatoly.burakov, john.mcnamara,
	marko.kovacevic, dev, Smadar Fuks, Dovrat Zifroni, Liron Himi

12/10/2020 19:09, Guy Kaneti:
> From: Thomas Monjalon <thomas@monjalon.net>
> > 12/10/2020 13:31, guyk@marvell.com:
> > > From: Guy Kaneti <guyk@marvell.com>
> > >
> > > Added Marvell OCTEON TX2 regex guide, features and updated release
> > > notes.
> > 
> > I think this patch should be merged with doc changes:

I meant with "code changes".

> > 	- almost all in patch 2 with driver code
> > 	- the dpdk-devbind.py chapter in patch 3
> 
> Do you mean do merge this patch with patch 2?

Almost yes.
The doc part about dpdk-devbind.py should be in patch 3.



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [dpdk-dev] [EXT] Re: [PATCH v2 2/4] regex/octeontx2: add build infra and device support
  2020-10-12 17:10         ` Thomas Monjalon
@ 2020-10-12 17:13           ` Guy Kaneti
  2020-10-12 17:19             ` Thomas Monjalon
  0 siblings, 1 reply; 33+ messages in thread
From: Guy Kaneti @ 2020-10-12 17:13 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: orika, Jerin Jacob Kollanukkaran, Nithin Kumar Dabilpuram, mdr,
	nhorman, bruce.richardson, anatoly.burakov, john.mcnamara,
	marko.kovacevic, dev, Smadar Fuks, Dovrat Zifroni, Liron Himi



> -----Original Message-----
> From: Thomas Monjalon <thomas@monjalon.net>
> Sent: Monday, October 12, 2020 8:11 PM
> To: Guy Kaneti <guyk@marvell.com>
> Cc: orika@mellanox.com; Jerin Jacob Kollanukkaran <jerinj@marvell.com>;
> Nithin Kumar Dabilpuram <ndabilpuram@marvell.com>; mdr@ashroe.eu;
> nhorman@tuxdriver.com; bruce.richardson@intel.com;
> anatoly.burakov@intel.com; john.mcnamara@intel.com;
> marko.kovacevic@intel.com; dev@dpdk.org; Smadar Fuks
> <smadarf@marvell.com>; Dovrat Zifroni <dovrat@marvell.com>; Liron Himi
> <lironh@marvell.com>
> Subject: Re: [EXT] Re: [dpdk-dev] [PATCH v2 2/4] regex/octeontx2: add build
> infra and device support
> 
> 12/10/2020 19:06, Guy Kaneti:
> > From: Thomas Monjalon <thomas@monjalon.net>
> > > 12/10/2020 13:31, guyk@marvell.com:
> > > > --- a/meson_options.txt
> > > > +++ b/meson_options.txt
> > > > +option('ree_compiler_sdk', type: 'string', value: '',
> > > > +	description: 'path to REE compiler SDK optional library for regex
> > > device')
> > >
> > > Is this SDK specific to Marvell or octeontx2?
> > > If yes, it should appear here.
> >
> > Yes, it is specific to Marvell.
> >
> > >
> > > Why this SDK requires setting the path manually?
> > > Well designed libs should use pkg-config.
> 
> You didn't reply this question.
> Really I would prefer avoiding this ugly meson option.
> Please rework the REE SDK to use pkg-config.
> 
It is required to be set manually mainly when cross compiling 
The target library will not be part of the host system.


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [dpdk-dev] [EXT] Re: [PATCH v2 2/4] regex/octeontx2: add build infra and device support
  2020-10-12 17:13           ` Guy Kaneti
@ 2020-10-12 17:19             ` Thomas Monjalon
  0 siblings, 0 replies; 33+ messages in thread
From: Thomas Monjalon @ 2020-10-12 17:19 UTC (permalink / raw)
  To: Guy Kaneti
  Cc: orika, Jerin Jacob Kollanukkaran, Nithin Kumar Dabilpuram, mdr,
	nhorman, bruce.richardson, anatoly.burakov, john.mcnamara,
	marko.kovacevic, dev, Smadar Fuks, Dovrat Zifroni, Liron Himi

12/10/2020 19:13, Guy Kaneti:
> From: Thomas Monjalon <thomas@monjalon.net>
> > 12/10/2020 19:06, Guy Kaneti:
> > > From: Thomas Monjalon <thomas@monjalon.net>
> > > > 12/10/2020 13:31, guyk@marvell.com:
> > > > > --- a/meson_options.txt
> > > > > +++ b/meson_options.txt
> > > > > +option('ree_compiler_sdk', type: 'string', value: '',
> > > > > +	description: 'path to REE compiler SDK optional library for regex
> > > > device')
> > > >
> > > > Is this SDK specific to Marvell or octeontx2?
> > > > If yes, it should appear here.
> > >
> > > Yes, it is specific to Marvell.
> > >
> > > >
> > > > Why this SDK requires setting the path manually?
> > > > Well designed libs should use pkg-config.
> > 
> > You didn't reply this question.
> > Really I would prefer avoiding this ugly meson option.
> > Please rework the REE SDK to use pkg-config.
> > 
> It is required to be set manually mainly when cross compiling 
> The target library will not be part of the host system.

It does not make sense. The cross-compiled lib is compiled on the host
and pkg-config works also for cross-compiling.
How do you think other libraries are linked?
I don't see why REE should be an exception.
It's the same issue with another Marvell SDK: lib_musdk_dir.
The other exceptions (which should be removed) are
armv8_crypto_dir and flexran_sdk.



^ permalink raw reply	[flat|nested] 33+ messages in thread

* [dpdk-dev] [PATCH v3 0/3] Add Marvell OCTEON TX2 regex driver
  2020-09-01 12:24 [dpdk-dev] [PATCH 0/4] Add Marvell OCTEON TX2 regex driver guyk
                   ` (5 preceding siblings ...)
  2020-10-12 11:31 ` [dpdk-dev] [PATCH v2 " guyk
@ 2020-10-13 10:10 ` guyk
  2020-10-13 10:10   ` [dpdk-dev] [PATCH v3 1/3] common/octeontx2: add REE definitions and logging support guyk
                     ` (3 more replies)
  6 siblings, 4 replies; 33+ messages in thread
From: guyk @ 2020-10-13 10:10 UTC (permalink / raw)
  To: orika, jerinj, ndabilpuram, thomas, mdr, nhorman,
	bruce.richardson, anatoly.burakov, john.mcnamara,
	marko.kovacevic
  Cc: dev, smadarf, dovrat, guyk, lironh

From: Guy Kaneti <guyk@marvell.com>

This patchset adds support for OCTEON TX2 regex driver as DPDK regexdev.
The driver implements the API defined in the regexdev lib.

v3:
* Fix ML comments.
 
v2:
* Rebase.
* Remove config/common_base from patch
* change rte_cio_wmb to rte_io_wmb

Guy Kaneti (3):
  common/octeontx2: add REE definitions and logging support
  regex/octeontx2: add build infra and device support
  usertools: add octeontx2 REE device binding

 MAINTAINERS                                   |    4 +
 doc/guides/platform/octeontx2.rst             |    5 +
 doc/guides/regexdevs/features/octeontx2.ini   |   10 +
 doc/guides/regexdevs/index.rst                |    1 +
 doc/guides/regexdevs/octeontx2.rst            |   49 +
 doc/guides/rel_notes/release_20_11.rst        |    5 +
 drivers/common/octeontx2/hw/otx2_ree.h        |   27 +
 drivers/common/octeontx2/hw/otx2_rvu.h        |    5 +
 drivers/common/octeontx2/otx2_common.c        |    1 +
 drivers/common/octeontx2/otx2_common.h        |    5 +
 drivers/common/octeontx2/otx2_mbox.h          |  103 ++
 .../rte_common_octeontx2_version.map          |    1 +
 drivers/regex/meson.build                     |    2 +-
 drivers/regex/octeontx2/meson.build           |   44 +
 drivers/regex/octeontx2/otx2_regexdev.c       | 1002 +++++++++++++++++
 drivers/regex/octeontx2/otx2_regexdev.h       |  109 ++
 .../regex/octeontx2/otx2_regexdev_compiler.c  |  229 ++++
 .../regex/octeontx2/otx2_regexdev_compiler.h  |   11 +
 .../regex/octeontx2/otx2_regexdev_hw_access.c |  167 +++
 .../regex/octeontx2/otx2_regexdev_hw_access.h |  202 ++++
 drivers/regex/octeontx2/otx2_regexdev_mbox.c  |  401 +++++++
 drivers/regex/octeontx2/otx2_regexdev_mbox.h  |   38 +
 .../rte_pmd_octeontx2_regex_version.map       |    3 +
 usertools/dpdk-devbind.py                     |    8 +
 24 files changed, 2431 insertions(+), 1 deletion(-)
 create mode 100644 doc/guides/regexdevs/features/octeontx2.ini
 create mode 100644 doc/guides/regexdevs/octeontx2.rst
 create mode 100644 drivers/common/octeontx2/hw/otx2_ree.h
 create mode 100644 drivers/regex/octeontx2/meson.build
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev.h
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_compiler.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_compiler.h
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_hw_access.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_hw_access.h
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_mbox.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_mbox.h
 create mode 100644 drivers/regex/octeontx2/rte_pmd_octeontx2_regex_version.map

-- 
2.28.0


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [dpdk-dev] [PATCH v3 1/3] common/octeontx2: add REE definitions and logging support
  2020-10-13 10:10 ` [dpdk-dev] [PATCH v3 0/3] Add Marvell OCTEON TX2 regex driver guyk
@ 2020-10-13 10:10   ` guyk
  2020-10-14  8:18     ` Thomas Monjalon
  2020-10-13 10:10   ` [dpdk-dev] [PATCH v3 2/3] regex/octeontx2: add build infra and device support guyk
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 33+ messages in thread
From: guyk @ 2020-10-13 10:10 UTC (permalink / raw)
  To: orika, jerinj, ndabilpuram, thomas, mdr, nhorman,
	bruce.richardson, anatoly.burakov, john.mcnamara,
	marko.kovacevic
  Cc: dev, smadarf, dovrat, guyk, lironh

From: Guy Kaneti <guyk@marvell.com>

Add REE mbox msg definitions, RVU and REE HW definitions

Signed-off-by: Guy Kaneti <guyk@marvell.com>
---
 drivers/common/octeontx2/hw/otx2_ree.h        |  27 +++++
 drivers/common/octeontx2/hw/otx2_rvu.h        |   5 +
 drivers/common/octeontx2/otx2_common.c        |   1 +
 drivers/common/octeontx2/otx2_common.h        |   5 +
 drivers/common/octeontx2/otx2_mbox.h          | 103 ++++++++++++++++++
 .../rte_common_octeontx2_version.map          |   1 +
 6 files changed, 142 insertions(+)
 create mode 100644 drivers/common/octeontx2/hw/otx2_ree.h

diff --git a/drivers/common/octeontx2/hw/otx2_ree.h b/drivers/common/octeontx2/hw/otx2_ree.h
new file mode 100644
index 000000000..b7481f125
--- /dev/null
+++ b/drivers/common/octeontx2/hw/otx2_ree.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#ifndef __OTX2_REE_HW_H__
+#define __OTX2_REE_HW_H__
+
+/* REE BAR0*/
+#define REE_AF_REEXM_MAX_MATCH		(0x80c8)
+
+/* REE BAR02 */
+#define REE_LF_MISC_INT                 (0x300)
+#define REE_LF_DONE_INT                 (0x120)
+
+#define REE_AF_QUEX_GMCTL(a)            (0x800 | (a) << 3)
+
+#define REE_AF_INT_VEC_RAS          (0x0ull)
+#define REE_AF_INT_VEC_RVU          (0x1ull)
+#define REE_AF_INT_VEC_QUE_DONE     (0x2ull)
+#define REE_AF_INT_VEC_AQ           (0x3ull)
+
+/* ENUMS */
+
+#define REE_LF_INT_VEC_QUE_DONE	(0x0ull)
+#define REE_LF_INT_VEC_MISC		(0x1ull)
+
+#endif /* __OTX2_REE_HW_H__*/
diff --git a/drivers/common/octeontx2/hw/otx2_rvu.h b/drivers/common/octeontx2/hw/otx2_rvu.h
index 330bfb37f..072515207 100644
--- a/drivers/common/octeontx2/hw/otx2_rvu.h
+++ b/drivers/common/octeontx2/hw/otx2_rvu.h
@@ -130,6 +130,7 @@
 #define RVU_BLOCK_TYPE_RAD                  (0xdull)
 #define RVU_BLOCK_TYPE_DFA                  (0xeull)
 #define RVU_BLOCK_TYPE_HNA                  (0xfull)
+#define RVU_BLOCK_TYPE_REE                  (0xeull)
 
 #define RVU_BLOCK_ADDR_RVUM                 (0x0ull)
 #define RVU_BLOCK_ADDR_LMT                  (0x1ull)
@@ -146,6 +147,8 @@
 #define RVU_BLOCK_ADDR_NDC2                 (0xeull)
 #define RVU_BLOCK_ADDR_R_END                (0x1full)
 #define RVU_BLOCK_ADDR_R_START              (0x14ull)
+#define RVU_BLOCK_ADDR_REE0                 (0x14ull)
+#define RVU_BLOCK_ADDR_REE1                 (0x15ull)
 
 #define RVU_VF_INT_VEC_MBOX                 (0x0ull)
 
@@ -167,6 +170,7 @@
 #define NPA_AF_BAR2_SEL			(0x9000000ull)
 #define CPT_AF_BAR2_SEL			(0x9000000ull)
 #define RVU_AF_BAR2_SEL			(0x9000000ull)
+#define REE_AF_BAR2_SEL			(0x9000000ull)
 
 #define AF_BAR2_ALIASX(a, b) \
 	(0x9100000ull | (uint64_t)(a) << 12 | (uint64_t)(b))
@@ -177,6 +181,7 @@
 #define NPA_AF_BAR2_ALIASX(a, b)		AF_BAR2_ALIASX(0, b)
 #define CPT_AF_BAR2_ALIASX(a, b)		AF_BAR2_ALIASX(a, b)
 #define RVU_AF_BAR2_ALIASX(a, b)		AF_BAR2_ALIASX(a, b)
+#define REE_AF_BAR2_ALIASX(a, b)		AF_BAR2_ALIASX(a, b)
 
 /* Structures definitions */
 
diff --git a/drivers/common/octeontx2/otx2_common.c b/drivers/common/octeontx2/otx2_common.c
index b292e999a..d23c50242 100644
--- a/drivers/common/octeontx2/otx2_common.c
+++ b/drivers/common/octeontx2/otx2_common.c
@@ -213,3 +213,4 @@ RTE_LOG_REGISTER(otx2_logtype_sso, pmd.event.octeontx2, NOTICE);
 RTE_LOG_REGISTER(otx2_logtype_tim, pmd.event.octeontx2.timer, NOTICE);
 RTE_LOG_REGISTER(otx2_logtype_dpi, pmd.raw.octeontx2.dpi, NOTICE);
 RTE_LOG_REGISTER(otx2_logtype_ep, pmd.raw.octeontx2.ep, NOTICE);
+RTE_LOG_REGISTER(otx2_logtype_ree, pmd.regex.octeontx2, NOTICE);
diff --git a/drivers/common/octeontx2/otx2_common.h b/drivers/common/octeontx2/otx2_common.h
index 2168cde4d..b6779f710 100644
--- a/drivers/common/octeontx2/otx2_common.h
+++ b/drivers/common/octeontx2/otx2_common.h
@@ -21,6 +21,7 @@
 #include "hw/otx2_sso.h"
 #include "hw/otx2_ssow.h"
 #include "hw/otx2_tim.h"
+#include "hw/otx2_ree.h"
 
 /* Alignment */
 #define OTX2_ALIGN  128
@@ -96,6 +97,7 @@ extern int otx2_logtype_tm;
 extern int otx2_logtype_tim;
 extern int otx2_logtype_dpi;
 extern int otx2_logtype_ep;
+extern int otx2_logtype_ree;
 
 #define otx2_err(fmt, args...)			\
 	RTE_LOG(ERR, PMD, "%s():%u " fmt "\n",	\
@@ -119,6 +121,7 @@ extern int otx2_logtype_ep;
 #define otx2_tim_dbg(fmt, ...) otx2_dbg(tim, fmt, ##__VA_ARGS__)
 #define otx2_dpi_dbg(fmt, ...) otx2_dbg(dpi, fmt, ##__VA_ARGS__)
 #define otx2_sdp_dbg(fmt, ...) otx2_dbg(ep, fmt, ##__VA_ARGS__)
+#define otx2_ree_dbg(fmt, ...) otx2_dbg(ree, fmt, ##__VA_ARGS__)
 
 /* PCI IDs */
 #define PCI_VENDOR_ID_CAVIUM			0x177D
@@ -136,6 +139,8 @@ extern int otx2_logtype_ep;
 #define PCI_DEVID_OCTEONTX2_EP_VF		0xB203 /* OCTEON TX2 EP mode */
 #define PCI_DEVID_OCTEONTX2_RVU_SDP_PF		0xA0f6
 #define PCI_DEVID_OCTEONTX2_RVU_SDP_VF		0xA0f7
+#define PCI_DEVID_OCTEONTX2_RVU_REE_PF		0xA0f4
+#define PCI_DEVID_OCTEONTX2_RVU_REE_VF		0xA0f5
 
 /*
  * REVID for RVU PCIe devices.
diff --git a/drivers/common/octeontx2/otx2_mbox.h b/drivers/common/octeontx2/otx2_mbox.h
index 78de432e7..aebb217ec 100644
--- a/drivers/common/octeontx2/otx2_mbox.h
+++ b/drivers/common/octeontx2/otx2_mbox.h
@@ -199,6 +199,19 @@ M(CPT_INLINE_IPSEC_CFG, 0xA04, cpt_inline_ipsec_cfg,			\
 M(CPT_RX_INLINE_LF_CFG, 0xBFE, cpt_rx_inline_lf_cfg,			\
 			       cpt_rx_inline_lf_cfg_msg, msg_rsp)	\
 M(CPT_GET_CAPS,		0xBFD, cpt_caps_get, msg_req, cpt_caps_rsp_msg)	\
+/* REE mbox IDs (range 0xE00 - 0xFFF) */				\
+M(REE_CONFIG_LF,	0xE01, ree_config_lf, ree_lf_req_msg,		\
+				msg_rsp)				\
+M(REE_RD_WR_REGISTER,	0xE02, ree_rd_wr_register, ree_rd_wr_reg_msg,	\
+				ree_rd_wr_reg_msg)			\
+M(REE_RULE_DB_PROG,	0xE03, ree_rule_db_prog,			\
+				ree_rule_db_prog_req_msg,		\
+				msg_rsp)				\
+M(REE_RULE_DB_LEN_GET,	0xE04, ree_rule_db_len_get, ree_req_msg,	\
+				ree_rule_db_len_rsp_msg)		\
+M(REE_RULE_DB_GET,	0xE05, ree_rule_db_get,				\
+				ree_rule_db_get_req_msg,		\
+				ree_rule_db_get_rsp_msg)		\
 /* NPC mbox IDs (range 0x6000 - 0x7FFF) */				\
 M(NPC_MCAM_ALLOC_ENTRY,	0x6000, npc_mcam_alloc_entry,			\
 				npc_mcam_alloc_entry_req,		\
@@ -1660,6 +1673,96 @@ struct tim_enable_rsp {
 	uint32_t __otx2_io currentbucket;
 };
 
+/* REE mailbox error codes
+ * Range 1001 - 1100.
+ */
+enum ree_af_status {
+	REE_AF_ERR_RULE_UNKNOWN_VALUE		= -1001,
+	REE_AF_ERR_LF_NO_MORE_RESOURCES		= -1002,
+	REE_AF_ERR_LF_INVALID			= -1003,
+	REE_AF_ERR_ACCESS_DENIED		= -1004,
+	REE_AF_ERR_RULE_DB_PARTIAL		= -1005,
+	REE_AF_ERR_RULE_DB_EQ_BAD_VALUE		= -1006,
+	REE_AF_ERR_RULE_DB_BLOCK_ALLOC_FAILED	= -1007,
+	REE_AF_ERR_BLOCK_NOT_IMPLEMENTED	= -1008,
+	REE_AF_ERR_RULE_DB_INC_OFFSET_TOO_BIG	= -1009,
+	REE_AF_ERR_RULE_DB_OFFSET_TOO_BIG	= -1010,
+	REE_AF_ERR_Q_IS_GRACEFUL_DIS		= -1011,
+	REE_AF_ERR_Q_NOT_GRACEFUL_DIS		= -1012,
+	REE_AF_ERR_RULE_DB_ALLOC_FAILED		= -1013,
+	REE_AF_ERR_RULE_DB_TOO_BIG		= -1014,
+	REE_AF_ERR_RULE_DB_GEQ_BAD_VALUE	= -1015,
+	REE_AF_ERR_RULE_DB_LEQ_BAD_VALUE	= -1016,
+	REE_AF_ERR_RULE_DB_WRONG_LENGTH		= -1017,
+	REE_AF_ERR_RULE_DB_WRONG_OFFSET		= -1018,
+	REE_AF_ERR_RULE_DB_BLOCK_TOO_BIG	= -1019,
+	REE_AF_ERR_RULE_DB_SHOULD_FILL_REQUEST	= -1020,
+	REE_AF_ERR_RULE_DBI_ALLOC_FAILED	= -1021,
+	REE_AF_ERR_LF_WRONG_PRIORITY		= -1022,
+	REE_AF_ERR_LF_SIZE_TOO_BIG		= -1023,
+};
+
+/* REE mbox message formats */
+
+struct ree_req_msg {
+	struct mbox_msghdr hdr;
+	uint32_t __otx2_io blkaddr;
+};
+
+struct ree_lf_req_msg {
+	struct mbox_msghdr hdr;
+	uint32_t __otx2_io blkaddr;
+	uint32_t __otx2_io size;
+	uint8_t __otx2_io lf;
+	uint8_t __otx2_io pri;
+};
+
+struct ree_rule_db_prog_req_msg {
+	struct mbox_msghdr hdr;
+#define REE_RULE_DB_REQ_BLOCK_SIZE (MBOX_SIZE >> 1)
+	uint8_t __otx2_io rule_db[REE_RULE_DB_REQ_BLOCK_SIZE];
+	uint32_t __otx2_io blkaddr; /* REE0 or REE1 */
+	uint32_t __otx2_io total_len; /* total len of rule db */
+	uint32_t __otx2_io offset; /* offset of current rule db block */
+	uint16_t __otx2_io len; /* length of rule db block */
+	uint8_t __otx2_io is_last; /* is this the last block */
+	uint8_t __otx2_io is_incremental; /* is incremental flow */
+	uint8_t __otx2_io is_dbi; /* is rule db incremental */
+};
+
+struct ree_rule_db_get_req_msg {
+	struct mbox_msghdr hdr;
+	uint32_t __otx2_io blkaddr;
+	uint32_t __otx2_io offset; /* retrieve db from this offset */
+	uint8_t __otx2_io is_dbi; /* is request for rule db incremental */
+};
+
+struct ree_rd_wr_reg_msg {
+	struct mbox_msghdr hdr;
+	uint64_t __otx2_io reg_offset;
+	uint64_t __otx2_io *ret_val;
+	uint64_t __otx2_io val;
+	uint32_t __otx2_io blkaddr;
+	uint8_t __otx2_io is_write;
+};
+
+struct ree_rule_db_len_rsp_msg {
+	struct mbox_msghdr hdr;
+	uint32_t __otx2_io blkaddr;
+	uint32_t __otx2_io len;
+	uint32_t __otx2_io inc_len;
+};
+
+struct ree_rule_db_get_rsp_msg {
+	struct mbox_msghdr hdr;
+#define REE_RULE_DB_RSP_BLOCK_SIZE (MBOX_DOWN_TX_SIZE - SZ_1K)
+	uint8_t __otx2_io rule_db[REE_RULE_DB_RSP_BLOCK_SIZE];
+	uint32_t __otx2_io total_len; /* total len of rule db */
+	uint32_t __otx2_io offset; /* offset of current rule db block */
+	uint16_t __otx2_io len; /* length of rule db block */
+	uint8_t __otx2_io is_last; /* is this the last block */
+};
+
 __rte_internal
 const char *otx2_mbox_id2name(uint16_t id);
 int otx2_mbox_id2size(uint16_t id);
diff --git a/drivers/common/octeontx2/rte_common_octeontx2_version.map b/drivers/common/octeontx2/rte_common_octeontx2_version.map
index 9a9969613..d269d70d8 100644
--- a/drivers/common/octeontx2/rte_common_octeontx2_version.map
+++ b/drivers/common/octeontx2/rte_common_octeontx2_version.map
@@ -38,6 +38,7 @@ INTERNAL {
 	otx2_sso_pf_func_get;
 	otx2_sso_pf_func_set;
 	otx2_unregister_irq;
+	otx2_logtype_ree;
 
 	local: *;
 };
-- 
2.28.0


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [dpdk-dev] [PATCH v3 2/3] regex/octeontx2: add build infra and device support
  2020-10-13 10:10 ` [dpdk-dev] [PATCH v3 0/3] Add Marvell OCTEON TX2 regex driver guyk
  2020-10-13 10:10   ` [dpdk-dev] [PATCH v3 1/3] common/octeontx2: add REE definitions and logging support guyk
@ 2020-10-13 10:10   ` guyk
  2020-10-14  8:26     ` Thomas Monjalon
  2020-10-13 10:10   ` [dpdk-dev] [PATCH v3 3/3] usertools: add octeontx2 REE device binding guyk
  2020-10-14  8:42   ` [dpdk-dev] [PATCH v3 0/3] Add Marvell OCTEON TX2 regex driver Thomas Monjalon
  3 siblings, 1 reply; 33+ messages in thread
From: guyk @ 2020-10-13 10:10 UTC (permalink / raw)
  To: orika, jerinj, ndabilpuram, thomas, mdr, nhorman,
	bruce.richardson, anatoly.burakov, john.mcnamara,
	marko.kovacevic
  Cc: dev, smadarf, dovrat, guyk, lironh

From: Guy Kaneti <guyk@marvell.com>

Add meson based build infrastructure along with the
OTX2 regexdev (REE) device functions.
Add Marvell OCTEON TX2 regex guide.

Signed-off-by: Guy Kaneti <guyk@marvell.com>
---
 MAINTAINERS                                   |    4 +
 doc/guides/platform/octeontx2.rst             |    5 +
 doc/guides/regexdevs/features/octeontx2.ini   |   10 +
 doc/guides/regexdevs/index.rst                |    1 +
 doc/guides/regexdevs/octeontx2.rst            |   38 +
 doc/guides/rel_notes/release_20_11.rst        |    5 +
 drivers/regex/meson.build                     |    2 +-
 drivers/regex/octeontx2/meson.build           |   44 +
 drivers/regex/octeontx2/otx2_regexdev.c       | 1002 +++++++++++++++++
 drivers/regex/octeontx2/otx2_regexdev.h       |  109 ++
 .../regex/octeontx2/otx2_regexdev_compiler.c  |  229 ++++
 .../regex/octeontx2/otx2_regexdev_compiler.h  |   11 +
 .../regex/octeontx2/otx2_regexdev_hw_access.c |  167 +++
 .../regex/octeontx2/otx2_regexdev_hw_access.h |  202 ++++
 drivers/regex/octeontx2/otx2_regexdev_mbox.c  |  401 +++++++
 drivers/regex/octeontx2/otx2_regexdev_mbox.h  |   38 +
 .../rte_pmd_octeontx2_regex_version.map       |    3 +
 17 files changed, 2270 insertions(+), 1 deletion(-)
 create mode 100644 doc/guides/regexdevs/features/octeontx2.ini
 create mode 100644 doc/guides/regexdevs/octeontx2.rst
 create mode 100644 drivers/regex/octeontx2/meson.build
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev.h
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_compiler.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_compiler.h
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_hw_access.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_hw_access.h
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_mbox.c
 create mode 100644 drivers/regex/octeontx2/otx2_regexdev_mbox.h
 create mode 100644 drivers/regex/octeontx2/rte_pmd_octeontx2_regex_version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index 2a18262d6..44c7cc82a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1112,6 +1112,10 @@ F: doc/guides/compressdevs/features/zlib.ini
 RegEx Drivers
 -------------
 
+Marvell OCTEON TX2 regex
+M: Guy Kaneti <guyk@marvell.com>
+F: drivers/regex/octeontx2/
+
 Mellanox mlx5
 M: Ori Kam <orika@nvidia.com>
 F: drivers/regex/mlx5/
diff --git a/doc/guides/platform/octeontx2.rst b/doc/guides/platform/octeontx2.rst
index 13255eec5..c4d64ab4b 100644
--- a/doc/guides/platform/octeontx2.rst
+++ b/doc/guides/platform/octeontx2.rst
@@ -67,6 +67,8 @@ DPDK subsystem.
    +---+-----+--------------------------------------------------------------+
    | 9 | SDP | rte_ethdev                                                   |
    +---+-----+--------------------------------------------------------------+
+   | 10| REE | rte_regexdev                                                 |
+   +---+-----+--------------------------------------------------------------+
 
 PF0 is called the administrative / admin function (AF) and has exclusive
 privileges to provision RVU functional block's LFs to each of the PF/VF.
@@ -156,6 +158,9 @@ This section lists dataplane H/W block(s) available in OCTEON TX2 SoC.
 #. **Crypto Device Driver**
    See :doc:`../cryptodevs/octeontx2` for CPT crypto device driver information.
 
+#. **Regex Device Driver**
+   See :doc:`../regexdevs/octeontx2` for REE regex device driver information.
+
 Procedure to Setup Platform
 ---------------------------
 
diff --git a/doc/guides/regexdevs/features/octeontx2.ini b/doc/guides/regexdevs/features/octeontx2.ini
new file mode 100644
index 000000000..c9b421a16
--- /dev/null
+++ b/doc/guides/regexdevs/features/octeontx2.ini
@@ -0,0 +1,10 @@
+;
+; Supported features of the 'octeontx2' regex driver.
+;
+; Refer to default.ini for the full list of available driver features.
+;
+[Features]
+PCRE back reference         = Y
+PCRE word boundary          = Y
+Run time compilation        = Y
+Armv8                       = Y
diff --git a/doc/guides/regexdevs/index.rst b/doc/guides/regexdevs/index.rst
index 49216a932..b1abc826b 100644
--- a/doc/guides/regexdevs/index.rst
+++ b/doc/guides/regexdevs/index.rst
@@ -13,3 +13,4 @@ which can be used from an application through RegEx API.
 
    features_overview
    mlx5
+   octeontx2
diff --git a/doc/guides/regexdevs/octeontx2.rst b/doc/guides/regexdevs/octeontx2.rst
new file mode 100644
index 000000000..87659b661
--- /dev/null
+++ b/doc/guides/regexdevs/octeontx2.rst
@@ -0,0 +1,38 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright(c) 2020 Marvell International Ltd.
+
+OCTEON TX2 REE Regexdev Driver
+===============================
+
+The OCTEON TX2 REE PMD (**librte_pmd_octeontx2_regex**) provides poll mode
+regexdev driver support for the inbuilt regex device found in the **Marvell OCTEON TX2**
+SoC family.
+
+More information about OCTEON TX2 SoC can be found at `Marvell Official Website
+<https://www.marvell.com/embedded-processors/infrastructure-processors/>`_.
+
+Features
+--------
+
+Features of the OCTEON TX2 REE PMD are:
+
+- 36 queues
+- Up to 254 matches for each regex operation
+
+Prerequisites and Compilation procedure
+---------------------------------------
+
+   See :doc:`../platform/octeontx2` for setup information.
+
+Debugging Options
+-----------------
+
+.. _table_octeontx2_regex_debug_options:
+
+.. table:: OCTEON TX2 regex device debug options
+
+   +---+------------+-------------------------------------------------------+
+   | # | Component  | EAL log command                                       |
+   +===+============+=======================================================+
+   | 1 | REE        | --log-level='pmd\.regex\.octeontx2,8'                 |
+   +---+------------+-------------------------------------------------------+
diff --git a/doc/guides/rel_notes/release_20_11.rst b/doc/guides/rel_notes/release_20_11.rst
index 57e3edcdd..90b32936f 100644
--- a/doc/guides/rel_notes/release_20_11.rst
+++ b/doc/guides/rel_notes/release_20_11.rst
@@ -148,6 +148,11 @@ New Features
   * Extern objects and functions can be plugged into the pipeline.
   * Transaction-oriented table updates.
 
+* **Added Marvell OCTEON TX2 regex PMD.**
+
+  Added a new PMD driver for hardware regex offload block for OCTEON TX2 SoC.
+
+  See the :doc:`../regexdevs/octeontx2` for more details.
 
 Removed Items
 -------------
diff --git a/drivers/regex/meson.build b/drivers/regex/meson.build
index 8edeba3a0..79bb5d5df 100644
--- a/drivers/regex/meson.build
+++ b/drivers/regex/meson.build
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright 2020 Mellanox Technologies, Ltd
 
-drivers = ['mlx5']
+drivers = ['mlx5', 'octeontx2']
 std_deps = ['ethdev', 'kvargs'] # 'ethdev' also pulls in mbuf, net, eal etc
 config_flag_fmt = 'RTE_LIBRTE_@0@_PMD'
 driver_name_fmt = 'rte_pmd_@0@'
diff --git a/drivers/regex/octeontx2/meson.build b/drivers/regex/octeontx2/meson.build
new file mode 100644
index 000000000..398a981c0
--- /dev/null
+++ b/drivers/regex/octeontx2/meson.build
@@ -0,0 +1,44 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(C) 2020 Marvell International Ltd.
+#
+
+if not is_linux
+	build = false
+	reason = 'only supported on Linux'
+endif
+
+lib = cc.find_library('librxp_compiler', required: false)
+if lib.found()
+	ext_deps += lib
+	ext_deps += cc.find_library('libstdc++', required: true)
+	includes += include_directories(inc_dir)
+	cflags += ['-DREE_COMPILER_SDK']
+endif
+
+sources = files('otx2_regexdev.c',
+		'otx2_regexdev_hw_access.c',
+		'otx2_regexdev_mbox.c',
+		'otx2_regexdev_compiler.c'
+		)
+
+extra_flags = []
+# This integrated controller runs only on a arm64 machine, remove 32bit warnings
+if not dpdk_conf.get('RTE_ARCH_64')
+	extra_flags += ['-Wno-int-to-pointer-cast', '-Wno-pointer-to-int-cast']
+endif
+
+# for clang 32-bit compiles we need libatomic for 64-bit atomic ops
+if cc.get_id() == 'clang' and dpdk_conf.get('RTE_ARCH_64') == false
+	ext_deps += cc.find_library('atomic')
+endif
+
+foreach flag: extra_flags
+	if cc.has_argument(flag)
+		cflags += flag
+	endif
+endforeach
+
+name = 'octeontx2_regex'
+deps += ['bus_pci', 'common_octeontx2', 'regexdev']
+
+includes += include_directories('../../common/octeontx2')
diff --git a/drivers/regex/octeontx2/otx2_regexdev.c b/drivers/regex/octeontx2/otx2_regexdev.c
new file mode 100644
index 000000000..39eed7a20
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev.c
@@ -0,0 +1,1002 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include <rte_malloc.h>
+#include <rte_memzone.h>
+#include <rte_regexdev.h>
+#include <rte_regexdev_core.h>
+#include <rte_regexdev_driver.h>
+
+
+/* REE common headers */
+#include "otx2_common.h"
+#include "otx2_dev.h"
+#include "otx2_regexdev.h"
+#include "otx2_regexdev_compiler.h"
+#include "otx2_regexdev_hw_access.h"
+#include "otx2_regexdev_mbox.h"
+
+
+/* HW matches are at offset 0x80 from RES_PTR_ADDR
+ * In op structure matches starts at W5 (0x28)
+ * There is a need to copy to 0x28 to 0x80 The matches that are at the tail
+ * Which are 88 B. Each match holds 8 B, so up to 11 matches can be copied
+ */
+#define REE_NUM_MATCHES_ALIGN	11
+/* The REE co-processor will write up to 254 job match structures
+ * (REE_MATCH_S) starting at address [RES_PTR_ADDR] + 0x80.
+ */
+#define REE_MATCH_OFFSET	0x80
+
+#define REE_MAX_RULES_PER_GROUP 0xFFFF
+#define REE_MAX_GROUPS 0xFFFF
+
+/* This is temporarily here */
+#define REE0_PF	19
+#define REE1_PF	20
+
+#define REE_RULE_DB_VERSION	2
+#define REE_RULE_DB_REVISION	0
+
+struct ree_rule_db_entry {
+	uint8_t		type;
+	uint32_t	addr;
+	uint64_t	value;
+};
+
+struct ree_rule_db {
+	uint32_t version;
+	uint32_t revision;
+	uint32_t number_of_entries;
+	struct ree_rule_db_entry entries[];
+} __rte_packed;
+
+static void
+qp_memzone_name_get(char *name, int size, int dev_id, int qp_id)
+{
+	snprintf(name, size, "otx2_ree_lf_mem_%u:%u", dev_id, qp_id);
+}
+
+static struct otx2_ree_qp *
+ree_qp_create(const struct rte_regexdev *dev, uint16_t qp_id)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	uint64_t pg_sz = sysconf(_SC_PAGESIZE);
+	struct otx2_ree_vf *vf = &data->vf;
+	const struct rte_memzone *lf_mem;
+	uint32_t len, iq_len, size_div2;
+	char name[RTE_MEMZONE_NAMESIZE];
+	uint64_t used_len, iova;
+	struct otx2_ree_qp *qp;
+	uint8_t *va;
+	int ret;
+
+	/* Allocate queue pair */
+	qp = rte_zmalloc("OCTEON TX2 Regex PMD Queue Pair", sizeof(*qp),
+				OTX2_ALIGN);
+	if (qp == NULL) {
+		otx2_err("Could not allocate queue pair");
+		return NULL;
+	}
+
+	iq_len = OTX2_REE_IQ_LEN;
+
+	/*
+	 * Queue size must be in units of 128B 2 * REE_INST_S (which is 64B),
+	 * and a power of 2.
+	 * effective queue size to software is (size - 1) * 128
+	 */
+	size_div2 = iq_len >> 1;
+
+	/* For pending queue */
+	len = iq_len * RTE_ALIGN(sizeof(struct otx2_ree_rid), 8);
+
+	/* So that instruction queues start as pg size aligned */
+	len = RTE_ALIGN(len, pg_sz);
+
+	/* For instruction queues */
+	len += OTX2_REE_IQ_LEN * sizeof(union otx2_ree_inst);
+
+	/* Waste after instruction queues */
+	len = RTE_ALIGN(len, pg_sz);
+
+	qp_memzone_name_get(name, RTE_MEMZONE_NAMESIZE, dev->data->dev_id,
+			    qp_id);
+
+	lf_mem = rte_memzone_reserve_aligned(name, len, vf->otx2_dev.node,
+			RTE_MEMZONE_SIZE_HINT_ONLY | RTE_MEMZONE_256MB,
+			RTE_CACHE_LINE_SIZE);
+	if (lf_mem == NULL) {
+		otx2_err("Could not allocate reserved memzone");
+		goto qp_free;
+	}
+
+	va = lf_mem->addr;
+	iova = lf_mem->iova;
+
+	memset(va, 0, len);
+
+	/* Initialize pending queue */
+	qp->pend_q.rid_queue = (struct otx2_ree_rid *)va;
+	qp->pend_q.enq_tail = 0;
+	qp->pend_q.deq_head = 0;
+	qp->pend_q.pending_count = 0;
+
+	used_len = iq_len * RTE_ALIGN(sizeof(struct otx2_ree_rid), 8);
+	used_len = RTE_ALIGN(used_len, pg_sz);
+	iova += used_len;
+
+	qp->iq_dma_addr = iova;
+	qp->id = qp_id;
+	qp->base = OTX2_REE_LF_BAR2(vf, qp_id);
+	qp->otx2_regexdev_jobid = 0;
+	qp->write_offset = 0;
+
+	ret = otx2_ree_iq_enable(dev, qp, OTX2_REE_QUEUE_HI_PRIO, size_div2);
+	if (ret) {
+		otx2_err("Could not enable instruction queue");
+		goto qp_free;
+	}
+
+	return qp;
+
+qp_free:
+	rte_free(qp);
+	return NULL;
+}
+
+static int
+ree_qp_destroy(const struct rte_regexdev *dev, struct otx2_ree_qp *qp)
+{
+	const struct rte_memzone *lf_mem;
+	char name[RTE_MEMZONE_NAMESIZE];
+	int ret;
+
+	otx2_ree_iq_disable(qp);
+
+	qp_memzone_name_get(name, RTE_MEMZONE_NAMESIZE, dev->data->dev_id,
+			    qp->id);
+
+	lf_mem = rte_memzone_lookup(name);
+
+	ret = rte_memzone_free(lf_mem);
+	if (ret)
+		return ret;
+
+	rte_free(qp);
+
+	return 0;
+}
+
+static int
+ree_queue_pair_release(struct rte_regexdev *dev, uint16_t qp_id)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_qp *qp = data->queue_pairs[qp_id];
+	int ret;
+
+	ree_func_trace("Queue=%d", qp_id);
+
+	if (qp == NULL)
+		return -EINVAL;
+
+	ret = ree_qp_destroy(dev, qp);
+	if (ret) {
+		otx2_err("Could not destroy queue pair %d", qp_id);
+		return ret;
+	}
+
+	data->queue_pairs[qp_id] = NULL;
+
+	return 0;
+}
+
+static struct rte_regexdev *
+ree_dev_register(const char *name)
+{
+	struct rte_regexdev *dev;
+
+	otx2_ree_dbg("Creating regexdev %s\n", name);
+
+	/* allocate device structure */
+	dev = rte_regexdev_register(name);
+	if (dev == NULL) {
+		otx2_err("Failed to allocate regex device for %s", name);
+		return NULL;
+	}
+
+	/* allocate private device structure */
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		dev->data->dev_private =
+				rte_zmalloc_socket("regexdev device private",
+						sizeof(struct otx2_ree_data),
+						RTE_CACHE_LINE_SIZE,
+						rte_socket_id());
+
+		if (dev->data->dev_private == NULL) {
+			otx2_err("Cannot allocate memory for dev %s private data",
+					name);
+
+			rte_regexdev_unregister(dev);
+			return NULL;
+		}
+	}
+
+	return dev;
+}
+
+static int
+ree_dev_unregister(struct rte_regexdev *dev)
+{
+	otx2_ree_dbg("Closing regex device %s", dev->device->name);
+
+	/* free regex device */
+	rte_regexdev_unregister(dev);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(dev->data->dev_private);
+
+	return 0;
+}
+
+static int
+ree_dev_fini(struct rte_regexdev *dev)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct rte_pci_device *pci_dev;
+	int i, ret;
+
+	ree_func_trace();
+
+	for (i = 0; i < data->nb_queue_pairs; i++) {
+		ret = ree_queue_pair_release(dev, i);
+		if (ret)
+			return ret;
+	}
+
+	ret = otx2_ree_queues_detach(dev);
+	if (ret)
+		otx2_err("Could not detach queues");
+
+	/* TEMP : should be in lib */
+	if (data->queue_pairs)
+		rte_free(data->queue_pairs);
+	if (data->rules)
+		rte_free(data->rules);
+
+	pci_dev = container_of(dev->device, struct rte_pci_device, device);
+	otx2_dev_fini(pci_dev, &(data->vf.otx2_dev));
+
+	ret = ree_dev_unregister(dev);
+	if (ret)
+		otx2_err("Could not destroy PMD");
+
+	return ret;
+}
+
+static inline int
+ree_enqueue(struct otx2_ree_qp *qp, struct rte_regex_ops *op,
+		 struct otx2_ree_pending_queue *pend_q)
+{
+	union otx2_ree_inst inst;
+	union otx2_ree_res *res;
+	uint32_t offset;
+
+	if (unlikely(pend_q->pending_count >= OTX2_REE_DEFAULT_CMD_QLEN)) {
+		otx2_err("Pending count %" PRIu64 " is greater than Q size %d",
+		pend_q->pending_count, OTX2_REE_DEFAULT_CMD_QLEN);
+		return -EAGAIN;
+	}
+	if (unlikely(op->mbuf->data_len > OTX2_REE_MAX_PAYLOAD_SIZE ||
+			op->mbuf->data_len == 0)) {
+		otx2_err("Packet length %d is greater than MAX payload %d",
+				op->mbuf->data_len, OTX2_REE_MAX_PAYLOAD_SIZE);
+		return -EAGAIN;
+	}
+
+	/* W 0 */
+	inst.cn98xx.ooj = 1;
+	inst.cn98xx.dg = 0;
+	inst.cn98xx.doneint = 0;
+	/* W 1 */
+	inst.cn98xx.inp_ptr_addr = rte_pktmbuf_mtod(op->mbuf, uint64_t);
+	/* W 2 */
+	inst.cn98xx.inp_ptr_ctl = op->mbuf->data_len & 0x7FFF;
+	inst.cn98xx.inp_ptr_ctl = inst.cn98xx.inp_ptr_ctl << 32;
+
+	/* W 3 */
+	inst.cn98xx.res_ptr_addr = (uint64_t)op;
+	/* W 4 */
+	inst.cn98xx.wq_ptr = 0;
+	/* W 5 */
+	inst.cn98xx.ggrp = 0;
+	inst.cn98xx.tt = 0;
+	inst.cn98xx.tag = 0;
+	/* W 6 */
+	inst.cn98xx.ree_job_length = op->mbuf->data_len & 0x7FFF;
+	if (op->req_flags & RTE_REGEX_OPS_REQ_STOP_ON_MATCH_F)
+		inst.cn98xx.ree_job_ctrl = (0x2 << 8);
+	else if (op->req_flags & RTE_REGEX_OPS_REQ_MATCH_HIGH_PRIORITY_F)
+		inst.cn98xx.ree_job_ctrl = (0x1 << 8);
+	else
+		inst.cn98xx.ree_job_ctrl = 0;
+	inst.cn98xx.ree_job_id = qp->otx2_regexdev_jobid;
+	/* W 7 */
+	inst.cn98xx.ree_job_subset_id_0 = op->group_id0;
+	if (op->req_flags & RTE_REGEX_OPS_REQ_GROUP_ID1_VALID_F)
+		inst.cn98xx.ree_job_subset_id_1 = op->group_id1;
+	else
+		inst.cn98xx.ree_job_subset_id_1 = op->group_id0;
+	if (op->req_flags & RTE_REGEX_OPS_REQ_GROUP_ID2_VALID_F)
+		inst.cn98xx.ree_job_subset_id_2 = op->group_id2;
+	else
+		inst.cn98xx.ree_job_subset_id_2 = op->group_id0;
+	if (op->req_flags & RTE_REGEX_OPS_REQ_GROUP_ID3_VALID_F)
+		inst.cn98xx.ree_job_subset_id_3 = op->group_id3;
+	else
+		inst.cn98xx.ree_job_subset_id_3 = op->group_id0;
+
+	/* Copy REE command to Q */
+	offset = qp->write_offset * sizeof(inst);
+	memcpy((void *)(qp->iq_dma_addr + offset), &inst, sizeof(inst));
+
+	pend_q->rid_queue[pend_q->enq_tail].rid = (uintptr_t)op;
+	pend_q->rid_queue[pend_q->enq_tail].user_id = op->user_id;
+
+	/* Mark result as not done */
+	res = (union otx2_ree_res *)(op);
+	res->s.done = 0;
+	res->s.ree_err = 0;
+
+	/* We will use soft queue length here to limit requests */
+	REE_MOD_INC(pend_q->enq_tail, OTX2_REE_DEFAULT_CMD_QLEN);
+	pend_q->pending_count += 1;
+	REE_MOD_INC(qp->otx2_regexdev_jobid, 0xFFFFFF);
+	REE_MOD_INC(qp->write_offset, OTX2_REE_IQ_LEN);
+
+	return 0;
+}
+
+static uint16_t
+otx2_ree_enqueue_burst(struct rte_regexdev *dev, uint16_t qp_id,
+		       struct rte_regex_ops **ops, uint16_t nb_ops)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_qp *qp = data->queue_pairs[qp_id];
+	struct otx2_ree_pending_queue *pend_q;
+	uint16_t nb_allowed, count = 0;
+	struct rte_regex_ops *op;
+	int ret;
+
+	pend_q = &qp->pend_q;
+
+	nb_allowed = OTX2_REE_DEFAULT_CMD_QLEN - pend_q->pending_count;
+	if (nb_ops > nb_allowed)
+		nb_ops = nb_allowed;
+
+	for (count = 0; count < nb_ops; count++) {
+		op = ops[count];
+		ret = ree_enqueue(qp, op, pend_q);
+
+		if (unlikely(ret))
+			break;
+	}
+
+	/*
+	 * Make sure all instructions are written before DOORBELL is activated
+	 */
+	rte_io_wmb();
+
+	/* Update Doorbell */
+	otx2_write64(count, qp->base + OTX2_REE_LF_DOORBELL);
+
+	return count;
+}
+
+static inline void
+ree_dequeue_post_process(struct rte_regex_ops *ops)
+{
+	uint8_t ree_res_mcnt, ree_res_dmcnt;
+	int off = REE_MATCH_OFFSET;
+	struct ree_res_s_98 *res;
+	uint16_t ree_res_status;
+	uint64_t match;
+
+	res = (struct ree_res_s_98 *)ops;
+	/* store res values on stack since ops and res
+	 * are using the same memory
+	 */
+	ree_res_status = res->ree_res_status;
+	ree_res_mcnt = res->ree_res_mcnt;
+	ree_res_dmcnt = res->ree_res_dmcnt;
+	ops->rsp_flags = 0;
+	ops->nb_actual_matches = ree_res_dmcnt;
+	ops->nb_matches = ree_res_mcnt;
+	if (unlikely(res->ree_err)) {
+		ops->nb_actual_matches = 0;
+		ops->nb_matches = 0;
+	}
+
+	if (unlikely(ree_res_status != REE_TYPE_RESULT_DESC)) {
+		if (ree_res_status & OTX2_REE_STATUS_PMI_SOJ_BIT)
+			ops->rsp_flags |= RTE_REGEX_OPS_RSP_PMI_SOJ_F;
+		if (ree_res_status & OTX2_REE_STATUS_PMI_EOJ_BIT)
+			ops->rsp_flags |= RTE_REGEX_OPS_RSP_PMI_EOJ_F;
+		if (ree_res_status & OTX2_REE_STATUS_ML_CNT_DET_BIT)
+			ops->rsp_flags |= RTE_REGEX_OPS_RSP_MAX_SCAN_TIMEOUT_F;
+		if (ree_res_status & OTX2_REE_STATUS_MM_CNT_DET_BIT)
+			ops->rsp_flags |= RTE_REGEX_OPS_RSP_MAX_MATCH_F;
+		if (ree_res_status & OTX2_REE_STATUS_MP_CNT_DET_BIT)
+			ops->rsp_flags |= RTE_REGEX_OPS_RSP_MAX_PREFIX_F;
+	}
+	if (ops->nb_matches > 0) {
+		/* Move the matches to the correct offset */
+		off = ((ops->nb_matches < REE_NUM_MATCHES_ALIGN) ?
+			ops->nb_matches : REE_NUM_MATCHES_ALIGN);
+		match = (uint64_t)ops + REE_MATCH_OFFSET;
+		match += (ops->nb_matches - off) *
+			sizeof(union otx2_ree_match);
+		memcpy((void *)ops->matches, (void *)match,
+			off * sizeof(union otx2_ree_match));
+	}
+}
+
+static uint16_t
+otx2_ree_dequeue_burst(struct rte_regexdev *dev, uint16_t qp_id,
+		       struct rte_regex_ops **ops, uint16_t nb_ops)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_qp *qp = data->queue_pairs[qp_id];
+	struct otx2_ree_pending_queue *pend_q;
+	int i, nb_pending, nb_completed = 0;
+	volatile struct ree_res_s_98 *res;
+	struct otx2_ree_rid *rid;
+
+	pend_q = &qp->pend_q;
+
+	nb_pending = pend_q->pending_count;
+
+	if (nb_ops > nb_pending)
+		nb_ops = nb_pending;
+
+	for (i = 0; i < nb_ops; i++) {
+		rid = &pend_q->rid_queue[pend_q->deq_head];
+		res = (volatile struct ree_res_s_98 *)(rid->rid);
+
+		/* Check response header done bit if completed */
+		if (unlikely(!res->done))
+			break;
+
+		ops[i] = (struct rte_regex_ops *)(rid->rid);
+		ops[i]->user_id = rid->user_id;
+
+		REE_MOD_INC(pend_q->deq_head, OTX2_REE_DEFAULT_CMD_QLEN);
+		pend_q->pending_count -= 1;
+	}
+
+	nb_completed = i;
+
+	for (i = 0; i < nb_completed; i++)
+		ree_dequeue_post_process(ops[i]);
+
+	return nb_completed;
+}
+
+static int
+otx2_ree_dev_info_get(struct rte_regexdev *dev, struct rte_regexdev_info *info)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+
+	ree_func_trace();
+
+	if (info == NULL)
+		return -EINVAL;
+
+	info->driver_name = dev->device->driver->name;
+	info->dev = dev->device;
+
+	info->max_queue_pairs = vf->max_queues;
+	info->max_matches = vf->max_matches;
+	info->max_payload_size = OTX2_REE_MAX_PAYLOAD_SIZE;
+	info->max_rules_per_group = data->max_rules_per_group;
+	info->max_groups = data->max_groups;
+	info->regexdev_capa = data->regexdev_capa;
+	info->rule_flags = data->rule_flags;
+
+	return 0;
+}
+
+static int
+otx2_ree_dev_config(struct rte_regexdev *dev,
+		    const struct rte_regexdev_config *cfg)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	const struct ree_rule_db *rule_db;
+	uint32_t rule_db_len;
+	int ret;
+
+	ree_func_trace();
+
+	if (cfg->nb_queue_pairs > vf->max_queues) {
+		otx2_err("Invalid number of queue pairs requested");
+		return -EINVAL;
+	}
+
+	if (cfg->nb_max_matches != vf->max_matches) {
+		otx2_err("Invalid number of max matches requested");
+		return -EINVAL;
+	}
+
+	if (cfg->dev_cfg_flags != 0) {
+		otx2_err("Invalid device configuration flags requested");
+		return -EINVAL;
+	}
+
+	/* Unregister error interrupts */
+	if (vf->err_intr_registered)
+		otx2_ree_err_intr_unregister(dev);
+
+	/* Detach queues */
+	if (vf->nb_queues) {
+		ret = otx2_ree_queues_detach(dev);
+		if (ret) {
+			otx2_err("Could not detach REE queues");
+			return ret;
+		}
+	}
+
+	/* TEMP : should be in lib */
+	if (data->queue_pairs == NULL) { /* first time configuration */
+		data->queue_pairs = rte_zmalloc("regexdev->queue_pairs",
+				sizeof(data->queue_pairs[0]) *
+				cfg->nb_queue_pairs, RTE_CACHE_LINE_SIZE);
+
+		if (data->queue_pairs == NULL) {
+			data->nb_queue_pairs = 0;
+			otx2_err("Failed to get memory for qp meta data, nb_queues %u",
+					cfg->nb_queue_pairs);
+			return -ENOMEM;
+		}
+	} else { /* re-configure */
+		uint16_t old_nb_queues = data->nb_queue_pairs;
+		void **qp;
+		unsigned int i;
+
+		qp = data->queue_pairs;
+
+		for (i = cfg->nb_queue_pairs; i < old_nb_queues; i++) {
+			ret = ree_queue_pair_release(dev, i);
+			if (ret < 0)
+				return ret;
+		}
+
+		qp = rte_realloc(qp, sizeof(qp[0]) * cfg->nb_queue_pairs,
+				RTE_CACHE_LINE_SIZE);
+		if (qp == NULL) {
+			otx2_err("Failed to realloc qp meta data, nb_queues %u",
+					cfg->nb_queue_pairs);
+			return -ENOMEM;
+		}
+
+		if (cfg->nb_queue_pairs > old_nb_queues) {
+			uint16_t new_qs = cfg->nb_queue_pairs - old_nb_queues;
+			memset(qp + old_nb_queues, 0, sizeof(qp[0]) * new_qs);
+		}
+
+		data->queue_pairs = qp;
+	}
+	data->nb_queue_pairs = cfg->nb_queue_pairs;
+
+	/* Attach queues */
+	otx2_ree_dbg("Attach %d queues", cfg->nb_queue_pairs);
+	ret = otx2_ree_queues_attach(dev, cfg->nb_queue_pairs);
+	if (ret) {
+		otx2_err("Could not attach queues");
+		return -ENODEV;
+	}
+
+	ret = otx2_ree_msix_offsets_get(dev);
+	if (ret) {
+		otx2_err("Could not get MSI-X offsets");
+		goto queues_detach;
+	}
+
+	if (cfg->rule_db && cfg->rule_db_len) {
+		otx2_ree_dbg("rule_db length %d", cfg->rule_db_len);
+		rule_db = (const struct ree_rule_db *)cfg->rule_db;
+		rule_db_len = rule_db->number_of_entries *
+				sizeof(struct ree_rule_db_entry);
+		otx2_ree_dbg("rule_db number of entries %d",
+				rule_db->number_of_entries);
+		if (rule_db_len > cfg->rule_db_len) {
+			otx2_err("Could not program rule db");
+			ret = -EINVAL;
+			goto queues_detach;
+		}
+		ret = otx2_ree_rule_db_prog(dev, (const char *)rule_db->entries,
+				rule_db_len, NULL, OTX2_REE_NON_INC_PROG);
+		if (ret) {
+			otx2_err("Could not program rule db");
+			goto queues_detach;
+		}
+	}
+
+	dev->enqueue = otx2_ree_enqueue_burst;
+	dev->dequeue = otx2_ree_dequeue_burst;
+
+	rte_mb();
+	return 0;
+
+queues_detach:
+	otx2_ree_queues_detach(dev);
+	return ret;
+}
+
+static int
+otx2_ree_stop(struct rte_regexdev *dev)
+{
+	RTE_SET_USED(dev);
+
+	ree_func_trace();
+	return 0;
+}
+
+static int
+otx2_ree_start(struct rte_regexdev *dev)
+{
+	uint32_t rule_db_len = 0;
+	int ret;
+
+	ree_func_trace();
+
+	ret = otx2_ree_rule_db_len_get(dev, &rule_db_len, NULL);
+	if (ret)
+		return ret;
+	if (rule_db_len == 0) {
+		otx2_err("Rule db not programmed");
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+static int
+otx2_ree_close(struct rte_regexdev *dev)
+{
+	return ree_dev_fini(dev);
+}
+
+static int
+otx2_ree_queue_pair_setup(struct rte_regexdev *dev, uint16_t qp_id,
+		const struct rte_regexdev_qp_conf *qp_conf)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_qp *qp;
+
+	ree_func_trace("Queue=%d", qp_id);
+
+	if (data->queue_pairs[qp_id] != NULL)
+		ree_queue_pair_release(dev, qp_id);
+
+	if (qp_conf->nb_desc > OTX2_REE_DEFAULT_CMD_QLEN) {
+		otx2_err("Could not setup queue pair for %u descriptors",
+				qp_conf->nb_desc);
+		return -EINVAL;
+	}
+	if (qp_conf->qp_conf_flags != 0) {
+		otx2_err("Could not setup queue pair with configuration flags 0x%x",
+				qp_conf->qp_conf_flags);
+		return -EINVAL;
+	}
+
+	qp = ree_qp_create(dev, qp_id);
+	if (qp == NULL) {
+		otx2_err("Could not create queue pair %d", qp_id);
+		return -ENOMEM;
+	}
+	qp->cb = qp_conf->cb;
+	data->queue_pairs[qp_id] = qp;
+
+	return 0;
+}
+
+static int
+otx2_ree_rule_db_compile_activate(struct rte_regexdev *dev)
+{
+	return otx2_ree_rule_db_compile_prog(dev);
+}
+
+static int
+otx2_ree_rule_db_update(struct rte_regexdev *dev,
+		const struct rte_regexdev_rule *rules, uint16_t nb_rules)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct rte_regexdev_rule *old_ptr;
+	uint32_t i, sum_nb_rules;
+
+	ree_func_trace("nb_rules=%d", nb_rules);
+
+	for (i = 0; i < nb_rules; i++) {
+		if (rules[i].op == RTE_REGEX_RULE_OP_REMOVE)
+			break;
+		if (rules[i].group_id >= data->max_groups)
+			break;
+		if (rules[i].rule_id >= data->max_rules_per_group)
+			break;
+		/* logical implication
+		 * p    q    p -> q
+		 * 0    0      1
+		 * 0    1      1
+		 * 1    0      0
+		 * 1    1      1
+		 */
+		if ((~(rules[i].rule_flags) | data->rule_flags) == 0)
+			break;
+	}
+	nb_rules = i;
+
+	if (data->nb_rules == 0) {
+
+		data->rules = rte_malloc("rte_regexdev_rules",
+				nb_rules*sizeof(struct rte_regexdev_rule), 0);
+		if (data->rules == NULL)
+			return -ENOMEM;
+
+		memcpy(data->rules, rules,
+				nb_rules*sizeof(struct rte_regexdev_rule));
+		data->nb_rules = nb_rules;
+	} else {
+
+		old_ptr = data->rules;
+		sum_nb_rules = data->nb_rules + nb_rules;
+		data->rules = rte_realloc(data->rules,
+				sum_nb_rules * sizeof(struct rte_regexdev_rule),
+							0);
+		if (data->rules == NULL) {
+			data->rules = old_ptr;
+			return -ENOMEM;
+		}
+		memcpy(&data->rules[data->nb_rules], rules,
+				nb_rules*sizeof(struct rte_regexdev_rule));
+		data->nb_rules = sum_nb_rules;
+	}
+	return nb_rules;
+}
+
+static int
+otx2_ree_rule_db_import(struct rte_regexdev *dev, const char *rule_db,
+		uint32_t rule_db_len)
+{
+
+	const struct ree_rule_db *ree_rule_db;
+	uint32_t ree_rule_db_len;
+	int ret;
+
+	ree_func_trace("rule_db_len=%d", rule_db_len);
+
+	ree_rule_db = (const struct ree_rule_db *)rule_db;
+	ree_rule_db_len = ree_rule_db->number_of_entries *
+			sizeof(struct ree_rule_db_entry);
+	if (ree_rule_db_len > rule_db_len) {
+		otx2_err("Could not program rule db");
+		return -EINVAL;
+	}
+	ret = otx2_ree_rule_db_prog(dev, (const char *)ree_rule_db->entries,
+			ree_rule_db_len, NULL, OTX2_REE_NON_INC_PROG);
+	if (ret) {
+		otx2_err("Could not program rule db");
+		return -ENOSPC;
+	}
+	return 0;
+}
+
+static int
+otx2_ree_rule_db_export(struct rte_regexdev *dev, char *rule_db)
+{
+	struct ree_rule_db *ree_rule_db;
+	uint32_t rule_dbi_len;
+	uint32_t rule_db_len;
+	int ret;
+
+	ree_func_trace();
+
+	ret = otx2_ree_rule_db_len_get(dev, &rule_db_len, &rule_dbi_len);
+	if (ret)
+		return ret;
+
+	if (rule_db == NULL) {
+		rule_db_len += sizeof(struct ree_rule_db);
+		return rule_db_len;
+	}
+
+	ree_rule_db = (struct ree_rule_db *)rule_db;
+	ret = otx2_ree_rule_db_get(dev, (char *)ree_rule_db->entries,
+			rule_db_len, NULL, 0);
+	if (ret) {
+		otx2_err("Could not export rule db");
+		return -EFAULT;
+	}
+	ree_rule_db->number_of_entries =
+			rule_db_len/sizeof(struct ree_rule_db_entry);
+	ree_rule_db->revision = REE_RULE_DB_REVISION;
+	ree_rule_db->version = REE_RULE_DB_VERSION;
+
+	return 0;
+}
+
+static int
+ree_get_blkaddr(struct otx2_dev *dev)
+{
+	int pf;
+
+	pf = otx2_get_pf(dev->pf_func);
+	if (pf == REE0_PF)
+		return RVU_BLOCK_ADDR_REE0;
+	else if (pf == REE1_PF)
+		return RVU_BLOCK_ADDR_REE1;
+	else
+		return 0;
+}
+
+static struct rte_regexdev_ops otx2_ree_ops = {
+		.dev_info_get = otx2_ree_dev_info_get,
+		.dev_configure = otx2_ree_dev_config,
+		.dev_qp_setup = otx2_ree_queue_pair_setup,
+		.dev_start = otx2_ree_start,
+		.dev_stop = otx2_ree_stop,
+		.dev_close = otx2_ree_close,
+		.dev_attr_get = NULL,
+		.dev_attr_set = NULL,
+		.dev_rule_db_update = otx2_ree_rule_db_update,
+		.dev_rule_db_compile_activate =
+				otx2_ree_rule_db_compile_activate,
+		.dev_db_import = otx2_ree_rule_db_import,
+		.dev_db_export = otx2_ree_rule_db_export,
+		.dev_xstats_names_get = NULL,
+		.dev_xstats_get = NULL,
+		.dev_xstats_by_name_get = NULL,
+		.dev_xstats_reset = NULL,
+		.dev_selftest = NULL,
+		.dev_dump = NULL,
+};
+
+static int
+otx2_ree_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
+		   struct rte_pci_device *pci_dev)
+{
+	char name[RTE_REGEXDEV_NAME_MAX_LEN];
+	struct otx2_ree_data *data;
+	struct otx2_dev *otx2_dev;
+	struct rte_regexdev *dev;
+	uint8_t max_matches = 0;
+	struct otx2_ree_vf *vf;
+	uint16_t nb_queues = 0;
+	int ret;
+
+	rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
+
+	dev = ree_dev_register(name);
+	if (dev == NULL) {
+		ret = -ENODEV;
+		goto exit;
+	}
+
+	dev->dev_ops = &otx2_ree_ops;
+	dev->device = &pci_dev->device;
+
+	/* Get private data space allocated */
+	data = dev->data->dev_private;
+	vf = &data->vf;
+
+	otx2_dev = &vf->otx2_dev;
+
+	/* Initialize the base otx2_dev object */
+	ret = otx2_dev_init(pci_dev, otx2_dev);
+	if (ret) {
+		otx2_err("Could not initialize otx2_dev");
+		goto dev_unregister;
+	}
+	/* Get REE block address */
+	vf->block_address = ree_get_blkaddr(otx2_dev);
+	if (!vf->block_address) {
+		otx2_err("Could not determine block PF number");
+		goto otx2_dev_fini;
+	}
+
+	/* Get number of queues available on the device */
+	ret = otx2_ree_available_queues_get(dev, &nb_queues);
+	if (ret) {
+		otx2_err("Could not determine the number of queues available");
+		goto otx2_dev_fini;
+	}
+
+	/* Don't exceed the limits set per VF */
+	nb_queues = RTE_MIN(nb_queues, OTX2_REE_MAX_QUEUES_PER_VF);
+
+	if (nb_queues == 0) {
+		otx2_err("No free queues available on the device");
+		goto otx2_dev_fini;
+	}
+
+	vf->max_queues = nb_queues;
+
+	otx2_ree_dbg("Max queues supported by device: %d", vf->max_queues);
+
+	/* Get number of maximum matches supported on the device */
+	ret = otx2_ree_max_matches_get(dev, &max_matches);
+	if (ret) {
+		otx2_err("Could not determine the maximum matches supported");
+		goto otx2_dev_fini;
+	}
+	/* Don't exceed the limits set per VF */
+	max_matches = RTE_MIN(max_matches, OTX2_REE_MAX_MATCHES_PER_VF);
+	if (max_matches == 0) {
+		otx2_err("Could not determine the maximum matches supported");
+		goto otx2_dev_fini;
+	}
+
+	vf->max_matches = max_matches;
+
+	otx2_ree_dbg("Max matches supported by device: %d", vf->max_matches);
+	data->rule_flags = RTE_REGEX_PCRE_RULE_ALLOW_EMPTY_F |
+			RTE_REGEX_PCRE_RULE_ANCHORED_F;
+	data->regexdev_capa = 0;
+	data->max_groups = REE_MAX_GROUPS;
+	data->max_rules_per_group = REE_MAX_RULES_PER_GROUP;
+	data->nb_rules = 0;
+
+	dev->state = RTE_REGEXDEV_READY;
+	return 0;
+
+otx2_dev_fini:
+	otx2_dev_fini(pci_dev, otx2_dev);
+dev_unregister:
+	ree_dev_unregister(dev);
+exit:
+	otx2_err("Could not create device (vendor_id: 0x%x device_id: 0x%x)",
+		    pci_dev->id.vendor_id, pci_dev->id.device_id);
+	return ret;
+}
+
+static int
+otx2_ree_pci_remove(struct rte_pci_device *pci_dev)
+{
+	char name[RTE_REGEXDEV_NAME_MAX_LEN];
+	struct rte_regexdev *dev = NULL;
+
+	if (pci_dev == NULL)
+		return -EINVAL;
+
+	rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
+
+	dev = rte_regexdev_get_device_by_name(name);
+
+	if (dev == NULL)
+		return -ENODEV;
+
+	return ree_dev_fini(dev);
+}
+
+static struct rte_pci_id pci_id_ree_table[] = {
+	{
+		RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM,
+				PCI_DEVID_OCTEONTX2_RVU_REE_PF)
+	},
+};
+
+static struct rte_pci_driver otx2_regexdev_pmd = {
+	.id_table = pci_id_ree_table,
+	.drv_flags = RTE_PCI_DRV_NEED_MAPPING,
+	.probe = otx2_ree_pci_probe,
+	.remove = otx2_ree_pci_remove,
+};
+
+
+RTE_PMD_REGISTER_PCI(REGEXDEV_NAME_OCTEONTX2_PMD, otx2_regexdev_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(REGEXDEV_NAME_OCTEONTX2_PMD, pci_id_ree_table);
diff --git a/drivers/regex/octeontx2/otx2_regexdev.h b/drivers/regex/octeontx2/otx2_regexdev.h
new file mode 100644
index 000000000..d710535f5
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev.h
@@ -0,0 +1,109 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _OTX2_REGEXDEV_H_
+#define _OTX2_REGEXDEV_H_
+
+#include <rte_common.h>
+#include <rte_regexdev.h>
+
+#include "otx2_dev.h"
+
+#define ree_func_trace otx2_ree_dbg
+
+/* Marvell OCTEON TX2 Regex PMD device name */
+#define REGEXDEV_NAME_OCTEONTX2_PMD	regex_octeontx2
+
+#define OTX2_REE_MAX_LFS		36
+#define OTX2_REE_MAX_QUEUES_PER_VF	36
+#define OTX2_REE_MAX_MATCHES_PER_VF	254
+
+#define OTX2_REE_MAX_PAYLOAD_SIZE	(1 << 14)
+
+#define OTX2_REE_NON_INC_PROG 0
+#define OTX2_REE_INC_PROG 1
+
+#define REE_MOD_INC(i, l)   ((i) == (l - 1) ? (i) = 0 : (i)++)
+
+
+/**
+ * Device vf data
+ */
+struct otx2_ree_vf {
+	struct otx2_dev otx2_dev;
+	/**< Base class */
+	uint16_t max_queues;
+	/**< Max queues supported */
+	uint8_t nb_queues;
+	/**< Number of regex queues attached */
+	uint16_t max_matches;
+	/**<  Max matches supported*/
+	uint16_t lf_msixoff[OTX2_REE_MAX_LFS];
+	/**< MSI-X offsets */
+	uint8_t block_address;
+	/**< REE Block Address */
+	uint8_t err_intr_registered:1;
+	/**< Are error interrupts registered? */
+};
+
+/**
+ * Device private data
+ */
+struct otx2_ree_data {
+	uint32_t regexdev_capa;
+	uint64_t rule_flags;
+	/**< Feature flags exposes HW/SW features for the given device */
+	uint16_t max_rules_per_group;
+	/**< Maximum rules supported per subset by this device */
+	uint16_t max_groups;
+	/**< Maximum subset supported by this device */
+	void **queue_pairs;
+	/**< Array of pointers to queue pairs. */
+	uint16_t nb_queue_pairs;
+	/**< Number of device queue pairs. */
+	struct otx2_ree_vf vf;
+	/**< vf data */
+	struct rte_regexdev_rule *rules;
+	/**< rules to be compiled */
+	uint16_t nb_rules;
+	/**< number of rules */
+} __rte_cache_aligned;
+
+struct otx2_ree_rid {
+	uintptr_t rid;
+	/** Request id of a ree operation */
+	uint64_t user_id;
+	/* Client data */
+	/**< IOVA address of the pattern to be matched. */
+};
+
+struct otx2_ree_pending_queue {
+	uint64_t pending_count;
+	/** Pending requests count */
+	struct otx2_ree_rid *rid_queue;
+	/** Array of pending requests */
+	uint16_t enq_tail;
+	/** Tail of queue to be used for enqueue */
+	uint16_t deq_head;
+	/** Head of queue to be used for dequeue */
+};
+
+struct otx2_ree_qp {
+	uint32_t id;
+	/**< Queue pair id */
+	uintptr_t base;
+	/**< Base address where BAR is mapped */
+	struct otx2_ree_pending_queue pend_q;
+	/**< Pending queue */
+	rte_iova_t iq_dma_addr;
+	/**< Instruction queue address */
+	uint32_t otx2_regexdev_jobid;
+	/**< Job ID */
+	uint32_t write_offset;
+	/**< write offset */
+	regexdev_stop_flush_t cb;
+	/**< Callback function called during rte_regex_dev_stop()*/
+};
+
+#endif /* _OTX2_REGEXDEV_H_ */
diff --git a/drivers/regex/octeontx2/otx2_regexdev_compiler.c b/drivers/regex/octeontx2/otx2_regexdev_compiler.c
new file mode 100644
index 000000000..785459f74
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev_compiler.c
@@ -0,0 +1,229 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#include <rte_malloc.h>
+#include <rte_regexdev.h>
+
+#include "otx2_regexdev.h"
+#include "otx2_regexdev_compiler.h"
+#include "otx2_regexdev_mbox.h"
+
+#ifdef REE_COMPILER_SDK
+#include <rxp-compiler.h>
+
+static int
+ree_rule_db_compile(const struct rte_regexdev_rule *rules,
+		uint16_t nb_rules, struct rxp_rof **rof, struct rxp_rof **rofi,
+		struct rxp_rof *rof_for_incremental_compile,
+		struct rxp_rof *rofi_for_incremental_compile)
+{
+	/*INPUT*/
+	struct rxp_prefix_selection_control_list *prefix_selection_control_list
+		= NULL;
+	struct rxp_blacklist_data_sample *blacklist_sample_data = NULL;
+	struct rxp_rule_ids_to_remove *rule_ids_to_remove = NULL;
+	struct rxp_roff *roff_for_incremental_compile = NULL;
+
+	/*OPTIONS - setting default values*/
+	enum rxp_virtual_prefix_mode virtual_prefix_mode =
+			RXP_VIRTUAL_PREFIX_MODE_0;
+	enum rxp_prefix_capacity prefix_capacity = RXP_PREFIX_CAPACITY_32K;
+	/**< rxp_global_regex_options_flags*/
+	enum rxp_compiler_objective objective = RXP_COMPILER_OBJECTIVE_5;
+	enum rxp_tpe_data_width tpe_data_width = RXP_TPE_DATA_WIDTH_4;
+	uint32_t compiler_options = RXP_COMPILER_OPTIONS_FORCE;
+	/**< rxp_compiler_options_flags*/
+	enum rxp_verbose_level verbose = RXP_VERBOSE_LEVEL_3;
+	enum rxp_version set_rxp_version = RXP_VERSION_V5_8;
+	uint32_t compiler_output_flags = 0;
+	/**< rxp_compiler_output_flags*/
+	uint32_t global_regex_options = 0;
+	/**< rxp_global_regex_options_flags*/
+	float set_auto_blacklist = 0;
+	uint32_t max_rep_max = 65535;
+	uint32_t divide_ruleset = 1;
+	struct rxp_ruleset ruleset;
+	float ptpb_threshold = 0;
+	uint32_t set_max = 0;
+	uint32_t threads = 1;
+
+	/*OUTPUT*/
+	struct rxp_rule_direction_analysis *rule_direction_analysis = NULL;
+	struct rxp_compilation_statistics *compilation_statistics = NULL;
+	struct rxp_prefix_selection_control_list *generated_pscl = NULL;
+	struct rxp_uncompiled_rules_log *uncompiled_rules_log = NULL;
+	struct rxp_critical_rules_rank *critical_rules_rank = NULL;
+	struct rxp_compiled_rules_log *compiled_rules_log = NULL;
+	struct rxp_roff *roff = NULL;
+
+	uint16_t i;
+	int ret;
+
+	ruleset.number_of_entries = nb_rules;
+	ruleset.rules = rte_malloc("rxp_rule_entry",
+			nb_rules*sizeof(struct rxp_rule_entry), 0);
+
+	if (ruleset.rules == NULL) {
+		otx2_err("Could not allocate memory for rule compilation\n");
+		return -EFAULT;
+	}
+	if (rof_for_incremental_compile)
+		compiler_options |= RXP_COMPILER_OPTIONS_INCREMENTAL;
+	if (rofi_for_incremental_compile)
+		compiler_options |= RXP_COMPILER_OPTIONS_CHECKSUM;
+
+	for (i = 0; i < nb_rules; i++) {
+		ruleset.rules[i].number_of_prefix_entries = 0;
+		ruleset.rules[i].prefix = NULL;
+		ruleset.rules[i].rule = rules[i].pcre_rule;
+		ruleset.rules[i].rule_id = rules[i].rule_id;
+		ruleset.rules[i].subset_id = rules[i].group_id;
+		ruleset.rules[i].rule_direction_type =
+				RXP_RULE_DIRECTION_TYPE_NONE;
+	}
+
+	ret = rxp_compile_advanced(
+			/*INPUT*/
+			&ruleset,
+			prefix_selection_control_list,
+			rof_for_incremental_compile,
+			roff_for_incremental_compile,
+			rofi_for_incremental_compile,
+			rule_ids_to_remove,
+			blacklist_sample_data,
+
+			/*OPTIONS*/
+			compiler_options,
+			prefix_capacity,
+			global_regex_options,
+			set_auto_blacklist,
+			set_max,
+			objective,
+			ptpb_threshold,
+			max_rep_max,
+			threads,
+			set_rxp_version,
+			verbose,
+			tpe_data_width,
+			virtual_prefix_mode,
+			compiler_output_flags,
+			divide_ruleset,
+
+			/*OUTPUT*/
+			&compilation_statistics,
+			&compiled_rules_log,
+			&critical_rules_rank,
+			&rule_direction_analysis,
+			&uncompiled_rules_log,
+			rof,
+			&roff,
+			rofi,
+			&generated_pscl);
+	rte_free(ruleset.rules);
+
+	return ret;
+}
+
+int
+otx2_ree_rule_db_compile_prog(struct rte_regexdev *dev)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	char compiler_version[] = "20.5.2.eda0fa2";
+	char timestamp[] = "19700101_000001";
+	uint32_t rule_db_len, rule_dbi_len;
+	struct rxp_rof *rofi_inc_p = NULL;
+	struct rxp_rof_entry rule_dbi[6];
+	char *rofi_rof_entries = NULL;
+	struct rxp_rof *rofi = NULL;
+	struct rxp_rof *rof = NULL;
+	struct rxp_rof rofi_inc;
+	struct rxp_rof rof_inc;
+	char *rule_db = NULL;
+	int ret;
+
+	ree_func_trace();
+
+	ret = otx2_ree_rule_db_len_get(dev, &rule_db_len, &rule_dbi_len);
+	if (ret != 0) {
+		otx2_err("Could not get rule db length");
+		return ret;
+	}
+
+	if (rule_db_len > 0) {
+		otx2_ree_dbg("Incremental compile, rule db len %d rule dbi len %d",
+				rule_db_len, rule_dbi_len);
+		rule_db = rte_malloc("ree_rule_db", rule_db_len, 0);
+		if (!rule_db) {
+			otx2_err("Could not allocate memory for rule db");
+			return -EFAULT;
+		}
+
+		ret = otx2_ree_rule_db_get(dev, rule_db, rule_db_len,
+				(char *)rule_dbi, rule_dbi_len);
+		if (ret) {
+			otx2_err("Could not read rule db");
+			rte_free(rule_db);
+			return -EFAULT;
+		}
+		rof_inc.rof_revision = 0;
+		rof_inc.rof_version = 2;
+		rof_inc.rof_entries = (struct rxp_rof_entry *)rule_db;
+		rof_inc.rxp_compiler_version = compiler_version;
+		rof_inc.timestamp = timestamp;
+		rof_inc.number_of_entries =
+				(rule_db_len/sizeof(struct rxp_rof_entry));
+
+		if (rule_dbi_len > 0) {
+			/* incremental compilation not the first time */
+			rofi_inc.rof_revision = 0;
+			rofi_inc.rof_version = 2;
+			rofi_inc.rof_entries = rule_dbi;
+			rofi_inc.rxp_compiler_version = compiler_version;
+			rofi_inc.timestamp = timestamp;
+			rofi_inc.number_of_entries =
+				(rule_dbi_len/sizeof(struct rxp_rof_entry));
+			rofi_inc_p = &rofi_inc;
+		}
+		ret = ree_rule_db_compile(data->rules, data->nb_rules, &rof,
+				&rofi, &rof_inc, rofi_inc_p);
+		if (rofi->number_of_entries == 0) {
+			otx2_ree_dbg("No change to rule db");
+			ret = 0;
+			goto free_structs;
+		}
+		rule_dbi_len = rofi->number_of_entries *
+				sizeof(struct rxp_rof_entry);
+		rofi_rof_entries = (char *)rofi->rof_entries;
+	} else {
+		/* full compilation */
+		ret = ree_rule_db_compile(data->rules, data->nb_rules, &rof,
+				&rofi, NULL, NULL);
+	}
+	if (ret != 0) {
+		otx2_err("Could not compile rule db");
+		goto free_structs;
+	}
+	rule_db_len = rof->number_of_entries * sizeof(struct rxp_rof_entry);
+	ret = otx2_ree_rule_db_prog(dev, (char *)rof->rof_entries, rule_db_len,
+			rofi_rof_entries, rule_dbi_len);
+	if (ret)
+		otx2_err("Could not program rule db");
+
+free_structs:
+	rxp_free_structs(NULL, NULL, NULL, NULL, NULL, &rof, NULL, &rofi, NULL,
+			1);
+
+	if (rule_db)
+		rte_free(rule_db);
+
+	return ret;
+}
+#else
+int
+otx2_ree_rule_db_compile_prog(struct rte_regexdev *dev)
+{
+	RTE_SET_USED(dev);
+	return -ENOTSUP;
+}
+#endif
diff --git a/drivers/regex/octeontx2/otx2_regexdev_compiler.h b/drivers/regex/octeontx2/otx2_regexdev_compiler.h
new file mode 100644
index 000000000..8d2625bf7
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev_compiler.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _OTX2_REGEXDEV_COMPILER_H_
+#define _OTX2_REGEXDEV_COMPILER_H_
+
+int
+otx2_ree_rule_db_compile_prog(struct rte_regexdev *dev);
+
+#endif /* _OTX2_REGEXDEV_COMPILER_H_ */
diff --git a/drivers/regex/octeontx2/otx2_regexdev_hw_access.c b/drivers/regex/octeontx2/otx2_regexdev_hw_access.c
new file mode 100644
index 000000000..620d5c912
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev_hw_access.c
@@ -0,0 +1,167 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#include "otx2_common.h"
+#include "otx2_dev.h"
+#include "otx2_regexdev_hw_access.h"
+#include "otx2_regexdev_mbox.h"
+
+static void
+ree_lf_err_intr_handler(void *param)
+{
+	uintptr_t base = (uintptr_t)param;
+	uint8_t lf_id;
+	uint64_t intr;
+
+	lf_id = (base >> 12) & 0xFF;
+
+	intr = otx2_read64(base + OTX2_REE_LF_MISC_INT);
+	if (intr == 0)
+		return;
+
+	otx2_ree_dbg("LF %d MISC_INT: 0x%" PRIx64 "", lf_id, intr);
+
+	/* Clear interrupt */
+	otx2_write64(intr, base + OTX2_REE_LF_MISC_INT);
+}
+
+static void
+ree_lf_err_intr_unregister(const struct rte_regexdev *dev, uint16_t msix_off,
+			   uintptr_t base)
+{
+	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
+	struct rte_intr_handle *handle = &pci_dev->intr_handle;
+
+	/* Disable error interrupts */
+	otx2_write64(~0ull, base + OTX2_REE_LF_MISC_INT_ENA_W1C);
+
+	otx2_unregister_irq(handle, ree_lf_err_intr_handler, (void *)base,
+			    msix_off);
+}
+
+void
+otx2_ree_err_intr_unregister(const struct rte_regexdev *dev)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	uintptr_t base;
+	uint32_t i;
+
+	for (i = 0; i < vf->nb_queues; i++) {
+		base = OTX2_REE_LF_BAR2(vf, i);
+		ree_lf_err_intr_unregister(dev, vf->lf_msixoff[i], base);
+	}
+
+	vf->err_intr_registered = 0;
+}
+
+static int
+ree_lf_err_intr_register(const struct rte_regexdev *dev, uint16_t msix_off,
+			 uintptr_t base)
+{
+	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
+	struct rte_intr_handle *handle = &pci_dev->intr_handle;
+	int ret;
+
+	/* Disable error interrupts */
+	otx2_write64(~0ull, base + OTX2_REE_LF_MISC_INT_ENA_W1C);
+
+	/* Register error interrupt handler */
+	ret = otx2_register_irq(handle, ree_lf_err_intr_handler, (void *)base,
+				msix_off);
+	if (ret)
+		return ret;
+
+	/* Enable error interrupts */
+	otx2_write64(~0ull, base + OTX2_REE_LF_MISC_INT_ENA_W1S);
+
+	return 0;
+}
+
+int
+otx2_ree_err_intr_register(const struct rte_regexdev *dev)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	uint32_t i, j, ret;
+	uintptr_t base;
+
+	for (i = 0; i < vf->nb_queues; i++) {
+		if (vf->lf_msixoff[i] == MSIX_VECTOR_INVALID) {
+			otx2_err("Invalid REE LF MSI-X offset: 0x%x",
+				    vf->lf_msixoff[i]);
+			return -EINVAL;
+		}
+	}
+
+	for (i = 0; i < vf->nb_queues; i++) {
+		base = OTX2_REE_LF_BAR2(vf, i);
+		ret = ree_lf_err_intr_register(dev, vf->lf_msixoff[i], base);
+		if (ret)
+			goto intr_unregister;
+	}
+
+	vf->err_intr_registered = 1;
+	return 0;
+
+intr_unregister:
+	/* Unregister the ones already registered */
+	for (j = 0; j < i; j++) {
+		base = OTX2_REE_LF_BAR2(vf, j);
+		ree_lf_err_intr_unregister(dev, vf->lf_msixoff[j], base);
+	}
+	return ret;
+}
+
+int
+otx2_ree_iq_enable(const struct rte_regexdev *dev, const struct otx2_ree_qp *qp,
+		   uint8_t pri, uint32_t size_div2)
+{
+	union otx2_ree_lf_sbuf_addr base;
+	union otx2_ree_lf_ena lf_ena;
+
+	/* Set instruction queue size and priority */
+	otx2_ree_config_lf(dev, qp->id, pri, size_div2);
+
+	/* Set instruction queue base address */
+	/* Should be written after SBUF_CTL and before LF_ENA */
+
+	base.u = otx2_read64(qp->base + OTX2_REE_LF_SBUF_ADDR);
+	base.s.ptr = qp->iq_dma_addr >> 7;
+	otx2_write64(base.u, qp->base + OTX2_REE_LF_SBUF_ADDR);
+
+	/* Enable instruction queue */
+
+	lf_ena.u = otx2_read64(qp->base + OTX2_REE_LF_ENA);
+	lf_ena.s.ena = 1;
+	otx2_write64(lf_ena.u, qp->base + OTX2_REE_LF_ENA);
+
+	return 0;
+}
+
+void
+otx2_ree_iq_disable(struct otx2_ree_qp *qp)
+{
+	union otx2_ree_lf_ena lf_ena;
+
+	/* Stop instruction execution */
+	lf_ena.u = otx2_read64(qp->base + OTX2_REE_LF_ENA);
+	lf_ena.s.ena = 0x0;
+	otx2_write64(lf_ena.u, qp->base + OTX2_REE_LF_ENA);
+}
+
+int
+otx2_ree_max_matches_get(const struct rte_regexdev *dev, uint8_t *max_matches)
+{
+	union otx2_ree_af_reexm_max_match reexm_max_match;
+	int ret;
+
+	ret = otx2_ree_af_reg_read(dev, REE_AF_REEXM_MAX_MATCH,
+				   &reexm_max_match.u);
+	if (ret)
+		return ret;
+
+	*max_matches = reexm_max_match.s.max;
+	return 0;
+}
diff --git a/drivers/regex/octeontx2/otx2_regexdev_hw_access.h b/drivers/regex/octeontx2/otx2_regexdev_hw_access.h
new file mode 100644
index 000000000..dedf5f328
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev_hw_access.h
@@ -0,0 +1,202 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _OTX2_REGEXDEV_HW_ACCESS_H_
+#define _OTX2_REGEXDEV_HW_ACCESS_H_
+
+#include <stdint.h>
+
+#include "otx2_regexdev.h"
+
+/* REE instruction queue length */
+#define OTX2_REE_IQ_LEN			(1 << 13)
+
+#define OTX2_REE_DEFAULT_CMD_QLEN	OTX2_REE_IQ_LEN
+
+/* Status register bits */
+#define OTX2_REE_STATUS_PMI_EOJ_BIT		(1 << 14)
+#define OTX2_REE_STATUS_PMI_SOJ_BIT		(1 << 13)
+#define OTX2_REE_STATUS_MP_CNT_DET_BIT		(1 << 7)
+#define OTX2_REE_STATUS_MM_CNT_DET_BIT		(1 << 6)
+#define OTX2_REE_STATUS_ML_CNT_DET_BIT		(1 << 5)
+#define OTX2_REE_STATUS_MST_CNT_DET_BIT		(1 << 4)
+#define OTX2_REE_STATUS_MPT_CNT_DET_BIT		(1 << 3)
+
+/* Register offsets */
+/* REE LF registers */
+#define OTX2_REE_LF_DONE_INT		0x120ull
+#define OTX2_REE_LF_DONE_INT_W1S	0x130ull
+#define OTX2_REE_LF_DONE_INT_ENA_W1S	0x138ull
+#define OTX2_REE_LF_DONE_INT_ENA_W1C	0x140ull
+#define OTX2_REE_LF_MISC_INT		0x300ull
+#define OTX2_REE_LF_MISC_INT_W1S	0x310ull
+#define OTX2_REE_LF_MISC_INT_ENA_W1S	0x320ull
+#define OTX2_REE_LF_MISC_INT_ENA_W1C	0x330ull
+#define OTX2_REE_LF_ENA			0x10ull
+#define OTX2_REE_LF_SBUF_ADDR		0x20ull
+#define OTX2_REE_LF_DONE		0x100ull
+#define OTX2_REE_LF_DONE_ACK		0x110ull
+#define OTX2_REE_LF_DONE_WAIT		0x148ull
+#define OTX2_REE_LF_DOORBELL		0x400ull
+#define OTX2_REE_LF_OUTSTAND_JOB	0x410ull
+
+/* BAR 0 */
+#define OTX2_REE_AF_QUE_SBUF_CTL(a)	(0x1200ull | (uint64_t)(a) << 3)
+#define OTX2_REE_PRIV_LF_CFG(a)		(0x41000ull | (uint64_t)(a) << 3)
+
+#define OTX2_REE_LF_BAR2(vf, q_id) \
+		((vf)->otx2_dev.bar2 + \
+		 (((vf)->block_address << 20) | ((q_id) << 12)))
+
+
+#define OTX2_REE_QUEUE_HI_PRIO 0x1
+
+enum ree_desc_type_e {
+	REE_TYPE_JOB_DESC    = 0x0,
+	REE_TYPE_RESULT_DESC = 0x1,
+	REE_TYPE_ENUM_LAST   = 0x2
+};
+
+union otx2_ree_priv_lf_cfg {
+	uint64_t u;
+	struct {
+		uint64_t slot                        : 8;
+		uint64_t pf_func                     : 16;
+		uint64_t reserved_24_62              : 39;
+		uint64_t ena                         : 1;
+	} s;
+};
+
+
+union otx2_ree_lf_sbuf_addr {
+	uint64_t u;
+	struct {
+		uint64_t off                         : 7;
+		uint64_t ptr                         : 46;
+		uint64_t reserved_53_63              : 11;
+	} s;
+};
+
+union otx2_ree_lf_ena {
+	uint64_t u;
+	struct {
+		uint64_t ena                         : 1;
+		uint64_t reserved_1_63               : 63;
+	} s;
+};
+
+union otx2_ree_af_reexm_max_match {
+	uint64_t u;
+	struct {
+		uint64_t max                         : 8;
+		uint64_t reserved_8_63               : 56;
+	} s;
+};
+
+union otx2_ree_lf_done {
+	uint64_t u;
+	struct {
+		uint64_t done                        : 20;
+		uint64_t reserved_20_63              : 44;
+	} s;
+};
+
+union otx2_ree_inst {
+	uint64_t u[8];
+	struct  {
+		uint64_t doneint                     :  1;
+		uint64_t reserved_1_3                :  3;
+		uint64_t dg                          :  1;
+		uint64_t reserved_5_7                :  3;
+		uint64_t ooj                         :  1;
+		uint64_t reserved_9_15               :  7;
+		uint64_t reserved_16_63              : 48;
+		uint64_t inp_ptr_addr                : 64;
+		uint64_t inp_ptr_ctl                 : 64;
+		uint64_t res_ptr_addr                : 64;
+		uint64_t wq_ptr                      : 64;
+		uint64_t tag                         : 32;
+		uint64_t tt                          :  2;
+		uint64_t ggrp                        : 10;
+		uint64_t reserved_364_383            : 20;
+		uint64_t reserved_384_391            :  8;
+		uint64_t ree_job_id                  : 24;
+		uint64_t ree_job_ctrl                : 16;
+		uint64_t ree_job_length              : 15;
+		uint64_t reserved_447_447            :  1;
+		uint64_t ree_job_subset_id_0         : 16;
+		uint64_t ree_job_subset_id_1         : 16;
+		uint64_t ree_job_subset_id_2         : 16;
+		uint64_t ree_job_subset_id_3         : 16;
+	} cn98xx;
+};
+
+union otx2_ree_res_status {
+	uint64_t u;
+	struct {
+		uint64_t job_type                    :  3;
+		uint64_t mpt_cnt_det                 :  1;
+		uint64_t mst_cnt_det                 :  1;
+		uint64_t ml_cnt_det                  :  1;
+		uint64_t mm_cnt_det                  :  1;
+		uint64_t mp_cnt_det                  :  1;
+		uint64_t mode                        :  2;
+		uint64_t reserved_10_11              :  2;
+		uint64_t reserved_12_12              :  1;
+		uint64_t pmi_soj                     :  1;
+		uint64_t pmi_eoj                     :  1;
+		uint64_t reserved_15_15              :  1;
+		uint64_t reserved_16_63              : 48;
+	} s;
+};
+
+union otx2_ree_res {
+	uint64_t u[8];
+	struct ree_res_s_98 {
+		uint64_t done			:  1;
+		uint64_t hwjid			:  7;
+		uint64_t ree_res_job_id		: 24;
+		uint64_t ree_res_status		: 16;
+		uint64_t ree_res_dmcnt		:  8;
+		uint64_t ree_res_mcnt		:  8;
+		uint64_t ree_meta_ptcnt		: 16;
+		uint64_t ree_meta_icnt		: 16;
+		uint64_t ree_meta_lcnt		: 16;
+		uint64_t ree_pmi_min_byte_ptr	: 16;
+		uint64_t ree_err		:  1;
+		uint64_t reserved_129_190	: 62;
+		uint64_t doneint		:  1;
+		uint64_t reserved_192_255	: 64;
+		uint64_t reserved_256_319	: 64;
+		uint64_t reserved_320_383	: 64;
+		uint64_t reserved_384_447	: 64;
+		uint64_t reserved_448_511	: 64;
+	} s;
+};
+
+union otx2_ree_match {
+	uint64_t u;
+	struct {
+		uint64_t ree_rule_id                 : 32;
+		uint64_t start_ptr                   : 14;
+		uint64_t reserved_46_47              :  2;
+		uint64_t match_length                : 15;
+		uint64_t reserved_63_63              :  1;
+	} s;
+};
+
+void otx2_ree_err_intr_unregister(const struct rte_regexdev *dev);
+
+int otx2_ree_err_intr_register(const struct rte_regexdev *dev);
+
+int otx2_ree_iq_enable(const struct rte_regexdev *dev,
+		       const struct otx2_ree_qp *qp,
+		       uint8_t pri, uint32_t size_div128);
+
+void otx2_ree_iq_disable(struct otx2_ree_qp *qp);
+
+int otx2_ree_max_matches_get(const struct rte_regexdev *dev,
+			     uint8_t *max_matches);
+
+#endif /* _OTX2_REGEXDEV_HW_ACCESS_H_ */
diff --git a/drivers/regex/octeontx2/otx2_regexdev_mbox.c b/drivers/regex/octeontx2/otx2_regexdev_mbox.c
new file mode 100644
index 000000000..6d58d367d
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev_mbox.c
@@ -0,0 +1,401 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#include "otx2_common.h"
+#include "otx2_dev.h"
+#include "otx2_regexdev_mbox.h"
+#include "otx2_regexdev.h"
+
+int
+otx2_ree_available_queues_get(const struct rte_regexdev *dev,
+			      uint16_t *nb_queues)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct free_rsrcs_rsp *rsp;
+	struct otx2_dev *otx2_dev;
+	int ret;
+
+	otx2_dev = &vf->otx2_dev;
+	otx2_mbox_alloc_msg_free_rsrc_cnt(otx2_dev->mbox);
+
+	ret = otx2_mbox_process_msg(otx2_dev->mbox, (void *)&rsp);
+	if (ret)
+		return -EIO;
+
+	if (vf->block_address == RVU_BLOCK_ADDR_REE0)
+		*nb_queues = rsp->ree0;
+	else
+		*nb_queues = rsp->ree1;
+	return 0;
+}
+
+int
+otx2_ree_queues_attach(const struct rte_regexdev *dev, uint8_t nb_queues)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct rsrc_attach_req *req;
+	struct otx2_mbox *mbox;
+
+	/* Ask AF to attach required LFs */
+	mbox = vf->otx2_dev.mbox;
+	req = otx2_mbox_alloc_msg_attach_resources(mbox);
+
+	/* 1 LF = 1 queue */
+	req->reelfs = nb_queues;
+	req->ree_blkaddr = vf->block_address;
+
+	if (otx2_mbox_process(mbox) < 0)
+		return -EIO;
+
+	/* Update number of attached queues */
+	vf->nb_queues = nb_queues;
+
+	return 0;
+}
+
+int
+otx2_ree_queues_detach(const struct rte_regexdev *dev)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct rsrc_detach_req *req;
+	struct otx2_mbox *mbox;
+
+	mbox = vf->otx2_dev.mbox;
+	req = otx2_mbox_alloc_msg_detach_resources(mbox);
+	req->reelfs = true;
+	req->partial = true;
+	if (otx2_mbox_process(mbox) < 0)
+		return -EIO;
+
+	/* Queues have been detached */
+	vf->nb_queues = 0;
+
+	return 0;
+}
+
+int
+otx2_ree_msix_offsets_get(const struct rte_regexdev *dev)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct msix_offset_rsp *rsp;
+	struct otx2_mbox *mbox;
+	uint32_t i, ret;
+
+	/* Get REE MSI-X vector offsets */
+	mbox = vf->otx2_dev.mbox;
+	otx2_mbox_alloc_msg_msix_offset(mbox);
+
+	ret = otx2_mbox_process_msg(mbox, (void *)&rsp);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < vf->nb_queues; i++) {
+		if (vf->block_address == RVU_BLOCK_ADDR_REE0)
+			vf->lf_msixoff[i] = rsp->ree0_lf_msixoff[i];
+		else
+			vf->lf_msixoff[i] = rsp->ree1_lf_msixoff[i];
+		otx2_ree_dbg("lf_msixoff[%d]  0x%x", i, vf->lf_msixoff[i]);
+	}
+
+	return 0;
+}
+
+static int
+ree_send_mbox_msg(struct otx2_ree_vf *vf)
+{
+	struct otx2_mbox *mbox = vf->otx2_dev.mbox;
+	int ret;
+
+	otx2_mbox_msg_send(mbox, 0);
+
+	ret = otx2_mbox_wait_for_rsp(mbox, 0);
+	if (ret < 0) {
+		otx2_err("Could not get mailbox response");
+		return ret;
+	}
+
+	return 0;
+}
+
+int
+otx2_ree_config_lf(const struct rte_regexdev *dev, uint8_t lf, uint8_t pri,
+		   uint32_t size)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct ree_lf_req_msg *req;
+	struct otx2_mbox *mbox;
+	int ret;
+
+	mbox = vf->otx2_dev.mbox;
+	req = otx2_mbox_alloc_msg_ree_config_lf(mbox);
+
+	req->lf = lf;
+	req->pri =  pri ? 1 : 0;
+	req->size = size;
+	req->blkaddr = vf->block_address;
+
+	ret = otx2_mbox_process(mbox);
+	if (ret < 0) {
+		otx2_err("Could not get mailbox response");
+		return ret;
+	}
+	return 0;
+}
+
+int
+otx2_ree_af_reg_read(const struct rte_regexdev *dev, uint64_t reg,
+		     uint64_t *val)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct ree_rd_wr_reg_msg *msg;
+	struct otx2_mbox_dev *mdev;
+	struct otx2_mbox *mbox;
+	int ret, off;
+
+	mbox = vf->otx2_dev.mbox;
+	mdev = &mbox->dev[0];
+	msg = (struct ree_rd_wr_reg_msg *)otx2_mbox_alloc_msg_rsp(mbox, 0,
+						sizeof(*msg), sizeof(*msg));
+	if (msg == NULL) {
+		otx2_err("Could not allocate mailbox message");
+		return -EFAULT;
+	}
+
+	msg->hdr.id = MBOX_MSG_REE_RD_WR_REGISTER;
+	msg->hdr.sig = OTX2_MBOX_REQ_SIG;
+	msg->hdr.pcifunc = vf->otx2_dev.pf_func;
+	msg->is_write = 0;
+	msg->reg_offset = reg;
+	msg->ret_val = val;
+	msg->blkaddr = vf->block_address;
+
+	ret = ree_send_mbox_msg(vf);
+	if (ret < 0)
+		return ret;
+
+	off = mbox->rx_start +
+			RTE_ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
+	msg = (struct ree_rd_wr_reg_msg *) ((uintptr_t)mdev->mbase + off);
+
+	*val = msg->val;
+
+	return 0;
+}
+
+int
+otx2_ree_af_reg_write(const struct rte_regexdev *dev, uint64_t reg,
+		      uint64_t val)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct ree_rd_wr_reg_msg *msg;
+	struct otx2_mbox *mbox;
+
+	mbox = vf->otx2_dev.mbox;
+	msg = (struct ree_rd_wr_reg_msg *)otx2_mbox_alloc_msg_rsp(mbox, 0,
+						sizeof(*msg), sizeof(*msg));
+	if (msg == NULL) {
+		otx2_err("Could not allocate mailbox message");
+		return -EFAULT;
+	}
+
+	msg->hdr.id = MBOX_MSG_REE_RD_WR_REGISTER;
+	msg->hdr.sig = OTX2_MBOX_REQ_SIG;
+	msg->hdr.pcifunc = vf->otx2_dev.pf_func;
+	msg->is_write = 1;
+	msg->reg_offset = reg;
+	msg->val = val;
+	msg->blkaddr = vf->block_address;
+
+	return ree_send_mbox_msg(vf);
+}
+
+int
+otx2_ree_rule_db_get(const struct rte_regexdev *dev, char *rule_db,
+		uint32_t rule_db_len, char *rule_dbi, uint32_t rule_dbi_len)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct ree_rule_db_get_req_msg *req;
+	struct ree_rule_db_get_rsp_msg *rsp;
+	char *rule_db_ptr = (char *)rule_db;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct otx2_mbox *mbox;
+	int ret, last = 0;
+	uint32_t len = 0;
+
+	mbox = vf->otx2_dev.mbox;
+	if (!rule_db) {
+		otx2_err("Couldn't return rule db due to NULL pointer");
+		return -EFAULT;
+	}
+
+	while (!last) {
+		req = (struct ree_rule_db_get_req_msg *)
+			otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
+						sizeof(*rsp));
+		if (!req) {
+			otx2_err("Could not allocate mailbox message");
+			return -EFAULT;
+		}
+
+		req->hdr.id = MBOX_MSG_REE_RULE_DB_GET;
+		req->hdr.sig = OTX2_MBOX_REQ_SIG;
+		req->hdr.pcifunc = vf->otx2_dev.pf_func;
+		req->blkaddr = vf->block_address;
+		req->is_dbi = 0;
+		req->offset = len;
+		ret = otx2_mbox_process_msg(mbox, (void *)&rsp);
+		if (ret)
+			return ret;
+		if (rule_db_len < len + rsp->len) {
+			otx2_err("Rule db size is too small");
+			return -EFAULT;
+		}
+		otx2_mbox_memcpy(rule_db_ptr, rsp->rule_db, rsp->len);
+		len += rsp->len;
+		rule_db_ptr = rule_db_ptr + rsp->len;
+		last = rsp->is_last;
+	}
+
+	if (rule_dbi) {
+		req = (struct ree_rule_db_get_req_msg *)
+			otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
+						sizeof(*rsp));
+		if (!req) {
+			otx2_err("Could not allocate mailbox message");
+			return -EFAULT;
+		}
+
+		req->hdr.id = MBOX_MSG_REE_RULE_DB_GET;
+		req->hdr.sig = OTX2_MBOX_REQ_SIG;
+		req->hdr.pcifunc = vf->otx2_dev.pf_func;
+		req->blkaddr = vf->block_address;
+		req->is_dbi = 1;
+		req->offset = 0;
+
+		ret = otx2_mbox_process_msg(mbox, (void *)&rsp);
+		if (ret)
+			return ret;
+		if (rule_dbi_len < rsp->len) {
+			otx2_err("Rule dbi size is too small");
+			return -EFAULT;
+		}
+		otx2_mbox_memcpy(rule_dbi, rsp->rule_db, rsp->len);
+	}
+	return 0;
+}
+
+int
+otx2_ree_rule_db_len_get(const struct rte_regexdev *dev,
+		uint32_t *rule_db_len,
+		uint32_t *rule_dbi_len)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	struct ree_rule_db_len_rsp_msg *rsp;
+	struct otx2_ree_vf *vf = &data->vf;
+	struct ree_req_msg *req;
+	struct otx2_mbox *mbox;
+	int ret;
+
+	mbox = vf->otx2_dev.mbox;
+	req = (struct ree_req_msg *)
+		otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req), sizeof(*rsp));
+	if (!req) {
+		otx2_err("Could not allocate mailbox message");
+		return -EFAULT;
+	}
+
+	req->hdr.id = MBOX_MSG_REE_RULE_DB_LEN_GET;
+	req->hdr.sig = OTX2_MBOX_REQ_SIG;
+	req->hdr.pcifunc = vf->otx2_dev.pf_func;
+	req->blkaddr = vf->block_address;
+	ret = otx2_mbox_process_msg(mbox, (void *)&rsp);
+	if (ret)
+		return ret;
+	if (rule_db_len != NULL)
+		*rule_db_len = rsp->len;
+	if (rule_dbi_len != NULL)
+		*rule_dbi_len = rsp->inc_len;
+
+	return 0;
+}
+
+static int
+ree_db_msg(const struct rte_regexdev *dev, const char *db, uint32_t db_len,
+		int inc, int dbi)
+{
+	struct otx2_ree_data *data = dev->data->dev_private;
+	uint32_t len_left = db_len, offset = 0;
+	struct ree_rule_db_prog_req_msg *req;
+	struct otx2_ree_vf *vf = &data->vf;
+	const char *rule_db_ptr = db;
+	struct otx2_mbox *mbox;
+	struct msg_rsp *rsp;
+	int ret;
+
+	mbox = vf->otx2_dev.mbox;
+	while (len_left) {
+		req = (struct ree_rule_db_prog_req_msg *)
+			otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
+						sizeof(*rsp));
+		if (!req) {
+			otx2_err("Could not allocate mailbox message");
+			return -EFAULT;
+		}
+		req->hdr.id = MBOX_MSG_REE_RULE_DB_PROG;
+		req->hdr.sig = OTX2_MBOX_REQ_SIG;
+		req->hdr.pcifunc = vf->otx2_dev.pf_func;
+		req->offset = offset;
+		req->total_len = db_len;
+		req->len = REE_RULE_DB_REQ_BLOCK_SIZE;
+		req->is_incremental = inc;
+		req->is_dbi = dbi;
+		req->blkaddr = vf->block_address;
+
+		if (len_left < REE_RULE_DB_REQ_BLOCK_SIZE) {
+			req->is_last = true;
+			req->len = len_left;
+		}
+		otx2_mbox_memcpy(req->rule_db, rule_db_ptr, req->len);
+		ret = otx2_mbox_process_msg(mbox, (void *)&rsp);
+		if (ret) {
+			otx2_err("Programming mailbox processing failed");
+			return ret;
+		}
+		len_left -= req->len;
+		offset += req->len;
+		rule_db_ptr = rule_db_ptr + req->len;
+	}
+	return 0;
+}
+
+int
+otx2_ree_rule_db_prog(const struct rte_regexdev *dev, const char *rule_db,
+		uint32_t rule_db_len, const char *rule_dbi,
+		uint32_t rule_dbi_len)
+{
+	int inc, ret;
+
+	if (rule_db_len == 0) {
+		otx2_err("Couldn't program empty rule db");
+		return -EFAULT;
+	}
+	inc = (rule_dbi_len != 0);
+	if ((rule_db == NULL) || (inc && (rule_dbi == NULL))) {
+		otx2_err("Couldn't program NULL rule db");
+		return -EFAULT;
+	}
+	if (inc) {
+		ret = ree_db_msg(dev, rule_dbi, rule_dbi_len, inc, 1);
+		if (ret)
+			return ret;
+	}
+	return ree_db_msg(dev, rule_db, rule_db_len, inc, 0);
+}
diff --git a/drivers/regex/octeontx2/otx2_regexdev_mbox.h b/drivers/regex/octeontx2/otx2_regexdev_mbox.h
new file mode 100644
index 000000000..953efa672
--- /dev/null
+++ b/drivers/regex/octeontx2/otx2_regexdev_mbox.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _OTX2_REGEXDEV_MBOX_H_
+#define _OTX2_REGEXDEV_MBOX_H_
+
+#include <rte_regexdev.h>
+
+int otx2_ree_available_queues_get(const struct rte_regexdev *dev,
+				  uint16_t *nb_queues);
+
+int otx2_ree_queues_attach(const struct rte_regexdev *dev, uint8_t nb_queues);
+
+int otx2_ree_queues_detach(const struct rte_regexdev *dev);
+
+int otx2_ree_msix_offsets_get(const struct rte_regexdev *dev);
+
+int otx2_ree_config_lf(const struct rte_regexdev *dev, uint8_t lf, uint8_t pri,
+		       uint32_t size);
+
+int otx2_ree_af_reg_read(const struct rte_regexdev *dev, uint64_t reg,
+			 uint64_t *val);
+
+int otx2_ree_af_reg_write(const struct rte_regexdev *dev, uint64_t reg,
+			  uint64_t val);
+
+int otx2_ree_rule_db_get(const struct rte_regexdev *dev, char *rule_db,
+		 uint32_t rule_db_len, char *rule_dbi, uint32_t rule_dbi_len);
+
+int otx2_ree_rule_db_len_get(const struct rte_regexdev *dev,
+			     uint32_t *rule_db_len, uint32_t *rule_dbi_len);
+
+int otx2_ree_rule_db_prog(const struct rte_regexdev *dev, const char *rule_db,
+		uint32_t rule_db_len, const char *rule_dbi,
+		uint32_t rule_dbi_len);
+
+#endif /* _OTX2_REGEXDEV_MBOX_H_ */
diff --git a/drivers/regex/octeontx2/rte_pmd_octeontx2_regex_version.map b/drivers/regex/octeontx2/rte_pmd_octeontx2_regex_version.map
new file mode 100644
index 000000000..4a76d1d52
--- /dev/null
+++ b/drivers/regex/octeontx2/rte_pmd_octeontx2_regex_version.map
@@ -0,0 +1,3 @@
+DPDK_21 {
+	local: *;
+};
-- 
2.28.0


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [dpdk-dev] [PATCH v3 3/3] usertools: add octeontx2 REE device binding
  2020-10-13 10:10 ` [dpdk-dev] [PATCH v3 0/3] Add Marvell OCTEON TX2 regex driver guyk
  2020-10-13 10:10   ` [dpdk-dev] [PATCH v3 1/3] common/octeontx2: add REE definitions and logging support guyk
  2020-10-13 10:10   ` [dpdk-dev] [PATCH v3 2/3] regex/octeontx2: add build infra and device support guyk
@ 2020-10-13 10:10   ` guyk
  2020-10-14  8:42   ` [dpdk-dev] [PATCH v3 0/3] Add Marvell OCTEON TX2 regex driver Thomas Monjalon
  3 siblings, 0 replies; 33+ messages in thread
From: guyk @ 2020-10-13 10:10 UTC (permalink / raw)
  To: orika, jerinj, ndabilpuram, thomas, mdr, nhorman,
	bruce.richardson, anatoly.burakov, john.mcnamara,
	marko.kovacevic
  Cc: dev, smadarf, dovrat, guyk, lironh

From: Guy Kaneti <guyk@marvell.com>

Update the devbind script with new section of regex devices, also
added OCTEONTX2 REE device ID to regex device list

Signed-off-by: Guy Kaneti <guyk@marvell.com>
---
 doc/guides/regexdevs/octeontx2.rst | 11 +++++++++++
 usertools/dpdk-devbind.py          |  8 ++++++++
 2 files changed, 19 insertions(+)

diff --git a/doc/guides/regexdevs/octeontx2.rst b/doc/guides/regexdevs/octeontx2.rst
index 87659b661..859780da1 100644
--- a/doc/guides/regexdevs/octeontx2.rst
+++ b/doc/guides/regexdevs/octeontx2.rst
@@ -24,6 +24,17 @@ Prerequisites and Compilation procedure
 
    See :doc:`../platform/octeontx2` for setup information.
 
+Device Setup
+------------
+
+The OCTEON TX2 REE devices will need to be bound to a user-space IO driver
+for use. The script ``dpdk-devbind.py`` script included with DPDK can be
+used to view the state of the devices and to bind them to a suitable
+DPDK-supported kernel driver. When querying the status of the devices,
+they will appear under the category of "REGEX devices", i.e. the command
+``dpdk-devbind.py --status-dev regex`` can be used to see the state of
+those devices alone.
+
 Debugging Options
 -----------------
 
diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py
index 1d1113a08..99112b7ab 100755
--- a/usertools/dpdk-devbind.py
+++ b/usertools/dpdk-devbind.py
@@ -41,6 +41,8 @@
               'SVendor': None, 'SDevice': None}
 octeontx2_dma = {'Class': '08', 'Vendor': '177d', 'Device': 'a081',
               'SVendor': None, 'SDevice': None}
+octeontx2_ree = {'Class': '08', 'Vendor': '177d', 'Device': 'a0f4',
+              'SVendor': None, 'SDevice': None}
 
 intel_ioat_bdw = {'Class': '08', 'Vendor': '8086', 'Device': '6f20,6f21,6f22,6f23,6f24,6f25,6f26,6f27,6f2e,6f2f',
               'SVendor': None, 'SDevice': None}
@@ -61,6 +63,7 @@
 eventdev_devices = [cavium_sso, cavium_tim, octeontx2_sso]
 mempool_devices = [cavium_fpa, octeontx2_npa]
 compress_devices = [cavium_zip]
+regex_devices = [octeontx2_ree]
 misc_devices = [intel_ioat_bdw, intel_ioat_skx, intel_ioat_icx, intel_idxd_spr,
                 intel_ntb_skx, intel_ntb_icx,
                 octeontx2_dma]
@@ -650,6 +653,9 @@ def show_status():
     if status_dev == "misc" or status_dev == "all":
         show_device_status(misc_devices, "Misc (rawdev)")
 
+    if status_dev == "regex" or status_dev == "all":
+        show_device_status(regex_devices, "Regex")
+
 
 def pci_glob(arg):
     '''Returns a list containing either:
@@ -742,6 +748,7 @@ def do_arg_actions():
             get_device_details(eventdev_devices)
             get_device_details(mempool_devices)
             get_device_details(compress_devices)
+            get_device_details(regex_devices)
             get_device_details(misc_devices)
         show_status()
 
@@ -763,6 +770,7 @@ def main():
     get_device_details(eventdev_devices)
     get_device_details(mempool_devices)
     get_device_details(compress_devices)
+    get_device_details(regex_devices)
     get_device_details(misc_devices)
     do_arg_actions()
 
-- 
2.28.0


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [dpdk-dev] [PATCH v3 1/3] common/octeontx2: add REE definitions and logging support
  2020-10-13 10:10   ` [dpdk-dev] [PATCH v3 1/3] common/octeontx2: add REE definitions and logging support guyk
@ 2020-10-14  8:18     ` Thomas Monjalon
  0 siblings, 0 replies; 33+ messages in thread
From: Thomas Monjalon @ 2020-10-14  8:18 UTC (permalink / raw)
  To: guyk
  Cc: orika, jerinj, ndabilpuram, mdr, nhorman, bruce.richardson,
	anatoly.burakov, john.mcnamara, marko.kovacevic, dev, smadarf,
	dovrat, lironh

13/10/2020 12:10, guyk@marvell.com:
> From: Guy Kaneti <guyk@marvell.com>
> 
> Add REE mbox msg definitions, RVU and REE HW definitions
> 
> Signed-off-by: Guy Kaneti <guyk@marvell.com>
> ---
> --- a/drivers/common/octeontx2/rte_common_octeontx2_version.map
> +++ b/drivers/common/octeontx2/rte_common_octeontx2_version.map
> @@ -38,6 +38,7 @@ INTERNAL {
>  	otx2_sso_pf_func_get;
>  	otx2_sso_pf_func_set;
>  	otx2_unregister_irq;
> +	otx2_logtype_ree;

I will sort this symbol in the list.





^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [dpdk-dev] [PATCH v3 2/3] regex/octeontx2: add build infra and device support
  2020-10-13 10:10   ` [dpdk-dev] [PATCH v3 2/3] regex/octeontx2: add build infra and device support guyk
@ 2020-10-14  8:26     ` Thomas Monjalon
  0 siblings, 0 replies; 33+ messages in thread
From: Thomas Monjalon @ 2020-10-14  8:26 UTC (permalink / raw)
  To: guyk
  Cc: orika, jerinj, ndabilpuram, mdr, nhorman, bruce.richardson,
	anatoly.burakov, john.mcnamara, marko.kovacevic, dev, smadarf,
	dovrat, lironh

13/10/2020 12:10, guyk@marvell.com:
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1112,6 +1112,10 @@ F: doc/guides/compressdevs/features/zlib.ini
>  RegEx Drivers
>  -------------
>  
> +Marvell OCTEON TX2 regex
> +M: Guy Kaneti <guyk@marvell.com>
> +F: drivers/regex/octeontx2/
> +

Will add doc file here.




^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [dpdk-dev] [PATCH v3 0/3] Add Marvell OCTEON TX2 regex driver
  2020-10-13 10:10 ` [dpdk-dev] [PATCH v3 0/3] Add Marvell OCTEON TX2 regex driver guyk
                     ` (2 preceding siblings ...)
  2020-10-13 10:10   ` [dpdk-dev] [PATCH v3 3/3] usertools: add octeontx2 REE device binding guyk
@ 2020-10-14  8:42   ` Thomas Monjalon
  3 siblings, 0 replies; 33+ messages in thread
From: Thomas Monjalon @ 2020-10-14  8:42 UTC (permalink / raw)
  To: guyk
  Cc: orika, jerinj, ndabilpuram, mdr, nhorman, bruce.richardson,
	anatoly.burakov, john.mcnamara, marko.kovacevic, dev, smadarf,
	dovrat, lironh

13/10/2020 12:10, guyk@marvell.com:
> From: Guy Kaneti <guyk@marvell.com>
> 
> This patchset adds support for OCTEON TX2 regex driver as DPDK regexdev.
> The driver implements the API defined in the regexdev lib.
> 
> v3:
> * Fix ML comments.
>  
> v2:
> * Rebase.
> * Remove config/common_base from patch
> * change rte_cio_wmb to rte_io_wmb
> 
> Guy Kaneti (3):
>   common/octeontx2: add REE definitions and logging support
>   regex/octeontx2: add build infra and device support
>   usertools: add octeontx2 REE device binding

Applied with last minor changes described in this thread, thanks.



^ permalink raw reply	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2020-10-14  8:42 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-01 12:24 [dpdk-dev] [PATCH 0/4] Add Marvell OCTEON TX2 regex driver guyk
2020-09-01 12:24 ` [dpdk-dev] [PATCH 1/4] common/octeontx2: add REE definitions and logging support guyk
2020-10-11  7:35   ` Liron Himi
2020-09-01 12:24 ` [dpdk-dev] [PATCH 2/4] regex/octeontx2: add build infra and device support guyk
2020-10-11  7:36   ` Liron Himi
2020-09-01 12:24 ` [dpdk-dev] [PATCH 3/4] usertools: add octeontx2 REE device binding guyk
2020-10-11  7:36   ` Liron Himi
2020-09-01 12:24 ` [dpdk-dev] [PATCH 4/4] doc: add Marvell OCTEON TX2 regex guide guyk
2020-10-11  7:36   ` Liron Himi
2020-10-08  6:31 ` [dpdk-dev] [PATCH 0/4] Add Marvell OCTEON TX2 regex driver Guy Kaneti
2020-10-11 21:23   ` Thomas Monjalon
2020-10-12 11:34     ` [dpdk-dev] [EXT] " Guy Kaneti
2020-10-12 11:31 ` [dpdk-dev] [PATCH v2 " guyk
2020-10-12 11:31   ` [dpdk-dev] [PATCH v2 1/4] common/octeontx2: add REE definitions and logging support guyk
2020-10-12 11:31   ` [dpdk-dev] [PATCH v2 2/4] regex/octeontx2: add build infra and device support guyk
2020-10-12 14:33     ` Thomas Monjalon
2020-10-12 17:06       ` [dpdk-dev] [EXT] " Guy Kaneti
2020-10-12 17:10         ` Thomas Monjalon
2020-10-12 17:13           ` Guy Kaneti
2020-10-12 17:19             ` Thomas Monjalon
2020-10-12 11:31   ` [dpdk-dev] [PATCH v2 3/4] usertools: add octeontx2 REE device binding guyk
2020-10-12 14:35     ` Thomas Monjalon
2020-10-12 11:31   ` [dpdk-dev] [PATCH v2 4/4] doc: add Marvell OCTEON TX2 regex guide guyk
2020-10-12 14:38     ` Thomas Monjalon
2020-10-12 17:09       ` [dpdk-dev] [EXT] " Guy Kaneti
2020-10-12 17:12         ` Thomas Monjalon
2020-10-13 10:10 ` [dpdk-dev] [PATCH v3 0/3] Add Marvell OCTEON TX2 regex driver guyk
2020-10-13 10:10   ` [dpdk-dev] [PATCH v3 1/3] common/octeontx2: add REE definitions and logging support guyk
2020-10-14  8:18     ` Thomas Monjalon
2020-10-13 10:10   ` [dpdk-dev] [PATCH v3 2/3] regex/octeontx2: add build infra and device support guyk
2020-10-14  8:26     ` Thomas Monjalon
2020-10-13 10:10   ` [dpdk-dev] [PATCH v3 3/3] usertools: add octeontx2 REE device binding guyk
2020-10-14  8:42   ` [dpdk-dev] [PATCH v3 0/3] Add Marvell OCTEON TX2 regex driver Thomas Monjalon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).