2023-06-01 07:24:36

by Yuezhen Luan

[permalink] [raw]
Subject: [PATCH v2] igb: Fix extts capture value format for 82580/i354/i350

82580/i354/i350 features circle-counter-like timestamp registers
that are different with newer i210. The EXTTS capture value in
AUXTSMPx should be converted from raw circle counter value to
timestamp value in resolution of 1 nanosec by the driver.

This issue can be reproduced on i350 nics, connecting an 1PPS
signal to a SDP pin, and run 'ts2phc' command to read external
1PPS timestamp value. On i210 this works fine, but on i350 the
extts is not correctly converted.

The i350/i354/82580's SYSTIM and other timestamp registers are
40bit counters, presenting time range of 2^40 ns, that means these
registers overflows every about 1099s. This causes all these regs
can't be used directly in contrast to the newer i210/i211s.

The igb driver needs to convert these raw register values to
valid time stamp format by using kernel timecounter apis for i350s
families. Here the igb_extts() just forgot to do the convert.

Signed-off-by: Yuezhen Luan <[email protected]>
---
drivers/net/ethernet/intel/igb/igb_main.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 58872a4c2..bb3db387d 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -6947,6 +6947,7 @@ static void igb_extts(struct igb_adapter *adapter, int tsintr_tt)
struct e1000_hw *hw = &adapter->hw;
struct ptp_clock_event event;
struct timespec64 ts;
+ unsigned long flags;

if (pin < 0 || pin >= IGB_N_SDP)
return;
@@ -6954,9 +6955,12 @@ static void igb_extts(struct igb_adapter *adapter, int tsintr_tt)
if (hw->mac.type == e1000_82580 ||
hw->mac.type == e1000_i354 ||
hw->mac.type == e1000_i350) {
- s64 ns = rd32(auxstmpl);
+ u64 ns = rd32(auxstmpl);

- ns += ((s64)(rd32(auxstmph) & 0xFF)) << 32;
+ ns += ((u64)(rd32(auxstmph) & 0xFF)) << 32;
+ spin_lock_irqsave(&adapter->tmreg_lock, flags);
+ ns = timecounter_cyc2time(&adapter->tc, ns);
+ spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
ts = ns_to_timespec64(ns);
} else {
ts.tv_nsec = rd32(auxstmpl);
--
2.34.1



2023-06-01 17:22:43

by Jacob Keller

[permalink] [raw]
Subject: RE: [PATCH v2] igb: Fix extts capture value format for 82580/i354/i350



> -----Original Message-----
> From: Yuezhen Luan <[email protected]>
> Sent: Thursday, June 1, 2023 12:01 AM
> To: Brandeburg, Jesse <[email protected]>; Nguyen, Anthony L
> <[email protected]>; [email protected];
> [email protected]; [email protected]; [email protected]
> Cc: [email protected]; [email protected]; linux-
> [email protected]; Keller, Jacob E <[email protected]>; Yuezhen
> Luan <[email protected]>
> Subject: [PATCH v2] igb: Fix extts capture value format for 82580/i354/i350
>
> 82580/i354/i350 features circle-counter-like timestamp registers
> that are different with newer i210. The EXTTS capture value in
> AUXTSMPx should be converted from raw circle counter value to
> timestamp value in resolution of 1 nanosec by the driver.
>
> This issue can be reproduced on i350 nics, connecting an 1PPS
> signal to a SDP pin, and run 'ts2phc' command to read external
> 1PPS timestamp value. On i210 this works fine, but on i350 the
> extts is not correctly converted.
>
> The i350/i354/82580's SYSTIM and other timestamp registers are
> 40bit counters, presenting time range of 2^40 ns, that means these
> registers overflows every about 1099s. This causes all these regs
> can't be used directly in contrast to the newer i210/i211s.
>
> The igb driver needs to convert these raw register values to
> valid time stamp format by using kernel timecounter apis for i350s
> families. Here the igb_extts() just forgot to do the convert.
>
> Signed-off-by: Yuezhen Luan <[email protected]>

Reviewed-by: Jacob Keller <[email protected]>

Thanks for fixing this!

@Nguyen, Anthony L
I think this is a worthy net fix.

> ---
> drivers/net/ethernet/intel/igb/igb_main.c | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/igb/igb_main.c
> b/drivers/net/ethernet/intel/igb/igb_main.c
> index 58872a4c2..bb3db387d 100644
> --- a/drivers/net/ethernet/intel/igb/igb_main.c
> +++ b/drivers/net/ethernet/intel/igb/igb_main.c
> @@ -6947,6 +6947,7 @@ static void igb_extts(struct igb_adapter *adapter, int
> tsintr_tt)
> struct e1000_hw *hw = &adapter->hw;
> struct ptp_clock_event event;
> struct timespec64 ts;
> + unsigned long flags;
>
> if (pin < 0 || pin >= IGB_N_SDP)
> return;
> @@ -6954,9 +6955,12 @@ static void igb_extts(struct igb_adapter *adapter, int
> tsintr_tt)
> if (hw->mac.type == e1000_82580 ||
> hw->mac.type == e1000_i354 ||
> hw->mac.type == e1000_i350) {
> - s64 ns = rd32(auxstmpl);
> + u64 ns = rd32(auxstmpl);
>
> - ns += ((s64)(rd32(auxstmph) & 0xFF)) << 32;
> + ns += ((u64)(rd32(auxstmph) & 0xFF)) << 32;
> + spin_lock_irqsave(&adapter->tmreg_lock, flags);
> + ns = timecounter_cyc2time(&adapter->tc, ns);
> + spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
> ts = ns_to_timespec64(ns);
> } else {
> ts.tv_nsec = rd32(auxstmpl);
> --
> 2.34.1


2023-06-01 20:59:06

by Tony Nguyen

[permalink] [raw]
Subject: Re: [PATCH v2] igb: Fix extts capture value format for 82580/i354/i350

On 6/1/2023 10:05 AM, Keller, Jacob E wrote:
>
>
>> -----Original Message-----
>> From: Yuezhen Luan <[email protected]>
>> Sent: Thursday, June 1, 2023 12:01 AM
>> To: Brandeburg, Jesse <[email protected]>; Nguyen, Anthony L
>> <[email protected]>; [email protected];
>> [email protected]; [email protected]; [email protected]
>> Cc: [email protected]; [email protected]; linux-
>> [email protected]; Keller, Jacob E <[email protected]>; Yuezhen
>> Luan <[email protected]>
>> Subject: [PATCH v2] igb: Fix extts capture value format for 82580/i354/i350
>>
>> 82580/i354/i350 features circle-counter-like timestamp registers
>> that are different with newer i210. The EXTTS capture value in
>> AUXTSMPx should be converted from raw circle counter value to
>> timestamp value in resolution of 1 nanosec by the driver.
>>
>> This issue can be reproduced on i350 nics, connecting an 1PPS
>> signal to a SDP pin, and run 'ts2phc' command to read external
>> 1PPS timestamp value. On i210 this works fine, but on i350 the
>> extts is not correctly converted.
>>
>> The i350/i354/82580's SYSTIM and other timestamp registers are
>> 40bit counters, presenting time range of 2^40 ns, that means these
>> registers overflows every about 1099s. This causes all these regs
>> can't be used directly in contrast to the newer i210/i211s.
>>
>> The igb driver needs to convert these raw register values to
>> valid time stamp format by using kernel timecounter apis for i350s
>> families. Here the igb_extts() just forgot to do the convert.
>>
>> Signed-off-by: Yuezhen Luan <[email protected]>
>
> Reviewed-by: Jacob Keller <[email protected]>

Thanks for reviewing Jake.

> Thanks for fixing this!
>
> @Nguyen, Anthony L
> I think this is a worthy net fix.

Hi Yuezhen,

Could you include a Fixes: so that we can route this through net.

You should also add a target tree for your patch (net or net-next).
Here's some useful intro information for netdev [1].

Thanks,
Tony

[1]
https://www.kernel.org/doc/html/latest/process/maintainer-netdev.html#netdev-faq



2023-06-02 06:42:23

by Yuezhen Luan

[permalink] [raw]
Subject: Re: [PATCH v2] igb: Fix extts capture value format for 82580/i354/i350

Dear Tony and Jacob,

Thanks for the review, I'll optimize the patch soon.

Regards,
Yuezhen Luan