diff options
author | Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com> | 2009-02-06 02:54:21 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-02-06 02:54:21 -0500 |
commit | 3201d3130ee3eb49ed0e905654568f02736afdcb (patch) | |
tree | f07287c17728f225881dfc0b111b219a0d3197aa /drivers/net | |
parent | bc97114d3f998a040876695a9b2b5be0b1a5320b (diff) |
ixgbe: Update link setup code to better support autonegotiation of speed
The current code has some flaws in it when performing autonegotiation,
especially on KX/KX4 links. This patch updates the code to better handle
the autonegotiation states on link setup. The patch also removes a redundant
link configuration call on driver load, and moves link configuration to
the ->open() path.
Signed-off-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@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')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_82598.c | 114 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_common.c | 3 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 3 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_type.h | 9 |
4 files changed, 49 insertions, 80 deletions
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index 8e7315e0a7fa..f726a14d1a73 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c | |||
@@ -146,18 +146,12 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw, | |||
146 | bool *autoneg) | 146 | bool *autoneg) |
147 | { | 147 | { |
148 | s32 status = 0; | 148 | s32 status = 0; |
149 | s32 autoc_reg; | ||
150 | 149 | ||
151 | autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); | 150 | /* |
152 | 151 | * Determine link capabilities based on the stored value of AUTOC, | |
153 | if (hw->mac.link_settings_loaded) { | 152 | * which represents EEPROM defaults. |
154 | autoc_reg &= ~IXGBE_AUTOC_LMS_ATTACH_TYPE; | 153 | */ |
155 | autoc_reg &= ~IXGBE_AUTOC_LMS_MASK; | 154 | switch (hw->mac.orig_autoc & IXGBE_AUTOC_LMS_MASK) { |
156 | autoc_reg |= hw->mac.link_attach_type; | ||
157 | autoc_reg |= hw->mac.link_mode_select; | ||
158 | } | ||
159 | |||
160 | switch (autoc_reg & IXGBE_AUTOC_LMS_MASK) { | ||
161 | case IXGBE_AUTOC_LMS_1G_LINK_NO_AN: | 155 | case IXGBE_AUTOC_LMS_1G_LINK_NO_AN: |
162 | *speed = IXGBE_LINK_SPEED_1GB_FULL; | 156 | *speed = IXGBE_LINK_SPEED_1GB_FULL; |
163 | *autoneg = false; | 157 | *autoneg = false; |
@@ -176,9 +170,9 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw, | |||
176 | case IXGBE_AUTOC_LMS_KX4_AN: | 170 | case IXGBE_AUTOC_LMS_KX4_AN: |
177 | case IXGBE_AUTOC_LMS_KX4_AN_1G_AN: | 171 | case IXGBE_AUTOC_LMS_KX4_AN_1G_AN: |
178 | *speed = IXGBE_LINK_SPEED_UNKNOWN; | 172 | *speed = IXGBE_LINK_SPEED_UNKNOWN; |
179 | if (autoc_reg & IXGBE_AUTOC_KX4_SUPP) | 173 | if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP) |
180 | *speed |= IXGBE_LINK_SPEED_10GB_FULL; | 174 | *speed |= IXGBE_LINK_SPEED_10GB_FULL; |
181 | if (autoc_reg & IXGBE_AUTOC_KX_SUPP) | 175 | if (hw->mac.orig_autoc & IXGBE_AUTOC_KX_SUPP) |
182 | *speed |= IXGBE_LINK_SPEED_1GB_FULL; | 176 | *speed |= IXGBE_LINK_SPEED_1GB_FULL; |
183 | *autoneg = true; | 177 | *autoneg = true; |
184 | break; | 178 | break; |
@@ -390,27 +384,17 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw) | |||
390 | u32 i; | 384 | u32 i; |
391 | s32 status = 0; | 385 | s32 status = 0; |
392 | 386 | ||
393 | autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); | ||
394 | |||
395 | if (hw->mac.link_settings_loaded) { | ||
396 | autoc_reg &= ~IXGBE_AUTOC_LMS_ATTACH_TYPE; | ||
397 | autoc_reg &= ~IXGBE_AUTOC_LMS_MASK; | ||
398 | autoc_reg |= hw->mac.link_attach_type; | ||
399 | autoc_reg |= hw->mac.link_mode_select; | ||
400 | |||
401 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); | ||
402 | IXGBE_WRITE_FLUSH(hw); | ||
403 | msleep(50); | ||
404 | } | ||
405 | |||
406 | /* Restart link */ | 387 | /* Restart link */ |
388 | autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); | ||
407 | autoc_reg |= IXGBE_AUTOC_AN_RESTART; | 389 | autoc_reg |= IXGBE_AUTOC_AN_RESTART; |
408 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); | 390 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); |
409 | 391 | ||
410 | /* Only poll for autoneg to complete if specified to do so */ | 392 | /* Only poll for autoneg to complete if specified to do so */ |
411 | if (hw->phy.autoneg_wait_to_complete) { | 393 | if (hw->phy.autoneg_wait_to_complete) { |
412 | if (hw->mac.link_mode_select == IXGBE_AUTOC_LMS_KX4_AN || | 394 | if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) == |
413 | hw->mac.link_mode_select == IXGBE_AUTOC_LMS_KX4_AN_1G_AN) { | 395 | IXGBE_AUTOC_LMS_KX4_AN || |
396 | (autoc_reg & IXGBE_AUTOC_LMS_MASK) == | ||
397 | IXGBE_AUTOC_LMS_KX4_AN_1G_AN) { | ||
414 | links_reg = 0; /* Just in case Autoneg time = 0 */ | 398 | links_reg = 0; /* Just in case Autoneg time = 0 */ |
415 | for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) { | 399 | for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) { |
416 | links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); | 400 | links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); |
@@ -534,37 +518,43 @@ out: | |||
534 | * Set the link speed in the AUTOC register and restarts link. | 518 | * Set the link speed in the AUTOC register and restarts link. |
535 | **/ | 519 | **/ |
536 | static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw, | 520 | static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw, |
537 | ixgbe_link_speed speed, bool autoneg, | 521 | ixgbe_link_speed speed, bool autoneg, |
538 | bool autoneg_wait_to_complete) | 522 | bool autoneg_wait_to_complete) |
539 | { | 523 | { |
540 | s32 status = 0; | 524 | s32 status = 0; |
525 | ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN; | ||
526 | u32 curr_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); | ||
527 | u32 autoc = curr_autoc; | ||
528 | u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK; | ||
541 | 529 | ||
542 | /* If speed is 10G, then check for CX4 or XAUI. */ | 530 | /* Check to see if speed passed in is supported. */ |
543 | if ((speed == IXGBE_LINK_SPEED_10GB_FULL) && | 531 | ixgbe_get_link_capabilities_82598(hw, &link_capabilities, &autoneg); |
544 | (!(hw->mac.link_attach_type & IXGBE_AUTOC_10G_KX4))) { | 532 | speed &= link_capabilities; |
545 | hw->mac.link_mode_select = IXGBE_AUTOC_LMS_10G_LINK_NO_AN; | 533 | |
546 | } else if ((speed == IXGBE_LINK_SPEED_1GB_FULL) && (!autoneg)) { | 534 | if (speed == IXGBE_LINK_SPEED_UNKNOWN) |
547 | hw->mac.link_mode_select = IXGBE_AUTOC_LMS_1G_LINK_NO_AN; | ||
548 | } else if (autoneg) { | ||
549 | /* BX mode - Autonegotiate 1G */ | ||
550 | if (!(hw->mac.link_attach_type & IXGBE_AUTOC_1G_PMA_PMD)) | ||
551 | hw->mac.link_mode_select = IXGBE_AUTOC_LMS_1G_AN; | ||
552 | else /* KX/KX4 mode */ | ||
553 | hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN_1G_AN; | ||
554 | } else { | ||
555 | status = IXGBE_ERR_LINK_SETUP; | 535 | status = IXGBE_ERR_LINK_SETUP; |
536 | |||
537 | /* Set KX4/KX support according to speed requested */ | ||
538 | else if (link_mode == IXGBE_AUTOC_LMS_KX4_AN || | ||
539 | link_mode == IXGBE_AUTOC_LMS_KX4_AN_1G_AN) { | ||
540 | autoc &= ~IXGBE_AUTOC_KX4_KX_SUPP_MASK; | ||
541 | if (speed & IXGBE_LINK_SPEED_10GB_FULL) | ||
542 | autoc |= IXGBE_AUTOC_KX4_SUPP; | ||
543 | if (speed & IXGBE_LINK_SPEED_1GB_FULL) | ||
544 | autoc |= IXGBE_AUTOC_KX_SUPP; | ||
545 | if (autoc != curr_autoc) | ||
546 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc); | ||
556 | } | 547 | } |
557 | 548 | ||
558 | if (status == 0) { | 549 | if (status == 0) { |
559 | hw->phy.autoneg_wait_to_complete = autoneg_wait_to_complete; | 550 | hw->phy.autoneg_wait_to_complete = autoneg_wait_to_complete; |
560 | 551 | ||
561 | hw->mac.link_settings_loaded = true; | ||
562 | /* | 552 | /* |
563 | * Setup and restart the link based on the new values in | 553 | * Setup and restart the link based on the new values in |
564 | * ixgbe_hw This will write the AUTOC register based on the new | 554 | * ixgbe_hw This will write the AUTOC register based on the new |
565 | * stored values | 555 | * stored values |
566 | */ | 556 | */ |
567 | ixgbe_setup_mac_link_82598(hw); | 557 | status = ixgbe_setup_mac_link_82598(hw); |
568 | } | 558 | } |
569 | 559 | ||
570 | return status; | 560 | return status; |
@@ -587,10 +577,6 @@ static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw) | |||
587 | /* Restart autonegotiation on PHY */ | 577 | /* Restart autonegotiation on PHY */ |
588 | status = hw->phy.ops.setup_link(hw); | 578 | status = hw->phy.ops.setup_link(hw); |
589 | 579 | ||
590 | /* Set MAC to KX/KX4 autoneg, which defaults to Parallel detection */ | ||
591 | hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX); | ||
592 | hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN; | ||
593 | |||
594 | /* Set up MAC */ | 580 | /* Set up MAC */ |
595 | ixgbe_setup_mac_link_82598(hw); | 581 | ixgbe_setup_mac_link_82598(hw); |
596 | 582 | ||
@@ -617,10 +603,6 @@ static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, | |||
617 | status = hw->phy.ops.setup_link_speed(hw, speed, autoneg, | 603 | status = hw->phy.ops.setup_link_speed(hw, speed, autoneg, |
618 | autoneg_wait_to_complete); | 604 | autoneg_wait_to_complete); |
619 | 605 | ||
620 | /* Set MAC to KX/KX4 autoneg, which defaults to Parallel detection */ | ||
621 | hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX); | ||
622 | hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN; | ||
623 | |||
624 | /* Set up MAC */ | 606 | /* Set up MAC */ |
625 | ixgbe_setup_mac_link_82598(hw); | 607 | ixgbe_setup_mac_link_82598(hw); |
626 | 608 | ||
@@ -720,24 +702,16 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw) | |||
720 | IXGBE_WRITE_REG(hw, IXGBE_GHECCR, gheccr); | 702 | IXGBE_WRITE_REG(hw, IXGBE_GHECCR, gheccr); |
721 | 703 | ||
722 | /* | 704 | /* |
723 | * AUTOC register which stores link settings gets cleared | 705 | * Store the original AUTOC value if it has not been |
724 | * and reloaded from EEPROM after reset. We need to restore | 706 | * stored off yet. Otherwise restore the stored original |
725 | * our stored value from init in case SW changed the attach | 707 | * AUTOC value since the reset operation sets back to deaults. |
726 | * type or speed. If this is the first time and link settings | ||
727 | * have not been stored, store default settings from AUTOC. | ||
728 | */ | 708 | */ |
729 | autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); | 709 | autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); |
730 | if (hw->mac.link_settings_loaded) { | 710 | if (hw->mac.orig_link_settings_stored == false) { |
731 | autoc &= ~(IXGBE_AUTOC_LMS_ATTACH_TYPE); | 711 | hw->mac.orig_autoc = autoc; |
732 | autoc &= ~(IXGBE_AUTOC_LMS_MASK); | 712 | hw->mac.orig_link_settings_stored = true; |
733 | autoc |= hw->mac.link_attach_type; | 713 | } else if (autoc != hw->mac.orig_autoc) { |
734 | autoc |= hw->mac.link_mode_select; | 714 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc); |
735 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc); | ||
736 | } else { | ||
737 | hw->mac.link_attach_type = | ||
738 | (autoc & IXGBE_AUTOC_LMS_ATTACH_TYPE); | ||
739 | hw->mac.link_mode_select = (autoc & IXGBE_AUTOC_LMS_MASK); | ||
740 | hw->mac.link_settings_loaded = true; | ||
741 | } | 715 | } |
742 | 716 | ||
743 | /* Store the permanent mac address */ | 717 | /* Store the permanent mac address */ |
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 05f0e872947f..13ad5ba66b63 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c | |||
@@ -80,9 +80,6 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) | |||
80 | /* Clear the VLAN filter table */ | 80 | /* Clear the VLAN filter table */ |
81 | hw->mac.ops.clear_vfta(hw); | 81 | hw->mac.ops.clear_vfta(hw); |
82 | 82 | ||
83 | /* Set up link */ | ||
84 | hw->mac.ops.setup_link(hw); | ||
85 | |||
86 | /* Clear statistics registers */ | 83 | /* Clear statistics registers */ |
87 | hw->mac.ops.clear_hw_cntrs(hw); | 84 | hw->mac.ops.clear_hw_cntrs(hw); |
88 | 85 | ||
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index d396c6e01fb5..5db82b5fa9b3 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -2799,9 +2799,6 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) | |||
2799 | hw->fc.pause_time = IXGBE_DEFAULT_FCPAUSE; | 2799 | hw->fc.pause_time = IXGBE_DEFAULT_FCPAUSE; |
2800 | hw->fc.send_xon = true; | 2800 | hw->fc.send_xon = true; |
2801 | 2801 | ||
2802 | /* select 10G link by default */ | ||
2803 | hw->mac.link_mode_select = IXGBE_AUTOC_LMS_10G_LINK_NO_AN; | ||
2804 | |||
2805 | /* enable itr by default in dynamic mode */ | 2802 | /* enable itr by default in dynamic mode */ |
2806 | adapter->itr_setting = 1; | 2803 | adapter->itr_setting = 1; |
2807 | adapter->eitr_param = 20000; | 2804 | adapter->eitr_param = 20000; |
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index c49ba8a17f1b..984b4ed372f1 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h | |||
@@ -721,6 +721,7 @@ | |||
721 | #define IXGBE_LED_OFF 0xF | 721 | #define IXGBE_LED_OFF 0xF |
722 | 722 | ||
723 | /* AUTOC Bit Masks */ | 723 | /* AUTOC Bit Masks */ |
724 | #define IXGBE_AUTOC_KX4_KX_SUPP_MASK 0xC0000000 | ||
724 | #define IXGBE_AUTOC_KX4_SUPP 0x80000000 | 725 | #define IXGBE_AUTOC_KX4_SUPP 0x80000000 |
725 | #define IXGBE_AUTOC_KX_SUPP 0x40000000 | 726 | #define IXGBE_AUTOC_KX_SUPP 0x40000000 |
726 | #define IXGBE_AUTOC_PAUSE 0x30000000 | 727 | #define IXGBE_AUTOC_PAUSE 0x30000000 |
@@ -1456,11 +1457,11 @@ struct ixgbe_mac_info { | |||
1456 | u32 max_tx_queues; | 1457 | u32 max_tx_queues; |
1457 | u32 max_rx_queues; | 1458 | u32 max_rx_queues; |
1458 | u32 max_msix_vectors; | 1459 | u32 max_msix_vectors; |
1459 | u32 link_attach_type; | 1460 | u32 orig_autoc; |
1460 | u32 link_mode_select; | 1461 | u32 orig_autoc2; |
1461 | bool link_settings_loaded; | 1462 | bool orig_link_settings_stored; |
1462 | bool autoneg; | 1463 | bool autoneg; |
1463 | bool autoneg_failed; | 1464 | bool autoneg_succeeded; |
1464 | }; | 1465 | }; |
1465 | 1466 | ||
1466 | struct ixgbe_phy_info { | 1467 | struct ixgbe_phy_info { |