Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

e1000e: change usleep_range to udelay in PHY mdic access

This is a partial revert of commit 6dbdd4de0362 ("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: 6dbdd4de0362 ("e1000e: Workaround for sporadic MDI error on Meteor Lake systems")
Cc: stable@vger.kernel.org
Reported-by: Jé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: Sasha Neftin <sasha.neftin@intel.com>
Signed-off-by: Sasha Neftin <sasha.neftin@intel.com>
Signed-off-by: Vitaly Lifshits <vitaly.lifshits@intel.com>
Tested-by: Dima Ruinskiy <dima.ruinskiy@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://lore.kernel.org/r/20240429171040.1152516-1-anthony.l.nguyen@intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Vitaly Lifshits and committed by
Jakub Kicinski
387f295c b9a61c20

+4 -4
+4 -4
drivers/net/ethernet/intel/e1000e/phy.c
··· 157 157 * the lower time out 158 158 */ 159 159 for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) { 160 - usleep_range(50, 60); 160 + udelay(50); 161 161 mdic = er32(MDIC); 162 162 if (mdic & E1000_MDIC_READY) 163 163 break; ··· 181 181 * reading duplicate data in the next MDIC transaction. 182 182 */ 183 183 if (hw->mac.type == e1000_pch2lan) 184 - usleep_range(100, 150); 184 + udelay(100); 185 185 186 186 if (success) { 187 187 *data = (u16)mdic; ··· 237 237 * the lower time out 238 238 */ 239 239 for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) { 240 - usleep_range(50, 60); 240 + udelay(50); 241 241 mdic = er32(MDIC); 242 242 if (mdic & E1000_MDIC_READY) 243 243 break; ··· 261 261 * reading duplicate data in the next MDIC transaction. 262 262 */ 263 263 if (hw->mac.type == e1000_pch2lan) 264 - usleep_range(100, 150); 264 + udelay(100); 265 265 266 266 if (success) 267 267 return 0;