]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: iwlwifi: pcie: simplify the resume flow if fast resume is not used
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Sun, 31 May 2026 10:30:19 +0000 (13:30 +0300)
committerMiri Korenblit <miriam.rachel.korenblit@intel.com>
Sun, 31 May 2026 14:07:11 +0000 (17:07 +0300)
In most distributions, NetworkManager shuts the device down before
entering system suspend, so fast suspend is typically not used.

On older devices, resume currently tries to grab NIC access to infer
whether the device was powered off while suspended. That probe is only
meaningful for the fast-suspend path where the device is expected to
remain alive.

Unfortunately, for unclear reasons, grabbing NIC access was harmful as
reported in the bugzilla ticket below.

Workaround this issue by simply not grabbing NIC access if fast suspend
is not used.

Cc: stable@vger.kernel.org
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221501
Assisted-by: GitHub Copilot:gpt-5.3-codex
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Link: https://patch.msgid.link/20260531133005.e2ed9e0cd44f.If283625983a843933e0c01561a421daff184e9e9@changeid
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
drivers/net/wireless/intel/iwlwifi/pcie/drv.c

index dc99e7ac47261e647fac3ba1fb5babe5e5e31121..eb3c5a6dd08841d27dd2d0b77de6014e9a1145ff 100644 (file)
@@ -1225,33 +1225,41 @@ static int _iwl_pci_resume(struct device *device, bool restore)
        if (!trans->op_mode)
                return 0;
 
-       /*
-        * Scratch value was altered, this means the device was powered off, we
-        * need to reset it completely.
-        * Note: MAC (bits 0:7) will be cleared upon suspend even with wowlan,
-        * but not bits [15:8]. So if we have bits set in lower word, assume
-        * the device is alive.
-        * Alternatively, if the scratch value is 0xFFFFFFFF, then we no longer
-        * have access to the device and consider it powered off.
-        * For older devices, just try silently to grab the NIC.
-        */
-       if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) {
-               u32 scratch = iwl_read32(trans, CSR_FUNC_SCRATCH);
-
-               if (!(scratch & CSR_FUNC_SCRATCH_POWER_OFF_MASK) ||
-                   scratch == ~0U)
-                       device_was_powered_off = true;
-       } else {
+       if (test_bit(STATUS_DEVICE_ENABLED, &trans->status)) {
                /*
-                * bh are re-enabled by iwl_trans_pcie_release_nic_access,
-                * so re-enable them if _iwl_trans_pcie_grab_nic_access fails.
+                * Scratch value was altered, this means the device was powered
+                * off, we need to reset it completely.
+                * Note: MAC (bits 0:7) will be cleared upon suspend even with
+                * wowlan, but not bits [15:8]. So if we have bits set in lower
+                * word, assume the device is alive.
+                * Alternatively, if the scratch value is 0xFFFFFFFF, then we
+                * no longer have access to the device and consider it powered
+                * off.
+                * For older devices, just try silently to grab the NIC.
                 */
-               local_bh_disable();
-               if (_iwl_trans_pcie_grab_nic_access(trans, true)) {
-                       iwl_trans_pcie_release_nic_access(trans);
+               if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) {
+                       u32 scratch = iwl_read32(trans, CSR_FUNC_SCRATCH);
+
+                       if (!(scratch & CSR_FUNC_SCRATCH_POWER_OFF_MASK) ||
+                           scratch == ~0U) {
+                               IWL_DEBUG_WOWLAN(trans,
+                                                "Scratch 0x%08x indicates device was powered off\n",
+                                                scratch);
+                               device_was_powered_off = true;
+                       }
                } else {
-                       device_was_powered_off = true;
-                       local_bh_enable();
+                       /*
+                        * bh are re-enabled by iwl_trans_pcie_release_nic_access,
+                        * so re-enable them if _iwl_trans_pcie_grab_nic_access
+                        * fails.
+                        */
+                       local_bh_disable();
+                       if (_iwl_trans_pcie_grab_nic_access(trans, true)) {
+                               iwl_trans_pcie_release_nic_access(trans);
+                       } else {
+                               device_was_powered_off = true;
+                               local_bh_enable();
+                       }
                }
        }