Commit fd0daf9d58f6b3342d07c5f6bbfb304dbe5db4ec
Committed by
David S. Miller
1 parent
94265cf5f7
Exists in
master
and in
4 other branches
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>
Showing 1 changed file with 24 additions and 1 deletions Side-by-side Diff
net/core/ethtool.c
... | ... | @@ -233,6 +233,29 @@ |
233 | 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 | 259 | static int ethtool_set_features_compat(struct net_device *dev, |
237 | 260 | struct ethtool_set_features_block *features) |
238 | 261 | { |
... | ... | @@ -249,7 +272,7 @@ |
249 | 272 | features, NETIF_F_ALL_TSO); |
250 | 273 | compat |= ethtool_set_feature_compat(dev, dev->ethtool_ops->set_rx_csum, |
251 | 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 | 276 | features, flags_dup_features); |
254 | 277 | |
255 | 278 | return compat; |