From 7fdbba5e46120ad831725c7633c5dce5bd1f192e Mon Sep 17 00:00:00 2001 From: Ryan Stone Date: Sun, 1 Mar 2015 00:59:35 +0000 Subject: [PATCH] Teach pciconf how to dump out SR-IOV capability Differential Revision: https://reviews.freebsd.org/D1639 Reviewed by: jhb MFC after: 1 month Sponsored by: Sandvine Inc. --- usr.sbin/pciconf/cap.c | 79 ++++++++++++++++++++++++++++++++++---- usr.sbin/pciconf/pciconf.c | 77 ++++++++++++++++++++----------------- usr.sbin/pciconf/pciconf.h | 1 + 3 files changed, 115 insertions(+), 42 deletions(-) diff --git a/usr.sbin/pciconf/cap.c b/usr.sbin/pciconf/cap.c index bdcbe1d0079b..2e2e359fb825 100644 --- a/usr.sbin/pciconf/cap.c +++ b/usr.sbin/pciconf/cap.c @@ -37,6 +37,7 @@ static const char rcsid[] = #include #include +#include #include #include @@ -636,7 +637,7 @@ ecap_aer(int fd, struct pci_conf *p, uint16_t ptr, uint8_t ver) 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 @@ -652,6 +653,7 @@ ecap_vc(int fd, struct pci_conf *p, uint16_t ptr, uint8_t ver) 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 @@ -664,7 +666,7 @@ ecap_sernum(int fd, struct pci_conf *p, uint16_t ptr, uint8_t ver) 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 @@ -676,7 +678,7 @@ ecap_vendor(int fd, struct pci_conf *p, uint16_t ptr, uint8_t ver) 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 @@ -688,7 +690,69 @@ ecap_sec_pcie(int fd, struct pci_conf *p, uint16_t ptr, uint8_t ver) 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 { @@ -704,7 +768,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" }, @@ -743,6 +806,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++) @@ -750,10 +816,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; diff --git a/usr.sbin/pciconf/pciconf.c b/usr.sbin/pciconf/pciconf.c index 33fe95db57f3..31b388078e7c 100644 --- a/usr.sbin/pciconf/pciconf.c +++ b/usr.sbin/pciconf/pciconf.c @@ -263,10 +263,7 @@ list_devs(const char *name, int verbose, int bars, int caps, int errors, 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 diff --git a/usr.sbin/pciconf/pciconf.h b/usr.sbin/pciconf/pciconf.h index 042c4a1bc234..734007eba920 100644 --- a/usr.sbin/pciconf/pciconf.h +++ b/usr.sbin/pciconf/pciconf.h @@ -37,6 +37,7 @@ void list_caps(int fd, struct pci_conf *p); 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