From: Kurtis Bohlen Date: Fri, 3 Jul 2026 23:16:42 +0000 (+0000) Subject: pcilmr: update PCIe 6.0 margin handling X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;ds=sidebyside;p=thirdparty%2Fpciutils.git pcilmr: update PCIe 6.0 margin handling --- diff --git a/lmr/lmr.h b/lmr/lmr.h index d9995e0..107d6ea 100644 --- 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); diff --git a/lmr/margin.c b/lmr/margin.c index 4d68031..6bcc499 100644 --- a/lmr/margin.c +++ b/lmr/margin.c @@ -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; diff --git a/lmr/margin_log.c b/lmr/margin_log.c index ce8381b..82a180f 100644 --- a/lmr/margin_log.c +++ b/lmr/margin_log.c @@ -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 diff --git a/lmr/margin_results.c b/lmr/margin_results.c index 9543100..a13569d 100644 --- a/lmr/margin_results.c +++ b/lmr/margin_results.c @@ -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++) {