Loading drivers/net/bnx2.c +56 −21 Original line number Diff line number Diff line Loading @@ -1067,7 +1067,6 @@ bnx2_setup_serdes_phy(struct bnx2 *bp) bnx2_write_phy(bp, MII_ADVERTISE, new_adv); bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART | BMCR_ANENABLE); if (CHIP_NUM(bp) == CHIP_NUM_5706) { /* Speed up link-up time when the link partner * does not autonegotiate which is very common * in blade servers. Some blade servers use Loading @@ -1080,7 +1079,6 @@ bnx2_setup_serdes_phy(struct bnx2 *bp) bp->serdes_an_pending = 1; mod_timer(&bp->timer, jiffies + bp->current_interval); } } return 0; } Loading Loading @@ -4227,6 +4225,41 @@ bnx2_5706_serdes_timer(struct bnx2 *bp) spin_unlock(&bp->phy_lock); } static void bnx2_5708_serdes_timer(struct bnx2 *bp) { if ((bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) == 0) { bp->serdes_an_pending = 0; return; } spin_lock(&bp->phy_lock); if (bp->serdes_an_pending) bp->serdes_an_pending--; else if ((bp->link_up == 0) && (bp->autoneg & AUTONEG_SPEED)) { u32 bmcr; bnx2_read_phy(bp, MII_BMCR, &bmcr); if (bmcr & BMCR_ANENABLE) { bmcr &= ~BMCR_ANENABLE; bmcr |= BMCR_FULLDPLX | BCM5708S_BMCR_FORCE_2500; bnx2_write_phy(bp, MII_BMCR, bmcr); bp->current_interval = SERDES_FORCED_TIMEOUT; } else { bmcr &= ~(BMCR_FULLDPLX | BCM5708S_BMCR_FORCE_2500); bmcr |= BMCR_ANENABLE; bnx2_write_phy(bp, MII_BMCR, bmcr); bp->serdes_an_pending = 2; bp->current_interval = bp->timer_interval; } } else bp->current_interval = bp->timer_interval; spin_unlock(&bp->phy_lock); } static void bnx2_timer(unsigned long data) { Loading @@ -4244,9 +4277,12 @@ bnx2_timer(unsigned long data) bp->stats_blk->stat_FwRxDrop = REG_RD_IND(bp, BNX2_FW_RX_DROP_COUNT); if ((bp->phy_flags & PHY_SERDES_FLAG) && (CHIP_NUM(bp) == CHIP_NUM_5706)) if (bp->phy_flags & PHY_SERDES_FLAG) { if (CHIP_NUM(bp) == CHIP_NUM_5706) bnx2_5706_serdes_timer(bp); else if (CHIP_NUM(bp) == CHIP_NUM_5708) bnx2_5708_serdes_timer(bp); } bnx2_restart_timer: mod_timer(&bp->timer, jiffies + bp->current_interval); Loading Loading @@ -4917,12 +4953,11 @@ bnx2_nway_reset(struct net_device *dev) msleep(20); spin_lock_bh(&bp->phy_lock); if (CHIP_NUM(bp) == CHIP_NUM_5706) { bp->current_interval = SERDES_AN_TIMEOUT; bp->serdes_an_pending = 1; mod_timer(&bp->timer, jiffies + bp->current_interval); } } bnx2_read_phy(bp, MII_BMCR, &bmcr); bmcr &= ~BMCR_LOOPBACK; Loading drivers/net/bnx2.h +1 −0 Original line number Diff line number Diff line Loading @@ -4040,6 +4040,7 @@ struct bnx2 { u8 serdes_an_pending; #define SERDES_AN_TIMEOUT (HZ / 3) #define SERDES_FORCED_TIMEOUT (HZ / 10) u8 mac_addr[8]; Loading Loading
drivers/net/bnx2.c +56 −21 Original line number Diff line number Diff line Loading @@ -1067,7 +1067,6 @@ bnx2_setup_serdes_phy(struct bnx2 *bp) bnx2_write_phy(bp, MII_ADVERTISE, new_adv); bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART | BMCR_ANENABLE); if (CHIP_NUM(bp) == CHIP_NUM_5706) { /* Speed up link-up time when the link partner * does not autonegotiate which is very common * in blade servers. Some blade servers use Loading @@ -1080,7 +1079,6 @@ bnx2_setup_serdes_phy(struct bnx2 *bp) bp->serdes_an_pending = 1; mod_timer(&bp->timer, jiffies + bp->current_interval); } } return 0; } Loading Loading @@ -4227,6 +4225,41 @@ bnx2_5706_serdes_timer(struct bnx2 *bp) spin_unlock(&bp->phy_lock); } static void bnx2_5708_serdes_timer(struct bnx2 *bp) { if ((bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) == 0) { bp->serdes_an_pending = 0; return; } spin_lock(&bp->phy_lock); if (bp->serdes_an_pending) bp->serdes_an_pending--; else if ((bp->link_up == 0) && (bp->autoneg & AUTONEG_SPEED)) { u32 bmcr; bnx2_read_phy(bp, MII_BMCR, &bmcr); if (bmcr & BMCR_ANENABLE) { bmcr &= ~BMCR_ANENABLE; bmcr |= BMCR_FULLDPLX | BCM5708S_BMCR_FORCE_2500; bnx2_write_phy(bp, MII_BMCR, bmcr); bp->current_interval = SERDES_FORCED_TIMEOUT; } else { bmcr &= ~(BMCR_FULLDPLX | BCM5708S_BMCR_FORCE_2500); bmcr |= BMCR_ANENABLE; bnx2_write_phy(bp, MII_BMCR, bmcr); bp->serdes_an_pending = 2; bp->current_interval = bp->timer_interval; } } else bp->current_interval = bp->timer_interval; spin_unlock(&bp->phy_lock); } static void bnx2_timer(unsigned long data) { Loading @@ -4244,9 +4277,12 @@ bnx2_timer(unsigned long data) bp->stats_blk->stat_FwRxDrop = REG_RD_IND(bp, BNX2_FW_RX_DROP_COUNT); if ((bp->phy_flags & PHY_SERDES_FLAG) && (CHIP_NUM(bp) == CHIP_NUM_5706)) if (bp->phy_flags & PHY_SERDES_FLAG) { if (CHIP_NUM(bp) == CHIP_NUM_5706) bnx2_5706_serdes_timer(bp); else if (CHIP_NUM(bp) == CHIP_NUM_5708) bnx2_5708_serdes_timer(bp); } bnx2_restart_timer: mod_timer(&bp->timer, jiffies + bp->current_interval); Loading Loading @@ -4917,12 +4953,11 @@ bnx2_nway_reset(struct net_device *dev) msleep(20); spin_lock_bh(&bp->phy_lock); if (CHIP_NUM(bp) == CHIP_NUM_5706) { bp->current_interval = SERDES_AN_TIMEOUT; bp->serdes_an_pending = 1; mod_timer(&bp->timer, jiffies + bp->current_interval); } } bnx2_read_phy(bp, MII_BMCR, &bmcr); bmcr &= ~BMCR_LOOPBACK; Loading
drivers/net/bnx2.h +1 −0 Original line number Diff line number Diff line Loading @@ -4040,6 +4040,7 @@ struct bnx2 { u8 serdes_an_pending; #define SERDES_AN_TIMEOUT (HZ / 3) #define SERDES_FORCED_TIMEOUT (HZ / 10) u8 mac_addr[8]; Loading