Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.2/patches/2234570/?format=api
{ "id": 2234570, "url": "http://patchwork.ozlabs.org/api/1.2/patches/2234570/?format=api", "web_url": "http://patchwork.ozlabs.org/project/hostap/patch/20260507192335.7612031264fc.I1dd16bb1ffbcf19c38d2d73626776aca4070fbc1@changeid/", "project": { "id": 22, "url": "http://patchwork.ozlabs.org/api/1.2/projects/22/?format=api", "name": "HostAP Development", "link_name": "hostap", "list_id": "hostap.lists.infradead.org", "list_email": "hostap@lists.infradead.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260507192335.7612031264fc.I1dd16bb1ffbcf19c38d2d73626776aca4070fbc1@changeid>", "list_archive_url": null, "date": "2026-05-07T17:21:29", "name": "[v3,02/12] initial UHR support", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "fd4d396db935c23338481ed12a9e15434ae3d5ec", "submitter": { "id": 265, "url": "http://patchwork.ozlabs.org/api/1.2/people/265/?format=api", "name": "Johannes Berg", "email": "johannes@sipsolutions.net" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/hostap/patch/20260507192335.7612031264fc.I1dd16bb1ffbcf19c38d2d73626776aca4070fbc1@changeid/mbox/", "series": [ { "id": 503235, "url": "http://patchwork.ozlabs.org/api/1.2/series/503235/?format=api", "web_url": "http://patchwork.ozlabs.org/project/hostap/list/?series=503235", "date": "2026-05-07T17:21:28", "name": "some UHR support", "version": 3, "mbox": "http://patchwork.ozlabs.org/series/503235/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2234570/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2234570/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "\n <hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n secure) header.d=lists.infradead.org header.i=@lists.infradead.org\n header.a=rsa-sha256 header.s=bombadil.20210309 header.b=FEWjDcf5;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n secure) header.d=sipsolutions.net header.i=@sipsolutions.net\n header.a=rsa-sha256 header.s=mail header.b=juFVKKdI;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=none (no SPF record) smtp.mailfrom=lists.infradead.org\n (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org;\n envelope-from=hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org;\n receiver=patchwork.ozlabs.org)" ], "Received": [ "from bombadil.infradead.org (bombadil.infradead.org\n [IPv6:2607:7c80:54:3::133])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4gBPyM2dCMz1yK7\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 08 May 2026 07:09:31 +1000 (AEST)", "from localhost ([::1] helo=bombadil.infradead.org)\n\tby bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux))\n\tid 1wL5ws-00000004stC-2qRk;\n\tThu, 07 May 2026 21:07:58 +0000", "from s3.sipsolutions.net ([2a01:4f8:242:246e::2]\n helo=sipsolutions.net)\n\tby bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux))\n\tid 1wL2S0-00000004SUE-0U15\n\tfor hostap@lists.infradead.org;\n\tThu, 07 May 2026 17:23:55 +0000", "by sipsolutions.net with esmtpsa\n (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256)\n\t(Exim 4.98.2)\n\t(envelope-from <johannes@sipsolutions.net>)\n\tid 1wL2Rr-000000045pG-0166;\n\tThu, 07 May 2026 19:23:43 +0200" ], "DKIM-Signature": [ "v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;\n\td=lists.infradead.org; s=bombadil.20210309; h=Sender:\n\tContent-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post:\n\tList-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:\n\tMessage-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description:\n\tResent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:\n\tList-Owner; bh=pq4mKxRoo9xyaizTA4RMnZ7IZNKEYlTWq4wUcBSaCl8=; b=FEWjDcf5as/rhN\n\tTGMyLOzDUnB3fczzTitdCB4GNNZdFutkf/hMdGSIIbiCYMMAWBxbEGC6Bubtm2Kx5/ewn6tI0oJbL\n\tpfwHbzr4xFWBZGmU0MJjWgGywlkGAtxZ0gkFw9khAUfS6Axg53Rsfh2/0LHR2cSaAxN7wcqkxUAjt\n\tKZvUPpnBq3Cmc8Yo7/R0icoHsE6/wvW2+VIfHTH1SyhcHOD5LTb5Riz4nyvq0ugIs0Nj6WdCx+W5i\n\tuz3VU/GQr8PVjTaSvrYZTfGhOClK0gP0fdWhts/w81YcjXNBjK1zXzxV/VBaWThS4bEikj4EOb0gc\n\tPDbO7srW9Cot6TJrmLUg==;", "v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;\n\td=sipsolutions.net; s=mail; h=Content-Transfer-Encoding:MIME-Version:\n\tReferences:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Content-Type:Sender\n\t:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-To:\n\tResent-Cc:Resent-Message-ID; bh=BNPQHZFL3uOUM/+E2uEPujyrdlW4qQu43ZNhdS6tVWs=;\n\tt=1778174632; x=1779384232; b=juFVKKdI16xZXbaQvYw7VUnEmUQmNd+VhA23HrhRQ2pkkAv\n\t9Vy0smQ5uOZUZo/NqeKDK+XnlVGOycB2UAT0eQ5+iRtKVh57dkQmo/yngQv3qDiEIx8ebqS8AJZEt\n\tHz6ReA7cvOSL1IUmieubwWcBoop8Rt/WMFlg7w5UVJP4e8n5vUbIQj/koRHeTlj+QtEiTVcM1rrz4\n\t/S15E4Tmnf9ulQgJi24IuJNhh7Iy5Rs3BX5Dy3+20qDlKbhtTjDDRTaOFIQBJHPD2dmjKfT0XJLwP\n\tpg6MmWjmrhOfYtcLeGVNGu0fav9MdMgD9ah/kpCMF96cXZgYN6eELK1CjY45Zs+A==;" ], "From": "Johannes Berg <johannes@sipsolutions.net>", "To": "hostap@lists.infradead.org", "Cc": "Johannes Berg <johannes.berg@intel.com>", "Subject": "[PATCH v3 02/12] initial UHR support", "Date": "Thu, 7 May 2026 19:21:29 +0200", "Message-ID": "\n <20260507192335.7612031264fc.I1dd16bb1ffbcf19c38d2d73626776aca4070fbc1@changeid>", "X-Mailer": "git-send-email 2.53.0", "In-Reply-To": "<20260507172335.546456-14-johannes@sipsolutions.net>", "References": "<20260507172335.546456-14-johannes@sipsolutions.net>", "MIME-Version": "1.0", "X-CRM114-Version": "20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 ", "X-CRM114-CacheID": "sfid-20260507_102352_654198_506B7039 ", "X-CRM114-Status": "GOOD ( 24.46 )", "X-Spam-Score": "-2.1 (--)", "X-Spam-Report": "Spam detection software,\n running on the system \"bombadil.infradead.org\",\n has NOT identified this incoming email as spam. The original\n message has been attached to this so you can view it or label\n similar future email. If you have any questions, see\n the administrator of that system for details.\n Content preview: From: Johannes Berg <johannes.berg@intel.com> Add initial\n UHR support, based on a very \"superficial\" reading of D1.3/D1.4 (which are\n incomplete and not well- specified in quite a few places.) Signed-off-by:\n Johannes Berg <johannes.berg@intel.com> --- hostapd/Android.mk | 6 +\n hostapd/Makefile\n | 6 + hostapd/config_file.c | 8 ++ hostapd/hostapd.conf | 13 ++\n src/ap/ap_config.h\n | 6 + src/ap/ap_ [...]\n Content analysis details: (-2.1 points, 5.0 required)\n pts rule name description\n ---- ----------------------\n --------------------------------------------------\n 0.0 SPF_NONE SPF: sender does not publish an SPF Record\n 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record\n -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from\n envelope-from domain\n -0.1 DKIM_VALID Message has at least one valid DKIM or DK\n signature\n -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from\n author's\n domain\n 0.1 DKIM_SIGNED Message has a DKIM or DK signature,\n not necessarily valid\n -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1%\n [score: 0.0000]\n -0.0 DMARC_PASS DMARC pass policy", "X-Mailman-Approved-At": "Thu, 07 May 2026 14:07:57 -0700", "X-BeenThere": "hostap@lists.infradead.org", "X-Mailman-Version": "2.1.34", "Precedence": "list", "List-Id": "<hostap.lists.infradead.org>", "List-Unsubscribe": "<http://lists.infradead.org/mailman/options/hostap>,\n <mailto:hostap-request@lists.infradead.org?subject=unsubscribe>", "List-Archive": "<http://lists.infradead.org/pipermail/hostap/>", "List-Post": "<mailto:hostap@lists.infradead.org>", "List-Help": "<mailto:hostap-request@lists.infradead.org?subject=help>", "List-Subscribe": "<http://lists.infradead.org/mailman/listinfo/hostap>,\n <mailto:hostap-request@lists.infradead.org?subject=subscribe>", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Sender": "\"Hostap\" <hostap-bounces@lists.infradead.org>", "Errors-To": "hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org" }, "content": "From: Johannes Berg <johannes.berg@intel.com>\n\nAdd initial UHR support, based on a very \"superficial\"\nreading of D1.3/D1.4 (which are incomplete and not well-\nspecified in quite a few places.)\n\nSigned-off-by: Johannes Berg <johannes.berg@intel.com>\n---\n hostapd/Android.mk | 6 +\n hostapd/Makefile | 6 +\n hostapd/config_file.c | 8 ++\n hostapd/hostapd.conf | 13 ++\n src/ap/ap_config.h | 6 +\n src/ap/ap_drv_ops.c | 4 +\n src/ap/ap_drv_ops.h | 2 +\n src/ap/beacon.c | 24 ++++\n src/ap/ctrl_iface_ap.c | 16 +++\n src/ap/hostapd.h | 6 +\n src/ap/ieee802_11.c | 52 +++++++-\n src/ap/ieee802_11.h | 13 ++\n src/ap/ieee802_11_uhr.c | 145 +++++++++++++++++++++\n src/ap/sta_info.c | 10 +-\n src/ap/sta_info.h | 65 ++++-----\n src/common/ieee802_11_common.c | 16 +++\n src/common/ieee802_11_common.h | 4 +\n src/common/ieee802_11_defs.h | 28 ++++\n src/drivers/driver.h | 22 ++++\n src/drivers/driver_common.c | 6 +\n src/drivers/driver_nl80211.c | 14 ++\n src/drivers/driver_nl80211_capa.c | 19 +++\n tests/hwsim/example-hostapd.config | 2 +\n tests/hwsim/example-wpa_supplicant.config | 1 +\n tests/hwsim/test_uhr.py | 152 ++++++++++++++++++++++\n wpa_supplicant/Android.mk | 3 +\n wpa_supplicant/Makefile | 7 +\n wpa_supplicant/config.c | 1 +\n wpa_supplicant/config_file.c | 1 +\n wpa_supplicant/config_ssid.h | 8 ++\n wpa_supplicant/ctrl_iface.c | 8 +-\n wpa_supplicant/events.c | 13 ++\n wpa_supplicant/sme.c | 1 +\n wpa_supplicant/wpa_cli.c | 1 +\n wpa_supplicant/wpa_supplicant.c | 17 ++-\n wpa_supplicant/wpa_supplicant_i.h | 4 +\n 36 files changed, 663 insertions(+), 41 deletions(-)\n create mode 100644 src/ap/ieee802_11_uhr.c\n create mode 100644 tests/hwsim/test_uhr.py", "diff": "diff --git a/hostapd/Android.mk b/hostapd/Android.mk\nindex bff81cac4a31..492d54e50aed 100644\n--- a/hostapd/Android.mk\n+++ b/hostapd/Android.mk\n@@ -299,6 +299,12 @@ ifdef CONFIG_IEEE80211AC\n L_CFLAGS += -DCONFIG_IEEE80211AC\n endif\n \n+ifdef CONFIG_IEEE80211BN\n+CONFIG_IEEE80211BE=y\n+L_CFLAGS += -DCONFIG_IEEE80211BN\n+OBJS += src/ap/ieee802_11_uhr.c\n+endif\n+\n ifdef CONFIG_IEEE80211BE\n CONFIG_IEEE80211AX=y\n L_CFLAGS += -DCONFIG_IEEE80211BE\ndiff --git a/hostapd/Makefile b/hostapd/Makefile\nindex b2420e8474be..b12a40cbc058 100644\n--- a/hostapd/Makefile\n+++ b/hostapd/Makefile\n@@ -344,6 +344,12 @@ ifdef CONFIG_IEEE80211AC\n CFLAGS += -DCONFIG_IEEE80211AC\n endif\n \n+ifdef CONFIG_IEEE80211BN\n+CONFIG_IEEE80211BE=y\n+CFLAGS += -DCONFIG_IEEE80211BN\n+OBJS += ../src/ap/ieee802_11_uhr.o\n+endif\n+\n ifdef CONFIG_IEEE80211BE\n CONFIG_IEEE80211AX=y\n CFLAGS += -DCONFIG_IEEE80211BE\ndiff --git a/hostapd/config_file.c b/hostapd/config_file.c\nindex d34b4aa83950..3cb200ea358b 100644\n--- a/hostapd/config_file.c\n+++ b/hostapd/config_file.c\n@@ -4876,6 +4876,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,\n \t\tbss->disable_11ax = !!atoi(pos);\n \t} else if (os_strcmp(buf, \"disable_11be\") == 0) {\n \t\tbss->disable_11be = !!atoi(pos);\n+\t} else if (os_strcmp(buf, \"disable_11bn\") == 0) {\n+\t\tbss->disable_11bn = !!atoi(pos);\n #ifdef CONFIG_PASN\n #ifdef CONFIG_TESTING_OPTIONS\n \t} else if (os_strcmp(buf, \"force_kdk_derivation\") == 0) {\n@@ -4990,6 +4992,12 @@ static int hostapd_config_fill(struct hostapd_config *conf,\n \t\tconf->disable_mcs15_rx = atoi(pos);\n #endif /* CONFIG_TESTING_OPTIONS */\n #endif /* CONFIG_IEEE80211BE */\n+#ifdef CONFIG_IEEE80211BN\n+\t} else if (os_strcmp(buf, \"ieee80211bn\") == 0) {\n+\t\tconf->ieee80211bn = atoi(pos);\n+\t} else if (os_strcmp(buf, \"require_uhr\") == 0) {\n+\t\tconf->require_uhr = atoi(pos);\n+#endif /* CONFIG_IEEE80211BN */\n \t} else if (os_strcmp(buf, \"i2r_lmr_policy\") == 0) {\n \t\tconf->i2r_lmr_policy = atoi(pos);\n \t} else {\ndiff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf\nindex 20e09a9e329d..9eca437ec565 100644\n--- a/hostapd/hostapd.conf\n+++ b/hostapd/hostapd.conf\n@@ -1132,6 +1132,19 @@ wmm_ac_vo_acm=0\n # is disabled.\n #disable_mcs15_rx=1\n \n+##### IEEE 802.11bn related configuration #####################################\n+\n+#ieee80211bn: Whether IEEE 802.11bn (UHR) is enabled\n+# 0 = disabled (default)\n+# 1 = enabled\n+#ieee80211bn=1\n+\n+#disable_11bn: Boolean (0/1) to disable UHR for a specific BSS\n+#disable_11bn=0\n+\n+# Require stations to support UHR PHY (reject association if they do not)\n+#require_uhr=0\n+\n ##### IEEE 802.1X-2004 related configuration ##################################\n \n # Require IEEE 802.1X authorization\ndiff --git a/src/ap/ap_config.h b/src/ap/ap_config.h\nindex 3fe2206b9133..57ee0917bbef 100644\n--- a/src/ap/ap_config.h\n+++ b/src/ap/ap_config.h\n@@ -569,6 +569,7 @@ struct hostapd_bss_config {\n \tbool disable_11ac;\n \tbool disable_11ax;\n \tbool disable_11be;\n+\tbool disable_11bn;\n \n \t/* IEEE 802.11v */\n \tint time_advertisement;\n@@ -1245,6 +1246,11 @@ struct hostapd_config {\n \tbool require_eht;\n #endif /* CONFIG_IEEE80211BE */\n \n+\tint ieee80211bn;\n+#ifdef CONFIG_IEEE80211BN\n+\tbool require_uhr;\n+#endif\n+\n \t/* EHT enable/disable config from CHAN_SWITCH */\n #define CH_SWITCH_EHT_ENABLED BIT(0)\n #define CH_SWITCH_EHT_DISABLED BIT(1)\ndiff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c\nindex dc46b599cfb1..556f4b9d469a 100644\n--- a/src/ap/ap_drv_ops.c\n+++ b/src/ap/ap_drv_ops.c\n@@ -477,6 +477,8 @@ int hostapd_sta_add(struct hostapd_data *hapd,\n \t\t size_t he_capab_len,\n \t\t const struct ieee80211_eht_capabilities *eht_capab,\n \t\t size_t eht_capab_len,\n+\t\t const struct ieee80211_uhr_capabilities *uhr_capab,\n+\t\t size_t uhr_capab_len,\n \t\t const struct ieee80211_he_6ghz_band_cap *he_6ghz_capab,\n \t\t u32 flags, u8 qosinfo, u8 vht_opmode, int supp_p2p_ps,\n \t\t int set, const u8 *link_addr, bool mld_link_sta,\n@@ -502,6 +504,8 @@ int hostapd_sta_add(struct hostapd_data *hapd,\n \tparams.he_capab_len = he_capab_len;\n \tparams.eht_capab = eht_capab;\n \tparams.eht_capab_len = eht_capab_len;\n+\tparams.uhr_capab = uhr_capab;\n+\tparams.uhr_capab_len = uhr_capab_len;\n \tparams.he_6ghz_capab = he_6ghz_capab;\n \tparams.vht_opmode_enabled = !!(flags & WLAN_STA_VHT_OPMODE_ENABLED);\n \tparams.vht_opmode = vht_opmode;\ndiff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h\nindex 66913ed0fca7..f09b3ad9a306 100644\n--- a/src/ap/ap_drv_ops.h\n+++ b/src/ap/ap_drv_ops.h\n@@ -47,6 +47,8 @@ int hostapd_sta_add(struct hostapd_data *hapd,\n \t\t size_t he_capab_len,\n \t\t const struct ieee80211_eht_capabilities *eht_capab,\n \t\t size_t eht_capab_len,\n+\t\t const struct ieee80211_uhr_capabilities *uhr_capab,\n+\t\t size_t uhr_capab_len,\n \t\t const struct ieee80211_he_6ghz_band_cap *he_6ghz_capab,\n \t\t u32 flags, u8 qosinfo, u8 vht_opmode, int supp_p2p_ps,\n \t\t int set, const u8 *link_addr, bool mld_link_sta,\ndiff --git a/src/ap/beacon.c b/src/ap/beacon.c\nindex fba6a473396f..ecf19c7910e3 100644\n--- a/src/ap/beacon.c\n+++ b/src/ap/beacon.c\n@@ -809,6 +809,13 @@ static size_t hostapd_probe_resp_elems_len(struct hostapd_data *hapd,\n \t}\n #endif /* CONFIG_IEEE80211BE */\n \n+#ifdef CONFIG_IEEE80211BN\n+\tif (hostapd_is_uhr_enabled(hapd)) {\n+\t\tbuflen += hostapd_eid_uhr_capab_len(hapd, IEEE80211_MODE_AP);\n+\t\tbuflen += 3 + IEEE80211_UHR_OPER_MAX_SIZE;\n+\t}\n+#endif /* CONFIG_IEEE80211BN */\n+\n \tbuflen += hostapd_eid_mbssid_len(hapd_probed, WLAN_FC_STYPE_PROBE_RESP,\n \t\t\t\t\t NULL,\n \t\t\t\t\t params->known_bss,\n@@ -981,6 +988,13 @@ static u8 * hostapd_probe_resp_fill_elems(struct hostapd_data *hapd,\n \t}\n #endif /* CONFIG_IEEE80211BE */\n \n+#ifdef CONFIG_IEEE80211BN\n+\tif (hostapd_is_uhr_enabled(hapd)) {\n+\t\tpos = hostapd_eid_uhr_capab(hapd, pos, IEEE80211_MODE_AP);\n+\t\tpos = hostapd_eid_uhr_operation(hapd, pos, false);\n+\t}\n+#endif /* CONFIG_IEEE80211BN */\n+\n #ifdef CONFIG_IEEE80211AC\n \tif (hapd->conf->vendor_vht)\n \t\tpos = hostapd_eid_vendor_vht(hapd, pos);\n@@ -2299,6 +2313,11 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,\n \t}\n #endif /* CONFIG_IEEE80211BE */\n \n+#ifdef CONFIG_IEEE80211BN\n+\tif (hostapd_is_uhr_enabled(hapd))\n+\t\ttail_len += 3 + sizeof(struct ieee80211_uhr_operation);\n+#endif /* CONFIG_IEEE80211BN */\n+\n \tif (hapd->iconf->mbssid == ENHANCED_MBSSID_ENABLED &&\n \t hapd == hostapd_mbssid_get_tx_bss(hapd))\n \t\ttail_len += 5; /* Multiple BSSID Configuration element */\n@@ -2481,6 +2500,11 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,\n \t}\n #endif /* CONFIG_IEEE80211BE */\n \n+#ifdef CONFIG_IEEE80211BN\n+\tif (hostapd_is_uhr_enabled(hapd))\n+\t\ttailpos = hostapd_eid_uhr_operation(hapd, tailpos, true);\n+#endif /* CONFIG_IEEE80211BN */\n+\n #ifdef CONFIG_IEEE80211AC\n \tif (hapd->conf->vendor_vht)\n \t\ttailpos = hostapd_eid_vendor_vht(hapd, tailpos);\ndiff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c\nindex 90a0a49363e3..57ec4f6ec12d 100644\n--- a/src/ap/ctrl_iface_ap.c\n+++ b/src/ap/ctrl_iface_ap.c\n@@ -405,6 +405,20 @@ static int hostapd_ctrl_iface_sta_mib(struct hostapd_data *hapd,\n \t}\n #endif /* CONFIG_IEEE80211BE */\n \n+#ifdef CONFIG_IEEE80211BN\n+\tif ((sta->flags & WLAN_STA_UHR) && sta->uhr_capab) {\n+\t\tres = os_snprintf(buf + len, buflen - len, \"uhr_capab=\");\n+\t\tif (!os_snprintf_error(buflen - len, res))\n+\t\t\tlen += res;\n+\t\tlen += wpa_snprintf_hex(buf + len, buflen - len,\n+\t\t\t\t\t(const u8 *) sta->uhr_capab,\n+\t\t\t\t\tsta->uhr_capab_len);\n+\t\tres = os_snprintf(buf + len, buflen - len, \"\\n\");\n+\t\tif (!os_snprintf_error(buflen - len, res))\n+\t\t\tlen += res;\n+\t}\n+#endif /* CONFIG_IEEE80211BN */\n+\n #ifdef CONFIG_IEEE80211AC\n \tif ((sta->flags & WLAN_STA_VHT) && sta->vht_capabilities) {\n \t\tres = os_snprintf(buf + len, buflen - len,\n@@ -885,6 +899,7 @@ int hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf,\n \t\t\t \"ieee80211ac=%d\\n\"\n \t\t\t \"ieee80211ax=%d\\n\"\n \t\t\t \"ieee80211be=%d\\n\"\n+\t\t\t \"ieee80211bn=%d\\n\"\n \t\t\t \"beacon_int=%u\\n\"\n \t\t\t \"dtim_period=%d\\n\",\n \t\t\t iface->conf->channel,\n@@ -896,6 +911,7 @@ int hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf,\n \t\t\t hostapd_is_vht_enabled(hapd),\n \t\t\t hostapd_is_he_enabled(hapd),\n \t\t\t hostapd_is_eht_enabled(hapd),\n+\t\t\t hostapd_is_uhr_enabled(hapd),\n \t\t\t iface->conf->beacon_int,\n \t\t\t hapd->conf->dtim_period);\n \tif (os_snprintf_error(buflen - len, ret))\ndiff --git a/src/ap/hostapd.h b/src/ap/hostapd.h\nindex fb06a5afd935..974964d341e9 100644\n--- a/src/ap/hostapd.h\n+++ b/src/ap/hostapd.h\n@@ -965,4 +965,10 @@ hostapd_is_eht_enabled(struct hostapd_data *hapd)\n \treturn hapd->iconf->ieee80211be && !hapd->conf->disable_11be;\n }\n \n+static inline bool\n+hostapd_is_uhr_enabled(struct hostapd_data *hapd)\n+{\n+\treturn hapd->iconf->ieee80211bn && !hapd->conf->disable_11bn;\n+}\n+\n #endif /* HOSTAPD_H */\ndiff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c\nindex 3abb437b002e..8a3d3208debd 100644\n--- a/src/ap/ieee802_11.c\n+++ b/src/ap/ieee802_11.c\n@@ -155,6 +155,11 @@ static size_t hostapd_supp_rates(struct hostapd_data *hapd, u8 *buf)\n \t\t*pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_EHT_PHY;\n #endif /* CONFIG_IEEE80211BE */\n \n+#ifdef CONFIG_IEEE80211BN\n+\tif (hapd->iconf->ieee80211bn && hapd->iconf->require_uhr)\n+\t\t*pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_UHR_PHY;\n+#endif /* CONFIG_IEEE80211BN */\n+\n #ifdef CONFIG_SAE\n \tif ((hapd->conf->sae_pwe == SAE_PWE_HASH_TO_ELEMENT ||\n \t hostapd_sae_pw_id_in_use(hapd->conf) == 2) &&\n@@ -5542,6 +5547,23 @@ static int __check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,\n \t\t}\n \t}\n #endif /* CONFIG_IEEE80211BE */\n+#ifdef CONFIG_IEEE80211BN\n+\tif (hostapd_is_uhr_enabled(hapd)) {\n+\t\tresp = copy_sta_uhr_capab(hapd, sta, IEEE80211_MODE_AP,\n+\t\t\t\t\t elems->uhr_capabilities,\n+\t\t\t\t\t elems->uhr_capabilities_len);\n+\t\tif (resp != WLAN_STATUS_SUCCESS)\n+\t\t\treturn resp;\n+\n+\t\tif (hapd->iconf->require_uhr && !(sta->flags & WLAN_STA_UHR)) {\n+\t\t\thostapd_logger(hapd, sta->addr,\n+\t\t\t\t HOSTAPD_MODULE_IEEE80211,\n+\t\t\t\t HOSTAPD_LEVEL_INFO,\n+\t\t\t\t \"Station does not support mandatory UHR PHY - reject association\");\n+\t\t\treturn WLAN_STATUS_DENIED_UHR_NOT_SUPPORTED;\n+\t\t}\n+\t}\n+#endif /* CONFIG_IEEE80211BN */\n \n #ifdef CONFIG_P2P\n \tif (elems->p2p && ies && ies_len) {\n@@ -6200,6 +6222,13 @@ void ieee80211_ml_build_assoc_resp(struct hostapd_data *hapd,\n \t\t}\n \t}\n \n+#ifdef CONFIG_IEEE80211BN\n+\tif (hostapd_is_uhr_enabled(hapd)) {\n+\t\tp = hostapd_eid_uhr_capab(hapd, p, IEEE80211_MODE_AP);\n+\t\tp = hostapd_eid_uhr_operation(hapd, p, false);\n+\t}\n+#endif /* CONFIG_IEEE80211BN */\n+\n \tp = hostapd_eid_ext_capab(hapd, p, false);\n \tp = hostapd_eid_mbo(hapd, p, buf + buflen - p);\n \tp = hostapd_eid_wmm(hapd, p);\n@@ -6471,6 +6500,7 @@ static int add_associated_sta(struct hostapd_data *hapd,\n \tstruct ieee80211_vht_capabilities vht_cap;\n \tstruct ieee80211_he_capabilities he_cap;\n \tstruct ieee80211_eht_capabilities eht_cap;\n+\tstruct ieee80211_uhr_capabilities uhr_cap;\n \tint set = 1;\n \tconst u8 *mld_link_addr = NULL;\n \tbool mld_link_sta = false, epp_sta = false;\n@@ -6552,6 +6582,11 @@ static int add_associated_sta(struct hostapd_data *hapd,\n \t\thostapd_get_eht_capab(hapd, sta->eht_capab, &eht_cap,\n \t\t\t\t sta->eht_capab_len);\n #endif /* CONFIG_IEEE80211BE */\n+#ifdef CONFIG_IEEE80211BN\n+\tif (sta->flags & WLAN_STA_UHR)\n+\t\thostapd_get_uhr_capab(hapd, sta->uhr_capab, &uhr_cap,\n+\t\t\t\t sta->uhr_capab_len);\n+#endif /* CONFIG_IEEE80211BN */\n \n \t/*\n \t * Add the station with forced WLAN_STA_ASSOC flag. The sta->flags\n@@ -6567,6 +6602,8 @@ static int add_associated_sta(struct hostapd_data *hapd,\n \t\t\t sta->flags & WLAN_STA_HE ? sta->he_capab_len : 0,\n \t\t\t sta->flags & WLAN_STA_EHT ? &eht_cap : NULL,\n \t\t\t sta->flags & WLAN_STA_EHT ? sta->eht_capab_len : 0,\n+\t\t\t sta->flags & WLAN_STA_UHR ? &uhr_cap : NULL,\n+\t\t\t sta->flags & WLAN_STA_UHR ? sta->uhr_capab_len : 0,\n \t\t\t sta->he_6ghz_capab,\n \t\t\t sta->flags | WLAN_STA_ASSOC, sta->qosinfo,\n \t\t\t sta->vht_opmode, sta->p2p_ie ? 1 : 0,\n@@ -6628,6 +6665,12 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,\n \t\t\tbuflen += hostapd_eid_eht_ml_tid_to_link_map_len(hapd);\n \t}\n #endif /* CONFIG_IEEE80211BE */\n+#ifdef CONFIG_IEEE80211BN\n+\tif (hostapd_is_uhr_enabled(hapd)) {\n+\t\tbuflen += hostapd_eid_uhr_capab_len(hapd, IEEE80211_MODE_AP);\n+\t\tbuflen += 3 + IEEE80211_UHR_OPER_MAX_SIZE;\n+\t}\n+#endif /* CONFIG_IEEE80211BN */\n \n \tbuf = os_zalloc(buflen);\n \tif (!buf) {\n@@ -6790,6 +6833,13 @@ rsnxe_done:\n \t}\n #endif /* CONFIG_IEEE80211BE */\n \n+#ifdef CONFIG_IEEE80211BN\n+\tif (hostapd_is_uhr_enabled(hapd)) {\n+\t\tp = hostapd_eid_uhr_capab(hapd, p, IEEE80211_MODE_AP);\n+\t\tp = hostapd_eid_uhr_operation(hapd, p, false);\n+\t}\n+#endif /* CONFIG_IEEE80211BN */\n+\n #ifdef CONFIG_OWE\n \tif (((hapd->conf->wpa_key_mgmt | hapd->conf->rsn_override_key_mgmt |\n \t hapd->conf->rsn_override_key_mgmt_2) & WPA_KEY_MGMT_OWE) &&\n@@ -7339,7 +7389,7 @@ static void handle_assoc(struct hostapd_data *hapd,\n \t\t\thostapd_logger(hapd, mgmt->sa,\n \t\t\t\t HOSTAPD_MODULE_IEEE80211,\n \t\t\t\t HOSTAPD_LEVEL_INFO,\n-\t\t\t\t \"Station tried to associate before authentication (aid=%d flags=0x%x)\",\n+\t\t\t\t \"Station tried to associate before authentication (aid=%d flags=0x%llx)\",\n \t\t\t\t sta ? sta->aid : -1,\n \t\t\t\t sta ? sta->flags : 0);\n \t\t\tsend_deauth(hapd, mgmt->sa,\ndiff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h\nindex 664d585b994c..32db78f471ff 100644\n--- a/src/ap/ieee802_11.h\n+++ b/src/ap/ieee802_11.h\n@@ -334,4 +334,17 @@ void ieee80211_send_eap_req(struct hostapd_data *hapd, struct sta_info *sta,\n \t\t\t struct rsn_pmksa_cache_entry *cached_pmk,\n \t\t\t const u8 *eap_req, size_t eap_req_len);\n \n+size_t hostapd_eid_uhr_capab_len(struct hostapd_data *hapd,\n+\t\t\t\t enum ieee80211_op_mode opmode);\n+u8 * hostapd_eid_uhr_capab(struct hostapd_data *hapd, u8 *eid,\n+\t\t\t enum ieee80211_op_mode opmode);\n+u8 * hostapd_eid_uhr_operation(struct hostapd_data *hapd, u8 *eid, bool beacon);\n+u16 copy_sta_uhr_capab(struct hostapd_data *hapd, struct sta_info *sta,\n+\t\t enum ieee80211_op_mode opmode,\n+\t\t const u8 *uhr_capab, size_t uhr_capab_len);\n+void hostapd_get_uhr_capab(struct hostapd_data *hapd,\n+\t\t\t const struct ieee80211_uhr_capabilities *src,\n+\t\t\t struct ieee80211_uhr_capabilities *dest,\n+\t\t\t size_t len);\n+\n #endif /* IEEE802_11_H */\ndiff --git a/src/ap/ieee802_11_uhr.c b/src/ap/ieee802_11_uhr.c\nnew file mode 100644\nindex 000000000000..6538e0e0b9ea\n--- /dev/null\n+++ b/src/ap/ieee802_11_uhr.c\n@@ -0,0 +1,145 @@\n+/*\n+ * hostapd / IEEE 802.11bn UHR\n+ * Copyright (C) 2025 Intel Corporation\n+ *\n+ * This software may be distributed under the terms of the BSD license.\n+ * See README for more details.\n+ */\n+\n+#include \"utils/includes.h\"\n+#include \"utils/common.h\"\n+#include \"common/ocv.h\"\n+#include \"common/wpa_ctrl.h\"\n+#include \"crypto/crypto.h\"\n+#include \"crypto/dh_groups.h\"\n+#include \"hostapd.h\"\n+#include \"sta_info.h\"\n+#include \"ap_drv_ops.h\"\n+#include \"wpa_auth.h\"\n+#include \"ieee802_11.h\"\n+\n+\n+size_t hostapd_eid_uhr_capab_len(struct hostapd_data *hapd,\n+\t\t\t\t enum ieee80211_op_mode opmode)\n+{\n+\tstruct hostapd_hw_modes *mode;\n+\tstruct uhr_capabilities *uhr_cap;\n+\n+\tmode = hapd->iface->current_mode;\n+\tif (!mode)\n+\t\treturn 0;\n+\n+\tuhr_cap = &mode->uhr_capab[opmode];\n+\tif (!uhr_cap->uhr_supported)\n+\t\treturn 0;\n+\n+\treturn 3 /* ext elem header */ + 6 /* MAC + PHY */;\n+}\n+\n+\n+u8 * hostapd_eid_uhr_capab(struct hostapd_data *hapd, u8 *eid,\n+\t\t\t enum ieee80211_op_mode opmode)\n+{\n+\tstruct hostapd_hw_modes *mode;\n+\tstruct uhr_capabilities *uhr_cap;\n+\tstruct ieee80211_uhr_capabilities *cap;\n+\tu8 *pos = eid, *length_pos;\n+\n+\tmode = hapd->iface->current_mode;\n+\tif (!mode)\n+\t\treturn eid;\n+\n+\tuhr_cap = &mode->uhr_capab[opmode];\n+\tif (!uhr_cap->uhr_supported)\n+\t\treturn eid;\n+\n+\t*pos++ = WLAN_EID_EXTENSION;\n+\tlength_pos = pos++;\n+\t*pos++ = WLAN_EID_EXT_UHR_CAPABILITIES;\n+\n+\tcap = (struct ieee80211_uhr_capabilities *) pos;\n+\tos_memcpy(cap->mac, uhr_cap->mac, sizeof(cap->mac));\n+\tos_memcpy(cap->phy, uhr_cap->phy, sizeof(cap->phy));\n+\tpos += sizeof(*cap);\n+\n+\t*length_pos = pos - (eid + 2);\n+\treturn pos;\n+}\n+\n+\n+u8 * hostapd_eid_uhr_operation(struct hostapd_data *hapd, u8 *eid, bool beacon)\n+{\n+\tstruct ieee80211_uhr_operation *oper;\n+\tu8 *pos = eid;\n+\n+\tif (!hapd->iface->current_mode)\n+\t\treturn eid;\n+\n+\t*pos++ = WLAN_EID_EXTENSION;\n+\t*pos++ = 1 + sizeof(*oper);\n+\t*pos++ = WLAN_EID_EXT_UHR_OPERATION;\n+\n+\toper = (void *) pos;\n+\toper->oper_params = 0;\n+\n+\t/* TODO: Fill in appropriate UHR-MCS max Nss information */\n+\toper->basic_uhr_mcs_nss_set[0] = 0x11;\n+\toper->basic_uhr_mcs_nss_set[1] = 0x00;\n+\toper->basic_uhr_mcs_nss_set[2] = 0x00;\n+\toper->basic_uhr_mcs_nss_set[3] = 0x00;\n+\n+\treturn pos + sizeof(*oper);\n+}\n+\n+\n+static bool ieee80211_invalid_uhr_cap_size(enum hostapd_hw_mode mode,\n+\t\t\t\t\t const u8 *uhr_cap, size_t len)\n+{\n+\treturn len < sizeof(struct ieee80211_uhr_capabilities);\n+}\n+\n+\n+u16 copy_sta_uhr_capab(struct hostapd_data *hapd, struct sta_info *sta,\n+\t\t enum ieee80211_op_mode opmode,\n+\t\t const u8 *uhr_capab, size_t uhr_capab_len)\n+{\n+\tstruct hostapd_hw_modes *c_mode = hapd->iface->current_mode;\n+\tenum hostapd_hw_mode mode = c_mode ? c_mode->mode : NUM_HOSTAPD_MODES;\n+\n+\tif (!hostapd_is_uhr_enabled(hapd) || !uhr_capab ||\n+\t ieee80211_invalid_uhr_cap_size(mode, uhr_capab, uhr_capab_len)) {\n+\t\tsta->flags &= ~WLAN_STA_UHR;\n+\t\tos_free(sta->uhr_capab);\n+\t\tsta->uhr_capab = NULL;\n+\t\treturn WLAN_STATUS_SUCCESS;\n+\t}\n+\n+\tos_free(sta->uhr_capab);\n+\tsta->uhr_capab = os_memdup(uhr_capab, uhr_capab_len);\n+\tif (!sta->uhr_capab) {\n+\t\tsta->uhr_capab_len = 0;\n+\t\treturn WLAN_STATUS_UNSPECIFIED_FAILURE;\n+\t}\n+\n+\tsta->flags |= WLAN_STA_UHR;\n+\tsta->uhr_capab_len = uhr_capab_len;\n+\n+\treturn WLAN_STATUS_SUCCESS;\n+}\n+\n+\n+void hostapd_get_uhr_capab(struct hostapd_data *hapd,\n+\t\t\t const struct ieee80211_uhr_capabilities *src,\n+\t\t\t struct ieee80211_uhr_capabilities *dest,\n+\t\t\t size_t len)\n+{\n+\tif (!src || !dest)\n+\t\treturn;\n+\n+\tif (len > sizeof(*dest))\n+\t\tlen = sizeof(*dest);\n+\t/* TODO: mask out unsupported features */\n+\n+\tos_memset(dest, 0, sizeof(*dest));\n+\tos_memcpy(dest, src, len);\n+}\ndiff --git a/src/ap/sta_info.c b/src/ap/sta_info.c\nindex 2bb7e1235cb0..98f968eb1c9a 100644\n--- a/src/ap/sta_info.c\n+++ b/src/ap/sta_info.c\n@@ -474,6 +474,7 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)\n \tos_free(sta->he_capab);\n \tos_free(sta->he_6ghz_capab);\n \tos_free(sta->eht_capab);\n+\tos_free(sta->uhr_capab);\n \thostapd_free_psk_list(sta->psk);\n \tos_free(sta->identity);\n \tos_free(sta->radius_cui);\n@@ -602,7 +603,7 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)\n \tint reason;\n \tint max_inactivity = hapd->conf->ap_max_inactivity;\n \n-\twpa_printf(MSG_DEBUG, \"%s: %s: \" MACSTR \" flags=0x%x timeout_next=%d\",\n+\twpa_printf(MSG_DEBUG, \"%s: %s: \" MACSTR \" flags=0x%llx timeout_next=%d\",\n \t\t hapd->conf->iface, __func__, MAC2STR(sta->addr), sta->flags,\n \t\t sta->timeout_next);\n \tif (sta->timeout_next == STA_REMOVE) {\n@@ -1964,13 +1965,13 @@ void ap_sta_clear_assoc_timeout(struct hostapd_data *hapd,\n }\n \n \n-int ap_sta_flags_txt(u32 flags, char *buf, size_t buflen)\n+int ap_sta_flags_txt(unsigned long long flags, char *buf, size_t buflen)\n {\n \tint res;\n \n \tbuf[0] = '\\0';\n \tres = os_snprintf(buf, buflen,\n-\t\t\t \"%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\",\n+\t\t\t \"%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\",\n \t\t\t (flags & WLAN_STA_AUTH ? \"[AUTH]\" : \"\"),\n \t\t\t (flags & WLAN_STA_ASSOC ? \"[ASSOC]\" : \"\"),\n \t\t\t (flags & WLAN_STA_AUTHORIZED ? \"[AUTHORIZED]\" : \"\"),\n@@ -1991,6 +1992,7 @@ int ap_sta_flags_txt(u32 flags, char *buf, size_t buflen)\n \t\t\t (flags & WLAN_STA_VHT ? \"[VHT]\" : \"\"),\n \t\t\t (flags & WLAN_STA_HE ? \"[HE]\" : \"\"),\n \t\t\t (flags & WLAN_STA_EHT ? \"[EHT]\" : \"\"),\n+\t\t\t (flags & WLAN_STA_UHR ? \"[UHR]\" : \"\"),\n \t\t\t (flags & WLAN_STA_6GHZ ? \"[6GHZ]\" : \"\"),\n \t\t\t (flags & WLAN_STA_VENDOR_VHT ? \"[VENDOR_VHT]\" : \"\"),\n \t\t\t (flags & WLAN_STA_SPP_AMSDU ? \"[SPP-A-MSDU]\" : \"\"),\n@@ -2115,7 +2117,7 @@ int ap_sta_re_add(struct hostapd_data *hapd, struct sta_info *sta)\n \tif (hostapd_sta_add(hapd, sta->addr, 0, 0,\n \t\t\t sta->supported_rates,\n \t\t\t sta->supported_rates_len,\n-\t\t\t 0, NULL, NULL, NULL, 0, NULL, 0, NULL,\n+\t\t\t 0, NULL, NULL, NULL, 0, NULL, 0, NULL, 0, NULL,\n \t\t\t sta->flags, 0, 0, 0, 0,\n \t\t\t mld_link_addr, mld_link_sta, eml_cap, epp_sta)) {\n \t\thostapd_logger(hapd, sta->addr,\ndiff --git a/src/ap/sta_info.h b/src/ap/sta_info.h\nindex 9810eb22f9a4..38967b2f79b3 100644\n--- a/src/ap/sta_info.h\n+++ b/src/ap/sta_info.h\n@@ -20,35 +20,36 @@\n #include \"hostapd.h\"\n \n /* STA flags */\n-#define WLAN_STA_AUTH BIT(0)\n-#define WLAN_STA_ASSOC BIT(1)\n-#define WLAN_STA_SPP_AMSDU BIT(2)\n-#define WLAN_STA_AUTHORIZED BIT(5)\n-#define WLAN_STA_PENDING_POLL BIT(6) /* pending activity poll not ACKed */\n-#define WLAN_STA_SHORT_PREAMBLE BIT(7)\n-#define WLAN_STA_PREAUTH BIT(8)\n-#define WLAN_STA_WMM BIT(9)\n-#define WLAN_STA_MFP BIT(10)\n-#define WLAN_STA_HT BIT(11)\n-#define WLAN_STA_WPS BIT(12)\n-#define WLAN_STA_MAYBE_WPS BIT(13)\n-#define WLAN_STA_WDS BIT(14)\n-#define WLAN_STA_ASSOC_REQ_OK BIT(15)\n-#define WLAN_STA_WPS2 BIT(16)\n-#define WLAN_STA_GAS BIT(17)\n-#define WLAN_STA_VHT BIT(18)\n-#define WLAN_STA_WNM_SLEEP_MODE BIT(19)\n-#define WLAN_STA_VHT_OPMODE_ENABLED BIT(20)\n-#define WLAN_STA_VENDOR_VHT BIT(21)\n-#define WLAN_STA_PENDING_FILS_ERP BIT(22)\n-#define WLAN_STA_MULTI_AP BIT(23)\n-#define WLAN_STA_HE BIT(24)\n-#define WLAN_STA_6GHZ BIT(25)\n-#define WLAN_STA_PENDING_PASN_FILS_ERP BIT(26)\n-#define WLAN_STA_EHT BIT(27)\n-#define WLAN_STA_PENDING_DISASSOC_CB BIT(29)\n-#define WLAN_STA_PENDING_DEAUTH_CB BIT(30)\n-#define WLAN_STA_NONERP BIT(31)\n+#define WLAN_STA_AUTH BIT_ULL(0)\n+#define WLAN_STA_ASSOC BIT_ULL(1)\n+#define WLAN_STA_SPP_AMSDU BIT_ULL(2)\n+#define WLAN_STA_AUTHORIZED BIT_ULL(5)\n+#define WLAN_STA_PENDING_POLL BIT_ULL(6) /* pending activity poll not ACKed */\n+#define WLAN_STA_SHORT_PREAMBLE BIT_ULL(7)\n+#define WLAN_STA_PREAUTH BIT_ULL(8)\n+#define WLAN_STA_WMM BIT_ULL(9)\n+#define WLAN_STA_MFP BIT_ULL(10)\n+#define WLAN_STA_HT BIT_ULL(11)\n+#define WLAN_STA_WPS BIT_ULL(12)\n+#define WLAN_STA_MAYBE_WPS BIT_ULL(13)\n+#define WLAN_STA_WDS BIT_ULL(14)\n+#define WLAN_STA_ASSOC_REQ_OK BIT_ULL(15)\n+#define WLAN_STA_WPS2 BIT_ULL(16)\n+#define WLAN_STA_GAS BIT_ULL(17)\n+#define WLAN_STA_VHT BIT_ULL(18)\n+#define WLAN_STA_WNM_SLEEP_MODE BIT_ULL(19)\n+#define WLAN_STA_VHT_OPMODE_ENABLED BIT_ULL(20)\n+#define WLAN_STA_VENDOR_VHT BIT_ULL(21)\n+#define WLAN_STA_PENDING_FILS_ERP BIT_ULL(22)\n+#define WLAN_STA_MULTI_AP BIT_ULL(23)\n+#define WLAN_STA_HE BIT_ULL(24)\n+#define WLAN_STA_6GHZ BIT_ULL(25)\n+#define WLAN_STA_PENDING_PASN_FILS_ERP BIT_ULL(26)\n+#define WLAN_STA_EHT BIT_ULL(27)\n+#define WLAN_STA_PENDING_DISASSOC_CB BIT_ULL(29)\n+#define WLAN_STA_PENDING_DEAUTH_CB BIT_ULL(30)\n+#define WLAN_STA_NONERP BIT_ULL(31)\n+#define WLAN_STA_UHR BIT_ULL(32)\n \n /* Maximum number of supported rates (from both Supported Rates and Extended\n * Supported Rates IEs). */\n@@ -112,7 +113,7 @@ struct sta_info {\n \tstruct dl_list ip6addr; /* list head for struct ip6addr */\n \tu16 aid; /* STA's unique AID (1 .. 2007) or 0 if not yet assigned */\n \tu16 disconnect_reason_code; /* RADIUS server override */\n-\tu32 flags; /* Bitfield of WLAN_STA_* */\n+\tunsigned long long flags; /* Bitfield of WLAN_STA_* */\n \tu16 capability;\n \tu16 listen_interval; /* or beacon_int for APs */\n \tu8 supported_rates[WLAN_SUPP_RATES_MAX];\n@@ -226,6 +227,8 @@ struct sta_info {\n \tstruct ieee80211_he_6ghz_band_cap *he_6ghz_capab;\n \tstruct ieee80211_eht_capabilities *eht_capab;\n \tsize_t eht_capab_len;\n+\tstruct ieee80211_uhr_capabilities *uhr_capab;\n+\tsize_t uhr_capab_len;\n \n \tint sa_query_count; /* number of pending SA Query requests;\n \t\t\t * 0 = no SA Query in progress */\n@@ -441,7 +444,7 @@ void ap_sta_clear_disconnect_timeouts(struct hostapd_data *hapd,\n void ap_sta_clear_assoc_timeout(struct hostapd_data *hapd,\n \t\t\t\tstruct sta_info *sta);\n \n-int ap_sta_flags_txt(u32 flags, char *buf, size_t buflen);\n+int ap_sta_flags_txt(unsigned long long flags, char *buf, size_t buflen);\n void ap_sta_delayed_1x_auth_fail_disconnect(struct hostapd_data *hapd,\n \t\t\t\t\t struct sta_info *sta,\n \t\t\t\t\t unsigned timeout);\ndiff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c\nindex 0dd302e11a5b..c52241f14fd5 100644\n--- a/src/common/ieee802_11_common.c\n+++ b/src/common/ieee802_11_common.c\n@@ -452,6 +452,14 @@ static int ieee802_11_parse_extension(const u8 *pos, size_t elen,\n \t\telems->supported_groups = pos;\n \t\telems->supported_groups_len = elen;\n \t\tbreak;\n+\tcase WLAN_EID_EXT_UHR_CAPABILITIES:\n+\t\telems->uhr_capabilities = pos;\n+\t\telems->uhr_capabilities_len = elen;\n+\t\tbreak;\n+\tcase WLAN_EID_EXT_UHR_OPERATION:\n+\t\telems->uhr_operation = pos;\n+\t\telems->uhr_operation_len = elen;\n+\t\tbreak;\n \tdefault:\n \t\tif (show_errors) {\n \t\t\twpa_printf(MSG_MSGDUMP,\n@@ -1026,6 +1034,14 @@ void ieee802_11_elems_clear_ext_ids(struct ieee802_11_elems *elems,\n \t\t\telems->eht_operation = NULL;\n \t\t\telems->eht_operation_len = 0;\n \t\t\tbreak;\n+\t\tcase WLAN_EID_EXT_UHR_CAPABILITIES:\n+\t\t\telems->uhr_capabilities = NULL;\n+\t\t\telems->uhr_capabilities_len = 0;\n+\t\t\tbreak;\n+\t\tcase WLAN_EID_EXT_UHR_OPERATION:\n+\t\t\telems->uhr_operation = NULL;\n+\t\t\telems->uhr_operation_len = 0;\n+\t\t\tbreak;\n \t\t}\n \t}\n }\ndiff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h\nindex 5d9c840cee76..2751c668c9f4 100644\n--- a/src/common/ieee802_11_common.h\n+++ b/src/common/ieee802_11_common.h\n@@ -131,6 +131,8 @@ struct ieee802_11_elems {\n \tconst u8 *akm_suite_selector;\n \tconst u8 *supported_groups;\n \tconst u8 *nan_ie;\n+\tconst u8 *uhr_capabilities;\n+\tconst u8 *uhr_operation;\n \n \tu8 ssid_len;\n \tu8 supp_rates_len;\n@@ -205,6 +207,8 @@ struct ieee802_11_elems {\n \tu8 akm_suite_selector_len;\n \tu8 supported_groups_len;\n \tsize_t nan_len;\n+\tu8 uhr_capabilities_len;\n+\tu8 uhr_operation_len;\n \n \tstruct mb_ies_info mb_ies;\n \ndiff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h\nindex febaab8f1be3..756c36d2b439 100644\n--- a/src/common/ieee802_11_defs.h\n+++ b/src/common/ieee802_11_defs.h\n@@ -246,6 +246,7 @@\n #define WLAN_STATUS_DENIED_OPERATION_PARAMETER_UPDATE 141\n #define WLAN_STATUS_802_1_X_AUTH_FAILED 152\n #define WLAN_STATUS_802_1_X_AUTH_SUCCESS 153\n+#define WLAN_STATUS_DENIED_UHR_NOT_SUPPORTED 157\n \n /* Reason codes (IEEE Std 802.11-2020, 9.4.1.7, Table 9-90) */\n #define WLAN_REASON_UNSPECIFIED 1\n@@ -541,6 +542,8 @@\n #define WLAN_EID_EXT_BANDWIDTH_INDICATION 135\n #define WLAN_EID_EXT_KNOWN_STA_IDENTIFICATION 136\n #define WLAN_EID_EXT_PASN_ENCRYPTED_DATA 140\n+#define WLAN_EID_EXT_UHR_OPERATION 151\n+#define WLAN_EID_EXT_UHR_CAPABILITIES 152\n #define WLAN_EID_EXT_SUPPORTED_GROUPS 161\n \n /* Extended Capabilities field */\n@@ -1413,6 +1416,7 @@ struct ieee80211_ampe_ie {\n #define HT_OPER_PARAM_PCO_PHASE\t\t\t\t((u16) BIT(11))\n /* B36..B39 - Reserved */\n \n+#define BSS_MEMBERSHIP_SELECTOR_UHR_PHY 120\n #define BSS_MEMBERSHIP_SELECTOR_EHT_PHY 121\n #define BSS_MEMBERSHIP_SELECTOR_HE_PHY 122\n #define BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY 123\n@@ -3294,6 +3298,30 @@ struct ieee80211_s1g_beacon_compat {\n \tle32 tsf_completion;\n } STRUCT_PACKED;\n \n+/* UHR Capabilities element format */\n+struct ieee80211_uhr_capabilities {\n+\t/* UHR MAC Capabilities Information */\n+\tu8 mac[5];\n+\t/* UHR PHY Capabilities Information */\n+\tu8 phy[1];\n+} STRUCT_PACKED;\n+\n+#define UHR_OPER_PARAMS_DPS_ENA 0x0001\n+#define UHR_OPER_PARAMS_NPCA_ENA 0x0002\n+#define UHR_OPER_PARAMS_PEDCA_ENA 0x0004\n+#define UHR_OPER_PARAMS_DBE_ENA 0x0008\n+\n+/* UHR Operation element format */\n+struct ieee80211_uhr_operation {\n+\tle16 oper_params; /* UHR Operation Parameters: UHR_OPER_* bits */\n+\tu8 basic_uhr_mcs_nss_set[4];\n+\t/* FIXME: DPS, NPCA, P-EDCA, DBE */\n+} STRUCT_PACKED;\n+\n+/* Max size in Draft P802.11bn D1.3 with DPS, NPCA, P-EDCA, DBE */\n+#define IEEE80211_UHR_OPER_MAX_SIZE\t\\\n+\t(sizeof(struct ieee80211_uhr_operation) + 4 + 6 + 3 + 3)\n+\n #ifdef _MSC_VER\n #pragma pack(pop)\n #endif /* _MSC_VER */\ndiff --git a/src/drivers/driver.h b/src/drivers/driver.h\nindex 3807fc0f8b38..2f50265657a7 100644\n--- a/src/drivers/driver.h\n+++ b/src/drivers/driver.h\n@@ -216,6 +216,13 @@ struct eht_capabilities {\n \tu8 ppet[EHT_PPE_THRESH_CAPAB_LEN];\n };\n \n+/* struct uhr_capabilities - IEEE 802.11bn UHR capabilities */\n+struct uhr_capabilities {\n+\tbool uhr_supported;\n+\tu8 mac[5];\n+\tu8 phy[1];\n+};\n+\n #define HOSTAPD_MODE_FLAG_HT_INFO_KNOWN BIT(0)\n #define HOSTAPD_MODE_FLAG_VHT_INFO_KNOWN BIT(1)\n #define HOSTAPD_MODE_FLAG_HE_INFO_KNOWN BIT(2)\n@@ -326,6 +333,11 @@ struct hostapd_hw_modes {\n \t * eht_capab - EHT (IEEE 802.11be) capabilities\n \t */\n \tstruct eht_capabilities eht_capab[IEEE80211_MODE_NUM];\n+\n+\t/**\n+\t * uhr_capab - UHR (IEEE 802.11bn) capabilities\n+\t */\n+\tstruct uhr_capabilities uhr_capab[IEEE80211_MODE_NUM];\n };\n \n \n@@ -1403,6 +1415,11 @@ struct wpa_driver_associate_params {\n \t */\n \tint disable_eht;\n \n+\t/**\n+\t * disable_uhr - Disable UHR for this connection\n+\t */\n+\tint disable_uhr;\n+\n \t/*\n \t * mld_params - MLD association parameters\n \t */\n@@ -2782,6 +2799,9 @@ struct hostapd_sta_add_params {\n \tconst u8 *mld_link_addr;\n \tu16 eml_cap;\n \n+\tconst struct ieee80211_uhr_capabilities *uhr_capab;\n+\tsize_t uhr_capab_len;\n+\n #ifdef CONFIG_NAN\n \t/*\n \t * For a station added to a NAN Data Interface (NDI) indicate the\n@@ -7620,6 +7640,8 @@ bool he_supported(const struct hostapd_hw_modes *hw_mode,\n \t\t enum ieee80211_op_mode op_mode);\n bool eht_supported(const struct hostapd_hw_modes *hw_mode,\n \t\t enum ieee80211_op_mode op_mode);\n+bool uhr_supported(const struct hostapd_hw_modes *hw_mode,\n+\t\t enum ieee80211_op_mode op_mode);\n \n struct wowlan_triggers *\n wpa_get_wowlan_triggers(const char *wowlan_triggers,\ndiff --git a/src/drivers/driver_common.c b/src/drivers/driver_common.c\nindex 50a0b682d9c7..223085ac4b2c 100644\n--- a/src/drivers/driver_common.c\n+++ b/src/drivers/driver_common.c\n@@ -221,6 +221,12 @@ bool eht_supported(const struct hostapd_hw_modes *hw_mode,\n \treturn hw_mode->eht_capab[op_mode].eht_supported;\n }\n \n+bool uhr_supported(const struct hostapd_hw_modes *hw_mode,\n+\t\t enum ieee80211_op_mode op_mode)\n+{\n+\treturn hw_mode->uhr_capab[op_mode].uhr_supported;\n+}\n+\n \n static int wpa_check_wowlan_trigger(const char *start, const char *trigger,\n \t\t\t\t int capa_trigger, u8 *param_trigger)\ndiff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c\nindex d2d0a5cf0353..167f12069718 100644\n--- a/src/drivers/driver_nl80211.c\n+++ b/src/drivers/driver_nl80211.c\n@@ -6227,6 +6227,14 @@ static int wpa_driver_nl80211_sta_add(void *priv,\n \t\t\t\tgoto fail;\n \t\t}\n \n+\t\tif (params->uhr_capab) {\n+\t\t\twpa_hexdump(MSG_DEBUG, \" * uhr_capab\",\n+\t\t\t\t params->uhr_capab, params->uhr_capab_len);\n+\t\t\tif (nla_put(msg, NL80211_ATTR_UHR_CAPABILITY,\n+\t\t\t\t params->uhr_capab_len, params->uhr_capab))\n+\t\t\t\tgoto fail;\n+\t\t}\n+\n \t\tif (params->ext_capab) {\n \t\t\twpa_hexdump(MSG_DEBUG, \" * ext_capab\",\n \t\t\t\t params->ext_capab, params->ext_capab_len);\n@@ -7164,6 +7172,12 @@ static int nl80211_ht_vht_overrides(struct nl_msg *msg,\n \t\t\treturn -1;\n \t}\n \n+\tif (params->disable_uhr) {\n+\t\twpa_printf(MSG_DEBUG, \" * UHR disabled\");\n+\t\tif (nla_put_flag(msg, NL80211_ATTR_DISABLE_UHR))\n+\t\t\treturn -1;\n+\t}\n+\n \treturn 0;\n }\n \ndiff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c\nindex 620cff5d8d7c..615164b0381d 100644\n--- a/src/drivers/driver_nl80211_capa.c\n+++ b/src/drivers/driver_nl80211_capa.c\n@@ -2189,6 +2189,7 @@ static void phy_info_iftype_copy(struct hostapd_hw_modes *mode,\n \tsize_t len;\n \tstruct he_capabilities *he_capab = &mode->he_capab[opmode];\n \tstruct eht_capabilities *eht_capab = &mode->eht_capab[opmode];\n+\tstruct uhr_capabilities *uhr_capab = &mode->uhr_capab[opmode];\n \n \tswitch (opmode) {\n \tcase IEEE80211_MODE_INFRA:\n@@ -2296,6 +2297,24 @@ static void phy_info_iftype_copy(struct hostapd_hw_modes *mode,\n \t\t\t nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE]),\n \t\t\t len);\n \t}\n+\n+\tif (!tb[NL80211_BAND_IFTYPE_ATTR_UHR_CAP_MAC] ||\n+\t !tb[NL80211_BAND_IFTYPE_ATTR_UHR_CAP_PHY])\n+\t\treturn;\n+\n+\tuhr_capab->uhr_supported = true;\n+\n+\tif (tb[NL80211_BAND_IFTYPE_ATTR_UHR_CAP_MAC] &&\n+\t nla_len(tb[NL80211_BAND_IFTYPE_ATTR_UHR_CAP_MAC]) >= (int)sizeof(uhr_capab->mac))\n+\t\tos_memcpy(uhr_capab->mac,\n+\t\t\t nla_data(tb[NL80211_BAND_IFTYPE_ATTR_UHR_CAP_MAC]),\n+\t\t\t sizeof(uhr_capab->mac));\n+\n+\tif (tb[NL80211_BAND_IFTYPE_ATTR_UHR_CAP_PHY] &&\n+\t nla_len(tb[NL80211_BAND_IFTYPE_ATTR_UHR_CAP_PHY]) >= (int)sizeof(uhr_capab->phy))\n+\t\tos_memcpy(uhr_capab->phy,\n+\t\t\t nla_data(tb[NL80211_BAND_IFTYPE_ATTR_UHR_CAP_PHY]),\n+\t\t\t sizeof(uhr_capab->phy));\n }\n \n \ndiff --git a/tests/hwsim/example-hostapd.config b/tests/hwsim/example-hostapd.config\nindex 41611b0f2f16..32ebf0870ee9 100644\n--- a/tests/hwsim/example-hostapd.config\n+++ b/tests/hwsim/example-hostapd.config\n@@ -53,6 +53,8 @@ CONFIG_LIBNL3_ROUTE=y\n CONFIG_IEEE80211R=y\n CONFIG_IEEE80211AC=y\n CONFIG_IEEE80211AX=y\n+CONFIG_IEEE80211BE=y\n+CONFIG_IEEE80211BN=y\n \n CONFIG_OCV=y\n \ndiff --git a/tests/hwsim/example-wpa_supplicant.config b/tests/hwsim/example-wpa_supplicant.config\nindex c5b364757afa..f3c1727f60ce 100644\n--- a/tests/hwsim/example-wpa_supplicant.config\n+++ b/tests/hwsim/example-wpa_supplicant.config\n@@ -169,6 +169,7 @@ CONFIG_PASN=y\n CONFIG_NAN_USD=y\n \n CONFIG_IEEE80211BE=y\n+CONFIG_IEEE80211BN=y\n CONFIG_PROCESS_COORDINATION=y\n \n CONFIG_NAN=y\ndiff --git a/tests/hwsim/test_uhr.py b/tests/hwsim/test_uhr.py\nnew file mode 100644\nindex 000000000000..b2a075aaae91\n--- /dev/null\n+++ b/tests/hwsim/test_uhr.py\n@@ -0,0 +1,152 @@\n+# UHR tests\n+# Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc.\n+# Copyright (C) 2025 Intel Corporation\n+#\n+# This software may be distributed under the terms of the BSD license.\n+# See README for more details.\n+\n+import binascii\n+import tempfile\n+import time\n+\n+import hostapd\n+from utils import *\n+from hwsim import HWSimRadio\n+import hwsim_utils\n+from wpasupplicant import WpaSupplicant\n+from test_eht import eht_verify_status, traffic_test\n+from test_eht import eht_mld_ap_wpa2_params, eht_mld_enable_ap\n+\n+def uhr_verify_wifi_version(dev):\n+ status = dev.get_status()\n+ logger.info(\"station status: \" + str(status))\n+\n+ if 'wifi_generation' not in status:\n+ raise Exception(\"Missing wifi_generation information\")\n+ if status['wifi_generation'] != \"8\":\n+ raise Exception(\"Unexpected wifi_generation value: \" + status['wifi_generation'])\n+\n+def uhr_verify_status(wpas, hapd, is_ht=False, is_vht=False):\n+ status = hapd.get_status()\n+\n+ logger.info(\"hostapd STATUS: \" + str(status))\n+ if is_ht and status[\"ieee80211n\"] != \"1\":\n+ raise Exception(\"Unexpected STATUS ieee80211n value\")\n+ if is_vht and status[\"ieee80211ac\"] != \"1\":\n+ raise Exception(\"Unexpected STATUS ieee80211ac value\")\n+ if status[\"ieee80211ax\"] != \"1\":\n+ raise Exception(\"Unexpected STATUS ieee80211ax value\")\n+ if status[\"ieee80211be\"] != \"1\":\n+ raise Exception(\"Unexpected STATUS ieee80211be value\")\n+ if status[\"ieee80211bn\"] != \"1\":\n+ raise Exception(\"Unexpected STATUS ieee80211bn value\")\n+\n+ sta = hapd.get_sta(wpas.own_addr())\n+ logger.info(\"hostapd STA: \" + str(sta))\n+ if sta['addr'] == 'FAIL':\n+ raise Exception(\"hostapd \" + hapd.ifname + \" did not have a STA entry for the STA \" + wpas.own_addr())\n+ if is_ht and \"[HT]\" not in sta['flags']:\n+ raise Exception(\"Missing STA flag: HT\")\n+ if is_vht and \"[VHT]\" not in sta['flags']:\n+ raise Exception(\"Missing STA flag: VHT\")\n+ if \"[HE]\" not in sta['flags']:\n+ raise Exception(\"Missing STA flag: HE\")\n+ if \"[EHT]\" not in sta['flags']:\n+ raise Exception(\"Missing STA flag: EHT\")\n+ if \"[UHR]\" not in sta['flags']:\n+ raise Exception(\"Missing STA flag: UHR\")\n+\n+def test_uhr_simple(dev, apdev):\n+ \"\"\"UHR AP with simple SAE configuration\"\"\"\n+ with HWSimRadio(use_mlo=True) as (hapd_radio, hapd_iface), \\\n+ HWSimRadio(use_mlo=True) as (wpas_radio, wpas_iface):\n+ wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')\n+ wpas.interface_add(wpas_iface)\n+ check_sae_capab(wpas)\n+\n+ passphrase = 'qwertyuiop'\n+ params = eht_mld_ap_wpa2_params(\"uhr\", key_mgmt=\"SAE\",\n+ passphrase=passphrase,\n+ pwe='2', mfp='2')\n+ params['ieee80211bn'] = '1'\n+ params['require_uhr'] = '1'\n+ try:\n+ hapd = eht_mld_enable_ap(hapd_iface, 0, params)\n+ except Exception as e:\n+ if isinstance(e, Exception) and \\\n+ str(e) == \"Failed to set hostapd parameter ieee80211bn\":\n+ raise HwsimSkip(\"UHR not supported\")\n+ raise\n+ if hapd.get_status_field(\"ieee80211bn\") != \"1\":\n+ raise Exception(\"AP STATUS did not indicate ieee80211bn=1\")\n+ wpas.set(\"sae_pwe\", \"1\")\n+ wpas.connect(\"uhr\", key_mgmt=\"SAE\", sae_password=passphrase,\n+ ieee80211w=\"2\", scan_freq=\"2412\")\n+ hapd.wait_sta()\n+ sta = hapd.get_sta(wpas.own_addr())\n+ uhr_verify_status(wpas, hapd, is_ht=True)\n+ status = wpas.request(\"STATUS\")\n+ if \"wifi_generation=8\" not in status:\n+ raise Exception(\"STA STATUS did not indicate wifi_generation=8\")\n+\n+def uhr_mld_ap_wpa2_params(ssid, passphrase=None, key_mgmt=\"WPA-PSK-SHA256\",\n+ mfp=\"2\", pwe=None, beacon_prot=\"1\", bridge=False):\n+ params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase,\n+ wpa_key_mgmt=key_mgmt, ieee80211w=mfp)\n+ params['ieee80211n'] = '1'\n+ params['ieee80211ax'] = '1'\n+ params['ieee80211be'] = '1'\n+ params['ieee80211bn'] = '1'\n+ params['channel'] = '1'\n+ params['hw_mode'] = 'g'\n+ params['group_mgmt_cipher'] = \"AES-128-CMAC\"\n+ params['beacon_prot'] = beacon_prot\n+ if bridge:\n+ params['bridge'] = 'ap-br0'\n+\n+ if pwe is not None:\n+ params['sae_pwe'] = pwe\n+\n+ return params\n+\n+def uhr_mld_enable_ap(iface, link_id, params):\n+ hapd = hostapd.add_mld_link(iface, link_id, params)\n+ hapd.enable()\n+\n+ ev = hapd.wait_event([\"AP-ENABLED\", \"AP-DISABLED\"], timeout=1)\n+ if ev is None:\n+ raise Exception(\"AP startup timed out\")\n+ if \"AP-ENABLED\" not in ev:\n+ raise Exception(\"AP startup failed\")\n+\n+ return hapd\n+\n+def run_uhr_mld_sae_single_link(dev, apdev, anti_clogging_token=False):\n+ with HWSimRadio(use_mlo=True) as (hapd_radio, hapd_iface), \\\n+ HWSimRadio(use_mlo=True) as (wpas_radio, wpas_iface):\n+ wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')\n+ wpas.interface_add(wpas_iface)\n+ check_sae_capab(wpas)\n+\n+ passphrase = 'qwertyuiop'\n+ ssid = \"mld_ap_sae_single_link\"\n+ params = uhr_mld_ap_wpa2_params(ssid, passphrase, key_mgmt=\"SAE\",\n+ mfp=\"2\", pwe='2')\n+ if anti_clogging_token:\n+ params['sae_anti_clogging_threshold'] = '0'\n+\n+ hapd0 = uhr_mld_enable_ap(hapd_iface, 0, params)\n+\n+ wpas.set(\"sae_pwe\", \"1\")\n+ wpas.connect(ssid, sae_password=passphrase, scan_freq=\"2412\",\n+ key_mgmt=\"SAE\", ieee80211w=\"2\")\n+\n+ eht_verify_status(wpas, hapd0, 2412, 20, is_ht=True, mld=True,\n+ valid_links=1, active_links=1)\n+ uhr_verify_status(wpas, hapd0, is_ht=True)\n+ uhr_verify_wifi_version(wpas)\n+ traffic_test(wpas, hapd0)\n+\n+def test_uhr_mld_sae_single_link(dev, apdev):\n+ \"\"\"UHR MLD AP with MLD client SAE H2E connection using single link\"\"\"\n+ run_uhr_mld_sae_single_link(dev, apdev)\ndiff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk\nindex cbb839780b74..96488ae13e1f 100644\n--- a/wpa_supplicant/Android.mk\n+++ b/wpa_supplicant/Android.mk\n@@ -989,6 +989,9 @@ endif\n ifdef CONFIG_IEEE80211BE\n OBJS += src/ap/ieee802_11_eht.c\n endif\n+ifdef CONFIG_IEEE80211BN\n+OBJS += src/ap/ieee802_11_uhr.c\n+endif\n ifdef CONFIG_WNM_AP\n L_CFLAGS += -DCONFIG_WNM_AP\n OBJS += src/ap/wnm_ap.c\ndiff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile\nindex 67f337df33da..460d4be813b1 100644\n--- a/wpa_supplicant/Makefile\n+++ b/wpa_supplicant/Makefile\n@@ -1063,6 +1063,9 @@ endif\n ifdef CONFIG_IEEE80211BE\n OBJS += ../src/ap/ieee802_11_eht.o\n endif\n+ifdef CONFIG_IEEE80211BN\n+OBJS += ../src/ap/ieee802_11_uhr.o\n+endif\n ifdef CONFIG_WNM_AP\n CFLAGS += -DCONFIG_WNM_AP\n OBJS += ../src/ap/wnm_ap.o\n@@ -1085,6 +1088,10 @@ OBJS += ../src/eap_server/eap_server_methods.o\n ifdef CONFIG_IEEE80211AC\n CFLAGS += -DCONFIG_IEEE80211AC\n endif\n+ifdef CONFIG_IEEE80211BN\n+CONFIG_IEEE80211BE=y\n+CFLAGS += -DCONFIG_IEEE80211BN\n+endif\n ifdef CONFIG_IEEE80211BE\n CONFIG_IEEE80211AX=y\n CFLAGS += -DCONFIG_IEEE80211BE\ndiff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c\nindex e99036366681..b05a4d985417 100644\n--- a/wpa_supplicant/config.c\n+++ b/wpa_supplicant/config.c\n@@ -2943,6 +2943,7 @@ static const struct parse_data ssid_fields[] = {\n \t{ INT_RANGE(transition_disable, 0, 255) },\n \t{ INT_RANGE(sae_pk, 0, 2) },\n \t{ INT_RANGE(disable_eht, 0, 1)},\n+\t{ INT_RANGE(disable_uhr, 0, 1)},\n \t{ INT_RANGE(enable_4addr_mode, 0, 1)},\n \t{ INT_RANGE(max_idle, 0, 65535)},\n \t{ BOOL(ssid_protection)},\ndiff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c\nindex 81d92b7ddf21..7360f7012ea2 100644\n--- a/wpa_supplicant/config_file.c\n+++ b/wpa_supplicant/config_file.c\n@@ -1019,6 +1019,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid,\n \tINT(disable_he);\n #endif /* CONFIG_HE_OVERRIDES */\n \tINT(disable_eht);\n+\tINT(disable_uhr);\n \tINT(enable_4addr_mode);\n \tINT(max_idle);\n \tINT(ssid_protection);\ndiff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h\nindex 7c60d4e38cab..369b867b8b35 100644\n--- a/wpa_supplicant/config_ssid.h\n+++ b/wpa_supplicant/config_ssid.h\n@@ -1300,6 +1300,14 @@ struct wpa_ssid {\n \t */\n \tint disable_eht;\n \n+\t/**\n+\t * disable_uhr - Disable UHR (IEEE 802.11bn) for this network\n+\t *\n+\t * By default, use it if it is available, but this can be configured\n+\t * to 1 to have it disabled.\n+\t */\n+\tint disable_uhr;\n+\n \t/**\n \t * enable_4addr_mode - Set 4addr mode after association\n \t * 0 = Do not attempt to set 4addr mode\ndiff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c\nindex 1096fa228d06..78f101ba9d29 100644\n--- a/wpa_supplicant/ctrl_iface.c\n+++ b/wpa_supplicant/ctrl_iface.c\n@@ -2379,12 +2379,14 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,\n \n \t\tif (wpa_s->connection_set &&\n \t\t (wpa_s->connection_ht || wpa_s->connection_vht ||\n-\t\t wpa_s->connection_he || wpa_s->connection_eht)) {\n+\t\t wpa_s->connection_he || wpa_s->connection_eht ||\n+\t\t wpa_s->connection_uhr)) {\n \t\t\tret = os_snprintf(pos, end - pos,\n \t\t\t\t\t \"wifi_generation=%u\\n\",\n+\t\t\t\t\t wpa_s->connection_uhr ? 8 :\n \t\t\t\t\t wpa_s->connection_eht ? 7 :\n-\t\t\t\t\t (wpa_s->connection_he ? 6 :\n-\t\t\t\t\t (wpa_s->connection_vht ? 5 : 4)));\n+\t\t\t\t\t wpa_s->connection_he ? 6 :\n+\t\t\t\t\t wpa_s->connection_vht ? 5 : 4);\n \t\t\tif (os_snprintf_error(end - pos, ret))\n \t\t\t\treturn pos - buf;\n \t\t\tpos += ret;\ndiff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c\nindex 2a281e4c4b06..a412361195ef 100644\n--- a/wpa_supplicant/events.c\n+++ b/wpa_supplicant/events.c\n@@ -1064,6 +1064,17 @@ static int rate_match(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,\n \t\t\t\tcontinue;\n \t\t\t}\n \n+\t\t\tif (flagged && ((rate_ie[j] & 0x7f) ==\n+\t\t\t\t\tBSS_MEMBERSHIP_SELECTOR_UHR_PHY)) {\n+\t\t\t\tif (!uhr_supported(mode, IEEE80211_MODE_INFRA)) {\n+\t\t\t\t\tif (debug_print)\n+\t\t\t\t\t\twpa_dbg(wpa_s, MSG_DEBUG,\n+\t\t\t\t\t\t\t\" hardware does not support UHR PHY\");\n+\t\t\t\t\treturn 0;\n+\t\t\t\t}\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n #ifdef CONFIG_SAE\n \t\t\tif (flagged && ((rate_ie[j] & 0x7f) ==\n \t\t\t\t\tBSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY)) {\n@@ -3556,6 +3567,8 @@ static void wpas_parse_connection_info(struct wpa_supplicant *wpa_s,\n \t\tresp_elems.eht_capabilities;\n \tif (req_elems.rrm_enabled)\n \t\twpa_s->rrm.rrm_used = 1;\n+\twpa_s->connection_uhr = req_elems.uhr_capabilities &&\n+\t\tresp_elems.uhr_capabilities;\n \n #ifdef CONFIG_PMKSA_PRIVACY\n \tif (wpa_s->assoc_resp_encrypted && resp_elems.nonce) {\ndiff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c\nindex f110e161f067..15986067135c 100644\n--- a/wpa_supplicant/sme.c\n+++ b/wpa_supplicant/sme.c\n@@ -4139,6 +4139,7 @@ mscs_fail:\n \twpa_supplicant_apply_he_overrides(wpa_s, ssid, ¶ms);\n #endif /* CONFIG_HE_OVERRIDES */\n \twpa_supplicant_apply_eht_overrides(wpa_s, ssid, ¶ms);\n+\twpa_supplicant_apply_uhr_overrides(wpa_s, ssid, ¶ms);\n #ifdef CONFIG_IEEE80211R\n \tif (auth_type == WLAN_AUTH_FT && wpa_s->sme.ft_ies &&\n \t get_ie(wpa_s->sme.ft_ies, wpa_s->sme.ft_ies_len,\ndiff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c\nindex 64d6154ee2e8..6b523ae8387c 100644\n--- a/wpa_supplicant/wpa_cli.c\n+++ b/wpa_supplicant/wpa_cli.c\n@@ -1497,6 +1497,7 @@ static const char *network_fields[] = {\n \t\"disable_he\",\n #endif /* CONFIG_HE_OVERRIDES */\n \t\"disable_eht\",\n+\t\"disable_uhr\",\n \t\"ap_max_inactivity\", \"dtim_period\", \"beacon_int\",\n #ifdef CONFIG_MACSEC\n \t\"macsec_policy\",\ndiff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c\nindex c9dfe41bca41..515682f67242 100644\n--- a/wpa_supplicant/wpa_supplicant.c\n+++ b/wpa_supplicant/wpa_supplicant.c\n@@ -2262,7 +2262,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,\n \t\twpa_sm_set_param(wpa_s->wpa, WPA_PARAM_USE_EXT_KEY_ID, 0);\n \t}\n \n-\t/* Mark WMM enabled for any HT/VHT/HE/EHT association to get more\n+\t/* Mark WMM enabled for any HT/VHT/HE/EHT/UHR association to get more\n \t * appropriate advertisement of the supported number of PTKSA receive\n \t * counters. In theory, this could be based on a driver capability, but\n \t * in practice all cases using WMM support at least eight replay\n@@ -2273,7 +2273,8 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,\n \t * is far more likely for any current device to support WMM. */\n \twmm = wpa_s->connection_set &&\n \t\t(wpa_s->connection_ht || wpa_s->connection_vht ||\n-\t\t wpa_s->connection_he || wpa_s->connection_eht);\n+\t\t wpa_s->connection_he || wpa_s->connection_eht ||\n+\t\t wpa_s->connection_uhr);\n \tif (!wmm && bss)\n \t\twmm = !!wpa_bss_get_vendor_ie(bss, WMM_IE_VENDOR_TYPE);\n \twpa_sm_set_param(wpa_s->wpa, WPA_PARAM_WMM_ENABLED, wmm);\n@@ -4957,6 +4958,7 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)\n \twpa_supplicant_apply_he_overrides(wpa_s, ssid, ¶ms);\n #endif /* CONFIG_HE_OVERRIDES */\n \twpa_supplicant_apply_eht_overrides(wpa_s, ssid, ¶ms);\n+\twpa_supplicant_apply_uhr_overrides(wpa_s, ssid, ¶ms);\n \n #ifdef CONFIG_P2P\n \t/*\n@@ -6910,6 +6912,17 @@ void wpa_supplicant_apply_eht_overrides(\n }\n \n \n+void wpa_supplicant_apply_uhr_overrides(\n+\tstruct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,\n+\tstruct wpa_driver_associate_params *params)\n+{\n+\tif (!ssid)\n+\t\treturn;\n+\n+\tparams->disable_uhr = ssid->disable_uhr;\n+}\n+\n+\n static int pcsc_reader_init(struct wpa_supplicant *wpa_s)\n {\n #ifdef PCSC_FUNCS\ndiff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h\nindex d68dd582fb75..6724bc017374 100644\n--- a/wpa_supplicant/wpa_supplicant_i.h\n+++ b/wpa_supplicant/wpa_supplicant_i.h\n@@ -1054,6 +1054,7 @@ struct wpa_supplicant {\n \tunsigned int connection_vht:1;\n \tunsigned int connection_he:1;\n \tunsigned int connection_eht:1;\n+\tunsigned int connection_uhr:1;\n \tunsigned int disable_mbo_oce:1;\n \tu8 connection_max_nss_rx;\n \tu8 connection_max_nss_tx;\n@@ -1765,6 +1766,9 @@ void wpa_supplicant_apply_he_overrides(\n void wpa_supplicant_apply_eht_overrides(\n \tstruct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,\n \tstruct wpa_driver_associate_params *params);\n+void wpa_supplicant_apply_uhr_overrides(\n+\tstruct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,\n+\tstruct wpa_driver_associate_params *params);\n \n int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);\n int wpa_supplicant_set_wpa_none_key(struct wpa_supplicant *wpa_s,\n", "prefixes": [ "v3", "02/12" ] }