xref: /linux/drivers/net/ethernet/google/gve/gve_ptp.c (revision 8be4d31cb8aaeea27bde4b7ddb26e28a89062ebf)
1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
2 /* Google virtual Ethernet (gve) driver
3  *
4  * Copyright (C) 2025 Google LLC
5  */
6 
7 #include "gve.h"
8 #include "gve_adminq.h"
9 
10 /* Interval to schedule a nic timestamp calibration, 250ms. */
11 #define GVE_NIC_TS_SYNC_INTERVAL_MS 250
12 
13 /* Read the nic timestamp from hardware via the admin queue. */
gve_clock_nic_ts_read(struct gve_priv * priv)14 int gve_clock_nic_ts_read(struct gve_priv *priv)
15 {
16 	u64 nic_raw;
17 	int err;
18 
19 	err = gve_adminq_report_nic_ts(priv, priv->nic_ts_report_bus);
20 	if (err)
21 		return err;
22 
23 	nic_raw = be64_to_cpu(priv->nic_ts_report->nic_timestamp);
24 	WRITE_ONCE(priv->last_sync_nic_counter, nic_raw);
25 
26 	return 0;
27 }
28 
gve_ptp_do_aux_work(struct ptp_clock_info * info)29 static long gve_ptp_do_aux_work(struct ptp_clock_info *info)
30 {
31 	const struct gve_ptp *ptp = container_of(info, struct gve_ptp, info);
32 	struct gve_priv *priv = ptp->priv;
33 	int err;
34 
35 	if (gve_get_reset_in_progress(priv) || !gve_get_admin_queue_ok(priv))
36 		goto out;
37 
38 	err = gve_clock_nic_ts_read(priv);
39 	if (err && net_ratelimit())
40 		dev_err(&priv->pdev->dev,
41 			"%s read err %d\n", __func__, err);
42 
43 out:
44 	return msecs_to_jiffies(GVE_NIC_TS_SYNC_INTERVAL_MS);
45 }
46 
47 static const struct ptp_clock_info gve_ptp_caps = {
48 	.owner          = THIS_MODULE,
49 	.name		= "gve clock",
50 	.do_aux_work	= gve_ptp_do_aux_work,
51 };
52 
gve_ptp_init(struct gve_priv * priv)53 static int gve_ptp_init(struct gve_priv *priv)
54 {
55 	struct gve_ptp *ptp;
56 	int err;
57 
58 	if (!priv->nic_timestamp_supported) {
59 		dev_dbg(&priv->pdev->dev, "Device does not support PTP\n");
60 		return -EOPNOTSUPP;
61 	}
62 
63 	priv->ptp = kzalloc(sizeof(*priv->ptp), GFP_KERNEL);
64 	if (!priv->ptp)
65 		return -ENOMEM;
66 
67 	ptp = priv->ptp;
68 	ptp->info = gve_ptp_caps;
69 	ptp->clock = ptp_clock_register(&ptp->info, &priv->pdev->dev);
70 
71 	if (IS_ERR(ptp->clock)) {
72 		dev_err(&priv->pdev->dev, "PTP clock registration failed\n");
73 		err  = PTR_ERR(ptp->clock);
74 		goto free_ptp;
75 	}
76 
77 	ptp->priv = priv;
78 	return 0;
79 
80 free_ptp:
81 	kfree(ptp);
82 	priv->ptp = NULL;
83 	return err;
84 }
85 
gve_ptp_release(struct gve_priv * priv)86 static void gve_ptp_release(struct gve_priv *priv)
87 {
88 	struct gve_ptp *ptp = priv->ptp;
89 
90 	if (!ptp)
91 		return;
92 
93 	if (ptp->clock)
94 		ptp_clock_unregister(ptp->clock);
95 
96 	kfree(ptp);
97 	priv->ptp = NULL;
98 }
99 
gve_init_clock(struct gve_priv * priv)100 int gve_init_clock(struct gve_priv *priv)
101 {
102 	int err;
103 
104 	if (!priv->nic_timestamp_supported)
105 		return 0;
106 
107 	err = gve_ptp_init(priv);
108 	if (err)
109 		return err;
110 
111 	priv->nic_ts_report =
112 		dma_alloc_coherent(&priv->pdev->dev,
113 				   sizeof(struct gve_nic_ts_report),
114 				   &priv->nic_ts_report_bus,
115 				   GFP_KERNEL);
116 	if (!priv->nic_ts_report) {
117 		dev_err(&priv->pdev->dev, "%s dma alloc error\n", __func__);
118 		err = -ENOMEM;
119 		goto release_ptp;
120 	}
121 
122 	return 0;
123 
124 release_ptp:
125 	gve_ptp_release(priv);
126 	return err;
127 }
128 
gve_teardown_clock(struct gve_priv * priv)129 void gve_teardown_clock(struct gve_priv *priv)
130 {
131 	gve_ptp_release(priv);
132 
133 	if (priv->nic_ts_report) {
134 		dma_free_coherent(&priv->pdev->dev,
135 				  sizeof(struct gve_nic_ts_report),
136 				  priv->nic_ts_report, priv->nic_ts_report_bus);
137 		priv->nic_ts_report = NULL;
138 	}
139 }
140