Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4a674b8e authored by Yannick Vignon's avatar Yannick Vignon Committed by Greg Kroah-Hartman
Browse files

net: stmmac: ensure PTP time register reads are consistent



commit 80d4609008e6d696a279e39ae7458c916fcd44c1 upstream.

Even if protected from preemption and interrupts, a small time window
remains when the 2 register reads could return inconsistent values,
each time the "seconds" register changes. This could lead to an about
1-second error in the reported time.

Add logic to ensure the "seconds" and "nanoseconds" values are consistent.

Fixes: 92ba6888 ("stmmac: add the support for PTP hw clock driver")
Signed-off-by: default avatarYannick Vignon <yannick.vignon@nxp.com>
Reviewed-by: default avatarRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
Link: https://lore.kernel.org/r/20220203160025.750632-1-yannick.vignon@oss.nxp.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 9afc0286
Loading
Loading
Loading
Loading
+12 −7
Original line number Diff line number Diff line
@@ -149,15 +149,20 @@ static int adjust_systime(void __iomem *ioaddr, u32 sec, u32 nsec,

static void get_systime(void __iomem *ioaddr, u64 *systime)
{
	u64 ns;
	u64 ns, sec0, sec1;

	/* Get the TSS value */
	sec1 = readl_relaxed(ioaddr + PTP_STSR);
	do {
		sec0 = sec1;
		/* Get the TSSS value */
	ns = readl(ioaddr + PTP_STNSR);
	/* Get the TSS and convert sec time value to nanosecond */
	ns += readl(ioaddr + PTP_STSR) * 1000000000ULL;
		ns = readl_relaxed(ioaddr + PTP_STNSR);
		/* Get the TSS value */
		sec1 = readl_relaxed(ioaddr + PTP_STSR);
	} while (sec0 != sec1);

	if (systime)
		*systime = ns;
		*systime = ns + (sec1 * 1000000000ULL);
}

const struct stmmac_hwtimestamp stmmac_ptp = {