Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 3 Jan 2016 06:38:50 +0000 (UTC)
From:      Garrett Cooper <ngie@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r293077 - in user/ngie/stable-10-libnv: sys/dev/pci sys/kern sys/sys usr.sbin/pciconf
Message-ID:  <201601030638.u036coIL079674@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ngie
Date: Sun Jan  3 06:38:50 2016
New Revision: 293077
URL: https://svnweb.freebsd.org/changeset/base/293077

Log:
  MFC r279466,r279868:
  
  r279466 (by rstone):
  
  Teach pciconf how to dump out SR-IOV capability
  
  r279868 (by rstone):
  
  Fix SR-IOV passthrough devices to allow ppt to attach
  
  A late change to the SR-IOV infrastructure broke passthrough of
  VFs.  device_set_devclass() was being used to try to force the
  ppt driver to attach to the device, but this didn't work because
  the DF_FIXEDCLASS flag wasn't being set on the device, so the
  ppt driver probe routine would not match when it returned
  BUS_NOWILDCARD.  Fix this by adding a new device function that
  both sets the devclass and sets the DF_FIXEDCLASS flag, and use
  that to force the ppt driver to attach to VFs.

Modified:
  user/ngie/stable-10-libnv/sys/dev/pci/pci_iov.c
  user/ngie/stable-10-libnv/sys/kern/subr_bus.c
  user/ngie/stable-10-libnv/sys/sys/bus.h
  user/ngie/stable-10-libnv/usr.sbin/pciconf/cap.c
  user/ngie/stable-10-libnv/usr.sbin/pciconf/pciconf.c
  user/ngie/stable-10-libnv/usr.sbin/pciconf/pciconf.h
Directory Properties:
  user/ngie/stable-10-libnv/   (props changed)

Modified: user/ngie/stable-10-libnv/sys/dev/pci/pci_iov.c
==============================================================================
--- user/ngie/stable-10-libnv/sys/dev/pci/pci_iov.c	Sun Jan  3 06:33:46 2016	(r293076)
+++ user/ngie/stable-10-libnv/sys/dev/pci/pci_iov.c	Sun Jan  3 06:38:50 2016	(r293077)
@@ -582,7 +582,7 @@ pci_iov_enumerate_vfs(struct pci_devinfo
 		 * VFs.
 		 */
 		if (nvlist_get_bool(iov_config, "passthrough"))
-			device_set_devclass(vf, "ppt");
+			device_set_devclass_fixed(vf, "ppt");
 
 		vfinfo = device_get_ivars(vf);
 

Modified: user/ngie/stable-10-libnv/sys/kern/subr_bus.c
==============================================================================
--- user/ngie/stable-10-libnv/sys/kern/subr_bus.c	Sun Jan  3 06:33:46 2016	(r293076)
+++ user/ngie/stable-10-libnv/sys/kern/subr_bus.c	Sun Jan  3 06:38:50 2016	(r293077)
@@ -2679,6 +2679,25 @@ device_set_devclass(device_t dev, const 
 }
 
 /**
+ * @brief Set the devclass of a device and mark the devclass fixed.
+ * @see device_set_devclass()
+ */
+int
+device_set_devclass_fixed(device_t dev, const char *classname)
+{
+	int error;
+
+	if (classname == NULL)
+		return (EINVAL);
+
+	error = device_set_devclass(dev, classname);
+	if (error)
+		return (error);
+	dev->flags |= DF_FIXEDCLASS;
+	return (0);
+}
+
+/**
  * @brief Set the driver of a device
  *
  * @retval 0		success

Modified: user/ngie/stable-10-libnv/sys/sys/bus.h
==============================================================================
--- user/ngie/stable-10-libnv/sys/sys/bus.h	Sun Jan  3 06:33:46 2016	(r293076)
+++ user/ngie/stable-10-libnv/sys/sys/bus.h	Sun Jan  3 06:38:50 2016	(r293077)
@@ -465,6 +465,7 @@ void	device_quiet(device_t dev);
 void	device_set_desc(device_t dev, const char* desc);
 void	device_set_desc_copy(device_t dev, const char* desc);
 int	device_set_devclass(device_t dev, const char *classname);
+int	device_set_devclass_fixed(device_t dev, const char *classname);
 int	device_set_driver(device_t dev, driver_t *driver);
 void	device_set_flags(device_t dev, u_int32_t flags);
 void	device_set_softc(device_t dev, void *softc);

Modified: user/ngie/stable-10-libnv/usr.sbin/pciconf/cap.c
==============================================================================
--- user/ngie/stable-10-libnv/usr.sbin/pciconf/cap.c	Sun Jan  3 06:33:46 2016	(r293076)
+++ user/ngie/stable-10-libnv/usr.sbin/pciconf/cap.c	Sun Jan  3 06:38:50 2016	(r293077)
@@ -37,6 +37,7 @@ static const char rcsid[] =
 
 #include <err.h>
 #include <stdio.h>
+#include <strings.h>
 #include <sys/agpio.h>
 #include <sys/pciio.h>
 
@@ -640,7 +641,7 @@ ecap_aer(int fd, struct pci_conf *p, uin
 	printf(" %d fatal", bitcount32(sta & mask));
 	printf(" %d non-fatal", bitcount32(sta & ~mask));
 	sta = read_config(fd, &p->pc_sel, ptr + PCIR_AER_COR_STATUS, 4);
-	printf(" %d corrected", bitcount32(sta));
+	printf(" %d corrected\n", bitcount32(sta));
 }
 
 static void
@@ -656,6 +657,7 @@ ecap_vc(int fd, struct pci_conf *p, uint
 	if ((cap1 & PCIM_VC_CAP1_LOWPRI_EXT_COUNT) != 0)
 		printf(" lowpri VC0-VC%d",
 		    (cap1 & PCIM_VC_CAP1_LOWPRI_EXT_COUNT) >> 4);
+	printf("\n");
 }
 
 static void
@@ -668,7 +670,7 @@ ecap_sernum(int fd, struct pci_conf *p, 
 		return;
 	low = read_config(fd, &p->pc_sel, ptr + PCIR_SERIAL_LOW, 4);
 	high = read_config(fd, &p->pc_sel, ptr + PCIR_SERIAL_HIGH, 4);
-	printf(" %08x%08x", high, low);
+	printf(" %08x%08x\n", high, low);
 }
 
 static void
@@ -680,7 +682,7 @@ ecap_vendor(int fd, struct pci_conf *p, 
 	if (ver < 1)
 		return;
 	val = read_config(fd, &p->pc_sel, ptr + 4, 4);
-	printf(" ID %d", val & 0xffff);
+	printf(" ID %d\n", val & 0xffff);
 }
 
 static void
@@ -692,7 +694,69 @@ ecap_sec_pcie(int fd, struct pci_conf *p
 	if (ver < 1)
 		return;
 	val = read_config(fd, &p->pc_sel, ptr + 8, 4);
-	printf(" lane errors %#x", val);
+	printf(" lane errors %#x\n", val);
+}
+
+static const char *
+check_enabled(int value)
+{
+
+	return (value ? "enabled" : "disabled");
+}
+
+static void
+ecap_sriov(int fd, struct pci_conf *p, uint16_t ptr, uint8_t ver)
+{
+	const char *comma, *enabled;
+	uint16_t iov_ctl, total_vfs, num_vfs, vf_offset, vf_stride, vf_did;
+	uint32_t page_caps, page_size, page_shift, size;
+	int i;
+
+	printf("SR-IOV %d ", ver);
+
+	iov_ctl = read_config(fd, &p->pc_sel, ptr + PCIR_SRIOV_CTL, 2);
+	printf("IOV %s, Memory Space %s, ARI %s\n",
+	    check_enabled(iov_ctl & PCIM_SRIOV_VF_EN),
+	    check_enabled(iov_ctl & PCIM_SRIOV_VF_MSE),
+	    check_enabled(iov_ctl & PCIM_SRIOV_ARI_EN));
+
+	total_vfs = read_config(fd, &p->pc_sel, ptr + PCIR_SRIOV_TOTAL_VFS, 2);
+	num_vfs = read_config(fd, &p->pc_sel, ptr + PCIR_SRIOV_NUM_VFS, 2);
+	printf("                     ");
+	printf("%d VFs configured out of %d supported\n", num_vfs, total_vfs);
+
+	vf_offset = read_config(fd, &p->pc_sel, ptr + PCIR_SRIOV_VF_OFF, 2);
+	vf_stride = read_config(fd, &p->pc_sel, ptr + PCIR_SRIOV_VF_STRIDE, 2);
+	printf("                     ");
+	printf("First VF RID Offset 0x%04x, VF RID Stride 0x%04x\n", vf_offset,
+	    vf_stride);
+
+	vf_did = read_config(fd, &p->pc_sel, ptr + PCIR_SRIOV_VF_DID, 2);
+	printf("                     VF Device ID 0x%04x\n", vf_did);
+
+	page_caps = read_config(fd, &p->pc_sel, ptr + PCIR_SRIOV_PAGE_CAP, 4);
+	page_size = read_config(fd, &p->pc_sel, ptr + PCIR_SRIOV_PAGE_SIZE, 4);
+	printf("                     ");
+	printf("Page Sizes: ");
+	comma = "";
+	while (page_caps != 0) {
+		page_shift = ffs(page_caps) - 1;
+
+		if (page_caps & page_size)
+			enabled = " (enabled)";
+		else
+			enabled = "";
+
+		size = (1 << (page_shift + PCI_SRIOV_BASE_PAGE_SHIFT));
+		printf("%s%d%s", comma, size, enabled);
+		comma = ", ";
+
+		page_caps &= ~(1 << page_shift);
+	}
+	printf("\n");
+
+	for (i = 0; i <= PCIR_MAX_BAR_0; i++)
+		print_bar(fd, p, "iov bar  ", ptr + PCIR_SRIOV_BAR(i));
 }
 
 struct {
@@ -708,7 +772,6 @@ struct {
 	{ PCIZ_ACS, "ACS" },
 	{ PCIZ_ARI, "ARI" },
 	{ PCIZ_ATS, "ATS" },
-	{ PCIZ_SRIOV, "SRIOV" },
 	{ PCIZ_MULTICAST, "Multicast" },
 	{ PCIZ_RESIZE_BAR, "Resizable BAR" },
 	{ PCIZ_DPA, "DPA" },
@@ -747,6 +810,9 @@ list_ecaps(int fd, struct pci_conf *p)
 		case PCIZ_SEC_PCIE:
 			ecap_sec_pcie(fd, p, ptr, PCI_EXTCAP_VER(ecap));
 			break;
+		case PCIZ_SRIOV:
+			ecap_sriov(fd, p, ptr, PCI_EXTCAP_VER(ecap));
+			break;
 		default:
 			name = "unknown";
 			for (i = 0; ecap_names[i].name != NULL; i++)
@@ -754,10 +820,9 @@ list_ecaps(int fd, struct pci_conf *p)
 					name = ecap_names[i].name;
 					break;
 				}
-			printf("%s %d", name, PCI_EXTCAP_VER(ecap));
+			printf("%s %d\n", name, PCI_EXTCAP_VER(ecap));
 			break;
 		}
-		printf("\n");
 		ptr = PCI_EXTCAP_NEXTPTR(ecap);
 		if (ptr == 0)
 			break;

Modified: user/ngie/stable-10-libnv/usr.sbin/pciconf/pciconf.c
==============================================================================
--- user/ngie/stable-10-libnv/usr.sbin/pciconf/pciconf.c	Sun Jan  3 06:33:46 2016	(r293076)
+++ user/ngie/stable-10-libnv/usr.sbin/pciconf/pciconf.c	Sun Jan  3 06:38:50 2016	(r293077)
@@ -263,10 +263,7 @@ list_devs(const char *name, int verbose,
 static void
 list_bars(int fd, struct pci_conf *p)
 {
-	struct pci_bar_io bar;
-	uint64_t base;
-	const char *type;
-	int i, range, max;
+	int i, max;
 
 	switch (p->pc_hdr & PCIM_HDRTYPE) {
 	case PCIM_HDRTYPE_NORMAL:
@@ -282,40 +279,50 @@ list_bars(int fd, struct pci_conf *p)
 		return;
 	}
 
-	for (i = 0; i <= max; i++) {
-		bar.pbi_sel = p->pc_sel;
-		bar.pbi_reg = PCIR_BAR(i);
-		if (ioctl(fd, PCIOCGETBAR, &bar) < 0)
-			continue;
-		if (PCI_BAR_IO(bar.pbi_base)) {
-			type = "I/O Port";
+	for (i = 0; i <= max; i++)
+		print_bar(fd, p, "bar   ", PCIR_BAR(i));
+}
+
+void
+print_bar(int fd, struct pci_conf *p, const char *label, uint16_t bar_offset)
+{
+	uint64_t base;
+	const char *type;
+	struct pci_bar_io bar;
+	int range;
+
+	bar.pbi_sel = p->pc_sel;
+	bar.pbi_reg = bar_offset;
+	if (ioctl(fd, PCIOCGETBAR, &bar) < 0)
+		return;
+	if (PCI_BAR_IO(bar.pbi_base)) {
+		type = "I/O Port";
+		range = 32;
+		base = bar.pbi_base & PCIM_BAR_IO_BASE;
+	} else {
+		if (bar.pbi_base & PCIM_BAR_MEM_PREFETCH)
+			type = "Prefetchable Memory";
+		else
+			type = "Memory";
+		switch (bar.pbi_base & PCIM_BAR_MEM_TYPE) {
+		case PCIM_BAR_MEM_32:
 			range = 32;
-			base = bar.pbi_base & PCIM_BAR_IO_BASE;
-		} else {
-			if (bar.pbi_base & PCIM_BAR_MEM_PREFETCH)
-				type = "Prefetchable Memory";
-			else
-				type = "Memory";
-			switch (bar.pbi_base & PCIM_BAR_MEM_TYPE) {
-			case PCIM_BAR_MEM_32:
-				range = 32;
-				break;
-			case PCIM_BAR_MEM_1MB:
-				range = 20;
-				break;
-			case PCIM_BAR_MEM_64:
-				range = 64;
-				break;
-			default:
-				range = -1;
-			}
-			base = bar.pbi_base & ~((uint64_t)0xf);
+			break;
+		case PCIM_BAR_MEM_1MB:
+			range = 20;
+			break;
+		case PCIM_BAR_MEM_64:
+			range = 64;
+			break;
+		default:
+			range = -1;
 		}
-		printf("    bar   [%02x] = type %s, range %2d, base %#jx, ",
-		    PCIR_BAR(i), type, range, (uintmax_t)base);
-		printf("size %ju, %s\n", (uintmax_t)bar.pbi_length,
-		    bar.pbi_enabled ? "enabled" : "disabled");
+		base = bar.pbi_base & ~((uint64_t)0xf);
 	}
+	printf("    %s[%02x] = type %s, range %2d, base %#jx, ",
+	    label, bar_offset, type, range, (uintmax_t)base);
+	printf("size %ju, %s\n", (uintmax_t)bar.pbi_length,
+	    bar.pbi_enabled ? "enabled" : "disabled");
 }
 
 static void

Modified: user/ngie/stable-10-libnv/usr.sbin/pciconf/pciconf.h
==============================================================================
--- user/ngie/stable-10-libnv/usr.sbin/pciconf/pciconf.h	Sun Jan  3 06:33:46 2016	(r293076)
+++ user/ngie/stable-10-libnv/usr.sbin/pciconf/pciconf.h	Sun Jan  3 06:38:50 2016	(r293077)
@@ -37,6 +37,7 @@ void	list_caps(int fd, struct pci_conf *
 void	list_errors(int fd, struct pci_conf *p);
 uint8_t	pci_find_cap(int fd, struct pci_conf *p, uint8_t id);
 uint16_t pcie_find_cap(int fd, struct pci_conf *p, uint16_t id);
+void	print_bar(int fd, struct pci_conf *p, const char *label,  uint16_t bar);
 uint32_t read_config(int fd, struct pcisel *sel, long reg, int width);
 
 #endif



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