* Re: 6.18.13 iwlwifi deadlock allocating cma while work-item is active.
From: Johannes Berg @ 2026-03-03 21:03 UTC (permalink / raw)
To: Tejun Heo
Cc: Ben Greear, linux-wireless, Korenblit, Miriam Rachel, linux-mm,
linux-kernel
In-Reply-To: <aadKDCKGHk1Ua-7_@slm.duckdns.org>
On Tue, 2026-03-03 at 10:52 -1000, Tejun Heo wrote:
> Hello,
>
> On Tue, Mar 03, 2026 at 12:49:24PM +0100, Johannes Berg wrote:
> > Fair. I don't know, I don't think there's anything that even shows that
> > there's a dependency between the two workqueues and the
> > "((wq_completion)events_unbound)" and "((wq_completion)events)", and
> > there would have to be for it to deadlock this way because of that?
> >
> > But one is mm_percpu_wq and the other is system_percpu_wq.
> >
> > Tejun, does the workqueue code somehow introduce a dependency between
> > different per-CPU workqueues that's not modelled in lockdep?
>
> Hopefully not. Kinda late to the party.
Yeah, sorry, should've included a link:
https://lore.kernel.org/linux-wireless/fa4e82ee-eb14-3930-c76c-f3bd59c5f258@candelatech.com/
> Why isn't mm_percpu_wq making
> forward progress? That should in all circumstances. What's the work item and
> kworker doing?
So it seems that first iwlwifi is holding the RTNL:
ieee80211_open+0x62/0xe0 [mac80211]
__dev_open+0x11a/0x2e0
__dev_change_flags+0x1f8/0x280
netif_change_flags+0x22/0x60
do_setlink.isra.0+0xe57/0x11a0
rtnl_newlink+0x7e8/0xb50
(last stack trace at the above link)
This stuff definitely happens with the RTNL held, although I didn't
check now which function actually acquires it in this stack.
Simultaneously the kworker/6:0 is stuck in reg_todo(), trying to acquire
the RTNL.
So far that seems fairly much normal. The kworker/6:0 running reg_todo()
is from net/wireless/reg.c, reg_work, scheduled to system_percpu_wq (by
simply schedule_work.)
Now iwlwifi is also trying to allocate coherent DMA memory (continuing
the stack trace), potentially a significant chunk for firmware loading:
dma_direct_alloc+0x7b/0x250
dma_alloc_attrs+0xa1/0x2a0
_iwl_pcie_ctxt_info_dma_alloc_coherent+0x31/0xb0 [iwlwifi]
iwl_pcie_ctxt_info_alloc_dma+0x20/0x50 [iwlwifi]
iwl_pcie_init_fw_sec+0x2fc/0x380 [iwlwifi]
iwl_pcie_ctxt_info_v2_alloc+0x19e/0x530 [iwlwifi]
iwl_trans_pcie_gen2_start_fw+0x2e2/0x820 [iwlwifi]
iwl_trans_start_fw+0x77/0x90 [iwlwifi]
iwl_mld_load_fw_wait_alive+0x97/0x2c0 [iwlmld]
iwl_mld_load_fw+0x91/0x240 [iwlmld]
iwl_mld_start_fw+0x44/0x470 [iwlmld]
iwl_mld_mac80211_start+0x3d/0x1b0 [iwlmld]
drv_start+0x6f/0x1d0 [mac80211]
ieee80211_do_open+0x2d6/0x960 [mac80211]
ieee80211_open+0x62/0xe0 [mac80211]
This is fine, but then it gets into __flush_work() in
__lru_add_drain_all():
__flush_work+0x34e/0x530
__lru_add_drain_all+0x19b/0x220
alloc_contig_range_noprof+0x1de/0x8a0
__cma_alloc+0x1f1/0x6a0
__dma_direct_alloc_pages.isra.0+0xcb/0x2f0
dma_direct_alloc+0x7b/0x250
which is because __lru_add_drain_all() schedules a bunch of workers, one
for each CPU, onto the mm_percpu_wq and then waits for them.
Conceptually, I see nothing wrong with this, hence my question; Ben says
that the system stops making progress at this point.
johannes
^ permalink raw reply
* Re: 6.18.13 iwlwifi deadlock allocating cma while work-item is active.
From: Tejun Heo @ 2026-03-03 20:52 UTC (permalink / raw)
To: Johannes Berg
Cc: Ben Greear, linux-wireless, Korenblit, Miriam Rachel, linux-mm,
linux-kernel
In-Reply-To: <35779061f94c2a55bb58dcd619ae91c618509cf4.camel@sipsolutions.net>
Hello,
On Tue, Mar 03, 2026 at 12:49:24PM +0100, Johannes Berg wrote:
> Fair. I don't know, I don't think there's anything that even shows that
> there's a dependency between the two workqueues and the
> "((wq_completion)events_unbound)" and "((wq_completion)events)", and
> there would have to be for it to deadlock this way because of that?
>
> But one is mm_percpu_wq and the other is system_percpu_wq.
>
> Tejun, does the workqueue code somehow introduce a dependency between
> different per-CPU workqueues that's not modelled in lockdep?
Hopefully not. Kinda late to the party. Why isn't mm_percpu_wq making
forward progress? That should in all circumstances. What's the work item and
kworker doing?
Thanks.
--
tejun
^ permalink raw reply
* iwlwifi: improve cleanup to fix use-after-free.
From: Ben Greear @ 2026-03-03 20:20 UTC (permalink / raw)
To: linux-wireless, Korenblit, Miriam Rachel
Hello,
I believe I found the cause of the use-after-free crash related to iwl_mld_rm_link_from_fw
access.
From the logging I've added, we see that the logic in mlme.c is failing:
static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
struct cfg80211_bss *cbss, s8 link_id,
const u8 *ap_mld_addr, bool assoc,
struct ieee80211_conn_settings *conn,
bool override,
unsigned long *userspace_selectors)
{
struct ieee80211_local *local = sdata->local;
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
struct ieee80211_bss *bss = (void *)cbss->priv;
struct sta_info *new_sta = NULL;
struct ieee80211_link_data *link;
bool have_sta = false;
bool mlo;
int err;
u16 new_links;
if (link_id >= 0) {
mlo = true;
if (WARN_ON(!ap_mld_addr))
return -EINVAL;
new_links = BIT(link_id);
} else {
if (WARN_ON(ap_mld_addr))
return -EINVAL;
ap_mld_addr = cbss->bssid;
new_links = 0;
link_id = 0;
mlo = false;
}
if (assoc) {
rcu_read_lock();
have_sta = sta_info_get(sdata, ap_mld_addr);
rcu_read_unlock();
}
if (mlo && !have_sta &&
WARN_ON_ONCE(sdata->vif.valid_links || sdata->vif.active_links)) {
pr_err("%s: prep-connection, no-have-sta, valid-links: 0x%x active-links: 0x%x\n",
sdata->dev->name, sdata->vif.valid_links, sdata->vif.active_links);
return -EINVAL;
}
I'm not sure exactly how, but this path (or something related) appears to only half-configure
the iwlwifi driver.
I added improved safety code in iwlwifi to force clearing pointers and I see that code hitting. The system
did not crash this time, and STA reconnected. This patch below is on top of some previous debugging
I had added, I'll paste code w/out diff below the diff.
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/link.c b/drivers/net/wireless/intel/iwlwifi/mld/link.c
index a5472ede2803..c0ee7de35aa9 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/link.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/link.c
@@ -507,32 +507,49 @@ void iwl_mld_remove_link(struct iwl_mld *mld,
struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(bss_conf->vif);
struct iwl_mld_link *link = iwl_mld_link_from_mac80211(bss_conf);
bool is_deflink = link == &mld_vif->deflink;
- u8 fw_id;
+ u16 fw_id;
if (WARN_ON_ONCE(!link)) {
- IWL_ERR(mld, "Attempted to remove nonexistent link.\n");
- return;
+ IWL_ERR(mld, "Remove nonexistent link, bss_conf: 0x%px link-id: %d\n",
+ bss_conf, bss_conf->link_id);
+ fw_id = 0xffff;
}
-
- if (WARN_ON_ONCE(link->active)) {
- IWL_ERR(mld, "Attempted to remove active link.\n");
- return;
+ else {
+ fw_id = link->fw_id;
}
- fw_id = link->fw_id;
+ /* Not cleaning it up seems worse than cleaning up an active link,
+ * so continue on even in warning case.
+ */
+ if (link && WARN_ON_ONCE(link->active))
+ IWL_ERR(mld, "Removing active link, id: %d\n",
+ bss_conf->link_id);
iwl_mld_rm_link_from_fw(mld, bss_conf);
/* Continue cleanup on failure */
- if (!is_deflink)
+ if (link && !is_deflink)
kfree_rcu(link, rcu_head);
RCU_INIT_POINTER(mld_vif->link[bss_conf->link_id], NULL);
- if (WARN_ON(fw_id >= mld->fw->ucode_capa.num_links))
- return;
-
- RCU_INIT_POINTER(mld->fw_id_to_bss_conf[fw_id], NULL);
+ if (fw_id >= mld->fw->ucode_capa.num_links) {
+ struct ieee80211_bss_conf *tmp_bss_conf;
+ int i;
+
+ /* Search for any existing back-pointer */
+ for (i = 0; i<ARRAY_SIZE(mld->fw_id_to_bss_conf); i++) {
+ tmp_bss_conf = rcu_dereference(mld->fw_id_to_bss_conf[i]);
+ if (tmp_bss_conf == bss_conf) {
+ IWL_ERR(mld, "WARNING: Found bss_conf in fw_id_to_bss_conf[%i], Nulling pointer.\n",
+ i);
+ RCU_INIT_POINTER(mld->fw_id_to_bss_conf[i], NULL);
+ }
+ }
+ }
+ else {
+ RCU_INIT_POINTER(mld->fw_id_to_bss_conf[fw_id], NULL);
+ }
}
/* Remove link from fw, unmap the bss_conf, and destroy the link structure */
void iwl_mld_remove_link(struct iwl_mld *mld,
struct ieee80211_bss_conf *bss_conf)
{
struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(bss_conf->vif);
struct iwl_mld_link *link = iwl_mld_link_from_mac80211(bss_conf);
bool is_deflink = link == &mld_vif->deflink;
u16 fw_id;
if (WARN_ON_ONCE(!link)) {
IWL_ERR(mld, "Remove nonexistent link, bss_conf: 0x%px link-id: %d\n",
bss_conf, bss_conf->link_id);
fw_id = 0xffff;
}
else {
fw_id = link->fw_id;
}
/* Not cleaning it up seems worse than cleaning up an active link,
* so continue on even in warning case.
*/
if (link && WARN_ON_ONCE(link->active))
IWL_ERR(mld, "Removing active link, id: %d\n",
bss_conf->link_id);
iwl_mld_rm_link_from_fw(mld, bss_conf);
/* Continue cleanup on failure */
if (link && !is_deflink)
kfree_rcu(link, rcu_head);
RCU_INIT_POINTER(mld_vif->link[bss_conf->link_id], NULL);
if (fw_id >= mld->fw->ucode_capa.num_links) {
struct ieee80211_bss_conf *tmp_bss_conf;
int i;
/* Search for any existing back-pointer */
for (i = 0; i<ARRAY_SIZE(mld->fw_id_to_bss_conf); i++) {
tmp_bss_conf = rcu_dereference(mld->fw_id_to_bss_conf[i]);
if (tmp_bss_conf == bss_conf) {
IWL_ERR(mld, "WARNING: Found bss_conf in fw_id_to_bss_conf[%i], Nulling pointer.\n",
i);
RCU_INIT_POINTER(mld->fw_id_to_bss_conf[i], NULL);
}
}
}
else {
RCU_INIT_POINTER(mld->fw_id_to_bss_conf[fw_id], NULL);
}
}
Miriam, please let me know if you are interested in a patch like this, and if so, do you
want the IWL_ERR printing in there or not?
Here are the logs of this happening:
Mar 03 11:45:01 ct523c-ccbc kernel: wlan10: prep-connection, no-have-sta, valid-links: 0x4 active-links: 0x4
Mar 03 11:45:01 ct523c-ccbc kernel: wlan10: mgd_auth, prep connection failed: -22
Mar 03 11:45:01 ct523c-ccbc kernel: wlan10: mgd_auth failed, err: -22
Mar 03 11:45:01 ct523c-ccbc kernel: wlan10: prep-connection, no-have-sta, valid-links: 0x4 active-links: 0x4
Mar 03 11:45:01 ct523c-ccbc kernel: wlan10: mgd_auth, prep connection failed: -22
Mar 03 11:45:01 ct523c-ccbc kernel: wlan10: mgd_auth failed, err: -22
Mar 03 11:45:01 ct523c-ccbc kernel: wlan10: ieee80211_vif_set_links: new_links=0x0; dormant_links=0x0
Mar 03 11:45:01 ct523c-ccbc kernel: iwlwifi 0000:38:00.0: Attempted to remove nonexistent link, bss_conf: 0xffff888186c1c470 link-id: 2
Mar 03 11:45:01 ct523c-ccbc kernel: ------------[ cut here ]------------
Mar 03 11:45:01 ct523c-ccbc kernel: WARNING: CPU: 1 PID: 44077 at drivers/net/wireless/intel/iwlwifi/mld/link.c:432 iwl_mld_rm_link_from_fw+0x25a/0x3a0 [iwlmld]
Mar 03 11:45:01 ct523c-ccbc kernel: Modules linked in: vrf nf_conntrack_netlink nf_conntrack nfnetlink nf_defrag_ipv6 nf_defrag_ipv4 8021q garp mrp stp llc
macvlan pktgen rfcomm rpcrdma rdma_cm iw_cm nfsv3 ib_cm ib_core nfs netfs qrtr bnep intel_rapl_msr iTCO_wdt ee1004 intel_pmc_bxt coretemp intel_rapl_common
snd_hda_codec_intelhdmi intel_uncore_frequency snd_hda_codec_hdmi intel_uncore_frequency_common iTCO_vendor_support snd_hda_codec_alc662
snd_hda_codec_realtek_lib snd_hda_codec_generic iwlmld intel_tcc_cooling x86_pkg_temp_thermal snd_hda_intel intel_wmi_thunderbolt intel_powerclamp
snd_intel_dspcfg pcspkr snd_hda_codec snd_hda_core mac80211 snd_hwdep snd_seq btusb snd_seq_device btbcm btmtk btrtl btintel snd_pcm bluetooth iwlwifi snd_timer
cfg80211 ftdi_sio i2c_i801 snd i2c_smbus soundcore i2c_mux mei_hdcp mei_pxp intel_pch_thermal intel_pmc_core pmt_telemetry pmt_discovery pmt_class
intel_pmc_ssram_telemetry intel_vsec acpi_pad bfq sch_fq_codel nfsd auth_rpcgss nfs_acl lockd grace nfs_localio sunrpc zram raid1 dm_raid raid456
Mar 03 11:45:01 ct523c-ccbc kernel: async_raid6_recov async_memcpy async_pq async_xor xor async_tx raid6_pq i915 drm_buddy intel_gtt drm_client_lib
drm_display_helper drm_kms_helper cec rc_core igb ttm agpgart dca i2c_algo_bit hwmon drm mei_wdt i2c_core intel_oc_wdt video wmi scsi_dh_rdac scsi_dh_emc
scsi_dh_alua dm_multipath fuse [last unloaded: nfnetlink]
Mar 03 11:45:01 ct523c-ccbc kernel: CPU: 1 UID: 0 PID: 44077 Comm: wpa_supplicant Kdump: loaded Tainted: G W 6.18.14+ #28 PREEMPT(full)
Mar 03 11:45:01 ct523c-ccbc kernel: Tainted: [W]=WARN
Mar 03 11:45:01 ct523c-ccbc kernel: Hardware name: Default string Default string/SKYBAY, BIOS 5.12 02/21/2023
Mar 03 11:45:01 ct523c-ccbc kernel: RIP: 0010:iwl_mld_rm_link_from_fw+0x25a/0x3a0 [iwlmld]
Mar 03 11:45:01 ct523c-ccbc kernel: Code: 00 49 8b 84 24 18 11 00 00 be ff ff ff ff 48 8d 78 68 e8 c9 07 9e e1 85 c0 0f 85 03 ff ff ff 0f 0b 4d 85 ff 0f 85 01
ff ff ff <0f> 0b e9 69 ff ff ff 48 8d ba e0 05 00 00 48 b8 00 00 00 00 00 fc
Mar 03 11:45:01 ct523c-ccbc kernel: RSP: 0018:ffff88821104eae0 EFLAGS: 00010246
Mar 03 11:45:01 ct523c-ccbc kernel: RAX: 0000000000000000 RBX: 1ffff11042209d5d RCX: 1ffffffff0b57d64
Mar 03 11:45:01 ct523c-ccbc kernel: RDX: 0000000000000000 RSI: ffff888186c1c470 RDI: ffff88821104ebe8
Mar 03 11:45:01 ct523c-ccbc kernel: RBP: ffff888186c1c470 R08: 0000000000000001 R09: ffffed1042209cfe
Mar 03 11:45:01 ct523c-ccbc kernel: R10: ffff88821104e7f7 R11: 0000000000086478 R12: ffff888168665508
Mar 03 11:45:01 ct523c-ccbc kernel: R13: ffff888186c1c488 R14: ffff88821104eb18 R15: 0000000000000000
Mar 03 11:45:01 ct523c-ccbc kernel: FS: 00007fdab99f5780(0000) GS:ffff8884973c6000(0000) knlGS:0000000000000000
Mar 03 11:45:01 ct523c-ccbc kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
Mar 03 11:45:01 ct523c-ccbc kernel: CR2: 0000000002d4e878 CR3: 000000020ebc2001 CR4: 00000000003706f0
Mar 03 11:45:01 ct523c-ccbc kernel: Call Trace:
Mar 03 11:45:01 ct523c-ccbc kernel: <TASK>
Mar 03 11:45:01 ct523c-ccbc kernel: ? iwl_mld_send_link_cmd+0x360/0x360 [iwlmld]
Mar 03 11:45:01 ct523c-ccbc kernel: ? iwl_mld_remove_link+0x3ee/0x5c0 [iwlmld]
Mar 03 11:45:01 ct523c-ccbc kernel: iwl_mld_remove_link+0x460/0x5c0 [iwlmld]
Mar 03 11:45:01 ct523c-ccbc kernel: iwl_mld_change_vif_links+0xf9/0x760 [iwlmld]
Mar 03 11:45:01 ct523c-ccbc kernel: drv_change_vif_links+0x2e7/0x620 [mac80211]
Mar 03 11:45:01 ct523c-ccbc kernel: ieee80211_vif_update_links+0xced/0x1500 [mac80211]
Mar 03 11:45:01 ct523c-ccbc kernel: ? irq_work_queue+0x69/0xa0
Mar 03 11:45:02 ct523c-ccbc kernel: ? ieee80211_apvlan_link_clear+0x60/0x60 [mac80211]
Mar 03 11:45:02 ct523c-ccbc kernel: ? vprintk_emit+0x2e4/0x3e0
Mar 03 11:45:02 ct523c-ccbc kernel: ? wake_up_klogd_work_func+0x80/0x80
Mar 03 11:45:02 ct523c-ccbc kernel: ? _printk+0xb2/0xe0
Mar 03 11:45:02 ct523c-ccbc kernel: ? printk_get_console_flush_type+0x2d0/0x2d0
Mar 03 11:45:02 ct523c-ccbc kernel: ? lock_release+0x1cc/0x290
Mar 03 11:45:02 ct523c-ccbc kernel: ieee80211_vif_set_links+0xa8/0x130 [mac80211]
Mar 03 11:45:02 ct523c-ccbc kernel: ? ieee80211_find_best_sta_link+0x430/0x430 [mac80211]
Mar 03 11:45:02 ct523c-ccbc kernel: ? unwind_get_return_address+0x56/0xa0
Mar 03 11:45:02 ct523c-ccbc kernel: ? write_profile+0xf0/0xf0
Mar 03 11:45:02 ct523c-ccbc kernel: ? arch_stack_walk+0x97/0xe0
Mar 03 11:45:02 ct523c-ccbc kernel: ? ieee80211_send_teardown_neg_ttlm+0x2e0/0x2e0 [mac80211]
Mar 03 11:45:02 ct523c-ccbc kernel: ieee80211_prep_connection+0xe3/0x1550 [mac80211]
Mar 03 11:45:02 ct523c-ccbc kernel: ieee80211_mgd_auth+0xec6/0x1960 [mac80211]
Mar 03 11:45:02 ct523c-ccbc kernel: ? kasan_save_stack+0x2a/0x40
Mar 03 11:45:02 ct523c-ccbc kernel: ? ieee80211_mlme_notify_scan_completed+0x300/0x300 [mac80211]
Mar 03 11:45:02 ct523c-ccbc kernel: ? __kmalloc_noprof+0x24e/0x7d0
Mar 03 11:45:02 ct523c-ccbc kernel: ? cfg80211_find_elem_match+0xd6/0x1b0 [cfg80211]
Mar 03 11:45:02 ct523c-ccbc kernel: ? lock_release+0x1cc/0x290
Mar 03 11:45:02 ct523c-ccbc kernel: ? __cfg80211_get_bss+0x429/0xa50 [cfg80211]
Mar 03 11:45:02 ct523c-ccbc kernel: ? trace_irq_enable.constprop.0+0xbe/0x100
Mar 03 11:45:02 ct523c-ccbc kernel: ? __cfg80211_get_bss+0x429/0xa50 [cfg80211]
Mar 03 11:45:02 ct523c-ccbc kernel: ? __cfg80211_get_bss+0x46f/0xa50 [cfg80211]
Mar 03 11:45:02 ct523c-ccbc kernel: cfg80211_mlme_auth+0x458/0x7f0 [cfg80211]
Mar 03 11:45:02 ct523c-ccbc kernel: nl80211_authenticate+0xa90/0x1180 [cfg80211]
Mar 03 11:45:02 ct523c-ccbc kernel: ? __rtnl_unlock+0x65/0xf0
Mar 03 11:45:02 ct523c-ccbc kernel: ? nl80211_parse_key+0xe60/0xe60 [cfg80211]
Mar 03 11:45:02 ct523c-ccbc kernel: ? __kasan_kmalloc+0x83/0x90
Mar 03 11:45:02 ct523c-ccbc kernel: ? nl80211_pre_doit+0x3f3/0x750 [cfg80211]
Mar 03 11:45:02 ct523c-ccbc kernel: genl_family_rcv_msg_doit+0x1cb/0x2a0
Mar 03 11:45:02 ct523c-ccbc kernel: ? genl_family_rcv_msg_attrs_parse.constprop.0+0x230/0x230
Mar 03 11:45:02 ct523c-ccbc kernel: ? security_capable+0x2d/0x80
Mar 03 11:45:02 ct523c-ccbc kernel: genl_rcv_msg+0x3f7/0x6b0
Mar 03 11:45:02 ct523c-ccbc kernel: ? genl_family_rcv_msg_dumpit+0x2a0/0x2a0
Mar 03 11:45:02 ct523c-ccbc kernel: ? ext4_inode_csum+0x27e/0x350
Mar 03 11:45:02 ct523c-ccbc kernel: ? nl80211_get_reg_dump+0x450/0x450 [cfg80211]
Mar 03 11:45:02 ct523c-ccbc kernel: ? nl80211_parse_key+0xe60/0xe60 [cfg80211]
Mar 03 11:45:02 ct523c-ccbc kernel: ? nlmsg_trim+0x60/0x60 [cfg80211]
Mar 03 11:45:02 ct523c-ccbc kernel: ? from_kprojid+0x8b/0xc0
Mar 03 11:45:02 ct523c-ccbc kernel: netlink_rcv_skb+0x125/0x380
Mar 03 11:45:02 ct523c-ccbc kernel: ? genl_family_rcv_msg_dumpit+0x2a0/0x2a0
Mar 03 11:45:02 ct523c-ccbc kernel: ? lock_acquire+0x291/0x2e0
Mar 03 11:45:02 ct523c-ccbc kernel: ? netlink_ack+0xda0/0xda0
Mar 03 11:45:02 ct523c-ccbc kernel: ? netlink_deliver_tap+0x14f/0xb60
Mar 03 11:45:02 ct523c-ccbc kernel: genl_rcv+0x24/0x40
Mar 03 11:45:02 ct523c-ccbc kernel: netlink_unicast+0x5dd/0x9d0
Mar 03 11:45:02 ct523c-ccbc kernel: ? netlink_attachskb+0x9b0/0x9b0
Mar 03 11:45:02 ct523c-ccbc kernel: ? __virt_addr_valid+0x205/0x3f0
Mar 03 11:45:02 ct523c-ccbc kernel: ? __check_object_size+0x489/0x640
Mar 03 11:45:02 ct523c-ccbc kernel: netlink_sendmsg+0x749/0xc00
Mar 03 11:45:02 ct523c-ccbc kernel: ? netlink_unicast+0x9d0/0x9d0
Mar 03 11:45:02 ct523c-ccbc kernel: ? lock_release+0x1cc/0x290
Mar 03 11:45:02 ct523c-ccbc kernel: ? netlink_unicast+0x9d0/0x9d0
Mar 03 11:45:02 ct523c-ccbc kernel: __sock_sendmsg+0xc1/0x150
Mar 03 11:45:02 ct523c-ccbc kernel: ____sys_sendmsg+0x5f4/0x8f0
Mar 03 11:45:02 ct523c-ccbc kernel: ? kernel_sendmsg+0x30/0x30
Mar 03 11:45:02 ct523c-ccbc kernel: ? __copy_msghdr+0x400/0x400
Mar 03 11:45:02 ct523c-ccbc kernel: ? ext4_buffered_write_iter+0xf4/0x360
Mar 03 11:45:02 ct523c-ccbc kernel: ___sys_sendmsg+0xed/0x170
Mar 03 11:45:02 ct523c-ccbc kernel: ? copy_msghdr_from_user+0x110/0x110
Mar 03 11:45:02 ct523c-ccbc kernel: ? _copy_from_user+0x4f/0x90
Mar 03 11:45:02 ct523c-ccbc kernel: ? lock_acquire+0x291/0x2e0
Mar 03 11:45:02 ct523c-ccbc kernel: ? netlink_setsockopt+0x32d/0x650
Mar 03 11:45:02 ct523c-ccbc kernel: ? lock_release+0x1cc/0x290
Mar 03 11:45:02 ct523c-ccbc kernel: ? kfree+0x2ae/0x580
Mar 03 11:45:02 ct523c-ccbc kernel: ? vfs_write+0x2d9/0x1150
Mar 03 11:45:02 ct523c-ccbc kernel: ? do_sock_setsockopt+0x1c2/0x3b0
Mar 03 11:45:02 ct523c-ccbc kernel: ? do_sock_setsockopt+0x1c2/0x3b0
Mar 03 11:45:02 ct523c-ccbc kernel: ? move_addr_to_user+0x150/0x150
Mar 03 11:45:02 ct523c-ccbc kernel: __sys_sendmsg+0x107/0x1a0
Mar 03 11:45:02 ct523c-ccbc kernel: ? __sys_sendmsg_sock+0x20/0x20
Mar 03 11:45:02 ct523c-ccbc kernel: do_syscall_64+0x69/0x1210
Mar 03 11:45:02 ct523c-ccbc kernel: entry_SYSCALL_64_after_hwframe+0x4b/0x53
Mar 03 11:45:02 ct523c-ccbc kernel: RIP: 0033:0x7fdab9335e24
Mar 03 11:45:02 ct523c-ccbc kernel: Code: 15 f1 ff 0b 00 f7 d8 64 89 02 b8 ff ff ff ff eb bf 0f 1f 44 00 00 f3 0f 1e fa 80 3d 45 85 0c 00 00 74 13 b8 2e 00 00
00 0f 05 <48> 3d 00 f0 ff ff 77 4c c3 0f 1f 00 55 48 89 e5 48 83 ec 20 89 55
Mar 03 11:45:02 ct523c-ccbc kernel: RSP: 002b:00007ffd9daf6308 EFLAGS: 00000202 ORIG_RAX: 000000000000002e
Mar 03 11:45:02 ct523c-ccbc kernel: RAX: ffffffffffffffda RBX: 0000000002cc6f50 RCX: 00007fdab9335e24
Mar 03 11:45:02 ct523c-ccbc kernel: RDX: 0000000000000000 RSI: 00007ffd9daf6360 RDI: 0000000000000007
Mar 03 11:45:02 ct523c-ccbc kernel: RBP: 0000000002d47af0 R08: 0000000000000004 R09: 000000000000000d
Mar 03 11:45:02 ct523c-ccbc kernel: R10: 00007ffd9daf642c R11: 0000000000000202 R12: 0000000002cc6e60
Mar 03 11:45:02 ct523c-ccbc kernel: R13: 00007ffd9daf6360 R14: 00007fdab9b47000 R15: 00000000007e3d78
Mar 03 11:45:02 ct523c-ccbc kernel: </TASK>
Mar 03 11:45:02 ct523c-ccbc kernel: irq event stamp: 0
Mar 03 11:45:02 ct523c-ccbc kernel: hardirqs last enabled at (0): [<0000000000000000>] 0x0
Mar 03 11:45:02 ct523c-ccbc kernel: hardirqs last disabled at (0): [<ffffffff814500f7>] copy_process+0x1c07/0x67e0
Mar 03 11:45:02 ct523c-ccbc kernel: softirqs last enabled at (0): [<ffffffff81450144>] copy_process+0x1c54/0x67e0
Mar 03 11:45:02 ct523c-ccbc kernel: softirqs last disabled at (0): [<0000000000000000>] 0x0
Mar 03 11:45:02 ct523c-ccbc kernel: ---[ end trace 0000000000000000 ]---
Mar 03 11:45:02 ct523c-ccbc kernel: iwlwifi 0000:38:00.0: WARNING: Found bss_conf in fw_id_to_bss_conf[0], Nulling pointer.
Mar 03 11:45:02 ct523c-ccbc kernel: iwlwifi 0000:38:00.0: add-link-sta, allocated fw_id_to_link_sta[4]
Mar 03 11:45:02 ct523c-ccbc kernel: wlan10: sta-info-insert-drv-state, sta is uploaded
Mar 03 11:45:02 ct523c-ccbc kernel: wlan10: e0:8f:4c:a0:2a:8a authenticate with 70:58:a4:ff:75:59 (local address=e0:8f:4c:a0:2a:8a)
Mar 03 11:45:02 ct523c-ccbc kernel: wlan10: send auth to 70:58:a4:ff:75:59 (try 1/4)
Mar 03 11:45:03 ct523c-ccbc dhclient[43442]: DHCPDISCOVER on wlan1 to 255.255.255.255 port 67 interval 9
Mar 03 11:45:03 ct523c-ccbc kernel: wlan10: send auth to 70:58:a4:ff:75:59 (try 2/4)
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply related
* Re: [PATCH wireless-next] wifi: nl80211: split out UHR operation information
From: kernel test robot @ 2026-03-03 20:19 UTC (permalink / raw)
To: Johannes Berg, linux-wireless; +Cc: oe-kbuild-all, Johannes Berg
In-Reply-To: <20260303152558.00e7bc8e9f4b.Iafdf37fb0f4304bdcdb824977d61e17b38c47685@changeid>
Hi Johannes,
kernel test robot noticed the following build errors:
[auto build test ERROR on wireless-next/main]
[also build test ERROR on next-20260303]
[cannot apply to wireless/main linus/master v7.0-rc2]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Johannes-Berg/wifi-nl80211-split-out-UHR-operation-information/20260303-223359
base: https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next.git main
patch link: https://lore.kernel.org/r/20260303152558.00e7bc8e9f4b.Iafdf37fb0f4304bdcdb824977d61e17b38c47685%40changeid
patch subject: [PATCH wireless-next] wifi: nl80211: split out UHR operation information
config: x86_64-rhel-9.4-ltp (https://download.01.org/0day-ci/archive/20260303/202603032131.yShfv7Yn-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260303/202603032131.yShfv7Yn-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603032131.yShfv7Yn-lkp@intel.com/
All error/warnings (new ones prefixed by >>):
>> net/wireless/nl80211.c:961:10: error: expected expression before '[' token
961 | [[NL80211_ATTR_UHR_OPERATION] =
| ^
net/wireless/nl80211.c:963:1: error: expected expression before '}' token
963 | };
| ^
net/wireless/nl80211.c: In function 'nl80211_parse_key_new':
>> net/wireless/nl80211.c:1454:47: error: 'nl80211_key_policy' undeclared (first use in this function); did you mean 'nl80211_rekey_policy'?
1454 | nl80211_key_policy,
| ^~~~~~~~~~~~~~~~~~
| nl80211_rekey_policy
net/wireless/nl80211.c:1454:47: note: each undeclared identifier is reported only once for each function it appears in
net/wireless/nl80211.c: At top level:
>> net/wireless/nl80211.c:345:12: warning: 'validate_uhr_operation' defined but not used [-Wunused-function]
345 | static int validate_uhr_operation(const struct nlattr *attr,
| ^~~~~~~~~~~~~~~~~~~~~~
vim +961 net/wireless/nl80211.c
583
584 static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
585 [0] = { .strict_start_type = NL80211_ATTR_HE_OBSS_PD },
586 [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
587 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
588 .len = 20-1 },
589 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
590
591 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
592 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
593 [NL80211_ATTR_WIPHY_EDMG_CHANNELS] = NLA_POLICY_RANGE(NLA_U8,
594 NL80211_EDMG_CHANNELS_MIN,
595 NL80211_EDMG_CHANNELS_MAX),
596 [NL80211_ATTR_WIPHY_EDMG_BW_CONFIG] = NLA_POLICY_RANGE(NLA_U8,
597 NL80211_EDMG_BW_CONFIG_MIN,
598 NL80211_EDMG_BW_CONFIG_MAX),
599
600 [NL80211_ATTR_CHANNEL_WIDTH] = { .type = NLA_U32 },
601 [NL80211_ATTR_CENTER_FREQ1] = { .type = NLA_U32 },
602 [NL80211_ATTR_CENTER_FREQ1_OFFSET] = NLA_POLICY_RANGE(NLA_U32, 0, 999),
603 [NL80211_ATTR_CENTER_FREQ2] = { .type = NLA_U32 },
604
605 [NL80211_ATTR_WIPHY_RETRY_SHORT] = NLA_POLICY_MIN(NLA_U8, 1),
606 [NL80211_ATTR_WIPHY_RETRY_LONG] = NLA_POLICY_MIN(NLA_U8, 1),
607 [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
608 [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 },
609 [NL80211_ATTR_WIPHY_COVERAGE_CLASS] = { .type = NLA_U8 },
610 [NL80211_ATTR_WIPHY_DYN_ACK] = { .type = NLA_FLAG },
611
612 [NL80211_ATTR_IFTYPE] = NLA_POLICY_MAX(NLA_U32, NL80211_IFTYPE_MAX),
613 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
614 [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
615
616 [NL80211_ATTR_MAC] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
617 [NL80211_ATTR_PREV_BSSID] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
618
619 [NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
620 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
621 .len = WLAN_MAX_KEY_LEN },
622 [NL80211_ATTR_KEY_IDX] = NLA_POLICY_MAX(NLA_U8, 7),
623 [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
624 [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
625 [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
626 [NL80211_ATTR_KEY_TYPE] =
627 NLA_POLICY_MAX(NLA_U32, NUM_NL80211_KEYTYPES),
628
629 [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
630 [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
631 [NL80211_ATTR_BEACON_HEAD] =
632 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_beacon_head,
633 IEEE80211_MAX_DATA_LEN),
634 [NL80211_ATTR_BEACON_TAIL] =
635 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
636 IEEE80211_MAX_DATA_LEN),
637 [NL80211_ATTR_STA_AID] =
638 NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
639 [NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED },
640 [NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 },
641 [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY,
642 .len = NL80211_MAX_SUPP_RATES },
643 [NL80211_ATTR_STA_PLINK_ACTION] =
644 NLA_POLICY_MAX(NLA_U8, NUM_NL80211_PLINK_ACTIONS - 1),
645 [NL80211_ATTR_STA_TX_POWER_SETTING] =
646 NLA_POLICY_RANGE(NLA_U8,
647 NL80211_TX_POWER_AUTOMATIC,
648 NL80211_TX_POWER_FIXED),
649 [NL80211_ATTR_STA_TX_POWER] = { .type = NLA_S16 },
650 [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
651 [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ },
652 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
653 .len = IEEE80211_MAX_MESH_ID_LEN },
654 [NL80211_ATTR_MPATH_NEXT_HOP] = NLA_POLICY_ETH_ADDR_COMPAT,
655
656 /* allow 3 for NUL-termination, we used to declare this NLA_STRING */
657 [NL80211_ATTR_REG_ALPHA2] = NLA_POLICY_RANGE(NLA_BINARY, 2, 3),
658 [NL80211_ATTR_REG_RULES] = { .type = NLA_NESTED },
659
660 [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 },
661 [NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 },
662 [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 },
663 [NL80211_ATTR_BSS_BASIC_RATES] = { .type = NLA_BINARY,
664 .len = NL80211_MAX_SUPP_RATES },
665 [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 },
666
667 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
668 [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
669
670 [NL80211_ATTR_HT_CAPABILITY] = NLA_POLICY_EXACT_LEN_WARN(NL80211_HT_CAPABILITY_LEN),
671
672 [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
673 [NL80211_ATTR_IE] = NLA_POLICY_VALIDATE_FN(NLA_BINARY,
674 validate_ie_attr,
675 IEEE80211_MAX_DATA_LEN),
676 [NL80211_ATTR_SCAN_FREQUENCIES] = { .type = NLA_NESTED },
677 [NL80211_ATTR_SCAN_SSIDS] = { .type = NLA_NESTED },
678
679 [NL80211_ATTR_SSID] = { .type = NLA_BINARY,
680 .len = IEEE80211_MAX_SSID_LEN },
681 [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 },
682 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 },
683 [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG },
684 [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG },
685 [NL80211_ATTR_USE_MFP] = NLA_POLICY_RANGE(NLA_U32,
686 NL80211_MFP_NO,
687 NL80211_MFP_OPTIONAL),
688 [NL80211_ATTR_STA_FLAGS2] =
689 NLA_POLICY_EXACT_LEN_WARN(sizeof(struct nl80211_sta_flag_update)),
690 [NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG },
691 [NL80211_ATTR_CONTROL_PORT_ETHERTYPE] = { .type = NLA_U16 },
692 [NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG },
693 [NL80211_ATTR_CONTROL_PORT_OVER_NL80211] = { .type = NLA_FLAG },
694 [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG },
695 [NL80211_ATTR_STATUS_CODE] = { .type = NLA_U16 },
696 [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 },
697 [NL80211_ATTR_WPA_VERSIONS] =
698 NLA_POLICY_RANGE(NLA_U32, 0,
699 NL80211_WPA_VERSION_1 |
700 NL80211_WPA_VERSION_2 |
701 NL80211_WPA_VERSION_3),
702 [NL80211_ATTR_PID] = { .type = NLA_U32 },
703 [NL80211_ATTR_4ADDR] = { .type = NLA_U8 },
704 [NL80211_ATTR_PMKID] = NLA_POLICY_EXACT_LEN_WARN(WLAN_PMKID_LEN),
705 [NL80211_ATTR_DURATION] = { .type = NLA_U32 },
706 [NL80211_ATTR_COOKIE] = { .type = NLA_U64 },
707 [NL80211_ATTR_TX_RATES] = { .type = NLA_NESTED },
708 [NL80211_ATTR_FRAME] = { .type = NLA_BINARY,
709 .len = IEEE80211_MAX_DATA_LEN },
710 [NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, },
711 [NL80211_ATTR_PS_STATE] = NLA_POLICY_RANGE(NLA_U32,
712 NL80211_PS_DISABLED,
713 NL80211_PS_ENABLED),
714 [NL80211_ATTR_CQM] = { .type = NLA_NESTED, },
715 [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG },
716 [NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 },
717 [NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 },
718 [NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 },
719 [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 },
720 [NL80211_ATTR_WIPHY_ANTENNA_TX] = { .type = NLA_U32 },
721 [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 },
722 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
723 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
724 [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
725 [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED },
726 [NL80211_ATTR_STA_PLINK_STATE] =
727 NLA_POLICY_MAX(NLA_U8, NUM_NL80211_PLINK_STATES - 1),
728 [NL80211_ATTR_MEASUREMENT_DURATION] = { .type = NLA_U16 },
729 [NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY] = { .type = NLA_FLAG },
730 [NL80211_ATTR_MESH_PEER_AID] =
731 NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
732 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
733 [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
734 [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
735 [NL80211_ATTR_HIDDEN_SSID] =
736 NLA_POLICY_RANGE(NLA_U32,
737 NL80211_HIDDEN_SSID_NOT_IN_USE,
738 NL80211_HIDDEN_SSID_ZERO_CONTENTS),
739 [NL80211_ATTR_IE_PROBE_RESP] =
740 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
741 IEEE80211_MAX_DATA_LEN),
742 [NL80211_ATTR_IE_ASSOC_RESP] =
743 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
744 IEEE80211_MAX_DATA_LEN),
745 [NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG },
746 [NL80211_ATTR_STA_WME] = NLA_POLICY_NESTED(nl80211_sta_wme_policy),
747 [NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED },
748 [NL80211_ATTR_TX_NO_CCK_RATE] = { .type = NLA_FLAG },
749 [NL80211_ATTR_TDLS_ACTION] = { .type = NLA_U8 },
750 [NL80211_ATTR_TDLS_DIALOG_TOKEN] = { .type = NLA_U8 },
751 [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
752 [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
753 [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
754 [NL80211_ATTR_TDLS_INITIATOR] = { .type = NLA_FLAG },
755 [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG },
756 [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY,
757 .len = IEEE80211_MAX_DATA_LEN },
758 [NL80211_ATTR_DFS_REGION] = { .type = NLA_U8 },
759 [NL80211_ATTR_DISABLE_HT] = { .type = NLA_FLAG },
760 [NL80211_ATTR_HT_CAPABILITY_MASK] = {
761 .len = NL80211_HT_CAPABILITY_LEN
762 },
763 [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 },
764 [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 },
765 [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 },
766 [NL80211_ATTR_WDEV] = { .type = NLA_U64 },
767 [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 },
768
769 /* need to include at least Auth Transaction and Status Code */
770 [NL80211_ATTR_AUTH_DATA] = NLA_POLICY_MIN_LEN(4),
771
772 [NL80211_ATTR_VHT_CAPABILITY] = NLA_POLICY_EXACT_LEN_WARN(NL80211_VHT_CAPABILITY_LEN),
773 [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
774 [NL80211_ATTR_P2P_CTWINDOW] = NLA_POLICY_MAX(NLA_U8, 127),
775 [NL80211_ATTR_P2P_OPPPS] = NLA_POLICY_MAX(NLA_U8, 1),
776 [NL80211_ATTR_LOCAL_MESH_POWER_MODE] =
777 NLA_POLICY_RANGE(NLA_U32,
778 NL80211_MESH_POWER_UNKNOWN + 1,
779 NL80211_MESH_POWER_MAX),
780 [NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 },
781 [NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED },
782 [NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },
783 [NL80211_ATTR_STA_EXT_CAPABILITY] = { .type = NLA_BINARY, },
784 [NL80211_ATTR_SPLIT_WIPHY_DUMP] = { .type = NLA_FLAG, },
785 [NL80211_ATTR_DISABLE_VHT] = { .type = NLA_FLAG },
786 [NL80211_ATTR_VHT_CAPABILITY_MASK] = {
787 .len = NL80211_VHT_CAPABILITY_LEN,
788 },
789 [NL80211_ATTR_MDID] = { .type = NLA_U16 },
790 [NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
791 .len = IEEE80211_MAX_DATA_LEN },
792 [NL80211_ATTR_CRIT_PROT_ID] = { .type = NLA_U16 },
793 [NL80211_ATTR_MAX_CRIT_PROT_DURATION] =
794 NLA_POLICY_MAX(NLA_U16, NL80211_CRIT_PROTO_MAX_DURATION),
795 [NL80211_ATTR_PEER_AID] =
796 NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
797 [NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 },
798 [NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG },
799 [NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED },
800 [NL80211_ATTR_CNTDWN_OFFS_BEACON] = { .type = NLA_BINARY },
801 [NL80211_ATTR_CNTDWN_OFFS_PRESP] = { .type = NLA_BINARY },
802 [NL80211_ATTR_STA_SUPPORTED_CHANNELS] = NLA_POLICY_MIN_LEN(2),
803 /*
804 * The value of the Length field of the Supported Operating
805 * Classes element is between 2 and 253.
806 */
807 [NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] =
808 NLA_POLICY_RANGE(NLA_BINARY, 2, 253),
809 [NL80211_ATTR_HANDLE_DFS] = { .type = NLA_FLAG },
810 [NL80211_ATTR_OPMODE_NOTIF] = { .type = NLA_U8 },
811 [NL80211_ATTR_VENDOR_ID] = { .type = NLA_U32 },
812 [NL80211_ATTR_VENDOR_SUBCMD] = { .type = NLA_U32 },
813 [NL80211_ATTR_VENDOR_DATA] = { .type = NLA_BINARY },
814 [NL80211_ATTR_QOS_MAP] = NLA_POLICY_RANGE(NLA_BINARY,
815 IEEE80211_QOS_MAP_LEN_MIN,
816 IEEE80211_QOS_MAP_LEN_MAX),
817 [NL80211_ATTR_MAC_HINT] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
818 [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 },
819 [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 },
820 [NL80211_ATTR_SOCKET_OWNER] = { .type = NLA_FLAG },
821 [NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY },
822 [NL80211_ATTR_USE_RRM] = { .type = NLA_FLAG },
823 [NL80211_ATTR_TSID] = NLA_POLICY_MAX(NLA_U8, IEEE80211_NUM_TIDS - 1),
824 [NL80211_ATTR_USER_PRIO] =
825 NLA_POLICY_MAX(NLA_U8, IEEE80211_NUM_UPS - 1),
826 [NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 },
827 [NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 },
828 [NL80211_ATTR_OPER_CLASS] = { .type = NLA_U8 },
829 [NL80211_ATTR_MAC_MASK] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
830 [NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG },
831 [NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 },
832 [NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 },
833 [NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG },
834 [NL80211_ATTR_PBSS] = { .type = NLA_FLAG },
835 [NL80211_ATTR_BSS_SELECT] = { .type = NLA_NESTED },
836 [NL80211_ATTR_STA_SUPPORT_P2P_PS] =
837 NLA_POLICY_MAX(NLA_U8, NUM_NL80211_P2P_PS_STATUS - 1),
838 [NL80211_ATTR_MU_MIMO_GROUP_DATA] = {
839 .len = VHT_MUMIMO_GROUPS_DATA_LEN
840 },
841 [NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
842 [NL80211_ATTR_NAN_MASTER_PREF] = NLA_POLICY_MIN(NLA_U8, 1),
843 [NL80211_ATTR_BANDS] = { .type = NLA_U32 },
844 [NL80211_ATTR_NAN_CONFIG] = NLA_POLICY_NESTED(nl80211_nan_conf_policy),
845 [NL80211_ATTR_NAN_FUNC] = { .type = NLA_NESTED },
846 [NL80211_ATTR_FILS_KEK] = { .type = NLA_BINARY,
847 .len = FILS_MAX_KEK_LEN },
848 [NL80211_ATTR_FILS_NONCES] = NLA_POLICY_EXACT_LEN_WARN(2 * FILS_NONCE_LEN),
849 [NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED] = { .type = NLA_FLAG, },
850 [NL80211_ATTR_BSSID] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
851 [NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI] = { .type = NLA_S8 },
852 [NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST] = {
853 .len = sizeof(struct nl80211_bss_select_rssi_adjust)
854 },
855 [NL80211_ATTR_TIMEOUT_REASON] = { .type = NLA_U32 },
856 [NL80211_ATTR_FILS_ERP_USERNAME] = { .type = NLA_BINARY,
857 .len = FILS_ERP_MAX_USERNAME_LEN },
858 [NL80211_ATTR_FILS_ERP_REALM] = { .type = NLA_BINARY,
859 .len = FILS_ERP_MAX_REALM_LEN },
860 [NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] = { .type = NLA_U16 },
861 [NL80211_ATTR_FILS_ERP_RRK] = { .type = NLA_BINARY,
862 .len = FILS_ERP_MAX_RRK_LEN },
863 [NL80211_ATTR_FILS_CACHE_ID] = NLA_POLICY_EXACT_LEN_WARN(2),
864 [NL80211_ATTR_PMK] = { .type = NLA_BINARY, .len = PMK_MAX_LEN },
865 [NL80211_ATTR_PMKR0_NAME] = NLA_POLICY_EXACT_LEN(WLAN_PMK_NAME_LEN),
866 [NL80211_ATTR_SCHED_SCAN_MULTI] = { .type = NLA_FLAG },
867 [NL80211_ATTR_EXTERNAL_AUTH_SUPPORT] = { .type = NLA_FLAG },
868
869 [NL80211_ATTR_TXQ_LIMIT] = { .type = NLA_U32 },
870 [NL80211_ATTR_TXQ_MEMORY_LIMIT] = { .type = NLA_U32 },
871 [NL80211_ATTR_TXQ_QUANTUM] = NLA_POLICY_FULL_RANGE(NLA_U32, &q_range),
872 [NL80211_ATTR_HE_CAPABILITY] =
873 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_he_capa,
874 NL80211_HE_MAX_CAPABILITY_LEN),
875 [NL80211_ATTR_FTM_RESPONDER] =
876 NLA_POLICY_NESTED(nl80211_ftm_responder_policy),
877 [NL80211_ATTR_TIMEOUT] = NLA_POLICY_MIN(NLA_U32, 1),
878 [NL80211_ATTR_PEER_MEASUREMENTS] =
879 NLA_POLICY_NESTED(nl80211_pmsr_attr_policy),
880 [NL80211_ATTR_AIRTIME_WEIGHT] = NLA_POLICY_MIN(NLA_U16, 1),
881 [NL80211_ATTR_SAE_PASSWORD] = { .type = NLA_BINARY,
882 .len = SAE_PASSWORD_MAX_LEN },
883 [NL80211_ATTR_TWT_RESPONDER] = { .type = NLA_FLAG },
884 [NL80211_ATTR_HE_OBSS_PD] = NLA_POLICY_NESTED(he_obss_pd_policy),
885 [NL80211_ATTR_VLAN_ID] = NLA_POLICY_RANGE(NLA_U16, 1, VLAN_N_VID - 2),
886 [NL80211_ATTR_HE_BSS_COLOR] = NLA_POLICY_NESTED(he_bss_color_policy),
887 [NL80211_ATTR_TID_CONFIG] =
888 NLA_POLICY_NESTED_ARRAY(nl80211_tid_config_attr_policy),
889 [NL80211_ATTR_CONTROL_PORT_NO_PREAUTH] = { .type = NLA_FLAG },
890 [NL80211_ATTR_PMK_LIFETIME] = NLA_POLICY_MIN(NLA_U32, 1),
891 [NL80211_ATTR_PMK_REAUTH_THRESHOLD] = NLA_POLICY_RANGE(NLA_U8, 1, 100),
892 [NL80211_ATTR_RECEIVE_MULTICAST] = { .type = NLA_FLAG },
893 [NL80211_ATTR_WIPHY_FREQ_OFFSET] = NLA_POLICY_RANGE(NLA_U32, 0, 999),
894 [NL80211_ATTR_SCAN_FREQ_KHZ] = { .type = NLA_NESTED },
895 [NL80211_ATTR_HE_6GHZ_CAPABILITY] =
896 NLA_POLICY_EXACT_LEN(sizeof(struct ieee80211_he_6ghz_capa)),
897 [NL80211_ATTR_FILS_DISCOVERY] =
898 NLA_POLICY_NESTED(nl80211_fils_discovery_policy),
899 [NL80211_ATTR_UNSOL_BCAST_PROBE_RESP] =
900 NLA_POLICY_NESTED(nl80211_unsol_bcast_probe_resp_policy),
901 [NL80211_ATTR_S1G_CAPABILITY] =
902 NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
903 [NL80211_ATTR_S1G_CAPABILITY_MASK] =
904 NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
905 [NL80211_ATTR_SAE_PWE] =
906 NLA_POLICY_RANGE(NLA_U8, NL80211_SAE_PWE_HUNT_AND_PECK,
907 NL80211_SAE_PWE_BOTH),
908 [NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT },
909 [NL80211_ATTR_SAR_SPEC] = NLA_POLICY_NESTED(sar_policy),
910 [NL80211_ATTR_DISABLE_HE] = { .type = NLA_FLAG },
911 [NL80211_ATTR_OBSS_COLOR_BITMAP] = { .type = NLA_U64 },
912 [NL80211_ATTR_COLOR_CHANGE_COUNT] = { .type = NLA_U8 },
913 [NL80211_ATTR_COLOR_CHANGE_COLOR] = { .type = NLA_U8 },
914 [NL80211_ATTR_COLOR_CHANGE_ELEMS] = NLA_POLICY_NESTED(nl80211_policy),
915 [NL80211_ATTR_MBSSID_CONFIG] =
916 NLA_POLICY_NESTED(nl80211_mbssid_config_policy),
917 [NL80211_ATTR_MBSSID_ELEMS] = { .type = NLA_NESTED },
918 [NL80211_ATTR_RADAR_BACKGROUND] = { .type = NLA_FLAG },
919 [NL80211_ATTR_AP_SETTINGS_FLAGS] = { .type = NLA_U32 },
920 [NL80211_ATTR_EHT_CAPABILITY] =
921 NLA_POLICY_RANGE(NLA_BINARY,
922 NL80211_EHT_MIN_CAPABILITY_LEN,
923 NL80211_EHT_MAX_CAPABILITY_LEN),
924 [NL80211_ATTR_DISABLE_EHT] = { .type = NLA_FLAG },
925 [NL80211_ATTR_MLO_LINKS] =
926 NLA_POLICY_NESTED_ARRAY(nl80211_policy),
927 [NL80211_ATTR_MLO_LINK_ID] =
928 NLA_POLICY_RANGE(NLA_U8, 0, IEEE80211_MLD_MAX_NUM_LINKS - 1),
929 [NL80211_ATTR_MLD_ADDR] = NLA_POLICY_EXACT_LEN(ETH_ALEN),
930 [NL80211_ATTR_MLO_SUPPORT] = { .type = NLA_FLAG },
931 [NL80211_ATTR_MAX_NUM_AKM_SUITES] = { .type = NLA_REJECT },
932 [NL80211_ATTR_EML_CAPABILITY] = { .type = NLA_U16 },
933 [NL80211_ATTR_PUNCT_BITMAP] =
934 NLA_POLICY_FULL_RANGE(NLA_U32, &nl80211_punct_bitmap_range),
935
936 [NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS] = { .type = NLA_U16 },
937 [NL80211_ATTR_HW_TIMESTAMP_ENABLED] = { .type = NLA_FLAG },
938 [NL80211_ATTR_EMA_RNR_ELEMS] = { .type = NLA_NESTED },
939 [NL80211_ATTR_MLO_LINK_DISABLED] = { .type = NLA_FLAG },
940 [NL80211_ATTR_BSS_DUMP_INCLUDE_USE_DATA] = { .type = NLA_FLAG },
941 [NL80211_ATTR_MLO_TTLM_DLINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8),
942 [NL80211_ATTR_MLO_TTLM_ULINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8),
943 [NL80211_ATTR_ASSOC_SPP_AMSDU] = { .type = NLA_FLAG },
944 [NL80211_ATTR_VIF_RADIO_MASK] = { .type = NLA_U32 },
945 [NL80211_ATTR_SUPPORTED_SELECTORS] =
946 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_supported_selectors,
947 NL80211_MAX_SUPP_SELECTORS),
948 [NL80211_ATTR_MLO_RECONF_REM_LINKS] = { .type = NLA_U16 },
949 [NL80211_ATTR_EPCS] = { .type = NLA_FLAG },
950 [NL80211_ATTR_ASSOC_MLD_EXT_CAPA_OPS] = { .type = NLA_U16 },
951 [NL80211_ATTR_WIPHY_RADIO_INDEX] = { .type = NLA_U8 },
952 [NL80211_ATTR_S1G_LONG_BEACON_PERIOD] = NLA_POLICY_MIN(NLA_U8, 2),
953 [NL80211_ATTR_S1G_SHORT_BEACON] =
954 NLA_POLICY_NESTED(nl80211_s1g_short_beacon),
955 [NL80211_ATTR_BSS_PARAM] = { .type = NLA_FLAG },
956 [NL80211_ATTR_S1G_PRIMARY_2MHZ] = { .type = NLA_FLAG },
957 [NL80211_ATTR_EPP_PEER] = { .type = NLA_FLAG },
958 [NL80211_ATTR_UHR_CAPABILITY] =
959 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_uhr_capa, 255),
960 [NL80211_ATTR_DISABLE_UHR] = { .type = NLA_FLAG },
> 961 [[NL80211_ATTR_UHR_OPERATION] =
962 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_uhr_operation),
963 };
964
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: New warning `ath10k_pci 0000:3a:00.0: not found station for peer stats`
From: Paul Menzel @ 2026-03-03 20:01 UTC (permalink / raw)
To: Baochen Qiang, Jeff Johnson; +Cc: linux-wireless, ath10k
In-Reply-To: <badaf39e-6ab7-4be7-944a-cfc9d6757db2@oss.qualcomm.com>
Dear Baochen,
Am 11.02.26 um 06:43 schrieb Baochen Qiang:
> On 2/10/2026 6:31 AM, Paul Menzel wrote:
>> Am 09.02.26 um 03:44 schrieb Baochen Qiang:
>>
>>> On 2/7/2026 1:55 PM, Paul Menzel wrote:
>>
>>>> Am 19.01.26 um 17:41 schrieb Paul Menzel:
>>>>
>>>>> Since January 10th, I have started seeing the warning below in
>>>>> my Linux logs, that reach back to September 24th, 2025:
>>>>>
>>>>> [ 37.108902] ath10k_pci 0000:3a:00.0: not found station for peer stats
>>>>> [ 37.108906] ath10k_pci 0000:3a:00.0: failed to parse stats info tlv: -22
>>>>>
>>>>> It started appearing with 6.19.0-rc4-00282-gb6151c4e60e5, the
>>>>> version running before is 6.19.0-rc4-00003-g3609fa95fb0f, but I
>>>>> do not see anything related in the commit list:
>>>>>
>>>>> git log --oneline 3609fa95fb0f...b6151c4e60e5
>>>>>
>>>>> The warning log from `drivers/net/wireless/ath/ath10k/wmi-tlv.c` has also been there
>>>>> since 2021.
>>>>>
>>>>> Do you have an idea? Please find the output of `dmesg` attached.
>>>>
>>>> Looking through the commit list from above again, commit
>>>> a203dbeeca15 (wifi: mac80211: collect station statistics earlier
>>>> when disconnect) probably introduced the new behavior.
>>>
>>> is this error seen when disconnecting from AP?
>>
>> I attached the logs in my first message. But yes, it looks like this:
>
> sorry, didn't notice there was an attachment.
>
>>
>> Feb 07 06:32:52 abreu kernel: wlp58s0: deauthenticating from 74:1a:e0:e7:b4:c8 by local choice (Reason: 3=DEAUTH_LEAVING)
>> Feb 07 06:32:52 abreu kernel: ath10k_pci 0000:3a:00.0: not found station for peer stats
>> Feb 07 06:32:52 abreu kernel: ath10k_pci 0000:3a:00.0: failed to parse stats info tlv: -22
>> Feb 07 06:32:52 abreu wpa_supplicant[846]: wlp58s0: CTRL-EVENT-DISCONNECTED bssid=74:1a:e0:e7:b4:c8 reason=3 locally_generated=1
>> Feb 07 06:32:52 abreu wpa_supplicant[846]: BSSID 74:1a:e0:e7:b4:c8 ignore list count incremented to 2, ignoring for 10 seconds
>>
>>> did you try with that commit reverted?
>>
>> Yes, I tried it now with Linux 6.19 and reverting the commit. The warnings are gone now.
>>
>> Are you able to reproduce the issue? What devices are you testing with?
>
> I managed to reproduce this issue locally. Will submit a patch fixing it.
Sorry for being impatient, but as Linux 7.0-rc2 was tagged, were you
able to come up with a patch, or should the commit be reverted for now
to have more time to analyze this?
Kind regards,
Paul
^ permalink raw reply
* Re: [PATCH wireless-next] wifi: nl80211: split out UHR operation information
From: kernel test robot @ 2026-03-03 19:59 UTC (permalink / raw)
To: Johannes Berg, linux-wireless; +Cc: llvm, oe-kbuild-all, Johannes Berg
In-Reply-To: <20260303152558.00e7bc8e9f4b.Iafdf37fb0f4304bdcdb824977d61e17b38c47685@changeid>
Hi Johannes,
kernel test robot noticed the following build errors:
[auto build test ERROR on wireless-next/main]
[also build test ERROR on next-20260303]
[cannot apply to wireless/main linus/master v6.16-rc1]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Johannes-Berg/wifi-nl80211-split-out-UHR-operation-information/20260303-223359
base: https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next.git main
patch link: https://lore.kernel.org/r/20260303152558.00e7bc8e9f4b.Iafdf37fb0f4304bdcdb824977d61e17b38c47685%40changeid
patch subject: [PATCH wireless-next] wifi: nl80211: split out UHR operation information
config: x86_64-kexec (https://download.01.org/0day-ci/archive/20260303/202603032000.hvuqXXkv-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260303/202603032000.hvuqXXkv-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603032000.hvuqXXkv-lkp@intel.com/
All errors (new ones prefixed by >>):
>> net/wireless/nl80211.c:961:3: error: expected expression
961 | [[NL80211_ATTR_UHR_OPERATION] =
| ^
1 error generated.
vim +961 net/wireless/nl80211.c
583
584 static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
585 [0] = { .strict_start_type = NL80211_ATTR_HE_OBSS_PD },
586 [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
587 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
588 .len = 20-1 },
589 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
590
591 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
592 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
593 [NL80211_ATTR_WIPHY_EDMG_CHANNELS] = NLA_POLICY_RANGE(NLA_U8,
594 NL80211_EDMG_CHANNELS_MIN,
595 NL80211_EDMG_CHANNELS_MAX),
596 [NL80211_ATTR_WIPHY_EDMG_BW_CONFIG] = NLA_POLICY_RANGE(NLA_U8,
597 NL80211_EDMG_BW_CONFIG_MIN,
598 NL80211_EDMG_BW_CONFIG_MAX),
599
600 [NL80211_ATTR_CHANNEL_WIDTH] = { .type = NLA_U32 },
601 [NL80211_ATTR_CENTER_FREQ1] = { .type = NLA_U32 },
602 [NL80211_ATTR_CENTER_FREQ1_OFFSET] = NLA_POLICY_RANGE(NLA_U32, 0, 999),
603 [NL80211_ATTR_CENTER_FREQ2] = { .type = NLA_U32 },
604
605 [NL80211_ATTR_WIPHY_RETRY_SHORT] = NLA_POLICY_MIN(NLA_U8, 1),
606 [NL80211_ATTR_WIPHY_RETRY_LONG] = NLA_POLICY_MIN(NLA_U8, 1),
607 [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
608 [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 },
609 [NL80211_ATTR_WIPHY_COVERAGE_CLASS] = { .type = NLA_U8 },
610 [NL80211_ATTR_WIPHY_DYN_ACK] = { .type = NLA_FLAG },
611
612 [NL80211_ATTR_IFTYPE] = NLA_POLICY_MAX(NLA_U32, NL80211_IFTYPE_MAX),
613 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
614 [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
615
616 [NL80211_ATTR_MAC] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
617 [NL80211_ATTR_PREV_BSSID] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
618
619 [NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
620 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
621 .len = WLAN_MAX_KEY_LEN },
622 [NL80211_ATTR_KEY_IDX] = NLA_POLICY_MAX(NLA_U8, 7),
623 [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
624 [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
625 [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
626 [NL80211_ATTR_KEY_TYPE] =
627 NLA_POLICY_MAX(NLA_U32, NUM_NL80211_KEYTYPES),
628
629 [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
630 [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
631 [NL80211_ATTR_BEACON_HEAD] =
632 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_beacon_head,
633 IEEE80211_MAX_DATA_LEN),
634 [NL80211_ATTR_BEACON_TAIL] =
635 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
636 IEEE80211_MAX_DATA_LEN),
637 [NL80211_ATTR_STA_AID] =
638 NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
639 [NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED },
640 [NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 },
641 [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY,
642 .len = NL80211_MAX_SUPP_RATES },
643 [NL80211_ATTR_STA_PLINK_ACTION] =
644 NLA_POLICY_MAX(NLA_U8, NUM_NL80211_PLINK_ACTIONS - 1),
645 [NL80211_ATTR_STA_TX_POWER_SETTING] =
646 NLA_POLICY_RANGE(NLA_U8,
647 NL80211_TX_POWER_AUTOMATIC,
648 NL80211_TX_POWER_FIXED),
649 [NL80211_ATTR_STA_TX_POWER] = { .type = NLA_S16 },
650 [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
651 [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ },
652 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
653 .len = IEEE80211_MAX_MESH_ID_LEN },
654 [NL80211_ATTR_MPATH_NEXT_HOP] = NLA_POLICY_ETH_ADDR_COMPAT,
655
656 /* allow 3 for NUL-termination, we used to declare this NLA_STRING */
657 [NL80211_ATTR_REG_ALPHA2] = NLA_POLICY_RANGE(NLA_BINARY, 2, 3),
658 [NL80211_ATTR_REG_RULES] = { .type = NLA_NESTED },
659
660 [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 },
661 [NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 },
662 [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 },
663 [NL80211_ATTR_BSS_BASIC_RATES] = { .type = NLA_BINARY,
664 .len = NL80211_MAX_SUPP_RATES },
665 [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 },
666
667 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
668 [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
669
670 [NL80211_ATTR_HT_CAPABILITY] = NLA_POLICY_EXACT_LEN_WARN(NL80211_HT_CAPABILITY_LEN),
671
672 [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
673 [NL80211_ATTR_IE] = NLA_POLICY_VALIDATE_FN(NLA_BINARY,
674 validate_ie_attr,
675 IEEE80211_MAX_DATA_LEN),
676 [NL80211_ATTR_SCAN_FREQUENCIES] = { .type = NLA_NESTED },
677 [NL80211_ATTR_SCAN_SSIDS] = { .type = NLA_NESTED },
678
679 [NL80211_ATTR_SSID] = { .type = NLA_BINARY,
680 .len = IEEE80211_MAX_SSID_LEN },
681 [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 },
682 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 },
683 [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG },
684 [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG },
685 [NL80211_ATTR_USE_MFP] = NLA_POLICY_RANGE(NLA_U32,
686 NL80211_MFP_NO,
687 NL80211_MFP_OPTIONAL),
688 [NL80211_ATTR_STA_FLAGS2] =
689 NLA_POLICY_EXACT_LEN_WARN(sizeof(struct nl80211_sta_flag_update)),
690 [NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG },
691 [NL80211_ATTR_CONTROL_PORT_ETHERTYPE] = { .type = NLA_U16 },
692 [NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG },
693 [NL80211_ATTR_CONTROL_PORT_OVER_NL80211] = { .type = NLA_FLAG },
694 [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG },
695 [NL80211_ATTR_STATUS_CODE] = { .type = NLA_U16 },
696 [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 },
697 [NL80211_ATTR_WPA_VERSIONS] =
698 NLA_POLICY_RANGE(NLA_U32, 0,
699 NL80211_WPA_VERSION_1 |
700 NL80211_WPA_VERSION_2 |
701 NL80211_WPA_VERSION_3),
702 [NL80211_ATTR_PID] = { .type = NLA_U32 },
703 [NL80211_ATTR_4ADDR] = { .type = NLA_U8 },
704 [NL80211_ATTR_PMKID] = NLA_POLICY_EXACT_LEN_WARN(WLAN_PMKID_LEN),
705 [NL80211_ATTR_DURATION] = { .type = NLA_U32 },
706 [NL80211_ATTR_COOKIE] = { .type = NLA_U64 },
707 [NL80211_ATTR_TX_RATES] = { .type = NLA_NESTED },
708 [NL80211_ATTR_FRAME] = { .type = NLA_BINARY,
709 .len = IEEE80211_MAX_DATA_LEN },
710 [NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, },
711 [NL80211_ATTR_PS_STATE] = NLA_POLICY_RANGE(NLA_U32,
712 NL80211_PS_DISABLED,
713 NL80211_PS_ENABLED),
714 [NL80211_ATTR_CQM] = { .type = NLA_NESTED, },
715 [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG },
716 [NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 },
717 [NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 },
718 [NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 },
719 [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 },
720 [NL80211_ATTR_WIPHY_ANTENNA_TX] = { .type = NLA_U32 },
721 [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 },
722 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
723 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
724 [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
725 [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED },
726 [NL80211_ATTR_STA_PLINK_STATE] =
727 NLA_POLICY_MAX(NLA_U8, NUM_NL80211_PLINK_STATES - 1),
728 [NL80211_ATTR_MEASUREMENT_DURATION] = { .type = NLA_U16 },
729 [NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY] = { .type = NLA_FLAG },
730 [NL80211_ATTR_MESH_PEER_AID] =
731 NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
732 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
733 [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
734 [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
735 [NL80211_ATTR_HIDDEN_SSID] =
736 NLA_POLICY_RANGE(NLA_U32,
737 NL80211_HIDDEN_SSID_NOT_IN_USE,
738 NL80211_HIDDEN_SSID_ZERO_CONTENTS),
739 [NL80211_ATTR_IE_PROBE_RESP] =
740 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
741 IEEE80211_MAX_DATA_LEN),
742 [NL80211_ATTR_IE_ASSOC_RESP] =
743 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
744 IEEE80211_MAX_DATA_LEN),
745 [NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG },
746 [NL80211_ATTR_STA_WME] = NLA_POLICY_NESTED(nl80211_sta_wme_policy),
747 [NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED },
748 [NL80211_ATTR_TX_NO_CCK_RATE] = { .type = NLA_FLAG },
749 [NL80211_ATTR_TDLS_ACTION] = { .type = NLA_U8 },
750 [NL80211_ATTR_TDLS_DIALOG_TOKEN] = { .type = NLA_U8 },
751 [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
752 [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
753 [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
754 [NL80211_ATTR_TDLS_INITIATOR] = { .type = NLA_FLAG },
755 [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG },
756 [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY,
757 .len = IEEE80211_MAX_DATA_LEN },
758 [NL80211_ATTR_DFS_REGION] = { .type = NLA_U8 },
759 [NL80211_ATTR_DISABLE_HT] = { .type = NLA_FLAG },
760 [NL80211_ATTR_HT_CAPABILITY_MASK] = {
761 .len = NL80211_HT_CAPABILITY_LEN
762 },
763 [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 },
764 [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 },
765 [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 },
766 [NL80211_ATTR_WDEV] = { .type = NLA_U64 },
767 [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 },
768
769 /* need to include at least Auth Transaction and Status Code */
770 [NL80211_ATTR_AUTH_DATA] = NLA_POLICY_MIN_LEN(4),
771
772 [NL80211_ATTR_VHT_CAPABILITY] = NLA_POLICY_EXACT_LEN_WARN(NL80211_VHT_CAPABILITY_LEN),
773 [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
774 [NL80211_ATTR_P2P_CTWINDOW] = NLA_POLICY_MAX(NLA_U8, 127),
775 [NL80211_ATTR_P2P_OPPPS] = NLA_POLICY_MAX(NLA_U8, 1),
776 [NL80211_ATTR_LOCAL_MESH_POWER_MODE] =
777 NLA_POLICY_RANGE(NLA_U32,
778 NL80211_MESH_POWER_UNKNOWN + 1,
779 NL80211_MESH_POWER_MAX),
780 [NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 },
781 [NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED },
782 [NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },
783 [NL80211_ATTR_STA_EXT_CAPABILITY] = { .type = NLA_BINARY, },
784 [NL80211_ATTR_SPLIT_WIPHY_DUMP] = { .type = NLA_FLAG, },
785 [NL80211_ATTR_DISABLE_VHT] = { .type = NLA_FLAG },
786 [NL80211_ATTR_VHT_CAPABILITY_MASK] = {
787 .len = NL80211_VHT_CAPABILITY_LEN,
788 },
789 [NL80211_ATTR_MDID] = { .type = NLA_U16 },
790 [NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
791 .len = IEEE80211_MAX_DATA_LEN },
792 [NL80211_ATTR_CRIT_PROT_ID] = { .type = NLA_U16 },
793 [NL80211_ATTR_MAX_CRIT_PROT_DURATION] =
794 NLA_POLICY_MAX(NLA_U16, NL80211_CRIT_PROTO_MAX_DURATION),
795 [NL80211_ATTR_PEER_AID] =
796 NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
797 [NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 },
798 [NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG },
799 [NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED },
800 [NL80211_ATTR_CNTDWN_OFFS_BEACON] = { .type = NLA_BINARY },
801 [NL80211_ATTR_CNTDWN_OFFS_PRESP] = { .type = NLA_BINARY },
802 [NL80211_ATTR_STA_SUPPORTED_CHANNELS] = NLA_POLICY_MIN_LEN(2),
803 /*
804 * The value of the Length field of the Supported Operating
805 * Classes element is between 2 and 253.
806 */
807 [NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] =
808 NLA_POLICY_RANGE(NLA_BINARY, 2, 253),
809 [NL80211_ATTR_HANDLE_DFS] = { .type = NLA_FLAG },
810 [NL80211_ATTR_OPMODE_NOTIF] = { .type = NLA_U8 },
811 [NL80211_ATTR_VENDOR_ID] = { .type = NLA_U32 },
812 [NL80211_ATTR_VENDOR_SUBCMD] = { .type = NLA_U32 },
813 [NL80211_ATTR_VENDOR_DATA] = { .type = NLA_BINARY },
814 [NL80211_ATTR_QOS_MAP] = NLA_POLICY_RANGE(NLA_BINARY,
815 IEEE80211_QOS_MAP_LEN_MIN,
816 IEEE80211_QOS_MAP_LEN_MAX),
817 [NL80211_ATTR_MAC_HINT] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
818 [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 },
819 [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 },
820 [NL80211_ATTR_SOCKET_OWNER] = { .type = NLA_FLAG },
821 [NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY },
822 [NL80211_ATTR_USE_RRM] = { .type = NLA_FLAG },
823 [NL80211_ATTR_TSID] = NLA_POLICY_MAX(NLA_U8, IEEE80211_NUM_TIDS - 1),
824 [NL80211_ATTR_USER_PRIO] =
825 NLA_POLICY_MAX(NLA_U8, IEEE80211_NUM_UPS - 1),
826 [NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 },
827 [NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 },
828 [NL80211_ATTR_OPER_CLASS] = { .type = NLA_U8 },
829 [NL80211_ATTR_MAC_MASK] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
830 [NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG },
831 [NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 },
832 [NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 },
833 [NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG },
834 [NL80211_ATTR_PBSS] = { .type = NLA_FLAG },
835 [NL80211_ATTR_BSS_SELECT] = { .type = NLA_NESTED },
836 [NL80211_ATTR_STA_SUPPORT_P2P_PS] =
837 NLA_POLICY_MAX(NLA_U8, NUM_NL80211_P2P_PS_STATUS - 1),
838 [NL80211_ATTR_MU_MIMO_GROUP_DATA] = {
839 .len = VHT_MUMIMO_GROUPS_DATA_LEN
840 },
841 [NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
842 [NL80211_ATTR_NAN_MASTER_PREF] = NLA_POLICY_MIN(NLA_U8, 1),
843 [NL80211_ATTR_BANDS] = { .type = NLA_U32 },
844 [NL80211_ATTR_NAN_CONFIG] = NLA_POLICY_NESTED(nl80211_nan_conf_policy),
845 [NL80211_ATTR_NAN_FUNC] = { .type = NLA_NESTED },
846 [NL80211_ATTR_FILS_KEK] = { .type = NLA_BINARY,
847 .len = FILS_MAX_KEK_LEN },
848 [NL80211_ATTR_FILS_NONCES] = NLA_POLICY_EXACT_LEN_WARN(2 * FILS_NONCE_LEN),
849 [NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED] = { .type = NLA_FLAG, },
850 [NL80211_ATTR_BSSID] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
851 [NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI] = { .type = NLA_S8 },
852 [NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST] = {
853 .len = sizeof(struct nl80211_bss_select_rssi_adjust)
854 },
855 [NL80211_ATTR_TIMEOUT_REASON] = { .type = NLA_U32 },
856 [NL80211_ATTR_FILS_ERP_USERNAME] = { .type = NLA_BINARY,
857 .len = FILS_ERP_MAX_USERNAME_LEN },
858 [NL80211_ATTR_FILS_ERP_REALM] = { .type = NLA_BINARY,
859 .len = FILS_ERP_MAX_REALM_LEN },
860 [NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] = { .type = NLA_U16 },
861 [NL80211_ATTR_FILS_ERP_RRK] = { .type = NLA_BINARY,
862 .len = FILS_ERP_MAX_RRK_LEN },
863 [NL80211_ATTR_FILS_CACHE_ID] = NLA_POLICY_EXACT_LEN_WARN(2),
864 [NL80211_ATTR_PMK] = { .type = NLA_BINARY, .len = PMK_MAX_LEN },
865 [NL80211_ATTR_PMKR0_NAME] = NLA_POLICY_EXACT_LEN(WLAN_PMK_NAME_LEN),
866 [NL80211_ATTR_SCHED_SCAN_MULTI] = { .type = NLA_FLAG },
867 [NL80211_ATTR_EXTERNAL_AUTH_SUPPORT] = { .type = NLA_FLAG },
868
869 [NL80211_ATTR_TXQ_LIMIT] = { .type = NLA_U32 },
870 [NL80211_ATTR_TXQ_MEMORY_LIMIT] = { .type = NLA_U32 },
871 [NL80211_ATTR_TXQ_QUANTUM] = NLA_POLICY_FULL_RANGE(NLA_U32, &q_range),
872 [NL80211_ATTR_HE_CAPABILITY] =
873 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_he_capa,
874 NL80211_HE_MAX_CAPABILITY_LEN),
875 [NL80211_ATTR_FTM_RESPONDER] =
876 NLA_POLICY_NESTED(nl80211_ftm_responder_policy),
877 [NL80211_ATTR_TIMEOUT] = NLA_POLICY_MIN(NLA_U32, 1),
878 [NL80211_ATTR_PEER_MEASUREMENTS] =
879 NLA_POLICY_NESTED(nl80211_pmsr_attr_policy),
880 [NL80211_ATTR_AIRTIME_WEIGHT] = NLA_POLICY_MIN(NLA_U16, 1),
881 [NL80211_ATTR_SAE_PASSWORD] = { .type = NLA_BINARY,
882 .len = SAE_PASSWORD_MAX_LEN },
883 [NL80211_ATTR_TWT_RESPONDER] = { .type = NLA_FLAG },
884 [NL80211_ATTR_HE_OBSS_PD] = NLA_POLICY_NESTED(he_obss_pd_policy),
885 [NL80211_ATTR_VLAN_ID] = NLA_POLICY_RANGE(NLA_U16, 1, VLAN_N_VID - 2),
886 [NL80211_ATTR_HE_BSS_COLOR] = NLA_POLICY_NESTED(he_bss_color_policy),
887 [NL80211_ATTR_TID_CONFIG] =
888 NLA_POLICY_NESTED_ARRAY(nl80211_tid_config_attr_policy),
889 [NL80211_ATTR_CONTROL_PORT_NO_PREAUTH] = { .type = NLA_FLAG },
890 [NL80211_ATTR_PMK_LIFETIME] = NLA_POLICY_MIN(NLA_U32, 1),
891 [NL80211_ATTR_PMK_REAUTH_THRESHOLD] = NLA_POLICY_RANGE(NLA_U8, 1, 100),
892 [NL80211_ATTR_RECEIVE_MULTICAST] = { .type = NLA_FLAG },
893 [NL80211_ATTR_WIPHY_FREQ_OFFSET] = NLA_POLICY_RANGE(NLA_U32, 0, 999),
894 [NL80211_ATTR_SCAN_FREQ_KHZ] = { .type = NLA_NESTED },
895 [NL80211_ATTR_HE_6GHZ_CAPABILITY] =
896 NLA_POLICY_EXACT_LEN(sizeof(struct ieee80211_he_6ghz_capa)),
897 [NL80211_ATTR_FILS_DISCOVERY] =
898 NLA_POLICY_NESTED(nl80211_fils_discovery_policy),
899 [NL80211_ATTR_UNSOL_BCAST_PROBE_RESP] =
900 NLA_POLICY_NESTED(nl80211_unsol_bcast_probe_resp_policy),
901 [NL80211_ATTR_S1G_CAPABILITY] =
902 NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
903 [NL80211_ATTR_S1G_CAPABILITY_MASK] =
904 NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
905 [NL80211_ATTR_SAE_PWE] =
906 NLA_POLICY_RANGE(NLA_U8, NL80211_SAE_PWE_HUNT_AND_PECK,
907 NL80211_SAE_PWE_BOTH),
908 [NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT },
909 [NL80211_ATTR_SAR_SPEC] = NLA_POLICY_NESTED(sar_policy),
910 [NL80211_ATTR_DISABLE_HE] = { .type = NLA_FLAG },
911 [NL80211_ATTR_OBSS_COLOR_BITMAP] = { .type = NLA_U64 },
912 [NL80211_ATTR_COLOR_CHANGE_COUNT] = { .type = NLA_U8 },
913 [NL80211_ATTR_COLOR_CHANGE_COLOR] = { .type = NLA_U8 },
914 [NL80211_ATTR_COLOR_CHANGE_ELEMS] = NLA_POLICY_NESTED(nl80211_policy),
915 [NL80211_ATTR_MBSSID_CONFIG] =
916 NLA_POLICY_NESTED(nl80211_mbssid_config_policy),
917 [NL80211_ATTR_MBSSID_ELEMS] = { .type = NLA_NESTED },
918 [NL80211_ATTR_RADAR_BACKGROUND] = { .type = NLA_FLAG },
919 [NL80211_ATTR_AP_SETTINGS_FLAGS] = { .type = NLA_U32 },
920 [NL80211_ATTR_EHT_CAPABILITY] =
921 NLA_POLICY_RANGE(NLA_BINARY,
922 NL80211_EHT_MIN_CAPABILITY_LEN,
923 NL80211_EHT_MAX_CAPABILITY_LEN),
924 [NL80211_ATTR_DISABLE_EHT] = { .type = NLA_FLAG },
925 [NL80211_ATTR_MLO_LINKS] =
926 NLA_POLICY_NESTED_ARRAY(nl80211_policy),
927 [NL80211_ATTR_MLO_LINK_ID] =
928 NLA_POLICY_RANGE(NLA_U8, 0, IEEE80211_MLD_MAX_NUM_LINKS - 1),
929 [NL80211_ATTR_MLD_ADDR] = NLA_POLICY_EXACT_LEN(ETH_ALEN),
930 [NL80211_ATTR_MLO_SUPPORT] = { .type = NLA_FLAG },
931 [NL80211_ATTR_MAX_NUM_AKM_SUITES] = { .type = NLA_REJECT },
932 [NL80211_ATTR_EML_CAPABILITY] = { .type = NLA_U16 },
933 [NL80211_ATTR_PUNCT_BITMAP] =
934 NLA_POLICY_FULL_RANGE(NLA_U32, &nl80211_punct_bitmap_range),
935
936 [NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS] = { .type = NLA_U16 },
937 [NL80211_ATTR_HW_TIMESTAMP_ENABLED] = { .type = NLA_FLAG },
938 [NL80211_ATTR_EMA_RNR_ELEMS] = { .type = NLA_NESTED },
939 [NL80211_ATTR_MLO_LINK_DISABLED] = { .type = NLA_FLAG },
940 [NL80211_ATTR_BSS_DUMP_INCLUDE_USE_DATA] = { .type = NLA_FLAG },
941 [NL80211_ATTR_MLO_TTLM_DLINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8),
942 [NL80211_ATTR_MLO_TTLM_ULINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8),
943 [NL80211_ATTR_ASSOC_SPP_AMSDU] = { .type = NLA_FLAG },
944 [NL80211_ATTR_VIF_RADIO_MASK] = { .type = NLA_U32 },
945 [NL80211_ATTR_SUPPORTED_SELECTORS] =
946 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_supported_selectors,
947 NL80211_MAX_SUPP_SELECTORS),
948 [NL80211_ATTR_MLO_RECONF_REM_LINKS] = { .type = NLA_U16 },
949 [NL80211_ATTR_EPCS] = { .type = NLA_FLAG },
950 [NL80211_ATTR_ASSOC_MLD_EXT_CAPA_OPS] = { .type = NLA_U16 },
951 [NL80211_ATTR_WIPHY_RADIO_INDEX] = { .type = NLA_U8 },
952 [NL80211_ATTR_S1G_LONG_BEACON_PERIOD] = NLA_POLICY_MIN(NLA_U8, 2),
953 [NL80211_ATTR_S1G_SHORT_BEACON] =
954 NLA_POLICY_NESTED(nl80211_s1g_short_beacon),
955 [NL80211_ATTR_BSS_PARAM] = { .type = NLA_FLAG },
956 [NL80211_ATTR_S1G_PRIMARY_2MHZ] = { .type = NLA_FLAG },
957 [NL80211_ATTR_EPP_PEER] = { .type = NLA_FLAG },
958 [NL80211_ATTR_UHR_CAPABILITY] =
959 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_uhr_capa, 255),
960 [NL80211_ATTR_DISABLE_UHR] = { .type = NLA_FLAG },
> 961 [[NL80211_ATTR_UHR_OPERATION] =
962 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_uhr_operation),
963 };
964
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* [PATCH] wifi: rtl8xxxu: Mark RTL8188ETV (0bda:0179) as tested
From: J. Neuschäfer via B4 Relay @ 2026-03-03 17:49 UTC (permalink / raw)
To: Jes Sorensen; +Cc: linux-wireless, linux-kernel, J. Neuschäfer
From: "J. Neuschäfer" <j.ne@posteo.net>
This WiFi chip appears in the "TCU Fernsehfee 3.0" set-top box.
I have tested that it works in WPA2-PSK-CCMP client mode.
Cc: Jes.Sorensen@gmail.com
Signed-off-by: J. Neuschäfer <j.ne@posteo.net>
---
drivers/net/wireless/realtek/rtl8xxxu/core.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/core.c b/drivers/net/wireless/realtek/rtl8xxxu/core.c
index 794187d28caa09..b4efc6f00a379a 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/core.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/core.c
@@ -7703,6 +7703,7 @@ static int rtl8xxxu_probe(struct usb_interface *interface,
switch (id->idVendor) {
case USB_VENDOR_ID_REALTEK:
switch(id->idProduct) {
+ case 0x0179:
case 0x1724:
case 0x8176:
case 0x8178:
---
base-commit: 11439c4635edd669ae435eec308f4ab8a0804808
change-id: 20250625-rtl8xxx-tested-791302586b6b
Best regards,
--
J. Neuschäfer <j.ne@posteo.net>
^ permalink raw reply related
* [PATCH] mac80211_hwsim: change hwsim_class to a const struct
From: Jori Koolstra @ 2026-03-03 16:59 UTC (permalink / raw)
To: Johannes Berg
Cc: Jori Koolstra, Greg Kroah-Hartman, open list:MAC80211, open list
The class_create() call has been deprecated in favor of class_register()
as the driver core now allows for a struct class to be in read-only
memory. Change hwsim_class to be a const struct class and drop the
class_create() call.
Link: https://lore.kernel.org/all/2023040244-duffel-pushpin-f738@gregkh/
Suggested-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Jori Koolstra <jkoolstra@xs4all.nl>
---
drivers/net/wireless/virtual/mac80211_hwsim.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c
index e89173f91637..506f865075b1 100644
--- a/drivers/net/wireless/virtual/mac80211_hwsim.c
+++ b/drivers/net/wireless/virtual/mac80211_hwsim.c
@@ -337,7 +337,9 @@ static inline void hwsim_net_set_wmediumd(struct net *net, u32 portid)
hwsim_net->wmediumd = portid;
}
-static struct class *hwsim_class;
+static const struct class hwsim_class = {
+ .name = "mac80211_hwsim"
+};
static struct net_device *hwsim_mon; /* global monitor netdev */
@@ -5424,7 +5426,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
data = hw->priv;
data->hw = hw;
- data->dev = device_create(hwsim_class, NULL, 0, hw, "hwsim%d", idx);
+ data->dev = device_create(&hwsim_class, NULL, 0, hw, "hwsim%d", idx);
if (IS_ERR(data->dev)) {
printk(KERN_DEBUG
"mac80211_hwsim: device_create failed (%ld)\n",
@@ -5978,7 +5980,7 @@ static void mac80211_hwsim_free(void)
spin_lock_bh(&hwsim_radio_lock);
}
spin_unlock_bh(&hwsim_radio_lock);
- class_destroy(hwsim_class);
+ class_unregister(&hwsim_class);
}
static const struct net_device_ops hwsim_netdev_ops = {
@@ -7083,11 +7085,9 @@ static int __init init_mac80211_hwsim(void)
if (err)
goto out_exit_netlink;
- hwsim_class = class_create("mac80211_hwsim");
- if (IS_ERR(hwsim_class)) {
- err = PTR_ERR(hwsim_class);
+ err = class_register(&hwsim_class);
+ if (err)
goto out_exit_virtio;
- }
hwsim_init_s1g_channels(hwsim_channels_s1g);
base-commit: d466c332e106fe666d1e2f5a24d08e308bebbfa1
--
2.53.0
^ permalink raw reply related
* [PATCH wireless v2] wifi: mac80211: use jiffies_delta_to_msecs() for sta_info inactive times
From: Nicolas Cavallari @ 2026-03-03 16:06 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
Inactive times of around 0xffffffff milliseconds have been observed on
an ath9k device on ARM. This is likely due to a memory ordering race in
the jiffies_to_msecs(jiffies - last_active()) calculation causing an
overflow when the observed jiffies is below ieee80211_sta_last_active().
Use jiffies_delta_to_msecs() instead to avoid this problem.
Fixes: 7bbdd2d98797 ("mac80211: implement station stats retrieval")
Signed-off-by: Nicolas Cavallari <nicolas.cavallari@green-communications.fr>
---
net/mac80211/sta_info.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
v2: reformat patch, change commit message to obey unwritten rule
also, the wireless tree does not compile on ARCH=um as of d973b1039ccd
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 6dc22f1593be..dd51a578fbc5 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -2782,7 +2782,9 @@ static void sta_set_link_sinfo(struct sta_info *sta,
}
link_sinfo->inactive_time =
- jiffies_to_msecs(jiffies - ieee80211_sta_last_active(sta, link_id));
+ jiffies_delta_to_msecs(jiffies -
+ ieee80211_sta_last_active(sta,
+ link_id));
if (!(link_sinfo->filled & (BIT_ULL(NL80211_STA_INFO_TX_BYTES64) |
BIT_ULL(NL80211_STA_INFO_TX_BYTES)))) {
@@ -3015,7 +3017,8 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo,
sinfo->connected_time = ktime_get_seconds() - sta->last_connected;
sinfo->assoc_at = sta->assoc_at;
sinfo->inactive_time =
- jiffies_to_msecs(jiffies - ieee80211_sta_last_active(sta, -1));
+ jiffies_delta_to_msecs(jiffies -
+ ieee80211_sta_last_active(sta, -1));
if (!(sinfo->filled & (BIT_ULL(NL80211_STA_INFO_TX_BYTES64) |
BIT_ULL(NL80211_STA_INFO_TX_BYTES)))) {
base-commit: d973b1039ccde6b241b438d53297edce4de45b5c
--
2.53.0
^ permalink raw reply related
* Re: pull-request: ath-next-20260303
From: Jeff Johnson @ 2026-03-03 16:34 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
In-Reply-To: <79e82568-e951-43f4-ac87-2319245a5490@oss.qualcomm.com>
On 3/3/2026 8:27 AM, Jeff Johnson wrote:
> The following changes since commit 8bf22c33e7a172fbc72464f4cc484d23a6b412ba:
>
> Merge tag 'net-7.0-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net (2026-02-19 10:39:08 -0800)
>
> are available in the Git repository at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/ath/ath.git tags/ath-next-20260303
>
> for you to fetch changes up to cf7cbf97c630c3414302945617b8ac405e2b0dd7:
>
> wifi: ath12k: Remove the unused argument from the Rx data path (2026-03-02 13:02:05 -0800)
>
> ----------------------------------------------------------------
> ath.git patches for v7.1 (PR #1)
>
> For ath12k:
> Add basic hwmon temperature reporting.
> Enable monitor mode on IPQ5332.
>
> Also a few small cleanups and bug fixes across ath drivers.
FYI the reason for the early PR is that I made the mistake of pulling some
patches into ath-next before I realized that Kees & Linux had applied the
treewide kmalloc_obj() feature, so now I need to merge so I can then fast
forward to wireless-next/main to pick that up. I don't want to take any more
ath-next changes until that is in place.
/jeff
^ permalink raw reply
* pull-request: ath-next-20260303
From: Jeff Johnson @ 2026-03-03 16:27 UTC (permalink / raw)
To: linux-wireless, Johannes Berg; +Cc: ath10k, ath11k, ath12k, jjohnson
The following changes since commit 8bf22c33e7a172fbc72464f4cc484d23a6b412ba:
Merge tag 'net-7.0-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net (2026-02-19 10:39:08 -0800)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/ath/ath.git tags/ath-next-20260303
for you to fetch changes up to cf7cbf97c630c3414302945617b8ac405e2b0dd7:
wifi: ath12k: Remove the unused argument from the Rx data path (2026-03-02 13:02:05 -0800)
----------------------------------------------------------------
ath.git patches for v7.1 (PR #1)
For ath12k:
Add basic hwmon temperature reporting.
Enable monitor mode on IPQ5332.
Also a few small cleanups and bug fixes across ath drivers.
----------------------------------------------------------------
Aaradhana Sahu (1):
wifi: ath12k: Enable monitor mode support on IPQ5332
Alejandro Colomar (1):
wifi: ath9k: Fix typo
Baochen Qiang (1):
wifi: ath12k: fix indentation in ath12k_qmi_aux_uc_load()
Bjorn Andersson (1):
wifi: ath11k: Silence remoteproc probe deferral prints
Karthikeyan Periyasamy (1):
wifi: ath12k: Remove the unused argument from the Rx data path
Maharaja Kennadyrajan (1):
wifi: ath12k: add basic hwmon temperature reporting
Ramya Gnanasekar (1):
wifi: ath12k: Set up MLO after SSR
Zilin Guan (1):
wifi: ath11k: fix memory leaks in beacon template setup
drivers/net/wireless/ath/ath11k/ahb.c | 10 +--
drivers/net/wireless/ath/ath11k/mac.c | 28 +++---
drivers/net/wireless/ath/ath12k/Makefile | 1 +
drivers/net/wireless/ath/ath12k/core.c | 23 ++++-
drivers/net/wireless/ath/ath12k/core.h | 3 +
drivers/net/wireless/ath/ath12k/dp_rx.c | 2 -
drivers/net/wireless/ath/ath12k/dp_rx.h | 2 -
drivers/net/wireless/ath/ath12k/mac.c | 4 +
drivers/net/wireless/ath/ath12k/qmi.c | 2 +-
drivers/net/wireless/ath/ath12k/thermal.c | 124 ++++++++++++++++++++++++++
drivers/net/wireless/ath/ath12k/thermal.h | 40 +++++++++
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 25 +++---
drivers/net/wireless/ath/ath12k/wifi7/hw.c | 4 +-
drivers/net/wireless/ath/ath12k/wmi.c | 57 ++++++------
drivers/net/wireless/ath/ath9k/ath9k.h | 2 +-
15 files changed, 255 insertions(+), 72 deletions(-)
create mode 100644 drivers/net/wireless/ath/ath12k/thermal.c
create mode 100644 drivers/net/wireless/ath/ath12k/thermal.h
^ permalink raw reply
* [RFC wireless-next 6/8] wifi: mac80211: allow only AP chanctx sharing with NPCA
From: Johannes Berg @ 2026-03-03 14:27 UTC (permalink / raw)
To: linux-wireless; +Cc: Johannes Berg
In-Reply-To: <20260303143434.273141-10-johannes@sipsolutions.net>
From: Johannes Berg <johannes.berg@intel.com>
When two interfaces share a channel context, disable NPCA
unless both are AP interfaces that require NPCA. This way,
two AP interfaces can have identical chandefs set up and
share the channel context, but any non-APs cannot share a
chanctx with NPCA (they'd almost certainly have different
BSS color.)
This doesn't mean the chanctx cannot be shared but rather
that NPCA will be disabled on the shared channel context.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
include/net/mac80211.h | 7 +++++++
net/mac80211/cfg.c | 15 ++++++++++++---
net/mac80211/chan.c | 34 ++++++++++++++++++++++++++++++----
3 files changed, 49 insertions(+), 7 deletions(-)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 9f8251fb9832..11ee96aeb155 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -218,6 +218,8 @@ struct ieee80211_low_level_stats {
* bandwidth) OFDMA settings need to be changed
* @IEEE80211_CHANCTX_CHANGE_PUNCTURING: The punctured channel(s) bitmap
* was changed.
+ * @IEEE80211_CHANCTX_CHANGE_NPCA: NPCA configuration changed
+ * @IEEE80211_CHANCTX_CHANGE_NPCA_PUNCT: NPCA puncturing changed
*/
enum ieee80211_chanctx_change {
IEEE80211_CHANCTX_CHANGE_WIDTH = BIT(0),
@@ -227,6 +229,8 @@ enum ieee80211_chanctx_change {
IEEE80211_CHANCTX_CHANGE_MIN_DEF = BIT(4),
IEEE80211_CHANCTX_CHANGE_AP = BIT(5),
IEEE80211_CHANCTX_CHANGE_PUNCTURING = BIT(6),
+ IEEE80211_CHANCTX_CHANGE_NPCA = BIT(7),
+ IEEE80211_CHANCTX_CHANGE_NPCA_PUNCT = BIT(8),
};
/**
@@ -234,10 +238,13 @@ enum ieee80211_chanctx_change {
* @oper: channel definition to use for operation
* @ap: the channel definition of the AP, if any
* (otherwise the chan member is %NULL)
+ * @require_npca: If NPCA is configured, require it to
+ * remain, this is used by AP interfaces
*/
struct ieee80211_chan_req {
struct cfg80211_chan_def oper;
struct cfg80211_chan_def ap;
+ bool require_npca;
};
/**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index ee64ac8e0f61..a1691b9bfceb 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1493,7 +1493,10 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
unsigned int link_id = params->beacon.link_id;
struct ieee80211_link_data *link;
struct ieee80211_bss_conf *link_conf;
- struct ieee80211_chan_req chanreq = { .oper = params->chandef };
+ struct ieee80211_chan_req chanreq = {
+ .oper = params->chandef,
+ .require_npca = true,
+ };
u64 tsf;
lockdep_assert_wiphy(local->hw.wiphy);
@@ -4349,7 +4352,10 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_csa_settings *params)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- struct ieee80211_chan_req chanreq = { .oper = params->chandef };
+ struct ieee80211_chan_req chanreq = {
+ .oper = params->chandef,
+ .require_npca = true,
+ };
struct ieee80211_local *local = sdata->local;
struct ieee80211_channel_switch ch_switch = {
.link_id = params->link_id,
@@ -4791,7 +4797,10 @@ static int ieee80211_set_ap_chanwidth(struct wiphy *wiphy,
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_link_data *link;
- struct ieee80211_chan_req chanreq = { .oper = *chandef };
+ struct ieee80211_chan_req chanreq = {
+ .oper = *chandef,
+ .require_npca = true,
+ };
int ret;
u64 changed = 0;
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 2f0c93f3ace6..26ae7da3b2fd 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -223,19 +223,41 @@ ieee80211_chanreq_compatible(const struct ieee80211_chan_req *a,
const struct ieee80211_chan_req *b,
struct ieee80211_chan_req *tmp)
{
+ struct ieee80211_chan_req _a = *a, _b = *b;
const struct cfg80211_chan_def *compat;
if (a->ap.chan && b->ap.chan &&
!cfg80211_chandef_identical(&a->ap, &b->ap))
return NULL;
- compat = cfg80211_chandef_compatible(&a->oper, &b->oper);
+ /*
+ * Remove NPCA if it's not required, so that interfaces
+ * sharing a channel context will not use NPCA while the
+ * channel context is shared.
+ * If both sides are AP interfaces requiring NPC, there's
+ * an assumption that userspace will set them up with
+ * identical configurations and the same BSS color
+ * (if the config is not identical, sharing will fail due
+ * to cfg80211_chandef_compatible() failing below.)
+ */
+ if (!_a.require_npca) {
+ _a.oper.npca_chan = NULL;
+ _a.oper.npca_punctured = 0;
+ }
+
+ if (!_b.require_npca) {
+ _b.oper.npca_chan = NULL;
+ _b.oper.npca_punctured = 0;
+ }
+
+ compat = cfg80211_chandef_compatible(&_a.oper, &_b.oper);
if (!compat)
return NULL;
/* Note: later code assumes this always fills & returns tmp if compat */
tmp->oper = *compat;
tmp->ap = a->ap.chan ? a->ap : b->ap;
+ tmp->require_npca = a->require_npca && b->require_npca;
return tmp;
}
@@ -671,7 +693,6 @@ static void _ieee80211_change_chanctx(struct ieee80211_local *local,
const struct ieee80211_chan_req *chanreq,
struct ieee80211_link_data *rsvd_for)
{
- const struct cfg80211_chan_def *chandef = &chanreq->oper;
struct ieee80211_chan_req ctx_req = {
.oper = ctx->conf.def,
.ap = ctx->conf.ap,
@@ -679,7 +700,7 @@ static void _ieee80211_change_chanctx(struct ieee80211_local *local,
u32 changed = 0;
/* 5/10 MHz not handled here */
- switch (chandef->width) {
+ switch (chanreq->oper.width) {
case NL80211_CHAN_WIDTH_1:
case NL80211_CHAN_WIDTH_2:
case NL80211_CHAN_WIDTH_4:
@@ -724,10 +745,15 @@ static void _ieee80211_change_chanctx(struct ieee80211_local *local,
changed |= IEEE80211_CHANCTX_CHANGE_WIDTH;
if (ctx->conf.def.punctured != chanreq->oper.punctured)
changed |= IEEE80211_CHANCTX_CHANGE_PUNCTURING;
+ if (ctx->conf.def.npca_chan != chanreq->oper.npca_chan)
+ changed |= IEEE80211_CHANCTX_CHANGE_NPCA;
+ if (chanreq->oper.npca_chan &&
+ ctx->conf.def.npca_punctured != chanreq->oper.npca_punctured)
+ changed |= IEEE80211_CHANCTX_CHANGE_NPCA_PUNCT;
}
if (!cfg80211_chandef_identical(&ctx->conf.ap, &chanreq->ap))
changed |= IEEE80211_CHANCTX_CHANGE_AP;
- ctx->conf.def = *chandef;
+ ctx->conf.def = chanreq->oper;
ctx->conf.ap = chanreq->ap;
/* check if min chanctx also changed */
--
2.53.0
^ permalink raw reply related
* [RFC wireless-next 8/8] wifi: mac80211: set AP NPCA parameters in bss_conf
From: Johannes Berg @ 2026-03-03 14:27 UTC (permalink / raw)
To: linux-wireless; +Cc: Johannes Berg
In-Reply-To: <20260303143434.273141-10-johannes@sipsolutions.net>
From: Johannes Berg <johannes.berg@intel.com>
Set the parameters advertised in the beacon in the BSS
configuration as well.
Note this is incomplete since it doesn't track updates.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/cfg.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index a1691b9bfceb..e12686b1e569 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1605,10 +1605,42 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
}
if (params->uhr_oper) {
+ const struct ieee80211_uhr_npca_info *npca;
+ struct ieee80211_bss_npca_params npca_params = {};
+
if (!link_conf->eht_support)
return -EOPNOTSUPP;
link_conf->uhr_support = true;
+
+ npca = ieee80211_uhr_npca_info(params->uhr_oper);
+ if (!npca) {
+ chanreq.oper.npca_chan = NULL;
+ chanreq.oper.npca_punctured = 0;
+ } else {
+ npca_params.min_dur_thresh =
+ le32_get_bits(npca->params,
+ IEEE80211_UHR_NPCA_PARAMS_MIN_DUR_THRESH);
+ npca_params.switch_delay =
+ le32_get_bits(npca->params,
+ IEEE80211_UHR_NPCA_PARAMS_SWITCH_DELAY);
+ npca_params.switch_back_delay =
+ le32_get_bits(npca->params,
+ IEEE80211_UHR_NPCA_PARAMS_SWITCH_BACK_DELAY);
+ npca_params.init_qsrc =
+ le32_get_bits(npca->params,
+ IEEE80211_UHR_NPCA_PARAMS_INIT_QSRC);
+ npca_params.moplen =
+ le32_get_bits(npca->params,
+ IEEE80211_UHR_NPCA_PARAMS_MOPLEN);
+ npca_params.enabled = true;
+ }
+
+ if (memcmp(&npca_params, &link->conf->npca,
+ sizeof(npca_params))) {
+ link->conf->npca = npca_params;
+ changed |= BSS_CHANGED_NPCA;
+ }
}
if (sdata->vif.type == NL80211_IFTYPE_AP &&
--
2.53.0
^ permalink raw reply related
* [RFC wireless-next 7/8] wifi: mac80211: mlme: use NPCA chandef if capable
From: Johannes Berg @ 2026-03-03 14:27 UTC (permalink / raw)
To: linux-wireless; +Cc: Johannes Berg
In-Reply-To: <20260303143434.273141-10-johannes@sipsolutions.net>
From: Johannes Berg <johannes.berg@intel.com>
If the device is capable, parse the AP chandef with NPCA.
Also advertise the other NPCA operational parameters to the
underlying driver and track if they change (though not with
BSS critical update etc. yet)
Since NPCA can only be enabled when the chanctx isn't shared,
the channel context code needs to clear/set npca.enabled in
the per-link configuration, except during association since
we can't enable NPCA before having completed association. In
this case, set npca.enabled during the association process.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
include/net/mac80211.h | 25 ++++++++++++++
net/mac80211/chan.c | 38 +++++++++++++++++++++
net/mac80211/mlme.c | 77 +++++++++++++++++++++++++++++++++++++++++-
net/mac80211/util.c | 3 ++
4 files changed, 142 insertions(+), 1 deletion(-)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 11ee96aeb155..9c8871f7d606 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -372,6 +372,7 @@ struct ieee80211_vif_chanctx_switch {
* @BSS_CHANGED_MLD_VALID_LINKS: MLD valid links status changed.
* @BSS_CHANGED_MLD_TTLM: negotiated TID to link mapping was changed
* @BSS_CHANGED_TPE: transmit power envelope changed
+ * @BSS_CHANGED_NPCA: NPCA parameters changed
*/
enum ieee80211_bss_change {
BSS_CHANGED_ASSOC = 1<<0,
@@ -409,6 +410,7 @@ enum ieee80211_bss_change {
BSS_CHANGED_MLD_VALID_LINKS = BIT_ULL(33),
BSS_CHANGED_MLD_TTLM = BIT_ULL(34),
BSS_CHANGED_TPE = BIT_ULL(35),
+ BSS_CHANGED_NPCA = BIT_ULL(36),
/* when adding here, make sure to change ieee80211_reconfig */
};
@@ -594,6 +596,26 @@ struct ieee80211_parsed_tpe {
struct ieee80211_parsed_tpe_psd psd_local[2], psd_reg_client[2];
};
+/**
+ * struct ieee80211_bss_npca_params - NPCA parameters
+ * @min_dur_thresh: NPCA minimum duration threshold (512 + 128*n usec)
+ * @switch_delay: NPCA switch delay (units of 4 usec)
+ * @switch_back_delay: NPCA switch back delay (units of 4 usec)
+ * @init_qsrc: initial QSRC value
+ * @moplen: indicates MOPLEN NPCA is permitted in the BSS
+ * @enabled: NPCA is enabled for this link
+ *
+ * Note: the individual values (except @enabled) are in spec representation.
+ */
+struct ieee80211_bss_npca_params {
+ u32 min_dur_thresh:4,
+ switch_delay:6,
+ switch_back_delay:6,
+ init_qsrc:2,
+ moplen:1,
+ enabled:1;
+};
+
/**
* struct ieee80211_bss_conf - holds the BSS's changing parameters
*
@@ -768,6 +790,7 @@ struct ieee80211_parsed_tpe {
* (as opposed to hearing its value from another link's beacon).
* @s1g_long_beacon_period: number of beacon intervals between each long
* beacon transmission.
+ * @npca: NPCA parameters
*/
struct ieee80211_bss_conf {
struct ieee80211_vif *vif;
@@ -871,6 +894,8 @@ struct ieee80211_bss_conf {
u8 bss_param_ch_cnt_link_id;
u8 s1g_long_beacon_period;
+
+ struct ieee80211_bss_npca_params npca;
};
/**
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 26ae7da3b2fd..88528714496c 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -687,6 +687,38 @@ void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
_ieee80211_recalc_chanctx_min_def(local, ctx, NULL, false);
}
+static void
+ieee80211_chanctx_update_npca_links(struct ieee80211_local *local,
+ struct ieee80211_chanctx *ctx,
+ bool enable)
+{
+ struct ieee80211_chanctx_user_iter iter;
+
+ if (!!ctx->conf.def.npca_chan != enable)
+ return;
+
+ for_each_chanctx_user_assigned(local, ctx, &iter) {
+ if (!iter.link)
+ continue;
+ if (!iter.sdata->vif.cfg.assoc)
+ continue;
+
+ if (enable) {
+ if (!iter.link->conf->chanreq.oper.npca_chan)
+ continue;
+ } else {
+ if (!iter.link->conf->npca.enabled)
+ continue;
+ }
+
+ iter.link->conf->npca.enabled = enable;
+ drv_link_info_changed(local, iter.sdata,
+ iter.link->conf,
+ iter.link->link_id,
+ BSS_CHANGED_NPCA);
+ }
+}
+
static void _ieee80211_change_chanctx(struct ieee80211_local *local,
struct ieee80211_chanctx *ctx,
struct ieee80211_chanctx *old_ctx,
@@ -762,10 +794,16 @@ static void _ieee80211_change_chanctx(struct ieee80211_local *local,
ieee80211_add_wbrf(local, &ctx->conf.def);
+ /* disable NPCA on the link using it */
+ ieee80211_chanctx_update_npca_links(local, ctx, false);
+
drv_change_chanctx(local, ctx, changed);
/* check if BW is wider */
ieee80211_chan_bw_change(local, old_ctx, false, false);
+
+ /* enable NPCA on the link that requested it */
+ ieee80211_chanctx_update_npca_links(local, ctx, true);
}
static void ieee80211_change_chanctx(struct ieee80211_local *local,
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index ecce6382e6cb..d34b7ae18db5 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -356,6 +356,7 @@ ieee80211_determine_ap_chan(struct ieee80211_sub_if_data *sdata,
elems->uhr_operation_len,
false)) {
struct cfg80211_chan_def npca_chandef = *chandef;
+ const struct ieee80211_sta_uhr_cap *uhr_cap;
const struct ieee80211_uhr_npca_info *npca;
npca = ieee80211_uhr_npca_info(uhr_oper);
@@ -366,6 +367,14 @@ ieee80211_determine_ap_chan(struct ieee80211_sub_if_data *sdata,
"AP UHR NPCA settings invalid, disabling UHR\n");
return IEEE80211_CONN_MODE_EHT;
}
+
+ uhr_cap = ieee80211_get_uhr_iftype_cap_vif(sband, &sdata->vif);
+ /* can't happen since we must have UHR to parse the elems */
+ if (WARN_ON(!uhr_cap))
+ return IEEE80211_CONN_MODE_EHT;
+
+ if (uhr_cap->mac.mac_cap[0] & IEEE80211_UHR_MAC_CAP0_NPCA_SUPP)
+ *chandef = npca_chandef;
}
return IEEE80211_CONN_MODE_UHR;
@@ -1274,6 +1283,7 @@ static int ieee80211_config_bw(struct ieee80211_link_data *link,
{
struct ieee80211_channel *channel = link->conf->chanreq.oper.chan;
struct ieee80211_sub_if_data *sdata = link->sdata;
+ struct ieee80211_chanctx_conf *chanctx_conf;
struct ieee80211_chan_req chanreq = {};
struct cfg80211_chan_def ap_chandef;
enum ieee80211_conn_mode ap_mode;
@@ -1360,8 +1370,55 @@ static int ieee80211_config_bw(struct ieee80211_link_data *link,
}
}
- if (ieee80211_chanreq_identical(&chanreq, &link->conf->chanreq))
+ /*
+ * Beacons don't have the full information - we need to track
+ * critical updates for NPCA parameters etc. For now only handle
+ * association and link reconfiguration response.
+ */
+ if (stype != IEEE80211_STYPE_BEACON &&
+ chanreq.oper.npca_chan && elems->uhr_operation &&
+ ieee80211_uhr_oper_size_ok((const void *)elems->uhr_operation,
+ elems->uhr_operation_len,
+ false)) {
+ const struct ieee80211_uhr_npca_info *npca;
+ struct ieee80211_bss_npca_params params = {};
+
+ npca = ieee80211_uhr_npca_info(elems->uhr_operation);
+ if (!npca) {
+ chanreq.oper.npca_chan = NULL;
+ chanreq.oper.npca_punctured = 0;
+ } else {
+ params.min_dur_thresh =
+ le32_get_bits(npca->params,
+ IEEE80211_UHR_NPCA_PARAMS_MIN_DUR_THRESH);
+ params.switch_delay =
+ le32_get_bits(npca->params,
+ IEEE80211_UHR_NPCA_PARAMS_SWITCH_DELAY);
+ params.switch_back_delay =
+ le32_get_bits(npca->params,
+ IEEE80211_UHR_NPCA_PARAMS_SWITCH_BACK_DELAY);
+ params.init_qsrc =
+ le32_get_bits(npca->params,
+ IEEE80211_UHR_NPCA_PARAMS_INIT_QSRC);
+ params.moplen =
+ le32_get_bits(npca->params,
+ IEEE80211_UHR_NPCA_PARAMS_MOPLEN);
+ /* don't change the enabled bit yet */
+ params.enabled = link->conf->npca.enabled;
+ }
+
+ if (memcmp(¶ms, &link->conf->npca, sizeof(params)) ||
+ !update) {
+ link->conf->npca = params;
+ *changed |= BSS_CHANGED_NPCA;
+ }
+ }
+
+ if (ieee80211_chanreq_identical(&chanreq, &link->conf->chanreq)) {
+ if (update)
+ goto update_npca;
return 0;
+ }
link_info(link,
"AP %pM changed bandwidth in %s, new used config is %d.%03d MHz, width %d (%d.%03d/%d MHz)\n",
@@ -1408,6 +1465,24 @@ static int ieee80211_config_bw(struct ieee80211_link_data *link,
}
cfg80211_schedule_channels_check(&sdata->wdev);
+
+update_npca:
+ chanctx_conf = sdata_dereference(link->conf->chanctx_conf, sdata);
+ /* must be non-NULL when update is true */
+ if (WARN_ON(!chanctx_conf))
+ return -EINVAL;
+
+ /*
+ * If we're not associated yet (i.e. in the process associating)
+ * then the chanctx code won't have enabled NPCA in the link, so
+ * if the channel context was set up with NPCA for us, enable it.
+ */
+ if (chanreq.oper.npca_chan && chanctx_conf->def.npca_chan &&
+ !link->conf->npca.enabled && !sdata->vif.cfg.assoc) {
+ link->conf->npca.enabled = true;
+ *changed |= BSS_CHANGED_NPCA;
+ }
+
return 0;
}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 373d0f853dbc..80b9f069df8e 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -2059,6 +2059,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
ieee80211_bss_info_change_notify(sdata,
changed);
} else if (!WARN_ON(!link)) {
+ if (link->conf->npca.enabled)
+ changed |= BSS_CHANGED_NPCA;
+
ieee80211_link_info_change_notify(sdata, link,
changed);
changed = BSS_CHANGED_ASSOC |
--
2.53.0
^ permalink raw reply related
* [RFC wireless-next 5/8] wifi: mac80211: add NPCA to chandef tracing
From: Johannes Berg @ 2026-03-03 14:27 UTC (permalink / raw)
To: linux-wireless; +Cc: Johannes Berg
In-Reply-To: <20260303143434.273141-10-johannes@sipsolutions.net>
From: Johannes Berg <johannes.berg@intel.com>
Add the NPCA parameters (NPCA primary channel and puncturing bitmap)
to the chandef tracing.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/trace.h | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 1f0c07eaad1b..c897d9968399 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -44,7 +44,9 @@
__field(u32, n##center_freq1) \
__field(u32, n##freq1_offset) \
__field(u32, n##center_freq2) \
- __field(u16, n##punctured)
+ __field(u16, n##punctured) \
+ __field(u32, n##npca_pri_freq) \
+ __field(u16, n##npca_punctured)
#define __CHANDEF_ASSIGN(n, c) \
__entry->n##control_freq = (c) && (c)->chan ? \
(c)->chan->center_freq : 0; \
@@ -54,14 +56,18 @@
__entry->n##center_freq1 = (c) ? (c)->center_freq1 : 0; \
__entry->n##freq1_offset = (c) ? (c)->freq1_offset : 0; \
__entry->n##center_freq2 = (c) ? (c)->center_freq2 : 0; \
- __entry->n##punctured = (c) ? (c)->punctured : 0;
+ __entry->n##punctured = (c) ? (c)->punctured : 0; \
+ __entry->n##npca_pri_freq = (c) && (c)->npca_chan ? \
+ (c)->npca_chan->center_freq : 0; \
+ __entry->n##npca_punctured = (c) ? (c)->npca_punctured : 0;
#define __CHANDEF_PR_FMT(n) \
- " " #n "(%d.%03d MHz,width:%d,center: %d.%03d/%d MHz, punct:0x%x)"
+ " " #n "(%d.%03d MHz,width:%d,center: %d.%03d/%d MHz, punct:0x%x, npca:%u, npca_punct:0x%x)"
#define __CHANDEF_PR_ARG(n) \
__entry->n##control_freq, __entry->n##freq_offset, \
__entry->n##chan_width, __entry->n##center_freq1, \
__entry->n##freq1_offset, __entry->n##center_freq2, \
- __entry->n##punctured
+ __entry->n##punctured, __entry->n##npca_pri_freq, \
+ __entry->n##npca_punctured
#define CHANDEF_ENTRY __CHANDEF_ENTRY()
#define CHANDEF_ASSIGN(c) __CHANDEF_ASSIGN(, c)
--
2.53.0
^ permalink raw reply related
* [RFC wireless-next 4/8] wifi: mac80211: remove NPCA during chandef downgrade
From: Johannes Berg @ 2026-03-03 14:26 UTC (permalink / raw)
To: linux-wireless; +Cc: Johannes Berg
In-Reply-To: <20260303143434.273141-10-johannes@sipsolutions.net>
From: Johannes Berg <johannes.berg@intel.com>
We can't use NPCA any more if the chandef was downgraded,
for obvious reasons. Clear NPCA during any downgrade.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/util.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index b2e6c8b98381..373d0f853dbc 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -3752,6 +3752,10 @@ void ieee80211_chandef_downgrade(struct cfg80211_chan_def *c,
c->width = new_primary_width;
}
+ /* whatever we do, downgrading removes NPCA */
+ c->npca_chan = NULL;
+ c->npca_punctured = 0;
+
/*
* With an 80 MHz channel, we might have the puncturing in the primary
* 40 Mhz channel, but that's not valid when downgraded to 40 MHz width.
--
2.53.0
^ permalink raw reply related
* [RFC wireless-next 2/8] wifi: cfg80211: add helper for parsing NPCA to chandef
From: Johannes Berg @ 2026-03-03 14:26 UTC (permalink / raw)
To: linux-wireless; +Cc: Johannes Berg
In-Reply-To: <20260303143434.273141-10-johannes@sipsolutions.net>
From: Johannes Berg <johannes.berg@intel.com>
Add a cfg80211_chandef_add_npca() helper function that takes an
existing chandef without NPCA and sets the NPCA information from
the format used in UHR operation and UHR Parameters Update.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
include/net/cfg80211.h | 13 ++++++++++++
net/wireless/chan.c | 46 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 59 insertions(+)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 828d5cc84028..d09ec65514fc 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1150,6 +1150,19 @@ int cfg80211_chandef_primary(const struct cfg80211_chan_def *chandef,
enum nl80211_chan_width primary_chan_width,
u16 *punctured);
+/**
+ * cfg80211_chandef_add_npca - parse and add NPCA information to chandef
+ * @wiphy: the wiphy this will be used for, for channel pointer lookup
+ * @chandef: the chandef to modify, must be a valid chandef without NPCA
+ * @npca: the NPCA information, can be %NULL
+ *
+ * Returns: 0 if the NPCA information was added and the resulting
+ * chandef is valid, a negative error code on errors
+ */
+int cfg80211_chandef_add_npca(struct wiphy *wiphy,
+ struct cfg80211_chan_def *chandef,
+ const struct ieee80211_uhr_npca_info *npca);
+
/**
* nl80211_send_chandef - sends the channel definition.
* @msg: the msg to send channel definition
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 7f6f4cfc3272..9d8c8ebf9644 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -546,6 +546,52 @@ int cfg80211_chandef_primary(const struct cfg80211_chan_def *c,
}
EXPORT_SYMBOL(cfg80211_chandef_primary);
+int cfg80211_chandef_add_npca(struct wiphy *wiphy,
+ struct cfg80211_chan_def *chandef,
+ const struct ieee80211_uhr_npca_info *npca)
+{
+ struct cfg80211_chan_def new_chandef = *chandef;
+ u32 width, npca_freq;
+ u8 offs;
+
+ if (chandef->npca_chan || chandef->npca_punctured)
+ return -EINVAL;
+
+ if (WARN_ON(!cfg80211_chandef_valid(chandef)))
+ return -EINVAL;
+
+ if (!npca)
+ return 0;
+
+ switch (chandef->width) {
+ case NL80211_CHAN_WIDTH_80:
+ case NL80211_CHAN_WIDTH_160:
+ case NL80211_CHAN_WIDTH_320:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ offs = le32_get_bits(npca->params,
+ IEEE80211_UHR_NPCA_PARAMS_PRIMARY_CHAN_OFFS);
+
+ width = cfg80211_chandef_get_width(chandef);
+ npca_freq = chandef->center_freq1 - width / 2 + 10 + 20 * offs;
+ new_chandef.npca_chan = ieee80211_get_channel(wiphy, npca_freq);
+ if (!new_chandef.npca_chan)
+ return -EINVAL;
+
+ if (npca->params & cpu_to_le32(IEEE80211_UHR_NPCA_PARAMS_DIS_SUBCH_BMAP_PRES))
+ new_chandef.npca_punctured = le16_to_cpu(npca->dis_subch_bmap[0]);
+
+ if (!cfg80211_chandef_valid(&new_chandef))
+ return -EINVAL;
+
+ *chandef = new_chandef;
+ return 0;
+}
+EXPORT_SYMBOL(cfg80211_chandef_add_npca);
+
static const struct cfg80211_chan_def *
check_chandef_primary_compat(const struct cfg80211_chan_def *c1,
const struct cfg80211_chan_def *c2,
--
2.53.0
^ permalink raw reply related
* [RFC wireless-next 3/8] wifi: mac80211: use NPCA in chandef for validation
From: Johannes Berg @ 2026-03-03 14:26 UTC (permalink / raw)
To: linux-wireless; +Cc: Johannes Berg
In-Reply-To: <20260303143434.273141-10-johannes@sipsolutions.net>
From: Johannes Berg <johannes.berg@intel.com>
Put the NPCA parameters into a chandef when parsing data from
the AP to validate them using the cfg80211 code, rather than
implementing that in mac80211 directly.
Note that the parameters are not applied yet, since mac80211
doesn't yet have NPCA support.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/mlme.c | 37 +++----------------------------------
1 file changed, 3 insertions(+), 34 deletions(-)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 170330d924a3..ecce6382e6cb 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -357,44 +357,13 @@ ieee80211_determine_ap_chan(struct ieee80211_sub_if_data *sdata,
false)) {
struct cfg80211_chan_def npca_chandef = *chandef;
const struct ieee80211_uhr_npca_info *npca;
- const __le16 *dis_subch_bmap;
- u16 punct = chandef->punctured, npca_punct;
npca = ieee80211_uhr_npca_info(uhr_oper);
- if (npca) {
- int width = cfg80211_chandef_get_width(chandef);
- u8 offs = le32_get_bits(npca->params,
- IEEE80211_UHR_NPCA_PARAMS_PRIMARY_CHAN_OFFS);
- u32 cf1 = chandef->center_freq1;
- bool pri_upper, npca_upper;
- pri_upper = chandef->chan->center_freq > cf1;
- npca_upper = 20 * offs >= width / 2;
-
- if (20 * offs >= cfg80211_chandef_get_width(chandef) ||
- pri_upper == npca_upper) {
- sdata_info(sdata,
- "AP UHR NPCA primary channel invalid, disabling UHR\n");
- return IEEE80211_CONN_MODE_EHT;
- }
- }
-
- dis_subch_bmap = ieee80211_uhr_npca_dis_subch_bitmap(uhr_oper);
-
- if (dis_subch_bmap) {
- npca_punct = get_unaligned_le16(dis_subch_bmap);
- npca_chandef.punctured = npca_punct;
- }
-
- /*
- * must be a valid puncturing pattern for this channel as
- * well as puncturing all subchannels that are already in
- * the disabled subchannel bitmap on the primary channel
- */
- if (!cfg80211_chandef_valid(&npca_chandef) ||
- ((punct & npca_punct) != punct)) {
+ if (cfg80211_chandef_add_npca(sdata->local->hw.wiphy,
+ &npca_chandef, npca)) {
sdata_info(sdata,
- "AP UHR NPCA disabled subchannel bitmap invalid, disabling UHR\n");
+ "AP UHR NPCA settings invalid, disabling UHR\n");
return IEEE80211_CONN_MODE_EHT;
}
}
--
2.53.0
^ permalink raw reply related
* [RFC wireless-next 1/8] wifi: cfg80211: allow representing NPCA in chandef
From: Johannes Berg @ 2026-03-03 14:26 UTC (permalink / raw)
To: linux-wireless; +Cc: Johannes Berg
In-Reply-To: <20260303143434.273141-10-johannes@sipsolutions.net>
From: Johannes Berg <johannes.berg@intel.com>
Add the necessary fields to the chandef data structure
to represent NPCA (the NPCA primary channel and NPCA
punctured/disabled subchannels bitmap), and the code
to check these for validity, compatibility, as well as
allowing it to be passed for AP mode for capable
devices.
Compatibility is assumed to only be the case when it's
actually identical, enabling later management of this
in channel contexts in mac80211 for multiple APs, but
requiring userspace to set up the identical chandef on
all AP interfaces that share a channel (and BSS color.)
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
include/net/cfg80211.h | 11 +++-
include/uapi/linux/nl80211.h | 6 ++
net/wireless/chan.c | 59 +++++++++++++++---
net/wireless/nl80211.c | 118 ++++++++++++++++++++++++++++++-----
net/wireless/nl80211.h | 5 +-
net/wireless/pmsr.c | 2 +-
net/wireless/trace.h | 16 ++++-
7 files changed, 188 insertions(+), 29 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 8cd870ece351..828d5cc84028 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -844,6 +844,7 @@ struct key_params {
/**
* struct cfg80211_chan_def - channel definition
* @chan: the (control) channel
+ * @npca_chan: the NPCA primary channel
* @width: channel width
* @center_freq1: center frequency of first segment
* @center_freq2: center frequency of second segment
@@ -856,18 +857,22 @@ struct key_params {
* @punctured: mask of the punctured 20 MHz subchannels, with
* bits turned on being disabled (punctured); numbered
* from lower to higher frequency (like in the spec)
+ * @npca_punctured: NPCA puncturing bitmap, like @punctured but for
+ * NPCA transmissions. If NPCA is used (@npca_chan is not %NULL)
+ * this will be a superset of the @punctured bimap.
* @s1g_primary_2mhz: Indicates if the control channel pointed to
* by 'chan' exists as a 1MHz primary subchannel within an
* S1G 2MHz primary channel.
*/
struct cfg80211_chan_def {
struct ieee80211_channel *chan;
+ struct ieee80211_channel *npca_chan;
enum nl80211_chan_width width;
u32 center_freq1;
u32 center_freq2;
struct ieee80211_edmg edmg;
u16 freq1_offset;
- u16 punctured;
+ u16 punctured, npca_punctured;
bool s1g_primary_2mhz;
};
@@ -1014,7 +1019,9 @@ cfg80211_chandef_identical(const struct cfg80211_chan_def *chandef1,
chandef1->freq1_offset == chandef2->freq1_offset &&
chandef1->center_freq2 == chandef2->center_freq2 &&
chandef1->punctured == chandef2->punctured &&
- chandef1->s1g_primary_2mhz == chandef2->s1g_primary_2mhz);
+ chandef1->s1g_primary_2mhz == chandef2->s1g_primary_2mhz &&
+ chandef1->npca_chan == chandef2->npca_chan &&
+ chandef1->npca_punctured == chandef2->npca_punctured);
}
/**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 67d764023988..02377c196082 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -3005,6 +3005,9 @@ enum nl80211_commands {
* association response etc., since it's abridged in the beacon. Used
* for START_AP etc.
*
+ * @NL80211_ATTR_NPCA_PRIMARY_FREQ: NPCA primary channel (u32)
+ * @NL80211_ATTR_NPCA_PUNCT_BITMAP: NPCA puncturing bitmap (u32)
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3582,6 +3585,9 @@ enum nl80211_attrs {
NL80211_ATTR_UHR_OPERATION,
+ NL80211_ATTR_NPCA_PRIMARY_FREQ,
+ NL80211_ATTR_NPCA_PUNCT_BITMAP,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index e3c18a4392bb..7f6f4cfc3272 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -136,9 +136,10 @@ static const struct cfg80211_per_bw_puncturing_values per_bw_puncturing[] = {
CFG80211_PER_BW_VALID_PUNCTURING_VALUES(320)
};
-static bool valid_puncturing_bitmap(const struct cfg80211_chan_def *chandef)
+static bool valid_puncturing_bitmap(const struct cfg80211_chan_def *chandef,
+ u32 primary_center, u32 punctured)
{
- u32 idx, i, start_freq, primary_center = chandef->chan->center_freq;
+ u32 idx, i, start_freq;
switch (chandef->width) {
case NL80211_CHAN_WIDTH_80:
@@ -154,18 +155,18 @@ static bool valid_puncturing_bitmap(const struct cfg80211_chan_def *chandef)
start_freq = chandef->center_freq1 - 160;
break;
default:
- return chandef->punctured == 0;
+ return punctured == 0;
}
- if (!chandef->punctured)
+ if (!punctured)
return true;
/* check if primary channel is punctured */
- if (chandef->punctured & (u16)BIT((primary_center - start_freq) / 20))
+ if (punctured & (u16)BIT((primary_center - start_freq) / 20))
return false;
for (i = 0; i < per_bw_puncturing[idx].len; i++) {
- if (per_bw_puncturing[idx].valid_values[i] == chandef->punctured)
+ if (per_bw_puncturing[idx].valid_values[i] == punctured)
return true;
}
@@ -448,6 +449,40 @@ bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef)
if (!cfg80211_chandef_valid_control_freq(chandef, control_freq))
return false;
+ if (chandef->npca_chan) {
+ bool pri_upper, npca_upper;
+ u32 cf1;
+
+ switch (chandef->width) {
+ case NL80211_CHAN_WIDTH_80:
+ case NL80211_CHAN_WIDTH_160:
+ case NL80211_CHAN_WIDTH_320:
+ break;
+ default:
+ return false;
+ }
+
+ if (!cfg80211_chandef_valid_control_freq(chandef,
+ chandef->npca_chan->center_freq))
+ return false;
+
+ cf1 = chandef->center_freq1;
+ pri_upper = chandef->chan->center_freq > cf1;
+ npca_upper = chandef->npca_chan->center_freq > cf1;
+
+ if (pri_upper == npca_upper)
+ return false;
+
+ if (!valid_puncturing_bitmap(chandef,
+ chandef->npca_chan->center_freq,
+ chandef->npca_punctured) ||
+ (chandef->punctured & chandef->npca_punctured) !=
+ chandef->punctured)
+ return false;
+ } else if (chandef->npca_punctured) {
+ return false;
+ }
+
if (!cfg80211_valid_center_freq(chandef->center_freq1, chandef->width))
return false;
@@ -467,7 +502,8 @@ bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef)
if (!cfg80211_chandef_is_s1g(chandef) && chandef->s1g_primary_2mhz)
return false;
- return valid_puncturing_bitmap(chandef);
+ return valid_puncturing_bitmap(chandef, control_freq,
+ chandef->punctured);
}
EXPORT_SYMBOL(cfg80211_chandef_valid);
@@ -554,6 +590,15 @@ _cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1,
if (c1->width == c2->width)
return NULL;
+ /*
+ * We need NPCA to be compatible for some scenarios such as
+ * multiple APs, but in this case userspace should configure
+ * identical chandefs including NPCA, even if perhaps one of
+ * the AP interfaces doesn't even advertise it.
+ */
+ if (c1->npca_chan || c2->npca_chan)
+ return NULL;
+
/*
* can't be compatible if one of them is 5/10 MHz or S1G
* but they don't have the same width.
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 818696fdc461..7c40cc50973a 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -960,6 +960,9 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_DISABLE_UHR] = { .type = NLA_FLAG },
[[NL80211_ATTR_UHR_OPERATION] =
NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_uhr_operation),
+ [NL80211_ATTR_NPCA_PRIMARY_FREQ] = { .type = NLA_U32 },
+ [NL80211_ATTR_NPCA_PUNCT_BITMAP] =
+ NLA_POLICY_FULL_RANGE(NLA_U32, &nl80211_punct_bitmap_range),
};
/* policy for the key attributes */
@@ -3589,7 +3592,8 @@ static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
static int _nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
struct netlink_ext_ack *extack,
struct nlattr **attrs, bool monitor,
- struct cfg80211_chan_def *chandef)
+ struct cfg80211_chan_def *chandef,
+ bool permit_npca)
{
u32 control_freq;
@@ -3700,6 +3704,34 @@ static int _nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
}
}
+ if (attrs[NL80211_ATTR_NPCA_PRIMARY_FREQ]) {
+ if (!permit_npca) {
+ NL_SET_ERR_MSG_ATTR(extack,
+ attrs[NL80211_ATTR_NPCA_PRIMARY_FREQ],
+ "NPCA not supported");
+ return -EINVAL;
+ }
+
+ chandef->npca_chan =
+ ieee80211_get_channel(&rdev->wiphy,
+ nla_get_u32(attrs[NL80211_ATTR_NPCA_PRIMARY_FREQ]));
+ if (!chandef->npca_chan) {
+ NL_SET_ERR_MSG_ATTR(extack,
+ attrs[NL80211_ATTR_NPCA_PRIMARY_FREQ],
+ "invalid NPCA primary channel");
+ return -EINVAL;
+ }
+
+ chandef->npca_punctured =
+ nla_get_u32_default(attrs[NL80211_ATTR_NPCA_PUNCT_BITMAP],
+ chandef->punctured);
+ } else if (attrs[NL80211_ATTR_NPCA_PUNCT_BITMAP]) {
+ NL_SET_ERR_MSG_ATTR(extack,
+ attrs[NL80211_ATTR_NPCA_PUNCT_BITMAP],
+ "NPCA puncturing only valid with NPCA");
+ return -EINVAL;
+ }
+
if (!cfg80211_chandef_valid(chandef)) {
NL_SET_ERR_MSG_ATTR(extack, attrs[NL80211_ATTR_WIPHY_FREQ],
"invalid channel definition");
@@ -3727,9 +3759,11 @@ static int _nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
struct netlink_ext_ack *extack,
struct nlattr **attrs,
- struct cfg80211_chan_def *chandef)
+ struct cfg80211_chan_def *chandef,
+ bool permit_npca)
{
- return _nl80211_parse_chandef(rdev, extack, attrs, false, chandef);
+ return _nl80211_parse_chandef(rdev, extack, attrs, false, chandef,
+ permit_npca);
}
static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
@@ -3742,6 +3776,7 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR;
struct wireless_dev *wdev = NULL;
int link_id = _link_id;
+ bool permit_npca;
if (dev)
wdev = dev->ieee80211_ptr;
@@ -3756,9 +3791,13 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
link_id = 0;
}
+ /* allow parsing it - will check on start_ap or below */
+ permit_npca = iftype == NL80211_IFTYPE_AP ||
+ iftype == NL80211_IFTYPE_P2P_GO;
+
result = _nl80211_parse_chandef(rdev, info->extack, info->attrs,
iftype == NL80211_IFTYPE_MONITOR,
- &chandef);
+ &chandef, permit_npca);
if (result)
return result;
@@ -3777,6 +3816,9 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
return -EBUSY;
/* Only allow dynamic channel width changes */
+ cur_chan = wdev->links[link_id].ap.chandef.npca_chan;
+ if (chandef.npca_chan != cur_chan)
+ return -EBUSY;
cur_chan = wdev->links[link_id].ap.chandef.chan;
if (chandef.chan != cur_chan)
return -EBUSY;
@@ -4261,6 +4303,15 @@ int nl80211_send_chandef(struct sk_buff *msg, const struct cfg80211_chan_def *ch
nla_put_flag(msg, NL80211_ATTR_S1G_PRIMARY_2MHZ))
return -ENOBUFS;
+ if (chandef->npca_chan &&
+ nla_put_u32(msg, NL80211_ATTR_NPCA_PRIMARY_FREQ,
+ chandef->npca_chan->center_freq))
+ return -ENOBUFS;
+ if (chandef->npca_punctured &&
+ nla_put_u32(msg, NL80211_ATTR_NPCA_PUNCT_BITMAP,
+ chandef->npca_punctured))
+ return -ENOBUFS;
+
return 0;
}
EXPORT_SYMBOL(nl80211_send_chandef);
@@ -6692,6 +6743,28 @@ nl80211_parse_s1g_short_beacon(struct cfg80211_registered_device *rdev,
return 0;
}
+static int nl80211_check_npca(struct cfg80211_registered_device *rdev,
+ const struct cfg80211_chan_def *chandef,
+ enum nl80211_iftype iftype,
+ struct netlink_ext_ack *extack)
+{
+ const struct ieee80211_supported_band *sband;
+ const struct ieee80211_sta_uhr_cap *uhr_cap;
+
+ if (!chandef->npca_chan)
+ return 0;
+
+ sband = rdev->wiphy.bands[chandef->chan->band];
+ uhr_cap = ieee80211_get_uhr_iftype_cap(sband, iftype);
+
+ if (uhr_cap &&
+ (uhr_cap->mac.mac_cap[0] & IEEE80211_UHR_MAC_CAP0_NPCA_SUPP))
+ return 0;
+
+ NL_SET_ERR_MSG(extack, "NPCA not supported");
+ return -EINVAL;
+}
+
static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -6836,7 +6909,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
err = nl80211_parse_chandef(rdev, info->extack, info->attrs,
- ¶ms->chandef);
+ ¶ms->chandef, true);
if (err)
goto out;
} else if (wdev->valid_links) {
@@ -6850,6 +6923,11 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
goto out;
}
+ err = nl80211_check_npca(rdev, ¶ms->chandef, wdev->iftype,
+ info->extack);
+ if (err)
+ goto out;
+
beacon_check.iftype = wdev->iftype;
beacon_check.relax = true;
beacon_check.reg_power =
@@ -11331,7 +11409,8 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
if (dfs_region == NL80211_DFS_UNSET)
return -EINVAL;
- err = nl80211_parse_chandef(rdev, info->extack, info->attrs, &chandef);
+ err = nl80211_parse_chandef(rdev, info->extack, info->attrs, &chandef,
+ false);
if (err)
return err;
@@ -11420,7 +11499,8 @@ static int nl80211_notify_radar_detection(struct sk_buff *skb,
return -EINVAL;
}
- err = nl80211_parse_chandef(rdev, info->extack, info->attrs, &chandef);
+ err = nl80211_parse_chandef(rdev, info->extack, info->attrs, &chandef,
+ false);
if (err) {
GENL_SET_ERR_MSG(info, "Unable to extract chandef info");
return err;
@@ -11503,6 +11583,7 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
int err;
bool need_new_beacon = false;
bool need_handle_dfs_flag = true;
+ bool permit_npca = false;
u32 cs_count;
if (!rdev->ops->channel_switch ||
@@ -11520,6 +11601,8 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
*/
need_handle_dfs_flag = false;
+ permit_npca = true;
+
/* useless if AP is not running */
if (!wdev->links[link_id].ap.beacon_interval)
return -ENOTCONN;
@@ -11606,7 +11689,12 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
skip_beacons:
err = nl80211_parse_chandef(rdev, info->extack, info->attrs,
- ¶ms.chandef);
+ ¶ms.chandef, permit_npca);
+ if (err)
+ goto free;
+
+ err = nl80211_check_npca(rdev, ¶ms.chandef, wdev->iftype,
+ info->extack);
if (err)
goto free;
@@ -12830,7 +12918,7 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
}
err = nl80211_parse_chandef(rdev, info->extack, info->attrs,
- &ibss.chandef);
+ &ibss.chandef, false);
if (err)
return err;
@@ -13828,7 +13916,8 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
duration > rdev->wiphy.max_remain_on_channel_duration)
return -EINVAL;
- err = nl80211_parse_chandef(rdev, info->extack, info->attrs, &chandef);
+ err = nl80211_parse_chandef(rdev, info->extack, info->attrs, &chandef,
+ false);
if (err)
return err;
@@ -14045,7 +14134,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
chandef.chan = NULL;
if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
err = nl80211_parse_chandef(rdev, info->extack, info->attrs,
- &chandef);
+ &chandef, false);
if (err)
return err;
}
@@ -14448,7 +14537,7 @@ static int nl80211_join_ocb(struct sk_buff *skb, struct genl_info *info)
int err;
err = nl80211_parse_chandef(rdev, info->extack, info->attrs,
- &setup.chandef);
+ &setup.chandef, false);
if (err)
return err;
@@ -14524,7 +14613,7 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
err = nl80211_parse_chandef(rdev, info->extack, info->attrs,
- &setup.chandef);
+ &setup.chandef, false);
if (err)
return err;
} else {
@@ -17006,7 +17095,8 @@ static int nl80211_tdls_channel_switch(struct sk_buff *skb,
!info->attrs[NL80211_ATTR_OPER_CLASS])
return -EINVAL;
- err = nl80211_parse_chandef(rdev, info->extack, info->attrs, &chandef);
+ err = nl80211_parse_chandef(rdev, info->extack, info->attrs, &chandef,
+ false);
if (err)
return err;
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 048ba92c3e42..bdb065d14054 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Portions of this file
- * Copyright (C) 2018, 2020-2025 Intel Corporation
+ * Copyright (C) 2018, 2020-2026 Intel Corporation
*/
#ifndef __NET_WIRELESS_NL80211_H
#define __NET_WIRELESS_NL80211_H
@@ -25,7 +25,8 @@ static inline u64 wdev_id(struct wireless_dev *wdev)
int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
struct netlink_ext_ack *extack,
struct nlattr **attrs,
- struct cfg80211_chan_def *chandef);
+ struct cfg80211_chan_def *chandef,
+ bool npca_permitted);
int nl80211_parse_random_mac(struct nlattr **attrs,
u8 *mac_addr, u8 *mac_addr_mask);
diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c
index 556f30f5d60a..c2263b0e39d4 100644
--- a/net/wireless/pmsr.c
+++ b/net/wireless/pmsr.c
@@ -238,7 +238,7 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
return err;
err = nl80211_parse_chandef(rdev, info->extack, info->attrs,
- &out->chandef);
+ &out->chandef, false);
if (err)
return err;
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index af23f4fca90a..2aeccb6c59c5 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -141,7 +141,9 @@
__field(u32, center_freq1) \
__field(u32, freq1_offset) \
__field(u32, center_freq2) \
- __field(u16, punctured)
+ __field(u16, punctured) \
+ __field(u32, npca_pri_freq) \
+ __field(u16, npca_punctured)
#define CHAN_DEF_ASSIGN(chandef) \
do { \
if ((chandef) && (chandef)->chan) { \
@@ -155,6 +157,11 @@
__entry->freq1_offset = (chandef)->freq1_offset;\
__entry->center_freq2 = (chandef)->center_freq2;\
__entry->punctured = (chandef)->punctured; \
+ __entry->npca_pri_freq = \
+ (chandef)->npca_chan ? \
+ (chandef)->npca_chan->center_freq : 0; \
+ __entry->npca_punctured = \
+ (chandef)->npca_punctured; \
} else { \
__entry->band = 0; \
__entry->control_freq = 0; \
@@ -164,14 +171,17 @@
__entry->freq1_offset = 0; \
__entry->center_freq2 = 0; \
__entry->punctured = 0; \
+ __entry->npca_pri_freq = 0; \
+ __entry->npca_punctured = 0; \
} \
} while (0)
#define CHAN_DEF_PR_FMT \
- "band: %d, control freq: %u.%03u, width: %d, cf1: %u.%03u, cf2: %u, punct: 0x%x"
+ "band: %d, control freq: %u.%03u, width: %d, cf1: %u.%03u, cf2: %u, punct: 0x%x, npca:%u, npca_punct:0x%x"
#define CHAN_DEF_PR_ARG __entry->band, __entry->control_freq, \
__entry->freq_offset, __entry->width, \
__entry->center_freq1, __entry->freq1_offset, \
- __entry->center_freq2, __entry->punctured
+ __entry->center_freq2, __entry->punctured, \
+ __entry->npca_pri_freq, __entry->npca_punctured
#define FILS_AAD_ASSIGN(fa) \
do { \
--
2.53.0
^ permalink raw reply related
* [RFC wireless-next 0/8] initial UHR NPCA support
From: Johannes Berg @ 2026-03-03 14:26 UTC (permalink / raw)
To: linux-wireless
Here's the UHR Non-Primary Channel ACcess (NPCA) support I've been
working on.
The idea is to represent the NPCA channel/puncturing in the chandef
and have the other parameters per link. That's maybe not compeletely
right, but having them all in the chandef seemed too complex, and
these have to be there to be able to set up things.
There is, however, a problem with the way I've done this: I'm now
checking that NPCA is legal, i.e. the NPCA primary channel [sic]
is actually in the second half of the chandef. This cause problems
when adding DBE, because DBE extends the chandef as well, and you
could have, for 320 MHz:
| p | | | | n | | | | | | | | | | | |
| BSS Channel |
| NPCA channel |
| DBE Channel |
p = primary channel
n = NPCA primary channel
so that the NPCA isn't actually in the second half. I think now
the right way is to actually represent it as in the picture, but
it seems the spec is also still evolving wrt. the intersection of
NPCA and DBE. Some folks want NPCA to be in DBE but that doesn't
seem to work well (to me) with puncturing patterns etc.
So I think I'm probably going to change the chandef validation on
top of these changes when adding DBE, and then we need a separate
NPCA validation function for mac80211 instead, but that seems OK.
This is based on the patches I sent a few minutes ago:
https://lore.kernel.org/linux-wireless/20260303152558.00e7bc8e9f4b.Iafdf37fb0f4304bdcdb824977d61e17b38c47685@changeid/T/#u
https://lore.kernel.org/linux-wireless/20260303142641.273071-5-johannes@sipsolutions.net/T/#t
johannes
^ permalink raw reply
* Re: Use-after-free in iwl-mld after hardware fails to restart.
From: Ben Greear @ 2026-03-03 14:27 UTC (permalink / raw)
To: Korenblit, Miriam Rachel, linux-wireless
In-Reply-To: <DM3PPF63A6024A9188ACD0856EDD0826643A37FA@DM3PPF63A6024A9.namprd11.prod.outlook.com>
On 3/2/26 23:19, Korenblit, Miriam Rachel wrote:
>
>
>> -----Original Message-----
>> From: Ben Greear <greearb@candelatech.com>
>> Sent: Monday, March 2, 2026 9:00 PM
>> To: linux-wireless <linux-wireless@vger.kernel.org>; Korenblit, Miriam Rachel
>> <miriam.rachel.korenblit@intel.com>
>> Subject: Use-after-free in iwl-mld after hardware fails to restart.
>>
>> Hello,
>>
>> Here's another failure case from my torture test system.
>>
>> This is from a patched 6.18.14+ kernel, but from a look at upstream Linux
>> kernel, the problems are there as well.
>>
>> I believe the problem is something like this:
>>
>> firmware crashes several times and cannot recover. Maybe
>> Intel folks can tell why it is crashing? I'd love to know if that
>> is something that can be fixed in the driver.
>>
>> From mac80211/util.c:
>>
>> int ieee80211_reconfig(struct ieee80211_local *local)
>> is called, and gets to the failure case in this code (I see that second WARN in the
>> crash logs)
>> .....
>> /*
>> * Upon resume hardware can sometimes be goofy due to
>> * various platform / driver / bus issues, so restarting
>> * the device may at times not work immediately. Propagate
>> * the error.
>> */
>> res = drv_start(local);
>> if (res) {
>> if (suspended)
>> WARN(1, "Hardware became unavailable upon resume.
>> This could be a software issue prior to suspend or a hardware issue.\n");
>> else
>> WARN(1, "Hardware became unavailable during
>> restart.\n");
>> ieee80211_wake_queues_by_reason(hw,
>> IEEE80211_MAX_QUEUE_MAP,
>>
>> IEEE80211_QUEUE_STOP_REASON_SUSPEND,
>> false);
>> ieee80211_handle_reconfig_failure(local);
>> return res;
>>
>>
>> This method has comments about cleaning things up, but I don't see where it
>> actually
>> cleans up the driver. And it sets SDATA_IN_DRIVER to false, so a lot of the calls
>> in driver-ops.h that would otherwise tell the driver to clean up skip calls to
>> the driver.
>>
>> static void ieee80211_handle_reconfig_failure(struct ieee80211_local *local)
>> {
>> struct ieee80211_sub_if_data *sdata;
>> struct ieee80211_chanctx *ctx;
>>
>> lockdep_assert_wiphy(local->hw.wiphy);
>>
>> /*
>> * We get here if during resume the device can't be restarted properly.
>> * We might also get here if this happens during HW reset, which is a
>> * slightly different situation and we need to drop all connections in
>> * the latter case.
>> *
>> * Ask cfg80211 to turn off all interfaces, this will result in more
>> * warnings but at least we'll then get into a clean stopped state.
>> */
>>
>> local->resuming = false;
>> local->suspended = false;
>> local->in_reconfig = false;
>> local->reconfig_failure = true;
>>
>> ieee80211_flush_completed_scan(local, true);
>>
>> /* scheduled scan clearly can't be running any more, but tell
>> * cfg80211 and clear local state
>> */
>> ieee80211_sched_scan_end(local);
>>
>> list_for_each_entry(sdata, &local->interfaces, list)
>> sdata->flags &= ~IEEE80211_SDATA_IN_DRIVER;
>>
>> /* Mark channel contexts as not being in the driver any more to avoid
>> * removing them from the driver during the shutdown process...
>> */
>> list_for_each_entry(ctx, &local->chanctx_list, list)
>> ctx->driver_present = false;
>> }
>>
>>
>> So, how is the driver supposed to be cleaned up in this scenario?
> Driver was cleaned up in drv_start. See iwl_mld_restart_cleanup.
> Could you please share the iwlmld.ko and iwlwifi.ko files?
I have already made code changes and re-compiled to try to track it down.
If you can let me know what sort of information you'd like to see (like
gdb code listings?) I can gather it next time I can reproduce the problem.
Any idea why the firmware is crashing?
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* [PATCH wireless-next 3/3] wifi: cfg80211: split control freq check from chandef check
From: Johannes Berg @ 2026-03-03 14:26 UTC (permalink / raw)
To: linux-wireless; +Cc: Johannes Berg
In-Reply-To: <20260303142641.273071-5-johannes@sipsolutions.net>
From: Johannes Berg <johannes.berg@intel.com>
In order to introduce NPCA later, split the control frequency
check out of cfg80211_chandef_valid().
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/wireless/chan.c | 98 +++++++++++++++++++++++++--------------------
1 file changed, 54 insertions(+), 44 deletions(-)
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index d9d4e043bb39..e3c18a4392bb 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -6,7 +6,7 @@
*
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH
- * Copyright 2018-2025 Intel Corporation
+ * Copyright 2018-2026 Intel Corporation
*/
#include <linux/export.h>
@@ -339,6 +339,58 @@ static bool cfg80211_valid_center_freq(u32 center,
return (center - bw / 2 - 5945) % step == 0;
}
+static bool
+cfg80211_chandef_valid_control_freq(const struct cfg80211_chan_def *chandef,
+ u32 control_freq)
+{
+ switch (chandef->width) {
+ case NL80211_CHAN_WIDTH_5:
+ case NL80211_CHAN_WIDTH_10:
+ case NL80211_CHAN_WIDTH_20:
+ case NL80211_CHAN_WIDTH_20_NOHT:
+ case NL80211_CHAN_WIDTH_1:
+ case NL80211_CHAN_WIDTH_2:
+ case NL80211_CHAN_WIDTH_4:
+ case NL80211_CHAN_WIDTH_8:
+ case NL80211_CHAN_WIDTH_16:
+ /* checked separately */
+ break;
+ case NL80211_CHAN_WIDTH_320:
+ if (chandef->center_freq1 == control_freq + 150 ||
+ chandef->center_freq1 == control_freq + 130 ||
+ chandef->center_freq1 == control_freq + 110 ||
+ chandef->center_freq1 == control_freq + 90 ||
+ chandef->center_freq1 == control_freq - 90 ||
+ chandef->center_freq1 == control_freq - 110 ||
+ chandef->center_freq1 == control_freq - 130 ||
+ chandef->center_freq1 == control_freq - 150)
+ break;
+ fallthrough;
+ case NL80211_CHAN_WIDTH_160:
+ if (chandef->center_freq1 == control_freq + 70 ||
+ chandef->center_freq1 == control_freq + 50 ||
+ chandef->center_freq1 == control_freq - 50 ||
+ chandef->center_freq1 == control_freq - 70)
+ break;
+ fallthrough;
+ case NL80211_CHAN_WIDTH_80P80:
+ case NL80211_CHAN_WIDTH_80:
+ if (chandef->center_freq1 == control_freq + 30 ||
+ chandef->center_freq1 == control_freq - 30)
+ break;
+ fallthrough;
+ case NL80211_CHAN_WIDTH_40:
+ if (chandef->center_freq1 == control_freq + 10 ||
+ chandef->center_freq1 == control_freq - 10)
+ break;
+ fallthrough;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef)
{
u32 control_freq, control_freq_khz, start_khz, end_khz;
@@ -393,50 +445,8 @@ bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef)
break;
}
- switch (chandef->width) {
- case NL80211_CHAN_WIDTH_5:
- case NL80211_CHAN_WIDTH_10:
- case NL80211_CHAN_WIDTH_20:
- case NL80211_CHAN_WIDTH_20_NOHT:
- case NL80211_CHAN_WIDTH_1:
- case NL80211_CHAN_WIDTH_2:
- case NL80211_CHAN_WIDTH_4:
- case NL80211_CHAN_WIDTH_8:
- case NL80211_CHAN_WIDTH_16:
- /* all checked above */
- break;
- case NL80211_CHAN_WIDTH_320:
- if (chandef->center_freq1 == control_freq + 150 ||
- chandef->center_freq1 == control_freq + 130 ||
- chandef->center_freq1 == control_freq + 110 ||
- chandef->center_freq1 == control_freq + 90 ||
- chandef->center_freq1 == control_freq - 90 ||
- chandef->center_freq1 == control_freq - 110 ||
- chandef->center_freq1 == control_freq - 130 ||
- chandef->center_freq1 == control_freq - 150)
- break;
- fallthrough;
- case NL80211_CHAN_WIDTH_160:
- if (chandef->center_freq1 == control_freq + 70 ||
- chandef->center_freq1 == control_freq + 50 ||
- chandef->center_freq1 == control_freq - 50 ||
- chandef->center_freq1 == control_freq - 70)
- break;
- fallthrough;
- case NL80211_CHAN_WIDTH_80P80:
- case NL80211_CHAN_WIDTH_80:
- if (chandef->center_freq1 == control_freq + 30 ||
- chandef->center_freq1 == control_freq - 30)
- break;
- fallthrough;
- case NL80211_CHAN_WIDTH_40:
- if (chandef->center_freq1 == control_freq + 10 ||
- chandef->center_freq1 == control_freq - 10)
- break;
- fallthrough;
- default:
+ if (!cfg80211_chandef_valid_control_freq(chandef, control_freq))
return false;
- }
if (!cfg80211_valid_center_freq(chandef->center_freq1, chandef->width))
return false;
--
2.53.0
^ permalink raw reply related
* [PATCH wireless-next 2/3] wifi: mac80211: always use full chanctx compatible check
From: Johannes Berg @ 2026-03-03 14:26 UTC (permalink / raw)
To: linux-wireless; +Cc: Johannes Berg
In-Reply-To: <20260303142641.273071-5-johannes@sipsolutions.net>
From: Johannes Berg <johannes.berg@intel.com>
For NPCA, we need to treat the channel request differently
for AP and other interfaces (APs can share NPCA, under the
assumption that userspace will set them up with the same
BSS color.) This is difficult if we have to check against
a chanreq made up from the chanctx, but this isn't a code
path that needs to be highly optimised, so just always use
the (originally) recheck functionality to check against
all users of the chanctx.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/chan.c | 90 ++++++++++++++++++++-------------------------
1 file changed, 39 insertions(+), 51 deletions(-)
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 4447cf03c41b..2f0c93f3ace6 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* mac80211 - channel management
- * Copyright 2020 - 2025 Intel Corporation
+ * Copyright 2020-2026 Intel Corporation
*/
#include <linux/nl80211.h>
@@ -239,24 +239,45 @@ ieee80211_chanreq_compatible(const struct ieee80211_chan_req *a,
return tmp;
}
+/*
+ * When checking for compatible, check against all the links using
+ * the chanctx (except the one passed that might be changing) to
+ * allow changes to the AP's bandwidth for wider bandwidth OFDMA
+ * purposes, which wouldn't be treated as compatible by checking
+ * against the chanctx's oper/ap chandefs.
+ */
static const struct ieee80211_chan_req *
-ieee80211_chanctx_compatible(struct ieee80211_chanctx *ctx,
+_ieee80211_chanctx_compatible(struct ieee80211_local *local,
+ struct ieee80211_link_data *skip_link,
+ struct ieee80211_chanctx *ctx,
+ const struct ieee80211_chan_req *req,
+ struct ieee80211_chan_req *tmp)
+{
+ const struct ieee80211_chan_req *ret = req;
+ struct ieee80211_chanctx_user_iter iter;
+
+ lockdep_assert_wiphy(local->hw.wiphy);
+
+ for_each_chanctx_user_all(local, ctx, &iter) {
+ if (iter.link && iter.link == skip_link)
+ continue;
+
+ ret = ieee80211_chanreq_compatible(ret, iter.chanreq, tmp);
+ if (!ret)
+ return NULL;
+ }
+
+ *tmp = *ret;
+ return tmp;
+}
+
+static const struct ieee80211_chan_req *
+ieee80211_chanctx_compatible(struct ieee80211_local *local,
+ struct ieee80211_chanctx *ctx,
const struct ieee80211_chan_req *req,
struct ieee80211_chan_req *tmp)
{
- const struct ieee80211_chan_req *ret;
- struct ieee80211_chan_req tmp2;
-
- *tmp = (struct ieee80211_chan_req){
- .oper = ctx->conf.def,
- .ap = ctx->conf.ap,
- };
-
- ret = ieee80211_chanreq_compatible(tmp, req, &tmp2);
- if (!ret)
- return NULL;
- *tmp = *ret;
- return tmp;
+ return _ieee80211_chanctx_compatible(local, NULL, ctx, req, tmp);
}
static const struct ieee80211_chan_req *
@@ -756,7 +777,8 @@ ieee80211_find_chanctx(struct ieee80211_local *local,
if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE)
continue;
- compat = ieee80211_chanctx_compatible(ctx, chanreq, &tmp);
+ compat = ieee80211_chanctx_compatible(local, ctx, chanreq,
+ &tmp);
if (!compat)
continue;
@@ -2128,40 +2150,6 @@ int ieee80211_link_use_reserved_context(struct ieee80211_link_data *link)
return 0;
}
-/*
- * This is similar to ieee80211_chanctx_compatible(), but rechecks
- * against all the links actually using it (except the one that's
- * passed, since that one is changing).
- * This is done in order to allow changes to the AP's bandwidth for
- * wider bandwidth OFDMA purposes, which wouldn't be treated as
- * compatible by ieee80211_chanctx_recheck() but is OK if the link
- * requesting the update is the only one using it.
- */
-static const struct ieee80211_chan_req *
-ieee80211_chanctx_recheck(struct ieee80211_local *local,
- struct ieee80211_link_data *skip_link,
- struct ieee80211_chanctx *ctx,
- const struct ieee80211_chan_req *req,
- struct ieee80211_chan_req *tmp)
-{
- const struct ieee80211_chan_req *ret = req;
- struct ieee80211_chanctx_user_iter iter;
-
- lockdep_assert_wiphy(local->hw.wiphy);
-
- for_each_chanctx_user_all(local, ctx, &iter) {
- if (iter.link == skip_link)
- continue;
-
- ret = ieee80211_chanreq_compatible(ret, iter.chanreq, tmp);
- if (!ret)
- return NULL;
- }
-
- *tmp = *ret;
- return tmp;
-}
-
int ieee80211_link_change_chanreq(struct ieee80211_link_data *link,
const struct ieee80211_chan_req *chanreq,
u64 *changed)
@@ -2198,7 +2186,7 @@ int ieee80211_link_change_chanreq(struct ieee80211_link_data *link,
ctx = container_of(conf, struct ieee80211_chanctx, conf);
- compat = ieee80211_chanctx_recheck(local, link, ctx, chanreq, &tmp);
+ compat = _ieee80211_chanctx_compatible(local, link, ctx, chanreq, &tmp);
if (!compat)
return -EINVAL;
--
2.53.0
^ permalink raw reply related
* [PATCH wireless-next 1/3] wifi: mac80211: refactor chandef tracing macros
From: Johannes Berg @ 2026-03-03 14:26 UTC (permalink / raw)
To: linux-wireless; +Cc: Johannes Berg, Miriam Rachel Korenblit
In-Reply-To: <20260303142641.273071-5-johannes@sipsolutions.net>
From: Johannes Berg <johannes.berg@intel.com>
We don't need to duplicate the macros, just make a generic
one that gets the name prefix to be used, and use that to
create the others. While at it, add the puncturing bitmap
to the trace and simplify the ternary expressions.
Reviewed-by: Miriam Rachel Korenblit <miriam.rachel.korenblit@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/trace.h | 94 ++++++++++++++++++--------------------------
1 file changed, 38 insertions(+), 56 deletions(-)
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index c04d4547e8f4..1f0c07eaad1b 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -2,7 +2,7 @@
/*
* Portions of this file
* Copyright(c) 2016-2017 Intel Deutschland GmbH
- * Copyright (C) 2018 - 2024 Intel Corporation
+ * Copyright (C) 2018-2024, 2026 Intel Corporation
*/
#if !defined(__MAC80211_DRIVER_TRACE) || defined(TRACE_HEADER_MULTI_READ)
@@ -37,64 +37,46 @@
#define VIF_PR_FMT " vif:%s(%d%s)"
#define VIF_PR_ARG __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : ""
-#define CHANDEF_ENTRY __field(u32, control_freq) \
- __field(u32, freq_offset) \
- __field(u32, chan_width) \
- __field(u32, center_freq1) \
- __field(u32, freq1_offset) \
- __field(u32, center_freq2)
-#define CHANDEF_ASSIGN(c) \
- __entry->control_freq = (c) ? ((c)->chan ? (c)->chan->center_freq : 0) : 0; \
- __entry->freq_offset = (c) ? ((c)->chan ? (c)->chan->freq_offset : 0) : 0; \
- __entry->chan_width = (c) ? (c)->width : 0; \
- __entry->center_freq1 = (c) ? (c)->center_freq1 : 0; \
- __entry->freq1_offset = (c) ? (c)->freq1_offset : 0; \
- __entry->center_freq2 = (c) ? (c)->center_freq2 : 0;
-#define CHANDEF_PR_FMT " chandef(%d.%03d MHz,width:%d,center: %d.%03d/%d MHz)"
-#define CHANDEF_PR_ARG __entry->control_freq, __entry->freq_offset, __entry->chan_width, \
- __entry->center_freq1, __entry->freq1_offset, __entry->center_freq2
+#define __CHANDEF_ENTRY(n) \
+ __field(u32, n##control_freq) \
+ __field(u32, n##freq_offset) \
+ __field(u32, n##chan_width) \
+ __field(u32, n##center_freq1) \
+ __field(u32, n##freq1_offset) \
+ __field(u32, n##center_freq2) \
+ __field(u16, n##punctured)
+#define __CHANDEF_ASSIGN(n, c) \
+ __entry->n##control_freq = (c) && (c)->chan ? \
+ (c)->chan->center_freq : 0; \
+ __entry->n##freq_offset = (c) && (c)->chan ? \
+ (c)->chan->freq_offset : 0; \
+ __entry->n##chan_width = (c) ? (c)->width : 0; \
+ __entry->n##center_freq1 = (c) ? (c)->center_freq1 : 0; \
+ __entry->n##freq1_offset = (c) ? (c)->freq1_offset : 0; \
+ __entry->n##center_freq2 = (c) ? (c)->center_freq2 : 0; \
+ __entry->n##punctured = (c) ? (c)->punctured : 0;
+#define __CHANDEF_PR_FMT(n) \
+ " " #n "(%d.%03d MHz,width:%d,center: %d.%03d/%d MHz, punct:0x%x)"
+#define __CHANDEF_PR_ARG(n) \
+ __entry->n##control_freq, __entry->n##freq_offset, \
+ __entry->n##chan_width, __entry->n##center_freq1, \
+ __entry->n##freq1_offset, __entry->n##center_freq2, \
+ __entry->n##punctured
-#define MIN_CHANDEF_ENTRY \
- __field(u32, min_control_freq) \
- __field(u32, min_freq_offset) \
- __field(u32, min_chan_width) \
- __field(u32, min_center_freq1) \
- __field(u32, min_freq1_offset) \
- __field(u32, min_center_freq2)
+#define CHANDEF_ENTRY __CHANDEF_ENTRY()
+#define CHANDEF_ASSIGN(c) __CHANDEF_ASSIGN(, c)
+#define CHANDEF_PR_FMT __CHANDEF_PR_FMT(chandef)
+#define CHANDEF_PR_ARG __CHANDEF_PR_ARG()
-#define MIN_CHANDEF_ASSIGN(c) \
- __entry->min_control_freq = (c)->chan ? (c)->chan->center_freq : 0; \
- __entry->min_freq_offset = (c)->chan ? (c)->chan->freq_offset : 0; \
- __entry->min_chan_width = (c)->width; \
- __entry->min_center_freq1 = (c)->center_freq1; \
- __entry->min_freq1_offset = (c)->freq1_offset; \
- __entry->min_center_freq2 = (c)->center_freq2;
-#define MIN_CHANDEF_PR_FMT " mindef(%d.%03d MHz,width:%d,center: %d.%03d/%d MHz)"
-#define MIN_CHANDEF_PR_ARG __entry->min_control_freq, __entry->min_freq_offset, \
- __entry->min_chan_width, \
- __entry->min_center_freq1, __entry->min_freq1_offset, \
- __entry->min_center_freq2
+#define MIN_CHANDEF_ENTRY __CHANDEF_ENTRY(min)
+#define MIN_CHANDEF_ASSIGN(c) __CHANDEF_ASSIGN(min, c)
+#define MIN_CHANDEF_PR_FMT __CHANDEF_PR_FMT(mindef)
+#define MIN_CHANDEF_PR_ARG __CHANDEF_PR_ARG(min)
-#define AP_CHANDEF_ENTRY \
- __field(u32, ap_control_freq) \
- __field(u32, ap_freq_offset) \
- __field(u32, ap_chan_width) \
- __field(u32, ap_center_freq1) \
- __field(u32, ap_freq1_offset) \
- __field(u32, ap_center_freq2)
-
-#define AP_CHANDEF_ASSIGN(c) \
- __entry->ap_control_freq = (c)->chan ? (c)->chan->center_freq : 0;\
- __entry->ap_freq_offset = (c)->chan ? (c)->chan->freq_offset : 0;\
- __entry->ap_chan_width = (c)->chan ? (c)->width : 0; \
- __entry->ap_center_freq1 = (c)->chan ? (c)->center_freq1 : 0; \
- __entry->ap_freq1_offset = (c)->chan ? (c)->freq1_offset : 0; \
- __entry->ap_center_freq2 = (c)->chan ? (c)->center_freq2 : 0;
-#define AP_CHANDEF_PR_FMT " ap(%d.%03d MHz,width:%d,center: %d.%03d/%d MHz)"
-#define AP_CHANDEF_PR_ARG __entry->ap_control_freq, __entry->ap_freq_offset, \
- __entry->ap_chan_width, \
- __entry->ap_center_freq1, __entry->ap_freq1_offset, \
- __entry->ap_center_freq2
+#define AP_CHANDEF_ENTRY __CHANDEF_ENTRY(ap)
+#define AP_CHANDEF_ASSIGN(c) __CHANDEF_ASSIGN(ap, c)
+#define AP_CHANDEF_PR_FMT __CHANDEF_PR_FMT(ap)
+#define AP_CHANDEF_PR_ARG __CHANDEF_PR_ARG(ap)
#define CHANCTX_ENTRY CHANDEF_ENTRY \
MIN_CHANDEF_ENTRY \
--
2.53.0
^ permalink raw reply related
* [PATCH wireless-next 0/3] wifi: cfg/mac: refactor for NPCA
From: Johannes Berg @ 2026-03-03 14:26 UTC (permalink / raw)
To: linux-wireless
This is just some refactor for the addition of NPCA.
johannes
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox