>-----Original Message-----
>From: Intel-wired-lan <[email protected]> On Behalf Of Vitaly 
>Lifshits
>Sent: Monday, January 5, 2026 8:58 AM
>To: [email protected]
>Cc: Lifshits, Vitaly <[email protected]>
>Subject: [Intel-wired-lan] [PATCH iwl-next v1 1/1] e1000e: correct TIMINCA on 
>ADP/TGP systems with wrong XTAL frequency
>
>On some Tiger Lake (TGP) and Alder Lake (ADP) platforms, the hardware XTAL 
>clock is incorrectly configured to 24 MHz instead of the expected
>38.4 MHz. This causes the PHC to run significantly faster than system time, 
>breaking PTP synchronization.
>
>To mitigate this at runtime, measure PHC vs system time over ~1 ms using 
>cross-timestamps. If the PHC increment differs from system time beyond the 
>expected tolerance (currently >100 uSecs), reprogram TIMINCA for the
>38.4 MHz profile and reinitialize the timecounter.
>
>Tested on an affected system using phc_ctl:
>Without fix:
>sudo phc_ctl enp0s31f6 set 0.0 wait 10 get clock time: 16.000541250 (expected 
>~10s)
>
>With fix:
>sudo phc_ctl enp0s31f6 set 0.0 wait 10 get clock time: 9.984407212 (expected 
>~10s)
>
>Signed-off-by: Vitaly Lifshits <[email protected]>
>---
> drivers/net/ethernet/intel/e1000e/netdev.c | 79 ++++++++++++++++++++++
> 1 file changed, 79 insertions(+)
>
>diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c 
>b/drivers/net/ethernet/intel/e1000e/netdev.c
>index 116f3c92b5bc..4ab6897577e5 100644
>--- a/drivers/net/ethernet/intel/e1000e/netdev.c
>+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
>@@ -3904,6 +3904,82 @@ static void e1000_flush_desc_rings(struct e1000_adapter 
>*adapter)
>               e1000_flush_rx_ring(adapter);
> }
> 
>+/**
>+ * e1000e_xtal_tgp_workaround - Adjust XTAL clock based on PHC and 
>+system
>+ * clock delta.
>+ *
>+ * Measures the time difference between the PHC (Precision Hardware 
>+Clock)
>+ * and the system clock over a 1 millisecond interval. If the delta
>+ * exceeds 100 microseconds, reconfigure the XTAL clock to 38.4 MHz.
>+ *
>+ * @adapter: Pointer to the private adapter structure  **/ static void 
>+e1000e_xtal_tgp_workaround(struct e1000_adapter *adapter) {
>+      s64 phc_delta, sys_delta, sys_start_ns, sys_end_ns, delta;
>+      struct ptp_system_timestamp sys_start = {}, sys_end = {};
>+      struct ptp_clock_info *info = &adapter->ptp_clock_info;
>+      struct timespec64 phc_start, phc_end;
>+      struct e1000_hw *hw = &adapter->hw;
>+      struct netlink_ext_ack extack = {};
>+      unsigned long flags;
>+      u32 timinca;
>+      s32 ret_val;
>+
>+      /* Capture start */
>+      if (info->gettimex64(info, &phc_start, &sys_start)) {
>+              e_dbg("PHC gettimex(start) failed\n");
>+              return;
>+      }
>+
>+      /* Small interval to measure increment */
>+      usleep_range(1000, 1100);
>+
>+      /* Capture end */
>+      if (info->gettimex64(info, &phc_end, &sys_end)) {
>+              e_dbg("PHC gettimex(end) failed\n");
>+              return;
>+      }
>+
>+      /* Compute deltas */
>+      phc_delta = timespec64_to_ns(&phc_end) -
>+                  timespec64_to_ns(&phc_start);
>+
>+      sys_start_ns = (timespec64_to_ns(&sys_start.pre_ts) +
>+                      timespec64_to_ns(&sys_start.post_ts)) >> 1;
>+
>+      sys_end_ns = (timespec64_to_ns(&sys_end.pre_ts) +
>+                    timespec64_to_ns(&sys_end.post_ts)) >> 1;
>+
>+      sys_delta = sys_end_ns - sys_start_ns;
>+
>+      delta = phc_delta - sys_delta;
>+      if (delta > 100000) {
Please rename to delta_ns
Piotr

[...]

Reply via email to