From 2c6cc0d8539f121c3c75aa3641c19b67e8723379 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sat, 17 Jun 2006 22:06:45 -0700 Subject: [BRIDGE]: Add support for NETIF_F_HW_CSUM devices As it is the bridge will only ever declare NETIF_F_IP_CSUM even if all its constituent devices support NETIF_F_HW_CSUM. This patch fixes this by supporting the first one out of NETIF_F_NO_CSUM, NETIF_F_HW_CSUM, and NETIF_F_IP_CSUM that is supported by all constituent devices. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/bridge/br_device.c | 6 +++--- net/bridge/br_if.c | 12 +++++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 0c88a2a..2afdc7c 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -145,9 +145,9 @@ static int br_set_tx_csum(struct net_device *dev, u32 data) struct net_bridge *br = netdev_priv(dev); if (data) - br->feature_mask |= NETIF_F_IP_CSUM; + br->feature_mask |= NETIF_F_NO_CSUM; else - br->feature_mask &= ~NETIF_F_IP_CSUM; + br->feature_mask &= ~NETIF_F_ALL_CSUM; br_features_recompute(br); return 0; @@ -185,5 +185,5 @@ void br_dev_setup(struct net_device *dev) dev->priv_flags = IFF_EBRIDGE; dev->features = NETIF_F_SG | NETIF_F_FRAGLIST - | NETIF_F_HIGHDMA | NETIF_F_TSO | NETIF_F_IP_CSUM; + | NETIF_F_HIGHDMA | NETIF_F_TSO | NETIF_F_NO_CSUM; } diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 90c95f5..fdec773 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -372,11 +372,17 @@ void br_features_recompute(struct net_bridge *br) struct net_bridge_port *p; unsigned long features, checksum; - features = br->feature_mask &~ NETIF_F_IP_CSUM; - checksum = br->feature_mask & NETIF_F_IP_CSUM; + checksum = br->feature_mask & NETIF_F_ALL_CSUM ? NETIF_F_NO_CSUM : 0; + features = br->feature_mask & ~NETIF_F_ALL_CSUM; list_for_each_entry(p, &br->port_list, list) { - if (!(p->dev->features & NETIF_F_ALL_CSUM)) + if (checksum & NETIF_F_NO_CSUM && + !(p->dev->features & NETIF_F_NO_CSUM)) + checksum ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM; + if (checksum & NETIF_F_HW_CSUM && + !(p->dev->features & NETIF_F_HW_CSUM)) + checksum ^= NETIF_F_HW_CSUM | NETIF_F_IP_CSUM; + if (!(p->dev->features & NETIF_F_IP_CSUM)) checksum = 0; features &= p->dev->features; } -- cgit v1.1