aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/ixgbe
diff options
context:
space:
mode:
authorDon Skidmore <donald.c.skidmore@intel.com>2012-10-24 02:19:01 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2012-10-30 01:14:48 -0400
commitd7bbcd32adafee94e965d9ca188ddeede4c94597 (patch)
treefe88f22de09a1311f60796b1ab35e68a254dfc5a /drivers/net/ethernet/intel/ixgbe
parenta932657f51eadb8280166e82dc7034dfbff3985a (diff)
ixgbe: Add support for pipeline reset
Calling the ixgbe_reset_pipeline_82599 function will ensure a full pipeline reset on all 82599 devices. This is necessary to avoid possible link issues. Since this patch accomplishes this by modifying AUTOC.LMS we need to wrap all AUTOC writes when LESM is enabled. v2- fix LMS behaviour based on feedback by Martin Josefsson CC: Martin Josefsson <gandalf@mjufs.se> Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com> Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/ixgbe')
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe.h1
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c114
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_common.c70
3 files changed, 153 insertions, 32 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index c64a777b2c0b..a17116b3c470 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -693,6 +693,7 @@ extern s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw,
693 u16 soft_id); 693 u16 soft_id);
694extern void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input, 694extern void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input,
695 union ixgbe_atr_input *mask); 695 union ixgbe_atr_input *mask);
696extern bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw);
696extern void ixgbe_set_rx_mode(struct net_device *netdev); 697extern void ixgbe_set_rx_mode(struct net_device *netdev);
697#ifdef CONFIG_IXGBE_DCB 698#ifdef CONFIG_IXGBE_DCB
698extern void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter); 699extern void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
index b52781351659..e75f5a4a2a6d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
@@ -62,7 +62,6 @@ static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
62 bool autoneg, 62 bool autoneg,
63 bool autoneg_wait_to_complete); 63 bool autoneg_wait_to_complete);
64static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw); 64static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw);
65static bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw);
66 65
67static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw) 66static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
68{ 67{
@@ -99,9 +98,8 @@ static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
99static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw) 98static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
100{ 99{
101 s32 ret_val = 0; 100 s32 ret_val = 0;
102 u32 reg_anlp1 = 0;
103 u32 i = 0;
104 u16 list_offset, data_offset, data_value; 101 u16 list_offset, data_offset, data_value;
102 bool got_lock = false;
105 103
106 if (hw->phy.sfp_type != ixgbe_sfp_type_unknown) { 104 if (hw->phy.sfp_type != ixgbe_sfp_type_unknown) {
107 ixgbe_init_mac_link_ops_82599(hw); 105 ixgbe_init_mac_link_ops_82599(hw);
@@ -137,28 +135,36 @@ static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
137 usleep_range(hw->eeprom.semaphore_delay * 1000, 135 usleep_range(hw->eeprom.semaphore_delay * 1000,
138 hw->eeprom.semaphore_delay * 2000); 136 hw->eeprom.semaphore_delay * 2000);
139 137
140 /* Now restart DSP by setting Restart_AN and clearing LMS */ 138 /* Need SW/FW semaphore around AUTOC writes if LESM on,
141 IXGBE_WRITE_REG(hw, IXGBE_AUTOC, ((IXGBE_READ_REG(hw, 139 * likewise reset_pipeline requires lock as it also writes
142 IXGBE_AUTOC) & ~IXGBE_AUTOC_LMS_MASK) | 140 * AUTOC.
143 IXGBE_AUTOC_AN_RESTART)); 141 */
144 142 if (ixgbe_verify_lesm_fw_enabled_82599(hw)) {
145 /* Wait for AN to leave state 0 */ 143 ret_val = hw->mac.ops.acquire_swfw_sync(hw,
146 for (i = 0; i < 10; i++) { 144 IXGBE_GSSR_MAC_CSR_SM);
147 usleep_range(4000, 8000); 145 if (ret_val)
148 reg_anlp1 = IXGBE_READ_REG(hw, IXGBE_ANLP1); 146 goto setup_sfp_out;
149 if (reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK) 147
150 break; 148 got_lock = true;
149 }
150
151 /* Restart DSP and set SFI mode */
152 IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (IXGBE_READ_REG(hw,
153 IXGBE_AUTOC) | IXGBE_AUTOC_LMS_10G_SERIAL));
154
155 ret_val = ixgbe_reset_pipeline_82599(hw);
156
157 if (got_lock) {
158 hw->mac.ops.release_swfw_sync(hw,
159 IXGBE_GSSR_MAC_CSR_SM);
160 got_lock = false;
151 } 161 }
152 if (!(reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK)) { 162
153 hw_dbg(hw, "sfp module setup not complete\n"); 163 if (ret_val) {
164 hw_dbg(hw, " sfp module setup not complete\n");
154 ret_val = IXGBE_ERR_SFP_SETUP_NOT_COMPLETE; 165 ret_val = IXGBE_ERR_SFP_SETUP_NOT_COMPLETE;
155 goto setup_sfp_out; 166 goto setup_sfp_out;
156 } 167 }
157
158 /* Restart DSP by setting Restart_AN and return to SFI mode */
159 IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (IXGBE_READ_REG(hw,
160 IXGBE_AUTOC) | IXGBE_AUTOC_LMS_10G_SERIAL |
161 IXGBE_AUTOC_AN_RESTART));
162 } 168 }
163 169
164setup_sfp_out: 170setup_sfp_out:
@@ -394,14 +400,26 @@ static s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
394 u32 links_reg; 400 u32 links_reg;
395 u32 i; 401 u32 i;
396 s32 status = 0; 402 s32 status = 0;
403 bool got_lock = false;
404
405 if (ixgbe_verify_lesm_fw_enabled_82599(hw)) {
406 status = hw->mac.ops.acquire_swfw_sync(hw,
407 IXGBE_GSSR_MAC_CSR_SM);
408 if (status)
409 goto out;
410
411 got_lock = true;
412 }
397 413
398 /* Restart link */ 414 /* Restart link */
399 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); 415 ixgbe_reset_pipeline_82599(hw);
400 autoc_reg |= IXGBE_AUTOC_AN_RESTART; 416
401 IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); 417 if (got_lock)
418 hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
402 419
403 /* Only poll for autoneg to complete if specified to do so */ 420 /* Only poll for autoneg to complete if specified to do so */
404 if (autoneg_wait_to_complete) { 421 if (autoneg_wait_to_complete) {
422 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
405 if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) == 423 if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
406 IXGBE_AUTOC_LMS_KX4_KX_KR || 424 IXGBE_AUTOC_LMS_KX4_KX_KR ||
407 (autoc_reg & IXGBE_AUTOC_LMS_MASK) == 425 (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
@@ -425,6 +443,7 @@ static s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
425 /* Add delay to filter out noises during initial link setup */ 443 /* Add delay to filter out noises during initial link setup */
426 msleep(50); 444 msleep(50);
427 445
446out:
428 return status; 447 return status;
429} 448}
430 449
@@ -779,6 +798,7 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
779 u32 links_reg; 798 u32 links_reg;
780 u32 i; 799 u32 i;
781 ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN; 800 ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
801 bool got_lock = false;
782 802
783 /* Check to see if speed passed in is supported. */ 803 /* Check to see if speed passed in is supported. */
784 status = hw->mac.ops.get_link_capabilities(hw, &link_capabilities, 804 status = hw->mac.ops.get_link_capabilities(hw, &link_capabilities,
@@ -836,9 +856,26 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
836 } 856 }
837 857
838 if (autoc != start_autoc) { 858 if (autoc != start_autoc) {
859 /* Need SW/FW semaphore around AUTOC writes if LESM is on,
860 * likewise reset_pipeline requires us to hold this lock as
861 * it also writes to AUTOC.
862 */
863 if (ixgbe_verify_lesm_fw_enabled_82599(hw)) {
864 status = hw->mac.ops.acquire_swfw_sync(hw,
865 IXGBE_GSSR_MAC_CSR_SM);
866 if (status != 0)
867 goto out;
868
869 got_lock = true;
870 }
871
839 /* Restart link */ 872 /* Restart link */
840 autoc |= IXGBE_AUTOC_AN_RESTART;
841 IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc); 873 IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
874 ixgbe_reset_pipeline_82599(hw);
875
876 if (got_lock)
877 hw->mac.ops.release_swfw_sync(hw,
878 IXGBE_GSSR_MAC_CSR_SM);
842 879
843 /* Only poll for autoneg to complete if specified to do so */ 880 /* Only poll for autoneg to complete if specified to do so */
844 if (autoneg_wait_to_complete) { 881 if (autoneg_wait_to_complete) {
@@ -994,9 +1031,28 @@ mac_reset_top:
994 hw->mac.orig_autoc2 = autoc2; 1031 hw->mac.orig_autoc2 = autoc2;
995 hw->mac.orig_link_settings_stored = true; 1032 hw->mac.orig_link_settings_stored = true;
996 } else { 1033 } else {
997 if (autoc != hw->mac.orig_autoc) 1034 if (autoc != hw->mac.orig_autoc) {
998 IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (hw->mac.orig_autoc | 1035 /* Need SW/FW semaphore around AUTOC writes if LESM is
999 IXGBE_AUTOC_AN_RESTART)); 1036 * on, likewise reset_pipeline requires us to hold
1037 * this lock as it also writes to AUTOC.
1038 */
1039 bool got_lock = false;
1040 if (ixgbe_verify_lesm_fw_enabled_82599(hw)) {
1041 status = hw->mac.ops.acquire_swfw_sync(hw,
1042 IXGBE_GSSR_MAC_CSR_SM);
1043 if (status)
1044 goto reset_hw_out;
1045
1046 got_lock = true;
1047 }
1048
1049 IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc);
1050 ixgbe_reset_pipeline_82599(hw);
1051
1052 if (got_lock)
1053 hw->mac.ops.release_swfw_sync(hw,
1054 IXGBE_GSSR_MAC_CSR_SM);
1055 }
1000 1056
1001 if ((autoc2 & IXGBE_AUTOC2_UPPER_MASK) != 1057 if ((autoc2 & IXGBE_AUTOC2_UPPER_MASK) !=
1002 (hw->mac.orig_autoc2 & IXGBE_AUTOC2_UPPER_MASK)) { 1058 (hw->mac.orig_autoc2 & IXGBE_AUTOC2_UPPER_MASK)) {
@@ -1983,7 +2039,7 @@ fw_version_out:
1983 * Returns true if the LESM FW module is present and enabled. Otherwise 2039 * Returns true if the LESM FW module is present and enabled. Otherwise
1984 * returns false. Smart Speed must be disabled if LESM FW module is enabled. 2040 * returns false. Smart Speed must be disabled if LESM FW module is enabled.
1985 **/ 2041 **/
1986static bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw) 2042bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw)
1987{ 2043{
1988 bool lesm_enabled = false; 2044 bool lesm_enabled = false;
1989 u16 fw_offset, fw_lesm_param_offset, fw_lesm_state; 2045 u16 fw_offset, fw_lesm_param_offset, fw_lesm_state;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index a2a9bcca4915..8f285edb5094 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -90,6 +90,7 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw)
90 s32 ret_val = 0; 90 s32 ret_val = 0;
91 u32 reg = 0, reg_bp = 0; 91 u32 reg = 0, reg_bp = 0;
92 u16 reg_cu = 0; 92 u16 reg_cu = 0;
93 bool got_lock = false;
93 94
94 /* 95 /*
95 * Validate the requested mode. Strict IEEE mode does not allow 96 * Validate the requested mode. Strict IEEE mode does not allow
@@ -210,8 +211,29 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw)
210 * 211 *
211 */ 212 */
212 if (hw->phy.media_type == ixgbe_media_type_backplane) { 213 if (hw->phy.media_type == ixgbe_media_type_backplane) {
213 reg_bp |= IXGBE_AUTOC_AN_RESTART; 214 /* Need the SW/FW semaphore around AUTOC writes if 82599 and
215 * LESM is on, likewise reset_pipeline requries the lock as
216 * it also writes AUTOC.
217 */
218 if ((hw->mac.type == ixgbe_mac_82599EB) &&
219 ixgbe_verify_lesm_fw_enabled_82599(hw)) {
220 ret_val = hw->mac.ops.acquire_swfw_sync(hw,
221 IXGBE_GSSR_MAC_CSR_SM);
222 if (ret_val)
223 goto out;
224
225 got_lock = true;
226 }
227
214 IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_bp); 228 IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_bp);
229
230 if (hw->mac.type == ixgbe_mac_82599EB)
231 ixgbe_reset_pipeline_82599(hw);
232
233 if (got_lock)
234 hw->mac.ops.release_swfw_sync(hw,
235 IXGBE_GSSR_MAC_CSR_SM);
236
215 } else if ((hw->phy.media_type == ixgbe_media_type_copper) && 237 } else if ((hw->phy.media_type == ixgbe_media_type_copper) &&
216 (ixgbe_device_supports_autoneg_fc(hw) == 0)) { 238 (ixgbe_device_supports_autoneg_fc(hw) == 0)) {
217 hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE, 239 hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE,
@@ -2616,6 +2638,7 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
2616 bool link_up = false; 2638 bool link_up = false;
2617 u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); 2639 u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
2618 u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); 2640 u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
2641 s32 ret_val = 0;
2619 2642
2620 /* 2643 /*
2621 * Link must be up to auto-blink the LEDs; 2644 * Link must be up to auto-blink the LEDs;
@@ -2624,10 +2647,28 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
2624 hw->mac.ops.check_link(hw, &speed, &link_up, false); 2647 hw->mac.ops.check_link(hw, &speed, &link_up, false);
2625 2648
2626 if (!link_up) { 2649 if (!link_up) {
2650 /* Need the SW/FW semaphore around AUTOC writes if 82599 and
2651 * LESM is on.
2652 */
2653 bool got_lock = false;
2654
2655 if ((hw->mac.type == ixgbe_mac_82599EB) &&
2656 ixgbe_verify_lesm_fw_enabled_82599(hw)) {
2657 ret_val = hw->mac.ops.acquire_swfw_sync(hw,
2658 IXGBE_GSSR_MAC_CSR_SM);
2659 if (ret_val)
2660 goto out;
2661
2662 got_lock = true;
2663 }
2627 autoc_reg |= IXGBE_AUTOC_AN_RESTART; 2664 autoc_reg |= IXGBE_AUTOC_AN_RESTART;
2628 autoc_reg |= IXGBE_AUTOC_FLU; 2665 autoc_reg |= IXGBE_AUTOC_FLU;
2629 IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); 2666 IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
2630 IXGBE_WRITE_FLUSH(hw); 2667 IXGBE_WRITE_FLUSH(hw);
2668
2669 if (got_lock)
2670 hw->mac.ops.release_swfw_sync(hw,
2671 IXGBE_GSSR_MAC_CSR_SM);
2631 usleep_range(10000, 20000); 2672 usleep_range(10000, 20000);
2632 } 2673 }
2633 2674
@@ -2636,7 +2677,8 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
2636 IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); 2677 IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
2637 IXGBE_WRITE_FLUSH(hw); 2678 IXGBE_WRITE_FLUSH(hw);
2638 2679
2639 return 0; 2680out:
2681 return ret_val;
2640} 2682}
2641 2683
2642/** 2684/**
@@ -2648,18 +2690,40 @@ s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index)
2648{ 2690{
2649 u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); 2691 u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
2650 u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); 2692 u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
2693 s32 ret_val = 0;
2694 bool got_lock = false;
2695
2696 /* Need the SW/FW semaphore around AUTOC writes if 82599 and
2697 * LESM is on.
2698 */
2699 if ((hw->mac.type == ixgbe_mac_82599EB) &&
2700 ixgbe_verify_lesm_fw_enabled_82599(hw)) {
2701 ret_val = hw->mac.ops.acquire_swfw_sync(hw,
2702 IXGBE_GSSR_MAC_CSR_SM);
2703 if (ret_val)
2704 goto out;
2705
2706 got_lock = true;
2707 }
2651 2708
2652 autoc_reg &= ~IXGBE_AUTOC_FLU; 2709 autoc_reg &= ~IXGBE_AUTOC_FLU;
2653 autoc_reg |= IXGBE_AUTOC_AN_RESTART; 2710 autoc_reg |= IXGBE_AUTOC_AN_RESTART;
2654 IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); 2711 IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
2655 2712
2713 if (hw->mac.type == ixgbe_mac_82599EB)
2714 ixgbe_reset_pipeline_82599(hw);
2715
2716 if (got_lock)
2717 hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
2718
2656 led_reg &= ~IXGBE_LED_MODE_MASK(index); 2719 led_reg &= ~IXGBE_LED_MODE_MASK(index);
2657 led_reg &= ~IXGBE_LED_BLINK(index); 2720 led_reg &= ~IXGBE_LED_BLINK(index);
2658 led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index); 2721 led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index);
2659 IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); 2722 IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
2660 IXGBE_WRITE_FLUSH(hw); 2723 IXGBE_WRITE_FLUSH(hw);
2661 2724
2662 return 0; 2725out:
2726 return ret_val;
2663} 2727}
2664 2728
2665/** 2729/**