]> mj.ucw.cz Git - pciutils.git/commitdiff
Add display function for cxl1.1 device link status information. (#183)
authorKobayashi Daisuke <kobayashi.da-06@fujitsu.com>
Thu, 30 May 2024 15:41:28 +0000 (00:41 +0900)
committerGitHub <noreply@github.com>
Thu, 30 May 2024 15:41:28 +0000 (17:41 +0200)
* Add display function for cxl1.1 device link status information.

* Modifications according to comments. Adding a description, Fix odd indent, and remove unnecessary statement.

lib/pci.h
lib/sysfs.c
ls-caps.c
lspci.c

index 4b5f6c1a9af8ab350bc5c7ae716dcbf1952d8646..671972dd4fbb58e8c33dde92f119b099f9e23fb7 100644 (file)
--- a/lib/pci.h
+++ b/lib/pci.h
@@ -159,6 +159,9 @@ struct pci_dev {
   u16 subsys_vendor_id, subsys_id;     /* Subsystem vendor id and subsystem id */
   struct pci_dev *parent;              /* Parent device, does not have to be always accessible */
   int no_config_access;                        /* No access to config space for this device */
+  u32 rcd_link_cap;     /* Link Capabilities register for RCD */
+  u16 rcd_link_status;  /* Link Status register for RCD */
+  u16 rcd_link_ctrl;    /* Link Control register for RCD */
 
   /* Fields used internally */
   struct pci_access *access;
@@ -231,6 +234,7 @@ char *pci_get_string_property(struct pci_dev *d, u32 prop) PCI_ABI;
 #define PCI_FILL_SUBSYS                0x00040000      /* subsys_vendor_id and subsys_id */
 #define PCI_FILL_PARENT                0x00080000
 #define PCI_FILL_DRIVER                0x00100000      /* OS driver currently in use (string property) */
+#define PCI_FILL_RCD_LNK       0x00200000      /* CXL RCD Link status properties */
 
 void pci_setup_cache(struct pci_dev *, u8 *cache, int len) PCI_ABI;
 
index 439c4cbd6aa01538ce99529602c86cdd9fde439b..7dedc0b7fba23a4496568ee14c74b90899d7376e 100644 (file)
@@ -484,6 +484,17 @@ sysfs_fill_info(struct pci_dev *d, unsigned int flags)
         clear_fill(d, PCI_FILL_DRIVER);
     }
 
+  if (want_fill(d, flags, PCI_FILL_RCD_LNK))
+    {
+      char buf[OBJBUFSIZE];
+      if (sysfs_get_string(d, "rcd_link_cap", buf, 0))
+        d->rcd_link_cap = strtoul(buf, NULL, 16);
+      if (sysfs_get_string(d, "rcd_link_ctrl", buf, 0))
+        d->rcd_link_ctrl = strtoul(buf, NULL, 16);
+      if (sysfs_get_string(d, "rcd_link_status", buf, 0))
+        d->rcd_link_status = strtoul(buf, NULL, 16);
+    }
+
   pci_generic_fill_info(d, flags);
 }
 
index 65e92e687591ef84092a9f84e57ec814d6fd5a44..fca11647239214234700c1b59508615f8757d4a1 100644 (file)
--- a/ls-caps.c
+++ b/ls-caps.c
@@ -10,6 +10,7 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
 
 #include "lspci.h"
 
@@ -1390,6 +1391,68 @@ static void cap_express_slot2(struct device *d UNUSED, int where UNUSED)
   /* No capabilities that require this field in PCIe rev2.0 spec. */
 }
 
+static void cap_express_link_rcd(struct device *d)
+{
+  u32 t, aspm, cap_speed, cap_width, sta_speed, sta_width;
+  u16 w;
+  struct pci_dev *pdev = d->dev;
+
+  if (!pdev->rcd_link_cap)
+    return;
+  t = pdev->rcd_link_cap;
+  aspm = (t & PCI_EXP_LNKCAP_ASPM) >> 10;
+  cap_speed = t & PCI_EXP_LNKCAP_SPEED;
+  cap_width = (t & PCI_EXP_LNKCAP_WIDTH) >> 4;
+  printf("\t\tLnkCap:\tPort #%d, Speed %s, Width x%d, ASPM %s",
+   t >> 24,
+   link_speed(cap_speed), cap_width,
+   aspm_support(aspm));
+  if (aspm) {
+      printf(", Exit Latency ");
+      if (aspm & 1)
+        printf("L0s %s", latency_l0s((t & PCI_EXP_LNKCAP_L0S) >> 12));
+      if (aspm & 2)
+        printf("%sL1 %s", (aspm & 1) ? ", " : "",
+      latency_l1((t & PCI_EXP_LNKCAP_L1) >> 15));
+  }
+  printf("\n");
+  printf("\t\t\tClockPM%c Surprise%c LLActRep%c BwNot%c ASPMOptComp%c\n",
+   FLAG(t, PCI_EXP_LNKCAP_CLOCKPM),
+   FLAG(t, PCI_EXP_LNKCAP_SURPRISE),
+   FLAG(t, PCI_EXP_LNKCAP_DLLA),
+   FLAG(t, PCI_EXP_LNKCAP_LBNC),
+   FLAG(t, PCI_EXP_LNKCAP_AOC));
+
+  w = pdev->rcd_link_ctrl;
+  printf("\t\tLnkCtl:\tASPM %s;", aspm_enabled(w & PCI_EXP_LNKCTL_ASPM));
+  printf(" Disabled%c CommClk%c\n\t\t\tExtSynch%c ClockPM%c AutWidDis%c BWInt%c AutBWInt%c\n",
+   FLAG(w, PCI_EXP_LNKCTL_DISABLE),
+   FLAG(w, PCI_EXP_LNKCTL_CLOCK),
+   FLAG(w, PCI_EXP_LNKCTL_XSYNCH),
+   FLAG(w, PCI_EXP_LNKCTL_CLOCKPM),
+   FLAG(w, PCI_EXP_LNKCTL_HWAUTWD),
+   FLAG(w, PCI_EXP_LNKCTL_BWMIE),
+   FLAG(w, PCI_EXP_LNKCTL_AUTBWIE));
+
+  w = pdev->rcd_link_status;
+  sta_speed = w & PCI_EXP_LNKSTA_SPEED;
+  sta_width = (w & PCI_EXP_LNKSTA_WIDTH) >> 4;
+  printf("\t\tLnkSta:\tSpeed %s%s, Width x%d%s\n",
+   link_speed(sta_speed),
+   link_compare(PCI_EXP_TYPE_ROOT_INT_EP, sta_speed, cap_speed),
+   sta_width,
+   link_compare(PCI_EXP_TYPE_ROOT_INT_EP, sta_width, cap_width));
+  printf("\t\t\tTrErr%c Train%c SlotClk%c DLActive%c BWMgmt%c ABWMgmt%c\n",
+   FLAG(w, PCI_EXP_LNKSTA_TR_ERR),
+   FLAG(w, PCI_EXP_LNKSTA_TRAIN),
+   FLAG(w, PCI_EXP_LNKSTA_SL_CLK),
+   FLAG(w, PCI_EXP_LNKSTA_DL_ACT),
+   FLAG(w, PCI_EXP_LNKSTA_BWMGMT),
+   FLAG(w, PCI_EXP_LNKSTA_AUTBW));
+
+  return;
+}
+
 static int
 cap_express(struct device *d, int where, int cap)
 {
@@ -1454,6 +1517,9 @@ cap_express(struct device *d, int where, int cap)
   cap_express_dev(d, where, type);
   if (link)
     cap_express_link(d, where, type);
+  else if (d->dev->rcd_link_cap)
+    cap_express_link_rcd(d);
+   
   if (slot)
     cap_express_slot(d, where);
   if (type == PCI_EXP_TYPE_ROOT_PORT || type == PCI_EXP_TYPE_ROOT_EC)
diff --git a/lspci.c b/lspci.c
index 071cc117bc682c11917e57d6392a987c6a50d528..aee16736357379c1b81f04507fd9f007d45f4d01 100644 (file)
--- a/lspci.c
+++ b/lspci.c
@@ -805,7 +805,7 @@ show_verbose(struct device *d)
 
   pci_fill_info(p, PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES |
     PCI_FILL_PHYS_SLOT | PCI_FILL_NUMA_NODE | PCI_FILL_DT_NODE | PCI_FILL_IOMMU_GROUP |
-    PCI_FILL_BRIDGE_BASES | PCI_FILL_CLASS_EXT | PCI_FILL_SUBSYS);
+    PCI_FILL_BRIDGE_BASES | PCI_FILL_CLASS_EXT | PCI_FILL_SUBSYS | PCI_FILL_RCD_LNK);
 
   switch (htype)
     {