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