* [PATCH wireless-next v2 0/3] wifi: add S1G response indication configuration with NDP BA support
@ 2025-12-09 6:24 Ria Thomas
2025-12-09 6:24 ` [PATCH wireless-next v2 1/3] wifi: cfg80211: Add support for S1G Response Indication Configuration Ria Thomas
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Ria Thomas @ 2025-12-09 6:24 UTC (permalink / raw)
To: johannes
Cc: linux-wireless, lachlan.hodges, arien.judge, pradeep.reddy, simon,
Ria Thomas
This patchset adds support for S1G Response Indication configuration;
section 10.3.2.17 and NDP ADDBA/DELBA negotiations; section 11.5.2.2 (b),
in accordance with IEEE 802.11-2024.
The Response Indication (RI) mechanism is unique to S1G and is used to
explicitly signal which type of response frame is expected at SIFS following
an eliciting frame. The RI is signaled in management and action frames and
must be tracked across session setup, which is very much required in
context of Block Ack negotiation.
The NDP-based Block Ack mechanism allows aggregation setup using null data
frames, avoiding legacy ADDBA/DELBA exchanges. When negotiation fails due to
mismatched support, the responder returns a status code indicating NDP
Block Ack is suggested (REJECTED_NDP_BLOCK_ACK_SUGGESTED), as
specified in IEEE 802.11-2024.
Trace sample:
IEEE 802.11 Wireless Management
Fixed parameters
Category code: Block Ack (3)
Action code: NDP ADDBA Request (0x80)
Dialog token: 0x01
Block Ack Parameters: 0x1003, A-MSDUs, Block Ack Policy
.... .... .... ...1 = A-MSDUs: Permitted in QoS Data MPDUs
.... .... .... ..1. = Block Ack Policy: Immediate Block Ack
.... .... ..00 00.. = Traffic Identifier: 0x0
0001 0000 00.. .... = Number of Buffers (1 Buffer = 2304 Bytes): 64
Block Ack Timeout: 0x0000
Block Ack Starting Sequence Control (SSC): 0x0010
.... .... .... 0000 = Fragment: 0
0000 0000 0001 .... = Starting Sequence Number: 1
IEEE 802.11 Wireless Management
Fixed parameters
Category code: Block Ack (3)
Action code: NDP ADDBA Response (0x81)
Dialog token: 0x02
Status code: BlockAck negotiation refused because, due to buffer constraints and other unspecified reasons, the recipient prefers to generate only NDP BlockAck frames (0x006d)
Block Ack Parameters: 0x1002, Block Ack Policy
.... .... .... ...0 = A-MSDUs: Not Permitted
.... .... .... ..1. = Block Ack Policy: Immediate Block Ack
.... .... ..00 00.. = Traffic Identifier: 0x0
0001 0000 00.. .... = Number of Buffers (1 Buffer = 2304 Bytes): 64
Block Ack Timeout: 0x0000
This patchset has been tested on S1G capable Morse Micro hardware and
verifies correct RI signaling and NDP Block Ack negotiation during
association and data exchange.
Changes since v1:
- Fixed kernel docs
Ria Thomas (3):
wifi: cfg80211: Add support for S1G Response Indication Configuration
wifi: mac80211: track S1G Response Indication (RI) and notify drivers
wifi: mac80211: add support for NDP ADDBA/DELBA for S1G
include/linux/ieee80211-ht.h | 3 +++
include/linux/ieee80211-s1g.h | 14 +++++++++++++
include/linux/ieee80211.h | 2 ++
include/net/cfg80211.h | 3 +++
include/net/mac80211.h | 9 +++++++++
include/uapi/linux/nl80211.h | 14 +++++++++++++
net/mac80211/agg-rx.c | 37 ++++++++++++++++++++++++++++++++---
net/mac80211/agg-tx.c | 22 +++++++++++++++++----
net/mac80211/cfg.c | 18 +++++++++++++++++
net/mac80211/debugfs.c | 1 +
net/mac80211/ht.c | 8 +++++---
net/mac80211/ieee80211_i.h | 9 ++++++++-
net/mac80211/iface.c | 3 +++
net/mac80211/link.c | 1 +
net/mac80211/rx.c | 11 +++++++++--
net/mac80211/s1g.c | 23 ++++++++++++++++++++++
net/mac80211/sta_info.h | 2 ++
net/mac80211/util.c | 3 +++
net/wireless/nl80211.c | 24 +++++++++++++++++++++++
net/wireless/rdev-ops.h | 14 +++++++++++++
net/wireless/trace.h | 18 +++++++++++++++++
21 files changed, 226 insertions(+), 13 deletions(-)
--
2.25.1
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH wireless-next v2 1/3] wifi: cfg80211: Add support for S1G Response Indication Configuration 2025-12-09 6:24 [PATCH wireless-next v2 0/3] wifi: add S1G response indication configuration with NDP BA support Ria Thomas @ 2025-12-09 6:24 ` Ria Thomas 2026-01-08 12:27 ` Johannes Berg 2025-12-09 6:24 ` [PATCH wireless-next v2 2/3] wifi: mac80211: track S1G Response Indication (RI) and notify drivers Ria Thomas 2025-12-09 6:24 ` [PATCH wireless-next v2 3/3] wifi: mac80211: add support for NDP ADDBA/DELBA for S1G Ria Thomas 2 siblings, 1 reply; 12+ messages in thread From: Ria Thomas @ 2025-12-09 6:24 UTC (permalink / raw) To: johannes Cc: linux-wireless, lachlan.hodges, arien.judge, pradeep.reddy, simon, Ria Thomas In S1G, a STA distributes a Response Indication (RI) to protect the frame expected at SIFS after the eliciting frame. Introduce a userspace configurable selector for the expected response frame type (i.e., Block Ack, NDP, or no response) after transmitting certain S1G frames. Signed-off-by: Ria Thomas <ria.thomas@morsemicro.com> --- v1 -> v2 - fixed kernel doc --- include/net/cfg80211.h | 3 +++ include/uapi/linux/nl80211.h | 14 ++++++++++++++ net/wireless/nl80211.c | 24 ++++++++++++++++++++++++ net/wireless/rdev-ops.h | 14 ++++++++++++++ net/wireless/trace.h | 18 ++++++++++++++++++ 5 files changed, 73 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 899f267b7cf9..8c538a9e3471 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -4839,6 +4839,7 @@ struct mgmt_frame_regs { * links by calling cfg80211_mlo_reconf_add_done(). When calling * cfg80211_mlo_reconf_add_done() the bss pointer must be given for each * link for which MLO reconfiguration 'add' operation was requested. + * @set_s1g_ri: Set response indication frame type. */ struct cfg80211_ops { int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); @@ -5210,6 +5211,8 @@ struct cfg80211_ops { struct cfg80211_ml_reconf_req *req); int (*set_epcs)(struct wiphy *wiphy, struct net_device *dev, bool val); + int (*set_s1g_ri)(struct wiphy *wiphy, struct net_device *dev, + u8 val); }; /* diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 8134f10e4e6c..4ca86c1fd361 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -1361,6 +1361,10 @@ * user space that the NAN new cluster has been joined. The cluster ID is * indicated by %NL80211_ATTR_MAC. * + * @NL80211_CMD_SET_S1G_RI: This command is used to enable and set the + * response indication type for an S1G station. The frame type is + * indicated by %NL80211_ATTR_S1G_RI_FRAME_TYPE. + * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -1624,6 +1628,8 @@ enum nl80211_commands { NL80211_CMD_NAN_NEXT_DW_NOTIFICATION, NL80211_CMD_NAN_CLUSTER_JOINED, + NL80211_CMD_SET_S1G_RI, + /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ @@ -2973,6 +2979,12 @@ enum nl80211_commands { * primary channel is 2 MHz wide, and the control channel designates * the 1 MHz primary subchannel within that 2 MHz primary. * + * @NL80211_ATTR_S1G_RI_FRAME_TYPE: (u8) Integer attibute used with + * %NL80211_CMD_SET_S1G_RI that represents the RID + * (Response Indication Deferral) information distributed by + * an S1G STA in order to protect the response frame, which is + * expected a SIFS time after the frame that elicits that response. + * * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use @@ -3541,6 +3553,8 @@ enum nl80211_attrs { NL80211_ATTR_S1G_PRIMARY_2MHZ, + NL80211_ATTR_S1G_RI_FRAME_TYPE, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index c961cd42a832..315e17997cb6 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -932,6 +932,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { NLA_POLICY_NESTED(nl80211_s1g_short_beacon), [NL80211_ATTR_BSS_PARAM] = { .type = NLA_FLAG }, [NL80211_ATTR_S1G_PRIMARY_2MHZ] = { .type = NLA_FLAG }, + [NL80211_ATTR_S1G_RI_FRAME_TYPE] = { .type = NLA_U8 }, }; /* policy for the key attributes */ @@ -17826,6 +17827,23 @@ nl80211_epcs_cfg(struct sk_buff *skb, struct genl_info *info) return rdev_set_epcs(rdev, dev, val); } +static int nl80211_set_s1g_ri(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + u8 val; + + if (!rdev->ops->set_s1g_ri) + return -EOPNOTSUPP; + + if (!info->attrs[NL80211_ATTR_S1G_RI_FRAME_TYPE]) + return -EINVAL; + + val = nla_get_u8(info->attrs[NL80211_ATTR_S1G_RI_FRAME_TYPE]); + + return rdev_set_s1g_ri(rdev, dev, val); +} + #define NL80211_FLAG_NEED_WIPHY 0x01 #define NL80211_FLAG_NEED_NETDEV 0x02 #define NL80211_FLAG_NEED_RTNL 0x04 @@ -19031,6 +19049,12 @@ static const struct genl_small_ops nl80211_small_ops[] = { .flags = GENL_UNS_ADMIN_PERM, .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP), }, + { + .cmd = NL80211_CMD_SET_S1G_RI, + .doit = nl80211_set_s1g_ri, + .flags = GENL_UNS_ADMIN_PERM, + .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP), + }, }; static struct genl_family nl80211_fam __ro_after_init = { diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index ac6884bacf3f..d29a4d55f860 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h @@ -1584,4 +1584,18 @@ rdev_set_epcs(struct cfg80211_registered_device *rdev, return ret; } +static inline int +rdev_set_s1g_ri(struct cfg80211_registered_device *rdev, + struct net_device *dev, u8 val) +{ + struct wiphy *wiphy = &rdev->wiphy; + int ret = -EOPNOTSUPP; + + trace_rdev_set_s1g_ri(wiphy, dev, val); + ret = rdev->ops->set_s1g_ri(wiphy, dev, val); + trace_rdev_return_int(wiphy, ret); + + return ret; +} + #endif /* __CFG80211_RDEV_OPS */ diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 2b71f1d867a0..ec200e94e9a6 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -3122,6 +3122,24 @@ TRACE_EVENT(rdev_set_epcs, WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->val) ); +TRACE_EVENT(rdev_set_s1g_ri, + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, + u8 val), + TP_ARGS(wiphy, netdev, val), + TP_STRUCT__entry( + WIPHY_ENTRY + NETDEV_ENTRY + __field(u8, val) + ), + TP_fast_assign( + WIPHY_ASSIGN; + NETDEV_ASSIGN; + __entry->val = val; + ), + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", ri=%u", + WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->val) +); + /************************************************************* * cfg80211 exported functions traces * *************************************************************/ -- 2.25.1 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH wireless-next v2 1/3] wifi: cfg80211: Add support for S1G Response Indication Configuration 2025-12-09 6:24 ` [PATCH wireless-next v2 1/3] wifi: cfg80211: Add support for S1G Response Indication Configuration Ria Thomas @ 2026-01-08 12:27 ` Johannes Berg 2026-01-09 4:00 ` Ria Thomas 0 siblings, 1 reply; 12+ messages in thread From: Johannes Berg @ 2026-01-08 12:27 UTC (permalink / raw) To: Ria Thomas Cc: linux-wireless, lachlan.hodges, arien.judge, pradeep.reddy, simon On Tue, 2025-12-09 at 11:54 +0530, Ria Thomas wrote: > In S1G, a STA distributes a Response Indication (RI) to protect the > frame expected at SIFS after the eliciting frame. Introduce a > userspace configurable selector for the expected response frame > type (i.e., Block Ack, NDP, or no response) after transmitting > certain S1G frames. > + int (*set_s1g_ri)(struct wiphy *wiphy, struct net_device *dev, > + u8 val); I'm generally not very happy with state that simply "exists" at the interface level. The documentation doesn't indicate anything, but the implementation in mac80211 just treats it as such. Does it really _need_ to be that way for any reason, rather than being a setting that is, say, part of the association and/or AP setup? johannes ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH wireless-next v2 1/3] wifi: cfg80211: Add support for S1G Response Indication Configuration 2026-01-08 12:27 ` Johannes Berg @ 2026-01-09 4:00 ` Ria Thomas 2026-01-13 8:50 ` Johannes Berg 0 siblings, 1 reply; 12+ messages in thread From: Ria Thomas @ 2026-01-09 4:00 UTC (permalink / raw) To: Johannes Berg Cc: linux-wireless, lachlan.hodges, arien.judge, pradeep.reddy, simon On Thu, Jan 08, 2026 at 01:27:44PM +0100, Johannes Berg wrote: > On Tue, 2025-12-09 at 11:54 +0530, Ria Thomas wrote: > > In S1G, a STA distributes a Response Indication (RI) to protect the > > frame expected at SIFS after the eliciting frame. Introduce a > > userspace configurable selector for the expected response frame > > type (i.e., Block Ack, NDP, or no response) after transmitting > > certain S1G frames. > > > > + int (*set_s1g_ri)(struct wiphy *wiphy, struct net_device *dev, > > + u8 val); > > I'm generally not very happy with state that simply "exists" at the > interface level. The documentation doesn't indicate anything, but the > implementation in mac80211 just treats it as such. > > Does it really _need_ to be that way for any reason, rather than being a > setting that is, say, part of the association and/or AP setup? > > johannes The WFA HaLow test plan includes explicit test cases that require configuring the Response Indication on both the AP and the STA. In these scenarios, the Response Indication is not negotiated as part of association, but is instead set dynamically after the association has been established. As a result, the Response Indication needs to be configurable at runtime from userspace and applied to the driver/firmware independently of association or AP setup. This requirement motivated the introduction of a userspace‑configurable selector that updates the Response Indicationstate on an already active interface. If there is a preferred way to better scope this configuration while still supporting post‑association updates mandated by the WFA test plan, I am happy to explore that. Ria ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH wireless-next v2 1/3] wifi: cfg80211: Add support for S1G Response Indication Configuration 2026-01-09 4:00 ` Ria Thomas @ 2026-01-13 8:50 ` Johannes Berg 2026-01-16 5:31 ` Ria Thomas 2026-02-06 6:11 ` Ria Thomas 0 siblings, 2 replies; 12+ messages in thread From: Johannes Berg @ 2026-01-13 8:50 UTC (permalink / raw) To: Ria Thomas Cc: linux-wireless, lachlan.hodges, arien.judge, pradeep.reddy, simon On Fri, 2026-01-09 at 09:30 +0530, Ria Thomas wrote: > The WFA HaLow test plan includes explicit test cases that require > configuring the Response Indication on both the AP and the STA. > In these scenarios, the Response Indication is not negotiated as > part of association, but is instead set dynamically after the > association has been established. Fair. > As a result, the Response Indication needs to be configurable at > runtime from userspace and applied to the driver/firmware > independently of association or AP setup. This requirement > motivated the introduction of a userspace‑configurable selector > that updates the Response Indication state on an already active > interface. Actually, reading the spec, are you sure it's even on an *interface* scope? A lot of this seems to me like it should be per intended receiver, and you need to know its capabilities for generating the intended response? If it were per-STA then I think that'd have a much more natural lifetime (since it cannot exceed that of the STA) which seems far better to me. But you're going to have to help me understand it :) johannes ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH wireless-next v2 1/3] wifi: cfg80211: Add support for S1G Response Indication Configuration 2026-01-13 8:50 ` Johannes Berg @ 2026-01-16 5:31 ` Ria Thomas 2026-02-06 6:11 ` Ria Thomas 1 sibling, 0 replies; 12+ messages in thread From: Ria Thomas @ 2026-01-16 5:31 UTC (permalink / raw) To: Johannes Berg Cc: linux-wireless, lachlan.hodges, arien.judge, pradeep.reddy, simon On Tue, Jan 13, 2026 at 09:50:44AM +0100, Johannes Berg wrote: > > Actually, reading the spec, are you sure it's even on an *interface* > scope? A lot of this seems to me like it should be per intended > receiver, and you need to know its capabilities for generating the > intended response? > After reviewing the IEEE 802.11ah specification and correlating it with the WFA HaLow certification tests, it is clear that Response Indication is not intended to be a per-receiver or per-peer configuration. Per IEEE Std 802.11-2024, 10.3.2.17, Response Indication is a TXVECTOR parameter set by the transmitting MAC entity (AP or STA) to advertise the expected response type for a specific PPDU and to protect the corresponding response PPDU expected SIFS later. As a TXVECTOR parameter, Response Indication is selected for each transmission and applies at the PPDU level; it is not defined as persistent state associated with a specific peer STA. The selection of a Response Indication value is governed by the established BSS context and the protocol rules defined by the standard for when a response is expected, rather than by any explicit per-peer Response Indication capability negotiation. Accordingly, the implementation treats Response Indication as a per-interface (per MAC/VIF) transmit configuration, applied when constructing the TXVECTOR for each PPDU. Response Indication therefore remains a local, per-transmission decision, governed by the applicable protocol rules and operating context, rather than by persistent per-receiver configuration. I hope this clarifies the rationale behind the current approach. I am happy to discuss further if there are specific scenarios you would like to examine. Ria ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH wireless-next v2 1/3] wifi: cfg80211: Add support for S1G Response Indication Configuration 2026-01-13 8:50 ` Johannes Berg 2026-01-16 5:31 ` Ria Thomas @ 2026-02-06 6:11 ` Ria Thomas 2026-02-06 7:57 ` Johannes Berg 1 sibling, 1 reply; 12+ messages in thread From: Ria Thomas @ 2026-02-06 6:11 UTC (permalink / raw) To: Johannes Berg Cc: linux-wireless, lachlan.hodges, arien.judge, pradeep.reddy, simon > Actually, reading the spec, are you sure it's even on an *interface* > scope? A lot of this seems to me like it should be per intended > receiver, and you need to know its capabilities for generating the > intended response? > > If it were per-STA then I think that'd have a much more natural lifetime > (since it cannot exceed that of the STA) which seems far better to me. > Just wanted to follow up on the earlier reply and check if you've had a chance to review it. To explain the implementation a bit more clearly: The issue is that response indication from a MAC perspective doesn't really make sense elsewhere. It's simply embedded into the PPDU for the VIF that has response indication configured, and the receiver uses it to determine which type (if any) of ACK to respond with. So it's entirely handled by the lower MAC besides of course setting the value from the upper MAC. While it may seem more ideal to sit in a per station or something similar where the lifetimes are more natural, there isn't a capability exchange that occurs - configuration is more for local transmitter config. On the receiver side, it isn't communicated to the upper MAC at all - so considering it as a STA entry dosen't really make much sense. Please let me know if you see any issues with this approach. Looking forward to hear your thoughts on this whenever you have a chance Ria ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH wireless-next v2 1/3] wifi: cfg80211: Add support for S1G Response Indication Configuration 2026-02-06 6:11 ` Ria Thomas @ 2026-02-06 7:57 ` Johannes Berg 2026-02-12 8:43 ` Ria Thomas 0 siblings, 1 reply; 12+ messages in thread From: Johannes Berg @ 2026-02-06 7:57 UTC (permalink / raw) To: Ria Thomas Cc: linux-wireless, lachlan.hodges, arien.judge, pradeep.reddy, simon Hi Ria, > Just wanted to follow up on the earlier reply and check if you've > had a chance to review it. Sorry, I had seen it, but it took a backseat to shuffling patches and other things I had to do, on top of having been somewhat sick until early this week. > To explain the implementation a bit more clearly: The issue is that > response indication from a MAC perspective doesn't really make sense > elsewhere. It's simply embedded into the PPDU for the VIF that has > response indication configured, and the receiver uses it to determine > which type (if any) of ACK to respond with. So it's entirely handled > by the lower MAC besides of course setting the value from the upper MAC. Let me summarise that how I understand what you said, and the spec: The transmitter MAC sets the RESPONSE_INDICATION in the TXVECTOR for the PHY-TXSTART.request primitive. The (S1G) PHY then embeds this in the preamble, so that the receiver can react accordingly. There are certain rules for both transmitter and receiver, but the transmitter MAC has a certain set of choices for how to set this. And for the certification test, presumably the choice for testbed STA (for certain frames at least, I guess not intended to break the rules for cases where there's no/less choice) is not meant to be left to the implementation, but rather meant to be set, presumably to check that the receiver reacts correctly. (If I got this wrong so far, probably better to stop reading here and tell me.) > While it may seem more ideal to sit in a per station or something similar > where the lifetimes are more natural, there isn't a capability exchange > that occurs - configuration is more for local transmitter config. On the > receiver side, it isn't communicated to the upper MAC at all - so considering > it as a STA entry dosen't really make much sense. Yes, I can understand that argument in some way. OTOH, while I'd tend to agree that it somewhat argues against it being a per-STA configuration, I'm not really sure it really argues _for_ it being an interface config. Based on the understanding I outlined above, I'd argue the spec doesn't really say anything to this effect at all. It leaves a choice to the MAC implementation on how to set it for every individual PPDU it sends. Now, clearly we can't very well have an implementation where something in userspace decides for every PPDU, so we have to make an implementation choice of how the MAC decides. You've made a choice here that it should be decided per interface, and due to lifetime issue I've outlined a choice where it decides per (destination) STA. I don't think from a spec perspective this choice really matters at all, since the setting of the TXVECTOR is independent for each PHY-TXSTART.request. Now that I've described it this way, I think the biggest question I have is actually how, if at all, we need this in a non-testing scenario? Which choices of implementation makes sense there? What are the use cases for this other than testing? I think this could inform the implementation choice here. (And as an aside, if it ends up being only for testing, then I think we can also simply stick it in mac80211 debugfs rather than building out the elaborate cfg80211/nl80211 infrastructure. But we still need to decide where it should live, although in that case I'd be more willing to accept an interface setting despite the lifetime issues.) johannes ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH wireless-next v2 1/3] wifi: cfg80211: Add support for S1G Response Indication Configuration 2026-02-06 7:57 ` Johannes Berg @ 2026-02-12 8:43 ` Ria Thomas 2026-02-17 11:41 ` Johannes Berg 0 siblings, 1 reply; 12+ messages in thread From: Ria Thomas @ 2026-02-12 8:43 UTC (permalink / raw) To: Johannes Berg Cc: linux-wireless, lachlan.hodges, arien.judge, pradeep.reddy, simon Hi Johannes, Thanks for the feedback. > And for the certification test, presumably the choice for testbed STA > (for certain frames at least, I guess not intended to break the rules > for cases where there's no/less choice) is not meant to be left to the > implementation, but rather meant to be set, presumably to check that the > receiver reacts correctly. Yes, for certification testing this configuration is intended to verify that the receiver of the PPDU correctly interprets and acts upon the Response Indication value set by the transmitter. > Now that I've described it this way, I think the biggest question I have > is actually how, if at all, we need this in a non-testing scenario? This configuration is not expected to be used in any non-testing cases. > But we still need to decide where it should live, although in > that case I'd be more willing to accept an interface setting despite > the lifetime issues.) > We think it makes the most sense to treat Response Indication as an interface-level setting as it avoids introducing peer-specific state that is neither negotiated nor maintained by the protocol. That said as the response indication is only a test configuration there is expected to be some changes to the upcoming patches. I would preferably submit the response indication configuration as a single patch and NDP ADDBA/DELBA negotiations as a different patch. This would open up two different new mail chains for two patches which is different from the current one. Looking forward to hear your thoughts on this. Ria ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH wireless-next v2 1/3] wifi: cfg80211: Add support for S1G Response Indication Configuration 2026-02-12 8:43 ` Ria Thomas @ 2026-02-17 11:41 ` Johannes Berg 0 siblings, 0 replies; 12+ messages in thread From: Johannes Berg @ 2026-02-17 11:41 UTC (permalink / raw) To: Ria Thomas Cc: linux-wireless, lachlan.hodges, arien.judge, pradeep.reddy, simon Hi, > > But we still need to decide where it should live, although in > > that case I'd be more willing to accept an interface setting despite > > the lifetime issues.) > > > > We think it makes the most sense to treat Response Indication as an > interface-level setting as it avoids introducing peer-specific state > that is neither negotiated nor maintained by the protocol. Fair. I don't really think it makes a huge difference - this state is not negotiated nor maintained by the protocol at the interface level either, after all :-) In a way I don't think it's a good argument either way I guess, but if it's only a debug config I also don't care much (and we already have things like tkip_mic_test that are in a way similar.) > That said as the response indication is only a test configuration there > is expected to be some changes to the upcoming patches. I would preferably > submit the response indication configuration as a single patch and NDP > ADDBA/DELBA negotiations as a different patch. This would open up two different > new mail chains for two patches which is different from the current one. Sure, if it can be separated I have no issues with that. johannes ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH wireless-next v2 2/3] wifi: mac80211: track S1G Response Indication (RI) and notify drivers 2025-12-09 6:24 [PATCH wireless-next v2 0/3] wifi: add S1G response indication configuration with NDP BA support Ria Thomas 2025-12-09 6:24 ` [PATCH wireless-next v2 1/3] wifi: cfg80211: Add support for S1G Response Indication Configuration Ria Thomas @ 2025-12-09 6:24 ` Ria Thomas 2025-12-09 6:24 ` [PATCH wireless-next v2 3/3] wifi: mac80211: add support for NDP ADDBA/DELBA for S1G Ria Thomas 2 siblings, 0 replies; 12+ messages in thread From: Ria Thomas @ 2025-12-09 6:24 UTC (permalink / raw) To: johannes Cc: linux-wireless, lachlan.hodges, arien.judge, pradeep.reddy, simon, Ria Thomas S1G STAs advertise a Response Indication (RI) that signals which immediate response (at SIFS) is expected to the eliciting frame. Updates mac80211 to track this configured response indication throughout the device's operation. It ensures that changes are recognized and communicated to the driver layer via BSS_CHANGED_S1G_RI, allowing firmware/hardware to be configured accordingly while also maintaining correct behaviour during interface restarts and ensuring that non-S1G interfaces are unaffected. enum defined for the RI types per IEEE Std 802.11-2024 Table 10-7. Signed-off-by: Ria Thomas <ria.thomas@morsemicro.com> --- v1 -> v2 - fixed kernel doc --- include/linux/ieee80211-s1g.h | 14 ++++++++++++++ include/net/mac80211.h | 5 +++++ net/mac80211/cfg.c | 18 ++++++++++++++++++ net/mac80211/link.c | 1 + net/mac80211/util.c | 3 +++ 5 files changed, 41 insertions(+) diff --git a/include/linux/ieee80211-s1g.h b/include/linux/ieee80211-s1g.h index 5b9ed2dcc00e..df5e37d07bf5 100644 --- a/include/linux/ieee80211-s1g.h +++ b/include/linux/ieee80211-s1g.h @@ -109,6 +109,20 @@ enum ieee80211_s1g_pri_chanwidth { IEEE80211_S1G_PRI_CHANWIDTH_1MHZ = 1, }; +/** + * enum ieee80211_s1g_ri - S1G Response Indication type + * @IEEE80211_S1G_RI_NO_RESPONSE: No immediate response + * @IEEE80211_S1G_RI_NDP_RESPONSE: NDP Ack/CTS/BlockAck + * @IEEE80211_S1G_RI_NORMAL_RESPONSE: Ack/CTS/BlockAck/TACK + * @IEEE80211_S1G_RI_LONG_RESPONSE: Not an individual control response frame + */ +enum ieee80211_s1g_ri { + IEEE80211_S1G_RI_NO_RESPONSE = 0, + IEEE80211_S1G_RI_NDP_RESPONSE = 1, + IEEE80211_S1G_RI_NORMAL_RESPONSE = 2, + IEEE80211_S1G_RI_LONG_RESPONSE = 3, +}; + /** * struct ieee80211_s1g_bcn_compat_ie - S1G Beacon Compatibility element * @compat_info: Compatibility Information diff --git a/include/net/mac80211.h b/include/net/mac80211.h index c2e49542626c..89084ae46d26 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -365,6 +365,7 @@ struct ieee80211_vif_chanctx_switch { * @BSS_CHANGED_MLD_VALID_LINKS: MLD valid links status changed. * @BSS_CHANGED_MLD_TTLM: negotiated TID to link mapping was changed * @BSS_CHANGED_TPE: transmit power envelope changed + * @BSS_CHANGED_S1G_RI: S1G response indication type changed */ enum ieee80211_bss_change { BSS_CHANGED_ASSOC = 1<<0, @@ -402,6 +403,7 @@ enum ieee80211_bss_change { BSS_CHANGED_MLD_VALID_LINKS = BIT_ULL(33), BSS_CHANGED_MLD_TTLM = BIT_ULL(34), BSS_CHANGED_TPE = BIT_ULL(35), + BSS_CHANGED_S1G_RI = BIT_ULL(36), /* when adding here, make sure to change ieee80211_reconfig */ }; @@ -760,6 +762,8 @@ struct ieee80211_parsed_tpe { * (as opposed to hearing its value from another link's beacon). * @s1g_long_beacon_period: number of beacon intervals between each long * beacon transmission. + * @s1g_ri: Response indication type expected for the frame sent on this + * BSS */ struct ieee80211_bss_conf { struct ieee80211_vif *vif; @@ -861,6 +865,7 @@ struct ieee80211_bss_conf { u8 bss_param_ch_cnt_link_id; u8 s1g_long_beacon_period; + enum ieee80211_s1g_ri s1g_ri; }; /** diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index b51c2c8584ae..ae47ae70d36a 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -5533,6 +5533,23 @@ ieee80211_set_epcs(struct wiphy *wiphy, struct net_device *dev, bool enable) return ieee80211_mgd_set_epcs(sdata, enable); } +static int +ieee80211_set_s1g_ri(struct wiphy *wiphy, struct net_device *dev, u8 ri) +{ + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + + if (!sdata->vif.cfg.s1g) + return -EOPNOTSUPP; + + sdata->vif.bss_conf.s1g_ri = ri; + + if (ieee80211_sdata_running(sdata)) + ieee80211_link_info_change_notify(sdata, &sdata->deflink, + BSS_CHANGED_S1G_RI); + + return 0; +} + const struct cfg80211_ops mac80211_config_ops = { .add_virtual_intf = ieee80211_add_iface, .del_virtual_intf = ieee80211_del_iface, @@ -5649,4 +5666,5 @@ const struct cfg80211_ops mac80211_config_ops = { .get_radio_mask = ieee80211_get_radio_mask, .assoc_ml_reconf = ieee80211_assoc_ml_reconf, .set_epcs = ieee80211_set_epcs, + .set_s1g_ri = ieee80211_set_s1g_ri, }; diff --git a/net/mac80211/link.c b/net/mac80211/link.c index 1e05845872af..4bf8155b4935 100644 --- a/net/mac80211/link.c +++ b/net/mac80211/link.c @@ -109,6 +109,7 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata, link->ap_power_level = IEEE80211_UNSET_POWER_LEVEL; link->user_power_level = sdata->local->user_power_level; link_conf->txpower = INT_MIN; + link_conf->s1g_ri = IEEE80211_S1G_RI_NDP_RESPONSE; wiphy_work_init(&link->csa.finalize_work, ieee80211_csa_finalize_work); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 0c46009a3d63..309a3a3b9441 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1960,6 +1960,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) ieee80211_assign_chanctx(local, sdata, link); } + if (sdata->vif.cfg.s1g) + changed |= BSS_CHANGED_S1G_RI; + switch (sdata->vif.type) { case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_MONITOR: -- 2.25.1 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH wireless-next v2 3/3] wifi: mac80211: add support for NDP ADDBA/DELBA for S1G 2025-12-09 6:24 [PATCH wireless-next v2 0/3] wifi: add S1G response indication configuration with NDP BA support Ria Thomas 2025-12-09 6:24 ` [PATCH wireless-next v2 1/3] wifi: cfg80211: Add support for S1G Response Indication Configuration Ria Thomas 2025-12-09 6:24 ` [PATCH wireless-next v2 2/3] wifi: mac80211: track S1G Response Indication (RI) and notify drivers Ria Thomas @ 2025-12-09 6:24 ` Ria Thomas 2 siblings, 0 replies; 12+ messages in thread From: Ria Thomas @ 2025-12-09 6:24 UTC (permalink / raw) To: johannes Cc: linux-wireless, lachlan.hodges, arien.judge, pradeep.reddy, simon, Ria Thomas S1G defines use of NDP Block Ack (BA) for aggregation, requiring negotiation of NDP ADDBA/DELBA action frames. When an S1G STA supports HT-immediate BA, it may reject legacy ADDBA requests, indicating preference for NDP Block Ack. Introduce support for NDP ADDBA and DELBA exchange in mac80211. The implementation negotiates the BA mechanism during setup based on station capabilities and driver support (IEEE80211_HW_SUPPORTS_NDP_BLOCKACK). If negotiation fails due to mismatched expectations, a rejection with status code WLAN_STATUS_REJECTED_NDP_BLOCK_ACK_SUGGESTED is returned as per IEEE 802.11-2024. The selected response indication (RI) is updated upon successful negotiation and NDP preference is maintained throughout session setup, management and teardown on both TX and RX paths Signed-off-by: Ria Thomas <ria.thomas@morsemicro.com> --- include/linux/ieee80211-ht.h | 3 +++ include/linux/ieee80211.h | 2 ++ include/net/mac80211.h | 4 ++++ net/mac80211/agg-rx.c | 37 +++++++++++++++++++++++++++++++++--- net/mac80211/agg-tx.c | 22 +++++++++++++++++---- net/mac80211/debugfs.c | 1 + net/mac80211/ht.c | 8 +++++--- net/mac80211/ieee80211_i.h | 9 ++++++++- net/mac80211/iface.c | 3 +++ net/mac80211/rx.c | 11 +++++++++-- net/mac80211/s1g.c | 23 ++++++++++++++++++++++ net/mac80211/sta_info.h | 2 ++ 12 files changed, 112 insertions(+), 13 deletions(-) diff --git a/include/linux/ieee80211-ht.h b/include/linux/ieee80211-ht.h index 21bbf470540f..7612b72f9c7c 100644 --- a/include/linux/ieee80211-ht.h +++ b/include/linux/ieee80211-ht.h @@ -281,6 +281,9 @@ enum ieee80211_back_actioncode { WLAN_ACTION_ADDBA_REQ = 0, WLAN_ACTION_ADDBA_RESP = 1, WLAN_ACTION_DELBA = 2, + WLAN_ACTION_NDP_ADDBA_REQ = 128, + WLAN_ACTION_NDP_ADDBA_RESP = 129, + WLAN_ACTION_NDP_DELBA = 130, }; /* BACK (block-ack) parties */ diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 96439de55f07..b6a1492cdb4d 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -1492,6 +1492,8 @@ enum ieee80211_statuscode { WLAN_STATUS_REJECT_DSE_BAND = 96, WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL = 99, WLAN_STATUS_DENIED_DUE_TO_SPECTRUM_MANAGEMENT = 103, + /* 802.11ah */ + WLAN_STATUS_REJECTED_NDP_BLOCK_ACK_SUGGESTED = 109, /* 802.11ai */ WLAN_STATUS_FILS_AUTHENTICATION_FAILURE = 112, WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER = 113, diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 89084ae46d26..51119eec4ca8 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2874,6 +2874,9 @@ struct ieee80211_txq { * HW flag so drivers can opt in according to their own control, e.g. in * testing. * + * @IEEE80211_HW_SUPPORTS_NDP_BLOCKACK: HW can transmit/receive S1G NDP + * BlockAck frames. + * * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays */ enum ieee80211_hw_flags { @@ -2934,6 +2937,7 @@ enum ieee80211_hw_flags { IEEE80211_HW_DISALLOW_PUNCTURING, IEEE80211_HW_HANDLES_QUIET_CSA, IEEE80211_HW_STRICT, + IEEE80211_HW_SUPPORTS_NDP_BLOCKACK, /* keep last, obviously */ NUM_IEEE80211_HW_FLAGS diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index 7da909d78c68..65ae8bc1d96a 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c @@ -94,7 +94,8 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, /* check if this is a self generated aggregation halt */ if (initiator == WLAN_BACK_RECIPIENT && tx) ieee80211_send_delba(sta->sdata, sta->sta.addr, - tid, WLAN_BACK_RECIPIENT, reason); + tid, WLAN_BACK_RECIPIENT, reason, + ieee80211_s1g_use_ndp_ba(sta->sdata, sta)); /* * return here in case tid_rx is not assigned - which will happen if @@ -240,6 +241,7 @@ static void ieee80211_send_addba_resp(struct sta_info *sta, u8 *da, u16 tid, struct sk_buff *skb; struct ieee80211_mgmt *mgmt; bool amsdu = ieee80211_hw_check(&local->hw, SUPPORTS_AMSDU_IN_AMPDU); + bool use_ndp = ieee80211_s1g_use_ndp_ba(sdata, sta); u16 capab; skb = dev_alloc_skb(sizeof(*mgmt) + @@ -253,7 +255,8 @@ static void ieee80211_send_addba_resp(struct sta_info *sta, u8 *da, u16 tid, skb_put(skb, 1 + sizeof(mgmt->u.action.u.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.action_code = use_ndp ? + WLAN_ACTION_NDP_ADDBA_RESP : WLAN_ACTION_ADDBA_RESP; mgmt->u.action.u.addba_resp.dialog_token = dialog_token; capab = u16_encode_bits(amsdu, IEEE80211_ADDBA_PARAM_AMSDU_MASK); @@ -275,6 +278,7 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta, u8 dialog_token, u16 timeout, u16 start_seq_num, u16 ba_policy, u16 tid, u16 buf_size, bool tx, bool auto_seq, + bool req_ndp, const u8 addba_ext_data) { struct ieee80211_local *local = sta->sdata->local; @@ -300,6 +304,18 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta, goto end; } + if (tx && ieee80211_s1g_use_ndp_ba(sta->sdata, sta) && !req_ndp) { + /* + * According to IEEE 802.11-2024: Inform S1G originator + * ADDBA rejected as NDP BlockAck is preferred + */ + status = WLAN_STATUS_REJECTED_NDP_BLOCK_ACK_SUGGESTED; + ht_dbg(sta->sdata, + "Rejecting AddBA Req from %pM tid %u - require NDP BlockAck\n", + sta->sta.addr, tid); + goto end; + } + if (!sta->sta.valid_links && !sta->sta.deflink.ht_cap.ht_supported && !sta->sta.deflink.he_cap.has_he && @@ -457,6 +473,18 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta, end: if (status == WLAN_STATUS_SUCCESS) { + /* + * Keep user-forced NO_RESPONSE; otherwise + * track negotiated BA type + */ + if (sta->sdata->vif.bss_conf.s1g_ri != + IEEE80211_S1G_RI_NO_RESPONSE) { + u8 ri = req_ndp ? IEEE80211_S1G_RI_NDP_RESPONSE : + IEEE80211_S1G_RI_NORMAL_RESPONSE; + + ieee80211_s1g_update_ri(sta->sdata, + &sta->sdata->deflink, ri); + } __set_bit(tid, sta->ampdu_mlme.agg_session_valid); __clear_bit(tid, sta->ampdu_mlme.unexpected_agg); sta->ampdu_mlme.tid_rx_token[tid] = dialog_token; @@ -473,6 +501,8 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, struct ieee80211_mgmt *mgmt, size_t len) { + bool req_ndp = mgmt->u.action.u.addba_req.action_code == + WLAN_ACTION_NDP_ADDBA_REQ; u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num; u8 dialog_token, addba_ext_data; @@ -497,7 +527,8 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, __ieee80211_start_rx_ba_session(sta, dialog_token, timeout, start_seq_num, ba_policy, tid, - buf_size, true, false, addba_ext_data); + buf_size, true, false, + req_ndp, addba_ext_data); } void ieee80211_manage_rx_ba_offl(struct ieee80211_vif *vif, diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index d981b0fc57bf..17d9c047134d 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -60,7 +60,7 @@ static void ieee80211_send_addba_request(struct sta_info *sta, u16 tid, u8 dialog_token, u16 start_seq_num, - u16 agg_size, u16 timeout) + u16 agg_size, u16 timeout, bool ndp) { struct ieee80211_sub_if_data *sdata = sta->sdata; struct ieee80211_local *local = sdata->local; @@ -80,7 +80,8 @@ static void ieee80211_send_addba_request(struct sta_info *sta, u16 tid, skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_req)); mgmt->u.action.category = WLAN_CATEGORY_BACK; - mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ; + mgmt->u.action.u.addba_req.action_code = ndp ? + WLAN_ACTION_NDP_ADDBA_REQ : WLAN_ACTION_ADDBA_REQ; mgmt->u.action.u.addba_req.dialog_token = dialog_token; capab = IEEE80211_ADDBA_PARAM_AMSDU_MASK; @@ -484,7 +485,8 @@ static void ieee80211_send_addba_with_timeout(struct sta_info *sta, /* send AddBA request */ ieee80211_send_addba_request(sta, tid, tid_tx->dialog_token, - tid_tx->ssn, buf_size, tid_tx->timeout); + tid_tx->ssn, buf_size, tid_tx->timeout, + tid_tx->ndp); WARN_ON(test_and_set_bit(HT_AGG_STATE_SENT_ADDBA, &tid_tx->state)); } @@ -521,6 +523,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) */ synchronize_net(); + tid_tx->ndp = ieee80211_s1g_use_ndp_ba(sdata, sta); params.ssn = sta->tid_seq[tid] >> 4; ret = drv_ampdu_action(local, sdata, ¶ms); tid_tx->ssn = params.ssn; @@ -940,7 +943,9 @@ void ieee80211_stop_tx_ba_cb(struct sta_info *sta, int tid, if (send_delba) ieee80211_send_delba(sdata, sta->sta.addr, tid, - WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); + WLAN_BACK_INITIATOR, + WLAN_REASON_QSTA_NOT_USE, + tid_tx->ndp); } void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, @@ -973,6 +978,8 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, { struct tid_ampdu_tx *tid_tx; struct ieee80211_txq *txq; + struct ieee80211_sub_if_data *sdata = sta->sdata; + struct ieee80211_link_data *link = &sdata->deflink; u16 capab, tid, buf_size; bool amsdu; @@ -1054,6 +1061,13 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, tid_tx->last_tx = jiffies; } + if (sdata->vif.bss_conf.s1g_ri != + IEEE80211_S1G_RI_NO_RESPONSE) { + u8 ri = tid_tx->ndp ? IEEE80211_S1G_RI_NDP_RESPONSE : + IEEE80211_S1G_RI_NORMAL_RESPONSE; + + ieee80211_s1g_update_ri(sdata, link, ri); + } } else { __ieee80211_stop_tx_ba_session(sta, tid, AGG_STOP_DECLINED); } diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index d02f07368c51..e8d0a8b71d59 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -490,6 +490,7 @@ static const char *hw_flag_names[] = { FLAG(DISALLOW_PUNCTURING), FLAG(HANDLES_QUIET_CSA), FLAG(STRICT), + FLAG(SUPPORTS_NDP_BLOCKACK), #undef FLAG }; diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 1c82a28b03de..ac67bf55f983 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c @@ -379,7 +379,7 @@ void ieee80211_ba_session_work(struct wiphy *wiphy, struct wiphy_work *work) sta->ampdu_mlme.tid_rx_manage_offl)) __ieee80211_start_rx_ba_session(sta, 0, 0, 0, 1, tid, IEEE80211_MAX_AMPDU_BUF_HT, - false, true, 0); + false, true, false, 0); if (test_and_clear_bit(tid + IEEE80211_NUM_TIDS, sta->ampdu_mlme.tid_rx_manage_offl)) @@ -455,7 +455,8 @@ void ieee80211_ba_session_work(struct wiphy *wiphy, struct wiphy_work *work) void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, const u8 *da, u16 tid, - u16 initiator, u16 reason_code) + u16 initiator, u16 reason_code, + bool use_ndp) { struct ieee80211_local *local = sdata->local; struct sk_buff *skb; @@ -472,7 +473,8 @@ void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, skb_put(skb, 1 + sizeof(mgmt->u.action.u.delba)); mgmt->u.action.category = WLAN_CATEGORY_BACK; - mgmt->u.action.u.delba.action_code = WLAN_ACTION_DELBA; + mgmt->u.action.u.delba.action_code = use_ndp ? + WLAN_ACTION_NDP_DELBA : WLAN_ACTION_DELBA; params = (u16)(initiator << 11); /* bit 11 initiator */ params |= (u16)(tid << 12); /* bit 15:12 TID number */ diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 9d9313eee59f..265b41d07243 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -2185,7 +2185,8 @@ bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata, struct link_sta_info *link_sta); void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, const u8 *da, u16 tid, - u16 initiator, u16 reason_code); + u16 initiator, u16 reason_code, + bool use_ndp); int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, enum ieee80211_smps_mode smps, const u8 *da, const u8 *bssid, int link_id); @@ -2201,6 +2202,7 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta, u8 dialog_token, u16 timeout, u16 start_seq_num, u16 ba_policy, u16 tid, u16 buf_size, bool tx, bool auto_seq, + bool req_ndp, const u8 addba_ext_data); void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, enum ieee80211_agg_stop_reason reason); @@ -2326,6 +2328,11 @@ void ieee80211_s1g_status_twt_action(struct ieee80211_sub_if_data *sdata, void ieee80211_s1g_cap_to_sta_s1g_cap(struct ieee80211_sub_if_data *sdata, const struct ieee80211_s1g_cap *s1g_cap_ie, struct link_sta_info *link_sta); +bool ieee80211_s1g_use_ndp_ba(const struct ieee80211_sub_if_data *sdata, + const struct sta_info *sta); +void ieee80211_s1g_update_ri(struct ieee80211_sub_if_data *sdata, + struct ieee80211_link_data *link, + enum ieee80211_s1g_ri ri); /* Spectrum management */ void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 4f04d95c19d4..1ef11a8e742d 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -1577,14 +1577,17 @@ static void ieee80211_iface_process_skb(struct ieee80211_local *local, if (sta) { switch (mgmt->u.action.u.addba_req.action_code) { case WLAN_ACTION_ADDBA_REQ: + case WLAN_ACTION_NDP_ADDBA_REQ: ieee80211_process_addba_request(local, sta, mgmt, len); break; case WLAN_ACTION_ADDBA_RESP: + case WLAN_ACTION_NDP_ADDBA_RESP: ieee80211_process_addba_resp(local, sta, mgmt, len); break; case WLAN_ACTION_DELBA: + case WLAN_ACTION_NDP_DELBA: ieee80211_process_delba(sdata, sta, mgmt, len); break; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 6a1899512d07..d4607057b2e1 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1475,7 +1475,9 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx, !test_and_set_bit(tid, rx->sta->ampdu_mlme.unexpected_agg)) ieee80211_send_delba(rx->sdata, rx->sta->sta.addr, tid, WLAN_BACK_RECIPIENT, - WLAN_REASON_QSTA_REQUIRE_SETUP); + WLAN_REASON_QSTA_REQUIRE_SETUP, + ieee80211_s1g_use_ndp_ba(rx->sdata, + rx->sta)); goto dont_reorder; } @@ -3364,7 +3366,9 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames) !test_and_set_bit(tid, rx->sta->ampdu_mlme.unexpected_agg)) ieee80211_send_delba(rx->sdata, rx->sta->sta.addr, tid, WLAN_BACK_RECIPIENT, - WLAN_REASON_QSTA_REQUIRE_SETUP); + WLAN_REASON_QSTA_REQUIRE_SETUP, + ieee80211_s1g_use_ndp_ba(rx->sdata, + rx->sta)); tid_agg_rx = rcu_dereference(rx->sta->ampdu_mlme.tid_rx[tid]); if (!tid_agg_rx) @@ -3743,16 +3747,19 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) switch (mgmt->u.action.u.addba_req.action_code) { case WLAN_ACTION_ADDBA_REQ: + case WLAN_ACTION_NDP_ADDBA_REQ: if (len < (IEEE80211_MIN_ACTION_SIZE + sizeof(mgmt->u.action.u.addba_req))) goto invalid; break; case WLAN_ACTION_ADDBA_RESP: + case WLAN_ACTION_NDP_ADDBA_RESP: if (len < (IEEE80211_MIN_ACTION_SIZE + sizeof(mgmt->u.action.u.addba_resp))) goto invalid; break; case WLAN_ACTION_DELBA: + case WLAN_ACTION_NDP_DELBA: if (len < (IEEE80211_MIN_ACTION_SIZE + sizeof(mgmt->u.action.u.delba))) goto invalid; diff --git a/net/mac80211/s1g.c b/net/mac80211/s1g.c index 1f68df6e8067..fa26322d979a 100644 --- a/net/mac80211/s1g.c +++ b/net/mac80211/s1g.c @@ -220,3 +220,26 @@ void ieee80211_s1g_cap_to_sta_s1g_cap(struct ieee80211_sub_if_data *sdata, ieee80211_sta_recalc_aggregates(&link_sta->sta->sta); } + +bool ieee80211_s1g_use_ndp_ba(const struct ieee80211_sub_if_data *sdata, + const struct sta_info *sta) +{ + if (!sdata->vif.cfg.s1g || + !ieee80211_hw_check(&sdata->local->hw, SUPPORTS_NDP_BLOCKACK)) + return false; + + return sdata->vif.bss_conf.s1g_ri == IEEE80211_S1G_RI_NDP_RESPONSE || + (sta && sta->sta.deflink.s1g_cap.s1g); +} + +void ieee80211_s1g_update_ri(struct ieee80211_sub_if_data *sdata, + struct ieee80211_link_data *link, + enum ieee80211_s1g_ri ri) +{ + if (!sdata->vif.cfg.s1g || + sdata->vif.bss_conf.s1g_ri == ri) + return; + + sdata->vif.bss_conf.s1g_ri = ri; + ieee80211_link_info_change_notify(sdata, link, BSS_CHANGED_S1G_RI); +} diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 5288d5286651..870fbf4baba6 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -171,6 +171,7 @@ struct sta_info; * @bar_pending: BAR needs to be re-sent * @amsdu: support A-MSDU within A-MDPU * @ssn: starting sequence number of the session + * @ndp: this session is using NDP Block ACKs * * This structure's lifetime is managed by RCU, assignments to * the array holding it must hold the aggregation mutex. @@ -199,6 +200,7 @@ struct tid_ampdu_tx { u16 failed_bar_ssn; bool bar_pending; bool amsdu; + bool ndp; u8 tid; }; -- 2.25.1 ^ permalink raw reply related [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-02-17 11:41 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-12-09 6:24 [PATCH wireless-next v2 0/3] wifi: add S1G response indication configuration with NDP BA support Ria Thomas 2025-12-09 6:24 ` [PATCH wireless-next v2 1/3] wifi: cfg80211: Add support for S1G Response Indication Configuration Ria Thomas 2026-01-08 12:27 ` Johannes Berg 2026-01-09 4:00 ` Ria Thomas 2026-01-13 8:50 ` Johannes Berg 2026-01-16 5:31 ` Ria Thomas 2026-02-06 6:11 ` Ria Thomas 2026-02-06 7:57 ` Johannes Berg 2026-02-12 8:43 ` Ria Thomas 2026-02-17 11:41 ` Johannes Berg 2025-12-09 6:24 ` [PATCH wireless-next v2 2/3] wifi: mac80211: track S1G Response Indication (RI) and notify drivers Ria Thomas 2025-12-09 6:24 ` [PATCH wireless-next v2 3/3] wifi: mac80211: add support for NDP ADDBA/DELBA for S1G Ria Thomas
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox