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
This commit is contained in:
Bjorn Helgaas 2021-11-05 11:28:46 -05:00
commit 7aae94125f

View File

@ -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);