]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Add VHT support for Mesh
authorPeter Oh <poh@qca.qualcomm.com>
Tue, 10 Nov 2015 19:01:20 +0000 (11:01 -0800)
committerJouni Malinen <j@w1.fi>
Thu, 19 Nov 2015 09:37:41 +0000 (11:37 +0200)
Mesh Points themselves have capability to support VHT as long as
hardware supports it. However, supporting VHT in mesh mode was disabled
because no one had clearly tested and confirmed its functionality. Since
VHT80 has now been verified to work with ath10k QCA988X driver and
mac80211_hwsim, enable VHT support in mesh mode.

Signed-off-by: Peter Oh <poh@qca.qualcomm.com>
wpa_supplicant/mesh.c
wpa_supplicant/mesh_mpm.c
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant_i.h

index 77f708b42daa9690b572ad7018abc6f8bc3cf2ce..59377777b9fa80356cf156e4b9f38e040e58e4d9 100644 (file)
@@ -323,6 +323,7 @@ int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s,
        params.meshid_len = ssid->ssid_len;
        ibss_mesh_setup_freq(wpa_s, ssid, &params.freq);
        wpa_s->mesh_ht_enabled = !!params.freq.ht_enabled;
+       wpa_s->mesh_vht_enabled = !!params.freq.vht_enabled;
        if (ssid->beacon_int > 0)
                params.beacon_int = ssid->beacon_int;
        else if (wpa_s->conf->beacon_int > 0)
index 0a058155166bbb366410b3186ea238cd2b5d38e0..7ebd4d2e686c6523d205ea6aef62c1700ccd4127 100644 (file)
@@ -212,9 +212,6 @@ static void mesh_mpm_send_plink_action(struct wpa_supplicant *wpa_s,
        struct hostapd_data *bss = ifmsh->bss[0];
        struct mesh_conf *conf = ifmsh->mconf;
        u8 supp_rates[2 + 2 + 32];
-#ifdef CONFIG_IEEE80211N
-       u8 ht_capa_oper[2 + 26 + 2 + 22];
-#endif /* CONFIG_IEEE80211N */
        u8 *pos, *cat;
        u8 ie_len, add_plid = 0;
        int ret;
@@ -239,6 +236,12 @@ static void mesh_mpm_send_plink_action(struct wpa_supplicant *wpa_s,
                           2 + 22;  /* HT operation */
        }
 #endif /* CONFIG_IEEE80211N */
+#ifdef CONFIG_IEEE80211AC
+       if (type != PLINK_CLOSE && wpa_s->mesh_vht_enabled) {
+               buf_len += 2 + 12 + /* VHT Capabilities */
+                          2 + 5;  /* VHT Operation */
+       }
+#endif /* CONFIG_IEEE80211AC */
        if (type != PLINK_CLOSE)
                buf_len += conf->rsn_ie_len; /* RSN IE */
 
@@ -334,11 +337,22 @@ static void mesh_mpm_send_plink_action(struct wpa_supplicant *wpa_s,
 
 #ifdef CONFIG_IEEE80211N
        if (type != PLINK_CLOSE && wpa_s->mesh_ht_enabled) {
+               u8 ht_capa_oper[2 + 26 + 2 + 22];
+
                pos = hostapd_eid_ht_capabilities(bss, ht_capa_oper);
                pos = hostapd_eid_ht_operation(bss, pos);
                wpabuf_put_data(buf, ht_capa_oper, pos - ht_capa_oper);
        }
 #endif /* CONFIG_IEEE80211N */
+#ifdef CONFIG_IEEE80211AC
+       if (type != PLINK_CLOSE && wpa_s->mesh_vht_enabled) {
+               u8 vht_capa_oper[2 + 12 + 2 + 5];
+
+               pos = hostapd_eid_vht_capabilities(bss, vht_capa_oper);
+               pos = hostapd_eid_vht_operation(bss, pos);
+               wpabuf_put_data(buf, vht_capa_oper, pos - vht_capa_oper);
+       }
+#endif /* CONFIG_IEEE80211AC */
 
        if (ampe && mesh_rsn_protect_frame(wpa_s->mesh_rsn, sta, cat, buf)) {
                wpa_msg(wpa_s, MSG_INFO,
@@ -564,6 +578,11 @@ static struct sta_info * mesh_mpm_add_peer(struct wpa_supplicant *wpa_s,
        update_ht_state(data, sta);
 #endif /* CONFIG_IEEE80211N */
 
+#ifdef CONFIG_IEEE80211AC
+       copy_sta_vht_capab(data, sta, elems->vht_capabilities);
+       set_sta_vht_opmode(data, sta, elems->vht_opmode_notif);
+#endif /* CONFIG_IEEE80211AC */
+
        if (hostapd_get_aid(data, sta) < 0) {
                wpa_msg(wpa_s, MSG_ERROR, "No AIDs available");
                ap_free_sta(data, sta);
@@ -579,6 +598,7 @@ static struct sta_info * mesh_mpm_add_peer(struct wpa_supplicant *wpa_s,
        params.aid = sta->aid;
        params.listen_interval = 100;
        params.ht_capabilities = sta->ht_capabilities;
+       params.vht_capabilities = sta->vht_capabilities;
        params.flags |= WPA_STA_WMM;
        params.flags_mask |= WPA_STA_AUTHENTICATED;
        if (conf->security == MESH_CONF_SEC_NONE) {
index 7631a7940db885197a7286e1401b93265a1544e0..0b9b3f9654bd091b2c4909e5d6be61518117fd6f 100644 (file)
@@ -1722,6 +1722,36 @@ static int bss_is_ibss(struct wpa_bss *bss)
 }
 
 
+static int drv_supports_vht(struct wpa_supplicant *wpa_s,
+                           const struct wpa_ssid *ssid)
+{
+       enum hostapd_hw_mode hw_mode;
+       struct hostapd_hw_modes *mode = NULL;
+       u8 channel;
+       int i;
+
+#ifdef CONFIG_HT_OVERRIDES
+       if (ssid->disable_ht)
+               return 0;
+#endif /* CONFIG_HT_OVERRIDES */
+
+       hw_mode = ieee80211_freq_to_chan(ssid->frequency, &channel);
+       if (hw_mode == NUM_HOSTAPD_MODES)
+               return 0;
+       for (i = 0; wpa_s->hw.modes && i < wpa_s->hw.num_modes; i++) {
+               if (wpa_s->hw.modes[i].mode == hw_mode) {
+                       mode = &wpa_s->hw.modes[i];
+                       break;
+               }
+       }
+
+       if (!mode)
+               return 0;
+
+       return mode->vht_capab != 0;
+}
+
+
 void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s,
                          const struct wpa_ssid *ssid,
                          struct hostapd_freq_params *freq)
@@ -1885,12 +1915,12 @@ void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s,
                   "IBSS/mesh: setup freq channel %d, sec_channel_offset %d",
                   freq->channel, freq->sec_channel_offset);
 
-       /* Not sure if mesh is ready for VHT */
-       if (ssid->mode != WPAS_MODE_IBSS)
+       if (!drv_supports_vht(wpa_s, ssid))
                return;
 
        /* For IBSS check VHT_IBSS flag */
-       if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_VHT_IBSS))
+       if (ssid->mode == WPAS_MODE_IBSS &&
+           !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_VHT_IBSS))
                return;
 
        vht_freq = *freq;
index 5caa63e6c02f2b0529f4b8196a0984552996bcef..6d2786b33a8810583d866a64dd643d122fb84c42 100644 (file)
@@ -734,6 +734,7 @@ struct wpa_supplicant {
        int mesh_if_idx;
        unsigned int mesh_if_created:1;
        unsigned int mesh_ht_enabled:1;
+       unsigned int mesh_vht_enabled:1;
        int mesh_auth_block_duration; /* sec */
 #endif /* CONFIG_MESH */