From 0ba1b366185b770440bf4eee3c4a929bc3cfc0e9 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Sat, 14 Feb 2026 11:05:09 -0800 Subject: [PATCH 01/46] wifi: iwlwifi: Clean dangling pointer in tx path If iwl_txq_gen2_build_tfd fails, we return -1, which will cause calling code to dispose of the skb one way or another. Remove any reference to that skb from the txq entries so that nothing will try to access it later. Signed-off-by: Ben Greear Link: https://patch.msgid.link/20260214190509.2098565-1-greearb@candelatech.com Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/tx-gen2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/tx-gen2.c index bda9f807321e..27f4973791d0 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/tx-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/tx-gen2.c @@ -773,6 +773,8 @@ int iwl_txq_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb, tfd = iwl_txq_gen2_build_tfd(trans, txq, dev_cmd, skb, out_meta); if (!tfd) { + txq->entries[idx].skb = NULL; + txq->entries[idx].cmd = NULL; spin_unlock(&txq->lock); return -1; } From d6061f5f1318a0fc116fa442bea299095d211ad4 Mon Sep 17 00:00:00 2001 From: Praveen Rajendran Date: Fri, 3 Jul 2026 19:37:57 +0530 Subject: [PATCH 02/46] wifi: iwlwifi: fw: Fix spelling typo in error-dump.h Correct a minor grammatical error inside the kernel-doc comments of error-dump.h where "configuration" was misspelled as "configuraiton". Signed-off-by: Praveen Rajendran Link: https://patch.msgid.link/20260703140757.3372-1-praveenrajendran2009@gmail.com Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/fw/error-dump.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h index 07f1240df866..692bb17dfc33 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h @@ -352,7 +352,7 @@ struct iwl_fw_ini_error_dump_register { * struct iwl_fw_ini_dump_cfg_name - configuration name * @image_type: image type the configuration is related to * @cfg_name_len: length of the configuration name - * @cfg_name: name of the configuraiton + * @cfg_name: name of the configuration */ struct iwl_fw_ini_dump_cfg_name { __le32 image_type; From 67105abd6195a685a84dcb8a5daf54a1f4bfdb60 Mon Sep 17 00:00:00 2001 From: Dawei Feng Date: Wed, 24 Jun 2026 16:44:04 +0800 Subject: [PATCH 03/46] wifi: iwlwifi: dvm: fix memory leak in iwl_op_mode_dvm_start() In iwl_op_mode_dvm_start(), jumping to out_free_eeprom currently bypasses the out_free_eeprom_blob label. Consequently, error paths triggered after successfully parsing the EEPROM free priv->nvm_data but leak priv->eeprom_blob. Fix this memory leak by reordering the error handling labels so that out_free_eeprom falls through to out_free_eeprom_blob. The bug was first flagged by an experimental analysis tool we are developing for kernel memory-management bugs while analyzing v6.13-rc1. The tool is still under development and is not yet publicly available. Manual inspection confirms that the bug is still present in v7.1-rc6. An x86_64 allyesconfig build showed no new warnings. As we do not have supported Intel DVM wireless hardware and firmware to test with, no runtime testing was able to be performed. Cc: stable@vger.kernel.org Signed-off-by: Dawei Feng Link: https://patch.msgid.link/20260624084404.570703-1-dawei.feng@seu.edu.cn Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/dvm/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c index ca5a8140908a..6bd5b6d84b2a 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c @@ -1511,10 +1511,10 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, priv->workqueue = NULL; out_uninit_drv: iwl_uninit_drv(priv); -out_free_eeprom_blob: - kfree(priv->eeprom_blob); out_free_eeprom: kfree(priv->nvm_data); +out_free_eeprom_blob: + kfree(priv->eeprom_blob); out_leave_trans: iwl_trans_op_mode_leave(priv->trans); out_free_hw: From 94280e6e0c69a5327e377803732f494d8b5a74cd Mon Sep 17 00:00:00 2001 From: Haoxiang Li Date: Wed, 1 Apr 2026 11:05:55 +0800 Subject: [PATCH 04/46] iwlwifi: dvm: add missing cleaup for on error path In iwlagn_tx_agg_start(), call iwlagn_dealloc_agg_txq() to clear bit on error path. Signed-off-by: Haoxiang Li Link: https://patch.msgid.link/20260401030555.541685-1-lihaoxiang@isrc.iscas.ac.cn Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/dvm/tx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c index a7806776a51e..1a0167f67c7b 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c @@ -604,8 +604,10 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, } ret = iwl_sta_tx_modify_enable_tid(priv, sta_id, tid); - if (ret) + if (ret) { + iwlagn_dealloc_agg_txq(priv, txq_id); return ret; + } spin_lock_bh(&priv->sta_lock); tid_data = &priv->tid_data[sta_id][tid]; From 7410e4548a17bd868dfc60b48f2e78eacde3ad78 Mon Sep 17 00:00:00 2001 From: Pengpeng Hou Date: Wed, 15 Jul 2026 21:57:50 +0800 Subject: [PATCH 05/46] wifi: iwlwifi: validate PNVM SKU TLV length iwl_pnvm_parse() reads an iwl_sku_id from an IWL_UCODE_TLV_PNVM_SKU payload after only checking that the generic TLV payload is present. A short type-specific payload can therefore make the three data[] reads extend beyond the TLV. Reject SKU TLVs shorter than the structure before accessing it. Signed-off-by: Pengpeng Hou Link: https://patch.msgid.link/20260715135916.24417-1-pengpeng@iscas.ac.cn Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/fw/pnvm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c index afff8d51ca95..6daa5cc8c20f 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c @@ -198,6 +198,12 @@ static int iwl_pnvm_parse(struct iwl_trans *trans, const u8 *data, IWL_DEBUG_FW(trans, "Got IWL_UCODE_TLV_PNVM_SKU len %d\n", tlv_len); + if (tlv_len < sizeof(*tlv_sku_id)) { + IWL_ERR(trans, "invalid PNVM SKU TLV len: %u\n", + tlv_len); + return -EINVAL; + } + IWL_DEBUG_FW(trans, "sku_id 0x%0x 0x%0x 0x%0x\n", le32_to_cpu(tlv_sku_id->data[0]), le32_to_cpu(tlv_sku_id->data[1]), From f051995c539582b05276abda4c5874fd4cafd2a5 Mon Sep 17 00:00:00 2001 From: Pengpeng Hou Date: Wed, 15 Jul 2026 21:57:50 +0800 Subject: [PATCH 06/46] wifi: iwlwifi: validate UEFI reduced-power SKU TLV length iwl_uefi_reduce_power_parse() reads an iwl_sku_id from an IWL_UCODE_TLV_PNVM_SKU payload after only checking that the generic TLV payload is present. A short type-specific payload can therefore make the three data[] reads extend beyond the TLV. Reject SKU TLVs shorter than the structure before accessing it. Signed-off-by: Pengpeng Hou Link: https://patch.msgid.link/20260715135916.24417-2-pengpeng@iscas.ac.cn Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/fw/uefi.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c index 2ef0a7a920ad..4cd36b42262c 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c @@ -248,6 +248,12 @@ int iwl_uefi_reduce_power_parse(struct iwl_trans *trans, IWL_DEBUG_FW(trans, "Got IWL_UCODE_TLV_PNVM_SKU len %d\n", tlv_len); + if (tlv_len < sizeof(*tlv_sku_id)) { + IWL_ERR(trans, "invalid PNVM SKU TLV len: %u\n", + tlv_len); + return -EINVAL; + } + IWL_DEBUG_FW(trans, "sku_id 0x%0x 0x%0x 0x%0x\n", le32_to_cpu(tlv_sku_id->data[0]), le32_to_cpu(tlv_sku_id->data[1]), From 478cad8bba59e8ee0e08d49edabf14bf1fbde5e4 Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Tue, 14 Jul 2026 17:02:04 +0300 Subject: [PATCH 07/46] wifi: iwlwifi: add a compile time check for too long hcmds A host command that is bigger than the allowed payload length should be sent with the NOCOPY flag. If it is sent without, we will get a warning. We do know at compile time what is the maximum size of a hcmd payload that the transport supports, so in order to catch bugs early, add a compile time check to iwl_*_send_cmd_pdu to catch that. Reviewed-by: Johannes Berg Link: https://patch.msgid.link/20260714165826.a549b9499e3e.Id1a95bbbf92b5862862becaf57419bb9fe1385e5@changeid Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/mld/hcmd.h | 9 +++++++-- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 20 ++++++++++++++----- .../net/wireless/intel/iwlwifi/mvm/utils.c | 8 ++++---- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mld/hcmd.h b/drivers/net/wireless/intel/iwlwifi/mld/hcmd.h index 64a8d4248324..19e1c9e509cf 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/hcmd.h +++ b/drivers/net/wireless/intel/iwlwifi/mld/hcmd.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2024-2025 Intel Corporation + * Copyright (C) 2024-2026 Intel Corporation */ #ifndef __iwl_mld_hcmd_h__ #define __iwl_mld_hcmd_h__ @@ -42,7 +42,12 @@ __iwl_mld_send_cmd_with_flags_pdu(struct iwl_mld *mld, u32 id, #define _iwl_mld_send_cmd_with_flags_pdu(mld, id, flags, data, len, \ ignored...) \ - __iwl_mld_send_cmd_with_flags_pdu(mld, id, flags, data, len) + ({ \ + BUILD_BUG_ON(__builtin_constant_p(len) && \ + (u16)(len) > IWL_MAX_CMD_PAYLOAD_SIZE); \ + __iwl_mld_send_cmd_with_flags_pdu(mld, id, flags, \ + data, len); \ + }) #define iwl_mld_send_cmd_with_flags_pdu(mld, id, flags, data, len...) \ _iwl_mld_send_cmd_with_flags_pdu(mld, id, flags, data, ##len, \ sizeof(*(data))) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 683cac56822c..1b56a2695bde 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1675,14 +1675,24 @@ u32 iwl_mvm_get_systime(struct iwl_mvm *mvm); /* Tx / Host Commands */ int iwl_mvm_send_cmd(struct iwl_mvm *mvm, struct iwl_host_cmd *cmd); -int iwl_mvm_send_cmd_pdu(struct iwl_mvm *mvm, u32 id, - u32 flags, u16 len, const void *data); +int _iwl_mvm_send_cmd_pdu(struct iwl_mvm *mvm, u32 id, + u32 flags, u16 len, const void *data); +#define iwl_mvm_send_cmd_pdu(mvm, id, flags, len, data) ({ \ + BUILD_BUG_ON(__builtin_constant_p(len) && \ + (u16)(len) > IWL_MAX_CMD_PAYLOAD_SIZE); \ + _iwl_mvm_send_cmd_pdu(mvm, id, flags, len, data); \ +}) int iwl_mvm_send_cmd_status(struct iwl_mvm *mvm, struct iwl_host_cmd *cmd, u32 *status); -int iwl_mvm_send_cmd_pdu_status(struct iwl_mvm *mvm, u32 id, - u16 len, const void *data, - u32 *status); +int _iwl_mvm_send_cmd_pdu_status(struct iwl_mvm *mvm, u32 id, + u16 len, const void *data, + u32 *status); +#define iwl_mvm_send_cmd_pdu_status(mvm, id, len, data, status) ({ \ + BUILD_BUG_ON(__builtin_constant_p(len) && \ + (u16)(len) > IWL_MAX_CMD_PAYLOAD_SIZE); \ + _iwl_mvm_send_cmd_pdu_status(mvm, id, len, data, status); \ +}) int iwl_mvm_tx_skb_sta(struct iwl_mvm *mvm, struct sk_buff *skb, struct ieee80211_sta *sta); int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index 2e12f93ad32b..849342c96ae7 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c @@ -73,8 +73,8 @@ int iwl_mvm_send_cmd(struct iwl_mvm *mvm, struct iwl_host_cmd *cmd) return ret; } -int iwl_mvm_send_cmd_pdu(struct iwl_mvm *mvm, u32 id, - u32 flags, u16 len, const void *data) +int _iwl_mvm_send_cmd_pdu(struct iwl_mvm *mvm, u32 id, + u32 flags, u16 len, const void *data) { struct iwl_host_cmd cmd = { .id = id, @@ -137,8 +137,8 @@ int iwl_mvm_send_cmd_status(struct iwl_mvm *mvm, struct iwl_host_cmd *cmd, /* * We assume that the caller set the status to the sucess value */ -int iwl_mvm_send_cmd_pdu_status(struct iwl_mvm *mvm, u32 id, u16 len, - const void *data, u32 *status) +int _iwl_mvm_send_cmd_pdu_status(struct iwl_mvm *mvm, u32 id, u16 len, + const void *data, u32 *status) { struct iwl_host_cmd cmd = { .id = id, From 1e749bd58e556f69a0251cfc8cd110b986f641f0 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 14 Jul 2026 17:02:05 +0300 Subject: [PATCH 08/46] wifi: iwlwifi: mvm: remove iwl_mvm_recalc_tcm() This function is only called in the worker, so it doesn't need to exist at all, simply move the code there. Signed-off-by: Johannes Berg Link: https://patch.msgid.link/20260714165826.dd9f49714128.I65fbe6890d67ec424d333c362aa7041a117aed44@changeid Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 1 - drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 16 +++++----------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 1b56a2695bde..4420005ef69e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -2412,7 +2412,6 @@ bool iwl_mvm_is_vif_assoc(struct iwl_mvm *mvm); #define MVM_TCM_PERIOD (HZ * MVM_TCM_PERIOD_MSEC / 1000) #define MVM_LL_PERIOD (10 * HZ) void iwl_mvm_tcm_work(struct work_struct *work); -void iwl_mvm_recalc_tcm(struct iwl_mvm *mvm); void iwl_mvm_pause_tcm(struct iwl_mvm *mvm, bool with_cancel); void iwl_mvm_resume_tcm(struct iwl_mvm *mvm); void iwl_mvm_tcm_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index 849342c96ae7..7eae10982869 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c @@ -1055,7 +1055,7 @@ static unsigned long iwl_mvm_calc_tcm_stats(struct iwl_mvm *mvm, /* * If the current load isn't low we need to force re-evaluation * in the TCM period, so that we can return to low load if there - * was no traffic at all (and thus iwl_mvm_recalc_tcm didn't get + * was no traffic at all (and thus iwl_mvm_tcm_work() didn't get * triggered by traffic). */ if (load != IWL_MVM_TRAFFIC_LOW) @@ -1081,8 +1081,11 @@ static unsigned long iwl_mvm_calc_tcm_stats(struct iwl_mvm *mvm, return 0; } -void iwl_mvm_recalc_tcm(struct iwl_mvm *mvm) +void iwl_mvm_tcm_work(struct work_struct *work) { + struct delayed_work *delayed_work = to_delayed_work(work); + struct iwl_mvm *mvm = container_of(delayed_work, struct iwl_mvm, + tcm.work); unsigned long ts = jiffies; bool handle_uapsd = time_after(ts, mvm->tcm.uapsd_nonagg_ts + @@ -1119,15 +1122,6 @@ void iwl_mvm_recalc_tcm(struct iwl_mvm *mvm) iwl_mvm_tcm_results(mvm); } -void iwl_mvm_tcm_work(struct work_struct *work) -{ - struct delayed_work *delayed_work = to_delayed_work(work); - struct iwl_mvm *mvm = container_of(delayed_work, struct iwl_mvm, - tcm.work); - - iwl_mvm_recalc_tcm(mvm); -} - void iwl_mvm_pause_tcm(struct iwl_mvm *mvm, bool with_cancel) { spin_lock_bh(&mvm->tcm.lock); From 6800559a1042bfef9985b400f9dd971650d122f4 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 14 Jul 2026 17:02:06 +0300 Subject: [PATCH 09/46] wifi: iwlwifi: claim UHR DBE capability for UHR devices When an Intel device supports UHR it also supports DBE (dynamic bandwidth extension) since that's handled in mac80211. Claim support for it for client mode. Signed-off-by: Johannes Berg Link: https://patch.msgid.link/20260714165826.435828046f11.I538b2d90a4c282118ca2e56292cf5615d477a44c@changeid Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c index d47b4ae2f486..761424812609 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c @@ -699,7 +699,8 @@ static const struct ieee80211_sband_iftype_data iwl_iftype_cap[] = { .mac.mac_cap = { [0] = IEEE80211_UHR_MAC_CAP0_NPCA_SUPP | IEEE80211_UHR_MAC_CAP0_DPS_SUPP, - [1] = IEEE80211_UHR_MAC_CAP1_DUO_SUPP, + [1] = IEEE80211_UHR_MAC_CAP1_DUO_SUPP | + IEEE80211_UHR_MAC_CAP1_DBE_SUPP, }, }, }, From 3bff0d12c36247073fca976498b58a940fca72dc Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Tue, 14 Jul 2026 17:02:07 +0300 Subject: [PATCH 10/46] wifi: iwlwifi: support TTL platform device ID Add support for a new device ID that we will have on TTL (sc2). Reviewed-by: Johannes Berg Link: https://patch.msgid.link/20260714165826.46183446954f.Icc260831e530c1c92c9be615a7077768b1b9ae30@changeid Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 7a7b10152e5a..a3e6c9e09a3b 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -548,6 +548,7 @@ VISIBLE_IF_IWLWIFI_KUNIT const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0xD340, PCI_ANY_ID, iwl_sc_mac_cfg)}, {IWL_PCI_DEVICE(0x6E70, PCI_ANY_ID, iwl_sc_mac_cfg)}, {IWL_PCI_DEVICE(0xD240, PCI_ANY_ID, iwl_sc_mac_cfg)}, + {IWL_PCI_DEVICE(0x9327, PCI_ANY_ID, iwl_sc_mac_cfg)}, #endif /* CONFIG_IWLMVM || CONFIG_IWLMLD */ {0} From 9119aeeddc210cdfce0537de3ea3bab9316b2589 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 14 Jul 2026 17:02:08 +0300 Subject: [PATCH 11/46] wifi: iwlwifi: mvm: fix the FCS truncation logic in d3 Fix a harmless mistake in the wake packet management code in the d3 wakeup flow. If the FCS is truncated, we want to detect it, but we cleared the icvlen before updating the truncated variable that holds the number of bytes having been truncated. Fix that. Signed-off-by: Emmanuel Grumbach Link: https://patch.msgid.link/20260714165826.a7d094168ed3.I1a4d13f276c7e75514ab2032ae387873337470b8@changeid Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 9a74f60c9185..d7ceb385ae0b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -1539,8 +1539,8 @@ static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm, /* if truncated, FCS/ICV is (partially) gone */ if (truncated >= icvlen) { - icvlen = 0; truncated -= icvlen; + icvlen = 0; } else { icvlen -= truncated; truncated = 0; From 68f7d05494403ce89eba2b5476b2cd9ac03041db Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 14 Jul 2026 17:02:09 +0300 Subject: [PATCH 12/46] wifi: iwlwifi: mld: treat valid BAID without STA as a FW error Somehow, the firmware sometimes seems to have a valid BAID even if the ieee80211_sta was not found. This happens in sniffer mode. Treat those as a firmware error. Signed-off-by: Emmanuel Grumbach Link: https://patch.msgid.link/20260714165826.4902f73de145.I2cec7133f2a2ec8c39dcfb36938aba2ea3d6be24@changeid Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/mld/agg.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mld/agg.c b/drivers/net/wireless/intel/iwlwifi/mld/agg.c index e3627ad0321c..1aa30d2e8133 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/agg.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/agg.c @@ -200,11 +200,11 @@ iwl_mld_reorder(struct iwl_mld *mld, struct napi_struct *napi, struct iwl_mld_baid_data *baid_data; struct iwl_mld_reorder_buffer *buffer; struct iwl_mld_reorder_buf_entry *entries; - struct iwl_mld_sta *mld_sta = iwl_mld_sta_from_mac80211(sta); struct iwl_mld_link_sta *mld_link_sta; u32 reorder = le32_to_cpu(desc->reorder_data); bool amsdu, last_subframe, is_old_sn, is_dup; u8 tid = ieee80211_get_tid(hdr); + struct iwl_mld_sta *mld_sta; u8 baid; u16 nssn, sn; u32 sta_mask = 0; @@ -223,10 +223,13 @@ iwl_mld_reorder(struct iwl_mld *mld, struct napi_struct *napi, return IWL_MLD_PASS_SKB; /* no sta yet */ - if (WARN_ONCE(!sta, - "Got valid BAID without a valid station assigned\n")) + if (IWL_FW_CHECK(mld, !sta, + "Got valid BAID without a valid station assigned - %d\n", + baid)) return IWL_MLD_PASS_SKB; + mld_sta = iwl_mld_sta_from_mac80211(sta); + /* not a data packet */ if (!ieee80211_is_data_qos(hdr->frame_control) || is_multicast_ether_addr(hdr->addr1)) From 21b3263b90e8006d488894e8a71c8debf45f6b88 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 14 Jul 2026 17:02:10 +0300 Subject: [PATCH 13/46] wifi: iwlwifi: mvm: validate monitor notif link_id MONITOR_NOTIF link_id is firmware-provided. Validate link_id range with IWL_FW_CHECK before vif lookup. Payload length is already checked by RX_HANDLER. Use iwl_mvm_rcu_dereference_vif_id which does all we need which allows us to drop iwl_mvm_get_vif_by_macid. Assisted-by: GitHubCopilot:gpt-5.3-codex Signed-off-by: Emmanuel Grumbach Link: https://patch.msgid.link/20260714165826.7601d05649a4.I237f58a007af761468057c9c09039953a3bb37da@changeid Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 1 - drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 4 +-- .../net/wireless/intel/iwlwifi/mvm/utils.c | 30 ------------------- 3 files changed, 2 insertions(+), 33 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 4420005ef69e..979b39314981 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -2405,7 +2405,6 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm, bool sync, const void *data, u32 size); struct ieee80211_vif *iwl_mvm_get_bss_vif(struct iwl_mvm *mvm); -struct ieee80211_vif *iwl_mvm_get_vif_by_macid(struct iwl_mvm *mvm, u32 macid); bool iwl_mvm_is_vif_assoc(struct iwl_mvm *mvm); #define MVM_TCM_PERIOD_MSEC 500 diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 2297392db955..f43895c2f3c6 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -155,8 +155,8 @@ static void iwl_mvm_rx_monitor_notif(struct iwl_mvm *mvm, if (notif->type != cpu_to_le32(IWL_DP_MON_NOTIF_TYPE_EXT_CCA)) return; - /* FIXME: should fetch the link and not the vif */ - vif = iwl_mvm_get_vif_by_macid(mvm, notif->link_id); + /* mac_id = link_id since we don't support MLO */ + vif = iwl_mvm_rcu_dereference_vif_id(mvm, notif->link_id, false); if (!vif || vif->type != NL80211_IFTYPE_STATION) return; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index 7eae10982869..2fd4a9961145 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c @@ -689,36 +689,6 @@ struct ieee80211_vif *iwl_mvm_get_bss_vif(struct iwl_mvm *mvm) return bss_iter_data.vif; } -struct iwl_bss_find_iter_data { - struct ieee80211_vif *vif; - u32 macid; -}; - -static void iwl_mvm_bss_find_iface_iterator(void *_data, u8 *mac, - struct ieee80211_vif *vif) -{ - struct iwl_bss_find_iter_data *data = _data; - struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - - if (mvmvif->id == data->macid) - data->vif = vif; -} - -struct ieee80211_vif *iwl_mvm_get_vif_by_macid(struct iwl_mvm *mvm, u32 macid) -{ - struct iwl_bss_find_iter_data data = { - .macid = macid, - }; - - lockdep_assert_held(&mvm->mutex); - - ieee80211_iterate_active_interfaces_atomic( - mvm->hw, IEEE80211_IFACE_ITER_NORMAL, - iwl_mvm_bss_find_iface_iterator, &data); - - return data.vif; -} - struct iwl_sta_iter_data { bool assoc; }; From c99bc4d4e0ba6f4661b2b914c96a597d26e7cc05 Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Tue, 14 Jul 2026 17:02:11 +0300 Subject: [PATCH 14/46] wifi: iwlwifi: mld: cancel wiphy work before freeing wiphy When we fail to load the fw during op-mode start, we purge the list of the async handlers but we don't cancel the work. Same when we stop the op-mode. Before freeing wiphy, we need to cancel/flush any pending wiphy work, otherwise the work will fire with a freed memory. cfg80211 will do it anyway, but it will warn. Cancel the work in those cases. Reviewed-by: Johannes Berg Link: https://patch.msgid.link/20260714165826.07aa49f755a2.I734a27b1b0eeb5b0e821aee3318fee8dc0a6bc03@changeid Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/mld/mld.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mld.c b/drivers/net/wireless/intel/iwlwifi/mld/mld.c index 78c78cf891cd..5a6c9ab20fd6 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mld.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/mld.c @@ -446,6 +446,8 @@ iwl_op_mode_mld_start(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg, } if (ret) { + /* wiphy memory is about to be freed, we should cancel any pending work */ + wiphy_work_cancel(mld->wiphy, &mld->async_handlers_wk); wiphy_unlock(mld->wiphy); rtnl_unlock(); goto err; @@ -511,6 +513,7 @@ iwl_op_mode_mld_stop(struct iwl_op_mode *op_mode) iwl_mld_thermal_exit(mld); wiphy_lock(mld->wiphy); + wiphy_work_cancel(mld->wiphy, &mld->async_handlers_wk); iwl_mld_low_latency_stop(mld); iwl_mld_deinit_time_sync(mld); wiphy_unlock(mld->wiphy); From 4e777dcdfe70d9b3ddf38cb49de9e30306889b18 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 14 Jul 2026 17:02:12 +0300 Subject: [PATCH 15/46] wifi: iwlwifi: mld: validate D3_END notif size Check D3_END_NOTIFICATION payload length before reading notif->flags. On short payloads, mark notif handling as failed. Avoid out-of-bounds reads from malformed notifications. Assisted-by: GitHubCopilot:gpt-5.3-codex Signed-off-by: Emmanuel Grumbach Link: https://patch.msgid.link/20260714165826.db2df8b6b6bb.I6163bbdf433379bf1dbf9eb46fb9562892217bd7@changeid Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/mld/d3.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mld/d3.c b/drivers/net/wireless/intel/iwlwifi/mld/d3.c index 458a668ba916..b5fed6090340 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/d3.c @@ -1449,8 +1449,16 @@ static bool iwl_mld_handle_d3_notif(struct iwl_notif_wait_data *notif_wait, } case WIDE_ID(PROT_OFFLOAD_GROUP, D3_END_NOTIFICATION): { struct iwl_d3_end_notif *notif = (void *)pkt->data; + u32 len = iwl_rx_packet_payload_len(pkt); + + if (IWL_FW_CHECK(mld, len < sizeof(*notif), + "Invalid D3_END notification (expected=%zu got=%u)\n", + sizeof(*notif), len)) { + resume_data->notif_handling_err = true; + } else { + resume_data->d3_end_flags = le32_to_cpu(notif->flags); + } - resume_data->d3_end_flags = le32_to_cpu(notif->flags); resume_data->notifs_received |= IWL_D3_NOTIF_D3_END_NOTIF; break; } From 5826799a26fd1c7dd954f6386a49e9fad747f21f Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 14 Jul 2026 17:02:13 +0300 Subject: [PATCH 16/46] wifi: iwlwifi: pcie: validate txq_id in txq_enable Avoid indexing txq arrays and queue-used bitmaps with an invalid queue ID by adding an early bounds check in iwl_trans_pcie_txq_enable(). Assisted-by: GitHubCopilot:gpt-5.3-codex Signed-off-by: Emmanuel Grumbach Link: https://patch.msgid.link/20260714165826.273be072f5ff.I0d6c36a4c06bdbb4655164c7792da32b6143731e@changeid Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/tx.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/tx.c index fdb3ba4f63c0..dc2fe0c4f68c 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/tx.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2003-2014, 2018-2021, 2023-2025 Intel Corporation + * Copyright (C) 2003-2014, 2018-2021, 2023-2026 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -1149,10 +1149,17 @@ bool iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn, unsigned int wdg_timeout) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_txq *txq = trans_pcie->txqs.txq[txq_id]; + struct iwl_txq *txq; int fifo = -1; bool scd_bug = false; + if (WARN_ONCE(txq_id < 0 || + txq_id >= trans->mac_cfg->base->num_of_queues, + "queue %d out of range", txq_id)) + return false; + + txq = trans_pcie->txqs.txq[txq_id]; + if (test_and_set_bit(txq_id, trans_pcie->txqs.queue_used)) WARN_ONCE(1, "queue %d already used - expect issues", txq_id); From 678148622fa8e5a118784fa3fcb9bd1876b8322a Mon Sep 17 00:00:00 2001 From: Pagadala Yesu Anjaneyulu Date: Tue, 14 Jul 2026 17:02:14 +0300 Subject: [PATCH 17/46] wifi: iwlwifi: ignore raw-DSM TLV for LARI cmd version 13 and above LARI_CONFIG_CHANGE command version 13 and above accepts raw DSM values by default in firmware, so FW_ACCEPTS_RAW_DSM_TABLE should not gate DSM bitmap handling for these versions. Set has_raw_dsm_capa based on command version (version 13 and above is true) with TLV fallback for older command versions. Also update TLV kernel-doc to mark this capability obsolete for LARI command version 13 and above. Signed-off-by: Pagadala Yesu Anjaneyulu Reviewed-by: Avinash Bhatt Link: https://patch.msgid.link/20260714165826.12c8b407e115.I6809041f1eb52b7fafe9172ca3e47323d43cc30a@changeid Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/fw/file.h | 5 +++-- .../net/wireless/intel/iwlwifi/mld/regulatory.c | 16 +++++++++++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index a26ed82a8106..664ac25754e9 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -448,8 +448,9 @@ typedef unsigned int __bitwise iwl_ucode_tlv_capa_t; * @IWL_UCODE_TLV_CAPA_EXT_FSEQ_IMAGE_SUPPORT: external FSEQ image support * @IWL_UCODE_TLV_CAPA_RESET_DURING_ASSERT: FW reset handshake is needed * during assert handling even if the dump isn't split - * @IWL_UCODE_TLV_CAPA_FW_ACCEPTS_RAW_DSM_TABLE: Firmware has capability of - * handling raw DSM table data. + * @IWL_UCODE_TLV_CAPA_FW_ACCEPTS_RAW_DSM_TABLE: Firmware can handle raw DSM + * table data. For LARI_CONFIG_CHANGE command version 13 and above, this + * capability is obsolete since raw DSM values are accepted by default. * @IWL_UCODE_TLV_CAPA_NAN_SYNC_SUPPORT: Supports NAN synchronization * * @NUM_IWL_UCODE_TLV_CAPA: number of bits used diff --git a/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c b/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c index 659243ada86c..858635607f5d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c @@ -325,8 +325,16 @@ void iwl_mld_configure_lari(struct iwl_mld *mld) struct iwl_lari_config_change_cmd cmd = { .config_bitmap = iwl_mld_get_lari_config_bitmap(fwrt), }; - bool has_raw_dsm_capa = fw_has_capa(&fwrt->fw->ucode_capa, - IWL_UCODE_TLV_CAPA_FW_ACCEPTS_RAW_DSM_TABLE); + u8 cmd_ver = iwl_fw_lookup_cmd_ver(mld->fw, + WIDE_ID(REGULATORY_AND_NVM_GROUP, + LARI_CONFIG_CHANGE), 12); + /* + * For LARI_CONFIG_CHANGE command version 13 and above, firmware accepts + * raw DSM values by default and this TLV is no longer needed. + */ + bool has_raw_dsm_capa = cmd_ver >= 13 || + fw_has_capa(&fwrt->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_FW_ACCEPTS_RAW_DSM_TABLE); int ret; u32 value; @@ -428,9 +436,7 @@ void iwl_mld_configure_lari(struct iwl_mld *mld) "sending LARI_CONFIG_CHANGE, oem_unii9_enable=0x%x\n", le32_to_cpu(cmd.oem_unii9_enable)); - if (iwl_fw_lookup_cmd_ver(mld->fw, - WIDE_ID(REGULATORY_AND_NVM_GROUP, - LARI_CONFIG_CHANGE), 12) == 12) { + if (cmd_ver == 12) { int cmd_size = offsetof(typeof(cmd), oem_11bn_allow_bitmap); ret = iwl_mld_send_cmd_pdu(mld, From 974cbad4c86d6442d9e08710322b924e4ae79023 Mon Sep 17 00:00:00 2001 From: Pagadala Yesu Anjaneyulu Date: Tue, 14 Jul 2026 17:02:15 +0300 Subject: [PATCH 18/46] wifi: iwlwifi: regulatory: add LARI_CONFIG_CHANGE command v14 support Add support for LARI_CONFIG_CHANGE version 14 and populate the newly added BIOS-related fields in the command payload. Extend the version 14 command layout with UHB extension, puncturing and WBEM metadata fields, update command-size handling for version negotiation, and wire the new data into the LARI configuration flow. Track WBEM and puncturing source/revision in fw runtime, set them when loading ACPI or UEFI tables, and pass the headers to firmware. Update send conditions, debug traces, and related documentation/comments to match the new format. Signed-off-by: Pagadala Yesu Anjaneyulu Link: https://patch.msgid.link/20260714165826.c73d2fbebbfe.I93af7c456f04ef10d03646a43aaeb1858ecdc36d@changeid Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/fw/acpi.c | 4 +- .../wireless/intel/iwlwifi/fw/api/nvm-reg.h | 15 ++++- .../net/wireless/intel/iwlwifi/fw/runtime.h | 13 +++- drivers/net/wireless/intel/iwlwifi/fw/uefi.c | 20 ++++--- drivers/net/wireless/intel/iwlwifi/fw/uefi.h | 4 +- drivers/net/wireless/intel/iwlwifi/mld/mcc.c | 2 +- drivers/net/wireless/intel/iwlwifi/mld/mld.c | 2 +- drivers/net/wireless/intel/iwlwifi/mld/mld.h | 2 - .../wireless/intel/iwlwifi/mld/regulatory.c | 60 ++++++++++++++----- 9 files changed, 88 insertions(+), 34 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c index bf0f851a9075..9f2f4a6af1ca 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* * Copyright (C) 2017 Intel Deutschland GmbH - * Copyright (C) 2019-2025 Intel Corporation + * Copyright (C) 2019-2026 Intel Corporation */ #include #include "iwl-drv.h" @@ -1188,6 +1188,8 @@ int iwl_acpi_get_wbem(struct iwl_fw_runtime *fwrt, u32 *value) *value = wifi_pkg->package.elements[1].integer.value & IWL_ACPI_WBEM_REV0_MASK; + fwrt->wbem_source = BIOS_SOURCE_ACPI; + fwrt->wbem_revision = tbl_rev; IWL_DEBUG_RADIO(fwrt, "Loaded WBEM config from ACPI\n"); ret = 0; out_free: diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h index 443a9a416325..d8ec9934a9b6 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2012-2014, 2018-2025 Intel Corporation + * Copyright (C) 2012-2014, 2018-2026 Intel Corporation * Copyright (C) 2013-2015 Intel Mobile Communications GmbH * Copyright (C) 2016-2017 Intel Deutschland GmbH */ @@ -662,6 +662,12 @@ struct iwl_lari_config_change_cmd_v8 { * get the data from the BIOS. * @oem_unii9_enable: UNII-9 enablement as read from the BIOS * @bios_hdr: bios config header + * @oem_uhb_allow_extension_bitmap: DSM Function 4 data as an extension of UHB + * enabled MCC sets + * @bios_wcpe_hdr: puncturing config header + * @wcpe_bitmap: bitmap of puncturing enablement per MCC + * @bios_wbem_hdr: 320 MHz per-MCC WBEM config header + * @reserved: reserved */ struct iwl_lari_config_change_cmd { __le32 config_bitmap; @@ -679,9 +685,16 @@ struct iwl_lari_config_change_cmd { __le32 oem_unii9_enable; /* since version 13 */ struct iwl_bios_config_hdr bios_hdr; + /* All the below are since version 14 */ + __le32 oem_uhb_allow_extension_bitmap; + struct iwl_bios_config_hdr bios_wcpe_hdr; + __le32 wcpe_bitmap; + struct iwl_bios_config_hdr bios_wbem_hdr; + __le32 reserved[10]; } __packed; /* LARI_CHANGE_CONF_CMD_S_VER_12 * LARI_CHANGE_CONF_CMD_S_VER_13 + * LARI_CHANGE_CONF_CMD_S_VER_14 */ /* Activate UNII-1 (5.2GHz) for World Wide */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h index d80ae610e56c..ac01ac0092ee 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* * Copyright (C) 2017 Intel Deutschland GmbH - * Copyright (C) 2018-2025 Intel Corporation + * Copyright (C) 2018-2026 Intel Corporation */ #ifndef __iwl_fw_runtime_h__ #define __iwl_fw_runtime_h__ @@ -144,6 +144,11 @@ struct iwl_txf_iter_data { * @tpc_enabled: TPC enabled * @dsm_source: one of &enum bios_source. UEFI, ACPI or NONE * @dsm_revision: the revision of the DSM table + * @wbem_source: one of &enum bios_source for the WBEM table + * @wbem_revision: the revision of the WBEM table + * @puncturing_source: one of &enum bios_source for the puncturing table + * @puncturing_revision: the revision of the puncturing table + * @bios_puncturing: per-country puncturing enablement bitmap from BIOS */ struct iwl_fw_runtime { struct iwl_trans *trans; @@ -226,6 +231,12 @@ struct iwl_fw_runtime { u32 dsm_funcs_valid; u32 dsm_values[DSM_FUNC_NUM_FUNCS]; #endif + + enum bios_source wbem_source; + u8 wbem_revision; + enum bios_source puncturing_source; + u8 puncturing_revision; + u32 bios_puncturing; }; void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans, diff --git a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c index 4cd36b42262c..01e495e24ebc 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright(c) 2021-2025 Intel Corporation + * Copyright(c) 2021-2026 Intel Corporation */ #include "iwl-drv.h" @@ -890,6 +890,8 @@ int iwl_uefi_get_wbem(struct iwl_fw_runtime *fwrt, u32 *value) goto out; } *value = data->wbem_320mhz_per_mcc & IWL_UEFI_WBEM_REV0_MASK; + fwrt->wbem_source = BIOS_SOURCE_UEFI; + fwrt->wbem_revision = data->revision; IWL_DEBUG_RADIO(fwrt, "Loaded WBEM config from UEFI\n"); out: kfree(data); @@ -976,29 +978,29 @@ int iwl_uefi_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func, int iwl_uefi_get_puncturing(struct iwl_fw_runtime *fwrt) { struct uefi_cnv_var_puncturing_data *data; - /* default value is not enabled if there is any issue in reading - * uefi variable or revision is not supported - */ - int puncturing = 0; + int ret = 0; data = iwl_uefi_get_verified_variable(fwrt->trans, IWL_UEFI_PUNCTURING_NAME, "UefiCnvWlanPuncturing", sizeof(*data), NULL); if (IS_ERR(data)) - return puncturing; + return -EINVAL; if (data->revision != IWL_UEFI_PUNCTURING_REVISION) { IWL_DEBUG_RADIO(fwrt, "Unsupported UEFI PUNCTURING rev:%d\n", data->revision); + ret = -EINVAL; } else { - puncturing = data->puncturing & IWL_UEFI_PUNCTURING_REV0_MASK; + fwrt->puncturing_source = BIOS_SOURCE_UEFI; + fwrt->puncturing_revision = data->revision; + fwrt->bios_puncturing = data->puncturing; IWL_DEBUG_RADIO(fwrt, "Loaded puncturing bits from UEFI: %d\n", - puncturing); + fwrt->bios_puncturing); } kfree(data); - return puncturing; + return ret; } IWL_EXPORT_SYMBOL(iwl_uefi_get_puncturing); diff --git a/drivers/net/wireless/intel/iwlwifi/fw/uefi.h b/drivers/net/wireless/intel/iwlwifi/fw/uefi.h index 474f06db4d43..386ca3744408 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/uefi.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/uefi.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright(c) 2021-2025 Intel Corporation + * Copyright(c) 2021-2026 Intel Corporation */ #ifndef __iwl_fw_uefi__ #define __iwl_fw_uefi__ @@ -275,8 +275,6 @@ enum iwl_uefi_cnv_puncturing_flags { IWL_UEFI_CNV_PUNCTURING_CANADA_EN_MSK = BIT(1), }; -#define IWL_UEFI_PUNCTURING_REV0_MASK (IWL_UEFI_CNV_PUNCTURING_USA_EN_MSK | \ - IWL_UEFI_CNV_PUNCTURING_CANADA_EN_MSK) /** * struct uefi_cnv_var_puncturing_data - controlling channel * puncturing for few countries. diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mcc.c b/drivers/net/wireless/intel/iwlwifi/mld/mcc.c index 8502129abe49..7649ae794dfd 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mcc.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/mcc.c @@ -131,7 +131,7 @@ iwl_mld_get_regdomain(struct iwl_mld *mld, /* FM follows BIOS/MCC policy, WH disallows puncturing only in US/CA. */ if (CSR_HW_RFID_TYPE(mld->trans->info.hw_rf_id) == IWL_CFG_RF_TYPE_FM) { - if (!iwl_puncturing_is_allowed_in_bios(mld->bios_enable_puncturing, + if (!iwl_puncturing_is_allowed_in_bios(mld->fwrt.bios_puncturing, le16_to_cpu(resp->mcc))) ieee80211_hw_set(mld->hw, DISALLOW_PUNCTURING); else diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mld.c b/drivers/net/wireless/intel/iwlwifi/mld/mld.c index 5a6c9ab20fd6..99506f354bfa 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mld.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/mld.c @@ -419,7 +419,7 @@ iwl_op_mode_mld_start(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg, iwl_mld_get_bios_tables(mld); iwl_uefi_get_sgom_table(trans, &mld->fwrt); - mld->bios_enable_puncturing = iwl_uefi_get_puncturing(&mld->fwrt); + iwl_uefi_get_puncturing(&mld->fwrt); iwl_mld_hw_set_regulatory(mld); diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mld.h b/drivers/net/wireless/intel/iwlwifi/mld/mld.h index 922aa3dbff54..37f41b504b54 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mld.h +++ b/drivers/net/wireless/intel/iwlwifi/mld/mld.h @@ -172,7 +172,6 @@ * @debug_max_sleep: maximum sleep time in D3 (for debug purposes) * @led: the led device * @mcc_src: the source id of the MCC, comes from the firmware - * @bios_enable_puncturing: is puncturing enabled by bios * @fw_id_to_ba: maps a fw (BA) id to a corresponding Block Ack session data. * @num_rx_ba_sessions: tracks the number of active Rx Block Ack (BA) sessions. * the driver ensures that new BA sessions are blocked once the maximum @@ -279,7 +278,6 @@ struct iwl_mld { struct led_classdev led; #endif enum iwl_mcc_source mcc_src; - bool bios_enable_puncturing; struct iwl_mld_baid_data __rcu *fw_id_to_ba[IWL_MAX_BAID]; u8 num_rx_ba_sessions; diff --git a/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c b/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c index 858635607f5d..4a93ccbef495 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c @@ -13,6 +13,23 @@ #include "mld.h" #include "hcmd.h" +static ssize_t iwl_mld_get_lari_config_cmd_size(u8 cmd_ver) +{ + switch (cmd_ver) { + case 14: + return sizeof(struct iwl_lari_config_change_cmd); + case 13: + return offsetof(struct iwl_lari_config_change_cmd, + oem_uhb_allow_extension_bitmap); + case 12: + return offsetof(struct iwl_lari_config_change_cmd, + oem_11bn_allow_bitmap); + default: + WARN(true, "unsupported version: %d", cmd_ver); + return -EINVAL; + } +} + void iwl_mld_get_bios_tables(struct iwl_mld *mld) { int ret; @@ -335,9 +352,13 @@ void iwl_mld_configure_lari(struct iwl_mld *mld) bool has_raw_dsm_capa = cmd_ver >= 13 || fw_has_capa(&fwrt->fw->ucode_capa, IWL_UCODE_TLV_CAPA_FW_ACCEPTS_RAW_DSM_TABLE); + ssize_t cmd_len = iwl_mld_get_lari_config_cmd_size(cmd_ver); int ret; u32 value; + if (cmd_len < 0) + return; + ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_11AX_ENABLEMENT, &value); if (!ret) { if (!has_raw_dsm_capa) @@ -379,8 +400,11 @@ void iwl_mld_configure_lari(struct iwl_mld *mld) } ret = iwl_bios_get_wbem(fwrt, &value); - if (!ret) + if (!ret) { cmd.oem_320mhz_allow_bitmap = cpu_to_le32(value); + cmd.bios_wbem_hdr.table_source = fwrt->wbem_source; + cmd.bios_wbem_hdr.table_revision = fwrt->wbem_revision; + } ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_11BE, &value); if (!ret) @@ -394,8 +418,17 @@ void iwl_mld_configure_lari(struct iwl_mld *mld) if (!ret) cmd.oem_unii9_enable = cpu_to_le32(value); + ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_REGULATORY_CONFIG, &value); + if (!ret) + cmd.oem_uhb_allow_extension_bitmap = cpu_to_le32(value); + + cmd.bios_wcpe_hdr.table_source = fwrt->puncturing_source; + cmd.bios_wcpe_hdr.table_revision = fwrt->puncturing_revision; + cmd.wcpe_bitmap = cpu_to_le32(fwrt->bios_puncturing); + if (!cmd.config_bitmap && !cmd.oem_uhb_allow_bitmap && + !cmd.oem_uhb_allow_extension_bitmap && !cmd.oem_11ax_allow_bitmap && !cmd.oem_unii4_allow_bitmap && !cmd.chan_state_active_bitmap && @@ -404,7 +437,8 @@ void iwl_mld_configure_lari(struct iwl_mld *mld) !cmd.oem_320mhz_allow_bitmap && !cmd.oem_11be_allow_bitmap && !cmd.oem_11bn_allow_bitmap && - !cmd.oem_unii9_enable) + !cmd.oem_unii9_enable && + !cmd.wcpe_bitmap) return; cmd.bios_hdr.table_source = fwrt->dsm_source; @@ -422,6 +456,9 @@ void iwl_mld_configure_lari(struct iwl_mld *mld) "sending LARI_CONFIG_CHANGE, oem_uhb_allow_bitmap=0x%x, force_disable_channels_bitmap=0x%x\n", le32_to_cpu(cmd.oem_uhb_allow_bitmap), le32_to_cpu(cmd.force_disable_channels_bitmap)); + IWL_DEBUG_RADIO(mld, + "sending LARI_CONFIG_CHANGE, oem_uhb_allow_extension_bitmap=0x%x\n", + le32_to_cpu(cmd.oem_uhb_allow_extension_bitmap)); IWL_DEBUG_RADIO(mld, "sending LARI_CONFIG_CHANGE, edt_bitmap=0x%x, oem_320mhz_allow_bitmap=0x%x\n", le32_to_cpu(cmd.edt_bitmap), @@ -435,20 +472,13 @@ void iwl_mld_configure_lari(struct iwl_mld *mld) IWL_DEBUG_RADIO(mld, "sending LARI_CONFIG_CHANGE, oem_unii9_enable=0x%x\n", le32_to_cpu(cmd.oem_unii9_enable)); + IWL_DEBUG_RADIO(mld, + "sending LARI_CONFIG_CHANGE, wcpe_bitmap=0x%x\n", + le32_to_cpu(cmd.wcpe_bitmap)); - if (cmd_ver == 12) { - int cmd_size = offsetof(typeof(cmd), oem_11bn_allow_bitmap); - - ret = iwl_mld_send_cmd_pdu(mld, - WIDE_ID(REGULATORY_AND_NVM_GROUP, - LARI_CONFIG_CHANGE), - &cmd, cmd_size); - } else { - ret = iwl_mld_send_cmd_pdu(mld, - WIDE_ID(REGULATORY_AND_NVM_GROUP, - LARI_CONFIG_CHANGE), - &cmd); - } + ret = iwl_mld_send_cmd_pdu(mld, + WIDE_ID(REGULATORY_AND_NVM_GROUP, + LARI_CONFIG_CHANGE), &cmd, cmd_len); if (ret) IWL_DEBUG_RADIO(mld, "Failed to send LARI_CONFIG_CHANGE (%d)\n", From a51cc8131214870af92abbceab64877b27e690c2 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 14 Jul 2026 17:02:16 +0300 Subject: [PATCH 19/46] wifi: iwlwifi: mvm: reset the smart fifo state upon FW stop The smart fifo is a feature in the firmware configured by the driver. The driver keeps a state to remember what was the last configuration sent to the firmware. Obviously, if the firmware stops, we need to reconfigure the smart fifo. Since we didn't reset that state upon firmware stop, we thought the firmware is already properly configured and we didn't send the smart fifo configuration command as part of the init sequence. Reset the smart fifo state in iwl_mvm_stop_device() so that we will properly send the command during the init that will come later. Signed-off-by: Emmanuel Grumbach Link: https://patch.msgid.link/20260714165826.7d3c5efe2d1a.I16b23c328a677257257f695fa6f439e41fbcd081@changeid Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index f43895c2f3c6..09150feb330d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -1535,6 +1535,7 @@ void iwl_mvm_stop_device(struct iwl_mvm *mvm) iwl_fw_cancel_timestamp(&mvm->fwrt); clear_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, &mvm->status); + mvm->sf_state = SF_UNINIT; iwl_mvm_pause_tcm(mvm, false); From 0a00c3ec2db7674483dece4863f105b18a966202 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 14 Jul 2026 17:02:17 +0300 Subject: [PATCH 20/46] wifi: iwlwifi: mvm: cleanup the driver state after device_powered_off If the device was powered off during suspend, we need to reload the firmware in resume which also means that we need to reconfigure it. It could be tempting to just set IWL_MVM_STATUS_HW_RESTART_REQUESTED but that would leave IWL_MVM_STATUS_IN_HW_RESTART set forever since that recovery is not managed by mac80211. Just call iwl_mvm_restart_cleanup() from device_powered_off(). Signed-off-by: Emmanuel Grumbach Link: https://patch.msgid.link/20260714165826.dc33533ac962.I6d7cca9c4e5643a477eae1d0a4f5fc83a10d0ee7@changeid Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 1 + drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 74bd4038fd56..fd2a50563ab5 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -1129,7 +1129,7 @@ static void iwl_mvm_cleanup_iterator(void *data, u8 *mac, RCU_INIT_POINTER(mvmvif->deflink.probe_resp_data, NULL); } -static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) +void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) { iwl_mvm_stop_device(mvm); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 979b39314981..d6bed2c08606 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1660,6 +1660,7 @@ void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags, u8 iwl_mvm_rate_idx_to_fw_idx(const struct iwl_fw *fw, int rate_idx); u8 iwl_mvm_mac80211_ac_to_ucode_ac(enum ieee80211_ac_numbers ac); bool iwl_mvm_is_nic_ack_enabled(struct iwl_mvm *mvm, struct ieee80211_vif *vif); +void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm); static inline void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm) { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 09150feb330d..6ae9f87d5221 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -2091,7 +2091,7 @@ static void iwl_op_mode_mvm_device_powered_off(struct iwl_op_mode *op_mode) mutex_lock(&mvm->mutex); clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status); - iwl_mvm_stop_device(mvm); + iwl_mvm_restart_cleanup(mvm); mvm->fast_resume = false; mutex_unlock(&mvm->mutex); } From 71ac392d8b5c23c45c66f30eff1c319580ada4da Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 14 Jul 2026 17:02:18 +0300 Subject: [PATCH 21/46] wifi: iwlwifi: mld: reset the driver state upon firmware recovery Just like we did in iwlmvm, we also need to clear the mld state when the firmware was killed because of the device being powered off during suspend. Signed-off-by: Emmanuel Grumbach Link: https://patch.msgid.link/20260714165826.ff1c9e05e0a9.I8df8d4a0384065fd2a32cf258339be77084c55bd@changeid Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/mld/mac80211.c | 3 +-- drivers/net/wireless/intel/iwlwifi/mld/mac80211.h | 2 ++ drivers/net/wireless/intel/iwlwifi/mld/mld.c | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c index 17286b3341c0..4065d8e4fa8c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c @@ -543,8 +543,7 @@ iwl_mld_mac80211_tx(struct ieee80211_hw *hw, iwl_mld_tx_skb(mld, skb, NULL); } -static void -iwl_mld_restart_cleanup(struct iwl_mld *mld) +void iwl_mld_restart_cleanup(struct iwl_mld *mld) { iwl_cleanup_mld(mld); diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.h b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.h index aad04d7b2617..f3302997b28f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.h +++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* * Copyright (C) 2024 Intel Corporation + * Copyright (C) 2026 Intel Corporation */ #ifndef __iwl_mld_mac80211_h__ #define __iwl_mld_mac80211_h__ @@ -9,5 +10,6 @@ int iwl_mld_register_hw(struct iwl_mld *mld); void iwl_mld_recalc_multicast_filter(struct iwl_mld *mld); +void iwl_mld_restart_cleanup(struct iwl_mld *mld); #endif /* __iwl_mld_mac80211_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mld.c b/drivers/net/wireless/intel/iwlwifi/mld/mld.c index 99506f354bfa..093bdc130704 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mld.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/mld.c @@ -748,6 +748,7 @@ static void iwl_mld_device_powered_off(struct iwl_op_mode *op_mode) wiphy_lock(mld->wiphy); iwl_mld_stop_fw(mld); + iwl_mld_restart_cleanup(mld); mld->fw_status.in_d3 = false; wiphy_unlock(mld->wiphy); } From ef704fc32ae1a519801ac4a06aa290fece5f403c Mon Sep 17 00:00:00 2001 From: Avraham Stern Date: Wed, 15 Jul 2026 22:04:17 +0300 Subject: [PATCH 22/46] wifi: iwlwifi: mld: support aborting an ongoing ftm request Add support for aborting an ongoing FTM request. Signed-off-by: Avraham Stern Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20260715220243.340040bdc6a3.Ifbbf70021e42bf1d59db6ec45a73f1806a1c2289@changeid --- .../intel/iwlwifi/mld/ftm-initiator.c | 21 +++++++++++++++++++ .../intel/iwlwifi/mld/ftm-initiator.h | 1 + .../net/wireless/intel/iwlwifi/mld/mac80211.c | 10 +++++++++ 3 files changed, 32 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mld/ftm-initiator.c b/drivers/net/wireless/intel/iwlwifi/mld/ftm-initiator.c index 81df3fdfcbf5..a4b8037b5c76 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/ftm-initiator.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/ftm-initiator.c @@ -459,3 +459,24 @@ void iwl_mld_ftm_restart_cleanup(struct iwl_mld *mld) mld->ftm_initiator.req, GFP_KERNEL); iwl_mld_ftm_reset(mld); } + +void iwl_mld_ftm_abort(struct iwl_mld *mld, struct cfg80211_pmsr_request *req) +{ + struct iwl_tof_range_abort_cmd cmd = { + .request_id = req->cookie, + }; + + lockdep_assert_wiphy(mld->wiphy); + + if (req != mld->ftm_initiator.req) + return; + + if (iwl_mld_send_cmd_pdu(mld, WIDE_ID(LOCATION_GROUP, + TOF_RANGE_ABORT_CMD), + &cmd)) + IWL_ERR(mld, "failed to abort FTM process\n"); + + iwl_mld_cancel_notifications_of_object(mld, IWL_MLD_OBJECT_TYPE_FTM_REQ, + mld->ftm_initiator.req->cookie); + iwl_mld_ftm_reset(mld); +} diff --git a/drivers/net/wireless/intel/iwlwifi/mld/ftm-initiator.h b/drivers/net/wireless/intel/iwlwifi/mld/ftm-initiator.h index 3fab25a52508..e82237b31467 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/ftm-initiator.h +++ b/drivers/net/wireless/intel/iwlwifi/mld/ftm-initiator.h @@ -25,5 +25,6 @@ int iwl_mld_ftm_start(struct iwl_mld *mld, struct ieee80211_vif *vif, void iwl_mld_handle_ftm_resp_notif(struct iwl_mld *mld, struct iwl_rx_packet *pkt); void iwl_mld_ftm_restart_cleanup(struct iwl_mld *mld); +void iwl_mld_ftm_abort(struct iwl_mld *mld, struct cfg80211_pmsr_request *req); #endif /* __iwl_mld_ftm_initiator_h__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c index 4065d8e4fa8c..17922ed3800d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c @@ -2852,6 +2852,15 @@ static int iwl_mld_start_pmsr(struct ieee80211_hw *hw, return iwl_mld_ftm_start(mld, vif, request); } +static void iwl_mld_abort_pmsr(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct cfg80211_pmsr_request *request) +{ + struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); + + iwl_mld_ftm_abort(mld, request); +} + static enum ieee80211_neg_ttlm_res iwl_mld_can_neg_ttlm(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_neg_ttlm *neg_ttlm) @@ -2973,6 +2982,7 @@ const struct ieee80211_ops iwl_mld_hw_ops = { .prep_add_interface = iwl_mld_prep_add_interface, .set_hw_timestamp = iwl_mld_set_hw_timestamp, .start_pmsr = iwl_mld_start_pmsr, + .abort_pmsr = iwl_mld_abort_pmsr, .can_neg_ttlm = iwl_mld_can_neg_ttlm, .start_nan = iwl_mld_start_nan, .stop_nan = iwl_mld_stop_nan, From 7e16dad5d47e29338db9effbeb26b4e8bcfbc2c0 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 15 Jul 2026 22:04:18 +0300 Subject: [PATCH 23/46] wifi: iwlwifi: mld: validate WoWLAN notif header Validate fixed wowlan_info_notif header size first. Only then read num_mlo_link_keys from pkt->data. Apply this to v5 and v6 parsing paths. Assisted-by: GitHubCopilot:gpt-5.3-codex Signed-off-by: Emmanuel Grumbach Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20260715220243.9c33c20194ad.I691d019927cc56898f2516fcf5795c8b1fae362c@changeid --- drivers/net/wireless/intel/iwlwifi/mld/d3.c | 57 ++++++++++++++------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mld/d3.c b/drivers/net/wireless/intel/iwlwifi/mld/d3.c index b5fed6090340..c9c0e3c729c9 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/d3.c @@ -573,18 +573,42 @@ iwl_mld_convert_wowlan_notif_v5(const struct iwl_wowlan_info_notif_v5 *notif_v5, } } -static bool iwl_mld_validate_wowlan_notif_size(struct iwl_mld *mld, - u32 len, - u32 expected_len, - u8 num_mlo_keys, +static bool iwl_mld_validate_wowlan_notif_size(struct iwl_mld *mld, u32 len, + const void *notif_data, int version) { u32 len_with_mlo_keys; + u32 expected_len; + u8 num_mlo_keys; - if (IWL_FW_CHECK(mld, len < expected_len, - "Invalid wowlan_info_notif v%d (expected=%u got=%u)\n", - version, expected_len, len)) + /* Extract num_mlo_keys from the void pointer based on version */ + if (version == 5) { + const struct iwl_wowlan_info_notif_v5 *notif_v5 = notif_data; + + expected_len = sizeof(*notif_v5); + + if (IWL_FW_CHECK(mld, len < expected_len, + "Invalid wowlan_info_notif v5 (expected=%u got=%u)\n", + expected_len, len)) + return false; + + num_mlo_keys = notif_v5->num_mlo_link_keys; + } else if (version == 6) { + const struct iwl_wowlan_info_notif *notif = notif_data; + + expected_len = sizeof(*notif); + + if (IWL_FW_CHECK(mld, len < expected_len, + "Invalid wowlan_info_notif v6 (expected=%u got=%u)\n", + expected_len, len)) + return false; + + num_mlo_keys = notif->num_mlo_link_keys; + } else { + IWL_WARN(mld, "Unsupported wowlan_info_notif version %d\n", + version); return false; + } len_with_mlo_keys = expected_len + (num_mlo_keys * sizeof(struct iwl_wowlan_mlo_gtk)); @@ -616,16 +640,14 @@ iwl_mld_handle_wowlan_info_notif(struct iwl_mld *mld, if (wowlan_info_ver == 5) { /* v5 format - validate before conversion */ - const struct iwl_wowlan_info_notif_v5 *notif_v5 = (void *)pkt->data; + const struct iwl_wowlan_info_notif_v5 *_notif = + (void *)pkt->data; - if (!iwl_mld_validate_wowlan_notif_size(mld, len, - sizeof(*notif_v5), - notif_v5->num_mlo_link_keys, - 5)) + if (!iwl_mld_validate_wowlan_notif_size(mld, len, _notif, 5)) return true; converted_notif = kzalloc_flex(*converted_notif, mlo_gtks, - notif_v5->num_mlo_link_keys, + _notif->num_mlo_link_keys, GFP_ATOMIC); if (!converted_notif) { IWL_ERR(mld, @@ -633,15 +655,12 @@ iwl_mld_handle_wowlan_info_notif(struct iwl_mld *mld, return true; } - iwl_mld_convert_wowlan_notif_v5(notif_v5, - converted_notif); + iwl_mld_convert_wowlan_notif_v5(_notif, converted_notif); notif = converted_notif; } else if (wowlan_info_ver == 6) { notif = (void *)pkt->data; - if (!iwl_mld_validate_wowlan_notif_size(mld, len, - sizeof(*notif), - notif->num_mlo_link_keys, - 6)) + + if (!iwl_mld_validate_wowlan_notif_size(mld, len, notif, 6)) return true; } else { /* smaller versions are not supported */ From bbe2d2fa8780a04dac8de0ecaa3895d3f3bc093e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 15 Jul 2026 22:04:19 +0300 Subject: [PATCH 24/46] wifi: iwlwifi: mvm/mld: fix PPE threshold debug print loop The loop should print all bandwidths, the extra * results in calculating the wrong ARRAY_SIZE() here (of the array inside the per-bandwidth, not the per-bandwidth array.) Fix that, and also clarify the array variable assignment. Signed-off-by: Johannes Berg Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20260715220243.5e1d3448bfca.I6919627382d46605b41b0c6a6f34deedfd45523c@changeid --- drivers/net/wireless/intel/iwlwifi/mld/sta.c | 5 ++--- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mld/sta.c b/drivers/net/wireless/intel/iwlwifi/mld/sta.c index e18d86f021dc..7957ac11b0cd 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/sta.c @@ -355,10 +355,9 @@ static void iwl_mld_fill_pkt_ext(struct iwl_mld *mld, for (int i = 0; i < MAX_HE_SUPP_NSS; i++) { for (int bw = 0; - bw < ARRAY_SIZE(*pkt_ext->pkt_ext_qam_th[i]); + bw < ARRAY_SIZE(pkt_ext->pkt_ext_qam_th[i]); bw++) { - u8 *qam_th = - &pkt_ext->pkt_ext_qam_th[i][bw][0]; + u8 *qam_th = pkt_ext->pkt_ext_qam_th[i][bw]; IWL_DEBUG_HT(mld, "PPE table: nss[%d] bw[%d] PPET8 = %d, PPET16 = %d\n", diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index fd2a50563ab5..14aec0bfd173 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -2352,10 +2352,9 @@ int iwl_mvm_set_sta_pkt_ext(struct iwl_mvm *mvm, int bw; for (bw = 0; - bw < ARRAY_SIZE(*pkt_ext->pkt_ext_qam_th[i]); + bw < ARRAY_SIZE(pkt_ext->pkt_ext_qam_th[i]); bw++) { - u8 *qam_th = - &pkt_ext->pkt_ext_qam_th[i][bw][0]; + u8 *qam_th = pkt_ext->pkt_ext_qam_th[i][bw]; IWL_DEBUG_HT(mvm, "PPE table: nss[%d] bw[%d] PPET8 = %d, PPET16 = %d\n", From 71e67b4b59337b2f9f4fef976a27de2dad7aabf2 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 15 Jul 2026 22:04:20 +0300 Subject: [PATCH 25/46] wifi: iwlwifi: fix counter type in iwl_fwrt_dump_error_logs The loop counter 'count' was declared as u8 while num_pc is u32. If firmware advertises more than 255 PC entries the counter wraps back to zero and the loop never terminates potentially causing an infinite loop or reading past the allocated pc_data array. Change the declaration to u32 to match num_pc. Fixes: 2b69d242e29b ("wifi: iwlwifi: fw: print PC register value instead of address") Assisted-by: GitHubCopilot:gpt-5.3-codex Signed-off-by: Emmanuel Grumbach Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20260715220243.a61c65f34e87.Ie5f1a7ca43e0cc5a0ddc8305b0448ddffc09cd18@changeid --- drivers/net/wireless/intel/iwlwifi/fw/dump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dump.c b/drivers/net/wireless/intel/iwlwifi/fw/dump.c index c2af66899a78..bbbf3669a555 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dump.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dump.c @@ -369,7 +369,7 @@ static void iwl_fwrt_dump_fseq_regs(struct iwl_fw_runtime *fwrt) void iwl_fwrt_dump_error_logs(struct iwl_fw_runtime *fwrt) { struct iwl_pc_data *pc_data; - u8 count; + u32 count; if (!iwl_trans_device_enabled(fwrt->trans)) { IWL_ERR(fwrt, From 405ff50b72db1dfb86d7502c3c84208779809ab2 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 15 Jul 2026 22:04:21 +0300 Subject: [PATCH 26/46] wifi: iwlwifi: mld: fix validation fallback in iwl_mld_notif_is_valid When a firmware notification version is not in the handler's size table, iwl_mld_notif_is_valid() falls back to comparing against the last known structure size but the comparison is wrong: 'return size < last_known_size' returns true (accept) for undersized payloads and false (reject) for payloads that are large enough. Instead of trying to accept notifications that are large enough, just refuse the notification. We shouldn't ever get a notification that is longer than what we expect. Assisted-by: GitHubCopilot:gpt-5.3-codex Signed-off-by: Emmanuel Grumbach Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20260715220243.e0b91efe689d.I7d7604be6819da263e9091370892e6b6f4c57913@changeid --- drivers/net/wireless/intel/iwlwifi/mld/notif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mld/notif.c b/drivers/net/wireless/intel/iwlwifi/mld/notif.c index 7574689e4088..b3a899828db9 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/notif.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/notif.c @@ -517,7 +517,7 @@ iwl_mld_notif_is_valid(struct iwl_mld *mld, struct iwl_rx_packet *pkt, handler->cmd_id, notif_ver, handler->sizes[handler->n_sizes - 1].ver); - return size < handler->sizes[handler->n_sizes - 1].size; + return false; } struct iwl_async_handler_entry { From f6a6c01cbc046f68e6916a7e047a1bc881c8c9ab Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 15 Jul 2026 22:04:22 +0300 Subject: [PATCH 27/46] wifi: iwlwifi: mvm: fix off-by-one in TXF key sanitiser iwl_mvm_frob_txf_key_iter() tracks the last matched byte position in loop variable 'i'. When a full key match is found (match == keylen), 'i' points at the last byte of the matched key. The memset start offset should therefore be i + 1 - keylen, not i - keylen; the current code zeroes one byte before the match and leaves the final key byte un-sanitised. Fixes: 12d60c1efc29 ("iwlwifi: mvm: scrub key material in firmware dumps") Assisted-by: GitHubCopilot:gpt-5.3-codex Signed-off-by: Emmanuel Grumbach Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20260715220243.355998ec4fbe.I40f3427657b897e911bdf4ebf8e494745508d126@changeid --- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 6ae9f87d5221..da4c67a91113 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -954,7 +954,7 @@ static void iwl_mvm_frob_txf_key_iter(struct ieee80211_hw *hw, } match++; if (match == keylen) { - memset(txf->buf + i - keylen, 0xAA, keylen); + memset(txf->buf + i + 1 - keylen, 0xAA, keylen); match = 0; } } From ad13072308f82a9aa2e68a135e70672454367d92 Mon Sep 17 00:00:00 2001 From: Pagadala Yesu Anjaneyulu Date: Wed, 15 Jul 2026 22:04:23 +0300 Subject: [PATCH 28/46] wifi: iwlwifi: mld: honor FW puncturing capability in MCC response New MCC response versions expose puncturing support directly in the regulatory capability flags. Propagate that information from NVM MCC parsing to MLD MCC handling and fall back to legacy FM/WH MCC-specific policy when puncturing status is unknown. Signed-off-by: Pagadala Yesu Anjaneyulu Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20260715220243.47d1389fa134.I5c7921d6e3c065e3962c5927991498c2d277fd8f@changeid --- .../wireless/intel/iwlwifi/iwl-nvm-parse.c | 30 ++++++++++++++++++- .../wireless/intel/iwlwifi/iwl-nvm-parse.h | 22 ++++++++++++-- drivers/net/wireless/intel/iwlwifi/mld/mcc.c | 24 ++++++++++----- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 2 +- 4 files changed, 67 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c index 761424812609..2f38eea42963 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c @@ -230,6 +230,18 @@ enum iwl_reg_capa_flags_v5 { REG_CAPA_V5_11BN_DISABLED = BIT(17), }; /* GEO_CHANNEL_CAPABILITIES_API_S_VER_4, 5 */ +/** + * enum iwl_reg_capa_flags_v6 - global capability flags, + * applicable from MCC response version 10 onwards. + * Response v6 includes all members of iwl_reg_capa_flags_v5; only v6-specific + * additions are listed here. + * @REG_CAPA_V6_EHT_PUNCTURING_ENABLED: EHT puncturing is enabled for this + * regulatory domain. + */ +enum iwl_reg_capa_flags_v6 { + REG_CAPA_V6_EHT_PUNCTURING_ENABLED = BIT(18), +}; /* GEO_CHANNEL_CAPABILITIES_API_S_VER_6 */ + /* * API v2 for reg_capa_flags is relevant from version 6 and onwards of the * MCC update command response. @@ -241,6 +253,11 @@ enum iwl_reg_capa_flags_v5 { */ #define REG_CAPA_V4_RESP_VER 8 +/* API v6 for reg_capa_flags is relevant from version 10 and onwards of the + * MCC update command response. + */ +#define REG_CAPA_V6_RESP_VER 10 + static inline void iwl_nvm_print_channel_flags(struct device *dev, u32 level, int chan, u32 flags) { @@ -1686,6 +1703,13 @@ static struct iwl_reg_capa iwl_get_reg_capa(u32 flags, u8 resp_ver) { struct iwl_reg_capa reg_capa = {}; + if (resp_ver >= REG_CAPA_V6_RESP_VER) { + if (flags & REG_CAPA_V6_EHT_PUNCTURING_ENABLED) + reg_capa.puncturing_status = IWL_PUNCTURING_STATUS_ENABLED; + else + reg_capa.puncturing_status = IWL_PUNCTURING_STATUS_DISABLED; + } + if (resp_ver >= REG_CAPA_V4_RESP_VER) { reg_capa.allow_40mhz = true; reg_capa.allow_80mhz = flags & REG_CAPA_V5_80MHZ_ALLOWED; @@ -1712,7 +1736,8 @@ static struct iwl_reg_capa iwl_get_reg_capa(u32 flags, u8 resp_ver) struct ieee80211_regdomain * iwl_parse_nvm_mcc_info(struct iwl_trans *trans, int num_of_ch, __le32 *channels, u16 fw_mcc, - u16 geo_info, u32 cap, u8 resp_ver) + u16 geo_info, u32 cap, u8 resp_ver, + enum iwl_puncturing_status *puncturing_status) { const struct iwl_rf_cfg *cfg = trans->cfg; struct device *dev = trans->dev; @@ -1772,6 +1797,9 @@ iwl_parse_nvm_mcc_info(struct iwl_trans *trans, /* parse regulatory capability flags */ reg_capa = iwl_get_reg_capa(cap, resp_ver); + if (puncturing_status) + *puncturing_status = reg_capa.puncturing_status; + for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) { enum nl80211_band band = iwl_nl80211_band_from_channel_idx(ch_idx); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h index e676d7c2d6cc..9ebb72d3726a 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2005-2015, 2018-2025 Intel Corporation + * Copyright (C) 2005-2015, 2018-2026 Intel Corporation * Copyright (C) 2016-2017 Intel Deutschland GmbH */ #ifndef __iwl_nvm_parse_h__ @@ -21,6 +21,19 @@ enum iwl_nvm_sbands_flags { IWL_NVM_SBANDS_FLAGS_NO_WIDE_IN_5GHZ = BIT(1), }; +/** + * enum iwl_puncturing_status - EHT puncturing status from MCC capabilities + * @IWL_PUNCTURING_STATUS_UNKNOWN: puncturing status is not provided by FW + * or is not initialized yet + * @IWL_PUNCTURING_STATUS_ENABLED: puncturing is enabled for the current MCC + * @IWL_PUNCTURING_STATUS_DISABLED: puncturing is disabled for the current MCC + */ +enum iwl_puncturing_status { + IWL_PUNCTURING_STATUS_UNKNOWN, + IWL_PUNCTURING_STATUS_ENABLED, + IWL_PUNCTURING_STATUS_DISABLED, +}; + /** * struct iwl_reg_capa - struct for global regulatory capabilities, Used for * handling the different APIs of reg_capa_flags. @@ -36,6 +49,8 @@ enum iwl_nvm_sbands_flags { * @disable_11ax: 11ax is forbidden for this regulatory domain. * @disable_11be: 11be is forbidden for this regulatory domain. * @disable_11bn: UHR/11bn is not allowed for this regulatory domain + * @puncturing_status: EHT puncturing status for the current MCC. + * See &enum iwl_puncturing_status. */ struct iwl_reg_capa { bool allow_40mhz; @@ -45,6 +60,7 @@ struct iwl_reg_capa { bool disable_11ax; bool disable_11be; bool disable_11bn; + enum iwl_puncturing_status puncturing_status; }; /** @@ -131,11 +147,13 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg, * @geo_info: geo info value * @cap: capability * @resp_ver: FW response version + * @puncturing_status: FW puncturing status for current MCC, when available */ struct ieee80211_regdomain * iwl_parse_nvm_mcc_info(struct iwl_trans *trans, int num_of_ch, __le32 *channels, u16 fw_mcc, - u16 geo_info, u32 cap, u8 resp_ver); + u16 geo_info, u32 cap, u8 resp_ver, + enum iwl_puncturing_status *puncturing_status); /** * struct iwl_nvm_section - describes an NVM section in memory. diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mcc.c b/drivers/net/wireless/intel/iwlwifi/mld/mcc.c index 7649ae794dfd..e3d1fa370616 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mcc.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/mcc.c @@ -89,6 +89,8 @@ iwl_mld_get_regdomain(struct iwl_mld *mld, struct iwl_mcc_update_resp_v8 *resp; u8 resp_ver = iwl_fw_lookup_notif_ver(mld->fw, IWL_ALWAYS_LONG_GROUP, MCC_UPDATE_CMD, 0); + enum iwl_puncturing_status puncturing_status; + u16 mcc; IWL_DEBUG_LAR(mld, "Getting regdomain data for %s from FW\n", alpha2); @@ -110,12 +112,13 @@ iwl_mld_get_regdomain(struct iwl_mld *mld, } IWL_DEBUG_LAR(mld, "MCC update response version: %d\n", resp_ver); + mcc = le16_to_cpu(resp->mcc); regd = iwl_parse_nvm_mcc_info(mld->trans, __le32_to_cpu(resp->n_channels), - resp->channels, - __le16_to_cpu(resp->mcc), + resp->channels, mcc, __le16_to_cpu(resp->geo_info), - le32_to_cpu(resp->cap), resp_ver); + le32_to_cpu(resp->cap), resp_ver, + &puncturing_status); if (IS_ERR(regd)) { IWL_DEBUG_LAR(mld, "Could not get parse update from FW %ld\n", @@ -129,18 +132,25 @@ iwl_mld_get_regdomain(struct iwl_mld *mld, mld->mcc_src = resp->source_id; + if (puncturing_status == IWL_PUNCTURING_STATUS_ENABLED) + __clear_bit(IEEE80211_HW_DISALLOW_PUNCTURING, + mld->hw->flags); + else if (puncturing_status == IWL_PUNCTURING_STATUS_DISABLED) + ieee80211_hw_set(mld->hw, DISALLOW_PUNCTURING); + + if (resp_ver >= 10) + goto out; + /* FM follows BIOS/MCC policy, WH disallows puncturing only in US/CA. */ if (CSR_HW_RFID_TYPE(mld->trans->info.hw_rf_id) == IWL_CFG_RF_TYPE_FM) { if (!iwl_puncturing_is_allowed_in_bios(mld->fwrt.bios_puncturing, - le16_to_cpu(resp->mcc))) + mcc)) ieee80211_hw_set(mld->hw, DISALLOW_PUNCTURING); else __clear_bit(IEEE80211_HW_DISALLOW_PUNCTURING, mld->hw->flags); } else if (CSR_HW_RFID_TYPE(mld->trans->info.hw_rf_id) == - IWL_CFG_RF_TYPE_WH) { - u16 mcc = le16_to_cpu(resp->mcc); - + IWL_CFG_RF_TYPE_WH) { if (mcc == IWL_MCC_US || mcc == IWL_MCC_CANADA) ieee80211_hw_set(mld->hw, DISALLOW_PUNCTURING); else diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 14aec0bfd173..37e2e2c6b716 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -152,7 +152,7 @@ struct ieee80211_regdomain *iwl_mvm_get_regdomain(struct wiphy *wiphy, resp->channels, __le16_to_cpu(resp->mcc), __le16_to_cpu(resp->geo_info), - le32_to_cpu(resp->cap), resp_ver); + le32_to_cpu(resp->cap), resp_ver, NULL); /* Store the return source id */ src_id = resp->source_id; if (IS_ERR_OR_NULL(regd)) { From ebc246e1d5a3e4502dba60cf9e9644de0fc5a8b6 Mon Sep 17 00:00:00 2001 From: Pagadala Yesu Anjaneyulu Date: Wed, 15 Jul 2026 22:04:24 +0300 Subject: [PATCH 29/46] wifi: iwlwifi: mvm: add LARI_CONFIG_EXTENSION command There is a new UHB extension bitmap that is part of the LARI configuration, which needs to be sent to the FW - also frozen ones. But in frozen FWs we cannot increase the version of an API, since the driver assumes a specific version, depending on the core number. In case of a (new) FW that expects the new version and a (old) driver that doesn't support that new version, the driver will send a default old version, causing a fw assert about its bad size. To mitigate this, there is a special command which will be supported only on those frozen FWs. Old drivers will simply not support/send it, and new driver will send it if supported by fw. Signed-off-by: Pagadala Yesu Anjaneyulu Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20260715220243.551f40ee2de3.I3e32a5d5c9aa13cbb0e599bef630cdb8e3b031c4@changeid --- .../wireless/intel/iwlwifi/fw/api/nvm-reg.h | 26 ++++++++++++++ drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 36 +++++++++++++++++++ drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 1 + 3 files changed, 63 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h index d8ec9934a9b6..360b626a9572 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h @@ -46,6 +46,11 @@ enum iwl_regulatory_and_nvm_subcmd_ids { */ MCC_ALLOWED_AP_TYPE_CMD = 0x5, + /** + * @LARI_CONFIG_EXTENSION: &struct iwl_lari_config_extension_cmd + */ + LARI_CONFIG_EXTENSION = 0x8, + /** * @PNVM_INIT_COMPLETE_NTFY: &struct iwl_pnvm_init_complete_ntfy */ @@ -514,6 +519,27 @@ struct iwl_bios_config_hdr { u8 reserved[2]; } __packed; /* BIOS_CONFIG_HDR_API_S_VER_1 */ +/** + * struct iwl_lari_config_extension_cmd - extend LARI configuration + * + * LARI_CONFIG_CHANGE's version must remain stable for frozen firmware. + * Because the driver might not know this version but still load that + * frozen FW and then send some default old version of LARI, causing the FW to + * assert about the bad size of it. To handle this, we do the following: + * 1. For newer firmware: increase the LARI_CONFIG_CHANGE version to support the + * new firmware API with extra UHB bits. + * 2. For frozen firmware: add a special alternative API that doesn't require + * modifying the frozen LARI_CONFIG_CHANGE's version. + * @dsm_table_hdr: BIOS DSM table source and revision + * @oem_uhb_allow_extension_bitmap: extension bitmap for OEM UHB config + * @reserved: reserved + */ +struct iwl_lari_config_extension_cmd { + struct iwl_bios_config_hdr dsm_table_hdr; + __le32 oem_uhb_allow_extension_bitmap; + __le32 reserved[10]; +} __packed; /* LARI_CONFIG_EXTENSION_CMD_API_S_VER_1 */ + /** * struct bios_value_u32 - BIOS configuration. * @hdr: bios config header diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 6e507d6dcdd2..187f39aa6249 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -1507,12 +1507,48 @@ static int iwl_mvm_fill_lari_config(struct iwl_fw_runtime *fwrt, return 0; } +static void iwl_mvm_send_lari_cfg_extension(struct iwl_mvm *mvm) +{ + struct iwl_fw_runtime *fwrt = &mvm->fwrt; + struct iwl_lari_config_extension_cmd cmd = {}; + u32 cmd_id = WIDE_ID(REGULATORY_AND_NVM_GROUP, + LARI_CONFIG_EXTENSION); + u32 value; + int ret; + + if (iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id, 0) < 1) + return; + + ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_REGULATORY_CONFIG, &value); + if (ret) + return; + + cmd.dsm_table_hdr.table_source = fwrt->dsm_source; + cmd.dsm_table_hdr.table_revision = fwrt->dsm_revision; + cmd.oem_uhb_allow_extension_bitmap = cpu_to_le32(value); + + IWL_DEBUG_RADIO(mvm, + "sending LARI_CONFIG_EXTENSION, oem_uhb_allow_extension_bitmap=0x%x\n", + le32_to_cpu(cmd.oem_uhb_allow_extension_bitmap)); + ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, sizeof(cmd), &cmd); + if (ret < 0) + IWL_DEBUG_RADIO(mvm, + "Failed to send LARI_CONFIG_EXTENSION (%d)\n", + ret); +} + static void iwl_mvm_lari_cfg(struct iwl_mvm *mvm) { struct iwl_lari_config_change_cmd cmd; size_t cmd_size; int ret; + /* + * LARI_CONFIG_CHANGE triggers a profile update, so send + * LARI_CONFIG_EXTENSION first to make sure its data is applied + * in the same update. + */ + iwl_mvm_send_lari_cfg_extension(mvm); ret = iwl_mvm_fill_lari_config(&mvm->fwrt, &cmd, &cmd_size); if (!ret) { ret = iwl_mvm_send_cmd_pdu(mvm, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index da4c67a91113..1dd27292af9b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -707,6 +707,7 @@ static const struct iwl_hcmd_names iwl_mvm_regulatory_and_nvm_names[] = { HCMD_NAME(NVM_ACCESS_COMPLETE), HCMD_NAME(NVM_GET_INFO), HCMD_NAME(TAS_CONFIG), + HCMD_NAME(LARI_CONFIG_EXTENSION), }; /* Please keep this array *SORTED* by hex value. From 51c45bb2c884e0e2f56d6770011994d653371702 Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Wed, 15 Jul 2026 22:04:25 +0300 Subject: [PATCH 30/46] wifi: iwlwifi: mld: add PNVM_INIT_COMPLETE_NTFY to the hcmd names Add it to the array of host command name so it will be printed with iwl_get_cmd_string Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20260715220243.e8da467f1883.I75ab56a022f31365042d29aff5484e4329b0f6ce@changeid --- drivers/net/wireless/intel/iwlwifi/mld/mld.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mld.c b/drivers/net/wireless/intel/iwlwifi/mld/mld.c index 093bdc130704..7c49d0441fdf 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mld.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/mld.c @@ -212,6 +212,7 @@ static const struct iwl_hcmd_names iwl_mld_reg_and_nvm_names[] = { HCMD_NAME(TAS_CONFIG), HCMD_NAME(SAR_OFFSET_MAPPING_TABLE_CMD), HCMD_NAME(MCC_ALLOWED_AP_TYPE_CMD), + HCMD_NAME(PNVM_INIT_COMPLETE_NTFY), }; /* Please keep this array *SORTED* by hex value. From c5aeb11489150be84d3a700711abffd98969d2d5 Mon Sep 17 00:00:00 2001 From: Shahar Tzarfati Date: Wed, 15 Jul 2026 22:04:26 +0300 Subject: [PATCH 31/46] wifi: iwlwifi: mld: fix read in wake packet notification handler In iwl_mld_handle_wake_pkt_notif(), expected_size was initialized from notif->wake_packet_length before the IWL_FW_CHECK that validates the payload covers sizeof(*notif). Move the assignment of expected_size to after the size check so that notif->wake_packet_length is only accessed once the payload length has been validated. Signed-off-by: Shahar Tzarfati Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20260715220243.94c526d2c66e.I065a19a9dcc7f45a7457667c0f625fcd2c7bf6b6@changeid --- drivers/net/wireless/intel/iwlwifi/mld/d3.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mld/d3.c b/drivers/net/wireless/intel/iwlwifi/mld/d3.c index c9c0e3c729c9..3b785c53948f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/d3.c @@ -705,7 +705,7 @@ iwl_mld_handle_wake_pkt_notif(struct iwl_mld *mld, { const struct iwl_wowlan_wake_pkt_notif *notif = (void *)pkt->data; u32 actual_size, len = iwl_rx_packet_payload_len(pkt); - u32 expected_size = le32_to_cpu(notif->wake_packet_length); + u32 expected_size; if (IWL_FW_CHECK(mld, len < sizeof(*notif), "Invalid WoWLAN wake packet notification (expected size=%zu got=%u)\n", @@ -718,6 +718,7 @@ iwl_mld_handle_wake_pkt_notif(struct iwl_mld *mld, wowlan_status->wakeup_reasons)) return true; + expected_size = le32_to_cpu(notif->wake_packet_length); actual_size = len - offsetof(struct iwl_wowlan_wake_pkt_notif, wake_packet); From 7d8cc301bcba233f31b589a45f4c1c97f2bb90d6 Mon Sep 17 00:00:00 2001 From: Avraham Stern Date: Wed, 15 Jul 2026 22:04:27 +0300 Subject: [PATCH 32/46] wifi: iwlwifi: mei: check SAP message length before reading it Verify the SAP message size is not larger than the local buffer before reading the message to avoid buffer overflow. Fixes: bcd68b3dbe78 ("wifi: iwlwifi: mei: fix tx DHCP packet for devices with new Tx API") Signed-off-by: Avraham Stern Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20260715220243.f0026ce26218.I00a856d3aacae1caac605c708f7362689b734234@changeid --- drivers/net/wireless/intel/iwlwifi/mei/main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mei/main.c b/drivers/net/wireless/intel/iwlwifi/mei/main.c index c5ff1b1b720f..c01435859349 100644 --- a/drivers/net/wireless/intel/iwlwifi/mei/main.c +++ b/drivers/net/wireless/intel/iwlwifi/mei/main.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2021-2024 Intel Corporation + * Copyright (C) 2026 Intel Corporation */ #include @@ -1147,6 +1148,11 @@ static void iwl_mei_handle_sap_rx_cmd(struct mei_cl_device *cldev, iwl_mei_read_from_q(q_head, q_sz, &rd, wr, hdr, sizeof(*hdr)); valid_rx_sz -= sizeof(*hdr); len = le16_to_cpu(hdr->len); + if (len + sizeof(*hdr) > PAGE_SIZE) { + dev_err(&cldev->dev, + "SAP message is too big: %u\n", len); + break; + } if (valid_rx_sz < len) break; From c00a5d65b7ada536eb488280fae53fcf1724a7c3 Mon Sep 17 00:00:00 2001 From: Avraham Stern Date: Wed, 15 Jul 2026 22:04:28 +0300 Subject: [PATCH 33/46] wifi: iwlwifi: mei: skip data read if length is too short When calculating the SAP data length, the code subtracts sizeof(*ethhdr) from len. If the SAP data header indicates a length that is shorter than ethernet header length, this will result in an unsigned underflow which will lead to a kernel panic when trying to put the data into the SKB. Fix it by skipping a message if the indicated length is too short. In addition, if the message type is not SAP_MSG_DATA_PACKET or skb allocation fails, the loop skips to the next message but without reading the message payload. This may result in reading the payload as the next message header, which will lead to errors in parsing the next messages. Fix it by skipping the message payload as well. Signed-off-by: Avraham Stern Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20260715220243.f66b10736047.I4a1dde517c36561d41358dd82a5cec8b6c886c14@changeid --- drivers/net/wireless/intel/iwlwifi/mei/main.c | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mei/main.c b/drivers/net/wireless/intel/iwlwifi/mei/main.c index c01435859349..c462c3b22ec1 100644 --- a/drivers/net/wireless/intel/iwlwifi/mei/main.c +++ b/drivers/net/wireless/intel/iwlwifi/mei/main.c @@ -1041,11 +1041,14 @@ static void iwl_mei_read_from_q(const u8 *q_head, u32 q_sz, u32 rd = *_rd; if (rd + len <= q_sz) { - memcpy(buf, q_head + rd, len); + if (buf) + memcpy(buf, q_head + rd, len); rd += len; } else { - memcpy(buf, q_head + rd, q_sz - rd); - memcpy(buf + q_sz - rd, q_head, len - (q_sz - rd)); + if (buf) { + memcpy(buf, q_head + rd, q_sz - rd); + memcpy(buf + q_sz - rd, q_head, len - (q_sz - rd)); + } rd = len - (q_sz - rd); } @@ -1086,24 +1089,29 @@ static void iwl_mei_handle_sap_data(struct mei_cl_device *cldev, break; } + valid_rx_sz -= len; + if (len < sizeof(*ethhdr)) { dev_err(&cldev->dev, "Data len is smaller than an ethernet header? len = %d\n", len); + iwl_mei_read_from_q(q_head, q_sz, &rd, wr, NULL, len); + continue; } - valid_rx_sz -= len; - if (le16_to_cpu(hdr.type) != SAP_MSG_DATA_PACKET) { dev_err(&cldev->dev, "Unsupported Rx data: type %d, len %d\n", le16_to_cpu(hdr.type), len); + iwl_mei_read_from_q(q_head, q_sz, &rd, wr, NULL, len); continue; } /* We need enough room for the WiFi header + SNAP + IV */ skb = netdev_alloc_skb(netdev, len + QOS_HDR_IV_SNAP_LEN); - if (!skb) + if (!skb) { + iwl_mei_read_from_q(q_head, q_sz, &rd, wr, NULL, len); continue; + } skb_reserve(skb, QOS_HDR_IV_SNAP_LEN); ethhdr = skb_push(skb, sizeof(*ethhdr)); From 9318bc0c41b24705690cf80d1596cf6b711e7027 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 15 Jul 2026 22:04:29 +0300 Subject: [PATCH 34/46] wifi: iwlwifi: guard against division by zero in iwl_dbg_tlv_alloc_fragments Make sure we don't end-up with a num_frags = 0 situation. For that, check that the required size is not 0 and put a checker on num_frags as well. Fixes: 14124b25780d ("iwlwifi: dbg_ini: implement monitor allocation flow") Assisted-by: GitHubCopilot:gpt-5.3-codex Signed-off-by: Emmanuel Grumbach Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20260715220243.60121deecf2c.Iebc891c95a7bd1b2a093b0bb88532db446a758ee@changeid --- drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c index d021b24d04d6..8b0f091ff4c1 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2018-2025 Intel Corporation + * Copyright (C) 2018-2026 Intel Corporation */ #include #include "iwl-drv.h" @@ -602,6 +602,9 @@ static int iwl_dbg_tlv_alloc_fragments(struct iwl_fw_runtime *fwrt, cpu_to_le32(IWL_FW_INI_LOCATION_DRAM_PATH)) return 0; + if (!fw_mon_cfg->req_size) + return -EIO; + num_frags = le32_to_cpu(fw_mon_cfg->max_frags_num); if (fwrt->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_AX210) { if (alloc_id != IWL_FW_INI_ALLOCATION_ID_DBGC1) @@ -612,6 +615,9 @@ static int iwl_dbg_tlv_alloc_fragments(struct iwl_fw_runtime *fwrt, return -EIO; } + if (!num_frags) + return -EIO; + remain_pages = DIV_ROUND_UP(le32_to_cpu(fw_mon_cfg->req_size), PAGE_SIZE); num_frags = min_t(u32, num_frags, BUF_ALLOC_MAX_NUM_FRAGS); From 1c031ac5a39ebcc3269eace8b606043adc398bfa Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Wed, 15 Jul 2026 22:04:30 +0300 Subject: [PATCH 35/46] wifi: iwlwifi: mld: Do not cleanup FW state when the device is dead When a channel context is unassigned, there is a path to cleanup the FW state in case of NON MLO connection: remove the link and add it again. However, when the transport is dead, e.g., during device removal etc., this flow will fail and as a result the mld_vif->link[0] would be set to NULL. Later, when the interface is removed, iwl_mld_remove_link() would warn as the link is NULL. Fix this by not doing the cleanup when the device is dead. Signed-off-by: Ilan Peer Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20260715220243.89a0c44a72a3.I45cca8b84a25943d5771199af6b0155dbac77b58@changeid --- drivers/net/wireless/intel/iwlwifi/mld/mac80211.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c index 17922ed3800d..92985e500459 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c @@ -1280,11 +1280,13 @@ void iwl_mld_unassign_vif_chanctx(struct ieee80211_hw *hw, iwl_mld_tlc_update_phy(mld, vif, link); /* in the non-MLO case, remove/re-add the link to clean up FW state. - * In MLO, it'll be done in drv_change_vif_link + * In MLO, it'll be done in drv_change_vif_link. + * Do not do so during restart or in case the device is dead. */ if (!ieee80211_vif_is_mld(vif) && !mld_vif->ap_sta && !WARN_ON_ONCE(vif->cfg.assoc) && - vif->type != NL80211_IFTYPE_AP && !mld->fw_status.in_hw_restart) { + vif->type != NL80211_IFTYPE_AP && !mld->fw_status.in_hw_restart && + !iwl_trans_is_dead(mld->trans)) { iwl_mld_remove_link(mld, link); iwl_mld_add_link(mld, link); } From 905f57aefde4f4092a411c8a55856182fb1c7598 Mon Sep 17 00:00:00 2001 From: Avraham Stern Date: Wed, 15 Jul 2026 22:04:31 +0300 Subject: [PATCH 36/46] wifi: iwlwifi: mei: pass correct argument to function The first argument to iwl_mei_write_cyclic_buf() should be the cldev but the q_head pointer is passed instead. Fix it. Fixes: 652291601459 ("iwlwifi: mei: don't rely on the size from the shared area") Signed-off-by: Avraham Stern Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20260715220243.24cea60c6428.I42301010c31487b1458faa967b22c8320b0cfd23@changeid --- drivers/net/wireless/intel/iwlwifi/mei/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mei/main.c b/drivers/net/wireless/intel/iwlwifi/mei/main.c index c462c3b22ec1..ce92e26c42d7 100644 --- a/drivers/net/wireless/intel/iwlwifi/mei/main.c +++ b/drivers/net/wireless/intel/iwlwifi/mei/main.c @@ -458,7 +458,7 @@ static int iwl_mei_send_sap_msg_payload(struct mei_cl_device *cldev, notif_q = &dir->q_ctrl_blk[SAP_QUEUE_IDX_NOTIF]; q_head = mei->shared_mem.q_head[SAP_DIRECTION_HOST_TO_ME][SAP_QUEUE_IDX_NOTIF]; q_sz = mei->shared_mem.q_size[SAP_DIRECTION_HOST_TO_ME][SAP_QUEUE_IDX_NOTIF]; - ret = iwl_mei_write_cyclic_buf(q_head, notif_q, q_head, hdr, q_sz); + ret = iwl_mei_write_cyclic_buf(cldev, notif_q, q_head, hdr, q_sz); if (ret < 0) return ret; From c5cb9dd220ba9fdcf4ba485ce3d1d36ca32ac00b Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Fri, 17 Jul 2026 17:31:05 +0300 Subject: [PATCH 37/46] wifi: iwlwifi: mld: validate wake packet crypto overhead Wake packet parsing only accounted for FCS and missed per-key IV/ICV overhead for protected data frames. Prevent size underflow and bad packet trimming when notifications are malformed or truncated. Signed-off-by: Emmanuel Grumbach Link: https://patch.msgid.link/20260717172958.e06595623533.Ie09494b7e34e5872b750fd90e325648ee469d0da@changeid Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/mld/d3.c | 63 +++++++++++++++++++-- 1 file changed, 57 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mld/d3.c b/drivers/net/wireless/intel/iwlwifi/mld/d3.c index 3b785c53948f..301983428a63 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/d3.c @@ -59,6 +59,30 @@ struct iwl_mld_suspend_key_iter_data { __le32 bigtk_cipher; }; +struct iwl_mld_wake_pkt_iter_data { + bool multicast; + u32 ivlen; + u32 icvlen; +}; + +static void +iwl_mld_wake_pkt_key_iter(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key, void *_data) +{ + struct iwl_mld_wake_pkt_iter_data *data = _data; + bool is_group_key = !sta; + + /* ignore anything that is not a PTK / GTK */ + if (key->keyidx > 3) + return; + if (is_group_key != data->multicast) + return; + + data->ivlen = key->iv_len; + data->icvlen = key->icv_len; +} + struct iwl_mld_mcast_key_data { u8 key[WOWLAN_KEY_MAX_SIZE]; u8 len; @@ -743,11 +767,17 @@ iwl_mld_set_wake_packet(struct iwl_mld *mld, struct cfg80211_wowlan_wakeup *wakeup, struct sk_buff **_pkt) { - int pkt_bufsize = wowlan_status->wake_packet_bufsize; - int expected_pktlen = wowlan_status->wake_packet_length; + u32 pkt_bufsize = wowlan_status->wake_packet_bufsize; + u32 expected_pktlen = wowlan_status->wake_packet_length; const u8 *pktdata = wowlan_status->wake_packet; const struct ieee80211_hdr *hdr = (const void *)pktdata; - int truncated = expected_pktlen - pkt_bufsize; + u32 truncated; + + if (IWL_FW_CHECK(mld, pkt_bufsize < sizeof(*hdr), + "pkt_bufsize is too short: %u\n", pkt_bufsize)) + return; + + truncated = expected_pktlen - pkt_bufsize; if (ieee80211_is_data(hdr->frame_control)) { int hdrlen = ieee80211_hdrlen(hdr->frame_control); @@ -758,9 +788,18 @@ iwl_mld_set_wake_packet(struct iwl_mld *mld, if (!pkt) return; - skb_put_data(pkt, pktdata, hdrlen); - pktdata += hdrlen; - pkt_bufsize -= hdrlen; + if (ieee80211_has_protected(hdr->frame_control)) { + struct iwl_mld_wake_pkt_iter_data iter_data = { + .multicast = + is_multicast_ether_addr(hdr->addr1), + }; + + ieee80211_iter_keys(mld->hw, vif, + iwl_mld_wake_pkt_key_iter, + &iter_data); + ivlen = iter_data.ivlen; + icvlen += iter_data.icvlen; + } /* if truncated, FCS/ICV is (partially) gone */ if (truncated >= icvlen) { @@ -771,6 +810,13 @@ iwl_mld_set_wake_packet(struct iwl_mld *mld, truncated = 0; } + if (IWL_FW_CHECK(mld, pkt_bufsize <= hdrlen + ivlen + icvlen, + "pkt_bufsize is too small %u\n", pkt_bufsize)) + return; + + skb_put_data(pkt, pktdata, hdrlen); + pktdata += hdrlen; + pkt_bufsize -= hdrlen; pkt_bufsize -= ivlen + icvlen; pktdata += ivlen; @@ -792,6 +838,11 @@ iwl_mld_set_wake_packet(struct iwl_mld *mld, fcslen -= truncated; truncated = 0; } + + if (IWL_FW_CHECK(mld, pkt_bufsize <= fcslen, + "pkt_bufsize is too small %u\n", pkt_bufsize)) + return; + pkt_bufsize -= fcslen; wakeup->packet = wowlan_status->wake_packet; wakeup->packet_present_len = pkt_bufsize; From 6aa811062cd78ad961410a64db55694ff609da57 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Fri, 17 Jul 2026 17:31:06 +0300 Subject: [PATCH 38/46] wifi: iwlwifi: mld: initialize scan-abort status Initialize abort status before issuing the abort command so debug logging never reads an uninitialized value on error paths. Assisted-by: GitHubCopilot:GPT-5.3-Codex Signed-off-by: Emmanuel Grumbach Link: https://patch.msgid.link/20260717172958.9d804f466534.I4e10270bd1dde4a80940a47ef5d383729cc66cb1@changeid Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/mld/scan.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mld/scan.c b/drivers/net/wireless/intel/iwlwifi/mld/scan.c index d80a1cfc2ed5..0faca402bc14 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/scan.c @@ -1681,7 +1681,8 @@ iwl_mld_scan_send_abort_cmd_status(struct iwl_mld *mld, int uid, u32 *status) static int iwl_mld_scan_abort(struct iwl_mld *mld, int type, int uid, bool *wait) { - enum iwl_umac_scan_abort_status status; + enum iwl_umac_scan_abort_status status = + IWL_UMAC_SCAN_ABORT_STATUS_NOT_FOUND; int ret; *wait = true; From a790f60cc4d7dc64a2d7cadb94a3d9f60392bed4 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Fri, 17 Jul 2026 17:31:07 +0300 Subject: [PATCH 39/46] wifi: iwlwifi: mvm: ignore sync frames when sync is disabled Gate time-sync frame interception on the active flag so frames are not queued after time-sync teardown. Assisted-by: GitHubCopilot:GPT-5.3-Codex Signed-off-by: Emmanuel Grumbach Link: https://patch.msgid.link/20260717172958.ac73ee199a25.Ic1489244f9b02da93060f0a0e5b300a73527f265@changeid Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/mvm/time-sync.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-sync.h b/drivers/net/wireless/intel/iwlwifi/mvm/time-sync.h index 2cfd0fb5e781..7bdbacb64078 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/time-sync.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-sync.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* * Copyright (C) 2022 Intel Corporation + * Copyright (C) 2026 Intel Corporation */ #ifndef __TIME_SYNC_H__ #define __TIME_SYNC_H__ @@ -19,6 +20,9 @@ int iwl_mvm_time_sync_config(struct iwl_mvm *mvm, const u8 *addr, static inline bool iwl_mvm_time_sync_frame(struct iwl_mvm *mvm, struct sk_buff *skb, u8 *addr) { + if (!mvm->time_sync.active) + return false; + if (ether_addr_equal(mvm->time_sync.peer_addr, addr) && (ieee80211_is_timing_measurement(skb) || ieee80211_is_ftm(skb))) { skb_queue_tail(&mvm->time_sync.frame_list, skb); From 4f5384b58b483e4aec576ce461dec45b41df18db Mon Sep 17 00:00:00 2001 From: Ayala Beker Date: Fri, 17 Jul 2026 17:31:08 +0300 Subject: [PATCH 40/46] wifi: iwlwifi: mld: drop connection on D3 resume failure When FW crashes on D3 exit, iwl_mld_nic_error() sets STATUS_RESET_PENDING and queues restart wk, but mac80211's resume callback synchronously calls iwl_trans_stop_device() which clears the flag. As a result restart wk skips sw_reset, and the FW error recovery buffer is never read. The new FW boots with empty BA state and initial sequence numbers, while the AP still holds its A-MPDU RX reorder window. This causes MPDUs to be dropped as IWL_RX_MPDU_REORDER_BA_OLD_SN until ADDBA is renegotiated. We don't know how long the firmware has been in an error state or whether the AP still considers us associated, so keeping the connection alive is not worth it. Call ieee80211_resume_disconnect() when iwl_mld_wait_d3_notif() fails, and let userspace reassociate. Signed-off-by: Ayala Beker Reviewed-by: Emmanuel Grumbach Link: https://patch.msgid.link/20260717172958.3e10c8498f53.Icf5644b42d79e984ecc16abfa873bd37f611e778@changeid Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/mld/d3.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mld/d3.c b/drivers/net/wireless/intel/iwlwifi/mld/d3.c index 301983428a63..55f9b809e764 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/d3.c @@ -2219,6 +2219,9 @@ int iwl_mld_wowlan_resume(struct iwl_mld *mld) ret = iwl_mld_wait_d3_notif(mld, &resume_data, true); if (ret) { IWL_ERR(mld, "Couldn't get the d3 notifs %d\n", ret); + + if (bss_vif->cfg.assoc) + ieee80211_resume_disconnect(bss_vif); goto err; } From 7e1d5ccac87ec618f393ec137743207282ef1af5 Mon Sep 17 00:00:00 2001 From: Avinash Bhatt Date: Fri, 17 Jul 2026 17:31:09 +0300 Subject: [PATCH 41/46] wifi: iwlwifi: fw: move SAR defines from acpi.h to regulatory.h IWL_SAR_ENABLE_MSK and IWL_REDUCE_POWER_FLAGS_POS describe the layout of the shared WRDS/SAR table format. They are not ACPI-specific: the same bit positions are used regardless of whether the data originates from ACPI, UEFI, or another BIOS source. IWL_SAR_ENABLE_MSK was already duplicated in regulatory.h; remove it from acpi.h to eliminate the duplication. Move IWL_REDUCE_POWER_FLAGS_POS to regulatory.h alongside IWL_SAR_ENABLE_MSK so that both SAR field descriptors live in the shared regulatory header, accessible to all BIOS configuration sources. No functional change. Signed-off-by: Avinash Bhatt Link: https://patch.msgid.link/20260717172958.32e5dcde4b90.I420c58b05ab6ab011c4c771ca9e4eb62740de549@changeid Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/fw/acpi.h | 5 +---- drivers/net/wireless/intel/iwlwifi/fw/regulatory.h | 3 ++- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h index 51a57e57de7a..45eb35ffb637 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* * Copyright (C) 2017 Intel Deutschland GmbH - * Copyright (C) 2018-2023, 2025 Intel Corporation + * Copyright (C) 2018-2023, 2025-2026 Intel Corporation */ #ifndef __iwl_fw_acpi__ #define __iwl_fw_acpi__ @@ -111,9 +111,6 @@ #define ACPI_PPAG_WIFI_DATA_SIZE_V3 ((ACPI_PPAG_NUM_CHAINS * \ ACPI_PPAG_NUM_BANDS_V3) + 2) -#define IWL_SAR_ENABLE_MSK BIT(0) -#define IWL_REDUCE_POWER_FLAGS_POS 1 - /* The Inidcator whether UEFI WIFI GUID tables are locked is read from ACPI */ #define UEFI_WIFI_GUID_UNLOCKED 0 diff --git a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.h b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.h index 6fffc032efd3..22c97c75b83c 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* - * Copyright (C) 2023-2025 Intel Corporation + * Copyright (C) 2023-2026 Intel Corporation */ #ifndef __fw_regulatory_h__ @@ -30,6 +30,7 @@ #define BIOS_GEO_MIN_PROFILE_NUM 3 #define IWL_SAR_ENABLE_MSK BIT(0) +#define IWL_REDUCE_POWER_FLAGS_POS 1 /* PPAG gain value bounds in 1/8 dBm */ #define IWL_PPAG_MIN_LB -16 From 340eafb30b35a600a66da333bb0c119a880b7062 Mon Sep 17 00:00:00 2001 From: Pagadala Yesu Anjaneyulu Date: Fri, 17 Jul 2026 17:31:10 +0300 Subject: [PATCH 42/46] wifi: iwlwifi: mld: support update_mcc notification v2 New firmware will support version 2 of the update_mcc notification. The extra field is used for a new feature, but we does not support it. Keep the existing payload definition compatible with both versions and register version 2 in the MLD notification version table so the driver accepts the newer notification without changing the behavior. This preserves version 1 support and adds compatibility with firmware that sends version 2. Signed-off-by: Pagadala Yesu Anjaneyulu Link: https://patch.msgid.link/20260717172958.9c5a940d37dc.I955800c2377b802ffb99003349552cc4036ca4bd@changeid Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h | 5 ++++- drivers/net/wireless/intel/iwlwifi/mld/notif.c | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h index 360b626a9572..9fbdb45e88db 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h @@ -411,7 +411,10 @@ struct iwl_mcc_chub_notif { __le16 mcc; u8 source_id; u8 reserved1; -} __packed; /* LAR_MCC_NOTIFY_S */ +} __packed; +/* LAR_MCC_NOTIFY_S_VER_1 + * LAR_MCC_NOTIFY_S_VER_2 + */ enum iwl_mcc_update_status { MCC_RESP_NEW_CHAN_PROFILE, diff --git a/drivers/net/wireless/intel/iwlwifi/mld/notif.c b/drivers/net/wireless/intel/iwlwifi/mld/notif.c index b3a899828db9..90733bbaf733 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/notif.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/notif.c @@ -298,7 +298,8 @@ CMD_VERSIONS(channel_survey_notif, CMD_VERSIONS(mfuart_notif, CMD_VER_ENTRY(2, iwl_mfuart_load_notif)) CMD_VERSIONS(update_mcc, - CMD_VER_ENTRY(1, iwl_mcc_chub_notif)) + CMD_VER_ENTRY(1, iwl_mcc_chub_notif) + CMD_VER_ENTRY(2, iwl_mcc_chub_notif)) CMD_VERSIONS(session_prot_notif, CMD_VER_ENTRY(3, iwl_session_prot_notif)) CMD_VERSIONS(missed_beacon_notif, From ac8227e35ff7c8953a7d8adf7f5230127ad97aae Mon Sep 17 00:00:00 2001 From: Pagadala Yesu Anjaneyulu Date: Fri, 17 Jul 2026 17:31:11 +0300 Subject: [PATCH 43/46] wifi: iwlwifi: mld: add debug log after AP type command Add a radio debug trace when MCC_ALLOWED_AP_TYPE_CMD is sent successfully during AP type table initialization. This improves bring-up visibility without changing runtime behavior. Failures are still reported through the existing error log path. Signed-off-by: Pagadala Yesu Anjaneyulu Link: https://patch.msgid.link/20260717172958.18e1fc5ec109.I76dd832f62d00a8f358f8e4a705f25184ac53da2@changeid Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/mld/regulatory.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c b/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c index 4a93ccbef495..be311f6c3d9f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c @@ -524,6 +524,8 @@ void iwl_mld_init_ap_type_tables(struct iwl_mld *mld) if (ret) IWL_ERR(mld, "failed to send MCC_ALLOWED_AP_TYPE_CMD (%d)\n", ret); + else + IWL_DEBUG_RADIO(mld, "MCC_ALLOWED_AP_TYPE_CMD sent to FW\n"); } void iwl_mld_init_tas(struct iwl_mld *mld) From a47ab1b9c0827f5bd6717abb3f9e3f4f6eb5e00c Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Fri, 17 Jul 2026 17:31:12 +0300 Subject: [PATCH 44/46] wifi: iwlwifi: mld: move BIOS reading code to where it belongs We have a dedicated function to fetch all the BIOS tables when the opmode starts, and yet we read a couple of tables directly from iwl_op_mode_mld_start, which is already a large function that does multiple things. Move the reading of the sgom, puncturing, and RFI enablement to the dedicated iwl_mld_get_bios_tables. Link: https://patch.msgid.link/20260717172958.b19a33e0b507.I73f6b5e6a81d0f411f12589ceb30afa655c0a16b@changeid Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/mld/mld.c | 2 -- drivers/net/wireless/intel/iwlwifi/mld/regulatory.c | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mld.c b/drivers/net/wireless/intel/iwlwifi/mld/mld.c index 7c49d0441fdf..6e991fb99ff3 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mld.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/mld.c @@ -419,8 +419,6 @@ iwl_op_mode_mld_start(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg, iwl_mld_construct_fw_runtime(mld, trans, fw, dbgfs_dir); iwl_mld_get_bios_tables(mld); - iwl_uefi_get_sgom_table(trans, &mld->fwrt); - iwl_uefi_get_puncturing(&mld->fwrt); iwl_mld_hw_set_regulatory(mld); diff --git a/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c b/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c index be311f6c3d9f..ad899ce5c64a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c @@ -84,6 +84,9 @@ void iwl_mld_get_bios_tables(struct iwl_mld *mld) iwl_uefi_get_uneb_table(mld->trans, &mld->fwrt); iwl_bios_get_phy_filters(&mld->fwrt); + + iwl_uefi_get_sgom_table(mld->trans, &mld->fwrt); + iwl_uefi_get_puncturing(&mld->fwrt); } static int iwl_mld_geo_sar_init(struct iwl_mld *mld) From 01f41f5fd823fb70a2f28ea87f6cf85a268ef8b9 Mon Sep 17 00:00:00 2001 From: Pagadala Yesu Anjaneyulu Date: Thu, 23 Jul 2026 14:23:36 +0300 Subject: [PATCH 45/46] wifi: iwlwifi: regulatory: add LARI v15 DSM support bitmap Firmware API v15 extends LARI config with the DSM function-0 support bitmap, and host must provide this information for regulatory handling. Without this, FW cannot use BIOS-reported DSM capability bits. Add oem_supported_dsm_bitmap to the host LARI config command definition and wire it into regulatory command construction. Populate it from DSM query data and keep backward compatibility by using the pre-v15 command size for command version 14. Behavior change: When DSM function-0 data is available, host includes it in the LARI config command sent to FW; older command versions remain compatible. Signed-off-by: Pagadala Yesu Anjaneyulu Link: https://patch.msgid.link/20260723142324.c576a8c7560b.I5cc1277d0ef31409f6a3364342a3f35cd9318ceb@changeid Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/fw/acpi.c | 3 ++- .../net/wireless/intel/iwlwifi/fw/api/nvm-reg.h | 5 +++++ drivers/net/wireless/intel/iwlwifi/fw/uefi.c | 2 +- .../net/wireless/intel/iwlwifi/mld/regulatory.c | 15 +++++++++++++-- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c index 9f2f4a6af1ca..0b1e478fb7b0 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c @@ -181,6 +181,7 @@ static int iwl_acpi_load_dsm_values(struct iwl_fw_runtime *fwrt) fwrt->dsm_revision = ACPI_DSM_REV; fwrt->dsm_source = BIOS_SOURCE_ACPI; + fwrt->dsm_values[DSM_FUNC_QUERY] = (u32)query_func_val; IWL_DEBUG_RADIO(fwrt, "ACPI DSM validity bitmap 0x%x\n", (u32)query_func_val); @@ -246,7 +247,7 @@ int iwl_acpi_get_dsm(struct iwl_fw_runtime *fwrt, BUILD_BUG_ON(ARRAY_SIZE(fwrt->dsm_values) != DSM_FUNC_NUM_FUNCS); BUILD_BUG_ON(BITS_PER_TYPE(fwrt->dsm_funcs_valid) < DSM_FUNC_NUM_FUNCS); - if (WARN_ON(func >= ARRAY_SIZE(fwrt->dsm_values) || !func)) + if (WARN_ON(func >= ARRAY_SIZE(fwrt->dsm_values))) return -EINVAL; if (!(fwrt->dsm_funcs_valid & BIT(func))) { diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h index 9fbdb45e88db..5f48e3b306eb 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h @@ -697,6 +697,8 @@ struct iwl_lari_config_change_cmd_v8 { * @wcpe_bitmap: bitmap of puncturing enablement per MCC * @bios_wbem_hdr: 320 MHz per-MCC WBEM config header * @reserved: reserved + * @oem_supported_dsm_bitmap: DSM function 0 bitmap describing supported + * DSM function indices */ struct iwl_lari_config_change_cmd { __le32 config_bitmap; @@ -720,10 +722,13 @@ struct iwl_lari_config_change_cmd { __le32 wcpe_bitmap; struct iwl_bios_config_hdr bios_wbem_hdr; __le32 reserved[10]; + /* since version 15 */ + __le32 oem_supported_dsm_bitmap; } __packed; /* LARI_CHANGE_CONF_CMD_S_VER_12 * LARI_CHANGE_CONF_CMD_S_VER_13 * LARI_CHANGE_CONF_CMD_S_VER_14 + * LARI_CHANGE_CONF_CMD_S_VER_15 */ /* Activate UNII-1 (5.2GHz) for World Wide */ diff --git a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c index 01e495e24ebc..f9187989c988 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c @@ -927,7 +927,7 @@ static int iwl_uefi_load_dsm_values(struct iwl_fw_runtime *fwrt) */ fwrt->dsm_funcs_valid |= BIT(DSM_FUNC_QUERY); - for (int func = 1; func < ARRAY_SIZE(fwrt->dsm_values); func++) { + for (int func = 0; func < ARRAY_SIZE(fwrt->dsm_values); func++) { if (!(fwrt->dsm_funcs_valid & BIT(func))) { IWL_DEBUG_RADIO(fwrt, "DSM func %d not in 0x%x\n", func, fwrt->dsm_funcs_valid); diff --git a/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c b/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c index ad899ce5c64a..533870cf443f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c @@ -16,8 +16,11 @@ static ssize_t iwl_mld_get_lari_config_cmd_size(u8 cmd_ver) { switch (cmd_ver) { - case 14: + case 15: return sizeof(struct iwl_lari_config_change_cmd); + case 14: + return offsetof(struct iwl_lari_config_change_cmd, + oem_supported_dsm_bitmap); case 13: return offsetof(struct iwl_lari_config_change_cmd, oem_uhb_allow_extension_bitmap); @@ -425,6 +428,10 @@ void iwl_mld_configure_lari(struct iwl_mld *mld) if (!ret) cmd.oem_uhb_allow_extension_bitmap = cpu_to_le32(value); + ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_QUERY, &value); + if (!ret) + cmd.oem_supported_dsm_bitmap = cpu_to_le32(value); + cmd.bios_wcpe_hdr.table_source = fwrt->puncturing_source; cmd.bios_wcpe_hdr.table_revision = fwrt->puncturing_revision; cmd.wcpe_bitmap = cpu_to_le32(fwrt->bios_puncturing); @@ -441,7 +448,8 @@ void iwl_mld_configure_lari(struct iwl_mld *mld) !cmd.oem_11be_allow_bitmap && !cmd.oem_11bn_allow_bitmap && !cmd.oem_unii9_enable && - !cmd.wcpe_bitmap) + !cmd.wcpe_bitmap && + !cmd.oem_supported_dsm_bitmap) return; cmd.bios_hdr.table_source = fwrt->dsm_source; @@ -478,6 +486,9 @@ void iwl_mld_configure_lari(struct iwl_mld *mld) IWL_DEBUG_RADIO(mld, "sending LARI_CONFIG_CHANGE, wcpe_bitmap=0x%x\n", le32_to_cpu(cmd.wcpe_bitmap)); + IWL_DEBUG_RADIO(mld, + "sending LARI_CONFIG_CHANGE, oem_supported_dsm_bitmap=0x%x\n", + le32_to_cpu(cmd.oem_supported_dsm_bitmap)); ret = iwl_mld_send_cmd_pdu(mld, WIDE_ID(REGULATORY_AND_NVM_GROUP, From 4a2610a5a9fcf77eaad82bb030ec77ec5e381db8 Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Thu, 23 Jul 2026 14:23:37 +0300 Subject: [PATCH 46/46] wifi: iwlwifi: bump core version for BZ/SC/DR Start supporting Core 107 FW on these devices. Link: https://patch.msgid.link/20260723142324.ed92b1d7f927.I6dd10d2f9a04a36751aea9e238fecfa62fe280a6@changeid Signed-off-by: Miri Korenblit --- drivers/net/wireless/intel/iwlwifi/cfg/bz.c | 2 +- drivers/net/wireless/intel/iwlwifi/cfg/dr.c | 2 +- drivers/net/wireless/intel/iwlwifi/cfg/sc.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/bz.c b/drivers/net/wireless/intel/iwlwifi/cfg/bz.c index 606362463dc7..1099d8cfe6aa 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/bz.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/bz.c @@ -10,7 +10,7 @@ #include "fw/api/txq.h" /* Highest firmware core release supported */ -#define IWL_BZ_UCODE_CORE_MAX 106 +#define IWL_BZ_UCODE_CORE_MAX 107 /* Lowest firmware core release supported */ #define IWL_BZ_UCODE_CORE_MIN 102 diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/dr.c b/drivers/net/wireless/intel/iwlwifi/cfg/dr.c index 946975294b4f..a89a2c75687f 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/dr.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/dr.c @@ -9,7 +9,7 @@ #include "fw/api/txq.h" /* Highest firmware core release supported */ -#define IWL_DR_UCODE_CORE_MAX 106 +#define IWL_DR_UCODE_CORE_MAX 107 /* Lowest firmware core release supported */ #define IWL_DR_UCODE_CORE_MIN 102 diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/sc.c b/drivers/net/wireless/intel/iwlwifi/cfg/sc.c index e8240c1782ac..16abf0147fe4 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/sc.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/sc.c @@ -10,7 +10,7 @@ #include "fw/api/txq.h" /* Highest firmware core release supported */ -#define IWL_SC_UCODE_CORE_MAX 106 +#define IWL_SC_UCODE_CORE_MAX 107 /* Lowest firmware core release supported */ #define IWL_SC_UCODE_CORE_MIN 102