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