[<prev] [next>] [day] [month] [year] [list]
Message-Id: <1223495327-21661-1-git-send-email-markmc@redhat.com>
Date: Wed, 8 Oct 2008 20:48:47 +0100
From: Mark McLoughlin <markmc@...hat.com>
To: Max Krasnyansky <maxk@...lcomm.com>
Cc: netdev@...r.kernel.org, Rusty Russell <rusty@...tcorp.com.au>,
Mark McLoughlin <markmc@...hat.com>
Subject: [PATCH] tun: Add offload related ethtool ops
The TUNSETOFFLOAD ioctl() allows setting various offload related
device fields, however it is not currently possible to then tweak
those settings using ethtool.
Implement the ethtool ops, but don't allow enabling a feature that
hasn't already been enabled by TUNSETOFFLOAD.
Signed-off-by: Mark McLoughlin <markmc@...hat.com>
---
drivers/net/tun.c | 40 +++++++++++++++++++++++++++++++++++++++-
1 files changed, 39 insertions(+), 1 deletions(-)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 6daea0c..211e953 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -90,6 +90,7 @@ struct tap_filter {
struct tun_struct {
struct list_head list;
unsigned int flags;
+ unsigned long offload;
int attached;
uid_t owner;
gid_t group;
@@ -753,6 +754,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
tun = netdev_priv(dev);
tun->dev = dev;
tun->flags = flags;
+ tun->offload = 0;
tun->txflt.count = 0;
tun_net_init(dev);
@@ -840,6 +842,7 @@ static int tun_get_iff(struct net *net, struct file *file, struct ifreq *ifr)
* privs required. */
static int set_offload(struct net_device *dev, unsigned long arg)
{
+ struct tun_struct *tun = netdev_priv(dev);
unsigned int old_features, features;
old_features = dev->features;
@@ -873,6 +876,8 @@ static int set_offload(struct net_device *dev, unsigned long arg)
if (old_features != dev->features)
netdev_features_change(dev);
+ tun->offload = dev->features & (NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_TSO);
+
return 0;
}
@@ -1187,6 +1192,36 @@ static int tun_set_rx_csum(struct net_device *dev, u32 data)
return 0;
}
+static int tun_set_tx_csum(struct net_device *dev, u32 data)
+{
+ struct tun_struct *tun = netdev_priv(dev);
+
+ if (data && !(tun->offload & NETIF_F_HW_CSUM))
+ return -EOPNOTSUPP;
+
+ return ethtool_op_set_tx_hw_csum(dev, data);
+}
+
+static int tun_set_sg(struct net_device *dev, u32 data)
+{
+ struct tun_struct *tun = netdev_priv(dev);
+
+ if (data && !(tun->offload & NETIF_F_SG))
+ return -EOPNOTSUPP;
+
+ return ethtool_op_set_sg(dev, data);
+}
+
+static int tun_set_tso(struct net_device *dev, u32 data)
+{
+ struct tun_struct *tun = netdev_priv(dev);
+
+ if (data && !(tun->offload & NETIF_F_TSO))
+ return -EOPNOTSUPP;
+
+ return ethtool_op_set_tso(dev, data);
+}
+
static const struct ethtool_ops tun_ethtool_ops = {
.get_settings = tun_get_settings,
.get_drvinfo = tun_get_drvinfo,
@@ -1194,7 +1229,10 @@ static const struct ethtool_ops tun_ethtool_ops = {
.set_msglevel = tun_set_msglevel,
.get_link = tun_get_link,
.get_rx_csum = tun_get_rx_csum,
- .set_rx_csum = tun_set_rx_csum
+ .set_rx_csum = tun_set_rx_csum,
+ .set_tx_csum = tun_set_tx_csum,
+ .set_sg = tun_set_sg,
+ .set_tso = tun_set_tso,
};
static int tun_init_net(struct net *net)
--
1.5.4.3
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists