AP: Add initial support for 6 GHz band

Add support for new hardware mode for 6 GHz band. 6 GHz operation is
defined in IEEE P802.11ax/D4.3. 6 GHz band adds global operating classes
131-135 that define channels in frequency range from 5940 MHz to 7105
MHz.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>

- Remove HOSTAPD_MODE_IEEE80211AX mode
- Replace check for HOSTAPD_MODE_IEEE80211AX with is_6ghz_freq()
- Move center_idx_to_bw_6ghz() to ieee802_11_common.c file

Signed-off-by: Vamsi Krishna <vamsin@codeaurora.org>
This commit is contained in:
Andrei Otcheretianski 2019-06-19 15:49:11 +03:00 committed by Jouni Malinen
parent a5b2faa714
commit d7c2c5c98c
4 changed files with 127 additions and 1 deletions

View file

@ -146,7 +146,8 @@ ssid=test
# Operation mode (a = IEEE 802.11a (5 GHz), b = IEEE 802.11b (2.4 GHz), # Operation mode (a = IEEE 802.11a (5 GHz), b = IEEE 802.11b (2.4 GHz),
# g = IEEE 802.11g (2.4 GHz), ad = IEEE 802.11ad (60 GHz); a/g options are used # g = IEEE 802.11g (2.4 GHz), ad = IEEE 802.11ad (60 GHz); a/g options are used
# with IEEE 802.11n (HT), too, to specify band). For IEEE 802.11ac (VHT), this # with IEEE 802.11n (HT), too, to specify band). For IEEE 802.11ac (VHT), this
# needs to be set to hw_mode=a. When using ACS (see channel parameter), a # needs to be set to hw_mode=a. For IEEE 802.11ax (HE) on 6 GHz this needs
# to be set to hw_mode=a. When using ACS (see channel parameter), a
# special value "any" can be used to indicate that any support band can be used. # special value "any" can be used to indicate that any support band can be used.
# This special case is currently supported only with drivers with which # This special case is currently supported only with drivers with which
# offloaded ACS is used. # offloaded ACS is used.
@ -805,6 +806,11 @@ wmm_ac_vo_acm=0
#he_rts_threshold=0 #he_rts_threshold=0
# HE operating channel information; see matching vht_* parameters for details. # HE operating channel information; see matching vht_* parameters for details.
# On the 6 GHz band the center freq calculation starts from 5.940 GHz offset.
# For example idx=3 would result in 5955 MHz center frequency. In addition,
# he_oper_chwidth is ignored, and the channel width is derived from the
# configured operating class or center frequency indexes (see
# IEEE P802.11ax/D4.3 Annex E, Table E-4).
#he_oper_chwidth #he_oper_chwidth
#he_oper_centr_freq_seg0_idx #he_oper_centr_freq_seg0_idx
#he_oper_centr_freq_seg1_idx #he_oper_centr_freq_seg1_idx

View file

@ -385,6 +385,71 @@ int hostapd_set_freq_params(struct hostapd_freq_params *data,
hostapd_encode_edmg_chan(enable_edmg, edmg_channel, channel, hostapd_encode_edmg_chan(enable_edmg, edmg_channel, channel,
&data->edmg); &data->edmg);
if (is_6ghz_freq(freq)) {
if (!data->he_enabled) {
wpa_printf(MSG_ERROR,
"Can't set 6 GHz mode - HE isn't enabled");
return -1;
}
if (center_idx_to_bw_6ghz(channel) != 0) {
wpa_printf(MSG_ERROR,
"Invalid control channel for 6 GHz band");
return -1;
}
if (!center_segment0) {
if (center_segment1) {
wpa_printf(MSG_ERROR,
"Segment 0 center frequency isn't set");
return -1;
}
data->center_freq1 = data->freq;
data->bandwidth = 20;
} else {
int freq1, freq2 = 0;
int bw = center_idx_to_bw_6ghz(center_segment0);
if (bw < 0) {
wpa_printf(MSG_ERROR,
"Invalid center frequency index for 6 GHz");
return -1;
}
freq1 = ieee80211_chan_to_freq(NULL, 131,
center_segment0);
if (freq1 < 0) {
wpa_printf(MSG_ERROR,
"Invalid segment 0 center frequency for 6 GHz");
return -1;
}
if (center_segment1) {
if (center_idx_to_bw_6ghz(center_segment1) != 2 ||
bw != 2) {
wpa_printf(MSG_ERROR,
"6 GHz 80+80 MHz configuration doesn't use valid 80 MHz channels");
return -1;
}
freq2 = ieee80211_chan_to_freq(NULL, 131,
center_segment1);
if (freq2 < 0) {
wpa_printf(MSG_ERROR,
"Invalid segment 1 center frequency for UHB");
return -1;
}
}
data->bandwidth = (1 << (u8) bw) * 20;
data->center_freq1 = freq1;
data->center_freq2 = freq2;
}
return 0;
}
if (data->vht_enabled) switch (oper_chwidth) { if (data->vht_enabled) switch (oper_chwidth) {
case CHANWIDTH_USE_HT: case CHANWIDTH_USE_HT:
if (center_segment1 || if (center_segment1 ||

View file

@ -882,6 +882,19 @@ enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
return HOSTAPD_MODE_IEEE80211AD; return HOSTAPD_MODE_IEEE80211AD;
} }
if (freq > 5940 && freq <= 7105) {
int bw;
u8 idx = (freq - 5940) / 5;
bw = center_idx_to_bw_6ghz(idx);
if (bw < 0)
return NUM_HOSTAPD_MODES;
*channel = idx;
*op_class = 131 + bw;
return HOSTAPD_MODE_IEEE80211A;
}
return NUM_HOSTAPD_MODES; return NUM_HOSTAPD_MODES;
} }
@ -1161,6 +1174,14 @@ static int ieee80211_chan_to_freq_global(u8 op_class, u8 chan)
if (chan < 36 || chan > 128) if (chan < 36 || chan > 128)
return -1; return -1;
return 5000 + 5 * chan; return 5000 + 5 * chan;
case 131: /* UHB channels, 20 MHz: 1, 5, 9.. */
case 132: /* UHB channels, 40 MHz: 3, 11, 19.. */
case 133: /* UHB channels, 80 MHz: 7, 23, 39.. */
case 134: /* UHB channels, 160 MHz: 15, 47, 79.. */
case 135: /* UHB channels, 80+80 MHz: 7, 23, 39.. */
if (chan < 1 || chan > 233)
return -1;
return 5940 + chan * 5;
case 180: /* 60 GHz band, channels 1..6 */ case 180: /* 60 GHz band, channels 1..6 */
if (chan < 1 || chan > 6) if (chan < 1 || chan > 6)
return -1; return -1;
@ -1591,6 +1612,7 @@ const struct oper_class_map global_op_class[] = {
{ HOSTAPD_MODE_IEEE80211A, 128, 36, 161, 4, BW80, P2P_SUPP }, { HOSTAPD_MODE_IEEE80211A, 128, 36, 161, 4, BW80, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 129, 50, 114, 16, BW160, P2P_SUPP }, { HOSTAPD_MODE_IEEE80211A, 129, 50, 114, 16, BW160, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 130, 36, 161, 4, BW80P80, P2P_SUPP }, { HOSTAPD_MODE_IEEE80211A, 130, 36, 161, 4, BW80P80, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 131, 1, 233, 4, BW20, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211AD, 180, 1, 4, 1, BW2160, P2P_SUPP }, { HOSTAPD_MODE_IEEE80211AD, 180, 1, 4, 1, BW2160, P2P_SUPP },
{ -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP } { -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP }
}; };
@ -1905,6 +1927,37 @@ int oper_class_bw_to_int(const struct oper_class_map *map)
} }
int center_idx_to_bw_6ghz(u8 idx)
{
/* channels: 1, 5, 9, 13... */
if ((idx & 0x3) == 0x1)
return 0; /* 20 MHz */
/* channels 3, 11, 19... */
if ((idx & 0x7) == 0x3)
return 1; /* 40 MHz */
/* channels 7, 23, 39.. */
if ((idx & 0xf) == 0x7)
return 2; /* 80 MHz */
/* channels 15, 47, 79...*/
if ((idx & 0x1f) == 0xf)
return 3; /* 160 MHz */
return -1;
}
int is_6ghz_freq(int freq)
{
if (freq < 5940 || freq > 7105)
return 0;
if (center_idx_to_bw_6ghz((freq - 5940) / 5) < 0)
return 0;
return 1;
}
int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep, int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
size_t nei_rep_len) size_t nei_rep_len)
{ {

View file

@ -220,6 +220,8 @@ u8 country_to_global_op_class(const char *country, u8 op_class);
const struct oper_class_map * get_oper_class(const char *country, u8 op_class); const struct oper_class_map * get_oper_class(const char *country, u8 op_class);
int oper_class_bw_to_int(const struct oper_class_map *map); int oper_class_bw_to_int(const struct oper_class_map *map);
int center_idx_to_bw_6ghz(u8 idx);
int is_6ghz_freq(int freq);
int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep, int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
size_t nei_rep_len); size_t nei_rep_len);