An S1G PPDU formats the TIM differently compared to non-S1G PPDUs, meaning in order for an S1G STA and AP to correctly coordinate power save, the TIM PVB shall be encoded as per IEEE80211-2024 9.4.2.5.1 Figure 9-213. v1: https://patchwork.kernel.org/project/linux-wireless/cover/20250722071642.875875-1-lachlan.hodges@xxxxxxxxxxxxxx/ Implementation Limitations -------------------------- The primary focus of this patchset is to enable mac80211 to encode and decode S1G TIM elements for the purposes of supporting power save. Due to TIM element length limits and no support for page slicing, this implementation limits the maximum number of associated stations to 1600, rather than the 8192 allowed by the standard. Encoding -------- This patchset extends support for mac80211 to encode the TIM using block bitmap mode without support for inversion. This is typically the default choice for hardware vendors, and helps to constrain the scope of this initial patchset. Decoding -------- In v1, we only added support for block bitmap decoding. However, to ensure interoperability, this patchset includes support for decoding all non optional modes - block bitmap, single AID and OLB. As ADE is optional, it is out of scope for this patchset. Unit Tests ---------- Given the complexity of encoding and decoding, unit tests for the S1G TIM formats have been added. These tests come directly from the examples in IEEE80211-2024 Annex L and cover block bitmap, single AID and OLB and their inverts. Changes Since v1 ---------------- (1) Move the macros that define the max S1G AID and block count to ieee80211_i.h from ieee80211.h as they are _not_ standard supported, but rather an implementation detail for current mac80211 support. (2) Perform validation of the AID on both the AP and STA side. In v1 it was just done in the client. I'm thinking this maybe could be done on just the AP side, but Im going to leave it as for now. (3) Added a comment to nl80211.h on the NL80211_ATTR_PEER_AID attribute as API documentation noting that S1G AID is limited to 1600 for this implementation. (4) Cleaned up the encoding path, based on feedback. Removed some unnecessary validation, used struct element, made the caller responsible for setting the TIM length, and adjusted some comments. (5) Added kunit tests for S1G tim decoding. These are the same test cases seen in IEEE80211-2024 Annex L. (6) Added support for other decoding paths. See below. New Decoding Path ----------------- The decoding path now supports all non-optional encoding types. This includes block bitmap, OLB and single AID and their inverse. ADE encoding is optional as per the standard and is not tested by WFA, so we have opted not to implement it. Before explaining the implementation, it's important to note that the standard makes no guarantee about the ordering of encoded blocks. Hence, as interpreted by our resident standards contributors, we must parse all encoded blocks until we find one with the target AID or exhaust all encoded blocks included in the TIM. First, we intoduce some helper structs to store the parse state and also reduce the parameter count we pass through. The struct s1g_tim_aid allows easy access to the various offsets calculated from the AID. The struct s1g_tim_enc_block contains actual state, and is populated by ieee80211_s1g_find_target_block. This function is responsible for enumerating all encoded blocks until we find one that describes our AIDs block or ENOENT if there is no entry. It will quickly decode the encoded block, check if it describes the block that our target AID resides in, and if it does it populates the struct s1g_tim_enc_block. Once we are at the encoded block that describes our AIDs target block, we decode it based on the encoding type and check if our AIDs bit is set. This also includes dealing with if the encoded block is inverted. While I feel our implementation is fairly good (heh) there are still some quirks I'm not sure are the ideal. Firstly, ieee80211_s1g_find_target_block currently returns various error codes but the caller handles them in the same way. Should we also include handling of a malformed TIM? Lachlan Hodges (3): wifi: mac80211: support block bitmap S1G TIM encoding wifi: mac80211: support parsing S1G TIM PVB wifi: mac80211: kunit: add kunit tests for S1G PVB decoding drivers/net/wireless/ath/carl9170/rx.c | 2 +- drivers/net/wireless/intersil/p54/txrx.c | 2 +- .../net/wireless/ralink/rt2x00/rt2x00dev.c | 2 +- drivers/net/wireless/realtek/rtlwifi/ps.c | 2 +- include/linux/ieee80211.h | 265 ++++++++++++- include/uapi/linux/nl80211.h | 3 +- net/mac80211/cfg.c | 10 +- net/mac80211/ieee80211_i.h | 8 + net/mac80211/mesh_ps.c | 2 +- net/mac80211/mlme.c | 22 +- net/mac80211/tests/Makefile | 2 +- net/mac80211/tests/s1g_tim.c | 357 ++++++++++++++++++ net/mac80211/tx.c | 166 ++++++-- 13 files changed, 777 insertions(+), 66 deletions(-) create mode 100644 net/mac80211/tests/s1g_tim.c -- 2.43.0