#define E1000_FWSM_WLOCK_MAC_MASK      0x0380
 #define E1000_FWSM_WLOCK_MAC_SHIFT     7
 #define E1000_FWSM_ULP_CFG_DONE                0x00000400      /* Low power cfg done */
+#define E1000_EXFWSM_DPG_EXIT_DONE     0x00000001
 
 /* Shared Receive Address Registers */
 #define E1000_SHRAL_PCH_LPT(_i)                (0x05408 + ((_i) * 8))
 
 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 */
                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 */
 
 
 #define E1000_FACTPS   0x05B30 /* Function Active and Power State to MNG */
 #define E1000_SWSM     0x05B50 /* SW Semaphore */
 #define E1000_FWSM     0x05B54 /* FW Semaphore */
+#define E1000_EXFWSM   0x05B58 /* Extended FW Semaphore */
 /* Driver-only SW semaphore (not used by BOOT agents) */
 #define E1000_SWSM2    0x05B58
 #define E1000_FFLT_DBG 0x05F04 /* Debug Register */