1// SPDX-License-Identifier: GPL-2.0+
2// Copyright (c) 2021 Hisilicon Limited.
3
4#include <linux/skbuff.h>
5#include "hclge_main.h"
6#include "hnae3.h"
7
8static int hclge_ptp_get_cycle(struct hclge_dev *hdev)
9{
10 struct hclge_ptp *ptp = hdev->ptp;
11
12 ptp->cycle.quo = readl(addr: hdev->ptp->io_base + HCLGE_PTP_CYCLE_QUO_REG) &
13 HCLGE_PTP_CYCLE_QUO_MASK;
14 ptp->cycle.numer = readl(addr: hdev->ptp->io_base + HCLGE_PTP_CYCLE_NUM_REG);
15 ptp->cycle.den = readl(addr: hdev->ptp->io_base + HCLGE_PTP_CYCLE_DEN_REG);
16
17 if (ptp->cycle.den == 0) {
18 dev_err(&hdev->pdev->dev, "invalid ptp cycle denominator!\n");
19 return -EINVAL;
20 }
21
22 return 0;
23}
24
25static int hclge_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
26{
27 struct hclge_dev *hdev = hclge_ptp_get_hdev(info: ptp);
28 struct hclge_ptp_cycle *cycle = &hdev->ptp->cycle;
29 u64 adj_val, adj_base;
30 unsigned long flags;
31 u32 quo, numerator;
32
33 adj_base = (u64)cycle->quo * (u64)cycle->den + (u64)cycle->numer;
34 adj_val = adjust_by_scaled_ppm(base: adj_base, scaled_ppm);
35
36 /* This clock cycle is defined by three part: quotient, numerator
37 * and denominator. For example, 2.5ns, the quotient is 2,
38 * denominator is fixed to ptp->cycle.den, and numerator
39 * is 0.5 * ptp->cycle.den.
40 */
41 quo = div_u64_rem(dividend: adj_val, divisor: cycle->den, remainder: &numerator);
42
43 spin_lock_irqsave(&hdev->ptp->lock, flags);
44 writel(val: quo & HCLGE_PTP_CYCLE_QUO_MASK,
45 addr: hdev->ptp->io_base + HCLGE_PTP_CYCLE_QUO_REG);
46 writel(val: numerator, addr: hdev->ptp->io_base + HCLGE_PTP_CYCLE_NUM_REG);
47 writel(val: cycle->den, addr: hdev->ptp->io_base + HCLGE_PTP_CYCLE_DEN_REG);
48 writel(HCLGE_PTP_CYCLE_ADJ_EN,
49 addr: hdev->ptp->io_base + HCLGE_PTP_CYCLE_CFG_REG);
50 spin_unlock_irqrestore(lock: &hdev->ptp->lock, flags);
51
52 return 0;
53}
54
55bool hclge_ptp_set_tx_info(struct hnae3_handle *handle, struct sk_buff *skb)
56{
57 struct hclge_vport *vport = hclge_get_vport(handle);
58 struct hclge_dev *hdev = vport->back;
59 struct hclge_ptp *ptp = hdev->ptp;
60
61 if (!test_bit(HCLGE_PTP_FLAG_TX_EN, &ptp->flags) ||
62 test_and_set_bit(nr: HCLGE_STATE_PTP_TX_HANDLING, addr: &hdev->state)) {
63 ptp->tx_skipped++;
64 return false;
65 }
66
67 ptp->tx_start = jiffies;
68 ptp->tx_skb = skb_get(skb);
69 ptp->tx_cnt++;
70
71 return true;
72}
73
74void hclge_ptp_clean_tx_hwts(struct hclge_dev *hdev)
75{
76 struct sk_buff *skb = hdev->ptp->tx_skb;
77 struct skb_shared_hwtstamps hwts;
78 u32 hi, lo;
79 u64 ns;
80
81 ns = readl(addr: hdev->ptp->io_base + HCLGE_PTP_TX_TS_NSEC_REG) &
82 HCLGE_PTP_TX_TS_NSEC_MASK;
83 lo = readl(addr: hdev->ptp->io_base + HCLGE_PTP_TX_TS_SEC_L_REG);
84 hi = readl(addr: hdev->ptp->io_base + HCLGE_PTP_TX_TS_SEC_H_REG) &
85 HCLGE_PTP_TX_TS_SEC_H_MASK;
86 hdev->ptp->last_tx_seqid = readl(addr: hdev->ptp->io_base +
87 HCLGE_PTP_TX_TS_SEQID_REG);
88
89 if (skb) {
90 hdev->ptp->tx_skb = NULL;
91 hdev->ptp->tx_cleaned++;
92
93 ns += (((u64)hi) << 32 | lo) * NSEC_PER_SEC;
94 hwts.hwtstamp = ns_to_ktime(ns);
95 skb_tstamp_tx(orig_skb: skb, hwtstamps: &hwts);
96 dev_kfree_skb_any(skb);
97 }
98
99 clear_bit(nr: HCLGE_STATE_PTP_TX_HANDLING, addr: &hdev->state);
100}
101
102void hclge_ptp_get_rx_hwts(struct hnae3_handle *handle, struct sk_buff *skb,
103 u32 nsec, u32 sec)
104{
105 struct hclge_vport *vport = hclge_get_vport(handle);
106 struct hclge_dev *hdev = vport->back;
107 unsigned long flags;
108 u64 ns = nsec;
109 u32 sec_h;
110
111 if (!hdev->ptp || !test_bit(HCLGE_PTP_FLAG_RX_EN, &hdev->ptp->flags))
112 return;
113
114 /* Since the BD does not have enough space for the higher 16 bits of
115 * second, and this part will not change frequently, so read it
116 * from register.
117 */
118 spin_lock_irqsave(&hdev->ptp->lock, flags);
119 sec_h = readl(addr: hdev->ptp->io_base + HCLGE_PTP_CUR_TIME_SEC_H_REG);
120 spin_unlock_irqrestore(lock: &hdev->ptp->lock, flags);
121
122 ns += (((u64)sec_h) << HCLGE_PTP_SEC_H_OFFSET | sec) * NSEC_PER_SEC;
123 skb_hwtstamps(skb)->hwtstamp = ns_to_ktime(ns);
124 hdev->ptp->last_rx = jiffies;
125 hdev->ptp->rx_cnt++;
126}
127
128static int hclge_ptp_gettimex(struct ptp_clock_info *ptp, struct timespec64 *ts,
129 struct ptp_system_timestamp *sts)
130{
131 struct hclge_dev *hdev = hclge_ptp_get_hdev(info: ptp);
132 unsigned long flags;
133 u32 hi, lo;
134 u64 ns;
135
136 spin_lock_irqsave(&hdev->ptp->lock, flags);
137 ns = readl(addr: hdev->ptp->io_base + HCLGE_PTP_CUR_TIME_NSEC_REG);
138 hi = readl(addr: hdev->ptp->io_base + HCLGE_PTP_CUR_TIME_SEC_H_REG);
139 lo = readl(addr: hdev->ptp->io_base + HCLGE_PTP_CUR_TIME_SEC_L_REG);
140 spin_unlock_irqrestore(lock: &hdev->ptp->lock, flags);
141
142 ns += (((u64)hi) << HCLGE_PTP_SEC_H_OFFSET | lo) * NSEC_PER_SEC;
143 *ts = ns_to_timespec64(nsec: ns);
144
145 return 0;
146}
147
148static int hclge_ptp_settime(struct ptp_clock_info *ptp,
149 const struct timespec64 *ts)
150{
151 struct hclge_dev *hdev = hclge_ptp_get_hdev(info: ptp);
152 unsigned long flags;
153
154 spin_lock_irqsave(&hdev->ptp->lock, flags);
155 writel(val: ts->tv_nsec, addr: hdev->ptp->io_base + HCLGE_PTP_TIME_NSEC_REG);
156 writel(val: ts->tv_sec >> HCLGE_PTP_SEC_H_OFFSET,
157 addr: hdev->ptp->io_base + HCLGE_PTP_TIME_SEC_H_REG);
158 writel(val: ts->tv_sec & HCLGE_PTP_SEC_L_MASK,
159 addr: hdev->ptp->io_base + HCLGE_PTP_TIME_SEC_L_REG);
160 /* synchronize the time of phc */
161 writel(HCLGE_PTP_TIME_SYNC_EN,
162 addr: hdev->ptp->io_base + HCLGE_PTP_TIME_SYNC_REG);
163 spin_unlock_irqrestore(lock: &hdev->ptp->lock, flags);
164
165 return 0;
166}
167
168static int hclge_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
169{
170 struct hclge_dev *hdev = hclge_ptp_get_hdev(info: ptp);
171 unsigned long flags;
172 bool is_neg = false;
173 u32 adj_val = 0;
174
175 if (delta < 0) {
176 adj_val |= HCLGE_PTP_TIME_NSEC_NEG;
177 delta = -delta;
178 is_neg = true;
179 }
180
181 if (delta > HCLGE_PTP_TIME_NSEC_MASK) {
182 struct timespec64 ts;
183 s64 ns;
184
185 hclge_ptp_gettimex(ptp, ts: &ts, NULL);
186 ns = timespec64_to_ns(ts: &ts);
187 ns = is_neg ? ns - delta : ns + delta;
188 ts = ns_to_timespec64(nsec: ns);
189 return hclge_ptp_settime(ptp, ts: &ts);
190 }
191
192 adj_val |= delta & HCLGE_PTP_TIME_NSEC_MASK;
193
194 spin_lock_irqsave(&hdev->ptp->lock, flags);
195 writel(val: adj_val, addr: hdev->ptp->io_base + HCLGE_PTP_TIME_NSEC_REG);
196 writel(HCLGE_PTP_TIME_ADJ_EN,
197 addr: hdev->ptp->io_base + HCLGE_PTP_TIME_ADJ_REG);
198 spin_unlock_irqrestore(lock: &hdev->ptp->lock, flags);
199
200 return 0;
201}
202
203int hclge_ptp_get_cfg(struct hclge_dev *hdev, struct ifreq *ifr)
204{
205 if (!test_bit(HCLGE_STATE_PTP_EN, &hdev->state))
206 return -EOPNOTSUPP;
207
208 return copy_to_user(to: ifr->ifr_data, from: &hdev->ptp->ts_cfg,
209 n: sizeof(struct hwtstamp_config)) ? -EFAULT : 0;
210}
211
212static int hclge_ptp_int_en(struct hclge_dev *hdev, bool en)
213{
214 struct hclge_ptp_int_cmd *req;
215 struct hclge_desc desc;
216 int ret;
217
218 req = (struct hclge_ptp_int_cmd *)desc.data;
219 hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_PTP_INT_EN, false);
220 req->int_en = en ? 1 : 0;
221
222 ret = hclge_cmd_send(hw: &hdev->hw, desc: &desc, num: 1);
223 if (ret)
224 dev_err(&hdev->pdev->dev,
225 "failed to %s ptp interrupt, ret = %d\n",
226 en ? "enable" : "disable", ret);
227
228 return ret;
229}
230
231int hclge_ptp_cfg_qry(struct hclge_dev *hdev, u32 *cfg)
232{
233 struct hclge_ptp_cfg_cmd *req;
234 struct hclge_desc desc;
235 int ret;
236
237 req = (struct hclge_ptp_cfg_cmd *)desc.data;
238 hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_PTP_MODE_CFG, true);
239 ret = hclge_cmd_send(hw: &hdev->hw, desc: &desc, num: 1);
240 if (ret) {
241 dev_err(&hdev->pdev->dev,
242 "failed to query ptp config, ret = %d\n", ret);
243 return ret;
244 }
245
246 *cfg = le32_to_cpu(req->cfg);
247
248 return 0;
249}
250
251static int hclge_ptp_cfg(struct hclge_dev *hdev, u32 cfg)
252{
253 struct hclge_ptp_cfg_cmd *req;
254 struct hclge_desc desc;
255 int ret;
256
257 req = (struct hclge_ptp_cfg_cmd *)desc.data;
258 hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_PTP_MODE_CFG, false);
259 req->cfg = cpu_to_le32(cfg);
260 ret = hclge_cmd_send(hw: &hdev->hw, desc: &desc, num: 1);
261 if (ret)
262 dev_err(&hdev->pdev->dev,
263 "failed to config ptp, ret = %d\n", ret);
264
265 return ret;
266}
267
268static int hclge_ptp_set_tx_mode(struct hwtstamp_config *cfg,
269 unsigned long *flags, u32 *ptp_cfg)
270{
271 switch (cfg->tx_type) {
272 case HWTSTAMP_TX_OFF:
273 clear_bit(HCLGE_PTP_FLAG_TX_EN, addr: flags);
274 break;
275 case HWTSTAMP_TX_ON:
276 set_bit(HCLGE_PTP_FLAG_TX_EN, addr: flags);
277 *ptp_cfg |= HCLGE_PTP_TX_EN_B;
278 break;
279 default:
280 return -ERANGE;
281 }
282
283 return 0;
284}
285
286static int hclge_ptp_set_rx_mode(struct hwtstamp_config *cfg,
287 unsigned long *flags, u32 *ptp_cfg)
288{
289 int rx_filter = cfg->rx_filter;
290
291 switch (cfg->rx_filter) {
292 case HWTSTAMP_FILTER_NONE:
293 clear_bit(HCLGE_PTP_FLAG_RX_EN, addr: flags);
294 break;
295 case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
296 case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
297 case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
298 set_bit(HCLGE_PTP_FLAG_RX_EN, addr: flags);
299 *ptp_cfg |= HCLGE_PTP_RX_EN_B;
300 *ptp_cfg |= HCLGE_PTP_UDP_FULL_TYPE << HCLGE_PTP_UDP_EN_SHIFT;
301 rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
302 break;
303 case HWTSTAMP_FILTER_PTP_V2_EVENT:
304 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
305 case HWTSTAMP_FILTER_PTP_V2_SYNC:
306 case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
307 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
308 case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
309 case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
310 case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
311 case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
312 set_bit(HCLGE_PTP_FLAG_RX_EN, addr: flags);
313 *ptp_cfg |= HCLGE_PTP_RX_EN_B;
314 *ptp_cfg |= HCLGE_PTP_UDP_FULL_TYPE << HCLGE_PTP_UDP_EN_SHIFT;
315 *ptp_cfg |= HCLGE_PTP_MSG1_V2_DEFAULT << HCLGE_PTP_MSG1_SHIFT;
316 *ptp_cfg |= HCLGE_PTP_MSG0_V2_EVENT << HCLGE_PTP_MSG0_SHIFT;
317 *ptp_cfg |= HCLGE_PTP_MSG_TYPE_V2 << HCLGE_PTP_MSG_TYPE_SHIFT;
318 rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
319 break;
320 case HWTSTAMP_FILTER_ALL:
321 default:
322 return -ERANGE;
323 }
324
325 cfg->rx_filter = rx_filter;
326
327 return 0;
328}
329
330static int hclge_ptp_set_ts_mode(struct hclge_dev *hdev,
331 struct hwtstamp_config *cfg)
332{
333 unsigned long flags = hdev->ptp->flags;
334 u32 ptp_cfg = 0;
335 int ret;
336
337 if (test_bit(HCLGE_PTP_FLAG_EN, &hdev->ptp->flags))
338 ptp_cfg |= HCLGE_PTP_EN_B;
339
340 ret = hclge_ptp_set_tx_mode(cfg, flags: &flags, ptp_cfg: &ptp_cfg);
341 if (ret)
342 return ret;
343
344 ret = hclge_ptp_set_rx_mode(cfg, flags: &flags, ptp_cfg: &ptp_cfg);
345 if (ret)
346 return ret;
347
348 ret = hclge_ptp_cfg(hdev, cfg: ptp_cfg);
349 if (ret)
350 return ret;
351
352 hdev->ptp->flags = flags;
353 hdev->ptp->ptp_cfg = ptp_cfg;
354
355 return 0;
356}
357
358int hclge_ptp_set_cfg(struct hclge_dev *hdev, struct ifreq *ifr)
359{
360 struct hwtstamp_config cfg;
361 int ret;
362
363 if (!test_bit(HCLGE_STATE_PTP_EN, &hdev->state)) {
364 dev_err(&hdev->pdev->dev, "phc is unsupported\n");
365 return -EOPNOTSUPP;
366 }
367
368 if (copy_from_user(to: &cfg, from: ifr->ifr_data, n: sizeof(cfg)))
369 return -EFAULT;
370
371 ret = hclge_ptp_set_ts_mode(hdev, cfg: &cfg);
372 if (ret)
373 return ret;
374
375 hdev->ptp->ts_cfg = cfg;
376
377 return copy_to_user(to: ifr->ifr_data, from: &cfg, n: sizeof(cfg)) ? -EFAULT : 0;
378}
379
380int hclge_ptp_get_ts_info(struct hnae3_handle *handle,
381 struct ethtool_ts_info *info)
382{
383 struct hclge_vport *vport = hclge_get_vport(handle);
384 struct hclge_dev *hdev = vport->back;
385
386 if (!test_bit(HCLGE_STATE_PTP_EN, &hdev->state)) {
387 dev_err(&hdev->pdev->dev, "phc is unsupported\n");
388 return -EOPNOTSUPP;
389 }
390
391 info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
392 SOF_TIMESTAMPING_RX_SOFTWARE |
393 SOF_TIMESTAMPING_SOFTWARE |
394 SOF_TIMESTAMPING_TX_HARDWARE |
395 SOF_TIMESTAMPING_RX_HARDWARE |
396 SOF_TIMESTAMPING_RAW_HARDWARE;
397
398 if (hdev->ptp->clock)
399 info->phc_index = ptp_clock_index(ptp: hdev->ptp->clock);
400 else
401 info->phc_index = -1;
402
403 info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON);
404
405 info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
406 BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
407 BIT(HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
408 BIT(HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ);
409
410 info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V1_L4_SYNC) |
411 BIT(HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) |
412 BIT(HWTSTAMP_FILTER_PTP_V2_EVENT) |
413 BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
414 BIT(HWTSTAMP_FILTER_PTP_V2_SYNC) |
415 BIT(HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
416 BIT(HWTSTAMP_FILTER_PTP_V2_DELAY_REQ) |
417 BIT(HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ);
418
419 return 0;
420}
421
422static int hclge_ptp_create_clock(struct hclge_dev *hdev)
423{
424 struct hclge_ptp *ptp;
425
426 ptp = devm_kzalloc(dev: &hdev->pdev->dev, size: sizeof(*ptp), GFP_KERNEL);
427 if (!ptp)
428 return -ENOMEM;
429
430 ptp->hdev = hdev;
431 snprintf(buf: ptp->info.name, size: sizeof(ptp->info.name), fmt: "%s",
432 HCLGE_DRIVER_NAME);
433 ptp->info.owner = THIS_MODULE;
434 ptp->info.max_adj = HCLGE_PTP_CYCLE_ADJ_MAX;
435 ptp->info.n_ext_ts = 0;
436 ptp->info.pps = 0;
437 ptp->info.adjfine = hclge_ptp_adjfine;
438 ptp->info.adjtime = hclge_ptp_adjtime;
439 ptp->info.gettimex64 = hclge_ptp_gettimex;
440 ptp->info.settime64 = hclge_ptp_settime;
441
442 ptp->info.n_alarm = 0;
443 ptp->clock = ptp_clock_register(info: &ptp->info, parent: &hdev->pdev->dev);
444 if (IS_ERR(ptr: ptp->clock)) {
445 dev_err(&hdev->pdev->dev,
446 "%d failed to register ptp clock, ret = %ld\n",
447 ptp->info.n_alarm, PTR_ERR(ptp->clock));
448 return -ENODEV;
449 } else if (!ptp->clock) {
450 dev_err(&hdev->pdev->dev, "failed to register ptp clock\n");
451 return -ENODEV;
452 }
453
454 spin_lock_init(&ptp->lock);
455 ptp->io_base = hdev->hw.hw.io_base + HCLGE_PTP_REG_OFFSET;
456 ptp->ts_cfg.rx_filter = HWTSTAMP_FILTER_NONE;
457 ptp->ts_cfg.tx_type = HWTSTAMP_TX_OFF;
458 hdev->ptp = ptp;
459
460 return 0;
461}
462
463static void hclge_ptp_destroy_clock(struct hclge_dev *hdev)
464{
465 ptp_clock_unregister(ptp: hdev->ptp->clock);
466 hdev->ptp->clock = NULL;
467 devm_kfree(dev: &hdev->pdev->dev, p: hdev->ptp);
468 hdev->ptp = NULL;
469}
470
471int hclge_ptp_init(struct hclge_dev *hdev)
472{
473 struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev: hdev->pdev);
474 struct timespec64 ts;
475 int ret;
476
477 if (!test_bit(HNAE3_DEV_SUPPORT_PTP_B, ae_dev->caps))
478 return 0;
479
480 if (!hdev->ptp) {
481 ret = hclge_ptp_create_clock(hdev);
482 if (ret)
483 return ret;
484
485 ret = hclge_ptp_get_cycle(hdev);
486 if (ret)
487 return ret;
488 }
489
490 ret = hclge_ptp_int_en(hdev, en: true);
491 if (ret)
492 goto out;
493
494 set_bit(HCLGE_PTP_FLAG_EN, addr: &hdev->ptp->flags);
495 ret = hclge_ptp_adjfine(ptp: &hdev->ptp->info, scaled_ppm: 0);
496 if (ret) {
497 dev_err(&hdev->pdev->dev,
498 "failed to init freq, ret = %d\n", ret);
499 goto out;
500 }
501
502 ret = hclge_ptp_set_ts_mode(hdev, cfg: &hdev->ptp->ts_cfg);
503 if (ret) {
504 dev_err(&hdev->pdev->dev,
505 "failed to init ts mode, ret = %d\n", ret);
506 goto out;
507 }
508
509 ktime_get_real_ts64(tv: &ts);
510 ret = hclge_ptp_settime(ptp: &hdev->ptp->info, ts: &ts);
511 if (ret) {
512 dev_err(&hdev->pdev->dev,
513 "failed to init ts time, ret = %d\n", ret);
514 goto out;
515 }
516
517 set_bit(nr: HCLGE_STATE_PTP_EN, addr: &hdev->state);
518 dev_info(&hdev->pdev->dev, "phc initializes ok!\n");
519
520 return 0;
521
522out:
523 hclge_ptp_destroy_clock(hdev);
524
525 return ret;
526}
527
528void hclge_ptp_uninit(struct hclge_dev *hdev)
529{
530 struct hclge_ptp *ptp = hdev->ptp;
531
532 if (!ptp)
533 return;
534
535 hclge_ptp_int_en(hdev, en: false);
536 clear_bit(nr: HCLGE_STATE_PTP_EN, addr: &hdev->state);
537 clear_bit(HCLGE_PTP_FLAG_EN, addr: &ptp->flags);
538 ptp->ts_cfg.rx_filter = HWTSTAMP_FILTER_NONE;
539 ptp->ts_cfg.tx_type = HWTSTAMP_TX_OFF;
540
541 if (hclge_ptp_set_ts_mode(hdev, cfg: &ptp->ts_cfg))
542 dev_err(&hdev->pdev->dev, "failed to disable phc\n");
543
544 if (ptp->tx_skb) {
545 struct sk_buff *skb = ptp->tx_skb;
546
547 ptp->tx_skb = NULL;
548 dev_kfree_skb_any(skb);
549 }
550
551 hclge_ptp_destroy_clock(hdev);
552}
553

source code of linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c