diff -ru linux-2.6.12-rc3/net/core/link_watch.c linux-2.6.12-work/net/core/link_watch.c --- linux-2.6.12-rc3/net/core/link_watch.c 2005-03-04 09:55:42.000000000 +0100 +++ linux-2.6.12-work/net/core/link_watch.c 2005-04-26 22:19:22.939393488 +0200 @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -74,6 +75,9 @@ clear_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state); if (dev->flags & IFF_UP) { + if (netif_carrier_ok(dev) && + dev->qdisc_sleeping != &noop_qdisc) + dev_activate(dev); netdev_state_change(dev); } diff -ru linux-2.6.12-rc3/net/sched/sch_generic.c linux-2.6.12-work/net/sched/sch_generic.c --- linux-2.6.12-rc3/net/sched/sch_generic.c 2005-03-04 09:55:44.000000000 +0100 +++ linux-2.6.12-work/net/sched/sch_generic.c 2005-04-26 22:19:22.939393488 +0200 @@ -185,6 +185,7 @@ static void dev_watchdog(unsigned long arg) { struct net_device *dev = (struct net_device *)arg; + int check_carrier = 0; spin_lock(&dev->xmit_lock); if (dev->qdisc != &noop_qdisc) { @@ -198,10 +199,23 @@ } if (!mod_timer(&dev->watchdog_timer, jiffies + dev->watchdog_timeo)) dev_hold(dev); - } + } else + check_carrier = 1; } spin_unlock(&dev->xmit_lock); + if (check_carrier) { + spin_lock(&dev->queue_lock); + if (!netif_carrier_ok(dev) && netif_queue_stopped(dev)) { + struct Qdisc *qdisc; + + qdisc = dev->qdisc; + dev->qdisc = &noop_qdisc; + qdisc_reset(qdisc); + } + spin_unlock(&dev->queue_lock); + } + dev_put(dev); }