aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant/mbo.c
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2016-06-30 18:59:09 (GMT)
committerJouni Malinen <j@w1.fi>2016-06-30 22:13:54 (GMT)
commit653d227e9f40cad1114c1c96654061446fd8b131 (patch)
treeee03ecbd31c4820e6e65b117834f0d6b9282ba92 /wpa_supplicant/mbo.c
parentb47a74394250ec8cdddece68d9c1202b21243ba4 (diff)
downloadhostap-653d227e9f40cad1114c1c96654061446fd8b131.zip
hostap-653d227e9f40cad1114c1c96654061446fd8b131.tar.gz
hostap-653d227e9f40cad1114c1c96654061446fd8b131.tar.bz2
MBO: Improve supported operating class generation
Previously, 2.4 GHz operating class 81 was not added for US due to not all of the channels (1-13 in this operating class) being supported. Still, this operating class is the main operating class in the global table for 2.4 GHz and it is the only option for indicating support for the 2.4 GHz band channels in US. Change the supported operating class building rules to include all operating classes for which at least one channel is enabled. In addition, fix the 80, 80+80, and 160 MHz channel checks (checking the center frequency channel was failing since it is not a valid 20 MHz channel). Signed-off-by: Jouni Malinen <j@w1.fi>
Diffstat (limited to 'wpa_supplicant/mbo.c')
-rw-r--r--wpa_supplicant/mbo.c69
1 files changed, 56 insertions, 13 deletions
diff --git a/wpa_supplicant/mbo.c b/wpa_supplicant/mbo.c
index c37d547..dcf07a9 100644
--- a/wpa_supplicant/mbo.c
+++ b/wpa_supplicant/mbo.c
@@ -532,9 +532,26 @@ static enum chan_allowed verify_channel(struct hostapd_hw_modes *mode,
return NOT_ALLOWED;
res2 = allow_channel(mode, channel + 4, NULL);
} else if (bw == BW80) {
- res2 = verify_80mhz(mode, channel);
+ /*
+ * channel is a center channel and as such, not necessarily a
+ * valid 20 MHz channels. Override earlier allow_channel()
+ * result and use only the 80 MHz specific version.
+ */
+ res2 = res = verify_80mhz(mode, channel);
} else if (bw == BW160) {
- res2 = verify_160mhz(mode, channel);
+ /*
+ * channel is a center channel and as such, not necessarily a
+ * valid 20 MHz channels. Override earlier allow_channel()
+ * result and use only the 160 MHz specific version.
+ */
+ res2 = res = verify_160mhz(mode, channel);
+ } else if (bw == BW80P80) {
+ /*
+ * channel is a center channel and as such, not necessarily a
+ * valid 20 MHz channels. Override earlier allow_channel()
+ * result and use only the 80 MHz specific version.
+ */
+ res2 = res = verify_80mhz(mode, channel);
}
if (res == NOT_ALLOWED || res2 == NOT_ALLOWED)
@@ -550,38 +567,64 @@ static int wpas_op_class_supported(struct wpa_supplicant *wpa_s,
int chan;
size_t i;
struct hostapd_hw_modes *mode;
+ int found;
mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, op_class->mode);
if (!mode)
return 0;
- if (op_class->op_class == 128 || op_class->op_class == 130) {
+ if (op_class->op_class == 128) {
u8 channels[] = { 42, 58, 106, 122, 138, 155 };
+ found = 0;
for (i = 0; i < ARRAY_SIZE(channels); i++) {
if (verify_channel(mode, channels[i], op_class->bw) ==
- NOT_ALLOWED)
- return 0;
+ ALLOWED)
+ return 1;
}
- return 1;
+ return 0;
}
if (op_class->op_class == 129) {
- if (verify_channel(mode, 50, op_class->bw) == NOT_ALLOWED ||
- verify_channel(mode, 114, op_class->bw) == NOT_ALLOWED)
- return 0;
+ /* Check if either 160 MHz channels is allowed */
+ return verify_channel(mode, 50, op_class->bw) == ALLOWED ||
+ verify_channel(mode, 114, op_class->bw) == ALLOWED;
+ }
+
+ if (op_class->op_class == 130) {
+ /* Need at least two non-contiguous 80 MHz segments */
+ found = 0;
+
+ if (verify_channel(mode, 42, op_class->bw) == ALLOWED ||
+ verify_channel(mode, 58, op_class->bw) == ALLOWED)
+ found++;
+ if (verify_channel(mode, 106, op_class->bw) == ALLOWED ||
+ verify_channel(mode, 122, op_class->bw) == ALLOWED ||
+ verify_channel(mode, 138, op_class->bw) == ALLOWED)
+ found++;
+ if (verify_channel(mode, 106, op_class->bw) == ALLOWED &&
+ verify_channel(mode, 138, op_class->bw) == ALLOWED)
+ found++;
+ if (verify_channel(mode, 155, op_class->bw) == ALLOWED)
+ found++;
+
+ if (found >= 2)
+ return 1;
- return 1;
+ return 0;
}
+ found = 0;
for (chan = op_class->min_chan; chan <= op_class->max_chan;
chan += op_class->inc) {
- if (verify_channel(mode, chan, op_class->bw) == NOT_ALLOWED)
- return 0;
+ if (verify_channel(mode, chan, op_class->bw) == ALLOWED) {
+ found = 1;
+ break;
+ }
}
- return 1;
+ return found;
}