Beispiel #1
0
VOID
WPS_CopyRxEAPPacket(
	IN	PADAPTER	Adapter,
	IN	PRT_RFD		pRfd
	)
{
	PSIMPLE_CONFIG_T	pSimpleConfig = GET_SIMPLE_CONFIG(&(GetDefaultAdapter(Adapter)->MgntInfo));
	pu1Byte 				RecieveBufPtrt,RfdBufferPtr;
	
	pu1Byte BufferPtr = (pu1Byte)&(pRfd->PacketLength );
	RT_TRACE(COMP_WPS, DBG_LOUD, ("In WPS Copy EAP Packet\n"));
	pRfd->PacketLength -= 18;//18 is the length we don't want
	PlatformFillMemory(pSimpleConfig->RecieveBuf, 1500, 0);
	PlatformMoveMemory(pSimpleConfig->RecieveBuf,BufferPtr, 2);
	RecieveBufPtrt = (pu1Byte)pSimpleConfig->RecieveBuf+2;
	RfdBufferPtr	 =pRfd->Buffer.VirtualAddress+4; //skip Version DATA TYPE fream control
	PlatformMoveMemory(RecieveBufPtrt,RfdBufferPtr, ETHERNET_ADDRESS_LENGTH*2);
	RecieveBufPtrt += (ETHERNET_ADDRESS_LENGTH*2);
	RfdBufferPtr	 += (ETHERNET_ADDRESS_LENGTH*2);
	RfdBufferPtr	 += 14;//Skip LLC Until 888E
	if(pRfd->Buffer.VirtualAddress[0] & 0x80) {//Skip QoS
		RfdBufferPtr	 += 2;
		RT_TRACE(COMP_WPS, DBG_LOUD, ("The Data is %x and QoS is Set\n",RfdBufferPtr[0]));
		pRfd->PacketLength -= 2;//18 is the length we don't want
		PlatformMoveMemory(pSimpleConfig->RecieveBuf,BufferPtr, 2);
		
	}
	PlatformMoveMemory(RecieveBufPtrt,RfdBufferPtr,(pRfd->PacketLength -(ETHERNET_ADDRESS_LENGTH*2)) );
	pSimpleConfig->bRecievePacket = TRUE;
	pSimpleConfig->RecieveLength = (pRfd->PacketLength+2);// 2 is the packet length we reserved for report to lib
	RT_PRINT_DATA(COMP_WPS, DBG_LOUD, "EAP Packet Content:", pSimpleConfig->RecieveBuf, pRfd->PacketLength);
			
}
Beispiel #2
0
static	void	
cmpk_Handle_Tx_Feedback(
	_adapter		*pAdapter, 
	u8			*pMsg)
{
#if 0
	PMGNT_INFO		pMgntInfo = &(pAdapter->MgntInfo);
	CMPK_TXFB_T		rx_tx_fb;	/* */	
	
	pAdapter->TxStats.NumTxFeedBack++;
	
	/* 0. Display received message. */
	//cmpk_Display_Message(CMPK_RX_TX_FB_SIZE, pMsg);
	
	/* 1. Extract TX feedback info from RFD to temp structure buffer. */
	/* It seems that FW use big endian(MIPS) and DRV use little endian in 
	   windows OS. So we have to read the content byte by byte or transfer 
	   endian type before copy the message copy. */	
	/* 2007/07/05 MH Use pointer to transfer structure memory. */
	//memcpy((UINT8 *)&rx_tx_fb, pMsg, sizeof(CMPK_TXFB_T));
	PlatformMoveMemory((PVOID)&rx_tx_fb, pMsg, sizeof(CMPK_TXFB_T));
	/* 2. Use tx feedback info to count TX statistics. */
	cmpk_CountTxStatistic(pAdapter, &rx_tx_fb);
	/* 2007/01/17 MH Comment previous method for TX statistic function. */
	/* Collect info TX feedback packet to fill TCB. */	
	/* We can not know the packet length and transmit type: broadcast or uni
	   or multicast. */	
	//CountTxStatistics( pAdapter, &tcb );
#endif	
}	/* cmpk_Handle_Tx_Feedback */
//
//	Description:
//		Retrive one log data from specified pool
//
//	Assumption:
//		pDstLogData	must pointer to a buffer with enough space, 
//		e.g. sizeof(DRV_LOG_DATA_IMP_T).
//
BOOLEAN
RemoveDrvLog(
	IN	PADAPTER		pAdapter,
	IN	DRV_LOG_TYPE_E	eLogType,
	OUT	PDRV_LOG_DATA_T	pDstLogData
	)
{
	PDRV_LOG_POOL_T pLogPool = GET_DRV_LOG_POOL(pAdapter, eLogType); 

	PlatformAcquireSpinLock(pAdapter, RT_LOG_SPINLOCK);
	if(pLogPool->LogCountUsed == 0)
	{
		PlatformReleaseSpinLock(pAdapter, RT_LOG_SPINLOCK);
		return FALSE;
	}
	else
	{
		PDRV_LOG_DATA_IMP_T pSrcLogData = pLogPool->pLogDataRing + pLogPool->LogStartIndex;
		u4Byte MaxLogCount = ((u4Byte)1 << g_LogTypes[eLogType].MaxLogCountPwr);
		u4Byte LogCountMask = MaxLogCount - 1;

		PlatformMoveMemory(
			pDstLogData, 
			pSrcLogData, 
			sizeof(DRV_LOG_DATA_T) + pSrcLogData->BufferLenUsed);
		pLogPool->LogStartIndex = (pLogPool->LogStartIndex + 1) & LogCountMask;
		pLogPool->LogCountUsed--;

		PlatformReleaseSpinLock(pAdapter, RT_LOG_SPINLOCK);
		return TRUE;
	}
}
RT_STATUS
P2PSvc_UpdateParam(
	IN  PP2PSVC_OBJ_LIST					pObjList,
	IN  u4Byte								paramId,
	IN  u4Byte								fromIdx,
	IN  u4Byte								bufLen,
	IN  PVOID								pBuf
	)
{
	RT_STATUS								rtStatus = RT_STATUS_SUCCESS;
	PRT_OBJECT_HEADER						pObj = NULL;

	P2PSVC_CHECK_NULL(pObjList);

	do
	{
		if(NULL == (pObj = P2PSvc_GetParam(pObjList, paramId, fromIdx)))
		{
			rtStatus = RT_STATUS_INVALID_DATA;
			break;
		}

		if(pObj->Length != bufLen)
		{
			rtStatus = RT_STATUS_INVALID_DATA;
			break;
		}
		
		PlatformMoveMemory(pObj->Value, pBuf, bufLen);
		
	}while(FALSE);

	return rtStatus;
}
VOID
PacketAppendData(
	IN	POCTET_STRING	packet,
	IN	OCTET_STRING	data
	)
{
	pu1Byte buf = packet->Octet + packet->Length;

	PlatformMoveMemory( buf, data.Octet, data.Length);

	packet->Length = packet->Length + data.Length;
}
Beispiel #6
0
/*-----------------------------------------------------------------------------
 * Function:	cmpk_Handle_Tx_Status()
 *
 * Overview:	Firmware add a new tx feedback status to reduce rx command 
 *				packet buffer operation load.
 *
 * Input:		NONE
 *
 * Output:		NONE
 *
 * Return:		NONE
 *
 * Revised History:
 *	When		Who		Remark
 *	09/11/2007	MHC		Create Version 0.  
 *
 *---------------------------------------------------------------------------*/
static	void	
cmpk_Handle_Tx_Status(
	_adapter		*pAdapter, 
	u8			*pMsg)
{	
#if 0
	CMPK_TX_STATUS_T	rx_tx_sts;	/* */
	
	PlatformMoveMemory((PVOID)&rx_tx_sts, pMsg, sizeof(CMPK_TX_STATUS_T));
	/* 2. Use tx feedback info to count TX statistics. */
	cmpk_CountTxStatus(pAdapter, &rx_tx_sts);
#endif
}	/* cmpk_Handle_Tx_Status */
VOID
ODM_MoveMemory(	
	IN 	PDM_ODM_T	pDM_Odm,
	OUT PVOID		pDest,
	IN  PVOID		pSrc,
	IN  u4Byte		Length
	)
{
#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL))
	memcpy(pDest, pSrc, Length);
#elif (DM_ODM_SUPPORT_TYPE & ODM_CE )	
	_rtw_memcpy(pDest, pSrc, Length);
#elif(DM_ODM_SUPPORT_TYPE & ODM_WIN)
	PlatformMoveMemory(pDest, pSrc, Length);
#endif	
}
VOID
PacketMakeElement(
	IN	POCTET_STRING	packet,
	IN	ELEMENT_ID		ID,
	IN	OCTET_STRING	info
	)
{
	pu1Byte buf = packet->Octet + packet->Length;

	buf[0] = (u1Byte)ID;
	buf[1] = (u1Byte)info.Length;

	if(info.Length > 0)
	{
		PlatformMoveMemory( buf + 2, info.Octet, info.Length);
	}

	packet->Length += info.Length + 2;
}
Beispiel #9
0
RT_STATUS
WPS_QueryRxEAPPacket(
	IN	PADAPTER		Adapter,
	IN	pu1Byte			InformationBuffer,
	IN	u4Byte			InformationBufferLength,
	OUT	pu4Byte			BytesWritten,
	OUT	pu4Byte			BytesNeeded
	)
{
	PSIMPLE_CONFIG_T 	pSimpleConfig = GET_SIMPLE_CONFIG(&(Adapter->MgntInfo));
	RT_STATUS			status = RT_STATUS_SUCCESS;
	
	RT_TRACE(COMP_WPS, DBG_LOUD, ("WPS Check Recieve Buffer:\n"));
	if( InformationBufferLength < pSimpleConfig->RecieveLength)
	{
		*BytesNeeded = pSimpleConfig->RecieveLength;
		*BytesWritten = 0;
		return RT_STATUS_INVALID_CONTEXT;
	}
	
	if(!pSimpleConfig->bRecievePacket)
	{
		*BytesNeeded =0;
		//*BytesWritten = 0;
	}
	else
	{
		RT_PRINT_DATA(COMP_WPS, DBG_LOUD, "Driver report Info Buffer before copy:", InformationBuffer, 16);
		InformationBufferLength = pSimpleConfig->RecieveLength;//Set For packet length
		PlatformMoveMemory( InformationBuffer, pSimpleConfig->RecieveBuf, pSimpleConfig->RecieveLength);
		RT_PRINT_DATA(COMP_WPS, DBG_LOUD, "Driver report Info Buffer After copy:", InformationBuffer, 16);
		*BytesWritten = pSimpleConfig->RecieveLength;
		pSimpleConfig->bRecievePacket = FALSE;
		RT_PRINT_DATA(COMP_WPS, DBG_LOUD, "Driver report EAP Packet Content:", pSimpleConfig->RecieveBuf, pSimpleConfig->RecieveLength);
	}
	return status;
}
//
//	Description:
//		Add one log to corresponding pool.
//
VOID
AddDrvLog(
	IN	PADAPTER		pAdapter,
	IN	DRV_LOG_ID_E	eLogId,
	IN	pu1Byte			pBuffer,
	IN	u4Byte			BufferLen	
	)
{
	DRV_LOG_TYPE_E eLogType = (DRV_LOG_TYPE_E)g_LogAttributes[eLogId].Type;
	PDRV_LOG_POOL_T pLogPool = GET_DRV_LOG_POOL(pAdapter, eLogType); 
	u8Byte CurrTime = PlatformGetCurrentTime();
	u4Byte MaxLogCount = ((u4Byte)1 << g_LogTypes[eLogType].MaxLogCountPwr);
	u4Byte LogCountMask = MaxLogCount - 1;
	PDRV_LOG_DATA_IMP_T pLogData;

	PlatformAcquireSpinLock(pAdapter, RT_LOG_SPINLOCK);

	if( pLogPool->LogCountUsed < MaxLogCount )
	{
		pLogData = pLogPool->pLogDataRing + 
					( (pLogPool->LogStartIndex + pLogPool->LogCountUsed) & LogCountMask );
		pLogPool->LogCountUsed++;
	}
	else
	{ // full! age out oldest one.
		pLogData = pLogPool->pLogDataRing + pLogPool->LogStartIndex;
		pLogPool->LogStartIndex = (pLogPool->LogStartIndex + 1) & LogCountMask;
	}

	pLogData->Id = eLogId;
	pLogData->BufferLenUsed = (BufferLen <= MAX_LOG_BUFFER_LEN) ? BufferLen: MAX_LOG_BUFFER_LEN;
	PlatformMoveMemory(pLogData->Buffer, pBuffer, pLogData->BufferLenUsed);
	pLogData->TimeStampLow = (u4Byte)CurrTime;
	pLogData->TimeStampHigh = (u4Byte)(CurrTime >> 32);

	PlatformReleaseSpinLock(pAdapter, RT_LOG_SPINLOCK);
}
// Description: According received EAPOL-key, enter the next state.
// Output: void
// Modify: Annie, 2005-07-02
//		Discard using condition pKeyMgnt->bPTKInstalled.
//		Instead, I add a macro KeyMgntStateIsWaitingEAPOLKey to check the state.
void 
Authenticator_OnEAPOLKeyRecvd(
	IN	PADAPTER				Adapter,
	IN	PAUTH_PKEY_MGNT_TAG	pKeyMgnt,
	IN	OCTET_STRING			pdu
	)
{
	PMGNT_INFO			pMgntInfo = &Adapter->MgntInfo;
	PAUTH_GLOBAL_KEY_TAG	pGlInfo = &pMgntInfo->globalKeyInfo;
	PRT_WLAN_STA		pEntry = pKeyMgnt->pWLanSTA;
	pu1Byte				pSTA_addr = Frame_pSaddr(pdu);
	pu1Byte				pAP_addr = Frame_pDaddr(pdu);
	PEAPOL_KEY_STRUCT	eapol_key_recvd;
	OCTET_STRING		SNonce;
	OCTET_STRING		RSNIE;
	MsgType				msg_type = type_unknow;

	RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("===> Authenticator_OnEAPOLKeyRecvd()\n") );

	pKeyMgnt->EvntID = ASMEID_EAPOLKeyRecvd;

	FillOctetString(pGlInfo->EapolKeyMsgRecvd,								\
		pGlInfo->EAPOLMsgRecvd.Octet+LIB1X_EAPOL_HDRLEN,					\
		pGlInfo->EAPOLMsgRecvd.Length-LIB1X_EAPOL_HDRLEN );				\

	eapol_key_recvd = (PEAPOL_KEY_STRUCT)pGlInfo->EapolKeyMsgRecvd.Octet;

	//PRINT_DATA( ("EapolKeyMsgRecvd: "), pGlInfo->EapolKeyMsgRecvd.Octet, pGlInfo->EapolKeyMsgRecvd.Length);
	RSNIE.Octet = NULL;
	RSNIE.Length = 0;
	
	// Get the message number.
	if( Message_KeyType(pGlInfo->EapolKeyMsgRecvd) == type_Pairwise )
	{
		if( (Message_Error(pGlInfo->EapolKeyMsgRecvd) == 1) &&
			(Message_Request(pGlInfo->EapolKeyMsgRecvd) == 1))
		{			
			//Enter integrity failure state...			
			Authenticator_StateINTEGRITYFAILURE(Adapter, pEntry);	
		}

		if( (eapol_key_recvd->key_info[0]==0x01 && eapol_key_recvd->key_info[1]==0x09) ||
		    ( eapol_key_recvd->key_info[0]==0x01 && eapol_key_recvd->key_info[1]==0x0a) ||
		    ( eapol_key_recvd->key_info[0]==0x03 && eapol_key_recvd->key_info[1]==0x0a) ||
		    ( eapol_key_recvd->key_info[0]==0x03 && eapol_key_recvd->key_info[1]==0x09) )
		{
			if( pMgntInfo->SecurityInfo.SecLvl == RT_SEC_LVL_WPA)
			RSNIE = EAPOLkeyGetRSNIE( pGlInfo->EapolKeyMsgRecvd, EID_Vendor );
			else if( pMgntInfo->SecurityInfo.SecLvl == RT_SEC_LVL_WPA2)
				RSNIE = EAPOLkeyGetRSNIE( pGlInfo->EapolKeyMsgRecvd, EID_WPA2 );
				
			if( RSNIE.Length != 0 )
				msg_type = type_4way2nd;		// with RSNIE: msg 2 (159 or 161)
			else
				msg_type = type_4way4th;		// msg 4 (135)
		}
		else
		{
			RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("unknow pairwise EAPOL-key: info=0x%X-0x%X\n", eapol_key_recvd->key_info[0], eapol_key_recvd->key_info[1]) );
		}
	}
	else
	{
		// [AnnieNote] Windows zero-config may send 2-way message as 03-01.
		//
		//if( eapol_key_recvd->key_info[0]==0x03 && eapol_key_recvd->key_info[1]==0x11 )	// if group key index is fixed 1, key information is 03-11.
		//	msg_type = type_2way2nd;			// group key msg2 (155)
		//else
		//	RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("unknow group EAPOL-key: info=0x%X-0x%X\n", eapol_key_recvd->key_info[0], eapol_key_recvd->key_info[1]) );
		
		msg_type = type_2way2nd;
	}

	// Check state.
	if( KeyMgntStateIsWaitingEAPOLKey(pKeyMgnt) )
	{

		if( 	(pKeyMgnt->PrState==ASMPS_PTKSTART && msg_type==type_4way2nd ) ||
			( pKeyMgnt->PrState==ASMPS_PTKINITNEGOTIATING && msg_type==type_4way2nd ))
		{
			RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("Recvd 4-way message 2\n"));
			pKeyMgnt->TimeoutCtr = 0;

			//  AnnieTODO: if (1)k is pairwise and (2)MICVerified , then enter ASMPS_PTKINITNEGOTIATING state
			//  TODO: MIC Verify
			SNonce = Message_KeyNonce( pGlInfo->EapolKeyMsgRecvd );
			CopyMem( pKeyMgnt->SNonce, SNonce.Octet, KEY_NONCE_LEN );

			
			CalcPTK( pAP_addr, pSTA_addr, pKeyMgnt->ANonce, pKeyMgnt->SNonce,
					 pGlInfo->PMK, PMK_LEN, pKeyMgnt->PTK_update, PTK_LEN );

			if(!CheckEapolMIC(Adapter , pGlInfo->EAPOLMsgRecvd , pKeyMgnt->PTK_update , KEY_MIC_LEN ))
			{
				SendDeauthentication( Adapter, pSTA_addr , mic_failure );
				PlatformStallExecution(100);
				RT_TRACE_F(COMP_AP, DBG_TRACE, ("AsocEntry_RemoveStation\n"));
				
				AsocEntry_RemoveStation( Adapter , pSTA_addr);
				RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("MIC erroe\n"));
				return;
			 }


			Authenticator_StatePTKINITNEGOTIATING(Adapter, pEntry);
		}
		else if( pKeyMgnt->PrState==ASMPS_PTKINITNEGOTIATING && msg_type==type_4way4th )
		{
			RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("Recvd 4-way message 4\n"));
			pKeyMgnt->TimeoutCtr = 0;

			// if (1)k is pairwise and (2)MICVerified , then enter ASMPS_PTKINITDONE state
			if(!CheckEapolMIC(Adapter , pGlInfo->EAPOLMsgRecvd , pKeyMgnt->PTK_update , KEY_MIC_LEN ))
			{
				SendDeauthentication( Adapter, pSTA_addr , mic_failure );
				PlatformStallExecution(100);
				RT_TRACE_F(COMP_AP, DBG_TRACE, ("AsocEntry_RemoveStation case 2\n"));
				
				AsocEntry_RemoveStation( Adapter , pSTA_addr);
				RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("MIC erroe\n"));
				return;
			 }

			PlatformMoveMemory(&pEntry->perSTAKeyInfo.RxIV, &((PEAPOL_KEY_STRUCT)eapol_key_recvd)->key_rsc[0], 6);
			pEntry->perSTAKeyInfo.RxIV &= UINT64_C(0x0000ffffffffffff);
			//RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("pEntry->perSTAKeyInfo.RxIV = 0x%16"i64fmt"x", pEntry->perSTAKeyInfo.RxIV));

			Authenticator_StatePTKINITDONE(Adapter, pEntry);		
		}
		else if(  pKeyMgnt->GrState == ASMGS_REKEYNEGOTIATING && msg_type==type_2way2nd )
		{
			RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("Recvd 2-way message 2\n"));
			pKeyMgnt->TimeoutCtr = 0;

			//  if (1)k is group and (2)MICVerified , then enter ASMGS_REKEYESTABLISHED state
			// 2012/01/17 CCW If 4-way check is ok, we need not to check 2-way again.
			/*
			if(!CheckEapolMIC(Adapter , pGlInfo->EAPOLMsgRecvd , pKeyMgnt->PTK_update , KEY_MIC_LEN ))
			{
				SendDeauthentication( Adapter, pSTA_addr , mic_failure );
				PlatformStallExecution(100);
				AsocEntry_RemoveStation( Adapter , pSTA_addr);
				RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("MIC erroe\n"));
				return;
			}
			*/
			Authenticator_StateREKEYESTABLISHED(Adapter, pEntry);
		}
		else
		{
			RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("Authenticator_OnEAPOLKeyRecvd(): Unexpected case: PrState=%d, GrState=%d, msg_type=%d\n",
											pKeyMgnt->PrState, pKeyMgnt->GrState, msg_type ) );
		}

	}
	else
	{
		RT_TRACE(COMP_AUTHENTICATOR, DBG_LOUD, ("Authenticator_OnEAPOLKeyRecvd(): Unexpected State!!\n"));
		RT_TRACE(COMP_AUTHENTICATOR, DBG_LOUD, ("--- TimeoutCounter:%d, PairwiseKeyState:%d, GroupKeyState:%d ---\n", pKeyMgnt->TimeoutCtr, pKeyMgnt->PrState, pKeyMgnt->GrState));
	}

	RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("<=== Authenticator_OnEAPOLKeyRecvd()\n") );

}
Beispiel #12
0
VOID
WPS_AppendElement(
	IN	PADAPTER			Adapter,
	IN	POCTET_STRING		posFrame,
	IN	BOOLEAN				bCheckFrag,
	IN	WPS_INFO_OPCODE	frameType
	)
{
	PSIMPLE_CONFIG_T	pSimpleConfig = GET_SIMPLE_CONFIG(&(GetDefaultAdapter(Adapter)->MgntInfo));
	OCTET_STRING		SimpleConfigInfo;	

	FunctionIn(COMP_WPS);
	#if 0
	if(bCheckFrag)
	{
		// WPS 2.0 Support IE Fragment	for Testbed function
		if(pSimpleConfig->bFragmentIE && pSimpleConfig->IELen <= MAX_SIMPLE_CONFIG_IE_LEN)
		{
			u1Byte tempBuf[MAX_SIMPLE_CONFIG_IE_LEN];
			pu1Byte currPtr;
			pu1Byte currPtrAftOui;
			RT_TRACE(COMP_WPS,DBG_LOUD,("ConstructProbeRequest: in Fragment IE\n"));
			PlatformZeroMemory(tempBuf, MAX_SIMPLE_CONFIG_IE_LEN);
			//Copy the OUI
			currPtr = pSimpleConfig->IEBuf;
			//Tesplan to copy the first octet in the first fragment
			PlatformMoveMemory(tempBuf, currPtr, SIZE_OUI + SIZE_OUI_TYPE);
			currPtr += (SIZE_OUI + SIZE_OUI_TYPE); 
			currPtrAftOui = &tempBuf[SIZE_OUI + SIZE_OUI_TYPE];

			// the first octet
			PlatformMoveMemory(currPtrAftOui, currPtr, 1);
			currPtr += 1;
			FillOctetString(SimpleConfigInfo,tempBuf,(SIZE_OUI + SIZE_OUI_TYPE +1));
			PacketMakeElement( posFrame, EID_Vendor, SimpleConfigInfo);
						
			// the rest octet			
			PlatformZeroMemory(currPtrAftOui, 1);
			PlatformMoveMemory(currPtrAftOui, currPtr, (pSimpleConfig->IELen-(SIZE_OUI + SIZE_OUI_TYPE)-1) );

			FillOctetString(SimpleConfigInfo,tempBuf,(pSimpleConfig->IELen-1));
			PacketMakeElement( posFrame, EID_Vendor, SimpleConfigInfo);

		}
		else if(pSimpleConfig->IELen > MAX_SIMPLE_CONFIG_IE_LEN)
		{
			u1Byte tempBuf[MAX_SIMPLE_CONFIG_IE_LEN];
			pu1Byte currPtr;
			pu1Byte currPtrAftOui;
			PlatformZeroMemory(tempBuf, MAX_SIMPLE_CONFIG_IE_LEN);
			//Copy the OUI
			currPtr = pSimpleConfig->IEBuf;
			//Tesplan to copy the first octet in the first fragment
			PlatformMoveMemory(tempBuf, currPtr, SIZE_OUI + SIZE_OUI_TYPE);
			currPtr += (SIZE_OUI + SIZE_OUI_TYPE); 
			currPtrAftOui = &tempBuf[SIZE_OUI + SIZE_OUI_TYPE];

			// the first fragment
			PlatformMoveMemory(currPtrAftOui, currPtr, (MAX_SIMPLE_CONFIG_IE_LEN - (SIZE_OUI + SIZE_OUI_TYPE)));
			currPtr += (MAX_SIMPLE_CONFIG_IE_LEN - (SIZE_OUI + SIZE_OUI_TYPE));
			FillOctetString(SimpleConfigInfo,tempBuf,(MAX_SIMPLE_CONFIG_IE_LEN - (SIZE_OUI + SIZE_OUI_TYPE)));
			PacketMakeElement( posFrame, EID_Vendor, SimpleConfigInfo);
						
			// the rest octet			
			PlatformZeroMemory(currPtrAftOui, (MAX_SIMPLE_CONFIG_IE_LEN - (SIZE_OUI + SIZE_OUI_TYPE)));
			PlatformMoveMemory(currPtrAftOui, currPtr, (pSimpleConfig->IELen-MAX_SIMPLE_CONFIG_IE_LEN) );

			FillOctetString(SimpleConfigInfo,tempBuf,(pSimpleConfig->IELen-MAX_SIMPLE_CONFIG_IE_LEN));
			PacketMakeElement( posFrame, EID_Vendor, SimpleConfigInfo);
			
		}
		else
		{
			FillOctetString(SimpleConfigInfo, pSimpleConfig->IEBuf, pSimpleConfig->IELen);
			PacketMakeElement( posFrame, EID_Vendor, SimpleConfigInfo);
		}
	}
	else
	#endif
	{
		if(((pSimpleConfig->WpsIeVersion < SUPPORT_WPS_INFO_VERSION) || (wps_IsWPSIEReady(Adapter) == FALSE)) && pSimpleConfig->IELen > 0)
		{
			FillOctetString(SimpleConfigInfo, pSimpleConfig->IEBuf, pSimpleConfig->IELen);
			PacketMakeElement( posFrame, EID_Vendor, SimpleConfigInfo);
		}
		else if(pSimpleConfig->WpsIeVersion == SUPPORT_WPS_INFO_VERSION)
		{
			switch(frameType)
			{
				case WPS_INFO_ASOCREQ_IE:
				{
					FillOctetString(SimpleConfigInfo, pSimpleConfig->ieAsocReqBuf, pSimpleConfig->ieAsocReqLen);
					if(pSimpleConfig->ieAsocReqLen > 0)
						PacketAppendData(posFrame, SimpleConfigInfo);
				}
				break;

				case WPS_INFO_ASOCRSP_IE:
				{
					FillOctetString(SimpleConfigInfo, pSimpleConfig->ieAsocRspBuf, pSimpleConfig->ieAsocRspLen);
					if(pSimpleConfig->ieAsocRspLen > 0)
						PacketAppendData(posFrame, SimpleConfigInfo);
				}
				break;
				
				case WPS_INFO_PROBEREQ_IE:
				{
					FillOctetString(SimpleConfigInfo, pSimpleConfig->ieProbeReqBuf, pSimpleConfig->ieProbeReqLen);
					if(pSimpleConfig->ieProbeReqLen > 0)
						PacketAppendData(posFrame, SimpleConfigInfo);
				}
				break;

				case WPS_INFO_PROBERSP_IE:
				{
					FillOctetString(SimpleConfigInfo, pSimpleConfig->ieProbeRspBuf, pSimpleConfig->ieProbeRspLen);
					if(pSimpleConfig->ieProbeRspLen > 0)
						PacketAppendData(posFrame, SimpleConfigInfo);
				}
				break;

				default: //for MacOS warning.
					break;

			}
		}
	}
}
Beispiel #13
0
BOOLEAN
ODM_PathDiversityBeforeLink92C(
	//IN	PADAPTER	Adapter
	IN		PDM_ODM_T		pDM_Odm
	)
{
#if (RT_MEM_SIZE_LEVEL != RT_MEM_SIZE_MINIMUM)
	PADAPTER		Adapter = pDM_Odm->Adapter;
	HAL_DATA_TYPE*	pHalData = NULL;
	PMGNT_INFO		pMgntInfo = NULL;
	//pSWAT_T		pDM_SWAT_Table = &Adapter->DM_SWAT_Table;
	pPD_T			pDM_PDTable = NULL;

	s1Byte			Score = 0;
	PRT_WLAN_BSS	pTmpBssDesc;
	PRT_WLAN_BSS	pTestBssDesc;

	u1Byte			target_chnl = 0;
	u2Byte			index;

	if (pDM_Odm->Adapter == NULL)  //For BSOD when plug/unplug fast.  //By YJ,120413
	{	// The ODM structure is not initialized.
		return FALSE;
	}
	pHalData = GET_HAL_DATA(Adapter);
	pMgntInfo = &Adapter->MgntInfo;
	pDM_PDTable = &Adapter->DM_PDTable;
	
	// Condition that does not need to use path diversity.
	if((!(pHalData->CVID_Version==VERSION_1_BEFORE_8703B && IS_92C_SERIAL(pHalData->VersionID))) || (pHalData->PathDivCfg!=1) || pMgntInfo->AntennaTest )
	{
		RT_TRACE(COMP_INIT, DBG_LOUD, 
				("ODM_PathDiversityBeforeLink92C(): No PathDiv Mechanism before link.\n"));
		return FALSE;
	}

	// Since driver is going to set BB register, it shall check if there is another thread controlling BB/RF.
	PlatformAcquireSpinLock(Adapter, RT_RF_STATE_SPINLOCK);
	if(pHalData->eRFPowerState!=eRfOn || pMgntInfo->RFChangeInProgress || pMgntInfo->bMediaConnect)
	{
		PlatformReleaseSpinLock(Adapter, RT_RF_STATE_SPINLOCK);
	
		RT_TRACE(COMP_INIT, DBG_LOUD, 
				("ODM_PathDiversityBeforeLink92C(): RFChangeInProgress(%x), eRFPowerState(%x)\n", 
				pMgntInfo->RFChangeInProgress,
				pHalData->eRFPowerState));
	
		//pDM_SWAT_Table->SWAS_NoLink_State = 0;
		pDM_PDTable->PathDiv_NoLink_State = 0;
		
		return FALSE;
	}
	else
	{
		PlatformReleaseSpinLock(Adapter, RT_RF_STATE_SPINLOCK);
	}

	//1 Run AntDiv mechanism "Before Link" part.
	//if(pDM_SWAT_Table->SWAS_NoLink_State == 0)
	if(pDM_PDTable->PathDiv_NoLink_State == 0)
	{
		//1 Prepare to do Scan again to check current antenna state.

		// Set check state to next step.
		//pDM_SWAT_Table->SWAS_NoLink_State = 1;
		pDM_PDTable->PathDiv_NoLink_State = 1;
	
		// Copy Current Scan list.
		Adapter->MgntInfo.tmpNumBssDesc = pMgntInfo->NumBssDesc;
		PlatformMoveMemory((PVOID)Adapter->MgntInfo.tmpbssDesc, (PVOID)pMgntInfo->bssDesc, sizeof(RT_WLAN_BSS)*MAX_BSS_DESC);

		// Switch Antenna to another one.
		if(pDM_PDTable->DefaultRespPath == 0)
		{
			PHY_SetBBReg(Adapter, rCCK0_AFESetting  , 0x0F000000, 0x05); // TRX path = PathB
			odm_SetRespPath_92C(Adapter, 1);
			pDM_PDTable->OFDMTXPath = 0xFFFFFFFF;
			pDM_PDTable->CCKTXPath = 0xFFFFFFFF;
		}
		else
		{
			PHY_SetBBReg(Adapter, rCCK0_AFESetting  , 0x0F000000, 0x00); // TRX path = PathA
			odm_SetRespPath_92C(Adapter, 0);
			pDM_PDTable->OFDMTXPath = 0x0;
			pDM_PDTable->CCKTXPath = 0x0;
		}
#if 0	

		pDM_SWAT_Table->PreAntenna = pDM_SWAT_Table->CurAntenna;
		pDM_SWAT_Table->CurAntenna = (pDM_SWAT_Table->CurAntenna==Antenna_A)?Antenna_B:Antenna_A;
		
		RT_TRACE(COMP_INIT, DBG_LOUD, 
			("ODM_SwAntDivCheckBeforeLink: Change to Ant(%s) for testing.\n", (pDM_SWAT_Table->CurAntenna==Antenna_A)?"A":"B"));
		//PHY_SetBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, 0x300, DM_SWAT_Table.CurAntenna);
		pDM_SWAT_Table->SWAS_NoLink_BK_Reg860 = ((pDM_SWAT_Table->SWAS_NoLink_BK_Reg860 & 0xfffffcff) | (pDM_SWAT_Table->CurAntenna<<8));
		PHY_SetBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, bMaskDWord, pDM_SWAT_Table->SWAS_NoLink_BK_Reg860);
#endif

		// Go back to scan function again.
		RT_TRACE(COMP_INIT, DBG_LOUD, ("ODM_PathDiversityBeforeLink92C: Scan one more time\n"));
		pMgntInfo->ScanStep=0;
		target_chnl = odm_SwAntDivSelectScanChnl(Adapter);
		odm_SwAntDivConstructScanChnl(Adapter, target_chnl);
		PlatformSetTimer(Adapter, &pMgntInfo->ScanTimer, 5);

		return TRUE;
	}
	else
	{
		//1 ScanComple() is called after antenna swiched.
		//1 Check scan result and determine which antenna is going
		//1 to be used.

		for(index=0; index<Adapter->MgntInfo.tmpNumBssDesc; index++)
		{
			pTmpBssDesc = &(Adapter->MgntInfo.tmpbssDesc[index]);
			pTestBssDesc = &(pMgntInfo->bssDesc[index]);

			if(PlatformCompareMemory(pTestBssDesc->bdBssIdBuf, pTmpBssDesc->bdBssIdBuf, 6)!=0)
			{
				RT_TRACE(COMP_INIT, DBG_LOUD, ("ODM_PathDiversityBeforeLink92C(): ERROR!! This shall not happen.\n"));
				continue;
			}

			if(pTmpBssDesc->RecvSignalPower > pTestBssDesc->RecvSignalPower)
			{
				RT_TRACE(COMP_INIT, DBG_LOUD, ("ODM_PathDiversityBeforeLink92C: Compare scan entry: Score++\n"));
				RT_PRINT_STR(COMP_INIT, DBG_LOUD, "SSID: ", pTestBssDesc->bdSsIdBuf, pTestBssDesc->bdSsIdLen);
				RT_TRACE(COMP_INIT, DBG_LOUD, ("Original: %d, Test: %d\n", pTmpBssDesc->RecvSignalPower, pTestBssDesc->RecvSignalPower));
			
				Score++;
				PlatformMoveMemory(pTestBssDesc, pTmpBssDesc, sizeof(RT_WLAN_BSS));
			}
			else if(pTmpBssDesc->RecvSignalPower < pTestBssDesc->RecvSignalPower)
			{
				RT_TRACE(COMP_INIT, DBG_LOUD, ("ODM_PathDiversityBeforeLink92C: Compare scan entry: Score--\n"));
				RT_PRINT_STR(COMP_INIT, DBG_LOUD, "SSID: ", pTestBssDesc->bdSsIdBuf, pTestBssDesc->bdSsIdLen);
				RT_TRACE(COMP_INIT, DBG_LOUD, ("Original: %d, Test: %d\n", pTmpBssDesc->RecvSignalPower, pTestBssDesc->RecvSignalPower));
				Score--;
			}

		}

		if(pMgntInfo->NumBssDesc!=0 && Score<=0)
		{
			RT_TRACE(COMP_INIT, DBG_LOUD,
				("ODM_PathDiversityBeforeLink92C(): DefaultRespPath=%d\n", pDM_PDTable->DefaultRespPath));

			//pDM_SWAT_Table->PreAntenna = pDM_SWAT_Table->CurAntenna;
		}
		else
		{
			RT_TRACE(COMP_INIT, DBG_LOUD, 
				("ODM_PathDiversityBeforeLink92C(): DefaultRespPath=%d\n", pDM_PDTable->DefaultRespPath));

			if(pDM_PDTable->DefaultRespPath == 0)
			{
				pDM_PDTable->OFDMTXPath = 0xFFFFFFFF;
				pDM_PDTable->CCKTXPath = 0xFFFFFFFF;
				odm_SetRespPath_92C(Adapter, 1);
			}
			else
			{
				pDM_PDTable->OFDMTXPath = 0x0;
				pDM_PDTable->CCKTXPath = 0x0;
				odm_SetRespPath_92C(Adapter, 0);
			}
			PHY_SetBBReg(Adapter, rCCK0_AFESetting  , 0x0F000000, 0x01); // RX path = PathAB

			//pDM_SWAT_Table->CurAntenna = pDM_SWAT_Table->PreAntenna;

			//PHY_SetBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, 0x300, DM_SWAT_Table.CurAntenna);
			//pDM_SWAT_Table->SWAS_NoLink_BK_Reg860 = ((pDM_SWAT_Table->SWAS_NoLink_BK_Reg860 & 0xfffffcff) | (pDM_SWAT_Table->CurAntenna<<8));
			//PHY_SetBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, bMaskDWord, pDM_SWAT_Table->SWAS_NoLink_BK_Reg860);
		}

		// Check state reset to default and wait for next time.
		//pDM_SWAT_Table->SWAS_NoLink_State = 0;
		pDM_PDTable->PathDiv_NoLink_State = 0;

		return FALSE;
	}
#else
		return	FALSE;
#endif
	
}
PADAPTER
MultiPortFeedPacketToMultipleAdapter(
	PADAPTER	pAdapter,
	PRT_RFD		pRfd
)
{
	// NOTE: --------------------------------------------------------------
	//  If only single adapter is needed, return that adapter.
	// --------------------------------------------------------------------

	PADAPTER pDefaultAdapter = GetDefaultAdapter(pAdapter);
	PMULTIPORT_COMMON_CONTEXT pMultiPortCommon = MultiPortGetCommonContext(pDefaultAdapter);
	PADAPTER pExtAdapter = NULL;
	PRT_RFD pExtRfd = NULL;
	u4Byte i = 0;
	RT_STATUS rtStatus = RT_STATUS_SUCCESS;
	
	// Assertion Check Variable
	u4Byte uCurrentCloneRFDs;
	
	// Target List 
	u4Byte uTargetAdapter = 0;
	PADAPTER TargetList[10];


	// Single MPDU
	OCTET_STRING frame = {NULL, 0};
	FillOctetString(frame, pRfd->Buffer.VirtualAddress, pRfd->PacketLength);

	if(pRfd->Status.bHwError)
	{
		RT_TRACE(COMP_RECV, DBG_TRACE, ("MultiPortFeedPacketToMultipleAdapter(): Return because bHwError is true.\n"));
		return NULL;
	}

	// Information Source: pRfd Status Checking -------------------------------------------------------
	RT_ASSERT(pRfd->Buffer.VirtualAddress != NULL, ("Error: pRfd->Buffer.VirtualAddress is NULL!\n"));
	RT_ASSERT(pRfd->Buffer.Length != 0, ("Error: pRfd->Buffer.Length is 0!\n"));
	RT_ASSERT(pRfd->PacketLength <= pRfd->Buffer.Length, ("Error: Packet Too Long!\n"));
	// ------------------------------------------------------------------------------------------

	// Clone RFD Status Checking ----------------------------------------------------------------------------------------------------------------------
	PlatformAcquireSpinLock(pDefaultAdapter, RT_RFD_SPINLOCK);
	uCurrentCloneRFDs = pMultiPortCommon->uCloneRfdIdleQueueSize + pMultiPortCommon->uCloneRfdBusyQueueSize;
	RT_ASSERT(uCurrentCloneRFDs == pMultiPortCommon->uNumberOfCloneRfds, 	("Failure: Some Clone RFDs are Lost!uCurrentCloneRFDs=%d\n", uCurrentCloneRFDs));
	PlatformReleaseSpinLock(pDefaultAdapter, RT_RFD_SPINLOCK);
	// ---------------------------------------------------------------------------------------------------------------------------------------------


	// Get the target adapter list -----------------------------------------------------------------------------
	uTargetAdapter = MultiPortGetTargetAdapterList(pAdapter, pRfd, frame, TargetList, sizeof(TargetList) / sizeof(PADAPTER));
	//RT_TRACE(COMP_INIT, DBG_TRACE, ("%s: uTargetAdapter: %d \n", __FUNCTION__, uTargetAdapter));
	
	if(uTargetAdapter == 0)
	{
		// Free the original RFD since the RFD is not necessary
		RT_TRACE(COMP_INIT, DBG_TRACE, ("%s: No Target Adapter Found!\n", __FUNCTION__));
		return NULL;
	}
	else if(uTargetAdapter == 1)
	{
		// Single adapter is needed. Do not free the original RFD, and run the original path
		return TargetList[0];
	}
	// ----------------------------------------------------------------------------------------------------


	// Send to each adapter
	for(i = 0; i < uTargetAdapter; i++)
	{
		// Get the target adapter element
		pExtAdapter = TargetList[i];

		PlatformAcquireSpinLock(pDefaultAdapter, RT_RFD_SPINLOCK);
		if(RTIsListEmpty(&pMultiPortCommon->CloneRfdIdleQueue))
		{			
			PlatformReleaseSpinLock(pDefaultAdapter, RT_RFD_SPINLOCK);
			RT_TRACE(COMP_INIT, DBG_SERIOUS, ("%s: No enough Clone RFD!\n", __FUNCTION__));
			break;
		}

		// Acquire an idle Clone RFD and initialize the Clone RFD -----------------------------------------
		pExtRfd = (PRT_RFD) RTRemoveHeadListWithCnt(
				&pMultiPortCommon->CloneRfdIdleQueue, 
				&pMultiPortCommon->uCloneRfdIdleQueueSize
			);

		// + Clone the original information
		PlatformZeroMemory(pExtRfd, sizeof(RT_RFD));
		PlatformMoveMemory(pExtRfd, pRfd, sizeof(RT_RFD));	

		// + Record the needed memory length 
		pExtRfd->mbCloneRfdDataBuffer.Length = pRfd->Buffer.Length;

		// + Allocate the memory based on the needed memory length above
		rtStatus = DrvIFAssociateRFD(pDefaultAdapter, pExtRfd);
		
		if(rtStatus != RT_STATUS_SUCCESS)
		{
			// Return the CloneRFD resource
			RTInsertTailListWithCnt(
				&pMultiPortCommon->CloneRfdIdleQueue, 
				&pExtRfd->List, 
				&pMultiPortCommon->uCloneRfdIdleQueueSize
			);
			PlatformReleaseSpinLock(pDefaultAdapter, RT_RFD_SPINLOCK);
			//RT_TRACE(COMP_INIT, DBG_SERIOUS, ("%s: No enough memory!\n", __FUNCTION__));
			break;
		}

		//Sinda 20150903, Should assign Buffer's address according to it is clone RFD.
		if(IsCloneRFD(pDefaultAdapter, pExtRfd))
		{
			// + Attach the memory to the CloneRFD
			pExtRfd->Buffer.VirtualAddress = pExtRfd->mbCloneRfdDataBuffer.Buffer;
			pExtRfd->Buffer.Length = pExtRfd->mbCloneRfdDataBuffer.Length;
		}

#if RX_AGGREGATION
		//   + No Next RFD
		pExtRfd->NextRfd = NULL;

		//  + Only Single MPDU Packet
		pExtRfd->nTotalFrag = 1;

		//   + No Parent RFD
		pExtRfd->ParentRfd = NULL;

		//   + Not in the USB temp RFD list: pAdapter->RfdTmpList
		pExtRfd->bIsTemp = FALSE;
#endif

		//	Please be careful to handle pRfd->Buffer.VirtualAddress offset.
		//	+ Move data
		PlatformMoveMemory(
				pExtRfd->Buffer.VirtualAddress,
				pRfd->Buffer.VirtualAddress - pAdapter->HalFunc.GetRxPacketShiftBytesHandler(pRfd), 
				(pRfd->PacketLength + pAdapter->HalFunc.GetRxPacketShiftBytesHandler(pRfd))>pAdapter->MAX_RECEIVE_BUFFER_SIZE? pAdapter->MAX_RECEIVE_BUFFER_SIZE:(pRfd->PacketLength + pAdapter->HalFunc.GetRxPacketShiftBytesHandler(pRfd))
			);

		//   + Get shifted bytes of starting address of 802.11 header (Sync the memory offset)
		pExtRfd->Buffer.VirtualAddress += pAdapter->HalFunc.GetRxPacketShiftBytesHandler(pRfd);
	 	// -------------------------------------------------------------------------------------

		// Insert into busy Clone RFD queue
		RTInsertHeadListWithCnt(
				&pMultiPortCommon->CloneRfdBusyQueue, 
				&pExtRfd->List, 
				&pMultiPortCommon->uCloneRfdBusyQueueSize
			);

		PlatformReleaseSpinLock(pDefaultAdapter, RT_RFD_SPINLOCK);
		// Iteration Flag
		pExtRfd->bFeedPacketToSingleAdapter = TRUE;

		// The pExtRfd will be free in ProcessReceivedPacket()
		ProcessReceivedPacketForEachPortSpecific(pExtAdapter, pExtRfd);
	}


	// Free the original RFD since the CloneRFD is adopted.
	return NULL;
}
// Description:
// Output:
// Modify: 
void 
Authenticator_StatePTKINITDONE(
	IN	PADAPTER		Adapter,
	IN	PRT_WLAN_STA	pSTA
	)
{
	PAUTH_PKEY_MGNT_TAG	pKeyMgnt = &pSTA->perSTAKeyInfo;

	RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("===> Authenticator_StatePTKINITDONE()\n") );


	// TODO: SetKey to CAM


	if( !ACTING_AS_AP(Adapter))
	{
		RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("[Warning] current: STA mode, return."));
		return;
	}

	pSTA->perSTAKeyInfo.PrState = ASMPS_PTKINITDONE;
	
	// TODO: Check SetKey completed, these lines were moved from Authenticator_OnEAPOLKeyRecvd() by Jay 
	if (pSTA->perSTAKeyInfo.Pair)
	{
		u4Byte  ucIndex = 0;
		CopyMem(pSTA->perSTAKeyInfo.PTK, pSTA->perSTAKeyInfo.PTK_update, PTK_LEN);	// Added by Annie, 2005-07-12.
		if( Adapter->MgntInfo.SecurityInfo.PairwiseEncAlgorithm != RT_ENC_ALG_AESCCMP )
		{
			pSTA->perSTAKeyInfo.TempEncKey = pKeyMgnt->PTK+TKIP_ENC_KEY_POS;
			pSTA->perSTAKeyInfo.TxMICKey = pKeyMgnt->PTK+(TKIP_MIC_KEY_POS);	
			pSTA->perSTAKeyInfo.RxMICKey = pKeyMgnt->PTK+(TKIP_MIC_KEY_POS+TKIP_MIC_KEY_LEN);

			//Add for AP mode HW enc,by CCW		
			ucIndex = AP_FindFreeEntry(Adapter , pSTA->MacAddr );
			if(ucIndex == Adapter->TotalCamEntry)
			{
				RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("[Warning] Authenticator_StatePTKINITDONE: Cam Entry is FULL!!!\n"));
				return;
			}
		
			//set key
			AP_Setkey(  Adapter , 
					      pSTA->perSTAKeyInfo.pWLanSTA->MacAddr,
					      ucIndex,  // Entey  index 
					      CAM_TKIP,
					      0,  // Parise key 
					      pSTA->perSTAKeyInfo.TempEncKey);	

			pSTA->keyindex  = ucIndex;
		}else{  // AES mode AP-WPA AES,CCW
		
			AESCCMP_BLOCK		blockKey;
			//RT_TRACE( COMP_WPAAES, DBG_LOUD, ("====> Set Station Key."));
			//Add for AP mode HW enc,by CCW		
			ucIndex = AP_FindFreeEntry(Adapter , pSTA->MacAddr);
			if(ucIndex == Adapter->TotalCamEntry)
			{
				RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("[Warning] Authenticator_StatePTKINITDONE: Cam Entry is FULL!!!\n"));
				return;
			}
			
			//Set Key 
			PlatformMoveMemory( blockKey.x , pKeyMgnt->PTK+TKIP_ENC_KEY_POS , 16);
			AES_SetKey(blockKey.x, AESCCMP_BLK_SIZE*8, (pu4Byte)pSTA->perSTAKeyInfo.AESKeyBuf);
			//set hw key
			AP_Setkey(  Adapter , 
					      pSTA->perSTAKeyInfo.pWLanSTA->MacAddr,
					      ucIndex,  // Entey  index 
					      CAM_AES,
					      0,  // Parise key 
					     pSTA->perSTAKeyInfo.PTK+TKIP_ENC_KEY_POS);	
			pSTA->keyindex  = ucIndex;
		}
		
	}
	//pSTA->perSTAKeyInfo.bPTKInstalled = TRUE;
	pSTA->perSTAKeyInfo.GInitAKeys = TRUE;
	pSTA->perSTAKeyInfo.PInitAKeys = TRUE;

	// Begin 2-way handshake
	if( Adapter->MgntInfo.SecurityInfo.SecLvl  == RT_SEC_LVL_WPA )
		Authenticator_StateREKEYNEGOTIATING(Adapter, pSTA);  // To do 2-way
	if( Adapter->MgntInfo.SecurityInfo.SecLvl  == RT_SEC_LVL_WPA2 )
	{
		Authenticator_StateREKEYESTABLISHED(Adapter, pSTA);  // No to do 2-way
		pKeyMgnt->TimeoutCtr = 0;
	}
	RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("<=== Authenticator_StatePTKINITDONE()\n") );
}
// Description:
// Output:
// Modify: 
void 
Authenticator_StatePTKINITNEGOTIATING(
	IN	PADAPTER		Adapter,
	IN	PRT_WLAN_STA	pSTA
	)
{
	PMGNT_INFO	pMgntInfo = &Adapter->MgntInfo;
	PAUTH_GLOBAL_KEY_TAG	pGlInfo = &pMgntInfo->globalKeyInfo;
	PAUTH_PKEY_MGNT_TAG	pKeyMgnt = &pSTA->perSTAKeyInfo;

	u8Byte					KeyReplayCounter = 0;
	u1Byte					temp[8] = {0};
	u1Byte					indexi = 0;

	RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("===> Authenticator_StatePTKINITNEGOTIATING()\n") );

	if( !ACTING_AS_AP(Adapter) )
	{
		RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("[Warning] current: STA mode, return."));
		return;
	}


	pSTA->perSTAKeyInfo.PrState = ASMPS_PTKINITNEGOTIATING;

	// [AnnieTODO]
	// 1. Construct 3rd message in 4-way handshake.
	// 	EAPOL(0, 1, 1, Pair,0, P, ANonce, MIC(PTK_update), 0)
	// 2. Send 3rd msg 

	pKeyMgnt->KeyReplayCounter ++;

	RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("Send 4-way message 3\n"));
	//RT_TRACE(COMP_AUTHENTICATOR, DBG_LOUD , (" KeyReplayCounter = %08"i64fmt"x \n",pKeyMgnt->KeyReplayCounter  ));

	for( indexi = 0 ; indexi < 8 ; indexi++)
		temp[indexi] =  (u1Byte)((pKeyMgnt->KeyReplayCounter >>( (7-indexi) *8)) &0xff );

	PlatformMoveMemory( &KeyReplayCounter , temp , 8 );
	
	if( pMgntInfo->SecurityInfo.SecLvl == RT_SEC_LVL_WPA )
	{
	SendEapolKeyPacket(
		Adapter, 
		pSTA->MacAddr, 
		pSTA->perSTAKeyInfo.PTK_update, // Pointer to KCK (EAPOL-Key Confirmation Key).
		pSTA->perSTAKeyInfo.PTK_update + 16,
		type_Pairwise, // EAPOL-Key Information field: Key Type bit: type_Group or type_Pairwise.
		TRUE, // EAPOL-Key Information field: Install Flag.
		TRUE, // EAPOL-Key Information field: Key Ack bit.
		TRUE, // EAPOL-Key Information field: Key MIC bit. If true, we will calculate EAPOL MIC and fill it into Key MIC field. 
		FALSE, // EAPOL-Key Information field: Secure bit.
		FALSE, // EAPOL-Key Information field: Error bit. True for MIC failure report.
		FALSE, // EAPOL-Key Information field: Requst bit.
		KeyReplayCounter, //pSTA->perSTAKeyInfo.KeyReplayCounter, // EAPOL-KEY Replay Counter field.
				pKeyMgnt->ANonce, // EAPOL-Key Key Nonce field (32-byte).
		pSTA->perSTAKeyInfo.KeyRSC, // perSTA EAPOL-Key Key RSC field (8-byte).
		&(pMgntInfo->SecurityInfo.RSNIE), // Key Data field: Pointer to RSN IE, NULL if 
		NULL // Key Data field: Pointer to GTK, NULL if Key Data Length = 0.
	);
	}
	else if( pMgntInfo->SecurityInfo.SecLvl == RT_SEC_LVL_WPA2 )
	{
		SendEapolKeyPacket(
			Adapter, 
			pSTA->MacAddr, 
			pSTA->perSTAKeyInfo.PTK_update, // Pointer to KCK (EAPOL-Key Confirmation Key).
			pSTA->perSTAKeyInfo.PTK_update + 16,
			type_Pairwise, // EAPOL-Key Information field: Key Type bit: type_Group or type_Pairwise.
			TRUE, // EAPOL-Key Information field: Install Flag.
			TRUE, // EAPOL-Key Information field: Key Ack bit.
			TRUE, // EAPOL-Key Information field: Key MIC bit. If true, we will calculate EAPOL MIC and fill it into Key MIC field. 
			TRUE, // EAPOL-Key Information field: Secure bit.
			FALSE, // EAPOL-Key Information field: Error bit. True for MIC failure report.
			FALSE, // EAPOL-Key Information field: Requst bit.
			KeyReplayCounter,//pSTA->perSTAKeyInfo.KeyReplayCounter, // EAPOL-KEY Replay Counter field.
			pKeyMgnt->ANonce, // EAPOL-Key Key Nonce field (32-byte).
			pSTA->perSTAKeyInfo.KeyRSC, // perSTA EAPOL-Key Key RSC field (8-byte).
			&(pMgntInfo->SecurityInfo.RSNIE), // Key Data field: Pointer to RSN IE, NULL if 
			pGlInfo->GTK  // Key Data field: Pointer to GTK, NULL if Key Data Length = 0.
		);
	}

	pKeyMgnt->TimeSlot_lastsend = pGlInfo->CurrentTimeSlot;	// Added by Annie, 2005-07-12.

	// [Note] Don't do pSTA->perSTAKeyInfo.TimeoutCtr++ here!
	// The counter is controlled in KeyMgntTimeout.

	RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("<=== Authenticator_StatePTKINITNEGOTIATING()\n") );

}
void 
Authenticator_StateINITIALIZE(
	IN	PADAPTER		Adapter,
	IN	PRT_WLAN_STA	pSTA
	)
{
	PAUTH_PKEY_MGNT_TAG	pKeyMgnt = &pSTA->perSTAKeyInfo;
	u1Byte	RdmBuf[20], NonceBuf[KEY_NONCE_LEN];
	u1Byte	i = 0;

	pKeyMgnt->pWLanSTA = pSTA;

	RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("===> Authenticator_StateINITIALIZE()\n") );

	if( !ACTING_AS_AP(Adapter)
		&& !GET_TDLS_ENABLED(&(Adapter->MgntInfo)) 
		)
	{
		RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("[Warning] current: STA mode, return."));
		return;
	}

	PlatformZeroMemory( pKeyMgnt->SNonce, KEY_NONCE_LEN );

	pKeyMgnt->TimeoutCtr = 0;
	pKeyMgnt->TimeSlot_sendstart = 0;
	pKeyMgnt->TimeSlot_lastsend = 0;

	if( Adapter->MgntInfo.SecurityInfo.AuthMode == RT_802_11AuthModeWPAPSK )
	{
		// 3. 802.1x::PortMode = Disable;
		pKeyMgnt->portMode = pmt_Disable;	// [TODO] other auth mode
		
		// 4. 802.1x::PortSecure = 0;
		pKeyMgnt->portSecure= psec_Unauthorized;	// [TODO] other auth mode
	}

	
	// 1. MSK = 0 ...?
	
	// 2. GNoStations = 0
	//	...it's for group key update. I don't do it currently. Annie, 2005-07-01.

	// Rest ANonce
	GetRandomBuffer( RdmBuf );
	for( i=0; i<16; i++ )
	{
		NonceBuf[i] = RdmBuf[i];
		NonceBuf[16+i] = RdmBuf[19-i];
	}

	PlatformMoveMemory( pKeyMgnt->ANonce , NonceBuf , KEY_NONCE_LEN );

	
	// 5. RemovePTK
	PlatformZeroMemory( pKeyMgnt->PTK, PTK_LEN );

	pKeyMgnt->TempEncKey = NULL;
	pKeyMgnt->TxMICKey   = NULL;
	pKeyMgnt->RxMICKey   = NULL;

	//AP-WPA AES ,CCW
	PlatformZeroMemory( pKeyMgnt->AESKeyBuf , AESCCMP_BLK_SIZE_TOTAL );
	
	//pKeyMgnt->bPTKInstalled = FALSE;
	pKeyMgnt->PInitAKeys = FALSE;
	pKeyMgnt->GInitAKeys = FALSE;
	pKeyMgnt->Pair = TRUE;				// [AnnieNote] Why not FALSE?? 2005-07-18.

	// TODO: 6. Revome key from CAM
	// [AnnieNote]
	// (1) We can only clear the MAC address (instead of total 6 double-word) in per CAM entry.
	// (2) When called by Authenticator_GlobalReset(), it takes a lot of I/O, and is H/W depended.
	//       Should we do it here? Or use workitem... ?

	//Remove  key from SW/HW CAM table, Add by CCW
	AP_RemoveKey( Adapter , pSTA );
	
	// 7. Reset ReplayCounter
	pKeyMgnt->KeyReplayCounter = 0;
	
	// 8. Reset SNonce
	PlatformZeroMemory( pKeyMgnt->SNonce, KEY_NONCE_LEN );

	// 9. Initialize TimeSlot_lastIntegrityFailed.
	pKeyMgnt->TimeSlot_lastIntegrityFailed = 0;

	pKeyMgnt->RxIV   = DEFAULT_INIT_RX_IV;
	pKeyMgnt->TxIV   = DEFAULT_INIT_TX_IV;
	pKeyMgnt->KeyRSC = pKeyMgnt->TxIV; 

	// Added by Annie for debug, 2005-07-25.
	pKeyMgnt->MicErrorCnt = 0;
	pKeyMgnt->WEPErrorCnt = 0;

	pKeyMgnt->PrState = ASMPS_INITIALIZE;
	pKeyMgnt->GrState = ASMGS_INITIALIZE;


	pSTA->keyindex = 0;

	RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("<=== Authenticator_StateINITIALIZE()\n") );

}
// Description: Initialize the global key data in Authenticator.
// Output: void
// Modify: Annie, 2005-07-02
//		I check the data struct again, and discard using pMgntInfo->globalKeyInfo.groupKeyInfo.
//		Now Global/group key data (PMK, GTK, ANonce): all kept in pMgntInfo->globalKeyInfo.
//		global key state: recorded in pEntry->perSTAKeyInfo.GrState. (I think it should be kept in per station.)
//
void 
Authenticator_GlobalReset(
	IN	PADAPTER		Adapter
	)
{
	PMGNT_INFO	pMgntInfo = &Adapter->MgntInfo;
	PRT_SECURITY_T	pSecInfo = &(pMgntInfo->SecurityInfo);
	PAUTH_GLOBAL_KEY_TAG	pGlInfo = &(pMgntInfo->globalKeyInfo);
	PRT_WLAN_STA	pEntry;
	int 		i;
	u1Byte	RdmBuf[20], NonceBuf[KEY_NONCE_LEN];
	static u1Byte	CAM_CONST_BROAD[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
	AESCCMP_BLOCK		blockKey;	


	//--- [AnnieWorkaround] See 11i D3.0 page91, GTK should be generated by PRF-X.
	u1Byte	TmpGTK[] = "12345678123456781234567812345678";
	//---

	RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("===> Authenticator_GlobalReset()\n") );

	if( !ACTING_AS_AP(Adapter) )
	{
		RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("[Warning] current: STA mode, return."));
		return;
	}

	pGlInfo->currentId = 0;

	if(pSecInfo->SecLvl == RT_SEC_LVL_WPA)
		pGlInfo->DescriptorType = desc_type_RSN;
	else
		pGlInfo->DescriptorType = desc_type_WPA2;

	GetRandomBuffer( RdmBuf );
	for( i=0; i<16; i++ )
	{
		NonceBuf[i] = RdmBuf[i];
		NonceBuf[16+i] = RdmBuf[19-i];
	}
	NonceBuf[KEY_NONCE_LEN-1] = 0;	//[AnnieWorkaround] Remove it if ANonce addition is ready. 2005-11-25.
	RT_PRINT_DATA( COMP_AUTHENTICATOR, DBG_LOUD, "Authenticator_GlobalReset(): NonceBuf", NonceBuf, KEY_NONCE_LEN );	

	// 1. Install PMK
	if( pGlInfo->PassphraseLen < 64 ){
	PasswordHash(pGlInfo->Passphrase, pGlInfo->PassphraseLen,
		pMgntInfo->Ssid.Octet, pMgntInfo->Ssid.Length, pGlInfo->PMK );
	}
	else
	{
		// Add for direct to set PMK 64-Hex mode...
		if( pGlInfo->PassphraseLen == 64 )
			PlatformMoveMemory(pGlInfo->PMK, pGlInfo->Passphrase , 32 );
	}
	// 2. Install GTK

        //
        // 2010/12/15 Neo Jou check in
        // When in Linux AP mode, hostapd will set down GTK before Authenticator_GlobalReset()
        // Thus for Linux AP mode case, we don't reset GTK here
        //
	PlatformZeroMemory( pGlInfo->GTK, GTK_LEN );
	PlatformMoveMemory( pGlInfo->GTK, TmpGTK, GTK_LEN );
	pGlInfo->TxMICKey = pGlInfo->GTK + GTK_MIC_TX_POS;
	pGlInfo->RxMICKey = pGlInfo->GTK + GTK_MIC_RX_POS;

	//AP WPA AES,CCW	
	PlatformMoveMemory( blockKey.x , pGlInfo->GTK , 16);
	AES_SetKey(blockKey.x, AESCCMP_BLK_SIZE*8, (pu4Byte)pGlInfo->AESGTK);
	//
	pSecInfo->GroupTransmitKeyIdx = 1;
	
			

	// 3. Install ANonce
//	CopyMem( pGlInfo->ANonce, NonceBuf, KEY_NONCE_LEN );
	PlatformMoveMemory(pGlInfo->ANonce, NonceBuf, KEY_NONCE_LEN );

	// 4. Install GNonce
//	CopyMem( pGlInfo->GNonce, NonceBuf, KEY_NONCE_LEN );
	PlatformMoveMemory(pGlInfo->GNonce, NonceBuf, KEY_NONCE_LEN );

	// 5. Reset KeyRSC
	pGlInfo->KeyRSC = 0;
	
	// 6. Reset time slot.
	pGlInfo->CurrentTimeSlot = 0;

#if 1 //Addedby Jay 0713
	pGlInfo->TimeSlot_IntegrityFail2 = 0;
#endif

	// 7. IV
#if 1 //Added by Jay 0712 for security IV
	pSecInfo->TxIV = DEFAULT_INIT_TX_IV;
#endif
	pMgntInfo->bAPGlobRest = TRUE;
	// Reset key information of each station.
	for(i = 0; i < ASSOCIATE_ENTRY_NUM; i++)
	{
		pEntry = &(pMgntInfo->AsocEntry[i]);
		Authenticator_StateINITIALIZE(Adapter, pEntry);
	}
	pMgntInfo->bAPGlobRest = FALSE;

	//reset SWCamTabe and HWCamtable ,add by CCW
	AP_ClearAllKey(Adapter);
	
	if( (MgntActQuery_ApType(Adapter) == RT_AP_TYPE_NORMAL ||
	MgntActQuery_ApType(Adapter) == RT_AP_TYPE_IBSS_EMULATED 
		 || MgntActQuery_ApType(Adapter) == RT_AP_TYPE_LINUX) && 
     	( pMgntInfo->NdisVersion  < RT_NDIS_VERSION_6_20 ))
	{
	switch( pSecInfo->PairwiseEncAlgorithm )
	{
	case RT_ENC_ALG_TKIP:
		AP_Setkey(  Adapter , 
			     CAM_CONST_BROAD,
			     1,  // Index entry
			     CAM_TKIP,
			     1,  // Set Group Key
			     pGlInfo->GTK);
		break;

	case RT_ENC_ALG_AESCCMP:
		AP_Setkey(  Adapter , 
			     	CAM_CONST_BROAD,
			     	1,  // Index entry
			     	CAM_AES,
			     	1,  // Set Group Key
			     	pGlInfo->GTK);
		break;

	case RT_ENC_ALG_WEP40: 
	case RT_ENC_ALG_WEP104:
		{
			static u1Byte	CAM_CONST_ADDR[4][6] = {
				{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
				{0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
				{0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
				{0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
				u1Byte EncAlgo = ((pSecInfo->PairwiseEncAlgorithm == RT_ENC_ALG_WEP40) ? CAM_WEP40 : CAM_WEP104);
	
			for(i = 0; i < 4; i++)
			{
				if(pSecInfo->KeyLen[i] > 0)
				{
					AP_Setkey(
						Adapter , 
						CAM_CONST_ADDR[i],
						i,  // Index entry
						EncAlgo,
						1,
						pSecInfo->KeyBuf[i]);
				}
			}
		}
		break;

	default:
		break;
	}
	}
	
	RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("<=== Authenticator_GlobalReset()\n") );
	
}
// Description:
// Output:
// Modify: 
void 
Authenticator_StateREKEYNEGOTIATING(
	IN	PADAPTER		Adapter,
	IN	PRT_WLAN_STA	pSTA
	)
{
	PMGNT_INFO	pMgntInfo = &Adapter->MgntInfo;
	PAUTH_GLOBAL_KEY_TAG	pGlInfo = &pMgntInfo->globalKeyInfo;
	PAUTH_PKEY_MGNT_TAG	pKeyMgnt = &pSTA->perSTAKeyInfo;

	u8Byte					KeyReplayCounter = 0;
	u1Byte					temp[8] = {0};
	u1Byte					indexi = 0;

	RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("===> Authenticator_StateREKEYNEGOTIATING()\n") );

	if( !ACTING_AS_AP(Adapter) )
	{
		RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("[Warning] current: STA mode, return."));
		return;
	}

	pKeyMgnt->GrState = ASMGS_REKEYNEGOTIATING;

	// [AnnieTODO]
	// 1. Construct 1st message in 2-way handshake.
	// 	EAPOL(1, 1, 1, !Pair, GN, G, GNonce, MIC(PTK), GTK[GN] )
	// 2. Send 1st msg in 2-way handshake.

	pKeyMgnt->KeyReplayCounter ++;

	RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("Send 2-way message 1\n"));

	for( indexi = 0 ; indexi < 8 ; indexi++)
		temp[indexi] =  (u1Byte)((pKeyMgnt->KeyReplayCounter >>( (7-indexi) *8)) &0xff );

	PlatformMoveMemory( &KeyReplayCounter , temp , 8 );
	
	SendEapolKeyPacket(
		Adapter, 
		pSTA->MacAddr, 
		pSTA->perSTAKeyInfo.PTK, // Pointer to KCK (EAPOL-Key Confirmation Key).
		pSTA->perSTAKeyInfo.PTK + 16,	// [AnnieWorkaround]
		type_Group, // EAPOL-Key Information field: Key Type bit: type_Group or type_Pairwise.
		FALSE, // EAPOL-Key Information field: Install Flag.
		TRUE, // EAPOL-Key Information field: Key Ack bit.
		TRUE, // EAPOL-Key Information field: Key MIC bit. If true, we will calculate EAPOL MIC and fill it into Key MIC field. 
		TRUE, // EAPOL-Key Information field: Secure bit.
		FALSE, // EAPOL-Key Information field: Error bit. True for MIC failure report.
		FALSE, // EAPOL-Key Information field: Requst bit.
		KeyReplayCounter,//pSTA->perSTAKeyInfo.KeyReplayCounter, // EAPOL-KEY Replay Counter field.
		pGlInfo->GNonce, // EAPOL-Key Key Nonce field (32-byte).
		pGlInfo->KeyRSC, // EAPOL-Key Key RSC field (8-byte).
		NULL, // Key Data field: Pointer to RSN IE, NULL if 
		pGlInfo->GTK  // Key Data field: Pointer to GTK, NULL if Key Data Length = 0.
	);

	pKeyMgnt->TimeSlot_lastsend = pGlInfo->CurrentTimeSlot;	// added by Annie, 2005-07-12.

	// [Note] Don't do pKeyMgnt->TimeoutCtr++ here!
	// The counter is controlled in KeyMgntTimeout.

	RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("<=== Authenticator_StateREKEYNEGOTIATING()\n") );

}
BOOLEAN
ODM_SwAntDivCheckBeforeLink(
	IN		PVOID		pDM_VOID
	)
{

#if (RT_MEM_SIZE_LEVEL != RT_MEM_SIZE_MINIMUM)

	PDM_ODM_T		pDM_Odm = (PDM_ODM_T)pDM_VOID;
	PADAPTER		Adapter = pDM_Odm->Adapter;
	HAL_DATA_TYPE*	pHalData = GET_HAL_DATA(Adapter);
	PMGNT_INFO		pMgntInfo = &Adapter->MgntInfo;
	pSWAT_T			pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table;
	pFAT_T	pDM_FatTable = &pDM_Odm->DM_FatTable;
	s1Byte			Score = 0;
	PRT_WLAN_BSS	pTmpBssDesc, pTestBssDesc;
	u1Byte 			power_target = 10, power_target_L = 9, power_target_H = 16;
	u1Byte			tmp_power_diff = 0,power_diff = 0,avg_power_diff = 0,max_power_diff = 0,min_power_diff = 0xff;
	u2Byte			index, counter = 0;
	static u1Byte		ScanChannel;
	u8Byte			tStamp_diff = 0;		
	u4Byte			tmp_SWAS_NoLink_BK_Reg948;

	ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ANTA_ON = (( %d )) , ANTB_ON = (( %d )) \n",pDM_Odm->DM_SWAT_Table.ANTA_ON ,pDM_Odm->DM_SWAT_Table.ANTB_ON ));

	//if(HP id)
	{
		if(pDM_Odm->DM_SWAT_Table.RSSI_AntDect_bResult==TRUE && pDM_Odm->SupportICType == ODM_RTL8723B)
		{
			ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("8723B RSSI-based Antenna Detection is done\n"));
			return FALSE;
		}
		
		if(pDM_Odm->SupportICType == ODM_RTL8723B)
		{
			if(pDM_SWAT_Table->SWAS_NoLink_BK_Reg948 == 0xff)
				pDM_SWAT_Table->SWAS_NoLink_BK_Reg948 = ODM_Read4Byte(pDM_Odm, rS0S1_PathSwitch );
		}
	}

	if (pDM_Odm->Adapter == NULL)  //For BSOD when plug/unplug fast.  //By YJ,120413
	{	// The ODM structure is not initialized.
		return FALSE;
	}

	// Retrieve antenna detection registry info, added by Roger, 2012.11.27.
	if(!IS_ANT_DETECT_SUPPORT_RSSI(Adapter))
	{
		return FALSE;
	}
	else
	{
		ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Antenna Detection: RSSI Method\n"));	
	}

	// Since driver is going to set BB register, it shall check if there is another thread controlling BB/RF.
	PlatformAcquireSpinLock(Adapter, RT_RF_STATE_SPINLOCK);
	if(pHalData->eRFPowerState!=eRfOn || pMgntInfo->RFChangeInProgress || pMgntInfo->bMediaConnect)
	{
		PlatformReleaseSpinLock(Adapter, RT_RF_STATE_SPINLOCK);
	
		ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, 
				("ODM_SwAntDivCheckBeforeLink(): RFChangeInProgress(%x), eRFPowerState(%x)\n", 
				pMgntInfo->RFChangeInProgress, pHalData->eRFPowerState));
	
		pDM_SWAT_Table->SWAS_NoLink_State = 0;
		
		return FALSE;
	}
	else
	{
		PlatformReleaseSpinLock(Adapter, RT_RF_STATE_SPINLOCK);
	}
	ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("pDM_SWAT_Table->SWAS_NoLink_State = %d\n", pDM_SWAT_Table->SWAS_NoLink_State));
	//1 Run AntDiv mechanism "Before Link" part.
	if(pDM_SWAT_Table->SWAS_NoLink_State == 0)
	{
		//1 Prepare to do Scan again to check current antenna state.

		// Set check state to next step.
		pDM_SWAT_Table->SWAS_NoLink_State = 1;
	
		// Copy Current Scan list.
		pMgntInfo->tmpNumBssDesc = pMgntInfo->NumBssDesc;
		PlatformMoveMemory((PVOID)Adapter->MgntInfo.tmpbssDesc, (PVOID)pMgntInfo->bssDesc, sizeof(RT_WLAN_BSS)*MAX_BSS_DESC);
		
		// Go back to scan function again.
		ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SwAntDivCheckBeforeLink: Scan one more time\n"));
		pMgntInfo->ScanStep=0;
		pMgntInfo->bScanAntDetect = TRUE;
		ScanChannel = odm_SwAntDivSelectScanChnl(Adapter);

		
		if(pDM_Odm->SupportICType & (ODM_RTL8188E|ODM_RTL8821))
		{
			if(pDM_FatTable->RxIdleAnt == MAIN_ANT)
				ODM_UpdateRxIdleAnt(pDM_Odm, AUX_ANT);
			else
				ODM_UpdateRxIdleAnt(pDM_Odm, MAIN_ANT);
			if(ScanChannel == 0)
			{
				ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, 
					("ODM_SwAntDivCheckBeforeLink(): No AP List Avaiable, Using Ant(%s)\n", (pDM_FatTable->RxIdleAnt==MAIN_ANT)?"AUX_ANT":"MAIN_ANT"));

				if(IS_5G_WIRELESS_MODE(pMgntInfo->dot11CurrentWirelessMode))
				{
					pDM_SWAT_Table->Ant5G = pDM_FatTable->RxIdleAnt;
					ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("pDM_SWAT_Table->Ant5G=%s\n", (pDM_FatTable->RxIdleAnt==MAIN_ANT)?"MAIN_ANT":"AUX_ANT"));
				}
				else
				{
					pDM_SWAT_Table->Ant2G = pDM_FatTable->RxIdleAnt;
					ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("pDM_SWAT_Table->Ant2G=%s\n", (pDM_FatTable->RxIdleAnt==MAIN_ANT)?"MAIN_ANT":"AUX_ANT"));
				}
				return FALSE;
			}

			ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, 
				("ODM_SwAntDivCheckBeforeLink: Change to %s for testing.\n", ((pDM_FatTable->RxIdleAnt == MAIN_ANT)?"MAIN_ANT":"AUX_ANT")));
		}
		else if(pDM_Odm->SupportICType & (ODM_RTL8192C|ODM_RTL8723B))
		{
			if(pDM_Odm->SupportICType == ODM_RTL8192C)
			{
			// Switch Antenna to another one.
			pDM_SWAT_Table->PreAntenna = pDM_SWAT_Table->CurAntenna;
			pDM_SWAT_Table->CurAntenna = (pDM_SWAT_Table->CurAntenna==MAIN_ANT)?AUX_ANT:MAIN_ANT;
			
				pDM_SWAT_Table->SWAS_NoLink_BK_Reg860 = ((pDM_SWAT_Table->SWAS_NoLink_BK_Reg860 & 0xfffffcff) | (pDM_SWAT_Table->CurAntenna<<8));
				ODM_SetBBReg(pDM_Odm,  rFPGA0_XA_RFInterfaceOE, bMaskDWord, pDM_SWAT_Table->SWAS_NoLink_BK_Reg860);
			}
			else if(pDM_Odm->SupportICType == ODM_RTL8723B)
			{
				// Switch Antenna to another one.
				
				tmp_SWAS_NoLink_BK_Reg948 = ODM_Read4Byte(pDM_Odm, rS0S1_PathSwitch );
				
				if( (pDM_SWAT_Table->CurAntenna = MAIN_ANT) && (tmp_SWAS_NoLink_BK_Reg948==0x200))
				{
					ODM_SetBBReg(pDM_Odm, rS0S1_PathSwitch, 0xfff, 0x280);
					ODM_SetBBReg(pDM_Odm, rAGC_table_select, BIT31, 0x1);
					pDM_SWAT_Table->CurAntenna = AUX_ANT;
			}
				else
				{
					ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("Reg[948]= (( %x )) was in wrong state\n", tmp_SWAS_NoLink_BK_Reg948 ));
					return FALSE;
				}
				ODM_StallExecution(10);
		
			}
			ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SwAntDivCheckBeforeLink: Change to (( %s-ant))  for testing.\n", (pDM_SWAT_Table->CurAntenna==MAIN_ANT)?"MAIN":"AUX"));
		}
		
		odm_SwAntDivConstructScanChnl(Adapter, ScanChannel);
		PlatformSetTimer(Adapter, &pMgntInfo->ScanTimer, 5);

		return TRUE;
	}
	else //pDM_SWAT_Table->SWAS_NoLink_State == 1
	{
		//1 ScanComple() is called after antenna swiched.
		//1 Check scan result and determine which antenna is going
		//1 to be used.

		ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,(" tmpNumBssDesc= (( %d )) \n",pMgntInfo->tmpNumBssDesc));// debug for Dino
		
		for(index = 0; index < pMgntInfo->tmpNumBssDesc; index++)
		{
			pTmpBssDesc = &(pMgntInfo->tmpbssDesc[index]); // Antenna 1
			pTestBssDesc = &(pMgntInfo->bssDesc[index]); // Antenna 2

			if(PlatformCompareMemory(pTestBssDesc->bdBssIdBuf, pTmpBssDesc->bdBssIdBuf, 6)!=0)
			{
				ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SwAntDivCheckBeforeLink(): ERROR!! This shall not happen.\n"));
				continue;
			}

			if(pDM_Odm->SupportICType != ODM_RTL8723B)
			{
				if(pTmpBssDesc->ChannelNumber == ScanChannel)
				{
			if(pTmpBssDesc->RecvSignalPower > pTestBssDesc->RecvSignalPower)
			{
					ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SwAntDivCheckBeforeLink: Compare scan entry: Score++\n"));
						RT_PRINT_STR(COMP_SCAN, DBG_WARNING, "GetScanInfo(): new Bss SSID:", pTmpBssDesc->bdSsIdBuf, pTmpBssDesc->bdSsIdLen);
						ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("at ch %d, Original: %d, Test: %d\n\n", pTmpBssDesc->ChannelNumber, pTmpBssDesc->RecvSignalPower, pTestBssDesc->RecvSignalPower));
			
				Score++;
				PlatformMoveMemory(pTestBssDesc, pTmpBssDesc, sizeof(RT_WLAN_BSS));
			}
			else if(pTmpBssDesc->RecvSignalPower < pTestBssDesc->RecvSignalPower)
			{
					ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SwAntDivCheckBeforeLink: Compare scan entry: Score--\n"));
						RT_PRINT_STR(COMP_SCAN, DBG_WARNING, "GetScanInfo(): new Bss SSID:", pTmpBssDesc->bdSsIdBuf, pTmpBssDesc->bdSsIdLen);
						ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("at ch %d, Original: %d, Test: %d\n\n", pTmpBssDesc->ChannelNumber, pTmpBssDesc->RecvSignalPower, pTestBssDesc->RecvSignalPower));
				Score--;
			}
					else
					{
						if(pTestBssDesc->bdTstamp - pTmpBssDesc->bdTstamp < 5000)
						{
							RT_PRINT_STR(COMP_SCAN, DBG_WARNING, "GetScanInfo(): new Bss SSID:", pTmpBssDesc->bdSsIdBuf, pTmpBssDesc->bdSsIdLen);
							ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("at ch %d, Original: %d, Test: %d\n", pTmpBssDesc->ChannelNumber, pTmpBssDesc->RecvSignalPower, pTestBssDesc->RecvSignalPower));
							ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("The 2nd Antenna didn't get this AP\n\n"));
						}
					}
				}
			}
			else // 8723B
			{ 
				if(pTmpBssDesc->ChannelNumber == ScanChannel)
				{
					ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("ChannelNumber == ScanChannel -> (( %d )) \n", pTmpBssDesc->ChannelNumber ));
				
					if(pTmpBssDesc->RecvSignalPower > pTestBssDesc->RecvSignalPower) // Pow(Ant1) > Pow(Ant2)
					{
						counter++;
						tmp_power_diff=(u1Byte)(pTmpBssDesc->RecvSignalPower - pTestBssDesc->RecvSignalPower);
						power_diff = power_diff + tmp_power_diff;	
						
						ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Original: %d, Test: %d\n", pTmpBssDesc->RecvSignalPower, pTestBssDesc->RecvSignalPower));
						ODM_PRINT_ADDR(pDM_Odm,ODM_COMP_ANT_DIV, DBG_LOUD, ("SSID:"), pTmpBssDesc->bdSsIdBuf);
						ODM_PRINT_ADDR(pDM_Odm,ODM_COMP_ANT_DIV, DBG_LOUD, ("BSSID:"), pTmpBssDesc->bdBssIdBuf);

						//ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("tmp_power_diff: (( %d)),max_power_diff: (( %d)),min_power_diff: (( %d))  \n", tmp_power_diff,max_power_diff,min_power_diff));
						if(tmp_power_diff > max_power_diff)
							max_power_diff=tmp_power_diff;
						if(tmp_power_diff < min_power_diff)
							min_power_diff=tmp_power_diff;
						//ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("max_power_diff: (( %d)),min_power_diff: (( %d))  \n",max_power_diff,min_power_diff));
						
						PlatformMoveMemory(pTestBssDesc, pTmpBssDesc, sizeof(RT_WLAN_BSS));
					}
					else if(pTestBssDesc->RecvSignalPower > pTmpBssDesc->RecvSignalPower) // Pow(Ant1) < Pow(Ant2)
					{
						counter++;
						tmp_power_diff=(u1Byte)(pTestBssDesc->RecvSignalPower - pTmpBssDesc->RecvSignalPower);
						power_diff = power_diff + tmp_power_diff;						
						ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Original: %d, Test: %d\n", pTmpBssDesc->RecvSignalPower, pTestBssDesc->RecvSignalPower));
						ODM_PRINT_ADDR(pDM_Odm,ODM_COMP_ANT_DIV, DBG_LOUD, ("SSID:"), pTmpBssDesc->bdSsIdBuf);
						ODM_PRINT_ADDR(pDM_Odm,ODM_COMP_ANT_DIV, DBG_LOUD, ("BSSID:"), pTmpBssDesc->bdBssIdBuf);							
						if(tmp_power_diff > max_power_diff)
							max_power_diff=tmp_power_diff;
						if(tmp_power_diff < min_power_diff)
							min_power_diff=tmp_power_diff;							
					}
					else // Pow(Ant1) = Pow(Ant2)
					{
						if(pTestBssDesc->bdTstamp > pTmpBssDesc->bdTstamp) //  Stamp(Ant1) < Stamp(Ant2) 
					{
						ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("time_diff: %lld\n", (pTestBssDesc->bdTstamp-pTmpBssDesc->bdTstamp)/1000));
						if(pTestBssDesc->bdTstamp - pTmpBssDesc->bdTstamp > 5000)
						{
							counter++;
							ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Original: %d, Test: %d\n", pTmpBssDesc->RecvSignalPower, pTestBssDesc->RecvSignalPower));
							ODM_PRINT_ADDR(pDM_Odm,ODM_COMP_ANT_DIV, DBG_LOUD, ("SSID:"), pTmpBssDesc->bdSsIdBuf);
								ODM_PRINT_ADDR(pDM_Odm,ODM_COMP_ANT_DIV, DBG_LOUD, ("BSSID:"), pTmpBssDesc->bdBssIdBuf);
								min_power_diff = 0;
						}
					}
						else
						{
							ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[Error !!!]: Time_diff: %lld\n", (pTestBssDesc->bdTstamp-pTmpBssDesc->bdTstamp)/1000));
						}
				}
			}
		}
		}

		if(pDM_Odm->SupportICType & (ODM_RTL8188E|ODM_RTL8821))
		{
			if(pMgntInfo->NumBssDesc!=0 && Score<0)
			{
				ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,
							("ODM_SwAntDivCheckBeforeLink(): Using Ant(%s)\n", (pDM_FatTable->RxIdleAnt==MAIN_ANT)?"MAIN_ANT":"AUX_ANT"));
			}
			else
			{
				ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, 
						("ODM_SwAntDivCheckBeforeLink(): Remain Ant(%s)\n", (pDM_FatTable->RxIdleAnt==MAIN_ANT)?"AUX_ANT":"MAIN_ANT"));

				if(pDM_FatTable->RxIdleAnt == MAIN_ANT)
					ODM_UpdateRxIdleAnt(pDM_Odm, AUX_ANT);
				else
					ODM_UpdateRxIdleAnt(pDM_Odm, MAIN_ANT);
			}
			
			if(IS_5G_WIRELESS_MODE(pMgntInfo->dot11CurrentWirelessMode))
			{
				pDM_SWAT_Table->Ant5G = pDM_FatTable->RxIdleAnt;
				ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("pDM_SWAT_Table->Ant5G=%s\n", (pDM_FatTable->RxIdleAnt==MAIN_ANT)?"MAIN_ANT":"AUX_ANT"));
			}
			else
			{
				pDM_SWAT_Table->Ant2G = pDM_FatTable->RxIdleAnt;
				ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("pDM_SWAT_Table->Ant2G=%s\n", (pDM_FatTable->RxIdleAnt==MAIN_ANT)?"MAIN_ANT":"AUX_ANT"));
			}
		}
		else if(pDM_Odm->SupportICType == ODM_RTL8723B)
		{
			if(counter == 0)
			{	
				if(pDM_Odm->DM_SWAT_Table.Pre_Aux_FailDetec == FALSE)
				{
					pDM_Odm->DM_SWAT_Table.Pre_Aux_FailDetec = TRUE;
					pDM_Odm->DM_SWAT_Table.RSSI_AntDect_bResult=FALSE;
					ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Counter=(( 0 )) , [[ Cannot find any AP with Aux-ant ]] ->  Scan Target-channel again  \n"));	

                                        //3 [ Scan again ]
					odm_SwAntDivConstructScanChnl(Adapter, ScanChannel);
					PlatformSetTimer(Adapter, &pMgntInfo->ScanTimer, 5);
					return TRUE;
				}
				else// Pre_Aux_FailDetec == TRUE
				{
					//2 [ Single Antenna ]
					pDM_Odm->DM_SWAT_Table.Pre_Aux_FailDetec = FALSE;
					pDM_Odm->DM_SWAT_Table.RSSI_AntDect_bResult=TRUE;
					ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Counter=(( 0 )) , [[  Still cannot find any AP ]] \n"));
					ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SwAntDivCheckBeforeLink(): Single antenna\n"));	
				}
				pDM_Odm->DM_SWAT_Table.Aux_FailDetec_Counter++;
			}
			else
			{
				pDM_Odm->DM_SWAT_Table.Pre_Aux_FailDetec = FALSE;
				
				if(counter==3)
				{
					avg_power_diff = ((power_diff-max_power_diff - min_power_diff)>>1)+ ((max_power_diff + min_power_diff)>>2);
					ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("counter: (( %d )) ,  power_diff: (( %d )) \n", counter, power_diff));
					ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ counter==3 ] Modified avg_power_diff: (( %d )) , max_power_diff: (( %d )) ,  min_power_diff: (( %d )) \n", avg_power_diff,max_power_diff, min_power_diff));
				}
				else if(counter>=4)
				{
					avg_power_diff=(power_diff-max_power_diff - min_power_diff) / (counter - 2);
					ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("counter: (( %d )) ,  power_diff: (( %d )) \n", counter, power_diff));
					ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[ counter>=4 ] Modified avg_power_diff: (( %d )) , max_power_diff: (( %d )) ,  min_power_diff: (( %d )) \n", avg_power_diff,max_power_diff, min_power_diff));
					
				}
				else//counter==1,2
				{
					avg_power_diff=power_diff/counter;
					ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("avg_power_diff: (( %d )) , counter: (( %d )) ,  power_diff: (( %d )) \n", avg_power_diff,counter, power_diff));
				}

				//2 [ Retry ]
				if( (avg_power_diff >=power_target_L) && (avg_power_diff <=power_target_H)  )
				{
					pDM_Odm->DM_SWAT_Table.Retry_Counter++;
					
					if(pDM_Odm->DM_SWAT_Table.Retry_Counter<=3)
					{
						pDM_Odm->DM_SWAT_Table.RSSI_AntDect_bResult=FALSE;
						ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[[ Low confidence result ]] avg_power_diff= (( %d ))  ->  Scan Target-channel again ]] \n", avg_power_diff));	

					         //3 [ Scan again ]
						odm_SwAntDivConstructScanChnl(Adapter, ScanChannel);
						PlatformSetTimer(Adapter, &pMgntInfo->ScanTimer, 5);
						return TRUE;					         
					}
					else
			{
						pDM_Odm->DM_SWAT_Table.RSSI_AntDect_bResult=TRUE;
						ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("[[ Still Low confidence result ]]  (( Retry_Counter > 3 )) \n"));
						ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SwAntDivCheckBeforeLink(): Single antenna\n"));
					}
					
				}
				//2 [ Dual Antenna ]
				else if( (pMgntInfo->NumBssDesc != 0) && (avg_power_diff < power_target_L)   ) 
				{
					pDM_Odm->DM_SWAT_Table.RSSI_AntDect_bResult=TRUE;
					if(pDM_Odm->DM_SWAT_Table.ANTB_ON == FALSE)
					{
						pDM_Odm->DM_SWAT_Table.ANTA_ON = TRUE;
						pDM_Odm->DM_SWAT_Table.ANTB_ON = TRUE;
					}
					ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("ODM_SwAntDivCheckBeforeLink(): Dual antenna\n"));
					pDM_Odm->DM_SWAT_Table.Dual_Ant_Counter++;

					// set bt coexDM from 1ant coexDM to 2ant coexDM
					BT_SetBtCoexAntNum(Adapter, BT_COEX_ANT_TYPE_DETECTED, 2);
					
					//3 [ Init antenna diversity ]
					pDM_Odm->SupportAbility |= ODM_BB_ANT_DIV; 
					ODM_AntDivInit(pDM_Odm);
				}
				//2 [ Single Antenna ]
				else if(avg_power_diff > power_target_H)
				{
					pDM_Odm->DM_SWAT_Table.RSSI_AntDect_bResult=TRUE;
					if(pDM_Odm->DM_SWAT_Table.ANTB_ON == TRUE)
					{
						pDM_Odm->DM_SWAT_Table.ANTA_ON = TRUE;
						pDM_Odm->DM_SWAT_Table.ANTB_ON = FALSE;
						//BT_SetBtCoexAntNum(Adapter, BT_COEX_ANT_TYPE_DETECTED, 1);
					}
					ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SwAntDivCheckBeforeLink(): Single antenna\n"));
					pDM_Odm->DM_SWAT_Table.Single_Ant_Counter++;
				}
			}
			//ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("bResult=(( %d ))\n",pDM_Odm->DM_SWAT_Table.RSSI_AntDect_bResult));
		ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("Dual_Ant_Counter = (( %d )), Single_Ant_Counter = (( %d )) , Retry_Counter = (( %d )) , Aux_FailDetec_Counter = (( %d ))\n\n\n",
			pDM_Odm->DM_SWAT_Table.Dual_Ant_Counter,pDM_Odm->DM_SWAT_Table.Single_Ant_Counter,pDM_Odm->DM_SWAT_Table.Retry_Counter,pDM_Odm->DM_SWAT_Table.Aux_FailDetec_Counter));

			//2 recover the antenna setting

			if(pDM_Odm->DM_SWAT_Table.ANTB_ON == FALSE)
				ODM_SetBBReg(pDM_Odm, rS0S1_PathSwitch, 0xfff, (pDM_SWAT_Table->SWAS_NoLink_BK_Reg948));
			
			ODM_RT_TRACE(pDM_Odm,ODM_COMP_ANT_DIV, ODM_DBG_LOUD,("bResult=(( %d )), Recover  Reg[948]= (( %x )) \n\n",pDM_Odm->DM_SWAT_Table.RSSI_AntDect_bResult, pDM_SWAT_Table->SWAS_NoLink_BK_Reg948 ));

			
		}