From: Miri Korenblit miriam.rachel.korenblit@intel.com
[ Upstream commit 1a33efe4fc64b8135fe94e22299761cc69333404 ]
trans_pcie::fh_mask and hw_mask indicates what are the interrupts are currently enabled (unmasked). When we disable all interrupts, those should be set to 0, so if, for some reason, we get an interrupt even though it was disabled, we will know to ignore.
Reviewed-by: Yedidya Ben Shimol yedidya.ben.shimol@intel.com Signed-off-by: Miri Korenblit miriam.rachel.korenblit@intel.com Link: https://patch.msgid.link/20250828111032.e293d6a8385b.I919375e5ad7bd7e4fee4a9... Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
YES
- What changed - In MSI-X mode, `_iwl_disable_interrupts()` now also clears the software-tracked masks by setting `trans_pcie->fh_mask = 0` and `trans_pcie->hw_mask = 0` after masking all causes in hardware (`CSR_MSIX_FH_INT_MASK_AD`/`CSR_MSIX_HW_INT_MASK_AD`): `drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/internal.h:849` and `drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/internal.h:850`. - In `iwl_enable_rfkill_int()`, after disabling all FH causes in hardware, the driver now records that no FH causes are enabled in software with `trans_pcie->fh_mask = 0`: `drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/internal.h:1033`.
- Why this fixes a real bug - The MSI-X interrupt handler explicitly filters incoming causes using the software masks: - FH causes: `inta_fh &= trans_pcie->fh_mask;` at `drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/rx.c:2314` - HW causes: `inta_hw &= trans_pcie->hw_mask;` at `drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/rx.c:2416` - Before this change, when interrupts were masked in hardware, the software masks (`fh_mask`/`hw_mask`) were not reset and could still reflect previously enabled causes. If a spurious interrupt arrived during shutdown/reset or during rfkill-only mode, the ISR would process it because the software masks still allowed it. The ISR even logs this mismatch: - FH masked interrupt detection: `drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/rx.c:2308` - HW masked interrupt detection: `drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/rx.c:2410` - Clearing `fh_mask`/`hw_mask` to 0 on disable makes the ISR ignore any such stray causes (due to the AND), preventing unintended NAPI scheduling, state transitions, or error handling during device teardown, reset, or low-power/rfkill transitions.
- Scope and risk assessment - Limited to MSI-X paths; non-MSI-X interrupt handling remains unchanged (`inta_mask` path unaffected): `drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/internal.h:835-843`. - No API or architectural changes; only aligns software state variables with the hardware-disabled state. - Interactions are straightforward: enabling paths already set `fh_mask`/`hw_mask` to the desired enabled causes (e.g., `iwl_enable_interrupts()` sets both masks and writes ~mask to the HW registers: `drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/internal.h:912-917`; `iwl_enable_hw_int_msk_msix()`/`iwl_enable_fh_int_msk_msix()` assign the masks as well: `drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/i nternal.h:929-943`). - The change prevents race-induced misprocessing; it does not open new code paths or alter timing beyond ignoring masked causes. It is a correctness fix with minimal regression risk.
- Stable backport criteria - Fixes a real bug that can affect users during device shutdown/reset/rfkill transitions by avoiding processing of interrupts that should be ignored. - Small, self-contained changes in a single header file within the iwlwifi PCIe MSI-X handling. - No new features, no ABI changes, no architectural rework. - Touches a well-scoped subsystem (iwlwifi PCIe interrupt handling).
Given the clear bug scenario and the minimal, targeted nature of the fix, this is a good candidate for stable backport.
drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/internal.h | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/internal.h index f48aeebb151cc..86edc79ac09f8 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/internal.h @@ -818,6 +818,8 @@ static inline void _iwl_disable_interrupts(struct iwl_trans *trans) trans_pcie->fh_init_mask); iwl_write32(trans, CSR_MSIX_HW_INT_MASK_AD, trans_pcie->hw_init_mask); + trans_pcie->fh_mask = 0; + trans_pcie->hw_mask = 0; } IWL_DEBUG_ISR(trans, "Disabled interrupts\n"); } @@ -1000,6 +1002,7 @@ static inline void iwl_enable_rfkill_int(struct iwl_trans *trans) } else { iwl_write32(trans, CSR_MSIX_FH_INT_MASK_AD, trans_pcie->fh_init_mask); + trans_pcie->fh_mask = 0; iwl_enable_hw_int_msk_msix(trans, MSIX_HW_INT_CAUSES_REG_RF_KILL); }