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