1
2
3
4
5#include <ethdev_driver.h>
6
7#include "otx2_ethdev.h"
8
9#define PTP_FREQ_ADJUST (1 << 9)
10
11
12void
13otx2_nix_ptp_enable_vf(struct rte_eth_dev *eth_dev)
14{
15 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
16
17 if (otx2_nix_recalc_mtu(eth_dev))
18 otx2_err("Failed to set MTU size for ptp");
19
20 dev->scalar_ena = true;
21 dev->rx_offload_flags |= NIX_RX_OFFLOAD_TSTAMP_F;
22
23
24 otx2_eth_set_rx_function(eth_dev);
25 otx2_eth_set_tx_function(eth_dev);
26}
27
28static uint16_t
29nix_eth_ptp_vf_burst(void *queue, struct rte_mbuf **mbufs, uint16_t pkts)
30{
31 struct otx2_eth_rxq *rxq = queue;
32 struct rte_eth_dev *eth_dev;
33
34 RTE_SET_USED(mbufs);
35 RTE_SET_USED(pkts);
36
37 eth_dev = rxq->eth_dev;
38 otx2_nix_ptp_enable_vf(eth_dev);
39
40 return 0;
41}
42
43static int
44nix_read_raw_clock(struct otx2_eth_dev *dev, uint64_t *clock, uint64_t *tsc,
45 uint8_t is_pmu)
46{
47 struct otx2_mbox *mbox = dev->mbox;
48 struct ptp_req *req;
49 struct ptp_rsp *rsp;
50 int rc;
51
52 req = otx2_mbox_alloc_msg_ptp_op(mbox);
53 req->op = PTP_OP_GET_CLOCK;
54 req->is_pmu = is_pmu;
55 rc = otx2_mbox_process_msg(mbox, (void *)&rsp);
56 if (rc)
57 goto fail;
58
59 if (clock)
60 *clock = rsp->clk;
61 if (tsc)
62 *tsc = rsp->tsc;
63
64fail:
65 return rc;
66}
67
68
69
70
71
72int
73otx2_nix_raw_clock_tsc_conv(struct otx2_eth_dev *dev)
74{
75 uint64_t ticks_base = 0, ticks = 0, tsc = 0, t_freq;
76 int rc, val;
77
78
79 rc = nix_read_raw_clock(dev, &ticks_base, &tsc, false);
80 if (rc) {
81 otx2_err("Failed to read the raw clock value: %d", rc);
82 goto fail;
83 }
84
85 rte_delay_ms(100);
86
87 rc = nix_read_raw_clock(dev, &ticks, &tsc, false);
88 if (rc) {
89 otx2_err("Failed to read the raw clock value: %d", rc);
90 goto fail;
91 }
92
93 t_freq = (ticks - ticks_base) * 10;
94
95
96
97
98 dev->clk_freq_mult =
99 (double)pow(10, floor(log10(t_freq))) / rte_get_timer_hz();
100
101 val = false;
102#ifdef RTE_ARM_EAL_RDTSC_USE_PMU
103 val = true;
104#endif
105 rc = nix_read_raw_clock(dev, &ticks, &tsc, val);
106 if (rc) {
107 otx2_err("Failed to read the raw clock value: %d", rc);
108 goto fail;
109 }
110
111
112 dev->clk_delta = ((uint64_t)(ticks / dev->clk_freq_mult) - tsc);
113
114fail:
115 return rc;
116}
117
118static void
119nix_start_timecounters(struct rte_eth_dev *eth_dev)
120{
121 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
122
123 memset(&dev->systime_tc, 0, sizeof(struct rte_timecounter));
124 memset(&dev->rx_tstamp_tc, 0, sizeof(struct rte_timecounter));
125 memset(&dev->tx_tstamp_tc, 0, sizeof(struct rte_timecounter));
126
127 dev->systime_tc.cc_mask = OTX2_CYCLECOUNTER_MASK;
128 dev->rx_tstamp_tc.cc_mask = OTX2_CYCLECOUNTER_MASK;
129 dev->tx_tstamp_tc.cc_mask = OTX2_CYCLECOUNTER_MASK;
130}
131
132static int
133nix_ptp_config(struct rte_eth_dev *eth_dev, int en)
134{
135 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
136 struct otx2_mbox *mbox = dev->mbox;
137 uint8_t rc = -EINVAL;
138
139 if (otx2_dev_is_vf_or_sdp(dev) || otx2_dev_is_lbk(dev))
140 return rc;
141
142 if (en) {
143
144 otx2_mbox_alloc_msg_nix_lf_ptp_tx_enable(mbox);
145 rc = otx2_mbox_process(mbox);
146 if (rc) {
147 otx2_err("MBOX ptp tx conf enable failed: err %d", rc);
148 return rc;
149 }
150
151 otx2_mbox_alloc_msg_cgx_ptp_rx_enable(mbox);
152 } else {
153
154 otx2_mbox_alloc_msg_nix_lf_ptp_tx_disable(mbox);
155 rc = otx2_mbox_process(mbox);
156 if (rc) {
157 otx2_err("MBOX ptp tx conf disable failed: err %d", rc);
158 return rc;
159 }
160
161 otx2_mbox_alloc_msg_cgx_ptp_rx_disable(mbox);
162 }
163
164 return otx2_mbox_process(mbox);
165}
166
167int
168otx2_eth_dev_ptp_info_update(struct otx2_dev *dev, bool ptp_en)
169{
170 struct otx2_eth_dev *otx2_dev = (struct otx2_eth_dev *)dev;
171 struct rte_eth_dev *eth_dev;
172 int i;
173
174 if (!dev)
175 return -EINVAL;
176
177 eth_dev = otx2_dev->eth_dev;
178 if (!eth_dev)
179 return -EINVAL;
180
181 otx2_dev->ptp_en = ptp_en;
182 for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
183 struct otx2_eth_rxq *rxq = eth_dev->data->rx_queues[i];
184 rxq->mbuf_initializer =
185 otx2_nix_rxq_mbuf_setup(otx2_dev,
186 eth_dev->data->port_id);
187 }
188 if (otx2_dev_is_vf(otx2_dev) && !(otx2_dev_is_sdp(otx2_dev)) &&
189 !(otx2_dev_is_lbk(otx2_dev))) {
190
191
192
193
194
195 eth_dev->rx_pkt_burst = nix_eth_ptp_vf_burst;
196 rte_mb();
197 }
198
199 return 0;
200}
201
202int
203otx2_nix_timesync_enable(struct rte_eth_dev *eth_dev)
204{
205 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
206 int i, rc = 0;
207
208
209 if (otx2_dev_is_vf_or_sdp(dev) || otx2_dev_is_lbk(dev)) {
210 otx2_info("PTP cannot be enabled in case of VF/SDP/LBK");
211 return -EINVAL;
212 }
213
214 if (otx2_ethdev_is_ptp_en(dev)) {
215 otx2_info("PTP mode is already enabled");
216 return -EINVAL;
217 }
218
219 if (!(dev->rx_offload_flags & NIX_RX_OFFLOAD_PTYPE_F)) {
220 otx2_err("Ptype offload is disabled, it should be enabled");
221 return -EINVAL;
222 }
223
224 if (dev->npc_flow.switch_header_type == OTX2_PRIV_FLAGS_HIGIG) {
225 otx2_err("Both PTP and switch header enabled");
226 return -EINVAL;
227 }
228
229
230 const struct rte_memzone *ts;
231 ts = rte_eth_dma_zone_reserve(eth_dev, "otx2_ts",
232 0, OTX2_ALIGN, OTX2_ALIGN,
233 dev->node);
234 if (ts == NULL) {
235 otx2_err("Failed to allocate mem for tx tstamp addr");
236 return -ENOMEM;
237 }
238
239 dev->tstamp.tx_tstamp_iova = ts->iova;
240 dev->tstamp.tx_tstamp = ts->addr;
241
242 rc = rte_mbuf_dyn_rx_timestamp_register(
243 &dev->tstamp.tstamp_dynfield_offset,
244 &dev->tstamp.rx_tstamp_dynflag);
245 if (rc != 0) {
246 otx2_err("Failed to register Rx timestamp field/flag");
247 return -rte_errno;
248 }
249
250
251 nix_start_timecounters(eth_dev);
252
253 dev->rx_offloads |= DEV_RX_OFFLOAD_TIMESTAMP;
254 dev->rx_offload_flags |= NIX_RX_OFFLOAD_TSTAMP_F;
255 dev->tx_offload_flags |= NIX_TX_OFFLOAD_TSTAMP_F;
256
257 rc = nix_ptp_config(eth_dev, 1);
258 if (!rc) {
259 for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
260 struct otx2_eth_txq *txq = eth_dev->data->tx_queues[i];
261 otx2_nix_form_default_desc(txq);
262 }
263
264
265 otx2_eth_set_rx_function(eth_dev);
266 otx2_eth_set_tx_function(eth_dev);
267 }
268
269 rc = otx2_nix_recalc_mtu(eth_dev);
270 if (rc)
271 otx2_err("Failed to set MTU size for ptp");
272
273 return rc;
274}
275
276int
277otx2_nix_timesync_disable(struct rte_eth_dev *eth_dev)
278{
279 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
280 int i, rc = 0;
281
282 if (!otx2_ethdev_is_ptp_en(dev)) {
283 otx2_nix_dbg("PTP mode is disabled");
284 return -EINVAL;
285 }
286
287 if (otx2_dev_is_vf_or_sdp(dev) || otx2_dev_is_lbk(dev))
288 return -EINVAL;
289
290 dev->rx_offloads &= ~DEV_RX_OFFLOAD_TIMESTAMP;
291 dev->rx_offload_flags &= ~NIX_RX_OFFLOAD_TSTAMP_F;
292 dev->tx_offload_flags &= ~NIX_TX_OFFLOAD_TSTAMP_F;
293
294 rc = nix_ptp_config(eth_dev, 0);
295 if (!rc) {
296 for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
297 struct otx2_eth_txq *txq = eth_dev->data->tx_queues[i];
298 otx2_nix_form_default_desc(txq);
299 }
300
301
302 otx2_eth_set_rx_function(eth_dev);
303 otx2_eth_set_tx_function(eth_dev);
304 }
305
306 rc = otx2_nix_recalc_mtu(eth_dev);
307 if (rc)
308 otx2_err("Failed to set MTU size for ptp");
309
310 return rc;
311}
312
313int
314otx2_nix_timesync_read_rx_timestamp(struct rte_eth_dev *eth_dev,
315 struct timespec *timestamp,
316 uint32_t __rte_unused flags)
317{
318 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
319 struct otx2_timesync_info *tstamp = &dev->tstamp;
320 uint64_t ns;
321
322 if (!tstamp->rx_ready)
323 return -EINVAL;
324
325 ns = rte_timecounter_update(&dev->rx_tstamp_tc, tstamp->rx_tstamp);
326 *timestamp = rte_ns_to_timespec(ns);
327 tstamp->rx_ready = 0;
328
329 otx2_nix_dbg("rx timestamp: %"PRIu64" sec: %"PRIu64" nsec %"PRIu64"",
330 (uint64_t)tstamp->rx_tstamp, (uint64_t)timestamp->tv_sec,
331 (uint64_t)timestamp->tv_nsec);
332
333 return 0;
334}
335
336int
337otx2_nix_timesync_read_tx_timestamp(struct rte_eth_dev *eth_dev,
338 struct timespec *timestamp)
339{
340 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
341 struct otx2_timesync_info *tstamp = &dev->tstamp;
342 uint64_t ns;
343
344 if (*tstamp->tx_tstamp == 0)
345 return -EINVAL;
346
347 ns = rte_timecounter_update(&dev->tx_tstamp_tc, *tstamp->tx_tstamp);
348 *timestamp = rte_ns_to_timespec(ns);
349
350 otx2_nix_dbg("tx timestamp: %"PRIu64" sec: %"PRIu64" nsec %"PRIu64"",
351 *tstamp->tx_tstamp, (uint64_t)timestamp->tv_sec,
352 (uint64_t)timestamp->tv_nsec);
353
354 *tstamp->tx_tstamp = 0;
355 rte_wmb();
356
357 return 0;
358}
359
360int
361otx2_nix_timesync_adjust_time(struct rte_eth_dev *eth_dev, int64_t delta)
362{
363 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
364 struct otx2_mbox *mbox = dev->mbox;
365 struct ptp_req *req;
366 struct ptp_rsp *rsp;
367 int rc;
368
369
370 if (delta < PTP_FREQ_ADJUST && delta > -PTP_FREQ_ADJUST) {
371 req = otx2_mbox_alloc_msg_ptp_op(mbox);
372 req->op = PTP_OP_ADJFINE;
373 req->scaled_ppm = delta;
374
375 rc = otx2_mbox_process_msg(mbox, (void *)&rsp);
376 if (rc)
377 return rc;
378
379
380
381
382 rc = otx2_nix_raw_clock_tsc_conv(dev);
383 if (rc)
384 otx2_err("Failed to calculate delta and freq mult");
385 }
386 dev->systime_tc.nsec += delta;
387 dev->rx_tstamp_tc.nsec += delta;
388 dev->tx_tstamp_tc.nsec += delta;
389
390 return 0;
391}
392
393int
394otx2_nix_timesync_write_time(struct rte_eth_dev *eth_dev,
395 const struct timespec *ts)
396{
397 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
398 uint64_t ns;
399
400 ns = rte_timespec_to_ns(ts);
401
402 dev->systime_tc.nsec = ns;
403 dev->rx_tstamp_tc.nsec = ns;
404 dev->tx_tstamp_tc.nsec = ns;
405
406 return 0;
407}
408
409int
410otx2_nix_timesync_read_time(struct rte_eth_dev *eth_dev, struct timespec *ts)
411{
412 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
413 struct otx2_mbox *mbox = dev->mbox;
414 struct ptp_req *req;
415 struct ptp_rsp *rsp;
416 uint64_t ns;
417 int rc;
418
419 req = otx2_mbox_alloc_msg_ptp_op(mbox);
420 req->op = PTP_OP_GET_CLOCK;
421 rc = otx2_mbox_process_msg(mbox, (void *)&rsp);
422 if (rc)
423 return rc;
424
425 ns = rte_timecounter_update(&dev->systime_tc, rsp->clk);
426 *ts = rte_ns_to_timespec(ns);
427
428 otx2_nix_dbg("PTP time read: %"PRIu64" .%09"PRIu64"",
429 (uint64_t)ts->tv_sec, (uint64_t)ts->tv_nsec);
430
431 return 0;
432}
433
434
435int
436otx2_nix_read_clock(struct rte_eth_dev *eth_dev, uint64_t *clock)
437{
438 struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
439
440
441
442
443
444
445
446
447 *clock = (rte_get_tsc_cycles() + dev->clk_delta) * dev->clk_freq_mult;
448
449 return 0;
450}
451