[PATCH net-next v4 2/2] net: stmmac: dwmac-socfpga: mask XGMAC_TSIE during cross-timestamp
From: Zxyan Zhu <hidden>
Date: 2026-09-02 13:15:21
Also in:
linux-arm-kernel, lkml
Subsystem:
arm/socfpga dwmac glue layer, networking drivers, stmmac ethernet driver, the rest · Maintainers:
Maxime Chevallier, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
The Agilex5 smtg_crosststamp() handler arms an internal auxiliary snapshot, toggles GPO0 and then polls XGMAC_INT_STATUS for TSIS in process context to learn that the snapshot is ready. Unlike the Intel cross-timestamp path it does not set STMMAC_FLAG_INT_SNAPSHOT_EN, so it relies on nothing else consuming TSIS. Once XGMAC_TSIE is unmasked (done by a companion change that enables it in XGMAC_INT_DEFAULT_EN), the DWXGMAC2 timestamp interrupt handler runs from hardirq on every timestamp event and clears TSIS by reading XGMAC_TIMESTAMP_STATUS. That read can win the race against the poll loop, which then times out and makes PTP_SYS_OFFSET_PRECISE fail with "Wait for time sync operation timeout". Mask XGMAC_TSIE around the snapshot trigger and FIFO read so the hardirq handler cannot clear TSIS while smtg_crosststamp() owns it, and restore it on every return path. Tested-by: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com> Signed-off-by: Zxyan Zhu <redacted> --- drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
index 1d7f0a57d288..a4d00bf81423 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c@@ -310,6 +310,13 @@ static int smtg_crosststamp(ktime_t *device, struct system_counterval_t *system, if (priv->plat->flags & STMMAC_FLAG_EXT_SNAPSHOT_EN) return -EBUSY; + /* The XGMAC timestamp interrupt handler clears TSIS by reading + * XGMAC_TIMESTAMP_STATUS, which would race with the TSIS poll + * below. Mask XGMAC_TSIE for the duration of the cross-timestamp + * so the handler does not run while we own the snapshot FIFO. + */ + stmmac_mac_irq_modify(priv, XGMAC_TSIE, 0); + mutex_lock(&priv->aux_ts_lock); /* Enable Internal snapshot trigger */ acr_value = readl(ptpaddr + PTP_ACR);
@@ -329,6 +336,7 @@ static int smtg_crosststamp(ktime_t *device, struct system_counterval_t *system, break; default: mutex_unlock(&priv->aux_ts_lock); + stmmac_mac_irq_modify(priv, 0, XGMAC_TSIE); return -EINVAL; } writel(acr_value, ptpaddr + PTP_ACR);
@@ -353,6 +361,7 @@ static int smtg_crosststamp(ktime_t *device, struct system_counterval_t *system, ret = readl_poll_timeout(priv->ioaddr + XGMAC_INT_STATUS, v, (v & XGMAC_INT_TSIS), 100, 10000); if (ret) { + stmmac_mac_irq_modify(priv, 0, XGMAC_TSIE); netdev_err(priv->dev, "%s: Wait for time sync operation timeout\n", __func__); return ret;
@@ -375,6 +384,8 @@ static int smtg_crosststamp(ktime_t *device, struct system_counterval_t *system, read_unlock_irqrestore(&priv->ptp_lock, flags); } + stmmac_mac_irq_modify(priv, 0, XGMAC_TSIE); + get_smtgtime(priv->mii, SMTG_MDIO_ADDR, &smtg_time); system->cycles = smtg_time;
--
2.34.1