iwinfo: add 802.11ax HE rate information
authorDavid Bauer <mail@david-bauer.net>
Sat, 17 Apr 2021 21:05:16 +0000 (23:05 +0200)
committerDavid Bauer <mail@david-bauer.net>
Sat, 1 May 2021 22:20:54 +0000 (00:20 +0200)
This adds 802.11ax HE specific rate information to iwinfo.

Add fields for HE status of a STA as well as DCM and guard interval
fields specific to HE operation.

Signed-off-by: David Bauer <mail@david-bauer.net>
api/nl80211.h
include/iwinfo.h
iwinfo_cli.c
iwinfo_lua.c
iwinfo_nl80211.c

index 3d252e49a6ac71f7f5fadc00dd30e3b2aae4f63a..22a709e02e481a0290e25341d1dbcb308f245172 100644 (file)
@@ -2353,6 +2353,13 @@ struct nl80211_sta_flag_update {
  * @NL80211_RATE_INFO_5_MHZ_WIDTH: 5 MHz width - note that this is
  *     a legacy rate and will be reported as the actual bitrate, i.e.
  *     a quarter of the base (20 MHz) rate
+ * @NL80211_RATE_INFO_HE_MCS: HE MCS index (u8, 0-11)
+ * @NL80211_RATE_INFO_HE_NSS: HE NSS value (u8, 1-8)
+ * @NL80211_RATE_INFO_HE_GI: HE guard interval identifier
+ *     (u8, see &enum nl80211_he_gi)
+ * @NL80211_RATE_INFO_HE_DCM: HE DCM value (u8, 0/1)
+ * @NL80211_RATE_INFO_RU_ALLOC: HE RU allocation, if not present then
+ *     non-OFDMA was used (u8, see &enum nl80211_he_ru_alloc)
  * @__NL80211_RATE_INFO_AFTER_LAST: internal use
  */
 enum nl80211_rate_info {
@@ -2369,6 +2376,11 @@ enum nl80211_rate_info {
        NL80211_RATE_INFO_160_MHZ_WIDTH,
        NL80211_RATE_INFO_10_MHZ_WIDTH,
        NL80211_RATE_INFO_5_MHZ_WIDTH,
+       NL80211_RATE_INFO_HE_MCS,
+       NL80211_RATE_INFO_HE_NSS,
+       NL80211_RATE_INFO_HE_GI,
+       NL80211_RATE_INFO_HE_DCM,
+       NL80211_RATE_INFO_HE_RU_ALLOC,
 
        /* keep last */
        __NL80211_RATE_INFO_AFTER_LAST,
index 1956abe063f1af5b2771fe5eec11683f668e9117..3fc414be492dfdcbe35199d502aa8ed785bc0730 100644 (file)
@@ -110,6 +110,9 @@ struct iwinfo_rate_entry {
        uint8_t is_short_gi:1;
        uint8_t is_ht:1;
        uint8_t is_vht:1;
+       uint8_t is_he:1;
+       uint8_t he_gi;
+       uint8_t he_dcm;
        uint8_t mhz;
        uint8_t nss;
 };
index 82b409c0fcf699e7bd0107f59ff849c26d8081b4..8691f3125f913174d654fea00d4ec79a40446de5 100644 (file)
@@ -322,6 +322,20 @@ static char * format_assocrate(struct iwinfo_rate_entry *r)
                                l = sizeof(buf) - (p - buf);
                        }
                }
+               else if (r->is_he)
+               {
+                       p += snprintf(p, l, ", HE-MCS %d, %dMHz", r->mcs, r->mhz);
+                       l = sizeof(buf) - (p - buf);
+
+                       p += snprintf(p, l, ", HE-NSS %d", r->nss);
+                       l = sizeof(buf) - (p - buf);
+
+                       p += snprintf(p, l, ", HE-GI %d", r->he_gi);
+                       l = sizeof(buf) - (p - buf);
+
+                       p += snprintf(p, l, ", HE-DCM %d", r->he_dcm);
+                       l = sizeof(buf) - (p - buf);
+               }
        }
 
        return buf;
index 9935a8daa5d7a840cbbaec199496fe3de662af8c..e49e454d3a81e12a58e5bb546b8ad63ecc59be3b 100644 (file)
@@ -268,6 +268,9 @@ static void set_rateinfo(lua_State *L, struct iwinfo_rate_entry *r, bool rx)
        lua_pushboolean(L, r->is_vht);
        lua_setfield(L, -2, rx ? "rx_vht" : "tx_vht");
 
+       lua_pushboolean(L, r->is_he);
+       lua_setfield(L, -2, rx ? "rx_he" : "tx_he");
+
        lua_pushnumber(L, r->mhz);
        lua_setfield(L, -2, rx ? "rx_mhz" : "tx_mhz");
 
@@ -282,7 +285,7 @@ static void set_rateinfo(lua_State *L, struct iwinfo_rate_entry *r, bool rx)
                lua_pushboolean(L, r->is_short_gi);
                lua_setfield(L, -2, rx ? "rx_short_gi" : "tx_short_gi");
        }
-       else if (r->is_vht)
+       else if (r->is_vht || r->is_he)
        {
                lua_pushnumber(L, r->mcs);
                lua_setfield(L, -2, rx ? "rx_mcs" : "tx_mcs");
@@ -290,8 +293,18 @@ static void set_rateinfo(lua_State *L, struct iwinfo_rate_entry *r, bool rx)
                lua_pushnumber(L, r->nss);
                lua_setfield(L, -2, rx ? "rx_nss" : "tx_nss");
 
-               lua_pushboolean(L, r->is_short_gi);
-               lua_setfield(L, -2, rx ? "rx_short_gi" : "tx_short_gi");
+               if (r->is_he) {
+                       lua_pushnumber(L, r->he_gi);
+                       lua_setfield(L, -2, rx ? "rx_he_gi" : "tx_he_gi");
+
+                       lua_pushnumber(L, r->he_dcm);
+                       lua_setfield(L, -2, rx ? "rx_he_dcm" : "tx_he_dcm");
+               }
+
+               if (r->is_vht) {
+                       lua_pushboolean(L, r->is_short_gi);
+                       lua_setfield(L, -2, rx ? "rx_short_gi" : "tx_short_gi");
+               }
        }
 }
 
index aeff7782266f4e44accff5362ab5a3324bcca5ca..eea521e445bd1179e81fac64a95d4884253eaa0b 100644 (file)
@@ -1869,7 +1869,19 @@ static void nl80211_parse_rateinfo(struct nlattr **ri,
        else if (ri[NL80211_RATE_INFO_BITRATE])
                re->rate = nla_get_u16(ri[NL80211_RATE_INFO_BITRATE]) * 100;
 
-       if (ri[NL80211_RATE_INFO_VHT_MCS])
+       if (ri[NL80211_RATE_INFO_HE_MCS])
+       {
+               re->is_he = 1;
+               re->mcs = nla_get_u8(ri[NL80211_RATE_INFO_HE_MCS]);
+
+               if (ri[NL80211_RATE_INFO_HE_NSS])
+                       re->nss = nla_get_u8(ri[NL80211_RATE_INFO_HE_NSS]);
+               if (ri[NL80211_RATE_INFO_HE_GI])
+                       re->he_gi = nla_get_u8(ri[NL80211_RATE_INFO_HE_GI]);
+               if (ri[NL80211_RATE_INFO_HE_DCM])
+                       re->he_dcm = nla_get_u8(ri[NL80211_RATE_INFO_HE_DCM]);
+       }
+       else if (ri[NL80211_RATE_INFO_VHT_MCS])
        {
                re->is_vht = 1;
                re->mcs = nla_get_u8(ri[NL80211_RATE_INFO_VHT_MCS]);