Extend support for the 6 GHz operating class 137 (320 MHz)
Commit 085a3fc76e
("EHT: Add 320 channel width support") added this in
various places, but it did not cover everything. Extend this support to
be more complete. In particular, this allows wpa_supplicant to report
the operating class 137 in the Supported Operating Classes element and
to use it when processing beacon requests.
Signed-off-by: Ainy Kumari <quic_ainykuma@quicinc.com>
This commit is contained in:
parent
e74d95e0aa
commit
5dabc10185
4 changed files with 84 additions and 4 deletions
|
@ -2416,6 +2416,9 @@ const struct oper_class_map global_op_class[] = {
|
||||||
{ HOSTAPD_MODE_IEEE80211A, 135, 1, 233, 16, BW80P80, NO_P2P_SUPP },
|
{ HOSTAPD_MODE_IEEE80211A, 135, 1, 233, 16, BW80P80, NO_P2P_SUPP },
|
||||||
{ HOSTAPD_MODE_IEEE80211A, 136, 2, 2, 4, BW20, NO_P2P_SUPP },
|
{ HOSTAPD_MODE_IEEE80211A, 136, 2, 2, 4, BW20, NO_P2P_SUPP },
|
||||||
|
|
||||||
|
/* IEEE P802.11be/D5.0, Table E-4 (Global operating classes) */
|
||||||
|
{ HOSTAPD_MODE_IEEE80211A, 137, 31, 191, 32, BW320, NO_P2P_SUPP },
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IEEE Std 802.11ad-2012 and P802.ay/D5.0 60 GHz operating classes.
|
* IEEE Std 802.11ad-2012 and P802.ay/D5.0 60 GHz operating classes.
|
||||||
* Class 180 has the legacy channels 1-6. Classes 181-183 include
|
* Class 180 has the legacy channels 1-6. Classes 181-183 include
|
||||||
|
@ -2737,6 +2740,8 @@ int oper_class_bw_to_int(const struct oper_class_map *map)
|
||||||
case BW80P80:
|
case BW80P80:
|
||||||
case BW160:
|
case BW160:
|
||||||
return 160;
|
return 160;
|
||||||
|
case BW320:
|
||||||
|
return 320;
|
||||||
case BW2160:
|
case BW2160:
|
||||||
return 2160;
|
return 2160;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -253,7 +253,7 @@ struct oper_class_map {
|
||||||
u8 max_chan;
|
u8 max_chan;
|
||||||
u8 inc;
|
u8 inc;
|
||||||
enum { BW20, BW40PLUS, BW40MINUS, BW40, BW80, BW2160, BW160, BW80P80,
|
enum { BW20, BW40PLUS, BW40MINUS, BW40, BW80, BW2160, BW160, BW80P80,
|
||||||
BW4320, BW6480, BW8640} bw;
|
BW320, BW4320, BW6480, BW8640} bw;
|
||||||
enum { P2P_SUPP, NO_P2P_SUPP } p2p;
|
enum { P2P_SUPP, NO_P2P_SUPP } p2p;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -22,13 +22,12 @@ static enum chan_allowed allow_channel(struct hostapd_hw_modes *mode,
|
||||||
unsigned int *flags)
|
unsigned int *flags)
|
||||||
{
|
{
|
||||||
int i;
|
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++) {
|
for (i = 0; i < mode->num_channels; i++) {
|
||||||
bool chan_is_6ghz;
|
bool chan_is_6ghz;
|
||||||
|
|
||||||
chan_is_6ghz = mode->channels[i].freq >= 5935 &&
|
chan_is_6ghz = is_6ghz_freq(mode->channels[i].freq);
|
||||||
mode->channels[i].freq <= 7115;
|
|
||||||
if (is_6ghz == chan_is_6ghz && mode->channels[i].chan == chan)
|
if (is_6ghz == chan_is_6ghz && mode->channels[i].chan == chan)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -187,6 +186,69 @@ static enum chan_allowed verify_160mhz(struct hostapd_hw_modes *mode,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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,
|
enum chan_allowed verify_channel(struct hostapd_hw_modes *mode, u8 op_class,
|
||||||
u8 channel, u8 bw)
|
u8 channel, u8 bw)
|
||||||
{
|
{
|
||||||
|
@ -228,6 +290,13 @@ enum chan_allowed verify_channel(struct hostapd_hw_modes *mode, u8 op_class,
|
||||||
* result and use only the 80 MHz specific version.
|
* result and use only the 80 MHz specific version.
|
||||||
*/
|
*/
|
||||||
res2 = res = verify_80mhz(mode, op_class, channel);
|
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)
|
if (res == NOT_ALLOWED || res2 == NOT_ALLOWED)
|
||||||
|
|
|
@ -515,6 +515,8 @@ static int * wpas_add_channels(const struct oper_class_map *op,
|
||||||
num_primary_channels = 4;
|
num_primary_channels = 4;
|
||||||
else if (op->bw == BW160)
|
else if (op->bw == BW160)
|
||||||
num_primary_channels = 8;
|
num_primary_channels = 8;
|
||||||
|
else if (op->bw == BW320)
|
||||||
|
num_primary_channels = 16;
|
||||||
else
|
else
|
||||||
num_primary_channels = 1;
|
num_primary_channels = 1;
|
||||||
|
|
||||||
|
@ -561,6 +563,7 @@ static int * wpas_op_class_freqs(const struct oper_class_map *op,
|
||||||
u8 channels_80mhz_6ghz[] = { 7, 23, 39, 55, 71, 87, 103, 119, 135, 151,
|
u8 channels_80mhz_6ghz[] = { 7, 23, 39, 55, 71, 87, 103, 119, 135, 151,
|
||||||
167, 183, 199, 215 };
|
167, 183, 199, 215 };
|
||||||
u8 channels_160mhz_6ghz[] = { 15, 47, 79, 111, 143, 175, 207 };
|
u8 channels_160mhz_6ghz[] = { 15, 47, 79, 111, 143, 175, 207 };
|
||||||
|
u8 channels_320mhz_6ghz[] = { 31, 63, 95, 127, 159, 191 };
|
||||||
const u8 *channels = NULL;
|
const u8 *channels = NULL;
|
||||||
size_t num_chan = 0;
|
size_t num_chan = 0;
|
||||||
bool is_6ghz = is_6ghz_op_class(op->op_class);
|
bool is_6ghz = is_6ghz_op_class(op->op_class);
|
||||||
|
@ -579,6 +582,9 @@ static int * wpas_op_class_freqs(const struct oper_class_map *op,
|
||||||
channels_160mhz_5ghz;
|
channels_160mhz_5ghz;
|
||||||
num_chan = is_6ghz ? ARRAY_SIZE(channels_160mhz_6ghz) :
|
num_chan = is_6ghz ? ARRAY_SIZE(channels_160mhz_6ghz) :
|
||||||
ARRAY_SIZE(channels_160mhz_5ghz);
|
ARRAY_SIZE(channels_160mhz_5ghz);
|
||||||
|
} else if (op->bw == BW320) {
|
||||||
|
channels = channels_320mhz_6ghz;
|
||||||
|
num_chan = ARRAY_SIZE(channels_320mhz_6ghz);
|
||||||
}
|
}
|
||||||
|
|
||||||
return wpas_add_channels(op, mode, channels, num_chan);
|
return wpas_add_channels(op, mode, channels, num_chan);
|
||||||
|
|
Loading…
Reference in a new issue