Introduce basic rate encoding/decoding for S1G stas such that the usermode rx reporting is relevant as it currently uses VHT calculations which are obviously wildy different to S1G. Sample iw output (with the associated iw patches applied): Connected to 0c:bf:74:00:21:c4 (on wlan0) SSID: wifi_halow freq: 923.500 RX: 7325230 bytes (4756 packets) TX: 190044 bytes (2238 packets) signal: -38 dBm rx bitrate: 43.3 MBit/s S1G-MCS 9 8MHz short GI S1G-NSS 1 tx bitrate: 43.3 MBit/s S1G-MCS 9 8MHz short GI S1G-NSS 1 bss flags: dtim period: 1 beacon int: 100 Signed-off-by: Lachlan Hodges --- include/net/mac80211.h | 1 + net/mac80211/rx.c | 8 ++++++++ net/mac80211/sta_info.c | 7 +++++++ net/mac80211/sta_info.h | 11 ++++++++++- 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 4fb579805e0f..7dd558f4025b 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1704,6 +1704,7 @@ enum mac80211_rx_encoding { RX_ENC_HE, RX_ENC_EHT, RX_ENC_UHR, + RX_ENC_S1G, }; /** diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index ef6086b183f7..91b4f6cbfce8 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -5621,6 +5621,14 @@ void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta, status->rate_idx, status->nss)) goto drop; break; + case RX_ENC_S1G: + if (WARN_ONCE(status->rate_idx > 12 || + !status->nss || + status->nss > 4, + "Rate marked as an S1G rate but data is invalid: MCS: %d, NSS: %d\n", + status->rate_idx, status->nss)) + goto drop; + break; default: WARN_ON_ONCE(1); fallthrough; diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 0ea37016cd4f..9adda77f2679 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -2605,6 +2605,13 @@ static void sta_stats_decode_rate(struct ieee80211_local *local, u32 rate, if (STA_STATS_GET(UHR_IM, rate)) rinfo->flags |= RATE_INFO_FLAGS_UHR_IM; break; + case STA_STATS_RATE_TYPE_S1G: + rinfo->flags = RATE_INFO_FLAGS_S1G_MCS; + rinfo->mcs = STA_STATS_GET(S1G_MCS, rate); + rinfo->nss = STA_STATS_GET(S1G_NSS, rate); + if (STA_STATS_GET(SGI, rate)) + rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; + break; } } diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 39608a0abbb5..e1837e986837 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -1042,7 +1042,7 @@ enum sta_stats_type { #define STA_STATS_FIELD_VHT_MCS 0x0000F000 #define STA_STATS_FIELD_VHT_NSS 0x000F0000 -/* HT & VHT */ +/* HT, VHT & S1G */ #define STA_STATS_FIELD_SGI 0x00100000 /* STA_STATS_RATE_TYPE_HE */ @@ -1066,6 +1066,9 @@ enum sta_stats_type { #define STA_STATS_FIELD_UHR_ELR 0x08000000 #define STA_STATS_FIELD_UHR_IM 0x10000000 +/* STA_STATS_RATE_TYPE_S1G */ +#define STA_STATS_FIELD_S1G_MCS 0x0000F000 +#define STA_STATS_FIELD_S1G_NSS 0x000F0000 #define STA_STATS_FIELD(_n, _v) FIELD_PREP(STA_STATS_FIELD_ ## _n, _v) #define STA_STATS_GET(_n, _v) FIELD_GET(STA_STATS_FIELD_ ## _n, _v) @@ -1081,6 +1084,7 @@ static inline u32 sta_stats_encode_rate(struct ieee80211_rx_status *s) switch (s->encoding) { case RX_ENC_HT: case RX_ENC_VHT: + case RX_ENC_S1G: if (s->enc_flags & RX_ENC_FLAG_SHORT_GI) r |= STA_STATS_FIELD(SGI, 1); break; @@ -1127,6 +1131,11 @@ static inline u32 sta_stats_encode_rate(struct ieee80211_rx_status *s) r |= STA_STATS_FIELD(UHR_ELR, s->uhr.elr); r |= STA_STATS_FIELD(UHR_IM, s->uhr.im); break; + case RX_ENC_S1G: + r |= STA_STATS_FIELD(TYPE, STA_STATS_RATE_TYPE_S1G); + r |= STA_STATS_FIELD(S1G_NSS, s->nss); + r |= STA_STATS_FIELD(S1G_MCS, s->rate_idx); + break; default: WARN_ON(1); return STA_STATS_RATE_INVALID; -- 2.43.0