diff options
author | Michał Mirosław <mirq-linux@rere.qmqm.pl> | 2011-02-15 11:59:17 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-02-17 17:16:33 -0500 |
commit | 5455c6998d34dc983a8693500e4dffefc3682dc5 (patch) | |
tree | b765aecf6d33d8c550cde78368ccc8654951ec07 /net/core/dev.c | |
parent | 0a417704777ed29d0e8c72b7274a328e61248e75 (diff) |
net: Introduce new feature setting ops
This introduces a new framework to handle device features setting.
It consists of:
- new fields in struct net_device:
+ hw_features - features that hw/driver supports toggling
+ wanted_features - features that user wants enabled, when possible
- new netdev_ops:
+ feat = ndo_fix_features(dev, feat) - API checking constraints for
enabling features or their combinations
+ ndo_set_features(dev) - API updating hardware state to match
changed dev->features
- new ethtool commands:
+ ETHTOOL_GFEATURES/ETHTOOL_SFEATURES: get/set dev->wanted_features
and trigger device reconfiguration if resulting dev->features
changed
+ ETHTOOL_GSTRINGS(ETH_SS_FEATURES): get feature bits names (meaning)
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/dev.c')
-rw-r--r-- | net/core/dev.c | 46 |
1 files changed, 40 insertions, 6 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 8686f6ffe7f0..4f6943928fe8 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -5302,6 +5302,37 @@ u32 netdev_fix_features(struct net_device *dev, u32 features) | |||
5302 | } | 5302 | } |
5303 | EXPORT_SYMBOL(netdev_fix_features); | 5303 | EXPORT_SYMBOL(netdev_fix_features); |
5304 | 5304 | ||
5305 | void netdev_update_features(struct net_device *dev) | ||
5306 | { | ||
5307 | u32 features; | ||
5308 | int err = 0; | ||
5309 | |||
5310 | features = netdev_get_wanted_features(dev); | ||
5311 | |||
5312 | if (dev->netdev_ops->ndo_fix_features) | ||
5313 | features = dev->netdev_ops->ndo_fix_features(dev, features); | ||
5314 | |||
5315 | /* driver might be less strict about feature dependencies */ | ||
5316 | features = netdev_fix_features(dev, features); | ||
5317 | |||
5318 | if (dev->features == features) | ||
5319 | return; | ||
5320 | |||
5321 | netdev_info(dev, "Features changed: 0x%08x -> 0x%08x\n", | ||
5322 | dev->features, features); | ||
5323 | |||
5324 | if (dev->netdev_ops->ndo_set_features) | ||
5325 | err = dev->netdev_ops->ndo_set_features(dev, features); | ||
5326 | |||
5327 | if (!err) | ||
5328 | dev->features = features; | ||
5329 | else if (err < 0) | ||
5330 | netdev_err(dev, | ||
5331 | "set_features() failed (%d); wanted 0x%08x, left 0x%08x\n", | ||
5332 | err, features, dev->features); | ||
5333 | } | ||
5334 | EXPORT_SYMBOL(netdev_update_features); | ||
5335 | |||
5305 | /** | 5336 | /** |
5306 | * netif_stacked_transfer_operstate - transfer operstate | 5337 | * netif_stacked_transfer_operstate - transfer operstate |
5307 | * @rootdev: the root or lower level device to transfer state from | 5338 | * @rootdev: the root or lower level device to transfer state from |
@@ -5436,15 +5467,18 @@ int register_netdevice(struct net_device *dev) | |||
5436 | if (dev->iflink == -1) | 5467 | if (dev->iflink == -1) |
5437 | dev->iflink = dev->ifindex; | 5468 | dev->iflink = dev->ifindex; |
5438 | 5469 | ||
5439 | /* Enable software offloads by default - will be stripped in | 5470 | /* Transfer changeable features to wanted_features and enable |
5440 | * netdev_fix_features() if not supported. */ | 5471 | * software offloads (GSO and GRO). |
5441 | dev->features |= NETIF_F_SOFT_FEATURES; | 5472 | */ |
5473 | dev->hw_features |= NETIF_F_SOFT_FEATURES; | ||
5474 | dev->wanted_features = (dev->features & dev->hw_features) | ||
5475 | | NETIF_F_SOFT_FEATURES; | ||
5442 | 5476 | ||
5443 | /* Avoid warning from netdev_fix_features() for GSO without SG */ | 5477 | /* Avoid warning from netdev_fix_features() for GSO without SG */ |
5444 | if (!(dev->features & NETIF_F_SG)) | 5478 | if (!(dev->wanted_features & NETIF_F_SG)) |
5445 | dev->features &= ~NETIF_F_GSO; | 5479 | dev->wanted_features &= ~NETIF_F_GSO; |
5446 | 5480 | ||
5447 | dev->features = netdev_fix_features(dev, dev->features); | 5481 | netdev_update_features(dev); |
5448 | 5482 | ||
5449 | /* Enable GRO and NETIF_F_HIGHDMA for vlans by default, | 5483 | /* Enable GRO and NETIF_F_HIGHDMA for vlans by default, |
5450 | * vlan_dev_init() will do the dev->features check, so these features | 5484 | * vlan_dev_init() will do the dev->features check, so these features |