diff options
Diffstat (limited to 'drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c')
| -rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 718 | 
1 files changed, 530 insertions, 188 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c index e5ba04025e2b..ef1504d41890 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c @@ -1,7 +1,7 @@  /*******************************************************************************    Intel 10 Gigabit PCI Express Linux driver -  Copyright(c) 1999 - 2013 Intel Corporation. +  Copyright(c) 1999 - 2015 Intel Corporation.    This program is free software; you can redistribute it and/or modify it    under the terms and conditions of the GNU General Public License, @@ -27,6 +27,7 @@  *******************************************************************************/  #include "ixgbe.h"  #include <linux/ptp_classify.h> +#include <linux/clocksource.h>  /*   * The 82599 and the X540 do not have true 64bit nanosecond scale @@ -93,7 +94,6 @@  #define IXGBE_INCVAL_SHIFT_82599 7  #define IXGBE_INCPER_SHIFT_82599 24 -#define IXGBE_MAX_TIMEADJ_VALUE  0x7FFFFFFFFFFFFFFFULL  #define IXGBE_OVERFLOW_PERIOD    (HZ * 30)  #define IXGBE_PTP_TX_TIMEOUT     (HZ * 15) @@ -104,8 +104,68 @@   */  #define IXGBE_PTP_PPS_HALF_SECOND 500000000ULL +/* In contrast, the X550 controller has two registers, SYSTIMEH and SYSTIMEL + * which contain measurements of seconds and nanoseconds respectively. This + * matches the standard linux representation of time in the kernel. In addition, + * the X550 also has a SYSTIMER register which represents residue, or + * subnanosecond overflow adjustments. To control clock adjustment, the TIMINCA + * register is used, but it is unlike the X540 and 82599 devices. TIMINCA + * represents units of 2^-32 nanoseconds, and uses 31 bits for this, with the + * high bit representing whether the adjustent is positive or negative. Every + * clock cycle, the X550 will add 12.5 ns + TIMINCA which can result in a range + * of 12 to 13 nanoseconds adjustment. Unlike the 82599 and X540 devices, the + * X550's clock for purposes of SYSTIME generation is constant and not dependent + * on the link speed. + * + *           SYSTIMEH           SYSTIMEL        SYSTIMER + *       +--------------+  +--------------+  +-------------+ + * X550  |      32      |  |      32      |  |     32      | + *       *--------------+  +--------------+  +-------------+ + *       \____seconds___/   \_nanoseconds_/  \__2^-32 ns__/ + * + * This results in a full 96 bits to represent the clock, with 32 bits for + * seconds, 32 bits for nanoseconds (largest value is 0d999999999 or just under + * 1 second) and an additional 32 bits to measure sub nanosecond adjustments for + * underflow of adjustments. + * + * The 32 bits of seconds for the X550 overflows every + *   2^32 / ( 365.25 * 24 * 60 * 60 ) = ~136 years. + * + * In order to adjust the clock frequency for the X550, the TIMINCA register is + * provided. This register represents a + or minus nearly 0.5 ns adjustment to + * the base frequency. It is measured in 2^-32 ns units, with the high bit being + * the sign bit. This register enables software to calculate frequency + * adjustments and apply them directly to the clock rate. + * + * The math for converting ppb into TIMINCA values is fairly straightforward. + *   TIMINCA value = ( Base_Frequency * ppb ) / 1000000000ULL + * + * This assumes that ppb is never high enough to create a value bigger than + * TIMINCA's 31 bits can store. This is ensured by the stack. Calculating this + * value is also simple. + *   Max ppb = ( Max Adjustment / Base Frequency ) / 1000000000ULL + * + * For the X550, the Max adjustment is +/- 0.5 ns, and the base frequency is + * 12.5 nanoseconds. This means that the Max ppb is 39999999 + *   Note: We subtract one in order to ensure no overflow, because the TIMINCA + *         register can only hold slightly under 0.5 nanoseconds. + * + * Because TIMINCA is measured in 2^-32 ns units, we have to convert 12.5 ns + * into 2^-32 units, which is + * + *  12.5 * 2^32 = C80000000 + * + * Some revisions of hardware have a faster base frequency than the registers + * were defined for. To fix this, we use a timecounter structure with the + * proper mult and shift to convert the cycles into nanoseconds of time. + */ +#define IXGBE_X550_BASE_PERIOD 0xC80000000ULL +#define INCVALUE_MASK	0x7FFFFFFF +#define ISGN		0x80000000 +#define MAX_TIMADJ	0x7FFFFFFF +  /** - * ixgbe_ptp_setup_sdp + * ixgbe_ptp_setup_sdp_x540   * @hw: the hardware private structure   *   * this function enables or disables the clock out feature on SDP0 for @@ -116,83 +176,116 @@   * 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_setup_sdp(struct ixgbe_adapter *adapter) +static void ixgbe_ptp_setup_sdp_x540(struct ixgbe_adapter *adapter)  {  	struct ixgbe_hw *hw = &adapter->hw; -	int shift = adapter->cc.shift; +	int shift = adapter->hw_cc.shift;  	u32 esdp, tsauxc, clktiml, clktimh, trgttiml, trgttimh, rem;  	u64 ns = 0, clock_edge = 0; -	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); -		/* disable the pin first */ -		IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, 0x0); -		IXGBE_WRITE_FLUSH(hw); +	if (!(adapter->flags2 & IXGBE_FLAG2_PTP_PPS_ENABLED)) +		return; -		esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); +	esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); -		/* -		 * 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 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 -		 */ -		tsauxc = (IXGBE_TSAUXC_EN_CLK | -			  IXGBE_TSAUXC_SYNCLK | -			  IXGBE_TSAUXC_SDP0_INT); +	/* 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_TSAUXC_SDP0_INT; -		/* clock period (or pulse length) */ -		clktiml = (u32)(IXGBE_PTP_PPS_HALF_SECOND << shift); -		clktimh = (u32)((IXGBE_PTP_PPS_HALF_SECOND << shift) >> 32); +	/* clock period (or pulse length) */ +	clktiml = (u32)(IXGBE_PTP_PPS_HALF_SECOND << shift); +	clktimh = (u32)((IXGBE_PTP_PPS_HALF_SECOND << shift) >> 32); -		/* -		 * Account for the cyclecounter wrap-around value by -		 * using the converted ns value of the current time to -		 * check for when the next aligned second would occur. -		 */ -		clock_edge |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIML); -		clock_edge |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIMH) << 32; -		ns = timecounter_cyc2time(&adapter->tc, clock_edge); +	/* Account for the cyclecounter wrap-around value by +	 * using the converted ns value of the current time to +	 * check for when the next aligned second would occur. +	 */ +	clock_edge |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIML); +	clock_edge |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIMH) << 32; +	ns = timecounter_cyc2time(&adapter->hw_tc, clock_edge); -		div_u64_rem(ns, IXGBE_PTP_PPS_HALF_SECOND, &rem); -		clock_edge += ((IXGBE_PTP_PPS_HALF_SECOND - (u64)rem) << shift); +	div_u64_rem(ns, IXGBE_PTP_PPS_HALF_SECOND, &rem); +	clock_edge += ((IXGBE_PTP_PPS_HALF_SECOND - (u64)rem) << shift); -		/* specify the initial clock start time */ -		trgttiml = (u32)clock_edge; -		trgttimh = (u32)(clock_edge >> 32); +	/* specify the initial clock start time */ +	trgttiml = (u32)clock_edge; +	trgttimh = (u32)(clock_edge >> 32); -		IXGBE_WRITE_REG(hw, IXGBE_CLKTIML, clktiml); -		IXGBE_WRITE_REG(hw, IXGBE_CLKTIMH, clktimh); -		IXGBE_WRITE_REG(hw, IXGBE_TRGTTIML0, trgttiml); -		IXGBE_WRITE_REG(hw, IXGBE_TRGTTIMH0, trgttimh); +	IXGBE_WRITE_REG(hw, IXGBE_CLKTIML, clktiml); +	IXGBE_WRITE_REG(hw, IXGBE_CLKTIMH, clktimh); +	IXGBE_WRITE_REG(hw, IXGBE_TRGTTIML0, trgttiml); +	IXGBE_WRITE_REG(hw, IXGBE_TRGTTIMH0, trgttimh); -		IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); -		IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, tsauxc); -	} else { -		IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, 0x0); -	} +	IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); +	IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, tsauxc);  	IXGBE_WRITE_FLUSH(hw);  }  /** - * ixgbe_ptp_read - read raw cycle counter (to be used by time counter) + * ixgbe_ptp_read_X550 - read cycle counter value + * @hw_cc: cyclecounter structure + * + * This function reads SYSTIME registers. It is called by the cyclecounter + * structure to convert from internal representation into nanoseconds. We need + * this for X550 since some skews do not have expected clock frequency and + * result of SYSTIME is 32bits of "billions of cycles" and 32 bits of + * "cycles", rather than seconds and nanoseconds. + */ +static cycle_t ixgbe_ptp_read_X550(const struct cyclecounter *hw_cc) +{ +	struct ixgbe_adapter *adapter = +			container_of(hw_cc, struct ixgbe_adapter, hw_cc); +	struct ixgbe_hw *hw = &adapter->hw; +	struct timespec64 ts; + +	/* storage is 32 bits of 'billions of cycles' and 32 bits of 'cycles'. +	 * Some revisions of hardware run at a higher frequency and so the +	 * cycles are not guaranteed to be nanoseconds. The timespec64 created +	 * here is used for its math/conversions but does not necessarily +	 * represent nominal time. +	 * +	 * It should be noted that this cyclecounter will overflow at a +	 * non-bitmask field since we have to convert our billions of cycles +	 * into an actual cycles count. This results in some possible weird +	 * situations at high cycle counter stamps. However given that 32 bits +	 * of "seconds" is ~138 years this isn't a problem. Even at the +	 * increased frequency of some revisions, this is still ~103 years. +	 * Since the SYSTIME values start at 0 and we never write them, it is +	 * highly unlikely for the cyclecounter to overflow in practice. +	 */ +	IXGBE_READ_REG(hw, IXGBE_SYSTIMR); +	ts.tv_nsec = IXGBE_READ_REG(hw, IXGBE_SYSTIML); +	ts.tv_sec = IXGBE_READ_REG(hw, IXGBE_SYSTIMH); + +	return (u64)timespec64_to_ns(&ts); +} + +/** + * ixgbe_ptp_read_82599 - read raw cycle counter (to be used by time counter)   * @cc: the cyclecounter structure   *   * this function reads the cyclecounter registers and is called by the   * cyclecounter structure used to construct a ns counter from the   * arbitrary fixed point registers   */ -static cycle_t ixgbe_ptp_read(const struct cyclecounter *cc) +static cycle_t ixgbe_ptp_read_82599(const struct cyclecounter *cc)  {  	struct ixgbe_adapter *adapter = -		container_of(cc, struct ixgbe_adapter, cc); +		container_of(cc, struct ixgbe_adapter, hw_cc);  	struct ixgbe_hw *hw = &adapter->hw;  	u64 stamp = 0; @@ -203,20 +296,79 @@ static cycle_t ixgbe_ptp_read(const struct cyclecounter *cc)  }  /** - * ixgbe_ptp_adjfreq + * ixgbe_ptp_convert_to_hwtstamp - convert register value to hw timestamp + * @adapter: private adapter structure + * @hwtstamp: stack timestamp structure + * @systim: unsigned 64bit system time value + * + * We need to convert the adapter's RX/TXSTMP registers into a hwtstamp value + * which can be used by the stack's ptp functions. + * + * The lock is used to protect consistency of the cyclecounter and the SYSTIME + * registers. However, it does not need to protect against the Rx or Tx + * timestamp registers, as there can't be a new timestamp until the old one is + * unlatched by reading. + * + * In addition to the timestamp in hardware, some controllers need a software + * overflow cyclecounter, and this function takes this into account as well. + **/ +static void ixgbe_ptp_convert_to_hwtstamp(struct ixgbe_adapter *adapter, +					  struct skb_shared_hwtstamps *hwtstamp, +					  u64 timestamp) +{ +	unsigned long flags; +	struct timespec64 systime; +	u64 ns; + +	memset(hwtstamp, 0, sizeof(*hwtstamp)); + +	switch (adapter->hw.mac.type) { +	/* X550 and later hardware supposedly represent time using a seconds +	 * and nanoseconds counter, instead of raw 64bits nanoseconds. We need +	 * to convert the timestamp into cycles before it can be fed to the +	 * cyclecounter. We need an actual cyclecounter because some revisions +	 * of hardware run at a higher frequency and thus the counter does +	 * not represent seconds/nanoseconds. Instead it can be thought of as +	 * cycles and billions of cycles. +	 */ +	case ixgbe_mac_X550: +	case ixgbe_mac_X550EM_x: +		/* Upper 32 bits represent billions of cycles, lower 32 bits +		 * represent cycles. However, we use timespec64_to_ns for the +		 * correct math even though the units haven't been corrected +		 * yet. +		 */ +		systime.tv_sec = timestamp >> 32; +		systime.tv_nsec = timestamp & 0xFFFFFFFF; + +		timestamp = timespec64_to_ns(&systime); +		break; +	default: +		break; +	} + +	spin_lock_irqsave(&adapter->tmreg_lock, flags); +	ns = timecounter_cyc2time(&adapter->hw_tc, timestamp); +	spin_unlock_irqrestore(&adapter->tmreg_lock, flags); + +	hwtstamp->hwtstamp = ns_to_ktime(ns); +} + +/** + * ixgbe_ptp_adjfreq_82599   * @ptp: the ptp clock structure   * @ppb: parts per billion adjustment from base   *   * adjust the frequency of the ptp cycle counter by the   * indicated ppb from the base frequency.   */ -static int ixgbe_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) +static int ixgbe_ptp_adjfreq_82599(struct ptp_clock_info *ptp, s32 ppb)  {  	struct ixgbe_adapter *adapter =  		container_of(ptp, struct ixgbe_adapter, ptp_caps);  	struct ixgbe_hw *hw = &adapter->hw; -	u64 freq; -	u32 diff, incval; +	u64 freq, incval; +	u32 diff;  	int neg_adj = 0;  	if (ppb < 0) { @@ -235,12 +387,16 @@ static int ixgbe_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)  	switch (hw->mac.type) {  	case ixgbe_mac_X540: -		IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, incval); +		if (incval > 0xFFFFFFFFULL) +			e_dev_warn("PTP ppb adjusted SYSTIME rate overflowed!\n"); +		IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, (u32)incval);  		break;  	case ixgbe_mac_82599EB: +		if (incval > 0x00FFFFFFULL) +			e_dev_warn("PTP ppb adjusted SYSTIME rate overflowed!\n");  		IXGBE_WRITE_REG(hw, IXGBE_TIMINCA,  				(1 << IXGBE_INCPER_SHIFT_82599) | -				incval); +				((u32)incval & 0x00FFFFFFUL));  		break;  	default:  		break; @@ -250,6 +406,43 @@ static int ixgbe_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)  }  /** + * ixgbe_ptp_adjfreq_X550 + * @ptp: the ptp clock structure + * @ppb: parts per billion adjustment from base + * + * adjust the frequency of the SYSTIME registers by the indicated ppb from base + * frequency + */ +static int ixgbe_ptp_adjfreq_X550(struct ptp_clock_info *ptp, s32 ppb) +{ +	struct ixgbe_adapter *adapter = +			container_of(ptp, struct ixgbe_adapter, ptp_caps); +	struct ixgbe_hw *hw = &adapter->hw; +	int neg_adj = 0; +	u64 rate = IXGBE_X550_BASE_PERIOD; +	u32 inca; + +	if (ppb < 0) { +		neg_adj = 1; +		ppb = -ppb; +	} +	rate *= ppb; +	rate = div_u64(rate, 1000000000ULL); + +	/* warn if rate is too large */ +	if (rate >= INCVALUE_MASK) +		e_dev_warn("PTP ppb adjusted SYSTIME rate overflowed!\n"); + +	inca = rate & INCVALUE_MASK; +	if (neg_adj) +		inca |= ISGN; + +	IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, inca); + +	return 0; +} + +/**   * ixgbe_ptp_adjtime   * @ptp: the ptp clock structure   * @delta: offset to adjust the cycle counter by @@ -263,10 +456,11 @@ static int ixgbe_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)  	unsigned long flags;  	spin_lock_irqsave(&adapter->tmreg_lock, flags); -	timecounter_adjtime(&adapter->tc, delta); +	timecounter_adjtime(&adapter->hw_tc, delta);  	spin_unlock_irqrestore(&adapter->tmreg_lock, flags); -	ixgbe_ptp_setup_sdp(adapter); +	if (adapter->ptp_setup_sdp) +		adapter->ptp_setup_sdp(adapter);  	return 0;  } @@ -283,11 +477,11 @@ static int ixgbe_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)  {  	struct ixgbe_adapter *adapter =  		container_of(ptp, struct ixgbe_adapter, ptp_caps); -	u64 ns;  	unsigned long flags; +	u64 ns;  	spin_lock_irqsave(&adapter->tmreg_lock, flags); -	ns = timecounter_read(&adapter->tc); +	ns = timecounter_read(&adapter->hw_tc);  	spin_unlock_irqrestore(&adapter->tmreg_lock, flags);  	*ts = ns_to_timespec64(ns); @@ -308,17 +502,16 @@ static int ixgbe_ptp_settime(struct ptp_clock_info *ptp,  {  	struct ixgbe_adapter *adapter =  		container_of(ptp, struct ixgbe_adapter, ptp_caps); -	u64 ns;  	unsigned long flags; - -	ns = timespec64_to_ns(ts); +	u64 ns = timespec64_to_ns(ts);  	/* reset the timecounter */  	spin_lock_irqsave(&adapter->tmreg_lock, flags); -	timecounter_init(&adapter->tc, &adapter->cc, ns); +	timecounter_init(&adapter->hw_tc, &adapter->hw_cc, ns);  	spin_unlock_irqrestore(&adapter->tmreg_lock, flags); -	ixgbe_ptp_setup_sdp(adapter); +	if (adapter->ptp_setup_sdp) +		adapter->ptp_setup_sdp(adapter);  	return 0;  } @@ -343,33 +536,26 @@ static int ixgbe_ptp_feature_enable(struct ptp_clock_info *ptp,  	 * event when the clock SDP triggers. Clear mask when PPS is  	 * disabled  	 */ -	if (rq->type == PTP_CLK_REQ_PPS) { -		switch (adapter->hw.mac.type) { -		case ixgbe_mac_X540: -			if (on) -				adapter->flags2 |= IXGBE_FLAG2_PTP_PPS_ENABLED; -			else -				adapter->flags2 &= ~IXGBE_FLAG2_PTP_PPS_ENABLED; +	if (rq->type != PTP_CLK_REQ_PPS || !adapter->ptp_setup_sdp) +		return -ENOTSUPP; -			ixgbe_ptp_setup_sdp(adapter); -			return 0; -		default: -			break; -		} -	} +	if (on) +		adapter->flags2 |= IXGBE_FLAG2_PTP_PPS_ENABLED; +	else +		adapter->flags2 &= ~IXGBE_FLAG2_PTP_PPS_ENABLED; -	return -ENOTSUPP; +	adapter->ptp_setup_sdp(adapter); +	return 0;  }  /**   * ixgbe_ptp_check_pps_event   * @adapter: the private adapter structure - * @eicr: the interrupt cause register value   *   * This function is called by the interrupt routine when checking for   * interrupts. It will check and handle a pps event.   */ -void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr) +void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter)  {  	struct ixgbe_hw *hw = &adapter->hw;  	struct ptp_clock_event event; @@ -425,7 +611,9 @@ void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter)  {  	struct ixgbe_hw *hw = &adapter->hw;  	u32 tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL); +	struct ixgbe_ring *rx_ring;  	unsigned long rx_event; +	int n;  	/* if we don't have a valid timestamp in the registers, just update the  	 * timeout counter and exit @@ -437,19 +625,43 @@ void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter)  	/* determine the most recent watchdog or rx_timestamp event */  	rx_event = adapter->last_rx_ptp_check; -	if (time_after(adapter->last_rx_timestamp, rx_event)) -		rx_event = adapter->last_rx_timestamp; +	for (n = 0; n < adapter->num_rx_queues; n++) { +		rx_ring = adapter->rx_ring[n]; +		if (time_after(rx_ring->last_rx_timestamp, rx_event)) +			rx_event = rx_ring->last_rx_timestamp; +	}  	/* only need to read the high RXSTMP register to clear the lock */ -	if (time_is_before_jiffies(rx_event + 5*HZ)) { +	if (time_is_before_jiffies(rx_event + 5 * HZ)) {  		IXGBE_READ_REG(hw, IXGBE_RXSTMPH);  		adapter->last_rx_ptp_check = jiffies; +		adapter->rx_hwtstamp_cleared++;  		e_warn(drv, "clearing RX Timestamp hang\n");  	}  }  /** + * ixgbe_ptp_clear_tx_timestamp - utility function to clear Tx timestamp state + * @adapter: the private adapter structure + * + * This function should be called whenever the state related to a Tx timestamp + * needs to be cleared. This helps ensure that all related bits are reset for + * the next Tx timestamp event. + */ +static void ixgbe_ptp_clear_tx_timestamp(struct ixgbe_adapter *adapter) +{ +	struct ixgbe_hw *hw = &adapter->hw; + +	IXGBE_READ_REG(hw, IXGBE_TXSTMPH); +	if (adapter->ptp_tx_skb) { +		dev_kfree_skb_any(adapter->ptp_tx_skb); +		adapter->ptp_tx_skb = NULL; +	} +	clear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, &adapter->state); +} + +/**   * ixgbe_ptp_tx_hwtstamp - utility function which checks for TX time stamp   * @adapter: the private adapter struct   * @@ -461,23 +673,15 @@ static void ixgbe_ptp_tx_hwtstamp(struct ixgbe_adapter *adapter)  {  	struct ixgbe_hw *hw = &adapter->hw;  	struct skb_shared_hwtstamps shhwtstamps; -	u64 regval = 0, ns; -	unsigned long flags; +	u64 regval = 0;  	regval |= (u64)IXGBE_READ_REG(hw, IXGBE_TXSTMPL);  	regval |= (u64)IXGBE_READ_REG(hw, IXGBE_TXSTMPH) << 32; -	spin_lock_irqsave(&adapter->tmreg_lock, flags); -	ns = timecounter_cyc2time(&adapter->tc, regval); -	spin_unlock_irqrestore(&adapter->tmreg_lock, flags); - -	memset(&shhwtstamps, 0, sizeof(shhwtstamps)); -	shhwtstamps.hwtstamp = ns_to_ktime(ns); +	ixgbe_ptp_convert_to_hwtstamp(adapter, &shhwtstamps, regval);  	skb_tstamp_tx(adapter->ptp_tx_skb, &shhwtstamps); -	dev_kfree_skb_any(adapter->ptp_tx_skb); -	adapter->ptp_tx_skb = NULL; -	clear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, &adapter->state); +	ixgbe_ptp_clear_tx_timestamp(adapter);  }  /** @@ -497,38 +701,85 @@ static void ixgbe_ptp_tx_hwtstamp_work(struct work_struct *work)  					      IXGBE_PTP_TX_TIMEOUT);  	u32 tsynctxctl; -	if (timeout) { -		dev_kfree_skb_any(adapter->ptp_tx_skb); -		adapter->ptp_tx_skb = NULL; -		clear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, &adapter->state); -		e_warn(drv, "clearing Tx Timestamp hang\n"); +	/* we have to have a valid skb to poll for a timestamp */ +	if (!adapter->ptp_tx_skb) { +		ixgbe_ptp_clear_tx_timestamp(adapter);  		return;  	} +	/* stop polling once we have a valid timestamp */  	tsynctxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCTXCTL); -	if (tsynctxctl & IXGBE_TSYNCTXCTL_VALID) +	if (tsynctxctl & IXGBE_TSYNCTXCTL_VALID) {  		ixgbe_ptp_tx_hwtstamp(adapter); -	else +		return; +	} + +	if (timeout) { +		ixgbe_ptp_clear_tx_timestamp(adapter); +		adapter->tx_hwtstamp_timeouts++; +		e_warn(drv, "clearing Tx Timestamp hang\n"); +	} else {  		/* reschedule to keep checking if it's not available yet */  		schedule_work(&adapter->ptp_tx_work); +	}  }  /** - * ixgbe_ptp_rx_hwtstamp - utility function which checks for RX time stamp - * @adapter: pointer to adapter struct + * ixgbe_ptp_rx_pktstamp - utility function to get RX time stamp from buffer + * @q_vector: structure containing interrupt and ring information + * @skb: the packet + * + * This function will be called by the Rx routine of the timestamp for this + * packet is stored in the buffer. The value is stored in little endian format + * starting at the end of the packet data. + */ +void ixgbe_ptp_rx_pktstamp(struct ixgbe_q_vector *q_vector, +			   struct sk_buff *skb) +{ +	__le64 regval; + +	/* copy the bits out of the skb, and then trim the skb length */ +	skb_copy_bits(skb, skb->len - IXGBE_TS_HDR_LEN, ®val, +		      IXGBE_TS_HDR_LEN); +	__pskb_trim(skb, skb->len - IXGBE_TS_HDR_LEN); + +	/* The timestamp is recorded in little endian format, and is stored at +	 * the end of the packet. +	 * +	 * DWORD: N              N + 1      N + 2 +	 * Field: End of Packet  SYSTIMH    SYSTIML +	 */ +	ixgbe_ptp_convert_to_hwtstamp(q_vector->adapter, skb_hwtstamps(skb), +				      le64_to_cpu(regval)); +} + +/** + * ixgbe_ptp_rx_rgtstamp - utility function which checks for RX time stamp + * @q_vector: structure containing interrupt and ring information   * @skb: particular skb to send timestamp with   *   * if the timestamp is valid, we convert it into the timecounter ns   * value, then store that result into the shhwtstamps structure which   * is passed up the network stack   */ -void ixgbe_ptp_rx_hwtstamp(struct ixgbe_adapter *adapter, struct sk_buff *skb) +void ixgbe_ptp_rx_rgtstamp(struct ixgbe_q_vector *q_vector, +			   struct sk_buff *skb)  { -	struct ixgbe_hw *hw = &adapter->hw; -	struct skb_shared_hwtstamps *shhwtstamps; -	u64 regval = 0, ns; +	struct ixgbe_adapter *adapter; +	struct ixgbe_hw *hw; +	u64 regval = 0;  	u32 tsyncrxctl; -	unsigned long flags; + +	/* we cannot process timestamps on a ring without a q_vector */ +	if (!q_vector || !q_vector->adapter) +		return; + +	adapter = q_vector->adapter; +	hw = &adapter->hw; + +	/* Read the tsyncrxctl register afterwards in order to prevent taking an +	 * I/O hit on every packet. +	 */  	tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL);  	if (!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID)) @@ -537,17 +788,7 @@ void ixgbe_ptp_rx_hwtstamp(struct ixgbe_adapter *adapter, struct sk_buff *skb)  	regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPL);  	regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPH) << 32; -	spin_lock_irqsave(&adapter->tmreg_lock, flags); -	ns = timecounter_cyc2time(&adapter->tc, regval); -	spin_unlock_irqrestore(&adapter->tmreg_lock, flags); - -	shhwtstamps = skb_hwtstamps(skb); -	shhwtstamps->hwtstamp = ns_to_ktime(ns); - -	/* Update the last_rx_timestamp timer in order to enable watchdog check -	 * for error case of latched timestamp on a dropped packet. -	 */ -	adapter->last_rx_timestamp = jiffies; +	ixgbe_ptp_convert_to_hwtstamp(adapter, skb_hwtstamps(skb), regval);  }  int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr) @@ -610,14 +851,20 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter,  	case HWTSTAMP_FILTER_NONE:  		tsync_rx_ctl = 0;  		tsync_rx_mtrl = 0; +		adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED | +				    IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);  		break;  	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:  		tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1;  		tsync_rx_mtrl |= IXGBE_RXMTRL_V1_SYNC_MSG; +		adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED | +				    IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);  		break;  	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:  		tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1;  		tsync_rx_mtrl |= IXGBE_RXMTRL_V1_DELAY_REQ_MSG; +		adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED | +				    IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);  		break;  	case HWTSTAMP_FILTER_PTP_V2_EVENT:  	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: @@ -631,9 +878,21 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter,  		tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_EVENT_V2;  		is_l2 = true;  		config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; +		adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED | +				    IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);  		break;  	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:  	case HWTSTAMP_FILTER_ALL: +		/* The X550 controller is capable of timestamping all packets, +		 * which allows it to accept any filter. +		 */ +		if (hw->mac.type >= ixgbe_mac_X550) { +			tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_ALL; +			config->rx_filter = HWTSTAMP_FILTER_ALL; +			adapter->flags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; +			break; +		} +		/* fall through */  	default:  		/*  		 * register RXMTRL must be set in order to do V1 packets, @@ -641,16 +900,46 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter,  		 * Delay_Req messages and hardware does not support  		 * timestamping all packets => return error  		 */ +		adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED | +				    IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);  		config->rx_filter = HWTSTAMP_FILTER_NONE;  		return -ERANGE;  	}  	if (hw->mac.type == ixgbe_mac_82598EB) { +		adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED | +				    IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER);  		if (tsync_rx_ctl | tsync_tx_ctl)  			return -ERANGE;  		return 0;  	} +	/* Per-packet timestamping only works if the filter is set to all +	 * packets. Since this is desired, always timestamp all packets as long +	 * as any Rx filter was configured. +	 */ +	switch (hw->mac.type) { +	case ixgbe_mac_X550: +	case ixgbe_mac_X550EM_x: +		/* enable timestamping all packets only if at least some +		 * packets were requested. Otherwise, play nice and disable +		 * timestamping +		 */ +		if (config->rx_filter == HWTSTAMP_FILTER_NONE) +			break; + +		tsync_rx_ctl = IXGBE_TSYNCRXCTL_ENABLED | +			       IXGBE_TSYNCRXCTL_TYPE_ALL | +			       IXGBE_TSYNCRXCTL_TSIP_UT_EN; +		config->rx_filter = HWTSTAMP_FILTER_ALL; +		adapter->flags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; +		adapter->flags &= ~IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER; +		is_l2 = true; +		break; +	default: +		break; +	} +  	/* define ethertype filter for timestamping L2 packets */  	if (is_l2)  		IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_1588), @@ -678,8 +967,8 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter,  	IXGBE_WRITE_FLUSH(hw);  	/* clear TX/RX time stamp registers, just to be sure */ -	regval = IXGBE_READ_REG(hw, IXGBE_TXSTMPH); -	regval = IXGBE_READ_REG(hw, IXGBE_RXSTMPH); +	ixgbe_ptp_clear_tx_timestamp(adapter); +	IXGBE_READ_REG(hw, IXGBE_RXSTMPH);  	return 0;  } @@ -712,23 +1001,9 @@ int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr)  		-EFAULT : 0;  } -/** - * ixgbe_ptp_start_cyclecounter - create the cycle counter from hw - * @adapter: pointer to the adapter structure - * - * This function should be called to set the proper values for the TIMINCA - * register and tell the cyclecounter structure what the tick rate of SYSTIME - * is. It does not directly modify SYSTIME registers or the timecounter - * structure. It should be called whenever a new TIMINCA value is necessary, - * such as during initialization or when the link speed changes. - */ -void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) +static void ixgbe_ptp_link_speed_adjust(struct ixgbe_adapter *adapter, +					u32 *shift, u32 *incval)  { -	struct ixgbe_hw *hw = &adapter->hw; -	u32 incval = 0; -	u32 shift = 0; -	unsigned long flags; -  	/**  	 * Scale the NIC cycle counter by a large factor so that  	 * relatively small corrections to the frequency can be added @@ -745,36 +1020,98 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter)  	 */  	switch (adapter->link_speed) {  	case IXGBE_LINK_SPEED_100_FULL: -		incval = IXGBE_INCVAL_100; -		shift = IXGBE_INCVAL_SHIFT_100; +		*shift = IXGBE_INCVAL_SHIFT_100; +		*incval = IXGBE_INCVAL_100;  		break;  	case IXGBE_LINK_SPEED_1GB_FULL: -		incval = IXGBE_INCVAL_1GB; -		shift = IXGBE_INCVAL_SHIFT_1GB; +		*shift = IXGBE_INCVAL_SHIFT_1GB; +		*incval = IXGBE_INCVAL_1GB;  		break;  	case IXGBE_LINK_SPEED_10GB_FULL:  	default: -		incval = IXGBE_INCVAL_10GB; -		shift = IXGBE_INCVAL_SHIFT_10GB; +		*shift = IXGBE_INCVAL_SHIFT_10GB; +		*incval = IXGBE_INCVAL_10GB;  		break;  	} +} -	/** -	 * Modify the calculated values to fit within the correct -	 * number of bits specified by the hardware. The 82599 doesn't -	 * have the same space as the X540, so bitshift the calculated -	 * values to fit. +/** + * ixgbe_ptp_start_cyclecounter - create the cycle counter from hw + * @adapter: pointer to the adapter structure + * + * This function should be called to set the proper values for the TIMINCA + * register and tell the cyclecounter structure what the tick rate of SYSTIME + * is. It does not directly modify SYSTIME registers or the timecounter + * structure. It should be called whenever a new TIMINCA value is necessary, + * such as during initialization or when the link speed changes. + */ +void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) +{ +	struct ixgbe_hw *hw = &adapter->hw; +	struct cyclecounter cc; +	unsigned long flags; +	u32 incval = 0; +	u32 tsauxc = 0; +	u32 fuse0 = 0; + +	/* For some of the boards below this mask is technically incorrect. +	 * The timestamp mask overflows at approximately 61bits. However the +	 * particular hardware does not overflow on an even bitmask value. +	 * Instead, it overflows due to conversion of upper 32bits billions of +	 * cycles. Timecounters are not really intended for this purpose so +	 * they do not properly function if the overflow point isn't 2^N-1. +	 * However, the actual SYSTIME values in question take ~138 years to +	 * overflow. In practice this means they won't actually overflow. A +	 * proper fix to this problem would require modification of the +	 * timecounter delta calculations.  	 */ +	cc.mask = CLOCKSOURCE_MASK(64); +	cc.mult = 1; +	cc.shift = 0; +  	switch (hw->mac.type) { +	case ixgbe_mac_X550EM_x: +		/* SYSTIME assumes X550EM_x board frequency is 300Mhz, and is +		 * designed to represent seconds and nanoseconds when this is +		 * the case. However, some revisions of hardware have a 400Mhz +		 * clock and we have to compensate for this frequency +		 * variation using corrected mult and shift values. +		 */ +		fuse0 = IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0)); +		if (!(fuse0 & IXGBE_FUSES0_300MHZ)) { +			cc.mult = 3; +			cc.shift = 2; +		} +		/* fallthrough */ +	case ixgbe_mac_X550: +		cc.read = ixgbe_ptp_read_X550; + +		/* enable SYSTIME counter */ +		IXGBE_WRITE_REG(hw, IXGBE_SYSTIMR, 0); +		IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0); +		IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0); +		tsauxc = IXGBE_READ_REG(hw, IXGBE_TSAUXC); +		IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, +				tsauxc & ~IXGBE_TSAUXC_DISABLE_SYSTIME); +		IXGBE_WRITE_REG(hw, IXGBE_TSIM, IXGBE_TSIM_TXTS); +		IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_TIMESYNC); + +		IXGBE_WRITE_FLUSH(hw); +		break;  	case ixgbe_mac_X540: +		cc.read = ixgbe_ptp_read_82599; + +		ixgbe_ptp_link_speed_adjust(adapter, &cc.shift, &incval);  		IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, incval);  		break;  	case ixgbe_mac_82599EB: +		cc.read = ixgbe_ptp_read_82599; + +		ixgbe_ptp_link_speed_adjust(adapter, &cc.shift, &incval);  		incval >>= IXGBE_INCVAL_SHIFT_82599; -		shift -= IXGBE_INCVAL_SHIFT_82599; +		cc.shift -= IXGBE_INCVAL_SHIFT_82599;  		IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, -				(1 << IXGBE_INCPER_SHIFT_82599) | -				incval); +				(1 << IXGBE_INCPER_SHIFT_82599) | incval);  		break;  	default:  		/* other devices aren't supported */ @@ -787,13 +1124,7 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter)  	/* need lock to prevent incorrect read while modifying cyclecounter */  	spin_lock_irqsave(&adapter->tmreg_lock, flags); - -	memset(&adapter->cc, 0, sizeof(adapter->cc)); -	adapter->cc.read = ixgbe_ptp_read; -	adapter->cc.mask = CYCLECOUNTER_MASK(64); -	adapter->cc.shift = shift; -	adapter->cc.mult = 1; - +	memcpy(&adapter->hw_cc, &cc, sizeof(adapter->hw_cc));  	spin_unlock_irqrestore(&adapter->tmreg_lock, flags);  } @@ -814,29 +1145,27 @@ void ixgbe_ptp_reset(struct ixgbe_adapter *adapter)  	struct ixgbe_hw *hw = &adapter->hw;  	unsigned long flags; -	/* set SYSTIME registers to 0 just in case */ -	IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0x00000000); -	IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0x00000000); -	IXGBE_WRITE_FLUSH(hw); -  	/* reset the hardware timestamping mode */  	ixgbe_ptp_set_timestamp_mode(adapter, &adapter->tstamp_config); +	/* 82598 does not support PTP */ +	if (hw->mac.type == ixgbe_mac_82598EB) +		return; +  	ixgbe_ptp_start_cyclecounter(adapter);  	spin_lock_irqsave(&adapter->tmreg_lock, flags); - -	/* reset the ns time counter */ -	timecounter_init(&adapter->tc, &adapter->cc, +	timecounter_init(&adapter->hw_tc, &adapter->hw_cc,  			 ktime_to_ns(ktime_get_real())); -  	spin_unlock_irqrestore(&adapter->tmreg_lock, flags); -	/* -	 * Now that the shift has been calculated and the systime +	adapter->last_overflow_check = jiffies; + +	/* Now that the shift has been calculated and the systime  	 * registers reset, (re-)enable the Clock out feature  	 */ -	ixgbe_ptp_setup_sdp(adapter); +	if (adapter->ptp_setup_sdp) +		adapter->ptp_setup_sdp(adapter);  }  /** @@ -845,11 +1174,11 @@ void ixgbe_ptp_reset(struct ixgbe_adapter *adapter)   *   * This function performs setup of the user entry point function table and   * initializes the PTP clock device, which is used to access the clock-like - * features of the PTP core. It will be called by ixgbe_ptp_init, only if - * there isn't already a clock device (such as after a suspend/resume cycle, - * where the clock device wasn't destroyed). + * features of the PTP core. It will be called by ixgbe_ptp_init, and may + * reuse a previously initialized clock (such as during a suspend/resume + * cycle).   */ -static int ixgbe_ptp_create_clock(struct ixgbe_adapter *adapter) +static long ixgbe_ptp_create_clock(struct ixgbe_adapter *adapter)  {  	struct net_device *netdev = adapter->netdev;  	long err; @@ -869,11 +1198,12 @@ static int ixgbe_ptp_create_clock(struct ixgbe_adapter *adapter)  		adapter->ptp_caps.n_ext_ts = 0;  		adapter->ptp_caps.n_per_out = 0;  		adapter->ptp_caps.pps = 1; -		adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq; +		adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq_82599;  		adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime;  		adapter->ptp_caps.gettime64 = ixgbe_ptp_gettime;  		adapter->ptp_caps.settime64 = ixgbe_ptp_settime;  		adapter->ptp_caps.enable = ixgbe_ptp_feature_enable; +		adapter->ptp_setup_sdp = ixgbe_ptp_setup_sdp_x540;  		break;  	case ixgbe_mac_82599EB:  		snprintf(adapter->ptp_caps.name, @@ -885,14 +1215,31 @@ static int ixgbe_ptp_create_clock(struct ixgbe_adapter *adapter)  		adapter->ptp_caps.n_ext_ts = 0;  		adapter->ptp_caps.n_per_out = 0;  		adapter->ptp_caps.pps = 0; -		adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq; +		adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq_82599; +		adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime; +		adapter->ptp_caps.gettime64 = ixgbe_ptp_gettime; +		adapter->ptp_caps.settime64 = ixgbe_ptp_settime; +		adapter->ptp_caps.enable = ixgbe_ptp_feature_enable; +		break; +	case ixgbe_mac_X550: +	case ixgbe_mac_X550EM_x: +		snprintf(adapter->ptp_caps.name, 16, "%s", netdev->name); +		adapter->ptp_caps.owner = THIS_MODULE; +		adapter->ptp_caps.max_adj = 30000000; +		adapter->ptp_caps.n_alarm = 0; +		adapter->ptp_caps.n_ext_ts = 0; +		adapter->ptp_caps.n_per_out = 0; +		adapter->ptp_caps.pps = 0; +		adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq_X550;  		adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime;  		adapter->ptp_caps.gettime64 = ixgbe_ptp_gettime;  		adapter->ptp_caps.settime64 = ixgbe_ptp_settime;  		adapter->ptp_caps.enable = ixgbe_ptp_feature_enable; +		adapter->ptp_setup_sdp = NULL;  		break;  	default:  		adapter->ptp_clock = NULL; +		adapter->ptp_setup_sdp = NULL;  		return -EOPNOTSUPP;  	} @@ -961,18 +1308,13 @@ void ixgbe_ptp_suspend(struct ixgbe_adapter *adapter)  	if (!test_and_clear_bit(__IXGBE_PTP_RUNNING, &adapter->state))  		return; -	/* since this might be called in suspend, we don't clear the state, -	 * but simply reset the auxiliary PPS signal control register -	 */ -	IXGBE_WRITE_REG(&adapter->hw, IXGBE_TSAUXC, 0x0); +	adapter->flags2 &= ~IXGBE_FLAG2_PTP_PPS_ENABLED; +	if (adapter->ptp_setup_sdp) +		adapter->ptp_setup_sdp(adapter);  	/* ensure that we cancel any pending PTP Tx work item in progress */  	cancel_work_sync(&adapter->ptp_tx_work); -	if (adapter->ptp_tx_skb) { -		dev_kfree_skb_any(adapter->ptp_tx_skb); -		adapter->ptp_tx_skb = NULL; -		clear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, &adapter->state); -	} +	ixgbe_ptp_clear_tx_timestamp(adapter);  }  /**  | 
