aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/e1000e/82571.c35
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 }