File Index
Files and directories
Sign in
FILE

hclge_ptp.c

File preview with syntax highlighting.

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