summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/intel/igb/igb_ptp.c
diff options
context:
space:
mode:
authorKshitiz Gupta <kshitiz.gupta@ni.com>2016-07-16 10:23:45 +0300
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2016-08-16 20:32:59 +0300
commit0066c8b6f4050d7c57f6379d6fd4535e2f267f17 (patch)
treeabdad4138d3ee1495bbd197a6ae613f3363d5e8f /drivers/net/ethernet/intel/igb/igb_ptp.c
parenta1560dd7a47f983419760aa7f6a481e3b910b54b (diff)
downloadlinux-0066c8b6f4050d7c57f6379d6fd4535e2f267f17.tar.xz
igb: fix adjusting PTP timestamps for Tx/Rx latency
Fix PHY delay compensation math in igb_ptp_tx_hwtstamp() and igb_ptp_rx_rgtstamp. Add PHY delay compensation in igb_ptp_rx_pktstamp(). In the IGB driver, there are two functions that retrieve timestamps received by the PHY - igb_ptp_rx_rgtstamp() and igb_ptp_rx_pktstamp(). The previous commit only changed igb_ptp_rx_rgtstamp(), and the change was incorrect. There are two instances in which PHY delay compensations should be made: - Before the packet transmission over the PHY, the latency between when the packet is timestamped and transmission of the packets, should be an add operation, but it is currently a subtract. - After the packets are received from the PHY, the latency between the receiving and timestamping of the packets should be a subtract operation, but it is currently an add. Signed-off-by: Kshitiz Gupta <kshitiz.gupta@ni.com> Fixes: 3f544d2 (igb: adjust ptp timestamps for tx/rx latency) Tested-by: Aaron Brown <aaron.f.brown@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/igb/igb_ptp.c')
-rw-r--r--drivers/net/ethernet/intel/igb/igb_ptp.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c
index e61b647f5f2a..336c103ae374 100644
--- a/drivers/net/ethernet/intel/igb/igb_ptp.c
+++ b/drivers/net/ethernet/intel/igb/igb_ptp.c
@@ -744,7 +744,8 @@ static void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter)
}
}
- shhwtstamps.hwtstamp = ktime_sub_ns(shhwtstamps.hwtstamp, adjust);
+ shhwtstamps.hwtstamp =
+ ktime_add_ns(shhwtstamps.hwtstamp, adjust);
skb_tstamp_tx(adapter->ptp_tx_skb, &shhwtstamps);
dev_kfree_skb_any(adapter->ptp_tx_skb);
@@ -767,13 +768,32 @@ void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector,
struct sk_buff *skb)
{
__le64 *regval = (__le64 *)va;
+ struct igb_adapter *adapter = q_vector->adapter;
+ int adjust = 0;
/* The timestamp is recorded in little endian format.
* DWORD: 0 1 2 3
* Field: Reserved Reserved SYSTIML SYSTIMH
*/
- igb_ptp_systim_to_hwtstamp(q_vector->adapter, skb_hwtstamps(skb),
+ igb_ptp_systim_to_hwtstamp(adapter, skb_hwtstamps(skb),
le64_to_cpu(regval[1]));
+
+ /* adjust timestamp for the RX latency based on link speed */
+ if (adapter->hw.mac.type == e1000_i210) {
+ switch (adapter->link_speed) {
+ case SPEED_10:
+ adjust = IGB_I210_RX_LATENCY_10;
+ break;
+ case SPEED_100:
+ adjust = IGB_I210_RX_LATENCY_100;
+ break;
+ case SPEED_1000:
+ adjust = IGB_I210_RX_LATENCY_1000;
+ break;
+ }
+ }
+ skb_hwtstamps(skb)->hwtstamp =
+ ktime_sub_ns(skb_hwtstamps(skb)->hwtstamp, adjust);
}
/**
@@ -825,7 +845,7 @@ void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector,
}
}
skb_hwtstamps(skb)->hwtstamp =
- ktime_add_ns(skb_hwtstamps(skb)->hwtstamp, adjust);
+ ktime_sub_ns(skb_hwtstamps(skb)->hwtstamp, adjust);
/* Update the last_rx_timestamp timer in order to enable watchdog check
* for error case of latched timestamp on a dropped packet.