Skip to content

Commit 15220a2

Browse files
egrumbachjmberg-intel
authored andcommitted
wifi: iwlwifi: don't warn if the NIC is gone in resume
Some BIOSes decide to power gate the WLAN device during S3. Since iwlwifi doesn't expect this, it gets very noisy reporting that the device is no longer available. Wifi is still available because iwlwifi recovers, but it spews scary prints in the log. Fix that by failing gracefully. Fixes: e8bb19c ("wifi: iwlwifi: support fast resume") Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219597 Signed-off-by: Emmanuel Grumbach <[email protected]> Signed-off-by: Miri Korenblit <[email protected]> Link: https://patch.msgid.link/20250420095642.d8d58146c829.I569ca15eaaa774d633038a749cc6ec7448419714@changeid Signed-off-by: Johannes Berg <[email protected]>
1 parent 60d418e commit 15220a2

File tree

5 files changed

+33
-12
lines changed

5 files changed

+33
-12
lines changed

drivers/net/wireless/intel/iwlwifi/iwl-trans.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,6 @@ void __releases(nic_access)
555555
iwl_trans_release_nic_access(struct iwl_trans *trans)
556556
{
557557
iwl_trans_pcie_release_nic_access(trans);
558-
__release(nic_access);
559558
}
560559
IWL_EXPORT_SYMBOL(iwl_trans_release_nic_access);
561560

drivers/net/wireless/intel/iwlwifi/pcie/drv.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1737,10 +1737,24 @@ static int _iwl_pci_resume(struct device *device, bool restore)
17371737
* need to reset it completely.
17381738
* Note: MAC (bits 0:7) will be cleared upon suspend even with wowlan,
17391739
* so assume that any bits there mean that the device is usable.
1740+
* For older devices, just try silently to grab the NIC.
17401741
*/
1741-
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ &&
1742-
!iwl_read32(trans, CSR_FUNC_SCRATCH))
1743-
device_was_powered_off = true;
1742+
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) {
1743+
if (!iwl_read32(trans, CSR_FUNC_SCRATCH))
1744+
device_was_powered_off = true;
1745+
} else {
1746+
/*
1747+
* bh are re-enabled by iwl_trans_pcie_release_nic_access,
1748+
* so re-enable them if _iwl_trans_pcie_grab_nic_access fails.
1749+
*/
1750+
local_bh_disable();
1751+
if (_iwl_trans_pcie_grab_nic_access(trans, true)) {
1752+
iwl_trans_pcie_release_nic_access(trans);
1753+
} else {
1754+
device_was_powered_off = true;
1755+
local_bh_enable();
1756+
}
1757+
}
17441758

17451759
if (restore || device_was_powered_off) {
17461760
trans->state = IWL_TRANS_NO_FW;

drivers/net/wireless/intel/iwlwifi/pcie/internal.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -558,10 +558,10 @@ void iwl_trans_pcie_free(struct iwl_trans *trans);
558558
void iwl_trans_pcie_free_pnvm_dram_regions(struct iwl_dram_regions *dram_regions,
559559
struct device *dev);
560560

561-
bool __iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans);
562-
#define _iwl_trans_pcie_grab_nic_access(trans) \
561+
bool __iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent);
562+
#define _iwl_trans_pcie_grab_nic_access(trans, silent) \
563563
__cond_lock(nic_access_nobh, \
564-
likely(__iwl_trans_pcie_grab_nic_access(trans)))
564+
likely(__iwl_trans_pcie_grab_nic_access(trans, silent)))
565565

566566
void iwl_trans_pcie_check_product_reset_status(struct pci_dev *pdev);
567567
void iwl_trans_pcie_check_product_reset_mode(struct pci_dev *pdev);
@@ -1105,7 +1105,8 @@ void iwl_trans_pcie_set_bits_mask(struct iwl_trans *trans, u32 reg,
11051105
int iwl_trans_pcie_read_config32(struct iwl_trans *trans, u32 ofs,
11061106
u32 *val);
11071107
bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans);
1108-
void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans);
1108+
void __releases(nic_access_nobh)
1109+
iwl_trans_pcie_release_nic_access(struct iwl_trans *trans);
11091110

11101111
/* transport gen 1 exported functions */
11111112
void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr);

drivers/net/wireless/intel/iwlwifi/pcie/trans.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2406,7 +2406,7 @@ EXPORT_SYMBOL(iwl_trans_pcie_reset);
24062406
* This version doesn't disable BHs but rather assumes they're
24072407
* already disabled.
24082408
*/
2409-
bool __iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans)
2409+
bool __iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent)
24102410
{
24112411
int ret;
24122412
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
@@ -2458,6 +2458,11 @@ bool __iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans)
24582458
if (unlikely(ret < 0)) {
24592459
u32 cntrl = iwl_read32(trans, CSR_GP_CNTRL);
24602460

2461+
if (silent) {
2462+
spin_unlock(&trans_pcie->reg_lock);
2463+
return false;
2464+
}
2465+
24612466
WARN_ONCE(1,
24622467
"Timeout waiting for hardware access (CSR_GP_CNTRL 0x%08x)\n",
24632468
cntrl);
@@ -2489,7 +2494,7 @@ bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans)
24892494
bool ret;
24902495

24912496
local_bh_disable();
2492-
ret = __iwl_trans_pcie_grab_nic_access(trans);
2497+
ret = __iwl_trans_pcie_grab_nic_access(trans, false);
24932498
if (ret) {
24942499
/* keep BHs disabled until iwl_trans_pcie_release_nic_access */
24952500
return ret;
@@ -2498,7 +2503,8 @@ bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans)
24982503
return false;
24992504
}
25002505

2501-
void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans)
2506+
void __releases(nic_access_nobh)
2507+
iwl_trans_pcie_release_nic_access(struct iwl_trans *trans)
25022508
{
25032509
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
25042510

@@ -2525,6 +2531,7 @@ void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans)
25252531
* scheduled on different CPUs (after we drop reg_lock).
25262532
*/
25272533
out:
2534+
__release(nic_access_nobh);
25282535
spin_unlock_bh(&trans_pcie->reg_lock);
25292536
}
25302537

drivers/net/wireless/intel/iwlwifi/pcie/tx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1021,7 +1021,7 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans,
10211021
* returned. This needs to be done only on NICs that have
10221022
* apmg_wake_up_wa set (see above.)
10231023
*/
1024-
if (!_iwl_trans_pcie_grab_nic_access(trans))
1024+
if (!_iwl_trans_pcie_grab_nic_access(trans, false))
10251025
return -EIO;
10261026

10271027
/*

0 commit comments

Comments
 (0)