diff options
author | Michał Mirosław <mirq-linux@rere.qmqm.pl> | 2011-05-25 20:42:57 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-05-26 14:13:59 -0400 |
commit | fd0daf9d58f6b3342d07c5f6bbfb304dbe5db4ec (patch) | |
tree | 6456e68bd8f9e85076f4c908933abd470dd1f014 /net/core | |
parent | 94265cf5f731c7df29fdfde262ca3e6d51e6828c (diff) |
net: fix ETHTOOL_SFEATURES compatibility with old ethtool_ops.set_flags
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 <mirq-linux@rere.qmqm.pl>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/ethtool.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 84e7304532e6..fd14116ad7f0 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
@@ -233,6 +233,29 @@ static int ethtool_set_feature_compat(struct net_device *dev, | |||
233 | return 1; | 233 | return 1; |
234 | } | 234 | } |
235 | 235 | ||
236 | static int ethtool_set_flags_compat(struct net_device *dev, | ||
237 | int (*legacy_set)(struct net_device *, u32), | ||
238 | struct ethtool_set_features_block *features, u32 mask) | ||
239 | { | ||
240 | u32 value; | ||
241 | |||
242 | if (!legacy_set) | ||
243 | return 0; | ||
244 | |||
245 | if (!(features[0].valid & mask)) | ||
246 | return 0; | ||
247 | |||
248 | value = dev->features & ~features[0].valid; | ||
249 | value |= features[0].requested; | ||
250 | |||
251 | features[0].valid &= ~mask; | ||
252 | |||
253 | if (legacy_set(dev, value & mask) < 0) | ||
254 | netdev_info(dev, "Legacy flags change failed\n"); | ||
255 | |||
256 | return 1; | ||
257 | } | ||
258 | |||
236 | static int ethtool_set_features_compat(struct net_device *dev, | 259 | static int ethtool_set_features_compat(struct net_device *dev, |
237 | struct ethtool_set_features_block *features) | 260 | struct ethtool_set_features_block *features) |
238 | { | 261 | { |
@@ -249,7 +272,7 @@ static int ethtool_set_features_compat(struct net_device *dev, | |||
249 | features, NETIF_F_ALL_TSO); | 272 | features, NETIF_F_ALL_TSO); |
250 | compat |= ethtool_set_feature_compat(dev, dev->ethtool_ops->set_rx_csum, | 273 | compat |= ethtool_set_feature_compat(dev, dev->ethtool_ops->set_rx_csum, |
251 | features, NETIF_F_RXCSUM); | 274 | features, NETIF_F_RXCSUM); |
252 | compat |= ethtool_set_feature_compat(dev, dev->ethtool_ops->set_flags, | 275 | compat |= ethtool_set_flags_compat(dev, dev->ethtool_ops->set_flags, |
253 | features, flags_dup_features); | 276 | features, flags_dup_features); |
254 | 277 | ||
255 | return compat; | 278 | return compat; |