Commit d13520c7 authored by Raghu Vatsavayi's avatar Raghu Vatsavayi Committed by David S. Miller

liquidio CN23XX: HW config for VF support

Adds support for configuring HW for creating VFs.
Signed-off-by: default avatarRaghu Vatsavayi <raghu.vatsavayi@caviumnetworks.com>
Signed-off-by: default avatarDerek Chickles <derek.chickles@caviumnetworks.com>
Signed-off-by: default avatarSatanand Burla <satananda.burla@caviumnetworks.com>
Signed-off-by: default avatarFelix Manlunas <felix.manlunas@caviumnetworks.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3418c681
...@@ -40,11 +40,6 @@ ...@@ -40,11 +40,6 @@
*/ */
#define CN23XX_INPUT_JABBER 64600 #define CN23XX_INPUT_JABBER 64600
#define LIOLUT_RING_DISTRIBUTION 9
const int liolut_num_vfs_to_rings_per_vf[LIOLUT_RING_DISTRIBUTION] = {
0, 8, 4, 2, 2, 2, 1, 1, 1
};
void cn23xx_dump_pf_initialized_regs(struct octeon_device *oct) void cn23xx_dump_pf_initialized_regs(struct octeon_device *oct)
{ {
int i = 0; int i = 0;
...@@ -309,9 +304,10 @@ u32 cn23xx_pf_get_oq_ticks(struct octeon_device *oct, u32 time_intr_in_us) ...@@ -309,9 +304,10 @@ u32 cn23xx_pf_get_oq_ticks(struct octeon_device *oct, u32 time_intr_in_us)
static void cn23xx_setup_global_mac_regs(struct octeon_device *oct) static void cn23xx_setup_global_mac_regs(struct octeon_device *oct)
{ {
u64 reg_val;
u16 mac_no = oct->pcie_port; u16 mac_no = oct->pcie_port;
u16 pf_num = oct->pf_num; u16 pf_num = oct->pf_num;
u64 reg_val;
u64 temp;
/* programming SRN and TRS for each MAC(0..3) */ /* programming SRN and TRS for each MAC(0..3) */
...@@ -333,6 +329,14 @@ static void cn23xx_setup_global_mac_regs(struct octeon_device *oct) ...@@ -333,6 +329,14 @@ static void cn23xx_setup_global_mac_regs(struct octeon_device *oct)
/* setting TRS <23:16> */ /* setting TRS <23:16> */
reg_val = reg_val | reg_val = reg_val |
(oct->sriov_info.trs << CN23XX_PKT_MAC_CTL_RINFO_TRS_BIT_POS); (oct->sriov_info.trs << CN23XX_PKT_MAC_CTL_RINFO_TRS_BIT_POS);
/* setting RPVF <39:32> */
temp = oct->sriov_info.rings_per_vf & 0xff;
reg_val |= (temp << CN23XX_PKT_MAC_CTL_RINFO_RPVF_BIT_POS);
/* setting NVFS <55:48> */
temp = oct->sriov_info.max_vfs & 0xff;
reg_val |= (temp << CN23XX_PKT_MAC_CTL_RINFO_NVFS_BIT_POS);
/* write these settings to MAC register */ /* write these settings to MAC register */
octeon_write_csr64(oct, CN23XX_SLI_PKT_MAC_RINFO64(mac_no, pf_num), octeon_write_csr64(oct, CN23XX_SLI_PKT_MAC_RINFO64(mac_no, pf_num),
reg_val); reg_val);
...@@ -399,11 +403,12 @@ static int cn23xx_reset_io_queues(struct octeon_device *oct) ...@@ -399,11 +403,12 @@ static int cn23xx_reset_io_queues(struct octeon_device *oct)
static int cn23xx_pf_setup_global_input_regs(struct octeon_device *oct) static int cn23xx_pf_setup_global_input_regs(struct octeon_device *oct)
{ {
struct octeon_cn23xx_pf *cn23xx = (struct octeon_cn23xx_pf *)oct->chip;
struct octeon_instr_queue *iq;
u64 intr_threshold, reg_val;
u32 q_no, ern, srn; u32 q_no, ern, srn;
u64 pf_num; u64 pf_num;
u64 intr_threshold, reg_val; u64 vf_num;
struct octeon_instr_queue *iq;
struct octeon_cn23xx_pf *cn23xx = (struct octeon_cn23xx_pf *)oct->chip;
pf_num = oct->pf_num; pf_num = oct->pf_num;
...@@ -420,6 +425,16 @@ static int cn23xx_pf_setup_global_input_regs(struct octeon_device *oct) ...@@ -420,6 +425,16 @@ static int cn23xx_pf_setup_global_input_regs(struct octeon_device *oct)
*/ */
for (q_no = 0; q_no < ern; q_no++) { for (q_no = 0; q_no < ern; q_no++) {
reg_val = oct->pcie_port << CN23XX_PKT_INPUT_CTL_MAC_NUM_POS; reg_val = oct->pcie_port << CN23XX_PKT_INPUT_CTL_MAC_NUM_POS;
/* for VF assigned queues. */
if (q_no < oct->sriov_info.pf_srn) {
vf_num = q_no / oct->sriov_info.rings_per_vf;
vf_num += 1; /* VF1, VF2,........ */
} else {
vf_num = 0;
}
reg_val |= vf_num << CN23XX_PKT_INPUT_CTL_VF_NUM_POS;
reg_val |= pf_num << CN23XX_PKT_INPUT_CTL_PF_NUM_POS; reg_val |= pf_num << CN23XX_PKT_INPUT_CTL_PF_NUM_POS;
octeon_write_csr64(oct, CN23XX_SLI_IQ_PKT_CONTROL64(q_no), octeon_write_csr64(oct, CN23XX_SLI_IQ_PKT_CONTROL64(q_no),
...@@ -1048,50 +1063,59 @@ static void cn23xx_setup_reg_address(struct octeon_device *oct) ...@@ -1048,50 +1063,59 @@ static void cn23xx_setup_reg_address(struct octeon_device *oct)
static int cn23xx_sriov_config(struct octeon_device *oct) static int cn23xx_sriov_config(struct octeon_device *oct)
{ {
u32 total_rings;
struct octeon_cn23xx_pf *cn23xx = (struct octeon_cn23xx_pf *)oct->chip; struct octeon_cn23xx_pf *cn23xx = (struct octeon_cn23xx_pf *)oct->chip;
/* num_vfs is already filled for us */ u32 max_rings, total_rings, max_vfs, rings_per_vf;
u32 pf_srn, num_pf_rings; u32 pf_srn, num_pf_rings;
u32 max_possible_vfs;
cn23xx->conf = cn23xx->conf =
(struct octeon_config *)oct_get_config_info(oct, LIO_23XX); (struct octeon_config *)oct_get_config_info(oct, LIO_23XX);
switch (oct->rev_id) { switch (oct->rev_id) {
case OCTEON_CN23XX_REV_1_0: case OCTEON_CN23XX_REV_1_0:
total_rings = CN23XX_MAX_RINGS_PER_PF_PASS_1_0; max_rings = CN23XX_MAX_RINGS_PER_PF_PASS_1_0;
max_possible_vfs = CN23XX_MAX_VFS_PER_PF_PASS_1_0;
break; break;
case OCTEON_CN23XX_REV_1_1: case OCTEON_CN23XX_REV_1_1:
total_rings = CN23XX_MAX_RINGS_PER_PF_PASS_1_1; max_rings = CN23XX_MAX_RINGS_PER_PF_PASS_1_1;
max_possible_vfs = CN23XX_MAX_VFS_PER_PF_PASS_1_1;
break; break;
default: default:
total_rings = CN23XX_MAX_RINGS_PER_PF; max_rings = CN23XX_MAX_RINGS_PER_PF;
max_possible_vfs = CN23XX_MAX_VFS_PER_PF;
break; break;
} }
if (!oct->sriov_info.num_pf_rings) {
if (total_rings > num_present_cpus())
num_pf_rings = num_present_cpus();
else
num_pf_rings = total_rings;
} else {
num_pf_rings = oct->sriov_info.num_pf_rings;
if (num_pf_rings > total_rings) { if (max_rings <= num_present_cpus())
dev_warn(&oct->pci_dev->dev, num_pf_rings = 1;
"num_queues_per_pf requested %u is more than available rings. Reducing to %u\n", else
num_pf_rings, total_rings); num_pf_rings = num_present_cpus();
num_pf_rings = total_rings;
} #ifdef CONFIG_PCI_IOV
} max_vfs = min_t(u32,
(max_rings - num_pf_rings), max_possible_vfs);
rings_per_vf = 1;
#else
max_vfs = 0;
rings_per_vf = 0;
#endif
total_rings = num_pf_rings + max_vfs;
total_rings = num_pf_rings;
/* the first ring of the pf */ /* the first ring of the pf */
pf_srn = total_rings - num_pf_rings; pf_srn = total_rings - num_pf_rings;
oct->sriov_info.trs = total_rings; oct->sriov_info.trs = total_rings;
oct->sriov_info.max_vfs = max_vfs;
oct->sriov_info.rings_per_vf = rings_per_vf;
oct->sriov_info.pf_srn = pf_srn; oct->sriov_info.pf_srn = pf_srn;
oct->sriov_info.num_pf_rings = num_pf_rings; oct->sriov_info.num_pf_rings = num_pf_rings;
dev_dbg(&oct->pci_dev->dev, "trs:%d pf_srn:%d num_pf_rings:%d\n", dev_notice(&oct->pci_dev->dev, "trs:%d max_vfs:%d rings_per_vf:%d pf_srn:%d num_pf_rings:%d\n",
oct->sriov_info.trs, oct->sriov_info.pf_srn, oct->sriov_info.trs, oct->sriov_info.max_vfs,
oct->sriov_info.num_pf_rings); oct->sriov_info.rings_per_vf, oct->sriov_info.pf_srn,
oct->sriov_info.num_pf_rings);
oct->sriov_info.sriov_enabled = 0;
return 0; return 0;
} }
......
...@@ -65,9 +65,15 @@ ...@@ -65,9 +65,15 @@
#define DEFAULT_NUM_NIC_PORTS_68XX_210NV 2 #define DEFAULT_NUM_NIC_PORTS_68XX_210NV 2
/* CN23xx IQ configuration macros */ /* CN23xx IQ configuration macros */
#define CN23XX_MAX_VFS_PER_PF_PASS_1_0 8
#define CN23XX_MAX_VFS_PER_PF_PASS_1_1 31
#define CN23XX_MAX_VFS_PER_PF 63
#define CN23XX_MAX_RINGS_PER_VF 8
#define CN23XX_MAX_RINGS_PER_PF_PASS_1_0 12 #define CN23XX_MAX_RINGS_PER_PF_PASS_1_0 12
#define CN23XX_MAX_RINGS_PER_PF_PASS_1_1 32 #define CN23XX_MAX_RINGS_PER_PF_PASS_1_1 32
#define CN23XX_MAX_RINGS_PER_PF 64 #define CN23XX_MAX_RINGS_PER_PF 64
#define CN23XX_MAX_RINGS_PER_VF 8
#define CN23XX_MAX_INPUT_QUEUES CN23XX_MAX_RINGS_PER_PF #define CN23XX_MAX_INPUT_QUEUES CN23XX_MAX_RINGS_PER_PF
#define CN23XX_MAX_IQ_DESCRIPTORS 2048 #define CN23XX_MAX_IQ_DESCRIPTORS 2048
......
...@@ -322,11 +322,21 @@ struct octeon_pf_vf_hs_word { ...@@ -322,11 +322,21 @@ struct octeon_pf_vf_hs_word {
}; };
struct octeon_sriov_info { struct octeon_sriov_info {
/* Number of rings assigned to VF */
u32 rings_per_vf;
/** Max Number of VF devices that can be enabled. This variable can
* specified during load time or it will be derived after allocating
* PF queues. When max_vfs is derived then each VF will get one queue
**/
u32 max_vfs;
/* Actual rings left for PF device */ /* Actual rings left for PF device */
u32 num_pf_rings; u32 num_pf_rings;
/* SRN of PF usable IO queues */ /* SRN of PF usable IO queues */
u32 pf_srn; u32 pf_srn;
/* total pf rings */ /* total pf rings */
u32 trs; u32 trs;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment