File Index
Files and directories
Sign in
FILE

ionic_phc.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/ethernet/pensando/ionic/ionic_phc.c C
  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}
~/ Read-only file preview.