aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/bnx2.c77
-rw-r--r--drivers/net/bnx2.h1
2 files changed, 57 insertions, 21 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 78974810e307..ea5daf6efa09 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -1067,19 +1067,17 @@ bnx2_setup_serdes_phy(struct bnx2 *bp)
1067 bnx2_write_phy(bp, MII_ADVERTISE, new_adv); 1067 bnx2_write_phy(bp, MII_ADVERTISE, new_adv);
1068 bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART | 1068 bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART |
1069 BMCR_ANENABLE); 1069 BMCR_ANENABLE);
1070 if (CHIP_NUM(bp) == CHIP_NUM_5706) { 1070 /* Speed up link-up time when the link partner
1071 /* Speed up link-up time when the link partner 1071 * does not autonegotiate which is very common
1072 * does not autonegotiate which is very common 1072 * in blade servers. Some blade servers use
1073 * in blade servers. Some blade servers use 1073 * IPMI for kerboard input and it's important
1074 * IPMI for kerboard input and it's important 1074 * to minimize link disruptions. Autoneg. involves
1075 * to minimize link disruptions. Autoneg. involves 1075 * exchanging base pages plus 3 next pages and
1076 * exchanging base pages plus 3 next pages and 1076 * normally completes in about 120 msec.
1077 * normally completes in about 120 msec. 1077 */
1078 */ 1078 bp->current_interval = SERDES_AN_TIMEOUT;
1079 bp->current_interval = SERDES_AN_TIMEOUT; 1079 bp->serdes_an_pending = 1;
1080 bp->serdes_an_pending = 1; 1080 mod_timer(&bp->timer, jiffies + bp->current_interval);
1081 mod_timer(&bp->timer, jiffies + bp->current_interval);
1082 }
1083 } 1081 }
1084 1082
1085 return 0; 1083 return 0;
@@ -4228,6 +4226,41 @@ bnx2_5706_serdes_timer(struct bnx2 *bp)
4228} 4226}
4229 4227
4230static void 4228static void
4229bnx2_5708_serdes_timer(struct bnx2 *bp)
4230{
4231 if ((bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) == 0) {
4232 bp->serdes_an_pending = 0;
4233 return;
4234 }
4235
4236 spin_lock(&bp->phy_lock);
4237 if (bp->serdes_an_pending)
4238 bp->serdes_an_pending--;
4239 else if ((bp->link_up == 0) && (bp->autoneg & AUTONEG_SPEED)) {
4240 u32 bmcr;
4241
4242 bnx2_read_phy(bp, MII_BMCR, &bmcr);
4243
4244 if (bmcr & BMCR_ANENABLE) {
4245 bmcr &= ~BMCR_ANENABLE;
4246 bmcr |= BMCR_FULLDPLX | BCM5708S_BMCR_FORCE_2500;
4247 bnx2_write_phy(bp, MII_BMCR, bmcr);
4248 bp->current_interval = SERDES_FORCED_TIMEOUT;
4249 } else {
4250 bmcr &= ~(BMCR_FULLDPLX | BCM5708S_BMCR_FORCE_2500);
4251 bmcr |= BMCR_ANENABLE;
4252 bnx2_write_phy(bp, MII_BMCR, bmcr);
4253 bp->serdes_an_pending = 2;
4254 bp->current_interval = bp->timer_interval;
4255 }
4256
4257 } else
4258 bp->current_interval = bp->timer_interval;
4259
4260 spin_unlock(&bp->phy_lock);
4261}
4262
4263static void
4231bnx2_timer(unsigned long data) 4264bnx2_timer(unsigned long data)
4232{ 4265{
4233 struct bnx2 *bp = (struct bnx2 *) data; 4266 struct bnx2 *bp = (struct bnx2 *) data;
@@ -4244,9 +4277,12 @@ bnx2_timer(unsigned long data)
4244 4277
4245 bp->stats_blk->stat_FwRxDrop = REG_RD_IND(bp, BNX2_FW_RX_DROP_COUNT); 4278 bp->stats_blk->stat_FwRxDrop = REG_RD_IND(bp, BNX2_FW_RX_DROP_COUNT);
4246 4279
4247 if ((bp->phy_flags & PHY_SERDES_FLAG) && 4280 if (bp->phy_flags & PHY_SERDES_FLAG) {
4248 (CHIP_NUM(bp) == CHIP_NUM_5706)) 4281 if (CHIP_NUM(bp) == CHIP_NUM_5706)
4249 bnx2_5706_serdes_timer(bp); 4282 bnx2_5706_serdes_timer(bp);
4283 else if (CHIP_NUM(bp) == CHIP_NUM_5708)
4284 bnx2_5708_serdes_timer(bp);
4285 }
4250 4286
4251bnx2_restart_timer: 4287bnx2_restart_timer:
4252 mod_timer(&bp->timer, jiffies + bp->current_interval); 4288 mod_timer(&bp->timer, jiffies + bp->current_interval);
@@ -4917,11 +4953,10 @@ bnx2_nway_reset(struct net_device *dev)
4917 msleep(20); 4953 msleep(20);
4918 4954
4919 spin_lock_bh(&bp->phy_lock); 4955 spin_lock_bh(&bp->phy_lock);
4920 if (CHIP_NUM(bp) == CHIP_NUM_5706) { 4956
4921 bp->current_interval = SERDES_AN_TIMEOUT; 4957 bp->current_interval = SERDES_AN_TIMEOUT;
4922 bp->serdes_an_pending = 1; 4958 bp->serdes_an_pending = 1;
4923 mod_timer(&bp->timer, jiffies + bp->current_interval); 4959 mod_timer(&bp->timer, jiffies + bp->current_interval);
4924 }
4925 } 4960 }
4926 4961
4927 bnx2_read_phy(bp, MII_BMCR, &bmcr); 4962 bnx2_read_phy(bp, MII_BMCR, &bmcr);
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index 78ff09d70de4..7fa7008f402a 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -4040,6 +4040,7 @@ struct bnx2 {
4040 4040
4041 u8 serdes_an_pending; 4041 u8 serdes_an_pending;
4042#define SERDES_AN_TIMEOUT (HZ / 3) 4042#define SERDES_AN_TIMEOUT (HZ / 3)
4043#define SERDES_FORCED_TIMEOUT (HZ / 10)
4043 4044
4044 u8 mac_addr[8]; 4045 u8 mac_addr[8];
4045 4046