diff mbox series

[04/15] net/octeontx_ep: Added basic device setup.

Message ID 20201231072247.5719-5-pnalla@marvell.com (mailing list archive)
State Superseded, archived
Delegated to: Ferruh Yigit
Headers show
Series Octeon Tx/Tx2 Endpoint pmd | expand

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Nalla Pradeep Dec. 31, 2020, 7:22 a.m. UTC
From: "Nalla Pradeep" <pnalla@marvell.com>

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 |  87 +++++++++++++
 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, 435 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 mbox series

Patch

diff --git a/drivers/net/octeontx_ep/meson.build b/drivers/net/octeontx_ep/meson.build
index 42eab9b648..c7a7aa84bb 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..f8be2f4864
--- /dev/null
+++ b/drivers/net/octeontx_ep/otx2_ep_vf.c
@@ -0,0 +1,138 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2019 Marvell International Ltd.
+ */
+
+#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 Fomat#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..52d6487548
--- /dev/null
+++ b/drivers/net/octeontx_ep/otx2_ep_vf.h
@@ -0,0 +1,11 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2019 Marvell International Ltd.
+ */
+#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 fca0c79a43..f096bec1c0 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,6 +26,76 @@ 
 #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 */
@@ -31,6 +110,14 @@  struct otx_ep_device {
 	/* 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 6012c3fe9d..7ae9618e72 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 = PCI_DEVID_OCTEONTX_EP_VF;
+		ret = otx_ep_vf_setup_device(otx_epvf);
 		break;
 	case PCI_DEVID_OCTEONTX2_EP_NET_VF:
 	case PCI_DEVID_98XX_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..9d9be66258
--- /dev/null
+++ b/drivers/net/octeontx_ep/otx_ep_vf.c
@@ -0,0 +1,154 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2019 Marvell International Ltd.
+ */
+
+#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 Fomat#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 bee8a26727..ff248c37c6 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_ */