Skip to content

Commit 07fc1b9

Browse files
Koral Ilguncmonroe
authored andcommitted
iwinfo: add basic IEEE 802.11be support
Add support for IEEE 802.11be via HW and HT modelist as well as EHT specific rate information for associated STAs. Signed-off-by: Koral Ilgun <koral.ilgun@smartrg.com> Signed-off-by: Chad Monroe <chad@monroe.io>
1 parent 660849b commit 07fc1b9

7 files changed

Lines changed: 123 additions & 11 deletions

File tree

include/iwinfo.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ enum iwinfo_80211 {
3131
IWINFO_80211_AC,
3232
IWINFO_80211_AD,
3333
IWINFO_80211_AX,
34+
IWINFO_80211_BE,
3435

3536
/* keep last */
3637
IWINFO_80211_COUNT
@@ -43,6 +44,7 @@ enum iwinfo_80211 {
4344
#define IWINFO_80211_AC (1 << IWINFO_80211_AC)
4445
#define IWINFO_80211_AD (1 << IWINFO_80211_AD)
4546
#define IWINFO_80211_AX (1 << IWINFO_80211_AX)
47+
#define IWINFO_80211_BE (1 << IWINFO_80211_BE)
4648

4749
extern const char * const IWINFO_80211_NAMES[IWINFO_80211_COUNT];
4850

@@ -192,6 +194,12 @@ enum iwinfo_htmode {
192194
IWINFO_HTMODE_HE80,
193195
IWINFO_HTMODE_HE80_80,
194196
IWINFO_HTMODE_HE160,
197+
IWINFO_HTMODE_EHT20,
198+
IWINFO_HTMODE_EHT40,
199+
IWINFO_HTMODE_EHT80,
200+
IWINFO_HTMODE_EHT80_80,
201+
IWINFO_HTMODE_EHT160,
202+
IWINFO_HTMODE_EHT320,
195203

196204
/* keep last */
197205
IWINFO_HTMODE_COUNT
@@ -210,6 +218,12 @@ enum iwinfo_htmode {
210218
#define IWINFO_HTMODE_HE80 (1 << IWINFO_HTMODE_HE80)
211219
#define IWINFO_HTMODE_HE80_80 (1 << IWINFO_HTMODE_HE80_80)
212220
#define IWINFO_HTMODE_HE160 (1 << IWINFO_HTMODE_HE160)
221+
#define IWINFO_HTMODE_EHT20 (1 << IWINFO_HTMODE_EHT20)
222+
#define IWINFO_HTMODE_EHT40 (1 << IWINFO_HTMODE_EHT40)
223+
#define IWINFO_HTMODE_EHT80 (1 << IWINFO_HTMODE_EHT80)
224+
#define IWINFO_HTMODE_EHT80_80 (1 << IWINFO_HTMODE_EHT80_80)
225+
#define IWINFO_HTMODE_EHT160 (1 << IWINFO_HTMODE_EHT160)
226+
#define IWINFO_HTMODE_EHT320 (1 << IWINFO_HTMODE_EHT320)
213227

214228
extern const char * const IWINFO_HTMODE_NAMES[IWINFO_HTMODE_COUNT];
215229

@@ -222,10 +236,13 @@ struct iwinfo_rate_entry {
222236
uint8_t is_ht:1;
223237
uint8_t is_vht:1;
224238
uint8_t is_he:1;
239+
uint8_t is_eht:1;
225240
uint8_t he_gi;
226241
uint8_t he_dcm;
227242
uint8_t mhz;
228243
uint8_t nss;
244+
uint8_t mhz_hi;
245+
uint8_t eht_gi;
229246
};
230247

231248
struct iwinfo_assoclist_entry {

include/iwinfo/utils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ size_t iwinfo_format_hwmodes(int modes, char *buf, size_t len);
5353
int iwinfo_htmode_is_ht(int htmode);
5454
int iwinfo_htmode_is_vht(int htmode);
5555
int iwinfo_htmode_is_he(int htmode);
56+
int iwinfo_htmode_is_eht(int htmode);
5657

5758
int iwinfo_ifup(const char *ifname);
5859
int iwinfo_ifdown(const char *ifname);

iwinfo_cli.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,17 @@ static char * format_assocrate(struct iwinfo_rate_entry *r)
327327
p += snprintf(p, l, ", HE-DCM %d", r->he_dcm);
328328
l = sizeof(buf) - (p - buf);
329329
}
330+
else if (r->is_eht)
331+
{
332+
p += snprintf(p, l, ", EHT-MCS %d, %dMHz", r->mcs, r->mhz_hi * 256 + r->mhz);
333+
l = sizeof(buf) - (p - buf);
334+
335+
p += snprintf(p, l, ", EHT-NSS %d", r->nss);
336+
l = sizeof(buf) - (p - buf);
337+
338+
p += snprintf(p, l, ", EHT-GI %d", r->eht_gi);
339+
l = sizeof(buf) - (p - buf);
340+
}
330341
}
331342

332343
return buf;

iwinfo_lib.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ const char * const IWINFO_80211_NAMES[IWINFO_80211_COUNT] = {
3030
"ac",
3131
"ad",
3232
"ax",
33+
"be",
3334
};
3435

3536
const char * const IWINFO_BAND_NAMES[IWINFO_BAND_COUNT] = {
@@ -92,7 +93,13 @@ const char * const IWINFO_HTMODE_NAMES[IWINFO_HTMODE_COUNT] = {
9293
"HE40",
9394
"HE80",
9495
"HE80+80",
95-
"HE160"
96+
"HE160",
97+
"EHT20",
98+
"EHT40",
99+
"EHT80",
100+
"EHT80+80",
101+
"EHT160",
102+
"EHT320",
96103
};
97104

98105
const char * const IWINFO_FREQ_FLAG_NAMES[IWINFO_FREQ_FLAG_COUNT] = {

iwinfo_lua.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,10 @@ static void set_rateinfo(lua_State *L, struct iwinfo_rate_entry *r, bool rx)
279279
lua_pushboolean(L, r->is_he);
280280
lua_setfield(L, -2, rx ? "rx_he" : "tx_he");
281281

282-
lua_pushnumber(L, r->mhz);
282+
lua_pushboolean(L, r->is_eht);
283+
lua_setfield(L, -2, rx ? "rx_eht" : "tx_eht");
284+
285+
lua_pushnumber(L, r->mhz_hi * 256 + r->mhz);
283286
lua_setfield(L, -2, rx ? "rx_mhz" : "tx_mhz");
284287

285288
if (r->is_ht)
@@ -293,7 +296,7 @@ static void set_rateinfo(lua_State *L, struct iwinfo_rate_entry *r, bool rx)
293296
lua_pushboolean(L, r->is_short_gi);
294297
lua_setfield(L, -2, rx ? "rx_short_gi" : "tx_short_gi");
295298
}
296-
else if (r->is_vht || r->is_he)
299+
else if (r->is_vht || r->is_he | r->is_eht)
297300
{
298301
lua_pushnumber(L, r->mcs);
299302
lua_setfield(L, -2, rx ? "rx_mcs" : "tx_mcs");
@@ -309,6 +312,11 @@ static void set_rateinfo(lua_State *L, struct iwinfo_rate_entry *r, bool rx)
309312
lua_setfield(L, -2, rx ? "rx_he_dcm" : "tx_he_dcm");
310313
}
311314

315+
if (r->is_eht) {
316+
lua_pushnumber(L, r->eht_gi);
317+
lua_setfield(L, -2, rx ? "rx_eht_gi" : "tx_eht_gi");
318+
}
319+
312320
if (r->is_vht) {
313321
lua_pushboolean(L, r->is_short_gi);
314322
lua_setfield(L, -2, rx ? "rx_short_gi" : "tx_short_gi");
@@ -554,6 +562,9 @@ static int iwinfo_L_hwmodelist(lua_State *L, int (*func)(const char *, int *))
554562
lua_pushboolean(L, hwmodes & IWINFO_80211_AX);
555563
lua_setfield(L, -2, "ax");
556564

565+
lua_pushboolean(L, hwmodes & IWINFO_80211_BE);
566+
lua_setfield(L, -2, "be");
567+
557568
return 1;
558569
}
559570

iwinfo_nl80211.c

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2047,7 +2047,17 @@ static void nl80211_parse_rateinfo(struct nlattr **ri,
20472047
else if (ri[NL80211_RATE_INFO_BITRATE])
20482048
re->rate = nla_get_u16(ri[NL80211_RATE_INFO_BITRATE]) * 100;
20492049

2050-
if (ri[NL80211_RATE_INFO_HE_MCS])
2050+
if (ri[NL80211_RATE_INFO_EHT_MCS])
2051+
{
2052+
re->is_eht = 1;
2053+
re->mcs = nla_get_u8(ri[NL80211_RATE_INFO_EHT_MCS]);
2054+
2055+
if (ri[NL80211_RATE_INFO_EHT_NSS])
2056+
re->nss = nla_get_u8(ri[NL80211_RATE_INFO_EHT_NSS]);
2057+
if (ri[NL80211_RATE_INFO_EHT_GI])
2058+
re->eht_gi = nla_get_u8(ri[NL80211_RATE_INFO_EHT_GI]);
2059+
}
2060+
else if (ri[NL80211_RATE_INFO_HE_MCS])
20512061
{
20522062
re->is_he = 1;
20532063
re->mcs = nla_get_u8(ri[NL80211_RATE_INFO_HE_MCS]);
@@ -2084,6 +2094,8 @@ static void nl80211_parse_rateinfo(struct nlattr **ri,
20842094
else if (ri[NL80211_RATE_INFO_80P80_MHZ_WIDTH] ||
20852095
ri[NL80211_RATE_INFO_160_MHZ_WIDTH])
20862096
re->mhz = 160;
2097+
else if (ri[NL80211_RATE_INFO_320_MHZ_WIDTH])
2098+
re->mhz_hi = 320 / 256, re->mhz = 320 % 256;
20872099
else
20882100
re->mhz = 20;
20892101

@@ -3155,6 +3167,7 @@ struct nl80211_modes
31553167
uint16_t nl_ht;
31563168
uint32_t nl_vht;
31573169
uint16_t he_phy_cap[6];
3170+
uint16_t eht_phy_cap[9];
31583171
};
31593172

31603173
static void nl80211_eval_modelist(struct nl80211_modes *m)
@@ -3183,6 +3196,22 @@ static void nl80211_eval_modelist(struct nl80211_modes *m)
31833196
m->ht |= IWINFO_HTMODE_HE160 | IWINFO_HTMODE_HE80_80;
31843197
}
31853198

3199+
if (m->eht_phy_cap[0] != 0) {
3200+
m->hw |= IWINFO_80211_BE;
3201+
m->ht |= IWINFO_HTMODE_EHT20;
3202+
3203+
if (m->he_phy_cap[0] & BIT(9))
3204+
m->ht |= IWINFO_HTMODE_EHT40;
3205+
if (m->he_phy_cap[0] & BIT(10))
3206+
m->ht |= IWINFO_HTMODE_EHT40 | IWINFO_HTMODE_EHT80;
3207+
if (m->he_phy_cap[0] & BIT(11))
3208+
m->ht |= IWINFO_HTMODE_EHT160;
3209+
if (m->he_phy_cap[0] & BIT(12))
3210+
m->ht |= IWINFO_HTMODE_EHT160 | IWINFO_HTMODE_EHT80_80;
3211+
if ((m->eht_phy_cap[0] & BIT(9)) && (m->bands & IWINFO_BAND_6))
3212+
m->ht |= IWINFO_HTMODE_EHT320;
3213+
}
3214+
31863215
if (m->bands & IWINFO_BAND_24)
31873216
{
31883217
m->hw |= IWINFO_80211_B;
@@ -3252,6 +3281,8 @@ static int nl80211_get_modelist_cb(struct nl_msg *msg, void *arg)
32523281
nla_for_each_nested(nl_iftype, bands[NL80211_BAND_ATTR_IFTYPE_DATA], rem_band) {
32533282
nla_parse(tb, NL80211_BAND_IFTYPE_ATTR_MAX,
32543283
nla_data(nl_iftype), nla_len(nl_iftype), NULL);
3284+
3285+
// HE
32553286
if (tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]) {
32563287
len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]);
32573288

@@ -3261,6 +3292,17 @@ static int nl80211_get_modelist_cb(struct nl_msg *msg, void *arg)
32613292
nla_data(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]),
32623293
len);
32633294
}
3295+
3296+
// EHT
3297+
if (tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY]) {
3298+
len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY]);
3299+
3300+
if (len > sizeof(m->eht_phy_cap) - 1)
3301+
len = sizeof(m->eht_phy_cap) - 1;
3302+
memcpy(&((uint8_t *)m->eht_phy_cap)[1],
3303+
nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY]),
3304+
len);
3305+
}
32643306
}
32653307
}
32663308
}
@@ -3325,6 +3367,7 @@ static int nl80211_get_htmode(const char *ifname, int *buf)
33253367
char *res, b[2] = { 0 };
33263368
int err;
33273369
bool he = false;
3370+
bool eht = false;
33283371

33293372
res = nl80211_phy2ifname(ifname);
33303373
*buf = 0;
@@ -3335,6 +3378,9 @@ static int nl80211_get_htmode(const char *ifname, int *buf)
33353378
if (err)
33363379
return -1;
33373380

3381+
if (nl80211_hostapd_query(res ? res : ifname, "ieee80211be", b, sizeof(b)))
3382+
eht = b[0] == '1';
3383+
33383384
if (nl80211_hostapd_query(res ? res : ifname, "ieee80211ax", b, sizeof(b)))
33393385
he = b[0] == '1';
33403386
else if (nl80211_wpactl_query(res ? res : ifname, "wifi_generation", b, sizeof(b)))
@@ -3343,38 +3389,41 @@ static int nl80211_get_htmode(const char *ifname, int *buf)
33433389
switch (chn.width) {
33443390
case NL80211_CHAN_WIDTH_20:
33453391
if (he)
3346-
*buf = IWINFO_HTMODE_HE20;
3392+
*buf = (eht == true) ? IWINFO_HTMODE_EHT20 : IWINFO_HTMODE_HE20;
33473393
else if (chn.mode == -1)
33483394
*buf = IWINFO_HTMODE_VHT20;
33493395
else
33503396
*buf = IWINFO_HTMODE_HT20;
33513397
break;
33523398
case NL80211_CHAN_WIDTH_40:
33533399
if (he)
3354-
*buf = IWINFO_HTMODE_HE40;
3400+
*buf = (eht == true) ? IWINFO_HTMODE_EHT40 : IWINFO_HTMODE_HE40;
33553401
else if (chn.mode == -1)
33563402
*buf = IWINFO_HTMODE_VHT40;
33573403
else
33583404
*buf = IWINFO_HTMODE_HT40;
33593405
break;
33603406
case NL80211_CHAN_WIDTH_80:
33613407
if (he)
3362-
*buf = IWINFO_HTMODE_HE80;
3408+
*buf = (eht == true) ? IWINFO_HTMODE_EHT80 : IWINFO_HTMODE_HE80;
33633409
else
33643410
*buf = IWINFO_HTMODE_VHT80;
33653411
break;
33663412
case NL80211_CHAN_WIDTH_80P80:
33673413
if (he)
3368-
*buf = IWINFO_HTMODE_HE80_80;
3414+
*buf = (eht == true) ? IWINFO_HTMODE_EHT80_80 : IWINFO_HTMODE_HE80_80;
33693415
else
33703416
*buf = IWINFO_HTMODE_VHT80_80;
33713417
break;
33723418
case NL80211_CHAN_WIDTH_160:
33733419
if (he)
3374-
*buf = IWINFO_HTMODE_HE160;
3420+
*buf = (eht == true) ? IWINFO_HTMODE_EHT160 : IWINFO_HTMODE_HE160;
33753421
else
33763422
*buf = IWINFO_HTMODE_VHT160;
33773423
break;
3424+
case NL80211_CHAN_WIDTH_320:
3425+
*buf = IWINFO_HTMODE_EHT320;
3426+
break;
33783427
case NL80211_CHAN_WIDTH_5:
33793428
case NL80211_CHAN_WIDTH_10:
33803429
case NL80211_CHAN_WIDTH_20_NOHT:

iwinfo_utils.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,8 @@ uint8_t iwinfo_ghz2band(uint32_t ghz)
151151

152152
size_t iwinfo_format_hwmodes(int modes, char *buf, size_t len)
153153
{
154-
// bit numbers as per IWINFO_80211_*: ad ac ax a b g n
155-
const int order[IWINFO_80211_COUNT] = { 5, 4, 6, 0, 1, 2, 3 };
154+
// bit numbers as per IWINFO_80211_*: ad ac ax a b be g n
155+
const int order[IWINFO_80211_COUNT] = { 5, 4, 6, 0, 1, 7, 2, 3 };
156156
size_t res = 0;
157157
int i;
158158

@@ -216,6 +216,22 @@ int iwinfo_htmode_is_he(int htmode)
216216
return 0;
217217
}
218218

219+
int iwinfo_htmode_is_eht(int htmode)
220+
{
221+
switch (htmode)
222+
{
223+
case IWINFO_HTMODE_EHT20:
224+
case IWINFO_HTMODE_EHT40:
225+
case IWINFO_HTMODE_EHT80:
226+
case IWINFO_HTMODE_EHT80_80:
227+
case IWINFO_HTMODE_EHT160:
228+
case IWINFO_HTMODE_EHT320:
229+
return 1;
230+
}
231+
232+
return 0;
233+
}
234+
219235
int iwinfo_ifup(const char *ifname)
220236
{
221237
struct ifreq ifr;

0 commit comments

Comments
 (0)