Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: [PATCH rtw-next v2] wifi: rtl8xxxu: Detect the maximum supported channel width
From: Thorsten Leemhuis @ 2026-05-12  7:17 UTC (permalink / raw)
  To: Ping-Ke Shih
  Cc: Jes Sorensen, Bitterblue Smith, linux-wireless@vger.kernel.org,
	art1310@proton.me, Linux kernel regressions list
In-Reply-To: <f26992e669744e6f87084e017f897275@realtek.com>



On 5/12/26 02:44, Ping-Ke Shih wrote:
> Thorsten Leemhuis <linux@leemhuis.info> wrote:
>> On 5/6/26 09:57, Ping-Ke Shih wrote:
>>> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>>>
>>>> Some devices malfunction when connected to a network with 40 MHz channel
>>>> width, because they don't support that.
>>>>
>>>> RTL8188FU, RTL8192FU, and RTL8710BU (RTL8188GU) have a way to signal
>>>> this (and some other capabilities) to the driver. Get this information
>>>> from the hardware and advertise 40 MHz support only when the hardware
>>>> can handle it. We assume the other chips can always handle it.
>>>>
>>>> RTL8710BU needs a different way to retrieve this information, which will
>>>> be implemented some other time.
>>>>
>>>> Fixes: dbf9b7bb0edf ("wifi: rtl8xxxu: Enable 40 MHz width by default")
>>>> Cc: stable@vger.kernel.org
>>>> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221394
>>>> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
>>>> Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
>>
>> Thx for fixing this!
>>
>>> 1 patch(es) applied to rtw-next branch of rtw.git, thanks.
>>> ef771eabc79d wifi: rtl8xxxu: Detect the maximum supported channel width
>>> https://github.com/pkshih/rtw.git
>>
>> rtw-next sounds like it aims for the next merge window; and it seems the
>> fix hasn't even hit -next yet. This is slightly unfortunate, as this
>> afaics is a fix for a recent regression -- so it ideally should head
>> towards mainline by now[1], as Linus' the rule of thumb is to "generally
>> fix regressions "within a week", preferably before the next rc"[1].
>>
>> Or am I missing something? That might very well be the case, so do not
>> hesitate to tell me!
> 
> As this patch applied to public rtw tree, and people who encountered the
> problem in bugzilla can work again. To prevent breaking the public tree,
> I'd keep it as was.

I'm not sure I understand this correctly.

Do you mean something like "the fix is now in the rtw-next tree, so I
can't mainline it now, as this would break the rtw-next"? But why? You
can cherry-pick or directly apply the fix to a pending branch (or even
ask Linus to merge it directly from the list, but that is likely not
worth it here) and git will normally later notice this and fully
automatically handle everything when the fix comes in again during the
next merge window.

Or did I misinterpret what you meant?

Ciao, Thorsten


^ permalink raw reply

* [PATCH] wifi: mt76: mt7921: fix resource leak in probe error path
From: Hongling Zeng @ 2026-05-12  6:52 UTC (permalink / raw)
  To: nbd, lorenzo, ryder.lee, shayne.chen, sean.wang, matthias.bgg,
	angelogioacchino.delregno, xiong.huang, madhurkumar004
  Cc: linux-wireless, linux-kernel, zhongling0719, Hongling Zeng

When pcim_iomap_region() or devm_kmemdup() fail, the code returns
directly without cleaning up previously allocated resources:
  - mt76_device allocated by mt76_alloc_device()
  - pci irq vectors allocated by pci_alloc_irq_vectors()
Fix this by jumping to the existing error cleanup path instead of
returning directly.

Fixes: ee5bb35d2b83 ("wifi: mt76: mt7921: switch to pcim_iomap_region")
Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
---
 drivers/net/wireless/mediatek/mt76/mt7921/pci.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
index 7a790ddf43bb..4bb436465a3d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
@@ -344,8 +344,10 @@ static int mt7921_pci_probe(struct pci_dev *pdev,
 	pci_set_drvdata(pdev, mdev);
 
 	regs =  pcim_iomap_region(pdev, 0, pci_name(pdev));
-	if (IS_ERR(regs))
-		return PTR_ERR(regs);
+	if (IS_ERR(regs)) {
+		ret = PTR_ERR(regs);
+		goto err_free_dev;
+	}
 
 	dev = container_of(mdev, struct mt792x_dev, mt76);
 	dev->fw_features = features;
@@ -359,8 +361,10 @@ static int mt7921_pci_probe(struct pci_dev *pdev,
 		/* MT7902 needs a mutable copy because wm2_complete_mask differs */
 		map = devm_kmemdup(&pdev->dev, &irq_map,
 				   sizeof(irq_map), GFP_KERNEL);
-		if (!map)
-			return -ENOMEM;
+		if (!map) {
+			ret = -ENOMEM;
+			goto err_free_dev;
+		}
 
 		map->rx.wm2_complete_mask = 0;
 		dev->irq_map = map;
-- 
2.25.1


^ permalink raw reply related

* Re: [PATCH v4] wifi: ath11k: fix peer resolution on rx path when peer_id=0
From: Praneesh P @ 2026-05-12  6:29 UTC (permalink / raw)
  To: Matthew Leach, Jeff Johnson
  Cc: Baochen Qiang, Rameshkumar Sundaram, linux-wireless, ath11k,
	linux-kernel, kernel
In-Reply-To: <20260424-ath11k-null-peerid-workaround-v4-1-252b224d3cf6@collabora.com>


On 4/24/2026 3:20 PM, Matthew Leach wrote:
> It has been observed that on certain chipsets a peer can be assigned
> peer_id=0. For reception of non-aggregated MPDUs this is fine as
> ath11k_dp_rx_h_find_peer() has a fallback case where it locates the peer
> based upon the source MAC address. On an aggregated link, the mpdu_start
> header is only populated by hardware on the first sub-MSDU. This causes
> the peer resolution to be skipped for the subsequent MSDUs and the
> encryption type of these frames to be set to an incorrect value,
> resulting in these MSDUs being dropped by ieee80211.
>
> ath11k_pci 0000:03:00.0: data rx skb 000000002f4b704d len 1534 peer xx:xx:xx:xx:xx:xx 0 ucast sn 3063 he160 rate_idx 9 vht_nss 2 freq 5240 band 1 flag 0x40d1a fcs-err 0 mic-err 0 amsdu-more 0 peer_id 0 first_msdu 1 last_msdu 0
> ath11k_pci 0000:03:00.0: data rx skb 0000000038acd580 len 1534 peer (null) 0 ucast sn 3063 he160 rate_idx 9 vht_nss 2 freq 5240 band 1 flag 0x40d00 fcs-err 0 mic-err 0 amsdu-more 0 peer_id 0 first_msdu 0 last_msdu 1
>
> Remove the null peer_id checks in ath11k_dp_rx_h_find_peer() and
> ath11k_hal_rx_parse_mon_status_tlv(), allowing peers with an assigned ID
> of 0 to be resolved.
>
> Fixes: 2167fa606c0f ("ath11k: Add support for RX decapsulation offload")
> Tested-on: QCA2066 hw2.1 PCI WLAN.HSP.1.1-03926.13-QCAHSPSWPL_V2_SILICONZ_CE-2.52297.9
> Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
> Signed-off-by: Matthew Leach <matthew.leach@collabora.com>
> ---
> Changes in v4:
> - Prefix subsystem with 'wifi:'.
> - Added the 'Tested-by' and 'Fixes' trailers.
> - Link to v3: https://patch.msgid.link/20260417-ath11k-null-peerid-workaround-v3-1-d04302284486@collabora.com
>
> Changes in v3:
> - Clarified that the mpdu_start header isn't populated by the h/w for
>    all sub-MSDUs in the commit message.
> - Fix second null-peer check in ath11k_hal_rx_parse_mon_status_tlv().
> - Link to v2: https://patch.msgid.link/20260415-ath11k-null-peerid-workaround-v2-1-2abae3bbac16@collabora.com
>
> Changes in v2:
>
> - Since peer_id=0 is a valid condition on some chips, remove the guard
>    that prevented the peer lookup.
> - Link to v1: https://patch.msgid.link/20260326-ath11k-null-peerid-workaround-v1-1-0c2fd53202f8@collabora.com
>
> To: Jeff Johnson <jjohnson@kernel.org>
> Cc: linux-wireless@vger.kernel.org
> Cc: ath11k@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> ---
>   drivers/net/wireless/ath/ath11k/dp_rx.c  | 3 +--
>   drivers/net/wireless/ath/ath11k/hal_rx.c | 5 +----
>   2 files changed, 2 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
> index 49d959b2e148..ff2c78a4e5f3 100644
> --- a/drivers/net/wireless/ath/ath11k/dp_rx.c
> +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
> @@ -2215,8 +2215,7 @@ ath11k_dp_rx_h_find_peer(struct ath11k_base *ab, struct sk_buff *msdu)
>   
>   	lockdep_assert_held(&ab->base_lock);
>   
> -	if (rxcb->peer_id)
> -		peer = ath11k_peer_find_by_id(ab, rxcb->peer_id);
> +	peer = ath11k_peer_find_by_id(ab, rxcb->peer_id);
>   
>   	if (peer)
>   		return peer;
> diff --git a/drivers/net/wireless/ath/ath11k/hal_rx.c b/drivers/net/wireless/ath/ath11k/hal_rx.c
> index 753bd93f0212..51e0840bc0d1 100644
> --- a/drivers/net/wireless/ath/ath11k/hal_rx.c
> +++ b/drivers/net/wireless/ath/ath11k/hal_rx.c
> @@ -1467,11 +1467,8 @@ ath11k_hal_rx_parse_mon_status_tlv(struct ath11k_base *ab,
>   	case HAL_RX_MPDU_START: {
>   		struct hal_rx_mpdu_info *mpdu_info =
>   				(struct hal_rx_mpdu_info *)tlv_data;
> -		u16 peer_id;
>   
> -		peer_id = ath11k_hal_rx_mpduinfo_get_peerid(ab, mpdu_info);
> -		if (peer_id)
> -			ppdu_info->peer_id = peer_id;
> +		ppdu_info->peer_id = ath11k_hal_rx_mpduinfo_get_peerid(ab, mpdu_info);
>   		break;
>   	}
>   	case HAL_RXPCU_PPDU_END_INFO: {
>
> ---
> base-commit: f338e77383789c0cae23ca3d48adcc5e9e137e3c
> change-id: 20260326-ath11k-null-peerid-workaround-625a129781b1
>
> Best regards,
> --
> Matt
Reviewed-by: P Praneesh <praneesh.p@oss.qualcomm.com>

^ permalink raw reply

* [PATCH iwlwifi-next 15/15] wifi: iwlwifi: mld: stop supporting rate_n_flags version 2
From: Miri Korenblit @ 2026-05-12  5:23 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg
In-Reply-To: <20260512052307.1603442-1-miriam.rachel.korenblit@intel.com>

Now as the oldest fw we support is core 101, and it supports only
version 3, remove version 2.

Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mld/debugfs.c |  3 +--
 .../net/wireless/intel/iwlwifi/mld/mac80211.c    | 16 ----------------
 drivers/net/wireless/intel/iwlwifi/mld/mld.c     |  3 ---
 drivers/net/wireless/intel/iwlwifi/mld/mld.h     |  5 +----
 drivers/net/wireless/intel/iwlwifi/mld/rx.c      |  3 +--
 drivers/net/wireless/intel/iwlwifi/mld/tlc.c     |  4 +---
 drivers/net/wireless/intel/iwlwifi/mld/tx.c      | 10 ++++------
 7 files changed, 8 insertions(+), 36 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mld/debugfs.c
index b05b58eb1281..9ec8ddce0c38 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/debugfs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/debugfs.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 /*
- * Copyright (C) 2024-2025 Intel Corporation
+ * Copyright (C) 2024-2026 Intel Corporation
  */
 
 #include "mld.h"
@@ -1035,7 +1035,6 @@ static ssize_t _iwl_dbgfs_fixed_rate_write(struct iwl_mld *mld, char *buf,
 
 	/* input is in FW format (v2 or v3) so convert to v3 */
 	rate = iwl_v3_rate_from_v2_v3(cpu_to_le32(rate), v3);
-	rate = le32_to_cpu(iwl_v3_rate_to_v2_v3(rate, mld->fw_rates_ver_3));
 
 	ret = iwl_mld_send_tlc_dhc(mld, fw_sta_id,
 				   partial ? IWL_TLC_DEBUG_PARTIAL_FIXED_RATE :
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
index f37a365a87a4..4315b1b2b36b 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
@@ -455,22 +455,6 @@ static void iwl_mac_hw_set_misc(struct iwl_mld *mld)
 
 static int iwl_mld_hw_verify_preconditions(struct iwl_mld *mld)
 {
-	int ratecheck;
-
-	/* check for rates version 3 */
-	ratecheck =
-		(iwl_fw_lookup_cmd_ver(mld->fw, TX_CMD, 0) >= 11) +
-		(iwl_fw_lookup_notif_ver(mld->fw, DATA_PATH_GROUP,
-					 TLC_MNG_UPDATE_NOTIF, 0) >= 4) +
-		(iwl_fw_lookup_notif_ver(mld->fw, LEGACY_GROUP,
-					 REPLY_RX_MPDU_CMD, 0) >= 6) +
-		(iwl_fw_lookup_notif_ver(mld->fw, LONG_GROUP, TX_CMD, 0) >= 9);
-
-	if (ratecheck != 0 && ratecheck != 4) {
-		IWL_ERR(mld, "Firmware has inconsistent rates\n");
-		return -EINVAL;
-	}
-
 	/* 11ax is expected to be enabled for all supported devices */
 	if (WARN_ON(!mld->nvm_data->sku_cap_11ax_enable))
 		return -EINVAL;
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mld.c b/drivers/net/wireless/intel/iwlwifi/mld/mld.c
index dfd4798c103a..9a3b768fce7a 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/mld.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/mld.c
@@ -413,9 +413,6 @@ iwl_op_mode_mld_start(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg,
 
 	iwl_construct_mld(mld, trans, cfg, fw, hw, dbgfs_dir);
 
-	/* we'll verify later it matches between commands */
-	mld->fw_rates_ver_3 = iwl_fw_lookup_cmd_ver(mld->fw, TX_CMD, 0) >= 11;
-
 	iwl_mld_construct_fw_runtime(mld, trans, fw, dbgfs_dir);
 
 	iwl_mld_get_bios_tables(mld);
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mld.h b/drivers/net/wireless/intel/iwlwifi/mld/mld.h
index 69da3c346394..1a59b3e4014d 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/mld.h
+++ b/drivers/net/wireless/intel/iwlwifi/mld/mld.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
 /*
- * Copyright (C) 2024-2025 Intel Corporation
+ * Copyright (C) 2024-2026 Intel Corporation
  */
 #ifndef __iwl_mld_h__
 #define __iwl_mld_h__
@@ -189,7 +189,6 @@
  *	TX rate_n_flags for non-STA mgmt frames (toggles on every TX failure).
  * @set_tx_ant: stores the last TX antenna bitmask set by user space (if any)
  * @set_rx_ant: stores the last RX antenna bitmask set by user space (if any)
- * @fw_rates_ver_3: FW rates are in version 3
  * @low_latency: low-latency manager.
  * @tzone: thermal zone device's data
  * @cooling_dev: cooling device's related data
@@ -299,8 +298,6 @@ struct iwl_mld {
 	u8 set_tx_ant;
 	u8 set_rx_ant;
 
-	bool fw_rates_ver_3;
-
 	struct iwl_mld_low_latency low_latency;
 
 	bool ibss_manager;
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/rx.c b/drivers/net/wireless/intel/iwlwifi/mld/rx.c
index a9f08f984633..01603dc07f0a 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/rx.c
@@ -39,8 +39,7 @@ iwl_mld_fill_phy_data_from_mpdu(struct iwl_mld *mld,
 	}
 
 	phy_data->phy_info = le16_to_cpu(desc->phy_info);
-	phy_data->rate_n_flags = iwl_v3_rate_from_v2_v3(desc->v3.rate_n_flags,
-							mld->fw_rates_ver_3);
+	phy_data->rate_n_flags = le32_to_cpu(desc->v3.rate_n_flags);
 	phy_data->gp2_on_air_rise = le32_to_cpu(desc->v3.gp2_on_air_rise);
 	phy_data->energy_a = desc->v3.energy_a;
 	phy_data->energy_b = desc->v3.energy_b;
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/tlc.c b/drivers/net/wireless/intel/iwlwifi/mld/tlc.c
index 7db56eefc7df..fb68d8810e14 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/tlc.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/tlc.c
@@ -956,9 +956,7 @@ void iwl_mld_handle_tlc_notif(struct iwl_mld *mld,
 		if (WARN_ON(!mld_link_sta))
 			return;
 
-		mld_link_sta->last_rate_n_flags =
-			iwl_v3_rate_from_v2_v3(notif->rate,
-					       mld->fw_rates_ver_3);
+		mld_link_sta->last_rate_n_flags = le32_to_cpu(notif->rate);
 
 		rs_pretty_print_rate(pretty_rate, sizeof(pretty_rate),
 				     mld_link_sta->last_rate_n_flags);
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/tx.c b/drivers/net/wireless/intel/iwlwifi/mld/tx.c
index dec8ecd6b805..636d24633e57 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/tx.c
@@ -494,7 +494,7 @@ static __le32 iwl_mld_get_tx_rate_n_flags(struct iwl_mld *mld,
 		rate = iwl_mld_mac80211_rate_idx_to_fw(mld, info, -1) |
 		       iwl_mld_get_tx_ant(mld, info, sta, fc);
 
-	return iwl_v3_rate_to_v2_v3(rate, mld->fw_rates_ver_3);
+	return cpu_to_le32(rate);
 }
 
 static void
@@ -1012,14 +1012,11 @@ void iwl_mld_tx_from_txq(struct iwl_mld *mld, struct ieee80211_txq *txq)
 	rcu_read_unlock();
 }
 
-static void iwl_mld_hwrate_to_tx_rate(struct iwl_mld *mld,
-				      __le32 rate_n_flags_fw,
+static void iwl_mld_hwrate_to_tx_rate(u32 rate_n_flags,
 				      struct ieee80211_tx_info *info)
 {
 	enum nl80211_band band = info->band;
 	struct ieee80211_tx_rate *tx_rate = &info->status.rates[0];
-	u32 rate_n_flags = iwl_v3_rate_from_v2_v3(rate_n_flags_fw,
-						  mld->fw_rates_ver_3);
 	u32 sgi = rate_n_flags & RATE_MCS_SGI_MSK;
 	u32 chan_width = rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK;
 	u32 format = rate_n_flags & RATE_MCS_MOD_TYPE_MSK;
@@ -1150,7 +1147,8 @@ void iwl_mld_handle_tx_resp_notif(struct iwl_mld *mld,
 			iwl_dbg_tlv_time_point(&mld->fwrt, tp, NULL);
 		}
 
-		iwl_mld_hwrate_to_tx_rate(mld, tx_resp->initial_rate, info);
+		iwl_mld_hwrate_to_tx_rate(le32_to_cpu(tx_resp->initial_rate),
+					  info);
 
 		if (likely(!iwl_mld_time_sync_frame(mld, skb, hdr->addr1)))
 			ieee80211_tx_status_skb(mld->hw, skb);
-- 
2.34.1


^ permalink raw reply related

* [PATCH iwlwifi-next 14/15] wifi: iwlwifi: mld: stop supporting TLC_MNG_UPDATE_NTFY_API_S_VER_3
From: Miri Korenblit @ 2026-05-12  5:23 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg
In-Reply-To: <20260512052307.1603442-1-miriam.rachel.korenblit@intel.com>

The oldest core iwlmld support is 101, which has version 4. Remove
version 3

Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mld/notif.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/notif.c b/drivers/net/wireless/intel/iwlwifi/mld/notif.c
index fc6550bea155..4e9f3768c381 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/notif.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/notif.c
@@ -309,7 +309,6 @@ CMD_VERSIONS(tx_resp_notif,
 CMD_VERSIONS(compressed_ba_notif,
 	     CMD_VER_ENTRY(7, iwl_compressed_ba_notif))
 CMD_VERSIONS(tlc_notif,
-	     CMD_VER_ENTRY(3, iwl_tlc_update_notif)
 	     CMD_VER_ENTRY(4, iwl_tlc_update_notif))
 CMD_VERSIONS(mu_mimo_grp_notif,
 	     CMD_VER_ENTRY(1, iwl_mu_group_mgmt_notif))
-- 
2.34.1


^ permalink raw reply related

* [PATCH iwlwifi-next 13/15] wifi: iwlwifi: mld: stop supporting MAC_PM_POWER_TABLE version 1
From: Miri Korenblit @ 2026-05-12  5:23 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg
In-Reply-To: <20260512052307.1603442-1-miriam.rachel.korenblit@intel.com>

The oldest core that iwmld loads is now 101, which supports version 2,
so remove version 1.
This allows to remove the smps workaround.

Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 .../net/wireless/intel/iwlwifi/mld/iface.h    |  2 --
 .../net/wireless/intel/iwlwifi/mld/mac80211.c | 28 +---------------
 .../net/wireless/intel/iwlwifi/mld/power.c    | 33 ++-----------------
 3 files changed, 4 insertions(+), 59 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/iface.h b/drivers/net/wireless/intel/iwlwifi/mld/iface.h
index 147ff6787ed9..71c794204475 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/iface.h
+++ b/drivers/net/wireless/intel/iwlwifi/mld/iface.h
@@ -138,7 +138,6 @@ struct iwl_mld_emlsr {
  * @beacon_inject_active: indicates an active debugfs beacon ie injection
  * @low_latency_causes: bit flags, indicating the causes for low-latency,
  *	see @iwl_mld_low_latency_cause.
- * @ps_disabled: indicates that PS is disabled for this interface
  * @last_link_activation_time: last time a link was activated, for
  *	deferring MLO scans (to make them more reliable)
  * @mld: pointer to the mld structure.
@@ -171,7 +170,6 @@ struct iwl_mld_vif {
 		bool beacon_inject_active;
 #endif
 		u8 low_latency_causes;
-		bool ps_disabled;
 		time64_t last_link_activation_time;
 	);
 	/* And here fields that survive a fw restart */
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
index 8856f96a9760..f37a365a87a4 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
@@ -1368,28 +1368,6 @@ iwl_mld_mac80211_link_info_changed(struct ieee80211_hw *hw,
 		iwl_mld_set_tx_power(mld, link_conf, link_conf->txpower);
 }
 
-static void
-iwl_mld_smps_workaround(struct iwl_mld *mld, struct ieee80211_vif *vif, bool enable)
-{
-	struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
-	bool workaround_required =
-		iwl_fw_lookup_cmd_ver(mld->fw, MAC_PM_POWER_TABLE, 0) < 2;
-
-	if (!workaround_required)
-		return;
-
-	/* Send the device-level power commands since the
-	 * firmware checks the POWER_TABLE_CMD's POWER_SAVE_EN bit to
-	 * determine SMPS mode.
-	 */
-	if (mld_vif->ps_disabled == !enable)
-		return;
-
-	mld_vif->ps_disabled = !enable;
-
-	iwl_mld_update_device_power(mld, false);
-}
-
 static
 void iwl_mld_mac80211_vif_cfg_changed(struct ieee80211_hw *hw,
 				      struct ieee80211_vif *vif,
@@ -1427,10 +1405,8 @@ void iwl_mld_mac80211_vif_cfg_changed(struct ieee80211_hw *hw,
 		}
 	}
 
-	if (changes & BSS_CHANGED_PS) {
-		iwl_mld_smps_workaround(mld, vif, vif->cfg.ps);
+	if (changes & BSS_CHANGED_PS)
 		iwl_mld_update_mac_power(mld, vif, false);
-	}
 
 	/* TODO: task=MLO BSS_CHANGED_MLD_VALID_LINKS/CHANGED_MLD_TTLM */
 }
@@ -1837,7 +1813,6 @@ static int iwl_mld_move_sta_state_up(struct iwl_mld *mld,
 						    FW_CTXT_ACTION_MODIFY);
 			if (ret)
 				return ret;
-			iwl_mld_smps_workaround(mld, vif, vif->cfg.ps);
 		}
 
 		/* MFP is set by default before the station is authorized.
@@ -1882,7 +1857,6 @@ static int iwl_mld_move_sta_state_down(struct iwl_mld *mld,
 						  &mld_vif->mlo_scan_start_wk);
 
 			iwl_mld_reset_cca_40mhz_workaround(mld, vif);
-			iwl_mld_smps_workaround(mld, vif, true);
 		}
 
 		/* once we move into assoc state, need to update the FW to
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/power.c b/drivers/net/wireless/intel/iwlwifi/mld/power.c
index 49b0d9f8f865..fe71da8b9c89 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/power.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/power.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 /*
- * Copyright (C) 2024-2025 Intel Corporation
+ * Copyright (C) 2024-2026 Intel Corporation
  */
 #include <net/mac80211.h>
 
@@ -11,36 +11,11 @@
 #include "link.h"
 #include "constants.h"
 
-static void iwl_mld_vif_ps_iterator(void *data, u8 *mac,
-				    struct ieee80211_vif *vif)
-{
-	bool *ps_enable = (bool *)data;
-	struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
-
-	if (vif->type != NL80211_IFTYPE_STATION)
-		return;
-
-	*ps_enable &= !mld_vif->ps_disabled;
-}
-
 int iwl_mld_update_device_power(struct iwl_mld *mld, bool d3)
 {
 	struct iwl_device_power_cmd cmd = {};
-	bool enable_ps = false;
 
-	if (iwlmld_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) {
-		enable_ps = true;
-
-		/* Disable power save if any STA interface has
-		 * power save turned off
-		 */
-		ieee80211_iterate_active_interfaces_mtx(mld->hw,
-							IEEE80211_IFACE_ITER_NORMAL,
-							iwl_mld_vif_ps_iterator,
-							&enable_ps);
-	}
-
-	if (enable_ps)
+	if (iwlmld_mod_params.power_scheme != IWL_POWER_SCHEME_CAM)
 		cmd.flags |=
 			cpu_to_le16(DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK);
 
@@ -252,9 +227,7 @@ static void iwl_mld_power_build_cmd(struct iwl_mld *mld,
 		return;
 
 	cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK);
-
-	if (iwl_fw_lookup_cmd_ver(mld->fw, MAC_PM_POWER_TABLE, 0) >= 2)
-		cmd->flags |= cpu_to_le16(POWER_FLAGS_ENABLE_SMPS_MSK);
+	cmd->flags |= cpu_to_le16(POWER_FLAGS_ENABLE_SMPS_MSK);
 
 	/* firmware supports LPRX for beacons at rate 1 Mbps or 6 Mbps only */
 	if (link_conf->beacon_rate &&
-- 
2.34.1


^ permalink raw reply related

* [PATCH iwlwifi-next 12/15] wifi: iwlwifi: mld: stop supporting iwl_compressed_ba_notif version 5 and 6
From: Miri Korenblit @ 2026-05-12  5:23 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg
In-Reply-To: <20260512052307.1603442-1-miriam.rachel.korenblit@intel.com>

The oldest core that devices that load iwlmld op mode are supporting is core 101.
Core 101 has version 7 of iwl_compressed_ba_notif, so earlier versions
are no longer needed.

Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mld/notif.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/notif.c b/drivers/net/wireless/intel/iwlwifi/mld/notif.c
index 692251257116..fc6550bea155 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/notif.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/notif.c
@@ -307,8 +307,6 @@ CMD_VERSIONS(tx_resp_notif,
 	     CMD_VER_ENTRY(8, iwl_tx_resp)
 	     CMD_VER_ENTRY(9, iwl_tx_resp))
 CMD_VERSIONS(compressed_ba_notif,
-	     CMD_VER_ENTRY(5, iwl_compressed_ba_notif)
-	     CMD_VER_ENTRY(6, iwl_compressed_ba_notif)
 	     CMD_VER_ENTRY(7, iwl_compressed_ba_notif))
 CMD_VERSIONS(tlc_notif,
 	     CMD_VER_ENTRY(3, iwl_tlc_update_notif)
-- 
2.34.1


^ permalink raw reply related

* [PATCH iwlwifi-next 11/15] wifi: iwlwifi: stop supporting cores 97 to 100
From: Miri Korenblit @ 2026-05-12  5:23 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg
In-Reply-To: <20260512052307.1603442-1-miriam.rachel.korenblit@intel.com>

Remove support from cores 97 to 100, including.

Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/cfg/bz.c | 6 +++---
 drivers/net/wireless/intel/iwlwifi/cfg/dr.c | 6 +++---
 drivers/net/wireless/intel/iwlwifi/cfg/sc.c | 6 +++---
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/bz.c b/drivers/net/wireless/intel/iwlwifi/cfg/bz.c
index 8b3f15899396..c060b12cc952 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/bz.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/bz.c
@@ -12,8 +12,8 @@
 /* Highest firmware core release supported */
 #define IWL_BZ_UCODE_CORE_MAX	103
 
-/* Lowest firmware API version supported */
-#define IWL_BZ_UCODE_API_MIN	100
+/* Lowest firmware core release supported */
+#define IWL_BZ_UCODE_CORE_MIN	101
 
 /* Memory offsets and lengths */
 #define IWL_BZ_SMEM_OFFSET		0x400000
@@ -69,7 +69,7 @@ static const struct iwl_family_base_params iwl_bz_base = {
 	},
 	.features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM,
 	.ucode_api_max = ENCODE_CORE_AS_API(IWL_BZ_UCODE_CORE_MAX),
-	.ucode_api_min = IWL_BZ_UCODE_API_MIN,
+	.ucode_api_min = ENCODE_CORE_AS_API(IWL_BZ_UCODE_CORE_MIN),
 };
 
 const struct iwl_mac_cfg iwl_bz_mac_cfg = {
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/dr.c b/drivers/net/wireless/intel/iwlwifi/cfg/dr.c
index a8f2ac688d31..3ccbb21276c1 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/dr.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/dr.c
@@ -11,8 +11,8 @@
 /* Highest firmware core release supported */
 #define IWL_DR_UCODE_CORE_MAX	103
 
-/* Lowest firmware API version supported */
-#define IWL_DR_UCODE_API_MIN	100
+/* Lowest firmware core release supported */
+#define IWL_DR_UCODE_CORE_MIN	101
 
 /* Memory offsets and lengths */
 #define IWL_DR_SMEM_OFFSET		0x400000
@@ -70,7 +70,7 @@ static const struct iwl_family_base_params iwl_dr_base = {
 	},
 	.features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM,
 	.ucode_api_max = ENCODE_CORE_AS_API(IWL_DR_UCODE_CORE_MAX),
-	.ucode_api_min = IWL_DR_UCODE_API_MIN,
+	.ucode_api_min = ENCODE_CORE_AS_API(IWL_DR_UCODE_CORE_MIN),
 };
 
 const struct iwl_mac_cfg iwl_dr_mac_cfg = {
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/sc.c b/drivers/net/wireless/intel/iwlwifi/cfg/sc.c
index 4532d31d5f8b..04c726e8c283 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/sc.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/sc.c
@@ -12,8 +12,8 @@
 /* Highest firmware core release supported */
 #define IWL_SC_UCODE_CORE_MAX	103
 
-/* Lowest firmware API version supported */
-#define IWL_SC_UCODE_API_MIN	100
+/* Lowest firmware core release supported */
+#define IWL_SC_UCODE_CORE_MIN	101
 
 /* Memory offsets and lengths */
 #define IWL_SC_SMEM_OFFSET		0x400000
@@ -75,7 +75,7 @@ static const struct iwl_family_base_params iwl_sc_base = {
 	},
 	.features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM,
 	.ucode_api_max = ENCODE_CORE_AS_API(IWL_SC_UCODE_CORE_MAX),
-	.ucode_api_min = IWL_SC_UCODE_API_MIN,
+	.ucode_api_min = ENCODE_CORE_AS_API(IWL_SC_UCODE_CORE_MIN),
 };
 
 const struct iwl_mac_cfg iwl_sc_mac_cfg = {
-- 
2.34.1


^ permalink raw reply related

* [PATCH iwlwifi-next 10/15] wifi: iwlwifi: mark that we support iwl_rx_mpdu_desc version 7 and 8
From: Miri Korenblit @ 2026-05-12  5:23 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg
In-Reply-To: <20260512052307.1603442-1-miriam.rachel.korenblit@intel.com>

Mark the driver struct as matching RX_MPDU_RES_START_API_S_VER_7 and
RX_MPDU_RES_START_API_S_VER_8

Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/api/rx.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
index aa4e5e9d4d4e..699343cf0279 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
@@ -735,6 +735,8 @@ struct iwl_rx_mpdu_desc {
 	     * RX_MPDU_RES_START_API_S_VER_4,
 	     * RX_MPDU_RES_START_API_S_VER_5,
 	     * RX_MPDU_RES_START_API_S_VER_6
+	     * RX_MPDU_RES_START_API_S_VER_7
+	     * RX_MPDU_RES_START_API_S_VER_8
 	     */
 
 #define IWL_RX_DESC_SIZE_V1 offsetofend(struct iwl_rx_mpdu_desc, v1)
-- 
2.34.1


^ permalink raw reply related

* [PATCH iwlwifi-next 09/15] wifi: iwlwifi: support a TLV indicating num of mgmt mcast keys
From: Miri Korenblit @ 2026-05-12  5:23 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg
In-Reply-To: <20260512052307.1603442-1-miriam.rachel.korenblit@intel.com>

FW has a limitation of how many multicast management keys it supports.
Until today we just assumed this limitation. But now as it is changing,
due to NAN, we need a clear indication from the FW so we know how many
we can install.

Read and store this indication from the FW's TLV.

Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/api/sta.h | 3 +--
 drivers/net/wireless/intel/iwlwifi/fw/file.h    | 3 ++-
 drivers/net/wireless/intel/iwlwifi/fw/img.h     | 3 ++-
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c    | 7 +++++++
 drivers/net/wireless/intel/iwlwifi/mld/key.c    | 2 +-
 5 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h b/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h
index e6f9abdfa546..3e62a458b131 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
 /*
- * Copyright (C) 2012-2014, 2018-2021, 2023, 2025 Intel Corporation
+ * Copyright (C) 2012-2014, 2018-2021, 2023, 2025-2026 Intel Corporation
  * Copyright (C) 2013-2014 Intel Mobile Communications GmbH
  * Copyright (C) 2016-2017 Intel Deutschland GmbH
  */
@@ -191,7 +191,6 @@ enum iwl_sta_sleep_flag {
 #define STA_KEY_IDX_INVALID (0xff)
 #define STA_KEY_MAX_DATA_KEY_NUM (4)
 #define IWL_MAX_GLOBAL_KEYS (4)
-#define IWL_MAX_NUM_IGTKS 2
 #define STA_KEY_LEN_WEP40 (5)
 #define STA_KEY_LEN_WEP104 (13)
 
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h
index f7a6f21267e9..68ddd99a9f7d 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/file.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
 /*
- * Copyright (C) 2008-2014, 2018-2024 Intel Corporation
+ * Copyright (C) 2008-2014, 2018-2024, 2026 Intel Corporation
  * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
  * Copyright (C) 2016-2017 Intel Deutschland GmbH
  */
@@ -111,6 +111,7 @@ enum iwl_ucode_tlv_type {
 	IWL_UCODE_TLV_FW_NUM_STATIONS		= IWL_UCODE_TLV_CONST_BASE + 0,
 	IWL_UCODE_TLV_FW_NUM_LINKS		= IWL_UCODE_TLV_CONST_BASE + 1,
 	IWL_UCODE_TLV_FW_NUM_BEACONS		= IWL_UCODE_TLV_CONST_BASE + 2,
+	IWL_UCODE_TLV_FW_NUM_MCAST_KEY_ENTRIES	= IWL_UCODE_TLV_CONST_BASE + 3,
 
 	IWL_UCODE_TLV_TYPE_DEBUG_INFO		= IWL_UCODE_TLV_DEBUG_BASE + 0,
 	IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION	= IWL_UCODE_TLV_DEBUG_BASE + 1,
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/img.h b/drivers/net/wireless/intel/iwlwifi/fw/img.h
index 94113d1db8e1..75b1344f6cbe 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/img.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/img.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
 /*
- * Copyright (C) 2005-2014, 2018-2024 Intel Corporation
+ * Copyright (C) 2005-2014, 2018-2024, 2026 Intel Corporation
  * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
  * Copyright (C) 2016 Intel Deutschland GmbH
  */
@@ -53,6 +53,7 @@ struct iwl_ucode_capabilities {
 	u32 num_stations;
 	u32 num_links;
 	u32 num_beacons;
+	u32 num_mcast_key_entries;
 	DECLARE_BITMAP(_api, NUM_IWL_UCODE_TLV_API);
 	DECLARE_BITMAP(_capa, NUM_IWL_UCODE_TLV_CAPA);
 
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
index 83a63be90e46..488524529538 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
@@ -1331,6 +1331,12 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
 			capa->num_beacons =
 				le32_to_cpup((const __le32 *)tlv_data);
 			break;
+		case IWL_UCODE_TLV_FW_NUM_MCAST_KEY_ENTRIES:
+			if (tlv_len != sizeof(u32))
+				goto invalid_tlv_len;
+			capa->num_mcast_key_entries =
+				le32_to_cpup((const __le32 *)tlv_data);
+			break;
 		case IWL_UCODE_TLV_UMAC_DEBUG_ADDRS: {
 			const struct iwl_umac_debug_addrs *dbg_ptrs =
 				(const void *)tlv_data;
@@ -1641,6 +1647,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
 	fw->ucode_capa.n_scan_channels = IWL_DEFAULT_SCAN_CHANNELS;
 	fw->ucode_capa.num_stations = IWL_STATION_COUNT_MAX;
 	fw->ucode_capa.num_beacons = 1;
+	fw->ucode_capa.num_mcast_key_entries = 2;
 	/* dump all fw memory areas by default */
 	fw->dbg.dump_mask = 0xffffffff;
 
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/key.c b/drivers/net/wireless/intel/iwlwifi/mld/key.c
index 944d5487c110..151e35b851f7 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/key.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/key.c
@@ -259,7 +259,7 @@ int iwl_mld_add_key(struct iwl_mld *mld,
 
 	igtk_ptr = iwl_mld_get_igtk_ptr(vif, sta, key);
 	if (igtk_ptr) {
-		if (mld->num_igtks == IWL_MAX_NUM_IGTKS)
+		if (mld->num_igtks == mld->fw->ucode_capa.num_mcast_key_entries)
 			return -EOPNOTSUPP;
 
 		if (*igtk_ptr) {
-- 
2.34.1


^ permalink raw reply related

* [PATCH iwlwifi-next 08/15] wifi: iwlwifi: print FSEQ sha1 in addition to version
From: Miri Korenblit @ 2026-05-12  5:23 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg
In-Reply-To: <20260512052307.1603442-1-miriam.rachel.korenblit@intel.com>

From: Johannes Berg <johannes.berg@intel.com>

The version isn't all that useful, however the sha1 will
identify the exact source. Print that as well.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
index d5ded4d3a30b..83a63be90e46 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 /*
- * Copyright (C) 2005-2014, 2018-2025 Intel Corporation
+ * Copyright (C) 2005-2014, 2018-2026 Intel Corporation
  * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
  * Copyright (C) 2016-2017 Intel Deutschland GmbH
  */
@@ -1294,8 +1294,9 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
 
 			if (tlv_len != sizeof(*fseq_ver))
 				goto invalid_tlv_len;
-			IWL_DEBUG_INFO(drv, "TLV_FW_FSEQ_VERSION: %.32s\n",
-				       fseq_ver->version);
+			IWL_DEBUG_INFO(drv,
+				       "TLV_FW_FSEQ_VERSION: %.32s (sha1: %.20s)\n",
+				       fseq_ver->version, fseq_ver->sha1);
 			}
 			break;
 		case IWL_UCODE_TLV_FW_NUM_STATIONS:
-- 
2.34.1


^ permalink raw reply related

* [PATCH iwlwifi-next 07/15] wifi: iwlwifi: remove nvm_ver for devices that don't need it
From: Miri Korenblit @ 2026-05-12  5:22 UTC (permalink / raw)
  To: linux-wireless; +Cc: Emmanuel Grumbach, Johannes Berg
In-Reply-To: <20260512052307.1603442-1-miriam.rachel.korenblit@intel.com>

From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>

This was needed only to check the NVM for devices that had a specific
firmware image to run the initial calibrations.
Remove this field from newer devices that no longer have a specific
image for those.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>

Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/cfg/rf-fm.c | 6 +-----
 drivers/net/wireless/intel/iwlwifi/cfg/rf-gf.c | 4 ----
 drivers/net/wireless/intel/iwlwifi/cfg/rf-hr.c | 6 +-----
 drivers/net/wireless/intel/iwlwifi/cfg/rf-pe.c | 5 +----
 drivers/net/wireless/intel/iwlwifi/cfg/rf-wh.c | 6 +-----
 drivers/net/wireless/intel/iwlwifi/cfg/sc.c    | 3 ---
 6 files changed, 4 insertions(+), 26 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/rf-fm.c b/drivers/net/wireless/intel/iwlwifi/cfg/rf-fm.c
index ad2536f53084..f482536e6b5e 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/rf-fm.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/rf-fm.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 /*
  * Copyright (C) 2015-2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2025 Intel Corporation
+ * Copyright (C) 2018-2026 Intel Corporation
  */
 #include "iwl-config.h"
 
@@ -11,9 +11,6 @@
 #define IWL_GL_B_FM_B_FW_PRE		"iwlwifi-gl-b0-fm-b0"
 #define IWL_GL_C_FM_C_FW_PRE		"iwlwifi-gl-c0-fm-c0"
 
-/* NVM versions */
-#define IWL_FM_NVM_VERSION		0x0a1d
-
 #define IWL_DEVICE_FM							\
 	.ht_params = {							\
 		.stbc = true,						\
@@ -27,7 +24,6 @@
 	.uhb_supported = true,						\
 	.eht_supported = true,						\
 	.num_rbds = IWL_NUM_RBDS_EHT,					\
-	.nvm_ver = IWL_FM_NVM_VERSION,					\
 	.nvm_type = IWL_NVM_EXT
 
 const struct iwl_rf_cfg iwl_rf_fm = {
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/rf-gf.c b/drivers/net/wireless/intel/iwlwifi/cfg/rf-gf.c
index 307b557dce99..e6f7066f5c7c 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/rf-gf.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/rf-gf.c
@@ -35,9 +35,6 @@
 #define IWL_SC_A_GF4_A_MODULE_FIRMWARE(api) \
 	IWL_SC_A_GF4_A_FW_PRE "-" __stringify(api) ".ucode"
 
-/* NVM versions */
-#define IWL_GF_NVM_VERSION		0x0a1d
-
 const struct iwl_rf_cfg iwl_rf_gf = {
 	.uhb_supported = true,
 	.led_mode = IWL_LED_RF_STATE,
@@ -49,7 +46,6 @@ const struct iwl_rf_cfg iwl_rf_gf = {
 		.ht40_bands = BIT(NL80211_BAND_2GHZ) |
 			      BIT(NL80211_BAND_5GHZ),
 	},
-	.nvm_ver = IWL_GF_NVM_VERSION,
 	.nvm_type = IWL_NVM_EXT,
 	.num_rbds = IWL_NUM_RBDS_HE,
 	.ucode_api_min = IWL_GF_UCODE_API_MIN,
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/rf-hr.c b/drivers/net/wireless/intel/iwlwifi/cfg/rf-hr.c
index 6cf187d92dbf..3c3a8d5702d8 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/rf-hr.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/rf-hr.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 /*
  * Copyright (C) 2015-2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2025 Intel Corporation
+ * Copyright (C) 2018-2026 Intel Corporation
  */
 #include "iwl-config.h"
 
@@ -40,9 +40,6 @@
 #define IWL_SC_A_HR_B_FW_MODULE_FIRMWARE(api)	\
 	IWL_SC_A_HR_B_FW_PRE "-" __stringify(api) ".ucode"
 
-/* NVM versions */
-#define IWL_HR_NVM_VERSION		0x0a1d
-
 #define IWL_DEVICE_HR							\
 	.led_mode = IWL_LED_RF_STATE,					\
 	.non_shared_ant = ANT_B,					\
@@ -54,7 +51,6 @@
 			      BIT(NL80211_BAND_5GHZ),			\
 	},								\
 	.num_rbds = IWL_NUM_RBDS_HE,					\
-	.nvm_ver = IWL_HR_NVM_VERSION,					\
 	.nvm_type = IWL_NVM_EXT,					\
 	.ucode_api_min = IWL_HR_UCODE_API_MIN,				\
 	.ucode_api_max = IWL_HR_UCODE_API_MAX
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/rf-pe.c b/drivers/net/wireless/intel/iwlwifi/cfg/rf-pe.c
index c02478b73057..7a04cb120b1b 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/rf-pe.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/rf-pe.c
@@ -1,11 +1,9 @@
 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 /*
- * Copyright (C) 2025 Intel Corporation
+ * Copyright (C) 2025-2026 Intel Corporation
  */
 #include "iwl-config.h"
 
-#define IWL_PE_NVM_VERSION		0x0a1d
-
 #define IWL_DEVICE_PE							\
 	.ht_params = {							\
 		.stbc = true,						\
@@ -20,7 +18,6 @@
 	.eht_supported = true,						\
 	.uhr_supported = true,						\
 	.num_rbds = IWL_NUM_RBDS_EHT,					\
-	.nvm_ver = IWL_PE_NVM_VERSION,					\
 	.nvm_type = IWL_NVM_EXT
 
 const struct iwl_rf_cfg iwl_rf_pe = {
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/rf-wh.c b/drivers/net/wireless/intel/iwlwifi/cfg/rf-wh.c
index b5803ea1eb78..fa63a9a01264 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/rf-wh.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/rf-wh.c
@@ -1,12 +1,9 @@
 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 /*
- * Copyright (C) 2025 Intel Corporation
+ * Copyright (C) 2025-2026 Intel Corporation
  */
 #include "iwl-config.h"
 
-/* NVM versions */
-#define IWL_WH_NVM_VERSION		0x0a1d
-
 #define IWL_DEVICE_WH							\
 	.ht_params = {							\
 		.stbc = true,						\
@@ -19,7 +16,6 @@
 	.vht_mu_mimo_supported = true,					\
 	.uhb_supported = true,						\
 	.num_rbds = IWL_NUM_RBDS_EHT,					\
-	.nvm_ver = IWL_WH_NVM_VERSION,					\
 	.nvm_type = IWL_NVM_EXT
 
 /* currently iwl_rf_wh/iwl_rf_wh_160mhz are just defines for the FM ones */
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/sc.c b/drivers/net/wireless/intel/iwlwifi/cfg/sc.c
index 8e6efde3c64b..4532d31d5f8b 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/sc.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/sc.c
@@ -15,9 +15,6 @@
 /* Lowest firmware API version supported */
 #define IWL_SC_UCODE_API_MIN	100
 
-/* NVM versions */
-#define IWL_SC_NVM_VERSION		0x0a1d
-
 /* Memory offsets and lengths */
 #define IWL_SC_SMEM_OFFSET		0x400000
 #define IWL_SC_SMEM_LEN			0xD0000
-- 
2.34.1


^ permalink raw reply related

* [PATCH iwlwifi-next 06/15] wifi: iwlwifi: advertise UHR capabilities for such devices
From: Miri Korenblit @ 2026-05-12  5:22 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg
In-Reply-To: <20260512052307.1603442-1-miriam.rachel.korenblit@intel.com>

From: Johannes Berg <johannes.berg@intel.com>

Advertise UHR capabilities for devices supporting UHR
(i.e. devices with some, but not all, PE RFs.)

For correct support it's also needed to plumb through
the regulatory flags the firmware might have/enforce.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 .../net/wireless/intel/iwlwifi/cfg/rf-pe.c    | 23 +++++-
 .../net/wireless/intel/iwlwifi/iwl-config.h   |  7 +-
 .../wireless/intel/iwlwifi/iwl-nvm-parse.c    | 77 ++++++++++++-------
 .../wireless/intel/iwlwifi/iwl-nvm-parse.h    |  2 +
 .../wireless/intel/iwlwifi/iwl-nvm-utils.h    |  1 +
 drivers/net/wireless/intel/iwlwifi/pcie/drv.c |  2 +-
 6 files changed, 80 insertions(+), 32 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/rf-pe.c b/drivers/net/wireless/intel/iwlwifi/cfg/rf-pe.c
index 2c29054ce7b8..c02478b73057 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/rf-pe.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/rf-pe.c
@@ -4,7 +4,28 @@
  */
 #include "iwl-config.h"
 
-/* currently iwl_rf_wh/iwl_rf_wh_160mhz are just defines for the FM ones */
+#define IWL_PE_NVM_VERSION		0x0a1d
+
+#define IWL_DEVICE_PE							\
+	.ht_params = {							\
+		.stbc = true,						\
+		.ldpc = true,						\
+		.ht40_bands = BIT(NL80211_BAND_2GHZ) |			\
+			      BIT(NL80211_BAND_5GHZ),			\
+	},								\
+	.led_mode = IWL_LED_RF_STATE,					\
+	.non_shared_ant = ANT_B,					\
+	.vht_mu_mimo_supported = true,					\
+	.uhb_supported = true,						\
+	.eht_supported = true,						\
+	.uhr_supported = true,						\
+	.num_rbds = IWL_NUM_RBDS_EHT,					\
+	.nvm_ver = IWL_PE_NVM_VERSION,					\
+	.nvm_type = IWL_NVM_EXT
+
+const struct iwl_rf_cfg iwl_rf_pe = {
+	IWL_DEVICE_PE,
+};
 
 const char iwl_killer_bn1850w2_name[] =
 	"Killer(R) Wi-Fi 8 BN1850w2 320MHz Wireless Network Adapter (BN201.D2W)";
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
index b9480a08bc86..c27ec543c872 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
@@ -416,6 +416,7 @@ struct iwl_mac_cfg {
  * @nvm_type: see &enum iwl_nvm_type
  * @uhb_supported: ultra high band channels supported
  * @eht_supported: EHT supported
+ * @uhr_supported: UHR supported
  * @num_rbds: number of receive buffer descriptors to use
  *	(only used for multi-queue capable devices)
  *
@@ -449,7 +450,8 @@ struct iwl_rf_cfg {
 	    lp_xtal_workaround:1,
 	    vht_mu_mimo_supported:1,
 	    uhb_supported:1,
-	    eht_supported:1;
+	    eht_supported:1,
+	    uhr_supported:1;
 	u8 valid_tx_ant;
 	u8 valid_rx_ant;
 	u8 non_shared_ant;
@@ -746,7 +748,8 @@ extern const struct iwl_rf_cfg iwl_rf_fm_160mhz;
 #define iwl_rf_wh iwl_rf_fm
 #define iwl_rf_wh_160mhz iwl_rf_fm_160mhz
 extern const struct iwl_rf_cfg iwl_rf_wh_non_eht;
-#define iwl_rf_pe iwl_rf_fm
+extern const struct iwl_rf_cfg iwl_rf_pe;
+#define iwl_rf_pe_no_uhr iwl_rf_fm
 #endif /* CONFIG_IWLMLD */
 
 #endif /* __IWL_CONFIG_H__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
index 455d6e8c7028..38ff6f944add 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
@@ -205,28 +205,30 @@ enum iwl_reg_capa_flags_v2 {
 }; /* GEO_CHANNEL_CAPABILITIES_API_S_VER_2 */
 
 /**
- * enum iwl_reg_capa_flags_v4 - global flags applied for the whole regulatory
+ * enum iwl_reg_capa_flags_v5 - global flags applied for the whole regulatory
  * domain.
- * @REG_CAPA_V4_160MHZ_ALLOWED: 11ac channel with a width of 160Mhz is allowed
+ * @REG_CAPA_V5_160MHZ_ALLOWED: 11ac channel with a width of 160Mhz is allowed
  *	for this regulatory domain (valid only in 5Ghz).
- * @REG_CAPA_V4_80MHZ_ALLOWED: 11ac channel with a width of 80Mhz is allowed
+ * @REG_CAPA_V5_80MHZ_ALLOWED: 11ac channel with a width of 80Mhz is allowed
  *	for this regulatory domain (valid only in 5Ghz).
- * @REG_CAPA_V4_MCS_12_ALLOWED: 11ac with MCS 12 is allowed.
- * @REG_CAPA_V4_MCS_13_ALLOWED: 11ac with MCS 13 is allowed.
- * @REG_CAPA_V4_11BE_DISABLED: 11be is forbidden for this regulatory domain.
- * @REG_CAPA_V4_11AX_DISABLED: 11ax is forbidden for this regulatory domain.
- * @REG_CAPA_V4_320MHZ_ALLOWED: 11be channel with a width of 320Mhz is allowed
+ * @REG_CAPA_V5_MCS_12_ALLOWED: 11ac with MCS 12 is allowed.
+ * @REG_CAPA_V5_MCS_13_ALLOWED: 11ac with MCS 13 is allowed.
+ * @REG_CAPA_V5_11BE_DISABLED: 11be is forbidden for this regulatory domain.
+ * @REG_CAPA_V5_11AX_DISABLED: 11ax is forbidden for this regulatory domain.
+ * @REG_CAPA_V5_320MHZ_ALLOWED: 11be channel with a width of 320Mhz is allowed
  *	for this regulatory domain (valid only in 5GHz).
+ * @REG_CAPA_V5_11BN_DISABLED: UHR is not allowed for this regulatory domain
  */
-enum iwl_reg_capa_flags_v4 {
-	REG_CAPA_V4_160MHZ_ALLOWED		= BIT(3),
-	REG_CAPA_V4_80MHZ_ALLOWED		= BIT(4),
-	REG_CAPA_V4_MCS_12_ALLOWED		= BIT(5),
-	REG_CAPA_V4_MCS_13_ALLOWED		= BIT(6),
-	REG_CAPA_V4_11BE_DISABLED		= BIT(8),
-	REG_CAPA_V4_11AX_DISABLED		= BIT(13),
-	REG_CAPA_V4_320MHZ_ALLOWED		= BIT(16),
-}; /* GEO_CHANNEL_CAPABILITIES_API_S_VER_4 */
+enum iwl_reg_capa_flags_v5 {
+	REG_CAPA_V5_160MHZ_ALLOWED		= BIT(3),
+	REG_CAPA_V5_80MHZ_ALLOWED		= BIT(4),
+	REG_CAPA_V5_MCS_12_ALLOWED		= BIT(5),
+	REG_CAPA_V5_MCS_13_ALLOWED		= BIT(6),
+	REG_CAPA_V5_11BE_DISABLED		= BIT(8),
+	REG_CAPA_V5_11AX_DISABLED		= BIT(13),
+	REG_CAPA_V5_320MHZ_ALLOWED		= BIT(16),
+	REG_CAPA_V5_11BN_DISABLED		= BIT(17),
+}; /* GEO_CHANNEL_CAPABILITIES_API_S_VER_4, 5 */
 
 /*
 * API v2 for reg_capa_flags is relevant from version 6 and onwards of the
@@ -545,7 +547,7 @@ static const u8 iwl_vendor_caps[] = {
 	0x00
 };
 
-static const struct ieee80211_sband_iftype_data iwl_he_eht_capa[] = {
+static const struct ieee80211_sband_iftype_data iwl_iftype_cap[] = {
 	{
 		.types_mask = BIT(NL80211_IFTYPE_STATION) |
 			      BIT(NL80211_IFTYPE_P2P_CLIENT),
@@ -689,6 +691,11 @@ static const struct ieee80211_sband_iftype_data iwl_he_eht_capa[] = {
 			 */
 			.eht_ppe_thres = {0xc1, 0x0e, 0xe0 }
 		},
+		.uhr_cap = {
+			.has_uhr = true,
+			.phy.cap = IEEE80211_UHR_PHY_CAP_ELR_RX |
+				   IEEE80211_UHR_PHY_CAP_ELR_TX,
+		},
 	},
 	{
 		.types_mask = BIT(NL80211_IFTYPE_AP) |
@@ -787,6 +794,11 @@ static const struct ieee80211_sband_iftype_data iwl_he_eht_capa[] = {
 			 */
 			.eht_ppe_thres = {0xc1, 0x0e, 0xe0 }
 		},
+		.uhr_cap = {
+			.has_uhr = true,
+			.phy.cap = IEEE80211_UHR_PHY_CAP_ELR_RX |
+				   IEEE80211_UHR_PHY_CAP_ELR_TX,
+		},
 	},
 };
 
@@ -854,6 +866,9 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans,
 	    fips_enabled)
 		iftype_data->eht_cap.has_eht = false;
 
+	if (!data->sku_cap_11bn_enable || !iftype_data->eht_cap.has_eht)
+		iftype_data->uhr_cap.has_uhr = false;
+
 	/* Advertise an A-MPDU exponent extension based on
 	 * operating band
 	 */
@@ -1022,9 +1037,9 @@ static void iwl_init_he_hw_capab(struct iwl_trans *trans,
 	struct ieee80211_sband_iftype_data *iftype_data;
 	int i;
 
-	BUILD_BUG_ON(sizeof(data->iftd.low) != sizeof(iwl_he_eht_capa));
-	BUILD_BUG_ON(sizeof(data->iftd.high) != sizeof(iwl_he_eht_capa));
-	BUILD_BUG_ON(sizeof(data->iftd.uhb) != sizeof(iwl_he_eht_capa));
+	BUILD_BUG_ON(sizeof(data->iftd.low) != sizeof(iwl_iftype_cap));
+	BUILD_BUG_ON(sizeof(data->iftd.high) != sizeof(iwl_iftype_cap));
+	BUILD_BUG_ON(sizeof(data->iftd.uhb) != sizeof(iwl_iftype_cap));
 
 	switch (sband->band) {
 	case NL80211_BAND_2GHZ:
@@ -1041,10 +1056,10 @@ static void iwl_init_he_hw_capab(struct iwl_trans *trans,
 		return;
 	}
 
-	memcpy(iftype_data, iwl_he_eht_capa, sizeof(iwl_he_eht_capa));
+	memcpy(iftype_data, iwl_iftype_cap, sizeof(iwl_iftype_cap));
 
 	_ieee80211_set_sband_iftype_data(sband, iftype_data,
-					 ARRAY_SIZE(iwl_he_eht_capa));
+					 ARRAY_SIZE(iwl_iftype_cap));
 
 	for (i = 0; i < sband->n_iftype_data; i++)
 		iwl_nvm_fixup_sband_iftd(trans, data, sband, &iftype_data[i],
@@ -1652,6 +1667,9 @@ u32 iwl_nvm_get_regdom_bw_flags(const u16 *nvm_chan,
 	if (reg_capa.disable_11be)
 		flags |= NL80211_RRF_NO_EHT;
 
+	if (reg_capa.disable_11bn)
+		flags |= NL80211_RRF_NO_UHR;
+
 	return flags;
 }
 EXPORT_SYMBOL_IF_IWLWIFI_KUNIT(iwl_nvm_get_regdom_bw_flags);
@@ -1662,11 +1680,13 @@ static struct iwl_reg_capa iwl_get_reg_capa(u32 flags, u8 resp_ver)
 
 	if (resp_ver >= REG_CAPA_V4_RESP_VER) {
 		reg_capa.allow_40mhz = true;
-		reg_capa.allow_80mhz = flags & REG_CAPA_V4_80MHZ_ALLOWED;
-		reg_capa.allow_160mhz = flags & REG_CAPA_V4_160MHZ_ALLOWED;
-		reg_capa.allow_320mhz = flags & REG_CAPA_V4_320MHZ_ALLOWED;
-		reg_capa.disable_11ax = flags & REG_CAPA_V4_11AX_DISABLED;
-		reg_capa.disable_11be = flags & REG_CAPA_V4_11BE_DISABLED;
+		reg_capa.allow_80mhz = flags & REG_CAPA_V5_80MHZ_ALLOWED;
+		reg_capa.allow_160mhz = flags & REG_CAPA_V5_160MHZ_ALLOWED;
+		reg_capa.allow_320mhz = flags & REG_CAPA_V5_320MHZ_ALLOWED;
+		reg_capa.disable_11ax = flags & REG_CAPA_V5_11AX_DISABLED;
+		reg_capa.disable_11be = flags & REG_CAPA_V5_11BE_DISABLED;
+		/* can check: was reserved and irrelevant for pre-UHR devices */
+		reg_capa.disable_11bn = flags & REG_CAPA_V5_11BN_DISABLED;
 	} else if (resp_ver >= REG_CAPA_V2_RESP_VER) {
 		reg_capa.allow_40mhz = flags & REG_CAPA_V2_40MHZ_ALLOWED;
 		reg_capa.allow_80mhz = flags & REG_CAPA_V2_80MHZ_ALLOWED;
@@ -2121,6 +2141,7 @@ struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans,
 		!!(mac_flags & NVM_MAC_SKU_FLAGS_MIMO_DISABLED);
 	if (trans->cfg->eht_supported)
 		nvm->sku_cap_11be_enable = true;
+	nvm->sku_cap_11bn_enable = trans->cfg->uhr_supported;
 
 	/* Initialize PHY sku data */
 	nvm->valid_tx_ant = (u8)le32_to_cpu(rsp->phy_sku.tx_chains);
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h
index 12f28bb0e859..e676d7c2d6cc 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h
@@ -35,6 +35,7 @@ enum iwl_nvm_sbands_flags {
  *	for this regulatory domain (valid only in 6 Ghz).
  * @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
  */
 struct iwl_reg_capa {
 	bool allow_40mhz;
@@ -43,6 +44,7 @@ struct iwl_reg_capa {
 	bool allow_320mhz;
 	bool disable_11ax;
 	bool disable_11be;
+	bool disable_11bn;
 };
 
 /**
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-utils.h b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-utils.h
index e0c31f328a6c..52d35b73ed74 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-utils.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-utils.h
@@ -32,6 +32,7 @@ struct iwl_nvm_data {
 	bool sku_cap_ipan_enable;
 	bool sku_cap_mimo_disabled;
 	bool sku_cap_11be_enable;
+	bool sku_cap_11bn_enable;
 
 	u16 radio_cfg_type;
 	u8 radio_cfg_step;
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index 6ff773d22ce0..e0be899b8fca 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -1070,7 +1070,7 @@ VISIBLE_IF_IWLWIFI_KUNIT const struct iwl_dev_info iwl_dev_info_table[] = {
 
 /* PE RF */
 	IWL_DEV_INFO(iwl_rf_pe, iwl_bn201_name, RF_TYPE(PE)),
-	IWL_DEV_INFO(iwl_rf_pe, iwl_be223_name, RF_TYPE(PE),
+	IWL_DEV_INFO(iwl_rf_pe_no_uhr, iwl_be223_name, RF_TYPE(PE),
 		     SUBDEV_MASKED(0x0524, 0xFFF)),
 	IWL_DEV_INFO(iwl_rf_pe, iwl_bn203_name, RF_TYPE(PE),
 		     SUBDEV_MASKED(0x0324, 0xFFF)),
-- 
2.34.1


^ permalink raw reply related

* [PATCH iwlwifi-next 05/15] wifi: iwlwifi: add support for AX231
From: Miri Korenblit @ 2026-05-12  5:22 UTC (permalink / raw)
  To: linux-wireless; +Cc: Emmanuel Grumbach, Johannes Berg
In-Reply-To: <20260512052307.1603442-1-miriam.rachel.korenblit@intel.com>

From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>

AX231 is a device that is based on AX211 that doesn't support 6E and
its bandwidth is limited to 80 MHz.
Just re-use the radio config from AX203 which has the exact same
characteristics.
It has a specific subdevice ID to allow the driver to differentiate
between AX211 and AX231.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/cfg/rf-gf.c  | 3 ++-
 drivers/net/wireless/intel/iwlwifi/iwl-config.h | 4 +++-
 drivers/net/wireless/intel/iwlwifi/pcie/drv.c   | 3 ++-
 3 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/rf-gf.c b/drivers/net/wireless/intel/iwlwifi/cfg/rf-gf.c
index c16cda087a7c..307b557dce99 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/rf-gf.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/rf-gf.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 /*
  * Copyright (C) 2015-2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2025 Intel Corporation
+ * Copyright (C) 2018-2026 Intel Corporation
  */
 #include "iwl-config.h"
 
@@ -71,6 +71,7 @@ const char iwl_ax411_killer_1690i_name[] =
 
 const char iwl_ax210_name[] = "Intel(R) Wi-Fi 6E AX210 160MHz";
 const char iwl_ax211_name[] = "Intel(R) Wi-Fi 6E AX211 160MHz";
+const char iwl_ax231_name[] = "Intel(R) Wi-Fi 6 AX231";
 const char iwl_ax411_name[] = "Intel(R) Wi-Fi 6E AX411 160MHz";
 
 IWL_FW_AND_PNVM(IWL_SO_A_GF_A_FW_PRE, IWL_GF_UCODE_API_MAX);
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
index 5f40cd15e27f..b9480a08bc86 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
@@ -2,7 +2,7 @@
 /*
  * Copyright (C) 2005-2014, 2018-2021 Intel Corporation
  * Copyright (C) 2016-2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2025 Intel Corporation
+ * Copyright (C) 2018-2026 Intel Corporation
  */
 #ifndef __IWL_CONFIG_H__
 #define __IWL_CONFIG_H__
@@ -667,6 +667,7 @@ extern const char iwl_ax411_killer_1690s_name[];
 extern const char iwl_ax411_killer_1690i_name[];
 extern const char iwl_ax210_name[];
 extern const char iwl_ax211_name[];
+extern const char iwl_ax231_name[];
 extern const char iwl_ax411_name[];
 extern const char iwl_killer_be1750s_name[];
 extern const char iwl_killer_be1750i_name[];
@@ -736,6 +737,7 @@ extern const struct iwl_rf_cfg iwl_rf_hr;
 extern const struct iwl_rf_cfg iwl_rf_hr_80mhz;
 
 extern const struct iwl_rf_cfg iwl_rf_gf;
+#define iwl_rf_ot iwl_rf_hr_80mhz
 #endif /* CONFIG_IWLMVM */
 
 #if IS_ENABLED(CONFIG_IWLMLD)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index dc99e7ac4726..6ff773d22ce0 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 /*
- * Copyright (C) 2005-2014, 2018-2025 Intel Corporation
+ * Copyright (C) 2005-2014, 2018-2026 Intel Corporation
  * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
  * Copyright (C) 2016-2017 Intel Deutschland GmbH
  */
@@ -1014,6 +1014,7 @@ VISIBLE_IF_IWLWIFI_KUNIT const struct iwl_dev_info iwl_dev_info_table[] = {
 
 /* GF RF */
 	IWL_DEV_INFO(iwl_rf_gf, iwl_ax211_name, RF_TYPE(GF)),
+	IWL_DEV_INFO(iwl_rf_ot, iwl_ax231_name, RF_TYPE(GF), SUBDEV(0x0294)),
 	IWL_DEV_INFO(iwl_rf_gf, iwl_ax411_name, RF_TYPE(GF), CDB),
 	IWL_DEV_INFO(iwl_rf_gf, iwl_ax210_name, DEVICE(0x2725)),
 
-- 
2.34.1


^ permalink raw reply related

* [PATCH iwlwifi-next 04/15] wifi: iwlwifi: mld: support the new statistics APIs
From: Miri Korenblit @ 2026-05-12  5:22 UTC (permalink / raw)
  To: linux-wireless; +Cc: Emmanuel Grumbach
In-Reply-To: <20260512052307.1603442-1-miriam.rachel.korenblit@intel.com>

From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>

This new API adds information about Coexistence.
It changes the layout of the notification, adapt the code accordingly.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 .../net/wireless/intel/iwlwifi/mld/notif.c    |  3 +-
 .../net/wireless/intel/iwlwifi/mld/stats.c    | 59 +++++++++++++++----
 2 files changed, 48 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/notif.c b/drivers/net/wireless/intel/iwlwifi/mld/notif.c
index f7aeff61d785..692251257116 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/notif.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/notif.c
@@ -330,7 +330,8 @@ CMD_VERSIONS(probe_resp_data_notif,
 CMD_VERSIONS(datapath_monitor_notif,
 	     CMD_VER_ENTRY(1, iwl_datapath_monitor_notif))
 CMD_VERSIONS(stats_oper_notif,
-	     CMD_VER_ENTRY(3, iwl_system_statistics_notif_oper_v3))
+	     CMD_VER_ENTRY(3, iwl_system_statistics_notif_oper_v3)
+	     CMD_VER_ENTRY(4, iwl_system_statistics_notif_oper))
 CMD_VERSIONS(stats_oper_part1_notif,
 	     CMD_VER_ENTRY(4, iwl_system_statistics_part1_notif_oper))
 CMD_VERSIONS(bt_coex_notif,
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/stats.c b/drivers/net/wireless/intel/iwlwifi/mld/stats.c
index 714d66324e9f..0daf16766d24 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/stats.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/stats.c
@@ -40,13 +40,21 @@ iwl_mld_fill_stats_from_oper_notif(struct iwl_mld *mld,
 				   struct iwl_rx_packet *pkt,
 				   u8 fw_sta_id, struct station_info *sinfo)
 {
-	const struct iwl_system_statistics_notif_oper_v3 *notif =
-		(void *)&pkt->data;
-	const struct iwl_stats_ntfy_per_sta *per_sta =
-		&notif->per_sta[fw_sta_id];
+	const struct iwl_stats_ntfy_per_sta *per_sta;
 	struct ieee80211_link_sta *link_sta;
 	struct iwl_mld_link_sta *mld_link_sta;
 
+	if (iwl_fw_lookup_notif_ver(mld->fw, STATISTICS_GROUP,
+				    STATISTICS_OPER_NOTIF, 3) >= 4) {
+		const struct iwl_system_statistics_notif_oper *notif =
+			(void *)&pkt->data;
+		per_sta = &notif->per_sta[fw_sta_id];
+	} else {
+		const struct iwl_system_statistics_notif_oper_v3 *notif =
+			(void *)&pkt->data;
+		per_sta = &notif->per_sta[fw_sta_id];
+	}
+
 	/* 0 isn't a valid value, but FW might send 0.
 	 * In that case, set the latest non-zero value we stored
 	 */
@@ -483,7 +491,7 @@ static void iwl_mld_fill_chanctx_stats(struct ieee80211_hw *hw,
 				       void *data)
 {
 	struct iwl_mld_phy *phy = iwl_mld_phy_from_mac80211(ctx);
-	const struct iwl_stats_ntfy_per_phy_v1 *per_phy = data;
+	const struct iwl_stats_ntfy_per_phy *per_phy = data;
 	u32 new_load, old_load;
 
 	if (WARN_ON(phy->fw_id >= IWL_STATS_MAX_PHY_OPERATIONAL))
@@ -512,7 +520,7 @@ static void iwl_mld_fill_chanctx_stats(struct ieee80211_hw *hw,
 
 static void
 iwl_mld_process_per_phy_stats(struct iwl_mld *mld,
-			      const struct iwl_stats_ntfy_per_phy_v1 *per_phy)
+			      const struct iwl_stats_ntfy_per_phy *per_phy)
 {
 	ieee80211_iter_chan_contexts_mtx(mld->hw,
 					 iwl_mld_fill_chanctx_stats,
@@ -523,17 +531,42 @@ iwl_mld_process_per_phy_stats(struct iwl_mld *mld,
 void iwl_mld_handle_stats_oper_notif(struct iwl_mld *mld,
 				     struct iwl_rx_packet *pkt)
 {
-	const struct iwl_system_statistics_notif_oper_v3 *stats =
+	struct iwl_system_statistics_notif_oper *_notif __free(kfree) = NULL;
+	const struct iwl_system_statistics_notif_oper *notif =
 		(void *)&pkt->data;
-	u32 curr_ts_usec = le32_to_cpu(stats->time_stamp);
 
-	BUILD_BUG_ON(ARRAY_SIZE(stats->per_sta) != IWL_STATION_COUNT_MAX);
-	BUILD_BUG_ON(ARRAY_SIZE(stats->per_link) <
+	BUILD_BUG_ON(ARRAY_SIZE(notif->per_sta) != IWL_STATION_COUNT_MAX);
+	BUILD_BUG_ON(ARRAY_SIZE(notif->per_link) <
 		     ARRAY_SIZE(mld->fw_id_to_bss_conf));
 
-	iwl_mld_process_per_link_stats(mld, stats->per_link, curr_ts_usec);
-	iwl_mld_process_per_sta_stats(mld, stats->per_sta);
-	iwl_mld_process_per_phy_stats(mld, stats->per_phy);
+	if (iwl_fw_lookup_notif_ver(mld->fw, STATISTICS_GROUP,
+				    STATISTICS_OPER_NOTIF, 3) == 3) {
+		const struct iwl_system_statistics_notif_oper_v3 *stats =
+			(void *)&pkt->data;
+		_notif = kzalloc(sizeof(*_notif), GFP_KERNEL);
+
+		if (!_notif)
+			return;
+
+		_notif->time_stamp = stats->time_stamp;
+		for (int i = 0; i < ARRAY_SIZE(_notif->per_link); i++)
+			_notif->per_link[i] = stats->per_link[i];
+
+		BUILD_BUG_ON(sizeof(_notif->per_phy[0]) <
+			     sizeof(stats->per_phy[0]));
+		for (int i = 0; i < ARRAY_SIZE(_notif->per_phy); i++)
+			memcpy(&_notif->per_phy[i], &stats->per_phy[i],
+			       sizeof(stats->per_phy[i]));
+		for (int i = 0; i < ARRAY_SIZE(_notif->per_sta); i++)
+			_notif->per_sta[i] = stats->per_sta[i];
+
+		notif = _notif;
+	}
+
+	iwl_mld_process_per_link_stats(mld, notif->per_link,
+				       le32_to_cpu(notif->time_stamp));
+	iwl_mld_process_per_sta_stats(mld, notif->per_sta);
+	iwl_mld_process_per_phy_stats(mld, notif->per_phy);
 }
 
 void iwl_mld_handle_stats_oper_part1_notif(struct iwl_mld *mld,
-- 
2.34.1


^ permalink raw reply related

* [PATCH iwlwifi-next 03/15] wifi: iwlwifi: introduce iwl_system_statistics_notif_oper version 4
From: Miri Korenblit @ 2026-05-12  5:22 UTC (permalink / raw)
  To: linux-wireless; +Cc: Emmanuel Grumbach
In-Reply-To: <20260512052307.1603442-1-miriam.rachel.korenblit@intel.com>

From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>

This new version includes Coex related statistics

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 .../net/wireless/intel/iwlwifi/fw/api/stats.h | 76 +++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/stats.h b/drivers/net/wireless/intel/iwlwifi/fw/api/stats.h
index 8d734512f4d5..8d16782a129c 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/stats.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/stats.h
@@ -585,6 +585,67 @@ struct iwl_stats_ntfy_per_phy_v1 {
 	__le32 last_tx_ch_width_indx;
 } __packed; /* STATISTICS_NTFY_PER_PHY_API_S_VER_1 */
 
+/**
+ * struct iwl_stats_ntfy_coex - coex statistics
+ *
+ * @wifi_kill_cnt: count of wifi frames killed by BT
+ * @wifi_tx_cts_kill_cnt: count of wifi Tx CTS frames killed by BT
+ * @ttc2_ppdu_error_count: Count PPDU errors on TTC2 - BT Tx indication rises
+ *	within wifi Tx packet on non-shared antenna and wifi is NOT killed by
+ *	PTA/TCL.
+ * @trc2_ppdu_error_count: count PPDU errors on TRC2 - BT Rx indication rises
+ *	within wifi Tx packet on non-shared antenna and wifi is  NOT killed by
+ *	PTA/TCL
+ * @rrc1_collision_count: count RRC1 - BT Rx indication rises within wifi Rx
+ *	packet on shared antenna
+ * @rrc2_collision_count: count RRC2 - BT Rx indication rises within wifi Rx
+ *	packet on non-shared antenna
+ * @rtc2_collision_count: count RTC2 - BT Tx indication rises within wifi Rx
+ *	packet on non-shared antenna
+ * @reserved: reserved
+ */
+struct iwl_stats_ntfy_coex {
+	__le16 wifi_kill_cnt;
+	__le16 wifi_tx_cts_kill_cnt;
+	__le16 ttc2_ppdu_error_count;
+	__le16 trc2_ppdu_error_count;
+	__le16 rrc1_collision_count;
+	__le16 rrc2_collision_count;
+	__le16 rtc2_collision_count;
+	__le16 reserved;
+} __packed; /* STATISTICS_FW_NTFY_COEX_TELEMETRY_API_S_VER_1 */
+
+/**
+ * struct iwl_stats_ntfy_per_phy - per PHY statistics
+ * @channel_load: channel load
+ * @channel_load_by_us: device contribution to MCLM
+ * @channel_load_not_by_us: other devices' contribution to MCLM
+ * @clt: CLT HW timer (TIM_CH_LOAD2)
+ * @act: active accumulator SW
+ * @elp: elapsed time accumulator SW
+ * @rx_detected_per_ch_width: number of deferred TX per channel width,
+ *	0 - 20, 1/2/3 - 40/80/160
+ * @success_per_ch_width: number of frames that got ACK/BACK/CTS
+ *	per channel BW. note, BACK counted as 1
+ * @fail_per_ch_width: number of frames that didn't get ACK/BACK/CTS
+ *	per channel BW. note BACK counted as 1
+ * @last_tx_ch_width_indx: last txed frame channel width index
+ * @coex: coex related data
+ */
+struct iwl_stats_ntfy_per_phy {
+	__le32 channel_load;
+	__le32 channel_load_by_us;
+	__le32 channel_load_not_by_us;
+	__le32 clt;
+	__le32 act;
+	__le32 elp;
+	__le32 rx_detected_per_ch_width[IWL_STATS_MAX_BW_INDEX];
+	__le32 success_per_ch_width[IWL_STATS_MAX_BW_INDEX];
+	__le32 fail_per_ch_width[IWL_STATS_MAX_BW_INDEX];
+	__le32 last_tx_ch_width_indx;
+	struct iwl_stats_ntfy_coex coex;
+} __packed; /* STATISTICS_NTFY_PER_PHY_API_S_VER_2 */
+
 /* unknown channel load (due to not being active on channel) */
 #define IWL_STATS_UNKNOWN_CHANNEL_LOAD	0xffffffff
 
@@ -614,6 +675,21 @@ struct iwl_system_statistics_notif_oper_v3 {
 	struct iwl_stats_ntfy_per_sta per_sta[IWL_STATION_COUNT_MAX];
 } __packed; /* STATISTICS_FW_NTFY_OPERATIONAL_API_S_VER_3 */
 
+/**
+ * struct iwl_system_statistics_notif_oper - statistics notification
+ *
+ * @time_stamp: time when the notification is sent from firmware
+ * @per_link: per link statistics, &struct iwl_stats_ntfy_per_link
+ * @per_phy: per phy statistics, &struct iwl_stats_ntfy_per_phy_v1
+ * @per_sta: per sta statistics, &struct iwl_stats_ntfy_per_sta
+ */
+struct iwl_system_statistics_notif_oper {
+	__le32 time_stamp;
+	struct iwl_stats_ntfy_per_link per_link[IWL_FW_MAX_LINKS];
+	struct iwl_stats_ntfy_per_phy per_phy[IWL_STATS_MAX_PHY_OPERATIONAL];
+	struct iwl_stats_ntfy_per_sta per_sta[IWL_STATION_COUNT_MAX];
+} __packed; /* STATISTICS_FW_NTFY_OPERATIONAL_API_S_VER_4 */
+
 /**
  * struct iwl_system_statistics_part1_notif_oper - part1 stats notification
  *
-- 
2.34.1


^ permalink raw reply related

* [PATCH iwlwifi-next 02/15] wifi: iwlwifi: rename iwl_system_statistics_notif_oper
From: Miri Korenblit @ 2026-05-12  5:22 UTC (permalink / raw)
  To: linux-wireless; +Cc: Emmanuel Grumbach
In-Reply-To: <20260512052307.1603442-1-miriam.rachel.korenblit@intel.com>

From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>

rename iwl_system_statistics_notif_oper to
iwl_system_statistics_notif_oper_v3 since v4 is on the way.
Same for iwl_stats_ntfy_per_phy, since v2 is on the way.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 .../wireless/intel/iwlwifi/fw/api/commands.h   |  4 ++--
 .../net/wireless/intel/iwlwifi/fw/api/stats.h  | 18 +++++++++---------
 drivers/net/wireless/intel/iwlwifi/mld/notif.c |  4 ++--
 drivers/net/wireless/intel/iwlwifi/mld/stats.c | 10 +++++-----
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c   |  4 ++--
 drivers/net/wireless/intel/iwlwifi/mvm/rx.c    |  9 +++++----
 6 files changed, 25 insertions(+), 24 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
index 36159a769916..dcac0ba8cccf 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
@@ -2,7 +2,7 @@
 /*
  * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
  * Copyright (C) 2016-2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2022, 2024-2025 Intel Corporation
+ * Copyright (C) 2018-2022, 2024-2026 Intel Corporation
  */
 #ifndef __iwl_fw_api_commands_h__
 #define __iwl_fw_api_commands_h__
@@ -653,7 +653,7 @@ enum iwl_system_subcmd_ids {
 enum iwl_statistics_subcmd_ids {
 	/**
 	 * @STATISTICS_OPER_NOTIF: Notification about operational
-	 *	statistics &struct iwl_system_statistics_notif_oper
+	 *	statistics &struct iwl_system_statistics_notif_oper_v3
 	 */
 	STATISTICS_OPER_NOTIF = 0x0,
 
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/stats.h b/drivers/net/wireless/intel/iwlwifi/fw/api/stats.h
index 68983f6a0026..8d734512f4d5 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/stats.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/stats.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
 /*
- * Copyright (C) 2012-2014, 2018, 2020-2021, 2023-2025 Intel Corporation
+ * Copyright (C) 2012-2014, 2018, 2020-2021, 2023-2026 Intel Corporation
  * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
  * Copyright (C) 2016-2017 Intel Deutschland GmbH
  */
@@ -557,7 +557,7 @@ struct iwl_stats_ntfy_per_mac {
 
 #define IWL_STATS_MAX_BW_INDEX 5
 /**
- * struct iwl_stats_ntfy_per_phy - per PHY statistics
+ * struct iwl_stats_ntfy_per_phy_v1 - per PHY statistics
  * @channel_load: channel load
  * @channel_load_by_us: device contribution to MCLM
  * @channel_load_not_by_us: other devices' contribution to MCLM
@@ -572,7 +572,7 @@ struct iwl_stats_ntfy_per_mac {
  *	per channel BW. note BACK counted as 1
  * @last_tx_ch_width_indx: last txed frame channel width index
  */
-struct iwl_stats_ntfy_per_phy {
+struct iwl_stats_ntfy_per_phy_v1 {
 	__le32 channel_load;
 	__le32 channel_load_by_us;
 	__le32 channel_load_not_by_us;
@@ -600,17 +600,17 @@ struct iwl_stats_ntfy_per_sta {
 #define IWL_STATS_MAX_PHY_OPERATIONAL 3
 
 /**
- * struct iwl_system_statistics_notif_oper - statistics notification
+ * struct iwl_system_statistics_notif_oper_v3 - statistics notification
  *
  * @time_stamp: time when the notification is sent from firmware
  * @per_link: per link statistics, &struct iwl_stats_ntfy_per_link
- * @per_phy: per phy statistics, &struct iwl_stats_ntfy_per_phy
+ * @per_phy: per phy statistics, &struct iwl_stats_ntfy_per_phy_v1
  * @per_sta: per sta statistics, &struct iwl_stats_ntfy_per_sta
  */
-struct iwl_system_statistics_notif_oper {
+struct iwl_system_statistics_notif_oper_v3 {
 	__le32 time_stamp;
 	struct iwl_stats_ntfy_per_link per_link[IWL_FW_MAX_LINKS];
-	struct iwl_stats_ntfy_per_phy per_phy[IWL_STATS_MAX_PHY_OPERATIONAL];
+	struct iwl_stats_ntfy_per_phy_v1 per_phy[IWL_STATS_MAX_PHY_OPERATIONAL];
 	struct iwl_stats_ntfy_per_sta per_sta[IWL_STATION_COUNT_MAX];
 } __packed; /* STATISTICS_FW_NTFY_OPERATIONAL_API_S_VER_3 */
 
@@ -642,7 +642,7 @@ struct iwl_system_statistics_end_notif {
  * @hdr: general statistics header
  * @flags: bitmap of possible notification structures
  * @per_mac: per mac statistics, &struct iwl_stats_ntfy_per_mac
- * @per_phy: per phy statistics, &struct iwl_stats_ntfy_per_phy
+ * @per_phy: per phy statistics, &struct iwl_stats_ntfy_per_phy_v1
  * @per_sta: per sta statistics, &struct iwl_stats_ntfy_per_sta
  * @rx_time: rx time
  * @tx_time: usec the radio is transmitting.
@@ -653,7 +653,7 @@ struct iwl_statistics_operational_ntfy {
 	struct iwl_statistics_ntfy_hdr hdr;
 	__le32 flags;
 	struct iwl_stats_ntfy_per_mac per_mac[MAC_INDEX_AUX];
-	struct iwl_stats_ntfy_per_phy per_phy[IWL_STATS_MAX_PHY_OPERATIONAL];
+	struct iwl_stats_ntfy_per_phy_v1 per_phy[IWL_STATS_MAX_PHY_OPERATIONAL];
 	struct iwl_stats_ntfy_per_sta per_sta[IWL_STATION_COUNT_MAX];
 	__le64 rx_time;
 	__le64 tx_time;
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/notif.c b/drivers/net/wireless/intel/iwlwifi/mld/notif.c
index 9c88a8579a75..f7aeff61d785 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/notif.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/notif.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 /*
- * Copyright (C) 2024-2025 Intel Corporation
+ * Copyright (C) 2024-2026 Intel Corporation
  */
 
 #include "mld.h"
@@ -330,7 +330,7 @@ CMD_VERSIONS(probe_resp_data_notif,
 CMD_VERSIONS(datapath_monitor_notif,
 	     CMD_VER_ENTRY(1, iwl_datapath_monitor_notif))
 CMD_VERSIONS(stats_oper_notif,
-	     CMD_VER_ENTRY(3, iwl_system_statistics_notif_oper))
+	     CMD_VER_ENTRY(3, iwl_system_statistics_notif_oper_v3))
 CMD_VERSIONS(stats_oper_part1_notif,
 	     CMD_VER_ENTRY(4, iwl_system_statistics_part1_notif_oper))
 CMD_VERSIONS(bt_coex_notif,
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/stats.c b/drivers/net/wireless/intel/iwlwifi/mld/stats.c
index 54eb0ead78ee..714d66324e9f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/stats.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/stats.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 /*
- * Copyright (C) 2024-2025 Intel Corporation
+ * Copyright (C) 2024-2026 Intel Corporation
  */
 
 #include "mld.h"
@@ -40,7 +40,7 @@ iwl_mld_fill_stats_from_oper_notif(struct iwl_mld *mld,
 				   struct iwl_rx_packet *pkt,
 				   u8 fw_sta_id, struct station_info *sinfo)
 {
-	const struct iwl_system_statistics_notif_oper *notif =
+	const struct iwl_system_statistics_notif_oper_v3 *notif =
 		(void *)&pkt->data;
 	const struct iwl_stats_ntfy_per_sta *per_sta =
 		&notif->per_sta[fw_sta_id];
@@ -483,7 +483,7 @@ static void iwl_mld_fill_chanctx_stats(struct ieee80211_hw *hw,
 				       void *data)
 {
 	struct iwl_mld_phy *phy = iwl_mld_phy_from_mac80211(ctx);
-	const struct iwl_stats_ntfy_per_phy *per_phy = data;
+	const struct iwl_stats_ntfy_per_phy_v1 *per_phy = data;
 	u32 new_load, old_load;
 
 	if (WARN_ON(phy->fw_id >= IWL_STATS_MAX_PHY_OPERATIONAL))
@@ -512,7 +512,7 @@ static void iwl_mld_fill_chanctx_stats(struct ieee80211_hw *hw,
 
 static void
 iwl_mld_process_per_phy_stats(struct iwl_mld *mld,
-			      const struct iwl_stats_ntfy_per_phy *per_phy)
+			      const struct iwl_stats_ntfy_per_phy_v1 *per_phy)
 {
 	ieee80211_iter_chan_contexts_mtx(mld->hw,
 					 iwl_mld_fill_chanctx_stats,
@@ -523,7 +523,7 @@ iwl_mld_process_per_phy_stats(struct iwl_mld *mld,
 void iwl_mld_handle_stats_oper_notif(struct iwl_mld *mld,
 				     struct iwl_rx_packet *pkt)
 {
-	const struct iwl_system_statistics_notif_oper *stats =
+	const struct iwl_system_statistics_notif_oper_v3 *stats =
 		(void *)&pkt->data;
 	u32 curr_ts_usec = le32_to_cpu(stats->time_stamp);
 
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index ae177477b201..726477336bb4 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.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
  */
@@ -335,7 +335,7 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
 	RX_HANDLER_GRP(STATISTICS_GROUP, STATISTICS_OPER_NOTIF,
 		       iwl_mvm_handle_rx_system_oper_stats,
 		       RX_HANDLER_ASYNC_LOCKED_WIPHY,
-		       struct iwl_system_statistics_notif_oper),
+		       struct iwl_system_statistics_notif_oper_v3),
 	RX_HANDLER_GRP(STATISTICS_GROUP, STATISTICS_OPER_PART1_NOTIF,
 		       iwl_mvm_handle_rx_system_oper_part1_stats,
 		       RX_HANDLER_ASYNC_LOCKED,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
index d0c0faae0122..269c4b45de80 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.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
  */
@@ -757,8 +757,9 @@ iwl_mvm_update_tcm_from_stats(struct iwl_mvm *mvm, __le32 *air_time_le,
 	spin_unlock(&mvm->tcm.lock);
 }
 
-static void iwl_mvm_handle_per_phy_stats(struct iwl_mvm *mvm,
-					 struct iwl_stats_ntfy_per_phy *per_phy)
+static void
+iwl_mvm_handle_per_phy_stats(struct iwl_mvm *mvm,
+			     struct iwl_stats_ntfy_per_phy_v1 *per_phy)
 {
 	int i;
 
@@ -937,7 +938,7 @@ void iwl_mvm_handle_rx_system_oper_stats(struct iwl_mvm *mvm,
 {
 	u8 average_energy[IWL_STATION_COUNT_MAX];
 	struct iwl_rx_packet *pkt = rxb_addr(rxb);
-	struct iwl_system_statistics_notif_oper *stats;
+	struct iwl_system_statistics_notif_oper_v3 *stats;
 	int i;
 	u32 notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, STATISTICS_GROUP,
 						STATISTICS_OPER_NOTIF, 0);
-- 
2.34.1


^ permalink raw reply related

* [PATCH iwlwifi-next 01/15] wifi: iwlwifi: pcie: fix ACPI DSM check
From: Miri Korenblit @ 2026-05-12  5:22 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg, Jeremy Compostella
In-Reply-To: <20260512052307.1603442-1-miriam.rachel.korenblit@intel.com>

From: Johannes Berg <johannes.berg@intel.com>

The acpi_check_dsm() function expects a bitmap of function
IDs to check for, not a single value. Evidently, on many
platforms function 1 exists so checking for 2 succeeded,
but it's wrong, we need to check correctly for function 2.
Fix that.

Fixes: 9673c35486d4 ("wifi: iwlwifi: implement product reset for TOP errors")
Reported-by: Jeremy Compostella <jeremy.compostella@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/trans.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/trans.c
index 377b2e30b540..9f4c99dca195 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/trans.c
@@ -2044,7 +2044,7 @@ iwl_trans_pcie_call_prod_reset_dsm(struct pci_dev *pdev, u16 cmd, u16 value)
 						 0xDD, 0x26, 0xB5, 0xFD);
 
 	if (!acpi_check_dsm(ACPI_HANDLE(&pdev->dev), &dsm_guid, ACPI_DSM_REV,
-			    DSM_INTERNAL_FUNC_PRODUCT_RESET))
+			    BIT(DSM_INTERNAL_FUNC_PRODUCT_RESET)))
 		return ERR_PTR(-ENODEV);
 
 	return iwl_acpi_get_dsm_object(&pdev->dev, ACPI_DSM_REV,
-- 
2.34.1


^ permalink raw reply related

* [PATCH iwlwifi-next 00/15] wifi: iwlwifi: updates - 2026-05-12
From: Miri Korenblit @ 2026-05-12  5:22 UTC (permalink / raw)
  To: linux-wireless

Hi,

Features, cleanups and fixes from our internal tree.

Thanks,
Miri

Emmanuel Grumbach (5):
  wifi: iwlwifi: rename iwl_system_statistics_notif_oper
  wifi: iwlwifi: introduce iwl_system_statistics_notif_oper version 4
  wifi: iwlwifi: mld: support the new statistics APIs
  wifi: iwlwifi: add support for AX231
  wifi: iwlwifi: remove nvm_ver for devices that don't need it

Johannes Berg (3):
  wifi: iwlwifi: pcie: fix ACPI DSM check
  wifi: iwlwifi: advertise UHR capabilities for such devices
  wifi: iwlwifi: print FSEQ sha1 in addition to version

Miri Korenblit (7):
  wifi: iwlwifi: support a TLV indicating num of mgmt mcast keys
  wifi: iwlwifi: mark that we support iwl_rx_mpdu_desc version 7 and 8
  wifi: iwlwifi: stop supporting cores 97 to 100
  wifi: iwlwifi: mld: stop supporting iwl_compressed_ba_notif version 5
    and 6
  wifi: iwlwifi: mld: stop supporting MAC_PM_POWER_TABLE version 1
  wifi: iwlwifi: mld: stop supporting TLC_MNG_UPDATE_NTFY_API_S_VER_3
  wifi: iwlwifi: mld: stop supporting rate_n_flags version 2

 drivers/net/wireless/intel/iwlwifi/cfg/bz.c   |  6 +-
 drivers/net/wireless/intel/iwlwifi/cfg/dr.c   |  6 +-
 .../net/wireless/intel/iwlwifi/cfg/rf-fm.c    |  6 +-
 .../net/wireless/intel/iwlwifi/cfg/rf-gf.c    |  7 +-
 .../net/wireless/intel/iwlwifi/cfg/rf-hr.c    |  6 +-
 .../net/wireless/intel/iwlwifi/cfg/rf-pe.c    | 22 ++++-
 .../net/wireless/intel/iwlwifi/cfg/rf-wh.c    |  6 +-
 drivers/net/wireless/intel/iwlwifi/cfg/sc.c   |  9 +-
 .../wireless/intel/iwlwifi/fw/api/commands.h  |  4 +-
 .../net/wireless/intel/iwlwifi/fw/api/rx.h    |  2 +
 .../net/wireless/intel/iwlwifi/fw/api/sta.h   |  3 +-
 .../net/wireless/intel/iwlwifi/fw/api/stats.h | 88 +++++++++++++++++--
 drivers/net/wireless/intel/iwlwifi/fw/file.h  |  3 +-
 drivers/net/wireless/intel/iwlwifi/fw/img.h   |  3 +-
 .../net/wireless/intel/iwlwifi/iwl-config.h   | 11 ++-
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c  | 14 ++-
 .../wireless/intel/iwlwifi/iwl-nvm-parse.c    | 77 ++++++++++------
 .../wireless/intel/iwlwifi/iwl-nvm-parse.h    |  2 +
 .../wireless/intel/iwlwifi/iwl-nvm-utils.h    |  1 +
 .../net/wireless/intel/iwlwifi/mld/debugfs.c  |  3 +-
 .../net/wireless/intel/iwlwifi/mld/iface.h    |  2 -
 drivers/net/wireless/intel/iwlwifi/mld/key.c  |  2 +-
 .../net/wireless/intel/iwlwifi/mld/mac80211.c | 44 +---------
 drivers/net/wireless/intel/iwlwifi/mld/mld.c  |  3 -
 drivers/net/wireless/intel/iwlwifi/mld/mld.h  |  5 +-
 .../net/wireless/intel/iwlwifi/mld/notif.c    |  8 +-
 .../net/wireless/intel/iwlwifi/mld/power.c    | 33 +------
 drivers/net/wireless/intel/iwlwifi/mld/rx.c   |  3 +-
 .../net/wireless/intel/iwlwifi/mld/stats.c    | 57 +++++++++---
 drivers/net/wireless/intel/iwlwifi/mld/tlc.c  |  4 +-
 drivers/net/wireless/intel/iwlwifi/mld/tx.c   | 10 +--
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c  |  4 +-
 drivers/net/wireless/intel/iwlwifi/mvm/rx.c   |  9 +-
 drivers/net/wireless/intel/iwlwifi/pcie/drv.c |  5 +-
 .../intel/iwlwifi/pcie/gen1_2/trans.c         |  2 +-
 35 files changed, 268 insertions(+), 202 deletions(-)

-- 
2.34.1


^ permalink raw reply

* Re: [PATCH ath-next v2] wifi: ath10k: skip WMI and beacon transmission when device is wedged
From: Baochen Qiang @ 2026-05-12  5:05 UTC (permalink / raw)
  To: Kang Yang, ath10k; +Cc: linux-wireless
In-Reply-To: <20260428061737.37-1-kang.yang@oss.qualcomm.com>



On 4/28/2026 2:17 PM, Kang Yang wrote:
> In ath10k_wmi_cmd_send(), the current code detects ATH10K_STATE_WEDGED
> and sets ret to -ESHUTDOWN, but still proceeds to transmit pending
> beacons and calls ath10k_wmi_cmd_send_nowait().
> 
> This can lead to incorrect behavior, as WMI commands and beacons are
> still sent after the device has been marked as wedged, and the original
> -ESHUTDOWN return value may be overwritten by the result of the send
> path.
> 
> The wedged state indicates the hardware is already unreliable, and no
> further interaction with firmware is expected or meaningful in this
> state.
> 
> Fix this by skipping beacon transmission and the WMI send path entirely
> once ATH10K_STATE_WEDGED is detected, ensuring consistent return values
> and avoiding unnecessary firmware interaction.
> 
> Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00288-QCARMSWPZ-1
> Tested-on: QCA6174 hw3.2 SDIO WLAN.RMH.4.4.1-00189
> 
> Fixes: c256a94d1b1b ("wifi: ath10k: shutdown driver when hardware is unreliable")
> Signed-off-by: Kang Yang <kang.yang@oss.qualcomm.com>

Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>


^ permalink raw reply

* [PATCH ath-next 2/2] wifi: ath12k: fix NULL deref in change_sta_links for unready link
From: Wei Zhang @ 2026-05-12  4:49 UTC (permalink / raw)
  To: jeff.johnson; +Cc: ath12k, linux-wireless, linux-kernel, wei.zhang
In-Reply-To: <20260512044906.1735821-1-wei.zhang@oss.qualcomm.com>

_ieee80211_set_active_links() calls _ieee80211_link_use_channel() for
each newly-added link and WARN_ON_ONCE()s if it fails. The call uses
assign_on_failure=true, which allows mac80211 to continue despite
driver failures, but when a mac80211-level channel validation fails
(e.g., combinations check, DFS, or no available radio),
drv_assign_vif_chanctx() is never reached. Since ath12k_mac_vdev_create()
is only called from that path, arvif->is_created remains false and
arvif->ar remains NULL for the failed link.

The subsequent drv_change_sta_links() call reaches
ath12k_mac_op_change_sta_links(), which allocates an arsta and sets
ahsta->links_map |= BIT(link_id) for the broken link before checking
whether the link is ready. When the vdev was never created, only
station_add() is skipped, but the link remains in links_map.

Any subsequent operation iterating links_map and dereferencing arvif->ar
without a NULL check will crash. Two observed examples are NULL deref in
ath12k_mac_ml_station_remove() on disconnect and in ath12k_mac_op_set_key()
when wpa_supplicant installs PTK keys.

  BUG: Unable to handle kernel NULL pointer dereference at 0x00000000
  pc : ath12k_mac_station_post_remove+0x40/0xe8 [ath12k]
  Call trace:
   ath12k_mac_station_post_remove+0x40/0xe8 [ath12k]
   ath12k_mac_op_sta_state+0xb60/0x1720 [ath12k]
   drv_sta_state+0x100/0xbd8 [mac80211]
   __sta_info_destroy_part2+0x148/0x178 [mac80211]
   ieee80211_set_disassoc+0x500/0x678 [mac80211]

  BUG: Unable to handle kernel NULL pointer dereference at 0x00000000
  pc : ath12k_mac_op_set_key+0x1f8/0x2c0 [ath12k]
  Call trace:
   ath12k_mac_op_set_key+0x1f8/0x2c0 [ath12k]
   drv_set_key+0x70/0x100 [mac80211]
   ieee80211_key_enable_hw_accel+0x78/0x260 [mac80211]
   ieee80211_add_key+0x16c/0x2ac [mac80211]
   nl80211_new_key+0x138/0x280 [cfg80211]

Fix this by checking arvif->is_created before calling
ath12k_mac_alloc_assign_link_sta(). This prevents the broken link from
entering links_map, so all subsequent operations iterating the bitmap
are protected. The reliability of arvif->is_created across all error
paths is ensured by the preceding patch.

Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3

Fixes: a27fa6148dac ("wifi: ath12k: support change_sta_links() mac80211 op")
Signed-off-by: Wei Zhang <wei.zhang@oss.qualcomm.com>
---
 drivers/net/wireless/ath/ath12k/mac.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index 8f8456509468..529a693fdd28 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -8045,16 +8045,16 @@ int ath12k_mac_op_change_sta_links(struct ieee80211_hw *hw,
 			continue;
 
 		arvif = wiphy_dereference(hw->wiphy, ahvif->link[link_id]);
-		arsta = ath12k_mac_alloc_assign_link_sta(ah, ahsta, ahvif, link_id);
+		if (!arvif || !arvif->is_created)
+			continue;
 
-		if (!arvif || !arsta) {
+		arsta = ath12k_mac_alloc_assign_link_sta(ah, ahsta, ahvif, link_id);
+		if (!arsta) {
 			ath12k_hw_warn(ah, "Failed to alloc/assign link sta");
 			continue;
 		}
 
 		ar = arvif->ar;
-		if (!ar)
-			continue;
 
 		ret = ath12k_mac_station_add(ar, arvif, arsta);
 		if (ret) {
-- 
2.34.1


^ permalink raw reply related

* [PATCH ath-next 1/2] wifi: ath12k: fix inconsistent arvif state in vdev_create error paths
From: Wei Zhang @ 2026-05-12  4:49 UTC (permalink / raw)
  To: jeff.johnson; +Cc: ath12k, linux-wireless, linux-kernel, wei.zhang
In-Reply-To: <20260512044906.1735821-1-wei.zhang@oss.qualcomm.com>

ath12k_mac_vdev_create() has three error path issues that leave arvif
in an inconsistent state:

1. When ath12k_wmi_vdev_create() fails, the function returns directly
   without clearing arvif->ar, which was already set before the WMI
   call. Subsequent code checking arvif->ar to determine vdev readiness
   will see a non-NULL value despite no vdev existing in firmware.

2. When ath12k_wmi_send_peer_delete_cmd() fails in err_peer_del, the
   code jumped to err: skipping the DP peer cleanup and vdev rollback,
   leaving num_created_vdevs, vdev maps and arvif list membership live.

3. When ath12k_wait_for_peer_delete_done() fails, the code jumped to
   err_vdev_del: skipping the DP peer cleanup.

Fix by changing the ath12k_wmi_vdev_create() failure to goto err instead
of returning directly, routing both err_peer_del failure paths through
err_dp_peer_del: for proper DP peer and vdev rollback, and consolidating
the arvif state cleanup at err:.

Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3

Fixes: 477cabfdb776 ("wifi: ath12k: modify link arvif creation and removal for MLO")
Signed-off-by: Wei Zhang <wei.zhang@oss.qualcomm.com>
---
 drivers/net/wireless/ath/ath12k/mac.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index 2dc7dba53ec8..8f8456509468 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -10290,7 +10290,7 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif)
 	if (ret) {
 		ath12k_warn(ab, "failed to create WMI vdev %d: %d\n",
 			    arvif->vdev_id, ret);
-		return ret;
+		goto err;
 	}
 
 	ar->num_created_vdevs++;
@@ -10437,13 +10437,13 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif)
 		if (ret) {
 			ath12k_warn(ar->ab, "failed to delete peer vdev_id %d addr %pM\n",
 				    arvif->vdev_id, arvif->bssid);
-			goto err;
+			goto err_dp_peer_del;
 		}
 
 		ret = ath12k_wait_for_peer_delete_done(ar, arvif->vdev_id,
 						       arvif->bssid);
 		if (ret)
-			goto err_vdev_del;
+			goto err_dp_peer_del;
 
 		ar->num_peers--;
 	}
@@ -10460,8 +10460,6 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif)
 
 	ath12k_wmi_vdev_delete(ar, arvif->vdev_id);
 	ar->num_created_vdevs--;
-	arvif->is_created = false;
-	arvif->ar = NULL;
 	ar->allocated_vdev_map &= ~(1LL << arvif->vdev_id);
 	ab->free_vdev_map |= 1LL << arvif->vdev_id;
 	ab->free_vdev_stats_id_map &= ~(1LL << arvif->vdev_stats_id);
@@ -10470,6 +10468,7 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif)
 	spin_unlock_bh(&ar->data_lock);
 
 err:
+	arvif->is_created = false;
 	arvif->ar = NULL;
 	return ret;
 }
-- 
2.34.1


^ permalink raw reply related

* [PATCH ath-next 0/2] wifi: ath12k: fix NULL deref when MLO link activation fails
From: Wei Zhang @ 2026-05-12  4:49 UTC (permalink / raw)
  To: jeff.johnson; +Cc: ath12k, linux-wireless, linux-kernel, wei.zhang

ath12k_mac_op_change_sta_links() adds a link to ahsta->links_map
before verifying that the link's vdev is ready, allowing broken links
to be processed by subsequent operations and causing NULL dereferences.

Patch 1 fixes three error path inconsistencies in ath12k_mac_vdev_create()
that leave arvif state or vdev resources inconsistent: a direct return on
wmi_vdev_create failure bypasses err: which clears arvif->ar; and both
failure paths in err_peer_del skip the DP peer cleanup and vdev rollback.

Patch 2 uses arvif->is_created (made reliable by patch 1) to guard
against links with no vdev before allocating a link station, preventing
broken links from entering links_map.

Wei Zhang (2):
  wifi: ath12k: fix inconsistent arvif state in vdev_create error paths
  wifi: ath12k: fix NULL deref in change_sta_links for unready link

 drivers/net/wireless/ath/ath12k/mac.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

base-commit: 7b25796f571fc09a7aa6fe7efb23edccd326917d
-- 
2.34.1


^ permalink raw reply

* Re: [PATCH v4] wifi: ath11k: fix peer resolution on rx path when peer_id=0
From: Baochen Qiang @ 2026-05-12  3:44 UTC (permalink / raw)
  To: Praneesh P, Matthew Leach, Jeff Johnson
  Cc: Rameshkumar Sundaram, linux-wireless, ath11k, linux-kernel,
	kernel
In-Reply-To: <e248e911-d317-41ee-a590-1385c39ee2e1@oss.qualcomm.com>



On 4/29/2026 6:47 PM, Praneesh P wrote:
> 
> On 4/29/2026 1:06 PM, Baochen Qiang wrote:
>>
>> On 4/24/2026 5:50 PM, Matthew Leach wrote:
>>> It has been observed that on certain chipsets a peer can be assigned
>>> peer_id=0. For reception of non-aggregated MPDUs this is fine as
>>> ath11k_dp_rx_h_find_peer() has a fallback case where it locates the peer
>>> based upon the source MAC address. On an aggregated link, the mpdu_start
>>> header is only populated by hardware on the first sub-MSDU. This causes
>>> the peer resolution to be skipped for the subsequent MSDUs and the
>>> encryption type of these frames to be set to an incorrect value,
>>> resulting in these MSDUs being dropped by ieee80211.
>>>
>>> ath11k_pci 0000:03:00.0: data rx skb 000000002f4b704d len 1534 peer xx:xx:xx:xx:xx:xx 0
>>> ucast sn 3063 he160 rate_idx 9 vht_nss 2 freq 5240 band 1 flag 0x40d1a fcs-err 0 mic-
>>> err 0 amsdu-more 0 peer_id 0 first_msdu 1 last_msdu 0
>>> ath11k_pci 0000:03:00.0: data rx skb 0000000038acd580 len 1534 peer (null) 0 ucast sn
>>> 3063 he160 rate_idx 9 vht_nss 2 freq 5240 band 1 flag 0x40d00 fcs-err 0 mic-err 0
>>> amsdu-more 0 peer_id 0 first_msdu 0 last_msdu 1
>>>
>>> Remove the null peer_id checks in ath11k_dp_rx_h_find_peer() and
>>> ath11k_hal_rx_parse_mon_status_tlv(), allowing peers with an assigned ID
>>> of 0 to be resolved.
>>>
>>> Fixes: 2167fa606c0f ("ath11k: Add support for RX decapsulation offload")
>>> Tested-on: QCA2066 hw2.1 PCI WLAN.HSP.1.1-03926.13-QCAHSPSWPL_V2_SILICONZ_CE-2.52297.9
>> Tested-on: is not an official tag but is ath driver specific, so generally it is put above
>> all official tags:
>>
>> Tested-on: ...
>> <blank line>
>> Fixes: ...
>> s-o-b: ...
>>
>> But since this is trivial I think Jeff can make the change when he merges it, so no need
>> to respin just for it.
> For QCN9074, IPQ8074, IPQ5018 and IPQ6018, Peer_id 0 is not a expected value. Like ath12k,
> it is better to handle it through hw_params.

ath12k takes the same way as used in this patch:

https://lore.kernel.org/all/20260512025732.1297849-1-hangtian.zhu@oss.qualcomm.com/

^ permalink raw reply

* Re: ath12k WCN7850: Q6 Hexagon fault at WLAON region 0x1792000 ~2s post-AUTHORIZE on X1E80100
From: Baochen Qiang @ 2026-05-12  3:38 UTC (permalink / raw)
  To: Marcus Glocker, ath12k, linux-wireless
  Cc: jjohnson, kvalo, manivannan.sadhasivam, Mark Kettenis
In-Reply-To: <g7dkeq3uwg7eby57zcuu5eysf4tqomh5civlvkpnlziipn6xis@45eevyzgfmaq>



On 5/5/2026 5:08 AM, Marcus Glocker wrote:
> Hi,
> 
> We're porting ath12k to OpenBSD as the qwz(4) driver, targeting Samsung
> Galaxy Book4 Edge (X1E80100 SoC, WCN7850 hw2.0).  Scan, auth, 4-way
> handshake all complete; ~2 seconds after WPA2 AUTHORIZE the WCN7850
> firmware crashes deterministically with:
> 
> 	dlpager_main.c:147 Non Page Fault Exception cause code 0x 23
> 	at Address: 0x 1792000
> 
> Cause code 0x23 isn't a valid arm64 exception -- the fault is on the
> WCN7850's on-die Hexagon Q6 DSP, with QURT's generic exception handler
> (which happens to live in dlpager_main.c) printing it.  So this is not
> a host CPU fault.
> 
> Per the RDDM segment table (at the start of the dump), VA 0x01792000
> is the start of the chip's WLAON_DUMP region (size 0x820).  The Q6 is
> trying to read its own always-on hardware state region and the chip
> refuses the access.
> 
> (Samsung, Asus, Honor) with multiple FW builds.  Currently testing
> with WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3
> (fw 0x110cffff, 2025-06-25) -- the exact blob a Linux ath12k user
> runs successfully on the identical Samsung hardware.  Same board-2.bin,
> same compiled DTB (upstream hamoa.dtsi based).
> 
> We've field-compared qwz against ath12k and ruled out (byte-level or
> wire-level):
> 
>   * QMI host_cap, m3_info, wlan_cfg, wlan_ini, bdf_download (all
>     fields including ce_config, svc_to_ce_map, shadow_reg_v3,
>     feature_list, m3 paddr/size, nm_modem)
>   * MHI bringup ordering (BHI -> wait SBL EE -> wait M0 -> BHIE)
>   * BHI/BHIE DMA coherency
>   * ASPM disable before MHI start
>   * WLAON_WARM_SW_ENTRY zeroing + QFPROM_PWR_CTRL VDD4BLOW clear
>   * static_window_map=false + window-bank register init
>   * Per-chunk vs monolithic respond_mem allocation
>   * WMI_PEER_MIMO_PS_STATE = WMI_PEER_SMPS_PS_NONE (added matching
>     ath12k_setup_peer_smps; doesn't help)
>   * FW image variation (c5 and c7 both fail identically)
> 
> Specifically NOT involved (we have evidence either way):
> 
>   * Gunyah -- X1E80100 is reportedly run in EL2 without Gunyah by
>     users where ath12k works; so Gunyah isn't programming WLAON
>     access for the Q6.
>   * SMMU / pcie_smmu -- pcie_smmu is status="reserved" upstream,
>     pcie4 has no iommus property; PCIe DMA bypasses SMMU.
>   * SCM/PAS -- ath12k's PCIe path makes no qcom_scm_* calls.
> 
> Question: what subsystem inside the WCN7850 firmware touches the
> WLAON region at 0x01792000 around 2 seconds after the host sends
> WMI_PEER_AUTHORIZE?  And what host-side configuration (WMI command,
> HTT message, MHI state, etc.) primes that path so the access
> succeeds on Linux?
> 
> Even a pointer at the right Linux code path or the right FW-side
> component would unblock us.  We have full RDDM dumps and dmesg
> captures available; happy to share off-list or as attachments.

please help collect ath12k successful dmesg log and qwz failed dmesg log for compare.

Please enable verbose ath12k log when loading ath12k driver:

If you are using the latest upstream ath12k:

	sudo modprobe ath12k debug_mask=0xffffffff
	sudo modprobe ath12k_wifi7

If you are using an old ath12k:

	sudo modprobe ath12k debug_mask=0xffffffff

> 
> Thanks,
> Marcus
> 


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox