gve: Add initial PTP device support

If the device supports reading of the nic clock, add support
to initialize and register the PTP clock.

Signed-off-by: Ziwei Xiao <ziweixiao@google.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Signed-off-by: Harshitha Ramamurthy <hramamurthy@google.com>
Link: https://patch.msgid.link/20250614000754.164827-4-hramamurthy@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Harshitha Ramamurthy 2025-06-14 00:07:49 +00:00 committed by Jakub Kicinski
parent e0c9d5682c
commit acd1638052
4 changed files with 71 additions and 1 deletions

View file

@ -18,6 +18,7 @@ if NET_VENDOR_GOOGLE
config GVE config GVE
tristate "Google Virtual NIC (gVNIC) support" tristate "Google Virtual NIC (gVNIC) support"
depends on (PCI_MSI && (X86 || CPU_LITTLE_ENDIAN)) depends on (PCI_MSI && (X86 || CPU_LITTLE_ENDIAN))
depends on PTP_1588_CLOCK_OPTIONAL
select PAGE_POOL select PAGE_POOL
help help
This driver supports Google Virtual NIC (gVNIC)" This driver supports Google Virtual NIC (gVNIC)"

View file

@ -1,5 +1,7 @@
# Makefile for the Google virtual Ethernet (gve) driver # Makefile for the Google virtual Ethernet (gve) driver
obj-$(CONFIG_GVE) += gve.o obj-$(CONFIG_GVE) += gve.o
gve-objs := gve_main.o gve_tx.o gve_tx_dqo.o gve_rx.o gve_rx_dqo.o gve_ethtool.o gve_adminq.o gve_utils.o gve_flow_rule.o \ gve-y := gve_main.o gve_tx.o gve_tx_dqo.o gve_rx.o gve_rx_dqo.o gve_ethtool.o gve_adminq.o gve_utils.o gve_flow_rule.o \
gve_buffer_mgmt_dqo.o gve_buffer_mgmt_dqo.o
gve-$(CONFIG_PTP_1588_CLOCK) += gve_ptp.o

View file

@ -12,6 +12,7 @@
#include <linux/ethtool_netlink.h> #include <linux/ethtool_netlink.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/ptp_clock_kernel.h>
#include <linux/u64_stats_sync.h> #include <linux/u64_stats_sync.h>
#include <net/page_pool/helpers.h> #include <net/page_pool/helpers.h>
#include <net/xdp.h> #include <net/xdp.h>
@ -750,6 +751,12 @@ struct gve_rss_config {
u32 *hash_lut; u32 *hash_lut;
}; };
struct gve_ptp {
struct ptp_clock_info info;
struct ptp_clock *clock;
struct gve_priv *priv;
};
struct gve_priv { struct gve_priv {
struct net_device *dev; struct net_device *dev;
struct gve_tx_ring *tx; /* array of tx_cfg.num_queues */ struct gve_tx_ring *tx; /* array of tx_cfg.num_queues */
@ -874,6 +881,7 @@ struct gve_priv {
/* True if the device supports reading the nic clock */ /* True if the device supports reading the nic clock */
bool nic_timestamp_supported; bool nic_timestamp_supported;
struct gve_ptp *ptp;
}; };
enum gve_service_task_flags_bit { enum gve_service_task_flags_bit {

View file

@ -0,0 +1,59 @@
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/* Google virtual Ethernet (gve) driver
*
* Copyright (C) 2025 Google LLC
*/
#include "gve.h"
static const struct ptp_clock_info gve_ptp_caps = {
.owner = THIS_MODULE,
.name = "gve clock",
};
static int __maybe_unused gve_ptp_init(struct gve_priv *priv)
{
struct gve_ptp *ptp;
int err;
if (!priv->nic_timestamp_supported) {
dev_dbg(&priv->pdev->dev, "Device does not support PTP\n");
return -EOPNOTSUPP;
}
priv->ptp = kzalloc(sizeof(*priv->ptp), GFP_KERNEL);
if (!priv->ptp)
return -ENOMEM;
ptp = priv->ptp;
ptp->info = gve_ptp_caps;
ptp->clock = ptp_clock_register(&ptp->info, &priv->pdev->dev);
if (IS_ERR(ptp->clock)) {
dev_err(&priv->pdev->dev, "PTP clock registration failed\n");
err = PTR_ERR(ptp->clock);
goto free_ptp;
}
ptp->priv = priv;
return 0;
free_ptp:
kfree(ptp);
priv->ptp = NULL;
return err;
}
static void __maybe_unused gve_ptp_release(struct gve_priv *priv)
{
struct gve_ptp *ptp = priv->ptp;
if (!ptp)
return;
if (ptp->clock)
ptp_clock_unregister(ptp->clock);
kfree(ptp);
priv->ptp = NULL;
}