diff --git a/lib/header.h b/lib/header.h
index b188313ea033..bb36ea1deeea 100644
--- a/lib/header.h
+++ b/lib/header.h
@@ -256,6 +256,7 @@
 #define PCI_EXT_CAP_ID_NPEM	0x29	/* Native PCIe Enclosure Management */
 #define PCI_EXT_CAP_ID_32GT	0x2a	/* Physical Layer 32.0 GT/s */
 #define PCI_EXT_CAP_ID_DOE	0x2e	/* Data Object Exchange */
+#define PCI_EXT_CAP_ID_DEV3	0x2f	/* Device 3 */
 #define PCI_EXT_CAP_ID_IDE	0x30	/* Integrity and Data Encryption */
 
 /*** Definitions of capabilities ***/
@@ -1501,6 +1502,25 @@
 /* IDE Address Association Register 2 is "Memory Limit Upper" */
 /* IDE Address Association Register 3 is "Memory Base Upper" */
 
+/* Device 3 Extended Capability */
+#define PCI_DEV3_DEVCAP3	0x4		/* Device Capabilities 3 Register */
+#define  PCI_DEV3_DEVCAP3_DMWR_REQ_ROUTING		0x1	/* DMWr Request Routing Support */
+#define  PCI_DEV3_DEVCAP3_14BIT_TAG_COMP		0x2	/* 14-Bit Tag Completer Support */
+#define  PCI_DEV3_DEVCAP3_14BIT_TAG_REQ			0x4	/* 14-Bit Tag Requester Support */
+#define  PCI_DEV3_DEVCAP3_L0P				0x8	/* L0p Support */
+#define  PCI_DEV3_DEVCAP3_PORT_L0P_EXIT			0x070	/* Port L0p Exit Latency */
+#define  PCI_DEV3_DEVCAP3_RETIMER_L0P_EXIT		0x380	/* Retimer L0p Exit Latency */
+#define PCI_DEV3_DEVCTL3	0x8		/* Device Control 3 Register */
+#define  PCI_DEV3_DEVCTL3_DMWR_REQ			0x1	/* DMWr Requester Enable */
+#define  PCI_DEV3_DEVCTL3_DMWR_EGRESS_BLOCK		0x2	/* DMWr Egress Blocking */
+#define  PCI_DEV3_DEVCTL3_14BIT_TAG_REQ			0x4	/* 14-Bit Tag Requester Enable */
+#define  PCI_DEV3_DEVCTL3_L0P				0x8	/* L0p Enable */
+#define  PCI_DEV3_DEVCTL3_TLW				0x70	/* Target Link Width */
+#define PCI_DEV3_DEVSTA3	0xC	/* Device Status 3 Register */
+#define  PCI_DEV3_DEVSTA3_ILW				0x7	/* Initial Link Width */
+#define  PCI_DEV3_DEVSTA3_SEG_CAPT			0x8	/* Segment Captured */
+#define  PCI_DEV3_DEVSTA3_REMOTE_L0P			0x10	/* Remote L0p Support */
+
 /*
  * The PCI interface treats multi-function devices as independent
  * devices.  The slot/function address of each device is encoded
diff --git a/ls-caps.c b/ls-caps.c
index 38a171a5fe4d..d9632b1d3a8e 100644
--- a/ls-caps.c
+++ b/ls-caps.c
@@ -1798,6 +1798,7 @@ void
 show_caps(struct device *d, int where)
 {
   int can_have_ext_caps = 0;
+  u16 pci_exp_cap = 0;
   int type = -1;
 
   if (get_conf_word(d, PCI_STATUS) & PCI_STATUS_CAP_LIST)
@@ -1882,6 +1883,7 @@ show_caps(struct device *d, int where)
 	    case PCI_CAP_ID_EXP:
 	      type = cap_express(d, where, cap);
 	      can_have_ext_caps = 1;
+	      pci_exp_cap = cap;
 	      break;
 	    case PCI_CAP_ID_MSIX:
 	      cap_msix(d, where, cap);
@@ -1902,5 +1904,5 @@ show_caps(struct device *d, int where)
 	}
     }
   if (can_have_ext_caps)
-    show_ext_caps(d, type);
+    show_ext_caps(d, type, pci_exp_cap);
 }
diff --git a/ls-ecaps.c b/ls-ecaps.c
index e817180889c2..d2aa3c5efd92 100644
--- a/ls-ecaps.c
+++ b/ls-ecaps.c
@@ -1704,8 +1704,44 @@ cap_ide(struct device *d, int where)
       }
 }
 
+static void
+cap_dev3(struct device *d, int where, u16 pci_exp_cap)
+{
+  const char *tlw[] = { "x1", "x2", "x4", "x8", "x16", "unknown", "unknown", "dynamic" };
+  u32 cap3, ctrl3, sta3;
+  u32 sta3_width;
+  printf("Device 3\n");
+  if (verbose < 2)
+    return;
+
+  if (!config_fetch(d, where + PCI_DEV3_DEVCAP3, 12))
+    return;
+
+  cap3 = get_conf_word(d, where + PCI_DEV3_DEVCAP3);
+  printf("\t\tDevCap3: DMWrReqRouting%c 14BitTagReq%c 14BitTagComp%c L0p%c\n",
+      FLAG(cap3, PCI_DEV3_DEVCAP3_DMWR_REQ_ROUTING),
+      FLAG(cap3, PCI_DEV3_DEVCAP3_14BIT_TAG_COMP),
+      FLAG(cap3, PCI_DEV3_DEVCAP3_14BIT_TAG_REQ),
+      FLAG(cap3, PCI_DEV3_DEVCAP3_L0P));
+  ctrl3 = get_conf_word(d, where + PCI_DEV3_DEVCTL3);
+  printf("\t\tDevCtl3: DMWrReqEn%c DMWrEgressBlck%c 14BitTagReqEn%c L0pEn%c\n",
+      FLAG(ctrl3, PCI_DEV3_DEVCTL3_DMWR_REQ),
+      FLAG(ctrl3, PCI_DEV3_DEVCTL3_DMWR_EGRESS_BLOCK),
+      FLAG(ctrl3, PCI_DEV3_DEVCTL3_14BIT_TAG_REQ),
+      FLAG(ctrl3, PCI_DEV3_DEVCTL3_L0P));
+  if (pci_exp_cap & PCI_EXP_FLAGS_FLIT)
+    printf("\t\t\t Target Link Width: %s\n",
+	   tlw[(ctrl3 & PCI_DEV3_DEVCTL3_TLW) >> 4]);
+  sta3 = get_conf_word(d, where + PCI_DEV3_DEVSTA3);
+  sta3_width = 1 << (sta3 & PCI_DEV3_DEVSTA3_ILW);
+  printf("\t\tDevSta3: Initial Link Width: x%u, SegCapture%c RemoteL0p%c\n",
+      sta3_width,
+      FLAG(sta3, PCI_DEV3_DEVSTA3_SEG_CAPT),
+      FLAG(sta3, PCI_DEV3_DEVSTA3_REMOTE_L0P));
+}
+
 void
-show_ext_caps(struct device *d, int type)
+show_ext_caps(struct device *d, int type, u16 pci_exp_cap)
 {
   int where = 0x100;
   char been_there[0x1000];
@@ -1860,6 +1896,9 @@ show_ext_caps(struct device *d, int type)
 	  case PCI_EXT_CAP_ID_IDE:
 	    cap_ide(d, where);
 	    break;
+	  case PCI_EXT_CAP_ID_DEV3:
+	    cap_dev3(d, where, pci_exp_cap);
+	    break;
 	  default:
 	    printf("Extended Capability ID %#02x\n", id);
 	    break;
diff --git a/lspci.h b/lspci.h
index 4d711a555d65..96f46722b2ef 100644
--- a/lspci.h
+++ b/lspci.h
@@ -68,7 +68,7 @@ void show_caps(struct device *d, int where);
 
 /* ls-ecaps.c */
 
-void show_ext_caps(struct device *d, int type);
+void show_ext_caps(struct device *d, int type, u16 pci_exp_cap);
 
 /* ls-caps-vendor.c */
 
