SPR allows us to detect OBSS overlaps and allows us to do adaptiv CCA thresholds. For this to work the AP needs to broadcast the IE first. Signed-off-by: Shashidhar Lakkavalli <slakkavalli@xxxxxxxxx> Signed-off-by: John Crispin <john@xxxxxxxxxxx> --- hostapd/config_file.c | 8 ++++++++ src/ap/ap_config.h | 13 +++++++++++++ src/ap/beacon.c | 8 ++++++-- src/ap/ieee802_11.h | 1 + src/ap/ieee802_11_he.c | 42 ++++++++++++++++++++++++++++++++++++++++++ src/common/ieee802_11_defs.h | 10 +++++++++- 6 files changed, 79 insertions(+), 3 deletions(-) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 42f3b40ef..c4c838dc8 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -3526,6 +3526,14 @@ static int hostapd_config_fill(struct hostapd_config *conf, } else if (os_strcmp(buf, "he_mu_edca_ac_vo_timer") == 0) { conf->he_mu_edca.he_mu_ac_vo_param[HE_MU_AC_PARAM_TIMER_IDX] = atoi(pos) & 0xff; + } else if (os_strcmp(buf, "he_srp_sr_control") == 0) { + conf->he_spr.sr_control = atoi(pos) & 0xff; + } else if (os_strcmp(buf, "he_srp_non_srg_obss_pd_max_offset") == 0) { + conf->he_spr.non_srg_obss_pd_max_offset = atoi(pos); + } else if (os_strcmp(buf, "he_srp_srg_obss_pd_min_offset") == 0) { + conf->he_spr.srg_obss_pd_min_offset = atoi(pos); + } else if (os_strcmp(buf, "he_srp_srg_obss_pd_max_offset") == 0) { + conf->he_spr.srg_obss_pd_max_offset = atoi(pos); #endif /* CONFIG_IEEE80211AX */ } else if (os_strcmp(buf, "max_listen_interval") == 0) { bss->max_listen_interval = atoi(pos); diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 82d17cbf4..b57705ec4 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -731,6 +731,18 @@ struct he_operation { }; /** + * struct he_operation - HE operation + */ +struct he_spatial_reuse { + u8 sr_control; + u8 non_srg_obss_pd_max_offset; + u8 srg_obss_pd_min_offset; + u8 srg_obss_pd_max_offset; + u8 srg_obss_color_bitmap; + u8 srg_obss_color_partial_bitmap; +}; + +/** * struct hostapd_config - Per-radio interface configuration */ struct hostapd_config { @@ -852,6 +864,7 @@ struct hostapd_config { struct he_phy_capabilities_info he_phy_capab; struct he_operation he_op; struct ieee80211_he_mu_edca_parameter_set he_mu_edca; + struct he_spatial_reuse he_spr; #endif /* CONFIG_IEEE80211AX */ /* VHT enable/disable config from CHAN_SWITCH */ diff --git a/src/ap/beacon.c b/src/ap/beacon.c index 3e62991d0..bbc3db12f 100644 --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -398,7 +398,8 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, if (hapd->iconf->ieee80211ax) { buflen += 3 + sizeof(struct ieee80211_he_capabilities) + 3 + sizeof(struct ieee80211_he_operation) + - 3 + sizeof(struct ieee80211_he_mu_edca_parameter_set); + 3 + sizeof(struct ieee80211_he_mu_edca_parameter_set) + + 3 + sizeof(struct ieee80211_he_spatial_reuse); } #endif /* CONFIG_IEEE80211AX */ @@ -512,6 +513,7 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, pos = hostapd_eid_he_capab(hapd, pos); pos = hostapd_eid_he_operation(hapd, pos); pos = hostapd_eid_he_mu_edca_parameter_set(hapd, pos); + pos = hostapd_eid_he_spatial_reuse(hapd, pos); } #endif /* CONFIG_IEEE80211AX */ @@ -1088,7 +1090,8 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, if (hapd->iconf->ieee80211ax) { tail_len += 3 + sizeof(struct ieee80211_he_capabilities) + 3 + sizeof(struct ieee80211_he_operation) + - 3 + sizeof(struct ieee80211_he_mu_edca_parameter_set); + 3 + sizeof(struct ieee80211_he_mu_edca_parameter_set) + + 3 + sizeof(struct ieee80211_he_spatial_reuse); } #endif /* CONFIG_IEEE80211AX */ @@ -1226,6 +1229,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, tailpos = hostapd_eid_he_capab(hapd, tailpos); tailpos = hostapd_eid_he_operation(hapd, tailpos); tailpos = hostapd_eid_he_mu_edca_parameter_set(hapd, tailpos); + tailpos = hostapd_eid_he_spatial_reuse(hapd, tailpos); } #endif /* CONFIG_IEEE80211AX */ diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h index db7badcff..3a1671e60 100644 --- a/src/ap/ieee802_11.h +++ b/src/ap/ieee802_11.h @@ -60,6 +60,7 @@ u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid); u8 * hostapd_eid_he_capab(struct hostapd_data *hapd, u8 *eid); u8 * hostapd_eid_he_operation(struct hostapd_data *hapd, u8 *eid); u8 * hostapd_eid_he_mu_edca_parameter_set(struct hostapd_data *hapd, u8 *eid); +u8 * hostapd_eid_he_spatial_reuse(struct hostapd_data *hapd, u8 *eid); int hostapd_ht_operation_update(struct hostapd_iface *iface); void ieee802_11_send_sa_query_req(struct hostapd_data *hapd, diff --git a/src/ap/ieee802_11_he.c b/src/ap/ieee802_11_he.c index ba300e390..2c3c1d6d2 100644 --- a/src/ap/ieee802_11_he.c +++ b/src/ap/ieee802_11_he.c @@ -124,3 +124,45 @@ u8 * hostapd_eid_he_mu_edca_parameter_set(struct hostapd_data *hapd, u8 *eid) return pos; } + + +u8 * hostapd_eid_he_spatial_reuse(struct hostapd_data *hapd, u8 *eid) +{ + struct ieee80211_he_spatial_reuse *spr; + u8 *pos = eid, *spr_param; + u8 sz = 1; + + if (hapd->iface->conf->he_spr.sr_control & + HE_SPATIAL_REUSE_NONE_SRG_OFFSET_PRESENT) { + sz++; + } + + if (hapd->iface->conf->he_spr.sr_control & + HE_SPATIAL_REUSE_SRG_INFORMATION_PRESENT) { + sz += 18; + } + + *pos++ = WLAN_EID_EXTENSION; + *pos++ = 1 + sz; + *pos++ = WLAN_EID_EXT_HE_SPATIAL_REUSE; + + spr = (struct ieee80211_he_spatial_reuse *) pos; + os_memset(spr, 0, sizeof(*spr)); + + spr->he_spr_sr_ctrl = + hapd->iface->conf->he_spr.sr_control; + pos++; + spr_param = spr->he_spr_params; + if (spr->he_spr_sr_ctrl & HE_SPATIAL_REUSE_NONE_SRG_OFFSET_PRESENT) { + *spr_param++ = + hapd->iface->conf->he_spr.non_srg_obss_pd_max_offset; + pos++; + } + if (spr->he_spr_sr_ctrl & HE_SPATIAL_REUSE_SRG_INFORMATION_PRESENT) { + *spr_param++ = hapd->iface->conf->he_spr.srg_obss_pd_min_offset; + *spr_param++ = hapd->iface->conf->he_spr.srg_obss_pd_max_offset; + pos += 18; + } + + return pos; +} diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index c9e8edf6f..f26d1c0de 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -468,6 +468,7 @@ #define WLAN_EID_EXT_HE_CAPABILITIES 35 #define WLAN_EID_EXT_HE_OPERATION 36 #define WLAN_EID_EXT_HE_MU_EDCA_PARAMS 38 +#define WLAN_EID_EXT_HE_SPATIAL_REUSE 39 #define WLAN_EID_EXT_OCV_OCI 54 /* Extended Capabilities field */ @@ -2118,6 +2119,11 @@ struct ieee80211_he_operation { /* Followed by conditional MaxBSSID Indicator subfield (u8) */ } STRUCT_PACKED; +struct ieee80211_he_spatial_reuse { + u8 he_spr_sr_ctrl; + u8 he_spr_params[19]; +} STRUCT_PACKED; + /* HE Capabilities Information defines */ #define HE_PHYCAP_SU_BEAMFORMER_CAPAB_IDX 3 #define HE_PHYCAP_SU_BEAMFORMER_CAPAB ((u8) BIT(7)) @@ -2145,7 +2151,9 @@ struct ieee80211_he_operation { #define HE_OPERATION_BSS_COLOR_DISABLED ((u32) BIT(31)) #define HE_OPERATION_BSS_COLOR_OFFSET 24 - +/* HE Spatial Reuse defines */ +#define HE_SPATIAL_REUSE_NONE_SRG_OFFSET_PRESENT 0x4 +#define HE_SPATIAL_REUSE_SRG_INFORMATION_PRESENT 0x8 struct ieee80211_he_mu_edca_parameter_set { u8 he_qos_info; -- 2.11.0 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap