Lines Matching +full:max +full:- +full:adj

1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2017 - 2021 Pensando Systems, Inc */
24 return -ERANGE; in ionic_hwstamp_tx_mode()
70 struct ionic *ionic = lif->ionic; in ionic_lif_hwstamp_set_ts_config()
79 if (!lif->phc || !lif->phc->ptp) in ionic_lif_hwstamp_set_ts_config()
80 return -EOPNOTSUPP; in ionic_lif_hwstamp_set_ts_config()
82 mutex_lock(&lif->phc->config_lock); in ionic_lif_hwstamp_set_ts_config()
94 memcpy(config, &lif->phc->ts_config, sizeof(*config)); in ionic_lif_hwstamp_set_ts_config()
95 memset(&lif->phc->ts_config, 0, sizeof(lif->phc->ts_config)); in ionic_lif_hwstamp_set_ts_config()
96 lif->phc->ts_config_tx_mode = 0; in ionic_lif_hwstamp_set_ts_config()
97 lif->phc->ts_config_rx_filt = 0; in ionic_lif_hwstamp_set_ts_config()
100 tx_mode = ionic_hwstamp_tx_mode(config->tx_type); in ionic_lif_hwstamp_set_ts_config()
107 if ((ionic->ident.lif.eth.hwstamp_tx_modes & mask) != mask) { in ionic_lif_hwstamp_set_ts_config()
108 err = -ERANGE; in ionic_lif_hwstamp_set_ts_config()
112 rx_filt = ionic_hwstamp_rx_filt(config->rx_filter); in ionic_lif_hwstamp_set_ts_config()
113 rx_all = config->rx_filter != HWTSTAMP_FILTER_NONE && !rx_filt; in ionic_lif_hwstamp_set_ts_config()
116 if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) != mask) { in ionic_lif_hwstamp_set_ts_config()
119 config->rx_filter = HWTSTAMP_FILTER_ALL; in ionic_lif_hwstamp_set_ts_config()
122 dev_dbg(ionic->dev, "%s: config_rx_filter %d rx_filt %#llx rx_all %d\n", in ionic_lif_hwstamp_set_ts_config()
123 __func__, config->rx_filter, rx_filt, rx_all); in ionic_lif_hwstamp_set_ts_config()
137 if (tx_mode != lif->phc->ts_config_tx_mode) { in ionic_lif_hwstamp_set_ts_config()
143 if (rx_filt != lif->phc->ts_config_rx_filt) { in ionic_lif_hwstamp_set_ts_config()
149 if (rx_all != (lif->phc->ts_config.rx_filter == HWTSTAMP_FILTER_ALL)) { in ionic_lif_hwstamp_set_ts_config()
155 memcpy(&lif->phc->ts_config, config, sizeof(*config)); in ionic_lif_hwstamp_set_ts_config()
156 lif->phc->ts_config_rx_filt = rx_filt; in ionic_lif_hwstamp_set_ts_config()
157 lif->phc->ts_config_tx_mode = tx_mode; in ionic_lif_hwstamp_set_ts_config()
159 mutex_unlock(&lif->phc->config_lock); in ionic_lif_hwstamp_set_ts_config()
164 if (rx_filt != lif->phc->ts_config_rx_filt) { in ionic_lif_hwstamp_set_ts_config()
165 rx_filt = lif->phc->ts_config_rx_filt; in ionic_lif_hwstamp_set_ts_config()
168 dev_err(ionic->dev, in ionic_lif_hwstamp_set_ts_config()
172 if (tx_mode != lif->phc->ts_config_tx_mode) { in ionic_lif_hwstamp_set_ts_config()
173 tx_mode = lif->phc->ts_config_tx_mode; in ionic_lif_hwstamp_set_ts_config()
176 dev_err(ionic->dev, in ionic_lif_hwstamp_set_ts_config()
182 mutex_unlock(&lif->phc->config_lock); in ionic_lif_hwstamp_set_ts_config()
191 if (!lif->phc || !lif->phc->ptp) in ionic_lif_hwstamp_set()
192 return -EOPNOTSUPP; in ionic_lif_hwstamp_set()
194 if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) in ionic_lif_hwstamp_set()
195 return -EFAULT; in ionic_lif_hwstamp_set()
197 mutex_lock(&lif->queue_lock); in ionic_lif_hwstamp_set()
199 mutex_unlock(&lif->queue_lock); in ionic_lif_hwstamp_set()
201 netdev_info(lif->netdev, "hwstamp set failed: %d\n", err); in ionic_lif_hwstamp_set()
205 if (copy_to_user(ifr->ifr_data, &config, sizeof(config))) in ionic_lif_hwstamp_set()
206 return -EFAULT; in ionic_lif_hwstamp_set()
215 if (!lif->phc || !lif->phc->ptp) in ionic_lif_hwstamp_replay()
218 mutex_lock(&lif->queue_lock); in ionic_lif_hwstamp_replay()
220 mutex_unlock(&lif->queue_lock); in ionic_lif_hwstamp_replay()
222 netdev_info(lif->netdev, "hwstamp replay failed: %d\n", err); in ionic_lif_hwstamp_replay()
229 if (!lif->phc || !lif->phc->ptp) in ionic_lif_hwstamp_recreate_queues()
232 mutex_lock(&lif->phc->config_lock); in ionic_lif_hwstamp_recreate_queues()
234 if (lif->phc->ts_config_tx_mode) { in ionic_lif_hwstamp_recreate_queues()
237 netdev_info(lif->netdev, "hwstamp recreate txq failed: %d\n", err); in ionic_lif_hwstamp_recreate_queues()
240 if (lif->phc->ts_config_rx_filt) { in ionic_lif_hwstamp_recreate_queues()
243 netdev_info(lif->netdev, "hwstamp recreate rxq failed: %d\n", err); in ionic_lif_hwstamp_recreate_queues()
246 mutex_unlock(&lif->phc->config_lock); in ionic_lif_hwstamp_recreate_queues()
253 if (!lif->phc || !lif->phc->ptp) in ionic_lif_hwstamp_get()
254 return -EOPNOTSUPP; in ionic_lif_hwstamp_get()
256 mutex_lock(&lif->phc->config_lock); in ionic_lif_hwstamp_get()
257 memcpy(&config, &lif->phc->ts_config, sizeof(config)); in ionic_lif_hwstamp_get()
258 mutex_unlock(&lif->phc->config_lock); in ionic_lif_hwstamp_get()
260 if (copy_to_user(ifr->ifr_data, &config, sizeof(config))) in ionic_lif_hwstamp_get()
261 return -EFAULT; in ionic_lif_hwstamp_get()
271 ioread32(&ionic->idev.hwstamp_regs->tick_low); in ionic_hwstamp_read()
273 tick_high_before = ioread32(&ionic->idev.hwstamp_regs->tick_high); in ionic_hwstamp_read()
276 tick_low = ioread32(&ionic->idev.hwstamp_regs->tick_low); in ionic_hwstamp_read()
279 tick_high = ioread32(&ionic->idev.hwstamp_regs->tick_high); in ionic_hwstamp_read()
281 /* If tick_high changed, re-read tick_low once more. Assume tick_high in ionic_hwstamp_read()
282 * cannot change again so soon as in the span of re-reading tick_low. in ionic_hwstamp_read()
286 tick_low = ioread32(&ionic->idev.hwstamp_regs->tick_low); in ionic_hwstamp_read()
296 struct ionic *ionic = phc->lif->ionic; in ionic_cc_read()
303 ctx->work = COMPLETION_INITIALIZER_ONSTACK(ctx->work); in ionic_setphc_cmd()
305 ctx->cmd.lif_setphc.opcode = IONIC_CMD_LIF_SETPHC; in ionic_setphc_cmd()
306 ctx->cmd.lif_setphc.lif_index = cpu_to_le16(phc->lif->index); in ionic_setphc_cmd()
308 ctx->cmd.lif_setphc.tick = cpu_to_le64(phc->tc.cycle_last); in ionic_setphc_cmd()
309 ctx->cmd.lif_setphc.nsec = cpu_to_le64(phc->tc.nsec); in ionic_setphc_cmd()
310 ctx->cmd.lif_setphc.frac = cpu_to_le64(phc->tc.frac); in ionic_setphc_cmd()
311 ctx->cmd.lif_setphc.mult = cpu_to_le32(phc->cc.mult); in ionic_setphc_cmd()
312 ctx->cmd.lif_setphc.shift = cpu_to_le32(phc->cc.shift); in ionic_setphc_cmd()
314 return ionic_adminq_post(phc->lif, ctx); in ionic_setphc_cmd()
322 s64 adj; in ionic_phc_adjfine() local
326 if (test_bit(IONIC_LIF_F_FW_RESET, phc->lif->state)) in ionic_phc_adjfine()
327 return -EBUSY; in ionic_phc_adjfine()
330 adj = (s64)scaled_ppm * phc->init_cc_mult; in ionic_phc_adjfine()
333 adj /= (s64)SCALED_PPM; in ionic_phc_adjfine()
336 adj += phc->init_cc_mult; in ionic_phc_adjfine()
338 spin_lock_irqsave(&phc->lock, irqflags); in ionic_phc_adjfine()
340 /* update the point-in-time basis to now, before adjusting the rate */ in ionic_phc_adjfine()
341 timecounter_read(&phc->tc); in ionic_phc_adjfine()
342 phc->cc.mult = adj; in ionic_phc_adjfine()
344 /* Setphc commands are posted in-order, sequenced by phc->lock. We in ionic_phc_adjfine()
349 spin_unlock_irqrestore(&phc->lock, irqflags); in ionic_phc_adjfine()
351 return ionic_adminq_wait(phc->lif, &ctx, err, true); in ionic_phc_adjfine()
362 if (test_bit(IONIC_LIF_F_FW_RESET, phc->lif->state)) in ionic_phc_adjtime()
363 return -EBUSY; in ionic_phc_adjtime()
365 spin_lock_irqsave(&phc->lock, irqflags); in ionic_phc_adjtime()
367 timecounter_adjtime(&phc->tc, delta); in ionic_phc_adjtime()
369 /* Setphc commands are posted in-order, sequenced by phc->lock. We in ionic_phc_adjtime()
374 spin_unlock_irqrestore(&phc->lock, irqflags); in ionic_phc_adjtime()
376 return ionic_adminq_wait(phc->lif, &ctx, err, true); in ionic_phc_adjtime()
389 if (test_bit(IONIC_LIF_F_FW_RESET, phc->lif->state)) in ionic_phc_settime64()
390 return -EBUSY; in ionic_phc_settime64()
394 spin_lock_irqsave(&phc->lock, irqflags); in ionic_phc_settime64()
396 timecounter_init(&phc->tc, &phc->cc, ns); in ionic_phc_settime64()
398 /* Setphc commands are posted in-order, sequenced by phc->lock. We in ionic_phc_settime64()
403 spin_unlock_irqrestore(&phc->lock, irqflags); in ionic_phc_settime64()
405 return ionic_adminq_wait(phc->lif, &ctx, err, true); in ionic_phc_settime64()
413 struct ionic *ionic = phc->lif->ionic; in ionic_phc_gettimex64()
418 if (test_bit(IONIC_LIF_F_FW_RESET, phc->lif->state)) in ionic_phc_gettimex64()
419 return -EBUSY; in ionic_phc_gettimex64()
421 spin_lock_irqsave(&phc->lock, irqflags); in ionic_phc_gettimex64()
425 ns = timecounter_cyc2time(&phc->tc, tick); in ionic_phc_gettimex64()
427 spin_unlock_irqrestore(&phc->lock, irqflags); in ionic_phc_gettimex64()
447 if (test_bit(IONIC_LIF_F_FW_RESET, phc->lif->state)) in ionic_phc_aux_work()
448 return phc->aux_work_delay; in ionic_phc_aux_work()
450 spin_lock_irqsave(&phc->lock, irqflags); in ionic_phc_aux_work()
452 /* update point-in-time basis to now */ in ionic_phc_aux_work()
453 timecounter_read(&phc->tc); in ionic_phc_aux_work()
455 /* Setphc commands are posted in-order, sequenced by phc->lock. We in ionic_phc_aux_work()
460 spin_unlock_irqrestore(&phc->lock, irqflags); in ionic_phc_aux_work()
462 ionic_adminq_wait(phc->lif, &ctx, err, true); in ionic_phc_aux_work()
464 return phc->aux_work_delay; in ionic_phc_aux_work()
472 if (!lif->phc) in ionic_lif_phc_ktime()
475 spin_lock_irqsave(&lif->phc->lock, irqflags); in ionic_lif_phc_ktime()
476 ns = timecounter_cyc2time(&lif->phc->tc, tick); in ionic_lif_phc_ktime()
477 spin_unlock_irqrestore(&lif->phc->lock, irqflags); in ionic_lif_phc_ktime()
494 if (!lif->phc || !(lif->hw_features & IONIC_ETH_HW_TIMESTAMP)) in ionic_lif_register_phc()
497 lif->phc->ptp = ptp_clock_register(&lif->phc->ptp_info, lif->ionic->dev); in ionic_lif_register_phc()
499 if (IS_ERR(lif->phc->ptp)) { in ionic_lif_register_phc()
500 dev_warn(lif->ionic->dev, "Cannot register phc device: %ld\n", in ionic_lif_register_phc()
501 PTR_ERR(lif->phc->ptp)); in ionic_lif_register_phc()
503 lif->phc->ptp = NULL; in ionic_lif_register_phc()
506 if (lif->phc->ptp) in ionic_lif_register_phc()
507 ptp_schedule_worker(lif->phc->ptp, lif->phc->aux_work_delay); in ionic_lif_register_phc()
512 if (!lif->phc || !lif->phc->ptp) in ionic_lif_unregister_phc()
515 ptp_clock_unregister(lif->phc->ptp); in ionic_lif_unregister_phc()
517 lif->phc->ptp = NULL; in ionic_lif_unregister_phc()
522 struct ionic *ionic = lif->ionic; in ionic_lif_alloc_phc()
529 if (!ionic->idev.hwstamp_regs) in ionic_lif_alloc_phc()
532 features = le64_to_cpu(ionic->ident.lif.eth.config.features); in ionic_lif_alloc_phc()
536 phc = devm_kzalloc(ionic->dev, sizeof(*phc), GFP_KERNEL); in ionic_lif_alloc_phc()
540 phc->lif = lif; in ionic_lif_alloc_phc()
542 phc->cc.read = ionic_cc_read; in ionic_lif_alloc_phc()
543 phc->cc.mask = le64_to_cpu(ionic->ident.dev.hwstamp_mask); in ionic_lif_alloc_phc()
544 phc->cc.mult = le32_to_cpu(ionic->ident.dev.hwstamp_mult); in ionic_lif_alloc_phc()
545 phc->cc.shift = le32_to_cpu(ionic->ident.dev.hwstamp_shift); in ionic_lif_alloc_phc()
547 if (!phc->cc.mult) { in ionic_lif_alloc_phc()
548 dev_err(lif->ionic->dev, in ionic_lif_alloc_phc()
550 phc->cc.mult); in ionic_lif_alloc_phc()
551 devm_kfree(lif->ionic->dev, phc); in ionic_lif_alloc_phc()
552 lif->phc = NULL; in ionic_lif_alloc_phc()
556 dev_dbg(lif->ionic->dev, "Device PHC mask %#llx mult %u shift %u\n", in ionic_lif_alloc_phc()
557 phc->cc.mask, phc->cc.mult, phc->cc.shift); in ionic_lif_alloc_phc()
559 spin_lock_init(&phc->lock); in ionic_lif_alloc_phc()
560 mutex_init(&phc->config_lock); in ionic_lif_alloc_phc()
562 /* max ticks is limited by the multiplier, or by the update period. */ in ionic_lif_alloc_phc()
563 if (phc->cc.shift + 2 + ilog2(IONIC_PHC_UPDATE_NS) >= 64) { in ionic_lif_alloc_phc()
564 /* max ticks that do not overflow when multiplied by max in ionic_lif_alloc_phc()
567 diff = U64_MAX / phc->cc.mult / 2; in ionic_lif_alloc_phc()
570 diff = (u64)IONIC_PHC_UPDATE_NS << (phc->cc.shift + 2); in ionic_lif_alloc_phc()
571 diff = DIV_ROUND_UP(diff, phc->cc.mult); in ionic_lif_alloc_phc()
583 diff &= phc->cc.mask; in ionic_lif_alloc_phc()
588 * should not see a difference of more than +/- diff/4. in ionic_lif_alloc_phc()
590 * this is sufficient not see a difference of more than +/- diff/2, as in ionic_lif_alloc_phc()
594 * - do not overflow 63 bits: init_cc_mult * SCALED_PPM in ionic_lif_alloc_phc()
595 * - do not overflow 64 bits: max_mult * (diff / 2) in ionic_lif_alloc_phc()
602 mult = U64_MAX / 2 / max(diff / 2, SCALED_PPM); in ionic_lif_alloc_phc()
603 shift = mult / phc->cc.mult; in ionic_lif_alloc_phc()
608 phc->cc.mult <<= shift; in ionic_lif_alloc_phc()
609 phc->cc.shift += shift; in ionic_lif_alloc_phc()
612 dev_dbg(lif->ionic->dev, "Initial PHC mask %#llx mult %u shift %u\n", in ionic_lif_alloc_phc()
613 phc->cc.mask, phc->cc.mult, phc->cc.shift); in ionic_lif_alloc_phc()
616 phc->init_cc_mult = phc->cc.mult; in ionic_lif_alloc_phc()
618 timecounter_init(&phc->tc, &phc->cc, ktime_get_real_ns()); in ionic_lif_alloc_phc()
622 cyclecounter_cyc2ns(&phc->cc, diff / 4, 0, &frac)); in ionic_lif_alloc_phc()
623 dev_dbg(lif->ionic->dev, "Work delay %llu ms\n", delay / NSEC_PER_MSEC); in ionic_lif_alloc_phc()
625 phc->aux_work_delay = nsecs_to_jiffies(delay); in ionic_lif_alloc_phc()
627 phc->ptp_info = ionic_ptp_info; in ionic_lif_alloc_phc()
629 /* We have allowed to adjust the multiplier up to +/- 1 part per 1. in ionic_lif_alloc_phc()
632 phc->ptp_info.max_adj = NORMAL_PPB; in ionic_lif_alloc_phc()
634 lif->phc = phc; in ionic_lif_alloc_phc()
639 if (!lif->phc) in ionic_lif_free_phc()
642 mutex_destroy(&lif->phc->config_lock); in ionic_lif_free_phc()
644 devm_kfree(lif->ionic->dev, lif->phc); in ionic_lif_free_phc()
645 lif->phc = NULL; in ionic_lif_free_phc()