Timestamp in packet (TSIP) is enabled by TSYNCRXCTL.TSIP_UT_EN, which
covers untagged frames only. VLAN tagged frames need the per user priority
mask in TSYNCRXCTL[31:24], which was never set, so they carry no timestamp
and IXGBE_RXD_STAT_TSIP stays clear. ixgbe_ptp_rx_hwtstamp() then falls
back to RXSTMPL/RXSTMPH, which hold a single timestamp latched until read,
so a tagged frame is given a stale timestamp left by an earlier packet.
Filter type TYPE_ALL also clears IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER, which
gates ixgbe_ptp_rx_hang(), so a stuck latch is never cleared either.

Set TSIP_UP_MASK along with TSIP_UT_EN, add the missing register
definition, and extend the clear mask so the new bits are cleared when Rx
timestamping is disabled.

This covers 802.1Q priorities 0-7. The fallback itself is left in place:
any frame class the hardware reports with STAT_TS but without TSIP, such
as a QinQ outer tag, would still be given a latched timestamp. Suppressing
the fallback outside IN_REGISTER mode is a separate change.

Observed on a machine in real use: ptp4l over an 802.1Q interface never
converged, reporting path delay between 444 ns and 31 us and even negative
values, while the untagged interface held a stable 3 us. Reproduced by
adding a VLAN interface and running ptp4l on it, with no kernel
modification and no error injection. Tested against that reproducer on two
Intel E610 10GBASE-T ports connected back to back at 10 Gbps, where ptp4l
now converges over VLAN as it does untagged. No kernel selftests cover Rx
hardware timestamping.

Fixes: a9763f3cb54c ("ixgbe: Update PTP to support X550EM_x devices")
Signed-off-by: Przemyslaw Korba <[email protected]>
Reviewed-by: Milena Olech <[email protected]>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c  | 6 ++++--
 drivers/net/ethernet/intel/ixgbe/ixgbe_type.h | 1 +
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
index 8dc6a009b62c..4be7450beea8 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
@@ -1084,7 +1084,8 @@ static int ixgbe_ptp_set_timestamp_mode(struct 
ixgbe_adapter *adapter,
 
                tsync_rx_ctl = IXGBE_TSYNCRXCTL_ENABLED |
                               IXGBE_TSYNCRXCTL_TYPE_ALL |
-                              IXGBE_TSYNCRXCTL_TSIP_UT_EN;
+                              IXGBE_TSYNCRXCTL_TSIP_UT_EN |
+                              IXGBE_TSYNCRXCTL_TSIP_UP_MASK;
                config->rx_filter = HWTSTAMP_FILTER_ALL;
                aflags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED;
                aflags &= ~IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER;
@@ -1112,7 +1113,8 @@ static int ixgbe_ptp_set_timestamp_mode(struct 
ixgbe_adapter *adapter,
        /* enable/disable RX */
        regval = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL);
        regval &= ~(IXGBE_TSYNCRXCTL_ENABLED | IXGBE_TSYNCRXCTL_TYPE_MASK |
-                   IXGBE_TSYNCRXCTL_TSIP_UT_EN);
+                   IXGBE_TSYNCRXCTL_TSIP_UT_EN |
+                   IXGBE_TSYNCRXCTL_TSIP_UP_MASK);
        regval |= tsync_rx_ctl;
        IXGBE_WRITE_REG(hw, IXGBE_TSYNCRXCTL, regval);
 
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
index c2bd104e64bf..78067b49216d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
@@ -2283,6 +2283,7 @@ enum {
 #define IXGBE_TSYNCRXCTL_TYPE_EVENT_V2 0x0A
 #define IXGBE_TSYNCRXCTL_ENABLED       0x00000010 /* Rx Timestamping enabled */
 #define IXGBE_TSYNCRXCTL_TSIP_UT_EN    0x00800000 /* Rx Timestamp in Packet */
+#define IXGBE_TSYNCRXCTL_TSIP_UP_MASK  0xFF000000 /* Rx Timestamp UP Mask */
 
 #define IXGBE_TSIM_TXTS                        0x00000002
 
-- 
2.43.0

Reply via email to