[dpdk-dev] [PATCH v3 08/46] net/liquidio: add API to setup IO queue registers

Shijith Thotton shijith.thotton at caviumnetworks.com
Sat Mar 25 07:24:19 CET 2017


Set default configuration values for input and output queue registers.

Signed-off-by: Shijith Thotton <shijith.thotton at caviumnetworks.com>
Signed-off-by: Jerin Jacob <jerin.jacob at caviumnetworks.com>
Signed-off-by: Derek Chickles <derek.chickles at caviumnetworks.com>
Signed-off-by: Venkat Koppula <venkat.koppula at caviumnetworks.com>
Signed-off-by: Srisivasubramanian S <ssrinivasan at caviumnetworks.com>
Signed-off-by: Mallesham Jatharakonda <mjatharakonda at oneconvergence.com>
---
 drivers/net/liquidio/base/lio_23xx_vf.c | 160 ++++++++++++++++++++++++++++++++
 drivers/net/liquidio/lio_ethdev.c       |   5 +
 drivers/net/liquidio/lio_struct.h       |   7 ++
 3 files changed, 172 insertions(+)

diff --git a/drivers/net/liquidio/base/lio_23xx_vf.c b/drivers/net/liquidio/base/lio_23xx_vf.c
index d9b9e2a..f61f185 100644
--- a/drivers/net/liquidio/base/lio_23xx_vf.c
+++ b/drivers/net/liquidio/base/lio_23xx_vf.c
@@ -39,6 +39,164 @@
 #include "lio_23xx_vf.h"
 #include "lio_23xx_reg.h"
 
+static int
+cn23xx_vf_reset_io_queues(struct lio_device *lio_dev, uint32_t num_queues)
+{
+	uint32_t loop = CN23XX_VF_BUSY_READING_REG_LOOP_COUNT;
+	uint64_t d64, q_no;
+	int ret_val = 0;
+
+	PMD_INIT_FUNC_TRACE();
+
+	for (q_no = 0; q_no < num_queues; q_no++) {
+		/* set RST bit to 1. This bit applies to both IQ and OQ */
+		d64 = lio_read_csr64(lio_dev,
+				     CN23XX_SLI_IQ_PKT_CONTROL64(q_no));
+		d64 = d64 | CN23XX_PKT_INPUT_CTL_RST;
+		lio_write_csr64(lio_dev, CN23XX_SLI_IQ_PKT_CONTROL64(q_no),
+				d64);
+	}
+
+	/* wait until the RST bit is clear or the RST and QUIET bits are set */
+	for (q_no = 0; q_no < num_queues; q_no++) {
+		volatile uint64_t reg_val;
+
+		reg_val	= lio_read_csr64(lio_dev,
+					 CN23XX_SLI_IQ_PKT_CONTROL64(q_no));
+		while ((reg_val & CN23XX_PKT_INPUT_CTL_RST) &&
+				!(reg_val & CN23XX_PKT_INPUT_CTL_QUIET) &&
+				loop) {
+			reg_val = lio_read_csr64(
+					lio_dev,
+					CN23XX_SLI_IQ_PKT_CONTROL64(q_no));
+			loop = loop - 1;
+		}
+
+		if (loop == 0) {
+			lio_dev_err(lio_dev,
+				    "clearing the reset reg failed or setting the quiet reg failed for qno: %lu\n",
+				    (unsigned long)q_no);
+			return -1;
+		}
+
+		reg_val = reg_val & ~CN23XX_PKT_INPUT_CTL_RST;
+		lio_write_csr64(lio_dev, CN23XX_SLI_IQ_PKT_CONTROL64(q_no),
+				reg_val);
+
+		reg_val = lio_read_csr64(
+		    lio_dev, CN23XX_SLI_IQ_PKT_CONTROL64(q_no));
+		if (reg_val & CN23XX_PKT_INPUT_CTL_RST) {
+			lio_dev_err(lio_dev,
+				    "clearing the reset failed for qno: %lu\n",
+				    (unsigned long)q_no);
+			ret_val = -1;
+		}
+	}
+
+	return ret_val;
+}
+
+static int
+cn23xx_vf_setup_global_input_regs(struct lio_device *lio_dev)
+{
+	uint64_t q_no;
+	uint64_t d64;
+
+	PMD_INIT_FUNC_TRACE();
+
+	if (cn23xx_vf_reset_io_queues(lio_dev,
+				      lio_dev->sriov_info.rings_per_vf))
+		return -1;
+
+	for (q_no = 0; q_no < (lio_dev->sriov_info.rings_per_vf); q_no++) {
+		lio_write_csr64(lio_dev, CN23XX_SLI_IQ_DOORBELL(q_no),
+				0xFFFFFFFF);
+
+		d64 = lio_read_csr64(lio_dev,
+				     CN23XX_SLI_IQ_INSTR_COUNT64(q_no));
+
+		d64 &= 0xEFFFFFFFFFFFFFFFL;
+
+		lio_write_csr64(lio_dev, CN23XX_SLI_IQ_INSTR_COUNT64(q_no),
+				d64);
+
+		/* Select ES, RO, NS, RDSIZE,DPTR Fomat#0 for
+		 * the Input Queues
+		 */
+		lio_write_csr64(lio_dev, CN23XX_SLI_IQ_PKT_CONTROL64(q_no),
+				CN23XX_PKT_INPUT_CTL_MASK);
+	}
+
+	return 0;
+}
+
+static void
+cn23xx_vf_setup_global_output_regs(struct lio_device *lio_dev)
+{
+	uint32_t reg_val;
+	uint32_t q_no;
+
+	PMD_INIT_FUNC_TRACE();
+
+	for (q_no = 0; q_no < lio_dev->sriov_info.rings_per_vf; q_no++) {
+		lio_write_csr(lio_dev, CN23XX_SLI_OQ_PKTS_CREDIT(q_no),
+			      0xFFFFFFFF);
+
+		reg_val =
+		    lio_read_csr(lio_dev, CN23XX_SLI_OQ_PKTS_SENT(q_no));
+
+		reg_val &= 0xEFFFFFFFFFFFFFFFL;
+
+		reg_val =
+		    lio_read_csr(lio_dev, CN23XX_SLI_OQ_PKT_CONTROL(q_no));
+
+		/* set IPTR & DPTR */
+		reg_val |=
+		    (CN23XX_PKT_OUTPUT_CTL_IPTR | CN23XX_PKT_OUTPUT_CTL_DPTR);
+
+		/* reset BMODE */
+		reg_val &= ~(CN23XX_PKT_OUTPUT_CTL_BMODE);
+
+		/* No Relaxed Ordering, No Snoop, 64-bit Byte swap
+		 * for Output Queue Scatter List
+		 * reset ROR_P, NSR_P
+		 */
+		reg_val &= ~(CN23XX_PKT_OUTPUT_CTL_ROR_P);
+		reg_val &= ~(CN23XX_PKT_OUTPUT_CTL_NSR_P);
+
+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+		reg_val &= ~(CN23XX_PKT_OUTPUT_CTL_ES_P);
+#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+		reg_val |= (CN23XX_PKT_OUTPUT_CTL_ES_P);
+#endif
+		/* No Relaxed Ordering, No Snoop, 64-bit Byte swap
+		 * for Output Queue Data
+		 * reset ROR, NSR
+		 */
+		reg_val &= ~(CN23XX_PKT_OUTPUT_CTL_ROR);
+		reg_val &= ~(CN23XX_PKT_OUTPUT_CTL_NSR);
+		/* set the ES bit */
+		reg_val |= (CN23XX_PKT_OUTPUT_CTL_ES);
+
+		/* write all the selected settings */
+		lio_write_csr(lio_dev, CN23XX_SLI_OQ_PKT_CONTROL(q_no),
+			      reg_val);
+	}
+}
+
+static int
+cn23xx_vf_setup_device_regs(struct lio_device *lio_dev)
+{
+	PMD_INIT_FUNC_TRACE();
+
+	if (cn23xx_vf_setup_global_input_regs(lio_dev))
+		return -1;
+
+	cn23xx_vf_setup_global_output_regs(lio_dev);
+
+	return 0;
+}
+
 int
 cn23xx_vf_setup_device(struct lio_device *lio_dev)
 {
@@ -63,6 +221,8 @@
 	if (lio_dev->default_config == NULL)
 		return -1;
 
+	lio_dev->fn_list.setup_device_regs	= cn23xx_vf_setup_device_regs;
+
 	return 0;
 }
 
diff --git a/drivers/net/liquidio/lio_ethdev.c b/drivers/net/liquidio/lio_ethdev.c
index 0487f3d..34b7b54 100644
--- a/drivers/net/liquidio/lio_ethdev.c
+++ b/drivers/net/liquidio/lio_ethdev.c
@@ -91,6 +91,11 @@
 		return -1;
 	}
 
+	if (lio_dev->fn_list.setup_device_regs(lio_dev)) {
+		lio_dev_err(lio_dev, "Failed to configure device registers\n");
+		return -1;
+	}
+
 	dpdk_queues = (int)lio_dev->sriov_info.rings_per_vf;
 
 	lio_dev->max_tx_queues = dpdk_queues;
diff --git a/drivers/net/liquidio/lio_struct.h b/drivers/net/liquidio/lio_struct.h
index a1203e4..577ea49 100644
--- a/drivers/net/liquidio/lio_struct.h
+++ b/drivers/net/liquidio/lio_struct.h
@@ -43,6 +43,11 @@
 
 #include "lio_hw_defs.h"
 
+struct lio_device;
+struct lio_fn_list {
+	int (*setup_device_regs)(struct lio_device *);
+};
+
 struct lio_sriov_info {
 	/** Number of rings assigned to VF */
 	uint32_t rings_per_vf;
@@ -117,6 +122,8 @@ struct lio_device {
 
 	uint8_t *hw_addr;
 
+	struct lio_fn_list fn_list;
+
 	struct lio_sriov_info sriov_info;
 
 	char dev_string[LIO_DEVICE_NAME_LEN]; /* Device print string */
-- 
1.8.3.1



More information about the dev mailing list