diff mbox series

[13/16] hostapd: MLO: fix advertisement of MLD capabilities

Message ID 20240306173947.2611965-14-quic_adisi@quicinc.com
State Accepted
Headers show
Series hostapd: scale up MLO flows | expand

Commit Message

Aditya Kumar Singh March 6, 2024, 5:39 p.m. UTC
Currently, hostapd directly advertises the MLD capabilities received from
the driver. Since this info is exchanged during init time only, driver will
advertise the max supported possible values. Hostapd should parse it and
then based on current situation should fill the values accordingly.

For example, Max number of simultaneous links is supposed to be value
between 0 and 14, which is the number of affiliated APs minus 1. Driver
advertises this value as 5 and hostapd, irrespective of current active
links, it puts 5 in the frames.

Fix this issue by parsing the value and at the same time using the values
as per the current situation of the links. The advertised values will be
used as the upper limit.

While at it, also print the MLD capabilities in debug print.

Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
---
 src/ap/ieee802_11_eht.c           | 30 ++++++++++++++++++++++++++----
 src/common/ieee802_11_defs.h      |  5 +++++
 src/drivers/driver_nl80211_capa.c |  4 ++++
 3 files changed, 35 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/src/ap/ieee802_11_eht.c b/src/ap/ieee802_11_eht.c
index 826edc5029d8..c908f9a1af08 100644
--- a/src/ap/ieee802_11_eht.c
+++ b/src/ap/ieee802_11_eht.c
@@ -452,13 +452,13 @@  static u8 * hostapd_eid_eht_basic_ml_common(struct hostapd_data *hapd,
 					    bool include_mld_id)
 {
 	struct wpabuf *buf;
-	u16 control;
+	u16 control, mld_cap;
 	u8 *pos = eid;
 	const u8 *ptr;
 	size_t len, slice_len;
 	u8 link_id;
 	u8 common_info_len;
-
+	u8 max_simul_links, tid_to_link_map, active_links;
 	/*
 	 * As the Multi-Link element can exceed the size of 255 bytes need to
 	 * first build it and then handle fragmentation.
@@ -507,9 +507,31 @@  static u8 * hostapd_eid_eht_basic_ml_common(struct hostapd_data *hapd,
 		   hapd->iface->mld_eml_capa);
 	wpabuf_put_le16(buf, hapd->iface->mld_eml_capa);
 
+	mld_cap = hapd->iface->mld_mld_capa;
+	max_simul_links = mld_cap & MLE_MLD_CAP_MAX_SIMULTANEOUS_LINK_MASK;
+	tid_to_link_map = (mld_cap & MLE_MLD_CAP_TID_TO_LINK_MAP_MASK) >>
+			  MLE_MLD_CAP_TID_TO_LINK_MAP_SHIFT;
+	active_links = hapd->mld->num_links - 1;
+
+	if (active_links > max_simul_links) {
+		wpa_printf(MSG_ERROR,
+			   "MLD: Error in max simultaneous links, advertised: 0x%x current: 0x%x",
+			   max_simul_links, active_links);
+		active_links = max_simul_links;
+	}
+
+	mld_cap &= ~MLE_MLD_CAP_MAX_SIMULTANEOUS_LINK_MASK;
+	mld_cap |= (active_links & MLE_MLD_CAP_MAX_SIMULTANEOUS_LINK_MASK);
+
+	/* TODO: advertise T2LM based on driver support as well */
+	tid_to_link_map = MLE_MLD_CAP_TID_TO_LINK_MAP_DISABLED;
+
+	mld_cap &= ~MLE_MLD_CAP_TID_TO_LINK_MAP_MASK;
+	mld_cap |= (tid_to_link_map << MLE_MLD_CAP_TID_TO_LINK_MAP_SHIFT);
+
 	wpa_printf(MSG_DEBUG, "MLD: MLD Capabilities and Operations=0x%x",
-		   hapd->iface->mld_mld_capa);
-	wpabuf_put_le16(buf, hapd->iface->mld_mld_capa);
+		   mld_cap);
+	wpabuf_put_le16(buf, mld_cap);
 
 	if (include_mld_id) {
 		wpa_printf(MSG_DEBUG, "MLD: AP MLD ID=0x%x",
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
index d070e42b875d..f2b7fa33a767 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -2719,6 +2719,11 @@  struct ieee80211_eht_capabilities {
 #define BASIC_MULTI_LINK_CTRL_PRES_MLD_CAPA		0x0100
 #define BASIC_MULTI_LINK_CTRL_PRES_AP_MLD_ID		0x0200
 
+#define MLE_MLD_CAP_MAX_SIMULTANEOUS_LINK_MASK ((u8)(BIT(0) | BIT(1) | BIT(2) | BIT(3)))
+#define MLE_MLD_CAP_TID_TO_LINK_MAP_SHIFT      5
+#define MLE_MLD_CAP_TID_TO_LINK_MAP_MASK       ((u8)(BIT(5) | BIT(6)))
+#define MLE_MLD_CAP_TID_TO_LINK_MAP_DISABLED   0
+
 /*
  * STA Control field definitions of Per-STA Profile subelement in Basic
  * Multi-Link element as described in Figure 9-1002n: STA Control field format.
diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
index 3bcd66c24533..65389d2069c0 100644
--- a/src/drivers/driver_nl80211_capa.c
+++ b/src/drivers/driver_nl80211_capa.c
@@ -889,6 +889,10 @@  static void wiphy_info_extended_capab(struct wpa_driver_nl80211_data *drv,
 				nla_get_u16(tb1[NL80211_ATTR_MLD_CAPA_AND_OPS]);
 		}
 
+		wpa_printf(MSG_DEBUG,
+			   "nl80211: EML Capability: 0x%x MLD Capability: 0x%x",
+			   capa->eml_capa, capa->mld_capa_and_ops);
+
 		drv->num_iface_capa++;
 		if (drv->num_iface_capa == NL80211_IFTYPE_MAX)
 			break;