]> git.ipfire.org Git - thirdparty/pciutils.git/commitdiff
CXL: Fix Flex Bus DVSEC cap
authorAlexis Gryta <alexis.gryta@liquid-markets.com>
Mon, 5 Jun 2023 06:06:08 +0000 (15:06 +0900)
committerAlexis Gryta <alexis.gryta@liquid-markets.com>
Tue, 6 Jun 2023 07:32:15 +0000 (16:32 +0900)
lib/header.h
ls-ecaps.c

index 63ee03c895a7e15e97b181615096f0028bb992c6..1a04a7802ae7519dc9c5cff3930e55cb34f1a755 100644 (file)
 #define PCI_CXL_FB_PORT_CTRL2               0x18    /* CXL Flex Bus Port Control2 Register */
 #define  PCI_CXL_FB_CTRL2_NOP_HINT          0x01    /* NOP Hint Enable */
 #define PCI_CXL_FB_PORT_STATUS2             0x1c    /* CXL Flex Bus Port Status2 Register */
+#define PCI_CXL_FB_NEXT_UNSUPPORTED         0x20
 
 /* PCIe CXL Designated Vendor-Specific Capabilities for Multi-Logical Device */
 #define PCI_CXL_MLD_LEN     0x10
index df41626f69e1ffdba001285d6087903cdde00c1b..a9d8470b6d95b557f7540e549677809a2f3e3e1a 100644 (file)
@@ -950,17 +950,33 @@ dvsec_cxl_gpf_port(struct device *d, int where)
 }
 
 static void
-dvsec_cxl_flex_bus(struct device *d, int where, int rev)
+dvsec_cxl_flex_bus(struct device *d, int where, int rev, int len)
 {
   u16 w;
   u32 l, data;
 
-  if (rev < 1)
-  {
-    printf("\t\tRevision %d not supported\n", rev);
-    return;
+  // Sanity check: Does the length correspond to its revision?
+  switch (rev) {
+    case 0:
+      if (len != PCI_CXL_FB_MOD_TS_DATA) {
+        printf("\t\t<Wrong length for Revision %d>\n", rev);
+      }
+      break;
+    case 1:
+      if (len != PCI_CXL_FB_PORT_CAP2) {
+        printf("\t\t<Wrong length for Revision %d>\n", rev);
+      }
+      break;
+    case 2:
+      if (len != PCI_CXL_FB_NEXT_UNSUPPORTED) {
+        printf("\t\t<Wrong length for Revision %d>\n", rev);
+      }
+      break;
+    default:
+      break;
   }
 
+  // From Rev 0
   w = get_conf_word(d, where + PCI_CXL_FB_PORT_CAP);
   printf("\t\tFBCap:\tCache%c IO%c Mem%c 68BFlit%c MltLogDev%c",
       FLAG(w, PCI_CXL_FB_CAP_CACHE), FLAG(w, PCI_CXL_FB_CAP_IO),
@@ -993,12 +1009,18 @@ dvsec_cxl_flex_bus(struct device *d, int where, int rev)
   if (rev > 1)
     printf(" 256BFlit%c PBRFlit%c",
         FLAG(w, PCI_CXL_FB_STAT_256B_FLIT), FLAG(w, PCI_CXL_FB_STAT_PBR_FLIT));
+  printf("\n");
 
-  l = get_conf_long(d, where + PCI_CXL_FB_MOD_TS_DATA);
-  data = BITS(l, 0, 24);
-  printf("\n\t\tFBModTS:\tReceived FB Data: %06x\n", (unsigned int)data);
+  // From Rev 1
+  if (rev >= 1)
+  {
+    l = get_conf_long(d, where + PCI_CXL_FB_MOD_TS_DATA);
+    data = BITS(l, 0, 24);
+    printf("\t\tFBModTS:\tReceived FB Data: %06x\n", (unsigned int)data);
+  }
 
-  if (rev > 1)
+  // From Rev 2
+  if (rev >= 2)
   {
     u8 nop;
 
@@ -1011,7 +1033,12 @@ dvsec_cxl_flex_bus(struct device *d, int where, int rev)
     l = get_conf_long(d, where + PCI_CXL_FB_PORT_STATUS2);
     nop = BITS(l, 0, 2);
     printf("\t\tFBSta2:\tNOPHintInfo: %x\n", nop);
-    }
+  }
+
+  // Unparsed data
+  if (len > PCI_CXL_FB_LEN) {
+    printf("\t\t<?>\n");
+  }
 }
 
 static void
@@ -1068,29 +1095,40 @@ cap_dvsec_cxl(struct device *d, int id, int rev, int where, int len)
   switch (id)
     {
     case 0:
+      printf("\t\tPCIe DVSEC for CXL Devices\n");
       dvsec_cxl_device(d, rev, where, len);
       break;
     case 2:
+      printf("\t\tNon-CXL Function Map DVSEC\n");
       dvsec_cxl_function_map(d, where);
       break;
     case 3:
+      printf("\t\tCXL Extensions DVSEC for Ports\n");
       dvsec_cxl_port(d, where, len);
       break;
     case 4:
+      printf("\t\tGPF DVSEC for CXL Ports\n");
       dvsec_cxl_gpf_port(d, where);
       break;
     case 5:
+      printf("\t\tGPF DVSEC for CXL Devices\n");
       dvsec_cxl_gpf_device(d, where);
       break;
     case 7:
-      dvsec_cxl_flex_bus(d, where, rev);
+      printf("\t\tPCIe DVSEC for Flex Bus Port\n");
+      dvsec_cxl_flex_bus(d, where, rev, len);
       break;
     case 8:
+      printf("\t\tRegister Locator DVSEC\n");
       dvsec_cxl_register_locator(d, where, len);
       break;
     case 9:
+      printf("\t\tMLD DVSEC\n");
       dvsec_cxl_mld(d, where);
       break;
+    case 0xa:
+      printf("\t\tPCIe DVSEC for Test Capability <?>\n");
+      break;
     default:
       printf("\t\tUnknown ID %04x\n", id);
     }