1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2021 Marvell.
5 #include "cnxk_ethdev.h"
7 /* This function calculates two parameters "clk_freq_mult" and
8 * "clk_delta" which is useful in deriving PTP HI clock from
9 * timestamp counter (tsc) value.
12 cnxk_nix_tsc_convert(struct cnxk_eth_dev *dev)
14 uint64_t ticks_base = 0, ticks = 0, tsc = 0, t_freq;
15 struct roc_nix *nix = &dev->nix;
18 /* Calculating the frequency at which PTP HI clock is running */
19 rc = roc_nix_ptp_clock_read(nix, &ticks_base, &tsc, false);
21 plt_err("Failed to read the raw clock value: %d", rc);
27 rc = roc_nix_ptp_clock_read(nix, &ticks, &tsc, false);
29 plt_err("Failed to read the raw clock value: %d", rc);
33 t_freq = (ticks - ticks_base) * 10;
35 /* Calculating the freq multiplier viz the ratio between the
36 * frequency at which PTP HI clock works and tsc clock runs
39 (double)pow(10, floor(log10(t_freq))) / rte_get_timer_hz();
42 #ifdef RTE_ARM_EAL_RDTSC_USE_PMU
45 rc = roc_nix_ptp_clock_read(nix, &ticks, &tsc, val);
47 plt_err("Failed to read the raw clock value: %d", rc);
51 /* Calculating delta between PTP HI clock and tsc */
52 dev->clk_delta = ((uint64_t)(ticks / dev->clk_freq_mult) - tsc);
59 cnxk_nix_timesync_enable(struct rte_eth_dev *eth_dev)
61 struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
62 struct cnxk_timesync_info *tstamp = &dev->tstamp;
63 struct roc_nix *nix = &dev->nix;
64 const struct rte_memzone *ts;
67 /* If we are VF/SDP/LBK, ptp cannot not be enabled */
68 if (roc_nix_is_vf_or_sdp(nix) || roc_nix_is_lbk(nix)) {
69 plt_err("PTP cannot be enabled for VF/SDP/LBK");
76 if (dev->ptype_disable) {
77 plt_err("Ptype offload is disabled, it should be enabled");
81 if (dev->npc.switch_header_type == ROC_PRIV_FLAGS_HIGIG) {
82 plt_err("Both PTP and switch header cannot be enabled");
86 /* Allocating a iova address for tx tstamp */
87 ts = rte_eth_dma_zone_reserve(eth_dev, "cnxk_ts", 0, 128, 128, 0);
89 plt_err("Failed to allocate mem for tx tstamp addr");
93 tstamp->tx_tstamp_iova = ts->iova;
94 tstamp->tx_tstamp = ts->addr;
96 rc = rte_mbuf_dyn_rx_timestamp_register(&tstamp->tstamp_dynfield_offset,
97 &tstamp->rx_tstamp_dynflag);
99 plt_err("Failed to register Rx timestamp field/flag");
103 /* System time should be already on by default */
104 memset(&dev->systime_tc, 0, sizeof(struct rte_timecounter));
105 memset(&dev->rx_tstamp_tc, 0, sizeof(struct rte_timecounter));
106 memset(&dev->tx_tstamp_tc, 0, sizeof(struct rte_timecounter));
108 dev->systime_tc.cc_mask = CNXK_CYCLECOUNTER_MASK;
109 dev->rx_tstamp_tc.cc_mask = CNXK_CYCLECOUNTER_MASK;
110 dev->tx_tstamp_tc.cc_mask = CNXK_CYCLECOUNTER_MASK;
112 dev->rx_offloads |= DEV_RX_OFFLOAD_TIMESTAMP;
114 rc = roc_nix_ptp_rx_ena_dis(nix, true);
116 rc = roc_nix_ptp_tx_ena_dis(nix, true);
118 roc_nix_ptp_rx_ena_dis(nix, false);
123 rc = nix_recalc_mtu(eth_dev);
125 plt_err("Failed to set MTU size for ptp");
132 rte_eth_dma_zone_free(eth_dev, "cnxk_ts", 0);
133 dev->tstamp.tx_tstamp_iova = 0;
134 dev->tstamp.tx_tstamp = NULL;
139 cnxk_nix_timesync_disable(struct rte_eth_dev *eth_dev)
141 struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
142 uint64_t rx_offloads = DEV_RX_OFFLOAD_TIMESTAMP;
143 struct roc_nix *nix = &dev->nix;
146 /* If we are VF/SDP/LBK, ptp cannot not be disabled */
147 if (roc_nix_is_vf_or_sdp(nix) || roc_nix_is_lbk(nix))
153 dev->rx_offloads &= ~rx_offloads;
155 rc = roc_nix_ptp_rx_ena_dis(nix, false);
157 rc = roc_nix_ptp_tx_ena_dis(nix, false);
159 roc_nix_ptp_rx_ena_dis(nix, true);
164 rc = nix_recalc_mtu(eth_dev);
166 plt_err("Failed to set MTU size for ptp");