* Re: [PATCH wireless-next 3/3] wifi: mac80211_hwsim: Advertise support for IEEE 802.1X authentication protocol
From: Kavita Kavita @ 2026-02-26 13:50 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
In-Reply-To: <3ecb3d440ed3ab4fe4cd3765e0c8457ef58fd6b6.camel@sipsolutions.net>
On 2/26/2026 2:06 PM, Johannes Berg wrote:
> On Thu, 2026-02-26 at 12:24 +0530, Kavita Kavita wrote:
>> Advertise support for the IEEE 802.1X authentication protocol in
>> mac80211_hwsim to enable testing scenarios.
>
> Do we even need this in drivers vs. mac80211 just setting it?
>
> All the code for it is in mac80211, so it shouldn't matter?
>
> I'd actually argue NL80211_EXT_FEATURE_EPPKE is the same, mac80211
> should set it instead of the driver (I didn't merge [1] yet anyway) and
> only NL80211_EXT_FEATURE_ASSOC_FRAME_ENCRYPTION should be in the driver?
For (Re)Association frame encryption, additional changes are required in the
driver and firmware. Because of this dependency, we initially thought it was
best to let the driver set the EPPKE and IEEE 802.1X Authentication feature
flags as well.
However, since no lower-layer changes are actually needed for EPPKE and
IEEE 802.1X Authentication, these can safely be advertised directly in mac80211.
The driver should only set the (Re)Association frame encryption feature flag,
and mac80211 can then conditionally enable the EPPKE and IEEE 802.1X Authentication
feature flags based on that indication.
I will send the updated patch set with these changes. Thank you.
>
>
> [1] https://patchwork.kernel.org/project/linux-wireless/patch/20260114111900.2196941-10-kavita.kavita@oss.qualcomm.com/
>
> johannes
^ permalink raw reply
* Re: [PATCH wireless-next 3/3] wifi: mac80211_hwsim: Advertise support for IEEE 802.1X authentication protocol
From: Johannes Berg @ 2026-02-26 13:53 UTC (permalink / raw)
To: Kavita Kavita; +Cc: linux-wireless
In-Reply-To: <af15a01f-93eb-4c0f-b13d-8cea41f82703@oss.qualcomm.com>
On Thu, 2026-02-26 at 19:20 +0530, Kavita Kavita wrote:
>
> On 2/26/2026 2:06 PM, Johannes Berg wrote:
> > On Thu, 2026-02-26 at 12:24 +0530, Kavita Kavita wrote:
> > > Advertise support for the IEEE 802.1X authentication protocol in
> > > mac80211_hwsim to enable testing scenarios.
> >
> > Do we even need this in drivers vs. mac80211 just setting it?
> >
> > All the code for it is in mac80211, so it shouldn't matter?
> >
> > I'd actually argue NL80211_EXT_FEATURE_EPPKE is the same, mac80211
> > should set it instead of the driver (I didn't merge [1] yet anyway) and
> > only NL80211_EXT_FEATURE_ASSOC_FRAME_ENCRYPTION should be in the driver?
>
>
> For (Re)Association frame encryption, additional changes are required in the
> driver and firmware. Because of this dependency, we initially thought it was
> best to let the driver set the EPPKE and IEEE 802.1X Authentication feature
> flags as well.
> However, since no lower-layer changes are actually needed for EPPKE and
> IEEE 802.1X Authentication, these can safely be advertised directly in mac80211.
> The driver should only set the (Re)Association frame encryption feature flag,
> and mac80211 can then conditionally enable the EPPKE and IEEE 802.1X Authentication
> feature flags based on that indication.
>
> I will send the updated patch set with these changes. Thank you.
Right, works for me. Can you please also resend the hwsim patch for
EPPKE/assoc frame encryption then, that I linked to earlier? Feel free
to just put it into this patchset (instead of this one) of course.
I'm planning to apply the AAD/nonce fix soon, and then this can go in.
johannes
^ permalink raw reply
* Re: [PATCH wireless-next 3/3] wifi: mac80211_hwsim: Advertise support for IEEE 802.1X authentication protocol
From: Kavita Kavita @ 2026-02-26 14:07 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
In-Reply-To: <e96a1d08ab71bb75bd7a65278b04d29c609904bf.camel@sipsolutions.net>
On 2/26/2026 7:23 PM, Johannes Berg wrote:
> On Thu, 2026-02-26 at 19:20 +0530, Kavita Kavita wrote:
>>
>> On 2/26/2026 2:06 PM, Johannes Berg wrote:
>>> On Thu, 2026-02-26 at 12:24 +0530, Kavita Kavita wrote:
>>>> Advertise support for the IEEE 802.1X authentication protocol in
>>>> mac80211_hwsim to enable testing scenarios.
>>>
>>> Do we even need this in drivers vs. mac80211 just setting it?
>>>
>>> All the code for it is in mac80211, so it shouldn't matter?
>>>
>>> I'd actually argue NL80211_EXT_FEATURE_EPPKE is the same, mac80211
>>> should set it instead of the driver (I didn't merge [1] yet anyway) and
>>> only NL80211_EXT_FEATURE_ASSOC_FRAME_ENCRYPTION should be in the driver?
>>
>>
>> For (Re)Association frame encryption, additional changes are required in the
>> driver and firmware. Because of this dependency, we initially thought it was
>> best to let the driver set the EPPKE and IEEE 802.1X Authentication feature
>> flags as well.
>> However, since no lower-layer changes are actually needed for EPPKE and
>> IEEE 802.1X Authentication, these can safely be advertised directly in mac80211.
>> The driver should only set the (Re)Association frame encryption feature flag,
>> and mac80211 can then conditionally enable the EPPKE and IEEE 802.1X Authentication
>> feature flags based on that indication.
>>
>> I will send the updated patch set with these changes. Thank you.
>
> Right, works for me. Can you please also resend the hwsim patch for
> EPPKE/assoc frame encryption then, that I linked to earlier? Feel free
> to just put it into this patchset (instead of this one) of course.
>
> I'm planning to apply the AAD/nonce fix soon, and then this can go in.
Sure, I will resend the hwsim patch for EPPKE/Assoc and will include it in the next
patchset version. Thank you.
>
> johannes
^ permalink raw reply
* Re: [PATCH ath-next 0/2] wifi: ath12k: fixes to station statistics request
From: Jeff Johnson @ 2026-02-26 15:27 UTC (permalink / raw)
To: Jeff Johnson, Baochen Qiang; +Cc: linux-wireless, ath12k
In-Reply-To: <20260129-ath12k-fw-stats-fixes-v1-0-55d66064f4d5@oss.qualcomm.com>
On Thu, 29 Jan 2026 10:24:04 +0800, Baochen Qiang wrote:
> ath12k hits timeout and memory leak when requesting firmware statistics,
> fix them.
>
>
Applied, thanks!
[1/2] wifi: ath12k: use correct pdev id when requesting firmware stats
commit: 8f153eb745463b0715f1aad41e765cd83e9da8c0
[2/2] wifi: ath12k: fix station lookup failure when disconnecting from AP
commit: 7259b1a0e54c2d3051ac8f1eb01de121b11118ea
Best regards,
--
Jeff Johnson <jeff.johnson@oss.qualcomm.com>
^ permalink raw reply
* Re: [PATCH wireless] wifi: mac80211: Fix ADDBA update when HW supports reordering
From: Remi Pommarel @ 2026-02-26 15:49 UTC (permalink / raw)
To: Pablo MARTIN-GOMEZ; +Cc: Johannes Berg, linux-wireless, linux-kernel
In-Reply-To: <19061b55-a211-4448-8c49-ca8daa6d9d61@freebox.fr>
On Mon, Feb 23, 2026 at 02:25:13PM +0100, Pablo MARTIN-GOMEZ wrote:
> Hello,
>
> On 23/02/2026 12:50, Johannes Berg wrote:
> > On Sun, 2026-02-22 at 17:06 +0100, Remi Pommarel wrote:
> >>>> 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?
> >>
> >> I was going to say it would not be a no-op for a buf_size update but,
> >> if I understand correctly, even when SUPPORTS_REORDERING_BUFFER is not
> >> set the buf_size update is ignored completely and the reorder_buf is
> >> not resized yet a successful addba response is sent. Don't we need to
> >> check for buf_size change as well as timeout also?
> >
> > I was going to say that I thought buf_size is not allowed to change, but
> > (re)reading the spec doesn't seem to bear that out.
> For once, the standard (802.11-2024) is really clear on this (10.25.2):
>
> A block ack agreement may be modified by the originator by sending an
> ADDBA Request frame (see 11.5.2, except that MLME-ADDBA primitives are
> not used by the originator). All parameters of the agreement may be
> modified except for the TID. If the request is not successful, the
> existing agreement is not modified. If the request is successful, the
> behavior is as if a DELBA frame for the block ack agreement had been
> transmitted by the originator and received by the recipient immediately
> prior to the ADDBA Request frame.
> >
> > I guess we could just unconditionally reject any updates. I'm not sure
> > now why we ever added the update in the first place. Perhaps some
> > implementation was doing no-op updates and failing on negative
> > responses?
> >
> If the originator is compliant and trying to update, unconditionally
> rejecing any update shouldn't have any side-effects. But if the
> originator doesn't receive the ADDBA response, it is going to resend an
> ADDBA request; for the originator, it is just a retry, but for the
> recipient it's an update, so the originator is going to receive a non
> success. And unless the originator sends a DELBA "by default" at some
> point, it won't be able to create a new BA (for a given TID) with the
> recipient.
> [...]
I’m a bit concerned that ignoring all ADDBA updates might break STAs
with finicky aggregation implementations. For example, I’ve observed an
ath12k mesh point get stuck in a loop, repeatedly sending the same ADDBA
request (with unchanged timeout or buffer size) only for us to keep
reject it each time.
But I am, of course, unfortunately unable to reproduce that easily.
--
Remi
^ permalink raw reply
* Re: [PATCH wireless] wifi: mac80211: Fix ADDBA update when HW supports reordering
From: Johannes Berg @ 2026-02-26 16:28 UTC (permalink / raw)
To: Remi Pommarel, Pablo MARTIN-GOMEZ; +Cc: linux-wireless, linux-kernel
In-Reply-To: <aaBo7rnVkRFz3h-U@pilgrim>
On Thu, 2026-02-26 at 16:49 +0100, Remi Pommarel wrote:
> On Mon, Feb 23, 2026 at 02:25:13PM +0100, Pablo MARTIN-GOMEZ wrote:
> > Hello,
> >
> > On 23/02/2026 12:50, Johannes Berg wrote:
> > > On Sun, 2026-02-22 at 17:06 +0100, Remi Pommarel wrote:
> > > > > > 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?
> > > >
> > > > I was going to say it would not be a no-op for a buf_size update but,
> > > > if I understand correctly, even when SUPPORTS_REORDERING_BUFFER is not
> > > > set the buf_size update is ignored completely and the reorder_buf is
> > > > not resized yet a successful addba response is sent. Don't we need to
> > > > check for buf_size change as well as timeout also?
> > >
> > > I was going to say that I thought buf_size is not allowed to change, but
> > > (re)reading the spec doesn't seem to bear that out.
> > For once, the standard (802.11-2024) is really clear on this (10.25.2):
> >
> > A block ack agreement may be modified by the originator by sending an
> > ADDBA Request frame (see 11.5.2, except that MLME-ADDBA primitives are
> > not used by the originator). All parameters of the agreement may be
> > modified except for the TID. If the request is not successful, the
> > existing agreement is not modified. If the request is successful, the
> > behavior is as if a DELBA frame for the block ack agreement had been
> > transmitted by the originator and received by the recipient immediately
> > prior to the ADDBA Request frame.
> > >
> > > I guess we could just unconditionally reject any updates. I'm not sure
> > > now why we ever added the update in the first place. Perhaps some
> > > implementation was doing no-op updates and failing on negative
> > > responses?
> > >
> > If the originator is compliant and trying to update, unconditionally
> > rejecing any update shouldn't have any side-effects. But if the
> > originator doesn't receive the ADDBA response, it is going to resend an
> > ADDBA request; for the originator, it is just a retry, but for the
> > recipient it's an update, so the originator is going to receive a non
> > success. And unless the originator sends a DELBA "by default" at some
> > point, it won't be able to create a new BA (for a given TID) with the
> > recipient.
> > [...]
>
> I’m a bit concerned that ignoring all ADDBA updates might break STAs
> with finicky aggregation implementations. For example, I’ve observed an
> ath12k mesh point get stuck in a loop, repeatedly sending the same ADDBA
> request (with unchanged timeout or buffer size) only for us to keep
> reject it each time.
Sounds like you're both arguing for an "accept if no-op" rather than
unconditional reject, which seems fine to me. Just means storing the
values differently?
johannes
^ permalink raw reply
* Re: [PATCH wireless-next 3/3] wifi: mac80211_hwsim: Advertise support for IEEE 802.1X authentication protocol
From: Kavita Kavita @ 2026-02-26 16:49 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
In-Reply-To: <e96a1d08ab71bb75bd7a65278b04d29c609904bf.camel@sipsolutions.net>
On 2/26/2026 7:23 PM, Johannes Berg wrote:
> On Thu, 2026-02-26 at 19:20 +0530, Kavita Kavita wrote:
>>
>> On 2/26/2026 2:06 PM, Johannes Berg wrote:
>>> On Thu, 2026-02-26 at 12:24 +0530, Kavita Kavita wrote:
>>>> Advertise support for the IEEE 802.1X authentication protocol in
>>>> mac80211_hwsim to enable testing scenarios.
>>>
>>> Do we even need this in drivers vs. mac80211 just setting it?
>>>
>>> All the code for it is in mac80211, so it shouldn't matter?
>>>
>>> I'd actually argue NL80211_EXT_FEATURE_EPPKE is the same, mac80211
>>> should set it instead of the driver (I didn't merge [1] yet anyway) and
>>> only NL80211_EXT_FEATURE_ASSOC_FRAME_ENCRYPTION should be in the driver?
>>
>>
>> For (Re)Association frame encryption, additional changes are required in the
>> driver and firmware. Because of this dependency, we initially thought it was
>> best to let the driver set the EPPKE and IEEE 802.1X Authentication feature
>> flags as well.
>> However, since no lower-layer changes are actually needed for EPPKE and
>> IEEE 802.1X Authentication, these can safely be advertised directly in mac80211.
>> The driver should only set the (Re)Association frame encryption feature flag,
>> and mac80211 can then conditionally enable the EPPKE and IEEE 802.1X Authentication
>> feature flags based on that indication.
>>
>> I will send the updated patch set with these changes. Thank you.
>
> Right, works for me. Can you please also resend the hwsim patch for
> EPPKE/assoc frame encryption then, that I linked to earlier? Feel free
> to just put it into this patchset (instead of this one) of course.
>
> I'm planning to apply the AAD/nonce fix soon, and then this can go in.
Sorry, I missed one case earlier. EPPKE mandates (Re)Association frame
encryption support, so we should only advertise EPPKE when the driver indicates
support for (Re)Association frame encryption in mac80211.
On the other hand, IEEE 802.1X Authentication can operate with or without
(Re)Association encryption support, as specified in IEEE P802.11bi/D4.0, clauses
12.16.5 and 12.16.8.2. I am thinking to advertise IEEE 802.1X Authentication
support directly from mac80211, without any (Re)Association encryption
support indication from the driver.
>
> johannes
^ permalink raw reply
* Re: [PATCH wireless-next 3/3] wifi: mac80211_hwsim: Advertise support for IEEE 802.1X authentication protocol
From: Johannes Berg @ 2026-02-26 16:50 UTC (permalink / raw)
To: Kavita Kavita; +Cc: linux-wireless
In-Reply-To: <15cd54d4-a663-423b-b4c5-9a058f5bc73d@oss.qualcomm.com>
On Thu, 2026-02-26 at 22:19 +0530, Kavita Kavita wrote:
>
> Sorry, I missed one case earlier. EPPKE mandates (Re)Association frame
> encryption support, so we should only advertise EPPKE when the driver indicates
> support for (Re)Association frame encryption in mac80211.
Oh, OK, but we could also check that in mac80211, in register_hw(), I
think?
johannes
^ permalink raw reply
* Re: [PATCH wireless-next 3/3] wifi: mac80211_hwsim: Advertise support for IEEE 802.1X authentication protocol
From: Kavita Kavita @ 2026-02-26 16:58 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
In-Reply-To: <916b0969c559f1faeba94bdef792da646b9b0c21.camel@sipsolutions.net>
On 2/26/2026 10:20 PM, Johannes Berg wrote:
> On Thu, 2026-02-26 at 22:19 +0530, Kavita Kavita wrote:
>>
>> Sorry, I missed one case earlier. EPPKE mandates (Re)Association frame
>> encryption support, so we should only advertise EPPKE when the driver indicates
>> support for (Re)Association frame encryption in mac80211.
>
> Oh, OK, but we could also check that in mac80211, in register_hw(), I
> think?
For EPPKE, I will handle it like this:
@@ -1598,6 +1598,15 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
local->sband_allocated |= BIT(band);
}
+ /*
+ * mac80211 supports EPPKE, if the driver supports (Re)Association
+ * frame encryption
+ */
+ if (wiphy_ext_feature_isset(local->hw.wiphy,
+ NL80211_EXT_FEATURE_ASSOC_FRAME_ENCRYPTION))
+ wiphy_ext_feature_set(local->hw.wiphy,
+ NL80211_EXT_FEATURE_EPPKE);
For IEEE 802.1X Authentication, I am thinking to advertise its support directly
from mac80211, in ieee80211_alloc_hw_nm, without checking for (Re)Association encryption
support from the driver.
>
>
> johannes
^ permalink raw reply
* Re: [PATCH wireless-next 3/3] wifi: mac80211_hwsim: Advertise support for IEEE 802.1X authentication protocol
From: Johannes Berg @ 2026-02-26 17:09 UTC (permalink / raw)
To: Kavita Kavita; +Cc: linux-wireless
In-Reply-To: <67e9955a-1287-4467-9b52-be89144effbc@oss.qualcomm.com>
On Thu, 2026-02-26 at 22:28 +0530, Kavita Kavita wrote:
>
> On 2/26/2026 10:20 PM, Johannes Berg wrote:
> > On Thu, 2026-02-26 at 22:19 +0530, Kavita Kavita wrote:
> > >
> > > Sorry, I missed one case earlier. EPPKE mandates (Re)Association frame
> > > encryption support, so we should only advertise EPPKE when the driver indicates
> > > support for (Re)Association frame encryption in mac80211.
> >
> > Oh, OK, but we could also check that in mac80211, in register_hw(), I
> > think?
>
> For EPPKE, I will handle it like this:
>
> @@ -1598,6 +1598,15 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
> local->sband_allocated |= BIT(band);
> }
>
> + /*
> + * mac80211 supports EPPKE, if the driver supports (Re)Association
> + * frame encryption
> + */
> + if (wiphy_ext_feature_isset(local->hw.wiphy,
> + NL80211_EXT_FEATURE_ASSOC_FRAME_ENCRYPTION))
> + wiphy_ext_feature_set(local->hw.wiphy,
> + NL80211_EXT_FEATURE_EPPKE);
>
> For IEEE 802.1X Authentication, I am thinking to advertise its support directly
> from mac80211, in ieee80211_alloc_hw_nm, without checking for (Re)Association encryption
> support from the driver.
>
Both Makes sense, thanks!
johannes
^ permalink raw reply
* [PATCH v2] wifi: move action code from per-type frame structs
From: Johannes Berg @ 2026-02-26 17:36 UTC (permalink / raw)
To: linux-wireless; +Cc: Johannes Berg
From: Johannes Berg <johannes.berg@intel.com>
The action code actually serves to identify the type of action
frame, so it really isn't part of the per-type structure. Pull
it out and have it in the general action frame format.
In theory, whether or not the action code is present in this
way is up to each category, but all categories that are defined
right now all have that value.
While at it, and since this change requires changing all users,
remove the 'u' and make it an anonymous union in this case, so
that all code using this changes.
Change IEEE80211_MIN_ACTION_SIZE to take an argument which says
how much of the frame is needed, e.g. category, action_code or
the specific frame type that's defined in the union. Again this
also ensures that all code is updated.
In some cases, fix bugs where the SKB length was checked after
having accessed beyond the checked length, in particular in FTM
code, e.g. ieee80211_is_ftm().
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
v2: fix public action frame handling
---
drivers/net/wireless/ath/ath11k/mac.c | 4 +-
drivers/net/wireless/ath/ath12k/mac.c | 4 +-
drivers/net/wireless/ath/ath12k/wifi7/hw.c | 2 +-
.../wireless/intel/iwlwifi/mld/time_sync.c | 6 +-
.../intel/iwlwifi/mvm/ftm-initiator.c | 7 +-
.../wireless/intel/iwlwifi/mvm/time-sync.c | 6 +-
drivers/net/wireless/marvell/mwifiex/tdls.c | 12 +-
drivers/net/wireless/marvell/mwl8k.c | 4 +-
.../wireless/mediatek/mt76/mt76_connac_mac.c | 4 +-
.../net/wireless/mediatek/mt76/mt7925/mac.c | 2 +-
.../net/wireless/mediatek/mt76/mt7996/mac.c | 2 +-
drivers/net/wireless/realtek/rtl8xxxu/core.c | 14 +-
drivers/net/wireless/realtek/rtlwifi/base.c | 28 ++--
drivers/net/wireless/realtek/rtlwifi/pci.c | 2 +-
include/linux/ieee80211.h | 83 +++++-------
net/mac80211/agg-rx.c | 27 ++--
net/mac80211/agg-tx.c | 28 ++--
net/mac80211/eht.c | 21 ++-
net/mac80211/ht.c | 31 ++---
net/mac80211/ibss.c | 18 +--
net/mac80211/iface.c | 18 +--
net/mac80211/mesh.c | 14 +-
net/mac80211/mesh_hwmp.c | 20 ++-
net/mac80211/mesh_plink.c | 21 ++-
net/mac80211/mlme.c | 82 +++++-------
net/mac80211/rx.c | 123 ++++++++----------
net/mac80211/s1g.c | 28 ++--
net/mac80211/spectmgmt.c | 31 ++---
net/mac80211/tdls.c | 29 ++---
net/mac80211/util.c | 5 +-
net/mac80211/vht.c | 10 +-
31 files changed, 301 insertions(+), 385 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index 4dfd08b58416..4abdbfb9c595 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -6282,10 +6282,10 @@ static int ath11k_mac_mgmt_action_frame_fill_elem_data(struct ath11k_vif *arvif,
lockdep_assert_held(&ar->conf_mutex);
/* make sure category field is present */
- if (skb->len < IEEE80211_MIN_ACTION_SIZE)
+ if (skb->len < IEEE80211_MIN_ACTION_SIZE(category))
return -EINVAL;
- remaining_len = skb->len - IEEE80211_MIN_ACTION_SIZE;
+ remaining_len = skb->len - IEEE80211_MIN_ACTION_SIZE(category);
has_protected = ieee80211_has_protected(hdr->frame_control);
/* In case of SW crypto and hdr protected (PMF), packet will already be encrypted,
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index 68431a0e128e..4bd0044b1e80 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -9117,10 +9117,10 @@ static int ath12k_mac_mgmt_action_frame_fill_elem_data(struct ath12k_link_vif *a
lockdep_assert_wiphy(wiphy);
/* make sure category field is present */
- if (skb->len < IEEE80211_MIN_ACTION_SIZE)
+ if (skb->len < IEEE80211_MIN_ACTION_SIZE(category))
return -EINVAL;
- remaining_len = skb->len - IEEE80211_MIN_ACTION_SIZE;
+ remaining_len = skb->len - IEEE80211_MIN_ACTION_SIZE(category);
has_protected = ieee80211_has_protected(hdr->frame_control);
/* In case of SW crypto and hdr protected (PMF), packet will already be encrypted,
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
index df045ddf42da..b1231d04fc2c 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
@@ -104,7 +104,7 @@ static bool ath12k_is_addba_resp_action_code(struct ieee80211_mgmt *mgmt)
if (mgmt->u.action.category != WLAN_CATEGORY_BACK)
return false;
- if (mgmt->u.action.u.addba_resp.action_code != WLAN_ACTION_ADDBA_RESP)
+ if (mgmt->u.action.action_code != WLAN_ACTION_ADDBA_RESP)
return false;
return true;
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/time_sync.c b/drivers/net/wireless/intel/iwlwifi/mld/time_sync.c
index 50799f9bfccb..76880bbae1df 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/time_sync.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/time_sync.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
- * Copyright (C) 2025 Intel Corporation
+ * Copyright (C) 2025-2026 Intel Corporation
*/
#include "mld.h"
@@ -117,9 +117,9 @@ static bool iwl_mld_is_skb_match(struct sk_buff *skb, u8 *addr, u8 dialog_token)
u8 skb_dialog_token;
if (ieee80211_is_timing_measurement(skb))
- skb_dialog_token = mgmt->u.action.u.wnm_timing_msr.dialog_token;
+ skb_dialog_token = mgmt->u.action.wnm_timing_msr.dialog_token;
else
- skb_dialog_token = mgmt->u.action.u.ftm.dialog_token;
+ skb_dialog_token = mgmt->u.action.ftm.dialog_token;
if ((ether_addr_equal(mgmt->sa, addr) ||
ether_addr_equal(mgmt->da, addr)) &&
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c
index a493ef6bedc3..7227df1c653a 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2015-2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2025 Intel Corporation
+ * Copyright (C) 2018-2026 Intel Corporation
*/
#include <linux/etherdevice.h>
#include <linux/math64.h>
@@ -1409,8 +1409,7 @@ void iwl_mvm_ftm_lc_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
struct iwl_mvm_loc_entry *entry;
const u8 *ies, *lci, *civic, *msr_ie;
size_t ies_len, lci_len = 0, civic_len = 0;
- size_t baselen = IEEE80211_MIN_ACTION_SIZE +
- sizeof(mgmt->u.action.u.ftm);
+ size_t baselen = IEEE80211_MIN_ACTION_SIZE(ftm);
static const u8 rprt_type_lci = IEEE80211_SPCT_MSR_RPRT_TYPE_LCI;
static const u8 rprt_type_civic = IEEE80211_SPCT_MSR_RPRT_TYPE_CIVIC;
@@ -1419,7 +1418,7 @@ void iwl_mvm_ftm_lc_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
lockdep_assert_held(&mvm->mutex);
- ies = mgmt->u.action.u.ftm.variable;
+ ies = mgmt->u.action.ftm.variable;
ies_len = len - baselen;
msr_ie = cfg80211_find_ie_match(WLAN_EID_MEASURE_REPORT, ies, ies_len,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-sync.c b/drivers/net/wireless/intel/iwlwifi/mvm/time-sync.c
index edae3e24192b..039b4daac73f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/time-sync.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-sync.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
- * Copyright (C) 2022 Intel Corporation
+ * Copyright (C) 2022, 2026 Intel Corporation
*/
#include "mvm.h"
@@ -18,9 +18,9 @@ static bool iwl_mvm_is_skb_match(struct sk_buff *skb, u8 *addr, u8 dialog_token)
u8 skb_dialog_token;
if (ieee80211_is_timing_measurement(skb))
- skb_dialog_token = mgmt->u.action.u.wnm_timing_msr.dialog_token;
+ skb_dialog_token = mgmt->u.action.wnm_timing_msr.dialog_token;
else
- skb_dialog_token = mgmt->u.action.u.ftm.dialog_token;
+ skb_dialog_token = mgmt->u.action.ftm.dialog_token;
if ((ether_addr_equal(mgmt->sa, addr) ||
ether_addr_equal(mgmt->da, addr)) &&
diff --git a/drivers/net/wireless/marvell/mwifiex/tdls.c b/drivers/net/wireless/marvell/mwifiex/tdls.c
index 77a9a6de636d..95fd5a924226 100644
--- a/drivers/net/wireless/marvell/mwifiex/tdls.c
+++ b/drivers/net/wireless/marvell/mwifiex/tdls.c
@@ -755,16 +755,12 @@ mwifiex_construct_tdls_action_frame(struct mwifiex_private *priv,
switch (action_code) {
case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
/* See the layout of 'struct ieee80211_mgmt'. */
- extra = sizeof(mgmt->u.action.u.tdls_discover_resp) +
- sizeof(mgmt->u.action.category);
+ extra = IEEE80211_MIN_ACTION_SIZE(tdls_discover_resp) - 24;
skb_put(skb, extra);
mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
- mgmt->u.action.u.tdls_discover_resp.action_code =
- WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
- mgmt->u.action.u.tdls_discover_resp.dialog_token =
- dialog_token;
- mgmt->u.action.u.tdls_discover_resp.capability =
- cpu_to_le16(capab);
+ mgmt->u.action.action_code = WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
+ mgmt->u.action.tdls_discover_resp.dialog_token = dialog_token;
+ mgmt->u.action.tdls_discover_resp.capability = cpu_to_le16(capab);
/* move back for addr4 */
memmove(pos + ETH_ALEN, &mgmt->u.action, extra);
/* init address 4 */
diff --git a/drivers/net/wireless/marvell/mwl8k.c b/drivers/net/wireless/marvell/mwl8k.c
index 54d6d00ecdf1..e43614df2164 100644
--- a/drivers/net/wireless/marvell/mwl8k.c
+++ b/drivers/net/wireless/marvell/mwl8k.c
@@ -1985,9 +1985,9 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw,
*/
if (unlikely(ieee80211_is_action(wh->frame_control) &&
mgmt->u.action.category == WLAN_CATEGORY_BACK &&
- mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ &&
+ mgmt->u.action.action_code == WLAN_ACTION_ADDBA_REQ &&
priv->ap_fw)) {
- u16 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
+ u16 capab = le16_to_cpu(mgmt->u.action.addba_req.capab);
tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
index = mwl8k_tid_queue_mapping(tid);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
index 3304b5971be0..38e17f0da1a9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
@@ -414,8 +414,8 @@ mt76_connac2_mac_write_txwi_80211(struct mt76_dev *dev, __le32 *txwi,
if (ieee80211_is_action(fc) &&
mgmt->u.action.category == WLAN_CATEGORY_BACK &&
- mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ) {
- u16 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
+ mgmt->u.action.action_code == WLAN_ACTION_ADDBA_REQ) {
+ u16 capab = le16_to_cpu(mgmt->u.action.addba_req.capab);
txwi[5] |= cpu_to_le32(MT_TXD5_ADD_BA);
tid = (capab >> 2) & IEEE80211_QOS_CTL_TID_MASK;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
index 871b67101976..01dfdb687af5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
@@ -669,7 +669,7 @@ mt7925_mac_write_txwi_80211(struct mt76_dev *dev, __le32 *txwi,
if (ieee80211_is_action(fc) &&
mgmt->u.action.category == WLAN_CATEGORY_BACK &&
- mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ)
+ mgmt->u.action.action_code == WLAN_ACTION_ADDBA_REQ)
tid = MT_TX_ADDBA;
else if (ieee80211_is_mgmt(hdr->frame_control))
tid = MT_TX_NORMAL;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
index 2560e2f46e89..e78febee9721 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
@@ -801,7 +801,7 @@ mt7996_mac_write_txwi_80211(struct mt7996_dev *dev, __le32 *txwi,
if (ieee80211_is_action(fc) &&
mgmt->u.action.category == WLAN_CATEGORY_BACK &&
- mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ) {
+ mgmt->u.action.action_code == WLAN_ACTION_ADDBA_REQ) {
if (is_mt7990(&dev->mt76))
txwi[6] |= cpu_to_le32(FIELD_PREP(MT_TXD6_TID_ADDBA, tid));
else
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/core.c b/drivers/net/wireless/realtek/rtl8xxxu/core.c
index f9a527f6a175..7b1080df8dfc 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/core.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/core.c
@@ -5146,10 +5146,10 @@ static void rtl8xxxu_dump_action(struct device *dev,
if (!(rtl8xxxu_debug & RTL8XXXU_DEBUG_ACTION))
return;
- switch (mgmt->u.action.u.addba_resp.action_code) {
+ switch (mgmt->u.action.action_code) {
case WLAN_ACTION_ADDBA_RESP:
- cap = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
- timeout = le16_to_cpu(mgmt->u.action.u.addba_resp.timeout);
+ cap = le16_to_cpu(mgmt->u.action.addba_resp.capab);
+ timeout = le16_to_cpu(mgmt->u.action.addba_resp.timeout);
dev_info(dev, "WLAN_ACTION_ADDBA_RESP: "
"timeout %i, tid %02x, buf_size %02x, policy %02x, "
"status %02x\n",
@@ -5157,11 +5157,11 @@ static void rtl8xxxu_dump_action(struct device *dev,
(cap & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2,
(cap & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6,
(cap >> 1) & 0x1,
- le16_to_cpu(mgmt->u.action.u.addba_resp.status));
+ le16_to_cpu(mgmt->u.action.addba_resp.status));
break;
case WLAN_ACTION_ADDBA_REQ:
- cap = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
- timeout = le16_to_cpu(mgmt->u.action.u.addba_req.timeout);
+ cap = le16_to_cpu(mgmt->u.action.addba_req.capab);
+ timeout = le16_to_cpu(mgmt->u.action.addba_req.timeout);
dev_info(dev, "WLAN_ACTION_ADDBA_REQ: "
"timeout %i, tid %02x, buf_size %02x, policy %02x\n",
timeout,
@@ -5171,7 +5171,7 @@ static void rtl8xxxu_dump_action(struct device *dev,
break;
default:
dev_info(dev, "action frame %02x\n",
- mgmt->u.action.u.addba_resp.action_code);
+ mgmt->u.action.action_code);
break;
}
}
diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c
index 09e5a16d7252..fdf482233d5e 100644
--- a/drivers/net/wireless/realtek/rtlwifi/base.c
+++ b/drivers/net/wireless/realtek/rtlwifi/base.c
@@ -1409,7 +1409,7 @@ bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
sta_entry =
(struct rtl_sta_info *)sta->drv_priv;
capab =
- le16_to_cpu(mgmt->u.action.u.addba_req.capab);
+ le16_to_cpu(mgmt->u.action.addba_req.capab);
tid = (capab &
IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
if (tid >= MAX_TID_COUNT) {
@@ -2392,35 +2392,35 @@ static struct sk_buff *rtl_make_smps_action(struct ieee80211_hw *hw,
struct sk_buff *skb;
struct ieee80211_mgmt *action_frame;
- /* 27 = header + category + action + smps mode */
- skb = dev_alloc_skb(27 + hw->extra_tx_headroom);
+ skb = dev_alloc_skb(IEEE80211_MIN_ACTION_SIZE(ht_smps) +
+ hw->extra_tx_headroom);
if (!skb)
return NULL;
skb_reserve(skb, hw->extra_tx_headroom);
- action_frame = skb_put_zero(skb, 27);
+ action_frame = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE(ht_smps));
memcpy(action_frame->da, da, ETH_ALEN);
memcpy(action_frame->sa, rtlefuse->dev_addr, ETH_ALEN);
memcpy(action_frame->bssid, bssid, ETH_ALEN);
action_frame->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_ACTION);
action_frame->u.action.category = WLAN_CATEGORY_HT;
- action_frame->u.action.u.ht_smps.action = WLAN_HT_ACTION_SMPS;
+ action_frame->u.action.action_code = WLAN_HT_ACTION_SMPS;
switch (smps) {
case IEEE80211_SMPS_AUTOMATIC:/* 0 */
case IEEE80211_SMPS_NUM_MODES:/* 4 */
WARN_ON(1);
fallthrough;
case IEEE80211_SMPS_OFF:/* 1 */ /*MIMO_PS_NOLIMIT*/
- action_frame->u.action.u.ht_smps.smps_control =
+ action_frame->u.action.ht_smps.smps_control =
WLAN_HT_SMPS_CONTROL_DISABLED;/* 0 */
break;
case IEEE80211_SMPS_STATIC:/* 2 */ /*MIMO_PS_STATIC*/
- action_frame->u.action.u.ht_smps.smps_control =
+ action_frame->u.action.ht_smps.smps_control =
WLAN_HT_SMPS_CONTROL_STATIC;/* 1 */
break;
case IEEE80211_SMPS_DYNAMIC:/* 3 */ /*MIMO_PS_DYNAMIC*/
- action_frame->u.action.u.ht_smps.smps_control =
+ action_frame->u.action.ht_smps.smps_control =
WLAN_HT_SMPS_CONTROL_DYNAMIC;/* 3 */
break;
}
@@ -2519,25 +2519,25 @@ struct sk_buff *rtl_make_del_ba(struct ieee80211_hw *hw,
struct ieee80211_mgmt *action_frame;
u16 params;
- /* 27 = header + category + action + smps mode */
- skb = dev_alloc_skb(34 + hw->extra_tx_headroom);
+ skb = dev_alloc_skb(IEEE80211_MIN_ACTION_SIZE(delba) +
+ hw->extra_tx_headroom);
if (!skb)
return NULL;
skb_reserve(skb, hw->extra_tx_headroom);
- action_frame = skb_put_zero(skb, 34);
+ action_frame = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE(delba));
memcpy(action_frame->sa, sa, ETH_ALEN);
memcpy(action_frame->da, rtlefuse->dev_addr, ETH_ALEN);
memcpy(action_frame->bssid, bssid, ETH_ALEN);
action_frame->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_ACTION);
action_frame->u.action.category = WLAN_CATEGORY_BACK;
- action_frame->u.action.u.delba.action_code = WLAN_ACTION_DELBA;
+ action_frame->u.action.action_code = WLAN_ACTION_DELBA;
params = (u16)(1 << 11); /* bit 11 initiator */
params |= (u16)(tid << 12); /* bit 15:12 TID number */
- action_frame->u.action.u.delba.params = cpu_to_le16(params);
- action_frame->u.action.u.delba.reason_code =
+ action_frame->u.action.delba.params = cpu_to_le16(params);
+ action_frame->u.action.delba.reason_code =
cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT);
return skb;
diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c
index d080469264cf..19e2ff62d9f1 100644
--- a/drivers/net/wireless/realtek/rtlwifi/pci.c
+++ b/drivers/net/wireless/realtek/rtlwifi/pci.c
@@ -507,7 +507,7 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
if (ieee80211_is_action(fc)) {
struct ieee80211_mgmt *action_frame =
(struct ieee80211_mgmt *)skb->data;
- if (action_frame->u.action.u.ht_smps.action ==
+ if (action_frame->u.action.action_code ==
WLAN_HT_ACTION_SMPS) {
dev_kfree_skb(skb);
goto tx_status_ok;
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 0aa2fb8f88de..0c5c847f72a8 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1046,31 +1046,28 @@ struct ieee80211_mgmt {
} __packed probe_resp;
struct {
u8 category;
+ u8 action_code;
union {
struct {
- u8 action_code;
u8 dialog_token;
u8 status_code;
u8 variable[];
} __packed wme_action;
struct{
- u8 action_code;
+ u8 no_fixed_fields[0];
u8 variable[];
} __packed chan_switch;
struct{
- u8 action_code;
struct ieee80211_ext_chansw_ie data;
u8 variable[];
} __packed ext_chan_switch;
struct{
- u8 action_code;
u8 dialog_token;
u8 element_id;
u8 length;
struct ieee80211_msrment_ie msr_elem;
} __packed measurement;
struct{
- u8 action_code;
u8 dialog_token;
__le16 capab;
__le16 timeout;
@@ -1079,7 +1076,6 @@ struct ieee80211_mgmt {
u8 variable[];
} __packed addba_req;
struct{
- u8 action_code;
u8 dialog_token;
__le16 status;
__le16 capab;
@@ -1088,54 +1084,45 @@ struct ieee80211_mgmt {
u8 variable[];
} __packed addba_resp;
struct{
- u8 action_code;
__le16 params;
__le16 reason_code;
} __packed delba;
struct {
- u8 action_code;
+ u8 no_fixed_fields[0];
u8 variable[];
} __packed self_prot;
struct{
- u8 action_code;
+ u8 no_fixed_fields[0];
u8 variable[];
} __packed mesh_action;
struct {
- u8 action;
u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN];
} __packed sa_query;
struct {
- u8 action;
u8 smps_control;
} __packed ht_smps;
struct {
- u8 action_code;
u8 chanwidth;
} __packed ht_notify_cw;
struct {
- u8 action_code;
u8 dialog_token;
__le16 capability;
u8 variable[];
} __packed tdls_discover_resp;
struct {
- u8 action_code;
u8 operating_mode;
} __packed vht_opmode_notif;
struct {
- u8 action_code;
u8 membership[WLAN_MEMBERSHIP_LEN];
u8 position[WLAN_USER_POSITION_LEN];
} __packed vht_group_notif;
struct {
- u8 action_code;
u8 dialog_token;
u8 tpc_elem_id;
u8 tpc_elem_length;
struct ieee80211_tpc_report_ie tpc;
} __packed tpc_report;
struct {
- u8 action_code;
u8 dialog_token;
u8 follow_up;
u8 tod[6];
@@ -1145,11 +1132,10 @@ struct ieee80211_mgmt {
u8 variable[];
} __packed ftm;
struct {
- u8 action_code;
+ u8 no_fixed_fields[0];
u8 variable[];
} __packed s1g;
struct {
- u8 action_code;
u8 dialog_token;
u8 follow_up;
u32 tod;
@@ -1158,41 +1144,37 @@ struct ieee80211_mgmt {
u8 max_toa_error;
} __packed wnm_timing_msr;
struct {
- u8 action_code;
u8 dialog_token;
u8 variable[];
} __packed ttlm_req;
struct {
- u8 action_code;
u8 dialog_token;
__le16 status_code;
u8 variable[];
} __packed ttlm_res;
struct {
- u8 action_code;
+ u8 no_fixed_fields[0];
+ /* no variable fields either */
} __packed ttlm_tear_down;
struct {
- u8 action_code;
u8 dialog_token;
u8 variable[];
} __packed ml_reconf_req;
struct {
- u8 action_code;
u8 dialog_token;
u8 count;
u8 variable[];
} __packed ml_reconf_resp;
struct {
- u8 action_code;
+ u8 no_fixed_fields[0];
u8 variable[];
} __packed epcs;
struct {
- u8 action_code;
u8 dialog_token;
u8 control;
u8 variable[];
} __packed eml_omn;
- } u;
+ };
} __packed action;
DECLARE_FLEX_ARRAY(u8, body); /* Generic frame body */
} u;
@@ -1210,8 +1192,7 @@ struct ieee80211_mgmt {
#define BSS_MEMBERSHIP_SELECTOR_MIN BSS_MEMBERSHIP_SELECTOR_UHR_PHY
-/* mgmt header + 1 byte category code */
-#define IEEE80211_MIN_ACTION_SIZE offsetof(struct ieee80211_mgmt, u.action.u)
+#define IEEE80211_MIN_ACTION_SIZE(type) offsetofend(struct ieee80211_mgmt, u.action.type)
/* Management MIC information element (IEEE 802.11w) for CMAC */
@@ -2389,7 +2370,7 @@ static inline bool ieee80211_is_bufferable_mmpdu(struct sk_buff *skb)
if (!ieee80211_is_action(fc))
return false;
- if (skb->len < offsetofend(typeof(*mgmt), u.action.u.ftm.action_code))
+ if (skb->len < IEEE80211_MIN_ACTION_SIZE(action_code))
return true;
/* action frame - additionally check for non-bufferable FTM */
@@ -2398,8 +2379,8 @@ static inline bool ieee80211_is_bufferable_mmpdu(struct sk_buff *skb)
mgmt->u.action.category != WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION)
return true;
- if (mgmt->u.action.u.ftm.action_code == WLAN_PUB_ACTION_FTM_REQUEST ||
- mgmt->u.action.u.ftm.action_code == WLAN_PUB_ACTION_FTM_RESPONSE)
+ if (mgmt->u.action.action_code == WLAN_PUB_ACTION_FTM_REQUEST ||
+ mgmt->u.action.action_code == WLAN_PUB_ACTION_FTM_RESPONSE)
return false;
return true;
@@ -2449,7 +2430,7 @@ static inline bool _ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr)
*/
static inline bool ieee80211_is_robust_mgmt_frame(struct sk_buff *skb)
{
- if (skb->len < IEEE80211_MIN_ACTION_SIZE)
+ if (skb->len < IEEE80211_MIN_ACTION_SIZE(category))
return false;
return _ieee80211_is_robust_mgmt_frame((void *)skb->data);
}
@@ -2465,7 +2446,7 @@ static inline bool ieee80211_is_public_action(struct ieee80211_hdr *hdr,
{
struct ieee80211_mgmt *mgmt = (void *)hdr;
- if (len < IEEE80211_MIN_ACTION_SIZE)
+ if (len < IEEE80211_MIN_ACTION_SIZE(category))
return false;
if (!ieee80211_is_action(hdr->frame_control))
return false;
@@ -2483,13 +2464,14 @@ static inline bool ieee80211_is_public_action(struct ieee80211_hdr *hdr,
static inline bool
ieee80211_is_protected_dual_of_public_action(struct sk_buff *skb)
{
+ struct ieee80211_mgmt *mgmt = (void *)skb->data;
u8 action;
if (!ieee80211_is_public_action((void *)skb->data, skb->len) ||
- skb->len < IEEE80211_MIN_ACTION_SIZE + 1)
+ skb->len < IEEE80211_MIN_ACTION_SIZE(action_code))
return false;
- action = *(u8 *)(skb->data + IEEE80211_MIN_ACTION_SIZE);
+ action = mgmt->u.action.action_code;
return action != WLAN_PUB_ACTION_20_40_BSS_COEX &&
action != WLAN_PUB_ACTION_DSE_REG_LOC_ANN &&
@@ -2528,7 +2510,7 @@ static inline bool _ieee80211_is_group_privacy_action(struct ieee80211_hdr *hdr)
*/
static inline bool ieee80211_is_group_privacy_action(struct sk_buff *skb)
{
- if (skb->len < IEEE80211_MIN_ACTION_SIZE)
+ if (skb->len < IEEE80211_MIN_ACTION_SIZE(category))
return false;
return _ieee80211_is_group_privacy_action((void *)skb->data);
}
@@ -2624,8 +2606,7 @@ static inline bool ieee80211_action_contains_tpc(struct sk_buff *skb)
if (!ieee80211_is_action(mgmt->frame_control))
return false;
- if (skb->len < IEEE80211_MIN_ACTION_SIZE +
- sizeof(mgmt->u.action.u.tpc_report))
+ if (skb->len < IEEE80211_MIN_ACTION_SIZE(tpc_report))
return false;
/*
@@ -2644,12 +2625,11 @@ static inline bool ieee80211_action_contains_tpc(struct sk_buff *skb)
return false;
/* both spectrum mgmt and link measurement have same action code */
- if (mgmt->u.action.u.tpc_report.action_code !=
- WLAN_ACTION_SPCT_TPC_RPRT)
+ if (mgmt->u.action.action_code != WLAN_ACTION_SPCT_TPC_RPRT)
return false;
- if (mgmt->u.action.u.tpc_report.tpc_elem_id != WLAN_EID_TPC_REPORT ||
- mgmt->u.action.u.tpc_report.tpc_elem_length !=
+ if (mgmt->u.action.tpc_report.tpc_elem_id != WLAN_EID_TPC_REPORT ||
+ mgmt->u.action.tpc_report.tpc_elem_length !=
sizeof(struct ieee80211_tpc_report_ie))
return false;
@@ -2665,16 +2645,15 @@ static inline bool ieee80211_is_timing_measurement(struct sk_buff *skb)
{
struct ieee80211_mgmt *mgmt = (void *)skb->data;
- if (skb->len < IEEE80211_MIN_ACTION_SIZE)
+ if (skb->len < IEEE80211_MIN_ACTION_SIZE(wnm_timing_msr))
return false;
if (!ieee80211_is_action(mgmt->frame_control))
return false;
if (mgmt->u.action.category == WLAN_CATEGORY_WNM_UNPROTECTED &&
- mgmt->u.action.u.wnm_timing_msr.action_code ==
- WLAN_UNPROTECTED_WNM_ACTION_TIMING_MEASUREMENT_RESPONSE &&
- skb->len >= offsetofend(typeof(*mgmt), u.action.u.wnm_timing_msr))
+ mgmt->u.action.action_code ==
+ WLAN_UNPROTECTED_WNM_ACTION_TIMING_MEASUREMENT_RESPONSE)
return true;
return false;
@@ -2689,15 +2668,13 @@ static inline bool ieee80211_is_ftm(struct sk_buff *skb)
{
struct ieee80211_mgmt *mgmt = (void *)skb->data;
+ if (skb->len < IEEE80211_MIN_ACTION_SIZE(ftm))
+ return false;
+
if (!ieee80211_is_public_action((void *)mgmt, skb->len))
return false;
- if (mgmt->u.action.u.ftm.action_code ==
- WLAN_PUB_ACTION_FTM_RESPONSE &&
- skb->len >= offsetofend(typeof(*mgmt), u.action.u.ftm))
- return true;
-
- return false;
+ return mgmt->u.action.action_code == WLAN_PUB_ACTION_FTM_RESPONSE;
}
struct element {
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 7da909d78c68..45e3a5d7b93d 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -9,7 +9,7 @@
* Copyright 2007, Michael Wu <flamingice@sourmilk.net>
* Copyright 2007-2010, Intel Corporation
* Copyright(c) 2015-2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2025 Intel Corporation
+ * Copyright (C) 2018-2026 Intel Corporation
*/
/**
@@ -251,19 +251,20 @@ static void ieee80211_send_addba_resp(struct sta_info *sta, u8 *da, u16 tid,
skb_reserve(skb, local->hw.extra_tx_headroom);
mgmt = ieee80211_mgmt_ba(skb, da, sdata);
- skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_resp));
+ skb_put(skb, 2 + sizeof(mgmt->u.action.addba_resp));
mgmt->u.action.category = WLAN_CATEGORY_BACK;
- mgmt->u.action.u.addba_resp.action_code = WLAN_ACTION_ADDBA_RESP;
- mgmt->u.action.u.addba_resp.dialog_token = dialog_token;
+ mgmt->u.action.action_code = WLAN_ACTION_ADDBA_RESP;
+
+ mgmt->u.action.addba_resp.dialog_token = dialog_token;
capab = u16_encode_bits(amsdu, IEEE80211_ADDBA_PARAM_AMSDU_MASK);
capab |= u16_encode_bits(policy, IEEE80211_ADDBA_PARAM_POLICY_MASK);
capab |= u16_encode_bits(tid, IEEE80211_ADDBA_PARAM_TID_MASK);
capab |= u16_encode_bits(buf_size, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK);
- mgmt->u.action.u.addba_resp.capab = cpu_to_le16(capab);
- mgmt->u.action.u.addba_resp.timeout = cpu_to_le16(timeout);
- mgmt->u.action.u.addba_resp.status = cpu_to_le16(status);
+ mgmt->u.action.addba_resp.capab = cpu_to_le16(capab);
+ mgmt->u.action.addba_resp.timeout = cpu_to_le16(timeout);
+ mgmt->u.action.addba_resp.status = cpu_to_le16(status);
if (sta->sta.valid_links || sta->sta.deflink.he_cap.has_he)
ieee80211_add_addbaext(skb, req_addba_ext_data, buf_size);
@@ -477,22 +478,22 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
u8 dialog_token, addba_ext_data;
/* extract session parameters from addba request frame */
- dialog_token = mgmt->u.action.u.addba_req.dialog_token;
- timeout = le16_to_cpu(mgmt->u.action.u.addba_req.timeout);
+ dialog_token = mgmt->u.action.addba_req.dialog_token;
+ timeout = le16_to_cpu(mgmt->u.action.addba_req.timeout);
start_seq_num =
- le16_to_cpu(mgmt->u.action.u.addba_req.start_seq_num) >> 4;
+ le16_to_cpu(mgmt->u.action.addba_req.start_seq_num) >> 4;
- capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
+ capab = le16_to_cpu(mgmt->u.action.addba_req.capab);
ba_policy = (capab & IEEE80211_ADDBA_PARAM_POLICY_MASK) >> 1;
tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6;
addba_ext_data =
ieee80211_retrieve_addba_ext_data(sta,
- mgmt->u.action.u.addba_req.variable,
+ mgmt->u.action.addba_req.variable,
len -
offsetof(typeof(*mgmt),
- u.action.u.addba_req.variable),
+ u.action.addba_req.variable),
&buf_size);
__ieee80211_start_rx_ba_session(sta, dialog_token, timeout,
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index d981b0fc57bf..de68f7da6f39 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -9,7 +9,7 @@
* Copyright 2007, Michael Wu <flamingice@sourmilk.net>
* Copyright 2007-2010, Intel Corporation
* Copyright(c) 2015-2017 Intel Deutschland GmbH
- * Copyright (C) 2018 - 2024 Intel Corporation
+ * Copyright (C) 2018-2026 Intel Corporation
*/
#include <linux/ieee80211.h>
@@ -68,7 +68,7 @@ static void ieee80211_send_addba_request(struct sta_info *sta, u16 tid,
struct ieee80211_mgmt *mgmt;
u16 capab;
- skb = dev_alloc_skb(sizeof(*mgmt) +
+ skb = dev_alloc_skb(IEEE80211_MIN_ACTION_SIZE(addba_req) +
2 + sizeof(struct ieee80211_addba_ext_ie) +
local->hw.extra_tx_headroom);
if (!skb)
@@ -77,21 +77,21 @@ static void ieee80211_send_addba_request(struct sta_info *sta, u16 tid,
skb_reserve(skb, local->hw.extra_tx_headroom);
mgmt = ieee80211_mgmt_ba(skb, sta->sta.addr, sdata);
- skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_req));
+ skb_put(skb, 2 + sizeof(mgmt->u.action.addba_req));
mgmt->u.action.category = WLAN_CATEGORY_BACK;
- mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ;
+ mgmt->u.action.action_code = WLAN_ACTION_ADDBA_REQ;
- mgmt->u.action.u.addba_req.dialog_token = dialog_token;
+ mgmt->u.action.addba_req.dialog_token = dialog_token;
capab = IEEE80211_ADDBA_PARAM_AMSDU_MASK;
capab |= IEEE80211_ADDBA_PARAM_POLICY_MASK;
capab |= u16_encode_bits(tid, IEEE80211_ADDBA_PARAM_TID_MASK);
capab |= u16_encode_bits(agg_size, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK);
- mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab);
+ mgmt->u.action.addba_req.capab = cpu_to_le16(capab);
- mgmt->u.action.u.addba_req.timeout = cpu_to_le16(timeout);
- mgmt->u.action.u.addba_req.start_seq_num =
+ mgmt->u.action.addba_req.timeout = cpu_to_le16(timeout);
+ mgmt->u.action.addba_req.start_seq_num =
cpu_to_le16(start_seq_num << 4);
if (sta->sta.deflink.he_cap.has_he)
@@ -978,15 +978,15 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
lockdep_assert_wiphy(sta->local->hw.wiphy);
- capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
+ capab = le16_to_cpu(mgmt->u.action.addba_resp.capab);
amsdu = capab & IEEE80211_ADDBA_PARAM_AMSDU_MASK;
tid = u16_get_bits(capab, IEEE80211_ADDBA_PARAM_TID_MASK);
buf_size = u16_get_bits(capab, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK);
ieee80211_retrieve_addba_ext_data(sta,
- mgmt->u.action.u.addba_resp.variable,
+ mgmt->u.action.addba_resp.variable,
len - offsetof(typeof(*mgmt),
- u.action.u.addba_resp.variable),
+ u.action.addba_resp.variable),
&buf_size);
buf_size = min(buf_size, local->hw.max_tx_aggregation_subframes);
@@ -999,7 +999,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
if (!tid_tx)
return;
- if (mgmt->u.action.u.addba_resp.dialog_token != tid_tx->dialog_token) {
+ if (mgmt->u.action.addba_resp.dialog_token != tid_tx->dialog_token) {
ht_dbg(sta->sdata, "wrong addBA response token, %pM tid %d\n",
sta->sta.addr, tid);
return;
@@ -1029,7 +1029,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
* is set to 0, the Buffer Size subfield is set to a value
* of at least 1.
*/
- if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
+ if (le16_to_cpu(mgmt->u.action.addba_resp.status)
== WLAN_STATUS_SUCCESS && buf_size) {
if (test_and_set_bit(HT_AGG_STATE_RESPONSE_RECEIVED,
&tid_tx->state)) {
@@ -1046,7 +1046,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
sta->ampdu_mlme.addba_req_num[tid] = 0;
tid_tx->timeout =
- le16_to_cpu(mgmt->u.action.u.addba_resp.timeout);
+ le16_to_cpu(mgmt->u.action.addba_resp.timeout);
if (tid_tx->timeout) {
mod_timer(&tid_tx->session_timer,
diff --git a/net/mac80211/eht.c b/net/mac80211/eht.c
index 75096b2195d2..ae594e77dbef 100644
--- a/net/mac80211/eht.c
+++ b/net/mac80211/eht.c
@@ -108,7 +108,7 @@ static void
ieee80211_send_eml_op_mode_notif(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *req, int opt_len)
{
- int len = offsetofend(struct ieee80211_mgmt, u.action.u.eml_omn);
+ int len = IEEE80211_MIN_ACTION_SIZE(eml_omn);
struct ieee80211_local *local = sdata->local;
struct ieee80211_mgmt *mgmt;
struct sk_buff *skb;
@@ -127,16 +127,15 @@ ieee80211_send_eml_op_mode_notif(struct ieee80211_sub_if_data *sdata,
memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
mgmt->u.action.category = WLAN_CATEGORY_PROTECTED_EHT;
- mgmt->u.action.u.eml_omn.action_code =
- WLAN_PROTECTED_EHT_ACTION_EML_OP_MODE_NOTIF;
- mgmt->u.action.u.eml_omn.dialog_token =
- req->u.action.u.eml_omn.dialog_token;
- mgmt->u.action.u.eml_omn.control = req->u.action.u.eml_omn.control &
+ mgmt->u.action.action_code = WLAN_PROTECTED_EHT_ACTION_EML_OP_MODE_NOTIF;
+ mgmt->u.action.eml_omn.dialog_token =
+ req->u.action.eml_omn.dialog_token;
+ mgmt->u.action.eml_omn.control = req->u.action.eml_omn.control &
~(IEEE80211_EML_CTRL_EMLSR_PARAM_UPDATE |
IEEE80211_EML_CTRL_INDEV_COEX_ACT);
/* Copy optional fields from the received notification frame */
- memcpy(mgmt->u.action.u.eml_omn.variable,
- req->u.action.u.eml_omn.variable, opt_len);
+ memcpy(mgmt->u.action.eml_omn.variable,
+ req->u.action.eml_omn.variable, opt_len);
ieee80211_tx_skb(sdata, skb);
}
@@ -144,14 +143,14 @@ ieee80211_send_eml_op_mode_notif(struct ieee80211_sub_if_data *sdata,
void ieee80211_rx_eml_op_mode_notif(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb)
{
- int len = offsetofend(struct ieee80211_mgmt, u.action.u.eml_omn);
+ int len = IEEE80211_MIN_ACTION_SIZE(eml_omn);
enum nl80211_iftype type = ieee80211_vif_type_p2p(&sdata->vif);
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
const struct wiphy_iftype_ext_capab *ift_ext_capa;
struct ieee80211_mgmt *mgmt = (void *)skb->data;
struct ieee80211_local *local = sdata->local;
- u8 control = mgmt->u.action.u.eml_omn.control;
- u8 *ptr = mgmt->u.action.u.eml_omn.variable;
+ u8 control = mgmt->u.action.eml_omn.control;
+ u8 *ptr = mgmt->u.action.eml_omn.variable;
struct ieee80211_eml_params eml_params = {
.link_id = status->link_id,
};
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index 1c82a28b03de..9e2469a8ce64 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -9,7 +9,7 @@
* Copyright 2007, Michael Wu <flamingice@sourmilk.net>
* Copyright 2007-2010, Intel Corporation
* Copyright 2017 Intel Deutschland GmbH
- * Copyright(c) 2020-2025 Intel Corporation
+ * Copyright(c) 2020-2026 Intel Corporation
*/
#include <linux/ieee80211.h>
@@ -462,22 +462,23 @@ void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt;
u16 params;
- skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
+ skb = dev_alloc_skb(IEEE80211_MIN_ACTION_SIZE(delba) +
+ local->hw.extra_tx_headroom);
if (!skb)
return;
skb_reserve(skb, local->hw.extra_tx_headroom);
mgmt = ieee80211_mgmt_ba(skb, da, sdata);
- skb_put(skb, 1 + sizeof(mgmt->u.action.u.delba));
+ skb_put(skb, 2 + sizeof(mgmt->u.action.delba));
mgmt->u.action.category = WLAN_CATEGORY_BACK;
- mgmt->u.action.u.delba.action_code = WLAN_ACTION_DELBA;
+ mgmt->u.action.action_code = WLAN_ACTION_DELBA;
params = (u16)(initiator << 11); /* bit 11 initiator */
params |= (u16)(tid << 12); /* bit 15:12 TID number */
- mgmt->u.action.u.delba.params = cpu_to_le16(params);
- mgmt->u.action.u.delba.reason_code = cpu_to_le16(reason_code);
+ mgmt->u.action.delba.params = cpu_to_le16(params);
+ mgmt->u.action.delba.reason_code = cpu_to_le16(reason_code);
ieee80211_tx_skb(sdata, skb);
}
@@ -489,14 +490,14 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
u16 tid, params;
u16 initiator;
- params = le16_to_cpu(mgmt->u.action.u.delba.params);
+ params = le16_to_cpu(mgmt->u.action.delba.params);
tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12;
initiator = (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) >> 11;
ht_dbg_ratelimited(sdata, "delba from %pM (%s) tid %d reason code %d\n",
mgmt->sa, initiator ? "initiator" : "recipient",
tid,
- le16_to_cpu(mgmt->u.action.u.delba.reason_code));
+ le16_to_cpu(mgmt->u.action.delba.reason_code));
if (initiator == WLAN_BACK_INITIATOR)
__ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_INITIATOR, 0,
@@ -530,20 +531,20 @@ int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
struct ieee80211_tx_info *info;
u8 status_link_id = link_id < 0 ? 0 : link_id;
- /* 27 = header + category + action + smps mode */
- skb = dev_alloc_skb(27 + local->hw.extra_tx_headroom);
+ skb = dev_alloc_skb(IEEE80211_MIN_ACTION_SIZE(ht_smps) +
+ local->hw.extra_tx_headroom);
if (!skb)
return -ENOMEM;
skb_reserve(skb, local->hw.extra_tx_headroom);
- action_frame = skb_put(skb, 27);
+ action_frame = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE(ht_smps));
memcpy(action_frame->da, da, ETH_ALEN);
memcpy(action_frame->sa, sdata->dev->dev_addr, ETH_ALEN);
memcpy(action_frame->bssid, bssid, ETH_ALEN);
action_frame->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_ACTION);
action_frame->u.action.category = WLAN_CATEGORY_HT;
- action_frame->u.action.u.ht_smps.action = WLAN_HT_ACTION_SMPS;
+ action_frame->u.action.action_code = WLAN_HT_ACTION_SMPS;
switch (smps) {
case IEEE80211_SMPS_AUTOMATIC:
case IEEE80211_SMPS_NUM_MODES:
@@ -551,15 +552,15 @@ int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
smps = IEEE80211_SMPS_OFF;
fallthrough;
case IEEE80211_SMPS_OFF:
- action_frame->u.action.u.ht_smps.smps_control =
+ action_frame->u.action.ht_smps.smps_control =
WLAN_HT_SMPS_CONTROL_DISABLED;
break;
case IEEE80211_SMPS_STATIC:
- action_frame->u.action.u.ht_smps.smps_control =
+ action_frame->u.action.ht_smps.smps_control =
WLAN_HT_SMPS_CONTROL_STATIC;
break;
case IEEE80211_SMPS_DYNAMIC:
- action_frame->u.action.u.ht_smps.smps_control =
+ action_frame->u.action.ht_smps.smps_control =
WLAN_HT_SMPS_CONTROL_DYNAMIC;
break;
}
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 168f84a1353b..0298272c37ec 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -9,7 +9,7 @@
* Copyright 2009, Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright(c) 2016 Intel Deutschland GmbH
- * Copyright(c) 2018-2025 Intel Corporation
+ * Copyright(c) 2018-2026 Intel Corporation
*/
#include <linux/delay.h>
@@ -888,19 +888,11 @@ ieee80211_rx_mgmt_spectrum_mgmt(struct ieee80211_sub_if_data *sdata,
struct ieee80211_rx_status *rx_status,
struct ieee802_11_elems *elems)
{
- int required_len;
-
- if (len < IEEE80211_MIN_ACTION_SIZE + 1)
+ if (len < IEEE80211_MIN_ACTION_SIZE(chan_switch))
return;
/* CSA is the only action we handle for now */
- if (mgmt->u.action.u.measurement.action_code !=
- WLAN_ACTION_SPCT_CHL_SWITCH)
- return;
-
- required_len = IEEE80211_MIN_ACTION_SIZE +
- sizeof(mgmt->u.action.u.chan_switch);
- if (len < required_len)
+ if (mgmt->u.action.action_code != WLAN_ACTION_SPCT_CHL_SWITCH)
return;
if (!sdata->vif.bss_conf.csa_active)
@@ -1613,12 +1605,12 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
case WLAN_CATEGORY_SPECTRUM_MGMT:
ies_len = skb->len -
offsetof(struct ieee80211_mgmt,
- u.action.u.chan_switch.variable);
+ u.action.chan_switch.variable);
if (ies_len < 0)
break;
- elems = ieee802_11_parse_elems(mgmt->u.action.u.chan_switch.variable,
+ elems = ieee802_11_parse_elems(mgmt->u.action.chan_switch.variable,
ies_len,
IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_ACTION,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 676b2a43c9f2..2e391cec73a0 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1579,7 +1579,7 @@ static void ieee80211_iface_process_skb(struct ieee80211_local *local,
sta = sta_info_get_bss(sdata, mgmt->sa);
if (sta) {
- switch (mgmt->u.action.u.addba_req.action_code) {
+ switch (mgmt->u.action.action_code) {
case WLAN_ACTION_ADDBA_REQ:
ieee80211_process_addba_request(local, sta,
mgmt, len);
@@ -1599,9 +1599,9 @@ static void ieee80211_iface_process_skb(struct ieee80211_local *local,
}
} else if (ieee80211_is_action(mgmt->frame_control) &&
mgmt->u.action.category == WLAN_CATEGORY_HT) {
- switch (mgmt->u.action.u.ht_smps.action) {
+ switch (mgmt->u.action.action_code) {
case WLAN_HT_ACTION_NOTIFY_CHANWIDTH: {
- u8 chanwidth = mgmt->u.action.u.ht_notify_cw.chanwidth;
+ u8 chanwidth = mgmt->u.action.ht_notify_cw.chanwidth;
struct ieee80211_rx_status *status;
struct link_sta_info *link_sta;
struct sta_info *sta;
@@ -1628,7 +1628,7 @@ static void ieee80211_iface_process_skb(struct ieee80211_local *local,
}
} else if (ieee80211_is_action(mgmt->frame_control) &&
mgmt->u.action.category == WLAN_CATEGORY_VHT) {
- switch (mgmt->u.action.u.vht_group_notif.action_code) {
+ switch (mgmt->u.action.action_code) {
case WLAN_VHT_ACTION_OPMODE_NOTIF: {
struct ieee80211_rx_status *status;
enum nl80211_band band;
@@ -1637,7 +1637,7 @@ static void ieee80211_iface_process_skb(struct ieee80211_local *local,
status = IEEE80211_SKB_RXCB(skb);
band = status->band;
- opmode = mgmt->u.action.u.vht_opmode_notif.operating_mode;
+ opmode = mgmt->u.action.vht_opmode_notif.operating_mode;
sta = sta_info_get_bss(sdata, mgmt->sa);
@@ -1658,7 +1658,7 @@ static void ieee80211_iface_process_skb(struct ieee80211_local *local,
}
} else if (ieee80211_is_action(mgmt->frame_control) &&
mgmt->u.action.category == WLAN_CATEGORY_S1G) {
- switch (mgmt->u.action.u.s1g.action_code) {
+ switch (mgmt->u.action.action_code) {
case WLAN_S1G_TWT_TEARDOWN:
case WLAN_S1G_TWT_SETUP:
ieee80211_s1g_rx_twt_action(sdata, skb);
@@ -1669,7 +1669,7 @@ static void ieee80211_iface_process_skb(struct ieee80211_local *local,
} else if (ieee80211_is_action(mgmt->frame_control) &&
mgmt->u.action.category == WLAN_CATEGORY_PROTECTED_EHT) {
if (sdata->vif.type == NL80211_IFTYPE_AP) {
- switch (mgmt->u.action.u.eml_omn.action_code) {
+ switch (mgmt->u.action.action_code) {
case WLAN_PROTECTED_EHT_ACTION_EML_OP_MODE_NOTIF:
ieee80211_rx_eml_op_mode_notif(sdata, skb);
break;
@@ -1677,7 +1677,7 @@ static void ieee80211_iface_process_skb(struct ieee80211_local *local,
break;
}
} else if (sdata->vif.type == NL80211_IFTYPE_STATION) {
- switch (mgmt->u.action.u.ttlm_req.action_code) {
+ switch (mgmt->u.action.action_code) {
case WLAN_PROTECTED_EHT_ACTION_TTLM_REQ:
ieee80211_process_neg_ttlm_req(sdata, mgmt,
skb->len);
@@ -1765,7 +1765,7 @@ static void ieee80211_iface_process_status(struct ieee80211_sub_if_data *sdata,
if (ieee80211_is_action(mgmt->frame_control) &&
mgmt->u.action.category == WLAN_CATEGORY_S1G) {
- switch (mgmt->u.action.u.s1g.action_code) {
+ switch (mgmt->u.action.action_code) {
case WLAN_S1G_TWT_TEARDOWN:
case WLAN_S1G_TWT_SETUP:
ieee80211_s1g_status_twt_action(sdata, skb);
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 68901f1def0d..ccbf33fb23bd 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2008, 2009 open80211s Ltd.
- * Copyright (C) 2018 - 2025 Intel Corporation
+ * Copyright (C) 2018-2026 Intel Corporation
* Authors: Luis Carlos Cobo <luisca@cozybit.com>
* Javier Cardona <javier@cozybit.com>
*/
@@ -19,8 +19,7 @@ static struct kmem_cache *rm_cache;
bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt)
{
- return (mgmt->u.action.u.mesh_action.action_code ==
- WLAN_MESH_ACTION_HWMP_PATH_SELECTION);
+ return mgmt->u.action.action_code == WLAN_MESH_ACTION_HWMP_PATH_SELECTION;
}
void ieee80211s_init(void)
@@ -1619,13 +1618,12 @@ static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata,
size_t baselen;
u8 *pos;
- if (mgmt->u.action.u.measurement.action_code !=
- WLAN_ACTION_SPCT_CHL_SWITCH)
+ if (mgmt->u.action.action_code != WLAN_ACTION_SPCT_CHL_SWITCH)
return;
- pos = mgmt->u.action.u.chan_switch.variable;
+ pos = mgmt->u.action.chan_switch.variable;
baselen = offsetof(struct ieee80211_mgmt,
- u.action.u.chan_switch.variable);
+ u.action.chan_switch.variable);
elems = ieee802_11_parse_elems(pos, len - baselen,
IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_ACTION,
@@ -1668,7 +1666,7 @@ static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
{
switch (mgmt->u.action.category) {
case WLAN_CATEGORY_SELF_PROTECTED:
- switch (mgmt->u.action.u.self_prot.action_code) {
+ switch (mgmt->u.action.action_code) {
case WLAN_SP_MESH_PEERING_OPEN:
case WLAN_SP_MESH_PEERING_CLOSE:
case WLAN_SP_MESH_PEERING_CONFIRM:
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index a41b57bd11ff..dad311e0833a 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2008, 2009 open80211s Ltd.
- * Copyright (C) 2019, 2021-2023, 2025 Intel Corporation
+ * Copyright (C) 2019, 2021-2023, 2025-2026 Intel Corporation
* Author: Luis Carlos Cobo <luisca@cozybit.com>
*/
@@ -105,12 +105,11 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
u32 lifetime, u32 metric, u32 preq_id,
struct ieee80211_sub_if_data *sdata)
{
+ int hdr_len = IEEE80211_MIN_ACTION_SIZE(mesh_action);
struct ieee80211_local *local = sdata->local;
struct sk_buff *skb;
struct ieee80211_mgmt *mgmt;
u8 *pos, ie_len;
- int hdr_len = offsetofend(struct ieee80211_mgmt,
- u.action.u.mesh_action);
skb = dev_alloc_skb(local->tx_headroom +
hdr_len +
@@ -127,8 +126,7 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
/* BSSID == SA */
memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION;
- mgmt->u.action.u.mesh_action.action_code =
- WLAN_MESH_ACTION_HWMP_PATH_SELECTION;
+ mgmt->u.action.action_code = WLAN_MESH_ACTION_HWMP_PATH_SELECTION;
switch (action) {
case MPATH_PREQ:
@@ -237,13 +235,12 @@ int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata,
u8 ttl, const u8 *target, u32 target_sn,
u16 target_rcode, const u8 *ra)
{
+ int hdr_len = IEEE80211_MIN_ACTION_SIZE(mesh_action);
struct ieee80211_local *local = sdata->local;
struct sk_buff *skb;
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
struct ieee80211_mgmt *mgmt;
u8 *pos, ie_len;
- int hdr_len = offsetofend(struct ieee80211_mgmt,
- u.action.u.mesh_action);
if (time_before(jiffies, ifmsh->next_perr))
return -EAGAIN;
@@ -265,8 +262,7 @@ int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata,
/* BSSID == SA */
memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION;
- mgmt->u.action.u.mesh_action.action_code =
- WLAN_MESH_ACTION_HWMP_PATH_SELECTION;
+ mgmt->u.action.action_code = WLAN_MESH_ACTION_HWMP_PATH_SELECTION;
ie_len = 15;
pos = skb_put(skb, 2 + ie_len);
*pos++ = WLAN_EID_PERR;
@@ -938,7 +934,7 @@ void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
struct sta_info *sta;
/* need action_code */
- if (len < IEEE80211_MIN_ACTION_SIZE + 1)
+ if (len < IEEE80211_MIN_ACTION_SIZE(mesh_action))
return;
rcu_read_lock();
@@ -949,8 +945,8 @@ void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
}
rcu_read_unlock();
- baselen = (u8 *) mgmt->u.action.u.mesh_action.variable - (u8 *) mgmt;
- elems = ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable,
+ baselen = mgmt->u.action.mesh_action.variable - (u8 *)mgmt;
+ elems = ieee802_11_parse_elems(mgmt->u.action.mesh_action.variable,
len - baselen,
IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_ACTION,
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 04c931cd2063..7d823a55636f 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2008, 2009 open80211s Ltd.
- * Copyright (C) 2019, 2021-2025 Intel Corporation
+ * Copyright (C) 2019, 2021-2026 Intel Corporation
* Author: Luis Carlos Cobo <luisca@cozybit.com>
*/
#include <linux/gfp.h>
@@ -13,7 +13,7 @@
#include "rate.h"
#include "mesh.h"
-#define PLINK_CNF_AID(mgmt) ((mgmt)->u.action.u.self_prot.variable + 2)
+#define PLINK_CNF_AID(mgmt) ((mgmt)->u.action.self_prot.variable + 2)
#define PLINK_GET_LLID(p) (p + 2)
#define PLINK_GET_PLID(p) (p + 4)
@@ -215,6 +215,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
enum ieee80211_self_protected_actioncode action,
u8 *da, u16 llid, u16 plid, u16 reason)
{
+ int hdr_len = IEEE80211_MIN_ACTION_SIZE(self_prot);
struct ieee80211_local *local = sdata->local;
struct sk_buff *skb;
struct ieee80211_tx_info *info;
@@ -223,7 +224,6 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
u16 peering_proto = 0;
u8 *pos, ie_len = 4;
u8 ie_len_he_cap, ie_len_eht_cap;
- int hdr_len = offsetofend(struct ieee80211_mgmt, u.action.u.self_prot);
int err = -ENOMEM;
ie_len_he_cap = ieee80211_ie_len_he_cap(sdata);
@@ -260,7 +260,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
mgmt->u.action.category = WLAN_CATEGORY_SELF_PROTECTED;
- mgmt->u.action.u.self_prot.action_code = action;
+ mgmt->u.action.action_code = action;
if (action != WLAN_SP_MESH_PEERING_CLOSE) {
struct ieee80211_supported_band *sband;
@@ -1141,7 +1141,7 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
return;
}
- ftype = mgmt->u.action.u.self_prot.action_code;
+ ftype = mgmt->u.action.action_code;
if ((ftype == WLAN_SP_MESH_PEERING_OPEN && ie_len != 4) ||
(ftype == WLAN_SP_MESH_PEERING_CONFIRM && ie_len != 6) ||
(ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len != 6
@@ -1224,8 +1224,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
size_t baselen;
u8 *baseaddr;
- /* need action_code, aux */
- if (len < IEEE80211_MIN_ACTION_SIZE + 3)
+ /* need aux */
+ if (len < IEEE80211_MIN_ACTION_SIZE(self_prot) + 1)
return;
if (sdata->u.mesh.user_mpm)
@@ -1238,10 +1238,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
return;
}
- baseaddr = mgmt->u.action.u.self_prot.variable;
- baselen = (u8 *) mgmt->u.action.u.self_prot.variable - (u8 *) mgmt;
- if (mgmt->u.action.u.self_prot.action_code ==
- WLAN_SP_MESH_PEERING_CONFIRM) {
+ baseaddr = mgmt->u.action.self_prot.variable;
+ baselen = mgmt->u.action.self_prot.variable - (u8 *)mgmt;
+ if (mgmt->u.action.action_code == WLAN_SP_MESH_PEERING_CONFIRM) {
baseaddr += 4;
baselen += 4;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index e83582b2c377..995855d49822 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -7897,7 +7897,7 @@ ieee80211_send_neg_ttlm_req(struct ieee80211_sub_if_data *sdata,
struct ieee80211_local *local = sdata->local;
struct ieee80211_mgmt *mgmt;
struct sk_buff *skb;
- int hdr_len = offsetofend(struct ieee80211_mgmt, u.action.u.ttlm_req);
+ int hdr_len = IEEE80211_MIN_ACTION_SIZE(ttlm_req);
int ttlm_max_len = 2 + 1 + sizeof(struct ieee80211_ttlm_elem) + 1 +
2 * 2 * IEEE80211_TTLM_NUM_TIDS;
@@ -7914,9 +7914,8 @@ ieee80211_send_neg_ttlm_req(struct ieee80211_sub_if_data *sdata,
memcpy(mgmt->bssid, sdata->vif.cfg.ap_addr, ETH_ALEN);
mgmt->u.action.category = WLAN_CATEGORY_PROTECTED_EHT;
- mgmt->u.action.u.ttlm_req.action_code =
- WLAN_PROTECTED_EHT_ACTION_TTLM_REQ;
- mgmt->u.action.u.ttlm_req.dialog_token = dialog_token;
+ mgmt->u.action.action_code = WLAN_PROTECTED_EHT_ACTION_TTLM_REQ;
+ mgmt->u.action.ttlm_req.dialog_token = dialog_token;
ieee80211_neg_ttlm_add_suggested_map(skb, neg_ttlm);
ieee80211_tx_skb(sdata, skb);
}
@@ -7966,7 +7965,7 @@ ieee80211_send_neg_ttlm_res(struct ieee80211_sub_if_data *sdata,
struct ieee80211_local *local = sdata->local;
struct ieee80211_mgmt *mgmt;
struct sk_buff *skb;
- int hdr_len = offsetofend(struct ieee80211_mgmt, u.action.u.ttlm_res);
+ int hdr_len = IEEE80211_MIN_ACTION_SIZE(ttlm_res);
int ttlm_max_len = 2 + 1 + sizeof(struct ieee80211_ttlm_elem) + 1 +
2 * 2 * IEEE80211_TTLM_NUM_TIDS;
u16 status_code;
@@ -7984,9 +7983,8 @@ ieee80211_send_neg_ttlm_res(struct ieee80211_sub_if_data *sdata,
memcpy(mgmt->bssid, sdata->vif.cfg.ap_addr, ETH_ALEN);
mgmt->u.action.category = WLAN_CATEGORY_PROTECTED_EHT;
- mgmt->u.action.u.ttlm_res.action_code =
- WLAN_PROTECTED_EHT_ACTION_TTLM_RES;
- mgmt->u.action.u.ttlm_res.dialog_token = dialog_token;
+ mgmt->u.action.action_code = WLAN_PROTECTED_EHT_ACTION_TTLM_RES;
+ mgmt->u.action.ttlm_res.dialog_token = dialog_token;
switch (ttlm_res) {
default:
WARN_ON(1);
@@ -8003,7 +8001,7 @@ ieee80211_send_neg_ttlm_res(struct ieee80211_sub_if_data *sdata,
break;
}
- mgmt->u.action.u.ttlm_res.status_code = cpu_to_le16(status_code);
+ mgmt->u.action.ttlm_res.status_code = cpu_to_le16(status_code);
ieee80211_tx_skb(sdata, skb);
}
@@ -8103,10 +8101,9 @@ void ieee80211_process_neg_ttlm_req(struct ieee80211_sub_if_data *sdata,
if (!ieee80211_vif_is_mld(&sdata->vif))
return;
- dialog_token = mgmt->u.action.u.ttlm_req.dialog_token;
- ies_len = len - offsetof(struct ieee80211_mgmt,
- u.action.u.ttlm_req.variable);
- elems = ieee802_11_parse_elems(mgmt->u.action.u.ttlm_req.variable,
+ dialog_token = mgmt->u.action.ttlm_req.dialog_token;
+ ies_len = len - IEEE80211_MIN_ACTION_SIZE(ttlm_req);
+ elems = ieee802_11_parse_elems(mgmt->u.action.ttlm_req.variable,
ies_len,
IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_ACTION,
@@ -8157,8 +8154,7 @@ void ieee80211_process_neg_ttlm_res(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt, size_t len)
{
if (!ieee80211_vif_is_mld(&sdata->vif) ||
- mgmt->u.action.u.ttlm_req.dialog_token !=
- sdata->u.mgd.dialog_token_alloc)
+ mgmt->u.action.ttlm_res.dialog_token != sdata->u.mgd.dialog_token_alloc)
return;
wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
@@ -8172,7 +8168,7 @@ void ieee80211_process_neg_ttlm_res(struct ieee80211_sub_if_data *sdata,
* This can be better implemented in the future, to handle request
* rejections.
*/
- if (le16_to_cpu(mgmt->u.action.u.ttlm_res.status_code) != WLAN_STATUS_SUCCESS)
+ if (le16_to_cpu(mgmt->u.action.ttlm_res.status_code) != WLAN_STATUS_SUCCESS)
__ieee80211_disconnect(sdata);
}
@@ -8205,12 +8201,11 @@ static void ieee80211_teardown_ttlm_work(struct wiphy *wiphy,
void ieee80211_send_teardown_neg_ttlm(struct ieee80211_vif *vif)
{
+ int frame_len = IEEE80211_MIN_ACTION_SIZE(ttlm_tear_down);
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
struct ieee80211_local *local = sdata->local;
struct ieee80211_mgmt *mgmt;
struct sk_buff *skb;
- int frame_len = offsetofend(struct ieee80211_mgmt,
- u.action.u.ttlm_tear_down);
struct ieee80211_tx_info *info;
skb = dev_alloc_skb(local->hw.extra_tx_headroom + frame_len);
@@ -8226,8 +8221,7 @@ void ieee80211_send_teardown_neg_ttlm(struct ieee80211_vif *vif)
memcpy(mgmt->bssid, sdata->vif.cfg.ap_addr, ETH_ALEN);
mgmt->u.action.category = WLAN_CATEGORY_PROTECTED_EHT;
- mgmt->u.action.u.ttlm_tear_down.action_code =
- WLAN_PROTECTED_EHT_ACTION_TTLM_TEARDOWN;
+ mgmt->u.action.action_code = WLAN_PROTECTED_EHT_ACTION_TTLM_TEARDOWN;
info = IEEE80211_SKB_CB(skb);
info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
@@ -8310,13 +8304,13 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
case WLAN_CATEGORY_SPECTRUM_MGMT:
ies_len = skb->len -
offsetof(struct ieee80211_mgmt,
- u.action.u.chan_switch.variable);
+ u.action.chan_switch.variable);
if (ies_len < 0)
break;
/* CSA IE cannot be overridden, no need for BSSID */
- elems = ieee802_11_parse_elems(mgmt->u.action.u.chan_switch.variable,
+ elems = ieee802_11_parse_elems(mgmt->u.action.chan_switch.variable,
ies_len,
IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_ACTION,
@@ -8338,7 +8332,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
case WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION:
ies_len = skb->len -
offsetof(struct ieee80211_mgmt,
- u.action.u.ext_chan_switch.variable);
+ u.action.ext_chan_switch.variable);
if (ies_len < 0)
break;
@@ -8347,7 +8341,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
* extended CSA IE can't be overridden, no need for
* BSSID
*/
- elems = ieee802_11_parse_elems(mgmt->u.action.u.ext_chan_switch.variable,
+ elems = ieee802_11_parse_elems(mgmt->u.action.ext_chan_switch.variable,
ies_len,
IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_ACTION,
@@ -8364,7 +8358,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
/* for the handling code pretend it was an IE */
elems->ext_chansw_ie =
- &mgmt->u.action.u.ext_chan_switch.data;
+ &mgmt->u.action.ext_chan_switch.data;
ieee80211_sta_process_chanswitch(link,
rx_status->mactime,
@@ -10356,25 +10350,25 @@ void ieee80211_process_ml_reconf_resp(struct ieee80211_sub_if_data *sdata,
u8 *pos;
if (!ieee80211_vif_is_mld(&sdata->vif) ||
- len < offsetofend(typeof(*mgmt), u.action.u.ml_reconf_resp) ||
- mgmt->u.action.u.ml_reconf_resp.dialog_token !=
- sdata->u.mgd.reconf.dialog_token ||
+ len < IEEE80211_MIN_ACTION_SIZE(ml_reconf_resp) ||
+ mgmt->u.action.ml_reconf_resp.dialog_token !=
+ sdata->u.mgd.reconf.dialog_token ||
!sta_changed_links)
return;
- pos = mgmt->u.action.u.ml_reconf_resp.variable;
- len -= offsetofend(typeof(*mgmt), u.action.u.ml_reconf_resp);
+ pos = mgmt->u.action.ml_reconf_resp.variable;
+ len -= offsetofend(typeof(*mgmt), u.action.ml_reconf_resp);
/* each status duple is 3 octets */
- if (len < mgmt->u.action.u.ml_reconf_resp.count * 3) {
+ if (len < mgmt->u.action.ml_reconf_resp.count * 3) {
sdata_info(sdata,
"mlo: reconf: unexpected len=%zu, count=%u\n",
- len, mgmt->u.action.u.ml_reconf_resp.count);
+ len, mgmt->u.action.ml_reconf_resp.count);
goto disconnect;
}
link_mask = sta_changed_links;
- for (i = 0; i < mgmt->u.action.u.ml_reconf_resp.count; i++) {
+ for (i = 0; i < mgmt->u.action.ml_reconf_resp.count; i++) {
u16 status = get_unaligned_le16(pos + 1);
link_id = *pos;
@@ -10659,8 +10653,7 @@ ieee80211_build_ml_reconf_req(struct ieee80211_sub_if_data *sdata,
return NULL;
skb_reserve(skb, local->hw.extra_tx_headroom);
- mgmt = skb_put_zero(skb, offsetofend(struct ieee80211_mgmt,
- u.action.u.ml_reconf_req));
+ mgmt = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE(ml_reconf_req));
/* Add the MAC header */
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
@@ -10671,12 +10664,11 @@ ieee80211_build_ml_reconf_req(struct ieee80211_sub_if_data *sdata,
/* Add the action frame fixed fields */
mgmt->u.action.category = WLAN_CATEGORY_PROTECTED_EHT;
- mgmt->u.action.u.ml_reconf_req.action_code =
- WLAN_PROTECTED_EHT_ACTION_LINK_RECONFIG_REQ;
+ mgmt->u.action.action_code = WLAN_PROTECTED_EHT_ACTION_LINK_RECONFIG_REQ;
/* allocate a dialog token and store it */
sdata->u.mgd.reconf.dialog_token = ++sdata->u.mgd.dialog_token_alloc;
- mgmt->u.action.u.ml_reconf_req.dialog_token =
+ mgmt->u.action.ml_reconf_req.dialog_token =
sdata->u.mgd.reconf.dialog_token;
/* Add the ML reconfiguration element and the common information */
@@ -11046,11 +11038,10 @@ static bool ieee80211_mgd_epcs_supp(struct ieee80211_sub_if_data *sdata)
int ieee80211_mgd_set_epcs(struct ieee80211_sub_if_data *sdata, bool enable)
{
+ int frame_len = IEEE80211_MIN_ACTION_SIZE(epcs) + (enable ? 1 : 0);
struct ieee80211_local *local = sdata->local;
struct ieee80211_mgmt *mgmt;
struct sk_buff *skb;
- int frame_len = offsetofend(struct ieee80211_mgmt,
- u.action.u.epcs) + (enable ? 1 : 0);
if (!ieee80211_mgd_epcs_supp(sdata))
return -EINVAL;
@@ -11079,15 +11070,15 @@ int ieee80211_mgd_set_epcs(struct ieee80211_sub_if_data *sdata, bool enable)
mgmt->u.action.category = WLAN_CATEGORY_PROTECTED_EHT;
if (enable) {
- u8 *pos = mgmt->u.action.u.epcs.variable;
+ u8 *pos = mgmt->u.action.epcs.variable;
- mgmt->u.action.u.epcs.action_code =
+ mgmt->u.action.action_code =
WLAN_PROTECTED_EHT_ACTION_EPCS_ENABLE_REQ;
*pos = ++sdata->u.mgd.dialog_token_alloc;
sdata->u.mgd.epcs.dialog_token = *pos;
} else {
- mgmt->u.action.u.epcs.action_code =
+ mgmt->u.action.action_code =
WLAN_PROTECTED_EHT_ACTION_EPCS_ENABLE_TEARDOWN;
ieee80211_epcs_teardown(sdata);
@@ -11176,7 +11167,7 @@ void ieee80211_process_epcs_ena_resp(struct ieee80211_sub_if_data *sdata,
return;
/* Handle dialog token and status code */
- pos = mgmt->u.action.u.epcs.variable;
+ pos = mgmt->u.action.epcs.variable;
dialog_token = *pos;
status_code = get_unaligned_le16(pos + 1);
@@ -11198,8 +11189,7 @@ void ieee80211_process_epcs_ena_resp(struct ieee80211_sub_if_data *sdata,
return;
pos += IEEE80211_EPCS_ENA_RESP_BODY_LEN;
- ies_len = len - offsetof(struct ieee80211_mgmt,
- u.action.u.epcs.variable) -
+ ies_len = len - IEEE80211_MIN_ACTION_SIZE(epcs) -
IEEE80211_EPCS_ENA_RESP_BODY_LEN;
elems = ieee802_11_parse_elems(pos, ies_len,
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 11d6c56c9d7e..7537ad4e1529 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -274,7 +274,7 @@ static void ieee80211_handle_mu_mimo_mon(struct ieee80211_sub_if_data *sdata,
if (!sdata)
return;
- BUILD_BUG_ON(sizeof(action) != IEEE80211_MIN_ACTION_SIZE + 1);
+ BUILD_BUG_ON(sizeof(action) != IEEE80211_MIN_ACTION_SIZE(action_code));
if (skb->len < rtap_space + sizeof(action) +
VHT_MUMIMO_GROUPS_DATA_LEN)
@@ -1162,7 +1162,7 @@ static ieee80211_rx_result ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
u8 category;
/* make sure category field is present */
- if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE)
+ if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE(category))
return RX_DROP_U_RUNT_ACTION;
mgmt = (struct ieee80211_mgmt *)hdr;
@@ -3422,7 +3422,7 @@ static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata,
return;
}
- if (len < 24 + 1 + sizeof(resp->u.action.u.sa_query)) {
+ if (len < IEEE80211_MIN_ACTION_SIZE(sa_query)) {
/* Too short SA Query request frame */
return;
}
@@ -3432,17 +3432,16 @@ static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata,
return;
skb_reserve(skb, local->hw.extra_tx_headroom);
- resp = skb_put_zero(skb, 24);
+ resp = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE(sa_query));
memcpy(resp->da, sdata->vif.cfg.ap_addr, ETH_ALEN);
memcpy(resp->sa, sdata->vif.addr, ETH_ALEN);
memcpy(resp->bssid, sdata->vif.cfg.ap_addr, ETH_ALEN);
resp->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_ACTION);
- skb_put(skb, 1 + sizeof(resp->u.action.u.sa_query));
resp->u.action.category = WLAN_CATEGORY_SA_QUERY;
- resp->u.action.u.sa_query.action = WLAN_ACTION_SA_QUERY_RESPONSE;
- memcpy(resp->u.action.u.sa_query.trans_id,
- mgmt->u.action.u.sa_query.trans_id,
+ resp->u.action.action_code = WLAN_ACTION_SA_QUERY_RESPONSE;
+ memcpy(resp->u.action.sa_query.trans_id,
+ mgmt->u.action.sa_query.trans_id,
WLAN_SA_QUERY_TR_ID_LEN);
ieee80211_tx_skb(sdata, skb);
@@ -3516,7 +3515,7 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx)
/* drop too small action frames */
if (ieee80211_is_action(mgmt->frame_control) &&
- rx->skb->len < IEEE80211_MIN_ACTION_SIZE)
+ rx->skb->len < IEEE80211_MIN_ACTION_SIZE(category))
return RX_DROP_U_RUNT_ACTION;
/* Drop non-broadcast Beacon frames */
@@ -3565,29 +3564,28 @@ ieee80211_process_rx_twt_action(struct ieee80211_rx_data *rx)
if (!rx->sta)
return false;
- switch (mgmt->u.action.u.s1g.action_code) {
+ switch (mgmt->u.action.action_code) {
case WLAN_S1G_TWT_SETUP: {
struct ieee80211_twt_setup *twt;
- if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE +
- 1 + /* action code */
+ if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE(action_code) +
sizeof(struct ieee80211_twt_setup) +
2 /* TWT req_type agrt */)
break;
- twt = (void *)mgmt->u.action.u.s1g.variable;
+ twt = (void *)mgmt->u.action.s1g.variable;
if (twt->element_id != WLAN_EID_S1G_TWT)
break;
- if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE +
- 4 + /* action code + token + tlv */
+ if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE(action_code) +
+ 3 + /* token + tlv */
twt->length)
break;
return true; /* queue the frame */
}
case WLAN_S1G_TWT_TEARDOWN:
- if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE + 2)
+ if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE(action_code) + 1)
break;
return true; /* queue the frame */
@@ -3632,10 +3630,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
break;
/* verify action & smps_control/chanwidth are present */
- if (len < IEEE80211_MIN_ACTION_SIZE + 2)
+ if (len < IEEE80211_MIN_ACTION_SIZE(ht_smps))
goto invalid;
- switch (mgmt->u.action.u.ht_smps.action) {
+ switch (mgmt->u.action.action_code) {
case WLAN_HT_ACTION_SMPS: {
struct ieee80211_supported_band *sband;
enum ieee80211_smps_mode smps_mode;
@@ -3646,7 +3644,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
goto handled;
/* convert to HT capability */
- switch (mgmt->u.action.u.ht_smps.smps_control) {
+ switch (mgmt->u.action.ht_smps.smps_control) {
case WLAN_HT_SMPS_CONTROL_DISABLED:
smps_mode = IEEE80211_SMPS_OFF;
break;
@@ -3679,7 +3677,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
goto handled;
}
case WLAN_HT_ACTION_NOTIFY_CHANWIDTH: {
- u8 chanwidth = mgmt->u.action.u.ht_notify_cw.chanwidth;
+ u8 chanwidth = mgmt->u.action.ht_notify_cw.chanwidth;
if (chanwidth != IEEE80211_HT_CHANWIDTH_20MHZ &&
chanwidth != IEEE80211_HT_CHANWIDTH_ANY)
@@ -3699,7 +3697,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
break;
case WLAN_CATEGORY_PUBLIC:
case WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION:
- if (len < IEEE80211_MIN_ACTION_SIZE + 1)
+ if (len < IEEE80211_MIN_ACTION_SIZE(action_code))
goto invalid;
if (sdata->vif.type != NL80211_IFTYPE_STATION)
break;
@@ -3707,11 +3705,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
break;
if (!ether_addr_equal(mgmt->bssid, sdata->deflink.u.mgd.bssid))
break;
- if (mgmt->u.action.u.ext_chan_switch.action_code !=
+ if (mgmt->u.action.action_code !=
WLAN_PUB_ACTION_EXT_CHANSW_ANN)
break;
- if (len < offsetof(struct ieee80211_mgmt,
- u.action.u.ext_chan_switch.variable))
+ if (len < IEEE80211_MIN_ACTION_SIZE(ext_chan_switch))
goto invalid;
goto queue;
case WLAN_CATEGORY_VHT:
@@ -3723,18 +3720,18 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
break;
/* verify action code is present */
- if (len < IEEE80211_MIN_ACTION_SIZE + 1)
+ if (len < IEEE80211_MIN_ACTION_SIZE(action_code))
goto invalid;
- switch (mgmt->u.action.u.vht_opmode_notif.action_code) {
+ switch (mgmt->u.action.action_code) {
case WLAN_VHT_ACTION_OPMODE_NOTIF: {
/* verify opmode is present */
- if (len < IEEE80211_MIN_ACTION_SIZE + 2)
+ if (len < IEEE80211_MIN_ACTION_SIZE(vht_opmode_notif))
goto invalid;
goto queue;
}
case WLAN_VHT_ACTION_GROUPID_MGMT: {
- if (len < IEEE80211_MIN_ACTION_SIZE + 25)
+ if (len < IEEE80211_MIN_ACTION_SIZE(vht_group_notif))
goto invalid;
goto queue;
}
@@ -3751,23 +3748,20 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
break;
/* verify action_code is present */
- if (len < IEEE80211_MIN_ACTION_SIZE + 1)
+ if (len < IEEE80211_MIN_ACTION_SIZE(action_code))
break;
- switch (mgmt->u.action.u.addba_req.action_code) {
+ switch (mgmt->u.action.action_code) {
case WLAN_ACTION_ADDBA_REQ:
- if (len < (IEEE80211_MIN_ACTION_SIZE +
- sizeof(mgmt->u.action.u.addba_req)))
+ if (len < IEEE80211_MIN_ACTION_SIZE(addba_req))
goto invalid;
break;
case WLAN_ACTION_ADDBA_RESP:
- if (len < (IEEE80211_MIN_ACTION_SIZE +
- sizeof(mgmt->u.action.u.addba_resp)))
+ if (len < IEEE80211_MIN_ACTION_SIZE(addba_resp))
goto invalid;
break;
case WLAN_ACTION_DELBA:
- if (len < (IEEE80211_MIN_ACTION_SIZE +
- sizeof(mgmt->u.action.u.delba)))
+ if (len < IEEE80211_MIN_ACTION_SIZE(delba))
goto invalid;
break;
default:
@@ -3777,16 +3771,15 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
goto queue;
case WLAN_CATEGORY_SPECTRUM_MGMT:
/* verify action_code is present */
- if (len < IEEE80211_MIN_ACTION_SIZE + 1)
+ if (len < IEEE80211_MIN_ACTION_SIZE(action_code))
break;
- switch (mgmt->u.action.u.measurement.action_code) {
+ switch (mgmt->u.action.action_code) {
case WLAN_ACTION_SPCT_MSR_REQ:
if (status->band != NL80211_BAND_5GHZ)
break;
- if (len < (IEEE80211_MIN_ACTION_SIZE +
- sizeof(mgmt->u.action.u.measurement)))
+ if (len < IEEE80211_MIN_ACTION_SIZE(measurement))
break;
if (sdata->vif.type != NL80211_IFTYPE_STATION)
@@ -3796,8 +3789,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
goto handled;
case WLAN_ACTION_SPCT_CHL_SWITCH: {
u8 *bssid;
- if (len < (IEEE80211_MIN_ACTION_SIZE +
- sizeof(mgmt->u.action.u.chan_switch)))
+ if (len < IEEE80211_MIN_ACTION_SIZE(chan_switch))
break;
if (sdata->vif.type != NL80211_IFTYPE_STATION &&
@@ -3822,11 +3814,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
}
break;
case WLAN_CATEGORY_SELF_PROTECTED:
- if (len < (IEEE80211_MIN_ACTION_SIZE +
- sizeof(mgmt->u.action.u.self_prot.action_code)))
+ if (len < IEEE80211_MIN_ACTION_SIZE(self_prot))
break;
- switch (mgmt->u.action.u.self_prot.action_code) {
+ switch (mgmt->u.action.action_code) {
case WLAN_SP_MESH_PEERING_OPEN:
case WLAN_SP_MESH_PEERING_CLOSE:
case WLAN_SP_MESH_PEERING_CONFIRM:
@@ -3844,8 +3835,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
}
break;
case WLAN_CATEGORY_MESH_ACTION:
- if (len < (IEEE80211_MIN_ACTION_SIZE +
- sizeof(mgmt->u.action.u.mesh_action.action_code)))
+ if (len < IEEE80211_MIN_ACTION_SIZE(action_code))
break;
if (!ieee80211_vif_is_mesh(&sdata->vif))
@@ -3855,11 +3845,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
break;
goto queue;
case WLAN_CATEGORY_S1G:
- if (len < offsetofend(typeof(*mgmt),
- u.action.u.s1g.action_code))
+ if (len < IEEE80211_MIN_ACTION_SIZE(action_code))
break;
- switch (mgmt->u.action.u.s1g.action_code) {
+ switch (mgmt->u.action.action_code) {
case WLAN_S1G_TWT_SETUP:
case WLAN_S1G_TWT_TEARDOWN:
if (ieee80211_process_rx_twt_action(rx))
@@ -3870,33 +3859,29 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
}
break;
case WLAN_CATEGORY_PROTECTED_EHT:
- if (len < offsetofend(typeof(*mgmt),
- u.action.u.ttlm_req.action_code))
+ if (len < IEEE80211_MIN_ACTION_SIZE(action_code))
break;
- switch (mgmt->u.action.u.ttlm_req.action_code) {
+ switch (mgmt->u.action.action_code) {
case WLAN_PROTECTED_EHT_ACTION_TTLM_REQ:
if (sdata->vif.type != NL80211_IFTYPE_STATION)
break;
- if (len < offsetofend(typeof(*mgmt),
- u.action.u.ttlm_req))
+ if (len < IEEE80211_MIN_ACTION_SIZE(ttlm_req))
goto invalid;
goto queue;
case WLAN_PROTECTED_EHT_ACTION_TTLM_RES:
if (sdata->vif.type != NL80211_IFTYPE_STATION)
break;
- if (len < offsetofend(typeof(*mgmt),
- u.action.u.ttlm_res))
+ if (len < IEEE80211_MIN_ACTION_SIZE(ttlm_res))
goto invalid;
goto queue;
case WLAN_PROTECTED_EHT_ACTION_TTLM_TEARDOWN:
if (sdata->vif.type != NL80211_IFTYPE_STATION)
break;
- if (len < offsetofend(typeof(*mgmt),
- u.action.u.ttlm_tear_down))
+ if (len < IEEE80211_MIN_ACTION_SIZE(ttlm_tear_down))
goto invalid;
goto queue;
case WLAN_PROTECTED_EHT_ACTION_LINK_RECONFIG_RESP:
@@ -3906,34 +3891,29 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
/* The reconfiguration response action frame must
* least one 'Status Duple' entry (3 octets)
*/
- if (len <
- offsetofend(typeof(*mgmt),
- u.action.u.ml_reconf_resp) + 3)
+ if (len < IEEE80211_MIN_ACTION_SIZE(ml_reconf_resp) + 3)
goto invalid;
goto queue;
case WLAN_PROTECTED_EHT_ACTION_EPCS_ENABLE_RESP:
if (sdata->vif.type != NL80211_IFTYPE_STATION)
break;
- if (len < offsetofend(typeof(*mgmt),
- u.action.u.epcs) +
- IEEE80211_EPCS_ENA_RESP_BODY_LEN)
+ if (len < IEEE80211_MIN_ACTION_SIZE(epcs) +
+ IEEE80211_EPCS_ENA_RESP_BODY_LEN)
goto invalid;
goto queue;
case WLAN_PROTECTED_EHT_ACTION_EPCS_ENABLE_TEARDOWN:
if (sdata->vif.type != NL80211_IFTYPE_STATION)
break;
- if (len < offsetofend(typeof(*mgmt),
- u.action.u.epcs))
+ if (len < IEEE80211_MIN_ACTION_SIZE(epcs))
goto invalid;
goto queue;
case WLAN_PROTECTED_EHT_ACTION_EML_OP_MODE_NOTIF:
if (sdata->vif.type != NL80211_IFTYPE_AP)
break;
- if (len < offsetofend(typeof(*mgmt),
- u.action.u.eml_omn))
+ if (len < IEEE80211_MIN_ACTION_SIZE(eml_omn))
goto invalid;
goto queue;
default:
@@ -4015,11 +3995,10 @@ ieee80211_rx_h_action_post_userspace(struct ieee80211_rx_data *rx)
switch (mgmt->u.action.category) {
case WLAN_CATEGORY_SA_QUERY:
- if (len < (IEEE80211_MIN_ACTION_SIZE +
- sizeof(mgmt->u.action.u.sa_query)))
+ if (len < IEEE80211_MIN_ACTION_SIZE(sa_query))
break;
- switch (mgmt->u.action.u.sa_query.action) {
+ switch (mgmt->u.action.action_code) {
case WLAN_ACTION_SA_QUERY_REQUEST:
if (sdata->vif.type != NL80211_IFTYPE_STATION)
break;
diff --git a/net/mac80211/s1g.c b/net/mac80211/s1g.c
index 1f68df6e8067..297abaa6fecf 100644
--- a/net/mac80211/s1g.c
+++ b/net/mac80211/s1g.c
@@ -2,7 +2,7 @@
/*
* S1G handling
* Copyright(c) 2020 Adapt-IP
- * Copyright (C) 2023 Intel Corporation
+ * Copyright (C) 2023, 2026 Intel Corporation
*/
#include <linux/ieee80211.h>
#include <net/mac80211.h>
@@ -27,14 +27,14 @@ bool ieee80211_s1g_is_twt_setup(struct sk_buff *skb)
if (likely(mgmt->u.action.category != WLAN_CATEGORY_S1G))
return false;
- return mgmt->u.action.u.s1g.action_code == WLAN_S1G_TWT_SETUP;
+ return mgmt->u.action.action_code == WLAN_S1G_TWT_SETUP;
}
static void
ieee80211_s1g_send_twt_setup(struct ieee80211_sub_if_data *sdata, const u8 *da,
const u8 *bssid, struct ieee80211_twt_setup *twt)
{
- int len = IEEE80211_MIN_ACTION_SIZE + 4 + twt->length;
+ int len = IEEE80211_MIN_ACTION_SIZE(s1g) + 3 + twt->length;
struct ieee80211_local *local = sdata->local;
struct ieee80211_mgmt *mgmt;
struct sk_buff *skb;
@@ -52,8 +52,8 @@ ieee80211_s1g_send_twt_setup(struct ieee80211_sub_if_data *sdata, const u8 *da,
memcpy(mgmt->bssid, bssid, ETH_ALEN);
mgmt->u.action.category = WLAN_CATEGORY_S1G;
- mgmt->u.action.u.s1g.action_code = WLAN_S1G_TWT_SETUP;
- memcpy(mgmt->u.action.u.s1g.variable, twt, 3 + twt->length);
+ mgmt->u.action.action_code = WLAN_S1G_TWT_SETUP;
+ memcpy(mgmt->u.action.s1g.variable, twt, 3 + twt->length);
IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
IEEE80211_TX_INTFL_MLME_CONN_TX |
@@ -71,12 +71,12 @@ ieee80211_s1g_send_twt_teardown(struct ieee80211_sub_if_data *sdata,
u8 *id;
skb = dev_alloc_skb(local->hw.extra_tx_headroom +
- IEEE80211_MIN_ACTION_SIZE + 2);
+ IEEE80211_MIN_ACTION_SIZE(s1g) + 1);
if (!skb)
return;
skb_reserve(skb, local->hw.extra_tx_headroom);
- mgmt = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE + 2);
+ mgmt = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE(s1g) + 1);
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_ACTION);
memcpy(mgmt->da, da, ETH_ALEN);
@@ -84,8 +84,8 @@ ieee80211_s1g_send_twt_teardown(struct ieee80211_sub_if_data *sdata,
memcpy(mgmt->bssid, bssid, ETH_ALEN);
mgmt->u.action.category = WLAN_CATEGORY_S1G;
- mgmt->u.action.u.s1g.action_code = WLAN_S1G_TWT_TEARDOWN;
- id = (u8 *)mgmt->u.action.u.s1g.variable;
+ mgmt->u.action.action_code = WLAN_S1G_TWT_TEARDOWN;
+ id = (u8 *)mgmt->u.action.s1g.variable;
*id = flowid;
IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
@@ -98,7 +98,7 @@ ieee80211_s1g_rx_twt_setup(struct ieee80211_sub_if_data *sdata,
struct sta_info *sta, struct sk_buff *skb)
{
struct ieee80211_mgmt *mgmt = (void *)skb->data;
- struct ieee80211_twt_setup *twt = (void *)mgmt->u.action.u.s1g.variable;
+ struct ieee80211_twt_setup *twt = (void *)mgmt->u.action.s1g.variable;
struct ieee80211_twt_params *twt_agrt = (void *)twt->params;
twt_agrt->req_type &= cpu_to_le16(~IEEE80211_TWT_REQTYPE_REQUEST);
@@ -128,7 +128,7 @@ ieee80211_s1g_rx_twt_teardown(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
drv_twt_teardown_request(sdata->local, sdata, &sta->sta,
- mgmt->u.action.u.s1g.variable[0]);
+ mgmt->u.action.s1g.variable[0]);
}
static void
@@ -136,7 +136,7 @@ ieee80211_s1g_tx_twt_setup_fail(struct ieee80211_sub_if_data *sdata,
struct sta_info *sta, struct sk_buff *skb)
{
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
- struct ieee80211_twt_setup *twt = (void *)mgmt->u.action.u.s1g.variable;
+ struct ieee80211_twt_setup *twt = (void *)mgmt->u.action.s1g.variable;
struct ieee80211_twt_params *twt_agrt = (void *)twt->params;
u8 flowid = le16_get_bits(twt_agrt->req_type,
IEEE80211_TWT_REQTYPE_FLOWID);
@@ -160,7 +160,7 @@ void ieee80211_s1g_rx_twt_action(struct ieee80211_sub_if_data *sdata,
if (!sta)
return;
- switch (mgmt->u.action.u.s1g.action_code) {
+ switch (mgmt->u.action.action_code) {
case WLAN_S1G_TWT_SETUP:
ieee80211_s1g_rx_twt_setup(sdata, sta, skb);
break;
@@ -185,7 +185,7 @@ void ieee80211_s1g_status_twt_action(struct ieee80211_sub_if_data *sdata,
if (!sta)
return;
- switch (mgmt->u.action.u.s1g.action_code) {
+ switch (mgmt->u.action.action_code) {
case WLAN_S1G_TWT_SETUP:
/* process failed twt setup frames */
ieee80211_s1g_tx_twt_setup_fail(sdata, sta, skb);
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c
index 7422888d3640..e2eaf8d8d7ff 100644
--- a/net/mac80211/spectmgmt.c
+++ b/net/mac80211/spectmgmt.c
@@ -9,7 +9,7 @@
* Copyright 2007, Michael Wu <flamingice@sourmilk.net>
* Copyright 2007-2008, Intel Corporation
* Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- * Copyright (C) 2018, 2020, 2022-2024 Intel Corporation
+ * Copyright (C) 2018, 2020, 2022-2024, 2026 Intel Corporation
*/
#include <linux/ieee80211.h>
@@ -409,35 +409,30 @@ static void ieee80211_send_refuse_measurement_request(struct ieee80211_sub_if_da
struct sk_buff *skb;
struct ieee80211_mgmt *msr_report;
- skb = dev_alloc_skb(sizeof(*msr_report) + local->hw.extra_tx_headroom +
- sizeof(struct ieee80211_msrment_ie));
+ skb = dev_alloc_skb(IEEE80211_MIN_ACTION_SIZE(measurement) +
+ local->hw.extra_tx_headroom);
if (!skb)
return;
skb_reserve(skb, local->hw.extra_tx_headroom);
- msr_report = skb_put_zero(skb, 24);
+ msr_report = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE(measurement));
memcpy(msr_report->da, da, ETH_ALEN);
memcpy(msr_report->sa, sdata->vif.addr, ETH_ALEN);
memcpy(msr_report->bssid, bssid, ETH_ALEN);
msr_report->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_ACTION);
- skb_put(skb, 1 + sizeof(msr_report->u.action.u.measurement));
msr_report->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT;
- msr_report->u.action.u.measurement.action_code =
- WLAN_ACTION_SPCT_MSR_RPRT;
- msr_report->u.action.u.measurement.dialog_token = dialog_token;
+ msr_report->u.action.action_code = WLAN_ACTION_SPCT_MSR_RPRT;
- msr_report->u.action.u.measurement.element_id = WLAN_EID_MEASURE_REPORT;
- msr_report->u.action.u.measurement.length =
+ msr_report->u.action.measurement.dialog_token = dialog_token;
+ msr_report->u.action.measurement.element_id = WLAN_EID_MEASURE_REPORT;
+ msr_report->u.action.measurement.length =
sizeof(struct ieee80211_msrment_ie);
-
- memset(&msr_report->u.action.u.measurement.msr_elem, 0,
- sizeof(struct ieee80211_msrment_ie));
- msr_report->u.action.u.measurement.msr_elem.token = request_ie->token;
- msr_report->u.action.u.measurement.msr_elem.mode |=
+ msr_report->u.action.measurement.msr_elem.token = request_ie->token;
+ msr_report->u.action.measurement.msr_elem.mode |=
IEEE80211_SPCT_MSR_RPRT_MODE_REFUSED;
- msr_report->u.action.u.measurement.msr_elem.type = request_ie->type;
+ msr_report->u.action.measurement.msr_elem.type = request_ie->type;
ieee80211_tx_skb(sdata, skb);
}
@@ -454,7 +449,7 @@ void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
* TODO: Answer basic measurement as unmeasured
*/
ieee80211_send_refuse_measurement_request(sdata,
- &mgmt->u.action.u.measurement.msr_elem,
+ &mgmt->u.action.measurement.msr_elem,
mgmt->sa, mgmt->bssid,
- mgmt->u.action.u.measurement.dialog_token);
+ mgmt->u.action.measurement.dialog_token);
}
diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c
index dbbfe2d6842f..1f30a4eda374 100644
--- a/net/mac80211/tdls.c
+++ b/net/mac80211/tdls.c
@@ -6,7 +6,7 @@
* Copyright 2014, Intel Corporation
* Copyright 2014 Intel Mobile Communications GmbH
* Copyright 2015 - 2016 Intel Deutschland GmbH
- * Copyright (C) 2019, 2021-2025 Intel Corporation
+ * Copyright (C) 2019, 2021-2026 Intel Corporation
*/
#include <linux/ieee80211.h>
@@ -879,28 +879,23 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_mgmt *mgmt;
- mgmt = skb_put_zero(skb, 24);
+ if (action_code != WLAN_PUB_ACTION_TDLS_DISCOVER_RES)
+ return -EINVAL;
+
+ mgmt = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE(tdls_discover_resp));
memcpy(mgmt->da, peer, ETH_ALEN);
memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
memcpy(mgmt->bssid, link->u.mgd.bssid, ETH_ALEN);
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_ACTION);
- switch (action_code) {
- case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
- skb_put(skb, 1 + sizeof(mgmt->u.action.u.tdls_discover_resp));
- mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
- mgmt->u.action.u.tdls_discover_resp.action_code =
- WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
- mgmt->u.action.u.tdls_discover_resp.dialog_token =
- dialog_token;
- mgmt->u.action.u.tdls_discover_resp.capability =
- cpu_to_le16(ieee80211_get_tdls_sta_capab(link,
- status_code));
- break;
- default:
- return -EINVAL;
- }
+ mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
+ mgmt->u.action.action_code = WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
+
+ mgmt->u.action.tdls_discover_resp.dialog_token = dialog_token;
+ mgmt->u.action.tdls_discover_resp.capability =
+ cpu_to_le16(ieee80211_get_tdls_sta_capab(link,
+ status_code));
return 0;
}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index a5e09c0fa6b3..f44d9cb35b0e 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -3768,12 +3768,11 @@ void ieee80211_chandef_downgrade(struct cfg80211_chan_def *c,
int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
struct cfg80211_csa_settings *csa_settings)
{
+ int hdr_len = IEEE80211_MIN_ACTION_SIZE(chan_switch);
struct sk_buff *skb;
struct ieee80211_mgmt *mgmt;
struct ieee80211_local *local = sdata->local;
int freq;
- int hdr_len = offsetofend(struct ieee80211_mgmt,
- u.action.u.chan_switch);
u8 *pos;
if (sdata->vif.type != NL80211_IFTYPE_ADHOC &&
@@ -3802,7 +3801,7 @@ int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN);
}
mgmt->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT;
- mgmt->u.action.u.chan_switch.action_code = WLAN_ACTION_SPCT_CHL_SWITCH;
+ mgmt->u.action.action_code = WLAN_ACTION_SPCT_CHL_SWITCH;
pos = skb_put(skb, 5);
*pos++ = WLAN_EID_CHANNEL_SWITCH; /* EID */
*pos++ = 3; /* IE length */
diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c
index b099d79e8fbb..80120f9f17b6 100644
--- a/net/mac80211/vht.c
+++ b/net/mac80211/vht.c
@@ -4,7 +4,7 @@
*
* Portions of this file
* Copyright(c) 2015 - 2016 Intel Deutschland GmbH
- * Copyright (C) 2018 - 2024 Intel Corporation
+ * Copyright (C) 2018-2026 Intel Corporation
*/
#include <linux/ieee80211.h>
@@ -723,17 +723,17 @@ void ieee80211_process_mu_groups(struct ieee80211_sub_if_data *sdata,
if (!link_conf->mu_mimo_owner)
return;
- if (!memcmp(mgmt->u.action.u.vht_group_notif.position,
+ if (!memcmp(mgmt->u.action.vht_group_notif.position,
link_conf->mu_group.position, WLAN_USER_POSITION_LEN) &&
- !memcmp(mgmt->u.action.u.vht_group_notif.membership,
+ !memcmp(mgmt->u.action.vht_group_notif.membership,
link_conf->mu_group.membership, WLAN_MEMBERSHIP_LEN))
return;
memcpy(link_conf->mu_group.membership,
- mgmt->u.action.u.vht_group_notif.membership,
+ mgmt->u.action.vht_group_notif.membership,
WLAN_MEMBERSHIP_LEN);
memcpy(link_conf->mu_group.position,
- mgmt->u.action.u.vht_group_notif.position,
+ mgmt->u.action.vht_group_notif.position,
WLAN_USER_POSITION_LEN);
ieee80211_link_info_change_notify(sdata, link,
--
2.53.0
^ permalink raw reply related
* [PATCH wireless-next v2 0/5] wifi: cfg80211/mac80211: Add support for IEEE 802.1X Authentication Protocol
From: Kavita Kavita @ 2026-02-26 18:55 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, kavita.kavita
Add support for the new IEEE 802.1X authentication protocol using
Authentication frames, both without (Re)Association frame encryption
as specified in "IEEE P802.11bi/D4.0, 12.16.5" and with
(Re)Association frame encryption as specified in
"IEEE P802.11bi/D4.0, 12.16.8.2".
This patch series introduces the required changes for non-AP STA mode.
For the AP mode, no additional changes are required for this
functionality. These patches have been tested end-to-end using the
Hwsim test tool.
Note: The patches apply cleanly and do not introduce any build issues
on their own. However, IEEE 802.1X Authentication depends on the
below mentioned functional dependency. Without it, the feature will
not work correctly, even though the series itself builds independently.
Functional dependencies:
- [PATCH wireless-next v4] wifi: mac80211: Fix AAD/Nonce computation
for management frames with MLO
Link: https://lore.kernel.org/linux-wireless/20260226042959.3766157-1-sai.magam@oss.qualcomm.com/T/#u
The functional dependency is still under review, and until it is
merged, this series will not be fully functional.
---
Changes in v2:
- Included two new patches for EPPKE/(Re)Association frame
encryption support, as requested.
- Updated the existing IEEE 802.1X patch to advertise support
directly in mac80211 instead of mac80211_hwsim.
---
Kavita Kavita (5):
wifi: mac80211_hwsim: Advertise support for (Re)Association frame
encryption
wifi: mac80211: Advertise EPPKE support based on driver capabilities
wifi: cfg80211: add support for IEEE 802.1X Authentication Protocol
wifi: mac80211: Add support for IEEE 802.1X authentication protocol in
non-AP STA mode
wifi: mac80211: Advertise IEEE 802.1X authentication support
drivers/net/wireless/virtual/mac80211_hwsim.c | 2 +
include/linux/ieee80211.h | 2 +
include/uapi/linux/nl80211.h | 9 +++
net/mac80211/main.c | 10 +++
net/mac80211/mlme.c | 78 +++++++++++++++++--
net/wireless/nl80211.c | 14 +++-
6 files changed, 107 insertions(+), 8 deletions(-)
base-commit: 8bf22c33e7a172fbc72464f4cc484d23a6b412ba
--
2.34.1
^ permalink raw reply
* [PATCH wireless-next v2 1/5] wifi: mac80211_hwsim: Advertise support for (Re)Association frame encryption
From: Kavita Kavita @ 2026-02-26 18:55 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, kavita.kavita
In-Reply-To: <20260226185553.1516290-1-kavita.kavita@oss.qualcomm.com>
Advertise support for (Re)Association frame encryption in mac80211_hwsim
for testing scenarios.
Signed-off-by: Kavita Kavita <kavita.kavita@oss.qualcomm.com>
---
drivers/net/wireless/virtual/mac80211_hwsim.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c
index 4d9f5f87e814..35f6266acf4b 100644
--- a/drivers/net/wireless/virtual/mac80211_hwsim.c
+++ b/drivers/net/wireless/virtual/mac80211_hwsim.c
@@ -5639,6 +5639,8 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT);
wiphy_ext_feature_set(hw->wiphy,
NL80211_EXT_FEATURE_BSS_COLOR);
+ wiphy_ext_feature_set(hw->wiphy,
+ NL80211_EXT_FEATURE_ASSOC_FRAME_ENCRYPTION);
hw->wiphy->interface_modes = param->iftypes;
--
2.34.1
^ permalink raw reply related
* [PATCH wireless-next v2 2/5] wifi: mac80211: Advertise EPPKE support based on driver capabilities
From: Kavita Kavita @ 2026-02-26 18:55 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, kavita.kavita
In-Reply-To: <20260226185553.1516290-1-kavita.kavita@oss.qualcomm.com>
Advertise support for Enhanced Privacy Protection Key Exchange (EPPKE)
authentication protocol in mac80211 when the driver supports
(Re)Association frame encryption. Since EPPKE mandates (Re)Association
frame encryption.
Signed-off-by: Kavita Kavita <kavita.kavita@oss.qualcomm.com>
---
net/mac80211/main.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index bedc81956fbc..93af2f58d7f7 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1598,6 +1598,15 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
local->sband_allocated |= BIT(band);
}
+ /*
+ * mac80211 supports EPPKE, if the driver supports (Re)Association
+ * frame encryption
+ */
+ if (wiphy_ext_feature_isset(local->hw.wiphy,
+ NL80211_EXT_FEATURE_ASSOC_FRAME_ENCRYPTION))
+ wiphy_ext_feature_set(local->hw.wiphy,
+ NL80211_EXT_FEATURE_EPPKE);
+
result = wiphy_register(local->hw.wiphy);
if (result < 0)
goto fail_wiphy_register;
--
2.34.1
^ permalink raw reply related
* [PATCH wireless-next v2 3/5] wifi: cfg80211: add support for IEEE 802.1X Authentication Protocol
From: Kavita Kavita @ 2026-02-26 18:55 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, kavita.kavita
In-Reply-To: <20260226185553.1516290-1-kavita.kavita@oss.qualcomm.com>
Add an extended feature flag NL80211_EXT_FEATURE_IEEE8021X_AUTH to
allow a driver to indicate support for the IEEE 802.1X authentication
protocol in non-AP STA mode, as defined in
"IEEE P802.11bi/D4.0, 12.16.5".
In case of SME in userspace, the Authentication frame body is prepared
in userspace while the driver finalizes the Authentication frame once
it receives the required fields and elements. The driver indicates
support for IEEE 802.1X authentication using the extended feature flag
so that userspace can initiate IEEE 802.1X authentication.
When the feature flag is set, process IEEE 802.1X Authentication frames
from userspace in non-AP STA mode. If the flag is not set, reject
IEEE 802.1X Authentication frames.
Define a new authentication type NL80211_AUTHTYPE_IEEE8021X for
IEEE 802.1X authentication.
Signed-off-by: Kavita Kavita <kavita.kavita@oss.qualcomm.com>
---
include/linux/ieee80211.h | 1 +
include/uapi/linux/nl80211.h | 9 +++++++++
net/wireless/nl80211.c | 14 ++++++++++++--
3 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 0aa2fb8f88de..1bf806f85372 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1358,6 +1358,7 @@ struct ieee80211_tdls_data {
#define WLAN_AUTH_FILS_SK 4
#define WLAN_AUTH_FILS_SK_PFS 5
#define WLAN_AUTH_FILS_PK 6
+#define WLAN_AUTH_IEEE8021X 8
#define WLAN_AUTH_EPPKE 9
#define WLAN_AUTH_LEAP 128
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index b63f71850906..6802e6884800 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -5466,6 +5466,8 @@ enum nl80211_bss_status {
* @NL80211_AUTHTYPE_FILS_SK_PFS: Fast Initial Link Setup shared key with PFS
* @NL80211_AUTHTYPE_FILS_PK: Fast Initial Link Setup public key
* @NL80211_AUTHTYPE_EPPKE: Enhanced Privacy Protection Key Exchange
+ * @NL80211_AUTHTYPE_IEEE8021X: IEEE 802.1X authentication utilizing
+ * Authentication frames
* @__NL80211_AUTHTYPE_NUM: internal
* @NL80211_AUTHTYPE_MAX: maximum valid auth algorithm
* @NL80211_AUTHTYPE_AUTOMATIC: determine automatically (if necessary by
@@ -5482,6 +5484,7 @@ enum nl80211_auth_type {
NL80211_AUTHTYPE_FILS_SK_PFS,
NL80211_AUTHTYPE_FILS_PK,
NL80211_AUTHTYPE_EPPKE,
+ NL80211_AUTHTYPE_IEEE8021X,
/* keep last */
__NL80211_AUTHTYPE_NUM,
@@ -6795,6 +6798,11 @@ enum nl80211_feature_flags {
* frames in both non‑AP STA and AP mode as specified in
* "IEEE P802.11bi/D3.0, 12.16.6".
*
+ * @NL80211_EXT_FEATURE_IEEE8021X_AUTH: Driver supports IEEE 802.1X
+ * authentication utilizing Authentication frames with user space SME
+ * (NL80211_CMD_AUTHENTICATE) in non-AP STA mode, as specified in
+ * "IEEE P802.11bi/D4.0, 12.16.5".
+ *
* @NUM_NL80211_EXT_FEATURES: number of extended features.
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
*/
@@ -6873,6 +6881,7 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_BEACON_RATE_EHT,
NL80211_EXT_FEATURE_EPPKE,
NL80211_EXT_FEATURE_ASSOC_FRAME_ENCRYPTION,
+ NL80211_EXT_FEATURE_IEEE8021X_AUTH,
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 6e58b238a1f8..3258ef2e3631 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -6542,6 +6542,10 @@ static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev,
NL80211_EXT_FEATURE_EPPKE) &&
auth_type == NL80211_AUTHTYPE_EPPKE)
return false;
+ if (!wiphy_ext_feature_isset(&rdev->wiphy,
+ NL80211_EXT_FEATURE_IEEE8021X_AUTH) &&
+ auth_type == NL80211_AUTHTYPE_IEEE8021X)
+ return false;
return true;
case NL80211_CMD_CONNECT:
if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
@@ -6563,6 +6567,10 @@ static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev,
NL80211_EXT_FEATURE_EPPKE) &&
auth_type == NL80211_AUTHTYPE_EPPKE)
return false;
+ if (!wiphy_ext_feature_isset(&rdev->wiphy,
+ NL80211_EXT_FEATURE_IEEE8021X_AUTH) &&
+ auth_type == NL80211_AUTHTYPE_IEEE8021X)
+ return false;
return true;
case NL80211_CMD_START_AP:
if (!wiphy_ext_feature_isset(&rdev->wiphy,
@@ -12077,7 +12085,8 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
auth_type == NL80211_AUTHTYPE_FILS_SK ||
auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
auth_type == NL80211_AUTHTYPE_FILS_PK ||
- auth_type == NL80211_AUTHTYPE_EPPKE) &&
+ auth_type == NL80211_AUTHTYPE_EPPKE ||
+ auth_type == NL80211_AUTHTYPE_IEEE8021X) &&
!info->attrs[NL80211_ATTR_AUTH_DATA])
return -EINVAL;
@@ -12086,7 +12095,8 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
auth_type != NL80211_AUTHTYPE_FILS_SK &&
auth_type != NL80211_AUTHTYPE_FILS_SK_PFS &&
auth_type != NL80211_AUTHTYPE_FILS_PK &&
- auth_type != NL80211_AUTHTYPE_EPPKE)
+ auth_type != NL80211_AUTHTYPE_EPPKE &&
+ auth_type != NL80211_AUTHTYPE_IEEE8021X)
return -EINVAL;
req.auth_data = nla_data(info->attrs[NL80211_ATTR_AUTH_DATA]);
req.auth_data_len = nla_len(info->attrs[NL80211_ATTR_AUTH_DATA]);
--
2.34.1
^ permalink raw reply related
* [PATCH wireless-next v2 4/5] wifi: mac80211: Add support for IEEE 802.1X authentication protocol in non-AP STA mode
From: Kavita Kavita @ 2026-02-26 18:55 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, kavita.kavita
In-Reply-To: <20260226185553.1516290-1-kavita.kavita@oss.qualcomm.com>
Add support for the IEEE 802.1X authentication protocol in non-AP STA
mode, as specified in "IEEE P802.11bi/D4.0, 12.16.5".
IEEE 802.1X authentication involves multiple Authentication frame
exchanges, with the non-AP STA and AP alternating transaction
sequence numbers. The number of Authentication frame exchanges
depends on the EAP method in use. For IEEE 802.1X authentication,
process only Authentication frames with the expected transaction
sequence number.
For IEEE 802.1X Authentication, Table 9-71 specifies that the
Encapsulation Length field as specified in Clause 9.4.1.82 shall be
present in all IEEE 802.1X Authentication frames. Drop the frame in
the mac80211 if the Encapsulation Length field is missing.
After receiving the final Authentication frame with status code
WLAN_STATUS_8021X_AUTH_SUCCESS from the AP, mac80211 marks the state
as authenticated, as it indicates the EAP handshake has completed
successfully over the Authentication frames as specified in
Clause 12.16.5.
In the PMKSA caching case, only two Authentication frames are
exchanged if the AP identifies a valid PMKSA, then as specified
in Clause 12.16.8.3, the AP shall set the Status Code to
WLAN_STATUS_SUCCESS in the final Authentication frame and must not
include an encapsulated EAPOL PDU. This frame will be the final
Authentication frame from the AP when PMKSA caching is enabled,
and mac80211 marks the state as authenticated.
In case of authentication success or failure, forward the
Authentication frame to userspace(e.g. wpa_supplicant), and let
userspace validate the Authentication frame from the AP as per the
specification.
Signed-off-by: Kavita Kavita <kavita.kavita@oss.qualcomm.com>
---
include/linux/ieee80211.h | 1 +
net/mac80211/mlme.c | 78 ++++++++++++++++++++++++++++++++++++---
2 files changed, 73 insertions(+), 6 deletions(-)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 1bf806f85372..3651b2e6c518 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1508,6 +1508,7 @@ enum ieee80211_statuscode {
WLAN_STATUS_SAE_PK = 127,
WLAN_STATUS_DENIED_TID_TO_LINK_MAPPING = 133,
WLAN_STATUS_PREF_TID_TO_LINK_MAPPING_SUGGESTED = 134,
+ WLAN_STATUS_8021X_AUTH_SUCCESS = 153,
};
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index e83582b2c377..a073451b0c94 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -4920,7 +4920,7 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt, size_t len)
{
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
- u16 auth_alg, auth_transaction, status_code;
+ u16 auth_alg, auth_transaction, status_code, encap_len;
struct ieee80211_event event = {
.type = MLME_EVENT,
.u.mlme.data = AUTH_EVENT,
@@ -4929,6 +4929,7 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
.subtype = IEEE80211_STYPE_AUTH,
};
bool sae_need_confirm = false;
+ bool auth_fail = false;
lockdep_assert_wiphy(sdata->local->hw.wiphy);
@@ -4945,6 +4946,15 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
status_code = le16_to_cpu(mgmt->u.auth.status_code);
+ /*
+ * IEEE 802.1X Authentication:
+ * Header + Authentication Algorithm Number(2 byte) + Authentication
+ * Transaction Sequence Number(2 byte) + Status Code(2 byte) +
+ * Encapsulation Length(2 byte).
+ */
+ if (auth_alg == WLAN_AUTH_IEEE8021X && len < 24 + 8)
+ return;
+
info.link_id = ifmgd->auth_data->link_id;
if (auth_alg != ifmgd->auth_data->algorithm ||
@@ -4960,7 +4970,24 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
goto notify_driver;
}
- if (status_code != WLAN_STATUS_SUCCESS) {
+ switch (auth_alg) {
+ case WLAN_AUTH_IEEE8021X:
+ if (status_code != WLAN_STATUS_SUCCESS &&
+ status_code != WLAN_STATUS_8021X_AUTH_SUCCESS)
+ auth_fail = true;
+
+ if (!auth_fail) {
+ /* Indicates length of encapsulated EAPOL PDU */
+ encap_len = get_unaligned_le16(mgmt->u.auth.variable);
+ }
+ break;
+ default:
+ if (status_code != WLAN_STATUS_SUCCESS)
+ auth_fail = true;
+ break;
+ }
+
+ if (auth_fail) {
cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len);
if (auth_alg == WLAN_AUTH_SAE &&
@@ -4997,6 +5024,7 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
case WLAN_AUTH_FILS_SK_PFS:
case WLAN_AUTH_FILS_PK:
case WLAN_AUTH_EPPKE:
+ case WLAN_AUTH_IEEE8021X:
break;
case WLAN_AUTH_SHARED_KEY:
if (ifmgd->auth_data->expected_transaction != 4) {
@@ -5017,8 +5045,37 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
if (ifmgd->auth_data->algorithm != WLAN_AUTH_SAE ||
(auth_transaction == 2 &&
ifmgd->auth_data->expected_transaction == 2)) {
- if (!ieee80211_mark_sta_auth(sdata))
- return; /* ignore frame -- wait for timeout */
+ switch (ifmgd->auth_data->algorithm) {
+ case WLAN_AUTH_IEEE8021X:
+ /*
+ * IEEE 802.1X authentication:
+ * - When the full EAP handshake completes over the
+ * Authentication process, the responder sets the
+ * Status Code to WLAN_STATUS_8021X_AUTH_SUCCESS as
+ * specified in "IEEE P802.11bi/D4.0, 12.16.5".
+ *
+ * - In the PMKSA caching case, only two Authentication
+ * frames are exchanged if the responder (e.g., AP)
+ * identifies a valid PMKSA, then as specified in
+ * "IEEE P802.11bi/D4.0, 12.16.8.3", the responder
+ * shall set the Status Code to SUCCESS in the final
+ * Authentication frame and must not include an
+ * encapsulated EAPOL PDU.
+ *
+ * Both conditions are treated as successful
+ * authentication, so mark the state to Authenticated.
+ */
+ if (status_code != WLAN_STATUS_8021X_AUTH_SUCCESS &&
+ !(status_code == WLAN_STATUS_SUCCESS &&
+ encap_len == 0))
+ break;
+ fallthrough;
+ default:
+ if (!ieee80211_mark_sta_auth(sdata))
+ return; /* ignore frame -- wait for timeout */
+
+ break;
+ }
} else if (ifmgd->auth_data->algorithm == WLAN_AUTH_SAE &&
auth_transaction == 1) {
sae_need_confirm = true;
@@ -8457,6 +8514,10 @@ static int ieee80211_auth(struct ieee80211_sub_if_data *sdata)
} else if (auth_data->algorithm == WLAN_AUTH_EPPKE) {
trans = auth_data->trans;
status = auth_data->status;
+ } else if (auth_data->algorithm == WLAN_AUTH_IEEE8021X) {
+ trans = auth_data->trans;
+ status = auth_data->status;
+ auth_data->expected_transaction = trans + 1;
}
if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS))
@@ -9114,7 +9175,8 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
}
if (ifmgd->auth_data &&
- ifmgd->auth_data->algorithm == WLAN_AUTH_EPPKE)
+ (ifmgd->auth_data->algorithm == WLAN_AUTH_EPPKE ||
+ ifmgd->auth_data->algorithm == WLAN_AUTH_IEEE8021X))
new_sta->sta.epp_peer = true;
new_sta->sta.mlo = mlo;
@@ -9374,6 +9436,9 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
case NL80211_AUTHTYPE_EPPKE:
auth_alg = WLAN_AUTH_EPPKE;
break;
+ case NL80211_AUTHTYPE_IEEE8021X:
+ auth_alg = WLAN_AUTH_IEEE8021X;
+ break;
default:
return -EOPNOTSUPP;
}
@@ -9399,7 +9464,8 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
if (req->auth_data_len >= 4) {
if (req->auth_type == NL80211_AUTHTYPE_SAE ||
- req->auth_type == NL80211_AUTHTYPE_EPPKE) {
+ req->auth_type == NL80211_AUTHTYPE_EPPKE ||
+ req->auth_type == NL80211_AUTHTYPE_IEEE8021X) {
__le16 *pos = (__le16 *) req->auth_data;
auth_data->trans = le16_to_cpu(pos[0]);
--
2.34.1
^ permalink raw reply related
* [PATCH wireless-next v2 5/5] wifi: mac80211: Advertise IEEE 802.1X authentication support
From: Kavita Kavita @ 2026-02-26 18:55 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, kavita.kavita
In-Reply-To: <20260226185553.1516290-1-kavita.kavita@oss.qualcomm.com>
Advertise support for IEEE 802.1X authentication protocol directly from
mac80211, without depending on driver indication of (Re)Association
frame encryption capability.
As specified in "IEEE P802.11bi/D4.0, clauses 12.16.5 and 12.16.8.2",
IEEE 802.1X authentication can operate with or without (Re)Association
frame encryption support. Therefore, mac80211 can safely advertise
802.1X support independently of driver capabilities.
Signed-off-by: Kavita Kavita <kavita.kavita@oss.qualcomm.com>
---
net/mac80211/main.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 93af2f58d7f7..10ddd261b084 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -915,6 +915,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_TXQS);
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_RRM);
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_IEEE8021X_AUTH);
wiphy->bss_priv_size = sizeof(struct ieee80211_bss);
--
2.34.1
^ permalink raw reply related
* [PATCH wireless 0/3] wifi: mt76: Fix possible out-of-bound accesses in mt76 driver
From: Lorenzo Bianconi @ 2026-02-26 19:11 UTC (permalink / raw)
To: Felix Fietkau, Ryder Lee, Shayne Chen, Sean Wang,
Matthias Brugger, AngeloGioacchino Del Regno, StanleyYP Wang,
Peter Chiu, MeiChia Chiu, Leon Yen, Deren Wu, Quan Zhou,
Mingyen Hsieh
Cc: Johannes Berg, Howard Hsu, Bo Jiao, linux-wireless,
linux-arm-kernel, linux-mediatek, Hao Zhang, Nelson Yu,
Lorenzo Bianconi
Check mgmt frame length before accessing header fields in order to avoid
a possible oob access for injected frames.
---
Lorenzo Bianconi (3):
wifi: mt76: mt7996: Fix possible oob access in mt7996_mac_write_txwi_80211()
wifi: mt76: mt7925: Fix possible oob access in mt7925_mac_write_txwi_80211()
wifi: mt76: Fix possible oob access in mt76_connac2_mac_write_txwi_80211()
drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c | 1 +
drivers/net/wireless/mediatek/mt76/mt7925/mac.c | 1 +
drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 1 +
3 files changed, 3 insertions(+)
---
base-commit: 8bf22c33e7a172fbc72464f4cc484d23a6b412ba
change-id: 20260226-mt76-addba-req-oob-access-848280920814
Best regards,
--
Lorenzo Bianconi <lorenzo@kernel.org>
^ permalink raw reply
* [PATCH wireless 1/3] wifi: mt76: mt7996: Fix possible oob access in mt7996_mac_write_txwi_80211()
From: Lorenzo Bianconi @ 2026-02-26 19:11 UTC (permalink / raw)
To: Felix Fietkau, Ryder Lee, Shayne Chen, Sean Wang,
Matthias Brugger, AngeloGioacchino Del Regno, StanleyYP Wang,
Peter Chiu, MeiChia Chiu, Leon Yen, Deren Wu, Quan Zhou,
Mingyen Hsieh
Cc: Johannes Berg, Howard Hsu, Bo Jiao, linux-wireless,
linux-arm-kernel, linux-mediatek, Hao Zhang, Nelson Yu,
Lorenzo Bianconi
In-Reply-To: <20260226-mt76-addba-req-oob-access-v1-0-b0f6d1ad4850@kernel.org>
Check frame length before accessing the mgmt fields in
mt7996_mac_write_txwi_80211 in order to avoid a possible oob access.
Fixes: 98686cd21624c ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
index 2560e2f46e89a4bc46e21d796fca80b7decefa5c..d4f3ee943b4727a0e20f96a55db3bf055df20cc7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
@@ -800,6 +800,7 @@ mt7996_mac_write_txwi_80211(struct mt7996_dev *dev, __le32 *txwi,
u32 val;
if (ieee80211_is_action(fc) &&
+ skb->len >= IEEE80211_MIN_ACTION_SIZE + 1 &&
mgmt->u.action.category == WLAN_CATEGORY_BACK &&
mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ) {
if (is_mt7990(&dev->mt76))
--
2.53.0
^ permalink raw reply related
* [PATCH wireless 2/3] wifi: mt76: mt7925: Fix possible oob access in mt7925_mac_write_txwi_80211()
From: Lorenzo Bianconi @ 2026-02-26 19:11 UTC (permalink / raw)
To: Felix Fietkau, Ryder Lee, Shayne Chen, Sean Wang,
Matthias Brugger, AngeloGioacchino Del Regno, StanleyYP Wang,
Peter Chiu, MeiChia Chiu, Leon Yen, Deren Wu, Quan Zhou,
Mingyen Hsieh
Cc: Johannes Berg, Howard Hsu, Bo Jiao, linux-wireless,
linux-arm-kernel, linux-mediatek, Hao Zhang, Nelson Yu,
Lorenzo Bianconi
In-Reply-To: <20260226-mt76-addba-req-oob-access-v1-0-b0f6d1ad4850@kernel.org>
Check frame length before accessing the mgmt fields in
mt7925_mac_write_txwi_80211 in order to avoid a possible oob access.
Fixes: c948b5da6bbec ("wifi: mt76: mt7925: add Mediatek Wi-Fi7 driver for mt7925 chips")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt7925/mac.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
index 871b67101976a7d72ca10c9736ccfa59b0f21122..0d94359004233e94c11a2d09f67b1ae61ccf71ad 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
@@ -668,6 +668,7 @@ mt7925_mac_write_txwi_80211(struct mt76_dev *dev, __le32 *txwi,
u32 val;
if (ieee80211_is_action(fc) &&
+ skb->len >= IEEE80211_MIN_ACTION_SIZE + 1 &&
mgmt->u.action.category == WLAN_CATEGORY_BACK &&
mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ)
tid = MT_TX_ADDBA;
--
2.53.0
^ permalink raw reply related
* [PATCH wireless 3/3] wifi: mt76: Fix possible oob access in mt76_connac2_mac_write_txwi_80211()
From: Lorenzo Bianconi @ 2026-02-26 19:11 UTC (permalink / raw)
To: Felix Fietkau, Ryder Lee, Shayne Chen, Sean Wang,
Matthias Brugger, AngeloGioacchino Del Regno, StanleyYP Wang,
Peter Chiu, MeiChia Chiu, Leon Yen, Deren Wu, Quan Zhou,
Mingyen Hsieh
Cc: Johannes Berg, Howard Hsu, Bo Jiao, linux-wireless,
linux-arm-kernel, linux-mediatek, Hao Zhang, Nelson Yu,
Lorenzo Bianconi
In-Reply-To: <20260226-mt76-addba-req-oob-access-v1-0-b0f6d1ad4850@kernel.org>
Check frame length before accessing the mgmt fields in
mt76_connac2_mac_write_txwi_80211 in order to avoid a possible oob
access.
Fixes: 182071cdd594b ("mt76: connac: move connac2_mac_write_txwi in mt76_connac module")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
index 3304b5971be09e4c20178bdff66febf67bcd5c19..ad66a64200213a45e44d6f30a7a1e4306fd84240 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
@@ -413,6 +413,7 @@ mt76_connac2_mac_write_txwi_80211(struct mt76_dev *dev, __le32 *txwi,
u32 val;
if (ieee80211_is_action(fc) &&
+ skb->len >= IEEE80211_MIN_ACTION_SIZE + 1 &&
mgmt->u.action.category == WLAN_CATEGORY_BACK &&
mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ) {
u16 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
--
2.53.0
^ permalink raw reply related
* Re: [PATCH v3] wifi: iwlwifi: prevent NAPI processing after firmware error
From: Ben Greear @ 2026-02-26 19:37 UTC (permalink / raw)
To: Cole Leavitt, johannes.berg, miriam.rachel.korenblit
Cc: linux-wireless, stable
In-Reply-To: <20260214184352.11512-1-cole@unwrap.rs>
On 2/14/26 10:43, Cole Leavitt wrote:
> After a firmware error is detected and STATUS_FW_ERROR is set, NAPI can
> still be actively polling or get scheduled from a prior interrupt. The
> NAPI poll functions (both legacy and MSIX variants) have no check for
> STATUS_FW_ERROR and will continue processing stale RX ring entries from
> dying firmware. This can dispatch TX completion notifications containing
> corrupt SSN values to iwl_mld_handle_tx_resp_notif(), which passes them
> to iwl_trans_reclaim(). If the corrupt SSN causes reclaim to walk TX
> queue entries that were already freed by a prior correct reclaim, the
> result is an skb use-after-free or double-free.
Hello Cole,
We've been testing with this patch, and today managed to see its logic trigger.
The system had a cascade of other errors leading to use-after-free that does
not appear to be related to the skb use-after free, but I can at least confirm your
patch can be triggered. Here are logs around this. I believe in this case, firmware
didn't actually bubble up a crash notification/interrupt, but probably the driver detected timeout
and faked a crash.
Feb 26 11:09:35 ct523c-de7c kernel: workqueue: blk_mq_requeue_work hogged CPU for >10000us 4 times, consider switching to WQ_UNBOUND
Feb 26 11:09:36 ct523c-de7c kernel: workqueue: gc_worker [nf_conntrack] hogged CPU for >10000us 515 times, consider switching to WQ_UNBOUND
Feb 26 11:09:39 ct523c-de7c kernel: iwlwifi 0000:28:00.0: Error sending SYSTEM_STATISTICS_CMD: time out after 2000ms.
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: Current CMD queue read_ptr 92 write_ptr 93
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: Start IWL Error Log Dump:
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: Transport status: 0x0000004A, valid: 6
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: Loaded firmware version: 101.6ef20b19.0 gl-c0-fm-c0-101.ucode
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000084 | NMI_INTERRUPT_UNKNOWN
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x000002F0 | trm_hw_status0
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | trm_hw_status1
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x002C438C | branchlink2
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00009C04 | interruptlink1
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00009C04 | interruptlink2
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00009C3C | data1
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x01000000 | data2
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | data3
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0xD040FE38 | beacon time
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x3B6411CD | tsf low
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x0000026B | tsf hi
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | time gp1
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x0616DB18 | time gp2
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000001 | uCode revision type
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000065 | uCode version major
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x6EF20B19 | uCode version minor
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000472 | hw version
Feb 26 11:09:40 ct523c-de7c kernel: ------------[ cut here ]------------
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi: NAPI MSIX poll[0] invoked after FW error
Feb 26 11:09:40 ct523c-de7c kernel: WARNING: CPU: 3 PID: 36 at drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/rx.c:1058 iwl_pcie_napi_poll_msix+0x29e/0x310
[iwlwifi]
Feb 26 11:09:40 ct523c-de7c 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 ib_cm ib_core qrtr bnep intel_rapl_msr iTCO_wdt intel_pmc_bxt ee1004 iTCO_vendor_support iwlmld coretemp
intel_rapl_common intel_uncore_frequency intel_uncore_frequency_common snd_hda_codec_intelhdmi snd_hda_codec_hdmi intel_tcc_cooling x86_pkg_temp_thermal
snd_hda_codec_alc662 snd_hda_codec_realtek_lib intel_powerclamp intel_wmi_thunderbolt snd_hda_codec_generic snd_hda_intel snd_intel_dspcfg snd_hda_codec
mac80211 snd_hda_core snd_hwdep snd_seq btusb btbcm snd_seq_device btmtk btrtl btintel snd_pcm iwlwifi bluetooth snd_timer cfg80211 i2c_i801 snd i2c_smbus
soundcore i2c_mux mei_pxp mei_hdcp intel_pch_thermal intel_pmc_core pmt_telemetry pmt_discovery pmt_class intel_pmc_ssram_telemetry intel_vsec acpi_pad bfq nfsd
sch_fq_codel auth_rpcgss nfs_acl lockd grace nfs_localio fuse sunrpc raid1 dm_raid raid456 async_raid6_recov async_memcpy async_pq
Feb 26 11:09:40 ct523c-de7c kernel: async_xor xor async_tx raid6_pq i915 drm_buddy intel_gtt drm_client_lib drm_display_helper drm_kms_helper cec rc_core ttm
agpgart ixgbe mdio igb libie_fwlog i2c_algo_bit dca drm hwmon mei_wdt i2c_core intel_oc_wdt video wmi scsi_dh_rdac scsi_dh_emc scsi_dh_alua dm_multipath [last
unloaded: nfnetlink]
Feb 26 11:09:40 ct523c-de7c kernel: CPU: 3 UID: 0 PID: 36 Comm: ksoftirqd/3 Kdump: loaded Not tainted 6.18.9+ #18 PREEMPT(full)
Feb 26 11:09:40 ct523c-de7c kernel: Hardware name: Default string Default string/SKYBAY, BIOS 5.12 02/21/2023
Feb 26 11:09:40 ct523c-de7c kernel: RIP: 0010:iwl_pcie_napi_poll_msix+0x29e/0x310 [iwlwifi]
Feb 26 11:09:40 ct523c-de7c kernel: Code: 00 00 fc ff df 48 89 fa 48 c1 ea 03 0f b6 04 02 84 c0 74 04 3c 03 7e 74 8b b3 48 ff ff ff 48 c7 c7 a0 d2 19 a2 e8 62
00 0f df <0f> 0b eb 96 4c 89 e7 e8 d6 92 9f df e9 0b fe ff ff e8 cc 92 9f df
Feb 26 11:09:40 ct523c-de7c kernel: RSP: 0018:ffff888120fe7b70 EFLAGS: 00010286
Feb 26 11:09:40 ct523c-de7c kernel: RAX: 0000000000000000 RBX: ffff888182e100b8 RCX: 0000000000000001
Feb 26 11:09:40 ct523c-de7c kernel: RDX: 0000000000000027 RSI: 0000000000000004 RDI: ffff88841dba4e48
Feb 26 11:09:40 ct523c-de7c kernel: RBP: ffff888132504028 R08: 0000000000000001 R09: ffffed1083b749c9
Feb 26 11:09:40 ct523c-de7c kernel: R10: ffff88841dba4e4b R11: 0000000000072ee8 R12: ffff888132504090
Feb 26 11:09:40 ct523c-de7c kernel: R13: ffff888132504d90 R14: 0000000000000040 R15: ffff888134b480b8
Feb 26 11:09:40 ct523c-de7c kernel: FS: 0000000000000000(0000) GS:ffff8884974c7000(0000) knlGS:0000000000000000
Feb 26 11:09:40 ct523c-de7c kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
Feb 26 11:09:40 ct523c-de7c kernel: CR2: 00007fd5beb80028 CR3: 000000013e2d4001 CR4: 00000000003706f0
Feb 26 11:09:40 ct523c-de7c kernel: Call Trace:
Feb 26 11:09:40 ct523c-de7c kernel: <TASK>
Feb 26 11:09:40 ct523c-de7c kernel: __napi_poll.constprop.0+0xa0/0x580
Feb 26 11:09:40 ct523c-de7c kernel: net_rx_action+0x84d/0xe40
Feb 26 11:09:40 ct523c-de7c kernel: ? __napi_poll.constprop.0+0x580/0x580
Feb 26 11:09:40 ct523c-de7c kernel: ? do_raw_spin_lock+0x12c/0x270
Feb 26 11:09:40 ct523c-de7c kernel: ? run_timer_softirq+0xf2/0x1b0
Feb 26 11:09:40 ct523c-de7c kernel: ? lock_release+0xce/0x290
Feb 26 11:09:40 ct523c-de7c kernel: ? trace_irq_enable.constprop.0+0xbe/0x100
Feb 26 11:09:40 ct523c-de7c kernel: handle_softirqs+0x1c6/0x810
Feb 26 11:09:40 ct523c-de7c kernel: run_ksoftirqd+0x2d/0x50
Feb 26 11:09:40 ct523c-de7c kernel: smpboot_thread_fn+0x338/0x8c0
Feb 26 11:09:40 ct523c-de7c kernel: ? sort_range+0x20/0x20
Feb 26 11:09:40 ct523c-de7c kernel: kthread+0x3b7/0x770
Feb 26 11:09:40 ct523c-de7c kernel: ? kthread_is_per_cpu+0xb0/0xb0
Feb 26 11:09:40 ct523c-de7c kernel: ? ret_from_fork+0x17/0x3a0
Feb 26 11:09:40 ct523c-de7c kernel: ? lock_release+0xce/0x290
Feb 26 11:09:40 ct523c-de7c kernel: ? kthread_is_per_cpu+0xb0/0xb0
Feb 26 11:09:40 ct523c-de7c kernel: ret_from_fork+0x28b/0x3a0
Feb 26 11:09:40 ct523c-de7c kernel: ? kthread_is_per_cpu+0xb0/0xb0
Feb 26 11:09:40 ct523c-de7c kernel: ret_from_fork_asm+0x11/0x20
Feb 26 11:09:40 ct523c-de7c kernel: </TASK>
Feb 26 11:09:40 ct523c-de7c kernel: irq event stamp: 36429934
Feb 26 11:09:40 ct523c-de7c kernel: hardirqs last enabled at (36429940): [<ffffffff816116ee>] __up_console_sem+0x5e/0x70
Feb 26 11:09:40 ct523c-de7c kernel: hardirqs last disabled at (36429945): [<ffffffff816116d3>] __up_console_sem+0x43/0x70
Feb 26 11:09:40 ct523c-de7c kernel: softirqs last enabled at (36428910): [<ffffffff81471d3d>] run_ksoftirqd+0x2d/0x50
Feb 26 11:09:40 ct523c-de7c kernel: softirqs last disabled at (36428915): [<ffffffff81471d3d>] run_ksoftirqd+0x2d/0x50
Feb 26 11:09:40 ct523c-de7c kernel: ---[ end trace 0000000000000000 ]---
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00C80002 | board version
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x036D001C | hcmd
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0xF6F38000 | isr0
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x01400000 | isr1
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x48F00002 | isr2
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00C00008 | isr3
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x18200000 | isr4
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x036D001C | last cmd Id
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00009C3C | wait_event
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x10000010 | l2p_control
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | l2p_duration
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | l2p_mhvalid
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | l2p_addr_match
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000009 | lmpm_pmg_sel
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | timestamp
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00009018 | flow_handler
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: Start IWL Error Log Dump:
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: Transport status: 0x0000004A, valid: 6
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: Loaded firmware version: 101.6ef20b19.0 gl-c0-fm-c0-101.ucode
Feb 26 11:09:40 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000084 | NMI_INTERRUPT_UNKNOWN
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x000002F0 | trm_hw_status0
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | trm_hw_status1
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x002C438C | branchlink2
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x002B8AD0 | interruptlink1
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x002B8AD0 | interruptlink2
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x002A5822 | data1
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x01000000 | data2
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | data3
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0xD040FE37 | beacon time
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x3B6411CE | tsf low
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x0000026B | tsf hi
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | time gp1
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x0616DB19 | time gp2
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000001 | uCode revision type
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000065 | uCode version major
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x6EF20B19 | uCode version minor
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000472 | hw version
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00C80002 | board version
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x804AFC12 | hcmd
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00020000 | isr0
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | isr1
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x48F00002 | isr2
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00C0001C | isr3
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | isr4
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | last cmd Id
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x002A5822 | wait_event
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x10000010 | l2p_control
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | l2p_duration
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | l2p_mhvalid
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | l2p_addr_match
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000028 | lmpm_pmg_sel
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | timestamp
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00009018 | flow_handler
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: Start IWL Error Log Dump:
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: Transport status: 0x0000004A, valid: 7
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x20000066 | NMI_INTERRUPT_HOST
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | umac branchlink1
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0xC00808AA | umac branchlink2
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x80287BFE | umac interruptlink1
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x0102163E | umac interruptlink2
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x01000000 | umac data1
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x0102163E | umac data2
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | umac data3
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000065 | umac major
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x6EF20B19 | umac minor
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x0616DB0F | frame pointer
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0xD00D6258 | stack pointer
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x005C020F | last host cmd
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000400 | isr status reg
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: TCM1 status:
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000070 | error ID
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00001D2E | tcm branchlink2
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x0000211C | tcm interruptlink1
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x0000211C | tcm interruptlink2
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x40000000 | tcm data1
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0xDEADBEEF | tcm data2
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0xDEADBEEF | tcm data3
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00001DAC | tcm log PC
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00803FF0 | tcm frame pointer
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00803F5C | tcm stack pointer
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | tcm msg ID
Feb 26 11:09:41 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x4000001F | tcm ISR status
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x000002F0 | tcm HW status[0]
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | tcm HW status[1]
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | tcm HW status[2]
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x40008300 | tcm HW status[3]
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | tcm HW status[4]
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | tcm SW status[0]
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: RCM1 status:
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000070 | error ID
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00001E2E | rcm branchlink2
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x000027A0 | rcm interruptlink1
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x000027A0 | rcm interruptlink2
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x20000000 | rcm data1
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0xDEADBEEF | rcm data2
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0xDEADBEEF | rcm data3
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00001E98 | rcm log PC
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00803FF0 | rcm frame pointer
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00803F5C | rcm stack pointer
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | rcm msg ID
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x2006F000 | rcm ISR status
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00020400 | frame HW status
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | LMAC-to-RCM request mbox
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | RCM-to-LMAC request mbox
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | MAC header control
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | MAC header addr1 low
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x003C0000 | MAC header info
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | MAC header error
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: TCM2 status:
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000070 | error ID
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00001D2E | tcm branchlink2
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x0000211C | tcm interruptlink1
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x0000211C | tcm interruptlink2
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x40000000 | tcm data1
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0xDEADBEEF | tcm data2
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0xDEADBEEF | tcm data3
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00001DAC | tcm log PC
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00803FF0 | tcm frame pointer
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00803F5C | tcm stack pointer
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | tcm msg ID
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x60000000 | tcm ISR status
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x000002F0 | tcm HW status[0]
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | tcm HW status[1]
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | tcm HW status[2]
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00008000 | tcm HW status[3]
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | tcm HW status[4]
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | tcm SW status[0]
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: RCM2 status:
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000070 | error ID
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00001E2E | rcm branchlink2
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x000027A0 | rcm interruptlink1
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x000027A0 | rcm interruptlink2
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x20000000 | rcm data1
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0xDEADBEEF | rcm data2
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0xDEADBEEF | rcm data3
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00001E98 | rcm log PC
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00803FF0 | rcm frame pointer
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00803F5C | rcm stack pointer
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | rcm msg ID
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x20000000 | rcm ISR status
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00020400 | frame HW status
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | LMAC-to-RCM request mbox
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | RCM-to-LMAC request mbox
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | MAC header control
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | MAC header addr1 low
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x003C0000 | MAC header info
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | MAC header error
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: IML/ROM dump:
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000B03 | IML/ROM error/state
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x0000EEE3 | IML/ROM data1
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000080 | IML/ROM WFPM_AUTH_KEY_0
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: Fseq Registers:
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x60000000 | FSEQ_ERROR_CODE
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x80B10006 | FSEQ_TOP_INIT_VERSION
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00570000 | FSEQ_CNVIO_INIT_VERSION
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x0000AA14 | FSEQ_OTP_VERSION
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x0000000F | FSEQ_TOP_CONTENT_VERSION
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x4552414E | FSEQ_ALIVE_TOKEN
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x02001910 | FSEQ_CNVI_ID
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x02001910 | FSEQ_CNVR_ID
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x02001910 | CNVI_AUX_MISC_CHIP
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x02001910 | CNVR_AUX_MISC_CHIP
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x8F0F1BEF | CNVR_SCU_SD_REGS_SD_REG_DIG_DCDC_VTRIM
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00000000 | CNVR_SCU_SD_REGS_SD_REG_ACTIVE_VDIG_MIRROR
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00570000 | FSEQ_PREV_CNVIO_INIT_VERSION
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00B10006 | FSEQ_WIFI_FSEQ_VERSION
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x00B10005 | FSEQ_BT_FSEQ_VERSION
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x000000DC | FSEQ_CLASS_TP_VERSION
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: UMAC CURRENT PC: 0x8028b720
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: LMAC1 CURRENT PC: 0xd0
Feb 26 11:09:42 ct523c-de7c kernel: iwlwifi 0000:28:00.0: LMAC2 CURRENT PC: 0xd0
Feb 26 11:09:43 ct523c-de7c kernel: iwlwifi 0000:28:00.0: UMAC CURRENT PC 1: 0x8028b722
Feb 26 11:09:43 ct523c-de7c kernel: iwlwifi 0000:28:00.0: TCM1 CURRENT PC: 0xd0
Feb 26 11:09:43 ct523c-de7c kernel: iwlwifi 0000:28:00.0: RCM1 CURRENT PC: 0xd0
Feb 26 11:09:43 ct523c-de7c kernel: iwlwifi 0000:28:00.0: RCM2 CURRENT PC: 0xd0
Feb 26 11:09:43 ct523c-de7c kernel: iwlwifi 0000:28:00.0: Function Scratch status:
Feb 26 11:09:43 ct523c-de7c kernel: iwlwifi 0000:28:00.0: 0x01010100 | Func Scratch
Feb 26 11:09:43 ct523c-de7c kernel: iwlwifi 0000:28:00.0: WRT: Collecting data: ini trigger 4 fired (delay=0ms).
Thanks,
Ben
>
> The race window opens when the MSIX IRQ handler schedules NAPI (lines
> 2319-2321 in rx.c) before processing the error bit (lines 2382-2396),
> or when NAPI is already running on another CPU from a previous interrupt
> when STATUS_FW_ERROR gets set on the current CPU.
>
> Add STATUS_FW_ERROR checks to both NAPI poll functions to prevent
> processing stale RX data after firmware error, and add early-return
> guards in the TX response and compressed BA notification handlers as
> defense-in-depth. Each check uses WARN_ONCE to log if the race is
> actually hit, which aids diagnosis of the hard-to-reproduce skb
> use-after-free reported on Intel BE200.
>
> Note that _iwl_trans_pcie_gen2_stop_device() already calls
> iwl_pcie_rx_napi_sync() to quiesce NAPI during device teardown, but that
> runs much later in the restart sequence. These checks close the window
> between error detection and device stop.
>
> Fixes: d1e879ec600f ("wifi: iwlwifi: add iwlmld sub-driver")
> Cc: stable@vger.kernel.org
> Signed-off-by: Cole Leavitt <cole@unwrap.rs>
> ---
> Changes since v1:
> - Added Fixes: tag and Cc: stable@vger.kernel.org
>
> Tested on Intel BE200 (FW 101.6e695a70.0) by forcing NMI via debugfs.
> The WARN_ONCE fires reliably:
>
> iwlwifi: NAPI MSIX poll[0] invoked after FW error
> WARNING: drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/rx.c:1058
> at iwl_pcie_napi_poll_msix+0xff/0x130 [iwlwifi], CPU#22
>
> Confirming NAPI poll is invoked after STATUS_FW_ERROR is set. Without
> this patch, that poll processes stale RX ring data from dead firmware.
>
> drivers/net/wireless/intel/iwlwifi/mld/tx.c | 19 ++++++++++++++++++
> .../wireless/intel/iwlwifi/pcie/gen1_2/rx.c | 20 +++++++++++++++++++
> 2 files changed, 39 insertions(+)
>
> diff --git a/drivers/net/wireless/intel/iwlwifi/mld/tx.c b/drivers/net/wireless/intel/iwlwifi/mld/tx.c
> index 3b4b575aadaa..3e99f3ded9bc 100644
> --- a/drivers/net/wireless/intel/iwlwifi/mld/tx.c
> +++ b/drivers/net/wireless/intel/iwlwifi/mld/tx.c
> @@ -1071,6 +1071,18 @@ void iwl_mld_handle_tx_resp_notif(struct iwl_mld *mld,
> bool mgmt = false;
> bool tx_failure = (status & TX_STATUS_MSK) != TX_STATUS_SUCCESS;
>
> + /* Firmware is dead — the TX response may contain corrupt SSN values
> + * from a dying firmware DMA. Processing it could cause
> + * iwl_trans_reclaim() to free the wrong TX queue entries, leading to
> + * skb use-after-free or double-free.
> + */
> + if (unlikely(test_bit(STATUS_FW_ERROR, &mld->trans->status))) {
> + WARN_ONCE(1,
> + "iwlwifi: TX resp notif (sta=%d txq=%d) after FW error\n",
> + sta_id, txq_id);
> + return;
> + }
> +
> if (IWL_FW_CHECK(mld, tx_resp->frame_count != 1,
> "Invalid tx_resp notif frame_count (%d)\n",
> tx_resp->frame_count))
> @@ -1349,6 +1361,13 @@ void iwl_mld_handle_compressed_ba_notif(struct iwl_mld *mld,
> u8 sta_id = ba_res->sta_id;
> struct ieee80211_link_sta *link_sta;
>
> + if (unlikely(test_bit(STATUS_FW_ERROR, &mld->trans->status))) {
> + WARN_ONCE(1,
> + "iwlwifi: BA notif (sta=%d) after FW error\n",
> + sta_id);
> + return;
> + }
> +
> if (!tfd_cnt)
> return;
>
> diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/rx.c
> index 619a9505e6d9..ba18d35fa55d 100644
> --- a/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/rx.c
> +++ b/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/rx.c
> @@ -1015,6 +1015,18 @@ static int iwl_pcie_napi_poll(struct napi_struct *napi, int budget)
> trans_pcie = iwl_netdev_to_trans_pcie(napi->dev);
> trans = trans_pcie->trans;
>
> + /* Stop processing RX if firmware has crashed. Stale notifications
> + * from dying firmware (e.g. TX completions with corrupt SSN values)
> + * can cause use-after-free in reclaim paths.
> + */
> + if (unlikely(test_bit(STATUS_FW_ERROR, &trans->status))) {
> + WARN_ONCE(1,
> + "iwlwifi: NAPI poll[%d] invoked after FW error\n",
> + rxq->id);
> + napi_complete_done(napi, 0);
> + return 0;
> + }
> +
> ret = iwl_pcie_rx_handle(trans, rxq->id, budget);
>
> IWL_DEBUG_ISR(trans, "[%d] handled %d, budget %d\n",
> @@ -1042,6 +1054,14 @@ static int iwl_pcie_napi_poll_msix(struct napi_struct *napi, int budget)
> trans_pcie = iwl_netdev_to_trans_pcie(napi->dev);
> trans = trans_pcie->trans;
>
> + if (unlikely(test_bit(STATUS_FW_ERROR, &trans->status))) {
> + WARN_ONCE(1,
> + "iwlwifi: NAPI MSIX poll[%d] invoked after FW error\n",
> + rxq->id);
> + napi_complete_done(napi, 0);
> + return 0;
> + }
> +
> ret = iwl_pcie_rx_handle(trans, rxq->id, budget);
> IWL_DEBUG_ISR(trans, "[%d] handled %d, budget %d\n", rxq->id, ret,
> budget);
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* iwlwifi + mac80211: Force success in case of EIO in dis-assoc path?
From: Ben Greear @ 2026-02-26 19:51 UTC (permalink / raw)
To: linux-wireless; +Cc: Korenblit, Miriam Rachel
Hello,
It looks like the radios in my system had some serious problem for one reason or another
and stopped responding, and it hit a warning of interest up in mac80211, in this code:
if (new_state < sta->sta_state &&
test_sta_flag(sta, WLAN_STA_INSERTED)) {
int err = drv_sta_state(sta->local, sta->sdata, sta,
sta->sta_state, new_state);
WARN_ONCE(err,
"Driver is not allowed to fail if the sta_state is transitioning down the list: %d\n",
err);
}
So in case the driver is trying to do drv_sta_state, and it runs into -EIO. If we are going 'down the list',
should we force driver to ignore the EIO error and return success?
I think this is the pertinent set of logs related to this failure (several radios were failing
concurrently I believe, so possibly some logs are jumbled).
Feb 26 11:09:56 ct523c-de7c kernel: ------------[ cut here ]------------
Feb 26 11:09:56 ct523c-de7c kernel: bad state = 0
Feb 26 11:09:56 ct523c-de7c kernel: WARNING: CPU: 1 PID: 111503 at drivers/net/wireless/intel/iwlwifi/iwl-trans.c:312 iwl_trans_send_cmd+0x2ad/0x330 [iwlwifi]
Feb 26 11:09:56 ct523c-de7c 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 ib_cm ib_core qrtr bnep intel_rapl_msr iTCO_wdt intel_pmc_bxt ee1004 iTCO_vendor_support iwlmld coretemp
intel_rapl_common intel_uncore_frequency intel_uncore_frequency_common snd_hda_codec_intelhdmi snd_hda_codec_hdmi intel_tcc_cooling x86_pkg_temp_thermal
snd_hda_codec_alc662 snd_hda_codec_realtek_lib intel_powerclamp intel_wmi_thunderbolt snd_hda_codec_generic snd_hda_intel snd_intel_dspcfg snd_hda_codec
mac80211 snd_hda_core snd_hwdep snd_seq btusb btbcm snd_seq_device btmtk btrtl btintel snd_pcm iwlwifi bluetooth snd_timer cfg80211 i2c_i801 snd i2c_smbus
soundcore i2c_mux mei_pxp mei_hdcp intel_pch_thermal intel_pmc_core pmt_telemetry pmt_discovery pmt_class intel_pmc_ssram_telemetry intel_vsec acpi_pad bfq nfsd
sch_fq_codel auth_rpcgss nfs_acl lockd grace nfs_localio fuse sunrpc raid1 dm_raid raid456 async_raid6_recov async_memcpy async_pq
Feb 26 11:09:56 ct523c-de7c kernel: async_xor xor async_tx raid6_pq i915 drm_buddy intel_gtt drm_client_lib drm_display_helper drm_kms_helper cec rc_core ttm
agpgart ixgbe mdio igb libie_fwlog i2c_algo_bit dca drm hwmon mei_wdt i2c_core intel_oc_wdt video wmi scsi_dh_rdac scsi_dh_emc scsi_dh_alua dm_multipath [last
unloaded: nfnetlink]
Feb 26 11:09:56 ct523c-de7c kernel: CPU: 1 UID: 0 PID: 111503 Comm: kworker/1:0 Kdump: loaded Tainted: G W 6.18.9+ #18 PREEMPT(full)
Feb 26 11:09:56 ct523c-de7c kernel: Tainted: [W]=WARN
Feb 26 11:09:56 ct523c-de7c kernel: Hardware name: Default string Default string/SKYBAY, BIOS 5.12 02/21/2023
Feb 26 11:09:56 ct523c-de7c kernel: Workqueue: events_freezable ieee80211_restart_work [mac80211]
Feb 26 11:09:56 ct523c-de7c kernel: RIP: 0010:iwl_trans_send_cmd+0x2ad/0x330 [iwlwifi]
Feb 26 11:09:56 ct523c-de7c kernel: Code: bd 7c ff ff ff e9 08 ff ff ff 80 3d 8c ba dc ff 00 0f 85 30 ff ff ff 48 c7 c7 00 8c 1a a2 c6 05 78 ba dc ff 01 e8 b3
bd 0a df <0f> 0b e9 16 ff ff ff 4c 89 e7 e8 14 50 9b df e9 7e fd ff ff e8 0a
Feb 26 11:09:56 ct523c-de7c kernel: RSP: 0018:ffff8881f7e96ea8 EFLAGS: 00010282
Feb 26 11:09:56 ct523c-de7c kernel: RAX: 0000000000000000 RBX: ffff888132504028 RCX: 0000000000000001
Feb 26 11:09:56 ct523c-de7c kernel: RDX: 0000000000000027 RSI: 0000000000000004 RDI: ffff88841daa4e48
Feb 26 11:09:56 ct523c-de7c kernel: RBP: ffff8881f7e96fb0 R08: 0000000000000001 R09: ffffed1083b549c9
Feb 26 11:09:56 ct523c-de7c kernel: R10: ffff88841daa4e4b R11: 000000000007bfe8 R12: ffff8881f7e96fd4
Feb 26 11:09:56 ct523c-de7c kernel: R13: ffff888132504090 R14: ffff88815aec7a68 R15: ffff88815aec5508
Feb 26 11:09:56 ct523c-de7c kernel: FS: 0000000000000000(0000) GS:ffff8884973c7000(0000) knlGS:0000000000000000
Feb 26 11:09:56 ct523c-de7c kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
Feb 26 11:09:56 ct523c-de7c kernel: CR2: 0000557cd9657138 CR3: 0000000128903001 CR4: 00000000003706f0
Feb 26 11:09:56 ct523c-de7c kernel: Call Trace:
Feb 26 11:09:56 ct523c-de7c kernel: <TASK>
Feb 26 11:09:56 ct523c-de7c kernel: iwl_mld_sync_rx_queues+0x297/0x6e0 [iwlmld]
Feb 26 11:09:56 ct523c-de7c kernel: ? mark_held_locks+0x49/0x70
Feb 26 11:09:56 ct523c-de7c kernel: ? iwl_mld_rx_mpdu+0x4100/0x4100 [iwlmld]
Feb 26 11:09:56 ct523c-de7c kernel: ? do_raw_spin_lock+0x12c/0x270
Feb 26 11:09:56 ct523c-de7c kernel: ? spin_bug+0x1d0/0x1d0
Feb 26 11:09:56 ct523c-de7c kernel: ? lock_is_held_type+0xa5/0x110
Feb 26 11:09:56 ct523c-de7c kernel: __sta_info_destroy_part1+0x252/0x12c0 [mac80211]
Feb 26 11:09:56 ct523c-de7c kernel: ? lock_is_held_type+0xa5/0x110
Feb 26 11:09:56 ct523c-de7c kernel: __sta_info_flush+0x2e1/0x610 [mac80211]
Feb 26 11:09:56 ct523c-de7c kernel: ? __sta_info_destroy+0x30/0x30 [mac80211]
Feb 26 11:09:56 ct523c-de7c kernel: ? ieee80211_bss_info_change_notify+0x53/0x650 [mac80211]
Feb 26 11:09:56 ct523c-de7c kernel: ieee80211_set_disassoc+0x14fb/0x1c10 [mac80211]
Feb 26 11:09:56 ct523c-de7c kernel: ? ieee80211_prep_channel+0x12b0/0x12b0 [mac80211]
Feb 26 11:09:56 ct523c-de7c kernel: ieee80211_mgd_deauth+0x526/0x1780 [mac80211]
Feb 26 11:09:56 ct523c-de7c kernel: ? check_irq_usage+0xb5/0xa20
Feb 26 11:09:56 ct523c-de7c kernel: ? ieee80211_mgd_assoc+0x5be0/0x5be0 [mac80211]
Feb 26 11:09:56 ct523c-de7c kernel: ? check_path.constprop.0+0x24/0x50
Feb 26 11:09:56 ct523c-de7c kernel: ? check_noncircular+0x7e/0x140
Feb 26 11:09:56 ct523c-de7c kernel: ? lock_is_held_type+0xa5/0x110
Feb 26 11:09:56 ct523c-de7c kernel: cfg80211_mlme_deauth+0x333/0x7a0 [cfg80211]
Feb 26 11:09:56 ct523c-de7c kernel: ? prb_final_commit+0x40/0x40
Feb 26 11:09:56 ct523c-de7c kernel: ? cfg80211_mlme_assoc+0x960/0x960 [cfg80211]
Feb 26 11:09:56 ct523c-de7c kernel: cfg80211_mlme_down+0x16f/0x230 [cfg80211]
Feb 26 11:09:56 ct523c-de7c kernel: ? cfg80211_mlme_disassoc+0x450/0x450 [cfg80211]
Feb 26 11:09:56 ct523c-de7c kernel: ? kfree+0x2ae/0x580
Feb 26 11:09:56 ct523c-de7c kernel: cfg80211_disconnect+0x4d2/0x700 [cfg80211]
Feb 26 11:09:56 ct523c-de7c kernel: cfg80211_netdev_notifier_call+0x661/0x10a0 [cfg80211]
Feb 26 11:09:56 ct523c-de7c kernel: ? __lock_acquire+0x432/0x23b0
Feb 26 11:09:56 ct523c-de7c kernel: ? cfg80211_register_netdevice+0x2a0/0x2a0 [cfg80211]
Feb 26 11:09:56 ct523c-de7c kernel: ? __lock_acquire+0x432/0x23b0
Feb 26 11:09:56 ct523c-de7c kernel: ? __bfs+0x12e/0x220
Feb 26 11:09:56 ct523c-de7c kernel: ? check_irq_usage+0xb5/0xa20
Feb 26 11:09:56 ct523c-de7c kernel: ? __bfs+0x12e/0x220
Feb 26 11:09:56 ct523c-de7c kernel: ? check_irq_usage+0xb5/0xa20
Feb 26 11:09:56 ct523c-de7c kernel: ? check_path.constprop.0+0x24/0x50
Feb 26 11:09:56 ct523c-de7c kernel: ? __bfs+0x12e/0x220
Feb 26 11:09:56 ct523c-de7c kernel: ? __lock_acquire+0x432/0x23b0
Feb 26 11:09:56 ct523c-de7c kernel: ? lock_acquire+0x155/0x2e0
Feb 26 11:09:56 ct523c-de7c kernel: ? packet_notifier+0xd3/0xa70
Feb 26 11:09:56 ct523c-de7c kernel: ? find_held_lock+0x2b/0x80
Feb 26 11:09:56 ct523c-de7c kernel: ? packet_notifier+0x1f0/0xa70
Feb 26 11:09:56 ct523c-de7c kernel: ? lock_release+0xce/0x290
Feb 26 11:09:56 ct523c-de7c kernel: ? packet_notifier+0x1fa/0xa70
Feb 26 11:09:56 ct523c-de7c kernel: ? packet_getname_spkt+0x290/0x290
Feb 26 11:09:56 ct523c-de7c kernel: ? lock_is_held_type+0xa5/0x110
Feb 26 11:09:56 ct523c-de7c kernel: notifier_call_chain+0x97/0x280
Feb 26 11:09:56 ct523c-de7c kernel: __dev_close_many+0xe8/0x670
Feb 26 11:09:56 ct523c-de7c kernel: ? netdev_notify_peers+0x20/0x20
Feb 26 11:09:56 ct523c-de7c kernel: netif_close_many+0x1e6/0x5c0
Feb 26 11:09:56 ct523c-de7c kernel: ? preempt_schedule+0x4c/0x70
Feb 26 11:09:56 ct523c-de7c kernel: ? __dev_close_many+0x670/0x670
Feb 26 11:09:56 ct523c-de7c kernel: ? wake_up_q+0xaf/0x130
Feb 26 11:09:56 ct523c-de7c kernel: netif_close+0x141/0x1d0
Feb 26 11:09:56 ct523c-de7c kernel: ? netif_close_many+0x5c0/0x5c0
Feb 26 11:09:56 ct523c-de7c kernel: dev_close+0x89/0x1f0
Feb 26 11:09:56 ct523c-de7c kernel: cfg80211_shutdown_all_interfaces+0x76/0x190 [cfg80211]
Feb 26 11:09:56 ct523c-de7c kernel: ieee80211_restart_work+0x2c8/0x3c0 [mac80211]
Feb 26 11:09:56 ct523c-de7c kernel: process_one_work+0x83f/0x17b0
Feb 26 11:09:56 ct523c-de7c kernel: ? pwq_dec_nr_in_flight+0xe00/0xe00
Feb 26 11:09:56 ct523c-de7c kernel: ? assign_work+0x168/0x240
Feb 26 11:09:56 ct523c-de7c kernel: ? lock_is_held_type+0xa5/0x110
Feb 26 11:09:56 ct523c-de7c kernel: worker_thread+0x58c/0xfb0
Feb 26 11:09:56 ct523c-de7c kernel: ? __kthread_parkme+0xc6/0x1f0
Feb 26 11:09:56 ct523c-de7c kernel: ? rescuer_thread+0xca0/0xca0
Feb 26 11:09:56 ct523c-de7c kernel: kthread+0x3b7/0x770
Feb 26 11:09:56 ct523c-de7c kernel: ? kthread_is_per_cpu+0xb0/0xb0
Feb 26 11:09:56 ct523c-de7c kernel: ? ret_from_fork+0x17/0x3a0
Feb 26 11:09:56 ct523c-de7c kernel: ? lock_release+0xce/0x290
Feb 26 11:09:56 ct523c-de7c kernel: ? kthread_is_per_cpu+0xb0/0xb0
Feb 26 11:09:56 ct523c-de7c kernel: ret_from_fork+0x28b/0x3a0
Feb 26 11:09:56 ct523c-de7c kernel: ? kthread_is_per_cpu+0xb0/0xb0
Feb 26 11:09:56 ct523c-de7c kernel: ret_from_fork_asm+0x11/0x20
Feb 26 11:09:56 ct523c-de7c kernel: </TASK>
Feb 26 11:09:56 ct523c-de7c kernel: irq event stamp: 1825193
Feb 26 11:09:56 ct523c-de7c kernel: hardirqs last enabled at (1825199): [<ffffffff816116ee>] __up_console_sem+0x5e/0x70
Feb 26 11:09:56 ct523c-de7c kernel: hardirqs last disabled at (1825204): [<ffffffff816116d3>] __up_console_sem+0x43/0x70
Feb 26 11:09:56 ct523c-de7c kernel: softirqs last enabled at (1823870): [<ffffffffa2661752>] __ieee80211_stop_tx_ba_session+0x6b2/0x780 [mac80211]
Feb 26 11:09:56 ct523c-de7c kernel: softirqs last disabled at (1823868): [<ffffffffa26611cd>] __ieee80211_stop_tx_ba_session+0x12d/0x780 [mac80211]
Feb 26 11:09:56 ct523c-de7c kernel: ---[ end trace 0000000000000000 ]---
Feb 26 11:09:56 ct523c-de7c kernel: iwlwifi 0000:28:00.0: Failed to trigger RX queues sync (-5)
Feb 26 11:09:56 ct523c-de7c kernel: ------------[ cut here ]------------
Feb 26 11:09:56 ct523c-de7c kernel: Driver is not allowed to fail if the sta_state is transitioning down the list: -5
Feb 26 11:09:56 ct523c-de7c kernel: WARNING: CPU: 1 PID: 111503 at net/mac80211/sta_info.c:1564 _sta_info_move_state+0x2a5/0x1420 [mac80211]
Feb 26 11:09:56 ct523c-de7c 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 ib_cm ib_core qrtr bnep intel_rapl_msr iTCO_wdt intel_pmc_bxt ee1004 iTCO_vendor_support iwlmld coretemp
intel_rapl_common intel_uncore_frequency intel_uncore_frequency_common snd_hda_codec_intelhdmi snd_hda_codec_hdmi intel_tcc_cooling x86_pkg_temp_thermal
snd_hda_codec_alc662 snd_hda_codec_realtek_lib intel_powerclamp intel_wmi_thunderbolt snd_hda_codec_generic snd_hda_intel snd_intel_dspcfg snd_hda_codec
mac80211 snd_hda_core snd_hwdep snd_seq btusb btbcm snd_seq_device btmtk btrtl btintel snd_pcm iwlwifi bluetooth snd_timer cfg80211 i2c_i801 snd i2c_smbus
soundcore i2c_mux mei_pxp mei_hdcp intel_pch_thermal intel_pmc_core pmt_telemetry pmt_discovery pmt_class intel_pmc_ssram_telemetry intel_vsec acpi_pad bfq nfsd
sch_fq_codel auth_rpcgss nfs_acl lockd grace nfs_localio fuse sunrpc raid1 dm_raid raid456 async_raid6_recov async_memcpy async_pq
Feb 26 11:09:56 ct523c-de7c kernel: async_xor xor async_tx raid6_pq i915 drm_buddy intel_gtt drm_client_lib drm_display_helper drm_kms_helper cec rc_core ttm
agpgart ixgbe mdio igb libie_fwlog i2c_algo_bit dca drm hwmon mei_wdt i2c_core intel_oc_wdt video wmi scsi_dh_rdac scsi_dh_emc scsi_dh_alua dm_multipath [last
unloaded: nfnetlink]
Feb 26 11:09:56 ct523c-de7c kernel: CPU: 1 UID: 0 PID: 111503 Comm: kworker/1:0 Kdump: loaded Tainted: G W 6.18.9+ #18 PREEMPT(full)
Feb 26 11:09:56 ct523c-de7c kernel: Tainted: [W]=WARN
Feb 26 11:09:56 ct523c-de7c kernel: Hardware name: Default string Default string/SKYBAY, BIOS 5.12 02/21/2023
Feb 26 11:09:56 ct523c-de7c kernel: Workqueue: events_freezable ieee80211_restart_work [mac80211]
Feb 26 11:09:56 ct523c-de7c kernel: RIP: 0010:_sta_info_move_state+0x2a5/0x1420 [mac80211]
Feb 26 11:09:56 ct523c-de7c kernel: Code: 85 c0 0f 84 cf 01 00 00 80 3d 0f 7c f1 ff 00 0f 85 c2 01 00 00 89 c6 48 c7 c7 80 bd a0 a2 c6 05 f9 7b f1 ff 01 e8 7b
59 e3 de <0f> 0b e9 a6 01 00 00 41 83 fd 04 0f 85 ce 02 00 00 83 fa 03 0f 85
Feb 26 11:09:56 ct523c-de7c kernel: RSP: 0018:ffff8881f7e97030 EFLAGS: 00010282
Feb 26 11:09:56 ct523c-de7c kernel: RAX: 0000000000000000 RBX: ffff8881377e0188 RCX: 0000000000000001
Feb 26 11:09:56 ct523c-de7c kernel: RDX: 0000000000000027 RSI: 0000000000000004 RDI: ffff88841daa4e48
Feb 26 11:09:56 ct523c-de7c kernel: RBP: ffff8881377e0058 R08: 0000000000000001 R09: ffffed1083b549c9
Feb 26 11:09:56 ct523c-de7c kernel: R10: ffff88841daa4e4b R11: 000000000007dc78 R12: ffff8881377e0050
Feb 26 11:09:56 ct523c-de7c kernel: R13: 0000000000000003 R14: ffff8881377e0180 R15: ffff8881377e0000
Feb 26 11:09:56 ct523c-de7c kernel: FS: 0000000000000000(0000) GS:ffff8884973c7000(0000) knlGS:0000000000000000
Feb 26 11:09:56 ct523c-de7c kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
Feb 26 11:09:56 ct523c-de7c kernel: CR2: 0000557cd9657138 CR3: 000000000509a002 CR4: 00000000003706f0
Feb 26 11:09:56 ct523c-de7c kernel: Call Trace:
Feb 26 11:09:56 ct523c-de7c kernel: <TASK>
Feb 26 11:09:56 ct523c-de7c kernel: ? lock_is_held_type+0xa5/0x110
Feb 26 11:09:56 ct523c-de7c kernel: __sta_info_destroy_part2+0x3e2/0x4a0 [mac80211]
Feb 26 11:09:56 ct523c-de7c kernel: __sta_info_flush+0x409/0x610 [mac80211]
Feb 26 11:09:56 ct523c-de7c kernel: ? __sta_info_destroy+0x30/0x30 [mac80211]
Feb 26 11:09:56 ct523c-de7c kernel: ? ieee80211_bss_info_change_notify+0x53/0x650 [mac80211]
Feb 26 11:09:56 ct523c-de7c kernel: ieee80211_set_disassoc+0x14fb/0x1c10 [mac80211]
Feb 26 11:09:56 ct523c-de7c kernel: ? ieee80211_prep_channel+0x12b0/0x12b0 [mac80211]
Feb 26 11:09:56 ct523c-de7c kernel: ieee80211_mgd_deauth+0x526/0x1780 [mac80211]
Feb 26 11:09:56 ct523c-de7c kernel: ? check_irq_usage+0xb5/0xa20
Feb 26 11:09:56 ct523c-de7c kernel: ? ieee80211_mgd_assoc+0x5be0/0x5be0 [mac80211]
Feb 26 11:09:56 ct523c-de7c kernel: ? check_path.constprop.0+0x24/0x50
Feb 26 11:09:56 ct523c-de7c kernel: ? check_noncircular+0x7e/0x140
Feb 26 11:09:56 ct523c-de7c kernel: ? lock_is_held_type+0xa5/0x110
Feb 26 11:09:56 ct523c-de7c kernel: cfg80211_mlme_deauth+0x333/0x7a0 [cfg80211]
Feb 26 11:09:56 ct523c-de7c kernel: ? prb_final_commit+0x40/0x40
Feb 26 11:09:56 ct523c-de7c kernel: ? cfg80211_mlme_assoc+0x960/0x960 [cfg80211]
Feb 26 11:09:56 ct523c-de7c kernel: cfg80211_mlme_down+0x16f/0x230 [cfg80211]
Feb 26 11:09:56 ct523c-de7c kernel: ? cfg80211_mlme_disassoc+0x450/0x450 [cfg80211]
Feb 26 11:09:56 ct523c-de7c kernel: ? kfree+0x2ae/0x580
Feb 26 11:09:56 ct523c-de7c kernel: cfg80211_disconnect+0x4d2/0x700 [cfg80211]
Feb 26 11:09:56 ct523c-de7c kernel: cfg80211_netdev_notifier_call+0x661/0x10a0 [cfg80211]
Feb 26 11:09:56 ct523c-de7c kernel: ? __lock_acquire+0x432/0x23b0
Feb 26 11:09:56 ct523c-de7c kernel: ? cfg80211_register_netdevice+0x2a0/0x2a0 [cfg80211]
Feb 26 11:09:56 ct523c-de7c kernel: ? __lock_acquire+0x432/0x23b0
Feb 26 11:09:56 ct523c-de7c kernel: ? __bfs+0x12e/0x220
Feb 26 11:09:56 ct523c-de7c kernel: ? check_irq_usage+0xb5/0xa20
Feb 26 11:09:56 ct523c-de7c kernel: ? __bfs+0x12e/0x220
Feb 26 11:09:56 ct523c-de7c kernel: ? check_irq_usage+0xb5/0xa20
Feb 26 11:09:56 ct523c-de7c kernel: ? check_path.constprop.0+0x24/0x50
Feb 26 11:09:56 ct523c-de7c kernel: ? __bfs+0x12e/0x220
Feb 26 11:09:56 ct523c-de7c kernel: ? __lock_acquire+0x432/0x23b0
Feb 26 11:09:56 ct523c-de7c kernel: ? lock_acquire+0x155/0x2e0
Feb 26 11:09:56 ct523c-de7c kernel: ? packet_notifier+0xd3/0xa70
Feb 26 11:09:56 ct523c-de7c kernel: ? find_held_lock+0x2b/0x80
Feb 26 11:09:56 ct523c-de7c kernel: ? packet_notifier+0x1f0/0xa70
Feb 26 11:09:56 ct523c-de7c kernel: ? lock_release+0xce/0x290
Feb 26 11:09:56 ct523c-de7c kernel: ? packet_notifier+0x1fa/0xa70
Feb 26 11:09:56 ct523c-de7c kernel: ? packet_getname_spkt+0x290/0x290
Feb 26 11:09:56 ct523c-de7c kernel: ? lock_is_held_type+0xa5/0x110
Feb 26 11:09:56 ct523c-de7c kernel: notifier_call_chain+0x97/0x280
Feb 26 11:09:56 ct523c-de7c kernel: __dev_close_many+0xe8/0x670
Feb 26 11:09:56 ct523c-de7c kernel: ? netdev_notify_peers+0x20/0x20
Feb 26 11:09:56 ct523c-de7c kernel: netif_close_many+0x1e6/0x5c0
Feb 26 11:09:56 ct523c-de7c kernel: ? preempt_schedule+0x4c/0x70
Feb 26 11:09:56 ct523c-de7c kernel: ? __dev_close_many+0x670/0x670
Feb 26 11:09:56 ct523c-de7c kernel: ? wake_up_q+0xaf/0x130
Feb 26 11:09:56 ct523c-de7c kernel: netif_close+0x141/0x1d0
Feb 26 11:09:56 ct523c-de7c kernel: ? netif_close_many+0x5c0/0x5c0
Feb 26 11:09:56 ct523c-de7c kernel: dev_close+0x89/0x1f0
Feb 26 11:09:56 ct523c-de7c kernel: cfg80211_shutdown_all_interfaces+0x76/0x190 [cfg80211]
Feb 26 11:09:56 ct523c-de7c kernel: ieee80211_restart_work+0x2c8/0x3c0 [mac80211]
Feb 26 11:09:56 ct523c-de7c kernel: process_one_work+0x83f/0x17b0
Feb 26 11:09:56 ct523c-de7c kernel: ? pwq_dec_nr_in_flight+0xe00/0xe00
Feb 26 11:09:56 ct523c-de7c kernel: ? assign_work+0x168/0x240
Feb 26 11:09:56 ct523c-de7c kernel: ? lock_is_held_type+0xa5/0x110
Feb 26 11:09:56 ct523c-de7c kernel: worker_thread+0x58c/0xfb0
Feb 26 11:09:56 ct523c-de7c kernel: ? __kthread_parkme+0xc6/0x1f0
Feb 26 11:09:56 ct523c-de7c kernel: ? rescuer_thread+0xca0/0xca0
Feb 26 11:09:56 ct523c-de7c kernel: kthread+0x3b7/0x770
Feb 26 11:09:56 ct523c-de7c kernel: ? kthread_is_per_cpu+0xb0/0xb0
Feb 26 11:09:56 ct523c-de7c kernel: ? ret_from_fork+0x17/0x3a0
Feb 26 11:09:56 ct523c-de7c kernel: ? lock_release+0xce/0x290
Feb 26 11:09:56 ct523c-de7c kernel: ? kthread_is_per_cpu+0xb0/0xb0
Feb 26 11:09:56 ct523c-de7c kernel: ret_from_fork+0x28b/0x3a0
Feb 26 11:09:56 ct523c-de7c kernel: ? kthread_is_per_cpu+0xb0/0xb0
Feb 26 11:09:56 ct523c-de7c kernel: ret_from_fork_asm+0x11/0x20
Feb 26 11:09:56 ct523c-de7c kernel: </TASK>
Feb 26 11:09:56 ct523c-de7c kernel: irq event stamp: 1826775
Feb 26 11:09:56 ct523c-de7c kernel: hardirqs last enabled at (1826781): [<ffffffff816116ee>] __up_console_sem+0x5e/0x70
Feb 26 11:09:56 ct523c-de7c kernel: hardirqs last disabled at (1826786): [<ffffffff816116d3>] __up_console_sem+0x43/0x70
Feb 26 11:09:56 ct523c-de7c kernel: softirqs last enabled at (1825488): [<ffffffffa26fa978>] ieee80211_clear_fast_rx+0x58/0x80 [mac80211]
Feb 26 11:09:56 ct523c-de7c kernel: softirqs last disabled at (1825486): [<ffffffffa26fa93b>] ieee80211_clear_fast_rx+0x1b/0x80 [mac80211]
Feb 26 11:09:56 ct523c-de7c kernel: ---[ end trace 0000000000000000 ]---
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: [PATCH wireless 0/3] wifi: mt76: Fix possible out-of-bound accesses in mt76 driver
From: Lorenzo Bianconi @ 2026-02-26 21:08 UTC (permalink / raw)
To: Felix Fietkau, Ryder Lee, Shayne Chen, Sean Wang,
Matthias Brugger, AngeloGioacchino Del Regno, StanleyYP Wang,
Peter Chiu, MeiChia Chiu, Leon Yen, Deren Wu, Quan Zhou,
Mingyen Hsieh
Cc: Johannes Berg, Howard Hsu, Bo Jiao, linux-wireless,
linux-arm-kernel, linux-mediatek, Hao Zhang, Nelson Yu
In-Reply-To: <20260226-mt76-addba-req-oob-access-v1-0-b0f6d1ad4850@kernel.org>
[-- Attachment #1: Type: text/plain, Size: 994 bytes --]
> Check mgmt frame length before accessing header fields in order to avoid
> a possible oob access for injected frames.
Hi Felix,
do you think these patches can go directly into the wireless tree or do you
prefer to get them into your tree?
Regards,
Lorenzo
>
> ---
> Lorenzo Bianconi (3):
> wifi: mt76: mt7996: Fix possible oob access in mt7996_mac_write_txwi_80211()
> wifi: mt76: mt7925: Fix possible oob access in mt7925_mac_write_txwi_80211()
> wifi: mt76: Fix possible oob access in mt76_connac2_mac_write_txwi_80211()
>
> drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c | 1 +
> drivers/net/wireless/mediatek/mt76/mt7925/mac.c | 1 +
> drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 1 +
> 3 files changed, 3 insertions(+)
> ---
> base-commit: 8bf22c33e7a172fbc72464f4cc484d23a6b412ba
> change-id: 20260226-mt76-addba-req-oob-access-848280920814
>
> Best regards,
> --
> Lorenzo Bianconi <lorenzo@kernel.org>
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH v1] wifi: ath9k: Fix typo
From: Jeff Johnson @ 2026-02-26 21:29 UTC (permalink / raw)
To: linux-wireless, Alejandro Colomar
Cc: Rajkumar Manoharan, John W. Linville,
Toke Høiland-Jørgensen
In-Reply-To: <6ab107cf786f9d05dc4d84ea4e2d1b219ce108c0.1766355822.git.alx@kernel.org>
On Sun, 21 Dec 2025 23:25:54 +0100, Alejandro Colomar wrote:
> This only worked by chance, because all callers of this macro used the
> same identifiers that were expected by the macro.
>
> $ grep -rn ath_for_each_chanctx
> drivers/net/wireless/ath/ath9k/main.c:1576: ath_for_each_chanctx(sc, ctx)
> drivers/net/wireless/ath/ath9k/main.c:2554: ath_for_each_chanctx(sc, ctx) {
> drivers/net/wireless/ath/ath9k/channel.c:165: ath_for_each_chanctx(sc, ctx) {
> drivers/net/wireless/ath/ath9k/channel.c:291: ath_for_each_chanctx(sc, ctx) {
> drivers/net/wireless/ath/ath9k/channel.c:861: ath_for_each_chanctx(sc, ctx) {
> drivers/net/wireless/ath/ath9k/debug.c:717: ath_for_each_chanctx(sc, ctx) {
> drivers/net/wireless/ath/ath9k/ath9k.h:446:#define ath_for_each_chanctx(_sc, _ctx) \
>
> [...]
Applied, thanks!
[1/1] wifi: ath9k: Fix typo
commit: a8911fbeff8bee4fe3376c5044b64fbf3cceb78e
Best regards,
--
Jeff Johnson <jeff.johnson@oss.qualcomm.com>
^ 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