xref: /wlan-dirver/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs_random_chan_sel.c (revision 1397a33f48ea6455be40871470b286e535820eb8)
1 /*
2  * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include "../dfs.h"
20 #include "../dfs_random_chan_sel.h"
21 #include <qdf_mc_timer.h>
22 #include <wlan_utility.h>
23 
24 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION
25 /*
26  * TODO: At present SAP Channel leakage matrix for ch 144
27  * is not available from system's team. So to play it safe
28  * and avoid crash if channel 144 is request, in following
29  * matix channel 144 is added such that it will cause code
30  * to avoid selecting channel 144.
31  *
32  * THESE ENTRIES SHOULD BE REPLACED WITH CORRECT VALUES AS
33  * PROVIDED BY SYSTEM'S TEAM.
34  */
35 
36 /* channel tx leakage table - ht80 */
37 struct dfs_matrix_tx_leak_info ht80_chan[] = {
38 	{52,
39 	 {{36, 148}, {40, 199},
40 	  {44, 193}, {48, 197},
41 	  {52, DFS_TX_LEAKAGE_MIN}, {56, 153},
42 	  {60, 137}, {64, 134},
43 	  {100, 358}, {104, 350},
44 	  {108, 404}, {112, 344},
45 	  {116, 424}, {120, 429},
46 	  {124, 437}, {128, 435},
47 	  {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX},
48 	  {140, DFS_TX_LEAKAGE_MAX},
49 	  {144, DFS_TX_LEAKAGE_MIN}
50 	  } },
51 
52 
53 	{56,
54 	 {{36, 171}, {40, 178},
55 	  {44, 171}, {48, 178},
56 	  {52, DFS_TX_LEAKAGE_MIN}, {56, DFS_TX_LEAKAGE_MIN},
57 	  {60, DFS_TX_LEAKAGE_MIN}, {64, 280},
58 	  {100, 351}, {104, 376},
59 	  {108, 362}, {112, 362},
60 	  {116, 403}, {120, 397},
61 	  {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX},
62 	  {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX},
63 	  {140, DFS_TX_LEAKAGE_MAX},
64 	  {144, DFS_TX_LEAKAGE_MIN}
65 	  } },
66 
67 	{60,
68 	 {{36, 156}, {40, 146},
69 	  {44, DFS_TX_LEAKAGE_MIN}, {48, DFS_TX_LEAKAGE_MIN},
70 	  {52, 180}, {56, DFS_TX_LEAKAGE_MIN},
71 	  {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN},
72 	  {100, 376}, {104, 360},
73 	  {108, DFS_TX_LEAKAGE_MAX}, {112, DFS_TX_LEAKAGE_MAX},
74 	  {116, 395}, {120, 399},
75 	  {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX},
76 	  {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX},
77 	  {140, DFS_TX_LEAKAGE_MAX},
78 	  {144, DFS_TX_LEAKAGE_MIN}
79 	  } },
80 
81 	{64,
82 	 {{36, 217}, {40, 221},
83 	  {44, DFS_TX_LEAKAGE_MIN}, {48, DFS_TX_LEAKAGE_MIN},
84 	  {52, 176}, {56, 176},
85 	  {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN},
86 	  {100, 384}, {104, 390},
87 	  {108, DFS_TX_LEAKAGE_MAX}, {112, DFS_TX_LEAKAGE_MAX},
88 	  {116, 375}, {120, 374},
89 	  {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX},
90 	  {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX},
91 	  {140, DFS_TX_LEAKAGE_MAX},
92 	  {144, DFS_TX_LEAKAGE_MIN}
93 	  } },
94 
95 	{100,
96 	 {{36, 357}, {40, 326},
97 	  {44, 321}, {48, 326},
98 	  {52, 378}, {56, 396},
99 	  {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX},
100 	  {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN},
101 	  {108, 196}, {112, 116},
102 	  {116, 166}, {120, DFS_TX_LEAKAGE_MIN},
103 	  {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN},
104 	  {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN},
105 	  {140, DFS_TX_LEAKAGE_MIN},
106 	  {144, DFS_TX_LEAKAGE_MIN}
107 	  } },
108 
109 	{104,
110 	 {{36, 325}, {40, 325},
111 	  {44, 305}, {48, 352},
112 	  {52, 411}, {56, 411},
113 	  {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX},
114 	  {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN},
115 	  {108, DFS_TX_LEAKAGE_MIN}, {112, 460},
116 	  {116, 198}, {120, DFS_TX_LEAKAGE_MIN},
117 	  {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN},
118 	  {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN},
119 	  {140, DFS_TX_LEAKAGE_MIN},
120 	  {144, DFS_TX_LEAKAGE_MIN}
121 	  } },
122 
123 	{108,
124 	 {{36, 304}, {40, 332},
125 	  {44, 310}, {48, 335},
126 	  {52, 431}, {56, 391},
127 	  {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX},
128 	  {100, 280}, {104, DFS_TX_LEAKAGE_MIN},
129 	  {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN},
130 	  {116, 185}, {120, DFS_TX_LEAKAGE_MIN},
131 	  {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN},
132 	  {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN},
133 	  {140, DFS_TX_LEAKAGE_MIN},
134 	  {144, DFS_TX_LEAKAGE_MIN}
135 	  } },
136 
137 	{112,
138 	 {{36, 327}, {40, 335},
139 	  {44, 331}, {48, 345},
140 	  {52, 367}, {56, 401},
141 	  {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX},
142 	  {100, 131}, {104, 132},
143 	  {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN},
144 	  {116, 189}, {120, DFS_TX_LEAKAGE_MIN},
145 	  {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN},
146 	  {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN},
147 	  {140, DFS_TX_LEAKAGE_MIN},
148 	  {144, DFS_TX_LEAKAGE_MIN}
149 	  } },
150 
151 	{116,
152 	 {{36, 384}, {40, 372},
153 	  {44, 389}, {48, 396},
154 	  {52, 348}, {56, 336},
155 	  {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX},
156 	  {100, 172}, {104, 169},
157 	  {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN},
158 	  {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN},
159 	  {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN},
160 	  {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN},
161 	  {140, DFS_TX_LEAKAGE_MIN},
162 	  {144, DFS_TX_LEAKAGE_MIN}
163 	  } },
164 
165 	{120,
166 	 {{36, 395}, {40, 419},
167 	  {44, 439}, {48, 407},
168 	  {52, 321}, {56, 334},
169 	  {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX},
170 	  {100, 134}, {104, 186},
171 	  {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN},
172 	  {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN},
173 	  {124, DFS_TX_LEAKAGE_MIN}, {128, 159},
174 	  {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN},
175 	  {140, DFS_TX_LEAKAGE_MIN},
176 	  {144, DFS_TX_LEAKAGE_MIN}
177 	  } },
178 
179 	{124,
180 	 {{36, 469}, {40, 433},
181 	  {44, 434}, {48, 435},
182 	  {52, 332}, {56, 345},
183 	  {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX},
184 	  {100, 146}, {104, 177},
185 	  {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN},
186 	  {116, 350}, {120, DFS_TX_LEAKAGE_MIN},
187 	  {124, DFS_TX_LEAKAGE_MIN}, {128, 138},
188 	  {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN},
189 	  {140, DFS_TX_LEAKAGE_MIN},
190 	  {144, DFS_TX_LEAKAGE_MIN}
191 	  } },
192 
193 	{128,
194 	 {{36, 408}, {40, 434},
195 	  {44, 449}, {48, 444},
196 	  {52, 341}, {56, 374},
197 	  {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX},
198 	  {100, 205}, {104, 208},
199 	  {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN},
200 	  {116, 142}, {120, DFS_TX_LEAKAGE_MIN},
201 	  {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN},
202 	  {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN},
203 	  {140, DFS_TX_LEAKAGE_MIN},
204 	  {144, DFS_TX_LEAKAGE_MIN}
205 	  } },
206 
207 	{132,
208 	 {{36, DFS_TX_LEAKAGE_MAX}, {40, DFS_TX_LEAKAGE_MAX},
209 	  {44, DFS_TX_LEAKAGE_MAX}, {48, DFS_TX_LEAKAGE_MAX},
210 	  {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX},
211 	  {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN},
212 	  {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN},
213 	  {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN},
214 	  {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN},
215 	  {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN},
216 	  {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN},
217 	  {140, DFS_TX_LEAKAGE_MIN},
218 	  {144, DFS_TX_LEAKAGE_MIN}
219 	  } },
220 
221 	{136,
222 	 {{36, DFS_TX_LEAKAGE_MAX}, {40, DFS_TX_LEAKAGE_MAX},
223 	  {44, DFS_TX_LEAKAGE_MAX}, {48, DFS_TX_LEAKAGE_MAX},
224 	  {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX},
225 	  {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN},
226 	  {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN},
227 	  {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN},
228 	  {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN},
229 	  {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN},
230 	  {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN},
231 	  {140, DFS_TX_LEAKAGE_MIN},
232 	  {144, DFS_TX_LEAKAGE_MIN}
233 	  } },
234 
235 	{140,
236 	 {{36, DFS_TX_LEAKAGE_MAX}, {40, DFS_TX_LEAKAGE_MAX},
237 	  {44, DFS_TX_LEAKAGE_MAX}, {48, DFS_TX_LEAKAGE_MAX},
238 	  {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX},
239 	  {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN},
240 	  {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN},
241 	  {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN},
242 	  {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN},
243 	  {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN},
244 	  {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN},
245 	  {144, DFS_TX_LEAKAGE_MIN}
246 	  } },
247 
248 	{144,
249 	 {{36, DFS_TX_LEAKAGE_MAX}, {40, DFS_TX_LEAKAGE_MAX},
250 	  {44, DFS_TX_LEAKAGE_MAX}, {48, DFS_TX_LEAKAGE_MAX},
251 	  {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX},
252 	  {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN},
253 	  {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN},
254 	  {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN},
255 	  {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN},
256 	  {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN},
257 	  {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN},
258 	  {144, DFS_TX_LEAKAGE_MIN}
259 	  } },
260 };
261 
262 /* channel tx leakage table - ht40 */
263 struct dfs_matrix_tx_leak_info ht40_chan[] = {
264 	{52,
265 	 {{36, DFS_TX_LEAKAGE_AUTO_MIN}, {40, DFS_TX_LEAKAGE_AUTO_MIN},
266 	  {44, 230}, {48, 230},
267 	  {52, DFS_TX_LEAKAGE_MIN}, {56, DFS_TX_LEAKAGE_MIN},
268 	  {60, DFS_TX_LEAKAGE_AUTO_MIN}, {64, DFS_TX_LEAKAGE_AUTO_MIN},
269 	  {100, 625}, {104, 323},
270 	  {108, 646}, {112, 646},
271 	  {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX},
272 	  {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX},
273 	  {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX},
274 	  {140, DFS_TX_LEAKAGE_MAX},
275 	  {144, DFS_TX_LEAKAGE_MIN}
276 	  } },
277 
278 	{56,
279 	 {{36, DFS_TX_LEAKAGE_AUTO_MIN}, {40, DFS_TX_LEAKAGE_AUTO_MIN},
280 	  {44, DFS_TX_LEAKAGE_AUTO_MIN}, {48, DFS_TX_LEAKAGE_AUTO_MIN},
281 	  {52, DFS_TX_LEAKAGE_MIN}, {56, DFS_TX_LEAKAGE_MIN},
282 	  {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN},
283 	  {100, 611}, {104, 611},
284 	  {108, 617}, {112, 617},
285 	  {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX},
286 	  {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX},
287 	  {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX},
288 	  {140, DFS_TX_LEAKAGE_MAX},
289 	  {144, DFS_TX_LEAKAGE_MIN}
290 	  } },
291 
292 	{60,
293 	 {{36, DFS_TX_LEAKAGE_AUTO_MIN}, {40, DFS_TX_LEAKAGE_AUTO_MIN},
294 	  {44, DFS_TX_LEAKAGE_AUTO_MIN}, {48, DFS_TX_LEAKAGE_AUTO_MIN},
295 	  {52, 190}, {56, 190},
296 	  {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN},
297 	  {100, 608}, {104, 608},
298 	  {108, 623}, {112, 623},
299 	  {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX},
300 	  {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX},
301 	  {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX},
302 	  {140, DFS_TX_LEAKAGE_MAX},
303 	  {144, DFS_TX_LEAKAGE_MIN}
304 	  } },
305 
306 	{64,
307 	 {{36, DFS_TX_LEAKAGE_AUTO_MIN}, {40, DFS_TX_LEAKAGE_AUTO_MIN},
308 	  {44, DFS_TX_LEAKAGE_AUTO_MIN}, {48, DFS_TX_LEAKAGE_AUTO_MIN},
309 	  {52, 295}, {56, 295},
310 	  {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN},
311 	  {100, 594}, {104, 594},
312 	  {108, 625}, {112, 625},
313 	  {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX},
314 	  {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX},
315 	  {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX},
316 	  {140, DFS_TX_LEAKAGE_MAX},
317 	  {144, DFS_TX_LEAKAGE_MIN}
318 	  } },
319 
320 	{100,
321 	 {{36, 618}, {40, 618},
322 	  {44, 604}, {48, 604},
323 	  {52, 596}, {56, 596},
324 	  {60, 584}, {64, 584},
325 	  {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN},
326 	  {108, 299}, {112, 299},
327 	  {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN},
328 	  {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN},
329 	  {132, 538}, {136, 538},
330 	  {140, 598},
331 	  {144, DFS_TX_LEAKAGE_MIN}
332 	  } },
333 
334 	{104,
335 	 {{36, 636}, {40, 636},
336 	  {44, 601}, {48, 601},
337 	  {52, 616}, {56, 616},
338 	  {60, 584}, {64, 584},
339 	  {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN},
340 	  {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN},
341 	  {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN},
342 	  {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN},
343 	  {132, 553}, {136, 553},
344 	  {140, 568},
345 	  {144, DFS_TX_LEAKAGE_MIN}
346 	  } },
347 
348 	{108,
349 	 {{36, 600}, {40, 600},
350 	  {44, 627}, {48, 627},
351 	  {52, 611}, {56, 611},
352 	  {60, 611}, {64, 611},
353 	  {100, 214}, {104, 214},
354 	  {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN},
355 	  {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN},
356 	  {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN},
357 	  {132, DFS_TX_LEAKAGE_AUTO_MIN}, {136, DFS_TX_LEAKAGE_AUTO_MIN},
358 	  {140, 534},
359 	  {144, DFS_TX_LEAKAGE_MIN}
360 	  } },
361 
362 	{112,
363 	 {{36, 645}, {40, 645},
364 	  {44, 641}, {48, 641},
365 	  {52, 618}, {56, 618},
366 	  {60, 612}, {64, 612},
367 	  {100, 293}, {104, 293},
368 	  {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN},
369 	  {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN},
370 	  {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN},
371 	  {132, DFS_TX_LEAKAGE_AUTO_MIN}, {136, DFS_TX_LEAKAGE_AUTO_MIN},
372 	  {140, 521},
373 	  {144, DFS_TX_LEAKAGE_MIN}
374 	  } },
375 
376 	{116,
377 	 {{36, 661}, {40, 661},
378 	  {44, 624}, {48, 624},
379 	  {52, 634}, {56, 634},
380 	  {60, 611}, {64, 611},
381 	  {100, DFS_TX_LEAKAGE_AUTO_MIN}, {104, DFS_TX_LEAKAGE_AUTO_MIN},
382 	  {108, 217}, {112, 217},
383 	  {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN},
384 	  {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN},
385 	  {132, DFS_TX_LEAKAGE_AUTO_MIN}, {136, DFS_TX_LEAKAGE_AUTO_MIN},
386 	  {140, DFS_TX_LEAKAGE_AUTO_MIN},
387 	  {144, DFS_TX_LEAKAGE_MIN}
388 	  } },
389 
390 	{120,
391 	 {{36, 667}, {40, 667},
392 	  {44, 645}, {48, 645},
393 	  {52, 633}, {56, 633},
394 	  {60, 619}, {64, 619},
395 	  {100, DFS_TX_LEAKAGE_AUTO_MIN}, {104, DFS_TX_LEAKAGE_AUTO_MIN},
396 	  {108, 291}, {112, 291},
397 	  {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN},
398 	  {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN},
399 	  {132, DFS_TX_LEAKAGE_AUTO_MIN}, {136, DFS_TX_LEAKAGE_AUTO_MIN},
400 	  {140, DFS_TX_LEAKAGE_AUTO_MIN},
401 	  {144, DFS_TX_LEAKAGE_MIN}
402 	  } },
403 
404 	{124,
405 	 {{36, 676}, {40, 676},
406 	  {44, 668}, {48, 668},
407 	  {52, 595}, {56, 595},
408 	  {60, 622}, {64, 622},
409 	  {100, DFS_TX_LEAKAGE_AUTO_MIN}, {104, DFS_TX_LEAKAGE_AUTO_MIN},
410 	  {108, DFS_TX_LEAKAGE_AUTO_MIN}, {112, DFS_TX_LEAKAGE_AUTO_MIN},
411 	  {116, 225}, {120, 225},
412 	  {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN},
413 	  {132, DFS_TX_LEAKAGE_AUTO_MIN}, {136, DFS_TX_LEAKAGE_AUTO_MIN},
414 	  {140, DFS_TX_LEAKAGE_AUTO_MIN},
415 	  {144, DFS_TX_LEAKAGE_MIN}
416 	  } },
417 
418 	{128,
419 	 {{36, 678}, {40, 678},
420 	  {44, 664}, {48, 664},
421 	  {52, 651}, {56, 651},
422 	  {60, 643}, {64, 643},
423 	  {100, DFS_TX_LEAKAGE_AUTO_MIN}, {104, DFS_TX_LEAKAGE_AUTO_MIN},
424 	  {108, DFS_TX_LEAKAGE_AUTO_MIN}, {112, DFS_TX_LEAKAGE_AUTO_MIN},
425 	  {116, 293}, {120, 293},
426 	  {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN},
427 	  {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN},
428 	  {140, DFS_TX_LEAKAGE_AUTO_MIN},
429 	  {144, DFS_TX_LEAKAGE_MIN}
430 	  } },
431 
432 	{132,
433 	 {{36, 689}, {40, 689},
434 	  {44, 669}, {48, 669},
435 	  {52, 662}, {56, 662},
436 	  {60, 609}, {64, 609},
437 	  {100, 538}, {104, 538},
438 	  {108, DFS_TX_LEAKAGE_AUTO_MIN}, {112, DFS_TX_LEAKAGE_AUTO_MIN},
439 	  {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN},
440 	  {124, 247}, {128, 247},
441 	  {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN},
442 	  {140, DFS_TX_LEAKAGE_MIN},
443 	  {144, DFS_TX_LEAKAGE_MIN}
444 	  } },
445 
446 	{136,
447 	 {{36, 703}, {40, 703},
448 	  {44, 688}, {48, DFS_TX_LEAKAGE_MIN},
449 	  {52, 671}, {56, 671},
450 	  {60, 658}, {64, 658},
451 	  {100, 504}, {104, 504},
452 	  {108, DFS_TX_LEAKAGE_AUTO_MIN}, {112, DFS_TX_LEAKAGE_AUTO_MIN},
453 	  {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN},
454 	  {124, 289}, {128, 289},
455 	  {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN},
456 	  {140, DFS_TX_LEAKAGE_MIN},
457 	  {144, DFS_TX_LEAKAGE_MIN}
458 	  } },
459 
460 	{140,
461 	 {{36, 695}, {40, 695},
462 	  {44, 684}, {48, 684},
463 	  {52, 664}, {56, 664},
464 	  {60, 658}, {64, 658},
465 	  {100, 601}, {104, 601},
466 	  {108, 545}, {112, 545},
467 	  {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN},
468 	  {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN},
469 	  {132, 262}, {136, 262},
470 	  {140, DFS_TX_LEAKAGE_MIN},
471 	  {144, DFS_TX_LEAKAGE_MIN}
472 	  } },
473 
474 	{144,
475 	 {{36, 695}, {40, 695},
476 	  {44, 684}, {48, 684},
477 	  {52, 664}, {56, 664},
478 	  {60, 658}, {64, 658},
479 	  {100, 601}, {104, 601},
480 	  {108, 545}, {112, 545},
481 	  {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN},
482 	  {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN},
483 	  {132, 262}, {136, 262},
484 	  {140, DFS_TX_LEAKAGE_MIN},
485 	  {144, DFS_TX_LEAKAGE_MIN}
486 	  } },
487 };
488 
489 /* channel tx leakage table - ht20 */
490 struct dfs_matrix_tx_leak_info ht20_chan[] = {
491 	{52,
492 	 {{36, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 286},
493 	  {44, 225}, {48, 121},
494 	  {52, DFS_TX_LEAKAGE_MIN}, {56, DFS_TX_LEAKAGE_MIN},
495 	  {60, 300}, {64, DFS_TX_LEAKAGE_AUTO_MIN},
496 	  {100, 637}, {104, DFS_TX_LEAKAGE_MAX},
497 	  {108, DFS_TX_LEAKAGE_MAX}, {112, DFS_TX_LEAKAGE_MAX},
498 	  {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX},
499 	  {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX},
500 	  {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX},
501 	  {140, DFS_TX_LEAKAGE_MAX},
502 	  {144, DFS_TX_LEAKAGE_MIN}
503 	  } },
504 
505 	{56,
506 	 {{36, 468}, {40, DFS_TX_LEAKAGE_AUTO_MIN},
507 	  {44, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 206},
508 	  {52, DFS_TX_LEAKAGE_MIN}, {56, DFS_TX_LEAKAGE_MIN},
509 	  {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN},
510 	  {100, DFS_TX_LEAKAGE_MAX}, {104, DFS_TX_LEAKAGE_MAX},
511 	  {108, DFS_TX_LEAKAGE_MAX}, {112, DFS_TX_LEAKAGE_MAX},
512 	  {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX},
513 	  {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX},
514 	  {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX},
515 	  {140, DFS_TX_LEAKAGE_MAX},
516 	  {144, DFS_TX_LEAKAGE_MIN}
517 	  } },
518 
519 	{60,
520 	 {{36, 507}, {40, 440},
521 	  {44, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 313},
522 	  {52, DFS_TX_LEAKAGE_MIN}, {56, DFS_TX_LEAKAGE_MIN},
523 	  {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN},
524 	  {100, DFS_TX_LEAKAGE_MAX}, {104, DFS_TX_LEAKAGE_MAX},
525 	  {108, DFS_TX_LEAKAGE_MAX}, {112, DFS_TX_LEAKAGE_MAX},
526 	  {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX},
527 	  {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX},
528 	  {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX},
529 	  {140, DFS_TX_LEAKAGE_MAX},
530 	  {144, DFS_TX_LEAKAGE_MIN}
531 	  } },
532 
533 	{64,
534 	 {{36, 516}, {40, 520},
535 	  {44, 506}, {48, DFS_TX_LEAKAGE_AUTO_MIN},
536 	  {52, 301}, {56, 258},
537 	  {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN},
538 	  {100, 620}, {104, 617},
539 	  {108, DFS_TX_LEAKAGE_MAX}, {112, DFS_TX_LEAKAGE_MAX},
540 	  {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX},
541 	  {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX},
542 	  {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX},
543 	  {140, DFS_TX_LEAKAGE_MAX},
544 	  {144, DFS_TX_LEAKAGE_MIN}
545 	  } },
546 
547 	{100,
548 	 {{36, 616}, {40, 601},
549 	  {44, 604}, {48, 589},
550 	  {52, 612}, {56, 592},
551 	  {60, 590}, {64, 582},
552 	  {100, DFS_TX_LEAKAGE_MIN}, {104, 131},
553 	  {108, DFS_TX_LEAKAGE_AUTO_MIN}, {112, DFS_TX_LEAKAGE_AUTO_MIN},
554 	  {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 522},
555 	  {124, 571}, {128, 589},
556 	  {132, 593}, {136, 598},
557 	  {140, 594},
558 	  {144, DFS_TX_LEAKAGE_MIN},
559 	  } },
560 
561 	{104,
562 	 {{36, 622}, {40, 624},
563 	  {44, 618}, {48, 610},
564 	  {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX},
565 	  {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX},
566 	  {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN},
567 	  {108, DFS_TX_LEAKAGE_MIN}, {112, 463},
568 	  {116, 483}, {120, 503},
569 	  {124, 523}, {128, 565},
570 	  {132, 570}, {136, 588},
571 	  {140, 585},
572 	  {144, DFS_TX_LEAKAGE_MIN},
573 	  } },
574 
575 	{108,
576 	 {{36, 620}, {40, 638},
577 	  {44, 611}, {48, 614},
578 	  {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX},
579 	  {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX},
580 	  {100, 477}, {104, DFS_TX_LEAKAGE_MIN},
581 	  {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN},
582 	  {116, 477}, {120, 497},
583 	  {124, 517}, {128, 537},
584 	  {132, 557}, {136, 577},
585 	  {140, 603},
586 	  {144, DFS_TX_LEAKAGE_MIN},
587 	  } },
588 
589 	{112,
590 	 {{36, 636}, {40, 623},
591 	  {44, 638}, {48, 628},
592 	  {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX},
593 	  {60, DFS_TX_LEAKAGE_MAX}, {64, 606},
594 	  {100, 501}, {104, 481},
595 	  {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN},
596 	  {116, DFS_TX_LEAKAGE_MIN}, {120, 481},
597 	  {124, 501}, {128, 421},
598 	  {132, 541}, {136, 561},
599 	  {140, 583},
600 	  {144, DFS_TX_LEAKAGE_MIN},
601 	  } },
602 
603 	{116,
604 	 {{36, 646}, {40, 648},
605 	  {44, 633}, {48, 634},
606 	  {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX},
607 	  {60, 615}, {64, 594},
608 	  {100, 575}, {104, 554},
609 	  {108, 534}, {112, DFS_TX_LEAKAGE_MIN},
610 	  {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN},
611 	  {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN},
612 	  {132, 534}, {136, 554},
613 	  {140, 574},
614 	  {144, DFS_TX_LEAKAGE_MIN},
615 	  } },
616 
617 	{120,
618 	 {{36, 643}, {40, 649},
619 	  {44, 654}, {48, 629},
620 	  {52, DFS_TX_LEAKAGE_MAX}, {56, 621},
621 	  {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX},
622 	  {100, 565}, {104, 545},
623 	  {108, 525}, {112, 505},
624 	  {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN},
625 	  {124, DFS_TX_LEAKAGE_MIN}, {128, 505},
626 	  {132, 525}, {136, 545},
627 	  {140, 565},
628 	  {144, DFS_TX_LEAKAGE_MIN},
629 	  } },
630 
631 	{124,
632 	 {{36, 638}, {40, 657},
633 	  {44, 663}, {48, 649},
634 	  {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX},
635 	  {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX},
636 	  {100, 581}, {104, 561},
637 	  {108, 541}, {112, 521},
638 	  {116, 499}, {120, DFS_TX_LEAKAGE_MIN},
639 	  {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN},
640 	  {132, 499}, {136, 519},
641 	  {140, 539},
642 	  {144, DFS_TX_LEAKAGE_MIN}
643 	  } },
644 
645 	{128,
646 	 {{36, 651}, {40, 651},
647 	  {44, 674}, {48, 640},
648 	  {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX},
649 	  {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX},
650 	  {100, 603}, {104, 560},
651 	  {108, 540}, {112, 520},
652 	  {116, 499}, {120, 479},
653 	  {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN},
654 	  {132, DFS_TX_LEAKAGE_MIN}, {136, 479},
655 	  {140, 499},
656 	  {144, DFS_TX_LEAKAGE_MIN}
657 	  } },
658 
659 	{132,
660 	 {{36, 643}, {40, 668},
661 	  {44, 651}, {48, 657},
662 	  {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX},
663 	  {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX},
664 	  {100, DFS_TX_LEAKAGE_MAX}, {104, 602},
665 	  {108, 578}, {112, 570},
666 	  {116, 550}, {120, 530},
667 	  {124, 510}, {128, DFS_TX_LEAKAGE_MIN},
668 	  {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN},
669 	  {140, 490},
670 	  {144, DFS_TX_LEAKAGE_MIN}
671 	  } },
672 
673 	{136,
674 	 {{36, 654}, {40, 667},
675 	  {44, 666}, {48, 642},
676 	  {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX},
677 	  {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX},
678 	  {100, DFS_TX_LEAKAGE_MAX}, {104, DFS_TX_LEAKAGE_MAX},
679 	  {108, DFS_TX_LEAKAGE_MAX}, {112, 596},
680 	  {116, 555}, {120, 535},
681 	  {124, 515}, {128, 495},
682 	  {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN},
683 	  {140, DFS_TX_LEAKAGE_MIN},
684 	  {144, DFS_TX_LEAKAGE_MIN}
685 	  } },
686 
687 	{140,
688 	 {{36, 679}, {40, 673},
689 	  {44, 667}, {48, 656},
690 	  {52, 634}, {56, 663},
691 	  {60, 662}, {64, 660},
692 	  {100, DFS_TX_LEAKAGE_MAX}, {104, DFS_TX_LEAKAGE_MAX},
693 	  {108, DFS_TX_LEAKAGE_MAX}, {112, 590},
694 	  {116, 573}, {120, 553},
695 	  {124, 533}, {128, 513},
696 	  {132, 490}, {136, DFS_TX_LEAKAGE_MIN},
697 	  {140, DFS_TX_LEAKAGE_MIN},
698 	  {144, DFS_TX_LEAKAGE_MIN}
699 	  } },
700 
701 	{144,
702 	 {{36, 679}, {40, 673},
703 	  {44, 667}, {48, 656},
704 	  {52, 634}, {56, 663},
705 	  {60, 662}, {64, 660},
706 	  {100, DFS_TX_LEAKAGE_MAX}, {104, DFS_TX_LEAKAGE_MAX},
707 	  {108, DFS_TX_LEAKAGE_MAX}, {112, 590},
708 	  {116, 573}, {120, 553},
709 	  {124, 533}, {128, 513},
710 	  {132, 490}, {136, DFS_TX_LEAKAGE_MIN},
711 	  {140, DFS_TX_LEAKAGE_MIN},
712 	  {144, DFS_TX_LEAKAGE_MIN}
713 	  } },
714 };
715 
716 /*
717  * dfs_find_target_channel_in_channel_matrix() - finds the leakage matrix
718  * @ch_width: target channel width
719  * @NOL_channel: the NOL channel whose leakage matrix is required
720  * @pTarget_chnl_mtrx: pointer to target channel matrix returned.
721  *
722  * This function gives the leakage matrix for given NOL channel and ch_width
723  *
724  * Return: TRUE or FALSE
725  */
726 static bool
727 dfs_find_target_channel_in_channel_matrix(enum phy_ch_width ch_width,
728 				uint8_t NOL_channel,
729 				struct dfs_tx_leak_info **pTarget_chnl_mtrx)
730 {
731 	struct dfs_tx_leak_info *target_chan_matrix = NULL;
732 	struct dfs_matrix_tx_leak_info *pchan_matrix = NULL;
733 	uint32_t nchan_matrix;
734 	int i = 0;
735 
736 	switch (ch_width) {
737 	case CH_WIDTH_20MHZ:
738 		/* HT20 */
739 		pchan_matrix = ht20_chan;
740 		nchan_matrix = QDF_ARRAY_SIZE(ht20_chan);
741 		break;
742 	case CH_WIDTH_40MHZ:
743 		/* HT40 */
744 		pchan_matrix = ht40_chan;
745 		nchan_matrix = QDF_ARRAY_SIZE(ht40_chan);
746 		break;
747 	case CH_WIDTH_80MHZ:
748 		/* HT80 */
749 		pchan_matrix = ht80_chan;
750 		nchan_matrix = QDF_ARRAY_SIZE(ht80_chan);
751 		break;
752 	default:
753 		/* handle exception and fall back to HT20 table */
754 		pchan_matrix = ht20_chan;
755 		nchan_matrix = QDF_ARRAY_SIZE(ht20_chan);
756 		break;
757 	}
758 
759 	for (i = 0; i < nchan_matrix; i++) {
760 		/* find the SAP channel to map the leakage matrix */
761 		if (NOL_channel == pchan_matrix[i].channel) {
762 			target_chan_matrix = pchan_matrix[i].chan_matrix;
763 			break;
764 		}
765 	}
766 
767 	if (NULL == target_chan_matrix) {
768 		return false;
769 	} else {
770 		*pTarget_chnl_mtrx = target_chan_matrix;
771 		return true;
772 	}
773 }
774 
775 QDF_STATUS
776 dfs_mark_leaking_ch(struct wlan_dfs *dfs,
777 		enum phy_ch_width ch_width,
778 		uint8_t temp_ch_lst_sz,
779 		uint8_t *temp_ch_lst)
780 {
781 	struct dfs_tx_leak_info *target_chan_matrix = NULL;
782 	uint32_t         num_channel = (CHAN_ENUM_144 - CHAN_ENUM_36) + 1;
783 	uint32_t         j = 0;
784 	uint32_t         k = 0;
785 	uint8_t          dfs_nol_channel;
786 	struct dfs_nolelem *nol;
787 
788 	nol = dfs->dfs_nol;
789 	while (nol) {
790 		dfs_nol_channel = wlan_freq_to_chan(nol->nol_freq);
791 		if (false == dfs_find_target_channel_in_channel_matrix(
792 					ch_width, dfs_nol_channel,
793 					&target_chan_matrix)) {
794 			/*
795 			 * should never happen, we should always find a table
796 			 * here, if we don't, need a fix here!
797 			 */
798 			dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
799 				"Couldn't find target channel matrix!");
800 			QDF_ASSERT(0);
801 			return QDF_STATUS_E_FAILURE;
802 		}
803 		/*
804 		 * following is based on assumption that both temp_ch_lst
805 		 * and target channel matrix are in increasing order of
806 		 * ch_id
807 		 */
808 		for (j = 0, k = 0; j < temp_ch_lst_sz && k < num_channel;) {
809 			if (temp_ch_lst[j] == 0) {
810 				j++;
811 				continue;
812 			}
813 			if (target_chan_matrix[k].leak_chan != temp_ch_lst[j]) {
814 				k++;
815 				continue;
816 			}
817 			/*
818 			 * check leakage from candidate channel
819 			 * to NOL channel
820 			 */
821 			if (target_chan_matrix[k].leak_lvl <=
822 				dfs->tx_leakage_threshold) {
823 				/*
824 				 * candidate channel will have
825 				 * bad leakage in NOL channel,
826 				 * remove from temp list
827 				 */
828 				dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
829 					"dfs: channel: %d will have bad leakage due to channel: %d\n",
830 					dfs_nol_channel, temp_ch_lst[j]);
831 				temp_ch_lst[j] = 0;
832 			}
833 			j++;
834 			k++;
835 		}
836 		nol = nol->nol_next;
837 	} /* end of loop that selects each NOL */
838 
839 	return QDF_STATUS_SUCCESS;
840 }
841 #else
842 QDF_STATUS
843 dfs_mark_leaking_ch(struct wlan_dfs *dfs,
844 		enum phy_ch_width ch_width,
845 		uint8_t temp_ch_lst_sz,
846 		uint8_t *temp_ch_lst)
847 {
848 	return QDF_STATUS_SUCCESS;
849 }
850 #endif
851 
852 /**
853  * dfs_populate_80mhz_available_channels()- Populate channels for 80MHz using
854  *                                          bitmap
855  * @dfs: Pointer to DFS structure.
856  * @bitmap: bitmap
857  * @avail_chnl: prepared channel list
858  *
859  * Prepare 80MHz channels from the bitmap.
860  *
861  * Return: channel count
862  */
863 static uint8_t dfs_populate_80mhz_available_channels(
864 		struct wlan_dfs *dfs,
865 		struct chan_bonding_bitmap *bitmap,
866 		uint8_t *avail_chnl)
867 {
868 	uint8_t i = 0;
869 	uint8_t chnl_count = 0;
870 	uint8_t start_chan = 0;
871 
872 	for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) {
873 		start_chan = bitmap->chan_bonding_set[i].start_chan;
874 		if (bitmap->chan_bonding_set[i].chan_map ==
875 			DFS_80MHZ_MASK) {
876 			avail_chnl[chnl_count++] = start_chan +
877 				(DFS_NEXT_5GHZ_CHANNEL * 0);
878 			avail_chnl[chnl_count++] = start_chan +
879 				(DFS_NEXT_5GHZ_CHANNEL * 1);
880 			avail_chnl[chnl_count++] = start_chan +
881 				(DFS_NEXT_5GHZ_CHANNEL * 2);
882 			avail_chnl[chnl_count++] = start_chan +
883 				(DFS_NEXT_5GHZ_CHANNEL * 3);
884 		}
885 	}
886 
887 	dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
888 			"channel count %d", chnl_count);
889 
890 	return chnl_count;
891 }
892 
893 /**
894  * dfs_populate_40mhz_available_channels()- Populate channels for 40MHz using
895  *                                          bitmap
896  * @dfs: Pointer to DFS structure.
897  * @bitmap: bitmap
898  * @avail_chnl: prepared channel list
899  *
900  * Prepare 40MHz channels from the bitmap.
901  *
902  * Return: channel count
903  */
904 static uint8_t dfs_populate_40mhz_available_channels(
905 		struct wlan_dfs *dfs,
906 		struct chan_bonding_bitmap *bitmap,
907 		uint8_t *avail_chnl)
908 {
909 	uint8_t i = 0;
910 	uint8_t chnl_count = 0;
911 	uint8_t start_chan = 0;
912 
913 	for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) {
914 		start_chan = bitmap->chan_bonding_set[i].start_chan;
915 		if ((bitmap->chan_bonding_set[i].chan_map &
916 			DFS_40MHZ_MASK_L) == DFS_40MHZ_MASK_L) {
917 			avail_chnl[chnl_count++] = start_chan +
918 				(DFS_NEXT_5GHZ_CHANNEL * 0);
919 			avail_chnl[chnl_count++] = start_chan +
920 				(DFS_NEXT_5GHZ_CHANNEL * 1);
921 		}
922 		if ((bitmap->chan_bonding_set[i].chan_map &
923 			DFS_40MHZ_MASK_H) == DFS_40MHZ_MASK_H) {
924 			avail_chnl[chnl_count++] = start_chan +
925 				(DFS_NEXT_5GHZ_CHANNEL * 2);
926 			avail_chnl[chnl_count++] = start_chan +
927 				(DFS_NEXT_5GHZ_CHANNEL * 3);
928 		}
929 	}
930 
931 	dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
932 			"channel count %d", chnl_count);
933 
934 	return chnl_count;
935 }
936 
937 /**
938  * dfs_populate_available_channels()- Populate channels based on width and
939  *                                    bitmap
940  * @dfs: Pointer to DFS structure.
941  * @bitmap: bitmap
942  * @ch_width: channel width
943  * @avail_chnl: prepared channel list
944  *
945  * Prepare channel list based on width and channel bitmap.
946  *
947  * Return: channel count
948  */
949 static uint8_t dfs_populate_available_channels(
950 		struct wlan_dfs *dfs,
951 		struct chan_bonding_bitmap *bitmap,
952 		uint8_t ch_width,
953 		uint8_t *avail_chnl)
954 {
955 	switch (ch_width) {
956 	case DFS_CH_WIDTH_160MHZ:
957 	case DFS_CH_WIDTH_80P80MHZ:
958 	case DFS_CH_WIDTH_80MHZ:
959 		return dfs_populate_80mhz_available_channels(
960 			dfs, bitmap, avail_chnl);
961 	case DFS_CH_WIDTH_40MHZ:
962 		return dfs_populate_40mhz_available_channels(
963 			dfs, bitmap, avail_chnl);
964 	default:
965 		dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
966 				"Invalid ch_width %d", ch_width);
967 		break;
968 	}
969 
970 	return 0;
971 }
972 
973 /**
974  * dfs_get_rand_from_lst()- Get random channel from a given channel list
975  * @dfs: Pointer to DFS structure.
976  * @ch_lst: channel list
977  * @num_ch: number of channels
978  *
979  * Get random channel from given channel list.
980  *
981  * Return: channel number
982  */
983 static uint8_t dfs_get_rand_from_lst(
984 		struct wlan_dfs *dfs,
985 		uint8_t *ch_lst,
986 		uint8_t num_ch)
987 {
988 	uint8_t i;
989 	uint32_t rand_byte = 0;
990 
991 	if (!num_ch || !ch_lst) {
992 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
993 				"invalid param ch_lst %pK, num_ch = %d",
994 				ch_lst, num_ch);
995 		return 0;
996 	}
997 
998 	get_random_bytes((uint8_t *)&rand_byte, 1);
999 	i = (rand_byte + qdf_mc_timer_get_system_ticks()) % num_ch;
1000 
1001 	dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1002 			"random channel %d", ch_lst[i]);
1003 
1004 	return ch_lst[i];
1005 }
1006 
1007 /**
1008  * dfs_random_channel_sel_set_bitmap()- Set channel bit in bitmap based
1009  * on given channel number
1010  * @dfs: Pointer to DFS structure.
1011  * @bitmap: bitmap
1012  * @channel: channel number
1013  *
1014  * Set channel bit in bitmap based on given channel number.
1015  *
1016  * Return: None
1017  */
1018 static void dfs_random_channel_sel_set_bitmap(
1019 		struct wlan_dfs *dfs,
1020 		struct chan_bonding_bitmap *bitmap,
1021 		uint8_t channel)
1022 {
1023 	int i = 0;
1024 	int start_chan = 0;
1025 
1026 	for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) {
1027 		start_chan = bitmap->chan_bonding_set[i].start_chan;
1028 		if (channel >= start_chan && channel <= start_chan + 12) {
1029 			bitmap->chan_bonding_set[i].chan_map |=
1030 			(1 << ((channel - start_chan) /
1031 			DFS_80_NUM_SUB_CHANNEL));
1032 			return;
1033 		}
1034 	}
1035 
1036 	dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1037 			"Channel=%d is not in the bitmap", channel);
1038 }
1039 
1040 /**
1041  * dfs_find_ch_with_fallback()- find random channel
1042  * @dfs: Pointer to DFS structure.
1043  * @ch_wd: channel width
1044  * @center_freq_seg1: center frequency of secondary segment.
1045  * @ch_lst: list of available channels.
1046  * @num_ch: number of channels in the list.
1047  *
1048  * Find random channel based on given channel width and channel list,
1049  * fallback to lower width if requested channel width not available.
1050  *
1051  * Return: channel number
1052  */
1053 static uint8_t dfs_find_ch_with_fallback(
1054 		struct wlan_dfs *dfs,
1055 		uint8_t *ch_wd,
1056 		uint8_t *center_freq_seg1,
1057 		uint8_t *ch_lst,
1058 		uint32_t num_ch)
1059 {
1060 	bool flag = false;
1061 	uint32_t rand_byte = 0;
1062 	struct  chan_bonding_bitmap ch_map = { { {0} } };
1063 	uint8_t count = 0, i, index = 0, final_cnt = 0, target_channel = 0;
1064 	uint8_t primary_seg_start_ch = 0, sec_seg_ch = 0, new_160_start_ch = 0;
1065 	uint8_t final_lst[DFS_MAX_NUM_CHAN] = {0};
1066 
1067 	/* initialize ch_map for all 80 MHz bands: we have 6 80MHz bands */
1068 	ch_map.chan_bonding_set[0].start_chan = 36;
1069 	ch_map.chan_bonding_set[1].start_chan = 52;
1070 	ch_map.chan_bonding_set[2].start_chan = 100;
1071 	ch_map.chan_bonding_set[3].start_chan = 116;
1072 	ch_map.chan_bonding_set[4].start_chan = 132;
1073 	ch_map.chan_bonding_set[5].start_chan = 149;
1074 
1075 	for (i = 0; i < num_ch; i++) {
1076 		dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1077 				"channel = %d added to bitmap", ch_lst[i]);
1078 		dfs_random_channel_sel_set_bitmap(dfs, &ch_map, ch_lst[i]);
1079 	}
1080 
1081 	/* populate available channel list from bitmap */
1082 	final_cnt = dfs_populate_available_channels(dfs, &ch_map,
1083 			*ch_wd, final_lst);
1084 
1085 	/* If no valid ch bonding found, fallback */
1086 	if (final_cnt == 0) {
1087 		if ((*ch_wd == DFS_CH_WIDTH_160MHZ) ||
1088 		    (*ch_wd == DFS_CH_WIDTH_80P80MHZ) ||
1089 		    (*ch_wd == DFS_CH_WIDTH_80MHZ)) {
1090 			dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1091 					"from [%d] to 40Mhz", *ch_wd);
1092 			*ch_wd = DFS_CH_WIDTH_40MHZ;
1093 		} else if (*ch_wd == DFS_CH_WIDTH_40MHZ) {
1094 			dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1095 					"from 40Mhz to 20MHz");
1096 			*ch_wd = DFS_CH_WIDTH_20MHZ;
1097 		}
1098 		return 0;
1099 	}
1100 
1101 	/* ch count should be > 8 to switch new channel in 160Mhz band */
1102 	if (((*ch_wd == DFS_CH_WIDTH_160MHZ) ||
1103 	     (*ch_wd == DFS_CH_WIDTH_80P80MHZ)) &&
1104 	     (final_cnt < DFS_MAX_20M_SUB_CH)) {
1105 		dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1106 				"from [%d] to 80Mhz", *ch_wd);
1107 		*ch_wd = DFS_CH_WIDTH_80MHZ;
1108 		return 0;
1109 	}
1110 
1111 	if (*ch_wd == DFS_CH_WIDTH_160MHZ) {
1112 		/*
1113 		 * Only 2 blocks for 160Mhz bandwidth i.e 36-64 & 100-128
1114 		 * and all the channels in these blocks are continuous
1115 		 * and separated by 4Mhz.
1116 		 */
1117 		for (i = 1; ((i < final_cnt)); i++) {
1118 			if ((final_lst[i] - final_lst[i-1]) ==
1119 			     DFS_NEXT_5GHZ_CHANNEL)
1120 				count++;
1121 			else
1122 				count = 0;
1123 			if (count == DFS_MAX_20M_SUB_CH - 1) {
1124 				flag = true;
1125 				new_160_start_ch = final_lst[i - count];
1126 				break;
1127 			}
1128 		}
1129 	} else if (*ch_wd == DFS_CH_WIDTH_80P80MHZ) {
1130 		flag = true;
1131 	}
1132 
1133 	if ((flag == false) && (*ch_wd > DFS_CH_WIDTH_80MHZ)) {
1134 		dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1135 				"from [%d] to 80Mhz", *ch_wd);
1136 		*ch_wd = DFS_CH_WIDTH_80MHZ;
1137 		return 0;
1138 	}
1139 
1140 	if (*ch_wd == DFS_CH_WIDTH_160MHZ) {
1141 		get_random_bytes((uint8_t *)&rand_byte, 1);
1142 		rand_byte = (rand_byte + qdf_mc_timer_get_system_ticks())
1143 			% DFS_MAX_20M_SUB_CH;
1144 		target_channel = new_160_start_ch + (rand_byte *
1145 				DFS_80_NUM_SUB_CHANNEL);
1146 	} else if (*ch_wd == DFS_CH_WIDTH_80P80MHZ) {
1147 		get_random_bytes((uint8_t *)&rand_byte, 1);
1148 		index = (rand_byte + qdf_mc_timer_get_system_ticks()) %
1149 			final_cnt;
1150 		target_channel = final_lst[index];
1151 		index -= (index % DFS_80_NUM_SUB_CHANNEL);
1152 		primary_seg_start_ch = final_lst[index];
1153 
1154 		/* reset channels associate with primary 80Mhz */
1155 		for (i = 0; i < DFS_80_NUM_SUB_CHANNEL; i++)
1156 			final_lst[i + index] = 0;
1157 		/* select and calculate center freq for secondary segment */
1158 		for (i = 0; i < final_cnt / DFS_80_NUM_SUB_CHANNEL; i++) {
1159 			if (final_lst[i * DFS_80_NUM_SUB_CHANNEL] &&
1160 			    (abs(primary_seg_start_ch -
1161 			     final_lst[i * DFS_80_NUM_SUB_CHANNEL]) >
1162 			     (DFS_MAX_20M_SUB_CH * 2))) {
1163 				sec_seg_ch =
1164 					final_lst[i * DFS_80_NUM_SUB_CHANNEL] +
1165 					DFS_80MHZ_START_CENTER_CH_DIFF;
1166 				break;
1167 			}
1168 		}
1169 
1170 		if (!sec_seg_ch && (final_cnt == DFS_MAX_20M_SUB_CH))
1171 			*ch_wd = DFS_CH_WIDTH_160MHZ;
1172 		else if (!sec_seg_ch)
1173 			*ch_wd = DFS_CH_WIDTH_80MHZ;
1174 
1175 		*center_freq_seg1 = sec_seg_ch;
1176 		dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1177 				"Center frequency seg1 = %d", sec_seg_ch);
1178 	} else {
1179 		target_channel = dfs_get_rand_from_lst(dfs,
1180 				final_lst, final_cnt);
1181 	}
1182 	dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1183 			"target channel = %d", target_channel);
1184 
1185 	return target_channel;
1186 }
1187 
1188 /**
1189  * dfs_remove_cur_ch_from_list()- remove current operating channels
1190  * @ch_list: list of avilable channel list
1191  * @ch_cnt: number of channels.
1192  * @ch_wd: channel width.
1193  * @cur_chan: current channel.
1194  *
1195  * Remove current channels from list of available channels.
1196  *
1197  * Return: channel number
1198  */
1199 static void dfs_remove_cur_ch_from_list(
1200 	struct dfs_channel *ch_list,
1201 	uint32_t *ch_cnt,
1202 	uint8_t *ch_wd,
1203 	struct dfs_channel *cur_chan)
1204 {
1205 	/* TODO */
1206 	return;
1207 }
1208 
1209 bool dfs_freq_is_in_nol(struct wlan_dfs *dfs, uint32_t freq)
1210 {
1211 	struct dfs_nolelem *nol;
1212 
1213 	if (!dfs) {
1214 		dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,  "null dfs");
1215 		return false;
1216 	}
1217 
1218 	nol = dfs->dfs_nol;
1219 	while (nol) {
1220 		if (freq == nol->nol_freq) {
1221 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1222 					"%d is in nol", freq);
1223 			return true;
1224 		}
1225 		nol = nol->nol_next;
1226 	}
1227 
1228 	return false;
1229 }
1230 
1231 /**
1232  * dfs_apply_rules()- prepare channel list based on flags
1233  * @dfs: dfs handler
1234  * @flags: channel flags
1235  * @random_chan_list: output channel list
1236  * @random_chan_cnt: output channel count
1237  * @ch_list: input channel list
1238  * @ch_cnt: input channel count
1239  * @dfs_region: dfs region
1240  * @acs_info: acs channel range information
1241  *
1242  * prepare channel list based on flags
1243  *
1244  * Return: None
1245  */
1246 static void dfs_apply_rules(struct wlan_dfs *dfs,
1247 	uint32_t flags,
1248 	uint8_t *random_chan_list,
1249 	uint32_t *random_chan_cnt,
1250 	struct dfs_channel *ch_list,
1251 	uint32_t ch_cnt,
1252 	uint8_t dfs_region,
1253 	struct dfs_acs_info *acs_info)
1254 {
1255 	struct dfs_channel *chan;
1256 	bool flag_no_weather = 0;
1257 	bool flag_no_lower_5g = 0;
1258 	bool flag_no_upper_5g = 0;
1259 	bool flag_no_dfs_chan = 0;
1260 	bool flag_no_2g_chan  = 0;
1261 	bool flag_no_5g_chan  = 0;
1262 	bool flag_no_japan_w53 = 0;
1263 	int i;
1264 
1265 	dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "flags %d", flags);
1266 	flag_no_weather = (dfs_region == DFS_ETSI_REGION_VAL) ?
1267 		flags & DFS_RANDOM_CH_FLAG_NO_WEATHER_CH : 0;
1268 
1269 	if (dfs_region == DFS_MKK_REGION_VAL) {
1270 		flag_no_lower_5g = flags & DFS_RANDOM_CH_FLAG_NO_LOWER_5G_CH;
1271 		flag_no_upper_5g = flags & DFS_RANDOM_CH_FLAG_NO_UPEER_5G_CH;
1272 		flag_no_japan_w53 = flags & DFS_RANDOM_CH_FLAG_NO_JAPAN_W53_CH;
1273 	}
1274 
1275 	flag_no_dfs_chan = flags & DFS_RANDOM_CH_FLAG_NO_DFS_CH;
1276 	flag_no_2g_chan  = flags & DFS_RANDOM_CH_FLAG_NO_2GHZ_CH;
1277 	flag_no_5g_chan  = flags & DFS_RANDOM_CH_FLAG_NO_5GHZ_CH;
1278 
1279 	for (i = 0; i < ch_cnt; i++) {
1280 		chan = &ch_list[i];
1281 
1282 		if ((chan->dfs_ch_ieee == 0) ||
1283 				(chan->dfs_ch_ieee > MAX_CHANNEL_NUM)) {
1284 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1285 				  "invalid channel %d", chan->dfs_ch_ieee);
1286 			continue;
1287 		}
1288 
1289 		if (flags & DFS_RANDOM_CH_FLAG_NO_CURR_OPE_CH) {
1290 			/* TODO : Skip all HT20 channels in the given mode */
1291 			if (chan->dfs_ch_ieee ==
1292 					dfs->dfs_curchan->dfs_ch_ieee) {
1293 				dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1294 					  "skip %d current operating channel",
1295 					  chan->dfs_ch_ieee);
1296 				continue;
1297 			}
1298 		}
1299 
1300 		if (acs_info && (acs_info->acs_mode == 1) &&
1301 		    ((chan->dfs_ch_ieee < acs_info->start_ch) ||
1302 		    (chan->dfs_ch_ieee > acs_info->end_ch))) {
1303 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1304 				  "skip ch %d not in acs range (%d-%d)",
1305 				  chan->dfs_ch_ieee, acs_info->start_ch,
1306 				  acs_info->end_ch);
1307 			continue;
1308 
1309 		}
1310 
1311 		if (flag_no_2g_chan &&
1312 				chan->dfs_ch_ieee <= DFS_MAX_24GHZ_CHANNEL) {
1313 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1314 				  "skip 2.4 GHz channel=%d", chan->dfs_ch_ieee);
1315 			continue;
1316 		}
1317 
1318 		if (flag_no_5g_chan &&
1319 				chan->dfs_ch_ieee > DFS_MAX_24GHZ_CHANNEL) {
1320 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1321 				  "skip 5 GHz channel=%d", chan->dfs_ch_ieee);
1322 			continue;
1323 		}
1324 
1325 		if (flag_no_weather) {
1326 			if (DFS_IS_CHANNEL_WEATHER_RADAR(chan->dfs_ch_freq)) {
1327 				dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1328 					  "skip weather channel=%d",
1329 					  chan->dfs_ch_ieee);
1330 				continue;
1331 			}
1332 		}
1333 
1334 		if (flag_no_lower_5g &&
1335 		    DFS_IS_CHAN_JAPAN_INDOOR(chan->dfs_ch_ieee)) {
1336 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1337 				  "skip indoor channel=%d", chan->dfs_ch_ieee);
1338 			continue;
1339 		}
1340 
1341 		if (flag_no_upper_5g &&
1342 		    DFS_IS_CHAN_JAPAN_OUTDOOR(chan->dfs_ch_ieee)) {
1343 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1344 				  "skip outdoor channel=%d", chan->dfs_ch_ieee);
1345 			continue;
1346 		}
1347 
1348 		if (flag_no_dfs_chan &&
1349 		    (chan->dfs_ch_flagext & WLAN_CHAN_DFS)) {
1350 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1351 				  "skip dfs channel=%d", chan->dfs_ch_ieee);
1352 			continue;
1353 		}
1354 
1355 		if (flag_no_japan_w53 &&
1356 		    DFS_IS_CHAN_JAPAN_W53(chan->dfs_ch_ieee)) {
1357 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1358 				  "skip japan W53 channel=%d",
1359 				  chan->dfs_ch_ieee);
1360 			continue;
1361 		}
1362 
1363 		if (dfs_freq_is_in_nol(dfs, chan->dfs_ch_freq)) {
1364 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1365 				  "skip nol channel=%d", chan->dfs_ch_ieee);
1366 			continue;
1367 		}
1368 
1369 		random_chan_list[*random_chan_cnt] = chan->dfs_ch_ieee;
1370 		*random_chan_cnt += 1;
1371 	}
1372 }
1373 
1374 uint8_t dfs_prepare_random_channel(struct wlan_dfs *dfs,
1375 	struct dfs_channel *ch_list,
1376 	uint32_t ch_cnt,
1377 	uint32_t flags,
1378 	uint8_t *ch_wd,
1379 	struct dfs_channel *cur_chan,
1380 	uint8_t dfs_region,
1381 	struct dfs_acs_info *acs_info)
1382 {
1383 	int i = 0;
1384 	uint8_t final_cnt = 0;
1385 	uint8_t target_ch = 0;
1386 	uint8_t *random_chan_list = NULL;
1387 	uint32_t random_chan_cnt = 0;
1388 	uint16_t flag_no_weather = 0;
1389 	uint8_t *leakage_adjusted_lst;
1390 	uint8_t final_lst[NUM_CHANNELS] = {0};
1391 
1392 	if (!ch_list || !ch_cnt) {
1393 		dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1394 				"Invalid params %pK, ch_cnt=%d",
1395 				ch_list, ch_cnt);
1396 		return 0;
1397 	}
1398 
1399 	if (*ch_wd < DFS_CH_WIDTH_20MHZ || *ch_wd > DFS_CH_WIDTH_80P80MHZ) {
1400 		dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1401 				"Invalid ch_wd %d", *ch_wd);
1402 		return 0;
1403 	}
1404 
1405 	random_chan_list = qdf_mem_malloc(ch_cnt * sizeof(*random_chan_list));
1406 	if (!random_chan_list) {
1407 		dfs_alert(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1408 				"Memory allocation failed");
1409 		return 0;
1410 	}
1411 
1412 	if (flags & DFS_RANDOM_CH_FLAG_NO_CURR_OPE_CH)
1413 		dfs_remove_cur_ch_from_list(ch_list, &ch_cnt, ch_wd, cur_chan);
1414 
1415 	dfs_apply_rules(dfs, flags, random_chan_list, &random_chan_cnt,
1416 		    ch_list, ch_cnt, dfs_region, acs_info);
1417 
1418 	flag_no_weather = (dfs_region == DFS_ETSI_REGION_VAL) ?
1419 		flags & DFS_RANDOM_CH_FLAG_NO_WEATHER_CH : 0;
1420 
1421 	/* list adjusted after leakage has been marked */
1422 	leakage_adjusted_lst = qdf_mem_malloc(random_chan_cnt);
1423 	if (!leakage_adjusted_lst) {
1424 		dfs_alert(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1425 				"Memory allocation failed");
1426 		qdf_mem_free(random_chan_list);
1427 		return 0;
1428 	}
1429 
1430 	do {
1431 		qdf_mem_copy(leakage_adjusted_lst, random_chan_list,
1432 			     random_chan_cnt);
1433 		if (QDF_IS_STATUS_ERROR(dfs_mark_leaking_ch(dfs, *ch_wd,
1434 				random_chan_cnt,
1435 				leakage_adjusted_lst))) {
1436 			qdf_mem_free(random_chan_list);
1437 			qdf_mem_free(leakage_adjusted_lst);
1438 			return 0;
1439 		}
1440 
1441 		if (*ch_wd == DFS_CH_WIDTH_20MHZ) {
1442 			/*
1443 			 * PASS: 3 - from leakage_adjusted_lst, prepare valid
1444 			 * ch list and use random number from that
1445 			 */
1446 			for (i = 0; i < random_chan_cnt; i++) {
1447 				if (leakage_adjusted_lst[i] == 0)
1448 					continue;
1449 				dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1450 					  "dfs: Channel=%d added to available list",
1451 					  leakage_adjusted_lst[i]);
1452 				final_lst[final_cnt] = leakage_adjusted_lst[i];
1453 				final_cnt++;
1454 			}
1455 			target_ch = dfs_get_rand_from_lst(
1456 				dfs, final_lst, final_cnt);
1457 			break;
1458 		}
1459 
1460 		target_ch = dfs_find_ch_with_fallback(dfs, ch_wd,
1461 				&cur_chan->dfs_ch_vhtop_ch_freq_seg2,
1462 				leakage_adjusted_lst,
1463 				random_chan_cnt);
1464 
1465 		/*
1466 		 * When flag_no_weather is set, avoid usage of Adjacent
1467 		 * weather radar channel in HT40 mode as extension channel
1468 		 * will be on 5600.
1469 		 */
1470 		if (flag_no_weather &&
1471 				(target_ch ==
1472 				 DFS_ADJACENT_WEATHER_RADAR_CHANNEL_NUM) &&
1473 				(*ch_wd == DFS_CH_WIDTH_40MHZ)) {
1474 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1475 					"skip weather adjacent ch=%d\n",
1476 					target_ch);
1477 			continue;
1478 		}
1479 
1480 		if (target_ch)
1481 			break;
1482 	} while (true);
1483 
1484 	qdf_mem_free(random_chan_list);
1485 	qdf_mem_free(leakage_adjusted_lst);
1486 	dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "target_ch = %d", target_ch);
1487 
1488 	return target_ch;
1489 }
1490