[PATCH v2 6/7] driver_nl80211: add UHR support

Johannes Berg johannes at sipsolutions.net
Tue Mar 17 09:35:54 PDT 2026


From: Johannes Berg <johannes.berg at intel.com>

Add UHR support to driver_nl80211, capturing capabilities and
setting them per stations, and sending the UHR operation down
for UHR AP configuration.

Signed-off-by: Johannes Berg <johannes.berg at intel.com>
---
 src/drivers/driver_nl80211.c      | 23 +++++++++++++++++++++++
 src/drivers/driver_nl80211_capa.c | 19 +++++++++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 031e68704dc8..1f56bbf8f963 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -5866,6 +5866,15 @@ static int wpa_driver_nl80211_set_ap(void *priv,
 		goto fail;
 #endif /* CONFIG_IEEE80211AX */
 
+#ifdef CONFIG_IEEE80211BN
+	if (params->uhr_oper &&
+	    nla_put(msg, NL80211_ATTR_UHR_OPERATION,
+		    /* nl80211 wants it without the extended element header */
+		    params->uhr_oper[1] - 1,
+		    params->uhr_oper + 3))
+		goto fail;
+#endif /* CONFIG_IEEE80211BN */
+
 #ifdef CONFIG_SAE
 	if (wpa_key_mgmt_sae(params->key_mgmt_suites) &&
 	    nl80211_put_sae_pwe(msg, params->sae_pwe) < 0)
@@ -6138,6 +6147,14 @@ static int wpa_driver_nl80211_sta_add(void *priv,
 				goto fail;
 		}
 
+		if (params->uhr_capab) {
+			wpa_hexdump(MSG_DEBUG, "  * uhr_capab",
+				    params->uhr_capab, params->uhr_capab_len);
+			if (nla_put(msg, NL80211_ATTR_UHR_CAPABILITY,
+				    params->uhr_capab_len, params->uhr_capab))
+				goto fail;
+		}
+
 		if (params->ext_capab) {
 			wpa_hexdump(MSG_DEBUG, "  * ext_capab",
 				    params->ext_capab, params->ext_capab_len);
@@ -7027,6 +7044,12 @@ static int nl80211_ht_vht_overrides(struct nl_msg *msg,
 			return -1;
 	}
 
+	if (params->disable_uhr) {
+		wpa_printf(MSG_DEBUG, "  * UHR disabled");
+		if (nla_put_flag(msg, NL80211_ATTR_DISABLE_UHR))
+			return -1;
+	}
+
 	return 0;
 }
 
diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
index 18154e2445a4..5b36982dea92 100644
--- a/src/drivers/driver_nl80211_capa.c
+++ b/src/drivers/driver_nl80211_capa.c
@@ -2012,6 +2012,7 @@ static void phy_info_iftype_copy(struct hostapd_hw_modes *mode,
 	size_t len;
 	struct he_capabilities *he_capab = &mode->he_capab[opmode];
 	struct eht_capabilities *eht_capab = &mode->eht_capab[opmode];
+	struct uhr_capabilities *uhr_capab = &mode->uhr_capab[opmode];
 
 	switch (opmode) {
 	case IEEE80211_MODE_INFRA:
@@ -2119,6 +2120,24 @@ static void phy_info_iftype_copy(struct hostapd_hw_modes *mode,
 			  nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE]),
 			  len);
 	}
+
+	if (!tb[NL80211_BAND_IFTYPE_ATTR_UHR_CAP_MAC] ||
+	    !tb[NL80211_BAND_IFTYPE_ATTR_UHR_CAP_PHY])
+		return;
+
+	uhr_capab->uhr_supported = true;
+
+	if (tb[NL80211_BAND_IFTYPE_ATTR_UHR_CAP_MAC] &&
+	    nla_len(tb[NL80211_BAND_IFTYPE_ATTR_UHR_CAP_MAC]) >= (int)sizeof(uhr_capab->mac))
+		os_memcpy(uhr_capab->mac,
+			  nla_data(tb[NL80211_BAND_IFTYPE_ATTR_UHR_CAP_MAC]),
+			  sizeof(uhr_capab->mac));
+
+	if (tb[NL80211_BAND_IFTYPE_ATTR_UHR_CAP_PHY] &&
+	    nla_len(tb[NL80211_BAND_IFTYPE_ATTR_UHR_CAP_PHY]) >= (int)sizeof(uhr_capab->phy))
+		os_memcpy(uhr_capab->phy,
+			  nla_data(tb[NL80211_BAND_IFTYPE_ATTR_UHR_CAP_PHY]),
+			  sizeof(uhr_capab->phy));
 }
 
 
-- 
2.53.0




More information about the Hostap mailing list