PCI: Make link active reporting detection generic
authorKeith Busch <keith.busch@intel.com>
Thu, 20 Sep 2018 16:27:17 +0000 (10:27 -0600)
committerBjorn Helgaas <bhelgaas@google.com>
Tue, 2 Oct 2018 21:04:40 +0000 (16:04 -0500)
The spec has timing requirements when waiting for a link to become active
after a conventional reset.  Implement those hard delays when waiting for
an active link so pciehp and dpc drivers don't need to duplicate this.

For devices that don't support data link layer active reporting, wait the
fixed time recommended by the PCIe spec.

Signed-off-by: Keith Busch <keith.busch@intel.com>
[bhelgaas: changelog]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Sinan Kaya <okaya@kernel.org>
drivers/pci/hotplug/pciehp.h
drivers/pci/hotplug/pciehp_hpc.c
drivers/pci/pci.c
drivers/pci/pcie/dpc.c
drivers/pci/probe.c
include/linux/pci.h

index 3740f1a759c548d2600be86420bcb1dfd3340739..75fd52571107d36e09f82326cb2ec0f148ace0f8 100644 (file)
@@ -62,11 +62,6 @@ do {                                                                 \
  * struct controller - PCIe hotplug controller
  * @pcie: pointer to the controller's PCIe port service device
  * @slot_cap: cached copy of the Slot Capabilities register
- * @link_active_reporting: cached copy of Data Link Layer Link Active Reporting
- *     Capable bit in Link Capabilities register; if this bit is zero, the
- *     Data Link Layer Link Active bit in the Link Status register will never
- *     be set and the driver is thus confined to wait 1 second before assuming
- *     the link to a hotplugged device is up and accessing it
  * @slot_ctrl: cached copy of the Slot Control register
  * @ctrl_lock: serializes writes to the Slot Control register
  * @cmd_started: jiffies when the Slot Control register was last written;
@@ -103,7 +98,6 @@ struct controller {
        struct pcie_device *pcie;
 
        u32 slot_cap;                           /* capabilities and quirks */
-       unsigned int link_active_reporting:1;
 
        u16 slot_ctrl;                          /* control register access */
        struct mutex ctrl_lock;
index 7b5f9db60d9a8ad781025ddea481771d2b0fb862..f0f3f4a3dac413575e1ab5d658b688381b506850 100644 (file)
@@ -214,13 +214,6 @@ bool pciehp_check_link_active(struct controller *ctrl)
        return ret;
 }
 
-static void pcie_wait_link_active(struct controller *ctrl)
-{
-       struct pci_dev *pdev = ctrl_dev(ctrl);
-
-       pcie_wait_for_link(pdev, true);
-}
-
 static bool pci_bus_check_dev(struct pci_bus *bus, int devfn)
 {
        u32 l;
@@ -253,18 +246,9 @@ int pciehp_check_link_status(struct controller *ctrl)
        bool found;
        u16 lnk_status;
 
-       /*
-        * Data Link Layer Link Active Reporting must be capable for
-        * hot-plug capable downstream port. But old controller might
-        * not implement it. In this case, we wait for 1000 ms.
-       */
-       if (ctrl->link_active_reporting)
-               pcie_wait_link_active(ctrl);
-       else
-               msleep(1000);
+       if (!pcie_wait_for_link(pdev, true))
+               return -1;
 
-       /* wait 100ms before read pci conf, and try in 1s */
-       msleep(100);
        found = pci_bus_check_dev(ctrl->pcie->port->subordinate,
                                        PCI_DEVFN(0, 0));
 
@@ -865,8 +849,6 @@ struct controller *pcie_init(struct pcie_device *dev)
 
        /* Check if Data Link Layer Link Active Reporting is implemented */
        pcie_capability_read_dword(pdev, PCI_EXP_LNKCAP, &link_cap);
-       if (link_cap & PCI_EXP_LNKCAP_DLLLARC)
-               ctrl->link_active_reporting = 1;
 
        /* Clear all remaining event bits in Slot Status register. */
        pcie_capability_write_word(pdev, PCI_EXP_SLTSTA,
index 6916af269b19739cbc6b4aafc28d16d2c3dd01c4..4b0b1d0548f0c0fda9b58dcd04f7a3586df55c0a 100644 (file)
@@ -4489,21 +4489,42 @@ bool pcie_wait_for_link(struct pci_dev *pdev, bool active)
        bool ret;
        u16 lnk_status;
 
+       /*
+        * Some controllers might not implement link active reporting. In this
+        * case, we wait for 1000 + 100 ms.
+        */
+       if (!pdev->link_active_reporting) {
+               msleep(1100);
+               return true;
+       }
+
+       /*
+        * PCIe r4.0 sec 6.6.1, a component must enter LTSSM Detect within 20ms,
+        * after which we should expect an link active if the reset was
+        * successful. If so, software must wait a minimum 100ms before sending
+        * configuration requests to devices downstream this port.
+        *
+        * If the link fails to activate, either the device was physically
+        * removed or the link is permanently failed.
+        */
+       if (active)
+               msleep(20);
        for (;;) {
                pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnk_status);
                ret = !!(lnk_status & PCI_EXP_LNKSTA_DLLLA);
                if (ret == active)
-                       return true;
+                       break;
                if (timeout <= 0)
                        break;
                msleep(10);
                timeout -= 10;
        }
-
-       pci_info(pdev, "Data Link Layer Link Active not %s in 1000 msec\n",
-                active ? "set" : "cleared");
-
-       return false;
+       if (active && ret)
+               msleep(100);
+       else if (ret != active)
+               pci_info(pdev, "Data Link Layer Link Active not %s in 1000 msec\n",
+                       active ? "set" : "cleared");
+       return ret == active;
 }
 
 void pci_reset_secondary_bus(struct pci_dev *dev)
index 23e063aefddfa9983615b6bef01c3e82d01113d7..e435d12e61a03bfdf2034f02b92c33db2327b6f9 100644 (file)
@@ -140,10 +140,12 @@ static pci_ers_result_t dpc_reset_link(struct pci_dev *pdev)
        pci_write_config_word(pdev, cap + PCI_EXP_DPC_STATUS,
                              PCI_EXP_DPC_STATUS_TRIGGER);
 
+       if (!pcie_wait_for_link(pdev, true))
+               return PCI_ERS_RESULT_DISCONNECT;
+
        return PCI_ERS_RESULT_RECOVERED;
 }
 
-
 static void dpc_process_rp_pio_error(struct dpc_dev *dpc)
 {
        struct device *dev = &dpc->dev->device;
index 201f9e5ff55c0a97e330d9dcf139f8d2cd96bad1..bb2999d1b199a0b46a59374a1d68e521e4edf4bb 100644 (file)
@@ -713,6 +713,7 @@ static void pci_set_bus_speed(struct pci_bus *bus)
 
                pcie_capability_read_dword(bridge, PCI_EXP_LNKCAP, &linkcap);
                bus->max_bus_speed = pcie_link_speed[linkcap & PCI_EXP_LNKCAP_SLS];
+               bridge->link_active_reporting = !!(linkcap & PCI_EXP_LNKCAP_DLLLARC);
 
                pcie_capability_read_word(bridge, PCI_EXP_LNKSTA, &linksta);
                pcie_update_link_speed(bus, linksta);
index 6925828f9f250fae21e19ef8338d46694621e2a2..896b42032ec5df0cc3d7475ea74882104e7e0ec7 100644 (file)
@@ -402,6 +402,7 @@ struct pci_dev {
        unsigned int    has_secondary_link:1;
        unsigned int    non_compliant_bars:1;   /* Broken BARs; ignore them */
        unsigned int    is_probed:1;            /* Device probing in progress */
+       unsigned int    link_active_reporting:1;/* Device capable of reporting link active */
        pci_dev_flags_t dev_flags;
        atomic_t        enable_cnt;     /* pci_enable_device has been called */