aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c')
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c160
1 files changed, 130 insertions, 30 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
index 1077cb2b38db..1073aea5da40 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)) {
@@ -1022,7 +1078,7 @@ mac_reset_top:
1022 hw->mac.ops.get_san_mac_addr(hw, hw->mac.san_addr); 1078 hw->mac.ops.get_san_mac_addr(hw, hw->mac.san_addr);
1023 1079
1024 /* Add the SAN MAC address to the RAR only if it's a valid address */ 1080 /* Add the SAN MAC address to the RAR only if it's a valid address */
1025 if (ixgbe_validate_mac_addr(hw->mac.san_addr) == 0) { 1081 if (is_valid_ether_addr(hw->mac.san_addr)) {
1026 hw->mac.ops.set_rar(hw, hw->mac.num_rar_entries - 1, 1082 hw->mac.ops.set_rar(hw, hw->mac.num_rar_entries - 1,
1027 hw->mac.san_addr, 0, IXGBE_RAH_AV); 1083 hw->mac.san_addr, 0, IXGBE_RAH_AV);
1028 1084
@@ -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;
@@ -2080,6 +2136,50 @@ static s32 ixgbe_read_eeprom_82599(struct ixgbe_hw *hw,
2080 return ret_val; 2136 return ret_val;
2081} 2137}
2082 2138
2139/**
2140 * ixgbe_reset_pipeline_82599 - perform pipeline reset
2141 *
2142 * @hw: pointer to hardware structure
2143 *
2144 * Reset pipeline by asserting Restart_AN together with LMS change to ensure
2145 * full pipeline reset. Note - We must hold the SW/FW semaphore before writing
2146 * to AUTOC, so this function assumes the semaphore is held.
2147 **/
2148s32 ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw)
2149{
2150 s32 i, autoc_reg, ret_val;
2151 s32 anlp1_reg = 0;
2152
2153 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
2154 autoc_reg |= IXGBE_AUTOC_AN_RESTART;
2155
2156 /* Write AUTOC register with toggled LMS[2] bit and Restart_AN */
2157 IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg ^ IXGBE_AUTOC_LMS_1G_AN);
2158
2159 /* Wait for AN to leave state 0 */
2160 for (i = 0; i < 10; i++) {
2161 usleep_range(4000, 8000);
2162 anlp1_reg = IXGBE_READ_REG(hw, IXGBE_ANLP1);
2163 if (anlp1_reg & IXGBE_ANLP1_AN_STATE_MASK)
2164 break;
2165 }
2166
2167 if (!(anlp1_reg & IXGBE_ANLP1_AN_STATE_MASK)) {
2168 hw_dbg(hw, "auto negotiation not completed\n");
2169 ret_val = IXGBE_ERR_RESET_FAILED;
2170 goto reset_pipeline_out;
2171 }
2172
2173 ret_val = 0;
2174
2175reset_pipeline_out:
2176 /* Write AUTOC register with original LMS field and Restart_AN */
2177 IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
2178 IXGBE_WRITE_FLUSH(hw);
2179
2180 return ret_val;
2181}
2182
2083static struct ixgbe_mac_operations mac_ops_82599 = { 2183static struct ixgbe_mac_operations mac_ops_82599 = {
2084 .init_hw = &ixgbe_init_hw_generic, 2184 .init_hw = &ixgbe_init_hw_generic,
2085 .reset_hw = &ixgbe_reset_hw_82599, 2185 .reset_hw = &ixgbe_reset_hw_82599,