aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikita Proshkin <n.proshkin@yadro.com>2023-12-27 14:45:01 +0500
committerMartin Mares <mj@ucw.cz>2024-02-17 23:44:51 +0100
commit65f3c322709d9a345f7808c14e937a5e3ca882c4 (patch)
tree810032a7e204d72512b328a708840714f92282ae
parent5648e3f67164f79efbaad88368587b83a175b3d4 (diff)
downloadpciutils-65f3c322709d9a345f7808c14e937a5e3ca882c4.tar.gz
pcilmr: Add --scan mode to search for all LMR-capable Links
Reviewed-by: Sergei Miroshnichenko <s.miroshnichenko@yadro.com> Signed-off-by: Nikita Proshkin <n.proshkin@yadro.com>
-rw-r--r--pcilmr.c43
1 files changed, 41 insertions, 2 deletions
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 */