Message ID | 1339925340-26286-1-git-send-email-jeffrey.t.kirsher@intel.com |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
From: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Date: Sun, 17 Jun 2012 02:29:00 -0700 > From: Jacob Keller <jacob.e.keller@intel.com> > > This patch fixes a potential hole when configuring the cycle counter used to > generate the nanosecond time clock. This clock is based off of the SYSTIME > registers along with the TIMINCA registers. The TIMINCA register determines > the increment to be added to the SYSTIME registers every DMA clock tick. This > register needs to be reconfigured whenever the link-speed changes. However, > the value calculated stays the same when link is down and when link is up. > Misconfiguration can occur if the link status changes due to a reset, which > causes the TIMINCA register to be reset. This reset puts the device in an > unstable state where the SYSTIME registers stop incrementing and the PTP > protocol does not function. > > The solution is to double check the TIMINCA value and always reset the value > if the register is zero. This prevents a misconfiguration bug that halts the > PHC. > > Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> > Acked-by: Don Skidmore <donald.c.skidmore@intel.com> > Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com> > Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Applied, thanks. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c index ddc6a4d..dcebd12 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c @@ -708,6 +708,7 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; u32 incval = 0; + u32 timinca = 0; u32 shift = 0; u32 cycle_speed; unsigned long flags; @@ -730,8 +731,16 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) break; } - /* Bail if the cycle speed didn't change */ - if (adapter->cycle_speed == cycle_speed) + /* + * grab the current TIMINCA value from the register so that it can be + * double checked. If the register value has been cleared, it must be + * reset to the correct value for generating a cyclecounter. If + * TIMINCA is zero, the SYSTIME registers do not increment at all. + */ + timinca = IXGBE_READ_REG(hw, IXGBE_TIMINCA); + + /* Bail if the cycle speed didn't change and TIMINCA is non-zero */ + if (adapter->cycle_speed == cycle_speed && timinca) return; /* disable the SDP clock out */