]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
nl80211: Add driver HE capabilities parsing support
authorJohn Crispin <john@phrozen.org>
Tue, 16 Apr 2019 12:33:57 +0000 (14:33 +0200)
committerJouni Malinen <j@w1.fi>
Thu, 25 Apr 2019 08:43:59 +0000 (11:43 +0300)
Add code to parse NL80211_BAND_ATTR_IFTYPE_DATA when reading the band
info. This is needed to find out about the local HE capabilities in AP
mode.

Signed-off-by: Shashidhar Lakkavalli <slakkavalli@datto.com>
Signed-off-by: John Crispin <john@phrozen.org>
src/drivers/driver.h
src/drivers/driver_nl80211_capa.c

index 095bfd96ae5d6ce8bb019e45b67f5bedfc3d1620..0acc0958aefb040a3f01274acdbf61ca8ed6613c 100644 (file)
@@ -159,7 +159,9 @@ struct hostapd_channel_data {
 };
 
 #define HE_MAX_NUM_SS          8
-#define HE_MAX_PHY_CAPAB_SIZE  3
+#define HE_MAX_MAC_CAPAB_SIZE  6
+#define HE_MAX_PHY_CAPAB_SIZE  11
+#define HE_MAX_MCS_CAPAB_SIZE  12
 
 /**
  * struct he_ppe_threshold - IEEE 802.11ax HE PPE Threshold
@@ -175,9 +177,9 @@ struct he_ppe_threshold {
  */
 struct he_capabilities {
        u8 he_supported;
-       u32 phy_cap[HE_MAX_PHY_CAPAB_SIZE];
-       u32 mac_cap;
-       u32 mcs;
+       u8 phy_cap[HE_MAX_PHY_CAPAB_SIZE];
+       u8 mac_cap[HE_MAX_MAC_CAPAB_SIZE];
+       u8 mcs[HE_MAX_MCS_CAPAB_SIZE];
        struct he_ppe_threshold ppet;
 };
 
index fad290bdf585a86f0f68c6f96ccf314e037e46f4..a90a55db8616edb73bcaf5e07c25ff380fbfde62 100644 (file)
@@ -1500,6 +1500,73 @@ static int phy_info_rates(struct hostapd_hw_modes *mode, struct nlattr *tb)
 }
 
 
+static int phy_info_iftype(struct hostapd_hw_modes *mode,
+                          struct nlattr *nl_iftype)
+{
+       struct nlattr *tb[NL80211_BAND_IFTYPE_ATTR_MAX + 1];
+       struct he_capabilities *he_capab = &mode->he_capab;
+       struct nlattr *tb_flags[NL80211_IFTYPE_MAX + 1];
+       size_t len;
+
+       nla_parse(tb, NL80211_BAND_IFTYPE_ATTR_MAX,
+                 nla_data(nl_iftype), nla_len(nl_iftype), NULL);
+
+       if (!tb[NL80211_BAND_IFTYPE_ATTR_IFTYPES])
+               return NL_STOP;
+
+       if (nla_parse_nested(tb_flags, NL80211_IFTYPE_MAX,
+                            tb[NL80211_BAND_IFTYPE_ATTR_IFTYPES], NULL))
+               return NL_STOP;
+
+       if (!nla_get_flag(tb_flags[NL80211_IFTYPE_AP]))
+               return NL_OK;
+
+       he_capab->he_supported = 1;
+
+       if (tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]) {
+               len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]);
+
+               if (len > sizeof(he_capab->phy_cap))
+                       len = sizeof(he_capab->phy_cap);
+               os_memcpy(he_capab->phy_cap,
+                         nla_data(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]),
+                         len);
+       }
+
+       if (tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC]) {
+               len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC]);
+
+               if (len > sizeof(he_capab->mac_cap))
+                       len = sizeof(he_capab->mac_cap);
+               os_memcpy(he_capab->mac_cap,
+                         nla_data(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC]),
+                         len);
+       }
+
+       if (tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET]) {
+               len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET]);
+
+               if (len > sizeof(he_capab->mcs))
+                       len = sizeof(he_capab->mcs);
+               os_memcpy(he_capab->mcs,
+                         nla_data(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET]),
+                         len);
+       }
+
+       if (tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE]) {
+               len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE]);
+
+               if (len > sizeof(he_capab->ppet))
+                       len = sizeof(he_capab->ppet);
+               os_memcpy(&he_capab->ppet,
+                         nla_data(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE]),
+                         len);
+       }
+
+       return NL_OK;
+}
+
+
 static int phy_info_band(struct phy_info_arg *phy_info, struct nlattr *nl_band)
 {
        struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1];
@@ -1556,6 +1623,19 @@ static int phy_info_band(struct phy_info_arg *phy_info, struct nlattr *nl_band)
                return ret;
        }
 
+       if (tb_band[NL80211_BAND_ATTR_IFTYPE_DATA]) {
+               struct nlattr *nl_iftype;
+               int rem_band;
+
+               nla_for_each_nested(nl_iftype,
+                                   tb_band[NL80211_BAND_ATTR_IFTYPE_DATA],
+                                   rem_band) {
+                       ret = phy_info_iftype(mode, nl_iftype);
+                       if (ret != NL_OK)
+                               return ret;
+               }
+       }
+
        return NL_OK;
 }