]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: mac80211: basic S1G rx rate reporting support
authorLachlan Hodges <lachlan.hodges@morsemicro.com>
Tue, 2 Jun 2026 06:22:24 +0000 (16:22 +1000)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 3 Jun 2026 12:11:56 +0000 (14:11 +0200)
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 <lachlan.hodges@morsemicro.com>
Link: https://patch.msgid.link/20260602062224.1792985-1-lachlan.hodges@morsemicro.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/mac80211.h
net/mac80211/rx.c
net/mac80211/sta_info.c
net/mac80211/sta_info.h

index 4fb579805e0fbf8fdb9c0e565911a33f4e49f2fd..7dd558f4025b28470515d06b6fa28ea9a5475726 100644 (file)
@@ -1704,6 +1704,7 @@ enum mac80211_rx_encoding {
        RX_ENC_HE,
        RX_ENC_EHT,
        RX_ENC_UHR,
+       RX_ENC_S1G,
 };
 
 /**
index ef6086b183f71f0fca42d201fb87750779357133..91b4f6cbfce8f5b1400ea5c441720f70322d1fd2 100644 (file)
@@ -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;
index 4c86a3793804f7a98da4479f4e2264202a846522..857c7d3355c7289e1372a10cffef97eda3ad6bbc 100644 (file)
@@ -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;
        }
 }
 
index 39608a0abbb5932178b4d6dd99bfc284c646944c..e1837e986837f89e56802e78d35d68731865f5a6 100644 (file)
@@ -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;