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