[PATCH 8/9] AP: Process HE 6 GHz band capab from HE STA

Rajkumar Manoharan <[email protected]>
Newsgroups gmane.linux.drivers.hostap
Message-ID <[email protected]>
Process HE 6 GHz band capabilities in (Re)Association Request frames
and pass the information to driver.

Signed-off-by: Rajkumar Manoharan <[email protected]>
---
 src/ap/ap_drv_ops.c    |  2 ++
 src/ap/ap_drv_ops.h    |  1 +
 src/ap/ieee802_11.c    | 11 ++++++++++-
 src/ap/ieee802_11.h    |  2 ++
 src/ap/ieee802_11_he.c | 25 +++++++++++++++++++++++++
 src/ap/sta_info.c      |  6 ++++--
 src/ap/sta_info.h      |  2 ++
 src/drivers/driver.h   |  1 +
 8 files changed, 47 insertions(+), 3 deletions(-)

diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
index 1f284f0f38d0..014c1788f6af 100644
--- a/src/ap/ap_drv_ops.c
+++ b/src/ap/ap_drv_ops.c
@@ -418,6 +418,7 @@ int hostapd_sta_add(struct hostapd_data *hapd,
 		    const struct ieee80211_vht_capabilities *vht_capab,
 		    const struct ieee80211_he_capabilities *he_capab,
 		    size_t he_capab_len,
+		    const struct ieee80211_he_6ghz_band_cap *he_6ghz_capab,
 		    u32 flags, u8 qosinfo, u8 vht_opmode, int supp_p2p_ps,
 		    int set)
 {
@@ -439,6 +440,7 @@ int hostapd_sta_add(struct hostapd_data *hapd,
 	params.vht_capabilities = vht_capab;
 	params.he_capab = he_capab;
 	params.he_capab_len = he_capab_len;
+	params.he_6ghz_capab = he_6ghz_capab;
 	params.vht_opmode_enabled = !!(flags & WLAN_STA_VHT_OPMODE_ENABLED);
 	params.vht_opmode = vht_opmode;
 	params.flags = hostapd_sta_flags_to_drv(flags);
diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
index 56d1ad86266b..c342ba8a330d 100644
--- a/src/ap/ap_drv_ops.h
+++ b/src/ap/ap_drv_ops.h
@@ -43,6 +43,7 @@ int hostapd_sta_add(struct hostapd_data *hapd,
 		    const struct ieee80211_vht_capabilities *vht_capab,
 		    const struct ieee80211_he_capabilities *he_capab,
 		    size_t he_capab_len,
+		    const struct ieee80211_he_6ghz_band_cap *he_6ghz_capab,
 		    u32 flags, u8 qosinfo, u8 vht_opmode, int supp_p2p_ps,
 		    int set);
 int hostapd_set_privacy(struct hostapd_data *hapd, int enabled);
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index b3644aa7991e..be95868b396f 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -3200,8 +3200,16 @@ static int check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
 			return resp;
 	}
 
+	if (is_6ghz_op_class(hapd->iconf->op_class)) {
+		resp = copy_sta_he_6ghz_capab(hapd, sta,
+					      elems.he_6ghz_band_cap);
+		if (resp != WLAN_STATUS_SUCCESS)
+			return resp;
+	}
+
 	if (is_6ghz_op_class(hapd->iconf->op_class) &&
-	    !(sta->flags & WLAN_STA_HE)) {
+	    (!(sta->flags & WLAN_STA_HE) ||
+	     !(sta->flags & WLAN_STA_6GHZ))) {
 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
 			       HOSTAPD_LEVEL_INFO, "Station does not support "
 			       "mandatory HE PHY - reject association");
@@ -3651,6 +3659,7 @@ static int add_associated_sta(struct hostapd_data *hapd,
 			    sta->flags & WLAN_STA_VHT ? &vht_cap : NULL,
 			    sta->flags & WLAN_STA_HE ? &he_cap : NULL,
 			    sta->flags & WLAN_STA_HE ? sta->he_capab_len : 0,
+			    sta->he_6ghz_capab,
 			    sta->flags | WLAN_STA_ASSOC, sta->qosinfo,
 			    sta->vht_opmode, sta->p2p_ie ? 1 : 0,
 			    set)) {
diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h
index ba505628982d..ea8c60846936 100644
--- a/src/ap/ieee802_11.h
+++ b/src/ap/ieee802_11.h
@@ -96,6 +96,8 @@ u16 set_sta_vht_opmode(struct hostapd_data *hapd, struct sta_info *sta,
 u16 copy_sta_he_capab(struct hostapd_data *hapd, struct sta_info *sta,
 		      enum ieee80211_op_mode opmode, const u8 *he_capab,
 		      size_t he_capab_len);
+u16 copy_sta_he_6ghz_capab(struct hostapd_data *hapd, struct sta_info *sta,
+			   const u8 *he_6ghz_capab);
 int hostapd_get_he_twt_responder(struct hostapd_data *hapd,
 				 enum ieee80211_op_mode mode);
 void hostapd_tx_status(struct hostapd_data *hapd, const u8 *addr,
diff --git a/src/ap/ieee802_11_he.c b/src/ap/ieee802_11_he.c
index 2c1b41d28cc4..ec5fb1bb702d 100644
--- a/src/ap/ieee802_11_he.c
+++ b/src/ap/ieee802_11_he.c
@@ -461,6 +461,31 @@ u16 copy_sta_he_capab(struct hostapd_data *hapd, struct sta_info *sta,
 }
 
 
+u16 copy_sta_he_6ghz_capab(struct hostapd_data *hapd, struct sta_info *sta,
+			   const u8 *he_6ghz_capab)
+{
+	if (!he_6ghz_capab || !is_6ghz_op_class(hapd->iconf->op_class)) {
+		sta->flags &= ~WLAN_STA_6GHZ;
+		os_free(sta->he_6ghz_capab);
+		sta->he_6ghz_capab = NULL;
+		return WLAN_STATUS_SUCCESS;
+	}
+
+	if (!sta->he_6ghz_capab) {
+		sta->he_6ghz_capab =
+			os_zalloc(sizeof(struct ieee80211_he_6ghz_band_cap));
+		if (!sta->he_6ghz_capab)
+			return WLAN_STATUS_UNSPECIFIED_FAILURE;
+	}
+
+	sta->flags |= WLAN_STA_6GHZ;
+	os_memcpy(sta->he_6ghz_capab, he_6ghz_capab,
+		  sizeof(struct ieee80211_he_6ghz_band_cap));
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+
 int hostapd_get_he_twt_responder(struct hostapd_data *hapd,
 				 enum ieee80211_op_mode mode)
 {
diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c
index 93f1f0c201e1..69ac540b59a5 100644
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
@@ -1424,7 +1424,8 @@ int ap_sta_flags_txt(u32 flags, char *buf, size_t buflen)
 	int res;
 
 	buf[0] = '\0';
-	res = os_snprintf(buf, buflen, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+	res = os_snprintf(buf, buflen,
+			  "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
 			  (flags & WLAN_STA_AUTH ? "[AUTH]" : ""),
 			  (flags & WLAN_STA_ASSOC ? "[ASSOC]" : ""),
 			  (flags & WLAN_STA_AUTHORIZED ? "[AUTHORIZED]" : ""),
@@ -1444,6 +1445,7 @@ int ap_sta_flags_txt(u32 flags, char *buf, size_t buflen)
 			  (flags & WLAN_STA_HT ? "[HT]" : ""),
 			  (flags & WLAN_STA_VHT ? "[VHT]" : ""),
 			  (flags & WLAN_STA_HE ? "[HE]" : ""),
+			  (flags & WLAN_STA_6GHZ ? "[6GHZ]" : ""),
 			  (flags & WLAN_STA_VENDOR_VHT ? "[VENDOR_VHT]" : ""),
 			  (flags & WLAN_STA_WNM_SLEEP_MODE ?
 			   "[WNM_SLEEP_MODE]" : ""));
@@ -1515,7 +1517,7 @@ int ap_sta_re_add(struct hostapd_data *hapd, struct sta_info *sta)
 	if (hostapd_sta_add(hapd, sta->addr, 0, 0,
 			    sta->supported_rates,
 			    sta->supported_rates_len,
-			    0, NULL, NULL, NULL, 0,
+			    0, NULL, NULL, NULL, 0, NULL,
 			    sta->flags, 0, 0, 0, 0)) {
 		hostapd_logger(hapd, sta->addr,
 			       HOSTAPD_MODULE_IEEE80211,
diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h
index 308aa29d992c..940d3159082f 100644
--- a/src/ap/sta_info.h
+++ b/src/ap/sta_info.h
@@ -38,6 +38,7 @@
 #define WLAN_STA_PENDING_FILS_ERP BIT(22)
 #define WLAN_STA_MULTI_AP BIT(23)
 #define WLAN_STA_HE BIT(24)
+#define WLAN_STA_6GHZ BIT(25)
 #define WLAN_STA_PENDING_DISASSOC_CB BIT(29)
 #define WLAN_STA_PENDING_DEAUTH_CB BIT(30)
 #define WLAN_STA_NONERP BIT(31)
@@ -170,6 +171,7 @@ struct sta_info {
 	u8 vht_opmode;
 	struct ieee80211_he_capabilities *he_capab;
 	size_t he_capab_len;
+	struct ieee80211_he_6ghz_band_cap *he_6ghz_capab;
 
 	int sa_query_count; /* number of pending SA Query requests;
 			     * 0 = no SA Query in progress */
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index e3b13bc25197..2ebda031497b 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -2018,6 +2018,7 @@ struct hostapd_sta_add_params {
 	u8 vht_opmode;
 	const struct ieee80211_he_capabilities *he_capab;
 	size_t he_capab_len;
+	const struct ieee80211_he_6ghz_band_cap *he_6ghz_capab;
 	u32 flags; /* bitmask of WPA_STA_* flags */
 	u32 flags_mask; /* unset bits in flags */
 #ifdef CONFIG_MESH
-- 
2.7.4
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.