};
/**
- * ixgbe_ptp_enable_sdp
+ * ixgbe_ptp_setup_sdp
* @hw: the hardware private structure
- * @shift: the clock shift for calculating nanoseconds
*
- * this function enables the clock out feature on the sdp0 for the
- * X540 device. It will create a 1second periodic output that can be
- * used as the PPS (via an interrupt).
+ * this function enables or disables the clock out feature on SDP0 for
+ * the X540 device. It will create a 1second periodic output that can
+ * be used as the PPS (via an interrupt).
*
* It calculates when the systime will be on an exact second, and then
* aligns the start of the PPS signal to that value. The shift is
* necessary because it can change based on the link speed.
*/
-static void ixgbe_ptp_enable_sdp(struct ixgbe_adapter *adapter)
+static void ixgbe_ptp_setup_sdp(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
int shift = adapter->cc.shift;
u32 esdp, tsauxc, clktiml, clktimh, trgttiml, trgttimh, rem;
u64 ns = 0, clock_edge = 0;
- switch (hw->mac.type) {
- case ixgbe_mac_X540:
+ if ((adapter->flags2 & IXGBE_FLAG2_PTP_PPS_ENABLED) &&
+ (hw->mac.type == ixgbe_mac_X540)) {
+
+ /* disable the pin first */
+ IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, 0x0);
+ IXGBE_WRITE_FLUSH(hw);
+
esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
/*
- * enable the SDP0 pin as output, and connected to the native
- * function for Timesync (ClockOut)
+ * enable the SDP0 pin as output, and connected to the
+ * native function for Timesync (ClockOut)
*/
esdp |= (IXGBE_ESDP_SDP0_DIR |
IXGBE_ESDP_SDP0_NATIVE);
/*
- * enable the Clock Out feature on SDP0, and allow interrupts
- * to occur when the pin changes
+ * enable the Clock Out feature on SDP0, and allow
+ * interrupts to occur when the pin changes
*/
tsauxc = (IXGBE_TSAUXC_EN_CLK |
IXGBE_TSAUXC_SYNCLK |
IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, tsauxc);
-
- IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EICR_TIMESYNC);
- IXGBE_WRITE_FLUSH(hw);
- break;
- default:
- break;
+ } else {
+ IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, 0x0);
}
-}
-/**
- * ixgbe_ptp_disable_sdp
- * @hw: the private hardware structure
- *
- * this function disables the auxiliary SDP clock out feature
- */
-static void ixgbe_ptp_disable_sdp(struct ixgbe_hw *hw)
-{
- IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EICR_TIMESYNC);
- IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, 0);
IXGBE_WRITE_FLUSH(hw);
}
unsigned long flags;
u64 now;
- ixgbe_ptp_disable_sdp(&adapter->hw);
spin_lock_irqsave(&adapter->tmreg_lock, flags);
now = timecounter_read(&adapter->tc);
now);
spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
- ixgbe_ptp_enable_sdp(adapter);
+
+ ixgbe_ptp_setup_sdp(adapter);
return 0;
}
ns = ts->tv_sec * 1000000000ULL;
ns += ts->tv_nsec;
- ixgbe_ptp_disable_sdp(&adapter->hw);
-
/* reset the timecounter */
spin_lock_irqsave(&adapter->tmreg_lock, flags);
timecounter_init(&adapter->tc, &adapter->cc, ns);
spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
- ixgbe_ptp_enable_sdp(adapter);
+ ixgbe_ptp_setup_sdp(adapter);
return 0;
}
if (on)
adapter->flags2 |= IXGBE_FLAG2_PTP_PPS_ENABLED;
else
- adapter->flags2 &=
- ~IXGBE_FLAG2_PTP_PPS_ENABLED;
+ adapter->flags2 &= ~IXGBE_FLAG2_PTP_PPS_ENABLED;
+
+ ixgbe_ptp_setup_sdp(adapter);
return 0;
default:
break;
struct ixgbe_hw *hw = &adapter->hw;
struct ptp_clock_event event;
- event.type = PTP_CLOCK_PPS;
-
- /* Make sure ptp clock is valid, and PPS event enabled */
- if (!adapter->ptp_clock ||
- !(adapter->flags2 & IXGBE_FLAG2_PTP_PPS_ENABLED))
- return;
-
- if (unlikely(eicr & IXGBE_EICR_TIMESYNC)) {
- switch (hw->mac.type) {
- case ixgbe_mac_X540:
- ptp_clock_event(adapter->ptp_clock, &event);
- break;
- default:
- break;
- }
+ switch (hw->mac.type) {
+ case ixgbe_mac_X540:
+ ptp_clock_event(adapter->ptp_clock, &event);
+ break;
+ default:
+ break;
}
}
if (adapter->cycle_speed == cycle_speed && timinca)
return;
- /* disable the SDP clock out */
- ixgbe_ptp_disable_sdp(hw);
-
/**
* Scale the NIC cycle counter by a large factor so that
* relatively small corrections to the frequency can be added
spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
- /* Now that the shift has been calculated and the systime
+ /*
+ * Now that the shift has been calculated and the systime
* registers reset, (re-)enable the Clock out feature
*/
- ixgbe_ptp_enable_sdp(adapter);
+ ixgbe_ptp_setup_sdp(adapter);
}
/**
*/
void ixgbe_ptp_stop(struct ixgbe_adapter *adapter)
{
- ixgbe_ptp_disable_sdp(&adapter->hw);
-
/* stop the overflow check task */
- adapter->flags2 &= ~IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED;
+ adapter->flags2 &= ~(IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED |
+ IXGBE_FLAG2_PTP_PPS_ENABLED);
+
+ ixgbe_ptp_setup_sdp(adapter);
if (adapter->ptp_clock) {
ptp_clock_unregister(adapter->ptp_clock);