diff mbox series

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

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

Commit Message

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

Patch

diff --git a/pcilmr.c b/pcilmr.c
index 3c2f250..43e791d 100644
--- a/pcilmr.c
+++ b/pcilmr.c
@@ -17,17 +17,19 @@ 
 
 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 */