]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - net/bridge/br_stp.c
timekeeping: Use syscore_ops instead of sysdev class and sysdev
[mv-sheeva.git] / net / bridge / br_stp.c
index 57186d84d2bd6497366d7d4d7cca7a694e0b5818..7370d14f634d71427d993dae89cd017067e8fcd1 100644 (file)
@@ -375,12 +375,12 @@ static void br_make_forwarding(struct net_bridge_port *p)
        if (p->state != BR_STATE_BLOCKING)
                return;
 
-       if (br->forward_delay == 0) {
+       if (br->stp_enabled == BR_NO_STP || br->forward_delay == 0) {
                p->state = BR_STATE_FORWARDING;
                br_topology_change_detection(br);
                del_timer(&p->forward_delay_timer);
        }
-       else if (p->br->stp_enabled == BR_KERNEL_STP)
+       else if (br->stp_enabled == BR_KERNEL_STP)
                p->state = BR_STATE_LISTENING;
        else
                p->state = BR_STATE_LEARNING;
@@ -397,28 +397,37 @@ static void br_make_forwarding(struct net_bridge_port *p)
 void br_port_state_selection(struct net_bridge *br)
 {
        struct net_bridge_port *p;
+       unsigned int liveports = 0;
 
        /* Don't change port states if userspace is handling STP */
        if (br->stp_enabled == BR_USER_STP)
                return;
 
        list_for_each_entry(p, &br->port_list, list) {
-               if (p->state != BR_STATE_DISABLED) {
-                       if (p->port_no == br->root_port) {
-                               p->config_pending = 0;
-                               p->topology_change_ack = 0;
-                               br_make_forwarding(p);
-                       } else if (br_is_designated_port(p)) {
-                               del_timer(&p->message_age_timer);
-                               br_make_forwarding(p);
-                       } else {
-                               p->config_pending = 0;
-                               p->topology_change_ack = 0;
-                               br_make_blocking(p);
-                       }
+               if (p->state == BR_STATE_DISABLED)
+                       continue;
+
+               if (p->port_no == br->root_port) {
+                       p->config_pending = 0;
+                       p->topology_change_ack = 0;
+                       br_make_forwarding(p);
+               } else if (br_is_designated_port(p)) {
+                       del_timer(&p->message_age_timer);
+                       br_make_forwarding(p);
+               } else {
+                       p->config_pending = 0;
+                       p->topology_change_ack = 0;
+                       br_make_blocking(p);
                }
 
+               if (p->state == BR_STATE_FORWARDING)
+                       ++liveports;
        }
+
+       if (liveports == 0)
+               netif_carrier_off(br->dev);
+       else
+               netif_carrier_on(br->dev);
 }
 
 /* called under bridge lock */