Author: hselasky
Date: Mon May 18 09:32:56 2020
New Revision: 361199
URL: https://svnweb.freebsd.org/changeset/base/361199

Log:
  MFC r345103:
  Implement more PCI speed related functions and macros in the LinuxKPI.
  
  Submitted by:         Johannes Lundberg <[email protected]>
  Sponsored by:         Limelight Networks
  Sponsored by:         Mellanox Technologies

Modified:
  stable/11/sys/compat/linuxkpi/common/include/linux/pci.h
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/compat/linuxkpi/common/include/linux/pci.h
==============================================================================
--- stable/11/sys/compat/linuxkpi/common/include/linux/pci.h    Mon May 18 
09:26:42 2020        (r361198)
+++ stable/11/sys/compat/linuxkpi/common/include/linux/pci.h    Mon May 18 
09:32:56 2020        (r361199)
@@ -141,10 +141,13 @@ struct pci_device_id {
 #define        PCI_EXP_TYPE_RC_EC      PCIEM_TYPE_ROOT_EC              /* Root 
Complex Event Collector */
 #define        PCI_EXP_LNKCAP_SLS_2_5GB 0x01   /* Supported Link Speed 2.5GT/s 
*/
 #define        PCI_EXP_LNKCAP_SLS_5_0GB 0x02   /* Supported Link Speed 5.0GT/s 
*/
+#define        PCI_EXP_LNKCAP_SLS_8_0GB 0x04   /* Supported Link Speed 8.0GT/s 
*/
+#define        PCI_EXP_LNKCAP_SLS_16_0GB 0x08  /* Supported Link Speed 
16.0GT/s */
 #define        PCI_EXP_LNKCAP_MLW      0x03f0  /* Maximum Link Width */
 #define        PCI_EXP_LNKCAP2_SLS_2_5GB 0x02  /* Supported Link Speed 2.5GT/s 
*/
 #define        PCI_EXP_LNKCAP2_SLS_5_0GB 0x04  /* Supported Link Speed 5.0GT/s 
*/
 #define        PCI_EXP_LNKCAP2_SLS_8_0GB 0x08  /* Supported Link Speed 8.0GT/s 
*/
+#define        PCI_EXP_LNKCAP2_SLS_16_0GB 0x10 /* Supported Link Speed 
16.0GT/s */
 
 #define PCI_EXP_LNKCTL_HAWD    PCIEM_LINK_CTL_HAWD
 #define PCI_EXP_LNKCAP_CLKPM   0x00040000
@@ -159,10 +162,19 @@ enum pci_bus_speed {
        PCIE_SPEED_2_5GT,
        PCIE_SPEED_5_0GT,
        PCIE_SPEED_8_0GT,
+       PCIE_SPEED_16_0GT,
 };
 
 enum pcie_link_width {
-       PCIE_LNK_WIDTH_UNKNOWN = 0xFF,
+       PCIE_LNK_WIDTH_RESRV    = 0x00,
+       PCIE_LNK_X1             = 0x01,
+       PCIE_LNK_X2             = 0x02,
+       PCIE_LNK_X4             = 0x04,
+       PCIE_LNK_X8             = 0x08,
+       PCIE_LNK_X12            = 0x0c,
+       PCIE_LNK_X16            = 0x10,
+       PCIE_LNK_X32            = 0x20,
+       PCIE_LNK_WIDTH_UNKNOWN  = 0xff,
 };
 
 typedef int pci_power_t;
@@ -895,6 +907,67 @@ static inline int
 pci_num_vf(struct pci_dev *dev)
 {
        return (0);
+}
+
+static inline enum pci_bus_speed
+pcie_get_speed_cap(struct pci_dev *dev)
+{
+       device_t root;
+       uint32_t lnkcap, lnkcap2;
+       int error, pos;
+
+       root = device_get_parent(dev->dev.bsddev);
+       if (root == NULL)
+               return (PCI_SPEED_UNKNOWN);
+       root = device_get_parent(root);
+       if (root == NULL)
+               return (PCI_SPEED_UNKNOWN);
+       root = device_get_parent(root);
+       if (root == NULL)
+               return (PCI_SPEED_UNKNOWN);
+
+       if (pci_get_vendor(root) == PCI_VENDOR_ID_VIA ||
+           pci_get_vendor(root) == PCI_VENDOR_ID_SERVERWORKS)
+               return (PCI_SPEED_UNKNOWN);
+
+       if ((error = pci_find_cap(root, PCIY_EXPRESS, &pos)) != 0)
+               return (PCI_SPEED_UNKNOWN);
+
+       lnkcap2 = pci_read_config(root, pos + PCIER_LINK_CAP2, 4);
+
+       if (lnkcap2) {  /* PCIe r3.0-compliant */
+               if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_2_5GB)
+                       return (PCIE_SPEED_2_5GT);
+               if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_5_0GB)
+                       return (PCIE_SPEED_5_0GT);
+               if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_8_0GB)
+                       return (PCIE_SPEED_8_0GT);
+               if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_16_0GB)
+                       return (PCIE_SPEED_16_0GT);
+       } else {        /* pre-r3.0 */
+               lnkcap = pci_read_config(root, pos + PCIER_LINK_CAP, 4);
+               if (lnkcap & PCI_EXP_LNKCAP_SLS_2_5GB)
+                       return (PCIE_SPEED_2_5GT);
+               if (lnkcap & PCI_EXP_LNKCAP_SLS_5_0GB)
+                       return (PCIE_SPEED_5_0GT);
+               if (lnkcap & PCI_EXP_LNKCAP_SLS_8_0GB)
+                       return (PCIE_SPEED_8_0GT);
+               if (lnkcap & PCI_EXP_LNKCAP_SLS_16_0GB)
+                       return (PCIE_SPEED_16_0GT);
+       }
+       return (PCI_SPEED_UNKNOWN);
+}
+
+static inline enum pcie_link_width
+pcie_get_width_cap(struct pci_dev *dev)
+{
+       uint32_t lnkcap;
+
+       pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnkcap);
+       if (lnkcap)
+               return ((lnkcap & PCI_EXP_LNKCAP_MLW) >> 4);
+
+       return (PCIE_LNK_WIDTH_UNKNOWN);
 }
 
 #endif /* _LINUX_PCI_H_ */
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to