]> git.ipfire.org Git - thirdparty/linux.git/blobdiff - drivers/pci/pci.c
Merge tag 'cxl-for-6.8' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl
[thirdparty/linux.git] / drivers / pci / pci.c
index 43e11c9502d1bab04a36130a744ea9c3174b4d15..d8f11a078924c1336326456b0e3f37f7b0e66df9 100644 (file)
@@ -6295,6 +6295,41 @@ int pcie_set_mps(struct pci_dev *dev, int mps)
 }
 EXPORT_SYMBOL(pcie_set_mps);
 
+static enum pci_bus_speed to_pcie_link_speed(u16 lnksta)
+{
+       return pcie_link_speed[FIELD_GET(PCI_EXP_LNKSTA_CLS, lnksta)];
+}
+
+int pcie_link_speed_mbps(struct pci_dev *pdev)
+{
+       u16 lnksta;
+       int err;
+
+       err = pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnksta);
+       if (err)
+               return err;
+
+       switch (to_pcie_link_speed(lnksta)) {
+       case PCIE_SPEED_2_5GT:
+               return 2500;
+       case PCIE_SPEED_5_0GT:
+               return 5000;
+       case PCIE_SPEED_8_0GT:
+               return 8000;
+       case PCIE_SPEED_16_0GT:
+               return 16000;
+       case PCIE_SPEED_32_0GT:
+               return 32000;
+       case PCIE_SPEED_64_0GT:
+               return 64000;
+       default:
+               break;
+       }
+
+       return -EINVAL;
+}
+EXPORT_SYMBOL(pcie_link_speed_mbps);
+
 /**
  * pcie_bandwidth_available - determine minimum link settings of a PCIe
  *                           device and its bandwidth limitation
@@ -6328,8 +6363,7 @@ u32 pcie_bandwidth_available(struct pci_dev *dev, struct pci_dev **limiting_dev,
        while (dev) {
                pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnksta);
 
-               next_speed = pcie_link_speed[FIELD_GET(PCI_EXP_LNKSTA_CLS,
-                                                      lnksta)];
+               next_speed = to_pcie_link_speed(lnksta);
                next_width = FIELD_GET(PCI_EXP_LNKSTA_NLW, lnksta);
 
                next_bw = next_width * PCIE_SPEED2MBS_ENC(next_speed);