1 /*
2 * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for
6 * any purpose with or without fee is hereby granted, provided that the
7 * above copyright notice and this permission notice appear in all
8 * copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 #include "../dfs.h"
21 #include "../dfs_random_chan_sel.h"
22 #include <qdf_mc_timer.h>
23 #include <wlan_utility.h>
24 #include <wlan_reg_services_api.h>
25 #include "../dfs_process_radar_found_ind.h"
26
27 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION
28 /*
29 * TODO: At present SAP Channel leakage matrix for ch 144
30 * is not available from system's team. So to play it safe
31 * and avoid crash if channel 144 is request, in following
32 * matrix channel 144 is added such that it will cause code
33 * to avoid selecting channel 144.
34 *
35 * THESE ENTRIES SHOULD BE REPLACED WITH CORRECT VALUES AS
36 * PROVIDED BY SYSTEM'S TEAM.
37 */
38
39 /* channel tx leakage table - ht80 */
40 struct dfs_matrix_tx_leak_info ht80_chan[] = {
41 {52, 5260,
42 {{36, 5180, 148}, {40, 5200, 199},
43 {44, 5520, 193}, {48, 5240, 197},
44 {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, 153},
45 {60, 5300, 137}, {64, 5320, 134},
46 {100, 5500, 358}, {104, 5520, 350},
47 {108, 5540, 404}, {112, 5560, 344},
48 {116, 5580, 424}, {120, 5600, 429},
49 {124, 5620, 437}, {128, 5640, 435},
50 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX},
51 {140, 5700, DFS_TX_LEAKAGE_MAX},
52 {144, 5720, DFS_TX_LEAKAGE_MIN}
53 } },
54
55
56 {56, 5280,
57 {{36, 5180, 171}, {40, 5200, 178},
58 {44, 5220, 171}, {48, 5240, 178},
59 {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN},
60 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, 280},
61 {100, 5500, 351}, {104, 5520, 376},
62 {108, 5540, 362}, {112, 5560, 362},
63 {116, 5580, 403}, {120, 5600, 397},
64 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX},
65 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX},
66 {140, 5700, DFS_TX_LEAKAGE_MAX},
67 {144, 5720, DFS_TX_LEAKAGE_MIN}
68 } },
69
70 {60,5300,
71 {{36, 5180, 156}, {40, 5200, 146},
72 {44, 5220, DFS_TX_LEAKAGE_MIN}, {48, 5240, DFS_TX_LEAKAGE_MIN},
73 {52, 5260, 180}, {56, 5280, DFS_TX_LEAKAGE_MIN},
74 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN},
75 {100, 5500, 376}, {104, 5520, 360},
76 {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX},
77 {116, 5580, 395}, {120, 5600, 399},
78 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX},
79 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX},
80 {140, 5700, DFS_TX_LEAKAGE_MAX},
81 {144, 5720, DFS_TX_LEAKAGE_MIN}
82 } },
83
84 {64, 5320,
85 {{36, 5180, 217}, {40, 5200, 221},
86 {44, 5220, DFS_TX_LEAKAGE_MIN}, {48, 5240, DFS_TX_LEAKAGE_MIN},
87 {52, 5260, 176}, {56, 5280, 176},
88 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN},
89 {100, 5500, 384}, {104, 5520, 390},
90 {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX},
91 {116, 5580, 375}, {120, 5600, 374},
92 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX},
93 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX},
94 {140, 5700, DFS_TX_LEAKAGE_MAX},
95 {144, 5720, DFS_TX_LEAKAGE_MIN}
96 } },
97
98 {100, 5500,
99 {{36, 5180, 357}, {40, 5200, 326},
100 {44, 5220, 321}, {48, 5240, 326},
101 {52, 5260, 378}, {56, 5280, 396},
102 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
103 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN},
104 {108, 5540, 196}, {112, 5560, 116},
105 {116, 5580, 166}, {120, 5600, DFS_TX_LEAKAGE_MIN},
106 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
107 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
108 {140, 5700, DFS_TX_LEAKAGE_MIN},
109 {144, 5720, DFS_TX_LEAKAGE_MIN}
110 } },
111
112 {104, 5520,
113 {{36, 5180, 325}, {40, 5200, 325},
114 {44, 5220, 305}, {48, 5240, 352},
115 {52, 5260, 411}, {56, 5280, 411},
116 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
117 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN},
118 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, 460},
119 {116, 5580, 198}, {120, 5600, DFS_TX_LEAKAGE_MIN},
120 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
121 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
122 {140, 5700, DFS_TX_LEAKAGE_MIN},
123 {144, 5720, DFS_TX_LEAKAGE_MIN}
124 } },
125
126 {108, 5540,
127 {{36,5180, 304}, {40, 5200, 332},
128 {44, 5220, 310}, {48, 5240, 335},
129 {52, 5260, 431}, {56, 5280, 391},
130 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
131 {100, 5500, 280}, {104, 5520, DFS_TX_LEAKAGE_MIN},
132 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
133 {116, 5580, 185}, {120, 5600, DFS_TX_LEAKAGE_MIN},
134 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
135 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
136 {140, 5700, DFS_TX_LEAKAGE_MIN},
137 {144, 5720, DFS_TX_LEAKAGE_MIN}
138 } },
139
140 {112,5560,
141 {{36, 5180, 327}, {40, 5200, 335},
142 {44, 5220, 331}, {48, 5240, 345},
143 {52, 5260, 367}, {56, 5280, 401},
144 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
145 {100, 5500, 131}, {104, 5520, 132},
146 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
147 {116, 5580, 189}, {120, 5600, DFS_TX_LEAKAGE_MIN},
148 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
149 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
150 {140, 5700, DFS_TX_LEAKAGE_MIN},
151 {144, 5720, DFS_TX_LEAKAGE_MIN}
152 } },
153
154 {116, 5580,
155 {{36, 5180, 384}, {40, 5200, 372},
156 {44, 5220, 389}, {48, 5240, 396},
157 {52, 5260, 348}, {56, 5280, 336},
158 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
159 {100, 5500, 172}, {104, 5520, 169},
160 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
161 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN},
162 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
163 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
164 {140, 5700, DFS_TX_LEAKAGE_MIN},
165 {144, 5720, DFS_TX_LEAKAGE_MIN}
166 } },
167
168 {120, 5600,
169 {{36, 5180, 395}, {40, 5200, 419},
170 {44, 5220, 439}, {48, 5240, 407},
171 {52, 5260, 321}, {56, 5280, 334},
172 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
173 {100, 5500, 134}, {104, 5520, 186},
174 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
175 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN},
176 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, 159},
177 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
178 {140, 5700, DFS_TX_LEAKAGE_MIN},
179 {144, 5720, DFS_TX_LEAKAGE_MIN}
180 } },
181
182 {124, 5620,
183 {{36, 5180, 469}, {40, 5200, 433},
184 {44, 5220, 434}, {48, 5240, 435},
185 {52, 5260, 332}, {56, 5280, 345},
186 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
187 {100, 5500, 146}, {104, 5520, 177},
188 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
189 {116, 5580, 350}, {120, 5600, DFS_TX_LEAKAGE_MIN},
190 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, 138},
191 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
192 {140, 5700, DFS_TX_LEAKAGE_MIN},
193 {144, 5720, DFS_TX_LEAKAGE_MIN}
194 } },
195
196 {128, 5640,
197 {{36, 5180, 408}, {40, 5200, 434},
198 {44, 5220, 449}, {48, 5240, 444},
199 {52, 5260, 341}, {56, 5280, 374},
200 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
201 {100, 5500, 205}, {104, 5520, 208},
202 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
203 {116, 5580, 142}, {120, 5600, DFS_TX_LEAKAGE_MIN},
204 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
205 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
206 {140, 5700, DFS_TX_LEAKAGE_MIN},
207 {144, 5720, DFS_TX_LEAKAGE_MIN}
208 } },
209
210 {132, 5660,
211 {{36, 5180, DFS_TX_LEAKAGE_MAX}, {40, 5200, DFS_TX_LEAKAGE_MAX},
212 {44, 5220, DFS_TX_LEAKAGE_MAX}, {48, 5240, DFS_TX_LEAKAGE_MAX},
213 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX},
214 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN},
215 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN},
216 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
217 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN},
218 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
219 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
220 {140, 5700, DFS_TX_LEAKAGE_MIN},
221 {144, 5720, DFS_TX_LEAKAGE_MIN}
222 } },
223
224 {136, 5680,
225 {{36, 5180, DFS_TX_LEAKAGE_MAX}, {40, 5200, DFS_TX_LEAKAGE_MAX},
226 {44, 5220, DFS_TX_LEAKAGE_MAX}, {48, 5240, DFS_TX_LEAKAGE_MAX},
227 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX},
228 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN},
229 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN},
230 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
231 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN},
232 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
233 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
234 {140, 5700, DFS_TX_LEAKAGE_MIN},
235 {144, 5720, DFS_TX_LEAKAGE_MIN}
236 } },
237
238 {140, 5700,
239 {{36, 5180, DFS_TX_LEAKAGE_MAX}, {40, 5200, DFS_TX_LEAKAGE_MAX},
240 {44, 5220, DFS_TX_LEAKAGE_MAX}, {48, 5240, DFS_TX_LEAKAGE_MAX},
241 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX},
242 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN},
243 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN},
244 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
245 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN},
246 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
247 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
248 {144, 5720, DFS_TX_LEAKAGE_MIN}
249 } },
250
251 {144, 5720,
252 {{36, 5180, DFS_TX_LEAKAGE_MAX}, {40, 5200, DFS_TX_LEAKAGE_MAX},
253 {44, 5220, DFS_TX_LEAKAGE_MAX}, {48, 5240, DFS_TX_LEAKAGE_MAX},
254 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX},
255 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN},
256 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN},
257 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
258 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN},
259 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
260 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
261 {144, 5720, DFS_TX_LEAKAGE_MIN}
262 } },
263 };
264
265 /* channel tx leakage table - ht40 */
266 struct dfs_matrix_tx_leak_info ht40_chan[] = {
267 {52, 5260,
268 {{36, 5180, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN},
269 {44, 5220, 230}, {48, 5240, 230},
270 {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN},
271 {60, 5300, DFS_TX_LEAKAGE_AUTO_MIN}, {64, 5320, DFS_TX_LEAKAGE_AUTO_MIN},
272 {100, 5500, 625}, {104, 5520, 323},
273 {108, 5540, 646}, {112, 5560, 646},
274 {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX},
275 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX},
276 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX},
277 {140, 5700, DFS_TX_LEAKAGE_MAX},
278 {144, 5720, DFS_TX_LEAKAGE_MIN}
279 } },
280
281 {56, 5280,
282 {{36, 5180, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN},
283 {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 5240, DFS_TX_LEAKAGE_AUTO_MIN},
284 {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN},
285 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN},
286 {100, 5500, 611}, {104, 5520, 611},
287 {108, 5540, 617}, {112, 5560, 617},
288 {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX},
289 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX},
290 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX},
291 {140, 5700, DFS_TX_LEAKAGE_MAX},
292 {144, 5720, DFS_TX_LEAKAGE_MIN}
293 } },
294
295 {60, 5300,
296 {{36, 5180, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN},
297 {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 5240, DFS_TX_LEAKAGE_AUTO_MIN},
298 {52, 5260, 190}, {56, 5280, 190},
299 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN},
300 {100, 5500, 608}, {104, 5520, 608},
301 {108, 5540, 623}, {112, 5560, 623},
302 {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX},
303 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX},
304 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX},
305 {140, 5700, DFS_TX_LEAKAGE_MAX},
306 {144, 5720, DFS_TX_LEAKAGE_MIN}
307 } },
308
309 {64, 5320,
310 {{36, 5180, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN},
311 {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 5240, DFS_TX_LEAKAGE_AUTO_MIN},
312 {52, 5260, 295}, {56, 5280, 295},
313 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN},
314 {100, 5500, 594}, {104, 5520, 594},
315 {108, 5540, 625}, {112, 5560, 625},
316 {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX},
317 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX},
318 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX},
319 {140, 5700, DFS_TX_LEAKAGE_MAX},
320 {144, 5720, DFS_TX_LEAKAGE_MIN}
321 } },
322
323 {100, 5500,
324 {{36, 5180, 618}, {40, 5200, 618},
325 {44, 5220, 604}, {48, 5240, 604},
326 {52, 5260, 596}, {56, 5280, 596},
327 {60, 5300, 584}, {64, 5320, 584},
328 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN},
329 {108, 5540, 299}, {112, 5560, 299},
330 {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN},
331 {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN},
332 {132, 5660, 538}, {136,5680, 538},
333 {140, 5700, 598},
334 {144, 5720, DFS_TX_LEAKAGE_MIN}
335 } },
336
337 {104, 5520,
338 {{36, 5180, 636}, {40, 5200, 636},
339 {44, 5220, 601}, {48, 5240, 601},
340 {52, 5260, 616}, {56, 5280, 616},
341 {60, 5300, 584}, {64, 5320, 584},
342 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN},
343 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
344 {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN},
345 {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN},
346 {132, 5660, 553}, {136, 5680, 553},
347 {140, 5700, 568},
348 {144, 5720, DFS_TX_LEAKAGE_MIN}
349 } },
350
351 {108, 5540,
352 {{36, 5180, 600}, {40, 5200, 600},
353 {44, 5220, 627}, {48, 5240, 627},
354 {52, 5260, 611}, {56, 5280, 611},
355 {60, 5300, 611}, {64, 5320, 611},
356 {100, 5500, 214}, {104, 5520, 214},
357 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
358 {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN},
359 {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN},
360 {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN},
361 {140, 5700, 534},
362 {144, 5720, DFS_TX_LEAKAGE_MIN}
363 } },
364
365 {112, 5560,
366 {{36, 5180, 645}, {40, 5200, 645},
367 {44, 5220, 641}, {48, 5240, 641},
368 {52, 5260, 618}, {56, 5280, 618},
369 {60, 5300, 612}, {64, 5320, 612},
370 {100, 5500, 293}, {104, 5520, 293},
371 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
372 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN},
373 {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN},
374 {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN},
375 {140, 5700, 521},
376 {144, 5720, DFS_TX_LEAKAGE_MIN}
377 } },
378
379 {116, 5580,
380 {{36, 5180, 661}, {40, 5200, 661},
381 {44, 5220, 624}, {48, 5240, 624},
382 {52, 5260, 634}, {56, 5280, 634},
383 {60, 5300, 611}, {64, 5320, 611},
384 {100, 5500, DFS_TX_LEAKAGE_AUTO_MIN}, {104, 5520, DFS_TX_LEAKAGE_AUTO_MIN},
385 {108, 5540, 217}, {112, 5560, 217},
386 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN},
387 {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN},
388 {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN},
389 {140, 5700, DFS_TX_LEAKAGE_AUTO_MIN},
390 {144, 5720, DFS_TX_LEAKAGE_MIN}
391 } },
392
393 {120, 5600,
394 {{36, 5180, 667}, {40, 5200, 667},
395 {44, 5220, 645}, {48, 5240, 645},
396 {52, 5260, 633}, {56, 5280, 633},
397 {60, 5300, 619}, {64, 5320, 619},
398 {100, 5500, DFS_TX_LEAKAGE_AUTO_MIN}, {104, 5520, DFS_TX_LEAKAGE_AUTO_MIN},
399 {108, 5540, 291}, {112, 5560, 291},
400 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN},
401 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
402 {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN},
403 {140, 5700, DFS_TX_LEAKAGE_AUTO_MIN},
404 {144, 5720, DFS_TX_LEAKAGE_MIN}
405 } },
406
407 {124, 5620,
408 {{36, 5180, 676}, {40, 5200, 676},
409 {44, 5220, 668}, {48, 5240, 668},
410 {52, 5260, 595}, {56, 5280, 595},
411 {60, 5300, 622}, {64, 5320, 622},
412 {100, 5500, DFS_TX_LEAKAGE_AUTO_MIN}, {104, 5520, DFS_TX_LEAKAGE_AUTO_MIN},
413 {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN},
414 {116, 5580, 225}, {120, 5600, 225},
415 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
416 {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN},
417 {140, 5700, DFS_TX_LEAKAGE_AUTO_MIN},
418 {144, 5720, DFS_TX_LEAKAGE_MIN}
419 } },
420
421 {128, 5640,
422 {{36, 5180, 678}, {40, 5200, 678},
423 {44, 5220, 664}, {48, 5240, 664},
424 {52, 5260, 651}, {56, 5280, 651},
425 {60, 5300, 643}, {64, 5320, 643},
426 {100, 5500, DFS_TX_LEAKAGE_AUTO_MIN}, {104, 5520, DFS_TX_LEAKAGE_AUTO_MIN},
427 {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN},
428 {116, 5580, 293}, {120, 5600, 293},
429 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
430 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
431 {140, 5700, DFS_TX_LEAKAGE_AUTO_MIN},
432 {144, 5720, DFS_TX_LEAKAGE_MIN}
433 } },
434
435 {132, 5660,
436 {{36, 5180, 689}, {40, 5200, 689},
437 {44, 5220, 669}, {48, 5240, 669},
438 {52, 5260, 662}, {56, 5280, 662},
439 {60, 5300, 609}, {64, 5320, 609},
440 {100, 5500, 538}, {104, 5520, 538},
441 {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN},
442 {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN},
443 {124, 5620, 247}, {128, 5640, 247},
444 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
445 {140, 5700, DFS_TX_LEAKAGE_MIN},
446 {144, 5720, DFS_TX_LEAKAGE_MIN}
447 } },
448
449 {136, 5680,
450 {{36, 5180, 703}, {40, 5200, 703},
451 {44, 5220, 688}, {48, 5240, DFS_TX_LEAKAGE_MIN},
452 {52, 5260, 671}, {56, 5280, 671},
453 {60, 5300, 658}, {64, 5320, 658},
454 {100, 5500, 504}, {104, 5520, 504},
455 {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN},
456 {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN},
457 {124, 5620, 289}, {128, 5640, 289},
458 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
459 {140, 5700, DFS_TX_LEAKAGE_MIN},
460 {144, 5720, DFS_TX_LEAKAGE_MIN}
461 } },
462
463 {140, 5700,
464 {{36, 5180, 695}, {40, 5200, 695},
465 {44, 5220, 684}, {48, 5240, 684},
466 {52, 5260, 664}, {56, 5280, 664},
467 {60, 5300, 658}, {64, 5320, 658},
468 {100, 5500, 601}, {104, 5520, 601},
469 {108, 5540, 545}, {112, 5560, 545},
470 {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN},
471 {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN},
472 {132, 5660, 262}, {136, 5680, 262},
473 {140, 5700, DFS_TX_LEAKAGE_MIN},
474 {144, 5720, DFS_TX_LEAKAGE_MIN}
475 } },
476
477 {144, 5720,
478 {{36, 5180, 695}, {40, 5200, 695},
479 {44, 5220, 684}, {48, 5240, 684},
480 {52, 5260, 664}, {56, 5280, 664},
481 {60, 5300, 658}, {64, 5320, 658},
482 {100, 5500, 601}, {104, 5520, 601},
483 {108, 5540, 545}, {112, 5560, 545},
484 {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN},
485 {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN},
486 {132, 5660, 262}, {136, 5680, 262},
487 {140, 5700, DFS_TX_LEAKAGE_MIN},
488 {144, 5720, DFS_TX_LEAKAGE_MIN}
489 } },
490 };
491
492 /* channel tx leakage table - ht20 */
493 struct dfs_matrix_tx_leak_info ht20_chan[] = {
494 {52, 5260,
495 {{36, 5180,DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, 286},
496 {44, 5220, 225}, {48,5240, 121},
497 {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN},
498 {60, 5300, 300}, {64, 5320, DFS_TX_LEAKAGE_AUTO_MIN},
499 {100, 5500, 637}, {104, 5520, DFS_TX_LEAKAGE_MAX},
500 {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX},
501 {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX},
502 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX},
503 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX},
504 {140, 5700, DFS_TX_LEAKAGE_MAX},
505 {144, 5720, DFS_TX_LEAKAGE_MIN}
506 } },
507
508 {56, 5280,
509 {{36, 5180, 468}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN},
510 {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 5240, 206},
511 {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN},
512 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN},
513 {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX},
514 {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX},
515 {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX},
516 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX},
517 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX},
518 {140, 5700, DFS_TX_LEAKAGE_MAX},
519 {144, 5720, DFS_TX_LEAKAGE_MIN}
520 } },
521
522 {60, 5300,
523 {{36, 5180, 507}, {40, 5200, 440},
524 {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48,5240, 313},
525 {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN},
526 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN},
527 {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX},
528 {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX},
529 {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX},
530 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX},
531 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX},
532 {140, 5700, DFS_TX_LEAKAGE_MAX},
533 {144, 5720, DFS_TX_LEAKAGE_MIN}
534 } },
535
536 {64, 5320 ,
537 {{36, 5180, 516}, {40, 5200, 520},
538 {44, 5220, 506}, {48, 5240,DFS_TX_LEAKAGE_AUTO_MIN},
539 {52, 5260, 301}, {56, 5280, 258},
540 {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN},
541 {100, 5500, 620}, {104, 5520, 617},
542 {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX},
543 {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX},
544 {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX},
545 {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX},
546 {140, 5700, DFS_TX_LEAKAGE_MAX},
547 {144, 5720, DFS_TX_LEAKAGE_MIN}
548 } },
549
550 {100, 5500,
551 {{36, 5180, 616}, {40, 5200, 601},
552 {44, 5220, 604}, {48, 5240, 589},
553 {52, 5260, 612}, {56, 5280, 592},
554 {60, 5300, 590}, {64, 5320, 582},
555 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, 131},
556 {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN},
557 {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, 522},
558 {124, 5620, 571}, {128, 5640, 589},
559 {132, 5660, 593}, {136, 5680, 598},
560 {140, 5700, 594},
561 {144, 5720, DFS_TX_LEAKAGE_MIN},
562 } },
563
564 {104, 5520,
565 {{36, 5180, 622}, {40, 5200, 624},
566 {44, 5220, 618}, {48, 5240, 610},
567 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX},
568 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
569 {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN},
570 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, 463},
571 {116, 5580, 483}, {120, 5600, 503},
572 {124, 5620, 523}, {128, 5640, 565},
573 {132, 5660, 570}, {136, 5680, 588},
574 {140, 5700, 585},
575 {144, 5720, DFS_TX_LEAKAGE_MIN},
576 } },
577
578 {108, 5540,
579 {{36, 5180, 620}, {40, 5200, 638},
580 {44, 5220, 611}, {48, 5240, 614},
581 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX},
582 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
583 {100, 5500, 477}, {104, 5520, DFS_TX_LEAKAGE_MIN},
584 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
585 {116, 5580, 477}, {120, 5600, 497},
586 {124, 5620, 517}, {128, 5640, 537},
587 {132, 5660, 557}, {136, 5680, 577},
588 {140, 5700, 603},
589 {144, 5720, DFS_TX_LEAKAGE_MIN},
590 } },
591
592 {112, 5560,
593 {{36, 5180, 636}, {40, 5200, 623},
594 {44, 5220, 638}, {48, 5240, 628},
595 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX},
596 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, 606},
597 {100, 5500, 501}, {104, 5520, 481},
598 {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
599 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, 481},
600 {124, 5620, 501}, {128, 5640, 421},
601 {132, 5660, 541}, {136, 5680, 561},
602 {140, 5700, 583},
603 {144, 5720, DFS_TX_LEAKAGE_MIN},
604 } },
605
606 {116, 5580,
607 {{36, 5180, 646}, {40, 5200, 648},
608 {44, 5220, 633}, {48, 5240, 634},
609 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX},
610 {60, 5300, 615}, {64, 5320, 594},
611 {100, 5500, 575}, {104, 5520, 554},
612 {108, 5540, 534}, {112, 5560, DFS_TX_LEAKAGE_MIN},
613 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN},
614 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
615 {132, 5660, 534}, {136, 5680, 554},
616 {140, 5700, 574},
617 {144, 5720, DFS_TX_LEAKAGE_MIN},
618 } },
619
620 {120, 5600,
621 {{36, 5180, 643}, {40, 5200, 649},
622 {44, 5220, 654}, {48, 5240, 629},
623 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, 621},
624 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
625 {100, 5500, 565}, {104, 5520, 545},
626 {108, 5540, 525}, {112, 5560, 505},
627 {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN},
628 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, 505},
629 {132, 5660, 525}, {136, 5680, 545},
630 {140, 5700, 565},
631 {144, 5720, DFS_TX_LEAKAGE_MIN},
632 } },
633
634 {124, 5620,
635 {{36, 5180, 638}, {40, 5200, 657},
636 {44, 5220, 663}, {48, 5240, 649},
637 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX},
638 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
639 {100, 5500, 581}, {104, 5520, 561},
640 {108, 5540, 541}, {112, 5560, 521},
641 {116, 5580, 499}, {120, 5600, DFS_TX_LEAKAGE_MIN},
642 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
643 {132, 5660, 499}, {136, 5680, 519},
644 {140, 5700, 539},
645 {144, 5720, DFS_TX_LEAKAGE_MIN}
646 } },
647
648 {128, 5640,
649 {{36, 5180, 651}, {40, 5200, 651},
650 {44, 5220, 674}, {48, 5240, 640},
651 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX},
652 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
653 {100, 5500, 603}, {104, 5520, 560},
654 {108, 5540, 540}, {112, 5560, 520},
655 {116, 5580, 499}, {120, 5600, 479},
656 {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
657 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, 479},
658 {140, 5700, 499},
659 {144, 5720, DFS_TX_LEAKAGE_MIN}
660 } },
661
662 {132, 5660,
663 {{36, 5180, 643}, {40, 5200, 668},
664 {44, 5220, 651}, {48, 5240, 657},
665 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX},
666 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
667 {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, 602},
668 {108, 5540, 578}, {112,5560, 570},
669 {116, 5580, 550}, {120, 5600, 530},
670 {124, 5620, 510}, {128, 5640, DFS_TX_LEAKAGE_MIN},
671 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
672 {140, 5700, 490},
673 {144, 5720, DFS_TX_LEAKAGE_MIN}
674 } },
675
676 {136,5680,
677 {{36, 5180, 654}, {40, 5200, 667},
678 {44, 5220, 666}, {48, 5240, 642},
679 {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX},
680 {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
681 {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX},
682 {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, 596},
683 {116, 5580, 555}, {120, 5600, 535},
684 {124, 5620, 515}, {128, 5640, 495},
685 {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
686 {140, 5700, DFS_TX_LEAKAGE_MIN},
687 {144, 5720, DFS_TX_LEAKAGE_MIN}
688 } },
689
690 {140,5700,
691 {{36, 5180, 679}, {40, 5200, 673},
692 {44, 5220, 667}, {48, 5240, 656},
693 {52, 5260, 634}, {56, 5280, 663},
694 {60, 5300, 662}, {64, 5320, 660},
695 {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX},
696 {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, 590},
697 {116, 5580, 573}, {120, 5600, 553},
698 {124, 5620, 533}, {128, 5640, 513},
699 {132, 5660, 490}, {136, 5680, DFS_TX_LEAKAGE_MIN},
700 {140, 5700, DFS_TX_LEAKAGE_MIN},
701 {144, 5720, DFS_TX_LEAKAGE_MIN}
702 } },
703
704 {144,5720,
705 {{36, 5180, 679}, {40, 5200, 673},
706 {44, 5220, 667}, {48, 5240, 656},
707 {52, 5260, 634}, {56, 5280, 663},
708 {60, 5300, 662}, {64, 5320, 660},
709 {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX},
710 {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, 590},
711 {116, 5580, 573}, {120, 5600, 553},
712 {124, 5620, 533}, {128, 5640, 513},
713 {132, 5660, 490}, {136, 5680, DFS_TX_LEAKAGE_MIN},
714 {140, 5700, DFS_TX_LEAKAGE_MIN},
715 {144, 5720, DFS_TX_LEAKAGE_MIN}
716 } },
717 };
718
719 /*
720 * dfs_find_target_channel_in_channel_matrix_for_freq() - finds the leakage
721 * matrix.
722 * @chan_width: target channel width
723 * @nol_channel: the NOL channel frequency whose leakage matrix is required
724 * @pTarget_chnl_mtrx: pointer to target channel matrix returned.
725 *
726 * This function gives the leakage matrix for given NOL channel and ch_width
727 *
728 * Return: TRUE or FALSE
729 */
730 #ifdef CONFIG_CHAN_FREQ_API
731 static bool
dfs_find_target_channel_in_channel_matrix_for_freq(enum phy_ch_width chan_width,uint16_t nol_freq,struct dfs_tx_leak_info ** pTarget_chnl_mtrx)732 dfs_find_target_channel_in_channel_matrix_for_freq(enum phy_ch_width chan_width,
733 uint16_t nol_freq,
734 struct dfs_tx_leak_info
735 **pTarget_chnl_mtrx)
736 {
737 struct dfs_tx_leak_info *target_chan_matrix = NULL;
738 struct dfs_matrix_tx_leak_info *pchan_matrix = NULL;
739 uint32_t nchan_matrix;
740 int i = 0;
741
742 switch (chan_width) {
743 case CH_WIDTH_20MHZ:
744 /* HT20 */
745 pchan_matrix = ht20_chan;
746 nchan_matrix = QDF_ARRAY_SIZE(ht20_chan);
747 break;
748 case CH_WIDTH_40MHZ:
749 /* HT40 */
750 pchan_matrix = ht40_chan;
751 nchan_matrix = QDF_ARRAY_SIZE(ht40_chan);
752 break;
753 case CH_WIDTH_80MHZ:
754 /* HT80 */
755 pchan_matrix = ht80_chan;
756 nchan_matrix = QDF_ARRAY_SIZE(ht80_chan);
757 break;
758 default:
759 /* handle exception and fall back to HT20 table */
760 pchan_matrix = ht20_chan;
761 nchan_matrix = QDF_ARRAY_SIZE(ht20_chan);
762 break;
763 }
764
765 for (i = 0; i < nchan_matrix; i++) {
766 /* find the SAP channel to map the leakage matrix */
767 if (nol_freq == pchan_matrix[i].channel_freq) {
768 target_chan_matrix = pchan_matrix[i].chan_matrix;
769 break;
770 }
771 }
772
773 if (!target_chan_matrix) {
774 return false;
775 } else {
776 *pTarget_chnl_mtrx = target_chan_matrix;
777 return true;
778 }
779 }
780 #endif
781
782 #ifdef CONFIG_CHAN_FREQ_API
783
784 #ifdef CONFIG_BAND_6GHZ
785 #define END_CHAN_INDEX CHAN_ENUM_7115
786 #else
787 #define END_CHAN_INDEX CHAN_ENUM_5720
788 #endif
789
790 #define START_CHAN_INDEX CHAN_ENUM_5180
791 QDF_STATUS
dfs_mark_leaking_chan_for_freq(struct wlan_dfs * dfs,enum phy_ch_width ch_width,uint8_t temp_chan_lst_sz,uint16_t * temp_freq_lst)792 dfs_mark_leaking_chan_for_freq(struct wlan_dfs *dfs,
793 enum phy_ch_width ch_width,
794 uint8_t temp_chan_lst_sz,
795 uint16_t *temp_freq_lst)
796 {
797 struct dfs_tx_leak_info *target_chan_matrix = NULL;
798 uint32_t num_channel = (END_CHAN_INDEX - START_CHAN_INDEX) + 1;
799 uint32_t j = 0;
800 uint32_t k = 0;
801 struct dfs_nolelem *nol;
802
803 nol = dfs->dfs_nol;
804 while (nol) {
805 if (false == dfs_find_target_channel_in_channel_matrix_for_freq(
806 ch_width, nol->nol_freq,
807 &target_chan_matrix)) {
808 /*
809 * should never happen, we should always find a table
810 * here, if we don't, need a fix here!
811 */
812 dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
813 "Couldn't find target channel matrix!");
814 QDF_ASSERT(0);
815 return QDF_STATUS_E_FAILURE;
816 }
817 /*
818 * following is based on assumption that both temp_freq_lst
819 * and target channel matrix are in increasing order of
820 * ch_id
821 */
822 for (j = 0, k = 0; j < temp_chan_lst_sz && k < num_channel;) {
823 if (temp_freq_lst[j] == 0) {
824 j++;
825 continue;
826 }
827 if (target_chan_matrix[k].leak_chan_freq !=
828 temp_freq_lst[j]) {
829 k++;
830 continue;
831 }
832 /*
833 * check leakage from candidate channel
834 * to NOL channel
835 */
836 if (target_chan_matrix[k].leak_lvl <=
837 dfs->tx_leakage_threshold) {
838 /*
839 * candidate channel will have
840 * bad leakage in NOL channel,
841 * remove from temp list
842 */
843 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
844 "dfs: channel: %d will have bad leakage due to channel: %d\n",
845 nol->nol_freq, temp_freq_lst[j]);
846 temp_freq_lst[j] = 0;
847 }
848 j++;
849 k++;
850 }
851 nol = nol->nol_next;
852 } /* end of loop that selects each NOL */
853
854 return QDF_STATUS_SUCCESS;
855 }
856 #endif
857 #else
858 #ifdef CONFIG_CHAN_FREQ_API
859 QDF_STATUS
dfs_mark_leaking_chan_for_freq(struct wlan_dfs * dfs,enum phy_ch_width ch_width,uint8_t temp_chan_lst_sz,uint16_t * temp_freq_lst)860 dfs_mark_leaking_chan_for_freq(struct wlan_dfs *dfs,
861 enum phy_ch_width ch_width,
862 uint8_t temp_chan_lst_sz,
863 uint16_t *temp_freq_lst)
864 {
865 return QDF_STATUS_SUCCESS;
866 }
867 #endif
868 #endif
869
870 /*
871 * dfs_populate_80mhz_available_channel_for_freq() - Populate 80MHZ channels
872 * available for selection.
873 * @dfs: Pointer to wlan_dfs.
874 * @bitmap: Pointer to bonding channel bitmap.
875 * @avail_freq_list: Pointer to frequency list of available channels.
876 */
877 #ifdef CONFIG_CHAN_FREQ_API
dfs_populate_80mhz_available_channel_for_freq(struct wlan_dfs * dfs,struct chan_bonding_bitmap * bitmap,uint16_t * avail_freq_list)878 static uint8_t dfs_populate_80mhz_available_channel_for_freq(
879 struct wlan_dfs *dfs,
880 struct chan_bonding_bitmap *bitmap,
881 uint16_t *avail_freq_list)
882 {
883 uint8_t i = 0;
884 uint8_t chnl_count = 0;
885 uint16_t start_chan_freq = 0;
886
887 for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) {
888 start_chan_freq = bitmap->chan_bonding_set[i].start_chan_freq;
889 if (bitmap->chan_bonding_set[i].chan_map ==
890 DFS_80MHZ_MASK) {
891 avail_freq_list[chnl_count++] = start_chan_freq +
892 (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 0);
893 avail_freq_list[chnl_count++] = start_chan_freq +
894 (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 1);
895 avail_freq_list[chnl_count++] = start_chan_freq +
896 (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 2);
897 avail_freq_list[chnl_count++] = start_chan_freq +
898 (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 3);
899 }
900 }
901
902 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
903 "channel count %d", chnl_count);
904
905 return chnl_count;
906 }
907 #endif
908
909 #ifdef CONFIG_CHAN_FREQ_API
910 static uint8_t
dfs_populate_40mhz_available_channel_for_freq(struct wlan_dfs * dfs,struct chan_bonding_bitmap * bmap,uint16_t * avail_freq_list)911 dfs_populate_40mhz_available_channel_for_freq(struct wlan_dfs *dfs,
912 struct chan_bonding_bitmap *bmap,
913 uint16_t *avail_freq_list)
914 {
915 uint8_t i = 0;
916 uint8_t chnl_count = 0;
917 uint16_t start_chan_freq = 0;
918
919 for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) {
920 start_chan_freq = bmap->chan_bonding_set[i].start_chan_freq;
921 if ((bmap->chan_bonding_set[i].chan_map &
922 DFS_40MHZ_MASK_L) == DFS_40MHZ_MASK_L) {
923 avail_freq_list[chnl_count++] = start_chan_freq +
924 (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 0);
925 avail_freq_list[chnl_count++] = start_chan_freq +
926 (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 1);
927 }
928 if ((bmap->chan_bonding_set[i].chan_map &
929 DFS_40MHZ_MASK_H) == DFS_40MHZ_MASK_H) {
930 avail_freq_list[chnl_count++] = start_chan_freq +
931 (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 2);
932 avail_freq_list[chnl_count++] = start_chan_freq +
933 (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 3);
934 }
935 }
936
937 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
938 "channel count %d", chnl_count);
939
940 return chnl_count;
941 }
942 #endif
943
944 /**
945 * dfs_populate_available_channel_for_freq()- Populate channels based on width
946 * and bitmap.
947 * @dfs: Pointer to DFS structure.
948 * @bitmap: bitmap
949 * @chan_width: channel width
950 * @freq_list: prepared channel list
951 *
952 * Prepare channel list based on width and channel bitmap.
953 *
954 * Return: channel count
955 */
956 #ifdef CONFIG_CHAN_FREQ_API
957 static uint8_t
dfs_populate_available_channel_for_freq(struct wlan_dfs * dfs,struct chan_bonding_bitmap * bitmap,uint16_t chan_width,uint16_t * freq_list)958 dfs_populate_available_channel_for_freq(struct wlan_dfs *dfs,
959 struct chan_bonding_bitmap *bitmap,
960 uint16_t chan_width,
961 uint16_t *freq_list)
962 {
963 switch (chan_width) {
964 case DFS_CH_WIDTH_320MHZ:
965 case DFS_CH_WIDTH_160MHZ:
966 case DFS_CH_WIDTH_80P80MHZ:
967 case DFS_CH_WIDTH_80MHZ:
968 return dfs_populate_80mhz_available_channel_for_freq(dfs,
969 bitmap,
970 freq_list);
971 case DFS_CH_WIDTH_40MHZ:
972 return dfs_populate_40mhz_available_channel_for_freq(dfs,
973 bitmap,
974 freq_list);
975 default:
976 dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
977 "Invalid chan_width %d", chan_width);
978 break;
979 }
980
981 return 0;
982 }
983 #endif
984
985 /**
986 * dfs_get_rand_from_lst_for_freq()- Get random channel from a given channel
987 * list.
988 * @dfs: Pointer to DFS structure.
989 * @freq_lst: Frequency list
990 * @num_chan: number of channels
991 *
992 * Get random channel from given channel list.
993 *
994 * Return: channel frequency.
995 */
996
997 #ifdef CONFIG_CHAN_FREQ_API
dfs_get_rand_from_lst_for_freq(struct wlan_dfs * dfs,uint16_t * freq_lst,uint8_t num_chan)998 static uint16_t dfs_get_rand_from_lst_for_freq(struct wlan_dfs *dfs,
999 uint16_t *freq_lst,
1000 uint8_t num_chan)
1001 {
1002 uint8_t i;
1003 uint32_t rand_byte = 0;
1004
1005 if (!num_chan || !freq_lst) {
1006 dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
1007 "invalid param freq_lst %pK, num_chan = %d",
1008 freq_lst, num_chan);
1009 return 0;
1010 }
1011
1012 get_random_bytes((uint8_t *)&rand_byte, 1);
1013 i = (rand_byte + qdf_mc_timer_get_system_ticks()) % num_chan;
1014
1015 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1016 "random chan freq %d", freq_lst[i]);
1017
1018 return freq_lst[i];
1019 }
1020 #endif
1021
1022 #ifdef CONFIG_CHAN_FREQ_API
1023 #define FREQUENCY_BAND_LIMIT 60
1024
1025 /**
1026 * dfs_random_channel_sel_set_bitmap_for_freq()- Set channel bit in bitmap based
1027 * on given channel number
1028 * @dfs: Pointer to DFS structure.
1029 * @bitmap: bitmap
1030 * @chan_freq: channel frequency
1031 *
1032 * Set channel bit in bitmap based on given channel frequency.
1033 *
1034 * Return: None
1035 */
1036 static void
dfs_random_channel_sel_set_bitmap_for_freq(struct wlan_dfs * dfs,struct chan_bonding_bitmap * bitmap,uint16_t chan_freq)1037 dfs_random_channel_sel_set_bitmap_for_freq(struct wlan_dfs *dfs,
1038 struct chan_bonding_bitmap *bitmap,
1039 uint16_t chan_freq)
1040 {
1041 int i = 0;
1042 int start_chan_freq = 0;
1043
1044 for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) {
1045 start_chan_freq = bitmap->chan_bonding_set[i].start_chan_freq;
1046 if (chan_freq >= start_chan_freq &&
1047 chan_freq <= start_chan_freq +
1048 FREQUENCY_BAND_LIMIT) {
1049 bitmap->chan_bonding_set[i].chan_map |=
1050 (1 << ((chan_freq - start_chan_freq) /
1051 DFS_80_NUM_SUB_CHANNEL_FREQ));
1052 return;
1053 }
1054 }
1055
1056 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1057 "Frequency=%d is not in the bitmap", chan_freq);
1058 }
1059 #endif
1060
1061 #ifdef CONFIG_BAND_6GHZ
1062 /**
1063 * dfs_assign_6g_channels()- Assign the center frequency of the first 20 MHZ
1064 * channel in every 80MHz channel, present in the 6G band.
1065 * @ch_map: Pointer to ch_map.
1066 *
1067 * Return: Void
1068 */
dfs_assign_6g_channels(struct chan_bonding_bitmap * ch_map)1069 static void dfs_assign_6g_channels(struct chan_bonding_bitmap *ch_map)
1070 {
1071 ch_map->chan_bonding_set[7].start_chan_freq = 5955;
1072 ch_map->chan_bonding_set[8].start_chan_freq = 6035;
1073 ch_map->chan_bonding_set[9].start_chan_freq = 6115;
1074 ch_map->chan_bonding_set[10].start_chan_freq = 6195;
1075 ch_map->chan_bonding_set[11].start_chan_freq = 6275;
1076 ch_map->chan_bonding_set[12].start_chan_freq = 6355;
1077 ch_map->chan_bonding_set[13].start_chan_freq = 6435;
1078 ch_map->chan_bonding_set[14].start_chan_freq = 6515;
1079 ch_map->chan_bonding_set[15].start_chan_freq = 6595;
1080 ch_map->chan_bonding_set[16].start_chan_freq = 6675;
1081 ch_map->chan_bonding_set[17].start_chan_freq = 6755;
1082 ch_map->chan_bonding_set[18].start_chan_freq = 6835;
1083 ch_map->chan_bonding_set[19].start_chan_freq = 6915;
1084 ch_map->chan_bonding_set[20].start_chan_freq = 6995;
1085 }
1086 #else
dfs_assign_6g_channels(struct chan_bonding_bitmap * ch_map)1087 static inline void dfs_assign_6g_channels(struct chan_bonding_bitmap *ch_map)
1088 {
1089 }
1090 #endif
1091
1092 /**
1093 * dfs_find_num_sub_channels_for_chwidth_320_160() - Find the max number
1094 * of sub channels for the given channel width (320/160)
1095 * @chan_width: Channel width
1096 *
1097 * Return - Number of sub-channels
1098 */
1099 static uint8_t
dfs_find_num_sub_channels_for_chwidth_320_160(uint16_t chan_width)1100 dfs_find_num_sub_channels_for_chwidth_320_160(uint16_t chan_width)
1101 {
1102 if (chan_width == DFS_CH_WIDTH_160MHZ)
1103 return DFS_MAX_NUM_160_SUBCHAN;
1104 else if (chan_width == DFS_CH_WIDTH_320MHZ)
1105 return DFS_MAX_NUM_240_SUBCHAN;
1106
1107 return 0;
1108 }
1109
1110 /**
1111 * dfs_find_next_chan_start_freq_for_320_160() - Find the next 160/320 channel's
1112 * start freq based on the available channel list. Validate the
1113 * continuity of the sub channels of 160/320M BW, if they are contiguous
1114 * declare channel to be found. Return the start_freq of the channel band found.
1115 * @chan_count: Total number of available channels.
1116 * @freq_list: Available list of frequency
1117 * @chan_width: Target channel width
1118 * @chan_found: Bool to indicate if channel is found
1119 *
1120 * Return: Next chan's start freq
1121 */
1122
1123 static qdf_freq_t
dfs_find_next_chan_start_freq_for_320_160(uint8_t chan_count,uint16_t * freq_list,uint16_t chan_width,bool * chan_found)1124 dfs_find_next_chan_start_freq_for_320_160(uint8_t chan_count,
1125 uint16_t *freq_list,
1126 uint16_t chan_width, bool *chan_found)
1127 {
1128 uint8_t i;
1129 uint8_t count = 0;
1130 qdf_freq_t next_chan_start_freq = 0;
1131 uint8_t num_sub_chans =
1132 dfs_find_num_sub_channels_for_chwidth_320_160(chan_width);
1133
1134 for (i = 1; i < chan_count; i++) {
1135 if ((freq_list[i] - freq_list[i - 1]) ==
1136 DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET)
1137 count++;
1138 else
1139 count = 0;
1140 if (count == num_sub_chans - 1) {
1141 *chan_found = true;
1142 next_chan_start_freq = freq_list[i - count];
1143 break;
1144 }
1145 }
1146 return next_chan_start_freq;
1147 }
1148
1149 /**
1150 * dfs_find_ch_with_fallback_for_freq()- find random channel
1151 * @dfs: Pointer to DFS structure.
1152 * @chan_wd: channel width
1153 * @center_freq_seg1: center frequency of secondary segment.
1154 * @freq_lst: list of available frequency.
1155 * @num_chan: number of channels in the list.
1156 *
1157 * Find random channel based on given channel width and channel list,
1158 * fallback to lower width if requested channel width not available.
1159 *
1160 * Return: channel frequency.
1161 */
1162 #ifdef CONFIG_CHAN_FREQ_API
dfs_find_ch_with_fallback_for_freq(struct wlan_dfs * dfs,uint16_t * chan_wd,qdf_freq_t * center_freq_seg1,uint16_t * freq_lst,uint32_t num_chan)1163 static uint16_t dfs_find_ch_with_fallback_for_freq(struct wlan_dfs *dfs,
1164 uint16_t *chan_wd,
1165 qdf_freq_t *center_freq_seg1,
1166 uint16_t *freq_lst,
1167 uint32_t num_chan)
1168 {
1169 bool flag = false;
1170 uint32_t rand_byte = 0;
1171 struct chan_bonding_bitmap ch_map = { { {0} } };
1172 uint8_t i, index = 0, final_cnt = 0;
1173 uint16_t target_channel = 0;
1174 uint16_t primary_seg_start_ch = 0, sec_seg_ch = 0, new_start_ch = 0;
1175 uint16_t final_lst[NUM_CHANNELS] = {0};
1176
1177 /* initialize ch_map for all 80 MHz bands: we have 6 80MHz bands */
1178 ch_map.chan_bonding_set[0].start_chan_freq = 5180;
1179 ch_map.chan_bonding_set[1].start_chan_freq = 5260;
1180 ch_map.chan_bonding_set[2].start_chan_freq = 5500;
1181 ch_map.chan_bonding_set[3].start_chan_freq = 5580;
1182 ch_map.chan_bonding_set[4].start_chan_freq = 5660;
1183 ch_map.chan_bonding_set[5].start_chan_freq = 5745;
1184 ch_map.chan_bonding_set[6].start_chan_freq = 5825;
1185
1186 dfs_assign_6g_channels(&ch_map);
1187 for (i = 0; i < num_chan; i++) {
1188 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1189 "channel = %d added to bitmap", freq_lst[i]);
1190 dfs_random_channel_sel_set_bitmap_for_freq(dfs, &ch_map,
1191 freq_lst[i]);
1192 }
1193
1194 /* populate available channel list from bitmap */
1195 final_cnt = dfs_populate_available_channel_for_freq(dfs, &ch_map,
1196 *chan_wd, final_lst);
1197
1198 /* If no valid 80mhz bonded chan found, fallback */
1199 if (final_cnt == 0) {
1200 if ((*chan_wd == DFS_CH_WIDTH_320MHZ) ||
1201 (*chan_wd == DFS_CH_WIDTH_160MHZ) ||
1202 (*chan_wd == DFS_CH_WIDTH_80P80MHZ) ||
1203 (*chan_wd == DFS_CH_WIDTH_80MHZ)) {
1204 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1205 "from [%d] to 40Mhz", *chan_wd);
1206 *chan_wd = DFS_CH_WIDTH_40MHZ;
1207 } else if (*chan_wd == DFS_CH_WIDTH_40MHZ) {
1208 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1209 "from 40Mhz to 20MHz");
1210 *chan_wd = DFS_CH_WIDTH_20MHZ;
1211 }
1212 return 0;
1213 }
1214
1215 /* ch count should be > 8 to switch new channel in 160Mhz band */
1216 if (((*chan_wd == DFS_CH_WIDTH_160MHZ) ||
1217 (*chan_wd == DFS_CH_WIDTH_80P80MHZ)) &&
1218 (final_cnt < DFS_MAX_NUM_160_SUBCHAN)) {
1219 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1220 "from [%d] to 80Mhz", *chan_wd);
1221 *chan_wd = DFS_CH_WIDTH_80MHZ;
1222 return 0;
1223 }
1224
1225 /* ch count should be 12 to switch new 320 channel band (240MHZ) */
1226 if (*chan_wd == DFS_CH_WIDTH_320MHZ) {
1227 if (final_cnt < DFS_MAX_NUM_240_SUBCHAN) {
1228 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1229 "from [%d] to 160Mhz", *chan_wd);
1230 *chan_wd = DFS_CH_WIDTH_160MHZ;
1231 return 0;
1232 }
1233 }
1234
1235 if (*chan_wd == DFS_CH_WIDTH_320MHZ ||
1236 *chan_wd == DFS_CH_WIDTH_160MHZ) {
1237 /*
1238 * Only 2 blocks for 160Mhz bandwidth i.e 36-64 & 100-128
1239 * and all the channels in these blocks are continuous
1240 * and separated by 4Mhz.
1241 * Only 1 block of 240 channel is
1242 * available from 100 - 140 comprising of 12 sub 20 channels.
1243 * These are continuous and separated by 20MHZ in
1244 * frequency spectrum.
1245 */
1246 new_start_ch =
1247 dfs_find_next_chan_start_freq_for_320_160(final_cnt,
1248 final_lst,
1249 *chan_wd,
1250 &flag);
1251 } else if (*chan_wd == DFS_CH_WIDTH_80P80MHZ) {
1252 flag = true;
1253 }
1254
1255 if (!flag) {
1256 if (*chan_wd == DFS_CH_WIDTH_320MHZ) {
1257 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1258 "from [%d] to 160Mhz", *chan_wd);
1259 *chan_wd = DFS_CH_WIDTH_160MHZ;
1260 return 0;
1261 } else if (*chan_wd == DFS_CH_WIDTH_160MHZ) {
1262 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1263 "from [%d] to 80Mhz", *chan_wd);
1264 *chan_wd = DFS_CH_WIDTH_80MHZ;
1265 return 0;
1266 }
1267 }
1268
1269 if (*chan_wd == DFS_CH_WIDTH_320MHZ ||
1270 *chan_wd == DFS_CH_WIDTH_160MHZ) {
1271 get_random_bytes((uint8_t *)&rand_byte, 1);
1272 rand_byte = (rand_byte + qdf_mc_timer_get_system_ticks())
1273 % dfs_find_num_sub_channels_for_chwidth_320_160
1274 (*chan_wd);
1275 target_channel = new_start_ch + (rand_byte *
1276 DFS_80_NUM_SUB_CHANNEL_FREQ);
1277 } else if (*chan_wd == DFS_CH_WIDTH_80P80MHZ) {
1278 get_random_bytes((uint8_t *)&rand_byte, 1);
1279 index = (rand_byte + qdf_mc_timer_get_system_ticks()) %
1280 final_cnt;
1281 target_channel = final_lst[index];
1282 index -= (index % DFS_80_NUM_SUB_CHANNEL);
1283 primary_seg_start_ch = final_lst[index];
1284
1285 /* reset channels associate with primary 80Mhz */
1286 for (i = 0; i < DFS_80_NUM_SUB_CHANNEL; i++)
1287 final_lst[i + index] = 0;
1288 /* select and calculate center freq for secondary segment */
1289 for (i = 0; i < final_cnt / DFS_80_NUM_SUB_CHANNEL; i++) {
1290 if (final_lst[i * DFS_80_NUM_SUB_CHANNEL] &&
1291 (abs(primary_seg_start_ch -
1292 final_lst[i * DFS_80_NUM_SUB_CHANNEL]) >
1293 (DFS_80P80M_FREQ_DIFF * 2))) {
1294 sec_seg_ch = final_lst[i *
1295 DFS_80_NUM_SUB_CHANNEL] +
1296 DFS_80MHZ_START_CENTER_CH_FREQ_DIFF;
1297 break;
1298 }
1299 }
1300
1301 if (!sec_seg_ch && (final_cnt == DFS_MAX_NUM_160_SUBCHAN))
1302 *chan_wd = DFS_CH_WIDTH_160MHZ;
1303 else if (!sec_seg_ch)
1304 *chan_wd = DFS_CH_WIDTH_80MHZ;
1305
1306 *center_freq_seg1 = sec_seg_ch;
1307 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1308 "Center frequency seg1 = %d", sec_seg_ch);
1309 } else {
1310 target_channel = dfs_get_rand_from_lst_for_freq(dfs,
1311 final_lst,
1312 final_cnt);
1313 }
1314 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1315 "target channel = %d", target_channel);
1316
1317 return target_channel;
1318 }
1319 #endif
1320
dfs_is_freq_in_nol(struct wlan_dfs * dfs,uint32_t freq)1321 bool dfs_is_freq_in_nol(struct wlan_dfs *dfs, uint32_t freq)
1322 {
1323 struct dfs_nolelem *nol;
1324
1325 if (!dfs) {
1326 dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "null dfs");
1327 return false;
1328 }
1329
1330 nol = dfs->dfs_nol;
1331 while (nol) {
1332 if (freq == nol->nol_freq) {
1333 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1334 "%d is in nol", freq);
1335 return true;
1336 }
1337 nol = nol->nol_next;
1338 }
1339
1340 return false;
1341 }
1342
1343 /**
1344 * dfs_apply_rules_for_freq()- prepare channel list based on flags
1345 * @dfs: dfs handler
1346 * @flags: channel flags
1347 * @random_chan_freq_list: output channel list
1348 * @random_chan_cnt: output channel count
1349 * @chan_list: input channel list
1350 * @chan_cnt: input channel count
1351 * @dfs_region: dfs region
1352 * @acs_info: acs channel range information
1353 *
1354 * prepare channel list based on flags
1355 *
1356 * return: none
1357 */
1358 #ifdef CONFIG_CHAN_FREQ_API
dfs_apply_rules_for_freq(struct wlan_dfs * dfs,uint32_t flags,uint16_t * random_chan_freq_list,uint32_t * random_chan_cnt,struct dfs_channel * chan_list,uint32_t chan_cnt,uint8_t dfs_region,struct dfs_acs_info * acs_info)1359 static void dfs_apply_rules_for_freq(struct wlan_dfs *dfs,
1360 uint32_t flags,
1361 uint16_t *random_chan_freq_list,
1362 uint32_t *random_chan_cnt,
1363 struct dfs_channel *chan_list,
1364 uint32_t chan_cnt,
1365 uint8_t dfs_region,
1366 struct dfs_acs_info *acs_info)
1367 {
1368 struct dfs_channel *chan;
1369 bool flag_no_weather = 0;
1370 bool flag_no_lower_5g = 0;
1371 bool flag_no_upper_5g = 0;
1372 bool flag_no_dfs_chan = 0;
1373 bool flag_no_2g_chan = 0;
1374 bool flag_no_5g_chan = 0;
1375 bool flag_no_japan_w53 = 0;
1376 bool flag_no_6g_freq;
1377 int i;
1378 bool found = false;
1379 uint16_t j;
1380 uint16_t freq_list[MAX_20MHZ_SUBCHANS];
1381 uint8_t num_channels = 0;
1382
1383 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "flags %d", flags);
1384 flag_no_weather = (dfs_region == DFS_ETSI_REGION) ?
1385 flags & DFS_RANDOM_CH_FLAG_NO_WEATHER_CH : 0;
1386
1387 if (dfs_region == DFS_MKK_REGION ||
1388 dfs_region == DFS_MKKN_REGION) {
1389 flag_no_lower_5g = flags & DFS_RANDOM_CH_FLAG_NO_LOWER_5G_CH;
1390 flag_no_upper_5g = flags & DFS_RANDOM_CH_FLAG_NO_UPEER_5G_CH;
1391 flag_no_japan_w53 = flags & DFS_RANDOM_CH_FLAG_NO_JAPAN_W53_CH;
1392 }
1393
1394 flag_no_dfs_chan = flags & DFS_RANDOM_CH_FLAG_NO_DFS_CH;
1395 flag_no_2g_chan = flags & DFS_RANDOM_CH_FLAG_NO_2GHZ_CH;
1396 flag_no_5g_chan = flags & DFS_RANDOM_CH_FLAG_NO_5GHZ_CH;
1397 flag_no_6g_freq = flags & DFS_RANDOM_CH_FLAG_NO_6GHZ_CH;
1398
1399 if (flags & DFS_RANDOM_CH_FLAG_NO_CURR_OPE_CH) {
1400 num_channels =
1401 dfs_get_bonding_channel_without_seg_info_for_freq
1402 (dfs->dfs_curchan, freq_list);
1403 }
1404
1405 for (i = 0; i < chan_cnt; i++) {
1406 chan = &chan_list[i];
1407 found = false;
1408
1409 if ((chan->dfs_ch_ieee == 0) ||
1410 (chan->dfs_ch_ieee > MAX_CHANNEL_NUM)) {
1411 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1412 "invalid channel %d", chan->dfs_ch_ieee);
1413 continue;
1414 }
1415
1416 if (flags & DFS_RANDOM_CH_FLAG_NO_CURR_OPE_CH) {
1417 for (j = 0; j < num_channels; j++) {
1418 if (chan->dfs_ch_freq == freq_list[j]) {
1419 dfs_debug(dfs,
1420 WLAN_DEBUG_DFS_RANDOM_CHAN,
1421 "skip %d current operating channel",
1422 chan->dfs_ch_freq);
1423 found = true;
1424 break;
1425 }
1426 }
1427
1428 if (found)
1429 continue;
1430 }
1431
1432 if (acs_info && acs_info->acs_mode) {
1433 for (j = 0; j < acs_info->num_of_channel; j++) {
1434 if (acs_info->chan_freq_list[j] ==
1435 chan->dfs_ch_freq) {
1436 found = true;
1437 break;
1438 }
1439 }
1440
1441 if (!found) {
1442 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1443 "skip ch freq %d not in acs range",
1444 chan->dfs_ch_freq);
1445 continue;
1446 }
1447 found = false;
1448 }
1449
1450 if (flag_no_2g_chan &&
1451 chan->dfs_ch_freq <= DFS_MAX_24GHZ_CHANNEL_FREQ) {
1452 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1453 "skip 2.4 GHz channel=%d", chan->dfs_ch_ieee);
1454 continue;
1455 }
1456
1457 if (flag_no_5g_chan &&
1458 WLAN_REG_IS_5GHZ_CH_FREQ(chan->dfs_ch_freq)) {
1459 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1460 "skip 5 GHz channel=%d", chan->dfs_ch_ieee);
1461 continue;
1462 }
1463
1464 if (flag_no_weather) {
1465 if (DFS_IS_CHANNEL_WEATHER_RADAR(chan->dfs_ch_freq)) {
1466 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1467 "skip weather channel=%d",
1468 chan->dfs_ch_ieee);
1469 continue;
1470 }
1471 }
1472
1473 if (flag_no_lower_5g &&
1474 DFS_IS_CHAN_JAPAN_INDOOR_FREQ(chan->dfs_ch_freq)) {
1475 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1476 "skip indoor channel=%d", chan->dfs_ch_ieee);
1477 continue;
1478 }
1479
1480 if (flag_no_upper_5g &&
1481 DFS_IS_CHAN_JAPAN_OUTDOOR_FREQ(chan->dfs_ch_freq)) {
1482 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1483 "skip outdoor channel=%d", chan->dfs_ch_ieee);
1484 continue;
1485 }
1486
1487 if (flag_no_6g_freq &&
1488 WLAN_REG_IS_6GHZ_CHAN_FREQ(chan->dfs_ch_freq)) {
1489 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1490 "skip 6 GHz channel=%d", chan->dfs_ch_ieee);
1491 continue;
1492 }
1493
1494 if (flag_no_dfs_chan &&
1495 (chan->dfs_ch_flagext & WLAN_CHAN_DFS)) {
1496 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1497 "skip dfs channel=%d", chan->dfs_ch_ieee);
1498 continue;
1499 }
1500
1501 if (flag_no_japan_w53 &&
1502 DFS_IS_CHAN_JAPAN_W53_FREQ(chan->dfs_ch_freq)) {
1503 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1504 "skip japan W53 channel=%d",
1505 chan->dfs_ch_ieee);
1506 continue;
1507 }
1508
1509 if (dfs_is_freq_in_nol(dfs, chan->dfs_ch_freq)) {
1510 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1511 "skip nol channel=%d", chan->dfs_ch_ieee);
1512 continue;
1513 }
1514
1515 random_chan_freq_list[*random_chan_cnt] = chan->dfs_ch_freq;
1516 *random_chan_cnt += 1;
1517 }
1518 }
1519 #endif
1520
1521 /**
1522 * dfs_remove_spruce_spur_channels_for_bw_20_40() - API to remove the
1523 * spur channels in spruce if current bw is 20/40MHz.
1524 * @freq_list: Input list from which spur channels are removed.
1525 * @freq_count: Input list count.
1526 *
1527 * return: void.
1528 */
1529 static void
dfs_remove_spruce_spur_channels_for_bw_20_40(uint16_t * freq_list,uint8_t freq_count)1530 dfs_remove_spruce_spur_channels_for_bw_20_40(uint16_t *freq_list,
1531 uint8_t freq_count)
1532 {
1533 uint8_t i;
1534
1535 for (i = 0; i < freq_count; i++) {
1536 if (DFS_IS_CHAN_SPRUCE_SPUR_FREQ_20_40_MHZ(freq_list[i]))
1537 freq_list[i] = 0;
1538 }
1539 }
1540
1541 #ifdef CONFIG_CHAN_FREQ_API
dfs_prepare_random_channel_for_freq(struct wlan_dfs * dfs,struct dfs_channel * chan_list,uint32_t chan_cnt,uint32_t flags,struct ch_params * chan_params,uint8_t dfs_region,struct dfs_acs_info * acs_info)1542 uint16_t dfs_prepare_random_channel_for_freq(struct wlan_dfs *dfs,
1543 struct dfs_channel *chan_list,
1544 uint32_t chan_cnt,
1545 uint32_t flags,
1546 struct ch_params *chan_params,
1547 uint8_t dfs_region,
1548 struct dfs_acs_info *acs_info)
1549 {
1550 int i = 0;
1551 uint8_t final_cnt = 0;
1552 uint16_t target_freq = 0;
1553 uint16_t *random_chan_freq_list = NULL;
1554 uint32_t random_chan_cnt = 0;
1555 uint16_t flag_no_weather = 0;
1556 uint16_t *leakage_adjusted_lst;
1557 uint16_t final_lst[NUM_CHANNELS] = {0};
1558 uint16_t *chan_wd = (uint16_t *)&chan_params->ch_width;
1559 bool flag_no_spur_leakage_adj_chans = false;
1560
1561 if (!chan_list || !chan_cnt) {
1562 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1563 "Invalid params %pK, chan_cnt=%d",
1564 chan_list, chan_cnt);
1565 return 0;
1566 }
1567
1568 if (*chan_wd < DFS_CH_WIDTH_20MHZ || *chan_wd > DFS_CH_WIDTH_320MHZ) {
1569 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1570 "Invalid chan_wd %d", *chan_wd);
1571 return 0;
1572 }
1573
1574 random_chan_freq_list =
1575 qdf_mem_malloc(chan_cnt * sizeof(*random_chan_freq_list));
1576 if (!random_chan_freq_list)
1577 return 0;
1578
1579 dfs_apply_rules_for_freq(dfs, flags, random_chan_freq_list,
1580 &random_chan_cnt, chan_list, chan_cnt,
1581 dfs_region, acs_info);
1582 flag_no_weather = (dfs_region == DFS_ETSI_REGION) ?
1583 flags & DFS_RANDOM_CH_FLAG_NO_WEATHER_CH : 0;
1584 flag_no_spur_leakage_adj_chans =
1585 flags & DFS_RANDOM_CH_FLAG_NO_SPRUCE_SPUR_ADJ_CH;
1586
1587 /* list adjusted after leakage has been marked */
1588 leakage_adjusted_lst = qdf_mem_malloc(random_chan_cnt *
1589 sizeof(*leakage_adjusted_lst));
1590 if (!leakage_adjusted_lst) {
1591 qdf_mem_free(random_chan_freq_list);
1592 return 0;
1593 }
1594
1595 if (flag_no_spur_leakage_adj_chans &&
1596 (*chan_wd == DFS_CH_WIDTH_20MHZ ||
1597 *chan_wd == DFS_CH_WIDTH_40MHZ))
1598 dfs_remove_spruce_spur_channels_for_bw_20_40(
1599 random_chan_freq_list,
1600 random_chan_cnt);
1601 do {
1602 int ret;
1603
1604 qdf_mem_copy(leakage_adjusted_lst, random_chan_freq_list,
1605 random_chan_cnt * sizeof(*leakage_adjusted_lst));
1606 ret = dfs_mark_leaking_chan_for_freq(dfs, *chan_wd,
1607 random_chan_cnt,
1608 leakage_adjusted_lst);
1609 if (QDF_IS_STATUS_ERROR(ret)) {
1610 qdf_mem_free(random_chan_freq_list);
1611 qdf_mem_free(leakage_adjusted_lst);
1612 return 0;
1613 }
1614
1615 if (*chan_wd == DFS_CH_WIDTH_20MHZ) {
1616 /*
1617 * PASS: 3 - from leakage_adjusted_lst, prepare valid
1618 * ch list and use random number from that
1619 */
1620 for (i = 0; i < random_chan_cnt; i++) {
1621 if (leakage_adjusted_lst[i] == 0)
1622 continue;
1623 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1624 "Chan freq =%d added to available list",
1625 leakage_adjusted_lst[i]);
1626 final_lst[final_cnt] = leakage_adjusted_lst[i];
1627 final_cnt++;
1628 }
1629 target_freq = dfs_get_rand_from_lst_for_freq(dfs,
1630 final_lst,
1631 final_cnt);
1632 break;
1633 }
1634 target_freq = dfs_find_ch_with_fallback_for_freq(
1635 dfs, chan_wd, &chan_params->mhz_freq_seg1,
1636 leakage_adjusted_lst, random_chan_cnt);
1637
1638 /* Since notion of 80+80 is not present in the regulatory
1639 * channel the function may return invalid 80+80 channels for
1640 * some devices (e.g. Pine). Therefore, check if we need to
1641 * correct it by checking the following condition.
1642 */
1643 if ((*chan_wd == DFS_CH_WIDTH_80P80MHZ) &&
1644 (flags & DFS_RANDOM_CH_FLAG_RESTRICTED_80P80_ENABLED) &&
1645 target_freq) {
1646 wlan_reg_set_channel_params_for_pwrmode(
1647 dfs->dfs_pdev_obj,
1648 target_freq,
1649 0, chan_params,
1650 REG_CURRENT_PWR_MODE);
1651 if (!(CHAN_WITHIN_RESTRICTED_80P80(
1652 chan_params->mhz_freq_seg0,
1653 chan_params->mhz_freq_seg1))) {
1654 *chan_wd = DFS_CH_WIDTH_160MHZ;
1655 target_freq =
1656 dfs_find_ch_with_fallback_for_freq(
1657 dfs, chan_wd,
1658 &chan_params->mhz_freq_seg1,
1659 leakage_adjusted_lst,
1660 random_chan_cnt);
1661 }
1662 }
1663
1664 /*
1665 * When flag_no_weather is set, avoid usage of Adjacent
1666 * weather radar channel in HT40 mode as extension channel
1667 * will be on 5600.
1668 */
1669 if (flag_no_weather &&
1670 (target_freq ==
1671 DFS_ADJACENT_WEATHER_RADAR_CHANNEL_FREQ) &&
1672 (*chan_wd == DFS_CH_WIDTH_40MHZ)) {
1673 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1674 "skip weather adjacent ch freq =%d\n",
1675 target_freq);
1676 continue;
1677 }
1678
1679 /*
1680 * Spur or leakage transmissions is observed in Spruce HW in
1681 * frequencies from 5260MHz to 5320MHz when one of the following
1682 * conditions is true,
1683 * i) The AP is transmitting in 52/56/60/64 in 80MHz mode and
1684 * then the AP moves to the adjacent channel 36/44/48 in 80MHz
1685 * mode and starts transmitting.
1686 * ii) The AP is transmitting in 36/44/48/52/56/60/64 in 160MHz
1687 * mode and then the AP moves to the adjacent channel 36/44/48
1688 * in 80MHz mode and starts transmitting.
1689 *
1690 * The random channel selection algorithm prevents the channel
1691 * movement mentioned above, thereby eliminating the leakage.
1692 */
1693 if (flag_no_spur_leakage_adj_chans &&
1694 DFS_IS_SPRUCE_SPUR_AVOID_FREQS(target_freq) &&
1695 *chan_wd == DFS_CH_WIDTH_80MHZ) {
1696 dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1697 "skip spruce spur causing (adjacent) channel=%hu",
1698 target_freq);
1699 continue;
1700 }
1701
1702 if (target_freq)
1703 break;
1704 } while (true);
1705
1706 qdf_mem_free(random_chan_freq_list);
1707 qdf_mem_free(leakage_adjusted_lst);
1708 dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "target_freq = %d",
1709 target_freq);
1710
1711 return target_freq;
1712 }
1713 #endif
1714