Revert "Revert "[wpa_supplicant] cumilative patch from commit 4b..."
Revert submission 28102966-revert-26533062-Supplicant_merge_June24-CUATTSRBBR
Fixed the regression issue (ag/28389573)
Bug: 329004037
Reverted changes: /q/submissionid:28102966-revert-26533062-Supplicant_merge_June24-CUATTSRBBR
Test: Turn ON/OFF SoftAp
Change-Id: Ie7ea1ee7f8b1311fce280907d37a2e321542f547
diff --git a/wpa_supplicant/op_classes.c b/wpa_supplicant/op_classes.c
index b4ad3ca..ff11d20 100644
--- a/wpa_supplicant/op_classes.c
+++ b/wpa_supplicant/op_classes.c
@@ -22,13 +22,12 @@
unsigned int *flags)
{
int i;
- bool is_6ghz = op_class >= 131 && op_class <= 136;
+ bool is_6ghz = is_6ghz_op_class(op_class);
for (i = 0; i < mode->num_channels; i++) {
bool chan_is_6ghz;
- chan_is_6ghz = mode->channels[i].freq >= 5935 &&
- mode->channels[i].freq <= 7115;
+ chan_is_6ghz = is_6ghz_freq(mode->channels[i].freq);
if (is_6ghz == chan_is_6ghz && mode->channels[i].chan == chan)
break;
}
@@ -187,6 +186,69 @@
}
+static int get_center_320mhz(struct hostapd_hw_modes *mode, u8 channel,
+ const u8 *center_channels, size_t num_chan)
+{
+ unsigned int i;
+
+ if (mode->mode != HOSTAPD_MODE_IEEE80211A || !mode->is_6ghz)
+ return 0;
+
+ for (i = 0; i < num_chan; i++) {
+ /*
+ * In 320 MHz, the bandwidth "spans" 60 channels (e.g., 65-125),
+ * so the center channel is 30 channels away from the start/end.
+ */
+ if (channel >= center_channels[i] - 30 &&
+ channel <= center_channels[i] + 30)
+ return center_channels[i];
+ }
+
+ return 0;
+}
+
+
+static enum chan_allowed verify_320mhz(struct hostapd_hw_modes *mode,
+ u8 op_class, u8 channel)
+{
+ u8 center_chan;
+ unsigned int i;
+ bool no_ir = false;
+ const u8 *center_channels;
+ size_t num_chan;
+ const u8 center_channels_6ghz[] = { 31, 63, 95, 127, 159, 191 };
+
+ center_channels = center_channels_6ghz;
+ num_chan = ARRAY_SIZE(center_channels_6ghz);
+
+ center_chan = get_center_320mhz(mode, channel, center_channels,
+ num_chan);
+ if (!center_chan)
+ return NOT_ALLOWED;
+
+ /* Check all the channels are available */
+ for (i = 0; i < 16; i++) {
+ unsigned int flags;
+ u8 adj_chan = center_chan - 30 + i * 4;
+
+ if (allow_channel(mode, op_class, adj_chan, &flags) ==
+ NOT_ALLOWED)
+ return NOT_ALLOWED;
+
+ if (!(flags & HOSTAPD_CHAN_EHT_320MHZ_SUBCHANNEL))
+ return NOT_ALLOWED;
+
+ if (flags & HOSTAPD_CHAN_NO_IR)
+ no_ir = true;
+ }
+
+ if (no_ir)
+ return NO_IR;
+
+ return ALLOWED;
+}
+
+
enum chan_allowed verify_channel(struct hostapd_hw_modes *mode, u8 op_class,
u8 channel, u8 bw)
{
@@ -228,6 +290,13 @@
* result and use only the 80 MHz specific version.
*/
res2 = res = verify_80mhz(mode, op_class, channel);
+ } else if (bw == BW320) {
+ /*
+ * channel is a center channel and as such, not necessarily a
+ * valid 20 MHz channels. Override earlier allow_channel()
+ * result and use only the 320 MHz specific version.
+ */
+ res2= res = verify_320mhz(mode, op_class, channel);
}
if (res == NOT_ALLOWED || res2 == NOT_ALLOWED)
@@ -251,6 +320,7 @@
int z;
int freq2 = 0;
int freq5 = 0;
+ bool freq6 = false;
mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, op_class->mode,
is_6ghz_op_class(op_class->op_class));
@@ -265,7 +335,9 @@
if (f == 0)
break; /* end of list */
- if (f > 4000 && f < 6000)
+ if (is_6ghz_freq(f))
+ freq6 = true;
+ else if (f > 4000 && f < 6000)
freq5 = 1;
else if (f > 2400 && f < 2500)
freq2 = 1;
@@ -274,8 +346,11 @@
/* No frequencies specified, can use anything hardware supports.
*/
freq2 = freq5 = 1;
+ freq6 = true;
}
+ if (is_6ghz_op_class(op_class->op_class) && !freq6)
+ return 0;
if (op_class->op_class >= 115 && op_class->op_class <= 130 && !freq5)
return 0;
if (op_class->op_class >= 81 && op_class->op_class <= 84 && !freq2)
@@ -453,6 +528,7 @@
u8 op, current, chan;
u8 *ie_len;
size_t res;
+ bool op128 = false, op130 = false, op133 = false, op135 = false;
/*
* Determine the current operating class correct mode based on
@@ -480,8 +556,50 @@
wpabuf_put_u8(buf, current);
for (op = 0; global_op_class[op].op_class; op++) {
- if (wpas_op_class_supported(wpa_s, ssid, &global_op_class[op]))
- wpabuf_put_u8(buf, global_op_class[op].op_class);
+ bool supp;
+ u8 op_class = global_op_class[op].op_class;
+
+ supp = wpas_op_class_supported(wpa_s, ssid,
+ &global_op_class[op]);
+ if (!supp)
+ continue;
+ switch (op_class) {
+ case 128:
+ op128 = true;
+ break;
+ case 130:
+ op130 = true;
+ break;
+ case 133:
+ op133 = true;
+ break;
+ case 135:
+ op135 = true;
+ break;
+ }
+ if (is_80plus_op_class(op_class))
+ continue;
+
+ /* Add a 1-octet operating class to the Operating Class field */
+ wpabuf_put_u8(buf, global_op_class[op].op_class);
+ }
+
+ /* Add the 2-octet operating classes (i.e., 80+80 MHz cases), if any */
+ if ((op128 && op130) || (op133 && op135)) {
+ /* Operating Class Duple Sequence field */
+
+ /* Zero Delimiter */
+ wpabuf_put_u8(buf, 0);
+
+ /* Operating Class Duple List */
+ if (op128 && op130) {
+ wpabuf_put_u8(buf, 130);
+ wpabuf_put_u8(buf, 128);
+ }
+ if (op133 && op135) {
+ wpabuf_put_u8(buf, 135);
+ wpabuf_put_u8(buf, 133);
+ }
}
*ie_len = wpabuf_len(buf) - 2;