Commit 03829520 authored by Alessandro Rubini's avatar Alessandro Rubini

test: patches/v2.6.35: fake stamping for RTL8169

Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent df023de2
From d3b127b9ecd60a6bff64269708b9099fe902c198 Mon Sep 17 00:00:00 2001
From: Alessandro Rubini <rubini@gnudd.com>
Date: Sat, 18 Dec 2010 17:01:30 +0100
Subject: [PATCH] r8169: added timestamp ioctl
This is a tool to fake hw timestamping on the 8169 gigabit ethernet.
The patch makes no actual stamping, which is added later.
Signed-off-by: Alessandro Rubini <rubini@gnudd.com>
---
drivers/net/r8169.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 47 insertions(+), 0 deletions(-)
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index cdc6a5c..4b4cca0 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -24,6 +24,7 @@
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/pm_runtime.h>
+#include <linux/net_tstamp.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -511,6 +512,9 @@ struct rtl8169_private {
struct mii_if_info mii;
struct rtl8169_counters counters;
u32 saved_wolopts;
+ int hwtstamp; /* hack -- ARub */
+#define TSTAMP_TX 1
+#define TSTAMP_RX 2
};
MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
@@ -2880,11 +2884,54 @@ static int rtl_set_mac_address(struct net_device *dev, void *p)
return 0;
}
+/* This copied from gianfar -- ARub */
+static int rtl8169_tstamp_ioctl(struct net_device *netdev,
+ struct ifreq *ifr, int cmd)
+{
+ struct hwtstamp_config config;
+ struct rtl8169_private *priv = netdev_priv(netdev);
+
+ if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
+ return -EFAULT;
+
+ /* reserved for future extensions */
+ if (config.flags)
+ return -EINVAL;
+
+ switch (config.tx_type) {
+ case HWTSTAMP_TX_OFF:
+ priv->hwtstamp &= ~TSTAMP_TX;
+ break;
+ case HWTSTAMP_TX_ON:
+ priv->hwtstamp |= TSTAMP_TX;
+ break;
+ default:
+ return -ERANGE;
+ }
+
+ switch (config.rx_filter) {
+ case HWTSTAMP_FILTER_NONE:
+ priv->hwtstamp &= ~TSTAMP_RX;
+ break;
+ default:
+ priv->hwtstamp |= TSTAMP_RX;
+ break;
+ }
+ printk("%s: stamp is %i\n", __func__, priv->hwtstamp);
+
+ return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
+ -EFAULT : 0;
+}
+
static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
struct rtl8169_private *tp = netdev_priv(dev);
struct mii_ioctl_data *data = if_mii(ifr);
+ if (cmd == SIOCSHWTSTAMP) {
+ return rtl8169_tstamp_ioctl(dev, ifr, cmd);
+ }
+
return netif_running(dev) ? tp->do_ioctl(tp, data, cmd) : -ENODEV;
}
--
1.5.6.5
From f68d43fbd71a12a31da21fe825987f87179c125b Mon Sep 17 00:00:00 2001
From: Alessandro Rubini <rubini@gnudd.com>
Date: Sat, 18 Dec 2010 17:35:08 +0100
Subject: [PATCH] r8169: added tx timestamp (possibly too late)
This adds actual stamping in the tx-done interrupt, for the fake
hw-timestap in the RTL8169 device. The stamp is taken with
getnstimeofday, keeping only the last 4 digits and 2 digits of the
seconds field.
Signed-off-by: Alessandro Rubini <rubini@gnudd.com>
---
drivers/net/r8169.c | 22 ++++++++++++++++++++++
1 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 4b4cca0..2a85588 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -4447,6 +4447,25 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev)
rtl8169_schedule_work(dev, rtl8169_reinit_task);
}
+static inline void __tstamp_tx(struct sk_buff *skb)
+{
+ union skb_shared_tx *shtx;
+ struct timespec ts;
+
+ getnstimeofday(&ts);
+ shtx = skb_tx(skb);
+ if (unlikely(shtx->hardware)) {
+ struct skb_shared_hwtstamps shhwtstamps;
+
+ memset(&shhwtstamps, 0, sizeof(shhwtstamps));
+ ts.tv_sec %=10000; /* sys tstamp different from sw one */
+ shhwtstamps.syststamp = timespec_to_ktime(ts);
+ ts.tv_sec %=100; /* and hw tstamp is still different */
+ shhwtstamps.hwtstamp = timespec_to_ktime(ts);
+ skb_tstamp_tx(skb, &shhwtstamps);
+ }
+}
+
static void rtl8169_tx_interrupt(struct net_device *dev,
struct rtl8169_private *tp,
void __iomem *ioaddr)
@@ -4474,6 +4493,9 @@ static void rtl8169_tx_interrupt(struct net_device *dev,
rtl8169_unmap_tx_skb(tp->pci_dev, tx_skb, tp->TxDescArray + entry);
if (status & LastFrag) {
+ /* We may need to tx-timestamp. FIXME: too late? */
+ if (unlikely(tp->hwtstamp & TSTAMP_TX))
+ __tstamp_tx(tx_skb->skb);
dev_kfree_skb(tx_skb->skb);
tx_skb->skb = NULL;
}
--
1.5.6.5
From e4aa9cf635afdfbe604c5fa61c3801653404713b Mon Sep 17 00:00:00 2001
From: Alessandro Rubini <rubini@gnudd.com>
Date: Sat, 18 Dec 2010 17:45:41 +0100
Subject: [PATCH] r8169: added rx timestamp
Like the previous patch, this adds fake hw-timestamp to the RTL8169 device.
Signed-off-by: Alessandro Rubini <rubini@gnudd.com>
---
drivers/net/r8169.c | 16 ++++++++++++++++
1 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 2a85588..9b37f02 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -4563,6 +4563,20 @@ out:
return done;
}
+static inline void __tstamp_rx(struct sk_buff *skb)
+{
+ struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb);
+ struct timespec ts;
+
+ getnstimeofday(&ts);
+
+ memset(shhwtstamps, 0, sizeof(*shhwtstamps));
+ ts.tv_sec %=10000; /* sys tstamp different from sw one */
+ shhwtstamps->syststamp = timespec_to_ktime(ts);
+ ts.tv_sec %=100; /* and hw tstamp is still different */
+ shhwtstamps->hwtstamp = timespec_to_ktime(ts);
+}
+
/*
* Warning : rtl8169_rx_interrupt() might be called :
* 1) from NAPI (softirq) context
@@ -4639,6 +4653,8 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
skb->protocol = eth_type_trans(skb, dev);
if (rtl8169_rx_vlan_skb(tp, desc, skb, polling) < 0) {
+ if (unlikely(tp->hwtstamp & TSTAMP_RX))
+ __tstamp_rx(skb);
if (likely(polling))
netif_receive_skb(skb);
else
--
1.5.6.5
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