[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20221202201528.26634-2-rrameshbabu@nvidia.com>
Date: Fri, 2 Dec 2022 12:15:29 -0800
From: Rahul Rameshbabu <rrameshbabu@...dia.com>
To: Saeed Mahameed <saeedm@...dia.com>,
Leon Romanovsky <leon@...nel.org>,
"David S. Miller" <davem@...emloft.net>,
Eric Dumazet <edumazet@...gle.com>,
Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>,
Richard Cochran <richardcochran@...il.com>,
Rahul Rameshbabu <rrameshbabu@...dia.com>,
Jacob Keller <jacob.e.keller@...el.com>,
Aya Levin <ayal@...dia.com>, Gal Pressman <gal@...dia.com>
Cc: netdev@...r.kernel.org
Subject: [PATCH net-next 1/2] ptp: Add .getfine function to support reporting frequency offset from hardware
Query the hardware for the operational frequency (represented in 16-bit
fractional parts-per-million) instead of caching the value last set by the
last adjfine command. Prevent inconsistencies between the ptp driver and
the hardware.
For drivers that do not implement the .getfine callback, the cached value
is used.
The linuxptp community has seen cases where the cached value for frequency
is incorrect due to concurrent ptp4l processes adjusting frequency but each
using a stale cache value for frequency. The .getfine callback remedies
that by letting implementers provide a method for querying the frequency.
Signed-off-by: Rahul Rameshbabu <rrameshbabu@...dia.com>
Reviewed-by: Gal Pressman <gal@...dia.com>
Cc: Richard Cochran <richardcochran@...il.com>
---
drivers/ptp/ptp_clock.c | 18 +++++++++++++++++-
include/linux/ptp_clock_kernel.h | 6 ++++++
2 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c
index 62d4d29e7c05..1655381ae731 100644
--- a/drivers/ptp/ptp_clock.c
+++ b/drivers/ptp/ptp_clock.c
@@ -66,6 +66,22 @@ static void enqueue_external_timestamp(struct timestamp_event_queue *queue,
/* posix clock implementation */
+static long ptp_get_fine(struct ptp_clock *ptp)
+{
+ struct ptp_clock_info *ops = ptp->info;
+
+ if (ops->getfine) {
+ long fine;
+
+ if (ops->getfine(ops, &fine))
+ return ptp->dialed_frequency;
+
+ return fine;
+ }
+
+ return ptp->dialed_frequency;
+}
+
static int ptp_clock_getres(struct posix_clock *pc, struct timespec64 *tp)
{
tp->tv_sec = 0;
@@ -143,7 +159,7 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct __kernel_timex *tx)
err = ops->adjphase(ops, offset);
}
} else if (tx->modes == 0) {
- tx->freq = ptp->dialed_frequency;
+ tx->freq = ptp_get_fine(ptp);
err = 0;
}
diff --git a/include/linux/ptp_clock_kernel.h b/include/linux/ptp_clock_kernel.h
index fdffa6a98d79..f17097de349e 100644
--- a/include/linux/ptp_clock_kernel.h
+++ b/include/linux/ptp_clock_kernel.h
@@ -77,6 +77,11 @@ struct ptp_system_timestamp {
* nominal frequency in parts per million, but with a
* 16 bit binary fractional field.
*
+ * @getfine: Reads the current frequency offset from the hardware clock.
+ * parameter scaled_ppm: Requested frequency offset from
+ * nominal frequency in parts per million, but with a
+ * 16 bit binary fractional field.
+ *
* @adjphase: Adjusts the phase offset of the hardware clock.
* parameter delta: Desired change in nanoseconds.
*
@@ -168,6 +173,7 @@ struct ptp_clock_info {
int pps;
struct ptp_pin_desc *pin_config;
int (*adjfine)(struct ptp_clock_info *ptp, long scaled_ppm);
+ int (*getfine)(struct ptp_clock_info *ptp, long *scaled_ppm);
int (*adjphase)(struct ptp_clock_info *ptp, s32 phase);
int (*adjtime)(struct ptp_clock_info *ptp, s64 delta);
int (*gettime64)(struct ptp_clock_info *ptp, struct timespec64 *ts);
--
2.36.2
Powered by blists - more mailing lists