X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fcore%2Fethtool.c;h=f05fde97c43d6a8741fa8992972f022998be5161;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=866f29277ed1318c6961524441fba79c44921edc;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 866f29277..f05fde97c 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -452,9 +452,23 @@ static int ethtool_get_tx_csum(struct net_device *dev, char __user *useraddr) return 0; } +static int __ethtool_set_sg(struct net_device *dev, u32 data) +{ + int err; + + if (!data && dev->ethtool_ops->set_tso) { + err = dev->ethtool_ops->set_tso(dev, 0); + if (err) + return err; + } + + return dev->ethtool_ops->set_sg(dev, data); +} + static int ethtool_set_tx_csum(struct net_device *dev, char __user *useraddr) { struct ethtool_value edata; + int err; if (!dev->ethtool_ops->set_tx_csum) return -EOPNOTSUPP; @@ -462,6 +476,12 @@ static int ethtool_set_tx_csum(struct net_device *dev, char __user *useraddr) if (copy_from_user(&edata, useraddr, sizeof(edata))) return -EFAULT; + if (!edata.data && dev->ethtool_ops->set_sg) { + err = __ethtool_set_sg(dev, 0); + if (err) + return err; + } + return dev->ethtool_ops->set_tx_csum(dev, edata.data); } @@ -489,7 +509,13 @@ static int ethtool_set_sg(struct net_device *dev, char __user *useraddr) if (copy_from_user(&edata, useraddr, sizeof(edata))) return -EFAULT; - return dev->ethtool_ops->set_sg(dev, edata.data); + if (edata.data && + !(dev->features & (NETIF_F_IP_CSUM | + NETIF_F_NO_CSUM | + NETIF_F_HW_CSUM))) + return -EINVAL; + + return __ethtool_set_sg(dev, edata.data); } static int ethtool_get_tso(struct net_device *dev, char __user *useraddr) @@ -516,6 +542,9 @@ static int ethtool_set_tso(struct net_device *dev, char __user *useraddr) if (copy_from_user(&edata, useraddr, sizeof(edata))) return -EFAULT; + if (edata.data && !(dev->features & NETIF_F_SG)) + return -EINVAL; + return dev->ethtool_ops->set_tso(dev, edata.data); }