aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacob Keller <jacob.e.keller@intel.com>2012-08-24 03:46:54 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2012-10-03 10:57:04 -0400
commitdb0677fa29862d29e9956980d9fab43c52179e34 (patch)
tree8c96754fbc9507c860e246f55d7ac1710eb3beae
parent8208367371b7f581dd13fe8bf28f8d7f17f4bf32 (diff)
ixgbe: (PTP) Fix PPS interrupt code
Driver was enabling PPS interrupt even when user wasn't enabling it via the ptp core. This patch fixes the PPS so that it is only enabled explicitly, and moves the interrupt enabling code into the correct location in the driver Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Cc: Stable <stable@vger.kernel.org> [3.5] Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c13
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c96
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 */
121static void ixgbe_ptp_enable_sdp(struct ixgbe_adapter *adapter) 120static 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 */
189static 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 */
990void ixgbe_ptp_stop(struct ixgbe_adapter *adapter) 967void 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);