summaryrefslogtreecommitdiff
path: root/lib/ethdev
diff options
context:
space:
mode:
authorMingjin Ye <[email protected]>2024-10-11 06:34:05 +0000
committerFerruh Yigit <[email protected]>2024-10-12 01:32:55 +0200
commitbe86a6823f5ae08efbdc11297425fa844508a15d (patch)
tree0a4ed3e1a66810f016936f111a4d0e030a6e555b /lib/ethdev
parent9c2e6e75f695f1c2ab1d2df99f1b4f427357609c (diff)
ethdev: add frequency adjustment
This patch adds freq adjustment API for PTP high accuracy. Signed-off-by: Simei Su <[email protected]> Signed-off-by: Mingjin Ye <[email protected]> Reviewed-by: Ferruh Yigit <[email protected]>
Diffstat (limited to 'lib/ethdev')
-rw-r--r--lib/ethdev/ethdev_driver.h5
-rw-r--r--lib/ethdev/ethdev_trace.h9
-rw-r--r--lib/ethdev/ethdev_trace_points.c3
-rw-r--r--lib/ethdev/rte_ethdev.c18
-rw-r--r--lib/ethdev/rte_ethdev.h43
-rw-r--r--lib/ethdev/version.map1
6 files changed, 79 insertions, 0 deletions
diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
index 620f1894e3..1fd4562b40 100644
--- a/lib/ethdev/ethdev_driver.h
+++ b/lib/ethdev/ethdev_driver.h
@@ -751,6 +751,9 @@ typedef int (*eth_timesync_read_tx_timestamp_t)(struct rte_eth_dev *dev,
/** @internal Function used to adjust the device clock. */
typedef int (*eth_timesync_adjust_time)(struct rte_eth_dev *dev, int64_t);
+/** @internal Function used to adjust the clock frequency. */
+typedef int (*eth_timesync_adjust_freq)(struct rte_eth_dev *dev, int64_t);
+
/** @internal Function used to get time from the device clock. */
typedef int (*eth_timesync_read_time)(struct rte_eth_dev *dev,
struct timespec *timestamp);
@@ -1511,6 +1514,8 @@ struct eth_dev_ops {
eth_timesync_read_tx_timestamp_t timesync_read_tx_timestamp;
/** Adjust the device clock */
eth_timesync_adjust_time timesync_adjust_time;
+ /** Adjust the clock frequency */
+ eth_timesync_adjust_freq timesync_adjust_freq;
/** Get the device clock time */
eth_timesync_read_time timesync_read_time;
/** Set the device clock time */
diff --git a/lib/ethdev/ethdev_trace.h b/lib/ethdev/ethdev_trace.h
index da4b3721ec..e96213365d 100644
--- a/lib/ethdev/ethdev_trace.h
+++ b/lib/ethdev/ethdev_trace.h
@@ -2185,6 +2185,15 @@ RTE_TRACE_POINT_FP(
rte_trace_point_emit_int(ret);
)
+/* Called in loop in examples/ptpclient */
+RTE_TRACE_POINT_FP(
+ rte_eth_trace_timesync_adjust_freq,
+ RTE_TRACE_POINT_ARGS(uint16_t port_id, int64_t ppm, int ret),
+ rte_trace_point_emit_u16(port_id);
+ rte_trace_point_emit_i64(ppm);
+ rte_trace_point_emit_int(ret);
+)
+
/* Called in loop in app/test-flow-perf */
RTE_TRACE_POINT_FP(
rte_flow_trace_create,
diff --git a/lib/ethdev/ethdev_trace_points.c b/lib/ethdev/ethdev_trace_points.c
index 902e4f7533..1f6ce341bf 100644
--- a/lib/ethdev/ethdev_trace_points.c
+++ b/lib/ethdev/ethdev_trace_points.c
@@ -415,6 +415,9 @@ RTE_TRACE_POINT_REGISTER(rte_eth_trace_timesync_read_tx_timestamp,
RTE_TRACE_POINT_REGISTER(rte_eth_trace_timesync_adjust_time,
lib.ethdev.timesync_adjust_time)
+RTE_TRACE_POINT_REGISTER(rte_eth_trace_timesync_adjust_freq,
+ lib.ethdev.timesync_adjust_freq)
+
RTE_TRACE_POINT_REGISTER(rte_eth_trace_timesync_read_time,
lib.ethdev.timesync_read_time)
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index 3f59672ddf..12f42f1d68 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -6398,6 +6398,24 @@ rte_eth_timesync_adjust_time(uint16_t port_id, int64_t delta)
}
int
+rte_eth_timesync_adjust_freq(uint16_t port_id, int64_t ppm)
+{
+ struct rte_eth_dev *dev;
+ int ret;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+ dev = &rte_eth_devices[port_id];
+
+ if (*dev->dev_ops->timesync_adjust_freq == NULL)
+ return -ENOTSUP;
+ ret = eth_err(port_id, (*dev->dev_ops->timesync_adjust_freq)(dev, ppm));
+
+ rte_eth_trace_timesync_adjust_freq(port_id, ppm, ret);
+
+ return ret;
+}
+
+int
rte_eth_timesync_read_time(uint16_t port_id, struct timespec *timestamp)
{
struct rte_eth_dev *dev;
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index 1c6bc14ed1..c4241d048c 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -5406,6 +5406,49 @@ int rte_eth_timesync_read_tx_timestamp(uint16_t port_id,
int rte_eth_timesync_adjust_time(uint16_t port_id, int64_t delta);
/**
+ * Adjust the clock frequency on an Ethernet device.
+ *
+ * Adjusts the base frequency by a specified percentage of ppm (parts per
+ * million). This is usually used in conjunction with other Ethdev timesync
+ * functions to synchronize the device time using the IEEE1588/802.1AS
+ * protocol.
+ *
+ * The clock is subject to frequency deviation and rate of change drift due to
+ * the environment. The upper layer APP calculates the frequency compensation
+ * value of the slave clock relative to the master clock via a servo algorithm
+ * and adjusts the device clock frequency via "rte_eth_timesync_adjust_freq()".
+ * Commonly used servo algorithms are pi/linreg/ntpshm, for implementation
+ * see: https://github.com/nxp-archive/openil_linuxptp.git.
+ *
+ * The adjustment value obtained by the servo algorithm is usually in
+ * ppb (parts per billion). For consistency with the kernel driver .adjfine,
+ * the tuning values are in ppm. Note that 1 ppb is approximately 65.536 scaled
+ * ppm, see Linux kernel upstream commit 1060707e3809 (‘ptp: introduce helpers
+ * to adjust by scaled parts per million’).
+ *
+ * In addition, the device reference frequency is usually also the stepping
+ * threshold for the servo algorithm, and the frequency up and down adjustment
+ * range is limited by the device. The device clock frequency should be
+ * adjusted with "rte_eth_timesync_adjust_freq()" every time the clock is
+ * synchronised. Also use ‘rte_eth_timesync_adjust_time()’ to update the device
+ * clock only if the absolute value of the master/slave clock offset is greater than
+ * or equal to the step threshold.
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @param ppm
+ * Parts per million with 16-bit fractional field
+ *
+ * @return
+ * - 0: Success.
+ * - -ENODEV: The port ID is invalid.
+ * - -EIO: if device is removed.
+ * - -ENOTSUP: The function is not supported by the Ethernet driver.
+ */
+__rte_experimental
+int rte_eth_timesync_adjust_freq(uint16_t port_id, int64_t ppm);
+
+/**
* Read the time from the timesync clock on an Ethernet device.
*
* This is usually used in conjunction with other Ethdev timesync functions to
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index 1c92714436..d42966ec85 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -334,6 +334,7 @@ EXPERIMENTAL {
rte_eth_speed_lanes_get;
rte_eth_speed_lanes_get_capability;
rte_eth_speed_lanes_set;
+ rte_eth_timesync_adjust_freq;
rte_flow_async_create_by_index_with_pattern;
};