mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-16 19:04:41 +08: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
@ -1089,6 +1089,7 @@ s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx)
|
||||
u32 mac_reg;
|
||||
s32 ret_val = 0;
|
||||
u16 phy_reg;
|
||||
u16 oem_reg = 0;
|
||||
|
||||
if ((hw->mac.type < e1000_pch_lpt) ||
|
||||
(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)
|
||||
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 */
|
||||
ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &phy_reg);
|
||||
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;
|
||||
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
|
||||
* 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 (er32(WUFC) & E1000_WUFC_LNKC)
|
||||
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_INBAND_EXIT;
|
||||
} else {
|
||||
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);
|
||||
|
||||
@ -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 */
|
||||
phy_reg |= I218_ULP_CONFIG1_START;
|
||||
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:
|
||||
hw->phy.ops.release(hw);
|
||||
out:
|
||||
|
Loading…
Reference in New Issue
Block a user