[v2,04/11] net/octeontx_ep: Added basic device setup.

Message ID 20210118093602.5449-4-pnalla@marvell.com (mailing list archive)
State Changes Requested, archived
Delegated to: Ferruh Yigit
Headers
Series [v2,01/11] net/octeontx_ep: add build and doc infrastructure |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Pradeep Nalla Jan. 18, 2021, 9:35 a.m. UTC
  Functions to setup device, basic IQ and OQ registers are added.

Signed-off-by: Nalla Pradeep <pnalla@marvell.com>
---
 drivers/net/octeontx_ep/meson.build     |   2 +
 drivers/net/octeontx_ep/otx2_ep_vf.c    | 138 +++++++++++++++++++++
 drivers/net/octeontx_ep/otx2_ep_vf.h    |  11 ++
 drivers/net/octeontx_ep/otx_ep_common.h |  92 ++++++++++++++
 drivers/net/octeontx_ep/otx_ep_ethdev.c |  10 ++
 drivers/net/octeontx_ep/otx_ep_vf.c     | 154 ++++++++++++++++++++++++
 drivers/net/octeontx_ep/otx_ep_vf.h     |  33 +++++
 7 files changed, 440 insertions(+)
 create mode 100644 drivers/net/octeontx_ep/otx2_ep_vf.c
 create mode 100644 drivers/net/octeontx_ep/otx2_ep_vf.h
 create mode 100644 drivers/net/octeontx_ep/otx_ep_vf.c
  

Comments

Jerin Jacob Jan. 19, 2021, 12:09 p.m. UTC | #1
On Mon, Jan 18, 2021 at 3:07 PM Nalla Pradeep <pnalla@marvell.com> wrote:
>
> Functions to setup device, basic IQ and OQ registers are added.
>
> Signed-off-by: Nalla Pradeep <pnalla@marvell.com>
> ---
>  drivers/net/octeontx_ep/meson.build     |   2 +
>  drivers/net/octeontx_ep/otx2_ep_vf.c    | 138 +++++++++++++++++++++
>  drivers/net/octeontx_ep/otx2_ep_vf.h    |  11 ++
>  drivers/net/octeontx_ep/otx_ep_common.h |  92 ++++++++++++++
>  drivers/net/octeontx_ep/otx_ep_ethdev.c |  10 ++
>  drivers/net/octeontx_ep/otx_ep_vf.c     | 154 ++++++++++++++++++++++++
>  drivers/net/octeontx_ep/otx_ep_vf.h     |  33 +++++
>  7 files changed, 440 insertions(+)
>  create mode 100644 drivers/net/octeontx_ep/otx2_ep_vf.c
>  create mode 100644 drivers/net/octeontx_ep/otx2_ep_vf.h
>  create mode 100644 drivers/net/octeontx_ep/otx_ep_vf.c
>
> diff --git a/drivers/net/octeontx_ep/meson.build b/drivers/net/octeontx_ep/meson.build
> index 06663de4e2..7c43c077cf 100644
> --- a/drivers/net/octeontx_ep/meson.build
> +++ b/drivers/net/octeontx_ep/meson.build
> @@ -4,6 +4,8 @@
>
>  sources = files(
>                 'otx_ep_ethdev.c',
> +               'otx_ep_vf.c',
> +               'otx2_ep_vf.c',
>                 )
>
>  extra_flags = []
> diff --git a/drivers/net/octeontx_ep/otx2_ep_vf.c b/drivers/net/octeontx_ep/otx2_ep_vf.c
> new file mode 100644
> index 0000000000..e03d39f7dc
> --- /dev/null
> +++ b/drivers/net/octeontx_ep/otx2_ep_vf.c
> @@ -0,0 +1,138 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(C) 2020 Marvell.
> + */
> +
> +#include "otx2_common.h"
> +#include "otx_ep_common.h"
> +#include "otx2_ep_vf.h"
> +
> +static void
> +otx2_vf_setup_global_iq_reg(struct otx_ep_device *otx_ep, int q_no)
> +{
> +       volatile uint64_t reg_val = 0ull;
> +
> +       /* Select ES, RO, NS, RDSIZE,DPTR Format#0 for IQs
> +        * IS_64B is by default enabled.
> +        */
> +       reg_val = otx2_read64(otx_ep->hw_addr + SDP_VF_R_IN_CONTROL(q_no));
> +
> +       reg_val |= SDP_VF_R_IN_CTL_RDSIZE;
> +       reg_val |= SDP_VF_R_IN_CTL_IS_64B;
> +       reg_val |= SDP_VF_R_IN_CTL_ESR;
> +
> +       otx2_write64(reg_val, otx_ep->hw_addr + SDP_VF_R_IN_CONTROL(q_no));
> +}
> +
> +static void
> +otx2_vf_setup_global_oq_reg(struct otx_ep_device *otx_ep, int q_no)
> +{
> +       volatile uint64_t reg_val = 0ull;
> +
> +       reg_val = otx2_read64(otx_ep->hw_addr + SDP_VF_R_OUT_CONTROL(q_no));
> +
> +#if defined(BUFPTR_ONLY_MODE)

Use devargs instead of compile-time flags.

> +       reg_val &= ~(SDP_VF_R_OUT_CTL_IMODE);
> +#else
> +       reg_val |= (SDP_VF_R_OUT_CTL_IMODE);
> +#endif
  
Ferruh Yigit Jan. 26, 2021, 3:29 p.m. UTC | #2
On 1/18/2021 9:35 AM, Nalla Pradeep wrote:
> Functions to setup device, basic IQ and OQ registers are added.
> 

As the patch title can you please start with lowercase after module, and do not 
use the final '.',
if you run './devtools/check-git-log.sh' script it will highlight these kind of 
issues, can you please be sure all are addressed in next version.

Also it would helpful to clarify all abbreviations used in the commit log, like 
IQ and OQ used above, it is helpul if you can write the long version for the 
fist time they are used like, Output Queue (OQ).

> Signed-off-by: Nalla Pradeep <pnalla@marvell.com>

<...>

> +static void
> +otx2_vf_setup_global_oq_reg(struct otx_ep_device *otx_ep, int q_no)
> +{
> +	volatile uint64_t reg_val = 0ull;
> +
> +	reg_val = otx2_read64(otx_ep->hw_addr + SDP_VF_R_OUT_CONTROL(q_no));
> +
> +#if defined(BUFPTR_ONLY_MODE)
> +	reg_val &= ~(SDP_VF_R_OUT_CTL_IMODE);
> +#else
> +	reg_val |= (SDP_VF_R_OUT_CTL_IMODE);
> +#endif

Where this macro, BUFPTR_ONLY_MODE, is defined, using macros like this can lead 
to the dead code, can you please either remove this or rename with RTE_ prefix 
and document it?

<...>

> +int
> +otx2_ep_vf_setup_device(struct otx_ep_device *otx_ep)
> +{
> +	uint64_t reg_val = 0ull;
> +
> +	/* If application doesn't provide its conf, use driver default conf */
> +	if (otx_ep->conf == NULL) {
> +		otx_ep->conf = otx2_ep_get_defconf(otx_ep);
> +		if (otx_ep->conf == NULL) {
> +			otx2_err("SDP VF default config not found");
> +			return -ENOMEM;


Similar comment as previous, please prefer ENOMEM error type when there is a 
problem with memory.
There are multiple occurance of returning ENOMEM.

<...>

> @@ -21,10 +22,12 @@ otx_ep_chip_specific_setup(struct otx_ep_device *otx_epvf)
>   	switch (dev_id) {
>   	case PCI_DEVID_OCTEONTX_EP_VF:
>   		otx_epvf->chip_id = dev_id;
> +		ret = otx_ep_vf_setup_device(otx_epvf);
>   		break;
>   	case PCI_DEVID_OCTEONTX2_EP_NET_VF:
>   	case PCI_DEVID_CN98XX_EP_NET_VF:
>   		otx_epvf->chip_id = dev_id;
> +		ret = otx2_ep_vf_setup_device(otx_epvf);
>   		break;
>   	default:
>   		otx_ep_err("Unsupported device\n");
> @@ -46,6 +49,13 @@ otx_epdev_init(struct otx_ep_device *otx_epvf)
>   		goto setup_fail;
>   	}
>   
> +	if (otx_epvf->fn_list.setup_device_regs(otx_epvf)) {
> +		otx_ep_err("Failed to configure device registers\n");
> +		goto setup_fail;
> +	}

So both otx & otx2 devices are supported via function pointers, out of curiosity 
how different the implementations are, since both are implementing same spec as 
far as I understand.
  

Patch

diff --git a/drivers/net/octeontx_ep/meson.build b/drivers/net/octeontx_ep/meson.build
index 06663de4e2..7c43c077cf 100644
--- a/drivers/net/octeontx_ep/meson.build
+++ b/drivers/net/octeontx_ep/meson.build
@@ -4,6 +4,8 @@ 
 
 sources = files(
                'otx_ep_ethdev.c',
+               'otx_ep_vf.c',
+               'otx2_ep_vf.c',
                )
 
 extra_flags = []
diff --git a/drivers/net/octeontx_ep/otx2_ep_vf.c b/drivers/net/octeontx_ep/otx2_ep_vf.c
new file mode 100644
index 0000000000..e03d39f7dc
--- /dev/null
+++ b/drivers/net/octeontx_ep/otx2_ep_vf.c
@@ -0,0 +1,138 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell.
+ */
+
+#include "otx2_common.h"
+#include "otx_ep_common.h"
+#include "otx2_ep_vf.h"
+
+static void
+otx2_vf_setup_global_iq_reg(struct otx_ep_device *otx_ep, int q_no)
+{
+	volatile uint64_t reg_val = 0ull;
+
+	/* Select ES, RO, NS, RDSIZE,DPTR Format#0 for IQs
+	 * IS_64B is by default enabled.
+	 */
+	reg_val = otx2_read64(otx_ep->hw_addr + SDP_VF_R_IN_CONTROL(q_no));
+
+	reg_val |= SDP_VF_R_IN_CTL_RDSIZE;
+	reg_val |= SDP_VF_R_IN_CTL_IS_64B;
+	reg_val |= SDP_VF_R_IN_CTL_ESR;
+
+	otx2_write64(reg_val, otx_ep->hw_addr + SDP_VF_R_IN_CONTROL(q_no));
+}
+
+static void
+otx2_vf_setup_global_oq_reg(struct otx_ep_device *otx_ep, int q_no)
+{
+	volatile uint64_t reg_val = 0ull;
+
+	reg_val = otx2_read64(otx_ep->hw_addr + SDP_VF_R_OUT_CONTROL(q_no));
+
+#if defined(BUFPTR_ONLY_MODE)
+	reg_val &= ~(SDP_VF_R_OUT_CTL_IMODE);
+#else
+	reg_val |= (SDP_VF_R_OUT_CTL_IMODE);
+#endif
+
+	reg_val &= ~(SDP_VF_R_OUT_CTL_ROR_P);
+	reg_val &= ~(SDP_VF_R_OUT_CTL_NSR_P);
+	reg_val &= ~(SDP_VF_R_OUT_CTL_ROR_I);
+	reg_val &= ~(SDP_VF_R_OUT_CTL_NSR_I);
+	reg_val &= ~(SDP_VF_R_OUT_CTL_ES_I);
+	reg_val &= ~(SDP_VF_R_OUT_CTL_ROR_D);
+	reg_val &= ~(SDP_VF_R_OUT_CTL_NSR_D);
+	reg_val &= ~(SDP_VF_R_OUT_CTL_ES_D);
+
+	/* INFO/DATA ptr swap is required  */
+	reg_val |= (SDP_VF_R_OUT_CTL_ES_P);
+
+	otx2_write64(reg_val, otx_ep->hw_addr + SDP_VF_R_OUT_CONTROL(q_no));
+}
+
+static void
+otx2_vf_setup_global_input_regs(struct otx_ep_device *otx_ep)
+{
+	uint64_t q_no = 0ull;
+
+	for (q_no = 0; q_no < (otx_ep->sriov_info.rings_per_vf); q_no++)
+		otx2_vf_setup_global_iq_reg(otx_ep, q_no);
+}
+
+static void
+otx2_vf_setup_global_output_regs(struct otx_ep_device *otx_ep)
+{
+	uint32_t q_no;
+
+	for (q_no = 0; q_no < (otx_ep->sriov_info.rings_per_vf); q_no++)
+		otx2_vf_setup_global_oq_reg(otx_ep, q_no);
+}
+
+static int
+otx2_vf_setup_device_regs(struct otx_ep_device *otx_ep)
+{
+	otx2_vf_setup_global_input_regs(otx_ep);
+	otx2_vf_setup_global_output_regs(otx_ep);
+
+	return 0;
+}
+
+static const struct otx_ep_config default_otx2_ep_conf = {
+	/* IQ attributes */
+	.iq                        = {
+		.max_iqs           = OTX_EP_CFG_IO_QUEUES,
+		.instr_type        = OTX_EP_64BYTE_INSTR,
+		.pending_list_size = (OTX_EP_MAX_IQ_DESCRIPTORS *
+				      OTX_EP_CFG_IO_QUEUES),
+	},
+
+	/* OQ attributes */
+	.oq                        = {
+		.max_oqs           = OTX_EP_CFG_IO_QUEUES,
+		.info_ptr          = OTX_EP_OQ_INFOPTR_MODE,
+		.refill_threshold  = OTX_EP_OQ_REFIL_THRESHOLD,
+	},
+
+	.num_iqdef_descs           = OTX_EP_MAX_IQ_DESCRIPTORS,
+	.num_oqdef_descs           = OTX_EP_MAX_OQ_DESCRIPTORS,
+	.oqdef_buf_size            = OTX_EP_OQ_BUF_SIZE,
+};
+
+static const struct otx_ep_config*
+otx2_ep_get_defconf(struct otx_ep_device *otx_ep_dev __rte_unused)
+{
+	const struct otx_ep_config *default_conf = NULL;
+
+	default_conf = &default_otx2_ep_conf;
+
+	return default_conf;
+}
+
+int
+otx2_ep_vf_setup_device(struct otx_ep_device *otx_ep)
+{
+	uint64_t reg_val = 0ull;
+
+	/* If application doesn't provide its conf, use driver default conf */
+	if (otx_ep->conf == NULL) {
+		otx_ep->conf = otx2_ep_get_defconf(otx_ep);
+		if (otx_ep->conf == NULL) {
+			otx2_err("SDP VF default config not found");
+			return -ENOMEM;
+		}
+		otx2_info("Default config is used");
+	}
+
+	/* Get IOQs (RPVF] count */
+	reg_val = otx2_read64(otx_ep->hw_addr + SDP_VF_R_IN_CONTROL(0));
+
+	otx_ep->sriov_info.rings_per_vf = ((reg_val >> SDP_VF_R_IN_CTL_RPVF_POS)
+					  & SDP_VF_R_IN_CTL_RPVF_MASK);
+
+	otx2_info("SDP RPVF: %d", otx_ep->sriov_info.rings_per_vf);
+
+	otx_ep->fn_list.setup_device_regs   = otx2_vf_setup_device_regs;
+
+	return 0;
+}
diff --git a/drivers/net/octeontx_ep/otx2_ep_vf.h b/drivers/net/octeontx_ep/otx2_ep_vf.h
new file mode 100644
index 0000000000..0d7c6e8e17
--- /dev/null
+++ b/drivers/net/octeontx_ep/otx2_ep_vf.h
@@ -0,0 +1,11 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell.
+ */
+#ifndef _OTX2_EP_VF_H_
+#define _OTX2_EP_VF_H_
+
+int
+otx2_ep_vf_setup_device(struct otx_ep_device *sdpvf);
+
+#endif /*_OTX2_EP_VF_H_ */
+
diff --git a/drivers/net/octeontx_ep/otx_ep_common.h b/drivers/net/octeontx_ep/otx_ep_common.h
index 1c31ea8de2..4ec7638219 100644
--- a/drivers/net/octeontx_ep/otx_ep_common.h
+++ b/drivers/net/octeontx_ep/otx_ep_common.h
@@ -4,6 +4,15 @@ 
 #ifndef _OTX_EP_COMMON_H_
 #define _OTX_EP_COMMON_H_
 
+#define OTX_EP_MAX_RINGS_PER_VF        (8)
+#define OTX_EP_CFG_IO_QUEUES        OTX_EP_MAX_RINGS_PER_VF
+#define OTX_EP_64BYTE_INSTR         (64)
+#define OTX_EP_MAX_IQ_DESCRIPTORS   (8192)
+#define OTX_EP_MAX_OQ_DESCRIPTORS   (8192)
+#define OTX_EP_OQ_BUF_SIZE          (2048)
+
+#define OTX_EP_OQ_INFOPTR_MODE      (0)
+#define OTX_EP_OQ_REFIL_THRESHOLD   (16)
 #define otx_ep_printf(level, fmt, args...)		\
 	rte_log(RTE_LOG_ ## level, RTE_LOGTYPE_PMD,		\
 		 fmt, ##args)
@@ -17,15 +26,98 @@ 
 #define otx_ep_dbg(fmt, args...)				\
 	otx_ep_printf(DEBUG, fmt, ##args)
 
+#define otx_ep_write64(value, base_addr, reg_off) \
+	{\
+	typeof(value) val = (value); \
+	typeof(reg_off) off = (reg_off); \
+	otx_ep_dbg("octeon_write_csr64: reg: 0x%08lx val: 0x%016llx\n", \
+		   (unsigned long)off, (unsigned long long)val); \
+	rte_write64(val, ((base_addr) + off)); \
+	}
+
+struct otx_ep_device;
+
+/* Structure to define the configuration attributes for each Input queue. */
+struct otx_ep_iq_config {
+	/* Max number of IQs available */
+	uint16_t max_iqs;
+
+	/* Command size - 32 or 64 bytes */
+	uint16_t instr_type;
+
+	/* Pending list size, usually set to the sum of the size of all IQs */
+	uint32_t pending_list_size;
+};
+
+/* Structure to define the configuration attributes for each Output queue. */
+struct otx_ep_oq_config {
+	/* Max number of OQs available */
+	uint16_t max_oqs;
+
+	/* If set, the Output queue uses info-pointer mode. (Default: 1 ) */
+	uint16_t info_ptr;
+
+	/** The number of buffers that were consumed during packet processing by
+	 *  the driver on this Output queue before the driver attempts to
+	 *  replenish the descriptor ring with new buffers.
+	 */
+	uint32_t refill_threshold;
+};
+
+/* Structure to define the configuration. */
+struct otx_ep_config {
+	/* Input Queue attributes. */
+	struct otx_ep_iq_config iq;
+
+	/* Output Queue attributes. */
+	struct otx_ep_oq_config oq;
+
+	/* Num of desc for IQ rings */
+	uint32_t num_iqdef_descs;
+
+	/* Num of desc for OQ rings */
+	uint32_t num_oqdef_descs;
+
+	/* OQ buffer size */
+	uint32_t oqdef_buf_size;
+};
+
+/* SRIOV information */
+struct otx_ep_sriov_info {
+	/* Number of rings assigned to VF */
+	uint32_t rings_per_vf;
+
+	/* Number of VF devices enabled */
+	uint32_t num_vfs;
+};
+
+/* Required functions for each VF device */
+struct otx_ep_fn_list {
+	int (*setup_device_regs)(struct otx_ep_device *otx_ep);
+};
+
 /* OTX_EP EP VF device data structure */
 struct otx_ep_device {
 	/* PCI device pointer */
 	struct rte_pci_device *pdev;
+
 	uint16_t chip_id;
+
 	struct rte_eth_dev *eth_dev;
+
 	int port_id;
+
 	/* Memory mapped h/w address */
 	uint8_t *hw_addr;
+
+	struct otx_ep_fn_list fn_list;
+
+	/* SR-IOV info */
+	struct otx_ep_sriov_info sriov_info;
+
+	/* Device configuration */
+	const struct otx_ep_config *conf;
+
 	int port_configured;
 };
 #endif  /* _OTX_EP_COMMON_H_ */
diff --git a/drivers/net/octeontx_ep/otx_ep_ethdev.c b/drivers/net/octeontx_ep/otx_ep_ethdev.c
index a1afdfab67..53e79d70ae 100644
--- a/drivers/net/octeontx_ep/otx_ep_ethdev.c
+++ b/drivers/net/octeontx_ep/otx_ep_ethdev.c
@@ -9,6 +9,7 @@ 
 #include "otx2_common.h"
 #include "otx_ep_common.h"
 #include "otx_ep_vf.h"
+#include "otx2_ep_vf.h"
 
 #define OTX_EP_DEV(_eth_dev)            ((_eth_dev)->data->dev_private)
 static int
@@ -21,10 +22,12 @@  otx_ep_chip_specific_setup(struct otx_ep_device *otx_epvf)
 	switch (dev_id) {
 	case PCI_DEVID_OCTEONTX_EP_VF:
 		otx_epvf->chip_id = dev_id;
+		ret = otx_ep_vf_setup_device(otx_epvf);
 		break;
 	case PCI_DEVID_OCTEONTX2_EP_NET_VF:
 	case PCI_DEVID_CN98XX_EP_NET_VF:
 		otx_epvf->chip_id = dev_id;
+		ret = otx2_ep_vf_setup_device(otx_epvf);
 		break;
 	default:
 		otx_ep_err("Unsupported device\n");
@@ -46,6 +49,13 @@  otx_epdev_init(struct otx_ep_device *otx_epvf)
 		goto setup_fail;
 	}
 
+	if (otx_epvf->fn_list.setup_device_regs(otx_epvf)) {
+		otx_ep_err("Failed to configure device registers\n");
+		goto setup_fail;
+	}
+
+	otx_ep_info("OTX_EP Device is Ready\n");
+
 	return 0;
 
 setup_fail:
diff --git a/drivers/net/octeontx_ep/otx_ep_vf.c b/drivers/net/octeontx_ep/otx_ep_vf.c
new file mode 100644
index 0000000000..7fad313982
--- /dev/null
+++ b/drivers/net/octeontx_ep/otx_ep_vf.c
@@ -0,0 +1,154 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell.
+ */
+
+#include <rte_common.h>
+#include <rte_cycles.h>
+#include <rte_ethdev_driver.h>
+#include <rte_ethdev_pci.h>
+#include <rte_io.h>
+
+#include "otx_ep_common.h"
+#include "otx_ep_vf.h"
+
+
+static void
+otx_ep_setup_global_iq_reg(struct otx_ep_device *otx_ep, int q_no)
+{
+	volatile uint64_t reg_val = 0ull;
+
+	/* Select ES, RO, NS, RDSIZE,DPTR Format#0 for IQs
+	 * IS_64B is by default enabled.
+	 */
+	reg_val = rte_read64(otx_ep->hw_addr + OTX_EP_R_IN_CONTROL(q_no));
+
+	reg_val |= OTX_EP_R_IN_CTL_RDSIZE;
+	reg_val |= OTX_EP_R_IN_CTL_IS_64B;
+	reg_val |= OTX_EP_R_IN_CTL_ESR;
+
+	otx_ep_write64(reg_val, otx_ep->hw_addr, OTX_EP_R_IN_CONTROL(q_no));
+	reg_val = rte_read64(otx_ep->hw_addr + OTX_EP_R_IN_CONTROL(q_no));
+
+	if (!(reg_val & OTX_EP_R_IN_CTL_IDLE)) {
+		do {
+			reg_val = rte_read64(otx_ep->hw_addr +
+					      OTX_EP_R_IN_CONTROL(q_no));
+		} while (!(reg_val & OTX_EP_R_IN_CTL_IDLE));
+	}
+}
+
+static void
+otx_ep_setup_global_oq_reg(struct otx_ep_device *otx_ep, int q_no)
+{
+	volatile uint64_t reg_val = 0ull;
+
+	reg_val = rte_read64(otx_ep->hw_addr + OTX_EP_R_OUT_CONTROL(q_no));
+
+#if defined(BUFPTR_ONLY_MODE)
+	reg_val &= ~(OTX_EP_R_OUT_CTL_IMODE);
+#else
+	reg_val |= (OTX_EP_R_OUT_CTL_IMODE);
+#endif
+	reg_val &= ~(OTX_EP_R_OUT_CTL_ROR_P);
+	reg_val &= ~(OTX_EP_R_OUT_CTL_NSR_P);
+	reg_val &= ~(OTX_EP_R_OUT_CTL_ROR_I);
+	reg_val &= ~(OTX_EP_R_OUT_CTL_NSR_I);
+	reg_val &= ~(OTX_EP_R_OUT_CTL_ES_I);
+	reg_val &= ~(OTX_EP_R_OUT_CTL_ROR_D);
+	reg_val &= ~(OTX_EP_R_OUT_CTL_NSR_D);
+	reg_val &= ~(OTX_EP_R_OUT_CTL_ES_D);
+
+	/* INFO/DATA ptr swap is required  */
+	reg_val |= (OTX_EP_R_OUT_CTL_ES_P);
+
+	otx_ep_write64(reg_val, otx_ep->hw_addr, OTX_EP_R_OUT_CONTROL(q_no));
+}
+
+static void
+otx_ep_setup_global_input_regs(struct otx_ep_device *otx_ep)
+{
+	uint64_t q_no = 0ull;
+
+	for (q_no = 0; q_no < (otx_ep->sriov_info.rings_per_vf); q_no++)
+		otx_ep_setup_global_iq_reg(otx_ep, q_no);
+}
+
+static void
+otx_ep_setup_global_output_regs(struct otx_ep_device *otx_ep)
+{
+	uint32_t q_no;
+
+	for (q_no = 0; q_no < (otx_ep->sriov_info.rings_per_vf); q_no++)
+		otx_ep_setup_global_oq_reg(otx_ep, q_no);
+}
+
+static int
+otx_ep_setup_device_regs(struct otx_ep_device *otx_ep)
+{
+	otx_ep_setup_global_input_regs(otx_ep);
+	otx_ep_setup_global_output_regs(otx_ep);
+
+	return 0;
+}
+
+/* OTX_EP default configuration */
+static const struct otx_ep_config default_otx_ep_conf = {
+	/* IQ attributes */
+	.iq                        = {
+		.max_iqs           = OTX_EP_CFG_IO_QUEUES,
+		.instr_type        = OTX_EP_64BYTE_INSTR,
+		.pending_list_size = (OTX_EP_MAX_IQ_DESCRIPTORS *
+				      OTX_EP_CFG_IO_QUEUES),
+	},
+
+	/* OQ attributes */
+	.oq                        = {
+		.max_oqs           = OTX_EP_CFG_IO_QUEUES,
+		.info_ptr          = OTX_EP_OQ_INFOPTR_MODE,
+		.refill_threshold  = OTX_EP_OQ_REFIL_THRESHOLD,
+	},
+
+	.num_iqdef_descs           = OTX_EP_MAX_IQ_DESCRIPTORS,
+	.num_oqdef_descs           = OTX_EP_MAX_OQ_DESCRIPTORS,
+	.oqdef_buf_size            = OTX_EP_OQ_BUF_SIZE,
+
+};
+
+
+static const struct otx_ep_config*
+otx_ep_get_defconf(struct otx_ep_device *otx_ep_dev __rte_unused)
+{
+	const struct otx_ep_config *default_conf = NULL;
+
+	default_conf = &default_otx_ep_conf;
+
+	return default_conf;
+}
+
+int
+otx_ep_vf_setup_device(struct otx_ep_device *otx_ep)
+{
+	uint64_t reg_val = 0ull;
+
+	/* If application doesn't provide its conf, use driver default conf */
+	if (otx_ep->conf == NULL) {
+		otx_ep->conf = otx_ep_get_defconf(otx_ep);
+		if (otx_ep->conf == NULL) {
+			otx_ep_err("OTX_EP VF default config not found\n");
+			return -ENOMEM;
+		}
+		otx_ep_info("Default config is used\n");
+	}
+
+	/* Get IOQs (RPVF] count */
+	reg_val = rte_read64(otx_ep->hw_addr + OTX_EP_R_IN_CONTROL(0));
+
+	otx_ep->sriov_info.rings_per_vf = ((reg_val >> OTX_EP_R_IN_CTL_RPVF_POS)
+					  & OTX_EP_R_IN_CTL_RPVF_MASK);
+
+	otx_ep_info("OTX_EP RPVF: %d\n", otx_ep->sriov_info.rings_per_vf);
+
+	otx_ep->fn_list.setup_device_regs   = otx_ep_setup_device_regs;
+
+	return 0;
+}
diff --git a/drivers/net/octeontx_ep/otx_ep_vf.h b/drivers/net/octeontx_ep/otx_ep_vf.h
index 0498dd0cf5..5366297ee8 100644
--- a/drivers/net/octeontx_ep/otx_ep_vf.h
+++ b/drivers/net/octeontx_ep/otx_ep_vf.h
@@ -4,6 +4,39 @@ 
 #ifndef _OTX_EP_VF_H_
 #define _OTX_EP_VF_H_
 
+#define OTX_EP_RING_OFFSET                (0x1ull << 17)
+
+/* OTX_EP VF IQ Registers */
+#define OTX_EP_R_IN_CONTROL_START         (0x10000)
+#define OTX_EP_R_IN_CONTROL(ring)  \
+	(OTX_EP_R_IN_CONTROL_START + ((ring) * OTX_EP_RING_OFFSET))
+
+/* OTX_EP VF IQ Masks */
+#define OTX_EP_R_IN_CTL_RPVF_MASK       (0xF)
+#define	OTX_EP_R_IN_CTL_RPVF_POS        (48)
+
+#define OTX_EP_R_IN_CTL_IDLE            (0x1ull << 28)
+#define OTX_EP_R_IN_CTL_RDSIZE          (0x3ull << 25) /* Setting to max(4) */
+#define OTX_EP_R_IN_CTL_IS_64B          (0x1ull << 24)
+#define OTX_EP_R_IN_CTL_ESR             (0x1ull << 1)
+/* OTX_EP VF OQ Registers */
+#define OTX_EP_R_OUT_CONTROL_START           (0x10150)
+#define OTX_EP_R_OUT_CONTROL(ring)    \
+	(OTX_EP_R_OUT_CONTROL_START + ((ring) * OTX_EP_RING_OFFSET))
+/* OTX_EP VF OQ Masks */
+#define OTX_EP_R_OUT_CTL_ES_I         (1ull << 34)
+#define OTX_EP_R_OUT_CTL_NSR_I        (1ull << 33)
+#define OTX_EP_R_OUT_CTL_ROR_I        (1ull << 32)
+#define OTX_EP_R_OUT_CTL_ES_D         (1ull << 30)
+#define OTX_EP_R_OUT_CTL_NSR_D        (1ull << 29)
+#define OTX_EP_R_OUT_CTL_ROR_D        (1ull << 28)
+#define OTX_EP_R_OUT_CTL_ES_P         (1ull << 26)
+#define OTX_EP_R_OUT_CTL_NSR_P        (1ull << 25)
+#define OTX_EP_R_OUT_CTL_ROR_P        (1ull << 24)
+#define OTX_EP_R_OUT_CTL_IMODE        (1ull << 23)
+
 #define PCI_DEVID_OCTEONTX_EP_VF 0xa303
 
+int
+otx_ep_vf_setup_device(struct otx_ep_device *otx_ep);
 #endif /*_OTX_EP_VF_H_ */