wifi: iwlwifi: fix merge damage related to iwl_pci_resume
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Tue, 3 Jun 2025 09:17:54 +0000 (12:17 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 11 Jun 2025 09:27:21 +0000 (11:27 +0200)
The changes I made in
wifi: iwlwifi: don't warn if the NIC is gone in resume
conflicted with a major rework done in this area.
The merge de-facto removed my changes.
Re-add them.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Link: https://patch.msgid.link/20250603091754.70182-1-emmanuel.grumbach@intel.com
Fixes: 06c4b2036818 ("Merge tag 'iwlwifi-next-2025-05-15' of https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/intel/iwlwifi/pcie/drv.c

index 656f8b06c27b579b21e9db29dc0cde4721475eea..0a9e0dbb58fbf7826bc2599afe8b9efa51c7ac51 100644 (file)
@@ -1501,11 +1501,27 @@ static int _iwl_pci_resume(struct device *device, bool restore)
         * 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,
-        * so assume that any bits there mean that the device is usable.
+        * but not bits [15:8]. So if we have bits set in lower word, assume
+        * the device is alive.
+        * For older devices, just try silently to grab the NIC.
         */
-       if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ &&
-           !iwl_read32(trans, CSR_FUNC_SCRATCH))
-               device_was_powered_off = true;
+       if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) {
+               if (!(iwl_read32(trans, CSR_FUNC_SCRATCH) &
+                     CSR_FUNC_SCRATCH_POWER_OFF_MASK))
+                       device_was_powered_off = true;
+       } else {
+               /*
+                * 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();
+               }
+       }
 
        if (restore || device_was_powered_off) {
                trans->state = IWL_TRANS_NO_FW;