net/liquidio: add API to setup IO queue registers

Set default configuration values for input and output queue registers.

Signed-off-by: Shijith Thotton <shijith.thotton@caviumnetworks.com>
Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
Signed-off-by: Derek Chickles <derek.chickles@caviumnetworks.com>
Signed-off-by: Venkat Koppula <venkat.koppula@caviumnetworks.com>
Signed-off-by: Srisivasubramanian S <ssrinivasan@caviumnetworks.com>
Signed-off-by: Mallesham Jatharakonda <mjatharakonda@oneconvergence.com>
This commit is contained in:
Shijith Thotton 2017-03-25 11:54:19 +05:30 committed by Ferruh Yigit
parent 6aefdb5897
commit ba5f9ac56b
3 changed files with 172 additions and 0 deletions

View File

@ -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 @@ cn23xx_vf_setup_device(struct lio_device *lio_dev)
if (lio_dev->default_config == NULL)
return -1;
lio_dev->fn_list.setup_device_regs = cn23xx_vf_setup_device_regs;
return 0;
}

View File

@ -91,6 +91,11 @@ lio_first_time_init(struct lio_device *lio_dev,
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;

View File

@ -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 */