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. */ 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 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 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 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 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 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