vlan: allow TSO setting on vlan interfaces
authorEric Dumazet <eric.dumazet@gmail.com>
Fri, 9 Jul 2010 06:12:21 +0000 (23:12 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 9 Jul 2010 06:12:21 +0000 (23:12 -0700)
When we need to shape traffic using low speeds, we need to
disable tso on network interface :

ethtool -K eth0.2240 tso off

It seems vlan interfaces miss the set_tso() ethtool method.

Before enabling TSO, we must check real device supports
TSO for VLAN-tagged packets and enables TSO.

Note that a TSO change on real device propagates TSO setting
on all vlans, even if admin selected a different TSO setting.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/8021q/vlan_dev.c

index 7865a4ce5250def20cbf3d850b44c1cd11ce71d1..a1b8171cfa7bd8cf9b8c741cbd96760d53bf2d9a 100644 (file)
@@ -836,12 +836,32 @@ static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, st
        return stats;
 }
 
+static int vlan_ethtool_set_tso(struct net_device *dev, u32 data)
+{
+       if (data) {
+               struct net_device *real_dev = vlan_dev_info(dev)->real_dev;
+
+               /* Underlying device must support TSO for VLAN-tagged packets
+                * and must have TSO enabled now.
+                */
+               if (!(real_dev->vlan_features & NETIF_F_TSO))
+                       return -EOPNOTSUPP;
+               if (!(real_dev->features & NETIF_F_TSO))
+                       return -EINVAL;
+               dev->features |= NETIF_F_TSO;
+       } else {
+               dev->features &= ~NETIF_F_TSO;
+       }
+       return 0;
+}
+
 static const struct ethtool_ops vlan_ethtool_ops = {
        .get_settings           = vlan_ethtool_get_settings,
        .get_drvinfo            = vlan_ethtool_get_drvinfo,
        .get_link               = ethtool_op_get_link,
        .get_rx_csum            = vlan_ethtool_get_rx_csum,
        .get_flags              = vlan_ethtool_get_flags,
+       .set_tso                = vlan_ethtool_set_tso,
 };
 
 static const struct net_device_ops vlan_netdev_ops = {