[PATCH v3 10/12] tests: Add two tests for UHR DBE
Johannes Berg
johannes at sipsolutions.net
Thu May 7 10:21:37 PDT 2026
From: Johannes Berg <johannes.berg at intel.com>
Add two simple tests for DBE with 80 MHz instead of the
EHT 40 MHz, one where it gets used by a UHR client and
one where it doesn't get used by a non-UHR client.
Signed-off-by: Johannes Berg <johannes.berg at intel.com>
---
tests/hwsim/test_uhr.py | 115 ++++++++++++++++++++++++++++++++++++++--
1 file changed, 112 insertions(+), 3 deletions(-)
diff --git a/tests/hwsim/test_uhr.py b/tests/hwsim/test_uhr.py
index aaffd5f51f83..67f6e06dbf79 100644
--- a/tests/hwsim/test_uhr.py
+++ b/tests/hwsim/test_uhr.py
@@ -8,13 +8,14 @@
import binascii
import tempfile
import time
+from functools import partial
import hostapd
from utils import *
from hwsim import HWSimRadio
import hwsim_utils
from wpasupplicant import WpaSupplicant
-from test_eht import eht_verify_status, traffic_test
+from test_eht import eht_verify_status, traffic_test, eht_verify_wifi_version
from test_eht import eht_mld_ap_wpa2_params, eht_mld_enable_ap
def uhr_verify_wifi_version(dev):
@@ -26,7 +27,7 @@ def uhr_verify_wifi_version(dev):
if status['wifi_generation'] != "8":
raise Exception("Unexpected wifi_generation value: " + status['wifi_generation'])
-def uhr_verify_status(wpas, hapd, is_ht=False, is_vht=False):
+def uhr_verify_status(wpas, hapd, is_ht=False, is_vht=False, sta_expect_uhr=True):
status = hapd.get_status()
logger.info("hostapd STATUS: " + str(status))
@@ -54,7 +55,10 @@ def uhr_verify_status(wpas, hapd, is_ht=False, is_vht=False):
if "[EHT]" not in sta['flags']:
raise Exception("Missing STA flag: EHT")
if "[UHR]" not in sta['flags']:
- raise Exception("Missing STA flag: UHR")
+ if sta_expect_uhr:
+ raise Exception("Missing STA flag: UHR")
+ elif not sta_expect_uhr:
+ raise Exception("Erroneous STA flag: UHR")
def test_uhr_simple(dev, apdev):
"""UHR AP with simple SAE configuration"""
@@ -173,3 +177,108 @@ def run_uhr_mld_sae_single_link(dev, apdev, anti_clogging_token=False):
def test_uhr_mld_sae_single_link(dev, apdev):
"""UHR MLD AP with MLD client SAE H2E connection using single link"""
run_uhr_mld_sae_single_link(dev, apdev)
+
+def uhr_5ghz_params(ssid, passphrase, channel, chanwidth, ccfs1, ccfs2=0,
+ he_ccfs1=None, he_oper_chanwidth=None):
+ if he_ccfs1 is None:
+ he_ccfs1 = ccfs1
+ if he_oper_chanwidth is None:
+ he_oper_chanwidth = chanwidth
+
+ params = uhr_mld_ap_wpa2_params(ssid, passphrase, key_mgmt="SAE",
+ mfp="2", pwe='2')
+ params.update({
+ "country_code": "US",
+ "hw_mode": "a",
+ "channel": str(channel),
+ "ieee80211n": "1",
+ "ieee80211ac": "1",
+ "ieee80211ax": "1",
+ "ieee80211be": "1",
+ "ieee80211bn": "1",
+ "vht_oper_chwidth": str(he_oper_chanwidth),
+ "vht_oper_centr_freq_seg0_idx": str(he_ccfs1),
+ "vht_oper_centr_freq_seg1_idx": str(ccfs2),
+ "he_oper_chwidth": str(he_oper_chanwidth),
+ "he_oper_centr_freq_seg0_idx": str(he_ccfs1),
+ "he_oper_centr_freq_seg1_idx": str(ccfs2),
+ "eht_oper_centr_freq_seg0_idx": str(ccfs1),
+ "eht_oper_chwidth": str(chanwidth),
+ })
+
+ if he_oper_chanwidth == 0:
+ if channel < he_ccfs1:
+ params["ht_capab"] = "[HT40+]"
+ elif channel > he_ccfs1:
+ params["ht_capab"] = "[HT40-]"
+ else:
+ params["ht_capab"] = "[HT40+]"
+ if he_oper_chanwidth == 2:
+ params["vht_capab"] = "[VHT160]"
+ elif he_oper_chanwidth == 3:
+ params["vht_capab"] = "[VHT160-80PLUS80]"
+
+ return params
+
+def _test_uhr_5ghz(channel, chanwidth, ccfs1, ccfs2=0,
+ callback=None, uhr_connection=True, **kw):
+ with HWSimRadio(use_mlo=True) as (hapd_radio, hapd_iface), \
+ HWSimRadio(use_mlo=True) as (wpas_radio, wpas_iface):
+ wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
+ wpas.interface_add(wpas_iface)
+ check_sae_capab(wpas)
+
+ passphrase = 'quertyiop'
+ params = uhr_5ghz_params('uhr', passphrase, channel,
+ chanwidth, ccfs1, ccfs2)
+ params.update(kw)
+
+ freq = 5000 + channel * 5
+
+ hapd = uhr_mld_enable_ap(hapd_iface, 0, params)
+ wpas.set('sae_pwe', '1')
+ wpas.connect('uhr', sae_password=passphrase, scan_freq=str(freq),
+ key_mgmt="SAE", ieee80211w="2",
+ disable_uhr='1' if not uhr_connection else '0')
+ hapd.wait_sta()
+
+ uhr_verify_status(wpas, hapd, is_ht=True, is_vht=True,
+ sta_expect_uhr=uhr_connection)
+ if uhr_connection:
+ uhr_verify_wifi_version(wpas)
+ else:
+ eht_verify_wifi_version(wpas)
+ hwsim_utils.test_connectivity(wpas, hapd)
+ if callback: callback(wpas, hapd)
+
+def _check_width(link, width, wpas, hapd):
+ sig = wpas.request("MLO_SIGNAL_POLL").splitlines()
+ logger.debug(sig)
+ link_data = {}
+ cur_link = None
+ for line in sig:
+ if line.startswith('LINK_ID='):
+ cur_link = int(line[8:])
+ if not cur_link in link_data:
+ link_data[cur_link] = []
+ link_data[cur_link].append(line)
+ assert link in link_data, f'link {link} not found'
+ assert f'WIDTH={width} MHz' in link_data[link], \
+ f'client not connected with {width} MHz'
+
+def test_uhr_5ghz_dbe_80(dev, apdev):
+ """UHR with DBE enabled"""
+ try:
+ _test_uhr_5ghz(36, 0, 38, dbe_bandwidth="2",
+ callback=partial(_check_width, 0, 80))
+ finally:
+ set_world_reg(apdev[0], None, dev[0])
+
+def test_uhr_5ghz_dbe_80_not_used(dev, apdev):
+ """UHR with DBE enabled but client can't use it"""
+ try:
+ _test_uhr_5ghz(36, 0, 38, dbe_bandwidth="2",
+ callback=partial(_check_width, 0, 40),
+ uhr_connection=False)
+ finally:
+ set_world_reg(apdev[0], None, dev[0])
--
2.53.0
More information about the Hostap
mailing list