blob: eb3adadb22695f4d558aac053f69abf9c05d29e4 [file] [log] [blame]
developer8eb72a32023-03-30 08:32:07 +08001From 5c3ed28b75be359a7ec230d37a35990f31926f62 Mon Sep 17 00:00:00 2001
developerc69da752023-03-20 16:35:02 +08002From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
3Date: Mon, 20 Mar 2023 16:08:30 +0800
developer8eb72a32023-03-30 08:32:07 +08004Subject: [PATCH 25/25] hostapd: mtk: Fix ZWDFS issue in BW 160
developerc69da752023-03-20 16:35:02 +08005
6When background radar is enabled and bandwidth is set to 160, AP will
7fail to startup due to the lack of non-DFS channel.
8Under this circumstance, AP should perform CAC itself, and the background
9chain could also perform CAC simultaneously.
10
11Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
12---
13 src/ap/dfs.c | 98 ++++++++++++++++++++++++++++++++++++++++++----------
14 1 file changed, 79 insertions(+), 19 deletions(-)
15
16diff --git a/src/ap/dfs.c b/src/ap/dfs.c
17index d082fe0..d688ecb 100644
18--- a/src/ap/dfs.c
19+++ b/src/ap/dfs.c
20@@ -69,15 +69,22 @@ static int dfs_get_used_n_chans(struct hostapd_iface *iface, int *seg1)
21 static int dfs_channel_available(struct hostapd_channel_data *chan,
22 enum dfs_channel_type type)
23 {
24+ int dfs_status = chan->flag & HOSTAPD_CHAN_DFS_MASK;
25+
26+ if (chan->flag & HOSTAPD_CHAN_DISABLED)
27+ return -1;
28+
29 if (type == DFS_NO_CAC_YET) {
30 /* Select only radar channel where CAC has not been
31 * performed yet
32 */
33- if ((chan->flag & HOSTAPD_CHAN_RADAR) &&
34- (chan->flag & HOSTAPD_CHAN_DFS_MASK) ==
35- HOSTAPD_CHAN_DFS_USABLE)
36+ if (!(chan->flag & HOSTAPD_CHAN_RADAR))
37+ return 0;
38+
39+ if (dfs_status == HOSTAPD_CHAN_DFS_USABLE)
40 return 1;
41- return 0;
42+
43+ return -1;
44 }
45
46 /*
47@@ -86,16 +93,14 @@ static int dfs_channel_available(struct hostapd_channel_data *chan,
48 * channel for CSA, unless they are available for immediate use.
49 */
50 if (type == DFS_AVAILABLE && (chan->flag & HOSTAPD_CHAN_RADAR) &&
51- ((chan->flag & HOSTAPD_CHAN_DFS_MASK) !=
52- HOSTAPD_CHAN_DFS_AVAILABLE))
53- return 0;
54+ (dfs_status != HOSTAPD_CHAN_DFS_AVAILABLE))
55+ return -1;
56
57- if (chan->flag & HOSTAPD_CHAN_DISABLED)
58- return 0;
59 if ((chan->flag & HOSTAPD_CHAN_RADAR) &&
60- ((chan->flag & HOSTAPD_CHAN_DFS_MASK) ==
61- HOSTAPD_CHAN_DFS_UNAVAILABLE))
62- return 0;
63+ ((dfs_status == HOSTAPD_CHAN_DFS_UNAVAILABLE) ||
64+ (dfs_status == HOSTAPD_CHAN_DFS_UNKNOWN)))
65+ return -1;
66+
67 return 1;
68 }
69
70@@ -167,7 +172,7 @@ static int dfs_chan_range_available(struct hostapd_hw_modes *mode,
71 enum dfs_channel_type type)
72 {
73 struct hostapd_channel_data *first_chan, *chan;
74- int i;
75+ int i, available = 0, ret = 0;
76 u32 bw = num_chan_to_bw(num_chans);
77
78 if (first_chan_idx + num_chans > mode->num_channels) {
79@@ -203,14 +208,17 @@ static int dfs_chan_range_available(struct hostapd_hw_modes *mode,
80 return 0;
81 }
82
83- if (!dfs_channel_available(chan, type)) {
84+ ret = dfs_channel_available(chan, type);
85+ if (ret < 0) {
86 wpa_printf(MSG_DEBUG, "DFS: channel not available %d",
87 first_chan->freq + i * 20);
88 return 0;
89 }
90+
91+ available |= ret;
92 }
93
94- return 1;
95+ return available;
96 }
97
98
99@@ -826,8 +834,12 @@ static unsigned int dfs_get_cac_time(struct hostapd_iface *iface,
100 */
101 int hostapd_handle_dfs(struct hostapd_iface *iface)
102 {
103+ struct hostapd_channel_data *channel;
104 int res, n_chans, n_chans1, start_chan_idx, start_chan_idx1;
105- int skip_radar = 0;
106+ int sec = 0, skip_radar = 0;
107+ u8 cf1 = 0, cf2 = 0;
108+ bool use_radar_background = dfs_use_radar_background(iface);
109+ enum dfs_channel_type channel_type = DFS_NO_CAC_YET;
110
111 if (is_6ghz_freq(iface->freq))
112 return 1;
113@@ -890,7 +902,7 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
114 /* Finally start CAC */
115 hostapd_set_state(iface, HAPD_IFACE_DFS);
116 wpa_printf(MSG_DEBUG, "DFS start CAC on %d MHz%s", iface->freq,
117- dfs_use_radar_background(iface) ? " (background)" : "");
118+ use_radar_background ? " (background)" : "");
119 wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_START
120 "freq=%d chan=%d sec_chan=%d, width=%d, seg0=%d, seg1=%d, cac_time=%ds",
121 iface->freq,
122@@ -900,6 +912,16 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
123 hostapd_get_oper_centr_freq_seg1_idx(iface->conf),
124 iface->dfs_cac_ms / 1000);
125
126+ if (use_radar_background) {
127+ channel = dfs_get_valid_channel(iface, &sec, &cf1, &cf2, DFS_AVAILABLE);
128+ /*
129+ * AP cannot get any random available channel.
130+ * Let AP and dedicated radar chain both perform CAC.
131+ */
132+ if (!channel)
133+ use_radar_background = false;
134+ }
135+
136 res = hostapd_start_dfs_cac(
137 iface, iface->conf->hw_mode, iface->freq, iface->conf->channel,
138 iface->conf->ieee80211n, iface->conf->ieee80211ac,
139@@ -908,14 +930,14 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
140 hostapd_get_oper_chwidth(iface->conf),
141 hostapd_get_oper_centr_freq_seg0_idx(iface->conf),
142 hostapd_get_oper_centr_freq_seg1_idx(iface->conf),
143- dfs_use_radar_background(iface));
144+ use_radar_background);
145
146 if (res) {
147 wpa_printf(MSG_ERROR, "DFS start_dfs_cac() failed, %d", res);
148 return -1;
149 }
150
151- if (dfs_use_radar_background(iface)) {
152+ if (use_radar_background) {
153 /* Cache background radar parameters. */
154 iface->radar_background.channel = iface->conf->channel;
155 iface->radar_background.secondary_channel =
156@@ -936,6 +958,35 @@ int hostapd_handle_dfs(struct hostapd_iface *iface)
157
158 iface->radar_background.temp_ch = 1;
159 return 1;
160+ } else if (dfs_use_radar_background(iface)) {
161+ if (iface->dfs_domain == HOSTAPD_DFS_REGION_ETSI)
162+ channel_type = DFS_ANY_CHANNEL;
163+
164+ channel = dfs_get_valid_channel(iface, &sec, &cf1, &cf2, channel_type);
165+
166+ if (!channel ||
167+ (channel->chan == iface->conf->channel &&
168+ cf1 == hostapd_get_oper_centr_freq_seg0_idx(iface->conf) &&
169+ cf2 == hostapd_get_oper_centr_freq_seg1_idx(iface->conf))) {
170+ wpa_printf(MSG_ERROR, "Background radar could not get valid channel\n");
171+ iface->radar_background.channel = -1;
172+ return 0;
173+ }
174+
175+ hostapd_start_dfs_cac(iface, iface->conf->hw_mode,
176+ channel->freq, channel->chan,
177+ iface->conf->ieee80211n,
178+ iface->conf->ieee80211ac,
179+ iface->conf->ieee80211ax,
180+ iface->conf->ieee80211be,
181+ sec, hostapd_get_oper_chwidth(iface->conf),
182+ cf1, cf2, true);
183+
184+ iface->radar_background.channel = channel->chan;
185+ iface->radar_background.freq = channel->freq;
186+ iface->radar_background.secondary_channel = sec;
187+ iface->radar_background.centr_freq_seg0_idx = cf1;
188+ iface->radar_background.centr_freq_seg1_idx = cf2;
189 }
190
191 return 0;
192@@ -1185,6 +1236,15 @@ int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq,
193 hostapd_setup_interface_complete(iface, 0);
194 iface->cac_started = 0;
195 }
196+
197+ /*
198+ * When background radar is enabled but the CAC completion
199+ * is not received from the background chain.
200+ * Then, reset radar background chain.
201+ */
202+ if (dfs_use_radar_background(iface) &&
203+ iface->radar_background.channel == -1)
204+ hostpad_dfs_update_background_chain(iface);
205 }
206 } else if (hostapd_dfs_is_background_event(iface, freq)) {
207 iface->radar_background.cac_started = 0;
208--
2092.18.0
210