Commit 387f295c authored by Vitaly Lifshits's avatar Vitaly Lifshits Committed by Jakub Kicinski
Browse files

e1000e: change usleep_range to udelay in PHY mdic access



This is a partial revert of commit 6dbdd4de ("e1000e: Workaround
for sporadic MDI error on Meteor Lake systems"). The referenced commit
used usleep_range inside the PHY access routines, which are sometimes
called from an atomic context. This can lead to a kernel panic in some
scenarios, such as cable disconnection and reconnection on vPro systems.

Solve this by changing the usleep_range calls back to udelay.

Fixes: 6dbdd4de ("e1000e: Workaround for sporadic MDI error on Meteor Lake systems")
Cc: stable@vger.kernel.org
Reported-by: default avatarJérôme Carretero <cJ@zougloub.eu>
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218740
Closes: https://lore.kernel.org/lkml/a7eb665c74b5efb5140e6979759ed243072cb24a.camel@zougloub.eu/


Co-developed-by: default avatarSasha Neftin <sasha.neftin@intel.com>
Signed-off-by: default avatarSasha Neftin <sasha.neftin@intel.com>
Signed-off-by: default avatarVitaly Lifshits <vitaly.lifshits@intel.com>
Tested-by: default avatarDima Ruinskiy <dima.ruinskiy@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Link: https://lore.kernel.org/r/20240429171040.1152516-1-anthony.l.nguyen@intel.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent b9a61c20
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -157,7 +157,7 @@ s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
		 * the lower time out
		 */
		for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
			usleep_range(50, 60);
			udelay(50);
			mdic = er32(MDIC);
			if (mdic & E1000_MDIC_READY)
				break;
@@ -181,7 +181,7 @@ s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
		 * reading duplicate data in the next MDIC transaction.
		 */
		if (hw->mac.type == e1000_pch2lan)
			usleep_range(100, 150);
			udelay(100);

		if (success) {
			*data = (u16)mdic;
@@ -237,7 +237,7 @@ s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
		 * the lower time out
		 */
		for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
			usleep_range(50, 60);
			udelay(50);
			mdic = er32(MDIC);
			if (mdic & E1000_MDIC_READY)
				break;
@@ -261,7 +261,7 @@ s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
		 * reading duplicate data in the next MDIC transaction.
		 */
		if (hw->mac.type == e1000_pch2lan)
			usleep_range(100, 150);
			udelay(100);

		if (success)
			return 0;