mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-05-24 10:39:52 +00:00
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>
This commit is contained in:
parent
beee8072c3
commit
6607c99e70
1 changed files with 34 additions and 15 deletions
|
@ -1089,6 +1089,7 @@ s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx)
|
||||||
u32 mac_reg;
|
u32 mac_reg;
|
||||||
s32 ret_val = 0;
|
s32 ret_val = 0;
|
||||||
u16 phy_reg;
|
u16 phy_reg;
|
||||||
|
u16 oem_reg = 0;
|
||||||
|
|
||||||
if ((hw->mac.type < e1000_pch_lpt) ||
|
if ((hw->mac.type < e1000_pch_lpt) ||
|
||||||
(hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPT_I217_LM) ||
|
(hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPT_I217_LM) ||
|
||||||
|
@ -1130,21 +1131,6 @@ s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx)
|
||||||
if (ret_val)
|
if (ret_val)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* Si workaround for ULP entry flow on i127/rev6 h/w. Enable
|
|
||||||
* LPLU and disable Gig speed when entering ULP
|
|
||||||
*/
|
|
||||||
if ((hw->phy.type == e1000_phy_i217) && (hw->phy.revision == 6)) {
|
|
||||||
ret_val = e1000_read_phy_reg_hv_locked(hw, HV_OEM_BITS,
|
|
||||||
&phy_reg);
|
|
||||||
if (ret_val)
|
|
||||||
goto release;
|
|
||||||
phy_reg |= HV_OEM_BITS_LPLU | HV_OEM_BITS_GBE_DIS;
|
|
||||||
ret_val = e1000_write_phy_reg_hv_locked(hw, HV_OEM_BITS,
|
|
||||||
phy_reg);
|
|
||||||
if (ret_val)
|
|
||||||
goto release;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Force SMBus mode in PHY */
|
/* Force SMBus mode in PHY */
|
||||||
ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &phy_reg);
|
ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &phy_reg);
|
||||||
if (ret_val)
|
if (ret_val)
|
||||||
|
@ -1157,6 +1143,25 @@ s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx)
|
||||||
mac_reg |= E1000_CTRL_EXT_FORCE_SMBUS;
|
mac_reg |= E1000_CTRL_EXT_FORCE_SMBUS;
|
||||||
ew32(CTRL_EXT, mac_reg);
|
ew32(CTRL_EXT, mac_reg);
|
||||||
|
|
||||||
|
/* Si workaround for ULP entry flow on i127/rev6 h/w. Enable
|
||||||
|
* LPLU and disable Gig speed when entering ULP
|
||||||
|
*/
|
||||||
|
if ((hw->phy.type == e1000_phy_i217) && (hw->phy.revision == 6)) {
|
||||||
|
ret_val = e1000_read_phy_reg_hv_locked(hw, HV_OEM_BITS,
|
||||||
|
&oem_reg);
|
||||||
|
if (ret_val)
|
||||||
|
goto release;
|
||||||
|
|
||||||
|
phy_reg = oem_reg;
|
||||||
|
phy_reg |= HV_OEM_BITS_LPLU | HV_OEM_BITS_GBE_DIS;
|
||||||
|
|
||||||
|
ret_val = e1000_write_phy_reg_hv_locked(hw, HV_OEM_BITS,
|
||||||
|
phy_reg);
|
||||||
|
|
||||||
|
if (ret_val)
|
||||||
|
goto release;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set Inband ULP Exit, Reset to SMBus mode and
|
/* Set Inband ULP Exit, Reset to SMBus mode and
|
||||||
* Disable SMBus Release on PERST# in PHY
|
* Disable SMBus Release on PERST# in PHY
|
||||||
*/
|
*/
|
||||||
|
@ -1168,10 +1173,15 @@ s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx)
|
||||||
if (to_sx) {
|
if (to_sx) {
|
||||||
if (er32(WUFC) & E1000_WUFC_LNKC)
|
if (er32(WUFC) & E1000_WUFC_LNKC)
|
||||||
phy_reg |= I218_ULP_CONFIG1_WOL_HOST;
|
phy_reg |= I218_ULP_CONFIG1_WOL_HOST;
|
||||||
|
else
|
||||||
|
phy_reg &= ~I218_ULP_CONFIG1_WOL_HOST;
|
||||||
|
|
||||||
phy_reg |= I218_ULP_CONFIG1_STICKY_ULP;
|
phy_reg |= I218_ULP_CONFIG1_STICKY_ULP;
|
||||||
|
phy_reg &= ~I218_ULP_CONFIG1_INBAND_EXIT;
|
||||||
} else {
|
} else {
|
||||||
phy_reg |= I218_ULP_CONFIG1_INBAND_EXIT;
|
phy_reg |= I218_ULP_CONFIG1_INBAND_EXIT;
|
||||||
|
phy_reg &= ~I218_ULP_CONFIG1_STICKY_ULP;
|
||||||
|
phy_reg &= ~I218_ULP_CONFIG1_WOL_HOST;
|
||||||
}
|
}
|
||||||
e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg);
|
e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg);
|
||||||
|
|
||||||
|
@ -1183,6 +1193,15 @@ s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx)
|
||||||
/* Commit ULP changes in PHY by starting auto ULP configuration */
|
/* Commit ULP changes in PHY by starting auto ULP configuration */
|
||||||
phy_reg |= I218_ULP_CONFIG1_START;
|
phy_reg |= I218_ULP_CONFIG1_START;
|
||||||
e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg);
|
e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg);
|
||||||
|
|
||||||
|
if ((hw->phy.type == e1000_phy_i217) && (hw->phy.revision == 6) &&
|
||||||
|
to_sx && (er32(STATUS) & E1000_STATUS_LU)) {
|
||||||
|
ret_val = e1000_write_phy_reg_hv_locked(hw, HV_OEM_BITS,
|
||||||
|
oem_reg);
|
||||||
|
if (ret_val)
|
||||||
|
goto release;
|
||||||
|
}
|
||||||
|
|
||||||
release:
|
release:
|
||||||
hw->phy.ops.release(hw);
|
hw->phy.ops.release(hw);
|
||||||
out:
|
out:
|
||||||
|
|
Loading…
Add table
Reference in a new issue