net/octeontx2: fix 32-bit build
[dpdk.git] / drivers / net / octeontx2 / otx2_ptp.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  */
4
5 #include <rte_ethdev_driver.h>
6
7 #include "otx2_ethdev.h"
8
9 #define PTP_FREQ_ADJUST (1 << 9)
10
11 static int
12 nix_read_raw_clock(struct otx2_eth_dev *dev, uint64_t *clock, uint64_t *tsc,
13                    uint8_t is_pmu)
14 {
15         struct otx2_mbox *mbox = dev->mbox;
16         struct ptp_req *req;
17         struct ptp_rsp *rsp;
18         int rc;
19
20         req = otx2_mbox_alloc_msg_ptp_op(mbox);
21         req->op = PTP_OP_GET_CLOCK;
22         req->is_pmu = is_pmu;
23         rc = otx2_mbox_process_msg(mbox, (void *)&rsp);
24         if (rc)
25                 goto fail;
26
27         if (clock)
28                 *clock = rsp->clk;
29         if (tsc)
30                 *tsc = rsp->tsc;
31
32 fail:
33         return rc;
34 }
35
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.
39  */
40 int
41 otx2_nix_raw_clock_tsc_conv(struct otx2_eth_dev *dev)
42 {
43         uint64_t ticks_base = 0, ticks = 0, tsc = 0, t_freq;
44         int rc, val;
45
46         /* Calculating the frequency at which PTP HI clock is running */
47         rc = nix_read_raw_clock(dev, &ticks_base, &tsc, false);
48         if (rc) {
49                 otx2_err("Failed to read the raw clock value: %d", rc);
50                 goto fail;
51         }
52
53         rte_delay_ms(100);
54
55         rc = nix_read_raw_clock(dev, &ticks, &tsc, false);
56         if (rc) {
57                 otx2_err("Failed to read the raw clock value: %d", rc);
58                 goto fail;
59         }
60
61         t_freq = (ticks - ticks_base) * 10;
62
63         /* Calculating the freq multiplier viz the ratio between the
64          * frequency at which PTP HI clock works and tsc clock runs
65          */
66         dev->clk_freq_mult =
67                 (double)pow(10, floor(log10(t_freq))) / rte_get_timer_hz();
68
69         val = false;
70 #ifdef RTE_ARM_EAL_RDTSC_USE_PMU
71         val = true;
72 #endif
73         rc = nix_read_raw_clock(dev, &ticks, &tsc, val);
74         if (rc) {
75                 otx2_err("Failed to read the raw clock value: %d", rc);
76                 goto fail;
77         }
78
79         /* Calculating delta between PTP HI clock and tsc */
80         dev->clk_delta = ((uint64_t)(ticks / dev->clk_freq_mult) - tsc);
81
82 fail:
83         return rc;
84 }
85
86 static void
87 nix_start_timecounters(struct rte_eth_dev *eth_dev)
88 {
89         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
90
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));
94
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;
98 }
99
100 static int
101 nix_ptp_config(struct rte_eth_dev *eth_dev, int en)
102 {
103         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
104         struct otx2_mbox *mbox = dev->mbox;
105         uint8_t rc = -EINVAL;
106
107         if (otx2_dev_is_vf(dev))
108                 return rc;
109
110         if (en) {
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);
114                 if (rc) {
115                         otx2_err("MBOX ptp tx conf enable failed: err %d", rc);
116                         return rc;
117                 }
118                 /* Enable time stamping of received PTP packets. */
119                 otx2_mbox_alloc_msg_cgx_ptp_rx_enable(mbox);
120         } else {
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);
124                 if (rc) {
125                         otx2_err("MBOX ptp tx conf disable failed: err %d", rc);
126                         return rc;
127                 }
128                 /* Disable time stamping of received PTP packets. */
129                 otx2_mbox_alloc_msg_cgx_ptp_rx_disable(mbox);
130         }
131
132         return otx2_mbox_process(mbox);
133 }
134
135 int
136 otx2_eth_dev_ptp_info_update(struct otx2_dev *dev, bool ptp_en)
137 {
138         struct otx2_eth_dev *otx2_dev = (struct otx2_eth_dev *)dev;
139         struct rte_eth_dev *eth_dev;
140         int i;
141
142         if (!dev)
143                 return -EINVAL;
144
145         eth_dev = otx2_dev->eth_dev;
146         if (!eth_dev)
147                 return -EINVAL;
148
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);
155         }
156         return 0;
157 }
158
159 int
160 otx2_nix_timesync_enable(struct rte_eth_dev *eth_dev)
161 {
162         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
163         int i, rc = 0;
164
165         if (otx2_ethdev_is_ptp_en(dev)) {
166                 otx2_info("PTP mode is already enabled ");
167                 return -EINVAL;
168         }
169
170         /* If we are VF, no further action can be taken */
171         if (otx2_dev_is_vf(dev))
172                 return -EINVAL;
173
174         if (!(dev->rx_offload_flags & NIX_RX_OFFLOAD_PTYPE_F)) {
175                 otx2_err("Ptype offload is disabled, it should be enabled");
176                 return -EINVAL;
177         }
178
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,
183                                       dev->node);
184         if (ts == NULL) {
185                 otx2_err("Failed to allocate mem for tx tstamp addr");
186                 return -ENOMEM;
187         }
188
189         dev->tstamp.tx_tstamp_iova = ts->iova;
190         dev->tstamp.tx_tstamp = ts->addr;
191
192         /* System time should be already on by default */
193         nix_start_timecounters(eth_dev);
194
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;
198
199         rc = nix_ptp_config(eth_dev, 1);
200         if (!rc) {
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);
204                 }
205
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);
209         }
210         return rc;
211 }
212
213 int
214 otx2_nix_timesync_disable(struct rte_eth_dev *eth_dev)
215 {
216         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
217         int i, rc = 0;
218
219         if (!otx2_ethdev_is_ptp_en(dev)) {
220                 otx2_nix_dbg("PTP mode is disabled");
221                 return -EINVAL;
222         }
223
224         /* If we are VF, nothing else can be done */
225         if (otx2_dev_is_vf(dev))
226                 return -EINVAL;
227
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;
231
232         rc = nix_ptp_config(eth_dev, 0);
233         if (!rc) {
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);
237                 }
238
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);
242         }
243         return rc;
244 }
245
246 int
247 otx2_nix_timesync_read_rx_timestamp(struct rte_eth_dev *eth_dev,
248                                     struct timespec *timestamp,
249                                     uint32_t __rte_unused flags)
250 {
251         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
252         struct otx2_timesync_info *tstamp = &dev->tstamp;
253         uint64_t ns;
254
255         if (!tstamp->rx_ready)
256                 return -EINVAL;
257
258         ns = rte_timecounter_update(&dev->rx_tstamp_tc, tstamp->rx_tstamp);
259         *timestamp = rte_ns_to_timespec(ns);
260         tstamp->rx_ready = 0;
261
262         otx2_nix_dbg("rx timestamp: %"PRIu64" sec: %"PRIu64" nsec %"PRIu64"",
263                      (uint64_t)tstamp->rx_tstamp, (uint64_t)timestamp->tv_sec,
264                      (uint64_t)timestamp->tv_nsec);
265
266         return 0;
267 }
268
269 int
270 otx2_nix_timesync_read_tx_timestamp(struct rte_eth_dev *eth_dev,
271                                     struct timespec *timestamp)
272 {
273         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
274         struct otx2_timesync_info *tstamp = &dev->tstamp;
275         uint64_t ns;
276
277         if (*tstamp->tx_tstamp == 0)
278                 return -EINVAL;
279
280         ns = rte_timecounter_update(&dev->tx_tstamp_tc, *tstamp->tx_tstamp);
281         *timestamp = rte_ns_to_timespec(ns);
282
283         otx2_nix_dbg("tx timestamp: %"PRIu64" sec: %"PRIu64" nsec %"PRIu64"",
284                      *tstamp->tx_tstamp, (uint64_t)timestamp->tv_sec,
285                      (uint64_t)timestamp->tv_nsec);
286
287         *tstamp->tx_tstamp = 0;
288         rte_wmb();
289
290         return 0;
291 }
292
293 int
294 otx2_nix_timesync_adjust_time(struct rte_eth_dev *eth_dev, int64_t delta)
295 {
296         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
297         struct otx2_mbox *mbox = dev->mbox;
298         struct ptp_req *req;
299         struct ptp_rsp *rsp;
300         int rc;
301
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;
307
308                 rc = otx2_mbox_process_msg(mbox, (void *)&rsp);
309                 if (rc)
310                         return rc;
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.
314                  */
315                 rc = otx2_nix_raw_clock_tsc_conv(dev);
316                 if (rc)
317                         otx2_err("Failed to calculate delta and freq mult");
318         }
319         dev->systime_tc.nsec += delta;
320         dev->rx_tstamp_tc.nsec += delta;
321         dev->tx_tstamp_tc.nsec += delta;
322
323         return 0;
324 }
325
326 int
327 otx2_nix_timesync_write_time(struct rte_eth_dev *eth_dev,
328                              const struct timespec *ts)
329 {
330         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
331         uint64_t ns;
332
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;
338
339         return 0;
340 }
341
342 int
343 otx2_nix_timesync_read_time(struct rte_eth_dev *eth_dev, struct timespec *ts)
344 {
345         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
346         struct otx2_mbox *mbox = dev->mbox;
347         struct ptp_req *req;
348         struct ptp_rsp *rsp;
349         uint64_t ns;
350         int rc;
351
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);
355         if (rc)
356                 return rc;
357
358         ns = rte_timecounter_update(&dev->systime_tc, rsp->clk);
359         *ts = rte_ns_to_timespec(ns);
360
361         otx2_nix_dbg("PTP time read: %"PRIu64" .%09"PRIu64"",
362                      (uint64_t)ts->tv_sec, (uint64_t)ts->tv_nsec);
363
364         return 0;
365 }
366
367
368 int
369 otx2_nix_read_clock(struct rte_eth_dev *eth_dev, uint64_t *clock)
370 {
371         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
372
373         /* This API returns the raw PTP HI clock value. Since LFs doesn't
374          * have direct access to PTP registers and it requires mbox msg
375          * to AF for this value. In fastpath reading this value for every
376          * packet (which involes mbox call) becomes very expensive, hence
377          * we should be able to derive PTP HI clock value from tsc by
378          * using freq_mult and clk_delta calculated during configure stage.
379          */
380         *clock = (rte_get_tsc_cycles() + dev->clk_delta) * dev->clk_freq_mult;
381
382         return 0;
383 }