summaryrefslogtreecommitdiffstats
path: root/include/linux/pci.h
diff options
context:
space:
mode:
authorHariprasad Shenai <hariprasad@chelsio.com>2015-10-18 10:25:04 -0400
committerBjorn Helgaas <bhelgaas@google.com>2015-10-22 22:58:08 -0400
commitc56d4450eb6886225a5a0bb231ad2cea9f03284a (patch)
treeef7de1f043e2bb122be96d09b8d1c10fd1d828e4 /include/linux/pci.h
parent68d0d9794864a6bfbc6f88bb0ec980400bc17922 (diff)
PCI: Turn off Request Attributes to avoid Chelsio T5 Completion erratum
The Chelsio T5 has a PCIe compliance erratum that causes Malformed TLP or Unexpected Completion errors in some systems, which may cause device access timeouts. Per PCIe r3.0, sec 2.2.9, "Completion headers must supply the same values for the Attribute as were supplied in the header of the corresponding Request, except as explicitly allowed when IDO is used." Instead of copying the Attributes from the Request to the Completion, the T5 always generates Completions with zero Attributes. The receiver of a Completion whose Attributes don't match the Request may accept it (which itself seems non-compliant based on sec 2.3.2), or it may handle it as a Malformed TLP or an Unexpected Completion, which will probably lead to a device access timeout. Work around this by disabling "Relaxed Ordering" and "No Snoop" in the Root Port so it always generate Requests with zero Attributes. This does affect all other devices which are downstream of that Root Port, but these are performance optimizations that should not make a functional difference. Note that Configuration Space accesses are never supposed to have TLP Attributes, so we're safe waiting till after any Configuration Space accesses to do the Root Port "fixup". Based on original work by Casey Leedom <leedom@chelsio.com> [bhelgaas: changelog, comments, rename to pci_find_pcie_root_port(), rework to use pci_upstream_bridge() and check for Root Port device type, edit diagnostics to clarify intent and devices affected] Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'include/linux/pci.h')
-rw-r--r--include/linux/pci.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/include/linux/pci.h b/include/linux/pci.h
index b54fbf1571b1..e828e7b4afec 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -820,6 +820,7 @@ void pci_bus_add_device(struct pci_dev *dev);
820void pci_read_bridge_bases(struct pci_bus *child); 820void pci_read_bridge_bases(struct pci_bus *child);
821struct resource *pci_find_parent_resource(const struct pci_dev *dev, 821struct resource *pci_find_parent_resource(const struct pci_dev *dev,
822 struct resource *res); 822 struct resource *res);
823struct pci_dev *pci_find_pcie_root_port(struct pci_dev *dev);
823u8 pci_swizzle_interrupt_pin(const struct pci_dev *dev, u8 pin); 824u8 pci_swizzle_interrupt_pin(const struct pci_dev *dev, u8 pin);
824int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge); 825int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge);
825u8 pci_common_swizzle(struct pci_dev *dev, u8 *pinp); 826u8 pci_common_swizzle(struct pci_dev *dev, u8 *pinp);