linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / net / bonding / bond_main.c
index cf906d7..bcf9f17 100644 (file)
@@ -33,6 +33,7 @@
 
 //#define BONDING_DEBUG 1
 
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/sched.h>
@@ -130,7 +131,7 @@ MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form");
 
 /*----------------------------- Global variables ----------------------------*/
 
-static const char * const version =
+static const char *version =
        DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n";
 
 LIST_HEAD(bond_dev_list);
@@ -557,42 +558,6 @@ out:
 
 /*------------------------------- Link status -------------------------------*/
 
-/*
- * Set the carrier state for the master according to the state of its
- * slaves.  If any slaves are up, the master is up.  In 802.3ad mode,
- * do special 802.3ad magic.
- *
- * Returns zero if carrier state does not change, nonzero if it does.
- */
-static int bond_set_carrier(struct bonding *bond)
-{
-       struct slave *slave;
-       int i;
-
-       if (bond->slave_cnt == 0)
-               goto down;
-
-       if (bond->params.mode == BOND_MODE_8023AD)
-               return bond_3ad_set_carrier(bond);
-
-       bond_for_each_slave(bond, slave, i) {
-               if (slave->link == BOND_LINK_UP) {
-                       if (!netif_carrier_ok(bond->dev)) {
-                               netif_carrier_on(bond->dev);
-                               return 1;
-                       }
-                       return 0;
-               }
-       }
-
-down:
-       if (netif_carrier_ok(bond->dev)) {
-               netif_carrier_off(bond->dev);
-               return 1;
-       }
-       return 0;
-}
-
 /*
  * Get link speed and duplex from the slave's base driver
  * using ethtool. If for some reason the call fails or the
@@ -1075,10 +1040,6 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
        if ((bond->params.mode == BOND_MODE_TLB) ||
            (bond->params.mode == BOND_MODE_ALB)) {
                bond_alb_handle_active_change(bond, new_active);
-               if (old_active)
-                       bond_set_slave_inactive_flags(old_active);
-               if (new_active)
-                       bond_set_slave_active_flags(new_active);
        } else {
                bond->curr_active_slave = new_active;
        }
@@ -1109,24 +1070,10 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
 void bond_select_active_slave(struct bonding *bond)
 {
        struct slave *best_slave;
-       int rv;
 
        best_slave = bond_find_best_slave(bond);
        if (best_slave != bond->curr_active_slave) {
                bond_change_active_slave(bond, best_slave);
-               rv = bond_set_carrier(bond);
-               if (!rv)
-                       return;
-
-               if (netif_carrier_ok(bond->dev)) {
-                       printk(KERN_INFO DRV_NAME
-                              ": %s: first active interface up!\n",
-                              bond->dev->name);
-               } else {
-                       printk(KERN_INFO DRV_NAME ": %s: "
-                              "now running without any active interface !\n",
-                              bond->dev->name);
-               }
        }
 }
 
@@ -1198,7 +1145,8 @@ int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev)
 }
 
 #define BOND_INTERSECT_FEATURES \
-       (NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_TSO | NETIF_F_UFO)
+       (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM|\
+       NETIF_F_TSO|NETIF_F_UFO)
 
 /* 
  * Compute the common dev->feature set available to all slaves.  Some
@@ -1216,7 +1164,9 @@ static int bond_compute_features(struct bonding *bond)
                features &= (slave->dev->features & BOND_INTERSECT_FEATURES);
 
        if ((features & NETIF_F_SG) && 
-           !(features & NETIF_F_ALL_CSUM))
+           !(features & (NETIF_F_IP_CSUM |
+                         NETIF_F_NO_CSUM |
+                         NETIF_F_HW_CSUM)))
                features &= ~NETIF_F_SG;
 
        /* 
@@ -1493,25 +1443,20 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 
        switch (bond->params.mode) {
        case BOND_MODE_ACTIVEBACKUP:
-               /* if we're in active-backup mode, we need one and
-                * only one active interface. The backup interfaces
-                * will have their SLAVE_INACTIVE flag set because we
-                * need them to be drop all packets. Thus, since we
-                * guarantee that curr_active_slave always point to
-                * the last usable interface, we just have to verify
-                * this interface's flag.
+               /* if we're in active-backup mode, we need one and only one active
+                * interface. The backup interfaces will have their NOARP flag set
+                * because we need them to be completely deaf and not to respond to
+                * any ARP request on the network to avoid fooling a switch. Thus,
+                * since we guarantee that curr_active_slave always point to the last
+                * usable interface, we just have to verify this interface's flag.
                 */
                if (((!bond->curr_active_slave) ||
-                    (bond->curr_active_slave->dev->priv_flags & IFF_SLAVE_INACTIVE)) &&
+                    (bond->curr_active_slave->dev->flags & IFF_NOARP)) &&
                    (new_slave->link != BOND_LINK_DOWN)) {
+                       dprintk("This is the first active slave\n");
                        /* first slave or no active slave yet, and this link
                           is OK, so make this interface the active one */
                        bond_change_active_slave(bond, new_slave);
-                       printk(KERN_INFO DRV_NAME
-                              ": %s: first active interface up!\n",
-                              bond->dev->name);
-                       netif_carrier_on(bond->dev);
-
                } else {
                        dprintk("This is just a backup slave\n");
                        bond_set_slave_inactive_flags(new_slave);
@@ -1547,8 +1492,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
                         * is OK, so make this interface the active one
                         */
                        bond_change_active_slave(bond, new_slave);
-               } else {
-                       bond_set_slave_inactive_flags(new_slave);
                }
                break;
        default:
@@ -1567,8 +1510,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
                break;
        } /* switch(bond_mode) */
 
-       bond_set_carrier(bond);
-
        write_unlock_bh(&bond->lock);
 
        res = bond_create_slave_symlinks(bond_dev, slave_dev);
@@ -1708,12 +1649,18 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
                bond_alb_deinit_slave(bond, slave);
        }
 
-       if (oldcurrent == slave)
+       if (oldcurrent == slave) {
                bond_select_active_slave(bond);
 
-       if (bond->slave_cnt == 0) {
-               bond_set_carrier(bond);
+               if (!bond->curr_active_slave) {
+                       printk(KERN_INFO DRV_NAME
+                              ": %s: now running without any active "
+                              "interface !\n",
+                              bond_dev->name);
+               }
+       }
 
+       if (bond->slave_cnt == 0) {
                /* if the last slave was removed, zero the mac address
                 * of the master so it will be set by the application
                 * to the mac address of the first slave
@@ -1777,8 +1724,13 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
        addr.sa_family = slave_dev->type;
        dev_set_mac_address(slave_dev, &addr);
 
-       slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB |
-                                  IFF_SLAVE_INACTIVE);
+       /* restore the original state of the
+        * IFF_NOARP flag that might have been
+        * set by bond_set_slave_inactive_flags()
+        */
+       if ((slave->original_flags & IFF_NOARP) == 0) {
+               slave_dev->flags &= ~IFF_NOARP;
+       }
 
        kfree(slave);
 
@@ -1797,8 +1749,6 @@ static int bond_release_all(struct net_device *bond_dev)
 
        write_lock_bh(&bond->lock);
 
-       netif_carrier_off(bond_dev);
-
        if (bond->slave_cnt == 0) {
                goto out;
        }
@@ -1866,8 +1816,12 @@ static int bond_release_all(struct net_device *bond_dev)
                addr.sa_family = slave_dev->type;
                dev_set_mac_address(slave_dev, &addr);
 
-               slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB |
-                                          IFF_SLAVE_INACTIVE);
+               /* restore the original state of the IFF_NOARP flag that might have
+                * been set by bond_set_slave_inactive_flags()
+                */
+               if ((slave->original_flags & IFF_NOARP) == 0) {
+                       slave_dev->flags &= ~IFF_NOARP;
+               }
 
                kfree(slave);
 
@@ -2235,9 +2189,15 @@ void bond_mii_monitor(struct net_device *bond_dev)
 
                bond_select_active_slave(bond);
 
+               if (oldcurrent && !bond->curr_active_slave) {
+                       printk(KERN_INFO DRV_NAME
+                              ": %s: now running without any active "
+                              "interface !\n",
+                              bond_dev->name);
+               }
+
                write_unlock(&bond->curr_slave_lock);
-       } else
-               bond_set_carrier(bond);
+       }
 
 re_arm:
        if (bond->params.miimon) {
@@ -2541,6 +2501,13 @@ void bond_loadbalance_arp_mon(struct net_device *bond_dev)
 
                bond_select_active_slave(bond);
 
+               if (oldcurrent && !bond->curr_active_slave) {
+                       printk(KERN_INFO DRV_NAME
+                              ": %s: now running without any active "
+                              "interface !\n",
+                              bond_dev->name);
+               }
+
                write_unlock(&bond->curr_slave_lock);
        }
 
@@ -2614,15 +2581,12 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev)
                                        bond->current_arp_slave = NULL;
                                }
 
-                               bond_set_carrier(bond);
-
                                if (slave == bond->curr_active_slave) {
                                        printk(KERN_INFO DRV_NAME
                                               ": %s: %s is up and now the "
                                               "active interface\n",
                                               bond_dev->name,
                                               slave->dev->name);
-                                       netif_carrier_on(bond->dev);
                                } else {
                                        printk(KERN_INFO DRV_NAME
                                               ": %s: backup interface %s is "
@@ -2882,8 +2846,7 @@ static void bond_info_show_master(struct seq_file *seq)
                           (curr) ? curr->dev->name : "None");
        }
 
-       seq_printf(seq, "MII Status: %s\n", netif_carrier_ok(bond->dev) ?
-                  "up" : "down");
+       seq_printf(seq, "MII Status: %s\n", (curr) ? "up" : "down");
        seq_printf(seq, "MII Polling Interval (ms): %d\n", bond->params.miimon);
        seq_printf(seq, "Up Delay (ms): %d\n",
                   bond->params.updelay * bond->params.miimon);
@@ -3198,7 +3161,7 @@ static int bond_slave_netdev_event(unsigned long event, struct net_device *slave
  * bond_netdev_event: handle netdev notifier chain events.
  *
  * This function receives events for the netdev chain.  The caller (an
- * ioctl handler calling blocking_notifier_call_chain) holds the necessary
+ * ioctl handler calling notifier_call_chain) holds the necessary
  * locks for us to safely manipulate the slave devices (RTNL lock,
  * dev_probe_lock).
  */
@@ -3547,7 +3510,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
                        mii->val_out = 0;
                        read_lock_bh(&bond->lock);
                        read_lock(&bond->curr_slave_lock);
-                       if (netif_carrier_ok(bond->dev)) {
+                       if (bond->curr_active_slave) {
                                mii->val_out = BMSR_LSTATUS;
                        }
                        read_unlock(&bond->curr_slave_lock);
@@ -4098,17 +4061,14 @@ void bond_set_mode_ops(struct bonding *bond, int mode)
                bond_dev->hard_start_xmit = bond_xmit_broadcast;
                break;
        case BOND_MODE_8023AD:
-               bond_set_master_3ad_flags(bond);
                bond_dev->hard_start_xmit = bond_3ad_xmit_xor;
                if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34)
                        bond->xmit_hash_policy = bond_xmit_hash_policy_l34;
                else
                        bond->xmit_hash_policy = bond_xmit_hash_policy_l2;
                break;
-       case BOND_MODE_ALB:
-               bond_set_master_alb_flags(bond);
-               /* FALLTHRU */
        case BOND_MODE_TLB:
+       case BOND_MODE_ALB:
                bond_dev->hard_start_xmit = bond_alb_xmit;
                bond_dev->set_mac_address = bond_alb_set_mac_address;
                break;
@@ -4187,7 +4147,7 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
         */
        bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
 
-       /* don't acquire bond device's netif_tx_lock when
+       /* don't acquire bond device's xmit_lock when 
         * transmitting */
        bond_dev->features |= NETIF_F_LLTX;
 
@@ -4532,8 +4492,6 @@ static int bond_check_params(struct bond_params *params)
        return 0;
 }
 
-static struct lock_class_key bonding_netdev_xmit_lock_key;
-
 /* Create a new bond based on the specified name and bonding parameters.
  * Caller must NOT hold rtnl_lock; we need to release it here before we
  * set up our sysfs entries.
@@ -4569,14 +4527,9 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond
        if (res < 0) {
                goto out_bond;
        }
-
-       lockdep_set_class(&bond_dev->_xmit_lock, &bonding_netdev_xmit_lock_key);
-
        if (newbond)
                *newbond = bond_dev->priv;
 
-       netif_carrier_off(bond_dev);
-
        rtnl_unlock(); /* allows sysfs registration of net device */
        res = bond_create_sysfs_entry(bond_dev->priv);
        goto done;