Module Name: src Committed By: msaitoh Date: Sat Jan 1 03:27:53 UTC 2022
Modified Files: src/sys/dev/pci: pci_subr.c pcireg.h Log Message: Print Physical Layer 16.0 GT/s and Lane Margining at the Receiver extended cap. - Decode Physical Layer 16.0 GT/s extended capability. - Decode Lane Margining at the Receiver extended capability. - Rename pcie_link_compliance_preset_deemphasis to pcie_link_preset_preshoot_deemphasis because the table is referenced from multiple places. - Print "reserved" instead of "unknown" when printing equalization preset. One of them is known to be the default value. - Rename PCI_EXTCAP_PYSLAY_16GT to PCI_EXTCAP_PL16G. To generate a diff of this commit: cvs rdiff -u -r1.235 -r1.236 src/sys/dev/pci/pci_subr.c cvs rdiff -u -r1.162 -r1.163 src/sys/dev/pci/pcireg.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/pci_subr.c diff -u src/sys/dev/pci/pci_subr.c:1.235 src/sys/dev/pci/pci_subr.c:1.236 --- src/sys/dev/pci/pci_subr.c:1.235 Tue Dec 28 09:19:02 2021 +++ src/sys/dev/pci/pci_subr.c Sat Jan 1 03:27:53 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: pci_subr.c,v 1.235 2021/12/28 09:19:02 msaitoh Exp $ */ +/* $NetBSD: pci_subr.c,v 1.236 2022/01/01 03:27:53 msaitoh Exp $ */ /* * Copyright (c) 1997 Zubin D. Dittia. All rights reserved. @@ -40,7 +40,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.235 2021/12/28 09:19:02 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.236 2022/01/01 03:27:53 msaitoh Exp $"); #ifdef _KERNEL_OPT #include "opt_pci.h" @@ -1833,10 +1833,10 @@ pci_print_pcie_link_deemphasis(pcireg_t } } -static const struct _pcie_link_compliance_preset_deemphasis { +static const struct _pcie_link_preset_preshoot_deemphasis { const char *preshoot; const char *deemphasis; -} pcie_link_compliance_preset_deemphasis[] = { +} pcie_link_preset_preshoot_deemphasis[] = { { "0.0", "-6.0+-1.5" }, /* P0 */ { "0.0", "-3.5+-1" }, /* P1 */ { "0.0", "-4.4+-1.5" }, /* P2 */ @@ -1851,18 +1851,22 @@ static const struct _pcie_link_complianc }; static void -pci_print_pcie_link_compliance_preset_deemphasis(pcireg_t val) +pci_print_pcie_link_preset_preshoot_deemphasis(pcireg_t val) { const char *deemphasis; - if (val >= __arraycount(pcie_link_compliance_preset_deemphasis)) { - printf("unknown value (0x%x)", val); + if (val >= __arraycount(pcie_link_preset_preshoot_deemphasis)) { + /* + * This may be printed because the default value of some + * register fields is 0b1111. + */ + printf("reserved value (0x%x)", val); return; } printf("Preshoot %sdB", - pcie_link_compliance_preset_deemphasis[val].preshoot); - deemphasis = pcie_link_compliance_preset_deemphasis[val].deemphasis; + pcie_link_preset_preshoot_deemphasis[val].preshoot); + deemphasis = pcie_link_preset_preshoot_deemphasis[val].deemphasis; if (deemphasis != NULL) printf(", De-emphasis %sdB", deemphasis); @@ -2402,7 +2406,7 @@ pci_conf_print_pcie_cap(const pcireg_t * onoff("Enter Modified Compliance", reg, PCIE_LCSR2_EN_MCOMP); onoff("Compliance SOS", reg, PCIE_LCSR2_COMP_SOS); printf(" Compliance Preset/De-emphasis: "); - pci_print_pcie_link_compliance_preset_deemphasis( + pci_print_pcie_link_preset_preshoot_deemphasis( PCIREG_SHIFTOUT(reg, PCIE_LCSR2_COMP_DEEMP)); printf("\n"); @@ -4300,6 +4304,179 @@ pci_conf_print_dlf_cap(const pcireg_t *r onoff("Remote DLF supported Valid", reg, PCI_DLF_STAT_RMTVALID); } +static void +pci_conf_print_pl16g_cap(const pcireg_t *regs, int extcapoff) +{ + pcireg_t reg, lwidth; + int pcie_capoff; + unsigned int i, j; + + printf("\n Physical Layer 16.0 GT/s\n"); + reg = regs[o2i(extcapoff + PCI_PL16G_CAP)]; + printf(" Capability register: 0x%08x\n", reg); + + reg = regs[o2i(extcapoff + PCI_PL16G_CTL)]; + printf(" Control register: 0x%08x\n", reg); + + reg = regs[o2i(extcapoff + PCI_PL16G_STAT)]; + printf(" Status register: 0x%08x\n", reg); + onoff("Equalization 16.0 GT/s Complete", reg, PCI_PL16G_STAT_EQ_COMPL); + onoff("Equalization 16.0 GT/s Phase 1 Successful", reg, + PCI_PL16G_STAT_EQ_P1S); + onoff("Equalization 16.0 GT/s Phase 2 Successful", reg, + PCI_PL16G_STAT_EQ_P2S); + onoff("Equalization 16.0 GT/s Phase 3 Successful", reg, + PCI_PL16G_STAT_EQ_P3S); + + reg = regs[o2i(extcapoff + PCI_PL16G_LDPMS)]; + printf(" Local Data Parity Mismatch Status register: 0x%08x\n", + reg); + + reg = regs[o2i(extcapoff + PCI_PL16G_FRDPMS)]; + printf(" First Retimer Data Parity Mismatch Status register:" + " 0x%08x\n", reg); + + reg = regs[o2i(extcapoff + PCI_PL16G_SRDPMS)]; + printf(" Second Retimer Data Parity Mismatch Status register:" + " 0x%08x\n", reg); + + if (pci_conf_find_cap(regs, PCI_CAP_PCIEXPRESS, &pcie_capoff) == 0) + return; /* error */ + + reg = regs[o2i(pcie_capoff + PCIE_LCAP)]; + lwidth = PCIREG_SHIFTOUT(reg, PCIE_LCAP_MAX_WIDTH); + + for (i = 0; i < lwidth;) { + reg = regs[o2i(extcapoff + PCI_PL16G_LEC + i)]; + + for (j = 0; j < 4; j++) { + pcireg_t up, down; + + down = reg & 0x0000000f; + up = (reg >> 4) & 0x0000000f; + printf(" Lane %d downstream: ", i); + pci_print_pcie_link_preset_preshoot_deemphasis(down); + printf("\n Lane %d upstream: ", i); + pci_print_pcie_link_preset_preshoot_deemphasis(up); + printf("\n"); + + reg >>= 8; + i++; + if (i >= lwidth) + break; + } + } +} + +static const char * const pcie_receive_number_dp[] = { + "Broadcast " + "(Downstream Port Receiver and all Retimer Pseudo Port Receiver", + "Rx(A) (Downstream Port Receiver)", + "Rx(B) (Retimer X or Z Upstream Pseudo Port Receiver)", + "Rx(C) (Retimer X or Z Downstream Pseudo Port Receiver)", + "Rx(D) (Retimer Y Upstream Pseudo Port Receiver)", + "Rx(E) (Retimer Y Downstream Pseudo Port Receiver)", + "Reserved", + "Reserved" +}; + +static const char * const pcie_receive_number_up[] = { + "Broadcast (Upstream Port Receiver)", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Rx(F) (Upstream Port Receiver)", + "Reserved" +}; + +/* + * Print PCI_LMR_LANECSR. This function is used for both control and status + * register. The reg argument in the lower 16bit has the control or status + * register. The encoding is the same except the receive number, so use _LCTL_ + * macro. + */ +static void +pci_conf_print_lmr_lcsr(pcireg_t reg, bool up, bool dp) +{ + int rnum; + + printf(" Receive Number: "); + rnum = PCIREG_SHIFTOUT(reg, PCI_LMR_LCTL_RNUM); + if (up) + printf("%s\n", pcie_receive_number_up[rnum]); + else if (dp) + printf("%s\n", pcie_receive_number_dp[rnum]); + else + printf("%x\n", rnum); + + printf(" Margin Type: %x\n", + PCIREG_SHIFTOUT(reg, PCI_LMR_LCTL_MTYPE)); + printf(" Usage Model: %s\n", + (PCIREG_SHIFTOUT(reg, PCI_LMR_LCTL_UMODEL) == 0) + ? "Lane Margining at Receiver" : "Reserved Encoding"); + printf(" Margin Payload: 0x%02x\n", + PCIREG_SHIFTOUT(reg, PCI_LMR_LCTL_MPAYLOAD)); +} + +static void +pci_conf_print_lmr_cap(const pcireg_t *regs, int extcapoff) +{ + pcireg_t reg, lwidth; + int pcie_capoff; + int pcie_devtype; + unsigned int i; + bool up, dp; + + printf("\n Lane Margining at the Receiver\n"); + reg = regs[o2i(extcapoff + PCI_LMR_PCAPSTAT)]; + printf(" Port Capability register: 0x%04x\n", reg & 0xffff); + onoff("Margining uses Driver Software", reg, PCI_LMR_PCAP_MUDS); + printf(" Port Status register: 0x%04x\n", (reg >> 16) & 0xffff); + onoff("Margining Ready", reg, PCI_LMR_PSTAT_MR); + onoff("Margining Software Ready", reg, PCI_LMR_PSTAT_MSR); + + if (pci_conf_find_cap(regs, PCI_CAP_PCIEXPRESS, &pcie_capoff) == 0) + return; /* error */ + + up = dp = false; + reg = regs[o2i(pcie_capoff)]; + pcie_devtype = PCIE_XCAP_TYPE(reg); + switch (pcie_devtype) { + case PCIE_XCAP_TYPE_PCIE_DEV: /* 0x0 */ + case PCIE_XCAP_TYPE_PCI_DEV: /* 0x1 */ + case PCIE_XCAP_TYPE_UP: /* 0x5 */ + case PCIE_XCAP_TYPE_PCIE2PCI: /* 0x7 */ + up = true; + break; + case PCIE_XCAP_TYPE_RP: /* 0x4 */ + case PCIE_XCAP_TYPE_DOWN: /* 0x6 */ + dp = true; + break; + default: + printf("neither upstream nor downstream?(%x)\n", pcie_devtype); + break; + } + + reg = regs[o2i(pcie_capoff + PCIE_LCAP)]; + lwidth = PCIREG_SHIFTOUT(reg, PCIE_LCAP_MAX_WIDTH); + + for (i = 0; i < lwidth; i++) { + pcireg_t lctl, lstat; + + reg = regs[o2i(extcapoff + PCI_LMR_LANECSR + (i * 4))]; + + lctl = reg & 0xffff; + printf(" Lane %d control: 0x%04x\n", i, lctl); + pci_conf_print_lmr_lcsr(lctl, up, dp); + + lstat = (reg >> 16) & 0xffff; + printf(" Lane %d status: 0x%04x\n", i, lstat); + pci_conf_print_lmr_lcsr(lstat, up, dp); + } +} + /* XXX pci_conf_print_hierarchyid_cap */ /* XXX pci_conf_print_npem_cap */ @@ -4387,8 +4564,10 @@ static struct { { PCI_EXTCAP_VF_RESIZBAR, "VF Resizable BARs", NULL }, { PCI_EXTCAP_DLF, "Data link Feature", pci_conf_print_dlf_cap }, - { PCI_EXTCAP_PYSLAY_16GT, "Physical Layer 16.0 GT/s", NULL }, - { PCI_EXTCAP_LMR, "Lane Margining at the Receiver", NULL }, + { PCI_EXTCAP_PL16G, "Physical Layer 16.0 GT/s", + pci_conf_print_pl16g_cap }, + { PCI_EXTCAP_LMR, "Lane Margining at the Receiver", + pci_conf_print_lmr_cap }, { PCI_EXTCAP_HIERARCHYID, "Hierarchy ID", NULL }, { PCI_EXTCAP_NPEM, "Native PCIe Enclosure Management", Index: src/sys/dev/pci/pcireg.h diff -u src/sys/dev/pci/pcireg.h:1.162 src/sys/dev/pci/pcireg.h:1.163 --- src/sys/dev/pci/pcireg.h:1.162 Tue Dec 28 09:16:05 2021 +++ src/sys/dev/pci/pcireg.h Sat Jan 1 03:27:53 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: pcireg.h,v 1.162 2021/12/28 09:16:05 msaitoh Exp $ */ +/* $NetBSD: pcireg.h,v 1.163 2022/01/01 03:27:53 msaitoh Exp $ */ /* * Copyright (c) 1995, 1996, 1999, 2000 @@ -1567,7 +1567,7 @@ struct pci_rom { #define PCI_EXTCAP_DESIGVNDSP 0x0023 /* Designated Vendor-Specific */ #define PCI_EXTCAP_VF_RESIZBAR 0x0024 /* VF Resizable BAR */ #define PCI_EXTCAP_DLF 0x0025 /* Data link Feature */ -#define PCI_EXTCAP_PYSLAY_16GT 0x0026 /* Physical Layer 16.0 GT/s */ +#define PCI_EXTCAP_PL16G 0x0026 /* Physical Layer 16.0 GT/s */ #define PCI_EXTCAP_LMR 0x0027 /* Lane Margining at the Receiver */ #define PCI_EXTCAP_HIERARCHYID 0x0028 /* Hierarchy ID */ #define PCI_EXTCAP_NPEM 0x0029 /* Native PCIe Enclosure Management */ @@ -2208,6 +2208,37 @@ struct pci_rom { * Extended capability ID: 0x0026 * Physical Layer 16.0 GT/s */ +#define PCI_PL16G_CAP 0x04 /* Capabilities Register */ +#define PCI_PL16G_CTL 0x08 /* Control Register */ +#define PCI_PL16G_STAT 0x0c /* Status Register */ +#define PCI_PL16G_STAT_EQ_COMPL __BIT(0) /* Equalization 16.0 GT/s Complete */ +#define PCI_PL16G_STAT_EQ_P1S __BIT(1) /* Eq. 16.0 GT/s Phase 1 Successful */ +#define PCI_PL16G_STAT_EQ_P2S __BIT(2) /* Eq. 16.0 GT/s Phase 2 Successful */ +#define PCI_PL16G_STAT_EQ_P3S __BIT(3) /* Eq. 16.0 GT/s Phase 3 Successful */ +#define PCI_PL16G_STAT_LEQR __BIT(4) /* Link Eq. Request 16.0 GT/s */ +#define PCI_PL16G_LDPMS 0x10 /* Local Data Parity Mismatch Status reg. */ +#define PCI_PL16G_FRDPMS 0x14 /* First Retimer Data Parity Mismatch Status */ +#define PCI_PL16G_SRDPMS 0x18 /* Second Retimer Data Parity Mismatch Status */ + /* 0x1c reserved */ +#define PCI_PL16G_LEC 0x20 /* Lane Equalization Control Register */ + +/* + * Extended capability ID: 0x0027 + * Lane Margining at the Receiver + */ +#define PCI_LMR_PCAPSTAT 0x04 /* Port Capabilities and Status Register */ +#define PCI_LMR_PCAP_MUDS __BIT(0) /* Margining uses Driver Software */ +#define PCI_LMR_PSTAT_MR __BIT(16) /* Margining Ready */ +#define PCI_LMR_PSTAT_MSR __BIT(17) /* Margining Software Ready */ +#define PCI_LMR_LANECSR 0x08 /* Lane Control and Status Register */ +#define PCI_LMR_LCTL_RNUM __BITS(2, 0) /* Receive Number */ +#define PCI_LMR_LCTL_MTYPE __BITS(5, 3) /* Margin Type */ +#define PCI_LMR_LCTL_UMODEL __BIT(6) /* Usage Model */ +#define PCI_LMR_LCTL_MPAYLOAD __BITS(15, 8) /* Margin Payload */ +#define PCI_LMR_LSTAT_RNUM __BITS(18, 16) /* Receive Number */ +#define PCI_LMR_LSTAT_MTYPE __BITS(21, 19) /* Margin Type */ +#define PCI_LMR_LSTAT_UMODEL __BIT(22) /* Usage Model */ +#define PCI_LMR_LSTAT_MPAYLOAD __BITS(31, 24) /* Margin Payload */ /* * Extended capability ID: 0x0028