liquidio: fix use of pf in pass-through mode in a virtual machine
Fix problem when PF is used in pass-through mode in a VM (w/embedded f/w). If host error reading PF num from CN23XX_PCIE_SRIOV_FDL reg, try to retrieve PF num from SLI_PKT(0)_INPUT_CONTROL (initialized by f/w). Signed-off-by: Rick Farrington <ricardo.farrington@cavium.com> Signed-off-by: Felix Manlunas <felix.manlunas@cavium.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
6eb15e2130
Коммит
0c45d7fe12
|
@ -1150,14 +1150,50 @@ static void cn23xx_get_pcie_qlmport(struct octeon_device *oct)
|
||||||
oct->pcie_port);
|
oct->pcie_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cn23xx_get_pf_num(struct octeon_device *oct)
|
static int cn23xx_get_pf_num(struct octeon_device *oct)
|
||||||
{
|
{
|
||||||
u32 fdl_bit = 0;
|
u32 fdl_bit = 0;
|
||||||
|
u64 pkt0_in_ctl, d64;
|
||||||
|
int pfnum, mac, trs, ret;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
/** Read Function Dependency Link reg to get the function number */
|
/** Read Function Dependency Link reg to get the function number */
|
||||||
pci_read_config_dword(oct->pci_dev, CN23XX_PCIE_SRIOV_FDL, &fdl_bit);
|
if (pci_read_config_dword(oct->pci_dev, CN23XX_PCIE_SRIOV_FDL,
|
||||||
oct->pf_num = ((fdl_bit >> CN23XX_PCIE_SRIOV_FDL_BIT_POS) &
|
&fdl_bit) == 0) {
|
||||||
CN23XX_PCIE_SRIOV_FDL_MASK);
|
oct->pf_num = ((fdl_bit >> CN23XX_PCIE_SRIOV_FDL_BIT_POS) &
|
||||||
|
CN23XX_PCIE_SRIOV_FDL_MASK);
|
||||||
|
} else {
|
||||||
|
ret = EINVAL;
|
||||||
|
|
||||||
|
/* Under some virtual environments, extended PCI regs are
|
||||||
|
* inaccessible, in which case the above read will have failed.
|
||||||
|
* In this case, read the PF number from the
|
||||||
|
* SLI_PKT0_INPUT_CONTROL reg (written by f/w)
|
||||||
|
*/
|
||||||
|
pkt0_in_ctl = octeon_read_csr64(oct,
|
||||||
|
CN23XX_SLI_IQ_PKT_CONTROL64(0));
|
||||||
|
pfnum = (pkt0_in_ctl >> CN23XX_PKT_INPUT_CTL_PF_NUM_POS) &
|
||||||
|
CN23XX_PKT_INPUT_CTL_PF_NUM_MASK;
|
||||||
|
mac = (octeon_read_csr(oct, CN23XX_SLI_MAC_NUMBER)) & 0xff;
|
||||||
|
|
||||||
|
/* validate PF num by reading RINFO; f/w writes RINFO.trs == 1*/
|
||||||
|
d64 = octeon_read_csr64(oct,
|
||||||
|
CN23XX_SLI_PKT_MAC_RINFO64(mac, pfnum));
|
||||||
|
trs = (int)(d64 >> CN23XX_PKT_MAC_CTL_RINFO_TRS_BIT_POS) & 0xff;
|
||||||
|
if (trs == 1) {
|
||||||
|
dev_err(&oct->pci_dev->dev,
|
||||||
|
"OCTEON: error reading PCI cfg space pfnum, re-read %u\n",
|
||||||
|
pfnum);
|
||||||
|
oct->pf_num = pfnum;
|
||||||
|
ret = 0;
|
||||||
|
} else {
|
||||||
|
dev_err(&oct->pci_dev->dev,
|
||||||
|
"OCTEON: error reading PCI cfg space pfnum; could not ascertain PF number\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cn23xx_setup_reg_address(struct octeon_device *oct)
|
static void cn23xx_setup_reg_address(struct octeon_device *oct)
|
||||||
|
@ -1279,7 +1315,8 @@ int setup_cn23xx_octeon_pf_device(struct octeon_device *oct)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cn23xx_get_pf_num(oct);
|
if (cn23xx_get_pf_num(oct) != 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
if (cn23xx_sriov_config(oct)) {
|
if (cn23xx_sriov_config(oct)) {
|
||||||
octeon_unmap_pci_barx(oct, 0);
|
octeon_unmap_pci_barx(oct, 0);
|
||||||
|
|
|
@ -1560,6 +1560,8 @@ static int octeon_chip_specific_setup(struct octeon_device *oct)
|
||||||
case OCTEON_CN23XX_PCIID_PF:
|
case OCTEON_CN23XX_PCIID_PF:
|
||||||
oct->chip_id = OCTEON_CN23XX_PF_VID;
|
oct->chip_id = OCTEON_CN23XX_PF_VID;
|
||||||
ret = setup_cn23xx_octeon_pf_device(oct);
|
ret = setup_cn23xx_octeon_pf_device(oct);
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
#ifdef CONFIG_PCI_IOV
|
#ifdef CONFIG_PCI_IOV
|
||||||
if (!ret)
|
if (!ret)
|
||||||
pci_sriov_set_totalvfs(oct->pci_dev,
|
pci_sriov_set_totalvfs(oct->pci_dev,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче