diff -ur linux-2.4.36-alb35.3/drivers/net/bonding/bond_main.c linux-2.4.36-alb35.3-alb500/drivers/net/bonding/bond_main.c --- linux-2.4.36-alb35.3/drivers/net/bonding/bond_main.c Sun Jul 20 22:06:13 2008 +++ linux-2.4.36-alb35.3-alb500/drivers/net/bonding/bond_main.c Mon Jul 21 00:36:29 2008 @@ -1074,7 +1074,11 @@ * if supports MII link status reporting, check its link status. * * We either do MII/ETHTOOL ioctls, or check netif_carrier_ok(), - * depening upon the setting of the use_carrier parameter. + * depening upon the setting of the use_carrier parameter. If use_carrier is + * not set, it is probably because the device does not support it reliably. + * However, a lot of other areas in the code rely on it through the IS_UP() + * macro. Thus we take this opportunity to update the slave's carrier status + * in order to report consistent status everywhere. * * Return either BMSR_LSTATUS, meaning that the link is up (or we * can't tell and just pretend it is), or 0, meaning that the link is @@ -1092,9 +1096,11 @@ struct ifreq ifr; struct mii_ioctl_data *mii; struct ethtool_value etool; + int old_link; + old_link = netif_carrier_ok(slave_dev); if (bond->params.use_carrier) { - return netif_carrier_ok(slave_dev) ? BMSR_LSTATUS : 0; + return old_link ? BMSR_LSTATUS : 0; } ioctl = slave_dev->do_ioctl; @@ -1117,7 +1123,15 @@ if (IOCTL(slave_dev, &ifr, SIOCGMIIPHY) == 0) { mii->reg_num = MII_BMSR; if (IOCTL(slave_dev, &ifr, SIOCGMIIREG) == 0) { - return (mii->val_out & BMSR_LSTATUS); + if (mii->val_out & BMSR_LSTATUS) { + if (!old_link) + netif_carrier_on(slave_dev); + return BMSR_LSTATUS; + } else { + if (old_link) + netif_carrier_off(slave_dev); + return 0; + } } } } @@ -1131,7 +1145,15 @@ link = slave_dev->ethtool_ops->get_link(slave_dev); - return link ? BMSR_LSTATUS : 0; + if (link) { + if (!old_link) + netif_carrier_on(slave_dev); + return BMSR_LSTATUS; + } else { + if (old_link) + netif_carrier_off(slave_dev); + return 0; + } } } @@ -1141,9 +1163,13 @@ ifr.ifr_data = (char*)&etool; if (IOCTL(slave_dev, &ifr, SIOCETHTOOL) == 0) { if (etool.data == 1) { + if (!old_link) + netif_carrier_on(slave_dev); return BMSR_LSTATUS; } else { dprintk("SIOCETHTOOL shows link down\n"); + if (old_link) + netif_carrier_off(slave_dev); return 0; } } @@ -1155,7 +1181,13 @@ * cannot report link status). If not reporting, pretend * we're ok. */ - return (reporting ? -1 : BMSR_LSTATUS); + if (reporting) + return -1; + + if (!old_link) + netif_carrier_on(slave_dev); + + return BMSR_LSTATUS; } /*----------------------------- Multicast list ------------------------------*/