Skip to content
Snippets Groups Projects
Commit 13bc7bd9 authored by Myron Stowe's avatar Myron Stowe
Browse files

PCI: Store all PCIe Supported Link Speeds

JIRA: https://issues.redhat.com/browse/RHEL-81906


Upstream Status: d2bd39c0456b75be9dfc7d774b8d021355c26ae3

commit d2bd39c0456b75be9dfc7d774b8d021355c26ae3
Author: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Date:   Fri Oct 18 17:47:49 2024 +0300

    PCI: Store all PCIe Supported Link Speeds

    The PCIe bandwidth controller added by a subsequent commit will require
    selecting PCIe Link Speeds that are lower than the Maximum Link Speed.

    The struct pci_bus only stores max_bus_speed. Even if PCIe r6.1 sec 8.2.1
    currently disallows gaps in supported Link Speeds, the Implementation Note
    in PCIe r6.1 sec 7.5.3.18, recommends determining supported Link Speeds
    using the Supported Link Speeds Vector in the Link Capabilities 2 Register
    (when available) to "avoid software being confused if a future
    specification defines Links that do not require support for all slower
    speeds."

    Reuse code in pcie_get_speed_cap() to add pcie_get_supported_speeds() to
    query the Supported Link Speeds Vector of a PCIe device. The value is taken
    directly from the Supported Link Speeds Vector or synthesized from the Max
    Link Speed in the Link Capabilities Register when the Link Capabilities 2
    Register is not available.

    The Supported Link Speeds Vector in the Link Capabilities Register 2
    corresponds to the bus below on Root Ports and Downstream Ports, whereas it
    corresponds to the bus above on Upstream Ports and Endpoints (PCIe r6.1 sec
    7.5.3.18):

      Supported Link Speeds Vector - This field indicates the supported Link
      speed(s) of the associated Port.

    Add supported_speeds into the struct pci_dev that caches the
    Supported Link Speeds Vector.

    supported_speeds contains a set of Link Speeds only in the case where PCIe
    Link Speed can be determined. Root Complex Integrated Endpoints do not have
    a well-defined Link Speed because they do not implement either of the Link
    Capabilities Registers, which is allowed by PCIe r6.1 sec 7.5.3 (the same
    limitation applies to determining cur_bus_speed and max_bus_speed that are
    PCI_SPEED_UNKNOWN in such case). This is of no concern from PCIe bandwidth
    controller point of view because such devices are not attached into a PCIe
    Root Port that could be controlled.

    The supported_speeds field keeps the extra reserved zero at the least
    significant bit to match the Link Capabilities 2 Register layout.

    An attempt was made to store supported_speeds field into the struct pci_bus
    as an intersection of both ends of the Link, however, the subordinate
    struct pci_bus is not available early enough. The Target Speed quirk (in
    pcie_failed_link_retrain()) can run either during initial scan or later,
    requiring it to use the API provided by the PCIe bandwidth controller to
    set the Target Link Speed in order to co-exist with the bandwidth
    controller. When the Target Speed quirk is calling the bandwidth controller
    during initial scan, the struct pci_bus is not yet initialized. As such,
    storing supported_speeds into the struct pci_bus is not viable.

Suggested-by: default avatarLukas Wunner <lukas@wunner.de>
    Link: https://lore.kernel.org/r/20241018144755.7875-4-ilpo.jarvinen@linux.intel.com


Signed-off-by: default avatarIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
    [bhelgaas: move pcie_get_supported_speeds() decl to drivers/pci/pci.h]
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Reviewed-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>

Signed-off-by: default avatarMyron Stowe <mstowe@redhat.com>
parent 3db93976
No related branches found
No related tags found
No related merge requests found
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment