summaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorYanir Lubetkin <yanirx.lubetkin@intel.com>2015-06-09 18:15:55 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2015-06-26 05:42:24 -0400
commit6607c99e7034e7565a1559a24dd35083d6719788 (patch)
tree09109e7e1ad07015630cad19b3b0cf6d09deaf8a /drivers/net
parentbeee8072c39cee74d4ff6e3b4ca8942f9966ed2e (diff)
e1000e: i219 - fix to enable both ULP and EEE in Sx state
In i219, there is a hardware bug that prevented ULP entry. A side effect of the original software fix for this was that EEE in Sx couldn't be enabled. This patch implements a modified flow that allows both ULP and EEE in Sx. Signed-off-by: Yanir Lubetkin <yanirx.lubetkin@intel.com> Tested-by: Aaron Brown <aaron.f.brown@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/intel/e1000e/ich8lan.c45
1 files changed, 32 insertions, 13 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c
index c742a4f5dc83..c5bb1dd8a18e 100644
--- a/drivers/net/ethernet/intel/e1000e/ich8lan.c
+++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c
@@ -1089,6 +1089,7 @@ s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx)
1089 u32 mac_reg; 1089 u32 mac_reg;
1090 s32 ret_val = 0; 1090 s32 ret_val = 0;
1091 u16 phy_reg; 1091 u16 phy_reg;
1092 u16 oem_reg = 0;
1092 1093
1093 if ((hw->mac.type < e1000_pch_lpt) || 1094 if ((hw->mac.type < e1000_pch_lpt) ||
1094 (hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPT_I217_LM) || 1095 (hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPT_I217_LM) ||
@@ -1130,33 +1131,37 @@ s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx)
1130 if (ret_val) 1131 if (ret_val)
1131 goto out; 1132 goto out;
1132 1133
1134 /* Force SMBus mode in PHY */
1135 ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &phy_reg);
1136 if (ret_val)
1137 goto release;
1138 phy_reg |= CV_SMB_CTRL_FORCE_SMBUS;
1139 e1000_write_phy_reg_hv_locked(hw, CV_SMB_CTRL, phy_reg);
1140
1141 /* Force SMBus mode in MAC */
1142 mac_reg = er32(CTRL_EXT);
1143 mac_reg |= E1000_CTRL_EXT_FORCE_SMBUS;
1144 ew32(CTRL_EXT, mac_reg);
1145
1133 /* Si workaround for ULP entry flow on i127/rev6 h/w. Enable 1146 /* Si workaround for ULP entry flow on i127/rev6 h/w. Enable
1134 * LPLU and disable Gig speed when entering ULP 1147 * LPLU and disable Gig speed when entering ULP
1135 */ 1148 */
1136 if ((hw->phy.type == e1000_phy_i217) && (hw->phy.revision == 6)) { 1149 if ((hw->phy.type == e1000_phy_i217) && (hw->phy.revision == 6)) {
1137 ret_val = e1000_read_phy_reg_hv_locked(hw, HV_OEM_BITS, 1150 ret_val = e1000_read_phy_reg_hv_locked(hw, HV_OEM_BITS,
1138 &phy_reg); 1151 &oem_reg);
1139 if (ret_val) 1152 if (ret_val)
1140 goto release; 1153 goto release;
1154
1155 phy_reg = oem_reg;
1141 phy_reg |= HV_OEM_BITS_LPLU | HV_OEM_BITS_GBE_DIS; 1156 phy_reg |= HV_OEM_BITS_LPLU | HV_OEM_BITS_GBE_DIS;
1157
1142 ret_val = e1000_write_phy_reg_hv_locked(hw, HV_OEM_BITS, 1158 ret_val = e1000_write_phy_reg_hv_locked(hw, HV_OEM_BITS,
1143 phy_reg); 1159 phy_reg);
1160
1144 if (ret_val) 1161 if (ret_val)
1145 goto release; 1162 goto release;
1146 } 1163 }
1147 1164
1148 /* Force SMBus mode in PHY */
1149 ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &phy_reg);
1150 if (ret_val)
1151 goto release;
1152 phy_reg |= CV_SMB_CTRL_FORCE_SMBUS;
1153 e1000_write_phy_reg_hv_locked(hw, CV_SMB_CTRL, phy_reg);
1154
1155 /* Force SMBus mode in MAC */
1156 mac_reg = er32(CTRL_EXT);
1157 mac_reg |= E1000_CTRL_EXT_FORCE_SMBUS;
1158 ew32(CTRL_EXT, mac_reg);
1159
1160 /* Set Inband ULP Exit, Reset to SMBus mode and 1165 /* Set Inband ULP Exit, Reset to SMBus mode and
1161 * Disable SMBus Release on PERST# in PHY 1166 * Disable SMBus Release on PERST# in PHY
1162 */ 1167 */
@@ -1168,10 +1173,15 @@ s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx)
1168 if (to_sx) { 1173 if (to_sx) {
1169 if (er32(WUFC) & E1000_WUFC_LNKC) 1174 if (er32(WUFC) & E1000_WUFC_LNKC)
1170 phy_reg |= I218_ULP_CONFIG1_WOL_HOST; 1175 phy_reg |= I218_ULP_CONFIG1_WOL_HOST;
1176 else
1177 phy_reg &= ~I218_ULP_CONFIG1_WOL_HOST;
1171 1178
1172 phy_reg |= I218_ULP_CONFIG1_STICKY_ULP; 1179 phy_reg |= I218_ULP_CONFIG1_STICKY_ULP;
1180 phy_reg &= ~I218_ULP_CONFIG1_INBAND_EXIT;
1173 } else { 1181 } else {
1174 phy_reg |= I218_ULP_CONFIG1_INBAND_EXIT; 1182 phy_reg |= I218_ULP_CONFIG1_INBAND_EXIT;
1183 phy_reg &= ~I218_ULP_CONFIG1_STICKY_ULP;
1184 phy_reg &= ~I218_ULP_CONFIG1_WOL_HOST;
1175 } 1185 }
1176 e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg); 1186 e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg);
1177 1187
@@ -1183,6 +1193,15 @@ s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx)
1183 /* Commit ULP changes in PHY by starting auto ULP configuration */ 1193 /* Commit ULP changes in PHY by starting auto ULP configuration */
1184 phy_reg |= I218_ULP_CONFIG1_START; 1194 phy_reg |= I218_ULP_CONFIG1_START;
1185 e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg); 1195 e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg);
1196
1197 if ((hw->phy.type == e1000_phy_i217) && (hw->phy.revision == 6) &&
1198 to_sx && (er32(STATUS) & E1000_STATUS_LU)) {
1199 ret_val = e1000_write_phy_reg_hv_locked(hw, HV_OEM_BITS,
1200 oem_reg);
1201 if (ret_val)
1202 goto release;
1203 }
1204
1186release: 1205release:
1187 hw->phy.ops.release(hw); 1206 hw->phy.ops.release(hw);
1188out: 1207out: