add MTK-combo-module,continue with commit 17f39ed917874e77e80411f33faba1b7ee8138c8
[firefly-linux-kernel-4.4.55.git] / drivers / mtk_wcn_combo / drv_wlan / wlan / mgmt / saa_fsm.c
1 /*
2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/mgmt/saa_fsm.c#1 $
3 */
4
5 /*! \file   "saa_fsm.c"
6     \brief  This file defines the FSM for SAA MODULE.
7
8     This file defines the FSM for SAA MODULE.
9 */
10
11 /*******************************************************************************
12 * Copyright (c) 2009 MediaTek Inc.
13 *
14 * All rights reserved. Copying, compilation, modification, distribution
15 * or any other use whatsoever of this material is strictly prohibited
16 * except in accordance with a Software License Agreement with
17 * MediaTek Inc.
18 ********************************************************************************
19 */
20
21 /*******************************************************************************
22 * LEGAL DISCLAIMER
23 *
24 * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND
25 * AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK
26 * SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE
27 * PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY
28 * DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
29 * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
30 * PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE
31 * ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY
32 * WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK
33 * SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY
34 * WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE
35 * FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO
36 * CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
37 *
38 * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
39 * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL
40 * BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT
41 * ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY
42 * BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
43 *
44 * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
45 * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT
46 * OF LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING
47 * THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN
48 * FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE
49 * (ICC).
50 ********************************************************************************
51 */
52
53 /*
54 ** $Log: saa_fsm.c $
55  *
56  * 01 20 2012 cp.wu
57  * [ALPS00096191] [MT6620 Wi-Fi][Driver][Firmware] Porting to ALPS4.0_DEV branch
58  * sync to up-to-date changes including:
59  * 1. BOW bugfix
60  * 2. XLOG
61  *
62  * 11 24 2011 wh.su
63  * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
64  * Adjust code for DBG and CONFIG_XLOG.
65  *
66  * 11 11 2011 wh.su
67  * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
68  * modify the xlog related code.
69  *
70  * 11 04 2011 cp.wu
71  * [WCXRP00001086] [MT6620 Wi-Fi][Driver] On Android, indicate an extra DISCONNECT for REASSOCIATED cases as an explicit trigger for Android framework
72  * 1. for DEAUTH/DISASSOC cases, indicate for DISCONNECTION immediately.
73  * 2. (Android only) when reassociation-and-non-roaming cases happened, indicate an extra DISCONNECT indication to Android Wi-Fi framework
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  * 05 12 2011 cp.wu
85  * [WCXRP00000720] [MT6620 Wi-Fi][Driver] Do not do any further operation in case STA-REC has been invalidated before SAA-FSM starts to roll
86  * check for valid STA-REC before SAA-FSM starts to roll.
87  *
88  * 04 21 2011 terry.wu
89  * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame
90  * Add network type parameter to authSendAuthFrame.
91  *
92  * 04 15 2011 chinghwa.yu
93  * [WCXRP00000065] Update BoW design and settings
94  * Add BOW short range mode.
95  *
96  * 04 14 2011 cm.chang
97  * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
98  * .
99  *
100  * 03 18 2011 cp.wu
101  * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver
102  * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk
103  *
104  * 02 10 2011 yuche.tsai
105  * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
106  * Add RX deauthentication & disassociation process under Hot-Spot mode.
107  *
108  * 01 26 2011 yuche.tsai
109  * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
110  * .
111  *
112  * 01 25 2011 yuche.tsai
113  * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
114  * Fix compile error of after Station Type Macro modification.
115  *
116  * 01 25 2011 yuche.tsai
117  * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
118  * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role.
119  *
120  * 11 29 2010 cp.wu
121  * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC for initial TX rate selection of auto-rate algorithm
122  * update ucRcpi of STA_RECORD_T for AIS when
123  * 1) Beacons for IBSS merge is received
124  * 2) Associate Response for a connecting peer is received
125  *
126  * 10 18 2010 cp.wu
127  * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS associated
128  * 1. remove redundant variables in STA_REC structure
129  * 2. add STA-REC uninitialization routine for clearing pending events
130  *
131  * 09 03 2010 kevin.huang
132  * NULL
133  * Refine #include sequence and solve recursive/nested #include issue
134  *
135  * 08 30 2010 cp.wu
136  * NULL
137  * eliminate klockwork errors
138  *
139  * 08 24 2010 chinghwa.yu
140  * NULL
141  * Update for MID_SCN_BOW_SCAN_DONE mboxDummy.
142  * Update saa_fsm for BOW.
143  *
144  * 08 16 2010 cp.wu
145  * NULL
146  * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI.
147  * There is no CFG_SUPPORT_BOW in driver domain source.
148  *
149  * 08 02 2010 yuche.tsai
150  * NULL
151  * Add support for P2P join event start.
152  *
153  * 07 12 2010 cp.wu
154  *
155  * SAA will take a record for tracking request sequence number.
156  *
157  * 07 08 2010 cp.wu
158  *
159  * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
160  *
161  * 07 01 2010 cp.wu
162  * [WPD00003833][MT6620 and MT5931] Driver migration
163  * AIS-FSM integration with CNM channel request messages
164  *
165  * 06 23 2010 cp.wu
166  * [WPD00003833][MT6620 and MT5931] Driver migration
167  * sync. with main branch for reseting to state 1 when associating with another AP
168  *
169  * 06 21 2010 cp.wu
170  * [WPD00003833][MT6620 and MT5931] Driver migration
171  * refine TX-DONE callback.
172  *
173  * 06 21 2010 wh.su
174  * [WPD00003840][MT6620 5931] Security migration
175  * remove duplicate variable for migration.
176  *
177  * 06 18 2010 cm.chang
178  * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
179  * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
180  *
181  * 06 18 2010 wh.su
182  * [WPD00003840][MT6620 5931] Security migration
183  * migration the security related function from firmware.
184  *
185  * 06 17 2010 yuche.tsai
186  * [WPD00003839][MT6620 5931][P2P] Feature migration
187  * Fix compile error when enable WiFi Direct function.
188  *
189  * 06 14 2010 cp.wu
190  * [WPD00003833][MT6620 and MT5931] Driver migration
191  * saa_fsm.c is migrated.
192  *
193  * 05 12 2010 kevin.huang
194  * [BORA00000794][WIFISYS][New Feature]Power Management Support
195  * Add Power Management - Legacy PS-POLL support.
196  *
197  * 04 24 2010 cm.chang
198  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
199  * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW
200  *
201  * 04 19 2010 kevin.huang
202  * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support
203  *
204  *  *  * Add Connection Policy - Any and Rx Burst Deauth Support for WHQL
205  *
206  * 03 10 2010 kevin.huang
207  * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support
208  * Add Channel Manager for arbitration of JOIN and SCAN Req
209  *
210  * 02 26 2010 kevin.huang
211  * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
212  * Add support of Driver STA_RECORD_T activation
213  *
214  * 02 04 2010 kevin.huang
215  * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
216  * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
217  *
218  * 01 27 2010 wh.su
219  * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code
220  * add and fixed some security function.
221  *
222  * 01 12 2010 kevin.huang
223  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
224  * Fix compile warning due to declared but not used
225  *
226  * 01 11 2010 kevin.huang
227  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
228  * Add Deauth and Disassoc Handler
229  *
230  * 01 08 2010 kevin.huang
231  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
232  * Refine Debug Label
233  *
234  * 12 18 2009 cm.chang
235  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
236  * .
237  *
238  * Dec 3 2009 mtk01461
239  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
240  * Update comment
241  *
242  * Dec 1 2009 mtk01088
243  * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
244  * rename the function
245  *
246  * Nov 24 2009 mtk01461
247  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
248  * Revise MGMT Handler with Retain Status
249  *
250  * Nov 23 2009 mtk01461
251  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
252  *
253 */
254
255 /*******************************************************************************
256 *                         C O M P I L E R   F L A G S
257 ********************************************************************************
258 */
259
260 /*******************************************************************************
261 *                    E X T E R N A L   R E F E R E N C E S
262 ********************************************************************************
263 */
264 #include "precomp.h"
265
266 /*******************************************************************************
267 *                              C O N S T A N T S
268 ********************************************************************************
269 */
270
271 /*******************************************************************************
272 *                             D A T A   T Y P E S
273 ********************************************************************************
274 */
275
276 /*******************************************************************************
277 *                            P U B L I C   D A T A
278 ********************************************************************************
279 */
280
281 /*******************************************************************************
282 *                           P R I V A T E   D A T A
283 ********************************************************************************
284 */
285 #if DBG
286 /*lint -save -e64 Type mismatch */
287 static PUINT_8 apucDebugAAState[AA_STATE_NUM] = {
288     (PUINT_8)DISP_STRING("AA_STATE_IDLE"),
289     (PUINT_8)DISP_STRING("SAA_STATE_SEND_AUTH1"),
290     (PUINT_8)DISP_STRING("SAA_STATE_WAIT_AUTH2"),
291     (PUINT_8)DISP_STRING("SAA_STATE_SEND_AUTH3"),
292     (PUINT_8)DISP_STRING("SAA_STATE_WAIT_AUTH4"),
293     (PUINT_8)DISP_STRING("SAA_STATE_SEND_ASSOC1"),
294     (PUINT_8)DISP_STRING("SAA_STATE_WAIT_ASSOC2"),
295     (PUINT_8)DISP_STRING("AAA_STATE_SEND_AUTH2"),
296     (PUINT_8)DISP_STRING("AAA_STATE_SEND_AUTH4"),
297     (PUINT_8)DISP_STRING("AAA_STATE_SEND_ASSOC2"),
298     (PUINT_8)DISP_STRING("AA_STATE_RESOURCE")
299 };
300 /*lint -restore */
301 #endif /* DBG */
302
303 /*******************************************************************************
304 *                                 M A C R O S
305 ********************************************************************************
306 */
307
308 /*******************************************************************************
309 *                   F U N C T I O N   D E C L A R A T I O N S
310 ********************************************************************************
311 */
312
313 /*******************************************************************************
314 *                              F U N C T I O N S
315 ********************************************************************************
316 */
317 /*----------------------------------------------------------------------------*/
318 /*!
319 * @brief The Core FSM engine of SAA Module.
320 *
321 * @param[in] prStaRec           Pointer to the STA_RECORD_T
322 * @param[in] eNextState         The value of Next State
323 * @param[in] prRetainedSwRfb    Pointer to the retained SW_RFB_T for JOIN Success
324 *
325 * @return (none)
326 */
327 /*----------------------------------------------------------------------------*/
328 VOID
329 saaFsmSteps (
330     IN P_ADAPTER_T prAdapter,
331     IN P_STA_RECORD_T prStaRec,
332     IN ENUM_AA_STATE_T eNextState,
333     IN P_SW_RFB_T prRetainedSwRfb
334     )
335 {
336     ENUM_AA_STATE_T ePreviousState;
337     BOOLEAN fgIsTransition;
338
339
340     ASSERT(prStaRec);
341     if(!prStaRec) {
342         return;
343     }
344
345     do {
346
347 #if CFG_SUPPORT_XLOG
348         DBGLOG(SAA, STATE, ("[%d] TRANSITION: [%d] -> [%d]\n",
349                             DBG_SAA_IDX,
350                             prStaRec->eAuthAssocState,
351                             eNextState));
352 #else
353         DBGLOG(SAA, STATE, ("TRANSITION: [%s] -> [%s]\n",
354                             apucDebugAAState[prStaRec->eAuthAssocState],
355                             apucDebugAAState[eNextState]));
356 #endif
357         ePreviousState = prStaRec->eAuthAssocState;
358
359         /* NOTE(Kevin): This is the only place to change the eAuthAssocState(except initial) */
360         prStaRec->eAuthAssocState = eNextState;
361
362
363         fgIsTransition = (BOOLEAN)FALSE;
364         switch (prStaRec->eAuthAssocState) {
365         case AA_STATE_IDLE:
366             {
367                 if (ePreviousState != prStaRec->eAuthAssocState) { /* Only trigger this event once */
368
369                     if (prRetainedSwRfb) {
370
371                         if (saaFsmSendEventJoinComplete(prAdapter,
372                                     WLAN_STATUS_SUCCESS,
373                                     prStaRec,
374                                     prRetainedSwRfb) == WLAN_STATUS_SUCCESS) {
375                         }
376                         else {
377                             eNextState = AA_STATE_RESOURCE;
378                             fgIsTransition = TRUE;
379                         }
380                     }
381                     else {
382                         if (saaFsmSendEventJoinComplete(prAdapter,
383                                     WLAN_STATUS_FAILURE,
384                                     prStaRec,
385                                     NULL) == WLAN_STATUS_RESOURCES) {
386                             eNextState = AA_STATE_RESOURCE;
387                             fgIsTransition = TRUE;
388                         }
389                     }
390
391                 }
392
393                 /* Free allocated TCM memory */
394                 if (prStaRec->prChallengeText) {
395                     cnmMemFree(prAdapter, prStaRec->prChallengeText);
396                     prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T)NULL;
397                 }
398             }
399             break;
400
401         case SAA_STATE_SEND_AUTH1:
402             {
403                 /* Do tasks in INIT STATE */
404                 if (prStaRec->ucTxAuthAssocRetryCount >=
405                     prStaRec->ucTxAuthAssocRetryLimit) {
406
407                     /* Record the Status Code of Authentication Request */
408                     prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT;
409
410                     eNextState = AA_STATE_IDLE;
411                     fgIsTransition = TRUE;
412                 }
413                 else {
414                     prStaRec->ucTxAuthAssocRetryCount++;
415
416                     /* Update Station Record - Class 1 Flag */
417                     cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
418
419 #if !CFG_SUPPORT_AAA
420                     if (authSendAuthFrame(prAdapter,
421                                 prStaRec,
422                                 AUTH_TRANSACTION_SEQ_1) != WLAN_STATUS_SUCCESS)
423 #else
424                     if (authSendAuthFrame(
425                                         prAdapter,
426                                         prStaRec,
427                                         prStaRec->ucNetTypeIndex,
428                                         NULL,
429                                         AUTH_TRANSACTION_SEQ_1,
430                                         STATUS_CODE_RESERVED) != WLAN_STATUS_SUCCESS)
431 #endif /* CFG_SUPPORT_AAA */
432                     {
433
434                         cnmTimerInitTimer(prAdapter,
435                                 &prStaRec->rTxReqDoneOrRxRespTimer,
436                                 (PFN_MGMT_TIMEOUT_FUNC)saaFsmRunEventTxReqTimeOut,
437                                 (UINT_32)prStaRec);
438
439                         cnmTimerStartTimer(prAdapter,
440                                 &prStaRec->rTxReqDoneOrRxRespTimer,
441                                 TU_TO_MSEC(TX_AUTHENTICATION_RETRY_TIMEOUT_TU));
442                     }
443                 }
444             }
445             break;
446
447         case SAA_STATE_WAIT_AUTH2:
448             break;
449
450         case SAA_STATE_SEND_AUTH3:
451             {
452                 /* Do tasks in INIT STATE */
453                 if (prStaRec->ucTxAuthAssocRetryCount >=
454                     prStaRec->ucTxAuthAssocRetryLimit) {
455
456                     /* Record the Status Code of Authentication Request */
457                     prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT;
458
459                     eNextState = AA_STATE_IDLE;
460                     fgIsTransition = TRUE;
461                 }
462                 else {
463                     prStaRec->ucTxAuthAssocRetryCount++;
464
465 #if !CFG_SUPPORT_AAA
466                     if (authSendAuthFrame(prAdapter,
467                                 prStaRec,
468                                 AUTH_TRANSACTION_SEQ_3) != WLAN_STATUS_SUCCESS)
469 #else
470                     if (authSendAuthFrame(prAdapter,
471                                 prStaRec,
472                                 prStaRec->ucNetTypeIndex,
473                                 NULL,
474                                 AUTH_TRANSACTION_SEQ_3,
475                                 STATUS_CODE_RESERVED) != WLAN_STATUS_SUCCESS)
476 #endif /* CFG_SUPPORT_AAA */
477                     {
478
479                         cnmTimerInitTimer(prAdapter,
480                                 &prStaRec->rTxReqDoneOrRxRespTimer,
481                                 (PFN_MGMT_TIMEOUT_FUNC)saaFsmRunEventTxReqTimeOut,
482                                 (UINT_32)prStaRec);
483
484                         cnmTimerStartTimer(prAdapter,
485                                 &prStaRec->rTxReqDoneOrRxRespTimer,
486                                 TU_TO_MSEC(TX_AUTHENTICATION_RETRY_TIMEOUT_TU));
487                     }
488                 }
489             }
490             break;
491
492         case SAA_STATE_WAIT_AUTH4:
493             break;
494
495         case SAA_STATE_SEND_ASSOC1:
496                 /* Do tasks in INIT STATE */
497                 if (prStaRec->ucTxAuthAssocRetryCount >=
498                     prStaRec->ucTxAuthAssocRetryLimit) {
499
500                     /* Record the Status Code of Authentication Request */
501                     prStaRec->u2StatusCode = STATUS_CODE_ASSOC_TIMEOUT;
502
503                     eNextState = AA_STATE_IDLE;
504                     fgIsTransition = TRUE;
505                 }
506                 else {
507                     prStaRec->ucTxAuthAssocRetryCount++;
508
509                     if (assocSendReAssocReqFrame(prAdapter, prStaRec) != WLAN_STATUS_SUCCESS) {
510
511                         cnmTimerInitTimer(prAdapter,
512                                 &prStaRec->rTxReqDoneOrRxRespTimer,
513                                 (PFN_MGMT_TIMEOUT_FUNC)saaFsmRunEventTxReqTimeOut,
514                                 (UINT_32)prStaRec);
515
516                         cnmTimerStartTimer(prAdapter,
517                                 &prStaRec->rTxReqDoneOrRxRespTimer,
518                                 TU_TO_MSEC(TX_ASSOCIATION_RETRY_TIMEOUT_TU));
519                     }
520                 }
521
522             break;
523
524         case SAA_STATE_WAIT_ASSOC2:
525             break;
526
527         case AA_STATE_RESOURCE:
528             /* TODO(Kevin) Can setup a timer and send message later */
529             break;
530
531         default:
532             DBGLOG(SAA, ERROR, ("Unknown AA STATE\n"));
533             ASSERT(0);
534             break;
535         }
536
537     }
538     while (fgIsTransition);
539
540     return;
541
542 } /* end of saaFsmSteps() */
543
544
545 /*----------------------------------------------------------------------------*/
546 /*!
547 * @brief This function will send Event to AIS/BOW/P2P
548 *
549 * @param[in] rJoinStatus        To indicate JOIN success or failure.
550 * @param[in] prStaRec           Pointer to the STA_RECORD_T
551 * @param[in] prSwRfb            Pointer to the SW_RFB_T
552
553 * @return (none)
554 */
555 /*----------------------------------------------------------------------------*/
556 WLAN_STATUS
557 saaFsmSendEventJoinComplete (
558     IN P_ADAPTER_T prAdapter,
559     IN WLAN_STATUS rJoinStatus,
560     IN P_STA_RECORD_T prStaRec,
561     IN P_SW_RFB_T prSwRfb
562     )
563 {
564     P_BSS_INFO_T prBssInfo;
565
566     ASSERT(prStaRec);
567     if(!prStaRec) {
568         return WLAN_STATUS_INVALID_PACKET;
569     }
570
571     /* Store limitation about 40Mhz bandwidth capability during association */
572     if (prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM) {
573         prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex];
574
575         if (rJoinStatus == WLAN_STATUS_SUCCESS) {
576             prBssInfo->fg40mBwAllowed = prBssInfo->fgAssoc40mBwAllowed;
577         }
578         prBssInfo->fgAssoc40mBwAllowed = FALSE;
579     }
580
581     if(prStaRec->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) {
582         P_MSG_SAA_FSM_COMP_T prSaaFsmCompMsg;
583
584         prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SAA_FSM_COMP_T));
585         if (!prSaaFsmCompMsg) {
586             return WLAN_STATUS_RESOURCES;
587         }
588
589         prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_AIS_JOIN_COMPLETE;
590         prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum;
591         prSaaFsmCompMsg->rJoinStatus = rJoinStatus;
592         prSaaFsmCompMsg->prStaRec = prStaRec;
593         prSaaFsmCompMsg->prSwRfb = prSwRfb;
594
595         /* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */
596         mboxSendMsg(prAdapter,
597                 MBOX_ID_0,
598                 (P_MSG_HDR_T)prSaaFsmCompMsg,
599                 MSG_SEND_METHOD_UNBUF);
600
601         return WLAN_STATUS_SUCCESS;
602     }
603 #if CFG_ENABLE_WIFI_DIRECT
604     else if ((prAdapter->fgIsP2PRegistered) &&
605         (IS_STA_IN_P2P(prStaRec))) {
606         P_MSG_SAA_FSM_COMP_T prSaaFsmCompMsg;
607
608         prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SAA_FSM_COMP_T));
609         if (!prSaaFsmCompMsg) {
610             return WLAN_STATUS_RESOURCES;
611         }
612
613         prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_P2P_JOIN_COMPLETE;
614         prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum;
615         prSaaFsmCompMsg->rJoinStatus = rJoinStatus;
616         prSaaFsmCompMsg->prStaRec = prStaRec;
617         prSaaFsmCompMsg->prSwRfb = prSwRfb;
618
619         /* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */
620         mboxSendMsg(prAdapter,
621                 MBOX_ID_0,
622                 (P_MSG_HDR_T)prSaaFsmCompMsg,
623                 MSG_SEND_METHOD_UNBUF);
624
625         return WLAN_STATUS_SUCCESS;
626     }
627 #endif
628 #if CFG_ENABLE_BT_OVER_WIFI
629     else if(prStaRec->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) {
630         //@TODO: BOW handler
631
632         P_MSG_SAA_FSM_COMP_T prSaaFsmCompMsg;
633
634         prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SAA_FSM_COMP_T));
635         if (!prSaaFsmCompMsg) {
636             return WLAN_STATUS_RESOURCES;
637         }
638
639         prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_BOW_JOIN_COMPLETE;
640         prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum;
641         prSaaFsmCompMsg->rJoinStatus = rJoinStatus;
642         prSaaFsmCompMsg->prStaRec = prStaRec;
643         prSaaFsmCompMsg->prSwRfb = prSwRfb;
644
645         /* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */
646         mboxSendMsg(prAdapter,
647                 MBOX_ID_0,
648                 (P_MSG_HDR_T)prSaaFsmCompMsg,
649                 MSG_SEND_METHOD_UNBUF);
650
651         return WLAN_STATUS_SUCCESS;
652     }
653 #endif
654     else {
655         ASSERT(0);
656         return WLAN_STATUS_FAILURE;
657     }
658
659 } /* end of saaFsmSendEventJoinComplete() */
660
661
662 /*----------------------------------------------------------------------------*/
663 /*!
664 * @brief This function will handle the Start Event to SAA FSM.
665 *
666 * @param[in] prMsgHdr   Message of Join Request for a particular STA.
667 *
668 * @return (none)
669 */
670 /*----------------------------------------------------------------------------*/
671 VOID
672 saaFsmRunEventStart (
673     IN P_ADAPTER_T prAdapter,
674     IN P_MSG_HDR_T prMsgHdr
675     )
676 {
677     P_MSG_SAA_FSM_START_T prSaaFsmStartMsg;
678     P_STA_RECORD_T prStaRec;
679     P_BSS_INFO_T prBssInfo;
680
681     ASSERT(prAdapter);
682     ASSERT(prMsgHdr);
683
684     prSaaFsmStartMsg = (P_MSG_SAA_FSM_START_T)prMsgHdr;
685     prStaRec = prSaaFsmStartMsg->prStaRec;
686
687     if((!prStaRec) || (prStaRec->fgIsInUse == FALSE)) {
688         cnmMemFree(prAdapter, prMsgHdr);
689         return;
690     }
691
692     ASSERT(prStaRec);
693
694     DBGLOG(SAA, LOUD, ("EVENT-START: Trigger SAA FSM.\n"));
695
696     /* record sequence number of request message */
697     prStaRec->ucAuthAssocReqSeqNum = prSaaFsmStartMsg->ucSeqNum;
698
699     cnmMemFree(prAdapter, prMsgHdr);
700
701     //4 <1> Validation of SAA Start Event
702     if (!IS_AP_STA(prStaRec)) {
703
704         DBGLOG(SAA, ERROR, ("EVENT-START: STA Type - %d was not supported.\n", prStaRec->eStaType));
705
706         /* Ignore the return value because don't care the prSwRfb */
707         saaFsmSendEventJoinComplete(prAdapter, WLAN_STATUS_FAILURE, prStaRec, NULL);
708
709         return;
710     }
711
712     //4 <2> The previous JOIN process is not completed ?
713     if (prStaRec->eAuthAssocState != AA_STATE_IDLE) {
714         DBGLOG(SAA, ERROR, ("EVENT-START: Reentry of SAA Module.\n"));
715         prStaRec->eAuthAssocState = AA_STATE_IDLE;
716     }
717
718     //4 <3> Reset Status Code and Time
719     /* Update Station Record - Status/Reason Code */
720     prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL;
721
722     /* Update the record join time. */
723     GET_CURRENT_SYSTIME(&prStaRec->rLastJoinTime);
724
725     prStaRec->ucTxAuthAssocRetryCount = 0;
726
727     if (prStaRec->prChallengeText) {
728         cnmMemFree(prAdapter, prStaRec->prChallengeText);
729         prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T)NULL;
730     }
731
732     cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
733
734 #if CFG_PRIVACY_MIGRATION
735     //4 <4> Init the sec fsm
736     secFsmInit(prAdapter, prStaRec);
737 #endif
738
739     //4 <5> Reset the STA STATE
740     /* Update Station Record - Class 1 Flag */
741     /* NOTE(Kevin): Moved to AIS FSM for Reconnect issue -
742      * We won't deactivate the same STA_RECORD_T and then activate it again for the
743      * case of reconnection.
744      */
745     //cnmStaRecChangeState(prStaRec, STA_STATE_1);
746
747     //4 <6> Decide if this BSS 20/40M bandwidth is allowed
748     if (prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM) {
749         prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex];
750
751         if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N)
752             && (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) {
753             prBssInfo->fgAssoc40mBwAllowed =
754                 cnmBss40mBwPermitted(prAdapter, prBssInfo->ucNetTypeIndex);
755         }
756         else {
757             prBssInfo->fgAssoc40mBwAllowed = FALSE;
758         }
759         DBGLOG(RLM, INFO, ("STA 40mAllowed=%d\n", prBssInfo->fgAssoc40mBwAllowed));
760     }
761
762     //4 <7> Trigger SAA FSM
763     saaFsmSteps(prAdapter, prStaRec, SAA_STATE_SEND_AUTH1, (P_SW_RFB_T)NULL);
764
765     return;
766 } /* end of saaFsmRunEventStart() */
767
768
769 /*----------------------------------------------------------------------------*/
770 /*!
771 * @brief This function will handle TxDone(Auth1/Auth3/AssocReq) Event of SAA FSM.
772 *
773 * @param[in] prMsduInfo     Pointer to the MSDU_INFO_T.
774 * @param[in] rTxDoneStatus  Return TX status of the Auth1/Auth3/AssocReq frame.
775 *
776 * @retval WLAN_STATUS_SUCCESS
777 */
778 /*----------------------------------------------------------------------------*/
779 WLAN_STATUS
780 saaFsmRunEventTxDone (
781     IN P_ADAPTER_T              prAdapter,
782     IN P_MSDU_INFO_T            prMsduInfo,
783     IN ENUM_TX_RESULT_CODE_T    rTxDoneStatus
784     )
785 {
786
787     P_STA_RECORD_T prStaRec;
788     ENUM_AA_STATE_T eNextState;
789
790
791     ASSERT(prMsduInfo);
792
793     prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
794
795     if(!prStaRec) {
796         return WLAN_STATUS_INVALID_PACKET;
797     }
798
799     ASSERT(prStaRec);
800
801     DBGLOG(SAA, LOUD, ("EVENT-TX DONE: Current Time = %ld\n", kalGetTimeTick()));
802
803     eNextState = prStaRec->eAuthAssocState;
804
805     switch (prStaRec->eAuthAssocState) {
806     case SAA_STATE_SEND_AUTH1:
807         {
808             /* Strictly check the outgoing frame is matched with current AA STATE */
809             if (authCheckTxAuthFrame(prAdapter,
810                         prMsduInfo,
811                         AUTH_TRANSACTION_SEQ_1) != WLAN_STATUS_SUCCESS) {
812                 break;
813             }
814
815             if (rTxDoneStatus == TX_RESULT_SUCCESS) {
816                 eNextState = SAA_STATE_WAIT_AUTH2;
817
818                 cnmTimerStopTimer(prAdapter,
819                         &prStaRec->rTxReqDoneOrRxRespTimer);
820
821                 cnmTimerInitTimer(prAdapter,
822                         &prStaRec->rTxReqDoneOrRxRespTimer,
823                         (PFN_MGMT_TIMEOUT_FUNC)saaFsmRunEventRxRespTimeOut,
824                         (UINT_32)prStaRec);
825
826                 cnmTimerStartTimer(prAdapter,
827                         &prStaRec->rTxReqDoneOrRxRespTimer,
828                         TU_TO_MSEC(DOT11_AUTHENTICATION_RESPONSE_TIMEOUT_TU));
829             }
830
831             /* if TX was successful, change to next state.
832              * if TX was failed, do retry if possible.
833              */
834             saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T)NULL);
835         }
836         break;
837
838     case SAA_STATE_SEND_AUTH3:
839         {
840             /* Strictly check the outgoing frame is matched with current JOIN STATE */
841             if (authCheckTxAuthFrame(prAdapter,
842                         prMsduInfo,
843                         AUTH_TRANSACTION_SEQ_3) != WLAN_STATUS_SUCCESS) {
844                 break;
845             }
846
847             if (rTxDoneStatus == TX_RESULT_SUCCESS) {
848                 eNextState = SAA_STATE_WAIT_AUTH4;
849
850                 cnmTimerStopTimer(prAdapter,
851                         &prStaRec->rTxReqDoneOrRxRespTimer);
852
853                 cnmTimerInitTimer(prAdapter,
854                         &prStaRec->rTxReqDoneOrRxRespTimer,
855                         (PFN_MGMT_TIMEOUT_FUNC)saaFsmRunEventRxRespTimeOut,
856                         (UINT_32)prStaRec);
857
858                 cnmTimerStartTimer(prAdapter,
859                         &prStaRec->rTxReqDoneOrRxRespTimer,
860                         TU_TO_MSEC(DOT11_AUTHENTICATION_RESPONSE_TIMEOUT_TU));
861             }
862
863             /* if TX was successful, change to next state.
864              * if TX was failed, do retry if possible.
865              */
866             saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T)NULL);
867         }
868         break;
869
870     case SAA_STATE_SEND_ASSOC1:
871         {
872             /* Strictly check the outgoing frame is matched with current SAA STATE */
873             if (assocCheckTxReAssocReqFrame(prAdapter, prMsduInfo) != WLAN_STATUS_SUCCESS) {
874                 break;
875             }
876
877             if (rTxDoneStatus == TX_RESULT_SUCCESS) {
878                 eNextState = SAA_STATE_WAIT_ASSOC2;
879
880                 cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
881
882                 cnmTimerInitTimer(prAdapter,
883                         &prStaRec->rTxReqDoneOrRxRespTimer,
884                         (PFN_MGMT_TIMEOUT_FUNC)saaFsmRunEventRxRespTimeOut,
885                         (UINT_32)prStaRec);
886
887                 cnmTimerStartTimer(prAdapter,
888                         &(prStaRec->rTxReqDoneOrRxRespTimer),
889                         TU_TO_MSEC(DOT11_ASSOCIATION_RESPONSE_TIMEOUT_TU));
890             }
891
892             /* if TX was successful, change to next state.
893              * if TX was failed, do retry if possible.
894              */
895             saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T)NULL);
896         }
897         break;
898
899     default:
900         break; /* Ignore other cases */
901     }
902
903
904     return WLAN_STATUS_SUCCESS;
905
906 } /* end of saaFsmRunEventTxDone() */
907
908
909 /*----------------------------------------------------------------------------*/
910 /*!
911 * @brief This function will send Tx Request Timeout Event to SAA FSM.
912 *
913 * @param[in] prStaRec           Pointer to the STA_RECORD_T
914 *
915 * @return (none)
916 */
917 /*----------------------------------------------------------------------------*/
918 VOID
919 saaFsmRunEventTxReqTimeOut (
920     IN P_ADAPTER_T prAdapter,
921     IN P_STA_RECORD_T prStaRec
922     )
923 {
924     ASSERT(prStaRec);
925     if(!prStaRec) {
926         return;
927     }
928
929     DBGLOG(SAA, LOUD, ("EVENT-TIMER: TX REQ TIMEOUT, Current Time = %ld\n", kalGetTimeTick()));
930
931     switch (prStaRec->eAuthAssocState) {
932     case SAA_STATE_SEND_AUTH1:
933     case SAA_STATE_SEND_AUTH3:
934     case SAA_STATE_SEND_ASSOC1:
935         saaFsmSteps(prAdapter, prStaRec, prStaRec->eAuthAssocState, (P_SW_RFB_T)NULL);
936         break;
937
938     default:
939         return;
940     }
941
942     return;
943 } /* end of saaFsmRunEventTxReqTimeOut() */
944
945
946 /*----------------------------------------------------------------------------*/
947 /*!
948 * @brief This function will send Rx Response Timeout Event to SAA FSM.
949 *
950 * @param[in] prStaRec           Pointer to the STA_RECORD_T
951 *
952 * @return (none)
953 */
954 /*----------------------------------------------------------------------------*/
955 VOID
956 saaFsmRunEventRxRespTimeOut (
957     IN P_ADAPTER_T prAdapter,
958     IN P_STA_RECORD_T prStaRec
959     )
960 {
961     ENUM_AA_STATE_T eNextState;
962
963
964     DBGLOG(SAA, LOUD, ("EVENT-TIMER: RX RESP TIMEOUT, Current Time = %ld\n", kalGetTimeTick()));
965
966     ASSERT(prStaRec);
967     if(!prStaRec) {
968         return;
969     }
970
971     eNextState = prStaRec->eAuthAssocState;
972
973     switch (prStaRec->eAuthAssocState) {
974     case SAA_STATE_WAIT_AUTH2:
975         /* Record the Status Code of Authentication Request */
976         prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT;
977
978         /* Pull back to earlier state to do retry */
979         eNextState = SAA_STATE_SEND_AUTH1;
980         break;
981
982     case SAA_STATE_WAIT_AUTH4:
983         /* Record the Status Code of Authentication Request */
984         prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT;
985
986         /* Pull back to earlier state to do retry */
987         eNextState = SAA_STATE_SEND_AUTH3;
988         break;
989
990     case SAA_STATE_WAIT_ASSOC2:
991         /* Record the Status Code of Authentication Request */
992         prStaRec->u2StatusCode = STATUS_CODE_ASSOC_TIMEOUT;
993
994         /* Pull back to earlier state to do retry */
995         eNextState = SAA_STATE_SEND_ASSOC1;
996         break;
997
998     default:
999         break; /* Ignore other cases */
1000     }
1001
1002
1003     if (eNextState != prStaRec->eAuthAssocState) {
1004         saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T)NULL);
1005     }
1006
1007     return;
1008 } /* end of saaFsmRunEventRxRespTimeOut() */
1009
1010
1011 /*----------------------------------------------------------------------------*/
1012 /*!
1013 * @brief This function will process the Rx Auth Response Frame and then
1014 *        trigger SAA FSM.
1015 *
1016 * @param[in] prSwRfb            Pointer to the SW_RFB_T structure.
1017 *
1018 * @return (none)
1019 */
1020 /*----------------------------------------------------------------------------*/
1021 VOID
1022 saaFsmRunEventRxAuth (
1023     IN P_ADAPTER_T prAdapter,
1024     IN P_SW_RFB_T prSwRfb
1025     )
1026 {
1027     P_STA_RECORD_T prStaRec;
1028     UINT_16 u2StatusCode;
1029     ENUM_AA_STATE_T eNextState;
1030
1031
1032     ASSERT(prSwRfb);
1033     prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
1034
1035     /* We should have the corresponding Sta Record. */
1036     if (!prStaRec) {
1037         ASSERT(0);
1038         return;
1039     }
1040
1041     if (!IS_AP_STA(prStaRec)) {
1042         return;
1043     }
1044
1045     switch(prStaRec->eAuthAssocState) {
1046     case SAA_STATE_SEND_AUTH1:
1047     case SAA_STATE_WAIT_AUTH2:
1048         /* Check if the incoming frame is what we are waiting for */
1049         if (authCheckRxAuthFrameStatus(prAdapter,
1050                     prSwRfb,
1051                     AUTH_TRANSACTION_SEQ_2,
1052                     &u2StatusCode) == WLAN_STATUS_SUCCESS) {
1053
1054             cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
1055
1056             /* Record the Status Code of Authentication Request */
1057             prStaRec->u2StatusCode = u2StatusCode;
1058
1059             if (u2StatusCode == STATUS_CODE_SUCCESSFUL) {
1060
1061                 authProcessRxAuth2_Auth4Frame(prAdapter, prSwRfb);
1062
1063                 if (prStaRec->ucAuthAlgNum ==
1064                     (UINT_8)AUTH_ALGORITHM_NUM_SHARED_KEY) {
1065
1066                     eNextState = SAA_STATE_SEND_AUTH3;
1067                 }
1068                 else {
1069                     /* Update Station Record - Class 2 Flag */
1070                     cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2);
1071
1072                     eNextState = SAA_STATE_SEND_ASSOC1;
1073                 }
1074             }
1075             else {
1076                 DBGLOG(SAA, INFO, ("Auth Req was rejected by ["MACSTR"], Status Code = %d\n",
1077                     MAC2STR(prStaRec->aucMacAddr), u2StatusCode));
1078
1079                 eNextState = AA_STATE_IDLE;
1080             }
1081
1082             /* Reset Send Auth/(Re)Assoc Frame Count */
1083             prStaRec->ucTxAuthAssocRetryCount = 0;
1084
1085             saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T)NULL);
1086         }
1087         break;
1088
1089     case SAA_STATE_SEND_AUTH3:
1090     case SAA_STATE_WAIT_AUTH4:
1091         /* Check if the incoming frame is what we are waiting for */
1092         if (authCheckRxAuthFrameStatus(prAdapter,
1093                     prSwRfb,
1094                     AUTH_TRANSACTION_SEQ_4,
1095                     &u2StatusCode) == WLAN_STATUS_SUCCESS) {
1096
1097             cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
1098
1099             /* Record the Status Code of Authentication Request */
1100             prStaRec->u2StatusCode = u2StatusCode;
1101
1102             if (u2StatusCode == STATUS_CODE_SUCCESSFUL) {
1103
1104                 authProcessRxAuth2_Auth4Frame(prAdapter, prSwRfb); /* Add for 802.11r handling */
1105
1106                 /* Update Station Record - Class 2 Flag */
1107                 cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2);
1108
1109                 eNextState = SAA_STATE_SEND_ASSOC1;
1110             }
1111             else {
1112                 DBGLOG(SAA, INFO, ("Auth Req was rejected by ["MACSTR"], Status Code = %d\n",
1113                     MAC2STR(prStaRec->aucMacAddr), u2StatusCode));
1114
1115                 eNextState = AA_STATE_IDLE;
1116             }
1117
1118             /* Reset Send Auth/(Re)Assoc Frame Count */
1119             prStaRec->ucTxAuthAssocRetryCount = 0;
1120
1121             saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T)NULL);
1122         }
1123         break;
1124
1125     default:
1126         break; /* Ignore other cases */
1127     }
1128
1129     return;
1130 } /* end of saaFsmRunEventRxAuth() */
1131
1132
1133 /*----------------------------------------------------------------------------*/
1134 /*!
1135 * @brief This function will process the Rx (Re)Association Response Frame and then
1136 *        trigger SAA FSM.
1137 *
1138 * @param[in] prSwRfb            Pointer to the SW_RFB_T structure.
1139 *
1140 * @retval WLAN_STATUS_SUCCESS           if the status code was not success
1141 * @retval WLAN_STATUS_BUFFER_RETAINED   if the status code was success
1142 */
1143 /*----------------------------------------------------------------------------*/
1144 WLAN_STATUS
1145 saaFsmRunEventRxAssoc (
1146     IN P_ADAPTER_T prAdapter,
1147     IN P_SW_RFB_T prSwRfb
1148     )
1149 {
1150     P_STA_RECORD_T prStaRec;
1151     UINT_16 u2StatusCode;
1152     ENUM_AA_STATE_T eNextState;
1153     P_SW_RFB_T prRetainedSwRfb = (P_SW_RFB_T)NULL;
1154     WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
1155
1156
1157     ASSERT(prSwRfb);
1158     prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
1159
1160     /* We should have the corresponding Sta Record. */
1161     if (!prStaRec) {
1162         ASSERT(0);
1163         return rStatus;
1164     }
1165
1166     if (!IS_AP_STA(prStaRec)) {
1167         return rStatus;
1168     }
1169
1170     switch (prStaRec->eAuthAssocState) {
1171     case SAA_STATE_SEND_ASSOC1:
1172     case SAA_STATE_WAIT_ASSOC2:
1173         /* TRUE if the incoming frame is what we are waiting for */
1174         if (assocCheckRxReAssocRspFrameStatus(prAdapter,
1175                     prSwRfb,
1176                     &u2StatusCode) == WLAN_STATUS_SUCCESS) {
1177
1178             cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
1179
1180
1181             /* Record the Status Code of Authentication Request */
1182             prStaRec->u2StatusCode = u2StatusCode;
1183
1184             if (u2StatusCode == STATUS_CODE_SUCCESSFUL) {
1185
1186                 /* Update Station Record - Class 3 Flag */
1187                 /* NOTE(Kevin): Moved to AIS FSM for roaming issue -
1188                  * We should deactivate the STA_RECORD_T of previous AP before
1189                  * activate new one in Driver.
1190                  */
1191                 //cnmStaRecChangeState(prStaRec, STA_STATE_3);
1192
1193                 prStaRec->ucJoinFailureCount = 0; // Clear history.
1194
1195                 prRetainedSwRfb = prSwRfb;
1196                 rStatus = WLAN_STATUS_PENDING;
1197             }
1198             else {
1199                 DBGLOG(SAA, INFO, ("Assoc Req was rejected by ["MACSTR"], Status Code = %d\n",
1200                     MAC2STR(prStaRec->aucMacAddr), u2StatusCode));
1201             }
1202
1203             /* Reset Send Auth/(Re)Assoc Frame Count */
1204             prStaRec->ucTxAuthAssocRetryCount = 0;
1205
1206             /* update RCPI */
1207             prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi;
1208
1209             eNextState = AA_STATE_IDLE;
1210
1211             saaFsmSteps(prAdapter, prStaRec, eNextState, prRetainedSwRfb);
1212         }
1213         break;
1214
1215     default:
1216         break; /* Ignore other cases */
1217     }
1218
1219     return rStatus;
1220
1221 } /* end of saaFsmRunEventRxAssoc() */
1222
1223
1224 /*----------------------------------------------------------------------------*/
1225 /*!
1226 * @brief This function will check the incoming Deauth Frame.
1227 *
1228 * @param[in] prSwRfb            Pointer to the SW_RFB_T structure.
1229 *
1230 * @retval WLAN_STATUS_SUCCESS   Always not retain deauthentication frames
1231 */
1232 /*----------------------------------------------------------------------------*/
1233 WLAN_STATUS
1234 saaFsmRunEventRxDeauth (
1235     IN P_ADAPTER_T prAdapter,
1236     IN P_SW_RFB_T prSwRfb
1237     )
1238 {
1239     P_STA_RECORD_T prStaRec;
1240 #if DBG
1241     P_WLAN_DEAUTH_FRAME_T prDeauthFrame;
1242 #endif /* DBG */
1243
1244
1245     ASSERT(prSwRfb);
1246     prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
1247
1248 #if DBG
1249     prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) prSwRfb->pvHeader;
1250
1251     DBGLOG(SAA, INFO, ("Rx Deauth frame from BSSID=["MACSTR"].\n",
1252         MAC2STR(prDeauthFrame->aucBSSID)));
1253 #endif /* DBG */
1254
1255     do {
1256
1257         /* We should have the corresponding Sta Record. */
1258         if (!prStaRec) {
1259             break;
1260         }
1261
1262         if (IS_STA_IN_AIS(prStaRec)) {
1263             P_AIS_BSS_INFO_T prAisBssInfo;
1264
1265
1266             if (!IS_AP_STA(prStaRec)) {
1267                 break;
1268             }
1269
1270             prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
1271
1272             if (prStaRec->ucStaState > STA_STATE_1) {
1273
1274                 /* Check if this is the AP we are associated or associating with */
1275                 if (authProcessRxDeauthFrame(prSwRfb,
1276                             prStaRec->aucMacAddr,
1277                             &prStaRec->u2ReasonCode) == WLAN_STATUS_SUCCESS) {
1278
1279                     if (STA_STATE_3 == prStaRec->ucStaState) {
1280                         P_MSG_AIS_ABORT_T prAisAbortMsg;
1281
1282                         /* NOTE(Kevin): Change state immediately to avoid starvation of
1283                          * MSG buffer because of too many deauth frames before changing
1284                          * the STA state.
1285                          */
1286                         cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
1287
1288                         prAisAbortMsg = (P_MSG_AIS_ABORT_T)cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T));
1289                         if (!prAisAbortMsg) {
1290                             break;
1291                         }
1292
1293                         prAisAbortMsg->rMsgHdr.eMsgId = MID_SAA_AIS_FSM_ABORT;
1294                         prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_DEAUTHENTICATED;
1295                         prAisAbortMsg->fgDelayIndication = FALSE;
1296
1297                         mboxSendMsg(prAdapter,
1298                                 MBOX_ID_0,
1299                                 (P_MSG_HDR_T) prAisAbortMsg,
1300                                 MSG_SEND_METHOD_BUF);
1301                     }
1302                     else {
1303
1304                         /* TODO(Kevin): Joining Abort */
1305                     }
1306
1307                 }
1308
1309             }
1310
1311         }
1312 #if CFG_ENABLE_WIFI_DIRECT
1313         else if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) {
1314             /* TODO(Kevin) */
1315             prAdapter->rP2pFuncLkr.prP2pFsmRunEventRxDeauthentication(prAdapter, prStaRec, prSwRfb);
1316         }
1317 #endif
1318 #if CFG_ENABLE_BT_OVER_WIFI
1319         else if (IS_STA_IN_BOW(prStaRec)) {
1320             bowRunEventRxDeAuth(prAdapter, prStaRec, prSwRfb);
1321         }
1322 #endif
1323         else {
1324             ASSERT(0);
1325         }
1326
1327     } while (FALSE);
1328
1329     return WLAN_STATUS_SUCCESS;
1330
1331 } /* end of saaFsmRunEventRxDeauth() */
1332
1333
1334 /*----------------------------------------------------------------------------*/
1335 /*!
1336 * @brief This function will check the incoming Disassociation Frame.
1337 *
1338 * @param[in] prSwRfb            Pointer to the SW_RFB_T structure.
1339 *
1340 * @retval WLAN_STATUS_SUCCESS   Always not retain disassociation frames
1341 */
1342 /*----------------------------------------------------------------------------*/
1343 WLAN_STATUS
1344 saaFsmRunEventRxDisassoc (
1345     IN P_ADAPTER_T prAdapter,
1346     IN P_SW_RFB_T prSwRfb
1347     )
1348 {
1349     P_STA_RECORD_T prStaRec;
1350 #if DBG
1351     P_WLAN_DISASSOC_FRAME_T prDisassocFrame;
1352 #endif /* DBG */
1353
1354
1355     ASSERT(prSwRfb);
1356     prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
1357
1358 #if DBG
1359     prDisassocFrame = (P_WLAN_DISASSOC_FRAME_T) prSwRfb->pvHeader;
1360
1361     DBGLOG(SAA, INFO, ("Rx Disassoc frame from BSSID=["MACSTR"].\n",
1362         MAC2STR(prDisassocFrame->aucBSSID)));
1363 #endif /* DBG */
1364
1365     do {
1366
1367         /* We should have the corresponding Sta Record. */
1368         if (!prStaRec) {
1369             break;
1370         }
1371
1372         if (IS_STA_IN_AIS(prStaRec)) {
1373             P_AIS_BSS_INFO_T prAisBssInfo;
1374
1375
1376             if (!IS_AP_STA(prStaRec)) {
1377                 break;
1378             }
1379
1380             prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
1381
1382             if (prStaRec->ucStaState > STA_STATE_1) {
1383
1384                 /* Check if this is the AP we are associated or associating with */
1385                 if (assocProcessRxDisassocFrame(prAdapter,
1386                             prSwRfb,
1387                             prStaRec->aucMacAddr,
1388                             &prStaRec->u2ReasonCode) == WLAN_STATUS_SUCCESS) {
1389
1390                     if (STA_STATE_3 == prStaRec->ucStaState) {
1391                         P_MSG_AIS_ABORT_T prAisAbortMsg;
1392
1393                         prAisAbortMsg = (P_MSG_AIS_ABORT_T)cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T));
1394                         if (!prAisAbortMsg) {
1395                             break;
1396                         }
1397
1398                         prAisAbortMsg->rMsgHdr.eMsgId = MID_SAA_AIS_FSM_ABORT;
1399                         prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_DISASSOCIATED;
1400                         prAisAbortMsg->fgDelayIndication = FALSE;
1401
1402                         mboxSendMsg(prAdapter,
1403                                 MBOX_ID_0,
1404                                 (P_MSG_HDR_T) prAisAbortMsg,
1405                                 MSG_SEND_METHOD_BUF);
1406                     }
1407                     else {
1408
1409                         /* TODO(Kevin): Joining Abort */
1410                     }
1411
1412                 }
1413
1414             }
1415
1416         }
1417 #if CFG_ENABLE_WIFI_DIRECT
1418         else if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) {
1419             /* TODO(Kevin) */
1420             prAdapter->rP2pFuncLkr.prP2pFsmRunEventRxDisassociation(prAdapter, prStaRec, prSwRfb);
1421         }
1422 #endif
1423 #if CFG_ENABLE_BT_OVER_WIFI
1424         else if (IS_STA_IN_BOW(prStaRec)) {
1425             /* TODO(Kevin) */
1426         }
1427 #endif
1428         else {
1429             ASSERT(0);
1430         }
1431
1432     } while (FALSE);
1433
1434     return WLAN_STATUS_SUCCESS;
1435
1436 } /* end of saaFsmRunEventRxDisassoc() */
1437
1438
1439 /*----------------------------------------------------------------------------*/
1440 /*!
1441 * @brief This function will handle the Abort Event to SAA FSM.
1442 *
1443 * @param[in] prMsgHdr   Message of Abort Request for a particular STA.
1444 *
1445 * @return none
1446 */
1447 /*----------------------------------------------------------------------------*/
1448 VOID
1449 saaFsmRunEventAbort (
1450     IN P_ADAPTER_T prAdapter,
1451     IN P_MSG_HDR_T prMsgHdr
1452     )
1453 {
1454     P_MSG_SAA_FSM_ABORT_T prSaaFsmAbortMsg;
1455     P_STA_RECORD_T prStaRec;
1456
1457
1458     ASSERT(prMsgHdr);
1459
1460     prSaaFsmAbortMsg = (P_MSG_SAA_FSM_ABORT_T)prMsgHdr;
1461     prStaRec = prSaaFsmAbortMsg->prStaRec;
1462
1463     ASSERT(prStaRec);
1464     if(!prStaRec) {
1465         cnmMemFree(prAdapter, prMsgHdr);
1466         return;
1467     }
1468
1469     DBGLOG(SAA, LOUD, ("EVENT-ABORT: Stop SAA FSM.\n"));
1470
1471     cnmMemFree(prAdapter, prMsgHdr);
1472
1473
1474     /* Reset Send Auth/(Re)Assoc Frame Count */
1475     prStaRec->ucTxAuthAssocRetryCount = 0;
1476
1477     /* Cancel JOIN relative Timer */
1478     cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
1479
1480     if (prStaRec->eAuthAssocState != AA_STATE_IDLE) {
1481 #if DBG
1482         DBGLOG(SAA, LOUD, ("EVENT-ABORT: Previous Auth/Assoc State == %s.\n",
1483             apucDebugAAState[prStaRec->eAuthAssocState]));
1484 #else
1485         DBGLOG(SAA, LOUD, ("EVENT-ABORT: Previous Auth/Assoc State == %d.\n",
1486             prStaRec->eAuthAssocState));
1487 #endif
1488     }
1489
1490     /* For the Auth/Assoc State to IDLE */
1491     prStaRec->eAuthAssocState = AA_STATE_IDLE;
1492
1493     return;
1494 } /* end of saaFsmRunEventAbort() */
1495
1496
1497 /* TODO(Kevin): following code will be modified and move to AIS FSM */
1498 #if 0
1499 /*----------------------------------------------------------------------------*/
1500 /*!
1501 * \brief This function will send Join Timeout Event to JOIN FSM.
1502 *
1503 * \param[in] prAdapter      Pointer to the Adapter structure.
1504 *
1505 * \retval WLAN_STATUS_FAILURE   Fail because of Join Timeout
1506 */
1507 /*----------------------------------------------------------------------------*/
1508 WLAN_STATUS
1509 joinFsmRunEventJoinTimeOut (
1510     IN P_ADAPTER_T  prAdapter
1511     )
1512 {
1513     P_JOIN_INFO_T prJoinInfo;
1514     P_STA_RECORD_T prStaRec;
1515
1516     DEBUGFUNC("joinFsmRunEventJoinTimeOut");
1517
1518
1519     ASSERT(prAdapter);
1520     prJoinInfo = &prAdapter->rJoinInfo;
1521
1522     DBGLOG(JOIN, EVENT, ("JOIN EVENT: JOIN TIMEOUT\n"));
1523
1524     /* Get a Station Record if possible, TA == BSSID for AP */
1525     prStaRec = staRecGetStaRecordByAddr(prAdapter,
1526                                         prJoinInfo->prBssDesc->aucBSSID);
1527
1528     /* We have renew this Sta Record when in JOIN_STATE_INIT */
1529     ASSERT(prStaRec);
1530
1531     /* Record the Status Code of Authentication Request */
1532     prStaRec->u2StatusCode = STATUS_CODE_JOIN_TIMEOUT;
1533
1534     /* Increase Failure Count */
1535     prStaRec->ucJoinFailureCount++;
1536
1537     /* Reset Send Auth/(Re)Assoc Frame Count */
1538     prJoinInfo->ucTxAuthAssocRetryCount = 0;
1539
1540     /* Cancel other JOIN relative Timer */
1541     ARB_CANCEL_TIMER(prAdapter,
1542                      prJoinInfo->rTxRequestTimer);
1543
1544     ARB_CANCEL_TIMER(prAdapter,
1545                      prJoinInfo->rRxResponseTimer);
1546
1547     /* Restore original setting from current BSS_INFO_T */
1548     if (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED) {
1549         joinAdoptParametersFromCurrentBss(prAdapter);
1550     }
1551
1552     /* Pull back to IDLE */
1553     joinFsmSteps(prAdapter, JOIN_STATE_IDLE);
1554
1555     return WLAN_STATUS_FAILURE;
1556
1557 } /* end of joinFsmRunEventJoinTimeOut() */
1558
1559 /*----------------------------------------------------------------------------*/
1560 /*!
1561 * \brief This function will adopt the parameters from Peer BSS.
1562 *
1563 * \param[in] prAdapter      Pointer to the Adapter structure.
1564 *
1565 * \return (none)
1566 */
1567 /*----------------------------------------------------------------------------*/
1568 VOID
1569 joinAdoptParametersFromPeerBss (
1570     IN P_ADAPTER_T prAdapter
1571     )
1572 {
1573     P_JOIN_INFO_T prJoinInfo;
1574     P_BSS_DESC_T prBssDesc;
1575
1576     DEBUGFUNC("joinAdoptParametersFromPeerBss");
1577
1578
1579     ASSERT(prAdapter);
1580     prJoinInfo = &prAdapter->rJoinInfo;
1581     prBssDesc = prJoinInfo->prBssDesc;
1582
1583     //4 <1> Adopt Peer BSS' PHY TYPE
1584     prAdapter->eCurrentPhyType = prBssDesc->ePhyType;
1585
1586     DBGLOG(JOIN, INFO, ("Target BSS[%s]'s PhyType = %s\n",
1587         prBssDesc->aucSSID, (prBssDesc->ePhyType == PHY_TYPE_ERP_INDEX) ? "ERP" : "HR_DSSS"));
1588
1589
1590     //4 <2> Adopt Peer BSS' Frequency(Band/Channel)
1591     DBGLOG(JOIN, INFO, ("Target BSS's Channel = %d, Band = %d\n",
1592         prBssDesc->ucChannelNum, prBssDesc->eBand));
1593
1594     nicSwitchChannel(prAdapter,
1595                      prBssDesc->eBand,
1596                      prBssDesc->ucChannelNum,
1597                      10);
1598
1599     prJoinInfo->fgIsParameterAdopted = TRUE;
1600
1601     return;
1602 } /* end of joinAdoptParametersFromPeerBss() */
1603
1604
1605 /*----------------------------------------------------------------------------*/
1606 /*!
1607 * \brief This function will adopt the parameters from current associated BSS.
1608 *
1609 * \param[in] prAdapter      Pointer to the Adapter structure.
1610 *
1611 * \return (none)
1612 */
1613 /*----------------------------------------------------------------------------*/
1614 VOID
1615 joinAdoptParametersFromCurrentBss (
1616     IN P_ADAPTER_T prAdapter
1617     )
1618 {
1619     //P_JOIN_INFO_T prJoinInfo = &prAdapter->rJoinInfo;
1620     P_BSS_INFO_T prBssInfo;
1621
1622
1623     ASSERT(prAdapter);
1624     prBssInfo = &prAdapter->rBssInfo;
1625
1626     //4 <1> Adopt current BSS' PHY TYPE
1627     prAdapter->eCurrentPhyType = prBssInfo->ePhyType;
1628
1629     //4 <2> Adopt current BSS' Frequency(Band/Channel)
1630     DBGLOG(JOIN, INFO, ("Current BSS's Channel = %d, Band = %d\n",
1631         prBssInfo->ucChnl, prBssInfo->eBand));
1632
1633     nicSwitchChannel(prAdapter,
1634                      prBssInfo->eBand,
1635                      prBssInfo->ucChnl,
1636                      10);
1637     return;
1638 } /* end of joinAdoptParametersFromCurrentBss() */
1639
1640
1641 /*----------------------------------------------------------------------------*/
1642 /*!
1643 * \brief This function will update all the SW variables and HW MCR registers after
1644 *        the association with target BSS.
1645 *
1646 * \param[in] prAdapter      Pointer to the Adapter structure.
1647 *
1648 * \return (none)
1649 */
1650 /*----------------------------------------------------------------------------*/
1651 VOID
1652 joinComplete (
1653     IN P_ADAPTER_T prAdapter
1654     )
1655 {
1656     P_JOIN_INFO_T prJoinInfo;
1657     P_BSS_DESC_T prBssDesc;
1658     P_PEER_BSS_INFO_T prPeerBssInfo;
1659     P_BSS_INFO_T prBssInfo;
1660     P_CONNECTION_SETTINGS_T prConnSettings;
1661     P_STA_RECORD_T prStaRec;
1662     P_TX_CTRL_T prTxCtrl;
1663 #if CFG_SUPPORT_802_11D
1664     P_IE_COUNTRY_T          prIECountry;
1665 #endif
1666
1667     DEBUGFUNC("joinComplete");
1668
1669
1670     ASSERT(prAdapter);
1671     prJoinInfo = &prAdapter->rJoinInfo;
1672     prBssDesc = prJoinInfo->prBssDesc;
1673     prPeerBssInfo = &prAdapter->rPeerBssInfo;
1674     prBssInfo = &prAdapter->rBssInfo;
1675     prConnSettings = &prAdapter->rConnSettings;
1676     prTxCtrl = &prAdapter->rTxCtrl;
1677
1678 //4 <1> Update Connecting & Connected Flag of BSS_DESC_T.
1679     /* Remove previous AP's Connection Flags if have */
1680     scanRemoveConnectionFlagOfBssDescByBssid(prAdapter, prBssInfo->aucBSSID);
1681
1682     prBssDesc->fgIsConnected = TRUE; /* Mask as Connected */
1683
1684     if (prBssDesc->fgIsHiddenSSID) {
1685         /* NOTE(Kevin): This is for the case of Passive Scan and the target BSS didn't
1686          * broadcast SSID on its Beacon Frame.
1687          */
1688         COPY_SSID(prBssDesc->aucSSID,
1689                   prBssDesc->ucSSIDLen,
1690                   prAdapter->rConnSettings.aucSSID,
1691                   prAdapter->rConnSettings.ucSSIDLen);
1692
1693         if (prBssDesc->ucSSIDLen) {
1694             prBssDesc->fgIsHiddenSSID = FALSE;
1695         }
1696 #if DBG
1697         else {
1698             ASSERT(0);
1699         }
1700 #endif /* DBG */
1701
1702         DBGLOG(JOIN, INFO, ("Hidden SSID! - Update SSID : %s\n", prBssDesc->aucSSID));
1703     }
1704
1705
1706 //4 <2> Update BSS_INFO_T from BSS_DESC_T
1707     //4 <2.A> PHY Type
1708     prBssInfo->ePhyType = prBssDesc->ePhyType;
1709
1710     //4 <2.B> BSS Type
1711     prBssInfo->eBSSType = BSS_TYPE_INFRASTRUCTURE;
1712
1713     //4 <2.C> BSSID
1714     COPY_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID);
1715
1716     DBGLOG(JOIN, INFO, ("JOIN to BSSID: ["MACSTR"]\n", MAC2STR(prBssDesc->aucBSSID)));
1717
1718
1719     //4 <2.D> SSID
1720     COPY_SSID(prBssInfo->aucSSID,
1721               prBssInfo->ucSSIDLen,
1722               prBssDesc->aucSSID,
1723               prBssDesc->ucSSIDLen);
1724
1725     //4 <2.E> Channel / Band information.
1726     prBssInfo->eBand = prBssDesc->eBand;
1727     prBssInfo->ucChnl = prBssDesc->ucChannelNum;
1728
1729     //4 <2.F> RSN/WPA information.
1730     secFsmRunEventStart(prAdapter);
1731     prBssInfo->u4RsnSelectedPairwiseCipher = prBssDesc->u4RsnSelectedPairwiseCipher;
1732     prBssInfo->u4RsnSelectedGroupCipher = prBssDesc->u4RsnSelectedGroupCipher;
1733     prBssInfo->u4RsnSelectedAKMSuite = prBssDesc->u4RsnSelectedAKMSuite;
1734
1735     if (secRsnKeyHandshakeEnabled()) {
1736         prBssInfo->fgIsWPAorWPA2Enabled = TRUE;
1737     }
1738     else {
1739         prBssInfo->fgIsWPAorWPA2Enabled = FALSE;
1740     }
1741
1742     //4 <2.G> Beacon interval.
1743     prBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval;
1744
1745     //4 <2.H> DTIM period.
1746     prBssInfo->ucDtimPeriod = prBssDesc->ucDTIMPeriod;
1747
1748     //4 <2.I> ERP Information
1749     if ((prBssInfo->ePhyType == PHY_TYPE_ERP_INDEX) && // Our BSS's PHY_TYPE is ERP now.
1750         (prBssDesc->fgIsERPPresent)) {
1751
1752         prBssInfo->fgIsERPPresent = TRUE;
1753         prBssInfo->ucERP = prBssDesc->ucERP; /* Save the ERP for later check */
1754     }
1755     else { /* Some AP, may send ProbeResp without ERP IE. Thus prBssDesc->fgIsERPPresent is FALSE. */
1756         prBssInfo->fgIsERPPresent = FALSE;
1757         prBssInfo->ucERP = 0;
1758     }
1759
1760 #if CFG_SUPPORT_802_11D
1761     //4 <2.J> Country inforamtion of the associated AP
1762     if (prConnSettings->fgMultiDomainCapabilityEnabled) {
1763         DOMAIN_INFO_ENTRY   rDomainInfo;
1764         if (domainGetDomainInfoByScanResult(prAdapter, &rDomainInfo)) {
1765             if (prBssDesc->prIECountry) {
1766                 prIECountry = prBssDesc->prIECountry;
1767
1768                 domainParseCountryInfoElem(prIECountry, &prBssInfo->rDomainInfo);
1769
1770                 /* use the domain get from the BSS info */
1771                 prBssInfo->fgIsCountryInfoPresent = TRUE;
1772                 nicSetupOpChnlList(prAdapter, prBssInfo->rDomainInfo.u2CountryCode, FALSE);
1773             } else {
1774                 /* use the domain get from the scan result */
1775                 prBssInfo->fgIsCountryInfoPresent = TRUE;
1776                 nicSetupOpChnlList(prAdapter, rDomainInfo.u2CountryCode, FALSE);
1777             }
1778         }
1779     }
1780 #endif
1781
1782     //4 <2.K> Signal Power of the associated AP
1783     prBssInfo->rRcpi = prBssDesc->rRcpi;
1784     prBssInfo->rRssi = RCPI_TO_dBm(prBssInfo->rRcpi);
1785     GET_CURRENT_SYSTIME(&prBssInfo->rRssiLastUpdateTime);
1786
1787     //4 <2.L> Capability Field of the associated AP
1788     prBssInfo->u2CapInfo = prBssDesc->u2CapInfo;
1789
1790     DBGLOG(JOIN, INFO, ("prBssInfo-> fgIsERPPresent = %d, ucERP = %02x, rRcpi = %d, rRssi = %ld\n",
1791         prBssInfo->fgIsERPPresent, prBssInfo->ucERP, prBssInfo->rRcpi, prBssInfo->rRssi));
1792
1793
1794 //4 <3> Update BSS_INFO_T from PEER_BSS_INFO_T & NIC RATE FUNC
1795     //4 <3.A> Association ID
1796     prBssInfo->u2AssocId = prPeerBssInfo->u2AssocId;
1797
1798     //4 <3.B> WMM Infomation
1799     if (prAdapter->fgIsEnableWMM &&
1800         (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_SUPPORT_WMM)) {
1801
1802         prBssInfo->fgIsWmmAssoc = TRUE;
1803         prTxCtrl->rTxQForVoipAccess = TXQ_AC3;
1804
1805         qosWmmInfoInit(&prBssInfo->rWmmInfo, (prBssInfo->ePhyType == PHY_TYPE_HR_DSSS_INDEX) ? TRUE : FALSE);
1806
1807         if (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_AC_PARAM_PRESENT) {
1808             kalMemCopy(&prBssInfo->rWmmInfo,
1809                        &prPeerBssInfo->rWmmInfo,
1810                        sizeof(WMM_INFO_T));
1811         }
1812         else {
1813             kalMemCopy(&prBssInfo->rWmmInfo,
1814                        &prPeerBssInfo->rWmmInfo,
1815                        sizeof(WMM_INFO_T) - sizeof(prPeerBssInfo->rWmmInfo.arWmmAcParams));
1816         }
1817     }
1818     else {
1819         prBssInfo->fgIsWmmAssoc = FALSE;
1820         prTxCtrl->rTxQForVoipAccess = TXQ_AC1;
1821
1822         kalMemZero(&prBssInfo->rWmmInfo, sizeof(WMM_INFO_T));
1823     }
1824
1825
1826     //4 <3.C> Operational Rate Set & BSS Basic Rate Set
1827     prBssInfo->u2OperationalRateSet = prPeerBssInfo->u2OperationalRateSet;
1828     prBssInfo->u2BSSBasicRateSet = prPeerBssInfo->u2BSSBasicRateSet;
1829
1830
1831     //4 <3.D> Short Preamble
1832     if (prBssInfo->fgIsERPPresent) {
1833
1834         /* NOTE(Kevin 2007/12/24): Truth Table.
1835          * Short Preamble Bit in
1836          * <AssocReq>     <AssocResp w/i ERP>     <BARKER(Long)>  Final Driver Setting(Short)
1837          * TRUE            FALSE                  FALSE           FALSE(shouldn't have such case, use the AssocResp)
1838          * TRUE            FALSE                  TRUE            FALSE
1839          * FALSE           FALSE                  FALSE           FALSE(shouldn't have such case, use the AssocResp)
1840          * FALSE           FALSE                  TRUE            FALSE
1841          * TRUE            TRUE                   FALSE           TRUE(follow ERP)
1842          * TRUE            TRUE                   TRUE            FALSE(follow ERP)
1843          * FALSE           TRUE                   FALSE           FALSE(shouldn't have such case, and we should set to FALSE)
1844          * FALSE           TRUE                   TRUE            FALSE(we should set to FALSE)
1845          */
1846         if ((prPeerBssInfo->fgIsShortPreambleAllowed) &&
1847             ((prConnSettings->ePreambleType == PREAMBLE_TYPE_SHORT) || /* Short Preamble Option Enable is TRUE */
1848              ((prConnSettings->ePreambleType == PREAMBLE_TYPE_AUTO) &&
1849               (prBssDesc->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)))) {
1850
1851             prBssInfo->fgIsShortPreambleAllowed = TRUE;
1852
1853             if (prBssInfo->ucERP & ERP_INFO_BARKER_PREAMBLE_MODE) {
1854                 prBssInfo->fgUseShortPreamble = FALSE;
1855             }
1856             else {
1857                 prBssInfo->fgUseShortPreamble = TRUE;
1858             }
1859         }
1860         else {
1861             prBssInfo->fgIsShortPreambleAllowed = FALSE;
1862             prBssInfo->fgUseShortPreamble = FALSE;
1863         }
1864     }
1865     else {
1866         /* NOTE(Kevin 2007/12/24): Truth Table.
1867          * Short Preamble Bit in
1868          * <AssocReq>     <AssocResp w/o ERP>     Final Driver Setting(Short)
1869          * TRUE            FALSE                  FALSE
1870          * FALSE           FALSE                  FALSE
1871          * TRUE            TRUE                   TRUE
1872          * FALSE           TRUE(status success)   TRUE
1873          * --> Honor the result of prPeerBssInfo.
1874          */
1875
1876         prBssInfo->fgIsShortPreambleAllowed = prBssInfo->fgUseShortPreamble =
1877             prPeerBssInfo->fgIsShortPreambleAllowed;
1878     }
1879
1880     DBGLOG(JOIN, INFO, ("prBssInfo->fgIsShortPreambleAllowed = %d, prBssInfo->fgUseShortPreamble = %d\n",
1881         prBssInfo->fgIsShortPreambleAllowed, prBssInfo->fgUseShortPreamble));
1882
1883
1884     //4 <3.E> Short Slot Time
1885     prBssInfo->fgUseShortSlotTime =
1886         prPeerBssInfo->fgUseShortSlotTime; /* AP support Short Slot Time */
1887
1888     DBGLOG(JOIN, INFO, ("prBssInfo->fgUseShortSlotTime = %d\n",
1889         prBssInfo->fgUseShortSlotTime));
1890
1891     nicSetSlotTime(prAdapter,
1892                    prBssInfo->ePhyType,
1893                    ((prConnSettings->fgIsShortSlotTimeOptionEnable &&
1894                      prBssInfo->fgUseShortSlotTime) ? TRUE : FALSE));
1895
1896
1897     //4 <3.F> Update Tx Rate for Control Frame
1898     bssUpdateTxRateForControlFrame(prAdapter);
1899
1900
1901     //4 <3.G> Save the available Auth Types during Roaming (Design for Fast BSS Transition).
1902     //if (prAdapter->fgIsEnableRoaming) /* NOTE(Kevin): Always prepare info for roaming */
1903     {
1904
1905         if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_OPEN_SYSTEM) {
1906             prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_OPEN_SYSTEM;
1907         }
1908         else if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) {
1909             prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_SHARED_KEY;
1910         }
1911
1912         prBssInfo->ucRoamingAuthTypes = prJoinInfo->ucRoamingAuthTypes;
1913
1914
1915         /* Set the stable time of the associated BSS. We won't do roaming decision
1916          * during the stable time.
1917          */
1918         SET_EXPIRATION_TIME(prBssInfo->rRoamingStableExpirationTime,
1919             SEC_TO_SYSTIME(ROAMING_STABLE_TIMEOUT_SEC));
1920     }
1921
1922
1923     //4 <3.H> Update Parameter for TX Fragmentation Threshold
1924 #if CFG_TX_FRAGMENT
1925     txFragInfoUpdate(prAdapter);
1926 #endif /* CFG_TX_FRAGMENT */
1927
1928
1929 //4 <4> Update STA_RECORD_T
1930     /* Get a Station Record if possible */
1931     prStaRec = staRecGetStaRecordByAddr(prAdapter,
1932                                         prBssDesc->aucBSSID);
1933
1934     if (prStaRec) {
1935         UINT_16 u2OperationalRateSet, u2DesiredRateSet;
1936
1937         //4 <4.A> Desired Rate Set
1938         u2OperationalRateSet = (rPhyAttributes[prBssInfo->ePhyType].u2SupportedRateSet &
1939                                 prBssInfo->u2OperationalRateSet);
1940
1941         u2DesiredRateSet = (u2OperationalRateSet & prConnSettings->u2DesiredRateSet);
1942         if (u2DesiredRateSet) {
1943             prStaRec->u2DesiredRateSet = u2DesiredRateSet;
1944         }
1945         else {
1946             /* For Error Handling - The Desired Rate Set is not covered in Operational Rate Set. */
1947             prStaRec->u2DesiredRateSet = u2OperationalRateSet;
1948         }
1949
1950         /* Try to set the best initial rate for this entry */
1951         if (!rateGetBestInitialRateIndex(prStaRec->u2DesiredRateSet,
1952                                          prStaRec->rRcpi,
1953                                          &prStaRec->ucCurrRate1Index)) {
1954
1955             if (!rateGetLowestRateIndexFromRateSet(prStaRec->u2DesiredRateSet,
1956                                                    &prStaRec->ucCurrRate1Index)) {
1957                 ASSERT(0);
1958             }
1959         }
1960
1961         DBGLOG(JOIN, INFO, ("prStaRec->ucCurrRate1Index = %d\n",
1962             prStaRec->ucCurrRate1Index));
1963
1964         //4 <4.B> Preamble Mode
1965         prStaRec->fgIsShortPreambleOptionEnable =
1966             prBssInfo->fgUseShortPreamble;
1967
1968         //4 <4.C> QoS Flag
1969         prStaRec->fgIsQoS = prBssInfo->fgIsWmmAssoc;
1970     }
1971 #if DBG
1972     else {
1973         ASSERT(0);
1974     }
1975 #endif /* DBG */
1976
1977
1978 //4 <5> Update NIC
1979     //4 <5.A> Update BSSID & Operation Mode
1980     nicSetupBSS(prAdapter, prBssInfo);
1981
1982     //4 <5.B> Update WLAN Table.
1983     if (nicSetHwBySta(prAdapter, prStaRec) == FALSE) {
1984         ASSERT(FALSE);
1985     }
1986
1987     //4 <5.C> Update Desired Rate Set for BT.
1988 #if CFG_TX_FRAGMENT
1989     if (prConnSettings->fgIsEnableTxAutoFragmentForBT) {
1990         txRateSetInitForBT(prAdapter, prStaRec);
1991     }
1992 #endif /* CFG_TX_FRAGMENT */
1993
1994     //4 <5.D> TX AC Parameter and TX/RX Queue Control
1995     if (prBssInfo->fgIsWmmAssoc) {
1996
1997 #if CFG_TX_AGGREGATE_HW_FIFO
1998         nicTxAggregateTXQ(prAdapter, FALSE);
1999 #endif /* CFG_TX_AGGREGATE_HW_FIFO */
2000
2001         qosUpdateWMMParametersAndAssignAllowedACI(prAdapter, &prBssInfo->rWmmInfo);
2002     }
2003     else {
2004
2005 #if CFG_TX_AGGREGATE_HW_FIFO
2006         nicTxAggregateTXQ(prAdapter, TRUE);
2007 #endif /* CFG_TX_AGGREGATE_HW_FIFO */
2008
2009         nicTxNonQoSAssignDefaultAdmittedTXQ(prAdapter);
2010
2011         nicTxNonQoSUpdateTXQParameters(prAdapter,
2012                                        prBssInfo->ePhyType);
2013     }
2014
2015 #if CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN
2016     {
2017         prTxCtrl->fgBlockTxDuringJoin = FALSE;
2018
2019     #if !CFG_TX_AGGREGATE_HW_FIFO /* TX FIFO AGGREGATE already do flush once */
2020         nicTxFlushStopQueues(prAdapter, (UINT_8)TXQ_DATA_MASK, (UINT_8)NULL);
2021     #endif /* CFG_TX_AGGREGATE_HW_FIFO */
2022
2023         nicTxRetransmitOfSendWaitQue(prAdapter);
2024
2025         if (prTxCtrl->fgIsPacketInOsSendQueue) {
2026             nicTxRetransmitOfOsSendQue(prAdapter);
2027         }
2028
2029     #if CFG_SDIO_TX_ENHANCE
2030         halTxLeftClusteredMpdu(prAdapter);
2031     #endif /* CFG_SDIO_TX_ENHANCE */
2032
2033     }
2034 #endif /* CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN */
2035
2036
2037 //4 <6> Setup CONNECTION flag.
2038     prAdapter->eConnectionState = MEDIA_STATE_CONNECTED;
2039     prAdapter->eConnectionStateIndicated = MEDIA_STATE_CONNECTED;
2040
2041     if (prJoinInfo->fgIsReAssoc) {
2042         prAdapter->fgBypassPortCtrlForRoaming = TRUE;
2043     }
2044     else {
2045         prAdapter->fgBypassPortCtrlForRoaming = FALSE;
2046     }
2047
2048     kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
2049         WLAN_STATUS_MEDIA_CONNECT,
2050         (PVOID)NULL,
2051         0);
2052
2053     return;
2054 } /* end of joinComplete() */
2055 #endif
2056