aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/bridge/br_device.c2
-rw-r--r--net/bridge/br_if.c36
-rw-r--r--net/core/dev.c39
3 files changed, 44 insertions, 33 deletions
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 5e1892d8d874..0eded176ce99 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -179,5 +179,5 @@ void br_dev_setup(struct net_device *dev)
179 dev->priv_flags = IFF_EBRIDGE; 179 dev->priv_flags = IFF_EBRIDGE;
180 180
181 dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | 181 dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
182 NETIF_F_TSO | NETIF_F_NO_CSUM | NETIF_F_GSO_ROBUST; 182 NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_LLTX;
183} 183}
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index b40dada002bf..749f0e8f541d 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -349,43 +349,15 @@ int br_min_mtu(const struct net_bridge *br)
349void br_features_recompute(struct net_bridge *br) 349void br_features_recompute(struct net_bridge *br)
350{ 350{
351 struct net_bridge_port *p; 351 struct net_bridge_port *p;
352 unsigned long features, checksum; 352 unsigned long features;
353 353
354 checksum = br->feature_mask & NETIF_F_ALL_CSUM ? NETIF_F_NO_CSUM : 0; 354 features = br->feature_mask;
355 features = br->feature_mask & ~NETIF_F_ALL_CSUM;
356 355
357 list_for_each_entry(p, &br->port_list, list) { 356 list_for_each_entry(p, &br->port_list, list) {
358 unsigned long feature = p->dev->features; 357 features = netdev_compute_features(features, p->dev->features);
359
360 /* if device needs checksumming, downgrade to hw checksumming */
361 if (checksum & NETIF_F_NO_CSUM && !(feature & NETIF_F_NO_CSUM))
362 checksum ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM;
363
364 /* if device can't do all checksum, downgrade to ipv4/ipv6 */
365 if (checksum & NETIF_F_HW_CSUM && !(feature & NETIF_F_HW_CSUM))
366 checksum ^= NETIF_F_HW_CSUM
367 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
368
369 if (checksum & NETIF_F_IPV6_CSUM && !(feature & NETIF_F_IPV6_CSUM))
370 checksum &= ~NETIF_F_IPV6_CSUM;
371
372 if (!(feature & NETIF_F_IP_CSUM))
373 checksum = 0;
374
375 if (feature & NETIF_F_GSO)
376 feature |= NETIF_F_GSO_SOFTWARE;
377 feature |= NETIF_F_GSO;
378
379 features &= feature;
380 } 358 }
381 359
382 if (!(checksum & NETIF_F_ALL_CSUM)) 360 br->dev->features = features;
383 features &= ~NETIF_F_SG;
384 if (!(features & NETIF_F_SG))
385 features &= ~NETIF_F_GSO_MASK;
386
387 br->dev->features = features | checksum | NETIF_F_LLTX |
388 NETIF_F_GSO_ROBUST;
389} 361}
390 362
391/* called with RTNL */ 363/* called with RTNL */
diff --git a/net/core/dev.c b/net/core/dev.c
index 6cc8a70350ac..a76021c71207 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3993,6 +3993,45 @@ static int __init netdev_dma_register(void)
3993static int __init netdev_dma_register(void) { return -ENODEV; } 3993static int __init netdev_dma_register(void) { return -ENODEV; }
3994#endif /* CONFIG_NET_DMA */ 3994#endif /* CONFIG_NET_DMA */
3995 3995
3996/**
3997 * netdev_compute_feature - compute conjunction of two feature sets
3998 * @all: first feature set
3999 * @one: second feature set
4000 *
4001 * Computes a new feature set after adding a device with feature set
4002 * @one to the master device with current feature set @all. Returns
4003 * the new feature set.
4004 */
4005int netdev_compute_features(unsigned long all, unsigned long one)
4006{
4007 /* if device needs checksumming, downgrade to hw checksumming */
4008 if (all & NETIF_F_NO_CSUM && !(one & NETIF_F_NO_CSUM))
4009 all ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM;
4010
4011 /* if device can't do all checksum, downgrade to ipv4/ipv6 */
4012 if (all & NETIF_F_HW_CSUM && !(one & NETIF_F_HW_CSUM))
4013 all ^= NETIF_F_HW_CSUM
4014 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
4015
4016 if (one & NETIF_F_GSO)
4017 one |= NETIF_F_GSO_SOFTWARE;
4018 one |= NETIF_F_GSO;
4019
4020 /* If even one device supports robust GSO, enable it for all. */
4021 if (one & NETIF_F_GSO_ROBUST)
4022 all |= NETIF_F_GSO_ROBUST;
4023
4024 all &= one | NETIF_F_LLTX;
4025
4026 if (!(all & NETIF_F_ALL_CSUM))
4027 all &= ~NETIF_F_SG;
4028 if (!(all & NETIF_F_SG))
4029 all &= ~NETIF_F_GSO_MASK;
4030
4031 return all;
4032}
4033EXPORT_SYMBOL(netdev_compute_features);
4034
3996/* 4035/*
3997 * Initialize the DEV module. At boot time this walks the device list and 4036 * Initialize the DEV module. At boot time this walks the device list and
3998 * unhooks any devices that fail to initialise (normally hardware not 4037 * unhooks any devices that fail to initialise (normally hardware not