diff -ur linux-2.6.11-rc2-bk8/net/core/link_watch.c linux-2.6.11-work/net/core/link_watch.c --- linux-2.6.11-rc2-bk8/net/core/link_watch.c 2005-01-30 22:08:44.000000000 +0100 +++ linux-2.6.11-work/net/core/link_watch.c 2005-01-31 00:17:45.716039247 +0100 @@ -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 -ur linux-2.6.11-rc2-bk8/net/sched/sch_generic.c linux-2.6.11-work/net/sched/sch_generic.c --- linux-2.6.11-rc2-bk8/net/sched/sch_generic.c 2005-01-30 22:11:50.458216314 +0100 +++ linux-2.6.11-work/net/sched/sch_generic.c 2005-01-31 00:06:47.609769835 +0100 @@ -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); }