* [PATCH iwlwifi-next 02/15] wifi: iwlwifi: mld: validate WoWLAN notif header
From: Miri Korenblit @ 2026-07-15 19:04 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Emmanuel Grumbach
In-Reply-To: <20260715190431.327910-1-miriam.rachel.korenblit@intel.com>
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
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 <emmanuel.grumbach@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
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 */
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-next 03/15] wifi: iwlwifi: mvm/mld: fix PPE threshold debug print loop
From: Miri Korenblit @ 2026-07-15 19:04 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Johannes Berg
In-Reply-To: <20260715190431.327910-1-miriam.rachel.korenblit@intel.com>
From: Johannes Berg <johannes.berg@intel.com>
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 <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
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",
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-next 01/15] wifi: iwlwifi: mld: support aborting an ongoing ftm request
From: Miri Korenblit @ 2026-07-15 19:04 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Avraham Stern
In-Reply-To: <20260715190431.327910-1-miriam.rachel.korenblit@intel.com>
From: Avraham Stern <avraham.stern@intel.com>
Add support for aborting an ongoing FTM request.
Signed-off-by: Avraham Stern <avraham.stern@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
.../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,
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-next 04/15] wifi: iwlwifi: fix counter type in iwl_fwrt_dump_error_logs
From: Miri Korenblit @ 2026-07-15 19:04 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Emmanuel Grumbach
In-Reply-To: <20260715190431.327910-1-miriam.rachel.korenblit@intel.com>
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
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 <emmanuel.grumbach@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
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,
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-next 05/15] wifi: iwlwifi: mld: fix validation fallback in iwl_mld_notif_is_valid
From: Miri Korenblit @ 2026-07-15 19:04 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Emmanuel Grumbach
In-Reply-To: <20260715190431.327910-1-miriam.rachel.korenblit@intel.com>
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
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 <emmanuel.grumbach@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
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 {
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-next 06/15] wifi: iwlwifi: mvm: fix off-by-one in TXF key sanitiser
From: Miri Korenblit @ 2026-07-15 19:04 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Emmanuel Grumbach
In-Reply-To: <20260715190431.327910-1-miriam.rachel.korenblit@intel.com>
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
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 <emmanuel.grumbach@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
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;
}
}
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-next 07/15] wifi: iwlwifi: mld: honor FW puncturing capability in MCC response
From: Miri Korenblit @ 2026-07-15 19:04 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Pagadala Yesu Anjaneyulu
In-Reply-To: <20260715190431.327910-1-miriam.rachel.korenblit@intel.com>
From: Pagadala Yesu Anjaneyulu <pagadala.yesu.anjaneyulu@intel.com>
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 <pagadala.yesu.anjaneyulu@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
.../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)) {
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-next 08/15] wifi: iwlwifi: mvm: add LARI_CONFIG_EXTENSION command
From: Miri Korenblit @ 2026-07-15 19:04 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Pagadala Yesu Anjaneyulu
In-Reply-To: <20260715190431.327910-1-miriam.rachel.korenblit@intel.com>
From: Pagadala Yesu Anjaneyulu <pagadala.yesu.anjaneyulu@intel.com>
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 <pagadala.yesu.anjaneyulu@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
.../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.
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-next 09/15] wifi: iwlwifi: mld: add PNVM_INIT_COMPLETE_NTFY to the hcmd names
From: Miri Korenblit @ 2026-07-15 19:04 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless
In-Reply-To: <20260715190431.327910-1-miriam.rachel.korenblit@intel.com>
Add it to the array of host command name so it will be printed with
iwl_get_cmd_string
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
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.
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-next 10/15] wifi: iwlwifi: mld: fix read in wake packet notification handler
From: Miri Korenblit @ 2026-07-15 19:04 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Shahar Tzarfati
In-Reply-To: <20260715190431.327910-1-miriam.rachel.korenblit@intel.com>
From: Shahar Tzarfati <shahar.tzarfati@intel.com>
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 <shahar.tzarfati@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
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);
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-next 11/15] wifi: iwlwifi: mei: check SAP message length before reading it
From: Miri Korenblit @ 2026-07-15 19:04 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Avraham Stern
In-Reply-To: <20260715190431.327910-1-miriam.rachel.korenblit@intel.com>
From: Avraham Stern <avraham.stern@intel.com>
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 <avraham.stern@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
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 <linux/etherdevice.h>
@@ -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;
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-next 12/15] wifi: iwlwifi: mei: skip data read if length is too short
From: Miri Korenblit @ 2026-07-15 19:04 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Avraham Stern
In-Reply-To: <20260715190431.327910-1-miriam.rachel.korenblit@intel.com>
From: Avraham Stern <avraham.stern@intel.com>
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 <avraham.stern@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
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));
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-next 13/15] wifi: iwlwifi: guard against division by zero in iwl_dbg_tlv_alloc_fragments
From: Miri Korenblit @ 2026-07-15 19:04 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Emmanuel Grumbach
In-Reply-To: <20260715190431.327910-1-miriam.rachel.korenblit@intel.com>
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
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 <emmanuel.grumbach@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
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 <linux/firmware.h>
#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);
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-next 14/15] wifi: iwlwifi: mld: Do not cleanup FW state when the device is dead
From: Miri Korenblit @ 2026-07-15 19:04 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Ilan Peer
In-Reply-To: <20260715190431.327910-1-miriam.rachel.korenblit@intel.com>
From: Ilan Peer <ilan.peer@intel.com>
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 <ilan.peer@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
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);
}
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-next 15/15] wifi: iwlwifi: mei: pass correct argument to function
From: Miri Korenblit @ 2026-07-15 19:04 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Avraham Stern
In-Reply-To: <20260715190431.327910-1-miriam.rachel.korenblit@intel.com>
From: Avraham Stern <avraham.stern@intel.com>
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 <avraham.stern@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
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;
--
2.34.1
^ permalink raw reply related
* Re: [PATCH] wifi: mwifiex: replace one-element arrays with flexible array members
From: George Valkov @ 2026-07-15 22:59 UTC (permalink / raw)
To: briannorris, Kees Cook
Cc: francesco, johannes.berg, bhelgaas, error27, s.kerkmann,
linux-wireless, linux-kernel
In-Reply-To: <202607150932.F2A0836@keescook>
Thank you for your help!
Please backport to 6.18 and 6.12, which are used by OpenWrt.
v2:
- restore the unions and use DECLARE_FLEX_ARRAY
for the flexible arrays inside
- restore use of sizeof(*member) instead of sizeof(struct)
From 654af1e2be5e0d2269a108f050dfbcbf1ad79262 Mon Sep 17 00:00:00 2001
From: Georgi Valkov <gvalkov@gmail.com>
Date: Thu, 16 Jul 2026 12:28:00 +0300
Subject: [PATCH v2] wifi: mwifiex: replace one-element arrays with flexible array
members
Replace deprecated one-element arrays with flexible array members.
CONFIG_FORTIFY_SOURCE reports the following warning when
one-element arrays are used as variable-length buffers:
sta_cmd.c:1033 mwifiex_sta_prepare_cmd
memcpy: detected field-spanning write (size 84) of single field
"domain->triplet" at .../marvell/mwifiex/sta_cmd.c:1033 (size 3)
Convert affected structs to use flexible array members.
- Preserve existing wire layouts.
- Use DECLARE_FLEX_ARRAY for structs inside affected unions.
Tested-on: WRT3200ACM, OpenWrt
Signed-off-by: Georgi Valkov <gvalkov@gmail.com>
---
drivers/net/wireless/marvell/mwifiex/fw.h | 18 +++++++++---------
drivers/net/wireless/marvell/mwifiex/join.c | 8 ++++----
drivers/net/wireless/marvell/mwifiex/sta_cmd.c | 2 +-
3 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h
index e9e896606912..93561116959a 100644
--- a/drivers/net/wireless/marvell/mwifiex/fw.h
+++ b/drivers/net/wireless/marvell/mwifiex/fw.h
@@ -823,7 +823,7 @@ struct chan_band_param_set {
struct mwifiex_ie_types_chan_band_list_param_set {
struct mwifiex_ie_types_header header;
- struct chan_band_param_set chan_band_param[1];
+ struct chan_band_param_set chan_band_param[];
} __packed;
struct mwifiex_ie_types_rates_param_set {
@@ -886,7 +886,7 @@ struct mwifiex_ie_types_wildcard_ssid_params {
#define TSF_DATA_SIZE 8
struct mwifiex_ie_types_tsf_timestamp {
struct mwifiex_ie_types_header header;
- u8 tsf_data[1];
+ u8 tsf_data[];
} __packed;
struct mwifiex_cf_param_set {
@@ -903,8 +903,8 @@ struct mwifiex_ibss_param_set {
struct mwifiex_ie_types_ss_param_set {
struct mwifiex_ie_types_header header;
union {
- struct mwifiex_cf_param_set cf_param_set[1];
- struct mwifiex_ibss_param_set ibss_param_set[1];
+ DECLARE_FLEX_ARRAY(struct mwifiex_cf_param_set, cf_param_set);
+ DECLARE_FLEX_ARRAY(struct mwifiex_ibss_param_set, ibss_param_set);
} cf_ibss;
} __packed;
@@ -922,8 +922,8 @@ struct mwifiex_ds_param_set {
struct mwifiex_ie_types_phy_param_set {
struct mwifiex_ie_types_header header;
union {
- struct mwifiex_fh_param_set fh_param_set[1];
- struct mwifiex_ds_param_set ds_param_set[1];
+ DECLARE_FLEX_ARRAY(struct mwifiex_fh_param_set, fh_param_set);
+ DECLARE_FLEX_ARRAY(struct mwifiex_ds_param_set, ds_param_set);
} fh_ds;
} __packed;
@@ -1383,7 +1383,7 @@ struct host_cmd_ds_802_11_snmp_mib {
__le16 query_type;
__le16 oid;
__le16 buf_size;
- u8 value[1];
+ u8 value[];
} __packed;
struct mwifiex_rate_scope {
@@ -1551,7 +1551,7 @@ struct mwifiex_scan_cmd_config {
* TLV_TYPE_CHANLIST, mwifiex_ie_types_chan_list_param_set
* WLAN_EID_SSID, mwifiex_ie_types_ssid_param_set
*/
- u8 tlv_buf[1]; /* SSID TLV(s) and ChanList TLVs are stored
+ u8 tlv_buf[]; /* SSID TLV(s) and ChanList TLVs are stored
here */
} __packed;
@@ -1683,7 +1683,7 @@ struct host_cmd_ds_802_11_bg_scan_query_rsp {
struct mwifiex_ietypes_domain_param_set {
struct mwifiex_ie_types_header header;
u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
- struct ieee80211_country_ie_triplet triplet[1];
+ struct ieee80211_country_ie_triplet triplet[];
} __packed;
struct host_cmd_ds_802_11d_domain_info {
diff --git a/drivers/net/wireless/marvell/mwifiex/join.c b/drivers/net/wireless/marvell/mwifiex/join.c
index 5a1a0287c1d5..a83f4d081fe2 100644
--- a/drivers/net/wireless/marvell/mwifiex/join.c
+++ b/drivers/net/wireless/marvell/mwifiex/join.c
@@ -421,15 +421,15 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
phy_tlv = (struct mwifiex_ie_types_phy_param_set *) pos;
phy_tlv->header.type = cpu_to_le16(WLAN_EID_DS_PARAMS);
- phy_tlv->header.len = cpu_to_le16(sizeof(phy_tlv->fh_ds.ds_param_set));
- memcpy(&phy_tlv->fh_ds.ds_param_set,
+ phy_tlv->header.len = cpu_to_le16(sizeof(*phy_tlv->fh_ds.ds_param_set));
+ memcpy(phy_tlv->fh_ds.ds_param_set,
&bss_desc->phy_param_set.ds_param_set.current_chan,
- sizeof(phy_tlv->fh_ds.ds_param_set));
+ sizeof(*phy_tlv->fh_ds.ds_param_set));
pos += sizeof(phy_tlv->header) + le16_to_cpu(phy_tlv->header.len);
ss_tlv = (struct mwifiex_ie_types_ss_param_set *) pos;
ss_tlv->header.type = cpu_to_le16(WLAN_EID_CF_PARAMS);
- ss_tlv->header.len = cpu_to_le16(sizeof(ss_tlv->cf_ibss.cf_param_set));
+ ss_tlv->header.len = cpu_to_le16(sizeof(*ss_tlv->cf_ibss.cf_param_set));
pos += sizeof(ss_tlv->header) + le16_to_cpu(ss_tlv->header.len);
/* Get the common rates supported between the driver and the BSS Desc */
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
index 623ddde8c8e5..071f7cb305e1 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
@@ -108,7 +108,7 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv,
"cmd: SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid);
cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB);
cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_snmp_mib)
- - 1 + S_DS_GEN);
+ + S_DS_GEN);
snmp_mib->oid = cpu_to_le16((u16)cmd_oid);
if (cmd_action == HostCmd_ACT_GEN_GET) {
-- 2.55.0
> On 15 Jul 2026, at 7:35 PM, Kees Cook <kees@kernel.org> wrote:
>
> On Mon, Jul 13, 2026 at 01:23:34AM +0300, Georgi Valkov wrote:
>> Replace deprecated one-element arrays with flexible array members.
>> CONFIG_FORTIFY_SOURCE reports the following warning when
>> one-element arrays are used as variable-length buffers:
>>
>> sta_cmd.c:1033 mwifiex_sta_prepare_cmd
>> memcpy: detected field-spanning write (size 84) of single field
>> "domain->triplet" at .../marvell/mwifiex/sta_cmd.c:1033 (size 3)
>>
>> Convert affected structs to use flexible array members.
>> - Preserve existing wire layouts.
>> - Replace affected uses of sizeof(member) with sizeof(type).
>> - Replace unions containing one-element arrays with
>> u8 flexible arrays, and document the stored parameter-set type.
>>
>> Tested-on: WRT3200ACM, OpenWrt
>> Signed-off-by: Georgi Valkov <gvalkov@gmail.com>
>> ---
>> drivers/net/wireless/marvell/mwifiex/fw.h | 20 +++++++------------
>> drivers/net/wireless/marvell/mwifiex/join.c | 8 ++++----
>> .../net/wireless/marvell/mwifiex/sta_cmd.c | 2 +-
>> 3 files changed, 12 insertions(+), 18 deletions(-)
>>
>> diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h
>> index e9e896606912..ec3e3f806134 100644
>> --- a/drivers/net/wireless/marvell/mwifiex/fw.h
>> +++ b/drivers/net/wireless/marvell/mwifiex/fw.h
>> @@ -823,7 +823,7 @@ struct chan_band_param_set {
>>
>> struct mwifiex_ie_types_chan_band_list_param_set {
>> struct mwifiex_ie_types_header header;
>> - struct chan_band_param_set chan_band_param[1];
>> + struct chan_band_param_set chan_band_param[];
>> } __packed;
>>
>> struct mwifiex_ie_types_rates_param_set {
>> @@ -886,7 +886,7 @@ struct mwifiex_ie_types_wildcard_ssid_params {
>> #define TSF_DATA_SIZE 8
>> struct mwifiex_ie_types_tsf_timestamp {
>> struct mwifiex_ie_types_header header;
>> - u8 tsf_data[1];
>> + u8 tsf_data[];
>> } __packed;
>>
>> struct mwifiex_cf_param_set {
>> @@ -902,10 +902,7 @@ struct mwifiex_ibss_param_set {
>>
>> struct mwifiex_ie_types_ss_param_set {
>> struct mwifiex_ie_types_header header;
>> - union {
>> - struct mwifiex_cf_param_set cf_param_set[1];
>> - struct mwifiex_ibss_param_set ibss_param_set[1];
>> - } cf_ibss;
>> + u8 cf_ibss[]; /* CF and IBSS param sets are stored here */
>> } __packed;
>>
>> struct mwifiex_fh_param_set {
>> @@ -921,10 +918,7 @@ struct mwifiex_ds_param_set {
>>
>> struct mwifiex_ie_types_phy_param_set {
>> struct mwifiex_ie_types_header header;
>> - union {
>> - struct mwifiex_fh_param_set fh_param_set[1];
>> - struct mwifiex_ds_param_set ds_param_set[1];
>> - } fh_ds;
>> + u8 fh_ds[]; /* FH and DS param sets are stored here */
>> } __packed;
>
> This (and below) can still be a union so you don't lose the type
> information:
>
> union {
> DECLARE_FLEX_ARRAY(struct mwifiex_fh_param_set, fh_param_set);
> DECLARE_FLEX_ARRAY(struct mwifiex_ds_param_set, ds_param_set);
> } fh_ds;
>
>>
>> struct mwifiex_ie_types_auth_type {
>> @@ -1383,7 +1377,7 @@ struct host_cmd_ds_802_11_snmp_mib {
>> __le16 query_type;
>> __le16 oid;
>> __le16 buf_size;
>> - u8 value[1];
>> + u8 value[];
>> } __packed;
>>
>> struct mwifiex_rate_scope {
>> @@ -1551,7 +1545,7 @@ struct mwifiex_scan_cmd_config {
>> * TLV_TYPE_CHANLIST, mwifiex_ie_types_chan_list_param_set
>> * WLAN_EID_SSID, mwifiex_ie_types_ssid_param_set
>> */
>> - u8 tlv_buf[1]; /* SSID TLV(s) and ChanList TLVs are stored
>> + u8 tlv_buf[]; /* SSID TLV(s) and ChanList TLVs are stored
>> here */
>> } __packed;
>>
>> @@ -1683,7 +1677,7 @@ struct host_cmd_ds_802_11_bg_scan_query_rsp {
>> struct mwifiex_ietypes_domain_param_set {
>> struct mwifiex_ie_types_header header;
>> u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
>> - struct ieee80211_country_ie_triplet triplet[1];
>> + struct ieee80211_country_ie_triplet triplet[];
>> } __packed;
>>
>> struct host_cmd_ds_802_11d_domain_info {
>> diff --git a/drivers/net/wireless/marvell/mwifiex/join.c b/drivers/net/wireless/marvell/mwifiex/join.c
>> index 5a1a0287c1d5..a2c427e6af3f 100644
>> --- a/drivers/net/wireless/marvell/mwifiex/join.c
>> +++ b/drivers/net/wireless/marvell/mwifiex/join.c
>> @@ -421,15 +421,15 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
>>
>> phy_tlv = (struct mwifiex_ie_types_phy_param_set *) pos;
>> phy_tlv->header.type = cpu_to_le16(WLAN_EID_DS_PARAMS);
>> - phy_tlv->header.len = cpu_to_le16(sizeof(phy_tlv->fh_ds.ds_param_set));
>> - memcpy(&phy_tlv->fh_ds.ds_param_set,
>> + phy_tlv->header.len = cpu_to_le16(sizeof(struct mwifiex_ds_param_set));
>
> And this would become (the "*" added to get the member size):
>
> phy_tlv->header.len = cpu_to_le16(sizeof(*phy_tlv->fh_ds.ds_param_set));
>
> etc.
>
>> + memcpy(phy_tlv->fh_ds,
>> &bss_desc->phy_param_set.ds_param_set.current_chan,
>> - sizeof(phy_tlv->fh_ds.ds_param_set));
>> + sizeof(struct mwifiex_ds_param_set));
>> pos += sizeof(phy_tlv->header) + le16_to_cpu(phy_tlv->header.len);
>>
>> ss_tlv = (struct mwifiex_ie_types_ss_param_set *) pos;
>> ss_tlv->header.type = cpu_to_le16(WLAN_EID_CF_PARAMS);
>> - ss_tlv->header.len = cpu_to_le16(sizeof(ss_tlv->cf_ibss.cf_param_set));
>> + ss_tlv->header.len = cpu_to_le16(sizeof(struct mwifiex_cf_param_set));
>> pos += sizeof(ss_tlv->header) + le16_to_cpu(ss_tlv->header.len);
>>
>> /* Get the common rates supported between the driver and the BSS Desc */
>> diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
>> index 623ddde8c8e5..071f7cb305e1 100644
>> --- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
>> +++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
>> @@ -108,7 +108,7 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv,
>> "cmd: SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid);
>> cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB);
>> cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_snmp_mib)
>> - - 1 + S_DS_GEN);
>> + + S_DS_GEN);
>>
>> snmp_mib->oid = cpu_to_le16((u16)cmd_oid);
>> if (cmd_action == HostCmd_ACT_GEN_GET) {
>> --
>> 2.55.0
>>
>
> --
> Kees Cook
^ permalink raw reply related
* Re: [PATCH v2] wifi: mwifiex: bound uAP association event IEs to the event buffer
From: HE WEI(ギカク) @ 2026-07-15 23:00 UTC (permalink / raw)
To: Francesco Dolcini
Cc: Brian Norris, Miri Korenblit, Johannes Berg, Kees Cook,
Kalle Valo, linux-wireless, linux-kernel
In-Reply-To: <20260715162855.GB86836@francesco-nb>
> Where you able to test this? It looks ok, but you never know ...
>
> Reviewed-by: Francesco Dolcini <francesco.dolcini@toradex.com>
Thanks for the review and the tag. Honest answer: not on real
hardware. I don't have a mwifiex device, and the event is delivered by
the device firmware, so I could not drive EVENT_UAP_STA_ASSOC through
an actual association.
What I did verify: the driver builds on arm64 with W=1 and KASAN
enabled, no new warnings. And I checked the logic with an
AddressSanitizer userspace model of the exact arithmetic and the
cfg80211_find_ie() / for_each_element() walk. Without the patch it
faults with a heap-buffer-overflow READ one byte past the region that
stands in for the end of event_body. With this bound check applied to
the same model, the underflow and the over-claim that would run past
event_body[MAX_EVENT_SIZE] are rejected before the walk, so ASan is
clean.
A full in-kernel KASAN reproduction would need an emulated mwifiex
device (raw-gadget plus dummy_hcd for the USB case) to inject the
crafted event, which I have not set up. If anyone with the hardware
sees a uAP STA association, dumping event->len for a normal client
would also confirm that honest firmware stays well under the bound.
No change is requested, so I was not planning a respin; please tell me
if you would prefer one.
Francesco Dolcini <francesco@dolcini.it> 于2026年7月16日周四 01:28写道:
>
> On Wed, Jul 15, 2026 at 10:57:11PM +0900, HE WEI (ギカク) wrote:
> > mwifiex_process_uap_event() handles EVENT_UAP_STA_ASSOC by exposing the
> > (re)association request IEs that the firmware copies into the event:
> >
> > sinfo->assoc_req_ies = &event->data[len];
> > len = (u8 *)sinfo->assoc_req_ies - (u8 *)&event->frame_control;
> > sinfo->assoc_req_ies_len = le16_to_cpu(event->len) - (u16)len;
> >
> > event->len is supplied by the device firmware and is never validated,
> > and the subtraction is unchecked. assoc_req_ies points into
> ...
>
> >
> > Fixes: e568634ae7ac ("mwifiex: add AP event handling framework")
> > Signed-off-by: HE WEI (ギカク) <skyexpoc@gmail.com>
>
> Where you able to test this? It looks ok, but you never know ...
>
> Reviewed-by: Francesco Dolcini <francesco.dolcini@toradex.com>
>
^ permalink raw reply
* [PATCH v3] wifi: mwifiex: replace one-element arrays with flexible array members
From: Georgi Valkov @ 2026-07-16 0:17 UTC (permalink / raw)
To: briannorris, kees
Cc: francesco, johannes.berg, bhelgaas, error27, s.kerkmann,
linux-wireless, linux-kernel, gvalkov
In-Reply-To: <202607150932.F2A0836@keescook>
Replace deprecated one-element arrays with flexible array members.
CONFIG_FORTIFY_SOURCE reports the following warning when
one-element arrays are used as variable-length buffers:
sta_cmd.c:1033 mwifiex_sta_prepare_cmd
memcpy: detected field-spanning write (size 84) of single field
"domain->triplet" at .../marvell/mwifiex/sta_cmd.c:1033 (size 3)
Convert affected structs to use flexible array members.
- Preserve existing wire layouts.
- Use DECLARE_FLEX_ARRAY() for structs inside affected unions.
Tested-on: WRT3200ACM, OpenWrt
Signed-off-by: Georgi Valkov <gvalkov@gmail.com>
---
Thank you for your help!
Please backport to 6.18 and 6.12, which are used by OpenWrt.
v3:
- resend, please ignore v2 (corrupted by mail client)
v2:
- restore the unions and use DECLARE_FLEX_ARRAY
for the flexible arrays inside
- restore use of sizeof(*member) instead of sizeof(struct)
drivers/net/wireless/marvell/mwifiex/fw.h | 18 +++++++++---------
drivers/net/wireless/marvell/mwifiex/join.c | 8 ++++----
drivers/net/wireless/marvell/mwifiex/sta_cmd.c | 2 +-
3 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h
index e9e896606912..93561116959a 100644
--- a/drivers/net/wireless/marvell/mwifiex/fw.h
+++ b/drivers/net/wireless/marvell/mwifiex/fw.h
@@ -823,7 +823,7 @@ struct chan_band_param_set {
struct mwifiex_ie_types_chan_band_list_param_set {
struct mwifiex_ie_types_header header;
- struct chan_band_param_set chan_band_param[1];
+ struct chan_band_param_set chan_band_param[];
} __packed;
struct mwifiex_ie_types_rates_param_set {
@@ -886,7 +886,7 @@ struct mwifiex_ie_types_wildcard_ssid_params {
#define TSF_DATA_SIZE 8
struct mwifiex_ie_types_tsf_timestamp {
struct mwifiex_ie_types_header header;
- u8 tsf_data[1];
+ u8 tsf_data[];
} __packed;
struct mwifiex_cf_param_set {
@@ -903,8 +903,8 @@ struct mwifiex_ibss_param_set {
struct mwifiex_ie_types_ss_param_set {
struct mwifiex_ie_types_header header;
union {
- struct mwifiex_cf_param_set cf_param_set[1];
- struct mwifiex_ibss_param_set ibss_param_set[1];
+ DECLARE_FLEX_ARRAY(struct mwifiex_cf_param_set, cf_param_set);
+ DECLARE_FLEX_ARRAY(struct mwifiex_ibss_param_set, ibss_param_set);
} cf_ibss;
} __packed;
@@ -922,8 +922,8 @@ struct mwifiex_ds_param_set {
struct mwifiex_ie_types_phy_param_set {
struct mwifiex_ie_types_header header;
union {
- struct mwifiex_fh_param_set fh_param_set[1];
- struct mwifiex_ds_param_set ds_param_set[1];
+ DECLARE_FLEX_ARRAY(struct mwifiex_fh_param_set, fh_param_set);
+ DECLARE_FLEX_ARRAY(struct mwifiex_ds_param_set, ds_param_set);
} fh_ds;
} __packed;
@@ -1383,7 +1383,7 @@ struct host_cmd_ds_802_11_snmp_mib {
__le16 query_type;
__le16 oid;
__le16 buf_size;
- u8 value[1];
+ u8 value[];
} __packed;
struct mwifiex_rate_scope {
@@ -1551,7 +1551,7 @@ struct mwifiex_scan_cmd_config {
* TLV_TYPE_CHANLIST, mwifiex_ie_types_chan_list_param_set
* WLAN_EID_SSID, mwifiex_ie_types_ssid_param_set
*/
- u8 tlv_buf[1]; /* SSID TLV(s) and ChanList TLVs are stored
+ u8 tlv_buf[]; /* SSID TLV(s) and ChanList TLVs are stored
here */
} __packed;
@@ -1683,7 +1683,7 @@ struct host_cmd_ds_802_11_bg_scan_query_rsp {
struct mwifiex_ietypes_domain_param_set {
struct mwifiex_ie_types_header header;
u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
- struct ieee80211_country_ie_triplet triplet[1];
+ struct ieee80211_country_ie_triplet triplet[];
} __packed;
struct host_cmd_ds_802_11d_domain_info {
diff --git a/drivers/net/wireless/marvell/mwifiex/join.c b/drivers/net/wireless/marvell/mwifiex/join.c
index 5a1a0287c1d5..a83f4d081fe2 100644
--- a/drivers/net/wireless/marvell/mwifiex/join.c
+++ b/drivers/net/wireless/marvell/mwifiex/join.c
@@ -421,15 +421,15 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
phy_tlv = (struct mwifiex_ie_types_phy_param_set *) pos;
phy_tlv->header.type = cpu_to_le16(WLAN_EID_DS_PARAMS);
- phy_tlv->header.len = cpu_to_le16(sizeof(phy_tlv->fh_ds.ds_param_set));
- memcpy(&phy_tlv->fh_ds.ds_param_set,
+ phy_tlv->header.len = cpu_to_le16(sizeof(*phy_tlv->fh_ds.ds_param_set));
+ memcpy(phy_tlv->fh_ds.ds_param_set,
&bss_desc->phy_param_set.ds_param_set.current_chan,
- sizeof(phy_tlv->fh_ds.ds_param_set));
+ sizeof(*phy_tlv->fh_ds.ds_param_set));
pos += sizeof(phy_tlv->header) + le16_to_cpu(phy_tlv->header.len);
ss_tlv = (struct mwifiex_ie_types_ss_param_set *) pos;
ss_tlv->header.type = cpu_to_le16(WLAN_EID_CF_PARAMS);
- ss_tlv->header.len = cpu_to_le16(sizeof(ss_tlv->cf_ibss.cf_param_set));
+ ss_tlv->header.len = cpu_to_le16(sizeof(*ss_tlv->cf_ibss.cf_param_set));
pos += sizeof(ss_tlv->header) + le16_to_cpu(ss_tlv->header.len);
/* Get the common rates supported between the driver and the BSS Desc */
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
index 623ddde8c8e5..071f7cb305e1 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
@@ -108,7 +108,7 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv,
"cmd: SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid);
cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB);
cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_snmp_mib)
- - 1 + S_DS_GEN);
+ + S_DS_GEN);
snmp_mib->oid = cpu_to_le16((u16)cmd_oid);
if (cmd_action == HostCmd_ACT_GEN_GET) {
--
2.55.0
^ permalink raw reply related
* Re: [PATCH v2] wifi: ath11k/ath12k: release QMI handles on late init failures
From: Jeff Johnson @ 2026-07-16 0:59 UTC (permalink / raw)
To: Guangshuo Li, Jeff Johnson, Anilkumar Kolli, Sriram R,
Shashidhar Lakkavalli, Kalle Valo, Venkateswara Naralasetty,
Vasanthakumar Thiagarajan, Baochen Qiang, linux-wireless, ath11k,
linux-kernel, ath12k
In-Reply-To: <20260715064042.1988288-1-lgs201920130244@gmail.com>
On 7/14/2026 11:40 PM, Guangshuo Li wrote:
> ath11k and ath12k initialize their QMI handles before allocating the QMI
> event workqueues and registering the service lookups.
>
> If either of these later initialization steps fails, the functions
> return without releasing the initialized QMI handles, leaking their
> resources.
>
> Release the QMI handles on the late failure paths in both drivers.
>
> ath12k_qmi_deinit_service() uses ab->qmi.ab to determine whether QMI
> service initialization completed successfully. Set it only after all
> initialization steps succeed. Keep the ath11k assignment unchanged
> because ath11k does not use it as an initialization-success guard.
>
> Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
> Fixes: 088a099690e4 ("wifi: ath12k: fix error handling in creating hardware group")
> Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
> ---
> v2:
> - Set ath12k ab->qmi.ab only after QMI service initialization succeeds,
> as suggested by Baochen Qiang.
> - Fix the same late initialization QMI handle leak in ath11k, as
> suggested by Vasanthakumar Thiagarajan.
> - Drop the Reviewed-by tag due to the code changes.
>
> drivers/net/wireless/ath/ath11k/qmi.c | 10 ++++++++--
> drivers/net/wireless/ath/ath12k/qmi.c | 13 ++++++++++---
> 2 files changed, 18 insertions(+), 5 deletions(-)
Please split into two patches, one for ath11k and one for ath12k
^ permalink raw reply
* Re: [PATCH v2 2/3] wifi: ath11k: implement custom wake_tx_queue with flow control
From: Tamizh Raja @ 2026-07-16 1:49 UTC (permalink / raw)
To: Jose Ignacio Tornos Martinez
Cc: jjohnson, ath11k, ath12k, linux-wireless, linux-kernel
In-Reply-To: <20260715125017.277242-3-jtornosm@redhat.com>
....
>
> drivers/net/wireless/ath/ath11k/dp.c | 1 +
> drivers/net/wireless/ath/ath11k/dp.h | 2 +
> drivers/net/wireless/ath/ath11k/mac.c | 60 ++++++++++++++++++++++++++-
> 3 files changed, 62 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/wireless/ath/ath11k/dp.c b/drivers/net/wireless/ath/ath11k/dp.c
> index f389b97acbdd..2e5978ec2b05 100644
> --- a/drivers/net/wireless/ath/ath11k/dp.c
> +++ b/drivers/net/wireless/ath/ath11k/dp.c
> @@ -1087,6 +1087,7 @@ int ath11k_dp_alloc(struct ath11k_base *ab)
> for (i = 0; i < ab->hw_params.hal_params->num_tx_rings; i++) {
> idr_init(&dp->tx_ring[i].txbuf_idr);
> spin_lock_init(&dp->tx_ring[i].tx_idr_lock);
> + spin_lock_init(&dp->tx_ring[i].wake_tx_lock);
> dp->tx_ring[i].tcl_data_ring_id = i;
>
> dp->tx_ring[i].tx_status_head = 0;
> diff --git a/drivers/net/wireless/ath/ath11k/dp.h b/drivers/net/wireless/ath/ath11k/dp.h
> index 84f66839f0c6..6d99501aa269 100644
> --- a/drivers/net/wireless/ath/ath11k/dp.h
> +++ b/drivers/net/wireless/ath/ath11k/dp.h
> @@ -87,6 +87,8 @@ struct dp_tx_ring {
> struct idr txbuf_idr;
> /* Protects txbuf_idr and num_pending */
> spinlock_t tx_idr_lock;
> + /* Serializes wake_tx_queue operations for this ring */
> + spinlock_t wake_tx_lock;
> struct hal_wbm_release_ring *tx_status;
> int tx_status_head;
> int tx_status_tail;
> diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
> index 2d55cdc4d165..046cefd53178 100644
> --- a/drivers/net/wireless/ath/ath11k/mac.c
> +++ b/drivers/net/wireless/ath/ath11k/mac.c
> @@ -10065,9 +10065,67 @@ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw,
> return ret;
> }
>
> +static void ath11k_mac_op_wake_tx_queue(struct ieee80211_hw *hw,
> + struct ieee80211_txq *txq)
> +{
> + struct ieee80211_tx_control control = {
> + .sta = txq->sta,
> + };
> + const struct sk_buff *peek_skb;
> + struct ath11k *ar = hw->priv;
> + struct dp_tx_ring *tx_ring;
> + struct hal_srng *tcl_ring;
> + struct sk_buff *skb;
> + u32 ring_selector;
> + int num_free;
> + u8 ring_id;
> +
> + if (!ar)
> + return;
> +
> + while (1) {
> + if (unlikely(test_bit(ATH11K_FLAG_CRASH_FLUSH,
> + &ar->ab->dev_flags)))
> + break;
> +
> + peek_skb = ieee80211_tx_peek(hw, txq);
in ieee80211_tx_peek() acquires fq->lock, peeks at the skb, releases
the lock, then returns the pointer.
Between spin_unlock_bh(&fq->lock) and using the pointer for
ring_selector. The same skb can also be returned for
the another CPU which calls this function. This may cause use after a
free scenario.
> + if (!peek_skb)
> + break;
> +
> + ring_selector = ar->ab->hw_params.hw_ops->get_ring_selector(
> + (struct sk_buff *)peek_skb);
> + ring_id = ring_selector %
> + ar->ab->hw_params.hal_params->num_tx_rings;
> +
> + tx_ring = &ar->ab->dp.tx_ring[ring_id];
> + tcl_ring = &ar->ab->hal.srng_list[tx_ring->tcl_data_ring.ring_id];
> +
> + spin_lock_bh(&tx_ring->wake_tx_lock);
> +
> + spin_lock(&tcl_ring->lock);
> + num_free = ath11k_hal_srng_src_num_free(ar->ab, tcl_ring, true);
> + spin_unlock(&tcl_ring->lock);
> +
> + if (num_free == 0) {
> + spin_unlock_bh(&tx_ring->wake_tx_lock);
> + break;
> + }
> +
> + skb = ieee80211_tx_dequeue(hw, txq);
> + if (!skb) {
> + spin_unlock_bh(&tx_ring->wake_tx_lock);
> + break;
> + }
> +
> + ath11k_mac_op_tx(hw, &control, skb);
> +
> + spin_unlock_bh(&tx_ring->wake_tx_lock);
> + }
> +}
> +
> static const struct ieee80211_ops ath11k_ops = {
> .tx = ath11k_mac_op_tx,
> - .wake_tx_queue = ieee80211_handle_wake_tx_queue,
> + .wake_tx_queue = ath11k_mac_op_wake_tx_queue,
> .start = ath11k_mac_op_start,
> .stop = ath11k_mac_op_stop,
> .reconfig_complete = ath11k_mac_op_reconfig_complete,
> --
> 2.54.0
>
>
--
- Tamizh.
^ permalink raw reply
* Re: [PATCH v2 3/3] wifi: ath12k: implement custom wake_tx_queue with flow control
From: Tamizh Raja @ 2026-07-16 1:57 UTC (permalink / raw)
To: Jose Ignacio Tornos Martinez
Cc: jjohnson, ath11k, ath12k, linux-wireless, linux-kernel
In-Reply-To: <20260715125017.277242-4-jtornosm@redhat.com>
On Wed, Jul 15, 2026 at 6:21 PM Jose Ignacio Tornos Martinez
<jtornosm@redhat.com> wrote:
>
> Under heavy traffic, ath12k can hang and experiences -ENOMEM errors
> ("failed to transmit frame -12") when the hardware TCL ring fills up.
> This issue is more commonly observed in VMs with PCIe passthrough but
> also occurs on bare metal systems.
>
> Implement a custom wake_tx_queue operation that:
>
> 1. Checks hardware ring space before dequeuing packets from mac80211
> 2. Uses per-ring locking to serialize ring access and prevent races
> 3. Syncs with hardware state to get accurate free slot count
> 4. Uses ieee80211_tx_peek() to determine the exact target ring via
> get_ring_selector(), matching dp_tx on all platforms
> 5. Returns early during firmware crash in the same way as other
> tx paths
>
> This approach follows the pattern used in the iwlwifi driver, adapted
> for ath12k's hardware ring architecture.
>
> This prevents hangs, eliminates -ENOMEM errors, and improves throughput
> by optimizing resource usage and preventing unnecessary packet drops.
>
> Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
.....
> drivers/net/wireless/ath/ath12k/dp.c | 1 +
> drivers/net/wireless/ath/ath12k/dp.h | 2 +
> drivers/net/wireless/ath/ath12k/hal.c | 1 +
> drivers/net/wireless/ath/ath12k/wifi7/hw.c | 65 +++++++++++++++++++++-
> 4 files changed, 68 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c
> index af5f11fc1d84..3d46cfbf0a1c 100644
> --- a/drivers/net/wireless/ath/ath12k/dp.c
> +++ b/drivers/net/wireless/ath/ath12k/dp.c
> @@ -1539,6 +1539,7 @@ static int ath12k_dp_setup(struct ath12k_base *ab)
> }
>
> for (i = 0; i < ab->hw_params->max_tx_ring; i++) {
> + spin_lock_init(&dp->tx_ring[i].wake_tx_lock);
> dp->tx_ring[i].tcl_data_ring_id = i;
>
> dp->tx_ring[i].tx_status_head = 0;
> diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h
> index f8cfc7bb29dd..68d2020be9b8 100644
> --- a/drivers/net/wireless/ath/ath12k/dp.h
> +++ b/drivers/net/wireless/ath/ath12k/dp.h
> @@ -58,6 +58,8 @@ struct dp_tx_ring {
> u8 tcl_data_ring_id;
> struct dp_srng tcl_data_ring;
> struct dp_srng tcl_comp_ring;
> + /* Serializes wake_tx_queue operations for this ring */
> + spinlock_t wake_tx_lock;
> struct hal_wbm_completion_ring_tx *tx_status;
> int tx_status_head;
> int tx_status_tail;
> diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c
> index a164563fff28..c1c656e4550b 100644
> --- a/drivers/net/wireless/ath/ath12k/hal.c
> +++ b/drivers/net/wireless/ath/ath12k/hal.c
> @@ -390,6 +390,7 @@ int ath12k_hal_srng_src_num_free(struct ath12k_base *ab, struct hal_srng *srng,
> else
> return ((srng->ring_size - hp + tp) / srng->entry_size) - 1;
> }
> +EXPORT_SYMBOL(ath12k_hal_srng_src_num_free);
>
> void *ath12k_hal_srng_src_next_peek(struct ath12k_base *ab,
> struct hal_srng *srng)
> diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
> index d9fdd2fc8298..306d51da3ea1 100644
> --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c
> +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
> @@ -1100,9 +1100,72 @@ static void ath12k_wifi7_mac_op_tx(struct ieee80211_hw *hw,
> }
> }
>
> +static void ath12k_wifi7_mac_op_wake_tx_queue(struct ieee80211_hw *hw,
> + struct ieee80211_txq *txq)
> +{
> + struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(txq->vif);
Is txq->vif always valid? Do we need a NULL check here?
> + struct ath12k_link_vif *arvif = &ahvif->deflink;
> + struct ieee80211_tx_control control = {
> + .sta = txq->sta,
> + };
> + const struct sk_buff *peek_skb;
> + struct dp_tx_ring *tx_ring;
> + struct hal_srng *tcl_ring;
> + struct ath12k_dp *dp;
> + struct sk_buff *skb;
> + struct ath12k *ar;
> + u32 ring_selector;
> + int num_free;
> + u8 ring_id;
> +
> + ar = arvif->ar;
Shouldn't we check the link_id for fetching proper arvif? this code
always chooses deflink ar and dp for packet transmission.
This needs to use the same link selection logic as op_tx.
> + if (!ar)
> + return;
> +
> + dp = ar->ab->dp;
> +
> + while (1) {
> + if (unlikely(test_bit(ATH12K_FLAG_CRASH_FLUSH,
> + &ar->ab->dev_flags)))
> + break;
> +
> + peek_skb = ieee80211_tx_peek(hw, txq);
> + if (!peek_skb)
> + break;
> +
> + ring_selector = dp->hw_params->hw_ops->get_ring_selector(
> + (struct sk_buff *)peek_skb);
> + ring_id = ring_selector % dp->hw_params->max_tx_ring;
> +
> + tx_ring = &dp->tx_ring[ring_id];
> + tcl_ring = &dp->hal->srng_list[tx_ring->tcl_data_ring.ring_id];
> +
> + spin_lock_bh(&tx_ring->wake_tx_lock);
> +
> + spin_lock(&tcl_ring->lock);
> + num_free = ath12k_hal_srng_src_num_free(ar->ab, tcl_ring, true);
> + spin_unlock(&tcl_ring->lock);
> +
> + if (num_free == 0) {
> + spin_unlock_bh(&tx_ring->wake_tx_lock);
> + break;
> + }
> +
> + skb = ieee80211_tx_dequeue(hw, txq);
> + if (!skb) {
> + spin_unlock_bh(&tx_ring->wake_tx_lock);
> + break;
> + }
> +
> + ath12k_wifi7_mac_op_tx(hw, &control, skb);
> +
> + spin_unlock_bh(&tx_ring->wake_tx_lock);
> + }
> +}
> +
> static const struct ieee80211_ops ath12k_ops_wifi7 = {
> .tx = ath12k_wifi7_mac_op_tx,
> - .wake_tx_queue = ieee80211_handle_wake_tx_queue,
> + .wake_tx_queue = ath12k_wifi7_mac_op_wake_tx_queue,
> .start = ath12k_mac_op_start,
> .stop = ath12k_mac_op_stop,
> .reconfig_complete = ath12k_mac_op_reconfig_complete,
> --
> 2.54.0
>
>
--
- Tamizh.
^ permalink raw reply
* [PATCH] NFC: trf7970a: Remove redundant dev_err()
From: Pan Chuang @ 2026-07-16 3:16 UTC (permalink / raw)
To: Mark Greer, David Heidelberg, open list:TI TRF7970A NFC DRIVER,
open list:NFC SUBSYSTEM, open list
Cc: Pan Chuang
Since commit 55b48e23f5c4 ("genirq/devres: Add error handling in
devm_request_*_irq()"), devm_request_threaded_irq() automatically logs
detailed error messages on failure. Remove the now-redundant
driver-specific dev_err() calls.
Signed-off-by: Pan Chuang <panchuang@vivo.com>
---
drivers/nfc/trf7970a.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c
index f22e091019de..277483b7a110 100644
--- a/drivers/nfc/trf7970a.c
+++ b/drivers/nfc/trf7970a.c
@@ -2128,10 +2128,8 @@ static int trf7970a_probe(struct spi_device *spi)
trf7970a_irq,
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
"trf7970a", trf);
- if (ret) {
- dev_err(trf->dev, "Can't request IRQ#%d: %d\n", spi->irq, ret);
+ if (ret)
return ret;
- }
mutex_init(&trf->lock);
INIT_DELAYED_WORK(&trf->timeout_work, trf7970a_timeout_work_handler);
--
2.34.1
^ permalink raw reply related
* [PATCH 0/2] Enable WiFi on Spacemit K3 Pico ITX
From: Anirudh Srinivasan @ 2026-07-16 3:21 UTC (permalink / raw)
To: Bjorn Helgaas, Yixun Lan, Ping-Ke Shih, Lorenzo Pieralisi,
Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
Inochi Amaoto
Cc: linux-pci, linux-kernel, linux-riscv, spacemit, linux-wireless,
Anirudh Srinivasan
The Spacemit K3 Pico ITX has a RTL8852BE Wifi card attached via PCIe.
The probe for the rtw89 driver currently fails because driver tries to
allocate a kernel page with GFP_DMA32, and this board has memory only
above the 32 bit range. The rtw89 driver has the ability to use 36 bit
DMA addresses, but this is only enabled for certain PCIe bridge/rootport
that have been validated to work on. Enable this ability for the PCIe
root port. A similar patch seems to exist in the vendor kernel tree.
To test this, you'll need the 3 patch series adding the K3 PCIe RC
Driver[1], K3 PCIe Phy[2] and K3 PCIe DTS[3].I have marked only [1] as
a depedency in b4 because this series doesn't depend on [2] or [3] to be
applied cleanly.
Inochi, Patch 1 could be potentially be merged in with your series [1],
any thougts on this?
One question I had was about whether the IOMMU on the K3 could be used
to do DMA mappings and allow the wifi card to work with a 32 bit virtual
address. The K3's IOMMU isn't supported currently in the kernel DT. It
seems to not be enabled in the vendor kernel too. Even if the IOMMU was
enabled, I'm not sure if it would help with this exact problem. The fix
proposed in this patch works to solve this problem, so I've sent it to
the list.
[1] https://lore.kernel.org/spacemit/20260709040027.958400-1-inochiama@gmail.com/
[2] https://lore.kernel.org/spacemit/20260703021024.495433-1-inochiama@gmail.com/
[3] https://lore.kernel.org/spacemit/20260709040415.977784-1-inochiama@gmail.com/
Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
---
Anirudh Srinivasan (2):
PCI: Move Spacemit vendor and device ID to linux/pci_Ids.h
wifi: rtw89: pci: enable 36-bit DMA on spacemit K3
drivers/net/wireless/realtek/rtw89/pci.c | 4 ++++
drivers/pci/controller/dwc/pcie-spacemit-k1.c | 4 ----
include/linux/pci_ids.h | 4 ++++
3 files changed, 8 insertions(+), 4 deletions(-)
---
base-commit: 728e68a889bcf257b1e67298b12c360e5c3a13e0
change-id: 20260715-rtw89-spacemit-k3-a37c9771b3c3
prerequisite-message-id: <20260709040027.958400-1-inochiama@gmail.com>
prerequisite-patch-id: ab02c35a752a1e8f0fff9bc06ebcf8961afef933
prerequisite-patch-id: e7cececa9950600cfeee3dc6d73d6c3a7cc16f32
prerequisite-patch-id: 49ba2fa5aa2d2069b8d857bbda6cc4813bfc015f
prerequisite-patch-id: f33c229b37442babb1289af29a33fd2a222304f0
prerequisite-patch-id: c91a780415fe64f11fe921761d213634d042fac7
prerequisite-patch-id: b2bbf0fe6a7d90be354bb266d311982ead5a0e6d
Best regards,
--
Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
^ permalink raw reply
* [PATCH 1/2] PCI: Move Spacemit vendor and device ID to linux/pci_Ids.h
From: Anirudh Srinivasan @ 2026-07-16 3:21 UTC (permalink / raw)
To: Bjorn Helgaas, Yixun Lan, Ping-Ke Shih, Lorenzo Pieralisi,
Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
Inochi Amaoto
Cc: linux-pci, linux-kernel, linux-riscv, spacemit, linux-wireless,
Anirudh Srinivasan
In-Reply-To: <20260715-rtw89-spacemit-k3-v1-0-e577bc63706b@oss.tenstorrent.com>
Move the vendor and device IDs for Spacemit PCIe Root Complexes to
include/linux/pci_ids.h so that they can be referenced elsewhere.
Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
---
drivers/pci/controller/dwc/pcie-spacemit-k1.c | 4 ----
include/linux/pci_ids.h | 4 ++++
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-spacemit-k1.c b/drivers/pci/controller/dwc/pcie-spacemit-k1.c
index 680acc93f5395..7b0bc1802954a 100644
--- a/drivers/pci/controller/dwc/pcie-spacemit-k1.c
+++ b/drivers/pci/controller/dwc/pcie-spacemit-k1.c
@@ -21,10 +21,6 @@
#include "pcie-designware.h"
-#define PCI_VENDOR_ID_SPACEMIT 0x201f
-#define PCI_DEVICE_ID_SPACEMIT_K1 0x0001
-#define PCI_DEVICE_ID_SPACEMIT_K3 0x0002
-
/* Offsets and field definitions for link management registers */
#define K1_PHY_AHB_IRQ_EN 0x0000
#define PCIE_INTERRUPT_EN BIT(0)
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 1c9d40e09107d..d6f26cacc8e35 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2640,6 +2640,10 @@
#define PCI_VENDOR_ID_SUNIX 0x1fd4
#define PCI_DEVICE_ID_SUNIX_1999 0x1999
+#define PCI_VENDOR_ID_SPACEMIT 0x201f
+#define PCI_DEVICE_ID_SPACEMIT_K1 0x0001
+#define PCI_DEVICE_ID_SPACEMIT_K3 0x0002
+
#define PCI_VENDOR_ID_HINT 0x3388
#define PCI_DEVICE_ID_HINT_VXPROII_IDE 0x8013
--
2.43.0
^ permalink raw reply related
* [PATCH 2/2] wifi: rtw89: pci: enable 36-bit DMA on spacemit K3
From: Anirudh Srinivasan @ 2026-07-16 3:21 UTC (permalink / raw)
To: Bjorn Helgaas, Yixun Lan, Ping-Ke Shih, Lorenzo Pieralisi,
Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
Inochi Amaoto
Cc: linux-pci, linux-kernel, linux-riscv, spacemit, linux-wireless,
Anirudh Srinivasan
In-Reply-To: <20260715-rtw89-spacemit-k3-v1-0-e577bc63706b@oss.tenstorrent.com>
The Spacemit K3 Pico ITX Board has a RTL8852BE pcie card behind a PCIe
root port, but the SoC doesn't have any 32 DMA addreseses which the
rtw89 seems to use by default. Enable 36 bit DMA ability that the driver
has when this particular root port is detected so that the driver can
probe on this SoC.
Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
---
drivers/net/wireless/realtek/rtw89/pci.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c
index 102bae4881805..c5b82fc46d063 100644
--- a/drivers/net/wireless/realtek/rtw89/pci.c
+++ b/drivers/net/wireless/realtek/rtw89/pci.c
@@ -3326,6 +3326,10 @@ static bool rtw89_pci_is_dac_compatible_bridge(struct rtw89_dev *rtwdev)
if (bridge->device == 0x2806)
return true;
break;
+ case PCI_VENDOR_ID_SPACEMIT:
+ if (bridge->device == PCI_DEVICE_ID_SPACEMIT_K3)
+ return true;
+ break;
}
return false;
--
2.43.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox