[PATCH 5/5] HE: Add spatial reuse IEs to the beacon

John Crispin john at phrozen.org
Tue Apr 16 05:34:01 PDT 2019


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 at datto.com>
Signed-off-by: John Crispin <john at phrozen.org>
---
 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




More information about the Hostap mailing list