]> mj.ucw.cz Git - pciutils.git/blobdiff - ls-caps.c
lspci: Improvements to PCIe link speed downgrade reporting
[pciutils.git] / ls-caps.c
index 495d73a92e29b38aaf44aee91688f43a6e59ba1e..79b61cd882e57a2a92181c742f5a16400ad2185f 100644 (file)
--- a/ls-caps.c
+++ b/ls-caps.c
@@ -771,13 +771,16 @@ static char *link_speed(int speed)
     }
 }
 
-static char *link_compare(int sta, int cap)
+static char *link_compare(int type, int sta, int cap)
 {
-  if (sta < cap)
-    return "downgraded";
   if (sta > cap)
-    return "strange";
-  return "ok";
+    return " (overdriven)";
+  if (sta == cap)
+    return "";
+  if ((type == PCI_EXP_TYPE_ROOT_PORT) || (type == PCI_EXP_TYPE_DOWNSTREAM) ||
+      (type == PCI_EXP_TYPE_PCIE_BRIDGE))
+    return "";
+  return " (downgraded)";
 }
 
 static char *aspm_support(int code)
@@ -850,11 +853,11 @@ static void cap_express_link(struct device *d, int where, int type)
   w = get_conf_word(d, where + PCI_EXP_LNKSTA);
   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",
+  printf("\t\tLnkSta:\tSpeed %s%s, Width x%d%s\n",
        link_speed(sta_speed),
-       link_compare(sta_speed, cap_speed),
+       link_compare(type, sta_speed, cap_speed),
        sta_width,
-       link_compare(sta_width, cap_width));
+       link_compare(type, 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),
@@ -1233,6 +1236,35 @@ static const char *cap_express_link2_deemphasis(int type)
     }
 }
 
+static const char *cap_express_link2_compliance_preset(int type)
+{
+  switch (type)
+    {
+      case 0:
+       return "-6dB de-emphasis, 0dB preshoot";
+      case 1:
+       return "-3.5dB de-emphasis, 0dB preshoot";
+      case 2:
+       return "-4.4dB de-emphasis, 0dB preshoot";
+      case 3:
+       return "-2.5dB de-emphasis, 0dB preshoot";
+      case 4:
+       return "0dB de-emphasis, 0dB preshoot";
+      case 5:
+       return "0dB de-emphasis, 1.9dB preshoot";
+      case 6:
+       return "0dB de-emphasis, 2.5dB preshoot";
+      case 7:
+       return "-6.0dB de-emphasis, 3.5dB preshoot";
+      case 8:
+       return "-3.5dB de-emphasis, 3.5dB preshoot";
+      case 9:
+       return "0dB de-emphasis, 3.5dB preshoot";
+      default:
+       return "Unknown";
+    }
+}
+
 static const char *cap_express_link2_transmargin(int type)
 {
   switch (type)
@@ -1314,11 +1346,11 @@ static void cap_express_link2(struct device *d, int where, int type)
        cap_express_link2_deemphasis(PCI_EXP_LNKCTL2_DEEMPHASIS(w)));
     printf("\n"
        "\t\t\t Transmit Margin: %s, EnterModifiedCompliance%c ComplianceSOS%c\n"
-       "\t\t\t Compliance De-emphasis: %s\n",
+       "\t\t\t Compliance Preset/De-emphasis: %s\n",
        cap_express_link2_transmargin(PCI_EXP_LNKCTL2_MARGIN(w)),
        FLAG(w, PCI_EXP_LNKCTL2_MOD_CMPLNC),
        FLAG(w, PCI_EXP_LNKCTL2_CMPLNC_SOS),
-       cap_express_link2_deemphasis(PCI_EXP_LNKCTL2_COM_DEEMPHASIS(w)));
+       cap_express_link2_compliance_preset(PCI_EXP_LNKCTL2_COM_DEEMPHASIS(w)));
   }
 
   w = get_conf_word(d, where + PCI_EXP_LNKSTA2);