forked from luck/tmp_suning_uos_patched
[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>
This commit is contained in:
parent
fc71acc846
commit
a2724e2559
@ -1273,14 +1273,20 @@ bnx2_set_link(struct bnx2 *bp)
|
|||||||
|
|
||||||
if ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) &&
|
if ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) &&
|
||||||
(CHIP_NUM(bp) == CHIP_NUM_5706)) {
|
(CHIP_NUM(bp) == CHIP_NUM_5706)) {
|
||||||
u32 val;
|
u32 val, an_dbg;
|
||||||
|
|
||||||
if (bp->phy_flags & BNX2_PHY_FLAG_FORCED_DOWN) {
|
if (bp->phy_flags & BNX2_PHY_FLAG_FORCED_DOWN) {
|
||||||
bnx2_5706s_force_link_dn(bp, 0);
|
bnx2_5706s_force_link_dn(bp, 0);
|
||||||
bp->phy_flags &= ~BNX2_PHY_FLAG_FORCED_DOWN;
|
bp->phy_flags &= ~BNX2_PHY_FLAG_FORCED_DOWN;
|
||||||
}
|
}
|
||||||
val = REG_RD(bp, BNX2_EMAC_STATUS);
|
val = REG_RD(bp, BNX2_EMAC_STATUS);
|
||||||
if (val & BNX2_EMAC_STATUS_LINK)
|
|
||||||
|
bnx2_write_phy(bp, MII_BNX2_MISC_SHADOW, MISC_SHDW_AN_DBG);
|
||||||
|
bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &an_dbg);
|
||||||
|
bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &an_dbg);
|
||||||
|
|
||||||
|
if ((val & BNX2_EMAC_STATUS_LINK) &&
|
||||||
|
!(an_dbg & MISC_SHDW_AN_DBG_NOSYNC))
|
||||||
bmsr |= BMSR_LSTATUS;
|
bmsr |= BMSR_LSTATUS;
|
||||||
else
|
else
|
||||||
bmsr &= ~BMSR_LSTATUS;
|
bmsr &= ~BMSR_LSTATUS;
|
||||||
@ -5390,13 +5396,6 @@ bnx2_5706_serdes_timer(struct bnx2 *bp)
|
|||||||
int check_link = 1;
|
int check_link = 1;
|
||||||
|
|
||||||
spin_lock(&bp->phy_lock);
|
spin_lock(&bp->phy_lock);
|
||||||
if (bp->phy_flags & BNX2_PHY_FLAG_FORCED_DOWN) {
|
|
||||||
bnx2_5706s_force_link_dn(bp, 0);
|
|
||||||
bp->phy_flags &= ~BNX2_PHY_FLAG_FORCED_DOWN;
|
|
||||||
spin_unlock(&bp->phy_lock);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bp->serdes_an_pending) {
|
if (bp->serdes_an_pending) {
|
||||||
bp->serdes_an_pending--;
|
bp->serdes_an_pending--;
|
||||||
check_link = 0;
|
check_link = 0;
|
||||||
@ -5420,7 +5419,6 @@ bnx2_5706_serdes_timer(struct bnx2 *bp)
|
|||||||
(bp->phy_flags & BNX2_PHY_FLAG_PARALLEL_DETECT)) {
|
(bp->phy_flags & BNX2_PHY_FLAG_PARALLEL_DETECT)) {
|
||||||
u32 phy2;
|
u32 phy2;
|
||||||
|
|
||||||
check_link = 0;
|
|
||||||
bnx2_write_phy(bp, 0x17, 0x0f01);
|
bnx2_write_phy(bp, 0x17, 0x0f01);
|
||||||
bnx2_read_phy(bp, 0x15, &phy2);
|
bnx2_read_phy(bp, 0x15, &phy2);
|
||||||
if (phy2 & 0x20) {
|
if (phy2 & 0x20) {
|
||||||
@ -5435,17 +5433,21 @@ bnx2_5706_serdes_timer(struct bnx2 *bp)
|
|||||||
} else
|
} else
|
||||||
bp->current_interval = bp->timer_interval;
|
bp->current_interval = bp->timer_interval;
|
||||||
|
|
||||||
if (bp->link_up && (bp->autoneg & AUTONEG_SPEED) && check_link) {
|
if (check_link) {
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
bnx2_write_phy(bp, MII_BNX2_MISC_SHADOW, MISC_SHDW_AN_DBG);
|
bnx2_write_phy(bp, MII_BNX2_MISC_SHADOW, MISC_SHDW_AN_DBG);
|
||||||
bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &val);
|
bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &val);
|
||||||
bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &val);
|
bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &val);
|
||||||
|
|
||||||
if (val & MISC_SHDW_AN_DBG_NOSYNC) {
|
if (bp->link_up && (val & MISC_SHDW_AN_DBG_NOSYNC)) {
|
||||||
bnx2_5706s_force_link_dn(bp, 1);
|
if (!(bp->phy_flags & BNX2_PHY_FLAG_FORCED_DOWN)) {
|
||||||
bp->phy_flags |= BNX2_PHY_FLAG_FORCED_DOWN;
|
bnx2_5706s_force_link_dn(bp, 1);
|
||||||
}
|
bp->phy_flags |= BNX2_PHY_FLAG_FORCED_DOWN;
|
||||||
|
} else
|
||||||
|
bnx2_set_link(bp);
|
||||||
|
} else if (!bp->link_up && !(val & MISC_SHDW_AN_DBG_NOSYNC))
|
||||||
|
bnx2_set_link(bp);
|
||||||
}
|
}
|
||||||
spin_unlock(&bp->phy_lock);
|
spin_unlock(&bp->phy_lock);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user