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. 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 Signed-off-by: Zxyan Zhu --- 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