diff options
-rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 13 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 96 |
2 files changed, 48 insertions, 61 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 868af6938219..c407b2f0f0f9 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | |||
@@ -2322,6 +2322,12 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter, bool queues, | |||
2322 | default: | 2322 | default: |
2323 | break; | 2323 | break; |
2324 | } | 2324 | } |
2325 | |||
2326 | #ifdef CONFIG_IXGBE_PTP | ||
2327 | if (adapter->hw.mac.type == ixgbe_mac_X540) | ||
2328 | mask |= IXGBE_EIMS_TIMESYNC; | ||
2329 | #endif | ||
2330 | |||
2325 | if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) && | 2331 | if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) && |
2326 | !(adapter->flags2 & IXGBE_FLAG2_FDIR_REQUIRES_REINIT)) | 2332 | !(adapter->flags2 & IXGBE_FLAG2_FDIR_REQUIRES_REINIT)) |
2327 | mask |= IXGBE_EIMS_FLOW_DIR; | 2333 | mask |= IXGBE_EIMS_FLOW_DIR; |
@@ -2385,8 +2391,10 @@ static irqreturn_t ixgbe_msix_other(int irq, void *data) | |||
2385 | } | 2391 | } |
2386 | 2392 | ||
2387 | ixgbe_check_fan_failure(adapter, eicr); | 2393 | ixgbe_check_fan_failure(adapter, eicr); |
2394 | |||
2388 | #ifdef CONFIG_IXGBE_PTP | 2395 | #ifdef CONFIG_IXGBE_PTP |
2389 | ixgbe_ptp_check_pps_event(adapter, eicr); | 2396 | if (unlikely(eicr & IXGBE_EICR_TIMESYNC)) |
2397 | ixgbe_ptp_check_pps_event(adapter, eicr); | ||
2390 | #endif | 2398 | #endif |
2391 | 2399 | ||
2392 | /* re-enable the original interrupt state, no lsc, no queues */ | 2400 | /* re-enable the original interrupt state, no lsc, no queues */ |
@@ -2580,7 +2588,8 @@ static irqreturn_t ixgbe_intr(int irq, void *data) | |||
2580 | 2588 | ||
2581 | ixgbe_check_fan_failure(adapter, eicr); | 2589 | ixgbe_check_fan_failure(adapter, eicr); |
2582 | #ifdef CONFIG_IXGBE_PTP | 2590 | #ifdef CONFIG_IXGBE_PTP |
2583 | ixgbe_ptp_check_pps_event(adapter, eicr); | 2591 | if (unlikely(eicr & IXGBE_EICR_TIMESYNC)) |
2592 | ixgbe_ptp_check_pps_event(adapter, eicr); | ||
2584 | #endif | 2593 | #endif |
2585 | 2594 | ||
2586 | /* would disable interrupts here but EIAM disabled it */ | 2595 | /* would disable interrupts here but EIAM disabled it */ |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c index 58d930dc6766..d9291316ee9f 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | |||
@@ -106,39 +106,43 @@ static struct sock_filter ptp_filter[] = { | |||
106 | }; | 106 | }; |
107 | 107 | ||
108 | /** | 108 | /** |
109 | * ixgbe_ptp_enable_sdp | 109 | * ixgbe_ptp_setup_sdp |
110 | * @hw: the hardware private structure | 110 | * @hw: the hardware private structure |
111 | * @shift: the clock shift for calculating nanoseconds | ||
112 | * | 111 | * |
113 | * this function enables the clock out feature on the sdp0 for the | 112 | * this function enables or disables the clock out feature on SDP0 for |
114 | * X540 device. It will create a 1second periodic output that can be | 113 | * the X540 device. It will create a 1second periodic output that can |
115 | * used as the PPS (via an interrupt). | 114 | * be used as the PPS (via an interrupt). |
116 | * | 115 | * |
117 | * It calculates when the systime will be on an exact second, and then | 116 | * It calculates when the systime will be on an exact second, and then |
118 | * aligns the start of the PPS signal to that value. The shift is | 117 | * aligns the start of the PPS signal to that value. The shift is |
119 | * necessary because it can change based on the link speed. | 118 | * necessary because it can change based on the link speed. |
120 | */ | 119 | */ |
121 | static void ixgbe_ptp_enable_sdp(struct ixgbe_adapter *adapter) | 120 | static void ixgbe_ptp_setup_sdp(struct ixgbe_adapter *adapter) |
122 | { | 121 | { |
123 | struct ixgbe_hw *hw = &adapter->hw; | 122 | struct ixgbe_hw *hw = &adapter->hw; |
124 | int shift = adapter->cc.shift; | 123 | int shift = adapter->cc.shift; |
125 | u32 esdp, tsauxc, clktiml, clktimh, trgttiml, trgttimh, rem; | 124 | u32 esdp, tsauxc, clktiml, clktimh, trgttiml, trgttimh, rem; |
126 | u64 ns = 0, clock_edge = 0; | 125 | u64 ns = 0, clock_edge = 0; |
127 | 126 | ||
128 | switch (hw->mac.type) { | 127 | if ((adapter->flags2 & IXGBE_FLAG2_PTP_PPS_ENABLED) && |
129 | case ixgbe_mac_X540: | 128 | (hw->mac.type == ixgbe_mac_X540)) { |
129 | |||
130 | /* disable the pin first */ | ||
131 | IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, 0x0); | ||
132 | IXGBE_WRITE_FLUSH(hw); | ||
133 | |||
130 | esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); | 134 | esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); |
131 | 135 | ||
132 | /* | 136 | /* |
133 | * enable the SDP0 pin as output, and connected to the native | 137 | * enable the SDP0 pin as output, and connected to the |
134 | * function for Timesync (ClockOut) | 138 | * native function for Timesync (ClockOut) |
135 | */ | 139 | */ |
136 | esdp |= (IXGBE_ESDP_SDP0_DIR | | 140 | esdp |= (IXGBE_ESDP_SDP0_DIR | |
137 | IXGBE_ESDP_SDP0_NATIVE); | 141 | IXGBE_ESDP_SDP0_NATIVE); |
138 | 142 | ||
139 | /* | 143 | /* |
140 | * enable the Clock Out feature on SDP0, and allow interrupts | 144 | * enable the Clock Out feature on SDP0, and allow |
141 | * to occur when the pin changes | 145 | * interrupts to occur when the pin changes |
142 | */ | 146 | */ |
143 | tsauxc = (IXGBE_TSAUXC_EN_CLK | | 147 | tsauxc = (IXGBE_TSAUXC_EN_CLK | |
144 | IXGBE_TSAUXC_SYNCLK | | 148 | IXGBE_TSAUXC_SYNCLK | |
@@ -171,25 +175,10 @@ static void ixgbe_ptp_enable_sdp(struct ixgbe_adapter *adapter) | |||
171 | 175 | ||
172 | IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); | 176 | IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); |
173 | IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, tsauxc); | 177 | IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, tsauxc); |
174 | 178 | } else { | |
175 | IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EICR_TIMESYNC); | 179 | IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, 0x0); |
176 | IXGBE_WRITE_FLUSH(hw); | ||
177 | break; | ||
178 | default: | ||
179 | break; | ||
180 | } | 180 | } |
181 | } | ||
182 | 181 | ||
183 | /** | ||
184 | * ixgbe_ptp_disable_sdp | ||
185 | * @hw: the private hardware structure | ||
186 | * | ||
187 | * this function disables the auxiliary SDP clock out feature | ||
188 | */ | ||
189 | static void ixgbe_ptp_disable_sdp(struct ixgbe_hw *hw) | ||
190 | { | ||
191 | IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EICR_TIMESYNC); | ||
192 | IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, 0); | ||
193 | IXGBE_WRITE_FLUSH(hw); | 182 | IXGBE_WRITE_FLUSH(hw); |
194 | } | 183 | } |
195 | 184 | ||
@@ -275,7 +264,6 @@ static int ixgbe_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) | |||
275 | unsigned long flags; | 264 | unsigned long flags; |
276 | u64 now; | 265 | u64 now; |
277 | 266 | ||
278 | ixgbe_ptp_disable_sdp(&adapter->hw); | ||
279 | spin_lock_irqsave(&adapter->tmreg_lock, flags); | 267 | spin_lock_irqsave(&adapter->tmreg_lock, flags); |
280 | 268 | ||
281 | now = timecounter_read(&adapter->tc); | 269 | now = timecounter_read(&adapter->tc); |
@@ -287,7 +275,8 @@ static int ixgbe_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) | |||
287 | now); | 275 | now); |
288 | 276 | ||
289 | spin_unlock_irqrestore(&adapter->tmreg_lock, flags); | 277 | spin_unlock_irqrestore(&adapter->tmreg_lock, flags); |
290 | ixgbe_ptp_enable_sdp(adapter); | 278 | |
279 | ixgbe_ptp_setup_sdp(adapter); | ||
291 | 280 | ||
292 | return 0; | 281 | return 0; |
293 | } | 282 | } |
@@ -337,14 +326,12 @@ static int ixgbe_ptp_settime(struct ptp_clock_info *ptp, | |||
337 | ns = ts->tv_sec * 1000000000ULL; | 326 | ns = ts->tv_sec * 1000000000ULL; |
338 | ns += ts->tv_nsec; | 327 | ns += ts->tv_nsec; |
339 | 328 | ||
340 | ixgbe_ptp_disable_sdp(&adapter->hw); | ||
341 | |||
342 | /* reset the timecounter */ | 329 | /* reset the timecounter */ |
343 | spin_lock_irqsave(&adapter->tmreg_lock, flags); | 330 | spin_lock_irqsave(&adapter->tmreg_lock, flags); |
344 | timecounter_init(&adapter->tc, &adapter->cc, ns); | 331 | timecounter_init(&adapter->tc, &adapter->cc, ns); |
345 | spin_unlock_irqrestore(&adapter->tmreg_lock, flags); | 332 | spin_unlock_irqrestore(&adapter->tmreg_lock, flags); |
346 | 333 | ||
347 | ixgbe_ptp_enable_sdp(adapter); | 334 | ixgbe_ptp_setup_sdp(adapter); |
348 | return 0; | 335 | return 0; |
349 | } | 336 | } |
350 | 337 | ||
@@ -375,8 +362,9 @@ static int ixgbe_ptp_enable(struct ptp_clock_info *ptp, | |||
375 | if (on) | 362 | if (on) |
376 | adapter->flags2 |= IXGBE_FLAG2_PTP_PPS_ENABLED; | 363 | adapter->flags2 |= IXGBE_FLAG2_PTP_PPS_ENABLED; |
377 | else | 364 | else |
378 | adapter->flags2 &= | 365 | adapter->flags2 &= ~IXGBE_FLAG2_PTP_PPS_ENABLED; |
379 | ~IXGBE_FLAG2_PTP_PPS_ENABLED; | 366 | |
367 | ixgbe_ptp_setup_sdp(adapter); | ||
380 | return 0; | 368 | return 0; |
381 | default: | 369 | default: |
382 | break; | 370 | break; |
@@ -399,21 +387,12 @@ void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr) | |||
399 | struct ixgbe_hw *hw = &adapter->hw; | 387 | struct ixgbe_hw *hw = &adapter->hw; |
400 | struct ptp_clock_event event; | 388 | struct ptp_clock_event event; |
401 | 389 | ||
402 | event.type = PTP_CLOCK_PPS; | 390 | switch (hw->mac.type) { |
403 | 391 | case ixgbe_mac_X540: | |
404 | /* Make sure ptp clock is valid, and PPS event enabled */ | 392 | ptp_clock_event(adapter->ptp_clock, &event); |
405 | if (!adapter->ptp_clock || | 393 | break; |
406 | !(adapter->flags2 & IXGBE_FLAG2_PTP_PPS_ENABLED)) | 394 | default: |
407 | return; | 395 | break; |
408 | |||
409 | if (unlikely(eicr & IXGBE_EICR_TIMESYNC)) { | ||
410 | switch (hw->mac.type) { | ||
411 | case ixgbe_mac_X540: | ||
412 | ptp_clock_event(adapter->ptp_clock, &event); | ||
413 | break; | ||
414 | default: | ||
415 | break; | ||
416 | } | ||
417 | } | 396 | } |
418 | } | 397 | } |
419 | 398 | ||
@@ -831,9 +810,6 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) | |||
831 | if (adapter->cycle_speed == cycle_speed && timinca) | 810 | if (adapter->cycle_speed == cycle_speed && timinca) |
832 | return; | 811 | return; |
833 | 812 | ||
834 | /* disable the SDP clock out */ | ||
835 | ixgbe_ptp_disable_sdp(hw); | ||
836 | |||
837 | /** | 813 | /** |
838 | * Scale the NIC cycle counter by a large factor so that | 814 | * Scale the NIC cycle counter by a large factor so that |
839 | * relatively small corrections to the frequency can be added | 815 | * relatively small corrections to the frequency can be added |
@@ -907,10 +883,11 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) | |||
907 | 883 | ||
908 | spin_unlock_irqrestore(&adapter->tmreg_lock, flags); | 884 | spin_unlock_irqrestore(&adapter->tmreg_lock, flags); |
909 | 885 | ||
910 | /* Now that the shift has been calculated and the systime | 886 | /* |
887 | * Now that the shift has been calculated and the systime | ||
911 | * registers reset, (re-)enable the Clock out feature | 888 | * registers reset, (re-)enable the Clock out feature |
912 | */ | 889 | */ |
913 | ixgbe_ptp_enable_sdp(adapter); | 890 | ixgbe_ptp_setup_sdp(adapter); |
914 | } | 891 | } |
915 | 892 | ||
916 | /** | 893 | /** |
@@ -989,10 +966,11 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter) | |||
989 | */ | 966 | */ |
990 | void ixgbe_ptp_stop(struct ixgbe_adapter *adapter) | 967 | void ixgbe_ptp_stop(struct ixgbe_adapter *adapter) |
991 | { | 968 | { |
992 | ixgbe_ptp_disable_sdp(&adapter->hw); | ||
993 | |||
994 | /* stop the overflow check task */ | 969 | /* stop the overflow check task */ |
995 | adapter->flags2 &= ~IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED; | 970 | adapter->flags2 &= ~(IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED | |
971 | IXGBE_FLAG2_PTP_PPS_ENABLED); | ||
972 | |||
973 | ixgbe_ptp_setup_sdp(adapter); | ||
996 | 974 | ||
997 | if (adapter->ptp_clock) { | 975 | if (adapter->ptp_clock) { |
998 | ptp_clock_unregister(adapter->ptp_clock); | 976 | ptp_clock_unregister(adapter->ptp_clock); |