diff options
author | Michael Chan <mchan@broadcom.com> | 2006-11-19 17:08:29 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-12-03 00:24:20 -0500 |
commit | f8dd064ee1bd62ef2cdb398cb9cdc8a8f112cb28 (patch) | |
tree | 0b112a7f0025033647b1ab70784f3e7501b1661f /drivers/net/bnx2.c | |
parent | 48b01e2d7c83d37321722f1cdd46193d4ca73b41 (diff) |
[BNX2]: Add 5708S parallel detection.
Add code to parallel detect 1Gbps and 2.5Gbps link speeds.
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2.c')
-rw-r--r-- | drivers/net/bnx2.c | 77 |
1 files changed, 56 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 | ||
4230 | static void | 4228 | static void |
4229 | bnx2_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 | |||
4263 | static void | ||
4231 | bnx2_timer(unsigned long data) | 4264 | bnx2_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 | ||
4251 | bnx2_restart_timer: | 4287 | bnx2_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); |