Fix "(unregistered net_device): Features changed" message
[pandora-kernel.git] / net / core / dev.c
index 54aaca6..77e5edb 100644 (file)
@@ -1281,10 +1281,13 @@ static int __dev_close_many(struct list_head *head)
 
 static int __dev_close(struct net_device *dev)
 {
+       int retval;
        LIST_HEAD(single);
 
        list_add(&dev->unreg_list, &single);
-       return __dev_close_many(&single);
+       retval = __dev_close_many(&single);
+       list_del(&single);
+       return retval;
 }
 
 static int dev_close_many(struct list_head *head)
@@ -1326,7 +1329,7 @@ int dev_close(struct net_device *dev)
 
        list_add(&dev->unreg_list, &single);
        dev_close_many(&single);
-
+       list_del(&single);
        return 0;
 }
 EXPORT_SYMBOL(dev_close);
@@ -3107,7 +3110,8 @@ static inline void skb_bond_set_mac_by_master(struct sk_buff *skb,
  * duplicates except for 802.3ad ETH_P_SLOW, alb non-mcast/bcast, and
  * ARP on active-backup slaves with arp_validate enabled.
  */
-int __skb_bond_should_drop(struct sk_buff *skb, struct net_device *master)
+static int __skb_bond_should_drop(struct sk_buff *skb,
+                                 struct net_device *master)
 {
        struct net_device *dev = skb->dev;
 
@@ -3141,14 +3145,12 @@ int __skb_bond_should_drop(struct sk_buff *skb, struct net_device *master)
        }
        return 0;
 }
-EXPORT_SYMBOL(__skb_bond_should_drop);
 
 static int __netif_receive_skb(struct sk_buff *skb)
 {
        struct packet_type *ptype, *pt_prev;
        rx_handler_func_t *rx_handler;
        struct net_device *orig_dev;
-       struct net_device *master;
        struct net_device *null_or_orig;
        struct net_device *orig_or_bond;
        int ret = NET_RX_DROP;
@@ -3175,15 +3177,19 @@ static int __netif_receive_skb(struct sk_buff *skb)
         */
        null_or_orig = NULL;
        orig_dev = skb->dev;
-       master = ACCESS_ONCE(orig_dev->master);
        if (skb->deliver_no_wcard)
                null_or_orig = orig_dev;
-       else if (master) {
-               if (skb_bond_should_drop(skb, master)) {
-                       skb->deliver_no_wcard = 1;
-                       null_or_orig = orig_dev; /* deliver only exact match */
-               } else
-                       skb->dev = master;
+       else if (netif_is_bond_slave(orig_dev)) {
+               struct net_device *bond_master = ACCESS_ONCE(orig_dev->master);
+
+               if (likely(bond_master)) {
+                       if (__skb_bond_should_drop(skb, bond_master)) {
+                               skb->deliver_no_wcard = 1;
+                               /* deliver only exact match */
+                               null_or_orig = orig_dev;
+                       } else
+                               skb->dev = bond_master;
+               }
        }
 
        __this_cpu_inc(softnet_data.processed);
@@ -4348,15 +4354,14 @@ static int __init dev_proc_init(void)
 
 
 /**
- *     netdev_set_master       -       set up master/slave pair
+ *     netdev_set_master       -       set up master pointer
  *     @slave: slave device
  *     @master: new master device
  *
  *     Changes the master device of the slave. Pass %NULL to break the
  *     bonding. The caller must hold the RTNL semaphore. On a failure
  *     a negative errno code is returned. On success the reference counts
- *     are adjusted, %RTM_NEWLINK is sent to the routing socket and the
- *     function returns zero.
+ *     are adjusted and the function returns zero.
  */
 int netdev_set_master(struct net_device *slave, struct net_device *master)
 {
@@ -4376,6 +4381,29 @@ int netdev_set_master(struct net_device *slave, struct net_device *master)
                synchronize_net();
                dev_put(old);
        }
+       return 0;
+}
+EXPORT_SYMBOL(netdev_set_master);
+
+/**
+ *     netdev_set_bond_master  -       set up bonding master/slave pair
+ *     @slave: slave device
+ *     @master: new master device
+ *
+ *     Changes the master device of the slave. Pass %NULL to break the
+ *     bonding. The caller must hold the RTNL semaphore. On a failure
+ *     a negative errno code is returned. On success %RTM_NEWLINK is sent
+ *     to the routing socket and the function returns zero.
+ */
+int netdev_set_bond_master(struct net_device *slave, struct net_device *master)
+{
+       int err;
+
+       ASSERT_RTNL();
+
+       err = netdev_set_master(slave, master);
+       if (err)
+               return err;
        if (master)
                slave->flags |= IFF_SLAVE;
        else
@@ -4384,7 +4412,7 @@ int netdev_set_master(struct net_device *slave, struct net_device *master)
        rtmsg_ifinfo(RTM_NEWLINK, slave, IFF_SLAVE);
        return 0;
 }
-EXPORT_SYMBOL(netdev_set_master);
+EXPORT_SYMBOL(netdev_set_bond_master);
 
 static void dev_change_rx_flags(struct net_device *dev, int flags)
 {
@@ -5219,6 +5247,7 @@ static void rollback_registered(struct net_device *dev)
 
        list_add(&dev->unreg_list, &single);
        rollback_registered_many(&single);
+       list_del(&single);
 }
 
 u32 netdev_fix_features(struct net_device *dev, u32 features)
@@ -5250,6 +5279,12 @@ u32 netdev_fix_features(struct net_device *dev, u32 features)
                features &= ~NETIF_F_TSO;
        }
 
+       /* Software GSO depends on SG. */
+       if ((features & NETIF_F_GSO) && !(features & NETIF_F_SG)) {
+               netdev_info(dev, "Dropping NETIF_F_GSO since no SG feature.\n");
+               features &= ~NETIF_F_GSO;
+       }
+
        /* UFO needs SG and checksumming */
        if (features & NETIF_F_UFO) {
                /* maybe split UFO into V4 and V6? */
@@ -5272,6 +5307,37 @@ u32 netdev_fix_features(struct net_device *dev, u32 features)
 }
 EXPORT_SYMBOL(netdev_fix_features);
 
+void netdev_update_features(struct net_device *dev)
+{
+       u32 features;
+       int err = 0;
+
+       features = netdev_get_wanted_features(dev);
+
+       if (dev->netdev_ops->ndo_fix_features)
+               features = dev->netdev_ops->ndo_fix_features(dev, features);
+
+       /* driver might be less strict about feature dependencies */
+       features = netdev_fix_features(dev, features);
+
+       if (dev->features == features)
+               return;
+
+       netdev_info(dev, "Features changed: 0x%08x -> 0x%08x\n",
+               dev->features, features);
+
+       if (dev->netdev_ops->ndo_set_features)
+               err = dev->netdev_ops->ndo_set_features(dev, features);
+
+       if (!err)
+               dev->features = features;
+       else if (err < 0)
+               netdev_err(dev,
+                       "set_features() failed (%d); wanted 0x%08x, left 0x%08x\n",
+                       err, features, dev->features);
+}
+EXPORT_SYMBOL(netdev_update_features);
+
 /**
  *     netif_stacked_transfer_operstate -      transfer operstate
  *     @rootdev: the root or lower level device to transfer state from
@@ -5406,11 +5472,16 @@ int register_netdevice(struct net_device *dev)
        if (dev->iflink == -1)
                dev->iflink = dev->ifindex;
 
-       dev->features = netdev_fix_features(dev, dev->features);
+       /* Transfer changeable features to wanted_features and enable
+        * software offloads (GSO and GRO).
+        */
+       dev->hw_features |= NETIF_F_SOFT_FEATURES;
+       dev->wanted_features = (dev->features & dev->hw_features)
+               | NETIF_F_SOFT_FEATURES;
 
-       /* Enable software GSO if SG is supported. */
-       if (dev->features & NETIF_F_SG)
-               dev->features |= NETIF_F_GSO;
+       /* Avoid warning from netdev_fix_features() for GSO without SG */
+       if (!(dev->wanted_features & NETIF_F_SG))
+               dev->wanted_features &= ~NETIF_F_GSO;
 
        /* Enable GRO and NETIF_F_HIGHDMA for vlans by default,
         * vlan_dev_init() will do the dev->features check, so these features
@@ -5428,6 +5499,8 @@ int register_netdevice(struct net_device *dev)
                goto err_uninit;
        dev->reg_state = NETREG_REGISTERED;
 
+       netdev_update_features(dev);
+
        /*
         *      Default initial state at registry is that the
         *      device is present.
@@ -6365,6 +6438,7 @@ static void __net_exit default_device_exit_batch(struct list_head *net_list)
                }
        }
        unregister_netdevice_many(&dev_kill_list);
+       list_del(&dev_kill_list);
        rtnl_unlock();
 }