1// SPDX-License-Identifier: GPL-2.0
2/* Marvell RVU Ethernet driver
3 *
4 * Copyright (C) 2020 Marvell.
5 *
6 */
7
8#include <linux/module.h>
9
10#include "otx2_common.h"
11#include "otx2_ptp.h"
12
13static bool is_tstmp_atomic_update_supported(struct otx2_ptp *ptp)
14{
15 struct ptp_get_cap_rsp *rsp;
16 struct msg_req *req;
17 int err;
18
19 if (!ptp->nic)
20 return false;
21
22 mutex_lock(&ptp->nic->mbox.lock);
23 req = otx2_mbox_alloc_msg_ptp_get_cap(mbox: &ptp->nic->mbox);
24 if (!req) {
25 mutex_unlock(lock: &ptp->nic->mbox.lock);
26 return false;
27 }
28
29 err = otx2_sync_mbox_msg(mbox: &ptp->nic->mbox);
30 if (err) {
31 mutex_unlock(lock: &ptp->nic->mbox.lock);
32 return false;
33 }
34 rsp = (struct ptp_get_cap_rsp *)otx2_mbox_get_rsp(mbox: &ptp->nic->mbox.mbox, devid: 0,
35 msg: &req->hdr);
36 mutex_unlock(lock: &ptp->nic->mbox.lock);
37
38 if (IS_ERR(ptr: rsp))
39 return false;
40
41 if (rsp->cap & PTP_CAP_HW_ATOMIC_UPDATE)
42 return true;
43
44 return false;
45}
46
47static int otx2_ptp_hw_adjtime(struct ptp_clock_info *ptp_info, s64 delta)
48{
49 struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp,
50 ptp_info);
51 struct otx2_nic *pfvf = ptp->nic;
52 struct ptp_req *req;
53 int rc;
54
55 if (!ptp->nic)
56 return -ENODEV;
57
58 mutex_lock(&pfvf->mbox.lock);
59 req = otx2_mbox_alloc_msg_ptp_op(mbox: &ptp->nic->mbox);
60 if (!req) {
61 mutex_unlock(lock: &pfvf->mbox.lock);
62 return -ENOMEM;
63 }
64 req->op = PTP_OP_ADJTIME;
65 req->delta = delta;
66 rc = otx2_sync_mbox_msg(mbox: &ptp->nic->mbox);
67 mutex_unlock(lock: &pfvf->mbox.lock);
68
69 return rc;
70}
71
72static u64 otx2_ptp_get_clock(struct otx2_ptp *ptp)
73{
74 struct ptp_req *req;
75 struct ptp_rsp *rsp;
76 int err;
77
78 if (!ptp->nic)
79 return 0;
80
81 req = otx2_mbox_alloc_msg_ptp_op(mbox: &ptp->nic->mbox);
82 if (!req)
83 return 0;
84
85 req->op = PTP_OP_GET_CLOCK;
86
87 err = otx2_sync_mbox_msg(mbox: &ptp->nic->mbox);
88 if (err)
89 return 0;
90
91 rsp = (struct ptp_rsp *)otx2_mbox_get_rsp(mbox: &ptp->nic->mbox.mbox, devid: 0,
92 msg: &req->hdr);
93 if (IS_ERR(ptr: rsp))
94 return 0;
95
96 return rsp->clk;
97}
98
99static int otx2_ptp_hw_gettime(struct ptp_clock_info *ptp_info,
100 struct timespec64 *ts)
101{
102 struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp,
103 ptp_info);
104 u64 tstamp;
105
106 tstamp = otx2_ptp_get_clock(ptp);
107
108 *ts = ns_to_timespec64(nsec: tstamp);
109 return 0;
110}
111
112static int otx2_ptp_hw_settime(struct ptp_clock_info *ptp_info,
113 const struct timespec64 *ts)
114{
115 struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp,
116 ptp_info);
117 struct otx2_nic *pfvf = ptp->nic;
118 struct ptp_req *req;
119 u64 nsec;
120 int rc;
121
122 if (!ptp->nic)
123 return -ENODEV;
124
125 nsec = timespec64_to_ns(ts);
126
127 mutex_lock(&pfvf->mbox.lock);
128 req = otx2_mbox_alloc_msg_ptp_op(mbox: &ptp->nic->mbox);
129 if (!req) {
130 mutex_unlock(lock: &pfvf->mbox.lock);
131 return -ENOMEM;
132 }
133
134 req->op = PTP_OP_SET_CLOCK;
135 req->clk = nsec;
136 rc = otx2_sync_mbox_msg(mbox: &ptp->nic->mbox);
137 mutex_unlock(lock: &pfvf->mbox.lock);
138
139 return rc;
140}
141
142static int otx2_ptp_adjfine(struct ptp_clock_info *ptp_info, long scaled_ppm)
143{
144 struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp,
145 ptp_info);
146 struct ptp_req *req;
147
148 if (!ptp->nic)
149 return -ENODEV;
150
151 req = otx2_mbox_alloc_msg_ptp_op(mbox: &ptp->nic->mbox);
152 if (!req)
153 return -ENOMEM;
154
155 req->op = PTP_OP_ADJFINE;
156 req->scaled_ppm = scaled_ppm;
157
158 return otx2_sync_mbox_msg(mbox: &ptp->nic->mbox);
159}
160
161static int ptp_set_thresh(struct otx2_ptp *ptp, u64 thresh)
162{
163 struct ptp_req *req;
164
165 if (!ptp->nic)
166 return -ENODEV;
167
168 req = otx2_mbox_alloc_msg_ptp_op(mbox: &ptp->nic->mbox);
169 if (!req)
170 return -ENOMEM;
171
172 req->op = PTP_OP_SET_THRESH;
173 req->thresh = thresh;
174
175 return otx2_sync_mbox_msg(mbox: &ptp->nic->mbox);
176}
177
178static int ptp_pps_on(struct otx2_ptp *ptp, int on, u64 period)
179{
180 struct ptp_req *req;
181
182 if (!ptp->nic)
183 return -ENODEV;
184
185 req = otx2_mbox_alloc_msg_ptp_op(mbox: &ptp->nic->mbox);
186 if (!req)
187 return -ENOMEM;
188
189 req->op = PTP_OP_PPS_ON;
190 req->pps_on = on;
191 req->period = period;
192
193 return otx2_sync_mbox_msg(mbox: &ptp->nic->mbox);
194}
195
196static u64 ptp_cc_read(const struct cyclecounter *cc)
197{
198 struct otx2_ptp *ptp = container_of(cc, struct otx2_ptp, cycle_counter);
199
200 return otx2_ptp_get_clock(ptp);
201}
202
203static u64 ptp_tstmp_read(struct otx2_ptp *ptp)
204{
205 struct ptp_req *req;
206 struct ptp_rsp *rsp;
207 int err;
208
209 if (!ptp->nic)
210 return 0;
211
212 req = otx2_mbox_alloc_msg_ptp_op(mbox: &ptp->nic->mbox);
213 if (!req)
214 return 0;
215
216 req->op = PTP_OP_GET_TSTMP;
217
218 err = otx2_sync_mbox_msg(mbox: &ptp->nic->mbox);
219 if (err)
220 return 0;
221
222 rsp = (struct ptp_rsp *)otx2_mbox_get_rsp(mbox: &ptp->nic->mbox.mbox, devid: 0,
223 msg: &req->hdr);
224 if (IS_ERR(ptr: rsp))
225 return 0;
226
227 return rsp->clk;
228}
229
230static int otx2_ptp_tc_adjtime(struct ptp_clock_info *ptp_info, s64 delta)
231{
232 struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp,
233 ptp_info);
234 struct otx2_nic *pfvf = ptp->nic;
235
236 mutex_lock(&pfvf->mbox.lock);
237 timecounter_adjtime(tc: &ptp->time_counter, delta);
238 mutex_unlock(lock: &pfvf->mbox.lock);
239
240 return 0;
241}
242
243static int otx2_ptp_tc_gettime(struct ptp_clock_info *ptp_info,
244 struct timespec64 *ts)
245{
246 struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp,
247 ptp_info);
248 u64 tstamp;
249
250 mutex_lock(&ptp->nic->mbox.lock);
251 tstamp = timecounter_read(tc: &ptp->time_counter);
252 mutex_unlock(lock: &ptp->nic->mbox.lock);
253 *ts = ns_to_timespec64(nsec: tstamp);
254
255 return 0;
256}
257
258static int otx2_ptp_tc_settime(struct ptp_clock_info *ptp_info,
259 const struct timespec64 *ts)
260{
261 struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp,
262 ptp_info);
263 u64 nsec;
264
265 nsec = timespec64_to_ns(ts);
266
267 mutex_lock(&ptp->nic->mbox.lock);
268 timecounter_init(tc: &ptp->time_counter, cc: &ptp->cycle_counter, start_tstamp: nsec);
269 mutex_unlock(lock: &ptp->nic->mbox.lock);
270
271 return 0;
272}
273
274static int otx2_ptp_verify_pin(struct ptp_clock_info *ptp, unsigned int pin,
275 enum ptp_pin_function func, unsigned int chan)
276{
277 switch (func) {
278 case PTP_PF_NONE:
279 case PTP_PF_EXTTS:
280 case PTP_PF_PEROUT:
281 break;
282 case PTP_PF_PHYSYNC:
283 return -1;
284 }
285 return 0;
286}
287
288static u64 otx2_ptp_hw_tstamp2time(const struct timecounter *time_counter, u64 tstamp)
289{
290 /* On HW which supports atomic updates, timecounter is not initialized */
291 return tstamp;
292}
293
294static void otx2_ptp_extts_check(struct work_struct *work)
295{
296 struct otx2_ptp *ptp = container_of(work, struct otx2_ptp,
297 extts_work.work);
298 struct ptp_clock_event event;
299 u64 tstmp, new_thresh;
300
301 mutex_lock(&ptp->nic->mbox.lock);
302 tstmp = ptp_tstmp_read(ptp);
303 mutex_unlock(lock: &ptp->nic->mbox.lock);
304
305 if (tstmp != ptp->last_extts) {
306 event.type = PTP_CLOCK_EXTTS;
307 event.index = 0;
308 event.timestamp = ptp->ptp_tstamp2nsec(&ptp->time_counter, tstmp);
309 ptp_clock_event(ptp: ptp->ptp_clock, event: &event);
310 new_thresh = tstmp % 500000000;
311 if (ptp->thresh != new_thresh) {
312 mutex_lock(&ptp->nic->mbox.lock);
313 ptp_set_thresh(ptp, thresh: new_thresh);
314 mutex_unlock(lock: &ptp->nic->mbox.lock);
315 ptp->thresh = new_thresh;
316 }
317 ptp->last_extts = tstmp;
318 }
319 schedule_delayed_work(dwork: &ptp->extts_work, delay: msecs_to_jiffies(m: 200));
320}
321
322static void otx2_sync_tstamp(struct work_struct *work)
323{
324 struct otx2_ptp *ptp = container_of(work, struct otx2_ptp,
325 synctstamp_work.work);
326 struct otx2_nic *pfvf = ptp->nic;
327 u64 tstamp;
328
329 mutex_lock(&pfvf->mbox.lock);
330 tstamp = otx2_ptp_get_clock(ptp);
331 mutex_unlock(lock: &pfvf->mbox.lock);
332
333 ptp->tstamp = ptp->ptp_tstamp2nsec(&ptp->time_counter, tstamp);
334 ptp->base_ns = tstamp % NSEC_PER_SEC;
335
336 schedule_delayed_work(dwork: &ptp->synctstamp_work, delay: msecs_to_jiffies(m: 250));
337}
338
339static int otx2_ptp_enable(struct ptp_clock_info *ptp_info,
340 struct ptp_clock_request *rq, int on)
341{
342 struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp,
343 ptp_info);
344 u64 period = 0;
345 int pin;
346
347 if (!ptp->nic)
348 return -ENODEV;
349
350 switch (rq->type) {
351 case PTP_CLK_REQ_EXTTS:
352 pin = ptp_find_pin(ptp: ptp->ptp_clock, func: PTP_PF_EXTTS,
353 chan: rq->extts.index);
354 if (pin < 0)
355 return -EBUSY;
356 if (on)
357 schedule_delayed_work(dwork: &ptp->extts_work, delay: msecs_to_jiffies(m: 200));
358 else
359 cancel_delayed_work_sync(dwork: &ptp->extts_work);
360
361 return 0;
362 case PTP_CLK_REQ_PEROUT:
363 if (rq->perout.flags)
364 return -EOPNOTSUPP;
365
366 if (rq->perout.index >= ptp_info->n_pins)
367 return -EINVAL;
368 if (on) {
369 period = rq->perout.period.sec * NSEC_PER_SEC +
370 rq->perout.period.nsec;
371 ptp_pps_on(ptp, on, period);
372 } else {
373 ptp_pps_on(ptp, on, period);
374 }
375 return 0;
376 default:
377 break;
378 }
379 return -EOPNOTSUPP;
380}
381
382int otx2_ptp_init(struct otx2_nic *pfvf)
383{
384 struct otx2_ptp *ptp_ptr;
385 struct cyclecounter *cc;
386 struct ptp_req *req;
387 int err;
388
389 if (is_otx2_lbkvf(pdev: pfvf->pdev)) {
390 pfvf->ptp = NULL;
391 return 0;
392 }
393
394 mutex_lock(&pfvf->mbox.lock);
395 /* check if PTP block is available */
396 req = otx2_mbox_alloc_msg_ptp_op(mbox: &pfvf->mbox);
397 if (!req) {
398 mutex_unlock(lock: &pfvf->mbox.lock);
399 return -ENOMEM;
400 }
401
402 req->op = PTP_OP_GET_CLOCK;
403
404 err = otx2_sync_mbox_msg(mbox: &pfvf->mbox);
405 if (err) {
406 mutex_unlock(lock: &pfvf->mbox.lock);
407 return err;
408 }
409 mutex_unlock(lock: &pfvf->mbox.lock);
410
411 ptp_ptr = kzalloc(size: sizeof(*ptp_ptr), GFP_KERNEL);
412 if (!ptp_ptr) {
413 err = -ENOMEM;
414 goto error;
415 }
416
417 ptp_ptr->nic = pfvf;
418
419 snprintf(buf: ptp_ptr->extts_config.name, size: sizeof(ptp_ptr->extts_config.name), fmt: "TSTAMP");
420 ptp_ptr->extts_config.index = 0;
421 ptp_ptr->extts_config.func = PTP_PF_NONE;
422
423 ptp_ptr->ptp_info = (struct ptp_clock_info) {
424 .owner = THIS_MODULE,
425 .name = "OcteonTX2 PTP",
426 .max_adj = 1000000000ull,
427 .n_ext_ts = 1,
428 .n_per_out = 1,
429 .n_pins = 1,
430 .pps = 0,
431 .pin_config = &ptp_ptr->extts_config,
432 .adjfine = otx2_ptp_adjfine,
433 .enable = otx2_ptp_enable,
434 .verify = otx2_ptp_verify_pin,
435 };
436
437 /* Check whether hardware supports atomic updates to timestamp */
438 if (is_tstmp_atomic_update_supported(ptp: ptp_ptr)) {
439 ptp_ptr->ptp_info.adjtime = otx2_ptp_hw_adjtime;
440 ptp_ptr->ptp_info.gettime64 = otx2_ptp_hw_gettime;
441 ptp_ptr->ptp_info.settime64 = otx2_ptp_hw_settime;
442
443 ptp_ptr->ptp_tstamp2nsec = otx2_ptp_hw_tstamp2time;
444 } else {
445 ptp_ptr->ptp_info.adjtime = otx2_ptp_tc_adjtime;
446 ptp_ptr->ptp_info.gettime64 = otx2_ptp_tc_gettime;
447 ptp_ptr->ptp_info.settime64 = otx2_ptp_tc_settime;
448
449 cc = &ptp_ptr->cycle_counter;
450 cc->read = ptp_cc_read;
451 cc->mask = CYCLECOUNTER_MASK(64);
452 cc->mult = 1;
453 cc->shift = 0;
454 ptp_ptr->ptp_tstamp2nsec = timecounter_cyc2time;
455
456 timecounter_init(tc: &ptp_ptr->time_counter, cc: &ptp_ptr->cycle_counter,
457 start_tstamp: ktime_to_ns(kt: ktime_get_real()));
458 }
459
460 INIT_DELAYED_WORK(&ptp_ptr->extts_work, otx2_ptp_extts_check);
461
462 ptp_ptr->ptp_clock = ptp_clock_register(info: &ptp_ptr->ptp_info, parent: pfvf->dev);
463 if (IS_ERR_OR_NULL(ptr: ptp_ptr->ptp_clock)) {
464 err = ptp_ptr->ptp_clock ?
465 PTR_ERR(ptr: ptp_ptr->ptp_clock) : -ENODEV;
466 kfree(objp: ptp_ptr);
467 goto error;
468 }
469
470 if (is_dev_otx2(pdev: pfvf->pdev)) {
471 ptp_ptr->convert_rx_ptp_tstmp = &otx2_ptp_convert_rx_timestamp;
472 ptp_ptr->convert_tx_ptp_tstmp = &otx2_ptp_convert_tx_timestamp;
473 } else {
474 ptp_ptr->convert_rx_ptp_tstmp = &cn10k_ptp_convert_timestamp;
475 ptp_ptr->convert_tx_ptp_tstmp = &cn10k_ptp_convert_timestamp;
476 }
477
478 INIT_DELAYED_WORK(&ptp_ptr->synctstamp_work, otx2_sync_tstamp);
479
480 pfvf->ptp = ptp_ptr;
481
482error:
483 return err;
484}
485EXPORT_SYMBOL_GPL(otx2_ptp_init);
486
487void otx2_ptp_destroy(struct otx2_nic *pfvf)
488{
489 struct otx2_ptp *ptp = pfvf->ptp;
490
491 if (!ptp)
492 return;
493
494 cancel_delayed_work(dwork: &pfvf->ptp->synctstamp_work);
495
496 ptp_clock_unregister(ptp: ptp->ptp_clock);
497 kfree(objp: ptp);
498 pfvf->ptp = NULL;
499}
500EXPORT_SYMBOL_GPL(otx2_ptp_destroy);
501
502int otx2_ptp_clock_index(struct otx2_nic *pfvf)
503{
504 if (!pfvf->ptp)
505 return -ENODEV;
506
507 return ptp_clock_index(ptp: pfvf->ptp->ptp_clock);
508}
509EXPORT_SYMBOL_GPL(otx2_ptp_clock_index);
510
511int otx2_ptp_tstamp2time(struct otx2_nic *pfvf, u64 tstamp, u64 *tsns)
512{
513 if (!pfvf->ptp)
514 return -ENODEV;
515
516 *tsns = pfvf->ptp->ptp_tstamp2nsec(&pfvf->ptp->time_counter, tstamp);
517
518 return 0;
519}
520EXPORT_SYMBOL_GPL(otx2_ptp_tstamp2time);
521
522MODULE_AUTHOR("Sunil Goutham <sgoutham@marvell.com>");
523MODULE_DESCRIPTION("Marvell RVU NIC PTP Driver");
524MODULE_LICENSE("GPL v2");
525

source code of linux/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c