diff options
Diffstat (limited to 'net/core/dev.c')
| -rw-r--r-- | net/core/dev.c | 143 | 
1 files changed, 74 insertions, 69 deletions
| diff --git a/net/core/dev.c b/net/core/dev.c index 1408a083fe4..d9038e328cc 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -924,10 +924,10 @@ int dev_change_name(struct net_device *dev, const char *newname)  		strlcpy(dev->name, newname, IFNAMSIZ);  rollback: -	err = device_rename(&dev->dev, dev->name); -	if (err) { +	ret = device_rename(&dev->dev, dev->name); +	if (ret) {  		memcpy(dev->name, oldname, IFNAMSIZ); -		return err; +		return ret;  	}  	write_lock_bh(&dev_base_lock); @@ -3947,6 +3947,46 @@ static void netdev_init_queue_locks(struct net_device *dev)  	__netdev_init_queue_locks_one(dev, &dev->rx_queue, NULL);  } +unsigned long netdev_fix_features(unsigned long features, const char *name) +{ +	/* Fix illegal SG+CSUM combinations. */ +	if ((features & NETIF_F_SG) && +	    !(features & NETIF_F_ALL_CSUM)) { +		if (name) +			printk(KERN_NOTICE "%s: Dropping NETIF_F_SG since no " +			       "checksum feature.\n", name); +		features &= ~NETIF_F_SG; +	} + +	/* TSO requires that SG is present as well. */ +	if ((features & NETIF_F_TSO) && !(features & NETIF_F_SG)) { +		if (name) +			printk(KERN_NOTICE "%s: Dropping NETIF_F_TSO since no " +			       "SG feature.\n", name); +		features &= ~NETIF_F_TSO; +	} + +	if (features & NETIF_F_UFO) { +		if (!(features & NETIF_F_GEN_CSUM)) { +			if (name) +				printk(KERN_ERR "%s: Dropping NETIF_F_UFO " +				       "since no NETIF_F_HW_CSUM feature.\n", +				       name); +			features &= ~NETIF_F_UFO; +		} + +		if (!(features & NETIF_F_SG)) { +			if (name) +				printk(KERN_ERR "%s: Dropping NETIF_F_UFO " +				       "since no NETIF_F_SG feature.\n", name); +			features &= ~NETIF_F_UFO; +		} +	} + +	return features; +} +EXPORT_SYMBOL(netdev_fix_features); +  /**   *	register_netdevice	- register a network device   *	@dev: device to register @@ -4032,36 +4072,7 @@ int register_netdevice(struct net_device *dev)  		dev->features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM|NETIF_F_HW_CSUM);  	} - -	/* Fix illegal SG+CSUM combinations. */ -	if ((dev->features & NETIF_F_SG) && -	    !(dev->features & NETIF_F_ALL_CSUM)) { -		printk(KERN_NOTICE "%s: Dropping NETIF_F_SG since no checksum feature.\n", -		       dev->name); -		dev->features &= ~NETIF_F_SG; -	} - -	/* TSO requires that SG is present as well. */ -	if ((dev->features & NETIF_F_TSO) && -	    !(dev->features & NETIF_F_SG)) { -		printk(KERN_NOTICE "%s: Dropping NETIF_F_TSO since no SG feature.\n", -		       dev->name); -		dev->features &= ~NETIF_F_TSO; -	} -	if (dev->features & NETIF_F_UFO) { -		if (!(dev->features & NETIF_F_HW_CSUM)) { -			printk(KERN_ERR "%s: Dropping NETIF_F_UFO since no " -					"NETIF_F_HW_CSUM feature.\n", -							dev->name); -			dev->features &= ~NETIF_F_UFO; -		} -		if (!(dev->features & NETIF_F_SG)) { -			printk(KERN_ERR "%s: Dropping NETIF_F_UFO since no " -					"NETIF_F_SG feature.\n", -					dev->name); -			dev->features &= ~NETIF_F_UFO; -		} -	} +	dev->features = netdev_fix_features(dev->features, dev->name);  	/* Enable software GSO if SG is supported. */  	if (dev->features & NETIF_F_SG) @@ -4700,49 +4711,45 @@ static int __init netdev_dma_register(void) { return -ENODEV; }  #endif /* CONFIG_NET_DMA */  /** - *	netdev_compute_feature - compute conjunction of two feature sets - *	@all: first feature set - *	@one: second feature set + *	netdev_increment_features - increment feature set by one + *	@all: current feature set + *	@one: new feature set + *	@mask: mask feature set   *   *	Computes a new feature set after adding a device with feature set - *	@one to the master device with current feature set @all.  Returns - *	the new feature set. + *	@one to the master device with current feature set @all.  Will not + *	enable anything that is off in @mask. Returns the new feature set.   */ -int netdev_compute_features(unsigned long all, unsigned long one) -{ -	/* if device needs checksumming, downgrade to hw checksumming */ -	if (all & NETIF_F_NO_CSUM && !(one & NETIF_F_NO_CSUM)) -		all ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM; - -	/* if device can't do all checksum, downgrade to ipv4/ipv6 */ -	if (all & NETIF_F_HW_CSUM && !(one & NETIF_F_HW_CSUM)) -		all ^= NETIF_F_HW_CSUM -			| NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; - -	if (one & NETIF_F_GSO) -		one |= NETIF_F_GSO_SOFTWARE; -	one |= NETIF_F_GSO; - -	/* -	 * If even one device supports a GSO protocol with software fallback, -	 * enable it for all. -	 */ -	all |= one & NETIF_F_GSO_SOFTWARE; +unsigned long netdev_increment_features(unsigned long all, unsigned long one, +					unsigned long mask) +{ +	/* If device needs checksumming, downgrade to it. */ +        if (all & NETIF_F_NO_CSUM && !(one & NETIF_F_NO_CSUM)) +		all ^= NETIF_F_NO_CSUM | (one & NETIF_F_ALL_CSUM); +	else if (mask & NETIF_F_ALL_CSUM) { +		/* If one device supports v4/v6 checksumming, set for all. */ +		if (one & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM) && +		    !(all & NETIF_F_GEN_CSUM)) { +			all &= ~NETIF_F_ALL_CSUM; +			all |= one & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); +		} -	/* If even one device supports robust GSO, enable it for all. */ -	if (one & NETIF_F_GSO_ROBUST) -		all |= NETIF_F_GSO_ROBUST; +		/* If one device supports hw checksumming, set for all. */ +		if (one & NETIF_F_GEN_CSUM && !(all & NETIF_F_GEN_CSUM)) { +			all &= ~NETIF_F_ALL_CSUM; +			all |= NETIF_F_HW_CSUM; +		} +	} -	all &= one | NETIF_F_LLTX; +	one |= NETIF_F_ALL_CSUM; -	if (!(all & NETIF_F_ALL_CSUM)) -		all &= ~NETIF_F_SG; -	if (!(all & NETIF_F_SG)) -		all &= ~NETIF_F_GSO_MASK; +	one |= all & NETIF_F_ONE_FOR_ALL; +	all &= one | NETIF_F_LLTX | NETIF_F_GSO; +	all |= one & mask & NETIF_F_ONE_FOR_ALL;  	return all;  } -EXPORT_SYMBOL(netdev_compute_features); +EXPORT_SYMBOL(netdev_increment_features);  static struct hlist_head *netdev_create_hash(void)  { @@ -4956,8 +4963,6 @@ EXPORT_SYMBOL(br_fdb_get_hook);  EXPORT_SYMBOL(br_fdb_put_hook);  #endif -#ifdef CONFIG_KMOD  EXPORT_SYMBOL(dev_load); -#endif  EXPORT_PER_CPU_SYMBOL(softnet_data); | 
