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 84e7304532e..fd14116ad7f 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; |
