net/octeontx2: support read clock
[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 = 0;
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 = otx2_dev->eth_dev;
140         int i;
141
142         otx2_dev->ptp_en = ptp_en;
143         for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
144                 struct otx2_eth_rxq *rxq = eth_dev->data->rx_queues[i];
145                 rxq->mbuf_initializer =
146                         otx2_nix_rxq_mbuf_setup(otx2_dev,
147                                                 eth_dev->data->port_id);
148         }
149         return 0;
150 }
151
152 int
153 otx2_nix_timesync_enable(struct rte_eth_dev *eth_dev)
154 {
155         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
156         int i, rc = 0;
157
158         if (otx2_ethdev_is_ptp_en(dev)) {
159                 otx2_info("PTP mode is already enabled ");
160                 return -EINVAL;
161         }
162
163         /* If we are VF, no further action can be taken */
164         if (otx2_dev_is_vf(dev))
165                 return -EINVAL;
166
167         if (!(dev->rx_offload_flags & NIX_RX_OFFLOAD_PTYPE_F)) {
168                 otx2_err("Ptype offload is disabled, it should be enabled");
169                 return -EINVAL;
170         }
171
172         /* Allocating a iova address for tx tstamp */
173         const struct rte_memzone *ts;
174         ts = rte_eth_dma_zone_reserve(eth_dev, "otx2_ts",
175                                       0, OTX2_ALIGN, OTX2_ALIGN,
176                                       dev->node);
177         if (ts == NULL)
178                 otx2_err("Failed to allocate mem for tx tstamp addr");
179
180         dev->tstamp.tx_tstamp_iova = ts->iova;
181         dev->tstamp.tx_tstamp = ts->addr;
182
183         /* System time should be already on by default */
184         nix_start_timecounters(eth_dev);
185
186         dev->rx_offloads |= DEV_RX_OFFLOAD_TIMESTAMP;
187         dev->rx_offload_flags |= NIX_RX_OFFLOAD_TSTAMP_F;
188         dev->tx_offload_flags |= NIX_TX_OFFLOAD_TSTAMP_F;
189
190         rc = nix_ptp_config(eth_dev, 1);
191         if (!rc) {
192                 for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
193                         struct otx2_eth_txq *txq = eth_dev->data->tx_queues[i];
194                         otx2_nix_form_default_desc(txq);
195                 }
196
197                 /* Setting up the function pointers as per new offload flags */
198                 otx2_eth_set_rx_function(eth_dev);
199                 otx2_eth_set_tx_function(eth_dev);
200         }
201         return rc;
202 }
203
204 int
205 otx2_nix_timesync_disable(struct rte_eth_dev *eth_dev)
206 {
207         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
208         int i, rc = 0;
209
210         if (!otx2_ethdev_is_ptp_en(dev)) {
211                 otx2_nix_dbg("PTP mode is disabled");
212                 return -EINVAL;
213         }
214
215         /* If we are VF, nothing else can be done */
216         if (otx2_dev_is_vf(dev))
217                 return -EINVAL;
218
219         dev->rx_offloads &= ~DEV_RX_OFFLOAD_TIMESTAMP;
220         dev->rx_offload_flags &= ~NIX_RX_OFFLOAD_TSTAMP_F;
221         dev->tx_offload_flags &= ~NIX_TX_OFFLOAD_TSTAMP_F;
222
223         rc = nix_ptp_config(eth_dev, 0);
224         if (!rc) {
225                 for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
226                         struct otx2_eth_txq *txq = eth_dev->data->tx_queues[i];
227                         otx2_nix_form_default_desc(txq);
228                 }
229
230                 /* Setting up the function pointers as per new offload flags */
231                 otx2_eth_set_rx_function(eth_dev);
232                 otx2_eth_set_tx_function(eth_dev);
233         }
234         return rc;
235 }
236
237 int
238 otx2_nix_timesync_read_rx_timestamp(struct rte_eth_dev *eth_dev,
239                                     struct timespec *timestamp,
240                                     uint32_t __rte_unused flags)
241 {
242         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
243         struct otx2_timesync_info *tstamp = &dev->tstamp;
244         uint64_t ns;
245
246         if (!tstamp->rx_ready)
247                 return -EINVAL;
248
249         ns = rte_timecounter_update(&dev->rx_tstamp_tc, tstamp->rx_tstamp);
250         *timestamp = rte_ns_to_timespec(ns);
251         tstamp->rx_ready = 0;
252
253         otx2_nix_dbg("rx timestamp: %llu sec: %lu nsec %lu",
254                      (unsigned long long)tstamp->rx_tstamp, timestamp->tv_sec,
255                      timestamp->tv_nsec);
256
257         return 0;
258 }
259
260 int
261 otx2_nix_timesync_read_tx_timestamp(struct rte_eth_dev *eth_dev,
262                                     struct timespec *timestamp)
263 {
264         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
265         struct otx2_timesync_info *tstamp = &dev->tstamp;
266         uint64_t ns;
267
268         if (*tstamp->tx_tstamp == 0)
269                 return -EINVAL;
270
271         ns = rte_timecounter_update(&dev->tx_tstamp_tc, *tstamp->tx_tstamp);
272         *timestamp = rte_ns_to_timespec(ns);
273
274         otx2_nix_dbg("tx timestamp: %llu sec: %lu nsec %lu",
275                      *(unsigned long long *)tstamp->tx_tstamp,
276                      timestamp->tv_sec, timestamp->tv_nsec);
277
278         *tstamp->tx_tstamp = 0;
279         rte_wmb();
280
281         return 0;
282 }
283
284 int
285 otx2_nix_timesync_adjust_time(struct rte_eth_dev *eth_dev, int64_t delta)
286 {
287         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
288         struct otx2_mbox *mbox = dev->mbox;
289         struct ptp_req *req;
290         struct ptp_rsp *rsp;
291         int rc;
292
293         /* Adjust the frequent to make tics increments in 10^9 tics per sec */
294         if (delta < PTP_FREQ_ADJUST && delta > -PTP_FREQ_ADJUST) {
295                 req = otx2_mbox_alloc_msg_ptp_op(mbox);
296                 req->op = PTP_OP_ADJFINE;
297                 req->scaled_ppm = delta;
298
299                 rc = otx2_mbox_process_msg(mbox, (void *)&rsp);
300                 if (rc)
301                         return rc;
302                 /* Since the frequency of PTP comp register is tuned, delta and
303                  * freq mult calculation for deriving PTP_HI from timestamp
304                  * counter should be done again.
305                  */
306                 rc = otx2_nix_raw_clock_tsc_conv(dev);
307                 if (rc)
308                         otx2_err("Failed to calculate delta and freq mult");
309         }
310         dev->systime_tc.nsec += delta;
311         dev->rx_tstamp_tc.nsec += delta;
312         dev->tx_tstamp_tc.nsec += delta;
313
314         return 0;
315 }
316
317 int
318 otx2_nix_timesync_write_time(struct rte_eth_dev *eth_dev,
319                              const struct timespec *ts)
320 {
321         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
322         uint64_t ns;
323
324         ns = rte_timespec_to_ns(ts);
325         /* Set the time counters to a new value. */
326         dev->systime_tc.nsec = ns;
327         dev->rx_tstamp_tc.nsec = ns;
328         dev->tx_tstamp_tc.nsec = ns;
329
330         return 0;
331 }
332
333 int
334 otx2_nix_timesync_read_time(struct rte_eth_dev *eth_dev, struct timespec *ts)
335 {
336         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
337         struct otx2_mbox *mbox = dev->mbox;
338         struct ptp_req *req;
339         struct ptp_rsp *rsp;
340         uint64_t ns;
341         int rc;
342
343         req = otx2_mbox_alloc_msg_ptp_op(mbox);
344         req->op = PTP_OP_GET_CLOCK;
345         rc = otx2_mbox_process_msg(mbox, (void *)&rsp);
346         if (rc)
347                 return rc;
348
349         ns = rte_timecounter_update(&dev->systime_tc, rsp->clk);
350         *ts = rte_ns_to_timespec(ns);
351
352         otx2_nix_dbg("PTP time read: %ld.%09ld", ts->tv_sec, ts->tv_nsec);
353
354         return 0;
355 }
356
357
358 int
359 otx2_nix_read_clock(struct rte_eth_dev *eth_dev, uint64_t *clock)
360 {
361         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
362
363         /* This API returns the raw PTP HI clock value. Since LFs doesn't
364          * have direct access to PTP registers and it requires mbox msg
365          * to AF for this value. In fastpath reading this value for every
366          * packet (which involes mbox call) becomes very expensive, hence
367          * we should be able to derive PTP HI clock value from tsc by
368          * using freq_mult and clk_delta calculated during configure stage.
369          */
370         *clock = (rte_get_tsc_cycles() + dev->clk_delta) * dev->clk_freq_mult;
371
372         return 0;
373 }