Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 May 2020 09:32:56 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r361199 - stable/11/sys/compat/linuxkpi/common/include/linux
Message-ID:  <202005180932.04I9Wucb071045@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <johalun0@gmail.com>
  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_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202005180932.04I9Wucb071045>