aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/ethtool.c
diff options
context:
space:
mode:
authorMichał Mirosław <mirq-linux@rere.qmqm.pl>2011-02-15 11:59:18 -0500
committerDavid S. Miller <davem@davemloft.net>2011-02-17 17:16:34 -0500
commitda8ac86c4a56a14bf8deea7d2f92d0a453c67f91 (patch)
tree9ccb11cb01f7917240efe014cae22f5ff3ce9d43 /net/core/ethtool.c
parent86794881c29a7ea6271644b49ad81518cabda96b (diff)
net: use ndo_fix_features for ethtool_ops->set_flags
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/ethtool.c')
-rw-r--r--net/core/ethtool.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 65999974f743..65b3d50a6df2 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -427,6 +427,34 @@ static int ethtool_set_one_feature(struct net_device *dev,
427 } 427 }
428} 428}
429 429
430static int __ethtool_set_flags(struct net_device *dev, u32 data)
431{
432 u32 changed;
433
434 if (data & ~flags_dup_features)
435 return -EINVAL;
436
437 /* legacy set_flags() op */
438 if (dev->ethtool_ops->set_flags) {
439 if (unlikely(dev->hw_features & flags_dup_features))
440 netdev_warn(dev,
441 "driver BUG: mixed hw_features and set_flags()\n");
442 return dev->ethtool_ops->set_flags(dev, data);
443 }
444
445 /* allow changing only bits set in hw_features */
446 changed = (data ^ dev->wanted_features) & flags_dup_features;
447 if (changed & ~dev->hw_features)
448 return (changed & dev->hw_features) ? -EINVAL : -EOPNOTSUPP;
449
450 dev->wanted_features =
451 (dev->wanted_features & ~changed) | data;
452
453 netdev_update_features(dev);
454
455 return 0;
456}
457
430static int ethtool_get_settings(struct net_device *dev, void __user *useraddr) 458static int ethtool_get_settings(struct net_device *dev, void __user *useraddr)
431{ 459{
432 struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET }; 460 struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET };
@@ -1768,8 +1796,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
1768 ethtool_op_get_flags)); 1796 ethtool_op_get_flags));
1769 break; 1797 break;
1770 case ETHTOOL_SFLAGS: 1798 case ETHTOOL_SFLAGS:
1771 rc = ethtool_set_value(dev, useraddr, 1799 rc = ethtool_set_value(dev, useraddr, __ethtool_set_flags);
1772 dev->ethtool_ops->set_flags);
1773 break; 1800 break;
1774 case ETHTOOL_GPFLAGS: 1801 case ETHTOOL_GPFLAGS:
1775 rc = ethtool_get_value(dev, useraddr, ethcmd, 1802 rc = ethtool_get_value(dev, useraddr, ethcmd,