]> git.ipfire.org Git - thirdparty/hostap.git/blame - tests/hwsim/test_ap_vht.py
tests: Fix ap_vht_csa_vht40 to use list of events with wait_event()
[thirdparty/hostap.git] / tests / hwsim / test_ap_vht.py
CommitLineData
7cd0aa7e
JM
1# Test cases for VHT operations with hostapd
2# Copyright (c) 2014, Qualcomm Atheros, Inc.
ea7526bf 3# Copyright (c) 2013, Intel Corporation
7cd0aa7e
JM
4#
5# This software may be distributed under the terms of the BSD license.
6# See README for more details.
7
8import logging
9logger = logging.getLogger()
6259fd81 10import os
ea7526bf 11import subprocess, time
7cd0aa7e
JM
12
13import hwsim_utils
14import hostapd
810dcfb6 15from wpasupplicant import WpaSupplicant
2e71d041 16from utils import *
6259fd81 17from test_dfs import wait_dfs_event
d4792c0c 18from test_ap_csa import csa_supported
29fb191c 19from test_ap_ht import clear_scan_cache
7cd0aa7e
JM
20
21def vht_supported():
22 cmd = subprocess.Popen(["iw", "reg", "get"], stdout=subprocess.PIPE)
23 reg = cmd.stdout.read()
24 if "@ 80)" in reg or "@ 160)" in reg:
25 return True
26 return False
27
28def test_ap_vht80(dev, apdev):
29 """VHT with 80 MHz channel width"""
30 try:
9d7fdac5 31 hapd = None
fab49f61
JM
32 params = {"ssid": "vht",
33 "country_code": "FI",
34 "hw_mode": "a",
35 "channel": "36",
36 "ht_capab": "[HT40+]",
37 "ieee80211n": "1",
38 "ieee80211ac": "1",
39 "vht_oper_chwidth": "1",
40 "vht_oper_centr_freq_seg0_idx": "42"}
8b8a1864 41 hapd = hostapd.add_ap(apdev[0], params)
528a7d22 42 bssid = apdev[0]['bssid']
7cd0aa7e
JM
43
44 dev[0].connect("vht", key_mgmt="NONE", scan_freq="5180")
a8375c94 45 hwsim_utils.test_connectivity(dev[0], hapd)
7e40a881
JM
46 sig = dev[0].request("SIGNAL_POLL").splitlines()
47 if "FREQUENCY=5180" not in sig:
48 raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
49 if "WIDTH=80 MHz" not in sig:
50 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
528a7d22
JM
51 est = dev[0].get_bss(bssid)['est_throughput']
52 if est != "390001":
53 raise Exception("Unexpected BSS est_throughput: " + est)
f98fdc4e
JM
54 status = dev[0].get_status()
55 if status["ieee80211ac"] != "1":
56 raise Exception("Unexpected STATUS ieee80211ac value (STA)")
96485214
JM
57 status = hapd.get_status()
58 logger.info("hostapd STATUS: " + str(status))
59 if status["ieee80211n"] != "1":
60 raise Exception("Unexpected STATUS ieee80211n value")
61 if status["ieee80211ac"] != "1":
62 raise Exception("Unexpected STATUS ieee80211ac value")
63 if status["secondary_channel"] != "1":
64 raise Exception("Unexpected STATUS secondary_channel value")
65 if status["vht_oper_chwidth"] != "1":
66 raise Exception("Unexpected STATUS vht_oper_chwidth value")
67 if status["vht_oper_centr_freq_seg0_idx"] != "42":
68 raise Exception("Unexpected STATUS vht_oper_centr_freq_seg0_idx value")
3bee996c
JM
69 if "vht_caps_info" not in status:
70 raise Exception("Missing vht_caps_info")
71
72 sta = hapd.get_sta(dev[0].own_addr())
73 logger.info("hostapd STA: " + str(sta))
74 if "[HT]" not in sta['flags']:
75 raise Exception("Missing STA flag: HT")
76 if "[VHT]" not in sta['flags']:
77 raise Exception("Missing STA flag: VHT")
bab493b9 78 except Exception as e:
7cd0aa7e
JM
79 if isinstance(e, Exception) and str(e) == "AP startup failed":
80 if not vht_supported():
81e787b7 81 raise HwsimSkip("80 MHz channel not supported in regulatory information")
7cd0aa7e
JM
82 raise
83 finally:
9d7fdac5 84 dev[0].request("DISCONNECT")
2d6889e0 85 clear_regdom(hapd, dev)
7cd0aa7e 86
810dcfb6
JM
87def test_ap_vht_wifi_generation(dev, apdev):
88 """VHT and wifi_generation"""
89 try:
90 hapd = None
fab49f61
JM
91 params = {"ssid": "vht",
92 "country_code": "FI",
93 "hw_mode": "a",
94 "channel": "36",
95 "ht_capab": "[HT40+]",
96 "ieee80211n": "1",
97 "ieee80211ac": "1",
98 "vht_oper_chwidth": "1",
99 "vht_oper_centr_freq_seg0_idx": "42"}
810dcfb6
JM
100 hapd = hostapd.add_ap(apdev[0], params)
101 bssid = apdev[0]['bssid']
102
103 dev[0].connect("vht", key_mgmt="NONE", scan_freq="5180")
104 status = dev[0].get_status()
105 if 'wifi_generation' not in status:
106 # For now, assume this is because of missing kernel support
107 raise HwsimSkip("Association Request IE reporting not supported")
108 #raise Exception("Missing wifi_generation information")
109 if status['wifi_generation'] != "5":
110 raise Exception("Unexpected wifi_generation value: " + status['wifi_generation'])
111
112 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
113 wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
114 wpas.connect("vht", key_mgmt="NONE", scan_freq="5180")
115 status = wpas.get_status()
116 if 'wifi_generation' not in status:
117 # For now, assume this is because of missing kernel support
118 raise HwsimSkip("Association Request IE reporting not supported")
119 #raise Exception("Missing wifi_generation information (connect)")
120 if status['wifi_generation'] != "5":
121 raise Exception("Unexpected wifi_generation value (connect): " + status['wifi_generation'])
122 except Exception as e:
123 if isinstance(e, Exception) and str(e) == "AP startup failed":
124 if not vht_supported():
125 raise HwsimSkip("80 MHz channel not supported in regulatory information")
126 raise
127 finally:
128 dev[0].request("DISCONNECT")
85873c66 129 clear_regdom(hapd, dev)
810dcfb6 130
5161ea8e 131def vht80_test(apdev, dev, channel, ht_capab):
cb3c0d96 132 clear_scan_cache(apdev)
5161ea8e
JM
133 try:
134 hapd = None
fab49f61
JM
135 params = {"ssid": "vht",
136 "country_code": "FI",
137 "hw_mode": "a",
138 "channel": str(channel),
139 "ht_capab": ht_capab,
140 "ieee80211n": "1",
141 "ieee80211ac": "1",
142 "vht_oper_chwidth": "1",
143 "vht_oper_centr_freq_seg0_idx": "42"}
afc26df2 144 hapd = hostapd.add_ap(apdev, params)
5161ea8e
JM
145 bssid = apdev['bssid']
146
3074cb1f
MH
147 dev[0].connect("vht", key_mgmt="NONE",
148 scan_freq=str(5000 + 5 * channel))
149 hwsim_utils.test_connectivity(dev[0], hapd)
bab493b9 150 except Exception as e:
5161ea8e
JM
151 if isinstance(e, Exception) and str(e) == "AP startup failed":
152 if not vht_supported():
153 raise HwsimSkip("80 MHz channel not supported in regulatory information")
154 raise
155 finally:
3074cb1f 156 clear_regdom(hapd, dev)
5161ea8e
JM
157
158def test_ap_vht80b(dev, apdev):
159 """VHT with 80 MHz channel width (HT40- channel 40)"""
3074cb1f 160 vht80_test(apdev[0], dev, 40, "[HT40-]")
5161ea8e
JM
161
162def test_ap_vht80c(dev, apdev):
163 """VHT with 80 MHz channel width (HT40+ channel 44)"""
3074cb1f 164 vht80_test(apdev[0], dev, 44, "[HT40+]")
5161ea8e
JM
165
166def test_ap_vht80d(dev, apdev):
167 """VHT with 80 MHz channel width (HT40- channel 48)"""
3074cb1f 168 vht80_test(apdev[0], dev, 48, "[HT40-]")
5161ea8e 169
7cd0aa7e
JM
170def test_ap_vht80_params(dev, apdev):
171 """VHT with 80 MHz channel width and number of optional features enabled"""
172 try:
9d7fdac5 173 hapd = None
fab49f61
JM
174 params = {"ssid": "vht",
175 "country_code": "FI",
176 "hw_mode": "a",
177 "channel": "36",
178 "ht_capab": "[HT40+][SHORT-GI-40][DSS_CCK-40]",
179 "ieee80211n": "1",
180 "ieee80211ac": "1",
181 "vht_oper_chwidth": "1",
182 "vht_capab": "[MAX-MPDU-11454][RXLDPC][SHORT-GI-80][TX-STBC-2BY1][RX-STBC-1][MAX-A-MPDU-LEN-EXP0]",
183 "vht_oper_centr_freq_seg0_idx": "42",
184 "require_vht": "1"}
8b8a1864 185 hapd = hostapd.add_ap(apdev[0], params)
7cd0aa7e 186
145f35bf
JM
187 dev[1].connect("vht", key_mgmt="NONE", scan_freq="5180",
188 disable_vht="1", wait_connect=False)
7cd0aa7e 189 dev[0].connect("vht", key_mgmt="NONE", scan_freq="5180")
2e71d041
JM
190 dev[2].connect("vht", key_mgmt="NONE", scan_freq="5180",
191 disable_sgi="1")
145f35bf
JM
192 ev = dev[1].wait_event(["CTRL-EVENT-ASSOC-REJECT"])
193 if ev is None:
194 raise Exception("Association rejection timed out")
195 if "status_code=104" not in ev:
196 raise Exception("Unexpected rejection status code")
197 dev[1].request("DISCONNECT")
a8375c94 198 hwsim_utils.test_connectivity(dev[0], hapd)
2e71d041
JM
199 sta0 = hapd.get_sta(dev[0].own_addr())
200 sta2 = hapd.get_sta(dev[2].own_addr())
201 capab0 = int(sta0['vht_caps_info'], base=16)
202 capab2 = int(sta2['vht_caps_info'], base=16)
203 if capab0 & 0x60 == 0:
204 raise Exception("dev[0] did not support SGI")
205 if capab2 & 0x60 != 0:
206 raise Exception("dev[2] claimed support for SGI")
bab493b9 207 except Exception as e:
7cd0aa7e
JM
208 if isinstance(e, Exception) and str(e) == "AP startup failed":
209 if not vht_supported():
e246d7d5 210 raise HwsimSkip("80 MHz channel not supported in regulatory information")
7cd0aa7e
JM
211 raise
212 finally:
2e71d041 213 clear_regdom(hapd, dev, count=3)
ea7526bf 214
6849b3de
JM
215def test_ap_vht80_invalid(dev, apdev):
216 """VHT with invalid 80 MHz channel configuration (seg1)"""
217 try:
218 hapd = None
fab49f61
JM
219 params = {"ssid": "vht",
220 "country_code": "US",
221 "hw_mode": "a",
222 "channel": "36",
223 "ht_capab": "[HT40+]",
224 "ieee80211n": "1",
225 "ieee80211ac": "1",
226 "vht_oper_chwidth": "1",
227 "vht_oper_centr_freq_seg0_idx": "42",
228 "vht_oper_centr_freq_seg1_idx": "155",
229 'ieee80211d': '1',
230 'ieee80211h': '1'}
8b8a1864 231 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
6849b3de
JM
232 # This fails due to unexpected seg1 configuration
233 ev = hapd.wait_event(["AP-DISABLED"], timeout=5)
234 if ev is None:
235 raise Exception("AP-DISABLED not reported")
bab493b9 236 except Exception as e:
6849b3de
JM
237 if isinstance(e, Exception) and str(e) == "AP startup failed":
238 if not vht_supported():
239 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
240 raise
241 finally:
fa4a938f 242 clear_regdom(hapd, dev)
6849b3de
JM
243
244def test_ap_vht80_invalid2(dev, apdev):
245 """VHT with invalid 80 MHz channel configuration (seg0)"""
246 try:
247 hapd = None
fab49f61
JM
248 params = {"ssid": "vht",
249 "country_code": "US",
250 "hw_mode": "a",
251 "channel": "36",
252 "ht_capab": "[HT40+]",
253 "ieee80211n": "1",
254 "ieee80211ac": "1",
255 "vht_oper_chwidth": "1",
256 "vht_oper_centr_freq_seg0_idx": "46",
257 'ieee80211d': '1',
258 'ieee80211h': '1'}
8b8a1864 259 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
6849b3de
JM
260 # This fails due to invalid seg0 configuration
261 ev = hapd.wait_event(["AP-DISABLED"], timeout=5)
262 if ev is None:
263 raise Exception("AP-DISABLED not reported")
bab493b9 264 except Exception as e:
6849b3de
JM
265 if isinstance(e, Exception) and str(e) == "AP startup failed":
266 if not vht_supported():
267 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
268 raise
269 finally:
9ab2360f 270 clear_regdom(hapd, dev)
6849b3de 271
ea7526bf 272def test_ap_vht_20(devs, apdevs):
14637401 273 """VHT and 20 MHz channel"""
ea7526bf
JB
274 dev = devs[0]
275 ap = apdevs[0]
276 try:
9d7fdac5 277 hapd = None
fab49f61
JM
278 params = {"ssid": "test-vht20",
279 "country_code": "DE",
280 "hw_mode": "a",
281 "channel": "36",
282 "ieee80211n": "1",
283 "ieee80211ac": "1",
284 "ht_capab": "",
285 "vht_capab": "",
286 "vht_oper_chwidth": "0",
287 "vht_oper_centr_freq_seg0_idx": "0",
288 "supported_rates": "60 120 240 360 480 540",
289 "require_vht": "1"}
afc26df2 290 hapd = hostapd.add_ap(ap, params)
ea7526bf 291 dev.connect("test-vht20", scan_freq="5180", key_mgmt="NONE")
a8375c94 292 hwsim_utils.test_connectivity(dev, hapd)
ea7526bf 293 finally:
9d7fdac5 294 dev.request("DISCONNECT")
28a57450 295 clear_regdom(hapd, devs)
4466fe65
JM
296
297def test_ap_vht_40(devs, apdevs):
298 """VHT and 40 MHz channel"""
299 dev = devs[0]
300 ap = apdevs[0]
301 try:
302 hapd = None
fab49f61
JM
303 params = {"ssid": "test-vht40",
304 "country_code": "DE",
305 "hw_mode": "a",
306 "channel": "36",
307 "ieee80211n": "1",
308 "ieee80211ac": "1",
309 "ht_capab": "[HT40+]",
310 "vht_capab": "",
311 "vht_oper_chwidth": "0",
312 "vht_oper_centr_freq_seg0_idx": "0"}
afc26df2 313 hapd = hostapd.add_ap(ap, params)
4466fe65
JM
314 dev.connect("test-vht40", scan_freq="5180", key_mgmt="NONE")
315 hwsim_utils.test_connectivity(dev, hapd)
316 finally:
317 dev.request("DISCONNECT")
c29855d3 318 clear_regdom(hapd, devs)
6acecce1
JM
319
320def test_ap_vht_capab_not_supported(dev, apdev):
321 """VHT configuration with driver not supporting all vht_capab entries"""
322 try:
fab49f61
JM
323 params = {"ssid": "vht",
324 "country_code": "FI",
325 "hw_mode": "a",
326 "channel": "36",
327 "ht_capab": "[HT40+][SHORT-GI-40][DSS_CCK-40]",
328 "ieee80211n": "1",
329 "ieee80211ac": "1",
330 "vht_oper_chwidth": "1",
331 "vht_capab": "[MAX-MPDU-7991][MAX-MPDU-11454][VHT160][VHT160-80PLUS80][RXLDPC][SHORT-GI-80][SHORT-GI-160][TX-STBC-2BY1][RX-STBC-1][RX-STBC-12][RX-STBC-123][RX-STBC-1234][SU-BEAMFORMER][SU-BEAMFORMEE][BF-ANTENNA-2][BF-ANTENNA-3][BF-ANTENNA-4][SOUNDING-DIMENSION-2][SOUNDING-DIMENSION-3][SOUNDING-DIMENSION-4][MU-BEAMFORMER][VHT-TXOP-PS][HTC-VHT][MAX-A-MPDU-LEN-EXP0][MAX-A-MPDU-LEN-EXP7][VHT-LINK-ADAPT2][VHT-LINK-ADAPT3][RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]",
332 "vht_oper_centr_freq_seg0_idx": "42",
333 "require_vht": "1"}
8b8a1864 334 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
6acecce1
JM
335 ev = hapd.wait_event(["AP-DISABLED"], timeout=5)
336 if ev is None:
337 raise Exception("Startup failure not reported")
338 for i in range(1, 7):
339 if "OK" not in hapd.request("SET vht_capab [MAX-A-MPDU-LEN-EXP%d]" % i):
340 raise Exception("Unexpected SET failure")
341 finally:
f3df0054 342 clear_regdom(hapd, dev)
6259fd81
JM
343
344def test_ap_vht160(dev, apdev):
b9e8f920 345 """VHT with 160 MHz channel width (1)"""
6259fd81 346 try:
9d7fdac5 347 hapd = None
fab49f61
JM
348 params = {"ssid": "vht",
349 "country_code": "FI",
350 "hw_mode": "a",
351 "channel": "36",
352 "ht_capab": "[HT40+]",
353 "ieee80211n": "1",
354 "ieee80211ac": "1",
355 "vht_oper_chwidth": "2",
356 "vht_oper_centr_freq_seg0_idx": "50",
357 'ieee80211d': '1',
358 'ieee80211h': '1'}
8b8a1864 359 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
6259fd81
JM
360
361 ev = wait_dfs_event(hapd, "DFS-CAC-START", 5)
362 if "DFS-CAC-START" not in ev:
363 raise Exception("Unexpected DFS event")
364
365 state = hapd.get_status_field("state")
366 if state != "DFS":
367 if state == "DISABLED" and not os.path.exists("dfs"):
368 # Not all systems have recent enough CRDA version and
369 # wireless-regdb changes to support 160 MHz and DFS. For now,
370 # do not report failures for this test case.
81e787b7 371 raise HwsimSkip("CRDA or wireless-regdb did not support 160 MHz")
6259fd81
JM
372 raise Exception("Unexpected interface state: " + state)
373
b9e8f920
JM
374 logger.info("Waiting for CAC to complete")
375
376 ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 70)
377 if "success=1" not in ev:
378 raise Exception("CAC failed")
379 if "freq=5180" not in ev:
380 raise Exception("Unexpected DFS freq result")
381
382 ev = hapd.wait_event(["AP-ENABLED"], timeout=5)
383 if not ev:
384 raise Exception("AP setup timed out")
385
386 state = hapd.get_status_field("state")
387 if state != "ENABLED":
388 raise Exception("Unexpected interface state")
389
390 dev[0].connect("vht", key_mgmt="NONE", scan_freq="5180")
b586054f 391 dev[0].wait_regdom(country_ie=True)
b9e8f920
JM
392 hwsim_utils.test_connectivity(dev[0], hapd)
393 sig = dev[0].request("SIGNAL_POLL").splitlines()
394 if "FREQUENCY=5180" not in sig:
395 raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
396 if "WIDTH=160 MHz" not in sig:
397 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
bab493b9 398 except Exception as e:
b9e8f920
JM
399 if isinstance(e, Exception) and str(e) == "AP startup failed":
400 if not vht_supported():
401 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
402 raise
403 finally:
b9e8f920
JM
404 if hapd:
405 hapd.request("DISABLE")
e01a492c 406 dev[0].disconnect_and_stop_scan()
b9e8f920 407 subprocess.call(['iw', 'reg', 'set', '00'])
b586054f 408 dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5)
b9e8f920
JM
409 dev[0].flush_scan_cache()
410
411def test_ap_vht160b(dev, apdev):
412 """VHT with 160 MHz channel width (2)"""
413 try:
414 hapd = None
415
fab49f61
JM
416 params = {"ssid": "vht",
417 "country_code": "FI",
418 "hw_mode": "a",
419 "channel": "104",
420 "ht_capab": "[HT40-]",
421 "ieee80211n": "1",
422 "ieee80211ac": "1",
423 "vht_oper_chwidth": "2",
424 "vht_oper_centr_freq_seg0_idx": "114",
425 'ieee80211d': '1',
426 'ieee80211h': '1'}
b9e8f920 427 hapd = hostapd.add_ap(apdev[1], params, wait_enabled=False)
6259fd81 428
b9e8f920 429 ev = wait_dfs_event(hapd, "DFS-CAC-START", 5)
6259fd81
JM
430 if "DFS-CAC-START" not in ev:
431 raise Exception("Unexpected DFS event(2)")
432
b9e8f920 433 state = hapd.get_status_field("state")
6259fd81 434 if state != "DFS":
b9e8f920
JM
435 if state == "DISABLED" and not os.path.exists("dfs"):
436 # Not all systems have recent enough CRDA version and
437 # wireless-regdb changes to support 160 MHz and DFS. For now,
438 # do not report failures for this test case.
439 raise HwsimSkip("CRDA or wireless-regdb did not support 160 MHz")
440 raise Exception("Unexpected interface state: " + state)
6259fd81
JM
441
442 logger.info("Waiting for CAC to complete")
443
444 ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 70)
6259fd81
JM
445 if "success=1" not in ev:
446 raise Exception("CAC failed(2)")
24f4ad04 447 if "freq=5520" not in ev:
6259fd81
JM
448 raise Exception("Unexpected DFS freq result(2)")
449
b9e8f920 450 ev = hapd.wait_event(["AP-ENABLED"], timeout=5)
6259fd81
JM
451 if not ev:
452 raise Exception("AP setup timed out(2)")
453
b9e8f920 454 state = hapd.get_status_field("state")
6259fd81
JM
455 if state != "ENABLED":
456 raise Exception("Unexpected interface state(2)")
457
b9e8f920 458 freq = hapd.get_status_field("freq")
24f4ad04 459 if freq != "5520":
6259fd81
JM
460 raise Exception("Unexpected frequency(2)")
461
b9e8f920 462 dev[0].connect("vht", key_mgmt="NONE", scan_freq="5520")
b586054f 463 dev[0].wait_regdom(country_ie=True)
a8375c94 464 hwsim_utils.test_connectivity(dev[0], hapd)
c2bf6d3a 465 sig = dev[0].request("SIGNAL_POLL").splitlines()
24f4ad04 466 if "FREQUENCY=5520" not in sig:
c2bf6d3a
JM
467 raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
468 if "WIDTH=160 MHz" not in sig:
469 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
bab493b9 470 except Exception as e:
6259fd81
JM
471 if isinstance(e, Exception) and str(e) == "AP startup failed":
472 if not vht_supported():
81e787b7 473 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
6259fd81
JM
474 raise
475 finally:
9d7fdac5
JM
476 if hapd:
477 hapd.request("DISABLE")
e01a492c 478 dev[0].disconnect_and_stop_scan()
c4668009 479 subprocess.call(['iw', 'reg', 'set', '00'])
b586054f 480 dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5)
9d7fdac5 481 dev[0].flush_scan_cache()
74ed673f 482
90bef2c9
JM
483def test_ap_vht160_no_dfs_100_plus(dev, apdev):
484 """VHT with 160 MHz channel width and no DFS (100 plus)"""
485 run_ap_vht160_no_dfs(dev, apdev, "100", "[HT40+]")
486
a6cc1e57 487def test_ap_vht160_no_dfs(dev, apdev):
90bef2c9
JM
488 """VHT with 160 MHz channel width and no DFS (104 minus)"""
489 run_ap_vht160_no_dfs(dev, apdev, "104", "[HT40-]")
490
491def test_ap_vht160_no_dfs_108_plus(dev, apdev):
492 """VHT with 160 MHz channel width and no DFS (108 plus)"""
493 run_ap_vht160_no_dfs(dev, apdev, "108", "[HT40+]")
494
495def test_ap_vht160_no_dfs_112_minus(dev, apdev):
496 """VHT with 160 MHz channel width and no DFS (112 minus)"""
497 run_ap_vht160_no_dfs(dev, apdev, "112", "[HT40-]")
498
499def test_ap_vht160_no_dfs_116_plus(dev, apdev):
500 """VHT with 160 MHz channel width and no DFS (116 plus)"""
501 run_ap_vht160_no_dfs(dev, apdev, "116", "[HT40+]")
502
503def test_ap_vht160_no_dfs_120_minus(dev, apdev):
504 """VHT with 160 MHz channel width and no DFS (120 minus)"""
505 run_ap_vht160_no_dfs(dev, apdev, "120", "[HT40-]")
506
507def test_ap_vht160_no_dfs_124_plus(dev, apdev):
508 """VHT with 160 MHz channel width and no DFS (124 plus)"""
509 run_ap_vht160_no_dfs(dev, apdev, "124", "[HT40+]")
510
511def test_ap_vht160_no_dfs_128_minus(dev, apdev):
512 """VHT with 160 MHz channel width and no DFS (128 minus)"""
513 run_ap_vht160_no_dfs(dev, apdev, "128", "[HT40-]")
514
515def run_ap_vht160_no_dfs(dev, apdev, channel, ht_capab):
a6cc1e57
JM
516 try:
517 hapd = None
fab49f61
JM
518 params = {"ssid": "vht",
519 "country_code": "ZA",
520 "hw_mode": "a",
521 "channel": channel,
522 "ht_capab": ht_capab,
523 "ieee80211n": "1",
524 "ieee80211ac": "1",
525 "vht_oper_chwidth": "2",
526 "vht_oper_centr_freq_seg0_idx": "114",
527 'ieee80211d': '1',
528 'ieee80211h': '1'}
8b8a1864 529 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
a6cc1e57
JM
530 ev = hapd.wait_event(["AP-ENABLED"], timeout=2)
531 if not ev:
532 cmd = subprocess.Popen(["iw", "reg", "get"], stdout=subprocess.PIPE)
533 reg = cmd.stdout.readlines()
534 for r in reg:
535 if "5490" in r and "DFS" in r:
536 raise HwsimSkip("ZA regulatory rule did not have DFS requirement removed")
537 raise Exception("AP setup timed out")
538
90bef2c9
JM
539 freq = str(int(channel) * 5 + 5000)
540 dev[0].connect("vht", key_mgmt="NONE", scan_freq=freq)
b586054f 541 dev[0].wait_regdom(country_ie=True)
a6cc1e57
JM
542 hwsim_utils.test_connectivity(dev[0], hapd)
543 sig = dev[0].request("SIGNAL_POLL").splitlines()
90bef2c9 544 if "FREQUENCY=" + freq not in sig:
a6cc1e57
JM
545 raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
546 if "WIDTH=160 MHz" not in sig:
547 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
bab493b9 548 except Exception as e:
a6cc1e57
JM
549 if isinstance(e, Exception) and str(e) == "AP startup failed":
550 if not vht_supported():
551 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
552 raise
553 finally:
9cff5c32 554 clear_regdom(hapd, dev)
a6cc1e57 555
b6437fa5
JM
556def test_ap_vht160_no_ht40(dev, apdev):
557 """VHT with 160 MHz channel width and HT40 disabled"""
558 try:
559 hapd = None
fab49f61
JM
560 params = {"ssid": "vht",
561 "country_code": "ZA",
562 "hw_mode": "a",
563 "channel": "108",
564 "ht_capab": "",
565 "ieee80211n": "1",
566 "ieee80211ac": "1",
567 "vht_oper_chwidth": "2",
568 "vht_oper_centr_freq_seg0_idx": "114",
569 'ieee80211d': '1',
570 'ieee80211h': '1'}
b6437fa5
JM
571 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
572 ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=2)
573 if not ev:
574 cmd = subprocess.Popen(["iw", "reg", "get"], stdout=subprocess.PIPE)
575 reg = cmd.stdout.readlines()
576 for r in reg:
577 if "5490" in r and "DFS" in r:
578 raise HwsimSkip("ZA regulatory rule did not have DFS requirement removed")
579 raise Exception("AP setup timed out")
580 if "AP-ENABLED" in ev:
581 # This was supposed to fail due to sec_channel_offset == 0
582 raise Exception("Unexpected AP-ENABLED")
bab493b9 583 except Exception as e:
b6437fa5
JM
584 if isinstance(e, Exception) and str(e) == "AP startup failed":
585 if not vht_supported():
586 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
587 raise
588 finally:
411b9e01 589 clear_regdom(hapd, dev)
b6437fa5 590
74ed673f
JM
591def test_ap_vht80plus80(dev, apdev):
592 """VHT with 80+80 MHz channel width"""
593 try:
9d7fdac5
JM
594 hapd = None
595 hapd2 = None
fab49f61
JM
596 params = {"ssid": "vht",
597 "country_code": "US",
598 "hw_mode": "a",
599 "channel": "52",
600 "ht_capab": "[HT40+]",
601 "ieee80211n": "1",
602 "ieee80211ac": "1",
603 "vht_oper_chwidth": "3",
604 "vht_oper_centr_freq_seg0_idx": "58",
605 "vht_oper_centr_freq_seg1_idx": "155",
606 'ieee80211d': '1',
607 'ieee80211h': '1'}
8b8a1864 608 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
74ed673f
JM
609 # This will actually fail since DFS on 80+80 is not yet supported
610 ev = hapd.wait_event(["AP-DISABLED"], timeout=5)
611 # ignore result to avoid breaking the test once 80+80 DFS gets enabled
612
fab49f61
JM
613 params = {"ssid": "vht2",
614 "country_code": "US",
615 "hw_mode": "a",
616 "channel": "36",
617 "ht_capab": "[HT40+]",
618 "ieee80211n": "1",
619 "ieee80211ac": "1",
620 "vht_oper_chwidth": "3",
621 "vht_oper_centr_freq_seg0_idx": "42",
622 "vht_oper_centr_freq_seg1_idx": "155"}
8b8a1864 623 hapd2 = hostapd.add_ap(apdev[1], params, wait_enabled=False)
74ed673f 624
e246d7d5 625 ev = hapd2.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=5)
74ed673f
JM
626 if not ev:
627 raise Exception("AP setup timed out(2)")
e246d7d5
JM
628 if "AP-DISABLED" in ev:
629 # Assume this failed due to missing regulatory update for now
630 raise HwsimSkip("80+80 MHz channel not supported in regulatory information")
74ed673f
JM
631
632 state = hapd2.get_status_field("state")
633 if state != "ENABLED":
634 raise Exception("Unexpected interface state(2)")
635
636 dev[1].connect("vht2", key_mgmt="NONE", scan_freq="5180")
a8375c94 637 hwsim_utils.test_connectivity(dev[1], hapd2)
c2bf6d3a
JM
638 sig = dev[1].request("SIGNAL_POLL").splitlines()
639 if "FREQUENCY=5180" not in sig:
640 raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
641 if "WIDTH=80+80 MHz" not in sig:
642 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
643 if "CENTER_FRQ1=5210" not in sig:
644 raise Exception("Unexpected SIGNAL_POLL value(3): " + str(sig))
645 if "CENTER_FRQ2=5775" not in sig:
646 raise Exception("Unexpected SIGNAL_POLL value(4): " + str(sig))
bab493b9 647 except Exception as e:
74ed673f
JM
648 if isinstance(e, Exception) and str(e) == "AP startup failed":
649 if not vht_supported():
81e787b7 650 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
74ed673f
JM
651 raise
652 finally:
9d7fdac5
JM
653 dev[0].request("DISCONNECT")
654 dev[1].request("DISCONNECT")
655 if hapd:
656 hapd.request("DISABLE")
657 if hapd2:
658 hapd2.request("DISABLE")
c4668009 659 subprocess.call(['iw', 'reg', 'set', '00'])
9d7fdac5
JM
660 dev[0].flush_scan_cache()
661 dev[1].flush_scan_cache()
d4792c0c 662
6849b3de
JM
663def test_ap_vht80plus80_invalid(dev, apdev):
664 """VHT with invalid 80+80 MHz channel"""
665 try:
666 hapd = None
fab49f61
JM
667 params = {"ssid": "vht",
668 "country_code": "US",
669 "hw_mode": "a",
670 "channel": "36",
671 "ht_capab": "[HT40+]",
672 "ieee80211n": "1",
673 "ieee80211ac": "1",
674 "vht_oper_chwidth": "3",
675 "vht_oper_centr_freq_seg0_idx": "42",
676 "vht_oper_centr_freq_seg1_idx": "0",
677 'ieee80211d': '1',
678 'ieee80211h': '1'}
8b8a1864 679 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
6849b3de
JM
680 # This fails due to missing(invalid) seg1 configuration
681 ev = hapd.wait_event(["AP-DISABLED"], timeout=5)
682 if ev is None:
683 raise Exception("AP-DISABLED not reported")
bab493b9 684 except Exception as e:
6849b3de
JM
685 if isinstance(e, Exception) and str(e) == "AP startup failed":
686 if not vht_supported():
687 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
688 raise
689 finally:
c3aa6e27 690 clear_regdom(hapd, dev)
6849b3de 691
d4792c0c
JM
692def test_ap_vht80_csa(dev, apdev):
693 """VHT with 80 MHz channel width and CSA"""
81e787b7 694 csa_supported(dev[0])
d4792c0c 695 try:
9d7fdac5 696 hapd = None
fab49f61
JM
697 params = {"ssid": "vht",
698 "country_code": "US",
699 "hw_mode": "a",
700 "channel": "149",
701 "ht_capab": "[HT40+]",
702 "ieee80211n": "1",
703 "ieee80211ac": "1",
704 "vht_oper_chwidth": "1",
705 "vht_oper_centr_freq_seg0_idx": "155"}
8b8a1864 706 hapd = hostapd.add_ap(apdev[0], params)
d4792c0c
JM
707
708 dev[0].connect("vht", key_mgmt="NONE", scan_freq="5745")
709 hwsim_utils.test_connectivity(dev[0], hapd)
710
711 hapd.request("CHAN_SWITCH 5 5180 ht vht blocktx center_freq1=5210 sec_channel_offset=1 bandwidth=80")
64c20a83
JM
712 ev = hapd.wait_event(["CTRL-EVENT-STARTED-CHANNEL-SWITCH"], timeout=10)
713 if ev is None:
714 raise Exception("Channel switch start event not seen")
715 if "freq=5180" not in ev:
716 raise Exception("Unexpected channel in CS started")
717 ev = hapd.wait_event(["CTRL-EVENT-CHANNEL-SWITCH"], timeout=10)
718 if ev is None:
719 raise Exception("Channel switch completion event not seen")
720 if "freq=5180" not in ev:
721 raise Exception("Unexpected channel in CS completed")
d4792c0c
JM
722 ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
723 if ev is None:
724 raise Exception("CSA finished event timed out")
725 if "freq=5180" not in ev:
726 raise Exception("Unexpected channel in CSA finished event")
727 time.sleep(0.5)
728 hwsim_utils.test_connectivity(dev[0], hapd)
729
730 hapd.request("CHAN_SWITCH 5 5745")
731 ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
732 if ev is None:
733 raise Exception("CSA finished event timed out")
734 if "freq=5745" not in ev:
735 raise Exception("Unexpected channel in CSA finished event")
736 time.sleep(0.5)
737 hwsim_utils.test_connectivity(dev[0], hapd)
738
739 # This CSA to same channel will fail in kernel, so use this only for
740 # extra code coverage.
741 hapd.request("CHAN_SWITCH 5 5745")
742 hapd.wait_event(["AP-CSA-FINISHED"], timeout=1)
bab493b9 743 except Exception as e:
d4792c0c
JM
744 if isinstance(e, Exception) and str(e) == "AP startup failed":
745 if not vht_supported():
81e787b7 746 raise HwsimSkip("80 MHz channel not supported in regulatory information")
d4792c0c
JM
747 raise
748 finally:
9d7fdac5 749 dev[0].request("DISCONNECT")
fec2aea7 750 clear_regdom(hapd, dev)
496c4e45 751
27fa1161
JM
752def test_ap_vht_csa_vht40(dev, apdev):
753 """VHT CSA with VHT40 getting enabled"""
754 csa_supported(dev[0])
755 try:
756 hapd = None
fab49f61
JM
757 params = {"ssid": "vht",
758 "country_code": "US",
759 "hw_mode": "a",
760 "channel": "149",
761 "ht_capab": "[HT40+]",
762 "ieee80211n": "1",
763 "ieee80211ac": "0"}
27fa1161
JM
764 hapd = hostapd.add_ap(apdev[0], params)
765 bssid = hapd.own_addr()
766
767 dev[0].connect("vht", key_mgmt="NONE", scan_freq="5745")
768 hwsim_utils.test_connectivity(dev[0], hapd)
769
7b1adf2c 770 hapd.request("CHAN_SWITCH 5 5765 sec_channel_offset=-1 center_freq1=5755 bandwidth=40 vht")
27fa1161
JM
771 ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
772 if ev is None:
773 raise Exception("CSA finished event timed out")
774 if "freq=5765" not in ev:
775 raise Exception("Unexpected channel in CSA finished event")
12c5c240 776 ev = dev[0].wait_event(["CTRL-EVENT-CHANNEL-SWITCH"], timeout=5)
27fa1161
JM
777 if ev is None:
778 raise Exception("Channel switch event not seen")
779 if "freq=5765" not in ev:
780 raise Exception("Channel mismatch: " + ev)
ad369d77
JM
781 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
782 if ev is not None:
783 raise Exception("Unexpected disconnection event from station")
27fa1161
JM
784 hwsim_utils.test_connectivity(dev[0], hapd)
785
786 dev[1].connect("vht", key_mgmt="NONE", scan_freq="5765")
787 hwsim_utils.test_connectivity(dev[1], hapd)
788
789 if dev[1].get_status_field("ieee80211ac") != '1':
790 raise Exception("VHT not enabled as part of channel switch")
791 finally:
792 dev[0].request("DISCONNECT")
793 dev[1].request("DISCONNECT")
794 if hapd:
795 hapd.request("DISABLE")
796 subprocess.call(['iw', 'reg', 'set', '00'])
797 dev[0].flush_scan_cache()
798 dev[1].flush_scan_cache()
799
800def test_ap_vht_csa_vht20(dev, apdev):
801 """VHT CSA with VHT20 getting enabled"""
802 csa_supported(dev[0])
803 try:
804 hapd = None
fab49f61
JM
805 params = {"ssid": "vht",
806 "country_code": "US",
807 "hw_mode": "a",
808 "channel": "149",
809 "ht_capab": "[HT40+]",
810 "ieee80211n": "1",
811 "ieee80211ac": "0"}
27fa1161
JM
812 hapd = hostapd.add_ap(apdev[0], params)
813 bssid = hapd.own_addr()
814
815 dev[0].connect("vht", key_mgmt="NONE", scan_freq="5745")
816 hwsim_utils.test_connectivity(dev[0], hapd)
817
818 hapd.request("CHAN_SWITCH 5 5200 center_freq1=5200 bandwidth=20 vht")
819 ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
820 if ev is None:
821 raise Exception("CSA finished event timed out")
822 if "freq=5200" not in ev:
823 raise Exception("Unexpected channel in CSA finished event")
824 time.sleep(0.5)
825 hwsim_utils.test_connectivity(dev[0], hapd)
826
827 dev[1].connect("vht", key_mgmt="NONE", scan_freq="5200")
828 hwsim_utils.test_connectivity(dev[1], hapd)
829
830 if dev[1].get_status_field("ieee80211ac") != '1':
831 raise Exception("VHT not enabled as part of channel switch")
832 finally:
833 dev[0].request("DISCONNECT")
834 dev[1].request("DISCONNECT")
835 if hapd:
836 hapd.request("DISABLE")
837 subprocess.call(['iw', 'reg', 'set', '00'])
838 dev[0].flush_scan_cache()
839 dev[1].flush_scan_cache()
840
841def test_ap_vht_csa_vht40_disable(dev, apdev):
842 """VHT CSA with VHT40 getting disabled"""
843 csa_supported(dev[0])
844 try:
845 hapd = None
fab49f61
JM
846 params = {"ssid": "vht",
847 "country_code": "US",
848 "hw_mode": "a",
849 "channel": "149",
850 "ht_capab": "[HT40+]",
851 "ieee80211n": "1",
852 "ieee80211ac": "1",
853 "vht_capab": "",
854 "vht_oper_chwidth": "0",
855 "vht_oper_centr_freq_seg0_idx": "0"}
27fa1161
JM
856 hapd = hostapd.add_ap(apdev[0], params)
857 bssid = hapd.own_addr()
858
859 dev[0].connect("vht", key_mgmt="NONE", scan_freq="5745")
860 hwsim_utils.test_connectivity(dev[0], hapd)
861
862 hapd.request("CHAN_SWITCH 5 5200 center_freq1=5200 bandwidth=40 ht")
863 ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10)
864 if ev is None:
865 raise Exception("CSA finished event timed out")
866 if "freq=5200" not in ev:
867 raise Exception("Unexpected channel in CSA finished event")
79b44113 868 ev = dev[0].wait_event(["CTRL-EVENT-CHANNEL-SWITCH"], timeout=5)
27fa1161
JM
869 if ev is None:
870 raise Exception("Channel switch event not seen")
871 if "freq=5200" not in ev:
872 raise Exception("Channel mismatch: " + ev)
873 time.sleep(0.5)
874 hwsim_utils.test_connectivity(dev[0], hapd)
875
876 dev[1].connect("vht", key_mgmt="NONE", scan_freq="5200")
877 hwsim_utils.test_connectivity(dev[1], hapd)
878
879 if dev[1].get_status_field("ieee80211ac") == '1':
880 raise Exception("VHT not disabled as part of channel switch")
881 finally:
882 dev[0].request("DISCONNECT")
883 dev[1].request("DISCONNECT")
884 if hapd:
885 hapd.request("DISABLE")
886 subprocess.call(['iw', 'reg', 'set', '00'])
887 dev[0].flush_scan_cache()
888 dev[1].flush_scan_cache()
889
496c4e45
JM
890def test_ap_vht_on_24ghz(dev, apdev):
891 """Subset of VHT features on 2.4 GHz"""
892 hapd = None
fab49f61
JM
893 params = {"ssid": "test-vht-2g",
894 "hw_mode": "g",
895 "channel": "1",
896 "ieee80211n": "1",
897 "vendor_vht": "1",
898 "vht_capab": "[MAX-MPDU-11454]",
899 "vht_oper_chwidth": "0",
900 "vht_oper_centr_freq_seg0_idx": "1"}
8b8a1864 901 hapd = hostapd.add_ap(apdev[0], params)
496c4e45
JM
902 try:
903 if "OK" not in dev[0].request("VENDOR_ELEM_ADD 13 dd1300904c0400bf0c3240820feaff0000eaff0000"):
904 raise Exception("Failed to add vendor element")
905 dev[0].connect("test-vht-2g", scan_freq="2412", key_mgmt="NONE")
906 hwsim_utils.test_connectivity(dev[0], hapd)
907 sta = hapd.get_sta(dev[0].own_addr())
908 if '[VENDOR_VHT]' not in sta['flags']:
909 raise Exception("No VENDOR_VHT STA flag")
910
911 dev[1].connect("test-vht-2g", scan_freq="2412", key_mgmt="NONE")
912 sta = hapd.get_sta(dev[1].own_addr())
913 if '[VENDOR_VHT]' in sta['flags']:
914 raise Exception("Unexpected VENDOR_VHT STA flag")
915 finally:
916 dev[0].request("VENDOR_ELEM_REMOVE 13 *")
528a7d22
JM
917
918def test_prefer_vht40(dev, apdev):
919 """Preference on VHT40 over HT40"""
920 try:
921 hapd2 = None
922
fab49f61
JM
923 params = {"ssid": "test",
924 "country_code": "FI",
925 "hw_mode": "a",
926 "channel": "36",
927 "ieee80211n": "1",
928 "ht_capab": "[HT40+]"}
8b8a1864 929 hapd = hostapd.add_ap(apdev[0], params)
528a7d22
JM
930 bssid = apdev[0]['bssid']
931
fab49f61
JM
932 params = {"ssid": "test",
933 "country_code": "FI",
934 "hw_mode": "a",
935 "channel": "36",
936 "ieee80211n": "1",
937 "ieee80211ac": "1",
938 "ht_capab": "[HT40+]",
939 "vht_capab": "",
940 "vht_oper_chwidth": "0",
941 "vht_oper_centr_freq_seg0_idx": "0"}
8b8a1864 942 hapd2 = hostapd.add_ap(apdev[1], params)
528a7d22
JM
943 bssid2 = apdev[1]['bssid']
944
945 dev[0].scan_for_bss(bssid, freq=5180)
946 dev[0].scan_for_bss(bssid2, freq=5180)
947 dev[0].connect("test", scan_freq="5180", key_mgmt="NONE")
948 if dev[0].get_status_field('bssid') != bssid2:
949 raise Exception("Unexpected BSS selected")
950
951 est = dev[0].get_bss(bssid)['est_throughput']
952 if est != "135000":
953 raise Exception("Unexpected BSS0 est_throughput: " + est)
954
955 est = dev[0].get_bss(bssid2)['est_throughput']
956 if est != "135001":
957 raise Exception("Unexpected BSS1 est_throughput: " + est)
958 finally:
959 dev[0].request("DISCONNECT")
77e16aac
MH
960 disable_hapd(hapd)
961 disable_hapd(hapd2)
962 clear_regdom_dev(dev)
39605857
JM
963
964def test_ap_vht80_pwr_constraint(dev, apdev):
965 """VHT with 80 MHz channel width and local power constraint"""
966 hapd = None
967 try:
fab49f61
JM
968 params = {"ssid": "vht",
969 "country_code": "FI",
970 "hw_mode": "a",
971 "channel": "36",
972 "ht_capab": "[HT40+]",
973 "ieee80211d": "1",
974 "local_pwr_constraint": "3",
975 "ieee80211n": "1",
976 "ieee80211ac": "1",
977 "vht_oper_chwidth": "1",
978 "vht_oper_centr_freq_seg0_idx": "42"}
8b8a1864 979 hapd = hostapd.add_ap(apdev[0], params)
39605857
JM
980
981 dev[0].connect("vht", key_mgmt="NONE", scan_freq="5180")
b586054f 982 dev[0].wait_regdom(country_ie=True)
bab493b9 983 except Exception as e:
39605857
JM
984 if isinstance(e, Exception) and str(e) == "AP startup failed":
985 if not vht_supported():
986 raise HwsimSkip("80 MHz channel not supported in regulatory information")
987 raise
988 finally:
39605857
JM
989 if hapd:
990 hapd.request("DISABLE")
e01a492c 991 dev[0].disconnect_and_stop_scan()
39605857 992 subprocess.call(['iw', 'reg', 'set', '00'])
b586054f 993 dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5)
39605857 994 dev[0].flush_scan_cache()
ff229935
JM
995
996def test_ap_vht_use_sta_nsts(dev, apdev):
997 """VHT with 80 MHz channel width and use_sta_nsts=1"""
998 try:
999 hapd = None
fab49f61
JM
1000 params = {"ssid": "vht",
1001 "country_code": "FI",
1002 "hw_mode": "a",
1003 "channel": "36",
1004 "ht_capab": "[HT40+]",
1005 "ieee80211n": "1",
1006 "ieee80211ac": "1",
1007 "vht_oper_chwidth": "1",
1008 "vht_oper_centr_freq_seg0_idx": "42",
1009 "use_sta_nsts": "1"}
ff229935
JM
1010 hapd = hostapd.add_ap(apdev[0], params)
1011 bssid = apdev[0]['bssid']
1012
1013 dev[0].connect("vht", key_mgmt="NONE", scan_freq="5180")
1014 hwsim_utils.test_connectivity(dev[0], hapd)
bab493b9 1015 except Exception as e:
ff229935
JM
1016 if isinstance(e, Exception) and str(e) == "AP startup failed":
1017 if not vht_supported():
1018 raise HwsimSkip("80 MHz channel not supported in regulatory information")
1019 raise
1020 finally:
6749c675 1021 clear_regdom(hapd, dev)
ab62d2e5
JM
1022
1023def test_ap_vht_tkip(dev, apdev):
1024 """VHT and TKIP"""
1025 try:
1026 hapd = None
fab49f61
JM
1027 params = {"ssid": "vht",
1028 "wpa": "1",
1029 "wpa_key_mgmt": "WPA-PSK",
1030 "wpa_pairwise": "TKIP",
1031 "wpa_passphrase": "12345678",
1032 "country_code": "FI",
1033 "hw_mode": "a",
1034 "channel": "36",
1035 "ht_capab": "[HT40+]",
1036 "ieee80211n": "1",
1037 "ieee80211ac": "1",
1038 "vht_oper_chwidth": "1",
1039 "vht_oper_centr_freq_seg0_idx": "42"}
ab62d2e5
JM
1040 hapd = hostapd.add_ap(apdev[0], params)
1041 bssid = apdev[0]['bssid']
1042
1043 dev[0].connect("vht", psk="12345678", scan_freq="5180")
1044 hwsim_utils.test_connectivity(dev[0], hapd)
1045 sig = dev[0].request("SIGNAL_POLL").splitlines()
1046 if "FREQUENCY=5180" not in sig:
1047 raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
1048 if "WIDTH=20 MHz (no HT)" not in sig:
1049 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
1050 status = hapd.get_status()
1051 logger.info("hostapd STATUS: " + str(status))
1052 if status["ieee80211n"] != "0":
1053 raise Exception("Unexpected STATUS ieee80211n value")
1054 if status["ieee80211ac"] != "0":
1055 raise Exception("Unexpected STATUS ieee80211ac value")
1056 if status["secondary_channel"] != "0":
1057 raise Exception("Unexpected STATUS secondary_channel value")
bab493b9 1058 except Exception as e:
ab62d2e5
JM
1059 if isinstance(e, Exception) and str(e) == "AP startup failed":
1060 if not vht_supported():
1061 raise HwsimSkip("80 MHz channel not supported in regulatory information")
1062 raise
1063 finally:
1064 dev[0].request("DISCONNECT")
4ab1ac90 1065 clear_regdom(hapd, dev)
f366ff24
JM
1066
1067def test_ap_vht_40_fallback_to_20(devs, apdevs):
1068 """VHT and 40 MHz channel configuration falling back to 20 MHz"""
1069 dev = devs[0]
1070 ap = apdevs[0]
1071 try:
1072 hapd = None
fab49f61
JM
1073 params = {"ssid": "test-vht40",
1074 "country_code": "US",
1075 "hw_mode": "a",
1076 "basic_rates": "60 120 240",
1077 "channel": "161",
1078 "ieee80211d": "1",
1079 "ieee80211h": "1",
1080 "ieee80211n": "1",
1081 "ieee80211ac": "1",
1082 "ht_capab": "[HT40+][SHORT-GI-20][SHORT-GI-40][DSSS_CCK-40]",
1083 "vht_capab": "[RXLDPC][SHORT-GI-80][TX-STBC-2BY1][RX-STBC1][MAX-MPDU-11454][MAX-A-MPDU-LEN-EXP7]",
1084 "vht_oper_chwidth": "0",
1085 "vht_oper_centr_freq_seg0_idx": "155"}
f366ff24
JM
1086 hapd = hostapd.add_ap(ap, params)
1087 dev.connect("test-vht40", scan_freq="5805", key_mgmt="NONE")
b586054f 1088 dev.wait_regdom(country_ie=True)
f366ff24
JM
1089 hwsim_utils.test_connectivity(dev, hapd)
1090 finally:
44cc7df6 1091 clear_regdom(hapd, devs)
30a67736
JM
1092
1093def test_ap_vht80_to_24g_ht(dev, apdev):
1094 """VHT with 80 MHz channel width reconfigured to 2.4 GHz HT"""
1095 try:
1096 hapd = None
fab49f61
JM
1097 params = {"ssid": "vht",
1098 "country_code": "FI",
1099 "hw_mode": "a",
1100 "channel": "36",
1101 "ht_capab": "[HT40+]",
1102 "ieee80211n": "1",
1103 "ieee80211ac": "1",
1104 "vht_oper_chwidth": "1",
1105 "vht_capab": "[MAX-MPDU-11454]",
1106 "vht_oper_centr_freq_seg0_idx": "42"}
30a67736
JM
1107 hapd = hostapd.add_ap(apdev[0], params)
1108 bssid = apdev[0]['bssid']
1109
1110 hapd.disable()
1111 hapd.set("ieee80211ac", "0")
1112 hapd.set("hw_mode", "g")
1113 hapd.set("channel", "1")
1114 hapd.set("ht_capab", "")
1115 hapd.set("vht_capab", "")
1116 hapd.enable()
1117
1118 dev[0].connect("vht", key_mgmt="NONE", scan_freq="2412")
bab493b9 1119 except Exception as e:
30a67736
JM
1120 if isinstance(e, Exception) and str(e) == "AP startup failed":
1121 if not vht_supported():
1122 raise HwsimSkip("80 MHz channel not supported in regulatory information")
1123 raise
1124 finally:
1125 dev[0].request("DISCONNECT")
b57d883c 1126 clear_regdom(hapd, dev)