Ejemplo n.º 1
0
/*----------------------------------------------------------------------------*/
VOID rlmProcessHtAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb)
{
	P_ACTION_NOTIFY_CHNL_WIDTH_FRAME prRxFrame;
	P_STA_RECORD_T prStaRec;

	ASSERT(prAdapter);
	ASSERT(prSwRfb);

	prRxFrame = (P_ACTION_NOTIFY_CHNL_WIDTH_FRAME) prSwRfb->pvHeader;
	prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);

	if (prRxFrame->ucAction != ACTION_HT_NOTIFY_CHANNEL_WIDTH ||
	    !prStaRec || prStaRec->ucStaState != STA_STATE_3 ||
	    prSwRfb->u2PacketLen < sizeof(ACTION_NOTIFY_CHNL_WIDTH_FRAME)) {
		return;
	}

	/* To do: depending regulation class 13 and 14 based on spec
	 * Note: (ucChannelWidth==1) shall restored back to original capability,
	 *       not current setting to 40MHz BW here
	 */
	if (prRxFrame->ucChannelWidth == 0) {
		prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_SUP_CHNL_WIDTH;
	} else if (prRxFrame->ucChannelWidth == 1) {
		prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH;
	}
	cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3);
}
Ejemplo n.º 2
0
VOID
p2pStateInit_GC_JOIN (
    IN P_ADAPTER_T prAdapter,
    IN P_P2P_FSM_INFO_T prP2pFsmInfo,
    IN P_BSS_INFO_T prP2pBssInfo,
    IN P_P2P_JOIN_INFO_T prJoinInfo,
    IN P_BSS_DESC_T prBssDesc
    )
{
    P_MSG_JOIN_REQ_T prJoinReqMsg = (P_MSG_JOIN_REQ_T)NULL;
    P_STA_RECORD_T prStaRec = (P_STA_RECORD_T)NULL;
    P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T)NULL;

    do {
        ASSERT_BREAK((prAdapter != NULL) &&
                                    (prP2pFsmInfo != NULL) &&
                                    (prP2pBssInfo != NULL) &&
                                    (prJoinInfo != NULL) &&
                                    (prBssDesc != NULL));

        prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings;

        if (prBssDesc->ucSSIDLen) {
            COPY_SSID(prP2pConnSettings->aucSSID,
                            prP2pConnSettings->ucSSIDLen,
                            prBssDesc->aucSSID,
                            prBssDesc->ucSSIDLen);
        }


        // Setup a join timer.
        DBGLOG(P2P, TRACE, ("Start a join init timer\n"));
        cnmTimerStartTimer(prAdapter,
                            &(prP2pFsmInfo->rP2pFsmTimeoutTimer),
                            (prP2pFsmInfo->u4GrantInterval - AIS_JOIN_CH_GRANT_THRESHOLD));

        //2 <1> We are goin to connect to this BSS
        prBssDesc->fgIsConnecting = TRUE;

        //2 <2> Setup corresponding STA_RECORD_T
        prStaRec = bssCreateStaRecFromBssDesc(prAdapter,
                                    (prBssDesc->fgIsP2PPresent?(STA_TYPE_P2P_GO):(STA_TYPE_LEGACY_AP)),
                                    NETWORK_TYPE_P2P_INDEX,
                                    prBssDesc);

        if (prStaRec == NULL) {
            DBGLOG(P2P, TRACE, ("Create station record fail\n"));
            break;
        }


        prJoinInfo->prTargetStaRec = prStaRec;
        prJoinInfo->fgIsJoinComplete = FALSE;
        prJoinInfo->u4BufLength = 0;

        //2 <2.1> Sync. to FW domain
        cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);


        if (prP2pBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) {
            P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T)NULL;

            prStaRec->fgIsReAssoc = FALSE;

            prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings;

            switch (prP2pConnSettings->eAuthMode) {
            case AUTH_MODE_OPEN:                /* Note: Omit break here. */
            case AUTH_MODE_WPA:
            case AUTH_MODE_WPA_PSK:
            case AUTH_MODE_WPA2:
            case AUTH_MODE_WPA2_PSK:
                prJoinInfo->ucAvailableAuthTypes = (UINT_8)AUTH_TYPE_OPEN_SYSTEM;
                break;
            case AUTH_MODE_SHARED:
                prJoinInfo->ucAvailableAuthTypes = (UINT_8)AUTH_TYPE_SHARED_KEY;
                break;
            case AUTH_MODE_AUTO_SWITCH:
                DBGLOG(P2P, LOUD, ("JOIN INIT: eAuthMode == AUTH_MODE_AUTO_SWITCH\n"));
                prJoinInfo->ucAvailableAuthTypes = (UINT_8)(AUTH_TYPE_OPEN_SYSTEM |
                                                              AUTH_TYPE_SHARED_KEY);
                break;
            default:
                ASSERT(!(prP2pConnSettings->eAuthMode == AUTH_MODE_WPA_NONE));
                DBGLOG(P2P, ERROR, ("JOIN INIT: Auth Algorithm : %d was not supported by JOIN\n",
                                               prP2pConnSettings->eAuthMode));
                /* TODO(Kevin): error handling ? */
                return;
            }
            prStaRec->ucTxAuthAssocRetryLimit = P2P_TX_AUTH_ASSOCI_RETRY_LIMIT;
        }
        else {
            ASSERT(FALSE);
            // TODO: Shall we considering ROAMIN case for P2P Device?.
        }


        //2 <4> Use an appropriate Authentication Algorithm Number among the ucAvailableAuthTypes.
        if (prJoinInfo->ucAvailableAuthTypes &
            (UINT_8)AUTH_TYPE_OPEN_SYSTEM) {

            DBGLOG(P2P, TRACE, ("JOIN INIT: Try to do Authentication with AuthType == OPEN_SYSTEM.\n"));

            prJoinInfo->ucAvailableAuthTypes &=
                                            ~(UINT_8)AUTH_TYPE_OPEN_SYSTEM;

            prStaRec->ucAuthAlgNum = (UINT_8)AUTH_ALGORITHM_NUM_OPEN_SYSTEM;
        }
        else if (prJoinInfo->ucAvailableAuthTypes &
            (UINT_8)AUTH_TYPE_SHARED_KEY) {

            DBGLOG(P2P, TRACE, ("JOIN INIT: Try to do Authentication with AuthType == SHARED_KEY.\n"));

            prJoinInfo->ucAvailableAuthTypes &=
                                            ~(UINT_8)AUTH_TYPE_SHARED_KEY;

            prStaRec->ucAuthAlgNum = (UINT_8)AUTH_ALGORITHM_NUM_SHARED_KEY;
        }
        else if (prJoinInfo->ucAvailableAuthTypes &
            (UINT_8)AUTH_TYPE_FAST_BSS_TRANSITION) {

            DBGLOG(P2P, TRACE, ("JOIN INIT: Try to do Authentication with AuthType == FAST_BSS_TRANSITION.\n"));

            prJoinInfo->ucAvailableAuthTypes &=
                                            ~(UINT_8)AUTH_TYPE_FAST_BSS_TRANSITION;

            prStaRec->ucAuthAlgNum = (UINT_8)AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION;
        }
        else {
            ASSERT(0);
        }


        //4 <5> Overwrite Connection Setting for eConnectionPolicy == ANY (Used by Assoc Req)
        if (prBssDesc->ucSSIDLen) {
            COPY_SSID(prJoinInfo->rSsidStruct.aucSsid,
                      prJoinInfo->rSsidStruct.ucSsidLen,
                      prBssDesc->aucSSID,
                      prBssDesc->ucSSIDLen);
        }

        //2 <5> Backup desired channel.

        //2 <6> Send a Msg to trigger SAA to start JOIN process.
        prJoinReqMsg = (P_MSG_JOIN_REQ_T)cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T));

        if (!prJoinReqMsg) {
            DBGLOG(P2P, TRACE, ("Allocation Join Message Fail\n"));
            ASSERT(FALSE);
            return;
        }

        prJoinReqMsg->rMsgHdr.eMsgId = MID_P2P_SAA_FSM_START;
        prJoinReqMsg->ucSeqNum = ++prJoinInfo->ucSeqNumOfReqMsg;
        prJoinReqMsg->prStaRec = prStaRec;

        // TODO: Consider fragmentation info in station record.

        mboxSendMsg(prAdapter,
                    MBOX_ID_0,
                    (P_MSG_HDR_T)prJoinReqMsg,
                    MSG_SEND_METHOD_BUF);




    } while (FALSE);

    return;
} /* p2pStateInit_GC_JOIN */
Ejemplo n.º 3
0
/*----------------------------------------------------------------------------*/
VOID aaaFsmRunEventRxAuth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
{
	P_BSS_INFO_T prBssInfo;
	P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL;
	UINT_16 u2StatusCode;
	BOOLEAN fgReplyAuth = FALSE;
	ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex;

	ASSERT(prAdapter);

	do {

		/* 4 <1> Check P2P network conditions */
#if CFG_ENABLE_WIFI_DIRECT
		if (prAdapter->fgIsP2PRegistered) {
			prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);

			if (prBssInfo->fgIsNetActive) {

				/* 4 <1.1> Validate Auth Frame by Auth Algorithm/Transation Seq */
				if (WLAN_STATUS_SUCCESS ==
				    authProcessRxAuth1Frame(prAdapter,
							    prSwRfb,
							    prBssInfo->aucBSSID,
							    AUTH_ALGORITHM_NUM_OPEN_SYSTEM,
							    AUTH_TRANSACTION_SEQ_1, &u2StatusCode)) {

					if (STATUS_CODE_SUCCESSFUL == u2StatusCode) {
						/* 4 <1.2> Validate Auth Frame for Network Specific Conditions */
						fgReplyAuth = p2pFuncValidateAuth(prAdapter,
										  prSwRfb, &prStaRec, &u2StatusCode);
					} else {
						fgReplyAuth = TRUE;
					}
					eNetTypeIndex = NETWORK_TYPE_P2P_INDEX;
					break;
				}
			}
		}
#endif /* CFG_ENABLE_WIFI_DIRECT */

		/* 4 <2> Check BOW network conditions */
#if CFG_ENABLE_BT_OVER_WIFI
		{
			prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]);

			if ((prBssInfo->fgIsNetActive) && (OP_MODE_BOW == prBssInfo->eCurrentOPMode)) {

				/* 4 <2.1> Validate Auth Frame by Auth Algorithm/Transation Seq */
				/* Check if for this BSSID */
				if (WLAN_STATUS_SUCCESS ==
				    authProcessRxAuth1Frame(prAdapter,
							    prSwRfb,
							    prBssInfo->aucBSSID,
							    AUTH_ALGORITHM_NUM_OPEN_SYSTEM,
							    AUTH_TRANSACTION_SEQ_1, &u2StatusCode)) {

					if (STATUS_CODE_SUCCESSFUL == u2StatusCode) {

						/* 4 <2.2> Validate Auth Frame for Network Specific Conditions */
						fgReplyAuth =
						    bowValidateAuth(prAdapter, prSwRfb, &prStaRec, &u2StatusCode);

					} else {

						fgReplyAuth = TRUE;
					}
					eNetTypeIndex = NETWORK_TYPE_BOW_INDEX;
					/* TODO(Kevin): Allocate a STA_RECORD_T for new client */
					break;
				}
			}
		}
#endif /* CFG_ENABLE_BT_OVER_WIFI */

		return;
	} while (FALSE);

	if (prStaRec) {
		/* update RCPI */
		prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi;
	}
	/* 4 <3> Update STA_RECORD_T and reply Auth_2(Response to Auth_1) Frame */
	if (fgReplyAuth) {

		if (prStaRec) {

			if (u2StatusCode == STATUS_CODE_SUCCESSFUL) {
				if (prStaRec->eAuthAssocState != AA_STATE_IDLE) {
					DBGLOG(AAA, WARN, "Previous AuthAssocState (%d) != IDLE.\n",
							   prStaRec->eAuthAssocState);
				}

				prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2;
			} else {
				prStaRec->eAuthAssocState = AA_STATE_IDLE;

				/* NOTE(Kevin): Change to STATE_1 */
				cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
			}

			/* Update the record join time. */
			GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime);

			/* Update Station Record - Status/Reason Code */
			prStaRec->u2StatusCode = u2StatusCode;

			prStaRec->ucAuthAlgNum = AUTH_ALGORITHM_NUM_OPEN_SYSTEM;
		} else {
			/* NOTE(Kevin): We should have STA_RECORD_T if the status code was successful */
			ASSERT(!(u2StatusCode == STATUS_CODE_SUCCESSFUL));
		}

		/* NOTE: Ignore the return status for AAA */
		/* 4 <4> Reply  Auth */
		authSendAuthFrame(prAdapter, prStaRec, eNetTypeIndex, prSwRfb, AUTH_TRANSACTION_SEQ_2, u2StatusCode);

	}

	return;
}				/* end of aaaFsmRunEventRxAuth() */
Ejemplo n.º 4
0
/*----------------------------------------------------------------------------*/
WLAN_STATUS aaaFsmRunEventRxAssoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
{
	P_BSS_INFO_T prBssInfo;
	P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL;
	UINT_16 u2StatusCode = STATUS_CODE_RESERVED;
	BOOLEAN fgReplyAssocResp = FALSE;

	ASSERT(prAdapter);

	do {

		/* 4 <1> Check if we have the STA_RECORD_T for incoming Assoc Req */
		prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);

		/* We should have the corresponding Sta Record. */
		if ((!prStaRec) || (!prStaRec->fgIsInUse)) {
			ASSERT(0);	/* Only for debug phase */
			break;
		}

		if (!IS_CLIENT_STA(prStaRec))
			break;

		if (prStaRec->ucStaState == STA_STATE_3) {
			/* Do Reassocation */
		} else if ((prStaRec->ucStaState == STA_STATE_2) &&
			   (prStaRec->eAuthAssocState == AAA_STATE_SEND_AUTH2)) {
			/* Normal case */
		} else {
			DBGLOG(AAA, INFO, "Previous AuthAssocState (%d) != SEND_AUTH2, ucStaState:%d.\n",
				prStaRec->eAuthAssocState,
				prStaRec->ucStaState);
			/* TODO: Why assoc req event is faster than tx done of auth */
			if (prStaRec->eAuthAssocState != AAA_STATE_SEND_AUTH2)
				break;
		}

		/* update RCPI */
		prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi;

		/* 4 <2> Check P2P network conditions */
#if CFG_ENABLE_WIFI_DIRECT
		if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) {

			prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);

			if (prBssInfo->fgIsNetActive) {

				/* 4 <2.1> Validate Assoc Req Frame and get Status Code */
				/* Check if for this BSSID */
				if (WLAN_STATUS_SUCCESS ==
				    assocProcessRxAssocReqFrame(prAdapter, prSwRfb, &u2StatusCode)) {

					if (STATUS_CODE_SUCCESSFUL == u2StatusCode) {
						/* 4 <2.2> Validate Assoc Req  Frame for Network Specific Conditions */
						fgReplyAssocResp = p2pFuncValidateAssocReq(prAdapter,
											   prSwRfb,
											   (PUINT_16) & u2StatusCode);
					} else {
						fgReplyAssocResp = TRUE;
					}

					break;
				}
			}
		}
#endif /* CFG_ENABLE_WIFI_DIRECT */

		/* 4 <3> Check BOW network conditions */
#if CFG_ENABLE_BT_OVER_WIFI
		if (IS_STA_IN_BOW(prStaRec)) {

			prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]);

			if ((prBssInfo->fgIsNetActive) && (OP_MODE_BOW == prBssInfo->eCurrentOPMode)) {

				/* 4 <3.1> Validate Auth Frame by Auth Algorithm/Transation Seq */
				/* Check if for this BSSID */
				if (WLAN_STATUS_SUCCESS ==
				    assocProcessRxAssocReqFrame(prAdapter, prSwRfb, &u2StatusCode)) {

					if (STATUS_CODE_SUCCESSFUL == u2StatusCode) {

						/* 4 <3.2> Validate Auth Frame for Network Specific Conditions */
						fgReplyAssocResp =
						    bowValidateAssocReq(prAdapter, prSwRfb, &u2StatusCode);

					} else {

						fgReplyAssocResp = TRUE;
					}

					/* TODO(Kevin): Allocate a STA_RECORD_T for new client */
					break;
				}
			}
		}
#endif /* CFG_ENABLE_BT_OVER_WIFI */

		return WLAN_STATUS_SUCCESS;	/* To release the SW_RFB_T */
	} while (FALSE);

	/* 4 <4> Update STA_RECORD_T and reply Assoc Resp Frame */
	if (fgReplyAssocResp) {
		UINT_16 u2IELength;
		PUINT_8 pucIE;

		if ((((P_WLAN_ASSOC_REQ_FRAME_T) (prSwRfb->pvHeader))->u2FrameCtrl & MASK_FRAME_TYPE) ==
		    MAC_FRAME_REASSOC_REQ) {

			u2IELength = prSwRfb->u2PacketLen -
			    (UINT_16) OFFSET_OF(WLAN_REASSOC_REQ_FRAME_T, aucInfoElem[0]);

			pucIE = ((P_WLAN_REASSOC_REQ_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem;
		} else {
			u2IELength = prSwRfb->u2PacketLen - (UINT_16) OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem[0]);

			pucIE = ((P_WLAN_ASSOC_REQ_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem;
		}

		rlmProcessAssocReq(prAdapter, prSwRfb, pucIE, u2IELength);

		/* 4 <4.1> Assign Association ID */
		if (u2StatusCode == STATUS_CODE_SUCCESSFUL) {

#if CFG_ENABLE_WIFI_DIRECT
			if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) {
				if (p2pRunEventAAAComplete(prAdapter, prStaRec) == WLAN_STATUS_SUCCESS) {
					prStaRec->u2AssocId = bssAssignAssocID(prStaRec);
					/* prStaRec->eAuthAssocState = AA_STATE_IDLE; */
					prStaRec->eAuthAssocState = AAA_STATE_SEND_ASSOC2;/* NOTE(Kevin): for TX done */

					/* NOTE(Kevin): Method A: Change to STATE_3 before handle TX Done */
					/* cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); */
				} else {
					/* Client List FULL. */
					u2StatusCode = STATUS_CODE_REQ_DECLINED;

					prStaRec->u2AssocId = 0;	/* Invalid Assocation ID */

					/* If (Re)association fail, the peer can try Assocation w/o Auth immediately */
					prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2;

					/* NOTE(Kevin): Better to change state here, not at TX Done */
					cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2);
				}
			}
#endif

#if CFG_ENABLE_BT_OVER_WIFI
			if ((IS_STA_IN_BOW(prStaRec))) {
				/* if (bowRunEventAAAComplete(prAdapter, prStaRec) == WLAN_STATUS_SUCCESS) { */
				prStaRec->u2AssocId = bssAssignAssocID(prStaRec);
				prStaRec->eAuthAssocState = AAA_STATE_SEND_ASSOC2;	/* NOTE(Kevin): for TX done */

				/* NOTE(Kevin): Method A: Change to STATE_3 before handle TX Done */
				/* cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); */
			}
#if 0
			else {
				/* Client List FULL. */
				u2StatusCode = STATUS_CODE_REQ_DECLINED;

				prStaRec->u2AssocId = 0;	/* Invalid Assocation ID */

				/* If (Re)association fail, the peer can try Assocation w/o Auth immediately */
				prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2;

				/* NOTE(Kevin): Better to change state here, not at TX Done */
				cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2);
			}
		}
#endif
#endif
	} else {
		prStaRec->u2AssocId = 0;	/* Invalid Assocation ID */

		/* If (Re)association fail, the peer can try Assocation w/o Auth immediately */
		prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2;

		/* NOTE(Kevin): Better to change state here, not at TX Done */
		cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2);
	}

	/* Update the record join time. */
	GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime);

	/* Update Station Record - Status/Reason Code */
	prStaRec->u2StatusCode = u2StatusCode;

	/* NOTE: Ignore the return status for AAA */
	/* 4 <4.2> Reply  Assoc Resp */
	assocSendReAssocRespFrame(prAdapter, prStaRec);

}
Ejemplo n.º 5
0
/*----------------------------------------------------------------------------*/
WLAN_STATUS
aaaFsmRunEventTxDone(IN P_ADAPTER_T prAdapter,
		     IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus)
{
	P_STA_RECORD_T prStaRec;
	P_BSS_INFO_T prBssInfo;


	ASSERT(prAdapter);
	ASSERT(prMsduInfo);

	DBGLOG(AAA, LOUD, ("EVENT-TX DONE: Current Time = %ld\n", kalGetTimeTick()));

	prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);

	if ((!prStaRec) || (!prStaRec->fgIsInUse))
		return WLAN_STATUS_SUCCESS;	/* For the case of replying ERROR STATUS CODE */


	ASSERT(prStaRec->ucBssIndex <= MAX_BSS_INDEX);

	prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex);

    /* Trigger statistics log if Auth/Assoc Tx failed */
    if(rTxDoneStatus != TX_RESULT_SUCCESS) {
        wlanTriggerStatsLog(prAdapter, prAdapter->rWifiVar.u4StatsLogDuration);
    }

	switch (prStaRec->eAuthAssocState) {
	case AAA_STATE_SEND_AUTH2:
		{
			/* Strictly check the outgoing frame is matched with current AA STATE */
			if (authCheckTxAuthFrame(prAdapter,
						 prMsduInfo,
						 AUTH_TRANSACTION_SEQ_2) != WLAN_STATUS_SUCCESS) {
				break;
			}

			if (STATUS_CODE_SUCCESSFUL == prStaRec->u2StatusCode) {
				if (TX_RESULT_SUCCESS == rTxDoneStatus) {

					/* NOTE(Kevin): Change to STATE_2 at TX Done */
					cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2);
				} else {

					prStaRec->eAuthAssocState = AA_STATE_IDLE;

					/* NOTE(Kevin): Change to STATE_1 */
					cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);

#if CFG_ENABLE_WIFI_DIRECT
					if (prBssInfo->eNetworkType == NETWORK_TYPE_P2P) {
						p2pRoleFsmRunEventAAATxFail(prAdapter, prStaRec,
									    prBssInfo);
					}
#endif				/* CFG_ENABLE_WIFI_DIRECT */
#if CFG_ENABLE_BT_OVER_WIFI
					if (IS_STA_BOW_TYPE(prStaRec))
						bowRunEventAAATxFail(prAdapter, prStaRec);

#endif				/* CFG_ENABLE_BT_OVER_WIFI */
				}

			}
			/* NOTE(Kevin): Ignore the TX Done Event of Auth Frame with Error Status Code */

		}
		break;

	case AAA_STATE_SEND_ASSOC2:
		{
			/* Strictly check the outgoing frame is matched with current SAA STATE */
			if (assocCheckTxReAssocRespFrame(prAdapter, prMsduInfo) !=
			    WLAN_STATUS_SUCCESS) {
				break;
			}

			if (STATUS_CODE_SUCCESSFUL == prStaRec->u2StatusCode) {
				if (TX_RESULT_SUCCESS == rTxDoneStatus) {

					prStaRec->eAuthAssocState = AA_STATE_IDLE;

					/* NOTE(Kevin): Change to STATE_3 at TX Done */
#if CFG_ENABLE_WIFI_DIRECT
					if (prBssInfo->eNetworkType == NETWORK_TYPE_P2P) {
						p2pRoleFsmRunEventAAASuccess(prAdapter, prStaRec,
									     prBssInfo);
					}
#endif				/* CFG_ENABLE_WIFI_DIRECT */

#if CFG_ENABLE_BT_OVER_WIFI

					if (IS_STA_BOW_TYPE(prStaRec))
						bowRunEventAAAComplete(prAdapter, prStaRec);

#endif				/* CFG_ENABLE_BT_OVER_WIFI */

				} else {

					prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2;

					/* NOTE(Kevin): Change to STATE_2 */
					cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2);

#if CFG_ENABLE_WIFI_DIRECT
					if (prBssInfo->eNetworkType == NETWORK_TYPE_P2P) {
						p2pRoleFsmRunEventAAATxFail(prAdapter, prStaRec,
									    prBssInfo);
					}
#endif				/* CFG_ENABLE_WIFI_DIRECT */

#if CFG_ENABLE_BT_OVER_WIFI
					if (IS_STA_BOW_TYPE(prStaRec))
						bowRunEventAAATxFail(prAdapter, prStaRec);

#endif				/* CFG_ENABLE_BT_OVER_WIFI */

				}
			}
			/* NOTE(Kevin): Ignore the TX Done Event of Auth Frame with Error Status Code */
		}
		break;

	case AA_STATE_IDLE:
		/* 2013-08-27 frog:  Do nothing.
		 * Somtimes we may send Assoc Resp twice. (Rx Assoc Req before the first Assoc TX Done)
		 * The AssocState is changed to IDLE after first TX done.
		 * Free station record when IDLE is seriously wrong.
		 */
		/* /cnmStaRecFree(prAdapter, prStaRec); */

	default:
		break;		/* Ignore other cases */
	}


	return WLAN_STATUS_SUCCESS;

}				/* end of aaaFsmRunEventTxDone() */