Enable user to configure Maximum MPDU Length, Maximum A-MPDU Length Exponent, Rx Antenna Pattern Consistency and Tx Antenna Pattern Consistency of 6 GHz capability through config file. Signed-off-by: Rajkumar Manoharan <rmanohar@xxxxxxxxxxxxxx> --- hostapd/config_file.c | 38 ++++++++++++++++++++++++++++++++++++++ hostapd/hostapd.conf | 25 +++++++++++++++++++++++++ src/ap/ap_config.h | 1 + src/ap/hostapd.c | 3 +++ src/ap/hw_features.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ src/ap/hw_features.h | 6 ++++++ src/ap/ieee802_11_he.c | 5 +++-- 7 files changed, 125 insertions(+), 2 deletions(-) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index cc1855dcd6ef..aa8b73bd3a7f 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -1313,6 +1313,42 @@ static u8 set_he_cap(int val, u8 mask) return (u8) (mask & (val << find_bit_offset(mask))); } +static void hostapd_config_he_6ghz_capab(struct hostapd_config *conf, + const char *capab) +{ + if (os_strstr(capab, "[MAX-A-MPDU-LEN-EXP7]")) + conf->he_6ghz_capab |= + HE_6GHZ_BAND_CAP_MAX_A_MPDU_LENGTH_EXPONENT_7; + else if (os_strstr(capab, "[MAX-A-MPDU-LEN-EXP6]")) + conf->he_6ghz_capab |= + HE_6GHZ_BAND_CAP_MAX_A_MPDU_LENGTH_EXPONENT_6; + else if (os_strstr(capab, "[MAX-A-MPDU-LEN-EXP5]")) + conf->he_6ghz_capab |= + HE_6GHZ_BAND_CAP_MAX_A_MPDU_LENGTH_EXPONENT_5; + else if (os_strstr(capab, "[MAX-A-MPDU-LEN-EXP4]")) + conf->he_6ghz_capab |= + HE_6GHZ_BAND_CAP_MAX_A_MPDU_LENGTH_EXPONENT_4; + else if (os_strstr(capab, "[MAX-A-MPDU-LEN-EXP3]")) + conf->he_6ghz_capab |= + HE_6GHZ_BAND_CAP_MAX_A_MPDU_LENGTH_EXPONENT_3; + else if (os_strstr(capab, "[MAX-A-MPDU-LEN-EXP2]")) + conf->he_6ghz_capab |= + HE_6GHZ_BAND_CAP_MAX_A_MPDU_LENGTH_EXPONENT_2; + else if (os_strstr(capab, "[MAX-A-MPDU-LEN-EXP1]")) + conf->he_6ghz_capab |= + HE_6GHZ_BAND_CAP_MAX_A_MPDU_LENGTH_EXPONENT_1; + if (os_strstr(capab, "[MAX-MPDU-7991]")) + conf->he_6ghz_capab |= + HE_6GHZ_BAND_CAP_MAX_MPDU_LENGTH_7991; + if (os_strstr(capab, "[MAX-MPDU-11454]")) + conf->he_6ghz_capab |= + HE_6GHZ_BAND_CAP_MAX_MPDU_LENGTH_11454; + if (os_strstr(capab, "[RX-ANTENNA-PATTERN]")) + conf->he_6ghz_capab |= HE_6GHZ_BAND_CAP_RX_ANTENNA_PATTERN; + if (os_strstr(capab, "[TX-ANTENNA-PATTERN]")) + conf->he_6ghz_capab |= HE_6GHZ_BAND_CAP_TX_ANTENNA_PATTERN; +} + #endif /* CONFIG_IEEE80211AX */ @@ -3606,6 +3642,8 @@ static int hostapd_config_fill(struct hostapd_config *conf, conf->he_oper_centr_freq_seg0_idx = atoi(pos); } else if (os_strcmp(buf, "he_oper_centr_freq_seg1_idx") == 0) { conf->he_oper_centr_freq_seg1_idx = atoi(pos); + } else if (os_strcmp(buf, "he_6ghz_capab") == 0) { + hostapd_config_he_6ghz_capab(conf, pos); #endif /* CONFIG_IEEE80211AX */ } else if (os_strcmp(buf, "max_listen_interval") == 0) { bss->max_listen_interval = atoi(pos); diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index 812c09a9f7e1..49eca87ebf37 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -867,6 +867,31 @@ wmm_ac_vo_acm=0 #he_spr_srg_obss_pd_min_offset #he_spr_srg_obss_pd_max_offset +# he_6ghz_capab: HE 6 GHz capabilities (list of flags) +# +# Maximum MPDU Length: [MAX-MPDU-7991] [MAX-MPDU-11454] +# Indicates maximum MPDU length +# 0 = 3895 octets (default) +# 1 = 7991 octets +# 2 = 11454 octets +# 3 = reserved +# +# Maximum A-MPDU Length Exponent: [MAX-A-MPDU-LEN-EXP0]..[MAX-A-MPDU-LEN-EXP7] +# Indicates the maximum length of A-MPDU pre-EOF padding that the STA can recv +# This field is an integer in the range of 0 to 7. +# The length defined by this field is equal to +# 2 pow(13 + Maximum A-MPDU Length Exponent) -1 octets +# +# Rx Antenna Pattern Consistency: [RX-ANTENNA-PATTERN] +# Indicates the possibility of Rx antenna pattern change +# 0 = Rx antenna pattern might change during the lifetime of an association +# 1 = Rx antenna pattern does not change during the lifetime of an association +# +# Tx Antenna Pattern Consistency: [TX-ANTENNA-PATTERN] +# Indicates the possibility of Tx antenna pattern change +# 0 = Tx antenna pattern might change during the lifetime of an association +# 1 = Tx antenna pattern does not change during the lifetime of an association +# ##### IEEE 802.1X-2004 related configuration ################################## # Require IEEE 802.1X authorization diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index cffa636cc298..d59e971583f5 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -1027,6 +1027,7 @@ struct hostapd_config { u8 he_oper_chwidth; u8 he_oper_centr_freq_seg0_idx; u8 he_oper_centr_freq_seg1_idx; + u16 he_6ghz_capab; #endif /* CONFIG_IEEE80211AX */ /* VHT enable/disable config from CHAN_SWITCH */ diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index b37f49f9a8ec..2d8d56e15345 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -1701,6 +1701,9 @@ static int setup_interface2(struct hostapd_iface *iface) ret = hostapd_check_edmg_capab(iface); if (ret < 0) goto fail; + ret = hostapd_check_he_6ghz_capab(iface); + if (ret < 0) + goto fail; ret = hostapd_check_ht_capab(iface); if (ret < 0) goto fail; diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c index f6e69030d767..a4dfde23f1db 100644 --- a/src/ap/hw_features.c +++ b/src/ap/hw_features.c @@ -732,6 +732,55 @@ int hostapd_check_edmg_capab(struct hostapd_iface *iface) } +int hostapd_check_he_6ghz_capab(struct hostapd_iface *iface) +{ + struct he_capabilities *he_cap; + u16 conf = iface->conf->he_6ghz_capab; + u16 hw; + + if (!iface->current_mode) + return 0; + + he_cap = &iface->current_mode->he_capab[IEEE80211_MODE_AP]; + if (!he_cap->he_6ghz_supported) + return 0; + + if (!is_6ghz_freq(iface->freq)) + return 0; + + hw = he_cap->he_6ghz_cap; + if ((conf & HE_6GHZ_BAND_CAP_MAX_MPDU_LENGTH_MASK) > + (hw & HE_6GHZ_BAND_CAP_MAX_MPDU_LENGTH_MASK)) { + wpa_printf(MSG_ERROR, "Driver does not support configured " + "HE 6GHz capability [MAX_MPDU_LENGTH]"); + return -1; + } + + if ((conf & HE_6GHZ_BAND_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) > + (hw & HE_6GHZ_BAND_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK)) { + wpa_printf(MSG_ERROR, "Driver does not support configured " + "HE 6 GHz capability [MAX_A_MPDU_LENGTH_EXPONENT]"); + return -1; + } + + if ((conf & HE_6GHZ_BAND_CAP_RX_ANTENNA_PATTERN) && + !(hw & HE_6GHZ_BAND_CAP_RX_ANTENNA_PATTERN)) { + wpa_printf(MSG_ERROR, "Driver does not support configured " + "HE 6 GHz capability [RX_ANTENNA_PATTERN]"); + return -1; + } + + if ((conf & HE_6GHZ_BAND_CAP_TX_ANTENNA_PATTERN) && + !(hw & HE_6GHZ_BAND_CAP_TX_ANTENNA_PATTERN)) { + wpa_printf(MSG_ERROR, "Driver does not support configured " + "HE 6 GHz capability [TX_ANTENNA_PATTERN]"); + return -1; + } + + return 0; +} + + static int hostapd_is_usable_chan(struct hostapd_iface *iface, int frequency, int primary) { diff --git a/src/ap/hw_features.h b/src/ap/hw_features.h index dd24f95b2ad8..ad0ddf7ff386 100644 --- a/src/ap/hw_features.h +++ b/src/ap/hw_features.h @@ -22,6 +22,7 @@ int hostapd_hw_get_freq(struct hostapd_data *hapd, int chan); int hostapd_hw_get_channel(struct hostapd_data *hapd, int freq); int hostapd_check_ht_capab(struct hostapd_iface *iface); int hostapd_check_edmg_capab(struct hostapd_iface *iface); +int hostapd_check_he_6ghz_capab(struct hostapd_iface *iface); int hostapd_prepare_rates(struct hostapd_iface *iface, struct hostapd_hw_modes *mode); void hostapd_stop_setup_timers(struct hostapd_iface *iface); @@ -85,6 +86,11 @@ static inline int hostapd_hw_skip_mode(struct hostapd_iface *iface, return 0; } +static inline int hostapd_check_he_6ghz_capab(struct hostapd_iface *iface) +{ + return 0; +} + #endif /* NEED_AP_MLME */ #endif /* HW_FEATURES_H */ diff --git a/src/ap/ieee802_11_he.c b/src/ap/ieee802_11_he.c index c2ef9e5f4d78..e0c56d223f3a 100644 --- a/src/ap/ieee802_11_he.c +++ b/src/ap/ieee802_11_he.c @@ -316,7 +316,7 @@ u8 * hostapd_eid_he_6ghz_band_cap(struct hostapd_data *hapd, u8 *eid) struct hostapd_hw_modes *mode = hapd->iface->current_mode; struct he_capabilities *he_cap; struct ieee80211_he_6ghz_band_cap *cap; - u16 capab; + u16 capab = hapd->iface->conf->he_6ghz_capab; u8 *pos; if (!mode || !is_6ghz_op_class(hapd->iconf->op_class)) @@ -326,7 +326,8 @@ u8 * hostapd_eid_he_6ghz_band_cap(struct hostapd_data *hapd, u8 *eid) if (!he_cap->he_6ghz_supported) return eid; - capab = he_cap->he_6ghz_cap; + capab |= (he_cap->he_6ghz_cap & + HE_6GHZ_BAND_CAP_MIN_MPDU_START_SPACE_MASK); capab |= HE_6GHZ_BAND_CAP_SMPS_DISABLED; pos = eid; -- 2.7.4 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap