aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2.c
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2008-02-23 22:47:44 -0500
committerDavid S. Miller <davem@davemloft.net>2008-02-23 22:47:44 -0500
commita2724e2559a3c41ac6182da6e2446d3abf0720a5 (patch)
tree6c22dd23d577d8bcb744e77b513190c97e3c3450 /drivers/net/bnx2.c
parentfc71acc846c577473ada72a46c5ea9c935eca086 (diff)
[BNX2]: More 5706S link down workaround.
The previous patches to workaround the 5706S on an HP blade were not sufficient. The link state still does not change properly in some cases. This patch adds polling to make it completely reliable. 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.c32
1 files changed, 17 insertions, 15 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 471c7f3e8a4a..2fa258050968 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -1273,14 +1273,20 @@ bnx2_set_link(struct bnx2 *bp)
1273 1273
1274 if ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) && 1274 if ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) &&
1275 (CHIP_NUM(bp) == CHIP_NUM_5706)) { 1275 (CHIP_NUM(bp) == CHIP_NUM_5706)) {
1276 u32 val; 1276 u32 val, an_dbg;
1277 1277
1278 if (bp->phy_flags & BNX2_PHY_FLAG_FORCED_DOWN) { 1278 if (bp->phy_flags & BNX2_PHY_FLAG_FORCED_DOWN) {
1279 bnx2_5706s_force_link_dn(bp, 0); 1279 bnx2_5706s_force_link_dn(bp, 0);
1280 bp->phy_flags &= ~BNX2_PHY_FLAG_FORCED_DOWN; 1280 bp->phy_flags &= ~BNX2_PHY_FLAG_FORCED_DOWN;
1281 } 1281 }
1282 val = REG_RD(bp, BNX2_EMAC_STATUS); 1282 val = REG_RD(bp, BNX2_EMAC_STATUS);
1283 if (val & BNX2_EMAC_STATUS_LINK) 1283
1284 bnx2_write_phy(bp, MII_BNX2_MISC_SHADOW, MISC_SHDW_AN_DBG);
1285 bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &an_dbg);
1286 bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &an_dbg);
1287
1288 if ((val & BNX2_EMAC_STATUS_LINK) &&
1289 !(an_dbg & MISC_SHDW_AN_DBG_NOSYNC))
1284 bmsr |= BMSR_LSTATUS; 1290 bmsr |= BMSR_LSTATUS;
1285 else 1291 else
1286 bmsr &= ~BMSR_LSTATUS; 1292 bmsr &= ~BMSR_LSTATUS;
@@ -5390,13 +5396,6 @@ bnx2_5706_serdes_timer(struct bnx2 *bp)
5390 int check_link = 1; 5396 int check_link = 1;
5391 5397
5392 spin_lock(&bp->phy_lock); 5398 spin_lock(&bp->phy_lock);
5393 if (bp->phy_flags & BNX2_PHY_FLAG_FORCED_DOWN) {
5394 bnx2_5706s_force_link_dn(bp, 0);
5395 bp->phy_flags &= ~BNX2_PHY_FLAG_FORCED_DOWN;
5396 spin_unlock(&bp->phy_lock);
5397 return;
5398 }
5399
5400 if (bp->serdes_an_pending) { 5399 if (bp->serdes_an_pending) {
5401 bp->serdes_an_pending--; 5400 bp->serdes_an_pending--;
5402 check_link = 0; 5401 check_link = 0;
@@ -5420,7 +5419,6 @@ bnx2_5706_serdes_timer(struct bnx2 *bp)
5420 (bp->phy_flags & BNX2_PHY_FLAG_PARALLEL_DETECT)) { 5419 (bp->phy_flags & BNX2_PHY_FLAG_PARALLEL_DETECT)) {
5421 u32 phy2; 5420 u32 phy2;
5422 5421
5423 check_link = 0;
5424 bnx2_write_phy(bp, 0x17, 0x0f01); 5422 bnx2_write_phy(bp, 0x17, 0x0f01);
5425 bnx2_read_phy(bp, 0x15, &phy2); 5423 bnx2_read_phy(bp, 0x15, &phy2);
5426 if (phy2 & 0x20) { 5424 if (phy2 & 0x20) {
@@ -5435,17 +5433,21 @@ bnx2_5706_serdes_timer(struct bnx2 *bp)
5435 } else 5433 } else
5436 bp->current_interval = bp->timer_interval; 5434 bp->current_interval = bp->timer_interval;
5437 5435
5438 if (bp->link_up && (bp->autoneg & AUTONEG_SPEED) && check_link) { 5436 if (check_link) {
5439 u32 val; 5437 u32 val;
5440 5438
5441 bnx2_write_phy(bp, MII_BNX2_MISC_SHADOW, MISC_SHDW_AN_DBG); 5439 bnx2_write_phy(bp, MII_BNX2_MISC_SHADOW, MISC_SHDW_AN_DBG);
5442 bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &val); 5440 bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &val);
5443 bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &val); 5441 bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &val);
5444 5442
5445 if (val & MISC_SHDW_AN_DBG_NOSYNC) { 5443 if (bp->link_up && (val & MISC_SHDW_AN_DBG_NOSYNC)) {
5446 bnx2_5706s_force_link_dn(bp, 1); 5444 if (!(bp->phy_flags & BNX2_PHY_FLAG_FORCED_DOWN)) {
5447 bp->phy_flags |= BNX2_PHY_FLAG_FORCED_DOWN; 5445 bnx2_5706s_force_link_dn(bp, 1);
5448 } 5446 bp->phy_flags |= BNX2_PHY_FLAG_FORCED_DOWN;
5447 } else
5448 bnx2_set_link(bp);
5449 } else if (!bp->link_up && !(val & MISC_SHDW_AN_DBG_NOSYNC))
5450 bnx2_set_link(bp);
5449 } 5451 }
5450 spin_unlock(&bp->phy_lock); 5452 spin_unlock(&bp->phy_lock);
5451} 5453}