Commit 6cb6a27c authored by Michał Mirosław's avatar Michał Mirosław Committed by David S. Miller

net: Call netdev_features_change() from netdev_update_features()

Issue FEAT_CHANGE notification when features are changed by
netdev_update_features().  This will allow changes made by extra constraints
on e.g. MTU change to be properly propagated like changes via ethtool.
Signed-off-by: default avatarMichał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e9403c84
...@@ -2550,6 +2550,7 @@ static inline u32 netdev_get_wanted_features(struct net_device *dev) ...@@ -2550,6 +2550,7 @@ static inline u32 netdev_get_wanted_features(struct net_device *dev)
} }
u32 netdev_increment_features(u32 all, u32 one, u32 mask); u32 netdev_increment_features(u32 all, u32 one, u32 mask);
u32 netdev_fix_features(struct net_device *dev, u32 features); u32 netdev_fix_features(struct net_device *dev, u32 features);
int __netdev_update_features(struct net_device *dev);
void netdev_update_features(struct net_device *dev); void netdev_update_features(struct net_device *dev);
void netif_stacked_transfer_operstate(const struct net_device *rootdev, void netif_stacked_transfer_operstate(const struct net_device *rootdev,
......
...@@ -5236,7 +5236,7 @@ u32 netdev_fix_features(struct net_device *dev, u32 features) ...@@ -5236,7 +5236,7 @@ u32 netdev_fix_features(struct net_device *dev, u32 features)
} }
EXPORT_SYMBOL(netdev_fix_features); EXPORT_SYMBOL(netdev_fix_features);
void netdev_update_features(struct net_device *dev) int __netdev_update_features(struct net_device *dev)
{ {
u32 features; u32 features;
int err = 0; int err = 0;
...@@ -5250,7 +5250,7 @@ void netdev_update_features(struct net_device *dev) ...@@ -5250,7 +5250,7 @@ void netdev_update_features(struct net_device *dev)
features = netdev_fix_features(dev, features); features = netdev_fix_features(dev, features);
if (dev->features == features) if (dev->features == features)
return; return 0;
netdev_info(dev, "Features changed: 0x%08x -> 0x%08x\n", netdev_info(dev, "Features changed: 0x%08x -> 0x%08x\n",
dev->features, features); dev->features, features);
...@@ -5258,12 +5258,23 @@ void netdev_update_features(struct net_device *dev) ...@@ -5258,12 +5258,23 @@ void netdev_update_features(struct net_device *dev)
if (dev->netdev_ops->ndo_set_features) if (dev->netdev_ops->ndo_set_features)
err = dev->netdev_ops->ndo_set_features(dev, features); err = dev->netdev_ops->ndo_set_features(dev, features);
if (!err) if (unlikely(err < 0)) {
dev->features = features;
else if (err < 0)
netdev_err(dev, netdev_err(dev,
"set_features() failed (%d); wanted 0x%08x, left 0x%08x\n", "set_features() failed (%d); wanted 0x%08x, left 0x%08x\n",
err, features, dev->features); err, features, dev->features);
return -1;
}
if (!err)
dev->features = features;
return 1;
}
void netdev_update_features(struct net_device *dev)
{
if (__netdev_update_features(dev))
netdev_features_change(dev);
} }
EXPORT_SYMBOL(netdev_update_features); EXPORT_SYMBOL(netdev_update_features);
...@@ -5430,7 +5441,7 @@ int register_netdevice(struct net_device *dev) ...@@ -5430,7 +5441,7 @@ int register_netdevice(struct net_device *dev)
goto err_uninit; goto err_uninit;
dev->reg_state = NETREG_REGISTERED; dev->reg_state = NETREG_REGISTERED;
netdev_update_features(dev); __netdev_update_features(dev);
/* /*
* Default initial state at registry is that the * Default initial state at registry is that the
......
...@@ -317,7 +317,7 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr) ...@@ -317,7 +317,7 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
dev->wanted_features &= ~features[0].valid; dev->wanted_features &= ~features[0].valid;
dev->wanted_features |= features[0].valid & features[0].requested; dev->wanted_features |= features[0].valid & features[0].requested;
netdev_update_features(dev); __netdev_update_features(dev);
if ((dev->wanted_features ^ dev->features) & features[0].valid) if ((dev->wanted_features ^ dev->features) & features[0].valid)
ret |= ETHTOOL_F_WISH; ret |= ETHTOOL_F_WISH;
...@@ -499,7 +499,7 @@ static int ethtool_set_one_feature(struct net_device *dev, ...@@ -499,7 +499,7 @@ static int ethtool_set_one_feature(struct net_device *dev,
else else
dev->wanted_features &= ~mask; dev->wanted_features &= ~mask;
netdev_update_features(dev); __netdev_update_features(dev);
return 0; return 0;
} }
...@@ -551,7 +551,7 @@ int __ethtool_set_flags(struct net_device *dev, u32 data) ...@@ -551,7 +551,7 @@ int __ethtool_set_flags(struct net_device *dev, u32 data)
dev->wanted_features = dev->wanted_features =
(dev->wanted_features & ~changed) | data; (dev->wanted_features & ~changed) | data;
netdev_update_features(dev); __netdev_update_features(dev);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment