]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
nl80211: Parse EHT capabilities from the driver
authorAloka Dixit <quic_alokad@quicinc.com>
Tue, 19 Apr 2022 18:04:10 +0000 (11:04 -0700)
committerJouni Malinen <j@w1.fi>
Fri, 29 Apr 2022 12:31:07 +0000 (15:31 +0300)
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>
src/drivers/driver.h
src/drivers/driver_nl80211_capa.c

index 49fe84dd869fef0f915cc722170d57fcb005c059..9fcae968e6ecafdcfd1e8ad95a9b42a4abdf646d 100644 (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];
 };
 
 
index 1ab23f0f3ec90614f6a91f716e519e3399b7092f..a0803bad046a4f64d791a9eca279b53c5e7fb00c 100644 (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;
 }