* [PATCH iwlwifi-fixes 03/15] wifi: iwlwifi: mld: fix an off-by-1 boundary check
From: Miri Korenblit @ 2026-07-14 11:19 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Emmanuel Grumbach
In-Reply-To: <20260714141909.fdf31f494f1c.I70d01ed2023f6584fb23ea8ab344a93d222cc4c0@changeid>
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Before looking at the 11th byte, check the length is big enough.
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/mac80211.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
index 17286b3341c0..9ac17be30400 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
@@ -1708,7 +1708,7 @@ static void iwl_mld_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy,
elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY, ies->data,
ies->len);
- if (!elem || elem->datalen < 10 ||
+ if (!elem || elem->datalen < 11 ||
!(elem->data[10] &
WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT)) {
*tolerated = false;
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-fixes 02/15] wifi: iwlwifi: mvm: fix an off-by-1 boundary check
From: Miri Korenblit @ 2026-07-14 11:19 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Emmanuel Grumbach, Ilan Peer
In-Reply-To: <20260714141909.fdf31f494f1c.I70d01ed2023f6584fb23ea8ab344a93d222cc4c0@changeid>
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Before looking at the 11th byte, check the length is big enough.
Fixes: 4f58121dc40a ("iwlwifi: mvm: Block 26-tone RU OFDMA transmissions")
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Reviewed-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 74bd4038fd56..48cc10db7b96 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -3490,7 +3490,7 @@ static void iwl_mvm_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy,
elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY, ies->data,
ies->len);
- if (!elem || elem->datalen < 10 ||
+ if (!elem || elem->datalen < 11 ||
!(elem->data[10] &
WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT)) {
data->tolerated = false;
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-fixes 01/15] wifi: iwlwifi: mvm: verify scan id reported by firmware
From: Miri Korenblit @ 2026-07-14 11:19 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Avraham Stern
From: Avraham Stern <avraham.stern@intel.com>
The scan id reported by firmware in scan complete notification is
used as an index to the scan status array. Verify the reported id
does not exceed the array size.
Fixes: 8d14ccd878e5 ("iwlwifi: mvm: make UMAC scans use the stopping scan status")
Signed-off-by: Avraham Stern <avraham.stern@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
index 79829f775c89..42f9d9a713b8 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
@@ -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
*/
@@ -3217,6 +3217,10 @@ void iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm,
mvm->mei_scan_filter.is_mei_limited_scan = false;
+ if (IWL_FW_CHECK(mvm, uid >= ARRAY_SIZE(mvm->scan_uid_status),
+ "FW reports out-of-range scan UID %d\n", uid))
+ return;
+
IWL_DEBUG_SCAN(mvm,
"Scan completed: uid=%u type=%u, status=%s, EBS=%s\n",
uid, mvm->scan_uid_status[uid],
--
2.34.1
^ permalink raw reply related
* [PATCH wireless] wifi: mac80211: copy aggregation information
From: Miri Korenblit @ 2026-07-14 11:10 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Benjamin Berg
From: Benjamin Berg <benjamin.berg@intel.com>
This information can be considered part of the capabilities and should
also be copied to the NAN data station.
Fixes: 27e9b326b674 ("wifi: mac80211: support NAN stations")
Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
net/mac80211/cfg.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index b00191e02a63..43f142624d33 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2611,6 +2611,9 @@ static int sta_apply_parameters(struct ieee80211_local *local,
memcpy(&sta->deflink.pub->supp_rates,
&nmi_sta->deflink.pub->supp_rates,
sizeof(sta->deflink.pub->supp_rates));
+
+ sta->deflink.pub->agg = nmi_sta->deflink.pub->agg;
+ __ieee80211_sta_recalc_aggregates(sta, 0);
}
/* set the STA state after all sta info from usermode has been set */
--
2.34.1
^ permalink raw reply related
* [PATCH v2 wireless-next 2/2] wifi: mac80211: parse enhanced critical updates field
From: Miri Korenblit @ 2026-07-14 10:43 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Johannes Berg
In-Reply-To: <20260714134154.e2fb22738aa1.Id86c1bd6ddb5ec13ad9cbf24fd36b8246f351fe6@changeid>
From: Johannes Berg <johannes.berg@intel.com>
For association and link reconfiguration response, parse
and store the enhanced BSS parameter change counter out
of the enhanced critical updates field in the multi-link
common info or per-STA profile. These are required for
UHR connections.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
include/linux/ieee80211-eht.h | 92 +++++++++++++++++++++++++++++++++++
include/net/mac80211.h | 6 +++
net/mac80211/mlme.c | 38 ++++++++++++++-
3 files changed, 134 insertions(+), 2 deletions(-)
diff --git a/include/linux/ieee80211-eht.h b/include/linux/ieee80211-eht.h
index 18f9c662cf4c..928811328bb0 100644
--- a/include/linux/ieee80211-eht.h
+++ b/include/linux/ieee80211-eht.h
@@ -481,6 +481,7 @@ struct ieee80211_multi_link_elem {
#define IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP 0x0100
#define IEEE80211_MLC_BASIC_PRES_MLD_ID 0x0200
#define IEEE80211_MLC_BASIC_PRES_EXT_MLD_CAPA_OP 0x0400
+#define IEEE80211_MLC_BASIC_PRES_ENH_CRIT_UPD 0x0800
#define IEEE80211_MED_SYNC_DELAY_DURATION 0x00ff
#define IEEE80211_MED_SYNC_DELAY_SYNC_OFDM_ED_THRESH 0x0f00
@@ -809,6 +810,49 @@ static inline u16 ieee80211_mle_get_ext_mld_capa_op(const u8 *data)
return get_unaligned_le16(common);
}
+/**
+ * ieee80211_mle_get_enh_crit_upd_info - returns the enhanced critical
+ * updates information
+ * @data: pointer to the multi-link element
+ * Return: the enhanced critical updates information field, or %NULL
+ *
+ * The element is assumed to be of the correct type (BASIC) and big enough,
+ * this must be checked using ieee80211_mle_type_ok().
+ */
+static inline const struct ieee80211_enh_crit_upd *
+ieee80211_mle_get_enh_crit_upd_info(const u8 *data)
+{
+ const struct ieee80211_multi_link_elem *mle = (const void *)data;
+ u16 control = le16_to_cpu(mle->control);
+ const u8 *common = mle->variable;
+
+ /*
+ * common points now at the beginning of
+ * ieee80211_mle_basic_common_info
+ */
+ common += sizeof(struct ieee80211_mle_basic_common_info);
+
+ if (!(control & IEEE80211_MLC_BASIC_PRES_ENH_CRIT_UPD))
+ return NULL;
+
+ if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID)
+ common += 1;
+ if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT)
+ common += 1;
+ if (control & IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY)
+ common += 2;
+ if (control & IEEE80211_MLC_BASIC_PRES_EML_CAPA)
+ common += 2;
+ if (control & IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP)
+ common += 2;
+ if (control & IEEE80211_MLC_BASIC_PRES_MLD_ID)
+ common += 1;
+ if (control & IEEE80211_MLC_BASIC_PRES_EXT_MLD_CAPA_OP)
+ common += 2;
+
+ return (const void *)common;
+}
+
/**
* ieee80211_mle_get_mld_id - returns the MLD ID
* @data: pointer to the multi-link element
@@ -883,6 +927,8 @@ static inline bool ieee80211_mle_size_ok(const u8 *data, size_t len)
common += 1;
if (control & IEEE80211_MLC_BASIC_PRES_EXT_MLD_CAPA_OP)
common += 2;
+ if (control & IEEE80211_MLC_BASIC_PRES_ENH_CRIT_UPD)
+ common += 1;
break;
case IEEE80211_ML_CONTROL_TYPE_PREQ:
common += sizeof(struct ieee80211_mle_preq_common_info);
@@ -959,6 +1005,8 @@ enum ieee80211_mle_subelems {
#define IEEE80211_MLE_STA_CONTROL_NSTR_LINK_PAIR_PRESENT 0x0200
#define IEEE80211_MLE_STA_CONTROL_NSTR_BITMAP_SIZE 0x0400
#define IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT 0x0800
+#define IEEE80211_MLE_STA_CONTROL_ENH_CRIT_UPD_PRESENT 0x1000
+#define IEEE80211_MLE_STA_CONTROL_AP_CONDUCTED_TX_PWR_PRESENT 0x2000
struct ieee80211_mle_per_sta_profile {
__le16 control;
@@ -1004,6 +1052,12 @@ static inline bool ieee80211_mle_basic_sta_prof_size_ok(const u8 *data,
if (control & IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT)
info_len += 1;
+ if (control & IEEE80211_MLE_STA_CONTROL_ENH_CRIT_UPD_PRESENT)
+ info_len += 1;
+
+ if (control & IEEE80211_MLE_STA_CONTROL_AP_CONDUCTED_TX_PWR_PRESENT)
+ info_len += 1;
+
return prof->sta_info_len >= info_len &&
fixed + prof->sta_info_len - 1 <= len;
}
@@ -1044,6 +1098,44 @@ ieee80211_mle_basic_sta_prof_bss_param_ch_cnt(const struct ieee80211_mle_per_sta
return *pos;
}
+/**
+ * ieee80211_mle_basic_sta_prof_enh_crit_upd - get per-STA profile enhanced
+ * critical updates field
+ * @prof: the per-STA profile, having been checked with
+ * ieee80211_mle_basic_sta_prof_size_ok() for the correct length
+ *
+ * Return: The enhanced critical updates field if present, %NULL otherwise.
+ */
+static inline const struct ieee80211_enh_crit_upd *
+ieee80211_mle_basic_sta_prof_enh_crit_upd(const struct ieee80211_mle_per_sta_profile *prof)
+{
+ u16 control = le16_to_cpu(prof->control);
+ const u8 *pos = prof->variable;
+
+ if (!(control & IEEE80211_MLE_STA_CONTROL_ENH_CRIT_UPD_PRESENT))
+ return NULL;
+
+ if (control & IEEE80211_MLE_STA_CONTROL_STA_MAC_ADDR_PRESENT)
+ pos += 6;
+ if (control & IEEE80211_MLE_STA_CONTROL_BEACON_INT_PRESENT)
+ pos += 2;
+ if (control & IEEE80211_MLE_STA_CONTROL_TSF_OFFS_PRESENT)
+ pos += 8;
+ if (control & IEEE80211_MLE_STA_CONTROL_DTIM_INFO_PRESENT)
+ pos += 2;
+ if (control & IEEE80211_MLE_STA_CONTROL_COMPLETE_PROFILE &&
+ control & IEEE80211_MLE_STA_CONTROL_NSTR_LINK_PAIR_PRESENT) {
+ if (control & IEEE80211_MLE_STA_CONTROL_NSTR_BITMAP_SIZE)
+ pos += 2;
+ else
+ pos += 1;
+ }
+ if (control & IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT)
+ pos += 1;
+
+ return (const void *)pos;
+}
+
#define IEEE80211_MLE_STA_RECONF_CONTROL_LINK_ID 0x000f
#define IEEE80211_MLE_STA_RECONF_CONTROL_COMPLETE_PROFILE 0x0010
#define IEEE80211_MLE_STA_RECONF_CONTROL_STA_MAC_ADDR_PRESENT 0x0020
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 4f95da023746..948a7cdab27c 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -790,6 +790,10 @@ struct ieee80211_bss_npca_params {
* be updated to 1, even if bss_param_ch_cnt didn't change. This allows
* the link to know that it heard the latest value from its own beacon
* (as opposed to hearing its value from another link's beacon).
+ * @enh_bss_param_ch_cnt: In BSS-mode, the enhanced BSS parameters change
+ * counter. See @bss_param_ch_cnt, it works the same way.
+ * @enh_bss_param_ch_cnt_link_id: In BSS-mode, the link_id for the enhanced
+ * BSS parameter change counter, see @bss_param_ch_cnt_link_id.
* @s1g_long_beacon_period: number of beacon intervals between each long
* beacon transmission.
* @npca: NPCA parameters
@@ -894,6 +898,8 @@ struct ieee80211_bss_conf {
u8 bss_param_ch_cnt;
u8 bss_param_ch_cnt_link_id;
+ u8 enh_bss_param_ch_cnt;
+ u8 enh_bss_param_ch_cnt_link_id;
u8 s1g_long_beacon_period;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index f1172a950284..5827a34ba6a7 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -5925,11 +5925,28 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
ieee80211_mle_basic_sta_prof_bss_param_ch_cnt(elems->prof);
bss_conf->bss_param_ch_cnt = bss_param_ch_cnt;
bss_conf->bss_param_ch_cnt_link_id = link_id;
+
+ if (link->u.mgd.conn.mode >= IEEE80211_CONN_MODE_UHR) {
+ const struct ieee80211_enh_crit_upd *enh_crit_upd;
+
+ enh_crit_upd = ieee80211_mle_basic_sta_prof_enh_crit_upd(elems->prof);
+ if (!enh_crit_upd) {
+ link_info(link,
+ "per-STA profile missing enhanced critical updates\n");
+ ret = false;
+ goto out;
+ }
+
+ bss_conf->enh_bss_param_ch_cnt =
+ u8_get_bits(enh_crit_upd->v,
+ IEEE80211_ENH_CRIT_UPD_EBPCC);
+ bss_conf->enh_bss_param_ch_cnt_link_id = link_id;
+ }
}
if (link_id == assoc_data->assoc_link_id && elems->ml_basic) {
- int bss_param_ch_cnt =
- ieee80211_mle_get_bss_param_ch_cnt((const void *)elems->ml_basic);
+ const void *mle = (const void *)elems->ml_basic;
+ int bss_param_ch_cnt = ieee80211_mle_get_bss_param_ch_cnt(mle);
if (bss_param_ch_cnt < 0) {
sdata_info(sdata,
@@ -5939,6 +5956,23 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
}
bss_conf->bss_param_ch_cnt = bss_param_ch_cnt;
bss_conf->bss_param_ch_cnt_link_id = link_id;
+
+ if (link->u.mgd.conn.mode >= IEEE80211_CONN_MODE_UHR) {
+ const struct ieee80211_enh_crit_upd *enh_crit_upd;
+
+ enh_crit_upd = ieee80211_mle_get_enh_crit_upd_info(mle);
+ if (!enh_crit_upd) {
+ link_info(link,
+ "No enhanced critical updates in assoc response\n");
+ ret = false;
+ goto out;
+ }
+
+ bss_conf->enh_bss_param_ch_cnt =
+ u8_get_bits(enh_crit_upd->v,
+ IEEE80211_ENH_CRIT_UPD_EBPCC);
+ bss_conf->enh_bss_param_ch_cnt_link_id = link_id;
+ }
}
if (!is_s1g && !elems->supp_rates) {
--
2.34.1
^ permalink raw reply related
* [PATCH v2 wireless-next 1/2] wifi: mac80211: refactor multi-link assoc response parsing
From: Miri Korenblit @ 2026-07-14 10:43 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Johannes Berg
From: Johannes Berg <johannes.berg@intel.com>
Refactor the parsing code a bit, introducing specific error
messages for the various failures and moving the BSS parameter
change count parsing out a level to be easier to extend for
UHR.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
net/mac80211/mlme.c | 53 ++++++++++++++++++++++++++++-----------------
1 file changed, 33 insertions(+), 20 deletions(-)
---
v2: add another patch which is dependent on this one
---
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 9e92337bb6f9..f1172a950284 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -5871,8 +5871,6 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
const struct cfg80211_bss_ies *bss_ies = NULL;
struct ieee80211_supported_band *sband;
struct ieee802_11_elems *elems;
- const __le16 prof_bss_param_ch_present =
- cpu_to_le16(IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT);
u16 capab_info;
bool ret;
@@ -5888,20 +5886,13 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
* successful, so set the status directly to success
*/
assoc_data->link[link_id].status = WLAN_STATUS_SUCCESS;
- if (elems->ml_basic) {
- int bss_param_ch_cnt =
- ieee80211_mle_get_bss_param_ch_cnt((const void *)elems->ml_basic);
-
- if (bss_param_ch_cnt < 0) {
- ret = false;
- goto out;
- }
- bss_conf->bss_param_ch_cnt = bss_param_ch_cnt;
- bss_conf->bss_param_ch_cnt_link_id = link_id;
- }
- } else if (elems->parse_error & IEEE80211_PARSE_ERR_DUP_NEST_ML_BASIC ||
- !elems->prof ||
- !(elems->prof->control & prof_bss_param_ch_present)) {
+ } else if (elems->parse_error & IEEE80211_PARSE_ERR_DUP_NEST_ML_BASIC) {
+ sdata_info(sdata,
+ "association response had nested multi-link element\n");
+ ret = false;
+ goto out;
+ } else if (!elems->prof) {
+ link_info(link, "link missing from association response\n");
ret = false;
goto out;
} else {
@@ -5915,10 +5906,6 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
*/
capab_info = get_unaligned_le16(ptr);
assoc_data->link[link_id].status = get_unaligned_le16(ptr + 2);
- bss_param_ch_cnt =
- ieee80211_mle_basic_sta_prof_bss_param_ch_cnt(elems->prof);
- bss_conf->bss_param_ch_cnt = bss_param_ch_cnt;
- bss_conf->bss_param_ch_cnt_link_id = link_id;
if (assoc_data->link[link_id].status != WLAN_STATUS_SUCCESS) {
link_info(link, "association response status code=%u\n",
@@ -5926,6 +5913,32 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
ret = true;
goto out;
}
+
+ if (!(elems->prof->control &
+ cpu_to_le16(IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT))) {
+ link_info(link,
+ "per-STA profile missing BSS parameter change count\n");
+ ret = false;
+ goto out;
+ }
+ bss_param_ch_cnt =
+ ieee80211_mle_basic_sta_prof_bss_param_ch_cnt(elems->prof);
+ bss_conf->bss_param_ch_cnt = bss_param_ch_cnt;
+ bss_conf->bss_param_ch_cnt_link_id = link_id;
+ }
+
+ if (link_id == assoc_data->assoc_link_id && elems->ml_basic) {
+ int bss_param_ch_cnt =
+ ieee80211_mle_get_bss_param_ch_cnt((const void *)elems->ml_basic);
+
+ if (bss_param_ch_cnt < 0) {
+ sdata_info(sdata,
+ "No BSS parameter change count in assoc response\n");
+ ret = false;
+ goto out;
+ }
+ bss_conf->bss_param_ch_cnt = bss_param_ch_cnt;
+ bss_conf->bss_param_ch_cnt_link_id = link_id;
}
if (!is_s1g && !elems->supp_rates) {
--
2.34.1
^ permalink raw reply related
* [PATCH wireless-next] wifi: mac80211: refactor multi-link assoc response parsing
From: Miri Korenblit @ 2026-07-14 10:37 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Johannes Berg
From: Johannes Berg <johannes.berg@intel.com>
Refactor the parsing code a bit, introducing specific error
messages for the various failures and moving the BSS parameter
change count parsing out a level to be easier to extend for
UHR.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
net/mac80211/mlme.c | 53 ++++++++++++++++++++++++++++-----------------
1 file changed, 33 insertions(+), 20 deletions(-)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 9e92337bb6f9..f1172a950284 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -5871,8 +5871,6 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
const struct cfg80211_bss_ies *bss_ies = NULL;
struct ieee80211_supported_band *sband;
struct ieee802_11_elems *elems;
- const __le16 prof_bss_param_ch_present =
- cpu_to_le16(IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT);
u16 capab_info;
bool ret;
@@ -5888,20 +5886,13 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
* successful, so set the status directly to success
*/
assoc_data->link[link_id].status = WLAN_STATUS_SUCCESS;
- if (elems->ml_basic) {
- int bss_param_ch_cnt =
- ieee80211_mle_get_bss_param_ch_cnt((const void *)elems->ml_basic);
-
- if (bss_param_ch_cnt < 0) {
- ret = false;
- goto out;
- }
- bss_conf->bss_param_ch_cnt = bss_param_ch_cnt;
- bss_conf->bss_param_ch_cnt_link_id = link_id;
- }
- } else if (elems->parse_error & IEEE80211_PARSE_ERR_DUP_NEST_ML_BASIC ||
- !elems->prof ||
- !(elems->prof->control & prof_bss_param_ch_present)) {
+ } else if (elems->parse_error & IEEE80211_PARSE_ERR_DUP_NEST_ML_BASIC) {
+ sdata_info(sdata,
+ "association response had nested multi-link element\n");
+ ret = false;
+ goto out;
+ } else if (!elems->prof) {
+ link_info(link, "link missing from association response\n");
ret = false;
goto out;
} else {
@@ -5915,10 +5906,6 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
*/
capab_info = get_unaligned_le16(ptr);
assoc_data->link[link_id].status = get_unaligned_le16(ptr + 2);
- bss_param_ch_cnt =
- ieee80211_mle_basic_sta_prof_bss_param_ch_cnt(elems->prof);
- bss_conf->bss_param_ch_cnt = bss_param_ch_cnt;
- bss_conf->bss_param_ch_cnt_link_id = link_id;
if (assoc_data->link[link_id].status != WLAN_STATUS_SUCCESS) {
link_info(link, "association response status code=%u\n",
@@ -5926,6 +5913,32 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
ret = true;
goto out;
}
+
+ if (!(elems->prof->control &
+ cpu_to_le16(IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT))) {
+ link_info(link,
+ "per-STA profile missing BSS parameter change count\n");
+ ret = false;
+ goto out;
+ }
+ bss_param_ch_cnt =
+ ieee80211_mle_basic_sta_prof_bss_param_ch_cnt(elems->prof);
+ bss_conf->bss_param_ch_cnt = bss_param_ch_cnt;
+ bss_conf->bss_param_ch_cnt_link_id = link_id;
+ }
+
+ if (link_id == assoc_data->assoc_link_id && elems->ml_basic) {
+ int bss_param_ch_cnt =
+ ieee80211_mle_get_bss_param_ch_cnt((const void *)elems->ml_basic);
+
+ if (bss_param_ch_cnt < 0) {
+ sdata_info(sdata,
+ "No BSS parameter change count in assoc response\n");
+ ret = false;
+ goto out;
+ }
+ bss_conf->bss_param_ch_cnt = bss_param_ch_cnt;
+ bss_conf->bss_param_ch_cnt_link_id = link_id;
}
if (!is_s1g && !elems->supp_rates) {
--
2.34.1
^ permalink raw reply related
* [PATCH wireless-next v2 2/2] wifi: mt76: mt7996: register a LED classdev for every band
From: Petr Wozniak @ 2026-07-14 10:26 UTC (permalink / raw)
To: nbd, lorenzo, ryder.lee
Cc: shayne.chen, sean.wang, linux-wireless, matthias.bgg, rex.lu,
linux-mediatek, angelogioacchino.delregno, linux-arm-kernel,
Petr Wozniak
In-Reply-To: <20260714102615.2943-1-petr.wozniak@gmail.com>
The per-band LED callbacks (brightness_set/blink_set) were only assigned
to the primary PHY (dev->mphy) in mt7996_init_wiphy(). The 5/6 GHz bands
are brought up later through mt7996_register_phy() ->
mt7996_init_wiphy_band(), which never set those callbacks, so
mt76_led_init() bailed out early for them and only the 2.4 GHz LED was
ever registered.
The hardware path is already per band: mt7996_led_set_config() indexes
MT_LED_EN()/MT_LED_CTRL()/MT_LED_TX_BLINK() by mphy->band_idx, so per-band
hardware TX-blink works as soon as the classdev exists.
Move the callback assignment into mt7996_init_wiphy_band(), which runs for
every band, so a LED classdev is registered for each band.
Signed-off-by: Petr Wozniak <petr.wozniak@gmail.com>
---
.../net/wireless/mediatek/mt76/mt7996/init.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/init.c b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
index d6f9aa1ab..b77b85654 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
@@ -472,6 +472,18 @@ mt7996_init_wiphy_band(struct ieee80211_hw *hw, struct mt7996_phy *phy)
mt7996_set_stream_vht_txbf_caps(phy);
mt7996_set_stream_he_eht_caps(phy);
mt7996_init_txpower(phy);
+
+ /* Register a LED classdev for every band, not just the primary one.
+ * Under single-wiphy MLO the 5/6 GHz bands are brought up through
+ * mt7996_register_phy(); without these callbacks mt76_led_init() skips
+ * them and only the 2.4 GHz LED is exposed. The hardware TX-blink path
+ * is already indexed by band_idx, so per-band blink works once the
+ * classdev exists.
+ */
+ if (IS_ENABLED(CONFIG_MT76_LEDS)) {
+ phy->mt76->leds.cdev.brightness_set = mt7996_led_set_brightness;
+ phy->mt76->leds.cdev.blink_set = mt7996_led_set_blink;
+ }
}
static void
@@ -542,12 +554,6 @@ mt7996_init_wiphy(struct ieee80211_hw *hw, struct mtk_wed_device *wed)
hw->max_tx_fragments = 4;
wiphy->txq_memory_limit = 32 << 20; /* 32 MiB */
- /* init led callbacks */
- if (IS_ENABLED(CONFIG_MT76_LEDS)) {
- dev->mphy.leds.cdev.brightness_set = mt7996_led_set_brightness;
- dev->mphy.leds.cdev.blink_set = mt7996_led_set_blink;
- }
-
wiphy->max_scan_ssids = 4;
wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
--
2.51.0
^ permalink raw reply related
* [PATCH wireless-next v2 1/2] wifi: mt76: share the throughput LED trigger across bands
From: Petr Wozniak @ 2026-07-14 10:26 UTC (permalink / raw)
To: nbd, lorenzo, ryder.lee
Cc: shayne.chen, sean.wang, linux-wireless, matthias.bgg, rex.lu,
linux-mediatek, angelogioacchino.delregno, linux-arm-kernel,
Petr Wozniak
In-Reply-To: <20260714102615.2943-1-petr.wozniak@gmail.com>
ieee80211_create_tpt_led_trigger() creates one trigger per ieee80211_hw
and returns NULL with a WARN_ON() if called again for the same hw.
Under the single-wiphy MLO model each band registers its own LED classdev
for the same hw, and the bands can be initialised in any order. Create the
trigger on the first mt76_led_init() call, stash it on the primary phy's
classdev and let the other bands reuse it. This avoids the WARN_ON() splat
and gives every band the same throughput trigger regardless of init order.
Signed-off-by: Petr Wozniak <petr.wozniak@gmail.com>
---
drivers/net/wireless/mediatek/mt76/mac80211.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
index 13c4e8abe..0c6641050 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -228,11 +228,19 @@ static int mt76_led_init(struct mt76_phy *phy)
wiphy_name(hw->wiphy));
phy->leds.cdev.name = phy->leds.name;
- phy->leds.cdev.default_trigger =
- ieee80211_create_tpt_led_trigger(hw,
- IEEE80211_TPT_LEDTRIG_FL_RADIO,
- mt76_tpt_blink,
- ARRAY_SIZE(mt76_tpt_blink));
+ /* The throughput trigger is created once per ieee80211_hw. Under
+ * single-wiphy MLO every band registers its own LED classdev for the
+ * same hw and the bands can come up in any order, so create the trigger
+ * on the first call, stash it on the primary phy and let other bands
+ * reuse it; calling it again would trip a WARN_ON().
+ */
+ if (!dev->phy.leds.cdev.default_trigger)
+ dev->phy.leds.cdev.default_trigger =
+ ieee80211_create_tpt_led_trigger(hw,
+ IEEE80211_TPT_LEDTRIG_FL_RADIO,
+ mt76_tpt_blink,
+ ARRAY_SIZE(mt76_tpt_blink));
+ phy->leds.cdev.default_trigger = dev->phy.leds.cdev.default_trigger;
dev_info(dev->dev,
"registering led '%s'\n", phy->leds.name);
--
2.51.0
^ permalink raw reply related
* [PATCH wireless-next v2 0/2] wifi: mt76: fix per-band LEDs under single-wiphy MLO
From: Petr Wozniak @ 2026-07-14 10:26 UTC (permalink / raw)
To: nbd, lorenzo, ryder.lee
Cc: shayne.chen, sean.wang, linux-wireless, matthias.bgg, rex.lu,
linux-mediatek, angelogioacchino.delregno, linux-arm-kernel,
Petr Wozniak
On MT7996 (and other single-wiphy MLO mt76 devices) only the 2.4 GHz LED
was ever usable: the 5/6 GHz band LEDs stayed dark and a WARN_ON() was hit
during probe.
Two issues are involved:
1. mt76_led_init() calls ieee80211_create_tpt_led_trigger() for every band,
but that helper supports only one trigger per ieee80211_hw and
WARN_ON()s + returns NULL on the second call, so the secondary bands got
a NULL default trigger.
2. mt7996 assigned the LED brightness_set/blink_set callbacks only to the
primary PHY, so mt76_led_init() bailed out early for the 5/6 GHz bands
and never registered their LED classdevs.
Patch 1 shares the throughput trigger across all bands; patch 2 registers a
LED classdev for every band. With both applied, all three band LEDs
(mt76-phy0/1/2) come up and blink on their band's traffic.
Tested on a BPI-R4 (MT7996/BE14): all three per-band LEDs register at boot
with no WARN_ON(), and each blinks on its own band's activity (verified
with single-band and MLO clients).
Changes in v2:
- Patch 1: reflow the throughput-trigger comment and wrap the
ieee80211_create_tpt_led_trigger() arguments to stay within 80 columns
(no functional change).
- Cc the MediaTek SoC/wireless maintainers reported by get_maintainer.pl.
- No code changes since v1.
v1: https://lore.kernel.org/all/20260628095313.7790-1-petr.wozniak@gmail.com/
Petr Wozniak (2):
wifi: mt76: share the throughput LED trigger across bands
wifi: mt76: mt7996: register a LED classdev for every band
drivers/net/wireless/mediatek/mt76/mac80211.c | 18 +++++++++++++-----
.../net/wireless/mediatek/mt76/mt7996/init.c | 18 ++++++++++++------
2 files changed, 25 insertions(+), 11 deletions(-)
--
2.51.0
^ permalink raw reply
* [PATCH wireless] wifi: wilc1000: validate assoc response length before subtracting header
From: Huihui Huang @ 2026-07-14 9:17 UTC (permalink / raw)
To: linux-wireless; +Cc: Huihui Huang, Ajay Singh, Claudiu Beznea, netdev, stable
wilc_parse_assoc_resp_info() computes the trailing IE length as
ies_len = buffer_len - sizeof(*res);
without first checking that buffer_len is at least sizeof(struct
wilc_assoc_resp) (6 bytes). buffer_len is the length reported for a
received association response (host_int_parse_assoc_resp_info() passes
hif_drv->assoc_resp / assoc_resp_info_len straight in) and must be
validated before the driver accesses the fixed header.
For a frame shorter than the 6-byte fixed header, the subtraction wraps.
For a four-byte response the result is truncated to a u16 ies_len of
65534, so kmemdup() then attempts to copy 65534 bytes starting at
buffer + sizeof(*res), beyond the valid association-response data
(CWE-125). A response shorter than four bytes can also cause an
out-of-bounds read of res->status_code at offsets 2 and 3.
Reject frames too short to hold the fixed header before touching the
header or computing ies_len. Also set the connection status to a failure
on this path: the caller falls through to a
"conn_info->status == WLAN_STATUS_SUCCESS" check after the parser
returns, so leaving the status untouched could let a malformed short
response be treated as a successful association.
Fixes: c5c77ba18ea6 ("staging: wilc1000: Add SDIO/SPI 802.11 driver")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Huihui Huang <hhhuang@smu.edu.sg>
---
drivers/net/wireless/microchip/wilc1000/hif.c | 5 +++++
1 file changed, 5 insertions(+)
Confirmed on Linux v7.2-rc2 with a temporary KUnit test that calls the
static wilc_parse_assoc_resp_info() on a 4-byte association-response frame
(status_code zeroed, i.e. WLAN_STATUS_SUCCESS). Verbatim KUnit output
(timestamps stripped):
before this change:
# wilc_assoc_resp_short_frame_test: ret=0 resp_ies=ffff888008890000 resp_ies_len=65534 (want -EINVAL / NULL / 0)
after this change:
# wilc_assoc_resp_short_frame_test: ret=-22 resp_ies=0000000000000000 resp_ies_len=0 (want -EINVAL / NULL / 0)
So a 4-byte frame drives a 65534-byte kmemdup() over-read before the fix,
and is rejected with -EINVAL after it. The test also asserts the rejected
frame does not leave conn_info->status at WLAN_STATUS_SUCCESS.
diff --git a/drivers/net/wireless/microchip/wilc1000/hif.c b/drivers/net/wireless/microchip/wilc1000/hif.c
index 009c477..60fe5f0 100644
--- a/drivers/net/wireless/microchip/wilc1000/hif.c
+++ b/drivers/net/wireless/microchip/wilc1000/hif.c
@@ -600,6 +600,11 @@ static s32 wilc_parse_assoc_resp_info(u8 *buffer, u32 buffer_len,
u16 ies_len;
struct wilc_assoc_resp *res = (struct wilc_assoc_resp *)buffer;
+ if (buffer_len < sizeof(*res)) {
+ ret_conn_info->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+ return -EINVAL;
+ }
+
ret_conn_info->status = le16_to_cpu(res->status_code);
if (ret_conn_info->status == WLAN_STATUS_SUCCESS) {
ies = &buffer[sizeof(*res)];
base-commit: a0d82fb8505326cbc53dc9a0c08f97d11197bb30
--
2.50.1
^ permalink raw reply related
* [PATCH v2] wifi: ath12k: Constify struct ath12k_dp_arch_ops
From: Christophe JAILLET @ 2026-07-14 8:39 UTC (permalink / raw)
To: Jeff Johnson
Cc: linux-kernel, kernel-janitors, Christophe JAILLET, linux-wireless,
ath12k
'struct ath12k_dp_arch_ops' is not modified in this driver.
Constifying this structure moves some data to a read-only section, so
increases overall security, especially when the structure holds some
function pointers.
On a x86_64, with allmodconfig, as an example:
Before:
======
text data bss dec hex filename
6318 3384 0 9702 25e6 drivers/net/wireless/ath/ath12k/wifi7/dp.o
After:
=====
text data bss dec hex filename
6478 3224 0 9702 25e6 drivers/net/wireless/ath/ath12k/wifi7/dp.o
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
---
Compile tested only.
Changes in v2:
- Add the missing const! [Ping-Ke Shih]
v1: https://lore.kernel.org/all/469d732e2c6f159e1a05e89c7e417c3a10db5fdf.1784010931.git.christophe.jaillet@wanadoo.fr/
---
drivers/net/wireless/ath/ath12k/dp.h | 2 +-
drivers/net/wireless/ath/ath12k/wifi7/dp.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h
index 64f79e43341e..a94bbc337df4 100644
--- a/drivers/net/wireless/ath/ath12k/dp.h
+++ b/drivers/net/wireless/ath/ath12k/dp.h
@@ -538,7 +538,7 @@ struct ath12k_dp {
/* Lock for protection of peers and rhead_peer_addr */
spinlock_t dp_lock;
- struct ath12k_dp_arch_ops *ops;
+ const struct ath12k_dp_arch_ops *ops;
/* Linked list of struct ath12k_dp_link_peer */
struct list_head peers;
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c
index c72f604661ce..01a45f428990 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c
@@ -139,7 +139,7 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp,
return tot_work_done;
}
-static struct ath12k_dp_arch_ops ath12k_wifi7_dp_arch_ops = {
+static const struct ath12k_dp_arch_ops ath12k_wifi7_dp_arch_ops = {
.service_srng = ath12k_wifi7_dp_service_srng,
.tx_get_vdev_bank_config = ath12k_wifi7_dp_tx_get_vdev_bank_config,
.reo_cmd_send = ath12k_wifi7_dp_reo_cmd_send,
--
2.55.0
^ permalink raw reply related
* RE: [BUG] rtw89: 8852be intermittent 2.4GHz packet loss regression 7.0.12 -> 7.1.x
From: Ping-Ke Shih @ 2026-07-14 8:34 UTC (permalink / raw)
To: nurofen55@meta.ua, linux-wireless@vger.kernel.org
In-Reply-To: <60828.185.222.23.114.1784014990.metamail@mail.meta.ua>
nurofen55@meta.ua <nurofen55@meta.ua> wrote:
> Hi,
> I'd like to report a regression in the rtw89 driver (RTL8852BE) affecting 2.4GHz stability, introduced
> somewhere between kernel 7.0.12 and 7.1.x. This was originally filed on openSUSE bugzilla (bug 1271359),
> and Jiri Slaby suggested I forward it here for visibility with the driver maintainers:
> https://bugzilla.opensuse.org/show_bug.cgi?id\x1271359
> Summary:
>
> After updating from kernel 7.0.12 to the 7.1.x series (tested on 7.1.2 and 7.1.3) on openSUSE Tumbleweed,
> intermittent connectivity issues appear specifically on the 2.4GHz band. On kernel 7.0.12, both 2.4GHz
> and 5GHz bands were equally stable at the same physical location. On kernel 7.1.x, the 5GHz band remains
> fully stable at the same location, while the 2.4GHz band exhibits intermittent high-latency/packet-loss
> events.
> Hardware:
>
> - Laptop: Lenovo IdeaPad Slim 3 15ARP10
>
> - CPU: AMD Ryzen 7 7735HS
>
> - Wi-Fi: Realtek RTL8852BE (rtw89_8852be), PCIe
>
> - Firmware: rtw89/rtw8852b_fw-2.bin, version 0.29.29.18 (9e3d777f) - unchanged throughout all testing
Please check the kernel to see the firmware it actually loaded.
The commit 1d67f1f8e9a0 ("wifi: rtw89: 8852b: update supported firmware format to 2")
added by 7.1 is changed to support -2 firmware. That means kernel 7.0 loads
rtw89/rtw8852b_fw.bin instead.
> (ruled out as a factor)
> Steps to reproduce:
>
> 1. Boot into kernel 7.1.x (reproduced on both 7.1.2 and 7.1.3)
>
> 2. Connect to the 2.4GHz SSID at a location with moderate signal (around -70 dBm)
If you locate your laptop nearby the AP (stronger signal), will it be improved?
Please also try to turn off power save by
sudo iw wlan0 set power_save off
to see if anything changes.
>
> 3. Run continuous monitoring (mtr/ping) while using the connection normally
>
> 4. Intermittent packet loss / latency spikes occur; the same location/conditions on the 5GHz SSID show
> no such issue
> Captured evidence of one event (kernel 7.1.3), mtr output during the drop:
> HOST: localhost.localdomain Loss% Snt Last Avg Best Wrst StDev
>
> 1.|-- 192.168.0.109 20.0% 10 3018. 958.6 9.0 3018. 1234.6
>
> 192.168.0.1
> A single packet showed about 3018 ms latency with 20% loss recorded during the sample.
> Notably, no corresponding entries appear in dmesg/journalctl during this event - no deauth, no driver
> error, no firmware timeout. iw dev wlp2s0 station dump immediately after showed the link as fully healthy:
> 0 tx retries, 0 tx failed, beacon loss 0. This suggests the packet loss happens at a level not surfaced
> by driver logging (possibly interference handling, channel contention, or power-save logic specific
> to 2.4GHz), rather than a link-layer disconnect.
> Expected behavior:
>
> 2.4GHz stability matching kernel 7.0.12 behavior (equivalent to current 5GHz stability on 7.1.x).
> Actual behavior:
>
> Intermittent high-latency/packet-loss events on 2.4GHz only, with kernel 7.1.x; not reproduced on 5GHz
> under the same conditions; not reproduced on 2.4GHz under kernel 7.0.12.
> Additional info:
>
> Kernel 7.0.12 is no longer installable via zypper in the current Tumbleweed OSS repo, so I'm currently
> unable to do further direct A/B testing against 7.0.12 - this report is based on testing done while
> 7.0.12 was still available. I understand older builds may still be available via
> download.opensuse.org/history if a fresh comparison is needed.
> I'm happy to test patches, run bisection guidance, or gather any additional debug output (debugfs,
> ethtool stats, etc.) if that would help narrow this down.
The commit bda294ed0ed0 ("wifi: rtw89: Drop malformed AMPDU frames with abnormal PN")
introduced by 7.0 with a bug, so we have another commit
63ccdfac8677 ("wifi: rtw89: correct drop logic for malformed AMPDU frames")
to fix it.
Could you please apply 63ccdfac8677 to 7.1.x?
Since I have reviewed changes between 7.0 and 7.1, if these suggestions
don't work, please help to bisect the cause.
Ping-Ke
^ permalink raw reply
* Re: [PATCH] wifi: ath12k: Constify struct ath12k_dp_arch_ops
From: Christophe JAILLET @ 2026-07-14 8:20 UTC (permalink / raw)
To: Ping-Ke Shih, Jeff Johnson
Cc: linux-kernel@vger.kernel.org, kernel-janitors@vger.kernel.org,
linux-wireless@vger.kernel.org, ath12k@lists.infradead.org
In-Reply-To: <2efa694140ce418c8d83a62d3f7b5309@realtek.com>
Le 14/07/2026 à 08:57, Ping-Ke Shih a écrit :
> Christophe JAILLET <christophe.jaillet@wanadoo.fr> wrote:
>> --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c
>> +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c
>> @@ -139,7 +139,7 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp,
>> return tot_work_done;
>> }
>>
>> -static struct ath12k_dp_arch_ops ath12k_wifi7_dp_arch_ops = {
>> +static struct ath12k_dp_arch_ops ath12k_wifi7_dp_arch_ops = {
>
> Did you miss 'const' here?
>
> My bad!
I reverted the change to compute the size before/after and forgot to add
it back before posting.
Sorry, I'll send a v2.
CJ
^ permalink raw reply
* RE: [PATCH rtw-next 08/16] wifi: rtw89: add IO offload support via firmware
From: Ping-Ke Shih @ 2026-07-14 7:53 UTC (permalink / raw)
To: Bitterblue Smith, linux-wireless@vger.kernel.org
Cc: Leo.Li, Gary Chang, Eric Huang, Johnson Tsai, Bernie Huang,
Isaiah, Zong-Zhe Yang, Mh_chen
In-Reply-To: <c2c05574-2179-4b9e-b681-90387bea3561@gmail.com>
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> On 20/04/2026 06:40, Ping-Ke Shih wrote:
> > +static void rtw89_fw_cmd_ofld_udelay(struct rtw89_dev *rtwdev, u32 us)
> > +{
> > + struct rtw89_fw_cmd_ofld_arg cmd = {
> > + .src = RTW89_FW_CMD_OFLD_SRC_OTHER,
> > + .type = RTW89_FW_CMD_OFLD_DELAY,
> > + .value = us,
> > + };
> > + int ret;
> > +
> > + ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd);
> > + if (ret)
> > + udelay(us);
> > +}
> > +
> > +static void rtw89_fw_cmd_ofld_mdelay(struct rtw89_dev *rtwdev, u32 ms)
> > +{
> > + struct rtw89_fw_cmd_ofld_arg cmd = {
> > + .src = RTW89_FW_CMD_OFLD_SRC_OTHER,
> > + .type = RTW89_FW_CMD_OFLD_DELAY,
> > + .value = ms * 1000,
> > + };
> > + int ret;
> > +
> > + ret = rtw89_fw_cmd_ofld_enqueue(rtwdev, &cmd);
> > + if (ret)
> > + mdelay(ms);
> > +}
> This can fail to compile with some kernel configurations because
> RTW89_FW_CMD_OFLD_SRC_OTHER (4) doesn't fit in the mask
> RTW89_H2C_CMD_OFLD_W0_SRC (GENMASK(0, 1)):
Thanks for the report.
I sent a patch [1] with first github link. If this the link isn't good to you,
please let me know. I can change it.
[1] https://lore.kernel.org/linux-wireless/20260714074811.30124-1-pkshih@realtek.com/T/#u
^ permalink raw reply
* [PATCH rtw-next] wifi: rtw89: fw: use MAC source for IO offload delay command
From: Ping-Ke Shih @ 2026-07-14 7:48 UTC (permalink / raw)
To: linux-wireless; +Cc: leo.li, rtl8821cerfe2
From: Chia-Yuan Li <leo.li@realtek.com>
The udelay/mdelay helpers set the command source to
RTW89_FW_CMD_OFLD_SRC_OTHER (4), which does not fit the two-bit field
RTW89_H2C_CMD_OFLD_W0_SRC (GENMASK(1, 0)). The le32_encode_bits() masks
it down to 0 (RTW89_FW_CMD_OFLD_SRC_BB), and compiler throws
__field_overflow() error. Fortunately it still works because firmware
ignores the source field for a delay command.
Use RTW89_FW_CMD_OFLD_SRC_MAC as the vendor driver does, and drop the
unused RTW89_FW_CMD_OFLD_SRC_OTHER enumerator.
Reported-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
Closes: https://github.com/morrownr/rtw89/issues/111
Fixes: ae3d327515f2 ("wifi: rtw89: add IO offload support via firmware")
Signed-off-by: Chia-Yuan Li <leo.li@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/fw.c | 4 ++--
drivers/net/wireless/realtek/rtw89/fw.h | 1 -
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 0e7168605850..ab97ab6969f9 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -12080,7 +12080,7 @@ static void rtw89_fw_cmd_ofld_write_rf(struct rtw89_dev *rtwdev,
static void rtw89_fw_cmd_ofld_udelay(struct rtw89_dev *rtwdev, u32 us)
{
struct rtw89_fw_cmd_ofld_arg cmd = {
- .src = RTW89_FW_CMD_OFLD_SRC_OTHER,
+ .src = RTW89_FW_CMD_OFLD_SRC_MAC,
.type = RTW89_FW_CMD_OFLD_DELAY,
.value = us,
};
@@ -12094,7 +12094,7 @@ static void rtw89_fw_cmd_ofld_udelay(struct rtw89_dev *rtwdev, u32 us)
static void rtw89_fw_cmd_ofld_mdelay(struct rtw89_dev *rtwdev, u32 ms)
{
struct rtw89_fw_cmd_ofld_arg cmd = {
- .src = RTW89_FW_CMD_OFLD_SRC_OTHER,
+ .src = RTW89_FW_CMD_OFLD_SRC_MAC,
.type = RTW89_FW_CMD_OFLD_DELAY,
.value = ms * 1000,
};
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index af126d15a1fb..52e037010f92 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -3139,7 +3139,6 @@ enum rtw89_fw_cmd_ofld_arg_src {
RTW89_FW_CMD_OFLD_SRC_RF,
RTW89_FW_CMD_OFLD_SRC_MAC,
RTW89_FW_CMD_OFLD_SRC_RF_DDIE,
- RTW89_FW_CMD_OFLD_SRC_OTHER,
};
enum rtw89_fw_cmd_ofld_arg_type {
base-commit: 6c080026ecc17eecb103f8927c64ea73a74bb818
--
2.25.1
^ permalink raw reply related
* [BUG] rtw89: 8852be intermittent 2.4GHz packet loss regression 7.0.12 -> 7.1.x
From: nurofen55 @ 2026-07-14 7:43 UTC (permalink / raw)
To: linux-wireless; +Cc: pkshih
Hi,
I'd like to report a regression in the rtw89 driver (RTL8852BE) affecting 2.4GHz stability, introduced somewhere between kernel 7.0.12 and 7.1.x. This was originally filed on openSUSE bugzilla (bug 1271359), and Jiri Slaby suggested I forward it here for visibility with the driver maintainers:
https://bugzilla.opensuse.org/show_bug.cgi?id\x1271359
Summary:
After updating from kernel 7.0.12 to the 7.1.x series (tested on 7.1.2 and 7.1.3) on openSUSE Tumbleweed, intermittent connectivity issues appear specifically on the 2.4GHz band. On kernel 7.0.12, both 2.4GHz and 5GHz bands were equally stable at the same physical location. On kernel 7.1.x, the 5GHz band remains fully stable at the same location, while the 2.4GHz band exhibits intermittent high-latency/packet-loss events.
Hardware:
- Laptop: Lenovo IdeaPad Slim 3 15ARP10
- CPU: AMD Ryzen 7 7735HS
- Wi-Fi: Realtek RTL8852BE (rtw89_8852be), PCIe
- Firmware: rtw89/rtw8852b_fw-2.bin, version 0.29.29.18 (9e3d777f) - unchanged throughout all testing (ruled out as a factor)
Steps to reproduce:
1. Boot into kernel 7.1.x (reproduced on both 7.1.2 and 7.1.3)
2. Connect to the 2.4GHz SSID at a location with moderate signal (around -70 dBm)
3. Run continuous monitoring (mtr/ping) while using the connection normally
4. Intermittent packet loss / latency spikes occur; the same location/conditions on the 5GHz SSID show no such issue
Captured evidence of one event (kernel 7.1.3), mtr output during the drop:
HOST: localhost.localdomain Loss% Snt Last Avg Best Wrst StDev
1.|-- 192.168.0.109 20.0% 10 3018. 958.6 9.0 3018. 1234.6
192.168.0.1
A single packet showed about 3018 ms latency with 20% loss recorded during the sample.
Notably, no corresponding entries appear in dmesg/journalctl during this event - no deauth, no driver error, no firmware timeout. iw dev wlp2s0 station dump immediately after showed the link as fully healthy: 0 tx retries, 0 tx failed, beacon loss 0. This suggests the packet loss happens at a level not surfaced by driver logging (possibly interference handling, channel contention, or power-save logic specific to 2.4GHz), rather than a link-layer disconnect.
Expected behavior:
2.4GHz stability matching kernel 7.0.12 behavior (equivalent to current 5GHz stability on 7.1.x).
Actual behavior:
Intermittent high-latency/packet-loss events on 2.4GHz only, with kernel 7.1.x; not reproduced on 5GHz under the same conditions; not reproduced on 2.4GHz under kernel 7.0.12.
Additional info:
Kernel 7.0.12 is no longer installable via zypper in the current Tumbleweed OSS repo, so I'm currently unable to do further direct A/B testing against 7.0.12 - this report is based on testing done while 7.0.12 was still available. I understand older builds may still be available via download.opensuse.org/history if a fresh comparison is needed.
I'm happy to test patches, run bisection guidance, or gather any additional debug output (debugfs, ethtool stats, etc.) if that would help narrow this down.
Thanks,
Sviatoslav
^ permalink raw reply
* [PATCH] cfg80211: use size_t for mesh_setup::ie_len
From: Srinivas Achary @ 2026-07-14 7:25 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, linux-kernel, ramakrishnan, Srinivas Achary
mesh_setup::ie_len is currently declared as u8, limiting the maximum
IE length to 255 bytes. Callers may provide larger IE buffers, causing
the length to be truncated and resulting in incomplete or incorrect
processing of mesh information elements.
Use size_t for ie_len to correctly represent the buffer size and align
the field with the kernel's convention for memory lengths.
Signed-off-by: Srinivas Achary <srinivas@aerlync.com>
Co-authored-by: Ramakrishnan Rathinasamy <ramakrishnan@aerlync.com>
---
include/net/cfg80211.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 8188ad200de5..ec715d10d98f 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2803,7 +2803,7 @@ struct mesh_setup {
u8 path_metric;
u8 auth_id;
const u8 *ie;
- u8 ie_len;
+ size_t ie_len;
bool is_authenticated;
bool is_secure;
bool user_mpm;
--
2.34.1
^ permalink raw reply related
* [PATCH] wifi: cfg80211: Constify struct cfg80211_ops
From: Christophe JAILLET @ 2026-07-14 7:14 UTC (permalink / raw)
Cc: linux-kernel, kernel-janitors, Christophe JAILLET, linux-wireless
'struct cfg80211_ops' is not modified in this driver.
Constifying this structure moves some data to a read-only section, so
increases overall security, especially when the structure holds some
function pointers.
On a x86_64, with allmodconfig, as an example:
Before:
======
text data bss dec hex filename
143726 34579 192 178497 2b941 drivers/net/wireless/ath/ath6kl/cfg80211.o
After:
=====
text data bss dec hex filename
144814 33491 192 178497 2b941 drivers/net/wireless/ath/ath6kl/cfg80211.o
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
---
Compile tested only.
---
drivers/net/wireless/ath/ath6kl/cfg80211.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index cc0f2c45fc3a..ecde91159b54 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -3437,7 +3437,7 @@ ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
},
};
-static struct cfg80211_ops ath6kl_cfg80211_ops = {
+static const struct cfg80211_ops ath6kl_cfg80211_ops = {
.add_virtual_intf = ath6kl_cfg80211_add_iface,
.del_virtual_intf = ath6kl_cfg80211_del_iface,
.change_virtual_intf = ath6kl_cfg80211_change_iface,
--
2.55.0
^ permalink raw reply related
* Re: [PATCH v2 0/3] MIPS: BCM47XX: convert buttons to software nodes
From: Arnd Bergmann @ 2026-07-14 7:12 UTC (permalink / raw)
To: Dmitry Torokhov, Rafał Miłecki, Michael Büsch,
Hauke Mehrtens, Thomas Bogendoerfer, Waldemar Brodkorb
Cc: Bartosz Golaszewski, linux-wireless, linux-kernel, linux-mips,
Bartosz Golaszewski
In-Reply-To: <20260713-b4-bcm47xx-swnode-v2-0-2b879f0c193c@gmail.com>
On Mon, Jul 13, 2026, at 23:58, Dmitry Torokhov wrote:
> This series converts the legacy gpio-keys platform device on BCM47XX
> boards to use software nodes and static properties.
>
> To do this properly without relying on legacy name-based matching
> (which is being removed from gpiolib), we introduce and register
> software nodes for the underlying GPIO controllers (BCMA and SSB)
> and reference them in the button properties.
>
> The first two patches add the software nodes to bcma-gpio and
> ssb-gpio respectively. The third patch performs the conversion
> for the BCM47XX buttons.
>
> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> ---
> As Johannes mentioned on v1 this best should go through MIPS tree.
Adding Waldemar to Cc. He has recently done some work to
get this platform working again in FreeWRT and should
be able to test your patches on hardware.
Arnd
^ permalink raw reply
* RE: [PATCH] wifi: ath12k: Constify struct ath12k_dp_arch_ops
From: Ping-Ke Shih @ 2026-07-14 6:57 UTC (permalink / raw)
To: Christophe JAILLET, Jeff Johnson
Cc: linux-kernel@vger.kernel.org, kernel-janitors@vger.kernel.org,
linux-wireless@vger.kernel.org, ath12k@lists.infradead.org
In-Reply-To: <469d732e2c6f159e1a05e89c7e417c3a10db5fdf.1784010931.git.christophe.jaillet@wanadoo.fr>
Christophe JAILLET <christophe.jaillet@wanadoo.fr> wrote:
> --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c
> +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c
> @@ -139,7 +139,7 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp,
> return tot_work_done;
> }
>
> -static struct ath12k_dp_arch_ops ath12k_wifi7_dp_arch_ops = {
> +static struct ath12k_dp_arch_ops ath12k_wifi7_dp_arch_ops = {
Did you miss 'const' here?
^ permalink raw reply
* Re: [PATCH] wifi: brcmfmac: cyw: clean up PMKID and cookie code
From: Bogdan Nicolae @ 2026-07-14 6:56 UTC (permalink / raw)
To: Arend van Spriel
Cc: linux-wireless, brcm80211, brcm80211-dev-list.pdl, linux-kernel,
Bogdan Nicolae
In-Reply-To: <99c2c345-c594-46e1-b48a-de7f6e52e1c6@broadcom.com>
Hi Arend,
The code already sets *cookie=0 in the beginning, which according to
my understanding tells the driver it does not require async tracking
upstream. This is correct, because the function calls
wait_for_completion_timeout, so mgmt tx completes by the time we exit
the function and doesn't need to be tracked upstream. However, while
we are waiting for mgmt tx to finish, the firmware may generate
non-matching completion events captured by notify_mgmt_tx_status.
That's why setting a non-zero packed_id (sent to and returned by
firmware as part of a completion event) and checking against
vif->mgmt_tx_id is important.
Cheers,
Bogdan
On Sun, Jul 12, 2026 at 5:30 PM Arend van Spriel
<arend.vanspriel@broadcom.com> wrote:
>
> On 09/07/2026 14:23, Bogdan Nicolae wrote:
> > Avoid setting packet_id to cookie, which is always 0. Instead, use an
> > increasing atomic counter. Avoids mismatches of completion events later
> > in brcmf_notify_mgmt_tx_status, where packet_id != vif->mgmt_tx_id is
> > checked.
> >
> > Also, zero out auth_status on initialization. Otherwise, garbage will
> > leak from the stack to the firmware (when bssid is less than 32 bytes
> > and/or when params->pmkid is set). Then, pass the params->pmkid to the
> > firmware (without it, the firmware caches a garbage PMKID on successful
> > authentication and denies a subsequent association request that includes
> > the PMKID).
> >
> > Signed-off-by: Bogdan Nicolae <bogdan.nicolae@acm.org>
>
> I always get a bit confused when people use different email addresses to
> send and sign-off patches.
> > ---
> > .../net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c | 8 ++++++--
> > 1 file changed, 6 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c
> > index ce09d44fa..cca53ff19 100644
> > --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c
> > +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c
> > @@ -23,6 +23,8 @@
> > #define MGMT_AUTH_FRAME_DWELL_TIME 4000
> > #define MGMT_AUTH_FRAME_WAIT_TIME (MGMT_AUTH_FRAME_DWELL_TIME + 100)
> >
> > +static atomic_t brcmf_cyw_mgmt_tx_id = ATOMIC_INIT(0);
> > +
> > static int brcmf_cyw_set_sae_pwd(struct brcmf_if *ifp,
> > struct cfg80211_crypto_settings *crypto)
> > {
> > @@ -155,7 +157,7 @@ int brcmf_cyw_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
> >
> > memcpy(&mf_params->da[0], &mgmt->da[0], ETH_ALEN);
> > memcpy(&mf_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
> > - mf_params->packet_id = cpu_to_le32(*cookie);
> > + mf_params->packet_id = cpu_to_le32(atomic_inc_return(&brcmf_cyw_mgmt_tx_id));
>
> As I understand things the cookie value here is an output parameter. The
> driver should assign it:
>
> + *cookie = atomic_inc_return(&brcmf_cyw_mgmt_tx_id);
> mf_params->packet_id = cpu_to_le32(*cookie);
>
> > memcpy(mf_params->data, &buf[DOT11_MGMT_HDR_LEN],
> > le16_to_cpu(mf_params->len));
> >
> Regards,
> Arend
^ permalink raw reply
* [PATCH] wifi: ath12k: Constify struct ath12k_dp_arch_ops
From: Christophe JAILLET @ 2026-07-14 6:35 UTC (permalink / raw)
To: Jeff Johnson
Cc: linux-kernel, kernel-janitors, Christophe JAILLET, linux-wireless,
ath12k
'struct ath12k_dp_arch_ops' is not modified in this driver.
Constifying this structure moves some data to a read-only section, so
increases overall security, especially when the structure holds some
function pointers.
On a x86_64, with allmodconfig, as an example:
Before:
======
text data bss dec hex filename
6318 3384 0 9702 25e6 drivers/net/wireless/ath/ath12k/wifi7/dp.o
After:
=====
text data bss dec hex filename
6478 3224 0 9702 25e6 drivers/net/wireless/ath/ath12k/wifi7/dp.o
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
---
Compile tested only.
---
drivers/net/wireless/ath/ath12k/dp.h | 2 +-
drivers/net/wireless/ath/ath12k/wifi7/dp.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h
index 64f79e43341e..a94bbc337df4 100644
--- a/drivers/net/wireless/ath/ath12k/dp.h
+++ b/drivers/net/wireless/ath/ath12k/dp.h
@@ -538,7 +538,7 @@ struct ath12k_dp {
/* Lock for protection of peers and rhead_peer_addr */
spinlock_t dp_lock;
- struct ath12k_dp_arch_ops *ops;
+ const struct ath12k_dp_arch_ops *ops;
/* Linked list of struct ath12k_dp_link_peer */
struct list_head peers;
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c
index c72f604661ce..01a45f428990 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c
@@ -139,7 +139,7 @@ static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp,
return tot_work_done;
}
-static struct ath12k_dp_arch_ops ath12k_wifi7_dp_arch_ops = {
+static struct ath12k_dp_arch_ops ath12k_wifi7_dp_arch_ops = {
.service_srng = ath12k_wifi7_dp_service_srng,
.tx_get_vdev_bank_config = ath12k_wifi7_dp_tx_get_vdev_bank_config,
.reo_cmd_send = ath12k_wifi7_dp_reo_cmd_send,
--
2.55.0
^ permalink raw reply related
* Re: [PATCH wireless-next v2] wifi: cfg80211: fix regulatory.db async firmware request blocking __usermodehelper_disable()
From: Kavita Kavita @ 2026-07-14 6:01 UTC (permalink / raw)
To: Carlos Llamas; +Cc: johannes, linux-wireless
In-Reply-To: <akQDnwSpBb-yTuLA@google.com>
On 6/30/2026 11:27 PM, Carlos Llamas wrote:
> On Tue, Jun 30, 2026 at 04:53:45PM +0000, Carlos Llamas wrote:
>> On Mon, Jun 29, 2026 at 12:01:59PM +0530, Kavita Kavita wrote:
>>> cfg80211 schedules an asynchronous request_firmware() work item for
>>> regulatory.db via request_firmware_work_func(). When the direct
>>> firmware load fails, _request_firmware() falls back to the sysfs
>>> fallback path via firmware_fallback_sysfs(), which blocks indefinitely
>>> in wait_for_completion_killable_timeout() waiting for userspace to
>>> supply the firmware through the sysfs interface.
>>>
>>> While this work item is pending, any caller of
>>> __usermodehelper_disable() will deadlock attempting to acquire the
>>> usermodehelper rwsem for writing, since the sysfs firmware fallback
>>> path holds the rwsem for reading and is blocked waiting for userspace
>>> response that can never arrive while usermode helpers are being
>>> disabled.
>>>
>>> Observed call traces where system suspend blocked due to regulatory.db
>>> async firmware request:
>>>
>>> kworker/6:3 (pid 194) holding usermodehelper rwsem read lock, blocked
>>> waiting for userspace firmware response:
>>> wait_for_completion_killable_timeout+0x48
>>> firmware_fallback_sysfs+0x270
>>> _request_firmware+0x790
>>> request_firmware_work_func+0x44
>>> process_one_work[jt]+0x59c
>>> worker_thread+0x260
>>> kthread+0x150
>>> ret_from_fork+0x10
>>>
>>> Caller blocked in __usermodehelper_disable() during system suspend:
>>> rwsem_down_write_slowpath+0x768
>>> down_write+0x98
>>> __usermodehelper_disable+0x3c
>>> freeze_processes+0x18
>>> pm_suspend+0x320
>>> state_store+0x104
>>> kernfs_fop_write_iter[jt]+0x168
>>> vfs_write+0x270
>>> ksys_write+0x78
>>>
>>> Any service or kernel subsystem invoking __usermodehelper_disable() is
>>> susceptible to this hang as long as the regulatory.db sysfs fallback
>>> request remains outstanding.
>>>
>>> Fix this by replacing the unconditional uevent-based load with a
>>> two-step approach. First, attempt a synchronous load via
>>> request_firmware_direct() at init time. This is fast and
>>> non-blocking, if the file is present in standard paths it is loaded
>>> immediately with no delay. If not found, the load is deferred to
>>> wiphy_regulatory_register() and triggered via
>>> firmware_request_nowait_nowarn() only when the first non-self-managed
>>> wiphy registers.
>>>
>>> For self-managed drivers (REGULATORY_WIPHY_SELF_MANAGED), the hang is
>>> avoided because wiphy_regulatory_register() handles them separately
>>> and the deferred load path is never reached, so the file load is not
>>> attempted at all. For this case, regulatory information is obtained
>>> from driver/firmware during wiphy registration. For non-self-managed
>>> drivers, the file is required and is expected to be present. The
>>> deferred load via firmware_request_nowait_nowarn() is triggered only
>>> when the first such wiphy registers. This ensures the database is
>>> loaded only when it is actually needed, avoiding the sysfs fallback
>>> path on systems where the file is absent at init time.
>>>
>>> Also refactor regdb_fw_cb() into two functions: regdb_load() which
>>> validates and stores the firmware image, and regdb_fw_cb_restore()
>>> which is the async callback that calls restore_regulatory_settings()
>>> to replay all pending regulatory requests (country hints from core,
>>> user, driver and country IE) that arrived while the database was not
>>> yet available.
>>>
>>> NOTE:
>>> This issue was observed on Android platforms where regulatory.db is
>>> absent.
>>> Steps to reproduce on Android platforms:
>>> 1. Power off the device completely.
>>> 2. Connect the charger; the device enters off-mode charging.
>>> 3. While in off-mode charging, short press the power key.
>>
>> Can you confirm that you see this with !FW_LOADER_USER_HELPER_FALLBACK?
>> IIUC, this is disabled in Android and shouldn't trigger this path?
Yes, FW_LOADER_USER_HELPER_FALLBACK is disabled by default. However, on our
platforms, force_sysfs_fallback is explicitly set to 1 through a vendor init script,
which causes the udev fallback path to be used.
>
> Also, you mentioned this happend while on "off-mode charging". So maybe
> don't set force_sysfs_fallback and attempt to load cfg8011 module here?
Well, this is one workaround. However, we cannot simply disable force_sysfs_fallback.
It is required for our firmware loading use cases in both off-mode charging and
normal boot modes.
The main purpose of this patch is to avoid attempting to load regulatory.db when
it is not needed.
>
> Anyway, this is orthogonal to this patch. It seems that holding the lock
> (read) with a long timeout (60sec?) _and_ trigger a suspend right after
> will fall under this trap as you mentioned. It seems a fairly easy thing
> to reproduce on vanilla distros I would think?
Yes, the issue is easy to reproduce. However, we have not tested it on vanilla
distros.
>
> --
> Carlos Llamas
^ permalink raw reply
* Re: [PATCH ath-next 0/2] wifi: ath: Correctly copy the hint BSSID in WMI scan request
From: Baochen Qiang @ 2026-07-14 2:43 UTC (permalink / raw)
To: Jeff Johnson, Jeff Johnson; +Cc: linux-wireless, ath11k, ath12k, linux-kernel
In-Reply-To: <20260713-ath12k_wmi_send_scan_start_cmd-bad-hint_bssid-v1-0-4ffc4a472992@oss.qualcomm.com>
On 7/14/2026 12:15 AM, Jeff Johnson wrote:
> Issue was reported in ath12k, but exists in ath11k as well.
>
> ---
> Jeff Johnson (2):
> wifi: ath12k: Correctly copy the hint BSSID in WMI scan request
> wifi: ath11k: Correctly copy the hint BSSID in WMI scan request
>
> drivers/net/wireless/ath/ath11k/wmi.c | 4 ++--
> drivers/net/wireless/ath/ath12k/wmi.c | 4 ++--
> 2 files changed, 4 insertions(+), 4 deletions(-)
> ---
> base-commit: fa1b1469f1c5f0f54ed9dab80106a117e7736bfd
> change-id: 20260712-ath12k_wmi_send_scan_start_cmd-bad-hint_bssid-8786dbd8cff9
>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
^ permalink raw reply
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