Commit | Line | Data |
---|---|---|
3a6a4eda JK |
1 | /******************************************************************************* |
2 | ||
3 | Intel 10 Gigabit PCI Express Linux driver | |
434c5e39 | 4 | Copyright(c) 1999 - 2013 Intel Corporation. |
3a6a4eda JK |
5 | |
6 | This program is free software; you can redistribute it and/or modify it | |
7 | under the terms and conditions of the GNU General Public License, | |
8 | version 2, as published by the Free Software Foundation. | |
9 | ||
10 | This program is distributed in the hope it will be useful, but WITHOUT | |
11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
13 | more details. | |
14 | ||
15 | You should have received a copy of the GNU General Public License along with | |
16 | this program; if not, write to the Free Software Foundation, Inc., | |
17 | 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | |
18 | ||
19 | The full GNU General Public License is included in this distribution in | |
20 | the file called "COPYING". | |
21 | ||
22 | Contact Information: | |
b89aae71 | 23 | Linux NICS <linux.nics@intel.com> |
3a6a4eda JK |
24 | e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> |
25 | Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | |
26 | ||
27 | *******************************************************************************/ | |
28 | #include "ixgbe.h" | |
29 | #include <linux/export.h> | |
1d1a79b5 | 30 | #include <linux/ptp_classify.h> |
3a6a4eda JK |
31 | |
32 | /* | |
33 | * The 82599 and the X540 do not have true 64bit nanosecond scale | |
34 | * counter registers. Instead, SYSTIME is defined by a fixed point | |
35 | * system which allows the user to define the scale counter increment | |
36 | * value at every level change of the oscillator driving the SYSTIME | |
37 | * value. For both devices the TIMINCA:IV field defines this | |
38 | * increment. On the X540 device, 31 bits are provided. However on the | |
39 | * 82599 only provides 24 bits. The time unit is determined by the | |
40 | * clock frequency of the oscillator in combination with the TIMINCA | |
41 | * register. When these devices link at 10Gb the oscillator has a | |
42 | * period of 6.4ns. In order to convert the scale counter into | |
43 | * nanoseconds the cyclecounter and timecounter structures are | |
44 | * used. The SYSTIME registers need to be converted to ns values by use | |
45 | * of only a right shift (division by power of 2). The following math | |
46 | * determines the largest incvalue that will fit into the available | |
47 | * bits in the TIMINCA register. | |
48 | * | |
49 | * PeriodWidth: Number of bits to store the clock period | |
50 | * MaxWidth: The maximum width value of the TIMINCA register | |
51 | * Period: The clock period for the oscillator | |
52 | * round(): discard the fractional portion of the calculation | |
53 | * | |
54 | * Period * [ 2 ^ ( MaxWidth - PeriodWidth ) ] | |
55 | * | |
56 | * For the X540, MaxWidth is 31 bits, and the base period is 6.4 ns | |
57 | * For the 82599, MaxWidth is 24 bits, and the base period is 6.4 ns | |
58 | * | |
59 | * The period also changes based on the link speed: | |
60 | * At 10Gb link or no link, the period remains the same. | |
61 | * At 1Gb link, the period is multiplied by 10. (64ns) | |
62 | * At 100Mb link, the period is multiplied by 100. (640ns) | |
63 | * | |
64 | * The calculated value allows us to right shift the SYSTIME register | |
65 | * value in order to quickly convert it into a nanosecond clock, | |
66 | * while allowing for the maximum possible adjustment value. | |
67 | * | |
68 | * These diagrams are only for the 10Gb link period | |
69 | * | |
70 | * SYSTIMEH SYSTIMEL | |
71 | * +--------------+ +--------------+ | |
72 | * X540 | 32 | | 1 | 3 | 28 | | |
73 | * *--------------+ +--------------+ | |
74 | * \________ 36 bits ______/ fract | |
75 | * | |
76 | * +--------------+ +--------------+ | |
77 | * 82599 | 32 | | 8 | 3 | 21 | | |
78 | * *--------------+ +--------------+ | |
79 | * \________ 43 bits ______/ fract | |
80 | * | |
81 | * The 36 bit X540 SYSTIME overflows every | |
82 | * 2^36 * 10^-9 / 60 = 1.14 minutes or 69 seconds | |
83 | * | |
84 | * The 43 bit 82599 SYSTIME overflows every | |
85 | * 2^43 * 10^-9 / 3600 = 2.4 hours | |
86 | */ | |
87 | #define IXGBE_INCVAL_10GB 0x66666666 | |
88 | #define IXGBE_INCVAL_1GB 0x40000000 | |
89 | #define IXGBE_INCVAL_100 0x50000000 | |
90 | ||
91 | #define IXGBE_INCVAL_SHIFT_10GB 28 | |
92 | #define IXGBE_INCVAL_SHIFT_1GB 24 | |
93 | #define IXGBE_INCVAL_SHIFT_100 21 | |
94 | ||
95 | #define IXGBE_INCVAL_SHIFT_82599 7 | |
96 | #define IXGBE_INCPER_SHIFT_82599 24 | |
97 | #define IXGBE_MAX_TIMEADJ_VALUE 0x7FFFFFFFFFFFFFFFULL | |
98 | ||
99 | #define IXGBE_OVERFLOW_PERIOD (HZ * 30) | |
891dc082 | 100 | #define IXGBE_PTP_TX_TIMEOUT (HZ * 15) |
3a6a4eda | 101 | |
681ae1ad JK |
102 | #ifndef NSECS_PER_SEC |
103 | #define NSECS_PER_SEC 1000000000ULL | |
104 | #endif | |
105 | ||
82083673 | 106 | /** |
db0677fa | 107 | * ixgbe_ptp_setup_sdp |
82083673 | 108 | * @hw: the hardware private structure |
82083673 | 109 | * |
db0677fa JK |
110 | * this function enables or disables the clock out feature on SDP0 for |
111 | * the X540 device. It will create a 1second periodic output that can | |
112 | * be used as the PPS (via an interrupt). | |
82083673 JK |
113 | * |
114 | * It calculates when the systime will be on an exact second, and then | |
115 | * aligns the start of the PPS signal to that value. The shift is | |
116 | * necessary because it can change based on the link speed. | |
117 | */ | |
db0677fa | 118 | static void ixgbe_ptp_setup_sdp(struct ixgbe_adapter *adapter) |
82083673 JK |
119 | { |
120 | struct ixgbe_hw *hw = &adapter->hw; | |
121 | int shift = adapter->cc.shift; | |
122 | u32 esdp, tsauxc, clktiml, clktimh, trgttiml, trgttimh, rem; | |
123 | u64 ns = 0, clock_edge = 0; | |
124 | ||
db0677fa JK |
125 | if ((adapter->flags2 & IXGBE_FLAG2_PTP_PPS_ENABLED) && |
126 | (hw->mac.type == ixgbe_mac_X540)) { | |
127 | ||
128 | /* disable the pin first */ | |
129 | IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, 0x0); | |
130 | IXGBE_WRITE_FLUSH(hw); | |
131 | ||
82083673 JK |
132 | esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); |
133 | ||
134 | /* | |
db0677fa JK |
135 | * enable the SDP0 pin as output, and connected to the |
136 | * native function for Timesync (ClockOut) | |
82083673 JK |
137 | */ |
138 | esdp |= (IXGBE_ESDP_SDP0_DIR | | |
139 | IXGBE_ESDP_SDP0_NATIVE); | |
140 | ||
141 | /* | |
db0677fa JK |
142 | * enable the Clock Out feature on SDP0, and allow |
143 | * interrupts to occur when the pin changes | |
82083673 JK |
144 | */ |
145 | tsauxc = (IXGBE_TSAUXC_EN_CLK | | |
146 | IXGBE_TSAUXC_SYNCLK | | |
147 | IXGBE_TSAUXC_SDP0_INT); | |
148 | ||
149 | /* clock period (or pulse length) */ | |
150 | clktiml = (u32)(NSECS_PER_SEC << shift); | |
151 | clktimh = (u32)((NSECS_PER_SEC << shift) >> 32); | |
152 | ||
153 | /* | |
154 | * Account for the cyclecounter wrap-around value by | |
155 | * using the converted ns value of the current time to | |
156 | * check for when the next aligned second would occur. | |
157 | */ | |
158 | clock_edge |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIML); | |
159 | clock_edge |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIMH) << 32; | |
160 | ns = timecounter_cyc2time(&adapter->tc, clock_edge); | |
161 | ||
162 | div_u64_rem(ns, NSECS_PER_SEC, &rem); | |
163 | clock_edge += ((NSECS_PER_SEC - (u64)rem) << shift); | |
164 | ||
165 | /* specify the initial clock start time */ | |
166 | trgttiml = (u32)clock_edge; | |
167 | trgttimh = (u32)(clock_edge >> 32); | |
168 | ||
169 | IXGBE_WRITE_REG(hw, IXGBE_CLKTIML, clktiml); | |
170 | IXGBE_WRITE_REG(hw, IXGBE_CLKTIMH, clktimh); | |
171 | IXGBE_WRITE_REG(hw, IXGBE_TRGTTIML0, trgttiml); | |
172 | IXGBE_WRITE_REG(hw, IXGBE_TRGTTIMH0, trgttimh); | |
173 | ||
174 | IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); | |
175 | IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, tsauxc); | |
db0677fa JK |
176 | } else { |
177 | IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, 0x0); | |
82083673 | 178 | } |
82083673 | 179 | |
82083673 JK |
180 | IXGBE_WRITE_FLUSH(hw); |
181 | } | |
182 | ||
3a6a4eda JK |
183 | /** |
184 | * ixgbe_ptp_read - read raw cycle counter (to be used by time counter) | |
49ce9c2c | 185 | * @cc: the cyclecounter structure |
3a6a4eda JK |
186 | * |
187 | * this function reads the cyclecounter registers and is called by the | |
188 | * cyclecounter structure used to construct a ns counter from the | |
189 | * arbitrary fixed point registers | |
190 | */ | |
191 | static cycle_t ixgbe_ptp_read(const struct cyclecounter *cc) | |
192 | { | |
193 | struct ixgbe_adapter *adapter = | |
194 | container_of(cc, struct ixgbe_adapter, cc); | |
195 | struct ixgbe_hw *hw = &adapter->hw; | |
196 | u64 stamp = 0; | |
197 | ||
198 | stamp |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIML); | |
199 | stamp |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIMH) << 32; | |
200 | ||
201 | return stamp; | |
202 | } | |
203 | ||
204 | /** | |
205 | * ixgbe_ptp_adjfreq | |
49ce9c2c BH |
206 | * @ptp: the ptp clock structure |
207 | * @ppb: parts per billion adjustment from base | |
3a6a4eda JK |
208 | * |
209 | * adjust the frequency of the ptp cycle counter by the | |
210 | * indicated ppb from the base frequency. | |
211 | */ | |
212 | static int ixgbe_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) | |
213 | { | |
214 | struct ixgbe_adapter *adapter = | |
215 | container_of(ptp, struct ixgbe_adapter, ptp_caps); | |
216 | struct ixgbe_hw *hw = &adapter->hw; | |
217 | u64 freq; | |
218 | u32 diff, incval; | |
219 | int neg_adj = 0; | |
220 | ||
221 | if (ppb < 0) { | |
222 | neg_adj = 1; | |
223 | ppb = -ppb; | |
224 | } | |
225 | ||
226 | smp_mb(); | |
227 | incval = ACCESS_ONCE(adapter->base_incval); | |
228 | ||
229 | freq = incval; | |
230 | freq *= ppb; | |
231 | diff = div_u64(freq, 1000000000ULL); | |
232 | ||
233 | incval = neg_adj ? (incval - diff) : (incval + diff); | |
234 | ||
235 | switch (hw->mac.type) { | |
236 | case ixgbe_mac_X540: | |
237 | IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, incval); | |
238 | break; | |
239 | case ixgbe_mac_82599EB: | |
240 | IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, | |
241 | (1 << IXGBE_INCPER_SHIFT_82599) | | |
242 | incval); | |
243 | break; | |
244 | default: | |
245 | break; | |
246 | } | |
247 | ||
248 | return 0; | |
249 | } | |
250 | ||
251 | /** | |
252 | * ixgbe_ptp_adjtime | |
49ce9c2c BH |
253 | * @ptp: the ptp clock structure |
254 | * @delta: offset to adjust the cycle counter by | |
3a6a4eda JK |
255 | * |
256 | * adjust the timer by resetting the timecounter structure. | |
257 | */ | |
258 | static int ixgbe_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) | |
259 | { | |
260 | struct ixgbe_adapter *adapter = | |
261 | container_of(ptp, struct ixgbe_adapter, ptp_caps); | |
262 | unsigned long flags; | |
263 | u64 now; | |
264 | ||
265 | spin_lock_irqsave(&adapter->tmreg_lock, flags); | |
266 | ||
267 | now = timecounter_read(&adapter->tc); | |
268 | now += delta; | |
269 | ||
270 | /* reset the timecounter */ | |
271 | timecounter_init(&adapter->tc, | |
272 | &adapter->cc, | |
273 | now); | |
274 | ||
275 | spin_unlock_irqrestore(&adapter->tmreg_lock, flags); | |
db0677fa JK |
276 | |
277 | ixgbe_ptp_setup_sdp(adapter); | |
82083673 | 278 | |
3a6a4eda JK |
279 | return 0; |
280 | } | |
281 | ||
282 | /** | |
283 | * ixgbe_ptp_gettime | |
49ce9c2c BH |
284 | * @ptp: the ptp clock structure |
285 | * @ts: timespec structure to hold the current time value | |
3a6a4eda JK |
286 | * |
287 | * read the timecounter and return the correct value on ns, | |
288 | * after converting it into a struct timespec. | |
289 | */ | |
290 | static int ixgbe_ptp_gettime(struct ptp_clock_info *ptp, struct timespec *ts) | |
291 | { | |
292 | struct ixgbe_adapter *adapter = | |
293 | container_of(ptp, struct ixgbe_adapter, ptp_caps); | |
294 | u64 ns; | |
295 | u32 remainder; | |
296 | unsigned long flags; | |
297 | ||
298 | spin_lock_irqsave(&adapter->tmreg_lock, flags); | |
299 | ns = timecounter_read(&adapter->tc); | |
300 | spin_unlock_irqrestore(&adapter->tmreg_lock, flags); | |
301 | ||
302 | ts->tv_sec = div_u64_rem(ns, 1000000000ULL, &remainder); | |
303 | ts->tv_nsec = remainder; | |
304 | ||
305 | return 0; | |
306 | } | |
307 | ||
308 | /** | |
309 | * ixgbe_ptp_settime | |
49ce9c2c BH |
310 | * @ptp: the ptp clock structure |
311 | * @ts: the timespec containing the new time for the cycle counter | |
3a6a4eda JK |
312 | * |
313 | * reset the timecounter to use a new base value instead of the kernel | |
314 | * wall timer value. | |
315 | */ | |
316 | static int ixgbe_ptp_settime(struct ptp_clock_info *ptp, | |
317 | const struct timespec *ts) | |
318 | { | |
319 | struct ixgbe_adapter *adapter = | |
320 | container_of(ptp, struct ixgbe_adapter, ptp_caps); | |
321 | u64 ns; | |
322 | unsigned long flags; | |
323 | ||
324 | ns = ts->tv_sec * 1000000000ULL; | |
325 | ns += ts->tv_nsec; | |
326 | ||
327 | /* reset the timecounter */ | |
328 | spin_lock_irqsave(&adapter->tmreg_lock, flags); | |
329 | timecounter_init(&adapter->tc, &adapter->cc, ns); | |
330 | spin_unlock_irqrestore(&adapter->tmreg_lock, flags); | |
331 | ||
db0677fa | 332 | ixgbe_ptp_setup_sdp(adapter); |
3a6a4eda JK |
333 | return 0; |
334 | } | |
335 | ||
336 | /** | |
337 | * ixgbe_ptp_enable | |
49ce9c2c BH |
338 | * @ptp: the ptp clock structure |
339 | * @rq: the requested feature to change | |
340 | * @on: whether to enable or disable the feature | |
3a6a4eda JK |
341 | * |
342 | * enable (or disable) ancillary features of the phc subsystem. | |
681ae1ad | 343 | * our driver only supports the PPS feature on the X540 |
3a6a4eda JK |
344 | */ |
345 | static int ixgbe_ptp_enable(struct ptp_clock_info *ptp, | |
346 | struct ptp_clock_request *rq, int on) | |
347 | { | |
681ae1ad JK |
348 | struct ixgbe_adapter *adapter = |
349 | container_of(ptp, struct ixgbe_adapter, ptp_caps); | |
350 | ||
351 | /** | |
352 | * When PPS is enabled, unmask the interrupt for the ClockOut | |
353 | * feature, so that the interrupt handler can send the PPS | |
354 | * event when the clock SDP triggers. Clear mask when PPS is | |
355 | * disabled | |
356 | */ | |
357 | if (rq->type == PTP_CLK_REQ_PPS) { | |
358 | switch (adapter->hw.mac.type) { | |
359 | case ixgbe_mac_X540: | |
360 | if (on) | |
361 | adapter->flags2 |= IXGBE_FLAG2_PTP_PPS_ENABLED; | |
362 | else | |
db0677fa JK |
363 | adapter->flags2 &= ~IXGBE_FLAG2_PTP_PPS_ENABLED; |
364 | ||
365 | ixgbe_ptp_setup_sdp(adapter); | |
681ae1ad JK |
366 | return 0; |
367 | default: | |
368 | break; | |
369 | } | |
370 | } | |
371 | ||
3a6a4eda JK |
372 | return -ENOTSUPP; |
373 | } | |
374 | ||
681ae1ad JK |
375 | /** |
376 | * ixgbe_ptp_check_pps_event | |
49ce9c2c BH |
377 | * @adapter: the private adapter structure |
378 | * @eicr: the interrupt cause register value | |
681ae1ad JK |
379 | * |
380 | * This function is called by the interrupt routine when checking for | |
381 | * interrupts. It will check and handle a pps event. | |
382 | */ | |
383 | void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr) | |
384 | { | |
385 | struct ixgbe_hw *hw = &adapter->hw; | |
386 | struct ptp_clock_event event; | |
387 | ||
3645adbb JK |
388 | event.type = PTP_CLOCK_PPS; |
389 | ||
390 | /* this check is necessary in case the interrupt was enabled via some | |
391 | * alternative means (ex. debug_fs). Better to check here than | |
392 | * everywhere that calls this function. | |
393 | */ | |
394 | if (!adapter->ptp_clock) | |
395 | return; | |
396 | ||
db0677fa JK |
397 | switch (hw->mac.type) { |
398 | case ixgbe_mac_X540: | |
399 | ptp_clock_event(adapter->ptp_clock, &event); | |
400 | break; | |
401 | default: | |
402 | break; | |
681ae1ad JK |
403 | } |
404 | } | |
405 | ||
3a6a4eda | 406 | /** |
f2f33387 JK |
407 | * ixgbe_ptp_overflow_check - watchdog task to detect SYSTIME overflow |
408 | * @adapter: private adapter struct | |
3a6a4eda | 409 | * |
f2f33387 | 410 | * this watchdog task periodically reads the timecounter |
3a6a4eda | 411 | * in order to prevent missing when the system time registers wrap |
f2f33387 | 412 | * around. This needs to be run approximately twice a minute. |
3a6a4eda JK |
413 | */ |
414 | void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter) | |
415 | { | |
f2f33387 JK |
416 | bool timeout = time_is_before_jiffies(adapter->last_overflow_check + |
417 | IXGBE_OVERFLOW_PERIOD); | |
3a6a4eda JK |
418 | struct timespec ts; |
419 | ||
891dc082 | 420 | if (timeout) { |
3a6a4eda JK |
421 | ixgbe_ptp_gettime(&adapter->ptp_caps, &ts); |
422 | adapter->last_overflow_check = jiffies; | |
423 | } | |
424 | } | |
425 | ||
1d1a79b5 | 426 | /** |
6cb562d6 JK |
427 | * ixgbe_ptp_rx_hang - detect error case when Rx timestamp registers latched |
428 | * @adapter: private network adapter structure | |
1d1a79b5 | 429 | * |
6cb562d6 JK |
430 | * this watchdog task is scheduled to detect error case where hardware has |
431 | * dropped an Rx packet that was timestamped when the ring is full. The | |
432 | * particular error is rare but leaves the device in a state unable to timestamp | |
433 | * any future packets. | |
1d1a79b5 | 434 | */ |
6cb562d6 | 435 | void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter) |
1d1a79b5 | 436 | { |
6cb562d6 JK |
437 | struct ixgbe_hw *hw = &adapter->hw; |
438 | struct ixgbe_ring *rx_ring; | |
439 | u32 tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL); | |
440 | unsigned long rx_event; | |
441 | int n; | |
1d1a79b5 | 442 | |
6cb562d6 JK |
443 | /* if we don't have a valid timestamp in the registers, just update the |
444 | * timeout counter and exit | |
445 | */ | |
446 | if (!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID)) { | |
447 | adapter->last_rx_ptp_check = jiffies; | |
448 | return; | |
1d1a79b5 JK |
449 | } |
450 | ||
6cb562d6 JK |
451 | /* determine the most recent watchdog or rx_timestamp event */ |
452 | rx_event = adapter->last_rx_ptp_check; | |
453 | for (n = 0; n < adapter->num_rx_queues; n++) { | |
454 | rx_ring = adapter->rx_ring[n]; | |
455 | if (time_after(rx_ring->last_rx_timestamp, rx_event)) | |
456 | rx_event = rx_ring->last_rx_timestamp; | |
457 | } | |
1d1a79b5 | 458 | |
6cb562d6 JK |
459 | /* only need to read the high RXSTMP register to clear the lock */ |
460 | if (time_is_before_jiffies(rx_event + 5*HZ)) { | |
461 | IXGBE_READ_REG(hw, IXGBE_RXSTMPH); | |
462 | adapter->last_rx_ptp_check = jiffies; | |
1d1a79b5 | 463 | |
6cb562d6 | 464 | e_warn(drv, "clearing RX Timestamp hang"); |
1d1a79b5 JK |
465 | } |
466 | } | |
467 | ||
3a6a4eda JK |
468 | /** |
469 | * ixgbe_ptp_tx_hwtstamp - utility function which checks for TX time stamp | |
891dc082 | 470 | * @adapter: the private adapter struct |
3a6a4eda JK |
471 | * |
472 | * if the timestamp is valid, we convert it into the timecounter ns | |
473 | * value, then store that result into the shhwtstamps structure which | |
474 | * is passed up the network stack | |
475 | */ | |
891dc082 | 476 | static void ixgbe_ptp_tx_hwtstamp(struct ixgbe_adapter *adapter) |
3a6a4eda | 477 | { |
891dc082 | 478 | struct ixgbe_hw *hw = &adapter->hw; |
3a6a4eda JK |
479 | struct skb_shared_hwtstamps shhwtstamps; |
480 | u64 regval = 0, ns; | |
3a6a4eda JK |
481 | unsigned long flags; |
482 | ||
3a6a4eda JK |
483 | regval |= (u64)IXGBE_READ_REG(hw, IXGBE_TXSTMPL); |
484 | regval |= (u64)IXGBE_READ_REG(hw, IXGBE_TXSTMPH) << 32; | |
485 | ||
3a6a4eda JK |
486 | spin_lock_irqsave(&adapter->tmreg_lock, flags); |
487 | ns = timecounter_cyc2time(&adapter->tc, regval); | |
488 | spin_unlock_irqrestore(&adapter->tmreg_lock, flags); | |
489 | ||
490 | memset(&shhwtstamps, 0, sizeof(shhwtstamps)); | |
491 | shhwtstamps.hwtstamp = ns_to_ktime(ns); | |
891dc082 JK |
492 | skb_tstamp_tx(adapter->ptp_tx_skb, &shhwtstamps); |
493 | ||
494 | dev_kfree_skb_any(adapter->ptp_tx_skb); | |
495 | adapter->ptp_tx_skb = NULL; | |
496 | } | |
497 | ||
498 | /** | |
499 | * ixgbe_ptp_tx_hwtstamp_work | |
500 | * @work: pointer to the work struct | |
501 | * | |
502 | * This work item polls TSYNCTXCTL valid bit to determine when a Tx hardware | |
503 | * timestamp has been taken for the current skb. It is necesary, because the | |
504 | * descriptor's "done" bit does not correlate with the timestamp event. | |
505 | */ | |
506 | static void ixgbe_ptp_tx_hwtstamp_work(struct work_struct *work) | |
507 | { | |
508 | struct ixgbe_adapter *adapter = container_of(work, struct ixgbe_adapter, | |
509 | ptp_tx_work); | |
510 | struct ixgbe_hw *hw = &adapter->hw; | |
511 | bool timeout = time_is_before_jiffies(adapter->ptp_tx_start + | |
512 | IXGBE_PTP_TX_TIMEOUT); | |
513 | u32 tsynctxctl; | |
514 | ||
515 | /* we have to have a valid skb */ | |
516 | if (!adapter->ptp_tx_skb) | |
517 | return; | |
518 | ||
519 | if (timeout) { | |
520 | dev_kfree_skb_any(adapter->ptp_tx_skb); | |
521 | adapter->ptp_tx_skb = NULL; | |
522 | e_warn(drv, "clearing Tx Timestamp hang"); | |
523 | return; | |
524 | } | |
525 | ||
526 | tsynctxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCTXCTL); | |
527 | if (tsynctxctl & IXGBE_TSYNCTXCTL_VALID) | |
528 | ixgbe_ptp_tx_hwtstamp(adapter); | |
529 | else | |
530 | /* reschedule to keep checking if it's not available yet */ | |
531 | schedule_work(&adapter->ptp_tx_work); | |
3a6a4eda JK |
532 | } |
533 | ||
534 | /** | |
39dfb71b | 535 | * __ixgbe_ptp_rx_hwtstamp - utility function which checks for RX time stamp |
3a6a4eda JK |
536 | * @q_vector: structure containing interrupt and ring information |
537 | * @skb: particular skb to send timestamp with | |
538 | * | |
539 | * if the timestamp is valid, we convert it into the timecounter ns | |
540 | * value, then store that result into the shhwtstamps structure which | |
541 | * is passed up the network stack | |
542 | */ | |
39dfb71b AD |
543 | void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, |
544 | struct sk_buff *skb) | |
3a6a4eda JK |
545 | { |
546 | struct ixgbe_adapter *adapter; | |
547 | struct ixgbe_hw *hw; | |
548 | struct skb_shared_hwtstamps *shhwtstamps; | |
549 | u64 regval = 0, ns; | |
550 | u32 tsyncrxctl; | |
551 | unsigned long flags; | |
552 | ||
553 | /* we cannot process timestamps on a ring without a q_vector */ | |
39dfb71b | 554 | if (!q_vector || !q_vector->adapter) |
3a6a4eda JK |
555 | return; |
556 | ||
39dfb71b | 557 | adapter = q_vector->adapter; |
3a6a4eda JK |
558 | hw = &adapter->hw; |
559 | ||
6cb562d6 JK |
560 | /* |
561 | * Read the tsyncrxctl register afterwards in order to prevent taking an | |
562 | * I/O hit on every packet. | |
563 | */ | |
3a6a4eda | 564 | tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL); |
f42df167 | 565 | if (!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID)) |
1d1a79b5 JK |
566 | return; |
567 | ||
3a6a4eda JK |
568 | regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPL); |
569 | regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPH) << 32; | |
570 | ||
3a6a4eda JK |
571 | |
572 | spin_lock_irqsave(&adapter->tmreg_lock, flags); | |
573 | ns = timecounter_cyc2time(&adapter->tc, regval); | |
574 | spin_unlock_irqrestore(&adapter->tmreg_lock, flags); | |
575 | ||
576 | shhwtstamps = skb_hwtstamps(skb); | |
577 | shhwtstamps->hwtstamp = ns_to_ktime(ns); | |
578 | } | |
579 | ||
93501d48 JK |
580 | int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr) |
581 | { | |
582 | struct hwtstamp_config *config = &adapter->tstamp_config; | |
583 | ||
584 | return copy_to_user(ifr->ifr_data, config, | |
585 | sizeof(*config)) ? -EFAULT : 0; | |
586 | } | |
587 | ||
3a6a4eda | 588 | /** |
93501d48 | 589 | * ixgbe_ptp_set_ts_config - control hardware time stamping |
3a6a4eda JK |
590 | * @adapter: pointer to adapter struct |
591 | * @ifreq: ioctl data | |
3a6a4eda JK |
592 | * |
593 | * Outgoing time stamping can be enabled and disabled. Play nice and | |
93501d48 | 594 | * disable it when requested, although it shouldn't cause any overhead |
3a6a4eda JK |
595 | * when no packet needs it. At most one packet in the queue may be |
596 | * marked for time stamping, otherwise it would be impossible to tell | |
597 | * for sure to which packet the hardware time stamp belongs. | |
598 | * | |
599 | * Incoming time stamping has to be configured via the hardware | |
600 | * filters. Not all combinations are supported, in particular event | |
601 | * type has to be specified. Matching the kind of event packet is | |
602 | * not supported, with the exception of "all V2 events regardless of | |
603 | * level 2 or 4". | |
c19197a7 JK |
604 | * |
605 | * Since hardware always timestamps Path delay packets when timestamping V2 | |
606 | * packets, regardless of the type specified in the register, only use V2 | |
607 | * Event mode. This more accurately tells the user what the hardware is going | |
608 | * to do anyways. | |
3a6a4eda | 609 | */ |
93501d48 | 610 | int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr) |
3a6a4eda JK |
611 | { |
612 | struct ixgbe_hw *hw = &adapter->hw; | |
613 | struct hwtstamp_config config; | |
614 | u32 tsync_tx_ctl = IXGBE_TSYNCTXCTL_ENABLED; | |
615 | u32 tsync_rx_ctl = IXGBE_TSYNCRXCTL_ENABLED; | |
f3444d8b | 616 | u32 tsync_rx_mtrl = PTP_EV_PORT << 16; |
3a6a4eda JK |
617 | bool is_l2 = false; |
618 | u32 regval; | |
619 | ||
620 | if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) | |
621 | return -EFAULT; | |
622 | ||
623 | /* reserved for future extensions */ | |
624 | if (config.flags) | |
625 | return -EINVAL; | |
626 | ||
627 | switch (config.tx_type) { | |
628 | case HWTSTAMP_TX_OFF: | |
629 | tsync_tx_ctl = 0; | |
630 | case HWTSTAMP_TX_ON: | |
631 | break; | |
632 | default: | |
633 | return -ERANGE; | |
634 | } | |
635 | ||
636 | switch (config.rx_filter) { | |
637 | case HWTSTAMP_FILTER_NONE: | |
638 | tsync_rx_ctl = 0; | |
f3444d8b | 639 | tsync_rx_mtrl = 0; |
3a6a4eda JK |
640 | break; |
641 | case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: | |
642 | tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; | |
b1e50f7a | 643 | tsync_rx_mtrl |= IXGBE_RXMTRL_V1_SYNC_MSG; |
3a6a4eda JK |
644 | break; |
645 | case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: | |
646 | tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; | |
b1e50f7a | 647 | tsync_rx_mtrl |= IXGBE_RXMTRL_V1_DELAY_REQ_MSG; |
3a6a4eda | 648 | break; |
c19197a7 JK |
649 | case HWTSTAMP_FILTER_PTP_V2_EVENT: |
650 | case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: | |
651 | case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: | |
3a6a4eda JK |
652 | case HWTSTAMP_FILTER_PTP_V2_SYNC: |
653 | case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: | |
654 | case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: | |
3a6a4eda JK |
655 | case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: |
656 | case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: | |
657 | case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: | |
3a6a4eda | 658 | tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_EVENT_V2; |
3a6a4eda | 659 | is_l2 = true; |
1d1a79b5 | 660 | config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; |
3a6a4eda JK |
661 | break; |
662 | case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: | |
663 | case HWTSTAMP_FILTER_ALL: | |
664 | default: | |
665 | /* | |
1d1a79b5 JK |
666 | * register RXMTRL must be set in order to do V1 packets, |
667 | * therefore it is not possible to time stamp both V1 Sync and | |
668 | * Delay_Req messages and hardware does not support | |
669 | * timestamping all packets => return error | |
3a6a4eda | 670 | */ |
1d1a79b5 | 671 | config.rx_filter = HWTSTAMP_FILTER_NONE; |
3a6a4eda JK |
672 | return -ERANGE; |
673 | } | |
674 | ||
675 | if (hw->mac.type == ixgbe_mac_82598EB) { | |
676 | if (tsync_rx_ctl | tsync_tx_ctl) | |
677 | return -ERANGE; | |
678 | return 0; | |
679 | } | |
680 | ||
6ccf7a57 | 681 | /* define ethertype filter for timestamping L2 packets */ |
3a6a4eda | 682 | if (is_l2) |
6ccf7a57 | 683 | IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_1588), |
3a6a4eda JK |
684 | (IXGBE_ETQF_FILTER_EN | /* enable filter */ |
685 | IXGBE_ETQF_1588 | /* enable timestamping */ | |
686 | ETH_P_1588)); /* 1588 eth protocol type */ | |
687 | else | |
6ccf7a57 | 688 | IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_1588), 0); |
3a6a4eda | 689 | |
3a6a4eda JK |
690 | |
691 | /* enable/disable TX */ | |
692 | regval = IXGBE_READ_REG(hw, IXGBE_TSYNCTXCTL); | |
693 | regval &= ~IXGBE_TSYNCTXCTL_ENABLED; | |
694 | regval |= tsync_tx_ctl; | |
695 | IXGBE_WRITE_REG(hw, IXGBE_TSYNCTXCTL, regval); | |
696 | ||
697 | /* enable/disable RX */ | |
698 | regval = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL); | |
699 | regval &= ~(IXGBE_TSYNCRXCTL_ENABLED | IXGBE_TSYNCRXCTL_TYPE_MASK); | |
700 | regval |= tsync_rx_ctl; | |
701 | IXGBE_WRITE_REG(hw, IXGBE_TSYNCRXCTL, regval); | |
702 | ||
703 | /* define which PTP packets are time stamped */ | |
704 | IXGBE_WRITE_REG(hw, IXGBE_RXMTRL, tsync_rx_mtrl); | |
705 | ||
706 | IXGBE_WRITE_FLUSH(hw); | |
707 | ||
708 | /* clear TX/RX time stamp registers, just to be sure */ | |
709 | regval = IXGBE_READ_REG(hw, IXGBE_TXSTMPH); | |
710 | regval = IXGBE_READ_REG(hw, IXGBE_RXSTMPH); | |
711 | ||
93501d48 JK |
712 | /* save these settings for future reference */ |
713 | memcpy(&adapter->tstamp_config, &config, | |
714 | sizeof(adapter->tstamp_config)); | |
715 | ||
3a6a4eda JK |
716 | return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? |
717 | -EFAULT : 0; | |
718 | } | |
719 | ||
720 | /** | |
721 | * ixgbe_ptp_start_cyclecounter - create the cycle counter from hw | |
49ce9c2c | 722 | * @adapter: pointer to the adapter structure |
3a6a4eda | 723 | * |
1a71ab24 JK |
724 | * This function should be called to set the proper values for the TIMINCA |
725 | * register and tell the cyclecounter structure what the tick rate of SYSTIME | |
726 | * is. It does not directly modify SYSTIME registers or the timecounter | |
727 | * structure. It should be called whenever a new TIMINCA value is necessary, | |
728 | * such as during initialization or when the link speed changes. | |
3a6a4eda JK |
729 | */ |
730 | void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) | |
731 | { | |
732 | struct ixgbe_hw *hw = &adapter->hw; | |
733 | u32 incval = 0; | |
734 | u32 shift = 0; | |
3a6a4eda JK |
735 | unsigned long flags; |
736 | ||
3a6a4eda JK |
737 | /** |
738 | * Scale the NIC cycle counter by a large factor so that | |
739 | * relatively small corrections to the frequency can be added | |
740 | * or subtracted. The drawbacks of a large factor include | |
741 | * (a) the clock register overflows more quickly, (b) the cycle | |
742 | * counter structure must be able to convert the systime value | |
743 | * to nanoseconds using only a multiplier and a right-shift, | |
744 | * and (c) the value must fit within the timinca register space | |
745 | * => math based on internal DMA clock rate and available bits | |
1a71ab24 JK |
746 | * |
747 | * Note that when there is no link, internal DMA clock is same as when | |
748 | * link speed is 10Gb. Set the registers correctly even when link is | |
749 | * down to preserve the clock setting | |
3a6a4eda | 750 | */ |
1a71ab24 | 751 | switch (adapter->link_speed) { |
3a6a4eda JK |
752 | case IXGBE_LINK_SPEED_100_FULL: |
753 | incval = IXGBE_INCVAL_100; | |
754 | shift = IXGBE_INCVAL_SHIFT_100; | |
755 | break; | |
756 | case IXGBE_LINK_SPEED_1GB_FULL: | |
757 | incval = IXGBE_INCVAL_1GB; | |
758 | shift = IXGBE_INCVAL_SHIFT_1GB; | |
759 | break; | |
760 | case IXGBE_LINK_SPEED_10GB_FULL: | |
1a71ab24 | 761 | default: |
3a6a4eda JK |
762 | incval = IXGBE_INCVAL_10GB; |
763 | shift = IXGBE_INCVAL_SHIFT_10GB; | |
764 | break; | |
765 | } | |
766 | ||
767 | /** | |
768 | * Modify the calculated values to fit within the correct | |
769 | * number of bits specified by the hardware. The 82599 doesn't | |
770 | * have the same space as the X540, so bitshift the calculated | |
771 | * values to fit. | |
772 | */ | |
773 | switch (hw->mac.type) { | |
774 | case ixgbe_mac_X540: | |
775 | IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, incval); | |
776 | break; | |
777 | case ixgbe_mac_82599EB: | |
778 | incval >>= IXGBE_INCVAL_SHIFT_82599; | |
779 | shift -= IXGBE_INCVAL_SHIFT_82599; | |
780 | IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, | |
781 | (1 << IXGBE_INCPER_SHIFT_82599) | | |
782 | incval); | |
783 | break; | |
784 | default: | |
785 | /* other devices aren't supported */ | |
786 | return; | |
787 | } | |
788 | ||
1a71ab24 | 789 | /* update the base incval used to calculate frequency adjustment */ |
3a6a4eda JK |
790 | ACCESS_ONCE(adapter->base_incval) = incval; |
791 | smp_mb(); | |
792 | ||
1a71ab24 | 793 | /* need lock to prevent incorrect read while modifying cyclecounter */ |
3a6a4eda JK |
794 | spin_lock_irqsave(&adapter->tmreg_lock, flags); |
795 | ||
796 | memset(&adapter->cc, 0, sizeof(adapter->cc)); | |
797 | adapter->cc.read = ixgbe_ptp_read; | |
798 | adapter->cc.mask = CLOCKSOURCE_MASK(64); | |
799 | adapter->cc.shift = shift; | |
800 | adapter->cc.mult = 1; | |
801 | ||
1a71ab24 JK |
802 | spin_unlock_irqrestore(&adapter->tmreg_lock, flags); |
803 | } | |
804 | ||
805 | /** | |
806 | * ixgbe_ptp_reset | |
807 | * @adapter: the ixgbe private board structure | |
808 | * | |
809 | * When the MAC resets, all timesync features are reset. This function should be | |
810 | * called to re-enable the PTP clock structure. It will re-init the timecounter | |
811 | * structure based on the kernel time as well as setup the cycle counter data. | |
812 | */ | |
813 | void ixgbe_ptp_reset(struct ixgbe_adapter *adapter) | |
814 | { | |
815 | struct ixgbe_hw *hw = &adapter->hw; | |
816 | unsigned long flags; | |
817 | ||
818 | /* set SYSTIME registers to 0 just in case */ | |
819 | IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0x00000000); | |
820 | IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0x00000000); | |
821 | IXGBE_WRITE_FLUSH(hw); | |
822 | ||
93501d48 JK |
823 | /* Reset the saved tstamp_config */ |
824 | memset(&adapter->tstamp_config, 0, sizeof(adapter->tstamp_config)); | |
825 | ||
1a71ab24 JK |
826 | ixgbe_ptp_start_cyclecounter(adapter); |
827 | ||
828 | spin_lock_irqsave(&adapter->tmreg_lock, flags); | |
829 | ||
3a6a4eda JK |
830 | /* reset the ns time counter */ |
831 | timecounter_init(&adapter->tc, &adapter->cc, | |
832 | ktime_to_ns(ktime_get_real())); | |
833 | ||
834 | spin_unlock_irqrestore(&adapter->tmreg_lock, flags); | |
82083673 | 835 | |
db0677fa JK |
836 | /* |
837 | * Now that the shift has been calculated and the systime | |
82083673 JK |
838 | * registers reset, (re-)enable the Clock out feature |
839 | */ | |
db0677fa | 840 | ixgbe_ptp_setup_sdp(adapter); |
3a6a4eda JK |
841 | } |
842 | ||
843 | /** | |
844 | * ixgbe_ptp_init | |
49ce9c2c | 845 | * @adapter: the ixgbe private adapter structure |
3a6a4eda JK |
846 | * |
847 | * This function performs the required steps for enabling ptp | |
848 | * support. If ptp support has already been loaded it simply calls the | |
849 | * cyclecounter init routine and exits. | |
850 | */ | |
851 | void ixgbe_ptp_init(struct ixgbe_adapter *adapter) | |
852 | { | |
853 | struct net_device *netdev = adapter->netdev; | |
854 | ||
855 | switch (adapter->hw.mac.type) { | |
856 | case ixgbe_mac_X540: | |
ca324099 JK |
857 | snprintf(adapter->ptp_caps.name, |
858 | sizeof(adapter->ptp_caps.name), | |
859 | "%s", netdev->name); | |
681ae1ad JK |
860 | adapter->ptp_caps.owner = THIS_MODULE; |
861 | adapter->ptp_caps.max_adj = 250000000; | |
862 | adapter->ptp_caps.n_alarm = 0; | |
863 | adapter->ptp_caps.n_ext_ts = 0; | |
864 | adapter->ptp_caps.n_per_out = 0; | |
865 | adapter->ptp_caps.pps = 1; | |
866 | adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq; | |
867 | adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime; | |
868 | adapter->ptp_caps.gettime = ixgbe_ptp_gettime; | |
869 | adapter->ptp_caps.settime = ixgbe_ptp_settime; | |
870 | adapter->ptp_caps.enable = ixgbe_ptp_enable; | |
871 | break; | |
3a6a4eda | 872 | case ixgbe_mac_82599EB: |
ca324099 JK |
873 | snprintf(adapter->ptp_caps.name, |
874 | sizeof(adapter->ptp_caps.name), | |
875 | "%s", netdev->name); | |
3a6a4eda JK |
876 | adapter->ptp_caps.owner = THIS_MODULE; |
877 | adapter->ptp_caps.max_adj = 250000000; | |
878 | adapter->ptp_caps.n_alarm = 0; | |
879 | adapter->ptp_caps.n_ext_ts = 0; | |
880 | adapter->ptp_caps.n_per_out = 0; | |
881 | adapter->ptp_caps.pps = 0; | |
882 | adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq; | |
883 | adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime; | |
884 | adapter->ptp_caps.gettime = ixgbe_ptp_gettime; | |
885 | adapter->ptp_caps.settime = ixgbe_ptp_settime; | |
886 | adapter->ptp_caps.enable = ixgbe_ptp_enable; | |
887 | break; | |
888 | default: | |
889 | adapter->ptp_clock = NULL; | |
890 | return; | |
891 | } | |
892 | ||
893 | spin_lock_init(&adapter->tmreg_lock); | |
891dc082 | 894 | INIT_WORK(&adapter->ptp_tx_work, ixgbe_ptp_tx_hwtstamp_work); |
3a6a4eda | 895 | |
1ef76158 RC |
896 | adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps, |
897 | &adapter->pdev->dev); | |
3a6a4eda JK |
898 | if (IS_ERR(adapter->ptp_clock)) { |
899 | adapter->ptp_clock = NULL; | |
900 | e_dev_err("ptp_clock_register failed\n"); | |
901 | } else | |
902 | e_dev_info("registered PHC device on %s\n", netdev->name); | |
903 | ||
1a71ab24 JK |
904 | ixgbe_ptp_reset(adapter); |
905 | ||
8fecf67c JK |
906 | /* enter the IXGBE_PTP_RUNNING state */ |
907 | set_bit(__IXGBE_PTP_RUNNING, &adapter->state); | |
1a71ab24 | 908 | |
3a6a4eda JK |
909 | return; |
910 | } | |
911 | ||
912 | /** | |
913 | * ixgbe_ptp_stop - disable ptp device and stop the overflow check | |
914 | * @adapter: pointer to adapter struct | |
915 | * | |
916 | * this function stops the ptp support, and cancels the delayed work. | |
917 | */ | |
918 | void ixgbe_ptp_stop(struct ixgbe_adapter *adapter) | |
919 | { | |
8fecf67c JK |
920 | /* Leave the IXGBE_PTP_RUNNING state. */ |
921 | if (!test_and_clear_bit(__IXGBE_PTP_RUNNING, &adapter->state)) | |
922 | return; | |
db0677fa | 923 | |
8fecf67c JK |
924 | /* stop the PPS signal */ |
925 | adapter->flags2 &= ~IXGBE_FLAG2_PTP_PPS_ENABLED; | |
db0677fa | 926 | ixgbe_ptp_setup_sdp(adapter); |
3a6a4eda | 927 | |
891dc082 JK |
928 | cancel_work_sync(&adapter->ptp_tx_work); |
929 | if (adapter->ptp_tx_skb) { | |
930 | dev_kfree_skb_any(adapter->ptp_tx_skb); | |
931 | adapter->ptp_tx_skb = NULL; | |
932 | } | |
933 | ||
3a6a4eda JK |
934 | if (adapter->ptp_clock) { |
935 | ptp_clock_unregister(adapter->ptp_clock); | |
936 | adapter->ptp_clock = NULL; | |
937 | e_dev_info("removed PHC on %s\n", | |
938 | adapter->netdev->name); | |
939 | } | |
940 | } |