]> git.ipfire.org Git - thirdparty/pciutils.git/commitdiff
pcilmr: update PCIe 6.0 margin handling master
authorKurtis Bohlen <kurtis.bohlen@asteralabs.com>
Fri, 3 Jul 2026 23:16:42 +0000 (23:16 +0000)
committerMartin Mareš <mj@ucw.cz>
Wed, 8 Jul 2026 18:43:58 +0000 (20:43 +0200)
lmr/lmr.h
lmr/margin.c
lmr/margin_log.c
lmr/margin_results.c

index d9995e0bee7aca73fd31b1dc8c305a6ebf11fb84..107d6ea432af94b0fec42664b45ae2ec28276d38 100644 (file)
--- a/lmr/lmr.h
+++ b/lmr/lmr.h
@@ -18,7 +18,7 @@
 enum margin_hw { MARGIN_HW_DEFAULT, MARGIN_ICE_LAKE_RC };
 
 // in ps
-static const double margin_ui[] = { 62.5, 31.25, 31.25 };
+static const double margin_ui[] = { 62.5, 31.25, 31.25, 15.625 };
 
 /* PCI Device wrapper for margining functions */
 struct margin_dev {
@@ -258,11 +258,11 @@ void margin_log_hw_quirks(struct margin_recv *recv);
 // (Transmitter Electrical Compliance)
 
 // values in ps
-static const double margin_ew_min[] = { 18.75, 9.375, 9.375 };
-static const double margin_ew_rec[] = { 23.75, 10.1565, 10.1565 };
+static const double margin_ew_min[] = { 18.75, 9.375, 3.125, 1.563 };
+static const double margin_ew_rec[] = { 23.75, 10.1565, 3.125, 1.563 };
 
-static const double margin_eh_min[] = { 15, 15, 5 };
-static const double margin_eh_rec[] = { 21, 19.75, 7 };
+static const double margin_eh_min[] = { 15, 15, 6, 10 };
+static const double margin_eh_rec[] = { 21, 19.75, 8, 12 };
 
 void margin_results_print_brief(struct margin_results *results, u8 recvs_n,
                                 struct margin_link_args *args);
index 4d680318c5e2c74665269ba97b6cc614069cf432..6bcc4995958b66aeb2d90497012d25978bfd8cbb 100644 (file)
@@ -160,6 +160,18 @@ margin_apply_hw_quirks(struct margin_recv *recv, struct margin_link_args *args)
     }
 }
 
+static double
+margin_max_timing_offset_pct(u8 link_speed)
+{
+  return link_speed >= 6 ? 35.0 : 50.0;
+}
+
+static double
+margin_volt_scale_mv(u8 link_speed)
+{
+  return link_speed >= 6 ? (10.0 / 3.0) : 10.0;
+}
+
 static bool
 read_params_internal(struct margin_dev *dev, u8 recvn, bool lane_reversal,
                      struct margin_params *params)
@@ -350,12 +362,10 @@ margin_test_receiver(struct margin_dev *dev, u8 recvn, struct margin_link_args *
 
   results->tim_off_reported = params.timing_offset != 0;
   results->volt_off_reported = params.volt_offset != 0;
-  double tim_offset = results->tim_off_reported ? (double)params.timing_offset : 50.0;
-  double volt_offset = results->volt_off_reported ? (double)params.volt_offset : 50.0;
-
-  results->tim_coef = tim_offset / (double)params.timing_steps;
-  results->volt_coef = volt_offset / (double)params.volt_steps * 10.0;
-
+  double tim_offset = results->tim_off_reported ? (double) params.timing_offset : margin_max_timing_offset_pct(dev->link_speed);
+  double volt_offset = results->volt_off_reported ? (double) params.volt_offset : 50.0;
+  results->tim_coef = tim_offset / (double) params.timing_steps;
+  results->volt_coef = volt_offset / (double) params.volt_steps * margin_volt_scale_mv(dev->link_speed);
   results->lane_reversal = recv.lane_reversal;
   results->link_speed = dev->link_speed;
   results->test_status = MARGIN_TEST_OK;
index ce8381bd194f18427ff69636edff8346998fddda..82a180f13ecdac0c43200ab565b27916eb53c15e 100644 (file)
@@ -87,6 +87,9 @@ margin_log_recvn(struct margin_recv *recv)
 void
 margin_log_receiver(struct margin_recv *recv)
 {
+  double max_timing_offset = recv->dev->link_speed >= 6 ? 35.0 : 50.0;
+  double max_voltage_mv = recv->dev->link_speed >= 6 ? (500.0 / 3.0) : 500.0;
+
   margin_log("\nError Count Limit = %d\n", recv->error_limit);
   margin_log("Parallel Lanes: %d\n", recv->parallel_lanes);
   margin_log("Margining dwell time: %d s\n\n", recv->dwell_time);
@@ -101,10 +104,12 @@ margin_log_receiver(struct margin_recv *recv)
 
   if (recv->params->timing_offset == 0)
     margin_log("\nWarning: Vendor chose not to report the Max Timing Offset.\n"
-               "Utility will use its max possible value - 50 (50%% UI).\n");
+               "Utility will use its max possible value - %.0f (%.1f%% UI).\n",
+               max_timing_offset, max_timing_offset);
   if (recv->params->volt_support && recv->params->volt_offset == 0)
     margin_log("\nWarning: Vendor chose not to report the Max Voltage Offset.\n"
-               "Utility will use its max possible value - 50 (500 mV).\n");
+               "Utility will use its max possible value - 50 (%.1f mV).\n",
+               max_voltage_mv);
 }
 
 void
index 95431006b58a5afa862d4d4e562fb4220e68db98..a13569d5f9a4281b76785cd5aaa10a914285ffbc 100644 (file)
@@ -147,18 +147,21 @@ margin_results_print_brief(struct margin_results *results, u8 recvs_n,
       if (res->lane_reversal)
         printf("Rx(%X) - Lane Reversal\n", 10 + res->recvn - 1);
 
+      double max_timing_offset = res->link_speed >= 6 ? 35.0 : 50.0;
+      double max_voltage_mv = res->link_speed >= 6 ? (500.0 / 3.0) : 500.0;
+
       if (!res->tim_off_reported)
         printf("Rx(%X) - Attention: Vendor chose not to report the Max Timing Offset.\n"
-               "Utility used its max possible value (50%% UI) for calculations of %% UI and ps.\n"
+               "Utility used its max possible value (%.1f%% UI) for calculations of %% UI and ps.\n"
                "Keep in mind that for timing results of this receiver only steps values are "
                "reliable.\n\n",
-               10 + res->recvn - 1);
+               10 + res->recvn - 1, max_timing_offset);
       if (params.volt_support && !res->volt_off_reported)
         printf("Rx(%X) - Attention: Vendor chose not to report the Max Voltage Offset.\n"
-               "Utility used its max possible value (500 mV) for calculations of mV.\n"
+               "Utility used its max possible value (%.1f mV) for calculations of mV.\n"
                "Keep in mind that for voltage results of this receiver only steps values are "
                "reliable.\n\n",
-               10 + res->recvn - 1);
+               10 + res->recvn - 1, max_voltage_mv);
 
       for (int j = 0; j < res->lanes_n; j++)
         {