From 20887dfe1afe5702d1d59cc8c7cfce9f75bbb69e Mon Sep 17 00:00:00 2001 From: James Prestwood Date: Wed, 21 Aug 2019 15:21:44 -0700 Subject: [PATCH] wiphy: explicitly set extended capability bits Some capability bits are required by the spec to be set for probe requests for certain features (HS20, FILS, FT). Currently these features work as-is, but depending on the hardware we may be in violation of the spec if we assume the correct bits are set when we get the wiphy dump. Just to be safe we can explicity set these capability bits. There are also two ways the kernel exposes these capabilities. Per-type or globally. The hardware may expose one, or both of these capability arrays. To combat this we are now always creating a per-type capability array for stations. If the wiphy dump has not produced a per-type capability array we now create one based off the global capability array. That way we can always assume there is a capability array for a station iftype. --- src/wiphy.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/wiphy.c b/src/wiphy.c index 2ff652fe..e50cdbef 100644 --- a/src/wiphy.c +++ b/src/wiphy.c @@ -951,6 +951,39 @@ void wiphy_update_from_genl(struct wiphy *wiphy, struct l_genl_msg *msg) wiphy_parse_attributes(wiphy, &attr); } +static void wiphy_set_station_capability_bits(struct wiphy *wiphy) +{ + uint8_t *ext_capa; + bool anqp_disabled; + + /* No per-type capabilities exist for station, just copy the global */ + if (!wiphy->iftype_extended_capabilities[NL80211_IFTYPE_STATION]) { + wiphy->iftype_extended_capabilities[NL80211_IFTYPE_STATION] = + l_new(uint8_t, EXT_CAP_LEN + 2); + + memcpy(wiphy->iftype_extended_capabilities[ + NL80211_IFTYPE_STATION], + wiphy->extended_capabilities, + EXT_CAP_LEN + 2); + } + + ext_capa = wiphy->iftype_extended_capabilities[NL80211_IFTYPE_STATION]; + + if (!l_settings_get_bool(iwd_get_config(), "General", "disable_anqp", + &anqp_disabled)) + anqp_disabled = true; + + /* Set BSS Transition Management */ + util_set_bit(ext_capa, 19); + + /* Set Interworking */ + if (!anqp_disabled) + util_set_bit(ext_capa, 31); + + /* Set FILS */ + util_set_bit(ext_capa, 72); +} + void wiphy_create_complete(struct wiphy *wiphy) { if (util_mem_is_zero(wiphy->permanent_addr, 6)) { @@ -961,6 +994,8 @@ void wiphy_create_complete(struct wiphy *wiphy) wiphy->name, strerror(-err)); } + wiphy_set_station_capability_bits(wiphy); + wiphy_print_basic_info(wiphy); }