Commit 7aae9412 authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'pci/virtualization'

- Avoid bus resets on Atheros QCA6174, since they hang (Ingmar Klein)

- Use store and forward mode on Pericom PI7C9X2G switches to avoid ACS
  erratum with ACS P2P Request Redirect (Nathan Rossi)

* pci/virtualization:
  PCI: Add ACS quirk for Pericom PI7C9X2G switches
  PCI: Mark Atheros QCA6174 to avoid bus reset
parents ebf275b8 acd61ffb
Loading
Loading
Loading
Loading
+56 −0
Original line number Diff line number Diff line
@@ -3612,6 +3612,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0032, quirk_no_bus_reset);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x003c, quirk_no_bus_reset);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0033, quirk_no_bus_reset);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0034, quirk_no_bus_reset);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x003e, quirk_no_bus_reset);

/*
 * Root port on some Cavium CN8xxx chips do not successfully complete a bus
@@ -5795,3 +5796,58 @@ static void apex_pci_fixup_class(struct pci_dev *pdev)
}
DECLARE_PCI_FIXUP_CLASS_HEADER(0x1ac1, 0x089a,
			       PCI_CLASS_NOT_DEFINED, 8, apex_pci_fixup_class);

/*
 * Pericom PI7C9X2G404/PI7C9X2G304/PI7C9X2G303 switch erratum E5 -
 * ACS P2P Request Redirect is not functional
 *
 * When ACS P2P Request Redirect is enabled and bandwidth is not balanced
 * between upstream and downstream ports, packets are queued in an internal
 * buffer until CPLD packet. The workaround is to use the switch in store and
 * forward mode.
 */
#define PI7C9X2Gxxx_MODE_REG		0x74
#define PI7C9X2Gxxx_STORE_FORWARD_MODE	BIT(0)
static void pci_fixup_pericom_acs_store_forward(struct pci_dev *pdev)
{
	struct pci_dev *upstream;
	u16 val;

	/* Downstream ports only */
	if (pci_pcie_type(pdev) != PCI_EXP_TYPE_DOWNSTREAM)
		return;

	/* Check for ACS P2P Request Redirect use */
	if (!pdev->acs_cap)
		return;
	pci_read_config_word(pdev, pdev->acs_cap + PCI_ACS_CTRL, &val);
	if (!(val & PCI_ACS_RR))
		return;

	upstream = pci_upstream_bridge(pdev);
	if (!upstream)
		return;

	pci_read_config_word(upstream, PI7C9X2Gxxx_MODE_REG, &val);
	if (!(val & PI7C9X2Gxxx_STORE_FORWARD_MODE)) {
		pci_info(upstream, "Setting PI7C9X2Gxxx store-forward mode to avoid ACS erratum\n");
		pci_write_config_word(upstream, PI7C9X2Gxxx_MODE_REG, val |
				      PI7C9X2Gxxx_STORE_FORWARD_MODE);
	}
}
/*
 * Apply fixup on enable and on resume, in order to apply the fix up whenever
 * ACS configuration changes or switch mode is reset
 */
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_PERICOM, 0x2404,
			 pci_fixup_pericom_acs_store_forward);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_PERICOM, 0x2404,
			 pci_fixup_pericom_acs_store_forward);
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_PERICOM, 0x2304,
			 pci_fixup_pericom_acs_store_forward);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_PERICOM, 0x2304,
			 pci_fixup_pericom_acs_store_forward);
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_PERICOM, 0x2303,
			 pci_fixup_pericom_acs_store_forward);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_PERICOM, 0x2303,
			 pci_fixup_pericom_acs_store_forward);