1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include <linux/ptp_classify.h>
22#include <linux/ptp_clock_kernel.h>
23
24#include "fm10k.h"
25
26#define FM10K_TS_TX_TIMEOUT (HZ * 15)
27
28void fm10k_systime_to_hwtstamp(struct fm10k_intfc *interface,
29 struct skb_shared_hwtstamps *hwtstamp,
30 u64 systime)
31{
32 unsigned long flags;
33
34 read_lock_irqsave(&interface->systime_lock, flags);
35 systime += interface->ptp_adjust;
36 read_unlock_irqrestore(&interface->systime_lock, flags);
37
38 hwtstamp->hwtstamp = ns_to_ktime(systime);
39}
40
41static struct sk_buff *fm10k_ts_tx_skb(struct fm10k_intfc *interface,
42 __le16 dglort)
43{
44 struct sk_buff_head *list = &interface->ts_tx_skb_queue;
45 struct sk_buff *skb;
46
47 skb_queue_walk(list, skb) {
48 if (FM10K_CB(skb)->fi.w.dglort == dglort)
49 return skb;
50 }
51
52 return NULL;
53}
54
55void fm10k_ts_tx_enqueue(struct fm10k_intfc *interface, struct sk_buff *skb)
56{
57 struct sk_buff_head *list = &interface->ts_tx_skb_queue;
58 struct sk_buff *clone;
59 unsigned long flags;
60
61
62 clone = skb_clone_sk(skb);
63 if (!clone)
64 return;
65
66 FM10K_CB(clone)->ts_tx_timeout = jiffies + FM10K_TS_TX_TIMEOUT;
67 spin_lock_irqsave(&list->lock, flags);
68
69
70
71
72 skb = fm10k_ts_tx_skb(interface, FM10K_CB(clone)->fi.w.dglort);
73 if (!skb)
74 __skb_queue_tail(list, clone);
75
76 spin_unlock_irqrestore(&list->lock, flags);
77
78
79 if (skb)
80 kfree_skb(skb);
81 else
82 skb_shinfo(clone)->tx_flags |= SKBTX_IN_PROGRESS;
83}
84
85void fm10k_ts_tx_hwtstamp(struct fm10k_intfc *interface, __le16 dglort,
86 u64 systime)
87{
88 struct skb_shared_hwtstamps shhwtstamps;
89 struct sk_buff_head *list = &interface->ts_tx_skb_queue;
90 struct sk_buff *skb;
91 unsigned long flags;
92
93 spin_lock_irqsave(&list->lock, flags);
94
95
96 skb = fm10k_ts_tx_skb(interface, dglort);
97 if (skb)
98 __skb_unlink(skb, list);
99
100 spin_unlock_irqrestore(&list->lock, flags);
101
102
103 if (!skb)
104 return;
105
106
107 fm10k_systime_to_hwtstamp(interface, &shhwtstamps, systime);
108 skb_complete_tx_timestamp(skb, &shhwtstamps);
109}
110
111void fm10k_ts_tx_subtask(struct fm10k_intfc *interface)
112{
113 struct sk_buff_head *list = &interface->ts_tx_skb_queue;
114 struct sk_buff *skb, *tmp;
115 unsigned long flags;
116
117
118 if (test_bit(__FM10K_DOWN, &interface->state) ||
119 test_bit(__FM10K_RESETTING, &interface->state))
120 return;
121
122 spin_lock_irqsave(&list->lock, flags);
123
124
125 skb_queue_walk_safe(list, skb, tmp) {
126 if (!time_is_after_jiffies(FM10K_CB(skb)->ts_tx_timeout))
127 continue;
128 __skb_unlink(skb, list);
129 kfree_skb(skb);
130 interface->tx_hwtstamp_timeouts++;
131 }
132
133 spin_unlock_irqrestore(&list->lock, flags);
134}
135
136static u64 fm10k_systime_read(struct fm10k_intfc *interface)
137{
138 struct fm10k_hw *hw = &interface->hw;
139
140 return hw->mac.ops.read_systime(hw);
141}
142
143void fm10k_ts_reset(struct fm10k_intfc *interface)
144{
145 s64 ns = ktime_to_ns(ktime_get_real());
146 unsigned long flags;
147
148
149 write_lock_irqsave(&interface->systime_lock, flags);
150 interface->ptp_adjust = fm10k_systime_read(interface) - ns;
151 write_unlock_irqrestore(&interface->systime_lock, flags);
152}
153
154void fm10k_ts_init(struct fm10k_intfc *interface)
155{
156
157 rwlock_init(&interface->systime_lock);
158
159
160 skb_queue_head_init(&interface->ts_tx_skb_queue);
161
162
163 fm10k_ts_reset(interface);
164}
165
166
167
168
169
170
171
172
173
174
175int fm10k_get_ts_config(struct net_device *netdev, struct ifreq *ifr)
176{
177 struct fm10k_intfc *interface = netdev_priv(netdev);
178 struct hwtstamp_config *config = &interface->ts_config;
179
180 return copy_to_user(ifr->ifr_data, config, sizeof(*config)) ?
181 -EFAULT : 0;
182}
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206int fm10k_set_ts_config(struct net_device *netdev, struct ifreq *ifr)
207{
208 struct fm10k_intfc *interface = netdev_priv(netdev);
209 struct hwtstamp_config ts_config;
210
211 if (copy_from_user(&ts_config, ifr->ifr_data, sizeof(ts_config)))
212 return -EFAULT;
213
214
215 if (ts_config.flags)
216 return -EINVAL;
217
218 switch (ts_config.tx_type) {
219 case HWTSTAMP_TX_OFF:
220 break;
221 case HWTSTAMP_TX_ON:
222
223 break;
224 default:
225 return -ERANGE;
226 }
227
228 switch (ts_config.rx_filter) {
229 case HWTSTAMP_FILTER_NONE:
230 interface->flags &= ~FM10K_FLAG_RX_TS_ENABLED;
231 break;
232 case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
233 case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
234 case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
235 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
236 case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
237 case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
238 case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
239 case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
240 case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
241 case HWTSTAMP_FILTER_PTP_V2_EVENT:
242 case HWTSTAMP_FILTER_PTP_V2_SYNC:
243 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
244 case HWTSTAMP_FILTER_ALL:
245 interface->flags |= FM10K_FLAG_RX_TS_ENABLED;
246 ts_config.rx_filter = HWTSTAMP_FILTER_ALL;
247 break;
248 default:
249 return -ERANGE;
250 }
251
252
253 interface->ts_config = ts_config;
254
255 return copy_to_user(ifr->ifr_data, &ts_config, sizeof(ts_config)) ?
256 -EFAULT : 0;
257}
258
259static int fm10k_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
260{
261 struct fm10k_intfc *interface;
262 struct fm10k_hw *hw;
263 int err;
264
265 interface = container_of(ptp, struct fm10k_intfc, ptp_caps);
266 hw = &interface->hw;
267
268 err = hw->mac.ops.adjust_systime(hw, ppb);
269
270
271 return (err == FM10K_ERR_PARAM) ? -ERANGE : err;
272}
273
274static int fm10k_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
275{
276 struct fm10k_intfc *interface;
277 unsigned long flags;
278
279 interface = container_of(ptp, struct fm10k_intfc, ptp_caps);
280
281 write_lock_irqsave(&interface->systime_lock, flags);
282 interface->ptp_adjust += delta;
283 write_unlock_irqrestore(&interface->systime_lock, flags);
284
285 return 0;
286}
287
288static int fm10k_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
289{
290 struct fm10k_intfc *interface;
291 unsigned long flags;
292 u64 now;
293
294 interface = container_of(ptp, struct fm10k_intfc, ptp_caps);
295
296 read_lock_irqsave(&interface->systime_lock, flags);
297 now = fm10k_systime_read(interface) + interface->ptp_adjust;
298 read_unlock_irqrestore(&interface->systime_lock, flags);
299
300 *ts = ns_to_timespec64(now);
301
302 return 0;
303}
304
305static int fm10k_ptp_settime(struct ptp_clock_info *ptp,
306 const struct timespec64 *ts)
307{
308 struct fm10k_intfc *interface;
309 unsigned long flags;
310 u64 ns = timespec64_to_ns(ts);
311
312 interface = container_of(ptp, struct fm10k_intfc, ptp_caps);
313
314 write_lock_irqsave(&interface->systime_lock, flags);
315 interface->ptp_adjust = fm10k_systime_read(interface) - ns;
316 write_unlock_irqrestore(&interface->systime_lock, flags);
317
318 return 0;
319}
320
321static int fm10k_ptp_enable(struct ptp_clock_info *ptp,
322 struct ptp_clock_request *rq,
323 int __always_unused on)
324{
325 struct ptp_clock_time *t = &rq->perout.period;
326 struct fm10k_intfc *interface;
327 struct fm10k_hw *hw;
328 u64 period;
329 u32 step;
330
331
332 if (rq->type != PTP_CLK_REQ_PEROUT)
333 return -EINVAL;
334
335
336 if (rq->perout.index >= ptp->n_per_out)
337 return -EINVAL;
338
339
340
341
342
343
344
345 if (t->sec > 4 || t->sec < 0)
346 return -ERANGE;
347
348 interface = container_of(ptp, struct fm10k_intfc, ptp_caps);
349 hw = &interface->hw;
350
351
352 if (!hw->sw_addr)
353 return -ENOTSUPP;
354
355
356 period = t->sec * 1000000000LL + t->nsec;
357
358
359 step = 2 * (fm10k_read_reg(hw, FM10K_SYSTIME_CFG) &
360 FM10K_SYSTIME_CFG_STEP_MASK);
361
362
363 if ((period && (period < step)) || (period > U32_MAX))
364 return -ERANGE;
365
366
367 fm10k_write_sw_reg(hw, FM10K_SW_SYSTIME_PULSE(rq->perout.index),
368 (u32)period);
369
370 return 0;
371}
372
373static struct ptp_pin_desc fm10k_ptp_pd[2] = {
374 {
375 .name = "IEEE1588_PULSE0",
376 .index = 0,
377 .func = PTP_PF_PEROUT,
378 .chan = 0
379 },
380 {
381 .name = "IEEE1588_PULSE1",
382 .index = 1,
383 .func = PTP_PF_PEROUT,
384 .chan = 1
385 }
386};
387
388static int fm10k_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin,
389 enum ptp_pin_function func, unsigned int chan)
390{
391
392 if (pin >= ptp->n_pins || !ptp->pin_config)
393 return -EINVAL;
394
395
396 if (chan != ptp->pin_config[pin].chan)
397 return -EINVAL;
398
399
400 if (func != ptp->pin_config[pin].func)
401 return -EINVAL;
402
403 return 0;
404}
405
406void fm10k_ptp_register(struct fm10k_intfc *interface)
407{
408 struct ptp_clock_info *ptp_caps = &interface->ptp_caps;
409 struct device *dev = &interface->pdev->dev;
410 struct ptp_clock *ptp_clock;
411
412 snprintf(ptp_caps->name, sizeof(ptp_caps->name),
413 "%s", interface->netdev->name);
414 ptp_caps->owner = THIS_MODULE;
415
416
417
418
419
420 ptp_caps->max_adj = 976562;
421 ptp_caps->adjfreq = fm10k_ptp_adjfreq;
422 ptp_caps->adjtime = fm10k_ptp_adjtime;
423 ptp_caps->gettime64 = fm10k_ptp_gettime;
424 ptp_caps->settime64 = fm10k_ptp_settime;
425
426
427 if (interface->sw_addr) {
428
429 ptp_caps->n_per_out = 2;
430 ptp_caps->enable = fm10k_ptp_enable;
431
432
433 ptp_caps->verify = fm10k_ptp_verify;
434 ptp_caps->n_pins = 2;
435 ptp_caps->pin_config = fm10k_ptp_pd;
436 }
437
438 ptp_clock = ptp_clock_register(ptp_caps, dev);
439 if (IS_ERR(ptp_clock)) {
440 ptp_clock = NULL;
441 dev_err(dev, "ptp_clock_register failed\n");
442 } else {
443 dev_info(dev, "registered PHC device %s\n", ptp_caps->name);
444 }
445
446 interface->ptp_clock = ptp_clock;
447}
448
449void fm10k_ptp_unregister(struct fm10k_intfc *interface)
450{
451 struct ptp_clock *ptp_clock = interface->ptp_clock;
452 struct device *dev = &interface->pdev->dev;
453
454 if (!ptp_clock)
455 return;
456
457 interface->ptp_clock = NULL;
458
459 ptp_clock_unregister(ptp_clock);
460 dev_info(dev, "removed PHC %s\n", interface->ptp_caps.name);
461}
462