aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>2009-06-04 07:10:53 -0400
committerDavid S. Miller <davem@davemloft.net>2009-06-07 08:20:18 -0400
commit50ac58ba1d707df33f0c398ae700214e49bf918f (patch)
tree2d9a80861ab57e4c3e24b17e5d828223658cb334
parentda4dd0f7ca3fa667b7bba5fd34adceaf3fb84a9b (diff)
ixgbe: Harden the 82599 multispeed fiber autotry mechanism
82599 supports multispeed fiber optical modules (10Gbps/1Gbps). Some scenarios can cause the autotry mechanism to not negotiate link properly. What needs to happen is the driver must flap the Tx laser to induce an Rx Loss of Signal on the link partner. This will restart the autotry mechanism to get link into a known state. The software definable pin (SDP) 3 on the 0x10fb NIC is wired to cause a Tx LOS event, which triggers the Rx LOS we require. Signed-off-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com> Acked-by: Mallikarjuna R Chilakala <mallikarjuna.chilakala@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ixgbe/ixgbe_82599.c120
-rw-r--r--drivers/net/ixgbe/ixgbe_common.c1
-rw-r--r--drivers/net/ixgbe/ixgbe_phy.c1
-rw-r--r--drivers/net/ixgbe/ixgbe_type.h7
4 files changed, 106 insertions, 23 deletions
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c
index a7611bbf3873..84b83f7b473f 100644
--- a/drivers/net/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ixgbe/ixgbe_82599.c
@@ -461,12 +461,23 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw,
461 u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP); 461 u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
462 bool link_up = false; 462 bool link_up = false;
463 bool negotiation; 463 bool negotiation;
464 int i;
464 465
465 /* Mask off requested but non-supported speeds */ 466 /* Mask off requested but non-supported speeds */
466 hw->mac.ops.get_link_capabilities(hw, &phy_link_speed, &negotiation); 467 hw->mac.ops.get_link_capabilities(hw, &phy_link_speed, &negotiation);
467 speed &= phy_link_speed; 468 speed &= phy_link_speed;
468 469
469 /* 470 /*
471 * When the driver changes the link speeds that it can support,
472 * it sets autotry_restart to true to indicate that we need to
473 * initiate a new autotry session with the link partner. To do
474 * so, we set the speed then disable and re-enable the tx laser, to
475 * alert the link partner that it also needs to restart autotry on its
476 * end. This is consistent with true clause 37 autoneg, which also
477 * involves a loss of signal.
478 */
479
480 /*
470 * Try each speed one by one, highest priority first. We do this in 481 * Try each speed one by one, highest priority first. We do this in
471 * software because 10gb fiber doesn't support speed autonegotiation. 482 * software because 10gb fiber doesn't support speed autonegotiation.
472 */ 483 */
@@ -474,21 +485,52 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw,
474 speedcnt++; 485 speedcnt++;
475 highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL; 486 highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL;
476 487
477 /* Set hardware SDP's */ 488 /* If we already have link at this speed, just jump out */
489 hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false);
490
491 if ((phy_link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up)
492 goto out;
493
494 /* Set the module link speed */
478 esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5); 495 esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
479 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); 496 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
480 497
481 ixgbe_setup_mac_link_speed_82599(hw, 498 /* Allow module to change analog characteristics (1G->10G) */
482 IXGBE_LINK_SPEED_10GB_FULL, 499 msleep(40);
483 autoneg,
484 autoneg_wait_to_complete);
485
486 msleep(50);
487 500
488 /* If we have link, just jump out */ 501 status = ixgbe_setup_mac_link_speed_82599(hw,
489 hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false); 502 IXGBE_LINK_SPEED_10GB_FULL,
490 if (link_up) 503 autoneg,
504 autoneg_wait_to_complete);
505 if (status != 0)
491 goto out; 506 goto out;
507
508 /* Flap the tx laser if it has not already been done */
509 if (hw->mac.autotry_restart) {
510 /* Disable tx laser; allow 100us to go dark per spec */
511 esdp_reg |= IXGBE_ESDP_SDP3;
512 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
513 udelay(100);
514
515 /* Enable tx laser; allow 2ms to light up per spec */
516 esdp_reg &= ~IXGBE_ESDP_SDP3;
517 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
518 msleep(2);
519
520 hw->mac.autotry_restart = false;
521 }
522
523 /* The controller may take up to 500ms at 10g to acquire link */
524 for (i = 0; i < 5; i++) {
525 /* Wait for the link partner to also set speed */
526 msleep(100);
527
528 /* If we have link, just jump out */
529 hw->mac.ops.check_link(hw, &phy_link_speed,
530 &link_up, false);
531 if (link_up)
532 goto out;
533 }
492 } 534 }
493 535
494 if (speed & IXGBE_LINK_SPEED_1GB_FULL) { 536 if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
@@ -496,16 +538,44 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw,
496 if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN) 538 if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN)
497 highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL; 539 highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL;
498 540
499 /* Set hardware SDP's */ 541 /* If we already have link at this speed, just jump out */
542 hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false);
543
544 if ((phy_link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up)
545 goto out;
546
547 /* Set the module link speed */
500 esdp_reg &= ~IXGBE_ESDP_SDP5; 548 esdp_reg &= ~IXGBE_ESDP_SDP5;
501 esdp_reg |= IXGBE_ESDP_SDP5_DIR; 549 esdp_reg |= IXGBE_ESDP_SDP5_DIR;
502 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); 550 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
503 551
504 ixgbe_setup_mac_link_speed_82599( 552 /* Allow module to change analog characteristics (10G->1G) */
505 hw, IXGBE_LINK_SPEED_1GB_FULL, autoneg, 553 msleep(40);
506 autoneg_wait_to_complete);
507 554
508 msleep(50); 555 status = ixgbe_setup_mac_link_speed_82599(hw,
556 IXGBE_LINK_SPEED_1GB_FULL,
557 autoneg,
558 autoneg_wait_to_complete);
559 if (status != 0)
560 goto out;
561
562 /* Flap the tx laser if it has not already been done */
563 if (hw->mac.autotry_restart) {
564 /* Disable tx laser; allow 100us to go dark per spec */
565 esdp_reg |= IXGBE_ESDP_SDP3;
566 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
567 udelay(100);
568
569 /* Enable tx laser; allow 2ms to light up per spec */
570 esdp_reg &= ~IXGBE_ESDP_SDP3;
571 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
572 msleep(2);
573
574 hw->mac.autotry_restart = false;
575 }
576
577 /* Wait for the link partner to also set speed */
578 msleep(100);
509 579
510 /* If we have link, just jump out */ 580 /* If we have link, just jump out */
511 hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false); 581 hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false);
@@ -591,6 +661,7 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
591 s32 status = 0; 661 s32 status = 0;
592 u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); 662 u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
593 u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2); 663 u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
664 u32 start_autoc = autoc;
594 u32 orig_autoc = 0; 665 u32 orig_autoc = 0;
595 u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK; 666 u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
596 u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK; 667 u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
@@ -603,6 +674,11 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
603 hw->mac.ops.get_link_capabilities(hw, &link_capabilities, &autoneg); 674 hw->mac.ops.get_link_capabilities(hw, &link_capabilities, &autoneg);
604 speed &= link_capabilities; 675 speed &= link_capabilities;
605 676
677 if (speed == IXGBE_LINK_SPEED_UNKNOWN) {
678 status = IXGBE_ERR_LINK_SETUP;
679 goto out;
680 }
681
606 /* Use stored value (EEPROM defaults) of AUTOC to find KR/KX4 support*/ 682 /* Use stored value (EEPROM defaults) of AUTOC to find KR/KX4 support*/
607 if (hw->mac.orig_link_settings_stored) 683 if (hw->mac.orig_link_settings_stored)
608 orig_autoc = hw->mac.orig_autoc; 684 orig_autoc = hw->mac.orig_autoc;
@@ -610,11 +686,9 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
610 orig_autoc = autoc; 686 orig_autoc = autoc;
611 687
612 688
613 if (speed == IXGBE_LINK_SPEED_UNKNOWN) { 689 if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR ||
614 status = IXGBE_ERR_LINK_SETUP; 690 link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
615 } else if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR || 691 link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
616 link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
617 link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
618 /* Set KX4/KX/KR support according to speed requested */ 692 /* Set KX4/KX/KR support according to speed requested */
619 autoc &= ~(IXGBE_AUTOC_KX4_KX_SUPP_MASK | IXGBE_AUTOC_KR_SUPP); 693 autoc &= ~(IXGBE_AUTOC_KX4_KX_SUPP_MASK | IXGBE_AUTOC_KR_SUPP);
620 if (speed & IXGBE_LINK_SPEED_10GB_FULL) 694 if (speed & IXGBE_LINK_SPEED_10GB_FULL)
@@ -646,7 +720,7 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
646 } 720 }
647 } 721 }
648 722
649 if (status == 0) { 723 if (autoc != start_autoc) {
650 /* Restart link */ 724 /* Restart link */
651 autoc |= IXGBE_AUTOC_AN_RESTART; 725 autoc |= IXGBE_AUTOC_AN_RESTART;
652 IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc); 726 IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
@@ -680,6 +754,7 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
680 msleep(50); 754 msleep(50);
681 } 755 }
682 756
757out:
683 return status; 758 return status;
684} 759}
685 760
@@ -1144,6 +1219,9 @@ s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw)
1144 } 1219 }
1145 IXGBE_WRITE_FLUSH(hw); 1220 IXGBE_WRITE_FLUSH(hw);
1146 1221
1222 /* We need to run link autotry after the driver loads */
1223 hw->mac.autotry_restart = true;
1224
1147 return 0; 1225 return 0;
1148} 1226}
1149 1227
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c
index 6f79409270a7..4d36cd32cd30 100644
--- a/drivers/net/ixgbe/ixgbe_common.c
+++ b/drivers/net/ixgbe/ixgbe_common.c
@@ -2068,6 +2068,7 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
2068 hw->mac.ops.check_link(hw, &speed, &link_up, false); 2068 hw->mac.ops.check_link(hw, &speed, &link_up, false);
2069 2069
2070 if (!link_up) { 2070 if (!link_up) {
2071 autoc_reg |= IXGBE_AUTOC_AN_RESTART;
2071 autoc_reg |= IXGBE_AUTOC_FLU; 2072 autoc_reg |= IXGBE_AUTOC_FLU;
2072 IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); 2073 IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
2073 msleep(10); 2074 msleep(10);
diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c
index e43d6248d7d4..453e966762f0 100644
--- a/drivers/net/ixgbe/ixgbe_phy.c
+++ b/drivers/net/ixgbe/ixgbe_phy.c
@@ -606,6 +606,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
606 hw->phy.sfp_setup_needed = true; 606 hw->phy.sfp_setup_needed = true;
607 607
608 /* Determine if the SFP+ PHY is dual speed or not. */ 608 /* Determine if the SFP+ PHY is dual speed or not. */
609 hw->phy.multispeed_fiber = false;
609 if (((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) && 610 if (((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) &&
610 (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)) || 611 (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)) ||
611 ((comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) && 612 ((comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) &&
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index a8a8243d8fdb..199b288c3459 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -1265,8 +1265,10 @@
1265#define IXGBE_STATUS_LAN_ID_1 0x00000004 /* LAN ID 1 */ 1265#define IXGBE_STATUS_LAN_ID_1 0x00000004 /* LAN ID 1 */
1266 1266
1267/* ESDP Bit Masks */ 1267/* ESDP Bit Masks */
1268#define IXGBE_ESDP_SDP0 0x00000001 1268#define IXGBE_ESDP_SDP0 0x00000001 /* SDP0 Data Value */
1269#define IXGBE_ESDP_SDP1 0x00000002 1269#define IXGBE_ESDP_SDP1 0x00000002 /* SDP1 Data Value */
1270#define IXGBE_ESDP_SDP2 0x00000004 /* SDP2 Data Value */
1271#define IXGBE_ESDP_SDP3 0x00000008 /* SDP3 Data Value */
1270#define IXGBE_ESDP_SDP4 0x00000010 /* SDP4 Data Value */ 1272#define IXGBE_ESDP_SDP4 0x00000010 /* SDP4 Data Value */
1271#define IXGBE_ESDP_SDP5 0x00000020 /* SDP5 Data Value */ 1273#define IXGBE_ESDP_SDP5 0x00000020 /* SDP5 Data Value */
1272#define IXGBE_ESDP_SDP6 0x00000040 /* SDP6 Data Value */ 1274#define IXGBE_ESDP_SDP6 0x00000040 /* SDP6 Data Value */
@@ -2281,6 +2283,7 @@ struct ixgbe_mac_info {
2281 bool orig_link_settings_stored; 2283 bool orig_link_settings_stored;
2282 bool autoneg; 2284 bool autoneg;
2283 bool autoneg_succeeded; 2285 bool autoneg_succeeded;
2286 bool autotry_restart;
2284}; 2287};
2285 2288
2286struct ixgbe_phy_info { 2289struct ixgbe_phy_info {