Skip to content

Commit 20bf98c

Browse files
Johannes Zinkkuba-moo
authored andcommitted
net: stmmac: correct MAC propagation delay
The IEEE1588 Standard specifies that the timestamps of Packets must be captured when the PTP message timestamp point (leading edge of first octet after the start of frame delimiter) crosses the boundary between the node and the network. As the MAC latches the timestamp at an internal point, the captured timestamp must be corrected for the additional path latency, as described in the publicly available datasheet [1]. This patch only corrects for the MAC-Internal delay, which can be read out from the MAC_Ingress_Timestamp_Latency register, since the Phy framework currently does not support querying the Phy ingress and egress latency. The Closs Domain Crossing Circuits errors as indicated in [1] are already being accounted in the stmmac_get_tx_hwtstamp() function and are not corrected here. As the Latency varies for different link speeds and MII modes of operation, the correction value needs to be updated on each link state change. As the delay also causes a phase shift in the timestamp counter compared to the rest of the network, this correction will also reduce phase error when generating PPS outputs from the timestamp counter. [1] i.MX8MP Reference Manual, rev.1 Section 11.7.2.5.3 "Timestamp correction" Signed-off-by: Johannes Zink <j.zink@pengutronix.de> Link: https://lore.kernel.org/r/20230719-stmmac_correct_mac_delay-v2-1-3366f38ee9a6@pengutronix.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 09bd2d7 commit 20bf98c

File tree

4 files changed

+56
-0
lines changed

4 files changed

+56
-0
lines changed

drivers/net/ethernet/stmicro/stmmac/hwif.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,7 @@ struct stmmac_hwtimestamp {
532532
void (*get_systime) (void __iomem *ioaddr, u64 *systime);
533533
void (*get_ptptime)(void __iomem *ioaddr, u64 *ptp_time);
534534
void (*timestamp_interrupt)(struct stmmac_priv *priv);
535+
void (*correct_latency)(struct stmmac_priv *priv);
535536
};
536537

537538
#define stmmac_config_hw_tstamping(__priv, __args...) \
@@ -550,6 +551,8 @@ struct stmmac_hwtimestamp {
550551
stmmac_do_void_callback(__priv, ptp, get_ptptime, __args)
551552
#define stmmac_timestamp_interrupt(__priv, __args...) \
552553
stmmac_do_void_callback(__priv, ptp, timestamp_interrupt, __args)
554+
#define stmmac_correct_latency(__priv, __args...) \
555+
stmmac_do_void_callback(__priv, ptp, correct_latency, __args)
553556

554557
struct stmmac_tx_queue;
555558
struct stmmac_rx_queue;

drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,48 @@ static void config_sub_second_increment(void __iomem *ioaddr,
6060
*ssinc = data;
6161
}
6262

63+
static void correct_latency(struct stmmac_priv *priv)
64+
{
65+
void __iomem *ioaddr = priv->ptpaddr;
66+
u32 reg_tsic, reg_tsicsns;
67+
u32 reg_tsec, reg_tsecsns;
68+
u64 scaled_ns;
69+
u32 val;
70+
71+
/* MAC-internal ingress latency */
72+
scaled_ns = readl(ioaddr + PTP_TS_INGR_LAT);
73+
74+
/* See section 11.7.2.5.3.1 "Ingress Correction" on page 4001 of
75+
* i.MX8MP Applications Processor Reference Manual Rev. 1, 06/2021
76+
*/
77+
val = readl(ioaddr + PTP_TCR);
78+
if (val & PTP_TCR_TSCTRLSSR)
79+
/* nanoseconds field is in decimal format with granularity of 1ns/bit */
80+
scaled_ns = ((u64)NSEC_PER_SEC << 16) - scaled_ns;
81+
else
82+
/* nanoseconds field is in binary format with granularity of ~0.466ns/bit */
83+
scaled_ns = ((1ULL << 31) << 16) -
84+
DIV_U64_ROUND_CLOSEST(scaled_ns * PSEC_PER_NSEC, 466U);
85+
86+
reg_tsic = scaled_ns >> 16;
87+
reg_tsicsns = scaled_ns & 0xff00;
88+
89+
/* set bit 31 for 2's compliment */
90+
reg_tsic |= BIT(31);
91+
92+
writel(reg_tsic, ioaddr + PTP_TS_INGR_CORR_NS);
93+
writel(reg_tsicsns, ioaddr + PTP_TS_INGR_CORR_SNS);
94+
95+
/* MAC-internal egress latency */
96+
scaled_ns = readl(ioaddr + PTP_TS_EGR_LAT);
97+
98+
reg_tsec = scaled_ns >> 16;
99+
reg_tsecsns = scaled_ns & 0xff00;
100+
101+
writel(reg_tsec, ioaddr + PTP_TS_EGR_CORR_NS);
102+
writel(reg_tsecsns, ioaddr + PTP_TS_EGR_CORR_SNS);
103+
}
104+
63105
static int init_systime(void __iomem *ioaddr, u32 sec, u32 nsec)
64106
{
65107
u32 value;
@@ -221,4 +263,5 @@ const struct stmmac_hwtimestamp stmmac_ptp = {
221263
.get_systime = get_systime,
222264
.get_ptptime = get_ptptime,
223265
.timestamp_interrupt = timestamp_interrupt,
266+
.correct_latency = correct_latency,
224267
};

drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,8 @@ static int stmmac_init_ptp(struct stmmac_priv *priv)
909909
priv->hwts_tx_en = 0;
910910
priv->hwts_rx_en = 0;
911911

912+
stmmac_correct_latency(priv, priv);
913+
912914
return 0;
913915
}
914916

@@ -1094,6 +1096,8 @@ static void stmmac_mac_link_up(struct phylink_config *config,
10941096

10951097
if (priv->dma_cap.fpesel)
10961098
stmmac_fpe_link_state_handle(priv, true);
1099+
1100+
stmmac_correct_latency(priv, priv);
10971101
}
10981102

10991103
static const struct phylink_mac_ops stmmac_phylink_mac_ops = {

drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@
2626
#define PTP_ACR 0x40 /* Auxiliary Control Reg */
2727
#define PTP_ATNR 0x48 /* Auxiliary Timestamp - Nanoseconds Reg */
2828
#define PTP_ATSR 0x4c /* Auxiliary Timestamp - Seconds Reg */
29+
#define PTP_TS_INGR_CORR_NS 0x58 /* Ingress timestamp correction nanoseconds */
30+
#define PTP_TS_EGR_CORR_NS 0x5C /* Egress timestamp correction nanoseconds*/
31+
#define PTP_TS_INGR_CORR_SNS 0x60 /* Ingress timestamp correction subnanoseconds */
32+
#define PTP_TS_EGR_CORR_SNS 0x64 /* Egress timestamp correction subnanoseconds */
33+
#define PTP_TS_INGR_LAT 0x68 /* MAC internal Ingress Latency */
34+
#define PTP_TS_EGR_LAT 0x6c /* MAC internal Egress Latency */
2935

3036
#define PTP_STNSUR_ADDSUB_SHIFT 31
3137
#define PTP_DIGITAL_ROLLOVER_MODE 0x3B9ACA00 /* 10e9-1 ns */

0 commit comments

Comments
 (0)