[PATCH wireless-next v2 0/5] wifi: cfg80211: Add fragmented per-link station stats in MLO
P Praneesh
praneesh.p at oss.qualcomm.com
Sat Jun 13 22:17:30 PDT 2026
This series introduces fragmentation support for Multi-Link Operation
(MLO) station statistics in nl80211.
The current nl80211_dump_station() implementation works well for legacy
(single-link) stations, but it does not scale for MLO peers. With
multiple links per station, dumping all per-link information in a single
netlink message can exceed size limits, resulting in -EMSGSIZE errors
and incomplete dumps.
With 802.11be (Wi-Fi 7), a single station may have multiple links, each
with its own statistics. To address this, this series introduces a
stateful dump mechanism that splits station information into multiple
messages when required.
The dump is performed in two phases:
- Phase 0: Aggregated (station-level) statistics
- Phase 1: Per-link statistics sent in separate messages
This ensures:
- Reliable delivery of complete station information for MLO peers
- Backward compatibility for legacy stations
- A scalable design for future extensions
Summary of changes:
- Drop unused per-link stats handling from nl80211_send_station()
- Introduce a helper to pack common station-level STA_INFO attributes
- Refactor nl80211_dump_station() to use a stateful dump context
- Implement per-link stats fragmentation using a two-phase approach
- Add optional MAC address filtering for per-link station dumps
Message Layout Examples:
Aggregated Stats (Phase 0)
NL80211_CMD_NEW_STATION
ââ NL80211_ATTR_IFINDEX
ââ NL80211_ATTR_MAC
ââ NL80211_ATTR_GENERATION
ââ NL80211_ATTR_STA_INFO
ââ <aggregated station attributes>
ââ ...
Note: No NL80211_ATTR_MLO_LINKS is included in this phase.
Per-link stats are sent in Phase 1.
Per-Link Stats (Phase 1) - one message per link
NL80211_CMD_NEW_STATION
ââ NL80211_ATTR_IFINDEX
ââ NL80211_ATTR_MAC (MLO MAC)
ââ NL80211_ATTR_GENERATION
ââ NL80211_ATTR_STA_INFO (empty - present for parser compat)
ââ NL80211_ATTR_MLO_LINKS
ââ [linkN]
ââ NL80211_ATTR_MLO_LINK_ID = N
ââ NL80211_ATTR_MAC = <linkN MAC>
ââ NL80211_ATTR_STA_INFO
ââ NL80211_STA_INFO_RX_BYTES
ââ NL80211_STA_INFO_TX_BYTES
ââ ... more linkN stats ..
Testing:
- Verified using "iw station dump" on a 3-link MLO station
- iw requires some updates to parse fragmented per-link stats
(e.g., NL80211_ATTR_MLO_LINKS handling). Those changes will be
submitted separately.
Sample station dump output:
Single link EHT STA:
~~~~~~~~~~~~~~~~~~~
Station ff:ff:ff:0f:f8:64 (on wlan0)
authorized: yes
authenticated: yes
associated: yes
preamble: long
WMM/WME: yes
MFP: yes
TDLS peer: no
inactive time: 182068 ms
rx bytes: 1567
rx packets: 15
tx bytes: 1083
tx packets: 6
tx retries: 0
tx failed: 0
rx drop misc: 0
signal: -30 dBm
signal avg: -27 dBm
tx bitrate: 6.0 MBit/s
tx duration: 3136 us
rx bitrate: 1441.3 MBit/s 80MHz EHT-MCS 7 EHT-NSS 4 EHT-GI 0
rx duration: 0 us
last ack signal:-31 dBm
avg ack signal: -31 dBm
DTIM period: 2
beacon interval:100
connected time: 185 seconds
associated at [boottime]: 157.326s
associated at: 157326 ms
current time: 342408 ms
Link 0:
address: ff:ff:ff:0f:f8:64
inactive time: 182068 ms
rx bytes: 1567
rx packets: 15
tx bytes: 1083
tx packets: 6
tx retries: 0
tx failed: 0
rx drop misc: 0
signal: -30 dBm
signal avg: -29 dBm
tx bitrate: 6.0 MBit/s
tx duration: 1568 us
rx duration: 0 us
last ack signal:-31 dBm
avg ack signal: -31 dBm
DTIM period: 2
beacon interval:100
3 link MLO EHT STA:
~~~~~~~~~~~~~~~~~~
Station ff:ff:ff:ff:5f:23 (on wlan0)
authorized: yes
authenticated: yes
associated: yes
preamble: long
WMM/WME: yes
MFP: yes
TDLS peer: no
inactive time: 173476 ms
rx bytes: 1036
rx packets: 9
tx bytes: 1694
tx packets: 6
tx retries: 1
tx failed: 1
rx drop misc: 0
signal: -20 dBm
signal avg: -22 dBm
tx bitrate: 6.0 MBit/s
tx duration: 2476 us
rx duration: 0 us
last ack signal:-22 dBm
avg ack signal: -22 dBm
DTIM period: 2
beacon interval:100
connected time: 174 seconds
associated at [boottime]: 168.236s
associated at: 168236 ms
current time: 342412 ms
Link 0:
address: ff:ff:ff:ff:5f:23
inactive time: 173476 ms
rx bytes: 138
rx packets: 3
tx bytes: 0
tx packets: 0
tx retries: 0
tx failed: 0
rx drop misc: 0
signal: -27 dBm
signal avg: -28 dBm
tx duration: 0 us
rx duration: 0 us
DTIM period: 2
beacon interval:100
Link 1:
address: ff:ff:ff:ff:5f:24
inactive time: 173976 ms
rx bytes: 898
rx packets: 6
tx bytes: 1694
tx packets: 6
tx retries: 0
tx failed: 0
rx drop misc: 0
signal: -20 dBm
signal avg: -22 dBm
tx bitrate: 6.0 MBit/s
tx duration: 2476 us
rx bitrate: 6.0 MBit/s
rx duration: 0 us
last ack signal:-22 dBm
avg ack signal: -22 dBm
DTIM period: 2
beacon interval:100
Link 2:
address: ff:ff:ff:ff:5f:25
inactive time: 174188 ms
rx bytes: 0
rx packets: 0
tx bytes: 0
tx packets: 0
tx retries: 1
tx failed: 1
rx drop misc: 0
signal: -30 dBm
signal avg: -31 dBm
tx bitrate: 12.0 MBit/s
tx duration: 1920 us
rx duration: 0 us
DTIM period: 2
beacon interval:100
With HE AP and STA:
~~~~~~~~~~~~~~~~~~
Station ff:ff:ff:f1:f8:f4 (on wlan0)
authorized: yes
authenticated: yes
associated: yes
preamble: long
WMM/WME: yes
MFP: yes
TDLS peer: no
inactive time: 10176 ms
rx bytes: 968
rx packets: 10
tx bytes: 856
tx packets: 6
tx retries: 0
tx failed: 0
rx drop misc: 0
signal: -24 dBm
signal avg: -27 dBm
tx bitrate: 6.0 MBit/s
tx duration: 1300 us
rx bitrate: 1297.1 MBit/s 80MHz HE-MCS 6 HE-NSS 4
rx duration: 0 us
last ack signal:-30 dBm
avg ack signal: -30 dBm
DTIM period: 2
beacon interval:100
short slot time:yes
connected time: 11 seconds
associated at [boottime]: 69.552s
associated at: 69530 ms
current time: 80780 ms
---
v2:
- In patch 1/5, Narrowed the scope: only drops the link stats from
nl80211_send_station() (formerly also deleted nl80211_fill_link_station();
that function is now moved to patch 4/5 and reused there). Also fix
the nla_put_failure label indentation (spurious leading space).
- In patch 2/5, Fix all nla_nest_start_noflag() calls in
nl80211_send_station() for nested attribute types (STA_INFO,
BSS_PARAM, TID_STATS, per-tid) to use nla_nest_start() so that
NLA_F_NESTED is set correctly.
- In patch 3/5, Drop nl80211_dump_station_cb wrapper struct and
nl80211_send_accumulated_station() helper; store the context pointer
directly at cb->args[2] following the nl80211_dump_wiphy pattern.
Build the common netlink header inline in the dump loop instead of
delegating to a helper. Add documentation explaining why
memset(&ctx->sinfo) is required after cfg80211_sinfo_release_content()
to prevent a double-free in nl80211_dump_station_done().
- In patch 4/5, Restructure the dump loop around a switch statement so
one netlink message is produced per iteration with header construction
in a single place. Replace nl80211_send_link_station() helper with a
leaner nl80211_put_link_station_payload() that only fills the
NL80211_ATTR_MLO_LINKS nest, leaving header assembly to the caller.
Fix all nla_nest_start_noflag() calls in nl80211_fill_link_station()
to use nla_nest_start(). Fix the AGGREGATED phase to propagate the
real error from nl80211_put_sta_info_common() instead of returning
skb->len, which would cause an infinite re-invocation loop on
-EMSGSIZE. Use __free(kfree) for attrbuf to avoid scattered manual
kfree() calls.
- In patch 5/5, Rename local mac_addr pointer to mac to avoid shadowing
the outer ctx->mac_addr field. Set cb->args[2] = 0 on the MAC
validation error path to prevent nl80211_dump_station_done() from
attempting to free a partially initialised context.
---
P Praneesh (5):
wifi: cfg80211: Drop unused link stats handling in
nl80211_send_station()
wifi: cfg80211: Add helper to pack station-level STA_INFO
wifi: cfg80211: Refactor nl80211_dump_station() to prepare for
per-link stats
wifi: cfg80211: Fragment per-link station stats in
nl80211_dump_station()
wifi: cfg80211: support MAC address filtering in station dump for link
stats
include/uapi/linux/nl80211.h | 19 ++
net/wireless/nl80211.c | 402 ++++++++++++++++++++++++-----------
2 files changed, 297 insertions(+), 124 deletions(-)
base-commit: 972c4dd19cb92e03d75b66c426cfade07582a1ba
--
2.43.0
More information about the ath12k
mailing list