From: Michał Mirosław Date: Thu, 26 May 2011 00:42:57 +0000 (+0000) Subject: net: fix ETHTOOL_SFEATURES compatibility with old ethtool_ops.set_flags X-Git-Tag: v2.6.39.3~108 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=70e0b9c5761165977eb698a36a781830e1e7832e;p=thirdparty%2Fkernel%2Fstable.git net: fix ETHTOOL_SFEATURES compatibility with old ethtool_ops.set_flags [ Upstream commit fd0daf9d58f6b3342d07c5f6bbfb304dbe5db4ec ] Current code squashes flags to bool - this makes set_flags fail whenever some ETH_FLAG_* equivalent features are set. Fix this. Signed-off-by: Micha©© Miros©©aw Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- diff --git a/net/core/ethtool.c b/net/core/ethtool.c index f337525331196..76ed64563a2eb 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -231,6 +231,29 @@ static int ethtool_set_feature_compat(struct net_device *dev, return 1; } +static int ethtool_set_flags_compat(struct net_device *dev, + int (*legacy_set)(struct net_device *, u32), + struct ethtool_set_features_block *features, u32 mask) +{ + u32 value; + + if (!legacy_set) + return 0; + + if (!(features[0].valid & mask)) + return 0; + + value = dev->features & ~features[0].valid; + value |= features[0].requested; + + features[0].valid &= ~mask; + + if (legacy_set(dev, value & mask) < 0) + netdev_info(dev, "Legacy flags change failed\n"); + + return 1; +} + static int ethtool_set_features_compat(struct net_device *dev, struct ethtool_set_features_block *features) { @@ -247,7 +270,7 @@ static int ethtool_set_features_compat(struct net_device *dev, features, NETIF_F_ALL_TSO); compat |= ethtool_set_feature_compat(dev, dev->ethtool_ops->set_rx_csum, features, NETIF_F_RXCSUM); - compat |= ethtool_set_feature_compat(dev, dev->ethtool_ops->set_flags, + compat |= ethtool_set_flags_compat(dev, dev->ethtool_ops->set_flags, features, flags_dup_features); return compat;