>-----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
[...]
