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 <jouni@codeaurora.org>
This commit is contained in:
Vamsi Krishna 2019-12-30 15:12:12 +05:30 committed by Jouni Malinen
parent 4658eb77d6
commit d0e116f61f
7 changed files with 27 additions and 16 deletions

View file

@ -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;

View file

@ -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 ||

View file

@ -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;

View file

@ -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);
}

View file

@ -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));

View file

@ -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];
}

View file

@ -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);