]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
PCI: pci-bridge-emul: Correctly set PCIe capabilities
authorPali Rohár <pali@kernel.org>
Wed, 24 Nov 2021 15:59:43 +0000 (16:59 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 27 Jan 2022 08:19:50 +0000 (09:19 +0100)
commit 1f1050c5e1fefb34ac90a506b43e9da803b5f8f7 upstream.

Older mvebu hardware provides PCIe Capability structure only in version 1.
New mvebu and aardvark hardware provides it in version 2. So do not force
version to 2 in pci_bridge_emul_init() and rather allow drivers to set
correct version. Drivers need to set version in pcie_conf.cap field without
overwriting PCI_CAP_LIST_ID register. Both drivers (mvebu and aardvark) do
not provide slot support yet, so do not set PCI_EXP_FLAGS_SLOT flag.

Link: https://lore.kernel.org/r/20211124155944.1290-6-pali@kernel.org
Fixes: 23a5fba4d941 ("PCI: Introduce PCI bridge emulated config space common logic")
Signed-off-by: Pali Rohár <pali@kernel.org>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/pci/controller/pci-aardvark.c
drivers/pci/controller/pci-mvebu.c
drivers/pci/pci-bridge-emul.c

index 9e208294946cd15838678cd5f04b025316ee16db..d2f8cd3a9568b1f48c072afa040cbc0d8e29c081 100644 (file)
@@ -863,7 +863,6 @@ advk_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge,
                return PCI_BRIDGE_EMUL_HANDLED;
        }
 
-       case PCI_CAP_LIST_ID:
        case PCI_EXP_DEVCAP:
        case PCI_EXP_DEVCTL:
                *value = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + reg);
@@ -944,6 +943,9 @@ static int advk_sw_pci_bridge_init(struct advk_pcie *pcie)
        /* Support interrupt A for MSI feature */
        bridge->conf.intpin = PCIE_CORE_INT_A_ASSERT_ENABLE;
 
+       /* Aardvark HW provides PCIe Capability structure in version 2 */
+       bridge->pcie_conf.cap = cpu_to_le16(2);
+
        /* Indicates supports for Completion Retry Status */
        bridge->pcie_conf.rootcap = cpu_to_le16(PCI_EXP_RTCAP_CRSVIS);
 
index 5a2483e125a3fea92cf3782b14449e40ca2763ee..09af97083ac090f60088f5f5bdab368a16c42844 100644 (file)
@@ -576,6 +576,8 @@ struct pci_bridge_emul_ops mvebu_pci_bridge_emul_ops = {
 static void mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port)
 {
        struct pci_bridge_emul *bridge = &port->bridge;
+       u32 pcie_cap = mvebu_readl(port, PCIE_CAP_PCIEXP);
+       u8 pcie_cap_ver = ((pcie_cap >> 16) & PCI_EXP_FLAGS_VERS);
 
        bridge->conf.vendor = PCI_VENDOR_ID_MARVELL;
        bridge->conf.device = mvebu_readl(port, PCIE_DEV_ID_OFF) >> 16;
@@ -588,6 +590,12 @@ static void mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port)
                bridge->conf.iolimit = PCI_IO_RANGE_TYPE_32;
        }
 
+       /*
+        * Older mvebu hardware provides PCIe Capability structure only in
+        * version 1. New hardware provides it in version 2.
+        */
+       bridge->pcie_conf.cap = cpu_to_le16(pcie_cap_ver);
+
        bridge->has_pcie = true;
        bridge->data = port;
        bridge->ops = &mvebu_pci_bridge_emul_ops;
index e47eb2a89579e8b6b4c334989feda9c7b8b6fe63..16daf40ab5556a11f87ac329528f8301ceee4065 100644 (file)
@@ -288,10 +288,7 @@ int pci_bridge_emul_init(struct pci_bridge_emul *bridge,
        if (bridge->has_pcie) {
                bridge->conf.capabilities_pointer = PCI_CAP_PCIE_START;
                bridge->pcie_conf.cap_id = PCI_CAP_ID_EXP;
-               /* Set PCIe v2, root port, slot support */
-               bridge->pcie_conf.cap =
-                       cpu_to_le16(PCI_EXP_TYPE_ROOT_PORT << 4 | 2 |
-                                   PCI_EXP_FLAGS_SLOT);
+               bridge->pcie_conf.cap |= cpu_to_le16(PCI_EXP_TYPE_ROOT_PORT << 4);
                bridge->pcie_cap_regs_behavior =
                        kmemdup(pcie_cap_regs_behavior,
                                sizeof(pcie_cap_regs_behavior),