1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 2 /* 3 * Copyright 2015-2022 Amazon.com, Inc. or its affiliates. All rights reserved. 4 */ 5 6 #include <linux/pci.h> 7 #include "ena_netdev.h" 8 #include "ena_phc.h" 9 #include "ena_devlink.h" 10 11 static int ena_phc_adjtime(struct ptp_clock_info *clock_info, s64 delta) 12 { 13 return -EOPNOTSUPP; 14 } 15 16 static int ena_phc_adjfine(struct ptp_clock_info *clock_info, long scaled_ppm) 17 { 18 return -EOPNOTSUPP; 19 } 20 21 static int ena_phc_feature_enable(struct ptp_clock_info *clock_info, 22 struct ptp_clock_request *rq, 23 int on) 24 { 25 return -EOPNOTSUPP; 26 } 27 28 static int ena_phc_gettimex64(struct ptp_clock_info *clock_info, 29 struct timespec64 *ts, 30 struct ptp_system_timestamp *sts) 31 { 32 struct ena_phc_info *phc_info = 33 container_of(clock_info, struct ena_phc_info, clock_info); 34 unsigned long flags; 35 u64 timestamp_nsec; 36 int rc; 37 38 spin_lock_irqsave(&phc_info->lock, flags); 39 40 ptp_read_system_prets(sts); 41 42 rc = ena_com_phc_get_timestamp(phc_info->adapter->ena_dev, 43 ×tamp_nsec); 44 45 ptp_read_system_postts(sts); 46 47 spin_unlock_irqrestore(&phc_info->lock, flags); 48 49 *ts = ns_to_timespec64(timestamp_nsec); 50 51 return rc; 52 } 53 54 static int ena_phc_settime64(struct ptp_clock_info *clock_info, 55 const struct timespec64 *ts) 56 { 57 return -EOPNOTSUPP; 58 } 59 60 static struct ptp_clock_info ena_ptp_clock_info = { 61 .owner = THIS_MODULE, 62 .n_alarm = 0, 63 .n_ext_ts = 0, 64 .n_per_out = 0, 65 .pps = 0, 66 .adjtime = ena_phc_adjtime, 67 .adjfine = ena_phc_adjfine, 68 .gettimex64 = ena_phc_gettimex64, 69 .settime64 = ena_phc_settime64, 70 .enable = ena_phc_feature_enable, 71 }; 72 73 /* Enable/Disable PHC by the kernel, affects on the next init flow */ 74 void ena_phc_enable(struct ena_adapter *adapter, bool enable) 75 { 76 struct ena_phc_info *phc_info = adapter->phc_info; 77 78 if (!phc_info) { 79 netdev_err(adapter->netdev, "phc_info is not allocated\n"); 80 return; 81 } 82 83 phc_info->enabled = enable; 84 } 85 86 /* Check if PHC is enabled by the kernel */ 87 bool ena_phc_is_enabled(struct ena_adapter *adapter) 88 { 89 struct ena_phc_info *phc_info = adapter->phc_info; 90 91 return (phc_info && phc_info->enabled); 92 } 93 94 /* PHC is activated if ptp clock is registered in the kernel */ 95 bool ena_phc_is_active(struct ena_adapter *adapter) 96 { 97 struct ena_phc_info *phc_info = adapter->phc_info; 98 99 return (phc_info && phc_info->clock); 100 } 101 102 static int ena_phc_register(struct ena_adapter *adapter) 103 { 104 struct pci_dev *pdev = adapter->pdev; 105 struct ptp_clock_info *clock_info; 106 struct ena_phc_info *phc_info; 107 int rc = 0; 108 109 phc_info = adapter->phc_info; 110 clock_info = &phc_info->clock_info; 111 112 /* PHC may already be registered in case of a reset */ 113 if (ena_phc_is_active(adapter)) 114 return 0; 115 116 phc_info->adapter = adapter; 117 118 spin_lock_init(&phc_info->lock); 119 120 /* Fill the ptp_clock_info struct and register PTP clock */ 121 *clock_info = ena_ptp_clock_info; 122 snprintf(clock_info->name, 123 sizeof(clock_info->name), 124 "ena-ptp-%02x", 125 PCI_SLOT(pdev->devfn)); 126 127 phc_info->clock = ptp_clock_register(clock_info, &pdev->dev); 128 if (IS_ERR(phc_info->clock)) { 129 rc = PTR_ERR(phc_info->clock); 130 netdev_err(adapter->netdev, "Failed registering ptp clock, error: %d\n", 131 rc); 132 phc_info->clock = NULL; 133 } 134 135 return rc; 136 } 137 138 static void ena_phc_unregister(struct ena_adapter *adapter) 139 { 140 struct ena_phc_info *phc_info = adapter->phc_info; 141 142 /* During reset flow, PHC must stay registered 143 * to keep kernel's PHC index 144 */ 145 if (ena_phc_is_active(adapter) && 146 !test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags)) { 147 ptp_clock_unregister(phc_info->clock); 148 phc_info->clock = NULL; 149 } 150 } 151 152 int ena_phc_alloc(struct ena_adapter *adapter) 153 { 154 /* Allocate driver specific PHC info */ 155 adapter->phc_info = vzalloc(sizeof(*adapter->phc_info)); 156 if (unlikely(!adapter->phc_info)) { 157 netdev_err(adapter->netdev, "Failed to alloc phc_info\n"); 158 return -ENOMEM; 159 } 160 161 return 0; 162 } 163 164 void ena_phc_free(struct ena_adapter *adapter) 165 { 166 if (adapter->phc_info) { 167 vfree(adapter->phc_info); 168 adapter->phc_info = NULL; 169 } 170 } 171 172 int ena_phc_init(struct ena_adapter *adapter) 173 { 174 struct ena_com_dev *ena_dev = adapter->ena_dev; 175 struct net_device *netdev = adapter->netdev; 176 int rc = -EOPNOTSUPP; 177 178 /* Validate PHC feature is supported in the device */ 179 if (!ena_com_phc_supported(ena_dev)) { 180 netdev_dbg(netdev, "PHC feature is not supported by the device\n"); 181 goto err_ena_com_phc_init; 182 } 183 184 /* Validate PHC feature is enabled by the kernel */ 185 if (!ena_phc_is_enabled(adapter)) { 186 netdev_dbg(netdev, "PHC feature is not enabled by the kernel\n"); 187 goto err_ena_com_phc_init; 188 } 189 190 /* Initialize device specific PHC info */ 191 rc = ena_com_phc_init(ena_dev); 192 if (unlikely(rc)) { 193 netdev_err(netdev, "Failed to init phc, error: %d\n", rc); 194 goto err_ena_com_phc_init; 195 } 196 197 /* Configure PHC feature in driver and device */ 198 rc = ena_com_phc_config(ena_dev); 199 if (unlikely(rc)) { 200 netdev_err(netdev, "Failed to config phc, error: %d\n", rc); 201 goto err_ena_com_phc_config; 202 } 203 204 /* Register to PTP class driver */ 205 rc = ena_phc_register(adapter); 206 if (unlikely(rc)) { 207 netdev_err(netdev, "Failed to register phc, error: %d\n", rc); 208 goto err_ena_com_phc_config; 209 } 210 211 return 0; 212 213 err_ena_com_phc_config: 214 ena_com_phc_destroy(ena_dev); 215 err_ena_com_phc_init: 216 ena_phc_enable(adapter, false); 217 ena_devlink_disable_phc_param(adapter->devlink); 218 return rc; 219 } 220 221 void ena_phc_destroy(struct ena_adapter *adapter) 222 { 223 ena_phc_unregister(adapter); 224 ena_com_phc_destroy(adapter->ena_dev); 225 } 226 227 int ena_phc_get_index(struct ena_adapter *adapter) 228 { 229 if (ena_phc_is_active(adapter)) 230 return ptp_clock_index(adapter->phc_info->clock); 231 232 return -1; 233 } 234