diff mbox series

[12/15] pciutils-pcilmr: Add --scan mode to search for all LMR-capable Links

Message ID 20231208091734.12225-13-n.proshkin@yadro.com (mailing list archive)
State Superseded
Headers show
Series pciutils: Add utility for Lane Margining | expand

Commit Message

Nikita Proshkin Dec. 8, 2023, 9:17 a.m. UTC
Reviewed-by: Sergei Miroshnichenko <s.miroshnichenko@yadro.com>
Signed-off-by: Nikita Proshkin <n.proshkin@yadro.com>
---
 pcilmr.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 46 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/pcilmr.c b/pcilmr.c
index ed37a05..46b9f24 100644
--- a/pcilmr.c
+++ b/pcilmr.c
@@ -9,19 +9,22 @@ 
 
 enum mode {
   MARGIN,
-  FULL
+  FULL,
+  SCAN
 };
 
 static void usage(void)
 {
   printf("Usage:\n"
          "pcilmr [--margin] [<margining options>] <downstream component> ...\n"
-         "pcilmr --full [<margining options>]\n\n"
+         "pcilmr --full [<margining options>]\n"
+         "pcilmr --scan\n\n"
          "Device Specifier:\n"
          "<device/component>:\t[<domain>:]<bus>:<dev>.<func>\n\n"
          "Modes:\n"
          "--margin\t\tMargin selected Links\n"
          "--full\t\t\tMargin all ready for testing Links in the system (one by one)\n"
+         "--scan\t\t\tScan for Links available for margining\n\n"
          "Margining options:\n\n"
          "Margining Test settings:\n"
          "-c\t\t\tPrint Device Lane Margining Capabilities only. Do not run margining.\n"
@@ -106,7 +109,38 @@  static uint8_t parse_csv_arg(char *arg, uint8_t *lanes)
   return cnt;
 }
 
-static uint8_t find_ready_links(struct pci_access *pacc, struct pci_dev **down_ports, 
+static void scan_links(struct pci_access *pacc, bool only_ready)
+{
+  if (only_ready)
+    printf("Links ready for margining:\n");
+  else
+    printf("Links with Lane Margining at the Receiver capabilities:\n");
+  bool flag = true;
+  for (struct pci_dev *up = pacc->devices; up; up = up->next)
+  {
+    if (pci_find_cap(up, PCI_EXT_CAP_ID_LMR, PCI_CAP_EXTENDED))
+    {
+      struct pci_dev *down = find_down_port_for_up(pacc, up);
+
+      if (down && margin_verify_link(down, up))
+      {
+        margin_log_bdfs(down, up);
+        if (!only_ready && (margin_check_ready_bit(down) || margin_check_ready_bit(up)))
+        {
+          printf(" - Ready");
+        }
+        printf("\n");
+        flag = false;
+      }
+    }
+  }
+  if (flag)
+    printf("Links not found or you don't have enough privileges.\n");
+  pci_cleanup(pacc);
+  exit(0);
+}
+
+static uint8_t find_ready_links(struct pci_access *pacc, struct pci_dev **down_ports,
                                 struct pci_dev **up_ports, bool cnt_only)
 {
   uint8_t cnt = 0;
@@ -184,7 +218,8 @@  int main(int argc, char **argv)
 
   struct option long_options[] = {
       {.name = "margin", .has_arg = no_argument, .flag = NULL, .val = 0},
-      {.name = "full", .has_arg = no_argument, .flag = NULL, .val = 1},
+      {.name = "scan", .has_arg = no_argument, .flag = NULL, .val = 1},
+      {.name = "full", .has_arg = no_argument, .flag = NULL, .val = 2},
       {0, 0, 0, 0}};
 
   int c;
@@ -198,6 +233,12 @@  int main(int argc, char **argv)
     mode = MARGIN;
     break;
   case 1:
+    mode = SCAN;
+    if (optind == argc)
+      scan_links(pacc, false);
+    optind--;
+    break;
+  case 2:
     mode = FULL;
     break;
   default: /*unknown option symbol*/
@@ -378,7 +419,7 @@  int main(int argc, char **argv)
         for (uint8_t j = 0; j < args[i].recvs_n; j++)
         {
           if (margin_read_params_standalone(pacc,
-                                            args[i].recvs[j] == 6 ? up_ports[i] : down_ports[i], 
+                                            args[i].recvs[j] == 6 ? up_ports[i] : down_ports[i],
                                             args[i].recvs[j], &caps))
           {
             uint8_t steps_t = steps_t_arg == -1 ? caps.timing_steps : steps_t_arg;