summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/intel/e1000e/netdev.c
diff options
context:
space:
mode:
authorSasha Neftin <sasha.neftin@intel.com>2021-06-24 11:18:46 +0300
committerTony Nguyen <anthony.l.nguyen@intel.com>2021-07-20 16:11:36 -0700
commitef407b86d3cc7ab7ad37658c1c7a094cb8f3b6b4 (patch)
treefb451d854474c4fcedb2cfdb0817a2ebe10da891 /drivers/net/ethernet/intel/e1000e/netdev.c
parent3e55d231716ea361b1520b801c6778c4c48de102 (diff)
e1000e: Add polling mechanism to indicate CSME DPG exit
Per guidance from the CSME architecture team, it may take up to 1 second for unconfiguring dynamic power gating mode. Practically it can take more time. Wait up to 2.5 seconds to indicate dynamic power gating exit from the S0ix configuration. Detect scenarios that take more than 1 second but less than 2.5 seconds will emit warning message. Signed-off-by: Sasha Neftin <sasha.neftin@intel.com> Tested-by: Dvora Fuxbrumer <dvorax.fuxbrumer@linux.intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/e1000e/netdev.c')
-rw-r--r--drivers/net/ethernet/intel/e1000e/netdev.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index 4fa6f9f7d199..27107a927455 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -6481,8 +6481,10 @@ static void e1000e_s0ix_entry_flow(struct e1000_adapter *adapter)
static void e1000e_s0ix_exit_flow(struct e1000_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
+ bool firmware_bug = false;
u32 mac_data;
u16 phy_data;
+ u32 i = 0;
if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID) {
/* Request ME unconfigure the device from S0ix */
@@ -6490,6 +6492,28 @@ static void e1000e_s0ix_exit_flow(struct e1000_adapter *adapter)
mac_data &= ~E1000_H2ME_START_DPG;
mac_data |= E1000_H2ME_EXIT_DPG;
ew32(H2ME, mac_data);
+
+ /* Poll up to 2.5 seconds for ME to unconfigure DPG.
+ * If this takes more than 1 second, show a warning indicating a
+ * firmware bug
+ */
+ while (!(er32(EXFWSM) & E1000_EXFWSM_DPG_EXIT_DONE)) {
+ if (i > 100 && !firmware_bug)
+ firmware_bug = true;
+
+ if (i++ == 250) {
+ e_dbg("Timeout (firmware bug): %d msec\n",
+ i * 10);
+ break;
+ }
+
+ usleep_range(10000, 11000);
+ }
+ if (firmware_bug)
+ e_warn("DPG_EXIT_DONE took %d msec. This is a firmware bug\n",
+ i * 10);
+ else
+ e_dbg("DPG_EXIT_DONE cleared after %d msec\n", i * 10);
} else {
/* Request driver unconfigure the device from S0ix */