Skip to content

Commit e6fc67c

Browse files
vlifshtsgregkh
authored andcommitted
e1000e: fix force smbus during suspend flow
commit 76a0a3f upstream. Commit 861e808 ("e1000e: move force SMBUS from enable ulp function to avoid PHY loss issue") resolved a PHY access loss during suspend on Meteor Lake consumer platforms, but it affected corporate systems incorrectly. A better fix, working for both consumer and corporate systems, was proposed in commit bfd546a ("e1000e: move force SMBUS near the end of enable_ulp function"). However, it introduced a regression on older devices, such as [8086:15B8], [8086:15F9], [8086:15BE]. This patch aims to fix the secondary regression, by limiting the scope of the changes to Meteor Lake platforms only. Fixes: bfd546a ("e1000e: move force SMBUS near the end of enable_ulp function") Reported-by: Todd Brandt <[email protected]> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218940 Reported-by: Dieter Mummenschanz <[email protected]> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218936 Signed-off-by: Vitaly Lifshits <[email protected]> Tested-by: Mor Bar-Gabay <[email protected]> (A Contingent Worker at Intel) Signed-off-by: Tony Nguyen <[email protected]> Reviewed-by: Simon Horman <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 611f74b commit e6fc67c

File tree

1 file changed

+53
-20
lines changed

1 file changed

+53
-20
lines changed

drivers/net/ethernet/intel/e1000e/ich8lan.c

Lines changed: 53 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,6 +1108,46 @@ static s32 e1000_platform_pm_pch_lpt(struct e1000_hw *hw, bool link)
11081108
return 0;
11091109
}
11101110

1111+
/**
1112+
* e1000e_force_smbus - Force interfaces to transition to SMBUS mode.
1113+
* @hw: pointer to the HW structure
1114+
*
1115+
* Force the MAC and the PHY to SMBUS mode. Assumes semaphore already
1116+
* acquired.
1117+
*
1118+
* Return: 0 on success, negative errno on failure.
1119+
**/
1120+
static s32 e1000e_force_smbus(struct e1000_hw *hw)
1121+
{
1122+
u16 smb_ctrl = 0;
1123+
u32 ctrl_ext;
1124+
s32 ret_val;
1125+
1126+
/* Switching PHY interface always returns MDI error
1127+
* so disable retry mechanism to avoid wasting time
1128+
*/
1129+
e1000e_disable_phy_retry(hw);
1130+
1131+
/* Force SMBus mode in the PHY */
1132+
ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &smb_ctrl);
1133+
if (ret_val) {
1134+
e1000e_enable_phy_retry(hw);
1135+
return ret_val;
1136+
}
1137+
1138+
smb_ctrl |= CV_SMB_CTRL_FORCE_SMBUS;
1139+
e1000_write_phy_reg_hv_locked(hw, CV_SMB_CTRL, smb_ctrl);
1140+
1141+
e1000e_enable_phy_retry(hw);
1142+
1143+
/* Force SMBus mode in the MAC */
1144+
ctrl_ext = er32(CTRL_EXT);
1145+
ctrl_ext |= E1000_CTRL_EXT_FORCE_SMBUS;
1146+
ew32(CTRL_EXT, ctrl_ext);
1147+
1148+
return 0;
1149+
}
1150+
11111151
/**
11121152
* e1000_enable_ulp_lpt_lp - configure Ultra Low Power mode for LynxPoint-LP
11131153
* @hw: pointer to the HW structure
@@ -1165,6 +1205,14 @@ s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx)
11651205
if (ret_val)
11661206
goto out;
11671207

1208+
if (hw->mac.type != e1000_pch_mtp) {
1209+
ret_val = e1000e_force_smbus(hw);
1210+
if (ret_val) {
1211+
e_dbg("Failed to force SMBUS: %d\n", ret_val);
1212+
goto release;
1213+
}
1214+
}
1215+
11681216
/* Si workaround for ULP entry flow on i127/rev6 h/w. Enable
11691217
* LPLU and disable Gig speed when entering ULP
11701218
*/
@@ -1225,27 +1273,12 @@ s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx)
12251273
}
12261274

12271275
release:
1228-
/* Switching PHY interface always returns MDI error
1229-
* so disable retry mechanism to avoid wasting time
1230-
*/
1231-
e1000e_disable_phy_retry(hw);
1232-
1233-
/* Force SMBus mode in PHY */
1234-
ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &phy_reg);
1235-
if (ret_val) {
1236-
e1000e_enable_phy_retry(hw);
1237-
hw->phy.ops.release(hw);
1238-
goto out;
1276+
if (hw->mac.type == e1000_pch_mtp) {
1277+
ret_val = e1000e_force_smbus(hw);
1278+
if (ret_val)
1279+
e_dbg("Failed to force SMBUS over MTL system: %d\n",
1280+
ret_val);
12391281
}
1240-
phy_reg |= CV_SMB_CTRL_FORCE_SMBUS;
1241-
e1000_write_phy_reg_hv_locked(hw, CV_SMB_CTRL, phy_reg);
1242-
1243-
e1000e_enable_phy_retry(hw);
1244-
1245-
/* Force SMBus mode in MAC */
1246-
mac_reg = er32(CTRL_EXT);
1247-
mac_reg |= E1000_CTRL_EXT_FORCE_SMBUS;
1248-
ew32(CTRL_EXT, mac_reg);
12491282

12501283
hw->phy.ops.release(hw);
12511284
out:

0 commit comments

Comments
 (0)