Lines Matching +full:clock +full:- +full:detection +full:- +full:disable

1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
3 * Copyright (c) 2015-2017 QLogic Corporation
4 * Copyright (c) 2019-2020 Marvell International Ltd.
15 struct ptp_clock *clock; member
31 * qede_ptp_adjfine() - Adjust the frequency of the PTP cycle counter.
33 * @info: The PTP clock info structure.
36 * Scaled parts per million is ppm with a 16-bit binary fractional field.
44 struct qede_dev *edev = ptp->edev; in qede_ptp_adjfine()
48 if (edev->state == QEDE_STATE_OPEN) { in qede_ptp_adjfine()
49 spin_lock_bh(&ptp->lock); in qede_ptp_adjfine()
50 rc = ptp->ops->adjfreq(edev->cdev, ppb); in qede_ptp_adjfine()
51 spin_unlock_bh(&ptp->lock); in qede_ptp_adjfine()
54 rc = -EFAULT; in qede_ptp_adjfine()
67 edev = ptp->edev; in qede_ptp_adjtime()
72 spin_lock_bh(&ptp->lock); in qede_ptp_adjtime()
73 timecounter_adjtime(&ptp->tc, delta); in qede_ptp_adjtime()
74 spin_unlock_bh(&ptp->lock); in qede_ptp_adjtime()
86 edev = ptp->edev; in qede_ptp_gettime()
88 spin_lock_bh(&ptp->lock); in qede_ptp_gettime()
89 ns = timecounter_read(&ptp->tc); in qede_ptp_gettime()
90 spin_unlock_bh(&ptp->lock); in qede_ptp_gettime()
107 edev = ptp->edev; in qede_ptp_settime()
113 /* Re-init the timecounter */ in qede_ptp_settime()
114 spin_lock_bh(&ptp->lock); in qede_ptp_settime()
115 timecounter_init(&ptp->tc, &ptp->cc, ns); in qede_ptp_settime()
116 spin_unlock_bh(&ptp->lock); in qede_ptp_settime()
121 /* Enable (or disable) ancillary features of the phc subsystem */
130 edev = ptp->edev; in qede_ptp_ancillary_feature_enable()
134 return -ENOTSUPP; in qede_ptp_ancillary_feature_enable()
147 edev = ptp->edev; in qede_ptp_task()
148 timedout = time_is_before_jiffies(ptp->ptp_tx_start + in qede_ptp_task()
152 spin_lock_bh(&ptp->lock); in qede_ptp_task()
153 rc = ptp->ops->read_tx_ts(edev->cdev, &timestamp); in qede_ptp_task()
154 spin_unlock_bh(&ptp->lock); in qede_ptp_task()
158 dev_kfree_skb_any(ptp->tx_skb); in qede_ptp_task()
159 ptp->tx_skb = NULL; in qede_ptp_task()
161 &edev->flags); in qede_ptp_task()
162 edev->ptp_skip_txts++; in qede_ptp_task()
165 schedule_work(&ptp->work); in qede_ptp_task()
170 ns = timecounter_cyc2time(&ptp->tc, timestamp); in qede_ptp_task()
173 skb_tstamp_tx(ptp->tx_skb, &shhwtstamps); in qede_ptp_task()
174 dev_kfree_skb_any(ptp->tx_skb); in qede_ptp_task()
175 ptp->tx_skb = NULL; in qede_ptp_task()
176 clear_bit_unlock(QEDE_FLAGS_PTP_TX_IN_PRORGESS, &edev->flags); in qede_ptp_task()
192 edev = ptp->edev; in qede_ptp_read_cc()
193 rc = ptp->ops->read_cc(edev->cdev, &phc_cycles); in qede_ptp_read_cc()
206 struct qede_ptp *ptp = edev->ptp; in qede_ptp_cfg_filters()
209 return -EIO; in qede_ptp_cfg_filters()
211 if (!ptp->hw_ts_ioctl_called) { in qede_ptp_cfg_filters()
216 switch (ptp->tx_type) { in qede_ptp_cfg_filters()
218 set_bit(QEDE_FLAGS_TX_TIMESTAMPING_EN, &edev->flags); in qede_ptp_cfg_filters()
223 clear_bit(QEDE_FLAGS_TX_TIMESTAMPING_EN, &edev->flags); in qede_ptp_cfg_filters()
229 DP_ERR(edev, "One-step timestamping is not supported\n"); in qede_ptp_cfg_filters()
230 return -ERANGE; in qede_ptp_cfg_filters()
233 spin_lock_bh(&ptp->lock); in qede_ptp_cfg_filters()
234 switch (ptp->rx_filter) { in qede_ptp_cfg_filters()
241 ptp->rx_filter = HWTSTAMP_FILTER_NONE; in qede_ptp_cfg_filters()
245 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; in qede_ptp_cfg_filters()
250 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; in qede_ptp_cfg_filters()
251 /* Initialize PTP detection for UDP/IPv4 events */ in qede_ptp_cfg_filters()
255 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; in qede_ptp_cfg_filters()
260 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; in qede_ptp_cfg_filters()
261 /* Initialize PTP detection for UDP/IPv4 or UDP/IPv6 events */ in qede_ptp_cfg_filters()
265 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT; in qede_ptp_cfg_filters()
270 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT; in qede_ptp_cfg_filters()
271 /* Initialize PTP detection L2 events */ in qede_ptp_cfg_filters()
275 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; in qede_ptp_cfg_filters()
280 ptp->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; in qede_ptp_cfg_filters()
281 /* Initialize PTP detection L2, UDP/IPv4 or UDP/IPv6 events */ in qede_ptp_cfg_filters()
286 ptp->ops->cfg_filters(edev->cdev, rx_filter, tx_type); in qede_ptp_cfg_filters()
288 spin_unlock_bh(&ptp->lock); in qede_ptp_cfg_filters()
299 ptp = edev->ptp; in qede_ptp_hw_ts()
301 return -EIO; in qede_ptp_hw_ts()
303 if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) in qede_ptp_hw_ts()
304 return -EFAULT; in qede_ptp_hw_ts()
310 ptp->hw_ts_ioctl_called = 1; in qede_ptp_hw_ts()
311 ptp->tx_type = config.tx_type; in qede_ptp_hw_ts()
312 ptp->rx_filter = config.rx_filter; in qede_ptp_hw_ts()
318 config.rx_filter = ptp->rx_filter; in qede_ptp_hw_ts()
320 return copy_to_user(ifr->ifr_data, &config, in qede_ptp_hw_ts()
321 sizeof(config)) ? -EFAULT : 0; in qede_ptp_hw_ts()
326 struct qede_ptp *ptp = edev->ptp; in qede_ptp_get_ts_info()
329 info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE; in qede_ptp_get_ts_info()
334 info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE | in qede_ptp_get_ts_info()
339 if (ptp->clock) in qede_ptp_get_ts_info()
340 info->phc_index = ptp_clock_index(ptp->clock); in qede_ptp_get_ts_info()
342 info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | in qede_ptp_get_ts_info()
356 info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON); in qede_ptp_get_ts_info()
365 ptp = edev->ptp; in qede_ptp_disable()
369 if (ptp->clock) { in qede_ptp_disable()
370 ptp_clock_unregister(ptp->clock); in qede_ptp_disable()
371 ptp->clock = NULL; in qede_ptp_disable()
377 cancel_work_sync(&ptp->work); in qede_ptp_disable()
378 if (ptp->tx_skb) { in qede_ptp_disable()
379 dev_kfree_skb_any(ptp->tx_skb); in qede_ptp_disable()
380 ptp->tx_skb = NULL; in qede_ptp_disable()
381 clear_bit_unlock(QEDE_FLAGS_PTP_TX_IN_PRORGESS, &edev->flags); in qede_ptp_disable()
384 /* Disable PTP in HW */ in qede_ptp_disable()
385 spin_lock_bh(&ptp->lock); in qede_ptp_disable()
386 ptp->ops->disable(edev->cdev); in qede_ptp_disable()
387 spin_unlock_bh(&ptp->lock); in qede_ptp_disable()
390 edev->ptp = NULL; in qede_ptp_disable()
398 ptp = edev->ptp; in qede_ptp_init()
400 return -EINVAL; in qede_ptp_init()
402 spin_lock_init(&ptp->lock); in qede_ptp_init()
405 rc = ptp->ops->enable(edev->cdev); in qede_ptp_init()
412 INIT_WORK(&ptp->work, qede_ptp_task); in qede_ptp_init()
415 memset(&ptp->cc, 0, sizeof(ptp->cc)); in qede_ptp_init()
416 ptp->cc.read = qede_ptp_read_cc; in qede_ptp_init()
417 ptp->cc.mask = CYCLECOUNTER_MASK(64); in qede_ptp_init()
418 ptp->cc.shift = 0; in qede_ptp_init()
419 ptp->cc.mult = 1; in qede_ptp_init()
421 timecounter_init(&ptp->tc, &ptp->cc, ktime_to_ns(ktime_get_real())); in qede_ptp_init()
434 return -ENOMEM; in qede_ptp_enable()
437 ptp->edev = edev; in qede_ptp_enable()
438 ptp->ops = edev->ops->ptp; in qede_ptp_enable()
439 if (!ptp->ops) { in qede_ptp_enable()
441 rc = -EIO; in qede_ptp_enable()
445 edev->ptp = ptp; in qede_ptp_enable()
453 /* Fill the ptp_clock_info struct and register PTP clock */ in qede_ptp_enable()
454 ptp->clock_info.owner = THIS_MODULE; in qede_ptp_enable()
455 snprintf(ptp->clock_info.name, 16, "%s", edev->ndev->name); in qede_ptp_enable()
456 ptp->clock_info.max_adj = QED_MAX_PHC_DRIFT_PPB; in qede_ptp_enable()
457 ptp->clock_info.n_alarm = 0; in qede_ptp_enable()
458 ptp->clock_info.n_ext_ts = 0; in qede_ptp_enable()
459 ptp->clock_info.n_per_out = 0; in qede_ptp_enable()
460 ptp->clock_info.pps = 0; in qede_ptp_enable()
461 ptp->clock_info.adjfine = qede_ptp_adjfine; in qede_ptp_enable()
462 ptp->clock_info.adjtime = qede_ptp_adjtime; in qede_ptp_enable()
463 ptp->clock_info.gettime64 = qede_ptp_gettime; in qede_ptp_enable()
464 ptp->clock_info.settime64 = qede_ptp_settime; in qede_ptp_enable()
465 ptp->clock_info.enable = qede_ptp_ancillary_feature_enable; in qede_ptp_enable()
467 ptp->clock = ptp_clock_register(&ptp->clock_info, &edev->pdev->dev); in qede_ptp_enable()
468 if (IS_ERR(ptp->clock)) { in qede_ptp_enable()
469 DP_ERR(edev, "PTP clock registration failed\n"); in qede_ptp_enable()
471 rc = -EINVAL; in qede_ptp_enable()
480 edev->ptp = NULL; in qede_ptp_enable()
489 ptp = edev->ptp; in qede_ptp_tx_ts()
494 &edev->flags)) { in qede_ptp_tx_ts()
496 edev->ptp_skip_txts++; in qede_ptp_tx_ts()
500 if (unlikely(!test_bit(QEDE_FLAGS_TX_TIMESTAMPING_EN, &edev->flags))) { in qede_ptp_tx_ts()
503 clear_bit_unlock(QEDE_FLAGS_PTP_TX_IN_PRORGESS, &edev->flags); in qede_ptp_tx_ts()
504 edev->ptp_skip_txts++; in qede_ptp_tx_ts()
505 } else if (unlikely(ptp->tx_skb)) { in qede_ptp_tx_ts()
508 clear_bit_unlock(QEDE_FLAGS_PTP_TX_IN_PRORGESS, &edev->flags); in qede_ptp_tx_ts()
509 edev->ptp_skip_txts++; in qede_ptp_tx_ts()
511 skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; in qede_ptp_tx_ts()
513 ptp->tx_skb = skb_get(skb); in qede_ptp_tx_ts()
514 ptp->ptp_tx_start = jiffies; in qede_ptp_tx_ts()
515 schedule_work(&ptp->work); in qede_ptp_tx_ts()
525 ptp = edev->ptp; in qede_ptp_rx_ts()
529 spin_lock_bh(&ptp->lock); in qede_ptp_rx_ts()
530 rc = ptp->ops->read_rx_ts(edev->cdev, &timestamp); in qede_ptp_rx_ts()
532 spin_unlock_bh(&ptp->lock); in qede_ptp_rx_ts()
537 ns = timecounter_cyc2time(&ptp->tc, timestamp); in qede_ptp_rx_ts()
538 spin_unlock_bh(&ptp->lock); in qede_ptp_rx_ts()
539 skb_hwtstamps(skb)->hwtstamp = ns_to_ktime(ns); in qede_ptp_rx_ts()