]> Pileus Git - ~andy/linux/blobdiff - drivers/net/bonding/bond_main.c
reciprocal_divide: update/correction of the algorithm
[~andy/linux] / drivers / net / bonding / bond_main.c
index f00dd45b0308d6f3035f7156076c2e7a17d13b11..f100bd958b8896d594d74012273137387e156b57 100644 (file)
@@ -79,7 +79,6 @@
 #include <net/pkt_sched.h>
 #include <linux/rculist.h>
 #include <net/flow_keys.h>
-#include <linux/reciprocal_div.h>
 #include "bonding.h"
 #include "bond_3ad.h"
 #include "bond_alb.h"
@@ -466,6 +465,22 @@ static void bond_update_speed_duplex(struct slave *slave)
        return;
 }
 
+const char *bond_slave_link_status(s8 link)
+{
+       switch (link) {
+       case BOND_LINK_UP:
+               return "up";
+       case BOND_LINK_FAIL:
+               return "going down";
+       case BOND_LINK_DOWN:
+               return "down";
+       case BOND_LINK_BACK:
+               return "going back";
+       default:
+               return "unknown";
+       }
+}
+
 /*
  * if <dev> supports MII link status reporting, check its link status.
  *
@@ -1576,6 +1591,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
                goto err_unregister;
        }
 
+       res = bond_sysfs_slave_add(new_slave);
+       if (res) {
+               pr_debug("Error %d calling bond_sysfs_slave_add\n", res);
+               goto err_upper_unlink;
+       }
+
        bond->slave_cnt++;
        bond_compute_features(bond);
        bond_set_carrier(bond);
@@ -1595,6 +1616,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
        return 0;
 
 /* Undo stages on error */
+err_upper_unlink:
+       bond_upper_dev_unlink(bond_dev, slave_dev);
+
 err_unregister:
        netdev_rx_handler_unregister(slave_dev);
 
@@ -1687,6 +1711,8 @@ static int __bond_release_one(struct net_device *bond_dev,
        /* release the slave from its bond */
        bond->slave_cnt--;
 
+       bond_sysfs_slave_del(slave);
+
        bond_upper_dev_unlink(bond_dev, slave_dev);
        /* unregister rx_handler early so bond_handle_frame wouldn't be called
         * for this slave anymore.
@@ -3569,8 +3595,9 @@ static void bond_xmit_slave_id(struct bonding *bond, struct sk_buff *skb, int sl
  */
 static u32 bond_rr_gen_slave_id(struct bonding *bond)
 {
-       int packets_per_slave = bond->params.packets_per_slave;
        u32 slave_id;
+       struct reciprocal_value reciprocal_packets_per_slave;
+       int packets_per_slave = bond->params.packets_per_slave;
 
        switch (packets_per_slave) {
        case 0:
@@ -3580,8 +3607,10 @@ static u32 bond_rr_gen_slave_id(struct bonding *bond)
                slave_id = bond->rr_tx_counter;
                break;
        default:
+               reciprocal_packets_per_slave =
+                       bond->params.reciprocal_packets_per_slave;
                slave_id = reciprocal_divide(bond->rr_tx_counter,
-                                            packets_per_slave);
+                                            reciprocal_packets_per_slave);
                break;
        }
        bond->rr_tx_counter++;
@@ -3856,6 +3885,7 @@ static const struct net_device_ops bond_netdev_ops = {
 #endif
        .ndo_add_slave          = bond_enslave,
        .ndo_del_slave          = bond_release,
+       .ndo_get_slave          = bond_get_slave,
        .ndo_fix_features       = bond_fix_features,
 };
 
@@ -4315,10 +4345,18 @@ static int bond_check_params(struct bond_params *params)
        params->resend_igmp = resend_igmp;
        params->min_links = min_links;
        params->lp_interval = lp_interval;
-       if (packets_per_slave > 1)
-               params->packets_per_slave = reciprocal_value(packets_per_slave);
-       else
-               params->packets_per_slave = packets_per_slave;
+       params->packets_per_slave = packets_per_slave;
+       if (packets_per_slave > 0) {
+               params->reciprocal_packets_per_slave =
+                       reciprocal_value(packets_per_slave);
+       } else {
+               /* reciprocal_packets_per_slave is unused if
+                * packets_per_slave is 0 or 1, just initialize it
+                */
+               params->reciprocal_packets_per_slave =
+                       (struct reciprocal_value) { 0 };
+       }
+
        if (primary) {
                strncpy(params->primary, primary, IFNAMSIZ);
                params->primary[IFNAMSIZ - 1] = 0;