Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[.joined/src/trunk]: .joined/src/sys/dev/pci Print Physical Layer 16.0 GT/s a...



details:   https://anonhg.NetBSD.org/.joined/src/rev/e6c56947fa3a
branches:  trunk
changeset: 359367:e6c56947fa3a
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Sat Jan 01 03:27:53 2022 +0000

description:
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.

diffstat:

 sys/dev/pci/pci_subr.c |  203 ++++++++++++++++++++++++++++++++++++++++++++++--
 sys/dev/pci/pcireg.h   |   35 +++++++-
 2 files changed, 224 insertions(+), 14 deletions(-)

diffs (truncated from 317 to 300 lines):

diff -r 70f3aac13960 -r e6c56947fa3a sys/dev/pci/pci_subr.c
--- a/sys/dev/pci/pci_subr.c    Sat Jan 01 01:15:11 2022 +0000
+++ b/sys/dev/pci/pci_subr.c    Sat Jan 01 03:27:53 2022 +0000
@@ -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 @@
        }
 }
 
-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 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 @@
                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 @@
        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 @@
        { 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",
diff -r 70f3aac13960 -r e6c56947fa3a sys/dev/pci/pcireg.h
--- a/sys/dev/pci/pcireg.h      Sat Jan 01 01:15:11 2022 +0000
+++ b/sys/dev/pci/pcireg.h      Sat Jan 01 03:27:53 2022 +0000
@@ -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 @@
 #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 @@
  * 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



Home | Main Index | Thread Index | Old Index