2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/saa_fsm.c#2 $
6 \brief This file defines the FSM for SAA MODULE.
8 This file defines the FSM for SAA MODULE.
16 * 07 17 2012 yuche.tsai
18 * Compile no error before trial run.
21 * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC
25 * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
26 * Adjust code for DBG and CONFIG_XLOG.
29 * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
30 * modify the xlog related code.
33 * [WCXRP00001086] [MT6620 Wi-Fi][Driver] On Android, indicate an extra DISCONNECT for REASSOCIATED cases as an explicit trigger for Android framework
34 * 1. for DEAUTH/DISASSOC cases, indicate for DISCONNECTION immediately.
35 * 2. (Android only) when reassociation-and-non-roaming cases happened, indicate an extra DISCONNECT indication to Android Wi-Fi framework
38 * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
39 * adding the code for XLOG.
42 * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band
43 * Add debug message about 40MHz bandwidth allowed
46 * [WCXRP00000720] [MT6620 Wi-Fi][Driver] Do not do any further operation in case STA-REC has been invalidated before SAA-FSM starts to roll
47 * check for valid STA-REC before SAA-FSM starts to roll.
50 * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame
51 * Add network type parameter to authSendAuthFrame.
53 * 04 15 2011 chinghwa.yu
54 * [WCXRP00000065] Update BoW design and settings
55 * Add BOW short range mode.
58 * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
65 * 02 10 2011 yuche.tsai
66 * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
67 * Add RX deauthentication & disassociation process under Hot-Spot mode.
69 * 01 26 2011 yuche.tsai
70 * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
73 * 01 25 2011 yuche.tsai
74 * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
75 * Fix compile error of after Station Type Macro modification.
77 * 01 25 2011 yuche.tsai
78 * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
79 * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role.
82 * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC for initial TX rate selection of auto-rate algorithm
83 * update ucRcpi of STA_RECORD_T for AIS when
84 * 1) Beacons for IBSS merge is received
85 * 2) Associate Response for a connecting peer is received
88 * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS associated
89 * 1. remove redundant variables in STA_REC structure
90 * 2. add STA-REC uninitialization routine for clearing pending events
92 * 09 03 2010 kevin.huang
94 * Refine #include sequence and solve recursive/nested #include issue
98 * eliminate klockwork errors
100 * 08 24 2010 chinghwa.yu
102 * Update for MID_SCN_BOW_SCAN_DONE mboxDummy.
103 * Update saa_fsm for BOW.
107 * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI.
108 * There is no CFG_SUPPORT_BOW in driver domain source.
110 * 08 02 2010 yuche.tsai
112 * Add support for P2P join event start.
116 * SAA will take a record for tracking request sequence number.
120 * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
123 * [WPD00003833][MT6620 and MT5931] Driver migration
124 * AIS-FSM integration with CNM channel request messages
127 * [WPD00003833][MT6620 and MT5931] Driver migration
128 * sync. with main branch for reseting to state 1 when associating with another AP
131 * [WPD00003833][MT6620 and MT5931] Driver migration
132 * refine TX-DONE callback.
135 * [WPD00003840][MT6620 5931] Security migration
136 * remove duplicate variable for migration.
138 * 06 18 2010 cm.chang
139 * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
140 * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
143 * [WPD00003840][MT6620 5931] Security migration
144 * migration the security related function from firmware.
146 * 06 17 2010 yuche.tsai
147 * [WPD00003839][MT6620 5931][P2P] Feature migration
148 * Fix compile error when enable WiFi Direct function.
151 * [WPD00003833][MT6620 and MT5931] Driver migration
152 * saa_fsm.c is migrated.
154 * 05 12 2010 kevin.huang
155 * [BORA00000794][WIFISYS][New Feature]Power Management Support
156 * Add Power Management - Legacy PS-POLL support.
158 * 04 24 2010 cm.chang
159 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
160 * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW
162 * 04 19 2010 kevin.huang
163 * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support
165 * * * Add Connection Policy - Any and Rx Burst Deauth Support for WHQL
167 * 03 10 2010 kevin.huang
168 * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support
169 * Add Channel Manager for arbitration of JOIN and SCAN Req
171 * 02 26 2010 kevin.huang
172 * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
173 * Add support of Driver STA_RECORD_T activation
175 * 02 04 2010 kevin.huang
176 * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
177 * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
180 * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code
181 * add and fixed some security function.
183 * 01 12 2010 kevin.huang
184 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
185 * Fix compile warning due to declared but not used
187 * 01 11 2010 kevin.huang
188 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
189 * Add Deauth and Disassoc Handler
191 * 01 08 2010 kevin.huang
192 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
195 * 12 18 2009 cm.chang
196 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
199 * Dec 3 2009 mtk01461
200 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
203 * Dec 1 2009 mtk01088
204 * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
205 * rename the function
207 * Nov 24 2009 mtk01461
208 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
209 * Revise MGMT Handler with Retain Status
211 * Nov 23 2009 mtk01461
212 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
216 /*******************************************************************************
217 * C O M P I L E R F L A G S
218 ********************************************************************************
221 /*******************************************************************************
222 * E X T E R N A L R E F E R E N C E S
223 ********************************************************************************
227 /*******************************************************************************
229 ********************************************************************************
232 /*******************************************************************************
234 ********************************************************************************
237 /*******************************************************************************
238 * P U B L I C D A T A
239 ********************************************************************************
242 /*******************************************************************************
243 * P R I V A T E D A T A
244 ********************************************************************************
247 /*lint -save -e64 Type mismatch */
248 static PUINT_8 apucDebugAAState[AA_STATE_NUM] = {
249 (PUINT_8)DISP_STRING("AA_STATE_IDLE"),
250 (PUINT_8)DISP_STRING("SAA_STATE_SEND_AUTH1"),
251 (PUINT_8)DISP_STRING("SAA_STATE_WAIT_AUTH2"),
252 (PUINT_8)DISP_STRING("SAA_STATE_SEND_AUTH3"),
253 (PUINT_8)DISP_STRING("SAA_STATE_WAIT_AUTH4"),
254 (PUINT_8)DISP_STRING("SAA_STATE_SEND_ASSOC1"),
255 (PUINT_8)DISP_STRING("SAA_STATE_WAIT_ASSOC2"),
256 (PUINT_8)DISP_STRING("AAA_STATE_SEND_AUTH2"),
257 (PUINT_8)DISP_STRING("AAA_STATE_SEND_AUTH4"),
258 (PUINT_8)DISP_STRING("AAA_STATE_SEND_ASSOC2"),
259 (PUINT_8)DISP_STRING("AA_STATE_RESOURCE")
264 /*******************************************************************************
266 ********************************************************************************
269 /*******************************************************************************
270 * F U N C T I O N D E C L A R A T I O N S
271 ********************************************************************************
274 /*******************************************************************************
276 ********************************************************************************
278 /*----------------------------------------------------------------------------*/
280 * @brief The Core FSM engine of SAA Module.
282 * @param[in] prStaRec Pointer to the STA_RECORD_T
283 * @param[in] eNextState The value of Next State
284 * @param[in] prRetainedSwRfb Pointer to the retained SW_RFB_T for JOIN Success
288 /*----------------------------------------------------------------------------*/
291 IN P_ADAPTER_T prAdapter,
292 IN P_STA_RECORD_T prStaRec,
293 IN ENUM_AA_STATE_T eNextState,
294 IN P_SW_RFB_T prRetainedSwRfb
297 ENUM_AA_STATE_T ePreviousState;
298 BOOLEAN fgIsTransition;
309 DBGLOG(SAA, STATE, ("TRANSITION: [%s] -> [%s]\n",
310 apucDebugAAState[prStaRec->eAuthAssocState],
311 apucDebugAAState[eNextState]));
313 DBGLOG(SAA, STATE, ("[%d] TRANSITION: [%d] -> [%d]\n",
315 prStaRec->eAuthAssocState,
318 ePreviousState = prStaRec->eAuthAssocState;
320 /* NOTE(Kevin): This is the only place to change the eAuthAssocState(except initial) */
321 prStaRec->eAuthAssocState = eNextState;
324 fgIsTransition = (BOOLEAN)FALSE;
325 switch (prStaRec->eAuthAssocState) {
328 if (ePreviousState != prStaRec->eAuthAssocState) { /* Only trigger this event once */
330 if (prRetainedSwRfb) {
332 if (saaFsmSendEventJoinComplete(prAdapter,
335 prRetainedSwRfb) == WLAN_STATUS_SUCCESS) {
338 eNextState = AA_STATE_RESOURCE;
339 fgIsTransition = TRUE;
343 if (saaFsmSendEventJoinComplete(prAdapter,
346 NULL) == WLAN_STATUS_RESOURCES) {
347 eNextState = AA_STATE_RESOURCE;
348 fgIsTransition = TRUE;
354 /* Free allocated TCM memory */
355 if (prStaRec->prChallengeText) {
356 cnmMemFree(prAdapter, prStaRec->prChallengeText);
357 prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T)NULL;
362 case SAA_STATE_SEND_AUTH1:
364 /* Do tasks in INIT STATE */
365 if (prStaRec->ucTxAuthAssocRetryCount >=
366 prStaRec->ucTxAuthAssocRetryLimit) {
368 /* Record the Status Code of Authentication Request */
369 prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT;
371 eNextState = AA_STATE_IDLE;
372 fgIsTransition = TRUE;
375 prStaRec->ucTxAuthAssocRetryCount++;
377 /* Update Station Record - Class 1 Flag */
378 cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
381 if (authSendAuthFrame(prAdapter,
383 AUTH_TRANSACTION_SEQ_1) != WLAN_STATUS_SUCCESS)
385 if (authSendAuthFrame(
388 prStaRec->ucNetTypeIndex,
390 AUTH_TRANSACTION_SEQ_1,
391 STATUS_CODE_RESERVED) != WLAN_STATUS_SUCCESS)
392 #endif /* CFG_SUPPORT_AAA */
395 cnmTimerInitTimer(prAdapter,
396 &prStaRec->rTxReqDoneOrRxRespTimer,
397 (PFN_MGMT_TIMEOUT_FUNC)saaFsmRunEventTxReqTimeOut,
400 cnmTimerStartTimer(prAdapter,
401 &prStaRec->rTxReqDoneOrRxRespTimer,
402 TU_TO_MSEC(TX_AUTHENTICATION_RETRY_TIMEOUT_TU));
408 case SAA_STATE_WAIT_AUTH2:
411 case SAA_STATE_SEND_AUTH3:
413 /* Do tasks in INIT STATE */
414 if (prStaRec->ucTxAuthAssocRetryCount >=
415 prStaRec->ucTxAuthAssocRetryLimit) {
417 /* Record the Status Code of Authentication Request */
418 prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT;
420 eNextState = AA_STATE_IDLE;
421 fgIsTransition = TRUE;
424 prStaRec->ucTxAuthAssocRetryCount++;
427 if (authSendAuthFrame(prAdapter,
429 AUTH_TRANSACTION_SEQ_3) != WLAN_STATUS_SUCCESS)
431 if (authSendAuthFrame(prAdapter,
433 prStaRec->ucNetTypeIndex,
435 AUTH_TRANSACTION_SEQ_3,
436 STATUS_CODE_RESERVED) != WLAN_STATUS_SUCCESS)
437 #endif /* CFG_SUPPORT_AAA */
440 cnmTimerInitTimer(prAdapter,
441 &prStaRec->rTxReqDoneOrRxRespTimer,
442 (PFN_MGMT_TIMEOUT_FUNC)saaFsmRunEventTxReqTimeOut,
445 cnmTimerStartTimer(prAdapter,
446 &prStaRec->rTxReqDoneOrRxRespTimer,
447 TU_TO_MSEC(TX_AUTHENTICATION_RETRY_TIMEOUT_TU));
453 case SAA_STATE_WAIT_AUTH4:
456 case SAA_STATE_SEND_ASSOC1:
457 /* Do tasks in INIT STATE */
458 if (prStaRec->ucTxAuthAssocRetryCount >=
459 prStaRec->ucTxAuthAssocRetryLimit) {
461 /* Record the Status Code of Authentication Request */
462 prStaRec->u2StatusCode = STATUS_CODE_ASSOC_TIMEOUT;
464 eNextState = AA_STATE_IDLE;
465 fgIsTransition = TRUE;
468 prStaRec->ucTxAuthAssocRetryCount++;
470 if (assocSendReAssocReqFrame(prAdapter, prStaRec) != WLAN_STATUS_SUCCESS) {
472 cnmTimerInitTimer(prAdapter,
473 &prStaRec->rTxReqDoneOrRxRespTimer,
474 (PFN_MGMT_TIMEOUT_FUNC)saaFsmRunEventTxReqTimeOut,
477 cnmTimerStartTimer(prAdapter,
478 &prStaRec->rTxReqDoneOrRxRespTimer,
479 TU_TO_MSEC(TX_ASSOCIATION_RETRY_TIMEOUT_TU));
485 case SAA_STATE_WAIT_ASSOC2:
488 case AA_STATE_RESOURCE:
489 /* TODO(Kevin) Can setup a timer and send message later */
493 DBGLOG(SAA, ERROR, ("Unknown AA STATE\n"));
499 while (fgIsTransition);
503 } /* end of saaFsmSteps() */
506 /*----------------------------------------------------------------------------*/
508 * @brief This function will send Event to AIS/BOW/P2P
510 * @param[in] rJoinStatus To indicate JOIN success or failure.
511 * @param[in] prStaRec Pointer to the STA_RECORD_T
512 * @param[in] prSwRfb Pointer to the SW_RFB_T
516 /*----------------------------------------------------------------------------*/
518 saaFsmSendEventJoinComplete (
519 IN P_ADAPTER_T prAdapter,
520 IN WLAN_STATUS rJoinStatus,
521 IN P_STA_RECORD_T prStaRec,
522 IN P_SW_RFB_T prSwRfb
525 P_BSS_INFO_T prBssInfo;
529 return WLAN_STATUS_INVALID_PACKET;
532 /* Store limitation about 40Mhz bandwidth capability during association */
533 if (prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM) {
534 prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex];
536 if (rJoinStatus == WLAN_STATUS_SUCCESS) {
537 prBssInfo->fg40mBwAllowed = prBssInfo->fgAssoc40mBwAllowed;
539 prBssInfo->fgAssoc40mBwAllowed = FALSE;
542 if(prStaRec->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) {
543 P_MSG_SAA_FSM_COMP_T prSaaFsmCompMsg;
545 prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SAA_FSM_COMP_T));
546 if (!prSaaFsmCompMsg) {
547 return WLAN_STATUS_RESOURCES;
550 prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_AIS_JOIN_COMPLETE;
551 prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum;
552 prSaaFsmCompMsg->rJoinStatus = rJoinStatus;
553 prSaaFsmCompMsg->prStaRec = prStaRec;
554 prSaaFsmCompMsg->prSwRfb = prSwRfb;
556 /* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */
557 mboxSendMsg(prAdapter,
559 (P_MSG_HDR_T)prSaaFsmCompMsg,
560 MSG_SEND_METHOD_UNBUF);
562 return WLAN_STATUS_SUCCESS;
564 #if CFG_ENABLE_WIFI_DIRECT
565 else if ((prAdapter->fgIsP2PRegistered) &&
566 (IS_STA_IN_P2P(prStaRec))) {
567 P_MSG_SAA_FSM_COMP_T prSaaFsmCompMsg;
569 prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SAA_FSM_COMP_T));
570 if (!prSaaFsmCompMsg) {
571 return WLAN_STATUS_RESOURCES;
574 prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_P2P_JOIN_COMPLETE;
575 prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum;
576 prSaaFsmCompMsg->rJoinStatus = rJoinStatus;
577 prSaaFsmCompMsg->prStaRec = prStaRec;
578 prSaaFsmCompMsg->prSwRfb = prSwRfb;
580 /* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */
581 mboxSendMsg(prAdapter,
583 (P_MSG_HDR_T)prSaaFsmCompMsg,
584 MSG_SEND_METHOD_UNBUF);
586 return WLAN_STATUS_SUCCESS;
589 #if CFG_ENABLE_BT_OVER_WIFI
590 else if(prStaRec->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) {
593 P_MSG_SAA_FSM_COMP_T prSaaFsmCompMsg;
595 prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SAA_FSM_COMP_T));
596 if (!prSaaFsmCompMsg) {
597 return WLAN_STATUS_RESOURCES;
600 prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_BOW_JOIN_COMPLETE;
601 prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum;
602 prSaaFsmCompMsg->rJoinStatus = rJoinStatus;
603 prSaaFsmCompMsg->prStaRec = prStaRec;
604 prSaaFsmCompMsg->prSwRfb = prSwRfb;
606 /* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */
607 mboxSendMsg(prAdapter,
609 (P_MSG_HDR_T)prSaaFsmCompMsg,
610 MSG_SEND_METHOD_UNBUF);
612 return WLAN_STATUS_SUCCESS;
617 return WLAN_STATUS_FAILURE;
620 } /* end of saaFsmSendEventJoinComplete() */
623 /*----------------------------------------------------------------------------*/
625 * @brief This function will handle the Start Event to SAA FSM.
627 * @param[in] prMsgHdr Message of Join Request for a particular STA.
631 /*----------------------------------------------------------------------------*/
633 saaFsmRunEventStart (
634 IN P_ADAPTER_T prAdapter,
635 IN P_MSG_HDR_T prMsgHdr
638 P_MSG_SAA_FSM_START_T prSaaFsmStartMsg;
639 P_STA_RECORD_T prStaRec;
640 P_BSS_INFO_T prBssInfo;
645 prSaaFsmStartMsg = (P_MSG_SAA_FSM_START_T)prMsgHdr;
646 prStaRec = prSaaFsmStartMsg->prStaRec;
648 if((!prStaRec) || (prStaRec->fgIsInUse == FALSE)) {
649 cnmMemFree(prAdapter, prMsgHdr);
655 DBGLOG(SAA, LOUD, ("EVENT-START: Trigger SAA FSM.\n"));
657 /* record sequence number of request message */
658 prStaRec->ucAuthAssocReqSeqNum = prSaaFsmStartMsg->ucSeqNum;
660 cnmMemFree(prAdapter, prMsgHdr);
662 //4 <1> Validation of SAA Start Event
663 if (!IS_AP_STA(prStaRec)) {
665 DBGLOG(SAA, ERROR, ("EVENT-START: STA Type - %d was not supported.\n", prStaRec->eStaType));
667 /* Ignore the return value because don't care the prSwRfb */
668 saaFsmSendEventJoinComplete(prAdapter, WLAN_STATUS_FAILURE, prStaRec, NULL);
673 //4 <2> The previous JOIN process is not completed ?
674 if (prStaRec->eAuthAssocState != AA_STATE_IDLE) {
675 DBGLOG(SAA, ERROR, ("EVENT-START: Reentry of SAA Module.\n"));
676 prStaRec->eAuthAssocState = AA_STATE_IDLE;
679 //4 <3> Reset Status Code and Time
680 /* Update Station Record - Status/Reason Code */
681 prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL;
683 /* Update the record join time. */
684 GET_CURRENT_SYSTIME(&prStaRec->rLastJoinTime);
686 prStaRec->ucTxAuthAssocRetryCount = 0;
688 if (prStaRec->prChallengeText) {
689 cnmMemFree(prAdapter, prStaRec->prChallengeText);
690 prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T)NULL;
693 cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
695 #if CFG_PRIVACY_MIGRATION
696 //4 <4> Init the sec fsm
697 secFsmInit(prAdapter, prStaRec);
700 //4 <5> Reset the STA STATE
701 /* Update Station Record - Class 1 Flag */
702 /* NOTE(Kevin): Moved to AIS FSM for Reconnect issue -
703 * We won't deactivate the same STA_RECORD_T and then activate it again for the
704 * case of reconnection.
706 //cnmStaRecChangeState(prStaRec, STA_STATE_1);
708 //4 <6> Decide if this BSS 20/40M bandwidth is allowed
709 if (prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM) {
710 prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex];
712 if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N)
713 && (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) {
714 prBssInfo->fgAssoc40mBwAllowed =
715 cnmBss40mBwPermitted(prAdapter, prBssInfo->ucNetTypeIndex);
718 prBssInfo->fgAssoc40mBwAllowed = FALSE;
720 DBGLOG(RLM, INFO, ("STA 40mAllowed=%d\n", prBssInfo->fgAssoc40mBwAllowed));
723 //4 <7> Trigger SAA FSM
724 saaFsmSteps(prAdapter, prStaRec, SAA_STATE_SEND_AUTH1, (P_SW_RFB_T)NULL);
727 } /* end of saaFsmRunEventStart() */
730 /*----------------------------------------------------------------------------*/
732 * @brief This function will handle TxDone(Auth1/Auth3/AssocReq) Event of SAA FSM.
734 * @param[in] prMsduInfo Pointer to the MSDU_INFO_T.
735 * @param[in] rTxDoneStatus Return TX status of the Auth1/Auth3/AssocReq frame.
737 * @retval WLAN_STATUS_SUCCESS
739 /*----------------------------------------------------------------------------*/
741 saaFsmRunEventTxDone (
742 IN P_ADAPTER_T prAdapter,
743 IN P_MSDU_INFO_T prMsduInfo,
744 IN ENUM_TX_RESULT_CODE_T rTxDoneStatus
748 P_STA_RECORD_T prStaRec;
749 ENUM_AA_STATE_T eNextState;
754 prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
757 return WLAN_STATUS_INVALID_PACKET;
762 DBGLOG(SAA, LOUD, ("EVENT-TX DONE: Current Time = %ld\n", kalGetTimeTick()));
764 eNextState = prStaRec->eAuthAssocState;
766 switch (prStaRec->eAuthAssocState) {
767 case SAA_STATE_SEND_AUTH1:
769 /* Strictly check the outgoing frame is matched with current AA STATE */
770 if (authCheckTxAuthFrame(prAdapter,
772 AUTH_TRANSACTION_SEQ_1) != WLAN_STATUS_SUCCESS) {
776 if (rTxDoneStatus == TX_RESULT_SUCCESS) {
777 eNextState = SAA_STATE_WAIT_AUTH2;
779 cnmTimerStopTimer(prAdapter,
780 &prStaRec->rTxReqDoneOrRxRespTimer);
782 cnmTimerInitTimer(prAdapter,
783 &prStaRec->rTxReqDoneOrRxRespTimer,
784 (PFN_MGMT_TIMEOUT_FUNC)saaFsmRunEventRxRespTimeOut,
787 cnmTimerStartTimer(prAdapter,
788 &prStaRec->rTxReqDoneOrRxRespTimer,
789 TU_TO_MSEC(DOT11_AUTHENTICATION_RESPONSE_TIMEOUT_TU));
792 /* if TX was successful, change to next state.
793 * if TX was failed, do retry if possible.
795 saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T)NULL);
799 case SAA_STATE_SEND_AUTH3:
801 /* Strictly check the outgoing frame is matched with current JOIN STATE */
802 if (authCheckTxAuthFrame(prAdapter,
804 AUTH_TRANSACTION_SEQ_3) != WLAN_STATUS_SUCCESS) {
808 if (rTxDoneStatus == TX_RESULT_SUCCESS) {
809 eNextState = SAA_STATE_WAIT_AUTH4;
811 cnmTimerStopTimer(prAdapter,
812 &prStaRec->rTxReqDoneOrRxRespTimer);
814 cnmTimerInitTimer(prAdapter,
815 &prStaRec->rTxReqDoneOrRxRespTimer,
816 (PFN_MGMT_TIMEOUT_FUNC)saaFsmRunEventRxRespTimeOut,
819 cnmTimerStartTimer(prAdapter,
820 &prStaRec->rTxReqDoneOrRxRespTimer,
821 TU_TO_MSEC(DOT11_AUTHENTICATION_RESPONSE_TIMEOUT_TU));
824 /* if TX was successful, change to next state.
825 * if TX was failed, do retry if possible.
827 saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T)NULL);
831 case SAA_STATE_SEND_ASSOC1:
833 /* Strictly check the outgoing frame is matched with current SAA STATE */
834 if (assocCheckTxReAssocReqFrame(prAdapter, prMsduInfo) != WLAN_STATUS_SUCCESS) {
838 if (rTxDoneStatus == TX_RESULT_SUCCESS) {
839 eNextState = SAA_STATE_WAIT_ASSOC2;
841 cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
843 cnmTimerInitTimer(prAdapter,
844 &prStaRec->rTxReqDoneOrRxRespTimer,
845 (PFN_MGMT_TIMEOUT_FUNC)saaFsmRunEventRxRespTimeOut,
848 cnmTimerStartTimer(prAdapter,
849 &(prStaRec->rTxReqDoneOrRxRespTimer),
850 TU_TO_MSEC(DOT11_ASSOCIATION_RESPONSE_TIMEOUT_TU));
853 /* if TX was successful, change to next state.
854 * if TX was failed, do retry if possible.
856 saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T)NULL);
861 break; /* Ignore other cases */
865 return WLAN_STATUS_SUCCESS;
867 } /* end of saaFsmRunEventTxDone() */
870 /*----------------------------------------------------------------------------*/
872 * @brief This function will send Tx Request Timeout Event to SAA FSM.
874 * @param[in] prStaRec Pointer to the STA_RECORD_T
878 /*----------------------------------------------------------------------------*/
880 saaFsmRunEventTxReqTimeOut (
881 IN P_ADAPTER_T prAdapter,
882 IN P_STA_RECORD_T prStaRec
890 DBGLOG(SAA, LOUD, ("EVENT-TIMER: TX REQ TIMEOUT, Current Time = %ld\n", kalGetTimeTick()));
892 switch (prStaRec->eAuthAssocState) {
893 case SAA_STATE_SEND_AUTH1:
894 case SAA_STATE_SEND_AUTH3:
895 case SAA_STATE_SEND_ASSOC1:
896 saaFsmSteps(prAdapter, prStaRec, prStaRec->eAuthAssocState, (P_SW_RFB_T)NULL);
904 } /* end of saaFsmRunEventTxReqTimeOut() */
907 /*----------------------------------------------------------------------------*/
909 * @brief This function will send Rx Response Timeout Event to SAA FSM.
911 * @param[in] prStaRec Pointer to the STA_RECORD_T
915 /*----------------------------------------------------------------------------*/
917 saaFsmRunEventRxRespTimeOut (
918 IN P_ADAPTER_T prAdapter,
919 IN P_STA_RECORD_T prStaRec
922 ENUM_AA_STATE_T eNextState;
925 DBGLOG(SAA, LOUD, ("EVENT-TIMER: RX RESP TIMEOUT, Current Time = %ld\n", kalGetTimeTick()));
932 eNextState = prStaRec->eAuthAssocState;
934 switch (prStaRec->eAuthAssocState) {
935 case SAA_STATE_WAIT_AUTH2:
936 /* Record the Status Code of Authentication Request */
937 prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT;
939 /* Pull back to earlier state to do retry */
940 eNextState = SAA_STATE_SEND_AUTH1;
943 case SAA_STATE_WAIT_AUTH4:
944 /* Record the Status Code of Authentication Request */
945 prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT;
947 /* Pull back to earlier state to do retry */
948 eNextState = SAA_STATE_SEND_AUTH3;
951 case SAA_STATE_WAIT_ASSOC2:
952 /* Record the Status Code of Authentication Request */
953 prStaRec->u2StatusCode = STATUS_CODE_ASSOC_TIMEOUT;
955 /* Pull back to earlier state to do retry */
956 eNextState = SAA_STATE_SEND_ASSOC1;
960 break; /* Ignore other cases */
964 if (eNextState != prStaRec->eAuthAssocState) {
965 saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T)NULL);
969 } /* end of saaFsmRunEventRxRespTimeOut() */
972 /*----------------------------------------------------------------------------*/
974 * @brief This function will process the Rx Auth Response Frame and then
977 * @param[in] prSwRfb Pointer to the SW_RFB_T structure.
981 /*----------------------------------------------------------------------------*/
983 saaFsmRunEventRxAuth (
984 IN P_ADAPTER_T prAdapter,
985 IN P_SW_RFB_T prSwRfb
988 P_STA_RECORD_T prStaRec;
989 UINT_16 u2StatusCode;
990 ENUM_AA_STATE_T eNextState;
994 prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
996 /* We should have the corresponding Sta Record. */
1002 if (!IS_AP_STA(prStaRec)) {
1006 switch(prStaRec->eAuthAssocState) {
1007 case SAA_STATE_SEND_AUTH1:
1008 case SAA_STATE_WAIT_AUTH2:
1009 /* Check if the incoming frame is what we are waiting for */
1010 if (authCheckRxAuthFrameStatus(prAdapter,
1012 AUTH_TRANSACTION_SEQ_2,
1013 &u2StatusCode) == WLAN_STATUS_SUCCESS) {
1015 cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
1017 /* Record the Status Code of Authentication Request */
1018 prStaRec->u2StatusCode = u2StatusCode;
1020 if (u2StatusCode == STATUS_CODE_SUCCESSFUL) {
1022 authProcessRxAuth2_Auth4Frame(prAdapter, prSwRfb);
1024 if (prStaRec->ucAuthAlgNum ==
1025 (UINT_8)AUTH_ALGORITHM_NUM_SHARED_KEY) {
1027 eNextState = SAA_STATE_SEND_AUTH3;
1030 /* Update Station Record - Class 2 Flag */
1031 cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2);
1033 eNextState = SAA_STATE_SEND_ASSOC1;
1037 DBGLOG(SAA, INFO, ("Auth Req was rejected by ["MACSTR"], Status Code = %d\n",
1038 MAC2STR(prStaRec->aucMacAddr), u2StatusCode));
1040 eNextState = AA_STATE_IDLE;
1043 /* Reset Send Auth/(Re)Assoc Frame Count */
1044 prStaRec->ucTxAuthAssocRetryCount = 0;
1046 saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T)NULL);
1050 case SAA_STATE_SEND_AUTH3:
1051 case SAA_STATE_WAIT_AUTH4:
1052 /* Check if the incoming frame is what we are waiting for */
1053 if (authCheckRxAuthFrameStatus(prAdapter,
1055 AUTH_TRANSACTION_SEQ_4,
1056 &u2StatusCode) == WLAN_STATUS_SUCCESS) {
1058 cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
1060 /* Record the Status Code of Authentication Request */
1061 prStaRec->u2StatusCode = u2StatusCode;
1063 if (u2StatusCode == STATUS_CODE_SUCCESSFUL) {
1065 authProcessRxAuth2_Auth4Frame(prAdapter, prSwRfb); /* Add for 802.11r handling */
1067 /* Update Station Record - Class 2 Flag */
1068 cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2);
1070 eNextState = SAA_STATE_SEND_ASSOC1;
1073 DBGLOG(SAA, INFO, ("Auth Req was rejected by ["MACSTR"], Status Code = %d\n",
1074 MAC2STR(prStaRec->aucMacAddr), u2StatusCode));
1076 eNextState = AA_STATE_IDLE;
1079 /* Reset Send Auth/(Re)Assoc Frame Count */
1080 prStaRec->ucTxAuthAssocRetryCount = 0;
1082 saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T)NULL);
1087 break; /* Ignore other cases */
1091 } /* end of saaFsmRunEventRxAuth() */
1094 /*----------------------------------------------------------------------------*/
1096 * @brief This function will process the Rx (Re)Association Response Frame and then
1099 * @param[in] prSwRfb Pointer to the SW_RFB_T structure.
1101 * @retval WLAN_STATUS_SUCCESS if the status code was not success
1102 * @retval WLAN_STATUS_BUFFER_RETAINED if the status code was success
1104 /*----------------------------------------------------------------------------*/
1106 saaFsmRunEventRxAssoc (
1107 IN P_ADAPTER_T prAdapter,
1108 IN P_SW_RFB_T prSwRfb
1111 P_STA_RECORD_T prStaRec;
1112 UINT_16 u2StatusCode;
1113 ENUM_AA_STATE_T eNextState;
1114 P_SW_RFB_T prRetainedSwRfb = (P_SW_RFB_T)NULL;
1115 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
1119 prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
1121 /* We should have the corresponding Sta Record. */
1127 if (!IS_AP_STA(prStaRec)) {
1131 switch (prStaRec->eAuthAssocState) {
1132 case SAA_STATE_SEND_ASSOC1:
1133 case SAA_STATE_WAIT_ASSOC2:
1134 /* TRUE if the incoming frame is what we are waiting for */
1135 if (assocCheckRxReAssocRspFrameStatus(prAdapter,
1137 &u2StatusCode) == WLAN_STATUS_SUCCESS) {
1139 cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
1142 /* Record the Status Code of Authentication Request */
1143 prStaRec->u2StatusCode = u2StatusCode;
1145 if (u2StatusCode == STATUS_CODE_SUCCESSFUL) {
1147 /* Update Station Record - Class 3 Flag */
1148 /* NOTE(Kevin): Moved to AIS FSM for roaming issue -
1149 * We should deactivate the STA_RECORD_T of previous AP before
1150 * activate new one in Driver.
1152 //cnmStaRecChangeState(prStaRec, STA_STATE_3);
1154 prStaRec->ucJoinFailureCount = 0; // Clear history.
1156 prRetainedSwRfb = prSwRfb;
1157 rStatus = WLAN_STATUS_PENDING;
1160 DBGLOG(SAA, INFO, ("Assoc Req was rejected by ["MACSTR"], Status Code = %d\n",
1161 MAC2STR(prStaRec->aucMacAddr), u2StatusCode));
1164 /* Reset Send Auth/(Re)Assoc Frame Count */
1165 prStaRec->ucTxAuthAssocRetryCount = 0;
1168 prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi;
1170 eNextState = AA_STATE_IDLE;
1172 saaFsmSteps(prAdapter, prStaRec, eNextState, prRetainedSwRfb);
1177 break; /* Ignore other cases */
1182 } /* end of saaFsmRunEventRxAssoc() */
1185 /*----------------------------------------------------------------------------*/
1187 * @brief This function will check the incoming Deauth Frame.
1189 * @param[in] prSwRfb Pointer to the SW_RFB_T structure.
1191 * @retval WLAN_STATUS_SUCCESS Always not retain deauthentication frames
1193 /*----------------------------------------------------------------------------*/
1195 saaFsmRunEventRxDeauth (
1196 IN P_ADAPTER_T prAdapter,
1197 IN P_SW_RFB_T prSwRfb
1200 P_STA_RECORD_T prStaRec;
1202 P_WLAN_DEAUTH_FRAME_T prDeauthFrame;
1207 prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
1210 prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) prSwRfb->pvHeader;
1212 DBGLOG(SAA, INFO, ("Rx Deauth frame from BSSID=["MACSTR"].\n",
1213 MAC2STR(prDeauthFrame->aucBSSID)));
1218 /* We should have the corresponding Sta Record. */
1223 if (IS_STA_IN_AIS(prStaRec)) {
1224 P_AIS_BSS_INFO_T prAisBssInfo;
1227 if (!IS_AP_STA(prStaRec)) {
1231 prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
1233 if (prStaRec->ucStaState > STA_STATE_1) {
1235 /* Check if this is the AP we are associated or associating with */
1236 if (authProcessRxDeauthFrame(prSwRfb,
1237 prStaRec->aucMacAddr,
1238 &prStaRec->u2ReasonCode) == WLAN_STATUS_SUCCESS) {
1240 if (STA_STATE_3 == prStaRec->ucStaState) {
1241 P_MSG_AIS_ABORT_T prAisAbortMsg;
1243 /* NOTE(Kevin): Change state immediately to avoid starvation of
1244 * MSG buffer because of too many deauth frames before changing
1247 cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
1249 prAisAbortMsg = (P_MSG_AIS_ABORT_T)cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T));
1250 if (!prAisAbortMsg) {
1254 prAisAbortMsg->rMsgHdr.eMsgId = MID_SAA_AIS_FSM_ABORT;
1255 prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_DEAUTHENTICATED;
1256 prAisAbortMsg->fgDelayIndication = FALSE;
1258 mboxSendMsg(prAdapter,
1260 (P_MSG_HDR_T) prAisAbortMsg,
1261 MSG_SEND_METHOD_BUF);
1265 /* TODO(Kevin): Joining Abort */
1273 #if CFG_ENABLE_WIFI_DIRECT
1274 else if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) {
1276 p2pFsmRunEventRxDeauthentication(prAdapter, prStaRec, prSwRfb);
1279 #if CFG_ENABLE_BT_OVER_WIFI
1280 else if (IS_STA_IN_BOW(prStaRec)) {
1281 bowRunEventRxDeAuth(prAdapter, prStaRec, prSwRfb);
1290 return WLAN_STATUS_SUCCESS;
1292 } /* end of saaFsmRunEventRxDeauth() */
1295 /*----------------------------------------------------------------------------*/
1297 * @brief This function will check the incoming Disassociation Frame.
1299 * @param[in] prSwRfb Pointer to the SW_RFB_T structure.
1301 * @retval WLAN_STATUS_SUCCESS Always not retain disassociation frames
1303 /*----------------------------------------------------------------------------*/
1305 saaFsmRunEventRxDisassoc (
1306 IN P_ADAPTER_T prAdapter,
1307 IN P_SW_RFB_T prSwRfb
1310 P_STA_RECORD_T prStaRec;
1312 P_WLAN_DISASSOC_FRAME_T prDisassocFrame;
1317 prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
1320 prDisassocFrame = (P_WLAN_DISASSOC_FRAME_T) prSwRfb->pvHeader;
1322 DBGLOG(SAA, INFO, ("Rx Disassoc frame from BSSID=["MACSTR"].\n",
1323 MAC2STR(prDisassocFrame->aucBSSID)));
1328 /* We should have the corresponding Sta Record. */
1333 if (IS_STA_IN_AIS(prStaRec)) {
1334 P_AIS_BSS_INFO_T prAisBssInfo;
1337 if (!IS_AP_STA(prStaRec)) {
1341 prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
1343 if (prStaRec->ucStaState > STA_STATE_1) {
1345 /* Check if this is the AP we are associated or associating with */
1346 if (assocProcessRxDisassocFrame(prAdapter,
1348 prStaRec->aucMacAddr,
1349 &prStaRec->u2ReasonCode) == WLAN_STATUS_SUCCESS) {
1351 if (STA_STATE_3 == prStaRec->ucStaState) {
1352 P_MSG_AIS_ABORT_T prAisAbortMsg;
1354 prAisAbortMsg = (P_MSG_AIS_ABORT_T)cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T));
1355 if (!prAisAbortMsg) {
1359 prAisAbortMsg->rMsgHdr.eMsgId = MID_SAA_AIS_FSM_ABORT;
1360 prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_DISASSOCIATED;
1361 prAisAbortMsg->fgDelayIndication = FALSE;
1363 mboxSendMsg(prAdapter,
1365 (P_MSG_HDR_T) prAisAbortMsg,
1366 MSG_SEND_METHOD_BUF);
1370 /* TODO(Kevin): Joining Abort */
1378 #if CFG_ENABLE_WIFI_DIRECT
1379 else if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) {
1381 p2pFsmRunEventRxDisassociation(prAdapter, prStaRec, prSwRfb);
1384 #if CFG_ENABLE_BT_OVER_WIFI
1385 else if (IS_STA_IN_BOW(prStaRec)) {
1395 return WLAN_STATUS_SUCCESS;
1397 } /* end of saaFsmRunEventRxDisassoc() */
1400 /*----------------------------------------------------------------------------*/
1402 * @brief This function will handle the Abort Event to SAA FSM.
1404 * @param[in] prMsgHdr Message of Abort Request for a particular STA.
1408 /*----------------------------------------------------------------------------*/
1410 saaFsmRunEventAbort (
1411 IN P_ADAPTER_T prAdapter,
1412 IN P_MSG_HDR_T prMsgHdr
1415 P_MSG_SAA_FSM_ABORT_T prSaaFsmAbortMsg;
1416 P_STA_RECORD_T prStaRec;
1421 prSaaFsmAbortMsg = (P_MSG_SAA_FSM_ABORT_T)prMsgHdr;
1422 prStaRec = prSaaFsmAbortMsg->prStaRec;
1426 cnmMemFree(prAdapter, prMsgHdr);
1430 DBGLOG(SAA, LOUD, ("EVENT-ABORT: Stop SAA FSM.\n"));
1432 cnmMemFree(prAdapter, prMsgHdr);
1435 /* Reset Send Auth/(Re)Assoc Frame Count */
1436 prStaRec->ucTxAuthAssocRetryCount = 0;
1438 /* Cancel JOIN relative Timer */
1439 cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
1441 if (prStaRec->eAuthAssocState != AA_STATE_IDLE) {
1443 DBGLOG(SAA, LOUD, ("EVENT-ABORT: Previous Auth/Assoc State == %s.\n",
1444 apucDebugAAState[prStaRec->eAuthAssocState]));
1446 DBGLOG(SAA, LOUD, ("EVENT-ABORT: Previous Auth/Assoc State == %d.\n",
1447 prStaRec->eAuthAssocState));
1452 /* For the Auth/Assoc State to IDLE */
1453 prStaRec->eAuthAssocState = AA_STATE_IDLE;
1455 /* Free this StaRec */
1456 cnmStaRecFree(prAdapter, prStaRec, FALSE);
1460 } /* end of saaFsmRunEventAbort() */
1463 /* TODO(Kevin): following code will be modified and move to AIS FSM */
1465 /*----------------------------------------------------------------------------*/
1467 * \brief This function will send Join Timeout Event to JOIN FSM.
1469 * \param[in] prAdapter Pointer to the Adapter structure.
1471 * \retval WLAN_STATUS_FAILURE Fail because of Join Timeout
1473 /*----------------------------------------------------------------------------*/
1475 joinFsmRunEventJoinTimeOut (
1476 IN P_ADAPTER_T prAdapter
1479 P_JOIN_INFO_T prJoinInfo;
1480 P_STA_RECORD_T prStaRec;
1482 DEBUGFUNC("joinFsmRunEventJoinTimeOut");
1486 prJoinInfo = &prAdapter->rJoinInfo;
1488 DBGLOG(JOIN, EVENT, ("JOIN EVENT: JOIN TIMEOUT\n"));
1490 /* Get a Station Record if possible, TA == BSSID for AP */
1491 prStaRec = staRecGetStaRecordByAddr(prAdapter,
1492 prJoinInfo->prBssDesc->aucBSSID);
1494 /* We have renew this Sta Record when in JOIN_STATE_INIT */
1497 /* Record the Status Code of Authentication Request */
1498 prStaRec->u2StatusCode = STATUS_CODE_JOIN_TIMEOUT;
1500 /* Increase Failure Count */
1501 prStaRec->ucJoinFailureCount++;
1503 /* Reset Send Auth/(Re)Assoc Frame Count */
1504 prJoinInfo->ucTxAuthAssocRetryCount = 0;
1506 /* Cancel other JOIN relative Timer */
1507 ARB_CANCEL_TIMER(prAdapter,
1508 prJoinInfo->rTxRequestTimer);
1510 ARB_CANCEL_TIMER(prAdapter,
1511 prJoinInfo->rRxResponseTimer);
1513 /* Restore original setting from current BSS_INFO_T */
1514 if (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED) {
1515 joinAdoptParametersFromCurrentBss(prAdapter);
1518 /* Pull back to IDLE */
1519 joinFsmSteps(prAdapter, JOIN_STATE_IDLE);
1521 return WLAN_STATUS_FAILURE;
1523 } /* end of joinFsmRunEventJoinTimeOut() */
1525 /*----------------------------------------------------------------------------*/
1527 * \brief This function will adopt the parameters from Peer BSS.
1529 * \param[in] prAdapter Pointer to the Adapter structure.
1533 /*----------------------------------------------------------------------------*/
1535 joinAdoptParametersFromPeerBss (
1536 IN P_ADAPTER_T prAdapter
1539 P_JOIN_INFO_T prJoinInfo;
1540 P_BSS_DESC_T prBssDesc;
1542 DEBUGFUNC("joinAdoptParametersFromPeerBss");
1546 prJoinInfo = &prAdapter->rJoinInfo;
1547 prBssDesc = prJoinInfo->prBssDesc;
1549 //4 <1> Adopt Peer BSS' PHY TYPE
1550 prAdapter->eCurrentPhyType = prBssDesc->ePhyType;
1552 DBGLOG(JOIN, INFO, ("Target BSS[%s]'s PhyType = %s\n",
1553 prBssDesc->aucSSID, (prBssDesc->ePhyType == PHY_TYPE_ERP_INDEX) ? "ERP" : "HR_DSSS"));
1556 //4 <2> Adopt Peer BSS' Frequency(Band/Channel)
1557 DBGLOG(JOIN, INFO, ("Target BSS's Channel = %d, Band = %d\n",
1558 prBssDesc->ucChannelNum, prBssDesc->eBand));
1560 nicSwitchChannel(prAdapter,
1562 prBssDesc->ucChannelNum,
1565 prJoinInfo->fgIsParameterAdopted = TRUE;
1568 } /* end of joinAdoptParametersFromPeerBss() */
1571 /*----------------------------------------------------------------------------*/
1573 * \brief This function will adopt the parameters from current associated BSS.
1575 * \param[in] prAdapter Pointer to the Adapter structure.
1579 /*----------------------------------------------------------------------------*/
1581 joinAdoptParametersFromCurrentBss (
1582 IN P_ADAPTER_T prAdapter
1585 //P_JOIN_INFO_T prJoinInfo = &prAdapter->rJoinInfo;
1586 P_BSS_INFO_T prBssInfo;
1590 prBssInfo = &prAdapter->rBssInfo;
1592 //4 <1> Adopt current BSS' PHY TYPE
1593 prAdapter->eCurrentPhyType = prBssInfo->ePhyType;
1595 //4 <2> Adopt current BSS' Frequency(Band/Channel)
1596 DBGLOG(JOIN, INFO, ("Current BSS's Channel = %d, Band = %d\n",
1597 prBssInfo->ucChnl, prBssInfo->eBand));
1599 nicSwitchChannel(prAdapter,
1604 } /* end of joinAdoptParametersFromCurrentBss() */
1607 /*----------------------------------------------------------------------------*/
1609 * \brief This function will update all the SW variables and HW MCR registers after
1610 * the association with target BSS.
1612 * \param[in] prAdapter Pointer to the Adapter structure.
1616 /*----------------------------------------------------------------------------*/
1619 IN P_ADAPTER_T prAdapter
1622 P_JOIN_INFO_T prJoinInfo;
1623 P_BSS_DESC_T prBssDesc;
1624 P_PEER_BSS_INFO_T prPeerBssInfo;
1625 P_BSS_INFO_T prBssInfo;
1626 P_CONNECTION_SETTINGS_T prConnSettings;
1627 P_STA_RECORD_T prStaRec;
1628 P_TX_CTRL_T prTxCtrl;
1629 #if CFG_SUPPORT_802_11D
1630 P_IE_COUNTRY_T prIECountry;
1633 DEBUGFUNC("joinComplete");
1637 prJoinInfo = &prAdapter->rJoinInfo;
1638 prBssDesc = prJoinInfo->prBssDesc;
1639 prPeerBssInfo = &prAdapter->rPeerBssInfo;
1640 prBssInfo = &prAdapter->rBssInfo;
1641 prConnSettings = &prAdapter->rConnSettings;
1642 prTxCtrl = &prAdapter->rTxCtrl;
1644 //4 <1> Update Connecting & Connected Flag of BSS_DESC_T.
1645 /* Remove previous AP's Connection Flags if have */
1646 scanRemoveConnectionFlagOfBssDescByBssid(prAdapter, prBssInfo->aucBSSID);
1648 prBssDesc->fgIsConnected = TRUE; /* Mask as Connected */
1650 if (prBssDesc->fgIsHiddenSSID) {
1651 /* NOTE(Kevin): This is for the case of Passive Scan and the target BSS didn't
1652 * broadcast SSID on its Beacon Frame.
1654 COPY_SSID(prBssDesc->aucSSID,
1655 prBssDesc->ucSSIDLen,
1656 prAdapter->rConnSettings.aucSSID,
1657 prAdapter->rConnSettings.ucSSIDLen);
1659 if (prBssDesc->ucSSIDLen) {
1660 prBssDesc->fgIsHiddenSSID = FALSE;
1668 DBGLOG(JOIN, INFO, ("Hidden SSID! - Update SSID : %s\n", prBssDesc->aucSSID));
1672 //4 <2> Update BSS_INFO_T from BSS_DESC_T
1674 prBssInfo->ePhyType = prBssDesc->ePhyType;
1677 prBssInfo->eBSSType = BSS_TYPE_INFRASTRUCTURE;
1680 COPY_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID);
1682 DBGLOG(JOIN, INFO, ("JOIN to BSSID: ["MACSTR"]\n", MAC2STR(prBssDesc->aucBSSID)));
1686 COPY_SSID(prBssInfo->aucSSID,
1687 prBssInfo->ucSSIDLen,
1689 prBssDesc->ucSSIDLen);
1691 //4 <2.E> Channel / Band information.
1692 prBssInfo->eBand = prBssDesc->eBand;
1693 prBssInfo->ucChnl = prBssDesc->ucChannelNum;
1695 //4 <2.F> RSN/WPA information.
1696 secFsmRunEventStart(prAdapter);
1697 prBssInfo->u4RsnSelectedPairwiseCipher = prBssDesc->u4RsnSelectedPairwiseCipher;
1698 prBssInfo->u4RsnSelectedGroupCipher = prBssDesc->u4RsnSelectedGroupCipher;
1699 prBssInfo->u4RsnSelectedAKMSuite = prBssDesc->u4RsnSelectedAKMSuite;
1701 if (secRsnKeyHandshakeEnabled()) {
1702 prBssInfo->fgIsWPAorWPA2Enabled = TRUE;
1705 prBssInfo->fgIsWPAorWPA2Enabled = FALSE;
1708 //4 <2.G> Beacon interval.
1709 prBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval;
1711 //4 <2.H> DTIM period.
1712 prBssInfo->ucDtimPeriod = prBssDesc->ucDTIMPeriod;
1714 //4 <2.I> ERP Information
1715 if ((prBssInfo->ePhyType == PHY_TYPE_ERP_INDEX) && // Our BSS's PHY_TYPE is ERP now.
1716 (prBssDesc->fgIsERPPresent)) {
1718 prBssInfo->fgIsERPPresent = TRUE;
1719 prBssInfo->ucERP = prBssDesc->ucERP; /* Save the ERP for later check */
1721 else { /* Some AP, may send ProbeResp without ERP IE. Thus prBssDesc->fgIsERPPresent is FALSE. */
1722 prBssInfo->fgIsERPPresent = FALSE;
1723 prBssInfo->ucERP = 0;
1726 #if CFG_SUPPORT_802_11D
1727 //4 <2.J> Country inforamtion of the associated AP
1728 if (prConnSettings->fgMultiDomainCapabilityEnabled) {
1729 DOMAIN_INFO_ENTRY rDomainInfo;
1730 if (domainGetDomainInfoByScanResult(prAdapter, &rDomainInfo)) {
1731 if (prBssDesc->prIECountry) {
1732 prIECountry = prBssDesc->prIECountry;
1734 domainParseCountryInfoElem(prIECountry, &prBssInfo->rDomainInfo);
1736 /* use the domain get from the BSS info */
1737 prBssInfo->fgIsCountryInfoPresent = TRUE;
1738 nicSetupOpChnlList(prAdapter, prBssInfo->rDomainInfo.u2CountryCode, FALSE);
1740 /* use the domain get from the scan result */
1741 prBssInfo->fgIsCountryInfoPresent = TRUE;
1742 nicSetupOpChnlList(prAdapter, rDomainInfo.u2CountryCode, FALSE);
1748 //4 <2.K> Signal Power of the associated AP
1749 prBssInfo->rRcpi = prBssDesc->rRcpi;
1750 prBssInfo->rRssi = RCPI_TO_dBm(prBssInfo->rRcpi);
1751 GET_CURRENT_SYSTIME(&prBssInfo->rRssiLastUpdateTime);
1753 //4 <2.L> Capability Field of the associated AP
1754 prBssInfo->u2CapInfo = prBssDesc->u2CapInfo;
1756 DBGLOG(JOIN, INFO, ("prBssInfo-> fgIsERPPresent = %d, ucERP = %02x, rRcpi = %d, rRssi = %ld\n",
1757 prBssInfo->fgIsERPPresent, prBssInfo->ucERP, prBssInfo->rRcpi, prBssInfo->rRssi));
1760 //4 <3> Update BSS_INFO_T from PEER_BSS_INFO_T & NIC RATE FUNC
1761 //4 <3.A> Association ID
1762 prBssInfo->u2AssocId = prPeerBssInfo->u2AssocId;
1764 //4 <3.B> WMM Infomation
1765 if (prAdapter->fgIsEnableWMM &&
1766 (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_SUPPORT_WMM)) {
1768 prBssInfo->fgIsWmmAssoc = TRUE;
1769 prTxCtrl->rTxQForVoipAccess = TXQ_AC3;
1771 qosWmmInfoInit(&prBssInfo->rWmmInfo, (prBssInfo->ePhyType == PHY_TYPE_HR_DSSS_INDEX) ? TRUE : FALSE);
1773 if (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_AC_PARAM_PRESENT) {
1774 kalMemCopy(&prBssInfo->rWmmInfo,
1775 &prPeerBssInfo->rWmmInfo,
1776 sizeof(WMM_INFO_T));
1779 kalMemCopy(&prBssInfo->rWmmInfo,
1780 &prPeerBssInfo->rWmmInfo,
1781 sizeof(WMM_INFO_T) - sizeof(prPeerBssInfo->rWmmInfo.arWmmAcParams));
1785 prBssInfo->fgIsWmmAssoc = FALSE;
1786 prTxCtrl->rTxQForVoipAccess = TXQ_AC1;
1788 kalMemZero(&prBssInfo->rWmmInfo, sizeof(WMM_INFO_T));
1792 //4 <3.C> Operational Rate Set & BSS Basic Rate Set
1793 prBssInfo->u2OperationalRateSet = prPeerBssInfo->u2OperationalRateSet;
1794 prBssInfo->u2BSSBasicRateSet = prPeerBssInfo->u2BSSBasicRateSet;
1797 //4 <3.D> Short Preamble
1798 if (prBssInfo->fgIsERPPresent) {
1800 /* NOTE(Kevin 2007/12/24): Truth Table.
1801 * Short Preamble Bit in
1802 * <AssocReq> <AssocResp w/i ERP> <BARKER(Long)> Final Driver Setting(Short)
1803 * TRUE FALSE FALSE FALSE(shouldn't have such case, use the AssocResp)
1804 * TRUE FALSE TRUE FALSE
1805 * FALSE FALSE FALSE FALSE(shouldn't have such case, use the AssocResp)
1806 * FALSE FALSE TRUE FALSE
1807 * TRUE TRUE FALSE TRUE(follow ERP)
1808 * TRUE TRUE TRUE FALSE(follow ERP)
1809 * FALSE TRUE FALSE FALSE(shouldn't have such case, and we should set to FALSE)
1810 * FALSE TRUE TRUE FALSE(we should set to FALSE)
1812 if ((prPeerBssInfo->fgIsShortPreambleAllowed) &&
1813 ((prConnSettings->ePreambleType == PREAMBLE_TYPE_SHORT) || /* Short Preamble Option Enable is TRUE */
1814 ((prConnSettings->ePreambleType == PREAMBLE_TYPE_AUTO) &&
1815 (prBssDesc->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)))) {
1817 prBssInfo->fgIsShortPreambleAllowed = TRUE;
1819 if (prBssInfo->ucERP & ERP_INFO_BARKER_PREAMBLE_MODE) {
1820 prBssInfo->fgUseShortPreamble = FALSE;
1823 prBssInfo->fgUseShortPreamble = TRUE;
1827 prBssInfo->fgIsShortPreambleAllowed = FALSE;
1828 prBssInfo->fgUseShortPreamble = FALSE;
1832 /* NOTE(Kevin 2007/12/24): Truth Table.
1833 * Short Preamble Bit in
1834 * <AssocReq> <AssocResp w/o ERP> Final Driver Setting(Short)
1838 * FALSE TRUE(status success) TRUE
1839 * --> Honor the result of prPeerBssInfo.
1842 prBssInfo->fgIsShortPreambleAllowed = prBssInfo->fgUseShortPreamble =
1843 prPeerBssInfo->fgIsShortPreambleAllowed;
1846 DBGLOG(JOIN, INFO, ("prBssInfo->fgIsShortPreambleAllowed = %d, prBssInfo->fgUseShortPreamble = %d\n",
1847 prBssInfo->fgIsShortPreambleAllowed, prBssInfo->fgUseShortPreamble));
1850 //4 <3.E> Short Slot Time
1851 prBssInfo->fgUseShortSlotTime =
1852 prPeerBssInfo->fgUseShortSlotTime; /* AP support Short Slot Time */
1854 DBGLOG(JOIN, INFO, ("prBssInfo->fgUseShortSlotTime = %d\n",
1855 prBssInfo->fgUseShortSlotTime));
1857 nicSetSlotTime(prAdapter,
1858 prBssInfo->ePhyType,
1859 ((prConnSettings->fgIsShortSlotTimeOptionEnable &&
1860 prBssInfo->fgUseShortSlotTime) ? TRUE : FALSE));
1863 //4 <3.F> Update Tx Rate for Control Frame
1864 bssUpdateTxRateForControlFrame(prAdapter);
1867 //4 <3.G> Save the available Auth Types during Roaming (Design for Fast BSS Transition).
1868 //if (prAdapter->fgIsEnableRoaming) /* NOTE(Kevin): Always prepare info for roaming */
1871 if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_OPEN_SYSTEM) {
1872 prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_OPEN_SYSTEM;
1874 else if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) {
1875 prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_SHARED_KEY;
1878 prBssInfo->ucRoamingAuthTypes = prJoinInfo->ucRoamingAuthTypes;
1881 /* Set the stable time of the associated BSS. We won't do roaming decision
1882 * during the stable time.
1884 SET_EXPIRATION_TIME(prBssInfo->rRoamingStableExpirationTime,
1885 SEC_TO_SYSTIME(ROAMING_STABLE_TIMEOUT_SEC));
1889 //4 <3.H> Update Parameter for TX Fragmentation Threshold
1891 txFragInfoUpdate(prAdapter);
1892 #endif /* CFG_TX_FRAGMENT */
1895 //4 <4> Update STA_RECORD_T
1896 /* Get a Station Record if possible */
1897 prStaRec = staRecGetStaRecordByAddr(prAdapter,
1898 prBssDesc->aucBSSID);
1901 UINT_16 u2OperationalRateSet, u2DesiredRateSet;
1903 //4 <4.A> Desired Rate Set
1904 u2OperationalRateSet = (rPhyAttributes[prBssInfo->ePhyType].u2SupportedRateSet &
1905 prBssInfo->u2OperationalRateSet);
1907 u2DesiredRateSet = (u2OperationalRateSet & prConnSettings->u2DesiredRateSet);
1908 if (u2DesiredRateSet) {
1909 prStaRec->u2DesiredRateSet = u2DesiredRateSet;
1912 /* For Error Handling - The Desired Rate Set is not covered in Operational Rate Set. */
1913 prStaRec->u2DesiredRateSet = u2OperationalRateSet;
1916 /* Try to set the best initial rate for this entry */
1917 if (!rateGetBestInitialRateIndex(prStaRec->u2DesiredRateSet,
1919 &prStaRec->ucCurrRate1Index)) {
1921 if (!rateGetLowestRateIndexFromRateSet(prStaRec->u2DesiredRateSet,
1922 &prStaRec->ucCurrRate1Index)) {
1927 DBGLOG(JOIN, INFO, ("prStaRec->ucCurrRate1Index = %d\n",
1928 prStaRec->ucCurrRate1Index));
1930 //4 <4.B> Preamble Mode
1931 prStaRec->fgIsShortPreambleOptionEnable =
1932 prBssInfo->fgUseShortPreamble;
1935 prStaRec->fgIsQoS = prBssInfo->fgIsWmmAssoc;
1945 //4 <5.A> Update BSSID & Operation Mode
1946 nicSetupBSS(prAdapter, prBssInfo);
1948 //4 <5.B> Update WLAN Table.
1949 if (nicSetHwBySta(prAdapter, prStaRec) == FALSE) {
1953 //4 <5.C> Update Desired Rate Set for BT.
1955 if (prConnSettings->fgIsEnableTxAutoFragmentForBT) {
1956 txRateSetInitForBT(prAdapter, prStaRec);
1958 #endif /* CFG_TX_FRAGMENT */
1960 //4 <5.D> TX AC Parameter and TX/RX Queue Control
1961 if (prBssInfo->fgIsWmmAssoc) {
1963 #if CFG_TX_AGGREGATE_HW_FIFO
1964 nicTxAggregateTXQ(prAdapter, FALSE);
1965 #endif /* CFG_TX_AGGREGATE_HW_FIFO */
1967 qosUpdateWMMParametersAndAssignAllowedACI(prAdapter, &prBssInfo->rWmmInfo);
1971 #if CFG_TX_AGGREGATE_HW_FIFO
1972 nicTxAggregateTXQ(prAdapter, TRUE);
1973 #endif /* CFG_TX_AGGREGATE_HW_FIFO */
1975 nicTxNonQoSAssignDefaultAdmittedTXQ(prAdapter);
1977 nicTxNonQoSUpdateTXQParameters(prAdapter,
1978 prBssInfo->ePhyType);
1981 #if CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN
1983 prTxCtrl->fgBlockTxDuringJoin = FALSE;
1985 #if !CFG_TX_AGGREGATE_HW_FIFO /* TX FIFO AGGREGATE already do flush once */
1986 nicTxFlushStopQueues(prAdapter, (UINT_8)TXQ_DATA_MASK, (UINT_8)NULL);
1987 #endif /* CFG_TX_AGGREGATE_HW_FIFO */
1989 nicTxRetransmitOfSendWaitQue(prAdapter);
1991 if (prTxCtrl->fgIsPacketInOsSendQueue) {
1992 nicTxRetransmitOfOsSendQue(prAdapter);
1995 #if CFG_SDIO_TX_ENHANCE
1996 halTxLeftClusteredMpdu(prAdapter);
1997 #endif /* CFG_SDIO_TX_ENHANCE */
2000 #endif /* CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN */
2003 //4 <6> Setup CONNECTION flag.
2004 prAdapter->eConnectionState = MEDIA_STATE_CONNECTED;
2005 prAdapter->eConnectionStateIndicated = MEDIA_STATE_CONNECTED;
2007 if (prJoinInfo->fgIsReAssoc) {
2008 prAdapter->fgBypassPortCtrlForRoaming = TRUE;
2011 prAdapter->fgBypassPortCtrlForRoaming = FALSE;
2014 kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
2015 WLAN_STATUS_MEDIA_CONNECT,
2020 } /* end of joinComplete() */