]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: iwlwifi: be less noisy if the NIC is dead in S3
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Mon, 28 Oct 2024 11:54:55 +0000 (13:54 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Thu, 7 Nov 2024 13:42:30 +0000 (14:42 +0100)
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>
drivers/net/wireless/intel/iwlwifi/fw/dump.c
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 3cabdeb53e99c8c9d65bb59d9c062ed75d838f6b..8e0c85a1240d75bac42b9c8c00b02837ee6db7ae 100644 (file)
@@ -537,13 +537,18 @@ bool iwl_fwrt_read_err_table(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);
 
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 fae9eabfa56eeb29fe736606e93714e1eb9eabe0..a6082150deab153ef02db5e772fdf02895c403e5 100644 (file)
@@ -3107,7 +3107,6 @@ static void iwl_mvm_d3_disconnect_iter(void *data, u8 *mac,
                ieee80211_resume_disconnect(vif);
 }
 
-
 static bool iwl_mvm_check_rt_status(struct iwl_mvm *mvm,
                                   struct ieee80211_vif *vif)
 {
@@ -3706,22 +3705,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;
 }