diff options
| author | Jakub Kicinski <kuba@kernel.org> | 2025-09-03 16:51:12 -0700 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2025-09-03 16:51:12 -0700 |
| commit | 648d628db536adfd8ae5e61b7a82908af8683918 (patch) | |
| tree | 1c5816e763b5f20ae9d09a7c99b1b6f7c2c84001 | |
| parent | 59aec9138f3056f0f6a521e065fd85853227bf45 (diff) | |
| parent | adbe2cfd8a93fdefb2bd238c1ccd22d2c40e8499 (diff) | |
Merge branch 'net-stmmac-allow-generation-of-flexible-pps-relative-to-mac-time'
Gatien Chevallier says:
====================
net: stmmac: allow generation of flexible PPS relative to MAC time
When doing some testing on stm32mp2x platforms(MACv5), I noticed that
the command previously used with a MACv4 for genering a PPS signal:
echo "0 0 0 1 1" > /sys/class/ptp/ptp0/period
did not work.
This is because the arguments passed through this command must contain
the start time at which the PPS should be generated, relative to the
MAC system time. For some reason, a time set in the past seems to work
with a MACv4.
Because passing such an argument is tedious, consider that any time
set in the past is an offset regarding the MAC system time. This way,
this does not impact existing scripts and the past time use case is
handled. Edit: But maybe that's not important and we can just change
the default behavior to this.
Example to generate a flexible PPS signal that has a 1s period 3s
relative to when the command was entered:
echo "0 3 0 1 1" > /sys/class/ptp/ptp0/period
====================
Link: https://patch.msgid.link/20250901-relative_flex_pps-v4-0-b874971dfe85@foss.st.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c | 34 | ||||
| -rw-r--r-- | kernel/time/time.c | 1 |
2 files changed, 34 insertions, 1 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c index 3767ba495e78..ecbff20771f4 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c @@ -10,6 +10,8 @@ #include "stmmac.h" #include "stmmac_ptp.h" +#define PTP_SAFE_TIME_OFFSET_NS 500000 + /** * stmmac_adjust_freq * @@ -171,7 +173,11 @@ static int stmmac_enable(struct ptp_clock_info *ptp, u32 acr_value; switch (rq->type) { - case PTP_CLK_REQ_PEROUT: + case PTP_CLK_REQ_PEROUT: { + struct timespec64 curr_time; + u64 target_ns = 0; + u64 ns = 0; + /* Reject requests with unsupported flags */ if (rq->perout.flags) return -EOPNOTSUPP; @@ -180,6 +186,31 @@ static int stmmac_enable(struct ptp_clock_info *ptp, cfg->start.tv_sec = rq->perout.start.sec; cfg->start.tv_nsec = rq->perout.start.nsec; + + /* A time set in the past won't trigger the start of the flexible PPS generation for + * the GMAC5. For some reason it does for the GMAC4 but setting a time in the past + * should be addressed anyway. Therefore, any value set it the past is considered as + * an offset compared to the current MAC system time. + * Be aware that an offset too low may not trigger flexible PPS generation + * if time spent in this configuration makes the targeted time already outdated. + * To address this, add a safe time offset. + */ + if (!cfg->start.tv_sec && cfg->start.tv_nsec < PTP_SAFE_TIME_OFFSET_NS) + cfg->start.tv_nsec += PTP_SAFE_TIME_OFFSET_NS; + + target_ns = cfg->start.tv_nsec + ((u64)cfg->start.tv_sec * NSEC_PER_SEC); + + stmmac_get_systime(priv, priv->ptpaddr, &ns); + if (ns > TIME64_MAX - PTP_SAFE_TIME_OFFSET_NS) + return -EINVAL; + + curr_time = ns_to_timespec64(ns); + if (target_ns < ns + PTP_SAFE_TIME_OFFSET_NS) { + cfg->start = timespec64_add_safe(cfg->start, curr_time); + if (cfg->start.tv_sec == TIME64_MAX) + return -EINVAL; + } + cfg->period.tv_sec = rq->perout.period.sec; cfg->period.tv_nsec = rq->perout.period.nsec; @@ -190,6 +221,7 @@ static int stmmac_enable(struct ptp_clock_info *ptp, priv->systime_flags); write_unlock_irqrestore(&priv->ptp_lock, flags); break; + } case PTP_CLK_REQ_EXTTS: { u8 channel; diff --git a/kernel/time/time.c b/kernel/time/time.c index 1b69caa87480..0ba8e3c50d62 100644 --- a/kernel/time/time.c +++ b/kernel/time/time.c @@ -858,6 +858,7 @@ struct timespec64 timespec64_add_safe(const struct timespec64 lhs, return res; } +EXPORT_SYMBOL_GPL(timespec64_add_safe); /** * get_timespec64 - get user's time value into kernel space |
