Module Name: src Committed By: martin Date: Sat Jan 29 17:08:33 UTC 2022
Modified Files: src/sys/dev/pci [netbsd-9]: pci_subr.c pcireg.h Log Message: Pull up the following revisions, requested by msaitoh in ticket #1412: sys/dev/pci/pci_subr.c 1.232-1.239 via patch sys/dev/pci/pcireg.h 1.62-1.63 - Decode link control2's Compliance Preset/De-emphasis more. - Decode Physical Layer 16.0 GT/s extended capability. - Decode Lane Margining at the Receiver extended capability. - Print "reserved" instead of "unknown" when printing equalization preset. One of them is known to be the default value. - Fix typo. To generate a diff of this commit: cvs rdiff -u -r1.215.2.5 -r1.215.2.6 src/sys/dev/pci/pci_subr.c cvs rdiff -u -r1.147.4.3 -r1.147.4.4 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.215.2.5 src/sys/dev/pci/pci_subr.c:1.215.2.6 --- src/sys/dev/pci/pci_subr.c:1.215.2.5 Fri Dec 3 19:40:38 2021 +++ src/sys/dev/pci/pci_subr.c Sat Jan 29 17:08:33 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: pci_subr.c,v 1.215.2.5 2021/12/03 19:40:38 martin Exp $ */ +/* $NetBSD: pci_subr.c,v 1.215.2.6 2022/01/29 17:08:33 martin 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.215.2.5 2021/12/03 19:40:38 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.215.2.6 2022/01/29 17:08:33 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_pci.h" @@ -1787,6 +1787,45 @@ pci_print_pcie_link_deemphasis(pcireg_t } } +static const struct _pcie_link_preset_preshoot_deemphasis { + const char *preshoot; + const char *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 */ + { "0.0", "-2.5+-1" }, /* P3 */ + { "0.0", "0.0" }, /* P4 */ + { "1.9+-1", "0.0" }, /* P5 */ + { "2.5+-1", "0.0" }, /* P6 */ + { "3.5+-1", "-6.0+-1.5" }, /* P7 */ + { "3.5+-1", "-3.5+-1" }, /* P8 */ + { "3.5+-1", "0.0" }, /* P9 */ + { "0.0", NULL } /* P10 */ +}; + +static void +pci_print_pcie_link_preset_preshoot_deemphasis(pcireg_t val) +{ + const char *deemphasis; + + 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_preset_preshoot_deemphasis[val].preshoot); + deemphasis = pcie_link_preset_preshoot_deemphasis[val].deemphasis; + + if (deemphasis != NULL) + printf(", De-emphasis %sdB", deemphasis); +} + static void pci_conf_print_pcie_cap(const pcireg_t *regs, int capoff) { @@ -2320,8 +2359,8 @@ pci_conf_print_pcie_cap(const pcireg_t * (unsigned int)__SHIFTOUT(reg, PCIE_LCSR2_TX_MARGIN)); onoff("Enter Modified Compliance", reg, PCIE_LCSR2_EN_MCOMP); onoff("Compliance SOS", reg, PCIE_LCSR2_COMP_SOS); - printf(" Compliance Present/De-emphasis: "); - pci_print_pcie_link_deemphasis( + printf(" Compliance Preset/De-emphasis: "); + pci_print_pcie_link_preset_preshoot_deemphasis( __SHIFTOUT(reg, PCIE_LCSR2_COMP_DEEMP)); printf("\n"); @@ -3854,7 +3893,7 @@ pci_conf_print_sec_pcie_cap(const pcireg reg = regs[o2i(pcie_capoff + PCIE_LCAP)]; maxlinkwidth = __SHIFTOUT(reg, PCIE_LCAP_MAX_WIDTH); } else { - printf("error: falied to get PCIe capablity\n"); + printf("error: failed to get PCIe capability\n"); return; } for (i = 0; i < maxlinkwidth; i++) { @@ -4220,6 +4259,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 = __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[] = { + [0] = ("Broadcast " + "(Downstream Port Receiver and all Retimer Pseudo Port Receiver)"), + [1] = "Rx(A) (Downstream Port Receiver)", + [2] = "Rx(B) (Retimer X or Z Upstream Pseudo Port Receiver)", + [3] = "Rx(C) (Retimer X or Z Downstream Pseudo Port Receiver)", + [4] = "Rx(D) (Retimer Y Upstream Pseudo Port Receiver)", + [5] = "Rx(E) (Retimer Y Downstream Pseudo Port Receiver)", + [6] = "Reserved", + [7] = "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 = __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", + (uint32_t)__SHIFTOUT(reg, PCI_LMR_LCTL_MTYPE)); + printf(" Usage Model: %s\n", + (__SHIFTOUT(reg, PCI_LMR_LCTL_UMODEL) == 0) + ? "Lane Margining at Receiver" : "Reserved Encoding"); + printf(" Margin Payload: 0x%02x\n", + (uint32_t)__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 = __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 */ @@ -4307,8 +4519,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.147.4.3 src/sys/dev/pci/pcireg.h:1.147.4.4 --- src/sys/dev/pci/pcireg.h:1.147.4.3 Fri Dec 3 19:40:38 2021 +++ src/sys/dev/pci/pcireg.h Sat Jan 29 17:08:33 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: pcireg.h,v 1.147.4.3 2021/12/03 19:40:38 martin Exp $ */ +/* $NetBSD: pcireg.h,v 1.147.4.4 2022/01/29 17:08:33 martin Exp $ */ /* * Copyright (c) 1995, 1996, 1999, 2000 @@ -1159,7 +1159,7 @@ typedef u_int8_t pci_revision_t; #define PCIE_LCSR2_TX_MARGIN __BITS(9, 7) /* Transmit Margin */ #define PCIE_LCSR2_EN_MCOMP __BIT(10) /* Enter Modified Compliance */ #define PCIE_LCSR2_COMP_SOS __BIT(11) /* Compliance SOS */ -#define PCIE_LCSR2_COMP_DEEMP __BITS(15, 12) /* Compliance Present/De-emph */ +#define PCIE_LCSR2_COMP_DEEMP __BITS(15, 12) /* Compliance Preset/De-emph */ #define PCIE_LCSR2_DEEMP_LVL __BIT(0 + 16) /* Current De-emphasis Level */ #define PCIE_LCSR2_EQ_COMPL __BIT(1 + 16) /* Equalization Complete */ #define PCIE_LCSR2_EQP1_SUC __BIT(2 + 16) /* Equaliz Phase 1 Successful */ @@ -1552,7 +1552,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 */ @@ -2193,6 +2193,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