]> mj.ucw.cz Git - pciutils.git/commitdiff
pcilmr: Add --scan mode to search for all LMR-capable Links
authorNikita Proshkin <n.proshkin@yadro.com>
Wed, 27 Dec 2023 09:45:01 +0000 (14:45 +0500)
committerMartin Mares <mj@ucw.cz>
Sat, 17 Feb 2024 22:44:51 +0000 (23:44 +0100)
Reviewed-by: Sergei Miroshnichenko <s.miroshnichenko@yadro.com>
Signed-off-by: Nikita Proshkin <n.proshkin@yadro.com>
pcilmr.c

index 3c2f2502a002e9b0361d719358fe82322affe7ae..43e791dd68edbf103f8bb29fadd2bc9cd68fb598 100644 (file)
--- a/pcilmr.c
+++ b/pcilmr.c
 
 const char program_name[] = "pcilmr";
 
-enum mode { MARGIN, FULL };
+enum mode { MARGIN, FULL, SCAN };
 
 static const char usage_msg[]
   = "Usage:\n"
     "pcilmr [--margin] [<margining options>] <downstream component> ...\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,6 +108,36 @@ parse_csv_arg(char *arg, u8 *vals)
   return cnt;
 }
 
+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 u8
 find_ready_links(struct pci_access *pacc, struct pci_dev **down_ports, struct pci_dev **up_ports,
                  bool cnt_only)
@@ -185,7 +217,8 @@ 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;
@@ -199,6 +232,12 @@ 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 */