From d0e116f61f0daafc1cba51027ad62c5668fc342a Mon Sep 17 00:00:00 2001 From: Vamsi Krishna Date: Mon, 30 Dec 2019 15:12:12 +0530 Subject: [PATCH] Enhance get_mode() to return correct hw_mode with 6 GHz support The 5 GHz channels are stored in one hw_features set with mode HOSTAPD_MODE_IEEE80211A while the 6 GHz channels will need to be stored in a separate hw_features set (but with same mode HOSTAPD_MODE_IEEE80211A) due to possibility of different HT/VHT/HE capabilities being available between the 5 GHz and 6 GHz bands. Iterate through all hw_features sets and check and match the band of channel supported by the hw_features set while getting the hw_features set in get_mode(). This allows both the 5 GHz and 6 GHz channels to be found and correct capabilities to be used in cases where the driver reports different capability values between 5 and 6 GHz channels. Signed-off-by: Jouni Malinen --- wpa_supplicant/op_classes.c | 3 ++- wpa_supplicant/p2p_supplicant.c | 9 +++++---- wpa_supplicant/rrm.c | 6 ++++-- wpa_supplicant/scan.c | 9 +++++---- wpa_supplicant/sme.c | 2 +- wpa_supplicant/wpa_supplicant.c | 11 ++++++++--- wpa_supplicant/wpa_supplicant_i.h | 3 ++- 7 files changed, 27 insertions(+), 16 deletions(-) diff --git a/wpa_supplicant/op_classes.c b/wpa_supplicant/op_classes.c index b15ac9e32..f49bdb094 100644 --- a/wpa_supplicant/op_classes.c +++ b/wpa_supplicant/op_classes.c @@ -228,7 +228,8 @@ static int wpas_op_class_supported(struct wpa_supplicant *wpa_s, int freq2 = 0; int freq5 = 0; - mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, op_class->mode); + mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, op_class->mode, + is_6ghz_op_class(op_class->op_class)); if (!mode) return 0; diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 8237242a7..974e3e0ed 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -1912,7 +1912,7 @@ static int wpas_p2p_freq_to_edmg_channel(struct wpa_supplicant *wpa_s, return -1; hwmode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, - HOSTAPD_MODE_IEEE80211AD); + HOSTAPD_MODE_IEEE80211AD, 0); if (!hwmode) { wpa_printf(MSG_ERROR, "Unsupported AP mode: HOSTAPD_MODE_IEEE80211AD"); @@ -3725,7 +3725,8 @@ static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s, if (o->p2p == NO_P2P_SUPP) continue; - mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, o->mode); + mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, o->mode, + is_6ghz_op_class(o->op_class)); if (mode == NULL) continue; if (mode->mode == HOSTAPD_MODE_IEEE80211G) @@ -6291,7 +6292,7 @@ static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s, cand = wpa_s->p2p_group_common_freqs[i]; mode = ieee80211_freq_to_chan(cand, &chan); hwmode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, - mode); + mode, is_6ghz_freq(cand)); if (!hwmode || wpas_p2p_verify_channel(wpa_s, hwmode, chan, BW80) != ALLOWED) @@ -6318,7 +6319,7 @@ static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s, cand = wpa_s->p2p_group_common_freqs[i]; mode = ieee80211_freq_to_chan(cand, &chan); hwmode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, - mode); + mode, is_6ghz_freq(cand)); if (!wpas_same_band(wpa_s->current_ssid->frequency, cand) || !hwmode || diff --git a/wpa_supplicant/rrm.c b/wpa_supplicant/rrm.c index 7930e012b..66855b877 100644 --- a/wpa_supplicant/rrm.c +++ b/wpa_supplicant/rrm.c @@ -609,7 +609,8 @@ static int * wpas_channel_report_freqs(struct wpa_supplicant *wpa_s, int active, pos++; left--; - mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, op->mode); + mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, op->mode, + is_6ghz_op_class(op->op_class)); if (!mode) continue; @@ -661,7 +662,8 @@ static int * wpas_beacon_request_freqs(struct wpa_supplicant *wpa_s, return NULL; } - mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, op->mode); + mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, op->mode, + is_6ghz_op_class(op->op_class)); if (!mode) return NULL; diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index 205653a67..c91517a45 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -668,13 +668,14 @@ static int non_p2p_network_enabled(struct wpa_supplicant *wpa_s) static void wpa_setband_scan_freqs_list(struct wpa_supplicant *wpa_s, enum hostapd_hw_mode band, - struct wpa_driver_scan_params *params) + struct wpa_driver_scan_params *params, + int is_6ghz) { /* Include only supported channels for the specified band */ struct hostapd_hw_modes *mode; int count, i; - mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, band); + mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, band, is_6ghz); if (mode == NULL) { /* No channels supported in this band - use empty list */ params->freqs = os_zalloc(sizeof(int)); @@ -701,10 +702,10 @@ static void wpa_setband_scan_freqs(struct wpa_supplicant *wpa_s, return; /* already using a limited channel set */ if (wpa_s->setband == WPA_SETBAND_5G) wpa_setband_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211A, - params); + params, 0); else if (wpa_s->setband == WPA_SETBAND_2G) wpa_setband_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211G, - params); + params, 0); } diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index ea4bad2b4..eafff1d6a 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -2339,7 +2339,7 @@ static void wpa_obss_scan_freqs_list(struct wpa_supplicant *wpa_s, int start, end; mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, - HOSTAPD_MODE_IEEE80211G); + HOSTAPD_MODE_IEEE80211G, 0); if (mode == NULL) { /* No channels supported in this band - use empty list */ params->freqs = os_zalloc(sizeof(int)); diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 8cf148f90..aa7e1d09a 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -3249,7 +3249,7 @@ get_supported_edmg(struct wpa_supplicant *wpa_s, if (hw_mode == NUM_HOSTAPD_MODES) goto fail; - mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, hw_mode); + mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, hw_mode, 0); if (!mode) goto fail; @@ -7727,12 +7727,17 @@ int wpas_vendor_elem_remove(struct wpa_supplicant *wpa_s, int frame, struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes, - u16 num_modes, enum hostapd_hw_mode mode) + u16 num_modes, enum hostapd_hw_mode mode, + int is_6ghz) { u16 i; for (i = 0; i < num_modes; i++) { - if (modes[i].mode == mode) + if (modes[i].mode != mode || + !modes[i].num_channels || !modes[i].channels) + continue; + if ((!is_6ghz && !is_6ghz_freq(modes[i].channels[0].freq)) || + (is_6ghz && is_6ghz_freq(modes[i].channels[0].freq))) return &modes[i]; } diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 7ab6ca377..ac4a1ba4e 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1560,7 +1560,8 @@ void fst_wpa_supplicant_fill_iface_obj(struct wpa_supplicant *wpa_s, int wpas_sched_scan_plans_set(struct wpa_supplicant *wpa_s, const char *cmd); struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes, - u16 num_modes, enum hostapd_hw_mode mode); + u16 num_modes, enum hostapd_hw_mode mode, + int is_6ghz); void wpa_bss_tmp_disallow(struct wpa_supplicant *wpa_s, const u8 *bssid, unsigned int sec, int rssi_threshold); -- 2.39.2