]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
wifi: iwlwifi: be less noisy if the NIC is dead in S3
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Mon, 23 Dec 2024 12:13:59 +0000 (14:13 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 2 Jan 2025 09:34:20 +0000 (10:34 +0100)
commit 0572b7715ffd2cac20aac00333706f3094028180 upstream

If the NIC is dead upon resume, try to catch the error earlier and exit
earlier. We'll print less error messages and get to the same recovery
path as before: reload the firmware.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20241028135215.3a18682261e5.I18f336a4537378a4c1a8537d7246cee1fc82b42c@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219597
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/wireless/intel/iwlwifi/iwl-trans.h
drivers/net/wireless/intel/iwlwifi/mvm/d3.c
drivers/net/wireless/intel/iwlwifi/pcie/trans.c

index e95ffe3035473cbe45584cb3363bb48a77056a8e..c70da7281551a2b8e3e1344ed215ed516123f1e0 100644 (file)
@@ -1074,12 +1074,13 @@ int iwl_trans_read_config32(struct iwl_trans *trans, u32 ofs,
 void iwl_trans_debugfs_cleanup(struct iwl_trans *trans);
 #endif
 
-#define iwl_trans_read_mem_bytes(trans, addr, buf, bufsize)                  \
-       do {                                                                  \
-               if (__builtin_constant_p(bufsize))                            \
-                       BUILD_BUG_ON((bufsize) % sizeof(u32));                \
-               iwl_trans_read_mem(trans, addr, buf, (bufsize) / sizeof(u32));\
-       } while (0)
+#define iwl_trans_read_mem_bytes(trans, addr, buf, bufsize)    \
+       ({                                                      \
+               if (__builtin_constant_p(bufsize))              \
+                       BUILD_BUG_ON((bufsize) % sizeof(u32));  \
+               iwl_trans_read_mem(trans, addr, buf,            \
+                                  (bufsize) / sizeof(u32));    \
+       })
 
 int iwl_trans_write_imr_mem(struct iwl_trans *trans, u32 dst_addr,
                            u64 src_addr, u32 byte_cnt);
index 244ca8cab9d1a239b7936b46fa58904ebf2ed4b3..1a814eb6743e807310b2039f36650f6644539381 100644 (file)
@@ -3032,13 +3032,18 @@ static bool iwl_mvm_rt_status(struct iwl_trans *trans, u32 base, u32 *err_id)
                /* cf. struct iwl_error_event_table */
                u32 valid;
                __le32 err_id;
-       } err_info;
+       } err_info = {};
+       int ret;
 
        if (!base)
                return false;
 
-       iwl_trans_read_mem_bytes(trans, base,
-                                &err_info, sizeof(err_info));
+       ret = iwl_trans_read_mem_bytes(trans, base,
+                                      &err_info, sizeof(err_info));
+
+       if (ret)
+               return true;
+
        if (err_info.valid && err_id)
                *err_id = le32_to_cpu(err_info.err_id);
 
@@ -3635,22 +3640,31 @@ int iwl_mvm_fast_resume(struct iwl_mvm *mvm)
        iwl_fw_dbg_read_d3_debug_data(&mvm->fwrt);
 
        if (iwl_mvm_check_rt_status(mvm, NULL)) {
+               IWL_ERR(mvm,
+                       "iwl_mvm_check_rt_status failed, device is gone during suspend\n");
                set_bit(STATUS_FW_ERROR, &mvm->trans->status);
                iwl_mvm_dump_nic_error_log(mvm);
                iwl_dbg_tlv_time_point(&mvm->fwrt,
                                       IWL_FW_INI_TIME_POINT_FW_ASSERT, NULL);
                iwl_fw_dbg_collect_desc(&mvm->fwrt, &iwl_dump_desc_assert,
                                        false, 0);
-               return -ENODEV;
+               mvm->trans->state = IWL_TRANS_NO_FW;
+               ret = -ENODEV;
+
+               goto out;
        }
        ret = iwl_mvm_d3_notif_wait(mvm, &d3_data);
+
+       if (ret) {
+               IWL_ERR(mvm, "Couldn't get the d3 notif %d\n", ret);
+               mvm->trans->state = IWL_TRANS_NO_FW;
+       }
+
+out:
        clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status);
        mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED;
        mvm->fast_resume = false;
 
-       if (ret)
-               IWL_ERR(mvm, "Couldn't get the d3 notif %d\n", ret);
-
        return ret;
 }
 
index 3b9943eb69341ef19061fd4f7c64d36503768558..d19b3bd0866bda559b95f289f5259f156368ea04 100644 (file)
@@ -1643,6 +1643,8 @@ int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
 out:
        if (*status == IWL_D3_STATUS_ALIVE)
                ret = iwl_pcie_d3_handshake(trans, false);
+       else
+               trans->state = IWL_TRANS_NO_FW;
 
        return ret;
 }