aboutsummaryrefslogtreecommitdiffstats
path: root/package/network/services/hostapd/patches/003-wpa_supplicant-handle-HT40-and-mode-downgrade-in-AP-.patch
blob: f42620042d2b55ce11a49cb7ae85d41e228bebc5 (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
From 978a59514ccde994b5c06e1cbb49cc8cebe6381c Mon Sep 17 00:00:00 2001
From: Markus Theil <markus.theil@tu-ilmenau.de>
Date: Tue, 30 Jun 2020 13:53:19 +0200
Subject: [PATCH 03/19] wpa_supplicant: handle HT40 and mode downgrade in AP
 mode

This patch adds some missing pieces to the interface configuration
of AP/mesh mode in wpa_supplicant.
 - check for secondary channel and HT40 capability
 - try to downgrade to 11b if 11g is not available
Especially with the HT40 check, this code now performs all settings,
which the deleted/duplicated mesh code did.

Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
---
 wpa_supplicant/ap.c | 49 ++++++++++++++++++++++++++++++++++++---------
 1 file changed, 40 insertions(+), 9 deletions(-)

--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -134,6 +134,23 @@ no_vht:
 }
 
 
+static struct hostapd_hw_modes *wpa_supplicant_find_hw_mode(struct wpa_supplicant *wpa_s,
+							    enum hostapd_hw_mode hw_mode)
+{
+	struct hostapd_hw_modes *mode = NULL;
+	int i;
+
+	for (i = 0; i < wpa_s->hw.num_modes; i++) {
+		if (wpa_s->hw.modes[i].mode == hw_mode) {
+			mode = &wpa_s->hw.modes[i];
+			break;
+		}
+	}
+
+	return mode;
+}
+
+
 int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s,
 			      struct wpa_ssid *ssid,
 			      struct hostapd_config *conf)
@@ -147,9 +164,6 @@ int wpa_supplicant_conf_ap_ht(struct wpa
 		return -1;
 	}
 
-	/* TODO: enable HT40 if driver supports it;
-	 * drop to 11b if driver does not support 11g */
-
 	/*
 	 * Enable HT20 if the driver supports it, by setting conf->ieee80211n
 	 * and a mask of allowed capabilities within conf->ht_capab.
@@ -158,17 +172,27 @@ int wpa_supplicant_conf_ap_ht(struct wpa
 	 */
 	if (wpa_s->hw.modes) {
 		struct hostapd_hw_modes *mode = NULL;
-		int i, no_ht = 0;
+		int no_ht = 0;
 
 		wpa_printf(MSG_DEBUG,
 			   "Determining HT/VHT options based on driver capabilities (freq=%u chan=%u)",
 			   ssid->frequency, conf->channel);
 
-		for (i = 0; i < wpa_s->hw.num_modes; i++) {
-			if (wpa_s->hw.modes[i].mode == conf->hw_mode) {
-				mode = &wpa_s->hw.modes[i];
-				break;
-			}
+		mode = wpa_supplicant_find_hw_mode(wpa_s, conf->hw_mode);
+
+		/* may drop drop to 11b if driver does not support 11g */
+		if (!mode && conf->hw_mode == HOSTAPD_MODE_IEEE80211G) {
+			conf->hw_mode = HOSTAPD_MODE_IEEE80211B;
+			wpa_printf(MSG_INFO,
+			   "Try downgrade to IEEE 802.11b as 802.11g is not "
+			   "supported by the current hardware");
+			mode = wpa_supplicant_find_hw_mode(wpa_s, conf->hw_mode);
+		}
+
+		if (!mode) {
+			wpa_printf(MSG_ERROR,
+			   "No match between requested and supported hw modes found");
+			return -1;
 		}
 
 #ifdef CONFIG_HT_OVERRIDES
@@ -193,6 +217,13 @@ int wpa_supplicant_conf_ap_ht(struct wpa
 				      HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET),
 				   ssid->ht40);
 			conf->ieee80211n = 1;
+
+			if (ssid->ht40 &&
+			    mode->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)
+				conf->secondary_channel = ssid->ht40;
+			else
+				conf->secondary_channel = 0;
+
 #ifdef CONFIG_P2P
 			if (ssid->p2p_group &&
 			    conf->hw_mode == HOSTAPD_MODE_IEEE80211A &&