Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0c45d7fe authored by Rick Farrington's avatar Rick Farrington Committed by David S. Miller
Browse files

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: default avatarRick Farrington <ricardo.farrington@cavium.com>
Signed-off-by: default avatarFelix Manlunas <felix.manlunas@cavium.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6eb15e21
Loading
Loading
Loading
Loading
+42 −5
Original line number Diff line number Diff line
@@ -1150,14 +1150,50 @@ static void cn23xx_get_pcie_qlmport(struct octeon_device *oct)
		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;
	u64 pkt0_in_ctl, d64;
	int pfnum, mac, trs, ret;

	ret = 0;

	/** 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,
				  &fdl_bit) == 0) {
		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)
@@ -1279,7 +1315,8 @@ int setup_cn23xx_octeon_pf_device(struct octeon_device *oct)
		return 1;
	}

	cn23xx_get_pf_num(oct);
	if (cn23xx_get_pf_num(oct) != 0)
		return 1;

	if (cn23xx_sriov_config(oct)) {
		octeon_unmap_pci_barx(oct, 0);
+2 −0
Original line number Diff line number Diff line
@@ -1560,6 +1560,8 @@ static int octeon_chip_specific_setup(struct octeon_device *oct)
	case OCTEON_CN23XX_PCIID_PF:
		oct->chip_id = OCTEON_CN23XX_PF_VID;
		ret = setup_cn23xx_octeon_pf_device(oct);
		if (ret)
			break;
#ifdef CONFIG_PCI_IOV
		if (!ret)
			pci_sriov_set_totalvfs(oct->pci_dev,