Search Linux Wireless

Re: [REGRESSION] iwlwifi resume error, bisected

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, 2024-09-08 at 11:53 +0300, Grumbach, Emmanuel wrote:
> On Sat, 2024-09-07 at 22:21 +0100, Chris Bainbridge wrote:
> > On Sat, 7 Sept 2024 at 19:35, Grumbach, Emmanuel
> > <emmanuel.grumbach@xxxxxxxxx> wrote:
> > > 
> > > Can you please try to add:
> > > https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless.git/commit/?id=094513f8a2fbddee51b055d8035f995551f98fce
> > > https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless.git/commit/?id=cb347bd29d0d106213a0cf4f86b72dffd08d3454
> > > 
> > > and let me know if things work again for you?
> > 
> > Both of those patches are already in v6.11-rc6 (which has the error).
> 
> Can you please try to apply this:
> 
> diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
> b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
> index 1822e22b7c0a..454eb1155881 100644
> --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
> +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
> @@ -1697,6 +1697,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;
>  }

Strike that.

Can you please take the patch in attached instead?

> 
> It should fix the last part of the error you pasted:
> 
> [  103.512122] iwlwifi 0000:01:00.0: Hardware error detected. Restarting.
> [  103.512330] iwlwifi 0000:01:00.0: Start IWL Error Log Dump:
> [  103.512331] iwlwifi 0000:01:00.0: Transport status: 0x0000004B
> 
> You'll still have the first part but I expect WiFi to work.

This is still true. I simulated your failure by injecting failure in the code that accesses the
device and see that WiFi is still functional after resume.

> I'm still checking internally what we need to do here.
> 
> Thanks for your report and bisection!
> 
> > 
> > > BTW - I assume that your system is configured not to power the WLAN device if the power cord
> > > is
> > > not
> > > connected and the system is suspended?
> > 
> > This is a HP laptop with default BIOS settings. It's possible that the
> > HP BIOS turns off the wifi when suspended on battery power, but I
> > haven't explicitly configured anything related to WLAN power (I don't
> > see any BIOS settings for that), and the kernel is running with
> > default parameters.
> 
> I see. Thanks.
> 

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index 0ef48effeefb..2d41d108112f 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -1076,12 +1076,15 @@ 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)		\
+	({								\
+		int __ret;						\
+		if (__builtin_constant_p(bufsize))			\
+			BUILD_BUG_ON((bufsize) % sizeof(u32));		\
+		__ret = iwl_trans_read_mem(trans, addr, buf,		\
+					   (bufsize) / sizeof(u32));	\
+		__ret;							\
+	})
 
 int iwl_trans_write_imr_mem(struct iwl_trans *trans, u32 dst_addr,
 			    u64 src_addr, u32 byte_cnt);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index 99a541d442bb..8f9c04be4d00 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -3030,13 +3030,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);
 
@@ -3633,12 +3638,17 @@ 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);
+		clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status);
+		mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED;
+		mvm->trans->state = IWL_TRANS_NO_FW;
 		return -ENODEV;
 	}
 	ret = iwl_mvm_d3_notif_wait(mvm, &d3_data);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 719ddc4b72c5..72989a99c777 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -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;
 }

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux