diff options
-rw-r--r-- | drivers/net/e1000e/82571.c | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index 280d41fc2a2d..e57e4097ef1b 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c | |||
@@ -52,6 +52,7 @@ | |||
52 | (ID_LED_DEF1_DEF2)) | 52 | (ID_LED_DEF1_DEF2)) |
53 | 53 | ||
54 | #define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000 | 54 | #define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000 |
55 | #define AN_RETRY_COUNT 5 /* Autoneg Retry Count value */ | ||
55 | #define E1000_BASE1000T_STATUS 10 | 56 | #define E1000_BASE1000T_STATUS 10 |
56 | #define E1000_IDLE_ERROR_COUNT_MASK 0xFF | 57 | #define E1000_IDLE_ERROR_COUNT_MASK 0xFF |
57 | #define E1000_RECEIVE_ERROR_COUNTER 21 | 58 | #define E1000_RECEIVE_ERROR_COUNTER 21 |
@@ -1503,6 +1504,8 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) | |||
1503 | u32 rxcw; | 1504 | u32 rxcw; |
1504 | u32 ctrl; | 1505 | u32 ctrl; |
1505 | u32 status; | 1506 | u32 status; |
1507 | u32 txcw; | ||
1508 | u32 i; | ||
1506 | s32 ret_val = 0; | 1509 | s32 ret_val = 0; |
1507 | 1510 | ||
1508 | ctrl = er32(CTRL); | 1511 | ctrl = er32(CTRL); |
@@ -1613,16 +1616,32 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) | |||
1613 | e_dbg("ANYSTATE -> DOWN\n"); | 1616 | e_dbg("ANYSTATE -> DOWN\n"); |
1614 | } else { | 1617 | } else { |
1615 | /* | 1618 | /* |
1616 | * We have sync, and can tolerate one invalid (IV) | 1619 | * Check several times, if Sync and Config |
1617 | * codeword before declaring link down, so reread | 1620 | * both are consistently 1 then simply ignore |
1618 | * to look again. | 1621 | * the Invalid bit and restart Autoneg |
1619 | */ | 1622 | */ |
1620 | udelay(10); | 1623 | for (i = 0; i < AN_RETRY_COUNT; i++) { |
1621 | rxcw = er32(RXCW); | 1624 | udelay(10); |
1622 | if (rxcw & E1000_RXCW_IV) { | 1625 | rxcw = er32(RXCW); |
1623 | mac->serdes_link_state = e1000_serdes_link_down; | 1626 | if ((rxcw & E1000_RXCW_IV) && |
1627 | !((rxcw & E1000_RXCW_SYNCH) && | ||
1628 | (rxcw & E1000_RXCW_C))) { | ||
1629 | mac->serdes_has_link = false; | ||
1630 | mac->serdes_link_state = | ||
1631 | e1000_serdes_link_down; | ||
1632 | e_dbg("ANYSTATE -> DOWN\n"); | ||
1633 | break; | ||
1634 | } | ||
1635 | } | ||
1636 | |||
1637 | if (i == AN_RETRY_COUNT) { | ||
1638 | txcw = er32(TXCW); | ||
1639 | txcw |= E1000_TXCW_ANE; | ||
1640 | ew32(TXCW, txcw); | ||
1641 | mac->serdes_link_state = | ||
1642 | e1000_serdes_link_autoneg_progress; | ||
1624 | mac->serdes_has_link = false; | 1643 | mac->serdes_has_link = false; |
1625 | e_dbg("ANYSTATE -> DOWN\n"); | 1644 | e_dbg("ANYSTATE -> AN_PROG\n"); |
1626 | } | 1645 | } |
1627 | } | 1646 | } |
1628 | } | 1647 | } |