diff options
author | Bruce Allan <bruce.w.allan@intel.com> | 2009-12-01 10:49:51 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-12-02 03:35:53 -0500 |
commit | 1a40d5c170f472d541844cb5b4292efbe02ef89c (patch) | |
tree | 33a85e29de0f6563f66387ac32bfeb1e8f4dcdd8 /drivers/net/e1000e | |
parent | 17f208deb9bf88315aa72c08c866a235c399fb9a (diff) |
e1000e: ensure the link state is correct for serdes links
This patch ensures that the link state (as reported in
mac->serdes_has_link) will transition to false when autoneg fails to
complete but valid codewords were detected.
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/e1000e')
-rw-r--r-- | drivers/net/e1000e/82571.c | 76 |
1 files changed, 48 insertions, 28 deletions
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index 26ea5d57a354..227f3d03ba2a 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c | |||
@@ -1356,8 +1356,20 @@ static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw) | |||
1356 | * e1000_check_for_serdes_link_82571 - Check for link (Serdes) | 1356 | * e1000_check_for_serdes_link_82571 - Check for link (Serdes) |
1357 | * @hw: pointer to the HW structure | 1357 | * @hw: pointer to the HW structure |
1358 | * | 1358 | * |
1359 | * Checks for link up on the hardware. If link is not up and we have | 1359 | * Reports the link state as up or down. |
1360 | * a signal, then we need to force link up. | 1360 | * |
1361 | * If autonegotiation is supported by the link partner, the link state is | ||
1362 | * determined by the result of autonegotiation. This is the most likely case. | ||
1363 | * If autonegotiation is not supported by the link partner, and the link | ||
1364 | * has a valid signal, force the link up. | ||
1365 | * | ||
1366 | * The link state is represented internally here by 4 states: | ||
1367 | * | ||
1368 | * 1) down | ||
1369 | * 2) autoneg_progress | ||
1370 | * 3) autoneg_complete (the link sucessfully autonegotiated) | ||
1371 | * 4) forced_up (the link has been forced up, it did not autonegotiate) | ||
1372 | * | ||
1361 | **/ | 1373 | **/ |
1362 | static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) | 1374 | static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) |
1363 | { | 1375 | { |
@@ -1383,6 +1395,7 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) | |||
1383 | */ | 1395 | */ |
1384 | mac->serdes_link_state = | 1396 | mac->serdes_link_state = |
1385 | e1000_serdes_link_autoneg_progress; | 1397 | e1000_serdes_link_autoneg_progress; |
1398 | mac->serdes_has_link = false; | ||
1386 | e_dbg("AN_UP -> AN_PROG\n"); | 1399 | e_dbg("AN_UP -> AN_PROG\n"); |
1387 | } | 1400 | } |
1388 | break; | 1401 | break; |
@@ -1397,57 +1410,64 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) | |||
1397 | if (rxcw & E1000_RXCW_C) { | 1410 | if (rxcw & E1000_RXCW_C) { |
1398 | /* Enable autoneg, and unforce link up */ | 1411 | /* Enable autoneg, and unforce link up */ |
1399 | ew32(TXCW, mac->txcw); | 1412 | ew32(TXCW, mac->txcw); |
1400 | ew32(CTRL, | 1413 | ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); |
1401 | (ctrl & ~E1000_CTRL_SLU)); | ||
1402 | mac->serdes_link_state = | 1414 | mac->serdes_link_state = |
1403 | e1000_serdes_link_autoneg_progress; | 1415 | e1000_serdes_link_autoneg_progress; |
1416 | mac->serdes_has_link = false; | ||
1404 | e_dbg("FORCED_UP -> AN_PROG\n"); | 1417 | e_dbg("FORCED_UP -> AN_PROG\n"); |
1405 | } | 1418 | } |
1406 | break; | 1419 | break; |
1407 | 1420 | ||
1408 | case e1000_serdes_link_autoneg_progress: | 1421 | case e1000_serdes_link_autoneg_progress: |
1409 | /* | 1422 | if (rxcw & E1000_RXCW_C) { |
1410 | * If the LU bit is set in the STATUS register, | 1423 | /* |
1411 | * autoneg has completed sucessfully. If not, | 1424 | * We received /C/ ordered sets, meaning the |
1412 | * try foring the link because the far end may be | 1425 | * link partner has autonegotiated, and we can |
1413 | * available but not capable of autonegotiation. | 1426 | * trust the Link Up (LU) status bit. |
1414 | */ | 1427 | */ |
1415 | if (status & E1000_STATUS_LU) { | 1428 | if (status & E1000_STATUS_LU) { |
1416 | mac->serdes_link_state = | 1429 | mac->serdes_link_state = |
1417 | e1000_serdes_link_autoneg_complete; | 1430 | e1000_serdes_link_autoneg_complete; |
1418 | e_dbg("AN_PROG -> AN_UP\n"); | 1431 | e_dbg("AN_PROG -> AN_UP\n"); |
1432 | mac->serdes_has_link = true; | ||
1433 | } else { | ||
1434 | /* Autoneg completed, but failed. */ | ||
1435 | mac->serdes_link_state = | ||
1436 | e1000_serdes_link_down; | ||
1437 | e_dbg("AN_PROG -> DOWN\n"); | ||
1438 | } | ||
1419 | } else { | 1439 | } else { |
1420 | /* | 1440 | /* |
1421 | * Disable autoneg, force link up and | 1441 | * The link partner did not autoneg. |
1422 | * full duplex, and change state to forced | 1442 | * Force link up and full duplex, and change |
1443 | * state to forced. | ||
1423 | */ | 1444 | */ |
1424 | ew32(TXCW, | 1445 | ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE)); |
1425 | (mac->txcw & ~E1000_TXCW_ANE)); | ||
1426 | ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD); | 1446 | ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD); |
1427 | ew32(CTRL, ctrl); | 1447 | ew32(CTRL, ctrl); |
1428 | 1448 | ||
1429 | /* Configure Flow Control after link up. */ | 1449 | /* Configure Flow Control after link up. */ |
1430 | ret_val = | 1450 | ret_val = e1000e_config_fc_after_link_up(hw); |
1431 | e1000e_config_fc_after_link_up(hw); | ||
1432 | if (ret_val) { | 1451 | if (ret_val) { |
1433 | e_dbg("Error config flow control\n"); | 1452 | e_dbg("Error config flow control\n"); |
1434 | break; | 1453 | break; |
1435 | } | 1454 | } |
1436 | mac->serdes_link_state = | 1455 | mac->serdes_link_state = |
1437 | e1000_serdes_link_forced_up; | 1456 | e1000_serdes_link_forced_up; |
1457 | mac->serdes_has_link = true; | ||
1438 | e_dbg("AN_PROG -> FORCED_UP\n"); | 1458 | e_dbg("AN_PROG -> FORCED_UP\n"); |
1439 | } | 1459 | } |
1440 | mac->serdes_has_link = true; | ||
1441 | break; | 1460 | break; |
1442 | 1461 | ||
1443 | case e1000_serdes_link_down: | 1462 | case e1000_serdes_link_down: |
1444 | default: | 1463 | default: |
1445 | /* The link was down but the receiver has now gained | 1464 | /* |
1465 | * The link was down but the receiver has now gained | ||
1446 | * valid sync, so lets see if we can bring the link | 1466 | * valid sync, so lets see if we can bring the link |
1447 | * up. */ | 1467 | * up. |
1468 | */ | ||
1448 | ew32(TXCW, mac->txcw); | 1469 | ew32(TXCW, mac->txcw); |
1449 | ew32(CTRL, | 1470 | ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); |
1450 | (ctrl & ~E1000_CTRL_SLU)); | ||
1451 | mac->serdes_link_state = | 1471 | mac->serdes_link_state = |
1452 | e1000_serdes_link_autoneg_progress; | 1472 | e1000_serdes_link_autoneg_progress; |
1453 | e_dbg("DOWN -> AN_PROG\n"); | 1473 | e_dbg("DOWN -> AN_PROG\n"); |
@@ -1460,9 +1480,9 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) | |||
1460 | e_dbg("ANYSTATE -> DOWN\n"); | 1480 | e_dbg("ANYSTATE -> DOWN\n"); |
1461 | } else { | 1481 | } else { |
1462 | /* | 1482 | /* |
1463 | * We have sync, and can tolerate one | 1483 | * We have sync, and can tolerate one invalid (IV) |
1464 | * invalid (IV) codeword before declaring | 1484 | * codeword before declaring link down, so reread |
1465 | * link down, so reread to look again | 1485 | * to look again. |
1466 | */ | 1486 | */ |
1467 | udelay(10); | 1487 | udelay(10); |
1468 | rxcw = er32(RXCW); | 1488 | rxcw = er32(RXCW); |