blob: 8101aa4e36eac5040a44328e293783a5a7a88b3e [file] [edit]
/******************************************************************************
*
* 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/aaa_fsm.c#3 $
*/
/*! \file "aaa_fsm.c"
* \brief This file defines the FSM for AAA MODULE.
*
* This file defines the FSM for AAA 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
******************************************************************************
*/
/******************************************************************************
* 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
******************************************************************************
*/
#if 0
/*----------------------------------------------------------------------------*/
/*!
* @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
*/
/*----------------------------------------------------------------------------*/
uint32_t aaaFsmSendEventJoinComplete(uint32_t rJoinStatus,
struct STA_RECORD *prStaRec, struct SW_RFB *prSwRfb)
{
P_MSG_SAA_JOIN_COMP_T prJoinCompMsg;
ASSERT(prStaRec);
prJoinCompMsg = cnmMemAlloc(RAM_TYPE_TCM, sizeof(MSG_SAA_JOIN_COMP_T));
if (!prJoinCompMsg)
return WLAN_STATUS_RESOURCES;
if (IS_STA_IN_AIS(prStaRec))
prJoinCompMsg->rMsgHdr.eMsgId = MID_SAA_AIS_JOIN_COMPLETE;
else if (IS_STA_IN_P2P(prStaRec))
prJoinCompMsg->rMsgHdr.eMsgId = MID_SAA_P2P_JOIN_COMPLETE;
else if (IS_STA_IN_BOW(prStaRec))
prJoinCompMsg->rMsgHdr.eMsgId = MID_SAA_BOW_JOIN_COMPLETE;
else
ASSERT(0);
prJoinCompMsg->rJoinStatus = rJoinStatus;
prJoinCompMsg->prStaRec = prStaRec;
prJoinCompMsg->prSwRfb = prSwRfb;
mboxSendMsg(MBOX_ID_0,
(struct MSG_HDR *) prJoinCompMsg,
MSG_SEND_METHOD_BUF);
return WLAN_STATUS_SUCCESS;
} /* end of saaFsmSendEventJoinComplete() */
/*----------------------------------------------------------------------------*/
/*!
* @brief This function will handle the Start Event to AAA FSM.
*
* @param[in] prMsgHdr Message of Join Request for a particular STA.
*
* @return none
*/
/*----------------------------------------------------------------------------*/
void aaaFsmRunEventStart(IN struct MSG_HDR *prMsgHdr)
{
P_MSG_SAA_JOIN_REQ_T prJoinReqMsg;
struct STA_RECORD *prStaRec;
struct BSS_INFO *prAisBssInfo;
ASSERT(prMsgHdr);
prJoinReqMsg = (P_MSG_SAA_JOIN_REQ_T) prMsgHdr;
prStaRec = prJoinReqMsg->prStaRec;
ASSERT(prStaRec);
DBGLOG(SAA, LOUD, "EVENT-START: Trigger SAA FSM\n");
cnmMemFree(prMsgHdr);
/* 4 <1> Validation of SAA Start Event */
if (!IS_AP_STA(prStaRec->eStaType)) {
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(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(prStaRec->prChallengeText);
prStaRec->prChallengeText = (struct IE_CHALLENGE_TEXT *) NULL;
}
cnmTimerStopTimer(&prStaRec->rTxReqDoneOrRxRespTimer);
prStaRec->ucStaState = STA_STATE_1;
/* Trigger SAA MODULE */
saaFsmSteps(prStaRec, SAA_STATE_SEND_AUTH1, (struct SW_RFB *) NULL);
} /* end of saaFsmRunEventStart() */
#endif
#if CFG_SUPPORT_AAA
void aaaFsmRunEventTxReqTimeOut(IN struct ADAPTER *prAdapter,
IN unsigned long plParamPtr)
{
struct STA_RECORD *prStaRec = (struct STA_RECORD *) plParamPtr;
struct BSS_INFO *prBssInfo;
prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex);
ASSERT(prStaRec);
if (!prStaRec)
return;
DBGLOG(AAA, 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 AAA_STATE_SEND_AUTH2:
DBGLOG(AAA, ERROR,
"LOST EVENT ,Auth Tx done disappear for (%d)Ms\n",
TU_TO_MSEC(TX_AUTHENTICATION_RESPONSE_TIMEOUT_TU));
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 */
break;
#if 0
/*state 2 to state 3 only check Assoc_req valid, no need for time out
*the fail case already handle at aaaFsmRunEventRxAssoc
*/
case AAA_STATE_SEND_ASSOC2:
DBGLOG(AAA, ERROR,
"LOST EVENT ,Assoc Tx done disappear for (%d)Ms\n",
TU_TO_MSEC(TX_AUTHENTICATION_RESPONSE_TIMEOUT_TU));
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 */
break;
#endif
default:
return;
}
} /* end of saaFsmRunEventTxReqTimeOut() */
/*---------------------------------------------------------------------------*/
/*!
* @brief This function will process the Rx Auth Request Frame and then
* trigger AAA FSM.
*
* @param[in] prAdapter Pointer to the Adapter structure.
* @param[in] prSwRfb Pointer to the SW_RFB_T structure.
*
* @return (none)
*/
/*---------------------------------------------------------------------------*/
void aaaFsmRunEventRxAuth(IN struct ADAPTER *prAdapter,
IN struct SW_RFB *prSwRfb)
{
struct BSS_INFO *prBssInfo = (struct BSS_INFO *) NULL;
struct STA_RECORD *prStaRec = (struct STA_RECORD *) NULL;
uint16_t u2StatusCode;
u_int8_t fgReplyAuth = FALSE;
struct WLAN_AUTH_FRAME *prAuthFrame = (struct WLAN_AUTH_FRAME *) NULL;
ASSERT(prAdapter);
do {
prAuthFrame = (struct WLAN_AUTH_FRAME *) prSwRfb->pvHeader;
DBGLOG(AAA, INFO,
"SA: " MACSTR ", bssid: " MACSTR ", sta idx: %d\n",
MAC2STR(prAuthFrame->aucSrcAddr),
MAC2STR(prAuthFrame->aucBSSID),
prSwRfb->ucStaRecIdx);
#if CFG_ENABLE_WIFI_DIRECT
prBssInfo = p2pFuncBSSIDFindBssInfo(prAdapter,
prAuthFrame->aucBSSID);
/* 4 <1> Check P2P network conditions */
/* if (prBssInfo && prAdapter->fgIsP2PRegistered) */
/* modify coding sytle to reduce indent */
if (!prAdapter->fgIsP2PRegistered)
goto bow_proc;
if (prBssInfo && 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 (u2StatusCode == STATUS_CODE_SUCCESSFUL) {
DBGLOG(AAA, TRACE,
"process RxAuth status success\n");
/* 4 <1.2> Validate Auth Frame
* for Network Specific Conditions
*/
fgReplyAuth = p2pFuncValidateAuth(
prAdapter,
prBssInfo,
prSwRfb,
&prStaRec,
&u2StatusCode);
#if CFG_SUPPORT_802_11W
/* AP PMF, if PMF connection,
* ignore Rx auth
*/
/* Certification 4.3.3.4 */
if (rsnCheckBipKeyInstalled(prAdapter,
prStaRec)) {
DBGLOG(AAA, INFO,
"Drop RxAuth\n");
return;
}
#endif
} else if (authFloodingCheck(
prAdapter,
prBssInfo,
prSwRfb) == FALSE) {
return;
} else {
fgReplyAuth = TRUE;
}
break;
}
}
#endif /* CFG_ENABLE_WIFI_DIRECT */
bow_proc:
/* 4 <2> Check BOW network conditions */
#if CFG_ENABLE_BT_OVER_WIFI
{
struct BOW_FSM_INFO *prBowFsmInfo =
(struct BOW_FSM_INFO *) NULL;
prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo);
prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter,
prBowFsmInfo->ucBssIndex);
if ((prBssInfo->fgIsNetActive)
&& (prBssInfo->eCurrentOPMode == OP_MODE_BOW)) {
/* 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 (u2StatusCode
== STATUS_CODE_SUCCESSFUL) {
/* 4 <2.2> Validate Auth Frame
* for Network Specific
* Conditions
*/
fgReplyAuth =
bowValidateAuth(prAdapter,
prSwRfb,
&prStaRec,
&u2StatusCode);
} else {
fgReplyAuth = TRUE;
}
/* TODO(Kevin): Allocate a STA_RECORD_T
* for new client
*/
break;
}
}
}
#endif /* CFG_ENABLE_BT_OVER_WIFI */
return;
} while (FALSE);
if (prStaRec) {
/* update RCPI */
ASSERT(prSwRfb->prRxStatusGroup3);
prStaRec->ucRCPI = nicRxGetRcpiValueFromRxv(RCPI_MODE_MAX,
prSwRfb);
}
/* 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);
}
if (prStaRec->eAuthAssocState
== AAA_STATE_SEND_AUTH2)
return;
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 */
if (WLAN_STATUS_SUCCESS !=
authSendAuthFrame(prAdapter,
prStaRec,
prBssInfo->ucBssIndex,
prSwRfb,
AUTH_TRANSACTION_SEQ_2,
u2StatusCode))
DBGLOG(AAA, WARN, "authSendAuthFrame fail!\n");
/*sta_rec might be removed
* when client list full, skip timer setting
*/
/*
* check if prStaRec valid as authSendAuthFrame may free
* StaRec when TX resource is not enough
*/
if (prStaRec && prStaRec->fgIsInUse) {
cnmTimerStopTimer(prAdapter,
&prStaRec->rTxReqDoneOrRxRespTimer);
/*ToDo:Init Timer to check get
* Auth Txdone avoid sta_rec not clear
*/
cnmTimerInitTimer(prAdapter,
&prStaRec->rTxReqDoneOrRxRespTimer,
(PFN_MGMT_TIMEOUT_FUNC)
aaaFsmRunEventTxReqTimeOut,
(unsigned long) prStaRec);
cnmTimerStartTimer(prAdapter,
&prStaRec->rTxReqDoneOrRxRespTimer,
TU_TO_MSEC(
TX_AUTHENTICATION_RESPONSE_TIMEOUT_TU));
}
} else if (prStaRec)
cnmStaRecFree(prAdapter, prStaRec);
} /* end of aaaFsmRunEventRxAuth() */
/*---------------------------------------------------------------------------*/
/*!
* @brief This function will process
* the Rx (Re)Association Request Frame and then
* trigger AAA FSM.
*
* @param[in] prAdapter Pointer to the Adapter structure.
* @param[in] prSwRfb Pointer to the SW_RFB_T structure.
*
* @retval WLAN_STATUS_SUCCESS Always return success
*/
/*---------------------------------------------------------------------------*/
uint32_t aaaFsmRunEventRxAssoc(IN struct ADAPTER *prAdapter,
IN struct SW_RFB *prSwRfb)
{
struct BSS_INFO *prBssInfo;
struct STA_RECORD *prStaRec = (struct STA_RECORD *) NULL;
uint16_t u2StatusCode = STATUS_CODE_RESERVED;
u_int8_t fgReplyAssocResp = FALSE;
u_int8_t fgSendSAQ = FALSE;
struct WLAN_ASSOC_REQ_FRAME *prAssocReqFrame =
(struct WLAN_ASSOC_REQ_FRAME *) NULL;
ASSERT(prAdapter);
ASSERT(prSwRfb);
do {
prAssocReqFrame =
(struct WLAN_ASSOC_REQ_FRAME *) prSwRfb->pvHeader;
DBGLOG(AAA, INFO,
"SA: " MACSTR ", bssid: " MACSTR ", sta idx: %d\n",
MAC2STR(prAssocReqFrame->aucSrcAddr),
MAC2STR(prAssocReqFrame->aucBSSID),
prSwRfb->ucStaRecIdx);
if (prSwRfb->ucStaRecIdx >= CFG_STA_REC_NUM)
return WLAN_STATUS_SUCCESS;
/* 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)) {
uint16_t i;
/* Not to reply association response
* with failure code due to lack of STA_REC
*/
DBGLOG(AAA, ERROR,
"get sta fail, wlan idx: %d, sta index: %d\n",
prSwRfb->ucWlanIdx,
prSwRfb->ucStaRecIdx);
for (i = 0; i < CFG_STA_REC_NUM; i++)
cnmDumpStaRec(prAdapter, i);
break;
}
if (!IS_CLIENT_STA(prStaRec)) {
DBGLOG(AAA, ERROR,
"error sta type, skip process rx assoc\n");
cnmDumpStaRec(prAdapter, prSwRfb->ucStaRecIdx);
break;
}
DBGLOG(AAA, TRACE,
"RxAssoc enter ucStaState:%d, eAuthassocState:%d\n",
prStaRec->ucStaState, prStaRec->eAuthAssocState);
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, WARN,
"Previous AuthAssocState (%d) != SEND_AUTH2.\n",
prStaRec->eAuthAssocState);
/* Maybe Auth Response TX fail,
* but actually it success.
*/
cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2);
}
/* update RCPI */
ASSERT(prSwRfb->prRxStatusGroup3);
prStaRec->ucRCPI =
nicRxGetRcpiValueFromRxv(RCPI_MODE_MAX, prSwRfb);
/* 4 <2> Check P2P network conditions */
#if CFG_ENABLE_WIFI_DIRECT
if ((prAdapter->fgIsP2PRegistered)
&& (IS_STA_IN_P2P(prStaRec))) {
prBssInfo =
GET_BSS_INFO_BY_INDEX(prAdapter,
prStaRec->ucBssIndex);
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 (u2StatusCode
== STATUS_CODE_SUCCESSFUL) {
/* 4 <2.2>
* Validate Assoc Req Frame
* for Network Specific
* Conditions
*/
fgReplyAssocResp =
p2pFuncValidateAssocReq(
prAdapter,
prSwRfb,
(uint16_t *)
&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_BOW_TYPE(prStaRec)) {
prBssInfo =
GET_BSS_INFO_BY_INDEX(prAdapter,
prStaRec->ucBssIndex);
if ((prBssInfo->fgIsNetActive)
&& (prBssInfo->eCurrentOPMode == OP_MODE_BOW)) {
/* 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 (u2StatusCode
== STATUS_CODE_SUCCESSFUL) {
/* 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) {
uint16_t u2IELength;
uint8_t *pucIE;
cnmTimerStopTimer(prAdapter,
&prStaRec->rTxReqDoneOrRxRespTimer);
if ((((struct WLAN_ASSOC_REQ_FRAME *)
(prSwRfb->pvHeader))->u2FrameCtrl & MASK_FRAME_TYPE) ==
MAC_FRAME_REASSOC_REQ) {
u2IELength = prSwRfb->u2PacketLen -
(uint16_t)
OFFSET_OF(struct WLAN_REASSOC_REQ_FRAME,
aucInfoElem[0]);
pucIE = ((struct WLAN_REASSOC_REQ_FRAME *)
(prSwRfb->pvHeader))->aucInfoElem;
} else {
u2IELength = prSwRfb->u2PacketLen -
(uint16_t)
OFFSET_OF(struct WLAN_ASSOC_REQ_FRAME,
aucInfoElem[0]);
pucIE = ((struct WLAN_ASSOC_REQ_FRAME *)
(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))) {
prBssInfo =
GET_BSS_INFO_BY_INDEX(prAdapter,
prStaRec->ucBssIndex);
if (p2pRoleFsmRunEventAAAComplete(prAdapter,
prStaRec, prBssInfo)
== WLAN_STATUS_SUCCESS) {
prStaRec->u2AssocId =
bssAssignAssocID(prStaRec);
/* prStaRec->eAuthAssocState
* = AA_STATE_IDLE;
*/
/* NOTE(Kevin): for TX done */
prStaRec->eAuthAssocState =
AAA_STATE_SEND_ASSOC2;
/* 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;
/* Invalid Association ID */
prStaRec->u2AssocId = 0;
/* If(Re)association fail,
* remove sta record and
* use class error to handle sta
*/
prStaRec->eAuthAssocState =
AA_STATE_IDLE;
/* 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_BOW_TYPE(prStaRec))) {
/* if (bowRunEventAAAComplete(prAdapter,
* prStaRec) == WLAN_STATUS_SUCCESS) {
*/
prStaRec->u2AssocId =
bssAssignAssocID(prStaRec);
/* NOTE(Kevin): for TX done */
prStaRec->eAuthAssocState =
AAA_STATE_SEND_ASSOC2;
/* NOTE(Kevin):
* Method A: Change to STATE_3
* before handle TX Done
*/
/* cnmStaRecChangeState(prAdapter,
* prStaRec, STA_STATE_3);
*/
}
#endif
} else {
#if CFG_SUPPORT_802_11W
/* AP PMF */
/* don't change state,
* just send assoc resp
* (NO need TX done, TIE + code30)
* and then SAQ
*/
if (u2StatusCode
== STATUS_CODE_ASSOC_REJECTED_TEMPORARILY) {
DBGLOG(AAA, INFO, "AP send SAQ\n");
fgSendSAQ = TRUE;
} else
#endif
{
/* Invalid Association ID */
prStaRec->u2AssocId = 0;
/* If (Re)association fail, remove sta record
* and use class error to handle sta
*/
prStaRec->eAuthAssocState = AA_STATE_IDLE;
/* Remove from client list if it was previously
* associated
*/
if ((prStaRec->ucStaState > STA_STATE_1) &&
prAdapter->fgIsP2PRegistered &&
(IS_STA_IN_P2P(prStaRec))) {
struct BSS_INFO *prBssInfo = NULL;
prBssInfo = GET_BSS_INFO_BY_INDEX(
prAdapter,
prStaRec->ucBssIndex);
if (prBssInfo) {
DBGLOG(AAA, INFO,
"Remove client\n");
bssRemoveClient(
prAdapter,
prBssInfo,
prStaRec);
}
}
/* 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);
#if CFG_SUPPORT_802_11W
/* AP PMF */
if (fgSendSAQ) {
/* if PMF connection, and return code 30, send SAQ */
rsnApStartSaQuery(prAdapter, prStaRec);
}
#endif
}
return WLAN_STATUS_SUCCESS;
} /* end of aaaFsmRunEventRxAssoc() */
/*---------------------------------------------------------------------------*/
/*!
* @brief This function will handle TxDone(Auth2/AssocReq) Event of AAA FSM.
*
* @param[in] prAdapter Pointer to the Adapter structure.
* @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
*/
/*---------------------------------------------------------------------------*/
uint32_t
aaaFsmRunEventTxDone(IN struct ADAPTER *prAdapter,
IN struct MSDU_INFO *prMsduInfo,
IN enum ENUM_TX_RESULT_CODE rTxDoneStatus)
{
struct STA_RECORD *prStaRec;
struct BSS_INFO *prBssInfo;
ASSERT(prAdapter);
ASSERT(prMsduInfo);
DBGLOG(AAA, INFO,
"EVENT-TX DONE [status: %d][seq: %d]: Current Time = %d\n",
rTxDoneStatus,
prMsduInfo->ucTxSeqNum,
kalGetTimeTick());
prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
/* For the case of replying ERROR STATUS CODE */
if ((!prStaRec) || (!prStaRec->fgIsInUse))
return WLAN_STATUS_SUCCESS;
ASSERT(prStaRec->ucBssIndex <= prAdapter->ucHwBssIdNum);
prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex);
DBGLOG(AAA, TRACE, "TxDone ucStaState:%d, eAuthAssocState:%d\n",
prStaRec->ucStaState, prStaRec->eAuthAssocState);
/* 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;
cnmTimerStopTimer(prAdapter,
&prStaRec->rTxReqDoneOrRxRespTimer);
if (prStaRec->u2StatusCode == STATUS_CODE_SUCCESSFUL) {
if (rTxDoneStatus == TX_RESULT_SUCCESS) {
/* NOTE(Kevin):
* Change to STATE_2 at TX Done
*/
cnmStaRecChangeState(prAdapter,
prStaRec, STA_STATE_2);
/* Error handle if can not
* complete the ASSOC flow
*/
cnmTimerStartTimer(prAdapter,
&prStaRec->rTxReqDoneOrRxRespTimer,
TU_TO_MSEC(TX_ASSOCIATE_TIMEOUT_TU));
} 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 */
#if IS_ENABLED(CFG_CCN7_SAP_EASYMESH)
aaaStaEventNotify(prStaRec,
prBssInfo->aucBSSID,
prStaRec->fgIsInUse);
#endif /* CFG_CCN7_SAP_EASYMESH */
}
}
/* 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 (prStaRec->u2StatusCode == STATUS_CODE_SUCCESSFUL) {
if (rTxDoneStatus == TX_RESULT_SUCCESS) {
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.
*/
/* 2017-01-12 Do nothing only when STA is in state 3 */
/* Free the StaRec if found any unexpected status */
if (prStaRec->ucStaState != STA_STATE_3)
cnmStaRecFree(prAdapter, prStaRec);
break;
default:
break; /* Ignore other cases */
}
DBGLOG(AAA, TRACE, "TxDone end ucStaState:%d, eAuthAssocState:%d\n",
prStaRec->ucStaState, prStaRec->eAuthAssocState);
return WLAN_STATUS_SUCCESS;
} /* end of aaaFsmRunEventTxDone() */
#if IS_ENABLED(CFG_CCN7_SAP_EASYMESH)
uint32_t aaaChanNoiseControl(struct GLUE_INFO *prGlueInfo,
bool fgIsChanNoiseEnable)
{
uint8_t ucBand = ENUM_BAND_0;
uint32_t u4BufLen = 0;
uint32_t rStatus = WLAN_STATUS_FAILURE;
struct CMD_GET_TRAFFIC_REPORT *cmd_traffic = NULL;
struct CMD_NOISE_HISTOGRAM_REPORT *cmd_noise = NULL;
/* traffic report and noise histogram */
cmd_traffic =
(struct CMD_GET_TRAFFIC_REPORT *)
kalMemAlloc(sizeof(*cmd_traffic), VIR_MEM_TYPE);
if (!cmd_traffic)
goto error;
cmd_noise =
(struct CMD_NOISE_HISTOGRAM_REPORT *)
kalMemAlloc(sizeof(*cmd_noise), VIR_MEM_TYPE);
if (!cmd_noise)
goto error;
/* set traffic report enable/disable */
memset(cmd_traffic, 0, sizeof(*cmd_traffic));
cmd_traffic->u2Type = CMD_GET_REPORT_TYPE;
cmd_traffic->u2Len = sizeof(*cmd_traffic);
cmd_traffic->ucBand = ucBand;
if (fgIsChanNoiseEnable) {
prGlueInfo->prAdapter->u4IsKeepFullPwrBitmap |=
KEEP_FULL_PWR_TRAFFIC_REPORT_BIT;
cmd_traffic->ucAction = CMD_GET_REPORT_ENABLE;
} else {
prGlueInfo->prAdapter->u4IsKeepFullPwrBitmap &=
~KEEP_FULL_PWR_TRAFFIC_REPORT_BIT;
cmd_traffic->ucAction = CMD_GET_REPORT_DISABLE;
}
cmd_traffic->u2Type |= CMD_ADV_CONTROL_SET;
rStatus = kalIoctl(prGlueInfo,
wlanoidAdvCtrl,
cmd_traffic,
sizeof(*cmd_traffic),
TRUE, TRUE, TRUE,
&u4BufLen);
if (rStatus != WLAN_STATUS_SUCCESS) {
DBGLOG(REQ, ERROR, "ERR: kalIoctl fail (%x)\r\n", rStatus);
goto error;
}
/* set noise histogram enable/disable */
memset(cmd_noise, 0, sizeof(*cmd_noise));
cmd_noise->u2Type = CMD_NOISE_HISTOGRAM_TYPE;
cmd_noise->u2Len = sizeof(*cmd_noise);
if (fgIsChanNoiseEnable) {
prGlueInfo->prAdapter->u4IsKeepFullPwrBitmap |=
KEEP_FULL_PWR_NOISE_HISTOGRAM_BIT;
cmd_noise->ucAction = CMD_NOISE_HISTOGRAM_ENABLE;
} else {
prGlueInfo->prAdapter->u4IsKeepFullPwrBitmap &=
~KEEP_FULL_PWR_NOISE_HISTOGRAM_BIT;
cmd_noise->ucAction = CMD_NOISE_HISTOGRAM_DISABLE;
}
cmd_noise->u2Type |= CMD_ADV_CONTROL_SET;
rStatus = kalIoctl(prGlueInfo,
wlanoidAdvCtrl,
cmd_noise,
sizeof(*cmd_noise),
TRUE, TRUE, TRUE,
&u4BufLen);
if (rStatus != WLAN_STATUS_SUCCESS) {
DBGLOG(REQ, ERROR, "ERR: kalIoctl fail (%x)\r\n", rStatus);
goto error;
}
rStatus = WLAN_STATUS_SUCCESS;
error:
if (cmd_traffic)
kalMemFree(cmd_traffic, VIR_MEM_TYPE, sizeof(*cmd_traffic));
if (cmd_noise)
kalMemFree(cmd_noise, VIR_MEM_TYPE, sizeof(*cmd_noise));
return rStatus;
}
void aaaChanNoiseInitWorkHandler(struct work_struct *work)
{
struct GLUE_INFO *prGlueInfo;
uint32_t rStatus = WLAN_STATUS_SUCCESS;
prGlueInfo = ENTRY_OF(work, struct GLUE_INFO, rChanNoiseControlWork);
/* Disable traffic report and noise histogram */
rStatus = aaaChanNoiseControl(prGlueInfo, FALSE);
if (rStatus != WLAN_STATUS_SUCCESS) {
DBGLOG(AAA, ERROR,
"Disable traffic report and nose histogram fail\n");
goto error;
}
/* Enable traffic report and noise histogram */
rStatus = aaaChanNoiseControl(prGlueInfo, TRUE);
if (rStatus != WLAN_STATUS_SUCCESS) {
DBGLOG(AAA, ERROR,
"Enable traffic report and nose histogram fail\n");
goto error;
}
error:
if (!rStatus)
schedule_delayed_work(&prGlueInfo->rChanNoiseGetInfoWork,
MSEC_TO_JIFFIES(SAP_CHAN_NOISE_GET_INFO_PERIOD));
else
schedule_delayed_work(&prGlueInfo->rChanNoiseControlWork, 0);
}
void aaaChanNoiseCollectionWorkHandler(struct work_struct *work)
{
struct GLUE_INFO *prGlueInfo;
uint32_t u4BufLen = 0;
uint8_t ucRoleIdx = 0;
uint8_t ucBssIdx = 0;
uint32_t u4SampleDuration = 0;
uint32_t u4NoiseTotalCnt = 0;
uint8_t ucBand = ENUM_BAND_0;
uint32_t rStatus = WLAN_STATUS_SUCCESS;
struct BSS_INFO *prBssInfo = NULL;
struct CMD_GET_TRAFFIC_REPORT *cmd_traffic = NULL;
struct CMD_NOISE_HISTOGRAM_REPORT *cmd_noise = NULL;
struct T_MULTI_AP_BSS_METRICS_RESP *sBssMetricsResp = NULL;
int32_t i4Ret = 0;
prGlueInfo = ENTRY_OF(work, struct GLUE_INFO, rChanNoiseGetInfoWork);
cmd_traffic = (struct CMD_GET_TRAFFIC_REPORT *)
kalMemAlloc(sizeof(*cmd_traffic), VIR_MEM_TYPE);
if (!cmd_traffic)
goto error;
cmd_noise = (struct CMD_NOISE_HISTOGRAM_REPORT *)
kalMemAlloc(sizeof(*cmd_noise), VIR_MEM_TYPE);
if (!cmd_noise)
goto error;
/* get Bss Index from ndev */
if (mtk_Netdev_To_RoleIdx(prGlueInfo,
prGlueInfo->prP2PInfo[1]->prDevHandler,
&ucRoleIdx) != 0)
goto error;
if (p2pFuncRoleToBssIdx(prGlueInfo->prAdapter,
ucRoleIdx, &ucBssIdx) != WLAN_STATUS_SUCCESS)
goto error;
DBGLOG(REQ, INFO, "ucRoleIdx = %d\n", ucRoleIdx);
prBssInfo = GET_BSS_INFO_BY_INDEX(prGlueInfo->prAdapter, ucBssIdx);
if (!prBssInfo) {
DBGLOG(REQ, WARN, "bss is not active\n");
goto error;
}
/* get traffic report */
memset(cmd_traffic, 0, sizeof(*cmd_traffic));
cmd_traffic->u2Type = CMD_GET_REPORT_TYPE;
cmd_traffic->u2Len = sizeof(*cmd_traffic);
cmd_traffic->ucBand = ucBand;
cmd_traffic->ucAction = CMD_GET_REPORT_GET;
rStatus = kalIoctl(prGlueInfo,
wlanoidAdvCtrl,
cmd_traffic,
sizeof(*cmd_traffic),
TRUE, TRUE, TRUE,
&u4BufLen);
if (rStatus != WLAN_STATUS_SUCCESS) {
DBGLOG(REQ, ERROR, "ERR: kalIoctl fail (%x)\r\n", rStatus);
goto error;
}
u4SampleDuration = cmd_traffic->u4FetchEd - cmd_traffic->u4FetchSt;
if (!u4SampleDuration)
u4SampleDuration = 255;
prBssInfo->u4ChanUtil = cmd_traffic->u4ChBusy
/ (u4SampleDuration / 255);
DBGLOG(AAA, INFO,
"[Traffic Report] u4ChBusy = %d\n", cmd_traffic->u4ChBusy);
DBGLOG(AAA, INFO,
"[Traffic Report] Duration = %d\n",
cmd_traffic->u4FetchEd - cmd_traffic->u4FetchSt);
/* get noise histogram */
memset(cmd_noise, 0, sizeof(*cmd_noise));
cmd_noise->u2Type = CMD_NOISE_HISTOGRAM_TYPE;
cmd_noise->u2Len = sizeof(*cmd_noise);
cmd_noise->ucAction = CMD_NOISE_HISTOGRAM_GET;
rStatus = kalIoctl(prGlueInfo,
wlanoidAdvCtrl,
cmd_noise,
sizeof(*cmd_noise),
TRUE, TRUE, TRUE,
&u4BufLen);
if (rStatus != WLAN_STATUS_SUCCESS) {
DBGLOG(REQ, ERROR, "ERR: kalIoctl fail (%x)\r\n", rStatus);
goto error;
}
u4NoiseTotalCnt =
cmd_noise->u4IPI0 + cmd_noise->u4IPI1
+ cmd_noise->u4IPI2 + cmd_noise->u4IPI3
+ cmd_noise->u4IPI4 + cmd_noise->u4IPI5
+ cmd_noise->u4IPI6 + cmd_noise->u4IPI7
+ cmd_noise->u4IPI8 + cmd_noise->u4IPI9
+ cmd_noise->u4IPI10;
if (!u4NoiseTotalCnt)
u4NoiseTotalCnt = 1;
prBssInfo->i4NoiseHistogram =
((cmd_noise->u4IPI0 * (95) + cmd_noise->u4IPI1 * (90) +
cmd_noise->u4IPI2 * (87) + cmd_noise->u4IPI3 * (84) +
cmd_noise->u4IPI4 * (81) + cmd_noise->u4IPI5 * (77) +
cmd_noise->u4IPI6 * (72) + cmd_noise->u4IPI7 * (67) +
cmd_noise->u4IPI8 * (62) + cmd_noise->u4IPI9 * (57) +
cmd_noise->u4IPI10 * (55)) / u4NoiseTotalCnt) * (-1);
DBGLOG(AAA, INFO,
"[Noise Histogram] u4NoiseTotalCnt = %d\n", u4NoiseTotalCnt);
DBGLOG(AAA, INFO,
"[Noise Histogram] i4NoiseHistogram = %d\n",
prBssInfo->i4NoiseHistogram);
sBssMetricsResp = (struct T_MULTI_AP_BSS_METRICS_RESP *)
kalMemAlloc(sizeof(struct T_MULTI_AP_BSS_METRICS_RESP),
VIR_MEM_TYPE);
if (sBssMetricsResp == NULL) {
DBGLOG(INIT, ERROR, "alloc memory fail\n");
goto error;
}
/* 1. BSS Measurement */
/* Interface Index */
i4Ret = sscanf(prGlueInfo->prP2PInfo[1]->prDevHandler->name,
"ap%u", &sBssMetricsResp->uIfIndex);
if (i4Ret != 1)
DBGLOG(P2P, WARN, "read sap index fail: %d\n", i4Ret);
COPY_MAC_ADDR(sBssMetricsResp->mBssid, prBssInfo->aucBSSID);
sBssMetricsResp->u8Channel = prBssInfo->ucPrimaryChannel;
sBssMetricsResp->u16AssocStaNum =
bssGetClientCount(prGlueInfo->prAdapter, prBssInfo);
sBssMetricsResp->u8ChanUtil = prBssInfo->u4ChanUtil;
sBssMetricsResp->iChanNoise = prBssInfo->i4NoiseHistogram;
DBGLOG(REQ, WARN,
"[SAP_Test] uIfIndex = %u\n", sBssMetricsResp->uIfIndex);
DBGLOG(REQ, WARN,
"[SAP_Test] mBssid = " MACSTR "\n",
MAC2STR(sBssMetricsResp->mBssid));
DBGLOG(REQ, WARN,
"[SAP_Test] u8Channel = %d\n", sBssMetricsResp->u8Channel);
DBGLOG(REQ, WARN,
"[SAP_Test] u16AssocStaNum = %d\n",
sBssMetricsResp->u16AssocStaNum);
DBGLOG(REQ, WARN,
"[SAP_Test] u8ChanUtil = %d\n", sBssMetricsResp->u8ChanUtil);
DBGLOG(REQ, WARN,
"[SAP_Test] iChanNoise = %d\n", sBssMetricsResp->iChanNoise);
i4Ret = MontorSendMsg(EV_WLAN_MULTIAP_BSS_METRICS_RESPONSE,
sBssMetricsResp, sizeof(*sBssMetricsResp));
if (i4Ret < 0)
DBGLOG(AAA, ERROR,
"EV_WLAN_MULTIAP_BSS_METRICS_RESPONSE nl send msg failed!\n");
kalMemFree(sBssMetricsResp, VIR_MEM_TYPE, sizeof(*sBssMetricsResp));
error:
if (cmd_traffic)
kalMemFree(cmd_traffic, VIR_MEM_TYPE, sizeof(*cmd_traffic));
if (cmd_noise)
kalMemFree(cmd_noise, VIR_MEM_TYPE, sizeof(*cmd_noise));
aaaChanNoiseControl(prGlueInfo, FALSE);
}
void aaaStaEventNotify(IN struct STA_RECORD *prStaRec,
IN unsigned char *pucAddr, IN unsigned char fgIsConnected)
{
int32_t i4Ret = 0;
struct T_MULTI_AP_STA_EVENT_NOTIFY *prStaEventNotify;
/* STA Event notification */
/* Multi-AP_Specification_v1.0 17.2.19 */
if (prStaRec->u2AssocReqIeLen
+ OFFSET_OF(struct T_MULTI_AP_STA_EVENT_NOTIFY, u8Cap)
> sizeof(struct T_MULTI_AP_STA_EVENT_NOTIFY)) {
DBGLOG(AAA, ERROR,
"IE too large %d %d\n",
prStaRec->u2AssocReqIeLen,
sizeof(struct T_MULTI_AP_STA_EVENT_NOTIFY));
return;
}
prStaEventNotify = kalMemAlloc(sizeof(*prStaEventNotify), VIR_MEM_TYPE);
if (!prStaEventNotify) {
DBGLOG(AAA, ERROR, "mem alloc fail\n");
return;
}
COPY_MAC_ADDR(prStaEventNotify->mStaMac, prStaRec->aucMacAddr);
COPY_MAC_ADDR(prStaEventNotify->mBssid, pucAddr);
prStaEventNotify->u8Status = fgIsConnected;
prStaEventNotify->uCapLen = 1 + 2 + 2 + prStaRec->u2AssocReqIeLen;
prStaEventNotify->u8Cap[0] = 0; /* 0:Success 1:Fail */
WLAN_SET_FIELD_16(prStaEventNotify->u8Cap + 1, prStaRec->u2CapInfo);
WLAN_SET_FIELD_16(prStaEventNotify->u8Cap + 3,
prStaRec->u2ListenInterval);
kalMemCopy(prStaEventNotify->u8Cap + 5,
prStaRec->pucAssocReqIe,
prStaRec->u2AssocReqIeLen);
DBGLOG(AAA, WARN,
"[SAP_Test] mStaMac=" MACSTR "\n",
MAC2STR(prStaEventNotify->mStaMac));
DBGLOG(AAA, WARN,
"[SAP_Test] mBssid=" MACSTR "\n",
MAC2STR(prStaEventNotify->mBssid));
DBGLOG(AAA, WARN,
"[SAP_Test] u8Status=%d\n", prStaEventNotify->u8Status);
DBGLOG(AAA, WARN,
"[SAP_Test] uCapLen=%d\n", prStaEventNotify->uCapLen);
DBGLOG_MEM8(AAA, WARN,
prStaEventNotify,
offsetof(struct T_MULTI_AP_STA_EVENT_NOTIFY, u8Cap) + 5);
DBGLOG_MEM8(AAA, WARN,
prStaEventNotify->u8Cap, prStaEventNotify->uCapLen);
i4Ret = MontorSendMsg(EV_WLAN_MULTIAP_STA_TOPOLOGY_NOTIFY,
prStaEventNotify, sizeof(*prStaEventNotify));
if (i4Ret < 0)
DBGLOG(AAA, ERROR,
"EV_WLAN_MULTIAP_STA_TOPOLOGY_NOTIFY nl send msg failed!\n");
kalMemFree(prStaEventNotify, VIR_MEM_TYPE, sizeof(*prStaEventNotify));
}
void aaaUnassocStaMeasureTimeout(IN struct ADAPTER *prAdapter,
unsigned long ulParamPtr)
{
int32_t i4Ret = 0;
uint8_t ucIndex = 0;
struct BSS_INFO *prBssInfo = NULL;
struct GLUE_INFO *prGlueInfo = NULL;
uint8_t aucZeroMacAddr[] = NULL_MAC_ADDR;
struct T_MULTI_AP_STA_UNASSOC_METRICS_RESP
*sStaUnAssocMetricsResp = NULL;
prGlueInfo = prAdapter->prGlueInfo;
prBssInfo = (struct BSS_INFO *) ulParamPtr;
if (!prBssInfo) {
DBGLOG(REQ, WARN, "bss is not active\n");
return;
}
sStaUnAssocMetricsResp =
kalMemAlloc(sizeof(*sStaUnAssocMetricsResp), VIR_MEM_TYPE);
if (!sStaUnAssocMetricsResp) {
DBGLOG(INIT, ERROR, "mem alloc fail\n");
return;
}
kalMemZero(sStaUnAssocMetricsResp,
sizeof(struct T_MULTI_AP_STA_UNASSOC_METRICS_RESP));
/* Interface Index */
i4Ret = sscanf(prGlueInfo->prP2PInfo[1]->prDevHandler->name,
"ap%u", &sStaUnAssocMetricsResp->uIfIndex);
if (i4Ret != 1)
DBGLOG(P2P, WARN, "read sap index fail: %d\n", i4Ret);
COPY_MAC_ADDR(sStaUnAssocMetricsResp->mBssid, prBssInfo->aucBSSID);
kalMemCopy(sStaUnAssocMetricsResp->tMetrics,
prBssInfo->arUnAssocSTA,
sizeof(struct T_MULTI_AP_STA_UNASSOC_METRICS)
* SAP_UNASSOC_METRICS_STA_MAX);
for (ucIndex = 0; ucIndex < SAP_UNASSOC_METRICS_STA_MAX; ucIndex++) {
if (EQUAL_MAC_ADDR(aucZeroMacAddr,
sStaUnAssocMetricsResp->tMetrics[ucIndex].mStaMac))
continue;
sStaUnAssocMetricsResp->u8StaNum++;
if (sStaUnAssocMetricsResp->tMetrics[ucIndex].uTime != 0)
sStaUnAssocMetricsResp->tMetrics[ucIndex].uTime =
kalGetTimeTick()
- sStaUnAssocMetricsResp
->tMetrics[ucIndex].uTime;
}
for (ucIndex = 0; ucIndex < SAP_UNASSOC_METRICS_STA_MAX; ucIndex++) {
DBGLOG(REQ, WARN,
"[SAP_Test] [Report] arUnAssocSTA[%d]="MACSTR
",time=%u, RSSI=%d, ch=%d\n",
ucIndex,
MAC2STR(sStaUnAssocMetricsResp
->tMetrics[ucIndex].mStaMac),
sStaUnAssocMetricsResp->tMetrics[ucIndex].uTime,
sStaUnAssocMetricsResp->tMetrics[ucIndex].iRssi,
sStaUnAssocMetricsResp->tMetrics[ucIndex].u8Channel);
}
DBGLOG(REQ, WARN,
"[SAP_Test] uIfIndex = %u\n",
sStaUnAssocMetricsResp->uIfIndex);
DBGLOG(REQ, WARN,
"[SAP_Test] mBssid = " MACSTR "\n",
MAC2STR(sStaUnAssocMetricsResp->mBssid));
DBGLOG(REQ, WARN,
"[SAP_Test] u8StaNum = %u\n",
sStaUnAssocMetricsResp->u8StaNum);
i4Ret = MontorSendMsg(EV_WLAN_MULTIAP_UNASSOC_STA_METRICS_RESPONSE,
sStaUnAssocMetricsResp, sizeof(*sStaUnAssocMetricsResp));
if (i4Ret < 0)
DBGLOG(AAA, ERROR,
"EV_WLAN_MULTIAP_UNASSOC_STA_METRICS_RESPONSE nl send msg failed!\n");
kalMemFree(sStaUnAssocMetricsResp,
VIR_MEM_TYPE,
sizeof(struct T_MULTI_AP_STA_UNASSOC_METRICS_RESP));
}
#endif
#endif /* CFG_SUPPORT_AAA */
#if 0
/* TODO(Kevin): for abort event, just reset the STA_RECORD_T. */
/*---------------------------------------------------------------------------*/
/*!
* \brief This function will send ABORT Event to JOIN FSM.
*
* \param[in] prAdapter Pointer to the Adapter structure.
*
* \return none
*/
/*---------------------------------------------------------------------------*/
void saaFsmRunEventAbort(IN struct MSG_HDR *prMsgHdr)
{
P_JOIN_INFO_T prJoinInfo;
struct STA_RECORD *prStaRec;
DEBUGFUNC("joinFsmRunEventAbort");
ASSERT(prAdapter);
prJoinInfo = &prAdapter->rJoinInfo;
DBGLOG(JOIN, EVENT, "JOIN EVENT: ABORT\n");
/* NOTE(Kevin): when reach here,
* the ARB_STATE should be in ARB_STATE_JOIN.
*/
ASSERT(prJoinInfo->prBssDesc);
/* 4 <1> Update Flags and Elements of JOIN Module. */
/* Reset Send Auth/(Re)Assoc Frame Count */
prJoinInfo->ucTxAuthAssocRetryCount = 0;
/* Cancel all JOIN relative Timer */
ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rTxRequestTimer);
ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rRxResponseTimer);
ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rJoinTimer);
/* 4 <2> Update the associated
* STA_RECORD_T during JOIN.
*/
/* Get a Station Record if possible, TA == BSSID for AP */
prStaRec = staRecGetStaRecordByAddr(prAdapter,
prJoinInfo->prBssDesc->aucBSSID);
if (prStaRec)
prStaRec->ucStaState = STA_STATE_1;
/* Update Station Record - Class 1 Flag */
#if DBG
else
ASSERT(0);
/* Shouldn't happened, because we already
* add this STA_RECORD_T at JOIN_STATE_INIT
*/
#endif /* DBG */
/* 4 <3> Pull back to IDLE. */
joinFsmSteps(prAdapter, JOIN_STATE_IDLE);
/* 4 <4> If we are in Roaming, recover the settings of previous BSS. */
/* NOTE: JOIN FAIL -
* Restore original setting from current struct BSS_INFO.
*/
if (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED)
joinAdoptParametersFromCurrentBss(prAdapter);
} /* end of joinFsmRunEventAbort() */
#endif
/* 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
*/
/*----------------------------------------------------------------------------*/
uint32_t joinFsmRunEventJoinTimeOut(IN struct ADAPTER *prAdapter)
{
P_JOIN_INFO_T prJoinInfo;
struct STA_RECORD *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 struct ADAPTER *prAdapter)
{
P_JOIN_INFO_T prJoinInfo;
struct BSS_DESC *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 struct ADAPTER *prAdapter)
{
/* P_JOIN_INFO_T prJoinInfo = &prAdapter->rJoinInfo; */
struct BSS_INFO *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 struct ADAPTER *prAdapter)
{
P_JOIN_INFO_T prJoinInfo;
struct BSS_DESC *prBssDesc;
P_PEER_BSS_INFO_T prPeerBssInfo;
struct BSS_INFO *prBssInfo;
struct CONNECTION_SETTINGS *prConnSettings;
struct STA_RECORD *prStaRec;
struct TX_CTRL *prTxCtrl;
#if CFG_SUPPORT_802_11D
struct IE_COUNTRY *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 */
/* Our BSS's PHY_TYPE is ERP now. */
if ((prBssInfo->ePhyType == PHY_TYPE_ERP_INDEX) &&
(prBssDesc->fgIsERPPresent)) {
prBssInfo->fgIsERPPresent = TRUE;
/* Save the ERP for later check */
prBssInfo->ucERP = prBssDesc->ucERP;
} 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) {
struct 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 */
/* AP support Short Slot Time */
prBssInfo->fgUseShortSlotTime =
prPeerBssInfo->fgUseShortSlotTime;
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) {
uint16_t 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,
(uint8_t) TXQ_DATA_MASK, (uint8_t) 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, (void *) NULL, 0);
} /* end of joinComplete() */
#endif