aboutsummaryrefslogtreecommitdiffstats
path: root/package/network/services/hostapd/patches/001-HE-VHT-fix-frequency-setup-with-HE-enabled.patch
blob: 37c17c50afc21fc75097548ab37a218437a27935 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
From 91976250359b263a44861aebe553b20627fe487e Mon Sep 17 00:00:00 2001
From: Markus Theil <markus.theil@tu-ilmenau.de>
Date: Tue, 30 Jun 2020 13:53:17 +0200
Subject: [PATCH 01/19] HE/VHT: fix frequency setup with HE enabled

Some places in the code base were not using the
wrappers like hostapd_set_oper_centr_freq_seg0_idx
and friends. This could lead to errors, for example when
joining 80 MHz mesh networks. Fix this, by enforcing
usage of these wrappers.

wpa_supplicant_conf_ap_ht now checks for HE capability
before dealing with VHT in order for these wrappers to work,
as they first check HE support in the config.

While doing these changes, I've noticed that the extra
channel setup code for mesh networks in wpa_supplicant/mesh.c
should not be necessary anymore and dropped it.
wpa_supplicant_conf_ap_ht should handle this setup already.

Acked-by: John Crispin <john@phrozen.org>
Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
---
 src/ap/dfs.c          |  8 ++++----
 wpa_supplicant/ap.c   | 40 +++++++++++++++++++++++-----------------
 wpa_supplicant/mesh.c | 24 ------------------------
 3 files changed, 27 insertions(+), 45 deletions(-)

--- a/src/ap/dfs.c
+++ b/src/ap/dfs.c
@@ -1028,7 +1028,7 @@ static int hostapd_dfs_start_channel_swi
 	unsigned int i;
 	int err = 1;
 	struct hostapd_hw_modes *cmode = iface->current_mode;
-	u8 current_vht_oper_chwidth = iface->conf->vht_oper_chwidth;
+	u8 current_vht_oper_chwidth = hostapd_get_oper_chwidth(iface->conf);
 
 	wpa_printf(MSG_DEBUG, "%s called (CAC active: %s, CSA active: %s)",
 		   __func__, iface->cac_started ? "yes" : "no",
@@ -1089,8 +1089,8 @@ static int hostapd_dfs_start_channel_swi
 		"freq=%d chan=%d sec_chan=%d", channel->freq,
 		channel->chan, secondary_channel);
 
-	new_vht_oper_chwidth = iface->conf->vht_oper_chwidth;
-	iface->conf->vht_oper_chwidth = current_vht_oper_chwidth;
+	new_vht_oper_chwidth = hostapd_get_oper_chwidth(iface->conf);
+	hostapd_set_oper_chwidth(iface->conf, current_vht_oper_chwidth);
 
 	/* Setup CSA request */
 	os_memset(&csa_settings, 0, sizeof(csa_settings));
@@ -1130,7 +1130,7 @@ static int hostapd_dfs_start_channel_swi
 		iface->freq = channel->freq;
 		iface->conf->channel = channel->chan;
 		iface->conf->secondary_channel = secondary_channel;
-		iface->conf->vht_oper_chwidth = new_vht_oper_chwidth;
+		hostapd_set_oper_chwidth(iface->conf, new_vht_oper_chwidth);
 		hostapd_set_oper_centr_freq_seg0_idx(iface->conf,
 						     oper_centr_freq_seg0_idx);
 		hostapd_set_oper_centr_freq_seg1_idx(iface->conf,
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -52,6 +52,7 @@ static void wpas_conf_ap_vht(struct wpa_
 #ifdef CONFIG_P2P
 	u8 center_chan = 0;
 	u8 channel = conf->channel;
+	u8 freq_seg_idx;
 #endif /* CONFIG_P2P */
 
 	if (!conf->secondary_channel)
@@ -59,19 +60,21 @@ static void wpas_conf_ap_vht(struct wpa_
 
 	/* Use the maximum oper channel width if it's given. */
 	if (ssid->max_oper_chwidth)
-		conf->vht_oper_chwidth = ssid->max_oper_chwidth;
+		hostapd_set_oper_chwidth(conf, ssid->max_oper_chwidth);
 
 	ieee80211_freq_to_chan(ssid->vht_center_freq2,
-			       &conf->vht_oper_centr_freq_seg1_idx);
+			       &freq_seg_idx);
+	hostapd_set_oper_centr_freq_seg1_idx(conf, freq_seg_idx);
 
 	if (!ssid->p2p_group) {
 		if (!ssid->vht_center_freq1 ||
-		    conf->vht_oper_chwidth == CHANWIDTH_USE_HT)
+		    hostapd_get_oper_chwidth(conf) == CHANWIDTH_USE_HT)
 			goto no_vht;
 		ieee80211_freq_to_chan(ssid->vht_center_freq1,
-				       &conf->vht_oper_centr_freq_seg0_idx);
+				       &freq_seg_idx);
+		hostapd_set_oper_centr_freq_seg0_idx(conf, freq_seg_idx);
 		wpa_printf(MSG_DEBUG, "VHT seg0 index %d for AP",
-			   conf->vht_oper_centr_freq_seg0_idx);
+			   hostapd_get_oper_centr_freq_seg0_idx(conf));
 		return;
 	}
 
@@ -96,14 +99,14 @@ static void wpas_conf_ap_vht(struct wpa_
 		 * try oper_cwidth 160 MHz first then VHT 80 MHz, if 160 MHz is
 		 * not supported.
 		 */
-		conf->vht_oper_chwidth = CHANWIDTH_160MHZ;
+		hostapd_set_oper_chwidth(conf, CHANWIDTH_160MHZ);
 		center_chan = wpas_p2p_get_vht160_center(wpa_s, mode, channel);
 		if (center_chan) {
 			wpa_printf(MSG_DEBUG,
 				   "VHT center channel %u for auto-selected 160 MHz bandwidth",
 				   center_chan);
 		} else {
-			conf->vht_oper_chwidth = CHANWIDTH_80MHZ;
+			hostapd_set_oper_chwidth(conf, CHANWIDTH_80MHZ);
 			center_chan = wpas_p2p_get_vht80_center(wpa_s, mode,
 								channel);
 			wpa_printf(MSG_DEBUG,
@@ -115,9 +118,9 @@ static void wpas_conf_ap_vht(struct wpa_
 	if (!center_chan)
 		goto no_vht;
 
-	conf->vht_oper_centr_freq_seg0_idx = center_chan;
+	hostapd_set_oper_centr_freq_seg0_idx(conf, center_chan);
 	wpa_printf(MSG_DEBUG, "VHT seg0 index %d for P2P GO",
-		   conf->vht_oper_centr_freq_seg0_idx);
+		   hostapd_get_oper_centr_freq_seg0_idx(conf));
 	return;
 #endif /* CONFIG_P2P */
 
@@ -125,9 +128,9 @@ no_vht:
 	wpa_printf(MSG_DEBUG,
 		   "No VHT higher bandwidth support for the selected channel %d",
 		   conf->channel);
-	conf->vht_oper_centr_freq_seg0_idx =
-		conf->channel + conf->secondary_channel * 2;
-	conf->vht_oper_chwidth = CHANWIDTH_USE_HT;
+	hostapd_set_oper_centr_freq_seg0_idx(conf,
+					     conf->channel + conf->secondary_channel * 2);
+	hostapd_set_oper_chwidth(conf, CHANWIDTH_USE_HT);
 }
 
 
@@ -231,16 +234,19 @@ int wpa_supplicant_conf_ap_ht(struct wpa
 				 HT_CAP_INFO_TX_STBC |
 				 HT_CAP_INFO_MAX_AMSDU_SIZE);
 
+			/* check this before VHT, because setting oper chan
+			 * width and friends is the same call for HE and VHT
+			 * and checks if conf->ieee8021ax == 1 */
+			if (mode->he_capab[wpas_mode_to_ieee80211_mode(
+					    ssid->mode)].he_supported &&
+			    ssid->he)
+				conf->ieee80211ax = 1;
+
 			if (mode->vht_capab && ssid->vht) {
 				conf->ieee80211ac = 1;
 				conf->vht_capab |= mode->vht_capab;
 				wpas_conf_ap_vht(wpa_s, ssid, conf, mode);
 			}
-
-			if (mode->he_capab[wpas_mode_to_ieee80211_mode(
-					    ssid->mode)].he_supported &&
-			    ssid->he)
-				conf->ieee80211ax = 1;
 		}
 	}
 
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
@@ -333,30 +333,6 @@ static int wpa_supplicant_mesh_init(stru
 			   frequency);
 		goto out_free;
 	}
-	if (ssid->ht40)
-		conf->secondary_channel = ssid->ht40;
-	if (conf->hw_mode == HOSTAPD_MODE_IEEE80211A && ssid->vht) {
-		if (ssid->max_oper_chwidth != DEFAULT_MAX_OPER_CHWIDTH)
-			conf->vht_oper_chwidth = ssid->max_oper_chwidth;
-		switch (conf->vht_oper_chwidth) {
-		case CHANWIDTH_80MHZ:
-		case CHANWIDTH_80P80MHZ:
-			ieee80211_freq_to_chan(
-				frequency,
-				&conf->vht_oper_centr_freq_seg0_idx);
-			conf->vht_oper_centr_freq_seg0_idx += ssid->ht40 * 2;
-			break;
-		case CHANWIDTH_160MHZ:
-			ieee80211_freq_to_chan(
-				frequency,
-				&conf->vht_oper_centr_freq_seg0_idx);
-			conf->vht_oper_centr_freq_seg0_idx += ssid->ht40 * 2;
-			conf->vht_oper_centr_freq_seg0_idx += 40 / 5;
-			break;
-		}
-		ieee80211_freq_to_chan(ssid->vht_center_freq2,
-				       &conf->vht_oper_centr_freq_seg1_idx);
-	}
 
 	if (ssid->mesh_basic_rates == NULL) {
 		/*