]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: iwlwifi: fix the check for the SCRATCH register upon resume
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Sun, 20 Apr 2025 07:00:01 +0000 (10:00 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 23 Apr 2025 12:45:29 +0000 (14:45 +0200)
We can't rely on the SCRATCH register being 0 on platform that power
gate the NIC in S3. Even in those platforms, the SCRATCH register is
still returning 0x1010000.

Make sure that we understand that those platforms have powered off the
device.

Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219597
Fixes: cb347bd29d0d ("wifi: iwlwifi: mvm: fix hibernation")
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20250420095642.a7e082ee785c.I9418d76f860f54261cfa89e1f7ac10300904ba40@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/intel/iwlwifi/iwl-csr.h
drivers/net/wireless/intel/iwlwifi/pcie/drv.c

index be9e464c9b7b0822390b0b23dbe91332431d5757..3ff493e920d28410e2900f56139290e64f195a44 100644 (file)
  * during a error FW error.
  */
 #define CSR_FUNC_SCRATCH_INIT_VALUE            (0x01010101)
+#define CSR_FUNC_SCRATCH_POWER_OFF_MASK                0xFFFF
 
 /* Bits for CSR_HW_IF_CONFIG_REG */
 #define CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP_DASH (0x0000000F)
index 3a605e7c070e43f3c16d3d1defeec75be3cc01fd..debeea2b3ae5771ef705987e89f2e3e42dc91cb3 100644 (file)
@@ -1736,11 +1736,13 @@ 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->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) {
-               if (!iwl_read32(trans, CSR_FUNC_SCRATCH))
+               if (!(iwl_read32(trans, CSR_FUNC_SCRATCH) &
+                     CSR_FUNC_SCRATCH_POWER_OFF_MASK))
                        device_was_powered_off = true;
        } else {
                /*