On Friday, September 19, 2025 6:11 AM, Keller, Jacob E 
<[email protected]> wrote:
>On 9/18/2025 1:47 PM, Vadim Fedorenko wrote:
>> On 18/09/2025 19:38, Chwee-Lin Choong wrote:
>>> 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(-)
>>>
>>
>> [...]
>>
>>>              * timestamp was captured, we can read the "high"
>>>              * register again.
>>>              */
>>
>> This comment begins with 'read the "high" register (to latch a new
>> timestamp)' ...
>>
>>> -           u32 txstmpl_old, txstmpl_new;
>>> +           u32 txstmpl_new;
>>>
>>> -           txstmpl_old = rd32(IGC_TXSTMPL);
>>>             rd32(IGC_TXSTMPH);
>>>             txstmpl_new = rd32(IGC_TXSTMPL);
>>
>> and a couple of lines later in this function you have
>>
>>              regval = txstmpl_new;
>>              regval |= (u64)rd32(IGC_TXSTMPH) << 32;
>>
>> According to the comment above, the value in the register will be
>> latched after reading IGC_TXSTMPH. As there will be no read of "low"
>> part of the register, it will stay latched with old value until the
>> next call to the same function. Could it be the reason of unit hangs?
>>
>> It looks like the value of previous read of IGC_TXSTMPH should be
>> stored and used to construct new timestamp, right?
>>
>
>I wouldn't trust the comment, but instead double check the data sheets.
>Unfortunately, I don't seem to have a copy of the igc hardware data sheet 
>handy :(
>
>Thanks,
>Jake

Flow before this patch:
        1. Read the TXTT bits into mask
        2. if TXTT_0 == 0, go to workaround ->If at this point register 0 
captures TX timestamp, and TXTT_0 is set but we think it is 0.
        3. Read LOW to OLD
        4. Read HIGH – this clears the TXTT_0
        5. Read LOW again , now to NEW.
        6. NEW==OLD, so the timestamp is discarded -> causing timestamp timeout
 
Flow after this patch:
        1. Read LOW to OLD
        2. Read the TXTT bits into mask
        3. if TXTT_0 == 0, go to workaround -> If at this point register 0 
captures TX timestamp, and TXTT_0 is set but we think it is 0.
        4. Read HIGH – this clears the TXTT_0
        5. Read LOW again , now to NEW.
        6. NEW!=OLD, so we detect this is a valid timestamp
              7. Read HIGH again and use the timestamp

Let me know if this address your questions?

Regards,
CL

Reply via email to