# 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
# 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.
# This special case is currently supported only with drivers with which
# offloaded ACS is used.
#he_rts_threshold=0
# 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_centr_freq_seg0_idx
#he_oper_centr_freq_seg1_idx
hostapd_encode_edmg_chan(enable_edmg, edmg_channel, channel,
&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) {
case CHANWIDTH_USE_HT:
if (center_segment1 ||
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;
}
if (chan < 36 || chan > 128)
return -1;
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 */
if (chan < 1 || chan > 6)
return -1;
{ HOSTAPD_MODE_IEEE80211A, 128, 36, 161, 4, BW80, 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, 131, 1, 233, 4, BW20, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211AD, 180, 1, 4, 1, BW2160, P2P_SUPP },
{ -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP }
};
}
+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,
size_t nei_rep_len)
{