aboutsummaryrefslogtreecommitdiffstats
path: root/package/network/services/hostapd/patches/010-mesh-Allow-DFS-channels-to-be-selected-if-dfs-is-ena.patch
blob: 0a51c84d2158b277b52a6a1db2431a6bc089db1c (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
From 8de8cd8380af0c43d4fde67a668d79ef73b26b26 Mon Sep 17 00:00:00 2001
From: Peter Oh <peter.oh@bowerswilkins.com>
Date: Tue, 30 Jun 2020 14:18:58 +0200
Subject: [PATCH 10/19] mesh: Allow DFS channels to be selected if dfs is
 enabled

Note: DFS is assumed to be usable if a country code has been set

Signed-off-by: Benjamin Berg <benjamin@sipsolutions.net>
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
---
 wpa_supplicant/wpa_supplicant.c | 25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)

--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -2638,7 +2638,7 @@ static int drv_supports_vht(struct wpa_s
 }
 
 
-static bool ibss_mesh_is_80mhz_avail(int channel, struct hostapd_hw_modes *mode)
+static bool ibss_mesh_is_80mhz_avail(int channel, struct hostapd_hw_modes *mode, bool dfs_enabled)
 {
 	int i;
 
@@ -2647,7 +2647,10 @@ static bool ibss_mesh_is_80mhz_avail(int
 
 		chan = hw_get_channel_chan(mode, i, NULL);
 		if (!chan ||
-		    chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
+		    chan->flag & HOSTAPD_CHAN_DISABLED)
+			return false;
+		
+		if (!dfs_enabled && chan->flag & (HOSTAPD_CHAN_RADAR | HOSTAPD_CHAN_NO_IR))
 			return false;
 	}
 
@@ -2774,7 +2777,7 @@ static void ibss_mesh_select_40mhz(struc
 				   const struct wpa_ssid *ssid,
 				   struct hostapd_hw_modes *mode,
 				   struct hostapd_freq_params *freq,
-				   int obss_scan) {
+				   int obss_scan, bool dfs_enabled) {
 	int chan_idx;
 	struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL;
 	int i, res;
@@ -2798,8 +2801,11 @@ static void ibss_mesh_select_40mhz(struc
 		return;
 
 	/* Check primary channel flags */
-	if (pri_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
+	if (pri_chan->flag & HOSTAPD_CHAN_DISABLED)
 		return;
+	if (pri_chan->flag & (HOSTAPD_CHAN_RADAR | HOSTAPD_CHAN_NO_IR))
+		if (!dfs_enabled)
+			return;
 
 #ifdef CONFIG_HT_OVERRIDES
 	if (ssid->disable_ht40)
@@ -2825,8 +2831,11 @@ static void ibss_mesh_select_40mhz(struc
 		return;
 
 	/* Check secondary channel flags */
-	if (sec_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
+	if (sec_chan->flag & HOSTAPD_CHAN_DISABLED)
 		return;
+	if (sec_chan->flag & (HOSTAPD_CHAN_RADAR | HOSTAPD_CHAN_NO_IR))
+		if (!dfs_enabled)
+			return;
 
 	if (ht40 == -1) {
 		if (!(pri_chan->flag & HOSTAPD_CHAN_HT40MINUS))
@@ -2880,7 +2889,7 @@ static bool ibss_mesh_select_80_160mhz(s
 				       const struct wpa_ssid *ssid,
 				       struct hostapd_hw_modes *mode,
 				       struct hostapd_freq_params *freq,
-				       int ieee80211_mode, bool is_6ghz) {
+				       int ieee80211_mode, bool is_6ghz, bool dfs_enabled) {
 	static const int bw80[] = {
 		5180, 5260, 5500, 5580, 5660, 5745, 5825,
 		5955, 6035, 6115, 6195, 6275, 6355, 6435,
@@ -2925,7 +2934,7 @@ static bool ibss_mesh_select_80_160mhz(s
 		goto skip_80mhz;
 
 	/* Use 40 MHz if channel not usable */
-	if (!ibss_mesh_is_80mhz_avail(channel, mode))
+	if (!ibss_mesh_is_80mhz_avail(channel, mode, dfs_enabled))
 		goto skip_80mhz;
 
 	chwidth = CONF_OPER_CHWIDTH_80MHZ;
@@ -2939,7 +2948,7 @@ static bool ibss_mesh_select_80_160mhz(s
 	if ((mode->he_capab[ieee80211_mode].phy_cap[
 		     HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &
 	     HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G) && is_6ghz &&
-	    ibss_mesh_is_80mhz_avail(channel + 16, mode)) {
+	    ibss_mesh_is_80mhz_avail(channel + 16, mode, dfs_enabled)) {
 		for (j = 0; j < ARRAY_SIZE(bw160); j++) {
 			if (freq->freq == bw160[j]) {
 				chwidth = CONF_OPER_CHWIDTH_160MHZ;
@@ -2967,10 +2976,12 @@ static bool ibss_mesh_select_80_160mhz(s
 				if (!chan)
 					continue;
 
-				if (chan->flag & (HOSTAPD_CHAN_DISABLED |
-						  HOSTAPD_CHAN_NO_IR |
-						  HOSTAPD_CHAN_RADAR))
+				if (chan->flag & HOSTAPD_CHAN_DISABLED)
 					continue;
+				if (chan->flag & (HOSTAPD_CHAN_RADAR |
+						  HOSTAPD_CHAN_NO_IR))
+					if (!dfs_enabled)
+						continue;
 
 				/* Found a suitable second segment for 80+80 */
 				chwidth = CONF_OPER_CHWIDTH_80P80MHZ;
@@ -3025,6 +3036,7 @@ void ibss_mesh_setup_freq(struct wpa_sup
 	int i, obss_scan = 1;
 	u8 channel;
 	bool is_6ghz;
+	bool dfs_enabled = wpa_s->conf->country[0] && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_RADAR);
 
 	freq->freq = ssid->frequency;
 
@@ -3070,9 +3082,9 @@ void ibss_mesh_setup_freq(struct wpa_sup
 	freq->channel = channel;
 	/* Setup higher BW only for 5 GHz */
 	if (mode->mode == HOSTAPD_MODE_IEEE80211A) {
-		ibss_mesh_select_40mhz(wpa_s, ssid, mode, freq, obss_scan);
+		ibss_mesh_select_40mhz(wpa_s, ssid, mode, freq, obss_scan, dfs_enabled);
 		if (!ibss_mesh_select_80_160mhz(wpa_s, ssid, mode, freq,
-						ieee80211_mode, is_6ghz))
+						ieee80211_mode, is_6ghz, dfs_enabled))
 			freq->he_enabled = freq->vht_enabled = false;
 	}