From 7b3fba91390c9d66f0fc3f48ef2d9ccea866d2f3 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Tue, 6 May 2025 22:40:58 +0300 Subject: wifi: iwlwifi: mld: call thermal exit without wiphy lock held [ Upstream commit 83128399f3b4926ab73ce8e5081ce6595e9230e9 ] The driver must not hold the wiphy mutex when unregistering the thermal devices. Do not hold the lock for the call to iwl_mld_thermal_exit and only do a lock/unlock to cancel the ct_kill_exit_wk work. The problem is that iwl_mld_tzone_get_temp needs to take the wiphy lock while the thermal code is holding its own locks already. When unregistering the device, the reverse would happen as the driver was calling thermal_cooling_device_unregister with the wiphy mutex already held. It is not likely to trigger this deadlock as it can only happen if the thermal code is polling the temperature while the driver is being unloaded. However, lockdep reported it so fix it. Signed-off-by: Benjamin Berg Reviewed-by: Johannes Berg Link: https://patch.msgid.link/20250506194102.3407967-12-miriam.rachel.korenblit@intel.com Signed-off-by: Miri Korenblit Signed-off-by: Sasha Levin --- drivers/net/wireless/intel/iwlwifi/mld/mld.c | 3 ++- drivers/net/wireless/intel/iwlwifi/mld/thermal.c | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/intel/iwlwifi') diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mld.c b/drivers/net/wireless/intel/iwlwifi/mld/mld.c index 7a098942dc80..21f65442638d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mld.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/mld.c @@ -475,8 +475,9 @@ iwl_op_mode_mld_stop(struct iwl_op_mode *op_mode) iwl_mld_ptp_remove(mld); iwl_mld_leds_exit(mld); - wiphy_lock(mld->wiphy); iwl_mld_thermal_exit(mld); + + wiphy_lock(mld->wiphy); iwl_mld_low_latency_stop(mld); iwl_mld_deinit_time_sync(mld); wiphy_unlock(mld->wiphy); diff --git a/drivers/net/wireless/intel/iwlwifi/mld/thermal.c b/drivers/net/wireless/intel/iwlwifi/mld/thermal.c index 1909953a9be9..670ac4352800 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/thermal.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/thermal.c @@ -419,6 +419,8 @@ static void iwl_mld_cooling_device_unregister(struct iwl_mld *mld) void iwl_mld_thermal_initialize(struct iwl_mld *mld) { + lockdep_assert_not_held(&mld->wiphy->mtx); + wiphy_delayed_work_init(&mld->ct_kill_exit_wk, iwl_mld_exit_ctkill); #ifdef CONFIG_THERMAL @@ -429,7 +431,9 @@ void iwl_mld_thermal_initialize(struct iwl_mld *mld) void iwl_mld_thermal_exit(struct iwl_mld *mld) { + wiphy_lock(mld->wiphy); wiphy_delayed_work_cancel(mld->wiphy, &mld->ct_kill_exit_wk); + wiphy_unlock(mld->wiphy); #ifdef CONFIG_THERMAL iwl_mld_cooling_device_unregister(mld); -- cgit v1.2.3 From d093eb4fc59bfad9a2fffbe754492f9499061f1e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 5 May 2025 21:56:47 +0300 Subject: wifi: iwlwifi: mvm: fix beacon CCK flag [ Upstream commit 8d7f08922a8cb621aa5d00bdce6a7afe57af1665 ] The beacon CCK flag should be set for any CCK rate, not just for 1 Mbps. Fix that. Signed-off-by: Johannes Berg Reviewed-by: Ilan Peer Link: https://patch.msgid.link/20250505215513.fe18b7d92d7d.I7bb40a92cea102677b695beb1e2a62a5ea72678b@changeid Signed-off-by: Miri Korenblit Signed-off-by: Sasha Levin --- drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless/intel/iwlwifi') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index bec18d197f31..83f1ed94ccab 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2012-2014, 2018-2024 Intel Corporation + * Copyright (C) 2012-2014, 2018-2025 Intel Corporation * Copyright (C) 2013-2014 Intel Mobile Communications GmbH * Copyright (C) 2015-2017 Intel Deutschland GmbH */ @@ -941,7 +941,7 @@ u16 iwl_mvm_mac_ctxt_get_beacon_flags(const struct iwl_fw *fw, u8 rate_idx) u16 flags = iwl_mvm_mac80211_idx_to_hwrate(fw, rate_idx); bool is_new_rate = iwl_fw_lookup_cmd_ver(fw, BEACON_TEMPLATE_CMD, 0) > 10; - if (rate_idx <= IWL_FIRST_CCK_RATE) + if (rate_idx <= IWL_LAST_CCK_RATE) flags |= is_new_rate ? IWL_MAC_BEACON_CCK : IWL_MAC_BEACON_CCK_V1; -- cgit v1.2.3 From a85832dae1d63880d360714c6a15616fac4337a3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 4 May 2025 13:26:30 +0300 Subject: wifi: iwlwifi: dvm: pair transport op-mode enter/leave [ Upstream commit 6b340a694cee9e7a24b2be827c738b5b6cb13c84 ] If there's a failure and the op-mode didn't actually fully initialize, it should leave the transport again. Fix that. Signed-off-by: Johannes Berg Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20250504132447.714c3517548b.I49557e7ba8c03be2b558cc9fb5efa2a9fbab890e@changeid Signed-off-by: Sasha Levin --- drivers/net/wireless/intel/iwlwifi/dvm/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless/intel/iwlwifi') diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c index a27a72cc017a..a7f9e244c097 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c @@ -1382,14 +1382,14 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, err = iwl_trans_start_hw(priv->trans); if (err) - goto out_free_hw; + goto out_leave_trans; /* Read the EEPROM */ err = iwl_read_eeprom(priv->trans, &priv->eeprom_blob, &priv->eeprom_blob_size); if (err) { IWL_ERR(priv, "Unable to init EEPROM\n"); - goto out_free_hw; + goto out_leave_trans; } /* Reset chip to save power until we load uCode during "up". */ @@ -1508,6 +1508,8 @@ out_free_eeprom_blob: kfree(priv->eeprom_blob); out_free_eeprom: kfree(priv->nvm_data); +out_leave_trans: + iwl_trans_op_mode_leave(priv->trans); out_free_hw: ieee80211_free_hw(priv->hw); out: -- cgit v1.2.3 From f8efb4a2b3fea7ab192db57ab879a4f58af8889c Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Wed, 30 Apr 2025 15:23:16 +0300 Subject: wifi: iwlwifi: mld: check for NULL before referencing a pointer [ Upstream commit f9151f16e140b9c43f076579146679408af6f442 ] Errors can happen, and it is better not to risk with a NULL pointer dereference. Make sure that the links-to-remove pointers are not NULL before dereferencing it. Signed-off-by: Miri Korenblit Reviewed-by: Johannes Berg Link: https://patch.msgid.link/20250430151952.408652d45cda.I1bb72836dab17895a2e39910e4493d667db0fa80@changeid Signed-off-by: Sasha Levin --- drivers/net/wireless/intel/iwlwifi/mld/mac80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless/intel/iwlwifi') diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c index 68d97d3b8f02..2d5233dc3e24 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c @@ -2460,7 +2460,7 @@ iwl_mld_change_vif_links(struct ieee80211_hw *hw, added |= BIT(0); for (int i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) { - if (removed & BIT(i)) + if (removed & BIT(i) && !WARN_ON(!old[i])) iwl_mld_remove_link(mld, old[i]); } -- cgit v1.2.3 From 3447aa5bbbb643405458d53e51cf1a39a7cb3412 Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Thu, 24 Apr 2025 15:38:30 +0300 Subject: wifi: iwlwifi: pcie: make sure to lock rxq->read [ Upstream commit 1cc2c48c4af81bed5ddbe9f2c9d6e20fa163acf9 ] rxq->read is accessed without the rxq->lock in a few places, Make sure to have the lock there. Signed-off-by: Miri Korenblit Reviewed-by: Emmanuel Grumbach Tested-by: Emmanuel Grumbach Link: https://patch.msgid.link/20250424153620.73725f207aaa.I1a3e4b6c5fd370e029fdacfcdc9ee335788afa98@changeid Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/net/wireless/intel/iwlwifi') diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 102a6123bba0..4cc7a2e5746d 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -2942,6 +2942,8 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file, for (i = 0; i < trans->num_rx_queues && pos < bufsz; i++) { struct iwl_rxq *rxq = &trans_pcie->rxq[i]; + spin_lock_bh(&rxq->lock); + pos += scnprintf(buf + pos, bufsz - pos, "queue#: %2d\n", i); pos += scnprintf(buf + pos, bufsz - pos, "\tread: %u\n", @@ -2962,6 +2964,7 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file, pos += scnprintf(buf + pos, bufsz - pos, "\tclosed_rb_num: Not Allocated\n"); } + spin_unlock_bh(&rxq->lock); } ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); kfree(buf); @@ -3662,8 +3665,11 @@ iwl_trans_pcie_dump_data(struct iwl_trans *trans, u32 dump_mask, /* Dump RBs is supported only for pre-9000 devices (1 queue) */ struct iwl_rxq *rxq = &trans_pcie->rxq[0]; /* RBs */ + spin_lock_bh(&rxq->lock); num_rbs = iwl_get_closed_rb_stts(trans, rxq); num_rbs = (num_rbs - rxq->read) & RX_QUEUE_MASK; + spin_unlock_bh(&rxq->lock); + len += num_rbs * (sizeof(*data) + sizeof(struct iwl_fw_error_dump_rb) + (PAGE_SIZE << trans_pcie->rx_page_order)); -- cgit v1.2.3 From 210dfda8003499b88162a7386861b1cdce8ffb9b Mon Sep 17 00:00:00 2001 From: Víctor Gonzalo Date: Wed, 13 Mar 2024 20:02:27 +0200 Subject: wifi: iwlwifi: Add missing MODULE_FIRMWARE for Qu-c0-jf-b0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 2b801487ac3be7bec561ae62d1a6c4d6f5283f8c ] The module metadata for the firmware file iwlwifi-Qu-c0-jf-b0-* is missing. Signed-off-by: Víctor Gonzalo Link: https://patch.msgid.link/20240313180227.2224780-1-victor.gonzalo@anddroptable.net Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/net/wireless/intel/iwlwifi') diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index 130b9a8aa7eb..67ee3b6e6d85 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -44,6 +44,8 @@ IWL_QU_C_HR_B_FW_PRE "-" __stringify(api) ".ucode" #define IWL_QU_B_JF_B_MODULE_FIRMWARE(api) \ IWL_QU_B_JF_B_FW_PRE "-" __stringify(api) ".ucode" +#define IWL_QU_C_JF_B_MODULE_FIRMWARE(api) \ + IWL_QU_C_JF_B_FW_PRE "-" __stringify(api) ".ucode" #define IWL_CC_A_MODULE_FIRMWARE(api) \ IWL_CC_A_FW_PRE "-" __stringify(api) ".ucode" @@ -422,6 +424,7 @@ const struct iwl_cfg iwl_cfg_quz_a0_hr_b0 = { MODULE_FIRMWARE(IWL_QU_B_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_QU_C_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_QU_B_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL_QU_C_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_QUZ_A_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_QUZ_A_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_CC_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); -- cgit v1.2.3 From 91a0421861592ea31de70a00aff11a2d9fbdaf35 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 21 Apr 2025 13:41:57 -0700 Subject: wifi: iwlwifi: mld: Work around Clang loop unrolling bug [ Upstream commit 368556dd234dc4a506a35a0c99c0eee2ab475c77 ] The nested loop in iwl_mld_send_proto_offload() confuses Clang into thinking there could be a final loop iteration past the end of the "nsc" array (which is only 4 entries). The FORTIFY checking in memcmp() (via ipv6_addr_cmp()) notices this (due to the available bytes in the out-of-bounds position of &nsc[4] being 0), and errors out, failing the build. For some reason (likely due to architectural loop unrolling configurations), this is only exposed on ARM builds currently. Due to Clang's lack of inline tracking[1], the warning is not very helpful: include/linux/fortify-string.h:719:4: error: call to '__read_overflow' declared with 'error' attribute: detected read beyond size of object (1st parameter) 719 | __read_overflow(); | ^ 1 error generated. But this was tracked down to iwl_mld_send_proto_offload()'s ipv6_addr_cmp() call. An upstream Clang bug has been filed[2] to track this. For now fix the build by explicitly bounding the inner loop by "n_nsc", which is what "c" is already limited to. Reported-by: Nathan Chancellor Closes: https://github.com/ClangBuiltLinux/linux/issues/2076 Link: https://github.com/llvm/llvm-project/pull/73552 [1] Link: https://github.com/llvm/llvm-project/issues/136603 [2] Link: https://lore.kernel.org/r/20250421204153.work.935-kees@kernel.org Signed-off-by: Kees Cook Signed-off-by: Sasha Levin --- drivers/net/wireless/intel/iwlwifi/mld/d3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless/intel/iwlwifi') diff --git a/drivers/net/wireless/intel/iwlwifi/mld/d3.c b/drivers/net/wireless/intel/iwlwifi/mld/d3.c index ee99298eebf5..7ce01ad3608e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/d3.c @@ -1757,7 +1757,7 @@ iwl_mld_send_proto_offload(struct iwl_mld *mld, addrconf_addr_solict_mult(&wowlan_data->target_ipv6_addrs[i], &solicited_addr); - for (j = 0; j < c; j++) + for (j = 0; j < n_nsc && j < c; j++) if (ipv6_addr_cmp(&nsc[j].dest_ipv6_addr, &solicited_addr) == 0) break; -- cgit v1.2.3