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 | |
| 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')
| -rw-r--r-- | drivers/net/bnx2.c | 77 | ||||
| -rw-r--r-- | drivers/net/bnx2.h | 1 |
2 files changed, 57 insertions, 21 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 78974810e3..ea5daf6efa 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); |
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 78ff09d70d..7fa7008f40 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 | ||
