blob: 16f32cf75c25de5ebe409d52f57ed4cd4d0fef70 [file] [log] [blame]
developer66e89bc2024-04-23 14:50:01 +08001From 5a471a9025d9bf2a871339f5306e5c9050357703 Mon Sep 17 00:00:00 2001
2From: Michael-CY Lee <michael-cy.lee@mediatek.com>
3Date: Mon, 29 Jan 2024 10:26:53 +0800
4Subject: [PATCH 077/104] Revert ACS upstream changes
5
6- 348c047af ACS: More consistent checking of the best channel pointer
7- 98f3bd26d ACS: Extend the 320 MHz support
8- 733de8568 ACS: Fix not selecting the best channel in the segment
9- dc57ede01 tests: Full validation of ACS selecting HT40- channel
10- 4881accbb ACS: Add HT40- support in the 2.4 GHz band
11- 29f38ebcf ACS: Check whether iface->current_mode is NULL before use
12- 6f014c0d0 ACS: Add 320 MHz support for EHT
13
14Note that "e6f2494c3 hostapd: Add eht_bw320_offset configuration option"
15is not reverted due to conflict.
16---
17 src/ap/acs.c | 160 +++++++++----------------------------
18 tests/hwsim/test_ap_acs.py | 19 ++---
19 2 files changed, 41 insertions(+), 138 deletions(-)
20
21diff --git a/src/ap/acs.c b/src/ap/acs.c
22index cb4db7147..cfa4a7d27 100644
23--- a/src/ap/acs.c
24+++ b/src/ap/acs.c
25@@ -245,8 +245,6 @@ enum bw_type {
26 ACS_BW40,
27 ACS_BW80,
28 ACS_BW160,
29- ACS_BW320_1,
30- ACS_BW320_2,
31 };
32
33 struct bw_item {
34@@ -288,20 +286,10 @@ static const struct bw_item bw_160[] = {
35 { 6435, 6575, 111 }, { 6595, 6735, 143 },
36 { 6755, 6895, 175 }, { 6915, 7055, 207 }, { -1, -1, -1 }
37 };
38-static const struct bw_item bw_320_1[] = {
39- { 5955, 6255, 31 }, { 6275, 6575, 95 }, { 6595, 6895, 159 },
40- { -1, -1, -1 }
41-};
42-static const struct bw_item bw_320_2[] = {
43- { 6115, 6415, 63 }, { 6435, 6735, 127 }, { 6755, 7055, 191 },
44- { -1, -1, -1 }
45-};
46 static const struct bw_item *bw_desc[] = {
47 [ACS_BW40] = bw_40,
48 [ACS_BW80] = bw_80,
49 [ACS_BW160] = bw_160,
50- [ACS_BW320_1] = bw_320_1,
51- [ACS_BW320_2] = bw_320_2,
52 };
53
54
55@@ -773,42 +761,6 @@ static void acs_update_puncturing_bitmap(struct hostapd_iface *iface,
56 #endif /* CONFIG_IEEE80211BE */
57
58
59-static bool
60-acs_usable_bw320_chan(struct hostapd_iface *iface,
61- struct hostapd_channel_data *chan, int *bw320_offset)
62-{
63- const char *bw320_str[] = { "320 MHz", "320 MHz-1", "320 MHz-2" };
64- int conf_bw320_offset = hostapd_get_bw320_offset(iface->conf);
65-
66- *bw320_offset = 0;
67- switch (conf_bw320_offset) {
68- case 1:
69- if (acs_usable_bw_chan(chan, ACS_BW320_1))
70- *bw320_offset = 1;
71- break;
72- case 2:
73- if (acs_usable_bw_chan(chan, ACS_BW320_2))
74- *bw320_offset = 2;
75- break;
76- case 0:
77- default:
78- conf_bw320_offset = 0;
79- if (acs_usable_bw_chan(chan, ACS_BW320_1))
80- *bw320_offset = 1;
81- else if (acs_usable_bw_chan(chan, ACS_BW320_2))
82- *bw320_offset = 2;
83- break;
84- }
85-
86- if (!*bw320_offset)
87- wpa_printf(MSG_DEBUG,
88- "ACS: Channel %d: not allowed as primary channel for %s bandwidth",
89- chan->chan, bw320_str[conf_bw320_offset]);
90-
91- return *bw320_offset != 0;
92-}
93-
94-
95 static void
96 acs_find_ideal_chan_mode(struct hostapd_iface *iface,
97 struct hostapd_hw_modes *mode,
98@@ -820,18 +772,14 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
99 struct hostapd_channel_data *chan, *adj_chan = NULL, *best;
100 long double factor;
101 int i, j;
102- int bw320_offset = 0, ideal_bw320_offset = 0;
103 unsigned int k;
104- int secondary_channel = 1, freq_offset;
105-
106- if (is_24ghz_mode(mode->mode))
107- secondary_channel = iface->conf->secondary_channel;
108
109 for (i = 0; i < mode->num_channels; i++) {
110- double total_weight = 0;
111+ double total_weight;
112 struct acs_bias *bias, tmp_bias;
113+ bool update_best = true;
114
115- chan = &mode->channels[i];
116+ best = chan = &mode->channels[i];
117
118 /* Since in the current ACS implementation the first channel is
119 * always a primary channel, skip channels not available as
120@@ -863,7 +811,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
121 iface->conf->country[2] == 0x4f)
122 continue;
123
124- if (!chan_bw_allowed(chan, bw, secondary_channel != -1, 1)) {
125+ if (!chan_bw_allowed(chan, bw, 1, 1)) {
126 wpa_printf(MSG_DEBUG,
127 "ACS: Channel %d: BW %u is not supported",
128 chan->chan, bw);
129@@ -884,8 +832,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
130 }
131
132 if (mode->mode == HOSTAPD_MODE_IEEE80211A &&
133- (iface->conf->ieee80211ac || iface->conf->ieee80211ax ||
134- iface->conf->ieee80211be)) {
135+ (iface->conf->ieee80211ac || iface->conf->ieee80211ax)) {
136 if (hostapd_get_oper_chwidth(iface->conf) ==
137 CONF_OPER_CHWIDTH_80MHZ &&
138 !acs_usable_bw_chan(chan, ACS_BW80)) {
139@@ -905,25 +852,13 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
140 }
141 }
142
143- if (mode->mode == HOSTAPD_MODE_IEEE80211A &&
144- iface->conf->ieee80211be) {
145- if (hostapd_get_oper_chwidth(iface->conf) ==
146- CONF_OPER_CHWIDTH_320MHZ &&
147- !acs_usable_bw320_chan(iface, chan, &bw320_offset))
148- continue;
149- }
150-
151 factor = 0;
152- best = NULL;
153- if (acs_usable_chan(chan)) {
154+ if (acs_usable_chan(chan))
155 factor = chan->interference_factor;
156- total_weight = 1;
157- best = chan;
158- }
159+ total_weight = 1;
160
161 for (j = 1; j < n_chans; j++) {
162- adj_chan = acs_find_chan(iface, chan->freq +
163- j * secondary_channel * 20);
164+ adj_chan = acs_find_chan(iface, chan->freq + (j * 20));
165 if (!adj_chan)
166 break;
167
168@@ -934,14 +869,16 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
169 break;
170 }
171
172- if (!acs_usable_chan(adj_chan))
173- continue;
174-
175- factor += adj_chan->interference_factor;
176- total_weight += 1;
177+ if (acs_usable_chan(adj_chan)) {
178+ factor += adj_chan->interference_factor;
179+ total_weight += 1;
180+ } else {
181+ update_best = false;
182+ }
183
184 /* find the best channel in this segment */
185- if (!best || adj_chan->interference_factor <
186+ if (update_best &&
187+ adj_chan->interference_factor <
188 best->interference_factor)
189 best = adj_chan;
190 }
191@@ -954,9 +891,8 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
192
193 /* If the AP is in the 5 GHz or 6 GHz band, lets prefer a less
194 * crowded primary channel if one was found in the segment */
195- if (iface->current_mode &&
196- iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A &&
197- best && chan != best) {
198+ if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A &&
199+ chan != best) {
200 wpa_printf(MSG_DEBUG,
201 "ACS: promoting channel %d over %d (less interference %Lg/%Lg)",
202 best->chan, chan->chan,
203@@ -969,9 +905,8 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
204 * channel interference factor. */
205 if (is_24ghz_mode(mode->mode)) {
206 for (j = 0; j < n_chans; j++) {
207- freq_offset = j * 20 * secondary_channel;
208 adj_chan = acs_find_chan(iface, chan->freq +
209- freq_offset - 5);
210+ (j * 20) - 5);
211 if (adj_chan && acs_usable_chan(adj_chan)) {
212 factor += ACS_ADJ_WEIGHT *
213 adj_chan->interference_factor;
214@@ -979,7 +914,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
215 }
216
217 adj_chan = acs_find_chan(iface, chan->freq +
218- freq_offset - 10);
219+ (j * 20) - 10);
220 if (adj_chan && acs_usable_chan(adj_chan)) {
221 factor += ACS_NEXT_ADJ_WEIGHT *
222 adj_chan->interference_factor;
223@@ -987,7 +922,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
224 }
225
226 adj_chan = acs_find_chan(iface, chan->freq +
227- freq_offset + 5);
228+ (j * 20) + 5);
229 if (adj_chan && acs_usable_chan(adj_chan)) {
230 factor += ACS_ADJ_WEIGHT *
231 adj_chan->interference_factor;
232@@ -995,7 +930,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
233 }
234
235 adj_chan = acs_find_chan(iface, chan->freq +
236- freq_offset + 10);
237+ (j * 20) + 10);
238 if (adj_chan && acs_usable_chan(adj_chan)) {
239 factor += ACS_NEXT_ADJ_WEIGHT *
240 adj_chan->interference_factor;
241@@ -1004,9 +939,6 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
242 }
243 }
244
245- if (total_weight == 0)
246- continue;
247-
248 factor /= total_weight;
249
250 bias = NULL;
251@@ -1044,7 +976,6 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
252
253 *ideal_factor = factor;
254 *ideal_chan = chan;
255- ideal_bw320_offset = bw320_offset;
256
257 #ifdef CONFIG_IEEE80211BE
258 if (iface->conf->ieee80211be)
259@@ -1055,13 +986,9 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
260 }
261
262 /* This channel would at least be usable */
263- if (!(*rand_chan)) {
264+ if (!(*rand_chan))
265 *rand_chan = chan;
266- ideal_bw320_offset = bw320_offset;
267- }
268 }
269-
270- hostapd_set_and_check_bw320_offset(iface->conf, ideal_bw320_offset);
271 }
272
273
274@@ -1088,12 +1015,19 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
275 goto bw_selected;
276 }
277
278+ /* TODO: HT40- support */
279+
280+ if (iface->conf->ieee80211n &&
281+ iface->conf->secondary_channel == -1) {
282+ wpa_printf(MSG_ERROR, "ACS: HT40- is not supported yet. Please try HT40+");
283+ return NULL;
284+ }
285+
286 if (iface->conf->ieee80211n &&
287 iface->conf->secondary_channel)
288 n_chans = 2;
289
290- if (iface->conf->ieee80211ac || iface->conf->ieee80211ax ||
291- iface->conf->ieee80211be) {
292+ if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) {
293 switch (hostapd_get_oper_chwidth(iface->conf)) {
294 case CONF_OPER_CHWIDTH_80MHZ:
295 n_chans = 4;
296@@ -1101,9 +1035,6 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
297 case CONF_OPER_CHWIDTH_160MHZ:
298 n_chans = 8;
299 break;
300- case CONF_OPER_CHWIDTH_320MHZ:
301- n_chans = 16;
302- break;
303 default:
304 break;
305 }
306@@ -1153,8 +1084,7 @@ static void acs_adjust_secondary(struct hostapd_iface *iface)
307 acs_find_mode(iface, iface->freq) != HOSTAPD_MODE_IEEE80211A)
308 return;
309
310- wpa_printf(MSG_DEBUG,
311- "ACS: Adjusting HT/VHT/HE/EHT secondary frequency");
312+ wpa_printf(MSG_DEBUG, "ACS: Adjusting HT/VHT/HE secondary frequency");
313
314 for (i = 0; bw_desc[ACS_BW40][i].first != -1; i++) {
315 if (iface->freq == bw_desc[ACS_BW40][i].first)
316@@ -1169,7 +1099,7 @@ static void acs_adjust_center_freq(struct hostapd_iface *iface)
317 {
318 int center;
319
320- wpa_printf(MSG_DEBUG, "ACS: Adjusting center frequency");
321+ wpa_printf(MSG_DEBUG, "ACS: Adjusting VHT center frequency");
322
323 switch (hostapd_get_oper_chwidth(iface->conf)) {
324 case CONF_OPER_CHWIDTH_USE_HT:
325@@ -1187,29 +1117,12 @@ static void acs_adjust_center_freq(struct hostapd_iface *iface)
326 break;
327 case CONF_OPER_CHWIDTH_160MHZ:
328 center = acs_get_bw_center_chan(iface->freq, ACS_BW160);
329- break;
330- case CONF_OPER_CHWIDTH_320MHZ:
331- switch (hostapd_get_bw320_offset(iface->conf)) {
332- case 1:
333- center = acs_get_bw_center_chan(iface->freq,
334- ACS_BW320_1);
335- break;
336- case 2:
337- center = acs_get_bw_center_chan(iface->freq,
338- ACS_BW320_2);
339- break;
340- default:
341- wpa_printf(MSG_INFO,
342- "ACS: BW320 offset is not selected");
343- return;
344- }
345-
346 break;
347 default:
348 /* TODO: How can this be calculated? Adjust
349 * acs_find_ideal_chan() */
350 wpa_printf(MSG_INFO,
351- "ACS: Only VHT20/40/80/160/320 is supported now");
352+ "ACS: Only VHT20/40/80/160 is supported now");
353 return;
354 }
355
356@@ -1272,8 +1185,7 @@ static void acs_study(struct hostapd_iface *iface)
357 iface->conf->punct_bitmap = ideal_chan->punct_bitmap;
358 #endif /* CONFIG_IEEE80211BE */
359
360- if (iface->conf->ieee80211ac || iface->conf->ieee80211ax ||
361- iface->conf->ieee80211be) {
362+ if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) {
363 acs_adjust_secondary(iface);
364 acs_adjust_center_freq(iface);
365 }
366diff --git a/tests/hwsim/test_ap_acs.py b/tests/hwsim/test_ap_acs.py
367index 001a5d4fd..e1359b6eb 100644
368--- a/tests/hwsim/test_ap_acs.py
369+++ b/tests/hwsim/test_ap_acs.py
370@@ -205,20 +205,11 @@ def test_ap_acs_40mhz_minus(dev, apdev):
371 params['acs_num_scans'] = '1'
372 params['chanlist'] = '1 11'
373 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
374- wait_acs(hapd)
375-
376- freq = hapd.get_status_field("freq")
377- if int(freq) < 2400:
378- raise Exception("Unexpected frequency")
379- sec = hapd.get_status_field("secondary_channel")
380- if int(sec) != -1:
381- raise Exception("Unexpected secondary_channel: " + sec)
382-
383- dev[0].connect("test-acs", psk="12345678", scan_freq=freq)
384- sig = dev[0].request("SIGNAL_POLL").splitlines()
385- logger.info("SIGNAL_POLL: " + str(sig))
386- if "WIDTH=40 MHz" not in sig:
387- raise Exception("Station did not report 40 MHz bandwidth")
388+ ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=10)
389+ if not ev:
390+ raise Exception("ACS start timed out")
391+ # HT40- is not currently supported in hostapd ACS, so do not try to connect
392+ # or verify that this operation succeeded.
393
394 def test_ap_acs_5ghz(dev, apdev):
395 """Automatic channel selection on 5 GHz"""
396--
3972.39.2
398