f42620042d2b55ce11a49cb7ae85d41e228bebc5
[openwrt/staging/linusw.git] /
1 From 978a59514ccde994b5c06e1cbb49cc8cebe6381c Mon Sep 17 00:00:00 2001
2 From: Markus Theil <markus.theil@tu-ilmenau.de>
3 Date: Tue, 30 Jun 2020 13:53:19 +0200
4 Subject: [PATCH 03/19] wpa_supplicant: handle HT40 and mode downgrade in AP
5 mode
6
7 This patch adds some missing pieces to the interface configuration
8 of AP/mesh mode in wpa_supplicant.
9 - check for secondary channel and HT40 capability
10 - try to downgrade to 11b if 11g is not available
11 Especially with the HT40 check, this code now performs all settings,
12 which the deleted/duplicated mesh code did.
13
14 Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
15 ---
16 wpa_supplicant/ap.c | 49 ++++++++++++++++++++++++++++++++++++---------
17 1 file changed, 40 insertions(+), 9 deletions(-)
18
19 --- a/wpa_supplicant/ap.c
20 +++ b/wpa_supplicant/ap.c
21 @@ -134,6 +134,23 @@ no_vht:
22 }
23
24
25 +static struct hostapd_hw_modes *wpa_supplicant_find_hw_mode(struct wpa_supplicant *wpa_s,
26 + enum hostapd_hw_mode hw_mode)
27 +{
28 + struct hostapd_hw_modes *mode = NULL;
29 + int i;
30 +
31 + for (i = 0; i < wpa_s->hw.num_modes; i++) {
32 + if (wpa_s->hw.modes[i].mode == hw_mode) {
33 + mode = &wpa_s->hw.modes[i];
34 + break;
35 + }
36 + }
37 +
38 + return mode;
39 +}
40 +
41 +
42 int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s,
43 struct wpa_ssid *ssid,
44 struct hostapd_config *conf)
45 @@ -147,9 +164,6 @@ int wpa_supplicant_conf_ap_ht(struct wpa
46 return -1;
47 }
48
49 - /* TODO: enable HT40 if driver supports it;
50 - * drop to 11b if driver does not support 11g */
51 -
52 /*
53 * Enable HT20 if the driver supports it, by setting conf->ieee80211n
54 * and a mask of allowed capabilities within conf->ht_capab.
55 @@ -158,17 +172,27 @@ int wpa_supplicant_conf_ap_ht(struct wpa
56 */
57 if (wpa_s->hw.modes) {
58 struct hostapd_hw_modes *mode = NULL;
59 - int i, no_ht = 0;
60 + int no_ht = 0;
61
62 wpa_printf(MSG_DEBUG,
63 "Determining HT/VHT options based on driver capabilities (freq=%u chan=%u)",
64 ssid->frequency, conf->channel);
65
66 - for (i = 0; i < wpa_s->hw.num_modes; i++) {
67 - if (wpa_s->hw.modes[i].mode == conf->hw_mode) {
68 - mode = &wpa_s->hw.modes[i];
69 - break;
70 - }
71 + mode = wpa_supplicant_find_hw_mode(wpa_s, conf->hw_mode);
72 +
73 + /* may drop drop to 11b if driver does not support 11g */
74 + if (!mode && conf->hw_mode == HOSTAPD_MODE_IEEE80211G) {
75 + conf->hw_mode = HOSTAPD_MODE_IEEE80211B;
76 + wpa_printf(MSG_INFO,
77 + "Try downgrade to IEEE 802.11b as 802.11g is not "
78 + "supported by the current hardware");
79 + mode = wpa_supplicant_find_hw_mode(wpa_s, conf->hw_mode);
80 + }
81 +
82 + if (!mode) {
83 + wpa_printf(MSG_ERROR,
84 + "No match between requested and supported hw modes found");
85 + return -1;
86 }
87
88 #ifdef CONFIG_HT_OVERRIDES
89 @@ -193,6 +217,13 @@ int wpa_supplicant_conf_ap_ht(struct wpa
90 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET),
91 ssid->ht40);
92 conf->ieee80211n = 1;
93 +
94 + if (ssid->ht40 &&
95 + mode->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)
96 + conf->secondary_channel = ssid->ht40;
97 + else
98 + conf->secondary_channel = 0;
99 +
100 #ifdef CONFIG_P2P
101 if (ssid->p2p_group &&
102 conf->hw_mode == HOSTAPD_MODE_IEEE80211A &&