summaryrefslogtreecommitdiff
path: root/target/linux/bcm53xx/patches-4.3/144-PCI-iproc-Improve-link-detection-logic.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/bcm53xx/patches-4.3/144-PCI-iproc-Improve-link-detection-logic.patch')
-rw-r--r--target/linux/bcm53xx/patches-4.3/144-PCI-iproc-Improve-link-detection-logic.patch84
1 files changed, 84 insertions, 0 deletions
diff --git a/target/linux/bcm53xx/patches-4.3/144-PCI-iproc-Improve-link-detection-logic.patch b/target/linux/bcm53xx/patches-4.3/144-PCI-iproc-Improve-link-detection-logic.patch
new file mode 100644
index 0000000..3fecba2
--- /dev/null
+++ b/target/linux/bcm53xx/patches-4.3/144-PCI-iproc-Improve-link-detection-logic.patch
@@ -0,0 +1,84 @@
+From aaf22ab4e916afa68a2e1aed4e913b76cbd58276 Mon Sep 17 00:00:00 2001
+From: Ray Jui <rjui@broadcom.com>
+Date: Tue, 15 Sep 2015 17:39:19 -0700
+Subject: [PATCH 144/147] PCI: iproc: Improve link detection logic
+
+Improve the link detection logic by explicitly querying the link status
+register to ensure link is active.
+
+Also force class to PCI_CLASS_BRIDGE_PCI (0x0604) through the host
+configuration space register.
+
+Signed-off-by: Ray Jui <rjui@broadcom.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Anup Patel <anup.patel@broadcom.com>
+Reviewed-by: Scott Branden <sbranden@broadcom.com>
+---
+ drivers/pci/host/pcie-iproc.c | 29 +++++++++++++++++++++++------
+ 1 file changed, 23 insertions(+), 6 deletions(-)
+
+--- a/drivers/pci/host/pcie-iproc.c
++++ b/drivers/pci/host/pcie-iproc.c
+@@ -60,6 +60,12 @@
+ #define SYS_RC_INTX_EN 0x330
+ #define SYS_RC_INTX_MASK 0xf
+
++#define PCIE_LINK_STATUS_OFFSET 0xf0c
++#define PCIE_PHYLINKUP_SHIFT 3
++#define PCIE_PHYLINKUP BIT(PCIE_PHYLINKUP_SHIFT)
++#define PCIE_DL_ACTIVE_SHIFT 2
++#define PCIE_DL_ACTIVE BIT(PCIE_DL_ACTIVE_SHIFT)
++
+ static inline struct iproc_pcie *iproc_data(struct pci_bus *bus)
+ {
+ struct iproc_pcie *pcie;
+@@ -138,9 +144,15 @@ static void iproc_pcie_reset(struct ipro
+ static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus)
+ {
+ u8 hdr_type;
+- u32 link_ctrl;
++ u32 link_ctrl, class, val;
+ u16 pos, link_status;
+- int link_is_active = 0;
++ bool link_is_active = false;
++
++ val = readl(pcie->base + PCIE_LINK_STATUS_OFFSET);
++ if (!(val & PCIE_PHYLINKUP) || !(val & PCIE_DL_ACTIVE)) {
++ dev_err(pcie->dev, "PHY or data link is INACTIVE!\n");
++ return -ENODEV;
++ }
+
+ /* make sure we are not in EP mode */
+ pci_bus_read_config_byte(bus, 0, PCI_HEADER_TYPE, &hdr_type);
+@@ -150,14 +162,19 @@ static int iproc_pcie_check_link(struct
+ }
+
+ /* force class to PCI_CLASS_BRIDGE_PCI (0x0604) */
+- pci_bus_write_config_word(bus, 0, PCI_CLASS_DEVICE,
+- PCI_CLASS_BRIDGE_PCI);
++#define PCI_BRIDGE_CTRL_REG_OFFSET 0x43c
++#define PCI_CLASS_BRIDGE_MASK 0xffff00
++#define PCI_CLASS_BRIDGE_SHIFT 8
++ pci_bus_read_config_dword(bus, 0, PCI_BRIDGE_CTRL_REG_OFFSET, &class);
++ class &= ~PCI_CLASS_BRIDGE_MASK;
++ class |= (PCI_CLASS_BRIDGE_PCI << PCI_CLASS_BRIDGE_SHIFT);
++ pci_bus_write_config_dword(bus, 0, PCI_BRIDGE_CTRL_REG_OFFSET, class);
+
+ /* check link status to see if link is active */
+ pos = pci_bus_find_capability(bus, 0, PCI_CAP_ID_EXP);
+ pci_bus_read_config_word(bus, 0, pos + PCI_EXP_LNKSTA, &link_status);
+ if (link_status & PCI_EXP_LNKSTA_NLW)
+- link_is_active = 1;
++ link_is_active = true;
+
+ if (!link_is_active) {
+ /* try GEN 1 link speed */
+@@ -181,7 +198,7 @@ static int iproc_pcie_check_link(struct
+ pci_bus_read_config_word(bus, 0, pos + PCI_EXP_LNKSTA,
+ &link_status);
+ if (link_status & PCI_EXP_LNKSTA_NLW)
+- link_is_active = 1;
++ link_is_active = true;
+ }
+ }
+