From 977509f7c5c6fb992ffcdf4291051af343b91645 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Mon, 2 Jan 2017 14:04:24 -0600 Subject: PCI: Apply _HPX settings only to relevant devices Previously we didn't check the type of device before trying to apply Type 1 (PCI-X) or Type 2 (PCIe) Setting Records from _HPX. We don't support PCI-X Setting Records, so this was harmless, but the warning was useless. We do support PCIe Setting Records, and we didn't check whether a device was PCIe before applying settings. I don't think anything bad happened on non-PCIe devices because pcie_capability_clear_and_set_word(), pcie_cap_has_lnkctl(), etc., would fail before doing any harm. But it's ugly to depend on those internals. Check the device type before attempting to apply Type 1 and Type 2 Setting Records (Type 0 records are applicable to PCI, PCI-X, and PCIe devices). A side benefit is that this prevents useless "not supported" warnings when a BIOS supplies a Type 1 (PCI-X) Setting Record and we try to apply it to every single device: pci 0000:00:00.0: PCI-X settings not supported After this patch, we'll get the warning only when a BIOS supplies a Type 1 record and we have a PCI-X device to which it should be applied. Link: https://bugzilla.kernel.org/show_bug.cgi?id=187731 Signed-off-by: Bjorn Helgaas --- drivers/pci/probe.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers/pci/probe.c') diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index e164b5c9f0f0..aca5b2466adb 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1554,8 +1554,16 @@ static void program_hpp_type0(struct pci_dev *dev, struct hpp_type0 *hpp) static void program_hpp_type1(struct pci_dev *dev, struct hpp_type1 *hpp) { - if (hpp) - dev_warn(&dev->dev, "PCI-X settings not supported\n"); + int pos; + + if (!hpp) + return; + + pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); + if (!pos) + return; + + dev_warn(&dev->dev, "PCI-X settings not supported\n"); } static bool pcie_root_rcb_set(struct pci_dev *dev) @@ -1581,6 +1589,9 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp) if (!hpp) return; + if (!pci_is_pcie(dev)) + return; + if (hpp->revision > 1) { dev_warn(&dev->dev, "PCIe settings rev %d not supported\n", hpp->revision); -- cgit v1.2.3 From 60db3a4d8cc9073cf56264785197ba75ee1caca4 Mon Sep 17 00:00:00 2001 From: Sinan Kaya Date: Fri, 20 Jan 2017 09:16:51 -0500 Subject: PCI: Enable PCIe Extended Tags if supported Every PCIe device can generate 5-bit transaction Tags, which allow up to 32 concurrent requests. Some devices can generate 8-bit Extended Tags, which allow up to 256 concurrent requests. Per the ECN mentioned below, all PCIe Receivers are expected to support Extended Tags, so devices are allowed (but not required) to enable them by default. If a device supports Extended Tags but does not enable them by default, enable them. This allows the device to have up to 256 outstanding transactions at a time, which may improve performance. [bhelgaas: changelog, check for PCIe device] Link: https://pcisig.com/sites/default/files/specification_documents/ECN_Extended_Tag_Enable_Default_05Sept2008_final.pdf Signed-off-by: Sinan Kaya Signed-off-by: Bjorn Helgaas --- drivers/pci/probe.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers/pci/probe.c') diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index aca5b2466adb..3abc94212197 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1661,12 +1661,30 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp) */ } +static void pci_configure_extended_tags(struct pci_dev *dev) +{ + u32 dev_cap; + int ret; + + if (!pci_is_pcie(dev)) + return; + + ret = pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &dev_cap); + if (ret) + return; + + if (dev_cap & PCI_EXP_DEVCAP_EXT_TAG) + pcie_capability_set_word(dev, PCI_EXP_DEVCTL, + PCI_EXP_DEVCTL_EXT_TAG); +} + static void pci_configure_device(struct pci_dev *dev) { struct hotplug_params hpp; int ret; pci_configure_mps(dev); + pci_configure_extended_tags(dev); memset(&hpp, 0, sizeof(hpp)); ret = pci_get_hp_params(dev, &hpp); -- cgit v1.2.3