All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFT PATCH 3/9] net: ethtool: break association of ETH_FLAG_* with NETIF_F_*
  2011-06-20 19:14 [RFT PATCH 0/9] Cleanup and extension of netdev features Michał Mirosław
@ 2011-06-20 19:14 ` Michał Mirosław
  2011-06-20 20:11   ` Ben Hutchings
  2011-06-20 19:14 ` [RFT PATCH 5/9] net: Define enum for net device features Michał Mirosław
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 28+ messages in thread
From: Michał Mirosław @ 2011-06-20 19:14 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Ben Hutchings

This is the only place where NETIF_F_* feature flags are exposed
to userspace. After this patch feature flags may be changed/reordered
freely.

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 net/core/ethtool.c |   33 +++++++++++++++++++++++----------
 1 files changed, 23 insertions(+), 10 deletions(-)

diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 58d98c3..9214e54 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -240,32 +240,45 @@ static int ethtool_set_one_feature(struct net_device *dev,
 	return 0;
 }
 
-/* the following list of flags are the same as their associated
- * NETIF_F_xxx values in include/linux/netdevice.h
- */
-static const u32 flags_dup_features =
-	(ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN | ETH_FLAG_NTUPLE |
-	 ETH_FLAG_RXHASH);
+#define ETH_ALL_FLAGS    (ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN | \
+			  ETH_FLAG_NTUPLE | ETH_FLAG_RXHASH)
+#define ETH_ALL_FEATURES (NETIF_F_LRO | NETIF_F_HW_VLAN_RX | \
+			  NETIF_F_HW_VLAN_TX | NETIF_F_NTUPLE | NETIF_F_RXHASH)
 
 static u32 __ethtool_get_flags(struct net_device *dev)
 {
-	return dev->features & flags_dup_features;
+	u32 flags = 0;
+
+	if (dev->features & NETIF_F_LRO)	flags |= ETH_FLAG_LRO;
+	if (dev->features & NETIF_F_HW_VLAN_RX)	flags |= ETH_FLAG_RXVLAN;
+	if (dev->features & NETIF_F_HW_VLAN_TX)	flags |= ETH_FLAG_TXVLAN;
+	if (dev->features & NETIF_F_NTUPLE)	flags |= ETH_FLAG_NTUPLE;
+	if (dev->features & NETIF_F_RXHASH)	flags |= ETH_FLAG_RXHASH;
+
+	return flags;
 }
 
 static int __ethtool_set_flags(struct net_device *dev, u32 data)
 {
+	u32 features = 0;
 	u32 changed;
 
-	if (data & ~flags_dup_features)
+	if (data & ~ETH_ALL_FLAGS)
 		return -EINVAL;
 
+	if (data & ETH_FLAG_LRO)	features |= NETIF_F_LRO;
+	if (data & ETH_FLAG_RXVLAN)	features |= NETIF_F_HW_VLAN_RX;
+	if (data & ETH_FLAG_TXVLAN)	features |= NETIF_F_HW_VLAN_TX;
+	if (data & ETH_FLAG_NTUPLE)	features |= NETIF_F_NTUPLE;
+	if (data & ETH_FLAG_RXHASH)	features |= NETIF_F_RXHASH;
+
 	/* allow changing only bits set in hw_features */
-	changed = (data ^ dev->features) & flags_dup_features;
+	changed = (features ^ dev->features) & ETH_ALL_FEATURES;
 	if (changed & ~dev->hw_features)
 		return (changed & dev->hw_features) ? -EINVAL : -EOPNOTSUPP;
 
 	dev->wanted_features =
-		(dev->wanted_features & ~changed) | (data & dev->hw_features);
+		(dev->wanted_features & ~changed) | (features & dev->hw_features);
 
 	__netdev_update_features(dev);
 
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [RFT PATCH 2/9] net: remove legacy ethtool ops
  2011-06-20 19:14 [RFT PATCH 0/9] Cleanup and extension of netdev features Michał Mirosław
  2011-06-20 19:14 ` [RFT PATCH 3/9] net: ethtool: break association of ETH_FLAG_* with NETIF_F_* Michał Mirosław
  2011-06-20 19:14 ` [RFT PATCH 5/9] net: Define enum for net device features Michał Mirosław
@ 2011-06-20 19:14 ` Michał Mirosław
  2011-06-20 19:14 ` [RFT PATCH 4/9] net: introduce and use netdev_features_t for device features sets Michał Mirosław
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 28+ messages in thread
From: Michał Mirosław @ 2011-06-20 19:14 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Ben Hutchings

As all drivers are converted, we may now remove discrete offload setting
callback handling.

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 include/linux/ethtool.h   |   53 ------
 include/linux/netdevice.h |   16 --
 net/8021q/vlan_dev.c      |    2 +-
 net/core/dev.c            |   12 +-
 net/core/ethtool.c        |  422 +++------------------------------------------
 5 files changed, 27 insertions(+), 478 deletions(-)

diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index dfd3493..b1d1a68 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -711,9 +711,6 @@ enum ethtool_sfeatures_retval_bits {
 
 #include <linux/rculist.h>
 
-/* needed by dev_disable_lro() */
-extern int __ethtool_set_flags(struct net_device *dev, u32 flags);
-
 /**
  * enum ethtool_phys_id_state - indicator state for physical identification
  * @ETHTOOL_ID_INACTIVE: Physical ID indicator should be deactivated
@@ -734,19 +731,6 @@ struct net_device;
 
 /* Some generic methods drivers may use in their ethtool_ops */
 u32 ethtool_op_get_link(struct net_device *dev);
-u32 ethtool_op_get_tx_csum(struct net_device *dev);
-int ethtool_op_set_tx_csum(struct net_device *dev, u32 data);
-int ethtool_op_set_tx_hw_csum(struct net_device *dev, u32 data);
-int ethtool_op_set_tx_ipv6_csum(struct net_device *dev, u32 data);
-u32 ethtool_op_get_sg(struct net_device *dev);
-int ethtool_op_set_sg(struct net_device *dev, u32 data);
-u32 ethtool_op_get_tso(struct net_device *dev);
-int ethtool_op_set_tso(struct net_device *dev, u32 data);
-u32 ethtool_op_get_ufo(struct net_device *dev);
-int ethtool_op_set_ufo(struct net_device *dev, u32 data);
-u32 ethtool_op_get_flags(struct net_device *dev);
-int ethtool_op_set_flags(struct net_device *dev, u32 data, u32 supported);
-bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported);
 
 /**
  * struct ethtool_ops - optional netdev operations
@@ -791,22 +775,6 @@ bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported);
  * @get_pauseparam: Report pause parameters
  * @set_pauseparam: Set pause parameters.  Returns a negative error code
  *	or zero.
- * @get_rx_csum: Deprecated in favour of the netdev feature %NETIF_F_RXCSUM.
- *	Report whether receive checksums are turned on or off.
- * @set_rx_csum: Deprecated in favour of generic netdev features.  Turn
- *	receive checksum on or off.  Returns a negative error code or zero.
- * @get_tx_csum: Deprecated as redundant. Report whether transmit checksums
- *	are turned on or off.
- * @set_tx_csum: Deprecated in favour of generic netdev features.  Turn
- *	transmit checksums on or off.  Returns a egative error code or zero.
- * @get_sg: Deprecated as redundant.  Report whether scatter-gather is
- *	enabled.  
- * @set_sg: Deprecated in favour of generic netdev features.  Turn
- *	scatter-gather on or off. Returns a negative error code or zero.
- * @get_tso: Deprecated as redundant.  Report whether TCP segmentation
- *	offload is enabled.
- * @set_tso: Deprecated in favour of generic netdev features.  Turn TCP
- *	segmentation offload on or off.  Returns a negative error code or zero.
  * @self_test: Run specified self-tests
  * @get_strings: Return a set of strings that describe the requested objects
  * @set_phys_id: Identify the physical devices, e.g. by flashing an LED
@@ -828,15 +796,6 @@ bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported);
  *	negative error code or zero.
  * @complete: Function to be called after any other operation except
  *	@begin.  Will be called even if the other operation failed.
- * @get_ufo: Deprecated as redundant.  Report whether UDP fragmentation
- *	offload is enabled.
- * @set_ufo: Deprecated in favour of generic netdev features.  Turn UDP
- *	fragmentation offload on or off.  Returns a negative error code or zero.
- * @get_flags: Deprecated as redundant.  Report features included in
- *	&enum ethtool_flags that are enabled.  
- * @set_flags: Deprecated in favour of generic netdev features.  Turn
- *	features included in &enum ethtool_flags on or off.  Returns a
- *	negative error code or zero.
  * @get_priv_flags: Report driver-specific feature flags.
  * @set_priv_flags: Set driver-specific feature flags.  Returns a negative
  *	error code or zero.
@@ -901,14 +860,6 @@ struct ethtool_ops {
 				  struct ethtool_pauseparam*);
 	int	(*set_pauseparam)(struct net_device *,
 				  struct ethtool_pauseparam*);
-	u32	(*get_rx_csum)(struct net_device *);
-	int	(*set_rx_csum)(struct net_device *, u32);
-	u32	(*get_tx_csum)(struct net_device *);
-	int	(*set_tx_csum)(struct net_device *, u32);
-	u32	(*get_sg)(struct net_device *);
-	int	(*set_sg)(struct net_device *, u32);
-	u32	(*get_tso)(struct net_device *);
-	int	(*set_tso)(struct net_device *, u32);
 	void	(*self_test)(struct net_device *, struct ethtool_test *, u64 *);
 	void	(*get_strings)(struct net_device *, u32 stringset, u8 *);
 	int	(*set_phys_id)(struct net_device *, enum ethtool_phys_id_state);
@@ -916,10 +867,6 @@ struct ethtool_ops {
 				     struct ethtool_stats *, u64 *);
 	int	(*begin)(struct net_device *);
 	void	(*complete)(struct net_device *);
-	u32	(*get_ufo)(struct net_device *);
-	int	(*set_ufo)(struct net_device *, u32);
-	u32	(*get_flags)(struct net_device *);
-	int	(*set_flags)(struct net_device *, u32);
 	u32	(*get_priv_flags)(struct net_device *);
 	int	(*set_priv_flags)(struct net_device *, u32);
 	int	(*get_sset_count)(struct net_device *, int);
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 6469fa9..3482ee9 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2604,22 +2604,6 @@ extern struct pernet_operations __net_initdata loopback_net_ops;
 int dev_ethtool_get_settings(struct net_device *dev,
 			     struct ethtool_cmd *cmd);
 
-static inline u32 dev_ethtool_get_rx_csum(struct net_device *dev)
-{
-	if (dev->features & NETIF_F_RXCSUM)
-		return 1;
-	if (!dev->ethtool_ops || !dev->ethtool_ops->get_rx_csum)
-		return 0;
-	return dev->ethtool_ops->get_rx_csum(dev);
-}
-
-static inline u32 dev_ethtool_get_flags(struct net_device *dev)
-{
-	if (!dev->ethtool_ops || !dev->ethtool_ops->get_flags)
-		return 0;
-	return dev->ethtool_ops->get_flags(dev);
-}
-
 /* Logging, debugging and troubleshooting/diagnostic helpers. */
 
 /* netdev_printk helpers, similar to dev_printk */
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 1c9aa8c..774bd22 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -591,7 +591,7 @@ static u32 vlan_dev_fix_features(struct net_device *dev, u32 features)
 
 	features &= real_dev->features;
 	features &= real_dev->vlan_features;
-	if (dev_ethtool_get_rx_csum(real_dev))
+	if (real_dev->features & NETIF_F_RXCSUM)
 		features |= NETIF_F_RXCSUM;
 	features |= NETIF_F_LLTX;
 
diff --git a/net/core/dev.c b/net/core/dev.c
index b3f52d2..3041b6ae 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1306,8 +1306,6 @@ EXPORT_SYMBOL(dev_close);
  */
 void dev_disable_lro(struct net_device *dev)
 {
-	u32 flags;
-
 	/*
 	 * If we're trying to disable lro on a vlan device
 	 * use the underlying physical device instead
@@ -1315,15 +1313,9 @@ void dev_disable_lro(struct net_device *dev)
 	if (is_vlan_dev(dev))
 		dev = vlan_dev_real_dev(dev);
 
-	if (dev->ethtool_ops && dev->ethtool_ops->get_flags)
-		flags = dev->ethtool_ops->get_flags(dev);
-	else
-		flags = ethtool_op_get_flags(dev);
+	dev->wanted_features &= ~NETIF_F_LRO;
+	netdev_update_features(dev);
 
-	if (!(flags & ETH_FLAG_LRO))
-		return;
-
-	__ethtool_set_flags(dev, flags & ~ETH_FLAG_LRO);
 	if (unlikely(dev->features & NETIF_F_LRO))
 		netdev_WARN(dev, "failed to disable LRO!\n");
 }
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index b7c12a6..58d98c3 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -36,236 +36,10 @@ u32 ethtool_op_get_link(struct net_device *dev)
 }
 EXPORT_SYMBOL(ethtool_op_get_link);
 
-u32 ethtool_op_get_tx_csum(struct net_device *dev)
-{
-	return (dev->features & NETIF_F_ALL_CSUM) != 0;
-}
-EXPORT_SYMBOL(ethtool_op_get_tx_csum);
-
-int ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
-{
-	if (data)
-		dev->features |= NETIF_F_IP_CSUM;
-	else
-		dev->features &= ~NETIF_F_IP_CSUM;
-
-	return 0;
-}
-EXPORT_SYMBOL(ethtool_op_set_tx_csum);
-
-int ethtool_op_set_tx_hw_csum(struct net_device *dev, u32 data)
-{
-	if (data)
-		dev->features |= NETIF_F_HW_CSUM;
-	else
-		dev->features &= ~NETIF_F_HW_CSUM;
-
-	return 0;
-}
-EXPORT_SYMBOL(ethtool_op_set_tx_hw_csum);
-
-int ethtool_op_set_tx_ipv6_csum(struct net_device *dev, u32 data)
-{
-	if (data)
-		dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
-	else
-		dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
-
-	return 0;
-}
-EXPORT_SYMBOL(ethtool_op_set_tx_ipv6_csum);
-
-u32 ethtool_op_get_sg(struct net_device *dev)
-{
-	return (dev->features & NETIF_F_SG) != 0;
-}
-EXPORT_SYMBOL(ethtool_op_get_sg);
-
-int ethtool_op_set_sg(struct net_device *dev, u32 data)
-{
-	if (data)
-		dev->features |= NETIF_F_SG;
-	else
-		dev->features &= ~NETIF_F_SG;
-
-	return 0;
-}
-EXPORT_SYMBOL(ethtool_op_set_sg);
-
-u32 ethtool_op_get_tso(struct net_device *dev)
-{
-	return (dev->features & NETIF_F_TSO) != 0;
-}
-EXPORT_SYMBOL(ethtool_op_get_tso);
-
-int ethtool_op_set_tso(struct net_device *dev, u32 data)
-{
-	if (data)
-		dev->features |= NETIF_F_TSO;
-	else
-		dev->features &= ~NETIF_F_TSO;
-
-	return 0;
-}
-EXPORT_SYMBOL(ethtool_op_set_tso);
-
-u32 ethtool_op_get_ufo(struct net_device *dev)
-{
-	return (dev->features & NETIF_F_UFO) != 0;
-}
-EXPORT_SYMBOL(ethtool_op_get_ufo);
-
-int ethtool_op_set_ufo(struct net_device *dev, u32 data)
-{
-	if (data)
-		dev->features |= NETIF_F_UFO;
-	else
-		dev->features &= ~NETIF_F_UFO;
-	return 0;
-}
-EXPORT_SYMBOL(ethtool_op_set_ufo);
-
-/* the following list of flags are the same as their associated
- * NETIF_F_xxx values in include/linux/netdevice.h
- */
-static const u32 flags_dup_features =
-	(ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN | ETH_FLAG_NTUPLE |
-	 ETH_FLAG_RXHASH);
-
-u32 ethtool_op_get_flags(struct net_device *dev)
-{
-	/* in the future, this function will probably contain additional
-	 * handling for flags which are not so easily handled
-	 * by a simple masking operation
-	 */
-
-	return dev->features & flags_dup_features;
-}
-EXPORT_SYMBOL(ethtool_op_get_flags);
-
-/* Check if device can enable (or disable) particular feature coded in "data"
- * argument. Flags "supported" describe features that can be toggled by device.
- * If feature can not be toggled, it state (enabled or disabled) must match
- * hardcoded device features state, otherwise flags are marked as invalid.
- */
-bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported)
-{
-	u32 features = dev->features & flags_dup_features;
-	/* "data" can contain only flags_dup_features bits,
-	 * see __ethtool_set_flags */
-
-	return (features & ~supported) != (data & ~supported);
-}
-EXPORT_SYMBOL(ethtool_invalid_flags);
-
-int ethtool_op_set_flags(struct net_device *dev, u32 data, u32 supported)
-{
-	if (ethtool_invalid_flags(dev, data, supported))
-		return -EINVAL;
-
-	dev->features = ((dev->features & ~flags_dup_features) |
-			 (data & flags_dup_features));
-	return 0;
-}
-EXPORT_SYMBOL(ethtool_op_set_flags);
-
 /* Handlers for each ethtool command */
 
 #define ETHTOOL_DEV_FEATURE_WORDS	1
 
-static void ethtool_get_features_compat(struct net_device *dev,
-	struct ethtool_get_features_block *features)
-{
-	if (!dev->ethtool_ops)
-		return;
-
-	/* getting RX checksum */
-	if (dev->ethtool_ops->get_rx_csum)
-		if (dev->ethtool_ops->get_rx_csum(dev))
-			features[0].active |= NETIF_F_RXCSUM;
-
-	/* mark legacy-changeable features */
-	if (dev->ethtool_ops->set_sg)
-		features[0].available |= NETIF_F_SG;
-	if (dev->ethtool_ops->set_tx_csum)
-		features[0].available |= NETIF_F_ALL_CSUM;
-	if (dev->ethtool_ops->set_tso)
-		features[0].available |= NETIF_F_ALL_TSO;
-	if (dev->ethtool_ops->set_rx_csum)
-		features[0].available |= NETIF_F_RXCSUM;
-	if (dev->ethtool_ops->set_flags)
-		features[0].available |= flags_dup_features;
-}
-
-static int ethtool_set_feature_compat(struct net_device *dev,
-	int (*legacy_set)(struct net_device *, u32),
-	struct ethtool_set_features_block *features, u32 mask)
-{
-	u32 do_set;
-
-	if (!legacy_set)
-		return 0;
-
-	if (!(features[0].valid & mask))
-		return 0;
-
-	features[0].valid &= ~mask;
-
-	do_set = !!(features[0].requested & mask);
-
-	if (legacy_set(dev, do_set) < 0)
-		netdev_info(dev,
-			"Legacy feature change (%s) failed for 0x%08x\n",
-			do_set ? "set" : "clear", mask);
-
-	return 1;
-}
-
-static int ethtool_set_flags_compat(struct net_device *dev,
-	int (*legacy_set)(struct net_device *, u32),
-	struct ethtool_set_features_block *features, u32 mask)
-{
-	u32 value;
-
-	if (!legacy_set)
-		return 0;
-
-	if (!(features[0].valid & mask))
-		return 0;
-
-	value = dev->features & ~features[0].valid;
-	value |= features[0].requested;
-
-	features[0].valid &= ~mask;
-
-	if (legacy_set(dev, value & mask) < 0)
-		netdev_info(dev, "Legacy flags change failed\n");
-
-	return 1;
-}
-
-static int ethtool_set_features_compat(struct net_device *dev,
-	struct ethtool_set_features_block *features)
-{
-	int compat;
-
-	if (!dev->ethtool_ops)
-		return 0;
-
-	compat  = ethtool_set_feature_compat(dev, dev->ethtool_ops->set_sg,
-		features, NETIF_F_SG);
-	compat |= ethtool_set_feature_compat(dev, dev->ethtool_ops->set_tx_csum,
-		features, NETIF_F_ALL_CSUM);
-	compat |= ethtool_set_feature_compat(dev, dev->ethtool_ops->set_tso,
-		features, NETIF_F_ALL_TSO);
-	compat |= ethtool_set_feature_compat(dev, dev->ethtool_ops->set_rx_csum,
-		features, NETIF_F_RXCSUM);
-	compat |= ethtool_set_flags_compat(dev, dev->ethtool_ops->set_flags,
-		features, flags_dup_features);
-
-	return compat;
-}
-
 static int ethtool_get_features(struct net_device *dev, void __user *useraddr)
 {
 	struct ethtool_gfeatures cmd = {
@@ -283,8 +57,6 @@ static int ethtool_get_features(struct net_device *dev, void __user *useraddr)
 	u32 __user *sizeaddr;
 	u32 copy_size;
 
-	ethtool_get_features_compat(dev, features);
-
 	sizeaddr = useraddr + offsetof(struct ethtool_gfeatures, size);
 	if (get_user(copy_size, sizeaddr))
 		return -EFAULT;
@@ -320,9 +92,6 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
 	if (features[0].valid & ~NETIF_F_ETHTOOL_BITS)
 		return -EINVAL;
 
-	if (ethtool_set_features_compat(dev, features))
-		ret |= ETHTOOL_F_COMPAT;
-
 	if (features[0].valid & ~dev->hw_features) {
 		features[0].valid &= dev->hw_features;
 		ret |= ETHTOOL_F_UNSUPPORTED;
@@ -433,34 +202,6 @@ static u32 ethtool_get_feature_mask(u32 eth_cmd)
 	}
 }
 
-static void *__ethtool_get_one_feature_actor(struct net_device *dev, u32 ethcmd)
-{
-	const struct ethtool_ops *ops = dev->ethtool_ops;
-
-	if (!ops)
-		return NULL;
-
-	switch (ethcmd) {
-	case ETHTOOL_GTXCSUM:
-		return ops->get_tx_csum;
-	case ETHTOOL_GRXCSUM:
-		return ops->get_rx_csum;
-	case ETHTOOL_SSG:
-		return ops->get_sg;
-	case ETHTOOL_STSO:
-		return ops->get_tso;
-	case ETHTOOL_SUFO:
-		return ops->get_ufo;
-	default:
-		return NULL;
-	}
-}
-
-static u32 __ethtool_get_rx_csum_oldbug(struct net_device *dev)
-{
-	return !!(dev->features & NETIF_F_ALL_CSUM);
-}
-
 static int ethtool_get_one_feature(struct net_device *dev,
 	char __user *useraddr, u32 ethcmd)
 {
@@ -470,31 +211,11 @@ static int ethtool_get_one_feature(struct net_device *dev,
 		.data = !!(dev->features & mask),
 	};
 
-	/* compatibility with discrete get_ ops */
-	if (!(dev->hw_features & mask)) {
-		u32 (*actor)(struct net_device *);
-
-		actor = __ethtool_get_one_feature_actor(dev, ethcmd);
-
-		/* bug compatibility with old get_rx_csum */
-		if (ethcmd == ETHTOOL_GRXCSUM && !actor)
-			actor = __ethtool_get_rx_csum_oldbug;
-
-		if (actor)
-			edata.data = actor(dev);
-	}
-
 	if (copy_to_user(useraddr, &edata, sizeof(edata)))
 		return -EFAULT;
 	return 0;
 }
 
-static int __ethtool_set_tx_csum(struct net_device *dev, u32 data);
-static int __ethtool_set_rx_csum(struct net_device *dev, u32 data);
-static int __ethtool_set_sg(struct net_device *dev, u32 data);
-static int __ethtool_set_tso(struct net_device *dev, u32 data);
-static int __ethtool_set_ufo(struct net_device *dev, u32 data);
-
 static int ethtool_set_one_feature(struct net_device *dev,
 	void __user *useraddr, u32 ethcmd)
 {
@@ -506,56 +227,38 @@ static int ethtool_set_one_feature(struct net_device *dev,
 
 	mask = ethtool_get_feature_mask(ethcmd);
 	mask &= dev->hw_features;
-	if (mask) {
-		if (edata.data)
-			dev->wanted_features |= mask;
-		else
-			dev->wanted_features &= ~mask;
-
-		__netdev_update_features(dev);
-		return 0;
-	}
-
-	/* Driver is not converted to ndo_fix_features or does not
-	 * support changing this offload. In the latter case it won't
-	 * have corresponding ethtool_ops field set.
-	 *
-	 * Following part is to be removed after all drivers advertise
-	 * their changeable features in netdev->hw_features and stop
-	 * using discrete offload setting ops.
-	 */
-
-	switch (ethcmd) {
-	case ETHTOOL_STXCSUM:
-		return __ethtool_set_tx_csum(dev, edata.data);
-	case ETHTOOL_SRXCSUM:
-		return __ethtool_set_rx_csum(dev, edata.data);
-	case ETHTOOL_SSG:
-		return __ethtool_set_sg(dev, edata.data);
-	case ETHTOOL_STSO:
-		return __ethtool_set_tso(dev, edata.data);
-	case ETHTOOL_SUFO:
-		return __ethtool_set_ufo(dev, edata.data);
-	default:
+	if (!mask)
 		return -EOPNOTSUPP;
-	}
+
+	if (edata.data)
+		dev->wanted_features |= mask;
+	else
+		dev->wanted_features &= ~mask;
+
+	__netdev_update_features(dev);
+
+	return 0;
+}
+
+/* the following list of flags are the same as their associated
+ * NETIF_F_xxx values in include/linux/netdevice.h
+ */
+static const u32 flags_dup_features =
+	(ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN | ETH_FLAG_NTUPLE |
+	 ETH_FLAG_RXHASH);
+
+static u32 __ethtool_get_flags(struct net_device *dev)
+{
+	return dev->features & flags_dup_features;
 }
 
-int __ethtool_set_flags(struct net_device *dev, u32 data)
+static int __ethtool_set_flags(struct net_device *dev, u32 data)
 {
 	u32 changed;
 
 	if (data & ~flags_dup_features)
 		return -EINVAL;
 
-	/* legacy set_flags() op */
-	if (dev->ethtool_ops->set_flags) {
-		if (unlikely(dev->hw_features & flags_dup_features))
-			netdev_warn(dev,
-				"driver BUG: mixed hw_features and set_flags()\n");
-		return dev->ethtool_ops->set_flags(dev, data);
-	}
-
 	/* allow changing only bits set in hw_features */
 	changed = (data ^ dev->features) & flags_dup_features;
 	if (changed & ~dev->hw_features)
@@ -1221,81 +924,6 @@ static int ethtool_set_pauseparam(struct net_device *dev, void __user *useraddr)
 	return dev->ethtool_ops->set_pauseparam(dev, &pauseparam);
 }
 
-static int __ethtool_set_sg(struct net_device *dev, u32 data)
-{
-	int err;
-
-	if (!dev->ethtool_ops->set_sg)
-		return -EOPNOTSUPP;
-
-	if (data && !(dev->features & NETIF_F_ALL_CSUM))
-		return -EINVAL;
-
-	if (!data && dev->ethtool_ops->set_tso) {
-		err = dev->ethtool_ops->set_tso(dev, 0);
-		if (err)
-			return err;
-	}
-
-	if (!data && dev->ethtool_ops->set_ufo) {
-		err = dev->ethtool_ops->set_ufo(dev, 0);
-		if (err)
-			return err;
-	}
-	return dev->ethtool_ops->set_sg(dev, data);
-}
-
-static int __ethtool_set_tx_csum(struct net_device *dev, u32 data)
-{
-	int err;
-
-	if (!dev->ethtool_ops->set_tx_csum)
-		return -EOPNOTSUPP;
-
-	if (!data && dev->ethtool_ops->set_sg) {
-		err = __ethtool_set_sg(dev, 0);
-		if (err)
-			return err;
-	}
-
-	return dev->ethtool_ops->set_tx_csum(dev, data);
-}
-
-static int __ethtool_set_rx_csum(struct net_device *dev, u32 data)
-{
-	if (!dev->ethtool_ops->set_rx_csum)
-		return -EOPNOTSUPP;
-
-	if (!data)
-		dev->features &= ~NETIF_F_GRO;
-
-	return dev->ethtool_ops->set_rx_csum(dev, data);
-}
-
-static int __ethtool_set_tso(struct net_device *dev, u32 data)
-{
-	if (!dev->ethtool_ops->set_tso)
-		return -EOPNOTSUPP;
-
-	if (data && !(dev->features & NETIF_F_SG))
-		return -EINVAL;
-
-	return dev->ethtool_ops->set_tso(dev, data);
-}
-
-static int __ethtool_set_ufo(struct net_device *dev, u32 data)
-{
-	if (!dev->ethtool_ops->set_ufo)
-		return -EOPNOTSUPP;
-	if (data && !(dev->features & NETIF_F_SG))
-		return -EINVAL;
-	if (data && !((dev->features & NETIF_F_GEN_CSUM) ||
-		(dev->features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))
-			== (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM)))
-		return -EINVAL;
-	return dev->ethtool_ops->set_ufo(dev, data);
-}
-
 static int ethtool_self_test(struct net_device *dev, char __user *useraddr)
 {
 	struct ethtool_test test;
@@ -1761,9 +1389,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
 		break;
 	case ETHTOOL_GFLAGS:
 		rc = ethtool_get_value(dev, useraddr, ethcmd,
-				       (dev->ethtool_ops->get_flags ?
-					dev->ethtool_ops->get_flags :
-					ethtool_op_get_flags));
+					__ethtool_get_flags);
 		break;
 	case ETHTOOL_SFLAGS:
 		rc = ethtool_set_value(dev, useraddr, __ethtool_set_flags);
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [RFT PATCH 0/9] Cleanup and extension of netdev features
@ 2011-06-20 19:14 Michał Mirosław
  2011-06-20 19:14 ` [RFT PATCH 3/9] net: ethtool: break association of ETH_FLAG_* with NETIF_F_* Michał Mirosław
                   ` (10 more replies)
  0 siblings, 11 replies; 28+ messages in thread
From: Michał Mirosław @ 2011-06-20 19:14 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Ben Hutchings

This is a preview of the cleanups pending after getting rid of old
ethtool ops from remaining drivers.

Patches inside:
 1. (placeholder for Intel patches)
 2. removal of old ethtool ops
	(most further patches depend on this one)
 3. break association of ETH_FLAG_* with netdev features
	this will allow to change the representation and access pattern
	of the feature sets if later needed; as a bonus, the features
	can be (almost) freely rearranged
 4. introducing netdev_features_t
	use new type wherever features are passed around (this needed
	new include - otherwise linux/skbuff.h would need linux/netdevice.h)
 5. cleanup of feature bits
 6. cleanup of feature name table
	(depends on #5)
 7. prepare ethtool [GS]FEATURES for larger netdev_features_t
 8. tadaaa: 64 bits for features
 9. a lone cleanup patch for NOCACHE_COPY feature

Bear in mind, that I only compile tested the whole series (x86 allyesconfig).
I'll do per-patch builds after all needed patches are in net-next.

Note about netdev_features_t: I don't like the idea of converting it to
bitmap type and building wrappers around, so I won't even try to
implement it. Nevertheless, this series will make the conversion easier
if someone ever wants to go that way.

Best Regards,
Michał Mirosław

---

Michał Mirosław (9):
  [NOT SENT] Intel net drivers: convert to ndo_fix_features
  net: remove legacy ethtool ops
  net: ethtool: break association of ETH_FLAG_* with NETIF_F_*
  net: introduce and use netdev_features_t for device features sets
  net: Define enum for net device features.
  net: ethtool: use C99 array initialization for feature-names table
  ethtool: prepare for larger netdev_features_t type
  net: extend netdev_features_t to 64 bits
  net: move NOCACHE_COPY checks to netdev_fix_features()

 drivers/net/8139cp.c                  |    2 +-
 drivers/net/bnx2.c                    |    6 +-
 drivers/net/bnx2x/bnx2x_cmn.c         |    5 +-
 drivers/net/bnx2x/bnx2x_cmn.h         |    5 +-
 drivers/net/bonding/bond_main.c       |    9 +-
 drivers/net/cxgb4/cxgb4_main.c        |   12 +-
 drivers/net/dm9000.c                  |    3 +-
 drivers/net/e1000/e1000_ethtool.c     |   69 ----
 drivers/net/e1000/e1000_main.c        |   31 ++-
 drivers/net/e1000e/ethtool.c          |   88 -----
 drivers/net/e1000e/netdev.c           |   35 ++-
 drivers/net/forcedeth.c               |    7 +-
 drivers/net/gianfar.h                 |    2 +-
 drivers/net/gianfar_ethtool.c         |    4 +-
 drivers/net/ibmveth.c                 |    6 +-
 drivers/net/igb/igb_ethtool.c         |   67 ----
 drivers/net/igb/igb_main.c            |   33 ++-
 drivers/net/igbvf/ethtool.c           |   57 ----
 drivers/net/igbvf/netdev.c            |   25 ++-
 drivers/net/ixgb/ixgb.h               |    2 +
 drivers/net/ixgb/ixgb_ethtool.c       |   98 +------
 drivers/net/ixgb/ixgb_main.c          |   44 +++-
 drivers/net/ixgbe/ixgbe_ethtool.c     |  183 ++++--------
 drivers/net/ixgbe/ixgbe_main.c        |   42 ++-
 drivers/net/ixgbevf/ethtool.c         |   46 ---
 drivers/net/ixgbevf/ixgbevf_main.c    |   26 ++-
 drivers/net/jme.c                     |    8 +-
 drivers/net/ksz884x.c                 |    3 +-
 drivers/net/mv643xx_eth.c             |    2 +-
 drivers/net/myri10ge/myri10ge.c       |    2 +-
 drivers/net/netxen/netxen_nic_main.c  |    6 +-
 drivers/net/pch_gbe/pch_gbe_main.c    |    5 +-
 drivers/net/qlcnic/qlcnic.h           |    5 +-
 drivers/net/qlcnic/qlcnic_hw.c        |    9 +-
 drivers/net/qlcnic/qlcnic_main.c      |    2 +-
 drivers/net/r8169.c                   |    6 +-
 drivers/net/s2io.c                    |    4 +-
 drivers/net/sfc/efx.c                 |    2 +-
 drivers/net/sky2.c                    |    5 +-
 drivers/net/tg3.c                     |    7 +-
 drivers/net/usb/smsc75xx.c            |    3 +-
 drivers/net/usb/smsc95xx.c            |    3 +-
 drivers/net/vmxnet3/vmxnet3_ethtool.c |    4 +-
 drivers/net/vmxnet3/vmxnet3_int.h     |    2 +-
 drivers/net/vxge/vxge-main.c          |    9 +-
 drivers/net/xen-netfront.c            |    8 +-
 drivers/s390/net/qeth_l3_main.c       |    6 +-
 include/linux/ethtool.h               |   53 ---
 include/linux/netdev_features.h       |  152 +++++++++
 include/linux/netdevice.h             |  141 ++-------
 include/linux/skbuff.h                |    4 +-
 include/net/protocol.h                |    4 +-
 include/net/tcp.h                     |    3 +-
 include/net/udp.h                     |    3 +-
 net/8021q/vlan_dev.c                  |    5 +-
 net/bridge/br_if.c                    |    5 +-
 net/core/dev.c                        |   71 ++--
 net/core/ethtool.c                    |  563 ++++++--------------------------
 net/core/net-sysfs.c                  |    3 +-
 net/core/skbuff.c                     |    2 +-
 net/ipv4/af_inet.c                    |    3 +-
 net/ipv4/tcp.c                        |    2 +-
 net/ipv4/udp.c                        |    3 +-
 net/ipv6/af_inet6.c                   |    3 +-
 net/ipv6/udp.c                        |    2 +-
 65 files changed, 683 insertions(+), 1347 deletions(-)
 create mode 100644 include/linux/netdev_features.h

-- 
1.7.2.5


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [RFT PATCH 5/9] net: Define enum for net device features.
  2011-06-20 19:14 [RFT PATCH 0/9] Cleanup and extension of netdev features Michał Mirosław
  2011-06-20 19:14 ` [RFT PATCH 3/9] net: ethtool: break association of ETH_FLAG_* with NETIF_F_* Michał Mirosław
@ 2011-06-20 19:14 ` Michał Mirosław
  2011-06-20 19:14 ` [RFT PATCH 2/9] net: remove legacy ethtool ops Michał Mirosław
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 28+ messages in thread
From: Michał Mirosław @ 2011-06-20 19:14 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Ben Hutchings

Define feature values by bit position instead of direct 2**i values
and force the values to be of type netdev_features_t.

Cleaned and extended from patch by Mahesh Bandewar <maheshb@google.com>:
+ added netdev_features_t casts
+ included bits under NETIF_F_GSO_MASK
+ moved feature #defines out of struct net_device definition

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 include/linux/netdev_features.h |  125 +++++++++++++++++++++++++++-----------
 1 files changed, 89 insertions(+), 36 deletions(-)

diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
index d36bdcd..2361e3ee 100644
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
@@ -14,55 +14,108 @@
 
 typedef u32 netdev_features_t;
 
-#define NETIF_F_SG		1	/* Scatter/gather IO. */
-#define NETIF_F_IP_CSUM		2	/* Can checksum TCP/UDP over IPv4. */
-#define NETIF_F_NO_CSUM		4	/* Does not require checksum. F.e. loopack. */
-#define NETIF_F_HW_CSUM		8	/* Can checksum all the packets. */
-#define NETIF_F_IPV6_CSUM	16	/* Can checksum TCP/UDP over IPV6 */
-#define NETIF_F_HIGHDMA		32	/* Can DMA to high memory. */
-#define NETIF_F_FRAGLIST	64	/* Scatter/gather IO. */
-#define NETIF_F_HW_VLAN_TX	128	/* Transmit VLAN hw acceleration */
-#define NETIF_F_HW_VLAN_RX	256	/* Receive VLAN hw acceleration */
-#define NETIF_F_HW_VLAN_FILTER	512	/* Receive filtering on VLAN */
-#define NETIF_F_VLAN_CHALLENGED	1024	/* Device cannot handle VLAN packets */
-#define NETIF_F_GSO		2048	/* Enable software GSO. */
-#define NETIF_F_LLTX		4096	/* LockLess TX - deprecated. Please */
+enum {
+	NETIF_F_SG_BIT,			/* Scatter/gather IO. */
+	NETIF_F_IP_CSUM_BIT,		/* Can checksum TCP/UDP over IPv4. */
+	NETIF_F_NO_CSUM_BIT,		/* Does not require checksum. F.e. loopack. */
+	NETIF_F_HW_CSUM_BIT,		/* Can checksum all the packets. */
+	NETIF_F_IPV6_CSUM_BIT,		/* Can checksum TCP/UDP over IPV6 */
+	NETIF_F_HIGHDMA_BIT,		/* Can DMA to high memory. */
+	NETIF_F_FRAGLIST_BIT,		/* Scatter/gather IO. */
+	NETIF_F_HW_VLAN_TX_BIT,		/* Transmit VLAN hw acceleration */
+	NETIF_F_HW_VLAN_RX_BIT,		/* Receive VLAN hw acceleration */
+	NETIF_F_HW_VLAN_FILTER_BIT,	/* Receive filtering on VLAN */
+	NETIF_F_VLAN_CHALLENGED_BIT,	/* Device cannot handle VLAN packets */
+	NETIF_F_GSO_BIT,		/* Enable software GSO. */
+	NETIF_F_LLTX_BIT,		/* LockLess TX - deprecated. Please */
 					/* do not use LLTX in new drivers */
-#define NETIF_F_NETNS_LOCAL	8192	/* Does not change network namespaces */
-#define NETIF_F_GRO		16384	/* Generic receive offload */
-#define NETIF_F_LRO		32768	/* large receive offload */
+	NETIF_F_NETNS_LOCAL_BIT,	/* Does not change network namespaces */
+	NETIF_F_GRO_BIT,		/* Generic receive offload */
+	NETIF_F_LRO_BIT,		/* large receive offload */
 
-/* the GSO_MASK reserves bits 16 through 23 */
-#define NETIF_F_FCOE_CRC	(1 << 24) /* FCoE CRC32 */
-#define NETIF_F_SCTP_CSUM	(1 << 25) /* SCTP checksum offload */
-#define NETIF_F_FCOE_MTU	(1 << 26) /* Supports max FCoE MTU, 2158 bytes*/
-#define NETIF_F_NTUPLE		(1 << 27) /* N-tuple filters supported */
-#define NETIF_F_RXHASH		(1 << 28) /* Receive hashing offload */
-#define NETIF_F_RXCSUM		(1 << 29) /* Receive checksumming offload */
-#define NETIF_F_NOCACHE_COPY	(1 << 30) /* Use no-cache copyfromuser */
-#define NETIF_F_LOOPBACK	(1 << 31) /* Enable loopback */
+	/**/NETIF_F_GSO_SHIFT,		/* keep the order of SKB_GSO_* bits */
+	NETIF_F_TSO_BIT			/* ... TCPv4 segmentation */
+		= NETIF_F_GSO_SHIFT,
+	NETIF_F_UFO_BIT,		/* ... UDPv4 fragmentation */
+	NETIF_F_GSO_ROBUST_BIT,		/* ... ->SKB_GSO_DODGY */
+	NETIF_F_TSO_ECN_BIT,		/* ... TCP ECN support */
+	NETIF_F_TSO6_BIT,		/* ... TCPv6 segmentation */
+	NETIF_F_FSO_BIT,		/* ... FCoE segmentation */
+	NETIF_F_GSO_RESERVED1,		/* ... free (fill GSO_MASK to 8 bits) */
+	/**/NETIF_F_GSO_LAST,		/* [can't be last bit, see GSO_MASK] */
+	NETIF_F_GSO_RESERVED2		/* ... free (fill GSO_MASK to 8 bits) */
+		= NETIF_F_GSO_LAST,
 
-	/* Segmentation offload features */
-#define NETIF_F_GSO_SHIFT	16
-#define NETIF_F_GSO_MASK	0x00ff0000
-#define NETIF_F_TSO		(SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT)
-#define NETIF_F_UFO		(SKB_GSO_UDP << NETIF_F_GSO_SHIFT)
-#define NETIF_F_GSO_ROBUST	(SKB_GSO_DODGY << NETIF_F_GSO_SHIFT)
-#define NETIF_F_TSO_ECN		(SKB_GSO_TCP_ECN << NETIF_F_GSO_SHIFT)
-#define NETIF_F_TSO6		(SKB_GSO_TCPV6 << NETIF_F_GSO_SHIFT)
-#define NETIF_F_FSO		(SKB_GSO_FCOE << NETIF_F_GSO_SHIFT)
+	NETIF_F_FCOE_CRC_BIT,		/* FCoE CRC32 */
+	NETIF_F_SCTP_CSUM_BIT,		/* SCTP checksum offload */
+	NETIF_F_FCOE_MTU_BIT,		/* Supports max FCoE MTU, 2158 bytes*/
+	NETIF_F_NTUPLE_BIT,		/* N-tuple filters supported */
+	NETIF_F_RXHASH_BIT,		/* Receive hashing offload */
+	NETIF_F_RXCSUM_BIT,		/* Receive checksumming offload */
+	NETIF_F_NOCACHE_COPY_BIT,	/* Use no-cache copyfromuser */
+	NETIF_F_LOOPBACK_BIT,		/* Enable loopback */
+
+	/*
+	 * Add your fresh new feature above and remember to update
+	 * netdev_features_strings[] in net/core/ethtool.c and maybe
+	 * some feature mask #defines below.
+	 */
+
+	/**/NETDEV_FEATURE_COUNT
+};
+
+/* copy'n'paste compression ;) */
+#define __NETIF_F_BIT(bit)	((netdev_features_t)1 << (bit))
+#define __NETIF_F(name)		__NETIF_F_BIT(NETIF_F_##name##_BIT)
+
+#define NETIF_F_SG		__NETIF_F(SG)
+#define NETIF_F_IP_CSUM		__NETIF_F(IP_CSUM)
+#define NETIF_F_NO_CSUM		__NETIF_F(NO_CSUM)
+#define NETIF_F_HW_CSUM		__NETIF_F(HW_CSUM)
+#define NETIF_F_IPV6_CSUM	__NETIF_F(IPV6_CSUM)
+#define NETIF_F_HIGHDMA		__NETIF_F(HIGHDMA)
+#define NETIF_F_FRAGLIST	__NETIF_F(FRAGLIST)
+#define NETIF_F_HW_VLAN_TX	__NETIF_F(HW_VLAN_TX)
+#define NETIF_F_HW_VLAN_RX	__NETIF_F(HW_VLAN_RX)
+#define NETIF_F_HW_VLAN_FILTER	__NETIF_F(HW_VLAN_FILTER)
+#define NETIF_F_VLAN_CHALLENGED	__NETIF_F(VLAN_CHALLENGED)
+#define NETIF_F_GSO		__NETIF_F(GSO)
+#define NETIF_F_LLTX		__NETIF_F(LLTX)
+#define NETIF_F_NETNS_LOCAL	__NETIF_F(NETNS_LOCAL)
+#define NETIF_F_GRO		__NETIF_F(GRO)
+#define NETIF_F_LRO		__NETIF_F(LRO)
+#define NETIF_F_TSO		__NETIF_F(TSO)
+#define NETIF_F_UFO		__NETIF_F(UFO)
+#define NETIF_F_GSO_ROBUST	__NETIF_F(GSO_ROBUST)
+#define NETIF_F_TSO_ECN		__NETIF_F(TSO_ECN)
+#define NETIF_F_TSO6		__NETIF_F(TSO6)
+#define NETIF_F_FSO		__NETIF_F(FSO)
+#define NETIF_F_FCOE_CRC	__NETIF_F(FCOE_CRC)
+#define NETIF_F_SCTP_CSUM	__NETIF_F(SCTP_CSUM)
+#define NETIF_F_FCOE_MTU	__NETIF_F(FCOE_MTU)
+#define NETIF_F_NTUPLE		__NETIF_F(NTUPLE)
+#define NETIF_F_RXHASH		__NETIF_F(RXHASH)
+#define NETIF_F_RXCSUM		__NETIF_F(RXCSUM)
+#define NETIF_F_NOCACHE_COPY	__NETIF_F(NOCACHE_COPY)
+#define NETIF_F_LOOPBACK	__NETIF_F(LOOPBACK)
 
 	/* Features valid for ethtool to change */
 	/* = all defined minus driver/device-class-related */
 #define NETIF_F_NEVER_CHANGE	(NETIF_F_VLAN_CHALLENGED | \
 				  NETIF_F_LLTX | NETIF_F_NETNS_LOCAL)
-#define NETIF_F_ETHTOOL_BITS	(0xff3fffff & ~NETIF_F_NEVER_CHANGE)
+	/* remember that ((t)1 << t_BITS) is undefined in C99 */
+#define NETIF_F_ETHTOOL_BITS	((__NETIF_F_BIT(NETDEV_FEATURE_COUNT - 1) | \
+		(__NETIF_F_BIT(NETDEV_FEATURE_COUNT - 1) - 1)) & \
+		~NETIF_F_NEVER_CHANGE)
+
+	/* Segmentation offload feature mask */
+#define NETIF_F_GSO_MASK	(__NETIF_F_BIT(NETIF_F_GSO_LAST + 1) - \
+		__NETIF_F_BIT(NETIF_F_GSO_SHIFT))
 
 	/* List of features with software fallbacks. */
 #define NETIF_F_GSO_SOFTWARE	(NETIF_F_TSO | NETIF_F_TSO_ECN | \
 				 NETIF_F_TSO6 | NETIF_F_UFO)
 
-
 #define NETIF_F_GEN_CSUM	(NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)
 #define NETIF_F_V4_CSUM		(NETIF_F_GEN_CSUM | NETIF_F_IP_CSUM)
 #define NETIF_F_V6_CSUM		(NETIF_F_GEN_CSUM | NETIF_F_IPV6_CSUM)
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [RFT PATCH 4/9] net: introduce and use netdev_features_t for device features sets
  2011-06-20 19:14 [RFT PATCH 0/9] Cleanup and extension of netdev features Michał Mirosław
                   ` (2 preceding siblings ...)
  2011-06-20 19:14 ` [RFT PATCH 2/9] net: remove legacy ethtool ops Michał Mirosław
@ 2011-06-20 19:14 ` Michał Mirosław
  2011-06-20 21:01   ` Ben Hutchings
  2011-06-20 19:14 ` [RFT PATCH 8/9] net: extend netdev_features_t to 64 bits Michał Mirosław
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 28+ messages in thread
From: Michał Mirosław @ 2011-06-20 19:14 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Ben Hutchings

The type and bits definitions are moved to separate header so that
linux/skbuff.h won't need to include linux/netdevice.h.

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 drivers/net/8139cp.c                  |    2 +-
 drivers/net/bnx2.c                    |    6 +-
 drivers/net/bnx2x/bnx2x_cmn.c         |    5 +-
 drivers/net/bnx2x/bnx2x_cmn.h         |    5 +-
 drivers/net/bonding/bond_main.c       |    9 ++-
 drivers/net/cxgb4/cxgb4_main.c        |   12 ++--
 drivers/net/dm9000.c                  |    3 +-
 drivers/net/e1000/e1000_main.c        |    5 +-
 drivers/net/forcedeth.c               |    7 +-
 drivers/net/gianfar.h                 |    2 +-
 drivers/net/gianfar_ethtool.c         |    4 +-
 drivers/net/ibmveth.c                 |    6 +-
 drivers/net/ixgbe/ixgbe_ethtool.c     |    7 +-
 drivers/net/ixgbe/ixgbe_main.c        |    5 +-
 drivers/net/jme.c                     |    8 +-
 drivers/net/ksz884x.c                 |    3 +-
 drivers/net/mv643xx_eth.c             |    2 +-
 drivers/net/myri10ge/myri10ge.c       |    2 +-
 drivers/net/netxen/netxen_nic_main.c  |    6 +-
 drivers/net/pch_gbe/pch_gbe_main.c    |    5 +-
 drivers/net/qlcnic/qlcnic.h           |    5 +-
 drivers/net/qlcnic/qlcnic_hw.c        |    9 ++-
 drivers/net/qlcnic/qlcnic_main.c      |    2 +-
 drivers/net/r8169.c                   |    6 +-
 drivers/net/s2io.c                    |    4 +-
 drivers/net/sfc/efx.c                 |    2 +-
 drivers/net/sky2.c                    |    5 +-
 drivers/net/tg3.c                     |    7 +-
 drivers/net/usb/smsc75xx.c            |    3 +-
 drivers/net/usb/smsc95xx.c            |    3 +-
 drivers/net/vmxnet3/vmxnet3_ethtool.c |    4 +-
 drivers/net/vmxnet3/vmxnet3_int.h     |    2 +-
 drivers/net/vxge/vxge-main.c          |    9 ++-
 drivers/net/xen-netfront.c            |    8 ++-
 drivers/s390/net/qeth_l3_main.c       |    6 +-
 include/linux/netdev_features.h       |   98 ++++++++++++++++++++++++++
 include/linux/netdevice.h             |  125 ++++++---------------------------
 include/linux/skbuff.h                |    4 +-
 include/net/protocol.h                |    4 +-
 include/net/tcp.h                     |    3 +-
 include/net/udp.h                     |    3 +-
 net/8021q/vlan_dev.c                  |    3 +-
 net/bridge/br_if.c                    |    5 +-
 net/core/dev.c                        |   34 +++++----
 net/core/ethtool.c                    |    9 +--
 net/core/net-sysfs.c                  |    2 +-
 net/core/skbuff.c                     |    2 +-
 net/ipv4/af_inet.c                    |    3 +-
 net/ipv4/tcp.c                        |    2 +-
 net/ipv4/udp.c                        |    3 +-
 net/ipv6/af_inet6.c                   |    3 +-
 net/ipv6/udp.c                        |    2 +-
 52 files changed, 271 insertions(+), 213 deletions(-)

diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index 73b10b0..a14bdf4 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -1416,7 +1416,7 @@ static void cp_set_msglevel(struct net_device *dev, u32 value)
 	cp->msg_enable = value;
 }
 
-static int cp_set_features(struct net_device *dev, u32 features)
+static int cp_set_features(struct net_device *dev, netdev_features_t features)
 {
 	struct cp_private *cp = netdev_priv(dev);
 	unsigned long flags;
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 74580bb..35f0c8a 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -7502,8 +7502,8 @@ bnx2_set_phys_id(struct net_device *dev, enum ethtool_phys_id_state state)
 	return 0;
 }
 
-static u32
-bnx2_fix_features(struct net_device *dev, u32 features)
+static netdev_features_t
+bnx2_fix_features(struct net_device *dev, netdev_features_t features)
 {
 	struct bnx2 *bp = netdev_priv(dev);
 
@@ -7514,7 +7514,7 @@ bnx2_fix_features(struct net_device *dev, u32 features)
 }
 
 static int
-bnx2_set_features(struct net_device *dev, u32 features)
+bnx2_set_features(struct net_device *dev, netdev_features_t features)
 {
 	struct bnx2 *bp = netdev_priv(dev);
 
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c
index bb75560..c7da8ac 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/bnx2x/bnx2x_cmn.c
@@ -3177,7 +3177,8 @@ int bnx2x_change_mtu(struct net_device *dev, int new_mtu)
 	return bnx2x_reload_if_running(dev);
 }
 
-u32 bnx2x_fix_features(struct net_device *dev, u32 features)
+netdev_features_t bnx2x_fix_features(struct net_device *dev,
+	netdev_features_t features)
 {
 	struct bnx2x *bp = netdev_priv(dev);
 
@@ -3188,7 +3189,7 @@ u32 bnx2x_fix_features(struct net_device *dev, u32 features)
 	return features;
 }
 
-int bnx2x_set_features(struct net_device *dev, u32 features)
+int bnx2x_set_features(struct net_device *dev, netdev_features_t features)
 {
 	struct bnx2x *bp = netdev_priv(dev);
 	u32 flags = bp->flags;
diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h
index c016e20..33095fb 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/bnx2x/bnx2x_cmn.h
@@ -519,8 +519,9 @@ void bnx2x_free_mem_bp(struct bnx2x *bp);
  */
 int bnx2x_change_mtu(struct net_device *dev, int new_mtu);
 
-u32 bnx2x_fix_features(struct net_device *dev, u32 features);
-int bnx2x_set_features(struct net_device *dev, u32 features);
+netdev_features_t bnx2x_fix_features(struct net_device *dev,
+	netdev_features_t features);
+int bnx2x_set_features(struct net_device *dev, netdev_features_t features);
 
 /**
  * bnx2x_tx_timeout - tx timeout netdev callback
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 07e866d..f99c8b2 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1375,11 +1375,12 @@ static int bond_sethwaddr(struct net_device *bond_dev,
 	return 0;
 }
 
-static u32 bond_fix_features(struct net_device *dev, u32 features)
+static netdev_features_t bond_fix_features(struct net_device *dev,
+	netdev_features_t features)
 {
 	struct slave *slave;
 	struct bonding *bond = netdev_priv(dev);
-	u32 mask;
+	netdev_features_t mask;
 	int i;
 
 	read_lock(&bond->lock);
@@ -1413,7 +1414,7 @@ static void bond_compute_features(struct bonding *bond)
 {
 	struct slave *slave;
 	struct net_device *bond_dev = bond->dev;
-	u32 vlan_features = BOND_VLAN_FEATURES;
+	netdev_features_t vlan_features = BOND_VLAN_FEATURES;
 	unsigned short max_hard_header_len = ETH_HLEN;
 	int i;
 
@@ -1951,7 +1952,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
 	struct bonding *bond = netdev_priv(bond_dev);
 	struct slave *slave, *oldcurrent;
 	struct sockaddr addr;
-	u32 old_features = bond_dev->features;
+	netdev_features_t old_features = bond_dev->features;
 
 	/* slave is not a slave or master is not master of this slave */
 	if (!(slave_dev->flags & IFF_SLAVE) ||
diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c
index c9957b7..255f9f0 100644
--- a/drivers/net/cxgb4/cxgb4_main.c
+++ b/drivers/net/cxgb4/cxgb4_main.c
@@ -1854,10 +1854,10 @@ static int set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 	return err;
 }
 
-static int cxgb_set_features(struct net_device *dev, u32 features)
+static int cxgb_set_features(struct net_device *dev, netdev_features_t features)
 {
 	const struct port_info *pi = netdev_priv(dev);
-	u32 changed = dev->features ^ features;
+	netdev_features_t changed = dev->features ^ features;
 	int err;
 
 	if (!(changed & NETIF_F_HW_VLAN_RX))
@@ -3536,7 +3536,7 @@ static int __devinit init_one(struct pci_dev *pdev,
 {
 	int func, i, err;
 	struct port_info *pi;
-	unsigned int highdma = 0;
+	bool highdma = false;
 	struct adapter *adapter = NULL;
 
 	printk_once(KERN_INFO "%s - version %s\n", DRV_DESC, DRV_VERSION);
@@ -3562,7 +3562,7 @@ static int __devinit init_one(struct pci_dev *pdev,
 	}
 
 	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
-		highdma = NETIF_F_HIGHDMA;
+		highdma = true;
 		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
 		if (err) {
 			dev_err(&pdev->dev, "unable to obtain 64-bit DMA for "
@@ -3636,7 +3636,9 @@ static int __devinit init_one(struct pci_dev *pdev,
 			NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
 			NETIF_F_RXCSUM | NETIF_F_RXHASH |
 			NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-		netdev->features |= netdev->hw_features | highdma;
+		if (highdma)
+			netdev->hw_features |= NETIF_F_HIGHDMA;
+		netdev->features |= netdev->hw_features;
 		netdev->vlan_features = netdev->features & VLAN_FEAT;
 
 		netdev->netdev_ops = &cxgb4_netdev_ops;
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 8ef31dc..45bcefc 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -469,7 +469,8 @@ static int dm9000_nway_reset(struct net_device *dev)
 	return mii_nway_restart(&dm->mii);
 }
 
-static int dm9000_set_features(struct net_device *dev, u32 features)
+static int dm9000_set_features(struct net_device *dev,
+	netdev_features_t features)
 {
 	board_info_t *dm = to_dm9000_board(dev);
 	u32 changed = dev->features ^ features;
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 188d99a..fab2ef6 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -797,10 +797,11 @@ static int e1000_is_need_ioport(struct pci_dev *pdev)
 	}
 }
 
-static int e1000_set_features(struct net_device *netdev, u32 features)
+static int e1000_set_features(struct net_device *netdev,
+	netdev_features_t features)
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
-	u32 changed = features ^ netdev->features;
+	netdev_features_t changed = features ^ netdev->features;
 
 	if (!(changed & NETIF_F_RXCSUM))
 		return 0;
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 537b695..c542766 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -4475,7 +4475,8 @@ static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam*
 	return 0;
 }
 
-static u32 nv_fix_features(struct net_device *dev, u32 features)
+static netdev_features_t nv_fix_features(struct net_device *dev,
+	netdev_features_t features)
 {
 	/* vlan is dependent on rx checksum offload */
 	if (features & (NETIF_F_HW_VLAN_TX|NETIF_F_HW_VLAN_RX))
@@ -4484,11 +4485,11 @@ static u32 nv_fix_features(struct net_device *dev, u32 features)
 	return features;
 }
 
-static int nv_set_features(struct net_device *dev, u32 features)
+static int nv_set_features(struct net_device *dev, netdev_features_t features)
 {
 	struct fe_priv *np = netdev_priv(dev);
 	u8 __iomem *base = get_hwbase(dev);
-	u32 changed = dev->features ^ features;
+	netdev_features_t changed = dev->features ^ features;
 
 	if (changed & NETIF_F_RXCSUM) {
 		spin_lock_irq(&np->lock);
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index fc86f51..3b980a2 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -1153,7 +1153,7 @@ extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev,
 extern void gfar_configure_coalescing(struct gfar_private *priv,
 		unsigned long tx_mask, unsigned long rx_mask);
 void gfar_init_sysfs(struct net_device *dev);
-int gfar_set_features(struct net_device *dev, u32 features);
+int gfar_set_features(struct net_device *dev, netdev_features_t features);
 
 extern const struct ethtool_ops gfar_ethtool_ops;
 
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
index 92d7ac0..4176b90 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -517,12 +517,12 @@ static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rva
 	return err;
 }
 
-int gfar_set_features(struct net_device *dev, u32 features)
+int gfar_set_features(struct net_device *dev, netdev_features_t features)
 {
 	struct gfar_private *priv = netdev_priv(dev);
 	unsigned long flags;
 	int err = 0, i = 0;
-	u32 changed = dev->features ^ features;
+	netdev_features_t changed = dev->features ^ features;
 
 	if (!(changed & NETIF_F_RXCSUM))
 		return 0;
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 838c5b6..06514bc 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -730,7 +730,8 @@ static void netdev_get_drvinfo(struct net_device *dev,
 		sizeof(info->version) - 1);
 }
 
-static u32 ibmveth_fix_features(struct net_device *dev, u32 features)
+static netdev_features_t ibmveth_fix_features(struct net_device *dev,
+	netdev_features_t features)
 {
 	/*
 	 * Since the ibmveth firmware interface does not have the
@@ -824,7 +825,8 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data)
 	return rc1 ? rc1 : rc2;
 }
 
-static int ibmveth_set_features(struct net_device *dev, u32 features)
+static int ibmveth_set_features(struct net_device *dev,
+	netdev_features_t features)
 {
 	struct ibmveth_adapter *adapter = netdev_priv(dev);
 	int rx_csum = !!(features & NETIF_F_RXCSUM);
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 38ee164..438c5b8 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -2188,7 +2188,8 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
 	return 0;
 }
 
-u32 ixgbe_fix_features(struct net_device *netdev, u32 features)
+netdev_features_t ixgbe_fix_features(struct net_device *netdev,
+	netdev_features_t features)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 
@@ -2211,10 +2212,10 @@ u32 ixgbe_fix_features(struct net_device *netdev, u32 features)
 	return features;
 }
 
-int ixgbe_set_features(struct net_device *netdev, u32 features)
+int ixgbe_set_features(struct net_device *netdev, netdev_features_t features)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
-	u32 changed = netdev->features ^ features;
+	netdev_features_t changed = netdev->features ^ features;
 	bool need_reset = !!(changed & NETIF_F_HW_VLAN_RX);
 
 	if (features & NETIF_F_RXCSUM)
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 1a77310..c720710 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -7199,8 +7199,9 @@ static struct rtnl_link_stats64 *ixgbe_get_stats64(struct net_device *netdev,
 	return stats;
 }
 
-u32 ixgbe_fix_features(struct net_device *netdev, u32 features);
-int ixgbe_set_features(struct net_device *netdev, u32 features);
+netdev_features_t ixgbe_fix_features(struct net_device *netdev,
+	netdev_features_t features);
+int ixgbe_set_features(struct net_device *netdev, netdev_features_t features);
 
 static const struct net_device_ops ixgbe_netdev_ops = {
 	.ndo_open		= ixgbe_open,
diff --git a/drivers/net/jme.c b/drivers/net/jme.c
index b5b174a..44f230a 100644
--- a/drivers/net/jme.c
+++ b/drivers/net/jme.c
@@ -1917,7 +1917,7 @@ jme_map_tx_skb(struct jme_adapter *jme, struct sk_buff *skb, int idx)
 	struct jme_ring *txring = &(jme->txring[0]);
 	struct txdesc *txdesc = txring->desc, *ctxdesc;
 	struct jme_buffer_info *txbi = txring->bufinf, *ctxbi;
-	u8 hidma = jme->dev->features & NETIF_F_HIGHDMA;
+	u8 hidma = !!(jme->dev->features & NETIF_F_HIGHDMA);
 	int i, nr_frags = skb_shinfo(skb)->nr_frags;
 	int mask = jme->tx_ring_mask;
 	struct skb_frag_struct *frag;
@@ -2632,8 +2632,8 @@ jme_set_msglevel(struct net_device *netdev, u32 value)
 	jme->msg_enable = value;
 }
 
-static u32
-jme_fix_features(struct net_device *netdev, u32 features)
+static netdev_features_t
+jme_fix_features(struct net_device *netdev, netdev_features_t features)
 {
 	if (netdev->mtu > 1900)
 		features &= ~(NETIF_F_ALL_TSO | NETIF_F_ALL_CSUM);
@@ -2641,7 +2641,7 @@ jme_fix_features(struct net_device *netdev, u32 features)
 }
 
 static int
-jme_set_features(struct net_device *netdev, u32 features)
+jme_set_features(struct net_device *netdev, netdev_features_t features)
 {
 	struct jme_adapter *jme = netdev_priv(netdev);
 
diff --git a/drivers/net/ksz884x.c b/drivers/net/ksz884x.c
index 2ac6c6c..9e2f8c9 100644
--- a/drivers/net/ksz884x.c
+++ b/drivers/net/ksz884x.c
@@ -6590,7 +6590,8 @@ static void netdev_get_ethtool_stats(struct net_device *dev,
  *
  * Return 0 if successful; otherwise an error code.
  */
-static int netdev_set_features(struct net_device *dev, u32 features)
+static int netdev_set_features(struct net_device *dev,
+	netdev_features_t features)
 {
 	struct dev_priv *priv = netdev_priv(dev);
 	struct dev_info *hw_priv = priv->adapter;
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index a5d9b1c..39ba830 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -1577,7 +1577,7 @@ mv643xx_eth_set_ringparam(struct net_device *dev, struct ethtool_ringparam *er)
 
 
 static int
-mv643xx_eth_set_features(struct net_device *dev, u32 features)
+mv643xx_eth_set_features(struct net_device *dev, netdev_features_t features)
 {
 	struct mv643xx_eth_private *mp = netdev_priv(dev);
 	u32 rx_csum = features & NETIF_F_RXCSUM;
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 04e10f4..6d0be83 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -1489,7 +1489,7 @@ myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget)
 	 * access to avoid theoretical race condition with functions that
 	 * change NETIF_F_LRO flag at runtime.
 	 */
-	bool lro_enabled = ACCESS_ONCE(mgp->dev->features) & NETIF_F_LRO;
+	bool lro_enabled = !!(ACCESS_ONCE(mgp->dev->features) & NETIF_F_LRO);
 
 	while (rx_done->entry[idx].length != 0 && work_done < budget) {
 		length = ntohs(rx_done->entry[idx].length);
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 684cace..75c4405 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -486,7 +486,8 @@ static void netxen_set_multicast_list(struct net_device *dev)
 	adapter->set_multi(dev);
 }
 
-static u32 netxen_fix_features(struct net_device *dev, u32 features)
+static netdev_features_t netxen_fix_features(struct net_device *dev,
+	netdev_features_t features)
 {
 	if (!(features & NETIF_F_RXCSUM)) {
 		netdev_info(dev, "disabling LRO as RXCSUM is off\n");
@@ -497,7 +498,8 @@ static u32 netxen_fix_features(struct net_device *dev, u32 features)
 	return features;
 }
 
-static int netxen_set_features(struct net_device *dev, u32 features)
+static int netxen_set_features(struct net_device *dev,
+	netdev_features_t features)
 {
 	struct netxen_adapter *adapter = netdev_priv(dev);
 	int hw_lro;
diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c
index eac3c5c..3684281 100644
--- a/drivers/net/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/pch_gbe/pch_gbe_main.c
@@ -2040,10 +2040,11 @@ static int pch_gbe_change_mtu(struct net_device *netdev, int new_mtu)
  * Returns
  *	0:		HW state updated successfully
  */
-static int pch_gbe_set_features(struct net_device *netdev, u32 features)
+static int pch_gbe_set_features(struct net_device *netdev,
+	netdev_features_t features)
 {
 	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
-	u32 changed = features ^ netdev->features;
+	netdev_features_t changed = features ^ netdev->features;
 
 	if (!(changed & NETIF_F_RXCSUM))
 		return 0;
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 480ef5c..49ed30d 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -1420,8 +1420,9 @@ void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, int linkup);
 
 int qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu);
 int qlcnic_change_mtu(struct net_device *netdev, int new_mtu);
-u32 qlcnic_fix_features(struct net_device *netdev, u32 features);
-int qlcnic_set_features(struct net_device *netdev, u32 features);
+netdev_features_t qlcnic_fix_features(struct net_device *netdev,
+	netdev_features_t features);
+int qlcnic_set_features(struct net_device *netdev, netdev_features_t features);
 int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable);
 int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable);
 int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter);
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c
index e965661..d0cc78e 100644
--- a/drivers/net/qlcnic/qlcnic_hw.c
+++ b/drivers/net/qlcnic/qlcnic_hw.c
@@ -760,12 +760,13 @@ int qlcnic_change_mtu(struct net_device *netdev, int mtu)
 }
 
 
-u32 qlcnic_fix_features(struct net_device *netdev, u32 features)
+netdev_features_t qlcnic_fix_features(struct net_device *netdev,
+	netdev_features_t features)
 {
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 
 	if ((adapter->flags & QLCNIC_ESWITCH_ENABLED)) {
-		u32 changed = features ^ netdev->features;
+		netdev_features_t changed = features ^ netdev->features;
 		features ^= changed & (NETIF_F_ALL_CSUM | NETIF_F_RXCSUM);
 	}
 
@@ -776,10 +777,10 @@ u32 qlcnic_fix_features(struct net_device *netdev, u32 features)
 }
 
 
-int qlcnic_set_features(struct net_device *netdev, u32 features)
+int qlcnic_set_features(struct net_device *netdev, netdev_features_t features)
 {
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
-	u32 changed = netdev->features ^ features;
+	netdev_features_t changed = netdev->features ^ features;
 	int hw_lro = (features & NETIF_F_LRO) ? QLCNIC_LRO_ENABLED : 0;
 
 	if (!(changed & NETIF_F_LRO))
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 3ab7d2c..979bca3 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -781,7 +781,7 @@ qlcnic_set_netdev_features(struct qlcnic_adapter *adapter,
 		struct qlcnic_esw_func_cfg *esw_cfg)
 {
 	struct net_device *netdev = adapter->netdev;
-	unsigned long features, vlan_features;
+	netdev_features_t features, vlan_features;
 
 	features = (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
 			NETIF_F_IPV6_CSUM | NETIF_F_GRO);
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index bc5bb37..78184ac 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1384,7 +1384,8 @@ static int rtl8169_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	return ret;
 }
 
-static u32 rtl8169_fix_features(struct net_device *dev, u32 features)
+static netdev_features_t rtl8169_fix_features(struct net_device *dev,
+	netdev_features_t features)
 {
 	if (dev->mtu > TD_MSS_MAX)
 		features &= ~NETIF_F_ALL_TSO;
@@ -1392,7 +1393,8 @@ static u32 rtl8169_fix_features(struct net_device *dev, u32 features)
 	return features;
 }
 
-static int rtl8169_set_features(struct net_device *dev, u32 features)
+static int rtl8169_set_features(struct net_device *dev,
+	netdev_features_t features)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
 	void __iomem *ioaddr = tp->mmio_addr;
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index df0d2c8..698fbfa 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -6670,10 +6670,10 @@ static void s2io_ethtool_get_strings(struct net_device *dev,
 	}
 }
 
-static int s2io_set_features(struct net_device *dev, u32 features)
+static int s2io_set_features(struct net_device *dev, netdev_features_t features)
 {
 	struct s2io_nic *sp = netdev_priv(dev);
-	u32 changed = (features ^ dev->features) & NETIF_F_LRO;
+	netdev_features_t changed = (features ^ dev->features) & NETIF_F_LRO;
 
 	if (changed && netif_running(dev)) {
 		int rc;
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index c914729..ca869c0 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -1883,7 +1883,7 @@ static void efx_set_multicast_list(struct net_device *net_dev)
 	/* Otherwise efx_start_port() will do this */
 }
 
-static int efx_set_features(struct net_device *net_dev, u32 data)
+static int efx_set_features(struct net_device *net_dev, netdev_features_t data)
 {
 	struct efx_nic *efx = netdev_priv(net_dev);
 
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index d252cb1..6068f49 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -4168,7 +4168,8 @@ static int sky2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom
 	return sky2_vpd_write(sky2->hw, cap, data, eeprom->offset, eeprom->len);
 }
 
-static u32 sky2_fix_features(struct net_device *dev, u32 features)
+static netdev_features_t sky2_fix_features(struct net_device *dev,
+	netdev_features_t features)
 {
 	const struct sky2_port *sky2 = netdev_priv(dev);
 	const struct sky2_hw *hw = sky2->hw;
@@ -4182,7 +4183,7 @@ static u32 sky2_fix_features(struct net_device *dev, u32 features)
 	return features;
 }
 
-static int sky2_set_features(struct net_device *dev, u32 features)
+static int sky2_set_features(struct net_device *dev, netdev_features_t features)
 {
 	struct sky2_port *sky2 = netdev_priv(dev);
 	u32 changed = dev->features ^ features;
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 97cd02d..67692b5 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -6186,7 +6186,8 @@ static void tg3_set_loopback(struct net_device *dev, u32 features)
 	}
 }
 
-static u32 tg3_fix_features(struct net_device *dev, u32 features)
+static netdev_features_t tg3_fix_features(struct net_device *dev,
+	netdev_features_t features)
 {
 	struct tg3 *tp = netdev_priv(dev);
 
@@ -6196,9 +6197,9 @@ static u32 tg3_fix_features(struct net_device *dev, u32 features)
 	return features;
 }
 
-static int tg3_set_features(struct net_device *dev, u32 features)
+static int tg3_set_features(struct net_device *dev, netdev_features_t features)
 {
-	u32 changed = dev->features ^ features;
+	netdev_features_t changed = dev->features ^ features;
 
 	if ((changed & NETIF_F_LOOPBACK) && netif_running(dev))
 		tg3_set_loopback(dev, features);
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c
index 15b3d68..f59b51f 100644
--- a/drivers/net/usb/smsc75xx.c
+++ b/drivers/net/usb/smsc75xx.c
@@ -727,7 +727,8 @@ static int smsc75xx_change_mtu(struct net_device *netdev, int new_mtu)
 }
 
 /* Enable or disable Rx checksum offload engine */
-static int smsc75xx_set_features(struct net_device *netdev, u32 features)
+static int smsc75xx_set_features(struct net_device *netdev,
+	netdev_features_t features)
 {
 	struct usbnet *dev = netdev_priv(netdev);
 	struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index f74f3ce..071a5cf 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -516,7 +516,8 @@ static void smsc95xx_status(struct usbnet *dev, struct urb *urb)
 }
 
 /* Enable or disable Tx & Rx checksum offload engines */
-static int smsc95xx_set_features(struct net_device *netdev, u32 features)
+static int smsc95xx_set_features(struct net_device *netdev,
+	netdev_features_t features)
 {
 	struct usbnet *dev = netdev_priv(netdev);
 	u32 read_buf;
diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c
index bba7c15..704c527 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethtool.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c
@@ -262,11 +262,11 @@ vmxnet3_get_strings(struct net_device *netdev, u32 stringset, u8 *buf)
 	}
 }
 
-int vmxnet3_set_features(struct net_device *netdev, u32 features)
+int vmxnet3_set_features(struct net_device *netdev, netdev_features_t features)
 {
 	struct vmxnet3_adapter *adapter = netdev_priv(netdev);
 	unsigned long flags;
-	u32 changed = features ^ netdev->features;
+	netdev_features_t changed = features ^ netdev->features;
 
 	if (changed & (NETIF_F_RXCSUM|NETIF_F_LRO)) {
 		if (features & NETIF_F_RXCSUM)
diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h
index 0e567c24..35e2b9b 100644
--- a/drivers/net/vmxnet3/vmxnet3_int.h
+++ b/drivers/net/vmxnet3/vmxnet3_int.h
@@ -399,7 +399,7 @@ void
 vmxnet3_rq_destroy_all(struct vmxnet3_adapter *adapter);
 
 int
-vmxnet3_set_features(struct net_device *netdev, u32 features);
+vmxnet3_set_features(struct net_device *netdev, netdev_features_t features);
 
 int
 vmxnet3_create_queues(struct vmxnet3_adapter *adapter,
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
index e658edd..7d3040c 100644
--- a/drivers/net/vxge/vxge-main.c
+++ b/drivers/net/vxge/vxge-main.c
@@ -2662,9 +2662,10 @@ static void vxge_poll_vp_lockup(unsigned long data)
 	mod_timer(&vdev->vp_lockup_timer, jiffies + HZ / 1000);
 }
 
-static u32 vxge_fix_features(struct net_device *dev, u32 features)
+static netdev_features_t vxge_fix_features(struct net_device *dev,
+	netdev_features_t features)
 {
-	u32 changed = dev->features ^ features;
+	netdev_features_t changed = dev->features ^ features;
 
 	/* Enabling RTH requires some of the logic in vxge_device_register and a
 	 * vpath reset.  Due to these restrictions, only allow modification
@@ -2676,10 +2677,10 @@ static u32 vxge_fix_features(struct net_device *dev, u32 features)
 	return features;
 }
 
-static int vxge_set_features(struct net_device *dev, u32 features)
+static int vxge_set_features(struct net_device *dev, netdev_features_t features)
 {
 	struct vxgedev *vdev = netdev_priv(dev);
-	u32 changed = dev->features ^ features;
+	netdev_features_t changed = dev->features ^ features;
 
 	if (!(changed & NETIF_F_RXHASH))
 		return 0;
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index d29365a..bfb5cf9 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -193,7 +193,7 @@ static void xennet_sysfs_delif(struct net_device *netdev);
 
 static int xennet_can_sg(struct net_device *dev)
 {
-	return dev->features & NETIF_F_SG;
+	return !!(dev->features & NETIF_F_SG);
 }
 
 
@@ -1140,7 +1140,8 @@ static void xennet_uninit(struct net_device *dev)
 	gnttab_free_grant_references(np->gref_rx_head);
 }
 
-static u32 xennet_fix_features(struct net_device *dev, u32 features)
+static netdev_features_t xennet_fix_features(struct net_device *dev,
+	netdev_features_t features)
 {
 	struct netfront_info *np = netdev_priv(dev);
 	int val;
@@ -1166,7 +1167,8 @@ static u32 xennet_fix_features(struct net_device *dev, u32 features)
 	return features;
 }
 
-static int xennet_set_features(struct net_device *dev, u32 features)
+static int xennet_set_features(struct net_device *dev,
+	netdev_features_t features)
 {
 	if (!(features & NETIF_F_SG) && dev->mtu > ETH_DATA_LEN) {
 		netdev_info(dev, "Reducing MTU because no SG offload");
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index fd69da3..3225a4d 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -3148,7 +3148,8 @@ static int qeth_l3_stop(struct net_device *dev)
 	return 0;
 }
 
-static u32 qeth_l3_fix_features(struct net_device *dev, u32 features)
+static netdev_features_t qeth_l3_fix_features(struct net_device *dev,
+	netdev_features_t features)
 {
 	struct qeth_card *card = dev->ml_priv;
 
@@ -3162,7 +3163,8 @@ static u32 qeth_l3_fix_features(struct net_device *dev, u32 features)
 	return features;
 }
 
-static int qeth_l3_set_features(struct net_device *dev, u32 features)
+static int qeth_l3_set_features(struct net_device *dev,
+	netdev_features_t features)
 {
 	struct qeth_card *card = dev->ml_priv;
 	u32 changed = dev->features ^ features;
diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
new file mode 100644
index 0000000..d36bdcd
--- /dev/null
+++ b/include/linux/netdev_features.h
@@ -0,0 +1,98 @@
+/*
+ * Network device features.
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _LINUX_NETDEV_FEATURES_H
+#define _LINUX_NETDEV_FEATURES_H
+
+#include <linux/types.h>
+
+typedef u32 netdev_features_t;
+
+#define NETIF_F_SG		1	/* Scatter/gather IO. */
+#define NETIF_F_IP_CSUM		2	/* Can checksum TCP/UDP over IPv4. */
+#define NETIF_F_NO_CSUM		4	/* Does not require checksum. F.e. loopack. */
+#define NETIF_F_HW_CSUM		8	/* Can checksum all the packets. */
+#define NETIF_F_IPV6_CSUM	16	/* Can checksum TCP/UDP over IPV6 */
+#define NETIF_F_HIGHDMA		32	/* Can DMA to high memory. */
+#define NETIF_F_FRAGLIST	64	/* Scatter/gather IO. */
+#define NETIF_F_HW_VLAN_TX	128	/* Transmit VLAN hw acceleration */
+#define NETIF_F_HW_VLAN_RX	256	/* Receive VLAN hw acceleration */
+#define NETIF_F_HW_VLAN_FILTER	512	/* Receive filtering on VLAN */
+#define NETIF_F_VLAN_CHALLENGED	1024	/* Device cannot handle VLAN packets */
+#define NETIF_F_GSO		2048	/* Enable software GSO. */
+#define NETIF_F_LLTX		4096	/* LockLess TX - deprecated. Please */
+					/* do not use LLTX in new drivers */
+#define NETIF_F_NETNS_LOCAL	8192	/* Does not change network namespaces */
+#define NETIF_F_GRO		16384	/* Generic receive offload */
+#define NETIF_F_LRO		32768	/* large receive offload */
+
+/* the GSO_MASK reserves bits 16 through 23 */
+#define NETIF_F_FCOE_CRC	(1 << 24) /* FCoE CRC32 */
+#define NETIF_F_SCTP_CSUM	(1 << 25) /* SCTP checksum offload */
+#define NETIF_F_FCOE_MTU	(1 << 26) /* Supports max FCoE MTU, 2158 bytes*/
+#define NETIF_F_NTUPLE		(1 << 27) /* N-tuple filters supported */
+#define NETIF_F_RXHASH		(1 << 28) /* Receive hashing offload */
+#define NETIF_F_RXCSUM		(1 << 29) /* Receive checksumming offload */
+#define NETIF_F_NOCACHE_COPY	(1 << 30) /* Use no-cache copyfromuser */
+#define NETIF_F_LOOPBACK	(1 << 31) /* Enable loopback */
+
+	/* Segmentation offload features */
+#define NETIF_F_GSO_SHIFT	16
+#define NETIF_F_GSO_MASK	0x00ff0000
+#define NETIF_F_TSO		(SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT)
+#define NETIF_F_UFO		(SKB_GSO_UDP << NETIF_F_GSO_SHIFT)
+#define NETIF_F_GSO_ROBUST	(SKB_GSO_DODGY << NETIF_F_GSO_SHIFT)
+#define NETIF_F_TSO_ECN		(SKB_GSO_TCP_ECN << NETIF_F_GSO_SHIFT)
+#define NETIF_F_TSO6		(SKB_GSO_TCPV6 << NETIF_F_GSO_SHIFT)
+#define NETIF_F_FSO		(SKB_GSO_FCOE << NETIF_F_GSO_SHIFT)
+
+	/* Features valid for ethtool to change */
+	/* = all defined minus driver/device-class-related */
+#define NETIF_F_NEVER_CHANGE	(NETIF_F_VLAN_CHALLENGED | \
+				  NETIF_F_LLTX | NETIF_F_NETNS_LOCAL)
+#define NETIF_F_ETHTOOL_BITS	(0xff3fffff & ~NETIF_F_NEVER_CHANGE)
+
+	/* List of features with software fallbacks. */
+#define NETIF_F_GSO_SOFTWARE	(NETIF_F_TSO | NETIF_F_TSO_ECN | \
+				 NETIF_F_TSO6 | NETIF_F_UFO)
+
+
+#define NETIF_F_GEN_CSUM	(NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)
+#define NETIF_F_V4_CSUM		(NETIF_F_GEN_CSUM | NETIF_F_IP_CSUM)
+#define NETIF_F_V6_CSUM		(NETIF_F_GEN_CSUM | NETIF_F_IPV6_CSUM)
+#define NETIF_F_ALL_CSUM	(NETIF_F_V4_CSUM | NETIF_F_V6_CSUM)
+
+#define NETIF_F_ALL_TSO 	(NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN)
+
+#define NETIF_F_ALL_FCOE	(NETIF_F_FCOE_CRC | NETIF_F_FCOE_MTU | \
+				 NETIF_F_FSO)
+
+#define NETIF_F_ALL_TX_OFFLOADS	(NETIF_F_ALL_CSUM | NETIF_F_SG | \
+				 NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \
+				 NETIF_F_HIGHDMA | \
+				 NETIF_F_SCTP_CSUM | \
+				 NETIF_F_ALL_FCOE)
+
+	/*
+	 * If one device supports one of these features, then enable them
+	 * for all in netdev_increment_features.
+	 */
+#define NETIF_F_ONE_FOR_ALL	(NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ROBUST | \
+				 NETIF_F_SG | NETIF_F_HIGHDMA |		\
+				 NETIF_F_FRAGLIST | NETIF_F_VLAN_CHALLENGED)
+	/*
+	 * If one device doesn't support one of these features, then disable it
+	 * for all in netdev_increment_features.
+	 */
+#define NETIF_F_ALL_FOR_ALL	(NETIF_F_NOCACHE_COPY | NETIF_F_FSO)
+
+	/* changeable features with no special hardware requirements */
+#define NETIF_F_SOFT_FEATURES	(NETIF_F_GSO | NETIF_F_GRO)
+
+#endif	/* _LINUX_NETDEV_FEATURES_H */
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 3482ee9..5e0e086 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -52,6 +52,8 @@
 #include <net/dcbnl.h>
 #endif
 
+#include <linux/netdev_features.h>
+
 struct vlan_group;
 struct netpoll_info;
 struct phy_device;
@@ -877,12 +879,12 @@ struct netdev_tc_txq {
  *	Called to release previously enslaved netdev.
  *
  *      Feature/offload setting functions.
- * u32 (*ndo_fix_features)(struct net_device *dev, u32 features);
+ * netdev_features_t (*ndo_fix_features)(struct net_device *dev, netdev_features_t features);
  *	Adjusts the requested feature flags according to device-specific
  *	constraints, and returns the resulting flags. Must not modify
  *	the device state.
  *
- * int (*ndo_set_features)(struct net_device *dev, u32 features);
+ * int (*ndo_set_features)(struct net_device *dev, netdev_features_t features);
  *	Called to update device configuration to new features. Passed
  *	feature set might be less than what was returned by ndo_fix_features()).
  *	Must return >0 or -errno if it changed dev->features itself.
@@ -974,10 +976,10 @@ struct net_device_ops {
 						 struct net_device *slave_dev);
 	int			(*ndo_del_slave)(struct net_device *dev,
 						 struct net_device *slave_dev);
-	u32			(*ndo_fix_features)(struct net_device *dev,
-						    u32 features);
+	netdev_features_t	(*ndo_fix_features)(struct net_device *dev,
+						    netdev_features_t features);
 	int			(*ndo_set_features)(struct net_device *dev,
-						    u32 features);
+						    netdev_features_t features);
 };
 
 /*
@@ -1027,97 +1029,13 @@ struct net_device {
 	struct list_head	unreg_list;
 
 	/* currently active device features */
-	u32			features;
+	netdev_features_t	features;
 	/* user-changeable features */
-	u32			hw_features;
+	netdev_features_t	hw_features;
 	/* user-requested features */
-	u32			wanted_features;
+	netdev_features_t	wanted_features;
 	/* mask of features inheritable by VLAN devices */
-	u32			vlan_features;
-
-	/* Net device feature bits; if you change something,
-	 * also update netdev_features_strings[] in ethtool.c */
-
-#define NETIF_F_SG		1	/* Scatter/gather IO. */
-#define NETIF_F_IP_CSUM		2	/* Can checksum TCP/UDP over IPv4. */
-#define NETIF_F_NO_CSUM		4	/* Does not require checksum. F.e. loopack. */
-#define NETIF_F_HW_CSUM		8	/* Can checksum all the packets. */
-#define NETIF_F_IPV6_CSUM	16	/* Can checksum TCP/UDP over IPV6 */
-#define NETIF_F_HIGHDMA		32	/* Can DMA to high memory. */
-#define NETIF_F_FRAGLIST	64	/* Scatter/gather IO. */
-#define NETIF_F_HW_VLAN_TX	128	/* Transmit VLAN hw acceleration */
-#define NETIF_F_HW_VLAN_RX	256	/* Receive VLAN hw acceleration */
-#define NETIF_F_HW_VLAN_FILTER	512	/* Receive filtering on VLAN */
-#define NETIF_F_VLAN_CHALLENGED	1024	/* Device cannot handle VLAN packets */
-#define NETIF_F_GSO		2048	/* Enable software GSO. */
-#define NETIF_F_LLTX		4096	/* LockLess TX - deprecated. Please */
-					/* do not use LLTX in new drivers */
-#define NETIF_F_NETNS_LOCAL	8192	/* Does not change network namespaces */
-#define NETIF_F_GRO		16384	/* Generic receive offload */
-#define NETIF_F_LRO		32768	/* large receive offload */
-
-/* the GSO_MASK reserves bits 16 through 23 */
-#define NETIF_F_FCOE_CRC	(1 << 24) /* FCoE CRC32 */
-#define NETIF_F_SCTP_CSUM	(1 << 25) /* SCTP checksum offload */
-#define NETIF_F_FCOE_MTU	(1 << 26) /* Supports max FCoE MTU, 2158 bytes*/
-#define NETIF_F_NTUPLE		(1 << 27) /* N-tuple filters supported */
-#define NETIF_F_RXHASH		(1 << 28) /* Receive hashing offload */
-#define NETIF_F_RXCSUM		(1 << 29) /* Receive checksumming offload */
-#define NETIF_F_NOCACHE_COPY	(1 << 30) /* Use no-cache copyfromuser */
-#define NETIF_F_LOOPBACK	(1 << 31) /* Enable loopback */
-
-	/* Segmentation offload features */
-#define NETIF_F_GSO_SHIFT	16
-#define NETIF_F_GSO_MASK	0x00ff0000
-#define NETIF_F_TSO		(SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT)
-#define NETIF_F_UFO		(SKB_GSO_UDP << NETIF_F_GSO_SHIFT)
-#define NETIF_F_GSO_ROBUST	(SKB_GSO_DODGY << NETIF_F_GSO_SHIFT)
-#define NETIF_F_TSO_ECN		(SKB_GSO_TCP_ECN << NETIF_F_GSO_SHIFT)
-#define NETIF_F_TSO6		(SKB_GSO_TCPV6 << NETIF_F_GSO_SHIFT)
-#define NETIF_F_FSO		(SKB_GSO_FCOE << NETIF_F_GSO_SHIFT)
-
-	/* Features valid for ethtool to change */
-	/* = all defined minus driver/device-class-related */
-#define NETIF_F_NEVER_CHANGE	(NETIF_F_VLAN_CHALLENGED | \
-				  NETIF_F_LLTX | NETIF_F_NETNS_LOCAL)
-#define NETIF_F_ETHTOOL_BITS	(0xff3fffff & ~NETIF_F_NEVER_CHANGE)
-
-	/* List of features with software fallbacks. */
-#define NETIF_F_GSO_SOFTWARE	(NETIF_F_TSO | NETIF_F_TSO_ECN | \
-				 NETIF_F_TSO6 | NETIF_F_UFO)
-
-
-#define NETIF_F_GEN_CSUM	(NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)
-#define NETIF_F_V4_CSUM		(NETIF_F_GEN_CSUM | NETIF_F_IP_CSUM)
-#define NETIF_F_V6_CSUM		(NETIF_F_GEN_CSUM | NETIF_F_IPV6_CSUM)
-#define NETIF_F_ALL_CSUM	(NETIF_F_V4_CSUM | NETIF_F_V6_CSUM)
-
-#define NETIF_F_ALL_TSO 	(NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN)
-
-#define NETIF_F_ALL_FCOE	(NETIF_F_FCOE_CRC | NETIF_F_FCOE_MTU | \
-				 NETIF_F_FSO)
-
-#define NETIF_F_ALL_TX_OFFLOADS	(NETIF_F_ALL_CSUM | NETIF_F_SG | \
-				 NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \
-				 NETIF_F_HIGHDMA | \
-				 NETIF_F_SCTP_CSUM | \
-				 NETIF_F_ALL_FCOE)
-
-	/*
-	 * If one device supports one of these features, then enable them
-	 * for all in netdev_increment_features.
-	 */
-#define NETIF_F_ONE_FOR_ALL	(NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ROBUST | \
-				 NETIF_F_SG | NETIF_F_HIGHDMA |		\
-				 NETIF_F_FRAGLIST | NETIF_F_VLAN_CHALLENGED)
-	/*
-	 * If one device doesn't support one of these features, then disable it
-	 * for all in netdev_increment_features.
-	 */
-#define NETIF_F_ALL_FOR_ALL	(NETIF_F_NOCACHE_COPY | NETIF_F_FSO)
-
-	/* changeable features with no special hardware requirements */
-#define NETIF_F_SOFT_FEATURES	(NETIF_F_GSO | NETIF_F_GRO)
+	netdev_features_t	vlan_features;
 
 	/* Interface index. Unique device identifier	*/
 	int			ifindex;
@@ -1551,7 +1469,7 @@ struct packet_type {
 					 struct packet_type *,
 					 struct net_device *);
 	struct sk_buff		*(*gso_segment)(struct sk_buff *skb,
-						u32 features);
+						netdev_features_t features);
 	int			(*gso_send_check)(struct sk_buff *skb);
 	struct sk_buff		**(*gro_receive)(struct sk_buff **head,
 					       struct sk_buff *skb);
@@ -2528,7 +2446,7 @@ extern int		netdev_set_master(struct net_device *dev, struct net_device *master)
 extern int netdev_set_bond_master(struct net_device *dev,
 				  struct net_device *master);
 extern int skb_checksum_help(struct sk_buff *skb);
-extern struct sk_buff *skb_gso_segment(struct sk_buff *skb, u32 features);
+extern struct sk_buff *skb_gso_segment(struct sk_buff *skb, netdev_features_t features);
 #ifdef CONFIG_BUG
 extern void netdev_rx_csum_fault(struct net_device *dev);
 #else
@@ -2555,12 +2473,12 @@ extern char *netdev_drivername(const struct net_device *dev, char *buffer, int l
 
 extern void linkwatch_run_queue(void);
 
-static inline u32 netdev_get_wanted_features(struct net_device *dev)
+static inline netdev_features_t netdev_get_wanted_features(struct net_device *dev)
 {
 	return (dev->features & ~dev->hw_features) | dev->wanted_features;
 }
-u32 netdev_increment_features(u32 all, u32 one, u32 mask);
-u32 netdev_fix_features(struct net_device *dev, u32 features);
+netdev_features_t netdev_increment_features(netdev_features_t all,
+	netdev_features_t one, netdev_features_t mask);
 int __netdev_update_features(struct net_device *dev);
 void netdev_update_features(struct net_device *dev);
 void netdev_change_features(struct net_device *dev);
@@ -2568,21 +2486,22 @@ void netdev_change_features(struct net_device *dev);
 void netif_stacked_transfer_operstate(const struct net_device *rootdev,
 					struct net_device *dev);
 
-u32 netif_skb_features(struct sk_buff *skb);
+netdev_features_t netif_skb_features(struct sk_buff *skb);
 
-static inline int net_gso_ok(u32 features, int gso_type)
+static inline int net_gso_ok(netdev_features_t features, int gso_type)
 {
-	int feature = gso_type << NETIF_F_GSO_SHIFT;
+	netdev_features_t feature = gso_type << NETIF_F_GSO_SHIFT;
 	return (features & feature) == feature;
 }
 
-static inline int skb_gso_ok(struct sk_buff *skb, u32 features)
+static inline int skb_gso_ok(struct sk_buff *skb, netdev_features_t features)
 {
 	return net_gso_ok(features, skb_shinfo(skb)->gso_type) &&
 	       (!skb_has_frag_list(skb) || (features & NETIF_F_FRAGLIST));
 }
 
-static inline int netif_needs_gso(struct sk_buff *skb, int features)
+static inline int netif_needs_gso(struct sk_buff *skb,
+	netdev_features_t features)
 {
 	return skb_is_gso(skb) && (!skb_gso_ok(skb, features) ||
 		unlikely(skb->ip_summed != CHECKSUM_PARTIAL));
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index f3af147..6aec265 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -29,6 +29,7 @@
 #include <linux/rcupdate.h>
 #include <linux/dmaengine.h>
 #include <linux/hrtimer.h>
+#include <linux/netdev_features.h>
 
 /* Don't change this without changing skb_csum_unnecessary! */
 #define CHECKSUM_NONE 0
@@ -1880,7 +1881,8 @@ extern void	       skb_split(struct sk_buff *skb,
 extern int	       skb_shift(struct sk_buff *tgt, struct sk_buff *skb,
 				 int shiftlen);
 
-extern struct sk_buff *skb_segment(struct sk_buff *skb, u32 features);
+extern struct sk_buff *skb_segment(struct sk_buff *skb,
+				   netdev_features_t features);
 
 static inline void *skb_header_pointer(const struct sk_buff *skb, int offset,
 				       int len, void *buffer)
diff --git a/include/net/protocol.h b/include/net/protocol.h
index 6f7eb80..e182e13 100644
--- a/include/net/protocol.h
+++ b/include/net/protocol.h
@@ -38,7 +38,7 @@ struct net_protocol {
 	void			(*err_handler)(struct sk_buff *skb, u32 info);
 	int			(*gso_send_check)(struct sk_buff *skb);
 	struct sk_buff	       *(*gso_segment)(struct sk_buff *skb,
-					       u32 features);
+					       netdev_features_t features);
 	struct sk_buff	      **(*gro_receive)(struct sk_buff **head,
 					       struct sk_buff *skb);
 	int			(*gro_complete)(struct sk_buff *skb);
@@ -57,7 +57,7 @@ struct inet6_protocol {
 
 	int	(*gso_send_check)(struct sk_buff *skb);
 	struct sk_buff *(*gso_segment)(struct sk_buff *skb,
-				       u32 features);
+				       netdev_features_t features);
 	struct sk_buff **(*gro_receive)(struct sk_buff **head,
 					struct sk_buff *skb);
 	int	(*gro_complete)(struct sk_buff *skb);
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 149a415..0c49be2 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1403,7 +1403,8 @@ extern struct request_sock_ops tcp6_request_sock_ops;
 extern void tcp_v4_destroy_sock(struct sock *sk);
 
 extern int tcp_v4_gso_send_check(struct sk_buff *skb);
-extern struct sk_buff *tcp_tso_segment(struct sk_buff *skb, u32 features);
+extern struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
+				       netdev_features_t features);
 extern struct sk_buff **tcp_gro_receive(struct sk_buff **head,
 					struct sk_buff *skb);
 extern struct sk_buff **tcp4_gro_receive(struct sk_buff **head,
diff --git a/include/net/udp.h b/include/net/udp.h
index 67ea6fc..691ca16 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -256,5 +256,6 @@ extern void udp4_proc_exit(void);
 extern void udp_init(void);
 
 extern int udp4_ufo_send_check(struct sk_buff *skb);
-extern struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, u32 features);
+extern struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb,
+	netdev_features_t features);
 #endif	/* _UDP_H */
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 774bd22..e47c1c8 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -585,7 +585,8 @@ static void vlan_dev_uninit(struct net_device *dev)
 	}
 }
 
-static u32 vlan_dev_fix_features(struct net_device *dev, u32 features)
+static netdev_features_t vlan_dev_fix_features(struct net_device *dev,
+	netdev_features_t features)
 {
 	struct net_device *real_dev = vlan_dev_info(dev)->real_dev;
 
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 1bacca4..c4908b7 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -292,10 +292,11 @@ int br_min_mtu(const struct net_bridge *br)
 /*
  * Recomputes features using slave's features
  */
-u32 br_features_recompute(struct net_bridge *br, u32 features)
+netdev_features_t br_features_recompute(struct net_bridge *br,
+	netdev_features_t features)
 {
 	struct net_bridge_port *p;
-	u32 mask;
+	netdev_features_t mask;
 
 	if (list_empty(&br->port_list))
 		return features;
diff --git a/net/core/dev.c b/net/core/dev.c
index 3041b6ae..a5a0e76 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1842,7 +1842,7 @@ EXPORT_SYMBOL(skb_checksum_help);
  *	It may return NULL if the skb requires no segmentation.  This is
  *	only possible when GSO is used for verifying header integrity.
  */
-struct sk_buff *skb_gso_segment(struct sk_buff *skb, u32 features)
+struct sk_buff *skb_gso_segment(struct sk_buff *skb, netdev_features_t features)
 {
 	struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
 	struct packet_type *ptype;
@@ -1872,8 +1872,8 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, u32 features)
 		if (dev && dev->ethtool_ops && dev->ethtool_ops->get_drvinfo)
 			dev->ethtool_ops->get_drvinfo(dev, &info);
 
-		WARN(1, "%s: caps=(0x%lx, 0x%lx) len=%d data_len=%d ip_summed=%d\n",
-		     info.driver, dev ? dev->features : 0L,
+		WARN(1, "%s: caps=(0x%llx, 0x%lx) len=%d data_len=%d ip_summed=%d\n",
+		     info.driver, dev ? (long long)dev->features : 0LL,
 		     skb->sk ? skb->sk->sk_route_caps : 0L,
 		     skb->len, skb->data_len, skb->ip_summed);
 
@@ -1980,7 +1980,7 @@ static void dev_gso_skb_destructor(struct sk_buff *skb)
  *	This function segments the given skb and stores the list of segments
  *	in skb->next.
  */
-static int dev_gso_segment(struct sk_buff *skb, int features)
+static int dev_gso_segment(struct sk_buff *skb, netdev_features_t features)
 {
 	struct sk_buff *segs;
 
@@ -2019,7 +2019,7 @@ static inline void skb_orphan_try(struct sk_buff *skb)
 	}
 }
 
-static bool can_checksum_protocol(unsigned long features, __be16 protocol)
+static bool can_checksum_protocol(netdev_features_t features, __be16 protocol)
 {
 	return ((features & NETIF_F_GEN_CSUM) ||
 		((features & NETIF_F_V4_CSUM) &&
@@ -2030,7 +2030,8 @@ static bool can_checksum_protocol(unsigned long features, __be16 protocol)
 		 protocol == htons(ETH_P_FCOE)));
 }
 
-static u32 harmonize_features(struct sk_buff *skb, __be16 protocol, u32 features)
+static netdev_features_t harmonize_features(struct sk_buff *skb,
+	__be16 protocol, netdev_features_t features)
 {
 	if (!can_checksum_protocol(features, protocol)) {
 		features &= ~NETIF_F_ALL_CSUM;
@@ -2042,10 +2043,10 @@ static u32 harmonize_features(struct sk_buff *skb, __be16 protocol, u32 features
 	return features;
 }
 
-u32 netif_skb_features(struct sk_buff *skb)
+netdev_features_t netif_skb_features(struct sk_buff *skb)
 {
 	__be16 protocol = skb->protocol;
-	u32 features = skb->dev->features;
+	netdev_features_t features = skb->dev->features;
 
 	if (protocol == htons(ETH_P_8021Q)) {
 		struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
@@ -2091,7 +2092,7 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
 	unsigned int skb_len;
 
 	if (likely(!skb->next)) {
-		u32 features;
+		netdev_features_t features;
 
 		/*
 		 * If device doesn't need skb->dst, release it right now while
@@ -5191,7 +5192,8 @@ static void rollback_registered(struct net_device *dev)
 	list_del(&single);
 }
 
-u32 netdev_fix_features(struct net_device *dev, u32 features)
+static netdev_features_t netdev_fix_features(struct net_device *dev,
+	netdev_features_t features)
 {
 	/* Fix illegal checksum combinations */
 	if ((features & NETIF_F_HW_CSUM) &&
@@ -5250,11 +5252,10 @@ u32 netdev_fix_features(struct net_device *dev, u32 features)
 
 	return features;
 }
-EXPORT_SYMBOL(netdev_fix_features);
 
 int __netdev_update_features(struct net_device *dev)
 {
-	u32 features;
+	netdev_features_t features;
 	int err = 0;
 
 	ASSERT_RTNL();
@@ -5270,8 +5271,10 @@ int __netdev_update_features(struct net_device *dev)
 	if (dev->features == features)
 		return 0;
 
+	BUILD_BUG_ON(sizeof(features) != sizeof(u32));	/* XXX: need: %Fx */
+
 	netdev_dbg(dev, "Features changed: 0x%08x -> 0x%08x\n",
-		dev->features, features);
+		(u32)dev->features, (u32)features);
 
 	if (dev->netdev_ops->ndo_set_features)
 		err = dev->netdev_ops->ndo_set_features(dev, features);
@@ -5279,7 +5282,7 @@ int __netdev_update_features(struct net_device *dev)
 	if (unlikely(err < 0)) {
 		netdev_err(dev,
 			"set_features() failed (%d); wanted 0x%08x, left 0x%08x\n",
-			err, features, dev->features);
+			err, (u32)features, (u32)dev->features);
 		return -1;
 	}
 
@@ -6193,7 +6196,8 @@ static int dev_cpu_callback(struct notifier_block *nfb,
  *	@one to the master device with current feature set @all.  Will not
  *	enable anything that is off in @mask. Returns the new feature set.
  */
-u32 netdev_increment_features(u32 all, u32 one, u32 mask)
+netdev_features_t netdev_increment_features(netdev_features_t all,
+	netdev_features_t one, netdev_features_t mask)
 {
 	if (mask & NETIF_F_GEN_CSUM)
 		mask |= NETIF_F_ALL_CSUM;
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 9214e54..17f5f96 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -171,7 +171,7 @@ static void __ethtool_get_strings(struct net_device *dev,
 		ops->get_strings(dev, stringset, data);
 }
 
-static u32 ethtool_get_feature_mask(u32 eth_cmd)
+static netdev_features_t ethtool_get_feature_mask(u32 eth_cmd)
 {
 	/* feature masks of legacy discrete ethtool ops */
 
@@ -205,7 +205,7 @@ static u32 ethtool_get_feature_mask(u32 eth_cmd)
 static int ethtool_get_one_feature(struct net_device *dev,
 	char __user *useraddr, u32 ethcmd)
 {
-	u32 mask = ethtool_get_feature_mask(ethcmd);
+	netdev_features_t mask = ethtool_get_feature_mask(ethcmd);
 	struct ethtool_value edata = {
 		.cmd = ethcmd,
 		.data = !!(dev->features & mask),
@@ -220,7 +220,7 @@ static int ethtool_set_one_feature(struct net_device *dev,
 	void __user *useraddr, u32 ethcmd)
 {
 	struct ethtool_value edata;
-	u32 mask;
+	netdev_features_t mask;
 
 	if (copy_from_user(&edata, useraddr, sizeof(edata)))
 		return -EFAULT;
@@ -260,8 +260,7 @@ static u32 __ethtool_get_flags(struct net_device *dev)
 
 static int __ethtool_set_flags(struct net_device *dev, u32 data)
 {
-	u32 features = 0;
-	u32 changed;
+	netdev_features_t features = 0, changed;
 
 	if (data & ~ETH_ALL_FLAGS)
 		return -EINVAL;
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 11b98bc..af35d90 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -100,7 +100,7 @@ NETDEVICE_SHOW(addr_assign_type, fmt_dec);
 NETDEVICE_SHOW(addr_len, fmt_dec);
 NETDEVICE_SHOW(iflink, fmt_dec);
 NETDEVICE_SHOW(ifindex, fmt_dec);
-NETDEVICE_SHOW(features, fmt_hex);
+NETDEVICE_SHOW(features, fmt_hex);	/* XXX: need %Fx */
 NETDEVICE_SHOW(type, fmt_dec);
 NETDEVICE_SHOW(link_mode, fmt_dec);
 
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 46cbd28..76edd5b 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2495,7 +2495,7 @@ EXPORT_SYMBOL_GPL(skb_pull_rcsum);
  *	a pointer to the first in a list of new skbs for the segments.
  *	In case of error it returns ERR_PTR(err).
  */
-struct sk_buff *skb_segment(struct sk_buff *skb, u32 features)
+struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
 {
 	struct sk_buff *segs = NULL;
 	struct sk_buff *tail = NULL;
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 83673d2..7c9a33f 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1242,7 +1242,8 @@ out:
 	return err;
 }
 
-static struct sk_buff *inet_gso_segment(struct sk_buff *skb, u32 features)
+static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
+	netdev_features_t features)
 {
 	struct sk_buff *segs = ERR_PTR(-EINVAL);
 	struct iphdr *iph;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 054a59d..ff9104f 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2654,7 +2654,7 @@ int compat_tcp_getsockopt(struct sock *sk, int level, int optname,
 EXPORT_SYMBOL(compat_tcp_getsockopt);
 #endif
 
-struct sk_buff *tcp_tso_segment(struct sk_buff *skb, u32 features)
+struct sk_buff *tcp_tso_segment(struct sk_buff *skb, netdev_features_t features)
 {
 	struct sk_buff *segs = ERR_PTR(-EINVAL);
 	struct tcphdr *th;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index abca870..2842993 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -2244,7 +2244,8 @@ int udp4_ufo_send_check(struct sk_buff *skb)
 	return 0;
 }
 
-struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, u32 features)
+struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb,
+	netdev_features_t features)
 {
 	struct sk_buff *segs = ERR_PTR(-EINVAL);
 	unsigned int mss;
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index b7919f9..34088f7 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -765,7 +765,8 @@ out:
 	return err;
 }
 
-static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, u32 features)
+static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,
+	netdev_features_t features)
 {
 	struct sk_buff *segs = ERR_PTR(-EINVAL);
 	struct ipv6hdr *ipv6h;
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 41f8c9c..1df53db 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1295,7 +1295,7 @@ static int udp6_ufo_send_check(struct sk_buff *skb)
 	return 0;
 }
 
-static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, u32 features)
+static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, netdev_features_t features)
 {
 	struct sk_buff *segs = ERR_PTR(-EINVAL);
 	unsigned int mss;
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [RFT PATCH 6/9] net: ethtool: use C99 array initialization for feature-names table
  2011-06-20 19:14 [RFT PATCH 0/9] Cleanup and extension of netdev features Michał Mirosław
                   ` (4 preceding siblings ...)
  2011-06-20 19:14 ` [RFT PATCH 8/9] net: extend netdev_features_t to 64 bits Michał Mirosław
@ 2011-06-20 19:14 ` Michał Mirosław
  2011-06-20 19:14 ` [RFT PATCH 7/9] ethtool: prepare for larger netdev_features_t type Michał Mirosław
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 28+ messages in thread
From: Michał Mirosław @ 2011-06-20 19:14 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Ben Hutchings

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 net/core/ethtool.c |   74 +++++++++++++++++++++++++--------------------------
 1 files changed, 36 insertions(+), 38 deletions(-)

diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 17f5f96..97bbf25 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -40,6 +40,42 @@ EXPORT_SYMBOL(ethtool_op_get_link);
 
 #define ETHTOOL_DEV_FEATURE_WORDS	1
 
+static const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN] = {
+	[NETIF_F_SG_BIT] =               "tx-scatter-gather",
+	[NETIF_F_IP_CSUM_BIT] =          "tx-checksum-ipv4",
+	[NETIF_F_NO_CSUM_BIT] =          "tx-checksum-unneeded",
+	[NETIF_F_HW_CSUM_BIT] =          "tx-checksum-ip-generic",
+	[NETIF_F_IPV6_CSUM_BIT] =        "tx-checksum-ipv6",
+	[NETIF_F_HIGHDMA_BIT] =          "highdma",
+	[NETIF_F_FRAGLIST_BIT] =         "tx-scatter-gather-fraglist",
+	[NETIF_F_HW_VLAN_TX_BIT] =       "tx-vlan-hw-insert",
+
+	[NETIF_F_HW_VLAN_RX_BIT] =       "rx-vlan-hw-parse",
+	[NETIF_F_HW_VLAN_FILTER_BIT] =   "rx-vlan-filter",
+	[NETIF_F_VLAN_CHALLENGED_BIT] =  "vlan-challenged",
+	[NETIF_F_GSO_BIT] =              "tx-generic-segmentation",
+	[NETIF_F_LLTX_BIT] =             "tx-lockless",
+	[NETIF_F_NETNS_LOCAL_BIT] =      "netns-local",
+	[NETIF_F_GRO_BIT] =              "rx-gro",
+	[NETIF_F_LRO_BIT] =              "rx-lro",
+
+	[NETIF_F_TSO_BIT] =              "tx-tcp-segmentation",
+	[NETIF_F_UFO_BIT] =              "tx-udp-fragmentation",
+	[NETIF_F_GSO_ROBUST_BIT] =       "tx-gso-robust",
+	[NETIF_F_TSO_ECN_BIT] =          "tx-tcp-ecn-segmentation",
+	[NETIF_F_TSO6_BIT] =             "tx-tcp6-segmentation",
+	[NETIF_F_FSO_BIT] =              "tx-fcoe-segmentation",
+
+	[NETIF_F_FCOE_CRC_BIT] =         "tx-checksum-fcoe-crc",
+	[NETIF_F_SCTP_CSUM_BIT] =        "tx-checksum-sctp",
+	[NETIF_F_FCOE_MTU_BIT] =         "fcoe-mtu",
+	[NETIF_F_NTUPLE_BIT] =           "rx-ntuple-filter",
+	[NETIF_F_RXHASH_BIT] =           "rx-hashing",
+	[NETIF_F_RXCSUM_BIT] =           "rx-checksum",
+	[NETIF_F_NOCACHE_COPY_BIT] =     "tx-nocache-copy",
+	[NETIF_F_LOOPBACK_BIT] =         "loopback",
+};
+
 static int ethtool_get_features(struct net_device *dev, void __user *useraddr)
 {
 	struct ethtool_gfeatures cmd = {
@@ -107,44 +143,6 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
 	return ret;
 }
 
-static const char netdev_features_strings[ETHTOOL_DEV_FEATURE_WORDS * 32][ETH_GSTRING_LEN] = {
-	/* NETIF_F_SG */              "tx-scatter-gather",
-	/* NETIF_F_IP_CSUM */         "tx-checksum-ipv4",
-	/* NETIF_F_NO_CSUM */         "tx-checksum-unneeded",
-	/* NETIF_F_HW_CSUM */         "tx-checksum-ip-generic",
-	/* NETIF_F_IPV6_CSUM */       "tx-checksum-ipv6",
-	/* NETIF_F_HIGHDMA */         "highdma",
-	/* NETIF_F_FRAGLIST */        "tx-scatter-gather-fraglist",
-	/* NETIF_F_HW_VLAN_TX */      "tx-vlan-hw-insert",
-
-	/* NETIF_F_HW_VLAN_RX */      "rx-vlan-hw-parse",
-	/* NETIF_F_HW_VLAN_FILTER */  "rx-vlan-filter",
-	/* NETIF_F_VLAN_CHALLENGED */ "vlan-challenged",
-	/* NETIF_F_GSO */             "tx-generic-segmentation",
-	/* NETIF_F_LLTX */            "tx-lockless",
-	/* NETIF_F_NETNS_LOCAL */     "netns-local",
-	/* NETIF_F_GRO */             "rx-gro",
-	/* NETIF_F_LRO */             "rx-lro",
-
-	/* NETIF_F_TSO */             "tx-tcp-segmentation",
-	/* NETIF_F_UFO */             "tx-udp-fragmentation",
-	/* NETIF_F_GSO_ROBUST */      "tx-gso-robust",
-	/* NETIF_F_TSO_ECN */         "tx-tcp-ecn-segmentation",
-	/* NETIF_F_TSO6 */            "tx-tcp6-segmentation",
-	/* NETIF_F_FSO */             "tx-fcoe-segmentation",
-	"",
-	"",
-
-	/* NETIF_F_FCOE_CRC */        "tx-checksum-fcoe-crc",
-	/* NETIF_F_SCTP_CSUM */       "tx-checksum-sctp",
-	/* NETIF_F_FCOE_MTU */        "fcoe-mtu",
-	/* NETIF_F_NTUPLE */          "rx-ntuple-filter",
-	/* NETIF_F_RXHASH */          "rx-hashing",
-	/* NETIF_F_RXCSUM */          "rx-checksum",
-	/* NETIF_F_NOCACHE_COPY */    "tx-nocache-copy",
-	/* NETIF_F_LOOPBACK */        "loopback",
-};
-
 static int __ethtool_get_sset_count(struct net_device *dev, int sset)
 {
 	const struct ethtool_ops *ops = dev->ethtool_ops;
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [RFT PATCH 7/9] ethtool: prepare for larger netdev_features_t type
  2011-06-20 19:14 [RFT PATCH 0/9] Cleanup and extension of netdev features Michał Mirosław
                   ` (5 preceding siblings ...)
  2011-06-20 19:14 ` [RFT PATCH 6/9] net: ethtool: use C99 array initialization for feature-names table Michał Mirosław
@ 2011-06-20 19:14 ` Michał Mirosław
  2011-06-20 21:16   ` Ben Hutchings
  2011-06-20 19:14 ` [RFT PATCH 9/9] net: move NOCACHE_COPY checks to netdev_fix_features() Michał Mirosław
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 28+ messages in thread
From: Michał Mirosław @ 2011-06-20 19:14 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Ben Hutchings

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 net/core/ethtool.c |   45 +++++++++++++++++++++++++++++----------------
 1 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 97bbf25..3a93932 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -38,7 +38,7 @@ EXPORT_SYMBOL(ethtool_op_get_link);
 
 /* Handlers for each ethtool command */
 
-#define ETHTOOL_DEV_FEATURE_WORDS	1
+#define ETHTOOL_DEV_FEATURE_WORDS	((NETDEV_FEATURE_COUNT + 31) / 32)
 
 static const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN] = {
 	[NETIF_F_SG_BIT] =               "tx-scatter-gather",
@@ -82,16 +82,21 @@ static int ethtool_get_features(struct net_device *dev, void __user *useraddr)
 		.cmd = ETHTOOL_GFEATURES,
 		.size = ETHTOOL_DEV_FEATURE_WORDS,
 	};
-	struct ethtool_get_features_block features[ETHTOOL_DEV_FEATURE_WORDS] = {
-		{
-			.available = dev->hw_features,
-			.requested = dev->wanted_features,
-			.active = dev->features,
-			.never_changed = NETIF_F_NEVER_CHANGE,
-		},
-	};
+	struct ethtool_get_features_block features[ETHTOOL_DEV_FEATURE_WORDS];
 	u32 __user *sizeaddr;
 	u32 copy_size;
+	int i;
+
+	/* in case feature bits run out again */
+	BUILD_BUG_ON(ETHTOOL_DEV_FEATURE_WORDS*sizeof(u32) > sizeof(netdev_features_t));
+
+	/* this should get loop-unrolled easily by compiler */
+	for (i = 0; i < ETHTOOL_DEV_FEATURE_WORDS; ++i) {
+		features[i].available = (u32)(dev->hw_features >> (32*i));
+		features[i].requested = (u32)(dev->wanted_features >> (32*i));
+		features[i].active = (u32)(dev->features >> (32*i));
+		features[i].never_changed = (u32)(NETIF_F_NEVER_CHANGE >> (32*i));
+	}
 
 	sizeaddr = useraddr + offsetof(struct ethtool_gfeatures, size);
 	if (get_user(copy_size, sizeaddr))
@@ -113,7 +118,8 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
 {
 	struct ethtool_sfeatures cmd;
 	struct ethtool_set_features_block features[ETHTOOL_DEV_FEATURE_WORDS];
-	int ret = 0;
+	netdev_features_t wanted = 0, valid = 0;
+	int i, ret = 0;
 
 	if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
 		return -EFAULT;
@@ -125,19 +131,26 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
 	if (copy_from_user(features, useraddr, sizeof(features)))
 		return -EFAULT;
 
-	if (features[0].valid & ~NETIF_F_ETHTOOL_BITS)
+	/* I wonder if the compiler will be smart enough to loop-unroll
+	 * and optimize this... (no worries if not) --mq */
+	for (i = ETHTOOL_DEV_FEATURE_WORDS; i-- > 0; ) {
+		valid = (valid << 32)|features[i].valid;
+		wanted = (wanted << 32)|features[i].requested;
+	}
+
+	if (valid & ~NETIF_F_ETHTOOL_BITS)
 		return -EINVAL;
 
-	if (features[0].valid & ~dev->hw_features) {
-		features[0].valid &= dev->hw_features;
+	if (valid & ~dev->hw_features) {
+		valid &= dev->hw_features;
 		ret |= ETHTOOL_F_UNSUPPORTED;
 	}
 
-	dev->wanted_features &= ~features[0].valid;
-	dev->wanted_features |= features[0].valid & features[0].requested;
+	dev->wanted_features &= ~valid;
+	dev->wanted_features |= wanted & valid;
 	__netdev_update_features(dev);
 
-	if ((dev->wanted_features ^ dev->features) & features[0].valid)
+	if ((dev->wanted_features ^ dev->features) & valid)
 		ret |= ETHTOOL_F_WISH;
 
 	return ret;
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [RFT PATCH 9/9] net: move NOCACHE_COPY checks to netdev_fix_features()
  2011-06-20 19:14 [RFT PATCH 0/9] Cleanup and extension of netdev features Michał Mirosław
                   ` (6 preceding siblings ...)
  2011-06-20 19:14 ` [RFT PATCH 7/9] ethtool: prepare for larger netdev_features_t type Michał Mirosław
@ 2011-06-20 19:14 ` Michał Mirosław
  2011-06-20 19:35 ` [RFT PATCH 0/9] Cleanup and extension of netdev features David Miller
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 28+ messages in thread
From: Michał Mirosław @ 2011-06-20 19:14 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Ben Hutchings

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 include/linux/netdev_features.h |    3 ++-
 net/core/dev.c                  |   21 +++++++++++++--------
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
index 86d6193..9f24781 100644
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
@@ -146,6 +146,7 @@ enum {
 #define NETIF_F_ALL_FOR_ALL	(NETIF_F_NOCACHE_COPY | NETIF_F_FSO)
 
 	/* changeable features with no special hardware requirements */
-#define NETIF_F_SOFT_FEATURES	(NETIF_F_GSO | NETIF_F_GRO)
+#define NETIF_F_SOFT_FEATURES	(NETIF_F_GSO | NETIF_F_GRO | \
+				 NETIF_F_NOCACHE_COPY)
 
 #endif	/* _LINUX_NETDEV_FEATURES_H */
diff --git a/net/core/dev.c b/net/core/dev.c
index 7e58353..30782b7 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5250,6 +5250,19 @@ static netdev_features_t netdev_fix_features(struct net_device *dev,
 		}
 	}
 
+	/* No cache copy is a win only with real HW with HW checksumming */
+	if (features & NETIF_F_NOCACHE_COPY) {
+		if (!(features & NETIF_F_ALL_CSUM)) {
+			netdev_dbg(dev,
+				"Dropping NETIF_F_NOCACHE_COPY since it needs HW checksumming.\n");
+			features &= ~NETIF_F_NOCACHE_COPY;
+		} else if (features & NETIF_F_NO_CSUM) {
+			netdev_dbg(dev,
+				"Dropping NETIF_F_NOCACHE_COPY for virtual device.\n");
+			features &= ~NETIF_F_NOCACHE_COPY;
+		}
+	}
+
 	return features;
 }
 
@@ -5465,14 +5478,6 @@ int register_netdevice(struct net_device *dev)
 	dev->features |= NETIF_F_SOFT_FEATURES;
 	dev->wanted_features = dev->features & dev->hw_features;
 
-	/* Turn on no cache copy if HW is doing checksum */
-	dev->hw_features |= NETIF_F_NOCACHE_COPY;
-	if ((dev->features & NETIF_F_ALL_CSUM) &&
-	    !(dev->features & NETIF_F_NO_CSUM)) {
-		dev->wanted_features |= NETIF_F_NOCACHE_COPY;
-		dev->features |= NETIF_F_NOCACHE_COPY;
-	}
-
 	/* Enable GRO and NETIF_F_HIGHDMA for vlans by default,
 	 * vlan_dev_init() will do the dev->features check, so these features
 	 * are enabled only if supported by underlying device.
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [RFT PATCH 8/9] net: extend netdev_features_t to 64 bits
  2011-06-20 19:14 [RFT PATCH 0/9] Cleanup and extension of netdev features Michał Mirosław
                   ` (3 preceding siblings ...)
  2011-06-20 19:14 ` [RFT PATCH 4/9] net: introduce and use netdev_features_t for device features sets Michał Mirosław
@ 2011-06-20 19:14 ` Michał Mirosław
  2011-06-20 19:14 ` [RFT PATCH 6/9] net: ethtool: use C99 array initialization for feature-names table Michał Mirosław
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 28+ messages in thread
From: Michał Mirosław @ 2011-06-20 19:14 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Ben Hutchings

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 include/linux/netdev_features.h |    2 +-
 net/core/dev.c                  |   10 +++++-----
 net/core/net-sysfs.c            |    3 ++-
 3 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
index 2361e3ee..86d6193 100644
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
@@ -12,7 +12,7 @@
 
 #include <linux/types.h>
 
-typedef u32 netdev_features_t;
+typedef u64 netdev_features_t;
 
 enum {
 	NETIF_F_SG_BIT,			/* Scatter/gather IO. */
diff --git a/net/core/dev.c b/net/core/dev.c
index a5a0e76..7e58353 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5271,18 +5271,18 @@ int __netdev_update_features(struct net_device *dev)
 	if (dev->features == features)
 		return 0;
 
-	BUILD_BUG_ON(sizeof(features) != sizeof(u32));	/* XXX: need: %Fx */
+	BUILD_BUG_ON(sizeof(features) != sizeof(u64));	/* XXX: need: %Fx */
 
-	netdev_dbg(dev, "Features changed: 0x%08x -> 0x%08x\n",
-		(u32)dev->features, (u32)features);
+	netdev_dbg(dev, "Features changed: 0x%016llx -> 0x%016llx\n",
+		(u64)dev->features, (u64)features);
 
 	if (dev->netdev_ops->ndo_set_features)
 		err = dev->netdev_ops->ndo_set_features(dev, features);
 
 	if (unlikely(err < 0)) {
 		netdev_err(dev,
-			"set_features() failed (%d); wanted 0x%08x, left 0x%08x\n",
-			err, (u32)features, (u32)dev->features);
+			"set_features() failed (%d); wanted 0x%016llx, left 0x%016llx\n",
+			err, (u64)features, (u64)dev->features);
 		return -1;
 	}
 
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index af35d90..b7feeab 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -27,6 +27,7 @@
 #ifdef CONFIG_SYSFS
 static const char fmt_hex[] = "%#x\n";
 static const char fmt_long_hex[] = "%#lx\n";
+static const char fmt_long_long_hex[] = "%#llx\n";
 static const char fmt_dec[] = "%d\n";
 static const char fmt_udec[] = "%u\n";
 static const char fmt_ulong[] = "%lu\n";
@@ -100,7 +101,7 @@ NETDEVICE_SHOW(addr_assign_type, fmt_dec);
 NETDEVICE_SHOW(addr_len, fmt_dec);
 NETDEVICE_SHOW(iflink, fmt_dec);
 NETDEVICE_SHOW(ifindex, fmt_dec);
-NETDEVICE_SHOW(features, fmt_hex);	/* XXX: need %Fx */
+NETDEVICE_SHOW(features, fmt_long_long_hex);	/* XXX: need %Fx */
 NETDEVICE_SHOW(type, fmt_dec);
 NETDEVICE_SHOW(link_mode, fmt_dec);
 
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [RFT PATCH 0/9] Cleanup and extension of netdev features
  2011-06-20 19:14 [RFT PATCH 0/9] Cleanup and extension of netdev features Michał Mirosław
                   ` (7 preceding siblings ...)
  2011-06-20 19:14 ` [RFT PATCH 9/9] net: move NOCACHE_COPY checks to netdev_fix_features() Michał Mirosław
@ 2011-06-20 19:35 ` David Miller
  2011-06-20 19:47   ` Michał Mirosław
  2011-06-21 21:43 ` [RFT PATCH 0/9] Cleanup and extension of netdev features Ben Greear
  2011-06-23 17:42 ` Mahesh Bandewar
  10 siblings, 1 reply; 28+ messages in thread
From: David Miller @ 2011-06-20 19:35 UTC (permalink / raw)
  To: mirq-linux; +Cc: netdev, bhutchings


Patch #1 was not sent out.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFT PATCH 0/9] Cleanup and extension of netdev features
  2011-06-20 19:35 ` [RFT PATCH 0/9] Cleanup and extension of netdev features David Miller
@ 2011-06-20 19:47   ` Michał Mirosław
  2011-06-20 19:55     ` [IGNORE PATCH 1/9] Intel net drivers: convert to ndo_fix_features Michał Mirosław
  0 siblings, 1 reply; 28+ messages in thread
From: Michał Mirosław @ 2011-06-20 19:47 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, bhutchings

On Mon, Jun 20, 2011 at 12:35:38PM -0700, David Miller wrote:
> Patch #1 was not sent out.

Yes, that's on purpose: it's outdated and is just for making intel
drivers compile. I'll append it so you have a clear view for the rest
of the series.

Best Regards,
Michał Mirosław

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [IGNORE PATCH 1/9] Intel net drivers: convert to ndo_fix_features
  2011-06-20 19:47   ` Michał Mirosław
@ 2011-06-20 19:55     ` Michał Mirosław
  0 siblings, 0 replies; 28+ messages in thread
From: Michał Mirosław @ 2011-06-20 19:55 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Ben Hutchings

[This is an outdated patch just for making the rest of the series compile.]

Private rx_csum flags are now duplicate of netdev->features & NETIF_F_RXCSUM.
Removing this needs deeper surgery.

Since ixgbevf doesn't change hardware state on RX csum enable/disable
its reset is avoided.

Things noticed:
 - e1000, e1000e and ixgb have RX csum disabled by default
 - HW VLAN acceleration probably can be toggled, but it's left as is
 - the resets on RX csum offload change can probably be avoided
 - there is A LOT of copy-and-pasted code here

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 drivers/net/e1000/e1000_ethtool.c  |   69 --------------
 drivers/net/e1000/e1000_main.c     |   30 +++++-
 drivers/net/e1000e/ethtool.c       |   88 -----------------
 drivers/net/e1000e/netdev.c        |   35 ++++++--
 drivers/net/igb/igb_ethtool.c      |   67 -------------
 drivers/net/igb/igb_main.c         |   33 +++++--
 drivers/net/igbvf/ethtool.c        |   57 -----------
 drivers/net/igbvf/netdev.c         |   25 ++++-
 drivers/net/ixgb/ixgb.h            |    2 +
 drivers/net/ixgb/ixgb_ethtool.c    |   98 +-------------------
 drivers/net/ixgb/ixgb_main.c       |   44 ++++++++-
 drivers/net/ixgbe/ixgbe_ethtool.c  |  182 +++++++++++-------------------------
 drivers/net/ixgbe/ixgbe_main.c     |   41 +++++---
 drivers/net/ixgbevf/ethtool.c      |   46 ---------
 drivers/net/ixgbevf/ixgbevf_main.c |   26 ++++-
 15 files changed, 244 insertions(+), 599 deletions(-)

diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index ec0fa42..c5f0f04 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -290,69 +290,6 @@ static int e1000_set_pauseparam(struct net_device *netdev,
 	return retval;
 }
 
-static u32 e1000_get_rx_csum(struct net_device *netdev)
-{
-	struct e1000_adapter *adapter = netdev_priv(netdev);
-	return adapter->rx_csum;
-}
-
-static int e1000_set_rx_csum(struct net_device *netdev, u32 data)
-{
-	struct e1000_adapter *adapter = netdev_priv(netdev);
-	adapter->rx_csum = data;
-
-	if (netif_running(netdev))
-		e1000_reinit_locked(adapter);
-	else
-		e1000_reset(adapter);
-	return 0;
-}
-
-static u32 e1000_get_tx_csum(struct net_device *netdev)
-{
-	return (netdev->features & NETIF_F_HW_CSUM) != 0;
-}
-
-static int e1000_set_tx_csum(struct net_device *netdev, u32 data)
-{
-	struct e1000_adapter *adapter = netdev_priv(netdev);
-	struct e1000_hw *hw = &adapter->hw;
-
-	if (hw->mac_type < e1000_82543) {
-		if (!data)
-			return -EINVAL;
-		return 0;
-	}
-
-	if (data)
-		netdev->features |= NETIF_F_HW_CSUM;
-	else
-		netdev->features &= ~NETIF_F_HW_CSUM;
-
-	return 0;
-}
-
-static int e1000_set_tso(struct net_device *netdev, u32 data)
-{
-	struct e1000_adapter *adapter = netdev_priv(netdev);
-	struct e1000_hw *hw = &adapter->hw;
-
-	if ((hw->mac_type < e1000_82544) ||
-	    (hw->mac_type == e1000_82547))
-		return data ? -EINVAL : 0;
-
-	if (data)
-		netdev->features |= NETIF_F_TSO;
-	else
-		netdev->features &= ~NETIF_F_TSO;
-
-	netdev->features &= ~NETIF_F_TSO6;
-
-	e_info(probe, "TSO is %s\n", data ? "Enabled" : "Disabled");
-	adapter->tso_force = true;
-	return 0;
-}
-
 static u32 e1000_get_msglevel(struct net_device *netdev)
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
@@ -1905,12 +1842,6 @@ static const struct ethtool_ops e1000_ethtool_ops = {
 	.set_ringparam          = e1000_set_ringparam,
 	.get_pauseparam         = e1000_get_pauseparam,
 	.set_pauseparam         = e1000_set_pauseparam,
-	.get_rx_csum            = e1000_get_rx_csum,
-	.set_rx_csum            = e1000_set_rx_csum,
-	.get_tx_csum            = e1000_get_tx_csum,
-	.set_tx_csum            = e1000_set_tx_csum,
-	.set_sg                 = ethtool_op_set_sg,
-	.set_tso                = e1000_set_tso,
 	.self_test              = e1000_diag_test,
 	.get_strings            = e1000_get_strings,
 	.set_phys_id            = e1000_set_phys_id,
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 76e8af0..188d99a 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -797,6 +797,24 @@ static int e1000_is_need_ioport(struct pci_dev *pdev)
 	}
 }
 
+static int e1000_set_features(struct net_device *netdev, u32 features)
+{
+	struct e1000_adapter *adapter = netdev_priv(netdev);
+	u32 changed = features ^ netdev->features;
+
+	if (!(changed & NETIF_F_RXCSUM))
+		return 0;
+
+	adapter->rx_csum = !!(features & NETIF_F_RXCSUM);
+
+	if (netif_running(netdev))
+		e1000_reinit_locked(adapter);
+	else
+		e1000_reset(adapter);
+
+	return 0;
+}
+
 static const struct net_device_ops e1000_netdev_ops = {
 	.ndo_open		= e1000_open,
 	.ndo_stop		= e1000_close,
@@ -815,6 +833,7 @@ static const struct net_device_ops e1000_netdev_ops = {
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= e1000_netpoll,
 #endif
+	.ndo_set_features       = e1000_set_features,
 };
 
 /**
@@ -1016,16 +1035,19 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 	}
 
 	if (hw->mac_type >= e1000_82543) {
-		netdev->features = NETIF_F_SG |
-				   NETIF_F_HW_CSUM |
-				   NETIF_F_HW_VLAN_TX |
+		netdev->hw_features = NETIF_F_SG |
+				   NETIF_F_HW_CSUM;
+		netdev->features = NETIF_F_HW_VLAN_TX |
 				   NETIF_F_HW_VLAN_RX |
 				   NETIF_F_HW_VLAN_FILTER;
 	}
 
 	if ((hw->mac_type >= e1000_82544) &&
 	   (hw->mac_type != e1000_82547))
-		netdev->features |= NETIF_F_TSO;
+		netdev->hw_features |= NETIF_F_TSO;
+
+	netdev->features |= netdev->hw_features;
+	netdev->hw_features |= NETIF_F_RXCSUM;
 
 	if (pci_using_dac) {
 		netdev->features |= NETIF_F_HIGHDMA;
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index cb1a362..25b5431 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -367,59 +367,6 @@ out:
 	return retval;
 }
 
-static u32 e1000_get_rx_csum(struct net_device *netdev)
-{
-	struct e1000_adapter *adapter = netdev_priv(netdev);
-	return adapter->flags & FLAG_RX_CSUM_ENABLED;
-}
-
-static int e1000_set_rx_csum(struct net_device *netdev, u32 data)
-{
-	struct e1000_adapter *adapter = netdev_priv(netdev);
-
-	if (data)
-		adapter->flags |= FLAG_RX_CSUM_ENABLED;
-	else
-		adapter->flags &= ~FLAG_RX_CSUM_ENABLED;
-
-	if (netif_running(netdev))
-		e1000e_reinit_locked(adapter);
-	else
-		e1000e_reset(adapter);
-	return 0;
-}
-
-static u32 e1000_get_tx_csum(struct net_device *netdev)
-{
-	return (netdev->features & NETIF_F_HW_CSUM) != 0;
-}
-
-static int e1000_set_tx_csum(struct net_device *netdev, u32 data)
-{
-	if (data)
-		netdev->features |= NETIF_F_HW_CSUM;
-	else
-		netdev->features &= ~NETIF_F_HW_CSUM;
-
-	return 0;
-}
-
-static int e1000_set_tso(struct net_device *netdev, u32 data)
-{
-	struct e1000_adapter *adapter = netdev_priv(netdev);
-
-	if (data) {
-		netdev->features |= NETIF_F_TSO;
-		netdev->features |= NETIF_F_TSO6;
-	} else {
-		netdev->features &= ~NETIF_F_TSO;
-		netdev->features &= ~NETIF_F_TSO6;
-	}
-
-	adapter->flags |= FLAG_TSO_FORCE;
-	return 0;
-}
-
 static u32 e1000_get_msglevel(struct net_device *netdev)
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
@@ -2003,31 +1950,6 @@ static void e1000_get_strings(struct net_device *netdev, u32 stringset,
 	}
 }
 
-static int e1000e_set_flags(struct net_device *netdev, u32 data)
-{
-	struct e1000_adapter *adapter = netdev_priv(netdev);
-	bool need_reset = false;
-	int rc;
-
-	need_reset = (data & ETH_FLAG_RXVLAN) !=
-		     (netdev->features & NETIF_F_HW_VLAN_RX);
-
-	rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_RXVLAN |
-				  ETH_FLAG_TXVLAN);
-
-	if (rc)
-		return rc;
-
-	if (need_reset) {
-		if (netif_running(netdev))
-			e1000e_reinit_locked(adapter);
-		else
-			e1000e_reset(adapter);
-	}
-
-	return 0;
-}
-
 static const struct ethtool_ops e1000_ethtool_ops = {
 	.get_settings		= e1000_get_settings,
 	.set_settings		= e1000_set_settings,
@@ -2047,14 +1969,6 @@ static const struct ethtool_ops e1000_ethtool_ops = {
 	.set_ringparam		= e1000_set_ringparam,
 	.get_pauseparam		= e1000_get_pauseparam,
 	.set_pauseparam		= e1000_set_pauseparam,
-	.get_rx_csum		= e1000_get_rx_csum,
-	.set_rx_csum		= e1000_set_rx_csum,
-	.get_tx_csum		= e1000_get_tx_csum,
-	.set_tx_csum		= e1000_set_tx_csum,
-	.get_sg			= ethtool_op_get_sg,
-	.set_sg			= ethtool_op_set_sg,
-	.get_tso		= ethtool_op_get_tso,
-	.set_tso		= e1000_set_tso,
 	.self_test		= e1000_diag_test,
 	.get_strings		= e1000_get_strings,
 	.set_phys_id		= e1000_set_phys_id,
@@ -2062,8 +1976,6 @@ static const struct ethtool_ops e1000_ethtool_ops = {
 	.get_sset_count		= e1000e_get_sset_count,
 	.get_coalesce		= e1000_get_coalesce,
 	.set_coalesce		= e1000_set_coalesce,
-	.get_flags		= ethtool_op_get_flags,
-	.set_flags		= e1000e_set_flags,
 };
 
 void e1000e_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 3bf5249..45c9d06 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -5751,6 +5751,28 @@ static void e1000_eeprom_checks(struct e1000_adapter *adapter)
 	}
 }
 
+static int e1000_set_features(struct net_device *netdev, u32 features)
+{
+	struct e1000_adapter *adapter = netdev_priv(netdev);
+	u32 changed = features ^ netdev->features;
+
+	if (features & NETIF_F_RXCSUM)
+		adapter->flags |= FLAG_RX_CSUM_ENABLED;
+	else
+		adapter->flags &= ~FLAG_RX_CSUM_ENABLED;
+
+	if (changed & NETIF_F_HW_VLAN_RX) {
+		netdev->features = features;
+		if (netif_running(netdev))
+			e1000e_reinit_locked(adapter);
+		else
+			e1000e_reset(adapter);
+		return 1;
+	}
+
+	return 0;
+}
+
 static const struct net_device_ops e1000e_netdev_ops = {
 	.ndo_open		= e1000_open,
 	.ndo_stop		= e1000_close,
@@ -5768,6 +5790,7 @@ static const struct net_device_ops e1000e_netdev_ops = {
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= e1000_netpoll,
 #endif
+	.ndo_set_features	= e1000_set_features,
 };
 
 /**
@@ -5927,17 +5950,15 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 	if (e1000_check_reset_block(&adapter->hw))
 		e_info("PHY reset is blocked due to SOL/IDER session.\n");
 
-	netdev->features = NETIF_F_SG |
-			   NETIF_F_HW_CSUM |
-			   NETIF_F_HW_VLAN_TX |
-			   NETIF_F_HW_VLAN_RX;
+	netdev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM |
+			      NETIF_F_TSO | NETIF_F_TSO6 |
+			      NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+	netdev->features = netdev->hw_features;
+	netdev->hw_features |= NETIF_F_RXCSUM;
 
 	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER)
 		netdev->features |= NETIF_F_HW_VLAN_FILTER;
 
-	netdev->features |= NETIF_F_TSO;
-	netdev->features |= NETIF_F_TSO6;
-
 	netdev->vlan_features |= NETIF_F_TSO;
 	netdev->vlan_features |= NETIF_F_TSO6;
 	netdev->vlan_features |= NETIF_F_HW_CSUM;
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index fdc895e..1862c97 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -318,65 +318,6 @@ static int igb_set_pauseparam(struct net_device *netdev,
 	return retval;
 }
 
-static u32 igb_get_rx_csum(struct net_device *netdev)
-{
-	struct igb_adapter *adapter = netdev_priv(netdev);
-	return !!(adapter->rx_ring[0]->flags & IGB_RING_FLAG_RX_CSUM);
-}
-
-static int igb_set_rx_csum(struct net_device *netdev, u32 data)
-{
-	struct igb_adapter *adapter = netdev_priv(netdev);
-	int i;
-
-	for (i = 0; i < adapter->num_rx_queues; i++) {
-		if (data)
-			adapter->rx_ring[i]->flags |= IGB_RING_FLAG_RX_CSUM;
-		else
-			adapter->rx_ring[i]->flags &= ~IGB_RING_FLAG_RX_CSUM;
-	}
-
-	return 0;
-}
-
-static u32 igb_get_tx_csum(struct net_device *netdev)
-{
-	return (netdev->features & NETIF_F_IP_CSUM) != 0;
-}
-
-static int igb_set_tx_csum(struct net_device *netdev, u32 data)
-{
-	struct igb_adapter *adapter = netdev_priv(netdev);
-
-	if (data) {
-		netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
-		if (adapter->hw.mac.type >= e1000_82576)
-			netdev->features |= NETIF_F_SCTP_CSUM;
-	} else {
-		netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
-		                      NETIF_F_SCTP_CSUM);
-	}
-
-	return 0;
-}
-
-static int igb_set_tso(struct net_device *netdev, u32 data)
-{
-	struct igb_adapter *adapter = netdev_priv(netdev);
-
-	if (data) {
-		netdev->features |= NETIF_F_TSO;
-		netdev->features |= NETIF_F_TSO6;
-	} else {
-		netdev->features &= ~NETIF_F_TSO;
-		netdev->features &= ~NETIF_F_TSO6;
-	}
-
-	dev_info(&adapter->pdev->dev, "TSO is %s\n",
-		 data ? "Enabled" : "Disabled");
-	return 0;
-}
-
 static u32 igb_get_msglevel(struct net_device *netdev)
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
@@ -2207,14 +2148,6 @@ static const struct ethtool_ops igb_ethtool_ops = {
 	.set_ringparam          = igb_set_ringparam,
 	.get_pauseparam         = igb_get_pauseparam,
 	.set_pauseparam         = igb_set_pauseparam,
-	.get_rx_csum            = igb_get_rx_csum,
-	.set_rx_csum            = igb_set_rx_csum,
-	.get_tx_csum            = igb_get_tx_csum,
-	.set_tx_csum            = igb_set_tx_csum,
-	.get_sg                 = ethtool_op_get_sg,
-	.set_sg                 = ethtool_op_set_sg,
-	.get_tso                = ethtool_op_get_tso,
-	.set_tso                = igb_set_tso,
 	.self_test              = igb_diag_test,
 	.get_strings            = igb_get_strings,
 	.set_phys_id            = igb_set_phys_id,
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index c2e9670..2841f14 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -1748,6 +1748,21 @@ void igb_reset(struct igb_adapter *adapter)
 	igb_get_phy_info(hw);
 }
 
+static int igb_set_features(struct net_device *netdev, u32 features)
+{
+	struct igb_adapter *adapter = netdev_priv(netdev);
+	int i;
+
+	for (i = 0; i < adapter->num_rx_queues; i++) {
+		if (features & NETIF_F_RXCSUM)
+			adapter->rx_ring[i]->flags |= IGB_RING_FLAG_RX_CSUM;
+		else
+			adapter->rx_ring[i]->flags &= ~IGB_RING_FLAG_RX_CSUM;
+	}
+
+	return 0;
+}
+
 static const struct net_device_ops igb_netdev_ops = {
 	.ndo_open		= igb_open,
 	.ndo_stop		= igb_close,
@@ -1770,6 +1785,7 @@ static const struct net_device_ops igb_netdev_ops = {
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= igb_netpoll,
 #endif
+	.ndo_set_features       = igb_set_features,
 };
 
 /**
@@ -1909,17 +1925,18 @@ static int __devinit igb_probe(struct pci_dev *pdev,
 		dev_info(&pdev->dev,
 			"PHY reset is blocked due to SOL/IDER session.\n");
 
-	netdev->features = NETIF_F_SG |
+	netdev->hw_features = NETIF_F_SG |
 			   NETIF_F_IP_CSUM |
+			   NETIF_F_IPV6_CSUM |
+			   NETIF_F_TSO |
+			   NETIF_F_TSO6 |
+			   NETIF_F_RXCSUM;
+
+	netdev->features = netdev->hw_features |
 			   NETIF_F_HW_VLAN_TX |
 			   NETIF_F_HW_VLAN_RX |
 			   NETIF_F_HW_VLAN_FILTER;
 
-	netdev->features |= NETIF_F_IPV6_CSUM;
-	netdev->features |= NETIF_F_TSO;
-	netdev->features |= NETIF_F_TSO6;
-	netdev->features |= NETIF_F_GRO;
-
 	netdev->vlan_features |= NETIF_F_TSO;
 	netdev->vlan_features |= NETIF_F_TSO6;
 	netdev->vlan_features |= NETIF_F_IP_CSUM;
@@ -1931,8 +1948,10 @@ static int __devinit igb_probe(struct pci_dev *pdev,
 		netdev->vlan_features |= NETIF_F_HIGHDMA;
 	}
 
-	if (hw->mac.type >= e1000_82576)
+	if (hw->mac.type >= e1000_82576) {
+		netdev->hw_features |= NETIF_F_SCTP_CSUM;
 		netdev->features |= NETIF_F_SCTP_CSUM;
+	}
 
 	adapter->en_mng_pt = igb_enable_mng_pass_thru(hw);
 
diff --git a/drivers/net/igbvf/ethtool.c b/drivers/net/igbvf/ethtool.c
index b0b14d6..fd36366 100644
--- a/drivers/net/igbvf/ethtool.c
+++ b/drivers/net/igbvf/ethtool.c
@@ -128,55 +128,6 @@ static int igbvf_set_pauseparam(struct net_device *netdev,
 	return -EOPNOTSUPP;
 }
 
-static u32 igbvf_get_rx_csum(struct net_device *netdev)
-{
-	struct igbvf_adapter *adapter = netdev_priv(netdev);
-	return !(adapter->flags & IGBVF_FLAG_RX_CSUM_DISABLED);
-}
-
-static int igbvf_set_rx_csum(struct net_device *netdev, u32 data)
-{
-	struct igbvf_adapter *adapter = netdev_priv(netdev);
-
-	if (data)
-		adapter->flags &= ~IGBVF_FLAG_RX_CSUM_DISABLED;
-	else
-		adapter->flags |= IGBVF_FLAG_RX_CSUM_DISABLED;
-
-	return 0;
-}
-
-static u32 igbvf_get_tx_csum(struct net_device *netdev)
-{
-	return (netdev->features & NETIF_F_IP_CSUM) != 0;
-}
-
-static int igbvf_set_tx_csum(struct net_device *netdev, u32 data)
-{
-	if (data)
-		netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
-	else
-		netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
-	return 0;
-}
-
-static int igbvf_set_tso(struct net_device *netdev, u32 data)
-{
-	struct igbvf_adapter *adapter = netdev_priv(netdev);
-
-	if (data) {
-		netdev->features |= NETIF_F_TSO;
-		netdev->features |= NETIF_F_TSO6;
-	} else {
-		netdev->features &= ~NETIF_F_TSO;
-		netdev->features &= ~NETIF_F_TSO6;
-	}
-
-	dev_info(&adapter->pdev->dev, "TSO is %s\n",
-	         data ? "Enabled" : "Disabled");
-	return 0;
-}
-
 static u32 igbvf_get_msglevel(struct net_device *netdev)
 {
 	struct igbvf_adapter *adapter = netdev_priv(netdev);
@@ -511,14 +462,6 @@ static const struct ethtool_ops igbvf_ethtool_ops = {
 	.set_ringparam		= igbvf_set_ringparam,
 	.get_pauseparam		= igbvf_get_pauseparam,
 	.set_pauseparam		= igbvf_set_pauseparam,
-	.get_rx_csum            = igbvf_get_rx_csum,
-	.set_rx_csum            = igbvf_set_rx_csum,
-	.get_tx_csum		= igbvf_get_tx_csum,
-	.set_tx_csum		= igbvf_set_tx_csum,
-	.get_sg			= ethtool_op_get_sg,
-	.set_sg			= ethtool_op_set_sg,
-	.get_tso		= ethtool_op_get_tso,
-	.set_tso		= igbvf_set_tso,
 	.self_test		= igbvf_diag_test,
 	.get_sset_count		= igbvf_get_sset_count,
 	.get_strings		= igbvf_get_strings,
diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c
index 64b47bf..bb2a596 100644
--- a/drivers/net/igbvf/netdev.c
+++ b/drivers/net/igbvf/netdev.c
@@ -2546,6 +2546,18 @@ static void igbvf_print_device_info(struct igbvf_adapter *adapter)
 	dev_info(&pdev->dev, "MAC: %d\n", hw->mac.type);
 }
 
+static int igbvf_set_features(struct net_device *netdev, u32 features)
+{
+	struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+	if (features & NETIF_F_RXCSUM)
+		adapter->flags &= ~IGBVF_FLAG_RX_CSUM_DISABLED;
+	else
+		adapter->flags |= IGBVF_FLAG_RX_CSUM_DISABLED;
+
+	return 0;
+}
+
 static const struct net_device_ops igbvf_netdev_ops = {
 	.ndo_open                       = igbvf_open,
 	.ndo_stop                       = igbvf_close,
@@ -2562,6 +2574,7 @@ static const struct net_device_ops igbvf_netdev_ops = {
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller            = igbvf_netpoll,
 #endif
+	.ndo_set_features               = igbvf_set_features,
 };
 
 /**
@@ -2669,16 +2682,18 @@ static int __devinit igbvf_probe(struct pci_dev *pdev,
 
 	adapter->bd_number = cards_found++;
 
-	netdev->features = NETIF_F_SG |
+	netdev->hw_features = NETIF_F_SG |
 	                   NETIF_F_IP_CSUM |
+	                   NETIF_F_IPV6_CSUM |
+			   NETIF_F_TSO |
+			   NETIF_F_TSO6 |
+			   NETIF_F_RXCSUM;
+
+	netdev->features = netdev->hw_features |
 	                   NETIF_F_HW_VLAN_TX |
 	                   NETIF_F_HW_VLAN_RX |
 	                   NETIF_F_HW_VLAN_FILTER;
 
-	netdev->features |= NETIF_F_IPV6_CSUM;
-	netdev->features |= NETIF_F_TSO;
-	netdev->features |= NETIF_F_TSO6;
-
 	if (pci_using_dac)
 		netdev->features |= NETIF_F_HIGHDMA;
 
diff --git a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h
index 49e8408..cb23448 100644
--- a/drivers/net/ixgb/ixgb.h
+++ b/drivers/net/ixgb/ixgb.h
@@ -204,6 +204,8 @@ extern void ixgb_set_ethtool_ops(struct net_device *netdev);
 extern char ixgb_driver_name[];
 extern const char ixgb_driver_version[];
 
+extern void ixgb_set_speed_duplex(struct net_device *netdev);
+
 extern int ixgb_up(struct ixgb_adapter *adapter);
 extern void ixgb_down(struct ixgb_adapter *adapter, bool kill_watchdog);
 extern void ixgb_reset(struct ixgb_adapter *adapter);
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
index 6da890b..ab404e7 100644
--- a/drivers/net/ixgb/ixgb_ethtool.c
+++ b/drivers/net/ixgb/ixgb_ethtool.c
@@ -115,7 +115,7 @@ ixgb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 	return 0;
 }
 
-static void ixgb_set_speed_duplex(struct net_device *netdev)
+void ixgb_set_speed_duplex(struct net_device *netdev)
 {
 	struct ixgb_adapter *adapter = netdev_priv(netdev);
 	/* be optimistic about our link, since we were up before */
@@ -195,57 +195,6 @@ ixgb_set_pauseparam(struct net_device *netdev,
 }
 
 static u32
-ixgb_get_rx_csum(struct net_device *netdev)
-{
-	struct ixgb_adapter *adapter = netdev_priv(netdev);
-
-	return adapter->rx_csum;
-}
-
-static int
-ixgb_set_rx_csum(struct net_device *netdev, u32 data)
-{
-	struct ixgb_adapter *adapter = netdev_priv(netdev);
-
-	adapter->rx_csum = data;
-
-	if (netif_running(netdev)) {
-		ixgb_down(adapter, true);
-		ixgb_up(adapter);
-		ixgb_set_speed_duplex(netdev);
-	} else
-		ixgb_reset(adapter);
-	return 0;
-}
-
-static u32
-ixgb_get_tx_csum(struct net_device *netdev)
-{
-	return (netdev->features & NETIF_F_HW_CSUM) != 0;
-}
-
-static int
-ixgb_set_tx_csum(struct net_device *netdev, u32 data)
-{
-	if (data)
-		netdev->features |= NETIF_F_HW_CSUM;
-	else
-		netdev->features &= ~NETIF_F_HW_CSUM;
-
-	return 0;
-}
-
-static int
-ixgb_set_tso(struct net_device *netdev, u32 data)
-{
-	if (data)
-		netdev->features |= NETIF_F_TSO;
-	else
-		netdev->features &= ~NETIF_F_TSO;
-	return 0;
-}
-
-static u32
 ixgb_get_msglevel(struct net_device *netdev)
 {
 	struct ixgb_adapter *adapter = netdev_priv(netdev);
@@ -685,43 +634,6 @@ ixgb_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
 	}
 }
 
-static int ixgb_set_flags(struct net_device *netdev, u32 data)
-{
-	struct ixgb_adapter *adapter = netdev_priv(netdev);
-	bool need_reset;
-	int rc;
-
-	/*
-	 * Tx VLAN insertion does not work per HW design when Rx stripping is
-	 * disabled.  Disable txvlan when rxvlan is turned off, and enable
-	 * rxvlan when txvlan is turned on.
-	 */
-	if (!(data & ETH_FLAG_RXVLAN) &&
-	    (netdev->features & NETIF_F_HW_VLAN_TX))
-		data &= ~ETH_FLAG_TXVLAN;
-	else if (data & ETH_FLAG_TXVLAN)
-		data |= ETH_FLAG_RXVLAN;
-
-	need_reset = (data & ETH_FLAG_RXVLAN) !=
-		     (netdev->features & NETIF_F_HW_VLAN_RX);
-
-	rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_RXVLAN |
-						ETH_FLAG_TXVLAN);
-	if (rc)
-		return rc;
-
-	if (need_reset) {
-		if (netif_running(netdev)) {
-			ixgb_down(adapter, true);
-			ixgb_up(adapter);
-			ixgb_set_speed_duplex(netdev);
-		} else
-			ixgb_reset(adapter);
-	}
-
-	return 0;
-}
-
 static const struct ethtool_ops ixgb_ethtool_ops = {
 	.get_settings = ixgb_get_settings,
 	.set_settings = ixgb_set_settings,
@@ -736,20 +648,12 @@ static const struct ethtool_ops ixgb_ethtool_ops = {
 	.set_ringparam = ixgb_set_ringparam,
 	.get_pauseparam	= ixgb_get_pauseparam,
 	.set_pauseparam	= ixgb_set_pauseparam,
-	.get_rx_csum = ixgb_get_rx_csum,
-	.set_rx_csum = ixgb_set_rx_csum,
-	.get_tx_csum = ixgb_get_tx_csum,
-	.set_tx_csum = ixgb_set_tx_csum,
-	.set_sg	= ethtool_op_set_sg,
 	.get_msglevel = ixgb_get_msglevel,
 	.set_msglevel = ixgb_set_msglevel,
-	.set_tso = ixgb_set_tso,
 	.get_strings = ixgb_get_strings,
 	.set_phys_id = ixgb_set_phys_id,
 	.get_sset_count = ixgb_get_sset_count,
 	.get_ethtool_stats = ixgb_get_ethtool_stats,
-	.get_flags = ethtool_op_get_flags,
-	.set_flags = ixgb_set_flags,
 };
 
 void ixgb_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index 6a130eb..a2c47bf 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -325,6 +325,40 @@ ixgb_reset(struct ixgb_adapter *adapter)
 	}
 }
 
+static u32
+ixgb_fix_features(struct net_device *netdev, u32 features)
+{
+	/*
+	 * Tx VLAN insertion does not work per HW design when Rx stripping is
+	 * disabled.
+	 */
+	if (!(features & NETIF_F_HW_VLAN_RX))
+		features &= ~NETIF_F_HW_VLAN_TX;
+
+	return features;
+}
+
+static int
+ixgb_set_features(struct net_device *netdev, u32 features)
+{
+	struct ixgb_adapter *adapter = netdev_priv(netdev);
+	u32 changed = features ^ netdev->features;
+
+	if (!(changed & (NETIF_F_RXCSUM|NETIF_F_HW_VLAN_RX)))
+		return 0;
+
+	adapter->rx_csum = !!(features & NETIF_F_RXCSUM);
+
+	if (netif_running(netdev)) {
+		ixgb_down(adapter, true);
+		ixgb_up(adapter);
+		ixgb_set_speed_duplex(netdev);
+	} else
+		ixgb_reset(adapter);
+
+	return 0;
+}
+
 static const struct net_device_ops ixgb_netdev_ops = {
 	.ndo_open 		= ixgb_open,
 	.ndo_stop		= ixgb_close,
@@ -334,6 +368,8 @@ static const struct net_device_ops ixgb_netdev_ops = {
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_set_mac_address	= ixgb_set_mac,
 	.ndo_change_mtu		= ixgb_change_mtu,
+	.ndo_fix_features       = ixgb_fix_features,
+	.ndo_set_features       = ixgb_set_features,
 	.ndo_tx_timeout		= ixgb_tx_timeout,
 	.ndo_vlan_rx_add_vid	= ixgb_vlan_rx_add_vid,
 	.ndo_vlan_rx_kill_vid	= ixgb_vlan_rx_kill_vid,
@@ -439,12 +475,14 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	if (err)
 		goto err_sw_init;
 
-	netdev->features = NETIF_F_SG |
-			   NETIF_F_HW_CSUM |
+	netdev->hw_features = NETIF_F_SG |
+			   NETIF_F_TSO |
+			   NETIF_F_HW_CSUM;
+	netdev->features = netdev->hw_features |
 			   NETIF_F_HW_VLAN_TX |
 			   NETIF_F_HW_VLAN_RX |
 			   NETIF_F_HW_VLAN_FILTER;
-	netdev->features |= NETIF_F_TSO;
+	netdev->hw_features |= NETIF_F_RXCSUM;
 
 	if (pci_using_dac) {
 		netdev->features |= NETIF_F_HIGHDMA;
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 4950d03..38ee164 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -442,62 +442,6 @@ static int ixgbe_set_pauseparam(struct net_device *netdev,
 	return 0;
 }
 
-static u32 ixgbe_get_rx_csum(struct net_device *netdev)
-{
-	struct ixgbe_adapter *adapter = netdev_priv(netdev);
-	return adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED;
-}
-
-static int ixgbe_set_rx_csum(struct net_device *netdev, u32 data)
-{
-	struct ixgbe_adapter *adapter = netdev_priv(netdev);
-	if (data)
-		adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED;
-	else
-		adapter->flags &= ~IXGBE_FLAG_RX_CSUM_ENABLED;
-
-	return 0;
-}
-
-static u32 ixgbe_get_tx_csum(struct net_device *netdev)
-{
-	return (netdev->features & NETIF_F_IP_CSUM) != 0;
-}
-
-static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data)
-{
-	struct ixgbe_adapter *adapter = netdev_priv(netdev);
-	u32 feature_list;
-
-	feature_list = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
-	switch (adapter->hw.mac.type) {
-	case ixgbe_mac_82599EB:
-	case ixgbe_mac_X540:
-		feature_list |= NETIF_F_SCTP_CSUM;
-		break;
-	default:
-		break;
-	}
-	if (data)
-		netdev->features |= feature_list;
-	else
-		netdev->features &= ~feature_list;
-
-	return 0;
-}
-
-static int ixgbe_set_tso(struct net_device *netdev, u32 data)
-{
-	if (data) {
-		netdev->features |= NETIF_F_TSO;
-		netdev->features |= NETIF_F_TSO6;
-	} else {
-		netdev->features &= ~NETIF_F_TSO;
-		netdev->features &= ~NETIF_F_TSO6;
-	}
-	return 0;
-}
-
 static u32 ixgbe_get_msglevel(struct net_device *netdev)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
@@ -2244,65 +2188,60 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
 	return 0;
 }
 
-static int ixgbe_set_flags(struct net_device *netdev, u32 data)
+u32 ixgbe_fix_features(struct net_device *netdev, u32 features)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
-	bool need_reset = false;
-	int rc;
 
 #ifdef CONFIG_IXGBE_DCB
-	if ((adapter->flags & IXGBE_FLAG_DCB_ENABLED) &&
-	    !(data & ETH_FLAG_RXVLAN))
-		return -EINVAL;
+	if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
+		features |= NETIF_F_HW_VLAN_RX;
 #endif
 
-	need_reset = (data & ETH_FLAG_RXVLAN) !=
-		     (netdev->features & NETIF_F_HW_VLAN_RX);
-
-	if ((data & ETH_FLAG_RXHASH) &&
-	    !(adapter->flags & IXGBE_FLAG_RSS_ENABLED))
-		return -EOPNOTSUPP;
-
-	rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_LRO | ETH_FLAG_NTUPLE |
-				  ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN |
-				  ETH_FLAG_RXHASH);
-	if (rc)
-		return rc;
-
-	/* if state changes we need to update adapter->flags and reset */
-	if ((adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) &&
-	    (!!(data & ETH_FLAG_LRO) !=
-	     !!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))) {
-		if ((data & ETH_FLAG_LRO) &&
-		    (!adapter->rx_itr_setting ||
-		     (adapter->rx_itr_setting > IXGBE_MAX_RSC_INT_RATE))) {
+	if (!adapter->rx_itr_setting ||
+	    adapter->rx_itr_setting > IXGBE_MAX_RSC_INT_RATE) {
+		if (features & NETIF_F_LRO)
 			e_info(probe, "rx-usecs set too low, "
 				      "not enabling RSC.\n");
-		} else {
-			adapter->flags2 ^= IXGBE_FLAG2_RSC_ENABLED;
-			switch (adapter->hw.mac.type) {
-			case ixgbe_mac_82599EB:
-				need_reset = true;
-				break;
-			case ixgbe_mac_X540: {
-				int i;
-				for (i = 0; i < adapter->num_rx_queues; i++) {
-					struct ixgbe_ring *ring =
-					                  adapter->rx_ring[i];
-					if (adapter->flags2 &
-					    IXGBE_FLAG2_RSC_ENABLED) {
-						ixgbe_configure_rscctl(adapter,
-						                       ring);
-					} else {
-						ixgbe_clear_rscctl(adapter,
-						                   ring);
-					}
-				}
+		features &= ~NETIF_F_LRO;
+	}
+
+	if (!(adapter->flags & IXGBE_FLAG_RSS_ENABLED))
+		features &= ~NETIF_F_RXHASH;
+
+	return features;
+}
+
+int ixgbe_set_features(struct net_device *netdev, u32 features)
+{
+	struct ixgbe_adapter *adapter = netdev_priv(netdev);
+	u32 changed = netdev->features ^ features;
+	bool need_reset = !!(changed & NETIF_F_HW_VLAN_RX);
+
+	if (features & NETIF_F_RXCSUM)
+		adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED;
+	else
+		adapter->flags &= ~IXGBE_FLAG_RX_CSUM_ENABLED;
+
+	/* if state changes we need to update adapter->flags and reset */
+	if (changed & NETIF_F_LRO) {
+		adapter->flags2 ^= IXGBE_FLAG2_RSC_ENABLED;
+		switch (adapter->hw.mac.type) {
+		case ixgbe_mac_82599EB:
+			need_reset = true;
+			break;
+		case ixgbe_mac_X540: {
+			int i;
+			for (i = 0; i < adapter->num_rx_queues; i++) {
+				struct ixgbe_ring *ring = adapter->rx_ring[i];
+				if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)
+					ixgbe_configure_rscctl(adapter, ring);
+				else
+					ixgbe_clear_rscctl(adapter, ring);
 			}
-				break;
-			default:
-				break;
+			break;
 			}
+		default:
+			break;
 		}
 	}
 
@@ -2310,20 +2249,17 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data)
 	 * Check if Flow Director n-tuple support was enabled or disabled.  If
 	 * the state changed, we need to reset.
 	 */
-	if ((adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) &&
-	    (!(data & ETH_FLAG_NTUPLE))) {
-		/* turn off Flow Director perfect, set hash and reset */
-		adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
-		adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE;
+	if (changed & NETIF_F_NTUPLE) {
+		if (features & NETIF_F_NTUPLE) {
+			/* turn off Flow Director hash, enable perfect and reset */
+			adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE;
+			adapter->flags |= IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
+		} else {
+			/* turn off Flow Director perfect, set hash and reset */
+			adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
+			adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE;
+		}
 		need_reset = true;
-	} else if ((!(adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) &&
-	           (data & ETH_FLAG_NTUPLE)) {
-		/* turn off Flow Director hash, enable perfect and reset */
-		adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE;
-		adapter->flags |= IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
-		need_reset = true;
-	} else {
-		/* no state change */
 	}
 
 	if (need_reset) {
@@ -2487,16 +2423,8 @@ static const struct ethtool_ops ixgbe_ethtool_ops = {
 	.set_ringparam          = ixgbe_set_ringparam,
 	.get_pauseparam         = ixgbe_get_pauseparam,
 	.set_pauseparam         = ixgbe_set_pauseparam,
-	.get_rx_csum            = ixgbe_get_rx_csum,
-	.set_rx_csum            = ixgbe_set_rx_csum,
-	.get_tx_csum            = ixgbe_get_tx_csum,
-	.set_tx_csum            = ixgbe_set_tx_csum,
-	.get_sg                 = ethtool_op_get_sg,
-	.set_sg                 = ethtool_op_set_sg,
 	.get_msglevel           = ixgbe_get_msglevel,
 	.set_msglevel           = ixgbe_set_msglevel,
-	.get_tso                = ethtool_op_get_tso,
-	.set_tso                = ixgbe_set_tso,
 	.self_test              = ixgbe_diag_test,
 	.get_strings            = ixgbe_get_strings,
 	.set_phys_id            = ixgbe_set_phys_id,
@@ -2504,8 +2432,6 @@ static const struct ethtool_ops ixgbe_ethtool_ops = {
 	.get_ethtool_stats      = ixgbe_get_ethtool_stats,
 	.get_coalesce           = ixgbe_get_coalesce,
 	.set_coalesce           = ixgbe_set_coalesce,
-	.get_flags              = ethtool_op_get_flags,
-	.set_flags              = ixgbe_set_flags,
 	.set_rx_ntuple          = ixgbe_set_rx_ntuple,
 };
 
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 06cfaf3..1a77310 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -7199,6 +7199,8 @@ static struct rtnl_link_stats64 *ixgbe_get_stats64(struct net_device *netdev,
 	return stats;
 }
 
+u32 ixgbe_fix_features(struct net_device *netdev, u32 features);
+int ixgbe_set_features(struct net_device *netdev, u32 features);
 
 static const struct net_device_ops ixgbe_netdev_ops = {
 	.ndo_open		= ixgbe_open,
@@ -7233,6 +7235,8 @@ static const struct net_device_ops ixgbe_netdev_ops = {
 	.ndo_fcoe_disable = ixgbe_fcoe_disable,
 	.ndo_fcoe_get_wwn = ixgbe_fcoe_get_wwn,
 #endif /* IXGBE_FCOE */
+	.ndo_fix_features = ixgbe_fix_features,
+	.ndo_set_features = ixgbe_set_features,
 };
 
 static void __devinit ixgbe_probe_vf(struct ixgbe_adapter *adapter,
@@ -7496,27 +7500,32 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
 
 	ixgbe_probe_vf(adapter, ii);
 
-	netdev->features = NETIF_F_SG |
+	netdev->hw_features = NETIF_F_SG |
 			   NETIF_F_IP_CSUM |
+			   NETIF_F_IPV6_CSUM |
+			   NETIF_F_TSO |
+			   NETIF_F_TSO6 |
+			   NETIF_F_RXCSUM |
 			   NETIF_F_HW_VLAN_TX |
 			   NETIF_F_HW_VLAN_RX |
+			   NETIF_F_NTUPLE |
+			   NETIF_F_RXHASH;
+
+	if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)
+		netdev->hw_features |= NETIF_F_LRO;
+
+	switch (adapter->hw.mac.type) {
+	case ixgbe_mac_82599EB:
+	case ixgbe_mac_X540:
+		netdev->hw_features |= NETIF_F_SCTP_CSUM;
+		break;
+	default:
+		break;
+	}
+
+	netdev->features = netdev->hw_features |
 			   NETIF_F_HW_VLAN_FILTER;
 
-	netdev->features |= NETIF_F_IPV6_CSUM;
-	netdev->features |= NETIF_F_TSO;
-	netdev->features |= NETIF_F_TSO6;
-	netdev->features |= NETIF_F_GRO;
-	netdev->features |= NETIF_F_RXHASH;
-
-	switch (adapter->hw.mac.type) {
-	case ixgbe_mac_82599EB:
-	case ixgbe_mac_X540:
-		netdev->features |= NETIF_F_SCTP_CSUM;
-		break;
-	default:
-		break;
-	}
-
 	netdev->vlan_features |= NETIF_F_TSO;
 	netdev->vlan_features |= NETIF_F_TSO6;
 	netdev->vlan_features |= NETIF_F_IP_CSUM;
diff --git a/drivers/net/ixgbevf/ethtool.c b/drivers/net/ixgbevf/ethtool.c
index deee375..e1d9e3b 100644
--- a/drivers/net/ixgbevf/ethtool.c
+++ b/drivers/net/ixgbevf/ethtool.c
@@ -117,44 +117,6 @@ static int ixgbevf_get_settings(struct net_device *netdev,
 	return 0;
 }
 
-static u32 ixgbevf_get_rx_csum(struct net_device *netdev)
-{
-	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
-	return adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED;
-}
-
-static int ixgbevf_set_rx_csum(struct net_device *netdev, u32 data)
-{
-	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
-	if (data)
-		adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED;
-	else
-		adapter->flags &= ~IXGBE_FLAG_RX_CSUM_ENABLED;
-
-	if (netif_running(netdev)) {
-		if (!adapter->dev_closed)
-			ixgbevf_reinit_locked(adapter);
-	} else {
-		ixgbevf_reset(adapter);
-	}
-
-	return 0;
-}
-
-static int ixgbevf_set_tso(struct net_device *netdev, u32 data)
-{
-	if (data) {
-		netdev->features |= NETIF_F_TSO;
-		netdev->features |= NETIF_F_TSO6;
-	} else {
-		netif_tx_stop_all_queues(netdev);
-		netdev->features &= ~NETIF_F_TSO;
-		netdev->features &= ~NETIF_F_TSO6;
-		netif_tx_start_all_queues(netdev);
-	}
-	return 0;
-}
-
 static u32 ixgbevf_get_msglevel(struct net_device *netdev)
 {
 	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
@@ -720,16 +682,8 @@ static struct ethtool_ops ixgbevf_ethtool_ops = {
 	.get_link               = ethtool_op_get_link,
 	.get_ringparam          = ixgbevf_get_ringparam,
 	.set_ringparam          = ixgbevf_set_ringparam,
-	.get_rx_csum            = ixgbevf_get_rx_csum,
-	.set_rx_csum            = ixgbevf_set_rx_csum,
-	.get_tx_csum            = ethtool_op_get_tx_csum,
-	.set_tx_csum            = ethtool_op_set_tx_ipv6_csum,
-	.get_sg                 = ethtool_op_get_sg,
-	.set_sg                 = ethtool_op_set_sg,
 	.get_msglevel           = ixgbevf_get_msglevel,
 	.set_msglevel           = ixgbevf_set_msglevel,
-	.get_tso                = ethtool_op_get_tso,
-	.set_tso                = ixgbevf_set_tso,
 	.self_test              = ixgbevf_diag_test,
 	.get_sset_count         = ixgbevf_get_sset_count,
 	.get_strings            = ixgbevf_get_strings,
diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c
index b2c5ecd..8c2be31 100644
--- a/drivers/net/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ixgbevf/ixgbevf_main.c
@@ -3248,6 +3248,19 @@ static void ixgbevf_shutdown(struct pci_dev *pdev)
 	pci_disable_device(pdev);
 }
 
+static int ixgbevf_set_features(struct net_device *netdev, u32 features)
+{
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+
+	if (features & NETIF_F_RXCSUM)
+		adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED;
+	else
+		adapter->flags &= ~IXGBE_FLAG_RX_CSUM_ENABLED;
+
+	return 0;
+}
+
+
 static const struct net_device_ops ixgbe_netdev_ops = {
 	.ndo_open		= &ixgbevf_open,
 	.ndo_stop		= &ixgbevf_close,
@@ -3261,6 +3274,7 @@ static const struct net_device_ops ixgbe_netdev_ops = {
 	.ndo_vlan_rx_register	= &ixgbevf_vlan_rx_register,
 	.ndo_vlan_rx_add_vid	= &ixgbevf_vlan_rx_add_vid,
 	.ndo_vlan_rx_kill_vid	= &ixgbevf_vlan_rx_kill_vid,
+	.ndo_set_features       = ixgbevf_set_features,
 };
 
 static void ixgbevf_assign_netdev_ops(struct net_device *dev)
@@ -3373,16 +3387,18 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev,
 	/* setup the private structure */
 	err = ixgbevf_sw_init(adapter);
 
-	netdev->features = NETIF_F_SG |
+	netdev->hw_features = NETIF_F_SG |
 			   NETIF_F_IP_CSUM |
+			   NETIF_F_IPV6_CSUM |
+			   NETIF_F_TSO |
+			   NETIF_F_TSO6 |
+			   NETIF_F_RXCSUM;
+
+	netdev->features = netdev->hw_features |
 			   NETIF_F_HW_VLAN_TX |
 			   NETIF_F_HW_VLAN_RX |
 			   NETIF_F_HW_VLAN_FILTER;
 
-	netdev->features |= NETIF_F_IPV6_CSUM;
-	netdev->features |= NETIF_F_TSO;
-	netdev->features |= NETIF_F_TSO6;
-	netdev->features |= NETIF_F_GRO;
 	netdev->vlan_features |= NETIF_F_TSO;
 	netdev->vlan_features |= NETIF_F_TSO6;
 	netdev->vlan_features |= NETIF_F_IP_CSUM;
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [RFT PATCH 3/9] net: ethtool: break association of ETH_FLAG_* with NETIF_F_*
  2011-06-20 19:14 ` [RFT PATCH 3/9] net: ethtool: break association of ETH_FLAG_* with NETIF_F_* Michał Mirosław
@ 2011-06-20 20:11   ` Ben Hutchings
  2011-06-20 20:27     ` David Miller
  2011-06-20 20:51     ` Stephen Hemminger
  0 siblings, 2 replies; 28+ messages in thread
From: Ben Hutchings @ 2011-06-20 20:11 UTC (permalink / raw)
  To: Michał Mirosław; +Cc: netdev, David S. Miller, Stephen Hemminger

On Mon, 2011-06-20 at 21:14 +0200, Michał Mirosław wrote:
> This is the only place where NETIF_F_* feature flags are exposed
> to userspace.

Except sysfs.

> After this patch feature flags may be changed/reordered freely.
[...]

Really, what do you think was the point of exposing features through
sysfs if they are going to be changed?

Oh, but they have been changed already:

v2.5.70
net-sysfs added

v2.6.15
+#define NETIF_F_UFO             8192    /* Can offload UDP Large Send*/

v2.6.18
-#define NETIF_F_TSO            2048    /* Can offload TCP/IP segmentation */
-#define NETIF_F_UFO             8192    /* Can offload UDP Large Send*/
+#define NETIF_F_GSO            2048    /* Enable software GSO. */
+#define NETIF_F_GSO_SHIFT      16
+#define NETIF_F_TSO            (SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT)
+#define NETIF_F_UFO            (SKB_GSO_UDP << NETIF_F_GSO_SHIFT)
+#define NETIF_F_GSO_ROBUST     (SKB_GSO_DODGY << NETIF_F_GSO_SHIFT)
+#define NETIF_F_TSO_ECN                (SKB_GSO_TCP_ECN << NETIF_F_GSO_SHIFT)
+#define NETIF_F_TSO6           (SKB_GSO_TCPV6 << NETIF_F_GSO_SHIFT)

v2.6.23
+#define NETIF_F_IPV6_CSUM      16      /* Can checksum TCP/UDP over IPV6 */
+#define NETIF_F_MULTI_QUEUE    16384   /* Has multiple TX/RX queues */

v2.6.24
+#define NETIF_F_NETNS_LOCAL    8192    /* Does not change network namespaces */

v2.6.27
-#define NETIF_F_MULTI_QUEUE    16384   /* Has multiple TX/RX queues */

v2.6.29
+#define NETIF_F_GRO            16384   /* Generic receive offload */

(I've omitted changes that use previously unused bits.)

If we're going to keep changing features (maybe even more often) then we
have to do something about this sysfs attribute.  Maybe get rid of it
(as it seems not to be widely used, thankfully).  Maybe fix it to use
the same feature values as today, but no new features.  But certainly
don't pretend that feature flags are not exposed.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFT PATCH 3/9] net: ethtool: break association of ETH_FLAG_* with NETIF_F_*
  2011-06-20 20:11   ` Ben Hutchings
@ 2011-06-20 20:27     ` David Miller
  2011-06-20 20:51     ` Stephen Hemminger
  1 sibling, 0 replies; 28+ messages in thread
From: David Miller @ 2011-06-20 20:27 UTC (permalink / raw)
  To: bhutchings; +Cc: mirq-linux, netdev, shemminger

From: Ben Hutchings <bhutchings@solarflare.com>
Date: Mon, 20 Jun 2011 21:11:21 +0100

> If we're going to keep changing features (maybe even more often) then we
> have to do something about this sysfs attribute.  Maybe get rid of it
> (as it seems not to be widely used, thankfully).  Maybe fix it to use
> the same feature values as today, but no new features.  But certainly
> don't pretend that feature flags are not exposed.

I'd say we just kill it off, our hands are tied too tightly otherwise.

And this ties in to our efforts to expand netdev->features to a larger
type.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFT PATCH 3/9] net: ethtool: break association of ETH_FLAG_* with NETIF_F_*
  2011-06-20 20:11   ` Ben Hutchings
  2011-06-20 20:27     ` David Miller
@ 2011-06-20 20:51     ` Stephen Hemminger
  2011-06-20 20:52       ` David Miller
  1 sibling, 1 reply; 28+ messages in thread
From: Stephen Hemminger @ 2011-06-20 20:51 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: Michał Mirosław, netdev, David S. Miller

On Mon, 20 Jun 2011 21:11:21 +0100
Ben Hutchings <bhutchings@solarflare.com> wrote:

> On Mon, 2011-06-20 at 21:14 +0200, Michał Mirosław wrote:
> > This is the only place where NETIF_F_* feature flags are exposed
> > to userspace.
> 
> Except sysfs.
> 
> > After this patch feature flags may be changed/reordered freely.
> [...]
> 
> Really, what do you think was the point of exposing features through
> sysfs if they are going to be changed?
> 
> Oh, but they have been changed already:
> 
> v2.5.70
> net-sysfs added
> 
> v2.6.15
> +#define NETIF_F_UFO             8192    /* Can offload UDP Large Send*/
> 
> v2.6.18
> -#define NETIF_F_TSO            2048    /* Can offload TCP/IP segmentation */
> -#define NETIF_F_UFO             8192    /* Can offload UDP Large Send*/
> +#define NETIF_F_GSO            2048    /* Enable software GSO. */
> +#define NETIF_F_GSO_SHIFT      16
> +#define NETIF_F_TSO            (SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT)
> +#define NETIF_F_UFO            (SKB_GSO_UDP << NETIF_F_GSO_SHIFT)
> +#define NETIF_F_GSO_ROBUST     (SKB_GSO_DODGY << NETIF_F_GSO_SHIFT)
> +#define NETIF_F_TSO_ECN                (SKB_GSO_TCP_ECN << NETIF_F_GSO_SHIFT)
> +#define NETIF_F_TSO6           (SKB_GSO_TCPV6 << NETIF_F_GSO_SHIFT)
> 
> v2.6.23
> +#define NETIF_F_IPV6_CSUM      16      /* Can checksum TCP/UDP over IPV6 */
> +#define NETIF_F_MULTI_QUEUE    16384   /* Has multiple TX/RX queues */
> 
> v2.6.24
> +#define NETIF_F_NETNS_LOCAL    8192    /* Does not change network namespaces */
> 
> v2.6.27
> -#define NETIF_F_MULTI_QUEUE    16384   /* Has multiple TX/RX queues */
> 
> v2.6.29
> +#define NETIF_F_GRO            16384   /* Generic receive offload */
> 
> (I've omitted changes that use previously unused bits.)
> 
> If we're going to keep changing features (maybe even more often) then we
> have to do something about this sysfs attribute.  Maybe get rid of it
> (as it seems not to be widely used, thankfully).  Maybe fix it to use
> the same feature values as today, but no new features.  But certainly
> don't pretend that feature flags are not exposed.
> 
> Ben.
> 


I have no problem with dropping or changing the sysfs feature output.
It is useful to have a way to check if device supports something. Sysfs
predates the feature support bits of ethtool. As long as ethtool supports
it then I am fine with that.

It would be nice to have a non-grotty way of doing something like:
  if ethtool eth0 --supports gro 
  then
       ...
  fi


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFT PATCH 3/9] net: ethtool: break association of ETH_FLAG_* with NETIF_F_*
  2011-06-20 20:51     ` Stephen Hemminger
@ 2011-06-20 20:52       ` David Miller
  2011-06-20 21:30         ` Ben Hutchings
  0 siblings, 1 reply; 28+ messages in thread
From: David Miller @ 2011-06-20 20:52 UTC (permalink / raw)
  To: shemminger; +Cc: bhutchings, mirq-linux, netdev

From: Stephen Hemminger <shemminger@vyatta.com>
Date: Mon, 20 Jun 2011 13:51:09 -0700

> I have no problem with dropping or changing the sysfs feature output.
> It is useful to have a way to check if device supports something.

These days that's not even where we store the "capabilities" of the
device.

That happens in ->hw_features now.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFT PATCH 4/9] net: introduce and use netdev_features_t for device features sets
  2011-06-20 19:14 ` [RFT PATCH 4/9] net: introduce and use netdev_features_t for device features sets Michał Mirosław
@ 2011-06-20 21:01   ` Ben Hutchings
  0 siblings, 0 replies; 28+ messages in thread
From: Ben Hutchings @ 2011-06-20 21:01 UTC (permalink / raw)
  To: Michał Mirosław; +Cc: netdev, David S. Miller

On Mon, 2011-06-20 at 21:14 +0200, Michał Mirosław wrote:
> The type and bits definitions are moved to separate header so that
> linux/skbuff.h won't need to include linux/netdevice.h.
[...]
> diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
> index c914729..ca869c0 100644
> --- a/drivers/net/sfc/efx.c
> +++ b/drivers/net/sfc/efx.c
> @@ -1883,7 +1883,7 @@ static void efx_set_multicast_list(struct net_device *net_dev)
>  	/* Otherwise efx_start_port() will do this */
>  }
>  
> -static int efx_set_features(struct net_device *net_dev, u32 data)
> +static int efx_set_features(struct net_device *net_dev, netdev_features_t data)
>  {
>  	struct efx_nic *efx = netdev_priv(net_dev);
>  

The type of efx_nic_type::offload_features, defined in
drivers/net/sfc/net_driver.h, will also need to be changed.

[...]
> --- /dev/null
> +++ b/include/linux/netdev_features.h
[...]
> +	/* Segmentation offload features */
[...]
> +	/* Features valid for ethtool to change */
> +	/* = all defined minus driver/device-class-related */
[...]
> +	/* List of features with software fallbacks. */
[...]
> +	/*
> +	 * If one device supports one of these features, then enable them
> +	 * for all in netdev_increment_features.
> +	 */
[...]
> +	/*
> +	 * If one device doesn't support one of these features, then disable it
> +	 * for all in netdev_increment_features.
> +	 */
[...]
> +	/* changeable features with no special hardware requirements */
[...]

A cosmetic detail: these comments should no longer be indented.

[...]
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 3041b6ae..a5a0e76 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
[...]
> @@ -1872,8 +1872,8 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, u32 features)
>  		if (dev && dev->ethtool_ops && dev->ethtool_ops->get_drvinfo)
>  			dev->ethtool_ops->get_drvinfo(dev, &info);
>  
> -		WARN(1, "%s: caps=(0x%lx, 0x%lx) len=%d data_len=%d ip_summed=%d\n",
> -		     info.driver, dev ? dev->features : 0L,
> +		WARN(1, "%s: caps=(0x%llx, 0x%lx) len=%d data_len=%d ip_summed=%d\n",
> +		     info.driver, dev ? (long long)dev->features : 0LL,
> 		     skb->sk ? skb->sk->sk_route_caps : 0L,
> 		     skb->len, skb->data_len, skb->ip_summed);

The types of sock::sk_route_caps and sock::sk_route_nocaps also need to
be fixed (they are still int and not even unsigned!).

[...]
> @@ -5250,11 +5252,10 @@ u32 netdev_fix_features(struct net_device *dev, u32 features)
>  
>  	return features;
>  }
> -EXPORT_SYMBOL(netdev_fix_features);

I don't think that change belongs in this patch!

[...]
> @@ -5270,8 +5271,10 @@ int __netdev_update_features(struct net_device *dev)
>  	if (dev->features == features)
>  		return 0;
>  
> +	BUILD_BUG_ON(sizeof(features) != sizeof(u32));	/* XXX: need: %Fx */
> +
>  	netdev_dbg(dev, "Features changed: 0x%08x -> 0x%08x\n",
> -		dev->features, features);
> +		(u32)dev->features, (u32)features);
[...]

You could either define macros for this:

#define NETDEV_FEATURES_FMT			"0x%08x"
#define NETDEV_FEATURES_FMT_ARG(features)	features

or follow the current trend of extending %p and passing a pointer to the
value.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFT PATCH 7/9] ethtool: prepare for larger netdev_features_t type
  2011-06-20 19:14 ` [RFT PATCH 7/9] ethtool: prepare for larger netdev_features_t type Michał Mirosław
@ 2011-06-20 21:16   ` Ben Hutchings
  2011-06-23 17:50     ` Mahesh Bandewar
  0 siblings, 1 reply; 28+ messages in thread
From: Ben Hutchings @ 2011-06-20 21:16 UTC (permalink / raw)
  To: Michał Mirosław; +Cc: netdev, David S. Miller

On Mon, 2011-06-20 at 21:14 +0200, Michał Mirosław wrote:
[...]
> @@ -125,19 +131,26 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
>  	if (copy_from_user(features, useraddr, sizeof(features)))
>  		return -EFAULT;
>  
> -	if (features[0].valid & ~NETIF_F_ETHTOOL_BITS)
> +	/* I wonder if the compiler will be smart enough to loop-unroll
> +	 * and optimize this... (no worries if not) --mq */
> +	for (i = ETHTOOL_DEV_FEATURE_WORDS; i-- > 0; ) {
> +		valid = (valid << 32)|features[i].valid;
> +		wanted = (wanted << 32)|features[i].requested;
> +	}
[...]

I don't know (or care) about optimisation of this, but I would expect
gcc to complain about shifting a 32-bit value by 32 bits.  I suggest you
write this as:

	for (i = 0; i < ETHTOOL_DEV_FEATURE_WORDS; ++i) {
		valid |= (netdev_features_t)features[i].valid << 32 *i;
		wanted |= (netdev_features_t)features[i].requested << 32 *i;
	}

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFT PATCH 3/9] net: ethtool: break association of ETH_FLAG_* with NETIF_F_*
  2011-06-20 20:52       ` David Miller
@ 2011-06-20 21:30         ` Ben Hutchings
  0 siblings, 0 replies; 28+ messages in thread
From: Ben Hutchings @ 2011-06-20 21:30 UTC (permalink / raw)
  To: David Miller; +Cc: shemminger, mirq-linux, netdev

On Mon, 2011-06-20 at 13:52 -0700, David Miller wrote:
> From: Stephen Hemminger <shemminger@vyatta.com>
> Date: Mon, 20 Jun 2011 13:51:09 -0700
> 
> > I have no problem with dropping or changing the sysfs feature output.
> > It is useful to have a way to check if device supports something.
> 
> These days that's not even where we store the "capabilities" of the
> device.
> 
> That happens in ->hw_features now.

In fact there never used to be any way for user-space to find out which
capabilities were *supported*, other than to try enabling them.

Once we work out how to deal with kernel-named features in ethtool it
shouldn't be too hard to add options to (quietly) test whether a given
feature is supported or enabled.  Having done that, we could think about
a fallback to sysfs and knowledge of the bit definitions for older
kernel versions.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFT PATCH 0/9] Cleanup and extension of netdev features
  2011-06-20 19:14 [RFT PATCH 0/9] Cleanup and extension of netdev features Michał Mirosław
                   ` (8 preceding siblings ...)
  2011-06-20 19:35 ` [RFT PATCH 0/9] Cleanup and extension of netdev features David Miller
@ 2011-06-21 21:43 ` Ben Greear
  2011-06-21 21:52   ` Ben Hutchings
  2011-06-21 23:27   ` Jeff Kirsher
  2011-06-23 17:42 ` Mahesh Bandewar
  10 siblings, 2 replies; 28+ messages in thread
From: Ben Greear @ 2011-06-21 21:43 UTC (permalink / raw)
  To: Michał Mirosław; +Cc: netdev, David S. Miller, Ben Hutchings

On 06/20/2011 12:14 PM, Michał Mirosław wrote:
> This is a preview of the cleanups pending after getting rid of old
> ethtool ops from remaining drivers.

Even when skipping patch 1 (seems this was just merged earlier today),
these patches do not all apply to net-next.

They are also full of white-space warnings.

Please re-post them when you sync against upstream
and I'll try to do some testing.

Also, do you have a cooresponding patch against ethtool
to make it able to handle the new 64-bit flags?

Thanks,
Ben

-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFT PATCH 0/9] Cleanup and extension of netdev features
  2011-06-21 21:43 ` [RFT PATCH 0/9] Cleanup and extension of netdev features Ben Greear
@ 2011-06-21 21:52   ` Ben Hutchings
  2011-06-21 23:27   ` Jeff Kirsher
  1 sibling, 0 replies; 28+ messages in thread
From: Ben Hutchings @ 2011-06-21 21:52 UTC (permalink / raw)
  To: Ben Greear; +Cc: Michał Mirosław, netdev, David S. Miller

On Tue, 2011-06-21 at 14:43 -0700, Ben Greear wrote:
> On 06/20/2011 12:14 PM, Michał Mirosław wrote:
> > This is a preview of the cleanups pending after getting rid of old
> > ethtool ops from remaining drivers.
> 
> Even when skipping patch 1 (seems this was just merged earlier today),
> these patches do not all apply to net-next.
> 
> They are also full of white-space warnings.
> 
> Please re-post them when you sync against upstream
> and I'll try to do some testing.
> 
> Also, do you have a cooresponding patch against ethtool
> to make it able to handle the new 64-bit flags?

It doesn't handle named features at all yet, though Michał has
previously prepared patches to do so.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFT PATCH 0/9] Cleanup and extension of netdev features
  2011-06-21 21:43 ` [RFT PATCH 0/9] Cleanup and extension of netdev features Ben Greear
  2011-06-21 21:52   ` Ben Hutchings
@ 2011-06-21 23:27   ` Jeff Kirsher
  1 sibling, 0 replies; 28+ messages in thread
From: Jeff Kirsher @ 2011-06-21 23:27 UTC (permalink / raw)
  To: Ben Greear
  Cc: Michał Mirosław, netdev, David S. Miller, Ben Hutchings

2011/6/21 Ben Greear <greearb@candelatech.com>:
> On 06/20/2011 12:14 PM, Michał Mirosław wrote:
>>
>> This is a preview of the cleanups pending after getting rid of old
>> ethtool ops from remaining drivers.
>
> Even when skipping patch 1 (seems this was just merged earlier today),
> these patches do not all apply to net-next.
>

Not all of patch was merged earlier today, just the update to e1000
and igbvf.  I still have e1000e, igb, ixgb, ixgbe and ixgbevf patches
still being worked on.  I do apologize for delay.

-- 
Cheers,
Jeff

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFT PATCH 0/9] Cleanup and extension of netdev features
  2011-06-20 19:14 [RFT PATCH 0/9] Cleanup and extension of netdev features Michał Mirosław
                   ` (9 preceding siblings ...)
  2011-06-21 21:43 ` [RFT PATCH 0/9] Cleanup and extension of netdev features Ben Greear
@ 2011-06-23 17:42 ` Mahesh Bandewar
  10 siblings, 0 replies; 28+ messages in thread
From: Mahesh Bandewar @ 2011-06-23 17:42 UTC (permalink / raw)
  To: Michał Mirosław; +Cc: netdev, David S. Miller, Ben Hutchings

On Mon, Jun 20, 2011 at 12:14 PM, Michał Mirosław
<mirq-linux@rere.qmqm.pl> wrote:
>
> This is a preview of the cleanups pending after getting rid of old
> ethtool ops from remaining drivers.
>
> Patches inside:
>  1. (placeholder for Intel patches)
>  2. removal of old ethtool ops
>        (most further patches depend on this one)
>  3. break association of ETH_FLAG_* with netdev features
>        this will allow to change the representation and access pattern
>        of the feature sets if later needed; as a bonus, the features
>        can be (almost) freely rearranged
>  4. introducing netdev_features_t
>        use new type wherever features are passed around (this needed
>        new include - otherwise linux/skbuff.h would need linux/netdevice.h)
>  5. cleanup of feature bits
>  6. cleanup of feature name table
>        (depends on #5)
>  7. prepare ethtool [GS]FEATURES for larger netdev_features_t
>  8. tadaaa: 64 bits for features
>  9. a lone cleanup patch for NOCACHE_COPY feature
>
> Bear in mind, that I only compile tested the whole series (x86 allyesconfig).
> I'll do per-patch builds after all needed patches are in net-next.
>
> Note about netdev_features_t: I don't like the idea of converting it to
> bitmap type and building wrappers around, so I won't even try to
> implement it. Nevertheless, this series will make the conversion easier
> if someone ever wants to go that way.
>
The idea is to make feature type (by defining netdev_feature_t)
opaque and should handle XX bit integer as well as bitmap types. So
netdev_feature_t typedef-ed to u64 is OK but changes that we make
should be able to handle bitmaps as well to minimize future changes.

--mahesh..

> Best Regards,
> Michał Mirosław
>
> ---
>
> Michał Mirosław (9):
>  [NOT SENT] Intel net drivers: convert to ndo_fix_features
>  net: remove legacy ethtool ops
>  net: ethtool: break association of ETH_FLAG_* with NETIF_F_*
>  net: introduce and use netdev_features_t for device features sets
>  net: Define enum for net device features.
>  net: ethtool: use C99 array initialization for feature-names table
>  ethtool: prepare for larger netdev_features_t type
>  net: extend netdev_features_t to 64 bits
>  net: move NOCACHE_COPY checks to netdev_fix_features()
>
>  drivers/net/8139cp.c                  |    2 +-
>  drivers/net/bnx2.c                    |    6 +-
>  drivers/net/bnx2x/bnx2x_cmn.c         |    5 +-
>  drivers/net/bnx2x/bnx2x_cmn.h         |    5 +-
>  drivers/net/bonding/bond_main.c       |    9 +-
>  drivers/net/cxgb4/cxgb4_main.c        |   12 +-
>  drivers/net/dm9000.c                  |    3 +-
>  drivers/net/e1000/e1000_ethtool.c     |   69 ----
>  drivers/net/e1000/e1000_main.c        |   31 ++-
>  drivers/net/e1000e/ethtool.c          |   88 -----
>  drivers/net/e1000e/netdev.c           |   35 ++-
>  drivers/net/forcedeth.c               |    7 +-
>  drivers/net/gianfar.h                 |    2 +-
>  drivers/net/gianfar_ethtool.c         |    4 +-
>  drivers/net/ibmveth.c                 |    6 +-
>  drivers/net/igb/igb_ethtool.c         |   67 ----
>  drivers/net/igb/igb_main.c            |   33 ++-
>  drivers/net/igbvf/ethtool.c           |   57 ----
>  drivers/net/igbvf/netdev.c            |   25 ++-
>  drivers/net/ixgb/ixgb.h               |    2 +
>  drivers/net/ixgb/ixgb_ethtool.c       |   98 +------
>  drivers/net/ixgb/ixgb_main.c          |   44 +++-
>  drivers/net/ixgbe/ixgbe_ethtool.c     |  183 ++++--------
>  drivers/net/ixgbe/ixgbe_main.c        |   42 ++-
>  drivers/net/ixgbevf/ethtool.c         |   46 ---
>  drivers/net/ixgbevf/ixgbevf_main.c    |   26 ++-
>  drivers/net/jme.c                     |    8 +-
>  drivers/net/ksz884x.c                 |    3 +-
>  drivers/net/mv643xx_eth.c             |    2 +-
>  drivers/net/myri10ge/myri10ge.c       |    2 +-
>  drivers/net/netxen/netxen_nic_main.c  |    6 +-
>  drivers/net/pch_gbe/pch_gbe_main.c    |    5 +-
>  drivers/net/qlcnic/qlcnic.h           |    5 +-
>  drivers/net/qlcnic/qlcnic_hw.c        |    9 +-
>  drivers/net/qlcnic/qlcnic_main.c      |    2 +-
>  drivers/net/r8169.c                   |    6 +-
>  drivers/net/s2io.c                    |    4 +-
>  drivers/net/sfc/efx.c                 |    2 +-
>  drivers/net/sky2.c                    |    5 +-
>  drivers/net/tg3.c                     |    7 +-
>  drivers/net/usb/smsc75xx.c            |    3 +-
>  drivers/net/usb/smsc95xx.c            |    3 +-
>  drivers/net/vmxnet3/vmxnet3_ethtool.c |    4 +-
>  drivers/net/vmxnet3/vmxnet3_int.h     |    2 +-
>  drivers/net/vxge/vxge-main.c          |    9 +-
>  drivers/net/xen-netfront.c            |    8 +-
>  drivers/s390/net/qeth_l3_main.c       |    6 +-
>  include/linux/ethtool.h               |   53 ---
>  include/linux/netdev_features.h       |  152 +++++++++
>  include/linux/netdevice.h             |  141 ++-------
>  include/linux/skbuff.h                |    4 +-
>  include/net/protocol.h                |    4 +-
>  include/net/tcp.h                     |    3 +-
>  include/net/udp.h                     |    3 +-
>  net/8021q/vlan_dev.c                  |    5 +-
>  net/bridge/br_if.c                    |    5 +-
>  net/core/dev.c                        |   71 ++--
>  net/core/ethtool.c                    |  563 ++++++--------------------------
>  net/core/net-sysfs.c                  |    3 +-
>  net/core/skbuff.c                     |    2 +-
>  net/ipv4/af_inet.c                    |    3 +-
>  net/ipv4/tcp.c                        |    2 +-
>  net/ipv4/udp.c                        |    3 +-
>  net/ipv6/af_inet6.c                   |    3 +-
>  net/ipv6/udp.c                        |    2 +-
>  65 files changed, 683 insertions(+), 1347 deletions(-)
>  create mode 100644 include/linux/netdev_features.h
>
> --
> 1.7.2.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFT PATCH 7/9] ethtool: prepare for larger netdev_features_t type
  2011-06-20 21:16   ` Ben Hutchings
@ 2011-06-23 17:50     ` Mahesh Bandewar
  2011-06-23 18:03       ` Ben Hutchings
  0 siblings, 1 reply; 28+ messages in thread
From: Mahesh Bandewar @ 2011-06-23 17:50 UTC (permalink / raw)
  To: Ben Hutchings, Michał Mirosław; +Cc: netdev, David S. Miller

On Mon, Jun 20, 2011 at 2:16 PM, Ben Hutchings
<bhutchings@solarflare.com> wrote:
>
> On Mon, 2011-06-20 at 21:14 +0200, Michał Mirosław wrote:
> [...]
> > @@ -125,19 +131,26 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
> >       if (copy_from_user(features, useraddr, sizeof(features)))
> >               return -EFAULT;
> >
> > -     if (features[0].valid & ~NETIF_F_ETHTOOL_BITS)
> > +     /* I wonder if the compiler will be smart enough to loop-unroll
> > +      * and optimize this... (no worries if not) --mq */
> > +     for (i = ETHTOOL_DEV_FEATURE_WORDS; i-- > 0; ) {
> > +             valid = (valid << 32)|features[i].valid;
> > +             wanted = (wanted << 32)|features[i].requested;
> > +     }
> [...]
>
> I don't know (or care) about optimisation of this, but I would expect
> gcc to complain about shifting a 32-bit value by 32 bits.  I suggest you
> write this as:
>
>        for (i = 0; i < ETHTOOL_DEV_FEATURE_WORDS; ++i) {
>                valid |= (netdev_features_t)features[i].valid << 32 *i;
>                wanted |= (netdev_features_t)features[i].requested << 32 *i;

It's a valid point but this type of typecast or similar usage would
imply that netdev_feature_t is an int of XXX bits. That's not opaque
and would hinder the way you can abstract the feature type.

--mahesh..
>
>        }
>
> Ben.
>
> --
> Ben Hutchings, Senior Software Engineer, Solarflare
> Not speaking for my employer; that's the marketing department's job.
> They asked us to note that Solarflare product names are trademarked.
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFT PATCH 7/9] ethtool: prepare for larger netdev_features_t type
  2011-06-23 17:50     ` Mahesh Bandewar
@ 2011-06-23 18:03       ` Ben Hutchings
  2011-06-23 18:21         ` Mahesh Bandewar
  0 siblings, 1 reply; 28+ messages in thread
From: Ben Hutchings @ 2011-06-23 18:03 UTC (permalink / raw)
  To: Mahesh Bandewar; +Cc: Michał Mirosław, netdev, David S. Miller

On Thu, 2011-06-23 at 10:50 -0700, Mahesh Bandewar wrote:
> On Mon, Jun 20, 2011 at 2:16 PM, Ben Hutchings
> <bhutchings@solarflare.com> wrote:
> >
> > On Mon, 2011-06-20 at 21:14 +0200, Michał Mirosław wrote:
> > [...]
> > > @@ -125,19 +131,26 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
> > >       if (copy_from_user(features, useraddr, sizeof(features)))
> > >               return -EFAULT;
> > >
> > > -     if (features[0].valid & ~NETIF_F_ETHTOOL_BITS)
> > > +     /* I wonder if the compiler will be smart enough to loop-unroll
> > > +      * and optimize this... (no worries if not) --mq */
> > > +     for (i = ETHTOOL_DEV_FEATURE_WORDS; i-- > 0; ) {
> > > +             valid = (valid << 32)|features[i].valid;
> > > +             wanted = (wanted << 32)|features[i].requested;
> > > +     }
> > [...]
> >
> > I don't know (or care) about optimisation of this, but I would expect
> > gcc to complain about shifting a 32-bit value by 32 bits.  I suggest you
> > write this as:
> >
> >        for (i = 0; i < ETHTOOL_DEV_FEATURE_WORDS; ++i) {
> >                valid |= (netdev_features_t)features[i].valid << 32 *i;
> >                wanted |= (netdev_features_t)features[i].requested << 32 *i;
> 
> It's a valid point but this type of typecast or similar usage would
> imply that netdev_feature_t is an int of XXX bits. That's not opaque
> and would hinder the way you can abstract the feature type.

Yes, ethtool_{get,set}_features() will have to be changed if and when
the representation of netdev_features_t is changed significantly.  I
don't think there's any way of avoiding that and I don't think it really
matters.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFT PATCH 7/9] ethtool: prepare for larger netdev_features_t type
  2011-06-23 18:03       ` Ben Hutchings
@ 2011-06-23 18:21         ` Mahesh Bandewar
  2011-06-23 18:55           ` Ben Hutchings
  0 siblings, 1 reply; 28+ messages in thread
From: Mahesh Bandewar @ 2011-06-23 18:21 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: Michał Mirosław, netdev, David S. Miller

On Thu, Jun 23, 2011 at 11:03 AM, Ben Hutchings
<bhutchings@solarflare.com> wrote:
> On Thu, 2011-06-23 at 10:50 -0700, Mahesh Bandewar wrote:
>> On Mon, Jun 20, 2011 at 2:16 PM, Ben Hutchings
>> <bhutchings@solarflare.com> wrote:
>> >
>> > On Mon, 2011-06-20 at 21:14 +0200, Michał Mirosław wrote:
>> > [...]
>> > > @@ -125,19 +131,26 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
>> > >       if (copy_from_user(features, useraddr, sizeof(features)))
>> > >               return -EFAULT;
>> > >
>> > > -     if (features[0].valid & ~NETIF_F_ETHTOOL_BITS)
>> > > +     /* I wonder if the compiler will be smart enough to loop-unroll
>> > > +      * and optimize this... (no worries if not) --mq */
>> > > +     for (i = ETHTOOL_DEV_FEATURE_WORDS; i-- > 0; ) {
>> > > +             valid = (valid << 32)|features[i].valid;
>> > > +             wanted = (wanted << 32)|features[i].requested;
>> > > +     }
>> > [...]
>> >
>> > I don't know (or care) about optimisation of this, but I would expect
>> > gcc to complain about shifting a 32-bit value by 32 bits.  I suggest you
>> > write this as:
>> >
>> >        for (i = 0; i < ETHTOOL_DEV_FEATURE_WORDS; ++i) {
>> >                valid |= (netdev_features_t)features[i].valid << 32 *i;
>> >                wanted |= (netdev_features_t)features[i].requested << 32 *i;
>>
>> It's a valid point but this type of typecast or similar usage would
>> imply that netdev_feature_t is an int of XXX bits. That's not opaque
>> and would hinder the way you can abstract the feature type.
>
> Yes, ethtool_{get,set}_features() will have to be changed if and when
> the representation of netdev_features_t is changed significantly.  I
> don't think there's any way of avoiding that and I don't think it really
> matters.
>
Well, if you have a conversion routine that converts (whatever the)
netdev_type_t type is to the ethtool representation (array of u32 for
example). So the changes would have to be done in that conversion
routine only and not get/set_features() ethtool methods as such.

--mahesh..

> Ben.
>
> --
> Ben Hutchings, Senior Software Engineer, Solarflare
> Not speaking for my employer; that's the marketing department's job.
> They asked us to note that Solarflare product names are trademarked.
>
>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFT PATCH 7/9] ethtool: prepare for larger netdev_features_t type
  2011-06-23 18:21         ` Mahesh Bandewar
@ 2011-06-23 18:55           ` Ben Hutchings
  2011-06-23 20:38             ` Mahesh Bandewar
  0 siblings, 1 reply; 28+ messages in thread
From: Ben Hutchings @ 2011-06-23 18:55 UTC (permalink / raw)
  To: Mahesh Bandewar; +Cc: Michał Mirosław, netdev, David S. Miller

On Thu, 2011-06-23 at 11:21 -0700, Mahesh Bandewar wrote:
> On Thu, Jun 23, 2011 at 11:03 AM, Ben Hutchings
> <bhutchings@solarflare.com> wrote:
> > On Thu, 2011-06-23 at 10:50 -0700, Mahesh Bandewar wrote:
> >> On Mon, Jun 20, 2011 at 2:16 PM, Ben Hutchings
> >> <bhutchings@solarflare.com> wrote:
> >> >
> >> > On Mon, 2011-06-20 at 21:14 +0200, Michał Mirosław wrote:
> >> > [...]
> >> > > @@ -125,19 +131,26 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
> >> > >       if (copy_from_user(features, useraddr, sizeof(features)))
> >> > >               return -EFAULT;
> >> > >
> >> > > -     if (features[0].valid & ~NETIF_F_ETHTOOL_BITS)
> >> > > +     /* I wonder if the compiler will be smart enough to loop-unroll
> >> > > +      * and optimize this... (no worries if not) --mq */
> >> > > +     for (i = ETHTOOL_DEV_FEATURE_WORDS; i-- > 0; ) {
> >> > > +             valid = (valid << 32)|features[i].valid;
> >> > > +             wanted = (wanted << 32)|features[i].requested;
> >> > > +     }
> >> > [...]
> >> >
> >> > I don't know (or care) about optimisation of this, but I would expect
> >> > gcc to complain about shifting a 32-bit value by 32 bits.  I suggest you
> >> > write this as:
> >> >
> >> >        for (i = 0; i < ETHTOOL_DEV_FEATURE_WORDS; ++i) {
> >> >                valid |= (netdev_features_t)features[i].valid << 32 *i;
> >> >                wanted |= (netdev_features_t)features[i].requested << 32 *i;
> >>
> >> It's a valid point but this type of typecast or similar usage would
> >> imply that netdev_feature_t is an int of XXX bits. That's not opaque
> >> and would hinder the way you can abstract the feature type.
> >
> > Yes, ethtool_{get,set}_features() will have to be changed if and when
> > the representation of netdev_features_t is changed significantly.  I
> > don't think there's any way of avoiding that and I don't think it really
> > matters.
> >
> Well, if you have a conversion routine that converts (whatever the)
> netdev_type_t type is to the ethtool representation (array of u32 for
> example). So the changes would have to be done in that conversion
> routine only and not get/set_features() ethtool methods as such.

These are precisely those conversion routines, because there is no other
place that needs to deal with the ethtool representation...

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [RFT PATCH 7/9] ethtool: prepare for larger netdev_features_t type
  2011-06-23 18:55           ` Ben Hutchings
@ 2011-06-23 20:38             ` Mahesh Bandewar
  0 siblings, 0 replies; 28+ messages in thread
From: Mahesh Bandewar @ 2011-06-23 20:38 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: Michał Mirosław, netdev, David S. Miller

On Thu, Jun 23, 2011 at 11:55 AM, Ben Hutchings
<bhutchings@solarflare.com> wrote:
> On Thu, 2011-06-23 at 11:21 -0700, Mahesh Bandewar wrote:
>> On Thu, Jun 23, 2011 at 11:03 AM, Ben Hutchings
>> <bhutchings@solarflare.com> wrote:
>> > On Thu, 2011-06-23 at 10:50 -0700, Mahesh Bandewar wrote:
>> >> On Mon, Jun 20, 2011 at 2:16 PM, Ben Hutchings
>> >> <bhutchings@solarflare.com> wrote:
>> >> >
>> >> > On Mon, 2011-06-20 at 21:14 +0200, Michał Mirosław wrote:
>> >> > [...]
>> >> > > @@ -125,19 +131,26 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
>> >> > >       if (copy_from_user(features, useraddr, sizeof(features)))
>> >> > >               return -EFAULT;
>> >> > >
>> >> > > -     if (features[0].valid & ~NETIF_F_ETHTOOL_BITS)
>> >> > > +     /* I wonder if the compiler will be smart enough to loop-unroll
>> >> > > +      * and optimize this... (no worries if not) --mq */
>> >> > > +     for (i = ETHTOOL_DEV_FEATURE_WORDS; i-- > 0; ) {
>> >> > > +             valid = (valid << 32)|features[i].valid;
>> >> > > +             wanted = (wanted << 32)|features[i].requested;
>> >> > > +     }
>> >> > [...]
>> >> >
>> >> > I don't know (or care) about optimisation of this, but I would expect
>> >> > gcc to complain about shifting a 32-bit value by 32 bits.  I suggest you
>> >> > write this as:
>> >> >
>> >> >        for (i = 0; i < ETHTOOL_DEV_FEATURE_WORDS; ++i) {
>> >> >                valid |= (netdev_features_t)features[i].valid << 32 *i;
>> >> >                wanted |= (netdev_features_t)features[i].requested << 32 *i;
>> >>
>> >> It's a valid point but this type of typecast or similar usage would
>> >> imply that netdev_feature_t is an int of XXX bits. That's not opaque
>> >> and would hinder the way you can abstract the feature type.
>> >
>> > Yes, ethtool_{get,set}_features() will have to be changed if and when
>> > the representation of netdev_features_t is changed significantly.  I
>> > don't think there's any way of avoiding that and I don't think it really
>> > matters.
>> >
>> Well, if you have a conversion routine that converts (whatever the)
>> netdev_type_t type is to the ethtool representation (array of u32 for
>> example). So the changes would have to be done in that conversion
>> routine only and not get/set_features() ethtool methods as such.
>
> These are precisely those conversion routines, because there is no other
> place that needs to deal with the ethtool representation...
>
Oh, I was considering get/set_features ethtool methods as APIs  to
manipulate certain bits from user-space into kernel space. I was
disassociating features bit representation as a separate aspect and
(of course) the conversion. So depending on the type selection you may
or may not need these conversion routines.

--mahesh..

> Ben.
>
> --
> Ben Hutchings, Senior Software Engineer, Solarflare
> Not speaking for my employer; that's the marketing department's job.
> They asked us to note that Solarflare product names are trademarked.
>
>

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2011-06-23 20:39 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-06-20 19:14 [RFT PATCH 0/9] Cleanup and extension of netdev features Michał Mirosław
2011-06-20 19:14 ` [RFT PATCH 3/9] net: ethtool: break association of ETH_FLAG_* with NETIF_F_* Michał Mirosław
2011-06-20 20:11   ` Ben Hutchings
2011-06-20 20:27     ` David Miller
2011-06-20 20:51     ` Stephen Hemminger
2011-06-20 20:52       ` David Miller
2011-06-20 21:30         ` Ben Hutchings
2011-06-20 19:14 ` [RFT PATCH 5/9] net: Define enum for net device features Michał Mirosław
2011-06-20 19:14 ` [RFT PATCH 2/9] net: remove legacy ethtool ops Michał Mirosław
2011-06-20 19:14 ` [RFT PATCH 4/9] net: introduce and use netdev_features_t for device features sets Michał Mirosław
2011-06-20 21:01   ` Ben Hutchings
2011-06-20 19:14 ` [RFT PATCH 8/9] net: extend netdev_features_t to 64 bits Michał Mirosław
2011-06-20 19:14 ` [RFT PATCH 6/9] net: ethtool: use C99 array initialization for feature-names table Michał Mirosław
2011-06-20 19:14 ` [RFT PATCH 7/9] ethtool: prepare for larger netdev_features_t type Michał Mirosław
2011-06-20 21:16   ` Ben Hutchings
2011-06-23 17:50     ` Mahesh Bandewar
2011-06-23 18:03       ` Ben Hutchings
2011-06-23 18:21         ` Mahesh Bandewar
2011-06-23 18:55           ` Ben Hutchings
2011-06-23 20:38             ` Mahesh Bandewar
2011-06-20 19:14 ` [RFT PATCH 9/9] net: move NOCACHE_COPY checks to netdev_fix_features() Michał Mirosław
2011-06-20 19:35 ` [RFT PATCH 0/9] Cleanup and extension of netdev features David Miller
2011-06-20 19:47   ` Michał Mirosław
2011-06-20 19:55     ` [IGNORE PATCH 1/9] Intel net drivers: convert to ndo_fix_features Michał Mirosław
2011-06-21 21:43 ` [RFT PATCH 0/9] Cleanup and extension of netdev features Ben Greear
2011-06-21 21:52   ` Ben Hutchings
2011-06-21 23:27   ` Jeff Kirsher
2011-06-23 17:42 ` Mahesh Bandewar

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.