1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2019 Marvell International Ltd.
5 #include <rte_ethdev_driver.h>
7 #include "otx2_ethdev.h"
9 #define PTP_FREQ_ADJUST (1 << 9)
12 nix_read_raw_clock(struct otx2_eth_dev *dev, uint64_t *clock, uint64_t *tsc,
15 struct otx2_mbox *mbox = dev->mbox;
20 req = otx2_mbox_alloc_msg_ptp_op(mbox);
21 req->op = PTP_OP_GET_CLOCK;
23 rc = otx2_mbox_process_msg(mbox, (void *)&rsp);
36 /* This function calculates two parameters "clk_freq_mult" and
37 * "clk_delta" which is useful in deriving PTP HI clock from
38 * timestamp counter (tsc) value.
41 otx2_nix_raw_clock_tsc_conv(struct otx2_eth_dev *dev)
43 uint64_t ticks_base = 0, ticks = 0, tsc = 0, t_freq;
46 /* Calculating the frequency at which PTP HI clock is running */
47 rc = nix_read_raw_clock(dev, &ticks_base, &tsc, false);
49 otx2_err("Failed to read the raw clock value: %d", rc);
55 rc = nix_read_raw_clock(dev, &ticks, &tsc, false);
57 otx2_err("Failed to read the raw clock value: %d", rc);
61 t_freq = (ticks - ticks_base) * 10;
63 /* Calculating the freq multiplier viz the ratio between the
64 * frequency at which PTP HI clock works and tsc clock runs
67 (double)pow(10, floor(log10(t_freq))) / rte_get_timer_hz();
70 #ifdef RTE_ARM_EAL_RDTSC_USE_PMU
73 rc = nix_read_raw_clock(dev, &ticks, &tsc, val);
75 otx2_err("Failed to read the raw clock value: %d", rc);
79 /* Calculating delta between PTP HI clock and tsc */
80 dev->clk_delta = ((uint64_t)(ticks / dev->clk_freq_mult) - tsc);
87 nix_start_timecounters(struct rte_eth_dev *eth_dev)
89 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
91 memset(&dev->systime_tc, 0, sizeof(struct rte_timecounter));
92 memset(&dev->rx_tstamp_tc, 0, sizeof(struct rte_timecounter));
93 memset(&dev->tx_tstamp_tc, 0, sizeof(struct rte_timecounter));
95 dev->systime_tc.cc_mask = OTX2_CYCLECOUNTER_MASK;
96 dev->rx_tstamp_tc.cc_mask = OTX2_CYCLECOUNTER_MASK;
97 dev->tx_tstamp_tc.cc_mask = OTX2_CYCLECOUNTER_MASK;
101 nix_ptp_config(struct rte_eth_dev *eth_dev, int en)
103 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
104 struct otx2_mbox *mbox = dev->mbox;
105 uint8_t rc = -EINVAL;
107 if (otx2_dev_is_vf(dev))
111 /* Enable time stamping of sent PTP packets. */
112 otx2_mbox_alloc_msg_nix_lf_ptp_tx_enable(mbox);
113 rc = otx2_mbox_process(mbox);
115 otx2_err("MBOX ptp tx conf enable failed: err %d", rc);
118 /* Enable time stamping of received PTP packets. */
119 otx2_mbox_alloc_msg_cgx_ptp_rx_enable(mbox);
121 /* Disable time stamping of sent PTP packets. */
122 otx2_mbox_alloc_msg_nix_lf_ptp_tx_disable(mbox);
123 rc = otx2_mbox_process(mbox);
125 otx2_err("MBOX ptp tx conf disable failed: err %d", rc);
128 /* Disable time stamping of received PTP packets. */
129 otx2_mbox_alloc_msg_cgx_ptp_rx_disable(mbox);
132 return otx2_mbox_process(mbox);
136 otx2_eth_dev_ptp_info_update(struct otx2_dev *dev, bool ptp_en)
138 struct otx2_eth_dev *otx2_dev = (struct otx2_eth_dev *)dev;
139 struct rte_eth_dev *eth_dev;
145 eth_dev = otx2_dev->eth_dev;
149 otx2_dev->ptp_en = ptp_en;
150 for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
151 struct otx2_eth_rxq *rxq = eth_dev->data->rx_queues[i];
152 rxq->mbuf_initializer =
153 otx2_nix_rxq_mbuf_setup(otx2_dev,
154 eth_dev->data->port_id);
160 otx2_nix_timesync_enable(struct rte_eth_dev *eth_dev)
162 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
165 if (otx2_ethdev_is_ptp_en(dev)) {
166 otx2_info("PTP mode is already enabled ");
170 /* If we are VF, no further action can be taken */
171 if (otx2_dev_is_vf(dev))
174 if (!(dev->rx_offload_flags & NIX_RX_OFFLOAD_PTYPE_F)) {
175 otx2_err("Ptype offload is disabled, it should be enabled");
179 /* Allocating a iova address for tx tstamp */
180 const struct rte_memzone *ts;
181 ts = rte_eth_dma_zone_reserve(eth_dev, "otx2_ts",
182 0, OTX2_ALIGN, OTX2_ALIGN,
185 otx2_err("Failed to allocate mem for tx tstamp addr");
189 dev->tstamp.tx_tstamp_iova = ts->iova;
190 dev->tstamp.tx_tstamp = ts->addr;
192 /* System time should be already on by default */
193 nix_start_timecounters(eth_dev);
195 dev->rx_offloads |= DEV_RX_OFFLOAD_TIMESTAMP;
196 dev->rx_offload_flags |= NIX_RX_OFFLOAD_TSTAMP_F;
197 dev->tx_offload_flags |= NIX_TX_OFFLOAD_TSTAMP_F;
199 rc = nix_ptp_config(eth_dev, 1);
201 for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
202 struct otx2_eth_txq *txq = eth_dev->data->tx_queues[i];
203 otx2_nix_form_default_desc(txq);
206 /* Setting up the function pointers as per new offload flags */
207 otx2_eth_set_rx_function(eth_dev);
208 otx2_eth_set_tx_function(eth_dev);
214 otx2_nix_timesync_disable(struct rte_eth_dev *eth_dev)
216 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
219 if (!otx2_ethdev_is_ptp_en(dev)) {
220 otx2_nix_dbg("PTP mode is disabled");
224 /* If we are VF, nothing else can be done */
225 if (otx2_dev_is_vf(dev))
228 dev->rx_offloads &= ~DEV_RX_OFFLOAD_TIMESTAMP;
229 dev->rx_offload_flags &= ~NIX_RX_OFFLOAD_TSTAMP_F;
230 dev->tx_offload_flags &= ~NIX_TX_OFFLOAD_TSTAMP_F;
232 rc = nix_ptp_config(eth_dev, 0);
234 for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
235 struct otx2_eth_txq *txq = eth_dev->data->tx_queues[i];
236 otx2_nix_form_default_desc(txq);
239 /* Setting up the function pointers as per new offload flags */
240 otx2_eth_set_rx_function(eth_dev);
241 otx2_eth_set_tx_function(eth_dev);
247 otx2_nix_timesync_read_rx_timestamp(struct rte_eth_dev *eth_dev,
248 struct timespec *timestamp,
249 uint32_t __rte_unused flags)
251 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
252 struct otx2_timesync_info *tstamp = &dev->tstamp;
255 if (!tstamp->rx_ready)
258 ns = rte_timecounter_update(&dev->rx_tstamp_tc, tstamp->rx_tstamp);
259 *timestamp = rte_ns_to_timespec(ns);
260 tstamp->rx_ready = 0;
262 otx2_nix_dbg("rx timestamp: %llu sec: %lu nsec %lu",
263 (unsigned long long)tstamp->rx_tstamp, timestamp->tv_sec,
270 otx2_nix_timesync_read_tx_timestamp(struct rte_eth_dev *eth_dev,
271 struct timespec *timestamp)
273 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
274 struct otx2_timesync_info *tstamp = &dev->tstamp;
277 if (*tstamp->tx_tstamp == 0)
280 ns = rte_timecounter_update(&dev->tx_tstamp_tc, *tstamp->tx_tstamp);
281 *timestamp = rte_ns_to_timespec(ns);
283 otx2_nix_dbg("tx timestamp: %llu sec: %lu nsec %lu",
284 *(unsigned long long *)tstamp->tx_tstamp,
285 timestamp->tv_sec, timestamp->tv_nsec);
287 *tstamp->tx_tstamp = 0;
294 otx2_nix_timesync_adjust_time(struct rte_eth_dev *eth_dev, int64_t delta)
296 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
297 struct otx2_mbox *mbox = dev->mbox;
302 /* Adjust the frequent to make tics increments in 10^9 tics per sec */
303 if (delta < PTP_FREQ_ADJUST && delta > -PTP_FREQ_ADJUST) {
304 req = otx2_mbox_alloc_msg_ptp_op(mbox);
305 req->op = PTP_OP_ADJFINE;
306 req->scaled_ppm = delta;
308 rc = otx2_mbox_process_msg(mbox, (void *)&rsp);
311 /* Since the frequency of PTP comp register is tuned, delta and
312 * freq mult calculation for deriving PTP_HI from timestamp
313 * counter should be done again.
315 rc = otx2_nix_raw_clock_tsc_conv(dev);
317 otx2_err("Failed to calculate delta and freq mult");
319 dev->systime_tc.nsec += delta;
320 dev->rx_tstamp_tc.nsec += delta;
321 dev->tx_tstamp_tc.nsec += delta;
327 otx2_nix_timesync_write_time(struct rte_eth_dev *eth_dev,
328 const struct timespec *ts)
330 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
333 ns = rte_timespec_to_ns(ts);
334 /* Set the time counters to a new value. */
335 dev->systime_tc.nsec = ns;
336 dev->rx_tstamp_tc.nsec = ns;
337 dev->tx_tstamp_tc.nsec = ns;
343 otx2_nix_timesync_read_time(struct rte_eth_dev *eth_dev, struct timespec *ts)
345 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
346 struct otx2_mbox *mbox = dev->mbox;
352 req = otx2_mbox_alloc_msg_ptp_op(mbox);
353 req->op = PTP_OP_GET_CLOCK;
354 rc = otx2_mbox_process_msg(mbox, (void *)&rsp);
358 ns = rte_timecounter_update(&dev->systime_tc, rsp->clk);
359 *ts = rte_ns_to_timespec(ns);
361 otx2_nix_dbg("PTP time read: %ld.%09ld", ts->tv_sec, ts->tv_nsec);
368 otx2_nix_read_clock(struct rte_eth_dev *eth_dev, uint64_t *clock)
370 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
372 /* This API returns the raw PTP HI clock value. Since LFs doesn't
373 * have direct access to PTP registers and it requires mbox msg
374 * to AF for this value. In fastpath reading this value for every
375 * packet (which involes mbox call) becomes very expensive, hence
376 * we should be able to derive PTP HI clock value from tsc by
377 * using freq_mult and clk_delta calculated during configure stage.
379 *clock = (rte_get_tsc_cycles() + dev->clk_delta) * dev->clk_freq_mult;