From: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
To: Maciek Machnikowski <maciek@machnikowski.net>, kuba@kernel.org
Cc: maciek@machnikowski.net, richardcochran@gmail.com,
netdev@vger.kernel.org, milena.olech@intel.com
Subject: Re: [PATCH net-next 2/2] netdevsim: Implement basic ptp support
Date: Fri, 20 Feb 2026 15:08:17 -0500 [thread overview]
Message-ID: <willemdebruijn.kernel.1957319fee759@gmail.com> (raw)
In-Reply-To: <20260219140530.2148-3-maciek@machnikowski.net>
Maciek Machnikowski wrote:
> Add support for virtual timestamping inside the netdevsim driver.
> The implementation uses two attached ptp_mock clocks, reads the timestamps
> of the ones attached either to the netdevsim or its peer and returns
> timestamps using standard timestamps APIs.
>
> This implementation enables running ptp4l on netdevsim adapters.
>
> Co-developed-by: Milena Olech <milena.olech@intel.com>
> Signed-off-by: Milena Olech <milena.olech@intel.com>
> Signed-off-by: Maciek Machnikowski <maciek@machnikowski.net>
> ---
> drivers/net/netdevsim/ethtool.c | 12 +++++
> drivers/net/netdevsim/netdev.c | 90 +++++++++++++++++++++++++++++++
> drivers/net/netdevsim/netdevsim.h | 1 +
> 3 files changed, 103 insertions(+)
>
> diff --git a/drivers/net/netdevsim/ethtool.c b/drivers/net/netdevsim/ethtool.c
> index 36a201533..367c7ca8b 100644
> --- a/drivers/net/netdevsim/ethtool.c
> +++ b/drivers/net/netdevsim/ethtool.c
> @@ -201,6 +201,18 @@ static int nsim_get_ts_info(struct net_device *dev,
> struct netdevsim *ns = netdev_priv(dev);
>
> info->phc_index = mock_phc_index(ns->phc);
> + if (info->phc_index < 0)
> + return 0;
> +
> + info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
> + SOF_TIMESTAMPING_RX_SOFTWARE |
> + SOF_TIMESTAMPING_SOFTWARE |
> + SOF_TIMESTAMPING_TX_HARDWARE |
> + SOF_TIMESTAMPING_RX_HARDWARE |
> + SOF_TIMESTAMPING_RAW_HARDWARE;
preferred model is to populate the device independent defaults with
ethtool_op_get_ts_info, then extend where relevant. See for instance
gve_get_ts_info.
> +
> + info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON);
> + info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | BIT(HWTSTAMP_FILTER_ALL);
>
> return 0;
> }
> diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
> index 6285fbefe..b1161c1ca 100644
> --- a/drivers/net/netdevsim/netdev.c
> +++ b/drivers/net/netdevsim/netdev.c
> @@ -30,6 +30,8 @@
> #include <net/rtnetlink.h>
> #include <net/udp_tunnel.h>
> #include <net/busy_poll.h>
> +#include <linux/ptp_clock_kernel.h>
> +#include <linux/timecounter.h>
>
> #include "netdevsim.h"
>
> @@ -119,12 +121,17 @@ static int nsim_forward_skb(struct net_device *tx_dev,
>
> static netdev_tx_t nsim_start_xmit(struct sk_buff *skb, struct net_device *dev)
> {
> + struct skb_shared_hwtstamps shhwtstamps = {};
> struct netdevsim *ns = netdev_priv(dev);
> + struct ptp_clock_info *ptp_info;
> + struct timespec64 tx_ts, rx_ts;
> + struct sk_buff *skb_orig = skb;
> struct skb_ext *psp_ext = NULL;
> struct net_device *peer_dev;
> unsigned int len = skb->len;
> struct netdevsim *peer_ns;
> struct netdev_config *cfg;
> + bool gen_tx_tstamp = false;
> struct nsim_rq *rq;
> int rxq;
> int dr;
> @@ -161,6 +168,27 @@ static netdev_tx_t nsim_start_xmit(struct sk_buff *skb, struct net_device *dev)
> skb_linearize(skb);
>
> skb_tx_timestamp(skb);
> + gen_tx_tstamp = skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP;
> + if (gen_tx_tstamp) {
> + ptp_info = mock_phc_get_ptp_info(ns->phc);
> +
> + /* Create a copy of tx skb to keep the tx reference */
> + skb_orig = skb;
> + skb = skb_copy(skb_orig, GFP_ATOMIC);
This should not be needed
skb_tstamp_tx itself will cal skg_clone or alloc_skb for the
notification skb.
Just queue the tx timestamp before nsim_forward_skb?
> + skb_shinfo(skb_orig)->tx_flags |= SKBTX_IN_PROGRESS;
> +
> + /* Timestamp as late as possible */
> + if (ptp_info)
> + ptp_info->gettime64(ptp_info, &tx_ts);
> + }
> +
> + /* Generate Rx tstamp based on the peer clock */
> + ptp_info = mock_phc_get_ptp_info(peer_ns->phc);
> + if (ptp_info) {
> + ptp_info->gettime64(ptp_info, &rx_ts);
> + skb_hwtstamps(skb)->hwtstamp = timespec64_to_ktime(rx_ts);
> + }
> +
> if (unlikely(nsim_forward_skb(dev, peer_dev,
> skb, rq, psp_ext) == NET_RX_DROP))
> goto out_drop_cnt;
> @@ -168,6 +196,13 @@ static netdev_tx_t nsim_start_xmit(struct sk_buff *skb, struct net_device *dev)
> if (!hrtimer_active(&rq->napi_timer))
> hrtimer_start(&rq->napi_timer, us_to_ktime(5), HRTIMER_MODE_REL);
>
> + /* only timestamp the outbound packet if user requested it */
> + if (gen_tx_tstamp) {
> + shhwtstamps.hwtstamp = timespec64_to_ktime(tx_ts);
> + skb_tstamp_tx(skb_orig, &shhwtstamps);
> + dev_kfree_skb_any(skb_orig);
> + }
> +
> rcu_read_unlock();
> dev_dstats_tx_add(dev, len);
> return NETDEV_TX_OK;
> @@ -182,6 +217,59 @@ static netdev_tx_t nsim_start_xmit(struct sk_buff *skb, struct net_device *dev)
> return NETDEV_TX_OK;
> }
>
> +static int nsim_set_ts_config(struct net_device *netdev,
> + struct kernel_hwtstamp_config *config,
> + struct netlink_ext_ack *extack)
> +{
> + struct netdevsim *ns = netdev_priv(netdev);
> +
> + if (!ns->phc)
> + return -EOPNOTSUPP;
> +
> + switch (config->tx_type) {
> + case HWTSTAMP_TX_OFF:
> + ns->tstamp_config.tx_type = HWTSTAMP_TX_OFF;
> + break;
> + case HWTSTAMP_TX_ON:
> + ns->tstamp_config.tx_type = HWTSTAMP_TX_ON;
> + break;
> + default:
> + return -ERANGE;
> + }
> +
> + switch (config->rx_filter) {
> + case HWTSTAMP_FILTER_NONE:
> + ns->tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE;
> + break;
> + case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
> + case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
> + case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
> + case HWTSTAMP_FILTER_PTP_V2_EVENT:
> + case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
> + case HWTSTAMP_FILTER_PTP_V2_SYNC:
> + case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
> + case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
> + case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
> + case HWTSTAMP_FILTER_NTP_ALL:
> + case HWTSTAMP_FILTER_ALL:
> + ns->tstamp_config.rx_filter = HWTSTAMP_FILTER_ALL;
> + break;
> + default:
> + return -ERANGE;
> + }
> +
> + return 0;
> +}
> +
> +static int nsim_get_ts_config(struct net_device *netdev,
> + struct kernel_hwtstamp_config *config)
> +{
> + struct netdevsim *ns = netdev_priv(netdev);
> +
> + *config = ns->tstamp_config;
> + return 0;
> +}
> +
> static void nsim_set_rx_mode(struct net_device *dev)
> {
> }
> @@ -660,6 +748,8 @@ static const struct net_device_ops nsim_netdev_ops = {
> .ndo_open = nsim_open,
> .ndo_stop = nsim_stop,
> .net_shaper_ops = &nsim_shaper_ops,
> + .ndo_hwtstamp_get = nsim_get_ts_config,
> + .ndo_hwtstamp_set = nsim_set_ts_config,
> };
>
> static const struct net_device_ops nsim_vf_netdev_ops = {
> diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
> index f767fc8a7..6d3e8700c 100644
> --- a/drivers/net/netdevsim/netdevsim.h
> +++ b/drivers/net/netdevsim/netdevsim.h
> @@ -103,6 +103,7 @@ struct netdevsim {
> struct net_device *netdev;
> struct nsim_dev *nsim_dev;
> struct nsim_dev_port *nsim_dev_port;
> + struct kernel_hwtstamp_config tstamp_config;
> struct mock_phc *phc;
> struct nsim_rq **rq;
>
> --
> 2.53.0
>
next prev parent reply other threads:[~2026-02-20 20:08 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-19 14:05 [PATCH net-next 0/2] Implement PTP support in netdevsim Maciek Machnikowski
2026-02-19 14:05 ` [PATCH net-next 1/2] ptp: Expose ptp_clock_info to external drivers Maciek Machnikowski
2026-02-19 14:05 ` [PATCH net-next 2/2] netdevsim: Implement basic ptp support Maciek Machnikowski
2026-02-19 16:16 ` Andrew Lunn
2026-02-19 20:42 ` Jakub Kicinski
2026-02-20 21:07 ` Maciek Machnikowski
2026-02-20 20:08 ` Willem de Bruijn [this message]
2026-02-20 21:06 ` Maciek Machnikowski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=willemdebruijn.kernel.1957319fee759@gmail.com \
--to=willemdebruijn.kernel@gmail.com \
--cc=kuba@kernel.org \
--cc=maciek@machnikowski.net \
--cc=milena.olech@intel.com \
--cc=netdev@vger.kernel.org \
--cc=richardcochran@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox