diff options
Diffstat (limited to 'drivers/net/ethernet/intel/igb/igb_ptp.c')
| -rw-r--r-- | drivers/net/ethernet/intel/igb/igb_ptp.c | 31 | 
1 files changed, 24 insertions, 7 deletions
| diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c index 7cc5428c3b3d..86a576201f5f 100644 --- a/drivers/net/ethernet/intel/igb/igb_ptp.c +++ b/drivers/net/ethernet/intel/igb/igb_ptp.c @@ -856,6 +856,9 @@ static void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter)  	dev_kfree_skb_any(skb);  } +#define IGB_RET_PTP_DISABLED 1 +#define IGB_RET_PTP_INVALID 2 +  /**   * igb_ptp_rx_pktstamp - retrieve Rx per packet timestamp   * @q_vector: Pointer to interrupt specific structure @@ -864,19 +867,29 @@ static void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter)   *   * This function is meant to retrieve a timestamp from the first buffer of an   * incoming frame.  The value is stored in little endian format starting on - * byte 8. + * byte 8 + * + * Returns: 0 if success, nonzero if failure   **/ -void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va, -			 struct sk_buff *skb) +int igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va, +			struct sk_buff *skb)  { -	__le64 *regval = (__le64 *)va;  	struct igb_adapter *adapter = q_vector->adapter; +	__le64 *regval = (__le64 *)va;  	int adjust = 0; +	if (!(adapter->ptp_flags & IGB_PTP_ENABLED)) +		return IGB_RET_PTP_DISABLED; +  	/* The timestamp is recorded in little endian format.  	 * DWORD: 0        1        2        3  	 * Field: Reserved Reserved SYSTIML  SYSTIMH  	 */ + +	/* check reserved dwords are zero, be/le doesn't matter for zero */ +	if (regval[0]) +		return IGB_RET_PTP_INVALID; +  	igb_ptp_systim_to_hwtstamp(adapter, skb_hwtstamps(skb),  				   le64_to_cpu(regval[1])); @@ -896,6 +909,8 @@ void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va,  	}  	skb_hwtstamps(skb)->hwtstamp =  		ktime_sub_ns(skb_hwtstamps(skb)->hwtstamp, adjust); + +	return 0;  }  /** @@ -906,13 +921,15 @@ void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va,   * This function is meant to retrieve a timestamp from the internal registers   * of the adapter and store it in the skb.   **/ -void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, -			 struct sk_buff *skb) +void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb)  {  	struct igb_adapter *adapter = q_vector->adapter;  	struct e1000_hw *hw = &adapter->hw; -	u64 regval;  	int adjust = 0; +	u64 regval; + +	if (!(adapter->ptp_flags & IGB_PTP_ENABLED)) +		return;  	/* If this bit is set, then the RX registers contain the time stamp. No  	 * other packet will be time stamped until we read these registers, so |