diff options
| -rw-r--r-- | drivers/net/ethernet/intel/e1000e/defines.h | 8 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/e1000e/hw.h | 8 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/e1000e/ich8lan.c | 324 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/e1000e/ich8lan.h | 22 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/e1000e/netdev.c | 24 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/e1000e/regs.h | 1 |
6 files changed, 354 insertions, 33 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/defines.h b/drivers/net/ethernet/intel/e1000e/defines.h index 1b7c26857881..d18e89212575 100644 --- a/drivers/net/ethernet/intel/e1000e/defines.h +++ b/drivers/net/ethernet/intel/e1000e/defines.h | |||
| @@ -28,9 +28,11 @@ | |||
| 28 | 28 | ||
| 29 | /* Definitions for power management and wakeup registers */ | 29 | /* Definitions for power management and wakeup registers */ |
| 30 | /* Wake Up Control */ | 30 | /* Wake Up Control */ |
| 31 | #define E1000_WUC_APME 0x00000001 /* APM Enable */ | 31 | #define E1000_WUC_APME 0x00000001 /* APM Enable */ |
| 32 | #define E1000_WUC_PME_EN 0x00000002 /* PME Enable */ | 32 | #define E1000_WUC_PME_EN 0x00000002 /* PME Enable */ |
| 33 | #define E1000_WUC_PHY_WAKE 0x00000100 /* if PHY supports wakeup */ | 33 | #define E1000_WUC_PME_STATUS 0x00000004 /* PME Status */ |
| 34 | #define E1000_WUC_APMPME 0x00000008 /* Assert PME on APM Wakeup */ | ||
| 35 | #define E1000_WUC_PHY_WAKE 0x00000100 /* if PHY supports wakeup */ | ||
| 34 | 36 | ||
| 35 | /* Wake Up Filter Control */ | 37 | /* Wake Up Filter Control */ |
| 36 | #define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */ | 38 | #define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */ |
diff --git a/drivers/net/ethernet/intel/e1000e/hw.h b/drivers/net/ethernet/intel/e1000e/hw.h index 016028350150..6b3de5f39a97 100644 --- a/drivers/net/ethernet/intel/e1000e/hw.h +++ b/drivers/net/ethernet/intel/e1000e/hw.h | |||
| @@ -648,12 +648,20 @@ struct e1000_shadow_ram { | |||
| 648 | 648 | ||
| 649 | #define E1000_ICH8_SHADOW_RAM_WORDS 2048 | 649 | #define E1000_ICH8_SHADOW_RAM_WORDS 2048 |
| 650 | 650 | ||
| 651 | /* I218 PHY Ultra Low Power (ULP) states */ | ||
| 652 | enum e1000_ulp_state { | ||
| 653 | e1000_ulp_state_unknown, | ||
| 654 | e1000_ulp_state_off, | ||
| 655 | e1000_ulp_state_on, | ||
| 656 | }; | ||
| 657 | |||
| 651 | struct e1000_dev_spec_ich8lan { | 658 | struct e1000_dev_spec_ich8lan { |
| 652 | bool kmrn_lock_loss_workaround_enabled; | 659 | bool kmrn_lock_loss_workaround_enabled; |
| 653 | struct e1000_shadow_ram shadow_ram[E1000_ICH8_SHADOW_RAM_WORDS]; | 660 | struct e1000_shadow_ram shadow_ram[E1000_ICH8_SHADOW_RAM_WORDS]; |
| 654 | bool nvm_k1_enabled; | 661 | bool nvm_k1_enabled; |
| 655 | bool eee_disable; | 662 | bool eee_disable; |
| 656 | u16 eee_lp_ability; | 663 | u16 eee_lp_ability; |
| 664 | enum e1000_ulp_state ulp_state; | ||
| 657 | }; | 665 | }; |
| 658 | 666 | ||
| 659 | struct e1000_hw { | 667 | struct e1000_hw { |
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 723410a60297..18984519a18d 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c | |||
| @@ -143,7 +143,9 @@ static void e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index); | |||
| 143 | static void e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index); | 143 | static void e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index); |
| 144 | static s32 e1000_k1_workaround_lv(struct e1000_hw *hw); | 144 | static s32 e1000_k1_workaround_lv(struct e1000_hw *hw); |
| 145 | static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate); | 145 | static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate); |
| 146 | static s32 e1000_disable_ulp_lpt_lp(struct e1000_hw *hw, bool force); | ||
| 146 | static s32 e1000_setup_copper_link_pch_lpt(struct e1000_hw *hw); | 147 | static s32 e1000_setup_copper_link_pch_lpt(struct e1000_hw *hw); |
| 148 | static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state); | ||
| 147 | 149 | ||
| 148 | static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg) | 150 | static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg) |
| 149 | { | 151 | { |
| @@ -240,6 +242,47 @@ out: | |||
| 240 | } | 242 | } |
| 241 | 243 | ||
| 242 | /** | 244 | /** |
| 245 | * e1000_toggle_lanphypc_pch_lpt - toggle the LANPHYPC pin value | ||
| 246 | * @hw: pointer to the HW structure | ||
| 247 | * | ||
| 248 | * Toggling the LANPHYPC pin value fully power-cycles the PHY and is | ||
| 249 | * used to reset the PHY to a quiescent state when necessary. | ||
| 250 | **/ | ||
| 251 | static void e1000_toggle_lanphypc_pch_lpt(struct e1000_hw *hw) | ||
| 252 | { | ||
| 253 | u32 mac_reg; | ||
| 254 | |||
| 255 | /* Set Phy Config Counter to 50msec */ | ||
| 256 | mac_reg = er32(FEXTNVM3); | ||
| 257 | mac_reg &= ~E1000_FEXTNVM3_PHY_CFG_COUNTER_MASK; | ||
| 258 | mac_reg |= E1000_FEXTNVM3_PHY_CFG_COUNTER_50MSEC; | ||
| 259 | ew32(FEXTNVM3, mac_reg); | ||
| 260 | |||
| 261 | /* Toggle LANPHYPC Value bit */ | ||
| 262 | mac_reg = er32(CTRL); | ||
| 263 | mac_reg |= E1000_CTRL_LANPHYPC_OVERRIDE; | ||
| 264 | mac_reg &= ~E1000_CTRL_LANPHYPC_VALUE; | ||
| 265 | ew32(CTRL, mac_reg); | ||
| 266 | e1e_flush(); | ||
| 267 | usleep_range(10, 20); | ||
| 268 | mac_reg &= ~E1000_CTRL_LANPHYPC_OVERRIDE; | ||
| 269 | ew32(CTRL, mac_reg); | ||
| 270 | e1e_flush(); | ||
| 271 | |||
| 272 | if (hw->mac.type < e1000_pch_lpt) { | ||
| 273 | msleep(50); | ||
| 274 | } else { | ||
| 275 | u16 count = 20; | ||
| 276 | |||
| 277 | do { | ||
| 278 | usleep_range(5000, 10000); | ||
| 279 | } while (!(er32(CTRL_EXT) & E1000_CTRL_EXT_LPCD) && count--); | ||
| 280 | |||
| 281 | msleep(30); | ||
| 282 | } | ||
| 283 | } | ||
| 284 | |||
| 285 | /** | ||
| 243 | * e1000_init_phy_workarounds_pchlan - PHY initialization workarounds | 286 | * e1000_init_phy_workarounds_pchlan - PHY initialization workarounds |
| 244 | * @hw: pointer to the HW structure | 287 | * @hw: pointer to the HW structure |
| 245 | * | 288 | * |
| @@ -257,6 +300,12 @@ static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw) | |||
| 257 | */ | 300 | */ |
| 258 | e1000_gate_hw_phy_config_ich8lan(hw, true); | 301 | e1000_gate_hw_phy_config_ich8lan(hw, true); |
| 259 | 302 | ||
| 303 | /* It is not possible to be certain of the current state of ULP | ||
| 304 | * so forcibly disable it. | ||
| 305 | */ | ||
| 306 | hw->dev_spec.ich8lan.ulp_state = e1000_ulp_state_unknown; | ||
| 307 | e1000_disable_ulp_lpt_lp(hw, true); | ||
| 308 | |||
| 260 | ret_val = hw->phy.ops.acquire(hw); | 309 | ret_val = hw->phy.ops.acquire(hw); |
| 261 | if (ret_val) { | 310 | if (ret_val) { |
| 262 | e_dbg("Failed to initialize PHY flow\n"); | 311 | e_dbg("Failed to initialize PHY flow\n"); |
| @@ -302,33 +351,9 @@ static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw) | |||
| 302 | break; | 351 | break; |
| 303 | } | 352 | } |
| 304 | 353 | ||
| 305 | e_dbg("Toggling LANPHYPC\n"); | ||
| 306 | |||
| 307 | /* Set Phy Config Counter to 50msec */ | ||
| 308 | mac_reg = er32(FEXTNVM3); | ||
| 309 | mac_reg &= ~E1000_FEXTNVM3_PHY_CFG_COUNTER_MASK; | ||
| 310 | mac_reg |= E1000_FEXTNVM3_PHY_CFG_COUNTER_50MSEC; | ||
| 311 | ew32(FEXTNVM3, mac_reg); | ||
| 312 | |||
| 313 | /* Toggle LANPHYPC Value bit */ | 354 | /* Toggle LANPHYPC Value bit */ |
| 314 | mac_reg = er32(CTRL); | 355 | e1000_toggle_lanphypc_pch_lpt(hw); |
| 315 | mac_reg |= E1000_CTRL_LANPHYPC_OVERRIDE; | 356 | if (hw->mac.type >= e1000_pch_lpt) { |
| 316 | mac_reg &= ~E1000_CTRL_LANPHYPC_VALUE; | ||
| 317 | ew32(CTRL, mac_reg); | ||
| 318 | e1e_flush(); | ||
| 319 | usleep_range(10, 20); | ||
| 320 | mac_reg &= ~E1000_CTRL_LANPHYPC_OVERRIDE; | ||
| 321 | ew32(CTRL, mac_reg); | ||
| 322 | e1e_flush(); | ||
| 323 | if (hw->mac.type < e1000_pch_lpt) { | ||
| 324 | msleep(50); | ||
| 325 | } else { | ||
| 326 | u16 count = 20; | ||
| 327 | do { | ||
| 328 | usleep_range(5000, 10000); | ||
| 329 | } while (!(er32(CTRL_EXT) & | ||
| 330 | E1000_CTRL_EXT_LPCD) && count--); | ||
| 331 | usleep_range(30000, 60000); | ||
| 332 | if (e1000_phy_is_accessible_pchlan(hw)) | 357 | if (e1000_phy_is_accessible_pchlan(hw)) |
| 333 | break; | 358 | break; |
| 334 | 359 | ||
| @@ -1006,6 +1031,253 @@ static s32 e1000_platform_pm_pch_lpt(struct e1000_hw *hw, bool link) | |||
| 1006 | } | 1031 | } |
| 1007 | 1032 | ||
| 1008 | /** | 1033 | /** |
| 1034 | * e1000_enable_ulp_lpt_lp - configure Ultra Low Power mode for LynxPoint-LP | ||
| 1035 | * @hw: pointer to the HW structure | ||
| 1036 | * @to_sx: boolean indicating a system power state transition to Sx | ||
| 1037 | * | ||
| 1038 | * When link is down, configure ULP mode to significantly reduce the power | ||
| 1039 | * to the PHY. If on a Manageability Engine (ME) enabled system, tell the | ||
| 1040 | * ME firmware to start the ULP configuration. If not on an ME enabled | ||
| 1041 | * system, configure the ULP mode by software. | ||
| 1042 | */ | ||
| 1043 | s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx) | ||
| 1044 | { | ||
| 1045 | u32 mac_reg; | ||
| 1046 | s32 ret_val = 0; | ||
| 1047 | u16 phy_reg; | ||
| 1048 | |||
| 1049 | if ((hw->mac.type < e1000_pch_lpt) || | ||
| 1050 | (hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPT_I217_LM) || | ||
| 1051 | (hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPT_I217_V) || | ||
| 1052 | (hw->adapter->pdev->device == E1000_DEV_ID_PCH_I218_LM2) || | ||
| 1053 | (hw->adapter->pdev->device == E1000_DEV_ID_PCH_I218_V2) || | ||
| 1054 | (hw->dev_spec.ich8lan.ulp_state == e1000_ulp_state_on)) | ||
| 1055 | return 0; | ||
| 1056 | |||
| 1057 | if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID) { | ||
| 1058 | /* Request ME configure ULP mode in the PHY */ | ||
| 1059 | mac_reg = er32(H2ME); | ||
| 1060 | mac_reg |= E1000_H2ME_ULP | E1000_H2ME_ENFORCE_SETTINGS; | ||
| 1061 | ew32(H2ME, mac_reg); | ||
| 1062 | |||
| 1063 | goto out; | ||
| 1064 | } | ||
| 1065 | |||
| 1066 | if (!to_sx) { | ||
| 1067 | int i = 0; | ||
| 1068 | |||
| 1069 | /* Poll up to 5 seconds for Cable Disconnected indication */ | ||
| 1070 | while (!(er32(FEXT) & E1000_FEXT_PHY_CABLE_DISCONNECTED)) { | ||
| 1071 | /* Bail if link is re-acquired */ | ||
| 1072 | if (er32(STATUS) & E1000_STATUS_LU) | ||
| 1073 | return -E1000_ERR_PHY; | ||
| 1074 | |||
| 1075 | if (i++ == 100) | ||
| 1076 | break; | ||
| 1077 | |||
| 1078 | msleep(50); | ||
| 1079 | } | ||
| 1080 | e_dbg("CABLE_DISCONNECTED %s set after %dmsec\n", | ||
| 1081 | (er32(FEXT) & | ||
| 1082 | E1000_FEXT_PHY_CABLE_DISCONNECTED) ? "" : "not", i * 50); | ||
| 1083 | } | ||
| 1084 | |||
| 1085 | ret_val = hw->phy.ops.acquire(hw); | ||
| 1086 | if (ret_val) | ||
| 1087 | goto out; | ||
| 1088 | |||
| 1089 | /* Force SMBus mode in PHY */ | ||
| 1090 | ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &phy_reg); | ||
| 1091 | if (ret_val) | ||
| 1092 | goto release; | ||
| 1093 | phy_reg |= CV_SMB_CTRL_FORCE_SMBUS; | ||
| 1094 | e1000_write_phy_reg_hv_locked(hw, CV_SMB_CTRL, phy_reg); | ||
| 1095 | |||
| 1096 | /* Force SMBus mode in MAC */ | ||
| 1097 | mac_reg = er32(CTRL_EXT); | ||
| 1098 | mac_reg |= E1000_CTRL_EXT_FORCE_SMBUS; | ||
| 1099 | ew32(CTRL_EXT, mac_reg); | ||
| 1100 | |||
| 1101 | /* Set Inband ULP Exit, Reset to SMBus mode and | ||
| 1102 | * Disable SMBus Release on PERST# in PHY | ||
| 1103 | */ | ||
| 1104 | ret_val = e1000_read_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, &phy_reg); | ||
| 1105 | if (ret_val) | ||
| 1106 | goto release; | ||
| 1107 | phy_reg |= (I218_ULP_CONFIG1_RESET_TO_SMBUS | | ||
| 1108 | I218_ULP_CONFIG1_DISABLE_SMB_PERST); | ||
| 1109 | if (to_sx) { | ||
| 1110 | if (er32(WUFC) & E1000_WUFC_LNKC) | ||
| 1111 | phy_reg |= I218_ULP_CONFIG1_WOL_HOST; | ||
| 1112 | |||
| 1113 | phy_reg |= I218_ULP_CONFIG1_STICKY_ULP; | ||
| 1114 | } else { | ||
| 1115 | phy_reg |= I218_ULP_CONFIG1_INBAND_EXIT; | ||
| 1116 | } | ||
| 1117 | e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg); | ||
| 1118 | |||
| 1119 | /* Set Disable SMBus Release on PERST# in MAC */ | ||
| 1120 | mac_reg = er32(FEXTNVM7); | ||
| 1121 | mac_reg |= E1000_FEXTNVM7_DISABLE_SMB_PERST; | ||
| 1122 | ew32(FEXTNVM7, mac_reg); | ||
| 1123 | |||
| 1124 | /* Commit ULP changes in PHY by starting auto ULP configuration */ | ||
| 1125 | phy_reg |= I218_ULP_CONFIG1_START; | ||
| 1126 | e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg); | ||
| 1127 | release: | ||
| 1128 | hw->phy.ops.release(hw); | ||
| 1129 | out: | ||
| 1130 | if (ret_val) | ||
| 1131 | e_dbg("Error in ULP enable flow: %d\n", ret_val); | ||
| 1132 | else | ||
| 1133 | hw->dev_spec.ich8lan.ulp_state = e1000_ulp_state_on; | ||
| 1134 | |||
| 1135 | return ret_val; | ||
| 1136 | } | ||
| 1137 | |||
| 1138 | /** | ||
| 1139 | * e1000_disable_ulp_lpt_lp - unconfigure Ultra Low Power mode for LynxPoint-LP | ||
| 1140 | * @hw: pointer to the HW structure | ||
| 1141 | * @force: boolean indicating whether or not to force disabling ULP | ||
| 1142 | * | ||
| 1143 | * Un-configure ULP mode when link is up, the system is transitioned from | ||
| 1144 | * Sx or the driver is unloaded. If on a Manageability Engine (ME) enabled | ||
| 1145 | * system, poll for an indication from ME that ULP has been un-configured. | ||
| 1146 | * If not on an ME enabled system, un-configure the ULP mode by software. | ||
| 1147 | * | ||
| 1148 | * During nominal operation, this function is called when link is acquired | ||
| 1149 | * to disable ULP mode (force=false); otherwise, for example when unloading | ||
| 1150 | * the driver or during Sx->S0 transitions, this is called with force=true | ||
| 1151 | * to forcibly disable ULP. | ||
| 1152 | */ | ||
| 1153 | static s32 e1000_disable_ulp_lpt_lp(struct e1000_hw *hw, bool force) | ||
| 1154 | { | ||
| 1155 | s32 ret_val = 0; | ||
| 1156 | u32 mac_reg; | ||
| 1157 | u16 phy_reg; | ||
| 1158 | int i = 0; | ||
| 1159 | |||
| 1160 | if ((hw->mac.type < e1000_pch_lpt) || | ||
| 1161 | (hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPT_I217_LM) || | ||
| 1162 | (hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPT_I217_V) || | ||
| 1163 | (hw->adapter->pdev->device == E1000_DEV_ID_PCH_I218_LM2) || | ||
| 1164 | (hw->adapter->pdev->device == E1000_DEV_ID_PCH_I218_V2) || | ||
| 1165 | (hw->dev_spec.ich8lan.ulp_state == e1000_ulp_state_off)) | ||
| 1166 | return 0; | ||
| 1167 | |||
| 1168 | if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID) { | ||
| 1169 | if (force) { | ||
| 1170 | /* Request ME un-configure ULP mode in the PHY */ | ||
| 1171 | mac_reg = er32(H2ME); | ||
| 1172 | mac_reg &= ~E1000_H2ME_ULP; | ||
| 1173 | mac_reg |= E1000_H2ME_ENFORCE_SETTINGS; | ||
| 1174 | ew32(H2ME, mac_reg); | ||
| 1175 | } | ||
| 1176 | |||
| 1177 | /* Poll up to 100msec for ME to clear ULP_CFG_DONE */ | ||
| 1178 | while (er32(FWSM) & E1000_FWSM_ULP_CFG_DONE) { | ||
| 1179 | if (i++ == 10) { | ||
| 1180 | ret_val = -E1000_ERR_PHY; | ||
| 1181 | goto out; | ||
| 1182 | } | ||
| 1183 | |||
| 1184 | usleep_range(10000, 20000); | ||
| 1185 | } | ||
| 1186 | e_dbg("ULP_CONFIG_DONE cleared after %dmsec\n", i * 10); | ||
| 1187 | |||
| 1188 | if (force) { | ||
| 1189 | mac_reg = er32(H2ME); | ||
| 1190 | mac_reg &= ~E1000_H2ME_ENFORCE_SETTINGS; | ||
| 1191 | ew32(H2ME, mac_reg); | ||
| 1192 | } else { | ||
| 1193 | /* Clear H2ME.ULP after ME ULP configuration */ | ||
| 1194 | mac_reg = er32(H2ME); | ||
| 1195 | mac_reg &= ~E1000_H2ME_ULP; | ||
| 1196 | ew32(H2ME, mac_reg); | ||
| 1197 | } | ||
| 1198 | |||
| 1199 | goto out; | ||
| 1200 | } | ||
| 1201 | |||
| 1202 | ret_val = hw->phy.ops.acquire(hw); | ||
| 1203 | if (ret_val) | ||
| 1204 | goto out; | ||
| 1205 | |||
| 1206 | if (force) | ||
| 1207 | /* Toggle LANPHYPC Value bit */ | ||
| 1208 | e1000_toggle_lanphypc_pch_lpt(hw); | ||
| 1209 | |||
| 1210 | /* Unforce SMBus mode in PHY */ | ||
| 1211 | ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &phy_reg); | ||
| 1212 | if (ret_val) { | ||
| 1213 | /* The MAC might be in PCIe mode, so temporarily force to | ||
| 1214 | * SMBus mode in order to access the PHY. | ||
| 1215 | */ | ||
| 1216 | mac_reg = er32(CTRL_EXT); | ||
| 1217 | mac_reg |= E1000_CTRL_EXT_FORCE_SMBUS; | ||
| 1218 | ew32(CTRL_EXT, mac_reg); | ||
| 1219 | |||
| 1220 | msleep(50); | ||
| 1221 | |||
| 1222 | ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, | ||
| 1223 | &phy_reg); | ||
| 1224 | if (ret_val) | ||
| 1225 | goto release; | ||
| 1226 | } | ||
| 1227 | phy_reg &= ~CV_SMB_CTRL_FORCE_SMBUS; | ||
| 1228 | e1000_write_phy_reg_hv_locked(hw, CV_SMB_CTRL, phy_reg); | ||
| 1229 | |||
| 1230 | /* Unforce SMBus mode in MAC */ | ||
| 1231 | mac_reg = er32(CTRL_EXT); | ||
| 1232 | mac_reg &= ~E1000_CTRL_EXT_FORCE_SMBUS; | ||
| 1233 | ew32(CTRL_EXT, mac_reg); | ||
| 1234 | |||
| 1235 | /* When ULP mode was previously entered, K1 was disabled by the | ||
| 1236 | * hardware. Re-Enable K1 in the PHY when exiting ULP. | ||
| 1237 | */ | ||
| 1238 | ret_val = e1000_read_phy_reg_hv_locked(hw, HV_PM_CTRL, &phy_reg); | ||
| 1239 | if (ret_val) | ||
| 1240 | goto release; | ||
| 1241 | phy_reg |= HV_PM_CTRL_K1_ENABLE; | ||
| 1242 | e1000_write_phy_reg_hv_locked(hw, HV_PM_CTRL, phy_reg); | ||
| 1243 | |||
| 1244 | /* Clear ULP enabled configuration */ | ||
| 1245 | ret_val = e1000_read_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, &phy_reg); | ||
| 1246 | if (ret_val) | ||
| 1247 | goto release; | ||
| 1248 | phy_reg &= ~(I218_ULP_CONFIG1_IND | | ||
| 1249 | I218_ULP_CONFIG1_STICKY_ULP | | ||
| 1250 | I218_ULP_CONFIG1_RESET_TO_SMBUS | | ||
| 1251 | I218_ULP_CONFIG1_WOL_HOST | | ||
| 1252 | I218_ULP_CONFIG1_INBAND_EXIT | | ||
| 1253 | I218_ULP_CONFIG1_DISABLE_SMB_PERST); | ||
| 1254 | e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg); | ||
| 1255 | |||
| 1256 | /* Commit ULP changes by starting auto ULP configuration */ | ||
| 1257 | phy_reg |= I218_ULP_CONFIG1_START; | ||
| 1258 | e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg); | ||
| 1259 | |||
| 1260 | /* Clear Disable SMBus Release on PERST# in MAC */ | ||
| 1261 | mac_reg = er32(FEXTNVM7); | ||
| 1262 | mac_reg &= ~E1000_FEXTNVM7_DISABLE_SMB_PERST; | ||
| 1263 | ew32(FEXTNVM7, mac_reg); | ||
| 1264 | |||
| 1265 | release: | ||
| 1266 | hw->phy.ops.release(hw); | ||
| 1267 | if (force) { | ||
| 1268 | e1000_phy_hw_reset(hw); | ||
| 1269 | msleep(50); | ||
| 1270 | } | ||
| 1271 | out: | ||
| 1272 | if (ret_val) | ||
| 1273 | e_dbg("Error in ULP disable flow: %d\n", ret_val); | ||
| 1274 | else | ||
| 1275 | hw->dev_spec.ich8lan.ulp_state = e1000_ulp_state_off; | ||
| 1276 | |||
| 1277 | return ret_val; | ||
| 1278 | } | ||
| 1279 | |||
| 1280 | /** | ||
| 1009 | * e1000_check_for_copper_link_ich8lan - Check for link (Copper) | 1281 | * e1000_check_for_copper_link_ich8lan - Check for link (Copper) |
| 1010 | * @hw: pointer to the HW structure | 1282 | * @hw: pointer to the HW structure |
| 1011 | * | 1283 | * |
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.h b/drivers/net/ethernet/intel/e1000e/ich8lan.h index 51e0b157a731..553f05ec0278 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.h +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.h | |||
| @@ -58,11 +58,16 @@ | |||
| 58 | 58 | ||
| 59 | #define E1000_FWSM_WLOCK_MAC_MASK 0x0380 | 59 | #define E1000_FWSM_WLOCK_MAC_MASK 0x0380 |
| 60 | #define E1000_FWSM_WLOCK_MAC_SHIFT 7 | 60 | #define E1000_FWSM_WLOCK_MAC_SHIFT 7 |
| 61 | #define E1000_FWSM_ULP_CFG_DONE 0x00000400 /* Low power cfg done */ | ||
| 61 | 62 | ||
| 62 | /* Shared Receive Address Registers */ | 63 | /* Shared Receive Address Registers */ |
| 63 | #define E1000_SHRAL_PCH_LPT(_i) (0x05408 + ((_i) * 8)) | 64 | #define E1000_SHRAL_PCH_LPT(_i) (0x05408 + ((_i) * 8)) |
| 64 | #define E1000_SHRAH_PCH_LPT(_i) (0x0540C + ((_i) * 8)) | 65 | #define E1000_SHRAH_PCH_LPT(_i) (0x0540C + ((_i) * 8)) |
| 65 | 66 | ||
| 67 | #define E1000_H2ME 0x05B50 /* Host to ME */ | ||
| 68 | #define E1000_H2ME_ULP 0x00000800 /* ULP Indication Bit */ | ||
| 69 | #define E1000_H2ME_ENFORCE_SETTINGS 0x00001000 /* Enforce Settings */ | ||
| 70 | |||
| 66 | #define ID_LED_DEFAULT_ICH8LAN ((ID_LED_DEF1_DEF2 << 12) | \ | 71 | #define ID_LED_DEFAULT_ICH8LAN ((ID_LED_DEF1_DEF2 << 12) | \ |
| 67 | (ID_LED_OFF1_OFF2 << 8) | \ | 72 | (ID_LED_OFF1_OFF2 << 8) | \ |
| 68 | (ID_LED_OFF1_ON2 << 4) | \ | 73 | (ID_LED_OFF1_ON2 << 4) | \ |
| @@ -75,6 +80,9 @@ | |||
| 75 | 80 | ||
| 76 | #define E1000_ICH8_LAN_INIT_TIMEOUT 1500 | 81 | #define E1000_ICH8_LAN_INIT_TIMEOUT 1500 |
| 77 | 82 | ||
| 83 | /* FEXT register bit definition */ | ||
| 84 | #define E1000_FEXT_PHY_CABLE_DISCONNECTED 0x00000004 | ||
| 85 | |||
| 78 | #define E1000_FEXTNVM_SW_CONFIG 1 | 86 | #define E1000_FEXTNVM_SW_CONFIG 1 |
| 79 | #define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* different on ICH8M */ | 87 | #define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* different on ICH8M */ |
| 80 | 88 | ||
| @@ -88,6 +96,8 @@ | |||
| 88 | #define E1000_FEXTNVM6_REQ_PLL_CLK 0x00000100 | 96 | #define E1000_FEXTNVM6_REQ_PLL_CLK 0x00000100 |
| 89 | #define E1000_FEXTNVM6_ENABLE_K1_ENTRY_CONDITION 0x00000200 | 97 | #define E1000_FEXTNVM6_ENABLE_K1_ENTRY_CONDITION 0x00000200 |
| 90 | 98 | ||
| 99 | #define E1000_FEXTNVM7_DISABLE_SMB_PERST 0x00000020 | ||
| 100 | |||
| 91 | #define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL | 101 | #define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL |
| 92 | 102 | ||
| 93 | #define E1000_ICH_RAR_ENTRIES 7 | 103 | #define E1000_ICH_RAR_ENTRIES 7 |
| @@ -154,6 +164,16 @@ | |||
| 154 | #define CV_SMB_CTRL PHY_REG(769, 23) | 164 | #define CV_SMB_CTRL PHY_REG(769, 23) |
| 155 | #define CV_SMB_CTRL_FORCE_SMBUS 0x0001 | 165 | #define CV_SMB_CTRL_FORCE_SMBUS 0x0001 |
| 156 | 166 | ||
| 167 | /* I218 Ultra Low Power Configuration 1 Register */ | ||
| 168 | #define I218_ULP_CONFIG1 PHY_REG(779, 16) | ||
| 169 | #define I218_ULP_CONFIG1_START 0x0001 /* Start auto ULP config */ | ||
| 170 | #define I218_ULP_CONFIG1_IND 0x0004 /* Pwr up from ULP indication */ | ||
| 171 | #define I218_ULP_CONFIG1_STICKY_ULP 0x0010 /* Set sticky ULP mode */ | ||
| 172 | #define I218_ULP_CONFIG1_INBAND_EXIT 0x0020 /* Inband on ULP exit */ | ||
| 173 | #define I218_ULP_CONFIG1_WOL_HOST 0x0040 /* WoL Host on ULP exit */ | ||
| 174 | #define I218_ULP_CONFIG1_RESET_TO_SMBUS 0x0100 /* Reset to SMBus mode */ | ||
| 175 | #define I218_ULP_CONFIG1_DISABLE_SMB_PERST 0x1000 /* Disable on PERST# */ | ||
| 176 | |||
| 157 | /* SMBus Address Phy Register */ | 177 | /* SMBus Address Phy Register */ |
| 158 | #define HV_SMB_ADDR PHY_REG(768, 26) | 178 | #define HV_SMB_ADDR PHY_REG(768, 26) |
| 159 | #define HV_SMB_ADDR_MASK 0x007F | 179 | #define HV_SMB_ADDR_MASK 0x007F |
| @@ -188,6 +208,7 @@ | |||
| 188 | /* PHY Power Management Control */ | 208 | /* PHY Power Management Control */ |
| 189 | #define HV_PM_CTRL PHY_REG(770, 17) | 209 | #define HV_PM_CTRL PHY_REG(770, 17) |
| 190 | #define HV_PM_CTRL_PLL_STOP_IN_K1_GIGA 0x100 | 210 | #define HV_PM_CTRL_PLL_STOP_IN_K1_GIGA 0x100 |
| 211 | #define HV_PM_CTRL_K1_ENABLE 0x4000 | ||
| 191 | 212 | ||
| 192 | #define SW_FLAG_TIMEOUT 1000 /* SW Semaphore flag timeout in ms */ | 213 | #define SW_FLAG_TIMEOUT 1000 /* SW Semaphore flag timeout in ms */ |
| 193 | 214 | ||
| @@ -262,4 +283,5 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable); | |||
| 262 | s32 e1000_read_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 *data); | 283 | s32 e1000_read_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 *data); |
| 263 | s32 e1000_write_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 data); | 284 | s32 e1000_write_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 data); |
| 264 | s32 e1000_set_eee_pchlan(struct e1000_hw *hw); | 285 | s32 e1000_set_eee_pchlan(struct e1000_hw *hw); |
| 286 | s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx); | ||
| 265 | #endif /* _E1000E_ICH8LAN_H_ */ | 287 | #endif /* _E1000E_ICH8LAN_H_ */ |
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 7fd1feaeb405..5129c4cd14bc 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c | |||
| @@ -5856,7 +5856,7 @@ static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) | |||
| 5856 | static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc) | 5856 | static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc) |
| 5857 | { | 5857 | { |
| 5858 | struct e1000_hw *hw = &adapter->hw; | 5858 | struct e1000_hw *hw = &adapter->hw; |
| 5859 | u32 i, mac_reg; | 5859 | u32 i, mac_reg, wuc; |
| 5860 | u16 phy_reg, wuc_enable; | 5860 | u16 phy_reg, wuc_enable; |
| 5861 | int retval; | 5861 | int retval; |
| 5862 | 5862 | ||
| @@ -5903,13 +5903,18 @@ static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc) | |||
| 5903 | phy_reg |= BM_RCTL_RFCE; | 5903 | phy_reg |= BM_RCTL_RFCE; |
| 5904 | hw->phy.ops.write_reg_page(&adapter->hw, BM_RCTL, phy_reg); | 5904 | hw->phy.ops.write_reg_page(&adapter->hw, BM_RCTL, phy_reg); |
| 5905 | 5905 | ||
| 5906 | wuc = E1000_WUC_PME_EN; | ||
| 5907 | if (wufc & (E1000_WUFC_MAG | E1000_WUFC_LNKC)) | ||
| 5908 | wuc |= E1000_WUC_APME; | ||
| 5909 | |||
| 5906 | /* enable PHY wakeup in MAC register */ | 5910 | /* enable PHY wakeup in MAC register */ |
| 5907 | ew32(WUFC, wufc); | 5911 | ew32(WUFC, wufc); |
| 5908 | ew32(WUC, E1000_WUC_PHY_WAKE | E1000_WUC_PME_EN); | 5912 | ew32(WUC, (E1000_WUC_PHY_WAKE | E1000_WUC_APMPME | |
| 5913 | E1000_WUC_PME_STATUS | wuc)); | ||
| 5909 | 5914 | ||
| 5910 | /* configure and enable PHY wakeup in PHY registers */ | 5915 | /* configure and enable PHY wakeup in PHY registers */ |
| 5911 | hw->phy.ops.write_reg_page(&adapter->hw, BM_WUFC, wufc); | 5916 | hw->phy.ops.write_reg_page(&adapter->hw, BM_WUFC, wufc); |
| 5912 | hw->phy.ops.write_reg_page(&adapter->hw, BM_WUC, E1000_WUC_PME_EN); | 5917 | hw->phy.ops.write_reg_page(&adapter->hw, BM_WUC, wuc); |
| 5913 | 5918 | ||
| 5914 | /* activate PHY wakeup */ | 5919 | /* activate PHY wakeup */ |
| 5915 | wuc_enable |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT; | 5920 | wuc_enable |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT; |
| @@ -6012,8 +6017,19 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime) | |||
| 6012 | e1000_power_down_phy(adapter); | 6017 | e1000_power_down_phy(adapter); |
| 6013 | } | 6018 | } |
| 6014 | 6019 | ||
| 6015 | if (adapter->hw.phy.type == e1000_phy_igp_3) | 6020 | if (adapter->hw.phy.type == e1000_phy_igp_3) { |
| 6016 | e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw); | 6021 | e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw); |
| 6022 | } else if (hw->mac.type == e1000_pch_lpt) { | ||
| 6023 | if (!(wufc & (E1000_WUFC_EX | E1000_WUFC_MC | E1000_WUFC_BC))) | ||
| 6024 | /* ULP does not support wake from unicast, multicast | ||
| 6025 | * or broadcast. | ||
| 6026 | */ | ||
| 6027 | retval = e1000_enable_ulp_lpt_lp(hw, !runtime); | ||
| 6028 | |||
| 6029 | if (retval) | ||
| 6030 | return retval; | ||
| 6031 | } | ||
| 6032 | |||
| 6017 | 6033 | ||
| 6018 | /* Release control of h/w to f/w. If f/w is AMT enabled, this | 6034 | /* Release control of h/w to f/w. If f/w is AMT enabled, this |
| 6019 | * would have already happened in close and is redundant. | 6035 | * would have already happened in close and is redundant. |
diff --git a/drivers/net/ethernet/intel/e1000e/regs.h b/drivers/net/ethernet/intel/e1000e/regs.h index 5c55ef348fc2..ea235bbe50d3 100644 --- a/drivers/net/ethernet/intel/e1000e/regs.h +++ b/drivers/net/ethernet/intel/e1000e/regs.h | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #define E1000_SCTL 0x00024 /* SerDes Control - RW */ | 32 | #define E1000_SCTL 0x00024 /* SerDes Control - RW */ |
| 33 | #define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */ | 33 | #define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */ |
| 34 | #define E1000_FCAH 0x0002C /* Flow Control Address High -RW */ | 34 | #define E1000_FCAH 0x0002C /* Flow Control Address High -RW */ |
| 35 | #define E1000_FEXT 0x0002C /* Future Extended - RW */ | ||
| 35 | #define E1000_FEXTNVM 0x00028 /* Future Extended NVM - RW */ | 36 | #define E1000_FEXTNVM 0x00028 /* Future Extended NVM - RW */ |
| 36 | #define E1000_FEXTNVM3 0x0003C /* Future Extended NVM 3 - RW */ | 37 | #define E1000_FEXTNVM3 0x0003C /* Future Extended NVM 3 - RW */ |
| 37 | #define E1000_FEXTNVM4 0x00024 /* Future Extended NVM 4 - RW */ | 38 | #define E1000_FEXTNVM4 0x00024 /* Future Extended NVM 4 - RW */ |
