]> git.ipfire.org Git - thirdparty/pciutils.git/commitdiff
lspci: decode flit error injection
authorAlex Martens <alex.martens@asteralabs.com>
Mon, 10 Nov 2025 18:29:12 +0000 (10:29 -0800)
committerAlex Martens <alex.martens@asteralabs.com>
Mon, 10 Nov 2025 18:31:38 +0000 (10:31 -0800)
The flit error injection extended capability is defined in the PCI
express base specification revision 6.4.

Signed-off-by: Alex Martens <alex.martens@asteralabs.com>
lib/header.h
ls-ecaps.c

index b68f2a0559e5ae2f31e00e65a8b19de36a28e07d..afd500b6cbb853b8344a8f92bad3f9d99b1f42e8 100644 (file)
 /* IDE Address Association Register 2 is "Memory Limit Upper" */
 /* IDE Address Association Register 3 is "Memory Base Upper" */
 
+/* Flit Error Injection Capability */
+#define PCI_FLIT_EI_CAP                0x04    /* Error Injection Capability Register */
+#define PCI_FLIT_EI_CTL1       0x08    /* Flit Error Injection Control 1 Register */
+#define  PCI_FLIT_EI_CTL1_EN   0x0001  /* Flit Error Injection Enable */
+#define  PCI_FLIT_EI_CTL1_TX   0x0002  /* Inject Errors on Transmitted Flits */
+#define  PCI_FLIT_EI_CTL1_RX   0x0004  /* Inject Errors on Received Flits */
+#define  PCI_FLIT_EI_CTL1_25GT 0x0040 /* Flit Error Injection Enable 2.5 GT/s Data Rate */
+#define  PCI_FLIT_EI_CTL1_50GT 0x0080 /* Flit Error Injection Enable 5.0 GT/s Data Rate */
+#define  PCI_FLIT_EI_CTL1_80GT 0x0100 /* Flit Error Injection Enable 8.0 GT/s Data Rate */
+#define  PCI_FLIT_EI_CTL1_16GT 0x0200 /* Flit Error Injection Enable 16.0 GT/s Data Rate */
+#define  PCI_FLIT_EI_CTL1_32GT 0x0400 /* Flit Error Injection Enable 32.0 GT/s Data Rate */
+#define  PCI_FLIT_EI_CTL1_64GT 0x0800 /* Flit Error Injection Enable 64.0 GT/s Data Rate */
+#define  PCI_FLIT_EI_CTL1_NUM_ERR(x) (((x) >> 16) & 0x1F) /* Number of Errors Injected */
+#define  PCI_FLIT_EI_CTL1_SPACING(x) (((x) >> 21) & 0xFF) /* Spacing Between Injected Errors */
+#define  PCI_FLIT_EI_CTL1_FLIT_TY(x) (((x) >> 29) & 0x3) /* Injection on Flit Type */
+#define PCI_FLIT_EI_CTL2       0x0C    /* Flit Error Injection Control 2 Register */
+#define  PCI_FLIT_EI_CTL2_CONSEC(x) ((x) & 0x7) /* Consecutive Error Injection */
+#define  PCI_FLIT_EI_CTL2_TYPE(x) (((x) >> 3) & 0x3) /* Error Type Being Injected */
+#define  PCI_FLIT_EI_CTL2_OFFS(x) (((x) >> 5) & 0x7F) /* Error Offset within Flit */
+#define  PCI_FLIT_EI_CTL2_MAG(x) (((x) >> 12) & 0xFF) /* Error Magnitude */
+#define PCI_FLIT_EI_STS                0x10    /* Flit Error Injection Status Register */
+#define  PCI_FLIT_EI_STS_TX(x) ((x) & 0x3) /* Flit Error Tx Injection Status */
+#define  PCI_FLIT_EI_STS_RX(x) (((x) >> 2) & 0x3) /* Flit Error Rx Injection Status */
+#define PCI_FLIT_EI_OS_CTL1    0x14    /* Ordered Set Error Injection Control 1 Register */
+#define  PCI_FLIT_EI_OS_CTL1_EN        0x00000001 /* Ordered Set Error Injection Enable */
+#define  PCI_FLIT_EI_OS_CTL1_TX        0x00000002 /* Inject Errors on Transmitted Ordered Sets */
+#define  PCI_FLIT_EI_OS_CTL1_RX        0x00000004 /* Inject Errors on Received Ordered Sets */
+#define  PCI_FLIT_EI_OS_CTL1_NUM(x) (((x) >> 3) & 0x1F) /* Number of Errors injected */
+#define  PCI_FLIT_EI_OS_CTL1_SPACING(x) (((x) >> 8) & 0xFF) /* Spacing Between Injected Errors */
+#define  PCI_FLIT_EI_OS_CTL1_TS0       0x00010000 /* Inject Error on TS0 OS */
+#define  PCI_FLIT_EI_OS_CTL1_TS1       0x00020000 /* Inject Error on TS1 OS */
+#define  PCI_FLIT_EI_OS_CTL1_TS2       0x00040000 /* Inject Error on TS2 OS */
+#define  PCI_FLIT_EI_OS_CTL1_SKP       0x00080000 /* Inject Error on SKP OS */
+#define  PCI_FLIT_EI_OS_CTL1_EIEOS     0x00100000 /* Inject Error on EIEOS OS */
+#define  PCI_FLIT_EI_OS_CTL1_EIOS      0x00200000 /* Inject Error on EIOS OS */
+#define  PCI_FLIT_EI_OS_CTL1_SDS       0x00400000 /* Inject Error on SDS OS */
+#define  PCI_FLIT_EI_OS_CTL1_POLL      0x00800000 /* Inject Error in Polling State */
+#define  PCI_FLIT_EI_OS_CTL1_CONF      0x01000000 /* Inject errors in the Configuration LTSSM state */
+#define  PCI_FLIT_EI_OS_CTL1_L0                0x02000000 /* Inject errors in the L0 LTSSM state */
+#define  PCI_FLIT_EI_OS_CTL1_NOEQ      0x04000000 /* Inject errors in the Recovery LTSSM states */
+#define  PCI_FLIT_EI_OS_CTL1_EQ01      0x08000000 /* Inject errors Recovery.Equalization Phase 0 and Phase 1 */
+#define  PCI_FLIT_EI_OS_CTL1_EQ2       0x10000000 /* Inject errors Recovery.Equalization Phase 2 */
+#define  PCI_FLIT_EI_OS_CTL1_EQ3       0x20000000 /* Inject errors Recovery.Equalization Phase 3 */
+#define PCI_FLIT_EI_OS_CTL2    0x18    /* Ordered Set Error Injection Control 2 Register */
+#define  PCI_FLIT_EI_OS_CTL2_BYTES(x) ((x) & 0xFFFF) /* Error Injection Bytes */
+#define  PCI_FLIT_EI_OS_CTL2_LANES(x) (((x) >> 16) & 0xFFFF) /* Lane Number for Error Injection */
+#define PCI_FLIT_EI_OS_TX      0x1C    /* Ordered Set Error Tx Injection Status Registe */
+#define  PCI_FLIT_EI_OS_TX_TS0(x) ((x) & 0x3) /* Tx Injection Status TS0 */
+#define  PCI_FLIT_EI_OS_TX_TS1(x) (((x) >> 2) & 0x3) /* Tx Injection Status TS1 */
+#define  PCI_FLIT_EI_OS_TX_TS2(x) (((x) >> 4) & 0x3) /* Tx Injection Status TS2 */
+#define  PCI_FLIT_EI_OS_TX_SKP(x) (((x) >> 6) & 0x3) /* Tx Injection Status SKP */
+#define  PCI_FLIT_EI_OS_TX_EIEOS(x) (((x) >> 8) & 0x3) /* Tx Injection Status EIEOS */
+#define  PCI_FLIT_EI_OS_TX_EIOS(x) (((x) >> 10) & 0x3) /* Tx Injection Status EIOS */
+#define  PCI_FLIT_EI_OS_TX_SDS(x) (((x) >> 12) & 0x3) /* Tx Injection Status SDS */
+#define  PCI_FLIT_EI_OS_TX_POLL(x) (((x) >> 14) & 0x3) /* Tx Injection Status Polling */
+#define  PCI_FLIT_EI_OS_TX_CONF(x) (((x) >> 16) & 0x3) /* Tx Injection Status Configuration */
+#define  PCI_FLIT_EI_OS_TX_L0(x) (((x) >> 18) & 0x3) /* Tx Injection Status L0 */
+#define  PCI_FLIT_EI_OS_TX_NOEQ(x) (((x) >> 20) & 0x3) /* Tx Injection Status non-EQ Recovery */
+#define  PCI_FLIT_EI_OS_TX_EQ01(x) (((x) >> 22) & 0x3) /* Tx Injection Status Recovery.Equalization Phase 0 and 1 */
+#define  PCI_FLIT_EI_OS_TX_EQ2(x) (((x) >> 24) & 0x3) /* Tx Injection Status Recovery.Equalization Phase 2 */
+#define  PCI_FLIT_EI_OS_TX_EQ3(x) (((x) >> 26) & 0x3) /* Tx Injection Status Recovery.Equalization Phase 3 */
+#define PCI_FLIT_EI_OS_RX      0x20    /* Ordered Set Error Rx Injection Status Register */
+#define  PCI_FLIT_EI_OS_RX_TS0(x) ((x) & 0x3) /* Rx Injection Status TS0 */
+#define  PCI_FLIT_EI_OS_RX_TS1(x) (((x) >> 2) & 0x3) /* Rx Injection Status TS1 */
+#define  PCI_FLIT_EI_OS_RX_TS2(x) (((x) >> 4) & 0x3) /* Rx Injection Status TS2 */
+#define  PCI_FLIT_EI_OS_RX_SKP(x) (((x) >> 6) & 0x3) /* Rx Injection Status SKP */
+#define  PCI_FLIT_EI_OS_RX_EIEOS(x) (((x) >> 8) & 0x3) /* Rx Injection Status EIEOS */
+#define  PCI_FLIT_EI_OS_RX_EIOS(x) (((x) >> 10) & 0x3) /* Rx Injection Status EIOS */
+#define  PCI_FLIT_EI_OS_RX_SDS(x) (((x) >> 12) & 0x3) /* Rx Injection Status SDS */
+#define  PCI_FLIT_EI_OS_RX_POLL(x) (((x) >> 14) & 0x3) /* Rx Injection Status Polling */
+#define  PCI_FLIT_EI_OS_RX_CONF(x) (((x) >> 16) & 0x3) /* Rx Injection Status Configuration */
+#define  PCI_FLIT_EI_OS_RX_L0(x) (((x) >> 18) & 0x3) /* Rx Injection Status L0 */
+#define  PCI_FLIT_EI_OS_RX_NOEQ(x) (((x) >> 20) & 0x3) /* Rx Injection Status non-EQ Recovery */
+#define  PCI_FLIT_EI_OS_RX_EQ01(x) (((x) >> 22) & 0x3) /* Rx Injection Status Recovery.Equalization Phase 0 and 1 */
+#define  PCI_FLIT_EI_OS_RX_EQ2(x) (((x) >> 24) & 0x3) /* Rx Injection Status Recovery.Equalization Phase 2 */
+#define  PCI_FLIT_EI_OS_RX_EQ3(x) (((x) >> 26) & 0x3) /* Rx Injection Status Recovery.Equalization Phase 3 */
+
 /*
  * The PCI interface treats multi-function devices as independent
  * devices.  The slot/function address of each device is encoded
index 0bb7412467e020dfe414c59a63fbd130568a6361..e6dbb17cbf1aee741da24e32613ed0c52cd77f72 100644 (file)
@@ -1910,6 +1910,198 @@ cap_dev3(struct device *d, int where)
          FLAG(devsta3, PCI_DEV3_DEVSTA3_REMOTE_L0P_SUPP));
 }
 
+static const char *flit_ei_flit_type_str(char *buf, size_t buflen, u8 type)
+{
+  switch (type)
+    {
+      case 0b000:
+        return "any";
+      case 0b001:
+        return "any non-IDLE";
+      case 0b010:
+        return "only payload";
+      case 0b011:
+        return "only NOP";
+      case 0b100:
+        return "only IDLE";
+      case 0b101:
+        return "only payload+seq";
+      case 0b110:
+        return "only payload+1seq";
+      default:
+        snprintf(buf, buflen, "Unknown (%u)", type);
+        return buf;
+    }
+}
+
+static const char *flit_ei_consec_str(char *buf, size_t buflen, u8 consec)
+{
+  switch (consec)
+    {
+      case 0b000:
+        return "none";
+      case 0b001:
+      case 0b010:
+      case 0b011:
+      case 0b101:
+      case 0b110:
+        snprintf(buf, buflen, "%u", consec);
+        return buf;
+      case 0b111:
+        return "pseudo-random";
+      default:
+        snprintf(buf, buflen, "Unknown (%u)", consec);
+        return buf;
+    }
+}
+
+static const char *flit_ei_err_type_str(char *buf, size_t buflen, u8 type)
+{
+  switch (type)
+    {
+      case 0b00:
+        return "random";
+      case 0b01:
+        return "correctable single group";
+      case 0b10:
+        return "correctable three groups";
+      case 0b011:
+        return "uncorrectable";
+      default:
+        snprintf(buf, buflen, "Unknown (%u)", type);
+        return buf;
+    }
+}
+
+static const char *flit_ei_sts_str(char *buf, size_t buflen, u8 sts)
+{
+  switch (sts)
+    {
+      case 0b00:
+        return "not started";
+      case 0b001:
+        return "started";
+      case 0b010:
+        return "completed";
+      case 0b011:
+        return "error";
+      default:
+        snprintf(buf, buflen, "Unknown (%u)", sts);
+        return buf;
+    }
+}
+
+static void
+cap_flit_ei(struct device *d, int where)
+{
+  char buf0[16], buf1[16], buf2[16];
+
+  printf("Flit Error Injection\n");
+
+  if (verbose < 2)
+    return;
+
+  if (!config_fetch(d, where + PCI_FLIT_EI_CAP, 32))
+    return;
+
+  u32 flit_ei_ctl1 = get_conf_long(d, where + PCI_FLIT_EI_CTL1);
+
+  printf("\t\tFlitEiCtl1:   En%c Tx%c Rx%c 2.5GT/s%c 5.0GT/s%c 8.0GT/s%c 16.0GT/s%c 32.0GT/s%c 64.0GT/s%c\n"
+         "\t\t\t      Number of errors: %u, Spacing between errors: %u, Flit Type: %s\n",
+         FLAG(flit_ei_ctl1, PCI_FLIT_EI_CTL1_EN),
+         FLAG(flit_ei_ctl1, PCI_FLIT_EI_CTL1_TX),
+         FLAG(flit_ei_ctl1, PCI_FLIT_EI_CTL1_RX),
+         FLAG(flit_ei_ctl1, PCI_FLIT_EI_CTL1_25GT),
+         FLAG(flit_ei_ctl1, PCI_FLIT_EI_CTL1_50GT),
+         FLAG(flit_ei_ctl1, PCI_FLIT_EI_CTL1_80GT),
+         FLAG(flit_ei_ctl1, PCI_FLIT_EI_CTL1_16GT),
+         FLAG(flit_ei_ctl1, PCI_FLIT_EI_CTL1_32GT),
+         FLAG(flit_ei_ctl1, PCI_FLIT_EI_CTL1_64GT),
+         PCI_FLIT_EI_CTL1_NUM_ERR(flit_ei_ctl1),
+         PCI_FLIT_EI_CTL1_SPACING(flit_ei_ctl1),
+         flit_ei_flit_type_str(buf0, sizeof(buf0), PCI_FLIT_EI_CTL1_FLIT_TY(flit_ei_ctl1)));
+
+  u32 flit_ei_ctl2 = get_conf_long(d, where + PCI_FLIT_EI_CTL2);
+  printf("\t\tFlitEiCtl2:   Consecutive: %s, Type: %s, Offset: %u, Magnitude: %u\n",
+         flit_ei_consec_str(buf0, sizeof(buf0), PCI_FLIT_EI_CTL2_CONSEC(flit_ei_ctl2)),
+         flit_ei_err_type_str(buf1, sizeof(buf1), PCI_FLIT_EI_CTL2_TYPE(flit_ei_ctl2)),
+         PCI_FLIT_EI_CTL2_OFFS(flit_ei_ctl2),
+         PCI_FLIT_EI_CTL2_MAG(flit_ei_ctl2));
+
+  u32 flit_ei_sts = get_conf_long(d, where + PCI_FLIT_EI_STS);
+  printf("\t\tFlitEiSts:    Tx: %s, Rx: %s\n",
+         flit_ei_sts_str(buf0, sizeof(buf0), PCI_FLIT_EI_STS_TX(flit_ei_sts)),
+         flit_ei_sts_str(buf1, sizeof(buf1), PCI_FLIT_EI_STS_RX(flit_ei_sts)));
+
+  u32 flit_ei_os_ctl1 = get_conf_long(d, where + PCI_FLIT_EI_OS_CTL1);
+  printf("\t\tFlitEiOsCtl1: En%c Tx%c Rx%c TS0%c TS1%c TS2%c SKP%c EIEOS%c EIOS%c\n"
+        "\t\t\t      SDS%c Poll%c Conf%c L0%c NoEq%c Eq01%c Eq2%c Eq3%c\n",
+        FLAG(flit_ei_os_ctl1, PCI_FLIT_EI_OS_CTL1_EN),
+        FLAG(flit_ei_os_ctl1, PCI_FLIT_EI_OS_CTL1_TX),
+        FLAG(flit_ei_os_ctl1, PCI_FLIT_EI_OS_CTL1_RX),
+        FLAG(flit_ei_os_ctl1, PCI_FLIT_EI_OS_CTL1_TS0),
+        FLAG(flit_ei_os_ctl1, PCI_FLIT_EI_OS_CTL1_TS1),
+        FLAG(flit_ei_os_ctl1, PCI_FLIT_EI_OS_CTL1_TS2),
+        FLAG(flit_ei_os_ctl1, PCI_FLIT_EI_OS_CTL1_SKP),
+        FLAG(flit_ei_os_ctl1, PCI_FLIT_EI_OS_CTL1_EIEOS),
+        FLAG(flit_ei_os_ctl1, PCI_FLIT_EI_OS_CTL1_EIOS),
+        FLAG(flit_ei_os_ctl1, PCI_FLIT_EI_OS_CTL1_SDS),
+        FLAG(flit_ei_os_ctl1, PCI_FLIT_EI_OS_CTL1_POLL),
+        FLAG(flit_ei_os_ctl1, PCI_FLIT_EI_OS_CTL1_CONF),
+        FLAG(flit_ei_os_ctl1, PCI_FLIT_EI_OS_CTL1_L0),
+        FLAG(flit_ei_os_ctl1, PCI_FLIT_EI_OS_CTL1_NOEQ),
+        FLAG(flit_ei_os_ctl1, PCI_FLIT_EI_OS_CTL1_EQ01),
+        FLAG(flit_ei_os_ctl1, PCI_FLIT_EI_OS_CTL1_EQ2),
+        FLAG(flit_ei_os_ctl1, PCI_FLIT_EI_OS_CTL1_EQ3));
+
+  u32 flit_ei_os_ctl2 = get_conf_long(d, where + PCI_FLIT_EI_OS_CTL2);
+  printf("\t\tFlitEiOsCtl2: Bytes: %04x, Lanes: %04x\n",
+         PCI_FLIT_EI_OS_CTL2_BYTES(flit_ei_os_ctl2),
+         PCI_FLIT_EI_OS_CTL2_LANES(flit_ei_os_ctl2));
+
+  u32 flit_ei_os_tx = get_conf_long(d, where + PCI_FLIT_EI_OS_TX);
+  printf("\t\tFlitEiOsTx:   TS0: %s, TS1: %s, TS2: %s\n",
+         flit_ei_sts_str(buf0, sizeof(buf0), PCI_FLIT_EI_OS_TX_TS0(flit_ei_os_tx)),
+         flit_ei_sts_str(buf1, sizeof(buf1), PCI_FLIT_EI_OS_TX_TS1(flit_ei_os_tx)),
+         flit_ei_sts_str(buf2, sizeof(buf2), PCI_FLIT_EI_OS_TX_TS2(flit_ei_os_tx)));
+  printf("\t\t\t      SKP: %s, EIEOS: %s, EIOS: %s\n",
+         flit_ei_sts_str(buf0, sizeof(buf0), PCI_FLIT_EI_OS_TX_SKP(flit_ei_os_tx)),
+         flit_ei_sts_str(buf1, sizeof(buf1), PCI_FLIT_EI_OS_TX_EIEOS(flit_ei_os_tx)),
+         flit_ei_sts_str(buf2, sizeof(buf2), PCI_FLIT_EI_OS_TX_EIOS(flit_ei_os_tx)));
+  printf("\t\t\t      SDS: %s, Polling: %s, Configuration: %s\n",
+         flit_ei_sts_str(buf0, sizeof(buf0), PCI_FLIT_EI_OS_TX_SDS(flit_ei_os_tx)),
+         flit_ei_sts_str(buf1, sizeof(buf1), PCI_FLIT_EI_OS_TX_POLL(flit_ei_os_tx)),
+         flit_ei_sts_str(buf2, sizeof(buf2), PCI_FLIT_EI_OS_TX_CONF(flit_ei_os_tx)));
+  printf("\t\t\t      L0: %s, non-EQ recovery: %s, Eq01: %s\n",
+         flit_ei_sts_str(buf0, sizeof(buf0), PCI_FLIT_EI_OS_TX_L0(flit_ei_os_tx)),
+         flit_ei_sts_str(buf1, sizeof(buf1), PCI_FLIT_EI_OS_TX_NOEQ(flit_ei_os_tx)),
+         flit_ei_sts_str(buf2, sizeof(buf2), PCI_FLIT_EI_OS_TX_EQ01(flit_ei_os_tx)));
+  printf("\t\t\t      Eq2: %s, Eq3: %s\n",
+         flit_ei_sts_str(buf0, sizeof(buf0), PCI_FLIT_EI_OS_TX_EQ2(flit_ei_os_tx)),
+         flit_ei_sts_str(buf1, sizeof(buf1), PCI_FLIT_EI_OS_TX_EQ3(flit_ei_os_tx)));
+
+  u32 flit_ei_os_rx = get_conf_long(d, where + PCI_FLIT_EI_OS_RX);
+  printf("\t\tFlitEiOsRx:   TS0: %s, TS1: %s, TS2: %s\n",
+         flit_ei_sts_str(buf0, sizeof(buf0), PCI_FLIT_EI_OS_RX_TS0(flit_ei_os_rx)),
+         flit_ei_sts_str(buf1, sizeof(buf1), PCI_FLIT_EI_OS_RX_TS1(flit_ei_os_rx)),
+         flit_ei_sts_str(buf2, sizeof(buf2), PCI_FLIT_EI_OS_RX_TS2(flit_ei_os_rx)));
+  printf("\t\t\t      SKP: %s, EIEOS: %s, EIOS: %s\n",
+         flit_ei_sts_str(buf0, sizeof(buf0), PCI_FLIT_EI_OS_RX_SKP(flit_ei_os_rx)),
+         flit_ei_sts_str(buf1, sizeof(buf1), PCI_FLIT_EI_OS_RX_EIEOS(flit_ei_os_rx)),
+         flit_ei_sts_str(buf2, sizeof(buf2), PCI_FLIT_EI_OS_RX_EIOS(flit_ei_os_rx)));
+  printf("\t\t\t      SDS: %s, Polling: %s, Configuration: %s\n",
+         flit_ei_sts_str(buf0, sizeof(buf0), PCI_FLIT_EI_OS_RX_SDS(flit_ei_os_rx)),
+         flit_ei_sts_str(buf1, sizeof(buf1), PCI_FLIT_EI_OS_RX_POLL(flit_ei_os_rx)),
+         flit_ei_sts_str(buf2, sizeof(buf2), PCI_FLIT_EI_OS_RX_CONF(flit_ei_os_rx)));
+  printf("\t\t\t      L0: %s, non-EQ recovery: %s, Eq01: %s\n",
+         flit_ei_sts_str(buf0, sizeof(buf0), PCI_FLIT_EI_OS_RX_L0(flit_ei_os_rx)),
+         flit_ei_sts_str(buf1, sizeof(buf1), PCI_FLIT_EI_OS_RX_NOEQ(flit_ei_os_rx)),
+         flit_ei_sts_str(buf2, sizeof(buf2), PCI_FLIT_EI_OS_RX_EQ01(flit_ei_os_rx)));
+  printf("\t\t\t      Eq2: %s, Eq3: %s\n",
+         flit_ei_sts_str(buf0, sizeof(buf0), PCI_FLIT_EI_OS_RX_EQ2(flit_ei_os_rx)),
+         flit_ei_sts_str(buf1, sizeof(buf1), PCI_FLIT_EI_OS_RX_EQ3(flit_ei_os_rx)));
+}
+
 void
 show_ext_caps(struct device *d, int type)
 {
@@ -2072,6 +2264,9 @@ show_ext_caps(struct device *d, int type)
          case PCI_EXT_CAP_ID_DEV3:
            cap_dev3(d, where);
            break;
+         case PCI_EXT_CAP_ID_FLIT_EI:
+           cap_flit_ei(d, where);
+           break;
          default:
            printf("Extended Capability ID %#02x\n", id);
            break;