xref: /wlan-dirver/qcacld-3.0/core/sap/src/sap_fsm.c (revision c657ef50ea91125e170c3881d4126a267d3adbd6)
1 /*
2  * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
3  *
4  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5  *
6  *
7  * Permission to use, copy, modify, and/or distribute this software for
8  * any purpose with or without fee is hereby granted, provided that the
9  * above copyright notice and this permission notice appear in all
10  * copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19  * PERFORMANCE OF THIS SOFTWARE.
20  */
21 
22 /*
23  * This file was originally distributed by Qualcomm Atheros, Inc.
24  * under proprietary terms before Copyright ownership was assigned
25  * to the Linux Foundation.
26  */
27 
28 /*===========================================================================
29 
30 			s a p F s m . C
31 
32    OVERVIEW:
33 
34    This software unit holds the implementation of the WLAN SAP Finite
35    State Machine modules
36 
37    DEPENDENCIES:
38 
39    Are listed for each API below.
40    ===========================================================================*/
41 
42 /*----------------------------------------------------------------------------
43  * Include Files
44  * -------------------------------------------------------------------------*/
45 #include "sap_internal.h"
46 /* Pick up the SME API definitions */
47 #include "sme_api.h"
48 /* Pick up the PMC API definitions */
49 #include "cds_utils.h"
50 #include "cds_ieee80211_common_i.h"
51 #include "cds_reg_service.h"
52 #include "qdf_util.h"
53 #include "cds_concurrency.h"
54 
55 /*----------------------------------------------------------------------------
56  * Preprocessor Definitions and Constants
57  * -------------------------------------------------------------------------*/
58 
59 /*----------------------------------------------------------------------------
60  * Type Declarations
61  * -------------------------------------------------------------------------*/
62 
63 /*----------------------------------------------------------------------------
64  * Global Data Definitions
65  * -------------------------------------------------------------------------*/
66 
67 /*----------------------------------------------------------------------------
68  *  External declarations for global context
69  * -------------------------------------------------------------------------*/
70 #ifdef FEATURE_WLAN_CH_AVOID
71 extern sapSafeChannelType safe_channels[];
72 #endif /* FEATURE_WLAN_CH_AVOID */
73 
74 /*----------------------------------------------------------------------------
75  * Static Variable Definitions
76  * -------------------------------------------------------------------------*/
77 
78 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION
79 /*
80  * TODO: At present SAP Channel leakage matrix for ch 144
81  * is not available from system's team. So to play it safe
82  * and avoid crash if channel 144 is request, in following
83  * matix channel 144 is added such that it will cause code
84  * to avoid selecting channel 144.
85  *
86  * THESE ENTRIES SHOULD BE REPLACED WITH CORRECT VALUES AS
87  * PROVIDED BY SYSTEM'S TEAM.
88  */
89 
90 /* channel tx leakage table - ht80 */
91 tSapChanMatrixInfo ht80_chan[] = {
92 	{52,
93 	 {{36, 148}, {40, 199},
94 	  {44, 193}, {48, 197},
95 	  {52, SAP_TX_LEAKAGE_MIN}, {56, 153},
96 	  {60, 137}, {64, 134},
97 	  {100, 358}, {104, 350},
98 	  {108, 404}, {112, 344},
99 	  {116, 424}, {120, 429},
100 	  {124, 437}, {128, 435},
101 	  {132, SAP_TX_LEAKAGE_MAX}, {136, SAP_TX_LEAKAGE_MAX},
102 	  {140, SAP_TX_LEAKAGE_MAX},
103 	  {144, SAP_TX_LEAKAGE_MIN}
104 	  } },
105 
106 
107 	{56,
108 	 {{36, 171}, {40, 178},
109 	  {44, 171}, {48, 178},
110 	  {52, SAP_TX_LEAKAGE_MIN}, {56, SAP_TX_LEAKAGE_MIN},
111 	  {60, SAP_TX_LEAKAGE_MIN}, {64, 280},
112 	  {100, 351}, {104, 376},
113 	  {108, 362}, {112, 362},
114 	  {116, 403}, {120, 397},
115 	  {124, SAP_TX_LEAKAGE_MAX}, {128, SAP_TX_LEAKAGE_MAX},
116 	  {132, SAP_TX_LEAKAGE_MAX}, {136, SAP_TX_LEAKAGE_MAX},
117 	  {140, SAP_TX_LEAKAGE_MAX},
118 	  {144, SAP_TX_LEAKAGE_MIN}
119 	  } },
120 
121 	{60,
122 	 {{36, 156}, {40, 146},
123 	  {44, SAP_TX_LEAKAGE_MIN}, {48, SAP_TX_LEAKAGE_MIN},
124 	  {52, 180}, {56, SAP_TX_LEAKAGE_MIN},
125 	  {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN},
126 	  {100, 376}, {104, 360},
127 	  {108, SAP_TX_LEAKAGE_MAX}, {112, SAP_TX_LEAKAGE_MAX},
128 	  {116, 395}, {120, 399},
129 	  {124, SAP_TX_LEAKAGE_MAX}, {128, SAP_TX_LEAKAGE_MAX},
130 	  {132, SAP_TX_LEAKAGE_MAX}, {136, SAP_TX_LEAKAGE_MAX},
131 	  {140, SAP_TX_LEAKAGE_MAX},
132 	  {144, SAP_TX_LEAKAGE_MIN}
133 	  } },
134 
135 	{64,
136 	 {{36, 217}, {40, 221},
137 	  {44, SAP_TX_LEAKAGE_MIN}, {48, SAP_TX_LEAKAGE_MIN},
138 	  {52, 176}, {56, 176},
139 	  {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN},
140 	  {100, 384}, {104, 390},
141 	  {108, SAP_TX_LEAKAGE_MAX}, {112, SAP_TX_LEAKAGE_MAX},
142 	  {116, 375}, {120, 374},
143 	  {124, SAP_TX_LEAKAGE_MAX}, {128, SAP_TX_LEAKAGE_MAX},
144 	  {132, SAP_TX_LEAKAGE_MAX}, {136, SAP_TX_LEAKAGE_MAX},
145 	  {140, SAP_TX_LEAKAGE_MAX},
146 	  {144, SAP_TX_LEAKAGE_MIN}
147 	  } },
148 
149 	{100,
150 	 {{36, 357}, {40, 326},
151 	  {44, 321}, {48, 326},
152 	  {52, 378}, {56, 396},
153 	  {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
154 	  {100, SAP_TX_LEAKAGE_MIN}, {104, SAP_TX_LEAKAGE_MIN},
155 	  {108, 196}, {112, 116},
156 	  {116, 166}, {120, SAP_TX_LEAKAGE_MIN},
157 	  {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN},
158 	  {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN},
159 	  {140, SAP_TX_LEAKAGE_MIN},
160 	  {144, SAP_TX_LEAKAGE_MIN}
161 	  } },
162 
163 	{104,
164 	 {{36, 325}, {40, 325},
165 	  {44, 305}, {48, 352},
166 	  {52, 411}, {56, 411},
167 	  {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
168 	  {100, SAP_TX_LEAKAGE_MIN}, {104, SAP_TX_LEAKAGE_MIN},
169 	  {108, SAP_TX_LEAKAGE_MIN}, {112, 460},
170 	  {116, 198}, {120, SAP_TX_LEAKAGE_MIN},
171 	  {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN},
172 	  {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN},
173 	  {140, SAP_TX_LEAKAGE_MIN},
174 	  {144, SAP_TX_LEAKAGE_MIN}
175 	  } },
176 
177 	{108,
178 	 {{36, 304}, {40, 332},
179 	  {44, 310}, {48, 335},
180 	  {52, 431}, {56, 391},
181 	  {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
182 	  {100, 280}, {104, SAP_TX_LEAKAGE_MIN},
183 	  {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN},
184 	  {116, 185}, {120, SAP_TX_LEAKAGE_MIN},
185 	  {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN},
186 	  {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN},
187 	  {140, SAP_TX_LEAKAGE_MIN},
188 	  {144, SAP_TX_LEAKAGE_MIN}
189 	  } },
190 
191 	{112,
192 	 {{36, 327}, {40, 335},
193 	  {44, 331}, {48, 345},
194 	  {52, 367}, {56, 401},
195 	  {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
196 	  {100, 131}, {104, 132},
197 	  {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN},
198 	  {116, 189}, {120, SAP_TX_LEAKAGE_MIN},
199 	  {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN},
200 	  {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN},
201 	  {140, SAP_TX_LEAKAGE_MIN},
202 	  {144, SAP_TX_LEAKAGE_MIN}
203 	  } },
204 
205 	{116,
206 	 {{36, 384}, {40, 372},
207 	  {44, 389}, {48, 396},
208 	  {52, 348}, {56, 336},
209 	  {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
210 	  {100, 172}, {104, 169},
211 	  {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN},
212 	  {116, SAP_TX_LEAKAGE_MIN}, {120, SAP_TX_LEAKAGE_MIN},
213 	  {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN},
214 	  {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN},
215 	  {140, SAP_TX_LEAKAGE_MIN},
216 	  {144, SAP_TX_LEAKAGE_MIN}
217 	  } },
218 
219 	{120,
220 	 {{36, 395}, {40, 419},
221 	  {44, 439}, {48, 407},
222 	  {52, 321}, {56, 334},
223 	  {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
224 	  {100, 134}, {104, 186},
225 	  {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN},
226 	  {116, SAP_TX_LEAKAGE_MIN}, {120, SAP_TX_LEAKAGE_MIN},
227 	  {124, SAP_TX_LEAKAGE_MIN}, {128, 159},
228 	  {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN},
229 	  {140, SAP_TX_LEAKAGE_MIN},
230 	  {144, SAP_TX_LEAKAGE_MIN}
231 	  } },
232 
233 	{124,
234 	 {{36, 469}, {40, 433},
235 	  {44, 434}, {48, 435},
236 	  {52, 332}, {56, 345},
237 	  {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
238 	  {100, 146}, {104, 177},
239 	  {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN},
240 	  {116, 350}, {120, SAP_TX_LEAKAGE_MIN},
241 	  {124, SAP_TX_LEAKAGE_MIN}, {128, 138},
242 	  {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN},
243 	  {140, SAP_TX_LEAKAGE_MIN},
244 	  {144, SAP_TX_LEAKAGE_MIN}
245 	  } },
246 
247 	{128,
248 	 {{36, 408}, {40, 434},
249 	  {44, 449}, {48, 444},
250 	  {52, 341}, {56, 374},
251 	  {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
252 	  {100, 205}, {104, 208},
253 	  {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN},
254 	  {116, 142}, {120, SAP_TX_LEAKAGE_MIN},
255 	  {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN},
256 	  {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN},
257 	  {140, SAP_TX_LEAKAGE_MIN},
258 	  {144, SAP_TX_LEAKAGE_MIN}
259 	  } },
260 
261 	{132,
262 	 {{36, SAP_TX_LEAKAGE_MAX}, {40, SAP_TX_LEAKAGE_MAX},
263 	  {44, SAP_TX_LEAKAGE_MAX}, {48, SAP_TX_LEAKAGE_MAX},
264 	  {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX},
265 	  {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN},
266 	  {100, SAP_TX_LEAKAGE_MIN}, {104, SAP_TX_LEAKAGE_MIN},
267 	  {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN},
268 	  {116, SAP_TX_LEAKAGE_MIN}, {120, SAP_TX_LEAKAGE_MIN},
269 	  {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN},
270 	  {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN},
271 	  {140, SAP_TX_LEAKAGE_MIN},
272 	  {144, SAP_TX_LEAKAGE_MIN}
273 	  } },
274 
275 	{136,
276 	 {{36, SAP_TX_LEAKAGE_MAX}, {40, SAP_TX_LEAKAGE_MAX},
277 	  {44, SAP_TX_LEAKAGE_MAX}, {48, SAP_TX_LEAKAGE_MAX},
278 	  {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX},
279 	  {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN},
280 	  {100, SAP_TX_LEAKAGE_MIN}, {104, SAP_TX_LEAKAGE_MIN},
281 	  {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN},
282 	  {116, SAP_TX_LEAKAGE_MIN}, {120, SAP_TX_LEAKAGE_MIN},
283 	  {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN},
284 	  {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN},
285 	  {140, SAP_TX_LEAKAGE_MIN},
286 	  {144, SAP_TX_LEAKAGE_MIN}
287 	  } },
288 
289 	{140,
290 	 {{36, SAP_TX_LEAKAGE_MAX}, {40, SAP_TX_LEAKAGE_MAX},
291 	  {44, SAP_TX_LEAKAGE_MAX}, {48, SAP_TX_LEAKAGE_MAX},
292 	  {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX},
293 	  {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN},
294 	  {100, SAP_TX_LEAKAGE_MIN}, {104, SAP_TX_LEAKAGE_MIN},
295 	  {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN},
296 	  {116, SAP_TX_LEAKAGE_MIN}, {120, SAP_TX_LEAKAGE_MIN},
297 	  {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN},
298 	  {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN},
299 	  {144, SAP_TX_LEAKAGE_MIN}
300 	  } },
301 };
302 
303 /* channel tx leakage table - ht40 */
304 tSapChanMatrixInfo ht40_chan[] = {
305 	{52,
306 	 {{36, SAP_TX_LEAKAGE_AUTO_MIN}, {40, SAP_TX_LEAKAGE_AUTO_MIN},
307 	  {44, 230}, {48, 230},
308 	  {52, SAP_TX_LEAKAGE_MIN}, {56, SAP_TX_LEAKAGE_MIN},
309 	  {60, SAP_TX_LEAKAGE_AUTO_MIN}, {64, SAP_TX_LEAKAGE_AUTO_MIN},
310 	  {100, 625}, {104, 323},
311 	  {108, 646}, {112, 646},
312 	  {116, SAP_TX_LEAKAGE_MAX}, {120, SAP_TX_LEAKAGE_MAX},
313 	  {124, SAP_TX_LEAKAGE_MAX}, {128, SAP_TX_LEAKAGE_MAX},
314 	  {132, SAP_TX_LEAKAGE_MAX}, {136, SAP_TX_LEAKAGE_MAX},
315 	  {140, SAP_TX_LEAKAGE_MAX},
316 	  {144, SAP_TX_LEAKAGE_MIN}
317 	  } },
318 
319 	{56,
320 	 {{36, SAP_TX_LEAKAGE_AUTO_MIN}, {40, SAP_TX_LEAKAGE_AUTO_MIN},
321 	  {44, SAP_TX_LEAKAGE_AUTO_MIN}, {48, SAP_TX_LEAKAGE_AUTO_MIN},
322 	  {52, SAP_TX_LEAKAGE_MIN}, {56, SAP_TX_LEAKAGE_MIN},
323 	  {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN},
324 	  {100, 611}, {104, 611},
325 	  {108, 617}, {112, 617},
326 	  {116, SAP_TX_LEAKAGE_MAX}, {120, SAP_TX_LEAKAGE_MAX},
327 	  {124, SAP_TX_LEAKAGE_MAX}, {128, SAP_TX_LEAKAGE_MAX},
328 	  {132, SAP_TX_LEAKAGE_MAX}, {136, SAP_TX_LEAKAGE_MAX},
329 	  {140, SAP_TX_LEAKAGE_MAX},
330 	  {144, SAP_TX_LEAKAGE_MIN}
331 	  } },
332 
333 	{60,
334 	 {{36, SAP_TX_LEAKAGE_AUTO_MIN}, {40, SAP_TX_LEAKAGE_AUTO_MIN},
335 	  {44, SAP_TX_LEAKAGE_AUTO_MIN}, {48, SAP_TX_LEAKAGE_AUTO_MIN},
336 	  {52, 190}, {56, 190},
337 	  {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN},
338 	  {100, 608}, {104, 608},
339 	  {108, 623}, {112, 623},
340 	  {116, SAP_TX_LEAKAGE_MAX}, {120, SAP_TX_LEAKAGE_MAX},
341 	  {124, SAP_TX_LEAKAGE_MAX}, {128, SAP_TX_LEAKAGE_MAX},
342 	  {132, SAP_TX_LEAKAGE_MAX}, {136, SAP_TX_LEAKAGE_MAX},
343 	  {140, SAP_TX_LEAKAGE_MAX},
344 	  {144, SAP_TX_LEAKAGE_MIN}
345 	  } },
346 
347 	{64,
348 	 {{36, SAP_TX_LEAKAGE_AUTO_MIN}, {40, SAP_TX_LEAKAGE_AUTO_MIN},
349 	  {44, SAP_TX_LEAKAGE_AUTO_MIN}, {48, SAP_TX_LEAKAGE_AUTO_MIN},
350 	  {52, 295}, {56, 295},
351 	  {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN},
352 	  {100, 594}, {104, 594},
353 	  {108, 625}, {112, 625},
354 	  {116, SAP_TX_LEAKAGE_MAX}, {120, SAP_TX_LEAKAGE_MAX},
355 	  {124, SAP_TX_LEAKAGE_MAX}, {128, SAP_TX_LEAKAGE_MAX},
356 	  {132, SAP_TX_LEAKAGE_MAX}, {136, SAP_TX_LEAKAGE_MAX},
357 	  {140, SAP_TX_LEAKAGE_MAX},
358 	  {144, SAP_TX_LEAKAGE_MIN}
359 	  } },
360 
361 	{100,
362 	 {{36, 618}, {40, 618},
363 	  {44, 604}, {48, 604},
364 	  {52, 596}, {56, 596},
365 	  {60, 584}, {64, 584},
366 	  {100, SAP_TX_LEAKAGE_MIN}, {104, SAP_TX_LEAKAGE_MIN},
367 	  {108, 299}, {112, 299},
368 	  {116, SAP_TX_LEAKAGE_AUTO_MIN}, {120, SAP_TX_LEAKAGE_AUTO_MIN},
369 	  {124, SAP_TX_LEAKAGE_AUTO_MIN}, {128, SAP_TX_LEAKAGE_AUTO_MIN},
370 	  {132, 538}, {136, 538},
371 	  {140, 598},
372 	  {144, SAP_TX_LEAKAGE_MIN}
373 	  } },
374 
375 	{104,
376 	 {{36, 636}, {40, 636},
377 	  {44, 601}, {48, 601},
378 	  {52, 616}, {56, 616},
379 	  {60, 584}, {64, 584},
380 	  {100, SAP_TX_LEAKAGE_MIN}, {104, SAP_TX_LEAKAGE_MIN},
381 	  {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN},
382 	  {116, SAP_TX_LEAKAGE_AUTO_MIN}, {120, SAP_TX_LEAKAGE_AUTO_MIN},
383 	  {124, SAP_TX_LEAKAGE_AUTO_MIN}, {128, SAP_TX_LEAKAGE_AUTO_MIN},
384 	  {132, 553}, {136, 553},
385 	  {140, 568},
386 	  {144, SAP_TX_LEAKAGE_MIN}
387 	  } },
388 
389 	{108,
390 	 {{36, 600}, {40, 600},
391 	  {44, 627}, {48, 627},
392 	  {52, 611}, {56, 611},
393 	  {60, 611}, {64, 611},
394 	  {100, 214}, {104, 214},
395 	  {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN},
396 	  {116, SAP_TX_LEAKAGE_AUTO_MIN}, {120, SAP_TX_LEAKAGE_AUTO_MIN},
397 	  {124, SAP_TX_LEAKAGE_AUTO_MIN}, {128, SAP_TX_LEAKAGE_AUTO_MIN},
398 	  {132, SAP_TX_LEAKAGE_AUTO_MIN}, {136, SAP_TX_LEAKAGE_AUTO_MIN},
399 	  {140, 534},
400 	  {144, SAP_TX_LEAKAGE_MIN}
401 	  } },
402 
403 	{112,
404 	 {{36, 645}, {40, 645},
405 	  {44, 641}, {48, 641},
406 	  {52, 618}, {56, 618},
407 	  {60, 612}, {64, 612},
408 	  {100, 293}, {104, 293},
409 	  {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN},
410 	  {116, SAP_TX_LEAKAGE_MIN}, {120, SAP_TX_LEAKAGE_MIN},
411 	  {124, SAP_TX_LEAKAGE_AUTO_MIN}, {128, SAP_TX_LEAKAGE_AUTO_MIN},
412 	  {132, SAP_TX_LEAKAGE_AUTO_MIN}, {136, SAP_TX_LEAKAGE_AUTO_MIN},
413 	  {140, 521},
414 	  {144, SAP_TX_LEAKAGE_MIN}
415 	  } },
416 
417 	{116,
418 	 {{36, 661}, {40, 661},
419 	  {44, 624}, {48, 624},
420 	  {52, 634}, {56, 634},
421 	  {60, 611}, {64, 611},
422 	  {100, SAP_TX_LEAKAGE_AUTO_MIN}, {104, SAP_TX_LEAKAGE_AUTO_MIN},
423 	  {108, 217}, {112, 217},
424 	  {116, SAP_TX_LEAKAGE_MIN}, {120, SAP_TX_LEAKAGE_MIN},
425 	  {124, SAP_TX_LEAKAGE_AUTO_MIN}, {128, SAP_TX_LEAKAGE_AUTO_MIN},
426 	  {132, SAP_TX_LEAKAGE_AUTO_MIN}, {136, SAP_TX_LEAKAGE_AUTO_MIN},
427 	  {140, SAP_TX_LEAKAGE_AUTO_MIN},
428 	  {144, SAP_TX_LEAKAGE_MIN}
429 	  } },
430 
431 	{120,
432 	 {{36, 667}, {40, 667},
433 	  {44, 645}, {48, 645},
434 	  {52, 633}, {56, 633},
435 	  {60, 619}, {64, 619},
436 	  {100, SAP_TX_LEAKAGE_AUTO_MIN}, {104, SAP_TX_LEAKAGE_AUTO_MIN},
437 	  {108, 291}, {112, 291},
438 	  {116, SAP_TX_LEAKAGE_MIN}, {120, SAP_TX_LEAKAGE_MIN},
439 	  {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN},
440 	  {132, SAP_TX_LEAKAGE_AUTO_MIN}, {136, SAP_TX_LEAKAGE_AUTO_MIN},
441 	  {140, SAP_TX_LEAKAGE_AUTO_MIN},
442 	  {144, SAP_TX_LEAKAGE_MIN}
443 	  } },
444 
445 	{124,
446 	 {{36, 676}, {40, 676},
447 	  {44, 668}, {48, 668},
448 	  {52, 595}, {56, 595},
449 	  {60, 622}, {64, 622},
450 	  {100, SAP_TX_LEAKAGE_AUTO_MIN}, {104, SAP_TX_LEAKAGE_AUTO_MIN},
451 	  {108, SAP_TX_LEAKAGE_AUTO_MIN}, {112, SAP_TX_LEAKAGE_AUTO_MIN},
452 	  {116, 225}, {120, 225},
453 	  {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN},
454 	  {132, SAP_TX_LEAKAGE_AUTO_MIN}, {136, SAP_TX_LEAKAGE_AUTO_MIN},
455 	  {140, SAP_TX_LEAKAGE_AUTO_MIN},
456 	  {144, SAP_TX_LEAKAGE_MIN}
457 	  } },
458 
459 	{128,
460 	 {{36, 678}, {40, 678},
461 	  {44, 664}, {48, 664},
462 	  {52, 651}, {56, 651},
463 	  {60, 643}, {64, 643},
464 	  {100, SAP_TX_LEAKAGE_AUTO_MIN}, {104, SAP_TX_LEAKAGE_AUTO_MIN},
465 	  {108, SAP_TX_LEAKAGE_AUTO_MIN}, {112, SAP_TX_LEAKAGE_AUTO_MIN},
466 	  {116, 293}, {120, 293},
467 	  {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN},
468 	  {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN},
469 	  {140, SAP_TX_LEAKAGE_AUTO_MIN},
470 	  {144, SAP_TX_LEAKAGE_MIN}
471 	  } },
472 
473 	{132,
474 	 {{36, 689}, {40, 689},
475 	  {44, 669}, {48, 669},
476 	  {52, 662}, {56, 662},
477 	  {60, 609}, {64, 609},
478 	  {100, 538}, {104, 538},
479 	  {108, SAP_TX_LEAKAGE_AUTO_MIN}, {112, SAP_TX_LEAKAGE_AUTO_MIN},
480 	  {116, SAP_TX_LEAKAGE_AUTO_MIN}, {120, SAP_TX_LEAKAGE_AUTO_MIN},
481 	  {124, 247}, {128, 247},
482 	  {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN},
483 	  {140, SAP_TX_LEAKAGE_MIN},
484 	  {144, SAP_TX_LEAKAGE_MIN}
485 	  } },
486 
487 	{136,
488 	 {{36, 703}, {40, 703},
489 	  {44, 688}, {48, SAP_TX_LEAKAGE_MIN},
490 	  {52, 671}, {56, 671},
491 	  {60, 658}, {64, 658},
492 	  {100, 504}, {104, 504},
493 	  {108, SAP_TX_LEAKAGE_AUTO_MIN}, {112, SAP_TX_LEAKAGE_AUTO_MIN},
494 	  {116, SAP_TX_LEAKAGE_AUTO_MIN}, {120, SAP_TX_LEAKAGE_AUTO_MIN},
495 	  {124, 289}, {128, 289},
496 	  {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN},
497 	  {140, SAP_TX_LEAKAGE_MIN},
498 	  {144, SAP_TX_LEAKAGE_MIN}
499 	  } },
500 
501 	{140,
502 	 {{36, 695}, {40, 695},
503 	  {44, 684}, {48, 684},
504 	  {52, 664}, {56, 664},
505 	  {60, 658}, {64, 658},
506 	  {100, 601}, {104, 601},
507 	  {108, 545}, {112, 545},
508 	  {116, SAP_TX_LEAKAGE_AUTO_MIN}, {120, SAP_TX_LEAKAGE_AUTO_MIN},
509 	  {124, SAP_TX_LEAKAGE_AUTO_MIN}, {128, SAP_TX_LEAKAGE_AUTO_MIN},
510 	  {132, 262}, {136, 262},
511 	  {140, SAP_TX_LEAKAGE_MIN},
512 	  {144, SAP_TX_LEAKAGE_MIN}
513 	  } },
514 
515 };
516 
517 /* channel tx leakage table - ht20 */
518 tSapChanMatrixInfo ht20_chan[] = {
519 	{52,
520 	 {{36, SAP_TX_LEAKAGE_AUTO_MIN}, {40, 286},
521 	  {44, 225}, {48, 121},
522 	  {52, SAP_TX_LEAKAGE_MIN}, {56, SAP_TX_LEAKAGE_MIN},
523 	  {60, 300}, {64, SAP_TX_LEAKAGE_AUTO_MIN},
524 	  {100, 637}, {104, SAP_TX_LEAKAGE_MAX},
525 	  {108, SAP_TX_LEAKAGE_MAX}, {112, SAP_TX_LEAKAGE_MAX},
526 	  {116, SAP_TX_LEAKAGE_MAX}, {120, SAP_TX_LEAKAGE_MAX},
527 	  {124, SAP_TX_LEAKAGE_MAX}, {128, SAP_TX_LEAKAGE_MAX},
528 	  {132, SAP_TX_LEAKAGE_MAX}, {136, SAP_TX_LEAKAGE_MAX},
529 	  {140, SAP_TX_LEAKAGE_MAX},
530 	  {144, SAP_TX_LEAKAGE_MIN}
531 	  } },
532 
533 	{56,
534 	 {{36, 468}, {40, SAP_TX_LEAKAGE_AUTO_MIN},
535 	  {44, SAP_TX_LEAKAGE_AUTO_MIN}, {48, 206},
536 	  {52, SAP_TX_LEAKAGE_MIN}, {56, SAP_TX_LEAKAGE_MIN},
537 	  {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN},
538 	  {100, SAP_TX_LEAKAGE_MAX}, {104, SAP_TX_LEAKAGE_MAX},
539 	  {108, SAP_TX_LEAKAGE_MAX}, {112, SAP_TX_LEAKAGE_MAX},
540 	  {116, SAP_TX_LEAKAGE_MAX}, {120, SAP_TX_LEAKAGE_MAX},
541 	  {124, SAP_TX_LEAKAGE_MAX}, {128, SAP_TX_LEAKAGE_MAX},
542 	  {132, SAP_TX_LEAKAGE_MAX}, {136, SAP_TX_LEAKAGE_MAX},
543 	  {140, SAP_TX_LEAKAGE_MAX},
544 	  {144, SAP_TX_LEAKAGE_MIN}
545 	  } },
546 
547 	{60,
548 	 {{36, 507}, {40, 440},
549 	  {44, SAP_TX_LEAKAGE_AUTO_MIN}, {48, 313},
550 	  {52, SAP_TX_LEAKAGE_MIN}, {56, SAP_TX_LEAKAGE_MIN},
551 	  {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN},
552 	  {100, SAP_TX_LEAKAGE_MAX}, {104, SAP_TX_LEAKAGE_MAX},
553 	  {108, SAP_TX_LEAKAGE_MAX}, {112, SAP_TX_LEAKAGE_MAX},
554 	  {116, SAP_TX_LEAKAGE_MAX}, {120, SAP_TX_LEAKAGE_MAX},
555 	  {124, SAP_TX_LEAKAGE_MAX}, {128, SAP_TX_LEAKAGE_MAX},
556 	  {132, SAP_TX_LEAKAGE_MAX}, {136, SAP_TX_LEAKAGE_MAX},
557 	  {140, SAP_TX_LEAKAGE_MAX},
558 	  {144, SAP_TX_LEAKAGE_MIN}
559 	  } },
560 
561 	{64,
562 	 {{36, 516}, {40, 520},
563 	  {44, 506}, {48, SAP_TX_LEAKAGE_AUTO_MIN},
564 	  {52, 301}, {56, 258},
565 	  {60, SAP_TX_LEAKAGE_MIN}, {64, SAP_TX_LEAKAGE_MIN},
566 	  {100, 620}, {104, 617},
567 	  {108, SAP_TX_LEAKAGE_MAX}, {112, SAP_TX_LEAKAGE_MAX},
568 	  {116, SAP_TX_LEAKAGE_MAX}, {120, SAP_TX_LEAKAGE_MAX},
569 	  {124, SAP_TX_LEAKAGE_MAX}, {128, SAP_TX_LEAKAGE_MAX},
570 	  {132, SAP_TX_LEAKAGE_MAX}, {136, SAP_TX_LEAKAGE_MAX},
571 	  {140, SAP_TX_LEAKAGE_MAX},
572 	  {144, SAP_TX_LEAKAGE_MIN}
573 	  } },
574 
575 	{100,
576 	 {{36, 616}, {40, 601},
577 	  {44, 604}, {48, 589},
578 	  {52, 612}, {56, 592},
579 	  {60, 590}, {64, 582},
580 	  {100, SAP_TX_LEAKAGE_MIN}, {104, 131},
581 	  {108, SAP_TX_LEAKAGE_AUTO_MIN}, {112, SAP_TX_LEAKAGE_AUTO_MIN},
582 	  {116, SAP_TX_LEAKAGE_AUTO_MIN}, {120, 522},
583 	  {124, 571}, {128, 589},
584 	  {132, 593}, {136, 598},
585 	  {140, 594},
586 	  {144, SAP_TX_LEAKAGE_MIN},
587 	  } },
588 
589 	{104,
590 	 {{36, 622}, {40, 624},
591 	  {44, 618}, {48, 610},
592 	  {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX},
593 	  {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
594 	  {100, SAP_TX_LEAKAGE_MIN}, {104, SAP_TX_LEAKAGE_MIN},
595 	  {108, SAP_TX_LEAKAGE_MIN}, {112, 463},
596 	  {116, 483}, {120, 503},
597 	  {124, 523}, {128, 565},
598 	  {132, 570}, {136, 588},
599 	  {140, 585},
600 	  {144, SAP_TX_LEAKAGE_MIN},
601 	  } },
602 
603 	{108,
604 	 {{36, 620}, {40, 638},
605 	  {44, 611}, {48, 614},
606 	  {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX},
607 	  {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
608 	  {100, 477}, {104, SAP_TX_LEAKAGE_MIN},
609 	  {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN},
610 	  {116, 477}, {120, 497},
611 	  {124, 517}, {128, 537},
612 	  {132, 557}, {136, 577},
613 	  {140, 603},
614 	  {144, SAP_TX_LEAKAGE_MIN},
615 	  } },
616 
617 	{112,
618 	 {{36, 636}, {40, 623},
619 	  {44, 638}, {48, 628},
620 	  {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX},
621 	  {60, SAP_TX_LEAKAGE_MAX}, {64, 606},
622 	  {100, 501}, {104, 481},
623 	  {108, SAP_TX_LEAKAGE_MIN}, {112, SAP_TX_LEAKAGE_MIN},
624 	  {116, SAP_TX_LEAKAGE_MIN}, {120, 481},
625 	  {124, 501}, {128, 421},
626 	  {132, 541}, {136, 561},
627 	  {140, 583},
628 	  {144, SAP_TX_LEAKAGE_MIN},
629 	  } },
630 
631 	{116,
632 	 {{36, 646}, {40, 648},
633 	  {44, 633}, {48, 634},
634 	  {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX},
635 	  {60, 615}, {64, 594},
636 	  {100, 575}, {104, 554},
637 	  {108, 534}, {112, SAP_TX_LEAKAGE_MIN},
638 	  {116, SAP_TX_LEAKAGE_MIN}, {120, SAP_TX_LEAKAGE_MIN},
639 	  {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN},
640 	  {132, 534}, {136, 554},
641 	  {140, 574},
642 	  {144, SAP_TX_LEAKAGE_MIN},
643 	  } },
644 
645 	{120,
646 	 {{36, 643}, {40, 649},
647 	  {44, 654}, {48, 629},
648 	  {52, SAP_TX_LEAKAGE_MAX}, {56, 621},
649 	  {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
650 	  {100, 565}, {104, 545},
651 	  {108, 525}, {112, 505},
652 	  {116, SAP_TX_LEAKAGE_MIN}, {120, SAP_TX_LEAKAGE_MIN},
653 	  {124, SAP_TX_LEAKAGE_MIN}, {128, 505},
654 	  {132, 525}, {136, 545},
655 	  {140, 565},
656 	  {144, SAP_TX_LEAKAGE_MIN},
657 	  } },
658 
659 	{124,
660 	 {{36, 638}, {40, 657},
661 	  {44, 663}, {48, 649},
662 	  {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX},
663 	  {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
664 	  {100, 581}, {104, 561},
665 	  {108, 541}, {112, 521},
666 	  {116, 499}, {120, SAP_TX_LEAKAGE_MIN},
667 	  {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN},
668 	  {132, 499}, {136, 519},
669 	  {140, 539},
670 	  {144, SAP_TX_LEAKAGE_MIN}
671 	  } },
672 
673 	{128,
674 	 {{36, 651}, {40, 651},
675 	  {44, 674}, {48, 640},
676 	  {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX},
677 	  {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
678 	  {100, 603}, {104, 560},
679 	  {108, 540}, {112, 520},
680 	  {116, 499}, {120, 479},
681 	  {124, SAP_TX_LEAKAGE_MIN}, {128, SAP_TX_LEAKAGE_MIN},
682 	  {132, SAP_TX_LEAKAGE_MIN}, {136, 479},
683 	  {140, 499},
684 	  {144, SAP_TX_LEAKAGE_MIN}
685 	  } },
686 
687 	{132,
688 	 {{36, 643}, {40, 668},
689 	  {44, 651}, {48, 657},
690 	  {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX},
691 	  {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
692 	  {100, SAP_TX_LEAKAGE_MAX}, {104, 602},
693 	  {108, 578}, {112, 570},
694 	  {116, 550}, {120, 530},
695 	  {124, 510}, {128, SAP_TX_LEAKAGE_MIN},
696 	  {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN},
697 	  {140, 490},
698 	  {144, SAP_TX_LEAKAGE_MIN}
699 	  } },
700 
701 	{136,
702 	 {{36, 654}, {40, 667},
703 	  {44, 666}, {48, 642},
704 	  {52, SAP_TX_LEAKAGE_MAX}, {56, SAP_TX_LEAKAGE_MAX},
705 	  {60, SAP_TX_LEAKAGE_MAX}, {64, SAP_TX_LEAKAGE_MAX},
706 	  {100, SAP_TX_LEAKAGE_MAX}, {104, SAP_TX_LEAKAGE_MAX},
707 	  {108, SAP_TX_LEAKAGE_MAX}, {112, 596},
708 	  {116, 555}, {120, 535},
709 	  {124, 515}, {128, 495},
710 	  {132, SAP_TX_LEAKAGE_MIN}, {136, SAP_TX_LEAKAGE_MIN},
711 	  {140, SAP_TX_LEAKAGE_MIN},
712 	  {144, SAP_TX_LEAKAGE_MIN}
713 	  } },
714 
715 	{140,
716 	 {{36, 679}, {40, 673},
717 	  {44, 667}, {48, 656},
718 	  {52, 634}, {56, 663},
719 	  {60, 662}, {64, 660},
720 	  {100, SAP_TX_LEAKAGE_MAX}, {104, SAP_TX_LEAKAGE_MAX},
721 	  {108, SAP_TX_LEAKAGE_MAX}, {112, 590},
722 	  {116, 573}, {120, 553},
723 	  {124, 533}, {128, 513},
724 	  {132, 490}, {136, SAP_TX_LEAKAGE_MIN},
725 	  {140, SAP_TX_LEAKAGE_MIN},
726 	  {144, SAP_TX_LEAKAGE_MIN}
727 	  } },
728 };
729 #endif /* WLAN_ENABLE_CHNL_MATRIX_RESTRICTION */
730 
731 /*----------------------------------------------------------------------------
732  * Static Function Declarations and Definitions
733  * -------------------------------------------------------------------------*/
734 #ifdef SOFTAP_CHANNEL_RANGE
735 static QDF_STATUS sap_get_channel_list(ptSapContext sapContext,
736 				    uint8_t **channelList,
737 				    uint8_t *numberOfChannels);
738 #endif
739 
740 /*==========================================================================
741    FUNCTION    sap_get_5ghz_channel_list
742 
743    DESCRIPTION
744     Function for initializing list of  2.4/5 Ghz [NON-DFS/DFS] available
745     channels in the current regulatory domain.
746 
747    DEPENDENCIES
748     NA.
749 
750    PARAMETERS
751 
752     IN
753     sapContext: SAP Context
754 
755    RETURN VALUE
756     NA
757 
758    SIDE EFFECTS
759    ============================================================================*/
760 static QDF_STATUS sap_get_5ghz_channel_list(ptSapContext sapContext);
761 
762 /*==========================================================================
763    FUNCTION    sapStopDfsCacTimer
764 
765    DESCRIPTION
766     Function to sttop the DFS CAC timer when SAP is stopped
767    DEPENDENCIES
768     NA.
769 
770    PARAMETERS
771 
772     IN
773     sapContext: SAP Context
774    RETURN VALUE
775     DFS Timer start status
776    SIDE EFFECTS
777    ============================================================================*/
778 
779 static int sap_stop_dfs_cac_timer(ptSapContext sapContext);
780 
781 /*==========================================================================
782    FUNCTION    sapStartDfsCacTimer
783 
784    DESCRIPTION
785     Function to start the DFS CAC timer when SAP is started on DFS Channel
786    DEPENDENCIES
787     NA.
788 
789    PARAMETERS
790 
791     IN
792     sapContext: SAP Context
793    RETURN VALUE
794     DFS Timer start status
795    SIDE EFFECTS
796    ============================================================================*/
797 
798 int sap_start_dfs_cac_timer(ptSapContext sapContext);
799 
800 /** sap_hdd_event_to_string() - convert hdd event to string
801  * @event: eSapHddEvent event type
802  *
803  * This function converts eSapHddEvent into string
804  *
805  * Return: string for the @event.
806  */
807 static uint8_t *sap_hdd_event_to_string(eSapHddEvent event)
808 {
809 	switch (event) {
810 	CASE_RETURN_STRING(eSAP_START_BSS_EVENT);
811 	CASE_RETURN_STRING(eSAP_STOP_BSS_EVENT);
812 	CASE_RETURN_STRING(eSAP_STA_ASSOC_IND);
813 	CASE_RETURN_STRING(eSAP_STA_ASSOC_EVENT);
814 	CASE_RETURN_STRING(eSAP_STA_REASSOC_EVENT);
815 	CASE_RETURN_STRING(eSAP_STA_DISASSOC_EVENT);
816 	CASE_RETURN_STRING(eSAP_STA_SET_KEY_EVENT);
817 	CASE_RETURN_STRING(eSAP_STA_MIC_FAILURE_EVENT);
818 	CASE_RETURN_STRING(eSAP_ASSOC_STA_CALLBACK_EVENT);
819 	CASE_RETURN_STRING(eSAP_GET_WPSPBC_SESSION_EVENT);
820 	CASE_RETURN_STRING(eSAP_WPS_PBC_PROBE_REQ_EVENT);
821 	CASE_RETURN_STRING(eSAP_REMAIN_CHAN_READY);
822 	CASE_RETURN_STRING(eSAP_SEND_ACTION_CNF);
823 	CASE_RETURN_STRING(eSAP_DISCONNECT_ALL_P2P_CLIENT);
824 	CASE_RETURN_STRING(eSAP_MAC_TRIG_STOP_BSS_EVENT);
825 	CASE_RETURN_STRING(eSAP_UNKNOWN_STA_JOIN);
826 	CASE_RETURN_STRING(eSAP_MAX_ASSOC_EXCEEDED);
827 	CASE_RETURN_STRING(eSAP_CHANNEL_CHANGE_EVENT);
828 	CASE_RETURN_STRING(eSAP_DFS_CAC_START);
829 	CASE_RETURN_STRING(eSAP_DFS_CAC_END);
830 	CASE_RETURN_STRING(eSAP_DFS_PRE_CAC_END);
831 	CASE_RETURN_STRING(eSAP_DFS_RADAR_DETECT);
832 	CASE_RETURN_STRING(eSAP_DFS_RADAR_DETECT_DURING_PRE_CAC);
833 	CASE_RETURN_STRING(eSAP_DFS_NOL_GET);
834 	CASE_RETURN_STRING(eSAP_DFS_NOL_SET);
835 	CASE_RETURN_STRING(eSAP_DFS_NO_AVAILABLE_CHANNEL);
836 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
837 	CASE_RETURN_STRING(eSAP_ACS_SCAN_SUCCESS_EVENT);
838 #endif
839 	CASE_RETURN_STRING(eSAP_ACS_CHANNEL_SELECTED);
840 	default:
841 		return "eSAP_HDD_EVENT_UNKNOWN";
842 	}
843 }
844 
845 /*----------------------------------------------------------------------------
846  * Externalized Function Definitions
847  * -------------------------------------------------------------------------*/
848 
849 /*----------------------------------------------------------------------------
850  * Function Declarations and Documentation
851  * -------------------------------------------------------------------------*/
852 
853 /*==========================================================================
854    FUNCTION    sap_event_init
855 
856    DESCRIPTION
857     Function for initializing sWLAN_SAPEvent structure
858 
859    DEPENDENCIES
860     NA.
861 
862    PARAMETERS
863 
864     IN
865     sapEvent    : State machine event
866 
867    RETURN VALUE
868 
869     None
870 
871    SIDE EFFECTS
872    ============================================================================*/
873 static inline void sap_event_init(ptWLAN_SAPEvent sapEvent)
874 {
875 	sapEvent->event = eSAP_MAC_SCAN_COMPLETE;
876 	sapEvent->params = 0;
877 	sapEvent->u1 = 0;
878 	sapEvent->u2 = 0;
879 }
880 
881 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION
882 /*
883  * sap_find_target_channel_in_channel_matrix() - finds the leakage matrix
884  * @sapContext: Pointer to vos global context structure
885  * @ch_width: target channel width
886  * @NOL_channel: the NOL channel whose leakage matrix is required
887  * @pTarget_chnl_mtrx: pointer to target channel matrix returned.
888  *
889  * This function gives the leakage matrix for given NOL channel and ch_width
890  *
891  * Return: TRUE or FALSE
892  */
893 bool
894 sap_find_target_channel_in_channel_matrix(ptSapContext sapContext,
895 					  enum phy_ch_width ch_width,
896 					  uint8_t NOL_channel,
897 					  tSapTxLeakInfo **pTarget_chnl_mtrx)
898 {
899 	tSapTxLeakInfo *target_chan_matrix = NULL;
900 	tSapChanMatrixInfo *pchan_matrix = NULL;
901 	uint32_t nchan_matrix;
902 	int i = 0;
903 
904 	switch (ch_width) {
905 	case CH_WIDTH_20MHZ:
906 		/* HT20 */
907 		pchan_matrix = ht20_chan;
908 		nchan_matrix = QDF_ARRAY_SIZE(ht20_chan);
909 		break;
910 	case CH_WIDTH_40MHZ:
911 		/* HT40 */
912 		pchan_matrix = ht40_chan;
913 		nchan_matrix = QDF_ARRAY_SIZE(ht40_chan);
914 		break;
915 	case CH_WIDTH_80MHZ:
916 		/* HT80 */
917 		pchan_matrix = ht80_chan;
918 		nchan_matrix = QDF_ARRAY_SIZE(ht80_chan);
919 		break;
920 	default:
921 		/* handle exception and fall back to HT20 table */
922 		pchan_matrix = ht20_chan;
923 		nchan_matrix = QDF_ARRAY_SIZE(ht20_chan);
924 		break;
925 	}
926 
927 	for (i = 0; i < nchan_matrix; i++) {
928 		/* find the SAP channel to map the leakage matrix */
929 		if (NOL_channel == pchan_matrix[i].channel) {
930 			target_chan_matrix = pchan_matrix[i].chan_matrix;
931 			break;
932 		}
933 	}
934 
935 	if (NULL == target_chan_matrix) {
936 		return false;
937 	} else {
938 		*pTarget_chnl_mtrx = target_chan_matrix;
939 		return true;
940 	}
941 }
942 
943 /**
944  * sap_mark_leaking_ch() - to mark channel leaking in to nol
945  * @sap_ctx: pointer to SAP context
946  * @ch_width: channel width
947  * @nol: nol info
948  * @temp_ch_lst_sz: the target channel list
949  * @temp_ch_lst: the target channel list
950  *
951  * This function removes the channels from temp channel list that
952  * (if selected as target channel) will cause leakage in one of
953  * the NOL channels
954  *
955  * Return: QDF_STATUS
956  */
957 
958 QDF_STATUS
959 sap_mark_leaking_ch(ptSapContext sap_ctx,
960 		enum phy_ch_width ch_width,
961 		tSapDfsNolInfo *nol,
962 		uint8_t temp_ch_lst_sz,
963 		uint8_t *temp_ch_lst)
964 {
965 	tSapTxLeakInfo *target_chan_matrix = NULL;
966 	uint32_t         num_channel = (CHAN_ENUM_144 - CHAN_ENUM_36) + 1;
967 	uint32_t         i = 0;
968 	uint32_t         j = 0;
969 	uint32_t         k = 0;
970 	uint8_t          dfs_nol_channel;
971 
972 
973 	/* traverse target_chan_matrix and */
974 	for (i = 0; i < NUM_5GHZ_CHANNELS ; i++) {
975 		dfs_nol_channel = nol[i].dfs_channel_number;
976 		if (nol[i].radar_status_flag == eSAP_DFS_CHANNEL_USABLE ||
977 		    nol[i].radar_status_flag == eSAP_DFS_CHANNEL_AVAILABLE) {
978 			/* not present in NOL */
979 			continue;
980 		}
981 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
982 			FL("sapdfs: processing NOL channel: %d"),
983 			dfs_nol_channel);
984 		if (false == sap_find_target_channel_in_channel_matrix(
985 					sap_ctx, ch_width, dfs_nol_channel,
986 					&target_chan_matrix)) {
987 			/*
988 			 * should never happen, we should always find a table
989 			 * here, if we don't, need a fix here!
990 			 */
991 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
992 				  FL("Couldn't find target channel matrix!"));
993 			QDF_ASSERT(0);
994 			return QDF_STATUS_E_FAILURE;
995 		}
996 		/*
997 		 * following is based on assumption that both temp_ch_lst
998 		 * and target channel matrix are in increasing order of
999 		 * ch_id
1000 		 */
1001 		for (j = 0, k = 0; j < temp_ch_lst_sz && k < num_channel;) {
1002 			if (temp_ch_lst[j] == 0) {
1003 				j++;
1004 				continue;
1005 			}
1006 			if (target_chan_matrix[k].leak_chan != temp_ch_lst[j]) {
1007 				k++;
1008 				continue;
1009 			}
1010 			/*
1011 			 * check leakage from candidate channel
1012 			 * to NOL channel
1013 			 */
1014 			if (target_chan_matrix[k].leak_lvl <=
1015 					SAP_TX_LEAKAGE_THRES) {
1016 				/*
1017 				 * candidate channel will have
1018 				 * bad leakage in NOL channel,
1019 				 * remove from temp list
1020 				 */
1021 				QDF_TRACE(QDF_MODULE_ID_SAP,
1022 					QDF_TRACE_LEVEL_INFO_LOW,
1023 					FL("sapdfs: channel: %d will have bad leakage due to channel: %d\n"),
1024 					dfs_nol_channel, temp_ch_lst[j]);
1025 				temp_ch_lst[j] = 0;
1026 				break;
1027 			}
1028 			j++;
1029 			k++;
1030 		}
1031 	} /* end of loop that selects each NOL */
1032 	return QDF_STATUS_SUCCESS;
1033 }
1034 #endif /* end of WLAN_ENABLE_CHNL_MATRIX_RESTRICTION */
1035 
1036 /*
1037  * This function adds availabe channel to bitmap
1038  *
1039  * PARAMETERS
1040  * IN
1041  * pBitmap: bitmap to populate
1042  * channel: channel to set in bitmap
1043  */
1044 static void sap_set_bitmap(chan_bonding_bitmap *pBitmap, uint8_t channel)
1045 {
1046 	int i = 0;
1047 	int start_channel = 0;
1048 	for (i = 0; i < MAX_80MHZ_BANDS; i++) {
1049 		start_channel = pBitmap->chanBondingSet[i].startChannel;
1050 		if (channel >= start_channel && channel <= start_channel + 12) {
1051 			pBitmap->chanBondingSet[i].channelMap |=
1052 				1 << ((channel - start_channel) / 4);
1053 			return;
1054 		}
1055 	}
1056 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1057 		  FL("Channel=%d is not in the bitmap"), channel);
1058 }
1059 
1060 /**
1061  * sap_populate_available_channels() - To populate available channel
1062  * @bitmap: bitmap to populate
1063  * @ch_width: channel width
1064  * @avail_chnl: available channel list to populate
1065  *
1066  * This function reads the bitmap and populates available channel
1067  * list according to channel bonding mode. This will be called for
1068  * 80 MHz and 40 Mhz only. For 20 MHz no need for bitmap hence list
1069  * is directly created while parsing the main list
1070  *
1071  * Return: number of channels found
1072  */
1073 static uint8_t sap_populate_available_channels(chan_bonding_bitmap *bitmap,
1074 		enum phy_ch_width ch_width,
1075 		uint8_t *avail_chnl)
1076 {
1077 	uint8_t i = 0;
1078 	uint8_t chnl_count = 0;
1079 	uint8_t start_channel = 0;
1080 
1081 	switch (ch_width) {
1082 	/* VHT80 */
1083 	case CH_WIDTH_160MHZ:
1084 	case CH_WIDTH_80P80MHZ:
1085 	case CH_WIDTH_80MHZ:
1086 		for (i = 0; i < MAX_80MHZ_BANDS; i++) {
1087 			start_channel = bitmap->chanBondingSet[i].startChannel;
1088 			if (bitmap->chanBondingSet[i].channelMap ==
1089 				SAP_80MHZ_MASK) {
1090 				avail_chnl[chnl_count++] = start_channel;
1091 				avail_chnl[chnl_count++] = start_channel + 4;
1092 				avail_chnl[chnl_count++] = start_channel + 8;
1093 				avail_chnl[chnl_count++] = start_channel + 12;
1094 			}
1095 		}
1096 		break;
1097 	/* HT40 */
1098 	case CH_WIDTH_40MHZ:
1099 		for (i = 0; i < MAX_80MHZ_BANDS; i++) {
1100 			start_channel = bitmap->chanBondingSet[i].startChannel;
1101 			if ((bitmap->chanBondingSet[i].channelMap &
1102 				SAP_40MHZ_MASK_L) == SAP_40MHZ_MASK_L) {
1103 				avail_chnl[chnl_count++] = start_channel;
1104 				avail_chnl[chnl_count++] = start_channel + 4;
1105 			}
1106 			if ((bitmap->chanBondingSet[i].channelMap &
1107 				SAP_40MHZ_MASK_H) == SAP_40MHZ_MASK_H) {
1108 				avail_chnl[chnl_count++] = start_channel + 8;
1109 				avail_chnl[chnl_count++] = start_channel + 12;
1110 			}
1111 		}
1112 		break;
1113 	default:
1114 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1115 			FL("Invalid case."));
1116 		break;
1117 	}
1118 
1119 	return chnl_count;
1120 }
1121 
1122 /*
1123  * FUNCTION  sap_dfs_is_w53_invalid
1124  *
1125  * DESCRIPTION Checks if the passed channel is W53 and returns if
1126  *             SAP W53 opearation is allowed.
1127  *
1128  * DEPENDENCIES PARAMETERS
1129  * IN hHAL : HAL pointer
1130  * channelID: Channel Number to be verified
1131  *
1132  * RETURN VALUE  : bool
1133  *                 true: If W53 operation is disabled
1134  *                 false: If W53 operation is enabled
1135  *
1136  * SIDE EFFECTS
1137  */
1138 bool sap_dfs_is_w53_invalid(tHalHandle hHal, uint8_t channelID)
1139 {
1140 	tpAniSirGlobal pMac;
1141 
1142 	pMac = PMAC_STRUCT(hHal);
1143 	if (NULL == pMac) {
1144 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1145 			  FL("invalid pMac"));
1146 		return false;
1147 	}
1148 
1149 	/*
1150 	 * Check for JAPAN W53 Channel operation capability
1151 	 */
1152 	if (true == pMac->sap.SapDfsInfo.is_dfs_w53_disabled &&
1153 	    true == IS_CHAN_JAPAN_W53(channelID)) {
1154 		return true;
1155 	}
1156 
1157 	return false;
1158 }
1159 
1160 /*
1161  * FUNCTION  sap_dfs_is_channel_in_preferred_location
1162  *
1163  * DESCRIPTION Checks if the passed channel is in accordance with preferred
1164  *          Channel location settings.
1165  *
1166  * DEPENDENCIES PARAMETERS
1167  * IN hHAL : HAL pointer
1168  * channelID: Channel Number to be verified
1169  *
1170  * RETURN VALUE  :bool
1171  *        true:If Channel location is same as the preferred location
1172  *        false:If Channel location is not same as the preferred location
1173  *
1174  * SIDE EFFECTS
1175  */
1176 bool sap_dfs_is_channel_in_preferred_location(tHalHandle hHal, uint8_t channelID)
1177 {
1178 	tpAniSirGlobal pMac;
1179 
1180 	pMac = PMAC_STRUCT(hHal);
1181 	if (NULL == pMac) {
1182 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1183 			  FL("invalid pMac"));
1184 		return true;
1185 	}
1186 	if ((SAP_CHAN_PREFERRED_INDOOR ==
1187 	     pMac->sap.SapDfsInfo.sap_operating_chan_preferred_location) &&
1188 	    (true == IS_CHAN_JAPAN_OUTDOOR(channelID))) {
1189 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1190 			  FL
1191 				  ("CHAN=%d is Outdoor so invalid,preferred Indoor only"),
1192 			  channelID);
1193 		return false;
1194 	} else if ((SAP_CHAN_PREFERRED_OUTDOOR ==
1195 		    pMac->sap.SapDfsInfo.sap_operating_chan_preferred_location)
1196 		   && (true == IS_CHAN_JAPAN_INDOOR(channelID))) {
1197 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1198 			  FL
1199 				  ("CHAN=%d is Indoor so invalid,preferred Outdoor only"),
1200 			  channelID);
1201 		return false;
1202 	}
1203 
1204 	return true;
1205 }
1206 
1207 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
1208 /**
1209  * sap_check_in_avoid_ch_list() - checks if given channel present is channel
1210  * avoidance list
1211  *
1212  * @sap_ctx:        sap context.
1213  * @channel:        channel to be checked in sap_ctx's avoid ch list
1214  *
1215  * sap_ctx contains sap_avoid_ch_info strcut containing the list of channels on
1216  * which MDM device's AP with MCC was detected. This function checks if given
1217  * channel is present in that list.
1218  *
1219  * Return: true, if channel was present, false othersie.
1220  */
1221 bool sap_check_in_avoid_ch_list(ptSapContext sap_ctx, uint8_t channel)
1222 {
1223 	uint8_t i = 0;
1224 	struct sap_avoid_channels_info *ie_info =
1225 		&sap_ctx->sap_detected_avoid_ch_ie;
1226 	for (i = 0; i < sizeof(ie_info->channels); i++)
1227 		if (ie_info->channels[i] == channel)
1228 			return true;
1229 	return false;
1230 }
1231 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
1232 
1233 /**
1234  * sap_apply_rules() - validates channels in sap_ctx channel list
1235  * @sap_ctx: sap context pointer
1236  *
1237  * This function takes the channel list in sap_ctx and marks invalid channel
1238  * based on following rules:
1239  * -> invalid due to different reg domain dfs channel list
1240  * -> already present in NOL
1241  * -> outside ACS range or not
1242  * -> not usable due to another SAP operating MCC mode in same channel
1243  * -> preferred location is indoors or outdoors
1244  *
1245  * Return: number of valid channels after applying all the rules
1246  */
1247 static uint8_t sap_apply_rules(ptSapContext sap_ctx)
1248 {
1249 	uint8_t num_valid_ch, dfs_region, i = 0, ch_id;
1250 	tAll5GChannelList *sap_all_ch = &sap_ctx->SapAllChnlList;
1251 	bool is_ch_nol = false;
1252 	bool is_out_of_range = false;
1253 	tpAniSirGlobal mac_ctx;
1254 	tHalHandle hal = CDS_GET_HAL_CB(sap_ctx->p_cds_gctx);
1255 	uint8_t preferred_location;
1256 
1257 	if (NULL == hal) {
1258 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1259 			  FL("hal pointer NULL"));
1260 		return 0;
1261 	}
1262 
1263 	mac_ctx = PMAC_STRUCT(hal);
1264 	if (NULL == mac_ctx) {
1265 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1266 			  FL("mac_ctx pointer NULL"));
1267 		return 0;
1268 	}
1269 
1270 	preferred_location =
1271 		mac_ctx->sap.SapDfsInfo.sap_operating_chan_preferred_location;
1272 	cds_get_dfs_region(&dfs_region);
1273 	/* loop to check ACS range or NOL channels */
1274 	num_valid_ch = sap_all_ch->numChannel;
1275 	for (i = 0; i < sap_all_ch->numChannel; i++) {
1276 		ch_id = sap_all_ch->channelList[i].channel;
1277 
1278 		/*
1279 		 * IN MKK DFS REGION CHECK IF THE FOLLOWING TWO
1280 		 * TWO RULES APPLY AND FILTER THE AVAILABLE CHANNELS
1281 		 * ACCORDINGLY.
1282 		 *
1283 		 * 1. If we are operating in Japan regulatory domain
1284 		 * Check if Japan W53 Channel operation is NOT
1285 		 * allowed and if its not allowed then mark all the
1286 		 * W53 channels as Invalid.
1287 		 *
1288 		 * 2. If we are operating in Japan regulatory domain
1289 		 * Check if channel switch between Indoor/Outdoor
1290 		 * is allowed. If it is not allowed then limit
1291 		 * the avaiable channels to Indoor or Outdoor
1292 		 * channels only based up on the SAP Channel location
1293 		 * indicated by "sap_operating_channel_location" param.
1294 		 */
1295 		if (DFS_MKK_REGION == dfs_region) {
1296 			/*
1297 			 * Check for JAPAN W53 Channel operation capability
1298 			 */
1299 			if (true == sap_dfs_is_w53_invalid(hal, ch_id)) {
1300 				QDF_TRACE(QDF_MODULE_ID_SAP,
1301 					  QDF_TRACE_LEVEL_INFO_LOW,
1302 					  FL("index:%d, Channel=%d Invalid,Japan W53 Disabled"),
1303 					  i, ch_id);
1304 				sap_all_ch->channelList[i].valid = false;
1305 				num_valid_ch--;
1306 				continue;
1307 			}
1308 
1309 			/*
1310 			 * If SAP's preferred channel location is Indoor
1311 			 * then set all the outdoor channels in the domain
1312 			 * to invalid.If the preferred channel location is
1313 			 * outdoor then set all the Indoor channels in the
1314 			 * domain to Invalid.
1315 			 */
1316 			if (false ==
1317 			    sap_dfs_is_channel_in_preferred_location(hal,
1318 								ch_id)) {
1319 				QDF_TRACE(QDF_MODULE_ID_SAP,
1320 					  QDF_TRACE_LEVEL_INFO_LOW,
1321 					  FL("CHAN=%d is invalid,preferred Channel Location %d Only"),
1322 					  ch_id, preferred_location);
1323 				sap_all_ch->channelList[i].valid = false;
1324 				num_valid_ch--;
1325 				continue;
1326 			}
1327 		}
1328 
1329 		if (cds_get_channel_state(ch_id) == CHANNEL_STATE_DFS) {
1330 			is_ch_nol = sap_dfs_is_channel_in_nol_list(sap_ctx,
1331 					ch_id, PHY_SINGLE_CHANNEL_CENTERED);
1332 			if (true == is_ch_nol) {
1333 				/*
1334 				 * Mark this channel invalid since it is still
1335 				 * in DFS Non-Occupancy-Period which is 30 mins.
1336 				 */
1337 				QDF_TRACE(QDF_MODULE_ID_SAP,
1338 					  QDF_TRACE_LEVEL_INFO_LOW,
1339 					  FL("index: %d, Channel = %d Present in NOL LIST"),
1340 					  i, ch_id);
1341 				sap_all_ch->channelList[i].valid = false;
1342 				num_valid_ch--;
1343 				continue;
1344 			}
1345 		}
1346 
1347 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
1348 		/* avoid ch on which another MDM AP in MCC mode is detected */
1349 		if (mac_ctx->sap.sap_channel_avoidance
1350 		    && sap_ctx->sap_detected_avoid_ch_ie.present) {
1351 			if (sap_check_in_avoid_ch_list(sap_ctx, ch_id)) {
1352 				QDF_TRACE(QDF_MODULE_ID_SAP,
1353 					  QDF_TRACE_LEVEL_INFO_LOW,
1354 					  FL("index: %d, Channel = %d, avoided due to presence of another AP+AP MCC device in same channel."),
1355 					  i, ch_id);
1356 				sap_all_ch->channelList[i].valid = false;
1357 			}
1358 		}
1359 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
1360 
1361 		/* check if the channel is within ACS channel range */
1362 		is_out_of_range = sap_acs_channel_check(sap_ctx, ch_id);
1363 		if (true == is_out_of_range) {
1364 			/*
1365 			 * mark this channel invalid since it is out of ACS
1366 			 * channel range
1367 			 */
1368 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1369 				  FL("index: %d, Channel = %d out of ACS channel range"),
1370 				  i, ch_id);
1371 			sap_all_ch->channelList[i].valid = false;
1372 			num_valid_ch--;
1373 			continue;
1374 		}
1375 	} /* end of check for NOL or ACS channels */
1376 	return num_valid_ch;
1377 }
1378 
1379 /**
1380  * select_rand_from_lst() - selects random channel from given list
1381  * @mac_ctx: mac context pointer
1382  * @ch_lst: channel list
1383  * @num_ch: number of channels
1384  *
1385  * Return: new target channel randomly selected
1386  */
1387 static uint8_t select_rand_from_lst(tpAniSirGlobal mac_ctx, uint8_t *ch_lst,
1388 				    uint8_t num_ch)
1389 {
1390 	uint32_t rand_byte = 0;
1391 	uint8_t i, target_channel, non_dfs_num_ch = 0, dfs_num_ch = 0;
1392 	uint8_t dfs_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
1393 	uint8_t non_dfs_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
1394 	if (num_ch) {
1395 		for (i = 0; i < num_ch; i++) {
1396 			if (CDS_IS_DFS_CH(ch_lst[i]))
1397 				dfs_ch[dfs_num_ch++] = ch_lst[i];
1398 			else
1399 				non_dfs_ch[non_dfs_num_ch++] = ch_lst[i];
1400 		}
1401 	} else {
1402 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1403 			  FL("No target channel found"));
1404 		return 0;
1405 	}
1406 
1407 	cds_rand_get_bytes(0, (uint8_t *)&rand_byte, 1);
1408 
1409 	/* Give preference to non-DFS channel */
1410 	if (!mac_ctx->f_prefer_non_dfs_on_radar) {
1411 		i = (rand_byte + qdf_mc_timer_get_system_ticks()) % num_ch;
1412 		target_channel = ch_lst[i];
1413 	} else if (non_dfs_num_ch) {
1414 		i = (rand_byte + qdf_mc_timer_get_system_ticks()) %
1415 							non_dfs_num_ch;
1416 		target_channel = non_dfs_ch[i];
1417 	} else {
1418 		i = (rand_byte + qdf_mc_timer_get_system_ticks()) % dfs_num_ch;
1419 		target_channel = dfs_ch[i];
1420 	}
1421 
1422 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1423 		  FL("sapdfs: New Channel width = %d"),
1424 		  mac_ctx->sap.SapDfsInfo.new_chanWidth);
1425 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1426 		  FL("sapdfs: target_channel = %d"), target_channel);
1427 
1428 	return target_channel;
1429 }
1430 
1431 /**
1432  * sap_find_ch_wh_fallback() - find given channel width from given list of
1433  * channels
1434  * @mac_ctx: mac context pointer
1435  * @ch_wd: channel width to find
1436  * @ch_lst: list of channels
1437  * @num_ch: number of channels
1438  *
1439  * This function tries to find given channel width and returns new target ch.
1440  * If not found updates ch_wd to next lower channel width.
1441  *
1442  * Return: new target channel if successful, 0 otherwise
1443  */
1444 static uint8_t sap_find_ch_wh_fallback(tpAniSirGlobal mac_ctx,
1445 				       enum phy_ch_width *ch_wd,
1446 				       uint8_t *ch_lst,
1447 				       uint8_t num_ch)
1448 {
1449 	bool flag = false;
1450 	uint32_t rand_byte = 0;
1451 	chan_bonding_bitmap ch_map = { { {0} } };
1452 	uint8_t count = 0, i, index = 0, final_cnt = 0, target_channel = 0;
1453 	uint8_t primary_seg_start_ch = 0, sec_seg_ch = 0, new_160_start_ch = 0;
1454 	uint8_t final_lst[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
1455 
1456 	/* initialize ch_map for all 80 MHz bands: we have 6 80MHz bands */
1457 	ch_map.chanBondingSet[0].startChannel = 36;
1458 	ch_map.chanBondingSet[1].startChannel = 52;
1459 	ch_map.chanBondingSet[2].startChannel = 100;
1460 	ch_map.chanBondingSet[3].startChannel = 116;
1461 	ch_map.chanBondingSet[4].startChannel = 132;
1462 	ch_map.chanBondingSet[5].startChannel = 149;
1463 
1464 	/* now loop through leakage free list */
1465 	for (i = 0; i < num_ch; i++) {
1466 		/* add tmp ch to bitmap */
1467 		if (ch_lst[i] == 0)
1468 			continue;
1469 
1470 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
1471 			  FL("sapdfs: Channel=%d added to bitmap"),
1472 			  ch_lst[i]);
1473 		sap_set_bitmap(&ch_map, ch_lst[i]);
1474 	}
1475 
1476 	/* populate available channel list from bitmap */
1477 	final_cnt = sap_populate_available_channels(&ch_map, *ch_wd, final_lst);
1478 	/* If no valid ch bonding found, fallback */
1479 	if (final_cnt == 0) {
1480 		if ((*ch_wd == CH_WIDTH_160MHZ) ||
1481 			(*ch_wd == CH_WIDTH_80P80MHZ) ||
1482 			(*ch_wd == CH_WIDTH_80MHZ)) {
1483 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN,
1484 				  FL("sapdfs:Changing chanWidth from [%d] to 40Mhz"),
1485 				  *ch_wd);
1486 			*ch_wd = CH_WIDTH_40MHZ;
1487 		} else if (*ch_wd == CH_WIDTH_40MHZ) {
1488 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN,
1489 				  FL("sapdfs:No 40MHz cb found, falling to 20MHz"));
1490 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN,
1491 				  FL("sapdfs:Changing chanWidth from [%d] to [%d]"),
1492 				  *ch_wd, CH_WIDTH_20MHZ);
1493 			*ch_wd = CH_WIDTH_20MHZ;
1494 		}
1495 		return 0;
1496 	}
1497 
1498 	/* ch count should be > 8 to switch new channel in 160Mhz band */
1499 	if (((*ch_wd == CH_WIDTH_160MHZ) || (*ch_wd == CH_WIDTH_80P80MHZ)) &&
1500 			(final_cnt < SIR_DFS_MAX_20M_SUB_CH)) {
1501 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN,
1502 			FL("sapdfs:Changing chanWidth from [%d] to [%d]"),
1503 			*ch_wd, CH_WIDTH_80MHZ);
1504 		*ch_wd = CH_WIDTH_80MHZ;
1505 		return 0;
1506 	}
1507 	if (*ch_wd == CH_WIDTH_160MHZ) {
1508 		/*
1509 		 * NA supports only 2 blocks for 160Mhz bandwidth i.e 36-64 &
1510 		 * 100-128 and all the channels in these blocks are continuous
1511 		 * and seperated by 4Mhz.
1512 		 */
1513 		for (i = 1; ((i < final_cnt)); i++) {
1514 			if ((final_lst[i] - final_lst[i-1]) == 4)
1515 				count++;
1516 			else
1517 				count = 0;
1518 			if (count == SIR_DFS_MAX_20M_SUB_CH - 1) {
1519 				flag = true;
1520 				new_160_start_ch = final_lst[i-7];
1521 				break;
1522 			}
1523 		}
1524 	} else if (*ch_wd == CH_WIDTH_80P80MHZ) {
1525 		flag = true;
1526 	}
1527 	if ((flag == false) && (*ch_wd > CH_WIDTH_80MHZ)) {
1528 		*ch_wd = CH_WIDTH_80MHZ;
1529 		return 0;
1530 	}
1531 
1532 	if (*ch_wd == CH_WIDTH_160MHZ) {
1533 		cds_rand_get_bytes(0, (uint8_t *)&rand_byte, 1);
1534 		rand_byte = (rand_byte + qdf_mc_timer_get_system_ticks())
1535 				% SIR_DFS_MAX_20M_SUB_CH;
1536 		target_channel = new_160_start_ch + (rand_byte * 4);
1537 	} else if (*ch_wd == CH_WIDTH_80P80MHZ) {
1538 		cds_rand_get_bytes(0, (uint8_t *)&rand_byte, 1);
1539 		index = (rand_byte + qdf_mc_timer_get_system_ticks()) %
1540 			final_cnt;
1541 		target_channel = final_lst[index];
1542 		index -= (index % 4);
1543 		primary_seg_start_ch = final_lst[index];
1544 
1545 		/* reset channels associate with primary 80Mhz */
1546 		for (i = 0; i < 4; i++)
1547 			final_lst[i + index] = 0;
1548 		/* select and calculate center freq for secondary segement */
1549 		for (i = 0; i < final_cnt / 4; i++) {
1550 			if (final_lst[i * 4] &&
1551 			    (abs(primary_seg_start_ch - final_lst[i * 4]) >
1552 				(SIR_DFS_MAX_20M_SUB_CH * 2))) {
1553 				sec_seg_ch = final_lst[i * 4] +
1554 				SIR_80MHZ_START_CENTER_CH_DIFF;
1555 				break;
1556 			}
1557 		}
1558 		if (!sec_seg_ch && (final_cnt == SIR_DFS_MAX_20M_SUB_CH))
1559 			*ch_wd = CH_WIDTH_160MHZ;
1560 		else if (!sec_seg_ch)
1561 			*ch_wd = CH_WIDTH_80MHZ;
1562 
1563 		mac_ctx->sap.SapDfsInfo.new_ch_params.center_freq_seg1
1564 								= sec_seg_ch;
1565 
1566 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1567 			FL("sapdfs: New Center Freq Seg1 = %d"), sec_seg_ch);
1568 	} else {
1569 		target_channel = select_rand_from_lst(mac_ctx, final_lst,
1570 						      final_cnt);
1571 	}
1572 	return target_channel;
1573 }
1574 
1575 /**
1576  * sap_random_channel_sel() - This function randomly pick up an available
1577  * channel
1578  * @sap_ctx:        sap context.
1579  *
1580  * This function first eliminates invalid channel, then selects random channel
1581  * using following algorithm:
1582  * PASS: 1 - invalidate ch in sap_ctx->all_ch_lst as per rules
1583  * PASS: 2 - now mark channels that will leak into NOL
1584  * PASS: 3 - from leakage_adjusted_lst, either select random channel (for 20MHz)
1585  *           or find given channel width possible. if not found fallback to
1586  *           lower channel width and try again. once given channel width found
1587  *           use random channel from give possibilities.
1588  * Return: channel number picked
1589  */
1590 static uint8_t sap_random_channel_sel(ptSapContext sap_ctx)
1591 {
1592 	uint8_t j = 0, i = 0, final_cnt = 0, target_channel = 0;
1593 	/* count and ch list after applying all rules */
1594 	uint8_t rule_adjusted_cnt, *rule_adjusted_lst;
1595 	/* ch list after invalidating channels leaking into NOL */
1596 	uint8_t *leakage_adjusted_lst;
1597 	/* final list of channel from which random channel will be selected */
1598 	uint8_t final_lst[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
1599 	tAll5GChannelList *all_ch = &sap_ctx->SapAllChnlList;
1600 	tHalHandle hal = CDS_GET_HAL_CB(sap_ctx->p_cds_gctx);
1601 	tpAniSirGlobal mac_ctx;
1602 	/* channel width for current iteration */
1603 	enum phy_ch_width ch_wd;
1604 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION
1605 	tSapDfsNolInfo *nol;
1606 #endif
1607 
1608 	if (NULL == hal) {
1609 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1610 			  FL("invalid hal"));
1611 		return 0;
1612 	}
1613 
1614 	mac_ctx = PMAC_STRUCT(hal);
1615 	if (NULL == mac_ctx) {
1616 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1617 			  FL("invalid mac_ctx"));
1618 		return 0;
1619 	}
1620 
1621 	/*
1622 	 * Retrieve the original one and store it.
1623 	 * use the stored original value when you call this function next time
1624 	 * so fall back mechanism always starts with original ini value.
1625 	 */
1626 	if (mac_ctx->sap.SapDfsInfo.orig_chanWidth == 0) {
1627 		ch_wd = sap_ctx->ch_width_orig;
1628 		mac_ctx->sap.SapDfsInfo.orig_chanWidth = ch_wd;
1629 	} else {
1630 		ch_wd = mac_ctx->sap.SapDfsInfo.orig_chanWidth;
1631 	}
1632 
1633 	if (sap_get_5ghz_channel_list(sap_ctx)) {
1634 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1635 			  FL("Getting 5Ghz channel list failed"));
1636 		return 0;
1637 	}
1638 
1639 	/* PASS: 1 - invalidate ch in sap_ctx->all_ch_lst as per rules */
1640 	rule_adjusted_cnt = sap_apply_rules(sap_ctx);
1641 	if (0 == rule_adjusted_cnt) {
1642 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1643 			  FL("No channels left after applying rules."));
1644 		return 0;
1645 	}
1646 
1647 	/* this is list we get after applying all rules */
1648 	rule_adjusted_lst = qdf_mem_malloc(rule_adjusted_cnt);
1649 
1650 	/* list adjusted after leakage has been marked */
1651 	leakage_adjusted_lst = qdf_mem_malloc(rule_adjusted_cnt);
1652 	if (rule_adjusted_lst == NULL || leakage_adjusted_lst == NULL) {
1653 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1654 				  FL("sapdfs: memory alloc failed"));
1655 		qdf_mem_free(rule_adjusted_lst);
1656 		qdf_mem_free(leakage_adjusted_lst);
1657 		return 0;
1658 	}
1659 
1660 	/* copy valid ch from sap_ctx->all_ch_lst into rule_adjusted_lst */
1661 	for (i = 0, j = 0; i < all_ch->numChannel; i++) {
1662 		if (!all_ch->channelList[i].valid)
1663 			continue;
1664 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1665 			  FL("sapdfs: Adding Channel = %d to temp List"),
1666 			  all_ch->channelList[i].channel);
1667 		rule_adjusted_lst[j++] = all_ch->channelList[i].channel;
1668 	}
1669 
1670 	/*
1671 	 * do - while loop for fallback mechanism. at each channel width this
1672 	 * will try to find channel bonding, if not fall back to lower ch width
1673 	 */
1674 	do {
1675 		/* save rules adjusted lst */
1676 		qdf_mem_copy(leakage_adjusted_lst, rule_adjusted_lst,
1677 			     rule_adjusted_cnt);
1678 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION
1679 		nol = mac_ctx->sap.SapDfsInfo.sapDfsChannelNolList;
1680 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1681 			  FL("sapdfs: Processing tmp ch list against NOL."));
1682 		/* PASS: 2 - now mark channels that will leak into NOL */
1683 		if (sap_mark_leaking_ch(sap_ctx, ch_wd, nol, rule_adjusted_cnt,
1684 				leakage_adjusted_lst) != QDF_STATUS_SUCCESS) {
1685 			qdf_mem_free(rule_adjusted_lst);
1686 			qdf_mem_free(leakage_adjusted_lst);
1687 			return 0;
1688 		}
1689 #endif
1690 		if (ch_wd == CH_WIDTH_20MHZ) {
1691 			/*
1692 			 * PASS: 3 - from leakage_adjusted_lst, prepare valid
1693 			 * ch list and use random number from that
1694 			 */
1695 			for (i = 0; i < rule_adjusted_cnt; i++) {
1696 				if (leakage_adjusted_lst[i] == 0)
1697 					continue;
1698 				QDF_TRACE(QDF_MODULE_ID_SAP,
1699 					  QDF_TRACE_LEVEL_DEBUG,
1700 					  FL("sapdfs: Channel=%d added to available list"),
1701 					  leakage_adjusted_lst[i]);
1702 				final_lst[final_cnt] = leakage_adjusted_lst[i];
1703 				final_cnt++;
1704 			}
1705 			target_channel = select_rand_from_lst(mac_ctx,
1706 							final_lst, final_cnt);
1707 			break;
1708 		}
1709 
1710 		/*
1711 		 * PASS: 3 - following function will check from valid channels
1712 		 * left if given ch_wd can be supported. if not reduce ch_wd
1713 		 * (fallback), then continue with reduced ch_wd
1714 		 */
1715 		target_channel = sap_find_ch_wh_fallback(mac_ctx, &ch_wd,
1716 							   leakage_adjusted_lst,
1717 							   rule_adjusted_cnt);
1718 		/*
1719 		 * if target channel is 0, no channel bonding was found
1720 		 * ch_wd would have been updated for fallback
1721 		 */
1722 		if (0 == target_channel)
1723 			continue;
1724 		else
1725 			break;
1726 	} while (true);
1727 
1728 	if (target_channel)
1729 		mac_ctx->sap.SapDfsInfo.new_chanWidth = ch_wd;
1730 
1731 	qdf_mem_free(rule_adjusted_lst);
1732 	qdf_mem_free(leakage_adjusted_lst);
1733 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1734 		FL("sapdfs: New Channel width = %d"),
1735 		mac_ctx->sap.SapDfsInfo.new_chanWidth);
1736 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1737 		FL("sapdfs: target_channel = %d"),
1738 		target_channel);
1739 	return target_channel;
1740 }
1741 
1742 bool sap_acs_channel_check(ptSapContext sapContext, uint8_t channelNumber)
1743 {
1744 	int i = 0;
1745 	if (!sapContext->acs_cfg->acs_mode)
1746 		return false;
1747 
1748 	if ((channelNumber >= sapContext->acs_cfg->start_ch) ||
1749 		(channelNumber <= sapContext->acs_cfg->end_ch)) {
1750 		if (!sapContext->acs_cfg->ch_list) {
1751 			return false;
1752 		} else {
1753 			for (i = 0; i < sapContext->acs_cfg->ch_list_count; i++)
1754 				if (channelNumber ==
1755 						sapContext->acs_cfg->ch_list[i])
1756 					return false;
1757 		}
1758 	}
1759 	return true;
1760 }
1761 
1762 /**
1763  * sap_mark_dfs_channels() - to mark dfs channel
1764  * @sapContext: pointer sap context
1765  * @channels: list of channels
1766  * @numChannels: number of channels
1767  * @time: time
1768  *
1769  * Mark the channels in NOL with time and eSAP_DFS_CHANNEL_UNAVAILABLE
1770  *
1771  * Return: none
1772  */
1773 void sap_mark_dfs_channels(ptSapContext sapContext, uint8_t *channels,
1774 			   uint8_t numChannels, uint64_t time)
1775 {
1776 	int i, j;
1777 	tSapDfsNolInfo *psapDfsChannelNolList = NULL;
1778 	uint8_t nRegDomainDfsChannels;
1779 	tHalHandle hHal;
1780 	tpAniSirGlobal pMac;
1781 
1782 	hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx);
1783 	if (NULL == channels)
1784 		return;
1785 	if (NULL == hHal) {
1786 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1787 			  FL("invalid hHal"));
1788 		return;
1789 	}
1790 	pMac = PMAC_STRUCT(hHal);
1791 	if (NULL == pMac) {
1792 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1793 			  FL("invalid pMac"));
1794 		return;
1795 	}
1796 
1797 	/*
1798 	 * Mark the current channel on which Radar is found
1799 	 * in the NOL list as eSAP_DFS_CHANNEL_UNAVAILABLE.
1800 	 */
1801 	psapDfsChannelNolList = pMac->sap.SapDfsInfo.sapDfsChannelNolList;
1802 	nRegDomainDfsChannels =
1803 		pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels;
1804 
1805 	for (i = 0; i < numChannels; i++) {
1806 		for (j = 0; j <= nRegDomainDfsChannels; j++) {
1807 			if (!(psapDfsChannelNolList[j].dfs_channel_number ==
1808 					channels[i]))
1809 				continue;
1810 			/*
1811 			 * If channel is already in NOL, don't update it again.
1812 			 * This is useful when marking bonding channels which
1813 			 * are already unavailable.
1814 			 */
1815 			if (psapDfsChannelNolList[j].radar_status_flag ==
1816 					eSAP_DFS_CHANNEL_UNAVAILABLE) {
1817 				QDF_TRACE(QDF_MODULE_ID_SAP,
1818 						QDF_TRACE_LEVEL_INFO_HIGH,
1819 						FL("Channel=%d already in NOL"),
1820 						channels[i]);
1821 				continue;
1822 			}
1823 			/*
1824 			 * Capture the Radar Found timestamp on the
1825 			 * Current Channel in ms.
1826 			 */
1827 			psapDfsChannelNolList[j].radar_found_timestamp = time;
1828 			/* Mark the Channel to be unavailble for next 30 mins */
1829 			psapDfsChannelNolList[j].radar_status_flag =
1830 				eSAP_DFS_CHANNEL_UNAVAILABLE;
1831 
1832 			QDF_TRACE(QDF_MODULE_ID_SAP,
1833 				QDF_TRACE_LEVEL_INFO_HIGH,
1834 				FL("Channel=%d Added to NOL LIST"),
1835 				channels[i]);
1836 		}
1837 	}
1838 }
1839 
1840 /*
1841  * This Function is to get bonding channels from primary channel.
1842  *
1843  */
1844 uint8_t sap_get_bonding_channels(ptSapContext sapContext, uint8_t channel,
1845 				 uint8_t *channels, uint8_t size,
1846 				 ePhyChanBondState chanBondState)
1847 {
1848 	tHalHandle hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx);
1849 	tpAniSirGlobal pMac;
1850 	uint8_t numChannel;
1851 
1852 	if (channels == NULL)
1853 		return 0;
1854 
1855 	if (size < MAX_BONDED_CHANNELS)
1856 		return 0;
1857 
1858 	if (NULL != hHal) {
1859 		pMac = PMAC_STRUCT(hHal);
1860 	} else
1861 		return 0;
1862 
1863 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
1864 		  FL("cbmode: %d, channel: %d"), chanBondState, channel);
1865 
1866 	switch (chanBondState) {
1867 	case PHY_SINGLE_CHANNEL_CENTERED:
1868 		numChannel = 1;
1869 		channels[0] = channel;
1870 		break;
1871 	case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
1872 		numChannel = 2;
1873 		channels[0] = channel - 4;
1874 		channels[1] = channel;
1875 		break;
1876 	case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
1877 		numChannel = 2;
1878 		channels[0] = channel;
1879 		channels[1] = channel + 4;
1880 		break;
1881 	case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
1882 		numChannel = 4;
1883 		channels[0] = channel;
1884 		channels[1] = channel + 4;
1885 		channels[2] = channel + 8;
1886 		channels[3] = channel + 12;
1887 		break;
1888 	case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
1889 		numChannel = 4;
1890 		channels[0] = channel - 4;
1891 		channels[1] = channel;
1892 		channels[2] = channel + 4;
1893 		channels[3] = channel + 8;
1894 		break;
1895 	case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
1896 		numChannel = 4;
1897 		channels[0] = channel - 8;
1898 		channels[1] = channel - 4;
1899 		channels[2] = channel;
1900 		channels[3] = channel + 4;
1901 		break;
1902 	case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
1903 		numChannel = 4;
1904 		channels[0] = channel - 12;
1905 		channels[1] = channel - 8;
1906 		channels[2] = channel - 4;
1907 		channels[3] = channel;
1908 		break;
1909 	default:
1910 		numChannel = 1;
1911 		channels[0] = channel;
1912 		break;
1913 	}
1914 
1915 	return numChannel;
1916 }
1917 
1918 /**
1919  * sap_dfs_check_if_channel_avaialable() - Check if a channel is out of NOL
1920  * @nol: Pointer to the Non-Occupancy List.
1921  *
1922  * This function Checks if a given channel is available or
1923  * usable or unavailable based on the time lapse since the
1924  * last radar time stamp.
1925  *
1926  * Return: true if channel available or usable, false if unavailable.
1927  */
1928 static bool sap_dfs_check_if_channel_avaialable(tSapDfsNolInfo *nol)
1929 {
1930 	uint64_t time_since_last_radar, time_when_radar_found, current_time = 0;
1931 	uint64_t max_jiffies;
1932 
1933 	if ((nol->radar_status_flag == eSAP_DFS_CHANNEL_USABLE) ||
1934 	    (nol->radar_status_flag == eSAP_DFS_CHANNEL_AVAILABLE)) {
1935 		/*
1936 		 * Allow SAP operation on this channel
1937 		 * either the DFS channel has not been used
1938 		 * for SAP operation or it is available for
1939 		 * SAP operation since it is past
1940 		 * Non-Occupancy-Period so, return false.
1941 		 */
1942 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1943 			  FL("Chan=%d not in NOL,CHAN AVAILABLE"),
1944 			  nol->dfs_channel_number);
1945 		return true;
1946 	} else if (nol->radar_status_flag == eSAP_DFS_CHANNEL_UNAVAILABLE) {
1947 		/*
1948 		 * If a DFS Channel is UNAVAILABLE then
1949 		 * check to see if it is past
1950 		 * Non-occupancy-period
1951 		 * of 30 minutes. If it is past 30 mins then
1952 		 * mark the channel as AVAILABLE and return
1953 		 * false as the channel is not anymore in
1954 		 * NON-Occupancy-Period.
1955 		 */
1956 		time_when_radar_found = nol->radar_found_timestamp;
1957 		current_time = cds_get_monotonic_boottime();
1958 		if (current_time < time_when_radar_found) {
1959 			/* cds_get_monotonic_boottime() can overflow.
1960 			 * Jiffies is initialized such that 32 bit jiffies
1961 			 * value wrap 5 minutes after boot so jiffies wrap bugs
1962 			 * show up earlier
1963 			 */
1964 			max_jiffies = (uint64_t)UINT_MAX * 1000;
1965 			time_since_last_radar = (max_jiffies -
1966 				time_when_radar_found) + (current_time);
1967 		} else {
1968 			time_since_last_radar = current_time -
1969 							time_when_radar_found;
1970 		}
1971 		if (time_since_last_radar >= SAP_DFS_NON_OCCUPANCY_PERIOD) {
1972 			nol->radar_status_flag = eSAP_DFS_CHANNEL_AVAILABLE;
1973 			nol->radar_found_timestamp = 0;
1974 
1975 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1976 				  FL("Chan=%d not in NOL, Channel AVAILABLE"),
1977 				  nol->dfs_channel_number);
1978 			return true;
1979 		} else {
1980 			/*
1981 			 * Channel is not still available for
1982 			 * SAP operation so return true; As the
1983 			 * Channel is still in
1984 			 * Non-occupancy-Period.
1985 			 */
1986 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1987 				  FL("Chan=%d in NOL, Channel UNAVAILBLE"),
1988 				  nol->dfs_channel_number);
1989 			return false;
1990 		}
1991 	} else {
1992 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1993 			  FL("Invalid Radar Status Flag"));
1994 	}
1995 	return true;
1996 }
1997 
1998 /**
1999  * sap_dfs_is_channel_in_nol_list() - given bonded channel is available
2000  * @sap_context: Handle to SAP context.
2001  * @channel_number: Channel on which availability should be checked.
2002  * @chan_bondState: The channel bonding mode of the passed channel.
2003  *
2004  * This function Checks if a given bonded channel is available or
2005  * usable for DFS operation.
2006  *
2007  * Return: false if channel is available, true if channel is in NOL.
2008  */
2009 bool
2010 sap_dfs_is_channel_in_nol_list(ptSapContext sap_context,
2011 			       uint8_t channel_number,
2012 			       ePhyChanBondState chan_bondState)
2013 {
2014 	int i, j;
2015 	tHalHandle h_hal = CDS_GET_HAL_CB(sap_context->p_cds_gctx);
2016 	tpAniSirGlobal mac_ctx;
2017 	uint8_t channels[MAX_BONDED_CHANNELS];
2018 	uint8_t num_channels;
2019 	tSapDfsNolInfo *nol;
2020 	tSapDfsInfo *dfs_info;
2021 	bool channel_available;
2022 
2023 	if (NULL == h_hal) {
2024 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2025 			  FL("invalid h_hal"));
2026 		return false;
2027 	} else {
2028 		mac_ctx = PMAC_STRUCT(h_hal);
2029 	}
2030 
2031 	dfs_info = &mac_ctx->sap.SapDfsInfo;
2032 	if ((dfs_info->numCurrentRegDomainDfsChannels == 0) ||
2033 	    (dfs_info->numCurrentRegDomainDfsChannels >
2034 	     NUM_5GHZ_CHANNELS)) {
2035 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
2036 			  FL("invalid dfs channel count %d"),
2037 			  dfs_info->numCurrentRegDomainDfsChannels);
2038 		return false;
2039 	}
2040 
2041 	/* get the bonded channels */
2042 	num_channels = sap_get_bonding_channels(sap_context, channel_number,
2043 				channels, MAX_BONDED_CHANNELS, chan_bondState);
2044 
2045 	/* check for NOL, first on will break the loop */
2046 	for (j = 0; j < num_channels; j++) {
2047 		for (i = 0; i < dfs_info->numCurrentRegDomainDfsChannels; i++) {
2048 			nol = &dfs_info->sapDfsChannelNolList[i];
2049 			if (nol->dfs_channel_number != channels[j])
2050 				continue;
2051 
2052 			channel_available =
2053 				sap_dfs_check_if_channel_avaialable(nol);
2054 
2055 			if (channel_available == false)
2056 				break;
2057 
2058 		} /* loop for dfs channels */
2059 
2060 		if (i < dfs_info->numCurrentRegDomainDfsChannels)
2061 			break;
2062 
2063 	} /* loop for bonded channels */
2064 
2065 	/*
2066 	 * if any of the channel is not available, mark all available channels
2067 	 * as unavailable with same time stamp.
2068 	 */
2069 	if (j < num_channels &&
2070 	    i < dfs_info->numCurrentRegDomainDfsChannels) {
2071 		if (num_channels > MAX_BONDED_CHANNELS) {
2072 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN,
2073 				  FL("num_channel>MAX_BONDED_CHANNEL, reset"));
2074 			num_channels = MAX_BONDED_CHANNELS;
2075 		}
2076 		nol = &dfs_info->sapDfsChannelNolList[i];
2077 		sap_mark_dfs_channels(sap_context, channels, num_channels,
2078 				nol->radar_found_timestamp);
2079 
2080 		/* set DFS-NOL back to keep it update-to-date in CNSS */
2081 		sap_signal_hdd_event(sap_context, NULL, eSAP_DFS_NOL_SET,
2082 				  (void *) eSAP_STATUS_SUCCESS);
2083 
2084 		return true;
2085 	}
2086 
2087 	return false;
2088 }
2089 
2090 /**
2091  * sap_goto_channel_sel - Function for initiating scan request for SME
2092  * @sap_context: Sap Context value.
2093  * @sap_event: State machine event
2094  * @sap_do_acs_pre_start_bss: true, if ACS scan is issued pre start BSS
2095  *                            false, if ACS scan is issued post start BSS.
2096  * @check_for_connection_update: true, check and wait for connection update
2097  *                               false, do not perform connection update
2098  *
2099  * Initiates sme scan for ACS to pick a channel.
2100  *
2101  * Return: The QDF_STATUS code associated with performing the operation.
2102  */
2103 QDF_STATUS sap_goto_channel_sel(ptSapContext sap_context,
2104 	ptWLAN_SAPEvent sap_event,
2105 	bool sap_do_acs_pre_start_bss,
2106 	bool check_for_connection_update)
2107 {
2108 
2109 	/* Initiate a SCAN request */
2110 	QDF_STATUS qdf_ret_status;
2111 	/* To be initialised if scan is required */
2112 	tCsrScanRequest scan_request;
2113 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
2114 	tpAniSirGlobal mac_ctx;
2115 
2116 #ifdef SOFTAP_CHANNEL_RANGE
2117 	uint8_t *channel_list = NULL;
2118 	uint8_t num_of_channels = 0;
2119 #endif
2120 	tHalHandle h_hal;
2121 	uint8_t con_ch;
2122 
2123 	h_hal = cds_get_context(QDF_MODULE_ID_SME);
2124 	if (NULL == h_hal) {
2125 		/* we have a serious problem */
2126 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
2127 			  FL("invalid h_hal"));
2128 		return QDF_STATUS_E_FAULT;
2129 	}
2130 
2131 	mac_ctx = PMAC_STRUCT(h_hal);
2132 	if (NULL == mac_ctx) {
2133 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2134 				FL("Invalid MAC context"));
2135 		return QDF_STATUS_E_FAILURE;
2136 	}
2137 
2138 	if (cds_concurrent_beaconing_sessions_running()) {
2139 		con_ch =
2140 			sme_get_concurrent_operation_channel(h_hal);
2141 #ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE
2142 		if (con_ch && sap_context->channel == AUTO_CHANNEL_SELECT) {
2143 			sap_context->dfs_ch_disable = true;
2144 		} else if (con_ch && sap_context->channel != con_ch &&
2145 			   CDS_IS_DFS_CH(sap_context->channel)) {
2146 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN,
2147 				  FL("MCC DFS not supported in AP_AP Mode"));
2148 			return QDF_STATUS_E_ABORTED;
2149 		}
2150 #endif
2151 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
2152 		if (sap_context->cc_switch_mode !=
2153 						QDF_MCC_TO_SCC_SWITCH_DISABLE) {
2154 			con_ch = sme_check_concurrent_channel_overlap(h_hal,
2155 					sap_context->channel,
2156 					sap_context->csr_roamProfile.phyMode,
2157 					sap_context->cc_switch_mode);
2158 			if (con_ch) {
2159 				QDF_TRACE(QDF_MODULE_ID_SAP,
2160 					QDF_TRACE_LEVEL_ERROR,
2161 					"%s: Override ch %d to %d due to CC Intf",
2162 					__func__, sap_context->channel, con_ch);
2163 				sap_context->channel = con_ch;
2164 				cds_set_channel_params(sap_context->channel, 0,
2165 						&sap_context->ch_params);
2166 			}
2167 		}
2168 #endif
2169 	}
2170 
2171 	if (cds_get_concurrency_mode() == (QDF_STA_MASK | QDF_SAP_MASK)) {
2172 #ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE
2173 		if (sap_context->channel == AUTO_CHANNEL_SELECT)
2174 			sap_context->dfs_ch_disable = true;
2175 		else if (CDS_IS_DFS_CH(sap_context->channel)) {
2176 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN,
2177 				  FL("DFS not supported in STA_AP Mode"));
2178 			return QDF_STATUS_E_ABORTED;
2179 		}
2180 #endif
2181 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
2182 		if (sap_context->cc_switch_mode !=
2183 						QDF_MCC_TO_SCC_SWITCH_DISABLE) {
2184 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
2185 				FL("check for overlap: chan:%d mode:%d"),
2186 				sap_context->channel,
2187 				sap_context->csr_roamProfile.phyMode);
2188 			con_ch = sme_check_concurrent_channel_overlap(h_hal,
2189 					sap_context->channel,
2190 					sap_context->csr_roamProfile.phyMode,
2191 					sap_context->cc_switch_mode);
2192 			if (con_ch && !CDS_IS_DFS_CH(con_ch)) {
2193 				QDF_TRACE(QDF_MODULE_ID_SAP,
2194 					QDF_TRACE_LEVEL_ERROR,
2195 					"%s: Override ch %d to %d due to CC Intf",
2196 					__func__, sap_context->channel, con_ch);
2197 				sap_context->channel = con_ch;
2198 				cds_set_channel_params(sap_context->channel, 0,
2199 						&sap_context->ch_params);
2200 			}
2201 		}
2202 #endif
2203 	}
2204 
2205 	if (sap_context->channel == AUTO_CHANNEL_SELECT) {
2206 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
2207 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2208 			  FL("%s skip_acs_status = %d "), __func__,
2209 			  sap_context->acs_cfg->skip_scan_status);
2210 		if (sap_context->acs_cfg->skip_scan_status !=
2211 						eSAP_SKIP_ACS_SCAN) {
2212 #endif
2213 		qdf_mem_zero(&scan_request, sizeof(scan_request));
2214 
2215 		/*
2216 		 * Set scanType to Active scan. FW takes care of using passive
2217 		 * scan for DFS and active for non DFS channels.
2218 		 */
2219 		scan_request.scanType = eSIR_ACTIVE_SCAN;
2220 
2221 		/* Set min and max channel time to zero */
2222 		scan_request.minChnTime = 0;
2223 		scan_request.maxChnTime = 0;
2224 
2225 		/* Set BSSType to default type */
2226 		scan_request.BSSType = eCSR_BSS_TYPE_ANY;
2227 
2228 #ifndef SOFTAP_CHANNEL_RANGE
2229 		/*Scan all the channels */
2230 		scan_request.ChannelInfo.num_of_channels = 0;
2231 
2232 		scan_request.ChannelInfo.ChannelList = NULL;
2233 
2234 		scan_request.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
2235 		/* eCSR_SCAN_REQUEST_11D_SCAN; */
2236 
2237 #else
2238 
2239 		sap_get_channel_list(sap_context, &channel_list,
2240 				  &num_of_channels);
2241 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
2242 		if (num_of_channels != 0) {
2243 #endif
2244 		/*Scan the channels in the list */
2245 		scan_request.ChannelInfo.numOfChannels =
2246 			num_of_channels;
2247 
2248 		scan_request.ChannelInfo.ChannelList =
2249 			channel_list;
2250 
2251 		scan_request.requestType =
2252 			eCSR_SCAN_SOFTAP_CHANNEL_RANGE;
2253 
2254 		sap_context->channelList = channel_list;
2255 
2256 #endif
2257 		/* Set requestType to Full scan */
2258 
2259 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2260 			  FL("calling sme_scan_request"));
2261 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
2262 		if (sap_context->acs_cfg->skip_scan_status ==
2263 			eSAP_DO_NEW_ACS_SCAN)
2264 #endif
2265 			sme_scan_flush_result(h_hal);
2266 		if (true == sap_do_acs_pre_start_bss) {
2267 			/*
2268 			 * when ID == 0 11D scan/active scan with callback,
2269 			 * min-maxChntime set in csrScanRequest()?
2270 			 * csrScanCompleteCallback callback
2271 			 * pContext scan_request_id filled up
2272 			 */
2273 			qdf_ret_status = sme_scan_request(h_hal,
2274 				sap_context->sessionId,
2275 				&scan_request,
2276 				&wlansap_pre_start_bss_acs_scan_callback,
2277 				sap_context);
2278 		} else {
2279 			/*
2280 			 * when ID == 0 11D scan/active scan with callback,
2281 			 * min-maxChntime set in csrScanRequest()?
2282 			 * csrScanCompleteCallback callback,
2283 			 * pContext scan_request_id filled up
2284 			 */
2285 			qdf_ret_status = sme_scan_request(h_hal,
2286 				sap_context->sessionId,
2287 				&scan_request,
2288 				&wlansap_scan_callback,
2289 				sap_context);
2290 		}
2291 		if (QDF_STATUS_SUCCESS != qdf_ret_status) {
2292 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2293 				  FL("sme_scan_request  fail %d!!!"),
2294 				  qdf_ret_status);
2295 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2296 				  FL("SAP Configuring default channel, Ch=%d"),
2297 				  sap_context->channel);
2298 			/* In case of error, switch to default channel */
2299 			sap_context->channel = SAP_DEFAULT_24GHZ_CHANNEL;
2300 
2301 #ifdef SOFTAP_CHANNEL_RANGE
2302 			if (sap_context->channelList != NULL) {
2303 				sap_context->channel =
2304 					sap_context->channelList[0];
2305 				qdf_mem_free(sap_context->
2306 					channelList);
2307 				sap_context->channelList = NULL;
2308 			}
2309 #endif
2310 			if (true == sap_do_acs_pre_start_bss) {
2311 				/*
2312 				* In case of ACS req before start Bss,
2313 				* return failure so that the calling
2314 				* fucntion can use the default channel.
2315 				*/
2316 				return QDF_STATUS_E_FAILURE;
2317 			} else {
2318 				/* Fill in the event structure */
2319 				sap_event_init(sap_event);
2320 				/* Handle event */
2321 				qdf_status = sap_fsm(sap_context, sap_event);
2322 			}
2323 		} else {
2324 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2325 				 FL("return sme_ScanReq, scanID=%d, Ch=%d"),
2326 				 scan_request.scan_id, sap_context->channel);
2327 		}
2328 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
2329 		}
2330 	} else {
2331 		sap_context->acs_cfg->skip_scan_status = eSAP_SKIP_ACS_SCAN;
2332 	}
2333 
2334 	if (sap_context->acs_cfg->skip_scan_status == eSAP_SKIP_ACS_SCAN) {
2335 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2336 			  FL("## %s SKIPPED ACS SCAN"), __func__);
2337 		wlansap_scan_callback(h_hal, sap_context,
2338 			sap_context->sessionId, 0, eCSR_SCAN_SUCCESS);
2339 	}
2340 #endif
2341 	} else {
2342 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2343 			  FL("for configured channel, Ch= %d"),
2344 			  sap_context->channel);
2345 
2346 		if (check_for_connection_update) {
2347 			/* This wait happens in the hostapd context. The event
2348 			 * is set in the MC thread context.
2349 			 */
2350 			qdf_status = cds_update_and_wait_for_connection_update(
2351 					sap_context->sessionId,
2352 					sap_context->channel,
2353 					SIR_UPDATE_REASON_START_AP);
2354 			if (QDF_IS_STATUS_ERROR(qdf_status))
2355 				return qdf_status;
2356 		}
2357 
2358 		if (sap_do_acs_pre_start_bss == true) {
2359 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
2360 				FL("ACS end due to Ch override. Sel Ch = %d"),
2361 							sap_context->channel);
2362 			sap_context->acs_cfg->pri_ch = sap_context->channel;
2363 			sap_context->acs_cfg->ch_width =
2364 						 sap_context->ch_width_orig;
2365 			sap_config_acs_result(h_hal, sap_context, 0);
2366 			return QDF_STATUS_E_CANCELED;
2367 		} else {
2368 			/*
2369 			 * Fill in the event structure
2370 			 * Eventhough scan was not done,
2371 			 * means a user set channel was chosen
2372 			 */
2373 			sap_event_init(sap_event);
2374 			/* Handle event */
2375 			qdf_status = sap_fsm(sap_context, sap_event);
2376 		}
2377 	}
2378 
2379 	/*
2380 	 * If scan failed, get default channel and advance state
2381 	 * machine as success with default channel
2382 	 *
2383 	 * Have to wait for the call back to be called to get the
2384 	 * channel cannot advance state machine here as said above
2385 	 */
2386 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2387 		  FL("before exiting sap_goto_channel_sel channel=%d"),
2388 		  sap_context->channel);
2389 
2390 	return QDF_STATUS_SUCCESS;
2391 }
2392 
2393 /**
2394  * sap_open_session() - Opens a SAP session
2395  * @hHal: Hal handle
2396  * @sapContext:  Sap Context value
2397  * @session_id: Pointer to the session id
2398  *
2399  * Function for opening SME and SAP sessions when system is in SoftAP role
2400  *
2401  * Return: QDF_STATUS
2402  */
2403 
2404 #define SAP_OPEN_SESSION_TIMEOUT 2000
2405 QDF_STATUS sap_open_session(tHalHandle hHal, ptSapContext sapContext,
2406 			    uint32_t *session_id)
2407 {
2408 	uint32_t type, subType;
2409 	QDF_STATUS qdf_ret_status;
2410 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
2411 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
2412 
2413 	if (sapContext->csr_roamProfile.csrPersona == QDF_P2P_GO_MODE)
2414 		status = cds_get_vdev_types(QDF_P2P_GO_MODE, &type, &subType);
2415 	else
2416 		status = cds_get_vdev_types(QDF_SAP_MODE, &type, &subType);
2417 
2418 	if (QDF_STATUS_SUCCESS != status) {
2419 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
2420 			  "failed to get vdev type");
2421 		return QDF_STATUS_E_FAILURE;
2422 	}
2423 
2424 	qdf_event_reset(&sapContext->sap_session_opened_evt);
2425 	/* Open SME Session for Softap */
2426 	qdf_ret_status = sme_open_session(hHal,
2427 					  &wlansap_roam_callback,
2428 					  sapContext,
2429 					  sapContext->self_mac_addr,
2430 					  &sapContext->sessionId, type, subType);
2431 
2432 	if (QDF_STATUS_SUCCESS != qdf_ret_status) {
2433 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2434 			  "Error: In %s calling sme_roam_connect status = %d",
2435 			  __func__, qdf_ret_status);
2436 
2437 		return QDF_STATUS_E_FAILURE;
2438 	}
2439 
2440 	status = qdf_wait_single_event(&sapContext->sap_session_opened_evt,
2441 				       SAP_OPEN_SESSION_TIMEOUT);
2442 
2443 	if (!QDF_IS_STATUS_SUCCESS(status)) {
2444 		cds_err("wait for sap open session event timed out");
2445 		return QDF_STATUS_E_FAILURE;
2446 	}
2447 
2448 	pMac->sap.sapCtxList[sapContext->sessionId].sessionID =
2449 		sapContext->sessionId;
2450 	pMac->sap.sapCtxList[sapContext->sessionId].pSapContext = sapContext;
2451 	pMac->sap.sapCtxList[sapContext->sessionId].sapPersona =
2452 		sapContext->csr_roamProfile.csrPersona;
2453 	*session_id = sapContext->sessionId;
2454 	sapContext->isSapSessionOpen = eSAP_TRUE;
2455 	sapContext->is_pre_cac_on = false;
2456 	sapContext->pre_cac_complete = false;
2457 	sapContext->chan_before_pre_cac = 0;
2458 	return QDF_STATUS_SUCCESS;
2459 }
2460 
2461 /*==========================================================================
2462    FUNCTION    sapGotoStarting
2463 
2464    DESCRIPTION
2465     Function for initiating start bss request for SME
2466 
2467    DEPENDENCIES
2468     NA.
2469 
2470    PARAMETERS
2471 
2472     IN
2473     sapContext  : Sap Context value
2474     sapEvent    : State machine event
2475     bssType     : Type of bss to start, INRA AP
2476     status      : Return the SAP status here
2477 
2478    RETURN VALUE
2479     The QDF_STATUS code associated with performing the operation
2480 
2481     QDF_STATUS_SUCCESS: Success
2482 
2483    SIDE EFFECTS
2484    ============================================================================*/
2485 QDF_STATUS sap_goto_starting(ptSapContext sapContext, ptWLAN_SAPEvent sapEvent,
2486 			     eCsrRoamBssType bssType)
2487 {
2488 	/* tHalHandle */
2489 	tHalHandle hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx);
2490 	QDF_STATUS qdf_ret_status;
2491 
2492 	/*- - - - - - - - TODO:once configs from hdd available - - - - - - - - -*/
2493 	char key_material[32] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3,
2494 		4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, };
2495 	sapContext->key_type = 0x05;
2496 	sapContext->key_length = 32;
2497 	/* Need a key size define */
2498 	qdf_mem_copy(sapContext->key_material, key_material,
2499 		     sizeof(key_material));
2500 
2501 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, "In %s",
2502 		  __func__);
2503 
2504 	if (NULL == hHal) {
2505 		/* we have a serious problem */
2506 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
2507 			  "In %s, invalid hHal", __func__);
2508 		return QDF_STATUS_E_FAULT;
2509 	}
2510 
2511 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, "%s: session: %d",
2512 		  __func__, sapContext->sessionId);
2513 
2514 	qdf_ret_status = sme_roam_connect(hHal, sapContext->sessionId,
2515 					  &sapContext->csr_roamProfile,
2516 					  &sapContext->csr_roamId);
2517 	if (QDF_STATUS_SUCCESS != qdf_ret_status)
2518 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2519 			"%s: Failed to issue sme_roam_connect", __func__);
2520 
2521 	return qdf_ret_status;
2522 } /* sapGotoStarting */
2523 
2524 /*==========================================================================
2525    FUNCTION    sapGotoDisconnecting
2526 
2527    DESCRIPTION
2528     Processing of SAP FSM Disconnecting state
2529 
2530    DEPENDENCIES
2531     NA.
2532 
2533    PARAMETERS
2534 
2535     IN
2536     sapContext  : Sap Context value
2537     status      : Return the SAP status here
2538 
2539    RETURN VALUE
2540     The QDF_STATUS code associated with performing the operation
2541 
2542     QDF_STATUS_SUCCESS: Success
2543 
2544    SIDE EFFECTS
2545    ============================================================================*/
2546 QDF_STATUS sap_goto_disconnecting(ptSapContext sapContext)
2547 {
2548 	QDF_STATUS qdf_ret_status;
2549 	tHalHandle hHal;
2550 
2551 	hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx);
2552 	if (NULL == hHal) {
2553 		/* we have a serious problem */
2554 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2555 			  "In %s, invalid hHal", __func__);
2556 		return QDF_STATUS_E_FAULT;
2557 	}
2558 
2559 	sap_free_roam_profile(&sapContext->csr_roamProfile);
2560 	qdf_ret_status = sme_roam_stop_bss(hHal, sapContext->sessionId);
2561 	if (QDF_STATUS_SUCCESS != qdf_ret_status) {
2562 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2563 			  "Error: In %s calling sme_roam_stop_bss status = %d",
2564 			  __func__, qdf_ret_status);
2565 		return QDF_STATUS_E_FAILURE;
2566 	}
2567 
2568 	return QDF_STATUS_SUCCESS;
2569 }
2570 
2571 static QDF_STATUS sap_roam_session_close_callback(void *pContext)
2572 {
2573 	ptSapContext sapContext = (ptSapContext) pContext;
2574 	return sap_signal_hdd_event(sapContext, NULL,
2575 				 eSAP_STOP_BSS_EVENT,
2576 				 (void *) eSAP_STATUS_SUCCESS);
2577 }
2578 
2579 /*==========================================================================
2580    FUNCTION    sapGotoDisconnected
2581 
2582    DESCRIPTION
2583     Function for setting the SAP FSM to Disconnection state
2584 
2585    DEPENDENCIES
2586     NA.
2587 
2588    PARAMETERS
2589 
2590     IN
2591     sapContext  : Sap Context value
2592     sapEvent    : State machine event
2593     status      : Return the SAP status here
2594 
2595    RETURN VALUE
2596     The QDF_STATUS code associated with performing the operation
2597 
2598     QDF_STATUS_SUCCESS: Success
2599 
2600    SIDE EFFECTS
2601    ============================================================================*/
2602 QDF_STATUS sap_goto_disconnected(ptSapContext sapContext)
2603 {
2604 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
2605 	tWLAN_SAPEvent sapEvent;
2606 	/* Processing has to be coded */
2607 	/* Clean up stations from TL etc as AP BSS is shut down then set event */
2608 	sapEvent.event = eSAP_MAC_READY_FOR_CONNECTIONS;        /* hardcoded */
2609 	sapEvent.params = 0;
2610 	sapEvent.u1 = 0;
2611 	sapEvent.u2 = 0;
2612 	/* Handle event */
2613 	qdf_status = sap_fsm(sapContext, &sapEvent);
2614 
2615 	return qdf_status;
2616 }
2617 
2618 /**
2619  * sap_signal_hdd_event() - send event notification
2620  * @sap_ctx: Sap Context
2621  * @csr_roaminfo: Pointer to CSR roam information
2622  * @sap_hddevent: SAP HDD event
2623  * @context: to pass the element for future support
2624  *
2625  * Function for HDD to send the event notification using callback
2626  *
2627  * Return: QDF_STATUS
2628  */
2629 QDF_STATUS sap_signal_hdd_event(ptSapContext sap_ctx,
2630 		tCsrRoamInfo *csr_roaminfo, eSapHddEvent sap_hddevent,
2631 		void *context)
2632 {
2633 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
2634 	tSap_Event sap_ap_event;       /* This now encodes ALL event types */
2635 	tHalHandle hal = CDS_GET_HAL_CB(sap_ctx->p_cds_gctx);
2636 	tpAniSirGlobal mac_ctx;
2637 	tSirSmeChanInfo *chaninfo;
2638 	tSap_StationAssocIndication *assoc_ind;
2639 	tSap_StartBssCompleteEvent *bss_complete;
2640 	struct sap_ch_selected_s *acs_selected;
2641 	tSap_StationAssocReassocCompleteEvent *reassoc_complete;
2642 	tSap_StationDisassocCompleteEvent *disassoc_comp;
2643 	tSap_StationSetKeyCompleteEvent *key_complete;
2644 	tSap_StationMICFailureEvent *mic_failure;
2645 
2646 	/* Format the Start BSS Complete event to return... */
2647 	if (NULL == sap_ctx->pfnSapEventCallback) {
2648 		QDF_ASSERT(0);
2649 		return QDF_STATUS_E_FAILURE;
2650 	}
2651 	if (NULL == hal) {
2652 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2653 			  FL("Invalid hal"));
2654 		return QDF_STATUS_E_FAILURE;
2655 	}
2656 	mac_ctx = PMAC_STRUCT(hal);
2657 	if (NULL == mac_ctx) {
2658 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2659 			  FL("Invalid MAC context"));
2660 		return QDF_STATUS_E_FAILURE;
2661 	}
2662 
2663 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2664 		  FL("SAP event callback event = %s"),
2665 		  sap_hdd_event_to_string(sap_hddevent));
2666 
2667 	switch (sap_hddevent) {
2668 	case eSAP_STA_ASSOC_IND:
2669 		/*  TODO - Indicate the assoc request indication to OS */
2670 		sap_ap_event.sapHddEventCode = eSAP_STA_ASSOC_IND;
2671 		assoc_ind = &sap_ap_event.sapevt.sapAssocIndication;
2672 
2673 		qdf_copy_macaddr(&assoc_ind->staMac, &csr_roaminfo->peerMac);
2674 		assoc_ind->staId = csr_roaminfo->staId;
2675 		assoc_ind->status = 0;
2676 		/* Required for indicating the frames to upper layer */
2677 		assoc_ind->beaconLength = csr_roaminfo->beaconLength;
2678 		assoc_ind->beaconPtr = csr_roaminfo->beaconPtr;
2679 		assoc_ind->assocReqLength = csr_roaminfo->assocReqLength;
2680 		assoc_ind->assocReqPtr = csr_roaminfo->assocReqPtr;
2681 		assoc_ind->fWmmEnabled = csr_roaminfo->wmmEnabledSta;
2682 		if (csr_roaminfo->u.pConnectedProfile != NULL) {
2683 			assoc_ind->negotiatedAuthType =
2684 				csr_roaminfo->u.pConnectedProfile->AuthType;
2685 			assoc_ind->negotiatedUCEncryptionType =
2686 			    csr_roaminfo->u.pConnectedProfile->EncryptionType;
2687 			assoc_ind->negotiatedMCEncryptionType =
2688 			    csr_roaminfo->u.pConnectedProfile->mcEncryptionType;
2689 			assoc_ind->fAuthRequired = csr_roaminfo->fAuthRequired;
2690 		}
2691 		break;
2692 	case eSAP_START_BSS_EVENT:
2693 		sap_ap_event.sapHddEventCode = eSAP_START_BSS_EVENT;
2694 		bss_complete = &sap_ap_event.sapevt.sapStartBssCompleteEvent;
2695 
2696 		bss_complete->status = (eSapStatus) context;
2697 		if (csr_roaminfo != NULL)
2698 			bss_complete->staId = csr_roaminfo->staId;
2699 		else
2700 			bss_complete->staId = 0;
2701 
2702 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2703 			  FL("(eSAP_START_BSS_EVENT): staId = %d"),
2704 			  bss_complete->staId);
2705 
2706 		bss_complete->operatingChannel = (uint8_t) sap_ctx->channel;
2707 		bss_complete->sessionId = sap_ctx->sessionId;
2708 		break;
2709 	case eSAP_DFS_CAC_START:
2710 	case eSAP_DFS_CAC_INTERRUPTED:
2711 	case eSAP_DFS_CAC_END:
2712 	case eSAP_DFS_PRE_CAC_END:
2713 	case eSAP_DFS_RADAR_DETECT:
2714 	case eSAP_DFS_RADAR_DETECT_DURING_PRE_CAC:
2715 	case eSAP_DFS_NO_AVAILABLE_CHANNEL:
2716 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
2717 	case eSAP_ACS_SCAN_SUCCESS_EVENT:
2718 #endif
2719 		sap_ap_event.sapHddEventCode = sap_hddevent;
2720 		sap_ap_event.sapevt.sapStopBssCompleteEvent.status =
2721 			(eSapStatus) context;
2722 		break;
2723 
2724 	case eSAP_ACS_CHANNEL_SELECTED:
2725 		sap_ap_event.sapHddEventCode = sap_hddevent;
2726 		acs_selected = &sap_ap_event.sapevt.sap_ch_selected;
2727 		if (eSAP_STATUS_SUCCESS == (eSapStatus)context) {
2728 			acs_selected->pri_ch = sap_ctx->acs_cfg->pri_ch;
2729 			acs_selected->ht_sec_ch = sap_ctx->acs_cfg->ht_sec_ch;
2730 			acs_selected->ch_width = sap_ctx->acs_cfg->ch_width;
2731 			acs_selected->vht_seg0_center_ch =
2732 				sap_ctx->acs_cfg->vht_seg0_center_ch;
2733 			acs_selected->vht_seg1_center_ch =
2734 				sap_ctx->acs_cfg->vht_seg1_center_ch;
2735 		} else if (eSAP_STATUS_FAILURE == (eSapStatus)context) {
2736 			acs_selected->pri_ch = 0;
2737 		}
2738 		break;
2739 
2740 	case eSAP_STOP_BSS_EVENT:
2741 		sap_ap_event.sapHddEventCode = eSAP_STOP_BSS_EVENT;
2742 		sap_ap_event.sapevt.sapStopBssCompleteEvent.status =
2743 			(eSapStatus) context;
2744 		break;
2745 
2746 	case eSAP_STA_ASSOC_EVENT:
2747 	case eSAP_STA_REASSOC_EVENT:
2748 		reassoc_complete =
2749 		    &sap_ap_event.sapevt.sapStationAssocReassocCompleteEvent;
2750 
2751 		if (csr_roaminfo->fReassocReq)
2752 			sap_ap_event.sapHddEventCode = eSAP_STA_REASSOC_EVENT;
2753 		else
2754 			sap_ap_event.sapHddEventCode = eSAP_STA_ASSOC_EVENT;
2755 
2756 		qdf_copy_macaddr(&reassoc_complete->staMac,
2757 				 &csr_roaminfo->peerMac);
2758 		reassoc_complete->staId = csr_roaminfo->staId;
2759 		reassoc_complete->statusCode = csr_roaminfo->statusCode;
2760 		reassoc_complete->iesLen = csr_roaminfo->rsnIELen;
2761 		qdf_mem_copy(reassoc_complete->ies, csr_roaminfo->prsnIE,
2762 			     csr_roaminfo->rsnIELen);
2763 
2764 #ifdef FEATURE_WLAN_WAPI
2765 		if (csr_roaminfo->wapiIELen) {
2766 			uint8_t len = reassoc_complete->iesLen;
2767 			reassoc_complete->iesLen += csr_roaminfo->wapiIELen;
2768 			qdf_mem_copy(&reassoc_complete->ies[len],
2769 				     csr_roaminfo->pwapiIE,
2770 				     csr_roaminfo->wapiIELen);
2771 		}
2772 #endif
2773 		if (csr_roaminfo->addIELen) {
2774 			uint8_t len = reassoc_complete->iesLen;
2775 			reassoc_complete->iesLen += csr_roaminfo->addIELen;
2776 			qdf_mem_copy(&reassoc_complete->ies[len],
2777 				     csr_roaminfo->paddIE,
2778 				     csr_roaminfo->addIELen);
2779 		}
2780 
2781 		/* also fill up the channel info from the csr_roamInfo */
2782 		chaninfo = &reassoc_complete->chan_info;
2783 
2784 		chaninfo->chan_id = csr_roaminfo->chan_info.chan_id;
2785 		chaninfo->mhz = csr_roaminfo->chan_info.mhz;
2786 		chaninfo->info = csr_roaminfo->chan_info.info;
2787 		chaninfo->band_center_freq1 =
2788 			csr_roaminfo->chan_info.band_center_freq1;
2789 		chaninfo->band_center_freq2 =
2790 			csr_roaminfo->chan_info.band_center_freq2;
2791 		chaninfo->reg_info_1 =
2792 			csr_roaminfo->chan_info.reg_info_1;
2793 		chaninfo->reg_info_2 =
2794 			csr_roaminfo->chan_info.reg_info_2;
2795 		chaninfo->nss = csr_roaminfo->chan_info.nss;
2796 		chaninfo->rate_flags = csr_roaminfo->chan_info.rate_flags;
2797 
2798 		reassoc_complete->wmmEnabled = csr_roaminfo->wmmEnabledSta;
2799 		reassoc_complete->status = (eSapStatus) context;
2800 		reassoc_complete->timingMeasCap = csr_roaminfo->timingMeasCap;
2801 		break;
2802 
2803 	case eSAP_STA_DISASSOC_EVENT:
2804 		sap_ap_event.sapHddEventCode = eSAP_STA_DISASSOC_EVENT;
2805 		disassoc_comp =
2806 			&sap_ap_event.sapevt.sapStationDisassocCompleteEvent;
2807 
2808 		qdf_copy_macaddr(&disassoc_comp->staMac,
2809 				 &csr_roaminfo->peerMac);
2810 		disassoc_comp->staId = csr_roaminfo->staId;
2811 		if (csr_roaminfo->reasonCode == eCSR_ROAM_RESULT_FORCED)
2812 			disassoc_comp->reason = eSAP_USR_INITATED_DISASSOC;
2813 		else
2814 			disassoc_comp->reason = eSAP_MAC_INITATED_DISASSOC;
2815 
2816 		disassoc_comp->statusCode = csr_roaminfo->statusCode;
2817 		disassoc_comp->status = (eSapStatus) context;
2818 		break;
2819 
2820 	case eSAP_STA_SET_KEY_EVENT:
2821 		sap_ap_event.sapHddEventCode = eSAP_STA_SET_KEY_EVENT;
2822 		key_complete =
2823 			&sap_ap_event.sapevt.sapStationSetKeyCompleteEvent;
2824 		key_complete->status = (eSapStatus) context;
2825 		qdf_copy_macaddr(&key_complete->peerMacAddr,
2826 				 &csr_roaminfo->peerMac);
2827 		break;
2828 
2829 	case eSAP_STA_MIC_FAILURE_EVENT:
2830 		sap_ap_event.sapHddEventCode = eSAP_STA_MIC_FAILURE_EVENT;
2831 		mic_failure = &sap_ap_event.sapevt.sapStationMICFailureEvent;
2832 
2833 		qdf_mem_copy(&mic_failure->srcMacAddr,
2834 			     csr_roaminfo->u.pMICFailureInfo->srcMacAddr,
2835 			     sizeof(tSirMacAddr));
2836 		qdf_mem_copy(&mic_failure->staMac.bytes,
2837 			     csr_roaminfo->u.pMICFailureInfo->taMacAddr,
2838 			     sizeof(tSirMacAddr));
2839 		qdf_mem_copy(&mic_failure->dstMacAddr.bytes,
2840 			     csr_roaminfo->u.pMICFailureInfo->dstMacAddr,
2841 			     sizeof(tSirMacAddr));
2842 		mic_failure->multicast =
2843 			csr_roaminfo->u.pMICFailureInfo->multicast;
2844 		mic_failure->IV1 = csr_roaminfo->u.pMICFailureInfo->IV1;
2845 		mic_failure->keyId = csr_roaminfo->u.pMICFailureInfo->keyId;
2846 		qdf_mem_copy(mic_failure->TSC,
2847 			     csr_roaminfo->u.pMICFailureInfo->TSC,
2848 			     SIR_CIPHER_SEQ_CTR_SIZE);
2849 		break;
2850 
2851 	case eSAP_ASSOC_STA_CALLBACK_EVENT:
2852 		break;
2853 
2854 	case eSAP_WPS_PBC_PROBE_REQ_EVENT:
2855 		sap_ap_event.sapHddEventCode = eSAP_WPS_PBC_PROBE_REQ_EVENT;
2856 
2857 		qdf_mem_copy(&sap_ap_event.sapevt.sapPBCProbeReqEvent.
2858 			     WPSPBCProbeReq, csr_roaminfo->u.pWPSPBCProbeReq,
2859 			     sizeof(tSirWPSPBCProbeReq));
2860 		break;
2861 
2862 	case eSAP_REMAIN_CHAN_READY:
2863 		sap_ap_event.sapHddEventCode = eSAP_REMAIN_CHAN_READY;
2864 		sap_ap_event.sapevt.sap_roc_ind.scan_id =
2865 				sap_ctx->roc_ind_scan_id;
2866 		break;
2867 	case eSAP_SEND_ACTION_CNF:
2868 		sap_ap_event.sapHddEventCode = eSAP_SEND_ACTION_CNF;
2869 		sap_ap_event.sapevt.sapActionCnf.actionSendSuccess =
2870 			(eSapStatus) context;
2871 		break;
2872 
2873 	case eSAP_DISCONNECT_ALL_P2P_CLIENT:
2874 		sap_ap_event.sapHddEventCode = eSAP_DISCONNECT_ALL_P2P_CLIENT;
2875 		sap_ap_event.sapevt.sapActionCnf.actionSendSuccess =
2876 			(eSapStatus) context;
2877 		break;
2878 
2879 	case eSAP_MAC_TRIG_STOP_BSS_EVENT:
2880 		sap_ap_event.sapHddEventCode = eSAP_MAC_TRIG_STOP_BSS_EVENT;
2881 		sap_ap_event.sapevt.sapActionCnf.actionSendSuccess =
2882 			(eSapStatus) context;
2883 		break;
2884 
2885 	case eSAP_UNKNOWN_STA_JOIN:
2886 		sap_ap_event.sapHddEventCode = eSAP_UNKNOWN_STA_JOIN;
2887 		qdf_mem_copy((void *) sap_ap_event.sapevt.sapUnknownSTAJoin.
2888 			     macaddr.bytes, (void *) context,
2889 			     QDF_MAC_ADDR_SIZE);
2890 		break;
2891 
2892 	case eSAP_MAX_ASSOC_EXCEEDED:
2893 		sap_ap_event.sapHddEventCode = eSAP_MAX_ASSOC_EXCEEDED;
2894 		qdf_copy_macaddr(&sap_ap_event.sapevt.
2895 				 sapMaxAssocExceeded.macaddr,
2896 				 &csr_roaminfo->peerMac);
2897 		break;
2898 
2899 	case eSAP_CHANNEL_CHANGE_EVENT:
2900 		/*
2901 		 * Reconfig ACS result info. For DFS AP-AP Mode Sec AP ACS
2902 		 * follows pri AP
2903 		 */
2904 		sap_ctx->acs_cfg->pri_ch = sap_ctx->channel;
2905 		sap_ctx->acs_cfg->ch_width =
2906 				sap_ctx->csr_roamProfile.ch_params.ch_width;
2907 		sap_config_acs_result(hal, sap_ctx,
2908 			sap_ctx->csr_roamProfile.ch_params.sec_ch_offset);
2909 
2910 		sap_ap_event.sapHddEventCode = eSAP_CHANNEL_CHANGE_EVENT;
2911 
2912 		acs_selected = &sap_ap_event.sapevt.sap_ch_selected;
2913 		acs_selected->pri_ch = sap_ctx->acs_cfg->pri_ch;
2914 		acs_selected->ht_sec_ch =
2915 			sap_ctx->csr_roamProfile.ch_params.sec_ch_offset;
2916 		acs_selected->ch_width =
2917 			sap_ctx->csr_roamProfile.ch_params.ch_width;
2918 		acs_selected->vht_seg0_center_ch =
2919 			sap_ctx->csr_roamProfile.ch_params.center_freq_seg0;
2920 		acs_selected->vht_seg1_center_ch =
2921 			sap_ctx->csr_roamProfile.ch_params.center_freq_seg1;
2922 		break;
2923 
2924 	case eSAP_DFS_NOL_GET:
2925 		sap_ap_event.sapHddEventCode = eSAP_DFS_NOL_GET;
2926 		sap_ap_event.sapevt.sapDfsNolInfo.sDfsList =
2927 			NUM_5GHZ_CHANNELS * sizeof(tSapDfsNolInfo);
2928 		sap_ap_event.sapevt.sapDfsNolInfo.pDfsList = (void *)
2929 			(&mac_ctx->sap.SapDfsInfo.sapDfsChannelNolList[0]);
2930 		break;
2931 
2932 	case eSAP_DFS_NOL_SET:
2933 		sap_ap_event.sapHddEventCode = eSAP_DFS_NOL_SET;
2934 		sap_ap_event.sapevt.sapDfsNolInfo.sDfsList =
2935 			mac_ctx->sap.SapDfsInfo.numCurrentRegDomainDfsChannels *
2936 			sizeof(tSapDfsNolInfo);
2937 		sap_ap_event.sapevt.sapDfsNolInfo.pDfsList = (void *)
2938 			(&mac_ctx->sap.SapDfsInfo.sapDfsChannelNolList[0]);
2939 		break;
2940 	case eSAP_ECSA_CHANGE_CHAN_IND:
2941 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2942 				"In %s, SAP event callback event = %s",
2943 				__func__, "eSAP_ECSA_CHANGE_CHAN_IND");
2944 		sap_ap_event.sapHddEventCode = eSAP_ECSA_CHANGE_CHAN_IND;
2945 		sap_ap_event.sapevt.sap_chan_cng_ind.new_chan =
2946 					   csr_roaminfo->target_channel;
2947 		break;
2948 	default:
2949 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2950 			  FL("SAP Unknown callback event = %d"),
2951 			  sap_hddevent);
2952 		break;
2953 	}
2954 	qdf_status = (*sap_ctx->pfnSapEventCallback)
2955 			(&sap_ap_event, sap_ctx->pUsrContext);
2956 
2957 	return qdf_status;
2958 
2959 }
2960 
2961 /*==========================================================================
2962    FUNCTION  sap_find_valid_concurrent_session
2963 
2964    DESCRIPTION
2965     This function will return sapcontext of any valid sap session.
2966 
2967    PARAMETERS
2968 
2969     IN
2970     hHal        : HAL pointer
2971 
2972    RETURN VALUE
2973     ptSapContext : valid sap context
2974 
2975    SIDE EFFECTS
2976     NA
2977    ============================================================================*/
2978 ptSapContext sap_find_valid_concurrent_session(tHalHandle hHal)
2979 {
2980 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
2981 	uint8_t intf = 0;
2982 
2983 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
2984 		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
2985 		    ||
2986 		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona)) &&
2987 		    pMac->sap.sapCtxList[intf].pSapContext != NULL) {
2988 			return pMac->sap.sapCtxList[intf].pSapContext;
2989 		}
2990 	}
2991 
2992 	return NULL;
2993 }
2994 
2995 /**
2996  * sap_find_cac_wait_session() - Get context of a SAP session in CAC wait state
2997  * @handle: Global MAC handle
2998  *
2999  * Finds and gets the context of a SAP session in CAC wait state.
3000  *
3001  * Return: Valid SAP context on success, else NULL
3002  */
3003 ptSapContext sap_find_cac_wait_session(tHalHandle handle)
3004 {
3005 	tpAniSirGlobal mac = PMAC_STRUCT(handle);
3006 	uint8_t i = 0;
3007 	ptSapContext sapContext;
3008 
3009 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
3010 			"%s", __func__);
3011 
3012 	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
3013 		sapContext = (ptSapContext) mac->sap.sapCtxList[i].pSapContext;
3014 		if (((QDF_SAP_MODE == mac->sap.sapCtxList[i].sapPersona)
3015 		    ||
3016 		    (QDF_P2P_GO_MODE == mac->sap.sapCtxList[i].sapPersona)) &&
3017 		    (sapContext) &&
3018 		    (sapContext->sapsMachine == eSAP_DFS_CAC_WAIT)) {
3019 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
3020 				"%s: found SAP in cac wait state", __func__);
3021 			return sapContext;
3022 		}
3023 		if (sapContext) {
3024 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
3025 					"sapdfs: mode:%d intf:%d state:%d",
3026 					mac->sap.sapCtxList[i].sapPersona, i,
3027 					sapContext->sapsMachine);
3028 		}
3029 	}
3030 
3031 	return NULL;
3032 }
3033 
3034 /*==========================================================================
3035    FUNCTION   sap_close_session
3036 
3037    DESCRIPTION
3038     This function will close all the sme sessions as well as zero-out the
3039     sap global structure
3040 
3041    PARAMETERS
3042 
3043     IN
3044     hHal        : HAL pointer
3045     sapContext  : Sap Context value
3046     callback    : Roam Session close callback
3047     valid       : Sap context is valid or no
3048 
3049    RETURN VALUE
3050     The QDF_STATUS code associated with performing the operation
3051     QDF_STATUS_SUCCESS: Success
3052 
3053    SIDE EFFECTS
3054     NA
3055    ============================================================================*/
3056 QDF_STATUS sap_close_session(tHalHandle hHal,
3057 			     ptSapContext sapContext,
3058 			     csr_roamSessionCloseCallback callback, bool valid)
3059 {
3060 	QDF_STATUS qdf_status;
3061 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3062 
3063 	if (false == valid) {
3064 		qdf_status = sme_close_session(hHal,
3065 					       sapContext->sessionId,
3066 					       callback, NULL);
3067 	} else {
3068 		qdf_status = sme_close_session(hHal,
3069 					       sapContext->sessionId,
3070 					       callback, sapContext);
3071 	}
3072 
3073 	sapContext->isCacStartNotified = false;
3074 	sapContext->isCacEndNotified = false;
3075 	pMac->sap.sapCtxList[sapContext->sessionId].pSapContext = NULL;
3076 	sapContext->isSapSessionOpen = false;
3077 	sapContext->pre_cac_complete = false;
3078 	sapContext->is_pre_cac_on = false;
3079 	sapContext->chan_before_pre_cac = 0;
3080 
3081 	if (NULL == sap_find_valid_concurrent_session(hHal)) {
3082 		/* If timer is running then stop the timer and destory it */
3083 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
3084 			  "sapdfs: no session are valid, so clearing dfs global structure");
3085 		/*
3086 		 * CAC timer will be initiated and started only when SAP starts
3087 		 * on DFS channel and it will be stopped and destroyed
3088 		 * immediately once the radar detected or timedout. So
3089 		 * as per design CAC timer should be destroyed after stop
3090 		 */
3091 		if (pMac->sap.SapDfsInfo.is_dfs_cac_timer_running) {
3092 			qdf_mc_timer_stop(&pMac->sap.SapDfsInfo.
3093 					  sap_dfs_cac_timer);
3094 			pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
3095 			qdf_mc_timer_destroy(
3096 				&pMac->sap.SapDfsInfo.sap_dfs_cac_timer);
3097 		}
3098 		pMac->sap.SapDfsInfo.cac_state = eSAP_DFS_DO_NOT_SKIP_CAC;
3099 		sap_cac_reset_notify(hHal);
3100 		qdf_mem_zero(&pMac->sap, sizeof(pMac->sap));
3101 	}
3102 
3103 	return qdf_status;
3104 }
3105 
3106 /*==========================================================================
3107    FUNCTION  sap_cac_reset_notify
3108 
3109    DESCRIPTION Function will be called up on stop bss indication to clean up
3110    DFS global structure.
3111 
3112    DEPENDENCIES PARAMETERS
3113      IN hHAL : HAL pointer
3114 
3115    RETURN VALUE  : void.
3116 
3117    SIDE EFFECTS
3118    ============================================================================*/
3119 void sap_cac_reset_notify(tHalHandle hHal)
3120 {
3121 	uint8_t intf = 0;
3122 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3123 
3124 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
3125 		ptSapContext pSapContext =
3126 			(ptSapContext) pMac->sap.sapCtxList[intf].pSapContext;
3127 		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
3128 		    ||
3129 		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona))
3130 		    && pMac->sap.sapCtxList[intf].pSapContext != NULL) {
3131 			pSapContext->isCacStartNotified = false;
3132 			pSapContext->isCacEndNotified = false;
3133 		}
3134 	}
3135 }
3136 
3137 /*==========================================================================
3138    FUNCTION  sap_cac_start_notify
3139 
3140    DESCRIPTION Function will be called to notify eSAP_DFS_CAC_START event
3141    to HDD
3142 
3143    DEPENDENCIES PARAMETERS
3144      IN hHAL : HAL pointer
3145 
3146    RETURN VALUE  : QDF_STATUS.
3147 
3148    SIDE EFFECTS
3149    ============================================================================*/
3150 QDF_STATUS sap_cac_start_notify(tHalHandle hHal)
3151 {
3152 	uint8_t intf = 0;
3153 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3154 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3155 
3156 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
3157 		ptSapContext pSapContext =
3158 			(ptSapContext) pMac->sap.sapCtxList[intf].pSapContext;
3159 		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
3160 		    ||
3161 		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona))
3162 		    && pMac->sap.sapCtxList[intf].pSapContext != NULL &&
3163 		    (false == pSapContext->isCacStartNotified)) {
3164 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
3165 				  "sapdfs: Signaling eSAP_DFS_CAC_START to HDD for sapctx[%p]",
3166 				  pSapContext);
3167 
3168 			qdf_status = sap_signal_hdd_event(pSapContext, NULL,
3169 							  eSAP_DFS_CAC_START,
3170 							  (void *)
3171 							  eSAP_STATUS_SUCCESS);
3172 			if (QDF_STATUS_SUCCESS != qdf_status) {
3173 				QDF_TRACE(QDF_MODULE_ID_SAP,
3174 					  QDF_TRACE_LEVEL_ERROR,
3175 					  "In %s, failed setting isCacStartNotified on interface[%d]",
3176 					  __func__, intf);
3177 				return qdf_status;
3178 			}
3179 			pSapContext->isCacStartNotified = true;
3180 		}
3181 	}
3182 	return qdf_status;
3183 }
3184 
3185 /**
3186  * wlansap_update_pre_cac_end() - Update pre cac end to upper layer
3187  * @sap_context: SAP context
3188  * @mac: Global MAC structure
3189  * @intf: Interface number
3190  *
3191  * Notifies pre cac end to upper layer
3192  *
3193  * Return: QDF_STATUS
3194  */
3195 static QDF_STATUS wlansap_update_pre_cac_end(ptSapContext sap_context,
3196 		tpAniSirGlobal mac, uint8_t intf)
3197 {
3198 	QDF_STATUS qdf_status;
3199 
3200 	sap_context->isCacEndNotified = true;
3201 	mac->sap.SapDfsInfo.sap_radar_found_status = false;
3202 	sap_context->sapsMachine = eSAP_STARTED;
3203 
3204 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3205 			"In %s, pre cac end notify on %d: from state %s => %s",
3206 			__func__, intf, "eSAP_DFS_CAC_WAIT",
3207 			"eSAP_STARTED");
3208 
3209 	qdf_status = sap_signal_hdd_event(sap_context,
3210 			NULL, eSAP_DFS_PRE_CAC_END,
3211 			(void *)eSAP_STATUS_SUCCESS);
3212 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
3213 		QDF_TRACE(QDF_MODULE_ID_SAP,
3214 				QDF_TRACE_LEVEL_ERROR,
3215 				"In %s, pre cac notify failed on intf %d",
3216 				__func__, intf);
3217 		return qdf_status;
3218 	}
3219 
3220 	return QDF_STATUS_SUCCESS;
3221 }
3222 
3223 /*==========================================================================
3224    FUNCTION  sap_cac_end_notify
3225 
3226    DESCRIPTION Function will be called to notify eSAP_DFS_CAC_END event
3227    to HDD
3228 
3229    DEPENDENCIES PARAMETERS
3230      IN hHAL : HAL pointer
3231 
3232    RETURN VALUE  : QDF_STATUS.
3233 
3234    SIDE EFFECTS
3235    ============================================================================*/
3236 QDF_STATUS sap_cac_end_notify(tHalHandle hHal, tCsrRoamInfo *roamInfo)
3237 {
3238 	uint8_t intf;
3239 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3240 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3241 
3242 	/*
3243 	 * eSAP_DFS_CHANNEL_CAC_END:
3244 	 * CAC Period elapsed and there was no radar
3245 	 * found so, SAP can continue beaconing.
3246 	 * sap_radar_found_status is set to 0
3247 	 */
3248 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
3249 		ptSapContext pSapContext =
3250 			(ptSapContext) pMac->sap.sapCtxList[intf].pSapContext;
3251 		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
3252 		    ||
3253 		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona))
3254 		    && pMac->sap.sapCtxList[intf].pSapContext != NULL &&
3255 		    (false == pSapContext->isCacEndNotified) &&
3256 		    (pSapContext->sapsMachine == eSAP_DFS_CAC_WAIT)) {
3257 			pSapContext = pMac->sap.sapCtxList[intf].pSapContext;
3258 
3259 			/* If this is an end notification of a pre cac, the
3260 			 * SAP must not start beaconing and must delete the
3261 			 * temporary interface created for pre cac and switch
3262 			 * the original SAP to the pre CAC channel.
3263 			 */
3264 			if (pSapContext->is_pre_cac_on) {
3265 				qdf_status = wlansap_update_pre_cac_end(
3266 						pSapContext, pMac, intf);
3267 				if (QDF_IS_STATUS_ERROR(qdf_status))
3268 					return qdf_status;
3269 				/* pre CAC is not allowed with any concurrency.
3270 				 * So, we can break from here.
3271 				 */
3272 				break;
3273 			}
3274 
3275 			qdf_status = sap_signal_hdd_event(pSapContext, NULL,
3276 							  eSAP_DFS_CAC_END,
3277 							  (void *)
3278 							  eSAP_STATUS_SUCCESS);
3279 			if (QDF_STATUS_SUCCESS != qdf_status) {
3280 				QDF_TRACE(QDF_MODULE_ID_SAP,
3281 					  QDF_TRACE_LEVEL_ERROR,
3282 					  "In %s, failed setting isCacEndNotified on interface[%d]",
3283 					  __func__, intf);
3284 				return qdf_status;
3285 			}
3286 			pSapContext->isCacEndNotified = true;
3287 			pMac->sap.SapDfsInfo.sap_radar_found_status = false;
3288 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
3289 				  "sapdfs: Start beacon request on sapctx[%p]",
3290 				  pSapContext);
3291 
3292 			/* Start beaconing on the new channel */
3293 			wlansap_start_beacon_req(pSapContext);
3294 
3295 			/* Transition from eSAP_STARTING to eSAP_STARTED
3296 			 * (both without substates)
3297 			 */
3298 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
3299 				  "sapdfs: channel[%d] from state %s => %s",
3300 				  pSapContext->channel, "eSAP_STARTING",
3301 				  "eSAP_STARTED");
3302 
3303 			pSapContext->sapsMachine = eSAP_STARTED;
3304 
3305 			/*Action code for transition */
3306 			qdf_status = sap_signal_hdd_event(pSapContext, roamInfo,
3307 							  eSAP_START_BSS_EVENT,
3308 							  (void *)
3309 							  eSAP_STATUS_SUCCESS);
3310 			if (QDF_STATUS_SUCCESS != qdf_status) {
3311 				QDF_TRACE(QDF_MODULE_ID_SAP,
3312 					  QDF_TRACE_LEVEL_ERROR,
3313 					  "In %s, failed setting isCacEndNotified on interface[%d]",
3314 					  __func__, intf);
3315 				return qdf_status;
3316 			}
3317 
3318 			/* Transition from eSAP_STARTING to eSAP_STARTED
3319 			 * (both without substates)
3320 			 */
3321 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3322 				  "In %s, from state %s => %s",
3323 				  __func__, "eSAP_DFS_CAC_WAIT",
3324 				  "eSAP_STARTED");
3325 		}
3326 	}
3327 	/*
3328 	 * All APs are done with CAC timer, all APs should start beaconing.
3329 	 * Lets assume AP1 and AP2 started beaconing on DFS channel, Now lets
3330 	 * say AP1 goes down and comes back on same DFS channel. In this case
3331 	 * AP1 shouldn't start CAC timer and start beacon immediately beacause
3332 	 * AP2 is already beaconing on this channel. This case will be handled
3333 	 * by checking against eSAP_DFS_SKIP_CAC while starting the timer.
3334 	 */
3335 	pMac->sap.SapDfsInfo.cac_state = eSAP_DFS_SKIP_CAC;
3336 	return qdf_status;
3337 }
3338 
3339 /**
3340  * sap_fsm_state_disconnected() - utility function called from sap fsm
3341  * @sap_ctx: SAP context
3342  * @sap_event: SAP event buffer
3343  * @mac_ctx: global MAC context
3344  * @hal: HAL handle
3345  *
3346  * This function is called for state transition from "eSAP_DISCONNECTED"
3347  *
3348  * Return: QDF_STATUS
3349  */
3350 static QDF_STATUS sap_fsm_state_disconnected(ptSapContext sap_ctx,
3351 			ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx,
3352 			tHalHandle hal)
3353 {
3354 	uint32_t msg = sap_event->event;
3355 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3356 
3357 	if (msg == eSAP_HDD_START_INFRA_BSS) {
3358 		/*
3359 		 * Transition from eSAP_DISCONNECTED to eSAP_CH_SELECT
3360 		 * (both without substates)
3361 		 */
3362 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3363 			  FL("new from state %s => %s: session:%d"),
3364 			  "eSAP_DISCONNECTED", "eSAP_CH_SELECT",
3365 			  sap_ctx->sessionId);
3366 
3367 		if (sap_ctx->isSapSessionOpen == eSAP_FALSE) {
3368 			uint32_t type, subtype;
3369 			if (sap_ctx->csr_roamProfile.csrPersona ==
3370 			    QDF_P2P_GO_MODE)
3371 				qdf_status = cds_get_vdev_types(QDF_P2P_GO_MODE,
3372 							&type, &subtype);
3373 			else
3374 				qdf_status = cds_get_vdev_types(QDF_SAP_MODE,
3375 								&type,
3376 								&subtype);
3377 
3378 			if (QDF_STATUS_SUCCESS != qdf_status) {
3379 				QDF_TRACE(QDF_MODULE_ID_SAP,
3380 						QDF_TRACE_LEVEL_FATAL,
3381 						"failed to get vdev type");
3382 				return QDF_STATUS_E_FAILURE;
3383 			}
3384 			/* Open SME Session for scan */
3385 			qdf_status = sme_open_session(hal, NULL,
3386 					sap_ctx, sap_ctx->self_mac_addr,
3387 					&sap_ctx->sessionId, type, subtype);
3388 			if (QDF_STATUS_SUCCESS != qdf_status) {
3389 				QDF_TRACE(QDF_MODULE_ID_SAP,
3390 					 QDF_TRACE_LEVEL_ERROR,
3391 					 FL("Error: calling sme_open_session"));
3392 				return QDF_STATUS_E_FAILURE;
3393 			}
3394 
3395 			sap_ctx->isSapSessionOpen = eSAP_TRUE;
3396 		}
3397 
3398 		/* init dfs channel nol */
3399 		sap_init_dfs_channel_nol_list(sap_ctx);
3400 
3401 		/* Set SAP device role */
3402 		sap_ctx->sapsMachine = eSAP_CH_SELECT;
3403 
3404 		/*
3405 		 * Perform sme_ScanRequest. This scan request is post start bss
3406 		 * request so, set the third to false.
3407 		 */
3408 		qdf_status = sap_goto_channel_sel(sap_ctx, sap_event, false,
3409 						true);
3410 
3411 		/*
3412 		 * Transition from eSAP_DISCONNECTED to eSAP_CH_SELECT
3413 		 * (both without substates)
3414 		 */
3415 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3416 			  FL("from state %s => %s"),
3417 			  "eSAP_DISCONNECTED", "eSAP_CH_SELECT");
3418 	} else if (msg == eSAP_DFS_CHANNEL_CAC_START) {
3419 		/*
3420 		 * No need of state check here, caller is expected to perform
3421 		 * the checks before sending the event
3422 		 */
3423 		sap_ctx->sapsMachine = eSAP_DFS_CAC_WAIT;
3424 
3425 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
3426 			FL("from state eSAP_DISCONNECTED => SAP_DFS_CAC_WAIT"));
3427 		if (mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running != true) {
3428 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
3429 			    FL("sapdfs: starting dfs cac timer on sapctx[%p]"),
3430 			    sap_ctx);
3431 			sap_start_dfs_cac_timer(sap_ctx);
3432 		}
3433 
3434 		qdf_status = sap_cac_start_notify(hal);
3435 	} else if (msg == eSAP_CHANNEL_SELECTION_RETRY) {
3436 		/* Set SAP device role */
3437 		sap_ctx->sapsMachine = eSAP_CH_SELECT;
3438 
3439 		/*
3440 		 * Perform sme_ScanRequest. This scan request is post start bss
3441 		 * request so, set the third to false.
3442 		 */
3443 		qdf_status = sap_goto_channel_sel(sap_ctx, sap_event, false,
3444 					false);
3445 	} else {
3446 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3447 			  FL("in state %s, event msg %d"),
3448 			  "eSAP_DISCONNECTED", msg);
3449 	}
3450 
3451 	return qdf_status;
3452 }
3453 
3454 /**
3455  * sap_fsm_state_ch_select() - utility function called from sap fsm
3456  * @sap_ctx: SAP context
3457  * @sap_event: SAP event buffer
3458  * @mac_ctx: global MAC context
3459  * @hal: HAL handle
3460  *
3461  * This function is called for state transition from "eSAP_CH_SELECT"
3462  *
3463  * Return: QDF_STATUS
3464  */
3465 static QDF_STATUS sap_fsm_state_ch_select(ptSapContext sap_ctx,
3466 			ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx,
3467 			tHalHandle hal)
3468 {
3469 	uint32_t msg = sap_event->event;
3470 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3471 	uint32_t cbmode;
3472 	bool b_leak_chan = false;
3473 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION
3474 	uint8_t temp_chan;
3475 	tSapDfsNolInfo *p_nol;
3476 #endif
3477 
3478 	if (msg == eSAP_MAC_SCAN_COMPLETE) {
3479 		/* get the bonding mode */
3480 		if (sap_ctx->channel <= 14)
3481 			cbmode = sme_get_cb_phy_state_from_cb_ini_value(
3482 					sme_get_channel_bonding_mode24_g(hal));
3483 		else
3484 			cbmode = sme_get_cb_phy_state_from_cb_ini_value(
3485 					sme_get_channel_bonding_mode5_g(hal));
3486 
3487 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION
3488 		temp_chan = sap_ctx->channel;
3489 		p_nol = mac_ctx->sap.SapDfsInfo.sapDfsChannelNolList;
3490 
3491 		sap_mark_leaking_ch(sap_ctx,
3492 			cbmode, p_nol, 1, &temp_chan);
3493 
3494 		/*
3495 		 * if selelcted channel has leakage to channels
3496 		 * in NOL, the temp_chan will be reset
3497 		 */
3498 		b_leak_chan = (temp_chan != sap_ctx->channel);
3499 #endif
3500 		/*
3501 		 * check if channel is in DFS_NOL or if the channel
3502 		 * has leakage to the channels in NOL
3503 		 */
3504 		if (sap_dfs_is_channel_in_nol_list(sap_ctx, sap_ctx->channel,
3505 			cbmode) || b_leak_chan) {
3506 			uint8_t ch;
3507 
3508 			/* find a new available channel */
3509 			ch = sap_random_channel_sel(sap_ctx);
3510 			if (ch == 0) {
3511 				/* No available channel found */
3512 				QDF_TRACE(QDF_MODULE_ID_SAP,
3513 					QDF_TRACE_LEVEL_ERROR,
3514 					FL("No available channel found!!!"));
3515 				sap_signal_hdd_event(sap_ctx, NULL,
3516 					eSAP_DFS_NO_AVAILABLE_CHANNEL,
3517 					(void *)eSAP_STATUS_SUCCESS);
3518 				return QDF_STATUS_E_FAULT;
3519 			}
3520 
3521 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3522 				  FL("channel %d is in NOL, StartBss on new channel %d"),
3523 				  sap_ctx->channel, ch);
3524 
3525 			sap_ctx->channel = ch;
3526 			cds_set_channel_params(sap_ctx->channel,
3527 				sap_ctx->secondary_ch, &sap_ctx->ch_params);
3528 		}
3529 		if (sap_ctx->channel > 14 &&
3530 		    (sap_ctx->csr_roamProfile.phyMode == eCSR_DOT11_MODE_11g ||
3531 		     sap_ctx->csr_roamProfile.phyMode ==
3532 						eCSR_DOT11_MODE_11g_ONLY))
3533 			sap_ctx->csr_roamProfile.phyMode = eCSR_DOT11_MODE_11a;
3534 
3535 		/*
3536 		 * when AP2 is started while AP1 is performing ACS, we may not
3537 		 * have the AP1 channel yet.So here after the completion of AP2
3538 		 * ACS check if AP1 ACS resulting channel is DFS and if yes
3539 		 * override AP2 ACS scan result with AP1 DFS channel
3540 		 */
3541 		if (cds_concurrent_beaconing_sessions_running()) {
3542 			uint16_t con_ch;
3543 
3544 			con_ch = sme_get_concurrent_operation_channel(hal);
3545 			if (con_ch && CDS_IS_DFS_CH(con_ch))
3546 				sap_ctx->channel = con_ch;
3547 		}
3548 
3549 		/*
3550 		 * Transition from eSAP_CH_SELECT to eSAP_STARTING
3551 		 * (both without substates)
3552 		 */
3553 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3554 			  FL("from state %s => %s"),
3555 			  "eSAP_CH_SELECT", "eSAP_STARTING");
3556 		/* Channel selected. Now can sap_goto_starting */
3557 		sap_ctx->sapsMachine = eSAP_STARTING;
3558 		/* Specify the channel */
3559 		sap_ctx->csr_roamProfile.ChannelInfo.numOfChannels =
3560 						1;
3561 		sap_ctx->csr_roamProfile.ChannelInfo.ChannelList =
3562 			&sap_ctx->csr_roamProfile.operationChannel;
3563 		sap_ctx->csr_roamProfile.operationChannel =
3564 			(uint8_t) sap_ctx->channel;
3565 		sap_ctx->csr_roamProfile.ch_params.ch_width =
3566 					sap_ctx->ch_params.ch_width;
3567 		sap_ctx->csr_roamProfile.ch_params.center_freq_seg0 =
3568 				sap_ctx->ch_params.center_freq_seg0;
3569 		sap_ctx->csr_roamProfile.ch_params.center_freq_seg1 =
3570 				sap_ctx->ch_params.center_freq_seg1;
3571 		sap_ctx->csr_roamProfile.ch_params.sec_ch_offset =
3572 				sap_ctx->ch_params.sec_ch_offset;
3573 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3574 		    FL("notify hostapd about channel selection: %d"),
3575 		    sap_ctx->channel);
3576 		sap_signal_hdd_event(sap_ctx, NULL,
3577 					eSAP_CHANNEL_CHANGE_EVENT,
3578 					(void *) eSAP_STATUS_SUCCESS);
3579 		qdf_status = sap_goto_starting(sap_ctx, sap_event,
3580 					  eCSR_BSS_TYPE_INFRA_AP);
3581 	} else if (msg == eSAP_CHANNEL_SELECTION_FAILED) {
3582 		sap_ctx->sapsMachine = eSAP_DISCONNECTED;
3583 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3584 		FL("Cannot start BSS, ACS Fail"));
3585 	} else if (msg == eSAP_HDD_STOP_INFRA_BSS) {
3586 		sap_ctx->sapsMachine = eSAP_DISCONNECTED;
3587 		sap_signal_hdd_event(sap_ctx, NULL, eSAP_START_BSS_EVENT,
3588 					(void *)eSAP_STATUS_FAILURE);
3589 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
3590 			"%s: BSS stopped when Ch select in Progress", __func__);
3591 	} else {
3592 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3593 			  FL("in state %s, invalid event msg %d"),
3594 			  "eSAP_CH_SELECT", msg);
3595 	}
3596 
3597 	return qdf_status;
3598 }
3599 
3600 /**
3601  * sap_fsm_state_dfs_cac_wait() - utility function called from sap fsm
3602  * @sap_ctx: SAP context
3603  * @sap_event: SAP event buffer
3604  * @mac_ctx: global MAC context
3605  * @hal: HAL handle
3606  *
3607  * This function is called for state transition from "eSAP_DFS_CAC_WAIT"
3608  *
3609  * Return: QDF_STATUS
3610  */
3611 static QDF_STATUS sap_fsm_state_dfs_cac_wait(ptSapContext sap_ctx,
3612 			ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx,
3613 			tHalHandle hal)
3614 {
3615 	uint32_t msg = sap_event->event;
3616 	tCsrRoamInfo *roam_info = (tCsrRoamInfo *) (sap_event->params);
3617 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3618 
3619 	if (msg == eSAP_DFS_CHANNEL_CAC_START) {
3620 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3621 			  FL("from state %s => %s"),
3622 			  "eSAP_CH_SELECT", "eSAP_DFS_CAC_WAIT");
3623 		if (mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running != true)
3624 			sap_start_dfs_cac_timer(sap_ctx);
3625 		qdf_status = sap_cac_start_notify(hal);
3626 	} else if (msg == eSAP_DFS_CHANNEL_CAC_RADAR_FOUND) {
3627 		uint8_t intf;
3628 		/*
3629 		 * Radar found while performing channel availability
3630 		 * check, need to switch the channel again
3631 		 */
3632 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
3633 			  "ENTERTRED CAC WAIT STATE-->eSAP_DISCONNECTING\n");
3634 		if (mac_ctx->sap.SapDfsInfo.target_channel) {
3635 			cds_set_channel_params(
3636 				mac_ctx->sap.SapDfsInfo.target_channel, 0,
3637 				&sap_ctx->ch_params);
3638 		}
3639 
3640 		for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
3641 			ptSapContext t_sap_ctx;
3642 			if (((QDF_SAP_MODE ==
3643 				 mac_ctx->sap.sapCtxList[intf].sapPersona) ||
3644 			     (QDF_P2P_GO_MODE ==
3645 				mac_ctx->sap.sapCtxList[intf].sapPersona)) &&
3646 			    mac_ctx->sap.sapCtxList[intf].pSapContext != NULL) {
3647 				t_sap_ctx =
3648 				    mac_ctx->sap.sapCtxList[intf].pSapContext;
3649 				/* SAP to be moved to DISCONNECTING state */
3650 				sap_ctx->sapsMachine = eSAP_DISCONNECTING;
3651 				/*
3652 				 * eSAP_DFS_CHANNEL_CAC_RADAR_FOUND:
3653 				 * A Radar is found on current DFS Channel
3654 				 * while in CAC WAIT period So, do a channel
3655 				 * switch to randomly selected  target channel.
3656 				 * Send the Channel change message to SME/PE.
3657 				 * sap_radar_found_status is set to 1
3658 				 */
3659 				sap_signal_hdd_event(t_sap_ctx, NULL,
3660 					eSAP_DFS_RADAR_DETECT,
3661 					(void *)eSAP_STATUS_SUCCESS);
3662 
3663 				wlansap_channel_change_request(
3664 					(void *)t_sap_ctx,
3665 					mac_ctx->sap.SapDfsInfo.target_channel);
3666 			}
3667 		}
3668 	} else if (msg == eSAP_DFS_CHANNEL_CAC_END) {
3669 		qdf_status = sap_cac_end_notify(hal, roam_info);
3670 	} else if (msg == eSAP_HDD_STOP_INFRA_BSS) {
3671 		/* Transition from eSAP_DFS_CAC_WAIT to eSAP_DISCONNECTING */
3672 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3673 			  FL("from state %s => %s"),
3674 			  "eSAP_DFS_CAC_WAIT", "eSAP_DISCONNECTING");
3675 
3676 		/*
3677 		 * Stop the CAC timer only in following conditions
3678 		 * single AP: if there is a single AP then stop the timer
3679 		 * mulitple APs: incase of multiple APs, make sure that
3680 		 *               all APs are down.
3681 		 */
3682 		if (NULL == sap_find_valid_concurrent_session(hal)) {
3683 			QDF_TRACE(QDF_MODULE_ID_SAP,
3684 				  QDF_TRACE_LEVEL_INFO_MED,
3685 				  FL("sapdfs: no sessions are valid, stopping timer"));
3686 			sap_stop_dfs_cac_timer(sap_ctx);
3687 		}
3688 
3689 		sap_ctx->sapsMachine = eSAP_DISCONNECTING;
3690 		qdf_status = sap_goto_disconnecting(sap_ctx);
3691 	} else {
3692 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3693 			  FL("in state %s, invalid event msg %d"),
3694 			  "eSAP_DFS_CAC_WAIT", msg);
3695 	}
3696 
3697 	return qdf_status;
3698 }
3699 
3700 /**
3701  * sap_fsm_state_starting() - utility function called from sap fsm
3702  * @sap_ctx: SAP context
3703  * @sap_event: SAP event buffer
3704  * @mac_ctx: global MAC context
3705  * @hal: HAL handle
3706  *
3707  * This function is called for state transition from "eSAP_STARTING"
3708  *
3709  * Return: QDF_STATUS
3710  */
3711 static QDF_STATUS sap_fsm_state_starting(ptSapContext sap_ctx,
3712 			ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx,
3713 			tHalHandle hal)
3714 {
3715 	uint32_t msg = sap_event->event;
3716 	tCsrRoamInfo *roam_info = (tCsrRoamInfo *) (sap_event->params);
3717 	tSapDfsInfo *sap_dfs_info;
3718 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3719 	uint8_t is_dfs = false;
3720 
3721 	if (msg == eSAP_MAC_START_BSS_SUCCESS) {
3722 		/*
3723 		 * Transition from eSAP_STARTING to eSAP_STARTED
3724 		 * (both without substates)
3725 		 */
3726 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3727 			  FL("from state channel = %d %s => %s ch_width %d"),
3728 			  sap_ctx->channel, "eSAP_STARTING", "eSAP_STARTED",
3729 			  sap_ctx->ch_params.ch_width);
3730 		sap_ctx->sapsMachine = eSAP_STARTED;
3731 
3732 		/* Action code for transition */
3733 		qdf_status = sap_signal_hdd_event(sap_ctx, roam_info,
3734 				eSAP_START_BSS_EVENT,
3735 				(void *) eSAP_STATUS_SUCCESS);
3736 
3737 		/*
3738 		 * The upper layers have been informed that AP is up and
3739 		 * running, however, the AP is still not beaconing, until
3740 		 * CAC is done if the operating channel is DFS
3741 		 */
3742 		if (sap_ctx->ch_params.ch_width == CH_WIDTH_160MHZ) {
3743 			is_dfs = true;
3744 		} else if (sap_ctx->ch_params.ch_width == CH_WIDTH_80P80MHZ) {
3745 			if (cds_get_channel_state(sap_ctx->channel) ==
3746 			    CHANNEL_STATE_DFS ||
3747 			    cds_get_channel_state(sap_ctx->
3748 				ch_params.center_freq_seg1 -
3749 				SIR_80MHZ_START_CENTER_CH_DIFF) ==
3750 					CHANNEL_STATE_DFS)
3751 				is_dfs = true;
3752 		} else {
3753 			if (cds_get_channel_state(sap_ctx->channel) ==
3754 							CHANNEL_STATE_DFS)
3755 				is_dfs = true;
3756 		}
3757 
3758 		if (is_dfs) {
3759 			sap_dfs_info = &mac_ctx->sap.SapDfsInfo;
3760 			if ((false == sap_dfs_info->ignore_cac) &&
3761 			    (eSAP_DFS_DO_NOT_SKIP_CAC ==
3762 					sap_dfs_info->cac_state) &&
3763 			    !sap_ctx->pre_cac_complete) {
3764 				/* Move the device in CAC_WAIT_STATE */
3765 				sap_ctx->sapsMachine = eSAP_DFS_CAC_WAIT;
3766 
3767 				/*
3768 				 * Need to stop the OS transmit queues,
3769 				 * so that no traffic can flow down the stack
3770 				 */
3771 
3772 				/* Start CAC wait timer */
3773 				if (sap_dfs_info->is_dfs_cac_timer_running !=
3774 									true)
3775 					sap_start_dfs_cac_timer(sap_ctx);
3776 				qdf_status = sap_cac_start_notify(hal);
3777 
3778 			} else {
3779 				wlansap_start_beacon_req(sap_ctx);
3780 			}
3781 		}
3782 	} else if (msg == eSAP_MAC_START_FAILS) {
3783 		/*
3784 		 * Transition from STARTING to DISCONNECTED
3785 		 * (both without substates)
3786 		 */
3787 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3788 			  FL("from state %s => %s"),
3789 			  "eSAP_STARTING", "eSAP_DISCONNECTED");
3790 
3791 		/*Action code for transition */
3792 		qdf_status = sap_signal_hdd_event(sap_ctx, NULL,
3793 				eSAP_START_BSS_EVENT,
3794 				(void *) eSAP_STATUS_FAILURE);
3795 		qdf_status = sap_goto_disconnected(sap_ctx);
3796 		/* Advance outer statevar */
3797 		sap_ctx->sapsMachine = eSAP_DISCONNECTED;
3798 	} else if (msg == eSAP_HDD_STOP_INFRA_BSS) {
3799 		/*
3800 		 * Transition from eSAP_STARTING to eSAP_DISCONNECTED
3801 		 * (both without substates)
3802 		 */
3803 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3804 			  FL("from state %s => %s"),
3805 			  "eSAP_STARTING", "eSAP_DISCONNECTED");
3806 
3807 		/* Advance outer statevar */
3808 		sap_ctx->sapsMachine = eSAP_DISCONNECTED;
3809 		qdf_status = sap_signal_hdd_event(sap_ctx, NULL,
3810 				eSAP_START_BSS_EVENT,
3811 				(void *) eSAP_STATUS_FAILURE);
3812 		qdf_status = sap_goto_disconnected(sap_ctx);
3813 		/* Close the SME session */
3814 
3815 		if (eSAP_TRUE == sap_ctx->isSapSessionOpen) {
3816 			if (QDF_STATUS_SUCCESS == sap_close_session(hal,
3817 						sap_ctx, NULL, false))
3818 				sap_ctx->isSapSessionOpen = eSAP_FALSE;
3819 		}
3820 	} else if (msg == eSAP_OPERATING_CHANNEL_CHANGED) {
3821 		/* The operating channel has changed, update hostapd */
3822 		sap_ctx->channel =
3823 			(uint8_t) mac_ctx->sap.SapDfsInfo.target_channel;
3824 
3825 		sap_ctx->sapsMachine = eSAP_STARTED;
3826 
3827 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3828 			  FL("from state %s => %s"),
3829 			  "eSAP_STARTING", "eSAP_STARTED");
3830 
3831 		/* Indicate change in the state to upper layers */
3832 		qdf_status = sap_signal_hdd_event(sap_ctx, roam_info,
3833 				  eSAP_START_BSS_EVENT,
3834 				  (void *)eSAP_STATUS_SUCCESS);
3835 	} else {
3836 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3837 			  FL("in state %s, invalid event msg %d"),
3838 			  "eSAP_STARTING", msg);
3839 	}
3840 
3841 	return qdf_status;
3842 }
3843 
3844 /**
3845  * sap_fsm_state_started() - utility function called from sap fsm
3846  * @sap_ctx: SAP context
3847  * @sap_event: SAP event buffer
3848  * @mac_ctx: global MAC context
3849  *
3850  * This function is called for state transition from "eSAP_STARTED"
3851  *
3852  * Return: QDF_STATUS
3853  */
3854 static QDF_STATUS sap_fsm_state_started(ptSapContext sap_ctx,
3855 			ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx)
3856 {
3857 	uint32_t msg = sap_event->event;
3858 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3859 
3860 	if (msg == eSAP_HDD_STOP_INFRA_BSS) {
3861 		/*
3862 		 * Transition from eSAP_STARTED to eSAP_DISCONNECTING
3863 		 * (both without substates)
3864 		 */
3865 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3866 			  FL("from state %s => %s"),
3867 			  "eSAP_STARTED", "eSAP_DISCONNECTING");
3868 		sap_ctx->sapsMachine = eSAP_DISCONNECTING;
3869 		qdf_status = sap_goto_disconnecting(sap_ctx);
3870 	} else if (eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START == msg) {
3871 		uint8_t intf;
3872 		/*
3873 		 * Radar is seen on the current operating channel
3874 		 * send CSA IE for all associated stations
3875 		 * Request for CSA IE transmission
3876 		 */
3877 		for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
3878 			ptSapContext temp_sap_ctx;
3879 			if (((QDF_SAP_MODE ==
3880 				mac_ctx->sap.sapCtxList[intf].sapPersona) ||
3881 			    (QDF_P2P_GO_MODE ==
3882 				mac_ctx->sap.sapCtxList[intf].sapPersona)) &&
3883 			    mac_ctx->sap.sapCtxList[intf].pSapContext != NULL) {
3884 				temp_sap_ctx =
3885 				    mac_ctx->sap.sapCtxList[intf].pSapContext;
3886 				QDF_TRACE(QDF_MODULE_ID_SAP,
3887 					  QDF_TRACE_LEVEL_INFO_MED,
3888 					  FL("sapdfs: Sending CSAIE for sapctx[%p]"),
3889 					  temp_sap_ctx);
3890 
3891 				qdf_status = wlansap_dfs_send_csa_ie_request(
3892 						(void *) temp_sap_ctx);
3893 			}
3894 		}
3895 	} else if (eSAP_CHANNEL_SWITCH_ANNOUNCEMENT_START == msg) {
3896 		enum tQDF_ADAPTER_MODE persona;
3897 
3898 		if (!sap_ctx) {
3899 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3900 					FL("Invalid sap_ctx"));
3901 			return qdf_status;
3902 		}
3903 
3904 		persona = mac_ctx->sap.sapCtxList[sap_ctx->sessionId].
3905 								sapPersona;
3906 
3907 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
3908 				FL("app trigger chan switch: mode:%d vdev:%d"),
3909 				persona, sap_ctx->sessionId);
3910 
3911 		if ((QDF_SAP_MODE == persona) || (QDF_P2P_GO_MODE == persona))
3912 			qdf_status = wlansap_dfs_send_csa_ie_request(
3913 					(void *) sap_ctx);
3914 	} else {
3915 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3916 			  FL("in state %s, invalid event msg %d"),
3917 			  "eSAP_STARTED", msg);
3918 	}
3919 
3920 	return qdf_status;
3921 }
3922 
3923 /**
3924  * sap_fsm_state_disconnecting() - utility function called from sap fsm
3925  * @sap_ctx: SAP context
3926  * @sap_event: SAP event buffer
3927  * @mac_ctx: global MAC context
3928  *
3929  * This function is called for state transition from "eSAP_DISCONNECTING"
3930  *
3931  * Return: QDF_STATUS
3932  */
3933 static QDF_STATUS sap_fsm_state_disconnecting(ptSapContext sap_ctx,
3934 			ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx,
3935 			tHalHandle hal)
3936 {
3937 	uint32_t msg = sap_event->event;
3938 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3939 
3940 	if (msg == eSAP_MAC_READY_FOR_CONNECTIONS) {
3941 		/*
3942 		 * Transition from eSAP_DISCONNECTING to eSAP_DISCONNECTED
3943 		 * (both without substates)
3944 		 */
3945 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3946 			  FL("from state %s => %s"),
3947 			  "eSAP_DISCONNECTING", "eSAP_DISCONNECTED");
3948 		sap_ctx->sapsMachine = eSAP_DISCONNECTED;
3949 
3950 		/* Close the SME session */
3951 		if (eSAP_TRUE == sap_ctx->isSapSessionOpen) {
3952 			sap_ctx->isSapSessionOpen = eSAP_FALSE;
3953 			qdf_status = sap_close_session(hal, sap_ctx,
3954 					sap_roam_session_close_callback, true);
3955 			if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
3956 				qdf_status = sap_signal_hdd_event(sap_ctx, NULL,
3957 						eSAP_STOP_BSS_EVENT,
3958 						(void *)eSAP_STATUS_SUCCESS);
3959 			}
3960 		}
3961 	} else if (msg == eWNI_SME_CHANNEL_CHANGE_REQ) {
3962 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
3963 			  FL("sapdfs: Send channel change request on sapctx[%p]"),
3964 			  sap_ctx);
3965 		/*
3966 		 * Most likely, radar has been detected and SAP wants to
3967 		 * change the channel
3968 		 */
3969 		qdf_status = wlansap_channel_change_request((void *) sap_ctx,
3970 				mac_ctx->sap.SapDfsInfo.target_channel);
3971 
3972 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
3973 			  FL("Sending DFS eWNI_SME_CHANNEL_CHANGE_REQ"));
3974 	} else {
3975 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3976 			  FL("in state %s, invalid event msg %d"),
3977 			  "eSAP_DISCONNECTING", msg);
3978 	}
3979 
3980 	return qdf_status;
3981 }
3982 
3983 /**
3984  * sap_fsm() - SAP statem machine entry function
3985  * @sap_ctx: SAP context
3986  * @sap_event: SAP event
3987  *
3988  * SAP statem machine entry function
3989  *
3990  * Return: QDF_STATUS
3991  */
3992 QDF_STATUS sap_fsm(ptSapContext sap_ctx, ptWLAN_SAPEvent sap_event)
3993 {
3994 	/*
3995 	 * Retrieve the phy link state machine structure
3996 	 * from the sap_ctx value
3997 	 * state var that keeps track of state machine
3998 	 */
3999 	eSapFsmStates_t state_var = sap_ctx->sapsMachine;
4000 	uint32_t msg = sap_event->event; /* State machine input event message */
4001 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
4002 	tHalHandle hal = CDS_GET_HAL_CB(sap_ctx->p_cds_gctx);
4003 	tpAniSirGlobal mac_ctx;
4004 
4005 	if (NULL == hal) {
4006 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4007 			  FL("Invalid hal"));
4008 		return QDF_STATUS_E_FAILURE;
4009 	}
4010 
4011 	mac_ctx = PMAC_STRUCT(hal);
4012 	if (NULL == mac_ctx) {
4013 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4014 			  FL("Invalid MAC context"));
4015 		return QDF_STATUS_E_FAILURE;
4016 	}
4017 
4018 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
4019 		  FL("sap_ctx=%p, state_var=%d, msg=0x%x"),
4020 		  sap_ctx, state_var, msg);
4021 
4022 	switch (state_var) {
4023 	case eSAP_DISCONNECTED:
4024 		qdf_status = sap_fsm_state_disconnected(sap_ctx, sap_event,
4025 				mac_ctx, hal);
4026 		break;
4027 
4028 	case eSAP_CH_SELECT:
4029 		qdf_status = sap_fsm_state_ch_select(sap_ctx, sap_event,
4030 				mac_ctx, hal);
4031 		break;
4032 
4033 	case eSAP_DFS_CAC_WAIT:
4034 		qdf_status = sap_fsm_state_dfs_cac_wait(sap_ctx, sap_event,
4035 				mac_ctx, hal);
4036 		break;
4037 
4038 	case eSAP_STARTING:
4039 		qdf_status = sap_fsm_state_starting(sap_ctx, sap_event,
4040 				mac_ctx, hal);
4041 		break;
4042 
4043 	case eSAP_STARTED:
4044 		qdf_status = sap_fsm_state_started(sap_ctx, sap_event,
4045 				mac_ctx);
4046 		break;
4047 
4048 	case eSAP_DISCONNECTING:
4049 		qdf_status = sap_fsm_state_disconnecting(sap_ctx, sap_event,
4050 				mac_ctx, hal);
4051 		break;
4052 	}
4053 	return qdf_status;
4054 }
4055 
4056 eSapStatus
4057 sapconvert_to_csr_profile(tsap_Config_t *pconfig_params, eCsrRoamBssType bssType,
4058 			  tCsrRoamProfile *profile)
4059 {
4060 	/* Create Roam profile for SoftAP to connect */
4061 	profile->BSSType = eCSR_BSS_TYPE_INFRA_AP;
4062 	profile->SSIDs.numOfSSIDs = 1;
4063 	profile->csrPersona = pconfig_params->persona;
4064 	profile->disableDFSChSwitch = pconfig_params->disableDFSChSwitch;
4065 
4066 	qdf_mem_zero(profile->SSIDs.SSIDList[0].SSID.ssId,
4067 		     sizeof(profile->SSIDs.SSIDList[0].SSID.ssId));
4068 
4069 	/* Flag to not broadcast the SSID information */
4070 	profile->SSIDs.SSIDList[0].ssidHidden =
4071 		pconfig_params->SSIDinfo.ssidHidden;
4072 
4073 	profile->SSIDs.SSIDList[0].SSID.length =
4074 		pconfig_params->SSIDinfo.ssid.length;
4075 	qdf_mem_copy(&profile->SSIDs.SSIDList[0].SSID.ssId,
4076 		     pconfig_params->SSIDinfo.ssid.ssId,
4077 		     sizeof(pconfig_params->SSIDinfo.ssid.ssId));
4078 
4079 	profile->negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4080 
4081 	if (pconfig_params->authType == eSAP_OPEN_SYSTEM) {
4082 		profile->negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4083 	} else if (pconfig_params->authType == eSAP_SHARED_KEY) {
4084 		profile->negotiatedAuthType = eCSR_AUTH_TYPE_SHARED_KEY;
4085 	} else {
4086 		profile->negotiatedAuthType = eCSR_AUTH_TYPE_AUTOSWITCH;
4087 	}
4088 
4089 	profile->AuthType.numEntries = 1;
4090 	profile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4091 
4092 	/* Always set the Encryption Type */
4093 	profile->EncryptionType.numEntries = 1;
4094 	profile->EncryptionType.encryptionType[0] =
4095 		pconfig_params->RSNEncryptType;
4096 
4097 	profile->mcEncryptionType.numEntries = 1;
4098 	profile->mcEncryptionType.encryptionType[0] =
4099 		pconfig_params->mcRSNEncryptType;
4100 
4101 	if (pconfig_params->privacy & eSAP_SHARED_KEY) {
4102 		profile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY;
4103 	}
4104 
4105 	profile->privacy = pconfig_params->privacy;
4106 	profile->fwdWPSPBCProbeReq = pconfig_params->fwdWPSPBCProbeReq;
4107 
4108 	if (pconfig_params->authType == eSAP_SHARED_KEY) {
4109 		profile->csr80211AuthType = eSIR_SHARED_KEY;
4110 	} else if (pconfig_params->authType == eSAP_OPEN_SYSTEM) {
4111 		profile->csr80211AuthType = eSIR_OPEN_SYSTEM;
4112 	} else {
4113 		profile->csr80211AuthType = eSIR_AUTO_SWITCH;
4114 	}
4115 
4116 	/* Initialize we are not going to use it */
4117 	profile->pWPAReqIE = NULL;
4118 	profile->nWPAReqIELength = 0;
4119 
4120 	/* set the RSN/WPA IE */
4121 	profile->pRSNReqIE = NULL;
4122 	profile->nRSNReqIELength = pconfig_params->RSNWPAReqIELength;
4123 	if (pconfig_params->RSNWPAReqIELength) {
4124 		profile->pRSNReqIE =
4125 			qdf_mem_malloc(pconfig_params->RSNWPAReqIELength);
4126 		if (NULL == profile->pRSNReqIE) {
4127 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4128 				  " %s Fail to alloc memory", __func__);
4129 			return eSAP_STATUS_FAILURE;
4130 		}
4131 		qdf_mem_copy(profile->pRSNReqIE, pconfig_params->RSNWPAReqIE,
4132 			     pconfig_params->RSNWPAReqIELength);
4133 		profile->nRSNReqIELength = pconfig_params->RSNWPAReqIELength;
4134 	}
4135 	/* Turn off CB mode */
4136 	profile->CBMode = eCSR_CB_OFF;
4137 
4138 	/* set the phyMode to accept anything */
4139 	/* Best means everything because it covers all the things we support */
4140 	/* eCSR_DOT11_MODE_BEST */
4141 	profile->phyMode = pconfig_params->SapHw_mode;
4142 
4143 	/* Configure beaconInterval */
4144 	profile->beaconInterval = (uint16_t) pconfig_params->beacon_int;
4145 
4146 	/* set DTIM period */
4147 	profile->dtimPeriod = pconfig_params->dtim_period;
4148 
4149 	/* set Uapsd enable bit */
4150 	profile->ApUapsdEnable = pconfig_params->UapsdEnable;
4151 
4152 	/* Enable protection parameters */
4153 	profile->protEnabled = pconfig_params->protEnabled;
4154 	profile->obssProtEnabled = pconfig_params->obssProtEnabled;
4155 	profile->cfg_protection = pconfig_params->ht_capab;
4156 
4157 	/* country code */
4158 	if (pconfig_params->countryCode[0])
4159 		qdf_mem_copy(profile->countryCode, pconfig_params->countryCode,
4160 			     WNI_CFG_COUNTRY_CODE_LEN);
4161 	profile->ieee80211d = pconfig_params->ieee80211d;
4162 	/* wps config info */
4163 	profile->wps_state = pconfig_params->wps_state;
4164 
4165 #ifdef WLAN_FEATURE_11W
4166 	/* MFP capable/required */
4167 	profile->MFPCapable = pconfig_params->mfpCapable ? 1 : 0;
4168 	profile->MFPRequired = pconfig_params->mfpRequired ? 1 : 0;
4169 #endif
4170 
4171 	if (pconfig_params->probeRespIEsBufferLen > 0 &&
4172 	    pconfig_params->pProbeRespIEsBuffer != NULL) {
4173 		profile->addIeParams.probeRespDataLen =
4174 			pconfig_params->probeRespIEsBufferLen;
4175 		profile->addIeParams.probeRespData_buff =
4176 			pconfig_params->pProbeRespIEsBuffer;
4177 	} else {
4178 		profile->addIeParams.probeRespDataLen = 0;
4179 		profile->addIeParams.probeRespData_buff = NULL;
4180 	}
4181 	/*assoc resp IE */
4182 	if (pconfig_params->assocRespIEsLen > 0 &&
4183 	    pconfig_params->pAssocRespIEsBuffer != NULL) {
4184 		profile->addIeParams.assocRespDataLen =
4185 			pconfig_params->assocRespIEsLen;
4186 		profile->addIeParams.assocRespData_buff =
4187 			pconfig_params->pAssocRespIEsBuffer;
4188 	} else {
4189 		profile->addIeParams.assocRespDataLen = 0;
4190 		profile->addIeParams.assocRespData_buff = NULL;
4191 	}
4192 
4193 	if (pconfig_params->probeRespBcnIEsLen > 0 &&
4194 	    pconfig_params->pProbeRespBcnIEsBuffer != NULL) {
4195 		profile->addIeParams.probeRespBCNDataLen =
4196 			pconfig_params->probeRespBcnIEsLen;
4197 		profile->addIeParams.probeRespBCNData_buff =
4198 			pconfig_params->pProbeRespBcnIEsBuffer;
4199 	} else {
4200 		profile->addIeParams.probeRespBCNDataLen = 0;
4201 		profile->addIeParams.probeRespBCNData_buff = NULL;
4202 	}
4203 	profile->sap_dot11mc = pconfig_params->sap_dot11mc;
4204 
4205 	return eSAP_STATUS_SUCCESS;     /* Success. */
4206 }
4207 
4208 void sap_free_roam_profile(tCsrRoamProfile *profile)
4209 {
4210 	if (profile->pRSNReqIE) {
4211 		qdf_mem_free(profile->pRSNReqIE);
4212 		profile->pRSNReqIE = NULL;
4213 	}
4214 }
4215 
4216 void sap_sort_mac_list(struct qdf_mac_addr *macList, uint8_t size)
4217 {
4218 	uint8_t outer, inner;
4219 	struct qdf_mac_addr temp;
4220 	int32_t nRes = -1;
4221 
4222 	if ((NULL == macList) || (size > MAX_ACL_MAC_ADDRESS)) {
4223 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4224 			FL("either buffer is NULL or size = %d is more"), size);
4225 		return;
4226 	}
4227 
4228 	for (outer = 0; outer < size; outer++) {
4229 		for (inner = 0; inner < size - 1; inner++) {
4230 			nRes =
4231 				qdf_mem_cmp((macList + inner)->bytes,
4232 						 (macList + inner + 1)->bytes,
4233 						 QDF_MAC_ADDR_SIZE);
4234 			if (nRes > 0) {
4235 				qdf_mem_copy(temp.bytes,
4236 					     (macList + inner + 1)->bytes,
4237 					     QDF_MAC_ADDR_SIZE);
4238 				qdf_mem_copy((macList + inner + 1)->bytes,
4239 					     (macList + inner)->bytes,
4240 					     QDF_MAC_ADDR_SIZE);
4241 				qdf_mem_copy((macList + inner)->bytes,
4242 					     temp.bytes, QDF_MAC_ADDR_SIZE);
4243 			}
4244 		}
4245 	}
4246 }
4247 
4248 eSapBool
4249 sap_search_mac_list(struct qdf_mac_addr *macList,
4250 		    uint8_t num_mac, uint8_t *peerMac,
4251 		    uint8_t *index)
4252 {
4253 	int32_t nRes = -1;
4254 	int8_t nStart = 0, nEnd, nMiddle;
4255 	nEnd = num_mac - 1;
4256 
4257 	if ((NULL == macList) || (num_mac > MAX_ACL_MAC_ADDRESS)) {
4258 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4259 		    FL("either buffer is NULL or size = %d is more."), num_mac);
4260 		return eSAP_FALSE;
4261 	}
4262 
4263 	while (nStart <= nEnd) {
4264 		nMiddle = (nStart + nEnd) / 2;
4265 		nRes =
4266 			qdf_mem_cmp(&macList[nMiddle], peerMac,
4267 					 QDF_MAC_ADDR_SIZE);
4268 
4269 		if (0 == nRes) {
4270 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4271 				  "search SUCC");
4272 			/* "index equals NULL" means the caller does not need the */
4273 			/* index value of the peerMac being searched */
4274 			if (index != NULL) {
4275 				*index = (uint8_t) nMiddle;
4276 				QDF_TRACE(QDF_MODULE_ID_SAP,
4277 					  QDF_TRACE_LEVEL_INFO_HIGH, "index %d",
4278 					  *index);
4279 			}
4280 			return eSAP_TRUE;
4281 		}
4282 		if (nRes < 0)
4283 			nStart = nMiddle + 1;
4284 		else
4285 			nEnd = nMiddle - 1;
4286 	}
4287 
4288 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4289 		  "search not succ");
4290 	return eSAP_FALSE;
4291 }
4292 
4293 void sap_add_mac_to_acl(struct qdf_mac_addr *macList,
4294 			uint8_t *size, uint8_t *peerMac)
4295 {
4296 	int32_t nRes = -1;
4297 	int i;
4298 
4299 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4300 		  "add acl entered");
4301 
4302 	if (NULL == macList || *size == 0 || *size > MAX_ACL_MAC_ADDRESS) {
4303 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4304 			FL("either buffer is NULL or size = %d is incorrect."),
4305 			*size);
4306 		return;
4307 	}
4308 
4309 	for (i = ((*size) - 1); i >= 0; i--) {
4310 		nRes =
4311 			qdf_mem_cmp(&macList[i], peerMac, QDF_MAC_ADDR_SIZE);
4312 		if (nRes > 0) {
4313 			/* Move alphabetically greater mac addresses one index down to allow for insertion
4314 			   of new mac in sorted order */
4315 			qdf_mem_copy((macList + i + 1)->bytes,
4316 				     (macList + i)->bytes, QDF_MAC_ADDR_SIZE);
4317 		} else {
4318 			break;
4319 		}
4320 	}
4321 	/* This should also take care of if the element is the first to be added in the list */
4322 	qdf_mem_copy((macList + i + 1)->bytes, peerMac, QDF_MAC_ADDR_SIZE);
4323 	/* increment the list size */
4324 	(*size)++;
4325 }
4326 
4327 void sap_remove_mac_from_acl(struct qdf_mac_addr *macList,
4328 			     uint8_t *size, uint8_t index)
4329 {
4330 	int i;
4331 
4332 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4333 		  "remove acl entered");
4334 	/*
4335 	 * Return if the list passed is empty. Ideally this should never happen
4336 	 * since this funcn is always called after sap_search_mac_list to get
4337 	 * the index of the mac addr to be removed and this will only get
4338 	 * called if the search is successful. Still no harm in having the check
4339 	 */
4340 	if ((macList == NULL) || (*size == 0) ||
4341 					(*size > MAX_ACL_MAC_ADDRESS)) {
4342 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4343 			FL("either buffer is NULL or size %d is incorrect."),
4344 			*size);
4345 		return;
4346 	}
4347 	for (i = index; i < ((*size) - 1); i++) {
4348 		/* Move mac addresses starting from "index" passed one index up to delete the void
4349 		   created by deletion of a mac address in ACL */
4350 		qdf_mem_copy((macList + i)->bytes, (macList + i + 1)->bytes,
4351 			     QDF_MAC_ADDR_SIZE);
4352 	}
4353 	/* The last space should be made empty since all mac addesses moved one step up */
4354 	qdf_mem_zero((macList + (*size) - 1)->bytes, QDF_MAC_ADDR_SIZE);
4355 	/* reduce the list size by 1 */
4356 	(*size)--;
4357 }
4358 
4359 void sap_print_acl(struct qdf_mac_addr *macList, uint8_t size)
4360 {
4361 	int i;
4362 	uint8_t *macArray;
4363 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4364 		  "print acl entered");
4365 
4366 	if ((NULL == macList) || (size == 0) || (size >= MAX_ACL_MAC_ADDRESS)) {
4367 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4368 			  "In %s, either buffer is NULL or size %d is incorrect.",
4369 			  __func__, size);
4370 		return;
4371 	}
4372 
4373 	for (i = 0; i < size; i++) {
4374 		macArray = (macList + i)->bytes;
4375 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4376 			  "** ACL entry %i - " MAC_ADDRESS_STR, i,
4377 			  MAC_ADDR_ARRAY(macArray));
4378 	}
4379 	return;
4380 }
4381 
4382 QDF_STATUS sap_is_peer_mac_allowed(ptSapContext sapContext, uint8_t *peerMac)
4383 {
4384 	if (eSAP_ALLOW_ALL == sapContext->eSapMacAddrAclMode)
4385 		return QDF_STATUS_SUCCESS;
4386 
4387 	if (sap_search_mac_list
4388 		    (sapContext->acceptMacList, sapContext->nAcceptMac, peerMac, NULL))
4389 		return QDF_STATUS_SUCCESS;
4390 
4391 	if (sap_search_mac_list
4392 		    (sapContext->denyMacList, sapContext->nDenyMac, peerMac, NULL)) {
4393 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4394 			  "In %s, Peer " MAC_ADDRESS_STR " in deny list",
4395 			  __func__, MAC_ADDR_ARRAY(peerMac));
4396 		return QDF_STATUS_E_FAILURE;
4397 	}
4398 	/* A new station CAN associate, unless in deny list. Less stringent mode */
4399 	if (eSAP_ACCEPT_UNLESS_DENIED == sapContext->eSapMacAddrAclMode)
4400 		return QDF_STATUS_SUCCESS;
4401 
4402 	/* A new station CANNOT associate, unless in accept list. More stringent mode */
4403 	if (eSAP_DENY_UNLESS_ACCEPTED == sapContext->eSapMacAddrAclMode) {
4404 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4405 			  "In %s, Peer " MAC_ADDRESS_STR
4406 			  " denied, Mac filter mode is eSAP_DENY_UNLESS_ACCEPTED",
4407 			  __func__, MAC_ADDR_ARRAY(peerMac));
4408 		return QDF_STATUS_E_FAILURE;
4409 	}
4410 
4411 	/* The new STA is neither in accept list nor in deny list. In this case, deny the association
4412 	 * but send a wifi event notification indicating the mac address being denied
4413 	 */
4414 	if (eSAP_SUPPORT_ACCEPT_AND_DENY == sapContext->eSapMacAddrAclMode) {
4415 		sap_signal_hdd_event(sapContext, NULL, eSAP_UNKNOWN_STA_JOIN,
4416 				     (void *) peerMac);
4417 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4418 			  "In %s, Peer " MAC_ADDRESS_STR
4419 			  " denied, Mac filter mode is eSAP_SUPPORT_ACCEPT_AND_DENY",
4420 			  __func__, MAC_ADDR_ARRAY(peerMac));
4421 		return QDF_STATUS_E_FAILURE;
4422 	}
4423 	return QDF_STATUS_SUCCESS;
4424 }
4425 
4426 #ifdef SOFTAP_CHANNEL_RANGE
4427 /**
4428  * sap_get_channel_list() - get the list of channels
4429  * @sap_ctx: sap context
4430  * @ch_list: pointer to channel list array
4431  * @num_ch: pointer to number of channels.
4432  *
4433  * This function populates the list of channels for scanning.
4434  *
4435  * Return: QDF_STATUS
4436  */
4437 static QDF_STATUS sap_get_channel_list(ptSapContext sap_ctx,
4438 				       uint8_t **ch_list,
4439 				       uint8_t *num_ch)
4440 {
4441 	uint8_t loop_count;
4442 	uint8_t *list;
4443 	uint8_t ch_count;
4444 	uint8_t start_ch_num, band_start_ch;
4445 	uint8_t end_ch_num, band_end_ch;
4446 	uint32_t en_lte_coex;
4447 	tHalHandle hal = CDS_GET_HAL_CB(sap_ctx->p_cds_gctx);
4448 #ifdef FEATURE_WLAN_CH_AVOID
4449 	uint8_t i;
4450 #endif
4451 	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
4452 
4453 	if (NULL == hal) {
4454 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4455 			FL("Invalid HAL pointer from p_cds_gctx"));
4456 		*num_ch = 0;
4457 		*ch_list = NULL;
4458 		return QDF_STATUS_E_FAULT;
4459 	}
4460 
4461 	start_ch_num = sap_ctx->acs_cfg->start_ch;
4462 	end_ch_num = sap_ctx->acs_cfg->end_ch;
4463 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
4464 			FL("startChannel %d, EndChannel %d, HW:%d"),
4465 			start_ch_num, end_ch_num,
4466 			sap_ctx->acs_cfg->hw_mode);
4467 
4468 	wlansap_extend_to_acs_range(&start_ch_num, &end_ch_num,
4469 					    &band_start_ch, &band_end_ch);
4470 
4471 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
4472 			  FL("expanded startChannel %d,EndChannel %d"),
4473 			  start_ch_num, end_ch_num);
4474 
4475 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
4476 			  FL("band_start_ch %d, band_end_ch %d"),
4477 			  band_start_ch, band_end_ch);
4478 
4479 	sme_cfg_get_int(hal, WNI_CFG_ENABLE_LTE_COEX, &en_lte_coex);
4480 
4481 	/* Check if LTE coex is enabled and 2.4GHz is selected */
4482 	if (en_lte_coex && (band_start_ch == CHAN_ENUM_1) &&
4483 	    (band_end_ch == CHAN_ENUM_14)) {
4484 		/* Set 2.4GHz upper limit to channel 9 for LTE COEX */
4485 		band_end_ch = CHAN_ENUM_9;
4486 	}
4487 
4488 	/* Allocate the max number of channel supported */
4489 	list = (uint8_t *) qdf_mem_malloc(NUM_5GHZ_CHANNELS +
4490 						NUM_24GHZ_CHANNELS);
4491 	if (NULL == list) {
4492 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4493 			  FL("Unable to allocate channel list"));
4494 		*num_ch = 0;
4495 		*ch_list = NULL;
4496 		return QDF_STATUS_E_NOMEM;
4497 	}
4498 
4499 	/* Search for the Active channels in the given range */
4500 	ch_count = 0;
4501 	for (loop_count = band_start_ch; loop_count <= band_end_ch;
4502 	     loop_count++) {
4503 		/* go to next channel if rf_channel is out of range */
4504 		if ((start_ch_num > CDS_CHANNEL_NUM(loop_count)) ||
4505 		    (end_ch_num < CDS_CHANNEL_NUM(loop_count)))
4506 			continue;
4507 		/*
4508 		 * go to next channel if none of these condition pass
4509 		 * - DFS scan enabled and chan not in CHANNEL_STATE_DISABLE
4510 		 * - DFS scan disable but chan in CHANNEL_STATE_ENABLE
4511 		 */
4512 		if (!(((eSAP_TRUE == mac_ctx->scan.fEnableDFSChnlScan) &&
4513 		      CDS_CHANNEL_STATE(loop_count)) ||
4514 		    ((eSAP_FALSE == mac_ctx->scan.fEnableDFSChnlScan) &&
4515 		     (CHANNEL_STATE_ENABLE ==
4516 		      CDS_CHANNEL_STATE(loop_count)))))
4517 			continue;
4518 
4519 #ifdef FEATURE_WLAN_CH_AVOID
4520 		for (i = 0; i < NUM_CHANNELS; i++) {
4521 			if ((safe_channels[i].channelNumber ==
4522 			     CDS_CHANNEL_NUM(loop_count))) {
4523 				/* Check if channel is safe */
4524 				if (true == safe_channels[i].isSafe) {
4525 #endif
4526 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
4527 		uint8_t ch;
4528 		ch = CDS_CHANNEL_NUM(loop_count);
4529 		if ((sap_ctx->acs_cfg->skip_scan_status ==
4530 			eSAP_DO_PAR_ACS_SCAN)) {
4531 		    if ((ch >= sap_ctx->acs_cfg->skip_scan_range1_stch &&
4532 			 ch <= sap_ctx->acs_cfg->skip_scan_range1_endch) ||
4533 			(ch >= sap_ctx->acs_cfg->skip_scan_range2_stch &&
4534 			 ch <= sap_ctx->acs_cfg->skip_scan_range2_endch)) {
4535 			list[ch_count] =
4536 				CDS_CHANNEL_NUM(loop_count);
4537 			ch_count++;
4538 			QDF_TRACE(QDF_MODULE_ID_SAP,
4539 				QDF_TRACE_LEVEL_INFO,
4540 				FL("%d %d added to ACS ch range"),
4541 				ch_count, ch);
4542 		    } else {
4543 			QDF_TRACE(QDF_MODULE_ID_SAP,
4544 				QDF_TRACE_LEVEL_INFO_HIGH,
4545 				FL("%d %d skipped from ACS ch range"),
4546 				ch_count, ch);
4547 		    }
4548 		} else {
4549 			list[ch_count] =
4550 				CDS_CHANNEL_NUM(loop_count);
4551 			ch_count++;
4552 			QDF_TRACE(QDF_MODULE_ID_SAP,
4553 				QDF_TRACE_LEVEL_INFO,
4554 				FL("%d %d added to ACS ch range"),
4555 				ch_count, ch);
4556 		}
4557 #else
4558 		list[ch_count] = CDS_CHANNEL_NUM(loop_count);
4559 		ch_count++;
4560 #endif
4561 #ifdef FEATURE_WLAN_CH_AVOID
4562 				}
4563 				break;
4564 			}
4565 		}
4566 #endif
4567 	}
4568 	if (0 == ch_count) {
4569 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4570 		    FL("No active channels present for the current region"));
4571 		/*
4572 		 * LTE COEX: channel range outside the restricted 2.4GHz
4573 		 * band limits
4574 		 */
4575 		if (en_lte_coex && (start_ch_num > band_end_ch))
4576 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
4577 				FL("SAP can't be started as due to LTE COEX"));
4578 	}
4579 
4580 	/* return the channel list and number of channels to scan */
4581 	*num_ch = ch_count;
4582 	if (ch_count != 0) {
4583 		*ch_list = list;
4584 	} else {
4585 		*ch_list = NULL;
4586 		qdf_mem_free(list);
4587 	}
4588 
4589 	for (loop_count = 0; loop_count < ch_count; loop_count++) {
4590 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
4591 			FL("channel number: %d"), list[loop_count]);
4592 	}
4593 	return QDF_STATUS_SUCCESS;
4594 }
4595 #endif
4596 
4597 /*
4598  * Function for initializing list of  2.4/5 Ghz [NON-DFS/DFS]
4599  * available channels in the current regulatory domain.
4600  */
4601 static QDF_STATUS sap_get_5ghz_channel_list(ptSapContext sapContext)
4602 {
4603 	uint8_t count = 0;
4604 	int i;
4605 	struct sir_pcl_list pcl;
4606 	QDF_STATUS status;
4607 	enum channel_state ch_state;
4608 	pcl.pcl_len = 0;
4609 	if (NULL == sapContext) {
4610 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4611 			  "Invalid sapContext pointer on sap_get_channel_list");
4612 		return QDF_STATUS_E_FAULT;
4613 	}
4614 
4615 	if (sapContext->SapAllChnlList.channelList) {
4616 		qdf_mem_free(sapContext->SapAllChnlList.channelList);
4617 		sapContext->SapAllChnlList.channelList = NULL;
4618 	}
4619 
4620 	sapContext->SapAllChnlList.channelList =
4621 		(tChannelInfo *) qdf_mem_malloc(WNI_CFG_VALID_CHANNEL_LIST_LEN *
4622 						sizeof(tChannelInfo));
4623 	if (NULL == sapContext->SapAllChnlList.channelList) {
4624 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4625 			  " Memory Allocation failed sap_get_channel_list");
4626 		return QDF_STATUS_E_NOMEM;
4627 	}
4628 
4629 	status = cds_get_pcl_for_existing_conn(CDS_SAP_MODE,
4630 			pcl.pcl_list, &pcl.pcl_len,
4631 			pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list));
4632 	if (status != QDF_STATUS_SUCCESS) {
4633 		cds_err("Get PCL failed");
4634 		return status;
4635 	}
4636 	for (i = 0; i <= pcl.pcl_len; i++) {
4637 		if (CDS_IS_CHANNEL_5GHZ(pcl.pcl_list[i])) {
4638 			ch_state = cds_get_channel_state(pcl.pcl_list[i]);
4639 			if (!(ch_state == CHANNEL_STATE_ENABLE ||
4640 				ch_state == CHANNEL_STATE_DFS))
4641 				continue;
4642 			sapContext->SapAllChnlList.channelList[count].channel =
4643 				pcl.pcl_list[i];
4644 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
4645 				  "%s[%d] CHANNEL = %d", __func__, __LINE__,
4646 				  pcl.pcl_list[i]);
4647 			sapContext->SapAllChnlList.channelList[count].valid =
4648 				true;
4649 			count++;
4650 		}
4651 	}
4652 
4653 	sapContext->SapAllChnlList.numChannel = count;
4654 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
4655 		  "%s[%d] NUMBER OF CHANNELS count = %d"
4656 		  "sapContext->SapAllChnlList.numChannel = %d",
4657 		  __func__, __LINE__, count,
4658 		  sapContext->SapAllChnlList.numChannel);
4659 	return QDF_STATUS_SUCCESS;
4660 }
4661 
4662 /*
4663  * This function randomly selects the channel to switch after the detection
4664  * of radar
4665  * param sapContext - sap context
4666  * dfs_event - Dfs information from DFS
4667  * return - channel to which AP wishes to switch
4668  */
4669 uint8_t sap_indicate_radar(ptSapContext sapContext,
4670 			   tSirSmeDfsEventInd *dfs_event)
4671 {
4672 	uint8_t target_channel = 0;
4673 	tHalHandle hHal;
4674 	tpAniSirGlobal pMac;
4675 
4676 	if (NULL == sapContext || NULL == dfs_event) {
4677 		/* Invalid sap context of dfs event passed */
4678 		return 0;
4679 	}
4680 	hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx);
4681 
4682 	if (NULL == hHal) {
4683 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4684 			  "In %s invalid hHal", __func__);
4685 		return 0;
4686 	}
4687 	pMac = PMAC_STRUCT(hHal);
4688 
4689 	if (!dfs_event->dfs_radar_status) {
4690 		/*dfs status does not indicate a radar on the channel-- False Alarm */
4691 		return 0;
4692 	}
4693 
4694 	/*
4695 	 * SAP needs to generate Channel Switch IE
4696 	 * if the radar is found in the STARTED state
4697 	 */
4698 	if (eSAP_STARTED == sapContext->sapsMachine)
4699 		pMac->sap.SapDfsInfo.csaIERequired = eSAP_TRUE;
4700 
4701 	if (sapContext->csr_roamProfile.disableDFSChSwitch) {
4702 		return sapContext->channel;
4703 	}
4704 
4705 	/* set the Radar Found flag in SapDfsInfo */
4706 	pMac->sap.SapDfsInfo.sap_radar_found_status = true;
4707 
4708 	if (dfs_event->chan_list.nchannels > SIR_DFS_MAX_20M_SUB_CH) {
4709 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN,
4710 			  FL("nchannels >SIR_DFS_MAX_20M_SUB_CH so resetting"));
4711 		dfs_event->chan_list.nchannels = SIR_DFS_MAX_20M_SUB_CH;
4712 	}
4713 
4714 	sap_mark_dfs_channels(sapContext, dfs_event->chan_list.channels,
4715 			      dfs_event->chan_list.nchannels,
4716 			      cds_get_monotonic_boottime());
4717 
4718 	if (sapContext->chan_before_pre_cac) {
4719 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
4720 			FL("sapdfs: set chan before pre cac %d as target chan"),
4721 			sapContext->chan_before_pre_cac);
4722 		return sapContext->chan_before_pre_cac;
4723 	}
4724 
4725 	/*
4726 	 * (1) skip static turbo channel as it will require STA to be in
4727 	 * static turbo to work.
4728 	 * (2) skip channel which's marked with radar detction
4729 	 * (3) WAR: we allow user to config not to use any DFS channel
4730 	 * (4) When we pick a channel, skip excluded 11D channels
4731 	 * (5) Create the available channel list with the above rules
4732 	 */
4733 
4734 	target_channel = sap_random_channel_sel(sapContext);
4735 	if (0 == target_channel) {
4736 		sap_signal_hdd_event(sapContext, NULL,
4737 				     eSAP_DFS_NO_AVAILABLE_CHANNEL,
4738 				     (void *) eSAP_STATUS_SUCCESS);
4739 	}
4740 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN,
4741 		  FL("sapdfs: New selected target channel is [%d]"),
4742 		  target_channel);
4743 	return target_channel;
4744 }
4745 
4746 /*
4747  * CAC timer callback function.
4748  * Post eSAP_DFS_CHANNEL_CAC_END event to sap_fsm().
4749  */
4750 void sap_dfs_cac_timer_callback(void *data)
4751 {
4752 	ptSapContext sapContext;
4753 	tWLAN_SAPEvent sapEvent;
4754 	tHalHandle hHal = (tHalHandle) data;
4755 	tpAniSirGlobal pMac;
4756 
4757 	if (NULL == hHal) {
4758 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4759 			  "In %s invalid hHal", __func__);
4760 		return;
4761 	}
4762 	pMac = PMAC_STRUCT(hHal);
4763 	sapContext = sap_find_cac_wait_session(hHal);
4764 	if (NULL == sapContext) {
4765 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4766 			"%s: no SAP contexts in wait state", __func__);
4767 		return;
4768 	}
4769 
4770 	/*
4771 	 * SAP may not be in CAC wait state, when the timer runs out.
4772 	 * if following flag is set, then timer is in initialized state,
4773 	 * destroy timer here.
4774 	 */
4775 	if (pMac->sap.SapDfsInfo.is_dfs_cac_timer_running == true) {
4776 		qdf_mc_timer_destroy(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer);
4777 		pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = false;
4778 	}
4779 
4780 	/*
4781 	 * CAC Complete, post eSAP_DFS_CHANNEL_CAC_END to sap_fsm
4782 	 */
4783 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
4784 			"sapdfs: Sending eSAP_DFS_CHANNEL_CAC_END for target_channel = %d on sapctx[%p]",
4785 			sapContext->channel, sapContext);
4786 
4787 	sapEvent.event = eSAP_DFS_CHANNEL_CAC_END;
4788 	sapEvent.params = 0;
4789 	sapEvent.u1 = 0;
4790 	sapEvent.u2 = 0;
4791 
4792 	sap_fsm(sapContext, &sapEvent);
4793 }
4794 
4795 /*
4796  * Function to stop the DFS CAC Timer
4797  */
4798 static int sap_stop_dfs_cac_timer(ptSapContext sapContext)
4799 {
4800 	tHalHandle hHal;
4801 	tpAniSirGlobal pMac;
4802 	if (sapContext == NULL)
4803 		return 0;
4804 
4805 	hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx);
4806 	if (NULL == hHal) {
4807 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4808 			  "In %s invalid hHal", __func__);
4809 		return 0;
4810 	}
4811 	pMac = PMAC_STRUCT(hHal);
4812 
4813 	if (QDF_TIMER_STATE_RUNNING !=
4814 	    qdf_mc_timer_get_current_state(&pMac->sap.SapDfsInfo.
4815 					   sap_dfs_cac_timer)) {
4816 		return 0;
4817 	}
4818 
4819 	qdf_mc_timer_stop(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer);
4820 	pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
4821 	qdf_mc_timer_destroy(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer);
4822 
4823 	return 0;
4824 }
4825 
4826 
4827 /**
4828  * sap_is_channel_bonding_etsi_weather_channel() - check weather chan bonding.
4829  * @sap_context:                                   SAP context
4830  *
4831  * Check if the current SAP operating channel is bonded to weather radar
4832  * channel in ETSI domain.
4833  *
4834  * Return: True if bonded to weather channel in ETSI
4835  */
4836 static bool
4837 sap_is_channel_bonding_etsi_weather_channel(ptSapContext sap_context)
4838 {
4839 	if (IS_CH_BONDING_WITH_WEATHER_CH(sap_context->channel) &&
4840 	  (sap_context->ch_params.ch_width != CH_WIDTH_20MHZ))
4841 		return true;
4842 
4843 	return false;
4844 }
4845 
4846 /*
4847  * Function to start the DFS CAC Timer
4848  * when SAP is started on a DFS channel
4849  */
4850 int sap_start_dfs_cac_timer(ptSapContext sapContext)
4851 {
4852 	QDF_STATUS status;
4853 	uint32_t cacTimeOut;
4854 	tHalHandle hHal = NULL;
4855 	tpAniSirGlobal pMac = NULL;
4856 	uint8_t dfs_region;
4857 
4858 	if (sapContext == NULL) {
4859 		return 0;
4860 	}
4861 	hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx);
4862 
4863 	if (NULL == hHal) {
4864 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4865 			  "In %s invalid hHal", __func__);
4866 		return 0;
4867 	}
4868 	pMac = PMAC_STRUCT(hHal);
4869 
4870 	if (pMac->sap.SapDfsInfo.ignore_cac) {
4871 		/*
4872 		 * If User has set to ignore the CAC
4873 		 * so, continue without CAC Timer.
4874 		 */
4875 		return 2;
4876 	}
4877 	cacTimeOut = DEFAULT_CAC_TIMEOUT;
4878 
4879 	cds_get_dfs_region(&dfs_region);
4880 
4881 	if ((dfs_region == DFS_ETSI_REGION)
4882 	    && ((IS_ETSI_WEATHER_CH(sapContext->channel)) ||
4883 		(sap_is_channel_bonding_etsi_weather_channel(sapContext)))) {
4884 		cacTimeOut = ETSI_WEATHER_CH_CAC_TIMEOUT;
4885 	}
4886 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
4887 		  "sapdfs: SAP_DFS_CHANNEL_CAC_START on CH - %d, CAC TIMEOUT - %d sec",
4888 		  sapContext->channel, cacTimeOut / 1000);
4889 
4890 	qdf_mc_timer_init(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer,
4891 			  QDF_TIMER_TYPE_SW,
4892 			  sap_dfs_cac_timer_callback, (void *) hHal);
4893 
4894 	/*Start the CAC timer */
4895 	status =
4896 		qdf_mc_timer_start(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer,
4897 				   cacTimeOut);
4898 	if (status == QDF_STATUS_SUCCESS) {
4899 		pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = true;
4900 		return 1;
4901 	} else {
4902 		pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = false;
4903 		qdf_mc_timer_destroy(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer);
4904 		return 0;
4905 	}
4906 }
4907 
4908 /*
4909  * This function initializes the NOL list
4910  * parameters required to track the radar
4911  * found DFS channels in the current Reg. Domain .
4912  */
4913 QDF_STATUS sap_init_dfs_channel_nol_list(ptSapContext sapContext)
4914 {
4915 	uint8_t count = 0;
4916 	int i;
4917 	bool bFound = false;
4918 	tHalHandle hHal;
4919 	tpAniSirGlobal pMac;
4920 
4921 	if (NULL == sapContext) {
4922 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4923 			  "Invalid sapContext pointer on sap_init_dfs_channel_nol_list");
4924 		return QDF_STATUS_E_FAULT;
4925 	}
4926 	hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx);
4927 
4928 	if (NULL == hHal) {
4929 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4930 			  "In %s invalid hHal", __func__);
4931 		return QDF_STATUS_E_FAULT;
4932 	}
4933 	pMac = PMAC_STRUCT(hHal);
4934 
4935 	/* to indicate hdd to get cnss dfs nol */
4936 	if (QDF_STATUS_SUCCESS == sap_signal_hdd_event(sapContext, NULL,
4937 						       eSAP_DFS_NOL_GET,
4938 						       (void *)
4939 						       eSAP_STATUS_SUCCESS)) {
4940 		bFound = true;
4941 	}
4942 
4943 	for (i = CHAN_ENUM_36; i <= CHAN_ENUM_165; i++) {
4944 		if (CDS_CHANNEL_STATE(i) == CHANNEL_STATE_DFS) {
4945 			/* if dfs nol is not found, initialize it */
4946 			if (!bFound) {
4947 				pMac->sap.SapDfsInfo.sapDfsChannelNolList[count]
4948 				.dfs_channel_number =
4949 					CDS_CHANNEL_NUM(i);
4950 
4951 				QDF_TRACE(QDF_MODULE_ID_SAP,
4952 					  QDF_TRACE_LEVEL_INFO_LOW,
4953 					  "%s: CHANNEL = %d", __func__,
4954 					  pMac->sap.SapDfsInfo.
4955 					  sapDfsChannelNolList[count].
4956 					  dfs_channel_number);
4957 
4958 				pMac->sap.SapDfsInfo.sapDfsChannelNolList[count]
4959 				.radar_status_flag =
4960 					eSAP_DFS_CHANNEL_USABLE;
4961 				pMac->sap.SapDfsInfo.sapDfsChannelNolList[count]
4962 				.radar_found_timestamp = 0;
4963 			}
4964 			count++;
4965 		}
4966 	}
4967 
4968 	pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels = count;
4969 
4970 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
4971 		  "%s[%d] NUMBER OF DFS CHANNELS = %d",
4972 		  __func__, __LINE__,
4973 		  pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels);
4974 
4975 	return QDF_STATUS_SUCCESS;
4976 }
4977 
4978 /*
4979  * This function will calculate how many interfaces
4980  * have sap persona and returns total number of sap persona.
4981  */
4982 uint8_t sap_get_total_number_sap_intf(tHalHandle hHal)
4983 {
4984 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4985 	uint8_t intf = 0;
4986 	uint8_t intf_count = 0;
4987 
4988 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
4989 		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
4990 		    ||
4991 		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona))
4992 		    && pMac->sap.sapCtxList[intf].pSapContext != NULL) {
4993 			intf_count++;
4994 		}
4995 	}
4996 	return intf_count;
4997 }
4998 
4999 /*
5000  * This function will find the concurrent sap context apart from
5001  * passed sap context and return its channel change ready status
5002  */
5003 bool is_concurrent_sap_ready_for_channel_change(tHalHandle hHal,
5004 						ptSapContext sapContext)
5005 {
5006 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5007 	ptSapContext pSapContext;
5008 	uint8_t intf = 0;
5009 
5010 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
5011 		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
5012 		    ||
5013 		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona))
5014 		    && pMac->sap.sapCtxList[intf].pSapContext != NULL) {
5015 			pSapContext =
5016 				(ptSapContext) pMac->sap.sapCtxList[intf].
5017 				pSapContext;
5018 			if (pSapContext == sapContext) {
5019 				QDF_TRACE(QDF_MODULE_ID_SAP,
5020 					  QDF_TRACE_LEVEL_ERROR,
5021 					  FL("sapCtx matched [%p]"),
5022 					  sapContext);
5023 				continue;
5024 			} else {
5025 				QDF_TRACE(QDF_MODULE_ID_SAP,
5026 					  QDF_TRACE_LEVEL_ERROR,
5027 					  FL
5028 						  ("concurrent sapCtx[%p] didn't matche with [%p]"),
5029 					  pSapContext, sapContext);
5030 				return pSapContext->is_sap_ready_for_chnl_chng;
5031 			}
5032 		}
5033 	}
5034 	return false;
5035 }
5036