diff mbox series

[1/6] AP: Add initial support for 6GHz band

Message ID 20190619124916.14150-2-andrei.otcheretianski@intel.com
State Changes Requested
Headers show
Series AP: Support for 6GHz band | expand

Commit Message

Andrei Otcheretianski June 19, 2019, 12:49 p.m. UTC
Add support for new hardware mode for 6GHz band. 6GHz operation is
defined in "Draft IEEE P802.11ax/D4.1".
6GHz band adds 131-135 operating classes that define channels in
frequency range from 5940MHz to 7105MHz.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
---
 hostapd/config_file.c           |  2 +
 hostapd/hostapd.conf            |  7 ++-
 src/ap/hw_features.c            |  3 ++
 src/common/defs.h               |  1 +
 src/common/hw_features_common.c | 84 +++++++++++++++++++++++++++++++++
 src/common/hw_features_common.h |  1 +
 src/common/ieee802_11_common.c  | 23 +++++++++
 wlantest/Makefile               |  1 +
 8 files changed, 121 insertions(+), 1 deletion(-)

Comments

Arend van Spriel June 20, 2019, 8:58 a.m. UTC | #1
On 6/19/2019 2:49 PM, Andrei Otcheretianski wrote:
> Add support for new hardware mode for 6GHz band. 6GHz operation is
> defined in "Draft IEEE P802.11ax/D4.1".
> 6GHz band adds 131-135 operating classes that define channels in
> frequency range from 5940MHz to 7105MHz.

Hi Andrei,

A few remarks below.

Regards,
Arend

> Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
> ---
>   hostapd/config_file.c           |  2 +
>   hostapd/hostapd.conf            |  7 ++-
>   src/ap/hw_features.c            |  3 ++
>   src/common/defs.h               |  1 +
>   src/common/hw_features_common.c | 84 +++++++++++++++++++++++++++++++++
>   src/common/hw_features_common.h |  1 +
>   src/common/ieee802_11_common.c  | 23 +++++++++
>   wlantest/Makefile               |  1 +
>   8 files changed, 121 insertions(+), 1 deletion(-)

[snip]

> diff --git a/src/common/hw_features_common.c b/src/common/hw_features_common.c
> index 3fdbf893d2..9996ef2bf7 100644
> --- a/src/common/hw_features_common.c
> +++ b/src/common/hw_features_common.c
> @@ -358,6 +358,25 @@ int check_40mhz_2g4(struct hostapd_hw_modes *mode,
>   }
>   
>   
> +int center_idx_to_width_6ghz(u8 idx)
> +{
> +	/* channels: 1, 5, 9, 13... */
> +	if ((idx & 0x3) == 0x1)
> +		return 0; /* 20mhz */
> +	/* channels 3, 11, 19... */
> +	if ((idx & 0x7) == 0x3)
> +		return 1; /* 40mhz */
> +	/* channels 7, 23, 39.. */
> +	if ((idx & 0xf) == 0x7)
> +		return 2; /* 80mhz */
> +	/* channels 15, 47, 79...*/
> +	if ((idx & 0x1f) == 0xf)
> +		return 3; /* 160mhz */
> +
> +	return -1;
> +}
> +
> +
>   int hostapd_set_freq_params(struct hostapd_freq_params *data,
>   			    enum hostapd_hw_mode mode,
>   			    int freq, int channel, int ht_enabled,
> @@ -381,6 +400,71 @@ int hostapd_set_freq_params(struct hostapd_freq_params *data,
>   	data->center_freq2 = 0;
>   	data->bandwidth = sec_channel_offset ? 40 : 20;
>   
> +	if (mode == HOSTAPD_MODE_IEEE80211AX) {
> +		if (!data->he_enabled) {
> +			wpa_printf(MSG_ERROR,
> +				   "Can't set 6GHz mode - HE isn't enabled");
> +			return -1;
> +		}
> +
> +		if (center_idx_to_width_6ghz(channel) != 0) {

Should the condition be '< 0' instead here?

> +			wpa_printf(MSG_ERROR,
> +				   "Invalid control channel for 6Ghz band");
> +			return -1;
> +		}
> +
> +		if (!center_segment0) {
> +			if (center_segment1) {
> +				wpa_printf(MSG_ERROR,
> +					   "Center0 freq isn't set");
> +				return -1;
> +			}
> +
> +			data->center_freq1 = data->freq;
> +			data->bandwidth = 20;
> +		} else {
> +			int freq1, freq2 = 0;
> +			int bw = center_idx_to_width_6ghz(center_segment0);
> +
> +			if (bw < 0 ) {
> +				wpa_printf(MSG_ERROR,
> +					   "Invalid center channel idx for 6GHz");
> +				return -1;
> +			}
> +
> +			freq1 = ieee80211_chan_to_freq(NULL, 131,
> +						       center_segment0);
> +			if (freq1 < 0) {
> +				wpa_printf(MSG_ERROR,
> +					   "Invalid center0 freq. for 6GHz");
> +				return -1;
> +			}
> +
> +			if (center_segment1) {
> +				if (center_idx_to_width_6ghz(center_segment1) != 2 ||
> +				    bw != 2) {

A nit really but you could check for 'bw != 2' first.

> +					wpa_printf(MSG_ERROR,
> +						   "6GHz 80+80 configuration doesn't use valid 80MHz channels");
> +					return -1;
> +				}

[snip]

> diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c
> index a081f87cc2..8096e17409 100644
> --- a/src/common/ieee802_11_common.c
> +++ b/src/common/ieee802_11_common.c

[snip]

> @@ -1161,6 +1175,14 @@ static int ieee80211_chan_to_freq_global(u8 op_class, u8 chan)
>   		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)

The spec mentions range 1..253. Where is 233 coming from?

> +			return -1;
> +		return 5940 + chan * 5;
>   	case 180: /* 60 GHz band, channels 1..4 */
>   		if (chan < 1 || chan > 4)
>   			return -1;
Jouni Malinen June 22, 2019, 5:30 p.m. UTC | #2
On Wed, Jun 19, 2019 at 03:49:11PM +0300, Andrei Otcheretianski wrote:
> Add support for new hardware mode for 6GHz band. 6GHz operation is
> defined in "Draft IEEE P802.11ax/D4.1".
> 6GHz band adds 131-135 operating classes that define channels in
> frequency range from 5940MHz to 7105MHz.

> diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
> @@ -147,7 +147,8 @@ ssid=test
>  # 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-7 GHz this needs
> +# to be set to hw_mode=ax. When using ACS (see channel parameter), a

This feels pretty confusing. Why would hw_mode=ax be used for the 6 GHz
band while all other cases of 802.11ax would not use hw_mode=ax? I'd
much rather continue using hw_mode=a for these and instead of trying to
encode the band somehow in the not exactly clear hw_mode, add a new
configuration parameter op_class that takes the global operating class
number (Table E-4 in the standard) to get the op_class,channel pair to
define the channel.

>  # HE operating channel information; see matching vht_* parameters for details.
> +# On 6GHz band (hw_mode=ax) the center freq calculation starts from 5.940 offset.
> +# For example idx=3 would result in 5955MHz center frequency. In addition,
> +# he_oper_chwidth is ignored, and the channel width is derived from the
> +# configured center frequencies (See IEEE802.11ax/D4.1 Annex E)

The bandwidth should really be from the op_class,channel pair, not
center frequency, so this is yet another justification for adding
op_class instead of trying to extend hw_mode.

> diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
> @@ -158,6 +158,7 @@ int hostapd_prepare_rates(struct hostapd_iface *iface,
>  	else switch (mode->mode) {
>  	case HOSTAPD_MODE_IEEE80211A:
> +	case HOSTAPD_MODE_IEEE80211AX: /* same as 5GHz */

Just like this type of cases where hw_mode=a would really be usable
as-is.
Andrei Otcheretianski June 23, 2019, 6:40 a.m. UTC | #3
> -----Original Message-----
> From: Arend Van Spriel [mailto:arend.vanspriel@broadcom.com]
> Sent: Thursday, June 20, 2019 11:59
> To: Otcheretianski, Andrei <andrei.otcheretianski@intel.com>;
> hostap@lists.infradead.org
> Subject: Re: [PATCH 1/6] AP: Add initial support for 6GHz band
> 
> On 6/19/2019 2:49 PM, Andrei Otcheretianski wrote:
> > Add support for new hardware mode for 6GHz band. 6GHz operation is
> > defined in "Draft IEEE P802.11ax/D4.1".
> > 6GHz band adds 131-135 operating classes that define channels in
> > frequency range from 5940MHz to 7105MHz.
> 
> Hi Andrei,
> 
> A few remarks below.

Thanks for your review :)

> 
> Regards,
> Arend
> 
> > +	if (mode == HOSTAPD_MODE_IEEE80211AX) {
> > +		if (!data->he_enabled) {
> > +			wpa_printf(MSG_ERROR,
> > +				   "Can't set 6GHz mode - HE isn't enabled");
> > +			return -1;
> > +		}
> > +
> > +		if (center_idx_to_width_6ghz(channel) != 0) {
> 
> Should the condition be '< 0' instead here?
> 

No,  because the control channel should be 20mhz valid one.

> > +			wpa_printf(MSG_ERROR,
> > +				   "Invalid control channel for 6Ghz band");
> > +			return -1;
> > +		}
> > +
> > +		if (!center_segment0) {
> > +			if (center_segment1) {
> > +				wpa_printf(MSG_ERROR,
> > +					   "Center0 freq isn't set");
> > +				return -1;
> > +			}
> > +
> > +			data->center_freq1 = data->freq;
> > +			data->bandwidth = 20;
> > +		} else {
> > +			int freq1, freq2 = 0;
> > +			int bw = center_idx_to_width_6ghz(center_segment0);
> > +
> > +			if (bw < 0 ) {
> > +				wpa_printf(MSG_ERROR,
> > +					   "Invalid center channel idx for 6GHz");
> > +				return -1;
> > +			}
> > +
> > +			freq1 = ieee80211_chan_to_freq(NULL, 131,
> > +						       center_segment0);
> > +			if (freq1 < 0) {
> > +				wpa_printf(MSG_ERROR,
> > +					   "Invalid center0 freq. for 6GHz");
> > +				return -1;
> > +			}
> > +
> > +			if (center_segment1) {
> > +				if
> (center_idx_to_width_6ghz(center_segment1) != 2 ||
> > +				    bw != 2) {
> 
> A nit really but you could check for 'bw != 2' first.

Right

> 
> > +					wpa_printf(MSG_ERROR,
> > +						   "6GHz 80+80 configuration
> doesn't use valid 80MHz channels");
> > +					return -1;
> > +				}
> 
> [snip]
> 
> > diff --git a/src/common/ieee802_11_common.c
> > b/src/common/ieee802_11_common.c index a081f87cc2..8096e17409 100644
> > --- a/src/common/ieee802_11_common.c
> > +++ b/src/common/ieee802_11_common.c
> 
> [snip]
> 
> > @@ -1161,6 +1175,14 @@ static int ieee80211_chan_to_freq_global(u8
> op_class, u8 chan)
> >   		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)
> 
> The spec mentions range 1..253. Where is 233 coming from?

233 is the highest channel mentioned in Annex E in op. classes 131-135

> 
> > +			return -1;
> > +		return 5940 + chan * 5;
> >   	case 180: /* 60 GHz band, channels 1..4 */
> >   		if (chan < 1 || chan > 4)
> >   			return -1;
Andrei Otcheretianski June 23, 2019, 7:24 a.m. UTC | #4
> 
> > diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf @@ -147,7
> > +147,8 @@ ssid=test  # 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-7 GHz
> > +this needs # to be set to hw_mode=ax. When using ACS (see channel
> > +parameter), a
> 
> This feels pretty confusing. Why would hw_mode=ax be used for the 6 GHz band
> while all other cases of 802.11ax would not use hw_mode=ax? I'd much rather
> continue using hw_mode=a for these and instead of trying to encode the band
> somehow in the not exactly clear hw_mode, add a new configuration parameter
> op_class that takes the global operating class number (Table E-4 in the standard)
> to get the op_class,channel pair to define the channel.

It makes sense. I'll change it to use operating classes instead.

> 
> >  # HE operating channel information; see matching vht_* parameters for
> details.
> > +# On 6GHz band (hw_mode=ax) the center freq calculation starts from 5.940
> offset.
> > +# For example idx=3 would result in 5955MHz center frequency. In
> > +addition, # he_oper_chwidth is ignored, and the channel width is
> > +derived from the # configured center frequencies (See
> > +IEEE802.11ax/D4.1 Annex E)
> 
> The bandwidth should really be from the op_class,channel pair, not center
> frequency, so this is yet another justification for adding op_class instead of trying
> to extend hw_mode.
> 
> > diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c @@ -158,6
> > +158,7 @@ int hostapd_prepare_rates(struct hostapd_iface *iface,
> >  	else switch (mode->mode) {
> >  	case HOSTAPD_MODE_IEEE80211A:
> > +	case HOSTAPD_MODE_IEEE80211AX: /* same as 5GHz */
> 
> Just like this type of cases where hw_mode=a would really be usable as-is.

Ok.. I'll submit an updated version

Andrei
> 
> --
> Jouni Malinen                                            PGP id EFC895FA
> 
> _______________________________________________
> Hostap mailing list
> Hostap@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/hostap
diff mbox series

Patch

diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index c4106c1283..21671721c0 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -3154,6 +3154,8 @@  static int hostapd_config_fill(struct hostapd_config *conf,
 			conf->hw_mode = HOSTAPD_MODE_IEEE80211G;
 		else if (os_strcmp(pos, "ad") == 0)
 			conf->hw_mode = HOSTAPD_MODE_IEEE80211AD;
+		else if (os_strcmp(pos, "ax") == 0)
+			conf->hw_mode = HOSTAPD_MODE_IEEE80211AX;
 		else if (os_strcmp(pos, "any") == 0)
 			conf->hw_mode = HOSTAPD_MODE_IEEE80211ANY;
 		else {
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index 71e577a89c..a25d3f0092 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -147,7 +147,8 @@  ssid=test
 # 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-7 GHz this needs
+# to be set to hw_mode=ax. 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.
@@ -800,6 +801,10 @@  wmm_ac_vo_acm=0
 #he_rts_threshold=0
 
 # HE operating channel information; see matching vht_* parameters for details.
+# On 6GHz band (hw_mode=ax) the center freq calculation starts from 5.940 offset.
+# For example idx=3 would result in 5955MHz center frequency. In addition,
+# he_oper_chwidth is ignored, and the channel width is derived from the
+# configured center frequencies (See IEEE802.11ax/D4.1 Annex E)
 #he_oper_chwidth
 #he_oper_centr_freq_seg0_idx
 #he_oper_centr_freq_seg1_idx
diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
index c1f19e26b5..4ba4cc7437 100644
--- a/src/ap/hw_features.c
+++ b/src/ap/hw_features.c
@@ -158,6 +158,7 @@  int hostapd_prepare_rates(struct hostapd_iface *iface,
 		basic_rates = iface->conf->basic_rates;
 	else switch (mode->mode) {
 	case HOSTAPD_MODE_IEEE80211A:
+	case HOSTAPD_MODE_IEEE80211AX: /* same as 5GHz */
 		basic_rates = basic_rates_a;
 		break;
 	case HOSTAPD_MODE_IEEE80211B:
@@ -934,6 +935,8 @@  const char * hostapd_hw_mode_txt(int mode)
 		return "IEEE 802.11g";
 	case HOSTAPD_MODE_IEEE80211AD:
 		return "IEEE 802.11ad";
+	case HOSTAPD_MODE_IEEE80211AX:
+		return "IEEE 802.11ax";
 	default:
 		return "UNKNOWN";
 	}
diff --git a/src/common/defs.h b/src/common/defs.h
index 4faf1c8601..c6bb7c0286 100644
--- a/src/common/defs.h
+++ b/src/common/defs.h
@@ -348,6 +348,7 @@  enum hostapd_hw_mode {
 	HOSTAPD_MODE_IEEE80211G,
 	HOSTAPD_MODE_IEEE80211A,
 	HOSTAPD_MODE_IEEE80211AD,
+	HOSTAPD_MODE_IEEE80211AX,
 	HOSTAPD_MODE_IEEE80211ANY,
 	NUM_HOSTAPD_MODES
 };
diff --git a/src/common/hw_features_common.c b/src/common/hw_features_common.c
index 3fdbf893d2..9996ef2bf7 100644
--- a/src/common/hw_features_common.c
+++ b/src/common/hw_features_common.c
@@ -358,6 +358,25 @@  int check_40mhz_2g4(struct hostapd_hw_modes *mode,
 }
 
 
+int center_idx_to_width_6ghz(u8 idx)
+{
+	/* channels: 1, 5, 9, 13... */
+	if ((idx & 0x3) == 0x1)
+		return 0; /* 20mhz */
+	/* channels 3, 11, 19... */
+	if ((idx & 0x7) == 0x3)
+		return 1; /* 40mhz */
+	/* channels 7, 23, 39.. */
+	if ((idx & 0xf) == 0x7)
+		return 2; /* 80mhz */
+	/* channels 15, 47, 79...*/
+	if ((idx & 0x1f) == 0xf)
+		return 3; /* 160mhz */
+
+	return -1;
+}
+
+
 int hostapd_set_freq_params(struct hostapd_freq_params *data,
 			    enum hostapd_hw_mode mode,
 			    int freq, int channel, int ht_enabled,
@@ -381,6 +400,71 @@  int hostapd_set_freq_params(struct hostapd_freq_params *data,
 	data->center_freq2 = 0;
 	data->bandwidth = sec_channel_offset ? 40 : 20;
 
+	if (mode == HOSTAPD_MODE_IEEE80211AX) {
+		if (!data->he_enabled) {
+			wpa_printf(MSG_ERROR,
+				   "Can't set 6GHz mode - HE isn't enabled");
+			return -1;
+		}
+
+		if (center_idx_to_width_6ghz(channel) != 0) {
+			wpa_printf(MSG_ERROR,
+				   "Invalid control channel for 6Ghz band");
+			return -1;
+		}
+
+		if (!center_segment0) {
+			if (center_segment1) {
+				wpa_printf(MSG_ERROR,
+					   "Center0 freq isn't set");
+				return -1;
+			}
+
+			data->center_freq1 = data->freq;
+			data->bandwidth = 20;
+		} else {
+			int freq1, freq2 = 0;
+			int bw = center_idx_to_width_6ghz(center_segment0);
+
+			if (bw < 0 ) {
+				wpa_printf(MSG_ERROR,
+					   "Invalid center channel idx for 6GHz");
+				return -1;
+			}
+
+			freq1 = ieee80211_chan_to_freq(NULL, 131,
+						       center_segment0);
+			if (freq1 < 0) {
+				wpa_printf(MSG_ERROR,
+					   "Invalid center0 freq. for 6GHz");
+				return -1;
+			}
+
+			if (center_segment1) {
+				if (center_idx_to_width_6ghz(center_segment1) != 2 ||
+				    bw != 2) {
+					wpa_printf(MSG_ERROR,
+						   "6GHz 80+80 configuration doesn't use valid 80MHz channels");
+					return -1;
+				}
+
+				freq2 = ieee80211_chan_to_freq(NULL, 131,
+							       center_segment1);
+				if (freq2 < 0) {
+					wpa_printf(MSG_ERROR,
+						   "Invalid center1 freq. 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 ||
diff --git a/src/common/hw_features_common.h b/src/common/hw_features_common.h
index 2d2a539943..c75a79746a 100644
--- a/src/common/hw_features_common.h
+++ b/src/common/hw_features_common.h
@@ -45,5 +45,6 @@  u32 num_chan_to_bw(int num_chans);
 int chan_bw_allowed(const struct hostapd_channel_data *chan, u32 bw,
 		    int ht40_plus, int pri);
 int chan_pri_allowed(const struct hostapd_channel_data *chan);
+int center_idx_to_width_6ghz(u8 idx);
 
 #endif /* HW_FEATURES_COMMON_H */
diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c
index a081f87cc2..8096e17409 100644
--- a/src/common/ieee802_11_common.c
+++ b/src/common/ieee802_11_common.c
@@ -15,6 +15,7 @@ 
 #include "qca-vendor.h"
 #include "ieee802_11_defs.h"
 #include "ieee802_11_common.h"
+#include "hw_features_common.h"
 
 
 static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen,
@@ -882,6 +883,19 @@  enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
 		return HOSTAPD_MODE_IEEE80211AD;
 	}
 
+	if (freq > 5940 && freq <= 7105) {
+		int bw;
+		u8 idx = (freq - 5940) / 5;
+
+		bw = center_idx_to_width_6ghz(idx);
+		if (bw < 0)
+			return NUM_HOSTAPD_MODES;
+
+		*channel = idx;
+		*op_class = 131 + bw;
+		return HOSTAPD_MODE_IEEE80211AX;
+	}
+
 	return NUM_HOSTAPD_MODES;
 }
 
@@ -1161,6 +1175,14 @@  static int ieee80211_chan_to_freq_global(u8 op_class, u8 chan)
 		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..4 */
 		if (chan < 1 || chan > 4)
 			return -1;
@@ -1590,6 +1612,7 @@  const struct oper_class_map global_op_class[] = {
 	{ 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_IEEE80211AX, 131, 1, 233, 4, BW20, NO_P2P_SUPP },
 	{ HOSTAPD_MODE_IEEE80211AD, 180, 1, 4, 1, BW2160, P2P_SUPP },
 	{ -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP }
 };
diff --git a/wlantest/Makefile b/wlantest/Makefile
index 4195a24dd1..8d5e69dd66 100644
--- a/wlantest/Makefile
+++ b/wlantest/Makefile
@@ -54,6 +54,7 @@  CFLAGS += -DCONFIG_FILS
 
 OBJS += ../src/common/ieee802_11_common.o
 OBJS += ../src/common/wpa_common.o
+OBJS += ../src/common/hw_features_common.o
 OBJS += ../src/radius/radius.o
 OBJS += ../src/rsn_supp/wpa_ie.o