> -----Original Message-----
> From: Intel-wired-lan <[email protected]> On Behalf
> Of Chwee-Lin Choong
> Sent: Thursday, September 18, 2025 8:38 PM
> To: Nguyen, Anthony L <[email protected]>; Kitszel,
> Przemyslaw <[email protected]>; Andrew Lunn
> <[email protected]>; David S . Miller <[email protected]>; Eric
> Dumazet <[email protected]>; Jakub Kicinski <[email protected]>; Paolo
> Abeni <[email protected]>; Richard Cochran <[email protected]>;
> Gomes, Vinicius <[email protected]>
> Cc: [email protected]; [email protected]; linux-
> [email protected]; Shalev, Avi <[email protected]>; Song,
> Yoong Siang <[email protected]>
> Subject: [Intel-wired-lan] [PATCH iwl-net v1] igc: fix race condition
> in TX timestamp read for register 0
>
> The current HW bug workaround checks the TXTT_0 ready bit first, then
> reads LOW -> HIGH -> LOW from register 0 to detect if a timestamp was
> captured.
>
> This sequence has a race: if a new timestamp is latched after reading
> the TXTT mask but before the first LOW read, both old and new
> timestamp match, causing the driver to drop a valid timestamp.
>
> Fix by reading the LOW register first, then the TXTT mask, so a newly
> latched timestamp will always be detected.
>
> This fix also prevents TX unit hangs observed under heavy timestamping
> load.
>
> Fixes: c789ad7cbebc ("igc: Work around HW bug causing missing
> timestamps")
> Suggested-by: Avi Shalev <[email protected]>
> Signed-off-by: Song Yoong Siang <[email protected]>
> Signed-off-by: Chwee-Lin Choong <[email protected]>
> ---
> drivers/net/ethernet/intel/igc/igc_ptp.c | 10 ++++++++--
> 1 file changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c
> b/drivers/net/ethernet/intel/igc/igc_ptp.c
> index b7b46d863bee..930486b02fc1 100644
> --- a/drivers/net/ethernet/intel/igc/igc_ptp.c
> +++ b/drivers/net/ethernet/intel/igc/igc_ptp.c
> @@ -774,10 +774,17 @@ static void igc_ptp_tx_reg_to_stamp(struct
> igc_adapter *adapter, static void igc_ptp_tx_hwtstamp(struct
> igc_adapter *adapter) {
> struct igc_hw *hw = &adapter->hw;
> + u32 txstmpl_old;
> u64 regval;
> u32 mask;
> int i;
>
> + /* Read the "low" register 0 first to establish a baseline
> value.
> + * This avoids a race where a new timestamp could be latched
> + * after checking the TXTT mask.
> + */
> + txstmpl_old = rd32(IGC_TXSTMPL);
> +
> mask = rd32(IGC_TSYNCTXCTL) & IGC_TSYNCTXCTL_TXTT_ANY;
> if (mask & IGC_TSYNCTXCTL_TXTT_0) {
> regval = rd32(IGC_TXSTMPL);
> @@ -801,9 +808,8 @@ static void igc_ptp_tx_hwtstamp(struct igc_adapter
> *adapter)
> * timestamp was captured, we can read the "high"
> * register again.
> */
> - u32 txstmpl_old, txstmpl_new;
> + u32 txstmpl_new;
>
> - txstmpl_old = rd32(IGC_TXSTMPL);
> rd32(IGC_TXSTMPH);
> txstmpl_new = rd32(IGC_TXSTMPL);
>
> --
> 2.42.0
Reviewed-by: Aleksandr Loktionov <[email protected]>