Merge remote-tracking branches 'spi/fix/bcm63xx', 'spi/fix/doc', 'spi/fix/mediatek...
[deliverable/linux.git] / drivers / net / ethernet / intel / fm10k / fm10k_ptp.c
CommitLineData
a211e013 1/* Intel Ethernet Switch Host Interface Driver
de445199 2 * Copyright(c) 2013 - 2015 Intel Corporation.
a211e013
AD
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * The full GNU General Public License is included in this distribution in
14 * the file called "COPYING".
15 *
16 * Contact Information:
17 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
18 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
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;
a211e013
AD
60
61 /* create clone for us to return on the Tx path */
62 clone = skb_clone_sk(skb);
63 if (!clone)
64 return;
65
66 FM10K_CB(clone)->ts_tx_timeout = jiffies + FM10K_TS_TX_TIMEOUT;
a211e013
AD
67 spin_lock_irqsave(&list->lock, flags);
68
69 /* attempt to locate any buffers with the same dglort,
70 * if none are present then insert skb in tail of list
71 */
72 skb = fm10k_ts_tx_skb(interface, FM10K_CB(clone)->fi.w.dglort);
e075996e
JK
73 if (!skb) {
74 skb_shinfo(clone)->tx_flags |= SKBTX_IN_PROGRESS;
a211e013 75 __skb_queue_tail(list, clone);
e075996e 76 }
a211e013
AD
77
78 spin_unlock_irqrestore(&list->lock, flags);
79
80 /* if list is already has one then we just free the clone */
81 if (skb)
c23544b1 82 dev_kfree_skb(clone);
a211e013
AD
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 /* attempt to locate and pull the sk_buff out of the list */
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 /* if not found do nothing */
103 if (!skb)
104 return;
105
608bb146 106 /* timestamp the sk_buff and free out copy */
a211e013 107 fm10k_systime_to_hwtstamp(interface, &shhwtstamps, systime);
608bb146
JK
108 skb_tstamp_tx(skb, &shhwtstamps);
109 dev_kfree_skb_any(skb);
a211e013
AD
110}
111
112void fm10k_ts_tx_subtask(struct fm10k_intfc *interface)
113{
114 struct sk_buff_head *list = &interface->ts_tx_skb_queue;
115 struct sk_buff *skb, *tmp;
116 unsigned long flags;
117
118 /* If we're down or resetting, just bail */
119 if (test_bit(__FM10K_DOWN, &interface->state) ||
120 test_bit(__FM10K_RESETTING, &interface->state))
121 return;
122
123 spin_lock_irqsave(&list->lock, flags);
124
125 /* walk though the list and flush any expired timestamp packets */
126 skb_queue_walk_safe(list, skb, tmp) {
127 if (!time_is_after_jiffies(FM10K_CB(skb)->ts_tx_timeout))
128 continue;
129 __skb_unlink(skb, list);
130 kfree_skb(skb);
131 interface->tx_hwtstamp_timeouts++;
132 }
133
134 spin_unlock_irqrestore(&list->lock, flags);
135}
136
137static u64 fm10k_systime_read(struct fm10k_intfc *interface)
138{
139 struct fm10k_hw *hw = &interface->hw;
140
141 return hw->mac.ops.read_systime(hw);
142}
143
144void fm10k_ts_reset(struct fm10k_intfc *interface)
145{
146 s64 ns = ktime_to_ns(ktime_get_real());
147 unsigned long flags;
148
149 /* reinitialize the clock */
150 write_lock_irqsave(&interface->systime_lock, flags);
151 interface->ptp_adjust = fm10k_systime_read(interface) - ns;
152 write_unlock_irqrestore(&interface->systime_lock, flags);
153}
154
155void fm10k_ts_init(struct fm10k_intfc *interface)
156{
157 /* Initialize lock protecting systime access */
158 rwlock_init(&interface->systime_lock);
159
160 /* Initialize skb queue for pending timestamp requests */
161 skb_queue_head_init(&interface->ts_tx_skb_queue);
162
163 /* reset the clock to current kernel time */
164 fm10k_ts_reset(interface);
165}
166
167/**
168 * fm10k_get_ts_config - get current hardware timestamping configuration
169 * @netdev: network interface device structure
170 * @ifreq: ioctl data
171 *
172 * This function returns the current timestamping settings. Rather than
173 * attempt to deconstruct registers to fill in the values, simply keep a copy
174 * of the old settings around, and return a copy when requested.
175 */
176int fm10k_get_ts_config(struct net_device *netdev, struct ifreq *ifr)
177{
178 struct fm10k_intfc *interface = netdev_priv(netdev);
179 struct hwtstamp_config *config = &interface->ts_config;
180
181 return copy_to_user(ifr->ifr_data, config, sizeof(*config)) ?
182 -EFAULT : 0;
183}
184
185/**
186 * fm10k_set_ts_config - control hardware time stamping
187 * @netdev: network interface device structure
188 * @ifreq: ioctl data
189 *
190 * Outgoing time stamping can be enabled and disabled. Play nice and
191 * disable it when requested, although it shouldn't cause any overhead
192 * when no packet needs it. At most one packet in the queue may be
193 * marked for time stamping, otherwise it would be impossible to tell
194 * for sure to which packet the hardware time stamp belongs.
195 *
196 * Incoming time stamping has to be configured via the hardware
197 * filters. Not all combinations are supported, in particular event
198 * type has to be specified. Matching the kind of event packet is
199 * not supported, with the exception of "all V2 events regardless of
200 * level 2 or 4".
201 *
202 * Since hardware always timestamps Path delay packets when timestamping V2
203 * packets, regardless of the type specified in the register, only use V2
204 * Event mode. This more accurately tells the user what the hardware is going
205 * to do anyways.
206 */
207int fm10k_set_ts_config(struct net_device *netdev, struct ifreq *ifr)
208{
209 struct fm10k_intfc *interface = netdev_priv(netdev);
210 struct hwtstamp_config ts_config;
211
212 if (copy_from_user(&ts_config, ifr->ifr_data, sizeof(ts_config)))
213 return -EFAULT;
214
215 /* reserved for future extensions */
216 if (ts_config.flags)
217 return -EINVAL;
218
219 switch (ts_config.tx_type) {
220 case HWTSTAMP_TX_OFF:
221 break;
222 case HWTSTAMP_TX_ON:
223 /* we likely need some check here to see if this is supported */
224 break;
225 default:
226 return -ERANGE;
227 }
228
229 switch (ts_config.rx_filter) {
230 case HWTSTAMP_FILTER_NONE:
231 interface->flags &= ~FM10K_FLAG_RX_TS_ENABLED;
232 break;
233 case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
234 case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
235 case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
236 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
237 case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
238 case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
239 case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
240 case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
241 case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
242 case HWTSTAMP_FILTER_PTP_V2_EVENT:
243 case HWTSTAMP_FILTER_PTP_V2_SYNC:
244 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
245 case HWTSTAMP_FILTER_ALL:
246 interface->flags |= FM10K_FLAG_RX_TS_ENABLED;
247 ts_config.rx_filter = HWTSTAMP_FILTER_ALL;
248 break;
249 default:
250 return -ERANGE;
251 }
252
253 /* save these settings for future reference */
254 interface->ts_config = ts_config;
255
256 return copy_to_user(ifr->ifr_data, &ts_config, sizeof(ts_config)) ?
257 -EFAULT : 0;
258}
259
260static int fm10k_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
261{
262 struct fm10k_intfc *interface;
263 struct fm10k_hw *hw;
264 int err;
265
266 interface = container_of(ptp, struct fm10k_intfc, ptp_caps);
267 hw = &interface->hw;
268
269 err = hw->mac.ops.adjust_systime(hw, ppb);
270
271 /* the only error we should see is if the value is out of range */
272 return (err == FM10K_ERR_PARAM) ? -ERANGE : err;
273}
274
275static int fm10k_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
276{
277 struct fm10k_intfc *interface;
278 unsigned long flags;
279
280 interface = container_of(ptp, struct fm10k_intfc, ptp_caps);
281
282 write_lock_irqsave(&interface->systime_lock, flags);
283 interface->ptp_adjust += delta;
284 write_unlock_irqrestore(&interface->systime_lock, flags);
285
286 return 0;
287}
288
843293e1 289static int fm10k_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
a211e013
AD
290{
291 struct fm10k_intfc *interface;
292 unsigned long flags;
293 u64 now;
294
295 interface = container_of(ptp, struct fm10k_intfc, ptp_caps);
296
297 read_lock_irqsave(&interface->systime_lock, flags);
298 now = fm10k_systime_read(interface) + interface->ptp_adjust;
299 read_unlock_irqrestore(&interface->systime_lock, flags);
300
843293e1 301 *ts = ns_to_timespec64(now);
a211e013
AD
302
303 return 0;
304}
305
306static int fm10k_ptp_settime(struct ptp_clock_info *ptp,
843293e1 307 const struct timespec64 *ts)
a211e013
AD
308{
309 struct fm10k_intfc *interface;
310 unsigned long flags;
843293e1 311 u64 ns = timespec64_to_ns(ts);
a211e013
AD
312
313 interface = container_of(ptp, struct fm10k_intfc, ptp_caps);
314
315 write_lock_irqsave(&interface->systime_lock, flags);
316 interface->ptp_adjust = fm10k_systime_read(interface) - ns;
317 write_unlock_irqrestore(&interface->systime_lock, flags);
318
319 return 0;
320}
321
322static int fm10k_ptp_enable(struct ptp_clock_info *ptp,
de445199
JK
323 struct ptp_clock_request *rq,
324 int __always_unused on)
a211e013
AD
325{
326 struct ptp_clock_time *t = &rq->perout.period;
327 struct fm10k_intfc *interface;
328 struct fm10k_hw *hw;
329 u64 period;
330 u32 step;
331
332 /* we can only support periodic output */
333 if (rq->type != PTP_CLK_REQ_PEROUT)
334 return -EINVAL;
335
336 /* verify the requested channel is there */
337 if (rq->perout.index >= ptp->n_per_out)
338 return -EINVAL;
339
340 /* we cannot enforce start time as there is no
341 * mechanism for that in the hardware, we can only control
342 * the period.
343 */
344
345 /* we cannot support periods greater than 4 seconds due to reg limit */
346 if (t->sec > 4 || t->sec < 0)
347 return -ERANGE;
348
349 interface = container_of(ptp, struct fm10k_intfc, ptp_caps);
350 hw = &interface->hw;
351
352 /* we simply cannot support the operation if we don't have BAR4 */
353 if (!hw->sw_addr)
354 return -ENOTSUPP;
355
356 /* convert to unsigned 64b ns, verify we can put it in a 32b register */
357 period = t->sec * 1000000000LL + t->nsec;
358
359 /* determine the minimum size for period */
360 step = 2 * (fm10k_read_reg(hw, FM10K_SYSTIME_CFG) &
361 FM10K_SYSTIME_CFG_STEP_MASK);
362
363 /* verify the value is in range supported by hardware */
364 if ((period && (period < step)) || (period > U32_MAX))
365 return -ERANGE;
366
367 /* notify hardware of request to being sending pulses */
368 fm10k_write_sw_reg(hw, FM10K_SW_SYSTIME_PULSE(rq->perout.index),
369 (u32)period);
370
371 return 0;
372}
373
374static struct ptp_pin_desc fm10k_ptp_pd[2] = {
375 {
376 .name = "IEEE1588_PULSE0",
377 .index = 0,
378 .func = PTP_PF_PEROUT,
379 .chan = 0
380 },
381 {
382 .name = "IEEE1588_PULSE1",
383 .index = 1,
384 .func = PTP_PF_PEROUT,
385 .chan = 1
386 }
387};
388
389static int fm10k_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin,
390 enum ptp_pin_function func, unsigned int chan)
391{
392 /* verify the requested pin is there */
393 if (pin >= ptp->n_pins || !ptp->pin_config)
394 return -EINVAL;
395
396 /* enforce locked channels, no changing them */
397 if (chan != ptp->pin_config[pin].chan)
398 return -EINVAL;
399
400 /* we want to keep the functions locked as well */
401 if (func != ptp->pin_config[pin].func)
402 return -EINVAL;
403
404 return 0;
405}
406
407void fm10k_ptp_register(struct fm10k_intfc *interface)
408{
409 struct ptp_clock_info *ptp_caps = &interface->ptp_caps;
410 struct device *dev = &interface->pdev->dev;
411 struct ptp_clock *ptp_clock;
412
413 snprintf(ptp_caps->name, sizeof(ptp_caps->name),
414 "%s", interface->netdev->name);
415 ptp_caps->owner = THIS_MODULE;
416 /* This math is simply the inverse of the math in
417 * fm10k_adjust_systime_pf applied to an adjustment value
418 * of 2^30 - 1 which is the maximum value of the register:
419 * max_ppb == ((2^30 - 1) * 5^9) / 2^31
420 */
421 ptp_caps->max_adj = 976562;
422 ptp_caps->adjfreq = fm10k_ptp_adjfreq;
423 ptp_caps->adjtime = fm10k_ptp_adjtime;
843293e1
RC
424 ptp_caps->gettime64 = fm10k_ptp_gettime;
425 ptp_caps->settime64 = fm10k_ptp_settime;
a211e013
AD
426
427 /* provide pins if BAR4 is accessible */
428 if (interface->sw_addr) {
429 /* enable periodic outputs */
430 ptp_caps->n_per_out = 2;
431 ptp_caps->enable = fm10k_ptp_enable;
432
433 /* enable clock pins */
434 ptp_caps->verify = fm10k_ptp_verify;
435 ptp_caps->n_pins = 2;
436 ptp_caps->pin_config = fm10k_ptp_pd;
437 }
438
439 ptp_clock = ptp_clock_register(ptp_caps, dev);
440 if (IS_ERR(ptp_clock)) {
441 ptp_clock = NULL;
442 dev_err(dev, "ptp_clock_register failed\n");
443 } else {
444 dev_info(dev, "registered PHC device %s\n", ptp_caps->name);
445 }
446
447 interface->ptp_clock = ptp_clock;
448}
449
450void fm10k_ptp_unregister(struct fm10k_intfc *interface)
451{
452 struct ptp_clock *ptp_clock = interface->ptp_clock;
453 struct device *dev = &interface->pdev->dev;
454
455 if (!ptp_clock)
456 return;
457
458 interface->ptp_clock = NULL;
459
460 ptp_clock_unregister(ptp_clock);
461 dev_info(dev, "removed PHC %s\n", interface->ptp_caps.name);
462}
This page took 0.106241 seconds and 5 git commands to generate.