xref: /wlan-dirver/qca-wifi-host-cmn/umac/dfs/core/src/misc/dfs_random_chan_sel.c (revision 503663c6daafffe652fa360bde17243568cd6d2a)
1 /*
2  * Copyright (c) 2012-2019 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 #include "../dfs_process_radar_found_ind.h"
24 
25 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION
26 /*
27  * TODO: At present SAP Channel leakage matrix for ch 144
28  * is not available from system's team. So to play it safe
29  * and avoid crash if channel 144 is request, in following
30  * matix channel 144 is added such that it will cause code
31  * to avoid selecting channel 144.
32  *
33  * THESE ENTRIES SHOULD BE REPLACED WITH CORRECT VALUES AS
34  * PROVIDED BY SYSTEM'S TEAM.
35  */
36 
37 /* channel tx leakage table - ht80 */
38 struct dfs_matrix_tx_leak_info ht80_chan[] = {
39 	{52, 5260,
40 	 {{36, 5180, 148}, {40, 5200, 199},
41 	  {44, 5520, 193}, {48, 5240, 197},
42 	  {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, 153},
43 	  {60, 5300, 137}, {64, 5320, 134},
44 	  {100, 5500, 358}, {104, 5520, 350},
45 	  {108, 5540, 404}, {112, 5560, 344},
46 	  {116, 5580, 424}, {120, 5600, 429},
47 	  {124, 5620, 437}, {128, 5640, 435},
48 	  {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX},
49 	  {140, 5700, DFS_TX_LEAKAGE_MAX},
50 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
51 	  } },
52 
53 
54 	{56, 5280,
55 	 {{36, 5180, 171}, {40, 5200, 178},
56 	  {44, 5220, 171}, {48, 5240, 178},
57 	  {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN},
58 	  {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, 280},
59 	  {100, 5500, 351}, {104, 5520, 376},
60 	  {108, 5540, 362}, {112, 5560, 362},
61 	  {116, 5580, 403}, {120, 5600, 397},
62 	  {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX},
63 	  {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX},
64 	  {140, 5700, DFS_TX_LEAKAGE_MAX},
65 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
66 	  } },
67 
68 	{60,5300,
69 	 {{36, 5180, 156}, {40, 5200, 146},
70 	  {44, 5220, DFS_TX_LEAKAGE_MIN}, {48, 5240, DFS_TX_LEAKAGE_MIN},
71 	  {52, 5260, 180}, {56, 5280, DFS_TX_LEAKAGE_MIN},
72 	  {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN},
73 	  {100, 5500, 376}, {104, 5520, 360},
74 	  {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX},
75 	  {116, 5580, 395}, {120, 5600, 399},
76 	  {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX},
77 	  {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX},
78 	  {140, 5700, DFS_TX_LEAKAGE_MAX},
79 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
80 	  } },
81 
82 	{64, 5320,
83 	 {{36, 5180,  217}, {40, 5200, 221},
84 	  {44, 5220, DFS_TX_LEAKAGE_MIN}, {48, 5240, DFS_TX_LEAKAGE_MIN},
85 	  {52, 5260, 176}, {56, 5280, 176},
86 	  {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN},
87 	  {100, 5500, 384}, {104, 5520, 390},
88 	  {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX},
89 	  {116, 5580, 375}, {120, 5600, 374},
90 	  {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX},
91 	  {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX},
92 	  {140, 5700, DFS_TX_LEAKAGE_MAX},
93 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
94 	  } },
95 
96 	{100, 5500,
97 	 {{36, 5180, 357}, {40, 5200, 326},
98 	  {44, 5220, 321}, {48, 5240, 326},
99 	  {52, 5260, 378}, {56, 5280, 396},
100 	  {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
101 	  {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN},
102 	  {108, 5540, 196}, {112, 5560, 116},
103 	  {116, 5580, 166}, {120, 5600, DFS_TX_LEAKAGE_MIN},
104 	  {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
105 	  {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
106 	  {140, 5700, DFS_TX_LEAKAGE_MIN},
107 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
108 	  } },
109 
110 	{104, 5520,
111 	 {{36, 5180,  325}, {40, 5200, 325},
112 	  {44, 5220, 305}, {48, 5240, 352},
113 	  {52, 5260, 411}, {56, 5280, 411},
114 	  {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
115 	  {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN},
116 	  {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, 460},
117 	  {116, 5580, 198}, {120, 5600, DFS_TX_LEAKAGE_MIN},
118 	  {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
119 	  {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
120 	  {140, 5700, DFS_TX_LEAKAGE_MIN},
121 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
122 	  } },
123 
124 	{108, 5540,
125 	 {{36,5180,  304}, {40, 5200, 332},
126 	  {44, 5220, 310}, {48, 5240, 335},
127 	  {52, 5260, 431}, {56, 5280, 391},
128 	  {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
129 	  {100, 5500, 280}, {104, 5520, DFS_TX_LEAKAGE_MIN},
130 	  {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
131 	  {116, 5580, 185}, {120, 5600, DFS_TX_LEAKAGE_MIN},
132 	  {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
133 	  {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
134 	  {140, 5700, DFS_TX_LEAKAGE_MIN},
135 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
136 	  } },
137 
138 	{112,5560,
139 	 {{36, 5180, 327}, {40, 5200, 335},
140 	  {44, 5220, 331}, {48, 5240, 345},
141 	  {52, 5260, 367}, {56, 5280, 401},
142 	  {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
143 	  {100, 5500, 131}, {104, 5520, 132},
144 	  {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
145 	  {116, 5580, 189}, {120, 5600, DFS_TX_LEAKAGE_MIN},
146 	  {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
147 	  {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
148 	  {140, 5700, DFS_TX_LEAKAGE_MIN},
149 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
150 	  } },
151 
152 	{116, 5580,
153 	 {{36, 5180, 384}, {40, 5200, 372},
154 	  {44, 5220, 389}, {48, 5240, 396},
155 	  {52, 5260, 348}, {56, 5280, 336},
156 	  {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
157 	  {100, 5500, 172}, {104, 5520, 169},
158 	  {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
159 	  {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN},
160 	  {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
161 	  {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
162 	  {140, 5700, DFS_TX_LEAKAGE_MIN},
163 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
164 	  } },
165 
166 	{120, 5600,
167 	 {{36, 5180, 395}, {40, 5200, 419},
168 	  {44, 5220, 439}, {48, 5240, 407},
169 	  {52, 5260, 321}, {56, 5280, 334},
170 	  {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
171 	  {100, 5500, 134}, {104, 5520, 186},
172 	  {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
173 	  {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN},
174 	  {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, 159},
175 	  {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
176 	  {140, 5700, DFS_TX_LEAKAGE_MIN},
177 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
178 	  } },
179 
180 	{124, 5620,
181 	 {{36, 5180, 469}, {40, 5200, 433},
182 	  {44, 5220, 434}, {48, 5240, 435},
183 	  {52, 5260, 332}, {56, 5280, 345},
184 	  {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
185 	  {100, 5500, 146}, {104, 5520, 177},
186 	  {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
187 	  {116, 5580, 350}, {120, 5600, DFS_TX_LEAKAGE_MIN},
188 	  {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, 138},
189 	  {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
190 	  {140, 5700, DFS_TX_LEAKAGE_MIN},
191 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
192 	  } },
193 
194 	{128, 5640,
195 	 {{36, 5180, 408}, {40, 5200, 434},
196 	  {44, 5220, 449}, {48, 5240, 444},
197 	  {52, 5260, 341}, {56, 5280, 374},
198 	  {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
199 	  {100, 5500, 205}, {104, 5520, 208},
200 	  {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
201 	  {116, 5580, 142}, {120, 5600, DFS_TX_LEAKAGE_MIN},
202 	  {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
203 	  {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
204 	  {140, 5700, DFS_TX_LEAKAGE_MIN},
205 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
206 	  } },
207 
208 	{132, 5660,
209 	 {{36, 5180, DFS_TX_LEAKAGE_MAX}, {40, 5200, DFS_TX_LEAKAGE_MAX},
210 	  {44, 5220, DFS_TX_LEAKAGE_MAX}, {48, 5240, DFS_TX_LEAKAGE_MAX},
211 	  {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX},
212 	  {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN},
213 	  {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN},
214 	  {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
215 	  {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN},
216 	  {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
217 	  {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
218 	  {140, 5700, DFS_TX_LEAKAGE_MIN},
219 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
220 	  } },
221 
222 	{136, 5680,
223 	 {{36, 5180, DFS_TX_LEAKAGE_MAX}, {40, 5200, DFS_TX_LEAKAGE_MAX},
224 	  {44, 5220, DFS_TX_LEAKAGE_MAX}, {48, 5240, DFS_TX_LEAKAGE_MAX},
225 	  {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX},
226 	  {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN},
227 	  {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN},
228 	  {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
229 	  {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN},
230 	  {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
231 	  {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
232 	  {140, 5700, DFS_TX_LEAKAGE_MIN},
233 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
234 	  } },
235 
236 	{140, 5700,
237 	 {{36, 5180,  DFS_TX_LEAKAGE_MAX}, {40, 5200, DFS_TX_LEAKAGE_MAX},
238 	  {44, 5220, DFS_TX_LEAKAGE_MAX}, {48, 5240, DFS_TX_LEAKAGE_MAX},
239 	  {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX},
240 	  {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN},
241 	  {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN},
242 	  {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
243 	  {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN},
244 	  {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
245 	  {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
246 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
247 	  } },
248 
249 	{144, 5720,
250 	 {{36, 5180, DFS_TX_LEAKAGE_MAX}, {40, 5200, DFS_TX_LEAKAGE_MAX},
251 	  {44, 5220, DFS_TX_LEAKAGE_MAX}, {48, 5240, DFS_TX_LEAKAGE_MAX},
252 	  {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX},
253 	  {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN},
254 	  {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN},
255 	  {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
256 	  {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN},
257 	  {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
258 	  {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
259 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
260 	  } },
261 };
262 
263 /* channel tx leakage table - ht40 */
264 struct dfs_matrix_tx_leak_info ht40_chan[] = {
265 	{52, 5260,
266 	 {{36, 5180, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN},
267 	  {44, 5220, 230}, {48, 5240, 230},
268 	  {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN},
269 	  {60, 5300, DFS_TX_LEAKAGE_AUTO_MIN}, {64, 5320, DFS_TX_LEAKAGE_AUTO_MIN},
270 	  {100, 5500, 625}, {104, 5520, 323},
271 	  {108, 5540, 646}, {112, 5560, 646},
272 	  {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX},
273 	  {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX},
274 	  {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX},
275 	  {140, 5700, DFS_TX_LEAKAGE_MAX},
276 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
277 	  } },
278 
279 	{56, 5280,
280 	 {{36, 5180, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN},
281 	  {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 5240, DFS_TX_LEAKAGE_AUTO_MIN},
282 	  {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN},
283 	  {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN},
284 	  {100, 5500, 611}, {104, 5520, 611},
285 	  {108, 5540, 617}, {112, 5560, 617},
286 	  {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX},
287 	  {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX},
288 	  {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX},
289 	  {140, 5700, DFS_TX_LEAKAGE_MAX},
290 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
291 	  } },
292 
293 	{60, 5300,
294 	 {{36, 5180, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN},
295 	  {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 5240, DFS_TX_LEAKAGE_AUTO_MIN},
296 	  {52, 5260, 190}, {56, 5280, 190},
297 	  {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN},
298 	  {100, 5500, 608}, {104, 5520, 608},
299 	  {108, 5540, 623}, {112, 5560, 623},
300 	  {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX},
301 	  {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX},
302 	  {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX},
303 	  {140, 5700, DFS_TX_LEAKAGE_MAX},
304 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
305 	  } },
306 
307 	{64, 5320,
308 	 {{36, 5180, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN},
309 	  {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 5240, DFS_TX_LEAKAGE_AUTO_MIN},
310 	  {52, 5260, 295}, {56, 5280, 295},
311 	  {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN},
312 	  {100, 5500, 594}, {104, 5520, 594},
313 	  {108, 5540, 625}, {112, 5560, 625},
314 	  {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX},
315 	  {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX},
316 	  {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX},
317 	  {140, 5700, DFS_TX_LEAKAGE_MAX},
318 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
319 	  } },
320 
321 	{100, 5500,
322 	 {{36, 5180, 618}, {40, 5200, 618},
323 	  {44, 5220, 604}, {48, 5240, 604},
324 	  {52, 5260, 596}, {56, 5280, 596},
325 	  {60, 5300, 584}, {64, 5320, 584},
326 	  {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN},
327 	  {108, 5540, 299}, {112, 5560, 299},
328 	  {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN},
329 	  {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN},
330 	  {132, 5660, 538}, {136,5680, 538},
331 	  {140, 5700, 598},
332 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
333 	  } },
334 
335 	{104, 5520,
336 	 {{36, 5180, 636}, {40, 5200, 636},
337 	  {44, 5220, 601}, {48, 5240, 601},
338 	  {52, 5260, 616}, {56, 5280, 616},
339 	  {60, 5300, 584}, {64, 5320, 584},
340 	  {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN},
341 	  {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
342 	  {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN},
343 	  {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN},
344 	  {132, 5660, 553}, {136, 5680, 553},
345 	  {140, 5700, 568},
346 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
347 	  } },
348 
349 	{108, 5540,
350 	 {{36, 5180, 600}, {40, 5200, 600},
351 	  {44, 5220, 627}, {48, 5240, 627},
352 	  {52, 5260, 611}, {56, 5280, 611},
353 	  {60, 5300, 611}, {64, 5320, 611},
354 	  {100, 5500, 214}, {104, 5520, 214},
355 	  {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
356 	  {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN},
357 	  {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN},
358 	  {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN},
359 	  {140, 5700, 534},
360 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
361 	  } },
362 
363 	{112, 5560,
364 	 {{36, 5180, 645}, {40, 5200, 645},
365 	  {44, 5220, 641}, {48, 5240, 641},
366 	  {52, 5260, 618}, {56, 5280, 618},
367 	  {60, 5300, 612}, {64, 5320, 612},
368 	  {100, 5500, 293}, {104, 5520, 293},
369 	  {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
370 	  {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN},
371 	  {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN},
372 	  {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN},
373 	  {140, 5700, 521},
374 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
375 	  } },
376 
377 	{116, 5580,
378 	 {{36, 5180, 661}, {40, 5200, 661},
379 	  {44, 5220, 624}, {48, 5240, 624},
380 	  {52, 5260, 634}, {56, 5280, 634},
381 	  {60, 5300, 611}, {64, 5320, 611},
382 	  {100, 5500, DFS_TX_LEAKAGE_AUTO_MIN}, {104, 5520, DFS_TX_LEAKAGE_AUTO_MIN},
383 	  {108, 5540, 217}, {112, 5560, 217},
384 	  {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN},
385 	  {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN},
386 	  {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN},
387 	  {140, 5700, DFS_TX_LEAKAGE_AUTO_MIN},
388 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
389 	  } },
390 
391 	{120, 5600,
392 	 {{36, 5180, 667}, {40, 5200, 667},
393 	  {44, 5220, 645}, {48, 5240, 645},
394 	  {52, 5260, 633}, {56, 5280, 633},
395 	  {60, 5300, 619}, {64, 5320, 619},
396 	  {100, 5500, DFS_TX_LEAKAGE_AUTO_MIN}, {104, 5520, DFS_TX_LEAKAGE_AUTO_MIN},
397 	  {108, 5540, 291}, {112, 5560, 291},
398 	  {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN},
399 	  {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
400 	  {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN},
401 	  {140, 5700, DFS_TX_LEAKAGE_AUTO_MIN},
402 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
403 	  } },
404 
405 	{124, 5620,
406 	 {{36, 5180,  676}, {40, 5200, 676},
407 	  {44, 5220, 668}, {48, 5240, 668},
408 	  {52, 5260, 595}, {56, 5280, 595},
409 	  {60, 5300, 622}, {64, 5320, 622},
410 	  {100, 5500, DFS_TX_LEAKAGE_AUTO_MIN}, {104, 5520, DFS_TX_LEAKAGE_AUTO_MIN},
411 	  {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN},
412 	  {116, 5580, 225}, {120, 5600, 225},
413 	  {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
414 	  {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN},
415 	  {140, 5700, DFS_TX_LEAKAGE_AUTO_MIN},
416 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
417 	  } },
418 
419 	{128, 5640,
420 	 {{36, 5180, 678}, {40, 5200, 678},
421 	  {44, 5220, 664}, {48, 5240, 664},
422 	  {52, 5260, 651}, {56, 5280, 651},
423 	  {60, 5300, 643}, {64, 5320, 643},
424 	  {100, 5500, DFS_TX_LEAKAGE_AUTO_MIN}, {104, 5520, DFS_TX_LEAKAGE_AUTO_MIN},
425 	  {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN},
426 	  {116, 5580, 293}, {120, 5600, 293},
427 	  {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
428 	  {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
429 	  {140, 5700, DFS_TX_LEAKAGE_AUTO_MIN},
430 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
431 	  } },
432 
433 	{132, 5660,
434 	 {{36, 5180, 689}, {40, 5200, 689},
435 	  {44, 5220, 669}, {48, 5240, 669},
436 	  {52, 5260, 662}, {56, 5280, 662},
437 	  {60, 5300, 609}, {64, 5320, 609},
438 	  {100, 5500, 538}, {104, 5520, 538},
439 	  {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN},
440 	  {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN},
441 	  {124, 5620, 247}, {128, 5640, 247},
442 	  {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
443 	  {140, 5700, DFS_TX_LEAKAGE_MIN},
444 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
445 	  } },
446 
447 	{136, 5680,
448 	 {{36, 5180, 703}, {40, 5200, 703},
449 	  {44, 5220, 688}, {48, 5240, DFS_TX_LEAKAGE_MIN},
450 	  {52, 5260, 671}, {56, 5280, 671},
451 	  {60, 5300, 658}, {64, 5320, 658},
452 	  {100, 5500, 504}, {104, 5520, 504},
453 	  {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN},
454 	  {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN},
455 	  {124, 5620, 289}, {128, 5640, 289},
456 	  {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
457 	  {140, 5700, DFS_TX_LEAKAGE_MIN},
458 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
459 	  } },
460 
461 	{140, 5700,
462 	 {{36, 5180, 695}, {40, 5200, 695},
463 	  {44, 5220, 684}, {48, 5240, 684},
464 	  {52, 5260, 664}, {56, 5280, 664},
465 	  {60, 5300, 658}, {64, 5320, 658},
466 	  {100, 5500, 601}, {104, 5520, 601},
467 	  {108, 5540, 545}, {112, 5560, 545},
468 	  {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN},
469 	  {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN},
470 	  {132, 5660, 262}, {136, 5680, 262},
471 	  {140, 5700, DFS_TX_LEAKAGE_MIN},
472 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
473 	  } },
474 
475 	{144, 5720,
476 	 {{36, 5180, 695}, {40, 5200, 695},
477 	  {44, 5220, 684}, {48, 5240, 684},
478 	  {52, 5260, 664}, {56, 5280, 664},
479 	  {60, 5300, 658}, {64, 5320, 658},
480 	  {100, 5500, 601}, {104, 5520, 601},
481 	  {108, 5540, 545}, {112, 5560, 545},
482 	  {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN},
483 	  {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN},
484 	  {132, 5660, 262}, {136, 5680, 262},
485 	  {140, 5700, DFS_TX_LEAKAGE_MIN},
486 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
487 	  } },
488 };
489 
490 /* channel tx leakage table - ht20 */
491 struct dfs_matrix_tx_leak_info ht20_chan[] = {
492 	{52, 5260,
493 	 {{36, 5180,DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, 286},
494 	  {44, 5220, 225}, {48,5240, 121},
495 	  {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN},
496 	  {60, 5300, 300}, {64, 5320, DFS_TX_LEAKAGE_AUTO_MIN},
497 	  {100, 5500, 637}, {104, 5520, DFS_TX_LEAKAGE_MAX},
498 	  {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX},
499 	  {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX},
500 	  {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX},
501 	  {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX},
502 	  {140, 5700, DFS_TX_LEAKAGE_MAX},
503 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
504 	  } },
505 
506 	{56, 5280,
507 	 {{36, 5180, 468}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN},
508 	  {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 5240, 206},
509 	  {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN},
510 	  {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN},
511 	  {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX},
512 	  {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX},
513 	  {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX},
514 	  {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX},
515 	  {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX},
516 	  {140, 5700, DFS_TX_LEAKAGE_MAX},
517 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
518 	  } },
519 
520 	{60, 5300,
521 	 {{36, 5180, 507}, {40, 5200, 440},
522 	  {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48,5240, 313},
523 	  {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN},
524 	  {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN},
525 	  {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX},
526 	  {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX},
527 	  {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX},
528 	  {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX},
529 	  {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX},
530 	  {140, 5700, DFS_TX_LEAKAGE_MAX},
531 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
532 	  } },
533 
534 	{64, 5320 ,
535 	 {{36, 5180, 516}, {40, 5200, 520},
536 	  {44, 5220, 506}, {48, 5240,DFS_TX_LEAKAGE_AUTO_MIN},
537 	  {52, 5260, 301}, {56, 5280, 258},
538 	  {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN},
539 	  {100, 5500, 620}, {104, 5520, 617},
540 	  {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX},
541 	  {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX},
542 	  {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX},
543 	  {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX},
544 	  {140, 5700, DFS_TX_LEAKAGE_MAX},
545 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
546 	  } },
547 
548 	{100, 5500,
549 	 {{36, 5180, 616}, {40, 5200, 601},
550 	  {44, 5220, 604}, {48, 5240, 589},
551 	  {52, 5260, 612}, {56, 5280, 592},
552 	  {60, 5300, 590}, {64, 5320, 582},
553 	  {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, 131},
554 	  {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN},
555 	  {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, 522},
556 	  {124, 5620, 571}, {128, 5640, 589},
557 	  {132, 5660, 593}, {136, 5680, 598},
558 	  {140, 5700, 594},
559 	  {144, 5720, DFS_TX_LEAKAGE_MIN},
560 	  } },
561 
562 	{104, 5520,
563 	 {{36, 5180, 622}, {40, 5200, 624},
564 	  {44, 5220, 618}, {48, 5240, 610},
565 	  {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX},
566 	  {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
567 	  {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN},
568 	  {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, 463},
569 	  {116, 5580, 483}, {120, 5600, 503},
570 	  {124, 5620, 523}, {128, 5640, 565},
571 	  {132, 5660, 570}, {136, 5680, 588},
572 	  {140, 5700, 585},
573 	  {144, 5720, DFS_TX_LEAKAGE_MIN},
574 	  } },
575 
576 	{108, 5540,
577 	 {{36, 5180, 620}, {40, 5200, 638},
578 	  {44, 5220, 611}, {48, 5240, 614},
579 	  {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX},
580 	  {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
581 	  {100, 5500, 477}, {104, 5520, DFS_TX_LEAKAGE_MIN},
582 	  {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
583 	  {116, 5580, 477}, {120, 5600, 497},
584 	  {124, 5620, 517}, {128, 5640, 537},
585 	  {132, 5660, 557}, {136, 5680, 577},
586 	  {140, 5700, 603},
587 	  {144, 5720, DFS_TX_LEAKAGE_MIN},
588 	  } },
589 
590 	{112, 5560,
591 	 {{36, 5180, 636}, {40, 5200, 623},
592 	  {44, 5220, 638}, {48, 5240, 628},
593 	  {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX},
594 	  {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, 606},
595 	  {100, 5500, 501}, {104, 5520, 481},
596 	  {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN},
597 	  {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, 481},
598 	  {124, 5620, 501}, {128, 5640, 421},
599 	  {132, 5660, 541}, {136, 5680, 561},
600 	  {140, 5700, 583},
601 	  {144, 5720, DFS_TX_LEAKAGE_MIN},
602 	  } },
603 
604 	{116, 5580,
605 	 {{36, 5180, 646}, {40, 5200, 648},
606 	  {44, 5220, 633}, {48, 5240, 634},
607 	  {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX},
608 	  {60, 5300, 615}, {64, 5320, 594},
609 	  {100, 5500, 575}, {104, 5520, 554},
610 	  {108, 5540, 534}, {112, 5560, DFS_TX_LEAKAGE_MIN},
611 	  {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN},
612 	  {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
613 	  {132, 5660, 534}, {136, 5680, 554},
614 	  {140, 5700, 574},
615 	  {144, 5720, DFS_TX_LEAKAGE_MIN},
616 	  } },
617 
618 	{120, 5600,
619 	 {{36, 5180, 643}, {40, 5200, 649},
620 	  {44, 5220, 654}, {48, 5240, 629},
621 	  {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, 621},
622 	  {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
623 	  {100, 5500, 565}, {104, 5520, 545},
624 	  {108, 5540, 525}, {112, 5560, 505},
625 	  {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN},
626 	  {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, 505},
627 	  {132, 5660, 525}, {136, 5680, 545},
628 	  {140, 5700, 565},
629 	  {144, 5720, DFS_TX_LEAKAGE_MIN},
630 	  } },
631 
632 	{124, 5620,
633 	 {{36, 5180, 638}, {40, 5200, 657},
634 	  {44, 5220, 663}, {48, 5240, 649},
635 	  {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX},
636 	  {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
637 	  {100, 5500, 581}, {104, 5520, 561},
638 	  {108, 5540, 541}, {112, 5560, 521},
639 	  {116, 5580, 499}, {120, 5600, DFS_TX_LEAKAGE_MIN},
640 	  {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
641 	  {132, 5660, 499}, {136, 5680, 519},
642 	  {140, 5700, 539},
643 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
644 	  } },
645 
646 	{128, 5640,
647 	 {{36, 5180, 651}, {40, 5200, 651},
648 	  {44, 5220, 674}, {48, 5240, 640},
649 	  {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX},
650 	  {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
651 	  {100, 5500, 603}, {104, 5520, 560},
652 	  {108, 5540, 540}, {112, 5560, 520},
653 	  {116, 5580, 499}, {120, 5600, 479},
654 	  {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN},
655 	  {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, 479},
656 	  {140, 5700, 499},
657 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
658 	  } },
659 
660 	{132, 5660,
661 	 {{36, 5180, 643}, {40, 5200, 668},
662 	  {44, 5220, 651}, {48, 5240, 657},
663 	  {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX},
664 	  {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
665 	  {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, 602},
666 	  {108, 5540, 578}, {112,5560, 570},
667 	  {116, 5580, 550}, {120, 5600, 530},
668 	  {124, 5620, 510}, {128, 5640, DFS_TX_LEAKAGE_MIN},
669 	  {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
670 	  {140, 5700, 490},
671 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
672 	  } },
673 
674 	{136,5680,
675 	 {{36, 5180, 654}, {40, 5200, 667},
676 	  {44, 5220, 666}, {48, 5240, 642},
677 	  {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX},
678 	  {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX},
679 	  {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX},
680 	  {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, 596},
681 	  {116, 5580, 555}, {120, 5600, 535},
682 	  {124, 5620, 515}, {128, 5640, 495},
683 	  {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN},
684 	  {140, 5700, DFS_TX_LEAKAGE_MIN},
685 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
686 	  } },
687 
688 	{140,5700,
689 	 {{36, 5180, 679}, {40, 5200, 673},
690 	  {44, 5220, 667}, {48, 5240, 656},
691 	  {52, 5260, 634}, {56, 5280, 663},
692 	  {60, 5300, 662}, {64, 5320, 660},
693 	  {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX},
694 	  {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, 590},
695 	  {116, 5580, 573}, {120, 5600, 553},
696 	  {124, 5620, 533}, {128, 5640, 513},
697 	  {132, 5660, 490}, {136, 5680, DFS_TX_LEAKAGE_MIN},
698 	  {140, 5700, DFS_TX_LEAKAGE_MIN},
699 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
700 	  } },
701 
702 	{144,5720,
703 	 {{36, 5180, 679}, {40, 5200, 673},
704 	  {44, 5220, 667}, {48, 5240, 656},
705 	  {52, 5260, 634}, {56, 5280, 663},
706 	  {60, 5300, 662}, {64, 5320, 660},
707 	  {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX},
708 	  {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, 590},
709 	  {116, 5580, 573}, {120, 5600, 553},
710 	  {124, 5620, 533}, {128, 5640, 513},
711 	  {132, 5660, 490}, {136, 5680, DFS_TX_LEAKAGE_MIN},
712 	  {140, 5700, DFS_TX_LEAKAGE_MIN},
713 	  {144, 5720, DFS_TX_LEAKAGE_MIN}
714 	  } },
715 };
716 
717 /*
718  * dfs_find_target_channel_in_channel_matrix() - finds the leakage matrix
719  * @ch_width: target channel width
720  * @NOL_channel: the NOL channel whose leakage matrix is required
721  * @pTarget_chnl_mtrx: pointer to target channel matrix returned.
722  *
723  * This function gives the leakage matrix for given NOL channel and ch_width
724  *
725  * Return: TRUE or FALSE
726  */
727 #ifdef CONFIG_CHAN_NUM_API
728 static bool
729 dfs_find_target_channel_in_channel_matrix(enum phy_ch_width ch_width,
730 				uint8_t NOL_channel,
731 				struct dfs_tx_leak_info **pTarget_chnl_mtrx)
732 {
733 	struct dfs_tx_leak_info *target_chan_matrix = NULL;
734 	struct dfs_matrix_tx_leak_info *pchan_matrix = NULL;
735 	uint32_t nchan_matrix;
736 	int i = 0;
737 
738 	switch (ch_width) {
739 	case CH_WIDTH_20MHZ:
740 		/* HT20 */
741 		pchan_matrix = ht20_chan;
742 		nchan_matrix = QDF_ARRAY_SIZE(ht20_chan);
743 		break;
744 	case CH_WIDTH_40MHZ:
745 		/* HT40 */
746 		pchan_matrix = ht40_chan;
747 		nchan_matrix = QDF_ARRAY_SIZE(ht40_chan);
748 		break;
749 	case CH_WIDTH_80MHZ:
750 		/* HT80 */
751 		pchan_matrix = ht80_chan;
752 		nchan_matrix = QDF_ARRAY_SIZE(ht80_chan);
753 		break;
754 	default:
755 		/* handle exception and fall back to HT20 table */
756 		pchan_matrix = ht20_chan;
757 		nchan_matrix = QDF_ARRAY_SIZE(ht20_chan);
758 		break;
759 	}
760 
761 	for (i = 0; i < nchan_matrix; i++) {
762 		/* find the SAP channel to map the leakage matrix */
763 		if (NOL_channel == pchan_matrix[i].channel) {
764 			target_chan_matrix = pchan_matrix[i].chan_matrix;
765 			break;
766 		}
767 	}
768 
769 	if (!target_chan_matrix) {
770 		return false;
771 	} else {
772 		*pTarget_chnl_mtrx = target_chan_matrix;
773 		return true;
774 	}
775 }
776 #endif
777 
778 /*
779  * dfs_find_target_channel_in_channel_matrix_for_freq() - finds the leakage
780  * matrix.
781  * @chan_width: target channel width
782  * @nol_channel: the NOL channel frequency whose leakage matrix is required
783  * @pTarget_chnl_mtrx: pointer to target channel matrix returned.
784  *
785  * This function gives the leakage matrix for given NOL channel and ch_width
786  *
787  * Return: TRUE or FALSE
788  */
789 #ifdef CONFIG_CHAN_FREQ_API
790 static bool
791 dfs_find_target_channel_in_channel_matrix_for_freq(enum phy_ch_width chan_width,
792 						   uint16_t nol_freq,
793 						   struct dfs_tx_leak_info
794 						   **pTarget_chnl_mtrx)
795 {
796 	struct dfs_tx_leak_info *target_chan_matrix = NULL;
797 	struct dfs_matrix_tx_leak_info *pchan_matrix = NULL;
798 	uint32_t nchan_matrix;
799 	int i = 0;
800 
801 	switch (chan_width) {
802 	case CH_WIDTH_20MHZ:
803 		/* HT20 */
804 		pchan_matrix = ht20_chan;
805 		nchan_matrix = QDF_ARRAY_SIZE(ht20_chan);
806 		break;
807 	case CH_WIDTH_40MHZ:
808 		/* HT40 */
809 		pchan_matrix = ht40_chan;
810 		nchan_matrix = QDF_ARRAY_SIZE(ht40_chan);
811 		break;
812 	case CH_WIDTH_80MHZ:
813 		/* HT80 */
814 		pchan_matrix = ht80_chan;
815 		nchan_matrix = QDF_ARRAY_SIZE(ht80_chan);
816 		break;
817 	default:
818 		/* handle exception and fall back to HT20 table */
819 		pchan_matrix = ht20_chan;
820 		nchan_matrix = QDF_ARRAY_SIZE(ht20_chan);
821 		break;
822 	}
823 
824 	for (i = 0; i < nchan_matrix; i++) {
825 		/* find the SAP channel to map the leakage matrix */
826 		if (nol_freq == pchan_matrix[i].channel_freq) {
827 			target_chan_matrix = pchan_matrix[i].chan_matrix;
828 			break;
829 		}
830 	}
831 
832 	if (!target_chan_matrix) {
833 		return false;
834 	} else {
835 		*pTarget_chnl_mtrx = target_chan_matrix;
836 		return true;
837 	}
838 }
839 #endif
840 
841 #ifdef CONFIG_CHAN_NUM_API
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 	struct dfs_tx_leak_info *target_chan_matrix = NULL;
849 	uint32_t         num_channel = (CHAN_ENUM_5720 - CHAN_ENUM_5180) + 1;
850 	uint32_t         j = 0;
851 	uint32_t         k = 0;
852 	uint8_t          dfs_nol_channel;
853 	struct dfs_nolelem *nol;
854 
855 	nol = dfs->dfs_nol;
856 	while (nol) {
857 		dfs_nol_channel = wlan_freq_to_chan(nol->nol_freq);
858 		if (false == dfs_find_target_channel_in_channel_matrix(
859 					ch_width, dfs_nol_channel,
860 					&target_chan_matrix)) {
861 			/*
862 			 * should never happen, we should always find a table
863 			 * here, if we don't, need a fix here!
864 			 */
865 			dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
866 				"Couldn't find target channel matrix!");
867 			QDF_ASSERT(0);
868 			return QDF_STATUS_E_FAILURE;
869 		}
870 		/*
871 		 * following is based on assumption that both temp_ch_lst
872 		 * and target channel matrix are in increasing order of
873 		 * ch_id
874 		 */
875 		for (j = 0, k = 0; j < temp_ch_lst_sz && k < num_channel;) {
876 			if (temp_ch_lst[j] == 0) {
877 				j++;
878 				continue;
879 			}
880 			if (target_chan_matrix[k].leak_chan != temp_ch_lst[j]) {
881 				k++;
882 				continue;
883 			}
884 			/*
885 			 * check leakage from candidate channel
886 			 * to NOL channel
887 			 */
888 			if (target_chan_matrix[k].leak_lvl <=
889 				dfs->tx_leakage_threshold) {
890 				/*
891 				 * candidate channel will have
892 				 * bad leakage in NOL channel,
893 				 * remove from temp list
894 				 */
895 				dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
896 					"dfs: channel: %d will have bad leakage due to channel: %d\n",
897 					dfs_nol_channel, temp_ch_lst[j]);
898 				temp_ch_lst[j] = 0;
899 			}
900 			j++;
901 			k++;
902 		}
903 		nol = nol->nol_next;
904 	} /* end of loop that selects each NOL */
905 
906 	return QDF_STATUS_SUCCESS;
907 }
908 #endif
909 
910 #ifdef CONFIG_CHAN_FREQ_API
911 #define END_CHAN_INDEX CHAN_ENUM_5720
912 #define START_CHAN_INDEX CHAN_ENUM_5180
913 QDF_STATUS
914 dfs_mark_leaking_chan_for_freq(struct wlan_dfs *dfs,
915 			     enum phy_ch_width ch_width,
916 			     uint8_t temp_chan_lst_sz,
917 			     uint16_t *temp_freq_lst)
918 {
919 	struct dfs_tx_leak_info *target_chan_matrix = NULL;
920 	uint32_t         num_channel = (END_CHAN_INDEX - START_CHAN_INDEX) + 1;
921 	uint32_t         j = 0;
922 	uint32_t         k = 0;
923 	struct dfs_nolelem *nol;
924 
925 	nol = dfs->dfs_nol;
926 	while (nol) {
927 		if (false == dfs_find_target_channel_in_channel_matrix_for_freq(
928 					ch_width, nol->nol_freq,
929 					&target_chan_matrix)) {
930 			/*
931 			 * should never happen, we should always find a table
932 			 * here, if we don't, need a fix here!
933 			 */
934 			dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
935 				"Couldn't find target channel matrix!");
936 			QDF_ASSERT(0);
937 			return QDF_STATUS_E_FAILURE;
938 		}
939 		/*
940 		 * following is based on assumption that both temp_freq_lst
941 		 * and target channel matrix are in increasing order of
942 		 * ch_id
943 		 */
944 		for (j = 0, k = 0; j < temp_chan_lst_sz && k < num_channel;) {
945 			if (temp_freq_lst[j] == 0) {
946 				j++;
947 				continue;
948 			}
949 			if (target_chan_matrix[k].leak_chan_freq !=
950 			    temp_freq_lst[j]) {
951 				k++;
952 				continue;
953 			}
954 			/*
955 			 * check leakage from candidate channel
956 			 * to NOL channel
957 			 */
958 			if (target_chan_matrix[k].leak_lvl <=
959 				dfs->tx_leakage_threshold) {
960 				/*
961 				 * candidate channel will have
962 				 * bad leakage in NOL channel,
963 				 * remove from temp list
964 				 */
965 				dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
966 					"dfs: channel: %d will have bad leakage due to channel: %d\n",
967 					nol->nol_freq, temp_freq_lst[j]);
968 				temp_freq_lst[j] = 0;
969 			}
970 			j++;
971 			k++;
972 		}
973 		nol = nol->nol_next;
974 	} /* end of loop that selects each NOL */
975 
976 	return QDF_STATUS_SUCCESS;
977 }
978 #endif
979 #else
980 #ifdef CONFIG_CHAN_NUM_API
981 QDF_STATUS
982 dfs_mark_leaking_ch(struct wlan_dfs *dfs,
983 		enum phy_ch_width ch_width,
984 		uint8_t temp_ch_lst_sz,
985 		uint8_t *temp_ch_lst)
986 {
987 	return QDF_STATUS_SUCCESS;
988 }
989 #endif
990 #ifdef CONFIG_CHAN_FREQ_API
991 QDF_STATUS
992 dfs_mark_leaking_chan_for_freq(struct wlan_dfs *dfs,
993 			     enum phy_ch_width ch_width,
994 			     uint8_t temp_chan_lst_sz,
995 			     uint16_t *temp_freq_lst)
996 {
997 	return QDF_STATUS_SUCCESS;
998 }
999 #endif
1000 #endif
1001 
1002 /**
1003  * dfs_populate_80mhz_available_channels()- Populate channels for 80MHz using
1004  *                                          bitmap
1005  * @dfs: Pointer to DFS structure.
1006  * @bitmap: bitmap
1007  * @avail_freq_list: prepared channel list
1008  *
1009  * Prepare 80MHz channels from the bitmap.
1010  *
1011  * Return: channel count
1012  */
1013 #ifdef CONFIG_CHAN_NUM_API
1014 static uint8_t dfs_populate_80mhz_available_channels(
1015 		struct wlan_dfs *dfs,
1016 		struct chan_bonding_bitmap *bitmap,
1017 		uint8_t *avail_chnl)
1018 {
1019 	uint8_t i = 0;
1020 	uint8_t chnl_count = 0;
1021 	uint8_t start_chan = 0;
1022 
1023 	for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) {
1024 		start_chan = bitmap->chan_bonding_set[i].start_chan;
1025 		if (bitmap->chan_bonding_set[i].chan_map ==
1026 			DFS_80MHZ_MASK) {
1027 			avail_chnl[chnl_count++] = start_chan +
1028 				(DFS_NEXT_5GHZ_CHANNEL * 0);
1029 			avail_chnl[chnl_count++] = start_chan +
1030 				(DFS_NEXT_5GHZ_CHANNEL * 1);
1031 			avail_chnl[chnl_count++] = start_chan +
1032 				(DFS_NEXT_5GHZ_CHANNEL * 2);
1033 			avail_chnl[chnl_count++] = start_chan +
1034 				(DFS_NEXT_5GHZ_CHANNEL * 3);
1035 		}
1036 	}
1037 
1038 	dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1039 			"channel count %d", chnl_count);
1040 
1041 	return chnl_count;
1042 }
1043 #endif
1044 
1045 /*
1046  * dfs_populate_80mhz_available_channel_for_freq() - Populate 80MHZ channels
1047  * available for selection.
1048  * @dfs: Pointer to wlan_dfs.
1049  * @bitmap: Pointer to bonding channel bitmap.
1050  * @avail_freq_list: Pointer to frequency list of available channels.
1051  */
1052 #ifdef CONFIG_CHAN_FREQ_API
1053 static uint8_t dfs_populate_80mhz_available_channel_for_freq(
1054 		struct wlan_dfs *dfs,
1055 		struct chan_bonding_bitmap *bitmap,
1056 		uint16_t *avail_freq_list)
1057 {
1058 	uint8_t i = 0;
1059 	uint8_t chnl_count = 0;
1060 	uint16_t start_chan_freq = 0;
1061 
1062 	for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) {
1063 		start_chan_freq = bitmap->chan_bonding_set[i].start_chan_freq;
1064 		if (bitmap->chan_bonding_set[i].chan_map ==
1065 			DFS_80MHZ_MASK) {
1066 			avail_freq_list[chnl_count++] = start_chan_freq +
1067 				(DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 0);
1068 			avail_freq_list[chnl_count++] = start_chan_freq +
1069 				(DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 1);
1070 			avail_freq_list[chnl_count++] = start_chan_freq +
1071 				(DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 2);
1072 			avail_freq_list[chnl_count++] = start_chan_freq +
1073 				(DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 3);
1074 		}
1075 	}
1076 
1077 	dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1078 		 "channel count %d", chnl_count);
1079 
1080 	return chnl_count;
1081 }
1082 #endif
1083 
1084 /**
1085  * dfs_populate_40mhz_available_channels()- Populate channels for 40MHz using
1086  *                                          bitmap
1087  * @dfs: Pointer to DFS structure.
1088  * @bitmap: bitmap
1089  * @avail_chnl: prepared channel list
1090  *
1091  * Prepare 40MHz channels from the bitmap.
1092  *
1093  * Return: channel count
1094  */
1095 #ifdef CONFIG_CHAN_NUM_API
1096 static uint8_t dfs_populate_40mhz_available_channels(
1097 		struct wlan_dfs *dfs,
1098 		struct chan_bonding_bitmap *bitmap,
1099 		uint8_t *avail_chnl)
1100 {
1101 	uint8_t i = 0;
1102 	uint8_t chnl_count = 0;
1103 	uint8_t start_chan = 0;
1104 
1105 	for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) {
1106 		start_chan = bitmap->chan_bonding_set[i].start_chan;
1107 		if ((bitmap->chan_bonding_set[i].chan_map &
1108 			DFS_40MHZ_MASK_L) == DFS_40MHZ_MASK_L) {
1109 			avail_chnl[chnl_count++] = start_chan +
1110 				(DFS_NEXT_5GHZ_CHANNEL * 0);
1111 			avail_chnl[chnl_count++] = start_chan +
1112 				(DFS_NEXT_5GHZ_CHANNEL * 1);
1113 		}
1114 		if ((bitmap->chan_bonding_set[i].chan_map &
1115 			DFS_40MHZ_MASK_H) == DFS_40MHZ_MASK_H) {
1116 			avail_chnl[chnl_count++] = start_chan +
1117 				(DFS_NEXT_5GHZ_CHANNEL * 2);
1118 			avail_chnl[chnl_count++] = start_chan +
1119 				(DFS_NEXT_5GHZ_CHANNEL * 3);
1120 		}
1121 	}
1122 
1123 	dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1124 			"channel count %d", chnl_count);
1125 
1126 	return chnl_count;
1127 }
1128 #endif
1129 
1130 #ifdef CONFIG_CHAN_FREQ_API
1131 static uint8_t
1132 dfs_populate_40mhz_available_channel_for_freq(struct wlan_dfs *dfs,
1133 					      struct chan_bonding_bitmap *bmap,
1134 					      uint16_t *avail_freq_list)
1135 {
1136 	uint8_t i = 0;
1137 	uint8_t chnl_count = 0;
1138 	uint16_t start_chan_freq = 0;
1139 
1140 	for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) {
1141 		start_chan_freq = bmap->chan_bonding_set[i].start_chan_freq;
1142 		if ((bmap->chan_bonding_set[i].chan_map &
1143 			DFS_40MHZ_MASK_L) == DFS_40MHZ_MASK_L) {
1144 			avail_freq_list[chnl_count++] = start_chan_freq +
1145 				(DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 0);
1146 			avail_freq_list[chnl_count++] = start_chan_freq +
1147 				(DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 1);
1148 		}
1149 		if ((bmap->chan_bonding_set[i].chan_map &
1150 			DFS_40MHZ_MASK_H) == DFS_40MHZ_MASK_H) {
1151 			avail_freq_list[chnl_count++] = start_chan_freq +
1152 				(DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 2);
1153 			avail_freq_list[chnl_count++] = start_chan_freq +
1154 				(DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 3);
1155 		}
1156 	}
1157 
1158 	dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1159 		 "channel count %d", chnl_count);
1160 
1161 	return chnl_count;
1162 }
1163 #endif
1164 
1165 /**
1166  * dfs_populate_available_channels()- Populate channels based on width and
1167  *                                    bitmap
1168  * @dfs: Pointer to DFS structure.
1169  * @bitmap: bitmap
1170  * @ch_width: channel width
1171  * @avail_chnl: prepared channel list
1172  *
1173  * Prepare channel list based on width and channel bitmap.
1174  *
1175  * Return: channel count
1176  */
1177 #ifdef CONFIG_CHAN_NUM_API
1178 static uint8_t dfs_populate_available_channels(
1179 		struct wlan_dfs *dfs,
1180 		struct chan_bonding_bitmap *bitmap,
1181 		uint8_t ch_width,
1182 		uint8_t *avail_chnl)
1183 {
1184 	switch (ch_width) {
1185 	case DFS_CH_WIDTH_160MHZ:
1186 	case DFS_CH_WIDTH_80P80MHZ:
1187 	case DFS_CH_WIDTH_80MHZ:
1188 		return dfs_populate_80mhz_available_channels(
1189 			dfs, bitmap, avail_chnl);
1190 	case DFS_CH_WIDTH_40MHZ:
1191 		return dfs_populate_40mhz_available_channels(
1192 			dfs, bitmap, avail_chnl);
1193 	default:
1194 		dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1195 				"Invalid ch_width %d", ch_width);
1196 		break;
1197 	}
1198 
1199 	return 0;
1200 }
1201 #endif
1202 
1203 /**
1204  * dfs_populate_available_channel_for_freq()- Populate channels based on width
1205  * and bitmap.
1206  * @dfs: Pointer to DFS structure.
1207  * @bitmap: bitmap
1208  * @chan_width: channel width
1209  * @avail_freq_list: prepared channel list
1210  *
1211  * Prepare channel list based on width and channel bitmap.
1212  *
1213  * Return: channel count
1214  */
1215 #ifdef CONFIG_CHAN_FREQ_API
1216 static uint8_t
1217 dfs_populate_available_channel_for_freq(struct wlan_dfs *dfs,
1218 					struct chan_bonding_bitmap *bitmap,
1219 					uint8_t chan_width,
1220 					uint16_t *freq_list)
1221 {
1222 	switch (chan_width) {
1223 	case DFS_CH_WIDTH_160MHZ:
1224 	case DFS_CH_WIDTH_80P80MHZ:
1225 	case DFS_CH_WIDTH_80MHZ:
1226 		return dfs_populate_80mhz_available_channel_for_freq(dfs,
1227 								     bitmap,
1228 								     freq_list);
1229 	case DFS_CH_WIDTH_40MHZ:
1230 		return dfs_populate_40mhz_available_channel_for_freq(dfs,
1231 								     bitmap,
1232 								     freq_list);
1233 	default:
1234 		dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1235 			"Invalid chan_width %d", chan_width);
1236 		break;
1237 	}
1238 
1239 	return 0;
1240 }
1241 #endif
1242 
1243 /**
1244  * dfs_get_rand_from_lst()- Get random channel from a given channel list
1245  * @dfs: Pointer to DFS structure.
1246  * @ch_lst: channel list
1247  * @num_ch: number of channels
1248  *
1249  * Get random channel from given channel list.
1250  *
1251  * Return: channel number
1252  */
1253 #ifdef CONFIG_CHAN_NUM_API
1254 static uint8_t dfs_get_rand_from_lst(
1255 		struct wlan_dfs *dfs,
1256 		uint8_t *ch_lst,
1257 		uint8_t num_ch)
1258 {
1259 	uint8_t i;
1260 	uint32_t rand_byte = 0;
1261 
1262 	if (!num_ch || !ch_lst) {
1263 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
1264 				"invalid param ch_lst %pK, num_ch = %d",
1265 				ch_lst, num_ch);
1266 		return 0;
1267 	}
1268 
1269 	get_random_bytes((uint8_t *)&rand_byte, 1);
1270 	i = (rand_byte + qdf_mc_timer_get_system_ticks()) % num_ch;
1271 
1272 	dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1273 			"random channel %d", ch_lst[i]);
1274 
1275 	return ch_lst[i];
1276 }
1277 #endif
1278 
1279 /**
1280  * dfs_get_rand_from_lst_for_freq()- Get random channel from a given channel
1281  * list.
1282  * @dfs: Pointer to DFS structure.
1283  * @freq_lst: Frequency list
1284  * @num_chan: number of channels
1285  *
1286  * Get random channel from given channel list.
1287  *
1288  * Return: channel frequency.
1289  */
1290 
1291 #ifdef CONFIG_CHAN_FREQ_API
1292 static uint16_t dfs_get_rand_from_lst_for_freq(struct wlan_dfs *dfs,
1293 					       uint16_t *freq_lst,
1294 					       uint8_t num_chan)
1295 {
1296 	uint8_t i;
1297 	uint32_t rand_byte = 0;
1298 
1299 	if (!num_chan || !freq_lst) {
1300 		dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
1301 			"invalid param freq_lst %pK, num_chan = %d",
1302 			freq_lst, num_chan);
1303 		return 0;
1304 	}
1305 
1306 	get_random_bytes((uint8_t *)&rand_byte, 1);
1307 	i = (rand_byte + qdf_mc_timer_get_system_ticks()) % num_chan;
1308 
1309 	dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1310 		 "random channel %d", freq_lst[i]);
1311 
1312 	return freq_lst[i];
1313 }
1314 #endif
1315 
1316 /**
1317  * dfs_random_channel_sel_set_bitmap()- Set channel bit in bitmap based
1318  * on given channel number
1319  * @dfs: Pointer to DFS structure.
1320  * @bitmap: bitmap
1321  * @channel: channel number
1322  *
1323  * Set channel bit in bitmap based on given channel number.
1324  *
1325  * Return: None
1326  */
1327 #ifdef CONFIG_CHAN_NUM_API
1328 static void dfs_random_channel_sel_set_bitmap(
1329 		struct wlan_dfs *dfs,
1330 		struct chan_bonding_bitmap *bitmap,
1331 		uint8_t channel)
1332 {
1333 	int i = 0;
1334 	int start_chan = 0;
1335 
1336 	for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) {
1337 		start_chan = bitmap->chan_bonding_set[i].start_chan;
1338 		if (channel >= start_chan && channel <= start_chan + 12) {
1339 			bitmap->chan_bonding_set[i].chan_map |=
1340 			(1 << ((channel - start_chan) /
1341 			DFS_80_NUM_SUB_CHANNEL));
1342 			return;
1343 		}
1344 	}
1345 
1346 	dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1347 			"Channel=%d is not in the bitmap", channel);
1348 }
1349 #endif
1350 
1351 /**
1352  * dfs_random_channel_sel_set_bitmap()- Set channel bit in bitmap based
1353  * on given channel number
1354  * @dfs: Pointer to DFS structure.
1355  * @bitmap: bitmap
1356  * @chan_freq: channel frequency
1357  *
1358  * Set channel bit in bitmap based on given channel frequency.
1359  *
1360  * Return: None
1361  */
1362 #ifdef CONFIG_CHAN_FREQ_API
1363 #define FREQUENCY_BAND_LIMIT 60
1364 static void
1365 dfs_random_channel_sel_set_bitmap_for_freq(struct wlan_dfs *dfs,
1366 					   struct chan_bonding_bitmap *bitmap,
1367 					   uint16_t chan_freq)
1368 {
1369 	int i = 0;
1370 	int start_chan_freq = 0;
1371 
1372 	for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) {
1373 		start_chan_freq = bitmap->chan_bonding_set[i].start_chan_freq;
1374 		if (chan_freq >= start_chan_freq &&
1375 		    chan_freq <= start_chan_freq +
1376 		    FREQUENCY_BAND_LIMIT) {
1377 			bitmap->chan_bonding_set[i].chan_map |=
1378 				(1 << ((chan_freq - start_chan_freq) /
1379 				       DFS_80_NUM_SUB_CHANNEL_FREQ));
1380 			return;
1381 		}
1382 	}
1383 
1384 	dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1385 		  "Frequency=%d is not in the bitmap", chan_freq);
1386 }
1387 #endif
1388 
1389 /**
1390  * dfs_find_ch_with_fallback()- find random channel
1391  * @dfs: Pointer to DFS structure.
1392  * @ch_wd: channel width
1393  * @center_freq_seg1: center frequency of secondary segment.
1394  * @ch_lst: list of available channels.
1395  * @num_ch: number of channels in the list.
1396  *
1397  * Find random channel based on given channel width and channel list,
1398  * fallback to lower width if requested channel width not available.
1399  *
1400  * Return: channel number
1401  */
1402 #ifdef CONFIG_CHAN_NUM_API
1403 static uint8_t dfs_find_ch_with_fallback(
1404 		struct wlan_dfs *dfs,
1405 		uint8_t *ch_wd,
1406 		uint8_t *center_freq_seg1,
1407 		uint8_t *ch_lst,
1408 		uint32_t num_ch)
1409 {
1410 	bool flag = false;
1411 	uint32_t rand_byte = 0;
1412 	struct  chan_bonding_bitmap ch_map = { { {0} } };
1413 	uint8_t count = 0, i, index = 0, final_cnt = 0, target_channel = 0;
1414 	uint8_t primary_seg_start_ch = 0, sec_seg_ch = 0, new_160_start_ch = 0;
1415 	uint8_t final_lst[DFS_MAX_NUM_CHAN] = {0};
1416 
1417 	/* initialize ch_map for all 80 MHz bands: we have 6 80MHz bands */
1418 	ch_map.chan_bonding_set[0].start_chan = 36;
1419 	ch_map.chan_bonding_set[1].start_chan = 52;
1420 	ch_map.chan_bonding_set[2].start_chan = 100;
1421 	ch_map.chan_bonding_set[3].start_chan = 116;
1422 	ch_map.chan_bonding_set[4].start_chan = 132;
1423 	ch_map.chan_bonding_set[5].start_chan = 149;
1424 
1425 	for (i = 0; i < num_ch; i++) {
1426 		dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1427 				"channel = %d added to bitmap", ch_lst[i]);
1428 		dfs_random_channel_sel_set_bitmap(dfs, &ch_map, ch_lst[i]);
1429 	}
1430 
1431 	/* populate available channel list from bitmap */
1432 	final_cnt = dfs_populate_available_channels(dfs, &ch_map,
1433 			*ch_wd, final_lst);
1434 
1435 	/* If no valid ch bonding found, fallback */
1436 	if (final_cnt == 0) {
1437 		if ((*ch_wd == DFS_CH_WIDTH_160MHZ) ||
1438 		    (*ch_wd == DFS_CH_WIDTH_80P80MHZ) ||
1439 		    (*ch_wd == DFS_CH_WIDTH_80MHZ)) {
1440 			dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1441 					"from [%d] to 40Mhz", *ch_wd);
1442 			*ch_wd = DFS_CH_WIDTH_40MHZ;
1443 		} else if (*ch_wd == DFS_CH_WIDTH_40MHZ) {
1444 			dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1445 					"from 40Mhz to 20MHz");
1446 			*ch_wd = DFS_CH_WIDTH_20MHZ;
1447 		}
1448 		return 0;
1449 	}
1450 
1451 	/* ch count should be > 8 to switch new channel in 160Mhz band */
1452 	if (((*ch_wd == DFS_CH_WIDTH_160MHZ) ||
1453 	     (*ch_wd == DFS_CH_WIDTH_80P80MHZ)) &&
1454 	     (final_cnt < DFS_MAX_20M_SUB_CH)) {
1455 		dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1456 				"from [%d] to 80Mhz", *ch_wd);
1457 		*ch_wd = DFS_CH_WIDTH_80MHZ;
1458 		return 0;
1459 	}
1460 
1461 	if (*ch_wd == DFS_CH_WIDTH_160MHZ) {
1462 		/*
1463 		 * Only 2 blocks for 160Mhz bandwidth i.e 36-64 & 100-128
1464 		 * and all the channels in these blocks are continuous
1465 		 * and separated by 4Mhz.
1466 		 */
1467 		for (i = 1; ((i < final_cnt)); i++) {
1468 			if ((final_lst[i] - final_lst[i-1]) ==
1469 			     DFS_NEXT_5GHZ_CHANNEL)
1470 				count++;
1471 			else
1472 				count = 0;
1473 			if (count == DFS_MAX_20M_SUB_CH - 1) {
1474 				flag = true;
1475 				new_160_start_ch = final_lst[i - count];
1476 				break;
1477 			}
1478 		}
1479 	} else if (*ch_wd == DFS_CH_WIDTH_80P80MHZ) {
1480 		flag = true;
1481 	}
1482 
1483 	if ((flag == false) && (*ch_wd > DFS_CH_WIDTH_80MHZ)) {
1484 		dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1485 				"from [%d] to 80Mhz", *ch_wd);
1486 		*ch_wd = DFS_CH_WIDTH_80MHZ;
1487 		return 0;
1488 	}
1489 
1490 	if (*ch_wd == DFS_CH_WIDTH_160MHZ) {
1491 		get_random_bytes((uint8_t *)&rand_byte, 1);
1492 		rand_byte = (rand_byte + qdf_mc_timer_get_system_ticks())
1493 			% DFS_MAX_20M_SUB_CH;
1494 		target_channel = new_160_start_ch + (rand_byte *
1495 				DFS_80_NUM_SUB_CHANNEL);
1496 	} else if (*ch_wd == DFS_CH_WIDTH_80P80MHZ) {
1497 		get_random_bytes((uint8_t *)&rand_byte, 1);
1498 		index = (rand_byte + qdf_mc_timer_get_system_ticks()) %
1499 			final_cnt;
1500 		target_channel = final_lst[index];
1501 		index -= (index % DFS_80_NUM_SUB_CHANNEL);
1502 		primary_seg_start_ch = final_lst[index];
1503 
1504 		/* reset channels associate with primary 80Mhz */
1505 		for (i = 0; i < DFS_80_NUM_SUB_CHANNEL; i++)
1506 			final_lst[i + index] = 0;
1507 		/* select and calculate center freq for secondary segment */
1508 		for (i = 0; i < final_cnt / DFS_80_NUM_SUB_CHANNEL; i++) {
1509 			if (final_lst[i * DFS_80_NUM_SUB_CHANNEL] &&
1510 			    (abs(primary_seg_start_ch -
1511 			     final_lst[i * DFS_80_NUM_SUB_CHANNEL]) >
1512 			     (DFS_MAX_20M_SUB_CH * 2))) {
1513 				sec_seg_ch =
1514 					final_lst[i * DFS_80_NUM_SUB_CHANNEL] +
1515 					DFS_80MHZ_START_CENTER_CH_DIFF;
1516 				break;
1517 			}
1518 		}
1519 
1520 		if (!sec_seg_ch && (final_cnt == DFS_MAX_20M_SUB_CH))
1521 			*ch_wd = DFS_CH_WIDTH_160MHZ;
1522 		else if (!sec_seg_ch)
1523 			*ch_wd = DFS_CH_WIDTH_80MHZ;
1524 
1525 		*center_freq_seg1 = sec_seg_ch;
1526 		dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1527 				"Center frequency seg1 = %d", sec_seg_ch);
1528 	} else {
1529 		target_channel = dfs_get_rand_from_lst(dfs,
1530 				final_lst, final_cnt);
1531 	}
1532 	dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1533 			"target channel = %d", target_channel);
1534 
1535 	return target_channel;
1536 }
1537 #endif
1538 
1539 /**
1540  * dfs_find_ch_with_fallback_for_freq()- find random channel
1541  * @dfs: Pointer to DFS structure.
1542  * @chan_wd: channel width
1543  * @center_freq_seg1: center frequency of secondary segment.
1544  * @freq_lst: list of available frequency.
1545  * @num_chan: number of channels in the list.
1546  *
1547  * Find random channel based on given channel width and channel list,
1548  * fallback to lower width if requested channel width not available.
1549  *
1550  * Return: channel frequency.
1551  */
1552 #ifdef CONFIG_CHAN_FREQ_API
1553 static uint16_t dfs_find_ch_with_fallback_for_freq(struct wlan_dfs *dfs,
1554 						   uint8_t *chan_wd,
1555 						   uint16_t *center_freq_seg1,
1556 						   uint16_t *freq_lst,
1557 						   uint32_t num_chan)
1558 {
1559 	bool flag = false;
1560 	uint32_t rand_byte = 0;
1561 	struct  chan_bonding_bitmap ch_map = { { {0} } };
1562 	uint8_t count = 0, i, index = 0, final_cnt = 0;
1563 	uint16_t target_channel = 0;
1564 	uint16_t primary_seg_start_ch = 0, sec_seg_ch = 0, new_160_start_ch = 0;
1565 	uint16_t final_lst[DFS_MAX_NUM_CHAN] = {0};
1566 
1567 	/* initialize ch_map for all 80 MHz bands: we have 6 80MHz bands */
1568 	ch_map.chan_bonding_set[0].start_chan_freq = 5180;
1569 	ch_map.chan_bonding_set[1].start_chan_freq = 5260;
1570 	ch_map.chan_bonding_set[2].start_chan_freq = 5500;
1571 	ch_map.chan_bonding_set[3].start_chan_freq = 5580;
1572 	ch_map.chan_bonding_set[4].start_chan_freq = 5660;
1573 	ch_map.chan_bonding_set[5].start_chan_freq = 5745;
1574 
1575 	for (i = 0; i < num_chan; i++) {
1576 		dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1577 			  "channel = %d added to bitmap", freq_lst[i]);
1578 		dfs_random_channel_sel_set_bitmap_for_freq(dfs, &ch_map,
1579 							   freq_lst[i]);
1580 	}
1581 
1582 	/* populate available channel list from bitmap */
1583 	final_cnt = dfs_populate_available_channel_for_freq(dfs, &ch_map,
1584 							    *chan_wd, final_lst);
1585 
1586 	/* If no valid ch bonding found, fallback */
1587 	if (final_cnt == 0) {
1588 		if ((*chan_wd == DFS_CH_WIDTH_160MHZ) ||
1589 		    (*chan_wd == DFS_CH_WIDTH_80P80MHZ) ||
1590 		    (*chan_wd == DFS_CH_WIDTH_80MHZ)) {
1591 			dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1592 				 "from [%d] to 40Mhz", *chan_wd);
1593 			*chan_wd = DFS_CH_WIDTH_40MHZ;
1594 		} else if (*chan_wd == DFS_CH_WIDTH_40MHZ) {
1595 			dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1596 				 "from 40Mhz to 20MHz");
1597 			*chan_wd = DFS_CH_WIDTH_20MHZ;
1598 		}
1599 		return 0;
1600 	}
1601 
1602 	/* ch count should be > 8 to switch new channel in 160Mhz band */
1603 	if (((*chan_wd == DFS_CH_WIDTH_160MHZ) ||
1604 	     (*chan_wd == DFS_CH_WIDTH_80P80MHZ)) &&
1605 	     (final_cnt < DFS_MAX_20M_SUB_CH)) {
1606 		dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1607 			 "from [%d] to 80Mhz", *chan_wd);
1608 		*chan_wd = DFS_CH_WIDTH_80MHZ;
1609 		return 0;
1610 	}
1611 
1612 	if (*chan_wd == DFS_CH_WIDTH_160MHZ) {
1613 		/*
1614 		 * Only 2 blocks for 160Mhz bandwidth i.e 36-64 & 100-128
1615 		 * and all the channels in these blocks are continuous
1616 		 * and separated by 4Mhz.
1617 		 */
1618 		for (i = 1; ((i < final_cnt)); i++) {
1619 			if ((final_lst[i] - final_lst[i - 1]) ==
1620 			     DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET)
1621 				count++;
1622 			else
1623 				count = 0;
1624 			if (count == DFS_MAX_20M_SUB_CH - 1) {
1625 				flag = true;
1626 				new_160_start_ch = final_lst[i - count];
1627 				break;
1628 			}
1629 		}
1630 	} else if (*chan_wd == DFS_CH_WIDTH_80P80MHZ) {
1631 		flag = true;
1632 	}
1633 
1634 	if ((flag == false) && (*chan_wd > DFS_CH_WIDTH_80MHZ)) {
1635 		dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1636 			 "from [%d] to 80Mhz", *chan_wd);
1637 		*chan_wd = DFS_CH_WIDTH_80MHZ;
1638 		return 0;
1639 	}
1640 
1641 	if (*chan_wd == DFS_CH_WIDTH_160MHZ) {
1642 		get_random_bytes((uint8_t *)&rand_byte, 1);
1643 		rand_byte = (rand_byte + qdf_mc_timer_get_system_ticks())
1644 			% DFS_MAX_20M_SUB_CH;
1645 		target_channel = new_160_start_ch + (rand_byte *
1646 				DFS_80_NUM_SUB_CHANNEL_FREQ);
1647 	} else if (*chan_wd == DFS_CH_WIDTH_80P80MHZ) {
1648 		get_random_bytes((uint8_t *)&rand_byte, 1);
1649 		index = (rand_byte + qdf_mc_timer_get_system_ticks()) %
1650 			final_cnt;
1651 		target_channel = final_lst[index];
1652 		index -= (index % DFS_80_NUM_SUB_CHANNEL);
1653 		primary_seg_start_ch = final_lst[index];
1654 
1655 		/* reset channels associate with primary 80Mhz */
1656 		for (i = 0; i < DFS_80_NUM_SUB_CHANNEL; i++)
1657 			final_lst[i + index] = 0;
1658 		/* select and calculate center freq for secondary segment */
1659 		for (i = 0; i < final_cnt / DFS_80_NUM_SUB_CHANNEL; i++) {
1660 			if (final_lst[i * DFS_80_NUM_SUB_CHANNEL] &&
1661 			    (abs(primary_seg_start_ch -
1662 				 final_lst[i * DFS_80_NUM_SUB_CHANNEL]) >
1663 			     (DFS_80P80M_FREQ_DIFF * 2))) {
1664 				sec_seg_ch = final_lst[i *
1665 					DFS_80_NUM_SUB_CHANNEL] +
1666 					DFS_80MHZ_START_CENTER_CH_FREQ_DIFF;
1667 				break;
1668 			}
1669 		}
1670 
1671 		if (!sec_seg_ch && (final_cnt == DFS_MAX_20M_SUB_CH))
1672 			*chan_wd = DFS_CH_WIDTH_160MHZ;
1673 		else if (!sec_seg_ch)
1674 			*chan_wd = DFS_CH_WIDTH_80MHZ;
1675 
1676 		*center_freq_seg1 = sec_seg_ch;
1677 		dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1678 			 "Center frequency seg1 = %d", sec_seg_ch);
1679 	} else {
1680 		target_channel = dfs_get_rand_from_lst_for_freq(dfs,
1681 								final_lst,
1682 								final_cnt);
1683 	}
1684 	dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1685 		 "target channel = %d", target_channel);
1686 
1687 	return target_channel;
1688 }
1689 #endif
1690 
1691 bool dfs_is_freq_in_nol(struct wlan_dfs *dfs, uint32_t freq)
1692 {
1693 	struct dfs_nolelem *nol;
1694 
1695 	if (!dfs) {
1696 		dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,  "null dfs");
1697 		return false;
1698 	}
1699 
1700 	nol = dfs->dfs_nol;
1701 	while (nol) {
1702 		if (freq == nol->nol_freq) {
1703 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1704 					"%d is in nol", freq);
1705 			return true;
1706 		}
1707 		nol = nol->nol_next;
1708 	}
1709 
1710 	return false;
1711 }
1712 
1713 /**
1714  * dfs_apply_rules()- prepare channel list based on flags
1715  * @dfs: dfs handler
1716  * @flags: channel flags
1717  * @random_chan_list: output channel list
1718  * @random_chan_cnt: output channel count
1719  * @ch_list: input channel list
1720  * @ch_cnt: input channel count
1721  * @dfs_region: dfs region
1722  * @acs_info: acs channel range information
1723  *
1724  * prepare channel list based on flags
1725  *
1726  * return: none
1727  */
1728 #ifdef CONFIG_CHAN_NUM_API
1729 static void dfs_apply_rules(struct wlan_dfs *dfs,
1730 	uint32_t flags,
1731 	uint8_t *random_chan_list,
1732 	uint32_t *random_chan_cnt,
1733 	struct dfs_channel *ch_list,
1734 	uint32_t ch_cnt,
1735 	uint8_t dfs_region,
1736 	struct dfs_acs_info *acs_info)
1737 {
1738 	struct dfs_channel *chan;
1739 	bool flag_no_weather = 0;
1740 	bool flag_no_lower_5g = 0;
1741 	bool flag_no_upper_5g = 0;
1742 	bool flag_no_dfs_chan = 0;
1743 	bool flag_no_2g_chan  = 0;
1744 	bool flag_no_5g_chan  = 0;
1745 	bool flag_no_japan_w53 = 0;
1746 	int i;
1747 	bool found = false;
1748 	uint16_t j;
1749 
1750 	dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "flags %d", flags);
1751 	flag_no_weather = (dfs_region == DFS_ETSI_REGION_VAL) ?
1752 		flags & DFS_RANDOM_CH_FLAG_NO_WEATHER_CH : 0;
1753 
1754 	if (dfs_region == DFS_MKK_REGION_VAL) {
1755 		flag_no_lower_5g = flags & DFS_RANDOM_CH_FLAG_NO_LOWER_5G_CH;
1756 		flag_no_upper_5g = flags & DFS_RANDOM_CH_FLAG_NO_UPEER_5G_CH;
1757 		flag_no_japan_w53 = flags & DFS_RANDOM_CH_FLAG_NO_JAPAN_W53_CH;
1758 	}
1759 
1760 	flag_no_dfs_chan = flags & DFS_RANDOM_CH_FLAG_NO_DFS_CH;
1761 	flag_no_2g_chan  = flags & DFS_RANDOM_CH_FLAG_NO_2GHZ_CH;
1762 	flag_no_5g_chan  = flags & DFS_RANDOM_CH_FLAG_NO_5GHZ_CH;
1763 
1764 	for (i = 0; i < ch_cnt; i++) {
1765 		chan = &ch_list[i];
1766 
1767 		if ((chan->dfs_ch_ieee == 0) ||
1768 				(chan->dfs_ch_ieee > MAX_CHANNEL_NUM)) {
1769 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1770 				  "invalid channel %d", chan->dfs_ch_ieee);
1771 			continue;
1772 		}
1773 
1774 		if (flags & DFS_RANDOM_CH_FLAG_NO_CURR_OPE_CH) {
1775 			/* TODO : Skip all HT20 channels in the given mode */
1776 			if (chan->dfs_ch_ieee ==
1777 					dfs->dfs_curchan->dfs_ch_ieee) {
1778 				dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1779 					  "skip %d current operating channel",
1780 					  chan->dfs_ch_ieee);
1781 				continue;
1782 			}
1783 		}
1784 
1785 		if (acs_info && acs_info->acs_mode) {
1786 			for (j = 0; j < acs_info->num_of_channel; j++) {
1787 				if (acs_info->chan_freq_list[j] ==
1788 				    wlan_chan_to_freq(chan->dfs_ch_ieee)) {
1789 					found = true;
1790 					break;
1791 				}
1792 			}
1793 
1794 			if (!found) {
1795 				dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1796 					  "skip ch %d not in acs range",
1797 					  chan->dfs_ch_ieee);
1798 				continue;
1799 			}
1800 			found = false;
1801 		}
1802 
1803 		if (flag_no_2g_chan &&
1804 				chan->dfs_ch_ieee <= DFS_MAX_24GHZ_CHANNEL) {
1805 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1806 				  "skip 2.4 GHz channel=%d", chan->dfs_ch_ieee);
1807 			continue;
1808 		}
1809 
1810 		if (flag_no_5g_chan &&
1811 				chan->dfs_ch_ieee > DFS_MAX_24GHZ_CHANNEL) {
1812 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1813 				  "skip 5 GHz channel=%d", chan->dfs_ch_ieee);
1814 			continue;
1815 		}
1816 
1817 		if (flag_no_weather) {
1818 			if (DFS_IS_CHANNEL_WEATHER_RADAR(chan->dfs_ch_freq)) {
1819 				dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1820 					  "skip weather channel=%d",
1821 					  chan->dfs_ch_ieee);
1822 				continue;
1823 			}
1824 		}
1825 
1826 		if (flag_no_lower_5g &&
1827 		    DFS_IS_CHAN_JAPAN_INDOOR(chan->dfs_ch_ieee)) {
1828 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1829 				  "skip indoor channel=%d", chan->dfs_ch_ieee);
1830 			continue;
1831 		}
1832 
1833 		if (flag_no_upper_5g &&
1834 		    DFS_IS_CHAN_JAPAN_OUTDOOR(chan->dfs_ch_ieee)) {
1835 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1836 				  "skip outdoor channel=%d", chan->dfs_ch_ieee);
1837 			continue;
1838 		}
1839 
1840 		if (flag_no_dfs_chan &&
1841 		    (chan->dfs_ch_flagext & WLAN_CHAN_DFS)) {
1842 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1843 				  "skip dfs channel=%d", chan->dfs_ch_ieee);
1844 			continue;
1845 		}
1846 
1847 		if (flag_no_japan_w53 &&
1848 		    DFS_IS_CHAN_JAPAN_W53(chan->dfs_ch_ieee)) {
1849 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1850 				  "skip japan W53 channel=%d",
1851 				  chan->dfs_ch_ieee);
1852 			continue;
1853 		}
1854 
1855 		if (dfs_is_freq_in_nol(dfs, chan->dfs_ch_freq)) {
1856 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1857 				  "skip nol channel=%d", chan->dfs_ch_ieee);
1858 			continue;
1859 		}
1860 
1861 		random_chan_list[*random_chan_cnt] = chan->dfs_ch_ieee;
1862 		*random_chan_cnt += 1;
1863 	}
1864 }
1865 #endif
1866 
1867 /**
1868  * dfs_apply_rules_for_freq()- prepare channel list based on flags
1869  * @dfs: dfs handler
1870  * @flags: channel flags
1871  * @random_chan_freq_list: output channel list
1872  * @random_chan_cnt: output channel count
1873  * @chan_list: input channel list
1874  * @chan_cnt: input channel count
1875  * @dfs_region: dfs region
1876  * @acs_info: acs channel range information
1877  *
1878  * prepare channel list based on flags
1879  *
1880  * return: none
1881  */
1882 #ifdef CONFIG_CHAN_FREQ_API
1883 static void dfs_apply_rules_for_freq(struct wlan_dfs *dfs,
1884 				     uint32_t flags,
1885 				     uint16_t *random_chan_freq_list,
1886 				     uint32_t *random_chan_cnt,
1887 				     struct dfs_channel *chan_list,
1888 				     uint32_t chan_cnt,
1889 				     uint8_t dfs_region,
1890 				     struct dfs_acs_info *acs_info)
1891 {
1892 	struct dfs_channel *chan;
1893 	bool flag_no_weather = 0;
1894 	bool flag_no_lower_5g = 0;
1895 	bool flag_no_upper_5g = 0;
1896 	bool flag_no_dfs_chan = 0;
1897 	bool flag_no_2g_chan  = 0;
1898 	bool flag_no_5g_chan  = 0;
1899 	bool flag_no_japan_w53 = 0;
1900 	int i;
1901 	bool found = false;
1902 	uint16_t j;
1903 	uint16_t freq_list[NUM_CHANNELS_160MHZ];
1904 	uint8_t num_channels = 0;
1905 
1906 	dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "flags %d", flags);
1907 	flag_no_weather = (dfs_region == DFS_ETSI_REGION_VAL) ?
1908 		flags & DFS_RANDOM_CH_FLAG_NO_WEATHER_CH : 0;
1909 
1910 	if (dfs_region == DFS_MKK_REGION_VAL) {
1911 		flag_no_lower_5g = flags & DFS_RANDOM_CH_FLAG_NO_LOWER_5G_CH;
1912 		flag_no_upper_5g = flags & DFS_RANDOM_CH_FLAG_NO_UPEER_5G_CH;
1913 		flag_no_japan_w53 = flags & DFS_RANDOM_CH_FLAG_NO_JAPAN_W53_CH;
1914 	}
1915 
1916 	flag_no_dfs_chan = flags & DFS_RANDOM_CH_FLAG_NO_DFS_CH;
1917 	flag_no_2g_chan  = flags & DFS_RANDOM_CH_FLAG_NO_2GHZ_CH;
1918 	flag_no_5g_chan  = flags & DFS_RANDOM_CH_FLAG_NO_5GHZ_CH;
1919 
1920 	if (flags & DFS_RANDOM_CH_FLAG_NO_CURR_OPE_CH) {
1921 		num_channels =
1922 			dfs_get_bonding_channel_without_seg_info_for_freq
1923 			(dfs->dfs_curchan, freq_list);
1924 	}
1925 
1926 	for (i = 0; i < chan_cnt; i++) {
1927 		chan = &chan_list[i];
1928 		found = false;
1929 
1930 		if ((chan->dfs_ch_ieee == 0) ||
1931 		    (chan->dfs_ch_ieee > MAX_CHANNEL_NUM)) {
1932 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1933 				  "invalid channel %d", chan->dfs_ch_ieee);
1934 			continue;
1935 		}
1936 
1937 		if (flags & DFS_RANDOM_CH_FLAG_NO_CURR_OPE_CH) {
1938 			for (j = 0; j < num_channels; j++) {
1939 				if (chan->dfs_ch_freq == freq_list[j]) {
1940 					dfs_debug(dfs,
1941 						  WLAN_DEBUG_DFS_RANDOM_CHAN,
1942 						  "skip %d current operating channel",
1943 						  chan->dfs_ch_freq);
1944 					found = true;
1945 					break;
1946 				}
1947 			}
1948 
1949 			if (found)
1950 				continue;
1951 		}
1952 
1953 		if (acs_info && acs_info->acs_mode) {
1954 			for (j = 0; j < acs_info->num_of_channel; j++) {
1955 				if (acs_info->chan_freq_list[j] ==
1956 				    chan->dfs_ch_freq) {
1957 					found = true;
1958 					break;
1959 				}
1960 			}
1961 
1962 			if (!found) {
1963 				dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1964 					  "skip ch freq %d not in acs range",
1965 					  chan->dfs_ch_freq);
1966 				continue;
1967 			}
1968 			found = false;
1969 		}
1970 
1971 		if (flag_no_2g_chan &&
1972 		    chan->dfs_ch_freq <= DFS_MAX_24GHZ_CHANNEL_FREQ) {
1973 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1974 				  "skip 2.4 GHz channel=%d", chan->dfs_ch_ieee);
1975 			continue;
1976 		}
1977 
1978 		if (flag_no_5g_chan && chan->dfs_ch_freq >
1979 		    DFS_MAX_24GHZ_CHANNEL_FREQ)
1980 		{
1981 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1982 				  "skip 5 GHz channel=%d", chan->dfs_ch_ieee);
1983 			continue;
1984 		}
1985 
1986 		if (flag_no_weather) {
1987 			if (DFS_IS_CHANNEL_WEATHER_RADAR(chan->dfs_ch_freq)) {
1988 				dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1989 					  "skip weather channel=%d",
1990 					  chan->dfs_ch_ieee);
1991 				continue;
1992 			}
1993 		}
1994 
1995 		if (flag_no_lower_5g &&
1996 		    DFS_IS_CHAN_JAPAN_INDOOR_FREQ(chan->dfs_ch_freq)) {
1997 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
1998 				  "skip indoor channel=%d", chan->dfs_ch_ieee);
1999 			continue;
2000 		}
2001 
2002 		if (flag_no_upper_5g &&
2003 		    DFS_IS_CHAN_JAPAN_OUTDOOR_FREQ(chan->dfs_ch_freq)) {
2004 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
2005 				  "skip outdoor channel=%d", chan->dfs_ch_ieee);
2006 			continue;
2007 		}
2008 
2009 		if (flag_no_dfs_chan &&
2010 		    (chan->dfs_ch_flagext & WLAN_CHAN_DFS)) {
2011 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
2012 				  "skip dfs channel=%d", chan->dfs_ch_ieee);
2013 			continue;
2014 		}
2015 
2016 		if (flag_no_japan_w53 &&
2017 		    DFS_IS_CHAN_JAPAN_W53_FREQ(chan->dfs_ch_freq)) {
2018 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
2019 				  "skip japan W53 channel=%d",
2020 				  chan->dfs_ch_ieee);
2021 			continue;
2022 		}
2023 
2024 		if (dfs_is_freq_in_nol(dfs, chan->dfs_ch_freq)) {
2025 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
2026 				  "skip nol channel=%d", chan->dfs_ch_ieee);
2027 			continue;
2028 		}
2029 
2030 		random_chan_freq_list[*random_chan_cnt] = chan->dfs_ch_freq;
2031 		*random_chan_cnt += 1;
2032 	}
2033 }
2034 #endif
2035 
2036 #ifdef CONFIG_CHAN_NUM_API
2037 uint8_t dfs_prepare_random_channel(struct wlan_dfs *dfs,
2038 	struct dfs_channel *ch_list,
2039 	uint32_t ch_cnt,
2040 	uint32_t flags,
2041 	uint8_t *ch_wd,
2042 	struct dfs_channel *cur_chan,
2043 	uint8_t dfs_region,
2044 	struct dfs_acs_info *acs_info)
2045 {
2046 	int i = 0;
2047 	uint8_t final_cnt = 0;
2048 	uint8_t target_ch = 0;
2049 	uint8_t *random_chan_list = NULL;
2050 	uint32_t random_chan_cnt = 0;
2051 	uint16_t flag_no_weather = 0;
2052 	uint8_t *leakage_adjusted_lst;
2053 	uint8_t final_lst[NUM_CHANNELS] = {0};
2054 
2055 	if (!ch_list || !ch_cnt) {
2056 		dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
2057 				"Invalid params %pK, ch_cnt=%d",
2058 				ch_list, ch_cnt);
2059 		return 0;
2060 	}
2061 
2062 	if (*ch_wd < DFS_CH_WIDTH_20MHZ || *ch_wd > DFS_CH_WIDTH_80P80MHZ) {
2063 		dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
2064 				"Invalid ch_wd %d", *ch_wd);
2065 		return 0;
2066 	}
2067 
2068 	random_chan_list = qdf_mem_malloc(ch_cnt * sizeof(*random_chan_list));
2069 	if (!random_chan_list)
2070 		return 0;
2071 
2072 	dfs_apply_rules(dfs, flags, random_chan_list, &random_chan_cnt,
2073 		    ch_list, ch_cnt, dfs_region, acs_info);
2074 
2075 	flag_no_weather = (dfs_region == DFS_ETSI_REGION_VAL) ?
2076 		flags & DFS_RANDOM_CH_FLAG_NO_WEATHER_CH : 0;
2077 
2078 	/* list adjusted after leakage has been marked */
2079 	leakage_adjusted_lst = qdf_mem_malloc(random_chan_cnt);
2080 	if (!leakage_adjusted_lst) {
2081 		qdf_mem_free(random_chan_list);
2082 		return 0;
2083 	}
2084 
2085 	do {
2086 		qdf_mem_copy(leakage_adjusted_lst, random_chan_list,
2087 			     random_chan_cnt);
2088 		if (QDF_IS_STATUS_ERROR(dfs_mark_leaking_ch(dfs, *ch_wd,
2089 				random_chan_cnt,
2090 				leakage_adjusted_lst))) {
2091 			qdf_mem_free(random_chan_list);
2092 			qdf_mem_free(leakage_adjusted_lst);
2093 			return 0;
2094 		}
2095 
2096 		if (*ch_wd == DFS_CH_WIDTH_20MHZ) {
2097 			/*
2098 			 * PASS: 3 - from leakage_adjusted_lst, prepare valid
2099 			 * ch list and use random number from that
2100 			 */
2101 			for (i = 0; i < random_chan_cnt; i++) {
2102 				if (leakage_adjusted_lst[i] == 0)
2103 					continue;
2104 				dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
2105 					  "dfs: Channel=%d added to available list",
2106 					  leakage_adjusted_lst[i]);
2107 				final_lst[final_cnt] = leakage_adjusted_lst[i];
2108 				final_cnt++;
2109 			}
2110 			target_ch = dfs_get_rand_from_lst(
2111 				dfs, final_lst, final_cnt);
2112 			break;
2113 		}
2114 
2115 		target_ch = dfs_find_ch_with_fallback(dfs, ch_wd,
2116 				&cur_chan->dfs_ch_vhtop_ch_freq_seg2,
2117 				leakage_adjusted_lst,
2118 				random_chan_cnt);
2119 
2120 		/*
2121 		 * When flag_no_weather is set, avoid usage of Adjacent
2122 		 * weather radar channel in HT40 mode as extension channel
2123 		 * will be on 5600.
2124 		 */
2125 		if (flag_no_weather &&
2126 				(target_ch ==
2127 				 DFS_ADJACENT_WEATHER_RADAR_CHANNEL_NUM) &&
2128 				(*ch_wd == DFS_CH_WIDTH_40MHZ)) {
2129 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
2130 					"skip weather adjacent ch=%d\n",
2131 					target_ch);
2132 			continue;
2133 		}
2134 
2135 		if (target_ch)
2136 			break;
2137 	} while (true);
2138 
2139 	qdf_mem_free(random_chan_list);
2140 	qdf_mem_free(leakage_adjusted_lst);
2141 	dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "target_ch = %d", target_ch);
2142 
2143 	return target_ch;
2144 }
2145 #endif
2146 
2147 #ifdef CONFIG_CHAN_FREQ_API
2148 uint16_t dfs_prepare_random_channel_for_freq(struct wlan_dfs *dfs,
2149 					     struct dfs_channel *chan_list,
2150 					     uint32_t chan_cnt,
2151 					     uint32_t flags,
2152 					     uint8_t *chan_wd,
2153 					     struct dfs_channel *cur_chan,
2154 					     uint8_t dfs_region,
2155 					     struct dfs_acs_info *acs_info)
2156 {
2157 	int i = 0;
2158 	uint8_t final_cnt = 0;
2159 	uint16_t target_freq = 0;
2160 	uint16_t *random_chan_freq_list = NULL;
2161 	uint32_t random_chan_cnt = 0;
2162 	uint16_t flag_no_weather = 0;
2163 	uint16_t *leakage_adjusted_lst;
2164 	uint16_t final_lst[NUM_CHANNELS] = {0};
2165 	uint16_t *dfs_cfreq_seg2 = NULL;
2166 
2167 	if (!chan_list || !chan_cnt) {
2168 		dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
2169 			 "Invalid params %pK, chan_cnt=%d",
2170 			 chan_list, chan_cnt);
2171 		return 0;
2172 	}
2173 
2174 	if (*chan_wd < DFS_CH_WIDTH_20MHZ || *chan_wd > DFS_CH_WIDTH_80P80MHZ) {
2175 		dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
2176 			 "Invalid chan_wd %d", *chan_wd);
2177 		return 0;
2178 	}
2179 
2180 	random_chan_freq_list =
2181 	    qdf_mem_malloc(chan_cnt * sizeof(*random_chan_freq_list));
2182 	if (!random_chan_freq_list)
2183 		return 0;
2184 
2185 	dfs_apply_rules_for_freq(dfs, flags, random_chan_freq_list,
2186 				 &random_chan_cnt, chan_list, chan_cnt,
2187 				 dfs_region, acs_info);
2188 	flag_no_weather = (dfs_region == DFS_ETSI_REGION_VAL) ?
2189 		flags & DFS_RANDOM_CH_FLAG_NO_WEATHER_CH : 0;
2190 
2191 	/* list adjusted after leakage has been marked */
2192 	leakage_adjusted_lst = qdf_mem_malloc(random_chan_cnt *
2193 					      sizeof(*leakage_adjusted_lst));
2194 	if (!leakage_adjusted_lst) {
2195 		qdf_mem_free(random_chan_freq_list);
2196 		return 0;
2197 	}
2198 
2199 	do {
2200 		int ret;
2201 
2202 		qdf_mem_copy(leakage_adjusted_lst, random_chan_freq_list,
2203 			     random_chan_cnt * sizeof(*leakage_adjusted_lst));
2204 		ret = dfs_mark_leaking_chan_for_freq(dfs, *chan_wd,
2205 						   random_chan_cnt,
2206 						   leakage_adjusted_lst);
2207 		if (QDF_IS_STATUS_ERROR(ret)) {
2208 			qdf_mem_free(random_chan_freq_list);
2209 			qdf_mem_free(leakage_adjusted_lst);
2210 			return 0;
2211 		}
2212 
2213 		if (*chan_wd == DFS_CH_WIDTH_20MHZ) {
2214 			/*
2215 			 * PASS: 3 - from leakage_adjusted_lst, prepare valid
2216 			 * ch list and use random number from that
2217 			 */
2218 			for (i = 0; i < random_chan_cnt; i++) {
2219 				if (leakage_adjusted_lst[i] == 0)
2220 					continue;
2221 				dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
2222 					  "Channel=%d added to available list",
2223 					  leakage_adjusted_lst[i]);
2224 				final_lst[final_cnt] = leakage_adjusted_lst[i];
2225 				final_cnt++;
2226 			}
2227 			target_freq = dfs_get_rand_from_lst_for_freq(dfs,
2228 								     final_lst,
2229 								     final_cnt);
2230 			break;
2231 		}
2232 		dfs_cfreq_seg2 = &cur_chan->dfs_ch_mhz_freq_seg2;
2233 		target_freq =
2234 			dfs_find_ch_with_fallback_for_freq(dfs, chan_wd,
2235 							   dfs_cfreq_seg2,
2236 							   leakage_adjusted_lst,
2237 							   random_chan_cnt);
2238 
2239 		/* Since notion of 80+80 is not present in the regulatory
2240 		 * channel the function may return invalid 80+80 channels for
2241 		 * some devices (e.g. Pine). Therefore, check if we need to
2242 		 * correct it by checking the following condition.
2243 		 */
2244 		if ((*chan_wd == DFS_CH_WIDTH_80P80MHZ) &&
2245 		    (flags & DFS_RANDOM_CH_FLAG_RESTRICTED_80P80_ENABLED) &&
2246 		    !(CHAN_WITHIN_RESTRICTED_80P80(target_freq,
2247 				*dfs_cfreq_seg2))) {
2248 			*chan_wd = DFS_CH_WIDTH_160MHZ;
2249 			target_freq = dfs_find_ch_with_fallback_for_freq(
2250 					dfs, chan_wd, dfs_cfreq_seg2,
2251 					leakage_adjusted_lst, random_chan_cnt);
2252 		}
2253 
2254 		/*
2255 		 * When flag_no_weather is set, avoid usage of Adjacent
2256 		 * weather radar channel in HT40 mode as extension channel
2257 		 * will be on 5600.
2258 		 */
2259 		if (flag_no_weather &&
2260 		    (target_freq ==
2261 		     DFS_ADJACENT_WEATHER_RADAR_CHANNEL_FREQ) &&
2262 		    (*chan_wd == DFS_CH_WIDTH_40MHZ)) {
2263 			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
2264 				  "skip weather adjacent ch=%d\n",
2265 				  target_freq);
2266 			continue;
2267 		}
2268 
2269 		if (target_freq)
2270 			break;
2271 	} while (true);
2272 
2273 	qdf_mem_free(random_chan_freq_list);
2274 	qdf_mem_free(leakage_adjusted_lst);
2275 	dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "target_freq = %d",
2276 		 target_freq);
2277 
2278 	return target_freq;
2279 }
2280 #endif
2281