Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH iwlwifi-next 04/15] wifi: iwlwifi: mld: fix smatch warning
From: Miri Korenblit @ 2026-05-27 20:05 UTC (permalink / raw)
  To: linux-wireless
In-Reply-To: <20260527200512.506707-1-miriam.rachel.korenblit@intel.com>

We dereference the mld_sta pointer before checking for NULL.
But we do check the sta pointer, and sta != NULL means mld_sta != NULL,
so there is no real issue.
Fix it anyway to silence the warning.

Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mld/tx.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/tx.c b/drivers/net/wireless/intel/iwlwifi/mld/tx.c
index 1e8716cbb4ce..2185dade95f8 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/tx.c
@@ -563,7 +563,8 @@ iwl_mld_fill_tx_cmd(struct iwl_mld *mld, struct sk_buff *skb,
 	 * - when no sta is given.
 	 * - frames that are sent to an NMI sta, which is only used for management.
 	 */
-	if (unlikely(!sta || mld_sta->vif->type == NL80211_IFTYPE_NAN ||
+	if (unlikely(!sta ||
+		     (mld_sta && mld_sta->vif->type == NL80211_IFTYPE_NAN) ||
 		     info->control.flags & IEEE80211_TX_CTRL_RATE_INJECT)) {
 		flags |= IWL_TX_FLAGS_CMD_RATE;
 		rate_n_flags = iwl_mld_get_tx_rate_n_flags(mld, info, sta,
-- 
2.34.1


^ permalink raw reply related

* [PATCH iwlwifi-next 03/15] wifi: iwlwifi: remove mvm prefix from marker command
From: Miri Korenblit @ 2026-05-27 20:05 UTC (permalink / raw)
  To: linux-wireless
In-Reply-To: <20260527200512.506707-1-miriam.rachel.korenblit@intel.com>

This command is sent in other opmodes as well. Remove the mvm prefix.

Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 .../net/wireless/intel/iwlwifi/fw/api/commands.h |  4 ++--
 .../net/wireless/intel/iwlwifi/fw/api/debug.h    | 16 ++++++++--------
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c      |  6 +++---
 3 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
index abd259350589..f76f76e54c4e 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
@@ -466,8 +466,8 @@ enum iwl_legacy_cmds {
 	MCC_CHUB_UPDATE_CMD = 0xc9,
 
 	/**
-	 * @MARKER_CMD: trace marker command, uses &struct iwl_mvm_marker
-	 * with &struct iwl_mvm_marker_rsp
+	 * @MARKER_CMD: trace marker command, uses &struct iwl_marker
+	 * with &struct iwl_marker_rsp
 	 */
 	MARKER_CMD = 0xcb,
 
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h b/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h
index 61a850de26fc..382d1c2581ad 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
 /*
- * Copyright (C) 2005-2014, 2018-2025 Intel Corporation
+ * Copyright (C) 2005-2014, 2018-2026 Intel Corporation
  * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
  * Copyright (C) 2016-2017 Intel Deutschland GmbH
  */
@@ -262,20 +262,20 @@ struct iwl_mfu_assert_dump_notif {
 } __packed; /* MFU_DUMP_ASSERT_API_S_VER_1 */
 
 /**
- * enum iwl_mvm_marker_id - marker ids
+ * enum iwl_marker_id - marker ids
  *
  * The ids for different type of markers to insert into the usniffer logs
  *
  * @MARKER_ID_TX_FRAME_LATENCY: TX latency marker
  * @MARKER_ID_SYNC_CLOCK: sync FW time and systime
  */
-enum iwl_mvm_marker_id {
+enum iwl_marker_id {
 	MARKER_ID_TX_FRAME_LATENCY = 1,
 	MARKER_ID_SYNC_CLOCK = 2,
 }; /* MARKER_ID_API_E_VER_2 */
 
 /**
- * struct iwl_mvm_marker - mark info into the usniffer logs
+ * struct iwl_marker - mark info into the usniffer logs
  *
  * (MARKER_CMD = 0xcb)
  *
@@ -284,12 +284,12 @@ enum iwl_mvm_marker_id {
  * In the command response the ucode will return the GP2 time.
  *
  * @dw_len: The amount of dwords following this byte including this byte.
- * @marker_id: A unique marker id (iwl_mvm_marker_id).
+ * @marker_id: A unique marker id (iwl_marker_id).
  * @reserved: reserved.
  * @timestamp: in milliseconds since 1970-01-01 00:00:00 UTC
  * @metadata: additional meta data that will be written to the unsiffer log
  */
-struct iwl_mvm_marker {
+struct iwl_marker {
 	u8 dw_len;
 	u8 marker_id;
 	__le16 reserved;
@@ -298,11 +298,11 @@ struct iwl_mvm_marker {
 } __packed; /* MARKER_API_S_VER_1 */
 
 /**
- * struct iwl_mvm_marker_rsp - Response to marker cmd
+ * struct iwl_marker_rsp - Response to marker cmd
  *
  * @gp2: The gp2 clock value in the FW
  */
-struct iwl_mvm_marker_rsp {
+struct iwl_marker_rsp {
 	__le32 gp2;
 } __packed;
 
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 337e312c2f43..6621ef9358bc 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -2383,8 +2383,8 @@ static int iwl_fw_dbg_restart_recording(struct iwl_trans *trans,
 
 int iwl_fw_send_timestamp_marker_cmd(struct iwl_fw_runtime *fwrt)
 {
-	struct iwl_mvm_marker marker = {
-		.dw_len = sizeof(struct iwl_mvm_marker) / 4,
+	struct iwl_marker marker = {
+		.dw_len = sizeof(struct iwl_marker) / 4,
 		.marker_id = MARKER_ID_SYNC_CLOCK,
 	};
 	struct iwl_host_cmd hcmd = {
@@ -2392,7 +2392,7 @@ int iwl_fw_send_timestamp_marker_cmd(struct iwl_fw_runtime *fwrt)
 		.id = WIDE_ID(LONG_GROUP, MARKER_CMD),
 		.dataflags = {},
 	};
-	struct iwl_mvm_marker_rsp *resp;
+	struct iwl_marker_rsp *resp;
 	int cmd_ver = iwl_fw_lookup_cmd_ver(fwrt->fw,
 					    WIDE_ID(LONG_GROUP, MARKER_CMD),
 					    IWL_FW_CMD_VER_UNKNOWN);
-- 
2.34.1


^ permalink raw reply related

* [PATCH iwlwifi-next 02/15] wifi: iwlwifi: remove stale comment
From: Miri Korenblit @ 2026-05-27 20:04 UTC (permalink / raw)
  To: linux-wireless
In-Reply-To: <20260527200512.506707-1-miriam.rachel.korenblit@intel.com>

iwl_pcie_set_hw_ready still returns the return value of iwl_poll_bits,
but the latter one no longer returns the time elapsed until success, now it
returns either success or failure.
Remove the comment entirely.

Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/trans.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/trans.c
index 40fd5f3fdeb7..976a47ef6d0e 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/trans.c
@@ -521,7 +521,6 @@ static int iwl_pcie_nic_init(struct iwl_trans *trans)
 
 #define HW_READY_TIMEOUT (50)
 
-/* Note: returns poll_bit return value, which is >= 0 if success */
 static int iwl_pcie_set_hw_ready(struct iwl_trans *trans)
 {
 	int ret;
-- 
2.34.1


^ permalink raw reply related

* [PATCH iwlwifi-next 01/15] wifi: iwlwifi: fw: cut down NIC wakeups during dump
From: Miri Korenblit @ 2026-05-27 20:04 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg
In-Reply-To: <20260527200512.506707-1-miriam.rachel.korenblit@intel.com>

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

Currently, the dump code attempts to dump any number of
memories and register banks, as defined by the firmware.
Especially when the device is failing, this can lead to
excessive time spent attempting to acquire NIC access
over and over again.

Improve the code to only attempt to acquire NIC access
once or twice, but using the new memory dump functions
that may drop the spinlock etc. Mark all dump regions
that require NIC access, and skip them if we couldn't
obtain that.

In order to avoid CPU latency due to the increased time
holding the spinlock (and possibly disabling softirqs),
drop locks and call cond_resched() after each section
(if holding NIC access) but don't release HW NIC access.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c   | 90 +++++++++----------
 .../net/wireless/intel/iwlwifi/iwl-trans.c    |  5 ++
 .../net/wireless/intel/iwlwifi/iwl-trans.h    | 11 +++
 .../intel/iwlwifi/pcie/gen1_2/internal.h      |  1 +
 .../intel/iwlwifi/pcie/gen1_2/trans.c         |  2 +-
 5 files changed, 63 insertions(+), 46 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 069c3bad6f29..337e312c2f43 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -103,7 +103,7 @@ static int iwl_dump_ini_prph_mac_iter_common(struct iwl_fw_runtime *fwrt,
 	range->internal_base_addr = cpu_to_le32(addr);
 	range->range_data_size = size;
 	for (i = 0; i < le32_to_cpu(size); i += 4)
-		*val++ = cpu_to_le32(iwl_read_prph(fwrt->trans, addr + i));
+		*val++ = cpu_to_le32(iwl_trans_read_prph(fwrt->trans, addr + i));
 
 	return sizeof(*range) + le32_to_cpu(range->range_data_size);
 }
@@ -158,9 +158,6 @@ static int iwl_dump_ini_prph_phy_iter_common(struct iwl_fw_runtime *fwrt,
 	indirect_wr_addr += le32_to_cpu(offset);
 	indirect_rd_addr += le32_to_cpu(offset);
 
-	if (!iwl_trans_grab_nic_access(fwrt->trans))
-		return -EBUSY;
-
 	dphy_addr = (offset) ? WFPM_LMAC2_PS_CTL_RW : WFPM_LMAC1_PS_CTL_RW;
 	dphy_state = iwl_read_umac_prph_no_grab(fwrt->trans, dphy_addr);
 
@@ -194,7 +191,6 @@ static int iwl_dump_ini_prph_phy_iter_common(struct iwl_fw_runtime *fwrt,
 		*val++ = cpu_to_le32(prph_val);
 	}
 
-	iwl_trans_release_nic_access(fwrt->trans);
 	return sizeof(*range) + le32_to_cpu(range->range_data_size);
 }
 
@@ -283,8 +279,8 @@ static int iwl_dump_ini_dev_mem_iter(struct iwl_fw_runtime *fwrt,
 
 	range->internal_base_addr = cpu_to_le32(addr);
 	range->range_data_size = reg->dev_addr.size;
-	iwl_trans_read_mem_bytes(fwrt->trans, addr, range->data,
-				 le32_to_cpu(reg->dev_addr.size));
+	iwl_trans_read_mem_bytes_no_grab(fwrt->trans, addr, range->data,
+					 le32_to_cpu(reg->dev_addr.size));
 
 	if (reg->sub_type == IWL_FW_INI_REGION_DEVICE_MEMORY_SUBTYPE_HW_SMEM &&
 	    fwrt->sanitize_ops && fwrt->sanitize_ops->frob_txf)
@@ -368,8 +364,8 @@ static int iwl_dump_ini_mon_smem_iter(struct iwl_fw_runtime *fwrt,
 
 	range->internal_base_addr = cpu_to_le32(addr);
 	range->range_data_size = reg->internal_buffer.size;
-	iwl_trans_read_mem_bytes(fwrt->trans, addr, range->data,
-				 le32_to_cpu(reg->internal_buffer.size));
+	iwl_trans_read_mem_bytes_no_grab(fwrt->trans, addr, range->data,
+					 le32_to_cpu(reg->internal_buffer.size));
 
 	return sizeof(*range) + le32_to_cpu(range->range_data_size);
 }
@@ -443,9 +439,6 @@ static int iwl_dump_ini_txf_iter(struct iwl_fw_runtime *fwrt,
 	if (!iwl_ini_txf_iter(fwrt, reg_data, idx))
 		return -EIO;
 
-	if (!iwl_trans_grab_nic_access(fwrt->trans))
-		return -EBUSY;
-
 	range->fifo_hdr.fifo_num = cpu_to_le32(iter->fifo);
 	range->fifo_hdr.num_of_registers = cpu_to_le32(registers_num);
 	range->range_data_size = cpu_to_le32(iter->fifo_size + registers_size);
@@ -489,8 +482,6 @@ static int iwl_dump_ini_txf_iter(struct iwl_fw_runtime *fwrt,
 					     reg_dump, iter->fifo_size);
 
 out:
-	iwl_trans_release_nic_access(fwrt->trans);
-
 	return sizeof(*range) + le32_to_cpu(range->range_data_size);
 }
 
@@ -511,9 +502,6 @@ iwl_dump_ini_prph_snps_dphyip_iter(struct iwl_fw_runtime *fwrt,
 	range->internal_base_addr = cpu_to_le32(addr);
 	range->range_data_size = reg->dev_addr.size;
 
-	if (!iwl_trans_grab_nic_access(fwrt->trans))
-		return -EBUSY;
-
 	indirect_rd_wr_addr += le32_to_cpu(offset);
 
 	dphy_addr = offset ? WFPM_LMAC2_PS_CTL_RW : WFPM_LMAC1_PS_CTL_RW;
@@ -537,7 +525,6 @@ iwl_dump_ini_prph_snps_dphyip_iter(struct iwl_fw_runtime *fwrt,
 				     DPHYIP_INDIRECT_RD_SHIFT);
 	}
 
-	iwl_trans_release_nic_access(fwrt->trans);
 	return sizeof(*range) + le32_to_cpu(range->range_data_size);
 }
 
@@ -626,9 +613,6 @@ static int iwl_dump_ini_rxf_iter(struct iwl_fw_runtime *fwrt,
 	if (!rxf_data.size)
 		return -EIO;
 
-	if (!iwl_trans_grab_nic_access(fwrt->trans))
-		return -EBUSY;
-
 	range->fifo_hdr.fifo_num = cpu_to_le32(rxf_data.fifo_num);
 	range->fifo_hdr.num_of_registers = cpu_to_le32(registers_num);
 	range->range_data_size = cpu_to_le32(rxf_data.size + registers_size);
@@ -668,8 +652,6 @@ static int iwl_dump_ini_rxf_iter(struct iwl_fw_runtime *fwrt,
 		*data++ = cpu_to_le32(iwl_trans_read_prph(fwrt->trans, addr));
 
 out:
-	iwl_trans_release_nic_access(fwrt->trans);
-
 	return sizeof(*range) + le32_to_cpu(range->range_data_size);
 }
 
@@ -686,8 +668,8 @@ iwl_dump_ini_err_table_iter(struct iwl_fw_runtime *fwrt,
 
 	range->internal_base_addr = cpu_to_le32(addr);
 	range->range_data_size = err_table->size;
-	iwl_trans_read_mem_bytes(fwrt->trans, addr, range->data,
-				 le32_to_cpu(err_table->size));
+	iwl_trans_read_mem_bytes_no_grab(fwrt->trans, addr, range->data,
+					 le32_to_cpu(err_table->size));
 
 	return sizeof(*range) + le32_to_cpu(range->range_data_size);
 }
@@ -707,8 +689,8 @@ iwl_dump_ini_special_mem_iter(struct iwl_fw_runtime *fwrt,
 
 	range->internal_base_addr = cpu_to_le32(addr);
 	range->range_data_size = special_mem->size;
-	iwl_trans_read_mem_bytes(fwrt->trans, addr, range->data,
-				 le32_to_cpu(special_mem->size));
+	iwl_trans_read_mem_bytes_no_grab(fwrt->trans, addr, range->data,
+					 le32_to_cpu(special_mem->size));
 
 	return sizeof(*range) + le32_to_cpu(range->range_data_size);
 }
@@ -724,9 +706,6 @@ iwl_dump_ini_dbgi_sram_iter(struct iwl_fw_runtime *fwrt,
 	u32 prph_data;
 	int i;
 
-	if (!iwl_trans_grab_nic_access(fwrt->trans))
-		return -EBUSY;
-
 	range->range_data_size = reg->dev_addr.size;
 	for (i = 0; i < (le32_to_cpu(reg->dev_addr.size) / 4); i++) {
 		prph_data =
@@ -734,13 +713,11 @@ iwl_dump_ini_dbgi_sram_iter(struct iwl_fw_runtime *fwrt,
 					    (i % 2) ?
 						DBGI_SRAM_TARGET_ACCESS_RDATA_MSB :
 						DBGI_SRAM_TARGET_ACCESS_RDATA_LSB);
-		if (iwl_trans_is_hw_error_value(prph_data)) {
-			iwl_trans_release_nic_access(fwrt->trans);
+		if (iwl_trans_is_hw_error_value(prph_data))
 			return -EBUSY;
-		}
 		*val++ = cpu_to_le32(prph_data);
 	}
-	iwl_trans_release_nic_access(fwrt->trans);
+
 	return sizeof(*range) + le32_to_cpu(range->range_data_size);
 }
 
@@ -787,8 +764,8 @@ static int iwl_dump_ini_imr_iter(struct iwl_fw_runtime *fwrt,
 	fwrt->trans->dbg.imr_data.imr_curr_addr = imr_curr_addr + size_to_dump;
 	fwrt->trans->dbg.imr_data.imr2sram_remainbyte -= size_to_dump;
 
-	iwl_trans_read_mem_bytes(fwrt->trans, sram_addr, range->data,
-				 size_to_dump);
+	iwl_trans_read_mem_bytes_no_grab(fwrt->trans, sram_addr, range->data,
+					 size_to_dump);
 	return sizeof(*range) + le32_to_cpu(range->range_data_size);
 }
 
@@ -842,11 +819,6 @@ iwl_dump_ini_mon_fill_header(struct iwl_fw_runtime *fwrt, u32 alloc_id,
 			     struct iwl_fw_ini_monitor_dump *data,
 			     const struct iwl_fw_mon_regs *addrs)
 {
-	if (!iwl_trans_grab_nic_access(fwrt->trans)) {
-		IWL_ERR(fwrt, "Failed to get monitor header\n");
-		return NULL;
-	}
-
 	data->write_ptr = iwl_get_mon_reg(fwrt, alloc_id,
 					  &addrs->write_ptr);
 	if (fwrt->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
@@ -859,8 +831,6 @@ iwl_dump_ini_mon_fill_header(struct iwl_fw_runtime *fwrt, u32 alloc_id,
 	data->cur_frag = iwl_get_mon_reg(fwrt, alloc_id,
 					 &addrs->cur_frag);
 
-	iwl_trans_release_nic_access(fwrt->trans);
-
 	data->header.version = cpu_to_le32(IWL_INI_DUMP_VER);
 
 	return data->data;
@@ -1266,6 +1236,7 @@ iwl_dump_ini_imr_get_size(struct iwl_fw_runtime *fwrt,
  *	the first range or NULL if failed to fill headers.
  * @fill_range: copies a given memory range into the dump.
  *	Returns the size of the range or negative error value otherwise.
+ * @requires_nic_access: indicates to dump only if NIC access was acquired
  */
 struct iwl_dump_ini_mem_ops {
 	u32 (*get_num_of_ranges)(struct iwl_fw_runtime *fwrt,
@@ -1278,6 +1249,7 @@ struct iwl_dump_ini_mem_ops {
 	int (*fill_range)(struct iwl_fw_runtime *fwrt,
 			  struct iwl_dump_ini_region_data *reg_data,
 			  void *range, int idx);
+	bool requires_nic_access;
 };
 
 struct iwl_fw_ini_dump_entry {
@@ -1374,7 +1346,8 @@ static void iwl_dump_ini_mem_prep(struct iwl_fw_runtime *fwrt,
 }
 
 static u32 iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt,
-			    struct iwl_fw_ini_dump_entry *entry)
+			    struct iwl_fw_ini_dump_entry *entry,
+			    bool have_nic_access)
 {
 	struct iwl_dump_ini_region_data *reg_data = &entry->reg_data;
 	struct iwl_fw_ini_region_tlv *reg = (void *)reg_data->reg_tlv->data;
@@ -1388,6 +1361,9 @@ static u32 iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt,
 	u32 free_size;
 	u64 header_size;
 
+	if (!have_nic_access && ops->requires_nic_access)
+		goto out_err;
+
 	tlv = (void *)entry->data;
 	header = (void *)tlv->data;
 
@@ -1541,36 +1517,42 @@ static const struct iwl_dump_ini_mem_ops iwl_dump_ini_region_ops[] = {
 		.get_size = iwl_dump_ini_mon_smem_get_size,
 		.fill_mem_hdr = iwl_dump_ini_mon_smem_fill_header,
 		.fill_range = iwl_dump_ini_mon_smem_iter,
+		.requires_nic_access = true,
 	},
 	[IWL_FW_INI_REGION_DRAM_BUFFER] = {
 		.get_num_of_ranges = iwl_dump_ini_mon_dram_ranges,
 		.get_size = iwl_dump_ini_mon_dram_get_size,
 		.fill_mem_hdr = iwl_dump_ini_mon_dram_fill_header,
 		.fill_range = iwl_dump_ini_mon_dram_iter,
+		.requires_nic_access = true,
 	},
 	[IWL_FW_INI_REGION_TXF] = {
 		.get_num_of_ranges = iwl_dump_ini_txf_ranges,
 		.get_size = iwl_dump_ini_txf_get_size,
 		.fill_mem_hdr = iwl_dump_ini_mem_fill_header,
 		.fill_range = iwl_dump_ini_txf_iter,
+		.requires_nic_access = true,
 	},
 	[IWL_FW_INI_REGION_RXF] = {
 		.get_num_of_ranges = iwl_dump_ini_single_range,
 		.get_size = iwl_dump_ini_rxf_get_size,
 		.fill_mem_hdr = iwl_dump_ini_mem_fill_header,
 		.fill_range = iwl_dump_ini_rxf_iter,
+		.requires_nic_access = true,
 	},
 	[IWL_FW_INI_REGION_LMAC_ERROR_TABLE] = {
 		.get_num_of_ranges = iwl_dump_ini_single_range,
 		.get_size = iwl_dump_ini_err_table_get_size,
 		.fill_mem_hdr = iwl_dump_ini_err_table_fill_header,
 		.fill_range = iwl_dump_ini_err_table_iter,
+		.requires_nic_access = true,
 	},
 	[IWL_FW_INI_REGION_UMAC_ERROR_TABLE] = {
 		.get_num_of_ranges = iwl_dump_ini_single_range,
 		.get_size = iwl_dump_ini_err_table_get_size,
 		.fill_mem_hdr = iwl_dump_ini_err_table_fill_header,
 		.fill_range = iwl_dump_ini_err_table_iter,
+		.requires_nic_access = true,
 	},
 	[IWL_FW_INI_REGION_RSP_OR_NOTIF] = {
 		.get_num_of_ranges = iwl_dump_ini_single_range,
@@ -1583,30 +1565,35 @@ static const struct iwl_dump_ini_mem_ops iwl_dump_ini_region_ops[] = {
 		.get_size = iwl_dump_ini_mem_get_size,
 		.fill_mem_hdr = iwl_dump_ini_mem_fill_header,
 		.fill_range = iwl_dump_ini_dev_mem_iter,
+		.requires_nic_access = true,
 	},
 	[IWL_FW_INI_REGION_PERIPHERY_MAC] = {
 		.get_num_of_ranges = iwl_dump_ini_mem_ranges,
 		.get_size = iwl_dump_ini_mem_get_size,
 		.fill_mem_hdr = iwl_dump_ini_mem_fill_header,
 		.fill_range = iwl_dump_ini_prph_mac_iter,
+		.requires_nic_access = true,
 	},
 	[IWL_FW_INI_REGION_PERIPHERY_PHY] = {
 		.get_num_of_ranges = iwl_dump_ini_mem_ranges,
 		.get_size = iwl_dump_ini_mem_get_size,
 		.fill_mem_hdr = iwl_dump_ini_mem_fill_header,
 		.fill_range = iwl_dump_ini_prph_phy_iter,
+		.requires_nic_access = true,
 	},
 	[IWL_FW_INI_REGION_PERIPHERY_MAC_RANGE] = {
 		.get_num_of_ranges = iwl_dump_ini_mem_block_ranges,
 		.get_size = iwl_dump_ini_mem_block_get_size,
 		.fill_mem_hdr = iwl_dump_ini_mem_fill_header,
 		.fill_range = iwl_dump_ini_prph_mac_block_iter,
+		.requires_nic_access = true,
 	},
 	[IWL_FW_INI_REGION_PERIPHERY_PHY_RANGE] = {
 		.get_num_of_ranges = iwl_dump_ini_mem_block_ranges,
 		.get_size = iwl_dump_ini_mem_block_get_size,
 		.fill_mem_hdr = iwl_dump_ini_mem_fill_header,
 		.fill_range = iwl_dump_ini_prph_phy_block_iter,
+		.requires_nic_access = true,
 	},
 	[IWL_FW_INI_REGION_PERIPHERY_AUX] = {},
 	[IWL_FW_INI_REGION_PAGING] = {
@@ -1626,6 +1613,7 @@ static const struct iwl_dump_ini_mem_ops iwl_dump_ini_region_ops[] = {
 		.get_size = iwl_dump_ini_imr_get_size,
 		.fill_mem_hdr = iwl_dump_ini_imr_fill_header,
 		.fill_range = iwl_dump_ini_imr_iter,
+		.requires_nic_access = true,
 	},
 	[IWL_FW_INI_REGION_PCI_IOSF_CONFIG] = {
 		.get_num_of_ranges = iwl_dump_ini_mem_ranges,
@@ -1638,18 +1626,21 @@ static const struct iwl_dump_ini_mem_ops iwl_dump_ini_region_ops[] = {
 		.get_size = iwl_dump_ini_special_mem_get_size,
 		.fill_mem_hdr = iwl_dump_ini_special_mem_fill_header,
 		.fill_range = iwl_dump_ini_special_mem_iter,
+		.requires_nic_access = true,
 	},
 	[IWL_FW_INI_REGION_DBGI_SRAM] = {
 		.get_num_of_ranges = iwl_dump_ini_mem_ranges,
 		.get_size = iwl_dump_ini_mon_dbgi_get_size,
 		.fill_mem_hdr = iwl_dump_ini_mon_dbgi_fill_header,
 		.fill_range = iwl_dump_ini_dbgi_sram_iter,
+		.requires_nic_access = true,
 	},
 	[IWL_FW_INI_REGION_PERIPHERY_SNPS_DPHYIP] = {
 		.get_num_of_ranges = iwl_dump_ini_mem_ranges,
 		.get_size = iwl_dump_ini_mem_get_size,
 		.fill_mem_hdr = iwl_dump_ini_mem_fill_header,
 		.fill_range = iwl_dump_ini_prph_snps_dphyip_iter,
+		.requires_nic_access = true,
 	},
 };
 
@@ -1733,8 +1724,11 @@ iwl_dump_ini_dump_entries(struct iwl_fw_runtime *fwrt,
 			  enum iwl_dump_ini_region_selector which)
 {
 	struct iwl_fw_ini_dump_entry *entry, *tmp;
+	bool have_nic_access;
 	u32 size = 0;
 
+	have_nic_access = iwl_trans_grab_nic_access(fwrt->trans);
+
 	list_for_each_entry_safe(entry, tmp, list, list) {
 		u32 dp = entry->region_dump_policy;
 
@@ -1751,9 +1745,15 @@ iwl_dump_ini_dump_entries(struct iwl_fw_runtime *fwrt,
 			break;
 		}
 
-		size += iwl_dump_ini_mem(fwrt, entry);
+		size += iwl_dump_ini_mem(fwrt, entry, have_nic_access);
+
+		if (have_nic_access)
+			iwl_trans_resched_with_nic_access(fwrt->trans);
 	}
 
+	if (have_nic_access)
+		iwl_trans_release_nic_access(fwrt->trans);
+
 	return size;
 }
 
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
index 0009488ca51b..73aae1125042 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
@@ -558,6 +558,11 @@ bool iwl_trans_grab_nic_access(struct iwl_trans *trans)
 }
 IWL_EXPORT_SYMBOL(iwl_trans_grab_nic_access);
 
+void iwl_trans_resched_with_nic_access(struct iwl_trans *trans)
+{
+	iwl_trans_pcie_resched_with_nic_access(trans);
+}
+
 void __releases(nic_access)
 iwl_trans_release_nic_access(struct iwl_trans *trans)
 {
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index 3ae840e546e8..914864005704 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -981,6 +981,17 @@ void iwl_trans_set_bits_mask(struct iwl_trans *trans, u32 reg,
 
 bool iwl_trans_grab_nic_access(struct iwl_trans *trans);
 
+/**
+ * iwl_trans_resched_with_nic_access - reschedule while holding NIC access
+ * @trans: the transport pointer
+ *
+ * This can be called while holding NIC access, during periods where
+ * the lock itself isn't interesting, the NIC should remain active,
+ * but a lot of processing is happening and the CPU may need to be
+ * released. In practice, this is only during FW dump.
+ */
+void iwl_trans_resched_with_nic_access(struct iwl_trans *trans);
+
 void __releases(nic_access)
 iwl_trans_release_nic_access(struct iwl_trans *trans);
 
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/internal.h
index abc0c831d1ca..d84c7c1efee1 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/internal.h
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/internal.h
@@ -1203,6 +1203,7 @@ void iwl_trans_pcie_set_bits_mask(struct iwl_trans *trans, u32 reg,
 int iwl_trans_pcie_read_config32(struct iwl_trans *trans, u32 ofs,
 				 u32 *val);
 bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans);
+void iwl_trans_pcie_resched_with_nic_access(struct iwl_trans *trans);
 void __releases(nic_access_nobh)
 iwl_trans_pcie_release_nic_access(struct iwl_trans *trans);
 void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans, u8 max_power);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/trans.c
index 1c4ee76d8387..40fd5f3fdeb7 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/trans.c
@@ -2424,7 +2424,7 @@ bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans)
 	return false;
 }
 
-static void iwl_trans_pcie_resched_with_nic_access(struct iwl_trans *trans)
+void iwl_trans_pcie_resched_with_nic_access(struct iwl_trans *trans)
 {
 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 
-- 
2.34.1


^ permalink raw reply related

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

Hi,

Features, fixes and cleanups from our internal tree.

Miri
---

Avinash Bhatt (1):
  wifi: iwlwifi: mld: add KUnit tests for duplicated beacon RSSI
    adjustment

Ilan Peer (1):
  wifi: iwlwifi: mld: Require HT support for NAN

Israel Kozitz (1):
  wifi: iwlwifi: mld: support FW TLV for NAN max channel switch time

Johannes Berg (5):
  wifi: iwlwifi: fw: cut down NIC wakeups during dump
  wifi: iwlwifi: mvm: rename iwl_mvm_mac80211_idx_to_hwrate()
  wifi: iwlwifi: move iwl_fw_rate_idx_to_plcp() to mvm
  wifi: iwlwifi: mld: don't WARN on WoWLAN suspend w/o netdetect
  wifi: iwlwifi: mvm: fix P2P-Device binding handling

Miri Korenblit (4):
  wifi: iwlwifi: remove stale comment
  wifi: iwlwifi: remove mvm prefix from marker command
  wifi: iwlwifi: mld: fix smatch warning
  wifi: iwlwifi: mld: always allow mimo in NAN

Moriya Itzchaki (1):
  wifi: iwlwifi: fix STEP_URM register address for SC devices

Pagadala Yesu Anjaneyulu (1):
  wifi: iwlwifi: mld: set fast-balance scan for active EMLSR

Shahar Tzarfati (1):
  wifi: iwlwifi: cfg: Revert "wifi: iwlwifi: cfg: move the
    MODULE_FIRMWARE to the per-rf file"

 drivers/net/wireless/intel/iwlwifi/cfg/bz.c   |  12 +++
 .../net/wireless/intel/iwlwifi/cfg/rf-fm.c    |  12 ---
 .../wireless/intel/iwlwifi/fw/api/commands.h  |   4 +-
 .../net/wireless/intel/iwlwifi/fw/api/debug.h |  16 +--
 .../net/wireless/intel/iwlwifi/fw/api/rs.h    |   3 +-
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c   |  96 ++++++++---------
 drivers/net/wireless/intel/iwlwifi/fw/file.h  |   1 +
 drivers/net/wireless/intel/iwlwifi/fw/img.h   |   1 +
 drivers/net/wireless/intel/iwlwifi/fw/rs.c    |  27 -----
 drivers/net/wireless/intel/iwlwifi/iwl-drv.c  |   6 ++
 drivers/net/wireless/intel/iwlwifi/iwl-prph.h |   3 +-
 .../net/wireless/intel/iwlwifi/iwl-trans.c    |   5 +
 .../net/wireless/intel/iwlwifi/iwl-trans.h    |  11 ++
 drivers/net/wireless/intel/iwlwifi/mld/d3.c   |   7 +-
 drivers/net/wireless/intel/iwlwifi/mld/link.c |   3 +-
 drivers/net/wireless/intel/iwlwifi/mld/link.h |   5 +
 .../net/wireless/intel/iwlwifi/mld/mac80211.c |   9 +-
 drivers/net/wireless/intel/iwlwifi/mld/nan.c  |   3 +-
 drivers/net/wireless/intel/iwlwifi/mld/scan.c |   8 +-
 drivers/net/wireless/intel/iwlwifi/mld/sta.c  |   6 ++
 .../wireless/intel/iwlwifi/mld/tests/link.c   | 102 +++++++++++++++++-
 .../wireless/intel/iwlwifi/mld/tests/utils.c  |  60 +++++++++++
 .../wireless/intel/iwlwifi/mld/tests/utils.h  |   7 +-
 drivers/net/wireless/intel/iwlwifi/mld/tx.c   |   3 +-
 .../net/wireless/intel/iwlwifi/mvm/binding.c  |   5 +-
 .../net/wireless/intel/iwlwifi/mvm/mac-ctxt.c |   6 +-
 .../net/wireless/intel/iwlwifi/mvm/mac80211.c |  12 ++-
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h  |   6 +-
 .../wireless/intel/iwlwifi/mvm/time-event.c   |   3 +-
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c   |  10 +-
 .../net/wireless/intel/iwlwifi/mvm/utils.c    |  32 +++++-
 .../intel/iwlwifi/pcie/gen1_2/internal.h      |   1 +
 .../intel/iwlwifi/pcie/gen1_2/trans-gen2.c    |  12 ++-
 .../intel/iwlwifi/pcie/gen1_2/trans.c         |   3 +-
 34 files changed, 367 insertions(+), 133 deletions(-)

-- 
2.34.1


^ permalink raw reply

* [PATCH wireless-next 3/3] wifi: mac80211: fix channel evacuation logic
From: Miri Korenblit @ 2026-05-27 19:51 UTC (permalink / raw)
  To: linux-wireless
In-Reply-To: <20260527195145.468037-1-miriam.rachel.korenblit@intel.com>

When we try to assign a chanctx to a link, if
ieee80211_find_or_create_chanctx() failed, we try to evacuate a NAN
channel and call it again.

This logic is broken:
In case there are not enough chanctxs we will fail earlier,
when we check ieee80211_check_combinations().

To fix this, do the following in case ieee80211_check_combinations()
failed:
- check if there is a NAN channel that can be evacuated
- make ieee80211_check_combinations() not consider the chanctx of that NAN
  channel, so we pretend that it was already evacuated
- If now ieee80211_check_combinations() is successful, we know that it
  helped, and we can remove that NAN channel for real.

Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 net/mac80211/chan.c        | 78 ++++++++++++++++++++++++++++++++------
 net/mac80211/ieee80211_i.h |  6 +++
 net/mac80211/nan.c         |  4 +-
 3 files changed, 75 insertions(+), 13 deletions(-)

diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index c64a99131954..23d46cd57137 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -2216,6 +2216,64 @@ ieee80211_find_or_create_chanctx(struct ieee80211_sub_if_data *sdata,
 				     assign_on_failure, radio_idx);
 }
 
+static bool
+ieee80211_nan_evac_chanctx_filter(struct ieee80211_chanctx *ctx,
+				  void *filter_data)
+{
+	return ctx == filter_data;
+}
+
+static int
+ieee80211_try_nan_chan_evacuation(struct ieee80211_local *local,
+				  struct ieee80211_sub_if_data *sdata,
+				  const struct cfg80211_chan_def *chandef,
+				  enum ieee80211_chanctx_mode mode,
+				  u8 radar_detect_width)
+{
+	struct ieee80211_sub_if_data *nan_sdata = ieee80211_find_nan_sdata(local);
+	struct ieee80211_check_combinations_data comb_data = {
+		.chandef = chandef,
+		.chanmode = mode,
+		.radar_detect = radar_detect_width,
+		.radio_idx = -1,
+		.chanctx_filter = ieee80211_nan_evac_chanctx_filter,
+	};
+	struct ieee80211_nan_channel *evac_chan;
+	struct ieee80211_chanctx *evac_ctx;
+	int ret;
+
+	if (!nan_sdata)
+		return -ENOENT;
+
+	/* Find an evacuation candidate... */
+	evac_chan = ieee80211_nan_find_evac_chan(local, nan_sdata, NULL);
+	if (!evac_chan || WARN_ON(!evac_chan->chanctx_conf))
+		return -ENOENT;
+
+	evac_ctx = container_of(evac_chan->chanctx_conf,
+				struct ieee80211_chanctx, conf);
+
+	/*
+	 * ... check combinations assuming to-be-evacuated ctx is already
+	 * released
+	 */
+	comb_data.filter_data = evac_ctx;
+	ret = ieee80211_check_combinations_ext(sdata, &comb_data);
+	if (ret < 0)
+		return ret;
+
+	/* That helped! Let's evacuate the channel */
+	ieee80211_nan_evacuate_channel(nan_sdata, evac_chan);
+
+	/* Re-check, just to be on the safe-side */
+	ret = ieee80211_check_combinations(sdata, chandef, mode,
+					   radar_detect_width, -1);
+
+	/* That shouldn't happen, we checked before! */
+	WARN_ON(ret);
+	return ret;
+}
+
 int _ieee80211_link_use_channel(struct ieee80211_link_data *link,
 				const struct ieee80211_chan_req *chanreq,
 				enum ieee80211_chanctx_mode mode,
@@ -2247,23 +2305,21 @@ int _ieee80211_link_use_channel(struct ieee80211_link_data *link,
 
 	ret = ieee80211_check_combinations(sdata, &chanreq->oper, mode,
 					   radar_detect_width, -1);
-	if (ret < 0)
-		goto out;
+	if (ret < 0) {
+		/* Let's check if evacuating a NAN channel will help */
+		ret = ieee80211_try_nan_chan_evacuation(local, sdata,
+							&chanreq->oper,
+							mode,
+							radar_detect_width);
+		if (ret < 0)
+			goto out;
+	}
 
 	if (!local->in_reconfig)
 		__ieee80211_link_release_channel(link, false);
 
 	ctx = ieee80211_find_or_create_chanctx(sdata, chanreq, mode,
 					       assign_on_failure, &reused_ctx);
-	if (IS_ERR(ctx)) {
-		/* Try to evacuate a NAN channel to free up a chanctx */
-		if (ieee80211_nan_try_evacuate(&local->hw, NULL))
-			ctx = ieee80211_find_or_create_chanctx(sdata, chanreq,
-							       mode,
-							       assign_on_failure,
-							       &reused_ctx);
-	}
-
 	if (IS_ERR(ctx)) {
 		ret = PTR_ERR(ctx);
 		goto out;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 29ae3004655c..99136a850fdf 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -2059,6 +2059,12 @@ int ieee80211_nan_set_peer_sched(struct ieee80211_sub_if_data *sdata,
 				 struct cfg80211_nan_peer_sched *sched);
 void ieee80211_nan_free_peer_sched(struct ieee80211_nan_peer_sched *sched);
 void ieee80211_nan_update_ndi_carrier(struct ieee80211_sub_if_data *ndi_sdata);
+struct ieee80211_nan_channel *
+ieee80211_nan_find_evac_chan(struct ieee80211_local *local,
+			     struct ieee80211_sub_if_data *sdata,
+			     struct ieee80211_chanctx *ctx);
+void ieee80211_nan_evacuate_channel(struct ieee80211_sub_if_data *sdata,
+				    struct ieee80211_nan_channel *nan_channel);
 
 static inline struct ieee80211_sub_if_data *
 ieee80211_find_nan_sdata(struct ieee80211_local *local)
diff --git a/net/mac80211/nan.c b/net/mac80211/nan.c
index 44b6e298d94d..1800bb96dd29 100644
--- a/net/mac80211/nan.c
+++ b/net/mac80211/nan.c
@@ -712,7 +712,7 @@ int ieee80211_nan_set_peer_sched(struct ieee80211_sub_if_data *sdata,
 	return ret;
 }
 
-static void
+void
 ieee80211_nan_evacuate_channel(struct ieee80211_sub_if_data *sdata,
 			       struct ieee80211_nan_channel *nan_channel)
 {
@@ -754,7 +754,7 @@ ieee80211_nan_evacuate_channel(struct ieee80211_sub_if_data *sdata,
 		ieee80211_free_chanctx(sdata->local, ctx, false);
 }
 
-static struct ieee80211_nan_channel *
+struct ieee80211_nan_channel *
 ieee80211_nan_find_evac_chan(struct ieee80211_local *local,
 			     struct ieee80211_sub_if_data *sdata,
 			     struct ieee80211_chanctx *ctx)
-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH 1/1] wifi: ath12k: support calibration-variant from device tree
From: Jeff Johnson @ 2026-05-27 19:52 UTC (permalink / raw)
  To: Andrew LaMarche, Jeff Johnson; +Cc: linux-wireless, ath12k, linux-kernel
In-Reply-To: <A2E3AAE1-1A80-4265-9497-0C95C3308CD7@gmail.com>

On 5/27/2026 9:12 AM, Andrew LaMarche wrote:
> Hi,
> 
> A kind ping here. I’m not sure why this functionality is missing in the first place, but it is needed for loading caldata from the device tree.

Your patch duplicates functionality in the Qualcomm authored series:
https://msgid.link/20250228184214.337119-1-quic_rajkbhag@quicinc.com

And note the upstream device bindings for ath10k and ath11k only support the
generic binding qcom,calibration-variant.

There are no longer any generation-specific bindings, see:
https://msgid.link/20250225-b-wifi-qcom-calibration-variant-v1-0-3b2aa3f89c53@linaro.org

/jeff

^ permalink raw reply

* [PATCH wireless-next 2/3] wifi: mac80211: refactor ieee80211_nan_try_evacuate
From: Miri Korenblit @ 2026-05-27 19:51 UTC (permalink / raw)
  To: linux-wireless
In-Reply-To: <20260527195145.468037-1-miriam.rachel.korenblit@intel.com>

Extract the logic that finds a NAN channel which makes a good evacuation
candidate into a separate function. It will be used in a later patch.

Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 net/mac80211/ieee80211_i.h | 27 +++++++++++++++----
 net/mac80211/nan.c         | 53 +++++++++++++++++++++++---------------
 2 files changed, 54 insertions(+), 26 deletions(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 1ac92e005763..29ae3004655c 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1946,6 +1946,11 @@ ieee80211_vif_get_num_mcast_if(struct ieee80211_sub_if_data *sdata)
 	return -1;
 }
 
+static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata)
+{
+	return test_bit(SDATA_STATE_RUNNING, &sdata->state);
+}
+
 int ieee80211_hw_config(struct ieee80211_local *local, int radio_idx,
 			u32 changed);
 int ieee80211_hw_conf_chan(struct ieee80211_local *local);
@@ -2055,6 +2060,23 @@ int ieee80211_nan_set_peer_sched(struct ieee80211_sub_if_data *sdata,
 void ieee80211_nan_free_peer_sched(struct ieee80211_nan_peer_sched *sched);
 void ieee80211_nan_update_ndi_carrier(struct ieee80211_sub_if_data *ndi_sdata);
 
+static inline struct ieee80211_sub_if_data *
+ieee80211_find_nan_sdata(struct ieee80211_local *local)
+{
+	struct ieee80211_sub_if_data *sdata;
+
+	lockdep_assert_wiphy(local->hw.wiphy);
+
+	/* Find the NAN interface - there can only be one */
+	list_for_each_entry(sdata, &local->interfaces, list) {
+		if (ieee80211_sdata_running(sdata) &&
+		    sdata->vif.type == NL80211_IFTYPE_NAN)
+			return sdata;
+	}
+
+	return NULL;
+}
+
 /* scan/BSS handling */
 void ieee80211_scan_work(struct wiphy *wiphy, struct wiphy_work *work);
 int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
@@ -2155,11 +2177,6 @@ void ieee80211_recalc_txpower(struct ieee80211_link_data *link,
 			      bool update_bss);
 void ieee80211_recalc_offload(struct ieee80211_local *local);
 
-static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata)
-{
-	return test_bit(SDATA_STATE_RUNNING, &sdata->state);
-}
-
 /* link handling */
 void ieee80211_link_setup(struct ieee80211_link_data *link);
 void ieee80211_link_init(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/nan.c b/net/mac80211/nan.c
index cea620aaee6a..44b6e298d94d 100644
--- a/net/mac80211/nan.c
+++ b/net/mac80211/nan.c
@@ -754,33 +754,20 @@ ieee80211_nan_evacuate_channel(struct ieee80211_sub_if_data *sdata,
 		ieee80211_free_chanctx(sdata->local, ctx, false);
 }
 
-bool ieee80211_nan_try_evacuate(struct ieee80211_hw *hw,
-				struct ieee80211_chanctx_conf *conf)
+static struct ieee80211_nan_channel *
+ieee80211_nan_find_evac_chan(struct ieee80211_local *local,
+			     struct ieee80211_sub_if_data *sdata,
+			     struct ieee80211_chanctx *ctx)
 {
-	struct ieee80211_sub_if_data *sdata = NULL, *tmp;
-	struct ieee80211_local *local = hw_to_local(hw);
-	struct ieee80211_nan_channel *evac_chan = NULL;
 	struct ieee80211_nan_sched_cfg *sched_cfg;
-	struct ieee80211_chanctx *ctx = NULL;
+	struct ieee80211_nan_channel *evac_chan = NULL;
 	int min_slot_count = INT_MAX;
 	int usable_channels = 0;
 
 	lockdep_assert_wiphy(local->hw.wiphy);
 
-	if (conf)
-		ctx = container_of(conf, struct ieee80211_chanctx, conf);
-
-	/* Find the NAN interface - there can only be one */
-	list_for_each_entry(tmp, &local->interfaces, list) {
-		if (ieee80211_sdata_running(tmp) &&
-		    tmp->vif.type == NL80211_IFTYPE_NAN) {
-			sdata = tmp;
-			break;
-		}
-	}
-
-	if (!sdata)
-		return false;
+	if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_NAN))
+		return NULL;
 
 	sched_cfg = &sdata->vif.cfg.nan_sched;
 
@@ -823,10 +810,34 @@ bool ieee80211_nan_try_evacuate(struct ieee80211_hw *hw,
 
 	/* No suitable NAN channel found */
 	if (!evac_chan)
-		return false;
+		return NULL;
 
 	/* NAN needs at least one remaining usable channel after evacuation */
 	if (usable_channels < 2)
+		return NULL;
+
+	return evac_chan;
+}
+
+bool ieee80211_nan_try_evacuate(struct ieee80211_hw *hw,
+				struct ieee80211_chanctx_conf *conf)
+{
+	struct ieee80211_local *local = hw_to_local(hw);
+	struct ieee80211_sub_if_data *sdata =
+		ieee80211_find_nan_sdata(local);
+	struct ieee80211_nan_channel *evac_chan;
+	struct ieee80211_chanctx *ctx = NULL;
+
+	lockdep_assert_wiphy(local->hw.wiphy);
+
+	if (!sdata)
+		return false;
+
+	if (conf)
+		ctx = container_of(conf, struct ieee80211_chanctx, conf);
+
+	evac_chan = ieee80211_nan_find_evac_chan(local, sdata, ctx);
+	if (!evac_chan)
 		return false;
 
 	ieee80211_nan_evacuate_channel(sdata, evac_chan);
-- 
2.34.1


^ permalink raw reply related

* [PATCH wireless-next 1/3] wifi: mac80211: add an option to filter out a channel in combinations check
From: Miri Korenblit @ 2026-05-27 19:51 UTC (permalink / raw)
  To: linux-wireless
In-Reply-To: <20260527195145.468037-1-miriam.rachel.korenblit@intel.com>

Sometimes, ieee80211_check_combinations fails, but it is hard to know
why exactly. We will have to return an array of reasons, one per
combination.

In cases where we want to check if it failed because there are not
enough chanctxs (and maybe remove one if needed), we can just not fill
in that chanctx(s) in iface_combination_params::num_different_channels
in ieee80211_fill_ifcomb_params, so that chanctx(s) won't be taken into
account.

To allow that, add an option to pass a callback to
ieee80211_fill_ifcomb_params. This callback will be called for each
chanctx we consider to count in num_different_channels and will return
whether or not this chanctx should be skipped and not counted.

This mechanism will be used later.

Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 net/mac80211/ieee80211_i.h | 34 ++++++++++++++++++++++++++++++----
 net/mac80211/util.c        | 34 +++++++++++++++++++++-------------
 2 files changed, 51 insertions(+), 17 deletions(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index fc4424b125c1..1ac92e005763 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -2818,10 +2818,36 @@ int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
 			      struct cfg80211_csa_settings *csa_settings);
 void ieee80211_recalc_sb_count(struct ieee80211_sub_if_data *sdata, u64 tsf);
 void ieee80211_recalc_dtim(struct ieee80211_sub_if_data *sdata, u64 tsf);
-int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
-				 const struct cfg80211_chan_def *chandef,
-				 enum ieee80211_chanctx_mode chanmode,
-				 u8 radar_detect, int radio_idx);
+
+struct ieee80211_check_combinations_data {
+	const struct cfg80211_chan_def *chandef;
+	enum ieee80211_chanctx_mode chanmode;
+	u8 radar_detect;
+	int radio_idx;
+	bool (*chanctx_filter)(struct ieee80211_chanctx *ctx,
+			       void *filter_data);
+	void *filter_data;
+};
+
+int ieee80211_check_combinations_ext(struct ieee80211_sub_if_data *sdata,
+				     struct ieee80211_check_combinations_data *data);
+
+static inline int
+ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
+			     const struct cfg80211_chan_def *chandef,
+			     enum ieee80211_chanctx_mode chanmode,
+			     u8 radar_detect, int radio_idx)
+{
+	struct ieee80211_check_combinations_data data = {
+		.chandef = chandef,
+		.chanmode = chanmode,
+		.radar_detect = radar_detect,
+		.radio_idx = radio_idx,
+	};
+
+	return ieee80211_check_combinations_ext(sdata, &data);
+}
+
 int ieee80211_max_num_channels(struct ieee80211_local *local, int radio_idx);
 u32 ieee80211_get_radio_mask(struct wiphy *wiphy, struct net_device *dev);
 void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local,
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 255905f971c8..2a7ab269687a 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -4260,7 +4260,10 @@ static int
 ieee80211_fill_ifcomb_params(struct ieee80211_local *local,
 			     struct iface_combination_params *params,
 			     const struct cfg80211_chan_def *chandef,
-			     struct ieee80211_sub_if_data *sdata)
+			     struct ieee80211_sub_if_data *sdata,
+			     bool (*chanctx_filter)(struct ieee80211_chanctx *ctx,
+						    void *filter_data),
+			     void *filter_data)
 {
 	struct ieee80211_sub_if_data *sdata_iter;
 	struct ieee80211_chanctx *ctx;
@@ -4281,6 +4284,10 @@ ieee80211_fill_ifcomb_params(struct ieee80211_local *local,
 		    cfg80211_chandef_compatible(chandef, &ctx->conf.def))
 			continue;
 
+		if (chanctx_filter &&
+		    chanctx_filter(ctx, filter_data))
+			continue;
+
 		params->num_different_channels++;
 	}
 
@@ -4305,26 +4312,25 @@ ieee80211_fill_ifcomb_params(struct ieee80211_local *local,
 	return total;
 }
 
-int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
-				 const struct cfg80211_chan_def *chandef,
-				 enum ieee80211_chanctx_mode chanmode,
-				 u8 radar_detect, int radio_idx)
+int ieee80211_check_combinations_ext(struct ieee80211_sub_if_data *sdata,
+				     struct ieee80211_check_combinations_data *data)
 {
-	bool shared = chanmode == IEEE80211_CHANCTX_SHARED;
+	const struct cfg80211_chan_def *chandef = data->chandef;
+	bool shared = data->chanmode == IEEE80211_CHANCTX_SHARED;
 	struct ieee80211_local *local = sdata->local;
 	enum nl80211_iftype iftype = sdata->wdev.iftype;
 	struct iface_combination_params params = {
-		.radar_detect = radar_detect,
-		.radio_idx = radio_idx,
+		.radar_detect = data->radar_detect,
+		.radio_idx = data->radio_idx,
 	};
 	int total;
 
 	lockdep_assert_wiphy(local->hw.wiphy);
 
-	if (WARN_ON(hweight32(radar_detect) > 1))
+	if (WARN_ON(hweight32(data->radar_detect) > 1))
 		return -EINVAL;
 
-	if (WARN_ON(chandef && chanmode == IEEE80211_CHANCTX_SHARED &&
+	if (WARN_ON(chandef && data->chanmode == IEEE80211_CHANCTX_SHARED &&
 		    !chandef->chan))
 		return -EINVAL;
 
@@ -4343,7 +4349,7 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
 
 	/* Always allow software iftypes */
 	if (cfg80211_iftype_allowed(local->hw.wiphy, iftype, 0, 1)) {
-		if (radar_detect)
+		if (data->radar_detect)
 			return -EINVAL;
 		return 0;
 	}
@@ -4356,7 +4362,9 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
 
 	total = ieee80211_fill_ifcomb_params(local, &params,
 					     shared ? chandef : NULL,
-					     sdata);
+					     sdata,
+					     data->chanctx_filter,
+					     data->filter_data);
 	if (total == 1 && !params.radar_detect)
 		return 0;
 
@@ -4383,7 +4391,7 @@ int ieee80211_max_num_channels(struct ieee80211_local *local, int radio_idx)
 
 	lockdep_assert_wiphy(local->hw.wiphy);
 
-	ieee80211_fill_ifcomb_params(local, &params, NULL, NULL);
+	ieee80211_fill_ifcomb_params(local, &params, NULL, NULL, NULL, NULL);
 
 	err = cfg80211_iter_combinations(local->hw.wiphy, &params,
 					 ieee80211_iter_max_chans,
-- 
2.34.1


^ permalink raw reply related

* [PATCH wireless-next 0/3] wifi: mac80211: fix channel evacuation logic
From: Miri Korenblit @ 2026-05-27 19:51 UTC (permalink / raw)
  To: linux-wireless

This series is fixing the channel evacuation logic: in case we are
missing a chanctx for example for a BSS, we will fail the combination
check.
OTOH, we don't want to evacuate a NAN channel and then find out that
there are other things that prevent this BSS channel.
This series adds an option to ingore one of the exitsing channel
contexts in the combination check (the one we want to evacuate) to make
sure that all other conditions meet for adding the new BSS channel.
In that case, we will evacuate the NAN channel.

Miri Korenblit (3):
  wifi: mac80211: add an option to filter out a channel in combinations
    check
  wifi: mac80211: refactor ieee80211_nan_try_evacuate
  wifi: mac80211: fix channel evacuation logic

 net/mac80211/chan.c        | 78 ++++++++++++++++++++++++++++++++------
 net/mac80211/ieee80211_i.h | 67 +++++++++++++++++++++++++++-----
 net/mac80211/nan.c         | 55 ++++++++++++++++-----------
 net/mac80211/util.c        | 34 ++++++++++-------
 4 files changed, 179 insertions(+), 55 deletions(-)

-- 
2.34.1


^ permalink raw reply

* [PATCH wireless-next] wifi: mac80211_hwsim: add debug messages for link changes
From: Miri Korenblit @ 2026-05-27 19:42 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg, Benjamin Berg

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

It's useful to be able to see the link addresses when the
interface links change, so add some prints to hwsim for the
vif link change callback.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Reviewed-by: Benjamin Berg <benjamin.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 drivers/net/wireless/virtual/mac80211_hwsim_main.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/virtual/mac80211_hwsim_main.c b/drivers/net/wireless/virtual/mac80211_hwsim_main.c
index 67a33e5e7d54..af9b0d957ad0 100644
--- a/drivers/net/wireless/virtual/mac80211_hwsim_main.c
+++ b/drivers/net/wireless/virtual/mac80211_hwsim_main.c
@@ -3505,8 +3505,13 @@ static int mac80211_hwsim_change_vif_links(struct ieee80211_hw *hw,
 	if (!new_links)
 		add |= BIT(0);
 
-	for_each_set_bit(i, &rem, IEEE80211_MLD_MAX_NUM_LINKS)
+	wiphy_dbg(hw->wiphy, "%s:\n", __func__);
+
+	for_each_set_bit(i, &rem, IEEE80211_MLD_MAX_NUM_LINKS) {
 		mac80211_hwsim_config_mac_nl(hw, old[i]->addr, false);
+		wiphy_dbg(hw->wiphy,
+			  "  link [%d/%pM] removed\n", i, old[i]->addr);
+	}
 
 	for_each_set_bit(i, &add, IEEE80211_MLD_MAX_NUM_LINKS) {
 		struct ieee80211_bss_conf *link_conf;
@@ -3516,6 +3521,8 @@ static int mac80211_hwsim_change_vif_links(struct ieee80211_hw *hw,
 			continue;
 
 		mac80211_hwsim_config_mac_nl(hw, link_conf->addr, true);
+		wiphy_dbg(hw->wiphy,
+			  "  link [%d/%pM] added\n", i, link_conf->addr);
 	}
 
 	return 0;
-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH mt76] wifi: mt76: mt7915: configure noise floor reporting on reset
From: David Bauer @ 2026-05-27 17:05 UTC (permalink / raw)
  To: Felix Fietkau, Lorenzo Bianconi, Ryder Lee, Shayne Chen,
	Sean Wang, Matthias Brugger, AngeloGioacchino Del Regno
  Cc: linux-wireless, linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <a83c9aca-da9e-4a5e-a364-382910388a68@nbd.name>

Hi Felix,

On 5/27/26 15:56, Felix Fietkau wrote:
> On 16.05.26 16:49, David Bauer wrote:
>> When performing a full system recovery of the MCU on a dual-phy
>> platform, band 0 (usually 2.4GHz) stops reading correct noise floor
>> data.
>>
>> This is due to noise floor reporting only being configured correctly
>> for the second device PHY.
>>
>> Configure the respective registers correctly after restarting the MCU
>> firmware to fix reported noise-floor values.
>>
>> Signed-off-by: David Bauer <mail@david-bauer.net>
> Have you considered clearing MT76_STATE_RUNNING in mt7915_mac_restart instead?

The call to mt7915_run is guarded by MT76_STATE_RUNNING being set per-phy.

I think this is to not start the second PHY in case it was never started due to
it not being present. We could in theory remove this check for the primary PHY
and clear the flag prior calling mt7915_run.

This seems a bit more hacky to me. Alternatively I can also refactor the entire
mechanism to make it easier to understand and resolve this indirection in the
process.

What do you think?

Best
David

> 
> - Felix


^ permalink raw reply

* Re: [PATCH v2] wireless-regdb: allow 320MHz channel width for Russia
From: Ilya K @ 2026-05-27 16:47 UTC (permalink / raw)
  To: Chen-Yu Tsai; +Cc: linux-wireless, wireless-regdb, Louis Kotze
In-Reply-To: <177751439231.3356117.7542785326182742344.b4-ty@kernel.org>

> 
> Applied to master in wens/wireless-regdb.git, thanks!
> 
> [1/1] wireless-regdb: allow 320MHz channel width for Russia
>       https://git.kernel.org/wens/wireless-regdb/c/62d72c287e99
> 
Hi, can we get a signed tag with this included?

^ permalink raw reply

* Re: [patch 05/24] KVM: arm64: Use ktime_get_snapshot_id() to retrieve CLOCK_BOOTTIME
From: Vincent Donnefort @ 2026-05-27 16:28 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, David Woodhouse, Miroslav Lichvar, John Stultz,
	Stephen Boyd, Anna-Maria Behnsen, Frederic Weisbecker,
	thomas.weissschuh, Arthur Kiyanovski, Marc Zyngier, Oliver Upton,
	kvmarm, Rodolfo Giometti, 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
In-Reply-To: <20260526171223.070087856@kernel.org>

On Tue, May 26, 2026 at 07:13:53PM +0200, Thomas Gleixner wrote:
> ktime_get_snapshot() is replaced by ktime_get_snapshot_id() which allows to
> request a particular CLOCK ID to be captured along with the clocksource
> counter.
> 
> Convert the tracing mechanism over and use the new
> system_time_snapshot::sys field, which holds the system timestamp selected
> by the CLOCK ID argument.
> 
> No functional change intended.
> 
> Signed-off-by: Thomas Gleixner <tglx@kernel.org>
> Cc: Vincent Donnefort <vdonnefort@google.com>
> Cc: Marc Zyngier <maz@kernel.org>
> Cc: Oliver Upton <oliver.upton@linux.dev>
> Cc: kvmarm@lists.linux.dev

Acked-by: Vincent Donnefort <vdonnefort@google.com>

> ---
>  arch/arm64/kvm/hyp_trace.c |    8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> --- a/arch/arm64/kvm/hyp_trace.c
> +++ b/arch/arm64/kvm/hyp_trace.c
> @@ -51,8 +51,8 @@ static void __hyp_clock_work(struct work
>  
>  	hyp_clock = container_of(dwork, struct hyp_trace_clock, work);
>  
> -	ktime_get_snapshot(&snap);
> -	boot = ktime_to_ns(snap.boot);
> +	ktime_get_snapshot_id(&snap, CLOCK_BOOTTIME);
> +	boot = ktime_to_ns(snap.sys);
>  
>  	delta_boot = boot - hyp_clock->boot;
>  	delta_cycles = snap.cycles - hyp_clock->cycles;
> @@ -118,9 +118,9 @@ static void hyp_trace_clock_enable(struc
>  		hyp_clock->running = false;
>  	}
>  
> -	ktime_get_snapshot(&snap);
> +	ktime_get_snapshot_id(&snap, CLOCK_BOOTTIME);
>  
> -	hyp_clock->boot = ktime_to_ns(snap.boot);
> +	hyp_clock->boot = ktime_to_ns(snap.sys);
>  	hyp_clock->cycles = snap.cycles;
>  	hyp_clock->mult = 0;
>  
> 

^ permalink raw reply

* Re: [PATCH 1/1] wifi: ath12k: support calibration-variant from device tree
From: Andrew LaMarche @ 2026-05-27 16:12 UTC (permalink / raw)
  To: Jeff Johnson; +Cc: linux-wireless, ath12k, linux-kernel
In-Reply-To: <20260131003222.2011259-1-andrewjlamarche@gmail.com>

Hi,

A kind ping here. I’m not sure why this functionality is missing in the first place, but it is needed for loading caldata from the device tree.

Cheers,
Andrew

> On Jan 30, 2026, at 7:32 PM, Andrew LaMarche <andrewjlamarche@gmail.com> wrote:
> 
> ath10k and ath11k support reading calibration variants from the device
> tree to locate the correct Board Description File (BDF). The ath12k-wsi
> binding already describes using qcom,calibration-variant and
> qcom,ath12k-calibration-variant, but it is not implemented in the code.
> 
> Many ath12k designs expose all the radios under a single phy, each of
> which typically require a separate BDF. Without this, the radios may not
> come up or will not be calibrated correctly.
> 
> Fix this by parsing the device tree for the generation-agnostic
> qcom,calibration-variant node or ath12k-specific
> qcom,ath12k-calibration-variant node. This allows the driver to properly
> select, read and apply the correct BDF.
> 
> Signed-off-by: Andrew LaMarche <andrewjlamarche@gmail.com>
> ---
> drivers/net/wireless/ath/ath12k/core.c | 25 +++++++++++++++++++++++++
> drivers/net/wireless/ath/ath12k/core.h |  2 +-
> drivers/net/wireless/ath/ath12k/qmi.c  |  4 ++++
> 3 files changed, 30 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
> index cc352eef1939..e45f76d81337 100644
> --- a/drivers/net/wireless/ath/ath12k/core.c
> +++ b/drivers/net/wireless/ath/ath12k/core.c
> @@ -806,6 +806,31 @@ int ath12k_core_check_smbios(struct ath12k_base *ab)
> 	return 0;
> }
> 
> +int ath12k_core_check_dt(struct ath12k_base *ab)
> +{
> +	size_t max_len = sizeof(ab->qmi.target.bdf_ext);
> +	const char *variant = NULL;
> +	struct device_node *node;
> +
> +	node = ab->dev->of_node;
> +	if (!node)
> +		return -ENOENT;
> +
> +	of_property_read_string(node, "qcom,calibration-variant",
> +			&variant);
> +	if (!variant)
> +		of_property_read_string(node, "qcom,ath12k-calibration-variant",
> +				&variant);
> +	if (!variant)
> +		return -ENODATA;
> +
> +	if (strscpy(ab->qmi.target.bdf_ext, variant, max_len) < 0)
> +		ath12k_dbg(ab, ATH12K_DBG_BOOT,
> +				"bdf variant string is longer than the buffer can accommodate (variant: %s)\n", variant);
> +
> +	return 0;
> +}
> +
> static int ath12k_core_soc_create(struct ath12k_base *ab)
> {
> 	int ret;
> diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h
> index 3c1e0069be1e..39700a780ee2 100644
> --- a/drivers/net/wireless/ath/ath12k/core.h
> +++ b/drivers/net/wireless/ath/ath12k/core.h
> @@ -1352,7 +1352,7 @@ int ath12k_core_fetch_bdf(struct ath12k_base *ath12k,
> 			  struct ath12k_board_data *bd);
> void ath12k_core_free_bdf(struct ath12k_base *ab, struct ath12k_board_data *bd);
> int ath12k_core_fetch_regdb(struct ath12k_base *ab, struct ath12k_board_data *bd);
> -int ath12k_core_check_dt(struct ath12k_base *ath12k);
> +int ath12k_core_check_dt(struct ath12k_base *ab);
> int ath12k_core_check_smbios(struct ath12k_base *ab);
> void ath12k_core_halt(struct ath12k *ar);
> int ath12k_core_resume_early(struct ath12k_base *ab);
> diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c
> index b7c48b6706df..22ef5aab871f 100644
> --- a/drivers/net/wireless/ath/ath12k/qmi.c
> +++ b/drivers/net/wireless/ath/ath12k/qmi.c
> @@ -2903,6 +2903,10 @@ int ath12k_qmi_request_target_cap(struct ath12k_base *ab)
> 	if (r)
> 		ath12k_dbg(ab, ATH12K_DBG_QMI, "SMBIOS bdf variant name not set.\n");
> 
> +	r = ath12k_core_check_dt(ab);
> +	if (r)
> +		ath12k_dbg(ab, ATH12K_DBG_QMI, "DT bdf variant name not set.\n");
> +
> 	r = ath12k_acpi_start(ab);
> 	if (r)
> 		/* ACPI is optional so continue in case of an error */
> -- 
> 2.43.0
> 


^ permalink raw reply

* Re: [patch 04/24] pps: Convert to ktime_get_snapshot_id()
From: Thomas Gleixner @ 2026-05-27 16:02 UTC (permalink / raw)
  To: Thomas Weißschuh
  Cc: LKML, David Woodhouse, Miroslav Lichvar, John Stultz,
	Stephen Boyd, Anna-Maria Behnsen, Frederic Weisbecker,
	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
In-Reply-To: <20260527090114-359e2553-2c63-4ac2-a15a-776ba08b6eec@linutronix.de>

On Wed, May 27 2026 at 09:02, Thomas Weißschuh wrote:
> On Tue, May 26, 2026 at 07:13:48PM +0200, Thomas Gleixner wrote:
>>  static inline void pps_get_ts(struct pps_event_time *ts)
>>  {
>> +#ifdef CONFIG_NTP_PPS
>
> IS_ENABLED()?

ts->ts_raw is #ifdeffed out then, which would make the build fail :(


^ permalink raw reply

* Re: [patch 01/24] timekeeping: Provide ktime_get_snapshot_id()
From: Thomas Gleixner @ 2026-05-27 15:58 UTC (permalink / raw)
  To: Jacob Keller, LKML
  Cc: David Woodhouse, 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, Tony Nguyen,
	Saeed Mahameed, Peter Hilber, Michael S. Tsirkin, virtualization,
	linux-wireless, linux-sound
In-Reply-To: <5b082d25-9a57-4612-a93e-a4591acd0ea6@intel.com>

On Tue, May 26 2026 at 14:41, Jacob Keller wrote:
> On 5/26/2026 10:13 AM, Thomas Gleixner wrote:
>> -void ktime_get_snapshot(struct system_time_snapshot *systime_snapshot)
>> +bool ktime_get_snapshot_id(struct system_time_snapshot *systime_snapshot, clockid_t clock_id)
>>  {
>
> Since this function now returns a bool would it make sense to add a
> "Return:" comment to the kdoc to help explain what the return value means?
>
> I saw that you have a WARN_ON with the ktime_get_snapshot wrapper. I
> guess it returns false if timekeeping_suspended.

...

> This warns here, and the wrapper ktime_get_snapshot also warns. Does
> that make sense? I guess eventually the ktime_get_snapshot will be removed?

No it does not and it's a leftover from an early version. I later
switched to have a valid bit in the struct because otherwise I'd need to
modify a gazillion call sites to propagate the return value through.

Let me remove it.

Thanks,

        tglx

^ permalink raw reply

* [PATCH wireless-next v2] wifi: mt76: mt7925: add Netgear A8500 USB device ID
From: Devin Wittmayer @ 2026-05-27 14:47 UTC (permalink / raw)
  To: linux-wireless
  Cc: Felix Fietkau, Lorenzo Bianconi, Sean Wang, Ryder Lee,
	linux-mediatek, Nick Morrow, Devin Wittmayer
In-Reply-To: <20260326190346.415226-1-lucid_duck@justthetip.ca>

Add USB device ID for the Netgear A8500 (0846:9050) which uses
the mt7925 chipset.

Signed-off-by: Devin Wittmayer <lucid_duck@justthetip.ca>
---
Changes in v2 (Sean Wang):
- Drop the Cc: stable tag.
- Use full name in Signed-off-by.

v1: https://lore.kernel.org/linux-wireless/20260326190346.415226-1-lucid_duck@justthetip.ca/
---
 drivers/net/wireless/mediatek/mt76/mt7925/usb.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/usb.c b/drivers/net/wireless/mediatek/mt76/mt7925/usb.c
index d9968f03856d..e44f0cafde01 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/usb.c
@@ -12,6 +12,9 @@
 static const struct usb_device_id mt7925u_device_table[] = {
 	{ USB_DEVICE_AND_INTERFACE_INFO(0x0e8d, 0x7925, 0xff, 0xff, 0xff),
 		.driver_info = (kernel_ulong_t)MT7925_FIRMWARE_WM },
+	/* Netgear, Inc. A8500 */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9050, 0xff, 0xff, 0xff),
+		.driver_info = (kernel_ulong_t)MT7925_FIRMWARE_WM },
 	/* Netgear, Inc. A9000 */
 	{ USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9072, 0xff, 0xff, 0xff),
 		.driver_info = (kernel_ulong_t)MT7925_FIRMWARE_WM },
-- 
2.54.0


^ permalink raw reply related

* Re: [PATCH mt76] wifi: mt76: mt7915: configure noise floor reporting on reset
From: Felix Fietkau @ 2026-05-27 13:56 UTC (permalink / raw)
  To: David Bauer, Lorenzo Bianconi, Ryder Lee, Shayne Chen, Sean Wang,
	Matthias Brugger, AngeloGioacchino Del Regno
  Cc: linux-wireless, linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <20260516144944.2574053-1-mail@david-bauer.net>

On 16.05.26 16:49, David Bauer wrote:
> When performing a full system recovery of the MCU on a dual-phy
> platform, band 0 (usually 2.4GHz) stops reading correct noise floor
> data.
> 
> This is due to noise floor reporting only being configured correctly
> for the second device PHY.
> 
> Configure the respective registers correctly after restarting the MCU
> firmware to fix reported noise-floor values.
> 
> Signed-off-by: David Bauer <mail@david-bauer.net>
Have you considered clearing MT76_STATE_RUNNING in mt7915_mac_restart 
instead?

- Felix

^ permalink raw reply

* [PATCH wireless-next] wifi: nl80211: re-check wiphy netns in testmode and vendor dump continuations
From: Maoyi Xie @ 2026-05-27 13:33 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, linux-kernel, Maoyi Xie

Commit 79240f3f6d76 ("wifi: nl80211: re-check wiphy netns in
nl80211_prepare_wdev_dump() continuation") fixed one dumpit path that
looked the wiphy up by index on a later call without confirming it was
still in the caller's netns. Two more dumpit paths have the same gap.

nl80211_testmode_dump() and nl80211_prepare_vendor_dump() both keep the
wiphy index in cb->args[] and look it up again on later calls, through
cfg80211_rdev_by_wiphy_idx() and wiphy_idx_to_wiphy(). The first call
binds to the caller's netns. A later call does not check it again. In
between, the wiphy can move to another netns via
NL80211_CMD_SET_WIPHY_NETNS.

Add the same net_eq() check to both. On a mismatch, return -ENODEV and
the dump ends.

No mainline driver registers .testmode_dump or
wiphy_vendor_command.dumpit, so these paths are not reachable today.
Drivers outside the tree can register either.

Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com>
---
 net/wireless/nl80211.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index f334cdef8958..d462e0b784ad 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -13420,6 +13420,16 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
 			err = -ENOENT;
 			goto out_err;
 		}
+
+		/*
+		 * The wiphy may have moved netns between dumpit
+		 * invocations (via NL80211_CMD_SET_WIPHY_NETNS), so
+		 * re-check that it still matches the caller's netns.
+		 */
+		if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk))) {
+			err = -ENODEV;
+			goto out_err;
+		}
 	} else {
 		attrbuf = kzalloc_objs(*attrbuf, NUM_NL80211_ATTR);
 		if (!attrbuf) {
@@ -17382,6 +17392,15 @@ static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
 
 		if (!wiphy)
 			return -ENODEV;
+
+		/*
+		 * The wiphy may have moved netns between dumpit
+		 * invocations (via NL80211_CMD_SET_WIPHY_NETNS), so
+		 * re-check that it still matches the caller's netns.
+		 */
+		if (!net_eq(wiphy_net(wiphy), sock_net(skb->sk)))
+			return -ENODEV;
+
 		*rdev = wiphy_to_rdev(wiphy);
 		*wdev = NULL;
 
-- 
2.34.1


^ permalink raw reply related

* Re: [patch 24/24] ptp: Switch to ktime_get_snapshot_id() for pre/post timestamps
From: Vadim Fedorenko @ 2026-05-27 13:10 UTC (permalink / raw)
  To: Thomas Gleixner, LKML
  Cc: David Woodhouse, 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
In-Reply-To: <20260526171224.499777655@kernel.org>

On 26/05/2026 18:15, Thomas Gleixner wrote:
> To prepare for a new PTP IOCTL, which exposes the raw counter value along
> with the requested system time snapshot, switch the pre/post time stamp
> sampling over to use ktime_get_snapshot_id() and fix up all usage sites.
> 
> No functional change intended.
> 
> The ptp_vmclock conversion was simplified by David Woodhouse.
> 
> Signed-off-by: Thomas Gleixner <tglx@kernel.org>

for ptp_ocp:
Acked-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>

^ permalink raw reply

* [PATCH] iw: fix broken links in README and iw.8
From: kawacoder @ 2026-05-27 13:02 UTC (permalink / raw)
  To: johannes_at_sipsolutions.net_kawacoder@duck.com
  Cc: linux-wireless_at_vger.kernel.org_kawacoder@duck.com

From 69851144ea8689b77379fbe2598a379564a7bb59 Mon Sep 17 00:00:00 2001
From: kawacoder <kawacoder@duck.com>
Date: Wed, 27 May 2026 12:05:22 +0200
Subject: [PATCH] iw: fix broken link in README and iw.8

Fixes a broken URL (404 error code) in the README and iw.8 that pointed to https://wireless.wiki.kernel.org/en/users/Documentation/iw. The new URL points to https://wireless.wiki.kernel.org/en/users/docume
ntation/iw

Signed-off-by: kawacoder <kawacoder@duck.com>
---
README | 2 +-
iw.8   | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/README b/README
index 113bf38..41b1613 100644
--- a/README
+++ b/README
@@ -9,7 +9,7 @@ to find libnl.
 
'iw' is currently maintained at http://git.sipsolutions.net/iw.git/,
some more documentation is available at
-https://wireless.wiki.kernel.org/en/users/Documentation/iw
+https://wireless.wiki.kernel.org/en/users/documentation/iw
 
Please send all patches to Johannes Berg <johannes@sipsolutions.net>
and CC linux-wireless@vger.kernel.org for community review.
diff --git a/iw.8 b/iw.8
index 4ae55b8..cec26f2 100644
--- a/iw.8
+++ b/iw.8
@@ -70,6 +70,6 @@ will print the help for all matching commands.
.BR regulatory.bin (5).
.
.P
-.UR https://wireless.wiki.kernel.org/en/users/Documentation/iw
+.UR https://wireless.wiki.kernel.org/en/users/documentation/iw
Documentation at kernel wiki
.UE .
--  
2.54.0


^ permalink raw reply related

* [bug report] wifi: mt76: mt7921: mt7925monitor-mode per-channel retune emits narrowband RF burst
From: John Henry @ 2026-05-27 12:24 UTC (permalink / raw)
  To: Javier Tia, Bradley Pizzimenti, linux-wireless, linux-kernel, nbd,
	lorenzo, ryder.lee, shayne.chen, sean.wang,
	moderated list:ARM/Mediatek SoC support, Deren Wu, Nick Morrow,
	Sean Wang

Just a kind reminder of this issue.

Please advise if this is already taken up in a separate issue I am
unaware of, but it is not directly related to the "iw set txpower
fixed accepted but ignored" issue.

On products available in the market, e.g.  the Alfa AWUS036AXML
consumer product and the Netgear Nighthawk A9000, in Monitor Mode
there is RF generated when scanning through channels and we get to 5
or more channels in succession.
This does not seem to occur at all in managed mode.

This means if we scan the 2.4GHz channel list, an RF Spectrum analyzer
will show a narrow pulse generated on each channel as we progress
through the channels.
This can 100% be reproduced using standard iw set channel commands as
shown below:
FACE=$(iw dev | awk '/Interface wl/ {print $2; exit}')
iw reg set US ; sleep 1
ip link set "$IFACE" down
iw dev "$IFACE" set type monitor
ip link set "$IFACE" up

# This triggers narrowband bursts at channel center on each retune:
while true; do
  for f in 2412 2417 2422 2427 2432; do
    iw dev "$IFACE" set freq "$f" HT20
  done
done

No special software required to reproduce.
I have shown that this occurs on all MT7921 based products, along with
MT7925 based products.
It does not occur if the channel list is set to the same 4 over and
over, no RF generated.

There are no calibration channel commands going from the driver to the
firmware, so I believe this is a firmware bug.

Best Regards,
John Henry

On Sun, May 17, 2026 at 9:01 AM John Henry <jshenry1963@gmail.com> wrote:
>
> Just a kind reminder of this issue, has anyone been able to reproduce
> this monitor mode issue?
> When scanning through channels, and the list of channels is > 4, there
> is a large transmit tick/burst coming from the MT7921u and the MT7925.
> This can easily be seen on an RF Spectrum Analyzer.
> Confirmed on an Alfa AWUS036AXML consumer product and the Netgear
> Nighthawk A9000.
> This can be reproduced with simple scripts.
>
> Reproduction with stock iw commands (no custom code):
>
> IFACE=$(iw dev | awk '/Interface wl/ {print $2; exit}')
> iw reg set US ; sleep 1
> ip link set "$IFACE" down
> iw dev "$IFACE" set type monitor
> ip link set "$IFACE" up
>
> # This triggers narrowband bursts at channel center on each retune:
> while true; do
>   for f in 2412 2417 2422 2427 2432; do
>     iw dev "$IFACE" set freq "$f" HT20
>   done
> done
>
> # This does NOT (only 4 frequencies):
> while true; do
>   for f in 2412 2422 2462 2484; do
>     iw dev "$IFACE" set freq "$f" HT20
>   done
> done
>
> Bursts are ~800 kHz wide at the base, -30 to -50 dBm OTA at close
> range, brief (estimated few hundred microseconds), at channel
> frequency. tx_stats counters remain zero throughout.
> On Mon, May 11, 2026 at 1:58 PM John Henry <jshenry1963@gmail.com> wrote:
> >
> > Bradley/Sean,
> >
> > Thank you all very much for the information.
> > I tested this on mt7921u based Alfa AWUS unit and also an mt7925 based
> > Netgear Nighthawk unit.
> > I can confirm that the RF tick issue is present on both models when in
> > Monitor Mode. I'm assuming it is in the base mt76?
> >
> > I attempted sudo iw dev wlxxx set txpower fixed nn where nn is the
> > minimum value, next few values up, and then a few near the max values,
> > and see no change in the signal strength of the RF Ticks when scanning
> > through 5 or more channels.
> >
> > Please keep this in mind when attempting to resolve the known txpower
> > 3dBm issue if possible, or please generate a new bug report for that
> > specifically so that I can track when it is patched, or in ??? version
> > so that I can test here locally.
> >
> > Incidentally, I'd appreciate it if anyone could please attempt to
> > repeat using the scripts I had shown in the previous posts and confirm
> > it is indeed seen by others.
> >
> > Thank you very much for your time and assistance
> >
> > John Henry
> >
> >
> >
> >
> > From: Bradley Pizzimenti <brad.pizzimenti@gmail.com>
> > To: linux-wireless@vger.kernel.org
> > Cc: linux-kernel@vger.kernel.org, nbd@nbd.name, lorenzo@kernel.org,
> > ryder.lee@mediatek.com, shayne.chen@mediatek.com,
> > sean.wang@mediatek.com
> > Subject: [bug report] wifi: mt76: mt7925: iw set txpower fixed
> > accepted but ignored
> > Date: Mon, 4 May 2026 15:04:35 -0700 [thread overview]
> > Message-ID: <CACjnFagN9zeSkwEv3-CSPJDUENPcEcOLjKyQoLQ91Yjn=rq5ww@mail.gmail.com>
> > (raw)
> >
> > Hi there maintainers,
> >
> > `iw dev <iface> set txpower fixed N` returns success on mt7925 for any
> > N tested, but the reported txpower never changes from a stuck value of
> > 3.00 dBm. The kernel accepts and ignores the call silently in both
> > directions (above and below the displayed value), and well below the
> > regulatory ceiling.
> >
> > I'm aware there's prior art on the cosmetic 3.00 dBm display issue
> > (Razvan Grigore's v2 series, Feb 2025; Ming Yen Hsieh's txpower init
> > refactor, Sept 2025). What seems potentially distinct here is that the
> > user-issued `iw set txpower fixed N` itself is silently no-op'd,
> > separate from the reported-value question. Reporting as breadcrumbs
> > in case the second observation is a separate bug rather than the same
> > one.
> >
> > Hardware
> > --------
> > MEDIATEK MT7925 [Filogic 360], 802.11be 2x2, PCI 14c3:7925
> > ASIC revision 0x79250000
> > Driver in use: mt7925e (in-tree)
> >
> > Firmware (from dmesg at probe)
> > ------------------------------
> > mt7925e 0000:01:00.0: HW/SW Version: 0x8a108a10,
> >                      Build Time: 20260106153007a
> > mt7925e 0000:01:00.0: WM Firmware Version: ____000000,
> >                      Build Time: 20260106153120
> > Files: mediatek/mt7925/WIFI_MT7925_PATCH_MCU_1_1_hdr.bin
> >        mediatek/mt7925/WIFI_RAM_CODE_MT7925_1_1.bin
> >
> > Kernel
> > ------
> > 6.18.18-1-MANJARO (close to vanilla 6.18 stable; not yet tested on
> > wireless-next or nbd168/wireless HEAD -- happy to retest if needed,
> > but flagging the data point in case it helps as-is).
> >
> > Tools: iw version 6.17
> >
> > Regulatory
> > ----------
> > $ iw reg get
> > country US: DFS-FCC
> >    ...
> >    (5730 - 5850 @ 80), (N/A, 30), (N/A), AUTO-BW
> >    ...
> >
> > Connection context: 5GHz channel 161 (5805 MHz), 80 MHz, VHT-MCS,
> > NSS 1. So we are on a band with a 30 dBm regulatory cap.
> >
> > Observed
> > --------
> > $ iw dev wlp1s0 info | grep txpower
> >         txpower 3.00 dBm
> >
> > $ sudo iw dev wlp1s0 set txpower fixed 100   # 1 dBm
> > $ iw dev wlp1s0 info | grep txpower
> >         txpower 3.00 dBm
> >
> > $ sudo iw dev wlp1s0 set txpower fixed 1500  # 15 dBm
> > $ iw dev wlp1s0 info | grep txpower
> >         txpower 3.00 dBm
> >
> > $ sudo iw dev wlp1s0 set txpower auto
> > $ iw dev wlp1s0 info | grep txpower
> >         txpower 3.00 dBm
> >
> > All four `set` invocations return exit code 0. The reported value
> > never moves.
> >
> > Expected
> > --------
> > Either:
> >   - The reported txpower follows the requested value (or, where
> >     capped, the actual applied value with extack indicating the
> >     cap reason), or
> >   - The set call returns an error rather than silently ignoring the
> >     request.
> >
> > Caveats
> > -------
> > - Not yet tested on wireless-next or nbd168/wireless HEAD. If a
> >   reproduction on a current dev tree would be useful, I can do that.
> > - I have not verified whether the actual radiated TX power changes
> >   in response to `set txpower fixed`; I am reporting only the
> >   user-visible behavior.
> >
> > Thanks,
> > Bradley
> >
> > On Wed, May 6, 2026 at 8:12 PM Sean Wang <sean.wang@kernel.org> wrote:
> > >
> > > Hi,
> > >
> > > The TX power reporting issue has already been investigated by Lucid
> > > from the Linux WiFi USB community, and there is a proposed solution.
> > > I think we can continue checking whether there are any remaining
> > > issues on top of that work. Please refer to the patches here:
> > > https://lists.infradead.org/pipermail/linux-mediatek/2026-April/105726.html
> > > Thanks everyone for reporting and raising these concerns.
> > >
> > > On Wed, May 6, 2026 at 3:09 PM Javier Tia <floss@jetm.me> wrote:
> > > >
> > > > On Sun May  4 22:04:48 2026 Bradley Pizzimenti wrote:
> > > > > `iw dev <iface> set txpower fixed N` returns success on mt7925 for
> > > > > any N tested, but the reported txpower never changes from a stuck
> > > > > value of 3.00 dBm.
> > > >
> > > > Hi Bradley,
> > > >
> > > > The 3 dBm display bug is a known issue we have seen when using mt7927
> > > > and a tested fix has been working well so far. The root cause is that
> > > > mt7925_mcu_set_rate_txpower() programs the per-band SKU tables into
> > > > firmware but never assigns phy->txpower_cur. mt76_get_txpower() then
> > > > computes:
> > > >
> > > >   DIV_ROUND_UP(0 + 6, 2) = 3
> > > >
> > > > regardless of the actual power level. The RF output is unaffected;
> > > > it is a display-only bug.
> > > >
> > > > The fix reads the effective TX power back from the rate power limits
> > > > after programming the SKU tables and writes it to phy->txpower_cur,
> > > > following the same pattern used by mt7996:
> > > >
> > > >   https://github.com/jetm/mediatek-mt7927-dkms/blob/master/mt7927-wifi-14-fix-reported-txpower-always-showing-3-db.patch
> > > >
> > > > This is part of a series we are targeting for wireless-next; not
> > > > yet upstream.
> > > >
> > > > > What seems potentially distinct here is that the user-issued
> > > > > `iw set txpower fixed N` itself is silently no-op'd, separate
> > > > > from the reported-value question.
> > > >
> > > > Agreed those are two separate issues. Our patch addresses the
> > > > display-only side: after applying it, iw will report the value the
> > > > firmware is actually using based on the SKU tables, rather than
> > > > always 3 dBm. Whether `set txpower fixed N` propagates to firmware
> > > > to change actual output power is orthogonal and not addressed here.
> > > >
> > > > If you can test the patch on your MT7925 and confirm the displayed
> > > > value reflects the correct power after association, a Tested-by
> > > > would be appreciated.
> > > >
> > > > Best,
> > > > Javier
> > > >
> > >

^ permalink raw reply

* RE: [PATCH v2 rtw-next 1/2] wifi: rtw89: add dev_id_quirks to driver_info for per-device quirk control
From: Johnson Tsai @ 2026-05-27 11:48 UTC (permalink / raw)
  To: Ping-Ke Shih, Greg KH
  Cc: linux-wireless@vger.kernel.org, driver-core@lists.linux.dev,
	johannes@sipsolutions.net, Mh_chen, charlesl@valvesoftware.com,
	sabae@valvesoftware.com
In-Reply-To: <1f68b31265984b4e9e4be7872fe516d5@realtek.com>


On Tuesday, May 26, 2026 9:10, Ping-Ke Shih wrote:
> Greg KH <gregkh@linuxfoundation.org> wrote:
> > On Mon, May 25, 2026 at 04:51:47PM +0800, Ping-Ke Shih wrote:
> > > --- a/drivers/net/wireless/realtek/rtw89/rtw8851be.c
> > > +++ b/drivers/net/wireless/realtek/rtw89/rtw8851be.c
> > > @@ -73,6 +73,7 @@ static const struct rtw89_driver_info
> rtw89_8851be_info = {
> > >       .chip = &rtw8851b_chip_info,
> > >       .variant = NULL,
> > >       .quirks = NULL,
> > > +     .dev_id_quirks = 0,
> >
> > Why are you manually adding a "= 0" for these when that's the default?
> > No need to do so, only do it when it is set to something, right?
> 
> I'd ask authors spending a little time to fill these default values because
> Realtek WiFi chips have many specific attributes for many chips, and
> somehow it gets messed. For example,
>  - miss to fill value for a certain chip
>    (people might only force on one chip he wants to fix)
>  - for some cases, it should set 0 explicitly as the value
>    (such as a threshold value of hardware register)
>  - messed up the order of attributes
>    People add a field along the existing field across all chips.
>    If a field is omitted, somehow people might add the field at wrong place.
>  - simply coding rule
>    People might forget why, so I'd have a simple rule for them.
> 
> I encountered these cases when I processed earlier Realtek WiFi drivers
> (rtlwifi, rtl8xxxu, rtw88), so I'd explicitly fill values to avoid them.
> 

Just a gentle follow-up on Ping-Ke's explanation regarding the explicit "= 0" initialization. 

If there are no further concerns on this, I will keep the current approach for this part and send out the v3 patch.


Thanks,

Johnson

^ permalink raw reply

* RE: [PATCH v2 rtw-next 2/2] wifi: rtw89: usb: add serial_number and uuid sysfs attributes for 0x28de:0x2432
From: Johnson Tsai @ 2026-05-27 11:46 UTC (permalink / raw)
  To: Greg KH, Ping-Ke Shih
  Cc: linux-wireless@vger.kernel.org, driver-core@lists.linux.dev,
	johannes@sipsolutions.net, Mh_chen, charlesl@valvesoftware.com,
	sabae@valvesoftware.com
In-Reply-To: <2026052524-ammonia-zeppelin-9edb@gregkh>



On : Tuesday, May 26, 2026 3:33, Greg KH wrote: 
> On Mon, May 25, 2026 at 04:51:48PM +0800, Ping-Ke Shih wrote:
> > From: Johnson Tsai <wenjie.tsai@realtek.com>
> >
> > Expose the device's Serial Number (SN) and UUID from EFUSE via two
> > read-only sysfs attributes, `serial_number` and `uuid`, on the
> > ieee80211 phy device under the `rtw89_usb` attribute group.
> >
> > This hardware identification information is essential for user-space
> > applications to uniquely identify, track, and manage specific Wi-Fi
> > adapters. For example, in automated factory provisioning or device
> > management systems, user-space tools rely on the EFUSE serial number
> > and UUID to bind configurations to specific physical adapters.
> > Currently, standard wireless APIs do not expose this low-level
> > hardware information, making these sysfs nodes the only viable
> > solution for user space to extract this data.
> >
> > The attributes are gated behind a new RTW89_QUIRK_HW_INFO_SYSFS
> quirk,
> > enabled only for the VID 0x28de / PID 0x2432 device via the
> > dev_id_quirks field in rtw89_driver_info.
> >
> > Example usage from user-space:
> >   $ cat /sys/class/ieee80211/phy0/rtw89_usb/serial_number
> >   3642000123
> >   $ cat /sys/class/ieee80211/phy0/rtw89_usb/uuid
> >   aaec2b7c-0a55-4727-8de0-b30febccbbaa
> >
> > Cc: Elliot Saba <sabae@valvesoftware.com>
> > Cc: Charles Lohr <charlesl@valvesoftware.com>
> > Signed-off-by: Johnson Tsai <wenjie.tsai@realtek.com>
> > Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
> > ---
> >  .../ABI/testing/sysfs-class-ieee80211-rtw89   | 24 ++++++++
> >  drivers/net/wireless/realtek/rtw89/core.h     |  6 ++
> >  drivers/net/wireless/realtek/rtw89/rtw8852c.c | 10 ++++
> > drivers/net/wireless/realtek/rtw89/rtw8852c.h |  6 +-
> >  .../net/wireless/realtek/rtw89/rtw8852cu.c    | 12 +++-
> >  drivers/net/wireless/realtek/rtw89/usb.c      | 57 +++++++++++++++++++
> >  6 files changed, 113 insertions(+), 2 deletions(-)  create mode
> > 100644 Documentation/ABI/testing/sysfs-class-ieee80211-rtw89
> >
> > diff --git a/Documentation/ABI/testing/sysfs-class-ieee80211-rtw89
> > b/Documentation/ABI/testing/sysfs-class-ieee80211-rtw89
> > new file mode 100644
> > index 000000000000..7dfdce08a42f
> > --- /dev/null
> > +++ b/Documentation/ABI/testing/sysfs-class-ieee80211-rtw89
> > @@ -0,0 +1,24 @@
> > +What:                /sys/class/ieee80211/phyX/rtw89_usb/serial_number
> > +Date:                May 2026
> > +Contact:     Johnson Tsai <wenjie.tsai@realtek.com>, linux-
> wireless@vger.kernel.org
> > +Description: (Read) Serial number burned into EFUSE of the RTL8852CU-
> based
> > +             USB Wi-Fi adapter.  Only present on devices that set the
> > +             RTW89_QUIRK_HW_INFO_SYSFS quirk (currently VID 0x28de /
> > +             PID 0x2432).
> > +
> > +             Format: %10phN (5 raw bytes printed as 10 lowercase hex
> > +             digits, no separators).
> > +
> > +             Example: 3642000123
> > +
> > +What:                /sys/class/ieee80211/phyX/rtw89_usb/uuid
> > +Date:                May 2026
> > +Contact:     Johnson Tsai <wenjie.tsai@realtek.com>, linux-
> wireless@vger.kernel.org
> > +Description: (Read) UUID burned into EFUSE of the RTL8852CU-based USB
> Wi-Fi
> > +             adapter.  Only present on devices that set the
> > +             RTW89_QUIRK_HW_INFO_SYSFS quirk (currently VID 0x28de /
> > +             PID 0x2432).
> > +
> > +             Format: %pUb (RFC 4122 UUID in lowercase with hyphens).
> > +
> > +             Example: aaec2b7c-0a55-4727-8de0-b30febccbbaa
> > diff --git a/drivers/net/wireless/realtek/rtw89/core.h
> > b/drivers/net/wireless/realtek/rtw89/core.h
> > index e687216da5b6..09f17d958075 100644
> > --- a/drivers/net/wireless/realtek/rtw89/core.h
> > +++ b/drivers/net/wireless/realtek/rtw89/core.h
> > @@ -3615,6 +3615,9 @@ struct rtw89_sta_link {
> >       u32 data_tx_cnt_lmt:6;
> >  };
> >
> > +#define RTW89_EFUSE_SN_LEN 5
> > +#define RTW89_EFUSE_UUID_LEN 16
> > +
> >  struct rtw89_efuse {
> >       bool valid;
> >       bool power_k_valid;
> > @@ -3625,6 +3628,8 @@ struct rtw89_efuse {
> >       u8 adc_td;
> >       u8 bt_setting_2;
> >       u8 bt_setting_3;
> > +     u8 sn[RTW89_EFUSE_SN_LEN];
> > +     u8 uuid[RTW89_EFUSE_UUID_LEN];
> >  };
> >
> >  struct rtw89_phy_rate_pattern {
> > @@ -5373,6 +5378,7 @@ enum rtw89_quirks {
> >       RTW89_QUIRK_PCI_BER,
> >       RTW89_QUIRK_THERMAL_PROT_120C,
> >       RTW89_QUIRK_THERMAL_PROT_110C,
> > +     RTW89_QUIRK_HW_INFO_SYSFS,
> >
> >       NUM_OF_RTW89_QUIRKS,
> >  };
> > diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c
> > b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
> > index 7bb1264bcaef..3861cce42b1b 100644
> > --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c
> > +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
> > @@ -621,6 +621,15 @@ static void
> rtw8852c_efuse_parsing_gain_offset(struct rtw89_dev *rtwdev,
> >       gain->offset_valid = valid;
> >  }
> >
> > +static void rtw8852c_efuse_copy_sn_uuid_usb(struct rtw89_dev *rtwdev,
> > +                                         const struct rtw8852c_efuse
> > +*map) {
> > +     struct rtw89_efuse *efuse = &rtwdev->efuse;
> > +
> > +     memcpy(efuse->sn, map->u.sn, sizeof(efuse->sn));
> > +     memcpy(efuse->uuid, map->u.uuid, sizeof(efuse->uuid)); }
> > +
> >  static int rtw8852c_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map,
> >                              enum rtw89_efuse_block block)  { @@
> > -640,6 +649,7 @@ static int rtw8852c_read_efuse(struct rtw89_dev
> *rtwdev, u8 *log_map,
> >               break;
> >       case RTW89_HCI_TYPE_USB:
> >               ether_addr_copy(efuse->addr, map->u.mac_addr);
> > +             rtw8852c_efuse_copy_sn_uuid_usb(rtwdev, map);
> >               break;
> >       default:
> >               return -ENOTSUPP;
> > diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.h
> > b/drivers/net/wireless/realtek/rtw89/rtw8852c.h
> > index 8585921ac6c4..b1d7c354c18e 100644
> > --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.h
> > +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.h
> > @@ -13,7 +13,11 @@
> >  struct rtw8852c_u_efuse {
> >       u8 rsvd[0x88];
> >       u8 mac_addr[ETH_ALEN];
> > -};
> > +     u8 rsvd1[8];
> > +     u8 sn[RTW89_EFUSE_SN_LEN];
> > +     u8 rsvd2[29];
> > +     u8 uuid[RTW89_EFUSE_UUID_LEN];
> > +} __packed;
> >
> >  struct rtw8852c_e_efuse {
> >       u8 mac_addr[ETH_ALEN];
> > diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852cu.c
> > b/drivers/net/wireless/realtek/rtw89/rtw8852cu.c
> > index 8f89f9a31455..81ee96b0a048 100644
> > --- a/drivers/net/wireless/realtek/rtw89/rtw8852cu.c
> > +++ b/drivers/net/wireless/realtek/rtw89/rtw8852cu.c
> > @@ -39,6 +39,16 @@ static const struct rtw89_driver_info
> rtw89_8852cu_info = {
> >       },
> >  };
> >
> > +static const struct rtw89_driver_info rtw89_8852cu_valve_info = {
> > +     .chip = &rtw8852c_chip_info,
> > +     .variant = NULL,
> > +     .quirks = NULL,
> > +     .dev_id_quirks = BIT(RTW89_QUIRK_HW_INFO_SYSFS),
> > +     .bus = {
> > +             .usb = &rtw8852c_usb_info,
> > +     },
> > +};
> > +
> >  static const struct usb_device_id rtw_8852cu_id_table[] = {
> >       { USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x03a6, 0xff, 0xff, 0xff),
> >         .driver_info = (kernel_ulong_t)&rtw89_8852cu_info }, @@ -53,7
> > +63,7 @@ static const struct usb_device_id rtw_8852cu_id_table[] = {
> >       { USB_DEVICE_AND_INTERFACE_INFO(0x0db0, 0x991d, 0xff, 0xff, 0xff),
> >         .driver_info = (kernel_ulong_t)&rtw89_8852cu_info },
> >       { USB_DEVICE_AND_INTERFACE_INFO(0x28de, 0x2432, 0xff, 0xff, 0xff),
> > -       .driver_info = (kernel_ulong_t)&rtw89_8852cu_info },
> > +       .driver_info = (kernel_ulong_t)&rtw89_8852cu_valve_info },
> >       { USB_DEVICE_AND_INTERFACE_INFO(0x2c7c, 0x8206, 0xff, 0xff, 0xff),
> >         .driver_info = (kernel_ulong_t)&rtw89_8852cu_info },
> >       { USB_DEVICE_AND_INTERFACE_INFO(0x35b2, 0x0502, 0xff, 0xff,
> > 0xff), diff --git a/drivers/net/wireless/realtek/rtw89/usb.c
> > b/drivers/net/wireless/realtek/rtw89/usb.c
> > index 88d7ec200837..7e23d0a32025 100644
> > --- a/drivers/net/wireless/realtek/rtw89/usb.c
> > +++ b/drivers/net/wireless/realtek/rtw89/usb.c
> > @@ -1059,6 +1059,61 @@ static void rtw89_usb_intf_deinit(struct
> rtw89_dev *rtwdev,
> >       usb_set_intfdata(intf, NULL);
> >  }
> >
> > +static ssize_t serial_number_show(struct device *dev,
> > +                               struct device_attribute *attr, char
> > +*buf) {
> > +     struct wiphy *wiphy = container_of(dev, struct wiphy, dev);
> > +     struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
> > +     struct rtw89_dev *rtwdev = hw->priv;
> > +     struct rtw89_efuse *efuse = &rtwdev->efuse;
> > +
> > +     return sysfs_emit(buf, "%*phN\n",
> > +                       (int)sizeof(efuse->sn), efuse->sn); } static
> > +DEVICE_ATTR_RO(serial_number);
> > +
> > +static ssize_t uuid_show(struct device *dev,
> > +                      struct device_attribute *attr, char *buf) {
> > +     struct wiphy *wiphy = container_of(dev, struct wiphy, dev);
> > +     struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
> > +     struct rtw89_dev *rtwdev = hw->priv;
> > +     struct rtw89_efuse *efuse = &rtwdev->efuse;
> > +
> > +     return sysfs_emit(buf, "%pUb\n", efuse->uuid); } static
> > +DEVICE_ATTR_RO(uuid);
> > +
> > +static struct attribute *rtw89_usb_attrs[] = {
> > +     &dev_attr_serial_number.attr,
> > +     &dev_attr_uuid.attr,
> > +     NULL,
> > +};
> > +
> > +static const struct attribute_group rtw89_usb_group = {
> > +     .name = "rtw89_usb",
> > +     .attrs = rtw89_usb_attrs,
> > +};
> > +__ATTRIBUTE_GROUPS(rtw89_usb);
> > +
> > +static void rtw89_usb_sysfs_create(struct rtw89_dev *rtwdev) {
> > +     int ret;
> > +
> > +     if (!test_bit(RTW89_QUIRK_HW_INFO_SYSFS, rtwdev->quirks))
> > +             return;
> > +
> > +     ret = sysfs_create_groups(&rtwdev->hw->wiphy->dev.kobj,
> > +                               rtw89_usb_groups);
> 
> You just raced with userspace and lost, please use the is_visable callback
> instead, and make this the default group attributes.

Thanks for the explanation.

I see the problem now. The user space sysfs path remains identical, 
but the timing and mechanism are different. Using dev.kobj requires 
manual creation/removal outside the hardware lifecycle, whereas 
setting dev.groups will automatically handle creation/removal within 
the same hardware lifecycle to avoid the race condition.

I will remove the manual sysfs creation and switch to default group 
attributes in v3. 

Specifically, the visibility of the entire group will be managed via the macro:

    /* Control the visibility of the entire attribute group */
    .is_visible = SYSFS_GROUP_VISIBLE(rtw89_usb),

And the group will be attached to the wiphy device default groups before registration:

    /* Attach the attribute group to the wiphy device */
    rtwdev->hw->wiphy->dev.groups = rtw89_usb_groups;


Thanks,

Johnson



^ permalink raw reply


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