1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2017 - 2021 Pensando Systems, Inc */
3
4 #include <linux/netdevice.h>
5 #include <linux/etherdevice.h>
6
7 #include "ionic.h"
8 #include "ionic_bus.h"
9 #include "ionic_lif.h"
10 #include "ionic_ethtool.h"
11
ionic_hwstamp_tx_mode(int config_tx_type)12 static int ionic_hwstamp_tx_mode(int config_tx_type)
13 {
14 switch (config_tx_type) {
15 case HWTSTAMP_TX_OFF:
16 return IONIC_TXSTAMP_OFF;
17 case HWTSTAMP_TX_ON:
18 return IONIC_TXSTAMP_ON;
19 case HWTSTAMP_TX_ONESTEP_SYNC:
20 return IONIC_TXSTAMP_ONESTEP_SYNC;
21 case HWTSTAMP_TX_ONESTEP_P2P:
22 return IONIC_TXSTAMP_ONESTEP_P2P;
23 default:
24 return -ERANGE;
25 }
26 }
27
ionic_hwstamp_rx_filt(int config_rx_filter)28 static u64 ionic_hwstamp_rx_filt(int config_rx_filter)
29 {
30 switch (config_rx_filter) {
31 case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
32 return IONIC_PKT_CLS_PTP1_ALL;
33 case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
34 return IONIC_PKT_CLS_PTP1_SYNC;
35 case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
36 return IONIC_PKT_CLS_PTP1_SYNC | IONIC_PKT_CLS_PTP1_DREQ;
37
38 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
39 return IONIC_PKT_CLS_PTP2_L4_ALL;
40 case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
41 return IONIC_PKT_CLS_PTP2_L4_SYNC;
42 case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
43 return IONIC_PKT_CLS_PTP2_L4_SYNC | IONIC_PKT_CLS_PTP2_L4_DREQ;
44
45 case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
46 return IONIC_PKT_CLS_PTP2_L2_ALL;
47 case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
48 return IONIC_PKT_CLS_PTP2_L2_SYNC;
49 case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
50 return IONIC_PKT_CLS_PTP2_L2_SYNC | IONIC_PKT_CLS_PTP2_L2_DREQ;
51
52 case HWTSTAMP_FILTER_PTP_V2_EVENT:
53 return IONIC_PKT_CLS_PTP2_ALL;
54 case HWTSTAMP_FILTER_PTP_V2_SYNC:
55 return IONIC_PKT_CLS_PTP2_SYNC;
56 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
57 return IONIC_PKT_CLS_PTP2_SYNC | IONIC_PKT_CLS_PTP2_DREQ;
58
59 case HWTSTAMP_FILTER_NTP_ALL:
60 return IONIC_PKT_CLS_NTP_ALL;
61
62 default:
63 return 0;
64 }
65 }
66
ionic_lif_hwstamp_set_ts_config(struct ionic_lif * lif,struct hwtstamp_config * new_ts)67 static int ionic_lif_hwstamp_set_ts_config(struct ionic_lif *lif,
68 struct hwtstamp_config *new_ts)
69 {
70 struct ionic *ionic = lif->ionic;
71 struct hwtstamp_config *config;
72 struct hwtstamp_config ts;
73 int tx_mode = 0;
74 u64 rx_filt = 0;
75 int err, err2;
76 bool rx_all;
77 __le64 mask;
78
79 if (!lif->phc || !lif->phc->ptp)
80 return -EOPNOTSUPP;
81
82 mutex_lock(&lif->phc->config_lock);
83
84 if (new_ts) {
85 config = new_ts;
86 } else {
87 /* If called with new_ts == NULL, replay the previous request
88 * primarily for recovery after a FW_RESET.
89 * We saved the previous configuration request info, so copy
90 * the previous request for reference, clear the current state
91 * to match the device's reset state, and run with it.
92 */
93 config = &ts;
94 memcpy(config, &lif->phc->ts_config, sizeof(*config));
95 memset(&lif->phc->ts_config, 0, sizeof(lif->phc->ts_config));
96 lif->phc->ts_config_tx_mode = 0;
97 lif->phc->ts_config_rx_filt = 0;
98 }
99
100 tx_mode = ionic_hwstamp_tx_mode(config->tx_type);
101 if (tx_mode < 0) {
102 err = tx_mode;
103 goto err_queues;
104 }
105
106 mask = cpu_to_le64(BIT_ULL(tx_mode));
107 if ((ionic->ident.lif.eth.hwstamp_tx_modes & mask) != mask) {
108 err = -ERANGE;
109 goto err_queues;
110 }
111
112 rx_filt = ionic_hwstamp_rx_filt(config->rx_filter);
113 rx_all = config->rx_filter != HWTSTAMP_FILTER_NONE && !rx_filt;
114
115 mask = cpu_to_le64(rx_filt);
116 if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) != mask) {
117 rx_filt = 0;
118 rx_all = true;
119 config->rx_filter = HWTSTAMP_FILTER_ALL;
120 }
121
122 dev_dbg(ionic->dev, "config_rx_filter %d rx_filt %#llx rx_all %d\n",
123 config->rx_filter, rx_filt, rx_all);
124
125 if (tx_mode) {
126 err = ionic_lif_create_hwstamp_txq(lif);
127 if (err)
128 goto err_queues;
129 }
130
131 if (rx_filt) {
132 err = ionic_lif_create_hwstamp_rxq(lif);
133 if (err)
134 goto err_queues;
135 }
136
137 if (tx_mode != lif->phc->ts_config_tx_mode) {
138 err = ionic_lif_set_hwstamp_txmode(lif, tx_mode);
139 if (err)
140 goto err_txmode;
141 }
142
143 if (rx_filt != lif->phc->ts_config_rx_filt) {
144 err = ionic_lif_set_hwstamp_rxfilt(lif, rx_filt);
145 if (err)
146 goto err_rxfilt;
147 }
148
149 if (rx_all != (lif->phc->ts_config.rx_filter == HWTSTAMP_FILTER_ALL)) {
150 err = ionic_lif_config_hwstamp_rxq_all(lif, rx_all);
151 if (err)
152 goto err_rxall;
153 }
154
155 memcpy(&lif->phc->ts_config, config, sizeof(*config));
156 lif->phc->ts_config_rx_filt = rx_filt;
157 lif->phc->ts_config_tx_mode = tx_mode;
158
159 mutex_unlock(&lif->phc->config_lock);
160
161 return 0;
162
163 err_rxall:
164 if (rx_filt != lif->phc->ts_config_rx_filt) {
165 rx_filt = lif->phc->ts_config_rx_filt;
166 err2 = ionic_lif_set_hwstamp_rxfilt(lif, rx_filt);
167 if (err2)
168 dev_err(ionic->dev,
169 "Failed to revert rx timestamp filter: %d\n", err2);
170 }
171 err_rxfilt:
172 if (tx_mode != lif->phc->ts_config_tx_mode) {
173 tx_mode = lif->phc->ts_config_tx_mode;
174 err2 = ionic_lif_set_hwstamp_txmode(lif, tx_mode);
175 if (err2)
176 dev_err(ionic->dev,
177 "Failed to revert tx timestamp mode: %d\n", err2);
178 }
179 err_txmode:
180 /* special queues remain allocated, just unused */
181 err_queues:
182 mutex_unlock(&lif->phc->config_lock);
183 return err;
184 }
185
ionic_lif_hwstamp_set(struct ionic_lif * lif,struct ifreq * ifr)186 int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr)
187 {
188 struct hwtstamp_config config;
189 int err;
190
191 if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
192 return -EFAULT;
193
194 err = ionic_lif_hwstamp_set_ts_config(lif, &config);
195 if (err) {
196 netdev_info(lif->netdev, "hwstamp set failed: %d\n", err);
197 return err;
198 }
199
200 if (copy_to_user(ifr->ifr_data, &config, sizeof(config)))
201 return -EFAULT;
202
203 return 0;
204 }
205
ionic_lif_hwstamp_replay(struct ionic_lif * lif)206 int ionic_lif_hwstamp_replay(struct ionic_lif *lif)
207 {
208 int err;
209
210 err = ionic_lif_hwstamp_set_ts_config(lif, NULL);
211 if (err)
212 netdev_info(lif->netdev, "hwstamp replay failed: %d\n", err);
213
214 return err;
215 }
216
ionic_lif_hwstamp_get(struct ionic_lif * lif,struct ifreq * ifr)217 int ionic_lif_hwstamp_get(struct ionic_lif *lif, struct ifreq *ifr)
218 {
219 struct hwtstamp_config config;
220
221 if (!lif->phc || !lif->phc->ptp)
222 return -EOPNOTSUPP;
223
224 mutex_lock(&lif->phc->config_lock);
225 memcpy(&config, &lif->phc->ts_config, sizeof(config));
226 mutex_unlock(&lif->phc->config_lock);
227
228 if (copy_to_user(ifr->ifr_data, &config, sizeof(config)))
229 return -EFAULT;
230 return 0;
231 }
232
ionic_hwstamp_read(struct ionic * ionic,struct ptp_system_timestamp * sts)233 static u64 ionic_hwstamp_read(struct ionic *ionic,
234 struct ptp_system_timestamp *sts)
235 {
236 u32 tick_high_before, tick_high, tick_low;
237
238 /* read and discard low part to defeat hw staging of high part */
239 (void)ioread32(&ionic->idev.hwstamp_regs->tick_low);
240
241 tick_high_before = ioread32(&ionic->idev.hwstamp_regs->tick_high);
242
243 ptp_read_system_prets(sts);
244 tick_low = ioread32(&ionic->idev.hwstamp_regs->tick_low);
245 ptp_read_system_postts(sts);
246
247 tick_high = ioread32(&ionic->idev.hwstamp_regs->tick_high);
248
249 /* If tick_high changed, re-read tick_low once more. Assume tick_high
250 * cannot change again so soon as in the span of re-reading tick_low.
251 */
252 if (tick_high != tick_high_before) {
253 ptp_read_system_prets(sts);
254 tick_low = ioread32(&ionic->idev.hwstamp_regs->tick_low);
255 ptp_read_system_postts(sts);
256 }
257
258 return (u64)tick_low | ((u64)tick_high << 32);
259 }
260
ionic_cc_read(const struct cyclecounter * cc)261 static u64 ionic_cc_read(const struct cyclecounter *cc)
262 {
263 struct ionic_phc *phc = container_of(cc, struct ionic_phc, cc);
264 struct ionic *ionic = phc->lif->ionic;
265
266 return ionic_hwstamp_read(ionic, NULL);
267 }
268
ionic_setphc_cmd(struct ionic_phc * phc,struct ionic_admin_ctx * ctx)269 static int ionic_setphc_cmd(struct ionic_phc *phc, struct ionic_admin_ctx *ctx)
270 {
271 ctx->work = COMPLETION_INITIALIZER_ONSTACK(ctx->work);
272
273 ctx->cmd.lif_setphc.opcode = IONIC_CMD_LIF_SETPHC;
274 ctx->cmd.lif_setphc.lif_index = cpu_to_le16(phc->lif->index);
275
276 ctx->cmd.lif_setphc.tick = cpu_to_le64(phc->tc.cycle_last);
277 ctx->cmd.lif_setphc.nsec = cpu_to_le64(phc->tc.nsec);
278 ctx->cmd.lif_setphc.frac = cpu_to_le64(phc->tc.frac);
279 ctx->cmd.lif_setphc.mult = cpu_to_le32(phc->cc.mult);
280 ctx->cmd.lif_setphc.shift = cpu_to_le32(phc->cc.shift);
281
282 return ionic_adminq_post(phc->lif, ctx);
283 }
284
ionic_phc_adjfine(struct ptp_clock_info * info,long scaled_ppm)285 static int ionic_phc_adjfine(struct ptp_clock_info *info, long scaled_ppm)
286 {
287 struct ionic_phc *phc = container_of(info, struct ionic_phc, ptp_info);
288 struct ionic_admin_ctx ctx = {};
289 unsigned long irqflags;
290 s64 adj;
291 int err;
292
293 /* Reject phc adjustments during device upgrade */
294 if (test_bit(IONIC_LIF_F_FW_RESET, phc->lif->state))
295 return -EBUSY;
296
297 /* Adjustment value scaled by 2^16 million */
298 adj = (s64)scaled_ppm * phc->init_cc_mult;
299
300 /* Adjustment value to scale */
301 adj /= (s64)SCALED_PPM;
302
303 /* Final adjusted multiplier */
304 adj += phc->init_cc_mult;
305
306 spin_lock_irqsave(&phc->lock, irqflags);
307
308 /* update the point-in-time basis to now, before adjusting the rate */
309 timecounter_read(&phc->tc);
310 phc->cc.mult = adj;
311
312 /* Setphc commands are posted in-order, sequenced by phc->lock. We
313 * need to drop the lock before waiting for the command to complete.
314 */
315 err = ionic_setphc_cmd(phc, &ctx);
316
317 spin_unlock_irqrestore(&phc->lock, irqflags);
318
319 return ionic_adminq_wait(phc->lif, &ctx, err);
320 }
321
ionic_phc_adjtime(struct ptp_clock_info * info,s64 delta)322 static int ionic_phc_adjtime(struct ptp_clock_info *info, s64 delta)
323 {
324 struct ionic_phc *phc = container_of(info, struct ionic_phc, ptp_info);
325 struct ionic_admin_ctx ctx = {};
326 unsigned long irqflags;
327 int err;
328
329 /* Reject phc adjustments during device upgrade */
330 if (test_bit(IONIC_LIF_F_FW_RESET, phc->lif->state))
331 return -EBUSY;
332
333 spin_lock_irqsave(&phc->lock, irqflags);
334
335 timecounter_adjtime(&phc->tc, delta);
336
337 /* Setphc commands are posted in-order, sequenced by phc->lock. We
338 * need to drop the lock before waiting for the command to complete.
339 */
340 err = ionic_setphc_cmd(phc, &ctx);
341
342 spin_unlock_irqrestore(&phc->lock, irqflags);
343
344 return ionic_adminq_wait(phc->lif, &ctx, err);
345 }
346
ionic_phc_settime64(struct ptp_clock_info * info,const struct timespec64 * ts)347 static int ionic_phc_settime64(struct ptp_clock_info *info,
348 const struct timespec64 *ts)
349 {
350 struct ionic_phc *phc = container_of(info, struct ionic_phc, ptp_info);
351 struct ionic_admin_ctx ctx = {};
352 unsigned long irqflags;
353 int err;
354 u64 ns;
355
356 /* Reject phc adjustments during device upgrade */
357 if (test_bit(IONIC_LIF_F_FW_RESET, phc->lif->state))
358 return -EBUSY;
359
360 ns = timespec64_to_ns(ts);
361
362 spin_lock_irqsave(&phc->lock, irqflags);
363
364 timecounter_init(&phc->tc, &phc->cc, ns);
365
366 /* Setphc commands are posted in-order, sequenced by phc->lock. We
367 * need to drop the lock before waiting for the command to complete.
368 */
369 err = ionic_setphc_cmd(phc, &ctx);
370
371 spin_unlock_irqrestore(&phc->lock, irqflags);
372
373 return ionic_adminq_wait(phc->lif, &ctx, err);
374 }
375
ionic_phc_gettimex64(struct ptp_clock_info * info,struct timespec64 * ts,struct ptp_system_timestamp * sts)376 static int ionic_phc_gettimex64(struct ptp_clock_info *info,
377 struct timespec64 *ts,
378 struct ptp_system_timestamp *sts)
379 {
380 struct ionic_phc *phc = container_of(info, struct ionic_phc, ptp_info);
381 struct ionic *ionic = phc->lif->ionic;
382 unsigned long irqflags;
383 u64 tick, ns;
384
385 /* Do not attempt to read device time during upgrade */
386 if (test_bit(IONIC_LIF_F_FW_RESET, phc->lif->state))
387 return -EBUSY;
388
389 spin_lock_irqsave(&phc->lock, irqflags);
390
391 tick = ionic_hwstamp_read(ionic, sts);
392
393 ns = timecounter_cyc2time(&phc->tc, tick);
394
395 spin_unlock_irqrestore(&phc->lock, irqflags);
396
397 *ts = ns_to_timespec64(ns);
398
399 return 0;
400 }
401
ionic_phc_aux_work(struct ptp_clock_info * info)402 static long ionic_phc_aux_work(struct ptp_clock_info *info)
403 {
404 struct ionic_phc *phc = container_of(info, struct ionic_phc, ptp_info);
405 struct ionic_admin_ctx ctx = {};
406 unsigned long irqflags;
407 int err;
408
409 /* Do not update phc during device upgrade, but keep polling to resume
410 * after upgrade. Since we don't update the point in time basis, there
411 * is no expectation that we are maintaining the phc time during the
412 * upgrade. After upgrade, it will need to be readjusted back to the
413 * correct time by the ptp daemon.
414 */
415 if (test_bit(IONIC_LIF_F_FW_RESET, phc->lif->state))
416 return phc->aux_work_delay;
417
418 spin_lock_irqsave(&phc->lock, irqflags);
419
420 /* update point-in-time basis to now */
421 timecounter_read(&phc->tc);
422
423 /* Setphc commands are posted in-order, sequenced by phc->lock. We
424 * need to drop the lock before waiting for the command to complete.
425 */
426 err = ionic_setphc_cmd(phc, &ctx);
427
428 spin_unlock_irqrestore(&phc->lock, irqflags);
429
430 ionic_adminq_wait(phc->lif, &ctx, err);
431
432 return phc->aux_work_delay;
433 }
434
ionic_lif_phc_ktime(struct ionic_lif * lif,u64 tick)435 ktime_t ionic_lif_phc_ktime(struct ionic_lif *lif, u64 tick)
436 {
437 unsigned long irqflags;
438 u64 ns;
439
440 if (!lif->phc)
441 return 0;
442
443 spin_lock_irqsave(&lif->phc->lock, irqflags);
444 ns = timecounter_cyc2time(&lif->phc->tc, tick);
445 spin_unlock_irqrestore(&lif->phc->lock, irqflags);
446
447 return ns_to_ktime(ns);
448 }
449
450 static const struct ptp_clock_info ionic_ptp_info = {
451 .owner = THIS_MODULE,
452 .name = "ionic_ptp",
453 .adjfine = ionic_phc_adjfine,
454 .adjtime = ionic_phc_adjtime,
455 .gettimex64 = ionic_phc_gettimex64,
456 .settime64 = ionic_phc_settime64,
457 .do_aux_work = ionic_phc_aux_work,
458 };
459
ionic_lif_register_phc(struct ionic_lif * lif)460 void ionic_lif_register_phc(struct ionic_lif *lif)
461 {
462 if (!lif->phc || !(lif->hw_features & IONIC_ETH_HW_TIMESTAMP))
463 return;
464
465 lif->phc->ptp = ptp_clock_register(&lif->phc->ptp_info, lif->ionic->dev);
466
467 if (IS_ERR(lif->phc->ptp)) {
468 dev_warn(lif->ionic->dev, "Cannot register phc device: %ld\n",
469 PTR_ERR(lif->phc->ptp));
470
471 lif->phc->ptp = NULL;
472 }
473
474 if (lif->phc->ptp)
475 ptp_schedule_worker(lif->phc->ptp, lif->phc->aux_work_delay);
476 }
477
ionic_lif_unregister_phc(struct ionic_lif * lif)478 void ionic_lif_unregister_phc(struct ionic_lif *lif)
479 {
480 if (!lif->phc || !lif->phc->ptp)
481 return;
482
483 ptp_clock_unregister(lif->phc->ptp);
484
485 lif->phc->ptp = NULL;
486 }
487
ionic_lif_alloc_phc(struct ionic_lif * lif)488 void ionic_lif_alloc_phc(struct ionic_lif *lif)
489 {
490 struct ionic *ionic = lif->ionic;
491 struct ionic_phc *phc;
492 u64 delay, diff, mult;
493 u64 frac = 0;
494 u64 features;
495 u32 shift;
496
497 if (!ionic->idev.hwstamp_regs)
498 return;
499
500 features = le64_to_cpu(ionic->ident.lif.eth.config.features);
501 if (!(features & IONIC_ETH_HW_TIMESTAMP))
502 return;
503
504 phc = devm_kzalloc(ionic->dev, sizeof(*phc), GFP_KERNEL);
505 if (!phc)
506 return;
507
508 phc->lif = lif;
509
510 phc->cc.read = ionic_cc_read;
511 phc->cc.mask = le64_to_cpu(ionic->ident.dev.hwstamp_mask);
512 phc->cc.mult = le32_to_cpu(ionic->ident.dev.hwstamp_mult);
513 phc->cc.shift = le32_to_cpu(ionic->ident.dev.hwstamp_shift);
514
515 if (!phc->cc.mult) {
516 dev_err(lif->ionic->dev,
517 "Invalid device PHC mask multiplier %u, disabling HW timestamp support\n",
518 phc->cc.mult);
519 devm_kfree(lif->ionic->dev, phc);
520 lif->phc = NULL;
521 return;
522 }
523
524 dev_dbg(lif->ionic->dev, "Device PHC mask %#llx mult %u shift %u\n",
525 phc->cc.mask, phc->cc.mult, phc->cc.shift);
526
527 spin_lock_init(&phc->lock);
528 mutex_init(&phc->config_lock);
529
530 /* max ticks is limited by the multiplier, or by the update period. */
531 if (phc->cc.shift + 2 + ilog2(IONIC_PHC_UPDATE_NS) >= 64) {
532 /* max ticks that do not overflow when multiplied by max
533 * adjusted multiplier (twice the initial multiplier)
534 */
535 diff = U64_MAX / phc->cc.mult / 2;
536 } else {
537 /* approx ticks at four times the update period */
538 diff = (u64)IONIC_PHC_UPDATE_NS << (phc->cc.shift + 2);
539 diff = DIV_ROUND_UP(diff, phc->cc.mult);
540 }
541
542 /* transform to bitmask */
543 diff |= diff >> 1;
544 diff |= diff >> 2;
545 diff |= diff >> 4;
546 diff |= diff >> 8;
547 diff |= diff >> 16;
548 diff |= diff >> 32;
549
550 /* constrain to the hardware bitmask, and use this as the bitmask */
551 diff &= phc->cc.mask;
552 phc->cc.mask = diff;
553
554 /* the wrap period is now defined by diff (or phc->cc.mask)
555 *
556 * we will update the time basis at about 1/4 the wrap period, so
557 * should not see a difference of more than +/- diff/4.
558 *
559 * this is sufficient not see a difference of more than +/- diff/2, as
560 * required by timecounter_cyc2time, to detect an old time stamp.
561 *
562 * adjust the initial multiplier, being careful to avoid overflow:
563 * - do not overflow 63 bits: init_cc_mult * SCALED_PPM
564 * - do not overflow 64 bits: max_mult * (diff / 2)
565 *
566 * we want to increase the initial multiplier as much as possible, to
567 * allow for more precise adjustment in ionic_phc_adjfine.
568 *
569 * only adjust the multiplier if we can double it or more.
570 */
571 mult = U64_MAX / 2 / max(diff / 2, SCALED_PPM);
572 shift = mult / phc->cc.mult;
573 if (shift >= 2) {
574 /* initial multiplier will be 2^n of hardware cc.mult */
575 shift = fls(shift);
576 /* increase cc.mult and cc.shift by the same 2^n and n. */
577 phc->cc.mult <<= shift;
578 phc->cc.shift += shift;
579 }
580
581 dev_dbg(lif->ionic->dev, "Initial PHC mask %#llx mult %u shift %u\n",
582 phc->cc.mask, phc->cc.mult, phc->cc.shift);
583
584 /* frequency adjustments are relative to the initial multiplier */
585 phc->init_cc_mult = phc->cc.mult;
586
587 timecounter_init(&phc->tc, &phc->cc, ktime_get_real_ns());
588
589 /* Update cycle_last at 1/4 the wrap period, or IONIC_PHC_UPDATE_NS */
590 delay = min_t(u64, IONIC_PHC_UPDATE_NS,
591 cyclecounter_cyc2ns(&phc->cc, diff / 4, 0, &frac));
592 dev_dbg(lif->ionic->dev, "Work delay %llu ms\n", delay / NSEC_PER_MSEC);
593
594 phc->aux_work_delay = nsecs_to_jiffies(delay);
595
596 phc->ptp_info = ionic_ptp_info;
597
598 /* We have allowed to adjust the multiplier up to +/- 1 part per 1.
599 * Here expressed as NORMAL_PPB (1 billion parts per billion).
600 */
601 phc->ptp_info.max_adj = NORMAL_PPB;
602
603 lif->phc = phc;
604 }
605
ionic_lif_free_phc(struct ionic_lif * lif)606 void ionic_lif_free_phc(struct ionic_lif *lif)
607 {
608 if (!lif->phc)
609 return;
610
611 mutex_destroy(&lif->phc->config_lock);
612
613 devm_kfree(lif->ionic->dev, lif->phc);
614 lif->phc = NULL;
615 }
616