Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH 1/1] wifi: iwlwifi: mld: fix TSO segmentation explosion when AMSDU is disabled
From: Cole Leavitt @ 2026-02-18 14:47 UTC (permalink / raw)
  To: greearb; +Cc: johannes, linux-wireless, miriam.rachel.korenblit, Cole Leavitt
In-Reply-To: <20260218144723.31699-1-cole@unwrap.rs>

When the TLC notification disables AMSDU for a TID, the MLD driver sets
max_tid_amsdu_len to the sentinel value 1. The TSO segmentation path in
iwl_mld_tx_tso_segment() checks for zero but not for this sentinel,
allowing it to reach the num_subframes calculation:

  num_subframes = (max_tid_amsdu_len + pad) / (subf_len + pad)
                = (1 + 2) / (1534 + 2) = 0

This zero propagates to iwl_tx_tso_segment() which sets:

  gso_size = num_subframes * mss = 0

Calling skb_gso_segment() with gso_size=0 creates over 32000 tiny
segments from a single GSO skb. This floods the TX ring with ~1024
micro-frames (the rest are purged), creating a massive burst of TX
completion events that can lead to memory corruption and a subsequent
use-after-free in TCP's retransmit queue (refcount underflow in
tcp_shifted_skb, NULL deref in tcp_rack_detect_loss).

The MVM driver is immune because it checks mvmsta->amsdu_enabled before
reaching the num_subframes calculation. The MLD driver has no equivalent
bitmap check and relies solely on max_tid_amsdu_len, which does not
catch the sentinel value.

Fix this by falling back to single-subframe TSO (num_subframes=1) when
the AMSDU length limit is too small to fit even one subframe.

Fixes: d1e879ec600f ("wifi: iwlwifi: add iwlmld sub-driver")
Signed-off-by: Cole Leavitt <cole@unwrap.rs>
---
 drivers/net/wireless/intel/iwlwifi/mld/tx.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/tx.c b/drivers/net/wireless/intel/iwlwifi/mld/tx.c
index fbb672f4d8c7..1d47254a4148 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/tx.c
@@ -846,6 +846,17 @@ static int iwl_mld_tx_tso_segment(struct iwl_mld *mld, struct sk_buff *skb,
 	 */
 	num_subframes = (max_tid_amsdu_len + pad) / (subf_len + pad);
 
+	/* If the AMSDU length limit is too small to fit even a single
+	 * subframe (e.g. max_tid_amsdu_len is the sentinel value 1 set by
+	 * the TLC notification when AMSDU is disabled for this TID), fall
+	 * back to non-AMSDU TSO segmentation. Without this guard,
+	 * num_subframes=0 causes gso_size=0 in iwl_tx_tso_segment(),
+	 * which makes skb_gso_segment() produce tens of thousands of
+	 * 1-byte segments, overloading the TX ring and completion path.
+	 */
+	if (!num_subframes)
+		return iwl_tx_tso_segment(skb, 1, netdev_flags, mpdus_skbs);
+
 	if (sta->max_amsdu_subframes &&
 	    num_subframes > sta->max_amsdu_subframes)
 		num_subframes = sta->max_amsdu_subframes;
-- 
2.52.0


^ permalink raw reply related

* [PATCH 0/1] wifi: iwlwifi: mld: fix TSO segmentation explosion causing UAF
From: Cole Leavitt @ 2026-02-18 14:47 UTC (permalink / raw)
  To: greearb; +Cc: johannes, linux-wireless, miriam.rachel.korenblit, Cole Leavitt
In-Reply-To: <9edde56d-bfdc-40f6-862c-b69950cc2f25@candelatech.com>

Ben,

I've been digging into the use-after-free crash you reported on your
BE200 running the MLD driver (tcp_shifted_skb refcount underflow,
followed by NULL deref in tcp_rack_detect_loss). I think I found the
root cause -- it's a missing guard in the MLD TSO segmentation path
that lets num_subframes=0 reach skb_gso_segment(), producing the 32k+
segment explosion you're seeing.

Here's the full chain:

1) mld/tlc.c:790 -- when firmware's TLC notification disables AMSDU for
   a TID (bit not set in amsdu_enabled), the MLD driver sets:

     link_sta->agg.max_tid_amsdu_len[i] = 1;

   This sentinel value 1 means "AMSDU disabled on this TID".

2) mld/tx.c:836-837 -- the TSO path checks:

     max_tid_amsdu_len = sta->cur->max_tid_amsdu_len[tid];
     if (!max_tid_amsdu_len)   // <-- only catches zero, not 1
         return iwl_tx_tso_segment(skb, 1, ...);

   Value 1 passes this check.

3) mld/tx.c:847 -- the division produces zero:

     num_subframes = (1 + 2) / (1534 + 2) = 0

   Any max_tid_amsdu_len below ~1534 (one subframe) produces 0 here.

4) iwl-utils.c:27 -- gso_size is set to zero:

     skb_shinfo(skb)->gso_size = num_subframes * mss = 0 * 1460 = 0

5) iwl-utils.c:30 -- skb_gso_segment() with gso_size=0 creates 32001+
   tiny segments, which is the error you're seeing:

     "skbuff: ERROR: Found more than 32000 packets in skb_segment"
     "iwl-mvm-tx-tso-segment, list gso-segment list is huge: 32001"

6) mld/tx.c:912-936 -- the loop queues ~1024 of those segments to the
   TX ring before it fills up, then purges the rest. This creates a
   massive burst of tiny frames that stress the BA completion path.

The MVM driver is immune because it checks mvmsta->amsdu_enabled (a
separate bitmap) at tx.c:912 and tx.c:936 BEFORE ever reaching the
num_subframes calculation. MLD has no equivalent -- it relies solely on
max_tid_amsdu_len, and the sentinel value 1 slips through.

This explains all your observations:
- 6.18 regression: BE200 moved from MVM (has guard) to MLD (no guard)
- AP-specific: the problem AP causes firmware to disable AMSDU for the
  active TID (other APs enable it, so max_tid_amsdu_len gets a proper
  value from iwl_mld_get_amsdu_size_of_tid())
- 28min gap between TSO explosion and UAF: the ~1024 micro-frame burst
  creates massive alloc/free churn in the skb slab, which can corrupt
  TCP retransmit queue entries allocated from the same cache
- No firmware error: firmware is fine, the bug is purely in MLD's TSO
  parameter calculation

The fix (in patch 1/1) adds a guard after the num_subframes
calculation -- if it's zero, fall back to single-subframe TSO
(num_subframes=1), which correctly sets gso_size=mss. This matches what
MVM effectively does via its amsdu_enabled checks.

Could you test this against the problem AP? Two things that would help
confirm the theory:

1) Before applying the fix, add this debug print to see the actual
   max_tid_amsdu_len value with the problem AP:

     // In iwl_mld_tx_tso_segment(), after line 847
     if (!num_subframes)
         pr_warn_once("iwlmld: num_subframes=0, max_tid_amsdu_len=%u "
                      "subf_len=%u mss=%u\n",
                      max_tid_amsdu_len, subf_len, mss);

2) After applying the fix, run against the problem AP for 1+ day and
   check if both the TSO explosion AND the UAF are gone.

I also noticed a few secondary defense-in-depth regressions in MLD's TX
completion path vs MVM:

- MLD's iwl_mld_tx_reclaim_txq() has no per-TID reclaim tracking
  (MVM has tid_data->next_reclaimed and validates tid_data->txq_id)
- The transport-level reclaim_lock prevents direct double-free, but
  MLD is missing MVM's extra safety checks

These are probably not directly causing your crash, but worth noting.

Cole Leavitt (1):
  wifi: iwlwifi: mld: fix TSO segmentation explosion when AMSDU is
    disabled

 drivers/net/wireless/intel/iwlwifi/mld/tx.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

-- 
2.52.0


^ permalink raw reply

* Re: [PATCH] wifi: iwlwifi: prevent NAPI processing after firmware error
From: Cole Leavitt @ 2026-02-18 14:44 UTC (permalink / raw)
  To: Ben Greear; +Cc: Johannes Berg, linux-wireless, Miri Korenblit
In-Reply-To: <9edde56d-bfdc-40f6-862c-b69950cc2f25@candelatech.com>

Ben,

I've been digging into the use-after-free crash you reported on your
BE200 running the MLD driver (tcp_shifted_skb refcount underflow,
followed by NULL deref in tcp_rack_detect_loss). I think I found the
root cause -- it's a missing guard in the MLD TSO segmentation path
that lets num_subframes=0 reach skb_gso_segment(), producing the 32k+
segment explosion you're seeing.

Here's the full chain:

1) mld/tlc.c:790 -- when firmware's TLC notification disables AMSDU for
   a TID (bit not set in amsdu_enabled), the MLD driver sets:

     link_sta->agg.max_tid_amsdu_len[i] = 1;

   This sentinel value 1 means "AMSDU disabled on this TID".

2) mld/tx.c:836-837 -- the TSO path checks:

     max_tid_amsdu_len = sta->cur->max_tid_amsdu_len[tid];
     if (!max_tid_amsdu_len)   // <-- only catches zero, not 1
         return iwl_tx_tso_segment(skb, 1, ...);

   Value 1 passes this check.

3) mld/tx.c:847 -- the division produces zero:

     num_subframes = (1 + 2) / (1534 + 2) = 0

   Any max_tid_amsdu_len below ~1534 (one subframe) produces 0 here.

4) iwl-utils.c:27 -- gso_size is set to zero:

     skb_shinfo(skb)->gso_size = num_subframes * mss = 0 * 1460 = 0

5) iwl-utils.c:30 -- skb_gso_segment() with gso_size=0 creates 32001+
   tiny segments, which is the error you're seeing:

     "skbuff: ERROR: Found more than 32000 packets in skb_segment"
     "iwl-mvm-tx-tso-segment, list gso-segment list is huge: 32001"

6) mld/tx.c:912-936 -- the loop queues ~1024 of those segments to the
   TX ring before it fills up, then purges the rest. This creates a
   massive burst of tiny frames that stress the BA completion path.

The MVM driver is immune because it checks mvmsta->amsdu_enabled (a
separate bitmap) at tx.c:912 and tx.c:936 BEFORE ever reaching the
num_subframes calculation. MLD has no equivalent -- it relies solely on
max_tid_amsdu_len, and the sentinel value 1 slips through.

This explains all your observations:
- 6.18 regression: BE200 moved from MVM (has guard) to MLD (no guard)
- AP-specific: the problem AP causes firmware to disable AMSDU for the
  active TID (other APs enable it, so max_tid_amsdu_len gets a proper
  value from iwl_mld_get_amsdu_size_of_tid())
- 28min gap between TSO explosion and UAF: the ~1024 micro-frame burst
  creates massive alloc/free churn in the skb slab, which can corrupt
  TCP retransmit queue entries allocated from the same cache
- No firmware error: firmware is fine, the bug is purely in MLD's TSO
  parameter calculation

Fix below. It adds a guard after the num_subframes calculation -- if
it's zero, fall back to single-subframe TSO (num_subframes=1), which
correctly sets gso_size=mss. This matches what MVM effectively does via
its amsdu_enabled checks.

Could you test this against the problem AP? Two things that would help
confirm the theory:

1) Before applying the fix, add this debug print to see the actual
   max_tid_amsdu_len value with the problem AP:

     // In iwl_mld_tx_tso_segment(), after line 847
     if (!num_subframes)
         pr_warn_once("iwlmld: num_subframes=0, max_tid_amsdu_len=%u "
                      "subf_len=%u mss=%u\n",
                      max_tid_amsdu_len, subf_len, mss);

2) After applying the fix, run against the problem AP for 1+ day and
   check if both the TSO explosion AND the UAF are gone.

I also noticed a few secondary defense-in-depth regressions in MLD's
TX completion path vs MVM:

- MLD's iwl_mld_tx_reclaim_txq() has no per-TID reclaim tracking
  (MVM has tid_data->next_reclaimed and validates tid_data->txq_id)
- The transport-level reclaim_lock prevents direct double-free, but
  MLD is missing MVM's extra safety checks

These are probably not directly causing your crash, but worth noting.

---
 drivers/net/wireless/intel/iwlwifi/mld/tx.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/tx.c b/drivers/net/wireless/intel/iwlwifi/mld/tx.c
index fbb672f4d8c7..1d47254a4148 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/tx.c
@@ -846,6 +846,17 @@ static int iwl_mld_tx_tso_segment(struct iwl_mld *mld, struct sk_buff *skb,
 	 */
 	num_subframes = (max_tid_amsdu_len + pad) / (subf_len + pad);
 
+	/* If the AMSDU length limit is too small to fit even a single
+	 * subframe (e.g. max_tid_amsdu_len is the sentinel value 1 set by
+	 * the TLC notification when AMSDU is disabled for this TID), fall
+	 * back to non-AMSDU TSO segmentation. Without this guard,
+	 * num_subframes=0 causes gso_size=0 in iwl_tx_tso_segment(),
+	 * which makes skb_gso_segment() produce tens of thousands of
+	 * 1-byte segments, overloading the TX ring and completion path.
+	 */
+	if (!num_subframes)
+		return iwl_tx_tso_segment(skb, 1, netdev_flags, mpdus_skbs);
+
 	if (sta->max_amsdu_subframes &&
 	    num_subframes > sta->max_amsdu_subframes)
 		num_subframes = sta->max_amsdu_subframes;
-- 
2.52.0

Cole


^ permalink raw reply related

* Re: [PATCH] wifi: iwlwifi: prevent NAPI processing after firmware error
From: Cole Leavitt @ 2026-02-18 14:44 UTC (permalink / raw)
  To: Ben Greear; +Cc: Johannes Berg, linux-wireless, Miri Korenblit
In-Reply-To: <9edde56d-bfdc-40f6-862c-b69950cc2f25@candelatech.com>

Ben,

I've been digging into the use-after-free crash you reported on your
BE200 running the MLD driver (tcp_shifted_skb refcount underflow,
followed by NULL deref in tcp_rack_detect_loss). I think I found the
root cause -- it's a missing guard in the MLD TSO segmentation path
that lets num_subframes=0 reach skb_gso_segment(), producing the 32k+
segment explosion you're seeing.

Here's the full chain:

1) mld/tlc.c:790 -- when firmware's TLC notification disables AMSDU for
   a TID (bit not set in amsdu_enabled), the MLD driver sets:

     link_sta->agg.max_tid_amsdu_len[i] = 1;

   This sentinel value 1 means "AMSDU disabled on this TID".

2) mld/tx.c:836-837 -- the TSO path checks:

     max_tid_amsdu_len = sta->cur->max_tid_amsdu_len[tid];
     if (!max_tid_amsdu_len)   // <-- only catches zero, not 1
         return iwl_tx_tso_segment(skb, 1, ...);

   Value 1 passes this check.

3) mld/tx.c:847 -- the division produces zero:

     num_subframes = (1 + 2) / (1534 + 2) = 0

   Any max_tid_amsdu_len below ~1534 (one subframe) produces 0 here.

4) iwl-utils.c:27 -- gso_size is set to zero:

     skb_shinfo(skb)->gso_size = num_subframes * mss = 0 * 1460 = 0

5) iwl-utils.c:30 -- skb_gso_segment() with gso_size=0 creates 32001+
   tiny segments, which is the error you're seeing:

     "skbuff: ERROR: Found more than 32000 packets in skb_segment"
     "iwl-mvm-tx-tso-segment, list gso-segment list is huge: 32001"

6) mld/tx.c:912-936 -- the loop queues ~1024 of those segments to the
   TX ring before it fills up, then purges the rest. This creates a
   massive burst of tiny frames that stress the BA completion path.

The MVM driver is immune because it checks mvmsta->amsdu_enabled (a
separate bitmap) at tx.c:912 and tx.c:936 BEFORE ever reaching the
num_subframes calculation. MLD has no equivalent -- it relies solely on
max_tid_amsdu_len, and the sentinel value 1 slips through.

This explains all your observations:
- 6.18 regression: BE200 moved from MVM (has guard) to MLD (no guard)
- AP-specific: the problem AP causes firmware to disable AMSDU for the
  active TID (other APs enable it, so max_tid_amsdu_len gets a proper
  value from iwl_mld_get_amsdu_size_of_tid())
- 28min gap between TSO explosion and UAF: the ~1024 micro-frame burst
  creates massive alloc/free churn in the skb slab, which can corrupt
  TCP retransmit queue entries allocated from the same cache
- No firmware error: firmware is fine, the bug is purely in MLD's TSO
  parameter calculation

Fix below. It adds a guard after the num_subframes calculation -- if
it's zero, fall back to single-subframe TSO (num_subframes=1), which
correctly sets gso_size=mss. This matches what MVM effectively does via
its amsdu_enabled checks.

Could you test this against the problem AP? Two things that would help
confirm the theory:

1) Before applying the fix, add this debug print to see the actual
   max_tid_amsdu_len value with the problem AP:

     // In iwl_mld_tx_tso_segment(), after line 847
     if (!num_subframes)
         pr_warn_once("iwlmld: num_subframes=0, max_tid_amsdu_len=%u "
                      "subf_len=%u mss=%u\n",
                      max_tid_amsdu_len, subf_len, mss);

2) After applying the fix, run against the problem AP for 1+ day and
   check if both the TSO explosion AND the UAF are gone.

I also noticed a few secondary defense-in-depth regressions in MLD's
TX completion path vs MVM:

- MLD's iwl_mld_tx_reclaim_txq() has no per-TID reclaim tracking
  (MVM has tid_data->next_reclaimed and validates tid_data->txq_id)
- The transport-level reclaim_lock prevents direct double-free, but
  MLD is missing MVM's extra safety checks

These are probably not directly causing your crash, but worth noting.

---
 drivers/net/wireless/intel/iwlwifi/mld/tx.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/tx.c b/drivers/net/wireless/intel/iwlwifi/mld/tx.c
index fbb672f4d8c7..1d47254a4148 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/tx.c
@@ -846,6 +846,17 @@ static int iwl_mld_tx_tso_segment(struct iwl_mld *mld, struct sk_buff *skb,
 	 */
 	num_subframes = (max_tid_amsdu_len + pad) / (subf_len + pad);
 
+	/* If the AMSDU length limit is too small to fit even a single
+	 * subframe (e.g. max_tid_amsdu_len is the sentinel value 1 set by
+	 * the TLC notification when AMSDU is disabled for this TID), fall
+	 * back to non-AMSDU TSO segmentation. Without this guard,
+	 * num_subframes=0 causes gso_size=0 in iwl_tx_tso_segment(),
+	 * which makes skb_gso_segment() produce tens of thousands of
+	 * 1-byte segments, overloading the TX ring and completion path.
+	 */
+	if (!num_subframes)
+		return iwl_tx_tso_segment(skb, 1, netdev_flags, mpdus_skbs);
+
 	if (sta->max_amsdu_subframes &&
 	    num_subframes > sta->max_amsdu_subframes)
 		num_subframes = sta->max_amsdu_subframes;
-- 
2.52.0

Cole


^ permalink raw reply related

* [PATCH v2] wifi: iwlwifi: mld: skip TX when firmware is dead
From: Cole Leavitt @ 2026-02-18 14:17 UTC (permalink / raw)
  To: linux-wireless
  Cc: johannes, miriam.rachel.korenblit, greearb, linux-kernel,
	Cole Leavitt
In-Reply-To: <20260214060716.16394-1-cole@unwrap.rs>

When firmware encounters an error, STATUS_FW_ERROR is set but the
mac80211 TX path continues pulling frames from TXQs. Each frame
fails at iwl_trans_tx() which checks STATUS_FW_ERROR and returns
-EIO, but iwl_mld_tx_from_txq() keeps looping over every queued
frame. This burns CPU in a tight loop on dead firmware and can
cause soft lockups during firmware error recovery.

Add a STATUS_FW_ERROR check at the top of iwl_mld_tx_from_txq()
to stop pulling frames from mac80211 TXQs when firmware is dead.
Also guard iwl_mld_mac80211_tx() which bypasses the TXQ path
entirely and would otherwise continue feeding frames to dead
firmware.

Once STATUS_FW_ERROR is cleared during firmware restart, TX
resumes naturally with no explicit wake needed.

Fixes: d1e879ec600f ("wifi: iwlwifi: add iwlmld sub-driver")
Signed-off-by: Cole Leavitt <cole@unwrap.rs>
---
v2:
 - Replace ieee80211_stop_queues()/wake_queues() with STATUS_FW_ERROR
   checks in the TX pull path, per Johannes Berg's feedback that
   stop/wake_queues doesn't interact well with TXQ-based APIs.
 - Guard both iwl_mld_tx_from_txq() (TXQ pull path) and
   iwl_mld_mac80211_tx() (direct mac80211 TX path).
 - Drop all changes to mld.c (no stop/wake in error/restart flows).

 drivers/net/wireless/intel/iwlwifi/mld/mac80211.c | 5 +++++
 drivers/net/wireless/intel/iwlwifi/mld/tx.c       | 8 ++++++++
 2 files changed, 13 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
index 3414b04a6953..1bd8411965f5 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
@@ -519,6 +519,11 @@ iwl_mld_mac80211_tx(struct ieee80211_hw *hw,
 	u32 link_id = u32_get_bits(info->control.flags,
 				   IEEE80211_TX_CTRL_MLO_LINK);
 
+	if (unlikely(test_bit(STATUS_FW_ERROR, &mld->trans->status))) {
+		ieee80211_free_txskb(hw, skb);
+		return;
+	}
+
 	/* In AP mode, mgmt frames are sent on the bcast station,
 	 * so the FW can't translate the MLD addr to the link addr. Do it here
 	 */
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/tx.c b/drivers/net/wireless/intel/iwlwifi/mld/tx.c
index 7c6a4b4e5523..fbb672f4d8c7 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/tx.c
@@ -970,6 +970,14 @@ void iwl_mld_tx_from_txq(struct iwl_mld *mld, struct ieee80211_txq *txq)
 	struct sk_buff *skb = NULL;
 	u8 zero_addr[ETH_ALEN] = {};
 
+	/* Firmware is dead - don't pull frames from mac80211 TXQs.
+	 * Packets dequeued here would fail at iwl_trans_tx() anyway,
+	 * but looping over every queued frame burns CPU and causes
+	 * soft lockups during firmware error recovery.
+	 */
+	if (unlikely(test_bit(STATUS_FW_ERROR, &mld->trans->status)))
+		return;
+
 	/*
 	 * No need for threads to be pending here, they can leave the first
 	 * taker all the work.
-- 
2.52.0


^ permalink raw reply related

* [PATCH net] wifi: brcmsmac: Fix dma_free_coherent() size
From: Thomas Fourier @ 2026-02-18 13:07 UTC (permalink / raw)
  Cc: Thomas Fourier, stable, Arend van Spriel, Johannes Berg,
	Simon Horman, John W. Linville, linux-wireless, brcm80211,
	brcm80211-dev-list.pdl, linux-kernel

dma_alloc_consistent() may change the size to align it. The new size is
saved in alloced.

Change the free size to match the allocation size.

Fixes: 5b435de0d786 ("net: wireless: add brcm80211 drivers")
Cc: <stable@vger.kernel.org>
Signed-off-by: Thomas Fourier <fourier.thomas@gmail.com>
---
 drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c
index c739bf7463b3..13d0d6b68238 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c
@@ -483,7 +483,7 @@ static void *dma_ringalloc(struct dma_info *di, u32 boundary, uint size,
 	if (((desc_strtaddr + size - 1) & boundary) != (desc_strtaddr
 							& boundary)) {
 		*alignbits = dma_align_sizetobits(size);
-		dma_free_coherent(di->dmadev, size, va, *descpa);
+		dma_free_coherent(di->dmadev, *alloced, va, *descpa);
 		va = dma_alloc_consistent(di, size, *alignbits,
 			alloced, descpa);
 	}
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH wireless-next v3] wifi: mac80211: Fix AAD/Nonce computation for management frames with MLO
From: Sai Pratyusha Magam @ 2026-02-18  6:24 UTC (permalink / raw)
  To: Chien Wong, johannes; +Cc: linux-wireless, quic_drohan
In-Reply-To: <DGCW7TTCQC89.2G77C3IBE4SRC@xv97.com>



On 2/12/2026 3:28 PM, Chien Wong wrote:
Hi Chien,

> Hey,
> While adding MLO decryption feature to Wireshark, I noticed this issue that
> mac80211_hwsim handles MLO management frames encryption incorrectly.
> It seems that wlantest can also verify the correctness of the encryption?
That's right, wlantest can decrypt protected management and data frames

./wlantest -r eht_mld_sae_two_links.hwsim0.pcapng -T <file containing TK 
without spaces> -n decrypted_sniffer.pcapng

> However, I couldn't get it to work—wlantest keeps reporting 'No PTK known
> to decrypt the frame', 
I gave a try to pass over-the-air capture of one run without this patch 
and another run with this patch. Without the patch, wlantest would fail 
to decrypt the protected deauthentication frame. Yes it throws an error 
- No PTK known to decrypt the frame. This is actually a decryption failure.

In the second run with the patch, decryption was successful.

but at least I verified using Wireshark that the
> encryption of unicast data frames and management frames in MLO is correct
> with the patch.
> 
Thanks for the info. As far as I know, Wireshark had an issue in 
decryption of data frames with MLO - I suppose that is because it needs 
to use the MLD addresses for AAD computation. Good to know that the next 
released version of wireshark will have this fixed.

> BTW, the changes to Wireshark are already in the upstream repository. If you
> want to use it for verification, you need to compile it yourself because
> the currently released version does not yet include these changes.
> 
> Tested on base commit 05f7e89ab9731565d8a62e3b5d1ec206485eeb0(v6.19)
> Tested case eht_mld_sae_two_link from hostapd
> 
> Tested-by: Chien Wong <m@xv97.com>


^ permalink raw reply

* Re: [RFC PATCH 2/2] wifi: ath10k: only wait for response to SET_KEY
From: Felix Kaechele @ 2026-02-18  4:14 UTC (permalink / raw)
  To: James Prestwood, Jeff Johnson, Richard Acayan, linux-wireless,
	ath10k, Baochen Qiang
In-Reply-To: <1c6a4aaa-b450-4843-8c44-930a8c3f6d66@gmail.com>

Hi,

On 2026-02-13 09:00, James Prestwood wrote:
> Hi Jeff/Baochen,
> 
> On 2/12/26 9:56 AM, Jeff Johnson wrote:
>> On 2/11/2026 6:11 PM, James Prestwood wrote:
>>> On 2/9/26 6:12 PM, Richard Acayan wrote:
>>>> When sending DELETE_KEY, the driver times out waiting for a response
>>>> that doesn't come. Only wait for a response when sending SET_KEY.
>>> We've run into the exact same thing on the QCA6174 and have been
>>> carrying an identical patch to this for at least a year.
>>>
>>> https://lore.kernel.org/linux-wireless/b2838a23-ea30-4dee-b513- 
>>> f5471d486af2@gmail.com/
>> Baochen,
>> Were we ever able to reproduce this?
>> Do we normally always get a response to DELETE_KEY but in some 
>> instances it
>> comes very late (or not at all)?
>> If we remove the wait, is there any concern that a late arriving 
>> DELETE_KEY
>> response might be processed as a response to a subsequent SET_KEY 
>> command?
> 
> For some added color, we only see this oddly with some vendors of APs, 
> primarily "classic" Cisco Aeronet equipment (not Meraki).

I use Ubiquiti nanoHD APs in my home network and have this issue with 
those. The device I am focusing on with this (Lenovo ThinkSmart View) 
originally came with Android and uses qcacld-2.0 there. I do see similar 
disconnects on group rekeying on Android as well and have reports from 
other users that WiFi does not consistently stay connected and on 
Android in some cases may even fail to reconnect at all.
With ath10k on near mainline Linux I have yet to see a full loss of 
connectivity.
To me this suggests that it's possibly a firmware issue.
I do have ath10k debug traces I can share, if this is helpful.

dmesg output:

qcom-msm8953 kernel: ath10k_sdio mmc1:0001:1: qca9379 hw1.0 sdio target 
0x05040000 chip_id 0x00000000 sub 0000:0000
qcom-msm8953 kernel: ath10k_sdio mmc1:0001:1: kconfig debug 1 debugfs 1 
tracing 1 dfs 0 testmode 0
qcom-msm8953 kernel: ath10k_sdio mmc1:0001:1: firmware ver 
WLAN.NPL.1.6-00163-QCANPLSWPZ-1 api 6 features wowlan,ignore-otp,mfp 
crc32 ac81ca26

Regards,
Felix

^ permalink raw reply

* [PATCH v2][next] wifi: ath6kl: wmi: Avoid -Wflex-array-member-not-at-end warning
From: Gustavo A. R. Silva @ 2026-02-17  5:10 UTC (permalink / raw)
  To: Jeff Johnson, Kalle Valo
  Cc: linux-wireless, linux-kernel, Gustavo A. R. Silva,
	linux-hardening

-Wflex-array-member-not-at-end was introduced in GCC-14, and we are
getting ready to enable it, globally.

struct bss_bias_info is a flexible structure, this is a structure
that contains a flexible-array member (struct bss_bias bss_bias[]).

Since struct roam_ctrl_cmd is defined by hardware, we create the new
struct bss_bias_info_hdr type, and use it to replace the object type
causing trouble in struct roam_ctrl_cmd, namely struct bss_bias_info.

Also, once -fms-extensions is enabled, we can use transparent struct
members in struct bss_bias_info.

Notice that the newly created type does not contain the flex-array
member `bss_bias`, which is the object causing the -Wfamnae warning.

After these changes, the size of struct roam_ctrl_cmd, along
with its member's offsets remain the same, hence the memory layout
doesn't change:

Before changes:
struct roam_ctrl_cmd {
	union {
		u8                 bssid[6];             /*     0     6 */
		u8                 roam_mode;            /*     0     1 */
		struct bss_bias_info bss;            	 /*     0     1 */
		struct low_rssi_scan_params params;      /*     0     8 */
	} info;                                          /*     0     8 */
	u8                         roam_ctrl;            /*     8     1 */

	/* size: 9, cachelines: 1, members: 2 */
	/* last cacheline: 9 bytes */
} __attribute__((__packed__));

After changes:
struct roam_ctrl_cmd {
	union {
		u8                 bssid[6];             /*     0     6 */
		u8                 roam_mode;            /*     0     1 */
		struct bss_bias_info_hdr bss;            /*     0     1 */
		struct low_rssi_scan_params params;      /*     0     8 */
	} info;                                          /*     0     8 */
	u8                         roam_ctrl;            /*     8     1 */

	/* size: 9, cachelines: 1, members: 2 */
	/* last cacheline: 9 bytes */
} __attribute__((__packed__));

With these changes fix the following warning:

drivers/net/wireless/ath/ath6kl/wmi.h:1658:20: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]

Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
---
Changes in v2:
 - Create new separate struct bss_bias_info_hdr, and use
   transparent struct members (in struct bss_bias_info)
   instead of rearranging members in struct roam_ctrl_cmd.
 - Update subject line - Add 'wifi:' prefix.

v1:
 - Link: https://lore.kernel.org/linux-hardening/aR153k4ExCD-QTMq@kspp/

 drivers/net/wireless/ath/ath6kl/wmi.h | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index 3080d82e25cc..d2a5c96fc878 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -1635,8 +1635,12 @@ struct bss_bias {
 	s8 bias;
 } __packed;
 
-struct bss_bias_info {
+struct bss_bias_info_hdr {
 	u8 num_bss;
+} __packed;
+
+struct bss_bias_info {
+	struct bss_bias_info_hdr;
 	struct bss_bias bss_bias[];
 } __packed;
 
@@ -1652,7 +1656,7 @@ struct roam_ctrl_cmd {
 	union {
 		u8 bssid[ETH_ALEN]; /* WMI_FORCE_ROAM */
 		u8 roam_mode; /* WMI_SET_ROAM_MODE */
-		struct bss_bias_info bss; /* WMI_SET_HOST_BIAS */
+		struct bss_bias_info_hdr bss; /* WMI_SET_HOST_BIAS */
 		struct low_rssi_scan_params params; /* WMI_SET_LRSSI_SCAN_PARAMS
 						     */
 	} __packed info;
-- 
2.43.0


^ permalink raw reply related

* Re: Receiving broadcast data frames in AP mode
From: Johannes Berg @ 2026-02-17 16:09 UTC (permalink / raw)
  To: Yannik Marchand, linux-wireless
In-Reply-To: <7ce3efae-ad08-4fe4-b3c3-f1340c213a22@me.com>

On Tue, 2026-02-17 at 15:56 +0100, Yannik Marchand wrote:

>  > I actually have a Switch 2 now, so I guess I could theoretically try
>  > out some of these things - though I don't have a lot of real WiFi
>  > hardware.
> 
> That's cool! I didn't know that you are interested in Nintendo games.

Hah, not all that much, my kids more :-P

> I am running most of my experiments with an ALFA AWUS036ACM currently, 
> because my old laptop had an Intel chip, which (as you mentioned) 
> filtered out too much. My new laptop has a MediaTek chip, which seems to 
> work mostly fine. So, whether you need "real WiFi hardware" probably 
> depends on what you currently have.

Yeah guess that depends on how much filtering there is in the (lower)
MAC.

>  > Have you heard of Ferris on Air?
> 
> I didn't know about FoA. Currently, I don't really have the time to port 
> my implementation to a different stack, but it might be interesting if 
> we run into more issues later on.

Sure, was just thinking that has pretty low-level access, so could be
easy, and having it interop with an esp32 might be interesting. Also,
they've said they might want to support the esp32 as a wifi NIC for
Linux.

>  > This is ... odd. Is there encryption? I can't imagine why they'd throw
>  > away non-broadcast packets.
> 
> Yes, all data frames are encrypted with CCMP with a key that is derived 
> from information in the action frame. The interesting part is that the 
> first few packets do arrive at the Nintendo Switch, which makes me 
> believe that my encryption algorithm is correct. After I found that 
> using the broadcast address solved the problem, I have not investigated 
> the issue any further.

Sounds odd. Maybe some PN issue? But I guess would need some more debug.

>  > That sounds pretty awkward!
>  >
>  > ...
>  >
>  > So there really is no good default mode to implement this in, and
>  > while we could add a "nintendo mode" to the kernel, it'd be unlikely
>  > that hardware/firmware implements it?
> 
> It was quite difficult indeed :)
> 
> The biggest issue has really been the filtering, namely:
> * Dropping broadcast action frames in station mode while being 
> associated with an AP.
> * Dropping broadcast data frames in AP mode.
> * Dropping association frames in IBSS mode.
> 
> The first issue seems to affect mostly Intel hardware, while the other 
> two issues affect all my hardware.

Right.

> Of course, it would be nice if this could be solved in the kernel, but 
> I'm personally not familiar enough to judge whether this is possible, or 
> whether it would require support from the hardware vendor.

The *kernel* would be doable, but a lot of this is likely even happening
in (lower) MAC firmware, depending on the device. Certainly for Intel
devices.

In some devices maybe broadcast data frames are seen in AP mode, and
then we could just not drop them in the kernel? Or introduce a Nintendo-
AP mode or something, but like I said, the bigger issue is FW support.
Though having such a mode would also allow drivers to advertise "this
works".

johannes

^ permalink raw reply

* Re: [PATCH wireless] wifi: mac80211: Fix ADDBA update when HW supports reordering
From: Johannes Berg @ 2026-02-17 16:00 UTC (permalink / raw)
  To: Remi Pommarel; +Cc: linux-wireless, linux-kernel, Pablo MARTIN-GOMEZ
In-Reply-To: <aZR9eQlhy55iD6IN@pilgrim>

On Tue, 2026-02-17 at 15:38 +0100, Remi Pommarel wrote:
> On Tue, Feb 17, 2026 at 02:59:34PM +0100, Johannes Berg wrote:
> > On Tue, 2026-02-17 at 14:05 +0100, Remi Pommarel wrote:
> > > On Tue, Feb 17, 2026 at 12:30:08PM +0100, Johannes Berg wrote:
> > > > On Tue, 2026-02-17 at 11:36 +0100, Remi Pommarel wrote:
> > > > > Commit f89e07d4cf26 ("mac80211: agg-rx: refuse ADDBA Request with timeout
> > > > > update") added a check to fail when ADDBA update would change the
> > > > > timeout param.
> > > > > 
> > > > > This param is kept in tid_ampdu_rx context which is only allocated on HW
> > > > > that do not set SUPPORTS_REORDERING_BUFFER. Because the timeout check
> > > > > was done regardless of this param, ADDBA update always failed on those
> > > > > HW.
> > > > 
> > > > Seems like a legit problem, but
> > > > 
> > > > > Fix this by only checking tid_ampdu_rx->timeout only when
> > > > > SUPPORTS_REORDERING_BUFFER is not set.
> > > > 
> > > > that doesn't seem right? Especially the way you implemented it, it won't
> > > > even respond at all when it's an update and SUPPORTS_REORDERING_BUFFER
> > > > is set.
> > > 
> > > I could be wrong but I think the patch format here make it difficult to
> > > read. If it's an update and SUPPORTS_REORDERING_BUFFER is set, the
> > > following "if" in the code (not fully visible in the diff here) will end
> > > calling drv_ampdu_action().
> > 
> > Yes, but it will be IEEE80211_AMPDU_RX_START which isn't really intended
> > by the state machine/API between mac80211/driver. So that doesn't seem
> > right.
> > 
> 
> That does make sense. However, if I understand correctly, it means that
> even if we end up storing the timeout for drivers that support
> reordering, a new IEEE80211_AMPDU_RX_UPDATE should still be introduced,
> right?

I guess in order to do a no-op update that doesn't change the timeout,
we could? But not sure it's all worth it?

Pablo seems to have looked up that it _is_ supported - which I didn't
expect because it's not part of the API contract, so the drivers
implemented something that can't actually ever get hit? Seems odd. And
I'm pretty sure e.g. iwlwifi wouldn't support it.

But I basically also think it's not worth it in practice; why try to
support something that's never going to happen?

johannes

^ permalink raw reply

* Re: [PATCH wireless] wifi: mac80211: Fix ADDBA update when HW supports reordering
From: Pablo MARTIN-GOMEZ @ 2026-02-17 15:30 UTC (permalink / raw)
  To: Johannes Berg, Remi Pommarel; +Cc: linux-wireless, linux-kernel
In-Reply-To: <d142f76473a03c76c780390f0352ffbb03566e48.camel@sipsolutions.net>

Hello,

On 17/02/2026 14:59, Johannes Berg wrote:
> On Tue, 2026-02-17 at 14:05 +0100, Remi Pommarel wrote:
>> On Tue, Feb 17, 2026 at 12:30:08PM +0100, Johannes Berg wrote:
[...]
>> we want the driver to decide if it wants to support timeout update ?
> Not really, there's no driver that _can_ to support it now, and it seems
> unlikely any driver would _want_ to support it.
>
> And if so it should probably not be IEEE80211_AMPDU_RX_START but rather
> some new IEEE80211_AMPDU_RX_UPDATE thing. But I don't think any driver
> would implement it, I don't see why anyone would want to, this flow is
> in the spec but never really used.
I've checked, and both mt76 and ath11k/ath12k drivers supports a BA 
update (but none of them supports the timeout though) through 
`IEEE80211_AMPDU_RX_START`. mt76 stop the session before starting one 
new (function `mt76_rx_aggr_start`) and ath11k/ath12k checks if a 
session is active to either modify it or create a new one (function 
`ath12k_dp_rx_peer_tid_setup`).
>
> johannes
>
Pablo MG

^ permalink raw reply

* Re: [PATCH wireless] wifi: mac80211: Fix ADDBA update when HW supports reordering
From: Remi Pommarel @ 2026-02-17 14:38 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, linux-kernel
In-Reply-To: <d142f76473a03c76c780390f0352ffbb03566e48.camel@sipsolutions.net>

On Tue, Feb 17, 2026 at 02:59:34PM +0100, Johannes Berg wrote:
> On Tue, 2026-02-17 at 14:05 +0100, Remi Pommarel wrote:
> > On Tue, Feb 17, 2026 at 12:30:08PM +0100, Johannes Berg wrote:
> > > On Tue, 2026-02-17 at 11:36 +0100, Remi Pommarel wrote:
> > > > Commit f89e07d4cf26 ("mac80211: agg-rx: refuse ADDBA Request with timeout
> > > > update") added a check to fail when ADDBA update would change the
> > > > timeout param.
> > > > 
> > > > This param is kept in tid_ampdu_rx context which is only allocated on HW
> > > > that do not set SUPPORTS_REORDERING_BUFFER. Because the timeout check
> > > > was done regardless of this param, ADDBA update always failed on those
> > > > HW.
> > > 
> > > Seems like a legit problem, but
> > > 
> > > > Fix this by only checking tid_ampdu_rx->timeout only when
> > > > SUPPORTS_REORDERING_BUFFER is not set.
> > > 
> > > that doesn't seem right? Especially the way you implemented it, it won't
> > > even respond at all when it's an update and SUPPORTS_REORDERING_BUFFER
> > > is set.
> > 
> > I could be wrong but I think the patch format here make it difficult to
> > read. If it's an update and SUPPORTS_REORDERING_BUFFER is set, the
> > following "if" in the code (not fully visible in the diff here) will end
> > calling drv_ampdu_action().
> 
> Yes, but it will be IEEE80211_AMPDU_RX_START which isn't really intended
> by the state machine/API between mac80211/driver. So that doesn't seem
> right.
> 

That does make sense. However, if I understand correctly, it means that
even if we end up storing the timeout for drivers that support
reordering, a new IEEE80211_AMPDU_RX_UPDATE should still be introduced,
right?

-- 
Remi

^ permalink raw reply

* Re: Receiving broadcast data frames in AP mode
From: Yannik Marchand @ 2026-02-17 14:56 UTC (permalink / raw)
  To: Johannes Berg, linux-wireless
In-Reply-To: <bb63abe8c61a02afd67921934e15c6a943a12fba.camel@sipsolutions.net>

Hi Johannes,

 > Cool story. For some reason your emails never made it to the list it
 > seems? I'm replying privately because of that.

That was a mistake on my side. For the first email, I used "Reply" 
instead of "Reply All", and only realized that after the email had 
already been sent. For the second email, I accidentally sent it with 
HTML instead of plaintext (it might have been rejected for that reason).

 > I actually have a Switch 2 now, so I guess I could theoretically try
 > out some of these things - though I don't have a lot of real WiFi
 > hardware.

That's cool! I didn't know that you are interested in Nintendo games.

I am running most of my experiments with an ALFA AWUS036ACM currently, 
because my old laptop had an Intel chip, which (as you mentioned) 
filtered out too much. My new laptop has a MediaTek chip, which seems to 
work mostly fine. So, whether you need "real WiFi hardware" probably 
depends on what you currently have.

 > Have you heard of Ferris on Air?

I didn't know about FoA. Currently, I don't really have the time to port 
my implementation to a different stack, but it might be interesting if 
we run into more issues later on.

 > This is ... odd. Is there encryption? I can't imagine why they'd throw
 > away non-broadcast packets.

Yes, all data frames are encrypted with CCMP with a key that is derived 
from information in the action frame. The interesting part is that the 
first few packets do arrive at the Nintendo Switch, which makes me 
believe that my encryption algorithm is correct. After I found that 
using the broadcast address solved the problem, I have not investigated 
the issue any further.

 > That sounds pretty awkward!
 >
 > ...
 >
 > So there really is no good default mode to implement this in, and
 > while we could add a "nintendo mode" to the kernel, it'd be unlikely
 > that hardware/firmware implements it?

It was quite difficult indeed :)

The biggest issue has really been the filtering, namely:
* Dropping broadcast action frames in station mode while being 
associated with an AP.
* Dropping broadcast data frames in AP mode.
* Dropping association frames in IBSS mode.

The first issue seems to affect mostly Intel hardware, while the other 
two issues affect all my hardware.

Of course, it would be nice if this could be solved in the kernel, but 
I'm personally not familiar enough to judge whether this is possible, or 
whether it would require support from the hardware vendor.

(also, I'm leaving the previous emails quoted below in case a mailing 
list user wants to catch up)

Kind regards,
Yannik Marchand

On 17/02/2026 13:40, Johannes Berg wrote:
> Hi Yannick,
> 
> Cool story. For some reason your emails never made it to the list it
> seems? I'm replying privately because of that.
> 
> I actually have a Switch 2 now, so I guess I could theoretically try out
> some of these things - though I don't have a lot of real WiFi hardware.
> 
> Have you heard of Ferris on Air? I've been in contact with one of the
> people involved in that, might be kind of interesting to interop with
> the switch from that ;-)
> 
> https://github.com/esp32-open-mac/FoA
> 
> 
> On Fri, 2026-02-13 at 17:30 +0100, Yannik Marchand wrote:
>> Update: I have no idea why, but sending all frames to ff:ff:ff:ff:ff:ff
>> instead of the MAC address of my Switch seems to have solved the issue.
>> It looks like all UDP packets are now being received properly :)
> 
> This is ... odd. Is there encryption? I can't imagine why they'd throw
> away non-broadcast packets.
> 
>> It seems that the protocol is somewhere between ad-hoc and
>> infrastructure mode. When a station joins the network, it must send an
>> authentication and association request to the host of the network,
>> which is similar to infrastructure mode. However, once authenticated,
>> the nodes can communicate directly with each other, which is more like
>> ad-hoc mode. Interestingly, packets from the host seem to have FromDS
>> set, while packets from other nodes in the network have neither FromDS
>> nor ToDS set.
> 
> IBSS (ad-hoc) can use authentication, but it's between each pair of
> devices, and not association I think, so it's indeed different. But I
> seem to remember from some (your?) documentation that the controller or
> host has some kind of beacon with the list of members, so I guess that
> makes some sense.
> 
>> Unfortunately, using an interface in IBSS mode did not work, because
>> none of my hardware supports receiving association requests in IBSS mode.
> 
> Curious that any hardware would even bother filtering. Though Intel FW
> does maybe filter, the folks working on those lower levels are a bit
> overdoing it sometimes ;-)
> 
>> Later, I learned about WiFi-Direct and P2P. While I initially thought
>> that using a P2P-GO mode interface would make it work, it seems that
>> it suffers from the same issue as AP mode, where broadcast data frames
>> are not received.
> 
> Yeah APs don't receive real broadcast data frames, so stands to reason
> they would drop those as useless.
> 
>> Then, I tried implementing the entire protocol in monitor mode. While
>> I have learned a lot, this turned out to be quite hard.
> 
> No surprise I guess.
> 
>> Today, I have finally managed to make it somewhat work. My setup uses
>> three interfaces, which is similar to what you suggested: one in AP
>> mode, one in monitor mode, and a TAP interface. The AP mode interface
>> handles the association and authentication frames. The monitor mode
>> interface handles the data frames. After parsing and decrypting the
>> data frames, the frames are written to the TAP interface, to avoid
>> having to implement L3 as well.
> 
> That sounds pretty awkward!
> 
> I guess your hardware then has some kind of extra "allow monitor"
> though, because it seems to receive more in the combination of AP +
> monitor than in pure AP. Intel hardware still wouldn't.
> 
> So overall this seems pretty awkward to implement over general purpose
> WiFi chips since you have conflicting requirements:
> 
>   - need beacon transmission and the timing
>     (normally IBSS, AP/P2P-GO, mesh)
>   - need auth/assoc handling
>     (normally AP/P2P-GO)
>   - need multicast data RX
>     (normally IBSS, client, maybe mesh)
> 
> So there really is no good default mode to implement this in, and while
> we could add a "nintendo mode" to the kernel, it'd be unlikely that
> hardware/firmware implements it?
> 
> johannes


^ permalink raw reply

* Re: [PATCH v3 wireless-next 08/15] wifi: cfg80211: add support for NAN data interface
From: Johannes Berg @ 2026-02-17 14:21 UTC (permalink / raw)
  To: Miri Korenblit, linux-wireless
In-Reply-To: <20260217134342.2d455362bd3b.I92973483e927820ae2297853c141842fdb262747@changeid>

On Tue, 2026-02-17 at 13:56 +0200, Miri Korenblit wrote:
> 
> +void cfg80211_leave(struct cfg80211_registered_device *rdev,
> +		    struct wireless_dev *wdev, int link_id)
> +{
> +	ASSERT_RTNL();
> +
> +	/* NAN_DATA interfaces must be closed before stopping NAN */
> +	cfg80211_close_dependents(rdev, wdev);

Turns out an equivalent change is missing in cfg80211_destroy_ifaces().

johannes

^ permalink raw reply

* Re: [PATCH wireless] wifi: mac80211: Fix ADDBA update when HW supports reordering
From: Johannes Berg @ 2026-02-17 13:59 UTC (permalink / raw)
  To: Remi Pommarel; +Cc: linux-wireless, linux-kernel
In-Reply-To: <aZRnlPA_uY9uWuKr@pilgrim>

On Tue, 2026-02-17 at 14:05 +0100, Remi Pommarel wrote:
> On Tue, Feb 17, 2026 at 12:30:08PM +0100, Johannes Berg wrote:
> > On Tue, 2026-02-17 at 11:36 +0100, Remi Pommarel wrote:
> > > Commit f89e07d4cf26 ("mac80211: agg-rx: refuse ADDBA Request with timeout
> > > update") added a check to fail when ADDBA update would change the
> > > timeout param.
> > > 
> > > This param is kept in tid_ampdu_rx context which is only allocated on HW
> > > that do not set SUPPORTS_REORDERING_BUFFER. Because the timeout check
> > > was done regardless of this param, ADDBA update always failed on those
> > > HW.
> > 
> > Seems like a legit problem, but
> > 
> > > Fix this by only checking tid_ampdu_rx->timeout only when
> > > SUPPORTS_REORDERING_BUFFER is not set.
> > 
> > that doesn't seem right? Especially the way you implemented it, it won't
> > even respond at all when it's an update and SUPPORTS_REORDERING_BUFFER
> > is set.
> 
> I could be wrong but I think the patch format here make it difficult to
> read. If it's an update and SUPPORTS_REORDERING_BUFFER is set, the
> following "if" in the code (not fully visible in the diff here) will end
> calling drv_ampdu_action().

Yes, but it will be IEEE80211_AMPDU_RX_START which isn't really intended
by the state machine/API between mac80211/driver. So that doesn't seem
right.

> That is another way of fixing that yes, but the question here is, don't
> we want the driver to decide if it wants to support timeout update ?

Not really, there's no driver that _can_ to support it now, and it seems
unlikely any driver would _want_ to support it.

And if so it should probably not be IEEE80211_AMPDU_RX_START but rather
some new IEEE80211_AMPDU_RX_UPDATE thing. But I don't think any driver
would implement it, I don't see why anyone would want to, this flow is
in the spec but never really used.

johannes

^ permalink raw reply

* Re: [PATCH v7 2/3] dt-bindings: net: wireless: mt76: add more PCI devices
From: Ryder Lee @ 2026-02-17 13:51 UTC (permalink / raw)
  To: krzk@kernel.org
  Cc: robh@kernel.org, nbd@nbd.name, linux-mediatek@lists.infradead.org,
	devicetree@vger.kernel.org, linux-wireless@vger.kernel.org
In-Reply-To: <af349cc1-cd30-497e-a36a-81d50ef3e659@kernel.org>

On Tue, 2026-02-17 at 14:23 +0100, Krzysztof Kozlowski wrote:
> On 17/02/2026 13:59, Ryder Lee wrote:
> > On Tue, 2026-02-17 at 08:48 +0100, Krzysztof Kozlowski wrote:
> > > On Mon, Feb 16, 2026 at 08:01:15AM -0800, Ryder Lee wrote:
> > > > This adds support for mt7915/mt7916/mt7990/mt7992/mt7996 PCI
> > > > devices.
> > > 
> > > No, it does not add any support. I asked you to provide rationale
> > > why
> > > this is needed.
> > > 
> > > Also, read submitting patches finally - it is not "This adds...".
> > 
> > Are you referring to this - Describe your changes in imperative
> > mood...
> 
> Yes
> 
> > So, what would you like me to describe this change? what about this
> > "Add platform IDs for known devices"?
> 
> First comment - provide rationale why discoverable devices needs to
> be
> described in non-discoverable way...
> 

"The rationale for describing these devices is that the WiFi TX power
settings must be provided via the platform's DTS node. Different device
generations interpret these settings differently, so we need to
distinguish them using PCI IDs or compatible strings in the
documentation. The following patch will further explain the differences
in TX power handling between generations."

If you think it's okay, I'll write it this way.

Ryder

^ permalink raw reply

* Re: [PATCH wireless] wifi: mac80211: Fix ADDBA update when HW supports reordering
From: Remi Pommarel @ 2026-02-17 13:05 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, linux-kernel
In-Reply-To: <f1243e86eea72999581d33c6f97ff9015ce71542.camel@sipsolutions.net>

On Tue, Feb 17, 2026 at 12:30:08PM +0100, Johannes Berg wrote:
> On Tue, 2026-02-17 at 11:36 +0100, Remi Pommarel wrote:
> > Commit f89e07d4cf26 ("mac80211: agg-rx: refuse ADDBA Request with timeout
> > update") added a check to fail when ADDBA update would change the
> > timeout param.
> > 
> > This param is kept in tid_ampdu_rx context which is only allocated on HW
> > that do not set SUPPORTS_REORDERING_BUFFER. Because the timeout check
> > was done regardless of this param, ADDBA update always failed on those
> > HW.
> 
> Seems like a legit problem, but
> 
> > Fix this by only checking tid_ampdu_rx->timeout only when
> > SUPPORTS_REORDERING_BUFFER is not set.
> 
> that doesn't seem right? Especially the way you implemented it, it won't
> even respond at all when it's an update and SUPPORTS_REORDERING_BUFFER
> is set.

I could be wrong but I think the patch format here make it difficult to
read. If it's an update and SUPPORTS_REORDERING_BUFFER is set, the
following "if" in the code (not fully visible in the diff here) will end
calling drv_ampdu_action().

> 
> Seems we perhaps just need to store the timeout elsewhere?
> 

That is another way of fixing that yes, but the question here is, don't
we want the driver to decide if it wants to support timeout update ?

> > @@ -374,14 +383,6 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
> >  			goto end;
> >  		}
> >  
> > -		ht_dbg_ratelimited(sta->sdata,
> > -				   "unexpected AddBA Req from %pM on tid %u\n",
> > -				   sta->sta.addr, tid);
> > -
> > -		/* delete existing Rx BA session on the same tid */
> > -		__ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT,
> > -					       WLAN_STATUS_UNSPECIFIED_QOS,
> > -					       false);
> >  	}
> 
> Also, nit, but this leaves a blank line at the end of the block.

Sure will remove that if we finally decide to keep the fix as is.

Thanks for the review.

-- 
Remi

^ permalink raw reply

* Re: [PATCH v7 2/3] dt-bindings: net: wireless: mt76: add more PCI devices
From: Krzysztof Kozlowski @ 2026-02-17 13:23 UTC (permalink / raw)
  To: Ryder Lee
  Cc: robh@kernel.org, nbd@nbd.name, linux-mediatek@lists.infradead.org,
	devicetree@vger.kernel.org, linux-wireless@vger.kernel.org
In-Reply-To: <23f43fb875ca41a945caceba5c9fcf05331afd58.camel@mediatek.com>

On 17/02/2026 13:59, Ryder Lee wrote:
> On Tue, 2026-02-17 at 08:48 +0100, Krzysztof Kozlowski wrote:
>> On Mon, Feb 16, 2026 at 08:01:15AM -0800, Ryder Lee wrote:
>>> This adds support for mt7915/mt7916/mt7990/mt7992/mt7996 PCI
>>> devices.
>>
>> No, it does not add any support. I asked you to provide rationale why
>> this is needed.
>>
>> Also, read submitting patches finally - it is not "This adds...".
> 
> Are you referring to this - Describe your changes in imperative mood...

Yes

> So, what would you like me to describe this change? what about this
> "Add platform IDs for known devices"?

First comment - provide rationale why discoverable devices needs to be
described in non-discoverable way...


> 
>>
>>>
>>> Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
>>> ---
>>> v7: add missing dts mailing list and maintainers
>>
>> No, you still did not bother to Cc maintainers. I gave you detailed
>> instruction which you just ignored.
>>
>> Best regards,
>> Krzysztof
>>
> 
> Oh, I used to do it this way. But aren’t you all on the devicetree
> mailing list?

No, I am not. None of us supposed to be anymore, although we can use
korgalore to achieve same result. Patchwork is on DT list, but the docs
still ask you to send to the maintainers directly and maintainers
organized their workflow around this.

> I did notice that running get_maintainer added some more people.
> I’ll include all dts maintainers as well.

Best regards,
Krzysztof

^ permalink raw reply

* Re: [PATCH v7 2/3] dt-bindings: net: wireless: mt76: add more PCI devices
From: Ryder Lee @ 2026-02-17 12:59 UTC (permalink / raw)
  To: krzk@kernel.org
  Cc: robh@kernel.org, nbd@nbd.name, linux-mediatek@lists.infradead.org,
	devicetree@vger.kernel.org, linux-wireless@vger.kernel.org
In-Reply-To: <20260217-lavender-dove-from-tartarus-fca40c@quoll>

On Tue, 2026-02-17 at 08:48 +0100, Krzysztof Kozlowski wrote:
> On Mon, Feb 16, 2026 at 08:01:15AM -0800, Ryder Lee wrote:
> > This adds support for mt7915/mt7916/mt7990/mt7992/mt7996 PCI
> > devices.
> 
> No, it does not add any support. I asked you to provide rationale why
> this is needed.
> 
> Also, read submitting patches finally - it is not "This adds...".

Are you referring to this - Describe your changes in imperative mood...
So, what would you like me to describe this change? what about this
"Add platform IDs for known devices"?

> 
> > 
> > Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
> > ---
> > v7: add missing dts mailing list and maintainers
> 
> No, you still did not bother to Cc maintainers. I gave you detailed
> instruction which you just ignored.
> 
> Best regards,
> Krzysztof
> 

Oh, I used to do it this way. But aren’t you all on the devicetree
mailing list?
I did notice that running get_maintainer added some more people.
I’ll include all dts maintainers as well.

Ryder

^ permalink raw reply

* [PATCH wireless] wifi: radiotap: reject radiotap with unknown bits
From: Johannes Berg @ 2026-02-17 12:05 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg, stable, syzbot+b09c1af8764c0097bb19

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

The radiotap parser is currently only used with the radiotap
namespace (not with vendor namespaces), but if the undefined
field 18 is used, the alignment/size is unknown as well. In
this case, iterator->_next_ns_data isn't initialized (it's
only set for skipping vendor namespaces), and syzbot points
out that we later compare against this uninitialized value.

Fix this by moving the rejection of unknown radiotap fields
down to after the in-namespace lookup, so it will really use
iterator->_next_ns_data only for vendor namespaces, even in
case undefined fields are present.

Cc: stable@vger.kernel.org
Fixes: 33e5a2f776e3 ("wireless: update radiotap parser")
Reported-by: syzbot+b09c1af8764c0097bb19@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/r/69944a91.a70a0220.2c38d7.00fc.GAE@google.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/wireless/radiotap.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c
index 326faea38ca3..c85eaa583a46 100644
--- a/net/wireless/radiotap.c
+++ b/net/wireless/radiotap.c
@@ -239,14 +239,14 @@ int ieee80211_radiotap_iterator_next(
 		default:
 			if (!iterator->current_namespace ||
 			    iterator->_arg_index >= iterator->current_namespace->n_bits) {
-				if (iterator->current_namespace == &radiotap_ns)
-					return -ENOENT;
 				align = 0;
 			} else {
 				align = iterator->current_namespace->align_size[iterator->_arg_index].align;
 				size = iterator->current_namespace->align_size[iterator->_arg_index].size;
 			}
 			if (!align) {
+				if (iterator->current_namespace == &radiotap_ns)
+					return -ENOENT;
 				/* skip all subsequent data */
 				iterator->_arg = iterator->_next_ns_data;
 				/* give up on this namespace */
-- 
2.53.0


^ permalink raw reply related

* [PATCH v3 wireless-next 15/15] wifi: nl80211: Add a notification to notify NAN channel evacuation
From: Miri Korenblit @ 2026-02-17 11:56 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg
In-Reply-To: <20260217115618.2066972-1-miriam.rachel.korenblit@intel.com>

If all available channel resources are used for NAN channels, and one of
them is shared with another interface, and that interface needs to move
to a different channel (for example STA interface that needs to do a
channel or a link switch), then the driver can evacuate one of the NAN
channels (i.e. detach it from its channel resource and announce to the
peers that this channel is ULWed). In that case, the driver needs to
notify user space about the channel evacuation, so the user space can
adjust the local schedule accordingly.

Add a notification to let userspace know about it.

Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 include/net/cfg80211.h       | 19 ++++++++++++++
 include/uapi/linux/nl80211.h | 27 +++++++++++++++-----
 net/wireless/nl80211.c       | 48 ++++++++++++++++++++++++++++++++++++
 net/wireless/trace.h         | 18 ++++++++++++++
 4 files changed, 106 insertions(+), 6 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index f6143ef9e2d0..620869db2cc9 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -10586,6 +10586,25 @@ void cfg80211_nan_cluster_joined(struct wireless_dev *wdev,
 void cfg80211_nan_ulw_update(struct wireless_dev *wdev,
 			     const u8 *ulw, size_t ulw_len, gfp_t gfp);
 
+/**
+ * cfg80211_nan_channel_evac - Notify user space about NAN channel evacuation
+ * @wdev: Pointer to the wireless device structure
+ * @chandef: Pointer to the channel definition of the NAN channel that was
+ *	evacuated
+ * @gfp: Memory allocation flags
+ *
+ * This function is used by drivers to notify user space when a NAN
+ * channel has been evacuated (i.e. ULWed) due to channel resource conflicts
+ * with other interfaces.
+ * This can happen when another interface sharing the channel resource with NAN
+ * needs to move to a different channel (e.g. due to channel switch or link
+ * switch). User space may reconfigure the local schedule to exclude the
+ * evacuated channel.
+ */
+void cfg80211_nan_channel_evac(struct wireless_dev *wdev,
+			       const struct cfg80211_chan_def *chandef,
+			       gfp_t gfp);
+
 #ifdef CONFIG_CFG80211_DEBUGFS
 /**
  * wiphy_locked_debugfs_read - do a locked read in debugfs
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 191bb2e9c7d9..d7baf3ca751c 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1399,6 +1399,15 @@
  *	with the updated ULW blob of the device. User space can use this blob
  *	to attach to frames sent to peers. This notification contains
  *	%NL80211_ATTR_NAN_ULW with the ULW blob.
+ * @NL80211_CMD_NAN_CHANNEL_EVAC: Notification to indicate that a NAN
+ *	channel has been evacuated due to resource conflicts with other
+ *	interfaces. This can happen when another interface sharing the channel
+ *	resource with NAN needs to move to a different channel (e.g., channel
+ *	switch or link switch on a BSS interface).
+ *	The notification contains %NL80211_ATTR_NAN_CHANNEL attribute
+ *	identifying the evacuated channel.
+ *	User space may reconfigure the local schedule in response to this
+ *	notification.
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -1669,6 +1678,9 @@ enum nl80211_commands {
 	NL80211_CMD_NAN_SET_PEER_SCHED,
 
 	NL80211_CMD_NAN_ULW_UPDATE,
+
+	NL80211_CMD_NAN_CHANNEL_EVAC,
+
 	/* add new commands above here */
 
 	/* used to define NL80211_CMD_MAX below */
@@ -3031,20 +3043,23 @@ enum nl80211_commands {
  *	Currently only supported in mac80211 drivers.
  * @NL80211_ATTR_NAN_CHANNEL: This is a nested attribute. There can be multiple
  *	attributes of this type, each one represents a channel definition and
- *	consists of top-level attributes like %NL80211_ATTR_WIPHY_FREQ. Must
- *	contain %NL80211_ATTR_NAN_CHANNEL_ENTRY and
- *	%NL80211_ATTR_NAN_RX_NSS.
- *	This attribute is used with %NL80211_CMD_NAN_SET_LOCAL_SCHED to specify
+ *	consists of top-level attributes like %NL80211_ATTR_WIPHY_FREQ.
+ *	When used with %NL80211_CMD_NAN_SET_LOCAL_SCHED, it specifies
  *	the channel definitions on which the radio needs to operate during
  *	specific time slots. All of the channel definitions should be mutually
- *	incompatible.
- *	This is also used with %NL80211_CMD_NAN_SET_PEER_SCHED to configure the
+ *	incompatible. With this command, %NL80211_ATTR_NAN_CHANNEL_ENTRY and
+ *	%NL80211_ATTR_NAN_RX_NSS are mandatory.
+ *	When used with %NL80211_CMD_NAN_SET_PEER_SCHED, it configures the
  *	peer NAN channels. In that case, the channel definitions can be
  *	compatible to each other, or even identical just with different RX NSS.
+ *	With this command, %NL80211_ATTR_NAN_CHANNEL_ENTRY and
+ *	%NL80211_ATTR_NAN_RX_NSS are mandatory.
  *	The number of channels should fit the current configuration of channels
  *	and the possible interface combinations.
  *	If an existing NAN channel is changed but the chandef isn't, the
  *	channel entry must also remain unchanged.
+ *	When used with %NL80211_CMD_NAN_CHANNEL_EVAC, this identifies the
+ *	channels that were evacuated.
  * @NL80211_ATTR_NAN_CHANNEL_ENTRY: a byte array of 6 bytes. contains the
  *	Channel Entry as defined in Wi-Fi Aware (TM) 4.0 specification Table
  *	100 (Channel Entry format for the NAN Availability attribute).
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 1c885d9c578d..b51f0676d7cc 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -22823,6 +22823,54 @@ void cfg80211_nan_ulw_update(struct wireless_dev *wdev,
 }
 EXPORT_SYMBOL(cfg80211_nan_ulw_update);
 
+void cfg80211_nan_channel_evac(struct wireless_dev *wdev,
+			       const struct cfg80211_chan_def *chandef,
+			       gfp_t gfp)
+{
+	struct wiphy *wiphy = wdev->wiphy;
+	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+	struct sk_buff *msg;
+	struct nlattr *chan_attr;
+	void *hdr;
+
+	trace_cfg80211_nan_channel_evac(wiphy, wdev, chandef);
+
+	if (!wdev->owner_nlportid)
+		return;
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
+	if (!msg)
+		return;
+
+	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NAN_CHANNEL_EVAC);
+	if (!hdr)
+		goto nla_put_failure;
+
+	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+	    nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
+			      NL80211_ATTR_PAD))
+		goto nla_put_failure;
+
+	chan_attr = nla_nest_start(msg, NL80211_ATTR_NAN_CHANNEL);
+	if (!chan_attr)
+		goto nla_put_failure;
+
+	if (nl80211_send_chandef(msg, chandef))
+		goto nla_put_failure;
+
+	nla_nest_end(msg, chan_attr);
+
+	genlmsg_end(msg, hdr);
+
+	genlmsg_unicast(wiphy_net(wiphy), msg, wdev->owner_nlportid);
+
+	return;
+
+ nla_put_failure:
+	nlmsg_free(msg);
+}
+EXPORT_SYMBOL(cfg80211_nan_channel_evac);
+
 /* initialisation/exit functions */
 
 int __init nl80211_init(void)
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 5ed551412119..0ff5779d2c7e 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -4344,6 +4344,24 @@ TRACE_EVENT(cfg80211_nan_ulw_update,
 		  __print_array(__get_dynamic_array(ulw),
 				__get_dynamic_array_len(ulw), 1))
 );
+
+TRACE_EVENT(cfg80211_nan_channel_evac,
+	TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
+		 const struct cfg80211_chan_def *chandef),
+	TP_ARGS(wiphy, wdev, chandef),
+	TP_STRUCT__entry(
+		WDEV_ENTRY
+		WIPHY_ENTRY
+		CHAN_DEF_ENTRY
+	),
+	TP_fast_assign(
+		WDEV_ASSIGN;
+		WIPHY_ASSIGN;
+		CHAN_DEF_ASSIGN(chandef);
+	),
+	TP_printk(WDEV_PR_FMT ", " WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT,
+		  WDEV_PR_ARG, WIPHY_PR_ARG, CHAN_DEF_PR_ARG)
+);
 #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
 
 #undef TRACE_INCLUDE_PATH
-- 
2.34.1


^ permalink raw reply related

* [PATCH v3 wireless-next 14/15] wifi: nl80211: add NL80211_CMD_NAN_ULW_UPDATE notification
From: Miri Korenblit @ 2026-02-17 11:56 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg
In-Reply-To: <20260217115618.2066972-1-miriam.rachel.korenblit@intel.com>

Add a new notification command that allows drivers to notify user space
when the device's ULW (Unaligned Schedule) blob has been updated. This
enables user space to attach the updated ULW blob to frames sent to NAN
peers.

Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 include/net/cfg80211.h       | 14 ++++++++++++
 include/uapi/linux/nl80211.h |  5 +++++
 net/wireless/nl80211.c       | 43 ++++++++++++++++++++++++++++++++++++
 net/wireless/trace.h         | 21 ++++++++++++++++++
 4 files changed, 83 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 0dee775ddbbc..f6143ef9e2d0 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -10572,6 +10572,20 @@ void cfg80211_nan_cluster_joined(struct wireless_dev *wdev,
 				 const u8 *cluster_id, bool new_cluster,
 				 gfp_t gfp);
 
+/**
+ * cfg80211_nan_ulw_update - Notify user space about ULW update
+ * @wdev: Pointer to the wireless device structure
+ * @ulw: Pointer to the ULW blob data
+ * @ulw_len: Length of the ULW blob in bytes
+ * @gfp: Memory allocation flags
+ *
+ * This function is used by drivers to notify user space when the device's
+ * ULW (Unaligned Schedule) blob has been updated. User space can use this
+ * blob to attach to frames sent to peers.
+ */
+void cfg80211_nan_ulw_update(struct wireless_dev *wdev,
+			     const u8 *ulw, size_t ulw_len, gfp_t gfp);
+
 #ifdef CONFIG_CFG80211_DEBUGFS
 /**
  * wiphy_locked_debugfs_read - do a locked read in debugfs
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 838edc27e666..191bb2e9c7d9 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1395,6 +1395,10 @@
  *	completely replace the previous one.
  *	The peer schedule is automatically removed when the NMI station is
  *	removed.
+ * @NL80211_CMD_NAN_ULW_UPDATE: Notification from the driver to user space
+ *	with the updated ULW blob of the device. User space can use this blob
+ *	to attach to frames sent to peers. This notification contains
+ *	%NL80211_ATTR_NAN_ULW with the ULW blob.
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -1664,6 +1668,7 @@ enum nl80211_commands {
 
 	NL80211_CMD_NAN_SET_PEER_SCHED,
 
+	NL80211_CMD_NAN_ULW_UPDATE,
 	/* add new commands above here */
 
 	/* used to define NL80211_CMD_MAX below */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 7a22980aa7f0..1c885d9c578d 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -22780,6 +22780,49 @@ void cfg80211_nan_cluster_joined(struct wireless_dev *wdev,
 }
 EXPORT_SYMBOL(cfg80211_nan_cluster_joined);
 
+void cfg80211_nan_ulw_update(struct wireless_dev *wdev,
+			     const u8 *ulw, size_t ulw_len, gfp_t gfp)
+{
+	struct wiphy *wiphy = wdev->wiphy;
+	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+	struct sk_buff *msg;
+	void *hdr;
+
+	trace_cfg80211_nan_ulw_update(wiphy, wdev, ulw, ulw_len);
+
+	if (!wdev->owner_nlportid)
+		return;
+
+	/* 32 for the wiphy idx, 64 for the wdev id, 100 for padding */
+	msg = nlmsg_new(nla_total_size(sizeof(u32)) +
+			nla_total_size(ulw_len) +
+			nla_total_size(sizeof(u64)) + 100,
+			gfp);
+	if (!msg)
+		return;
+
+	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NAN_ULW_UPDATE);
+	if (!hdr)
+		goto nla_put_failure;
+
+	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+	    nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
+			      NL80211_ATTR_PAD) ||
+	    (ulw && ulw_len &&
+	     nla_put(msg, NL80211_ATTR_NAN_ULW, ulw_len, ulw)))
+		goto nla_put_failure;
+
+	genlmsg_end(msg, hdr);
+
+	genlmsg_unicast(wiphy_net(wiphy), msg, wdev->owner_nlportid);
+
+	return;
+
+ nla_put_failure:
+	nlmsg_free(msg);
+}
+EXPORT_SYMBOL(cfg80211_nan_ulw_update);
+
 /* initialisation/exit functions */
 
 int __init nl80211_init(void)
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 55db53fb4c5d..5ed551412119 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -4323,6 +4323,27 @@ TRACE_EVENT(cfg80211_nan_sched_update_done,
 	TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT " success=%d",
 		  WIPHY_PR_ARG, WDEV_PR_ARG, __entry->success)
 );
+
+TRACE_EVENT(cfg80211_nan_ulw_update,
+	TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
+		 const u8 *ulw, size_t ulw_len),
+	TP_ARGS(wiphy, wdev, ulw, ulw_len),
+	TP_STRUCT__entry(
+		WIPHY_ENTRY
+		WDEV_ENTRY
+		__dynamic_array(u8, ulw, ulw_len)
+	),
+	TP_fast_assign(
+		WIPHY_ASSIGN;
+		WDEV_ASSIGN;
+		if (ulw && ulw_len)
+			memcpy(__get_dynamic_array(ulw), ulw, ulw_len);
+	),
+	TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT " ulw: %s",
+		  WIPHY_PR_ARG, WDEV_PR_ARG,
+		  __print_array(__get_dynamic_array(ulw),
+				__get_dynamic_array_len(ulw), 1))
+);
 #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
 
 #undef TRACE_INCLUDE_PATH
-- 
2.34.1


^ permalink raw reply related

* [PATCH v3 wireless-next 13/15] wifi: nl80211: allow reporting spurious NAN Data frames
From: Miri Korenblit @ 2026-02-17 11:56 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg
In-Reply-To: <20260217115618.2066972-1-miriam.rachel.korenblit@intel.com>

Currently we have this ability for AP and GO. But it is now needed also for
NAN_DATA mode - as per Wi-Fi Aware (TM) 4.0 specification 6.2.5:
"If a NAN Device receives a unicast NAN Data frame destined for it, but
 with A1 address and A2 address that are not assigned to the NDP, it shall
 discard the frame, and should send a Data Path Termination NAF to the
 frame transmitter"

To allow this, change NL80211_CMD_UNEXPECTED_FRAME to support also
NAN_DATA, so drivers can report such cases and the user space can act
accordingly.

Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260108102921.5cf9f1351655.I47c98ce37843730b8b9eb8bd8e9ef62ed6c17613@changeid
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 include/net/cfg80211.h       | 13 +++++++------
 include/uapi/linux/nl80211.h |  5 +++--
 net/wireless/mlme.c          |  4 ++--
 net/wireless/nl80211.c       | 12 +++++++-----
 4 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 57d0dca1702e..0dee775ddbbc 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -6936,8 +6936,8 @@ enum ieee80211_ap_reg_power {
  *	the P2P Device.
  * @ps: powersave mode is enabled
  * @ps_timeout: dynamic powersave timeout
- * @ap_unexpected_nlportid: (private) netlink port ID of application
- *	registered for unexpected class 3 frames (AP mode)
+ * @unexpected_nlportid: (private) netlink port ID of application
+ *	registered for unexpected frames (AP mode or NAN_DATA mode)
  * @conn: (private) cfg80211 software SME connection state machine data
  * @connect_keys: (private) keys to set after connection is established
  * @conn_bss_type: connecting/connected BSS type
@@ -6999,7 +6999,7 @@ struct wireless_dev {
 	bool ps;
 	int ps_timeout;
 
-	u32 ap_unexpected_nlportid;
+	u32 unexpected_nlportid;
 
 	u32 owner_nlportid;
 	bool nl_owner_dead;
@@ -9570,9 +9570,10 @@ void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
  * @addr: the transmitter address
  * @gfp: context flags
  *
- * This function is used in AP mode (only!) to inform userspace that
- * a spurious class 3 frame was received, to be able to deauth the
- * sender.
+ * This function is used in AP mode to inform userspace that a spurious
+ * class 3 frame was received, to be able to deauth the sender.
+ * It is also used in NAN_DATA mode to report frames from unknown peers
+ * (A2 not assigned to any active NDP), per Wi-Fi Aware (TM) 4.0 specification 6.2.5.
  * Return: %true if the frame was passed to userspace (or this failed
  * for a reason other than not having a subscription.)
  */
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index cc6eb95ccabf..838edc27e666 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -906,8 +906,9 @@
  * @NL80211_CMD_UNEXPECTED_FRAME: Used by an application controlling an AP
  *	(or GO) interface (i.e. hostapd) to ask for unexpected frames to
  *	implement sending deauth to stations that send unexpected class 3
- *	frames. Also used as the event sent by the kernel when such a frame
- *	is received.
+ *	frames. For NAN_DATA interfaces, this is used to report frames from
+ *	unknown peers (A2 not assigned to any active NDP).
+ *	Also used as the event sent by the kernel when such a frame is received.
  *	For the event, the %NL80211_ATTR_MAC attribute carries the TA and
  *	other attributes like the interface index are present.
  *	If used as the command it must have an interface index and you can
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 3fc175f9f868..903a3dc59007 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -782,8 +782,8 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlportid)
 		rdev_crit_proto_stop(rdev, wdev);
 	}
 
-	if (nlportid == wdev->ap_unexpected_nlportid)
-		wdev->ap_unexpected_nlportid = 0;
+	if (nlportid == wdev->unexpected_nlportid)
+		wdev->unexpected_nlportid = 0;
 }
 
 void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index a7f97efe6a0d..7a22980aa7f0 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -15750,13 +15750,14 @@ static int nl80211_register_unexpected_frame(struct sk_buff *skb,
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 
 	if (wdev->iftype != NL80211_IFTYPE_AP &&
-	    wdev->iftype != NL80211_IFTYPE_P2P_GO)
+	    wdev->iftype != NL80211_IFTYPE_P2P_GO &&
+	    wdev->iftype != NL80211_IFTYPE_NAN_DATA)
 		return -EINVAL;
 
-	if (wdev->ap_unexpected_nlportid)
+	if (wdev->unexpected_nlportid)
 		return -EBUSY;
 
-	wdev->ap_unexpected_nlportid = info->snd_portid;
+	wdev->unexpected_nlportid = info->snd_portid;
 	return 0;
 }
 
@@ -21215,7 +21216,7 @@ static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
 	struct sk_buff *msg;
 	void *hdr;
-	u32 nlportid = READ_ONCE(wdev->ap_unexpected_nlportid);
+	u32 nlportid = READ_ONCE(wdev->unexpected_nlportid);
 
 	if (!nlportid)
 		return false;
@@ -21255,7 +21256,8 @@ bool cfg80211_rx_spurious_frame(struct net_device *dev, const u8 *addr,
 	trace_cfg80211_rx_spurious_frame(dev, addr, link_id);
 
 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
-		    wdev->iftype != NL80211_IFTYPE_P2P_GO)) {
+		    wdev->iftype != NL80211_IFTYPE_P2P_GO &&
+		    wdev->iftype != NL80211_IFTYPE_NAN_DATA)) {
 		trace_cfg80211_return_bool(false);
 		return false;
 	}
-- 
2.34.1


^ permalink raw reply related

* [PATCH v3 wireless-next 12/15] wifi: cfg80211: allow ToDS=0/FromDS=0 data frames on NAN data interfaces
From: Miri Korenblit @ 2026-02-17 11:56 UTC (permalink / raw)
  To: linux-wireless; +Cc: Daniel Gabay
In-Reply-To: <20260217115618.2066972-1-miriam.rachel.korenblit@intel.com>

From: Daniel Gabay <daniel.gabay@intel.com>

According to Wi-Fi Aware (TM) specification Table 3, data frame should
have 0 in the FromDS/ToDS fields. Don't drop received frames with 0
FromDS/ToDS if they are received on NAN_DATA interface.
While at it, fix a double indent.

Signed-off-by: Daniel Gabay <daniel.gabay@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260108102921.de5f318a790a.Id34dd69552920b579e6881ffd38fa692a491b601@changeid
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 net/wireless/util.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/net/wireless/util.c b/net/wireless/util.c
index f2ebef59a943..dedbed33311f 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -625,8 +625,9 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
 	case cpu_to_le16(0):
 		if (iftype != NL80211_IFTYPE_ADHOC &&
 		    iftype != NL80211_IFTYPE_STATION &&
-		    iftype != NL80211_IFTYPE_OCB)
-				return -1;
+		    iftype != NL80211_IFTYPE_OCB &&
+		    iftype != NL80211_IFTYPE_NAN_DATA)
+			return -1;
 		break;
 	}
 
-- 
2.34.1


^ permalink raw reply related


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