PCI: Add ACS quirk for Zhaoxin Root/Downstream Ports
[linux-2.6-microblaze.git] / drivers / pci / quirks.c
index 7bdd0f5..b0de6df 100644 (file)
@@ -4399,6 +4399,29 @@ static int pci_quirk_xgene_acs(struct pci_dev *dev, u16 acs_flags)
                PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
 }
 
+/*
+ * Many Zhaoxin Root Ports and Switch Downstream Ports have no ACS capability.
+ * But the implementation could block peer-to-peer transactions between them
+ * and provide ACS-like functionality.
+ */
+static int  pci_quirk_zhaoxin_pcie_ports_acs(struct pci_dev *dev, u16 acs_flags)
+{
+       if (!pci_is_pcie(dev) ||
+           ((pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT) &&
+            (pci_pcie_type(dev) != PCI_EXP_TYPE_DOWNSTREAM)))
+               return -ENOTTY;
+
+       switch (dev->device) {
+       case 0x0710 ... 0x071e:
+       case 0x0721:
+       case 0x0723 ... 0x0732:
+               return pci_acs_ctrl_enabled(acs_flags,
+                       PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
+       }
+
+       return false;
+}
+
 /*
  * Many Intel PCH Root Ports do provide ACS-like features to disable peer
  * transactions and validate bus numbers in requests, but do not provide an
@@ -4705,6 +4728,8 @@ static const struct pci_dev_acs_enabled {
        { PCI_VENDOR_ID_ZHAOXIN, 0x3038, pci_quirk_mf_endpoint_acs },
        { PCI_VENDOR_ID_ZHAOXIN, 0x3104, pci_quirk_mf_endpoint_acs },
        { PCI_VENDOR_ID_ZHAOXIN, 0x9083, pci_quirk_mf_endpoint_acs },
+       /* Zhaoxin Root/Downstream Ports */
+       { PCI_VENDOR_ID_ZHAOXIN, PCI_ANY_ID, pci_quirk_zhaoxin_pcie_ports_acs },
        { 0 }
 };