bonding: remove useless assignment
[pandora-kernel.git] / drivers / net / bonding / bond_main.c
index 69c5b15..ef6af1c 100644 (file)
@@ -94,6 +94,7 @@ static int downdelay;
 static int use_carrier = 1;
 static char *mode;
 static char *primary;
+static char *primary_reselect;
 static char *lacp_rate;
 static char *ad_select;
 static char *xmit_hash_policy;
@@ -126,6 +127,14 @@ MODULE_PARM_DESC(mode, "Mode of operation : 0 for balance-rr, "
                       "6 for balance-alb");
 module_param(primary, charp, 0);
 MODULE_PARM_DESC(primary, "Primary network device to use");
+module_param(primary_reselect, charp, 0);
+MODULE_PARM_DESC(primary_reselect, "Reselect primary slave "
+                                  "once it comes up; "
+                                  "0 for always (default), "
+                                  "1 for only if speed of primary is "
+                                  "better, "
+                                  "2 for only on active slave "
+                                  "failure");
 module_param(lacp_rate, charp, 0);
 MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner "
                            "(slow/fast)");
@@ -200,6 +209,13 @@ const struct bond_parm_tbl fail_over_mac_tbl[] = {
 {      NULL,                   -1},
 };
 
+const struct bond_parm_tbl pri_reselect_tbl[] = {
+{      "always",               BOND_PRI_RESELECT_ALWAYS},
+{      "better",               BOND_PRI_RESELECT_BETTER},
+{      "failure",              BOND_PRI_RESELECT_FAILURE},
+{      NULL,                   -1},
+};
+
 struct bond_parm_tbl ad_select_tbl[] = {
 {      "stable",       BOND_AD_STABLE},
 {      "bandwidth",    BOND_AD_BANDWIDTH},
@@ -1070,6 +1086,25 @@ out:
 
 }
 
+static bool bond_should_change_active(struct bonding *bond)
+{
+       struct slave *prim = bond->primary_slave;
+       struct slave *curr = bond->curr_active_slave;
+
+       if (!prim || !curr || curr->link != BOND_LINK_UP)
+               return true;
+       if (bond->force_primary) {
+               bond->force_primary = false;
+               return true;
+       }
+       if (bond->params.primary_reselect == BOND_PRI_RESELECT_BETTER &&
+           (prim->speed < curr->speed ||
+            (prim->speed == curr->speed && prim->duplex <= curr->duplex)))
+               return false;
+       if (bond->params.primary_reselect == BOND_PRI_RESELECT_FAILURE)
+               return false;
+       return true;
+}
 
 /**
  * find_best_interface - select the best available slave to be the active one
@@ -1084,7 +1119,7 @@ static struct slave *bond_find_best_slave(struct bonding *bond)
        int mintime = bond->params.updelay;
        int i;
 
-       new_active = old_active = bond->curr_active_slave;
+       new_active = bond->curr_active_slave;
 
        if (!new_active) { /* there were no active slaves left */
                if (bond->slave_cnt > 0)   /* found one slave */
@@ -1094,7 +1129,8 @@ static struct slave *bond_find_best_slave(struct bonding *bond)
        }
 
        if ((bond->primary_slave) &&
-           bond->primary_slave->link == BOND_LINK_UP) {
+           bond->primary_slave->link == BOND_LINK_UP &&
+           bond_should_change_active(bond)) {
                new_active = bond->primary_slave;
        }
 
@@ -1678,8 +1714,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 
        if (USES_PRIMARY(bond->params.mode) && bond->params.primary[0]) {
                /* if there is a primary slave, remember it */
-               if (strcmp(bond->params.primary, new_slave->dev->name) == 0)
+               if (strcmp(bond->params.primary, new_slave->dev->name) == 0) {
                        bond->primary_slave = new_slave;
+                       bond->force_primary = true;
+               }
        }
 
        write_lock_bh(&bond->curr_slave_lock);
@@ -3201,11 +3239,14 @@ static void bond_info_show_master(struct seq_file *seq)
        }
 
        if (USES_PRIMARY(bond->params.mode)) {
-               seq_printf(seq, "Primary Slave: %s\n",
+               seq_printf(seq, "Primary Slave: %s",
                           (bond->primary_slave) ?
                           bond->primary_slave->dev->name : "None");
+               if (bond->primary_slave)
+                       seq_printf(seq, " (primary_reselect %s)",
+                  pri_reselect_tbl[bond->params.primary_reselect].modename);
 
-               seq_printf(seq, "Currently Active Slave: %s\n",
+               seq_printf(seq, "\nCurrently Active Slave: %s\n",
                           (curr) ? curr->dev->name : "None");
        }
 
@@ -4646,7 +4687,7 @@ int bond_parse_parm(const char *buf, const struct bond_parm_tbl *tbl)
 
 static int bond_check_params(struct bond_params *params)
 {
-       int arp_validate_value, fail_over_mac_value;
+       int arp_validate_value, fail_over_mac_value, primary_reselect_value;
 
        /*
         * Convert string parameters.
@@ -4665,7 +4706,8 @@ static int bond_check_params(struct bond_params *params)
                if ((bond_mode != BOND_MODE_XOR) &&
                    (bond_mode != BOND_MODE_8023AD)) {
                        pr_info(DRV_NAME
-                              ": xor_mode param is irrelevant in mode %s\n",
+                               ": xmit_hash_policy param is irrelevant in"
+                               " mode %s\n",
                               bond_mode_name(bond_mode));
                } else {
                        xmit_hashtype = bond_parse_parm(xmit_hash_policy,
@@ -4945,6 +4987,20 @@ static int bond_check_params(struct bond_params *params)
                primary = NULL;
        }
 
+       if (primary && primary_reselect) {
+               primary_reselect_value = bond_parse_parm(primary_reselect,
+                                                        pri_reselect_tbl);
+               if (primary_reselect_value == -1) {
+                       pr_err(DRV_NAME
+                              ": Error: Invalid primary_reselect \"%s\"\n",
+                              primary_reselect ==
+                                       NULL ? "NULL" : primary_reselect);
+                       return -EINVAL;
+               }
+       } else {
+               primary_reselect_value = BOND_PRI_RESELECT_ALWAYS;
+       }
+
        if (fail_over_mac) {
                fail_over_mac_value = bond_parse_parm(fail_over_mac,
                                                      fail_over_mac_tbl);
@@ -4976,6 +5032,7 @@ static int bond_check_params(struct bond_params *params)
        params->use_carrier = use_carrier;
        params->lacp_fast = lacp_fast;
        params->primary[0] = 0;
+       params->primary_reselect = primary_reselect_value;
        params->fail_over_mac = fail_over_mac_value;
 
        if (primary) {