xref: /wlan-dirver/qcacld-3.0/core/sap/src/sap_fsm.c (revision dcc4c875c4d7ee989869150e11c5e5d28effafb3)
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, 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 	enum dfs_region dfs_region;
1257 
1258 	if (NULL == hal) {
1259 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1260 			  FL("hal pointer NULL"));
1261 		return 0;
1262 	}
1263 
1264 	mac_ctx = PMAC_STRUCT(hal);
1265 	if (NULL == mac_ctx) {
1266 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1267 			  FL("mac_ctx pointer NULL"));
1268 		return 0;
1269 	}
1270 
1271 	preferred_location =
1272 		mac_ctx->sap.SapDfsInfo.sap_operating_chan_preferred_location;
1273 	cds_get_dfs_region(&dfs_region);
1274 	/* loop to check ACS range or NOL channels */
1275 	num_valid_ch = sap_all_ch->numChannel;
1276 	for (i = 0; i < sap_all_ch->numChannel; i++) {
1277 		ch_id = sap_all_ch->channelList[i].channel;
1278 
1279 		/*
1280 		 * IN MKK DFS REGION CHECK IF THE FOLLOWING TWO
1281 		 * TWO RULES APPLY AND FILTER THE AVAILABLE CHANNELS
1282 		 * ACCORDINGLY.
1283 		 *
1284 		 * 1. If we are operating in Japan regulatory domain
1285 		 * Check if Japan W53 Channel operation is NOT
1286 		 * allowed and if its not allowed then mark all the
1287 		 * W53 channels as Invalid.
1288 		 *
1289 		 * 2. If we are operating in Japan regulatory domain
1290 		 * Check if channel switch between Indoor/Outdoor
1291 		 * is allowed. If it is not allowed then limit
1292 		 * the avaiable channels to Indoor or Outdoor
1293 		 * channels only based up on the SAP Channel location
1294 		 * indicated by "sap_operating_channel_location" param.
1295 		 */
1296 		if (DFS_MKK_REGION == dfs_region) {
1297 			/*
1298 			 * Check for JAPAN W53 Channel operation capability
1299 			 */
1300 			if (true == sap_dfs_is_w53_invalid(hal, ch_id)) {
1301 				QDF_TRACE(QDF_MODULE_ID_SAP,
1302 					  QDF_TRACE_LEVEL_INFO_LOW,
1303 					  FL("index:%d, Channel=%d Invalid,Japan W53 Disabled"),
1304 					  i, ch_id);
1305 				sap_all_ch->channelList[i].valid = false;
1306 				num_valid_ch--;
1307 				continue;
1308 			}
1309 
1310 			/*
1311 			 * If SAP's preferred channel location is Indoor
1312 			 * then set all the outdoor channels in the domain
1313 			 * to invalid.If the preferred channel location is
1314 			 * outdoor then set all the Indoor channels in the
1315 			 * domain to Invalid.
1316 			 */
1317 			if (false ==
1318 			    sap_dfs_is_channel_in_preferred_location(hal,
1319 								ch_id)) {
1320 				QDF_TRACE(QDF_MODULE_ID_SAP,
1321 					  QDF_TRACE_LEVEL_INFO_LOW,
1322 					  FL("CHAN=%d is invalid,preferred Channel Location %d Only"),
1323 					  ch_id, preferred_location);
1324 				sap_all_ch->channelList[i].valid = false;
1325 				num_valid_ch--;
1326 				continue;
1327 			}
1328 		}
1329 
1330 		if (cds_get_channel_state(ch_id) == CHANNEL_STATE_DFS) {
1331 			is_ch_nol = sap_dfs_is_channel_in_nol_list(sap_ctx,
1332 					ch_id, PHY_SINGLE_CHANNEL_CENTERED);
1333 			if (true == is_ch_nol) {
1334 				/*
1335 				 * Mark this channel invalid since it is still
1336 				 * in DFS Non-Occupancy-Period which is 30 mins.
1337 				 */
1338 				QDF_TRACE(QDF_MODULE_ID_SAP,
1339 					  QDF_TRACE_LEVEL_INFO_LOW,
1340 					  FL("index: %d, Channel = %d Present in NOL LIST"),
1341 					  i, ch_id);
1342 				sap_all_ch->channelList[i].valid = false;
1343 				num_valid_ch--;
1344 				continue;
1345 			}
1346 		}
1347 
1348 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
1349 		/* avoid ch on which another MDM AP in MCC mode is detected */
1350 		if (mac_ctx->sap.sap_channel_avoidance
1351 		    && sap_ctx->sap_detected_avoid_ch_ie.present) {
1352 			if (sap_check_in_avoid_ch_list(sap_ctx, ch_id)) {
1353 				QDF_TRACE(QDF_MODULE_ID_SAP,
1354 					  QDF_TRACE_LEVEL_INFO_LOW,
1355 					  FL("index: %d, Channel = %d, avoided due to presence of another AP+AP MCC device in same channel."),
1356 					  i, ch_id);
1357 				sap_all_ch->channelList[i].valid = false;
1358 			}
1359 		}
1360 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
1361 
1362 		/* check if the channel is within ACS channel range */
1363 		is_out_of_range = sap_acs_channel_check(sap_ctx, ch_id);
1364 		if (true == is_out_of_range) {
1365 			/*
1366 			 * mark this channel invalid since it is out of ACS
1367 			 * channel range
1368 			 */
1369 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1370 				  FL("index: %d, Channel = %d out of ACS channel range"),
1371 				  i, ch_id);
1372 			sap_all_ch->channelList[i].valid = false;
1373 			num_valid_ch--;
1374 			continue;
1375 		}
1376 	} /* end of check for NOL or ACS channels */
1377 	return num_valid_ch;
1378 }
1379 
1380 /**
1381  * select_rand_from_lst() - selects random channel from given list
1382  * @mac_ctx: mac context pointer
1383  * @ch_lst: channel list
1384  * @num_ch: number of channels
1385  *
1386  * Return: new target channel randomly selected
1387  */
1388 static uint8_t select_rand_from_lst(tpAniSirGlobal mac_ctx, uint8_t *ch_lst,
1389 				    uint8_t num_ch)
1390 {
1391 	uint32_t rand_byte = 0;
1392 	uint8_t i, target_channel, non_dfs_num_ch = 0, dfs_num_ch = 0;
1393 	uint8_t dfs_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
1394 	uint8_t non_dfs_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
1395 	if (num_ch) {
1396 		for (i = 0; i < num_ch; i++) {
1397 			if (CDS_IS_DFS_CH(ch_lst[i]))
1398 				dfs_ch[dfs_num_ch++] = ch_lst[i];
1399 			else
1400 				non_dfs_ch[non_dfs_num_ch++] = ch_lst[i];
1401 		}
1402 	} else {
1403 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1404 			  FL("No target channel found"));
1405 		return 0;
1406 	}
1407 
1408 	cds_rand_get_bytes(0, (uint8_t *)&rand_byte, 1);
1409 
1410 	/* Give preference to non-DFS channel */
1411 	if (!mac_ctx->f_prefer_non_dfs_on_radar) {
1412 		i = (rand_byte + qdf_mc_timer_get_system_ticks()) % num_ch;
1413 		target_channel = ch_lst[i];
1414 	} else if (non_dfs_num_ch) {
1415 		i = (rand_byte + qdf_mc_timer_get_system_ticks()) %
1416 							non_dfs_num_ch;
1417 		target_channel = non_dfs_ch[i];
1418 	} else {
1419 		i = (rand_byte + qdf_mc_timer_get_system_ticks()) % dfs_num_ch;
1420 		target_channel = dfs_ch[i];
1421 	}
1422 
1423 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1424 		  FL("sapdfs: New Channel width = %d"),
1425 		  mac_ctx->sap.SapDfsInfo.new_chanWidth);
1426 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1427 		  FL("sapdfs: target_channel = %d"), target_channel);
1428 
1429 	return target_channel;
1430 }
1431 
1432 /**
1433  * sap_find_ch_wh_fallback() - find given channel width from given list of
1434  * channels
1435  * @mac_ctx: mac context pointer
1436  * @ch_wd: channel width to find
1437  * @ch_lst: list of channels
1438  * @num_ch: number of channels
1439  *
1440  * This function tries to find given channel width and returns new target ch.
1441  * If not found updates ch_wd to next lower channel width.
1442  *
1443  * Return: new target channel if successful, 0 otherwise
1444  */
1445 static uint8_t sap_find_ch_wh_fallback(tpAniSirGlobal mac_ctx,
1446 				       enum phy_ch_width *ch_wd,
1447 				       uint8_t *ch_lst,
1448 				       uint8_t num_ch)
1449 {
1450 	bool flag = false;
1451 	uint32_t rand_byte = 0;
1452 	chan_bonding_bitmap ch_map = { { {0} } };
1453 	uint8_t count = 0, i, index = 0, final_cnt = 0, target_channel = 0;
1454 	uint8_t primary_seg_start_ch = 0, sec_seg_ch = 0, new_160_start_ch = 0;
1455 	uint8_t final_lst[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
1456 
1457 	/* initialize ch_map for all 80 MHz bands: we have 6 80MHz bands */
1458 	ch_map.chanBondingSet[0].startChannel = 36;
1459 	ch_map.chanBondingSet[1].startChannel = 52;
1460 	ch_map.chanBondingSet[2].startChannel = 100;
1461 	ch_map.chanBondingSet[3].startChannel = 116;
1462 	ch_map.chanBondingSet[4].startChannel = 132;
1463 	ch_map.chanBondingSet[5].startChannel = 149;
1464 
1465 	/* now loop through leakage free list */
1466 	for (i = 0; i < num_ch; i++) {
1467 		/* add tmp ch to bitmap */
1468 		if (ch_lst[i] == 0)
1469 			continue;
1470 
1471 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
1472 			  FL("sapdfs: Channel=%d added to bitmap"),
1473 			  ch_lst[i]);
1474 		sap_set_bitmap(&ch_map, ch_lst[i]);
1475 	}
1476 
1477 	/* populate available channel list from bitmap */
1478 	final_cnt = sap_populate_available_channels(&ch_map, *ch_wd, final_lst);
1479 	/* If no valid ch bonding found, fallback */
1480 	if (final_cnt == 0) {
1481 		if ((*ch_wd == CH_WIDTH_160MHZ) ||
1482 			(*ch_wd == CH_WIDTH_80P80MHZ) ||
1483 			(*ch_wd == CH_WIDTH_80MHZ)) {
1484 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN,
1485 				  FL("sapdfs:Changing chanWidth from [%d] to 40Mhz"),
1486 				  *ch_wd);
1487 			*ch_wd = CH_WIDTH_40MHZ;
1488 		} else if (*ch_wd == CH_WIDTH_40MHZ) {
1489 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN,
1490 				  FL("sapdfs:No 40MHz cb found, falling to 20MHz"));
1491 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN,
1492 				  FL("sapdfs:Changing chanWidth from [%d] to [%d]"),
1493 				  *ch_wd, CH_WIDTH_20MHZ);
1494 			*ch_wd = CH_WIDTH_20MHZ;
1495 		}
1496 		return 0;
1497 	}
1498 
1499 	/* ch count should be > 8 to switch new channel in 160Mhz band */
1500 	if (((*ch_wd == CH_WIDTH_160MHZ) || (*ch_wd == CH_WIDTH_80P80MHZ)) &&
1501 			(final_cnt < SIR_DFS_MAX_20M_SUB_CH)) {
1502 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN,
1503 			FL("sapdfs:Changing chanWidth from [%d] to [%d]"),
1504 			*ch_wd, CH_WIDTH_80MHZ);
1505 		*ch_wd = CH_WIDTH_80MHZ;
1506 		return 0;
1507 	}
1508 	if (*ch_wd == CH_WIDTH_160MHZ) {
1509 		/*
1510 		 * NA supports only 2 blocks for 160Mhz bandwidth i.e 36-64 &
1511 		 * 100-128 and all the channels in these blocks are continuous
1512 		 * and seperated by 4Mhz.
1513 		 */
1514 		for (i = 1; ((i < final_cnt)); i++) {
1515 			if ((final_lst[i] - final_lst[i-1]) == 4)
1516 				count++;
1517 			else
1518 				count = 0;
1519 			if (count == SIR_DFS_MAX_20M_SUB_CH - 1) {
1520 				flag = true;
1521 				new_160_start_ch = final_lst[i-7];
1522 				break;
1523 			}
1524 		}
1525 	} else if (*ch_wd == CH_WIDTH_80P80MHZ) {
1526 		flag = true;
1527 	}
1528 	if ((flag == false) && (*ch_wd > CH_WIDTH_80MHZ)) {
1529 		*ch_wd = CH_WIDTH_80MHZ;
1530 		return 0;
1531 	}
1532 
1533 	if (*ch_wd == CH_WIDTH_160MHZ) {
1534 		cds_rand_get_bytes(0, (uint8_t *)&rand_byte, 1);
1535 		rand_byte = (rand_byte + qdf_mc_timer_get_system_ticks())
1536 				% SIR_DFS_MAX_20M_SUB_CH;
1537 		target_channel = new_160_start_ch + (rand_byte * 4);
1538 	} else if (*ch_wd == CH_WIDTH_80P80MHZ) {
1539 		cds_rand_get_bytes(0, (uint8_t *)&rand_byte, 1);
1540 		index = (rand_byte + qdf_mc_timer_get_system_ticks()) %
1541 			final_cnt;
1542 		target_channel = final_lst[index];
1543 		index -= (index % 4);
1544 		primary_seg_start_ch = final_lst[index];
1545 
1546 		/* reset channels associate with primary 80Mhz */
1547 		for (i = 0; i < 4; i++)
1548 			final_lst[i + index] = 0;
1549 		/* select and calculate center freq for secondary segement */
1550 		for (i = 0; i < final_cnt / 4; i++) {
1551 			if (final_lst[i * 4] &&
1552 			    (abs(primary_seg_start_ch - final_lst[i * 4]) >
1553 				(SIR_DFS_MAX_20M_SUB_CH * 2))) {
1554 				sec_seg_ch = final_lst[i * 4] +
1555 				SIR_80MHZ_START_CENTER_CH_DIFF;
1556 				break;
1557 			}
1558 		}
1559 		if (!sec_seg_ch && (final_cnt == SIR_DFS_MAX_20M_SUB_CH))
1560 			*ch_wd = CH_WIDTH_160MHZ;
1561 		else if (!sec_seg_ch)
1562 			*ch_wd = CH_WIDTH_80MHZ;
1563 
1564 		mac_ctx->sap.SapDfsInfo.new_ch_params.center_freq_seg1
1565 								= sec_seg_ch;
1566 
1567 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1568 			FL("sapdfs: New Center Freq Seg1 = %d"), sec_seg_ch);
1569 	} else {
1570 		target_channel = select_rand_from_lst(mac_ctx, final_lst,
1571 						      final_cnt);
1572 	}
1573 	return target_channel;
1574 }
1575 
1576 /**
1577  * sap_random_channel_sel() - This function randomly pick up an available
1578  * channel
1579  * @sap_ctx:        sap context.
1580  *
1581  * This function first eliminates invalid channel, then selects random channel
1582  * using following algorithm:
1583  * PASS: 1 - invalidate ch in sap_ctx->all_ch_lst as per rules
1584  * PASS: 2 - now mark channels that will leak into NOL
1585  * PASS: 3 - from leakage_adjusted_lst, either select random channel (for 20MHz)
1586  *           or find given channel width possible. if not found fallback to
1587  *           lower channel width and try again. once given channel width found
1588  *           use random channel from give possibilities.
1589  * Return: channel number picked
1590  */
1591 static uint8_t sap_random_channel_sel(ptSapContext sap_ctx)
1592 {
1593 	uint8_t j = 0, i = 0, final_cnt = 0, target_channel = 0;
1594 	/* count and ch list after applying all rules */
1595 	uint8_t rule_adjusted_cnt, *rule_adjusted_lst;
1596 	/* ch list after invalidating channels leaking into NOL */
1597 	uint8_t *leakage_adjusted_lst;
1598 	/* final list of channel from which random channel will be selected */
1599 	uint8_t final_lst[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
1600 	tAll5GChannelList *all_ch = &sap_ctx->SapAllChnlList;
1601 	tHalHandle hal = CDS_GET_HAL_CB(sap_ctx->p_cds_gctx);
1602 	tpAniSirGlobal mac_ctx;
1603 	/* channel width for current iteration */
1604 	enum phy_ch_width ch_wd;
1605 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION
1606 	tSapDfsNolInfo *nol;
1607 #endif
1608 
1609 	if (NULL == hal) {
1610 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1611 			  FL("invalid hal"));
1612 		return 0;
1613 	}
1614 
1615 	mac_ctx = PMAC_STRUCT(hal);
1616 	if (NULL == mac_ctx) {
1617 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1618 			  FL("invalid mac_ctx"));
1619 		return 0;
1620 	}
1621 
1622 	/*
1623 	 * Retrieve the original one and store it.
1624 	 * use the stored original value when you call this function next time
1625 	 * so fall back mechanism always starts with original ini value.
1626 	 */
1627 	if (mac_ctx->sap.SapDfsInfo.orig_chanWidth == 0) {
1628 		ch_wd = sap_ctx->ch_width_orig;
1629 		mac_ctx->sap.SapDfsInfo.orig_chanWidth = ch_wd;
1630 	} else {
1631 		ch_wd = mac_ctx->sap.SapDfsInfo.orig_chanWidth;
1632 	}
1633 
1634 	if (sap_get_5ghz_channel_list(sap_ctx)) {
1635 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1636 			  FL("Getting 5Ghz channel list failed"));
1637 		return 0;
1638 	}
1639 
1640 	/* PASS: 1 - invalidate ch in sap_ctx->all_ch_lst as per rules */
1641 	rule_adjusted_cnt = sap_apply_rules(sap_ctx);
1642 	if (0 == rule_adjusted_cnt) {
1643 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1644 			  FL("No channels left after applying rules."));
1645 		return 0;
1646 	}
1647 
1648 	/* this is list we get after applying all rules */
1649 	rule_adjusted_lst = qdf_mem_malloc(rule_adjusted_cnt);
1650 
1651 	/* list adjusted after leakage has been marked */
1652 	leakage_adjusted_lst = qdf_mem_malloc(rule_adjusted_cnt);
1653 	if (rule_adjusted_lst == NULL || leakage_adjusted_lst == NULL) {
1654 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1655 				  FL("sapdfs: memory alloc failed"));
1656 		qdf_mem_free(rule_adjusted_lst);
1657 		qdf_mem_free(leakage_adjusted_lst);
1658 		return 0;
1659 	}
1660 
1661 	/* copy valid ch from sap_ctx->all_ch_lst into rule_adjusted_lst */
1662 	for (i = 0, j = 0; i < all_ch->numChannel; i++) {
1663 		if (!all_ch->channelList[i].valid)
1664 			continue;
1665 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1666 			  FL("sapdfs: Adding Channel = %d to temp List"),
1667 			  all_ch->channelList[i].channel);
1668 		rule_adjusted_lst[j++] = all_ch->channelList[i].channel;
1669 	}
1670 
1671 	/*
1672 	 * do - while loop for fallback mechanism. at each channel width this
1673 	 * will try to find channel bonding, if not fall back to lower ch width
1674 	 */
1675 	do {
1676 		/* save rules adjusted lst */
1677 		qdf_mem_copy(leakage_adjusted_lst, rule_adjusted_lst,
1678 			     rule_adjusted_cnt);
1679 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION
1680 		nol = mac_ctx->sap.SapDfsInfo.sapDfsChannelNolList;
1681 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1682 			  FL("sapdfs: Processing tmp ch list against NOL."));
1683 		/* PASS: 2 - now mark channels that will leak into NOL */
1684 		if (sap_mark_leaking_ch(sap_ctx, ch_wd, nol, rule_adjusted_cnt,
1685 				leakage_adjusted_lst) != QDF_STATUS_SUCCESS) {
1686 			qdf_mem_free(rule_adjusted_lst);
1687 			qdf_mem_free(leakage_adjusted_lst);
1688 			return 0;
1689 		}
1690 #endif
1691 		if (ch_wd == CH_WIDTH_20MHZ) {
1692 			/*
1693 			 * PASS: 3 - from leakage_adjusted_lst, prepare valid
1694 			 * ch list and use random number from that
1695 			 */
1696 			for (i = 0; i < rule_adjusted_cnt; i++) {
1697 				if (leakage_adjusted_lst[i] == 0)
1698 					continue;
1699 				QDF_TRACE(QDF_MODULE_ID_SAP,
1700 					  QDF_TRACE_LEVEL_DEBUG,
1701 					  FL("sapdfs: Channel=%d added to available list"),
1702 					  leakage_adjusted_lst[i]);
1703 				final_lst[final_cnt] = leakage_adjusted_lst[i];
1704 				final_cnt++;
1705 			}
1706 			target_channel = select_rand_from_lst(mac_ctx,
1707 							final_lst, final_cnt);
1708 			break;
1709 		}
1710 
1711 		/*
1712 		 * PASS: 3 - following function will check from valid channels
1713 		 * left if given ch_wd can be supported. if not reduce ch_wd
1714 		 * (fallback), then continue with reduced ch_wd
1715 		 */
1716 		target_channel = sap_find_ch_wh_fallback(mac_ctx, &ch_wd,
1717 							   leakage_adjusted_lst,
1718 							   rule_adjusted_cnt);
1719 		/*
1720 		 * if target channel is 0, no channel bonding was found
1721 		 * ch_wd would have been updated for fallback
1722 		 */
1723 		if (0 == target_channel)
1724 			continue;
1725 		else
1726 			break;
1727 	} while (true);
1728 
1729 	if (target_channel)
1730 		mac_ctx->sap.SapDfsInfo.new_chanWidth = ch_wd;
1731 
1732 	qdf_mem_free(rule_adjusted_lst);
1733 	qdf_mem_free(leakage_adjusted_lst);
1734 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1735 		FL("sapdfs: New Channel width = %d"),
1736 		mac_ctx->sap.SapDfsInfo.new_chanWidth);
1737 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1738 		FL("sapdfs: target_channel = %d"),
1739 		target_channel);
1740 	return target_channel;
1741 }
1742 
1743 bool sap_acs_channel_check(ptSapContext sapContext, uint8_t channelNumber)
1744 {
1745 	int i = 0;
1746 	if (!sapContext->acs_cfg->acs_mode)
1747 		return false;
1748 
1749 	if ((channelNumber >= sapContext->acs_cfg->start_ch) &&
1750 		(channelNumber <= sapContext->acs_cfg->end_ch)) {
1751 		if (!sapContext->acs_cfg->ch_list) {
1752 			return false;
1753 		} else {
1754 			for (i = 0; i < sapContext->acs_cfg->ch_list_count; i++)
1755 				if (channelNumber ==
1756 						sapContext->acs_cfg->ch_list[i])
1757 					return false;
1758 		}
1759 	}
1760 	return true;
1761 }
1762 
1763 /**
1764  * sap_mark_dfs_channels() - to mark dfs channel
1765  * @sapContext: pointer sap context
1766  * @channels: list of channels
1767  * @numChannels: number of channels
1768  * @time: time
1769  *
1770  * Mark the channels in NOL with time and eSAP_DFS_CHANNEL_UNAVAILABLE
1771  *
1772  * Return: none
1773  */
1774 void sap_mark_dfs_channels(ptSapContext sapContext, uint8_t *channels,
1775 			   uint8_t numChannels, uint64_t time)
1776 {
1777 	int i, j;
1778 	tSapDfsNolInfo *psapDfsChannelNolList = NULL;
1779 	uint8_t nRegDomainDfsChannels;
1780 	tHalHandle hHal;
1781 	tpAniSirGlobal pMac;
1782 
1783 	hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx);
1784 	if (NULL == channels)
1785 		return;
1786 	if (NULL == hHal) {
1787 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1788 			  FL("invalid hHal"));
1789 		return;
1790 	}
1791 	pMac = PMAC_STRUCT(hHal);
1792 	if (NULL == pMac) {
1793 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1794 			  FL("invalid pMac"));
1795 		return;
1796 	}
1797 
1798 	/*
1799 	 * Mark the current channel on which Radar is found
1800 	 * in the NOL list as eSAP_DFS_CHANNEL_UNAVAILABLE.
1801 	 */
1802 	psapDfsChannelNolList = pMac->sap.SapDfsInfo.sapDfsChannelNolList;
1803 	nRegDomainDfsChannels =
1804 		pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels;
1805 
1806 	for (i = 0; i < numChannels; i++) {
1807 		for (j = 0; j <= nRegDomainDfsChannels; j++) {
1808 			if (!(psapDfsChannelNolList[j].dfs_channel_number ==
1809 					channels[i]))
1810 				continue;
1811 			/*
1812 			 * If channel is already in NOL, don't update it again.
1813 			 * This is useful when marking bonding channels which
1814 			 * are already unavailable.
1815 			 */
1816 			if (psapDfsChannelNolList[j].radar_status_flag ==
1817 					eSAP_DFS_CHANNEL_UNAVAILABLE) {
1818 				QDF_TRACE(QDF_MODULE_ID_SAP,
1819 						QDF_TRACE_LEVEL_INFO_HIGH,
1820 						FL("Channel=%d already in NOL"),
1821 						channels[i]);
1822 				continue;
1823 			}
1824 			/*
1825 			 * Capture the Radar Found timestamp on the
1826 			 * Current Channel in ms.
1827 			 */
1828 			psapDfsChannelNolList[j].radar_found_timestamp = time;
1829 			/* Mark the Channel to be unavailble for next 30 mins */
1830 			psapDfsChannelNolList[j].radar_status_flag =
1831 				eSAP_DFS_CHANNEL_UNAVAILABLE;
1832 
1833 			QDF_TRACE(QDF_MODULE_ID_SAP,
1834 				QDF_TRACE_LEVEL_INFO_HIGH,
1835 				FL("Channel=%d Added to NOL LIST"),
1836 				channels[i]);
1837 		}
1838 	}
1839 }
1840 
1841 /*
1842  * This Function is to get bonding channels from primary channel.
1843  *
1844  */
1845 uint8_t sap_get_bonding_channels(ptSapContext sapContext, uint8_t channel,
1846 				 uint8_t *channels, uint8_t size,
1847 				 ePhyChanBondState chanBondState)
1848 {
1849 	tHalHandle hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx);
1850 	tpAniSirGlobal pMac;
1851 	uint8_t numChannel;
1852 
1853 	if (channels == NULL)
1854 		return 0;
1855 
1856 	if (size < MAX_BONDED_CHANNELS)
1857 		return 0;
1858 
1859 	if (NULL != hHal) {
1860 		pMac = PMAC_STRUCT(hHal);
1861 	} else
1862 		return 0;
1863 
1864 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
1865 		  FL("cbmode: %d, channel: %d"), chanBondState, channel);
1866 
1867 	switch (chanBondState) {
1868 	case PHY_SINGLE_CHANNEL_CENTERED:
1869 		numChannel = 1;
1870 		channels[0] = channel;
1871 		break;
1872 	case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
1873 		numChannel = 2;
1874 		channels[0] = channel - 4;
1875 		channels[1] = channel;
1876 		break;
1877 	case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
1878 		numChannel = 2;
1879 		channels[0] = channel;
1880 		channels[1] = channel + 4;
1881 		break;
1882 	case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
1883 		numChannel = 4;
1884 		channels[0] = channel;
1885 		channels[1] = channel + 4;
1886 		channels[2] = channel + 8;
1887 		channels[3] = channel + 12;
1888 		break;
1889 	case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
1890 		numChannel = 4;
1891 		channels[0] = channel - 4;
1892 		channels[1] = channel;
1893 		channels[2] = channel + 4;
1894 		channels[3] = channel + 8;
1895 		break;
1896 	case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
1897 		numChannel = 4;
1898 		channels[0] = channel - 8;
1899 		channels[1] = channel - 4;
1900 		channels[2] = channel;
1901 		channels[3] = channel + 4;
1902 		break;
1903 	case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
1904 		numChannel = 4;
1905 		channels[0] = channel - 12;
1906 		channels[1] = channel - 8;
1907 		channels[2] = channel - 4;
1908 		channels[3] = channel;
1909 		break;
1910 	default:
1911 		numChannel = 1;
1912 		channels[0] = channel;
1913 		break;
1914 	}
1915 
1916 	return numChannel;
1917 }
1918 
1919 /**
1920  * sap_dfs_check_if_channel_avaialable() - Check if a channel is out of NOL
1921  * @nol: Pointer to the Non-Occupancy List.
1922  *
1923  * This function Checks if a given channel is available or
1924  * usable or unavailable based on the time lapse since the
1925  * last radar time stamp.
1926  *
1927  * Return: true if channel available or usable, false if unavailable.
1928  */
1929 static bool sap_dfs_check_if_channel_avaialable(tSapDfsNolInfo *nol)
1930 {
1931 	uint64_t time_since_last_radar, time_when_radar_found, current_time = 0;
1932 	uint64_t max_jiffies;
1933 
1934 	if ((nol->radar_status_flag == eSAP_DFS_CHANNEL_USABLE) ||
1935 	    (nol->radar_status_flag == eSAP_DFS_CHANNEL_AVAILABLE)) {
1936 		/*
1937 		 * Allow SAP operation on this channel
1938 		 * either the DFS channel has not been used
1939 		 * for SAP operation or it is available for
1940 		 * SAP operation since it is past
1941 		 * Non-Occupancy-Period so, return false.
1942 		 */
1943 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1944 			  FL("Chan=%d not in NOL,CHAN AVAILABLE"),
1945 			  nol->dfs_channel_number);
1946 		return true;
1947 	} else if (nol->radar_status_flag == eSAP_DFS_CHANNEL_UNAVAILABLE) {
1948 		/*
1949 		 * If a DFS Channel is UNAVAILABLE then
1950 		 * check to see if it is past
1951 		 * Non-occupancy-period
1952 		 * of 30 minutes. If it is past 30 mins then
1953 		 * mark the channel as AVAILABLE and return
1954 		 * false as the channel is not anymore in
1955 		 * NON-Occupancy-Period.
1956 		 */
1957 		time_when_radar_found = nol->radar_found_timestamp;
1958 		current_time = cds_get_monotonic_boottime();
1959 		if (current_time < time_when_radar_found) {
1960 			/* cds_get_monotonic_boottime() can overflow.
1961 			 * Jiffies is initialized such that 32 bit jiffies
1962 			 * value wrap 5 minutes after boot so jiffies wrap bugs
1963 			 * show up earlier
1964 			 */
1965 			max_jiffies = (uint64_t)UINT_MAX * 1000;
1966 			time_since_last_radar = (max_jiffies -
1967 				time_when_radar_found) + (current_time);
1968 		} else {
1969 			time_since_last_radar = current_time -
1970 							time_when_radar_found;
1971 		}
1972 		if (time_since_last_radar >= SAP_DFS_NON_OCCUPANCY_PERIOD) {
1973 			nol->radar_status_flag = eSAP_DFS_CHANNEL_AVAILABLE;
1974 			nol->radar_found_timestamp = 0;
1975 
1976 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1977 				  FL("Chan=%d not in NOL, Channel AVAILABLE"),
1978 				  nol->dfs_channel_number);
1979 			return true;
1980 		} else {
1981 			/*
1982 			 * Channel is not still available for
1983 			 * SAP operation so return true; As the
1984 			 * Channel is still in
1985 			 * Non-occupancy-Period.
1986 			 */
1987 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
1988 				  FL("Chan=%d in NOL, Channel UNAVAILBLE"),
1989 				  nol->dfs_channel_number);
1990 			return false;
1991 		}
1992 	} else {
1993 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
1994 			  FL("Invalid Radar Status Flag"));
1995 	}
1996 	return true;
1997 }
1998 
1999 /**
2000  * sap_dfs_is_channel_in_nol_list() - given bonded channel is available
2001  * @sap_context: Handle to SAP context.
2002  * @channel_number: Channel on which availability should be checked.
2003  * @chan_bondState: The channel bonding mode of the passed channel.
2004  *
2005  * This function Checks if a given bonded channel is available or
2006  * usable for DFS operation.
2007  *
2008  * Return: false if channel is available, true if channel is in NOL.
2009  */
2010 bool
2011 sap_dfs_is_channel_in_nol_list(ptSapContext sap_context,
2012 			       uint8_t channel_number,
2013 			       ePhyChanBondState chan_bondState)
2014 {
2015 	int i, j;
2016 	tHalHandle h_hal = CDS_GET_HAL_CB(sap_context->p_cds_gctx);
2017 	tpAniSirGlobal mac_ctx;
2018 	uint8_t channels[MAX_BONDED_CHANNELS];
2019 	uint8_t num_channels;
2020 	tSapDfsNolInfo *nol;
2021 	tSapDfsInfo *dfs_info;
2022 	bool channel_available;
2023 
2024 	if (NULL == h_hal) {
2025 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2026 			  FL("invalid h_hal"));
2027 		return false;
2028 	} else {
2029 		mac_ctx = PMAC_STRUCT(h_hal);
2030 	}
2031 
2032 	dfs_info = &mac_ctx->sap.SapDfsInfo;
2033 	if ((dfs_info->numCurrentRegDomainDfsChannels == 0) ||
2034 	    (dfs_info->numCurrentRegDomainDfsChannels >
2035 	     NUM_5GHZ_CHANNELS)) {
2036 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
2037 			  FL("invalid dfs channel count %d"),
2038 			  dfs_info->numCurrentRegDomainDfsChannels);
2039 		return false;
2040 	}
2041 
2042 	/* get the bonded channels */
2043 	num_channels = sap_get_bonding_channels(sap_context, channel_number,
2044 				channels, MAX_BONDED_CHANNELS, chan_bondState);
2045 
2046 	/* check for NOL, first on will break the loop */
2047 	for (j = 0; j < num_channels; j++) {
2048 		for (i = 0; i < dfs_info->numCurrentRegDomainDfsChannels; i++) {
2049 			nol = &dfs_info->sapDfsChannelNolList[i];
2050 			if (nol->dfs_channel_number != channels[j])
2051 				continue;
2052 
2053 			channel_available =
2054 				sap_dfs_check_if_channel_avaialable(nol);
2055 
2056 			if (channel_available == false)
2057 				break;
2058 
2059 		} /* loop for dfs channels */
2060 
2061 		if (i < dfs_info->numCurrentRegDomainDfsChannels)
2062 			break;
2063 
2064 	} /* loop for bonded channels */
2065 
2066 	/*
2067 	 * if any of the channel is not available, mark all available channels
2068 	 * as unavailable with same time stamp.
2069 	 */
2070 	if (j < num_channels &&
2071 	    i < dfs_info->numCurrentRegDomainDfsChannels) {
2072 		if (num_channels > MAX_BONDED_CHANNELS) {
2073 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN,
2074 				  FL("num_channel>MAX_BONDED_CHANNEL, reset"));
2075 			num_channels = MAX_BONDED_CHANNELS;
2076 		}
2077 		nol = &dfs_info->sapDfsChannelNolList[i];
2078 		sap_mark_dfs_channels(sap_context, channels, num_channels,
2079 				nol->radar_found_timestamp);
2080 
2081 		/* set DFS-NOL back to keep it update-to-date in CNSS */
2082 		sap_signal_hdd_event(sap_context, NULL, eSAP_DFS_NOL_SET,
2083 				  (void *) eSAP_STATUS_SUCCESS);
2084 
2085 		return true;
2086 	}
2087 
2088 	return false;
2089 }
2090 
2091 /**
2092  * sap_goto_channel_sel - Function for initiating scan request for SME
2093  * @sap_context: Sap Context value.
2094  * @sap_event: State machine event
2095  * @sap_do_acs_pre_start_bss: true, if ACS scan is issued pre start BSS
2096  *                            false, if ACS scan is issued post start BSS.
2097  * @check_for_connection_update: true, check and wait for connection update
2098  *                               false, do not perform connection update
2099  *
2100  * Initiates sme scan for ACS to pick a channel.
2101  *
2102  * Return: The QDF_STATUS code associated with performing the operation.
2103  */
2104 QDF_STATUS sap_goto_channel_sel(ptSapContext sap_context,
2105 	ptWLAN_SAPEvent sap_event,
2106 	bool sap_do_acs_pre_start_bss,
2107 	bool check_for_connection_update)
2108 {
2109 
2110 	/* Initiate a SCAN request */
2111 	QDF_STATUS qdf_ret_status;
2112 	/* To be initialised if scan is required */
2113 	tCsrScanRequest scan_request;
2114 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
2115 	tpAniSirGlobal mac_ctx;
2116 
2117 #ifdef SOFTAP_CHANNEL_RANGE
2118 	uint8_t *channel_list = NULL;
2119 	uint8_t num_of_channels = 0;
2120 #endif
2121 	tHalHandle h_hal;
2122 	uint8_t con_ch;
2123 
2124 	h_hal = cds_get_context(QDF_MODULE_ID_SME);
2125 	if (NULL == h_hal) {
2126 		/* we have a serious problem */
2127 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
2128 			  FL("invalid h_hal"));
2129 		return QDF_STATUS_E_FAULT;
2130 	}
2131 
2132 	mac_ctx = PMAC_STRUCT(h_hal);
2133 	if (NULL == mac_ctx) {
2134 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2135 				FL("Invalid MAC context"));
2136 		return QDF_STATUS_E_FAILURE;
2137 	}
2138 
2139 	if (cds_concurrent_beaconing_sessions_running()) {
2140 		con_ch =
2141 			sme_get_concurrent_operation_channel(h_hal);
2142 #ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE
2143 		if (con_ch && sap_context->channel == AUTO_CHANNEL_SELECT) {
2144 			sap_context->dfs_ch_disable = true;
2145 		} else if (con_ch && sap_context->channel != con_ch &&
2146 			   CDS_IS_DFS_CH(sap_context->channel)) {
2147 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN,
2148 				  FL("MCC DFS not supported in AP_AP Mode"));
2149 			return QDF_STATUS_E_ABORTED;
2150 		}
2151 #endif
2152 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
2153 		if (sap_context->cc_switch_mode !=
2154 						QDF_MCC_TO_SCC_SWITCH_DISABLE) {
2155 			con_ch = sme_check_concurrent_channel_overlap(h_hal,
2156 					sap_context->channel,
2157 					sap_context->csr_roamProfile.phyMode,
2158 					sap_context->cc_switch_mode);
2159 			if (con_ch) {
2160 				QDF_TRACE(QDF_MODULE_ID_SAP,
2161 					QDF_TRACE_LEVEL_ERROR,
2162 					"%s: Override ch %d to %d due to CC Intf",
2163 					__func__, sap_context->channel, con_ch);
2164 				sap_context->channel = con_ch;
2165 				cds_set_channel_params(sap_context->channel, 0,
2166 						&sap_context->ch_params);
2167 			}
2168 		}
2169 #endif
2170 	}
2171 
2172 	if (cds_get_concurrency_mode() == (QDF_STA_MASK | QDF_SAP_MASK)) {
2173 #ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE
2174 		if (sap_context->channel == AUTO_CHANNEL_SELECT)
2175 			sap_context->dfs_ch_disable = true;
2176 		else if (CDS_IS_DFS_CH(sap_context->channel)) {
2177 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN,
2178 				  FL("DFS not supported in STA_AP Mode"));
2179 			return QDF_STATUS_E_ABORTED;
2180 		}
2181 #endif
2182 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
2183 		if (sap_context->cc_switch_mode !=
2184 						QDF_MCC_TO_SCC_SWITCH_DISABLE) {
2185 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
2186 				FL("check for overlap: chan:%d mode:%d"),
2187 				sap_context->channel,
2188 				sap_context->csr_roamProfile.phyMode);
2189 			con_ch = sme_check_concurrent_channel_overlap(h_hal,
2190 					sap_context->channel,
2191 					sap_context->csr_roamProfile.phyMode,
2192 					sap_context->cc_switch_mode);
2193 			if (con_ch && !CDS_IS_DFS_CH(con_ch)) {
2194 				QDF_TRACE(QDF_MODULE_ID_SAP,
2195 					QDF_TRACE_LEVEL_ERROR,
2196 					"%s: Override ch %d to %d due to CC Intf",
2197 					__func__, sap_context->channel, con_ch);
2198 				sap_context->channel = con_ch;
2199 				cds_set_channel_params(sap_context->channel, 0,
2200 						&sap_context->ch_params);
2201 			}
2202 		}
2203 #endif
2204 	}
2205 
2206 	if (sap_context->channel == AUTO_CHANNEL_SELECT) {
2207 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
2208 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2209 			  FL("%s skip_acs_status = %d "), __func__,
2210 			  sap_context->acs_cfg->skip_scan_status);
2211 		if (sap_context->acs_cfg->skip_scan_status !=
2212 						eSAP_SKIP_ACS_SCAN) {
2213 #endif
2214 		qdf_mem_zero(&scan_request, sizeof(scan_request));
2215 
2216 		/*
2217 		 * Set scanType to Active scan. FW takes care of using passive
2218 		 * scan for DFS and active for non DFS channels.
2219 		 */
2220 		scan_request.scanType = eSIR_ACTIVE_SCAN;
2221 
2222 		/* Set min and max channel time to zero */
2223 		scan_request.minChnTime = 0;
2224 		scan_request.maxChnTime = 0;
2225 
2226 		/* Set BSSType to default type */
2227 		scan_request.BSSType = eCSR_BSS_TYPE_ANY;
2228 
2229 #ifndef SOFTAP_CHANNEL_RANGE
2230 		/*Scan all the channels */
2231 		scan_request.ChannelInfo.num_of_channels = 0;
2232 
2233 		scan_request.ChannelInfo.ChannelList = NULL;
2234 
2235 		scan_request.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
2236 		/* eCSR_SCAN_REQUEST_11D_SCAN; */
2237 
2238 #else
2239 
2240 		sap_get_channel_list(sap_context, &channel_list,
2241 				  &num_of_channels);
2242 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
2243 		if (num_of_channels != 0) {
2244 #endif
2245 		/*Scan the channels in the list */
2246 		scan_request.ChannelInfo.numOfChannels =
2247 			num_of_channels;
2248 
2249 		scan_request.ChannelInfo.ChannelList =
2250 			channel_list;
2251 
2252 		scan_request.requestType =
2253 			eCSR_SCAN_SOFTAP_CHANNEL_RANGE;
2254 
2255 		sap_context->channelList = channel_list;
2256 
2257 #endif
2258 		/* Set requestType to Full scan */
2259 
2260 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2261 			  FL("calling sme_scan_request"));
2262 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
2263 		if (sap_context->acs_cfg->skip_scan_status ==
2264 			eSAP_DO_NEW_ACS_SCAN)
2265 #endif
2266 			sme_scan_flush_result(h_hal);
2267 		if (true == sap_do_acs_pre_start_bss) {
2268 			/*
2269 			 * when ID == 0 11D scan/active scan with callback,
2270 			 * min-maxChntime set in csrScanRequest()?
2271 			 * csrScanCompleteCallback callback
2272 			 * pContext scan_request_id filled up
2273 			 */
2274 			qdf_ret_status = sme_scan_request(h_hal,
2275 				sap_context->sessionId,
2276 				&scan_request,
2277 				&wlansap_pre_start_bss_acs_scan_callback,
2278 				sap_context);
2279 		} else {
2280 			/*
2281 			 * when ID == 0 11D scan/active scan with callback,
2282 			 * min-maxChntime set in csrScanRequest()?
2283 			 * csrScanCompleteCallback callback,
2284 			 * pContext scan_request_id filled up
2285 			 */
2286 			qdf_ret_status = sme_scan_request(h_hal,
2287 				sap_context->sessionId,
2288 				&scan_request,
2289 				&wlansap_scan_callback,
2290 				sap_context);
2291 		}
2292 		if (QDF_STATUS_SUCCESS != qdf_ret_status) {
2293 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2294 				  FL("sme_scan_request  fail %d!!!"),
2295 				  qdf_ret_status);
2296 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2297 				  FL("SAP Configuring default channel, Ch=%d"),
2298 				  sap_context->channel);
2299 			/* In case of error, switch to default channel */
2300 			sap_context->channel = SAP_DEFAULT_24GHZ_CHANNEL;
2301 
2302 #ifdef SOFTAP_CHANNEL_RANGE
2303 			if (sap_context->channelList != NULL) {
2304 				sap_context->channel =
2305 					sap_context->channelList[0];
2306 				qdf_mem_free(sap_context->
2307 					channelList);
2308 				sap_context->channelList = NULL;
2309 			}
2310 #endif
2311 			if (true == sap_do_acs_pre_start_bss) {
2312 				/*
2313 				* In case of ACS req before start Bss,
2314 				* return failure so that the calling
2315 				* fucntion can use the default channel.
2316 				*/
2317 				return QDF_STATUS_E_FAILURE;
2318 			} else {
2319 				/* Fill in the event structure */
2320 				sap_event_init(sap_event);
2321 				/* Handle event */
2322 				qdf_status = sap_fsm(sap_context, sap_event);
2323 			}
2324 		} else {
2325 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2326 				 FL("return sme_ScanReq, scanID=%d, Ch=%d"),
2327 				 scan_request.scan_id, sap_context->channel);
2328 		}
2329 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
2330 		}
2331 	} else {
2332 		sap_context->acs_cfg->skip_scan_status = eSAP_SKIP_ACS_SCAN;
2333 	}
2334 
2335 	if (sap_context->acs_cfg->skip_scan_status == eSAP_SKIP_ACS_SCAN) {
2336 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2337 			  FL("## %s SKIPPED ACS SCAN"), __func__);
2338 		wlansap_scan_callback(h_hal, sap_context,
2339 			sap_context->sessionId, 0, eCSR_SCAN_SUCCESS);
2340 	}
2341 #endif
2342 	} else {
2343 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2344 			  FL("for configured channel, Ch= %d"),
2345 			  sap_context->channel);
2346 
2347 		if (check_for_connection_update) {
2348 			/* This wait happens in the hostapd context. The event
2349 			 * is set in the MC thread context.
2350 			 */
2351 			qdf_status = cds_update_and_wait_for_connection_update(
2352 					sap_context->sessionId,
2353 					sap_context->channel,
2354 					SIR_UPDATE_REASON_START_AP);
2355 			if (QDF_IS_STATUS_ERROR(qdf_status))
2356 				return qdf_status;
2357 		}
2358 
2359 		if (sap_do_acs_pre_start_bss == true) {
2360 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
2361 				FL("ACS end due to Ch override. Sel Ch = %d"),
2362 							sap_context->channel);
2363 			sap_context->acs_cfg->pri_ch = sap_context->channel;
2364 			sap_context->acs_cfg->ch_width =
2365 						 sap_context->ch_width_orig;
2366 			sap_config_acs_result(h_hal, sap_context, 0);
2367 			return QDF_STATUS_E_CANCELED;
2368 		} else {
2369 			/*
2370 			 * Fill in the event structure
2371 			 * Eventhough scan was not done,
2372 			 * means a user set channel was chosen
2373 			 */
2374 			sap_event_init(sap_event);
2375 			/* Handle event */
2376 			qdf_status = sap_fsm(sap_context, sap_event);
2377 		}
2378 	}
2379 
2380 	/*
2381 	 * If scan failed, get default channel and advance state
2382 	 * machine as success with default channel
2383 	 *
2384 	 * Have to wait for the call back to be called to get the
2385 	 * channel cannot advance state machine here as said above
2386 	 */
2387 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2388 		  FL("before exiting sap_goto_channel_sel channel=%d"),
2389 		  sap_context->channel);
2390 
2391 	return QDF_STATUS_SUCCESS;
2392 }
2393 
2394 /**
2395  * sap_open_session() - Opens a SAP session
2396  * @hHal: Hal handle
2397  * @sapContext:  Sap Context value
2398  * @session_id: Pointer to the session id
2399  *
2400  * Function for opening SME and SAP sessions when system is in SoftAP role
2401  *
2402  * Return: QDF_STATUS
2403  */
2404 
2405 #define SAP_OPEN_SESSION_TIMEOUT 2000
2406 QDF_STATUS sap_open_session(tHalHandle hHal, ptSapContext sapContext,
2407 			    uint32_t *session_id)
2408 {
2409 	uint32_t type, subType;
2410 	QDF_STATUS qdf_ret_status;
2411 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
2412 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
2413 
2414 	if (sapContext->csr_roamProfile.csrPersona == QDF_P2P_GO_MODE)
2415 		status = cds_get_vdev_types(QDF_P2P_GO_MODE, &type, &subType);
2416 	else
2417 		status = cds_get_vdev_types(QDF_SAP_MODE, &type, &subType);
2418 
2419 	if (QDF_STATUS_SUCCESS != status) {
2420 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
2421 			  "failed to get vdev type");
2422 		return QDF_STATUS_E_FAILURE;
2423 	}
2424 
2425 	qdf_event_reset(&sapContext->sap_session_opened_evt);
2426 	/* Open SME Session for Softap */
2427 	qdf_ret_status = sme_open_session(hHal,
2428 					  &wlansap_roam_callback,
2429 					  sapContext,
2430 					  sapContext->self_mac_addr,
2431 					  &sapContext->sessionId, type, subType);
2432 
2433 	if (QDF_STATUS_SUCCESS != qdf_ret_status) {
2434 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2435 			  "Error: In %s calling sme_roam_connect status = %d",
2436 			  __func__, qdf_ret_status);
2437 
2438 		return QDF_STATUS_E_FAILURE;
2439 	}
2440 
2441 	status = qdf_wait_single_event(&sapContext->sap_session_opened_evt,
2442 				       SAP_OPEN_SESSION_TIMEOUT);
2443 
2444 	if (!QDF_IS_STATUS_SUCCESS(status)) {
2445 		cds_err("wait for sap open session event timed out");
2446 		return QDF_STATUS_E_FAILURE;
2447 	}
2448 
2449 	pMac->sap.sapCtxList[sapContext->sessionId].sessionID =
2450 		sapContext->sessionId;
2451 	pMac->sap.sapCtxList[sapContext->sessionId].pSapContext = sapContext;
2452 	pMac->sap.sapCtxList[sapContext->sessionId].sapPersona =
2453 		sapContext->csr_roamProfile.csrPersona;
2454 	*session_id = sapContext->sessionId;
2455 	sapContext->isSapSessionOpen = eSAP_TRUE;
2456 	sapContext->is_pre_cac_on = false;
2457 	sapContext->pre_cac_complete = false;
2458 	sapContext->chan_before_pre_cac = 0;
2459 	return QDF_STATUS_SUCCESS;
2460 }
2461 
2462 /*==========================================================================
2463    FUNCTION    sapGotoStarting
2464 
2465    DESCRIPTION
2466     Function for initiating start bss request for SME
2467 
2468    DEPENDENCIES
2469     NA.
2470 
2471    PARAMETERS
2472 
2473     IN
2474     sapContext  : Sap Context value
2475     sapEvent    : State machine event
2476     bssType     : Type of bss to start, INRA AP
2477     status      : Return the SAP status here
2478 
2479    RETURN VALUE
2480     The QDF_STATUS code associated with performing the operation
2481 
2482     QDF_STATUS_SUCCESS: Success
2483 
2484    SIDE EFFECTS
2485    ============================================================================*/
2486 QDF_STATUS sap_goto_starting(ptSapContext sapContext, ptWLAN_SAPEvent sapEvent,
2487 			     eCsrRoamBssType bssType)
2488 {
2489 	/* tHalHandle */
2490 	tHalHandle hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx);
2491 	QDF_STATUS qdf_ret_status;
2492 
2493 	/*- - - - - - - - TODO:once configs from hdd available - - - - - - - - -*/
2494 	char key_material[32] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3,
2495 		4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, };
2496 	sapContext->key_type = 0x05;
2497 	sapContext->key_length = 32;
2498 	/* Need a key size define */
2499 	qdf_mem_copy(sapContext->key_material, key_material,
2500 		     sizeof(key_material));
2501 
2502 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, "In %s",
2503 		  __func__);
2504 
2505 	if (NULL == hHal) {
2506 		/* we have a serious problem */
2507 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
2508 			  "In %s, invalid hHal", __func__);
2509 		return QDF_STATUS_E_FAULT;
2510 	}
2511 
2512 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, "%s: session: %d",
2513 		  __func__, sapContext->sessionId);
2514 
2515 	qdf_ret_status = sme_roam_connect(hHal, sapContext->sessionId,
2516 					  &sapContext->csr_roamProfile,
2517 					  &sapContext->csr_roamId);
2518 	if (QDF_STATUS_SUCCESS != qdf_ret_status)
2519 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2520 			"%s: Failed to issue sme_roam_connect", __func__);
2521 
2522 	return qdf_ret_status;
2523 } /* sapGotoStarting */
2524 
2525 /*==========================================================================
2526    FUNCTION    sapGotoDisconnecting
2527 
2528    DESCRIPTION
2529     Processing of SAP FSM Disconnecting state
2530 
2531    DEPENDENCIES
2532     NA.
2533 
2534    PARAMETERS
2535 
2536     IN
2537     sapContext  : Sap Context value
2538     status      : Return the SAP status here
2539 
2540    RETURN VALUE
2541     The QDF_STATUS code associated with performing the operation
2542 
2543     QDF_STATUS_SUCCESS: Success
2544 
2545    SIDE EFFECTS
2546    ============================================================================*/
2547 QDF_STATUS sap_goto_disconnecting(ptSapContext sapContext)
2548 {
2549 	QDF_STATUS qdf_ret_status;
2550 	tHalHandle hHal;
2551 
2552 	hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx);
2553 	if (NULL == hHal) {
2554 		/* we have a serious problem */
2555 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2556 			  "In %s, invalid hHal", __func__);
2557 		return QDF_STATUS_E_FAULT;
2558 	}
2559 
2560 	sap_free_roam_profile(&sapContext->csr_roamProfile);
2561 	qdf_ret_status = sme_roam_stop_bss(hHal, sapContext->sessionId);
2562 	if (QDF_STATUS_SUCCESS != qdf_ret_status) {
2563 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2564 			  "Error: In %s calling sme_roam_stop_bss status = %d",
2565 			  __func__, qdf_ret_status);
2566 		return QDF_STATUS_E_FAILURE;
2567 	}
2568 
2569 	return QDF_STATUS_SUCCESS;
2570 }
2571 
2572 static QDF_STATUS sap_roam_session_close_callback(void *pContext)
2573 {
2574 	ptSapContext sapContext = (ptSapContext) pContext;
2575 	return sap_signal_hdd_event(sapContext, NULL,
2576 				 eSAP_STOP_BSS_EVENT,
2577 				 (void *) eSAP_STATUS_SUCCESS);
2578 }
2579 
2580 /*==========================================================================
2581    FUNCTION    sapGotoDisconnected
2582 
2583    DESCRIPTION
2584     Function for setting the SAP FSM to Disconnection state
2585 
2586    DEPENDENCIES
2587     NA.
2588 
2589    PARAMETERS
2590 
2591     IN
2592     sapContext  : Sap Context value
2593     sapEvent    : State machine event
2594     status      : Return the SAP status here
2595 
2596    RETURN VALUE
2597     The QDF_STATUS code associated with performing the operation
2598 
2599     QDF_STATUS_SUCCESS: Success
2600 
2601    SIDE EFFECTS
2602    ============================================================================*/
2603 QDF_STATUS sap_goto_disconnected(ptSapContext sapContext)
2604 {
2605 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
2606 	tWLAN_SAPEvent sapEvent;
2607 	/* Processing has to be coded */
2608 	/* Clean up stations from TL etc as AP BSS is shut down then set event */
2609 	sapEvent.event = eSAP_MAC_READY_FOR_CONNECTIONS;        /* hardcoded */
2610 	sapEvent.params = 0;
2611 	sapEvent.u1 = 0;
2612 	sapEvent.u2 = 0;
2613 	/* Handle event */
2614 	qdf_status = sap_fsm(sapContext, &sapEvent);
2615 
2616 	return qdf_status;
2617 }
2618 
2619 /**
2620  * sap_signal_hdd_event() - send event notification
2621  * @sap_ctx: Sap Context
2622  * @csr_roaminfo: Pointer to CSR roam information
2623  * @sap_hddevent: SAP HDD event
2624  * @context: to pass the element for future support
2625  *
2626  * Function for HDD to send the event notification using callback
2627  *
2628  * Return: QDF_STATUS
2629  */
2630 QDF_STATUS sap_signal_hdd_event(ptSapContext sap_ctx,
2631 		tCsrRoamInfo *csr_roaminfo, eSapHddEvent sap_hddevent,
2632 		void *context)
2633 {
2634 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
2635 	tSap_Event sap_ap_event;       /* This now encodes ALL event types */
2636 	tHalHandle hal = CDS_GET_HAL_CB(sap_ctx->p_cds_gctx);
2637 	tpAniSirGlobal mac_ctx;
2638 	tSirSmeChanInfo *chaninfo;
2639 	tSap_StationAssocIndication *assoc_ind;
2640 	tSap_StartBssCompleteEvent *bss_complete;
2641 	struct sap_ch_selected_s *acs_selected;
2642 	tSap_StationAssocReassocCompleteEvent *reassoc_complete;
2643 	tSap_StationDisassocCompleteEvent *disassoc_comp;
2644 	tSap_StationSetKeyCompleteEvent *key_complete;
2645 	tSap_StationMICFailureEvent *mic_failure;
2646 
2647 	/* Format the Start BSS Complete event to return... */
2648 	if (NULL == sap_ctx->pfnSapEventCallback) {
2649 		QDF_ASSERT(0);
2650 		return QDF_STATUS_E_FAILURE;
2651 	}
2652 	if (NULL == hal) {
2653 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2654 			  FL("Invalid hal"));
2655 		return QDF_STATUS_E_FAILURE;
2656 	}
2657 	mac_ctx = PMAC_STRUCT(hal);
2658 	if (NULL == mac_ctx) {
2659 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2660 			  FL("Invalid MAC context"));
2661 		return QDF_STATUS_E_FAILURE;
2662 	}
2663 
2664 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2665 		  FL("SAP event callback event = %s"),
2666 		  sap_hdd_event_to_string(sap_hddevent));
2667 
2668 	switch (sap_hddevent) {
2669 	case eSAP_STA_ASSOC_IND:
2670 		/*  TODO - Indicate the assoc request indication to OS */
2671 		sap_ap_event.sapHddEventCode = eSAP_STA_ASSOC_IND;
2672 		assoc_ind = &sap_ap_event.sapevt.sapAssocIndication;
2673 
2674 		qdf_copy_macaddr(&assoc_ind->staMac, &csr_roaminfo->peerMac);
2675 		assoc_ind->staId = csr_roaminfo->staId;
2676 		assoc_ind->status = 0;
2677 		/* Required for indicating the frames to upper layer */
2678 		assoc_ind->beaconLength = csr_roaminfo->beaconLength;
2679 		assoc_ind->beaconPtr = csr_roaminfo->beaconPtr;
2680 		assoc_ind->assocReqLength = csr_roaminfo->assocReqLength;
2681 		assoc_ind->assocReqPtr = csr_roaminfo->assocReqPtr;
2682 		assoc_ind->fWmmEnabled = csr_roaminfo->wmmEnabledSta;
2683 		if (csr_roaminfo->u.pConnectedProfile != NULL) {
2684 			assoc_ind->negotiatedAuthType =
2685 				csr_roaminfo->u.pConnectedProfile->AuthType;
2686 			assoc_ind->negotiatedUCEncryptionType =
2687 			    csr_roaminfo->u.pConnectedProfile->EncryptionType;
2688 			assoc_ind->negotiatedMCEncryptionType =
2689 			    csr_roaminfo->u.pConnectedProfile->mcEncryptionType;
2690 			assoc_ind->fAuthRequired = csr_roaminfo->fAuthRequired;
2691 		}
2692 		break;
2693 	case eSAP_START_BSS_EVENT:
2694 		sap_ap_event.sapHddEventCode = eSAP_START_BSS_EVENT;
2695 		bss_complete = &sap_ap_event.sapevt.sapStartBssCompleteEvent;
2696 
2697 		bss_complete->status = (eSapStatus) context;
2698 		if (csr_roaminfo != NULL)
2699 			bss_complete->staId = csr_roaminfo->staId;
2700 		else
2701 			bss_complete->staId = 0;
2702 
2703 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2704 			  FL("(eSAP_START_BSS_EVENT): staId = %d"),
2705 			  bss_complete->staId);
2706 
2707 		bss_complete->operatingChannel = (uint8_t) sap_ctx->channel;
2708 		bss_complete->sessionId = sap_ctx->sessionId;
2709 		break;
2710 	case eSAP_DFS_CAC_START:
2711 	case eSAP_DFS_CAC_INTERRUPTED:
2712 	case eSAP_DFS_CAC_END:
2713 	case eSAP_DFS_PRE_CAC_END:
2714 	case eSAP_DFS_RADAR_DETECT:
2715 	case eSAP_DFS_RADAR_DETECT_DURING_PRE_CAC:
2716 	case eSAP_DFS_NO_AVAILABLE_CHANNEL:
2717 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
2718 	case eSAP_ACS_SCAN_SUCCESS_EVENT:
2719 #endif
2720 		sap_ap_event.sapHddEventCode = sap_hddevent;
2721 		sap_ap_event.sapevt.sapStopBssCompleteEvent.status =
2722 			(eSapStatus) context;
2723 		break;
2724 
2725 	case eSAP_ACS_CHANNEL_SELECTED:
2726 		sap_ap_event.sapHddEventCode = sap_hddevent;
2727 		acs_selected = &sap_ap_event.sapevt.sap_ch_selected;
2728 		if (eSAP_STATUS_SUCCESS == (eSapStatus)context) {
2729 			acs_selected->pri_ch = sap_ctx->acs_cfg->pri_ch;
2730 			acs_selected->ht_sec_ch = sap_ctx->acs_cfg->ht_sec_ch;
2731 			acs_selected->ch_width = sap_ctx->acs_cfg->ch_width;
2732 			acs_selected->vht_seg0_center_ch =
2733 				sap_ctx->acs_cfg->vht_seg0_center_ch;
2734 			acs_selected->vht_seg1_center_ch =
2735 				sap_ctx->acs_cfg->vht_seg1_center_ch;
2736 		} else if (eSAP_STATUS_FAILURE == (eSapStatus)context) {
2737 			acs_selected->pri_ch = 0;
2738 		}
2739 		break;
2740 
2741 	case eSAP_STOP_BSS_EVENT:
2742 		sap_ap_event.sapHddEventCode = eSAP_STOP_BSS_EVENT;
2743 		sap_ap_event.sapevt.sapStopBssCompleteEvent.status =
2744 			(eSapStatus) context;
2745 		break;
2746 
2747 	case eSAP_STA_ASSOC_EVENT:
2748 	case eSAP_STA_REASSOC_EVENT:
2749 		reassoc_complete =
2750 		    &sap_ap_event.sapevt.sapStationAssocReassocCompleteEvent;
2751 
2752 		if (csr_roaminfo->fReassocReq)
2753 			sap_ap_event.sapHddEventCode = eSAP_STA_REASSOC_EVENT;
2754 		else
2755 			sap_ap_event.sapHddEventCode = eSAP_STA_ASSOC_EVENT;
2756 
2757 		qdf_copy_macaddr(&reassoc_complete->staMac,
2758 				 &csr_roaminfo->peerMac);
2759 		reassoc_complete->staId = csr_roaminfo->staId;
2760 		reassoc_complete->statusCode = csr_roaminfo->statusCode;
2761 		reassoc_complete->iesLen = csr_roaminfo->rsnIELen;
2762 		qdf_mem_copy(reassoc_complete->ies, csr_roaminfo->prsnIE,
2763 			     csr_roaminfo->rsnIELen);
2764 
2765 #ifdef FEATURE_WLAN_WAPI
2766 		if (csr_roaminfo->wapiIELen) {
2767 			uint8_t len = reassoc_complete->iesLen;
2768 			reassoc_complete->iesLen += csr_roaminfo->wapiIELen;
2769 			qdf_mem_copy(&reassoc_complete->ies[len],
2770 				     csr_roaminfo->pwapiIE,
2771 				     csr_roaminfo->wapiIELen);
2772 		}
2773 #endif
2774 		if (csr_roaminfo->addIELen) {
2775 			uint8_t len = reassoc_complete->iesLen;
2776 			reassoc_complete->iesLen += csr_roaminfo->addIELen;
2777 			qdf_mem_copy(&reassoc_complete->ies[len],
2778 				     csr_roaminfo->paddIE,
2779 				     csr_roaminfo->addIELen);
2780 		}
2781 
2782 		/* also fill up the channel info from the csr_roamInfo */
2783 		chaninfo = &reassoc_complete->chan_info;
2784 
2785 		chaninfo->chan_id = csr_roaminfo->chan_info.chan_id;
2786 		chaninfo->mhz = csr_roaminfo->chan_info.mhz;
2787 		chaninfo->info = csr_roaminfo->chan_info.info;
2788 		chaninfo->band_center_freq1 =
2789 			csr_roaminfo->chan_info.band_center_freq1;
2790 		chaninfo->band_center_freq2 =
2791 			csr_roaminfo->chan_info.band_center_freq2;
2792 		chaninfo->reg_info_1 =
2793 			csr_roaminfo->chan_info.reg_info_1;
2794 		chaninfo->reg_info_2 =
2795 			csr_roaminfo->chan_info.reg_info_2;
2796 		chaninfo->nss = csr_roaminfo->chan_info.nss;
2797 		chaninfo->rate_flags = csr_roaminfo->chan_info.rate_flags;
2798 
2799 		reassoc_complete->wmmEnabled = csr_roaminfo->wmmEnabledSta;
2800 		reassoc_complete->status = (eSapStatus) context;
2801 		reassoc_complete->timingMeasCap = csr_roaminfo->timingMeasCap;
2802 		break;
2803 
2804 	case eSAP_STA_DISASSOC_EVENT:
2805 		sap_ap_event.sapHddEventCode = eSAP_STA_DISASSOC_EVENT;
2806 		disassoc_comp =
2807 			&sap_ap_event.sapevt.sapStationDisassocCompleteEvent;
2808 
2809 		qdf_copy_macaddr(&disassoc_comp->staMac,
2810 				 &csr_roaminfo->peerMac);
2811 		disassoc_comp->staId = csr_roaminfo->staId;
2812 		if (csr_roaminfo->reasonCode == eCSR_ROAM_RESULT_FORCED)
2813 			disassoc_comp->reason = eSAP_USR_INITATED_DISASSOC;
2814 		else
2815 			disassoc_comp->reason = eSAP_MAC_INITATED_DISASSOC;
2816 
2817 		disassoc_comp->statusCode = csr_roaminfo->statusCode;
2818 		disassoc_comp->status = (eSapStatus) context;
2819 		break;
2820 
2821 	case eSAP_STA_SET_KEY_EVENT:
2822 		sap_ap_event.sapHddEventCode = eSAP_STA_SET_KEY_EVENT;
2823 		key_complete =
2824 			&sap_ap_event.sapevt.sapStationSetKeyCompleteEvent;
2825 		key_complete->status = (eSapStatus) context;
2826 		qdf_copy_macaddr(&key_complete->peerMacAddr,
2827 				 &csr_roaminfo->peerMac);
2828 		break;
2829 
2830 	case eSAP_STA_MIC_FAILURE_EVENT:
2831 		sap_ap_event.sapHddEventCode = eSAP_STA_MIC_FAILURE_EVENT;
2832 		mic_failure = &sap_ap_event.sapevt.sapStationMICFailureEvent;
2833 
2834 		qdf_mem_copy(&mic_failure->srcMacAddr,
2835 			     csr_roaminfo->u.pMICFailureInfo->srcMacAddr,
2836 			     sizeof(tSirMacAddr));
2837 		qdf_mem_copy(&mic_failure->staMac.bytes,
2838 			     csr_roaminfo->u.pMICFailureInfo->taMacAddr,
2839 			     sizeof(tSirMacAddr));
2840 		qdf_mem_copy(&mic_failure->dstMacAddr.bytes,
2841 			     csr_roaminfo->u.pMICFailureInfo->dstMacAddr,
2842 			     sizeof(tSirMacAddr));
2843 		mic_failure->multicast =
2844 			csr_roaminfo->u.pMICFailureInfo->multicast;
2845 		mic_failure->IV1 = csr_roaminfo->u.pMICFailureInfo->IV1;
2846 		mic_failure->keyId = csr_roaminfo->u.pMICFailureInfo->keyId;
2847 		qdf_mem_copy(mic_failure->TSC,
2848 			     csr_roaminfo->u.pMICFailureInfo->TSC,
2849 			     SIR_CIPHER_SEQ_CTR_SIZE);
2850 		break;
2851 
2852 	case eSAP_ASSOC_STA_CALLBACK_EVENT:
2853 		break;
2854 
2855 	case eSAP_WPS_PBC_PROBE_REQ_EVENT:
2856 		sap_ap_event.sapHddEventCode = eSAP_WPS_PBC_PROBE_REQ_EVENT;
2857 
2858 		qdf_mem_copy(&sap_ap_event.sapevt.sapPBCProbeReqEvent.
2859 			     WPSPBCProbeReq, csr_roaminfo->u.pWPSPBCProbeReq,
2860 			     sizeof(tSirWPSPBCProbeReq));
2861 		break;
2862 
2863 	case eSAP_REMAIN_CHAN_READY:
2864 		sap_ap_event.sapHddEventCode = eSAP_REMAIN_CHAN_READY;
2865 		sap_ap_event.sapevt.sap_roc_ind.scan_id =
2866 				sap_ctx->roc_ind_scan_id;
2867 		break;
2868 	case eSAP_SEND_ACTION_CNF:
2869 		sap_ap_event.sapHddEventCode = eSAP_SEND_ACTION_CNF;
2870 		sap_ap_event.sapevt.sapActionCnf.actionSendSuccess =
2871 			(eSapStatus) context;
2872 		break;
2873 
2874 	case eSAP_DISCONNECT_ALL_P2P_CLIENT:
2875 		sap_ap_event.sapHddEventCode = eSAP_DISCONNECT_ALL_P2P_CLIENT;
2876 		sap_ap_event.sapevt.sapActionCnf.actionSendSuccess =
2877 			(eSapStatus) context;
2878 		break;
2879 
2880 	case eSAP_MAC_TRIG_STOP_BSS_EVENT:
2881 		sap_ap_event.sapHddEventCode = eSAP_MAC_TRIG_STOP_BSS_EVENT;
2882 		sap_ap_event.sapevt.sapActionCnf.actionSendSuccess =
2883 			(eSapStatus) context;
2884 		break;
2885 
2886 	case eSAP_UNKNOWN_STA_JOIN:
2887 		sap_ap_event.sapHddEventCode = eSAP_UNKNOWN_STA_JOIN;
2888 		qdf_mem_copy((void *) sap_ap_event.sapevt.sapUnknownSTAJoin.
2889 			     macaddr.bytes, (void *) context,
2890 			     QDF_MAC_ADDR_SIZE);
2891 		break;
2892 
2893 	case eSAP_MAX_ASSOC_EXCEEDED:
2894 		sap_ap_event.sapHddEventCode = eSAP_MAX_ASSOC_EXCEEDED;
2895 		qdf_copy_macaddr(&sap_ap_event.sapevt.
2896 				 sapMaxAssocExceeded.macaddr,
2897 				 &csr_roaminfo->peerMac);
2898 		break;
2899 
2900 	case eSAP_CHANNEL_CHANGE_EVENT:
2901 		/*
2902 		 * Reconfig ACS result info. For DFS AP-AP Mode Sec AP ACS
2903 		 * follows pri AP
2904 		 */
2905 		sap_ctx->acs_cfg->pri_ch = sap_ctx->channel;
2906 		sap_ctx->acs_cfg->ch_width =
2907 				sap_ctx->csr_roamProfile.ch_params.ch_width;
2908 		sap_config_acs_result(hal, sap_ctx,
2909 			sap_ctx->csr_roamProfile.ch_params.sec_ch_offset);
2910 
2911 		sap_ap_event.sapHddEventCode = eSAP_CHANNEL_CHANGE_EVENT;
2912 
2913 		acs_selected = &sap_ap_event.sapevt.sap_ch_selected;
2914 		acs_selected->pri_ch = sap_ctx->acs_cfg->pri_ch;
2915 		acs_selected->ht_sec_ch =
2916 			sap_ctx->csr_roamProfile.ch_params.sec_ch_offset;
2917 		acs_selected->ch_width =
2918 			sap_ctx->csr_roamProfile.ch_params.ch_width;
2919 		acs_selected->vht_seg0_center_ch =
2920 			sap_ctx->csr_roamProfile.ch_params.center_freq_seg0;
2921 		acs_selected->vht_seg1_center_ch =
2922 			sap_ctx->csr_roamProfile.ch_params.center_freq_seg1;
2923 		break;
2924 
2925 	case eSAP_DFS_NOL_GET:
2926 		sap_ap_event.sapHddEventCode = eSAP_DFS_NOL_GET;
2927 		sap_ap_event.sapevt.sapDfsNolInfo.sDfsList =
2928 			NUM_5GHZ_CHANNELS * sizeof(tSapDfsNolInfo);
2929 		sap_ap_event.sapevt.sapDfsNolInfo.pDfsList = (void *)
2930 			(&mac_ctx->sap.SapDfsInfo.sapDfsChannelNolList[0]);
2931 		break;
2932 
2933 	case eSAP_DFS_NOL_SET:
2934 		sap_ap_event.sapHddEventCode = eSAP_DFS_NOL_SET;
2935 		sap_ap_event.sapevt.sapDfsNolInfo.sDfsList =
2936 			mac_ctx->sap.SapDfsInfo.numCurrentRegDomainDfsChannels *
2937 			sizeof(tSapDfsNolInfo);
2938 		sap_ap_event.sapevt.sapDfsNolInfo.pDfsList = (void *)
2939 			(&mac_ctx->sap.SapDfsInfo.sapDfsChannelNolList[0]);
2940 		break;
2941 	case eSAP_ECSA_CHANGE_CHAN_IND:
2942 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
2943 				"In %s, SAP event callback event = %s",
2944 				__func__, "eSAP_ECSA_CHANGE_CHAN_IND");
2945 		sap_ap_event.sapHddEventCode = eSAP_ECSA_CHANGE_CHAN_IND;
2946 		sap_ap_event.sapevt.sap_chan_cng_ind.new_chan =
2947 					   csr_roaminfo->target_channel;
2948 		break;
2949 	default:
2950 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
2951 			  FL("SAP Unknown callback event = %d"),
2952 			  sap_hddevent);
2953 		break;
2954 	}
2955 	qdf_status = (*sap_ctx->pfnSapEventCallback)
2956 			(&sap_ap_event, sap_ctx->pUsrContext);
2957 
2958 	return qdf_status;
2959 
2960 }
2961 
2962 /*==========================================================================
2963    FUNCTION  sap_find_valid_concurrent_session
2964 
2965    DESCRIPTION
2966     This function will return sapcontext of any valid sap session.
2967 
2968    PARAMETERS
2969 
2970     IN
2971     hHal        : HAL pointer
2972 
2973    RETURN VALUE
2974     ptSapContext : valid sap context
2975 
2976    SIDE EFFECTS
2977     NA
2978    ============================================================================*/
2979 ptSapContext sap_find_valid_concurrent_session(tHalHandle hHal)
2980 {
2981 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
2982 	uint8_t intf = 0;
2983 
2984 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
2985 		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
2986 		    ||
2987 		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona)) &&
2988 		    pMac->sap.sapCtxList[intf].pSapContext != NULL) {
2989 			return pMac->sap.sapCtxList[intf].pSapContext;
2990 		}
2991 	}
2992 
2993 	return NULL;
2994 }
2995 
2996 /**
2997  * sap_find_cac_wait_session() - Get context of a SAP session in CAC wait state
2998  * @handle: Global MAC handle
2999  *
3000  * Finds and gets the context of a SAP session in CAC wait state.
3001  *
3002  * Return: Valid SAP context on success, else NULL
3003  */
3004 ptSapContext sap_find_cac_wait_session(tHalHandle handle)
3005 {
3006 	tpAniSirGlobal mac = PMAC_STRUCT(handle);
3007 	uint8_t i = 0;
3008 	ptSapContext sapContext;
3009 
3010 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
3011 			"%s", __func__);
3012 
3013 	for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
3014 		sapContext = (ptSapContext) mac->sap.sapCtxList[i].pSapContext;
3015 		if (((QDF_SAP_MODE == mac->sap.sapCtxList[i].sapPersona)
3016 		    ||
3017 		    (QDF_P2P_GO_MODE == mac->sap.sapCtxList[i].sapPersona)) &&
3018 		    (sapContext) &&
3019 		    (sapContext->sapsMachine == eSAP_DFS_CAC_WAIT)) {
3020 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
3021 				"%s: found SAP in cac wait state", __func__);
3022 			return sapContext;
3023 		}
3024 		if (sapContext) {
3025 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
3026 					"sapdfs: mode:%d intf:%d state:%d",
3027 					mac->sap.sapCtxList[i].sapPersona, i,
3028 					sapContext->sapsMachine);
3029 		}
3030 	}
3031 
3032 	return NULL;
3033 }
3034 
3035 /*==========================================================================
3036    FUNCTION   sap_close_session
3037 
3038    DESCRIPTION
3039     This function will close all the sme sessions as well as zero-out the
3040     sap global structure
3041 
3042    PARAMETERS
3043 
3044     IN
3045     hHal        : HAL pointer
3046     sapContext  : Sap Context value
3047     callback    : Roam Session close callback
3048     valid       : Sap context is valid or no
3049 
3050    RETURN VALUE
3051     The QDF_STATUS code associated with performing the operation
3052     QDF_STATUS_SUCCESS: Success
3053 
3054    SIDE EFFECTS
3055     NA
3056    ============================================================================*/
3057 QDF_STATUS sap_close_session(tHalHandle hHal,
3058 			     ptSapContext sapContext,
3059 			     csr_roamSessionCloseCallback callback, bool valid)
3060 {
3061 	QDF_STATUS qdf_status;
3062 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3063 
3064 	if (false == valid) {
3065 		qdf_status = sme_close_session(hHal,
3066 					       sapContext->sessionId,
3067 					       callback, NULL);
3068 	} else {
3069 		qdf_status = sme_close_session(hHal,
3070 					       sapContext->sessionId,
3071 					       callback, sapContext);
3072 	}
3073 
3074 	sapContext->isCacStartNotified = false;
3075 	sapContext->isCacEndNotified = false;
3076 	pMac->sap.sapCtxList[sapContext->sessionId].pSapContext = NULL;
3077 	sapContext->isSapSessionOpen = false;
3078 	sapContext->pre_cac_complete = false;
3079 	sapContext->is_pre_cac_on = false;
3080 	sapContext->chan_before_pre_cac = 0;
3081 
3082 	if (NULL == sap_find_valid_concurrent_session(hHal)) {
3083 		/* If timer is running then stop the timer and destory it */
3084 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
3085 			  "sapdfs: no session are valid, so clearing dfs global structure");
3086 		/*
3087 		 * CAC timer will be initiated and started only when SAP starts
3088 		 * on DFS channel and it will be stopped and destroyed
3089 		 * immediately once the radar detected or timedout. So
3090 		 * as per design CAC timer should be destroyed after stop
3091 		 */
3092 		if (pMac->sap.SapDfsInfo.is_dfs_cac_timer_running) {
3093 			qdf_mc_timer_stop(&pMac->sap.SapDfsInfo.
3094 					  sap_dfs_cac_timer);
3095 			pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
3096 			qdf_mc_timer_destroy(
3097 				&pMac->sap.SapDfsInfo.sap_dfs_cac_timer);
3098 		}
3099 		pMac->sap.SapDfsInfo.cac_state = eSAP_DFS_DO_NOT_SKIP_CAC;
3100 		sap_cac_reset_notify(hHal);
3101 		qdf_mem_zero(&pMac->sap, sizeof(pMac->sap));
3102 	}
3103 
3104 	return qdf_status;
3105 }
3106 
3107 /*==========================================================================
3108    FUNCTION  sap_cac_reset_notify
3109 
3110    DESCRIPTION Function will be called up on stop bss indication to clean up
3111    DFS global structure.
3112 
3113    DEPENDENCIES PARAMETERS
3114      IN hHAL : HAL pointer
3115 
3116    RETURN VALUE  : void.
3117 
3118    SIDE EFFECTS
3119    ============================================================================*/
3120 void sap_cac_reset_notify(tHalHandle hHal)
3121 {
3122 	uint8_t intf = 0;
3123 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3124 
3125 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
3126 		ptSapContext pSapContext =
3127 			(ptSapContext) pMac->sap.sapCtxList[intf].pSapContext;
3128 		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
3129 		    ||
3130 		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona))
3131 		    && pMac->sap.sapCtxList[intf].pSapContext != NULL) {
3132 			pSapContext->isCacStartNotified = false;
3133 			pSapContext->isCacEndNotified = false;
3134 		}
3135 	}
3136 }
3137 
3138 /*==========================================================================
3139    FUNCTION  sap_cac_start_notify
3140 
3141    DESCRIPTION Function will be called to notify eSAP_DFS_CAC_START event
3142    to HDD
3143 
3144    DEPENDENCIES PARAMETERS
3145      IN hHAL : HAL pointer
3146 
3147    RETURN VALUE  : QDF_STATUS.
3148 
3149    SIDE EFFECTS
3150    ============================================================================*/
3151 QDF_STATUS sap_cac_start_notify(tHalHandle hHal)
3152 {
3153 	uint8_t intf = 0;
3154 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3155 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3156 
3157 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
3158 		ptSapContext pSapContext =
3159 			(ptSapContext) pMac->sap.sapCtxList[intf].pSapContext;
3160 		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
3161 		    ||
3162 		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona))
3163 		    && pMac->sap.sapCtxList[intf].pSapContext != NULL &&
3164 		    (false == pSapContext->isCacStartNotified)) {
3165 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
3166 				  "sapdfs: Signaling eSAP_DFS_CAC_START to HDD for sapctx[%p]",
3167 				  pSapContext);
3168 
3169 			qdf_status = sap_signal_hdd_event(pSapContext, NULL,
3170 							  eSAP_DFS_CAC_START,
3171 							  (void *)
3172 							  eSAP_STATUS_SUCCESS);
3173 			if (QDF_STATUS_SUCCESS != qdf_status) {
3174 				QDF_TRACE(QDF_MODULE_ID_SAP,
3175 					  QDF_TRACE_LEVEL_ERROR,
3176 					  "In %s, failed setting isCacStartNotified on interface[%d]",
3177 					  __func__, intf);
3178 				return qdf_status;
3179 			}
3180 			pSapContext->isCacStartNotified = true;
3181 		}
3182 	}
3183 	return qdf_status;
3184 }
3185 
3186 /**
3187  * wlansap_update_pre_cac_end() - Update pre cac end to upper layer
3188  * @sap_context: SAP context
3189  * @mac: Global MAC structure
3190  * @intf: Interface number
3191  *
3192  * Notifies pre cac end to upper layer
3193  *
3194  * Return: QDF_STATUS
3195  */
3196 static QDF_STATUS wlansap_update_pre_cac_end(ptSapContext sap_context,
3197 		tpAniSirGlobal mac, uint8_t intf)
3198 {
3199 	QDF_STATUS qdf_status;
3200 
3201 	sap_context->isCacEndNotified = true;
3202 	mac->sap.SapDfsInfo.sap_radar_found_status = false;
3203 	sap_context->sapsMachine = eSAP_STARTED;
3204 
3205 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3206 			"In %s, pre cac end notify on %d: from state %s => %s",
3207 			__func__, intf, "eSAP_DFS_CAC_WAIT",
3208 			"eSAP_STARTED");
3209 
3210 	qdf_status = sap_signal_hdd_event(sap_context,
3211 			NULL, eSAP_DFS_PRE_CAC_END,
3212 			(void *)eSAP_STATUS_SUCCESS);
3213 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
3214 		QDF_TRACE(QDF_MODULE_ID_SAP,
3215 				QDF_TRACE_LEVEL_ERROR,
3216 				"In %s, pre cac notify failed on intf %d",
3217 				__func__, intf);
3218 		return qdf_status;
3219 	}
3220 
3221 	return QDF_STATUS_SUCCESS;
3222 }
3223 
3224 /*==========================================================================
3225    FUNCTION  sap_cac_end_notify
3226 
3227    DESCRIPTION Function will be called to notify eSAP_DFS_CAC_END event
3228    to HDD
3229 
3230    DEPENDENCIES PARAMETERS
3231      IN hHAL : HAL pointer
3232 
3233    RETURN VALUE  : QDF_STATUS.
3234 
3235    SIDE EFFECTS
3236    ============================================================================*/
3237 QDF_STATUS sap_cac_end_notify(tHalHandle hHal, tCsrRoamInfo *roamInfo)
3238 {
3239 	uint8_t intf;
3240 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3241 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3242 
3243 	/*
3244 	 * eSAP_DFS_CHANNEL_CAC_END:
3245 	 * CAC Period elapsed and there was no radar
3246 	 * found so, SAP can continue beaconing.
3247 	 * sap_radar_found_status is set to 0
3248 	 */
3249 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
3250 		ptSapContext pSapContext =
3251 			(ptSapContext) pMac->sap.sapCtxList[intf].pSapContext;
3252 		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
3253 		    ||
3254 		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona))
3255 		    && pMac->sap.sapCtxList[intf].pSapContext != NULL &&
3256 		    (false == pSapContext->isCacEndNotified) &&
3257 		    (pSapContext->sapsMachine == eSAP_DFS_CAC_WAIT)) {
3258 			pSapContext = pMac->sap.sapCtxList[intf].pSapContext;
3259 
3260 			/* If this is an end notification of a pre cac, the
3261 			 * SAP must not start beaconing and must delete the
3262 			 * temporary interface created for pre cac and switch
3263 			 * the original SAP to the pre CAC channel.
3264 			 */
3265 			if (pSapContext->is_pre_cac_on) {
3266 				qdf_status = wlansap_update_pre_cac_end(
3267 						pSapContext, pMac, intf);
3268 				if (QDF_IS_STATUS_ERROR(qdf_status))
3269 					return qdf_status;
3270 				/* pre CAC is not allowed with any concurrency.
3271 				 * So, we can break from here.
3272 				 */
3273 				break;
3274 			}
3275 
3276 			qdf_status = sap_signal_hdd_event(pSapContext, NULL,
3277 							  eSAP_DFS_CAC_END,
3278 							  (void *)
3279 							  eSAP_STATUS_SUCCESS);
3280 			if (QDF_STATUS_SUCCESS != qdf_status) {
3281 				QDF_TRACE(QDF_MODULE_ID_SAP,
3282 					  QDF_TRACE_LEVEL_ERROR,
3283 					  "In %s, failed setting isCacEndNotified on interface[%d]",
3284 					  __func__, intf);
3285 				return qdf_status;
3286 			}
3287 			pSapContext->isCacEndNotified = true;
3288 			pMac->sap.SapDfsInfo.sap_radar_found_status = false;
3289 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
3290 				  "sapdfs: Start beacon request on sapctx[%p]",
3291 				  pSapContext);
3292 
3293 			/* Start beaconing on the new channel */
3294 			wlansap_start_beacon_req(pSapContext);
3295 
3296 			/* Transition from eSAP_STARTING to eSAP_STARTED
3297 			 * (both without substates)
3298 			 */
3299 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
3300 				  "sapdfs: channel[%d] from state %s => %s",
3301 				  pSapContext->channel, "eSAP_STARTING",
3302 				  "eSAP_STARTED");
3303 
3304 			pSapContext->sapsMachine = eSAP_STARTED;
3305 
3306 			/*Action code for transition */
3307 			qdf_status = sap_signal_hdd_event(pSapContext, roamInfo,
3308 							  eSAP_START_BSS_EVENT,
3309 							  (void *)
3310 							  eSAP_STATUS_SUCCESS);
3311 			if (QDF_STATUS_SUCCESS != qdf_status) {
3312 				QDF_TRACE(QDF_MODULE_ID_SAP,
3313 					  QDF_TRACE_LEVEL_ERROR,
3314 					  "In %s, failed setting isCacEndNotified on interface[%d]",
3315 					  __func__, intf);
3316 				return qdf_status;
3317 			}
3318 
3319 			/* Transition from eSAP_STARTING to eSAP_STARTED
3320 			 * (both without substates)
3321 			 */
3322 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3323 				  "In %s, from state %s => %s",
3324 				  __func__, "eSAP_DFS_CAC_WAIT",
3325 				  "eSAP_STARTED");
3326 		}
3327 	}
3328 	/*
3329 	 * All APs are done with CAC timer, all APs should start beaconing.
3330 	 * Lets assume AP1 and AP2 started beaconing on DFS channel, Now lets
3331 	 * say AP1 goes down and comes back on same DFS channel. In this case
3332 	 * AP1 shouldn't start CAC timer and start beacon immediately beacause
3333 	 * AP2 is already beaconing on this channel. This case will be handled
3334 	 * by checking against eSAP_DFS_SKIP_CAC while starting the timer.
3335 	 */
3336 	pMac->sap.SapDfsInfo.cac_state = eSAP_DFS_SKIP_CAC;
3337 	return qdf_status;
3338 }
3339 
3340 /**
3341  * sap_fsm_state_disconnected() - utility function called from sap fsm
3342  * @sap_ctx: SAP context
3343  * @sap_event: SAP event buffer
3344  * @mac_ctx: global MAC context
3345  * @hal: HAL handle
3346  *
3347  * This function is called for state transition from "eSAP_DISCONNECTED"
3348  *
3349  * Return: QDF_STATUS
3350  */
3351 static QDF_STATUS sap_fsm_state_disconnected(ptSapContext sap_ctx,
3352 			ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx,
3353 			tHalHandle hal)
3354 {
3355 	uint32_t msg = sap_event->event;
3356 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3357 
3358 	if (msg == eSAP_HDD_START_INFRA_BSS) {
3359 		/*
3360 		 * Transition from eSAP_DISCONNECTED to eSAP_CH_SELECT
3361 		 * (both without substates)
3362 		 */
3363 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3364 			  FL("new from state %s => %s: session:%d"),
3365 			  "eSAP_DISCONNECTED", "eSAP_CH_SELECT",
3366 			  sap_ctx->sessionId);
3367 
3368 		if (sap_ctx->isSapSessionOpen == eSAP_FALSE) {
3369 			uint32_t type, subtype;
3370 			if (sap_ctx->csr_roamProfile.csrPersona ==
3371 			    QDF_P2P_GO_MODE)
3372 				qdf_status = cds_get_vdev_types(QDF_P2P_GO_MODE,
3373 							&type, &subtype);
3374 			else
3375 				qdf_status = cds_get_vdev_types(QDF_SAP_MODE,
3376 								&type,
3377 								&subtype);
3378 
3379 			if (QDF_STATUS_SUCCESS != qdf_status) {
3380 				QDF_TRACE(QDF_MODULE_ID_SAP,
3381 						QDF_TRACE_LEVEL_FATAL,
3382 						"failed to get vdev type");
3383 				return QDF_STATUS_E_FAILURE;
3384 			}
3385 			/* Open SME Session for scan */
3386 			qdf_status = sme_open_session(hal, NULL,
3387 					sap_ctx, sap_ctx->self_mac_addr,
3388 					&sap_ctx->sessionId, type, subtype);
3389 			if (QDF_STATUS_SUCCESS != qdf_status) {
3390 				QDF_TRACE(QDF_MODULE_ID_SAP,
3391 					 QDF_TRACE_LEVEL_ERROR,
3392 					 FL("Error: calling sme_open_session"));
3393 				return QDF_STATUS_E_FAILURE;
3394 			}
3395 
3396 			sap_ctx->isSapSessionOpen = eSAP_TRUE;
3397 		}
3398 
3399 		/* init dfs channel nol */
3400 		sap_init_dfs_channel_nol_list(sap_ctx);
3401 
3402 		/* Set SAP device role */
3403 		sap_ctx->sapsMachine = eSAP_CH_SELECT;
3404 
3405 		/*
3406 		 * Perform sme_ScanRequest. This scan request is post start bss
3407 		 * request so, set the third to false.
3408 		 */
3409 		qdf_status = sap_goto_channel_sel(sap_ctx, sap_event, false,
3410 						true);
3411 
3412 		/*
3413 		 * Transition from eSAP_DISCONNECTED to eSAP_CH_SELECT
3414 		 * (both without substates)
3415 		 */
3416 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3417 			  FL("from state %s => %s"),
3418 			  "eSAP_DISCONNECTED", "eSAP_CH_SELECT");
3419 	} else if (msg == eSAP_DFS_CHANNEL_CAC_START) {
3420 		/*
3421 		 * No need of state check here, caller is expected to perform
3422 		 * the checks before sending the event
3423 		 */
3424 		sap_ctx->sapsMachine = eSAP_DFS_CAC_WAIT;
3425 
3426 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
3427 			FL("from state eSAP_DISCONNECTED => SAP_DFS_CAC_WAIT"));
3428 		if (mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running != true) {
3429 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
3430 			    FL("sapdfs: starting dfs cac timer on sapctx[%p]"),
3431 			    sap_ctx);
3432 			sap_start_dfs_cac_timer(sap_ctx);
3433 		}
3434 
3435 		qdf_status = sap_cac_start_notify(hal);
3436 	} else if (msg == eSAP_CHANNEL_SELECTION_RETRY) {
3437 		/* Set SAP device role */
3438 		sap_ctx->sapsMachine = eSAP_CH_SELECT;
3439 
3440 		/*
3441 		 * Perform sme_ScanRequest. This scan request is post start bss
3442 		 * request so, set the third to false.
3443 		 */
3444 		qdf_status = sap_goto_channel_sel(sap_ctx, sap_event, false,
3445 					false);
3446 	} else {
3447 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3448 			  FL("in state %s, event msg %d"),
3449 			  "eSAP_DISCONNECTED", msg);
3450 	}
3451 
3452 	return qdf_status;
3453 }
3454 
3455 /**
3456  * sap_fsm_state_ch_select() - utility function called from sap fsm
3457  * @sap_ctx: SAP context
3458  * @sap_event: SAP event buffer
3459  * @mac_ctx: global MAC context
3460  * @hal: HAL handle
3461  *
3462  * This function is called for state transition from "eSAP_CH_SELECT"
3463  *
3464  * Return: QDF_STATUS
3465  */
3466 static QDF_STATUS sap_fsm_state_ch_select(ptSapContext sap_ctx,
3467 			ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx,
3468 			tHalHandle hal)
3469 {
3470 	uint32_t msg = sap_event->event;
3471 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3472 	uint32_t cbmode;
3473 	bool b_leak_chan = false;
3474 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION
3475 	uint8_t temp_chan;
3476 	tSapDfsNolInfo *p_nol;
3477 #endif
3478 
3479 	if (msg == eSAP_MAC_SCAN_COMPLETE) {
3480 		/* get the bonding mode */
3481 		if (sap_ctx->channel <= 14)
3482 			cbmode = sme_get_cb_phy_state_from_cb_ini_value(
3483 					sme_get_channel_bonding_mode24_g(hal));
3484 		else
3485 			cbmode = sme_get_cb_phy_state_from_cb_ini_value(
3486 					sme_get_channel_bonding_mode5_g(hal));
3487 
3488 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION
3489 		temp_chan = sap_ctx->channel;
3490 		p_nol = mac_ctx->sap.SapDfsInfo.sapDfsChannelNolList;
3491 
3492 		sap_mark_leaking_ch(sap_ctx,
3493 			cbmode, p_nol, 1, &temp_chan);
3494 
3495 		/*
3496 		 * if selelcted channel has leakage to channels
3497 		 * in NOL, the temp_chan will be reset
3498 		 */
3499 		b_leak_chan = (temp_chan != sap_ctx->channel);
3500 #endif
3501 		/*
3502 		 * check if channel is in DFS_NOL or if the channel
3503 		 * has leakage to the channels in NOL
3504 		 */
3505 		if (sap_dfs_is_channel_in_nol_list(sap_ctx, sap_ctx->channel,
3506 			cbmode) || b_leak_chan) {
3507 			uint8_t ch;
3508 
3509 			/* find a new available channel */
3510 			ch = sap_random_channel_sel(sap_ctx);
3511 			if (ch == 0) {
3512 				/* No available channel found */
3513 				QDF_TRACE(QDF_MODULE_ID_SAP,
3514 					QDF_TRACE_LEVEL_ERROR,
3515 					FL("No available channel found!!!"));
3516 				sap_signal_hdd_event(sap_ctx, NULL,
3517 					eSAP_DFS_NO_AVAILABLE_CHANNEL,
3518 					(void *)eSAP_STATUS_SUCCESS);
3519 				return QDF_STATUS_E_FAULT;
3520 			}
3521 
3522 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3523 				  FL("channel %d is in NOL, StartBss on new channel %d"),
3524 				  sap_ctx->channel, ch);
3525 
3526 			sap_ctx->channel = ch;
3527 			cds_set_channel_params(sap_ctx->channel,
3528 				sap_ctx->secondary_ch, &sap_ctx->ch_params);
3529 		}
3530 		if (sap_ctx->channel > 14 &&
3531 		    (sap_ctx->csr_roamProfile.phyMode == eCSR_DOT11_MODE_11g ||
3532 		     sap_ctx->csr_roamProfile.phyMode ==
3533 						eCSR_DOT11_MODE_11g_ONLY))
3534 			sap_ctx->csr_roamProfile.phyMode = eCSR_DOT11_MODE_11a;
3535 
3536 		/*
3537 		 * when AP2 is started while AP1 is performing ACS, we may not
3538 		 * have the AP1 channel yet.So here after the completion of AP2
3539 		 * ACS check if AP1 ACS resulting channel is DFS and if yes
3540 		 * override AP2 ACS scan result with AP1 DFS channel
3541 		 */
3542 		if (cds_concurrent_beaconing_sessions_running()) {
3543 			uint16_t con_ch;
3544 
3545 			con_ch = sme_get_concurrent_operation_channel(hal);
3546 			if (con_ch && CDS_IS_DFS_CH(con_ch))
3547 				sap_ctx->channel = con_ch;
3548 		}
3549 
3550 		/*
3551 		 * Transition from eSAP_CH_SELECT to eSAP_STARTING
3552 		 * (both without substates)
3553 		 */
3554 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3555 			  FL("from state %s => %s"),
3556 			  "eSAP_CH_SELECT", "eSAP_STARTING");
3557 		/* Channel selected. Now can sap_goto_starting */
3558 		sap_ctx->sapsMachine = eSAP_STARTING;
3559 		/* Specify the channel */
3560 		sap_ctx->csr_roamProfile.ChannelInfo.numOfChannels =
3561 						1;
3562 		sap_ctx->csr_roamProfile.ChannelInfo.ChannelList =
3563 			&sap_ctx->csr_roamProfile.operationChannel;
3564 		sap_ctx->csr_roamProfile.operationChannel =
3565 			(uint8_t) sap_ctx->channel;
3566 		sap_ctx->csr_roamProfile.ch_params.ch_width =
3567 					sap_ctx->ch_params.ch_width;
3568 		sap_ctx->csr_roamProfile.ch_params.center_freq_seg0 =
3569 				sap_ctx->ch_params.center_freq_seg0;
3570 		sap_ctx->csr_roamProfile.ch_params.center_freq_seg1 =
3571 				sap_ctx->ch_params.center_freq_seg1;
3572 		sap_ctx->csr_roamProfile.ch_params.sec_ch_offset =
3573 				sap_ctx->ch_params.sec_ch_offset;
3574 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3575 		    FL("notify hostapd about channel selection: %d"),
3576 		    sap_ctx->channel);
3577 		sap_signal_hdd_event(sap_ctx, NULL,
3578 					eSAP_CHANNEL_CHANGE_EVENT,
3579 					(void *) eSAP_STATUS_SUCCESS);
3580 		qdf_status = sap_goto_starting(sap_ctx, sap_event,
3581 					  eCSR_BSS_TYPE_INFRA_AP);
3582 	} else if (msg == eSAP_CHANNEL_SELECTION_FAILED) {
3583 		sap_ctx->sapsMachine = eSAP_DISCONNECTED;
3584 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3585 		FL("Cannot start BSS, ACS Fail"));
3586 	} else if (msg == eSAP_HDD_STOP_INFRA_BSS) {
3587 		sap_ctx->sapsMachine = eSAP_DISCONNECTED;
3588 		sap_signal_hdd_event(sap_ctx, NULL, eSAP_START_BSS_EVENT,
3589 					(void *)eSAP_STATUS_FAILURE);
3590 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
3591 			"%s: BSS stopped when Ch select in Progress", __func__);
3592 	} else {
3593 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3594 			  FL("in state %s, invalid event msg %d"),
3595 			  "eSAP_CH_SELECT", msg);
3596 	}
3597 
3598 	return qdf_status;
3599 }
3600 
3601 /**
3602  * sap_fsm_state_dfs_cac_wait() - utility function called from sap fsm
3603  * @sap_ctx: SAP context
3604  * @sap_event: SAP event buffer
3605  * @mac_ctx: global MAC context
3606  * @hal: HAL handle
3607  *
3608  * This function is called for state transition from "eSAP_DFS_CAC_WAIT"
3609  *
3610  * Return: QDF_STATUS
3611  */
3612 static QDF_STATUS sap_fsm_state_dfs_cac_wait(ptSapContext sap_ctx,
3613 			ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx,
3614 			tHalHandle hal)
3615 {
3616 	uint32_t msg = sap_event->event;
3617 	tCsrRoamInfo *roam_info = (tCsrRoamInfo *) (sap_event->params);
3618 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3619 
3620 	if (msg == eSAP_DFS_CHANNEL_CAC_START) {
3621 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3622 			  FL("from state %s => %s"),
3623 			  "eSAP_CH_SELECT", "eSAP_DFS_CAC_WAIT");
3624 		if (mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running != true)
3625 			sap_start_dfs_cac_timer(sap_ctx);
3626 		qdf_status = sap_cac_start_notify(hal);
3627 	} else if (msg == eSAP_DFS_CHANNEL_CAC_RADAR_FOUND) {
3628 		uint8_t intf;
3629 		/*
3630 		 * Radar found while performing channel availability
3631 		 * check, need to switch the channel again
3632 		 */
3633 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
3634 			  "ENTERTRED CAC WAIT STATE-->eSAP_DISCONNECTING\n");
3635 		if (mac_ctx->sap.SapDfsInfo.target_channel) {
3636 			cds_set_channel_params(
3637 				mac_ctx->sap.SapDfsInfo.target_channel, 0,
3638 				&sap_ctx->ch_params);
3639 		}
3640 
3641 		for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
3642 			ptSapContext t_sap_ctx;
3643 			if (((QDF_SAP_MODE ==
3644 				 mac_ctx->sap.sapCtxList[intf].sapPersona) ||
3645 			     (QDF_P2P_GO_MODE ==
3646 				mac_ctx->sap.sapCtxList[intf].sapPersona)) &&
3647 			    mac_ctx->sap.sapCtxList[intf].pSapContext != NULL) {
3648 				t_sap_ctx =
3649 				    mac_ctx->sap.sapCtxList[intf].pSapContext;
3650 				/* SAP to be moved to DISCONNECTING state */
3651 				sap_ctx->sapsMachine = eSAP_DISCONNECTING;
3652 				/*
3653 				 * eSAP_DFS_CHANNEL_CAC_RADAR_FOUND:
3654 				 * A Radar is found on current DFS Channel
3655 				 * while in CAC WAIT period So, do a channel
3656 				 * switch to randomly selected  target channel.
3657 				 * Send the Channel change message to SME/PE.
3658 				 * sap_radar_found_status is set to 1
3659 				 */
3660 				sap_signal_hdd_event(t_sap_ctx, NULL,
3661 					eSAP_DFS_RADAR_DETECT,
3662 					(void *)eSAP_STATUS_SUCCESS);
3663 
3664 				wlansap_channel_change_request(
3665 					(void *)t_sap_ctx,
3666 					mac_ctx->sap.SapDfsInfo.target_channel);
3667 			}
3668 		}
3669 	} else if (msg == eSAP_DFS_CHANNEL_CAC_END) {
3670 		qdf_status = sap_cac_end_notify(hal, roam_info);
3671 	} else if (msg == eSAP_HDD_STOP_INFRA_BSS) {
3672 		/* Transition from eSAP_DFS_CAC_WAIT to eSAP_DISCONNECTING */
3673 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3674 			  FL("from state %s => %s"),
3675 			  "eSAP_DFS_CAC_WAIT", "eSAP_DISCONNECTING");
3676 
3677 		/*
3678 		 * Stop the CAC timer only in following conditions
3679 		 * single AP: if there is a single AP then stop the timer
3680 		 * mulitple APs: incase of multiple APs, make sure that
3681 		 *               all APs are down.
3682 		 */
3683 		if (NULL == sap_find_valid_concurrent_session(hal)) {
3684 			QDF_TRACE(QDF_MODULE_ID_SAP,
3685 				  QDF_TRACE_LEVEL_INFO_MED,
3686 				  FL("sapdfs: no sessions are valid, stopping timer"));
3687 			sap_stop_dfs_cac_timer(sap_ctx);
3688 		}
3689 
3690 		sap_ctx->sapsMachine = eSAP_DISCONNECTING;
3691 		qdf_status = sap_goto_disconnecting(sap_ctx);
3692 	} else {
3693 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3694 			  FL("in state %s, invalid event msg %d"),
3695 			  "eSAP_DFS_CAC_WAIT", msg);
3696 	}
3697 
3698 	return qdf_status;
3699 }
3700 
3701 /**
3702  * sap_fsm_state_starting() - utility function called from sap fsm
3703  * @sap_ctx: SAP context
3704  * @sap_event: SAP event buffer
3705  * @mac_ctx: global MAC context
3706  * @hal: HAL handle
3707  *
3708  * This function is called for state transition from "eSAP_STARTING"
3709  *
3710  * Return: QDF_STATUS
3711  */
3712 static QDF_STATUS sap_fsm_state_starting(ptSapContext sap_ctx,
3713 			ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx,
3714 			tHalHandle hal)
3715 {
3716 	uint32_t msg = sap_event->event;
3717 	tCsrRoamInfo *roam_info = (tCsrRoamInfo *) (sap_event->params);
3718 	tSapDfsInfo *sap_dfs_info;
3719 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3720 	uint8_t is_dfs = false;
3721 
3722 	if (msg == eSAP_MAC_START_BSS_SUCCESS) {
3723 		/*
3724 		 * Transition from eSAP_STARTING to eSAP_STARTED
3725 		 * (both without substates)
3726 		 */
3727 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3728 			  FL("from state channel = %d %s => %s ch_width %d"),
3729 			  sap_ctx->channel, "eSAP_STARTING", "eSAP_STARTED",
3730 			  sap_ctx->ch_params.ch_width);
3731 		sap_ctx->sapsMachine = eSAP_STARTED;
3732 
3733 		/* Action code for transition */
3734 		qdf_status = sap_signal_hdd_event(sap_ctx, roam_info,
3735 				eSAP_START_BSS_EVENT,
3736 				(void *) eSAP_STATUS_SUCCESS);
3737 
3738 		/*
3739 		 * The upper layers have been informed that AP is up and
3740 		 * running, however, the AP is still not beaconing, until
3741 		 * CAC is done if the operating channel is DFS
3742 		 */
3743 		if (sap_ctx->ch_params.ch_width == CH_WIDTH_160MHZ) {
3744 			is_dfs = true;
3745 		} else if (sap_ctx->ch_params.ch_width == CH_WIDTH_80P80MHZ) {
3746 			if (cds_get_channel_state(sap_ctx->channel) ==
3747 			    CHANNEL_STATE_DFS ||
3748 			    cds_get_channel_state(sap_ctx->
3749 				ch_params.center_freq_seg1 -
3750 				SIR_80MHZ_START_CENTER_CH_DIFF) ==
3751 					CHANNEL_STATE_DFS)
3752 				is_dfs = true;
3753 		} else {
3754 			if (cds_get_channel_state(sap_ctx->channel) ==
3755 							CHANNEL_STATE_DFS)
3756 				is_dfs = true;
3757 		}
3758 
3759 		if (is_dfs) {
3760 			sap_dfs_info = &mac_ctx->sap.SapDfsInfo;
3761 			if ((false == sap_dfs_info->ignore_cac) &&
3762 			    (eSAP_DFS_DO_NOT_SKIP_CAC ==
3763 					sap_dfs_info->cac_state) &&
3764 			    !sap_ctx->pre_cac_complete) {
3765 				/* Move the device in CAC_WAIT_STATE */
3766 				sap_ctx->sapsMachine = eSAP_DFS_CAC_WAIT;
3767 
3768 				/*
3769 				 * Need to stop the OS transmit queues,
3770 				 * so that no traffic can flow down the stack
3771 				 */
3772 
3773 				/* Start CAC wait timer */
3774 				if (sap_dfs_info->is_dfs_cac_timer_running !=
3775 									true)
3776 					sap_start_dfs_cac_timer(sap_ctx);
3777 				qdf_status = sap_cac_start_notify(hal);
3778 
3779 			} else {
3780 				wlansap_start_beacon_req(sap_ctx);
3781 			}
3782 		}
3783 	} else if (msg == eSAP_MAC_START_FAILS) {
3784 		/*
3785 		 * Transition from STARTING to DISCONNECTED
3786 		 * (both without substates)
3787 		 */
3788 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3789 			  FL("from state %s => %s"),
3790 			  "eSAP_STARTING", "eSAP_DISCONNECTED");
3791 
3792 		/*Action code for transition */
3793 		qdf_status = sap_signal_hdd_event(sap_ctx, NULL,
3794 				eSAP_START_BSS_EVENT,
3795 				(void *) eSAP_STATUS_FAILURE);
3796 		qdf_status = sap_goto_disconnected(sap_ctx);
3797 		/* Advance outer statevar */
3798 		sap_ctx->sapsMachine = eSAP_DISCONNECTED;
3799 	} else if (msg == eSAP_HDD_STOP_INFRA_BSS) {
3800 		/*
3801 		 * Transition from eSAP_STARTING to eSAP_DISCONNECTED
3802 		 * (both without substates)
3803 		 */
3804 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3805 			  FL("from state %s => %s"),
3806 			  "eSAP_STARTING", "eSAP_DISCONNECTED");
3807 
3808 		/* Advance outer statevar */
3809 		sap_ctx->sapsMachine = eSAP_DISCONNECTED;
3810 		qdf_status = sap_signal_hdd_event(sap_ctx, NULL,
3811 				eSAP_START_BSS_EVENT,
3812 				(void *) eSAP_STATUS_FAILURE);
3813 		qdf_status = sap_goto_disconnected(sap_ctx);
3814 		/* Close the SME session */
3815 
3816 		if (eSAP_TRUE == sap_ctx->isSapSessionOpen) {
3817 			if (QDF_STATUS_SUCCESS == sap_close_session(hal,
3818 						sap_ctx, NULL, false))
3819 				sap_ctx->isSapSessionOpen = eSAP_FALSE;
3820 		}
3821 	} else if (msg == eSAP_OPERATING_CHANNEL_CHANGED) {
3822 		/* The operating channel has changed, update hostapd */
3823 		sap_ctx->channel =
3824 			(uint8_t) mac_ctx->sap.SapDfsInfo.target_channel;
3825 
3826 		sap_ctx->sapsMachine = eSAP_STARTED;
3827 
3828 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3829 			  FL("from state %s => %s"),
3830 			  "eSAP_STARTING", "eSAP_STARTED");
3831 
3832 		/* Indicate change in the state to upper layers */
3833 		qdf_status = sap_signal_hdd_event(sap_ctx, roam_info,
3834 				  eSAP_START_BSS_EVENT,
3835 				  (void *)eSAP_STATUS_SUCCESS);
3836 	} else {
3837 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3838 			  FL("in state %s, invalid event msg %d"),
3839 			  "eSAP_STARTING", msg);
3840 	}
3841 
3842 	return qdf_status;
3843 }
3844 
3845 /**
3846  * sap_fsm_state_started() - utility function called from sap fsm
3847  * @sap_ctx: SAP context
3848  * @sap_event: SAP event buffer
3849  * @mac_ctx: global MAC context
3850  *
3851  * This function is called for state transition from "eSAP_STARTED"
3852  *
3853  * Return: QDF_STATUS
3854  */
3855 static QDF_STATUS sap_fsm_state_started(ptSapContext sap_ctx,
3856 			ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx)
3857 {
3858 	uint32_t msg = sap_event->event;
3859 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3860 
3861 	if (msg == eSAP_HDD_STOP_INFRA_BSS) {
3862 		/*
3863 		 * Transition from eSAP_STARTED to eSAP_DISCONNECTING
3864 		 * (both without substates)
3865 		 */
3866 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3867 			  FL("from state %s => %s"),
3868 			  "eSAP_STARTED", "eSAP_DISCONNECTING");
3869 		sap_ctx->sapsMachine = eSAP_DISCONNECTING;
3870 		qdf_status = sap_goto_disconnecting(sap_ctx);
3871 	} else if (eSAP_DFS_CHNL_SWITCH_ANNOUNCEMENT_START == msg) {
3872 		uint8_t intf;
3873 		/*
3874 		 * Radar is seen on the current operating channel
3875 		 * send CSA IE for all associated stations
3876 		 * Request for CSA IE transmission
3877 		 */
3878 		for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
3879 			ptSapContext temp_sap_ctx;
3880 			if (((QDF_SAP_MODE ==
3881 				mac_ctx->sap.sapCtxList[intf].sapPersona) ||
3882 			    (QDF_P2P_GO_MODE ==
3883 				mac_ctx->sap.sapCtxList[intf].sapPersona)) &&
3884 			    mac_ctx->sap.sapCtxList[intf].pSapContext != NULL) {
3885 				temp_sap_ctx =
3886 				    mac_ctx->sap.sapCtxList[intf].pSapContext;
3887 				QDF_TRACE(QDF_MODULE_ID_SAP,
3888 					  QDF_TRACE_LEVEL_INFO_MED,
3889 					  FL("sapdfs: Sending CSAIE for sapctx[%p]"),
3890 					  temp_sap_ctx);
3891 
3892 				qdf_status = wlansap_dfs_send_csa_ie_request(
3893 						(void *) temp_sap_ctx);
3894 			}
3895 		}
3896 	} else if (eSAP_CHANNEL_SWITCH_ANNOUNCEMENT_START == msg) {
3897 		enum tQDF_ADAPTER_MODE persona;
3898 
3899 		if (!sap_ctx) {
3900 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3901 					FL("Invalid sap_ctx"));
3902 			return qdf_status;
3903 		}
3904 
3905 		persona = mac_ctx->sap.sapCtxList[sap_ctx->sessionId].
3906 								sapPersona;
3907 
3908 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
3909 				FL("app trigger chan switch: mode:%d vdev:%d"),
3910 				persona, sap_ctx->sessionId);
3911 
3912 		if ((QDF_SAP_MODE == persona) || (QDF_P2P_GO_MODE == persona))
3913 			qdf_status = wlansap_dfs_send_csa_ie_request(
3914 					(void *) sap_ctx);
3915 	} else {
3916 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3917 			  FL("in state %s, invalid event msg %d"),
3918 			  "eSAP_STARTED", msg);
3919 	}
3920 
3921 	return qdf_status;
3922 }
3923 
3924 /**
3925  * sap_fsm_state_disconnecting() - utility function called from sap fsm
3926  * @sap_ctx: SAP context
3927  * @sap_event: SAP event buffer
3928  * @mac_ctx: global MAC context
3929  *
3930  * This function is called for state transition from "eSAP_DISCONNECTING"
3931  *
3932  * Return: QDF_STATUS
3933  */
3934 static QDF_STATUS sap_fsm_state_disconnecting(ptSapContext sap_ctx,
3935 			ptWLAN_SAPEvent sap_event, tpAniSirGlobal mac_ctx,
3936 			tHalHandle hal)
3937 {
3938 	uint32_t msg = sap_event->event;
3939 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3940 
3941 	if (msg == eSAP_MAC_READY_FOR_CONNECTIONS) {
3942 		/*
3943 		 * Transition from eSAP_DISCONNECTING to eSAP_DISCONNECTED
3944 		 * (both without substates)
3945 		 */
3946 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
3947 			  FL("from state %s => %s"),
3948 			  "eSAP_DISCONNECTING", "eSAP_DISCONNECTED");
3949 		sap_ctx->sapsMachine = eSAP_DISCONNECTED;
3950 
3951 		/* Close the SME session */
3952 		if (eSAP_TRUE == sap_ctx->isSapSessionOpen) {
3953 			sap_ctx->isSapSessionOpen = eSAP_FALSE;
3954 			qdf_status = sap_close_session(hal, sap_ctx,
3955 					sap_roam_session_close_callback, true);
3956 			if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
3957 				qdf_status = sap_signal_hdd_event(sap_ctx, NULL,
3958 						eSAP_STOP_BSS_EVENT,
3959 						(void *)eSAP_STATUS_SUCCESS);
3960 			}
3961 		}
3962 	} else if (msg == eWNI_SME_CHANNEL_CHANGE_REQ) {
3963 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
3964 			  FL("sapdfs: Send channel change request on sapctx[%p]"),
3965 			  sap_ctx);
3966 		/*
3967 		 * Most likely, radar has been detected and SAP wants to
3968 		 * change the channel
3969 		 */
3970 		qdf_status = wlansap_channel_change_request((void *) sap_ctx,
3971 				mac_ctx->sap.SapDfsInfo.target_channel);
3972 
3973 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
3974 			  FL("Sending DFS eWNI_SME_CHANNEL_CHANGE_REQ"));
3975 	} else {
3976 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
3977 			  FL("in state %s, invalid event msg %d"),
3978 			  "eSAP_DISCONNECTING", msg);
3979 	}
3980 
3981 	return qdf_status;
3982 }
3983 
3984 /**
3985  * sap_fsm() - SAP statem machine entry function
3986  * @sap_ctx: SAP context
3987  * @sap_event: SAP event
3988  *
3989  * SAP statem machine entry function
3990  *
3991  * Return: QDF_STATUS
3992  */
3993 QDF_STATUS sap_fsm(ptSapContext sap_ctx, ptWLAN_SAPEvent sap_event)
3994 {
3995 	/*
3996 	 * Retrieve the phy link state machine structure
3997 	 * from the sap_ctx value
3998 	 * state var that keeps track of state machine
3999 	 */
4000 	eSapFsmStates_t state_var = sap_ctx->sapsMachine;
4001 	uint32_t msg = sap_event->event; /* State machine input event message */
4002 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
4003 	tHalHandle hal = CDS_GET_HAL_CB(sap_ctx->p_cds_gctx);
4004 	tpAniSirGlobal mac_ctx;
4005 
4006 	if (NULL == hal) {
4007 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4008 			  FL("Invalid hal"));
4009 		return QDF_STATUS_E_FAILURE;
4010 	}
4011 
4012 	mac_ctx = PMAC_STRUCT(hal);
4013 	if (NULL == mac_ctx) {
4014 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4015 			  FL("Invalid MAC context"));
4016 		return QDF_STATUS_E_FAILURE;
4017 	}
4018 
4019 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
4020 		  FL("sap_ctx=%p, state_var=%d, msg=0x%x"),
4021 		  sap_ctx, state_var, msg);
4022 
4023 	switch (state_var) {
4024 	case eSAP_DISCONNECTED:
4025 		qdf_status = sap_fsm_state_disconnected(sap_ctx, sap_event,
4026 				mac_ctx, hal);
4027 		break;
4028 
4029 	case eSAP_CH_SELECT:
4030 		qdf_status = sap_fsm_state_ch_select(sap_ctx, sap_event,
4031 				mac_ctx, hal);
4032 		break;
4033 
4034 	case eSAP_DFS_CAC_WAIT:
4035 		qdf_status = sap_fsm_state_dfs_cac_wait(sap_ctx, sap_event,
4036 				mac_ctx, hal);
4037 		break;
4038 
4039 	case eSAP_STARTING:
4040 		qdf_status = sap_fsm_state_starting(sap_ctx, sap_event,
4041 				mac_ctx, hal);
4042 		break;
4043 
4044 	case eSAP_STARTED:
4045 		qdf_status = sap_fsm_state_started(sap_ctx, sap_event,
4046 				mac_ctx);
4047 		break;
4048 
4049 	case eSAP_DISCONNECTING:
4050 		qdf_status = sap_fsm_state_disconnecting(sap_ctx, sap_event,
4051 				mac_ctx, hal);
4052 		break;
4053 	}
4054 	return qdf_status;
4055 }
4056 
4057 eSapStatus
4058 sapconvert_to_csr_profile(tsap_Config_t *pconfig_params, eCsrRoamBssType bssType,
4059 			  tCsrRoamProfile *profile)
4060 {
4061 	/* Create Roam profile for SoftAP to connect */
4062 	profile->BSSType = eCSR_BSS_TYPE_INFRA_AP;
4063 	profile->SSIDs.numOfSSIDs = 1;
4064 	profile->csrPersona = pconfig_params->persona;
4065 	profile->disableDFSChSwitch = pconfig_params->disableDFSChSwitch;
4066 
4067 	qdf_mem_zero(profile->SSIDs.SSIDList[0].SSID.ssId,
4068 		     sizeof(profile->SSIDs.SSIDList[0].SSID.ssId));
4069 
4070 	/* Flag to not broadcast the SSID information */
4071 	profile->SSIDs.SSIDList[0].ssidHidden =
4072 		pconfig_params->SSIDinfo.ssidHidden;
4073 
4074 	profile->SSIDs.SSIDList[0].SSID.length =
4075 		pconfig_params->SSIDinfo.ssid.length;
4076 	qdf_mem_copy(&profile->SSIDs.SSIDList[0].SSID.ssId,
4077 		     pconfig_params->SSIDinfo.ssid.ssId,
4078 		     sizeof(pconfig_params->SSIDinfo.ssid.ssId));
4079 
4080 	profile->negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4081 
4082 	if (pconfig_params->authType == eSAP_OPEN_SYSTEM) {
4083 		profile->negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4084 	} else if (pconfig_params->authType == eSAP_SHARED_KEY) {
4085 		profile->negotiatedAuthType = eCSR_AUTH_TYPE_SHARED_KEY;
4086 	} else {
4087 		profile->negotiatedAuthType = eCSR_AUTH_TYPE_AUTOSWITCH;
4088 	}
4089 
4090 	profile->AuthType.numEntries = 1;
4091 	profile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4092 
4093 	/* Always set the Encryption Type */
4094 	profile->EncryptionType.numEntries = 1;
4095 	profile->EncryptionType.encryptionType[0] =
4096 		pconfig_params->RSNEncryptType;
4097 
4098 	profile->mcEncryptionType.numEntries = 1;
4099 	profile->mcEncryptionType.encryptionType[0] =
4100 		pconfig_params->mcRSNEncryptType;
4101 
4102 	if (pconfig_params->privacy & eSAP_SHARED_KEY) {
4103 		profile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY;
4104 	}
4105 
4106 	profile->privacy = pconfig_params->privacy;
4107 	profile->fwdWPSPBCProbeReq = pconfig_params->fwdWPSPBCProbeReq;
4108 
4109 	if (pconfig_params->authType == eSAP_SHARED_KEY) {
4110 		profile->csr80211AuthType = eSIR_SHARED_KEY;
4111 	} else if (pconfig_params->authType == eSAP_OPEN_SYSTEM) {
4112 		profile->csr80211AuthType = eSIR_OPEN_SYSTEM;
4113 	} else {
4114 		profile->csr80211AuthType = eSIR_AUTO_SWITCH;
4115 	}
4116 
4117 	/* Initialize we are not going to use it */
4118 	profile->pWPAReqIE = NULL;
4119 	profile->nWPAReqIELength = 0;
4120 
4121 	/* set the RSN/WPA IE */
4122 	profile->pRSNReqIE = NULL;
4123 	profile->nRSNReqIELength = pconfig_params->RSNWPAReqIELength;
4124 	if (pconfig_params->RSNWPAReqIELength) {
4125 		profile->pRSNReqIE =
4126 			qdf_mem_malloc(pconfig_params->RSNWPAReqIELength);
4127 		if (NULL == profile->pRSNReqIE) {
4128 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4129 				  " %s Fail to alloc memory", __func__);
4130 			return eSAP_STATUS_FAILURE;
4131 		}
4132 		qdf_mem_copy(profile->pRSNReqIE, pconfig_params->RSNWPAReqIE,
4133 			     pconfig_params->RSNWPAReqIELength);
4134 		profile->nRSNReqIELength = pconfig_params->RSNWPAReqIELength;
4135 	}
4136 	/* Turn off CB mode */
4137 	profile->CBMode = eCSR_CB_OFF;
4138 
4139 	/* set the phyMode to accept anything */
4140 	/* Best means everything because it covers all the things we support */
4141 	/* eCSR_DOT11_MODE_BEST */
4142 	profile->phyMode = pconfig_params->SapHw_mode;
4143 
4144 	/* Configure beaconInterval */
4145 	profile->beaconInterval = (uint16_t) pconfig_params->beacon_int;
4146 
4147 	/* set DTIM period */
4148 	profile->dtimPeriod = pconfig_params->dtim_period;
4149 
4150 	/* set Uapsd enable bit */
4151 	profile->ApUapsdEnable = pconfig_params->UapsdEnable;
4152 
4153 	/* Enable protection parameters */
4154 	profile->protEnabled = pconfig_params->protEnabled;
4155 	profile->obssProtEnabled = pconfig_params->obssProtEnabled;
4156 	profile->cfg_protection = pconfig_params->ht_capab;
4157 
4158 	/* country code */
4159 	if (pconfig_params->countryCode[0])
4160 		qdf_mem_copy(profile->countryCode, pconfig_params->countryCode,
4161 			     WNI_CFG_COUNTRY_CODE_LEN);
4162 	profile->ieee80211d = pconfig_params->ieee80211d;
4163 	/* wps config info */
4164 	profile->wps_state = pconfig_params->wps_state;
4165 
4166 #ifdef WLAN_FEATURE_11W
4167 	/* MFP capable/required */
4168 	profile->MFPCapable = pconfig_params->mfpCapable ? 1 : 0;
4169 	profile->MFPRequired = pconfig_params->mfpRequired ? 1 : 0;
4170 #endif
4171 
4172 	if (pconfig_params->probeRespIEsBufferLen > 0 &&
4173 	    pconfig_params->pProbeRespIEsBuffer != NULL) {
4174 		profile->addIeParams.probeRespDataLen =
4175 			pconfig_params->probeRespIEsBufferLen;
4176 		profile->addIeParams.probeRespData_buff =
4177 			pconfig_params->pProbeRespIEsBuffer;
4178 	} else {
4179 		profile->addIeParams.probeRespDataLen = 0;
4180 		profile->addIeParams.probeRespData_buff = NULL;
4181 	}
4182 	/*assoc resp IE */
4183 	if (pconfig_params->assocRespIEsLen > 0 &&
4184 	    pconfig_params->pAssocRespIEsBuffer != NULL) {
4185 		profile->addIeParams.assocRespDataLen =
4186 			pconfig_params->assocRespIEsLen;
4187 		profile->addIeParams.assocRespData_buff =
4188 			pconfig_params->pAssocRespIEsBuffer;
4189 	} else {
4190 		profile->addIeParams.assocRespDataLen = 0;
4191 		profile->addIeParams.assocRespData_buff = NULL;
4192 	}
4193 
4194 	if (pconfig_params->probeRespBcnIEsLen > 0 &&
4195 	    pconfig_params->pProbeRespBcnIEsBuffer != NULL) {
4196 		profile->addIeParams.probeRespBCNDataLen =
4197 			pconfig_params->probeRespBcnIEsLen;
4198 		profile->addIeParams.probeRespBCNData_buff =
4199 			pconfig_params->pProbeRespBcnIEsBuffer;
4200 	} else {
4201 		profile->addIeParams.probeRespBCNDataLen = 0;
4202 		profile->addIeParams.probeRespBCNData_buff = NULL;
4203 	}
4204 	profile->sap_dot11mc = pconfig_params->sap_dot11mc;
4205 
4206 	return eSAP_STATUS_SUCCESS;     /* Success. */
4207 }
4208 
4209 void sap_free_roam_profile(tCsrRoamProfile *profile)
4210 {
4211 	if (profile->pRSNReqIE) {
4212 		qdf_mem_free(profile->pRSNReqIE);
4213 		profile->pRSNReqIE = NULL;
4214 	}
4215 }
4216 
4217 void sap_sort_mac_list(struct qdf_mac_addr *macList, uint8_t size)
4218 {
4219 	uint8_t outer, inner;
4220 	struct qdf_mac_addr temp;
4221 	int32_t nRes = -1;
4222 
4223 	if ((NULL == macList) || (size > MAX_ACL_MAC_ADDRESS)) {
4224 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4225 			FL("either buffer is NULL or size = %d is more"), size);
4226 		return;
4227 	}
4228 
4229 	for (outer = 0; outer < size; outer++) {
4230 		for (inner = 0; inner < size - 1; inner++) {
4231 			nRes =
4232 				qdf_mem_cmp((macList + inner)->bytes,
4233 						 (macList + inner + 1)->bytes,
4234 						 QDF_MAC_ADDR_SIZE);
4235 			if (nRes > 0) {
4236 				qdf_mem_copy(temp.bytes,
4237 					     (macList + inner + 1)->bytes,
4238 					     QDF_MAC_ADDR_SIZE);
4239 				qdf_mem_copy((macList + inner + 1)->bytes,
4240 					     (macList + inner)->bytes,
4241 					     QDF_MAC_ADDR_SIZE);
4242 				qdf_mem_copy((macList + inner)->bytes,
4243 					     temp.bytes, QDF_MAC_ADDR_SIZE);
4244 			}
4245 		}
4246 	}
4247 }
4248 
4249 eSapBool
4250 sap_search_mac_list(struct qdf_mac_addr *macList,
4251 		    uint8_t num_mac, uint8_t *peerMac,
4252 		    uint8_t *index)
4253 {
4254 	int32_t nRes = -1;
4255 	int8_t nStart = 0, nEnd, nMiddle;
4256 	nEnd = num_mac - 1;
4257 
4258 	if ((NULL == macList) || (num_mac > MAX_ACL_MAC_ADDRESS)) {
4259 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4260 		    FL("either buffer is NULL or size = %d is more."), num_mac);
4261 		return eSAP_FALSE;
4262 	}
4263 
4264 	while (nStart <= nEnd) {
4265 		nMiddle = (nStart + nEnd) / 2;
4266 		nRes =
4267 			qdf_mem_cmp(&macList[nMiddle], peerMac,
4268 					 QDF_MAC_ADDR_SIZE);
4269 
4270 		if (0 == nRes) {
4271 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4272 				  "search SUCC");
4273 			/* "index equals NULL" means the caller does not need the */
4274 			/* index value of the peerMac being searched */
4275 			if (index != NULL) {
4276 				*index = (uint8_t) nMiddle;
4277 				QDF_TRACE(QDF_MODULE_ID_SAP,
4278 					  QDF_TRACE_LEVEL_INFO_HIGH, "index %d",
4279 					  *index);
4280 			}
4281 			return eSAP_TRUE;
4282 		}
4283 		if (nRes < 0)
4284 			nStart = nMiddle + 1;
4285 		else
4286 			nEnd = nMiddle - 1;
4287 	}
4288 
4289 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4290 		  "search not succ");
4291 	return eSAP_FALSE;
4292 }
4293 
4294 void sap_add_mac_to_acl(struct qdf_mac_addr *macList,
4295 			uint8_t *size, uint8_t *peerMac)
4296 {
4297 	int32_t nRes = -1;
4298 	int i;
4299 
4300 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4301 		  "add acl entered");
4302 
4303 	if (NULL == macList || *size == 0 || *size > MAX_ACL_MAC_ADDRESS) {
4304 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4305 			FL("either buffer is NULL or size = %d is incorrect."),
4306 			*size);
4307 		return;
4308 	}
4309 
4310 	for (i = ((*size) - 1); i >= 0; i--) {
4311 		nRes =
4312 			qdf_mem_cmp(&macList[i], peerMac, QDF_MAC_ADDR_SIZE);
4313 		if (nRes > 0) {
4314 			/* Move alphabetically greater mac addresses one index down to allow for insertion
4315 			   of new mac in sorted order */
4316 			qdf_mem_copy((macList + i + 1)->bytes,
4317 				     (macList + i)->bytes, QDF_MAC_ADDR_SIZE);
4318 		} else {
4319 			break;
4320 		}
4321 	}
4322 	/* This should also take care of if the element is the first to be added in the list */
4323 	qdf_mem_copy((macList + i + 1)->bytes, peerMac, QDF_MAC_ADDR_SIZE);
4324 	/* increment the list size */
4325 	(*size)++;
4326 }
4327 
4328 void sap_remove_mac_from_acl(struct qdf_mac_addr *macList,
4329 			     uint8_t *size, uint8_t index)
4330 {
4331 	int i;
4332 
4333 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4334 		  "remove acl entered");
4335 	/*
4336 	 * Return if the list passed is empty. Ideally this should never happen
4337 	 * since this funcn is always called after sap_search_mac_list to get
4338 	 * the index of the mac addr to be removed and this will only get
4339 	 * called if the search is successful. Still no harm in having the check
4340 	 */
4341 	if ((macList == NULL) || (*size == 0) ||
4342 					(*size > MAX_ACL_MAC_ADDRESS)) {
4343 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4344 			FL("either buffer is NULL or size %d is incorrect."),
4345 			*size);
4346 		return;
4347 	}
4348 	for (i = index; i < ((*size) - 1); i++) {
4349 		/* Move mac addresses starting from "index" passed one index up to delete the void
4350 		   created by deletion of a mac address in ACL */
4351 		qdf_mem_copy((macList + i)->bytes, (macList + i + 1)->bytes,
4352 			     QDF_MAC_ADDR_SIZE);
4353 	}
4354 	/* The last space should be made empty since all mac addesses moved one step up */
4355 	qdf_mem_zero((macList + (*size) - 1)->bytes, QDF_MAC_ADDR_SIZE);
4356 	/* reduce the list size by 1 */
4357 	(*size)--;
4358 }
4359 
4360 void sap_print_acl(struct qdf_mac_addr *macList, uint8_t size)
4361 {
4362 	int i;
4363 	uint8_t *macArray;
4364 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4365 		  "print acl entered");
4366 
4367 	if ((NULL == macList) || (size == 0) || (size >= MAX_ACL_MAC_ADDRESS)) {
4368 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4369 			  "In %s, either buffer is NULL or size %d is incorrect.",
4370 			  __func__, size);
4371 		return;
4372 	}
4373 
4374 	for (i = 0; i < size; i++) {
4375 		macArray = (macList + i)->bytes;
4376 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4377 			  "** ACL entry %i - " MAC_ADDRESS_STR, i,
4378 			  MAC_ADDR_ARRAY(macArray));
4379 	}
4380 	return;
4381 }
4382 
4383 QDF_STATUS sap_is_peer_mac_allowed(ptSapContext sapContext, uint8_t *peerMac)
4384 {
4385 	if (eSAP_ALLOW_ALL == sapContext->eSapMacAddrAclMode)
4386 		return QDF_STATUS_SUCCESS;
4387 
4388 	if (sap_search_mac_list
4389 		    (sapContext->acceptMacList, sapContext->nAcceptMac, peerMac, NULL))
4390 		return QDF_STATUS_SUCCESS;
4391 
4392 	if (sap_search_mac_list
4393 		    (sapContext->denyMacList, sapContext->nDenyMac, peerMac, NULL)) {
4394 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4395 			  "In %s, Peer " MAC_ADDRESS_STR " in deny list",
4396 			  __func__, MAC_ADDR_ARRAY(peerMac));
4397 		return QDF_STATUS_E_FAILURE;
4398 	}
4399 	/* A new station CAN associate, unless in deny list. Less stringent mode */
4400 	if (eSAP_ACCEPT_UNLESS_DENIED == sapContext->eSapMacAddrAclMode)
4401 		return QDF_STATUS_SUCCESS;
4402 
4403 	/* A new station CANNOT associate, unless in accept list. More stringent mode */
4404 	if (eSAP_DENY_UNLESS_ACCEPTED == sapContext->eSapMacAddrAclMode) {
4405 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4406 			  "In %s, Peer " MAC_ADDRESS_STR
4407 			  " denied, Mac filter mode is eSAP_DENY_UNLESS_ACCEPTED",
4408 			  __func__, MAC_ADDR_ARRAY(peerMac));
4409 		return QDF_STATUS_E_FAILURE;
4410 	}
4411 
4412 	/* The new STA is neither in accept list nor in deny list. In this case, deny the association
4413 	 * but send a wifi event notification indicating the mac address being denied
4414 	 */
4415 	if (eSAP_SUPPORT_ACCEPT_AND_DENY == sapContext->eSapMacAddrAclMode) {
4416 		sap_signal_hdd_event(sapContext, NULL, eSAP_UNKNOWN_STA_JOIN,
4417 				     (void *) peerMac);
4418 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
4419 			  "In %s, Peer " MAC_ADDRESS_STR
4420 			  " denied, Mac filter mode is eSAP_SUPPORT_ACCEPT_AND_DENY",
4421 			  __func__, MAC_ADDR_ARRAY(peerMac));
4422 		return QDF_STATUS_E_FAILURE;
4423 	}
4424 	return QDF_STATUS_SUCCESS;
4425 }
4426 
4427 #ifdef SOFTAP_CHANNEL_RANGE
4428 /**
4429  * sap_get_channel_list() - get the list of channels
4430  * @sap_ctx: sap context
4431  * @ch_list: pointer to channel list array
4432  * @num_ch: pointer to number of channels.
4433  *
4434  * This function populates the list of channels for scanning.
4435  *
4436  * Return: QDF_STATUS
4437  */
4438 static QDF_STATUS sap_get_channel_list(ptSapContext sap_ctx,
4439 				       uint8_t **ch_list,
4440 				       uint8_t *num_ch)
4441 {
4442 	uint8_t loop_count;
4443 	uint8_t *list;
4444 	uint8_t ch_count;
4445 	uint8_t start_ch_num, band_start_ch;
4446 	uint8_t end_ch_num, band_end_ch;
4447 	uint32_t en_lte_coex;
4448 	tHalHandle hal = CDS_GET_HAL_CB(sap_ctx->p_cds_gctx);
4449 #ifdef FEATURE_WLAN_CH_AVOID
4450 	uint8_t i;
4451 #endif
4452 	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
4453 
4454 	if (NULL == hal) {
4455 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4456 			FL("Invalid HAL pointer from p_cds_gctx"));
4457 		*num_ch = 0;
4458 		*ch_list = NULL;
4459 		return QDF_STATUS_E_FAULT;
4460 	}
4461 
4462 	start_ch_num = sap_ctx->acs_cfg->start_ch;
4463 	end_ch_num = sap_ctx->acs_cfg->end_ch;
4464 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
4465 			FL("startChannel %d, EndChannel %d, HW:%d"),
4466 			start_ch_num, end_ch_num,
4467 			sap_ctx->acs_cfg->hw_mode);
4468 
4469 	wlansap_extend_to_acs_range(&start_ch_num, &end_ch_num,
4470 					    &band_start_ch, &band_end_ch);
4471 
4472 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
4473 			  FL("expanded startChannel %d,EndChannel %d"),
4474 			  start_ch_num, end_ch_num);
4475 
4476 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
4477 			  FL("band_start_ch %d, band_end_ch %d"),
4478 			  band_start_ch, band_end_ch);
4479 
4480 	sme_cfg_get_int(hal, WNI_CFG_ENABLE_LTE_COEX, &en_lte_coex);
4481 
4482 	/* Check if LTE coex is enabled and 2.4GHz is selected */
4483 	if (en_lte_coex && (band_start_ch == CHAN_ENUM_1) &&
4484 	    (band_end_ch == CHAN_ENUM_14)) {
4485 		/* Set 2.4GHz upper limit to channel 9 for LTE COEX */
4486 		band_end_ch = CHAN_ENUM_9;
4487 	}
4488 
4489 	/* Allocate the max number of channel supported */
4490 	list = (uint8_t *) qdf_mem_malloc(NUM_5GHZ_CHANNELS +
4491 						NUM_24GHZ_CHANNELS);
4492 	if (NULL == list) {
4493 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4494 			  FL("Unable to allocate channel list"));
4495 		*num_ch = 0;
4496 		*ch_list = NULL;
4497 		return QDF_STATUS_E_NOMEM;
4498 	}
4499 
4500 	/* Search for the Active channels in the given range */
4501 	ch_count = 0;
4502 	for (loop_count = band_start_ch; loop_count <= band_end_ch;
4503 	     loop_count++) {
4504 		/* go to next channel if rf_channel is out of range */
4505 		if ((start_ch_num > CDS_CHANNEL_NUM(loop_count)) ||
4506 		    (end_ch_num < CDS_CHANNEL_NUM(loop_count)))
4507 			continue;
4508 		/*
4509 		 * go to next channel if none of these condition pass
4510 		 * - DFS scan enabled and chan not in CHANNEL_STATE_DISABLE
4511 		 * - DFS scan disable but chan in CHANNEL_STATE_ENABLE
4512 		 */
4513 		if (!(((eSAP_TRUE == mac_ctx->scan.fEnableDFSChnlScan) &&
4514 		      CDS_CHANNEL_STATE(loop_count)) ||
4515 		    ((eSAP_FALSE == mac_ctx->scan.fEnableDFSChnlScan) &&
4516 		     (CHANNEL_STATE_ENABLE ==
4517 		      CDS_CHANNEL_STATE(loop_count)))))
4518 			continue;
4519 
4520 #ifdef FEATURE_WLAN_CH_AVOID
4521 		for (i = 0; i < NUM_CHANNELS; i++) {
4522 			if ((safe_channels[i].channelNumber ==
4523 			     CDS_CHANNEL_NUM(loop_count))) {
4524 				/* Check if channel is safe */
4525 				if (true == safe_channels[i].isSafe) {
4526 #endif
4527 #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
4528 		uint8_t ch;
4529 		ch = CDS_CHANNEL_NUM(loop_count);
4530 		if ((sap_ctx->acs_cfg->skip_scan_status ==
4531 			eSAP_DO_PAR_ACS_SCAN)) {
4532 		    if ((ch >= sap_ctx->acs_cfg->skip_scan_range1_stch &&
4533 			 ch <= sap_ctx->acs_cfg->skip_scan_range1_endch) ||
4534 			(ch >= sap_ctx->acs_cfg->skip_scan_range2_stch &&
4535 			 ch <= sap_ctx->acs_cfg->skip_scan_range2_endch)) {
4536 			list[ch_count] =
4537 				CDS_CHANNEL_NUM(loop_count);
4538 			ch_count++;
4539 			QDF_TRACE(QDF_MODULE_ID_SAP,
4540 				QDF_TRACE_LEVEL_INFO,
4541 				FL("%d %d added to ACS ch range"),
4542 				ch_count, ch);
4543 		    } else {
4544 			QDF_TRACE(QDF_MODULE_ID_SAP,
4545 				QDF_TRACE_LEVEL_INFO_HIGH,
4546 				FL("%d %d skipped from ACS ch range"),
4547 				ch_count, ch);
4548 		    }
4549 		} else {
4550 			list[ch_count] =
4551 				CDS_CHANNEL_NUM(loop_count);
4552 			ch_count++;
4553 			QDF_TRACE(QDF_MODULE_ID_SAP,
4554 				QDF_TRACE_LEVEL_INFO,
4555 				FL("%d %d added to ACS ch range"),
4556 				ch_count, ch);
4557 		}
4558 #else
4559 		list[ch_count] = CDS_CHANNEL_NUM(loop_count);
4560 		ch_count++;
4561 #endif
4562 #ifdef FEATURE_WLAN_CH_AVOID
4563 				}
4564 				break;
4565 			}
4566 		}
4567 #endif
4568 	}
4569 	if (0 == ch_count) {
4570 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4571 		    FL("No active channels present for the current region"));
4572 		/*
4573 		 * LTE COEX: channel range outside the restricted 2.4GHz
4574 		 * band limits
4575 		 */
4576 		if (en_lte_coex && (start_ch_num > band_end_ch))
4577 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
4578 				FL("SAP can't be started as due to LTE COEX"));
4579 	}
4580 
4581 	/* return the channel list and number of channels to scan */
4582 	*num_ch = ch_count;
4583 	if (ch_count != 0) {
4584 		*ch_list = list;
4585 	} else {
4586 		*ch_list = NULL;
4587 		qdf_mem_free(list);
4588 	}
4589 
4590 	for (loop_count = 0; loop_count < ch_count; loop_count++) {
4591 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
4592 			FL("channel number: %d"), list[loop_count]);
4593 	}
4594 	return QDF_STATUS_SUCCESS;
4595 }
4596 #endif
4597 
4598 /*
4599  * Function for initializing list of  2.4/5 Ghz [NON-DFS/DFS]
4600  * available channels in the current regulatory domain.
4601  */
4602 static QDF_STATUS sap_get_5ghz_channel_list(ptSapContext sapContext)
4603 {
4604 	uint8_t count = 0;
4605 	int i;
4606 	struct sir_pcl_list pcl;
4607 	QDF_STATUS status;
4608 	enum channel_state ch_state;
4609 	pcl.pcl_len = 0;
4610 	if (NULL == sapContext) {
4611 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4612 			  "Invalid sapContext pointer on sap_get_channel_list");
4613 		return QDF_STATUS_E_FAULT;
4614 	}
4615 
4616 	if (sapContext->SapAllChnlList.channelList) {
4617 		qdf_mem_free(sapContext->SapAllChnlList.channelList);
4618 		sapContext->SapAllChnlList.channelList = NULL;
4619 	}
4620 
4621 	sapContext->SapAllChnlList.channelList =
4622 		(tChannelInfo *) qdf_mem_malloc(WNI_CFG_VALID_CHANNEL_LIST_LEN *
4623 						sizeof(tChannelInfo));
4624 	if (NULL == sapContext->SapAllChnlList.channelList) {
4625 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4626 			  " Memory Allocation failed sap_get_channel_list");
4627 		return QDF_STATUS_E_NOMEM;
4628 	}
4629 
4630 	status = cds_get_pcl_for_existing_conn(CDS_SAP_MODE,
4631 			pcl.pcl_list, &pcl.pcl_len,
4632 			pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list));
4633 	if (status != QDF_STATUS_SUCCESS) {
4634 		cds_err("Get PCL failed");
4635 		return status;
4636 	}
4637 	for (i = 0; i <= pcl.pcl_len; i++) {
4638 		if (CDS_IS_CHANNEL_5GHZ(pcl.pcl_list[i])) {
4639 			ch_state = cds_get_channel_state(pcl.pcl_list[i]);
4640 			if (!(ch_state == CHANNEL_STATE_ENABLE ||
4641 				ch_state == CHANNEL_STATE_DFS))
4642 				continue;
4643 			sapContext->SapAllChnlList.channelList[count].channel =
4644 				pcl.pcl_list[i];
4645 			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
4646 				  "%s[%d] CHANNEL = %d", __func__, __LINE__,
4647 				  pcl.pcl_list[i]);
4648 			sapContext->SapAllChnlList.channelList[count].valid =
4649 				true;
4650 			count++;
4651 		}
4652 	}
4653 
4654 	sapContext->SapAllChnlList.numChannel = count;
4655 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
4656 		  "%s[%d] NUMBER OF CHANNELS count = %d"
4657 		  "sapContext->SapAllChnlList.numChannel = %d",
4658 		  __func__, __LINE__, count,
4659 		  sapContext->SapAllChnlList.numChannel);
4660 	return QDF_STATUS_SUCCESS;
4661 }
4662 
4663 /*
4664  * This function randomly selects the channel to switch after the detection
4665  * of radar
4666  * param sapContext - sap context
4667  * dfs_event - Dfs information from DFS
4668  * return - channel to which AP wishes to switch
4669  */
4670 uint8_t sap_indicate_radar(ptSapContext sapContext,
4671 			   tSirSmeDfsEventInd *dfs_event)
4672 {
4673 	uint8_t target_channel = 0;
4674 	tHalHandle hHal;
4675 	tpAniSirGlobal pMac;
4676 
4677 	if (NULL == sapContext || NULL == dfs_event) {
4678 		/* Invalid sap context of dfs event passed */
4679 		return 0;
4680 	}
4681 	hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx);
4682 
4683 	if (NULL == hHal) {
4684 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4685 			  "In %s invalid hHal", __func__);
4686 		return 0;
4687 	}
4688 	pMac = PMAC_STRUCT(hHal);
4689 
4690 	if (!dfs_event->dfs_radar_status) {
4691 		/*dfs status does not indicate a radar on the channel-- False Alarm */
4692 		return 0;
4693 	}
4694 
4695 	/*
4696 	 * SAP needs to generate Channel Switch IE
4697 	 * if the radar is found in the STARTED state
4698 	 */
4699 	if (eSAP_STARTED == sapContext->sapsMachine)
4700 		pMac->sap.SapDfsInfo.csaIERequired = eSAP_TRUE;
4701 
4702 	if (sapContext->csr_roamProfile.disableDFSChSwitch) {
4703 		return sapContext->channel;
4704 	}
4705 
4706 	/* set the Radar Found flag in SapDfsInfo */
4707 	pMac->sap.SapDfsInfo.sap_radar_found_status = true;
4708 
4709 	if (dfs_event->chan_list.nchannels > SIR_DFS_MAX_20M_SUB_CH) {
4710 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN,
4711 			  FL("nchannels >SIR_DFS_MAX_20M_SUB_CH so resetting"));
4712 		dfs_event->chan_list.nchannels = SIR_DFS_MAX_20M_SUB_CH;
4713 	}
4714 
4715 	sap_mark_dfs_channels(sapContext, dfs_event->chan_list.channels,
4716 			      dfs_event->chan_list.nchannels,
4717 			      cds_get_monotonic_boottime());
4718 
4719 	if (sapContext->chan_before_pre_cac) {
4720 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
4721 			FL("sapdfs: set chan before pre cac %d as target chan"),
4722 			sapContext->chan_before_pre_cac);
4723 		return sapContext->chan_before_pre_cac;
4724 	}
4725 
4726 	/*
4727 	 * (1) skip static turbo channel as it will require STA to be in
4728 	 * static turbo to work.
4729 	 * (2) skip channel which's marked with radar detction
4730 	 * (3) WAR: we allow user to config not to use any DFS channel
4731 	 * (4) When we pick a channel, skip excluded 11D channels
4732 	 * (5) Create the available channel list with the above rules
4733 	 */
4734 
4735 	target_channel = sap_random_channel_sel(sapContext);
4736 	if (0 == target_channel) {
4737 		sap_signal_hdd_event(sapContext, NULL,
4738 				     eSAP_DFS_NO_AVAILABLE_CHANNEL,
4739 				     (void *) eSAP_STATUS_SUCCESS);
4740 	}
4741 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN,
4742 		  FL("sapdfs: New selected target channel is [%d]"),
4743 		  target_channel);
4744 	return target_channel;
4745 }
4746 
4747 /*
4748  * CAC timer callback function.
4749  * Post eSAP_DFS_CHANNEL_CAC_END event to sap_fsm().
4750  */
4751 void sap_dfs_cac_timer_callback(void *data)
4752 {
4753 	ptSapContext sapContext;
4754 	tWLAN_SAPEvent sapEvent;
4755 	tHalHandle hHal = (tHalHandle) data;
4756 	tpAniSirGlobal pMac;
4757 
4758 	if (NULL == hHal) {
4759 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4760 			  "In %s invalid hHal", __func__);
4761 		return;
4762 	}
4763 	pMac = PMAC_STRUCT(hHal);
4764 	sapContext = sap_find_cac_wait_session(hHal);
4765 	if (NULL == sapContext) {
4766 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4767 			"%s: no SAP contexts in wait state", __func__);
4768 		return;
4769 	}
4770 
4771 	/*
4772 	 * SAP may not be in CAC wait state, when the timer runs out.
4773 	 * if following flag is set, then timer is in initialized state,
4774 	 * destroy timer here.
4775 	 */
4776 	if (pMac->sap.SapDfsInfo.is_dfs_cac_timer_running == true) {
4777 		qdf_mc_timer_destroy(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer);
4778 		pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = false;
4779 	}
4780 
4781 	/*
4782 	 * CAC Complete, post eSAP_DFS_CHANNEL_CAC_END to sap_fsm
4783 	 */
4784 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
4785 			"sapdfs: Sending eSAP_DFS_CHANNEL_CAC_END for target_channel = %d on sapctx[%p]",
4786 			sapContext->channel, sapContext);
4787 
4788 	sapEvent.event = eSAP_DFS_CHANNEL_CAC_END;
4789 	sapEvent.params = 0;
4790 	sapEvent.u1 = 0;
4791 	sapEvent.u2 = 0;
4792 
4793 	sap_fsm(sapContext, &sapEvent);
4794 }
4795 
4796 /*
4797  * Function to stop the DFS CAC Timer
4798  */
4799 static int sap_stop_dfs_cac_timer(ptSapContext sapContext)
4800 {
4801 	tHalHandle hHal;
4802 	tpAniSirGlobal pMac;
4803 	if (sapContext == NULL)
4804 		return 0;
4805 
4806 	hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx);
4807 	if (NULL == hHal) {
4808 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4809 			  "In %s invalid hHal", __func__);
4810 		return 0;
4811 	}
4812 	pMac = PMAC_STRUCT(hHal);
4813 
4814 	if (QDF_TIMER_STATE_RUNNING !=
4815 	    qdf_mc_timer_get_current_state(&pMac->sap.SapDfsInfo.
4816 					   sap_dfs_cac_timer)) {
4817 		return 0;
4818 	}
4819 
4820 	qdf_mc_timer_stop(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer);
4821 	pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
4822 	qdf_mc_timer_destroy(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer);
4823 
4824 	return 0;
4825 }
4826 
4827 
4828 /**
4829  * sap_is_channel_bonding_etsi_weather_channel() - check weather chan bonding.
4830  * @sap_context:                                   SAP context
4831  *
4832  * Check if the current SAP operating channel is bonded to weather radar
4833  * channel in ETSI domain.
4834  *
4835  * Return: True if bonded to weather channel in ETSI
4836  */
4837 static bool
4838 sap_is_channel_bonding_etsi_weather_channel(ptSapContext sap_context)
4839 {
4840 	if (IS_CH_BONDING_WITH_WEATHER_CH(sap_context->channel) &&
4841 	  (sap_context->ch_params.ch_width != CH_WIDTH_20MHZ))
4842 		return true;
4843 
4844 	return false;
4845 }
4846 
4847 /*
4848  * Function to start the DFS CAC Timer
4849  * when SAP is started on a DFS channel
4850  */
4851 int sap_start_dfs_cac_timer(ptSapContext sapContext)
4852 {
4853 	QDF_STATUS status;
4854 	uint32_t cacTimeOut;
4855 	tHalHandle hHal = NULL;
4856 	tpAniSirGlobal pMac = NULL;
4857 	enum dfs_region dfs_region;
4858 
4859 	if (sapContext == NULL) {
4860 		return 0;
4861 	}
4862 	hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx);
4863 
4864 	if (NULL == hHal) {
4865 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4866 			  "In %s invalid hHal", __func__);
4867 		return 0;
4868 	}
4869 	pMac = PMAC_STRUCT(hHal);
4870 
4871 	if (pMac->sap.SapDfsInfo.ignore_cac) {
4872 		/*
4873 		 * If User has set to ignore the CAC
4874 		 * so, continue without CAC Timer.
4875 		 */
4876 		return 2;
4877 	}
4878 	cacTimeOut = DEFAULT_CAC_TIMEOUT;
4879 
4880 	cds_get_dfs_region(&dfs_region);
4881 
4882 	if ((dfs_region == DFS_ETSI_REGION)
4883 	    && ((IS_ETSI_WEATHER_CH(sapContext->channel)) ||
4884 		(sap_is_channel_bonding_etsi_weather_channel(sapContext)))) {
4885 		cacTimeOut = ETSI_WEATHER_CH_CAC_TIMEOUT;
4886 	}
4887 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED,
4888 		  "sapdfs: SAP_DFS_CHANNEL_CAC_START on CH - %d, CAC TIMEOUT - %d sec",
4889 		  sapContext->channel, cacTimeOut / 1000);
4890 
4891 	qdf_mc_timer_init(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer,
4892 			  QDF_TIMER_TYPE_SW,
4893 			  sap_dfs_cac_timer_callback, (void *) hHal);
4894 
4895 	/*Start the CAC timer */
4896 	status =
4897 		qdf_mc_timer_start(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer,
4898 				   cacTimeOut);
4899 	if (status == QDF_STATUS_SUCCESS) {
4900 		pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = true;
4901 		return 1;
4902 	} else {
4903 		pMac->sap.SapDfsInfo.is_dfs_cac_timer_running = false;
4904 		qdf_mc_timer_destroy(&pMac->sap.SapDfsInfo.sap_dfs_cac_timer);
4905 		return 0;
4906 	}
4907 }
4908 
4909 /*
4910  * This function initializes the NOL list
4911  * parameters required to track the radar
4912  * found DFS channels in the current Reg. Domain .
4913  */
4914 QDF_STATUS sap_init_dfs_channel_nol_list(ptSapContext sapContext)
4915 {
4916 	uint8_t count = 0;
4917 	int i;
4918 	bool bFound = false;
4919 	tHalHandle hHal;
4920 	tpAniSirGlobal pMac;
4921 
4922 	if (NULL == sapContext) {
4923 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4924 			  "Invalid sapContext pointer on sap_init_dfs_channel_nol_list");
4925 		return QDF_STATUS_E_FAULT;
4926 	}
4927 	hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx);
4928 
4929 	if (NULL == hHal) {
4930 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
4931 			  "In %s invalid hHal", __func__);
4932 		return QDF_STATUS_E_FAULT;
4933 	}
4934 	pMac = PMAC_STRUCT(hHal);
4935 
4936 	/* to indicate hdd to get cnss dfs nol */
4937 	if (QDF_STATUS_SUCCESS == sap_signal_hdd_event(sapContext, NULL,
4938 						       eSAP_DFS_NOL_GET,
4939 						       (void *)
4940 						       eSAP_STATUS_SUCCESS)) {
4941 		bFound = true;
4942 	}
4943 
4944 	for (i = CHAN_ENUM_36; i <= CHAN_ENUM_165; i++) {
4945 		if (CDS_CHANNEL_STATE(i) == CHANNEL_STATE_DFS) {
4946 			/* if dfs nol is not found, initialize it */
4947 			if (!bFound) {
4948 				pMac->sap.SapDfsInfo.sapDfsChannelNolList[count]
4949 				.dfs_channel_number =
4950 					CDS_CHANNEL_NUM(i);
4951 
4952 				QDF_TRACE(QDF_MODULE_ID_SAP,
4953 					  QDF_TRACE_LEVEL_INFO_LOW,
4954 					  "%s: CHANNEL = %d", __func__,
4955 					  pMac->sap.SapDfsInfo.
4956 					  sapDfsChannelNolList[count].
4957 					  dfs_channel_number);
4958 
4959 				pMac->sap.SapDfsInfo.sapDfsChannelNolList[count]
4960 				.radar_status_flag =
4961 					eSAP_DFS_CHANNEL_USABLE;
4962 				pMac->sap.SapDfsInfo.sapDfsChannelNolList[count]
4963 				.radar_found_timestamp = 0;
4964 			}
4965 			count++;
4966 		}
4967 	}
4968 
4969 	pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels = count;
4970 
4971 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW,
4972 		  "%s[%d] NUMBER OF DFS CHANNELS = %d",
4973 		  __func__, __LINE__,
4974 		  pMac->sap.SapDfsInfo.numCurrentRegDomainDfsChannels);
4975 
4976 	return QDF_STATUS_SUCCESS;
4977 }
4978 
4979 /*
4980  * This function will calculate how many interfaces
4981  * have sap persona and returns total number of sap persona.
4982  */
4983 uint8_t sap_get_total_number_sap_intf(tHalHandle hHal)
4984 {
4985 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4986 	uint8_t intf = 0;
4987 	uint8_t intf_count = 0;
4988 
4989 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
4990 		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
4991 		    ||
4992 		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona))
4993 		    && pMac->sap.sapCtxList[intf].pSapContext != NULL) {
4994 			intf_count++;
4995 		}
4996 	}
4997 	return intf_count;
4998 }
4999 
5000 /*
5001  * This function will find the concurrent sap context apart from
5002  * passed sap context and return its channel change ready status
5003  */
5004 bool is_concurrent_sap_ready_for_channel_change(tHalHandle hHal,
5005 						ptSapContext sapContext)
5006 {
5007 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5008 	ptSapContext pSapContext;
5009 	uint8_t intf = 0;
5010 
5011 	for (intf = 0; intf < SAP_MAX_NUM_SESSION; intf++) {
5012 		if (((QDF_SAP_MODE == pMac->sap.sapCtxList[intf].sapPersona)
5013 		    ||
5014 		    (QDF_P2P_GO_MODE == pMac->sap.sapCtxList[intf].sapPersona))
5015 		    && pMac->sap.sapCtxList[intf].pSapContext != NULL) {
5016 			pSapContext =
5017 				(ptSapContext) pMac->sap.sapCtxList[intf].
5018 				pSapContext;
5019 			if (pSapContext == sapContext) {
5020 				QDF_TRACE(QDF_MODULE_ID_SAP,
5021 					  QDF_TRACE_LEVEL_ERROR,
5022 					  FL("sapCtx matched [%p]"),
5023 					  sapContext);
5024 				continue;
5025 			} else {
5026 				QDF_TRACE(QDF_MODULE_ID_SAP,
5027 					  QDF_TRACE_LEVEL_ERROR,
5028 					  FL
5029 						  ("concurrent sapCtx[%p] didn't matche with [%p]"),
5030 					  pSapContext, sapContext);
5031 				return pSapContext->is_sap_ready_for_chnl_chng;
5032 			}
5033 		}
5034 	}
5035 	return false;
5036 }
5037