From nobody Mon Feb 9 10:42:54 2026 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D591B379990 for ; Thu, 29 Jan 2026 08:07:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769674038; cv=none; b=WjXkX/Gm8J4PyAK1rOvfXKaA+SyMgw2WLepHEPud86Qv4E4RaYhYd1FY+62Ct3yjyWwyH3DxW6bd576Lx0lgZ8TRLkQoQ3j1gz5grf5vTOpzxm3ofh5loeLXM7Owo9I+MNJSD3/Ew2z2jpJQlZKg9Jwq4K5dNqkN1o5VZabZe40= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769674038; c=relaxed/simple; bh=L4jc0RFkSEobO61Huzyq9HmNenulyjlvnXHrYnr4Gm8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=EaZecGdJcgSzBhR86tW1TETZZYzsgwwSmiF3OJxLqXEgXbNtnP1epoiC5poMZ6dCbRr8U2hF5Z86vG7OSt+97zoS41Xkl3Co/GjiWTByxdonFFn2pp5H0wgloWizCOi0dA3mknnFIsLxeCmbT2+20fnAjO5IN3fTE6fKCpx00i8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from ptz.office.stw.pengutronix.de ([2a0a:edc0:0:900:1d::77] helo=ratatoskr.trumtrar.info) by metis.whiteo.stw.pengutronix.de with esmtp (Exim 4.92) (envelope-from ) id 1vlN3J-0006b0-QZ; Thu, 29 Jan 2026 09:06:57 +0100 From: Steffen Trumtrar Date: Thu, 29 Jan 2026 09:06:41 +0100 Subject: [PATCH RFC v2 1/2] tun: support rx-tstamp Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260129-v6-7-topic-virtio-net-ptp-v2-1-30a27dc52760@pengutronix.de> References: <20260129-v6-7-topic-virtio-net-ptp-v2-0-30a27dc52760@pengutronix.de> In-Reply-To: <20260129-v6-7-topic-virtio-net-ptp-v2-0-30a27dc52760@pengutronix.de> To: "Michael S. Tsirkin" , Jason Wang , Xuan Zhuo , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Richard Cochran , Willem de Bruijn , Andrew Lunn , =?utf-8?q?Eugenio_P=C3=A9rez?= Cc: virtualization@lists.linux.dev, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Steffen Trumtrar X-Mailer: b4 0.14.3 X-SA-Exim-Connect-IP: 2a0a:edc0:0:900:1d::77 X-SA-Exim-Mail-From: s.trumtrar@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org Demonstrate support for new virtio-net features VIRTIO_NET_HDR_F_TSTAMP This is not intended to be merged. A full feature test also requires a patched qemu binary that knows these features and negotiates correct vnet_hdr_sz in virtio_net_set_mrg_rx_bufs. See https://github.com/strumtrar/qemu/tree/v10.2.0/virtio-rx-stamps Not-yet-signed-off-by: Steffen Trumtrar --- drivers/net/tun.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 8192740357a09..aa988a9c4bc99 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -2065,23 +2065,29 @@ static ssize_t tun_put_user(struct tun_struct *tun, } =20 if (vnet_hdr_sz) { - struct virtio_net_hdr_v1_hash_tunnel hdr; - struct virtio_net_hdr *gso; + struct virtio_net_hdr_v1_hash_tunnel_ts hdr; + + memset(&hdr, 0, sizeof(hdr)); =20 ret =3D tun_vnet_hdr_tnl_from_skb(tun->flags, tun->dev, skb, - &hdr); + (struct virtio_net_hdr_v1_hash_tunnel *)&hdr); if (ret) return ret; =20 - /* - * Drop the packet if the configured header size is too small - * WRT the enabled offloads. - */ - gso =3D (struct virtio_net_hdr *)&hdr; - ret =3D __tun_vnet_hdr_put(vnet_hdr_sz, tun->dev->features, - iter, gso); - if (ret) - return ret; + if (vnet_hdr_sz >=3D sizeof(struct virtio_net_hdr_v1_hash_tunnel_ts)) { + __le64 tstamp =3D cpu_to_le64(ktime_get_ns()); + + hdr.tstamp_0 =3D (tstamp & 0x000000000000ffffULL) >> 0; + hdr.tstamp_1 =3D (tstamp & 0x00000000ffff0000ULL) >> 16; + hdr.tstamp_2 =3D (tstamp & 0x0000ffff00000000ULL) >> 32; + hdr.tstamp_3 =3D (tstamp & 0xffff000000000000ULL) >> 48; + } + + if (unlikely(iov_iter_count(iter) < vnet_hdr_sz)) + return -EINVAL; + + if (unlikely(copy_to_iter(&hdr, vnet_hdr_sz, iter) !=3D vnet_hdr_sz)) + return -EFAULT; } =20 if (vlan_hlen) { --=20 2.52.0 From nobody Mon Feb 9 10:42:54 2026 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 723BF37AA68 for ; Thu, 29 Jan 2026 08:07:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769674039; cv=none; b=jpAUV7rWRqXjebeGTBsFX2tPYLf+6QCDNOeAG/BK/eOhTRNDHQnVha2ErZNM1StUrJuChjvETwejXJLCKH2wxC0Jsxfx9D7Qyw7+ikbmoPWxyDaSo5VV7UmxBsghMeIpAGW/eu7llSmutMcSU18Vw84jwtFh/KuNytSs/QtqWjA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769674039; c=relaxed/simple; bh=+xCKWt/Q3JTX2qrK4zrcv0kuPlLBRe4WDt8CynuLje4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hDSHI1H9qFv8c4i4F8stWf1v4TnI/tKkXPxmjCiaSJS4nCQKrP2gvDWIvbOczCuQ0xl8wtZ8GZXtby/NKAOxV6lI4HwWLEt9e4oQyq8ecDXnRZUbIGeg37Y0GhdFPn0eFKUn9vuSfJckY6oDhyM6q6L9NUS0tWCNRP1bpJd5yFY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from ptz.office.stw.pengutronix.de ([2a0a:edc0:0:900:1d::77] helo=ratatoskr.trumtrar.info) by metis.whiteo.stw.pengutronix.de with esmtp (Exim 4.92) (envelope-from ) id 1vlN3K-0006b0-89; Thu, 29 Jan 2026 09:06:58 +0100 From: Steffen Trumtrar Date: Thu, 29 Jan 2026 09:06:42 +0100 Subject: [PATCH RFC v2 2/2] virtio-net: support receive timestamp Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260129-v6-7-topic-virtio-net-ptp-v2-2-30a27dc52760@pengutronix.de> References: <20260129-v6-7-topic-virtio-net-ptp-v2-0-30a27dc52760@pengutronix.de> In-Reply-To: <20260129-v6-7-topic-virtio-net-ptp-v2-0-30a27dc52760@pengutronix.de> To: "Michael S. Tsirkin" , Jason Wang , Xuan Zhuo , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Richard Cochran , Willem de Bruijn , Andrew Lunn , =?utf-8?q?Eugenio_P=C3=A9rez?= Cc: virtualization@lists.linux.dev, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Steffen Trumtrar X-Mailer: b4 0.14.3 X-SA-Exim-Connect-IP: 2a0a:edc0:0:900:1d::77 X-SA-Exim-Mail-From: s.trumtrar@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org Add optional hardware rx timestamp offload for virtio-net. Introduce virtio feature VIRTIO_NET_F_TSTAMP. If negotiated, the virtio-net header is expanded with room for a timestamp. To get and set the hwtstamp the functions ndo_hwtstamp_set/get need to be implemented. This allows filtering the packets and only time stamp the packets where the filter matches. This way, the timestamping can be en/disabled at runtime. Tested: guest: ./timestamping eth0 \ SOF_TIMESTAMPING_RAW_HARDWARE \ SOF_TIMESTAMPING_RX_HARDWARE host: nc -4 -u 192.168.1.1 319 Signed-off-by: Steffen Trumtrar -- Changes to last version: - rework series to use flow filters - add new struct virtio_net_hdr_v1_hash_tunnel_ts - original work done by: Willem de Bruijn --- drivers/net/virtio_net.c | 136 ++++++++++++++++++++++++++++++++++++= ---- include/uapi/linux/virtio_net.h | 9 +++ 2 files changed, 133 insertions(+), 12 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 1bb3aeca66c6e..4e8d9b20c1b34 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -429,6 +429,9 @@ struct virtnet_info { struct virtio_net_rss_config_trailer rss_trailer; u8 rss_hash_key_data[VIRTIO_NET_RSS_MAX_KEY_SIZE]; =20 + /* Device passes time stamps from the driver */ + bool has_tstamp; + /* Has control virtqueue */ bool has_cvq; =20 @@ -475,6 +478,8 @@ struct virtnet_info { =20 struct control_buf *ctrl; =20 + struct kernel_hwtstamp_config tstamp_config; + /* Ethtool settings */ u8 duplex; u32 speed; @@ -511,6 +516,7 @@ struct virtio_net_common_hdr { struct virtio_net_hdr_mrg_rxbuf mrg_hdr; struct virtio_net_hdr_v1_hash hash_v1_hdr; struct virtio_net_hdr_v1_hash_tunnel tnl_hdr; + struct virtio_net_hdr_v1_hash_tunnel_ts ts_hdr; }; }; =20 @@ -682,6 +688,13 @@ skb_vnet_common_hdr(struct sk_buff *skb) return (struct virtio_net_common_hdr *)skb->cb; } =20 +static inline struct virtio_net_hdr_v1_hash_tunnel_ts *skb_vnet_hdr_ts(str= uct sk_buff *skb) +{ + BUILD_BUG_ON(sizeof(struct virtio_net_hdr_v1_hash_tunnel_ts) > sizeof(skb= ->cb)); + + return (void *)skb->cb; +} + /* * private is used to chain pages for big packets, put the whole * most recent used list in the beginning for reuse @@ -2560,6 +2573,15 @@ virtio_net_hash_value(const struct virtio_net_hdr_v1= _hash *hdr_hash) (__le16_to_cpu(hdr_hash->hash_value_hi) << 16); } =20 +static inline u64 +virtio_net_tstamp_value(const struct virtio_net_hdr_v1_hash_tunnel_ts *hdr= _hash_ts) +{ + return (u64)__le16_to_cpu(hdr_hash_ts->tstamp_0) | + ((u64)__le16_to_cpu(hdr_hash_ts->tstamp_1) << 16) | + ((u64)__le16_to_cpu(hdr_hash_ts->tstamp_2) << 32) | + ((u64)__le16_to_cpu(hdr_hash_ts->tstamp_3) << 48); +} + static void virtio_skb_set_hash(const struct virtio_net_hdr_v1_hash *hdr_h= ash, struct sk_buff *skb) { @@ -2589,6 +2611,18 @@ static void virtio_skb_set_hash(const struct virtio_= net_hdr_v1_hash *hdr_hash, skb_set_hash(skb, virtio_net_hash_value(hdr_hash), rss_hash_type); } =20 +static inline void virtnet_record_rx_tstamp(const struct virtnet_info *vi, + struct sk_buff *skb) +{ + struct skb_shared_hwtstamps *shhwtstamps =3D skb_hwtstamps(skb); + const struct virtio_net_hdr_v1_hash_tunnel_ts *h =3D skb_vnet_hdr_ts(skb); + u64 ts; + + ts =3D virtio_net_tstamp_value(h); + memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps)); + shhwtstamps->hwtstamp =3D ns_to_ktime(ts); +} + static void virtnet_receive_done(struct virtnet_info *vi, struct receive_q= ueue *rq, struct sk_buff *skb, u8 flags) { @@ -2617,6 +2651,8 @@ static void virtnet_receive_done(struct virtnet_info = *vi, struct receive_queue * goto frame_err; } =20 + if (vi->has_tstamp && vi->tstamp_config.rx_filter !=3D HWTSTAMP_FILTER_NO= NE) + virtnet_record_rx_tstamp(vi, skb); skb_record_rx_queue(skb, vq2rxq(rq->vq)); skb->protocol =3D eth_type_trans(skb, dev); pr_debug("Receiving skb proto 0x%04x len %i type %i\n", @@ -3321,7 +3357,7 @@ static int xmit_skb(struct send_queue *sq, struct sk_= buff *skb, bool orphan) { const unsigned char *dest =3D ((struct ethhdr *)skb->data)->h_dest; struct virtnet_info *vi =3D sq->vq->vdev->priv; - struct virtio_net_hdr_v1_hash_tunnel *hdr; + struct virtio_net_hdr_v1_hash_tunnel_ts *hdr; int num_sg; unsigned hdr_len =3D vi->hdr_len; bool can_push; @@ -3329,8 +3365,8 @@ static int xmit_skb(struct send_queue *sq, struct sk_= buff *skb, bool orphan) pr_debug("%s: xmit %p %pM\n", vi->dev->name, skb, dest); =20 /* Make sure it's safe to cast between formats */ - BUILD_BUG_ON(__alignof__(*hdr) !=3D __alignof__(hdr->hash_hdr)); - BUILD_BUG_ON(__alignof__(*hdr) !=3D __alignof__(hdr->hash_hdr.hdr)); + BUILD_BUG_ON(__alignof__(*hdr) !=3D __alignof__(hdr->tnl.hash_hdr)); + BUILD_BUG_ON(__alignof__(*hdr) !=3D __alignof__(hdr->tnl.hash_hdr.hdr)); =20 can_push =3D vi->any_header_sg && !((unsigned long)skb->data & (__alignof__(*hdr) - 1)) && @@ -3338,18 +3374,18 @@ static int xmit_skb(struct send_queue *sq, struct s= k_buff *skb, bool orphan) /* Even if we can, don't push here yet as this would skew * csum_start offset below. */ if (can_push) - hdr =3D (struct virtio_net_hdr_v1_hash_tunnel *)(skb->data - - hdr_len); + hdr =3D (struct virtio_net_hdr_v1_hash_tunnel_ts *)(skb->data - + hdr_len); else - hdr =3D &skb_vnet_common_hdr(skb)->tnl_hdr; + hdr =3D &skb_vnet_common_hdr(skb)->ts_hdr; =20 - if (virtio_net_hdr_tnl_from_skb(skb, hdr, vi->tx_tnl, + if (virtio_net_hdr_tnl_from_skb(skb, &hdr->tnl, vi->tx_tnl, virtio_is_little_endian(vi->vdev), 0, false)) return -EPROTO; =20 if (vi->mergeable_rx_bufs) - hdr->hash_hdr.hdr.num_buffers =3D 0; + hdr->tnl.hash_hdr.hdr.num_buffers =3D 0; =20 sg_init_table(sq->sg, skb_shinfo(skb)->nr_frags + (can_push ? 1 : 2)); if (can_push) { @@ -5563,6 +5599,22 @@ static int virtnet_get_per_queue_coalesce(struct net= _device *dev, return 0; } =20 +static int virtnet_get_ts_info(struct net_device *dev, + struct kernel_ethtool_ts_info *info) +{ + /* setup default software timestamp */ + ethtool_op_get_ts_info(dev, info); + + info->rx_filters =3D (BIT(HWTSTAMP_FILTER_NONE) | + BIT(HWTSTAMP_FILTER_PTP_V1_L4_SYNC) | + BIT(HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) | + BIT(HWTSTAMP_FILTER_ALL)); + + info->tx_types =3D HWTSTAMP_TX_OFF; + + return 0; +} + static void virtnet_init_settings(struct net_device *dev) { struct virtnet_info *vi =3D netdev_priv(dev); @@ -5658,7 +5710,7 @@ static const struct ethtool_ops virtnet_ethtool_ops = =3D { .get_ethtool_stats =3D virtnet_get_ethtool_stats, .set_channels =3D virtnet_set_channels, .get_channels =3D virtnet_get_channels, - .get_ts_info =3D ethtool_op_get_ts_info, + .get_ts_info =3D virtnet_get_ts_info, .get_link_ksettings =3D virtnet_get_link_ksettings, .set_link_ksettings =3D virtnet_set_link_ksettings, .set_coalesce =3D virtnet_set_coalesce, @@ -6242,6 +6294,58 @@ static void virtnet_tx_timeout(struct net_device *de= v, unsigned int txqueue) jiffies_to_usecs(jiffies - READ_ONCE(txq->trans_start))); } =20 +static int virtnet_hwtstamp_get(struct net_device *dev, + struct kernel_hwtstamp_config *tstamp_config) +{ + struct virtnet_info *vi =3D netdev_priv(dev); + + if (!netif_running(dev)) + return -EINVAL; + + *tstamp_config =3D vi->tstamp_config; + + return 0; +} + +static int virtnet_hwtstamp_set(struct net_device *dev, + struct kernel_hwtstamp_config *tstamp_config, + struct netlink_ext_ack *extack) +{ + struct virtnet_info *vi =3D netdev_priv(dev); + + if (!netif_running(dev)) + return -EINVAL; + + switch (tstamp_config->rx_filter) { + case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: + case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: + break; + case HWTSTAMP_FILTER_PTP_V2_EVENT: + case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: + case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: + case HWTSTAMP_FILTER_PTP_V2_SYNC: + case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: + case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: + case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: + case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: + case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: + tstamp_config->rx_filter =3D HWTSTAMP_FILTER_PTP_V2_EVENT; + break; + case HWTSTAMP_FILTER_NONE: + break; + case HWTSTAMP_FILTER_ALL: + tstamp_config->rx_filter =3D HWTSTAMP_FILTER_ALL; + break; + default: + tstamp_config->rx_filter =3D HWTSTAMP_FILTER_ALL; + return -ERANGE; + } + + vi->tstamp_config =3D *tstamp_config; + + return 0; +} + static int virtnet_init_irq_moder(struct virtnet_info *vi) { u8 profile_flags =3D 0, coal_flags =3D 0; @@ -6289,6 +6393,8 @@ static const struct net_device_ops virtnet_netdev =3D= { .ndo_get_phys_port_name =3D virtnet_get_phys_port_name, .ndo_set_features =3D virtnet_set_features, .ndo_tx_timeout =3D virtnet_tx_timeout, + .ndo_hwtstamp_set =3D virtnet_hwtstamp_set, + .ndo_hwtstamp_get =3D virtnet_hwtstamp_get, }; =20 static void virtnet_config_changed_work(struct work_struct *work) @@ -6911,6 +7017,9 @@ static int virtnet_probe(struct virtio_device *vdev) if (virtio_has_feature(vdev, VIRTIO_NET_F_HASH_REPORT)) vi->has_rss_hash_report =3D true; =20 + if (virtio_has_feature(vdev, VIRTIO_NET_F_TSTAMP)) + vi->has_tstamp =3D true; + if (virtio_has_feature(vdev, VIRTIO_NET_F_RSS)) { vi->has_rss =3D true; =20 @@ -6945,8 +7054,10 @@ static int virtnet_probe(struct virtio_device *vdev) dev->xdp_metadata_ops =3D &virtnet_xdp_metadata_ops; } =20 - if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO) || - virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UDP_TUNNEL_GSO)) + if (vi->has_tstamp) + vi->hdr_len =3D sizeof(struct virtio_net_hdr_v1_hash_tunnel_ts); + else if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO) || + virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UDP_TUNNEL_GSO)) vi->hdr_len =3D sizeof(struct virtio_net_hdr_v1_hash_tunnel); else if (vi->has_rss_hash_report) vi->hdr_len =3D sizeof(struct virtio_net_hdr_v1_hash); @@ -7269,7 +7380,8 @@ static struct virtio_device_id id_table[] =3D { VIRTIO_NET_F_SPEED_DUPLEX, VIRTIO_NET_F_STANDBY, \ VIRTIO_NET_F_RSS, VIRTIO_NET_F_HASH_REPORT, VIRTIO_NET_F_NOTF_COAL, \ VIRTIO_NET_F_VQ_NOTF_COAL, \ - VIRTIO_NET_F_GUEST_HDRLEN, VIRTIO_NET_F_DEVICE_STATS + VIRTIO_NET_F_GUEST_HDRLEN, VIRTIO_NET_F_DEVICE_STATS, \ + VIRTIO_NET_F_TSTAMP =20 static unsigned int features[] =3D { VIRTNET_FEATURES, diff --git a/include/uapi/linux/virtio_net.h b/include/uapi/linux/virtio_ne= t.h index 1db45b01532b5..9f967575956b8 100644 --- a/include/uapi/linux/virtio_net.h +++ b/include/uapi/linux/virtio_net.h @@ -56,6 +56,7 @@ #define VIRTIO_NET_F_MQ 22 /* Device supports Receive Flow * Steering */ #define VIRTIO_NET_F_CTRL_MAC_ADDR 23 /* Set MAC address */ +#define VIRTIO_NET_F_TSTAMP 49 /* Device sends TAI receive time */ #define VIRTIO_NET_F_DEVICE_STATS 50 /* Device can provide device-level st= atistics. */ #define VIRTIO_NET_F_VQ_NOTF_COAL 52 /* Device supports virtqueue notifica= tion coalescing */ #define VIRTIO_NET_F_NOTF_COAL 53 /* Device supports notifications coalesc= ing */ @@ -215,6 +216,14 @@ struct virtio_net_hdr_v1_hash_tunnel { __le16 inner_nh_offset; }; =20 +struct virtio_net_hdr_v1_hash_tunnel_ts { + struct virtio_net_hdr_v1_hash_tunnel tnl; + __le16 tstamp_0; + __le16 tstamp_1; + __le16 tstamp_2; + __le16 tstamp_3; +}; + #ifndef VIRTIO_NET_NO_LEGACY /* This header comes first in the scatter-gather list. * For legacy virtio, if VIRTIO_F_ANY_LAYOUT is not negotiated, it must --=20 2.52.0