]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
e1000e: clear DPG_EN after reset to avoid autonomous power-gating
authorVitaly Lifshits <vitaly.lifshits@intel.com>
Tue, 6 Jan 2026 14:14:20 +0000 (16:14 +0200)
committerTony Nguyen <anthony.l.nguyen@intel.com>
Wed, 25 Feb 2026 19:43:57 +0000 (11:43 -0800)
Panther Lake systems introduced an autonomous power gating feature for
the integrated Gigabit Ethernet in shutdown state (S5) state. As part of
it, the reset value of DPG_EN bit was changed to 1. Clear this bit after
performing hardware reset to avoid errors such as Tx/Rx hangs, or packet
loss/corruption.

Fixes: 0c9183ce61bc ("e1000e: Add support for the next LOM generation")
Signed-off-by: Vitaly Lifshits <vitaly.lifshits@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Tested-by: Avigail Dahan <avigailx.dahan@intel.com>
Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
drivers/net/ethernet/intel/e1000e/defines.h
drivers/net/ethernet/intel/e1000e/ich8lan.c

index ba331899d1861b337af9bb4bd3e230d34bd08ba2..d4a1041e456dcde795611fea1d6d5f8ad277053a 100644 (file)
@@ -33,6 +33,7 @@
 
 /* Extended Device Control */
 #define E1000_CTRL_EXT_LPCD  0x00000004     /* LCD Power Cycle Done */
+#define E1000_CTRL_EXT_DPG_EN  0x00000008 /* Dynamic Power Gating Enable */
 #define E1000_CTRL_EXT_SDP3_DATA 0x00000080 /* Value of SW Definable Pin 3 */
 #define E1000_CTRL_EXT_FORCE_SMBUS 0x00000800 /* Force SMBus mode */
 #define E1000_CTRL_EXT_EE_RST    0x00002000 /* Reinitialize from EEPROM */
index 23421a640097dd9fa66d03dbac9a3ea64d5ea538..dea208db1be5bf975a66e0b8e1bef8a07a45a309 100644 (file)
@@ -4932,6 +4932,15 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
        reg |= E1000_KABGTXD_BGSQLBIAS;
        ew32(KABGTXD, reg);
 
+       /* The hardware reset value of the DPG_EN bit is 1.
+        * Clear DPG_EN to prevent unexpected autonomous power gating.
+        */
+       if (hw->mac.type >= e1000_pch_ptp) {
+               reg = er32(CTRL_EXT);
+               reg &= ~E1000_CTRL_EXT_DPG_EN;
+               ew32(CTRL_EXT, reg);
+       }
+
        return 0;
 }