Merge branch 'merge' of master.kernel.org:/pub/scm/linux/kernel/git/paulus/powerpc
[powerpc.git] / net / bridge / br_if.c
index fdec773..f753c40 100644 (file)
@@ -163,7 +163,7 @@ static void del_nbp(struct net_bridge_port *p)
        br_stp_disable_port(p);
        spin_unlock_bh(&br->lock);
 
-       br_fdb_delete_by_port(br, p);
+       br_fdb_delete_by_port(br, p, 1);
 
        list_del_rcu(&p->list);
 
@@ -376,18 +376,29 @@ void br_features_recompute(struct net_bridge *br)
        features = br->feature_mask & ~NETIF_F_ALL_CSUM;
 
        list_for_each_entry(p, &br->port_list, list) {
-               if (checksum & NETIF_F_NO_CSUM &&
-                   !(p->dev->features & NETIF_F_NO_CSUM))
+               unsigned long feature = p->dev->features;
+
+               if (checksum & NETIF_F_NO_CSUM && !(feature & 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))
+               if (checksum & NETIF_F_HW_CSUM && !(feature & NETIF_F_HW_CSUM))
                        checksum ^= NETIF_F_HW_CSUM | NETIF_F_IP_CSUM;
-               if (!(p->dev->features & NETIF_F_IP_CSUM))
+               if (!(feature & NETIF_F_IP_CSUM))
                        checksum = 0;
-               features &= p->dev->features;
+
+               if (feature & NETIF_F_GSO)
+                       feature |= NETIF_F_GSO_SOFTWARE;
+               feature |= NETIF_F_GSO;
+
+               features &= feature;
        }
 
-       br->dev->features = features | checksum | NETIF_F_LLTX;
+       if (!(checksum & NETIF_F_ALL_CSUM))
+               features &= ~NETIF_F_SG;
+       if (!(features & NETIF_F_SG))
+               features &= ~NETIF_F_GSO_MASK;
+
+       br->dev->features = features | checksum | NETIF_F_LLTX |
+                           NETIF_F_GSO_ROBUST;
 }
 
 /* called with RTNL */
@@ -437,7 +448,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
 
        return 0;
 err2:
-       br_fdb_delete_by_port(br, p);
+       br_fdb_delete_by_port(br, p, 1);
 err1:
        kobject_del(&p->kobj);
 err0: