blob: a061d7a1bc98ed42a231da399c9d9076b8720264 [file] [log] [blame]
/******************************************************************************
*
* This file is provided under a dual license. When you use or
* distribute this software, you may choose to be licensed under
* version 2 of the GNU General Public License ("GPLv2 License")
* or BSD License.
*
* GPLv2 License
*
* Copyright(C) 2016 MediaTek Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See http://www.gnu.org/licenses/gpl-2.0.html for more details.
*
* BSD LICENSE
*
* Copyright(C) 2016 MediaTek Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
/*
** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/saa_fsm.c#2
*/
/*! \file "saa_fsm.c"
* \brief This file defines the FSM for SAA MODULE.
*
* This file defines the FSM for SAA MODULE.
*/
/*******************************************************************************
* C O M P I L E R F L A G S
********************************************************************************
*/
/*******************************************************************************
* E X T E R N A L R E F E R E N C E S
********************************************************************************
*/
#include "precomp.h"
/*******************************************************************************
* C O N S T A N T S
********************************************************************************
*/
/*******************************************************************************
* D A T A T Y P E S
********************************************************************************
*/
/*******************************************************************************
* P U B L I C D A T A
********************************************************************************
*/
/*******************************************************************************
* P R I V A T E D A T A
********************************************************************************
*/
static PUINT_8 apucDebugAAState[AA_STATE_NUM] = {
(PUINT_8) DISP_STRING("AA_IDLE"),
(PUINT_8) DISP_STRING("SAA_SEND_AUTH1"),
(PUINT_8) DISP_STRING("SAA_WAIT_AUTH2"),
(PUINT_8) DISP_STRING("SAA_SEND_AUTH3"),
(PUINT_8) DISP_STRING("SAA_WAIT_AUTH4"),
(PUINT_8) DISP_STRING("SAA_SEND_ASSOC1"),
(PUINT_8) DISP_STRING("SAA_WAIT_ASSOC2"),
(PUINT_8) DISP_STRING("AAA_SEND_AUTH2"),
(PUINT_8) DISP_STRING("AAA_SEND_AUTH4"),
(PUINT_8) DISP_STRING("AAA_SEND_ASSOC2"),
(PUINT_8) DISP_STRING("AA_RESOURCE")
};
/*******************************************************************************
* M A C R O S
********************************************************************************
*/
/*******************************************************************************
* F U N C T I O N D E C L A R A T I O N S
********************************************************************************
*/
/*******************************************************************************
* F U N C T I O N S
********************************************************************************
*/
/*----------------------------------------------------------------------------*/
/*!
* @brief The Core FSM engine of SAA Module.
*
* @param[in] prStaRec Pointer to the STA_RECORD_T
* @param[in] eNextState The value of Next State
* @param[in] prRetainedSwRfb Pointer to the retained SW_RFB_T for JOIN Success
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
VOID
saaFsmSteps(IN P_ADAPTER_T prAdapter,
IN P_STA_RECORD_T prStaRec, IN ENUM_AA_STATE_T eNextState, IN P_SW_RFB_T prRetainedSwRfb)
{
WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
ENUM_AA_STATE_T ePreviousState;
BOOLEAN fgIsTransition;
ASSERT(prStaRec);
if (!prStaRec)
return;
do {
DBGLOG(SAA, STATE, "[SAA]TRANSITION: [%s] -> [%s]\n",
apucDebugAAState[prStaRec->eAuthAssocState], apucDebugAAState[eNextState]);
ePreviousState = prStaRec->eAuthAssocState;
/* NOTE(Kevin): This is the only place to change the eAuthAssocState(except initial) */
prStaRec->eAuthAssocState = eNextState;
fgIsTransition = (BOOLEAN) FALSE;
switch (prStaRec->eAuthAssocState) {
case AA_STATE_IDLE:
if (ePreviousState != prStaRec->eAuthAssocState) { /* Only trigger this event once */
if (prRetainedSwRfb) {
if (saaFsmSendEventJoinComplete(prAdapter,
WLAN_STATUS_SUCCESS,
prStaRec,
prRetainedSwRfb) == WLAN_STATUS_SUCCESS) {
/* ToDo:: Nothing */
} else {
eNextState = AA_STATE_RESOURCE;
fgIsTransition = TRUE;
}
} else {
if (saaFsmSendEventJoinComplete(prAdapter,
WLAN_STATUS_FAILURE,
prStaRec, NULL) == WLAN_STATUS_RESOURCES) {
eNextState = AA_STATE_RESOURCE;
fgIsTransition = TRUE;
}
}
}
/* Free allocated TCM memory */
if (prStaRec->prChallengeText) {
cnmMemFree(prAdapter, prStaRec->prChallengeText);
prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T) NULL;
}
break;
case SAA_STATE_SEND_AUTH1:
/* Do tasks in INIT STATE */
if (prStaRec->ucTxAuthAssocRetryCount >= prStaRec->ucTxAuthAssocRetryLimit) {
/* Record the Status Code of Authentication Request */
prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT;
eNextState = AA_STATE_IDLE;
fgIsTransition = TRUE;
} else {
prStaRec->ucTxAuthAssocRetryCount++;
/* Update Station Record - Class 1 Flag */
cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
#if !CFG_SUPPORT_AAA
rStatus = authSendAuthFrame(prAdapter, prStaRec, AUTH_TRANSACTION_SEQ_1);
#else
rStatus = authSendAuthFrame(prAdapter,
prStaRec,
prStaRec->ucBssIndex,
NULL,
AUTH_TRANSACTION_SEQ_1,
STATUS_CODE_RESERVED);
#endif /* CFG_SUPPORT_AAA */
if (rStatus != WLAN_STATUS_SUCCESS) {
cnmTimerInitTimer(prAdapter,
&prStaRec->rTxReqDoneOrRxRespTimer, (PFN_MGMT_TIMEOUT_FUNC)
saaFsmRunEventTxReqTimeOut, (ULONG) prStaRec);
cnmTimerStartTimer(prAdapter,
&prStaRec->rTxReqDoneOrRxRespTimer,
TU_TO_MSEC(TX_AUTHENTICATION_RETRY_TIMEOUT_TU));
}
}
break;
case SAA_STATE_WAIT_AUTH2:
break;
case SAA_STATE_SEND_AUTH3:
/* Do tasks in INIT STATE */
if (prStaRec->ucTxAuthAssocRetryCount >= prStaRec->ucTxAuthAssocRetryLimit) {
/* Record the Status Code of Authentication Request */
prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT;
eNextState = AA_STATE_IDLE;
fgIsTransition = TRUE;
} else {
prStaRec->ucTxAuthAssocRetryCount++;
#if !CFG_SUPPORT_AAA
rStatus = authSendAuthFrame(prAdapter, prStaRec, AUTH_TRANSACTION_SEQ_3);
#else
rStatus = authSendAuthFrame(prAdapter,
prStaRec,
prStaRec->ucBssIndex,
NULL,
AUTH_TRANSACTION_SEQ_3,
STATUS_CODE_RESERVED);
#endif /* CFG_SUPPORT_AAA */
if (rStatus != WLAN_STATUS_SUCCESS) {
cnmTimerInitTimer(prAdapter,
&prStaRec->rTxReqDoneOrRxRespTimer, (PFN_MGMT_TIMEOUT_FUNC)
saaFsmRunEventTxReqTimeOut, (ULONG) prStaRec);
cnmTimerStartTimer(prAdapter,
&prStaRec->rTxReqDoneOrRxRespTimer,
TU_TO_MSEC(TX_AUTHENTICATION_RETRY_TIMEOUT_TU));
}
}
break;
case SAA_STATE_WAIT_AUTH4:
break;
case SAA_STATE_SEND_ASSOC1:
/* Do tasks in INIT STATE */
if (prStaRec->ucTxAuthAssocRetryCount >= prStaRec->ucTxAuthAssocRetryLimit) {
/* Record the Status Code of Authentication Request */
prStaRec->u2StatusCode = STATUS_CODE_ASSOC_TIMEOUT;
eNextState = AA_STATE_IDLE;
fgIsTransition = TRUE;
} else {
prStaRec->ucTxAuthAssocRetryCount++;
rStatus = assocSendReAssocReqFrame(prAdapter, prStaRec);
if (rStatus != WLAN_STATUS_SUCCESS) {
cnmTimerInitTimer(prAdapter,
&prStaRec->rTxReqDoneOrRxRespTimer, (PFN_MGMT_TIMEOUT_FUNC)
saaFsmRunEventTxReqTimeOut, (ULONG) prStaRec);
cnmTimerStartTimer(prAdapter,
&prStaRec->rTxReqDoneOrRxRespTimer,
TU_TO_MSEC(TX_ASSOCIATION_RETRY_TIMEOUT_TU));
}
}
break;
case SAA_STATE_WAIT_ASSOC2:
break;
case AA_STATE_RESOURCE:
/* TODO(Kevin) Can setup a timer and send message later */
break;
default:
DBGLOG(SAA, ERROR, "Unknown AA STATE\n");
ASSERT(0);
break;
}
} while (fgIsTransition);
return;
} /* end of saaFsmSteps() */
/*----------------------------------------------------------------------------*/
/*!
* @brief This function will send Event to AIS/BOW/P2P
*
* @param[in] rJoinStatus To indicate JOIN success or failure.
* @param[in] prStaRec Pointer to the STA_RECORD_T
* @param[in] prSwRfb Pointer to the SW_RFB_T
* @return (none)
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
saaFsmSendEventJoinComplete(IN P_ADAPTER_T prAdapter,
IN WLAN_STATUS rJoinStatus, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb)
{
P_BSS_INFO_T prBssInfo;
ASSERT(prStaRec);
if (!prStaRec) {
DBGLOG(SAA, ERROR, "[%s]prStaRec is NULL\n", __func__);
return WLAN_STATUS_INVALID_PACKET;
}
if (!prAdapter) {
DBGLOG(SAA, ERROR, "[%s]prAdapter is NULL\n", __func__);
return WLAN_STATUS_INVALID_PACKET;
}
if (!prAdapter->prAisBssInfo) {
DBGLOG(SAA, ERROR, "[%s]prAdapter->prAisBssInfo is NULL\n", __func__);
return WLAN_STATUS_INVALID_PACKET;
}
/* Store limitation about 40Mhz bandwidth capability during association */
if (prStaRec->ucBssIndex < BSS_INFO_NUM) {
prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex);
if (rJoinStatus == WLAN_STATUS_SUCCESS) {
prBssInfo->fg40mBwAllowed = prBssInfo->fgAssoc40mBwAllowed;
/* Initialize OpMode Channel Width change indicator */
prBssInfo->fgIsOpChangeChannelWidth = FALSE;
}
prBssInfo->fgAssoc40mBwAllowed = FALSE;
}
if (prStaRec->ucBssIndex == prAdapter->prAisBssInfo->ucBssIndex) {
P_MSG_SAA_FSM_COMP_T prSaaFsmCompMsg;
prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SAA_FSM_COMP_T));
if (!prSaaFsmCompMsg)
return WLAN_STATUS_RESOURCES;
prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_AIS_JOIN_COMPLETE;
prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum;
prSaaFsmCompMsg->rJoinStatus = rJoinStatus;
prSaaFsmCompMsg->prStaRec = prStaRec;
prSaaFsmCompMsg->prSwRfb = prSwRfb;
/* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */
mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prSaaFsmCompMsg, MSG_SEND_METHOD_UNBUF);
return WLAN_STATUS_SUCCESS;
}
#if CFG_ENABLE_WIFI_DIRECT
else if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) {
P_MSG_SAA_FSM_COMP_T prSaaFsmCompMsg;
prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SAA_FSM_COMP_T));
if (!prSaaFsmCompMsg)
return WLAN_STATUS_RESOURCES;
prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_P2P_JOIN_COMPLETE;
prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum;
prSaaFsmCompMsg->rJoinStatus = rJoinStatus;
prSaaFsmCompMsg->prStaRec = prStaRec;
prSaaFsmCompMsg->prSwRfb = prSwRfb;
/* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */
mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prSaaFsmCompMsg, MSG_SEND_METHOD_UNBUF);
return WLAN_STATUS_SUCCESS;
}
#endif
#if CFG_ENABLE_BT_OVER_WIFI
else if (IS_STA_BOW_TYPE(prStaRec)) {
/* @TODO: BOW handler */
P_MSG_SAA_FSM_COMP_T prSaaFsmCompMsg;
prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SAA_FSM_COMP_T));
if (!prSaaFsmCompMsg)
return WLAN_STATUS_RESOURCES;
prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_BOW_JOIN_COMPLETE;
prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum;
prSaaFsmCompMsg->rJoinStatus = rJoinStatus;
prSaaFsmCompMsg->prStaRec = prStaRec;
prSaaFsmCompMsg->prSwRfb = prSwRfb;
/* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */
mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prSaaFsmCompMsg, MSG_SEND_METHOD_UNBUF);
return WLAN_STATUS_SUCCESS;
}
#endif
else {
DBGLOG(SAA, ERROR, "Invalid case in %s.\n", __func__);
return WLAN_STATUS_FAILURE;
}
} /* end of saaFsmSendEventJoinComplete() */
/*----------------------------------------------------------------------------*/
/*!
* @brief This function will handle the Start Event to SAA FSM.
*
* @param[in] prMsgHdr Message of Join Request for a particular STA.
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
VOID saaFsmRunEventStart(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
{
P_MSG_SAA_FSM_START_T prSaaFsmStartMsg;
P_STA_RECORD_T prStaRec;
P_BSS_INFO_T prBssInfo;
ASSERT(prAdapter);
ASSERT(prMsgHdr);
prSaaFsmStartMsg = (P_MSG_SAA_FSM_START_T) prMsgHdr;
prStaRec = prSaaFsmStartMsg->prStaRec;
if ((!prStaRec) || (prStaRec->fgIsInUse == FALSE)) {
cnmMemFree(prAdapter, prMsgHdr);
return;
}
ASSERT(prStaRec);
DBGLOG(SAA, LOUD, "EVENT-START: Trigger SAA FSM.\n");
/* record sequence number of request message */
prStaRec->ucAuthAssocReqSeqNum = prSaaFsmStartMsg->ucSeqNum;
cnmMemFree(prAdapter, prMsgHdr);
/* 4 <1> Validation of SAA Start Event */
if (!IS_AP_STA(prStaRec)) {
DBGLOG(SAA, ERROR, "EVENT-START: STA Type - %d was not supported.\n", prStaRec->eStaType);
/* Ignore the return value because don't care the prSwRfb */
saaFsmSendEventJoinComplete(prAdapter, WLAN_STATUS_FAILURE, prStaRec, NULL);
return;
}
/* 4 <2> The previous JOIN process is not completed ? */
if (prStaRec->eAuthAssocState != AA_STATE_IDLE) {
DBGLOG(SAA, ERROR, "EVENT-START: Reentry of SAA Module.\n");
prStaRec->eAuthAssocState = AA_STATE_IDLE;
}
/* 4 <3> Reset Status Code and Time */
/* Update Station Record - Status/Reason Code */
prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL;
/* Update the record join time. */
GET_CURRENT_SYSTIME(&prStaRec->rLastJoinTime);
prStaRec->ucTxAuthAssocRetryCount = 0;
if (prStaRec->prChallengeText) {
cnmMemFree(prAdapter, prStaRec->prChallengeText);
prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T) NULL;
}
cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
/* 4 <4> Init the sec fsm */
/* secFsmInit(prAdapter, prStaRec); */
/* 4 <5> Reset the STA STATE */
/* Update Station Record - Class 1 Flag */
/* NOTE(Kevin): Moved to AIS FSM for Reconnect issue -
* We won't deactivate the same STA_RECORD_T and then activate it again for the
* case of reconnection.
*/
/* cnmStaRecChangeState(prStaRec, STA_STATE_1); */
/* 4 <6> Decide if this BSS 20/40M bandwidth is allowed */
if (prStaRec->ucBssIndex < BSS_INFO_NUM) {
prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex);
if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N)
&& (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) {
prBssInfo->fgAssoc40mBwAllowed = cnmBss40mBwPermitted(prAdapter, prBssInfo->ucBssIndex);
} else {
prBssInfo->fgAssoc40mBwAllowed = FALSE;
}
DBGLOG(RLM, TRACE, "STA 40mAllowed=%d\n", prBssInfo->fgAssoc40mBwAllowed);
}
/* 4 <7> Trigger SAA FSM */
if (prStaRec->ucStaState == STA_STATE_1)
saaFsmSteps(prAdapter, prStaRec, SAA_STATE_SEND_AUTH1, (P_SW_RFB_T) NULL);
else if (prStaRec->ucStaState == STA_STATE_2 || prStaRec->ucStaState == STA_STATE_3)
saaFsmSteps(prAdapter, prStaRec, SAA_STATE_SEND_ASSOC1, (P_SW_RFB_T) NULL);
} /* end of saaFsmRunEventStart() */
/*----------------------------------------------------------------------------*/
/*!
* @brief This function will handle TxDone(Auth1/Auth3/AssocReq) Event of SAA FSM.
*
* @param[in] prMsduInfo Pointer to the MSDU_INFO_T.
* @param[in] rTxDoneStatus Return TX status of the Auth1/Auth3/AssocReq frame.
*
* @retval WLAN_STATUS_SUCCESS
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
saaFsmRunEventTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus)
{
P_STA_RECORD_T prStaRec;
ENUM_AA_STATE_T eNextState;
ASSERT(prMsduInfo);
prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
if (!prStaRec)
return WLAN_STATUS_INVALID_PACKET;
ASSERT(prStaRec);
DBGLOG(SAA, LOUD, "EVENT-TX DONE: Current Time = %d\n", kalGetTimeTick());
/* Trigger statistics log if Auth/Assoc Tx failed */
if (rTxDoneStatus != TX_RESULT_SUCCESS)
wlanTriggerStatsLog(prAdapter, prAdapter->rWifiVar.u4StatsLogDuration);
eNextState = prStaRec->eAuthAssocState;
switch (prStaRec->eAuthAssocState) {
case SAA_STATE_SEND_AUTH1:
{
/* Strictly check the outgoing frame is matched with current AA STATE */
if (authCheckTxAuthFrame(prAdapter, prMsduInfo, AUTH_TRANSACTION_SEQ_1) != WLAN_STATUS_SUCCESS)
break;
if (rTxDoneStatus == TX_RESULT_SUCCESS) {
eNextState = SAA_STATE_WAIT_AUTH2;
cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
cnmTimerInitTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer, (PFN_MGMT_TIMEOUT_FUNC)
saaFsmRunEventRxRespTimeOut, (ULONG) prStaRec);
cnmTimerStartTimer(prAdapter,
&prStaRec->rTxReqDoneOrRxRespTimer,
TU_TO_MSEC(DOT11_AUTHENTICATION_RESPONSE_TIMEOUT_TU));
}
/* if TX was successful, change to next state.
* if TX was failed, do retry if possible.
*/
saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL);
}
break;
case SAA_STATE_SEND_AUTH3:
{
/* Strictly check the outgoing frame is matched with current JOIN STATE */
if (authCheckTxAuthFrame(prAdapter, prMsduInfo, AUTH_TRANSACTION_SEQ_3) != WLAN_STATUS_SUCCESS)
break;
if (rTxDoneStatus == TX_RESULT_SUCCESS) {
eNextState = SAA_STATE_WAIT_AUTH4;
cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
cnmTimerInitTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer, (PFN_MGMT_TIMEOUT_FUNC)
saaFsmRunEventRxRespTimeOut, (ULONG) prStaRec);
cnmTimerStartTimer(prAdapter,
&prStaRec->rTxReqDoneOrRxRespTimer,
TU_TO_MSEC(DOT11_AUTHENTICATION_RESPONSE_TIMEOUT_TU));
}
/* if TX was successful, change to next state.
* if TX was failed, do retry if possible.
*/
saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL);
}
break;
case SAA_STATE_SEND_ASSOC1:
{
/* Strictly check the outgoing frame is matched with current SAA STATE */
if (assocCheckTxReAssocReqFrame(prAdapter, prMsduInfo) != WLAN_STATUS_SUCCESS)
break;
if (rTxDoneStatus == TX_RESULT_SUCCESS) {
eNextState = SAA_STATE_WAIT_ASSOC2;
cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
cnmTimerInitTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer, (PFN_MGMT_TIMEOUT_FUNC)
saaFsmRunEventRxRespTimeOut, (ULONG) prStaRec);
cnmTimerStartTimer(prAdapter,
&(prStaRec->rTxReqDoneOrRxRespTimer),
TU_TO_MSEC(DOT11_ASSOCIATION_RESPONSE_TIMEOUT_TU));
}
/* if TX was successful, change to next state.
* if TX was failed, do retry if possible.
*/
saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL);
}
break;
default:
break; /* Ignore other cases */
}
return WLAN_STATUS_SUCCESS;
} /* end of saaFsmRunEventTxDone() */
/*----------------------------------------------------------------------------*/
/*!
* @brief This function will send Tx Request Timeout Event to SAA FSM.
*
* @param[in] prStaRec Pointer to the STA_RECORD_T
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
VOID saaFsmRunEventTxReqTimeOut(IN P_ADAPTER_T prAdapter, IN ULONG plParamPtr)
{
P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) plParamPtr;
ASSERT(prStaRec);
if (!prStaRec)
return;
DBGLOG(SAA, LOUD, "EVENT-TIMER: TX REQ TIMEOUT, Current Time = %d\n", kalGetTimeTick());
/* Trigger statistics log if Auth/Assoc Tx timeout */
wlanTriggerStatsLog(prAdapter, prAdapter->rWifiVar.u4StatsLogDuration);
switch (prStaRec->eAuthAssocState) {
case SAA_STATE_SEND_AUTH1:
case SAA_STATE_SEND_AUTH3:
case SAA_STATE_SEND_ASSOC1:
saaFsmSteps(prAdapter, prStaRec, prStaRec->eAuthAssocState, (P_SW_RFB_T) NULL);
break;
default:
return;
}
} /* end of saaFsmRunEventTxReqTimeOut() */
/*----------------------------------------------------------------------------*/
/*!
* @brief This function will send Rx Response Timeout Event to SAA FSM.
*
* @param[in] prStaRec Pointer to the STA_RECORD_T
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
VOID saaFsmRunEventRxRespTimeOut(IN P_ADAPTER_T prAdapter, IN ULONG ulParamPtr)
{
P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) ulParamPtr;
ENUM_AA_STATE_T eNextState;
DBGLOG(SAA, LOUD, "EVENT-TIMER: RX RESP TIMEOUT, Current Time = %d\n", kalGetTimeTick());
ASSERT(prStaRec);
if (!prStaRec)
return;
eNextState = prStaRec->eAuthAssocState;
switch (prStaRec->eAuthAssocState) {
case SAA_STATE_WAIT_AUTH2:
/* Record the Status Code of Authentication Request */
prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT;
/* Pull back to earlier state to do retry */
eNextState = SAA_STATE_SEND_AUTH1;
break;
case SAA_STATE_WAIT_AUTH4:
/* Record the Status Code of Authentication Request */
prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT;
/* Pull back to earlier state to do retry */
eNextState = SAA_STATE_SEND_AUTH3;
break;
case SAA_STATE_WAIT_ASSOC2:
/* Record the Status Code of Authentication Request */
prStaRec->u2StatusCode = STATUS_CODE_ASSOC_TIMEOUT;
/* Pull back to earlier state to do retry */
eNextState = SAA_STATE_SEND_ASSOC1;
break;
default:
break; /* Ignore other cases */
}
if (eNextState != prStaRec->eAuthAssocState)
saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL);
} /* end of saaFsmRunEventRxRespTimeOut() */
/*----------------------------------------------------------------------------*/
/*!
* @brief This function will process the Rx Auth Response Frame and then
* trigger SAA FSM.
*
* @param[in] prSwRfb Pointer to the SW_RFB_T structure.
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
VOID saaFsmRunEventRxAuth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
{
P_STA_RECORD_T prStaRec;
UINT_16 u2StatusCode;
ENUM_AA_STATE_T eNextState;
UINT_8 ucWlanIdx;
ASSERT(prSwRfb);
prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
ucWlanIdx = (UINT_8) HAL_RX_STATUS_GET_WLAN_IDX(prSwRfb->prRxStatus);
/* We should have the corresponding Sta Record. */
if (!prStaRec) {
DBGLOG(SAA, WARN, "Received a AuthResp: wlanIdx[%d] w/o corresponding staRec\n", ucWlanIdx);
return;
}
if (!IS_AP_STA(prStaRec))
return;
switch (prStaRec->eAuthAssocState) {
case SAA_STATE_SEND_AUTH1:
case SAA_STATE_WAIT_AUTH2:
/* Check if the incoming frame is what we are waiting for */
if (authCheckRxAuthFrameStatus(prAdapter,
prSwRfb, AUTH_TRANSACTION_SEQ_2, &u2StatusCode) == WLAN_STATUS_SUCCESS) {
cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
/* Record the Status Code of Authentication Request */
prStaRec->u2StatusCode = u2StatusCode;
if (u2StatusCode == STATUS_CODE_SUCCESSFUL) {
authProcessRxAuth2_Auth4Frame(prAdapter, prSwRfb);
if (prStaRec->ucAuthAlgNum == (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY) {
eNextState = SAA_STATE_SEND_AUTH3;
} else {
/* Update Station Record - Class 2 Flag */
cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2);
eNextState = SAA_STATE_SEND_ASSOC1;
}
} else {
DBGLOG(SAA, INFO,
"Auth Req was rejected by [" MACSTR "], Status Code = %d\n",
MAC2STR(prStaRec->aucMacAddr), u2StatusCode);
eNextState = AA_STATE_IDLE;
}
/* Reset Send Auth/(Re)Assoc Frame Count */
prStaRec->ucTxAuthAssocRetryCount = 0;
saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL);
}
break;
case SAA_STATE_SEND_AUTH3:
case SAA_STATE_WAIT_AUTH4:
/* Check if the incoming frame is what we are waiting for */
if (authCheckRxAuthFrameStatus(prAdapter,
prSwRfb, AUTH_TRANSACTION_SEQ_4, &u2StatusCode) == WLAN_STATUS_SUCCESS) {
cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
/* Record the Status Code of Authentication Request */
prStaRec->u2StatusCode = u2StatusCode;
if (u2StatusCode == STATUS_CODE_SUCCESSFUL) {
authProcessRxAuth2_Auth4Frame(prAdapter, prSwRfb); /* Add for 802.11r handling */
/* Update Station Record - Class 2 Flag */
cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2);
eNextState = SAA_STATE_SEND_ASSOC1;
} else {
DBGLOG(SAA, INFO,
"Auth Req was rejected by [" MACSTR "], Status Code = %d\n",
MAC2STR(prStaRec->aucMacAddr), u2StatusCode);
eNextState = AA_STATE_IDLE;
}
/* Reset Send Auth/(Re)Assoc Frame Count */
prStaRec->ucTxAuthAssocRetryCount = 0;
saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL);
}
break;
default:
break; /* Ignore other cases */
}
} /* end of saaFsmRunEventRxAuth() */
/*----------------------------------------------------------------------------*/
/*!
* @brief This function will process the Rx (Re)Association Response Frame and then
* trigger SAA FSM.
*
* @param[in] prSwRfb Pointer to the SW_RFB_T structure.
*
* @retval WLAN_STATUS_SUCCESS if the status code was not success
* @retval WLAN_STATUS_BUFFER_RETAINED if the status code was success
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS saaFsmRunEventRxAssoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
{
P_STA_RECORD_T prStaRec;
UINT_16 u2StatusCode;
ENUM_AA_STATE_T eNextState;
P_SW_RFB_T prRetainedSwRfb = (P_SW_RFB_T) NULL;
WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
UINT_8 ucWlanIdx;
ASSERT(prSwRfb);
prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
ucWlanIdx = (UINT_8) HAL_RX_STATUS_GET_WLAN_IDX(prSwRfb->prRxStatus);
/* We should have the corresponding Sta Record. */
if (!prStaRec) {
/* ASSERT(0); */
DBGLOG(SAA, WARN, "Received a AssocResp: wlanIdx[%d] w/o corresponding staRec\n", ucWlanIdx);
return rStatus;
}
if (!IS_AP_STA(prStaRec))
return rStatus;
switch (prStaRec->eAuthAssocState) {
case SAA_STATE_SEND_ASSOC1:
case SAA_STATE_WAIT_ASSOC2:
/* TRUE if the incoming frame is what we are waiting for */
if (assocCheckRxReAssocRspFrameStatus(prAdapter, prSwRfb, &u2StatusCode) == WLAN_STATUS_SUCCESS) {
cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
/* Record the Status Code of Authentication Request */
prStaRec->u2StatusCode = u2StatusCode;
if (u2StatusCode == STATUS_CODE_SUCCESSFUL) {
/* Update Station Record - Class 3 Flag */
/* NOTE(Kevin): Moved to AIS FSM for roaming issue -
* We should deactivate the STA_RECORD_T of previous AP before
* activate new one in Driver.
*/
/* cnmStaRecChangeState(prStaRec, STA_STATE_3); */
prStaRec->ucJoinFailureCount = 0; /* Clear history. */
prRetainedSwRfb = prSwRfb;
rStatus = WLAN_STATUS_PENDING;
} else {
DBGLOG(SAA, INFO,
"Assoc Req was rejected by [" MACSTR
"], Status Code = %d\n", MAC2STR(prStaRec->aucMacAddr), u2StatusCode);
}
/* Reset Send Auth/(Re)Assoc Frame Count */
prStaRec->ucTxAuthAssocRetryCount = 0;
/* update RCPI */
ASSERT(prSwRfb->prRxStatusGroup3);
prStaRec->ucRCPI = nicRxGetRcpiValueFromRxv(RCPI_MODE_WF0, prSwRfb);
eNextState = AA_STATE_IDLE;
saaFsmSteps(prAdapter, prStaRec, eNextState, prRetainedSwRfb);
}
break;
default:
break; /* Ignore other cases */
}
return rStatus;
} /* end of saaFsmRunEventRxAssoc() */
/*----------------------------------------------------------------------------*/
/*!
* @brief This function will check the incoming Deauth Frame.
*
* @param[in] prSwRfb Pointer to the SW_RFB_T structure.
*
* @retval WLAN_STATUS_SUCCESS Always not retain deauthentication frames
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS saaFsmRunEventRxDeauth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
{
P_STA_RECORD_T prStaRec;
P_WLAN_DEAUTH_FRAME_T prDeauthFrame;
UINT_8 ucWlanIdx;
ASSERT(prSwRfb);
prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) prSwRfb->pvHeader;
ucWlanIdx = (UINT_8) HAL_RX_STATUS_GET_WLAN_IDX(prSwRfb->prRxStatus);
DBGLOG(SAA, INFO, "Rx Deauth frame ,DA[" MACSTR "] SA[" MACSTR "] BSSID[" MACSTR "] ReasonCode[0x%x]\n",
MAC2STR(prDeauthFrame->aucDestAddr), MAC2STR(prDeauthFrame->aucSrcAddr),
MAC2STR(prDeauthFrame->aucBSSID), prDeauthFrame->u2ReasonCode);
do {
/* We should have the corresponding Sta Record. */
if (!prStaRec) {
DBGLOG(SAA, WARN, "Received a Deauth: wlanIdx[%d] w/o corresponding staRec\n", ucWlanIdx);
break;
}
if (IS_STA_IN_AIS(prStaRec)) {
P_BSS_INFO_T prAisBssInfo;
if (!IS_AP_STA(prStaRec))
break;
prAisBssInfo = prAdapter->prAisBssInfo;
if (prStaRec->ucStaState > STA_STATE_1) {
/* Check if this is the AP we are associated or associating with */
if (authProcessRxDeauthFrame(prSwRfb,
prStaRec->aucMacAddr,
&prStaRec->u2ReasonCode) == WLAN_STATUS_SUCCESS) {
#if CFG_SUPPORT_802_11W
P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
prAisSpecBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo);
DBGLOG(RSN, INFO,
"QM RX MGT: Deauth frame, P=%d Sec=%d CM=%d BC=%d fc=%02x\n",
prAisSpecBssInfo->fgMgmtProtection,
HAL_RX_STATUS_GET_SEC_MODE(prSwRfb->prRxStatus),
HAL_RX_STATUS_IS_CIPHER_MISMATCH(prSwRfb->prRxStatus),
IS_BMCAST_MAC_ADDR(prDeauthFrame->aucDestAddr),
prDeauthFrame->u2FrameCtrl);
if (prAisSpecBssInfo->fgMgmtProtection
&& HAL_RX_STATUS_IS_CIPHER_MISMATCH(prSwRfb->prRxStatus)
/* HAL_RX_STATUS_GET_SEC_MODE(prSwRfb->prRxStatus) != CIPHER_SUITE_BIP */
) {
saaChkDeauthfrmParamHandler(prAdapter, prSwRfb, prStaRec);
return WLAN_STATUS_SUCCESS;
}
#endif
saaSendDisconnectMsgHandler(prAdapter, prStaRec, prAisBssInfo, FRM_DEAUTH);
}
}
}
#if CFG_ENABLE_WIFI_DIRECT
else if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) {
/* TODO(Kevin) */
p2pRoleFsmRunEventRxDeauthentication(prAdapter, prStaRec, prSwRfb);
}
#endif
#if CFG_ENABLE_BT_OVER_WIFI
else if (IS_STA_BOW_TYPE(prStaRec))
bowRunEventRxDeAuth(prAdapter, prStaRec, prSwRfb);
#endif
else
ASSERT(0);
} while (FALSE);
return WLAN_STATUS_SUCCESS;
} /* end of saaFsmRunEventRxDeauth() */
/* for AOSP */
/*----------------------------------------------------------------------------*/
/*!
* @brief This function will check param of deauth frame and reson code for deauth
*
* @param[in]
*
* @retval
*/
/*----------------------------------------------------------------------------*/
VOID saaChkDeauthfrmParamHandler(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN P_STA_RECORD_T prStaRec)
{
P_WLAN_DEAUTH_FRAME_T prDeauthFrame;
do {
prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) prSwRfb->pvHeader;
if (!IS_BMCAST_MAC_ADDR(prDeauthFrame->aucDestAddr) &&
(prStaRec->u2ReasonCode == REASON_CODE_CLASS_2_ERR
|| prStaRec->u2ReasonCode == REASON_CODE_CLASS_3_ERR)) {
DBGLOG(RSN, INFO, "QM RX MGT: rsnStartSaQuery\n");
/* MFP test plan 5.3.3.5 */
rsnStartSaQuery(prAdapter);
} else {
DBGLOG(RSN, INFO, "RXM: Drop unprotected Mgmt frame\n");
DBGLOG(RSN, INFO,
"RXM: (MAC RX Done) RX (u2StatusFlag=0x%x) (ucKIdxSecMode=0x%x) (ucWlanIdx=0x%x)\n",
prSwRfb->prRxStatus->u2StatusFlag,
prSwRfb->prRxStatus->ucTidSecMode, prSwRfb->prRxStatus->ucWlanIdx);
}
} while (0);
}
/* for AOSP */
/*----------------------------------------------------------------------------*/
/*!
* @brief This function will check and send disconnect message to AIS module
*
* @param[in]
*
* @retval
*/
/*----------------------------------------------------------------------------*/
VOID
saaSendDisconnectMsgHandler(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_BSS_INFO_T prAisBssInfo,
IN ENUM_AA_FRM_TYPE_T eFrmType)
{
do {
if (eFrmType == FRM_DEAUTH) {
if (prStaRec->ucStaState == STA_STATE_3) {
P_MSG_AIS_ABORT_T prAisAbortMsg;
/* NOTE(Kevin): Change state immediately to avoid starvation of
* MSG buffer because of too many deauth frames before changing
* the STA state.
*/
cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
prAisAbortMsg =
(P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T));
if (!prAisAbortMsg)
break;
prAisAbortMsg->rMsgHdr.eMsgId = MID_SAA_AIS_FSM_ABORT;
prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_DEAUTHENTICATED;
prAisAbortMsg->fgDelayIndication = FALSE;
mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF);
} else {
/* TODO(Kevin): Joining Abort */
}
} else { /* FRM_DISASSOC */
if (prStaRec->ucStaState == STA_STATE_3) {
P_MSG_AIS_ABORT_T prAisAbortMsg;
prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter,
RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T));
if (!prAisAbortMsg)
break;
prAisAbortMsg->rMsgHdr.eMsgId = MID_SAA_AIS_FSM_ABORT;
prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_DISASSOCIATED;
prAisAbortMsg->fgDelayIndication = FALSE;
mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF);
} else {
/* TODO(Kevin): Joining Abort */
}
}
if (prAisBssInfo)
prAisBssInfo->u2DeauthReason = prStaRec->u2ReasonCode;
} while (0);
}
/*----------------------------------------------------------------------------*/
/*!
* @brief This function will check the incoming Disassociation Frame.
*
* @param[in] prSwRfb Pointer to the SW_RFB_T structure.
*
* @retval WLAN_STATUS_SUCCESS Always not retain disassociation frames
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS saaFsmRunEventRxDisassoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
{
P_STA_RECORD_T prStaRec;
P_WLAN_DISASSOC_FRAME_T prDisassocFrame;
UINT_8 ucWlanIdx;
ASSERT(prSwRfb);
prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
prDisassocFrame = (P_WLAN_DISASSOC_FRAME_T) prSwRfb->pvHeader;
ucWlanIdx = (UINT_8) HAL_RX_STATUS_GET_WLAN_IDX(prSwRfb->prRxStatus);
DBGLOG(SAA, INFO,
"Rx Disassoc frame from BSSID[" MACSTR "] DA[" MACSTR "] ReasonCode[0x%x]\n",
MAC2STR(prDisassocFrame->aucBSSID), MAC2STR(prDisassocFrame->aucDestAddr),
prDisassocFrame->u2ReasonCode);
do {
/* We should have the corresponding Sta Record. */
if (!prStaRec) {
DBGLOG(SAA, WARN, "Received a DisAssoc: wlanIdx[%d] w/o corresponding staRec\n", ucWlanIdx);
break;
}
if (IS_STA_IN_AIS(prStaRec)) {
P_BSS_INFO_T prAisBssInfo;
if (!IS_AP_STA(prStaRec))
break;
prAisBssInfo = prAdapter->prAisBssInfo;
if (prStaRec->ucStaState > STA_STATE_1) {
/* Check if this is the AP we are associated or associating with */
if (assocProcessRxDisassocFrame(prAdapter,
prSwRfb,
prStaRec->aucMacAddr,
&prStaRec->u2ReasonCode) == WLAN_STATUS_SUCCESS) {
#if CFG_SUPPORT_802_11W
P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
prAisSpecBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo);
DBGLOG(RSN, INFO,
"QM RX MGT: Disassoc frame, P=%d Sec=%d CM=%d BC=%d fc=%02x\n",
prAisSpecBssInfo->fgMgmtProtection,
HAL_RX_STATUS_GET_SEC_MODE(prSwRfb->prRxStatus),
HAL_RX_STATUS_IS_CIPHER_MISMATCH(prSwRfb->prRxStatus),
IS_BMCAST_MAC_ADDR(prDisassocFrame->aucDestAddr),
prDisassocFrame->u2FrameCtrl);
if (IS_STA_IN_AIS(prStaRec)
&& prAisSpecBssInfo->fgMgmtProtection
&& HAL_RX_STATUS_IS_CIPHER_MISMATCH(prSwRfb->prRxStatus)
/* HAL_RX_STATUS_GET_SEC_MODE(prSwRfb->prRxStatus) != CIPHER_SUITE_CCMP */
) {
/* prDisassocFrame = (P_WLAN_DISASSOC_FRAME_T) prSwRfb->pvHeader; */
saaChkDisassocfrmParamHandler(prAdapter, prDisassocFrame, prStaRec,
prSwRfb);
return WLAN_STATUS_SUCCESS;
}
#endif
saaSendDisconnectMsgHandler(prAdapter, prStaRec, prAisBssInfo, FRM_DISASSOC);
}
}
}
#if CFG_ENABLE_WIFI_DIRECT
else if (prAdapter->fgIsP2PRegistered && (IS_STA_IN_P2P(prStaRec))) {
/* TODO(Kevin) */
p2pRoleFsmRunEventRxDisassociation(prAdapter, prStaRec, prSwRfb);
}
#endif
#if CFG_ENABLE_BT_OVER_WIFI
else if (IS_STA_BOW_TYPE(prStaRec)) {
/* ToDo:: nothing */
/* TODO(Kevin) */
}
#endif
else
ASSERT(0);
} while (FALSE);
return WLAN_STATUS_SUCCESS;
} /* end of saaFsmRunEventRxDisassoc() */
/* for AOSP */
/*----------------------------------------------------------------------------*/
/*!
* @brief This function will check param of Disassoc frame and reson code for Disassoc
*
* @param[in]
*
* @retval
*/
/*----------------------------------------------------------------------------*/
VOID
saaChkDisassocfrmParamHandler(IN P_ADAPTER_T prAdapter,
IN P_WLAN_DISASSOC_FRAME_T prDisassocFrame, IN P_STA_RECORD_T prStaRec,
IN P_SW_RFB_T prSwRfb)
{
if (!IS_BMCAST_MAC_ADDR(prDisassocFrame->aucDestAddr) &&
(prStaRec->u2ReasonCode == REASON_CODE_CLASS_2_ERR || prStaRec->u2ReasonCode == REASON_CODE_CLASS_3_ERR)) {
/* MFP test plan 5.3.3.5 */
DBGLOG(RSN, INFO, "QM RX MGT: rsnStartSaQuery\n");
rsnStartSaQuery(prAdapter);
} else {
DBGLOG(RSN, INFO, "RXM: Drop unprotected Mgmt frame\n");
DBGLOG(RSN, INFO,
"RXM: (MAC RX Done) RX (u2StatusFlag=0x%x) (ucKIdxSecMode=0x%x) (ucWlanIdx=0x%x)\n",
prSwRfb->prRxStatus->u2StatusFlag,
prSwRfb->prRxStatus->ucTidSecMode, prSwRfb->prRxStatus->ucWlanIdx);
}
}
/*----------------------------------------------------------------------------*/
/*!
* @brief This function will handle the Abort Event to SAA FSM.
*
* @param[in] prMsgHdr Message of Abort Request for a particular STA.
*
* @return none
*/
/*----------------------------------------------------------------------------*/
VOID saaFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr)
{
P_MSG_SAA_FSM_ABORT_T prSaaFsmAbortMsg;
P_STA_RECORD_T prStaRec;
ASSERT(prMsgHdr);
prSaaFsmAbortMsg = (P_MSG_SAA_FSM_ABORT_T) prMsgHdr;
prStaRec = prSaaFsmAbortMsg->prStaRec;
ASSERT(prStaRec);
if (!prStaRec) {
cnmMemFree(prAdapter, prMsgHdr);
return;
}
DBGLOG(SAA, LOUD, "EVENT-ABORT: Stop SAA FSM.\n");
cnmMemFree(prAdapter, prMsgHdr);
/* Reset Send Auth/(Re)Assoc Frame Count */
prStaRec->ucTxAuthAssocRetryCount = 0;
/* Cancel JOIN relative Timer */
cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer);
if (prStaRec->eAuthAssocState != AA_STATE_IDLE) {
DBGLOG(SAA, LOUD, "EVENT-ABORT: Previous Auth/Assoc State == %s.\n",
apucDebugAAState[prStaRec->eAuthAssocState]);
}
#if 0
/* For the Auth/Assoc State to IDLE */
prStaRec->eAuthAssocState = AA_STATE_IDLE;
#else
/* Free this StaRec */
cnmStaRecFree(prAdapter, prStaRec);
#endif
} /* end of saaFsmRunEventAbort() */
/* TODO(Kevin): following code will be modified and move to AIS FSM */
#if 0
/*----------------------------------------------------------------------------*/
/*!
* \brief This function will send Join Timeout Event to JOIN FSM.
*
* \param[in] prAdapter Pointer to the Adapter structure.
*
* \retval WLAN_STATUS_FAILURE Fail because of Join Timeout
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS joinFsmRunEventJoinTimeOut(IN P_ADAPTER_T prAdapter)
{
P_JOIN_INFO_T prJoinInfo;
P_STA_RECORD_T prStaRec;
DEBUGFUNC("joinFsmRunEventJoinTimeOut");
ASSERT(prAdapter);
prJoinInfo = &prAdapter->rJoinInfo;
DBGLOG(JOIN, EVENT, "JOIN EVENT: JOIN TIMEOUT\n");
/* Get a Station Record if possible, TA == BSSID for AP */
prStaRec = staRecGetStaRecordByAddr(prAdapter, prJoinInfo->prBssDesc->aucBSSID);
/* We have renew this Sta Record when in JOIN_STATE_INIT */
ASSERT(prStaRec);
/* Record the Status Code of Authentication Request */
prStaRec->u2StatusCode = STATUS_CODE_JOIN_TIMEOUT;
/* Increase Failure Count */
prStaRec->ucJoinFailureCount++;
/* Reset Send Auth/(Re)Assoc Frame Count */
prJoinInfo->ucTxAuthAssocRetryCount = 0;
/* Cancel other JOIN relative Timer */
ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rTxRequestTimer);
ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rRxResponseTimer);
/* Restore original setting from current BSS_INFO_T */
if (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED)
joinAdoptParametersFromCurrentBss(prAdapter);
/* Pull back to IDLE */
joinFsmSteps(prAdapter, JOIN_STATE_IDLE);
return WLAN_STATUS_FAILURE;
} /* end of joinFsmRunEventJoinTimeOut() */
/*----------------------------------------------------------------------------*/
/*!
* \brief This function will adopt the parameters from Peer BSS.
*
* \param[in] prAdapter Pointer to the Adapter structure.
*
* \return (none)
*/
/*----------------------------------------------------------------------------*/
VOID joinAdoptParametersFromPeerBss(IN P_ADAPTER_T prAdapter)
{
P_JOIN_INFO_T prJoinInfo;
P_BSS_DESC_T prBssDesc;
DEBUGFUNC("joinAdoptParametersFromPeerBss");
ASSERT(prAdapter);
prJoinInfo = &prAdapter->rJoinInfo;
prBssDesc = prJoinInfo->prBssDesc;
/* 4 <1> Adopt Peer BSS' PHY TYPE */
prAdapter->eCurrentPhyType = prBssDesc->ePhyType;
DBGLOG(JOIN, INFO, "Target BSS[%s]'s PhyType = %s\n",
prBssDesc->aucSSID, (prBssDesc->ePhyType == PHY_TYPE_ERP_INDEX) ? "ERP" : "HR_DSSS");
/* 4 <2> Adopt Peer BSS' Frequency(Band/Channel) */
DBGLOG(JOIN, INFO, "Target BSS's Channel = %d, Band = %d\n", prBssDesc->ucChannelNum, prBssDesc->eBand);
nicSwitchChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum, 10);
prJoinInfo->fgIsParameterAdopted = TRUE;
} /* end of joinAdoptParametersFromPeerBss() */
/*----------------------------------------------------------------------------*/
/*!
* \brief This function will adopt the parameters from current associated BSS.
*
* \param[in] prAdapter Pointer to the Adapter structure.
*
* \return (none)
*/
/*----------------------------------------------------------------------------*/
VOID joinAdoptParametersFromCurrentBss(IN P_ADAPTER_T prAdapter)
{
/* P_JOIN_INFO_T prJoinInfo = &prAdapter->rJoinInfo; */
P_BSS_INFO_T prBssInfo;
ASSERT(prAdapter);
prBssInfo = &prAdapter->rBssInfo;
/* 4 <1> Adopt current BSS' PHY TYPE */
prAdapter->eCurrentPhyType = prBssInfo->ePhyType;
/* 4 <2> Adopt current BSS' Frequency(Band/Channel) */
DBGLOG(JOIN, INFO, "Current BSS's Channel = %d, Band = %d\n", prBssInfo->ucChnl, prBssInfo->eBand);
nicSwitchChannel(prAdapter, prBssInfo->eBand, prBssInfo->ucChnl, 10);
} /* end of joinAdoptParametersFromCurrentBss() */
/*----------------------------------------------------------------------------*/
/*!
* \brief This function will update all the SW variables and HW MCR registers after
* the association with target BSS.
*
* \param[in] prAdapter Pointer to the Adapter structure.
*
* \return (none)
*/
/*----------------------------------------------------------------------------*/
VOID joinComplete(IN P_ADAPTER_T prAdapter)
{
P_JOIN_INFO_T prJoinInfo;
P_BSS_DESC_T prBssDesc;
P_PEER_BSS_INFO_T prPeerBssInfo;
P_BSS_INFO_T prBssInfo;
P_CONNECTION_SETTINGS_T prConnSettings;
P_STA_RECORD_T prStaRec;
P_TX_CTRL_T prTxCtrl;
#if CFG_SUPPORT_802_11D
P_IE_COUNTRY_T prIECountry;
#endif
DEBUGFUNC("joinComplete");
ASSERT(prAdapter);
prJoinInfo = &prAdapter->rJoinInfo;
prBssDesc = prJoinInfo->prBssDesc;
prPeerBssInfo = &prAdapter->rPeerBssInfo;
prBssInfo = &prAdapter->rBssInfo;
prConnSettings = &prAdapter->rConnSettings;
prTxCtrl = &prAdapter->rTxCtrl;
/* 4 <1> Update Connecting & Connected Flag of BSS_DESC_T. */
/* Remove previous AP's Connection Flags if have */
scanRemoveConnectionFlagOfBssDescByBssid(prAdapter, prBssInfo->aucBSSID);
prBssDesc->fgIsConnected = TRUE; /* Mask as Connected */
if (prBssDesc->fgIsHiddenSSID) {
/* NOTE(Kevin): This is for the case of Passive Scan and the target BSS didn't
* broadcast SSID on its Beacon Frame.
*/
COPY_SSID(prBssDesc->aucSSID,
prBssDesc->ucSSIDLen, prAdapter->rConnSettings.aucSSID, prAdapter->rConnSettings.ucSSIDLen);
if (prBssDesc->ucSSIDLen)
prBssDesc->fgIsHiddenSSID = FALSE;
#if DBG
else
ASSERT(0);
#endif /* DBG */
DBGLOG(JOIN, INFO, "Hidden SSID! - Update SSID : %s\n", prBssDesc->aucSSID);
}
/* 4 <2> Update BSS_INFO_T from BSS_DESC_T */
/* 4 <2.A> PHY Type */
prBssInfo->ePhyType = prBssDesc->ePhyType;
/* 4 <2.B> BSS Type */
prBssInfo->eBSSType = BSS_TYPE_INFRASTRUCTURE;
/* 4 <2.C> BSSID */
COPY_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID);
DBGLOG(JOIN, INFO, "JOIN to BSSID: [" MACSTR "]\n", MAC2STR(prBssDesc->aucBSSID));
/* 4 <2.D> SSID */
COPY_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen);
/* 4 <2.E> Channel / Band information. */
prBssInfo->eBand = prBssDesc->eBand;
prBssInfo->ucChnl = prBssDesc->ucChannelNum;
/* 4 <2.F> RSN/WPA information. */
secFsmRunEventStart(prAdapter);
prBssInfo->u4RsnSelectedPairwiseCipher = prBssDesc->u4RsnSelectedPairwiseCipher;
prBssInfo->u4RsnSelectedGroupCipher = prBssDesc->u4RsnSelectedGroupCipher;
prBssInfo->u4RsnSelectedAKMSuite = prBssDesc->u4RsnSelectedAKMSuite;
if (secRsnKeyHandshakeEnabled())
prBssInfo->fgIsWPAorWPA2Enabled = TRUE;
else
prBssInfo->fgIsWPAorWPA2Enabled = FALSE;
/* 4 <2.G> Beacon interval. */
prBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval;
/* 4 <2.H> DTIM period. */
prBssInfo->ucDtimPeriod = prBssDesc->ucDTIMPeriod;
/* 4 <2.I> ERP Information */
if ((prBssInfo->ePhyType == PHY_TYPE_ERP_INDEX) && /* Our BSS's PHY_TYPE is ERP now. */
(prBssDesc->fgIsERPPresent)) {
prBssInfo->fgIsERPPresent = TRUE;
prBssInfo->ucERP = prBssDesc->ucERP; /* Save the ERP for later check */
} else {
/* Some AP, may send ProbeResp without ERP IE. Thus prBssDesc->fgIsERPPresent is FALSE. */
prBssInfo->fgIsERPPresent = FALSE;
prBssInfo->ucERP = 0;
}
#if CFG_SUPPORT_802_11D
/* 4 <2.J> Country inforamtion of the associated AP */
if (prConnSettings->fgMultiDomainCapabilityEnabled) {
DOMAIN_INFO_ENTRY rDomainInfo;
if (domainGetDomainInfoByScanResult(prAdapter, &rDomainInfo)) {
if (prBssDesc->prIECountry) {
prIECountry = prBssDesc->prIECountry;
domainParseCountryInfoElem(prIECountry, &prBssInfo->rDomainInfo);
/* use the domain get from the BSS info */
prBssInfo->fgIsCountryInfoPresent = TRUE;
nicSetupOpChnlList(prAdapter, prBssInfo->rDomainInfo.u2CountryCode, FALSE);
} else {
/* use the domain get from the scan result */
prBssInfo->fgIsCountryInfoPresent = TRUE;
nicSetupOpChnlList(prAdapter, rDomainInfo.u2CountryCode, FALSE);
}
}
}
#endif
/* 4 <2.K> Signal Power of the associated AP */
prBssInfo->rRcpi = prBssDesc->rRcpi;
prBssInfo->rRssi = RCPI_TO_dBm(prBssInfo->rRcpi);
GET_CURRENT_SYSTIME(&prBssInfo->rRssiLastUpdateTime);
/* 4 <2.L> Capability Field of the associated AP */
prBssInfo->u2CapInfo = prBssDesc->u2CapInfo;
DBGLOG(JOIN, INFO,
"prBssInfo-> fgIsERPPresent = %d, ucERP = %02x, rRcpi = %d, rRssi = %ld\n",
prBssInfo->fgIsERPPresent, prBssInfo->ucERP, prBssInfo->rRcpi, prBssInfo->rRssi);
/* 4 <3> Update BSS_INFO_T from PEER_BSS_INFO_T & NIC RATE FUNC */
/* 4 <3.A> Association ID */
prBssInfo->u2AssocId = prPeerBssInfo->u2AssocId;
/* 4 <3.B> WMM Information */
if (prAdapter->fgIsEnableWMM && (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_SUPPORT_WMM)) {
prBssInfo->fgIsWmmAssoc = TRUE;
prTxCtrl->rTxQForVoipAccess = TXQ_AC3;
qosWmmInfoInit(&prBssInfo->rWmmInfo, (prBssInfo->ePhyType == PHY_TYPE_HR_DSSS_INDEX) ? TRUE : FALSE);
if (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_AC_PARAM_PRESENT) {
kalMemCopy(&prBssInfo->rWmmInfo, &prPeerBssInfo->rWmmInfo, sizeof(WMM_INFO_T));
} else {
kalMemCopy(&prBssInfo->rWmmInfo,
&prPeerBssInfo->rWmmInfo,
sizeof(WMM_INFO_T) - sizeof(prPeerBssInfo->rWmmInfo.arWmmAcParams));
}
} else {
prBssInfo->fgIsWmmAssoc = FALSE;
prTxCtrl->rTxQForVoipAccess = TXQ_AC1;
kalMemZero(&prBssInfo->rWmmInfo, sizeof(WMM_INFO_T));
}
/* 4 <3.C> Operational Rate Set & BSS Basic Rate Set */
prBssInfo->u2OperationalRateSet = prPeerBssInfo->u2OperationalRateSet;
prBssInfo->u2BSSBasicRateSet = prPeerBssInfo->u2BSSBasicRateSet;
/* 4 <3.D> Short Preamble */
if (prBssInfo->fgIsERPPresent) {
/* NOTE(Kevin 2007/12/24): Truth Table.
* Short Preamble Bit in
* <AssocReq> <AssocResp w/i ERP> <BARKER(Long)> Final Driver Setting(Short)
* TRUE FALSE FALSE FALSE(shouldn't have such case, use the AssocResp)
* TRUE FALSE TRUE FALSE
* FALSE FALSE FALSE FALSE(shouldn't have such case, use the AssocResp)
* FALSE FALSE TRUE FALSE
* TRUE TRUE FALSE TRUE(follow ERP)
* TRUE TRUE TRUE FALSE(follow ERP)
* FALSE TRUE FALSE FALSE(shouldn't have such case, and we should set to FALSE)
* FALSE TRUE TRUE FALSE(we should set to FALSE)
*/
if ((prPeerBssInfo->fgIsShortPreambleAllowed) &&
((prConnSettings->ePreambleType == PREAMBLE_TYPE_SHORT) ||
/* Short Preamble Option Enable is TRUE */
((prConnSettings->ePreambleType == PREAMBLE_TYPE_AUTO) &&
(prBssDesc->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)))) {
prBssInfo->fgIsShortPreambleAllowed = TRUE;
if (prBssInfo->ucERP & ERP_INFO_BARKER_PREAMBLE_MODE)
prBssInfo->fgUseShortPreamble = FALSE;
else
prBssInfo->fgUseShortPreamble = TRUE;
} else {
prBssInfo->fgIsShortPreambleAllowed = FALSE;
prBssInfo->fgUseShortPreamble = FALSE;
}
} else {
/* NOTE(Kevin 2007/12/24): Truth Table.
* Short Preamble Bit in
* <AssocReq> <AssocResp w/o ERP> Final Driver Setting(Short)
* TRUE FALSE FALSE
* FALSE FALSE FALSE
* TRUE TRUE TRUE
* FALSE TRUE(status success) TRUE
* --> Honor the result of prPeerBssInfo.
*/
prBssInfo->fgIsShortPreambleAllowed = prBssInfo->fgUseShortPreamble =
prPeerBssInfo->fgIsShortPreambleAllowed;
}
DBGLOG(JOIN, INFO,
"prBssInfo->fgIsShortPreambleAllowed = %d, prBssInfo->fgUseShortPreamble = %d\n",
prBssInfo->fgIsShortPreambleAllowed, prBssInfo->fgUseShortPreamble);
/* 4 <3.E> Short Slot Time */
prBssInfo->fgUseShortSlotTime = prPeerBssInfo->fgUseShortSlotTime; /* AP support Short Slot Time */
DBGLOG(JOIN, INFO, "prBssInfo->fgUseShortSlotTime = %d\n", prBssInfo->fgUseShortSlotTime);
nicSetSlotTime(prAdapter,
prBssInfo->ePhyType,
((prConnSettings->fgIsShortSlotTimeOptionEnable &&
prBssInfo->fgUseShortSlotTime) ? TRUE : FALSE));
/* 4 <3.F> Update Tx Rate for Control Frame */
bssUpdateTxRateForControlFrame(prAdapter);
/* 4 <3.G> Save the available Auth Types during Roaming (Design for Fast BSS Transition). */
/* if (prAdapter->fgIsEnableRoaming) *//* NOTE(Kevin): Always prepare info for roaming */
{
if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_OPEN_SYSTEM)
prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_OPEN_SYSTEM;
else if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY)
prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_SHARED_KEY;
prBssInfo->ucRoamingAuthTypes = prJoinInfo->ucRoamingAuthTypes;
/* Set the stable time of the associated BSS. We won't do roaming decision
* during the stable time.
*/
SET_EXPIRATION_TIME(prBssInfo->rRoamingStableExpirationTime,
SEC_TO_SYSTIME(ROAMING_STABLE_TIMEOUT_SEC));
}
/* 4 <3.H> Update Parameter for TX Fragmentation Threshold */
#if CFG_TX_FRAGMENT
txFragInfoUpdate(prAdapter);
#endif /* CFG_TX_FRAGMENT */
/* 4 <4> Update STA_RECORD_T */
/* Get a Station Record if possible */
prStaRec = staRecGetStaRecordByAddr(prAdapter, prBssDesc->aucBSSID);
if (prStaRec) {
UINT_16 u2OperationalRateSet, u2DesiredRateSet;
/* 4 <4.A> Desired Rate Set */
u2OperationalRateSet = (rPhyAttributes[prBssInfo->ePhyType].u2SupportedRateSet &
prBssInfo->u2OperationalRateSet);
u2DesiredRateSet = (u2OperationalRateSet & prConnSettings->u2DesiredRateSet);
if (u2DesiredRateSet) {
prStaRec->u2DesiredRateSet = u2DesiredRateSet;
} else {
/* For Error Handling - The Desired Rate Set is not covered in Operational Rate Set. */
prStaRec->u2DesiredRateSet = u2OperationalRateSet;
}
/* Try to set the best initial rate for this entry */
if (!rateGetBestInitialRateIndex(prStaRec->u2DesiredRateSet,
prStaRec->rRcpi, &prStaRec->ucCurrRate1Index)) {
if (!rateGetLowestRateIndexFromRateSet(prStaRec->u2DesiredRateSet, &prStaRec->ucCurrRate1Index))
ASSERT(0);
}
DBGLOG(JOIN, INFO, "prStaRec->ucCurrRate1Index = %d\n", prStaRec->ucCurrRate1Index);
/* 4 <4.B> Preamble Mode */
prStaRec->fgIsShortPreambleOptionEnable = prBssInfo->fgUseShortPreamble;
/* 4 <4.C> QoS Flag */
prStaRec->fgIsQoS = prBssInfo->fgIsWmmAssoc;
}
#if DBG
else
ASSERT(0);
#endif /* DBG */
/* 4 <5> Update NIC */
/* 4 <5.A> Update BSSID & Operation Mode */
nicSetupBSS(prAdapter, prBssInfo);
/* 4 <5.B> Update WLAN Table. */
if (nicSetHwBySta(prAdapter, prStaRec) == FALSE)
ASSERT(FALSE);
/* 4 <5.C> Update Desired Rate Set for BT. */
#if CFG_TX_FRAGMENT
if (prConnSettings->fgIsEnableTxAutoFragmentForBT)
txRateSetInitForBT(prAdapter, prStaRec);
#endif /* CFG_TX_FRAGMENT */
/* 4 <5.D> TX AC Parameter and TX/RX Queue Control */
if (prBssInfo->fgIsWmmAssoc) {
#if CFG_TX_AGGREGATE_HW_FIFO
nicTxAggregateTXQ(prAdapter, FALSE);
#endif /* CFG_TX_AGGREGATE_HW_FIFO */
qosUpdateWMMParametersAndAssignAllowedACI(prAdapter, &prBssInfo->rWmmInfo);
} else {
#if CFG_TX_AGGREGATE_HW_FIFO
nicTxAggregateTXQ(prAdapter, TRUE);
#endif /* CFG_TX_AGGREGATE_HW_FIFO */
nicTxNonQoSAssignDefaultAdmittedTXQ(prAdapter);
nicTxNonQoSUpdateTXQParameters(prAdapter, prBssInfo->ePhyType);
}
#if CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN
{
prTxCtrl->fgBlockTxDuringJoin = FALSE;
#if !CFG_TX_AGGREGATE_HW_FIFO /* TX FIFO AGGREGATE already do flush once */
nicTxFlushStopQueues(prAdapter, (UINT_8) TXQ_DATA_MASK, (UINT_8) NULL);
#endif /* CFG_TX_AGGREGATE_HW_FIFO */
nicTxRetransmitOfSendWaitQue(prAdapter);
if (prTxCtrl->fgIsPacketInOsSendQueue)
nicTxRetransmitOfOsSendQue(prAdapter);
#if CFG_SDIO_TX_ENHANCE
halTxLeftClusteredMpdu(prAdapter);
#endif /* CFG_SDIO_TX_ENHANCE */
}
#endif /* CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN */
/* 4 <6> Setup CONNECTION flag. */
prAdapter->eConnectionState = MEDIA_STATE_CONNECTED;
prAdapter->eConnectionStateIndicated = MEDIA_STATE_CONNECTED;
if (prJoinInfo->fgIsReAssoc)
prAdapter->fgBypassPortCtrlForRoaming = TRUE;
else
prAdapter->fgBypassPortCtrlForRoaming = FALSE;
kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_CONNECT, (PVOID) NULL, 0);
} /* end of joinComplete() */
#endif