net: stmmac: ptp: switch to gettimex64() interface

The stmmac PTP support currently implements the gettime64 callback to
retrieve the hardware clock time. Update the implementation to provide
the gettimex64 callback instead, adding support for the
PTP_SYS_OFFSET_EXTENDED ioctl.

The system clock readings are taken around the read of the nanoseconds
register in get_systime(), so get_systime() gains a ptp_system_timestamp
argument.

Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Assisted-by: LLM
Signed-off-by: James Clark <jjc@jclark.com>
Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
Link: https://patch.msgid.link/20261008103809.1848255-1-jjc@jclark.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
James Clark 2026-10-08 17:38:09 +07:00 committed by Paolo Abeni
parent 26a8396802
commit d780425367
5 changed files with 24 additions and 16 deletions

View File

@ -493,6 +493,8 @@ struct stmmac_ops {
#define stmmac_fpe_map_preemption_class(__priv, __args...) \
stmmac_do_callback(__priv, mac, fpe_map_preemption_class, __args)
struct ptp_system_timestamp;
/* PTP and HW Timer helpers */
struct stmmac_hwtimestamp {
void (*config_hw_tstamping) (void __iomem *ioaddr, u32 data);
@ -502,7 +504,8 @@ struct stmmac_hwtimestamp {
int (*config_addend) (void __iomem *ioaddr, u32 addend);
int (*adjust_systime) (void __iomem *ioaddr, u32 sec, u32 nsec,
int add_sub, int gmac4);
void (*get_systime) (void __iomem *ioaddr, u64 *systime);
void (*get_systime)(void __iomem *ioaddr, u64 *systime,
struct ptp_system_timestamp *sts);
void (*get_ptptime)(void __iomem *ioaddr, u64 *ptp_time);
void (*timestamp_interrupt)(struct stmmac_priv *priv);
void (*hwtstamp_correct_latency)(struct stmmac_priv *priv);

View File

@ -183,7 +183,8 @@ static int adjust_systime(void __iomem *ioaddr, u32 sec, u32 nsec,
10, 100000);
}
static void get_systime(void __iomem *ioaddr, u64 *systime)
static void get_systime(void __iomem *ioaddr, u64 *systime,
struct ptp_system_timestamp *sts)
{
u64 ns, sec0, sec1;
@ -191,8 +192,10 @@ static void get_systime(void __iomem *ioaddr, u64 *systime)
sec1 = readl_relaxed(ioaddr + PTP_STSR);
do {
sec0 = sec1;
ptp_read_system_prets(sts);
/* Get the TSSS value */
ns = readl_relaxed(ioaddr + PTP_STNSR);
ns = readl(ioaddr + PTP_STNSR);
ptp_read_system_postts(sts);
/* Get the TSS value */
sec1 = readl_relaxed(ioaddr + PTP_STSR);
} while (sec0 != sec1);

View File

@ -89,7 +89,8 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 delta)
u64 cycle_time;
mutex_lock(&priv->est_lock);
priv->ptp_clock_ops.gettime64(&priv->ptp_clock_ops, &current_time);
priv->ptp_clock_ops.gettimex64(&priv->ptp_clock_ops,
&current_time, NULL);
current_time_ns = timespec64_to_ktime(current_time);
time.tv_nsec = priv->est->btr_reserve[0];
time.tv_sec = priv->est->btr_reserve[1];
@ -114,15 +115,15 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 delta)
}
/**
* stmmac_get_time
*
* stmmac_get_timex - read the PTP clock, with system timestamps if requested
* @ptp: pointer to ptp_clock_info structure
* @ts: pointer to hold time/result
* @sts: pointer to hold system timestamps around the read, or NULL
*
* Description: this function will read the current time from the
* hardware clock and store it in @ts.
* Return: 0
*/
static int stmmac_get_time(struct ptp_clock_info *ptp, struct timespec64 *ts)
static int stmmac_get_timex(struct ptp_clock_info *ptp, struct timespec64 *ts,
struct ptp_system_timestamp *sts)
{
struct stmmac_priv *priv =
container_of(ptp, struct stmmac_priv, ptp_clock_ops);
@ -130,7 +131,7 @@ static int stmmac_get_time(struct ptp_clock_info *ptp, struct timespec64 *ts)
u64 ns = 0;
read_lock_irqsave(&priv->ptp_lock, flags);
stmmac_get_systime(priv, priv->ptpaddr, &ns);
stmmac_get_systime(priv, priv->ptpaddr, &ns, sts);
read_unlock_irqrestore(&priv->ptp_lock, flags);
*ts = ns_to_timespec64(ns);
@ -200,7 +201,7 @@ static int stmmac_enable(struct ptp_clock_info *ptp,
target_ns = cfg->start.tv_nsec + ((u64)cfg->start.tv_sec * NSEC_PER_SEC);
stmmac_get_systime(priv, priv->ptpaddr, &ns);
stmmac_get_systime(priv, priv->ptpaddr, &ns, NULL);
if (ns > TIME64_MAX - PTP_SAFE_TIME_OFFSET_NS)
return -EINVAL;
@ -304,7 +305,7 @@ const struct ptp_clock_info stmmac_ptp_clock_ops = {
.pps = 0,
.adjfine = stmmac_adjust_freq,
.adjtime = stmmac_adjust_time,
.gettime64 = stmmac_get_time,
.gettimex64 = stmmac_get_timex,
.settime64 = stmmac_set_time,
.enable = stmmac_enable,
};
@ -321,7 +322,7 @@ const struct ptp_clock_info dwmac1000_ptp_clock_ops = {
.pps = 0,
.adjfine = stmmac_adjust_freq,
.adjtime = stmmac_adjust_time,
.gettime64 = stmmac_get_time,
.gettimex64 = stmmac_get_timex,
.settime64 = stmmac_set_time,
.enable = dwmac1000_ptp_enable,
};

View File

@ -1778,7 +1778,7 @@ static int stmmac_test_tbs(struct stmmac_priv *priv)
return ret;
read_lock_irqsave(&priv->ptp_lock, flags);
stmmac_get_systime(priv, priv->ptpaddr, &curr_time);
stmmac_get_systime(priv, priv->ptpaddr, &curr_time, NULL);
read_unlock_irqrestore(&priv->ptp_lock, flags);
if (!curr_time) {
@ -1800,7 +1800,7 @@ static int stmmac_test_tbs(struct stmmac_priv *priv)
/* Check if expected time has elapsed */
read_lock_irqsave(&priv->ptp_lock, flags);
stmmac_get_systime(priv, priv->ptpaddr, &curr_time);
stmmac_get_systime(priv, priv->ptpaddr, &curr_time, NULL);
read_unlock_irqrestore(&priv->ptp_lock, flags);
if ((curr_time - start_time) < STMMAC_TBS_LT_OFFSET)

View File

@ -1073,7 +1073,8 @@ static int tc_taprio_configure(struct stmmac_priv *priv,
mutex_lock(&priv->est_lock);
/* Adjust for real system time */
priv->ptp_clock_ops.gettime64(&priv->ptp_clock_ops, &current_time);
priv->ptp_clock_ops.gettimex64(&priv->ptp_clock_ops, &current_time,
NULL);
current_time_ns = timespec64_to_ktime(current_time);
time = stmmac_calc_tas_basetime(qopt->base_time, current_time_ns,
qopt->cycle_time);