RE: [PATCH v2] net/cpfl: add timesync support
"Mandal, Anurag" <[email protected]>
| Newsgroups | org.dpdk.dev |
|---|---|
| Message-ID | <SA1PR11MB67825EC0A3DAC9E8282B44FEE4A72@SA1PR11MB6782.namprd11.prod.outlook.com> |
Hi All, Gentle reminder for review & ack. Thank you. Regards, Anurag M > -----Original Message----- > From: Mandal, Anurag <[email protected]> > Sent: 03 August 2026 15:00 > To: [email protected] > Cc: Richardson, Bruce <[email protected]>; Shetty, Praveen > <[email protected]>; Mandal, Anurag <[email protected]> > Subject: [PATCH v2] net/cpfl: add timesync support > > The cpfl PMD advertises RTE_ETH_RX_OFFLOAD_TIMESTAMP, so received > packets carry a 32-bit hardware timestamp that the common idpf Rx path > extends to 64-bit nanoseconds using the device PTP clock (PHC). > However, it never initialised the PHC, so the timestamp conversion had no > reference time. > Applications had no way to enable timestamping or to read the current device > clock to correlate the mbuf timestamps. > > This patch adds PTP support by reusing the idpf common PTP helpers: > > - timesync_enable: allocate and initialise the adapter PTP state, > query the PTP capabilities, program the base increment value > and set the device clock to the current system time. > The PTP state is shared by all vports of an adapter, so it > is initialised only once. > > - timesync_read_time: return the current device clock as a timespec. > > - timesync_disable: release the PTP state. > > Once timesync is enabled, the common Rx path resolves the cached PHC time, > so the mbuf Rx timestamp dynfield reports valid nanosecond values and > applications can read the device clock with rte_eth_timesync_read_time(). > > Signed-off-by: Anurag Mandal <[email protected]> > --- > V2: Removed read_clock support > > drivers/net/intel/cpfl/cpfl_ethdev.c | 107 +++++++++++++++++++++++++++ > drivers/net/intel/cpfl/cpfl_ethdev.h | 1 + > drivers/net/intel/idpf/idpf_ptp.c | 5 ++ > drivers/net/intel/idpf/idpf_ptp.h | 4 + > 4 files changed, 117 insertions(+) > > diff --git a/drivers/net/intel/cpfl/cpfl_ethdev.c > b/drivers/net/intel/cpfl/cpfl_ethdev.c > index 4315adb68c..e4dabd8043 100644 > --- a/drivers/net/intel/cpfl/cpfl_ethdev.c > +++ b/drivers/net/intel/cpfl/cpfl_ethdev.c > @@ -1335,6 +1335,110 @@ cpfl_hairpin_unbind(struct rte_eth_dev *dev, > uint16_t rx_port) > return 0; > } > > +static int > +cpfl_timesync_enable(struct rte_eth_dev *dev) { > + struct cpfl_vport *cpfl_vport = dev->data->dev_private; > + struct idpf_vport *vport = &cpfl_vport->base; > + struct idpf_adapter *adapter = vport->adapter; > + struct timespec sys_ts; > + uint64_t ns; > + int ret; > + > + if (dev->data->dev_started && !(dev->data- > >dev_conf.rxmode.offloads & > + RTE_ETH_RX_OFFLOAD_TIMESTAMP)) { > + PMD_DRV_LOG(ERR, "Rx timestamp offload not configured"); > + return -1; > + } > + > + /* PTP state is shared by all vports of the adapter. */ > + if (adapter->ptp != NULL) > + return 0; > + > + adapter->ptp = rte_zmalloc(NULL, sizeof(struct idpf_ptp), 0); > + if (adapter->ptp == NULL) { > + PMD_DRV_LOG(ERR, "Failed to allocate memory for PTP"); > + return -ENOMEM; > + } > + > + ret = idpf_ptp_get_caps(adapter); > + if (ret) { > + PMD_DRV_LOG(ERR, "Failed to get PTP capabilities, err=%d", > ret); > + goto fail_ptp; > + } > + > + /* > + * Write the default increment time value if the clock adjustments > + * are enabled. > + */ > + if (adapter->ptp->adj_dev_clk_time_access != IDPF_PTP_NONE) { > + ret = idpf_ptp_adj_dev_clk_fine(adapter, adapter->ptp- > >base_incval); > + if (ret) { > + PMD_DRV_LOG(ERR, "PTP set incval failed, err=%d", > ret); > + goto fail_ptp; > + } > + } > + > + /* Do not initialize the PTP if the device clock time cannot be read. */ > + if (adapter->ptp->get_dev_clk_time_access == IDPF_PTP_NONE) { > + PMD_DRV_LOG(ERR, "Getting device clock time is not > supported"); > + ret = -EIO; > + goto fail_ptp; > + } > + > + /* Set the device clock time to system time. */ > + if (adapter->ptp->set_dev_clk_time_access != IDPF_PTP_NONE) { > + clock_gettime(CLOCK_REALTIME, &sys_ts); > + ns = rte_timespec_to_ns(&sys_ts); > + ret = idpf_ptp_set_dev_clk_time(adapter, ns); > + if (ret) { > + PMD_DRV_LOG(ERR, "PTP set clock time failed, > err=%d", ret); > + goto fail_ptp; > + } > + } > + > + adapter->ptp->cmd.shtime_enable_mask = > PF_GLTSYN_CMD_SYNC_SHTIME_EN_M; > + adapter->ptp->cmd.exec_cmd_mask = > PF_GLTSYN_CMD_SYNC_EXEC_CMD_M; > + > + return 0; > + > +fail_ptp: > + rte_free(adapter->ptp); > + adapter->ptp = NULL; > + return ret; > +} > + > +static int > +cpfl_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts) { > + struct cpfl_vport *cpfl_vport = dev->data->dev_private; > + struct idpf_adapter *adapter = cpfl_vport->base.adapter; > + uint64_t time; > + int ret; > + > + ret = idpf_ptp_read_src_clk_reg(adapter, &time); > + if (ret) > + PMD_DRV_LOG(ERR, "PTP read time failed, err %d", ret); > + else > + *ts = rte_ns_to_timespec(time); > + > + return ret; > +} > + > +static int > +cpfl_timesync_disable(struct rte_eth_dev *dev) { > + struct cpfl_vport *cpfl_vport = dev->data->dev_private; > + struct idpf_adapter *adapter = cpfl_vport->base.adapter; > + > + if (adapter->ptp != NULL) { > + rte_free(adapter->ptp); > + adapter->ptp = NULL; > + } > + > + return 0; > +} > + > static const struct eth_dev_ops cpfl_eth_dev_ops = { > .dev_configure = cpfl_dev_configure, > .dev_close = cpfl_dev_close, > @@ -1368,6 +1472,9 @@ static const struct eth_dev_ops cpfl_eth_dev_ops = > { > .hairpin_get_peer_ports = cpfl_hairpin_get_peer_ports, > .hairpin_bind = cpfl_hairpin_bind, > .hairpin_unbind = cpfl_hairpin_unbind, > + .timesync_enable = cpfl_timesync_enable, > + .timesync_read_time = cpfl_timesync_read_time, > + .timesync_disable = cpfl_timesync_disable, > }; > > static int > diff --git a/drivers/net/intel/cpfl/cpfl_ethdev.h > b/drivers/net/intel/cpfl/cpfl_ethdev.h > index d41aa93191..a9e532a46c 100644 > --- a/drivers/net/intel/cpfl/cpfl_ethdev.h > +++ b/drivers/net/intel/cpfl/cpfl_ethdev.h > @@ -16,6 +16,7 @@ > > #include <idpf_common_device.h> > #include <idpf_common_virtchnl.h> > +#include <idpf_ptp.h> > #include <base/idpf_prototype.h> > #include <base/virtchnl2.h> > > diff --git a/drivers/net/intel/idpf/idpf_ptp.c > b/drivers/net/intel/idpf/idpf_ptp.c > index 5c3fcb90e4..47830de239 100644 > --- a/drivers/net/intel/idpf/idpf_ptp.c > +++ b/drivers/net/intel/idpf/idpf_ptp.c > @@ -2,6 +2,7 @@ > * Copyright(c) 2025 Intel Corporation > */ > > +#include <eal_export.h> > #include "idpf_ptp.h" > #include "idpf_common_virtchnl.h" > #include "base/virtchnl2.h" > @@ -38,6 +39,7 @@ idpf_ptp_get_features_access(const struct idpf_adapter > *adapter) > IDPF_PTP_ACCESS(adapter, > VIRTCHNL2_CAP_PTP_TX_TSTAMPS); } > > +RTE_EXPORT_INTERNAL_SYMBOL(idpf_ptp_get_caps) > int > idpf_ptp_get_caps(struct idpf_adapter *adapter) { @@ -212,6 +214,7 @@ > idpf_ptp_get_cross_time(struct idpf_adapter *adapter, > return err; > } > > +RTE_EXPORT_INTERNAL_SYMBOL(idpf_ptp_set_dev_clk_time) > int > idpf_ptp_set_dev_clk_time(struct idpf_adapter *adapter, uint64_t time) { > @@ -256,6 +259,7 @@ idpf_ptp_adj_dev_clk_time(struct idpf_adapter > *adapter, int64_t delta) > return err; > } > > +RTE_EXPORT_INTERNAL_SYMBOL(idpf_ptp_adj_dev_clk_fine) > int > idpf_ptp_adj_dev_clk_fine(struct idpf_adapter *adapter, uint64_t incval) { > @@ -487,6 +491,7 @@ idpf_ptp_read_src_clk_reg_mailbox(struct > idpf_adapter *adapter, > * > * Return: 0 on success, -errno otherwise. > */ > +RTE_EXPORT_INTERNAL_SYMBOL(idpf_ptp_read_src_clk_reg) > int > idpf_ptp_read_src_clk_reg(struct idpf_adapter *adapter, uint64_t *src_clk) { > diff --git a/drivers/net/intel/idpf/idpf_ptp.h > b/drivers/net/intel/idpf/idpf_ptp.h > index 0c901440fb..851cdad027 100644 > --- a/drivers/net/intel/idpf/idpf_ptp.h > +++ b/drivers/net/intel/idpf/idpf_ptp.h > @@ -88,13 +88,17 @@ struct idpf_ptp_dev_timers { > uint64_t dev_clk_time_ns; > }; > > +__rte_internal > int idpf_ptp_get_caps(struct idpf_adapter *adapter); > +__rte_internal > int idpf_ptp_read_src_clk_reg(struct idpf_adapter *adapter, uint64_t > *src_clk); int idpf_ptp_get_dev_clk_time(struct idpf_adapter *adapter, > struct idpf_ptp_dev_timers *dev_clk_time); int > idpf_ptp_get_cross_time(struct idpf_adapter *adapter, > struct idpf_ptp_dev_timers *cross_time); > +__rte_internal > int idpf_ptp_set_dev_clk_time(struct idpf_adapter *adapter, uint64_t time); > +__rte_internal > int idpf_ptp_adj_dev_clk_fine(struct idpf_adapter *adapter, uint64_t incval); > int idpf_ptp_adj_dev_clk_time(struct idpf_adapter *adapter, int64_t delta); > int idpf_ptp_get_vport_tstamps_caps(struct idpf_vport *vport); > -- > 2.34.1