add MTK-combo-module,continue with commit 17f39ed917874e77e80411f33faba1b7ee8138c8
[firefly-linux-kernel-4.4.55.git] / drivers / mtk_wcn_combo / drv_wlan / wlan / mgmt / scan_fsm.c
1 /*
2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/mgmt/scan_fsm.c#1 $
3 */
4
5 /*! \file   "scan_fsm.c"
6     \brief  This file defines the state transition function for SCAN FSM.
7
8     The SCAN FSM is part of SCAN MODULE and responsible for performing basic SCAN
9     behavior as metioned in IEEE 802.11 2007 11.1.3.1 & 11.1.3.2 .
10 */
11
12 /*******************************************************************************
13 * Copyright (c) 2007 MediaTek Inc.
14 *
15 * All rights reserved. Copying, compilation, modification, distribution
16 * or any other use whatsoever of this material is strictly prohibited
17 * except in accordance with a Software License Agreement with
18 * MediaTek Inc.
19 ********************************************************************************
20 */
21
22 /*******************************************************************************
23 * LEGAL DISCLAIMER
24 *
25 * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND
26 * AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK
27 * SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE
28 * PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY
29 * DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
30 * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
31 * PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE
32 * ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY
33 * WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK
34 * SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY
35 * WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE
36 * FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO
37 * CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
38 *
39 * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
40 * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL
41 * BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT
42 * ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY
43 * BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
44 *
45 * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
46 * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT
47 * OF LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING
48 * THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN
49 * FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE
50 * (ICC).
51 ********************************************************************************
52 */
53
54 /*
55 ** $Log: scan_fsm.c $
56  *
57  * 01 20 2012 cp.wu
58  * [ALPS00096191] [MT6620 Wi-Fi][Driver][Firmware] Porting to ALPS4.0_DEV branch
59  * sync to up-to-date changes including:
60  * 1. BOW bugfix
61  * 2. XLOG
62  *
63  * 11 24 2011 wh.su
64  * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
65  * Adjust code for DBG and CONFIG_XLOG.
66  *
67  * 11 14 2011 yuche.tsai
68  * [WCXRP00001107] [Volunteer Patch][Driver] Large Network Type index assert in FW issue.
69  * Avoid possible FW assert when unload P2P module.
70  *
71  * 11 11 2011 wh.su
72  * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
73  * modify the xlog related code.
74  *
75  * 11 02 2011 wh.su
76  * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
77  * Add XLOG related code and define.
78  *
79  * 10 19 2011 yuche.tsai
80  * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch.
81  * Branch 2.1
82  * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926.
83  *
84  * 08 11 2011 cp.wu
85  * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time
86  * sparse channel detection:
87  * driver: collect sparse channel information with scan-done event
88
89  *
90  * 07 18 2011 cp.wu
91  * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search for more than one SSID in a single scanning request
92  * free mailbox message afte parsing is completed.
93  *
94  * 07 18 2011 cp.wu
95  * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search for more than one SSID in a single scanning request
96  * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID support as well as uProbeDelay in NDIS 6.x driver model
97  *
98  * 04 18 2011 terry.wu
99  * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
100  * Remove flag CFG_WIFI_DIRECT_MOVED.
101  *
102  * 03 29 2011 cp.wu
103  * [WCXRP00000604] [MT6620 Wi-Fi][Driver] Surpress Klockwork Warning
104  * surpress klock warning with code path rewritten
105  *
106  * 03 18 2011 cp.wu
107  * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver
108  * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk
109  *
110  * 03 18 2011 cm.chang
111  * [WCXRP00000576] [MT6620 Wi-Fi][Driver][FW] Remove P2P compile option in scan req/cancel command
112  * As CR title
113  *
114  * 02 18 2011 yuche.tsai
115  * [WCXRP00000478] [Volunteer Patch][MT6620][Driver] Probe request frame during search phase do not contain P2P wildcard SSID.
116  * Take P2P wildcard SSID into consideration.
117  *
118  * 01 27 2011 yuche.tsai
119  * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate.
120  * Fix scan channel extension issue when p2p module is not registered.
121  *
122  * 01 26 2011 yuche.tsai
123  * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
124  * .
125  *
126  * 01 25 2011 yuche.tsai
127  * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
128  * Fix Compile Error when DBG is disabled.
129  *
130  * 12 07 2010 cm.chang
131  * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant
132  * 1. Country code is from NVRAM or supplicant
133  * 2. Change band definition in CMD/EVENT.
134  *
135  * 09 03 2010 kevin.huang
136  * NULL
137  * Refine #include sequence and solve recursive/nested #include issue
138  *
139  * 08 30 2010 cp.wu
140  * NULL
141  * eliminate klockwork errors
142  *
143  * 08 16 2010 cp.wu
144  * NULL
145  * add interface for RLM to trigger OBSS-SCAN.
146  *
147  * 08 16 2010 yuche.tsai
148  * NULL
149  * Fix bug for processing queued scan request.
150  *
151  * 08 11 2010 yuche.tsai
152  * NULL
153  * Add a function for returning channel.
154  *
155  * 08 05 2010 yuche.tsai
156  * NULL
157  * Update SCAN FSM for support P2P Device discovery scan.
158  *
159  * 08 03 2010 cp.wu
160  * NULL
161  * surpress compilation warning.
162  *
163  * 07 26 2010 yuche.tsai
164  *
165  * Add option of channel extension while cancelling scan request.
166  *
167  * 07 21 2010 yuche.tsai
168  *
169  * Add P2P Scan & Scan Result Parsing & Saving.
170  *
171  * 07 20 2010 cp.wu
172  *
173  * pass band information for scan in an efficient way by mapping ENUM_BAND_T into UINT_8..
174  *
175  * 07 19 2010 cp.wu
176  *
177  * due to FW/DRV won't be sync. precisely, some strict assertions should be eased.
178  *
179  * 07 19 2010 cp.wu
180  *
181  * [WPD00003833] [MT6620 and MT5931] Driver migration.
182  * SCN module is now able to handle multiple concurrent scanning requests
183  *
184  * 07 16 2010 cp.wu
185  *
186  * [WPD00003833] [MT6620 and MT5931] Driver migration.
187  * bugfix for SCN migration
188  * 1) modify QUEUE_CONCATENATE_QUEUES() so it could be used to concatence with an empty queue
189  * 2) before AIS issues scan request, network(BSS) needs to be activated first
190  * 3) only invoke COPY_SSID when using specified SSID for scan
191  *
192  * 07 15 2010 cp.wu
193  *
194  * [WPD00003833] [MT6620 and MT5931] Driver migration.
195  * driver no longer generates probe request frames
196  *
197  * 07 14 2010 cp.wu
198  *
199  * [WPD00003833] [MT6620 and MT5931] Driver migration.
200  * pass band with channel number information as scan parameter
201  *
202  * 07 14 2010 cp.wu
203  *
204  * [WPD00003833] [MT6620 and MT5931] Driver migration.
205  * remove timer in DRV-SCN.
206  *
207  * 07 09 2010 cp.wu
208  *
209  * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection)
210  * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass
211  * 3) implment DRV-SCN module, currently only accepts single scan request, other request will be directly dropped by returning BUSY
212  *
213  * 07 08 2010 cp.wu
214  *
215  * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
216  *
217  * 07 08 2010 cp.wu
218  * [WPD00003833][MT6620 and MT5931] Driver migration
219  * take use of RLM module for parsing/generating HT IEs for 11n capability
220  *
221  * 07 02 2010 cp.wu
222  * [WPD00003833][MT6620 and MT5931] Driver migration
223  * when returning to SCAN_IDLE state, send a correct message to source FSM.
224  *
225  * 07 01 2010 cp.wu
226  * [WPD00003833][MT6620 and MT5931] Driver migration
227  * implementation of DRV-SCN and related mailbox message handling.
228  *
229  * 06 22 2010 cp.wu
230  * [WPD00003833][MT6620 and MT5931] Driver migration
231  * comment out RLM APIs by CFG_RLM_MIGRATION.
232  *
233  * 06 21 2010 cp.wu
234  * [WPD00003833][MT6620 and MT5931] Driver migration
235  * add scan_fsm into building.
236  *
237  * 05 14 2010 kevin.huang
238  * [BORA00000794][WIFISYS][New Feature]Power Management Support
239  * Refine the order of Stop TX Queue and Switch Channel
240  *
241  * 05 12 2010 kevin.huang
242  * [BORA00000794][WIFISYS][New Feature]Power Management Support
243  * Update pause/resume/flush API to new Bitmap API
244  *
245  * 05 12 2010 kevin.huang
246  * [BORA00000794][WIFISYS][New Feature]Power Management Support
247  * Add Power Management - Legacy PS-POLL support.
248  *
249  * 03 18 2010 kevin.huang
250  * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
251  * Ignore the PROBE_DELAY state if the value of Probe Delay == 0
252  *
253  * 03 10 2010 kevin.huang
254  * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support
255  * Add Channel Manager for arbitration of JOIN and SCAN Req
256  *
257  * 02 23 2010 kevin.huang
258  * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
259  * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb
260  *
261  * 01 08 2010 kevin.huang
262  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
263  * Add set RX Filter to receive BCN from different BSSID during SCAN
264  *
265  * 12 18 2009 cm.chang
266  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
267  * .
268  *
269  * Nov 25 2009 mtk01461
270  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
271  * Remove flag of CFG_TEST_MGMT_FSM
272  *
273  * Nov 20 2009 mtk01461
274  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
275  * Change parameter of scanSendProbeReqFrames()
276  *
277  * Nov 16 2009 mtk01461
278  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
279  * Update scnFsmSteps()
280  *
281  * Nov 5 2009 mtk01461
282  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
283  * Fix typo
284  *
285  * Nov 5 2009 mtk01461
286  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
287  *
288 */
289
290 /*******************************************************************************
291 *                         C O M P I L E R   F L A G S
292 ********************************************************************************
293 */
294
295 /*******************************************************************************
296 *                    E X T E R N A L   R E F E R E N C E S
297 ********************************************************************************
298 */
299 #include "precomp.h"
300
301 /*******************************************************************************
302 *                              C O N S T A N T S
303 ********************************************************************************
304 */
305
306 /*******************************************************************************
307 *                             D A T A   T Y P E S
308 ********************************************************************************
309 */
310
311 /*******************************************************************************
312 *                            P U B L I C   D A T A
313 ********************************************************************************
314 */
315
316 /*******************************************************************************
317 *                           P R I V A T E   D A T A
318 ********************************************************************************
319 */
320 #if DBG
321 /*lint -save -e64 Type mismatch */
322 static PUINT_8 apucDebugScanState[SCAN_STATE_NUM] = {
323     (PUINT_8)DISP_STRING("SCAN_STATE_IDLE"),
324     (PUINT_8)DISP_STRING("SCAN_STATE_SCANNING"),
325 };
326 /*lint -restore */
327 #endif /* DBG */
328
329 /*******************************************************************************
330 *                                 M A C R O S
331 ********************************************************************************
332 */
333
334 /*******************************************************************************
335 *                   F U N C T I O N   D E C L A R A T I O N S
336 ********************************************************************************
337 */
338
339 /*******************************************************************************
340 *                              F U N C T I O N S
341 ********************************************************************************
342 */
343 /*----------------------------------------------------------------------------*/
344 /*!
345 * \brief
346 *
347 * \param[in]
348 *
349 * \return none
350 */
351 /*----------------------------------------------------------------------------*/
352 VOID
353 scnFsmSteps (
354     IN P_ADAPTER_T prAdapter,
355     IN ENUM_SCAN_STATE_T eNextState
356     )
357 {
358     P_SCAN_INFO_T prScanInfo;
359     P_SCAN_PARAM_T prScanParam;
360     P_MSG_HDR_T prMsgHdr;
361
362     BOOLEAN fgIsTransition = (BOOLEAN)FALSE;
363
364     prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
365     prScanParam = &prScanInfo->rScanParam;
366
367     do {
368
369 #if CFG_SUPPORT_XLOG
370         DBGLOG(SCN, STATE, ("[%d] TRANSITION: [%d] -> [%d]\n",
371                              DBG_SCN_IDX,
372                              prScanInfo->eCurrentState,
373                              eNextState));
374 #else
375         DBGLOG(SCN, STATE, ("TRANSITION: [%s] -> [%s]\n",
376                              apucDebugScanState[prScanInfo->eCurrentState],
377                              apucDebugScanState[eNextState]));
378 #endif
379
380         /* NOTE(Kevin): This is the only place to change the eCurrentState(except initial) */
381         prScanInfo->eCurrentState = eNextState;
382
383         fgIsTransition = (BOOLEAN)FALSE;
384
385         switch (prScanInfo->eCurrentState) {
386         case SCAN_STATE_IDLE:
387             /* check for pending scanning requests */
388             if(!LINK_IS_EMPTY(&(prScanInfo->rPendingMsgList))) {
389                 // load next message from pending list as scan parameters
390                 LINK_REMOVE_HEAD(&(prScanInfo->rPendingMsgList), prMsgHdr, P_MSG_HDR_T);
391
392                 if(prMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ
393                         || prMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ
394                         || prMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ
395                         || prMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ) {
396                     scnFsmHandleScanMsg(prAdapter, (P_MSG_SCN_SCAN_REQ)prMsgHdr);
397                     }
398                     else {
399                     scnFsmHandleScanMsgV2(prAdapter, (P_MSG_SCN_SCAN_REQ_V2)prMsgHdr);
400                     }
401
402                 /* switch to next state */
403                 eNextState = SCAN_STATE_SCANNING;
404                 fgIsTransition = TRUE;
405
406                 cnmMemFree(prAdapter, prMsgHdr);
407                 }
408             break;
409
410         case SCAN_STATE_SCANNING:
411             if(prScanParam->fgIsScanV2 == FALSE) {
412                 scnSendScanReq(prAdapter);
413                 }
414                 else {
415                 scnSendScanReqV2(prAdapter);
416                 }
417             break;
418
419         default:
420             ASSERT(0);
421             break;
422
423                 }
424     }
425     while (fgIsTransition);
426
427     return;
428 }
429
430
431 /*----------------------------------------------------------------------------*/
432 /*!
433 * \brief        Generate CMD_ID_SCAN_REQ command
434 *
435 * \param[in]
436 *
437 * \return none
438 */
439 /*----------------------------------------------------------------------------*/
440 VOID
441 scnSendScanReq (
442     IN P_ADAPTER_T prAdapter
443     )
444 {
445     P_SCAN_INFO_T prScanInfo;
446     P_SCAN_PARAM_T prScanParam;
447     CMD_SCAN_REQ rCmdScanReq;
448     UINT_32 i;
449
450     ASSERT(prAdapter);
451
452     prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
453     prScanParam = &prScanInfo->rScanParam;
454
455             // send command packet for scan
456             kalMemZero(&rCmdScanReq, sizeof(CMD_SCAN_REQ));
457
458             rCmdScanReq.ucSeqNum        = prScanParam->ucSeqNum;
459             rCmdScanReq.ucNetworkType   = (UINT_8)prScanParam->eNetTypeIndex;
460             rCmdScanReq.ucScanType      = (UINT_8)prScanParam->eScanType;
461             rCmdScanReq.ucSSIDType      = prScanParam->ucSSIDType;
462
463     if(prScanParam->ucSSIDNum == 1) {
464                 COPY_SSID(rCmdScanReq.aucSSID,
465                         rCmdScanReq.ucSSIDLength,
466                 prScanParam->aucSpecifiedSSID[0],
467                 prScanParam->ucSpecifiedSSIDLen[0]);
468             }
469
470             rCmdScanReq.ucChannelType   = (UINT_8)prScanParam->eScanChannel;
471
472             if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) {
473                 /* P2P would use:
474                   * 1. Specified Listen Channel of passive scan for LISTEN state.
475                   * 2. Specified Listen Channel of Target Device of active scan for SEARCH state. (Target != NULL)
476                   */
477                 rCmdScanReq.ucChannelListNum    = prScanParam->ucChannelListNum;
478
479                 for(i = 0 ; i < rCmdScanReq.ucChannelListNum ; i++) {
480                     rCmdScanReq.arChannelList[i].ucBand =
481                             (UINT_8) prScanParam->arChnlInfoList[i].eBand;
482
483                     rCmdScanReq.arChannelList[i].ucChannelNum =
484                         (UINT_8)prScanParam->arChnlInfoList[i].ucChannelNum;
485                 }
486             }
487
488 #if CFG_ENABLE_WIFI_DIRECT
489             if(prAdapter->fgIsP2PRegistered) {
490                 rCmdScanReq.u2ChannelDwellTime = prScanParam->u2PassiveListenInterval;
491             }
492 #endif
493
494             if(prScanParam->u2IELen <= MAX_IE_LENGTH) {
495                 rCmdScanReq.u2IELen = prScanParam->u2IELen;
496             }
497             else {
498                 rCmdScanReq.u2IELen = MAX_IE_LENGTH;
499             }
500
501             if (prScanParam->u2IELen) {
502                 kalMemCopy(rCmdScanReq.aucIE,
503                         prScanParam->aucIE,
504                         sizeof(UINT_8) * rCmdScanReq.u2IELen);
505             }
506
507             wlanSendSetQueryCmd(prAdapter,
508                     CMD_ID_SCAN_REQ,
509                     TRUE,
510                     FALSE,
511                     FALSE,
512                     NULL,
513                     NULL,
514                     OFFSET_OF(CMD_SCAN_REQ, aucIE) + rCmdScanReq.u2IELen,
515                     (PUINT_8)&rCmdScanReq,
516                     NULL,
517                     0);
518 }
519
520
521 /*----------------------------------------------------------------------------*/
522 /*!
523 * \brief        Generate CMD_ID_SCAN_REQ_V2 command
524 *
525 * \param[in]
526 *
527 * \return none
528 */
529 /*----------------------------------------------------------------------------*/
530 VOID
531 scnSendScanReqV2 (
532     IN P_ADAPTER_T prAdapter
533     )
534 {
535     P_SCAN_INFO_T prScanInfo;
536     P_SCAN_PARAM_T prScanParam;
537     CMD_SCAN_REQ_V2 rCmdScanReq;
538     UINT_32 i;
539
540     ASSERT(prAdapter);
541
542     prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
543     prScanParam = &prScanInfo->rScanParam;
544
545     // send command packet for scan
546     kalMemZero(&rCmdScanReq, sizeof(CMD_SCAN_REQ_V2));
547
548     rCmdScanReq.ucSeqNum        = prScanParam->ucSeqNum;
549     rCmdScanReq.ucNetworkType   = (UINT_8)prScanParam->eNetTypeIndex;
550     rCmdScanReq.ucScanType      = (UINT_8)prScanParam->eScanType;
551     rCmdScanReq.ucSSIDType      = prScanParam->ucSSIDType;
552
553     for (i = 0 ; i < prScanParam->ucSSIDNum; i++) {
554         COPY_SSID(rCmdScanReq.arSSID[i].aucSsid,
555                 rCmdScanReq.arSSID[i].u4SsidLen,
556                 prScanParam->aucSpecifiedSSID[i],
557                 prScanParam->ucSpecifiedSSIDLen[i]);
558     }
559
560     rCmdScanReq.u2ProbeDelayTime    = (UINT_8)prScanParam->u2ProbeDelayTime;
561     rCmdScanReq.ucChannelType       = (UINT_8)prScanParam->eScanChannel;
562
563     if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) {
564         /* P2P would use:
565          * 1. Specified Listen Channel of passive scan for LISTEN state.
566          * 2. Specified Listen Channel of Target Device of active scan for SEARCH state. (Target != NULL)
567          */
568         rCmdScanReq.ucChannelListNum    = prScanParam->ucChannelListNum;
569
570         for(i = 0 ; i < rCmdScanReq.ucChannelListNum ; i++) {
571             rCmdScanReq.arChannelList[i].ucBand =
572                 (UINT_8) prScanParam->arChnlInfoList[i].eBand;
573
574             rCmdScanReq.arChannelList[i].ucChannelNum =
575                 (UINT_8)prScanParam->arChnlInfoList[i].ucChannelNum;
576         }
577     }
578
579 #if CFG_ENABLE_WIFI_DIRECT
580     if(prAdapter->fgIsP2PRegistered) {
581         rCmdScanReq.u2ChannelDwellTime = prScanParam->u2PassiveListenInterval;
582     }
583 #endif
584
585     if(prScanParam->u2IELen <= MAX_IE_LENGTH) {
586         rCmdScanReq.u2IELen = prScanParam->u2IELen;
587     }
588     else {
589         rCmdScanReq.u2IELen = MAX_IE_LENGTH;
590         }
591
592     if (prScanParam->u2IELen) {
593         kalMemCopy(rCmdScanReq.aucIE,
594                 prScanParam->aucIE,
595                 sizeof(UINT_8) * rCmdScanReq.u2IELen);
596     }
597
598     wlanSendSetQueryCmd(prAdapter,
599             CMD_ID_SCAN_REQ_V2,
600             TRUE,
601             FALSE,
602             FALSE,
603             NULL,
604             NULL,
605             OFFSET_OF(CMD_SCAN_REQ_V2, aucIE) + rCmdScanReq.u2IELen,
606             (PUINT_8)&rCmdScanReq,
607             NULL,
608             0);
609
610 }
611
612
613 /*----------------------------------------------------------------------------*/
614 /*!
615 * \brief
616 *
617 * \param[in]
618 *
619 * \return none
620 */
621 /*----------------------------------------------------------------------------*/
622 VOID
623 scnFsmMsgStart (
624     IN P_ADAPTER_T prAdapter,
625     IN P_MSG_HDR_T prMsgHdr
626     )
627 {
628     P_SCAN_INFO_T prScanInfo;
629     P_SCAN_PARAM_T prScanParam;
630
631     ASSERT(prMsgHdr);
632
633     prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
634     prScanParam = &prScanInfo->rScanParam;
635
636
637     if (prScanInfo->eCurrentState == SCAN_STATE_IDLE) {
638         if(prMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ
639                 || prMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ
640                 || prMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ
641                 || prMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ) {
642             scnFsmHandleScanMsg(prAdapter, (P_MSG_SCN_SCAN_REQ)prMsgHdr);
643         }
644         else if(prMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ_V2
645                 || prMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ_V2
646                 || prMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ_V2
647                 || prMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ_V2) {
648             scnFsmHandleScanMsgV2(prAdapter, (P_MSG_SCN_SCAN_REQ_V2)prMsgHdr);
649             }
650             else {
651             // should not deliver to this function
652             ASSERT(0);
653         }
654
655         cnmMemFree(prAdapter, prMsgHdr);
656         scnFsmSteps(prAdapter, SCAN_STATE_SCANNING);
657     }
658     else {
659         LINK_INSERT_TAIL(&prScanInfo->rPendingMsgList, &prMsgHdr->rLinkEntry);
660     }
661
662     return;
663 }
664
665
666
667 /*----------------------------------------------------------------------------*/
668 /*!
669 * \brief
670 *
671 * \param[in]
672 *
673 * \return none
674 */
675 /*----------------------------------------------------------------------------*/
676 VOID
677 scnFsmMsgAbort (
678     IN P_ADAPTER_T prAdapter,
679     IN P_MSG_HDR_T prMsgHdr
680     )
681 {
682     P_MSG_SCN_SCAN_CANCEL prScanCancel;
683     P_SCAN_INFO_T prScanInfo;
684     P_SCAN_PARAM_T prScanParam;
685     CMD_SCAN_CANCEL rCmdScanCancel;
686
687     ASSERT(prMsgHdr);
688
689     prScanCancel = (P_MSG_SCN_SCAN_CANCEL)prMsgHdr;
690     prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
691     prScanParam = &prScanInfo->rScanParam;
692
693     if (prScanInfo->eCurrentState != SCAN_STATE_IDLE) {
694         if(prScanCancel->ucSeqNum == prScanParam->ucSeqNum &&
695                 prScanCancel->ucNetTypeIndex == (UINT_8)prScanParam->eNetTypeIndex) {
696             /* send cancel message to firmware domain */
697             rCmdScanCancel.ucSeqNum = prScanParam->ucSeqNum;
698
699 #if CFG_ENABLE_WIFI_DIRECT
700             if(prAdapter->fgIsP2PRegistered) {
701                 rCmdScanCancel.ucIsExtChannel = (UINT_8) prScanCancel->fgIsChannelExt;
702             }
703             else {
704                 rCmdScanCancel.ucIsExtChannel = (UINT_8) FALSE;
705             }
706 #endif
707
708             wlanSendSetQueryCmd(prAdapter,
709                     CMD_ID_SCAN_CANCEL,
710                     TRUE,
711                     FALSE,
712                     FALSE,
713                     NULL,
714                     NULL,
715                     sizeof(CMD_SCAN_CANCEL),
716                     (PUINT_8)&rCmdScanCancel,
717                     NULL,
718                     0);
719
720             /* generate scan-done event for caller */
721             scnFsmGenerateScanDoneMsg(prAdapter,
722                     prScanParam->ucSeqNum,
723                     (UINT_8)prScanParam->eNetTypeIndex,
724                     SCAN_STATUS_CANCELLED);
725
726             /* switch to next pending scan */
727             scnFsmSteps(prAdapter, SCAN_STATE_IDLE);
728         }
729         else {
730             scnFsmRemovePendingMsg(prAdapter, prScanCancel->ucSeqNum, prScanCancel->ucNetTypeIndex);
731         }
732     }
733
734     cnmMemFree(prAdapter, prMsgHdr);
735
736     return;
737 }
738
739
740 /*----------------------------------------------------------------------------*/
741 /*!
742 * \brief            Scan Message Parsing (Legacy)
743 *
744 * \param[in]
745 *
746 * \return none
747 */
748 /*----------------------------------------------------------------------------*/
749 VOID
750 scnFsmHandleScanMsg (
751     IN P_ADAPTER_T prAdapter,
752     IN P_MSG_SCN_SCAN_REQ prScanReqMsg
753     )
754 {
755     P_SCAN_INFO_T prScanInfo;
756     P_SCAN_PARAM_T prScanParam;
757     UINT_32 i;
758
759     ASSERT(prAdapter);
760     ASSERT(prScanReqMsg);
761
762     prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
763     prScanParam = &prScanInfo->rScanParam;
764
765     prScanParam->eScanType      = prScanReqMsg->eScanType;
766     prScanParam->eNetTypeIndex  = (ENUM_NETWORK_TYPE_INDEX_T)prScanReqMsg->ucNetTypeIndex;
767     prScanParam->ucSSIDType     = prScanReqMsg->ucSSIDType;
768     if (prScanParam->ucSSIDType & (SCAN_REQ_SSID_SPECIFIED | SCAN_REQ_SSID_P2P_WILDCARD)) {
769         prScanParam->ucSSIDNum = 1;
770
771         COPY_SSID(prScanParam->aucSpecifiedSSID[0],
772                 prScanParam->ucSpecifiedSSIDLen[0],
773                 prScanReqMsg->aucSSID,
774                 prScanReqMsg->ucSSIDLength);
775
776         // reset SSID length to zero for rest array entries
777         for(i = 1 ; i < SCN_SSID_MAX_NUM ; i++) {
778             prScanParam->ucSpecifiedSSIDLen[i] = 0;
779         }
780     }
781     else {
782         prScanParam->ucSSIDNum = 0;
783
784         for(i = 0 ; i < SCN_SSID_MAX_NUM ; i++) {
785             prScanParam->ucSpecifiedSSIDLen[i] = 0;
786         }
787     }
788
789     prScanParam->u2ProbeDelayTime   = 0;
790     prScanParam->eScanChannel   = prScanReqMsg->eScanChannel;
791     if(prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) {
792         if(prScanReqMsg->ucChannelListNum <= MAXIMUM_OPERATION_CHANNEL_LIST) {
793             prScanParam->ucChannelListNum   = prScanReqMsg->ucChannelListNum;
794         }
795         else {
796             prScanParam->ucChannelListNum   = MAXIMUM_OPERATION_CHANNEL_LIST;
797         }
798
799         kalMemCopy(prScanParam->arChnlInfoList,
800                 prScanReqMsg->arChnlInfoList,
801                 sizeof(RF_CHANNEL_INFO_T) * prScanParam->ucChannelListNum);
802     }
803
804     if(prScanReqMsg->u2IELen <= MAX_IE_LENGTH) {
805         prScanParam->u2IELen    = prScanReqMsg->u2IELen;
806     }
807     else {
808         prScanParam->u2IELen    = MAX_IE_LENGTH;
809     }
810
811     if(prScanParam->u2IELen) {
812         kalMemCopy(prScanParam->aucIE, prScanReqMsg->aucIE, prScanParam->u2IELen);
813     }
814
815 #if CFG_ENABLE_WIFI_DIRECT
816     if(prAdapter->fgIsP2PRegistered) {
817         prScanParam->u2PassiveListenInterval = prScanReqMsg->u2ChannelDwellTime;
818     }
819 #endif
820     prScanParam->ucSeqNum       = prScanReqMsg->ucSeqNum;
821
822     if(prScanReqMsg->rMsgHdr.eMsgId == MID_RLM_SCN_SCAN_REQ) {
823         prScanParam->fgIsObssScan   = TRUE;
824     }
825     else {
826         prScanParam->fgIsObssScan   = FALSE;
827     }
828
829     prScanParam->fgIsScanV2 = FALSE;
830
831     return;
832 }
833
834
835 /*----------------------------------------------------------------------------*/
836 /*!
837 * \brief            Scan Message Parsing - V2 with multiple SSID support
838 *
839 * \param[in]
840 *
841 * \return none
842 */
843 /*----------------------------------------------------------------------------*/
844 VOID
845 scnFsmHandleScanMsgV2 (
846     IN P_ADAPTER_T prAdapter,
847     IN P_MSG_SCN_SCAN_REQ_V2 prScanReqMsg
848     )
849 {
850     P_SCAN_INFO_T prScanInfo;
851     P_SCAN_PARAM_T prScanParam;
852     UINT_32 i;
853
854     ASSERT(prAdapter);
855     ASSERT(prScanReqMsg);
856     ASSERT(prScanReqMsg->ucSSIDNum <= SCN_SSID_MAX_NUM);
857
858     prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
859     prScanParam = &prScanInfo->rScanParam;
860
861     prScanParam->eScanType      = prScanReqMsg->eScanType;
862     prScanParam->eNetTypeIndex  = (ENUM_NETWORK_TYPE_INDEX_T)prScanReqMsg->ucNetTypeIndex;
863     prScanParam->ucSSIDType     = prScanReqMsg->ucSSIDType;
864     prScanParam->ucSSIDNum      = prScanReqMsg->ucSSIDNum;
865
866     for(i = 0 ; i < prScanReqMsg->ucSSIDNum ; i++) {
867         COPY_SSID(prScanParam->aucSpecifiedSSID[i],
868                 prScanParam->ucSpecifiedSSIDLen[i],
869                 prScanReqMsg->prSsid[i].aucSsid,
870                 (UINT_8)prScanReqMsg->prSsid[i].u4SsidLen);
871     }
872
873     prScanParam->u2ProbeDelayTime   = prScanReqMsg->u2ProbeDelay;
874     prScanParam->eScanChannel       = prScanReqMsg->eScanChannel;
875     if(prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) {
876         if(prScanReqMsg->ucChannelListNum <= MAXIMUM_OPERATION_CHANNEL_LIST) {
877             prScanParam->ucChannelListNum   = prScanReqMsg->ucChannelListNum;
878         }
879         else {
880             prScanParam->ucChannelListNum   = MAXIMUM_OPERATION_CHANNEL_LIST;
881         }
882
883         kalMemCopy(prScanParam->arChnlInfoList,
884                 prScanReqMsg->arChnlInfoList,
885                 sizeof(RF_CHANNEL_INFO_T) * prScanParam->ucChannelListNum);
886     }
887
888     if(prScanReqMsg->u2IELen <= MAX_IE_LENGTH) {
889         prScanParam->u2IELen    = prScanReqMsg->u2IELen;
890     }
891     else {
892         prScanParam->u2IELen    = MAX_IE_LENGTH;
893     }
894
895     if(prScanParam->u2IELen) {
896         kalMemCopy(prScanParam->aucIE, prScanReqMsg->aucIE, prScanParam->u2IELen);
897     }
898
899 #if CFG_ENABLE_WIFI_DIRECT
900     if(prAdapter->fgIsP2PRegistered) {
901         prScanParam->u2PassiveListenInterval = prScanReqMsg->u2ChannelDwellTime;
902     }
903 #endif
904     prScanParam->ucSeqNum       = prScanReqMsg->ucSeqNum;
905
906     if(prScanReqMsg->rMsgHdr.eMsgId == MID_RLM_SCN_SCAN_REQ) {
907         prScanParam->fgIsObssScan   = TRUE;
908     }
909     else {
910         prScanParam->fgIsObssScan   = FALSE;
911     }
912
913     prScanParam->fgIsScanV2 = TRUE;
914
915     return;
916 }
917
918
919 /*----------------------------------------------------------------------------*/
920 /*!
921 * \brief            Remove pending scan request
922 *
923 * \param[in]
924 *
925 * \return none
926 */
927 /*----------------------------------------------------------------------------*/
928 VOID
929 scnFsmRemovePendingMsg (
930     IN P_ADAPTER_T  prAdapter,
931     IN UINT_8       ucSeqNum,
932     IN UINT_8       ucNetTypeIndex
933     )
934 {
935     P_SCAN_INFO_T prScanInfo;
936     P_SCAN_PARAM_T prScanParam;
937     P_MSG_HDR_T prPendingMsgHdr, prPendingMsgHdrNext, prRemoveMsgHdr = NULL;
938     P_LINK_ENTRY_T prRemoveLinkEntry = NULL;
939
940     ASSERT(prAdapter);
941
942     prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
943     prScanParam = &prScanInfo->rScanParam;
944
945             /* traverse through rPendingMsgList for removal */
946             LINK_FOR_EACH_ENTRY_SAFE(prPendingMsgHdr,
947                                         prPendingMsgHdrNext,
948                                         &(prScanInfo->rPendingMsgList),
949                                         rLinkEntry,
950                                         MSG_HDR_T) {
951         if(prPendingMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ
952                 || prPendingMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ
953                 || prPendingMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ
954                 || prPendingMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ) {
955                 P_MSG_SCN_SCAN_REQ prScanReqMsg = (P_MSG_SCN_SCAN_REQ)prPendingMsgHdr;
956
957             if(ucSeqNum == prScanReqMsg->ucSeqNum &&
958                     ucNetTypeIndex == prScanReqMsg->ucNetTypeIndex) {
959                 prRemoveLinkEntry = &(prScanReqMsg->rMsgHdr.rLinkEntry);
960                 prRemoveMsgHdr = prPendingMsgHdr;
961             }
962         }
963         else if(prPendingMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ_V2
964                 || prPendingMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ_V2
965                 || prPendingMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ_V2
966                 || prPendingMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ_V2) {
967             P_MSG_SCN_SCAN_REQ_V2 prScanReqMsgV2 = (P_MSG_SCN_SCAN_REQ_V2)prPendingMsgHdr;
968
969             if(ucSeqNum == prScanReqMsgV2->ucSeqNum &&
970                     ucNetTypeIndex == prScanReqMsgV2->ucNetTypeIndex) {
971                 prRemoveLinkEntry = &(prScanReqMsgV2->rMsgHdr.rLinkEntry);
972                 prRemoveMsgHdr = prPendingMsgHdr;
973             }
974         }
975
976         if(prRemoveLinkEntry) {
977                     /* generate scan-done event for caller */
978                     scnFsmGenerateScanDoneMsg(prAdapter,
979                     ucSeqNum,
980                     ucNetTypeIndex,
981                             SCAN_STATUS_CANCELLED);
982
983                     /* remove from pending list */
984             LINK_REMOVE_KNOWN_ENTRY(&(prScanInfo->rPendingMsgList), prRemoveLinkEntry);
985             cnmMemFree(prAdapter, prRemoveMsgHdr);
986
987                     break;
988                 }
989             }
990
991     return;
992 }
993
994
995 /*----------------------------------------------------------------------------*/
996 /*!
997 * \brief
998 *
999 * \param[in]
1000 *
1001 * \return none
1002 */
1003 /*----------------------------------------------------------------------------*/
1004 VOID
1005 scnEventScanDone (
1006     IN P_ADAPTER_T          prAdapter,
1007     IN P_EVENT_SCAN_DONE    prScanDone
1008     )
1009 {
1010     P_SCAN_INFO_T prScanInfo;
1011     P_SCAN_PARAM_T prScanParam;
1012
1013     prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1014     prScanParam = &prScanInfo->rScanParam;
1015
1016     // buffer empty channel information
1017     if(prScanParam->eScanChannel == SCAN_CHANNEL_FULL 
1018             || prScanParam->eScanChannel == SCAN_CHANNEL_2G4) {
1019         if(prScanDone->ucSparseChannelValid) {
1020             prScanInfo->fgIsSparseChannelValid      = TRUE;
1021             prScanInfo->rSparseChannel.eBand        = (ENUM_BAND_T)prScanDone->rSparseChannel.ucBand;
1022             prScanInfo->rSparseChannel.ucChannelNum = prScanDone->rSparseChannel.ucChannelNum;
1023         }
1024         else {
1025             prScanInfo->fgIsSparseChannelValid      = FALSE;
1026         }
1027     }
1028
1029     if(prScanInfo->eCurrentState == SCAN_STATE_SCANNING &&
1030             prScanDone->ucSeqNum == prScanParam->ucSeqNum) {
1031         /* generate scan-done event for caller */
1032         scnFsmGenerateScanDoneMsg(prAdapter,
1033                 prScanParam->ucSeqNum,
1034                 (UINT_8)prScanParam->eNetTypeIndex,
1035                 SCAN_STATUS_DONE);
1036
1037         /* switch to next pending scan */
1038         scnFsmSteps(prAdapter, SCAN_STATE_IDLE);
1039     }
1040     else {
1041         DBGLOG(SCN, LOUD, ("Unexpected SCAN-DONE event: SeqNum = %d, Current State = %d\n",
1042                  prScanDone->ucSeqNum,
1043                  prScanInfo->eCurrentState));
1044     }
1045
1046     return;
1047 } /* end of scnEventScanDone */
1048
1049
1050 /*----------------------------------------------------------------------------*/
1051 /*!
1052 * \brief
1053 *
1054 * \param[in]
1055 *
1056 * \return none
1057 */
1058 /*----------------------------------------------------------------------------*/
1059 VOID
1060 scnFsmGenerateScanDoneMsg (
1061     IN P_ADAPTER_T          prAdapter,
1062     IN UINT_8               ucSeqNum,
1063     IN UINT_8               ucNetTypeIndex,
1064     IN ENUM_SCAN_STATUS     eScanStatus
1065     )
1066 {
1067     P_SCAN_INFO_T prScanInfo;
1068     P_SCAN_PARAM_T prScanParam;
1069     P_MSG_SCN_SCAN_DONE prScanDoneMsg;
1070
1071     ASSERT(prAdapter);
1072
1073     prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1074     prScanParam = &prScanInfo->rScanParam;
1075
1076     prScanDoneMsg = (P_MSG_SCN_SCAN_DONE)cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_DONE));
1077     if (!prScanDoneMsg) {
1078         ASSERT(0); // Can't indicate SCAN FSM Complete
1079         return;
1080     }
1081
1082     if(prScanParam->fgIsObssScan == TRUE) {
1083         prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_RLM_SCAN_DONE;
1084     }
1085     else {
1086         switch((ENUM_NETWORK_TYPE_INDEX_T)ucNetTypeIndex) {
1087         case NETWORK_TYPE_AIS_INDEX:
1088             prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_AIS_SCAN_DONE;
1089             break;
1090
1091 #if CFG_ENABLE_WIFI_DIRECT
1092         case NETWORK_TYPE_P2P_INDEX:
1093             prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_P2P_SCAN_DONE;
1094             break;
1095 #endif
1096
1097 #if CFG_ENABLE_BT_OVER_WIFI
1098         case NETWORK_TYPE_BOW_INDEX:
1099             prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_BOW_SCAN_DONE;
1100             break;
1101 #endif
1102
1103         default:
1104             DBGLOG(SCN, LOUD, ("Unexpected Network Type: %d\n", ucNetTypeIndex));
1105             ASSERT(0);
1106             break;
1107         }
1108     }
1109
1110     prScanDoneMsg->ucSeqNum         = ucSeqNum;
1111     prScanDoneMsg->ucNetTypeIndex   = ucNetTypeIndex;
1112     prScanDoneMsg->eScanStatus      = eScanStatus;
1113
1114     mboxSendMsg(prAdapter,
1115             MBOX_ID_0,
1116             (P_MSG_HDR_T) prScanDoneMsg,
1117             MSG_SEND_METHOD_BUF);
1118
1119 } /* end of scnFsmGenerateScanDoneMsg() */
1120
1121
1122 /*----------------------------------------------------------------------------*/
1123 /*!
1124 * \brief        Query for most sparse channel 
1125 *
1126 * \param[in]
1127 *
1128 * \return none
1129 */
1130 /*----------------------------------------------------------------------------*/
1131 BOOLEAN
1132 scnQuerySparseChannel (
1133     IN P_ADAPTER_T      prAdapter,
1134     P_ENUM_BAND_T       prSparseBand,
1135     PUINT_8             pucSparseChannel
1136     )
1137 {
1138     P_SCAN_INFO_T prScanInfo;
1139
1140     ASSERT(prAdapter);
1141
1142     prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1143
1144     if(prScanInfo->fgIsSparseChannelValid == TRUE) {
1145         if(prSparseBand) {
1146             *prSparseBand = prScanInfo->rSparseChannel.eBand;
1147         }
1148
1149         if(pucSparseChannel) {
1150             *pucSparseChannel = prScanInfo->rSparseChannel.ucChannelNum;
1151         }
1152
1153         return TRUE;
1154     }
1155     else {
1156         return FALSE;
1157     }
1158 }
1159