nl80211: Parse EHT capabilities from the driver

Add nl80211 support to parse the EHT capabilities passed by the kernel
using new attributes added in NL80211_BAND_ATTR_IFTYPE_DATA.

Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc@quicinc.com>
This commit is contained in:
Aloka Dixit 2022-04-19 11:04:10 -07:00 committed by Jouni Malinen
parent c08b735fdb
commit 0c8a9aa5d2
2 changed files with 59 additions and 2 deletions

View file

@ -200,6 +200,15 @@ struct he_capabilities {
u16 he_6ghz_capa;
};
/* struct eht_capabilities - IEEE 802.11be EHT capabilities */
struct eht_capabilities {
bool eht_supported;
u16 mac_cap;
u8 phy_cap[EHT_PHY_CAPAB_LEN];
u8 mcs[EHT_MCS_NSS_CAPAB_LEN];
u8 ppet[EHT_PPE_THRESH_CAPAB_LEN];
};
#define HOSTAPD_MODE_FLAG_HT_INFO_KNOWN BIT(0)
#define HOSTAPD_MODE_FLAG_VHT_INFO_KNOWN BIT(1)
@ -298,6 +307,11 @@ struct hostapd_hw_modes {
* for IEEE 802.11ay EDMG configuration.
*/
struct ieee80211_edmg_config edmg;
/**
* eht_capab - EHT (IEEE 802.11be) capabilities
*/
struct eht_capabilities eht_capab[IEEE80211_MODE_NUM];
};

View file

@ -1778,12 +1778,14 @@ static int phy_info_rates(struct hostapd_hw_modes *mode, struct nlattr *tb)
}
static void phy_info_iftype_copy(struct he_capabilities *he_capab,
static void phy_info_iftype_copy(struct hostapd_hw_modes *mode,
enum ieee80211_op_mode opmode,
struct nlattr **tb, struct nlattr **tb_flags)
{
enum nl80211_iftype iftype;
size_t len;
struct he_capabilities *he_capab = &mode->he_capab[opmode];
struct eht_capabilities *eht_capab = &mode->eht_capab[opmode];
switch (opmode) {
case IEEE80211_MODE_INFRA:
@ -1853,6 +1855,47 @@ static void phy_info_iftype_copy(struct he_capabilities *he_capab,
capa = nla_get_u16(tb[NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA]);
he_capab->he_6ghz_capa = le_to_host16(capa);
}
if (!tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC] ||
!tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY])
return;
eht_capab->eht_supported = true;
if (tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC] &&
nla_len(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC]) >= 2) {
const u8 *pos;
pos = nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC]);
eht_capab->mac_cap = WPA_GET_LE16(pos);
}
if (tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY]) {
len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY]);
if (len > sizeof(eht_capab->phy_cap))
len = sizeof(eht_capab->phy_cap);
os_memcpy(eht_capab->phy_cap,
nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY]),
len);
}
if (tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET]) {
len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET]);
if (len > sizeof(eht_capab->mcs))
len = sizeof(eht_capab->mcs);
os_memcpy(eht_capab->mcs,
nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET]),
len);
}
if (tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE]) {
len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE]);
if (len > sizeof(eht_capab->ppet))
len = sizeof(eht_capab->ppet);
os_memcpy(&eht_capab->ppet,
nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE]),
len);
}
}
@ -1874,7 +1917,7 @@ static int phy_info_iftype(struct hostapd_hw_modes *mode,
return NL_STOP;
for (i = 0; i < IEEE80211_MODE_NUM; i++)
phy_info_iftype_copy(&mode->he_capab[i], i, tb, tb_flags);
phy_info_iftype_copy(mode, i, tb, tb_flags);
return NL_OK;
}