aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000e
diff options
context:
space:
mode:
authorBruce Allan <bruce.w.allan@intel.com>2009-12-01 10:49:51 -0500
committerDavid S. Miller <davem@davemloft.net>2009-12-02 03:35:53 -0500
commit1a40d5c170f472d541844cb5b4292efbe02ef89c (patch)
tree33a85e29de0f6563f66387ac32bfeb1e8f4dcdd8 /drivers/net/e1000e
parent17f208deb9bf88315aa72c08c866a235c399fb9a (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.c76
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 **/
1362static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) 1374static 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);