Commit c95b9687 authored by Manfred Rudigier's avatar Manfred Rudigier Committed by Greg Kroah-Hartman

net: dp83640: Fix tx timestamp overflow handling.

[ Upstream commit 81e8f2e9 ]

PHY status frames are not reliable, the PHY may not be able to send them
during heavy receive traffic. This overflow condition is signaled by the
PHY in the next status frame, but the driver did not make use of it.
Instead it always reported wrong tx timestamps to user space after an
overflow happened because it assigned newly received tx timestamps to old
packets in the queue.

This commit fixes this issue by clearing the tx timestamp queue every time
an overflow happens, so that no timestamps are delivered for overflow
packets. This way time stamping will continue correctly after an overflow.
Signed-off-by: default avatarManfred Rudigier <manfred.rudigier@omicron.at>
Acked-by: default avatarRichard Cochran <richardcochran@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 306d3165
...@@ -845,6 +845,11 @@ static void decode_rxts(struct dp83640_private *dp83640, ...@@ -845,6 +845,11 @@ static void decode_rxts(struct dp83640_private *dp83640,
struct skb_shared_hwtstamps *shhwtstamps = NULL; struct skb_shared_hwtstamps *shhwtstamps = NULL;
struct sk_buff *skb; struct sk_buff *skb;
unsigned long flags; unsigned long flags;
u8 overflow;
overflow = (phy_rxts->ns_hi >> 14) & 0x3;
if (overflow)
pr_debug("rx timestamp queue overflow, count %d\n", overflow);
spin_lock_irqsave(&dp83640->rx_lock, flags); spin_lock_irqsave(&dp83640->rx_lock, flags);
...@@ -887,6 +892,7 @@ static void decode_txts(struct dp83640_private *dp83640, ...@@ -887,6 +892,7 @@ static void decode_txts(struct dp83640_private *dp83640,
struct skb_shared_hwtstamps shhwtstamps; struct skb_shared_hwtstamps shhwtstamps;
struct sk_buff *skb; struct sk_buff *skb;
u64 ns; u64 ns;
u8 overflow;
/* We must already have the skb that triggered this. */ /* We must already have the skb that triggered this. */
...@@ -896,6 +902,17 @@ static void decode_txts(struct dp83640_private *dp83640, ...@@ -896,6 +902,17 @@ static void decode_txts(struct dp83640_private *dp83640,
pr_debug("have timestamp but tx_queue empty\n"); pr_debug("have timestamp but tx_queue empty\n");
return; return;
} }
overflow = (phy_txts->ns_hi >> 14) & 0x3;
if (overflow) {
pr_debug("tx timestamp queue overflow, count %d\n", overflow);
while (skb) {
skb_complete_tx_timestamp(skb, NULL);
skb = skb_dequeue(&dp83640->tx_queue);
}
return;
}
ns = phy2txts(phy_txts); ns = phy2txts(phy_txts);
memset(&shhwtstamps, 0, sizeof(shhwtstamps)); memset(&shhwtstamps, 0, sizeof(shhwtstamps));
shhwtstamps.hwtstamp = ns_to_ktime(ns); shhwtstamps.hwtstamp = ns_to_ktime(ns);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment