1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* Copyright(c) 2013 - 2018 Intel Corporation. */ |
3 | |
4 | #include <linux/ptp_classify.h> |
5 | #include <linux/posix-clock.h> |
6 | #include "i40e.h" |
7 | #include "i40e_devids.h" |
8 | |
9 | /* The XL710 timesync is very much like Intel's 82599 design when it comes to |
10 | * the fundamental clock design. However, the clock operations are much simpler |
11 | * in the XL710 because the device supports a full 64 bits of nanoseconds. |
12 | * Because the field is so wide, we can forgo the cycle counter and just |
13 | * operate with the nanosecond field directly without fear of overflow. |
14 | * |
15 | * Much like the 82599, the update period is dependent upon the link speed: |
16 | * At 40Gb, 25Gb, or no link, the period is 1.6ns. |
17 | * At 10Gb or 5Gb link, the period is multiplied by 2. (3.2ns) |
18 | * At 1Gb link, the period is multiplied by 20. (32ns) |
19 | * 1588 functionality is not supported at 100Mbps. |
20 | */ |
21 | #define I40E_PTP_40GB_INCVAL 0x0199999999ULL |
22 | #define I40E_PTP_10GB_INCVAL_MULT 2 |
23 | #define I40E_PTP_5GB_INCVAL_MULT 2 |
24 | #define I40E_PTP_1GB_INCVAL_MULT 20 |
25 | #define I40E_ISGN 0x80000000 |
26 | |
27 | #define I40E_PRTTSYN_CTL1_TSYNTYPE_V1 BIT(I40E_PRTTSYN_CTL1_TSYNTYPE_SHIFT) |
28 | #define I40E_PRTTSYN_CTL1_TSYNTYPE_V2 (2 << \ |
29 | I40E_PRTTSYN_CTL1_TSYNTYPE_SHIFT) |
30 | #define I40E_SUBDEV_ID_25G_PTP_PIN 0xB |
31 | |
32 | enum i40e_ptp_pin { |
33 | SDP3_2 = 0, |
34 | SDP3_3, |
35 | GPIO_4 |
36 | }; |
37 | |
38 | enum i40e_can_set_pins { |
39 | CANT_DO_PINS = -1, |
40 | CAN_SET_PINS, |
41 | CAN_DO_PINS |
42 | }; |
43 | |
44 | static struct ptp_pin_desc sdp_desc[] = { |
45 | /* name idx func chan */ |
46 | {"SDP3_2" , SDP3_2, PTP_PF_NONE, 0}, |
47 | {"SDP3_3" , SDP3_3, PTP_PF_NONE, 1}, |
48 | {"GPIO_4" , GPIO_4, PTP_PF_NONE, 1}, |
49 | }; |
50 | |
51 | enum i40e_ptp_gpio_pin_state { |
52 | end = -2, |
53 | invalid, |
54 | off, |
55 | in_A, |
56 | in_B, |
57 | out_A, |
58 | out_B, |
59 | }; |
60 | |
61 | static const char * const i40e_ptp_gpio_pin_state2str[] = { |
62 | "off" , "in_A" , "in_B" , "out_A" , "out_B" |
63 | }; |
64 | |
65 | enum i40e_ptp_led_pin_state { |
66 | led_end = -2, |
67 | low = 0, |
68 | high, |
69 | }; |
70 | |
71 | struct i40e_ptp_pins_settings { |
72 | enum i40e_ptp_gpio_pin_state sdp3_2; |
73 | enum i40e_ptp_gpio_pin_state sdp3_3; |
74 | enum i40e_ptp_gpio_pin_state gpio_4; |
75 | enum i40e_ptp_led_pin_state led2_0; |
76 | enum i40e_ptp_led_pin_state led2_1; |
77 | enum i40e_ptp_led_pin_state led3_0; |
78 | enum i40e_ptp_led_pin_state led3_1; |
79 | }; |
80 | |
81 | static const struct i40e_ptp_pins_settings |
82 | i40e_ptp_pin_led_allowed_states[] = { |
83 | {off, off, off, high, high, high, high}, |
84 | {off, in_A, off, high, high, high, low}, |
85 | {off, out_A, off, high, low, high, high}, |
86 | {off, in_B, off, high, high, high, low}, |
87 | {off, out_B, off, high, low, high, high}, |
88 | {in_A, off, off, high, high, high, low}, |
89 | {in_A, in_B, off, high, high, high, low}, |
90 | {in_A, out_B, off, high, low, high, high}, |
91 | {out_A, off, off, high, low, high, high}, |
92 | {out_A, in_B, off, high, low, high, high}, |
93 | {in_B, off, off, high, high, high, low}, |
94 | {in_B, in_A, off, high, high, high, low}, |
95 | {in_B, out_A, off, high, low, high, high}, |
96 | {out_B, off, off, high, low, high, high}, |
97 | {out_B, in_A, off, high, low, high, high}, |
98 | {off, off, in_A, high, high, low, high}, |
99 | {off, out_A, in_A, high, low, low, high}, |
100 | {off, in_B, in_A, high, high, low, low}, |
101 | {off, out_B, in_A, high, low, low, high}, |
102 | {out_A, off, in_A, high, low, low, high}, |
103 | {out_A, in_B, in_A, high, low, low, high}, |
104 | {in_B, off, in_A, high, high, low, low}, |
105 | {in_B, out_A, in_A, high, low, low, high}, |
106 | {out_B, off, in_A, high, low, low, high}, |
107 | {off, off, out_A, low, high, high, high}, |
108 | {off, in_A, out_A, low, high, high, low}, |
109 | {off, in_B, out_A, low, high, high, low}, |
110 | {off, out_B, out_A, low, low, high, high}, |
111 | {in_A, off, out_A, low, high, high, low}, |
112 | {in_A, in_B, out_A, low, high, high, low}, |
113 | {in_A, out_B, out_A, low, low, high, high}, |
114 | {in_B, off, out_A, low, high, high, low}, |
115 | {in_B, in_A, out_A, low, high, high, low}, |
116 | {out_B, off, out_A, low, low, high, high}, |
117 | {out_B, in_A, out_A, low, low, high, high}, |
118 | {off, off, in_B, high, high, low, high}, |
119 | {off, in_A, in_B, high, high, low, low}, |
120 | {off, out_A, in_B, high, low, low, high}, |
121 | {off, out_B, in_B, high, low, low, high}, |
122 | {in_A, off, in_B, high, high, low, low}, |
123 | {in_A, out_B, in_B, high, low, low, high}, |
124 | {out_A, off, in_B, high, low, low, high}, |
125 | {out_B, off, in_B, high, low, low, high}, |
126 | {out_B, in_A, in_B, high, low, low, high}, |
127 | {off, off, out_B, low, high, high, high}, |
128 | {off, in_A, out_B, low, high, high, low}, |
129 | {off, out_A, out_B, low, low, high, high}, |
130 | {off, in_B, out_B, low, high, high, low}, |
131 | {in_A, off, out_B, low, high, high, low}, |
132 | {in_A, in_B, out_B, low, high, high, low}, |
133 | {out_A, off, out_B, low, low, high, high}, |
134 | {out_A, in_B, out_B, low, low, high, high}, |
135 | {in_B, off, out_B, low, high, high, low}, |
136 | {in_B, in_A, out_B, low, high, high, low}, |
137 | {in_B, out_A, out_B, low, low, high, high}, |
138 | {end, end, end, led_end, led_end, led_end, led_end} |
139 | }; |
140 | |
141 | static int i40e_ptp_set_pins(struct i40e_pf *pf, |
142 | struct i40e_ptp_pins_settings *pins); |
143 | |
144 | /** |
145 | * i40e_ptp_extts0_work - workqueue task function |
146 | * @work: workqueue task structure |
147 | * |
148 | * Service for PTP external clock event |
149 | **/ |
150 | static void i40e_ptp_extts0_work(struct work_struct *work) |
151 | { |
152 | struct i40e_pf *pf = container_of(work, struct i40e_pf, |
153 | ptp_extts0_work); |
154 | struct i40e_hw *hw = &pf->hw; |
155 | struct ptp_clock_event event; |
156 | u32 hi, lo; |
157 | |
158 | /* Event time is captured by one of the two matched registers |
159 | * PRTTSYN_EVNT_L: 32 LSB of sampled time event |
160 | * PRTTSYN_EVNT_H: 32 MSB of sampled time event |
161 | * Event is defined in PRTTSYN_EVNT_0 register |
162 | */ |
163 | lo = rd32(hw, I40E_PRTTSYN_EVNT_L(0)); |
164 | hi = rd32(hw, I40E_PRTTSYN_EVNT_H(0)); |
165 | |
166 | event.timestamp = (((u64)hi) << 32) | lo; |
167 | |
168 | event.type = PTP_CLOCK_EXTTS; |
169 | event.index = hw->pf_id; |
170 | |
171 | /* fire event */ |
172 | ptp_clock_event(ptp: pf->ptp_clock, event: &event); |
173 | } |
174 | |
175 | /** |
176 | * i40e_is_ptp_pin_dev - check if device supports PTP pins |
177 | * @hw: pointer to the hardware structure |
178 | * |
179 | * Return true if device supports PTP pins, false otherwise. |
180 | **/ |
181 | static bool i40e_is_ptp_pin_dev(struct i40e_hw *hw) |
182 | { |
183 | return hw->device_id == I40E_DEV_ID_25G_SFP28 && |
184 | hw->subsystem_device_id == I40E_SUBDEV_ID_25G_PTP_PIN; |
185 | } |
186 | |
187 | /** |
188 | * i40e_can_set_pins - check possibility of manipulating the pins |
189 | * @pf: board private structure |
190 | * |
191 | * Check if all conditions are satisfied to manipulate PTP pins. |
192 | * Return CAN_SET_PINS if pins can be set on a specific PF or |
193 | * return CAN_DO_PINS if pins can be manipulated within a NIC or |
194 | * return CANT_DO_PINS otherwise. |
195 | **/ |
196 | static enum i40e_can_set_pins i40e_can_set_pins(struct i40e_pf *pf) |
197 | { |
198 | if (!i40e_is_ptp_pin_dev(hw: &pf->hw)) { |
199 | dev_warn(&pf->pdev->dev, |
200 | "PTP external clock not supported.\n" ); |
201 | return CANT_DO_PINS; |
202 | } |
203 | |
204 | if (!pf->ptp_pins) { |
205 | dev_warn(&pf->pdev->dev, |
206 | "PTP PIN manipulation not allowed.\n" ); |
207 | return CANT_DO_PINS; |
208 | } |
209 | |
210 | if (pf->hw.pf_id) { |
211 | dev_warn(&pf->pdev->dev, |
212 | "PTP PINs should be accessed via PF0.\n" ); |
213 | return CAN_DO_PINS; |
214 | } |
215 | |
216 | return CAN_SET_PINS; |
217 | } |
218 | |
219 | /** |
220 | * i40_ptp_reset_timing_events - Reset PTP timing events |
221 | * @pf: Board private structure |
222 | * |
223 | * This function resets timing events for pf. |
224 | **/ |
225 | static void i40_ptp_reset_timing_events(struct i40e_pf *pf) |
226 | { |
227 | u32 i; |
228 | |
229 | spin_lock_bh(lock: &pf->ptp_rx_lock); |
230 | for (i = 0; i <= I40E_PRTTSYN_RXTIME_L_MAX_INDEX; i++) { |
231 | /* reading and automatically clearing timing events registers */ |
232 | rd32(&pf->hw, I40E_PRTTSYN_RXTIME_L(i)); |
233 | rd32(&pf->hw, I40E_PRTTSYN_RXTIME_H(i)); |
234 | pf->latch_events[i] = 0; |
235 | } |
236 | /* reading and automatically clearing timing events registers */ |
237 | rd32(&pf->hw, I40E_PRTTSYN_TXTIME_L); |
238 | rd32(&pf->hw, I40E_PRTTSYN_TXTIME_H); |
239 | |
240 | pf->tx_hwtstamp_timeouts = 0; |
241 | pf->tx_hwtstamp_skipped = 0; |
242 | pf->rx_hwtstamp_cleared = 0; |
243 | pf->latch_event_flags = 0; |
244 | spin_unlock_bh(lock: &pf->ptp_rx_lock); |
245 | } |
246 | |
247 | /** |
248 | * i40e_ptp_verify - check pins |
249 | * @ptp: ptp clock |
250 | * @pin: pin index |
251 | * @func: assigned function |
252 | * @chan: channel |
253 | * |
254 | * Check pins consistency. |
255 | * Return 0 on success or error on failure. |
256 | **/ |
257 | static int i40e_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin, |
258 | enum ptp_pin_function func, unsigned int chan) |
259 | { |
260 | switch (func) { |
261 | case PTP_PF_NONE: |
262 | case PTP_PF_EXTTS: |
263 | case PTP_PF_PEROUT: |
264 | break; |
265 | case PTP_PF_PHYSYNC: |
266 | return -EOPNOTSUPP; |
267 | } |
268 | return 0; |
269 | } |
270 | |
271 | /** |
272 | * i40e_ptp_read - Read the PHC time from the device |
273 | * @pf: Board private structure |
274 | * @ts: timespec structure to hold the current time value |
275 | * @sts: structure to hold the system time before and after reading the PHC |
276 | * |
277 | * This function reads the PRTTSYN_TIME registers and stores them in a |
278 | * timespec. However, since the registers are 64 bits of nanoseconds, we must |
279 | * convert the result to a timespec before we can return. |
280 | **/ |
281 | static void i40e_ptp_read(struct i40e_pf *pf, struct timespec64 *ts, |
282 | struct ptp_system_timestamp *sts) |
283 | { |
284 | struct i40e_hw *hw = &pf->hw; |
285 | u32 hi, lo; |
286 | u64 ns; |
287 | |
288 | /* The timer latches on the lowest register read. */ |
289 | ptp_read_system_prets(sts); |
290 | lo = rd32(hw, I40E_PRTTSYN_TIME_L); |
291 | ptp_read_system_postts(sts); |
292 | hi = rd32(hw, I40E_PRTTSYN_TIME_H); |
293 | |
294 | ns = (((u64)hi) << 32) | lo; |
295 | |
296 | *ts = ns_to_timespec64(nsec: ns); |
297 | } |
298 | |
299 | /** |
300 | * i40e_ptp_write - Write the PHC time to the device |
301 | * @pf: Board private structure |
302 | * @ts: timespec structure that holds the new time value |
303 | * |
304 | * This function writes the PRTTSYN_TIME registers with the user value. Since |
305 | * we receive a timespec from the stack, we must convert that timespec into |
306 | * nanoseconds before programming the registers. |
307 | **/ |
308 | static void i40e_ptp_write(struct i40e_pf *pf, const struct timespec64 *ts) |
309 | { |
310 | struct i40e_hw *hw = &pf->hw; |
311 | u64 ns = timespec64_to_ns(ts); |
312 | |
313 | /* The timer will not update until the high register is written, so |
314 | * write the low register first. |
315 | */ |
316 | wr32(hw, I40E_PRTTSYN_TIME_L, ns & 0xFFFFFFFF); |
317 | wr32(hw, I40E_PRTTSYN_TIME_H, ns >> 32); |
318 | } |
319 | |
320 | /** |
321 | * i40e_ptp_convert_to_hwtstamp - Convert device clock to system time |
322 | * @hwtstamps: Timestamp structure to update |
323 | * @timestamp: Timestamp from the hardware |
324 | * |
325 | * We need to convert the NIC clock value into a hwtstamp which can be used by |
326 | * the upper level timestamping functions. Since the timestamp is simply a 64- |
327 | * bit nanosecond value, we can call ns_to_ktime directly to handle this. |
328 | **/ |
329 | static void i40e_ptp_convert_to_hwtstamp(struct skb_shared_hwtstamps *hwtstamps, |
330 | u64 timestamp) |
331 | { |
332 | memset(hwtstamps, 0, sizeof(*hwtstamps)); |
333 | |
334 | hwtstamps->hwtstamp = ns_to_ktime(ns: timestamp); |
335 | } |
336 | |
337 | /** |
338 | * i40e_ptp_adjfine - Adjust the PHC frequency |
339 | * @ptp: The PTP clock structure |
340 | * @scaled_ppm: Scaled parts per million adjustment from base |
341 | * |
342 | * Adjust the frequency of the PHC by the indicated delta from the base |
343 | * frequency. |
344 | * |
345 | * Scaled parts per million is ppm with a 16 bit binary fractional field. |
346 | **/ |
347 | static int i40e_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) |
348 | { |
349 | struct i40e_pf *pf = container_of(ptp, struct i40e_pf, ptp_caps); |
350 | struct i40e_hw *hw = &pf->hw; |
351 | u64 adj, base_adj; |
352 | |
353 | smp_mb(); /* Force any pending update before accessing. */ |
354 | base_adj = I40E_PTP_40GB_INCVAL * READ_ONCE(pf->ptp_adj_mult); |
355 | |
356 | adj = adjust_by_scaled_ppm(base: base_adj, scaled_ppm); |
357 | |
358 | wr32(hw, I40E_PRTTSYN_INC_L, adj & 0xFFFFFFFF); |
359 | wr32(hw, I40E_PRTTSYN_INC_H, adj >> 32); |
360 | |
361 | return 0; |
362 | } |
363 | |
364 | /** |
365 | * i40e_ptp_set_1pps_signal_hw - configure 1PPS PTP signal for pins |
366 | * @pf: the PF private data structure |
367 | * |
368 | * Configure 1PPS signal used for PTP pins |
369 | **/ |
370 | static void i40e_ptp_set_1pps_signal_hw(struct i40e_pf *pf) |
371 | { |
372 | struct i40e_hw *hw = &pf->hw; |
373 | struct timespec64 now; |
374 | u64 ns; |
375 | |
376 | wr32(hw, I40E_PRTTSYN_AUX_0(1), 0); |
377 | wr32(hw, I40E_PRTTSYN_AUX_1(1), I40E_PRTTSYN_AUX_1_INSTNT); |
378 | wr32(hw, I40E_PRTTSYN_AUX_0(1), I40E_PRTTSYN_AUX_0_OUT_ENABLE); |
379 | |
380 | i40e_ptp_read(pf, ts: &now, NULL); |
381 | now.tv_sec += I40E_PTP_2_SEC_DELAY; |
382 | now.tv_nsec = 0; |
383 | ns = timespec64_to_ns(ts: &now); |
384 | |
385 | /* I40E_PRTTSYN_TGT_L(1) */ |
386 | wr32(hw, I40E_PRTTSYN_TGT_L(1), ns & 0xFFFFFFFF); |
387 | /* I40E_PRTTSYN_TGT_H(1) */ |
388 | wr32(hw, I40E_PRTTSYN_TGT_H(1), ns >> 32); |
389 | wr32(hw, I40E_PRTTSYN_CLKO(1), I40E_PTP_HALF_SECOND); |
390 | wr32(hw, I40E_PRTTSYN_AUX_1(1), I40E_PRTTSYN_AUX_1_INSTNT); |
391 | wr32(hw, I40E_PRTTSYN_AUX_0(1), |
392 | I40E_PRTTSYN_AUX_0_OUT_ENABLE_CLK_MOD); |
393 | } |
394 | |
395 | /** |
396 | * i40e_ptp_adjtime - Adjust the PHC time |
397 | * @ptp: The PTP clock structure |
398 | * @delta: Offset in nanoseconds to adjust the PHC time by |
399 | * |
400 | * Adjust the current clock time by a delta specified in nanoseconds. |
401 | **/ |
402 | static int i40e_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) |
403 | { |
404 | struct i40e_pf *pf = container_of(ptp, struct i40e_pf, ptp_caps); |
405 | struct i40e_hw *hw = &pf->hw; |
406 | |
407 | mutex_lock(&pf->tmreg_lock); |
408 | |
409 | if (delta > -999999900LL && delta < 999999900LL) { |
410 | int neg_adj = 0; |
411 | u32 timadj; |
412 | u64 tohw; |
413 | |
414 | if (delta < 0) { |
415 | neg_adj = 1; |
416 | tohw = -delta; |
417 | } else { |
418 | tohw = delta; |
419 | } |
420 | |
421 | timadj = tohw & 0x3FFFFFFF; |
422 | if (neg_adj) |
423 | timadj |= I40E_ISGN; |
424 | wr32(hw, I40E_PRTTSYN_ADJ, timadj); |
425 | } else { |
426 | struct timespec64 then, now; |
427 | |
428 | then = ns_to_timespec64(nsec: delta); |
429 | i40e_ptp_read(pf, ts: &now, NULL); |
430 | now = timespec64_add(lhs: now, rhs: then); |
431 | i40e_ptp_write(pf, ts: (const struct timespec64 *)&now); |
432 | i40e_ptp_set_1pps_signal_hw(pf); |
433 | } |
434 | |
435 | mutex_unlock(lock: &pf->tmreg_lock); |
436 | |
437 | return 0; |
438 | } |
439 | |
440 | /** |
441 | * i40e_ptp_gettimex - Get the time of the PHC |
442 | * @ptp: The PTP clock structure |
443 | * @ts: timespec structure to hold the current time value |
444 | * @sts: structure to hold the system time before and after reading the PHC |
445 | * |
446 | * Read the device clock and return the correct value on ns, after converting it |
447 | * into a timespec struct. |
448 | **/ |
449 | static int i40e_ptp_gettimex(struct ptp_clock_info *ptp, struct timespec64 *ts, |
450 | struct ptp_system_timestamp *sts) |
451 | { |
452 | struct i40e_pf *pf = container_of(ptp, struct i40e_pf, ptp_caps); |
453 | |
454 | mutex_lock(&pf->tmreg_lock); |
455 | i40e_ptp_read(pf, ts, sts); |
456 | mutex_unlock(lock: &pf->tmreg_lock); |
457 | |
458 | return 0; |
459 | } |
460 | |
461 | /** |
462 | * i40e_ptp_settime - Set the time of the PHC |
463 | * @ptp: The PTP clock structure |
464 | * @ts: timespec64 structure that holds the new time value |
465 | * |
466 | * Set the device clock to the user input value. The conversion from timespec |
467 | * to ns happens in the write function. |
468 | **/ |
469 | static int i40e_ptp_settime(struct ptp_clock_info *ptp, |
470 | const struct timespec64 *ts) |
471 | { |
472 | struct i40e_pf *pf = container_of(ptp, struct i40e_pf, ptp_caps); |
473 | |
474 | mutex_lock(&pf->tmreg_lock); |
475 | i40e_ptp_write(pf, ts); |
476 | mutex_unlock(lock: &pf->tmreg_lock); |
477 | |
478 | return 0; |
479 | } |
480 | |
481 | /** |
482 | * i40e_pps_configure - configure PPS events |
483 | * @ptp: ptp clock |
484 | * @rq: clock request |
485 | * @on: status |
486 | * |
487 | * Configure PPS events for external clock source. |
488 | * Return 0 on success or error on failure. |
489 | **/ |
490 | static int i40e_pps_configure(struct ptp_clock_info *ptp, |
491 | struct ptp_clock_request *rq, |
492 | int on) |
493 | { |
494 | struct i40e_pf *pf = container_of(ptp, struct i40e_pf, ptp_caps); |
495 | |
496 | if (!!on) |
497 | i40e_ptp_set_1pps_signal_hw(pf); |
498 | |
499 | return 0; |
500 | } |
501 | |
502 | /** |
503 | * i40e_pin_state - determine PIN state |
504 | * @index: PIN index |
505 | * @func: function assigned to PIN |
506 | * |
507 | * Determine PIN state based on PIN index and function assigned. |
508 | * Return PIN state. |
509 | **/ |
510 | static enum i40e_ptp_gpio_pin_state i40e_pin_state(int index, int func) |
511 | { |
512 | enum i40e_ptp_gpio_pin_state state = off; |
513 | |
514 | if (index == 0 && func == PTP_PF_EXTTS) |
515 | state = in_A; |
516 | if (index == 1 && func == PTP_PF_EXTTS) |
517 | state = in_B; |
518 | if (index == 0 && func == PTP_PF_PEROUT) |
519 | state = out_A; |
520 | if (index == 1 && func == PTP_PF_PEROUT) |
521 | state = out_B; |
522 | |
523 | return state; |
524 | } |
525 | |
526 | /** |
527 | * i40e_ptp_enable_pin - enable PINs. |
528 | * @pf: private board structure |
529 | * @chan: channel |
530 | * @func: PIN function |
531 | * @on: state |
532 | * |
533 | * Enable PTP pins for external clock source. |
534 | * Return 0 on success or error code on failure. |
535 | **/ |
536 | static int i40e_ptp_enable_pin(struct i40e_pf *pf, unsigned int chan, |
537 | enum ptp_pin_function func, int on) |
538 | { |
539 | enum i40e_ptp_gpio_pin_state *pin = NULL; |
540 | struct i40e_ptp_pins_settings pins; |
541 | int pin_index; |
542 | |
543 | /* Use PF0 to set pins. Return success for user space tools */ |
544 | if (pf->hw.pf_id) |
545 | return 0; |
546 | |
547 | /* Preserve previous state of pins that we don't touch */ |
548 | pins.sdp3_2 = pf->ptp_pins->sdp3_2; |
549 | pins.sdp3_3 = pf->ptp_pins->sdp3_3; |
550 | pins.gpio_4 = pf->ptp_pins->gpio_4; |
551 | |
552 | /* To turn on the pin - find the corresponding one based on |
553 | * the given index. To to turn the function off - find |
554 | * which pin had it assigned. Don't use ptp_find_pin here |
555 | * because it tries to lock the pincfg_mux which is locked by |
556 | * ptp_pin_store() that calls here. |
557 | */ |
558 | if (on) { |
559 | pin_index = ptp_find_pin(ptp: pf->ptp_clock, func, chan); |
560 | if (pin_index < 0) |
561 | return -EBUSY; |
562 | |
563 | switch (pin_index) { |
564 | case SDP3_2: |
565 | pin = &pins.sdp3_2; |
566 | break; |
567 | case SDP3_3: |
568 | pin = &pins.sdp3_3; |
569 | break; |
570 | case GPIO_4: |
571 | pin = &pins.gpio_4; |
572 | break; |
573 | default: |
574 | return -EINVAL; |
575 | } |
576 | |
577 | *pin = i40e_pin_state(index: chan, func); |
578 | } else { |
579 | pins.sdp3_2 = off; |
580 | pins.sdp3_3 = off; |
581 | pins.gpio_4 = off; |
582 | } |
583 | |
584 | return i40e_ptp_set_pins(pf, pins: &pins) ? -EINVAL : 0; |
585 | } |
586 | |
587 | /** |
588 | * i40e_ptp_feature_enable - Enable external clock pins |
589 | * @ptp: The PTP clock structure |
590 | * @rq: The PTP clock request structure |
591 | * @on: To turn feature on/off |
592 | * |
593 | * Setting on/off PTP PPS feature for pin. |
594 | **/ |
595 | static int i40e_ptp_feature_enable(struct ptp_clock_info *ptp, |
596 | struct ptp_clock_request *rq, |
597 | int on) |
598 | { |
599 | struct i40e_pf *pf = container_of(ptp, struct i40e_pf, ptp_caps); |
600 | |
601 | enum ptp_pin_function func; |
602 | unsigned int chan; |
603 | |
604 | /* TODO: Implement flags handling for EXTTS and PEROUT */ |
605 | switch (rq->type) { |
606 | case PTP_CLK_REQ_EXTTS: |
607 | func = PTP_PF_EXTTS; |
608 | chan = rq->extts.index; |
609 | break; |
610 | case PTP_CLK_REQ_PEROUT: |
611 | func = PTP_PF_PEROUT; |
612 | chan = rq->perout.index; |
613 | break; |
614 | case PTP_CLK_REQ_PPS: |
615 | return i40e_pps_configure(ptp, rq, on); |
616 | default: |
617 | return -EOPNOTSUPP; |
618 | } |
619 | |
620 | return i40e_ptp_enable_pin(pf, chan, func, on); |
621 | } |
622 | |
623 | /** |
624 | * i40e_ptp_get_rx_events - Read I40E_PRTTSYN_STAT_1 and latch events |
625 | * @pf: the PF data structure |
626 | * |
627 | * This function reads I40E_PRTTSYN_STAT_1 and updates the corresponding timers |
628 | * for noticed latch events. This allows the driver to keep track of the first |
629 | * time a latch event was noticed which will be used to help clear out Rx |
630 | * timestamps for packets that got dropped or lost. |
631 | * |
632 | * This function will return the current value of I40E_PRTTSYN_STAT_1 and is |
633 | * expected to be called only while under the ptp_rx_lock. |
634 | **/ |
635 | static u32 i40e_ptp_get_rx_events(struct i40e_pf *pf) |
636 | { |
637 | struct i40e_hw *hw = &pf->hw; |
638 | u32 prttsyn_stat, new_latch_events; |
639 | int i; |
640 | |
641 | prttsyn_stat = rd32(hw, I40E_PRTTSYN_STAT_1); |
642 | new_latch_events = prttsyn_stat & ~pf->latch_event_flags; |
643 | |
644 | /* Update the jiffies time for any newly latched timestamp. This |
645 | * ensures that we store the time that we first discovered a timestamp |
646 | * was latched by the hardware. The service task will later determine |
647 | * if we should free the latch and drop that timestamp should too much |
648 | * time pass. This flow ensures that we only update jiffies for new |
649 | * events latched since the last time we checked, and not all events |
650 | * currently latched, so that the service task accounting remains |
651 | * accurate. |
652 | */ |
653 | for (i = 0; i < 4; i++) { |
654 | if (new_latch_events & BIT(i)) |
655 | pf->latch_events[i] = jiffies; |
656 | } |
657 | |
658 | /* Finally, we store the current status of the Rx timestamp latches */ |
659 | pf->latch_event_flags = prttsyn_stat; |
660 | |
661 | return prttsyn_stat; |
662 | } |
663 | |
664 | /** |
665 | * i40e_ptp_rx_hang - Detect error case when Rx timestamp registers are hung |
666 | * @pf: The PF private data structure |
667 | * |
668 | * This watchdog task is scheduled to detect error case where hardware has |
669 | * dropped an Rx packet that was timestamped when the ring is full. The |
670 | * particular error is rare but leaves the device in a state unable to timestamp |
671 | * any future packets. |
672 | **/ |
673 | void i40e_ptp_rx_hang(struct i40e_pf *pf) |
674 | { |
675 | struct i40e_hw *hw = &pf->hw; |
676 | unsigned int i, cleared = 0; |
677 | |
678 | /* Since we cannot turn off the Rx timestamp logic if the device is |
679 | * configured for Tx timestamping, we check if Rx timestamping is |
680 | * configured. We don't want to spuriously warn about Rx timestamp |
681 | * hangs if we don't care about the timestamps. |
682 | */ |
683 | if (!test_bit(I40E_FLAG_PTP_ENA, pf->flags) || !pf->ptp_rx) |
684 | return; |
685 | |
686 | spin_lock_bh(lock: &pf->ptp_rx_lock); |
687 | |
688 | /* Update current latch times for Rx events */ |
689 | i40e_ptp_get_rx_events(pf); |
690 | |
691 | /* Check all the currently latched Rx events and see whether they have |
692 | * been latched for over a second. It is assumed that any timestamp |
693 | * should have been cleared within this time, or else it was captured |
694 | * for a dropped frame that the driver never received. Thus, we will |
695 | * clear any timestamp that has been latched for over 1 second. |
696 | */ |
697 | for (i = 0; i < 4; i++) { |
698 | if ((pf->latch_event_flags & BIT(i)) && |
699 | time_is_before_jiffies(pf->latch_events[i] + HZ)) { |
700 | rd32(hw, I40E_PRTTSYN_RXTIME_H(i)); |
701 | pf->latch_event_flags &= ~BIT(i); |
702 | cleared++; |
703 | } |
704 | } |
705 | |
706 | spin_unlock_bh(lock: &pf->ptp_rx_lock); |
707 | |
708 | /* Log a warning if more than 2 timestamps got dropped in the same |
709 | * check. We don't want to warn about all drops because it can occur |
710 | * in normal scenarios such as PTP frames on multicast addresses we |
711 | * aren't listening to. However, administrator should know if this is |
712 | * the reason packets aren't receiving timestamps. |
713 | */ |
714 | if (cleared > 2) |
715 | dev_dbg(&pf->pdev->dev, |
716 | "Dropped %d missed RXTIME timestamp events\n" , |
717 | cleared); |
718 | |
719 | /* Finally, update the rx_hwtstamp_cleared counter */ |
720 | pf->rx_hwtstamp_cleared += cleared; |
721 | } |
722 | |
723 | /** |
724 | * i40e_ptp_tx_hang - Detect error case when Tx timestamp register is hung |
725 | * @pf: The PF private data structure |
726 | * |
727 | * This watchdog task is run periodically to make sure that we clear the Tx |
728 | * timestamp logic if we don't obtain a timestamp in a reasonable amount of |
729 | * time. It is unexpected in the normal case but if it occurs it results in |
730 | * permanently preventing timestamps of future packets. |
731 | **/ |
732 | void i40e_ptp_tx_hang(struct i40e_pf *pf) |
733 | { |
734 | struct sk_buff *skb; |
735 | |
736 | if (!test_bit(I40E_FLAG_PTP_ENA, pf->flags) || !pf->ptp_tx) |
737 | return; |
738 | |
739 | /* Nothing to do if we're not already waiting for a timestamp */ |
740 | if (!test_bit(__I40E_PTP_TX_IN_PROGRESS, pf->state)) |
741 | return; |
742 | |
743 | /* We already have a handler routine which is run when we are notified |
744 | * of a Tx timestamp in the hardware. If we don't get an interrupt |
745 | * within a second it is reasonable to assume that we never will. |
746 | */ |
747 | if (time_is_before_jiffies(pf->ptp_tx_start + HZ)) { |
748 | skb = pf->ptp_tx_skb; |
749 | pf->ptp_tx_skb = NULL; |
750 | clear_bit_unlock(nr: __I40E_PTP_TX_IN_PROGRESS, addr: pf->state); |
751 | |
752 | /* Free the skb after we clear the bitlock */ |
753 | dev_kfree_skb_any(skb); |
754 | pf->tx_hwtstamp_timeouts++; |
755 | } |
756 | } |
757 | |
758 | /** |
759 | * i40e_ptp_tx_hwtstamp - Utility function which returns the Tx timestamp |
760 | * @pf: Board private structure |
761 | * |
762 | * Read the value of the Tx timestamp from the registers, convert it into a |
763 | * value consumable by the stack, and store that result into the shhwtstamps |
764 | * struct before returning it up the stack. |
765 | **/ |
766 | void i40e_ptp_tx_hwtstamp(struct i40e_pf *pf) |
767 | { |
768 | struct skb_shared_hwtstamps shhwtstamps; |
769 | struct sk_buff *skb = pf->ptp_tx_skb; |
770 | struct i40e_hw *hw = &pf->hw; |
771 | u32 hi, lo; |
772 | u64 ns; |
773 | |
774 | if (!test_bit(I40E_FLAG_PTP_ENA, pf->flags) || !pf->ptp_tx) |
775 | return; |
776 | |
777 | /* don't attempt to timestamp if we don't have an skb */ |
778 | if (!pf->ptp_tx_skb) |
779 | return; |
780 | |
781 | lo = rd32(hw, I40E_PRTTSYN_TXTIME_L); |
782 | hi = rd32(hw, I40E_PRTTSYN_TXTIME_H); |
783 | |
784 | ns = (((u64)hi) << 32) | lo; |
785 | i40e_ptp_convert_to_hwtstamp(hwtstamps: &shhwtstamps, timestamp: ns); |
786 | |
787 | /* Clear the bit lock as soon as possible after reading the register, |
788 | * and prior to notifying the stack via skb_tstamp_tx(). Otherwise |
789 | * applications might wake up and attempt to request another transmit |
790 | * timestamp prior to the bit lock being cleared. |
791 | */ |
792 | pf->ptp_tx_skb = NULL; |
793 | clear_bit_unlock(nr: __I40E_PTP_TX_IN_PROGRESS, addr: pf->state); |
794 | |
795 | /* Notify the stack and free the skb after we've unlocked */ |
796 | skb_tstamp_tx(orig_skb: skb, hwtstamps: &shhwtstamps); |
797 | dev_kfree_skb_any(skb); |
798 | } |
799 | |
800 | /** |
801 | * i40e_ptp_rx_hwtstamp - Utility function which checks for an Rx timestamp |
802 | * @pf: Board private structure |
803 | * @skb: Particular skb to send timestamp with |
804 | * @index: Index into the receive timestamp registers for the timestamp |
805 | * |
806 | * The XL710 receives a notification in the receive descriptor with an offset |
807 | * into the set of RXTIME registers where the timestamp is for that skb. This |
808 | * function goes and fetches the receive timestamp from that offset, if a valid |
809 | * one exists. The RXTIME registers are in ns, so we must convert the result |
810 | * first. |
811 | **/ |
812 | void i40e_ptp_rx_hwtstamp(struct i40e_pf *pf, struct sk_buff *skb, u8 index) |
813 | { |
814 | u32 prttsyn_stat, hi, lo; |
815 | struct i40e_hw *hw; |
816 | u64 ns; |
817 | |
818 | /* Since we cannot turn off the Rx timestamp logic if the device is |
819 | * doing Tx timestamping, check if Rx timestamping is configured. |
820 | */ |
821 | if (!test_bit(I40E_FLAG_PTP_ENA, pf->flags) || !pf->ptp_rx) |
822 | return; |
823 | |
824 | hw = &pf->hw; |
825 | |
826 | spin_lock_bh(lock: &pf->ptp_rx_lock); |
827 | |
828 | /* Get current Rx events and update latch times */ |
829 | prttsyn_stat = i40e_ptp_get_rx_events(pf); |
830 | |
831 | /* TODO: Should we warn about missing Rx timestamp event? */ |
832 | if (!(prttsyn_stat & BIT(index))) { |
833 | spin_unlock_bh(lock: &pf->ptp_rx_lock); |
834 | return; |
835 | } |
836 | |
837 | /* Clear the latched event since we're about to read its register */ |
838 | pf->latch_event_flags &= ~BIT(index); |
839 | |
840 | lo = rd32(hw, I40E_PRTTSYN_RXTIME_L(index)); |
841 | hi = rd32(hw, I40E_PRTTSYN_RXTIME_H(index)); |
842 | |
843 | spin_unlock_bh(lock: &pf->ptp_rx_lock); |
844 | |
845 | ns = (((u64)hi) << 32) | lo; |
846 | |
847 | i40e_ptp_convert_to_hwtstamp(hwtstamps: skb_hwtstamps(skb), timestamp: ns); |
848 | } |
849 | |
850 | /** |
851 | * i40e_ptp_set_increment - Utility function to update clock increment rate |
852 | * @pf: Board private structure |
853 | * |
854 | * During a link change, the DMA frequency that drives the 1588 logic will |
855 | * change. In order to keep the PRTTSYN_TIME registers in units of nanoseconds, |
856 | * we must update the increment value per clock tick. |
857 | **/ |
858 | void i40e_ptp_set_increment(struct i40e_pf *pf) |
859 | { |
860 | struct i40e_link_status *hw_link_info; |
861 | struct i40e_hw *hw = &pf->hw; |
862 | u64 incval; |
863 | u32 mult; |
864 | |
865 | hw_link_info = &hw->phy.link_info; |
866 | |
867 | i40e_aq_get_link_info(hw: &pf->hw, enable_lse: true, NULL, NULL); |
868 | |
869 | switch (hw_link_info->link_speed) { |
870 | case I40E_LINK_SPEED_10GB: |
871 | mult = I40E_PTP_10GB_INCVAL_MULT; |
872 | break; |
873 | case I40E_LINK_SPEED_5GB: |
874 | mult = I40E_PTP_5GB_INCVAL_MULT; |
875 | break; |
876 | case I40E_LINK_SPEED_1GB: |
877 | mult = I40E_PTP_1GB_INCVAL_MULT; |
878 | break; |
879 | case I40E_LINK_SPEED_100MB: |
880 | { |
881 | static int warn_once; |
882 | |
883 | if (!warn_once) { |
884 | dev_warn(&pf->pdev->dev, |
885 | "1588 functionality is not supported at 100 Mbps. Stopping the PHC.\n" ); |
886 | warn_once++; |
887 | } |
888 | mult = 0; |
889 | break; |
890 | } |
891 | case I40E_LINK_SPEED_40GB: |
892 | default: |
893 | mult = 1; |
894 | break; |
895 | } |
896 | |
897 | /* The increment value is calculated by taking the base 40GbE incvalue |
898 | * and multiplying it by a factor based on the link speed. |
899 | */ |
900 | incval = I40E_PTP_40GB_INCVAL * mult; |
901 | |
902 | /* Write the new increment value into the increment register. The |
903 | * hardware will not update the clock until both registers have been |
904 | * written. |
905 | */ |
906 | wr32(hw, I40E_PRTTSYN_INC_L, incval & 0xFFFFFFFF); |
907 | wr32(hw, I40E_PRTTSYN_INC_H, incval >> 32); |
908 | |
909 | /* Update the base adjustement value. */ |
910 | WRITE_ONCE(pf->ptp_adj_mult, mult); |
911 | smp_mb(); /* Force the above update. */ |
912 | } |
913 | |
914 | /** |
915 | * i40e_ptp_get_ts_config - ioctl interface to read the HW timestamping |
916 | * @pf: Board private structure |
917 | * @ifr: ioctl data |
918 | * |
919 | * Obtain the current hardware timestamping settigs as requested. To do this, |
920 | * keep a shadow copy of the timestamp settings rather than attempting to |
921 | * deconstruct it from the registers. |
922 | **/ |
923 | int i40e_ptp_get_ts_config(struct i40e_pf *pf, struct ifreq *ifr) |
924 | { |
925 | struct hwtstamp_config *config = &pf->tstamp_config; |
926 | |
927 | if (!test_bit(I40E_FLAG_PTP_ENA, pf->flags)) |
928 | return -EOPNOTSUPP; |
929 | |
930 | return copy_to_user(to: ifr->ifr_data, from: config, n: sizeof(*config)) ? |
931 | -EFAULT : 0; |
932 | } |
933 | |
934 | /** |
935 | * i40e_ptp_free_pins - free memory used by PTP pins |
936 | * @pf: Board private structure |
937 | * |
938 | * Release memory allocated for PTP pins. |
939 | **/ |
940 | static void i40e_ptp_free_pins(struct i40e_pf *pf) |
941 | { |
942 | if (i40e_is_ptp_pin_dev(hw: &pf->hw)) { |
943 | kfree(objp: pf->ptp_pins); |
944 | kfree(objp: pf->ptp_caps.pin_config); |
945 | pf->ptp_pins = NULL; |
946 | } |
947 | } |
948 | |
949 | /** |
950 | * i40e_ptp_set_pin_hw - Set HW GPIO pin |
951 | * @hw: pointer to the hardware structure |
952 | * @pin: pin index |
953 | * @state: pin state |
954 | * |
955 | * Set status of GPIO pin for external clock handling. |
956 | **/ |
957 | static void i40e_ptp_set_pin_hw(struct i40e_hw *hw, |
958 | unsigned int pin, |
959 | enum i40e_ptp_gpio_pin_state state) |
960 | { |
961 | switch (state) { |
962 | case off: |
963 | wr32(hw, I40E_GLGEN_GPIO_CTL(pin), 0); |
964 | break; |
965 | case in_A: |
966 | wr32(hw, I40E_GLGEN_GPIO_CTL(pin), |
967 | I40E_GLGEN_GPIO_CTL_PORT_0_IN_TIMESYNC_0); |
968 | break; |
969 | case in_B: |
970 | wr32(hw, I40E_GLGEN_GPIO_CTL(pin), |
971 | I40E_GLGEN_GPIO_CTL_PORT_1_IN_TIMESYNC_0); |
972 | break; |
973 | case out_A: |
974 | wr32(hw, I40E_GLGEN_GPIO_CTL(pin), |
975 | I40E_GLGEN_GPIO_CTL_PORT_0_OUT_TIMESYNC_1); |
976 | break; |
977 | case out_B: |
978 | wr32(hw, I40E_GLGEN_GPIO_CTL(pin), |
979 | I40E_GLGEN_GPIO_CTL_PORT_1_OUT_TIMESYNC_1); |
980 | break; |
981 | default: |
982 | break; |
983 | } |
984 | } |
985 | |
986 | /** |
987 | * i40e_ptp_set_led_hw - Set HW GPIO led |
988 | * @hw: pointer to the hardware structure |
989 | * @led: led index |
990 | * @state: led state |
991 | * |
992 | * Set status of GPIO led for external clock handling. |
993 | **/ |
994 | static void i40e_ptp_set_led_hw(struct i40e_hw *hw, |
995 | unsigned int led, |
996 | enum i40e_ptp_led_pin_state state) |
997 | { |
998 | switch (state) { |
999 | case low: |
1000 | wr32(hw, I40E_GLGEN_GPIO_SET, |
1001 | I40E_GLGEN_GPIO_SET_DRV_SDP_DATA | led); |
1002 | break; |
1003 | case high: |
1004 | wr32(hw, I40E_GLGEN_GPIO_SET, |
1005 | I40E_GLGEN_GPIO_SET_DRV_SDP_DATA | |
1006 | I40E_GLGEN_GPIO_SET_SDP_DATA_HI | led); |
1007 | break; |
1008 | default: |
1009 | break; |
1010 | } |
1011 | } |
1012 | |
1013 | /** |
1014 | * i40e_ptp_init_leds_hw - init LEDs |
1015 | * @hw: pointer to a hardware structure |
1016 | * |
1017 | * Set initial state of LEDs |
1018 | **/ |
1019 | static void i40e_ptp_init_leds_hw(struct i40e_hw *hw) |
1020 | { |
1021 | wr32(hw, I40E_GLGEN_GPIO_CTL(I40E_LED2_0), |
1022 | I40E_GLGEN_GPIO_CTL_LED_INIT); |
1023 | wr32(hw, I40E_GLGEN_GPIO_CTL(I40E_LED2_1), |
1024 | I40E_GLGEN_GPIO_CTL_LED_INIT); |
1025 | wr32(hw, I40E_GLGEN_GPIO_CTL(I40E_LED3_0), |
1026 | I40E_GLGEN_GPIO_CTL_LED_INIT); |
1027 | wr32(hw, I40E_GLGEN_GPIO_CTL(I40E_LED3_1), |
1028 | I40E_GLGEN_GPIO_CTL_LED_INIT); |
1029 | } |
1030 | |
1031 | /** |
1032 | * i40e_ptp_set_pins_hw - Set HW GPIO pins |
1033 | * @pf: Board private structure |
1034 | * |
1035 | * This function sets GPIO pins for PTP |
1036 | **/ |
1037 | static void i40e_ptp_set_pins_hw(struct i40e_pf *pf) |
1038 | { |
1039 | const struct i40e_ptp_pins_settings *pins = pf->ptp_pins; |
1040 | struct i40e_hw *hw = &pf->hw; |
1041 | |
1042 | /* pin must be disabled before it may be used */ |
1043 | i40e_ptp_set_pin_hw(hw, I40E_SDP3_2, state: off); |
1044 | i40e_ptp_set_pin_hw(hw, I40E_SDP3_3, state: off); |
1045 | i40e_ptp_set_pin_hw(hw, I40E_GPIO_4, state: off); |
1046 | |
1047 | i40e_ptp_set_pin_hw(hw, I40E_SDP3_2, state: pins->sdp3_2); |
1048 | i40e_ptp_set_pin_hw(hw, I40E_SDP3_3, state: pins->sdp3_3); |
1049 | i40e_ptp_set_pin_hw(hw, I40E_GPIO_4, state: pins->gpio_4); |
1050 | |
1051 | i40e_ptp_set_led_hw(hw, I40E_LED2_0, state: pins->led2_0); |
1052 | i40e_ptp_set_led_hw(hw, I40E_LED2_1, state: pins->led2_1); |
1053 | i40e_ptp_set_led_hw(hw, I40E_LED3_0, state: pins->led3_0); |
1054 | i40e_ptp_set_led_hw(hw, I40E_LED3_1, state: pins->led3_1); |
1055 | |
1056 | dev_info(&pf->pdev->dev, |
1057 | "PTP configuration set to: SDP3_2: %s, SDP3_3: %s, GPIO_4: %s.\n" , |
1058 | i40e_ptp_gpio_pin_state2str[pins->sdp3_2], |
1059 | i40e_ptp_gpio_pin_state2str[pins->sdp3_3], |
1060 | i40e_ptp_gpio_pin_state2str[pins->gpio_4]); |
1061 | } |
1062 | |
1063 | /** |
1064 | * i40e_ptp_set_pins - set PTP pins in HW |
1065 | * @pf: Board private structure |
1066 | * @pins: PTP pins to be applied |
1067 | * |
1068 | * Validate and set PTP pins in HW for specific PF. |
1069 | * Return 0 on success or negative value on error. |
1070 | **/ |
1071 | static int i40e_ptp_set_pins(struct i40e_pf *pf, |
1072 | struct i40e_ptp_pins_settings *pins) |
1073 | { |
1074 | enum i40e_can_set_pins pin_caps = i40e_can_set_pins(pf); |
1075 | int i = 0; |
1076 | |
1077 | if (pin_caps == CANT_DO_PINS) |
1078 | return -EOPNOTSUPP; |
1079 | else if (pin_caps == CAN_DO_PINS) |
1080 | return 0; |
1081 | |
1082 | if (pins->sdp3_2 == invalid) |
1083 | pins->sdp3_2 = pf->ptp_pins->sdp3_2; |
1084 | if (pins->sdp3_3 == invalid) |
1085 | pins->sdp3_3 = pf->ptp_pins->sdp3_3; |
1086 | if (pins->gpio_4 == invalid) |
1087 | pins->gpio_4 = pf->ptp_pins->gpio_4; |
1088 | while (i40e_ptp_pin_led_allowed_states[i].sdp3_2 != end) { |
1089 | if (pins->sdp3_2 == i40e_ptp_pin_led_allowed_states[i].sdp3_2 && |
1090 | pins->sdp3_3 == i40e_ptp_pin_led_allowed_states[i].sdp3_3 && |
1091 | pins->gpio_4 == i40e_ptp_pin_led_allowed_states[i].gpio_4) { |
1092 | pins->led2_0 = |
1093 | i40e_ptp_pin_led_allowed_states[i].led2_0; |
1094 | pins->led2_1 = |
1095 | i40e_ptp_pin_led_allowed_states[i].led2_1; |
1096 | pins->led3_0 = |
1097 | i40e_ptp_pin_led_allowed_states[i].led3_0; |
1098 | pins->led3_1 = |
1099 | i40e_ptp_pin_led_allowed_states[i].led3_1; |
1100 | break; |
1101 | } |
1102 | i++; |
1103 | } |
1104 | if (i40e_ptp_pin_led_allowed_states[i].sdp3_2 == end) { |
1105 | dev_warn(&pf->pdev->dev, |
1106 | "Unsupported PTP pin configuration: SDP3_2: %s, SDP3_3: %s, GPIO_4: %s.\n" , |
1107 | i40e_ptp_gpio_pin_state2str[pins->sdp3_2], |
1108 | i40e_ptp_gpio_pin_state2str[pins->sdp3_3], |
1109 | i40e_ptp_gpio_pin_state2str[pins->gpio_4]); |
1110 | |
1111 | return -EPERM; |
1112 | } |
1113 | memcpy(pf->ptp_pins, pins, sizeof(*pins)); |
1114 | i40e_ptp_set_pins_hw(pf); |
1115 | i40_ptp_reset_timing_events(pf); |
1116 | |
1117 | return 0; |
1118 | } |
1119 | |
1120 | /** |
1121 | * i40e_ptp_alloc_pins - allocate PTP pins structure |
1122 | * @pf: Board private structure |
1123 | * |
1124 | * allocate PTP pins structure |
1125 | **/ |
1126 | int i40e_ptp_alloc_pins(struct i40e_pf *pf) |
1127 | { |
1128 | if (!i40e_is_ptp_pin_dev(hw: &pf->hw)) |
1129 | return 0; |
1130 | |
1131 | pf->ptp_pins = |
1132 | kzalloc(size: sizeof(struct i40e_ptp_pins_settings), GFP_KERNEL); |
1133 | |
1134 | if (!pf->ptp_pins) { |
1135 | dev_warn(&pf->pdev->dev, "Cannot allocate memory for PTP pins structure.\n" ); |
1136 | return -ENOMEM; |
1137 | } |
1138 | |
1139 | pf->ptp_pins->sdp3_2 = off; |
1140 | pf->ptp_pins->sdp3_3 = off; |
1141 | pf->ptp_pins->gpio_4 = off; |
1142 | pf->ptp_pins->led2_0 = high; |
1143 | pf->ptp_pins->led2_1 = high; |
1144 | pf->ptp_pins->led3_0 = high; |
1145 | pf->ptp_pins->led3_1 = high; |
1146 | |
1147 | /* Use PF0 to set pins in HW. Return success for user space tools */ |
1148 | if (pf->hw.pf_id) |
1149 | return 0; |
1150 | |
1151 | i40e_ptp_init_leds_hw(hw: &pf->hw); |
1152 | i40e_ptp_set_pins_hw(pf); |
1153 | |
1154 | return 0; |
1155 | } |
1156 | |
1157 | /** |
1158 | * i40e_ptp_set_timestamp_mode - setup hardware for requested timestamp mode |
1159 | * @pf: Board private structure |
1160 | * @config: hwtstamp settings requested or saved |
1161 | * |
1162 | * Control hardware registers to enter the specific mode requested by the |
1163 | * user. Also used during reset path to ensure that timestamp settings are |
1164 | * maintained. |
1165 | * |
1166 | * Note: modifies config in place, and may update the requested mode to be |
1167 | * more broad if the specific filter is not directly supported. |
1168 | **/ |
1169 | static int i40e_ptp_set_timestamp_mode(struct i40e_pf *pf, |
1170 | struct hwtstamp_config *config) |
1171 | { |
1172 | struct i40e_hw *hw = &pf->hw; |
1173 | u32 tsyntype, regval; |
1174 | |
1175 | /* Selects external trigger to cause event */ |
1176 | regval = rd32(hw, I40E_PRTTSYN_AUX_0(0)); |
1177 | /* Bit 17:16 is EVNTLVL, 01B rising edge */ |
1178 | regval &= 0; |
1179 | regval |= (1 << I40E_PRTTSYN_AUX_0_EVNTLVL_SHIFT); |
1180 | /* regval: 0001 0000 0000 0000 0000 */ |
1181 | wr32(hw, I40E_PRTTSYN_AUX_0(0), regval); |
1182 | |
1183 | /* Enabel interrupts */ |
1184 | regval = rd32(hw, I40E_PRTTSYN_CTL0); |
1185 | regval |= 1 << I40E_PRTTSYN_CTL0_EVENT_INT_ENA_SHIFT; |
1186 | wr32(hw, I40E_PRTTSYN_CTL0, regval); |
1187 | |
1188 | INIT_WORK(&pf->ptp_extts0_work, i40e_ptp_extts0_work); |
1189 | |
1190 | switch (config->tx_type) { |
1191 | case HWTSTAMP_TX_OFF: |
1192 | pf->ptp_tx = false; |
1193 | break; |
1194 | case HWTSTAMP_TX_ON: |
1195 | pf->ptp_tx = true; |
1196 | break; |
1197 | default: |
1198 | return -ERANGE; |
1199 | } |
1200 | |
1201 | switch (config->rx_filter) { |
1202 | case HWTSTAMP_FILTER_NONE: |
1203 | pf->ptp_rx = false; |
1204 | /* We set the type to V1, but do not enable UDP packet |
1205 | * recognition. In this way, we should be as close to |
1206 | * disabling PTP Rx timestamps as possible since V1 packets |
1207 | * are always UDP, since L2 packets are a V2 feature. |
1208 | */ |
1209 | tsyntype = I40E_PRTTSYN_CTL1_TSYNTYPE_V1; |
1210 | break; |
1211 | case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: |
1212 | case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: |
1213 | case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: |
1214 | if (!test_bit(I40E_HW_CAP_PTP_L4, pf->hw.caps)) |
1215 | return -ERANGE; |
1216 | pf->ptp_rx = true; |
1217 | tsyntype = I40E_PRTTSYN_CTL1_V1MESSTYPE0_MASK | |
1218 | I40E_PRTTSYN_CTL1_TSYNTYPE_V1 | |
1219 | I40E_PRTTSYN_CTL1_UDP_ENA_MASK; |
1220 | config->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; |
1221 | break; |
1222 | case HWTSTAMP_FILTER_PTP_V2_EVENT: |
1223 | case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: |
1224 | case HWTSTAMP_FILTER_PTP_V2_SYNC: |
1225 | case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: |
1226 | case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: |
1227 | case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: |
1228 | if (!test_bit(I40E_HW_CAP_PTP_L4, pf->hw.caps)) |
1229 | return -ERANGE; |
1230 | fallthrough; |
1231 | case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: |
1232 | case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: |
1233 | case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: |
1234 | pf->ptp_rx = true; |
1235 | tsyntype = I40E_PRTTSYN_CTL1_V2MESSTYPE0_MASK | |
1236 | I40E_PRTTSYN_CTL1_TSYNTYPE_V2; |
1237 | if (test_bit(I40E_HW_CAP_PTP_L4, pf->hw.caps)) { |
1238 | tsyntype |= I40E_PRTTSYN_CTL1_UDP_ENA_MASK; |
1239 | config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; |
1240 | } else { |
1241 | config->rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT; |
1242 | } |
1243 | break; |
1244 | case HWTSTAMP_FILTER_NTP_ALL: |
1245 | case HWTSTAMP_FILTER_ALL: |
1246 | default: |
1247 | return -ERANGE; |
1248 | } |
1249 | |
1250 | /* Clear out all 1588-related registers to clear and unlatch them. */ |
1251 | spin_lock_bh(lock: &pf->ptp_rx_lock); |
1252 | rd32(hw, I40E_PRTTSYN_STAT_0); |
1253 | rd32(hw, I40E_PRTTSYN_TXTIME_H); |
1254 | rd32(hw, I40E_PRTTSYN_RXTIME_H(0)); |
1255 | rd32(hw, I40E_PRTTSYN_RXTIME_H(1)); |
1256 | rd32(hw, I40E_PRTTSYN_RXTIME_H(2)); |
1257 | rd32(hw, I40E_PRTTSYN_RXTIME_H(3)); |
1258 | pf->latch_event_flags = 0; |
1259 | spin_unlock_bh(lock: &pf->ptp_rx_lock); |
1260 | |
1261 | /* Enable/disable the Tx timestamp interrupt based on user input. */ |
1262 | regval = rd32(hw, I40E_PRTTSYN_CTL0); |
1263 | if (pf->ptp_tx) |
1264 | regval |= I40E_PRTTSYN_CTL0_TXTIME_INT_ENA_MASK; |
1265 | else |
1266 | regval &= ~I40E_PRTTSYN_CTL0_TXTIME_INT_ENA_MASK; |
1267 | wr32(hw, I40E_PRTTSYN_CTL0, regval); |
1268 | |
1269 | regval = rd32(hw, I40E_PFINT_ICR0_ENA); |
1270 | if (pf->ptp_tx) |
1271 | regval |= I40E_PFINT_ICR0_ENA_TIMESYNC_MASK; |
1272 | else |
1273 | regval &= ~I40E_PFINT_ICR0_ENA_TIMESYNC_MASK; |
1274 | wr32(hw, I40E_PFINT_ICR0_ENA, regval); |
1275 | |
1276 | /* Although there is no simple on/off switch for Rx, we "disable" Rx |
1277 | * timestamps by setting to V1 only mode and clear the UDP |
1278 | * recognition. This ought to disable all PTP Rx timestamps as V1 |
1279 | * packets are always over UDP. Note that software is configured to |
1280 | * ignore Rx timestamps via the pf->ptp_rx flag. |
1281 | */ |
1282 | regval = rd32(hw, I40E_PRTTSYN_CTL1); |
1283 | /* clear everything but the enable bit */ |
1284 | regval &= I40E_PRTTSYN_CTL1_TSYNENA_MASK; |
1285 | /* now enable bits for desired Rx timestamps */ |
1286 | regval |= tsyntype; |
1287 | wr32(hw, I40E_PRTTSYN_CTL1, regval); |
1288 | |
1289 | return 0; |
1290 | } |
1291 | |
1292 | /** |
1293 | * i40e_ptp_set_ts_config - ioctl interface to control the HW timestamping |
1294 | * @pf: Board private structure |
1295 | * @ifr: ioctl data |
1296 | * |
1297 | * Respond to the user filter requests and make the appropriate hardware |
1298 | * changes here. The XL710 cannot support splitting of the Tx/Rx timestamping |
1299 | * logic, so keep track in software of whether to indicate these timestamps |
1300 | * or not. |
1301 | * |
1302 | * It is permissible to "upgrade" the user request to a broader filter, as long |
1303 | * as the user receives the timestamps they care about and the user is notified |
1304 | * the filter has been broadened. |
1305 | **/ |
1306 | int i40e_ptp_set_ts_config(struct i40e_pf *pf, struct ifreq *ifr) |
1307 | { |
1308 | struct hwtstamp_config config; |
1309 | int err; |
1310 | |
1311 | if (!test_bit(I40E_FLAG_PTP_ENA, pf->flags)) |
1312 | return -EOPNOTSUPP; |
1313 | |
1314 | if (copy_from_user(to: &config, from: ifr->ifr_data, n: sizeof(config))) |
1315 | return -EFAULT; |
1316 | |
1317 | err = i40e_ptp_set_timestamp_mode(pf, config: &config); |
1318 | if (err) |
1319 | return err; |
1320 | |
1321 | /* save these settings for future reference */ |
1322 | pf->tstamp_config = config; |
1323 | |
1324 | return copy_to_user(to: ifr->ifr_data, from: &config, n: sizeof(config)) ? |
1325 | -EFAULT : 0; |
1326 | } |
1327 | |
1328 | /** |
1329 | * i40e_init_pin_config - initialize pins. |
1330 | * @pf: private board structure |
1331 | * |
1332 | * Initialize pins for external clock source. |
1333 | * Return 0 on success or error code on failure. |
1334 | **/ |
1335 | static int i40e_init_pin_config(struct i40e_pf *pf) |
1336 | { |
1337 | int i; |
1338 | |
1339 | pf->ptp_caps.n_pins = 3; |
1340 | pf->ptp_caps.n_ext_ts = 2; |
1341 | pf->ptp_caps.pps = 1; |
1342 | pf->ptp_caps.n_per_out = 2; |
1343 | |
1344 | pf->ptp_caps.pin_config = kcalloc(n: pf->ptp_caps.n_pins, |
1345 | size: sizeof(*pf->ptp_caps.pin_config), |
1346 | GFP_KERNEL); |
1347 | if (!pf->ptp_caps.pin_config) |
1348 | return -ENOMEM; |
1349 | |
1350 | for (i = 0; i < pf->ptp_caps.n_pins; i++) { |
1351 | snprintf(buf: pf->ptp_caps.pin_config[i].name, |
1352 | size: sizeof(pf->ptp_caps.pin_config[i].name), |
1353 | fmt: "%s" , sdp_desc[i].name); |
1354 | pf->ptp_caps.pin_config[i].index = sdp_desc[i].index; |
1355 | pf->ptp_caps.pin_config[i].func = PTP_PF_NONE; |
1356 | pf->ptp_caps.pin_config[i].chan = sdp_desc[i].chan; |
1357 | } |
1358 | |
1359 | pf->ptp_caps.verify = i40e_ptp_verify; |
1360 | pf->ptp_caps.enable = i40e_ptp_feature_enable; |
1361 | |
1362 | pf->ptp_caps.pps = 1; |
1363 | |
1364 | return 0; |
1365 | } |
1366 | |
1367 | /** |
1368 | * i40e_ptp_create_clock - Create PTP clock device for userspace |
1369 | * @pf: Board private structure |
1370 | * |
1371 | * This function creates a new PTP clock device. It only creates one if we |
1372 | * don't already have one, so it is safe to call. Will return error if it |
1373 | * can't create one, but success if we already have a device. Should be used |
1374 | * by i40e_ptp_init to create clock initially, and prevent global resets from |
1375 | * creating new clock devices. |
1376 | **/ |
1377 | static long i40e_ptp_create_clock(struct i40e_pf *pf) |
1378 | { |
1379 | /* no need to create a clock device if we already have one */ |
1380 | if (!IS_ERR_OR_NULL(ptr: pf->ptp_clock)) |
1381 | return 0; |
1382 | |
1383 | strscpy(pf->ptp_caps.name, i40e_driver_name, |
1384 | sizeof(pf->ptp_caps.name) - 1); |
1385 | pf->ptp_caps.owner = THIS_MODULE; |
1386 | pf->ptp_caps.max_adj = 999999999; |
1387 | pf->ptp_caps.adjfine = i40e_ptp_adjfine; |
1388 | pf->ptp_caps.adjtime = i40e_ptp_adjtime; |
1389 | pf->ptp_caps.gettimex64 = i40e_ptp_gettimex; |
1390 | pf->ptp_caps.settime64 = i40e_ptp_settime; |
1391 | if (i40e_is_ptp_pin_dev(hw: &pf->hw)) { |
1392 | int err = i40e_init_pin_config(pf); |
1393 | |
1394 | if (err) |
1395 | return err; |
1396 | } |
1397 | |
1398 | /* Attempt to register the clock before enabling the hardware. */ |
1399 | pf->ptp_clock = ptp_clock_register(info: &pf->ptp_caps, parent: &pf->pdev->dev); |
1400 | if (IS_ERR(ptr: pf->ptp_clock)) |
1401 | return PTR_ERR(ptr: pf->ptp_clock); |
1402 | |
1403 | /* clear the hwtstamp settings here during clock create, instead of |
1404 | * during regular init, so that we can maintain settings across a |
1405 | * reset or suspend. |
1406 | */ |
1407 | pf->tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE; |
1408 | pf->tstamp_config.tx_type = HWTSTAMP_TX_OFF; |
1409 | |
1410 | /* Set the previous "reset" time to the current Kernel clock time */ |
1411 | ktime_get_real_ts64(tv: &pf->ptp_prev_hw_time); |
1412 | pf->ptp_reset_start = ktime_get(); |
1413 | |
1414 | return 0; |
1415 | } |
1416 | |
1417 | /** |
1418 | * i40e_ptp_save_hw_time - Save the current PTP time as ptp_prev_hw_time |
1419 | * @pf: Board private structure |
1420 | * |
1421 | * Read the current PTP time and save it into pf->ptp_prev_hw_time. This should |
1422 | * be called at the end of preparing to reset, just before hardware reset |
1423 | * occurs, in order to preserve the PTP time as close as possible across |
1424 | * resets. |
1425 | */ |
1426 | void i40e_ptp_save_hw_time(struct i40e_pf *pf) |
1427 | { |
1428 | /* don't try to access the PTP clock if it's not enabled */ |
1429 | if (!test_bit(I40E_FLAG_PTP_ENA, pf->flags)) |
1430 | return; |
1431 | |
1432 | i40e_ptp_gettimex(ptp: &pf->ptp_caps, ts: &pf->ptp_prev_hw_time, NULL); |
1433 | /* Get a monotonic starting time for this reset */ |
1434 | pf->ptp_reset_start = ktime_get(); |
1435 | } |
1436 | |
1437 | /** |
1438 | * i40e_ptp_restore_hw_time - Restore the ptp_prev_hw_time + delta to PTP regs |
1439 | * @pf: Board private structure |
1440 | * |
1441 | * Restore the PTP hardware clock registers. We previously cached the PTP |
1442 | * hardware time as pf->ptp_prev_hw_time. To be as accurate as possible, |
1443 | * update this value based on the time delta since the time was saved, using |
1444 | * CLOCK_MONOTONIC (via ktime_get()) to calculate the time difference. |
1445 | * |
1446 | * This ensures that the hardware clock is restored to nearly what it should |
1447 | * have been if a reset had not occurred. |
1448 | */ |
1449 | void i40e_ptp_restore_hw_time(struct i40e_pf *pf) |
1450 | { |
1451 | ktime_t delta = ktime_sub(ktime_get(), pf->ptp_reset_start); |
1452 | |
1453 | /* Update the previous HW time with the ktime delta */ |
1454 | timespec64_add_ns(a: &pf->ptp_prev_hw_time, ns: ktime_to_ns(kt: delta)); |
1455 | |
1456 | /* Restore the hardware clock registers */ |
1457 | i40e_ptp_settime(ptp: &pf->ptp_caps, ts: &pf->ptp_prev_hw_time); |
1458 | } |
1459 | |
1460 | /** |
1461 | * i40e_ptp_init - Initialize the 1588 support after device probe or reset |
1462 | * @pf: Board private structure |
1463 | * |
1464 | * This function sets device up for 1588 support. The first time it is run, it |
1465 | * will create a PHC clock device. It does not create a clock device if one |
1466 | * already exists. It also reconfigures the device after a reset. |
1467 | * |
1468 | * The first time a clock is created, i40e_ptp_create_clock will set |
1469 | * pf->ptp_prev_hw_time to the current system time. During resets, it is |
1470 | * expected that this timespec will be set to the last known PTP clock time, |
1471 | * in order to preserve the clock time as close as possible across a reset. |
1472 | **/ |
1473 | void i40e_ptp_init(struct i40e_pf *pf) |
1474 | { |
1475 | struct net_device *netdev = pf->vsi[pf->lan_vsi]->netdev; |
1476 | struct i40e_hw *hw = &pf->hw; |
1477 | u32 pf_id; |
1478 | long err; |
1479 | |
1480 | /* Only one PF is assigned to control 1588 logic per port. Do not |
1481 | * enable any support for PFs not assigned via PRTTSYN_CTL0.PF_ID |
1482 | */ |
1483 | pf_id = FIELD_GET(I40E_PRTTSYN_CTL0_PF_ID_MASK, |
1484 | rd32(hw, I40E_PRTTSYN_CTL0)); |
1485 | if (hw->pf_id != pf_id) { |
1486 | clear_bit(nr: I40E_FLAG_PTP_ENA, addr: pf->flags); |
1487 | dev_info(&pf->pdev->dev, "%s: PTP not supported on %s\n" , |
1488 | __func__, |
1489 | netdev->name); |
1490 | return; |
1491 | } |
1492 | |
1493 | mutex_init(&pf->tmreg_lock); |
1494 | spin_lock_init(&pf->ptp_rx_lock); |
1495 | |
1496 | /* ensure we have a clock device */ |
1497 | err = i40e_ptp_create_clock(pf); |
1498 | if (err) { |
1499 | pf->ptp_clock = NULL; |
1500 | dev_err(&pf->pdev->dev, "%s: ptp_clock_register failed\n" , |
1501 | __func__); |
1502 | } else if (pf->ptp_clock) { |
1503 | u32 regval; |
1504 | |
1505 | if (pf->hw.debug_mask & I40E_DEBUG_LAN) |
1506 | dev_info(&pf->pdev->dev, "PHC enabled\n" ); |
1507 | set_bit(nr: I40E_FLAG_PTP_ENA, addr: pf->flags); |
1508 | |
1509 | /* Ensure the clocks are running. */ |
1510 | regval = rd32(hw, I40E_PRTTSYN_CTL0); |
1511 | regval |= I40E_PRTTSYN_CTL0_TSYNENA_MASK; |
1512 | wr32(hw, I40E_PRTTSYN_CTL0, regval); |
1513 | regval = rd32(hw, I40E_PRTTSYN_CTL1); |
1514 | regval |= I40E_PRTTSYN_CTL1_TSYNENA_MASK; |
1515 | wr32(hw, I40E_PRTTSYN_CTL1, regval); |
1516 | |
1517 | /* Set the increment value per clock tick. */ |
1518 | i40e_ptp_set_increment(pf); |
1519 | |
1520 | /* reset timestamping mode */ |
1521 | i40e_ptp_set_timestamp_mode(pf, config: &pf->tstamp_config); |
1522 | |
1523 | /* Restore the clock time based on last known value */ |
1524 | i40e_ptp_restore_hw_time(pf); |
1525 | } |
1526 | |
1527 | i40e_ptp_set_1pps_signal_hw(pf); |
1528 | } |
1529 | |
1530 | /** |
1531 | * i40e_ptp_stop - Disable the driver/hardware support and unregister the PHC |
1532 | * @pf: Board private structure |
1533 | * |
1534 | * This function handles the cleanup work required from the initialization by |
1535 | * clearing out the important information and unregistering the PHC. |
1536 | **/ |
1537 | void i40e_ptp_stop(struct i40e_pf *pf) |
1538 | { |
1539 | struct i40e_hw *hw = &pf->hw; |
1540 | u32 regval; |
1541 | |
1542 | clear_bit(nr: I40E_FLAG_PTP_ENA, addr: pf->flags); |
1543 | pf->ptp_tx = false; |
1544 | pf->ptp_rx = false; |
1545 | |
1546 | if (pf->ptp_tx_skb) { |
1547 | struct sk_buff *skb = pf->ptp_tx_skb; |
1548 | |
1549 | pf->ptp_tx_skb = NULL; |
1550 | clear_bit_unlock(nr: __I40E_PTP_TX_IN_PROGRESS, addr: pf->state); |
1551 | dev_kfree_skb_any(skb); |
1552 | } |
1553 | |
1554 | if (pf->ptp_clock) { |
1555 | ptp_clock_unregister(ptp: pf->ptp_clock); |
1556 | pf->ptp_clock = NULL; |
1557 | dev_info(&pf->pdev->dev, "%s: removed PHC on %s\n" , __func__, |
1558 | pf->vsi[pf->lan_vsi]->netdev->name); |
1559 | } |
1560 | |
1561 | if (i40e_is_ptp_pin_dev(hw: &pf->hw)) { |
1562 | i40e_ptp_set_pin_hw(hw, I40E_SDP3_2, state: off); |
1563 | i40e_ptp_set_pin_hw(hw, I40E_SDP3_3, state: off); |
1564 | i40e_ptp_set_pin_hw(hw, I40E_GPIO_4, state: off); |
1565 | } |
1566 | |
1567 | regval = rd32(hw, I40E_PRTTSYN_AUX_0(0)); |
1568 | regval &= ~I40E_PRTTSYN_AUX_0_PTPFLAG_MASK; |
1569 | wr32(hw, I40E_PRTTSYN_AUX_0(0), regval); |
1570 | |
1571 | /* Disable interrupts */ |
1572 | regval = rd32(hw, I40E_PRTTSYN_CTL0); |
1573 | regval &= ~I40E_PRTTSYN_CTL0_EVENT_INT_ENA_MASK; |
1574 | wr32(hw, I40E_PRTTSYN_CTL0, regval); |
1575 | |
1576 | i40e_ptp_free_pins(pf); |
1577 | } |
1578 | |