Merge branch 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[pandora-kernel.git] / drivers / net / bonding / bond_3ad.c
index c7537ab..a047eb9 100644 (file)
@@ -262,7 +262,7 @@ static inline u32 __get_agg_selection_mode(struct port *port)
        if (bond == NULL)
                return BOND_AD_STABLE;
 
-       return BOND_AD_INFO(bond).agg_select_mode;
+       return bond->params.ad_select;
 }
 
 /**
@@ -1859,7 +1859,6 @@ static void ad_marker_response_received(struct bond_marker *marker,
 void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout)
 {
        BOND_AD_INFO(bond).agg_select_timer = timeout;
-       BOND_AD_INFO(bond).agg_select_mode = bond->params.ad_select;
 }
 
 static u16 aggregator_identifier;
@@ -1868,11 +1867,10 @@ static u16 aggregator_identifier;
  * bond_3ad_initialize - initialize a bond's 802.3ad parameters and structures
  * @bond: bonding struct to work on
  * @tick_resolution: tick duration (millisecond resolution)
- * @lacp_fast: boolean. whether fast periodic should be used
  *
  * Can be called only after the mac address of the bond is set.
  */
-void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution, int lacp_fast)
+void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution)
 {
        // check that the bond is not initialized yet
        if (MAC_ADDRESS_COMPARE(&(BOND_AD_INFO(bond).system.sys_mac_addr),
@@ -1880,7 +1878,6 @@ void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution, int lacp_fas
 
                aggregator_identifier = 0;
 
-               BOND_AD_INFO(bond).lacp_fast = lacp_fast;
                BOND_AD_INFO(bond).system.sys_priority = 0xFFFF;
                BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->dev->dev_addr);
 
@@ -1918,7 +1915,7 @@ int bond_3ad_bind_slave(struct slave *slave)
                // port initialization
                port = &(SLAVE_AD_INFO(slave).port);
 
-               ad_initialize_port(port, BOND_AD_INFO(bond).lacp_fast);
+               ad_initialize_port(port, bond->params.lacp_fast);
 
                port->slave = slave;
                port->actor_port_number = SLAVE_AD_INFO(slave).id;
@@ -2345,8 +2342,17 @@ void bond_3ad_handle_link_change(struct slave *slave, char link)
  */
 int bond_3ad_set_carrier(struct bonding *bond)
 {
-       if (__get_active_agg(&(SLAVE_AD_INFO(bond->first_slave).aggregator))) {
-               if (!netif_carrier_ok(bond->dev)) {
+       struct aggregator *active;
+
+       active = __get_active_agg(&(SLAVE_AD_INFO(bond->first_slave).aggregator));
+       if (active) {
+               /* are enough slaves available to consider link up? */
+               if (active->num_of_ports < bond->params.min_links) {
+                       if (netif_carrier_ok(bond->dev)) {
+                               netif_carrier_off(bond->dev);
+                               return 1;
+                       }
+               } else if (!netif_carrier_ok(bond->dev)) {
                        netif_carrier_on(bond->dev);
                        return 1;
                }
@@ -2473,3 +2479,34 @@ void bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond,
        bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len);
        read_unlock(&bond->lock);
 }
+
+/*
+ * When modify lacp_rate parameter via sysfs,
+ * update actor_oper_port_state of each port.
+ *
+ * Hold slave->state_machine_lock,
+ * so we can modify port->actor_oper_port_state,
+ * no matter bond is up or down.
+ */
+void bond_3ad_update_lacp_rate(struct bonding *bond)
+{
+       int i;
+       struct slave *slave;
+       struct port *port = NULL;
+       int lacp_fast;
+
+       read_lock(&bond->lock);
+       lacp_fast = bond->params.lacp_fast;
+
+       bond_for_each_slave(bond, slave, i) {
+               port = &(SLAVE_AD_INFO(slave).port);
+               __get_state_machine_lock(port);
+               if (lacp_fast)
+                       port->actor_oper_port_state |= AD_STATE_LACP_TIMEOUT;
+               else
+                       port->actor_oper_port_state &= ~AD_STATE_LACP_TIMEOUT;
+               __release_state_machine_lock(port);
+       }
+
+       read_unlock(&bond->lock);
+}