]> mj.ucw.cz Git - pciutils.git/blobdiff - lmr/lmr.h
pcilmr: Fix margining for ports with Lane reversal
[pciutils.git] / lmr / lmr.h
index c3a5039b994c1e821c56e6afb9bb295a4b9b222a..98df17a6803ba99615fecddf4e4837e21ca3df26 100644 (file)
--- a/lmr/lmr.h
+++ b/lmr/lmr.h
@@ -1,7 +1,7 @@
 /*
  *     The PCI Utilities -- Margining utility main header
  *
- *     Copyright (c) 2023 KNS Group LLC (YADRO)
+ *     Copyright (c) 2023-2024 KNS Group LLC (YADRO)
  *
  *     Can be freely distributed and used under the terms of the GNU GPL v2+.
  *
 
 #include "pciutils.h"
 
-#define MARGIN_STEP_MS 1000
+enum margin_hw { MARGIN_HW_DEFAULT, MARGIN_ICE_LAKE_RC };
+
+// in ps
+static const double margin_ui[] = { 62.5, 31.25 };
 
 /* PCI Device wrapper for margining functions */
 struct margin_dev {
   struct pci_dev *dev;
   int lmr_cap_addr;
-  u8 width;
+  u8 neg_width;
+  u8 max_width;
   u8 retimers_n;
   u8 link_speed;
 
+  enum margin_hw hw;
+
   /* Saved Device settings to restore after margining */
   u8 aspm;
   bool hasd; // Hardware Autonomous Speed Disable
   bool hawd; // Hardware Autonomous Width Disable
 };
 
-struct margin_link {
-  struct margin_dev down_port;
-  struct margin_dev up_port;
-};
-
 /* Specification Revision 5.0 Table 8-11 */
 struct margin_params {
   bool ind_error_sampler;
@@ -87,7 +88,7 @@ enum margin_test_status {
 
 /* All lanes Receiver results */
 struct margin_results {
-  u8 recvn; // Receiver Number
+  u8 recvn; // Receiver Number; from 1 to 6
   struct margin_params params;
   bool lane_reversal;
   u8 link_speed;
@@ -96,39 +97,67 @@ struct margin_results {
 
   /* Used to convert steps to physical quantity.
      Calculated from MaxOffset and NumSteps     */
-  double tim_coef;
+  double tim_coef; // from steps to % UI
   double volt_coef;
 
+  bool tim_off_reported;
+  bool volt_off_reported;
+
   u8 lanes_n;
   struct margin_res_lane *lanes;
 };
 
 /* pcilmr arguments */
-struct margin_args {
+
+// Common args
+struct margin_com_args {
+  u8 error_limit;    // [0; 63]
+  bool run_margin;   // Or print params only
+  u8 verbosity;      // 0 - basic;
+                     // 1 - add info about remaining time and lanes in progress during margining
+  u64 steps_utility; // For ETA logging
+  bool save_csv;
+  char *dir_for_csv;
+  u8 dwell_time;
+};
+
+struct margin_recv_args {
+  // Grading options
+  struct {
+    bool valid;
+    double criteria; // in ps/mV
+    bool one_side_is_whole;
+  } t, v;
+};
+
+struct margin_link_args {
+  struct margin_com_args *common;
   u8 steps_t;        // 0 == use NumTimingSteps
   u8 steps_v;        // 0 == use NumVoltageSteps
   u8 parallel_lanes; // [1; MaxLanes + 1]
-  u8 error_limit;    // [0; 63]
   u8 recvs[6];       // Receivers Numbers
   u8 recvs_n;        // 0 == margin all available receivers
-  u8 lanes[32];      // Lanes to Margin
-  u8 lanes_n;        // 0 == margin all available lanes
-  bool run_margin;   // Or print params only
-  u8 verbosity;      // 0 - basic;
-                     // 1 - add info about remaining time and lanes in progress during margining
+  struct margin_recv_args recv_args[6];
+  u8 lanes[32]; // Lanes to Margin
+  u8 lanes_n;   // 0 == margin all available lanes
+};
 
-  u64 *steps_utility; // For ETA logging
+struct margin_link {
+  struct margin_dev down_port;
+  struct margin_dev up_port;
+  struct margin_link_args args;
 };
 
 /* Receiver structure */
 struct margin_recv {
   struct margin_dev *dev;
-  u8 recvn; // Receiver Number
+  u8 recvn; // Receiver Number; from 1 to 6
   bool lane_reversal;
   struct margin_params *params;
 
   u8 parallel_lanes;
   u8 error_limit;
+  u8 dwell_time;
 };
 
 struct margin_lanes_data {
@@ -148,8 +177,23 @@ struct margin_lanes_data {
   u8 verbosity;
 };
 
+/* margin_args */
+
+enum margin_mode { MARGIN, FULL, SCAN };
+
+extern const char *usage;
+
+struct margin_link *margin_parse_util_args(struct pci_access *pacc, int argc, char **argv,
+                                           enum margin_mode mode, u8 *links_n);
+
 /* margin_hw */
 
+bool margin_port_is_down(struct pci_dev *dev);
+
+/* Results through down/up ports */
+bool margin_find_pair(struct pci_access *pacc, struct pci_dev *dev, struct pci_dev **down_port,
+                      struct pci_dev **up_port);
+
 /* Verify that devices form the link with 16 GT/s or 32 GT/s data rate */
 bool margin_verify_link(struct pci_dev *down_port, struct pci_dev *up_port);
 
@@ -172,12 +216,11 @@ void margin_restore_link(struct margin_link *link);
 bool margin_read_params(struct pci_access *pacc, struct pci_dev *dev, u8 recvn,
                         struct margin_params *params);
 
-enum margin_test_status margin_process_args(struct margin_dev *dev, struct margin_args *args);
+enum margin_test_status margin_process_args(struct margin_link *link);
 
-/* Awaits that args are prepared through process_args.
+/* Awaits that links are prepared through process_args.
    Returns number of margined Receivers through recvs_n */
-struct margin_results *margin_test_link(struct margin_link *link, struct margin_args *args,
-                                        u8 *recvs_n);
+struct margin_results *margin_test_link(struct margin_link *link, u8 *recvs_n);
 
 void margin_free_results(struct margin_results *results, u8 results_n);
 
@@ -190,8 +233,9 @@ void margin_log(char *format, ...);
 
 /* b:d.f -> b:d.f */
 void margin_log_bdfs(struct pci_dev *down_port, struct pci_dev *up_port);
+void margin_gen_bdfs(struct pci_dev *down_port, struct pci_dev *up_port, char *dest, size_t maxlen);
 
-/* Print Link header (bdfs, width, speed) */
+/* Print Link header (bdfs, neg_width, speed) */
 void margin_log_link(struct margin_link *link);
 
 void margin_log_params(struct margin_params *params);
@@ -205,4 +249,24 @@ void margin_log_receiver(struct margin_recv *recv);
 /* Margining in progress log */
 void margin_log_margining(struct margin_lanes_data arg);
 
+void margin_log_hw_quirks(struct margin_recv *recv);
+
+/* margin_results */
+
+// Min values are taken from PCIe Base Spec Rev. 5.0 Section 8.4.2.
+// Rec values are based on PCIe Arch PHY Test Spec Rev 5.0
+// (Transmitter Electrical Compliance)
+
+// values in ps
+static const double margin_ew_min[] = { 18.75, 9.375 };
+static const double margin_ew_rec[] = { 23.75, 10.1565 };
+
+static const double margin_eh_min[] = { 15, 15 };
+static const double margin_eh_rec[] = { 21, 19.75 };
+
+void margin_results_print_brief(struct margin_results *results, u8 recvs_n,
+                                struct margin_link_args *args);
+
+void margin_results_save_csv(struct margin_results *results, u8 recvs_n, struct margin_link *link);
+
 #endif