/******************************************************************************
 *
 * 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/bss.c#7
*/

/*! \file   "bss.c"
*    \brief  This file contains the functions for creating BSS(AP)/IBSS(AdHoc).
*
*   This file contains the functions for BSS(AP)/IBSS(AdHoc). We may create a BSS/IBSS
*   network, or merge with exist IBSS network and sending Beacon Frame or reply
*    the Probe Response Frame for received Probe Request Frame.
*/


/*******************************************************************************
*                         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
********************************************************************************
*/

const PUINT_8 apucNetworkType[NETWORK_TYPE_NUM] = {
	(PUINT_8) "AIS",
	(PUINT_8) "P2P",
	(PUINT_8) "BOW",
	(PUINT_8) "MBSS"
};

const PUINT_8 apucNetworkOpMode[] = {
	(PUINT_8) "INFRASTRUCTURE",
	(PUINT_8) "IBSS",
	(PUINT_8) "ACCESS_POINT",
	(PUINT_8) "P2P_DEVICE",
	(PUINT_8) "BOW"
};

#if (CFG_SUPPORT_ADHOC) || (CFG_SUPPORT_AAA)
APPEND_VAR_IE_ENTRY_T txBcnIETable[] = {
	{(ELEM_HDR_LEN + (RATE_NUM_SW - ELEM_MAX_LEN_SUP_RATES)), NULL, bssGenerateExtSuppRate_IE}	/* 50 */
	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, rlmRspGenerateErpIE}	/* 42 */
	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmRspGenerateHtCapIE}	/* 45 */
	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, rlmRspGenerateHtOpIE}	/* 61 */
#if CFG_ENABLE_WIFI_DIRECT
	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, rlmRspGenerateObssScanIE}	/* 74 */
#endif
	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE}	/* 127 */
	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWpaNoneIE}	/* 221 */
	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE}	/* 221 */
#if CFG_ENABLE_WIFI_DIRECT
	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWPAIE}	/* 221 */
	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE}	/* 48 */
#if 0				/* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */
	, {0, p2pFuncCalculateExtra_IELenForBeacon, p2pFuncGenerateExtra_IEForBeacon}	/* 221 */
#else
	, {0, p2pFuncCalculateP2p_IELenForBeacon, p2pFuncGenerateP2p_IEForBeacon}	/* 221 */
	, {0, p2pFuncCalculateWSC_IELenForBeacon, p2pFuncGenerateWSC_IEForBeacon}	/* 221 */
#endif
	, {0, p2pFuncCalculateP2P_IE_NoA, p2pFuncGenerateP2P_IE_NoA}	/* 221 */
#endif /* CFG_ENABLE_WIFI_DIRECT */
#if CFG_SUPPORT_802_11AC
	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_VHT_CAP), NULL, rlmRspGenerateVhtCapIE}	/*191 */
	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_VHT_OP), NULL, rlmRspGenerateVhtOpIE}	/*192 */
	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_VHT_OP_MODE_NOTIFICATION), NULL, rlmRspGenerateVhtOpNotificationIE}	/*199 */
#endif
#if CFG_SUPPORT_MTK_SYNERGY
	, {(ELEM_HDR_LEN + ELEM_MIN_LEN_MTK_OUI), NULL, rlmGenerateMTKOuiIE}	/* 221 */
#endif
#if (CFG_SUPPORT_DFS_MASTER == 1)
	, {(ELEM_HDR_LEN + ELEM_MIN_LEN_CSA), NULL, rlmGenerateCsaIE}            /* 37 */
#endif

};

APPEND_VAR_IE_ENTRY_T txProbRspIETable[] = {
	{(ELEM_HDR_LEN + (RATE_NUM_SW - ELEM_MAX_LEN_SUP_RATES)), NULL, bssGenerateExtSuppRate_IE}	/* 50 */
	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, rlmRspGenerateErpIE}	/* 42 */
	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmRspGenerateHtCapIE}	/* 45 */
	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, rlmRspGenerateHtOpIE}	/* 61 */
#if CFG_ENABLE_WIFI_DIRECT
	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE}	/* 48 */
	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, rlmRspGenerateObssScanIE}	/* 74 */
#endif
	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE}	/* 127 */
	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWpaNoneIE}	/* 221 */
	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE}	/* 221 */
#if CFG_SUPPORT_802_11AC
	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_VHT_CAP), NULL, rlmRspGenerateVhtCapIE}	/*191 */
	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_VHT_OP), NULL, rlmRspGenerateVhtOpIE}	/*192 */
	, {(ELEM_HDR_LEN + ELEM_MAX_LEN_VHT_OP_MODE_NOTIFICATION), NULL, rlmRspGenerateVhtOpNotificationIE}	/*199 */
#endif
#if CFG_SUPPORT_MTK_SYNERGY
	, {(ELEM_HDR_LEN + ELEM_MIN_LEN_MTK_OUI), NULL, rlmGenerateMTKOuiIE}	/* 221 */
#endif

};

#endif /* CFG_SUPPORT_ADHOC || CFG_SUPPORT_AAA */

/*******************************************************************************
*                           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
********************************************************************************
*/
/*----------------------------------------------------------------------------*/
/* Routines for all Operation Modes                                           */
/*----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*/
/*!
* @brief This function will decide PHY type set of STA_RECORD_T by given BSS_DESC_T for
*        Infrastructure or AdHoc Mode.
*
* @param[in] prAdapter              Pointer to the Adapter structure.
* @param[in] prBssDesc              Received Beacon/ProbeResp from this STA
* @param[out] prStaRec              StaRec to be decided PHY type set
*
* @retval   VOID
*/
/*----------------------------------------------------------------------------*/
VOID bssDetermineStaRecPhyTypeSet(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc, OUT P_STA_RECORD_T prStaRec)
{
	P_WIFI_VAR_T prWifiVar = &prAdapter->rWifiVar;
	UINT_8 ucHtOption = FEATURE_ENABLED;
	UINT_8 ucVhtOption = FEATURE_ENABLED;

	prStaRec->ucPhyTypeSet = prBssDesc->ucPhyTypeSet;
#if CFG_SUPPORT_BFEE
	prStaRec->ucVhtCapNumSoundingDimensions = prBssDesc->ucVhtCapNumSoundingDimensions;
#endif

	/* Decide AIS PHY type set */
	if (prStaRec->eStaType == STA_TYPE_LEGACY_AP) {
		if (!((prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_ENABLED) ||
		      (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_KEY_ABSENT)
		      || (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION_DISABLED)
		      || (prAdapter->prGlueInfo->u2WSCAssocInfoIELen)
#if CFG_SUPPORT_WAPI
		      || (prAdapter->prGlueInfo->u2WapiAssocInfoIESz)
#endif
		    )) {
			DBGLOG(BSS, INFO, "Ignore the HT Bit for TKIP as pairwise cipher configed!\n");
			prStaRec->ucPhyTypeSet &= ~(PHY_TYPE_BIT_HT | PHY_TYPE_BIT_VHT);
		}

		ucHtOption = prWifiVar->ucStaHt;
		ucVhtOption = prWifiVar->ucStaVht;
	}
	/* Decide P2P GC PHY type set */
	else if (prStaRec->eStaType == STA_TYPE_P2P_GO) {
		ucHtOption = prWifiVar->ucP2pGcHt;
		ucVhtOption = prWifiVar->ucP2pGcVht;
	}

	/* Set HT/VHT capability from Feature Option */
	if (IS_FEATURE_DISABLED(ucHtOption))
		prStaRec->ucPhyTypeSet &= ~PHY_TYPE_BIT_HT;
	else if (IS_FEATURE_FORCE_ENABLED(ucHtOption))
		prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HT;

	if (IS_FEATURE_DISABLED(ucVhtOption))
		prStaRec->ucPhyTypeSet &= ~PHY_TYPE_BIT_VHT;
	else if (IS_FEATURE_FORCE_ENABLED(ucVhtOption))
		prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_VHT;

	prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prAdapter->rWifiVar.ucAvailablePhyTypeSet;

}

/*----------------------------------------------------------------------------*/
/*!
* @brief This function will decide PHY type set of BSS_INFO for
*        AP Mode.
*
* @param[in] prAdapter              Pointer to the Adapter structure.
* @param[in] fgIsApMode             Legacy AP mode or P2P GO
* @param[out] prBssInfo             BssInfo to be decided PHY type set
*
* @retval   VOID
*/
/*----------------------------------------------------------------------------*/
VOID bssDetermineApBssInfoPhyTypeSet(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgIsPureAp, OUT P_BSS_INFO_T prBssInfo)
{
	P_WIFI_VAR_T prWifiVar = &prAdapter->rWifiVar;
	UINT_8 ucHtOption = FEATURE_ENABLED;
	UINT_8 ucVhtOption = FEATURE_ENABLED;

	/* Decide AP mode PHY type set */
	if (fgIsPureAp) {
		ucHtOption = prWifiVar->ucApHt;
		ucVhtOption = prWifiVar->ucApVht;
	}
	/* Decide P2P GO PHY type set */
	else {
		ucHtOption = prWifiVar->ucP2pGoHt;
		ucVhtOption = prWifiVar->ucP2pGoVht;
	}

	/* Set HT/VHT capability from Feature Option */
	if (IS_FEATURE_DISABLED(ucHtOption))
		prBssInfo->ucPhyTypeSet &= ~PHY_TYPE_BIT_HT;
	else if (IS_FEATURE_ENABLED(ucHtOption))
		prBssInfo->ucPhyTypeSet |= PHY_TYPE_BIT_HT;

	if (IS_FEATURE_DISABLED(ucVhtOption)) {
		prBssInfo->ucPhyTypeSet &= ~PHY_TYPE_BIT_VHT;
	} else if (IS_FEATURE_FORCE_ENABLED(ucVhtOption) ||
		   (IS_FEATURE_ENABLED(ucVhtOption) && (prBssInfo->eBand == BAND_5G))) {

		/* Enable HT capability if VHT is enabled */
		prBssInfo->ucPhyTypeSet |= PHY_TYPE_BIT_VHT;
	}

	prBssInfo->ucPhyTypeSet &= prAdapter->rWifiVar.ucAvailablePhyTypeSet;

}

/*----------------------------------------------------------------------------*/
/*!
* @brief This function will create or reset a STA_RECORD_T by given BSS_DESC_T for
*        Infrastructure or AdHoc Mode.
*
* @param[in] prAdapter              Pointer to the Adapter structure.
* @param[in] eStaType               Assign STA Type for this STA_RECORD_T
* @param[in] eNetTypeIndex          Assign Net Type Index for this STA_RECORD_T
* @param[in] prBssDesc              Received Beacon/ProbeResp from this STA
*
* @retval   Pointer to STA_RECORD_T
*/
/*----------------------------------------------------------------------------*/
P_STA_RECORD_T
bssCreateStaRecFromBssDesc(IN P_ADAPTER_T prAdapter,
			   IN ENUM_STA_TYPE_T eStaType, IN UINT_8 ucBssIndex, IN P_BSS_DESC_T prBssDesc)
{
	P_STA_RECORD_T prStaRec;
	UINT_8 ucNonHTPhyTypeSet;
	P_CONNECTION_SETTINGS_T prConnSettings;

	ASSERT(prBssDesc);

	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);

	/* 4 <1> Get a valid STA_RECORD_T */
	prStaRec = cnmGetStaRecByAddress(prAdapter, ucBssIndex, prBssDesc->aucSrcAddr);
	if (!prStaRec) {
		prStaRec = cnmStaRecAlloc(prAdapter, eStaType, ucBssIndex, prBssDesc->aucSrcAddr);

		if (!prStaRec) {
			DBGLOG(BSS, WARN,
			       "STA_REC entry is full, cannot acquire new entry for [" MACSTR
			       "]!!\n", MAC2STR(prBssDesc->aucSrcAddr));
			ASSERT(FALSE);
			return NULL;
		}

		prStaRec->ucStaState = STA_STATE_1;
		prStaRec->ucJoinFailureCount = 0;
		/* TODO(Kevin): If this is an old entry, we may also reset the ucJoinFailureCount to 0. */
	}
	/* 4 <2> Update information from BSS_DESC_T to current P_STA_RECORD_T */
	prStaRec->u2CapInfo = prBssDesc->u2CapInfo;

	prStaRec->u2OperationalRateSet = prBssDesc->u2OperationalRateSet;
	prStaRec->u2BSSBasicRateSet = prBssDesc->u2BSSBasicRateSet;

#if 1
	bssDetermineStaRecPhyTypeSet(prAdapter, prBssDesc, prStaRec);
#else
	prStaRec->ucPhyTypeSet = prBssDesc->ucPhyTypeSet;

	if (IS_STA_IN_AIS(prStaRec)) {
		if (!((prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_ENABLED) ||
		      (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_KEY_ABSENT)
		      || (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION_DISABLED)
		      || (prAdapter->prGlueInfo->u2WSCAssocInfoIELen)
#if CFG_SUPPORT_WAPI
		      || (prAdapter->prGlueInfo->u2WapiAssocInfoIESz)
#endif
		    )) {
			DBGLOG(BSS, INFO, "Ignore the HT Bit for TKIP as pairwise cipher configed!\n");
			prStaRec->ucPhyTypeSet &= ~PHY_TYPE_BIT_HT;
		}
	}

	prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prAdapter->rWifiVar.ucAvailablePhyTypeSet;
#endif

	ucNonHTPhyTypeSet = prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11ABG;

	/* Check for Target BSS's non HT Phy Types */
	if (ucNonHTPhyTypeSet) {

		if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_ERP) {
			prStaRec->ucNonHTBasicPhyType = PHY_TYPE_ERP_INDEX;
		} else if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_OFDM) {
			prStaRec->ucNonHTBasicPhyType = PHY_TYPE_OFDM_INDEX;
		} else {	/* if (ucNonHTPhyTypeSet & PHY_TYPE_HR_DSSS_INDEX) */

			prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX;
		}

		prStaRec->fgHasBasicPhyType = TRUE;
	} else {
		/* Use mandatory for 11N only BSS */
		ASSERT(prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N);

		{
			/* TODO(Kevin): which value should we set for 11n ? ERP ? */
			prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX;
		}

		prStaRec->fgHasBasicPhyType = FALSE;
	}

	/* Update non HT Desired Rate Set */
	prStaRec->u2DesiredNonHTRateSet = (prStaRec->u2OperationalRateSet & prConnSettings->u2DesiredNonHTRateSet);

	/* 4 <3> Update information from BSS_DESC_T to current P_STA_RECORD_T */
	if (IS_AP_STA(prStaRec)) {
		/* do not need to parse IE for DTIM,
		 * which have been parsed before inserting into BSS_DESC_T
		 */
		if (prBssDesc->ucDTIMPeriod)
			prStaRec->ucDTIMPeriod = prBssDesc->ucDTIMPeriod;
		else
			prStaRec->ucDTIMPeriod = 0;	/* Means that TIM was not parsed. */

	}
	/* 4 <4> Update default value */
	prStaRec->fgDiagnoseConnection = FALSE;

	/* 4 <5> Update default value for other Modules */
	/* Determine WMM related parameters for STA_REC */
	mqmProcessScanResult(prAdapter, prBssDesc, prStaRec);

	/* 4 <6> Update Tx Rate */
	/* Update default Tx rate */
	nicTxUpdateStaRecDefaultRate(prStaRec);

	return prStaRec;

}				/* end of bssCreateStaRecFromBssDesc() */

/*----------------------------------------------------------------------------*/
/*!
* @brief This function will compose the Null Data frame.
*
* @param[in] prAdapter              Pointer to the Adapter structure.
* @param[in] pucBuffer              Pointer to the frame buffer.
* @param[in] prStaRec               Pointer to the STA_RECORD_T.
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
VOID bssComposeNullFrame(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, IN P_STA_RECORD_T prStaRec)
{
	P_WLAN_MAC_HEADER_T prNullFrame;
	P_BSS_INFO_T prBssInfo;
	UINT_16 u2FrameCtrl;
	UINT_8 ucBssIndex;

	ASSERT(prStaRec);
	ucBssIndex = prStaRec->ucBssIndex;

	ASSERT(ucBssIndex <= MAX_BSS_INDEX);

	ASSERT(pucBuffer);

	prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex);
	ASSERT(prBssInfo);

	prNullFrame = (P_WLAN_MAC_HEADER_T) pucBuffer;

	/* 4 <1> Decide the Frame Control Field */
	u2FrameCtrl = MAC_FRAME_NULL;

	if (IS_AP_STA(prStaRec)) {
		u2FrameCtrl |= MASK_FC_TO_DS;

		if (prStaRec->fgSetPwrMgtBit)
			u2FrameCtrl |= MASK_FC_PWR_MGT;

	} else if (IS_CLIENT_STA(prStaRec)) {
		u2FrameCtrl |= MASK_FC_FROM_DS;
	} else if (IS_DLS_STA(prStaRec)) {
		/* TODO(Kevin) */
	} else {
		/* NOTE(Kevin): We won't send Null frame for IBSS */
		ASSERT(0);
		return;
	}

	/* 4 <2> Compose the Null frame */
	/* Fill the Frame Control field. */
	/* WLAN_SET_FIELD_16(&prNullFrame->u2FrameCtrl, u2FrameCtrl); */
	prNullFrame->u2FrameCtrl = u2FrameCtrl;	/* NOTE(Kevin): Optimized for ARM */

	/* Fill the Address 1 field with Target Peer Address. */
	COPY_MAC_ADDR(prNullFrame->aucAddr1, prStaRec->aucMacAddr);

	/* Fill the Address 2 field with our MAC Address. */
	COPY_MAC_ADDR(prNullFrame->aucAddr2, prBssInfo->aucOwnMacAddr);

	/* Fill the Address 3 field with Target BSSID. */
	COPY_MAC_ADDR(prNullFrame->aucAddr3, prBssInfo->aucBSSID);

	/* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */
	prNullFrame->u2SeqCtrl = 0;

	return;

}				/* end of bssComposeNullFrameHeader() */

/*----------------------------------------------------------------------------*/
/*!
* @brief This function will compose the QoS Null Data frame.
*
* @param[in] prAdapter              Pointer to the Adapter structure.
* @param[in] pucBuffer              Pointer to the frame buffer.
* @param[in] prStaRec               Pointer to the STA_RECORD_T.
* @param[in] ucUP                   User Priority.
* @param[in] fgSetEOSP              Set the EOSP bit.
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
VOID
bssComposeQoSNullFrame(IN P_ADAPTER_T prAdapter,
		       IN PUINT_8 pucBuffer, IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUP, IN BOOLEAN fgSetEOSP)
{
	P_WLAN_MAC_HEADER_QOS_T prQoSNullFrame;
	P_BSS_INFO_T prBssInfo;
	UINT_16 u2FrameCtrl;
	UINT_16 u2QosControl;
	UINT_8 ucBssIndex;

	ASSERT(prStaRec);
	ucBssIndex = prStaRec->ucBssIndex;

	ASSERT(ucBssIndex <= MAX_BSS_INDEX);

	ASSERT(pucBuffer);

	prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex);
	ASSERT(prBssInfo);

	prQoSNullFrame = (P_WLAN_MAC_HEADER_QOS_T) pucBuffer;

	/* 4 <1> Decide the Frame Control Field */
	u2FrameCtrl = MAC_FRAME_QOS_NULL;

	if (IS_AP_STA(prStaRec)) {
		u2FrameCtrl |= MASK_FC_TO_DS;

		if (prStaRec->fgSetPwrMgtBit)
			u2FrameCtrl |= MASK_FC_PWR_MGT;

	} else if (IS_CLIENT_STA(prStaRec)) {
		u2FrameCtrl |= MASK_FC_FROM_DS;
	} else if (IS_DLS_STA(prStaRec)) {
		/* TODO(Kevin) */
	} else {
		/* NOTE(Kevin): We won't send QoS Null frame for IBSS */
		ASSERT(0);
		return;
	}

	/* 4 <2> Compose the QoS Null frame */
	/* Fill the Frame Control field. */
	/* WLAN_SET_FIELD_16(&prQoSNullFrame->u2FrameCtrl, u2FrameCtrl); */
	prQoSNullFrame->u2FrameCtrl = u2FrameCtrl;	/* NOTE(Kevin): Optimized for ARM */

	/* Fill the Address 1 field with Target Peer Address. */
	COPY_MAC_ADDR(prQoSNullFrame->aucAddr1, prStaRec->aucMacAddr);

	/* Fill the Address 2 field with our MAC Address. */
	COPY_MAC_ADDR(prQoSNullFrame->aucAddr2, prBssInfo->aucOwnMacAddr);

	/* Fill the Address 3 field with Target BSSID. */
	COPY_MAC_ADDR(prQoSNullFrame->aucAddr3, prBssInfo->aucBSSID);

	/* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */
	prQoSNullFrame->u2SeqCtrl = 0;

	u2QosControl = (UINT_16) (ucUP & WMM_QC_UP_MASK);

	if (fgSetEOSP)
		u2QosControl |= WMM_QC_EOSP;

	/* WLAN_SET_FIELD_16(&prQoSNullFrame->u2QosCtrl, u2QosControl); */
	prQoSNullFrame->u2QosCtrl = u2QosControl;	/* NOTE(Kevin): Optimized for ARM */

	return;

}				/* end of bssComposeQoSNullFrameHeader() */

/*----------------------------------------------------------------------------*/
/*!
* @brief Send the Null Frame
*
* @param[in] prAdapter          Pointer to the Adapter structure.
* @param[in] prStaRec           Pointer to the STA_RECORD_T
* @param[in] pfTxDoneHandler    TX Done call back function
*
* @retval WLAN_STATUS_RESOURCE  No available resources to send frame.
* @retval WLAN_STATUS_SUCCESS   Succe]ss.
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
bssSendNullFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler)
{
	P_MSDU_INFO_T prMsduInfo;
	UINT_16 u2EstimatedFrameLen;

	/* 4 <1> Allocate a PKT_INFO_T for Null Frame */
	/* Init with MGMT Header Length */
	u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_LEN;

	/* Allocate a MSDU_INFO_T */
	prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen);
	if (prMsduInfo == NULL) {
		DBGLOG(BSS, WARN, "No PKT_INFO_T for sending Null Frame.\n");
		return WLAN_STATUS_RESOURCES;
	}
	/* 4 <2> Compose Null frame in MSDU_INfO_T. */
	bssComposeNullFrame(prAdapter, (PUINT_8) ((ULONG) prMsduInfo->prPacket + MAC_TX_RESERVED_FIELD), prStaRec);
#if 0
	/* 4 <3> Update information of MSDU_INFO_T */
	TXM_SET_DATA_PACKET(
				   /* STA_REC ptr */ prStaRec,
				   /* MSDU_INFO ptr */ prMsduInfo,
				   /* MAC HDR ptr */
				   (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD),
				   /* MAC HDR length */ WLAN_MAC_HEADER_LEN,
				   /* PAYLOAD ptr */
				   (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_LEN),
				   /* PAYLOAD length */ 0,
				   /* Network Type Index */ (UINT_8) prStaRec->ucNetTypeIndex,
				   /* TID */ 0 /* BE: AC1 */,
				   /* Flag 802.11 */ TRUE,
				   /* Pkt arrival time */ 0 /* TODO: Obtain the system time */,
				   /* Resource TC */ 0 /* Irrelevant */,
				   /* Flag 802.1x */ FALSE,
				   /* TX-done callback */ pfTxDoneHandler,
				   /* PS forwarding type */ PS_FORWARDING_TYPE_NON_PS,
				   /* PS Session ID */ 0 /* Irrelevant */,
				   /* Flag fixed rate */ TRUE,
				   /* Fixed tx rate */
				   g_aprBssInfo[prStaRec->ucNetTypeIndex]->ucHwDefaultFixedRateCode,
				   /* Fixed-rate retry */
				   BSS_DEFAULT_CONN_TEST_NULL_FRAME_RETRY_LIMIT,
				   /* PAL LLH */ 0 /* Irrelevant */,
				   /* ACL SN */ 0 /* Irrelevant */,
				   /* Flag No Ack */ FALSE
	    );

	/* Terminate with a NULL pointer */
	NIC_HIF_TX_SET_NEXT_MSDU_INFO(prMsduInfo, NULL);

	/* TODO(Kevin): Also release the unused tail room of the composed MMPDU */

	/* Indicate the packet to TXM */
	/* 4 <4> Inform TXM to send this Null frame. */
	txmSendFwDataPackets(prMsduInfo);
#endif

	TX_SET_MMPDU(prAdapter,
		     prMsduInfo,
		     prStaRec->ucBssIndex,
		     prStaRec->ucIndex, WLAN_MAC_HEADER_LEN, WLAN_MAC_HEADER_LEN, pfTxDoneHandler, MSDU_RATE_MODE_AUTO);

	/* 4 <4> Inform TXM  to send this Null frame. */
	nicTxEnqueueMsdu(prAdapter, prMsduInfo);

	return WLAN_STATUS_SUCCESS;

}				/* end of bssSendNullFrame() */

/*----------------------------------------------------------------------------*/
/*!
* @brief Send the QoS Null Frame
*
* @param[in] prAdapter          Pointer to the Adapter structure.
* @param[in] prStaRec           Pointer to the STA_RECORD_T
* @param[in] pfTxDoneHandler    TX Done call back function
*
* @retval WLAN_STATUS_RESOURCE  No available resources to send frame.
* @retval WLAN_STATUS_SUCCESS   Success.
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
bssSendQoSNullFrame(IN P_ADAPTER_T prAdapter,
		    IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUP, IN PFN_TX_DONE_HANDLER pfTxDoneHandler)
{
	P_MSDU_INFO_T prMsduInfo;
	UINT_16 u2EstimatedFrameLen;

	/* 4 <1> Allocate a PKT_INFO_T for Null Frame */
	/* Init with MGMT Header Length */
	u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_QOS_LEN;

	/* Allocate a MSDU_INFO_T */
	prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen);
	if (prMsduInfo == NULL) {
		DBGLOG(BSS, WARN, "No PKT_INFO_T for sending Null Frame.\n");
		return WLAN_STATUS_RESOURCES;
	}
	/* 4 <2> Compose Null frame in MSDU_INfO_T. */
	bssComposeQoSNullFrame(prAdapter,
			       (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD),
			       prStaRec, ucUP, FALSE);
#if 0
	/* 4 <3> Update information of MSDU_INFO_T */
	TXM_SET_DATA_PACKET(
				   /* STA_REC ptr */ prStaRec,
				   /* MSDU_INFO ptr */ prMsduInfo,
				   /* MAC HDR ptr */
				   (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD),
				   /* MAC HDR length */ WLAN_MAC_HEADER_QOS_LEN,
				   /* PAYLOAD ptr */
				   (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_QOS_LEN),
				   /* PAYLOAD length */ 0,
				   /* Network Type Index */ (UINT_8) prStaRec->ucNetTypeIndex,
				   /* TID */ 0 /* BE: AC1 */,
				   /* Flag 802.11 */ TRUE,
				   /* Pkt arrival time */ 0 /* TODO: Obtain the system time */,
				   /* Resource TC */ 0 /* Irrelevant */,
				   /* Flag 802.1x */ FALSE,
				   /* TX-done callback */ pfTxDoneHandler,
				   /* PS forwarding type */ PS_FORWARDING_TYPE_NON_PS,
				   /* PS Session ID */ 0 /* Irrelevant */,
				   /* Flag fixed rate */ TRUE,
				   /* Fixed tx rate */
				   g_aprBssInfo[prStaRec->ucNetTypeIndex]->ucHwDefaultFixedRateCode,
				   /* Fixed-rate retry */ TXM_DEFAULT_DATA_FRAME_RETRY_LIMIT,
				   /* PAL LLH */ 0 /* Irrelevant */,
				   /* ACL SN */ 0 /* Irrelevant */,
				   /* Flag No Ack */ FALSE
	    );

	/* Terminate with a NULL pointer */
	NIC_HIF_TX_SET_NEXT_MSDU_INFO(prMsduInfo, NULL);

	/* TODO(Kevin): Also release the unused tail room of the composed MMPDU */

	/* Indicate the packet to TXM */
	/* 4 <4> Inform TXM to send this Null frame. */
	txmSendFwDataPackets(prMsduInfo);
#endif

	TX_SET_MMPDU(prAdapter,
		     prMsduInfo,
		     prStaRec->ucBssIndex,
		     prStaRec->ucIndex,
		     WLAN_MAC_HEADER_QOS_LEN, WLAN_MAC_HEADER_QOS_LEN, pfTxDoneHandler, MSDU_RATE_MODE_AUTO);

	/* 4 <4> Inform TXM  to send this Null frame. */
	nicTxEnqueueMsdu(prAdapter, prMsduInfo);

	return WLAN_STATUS_SUCCESS;

}				/* end of bssSendQoSNullFrame() */

#if (CFG_SUPPORT_ADHOC) || (CFG_SUPPORT_AAA)
/*----------------------------------------------------------------------------*/
/* Routines for both IBSS(AdHoc) and BSS(AP)                                  */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/*!
* @brief This function is used to generate Information Elements of Extended
*        Support Rate
*
* @param[in] prAdapter      Pointer to the Adapter structure.
* @param[in] prMsduInfo     Pointer to the composed MSDU_INFO_T.
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
VOID bssGenerateExtSuppRate_IE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
{
	P_BSS_INFO_T prBssInfo;
	PUINT_8 pucBuffer;
	UINT_8 ucExtSupRatesLen;

	ASSERT(prMsduInfo);

	prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prMsduInfo->ucBssIndex);
	ASSERT(prBssInfo);

	pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (ULONG) prMsduInfo->u2FrameLength);
	ASSERT(pucBuffer);

	if (prBssInfo->ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES)

		ucExtSupRatesLen = prBssInfo->ucAllSupportedRatesLen - ELEM_MAX_LEN_SUP_RATES;
	else
		ucExtSupRatesLen = 0;

	/* Fill the Extended Supported Rates element. */
	if (ucExtSupRatesLen) {

		EXT_SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_EXTENDED_SUP_RATES;
		EXT_SUP_RATES_IE(pucBuffer)->ucLength = ucExtSupRatesLen;

		kalMemCopy(EXT_SUP_RATES_IE(pucBuffer)->aucExtSupportedRates,
			   &prBssInfo->aucAllSupportedRates[ELEM_MAX_LEN_SUP_RATES], ucExtSupRatesLen);

		prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
	}
}				/* end of bssGenerateExtSuppRate_IE() */

/*----------------------------------------------------------------------------*/
/*!
* @brief This function is used to compose Common Information Elements for Beacon
*        or Probe Response Frame.
*
* @param[in] prMsduInfo     Pointer to the composed MSDU_INFO_T.
* @param[in] prBssInfo      Pointer to the BSS_INFO_T.
* @param[in] pucDestAddr    Pointer to the Destination Address, if NULL, means Beacon.
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
VOID
bssBuildBeaconProbeRespFrameCommonIEs(IN P_MSDU_INFO_T prMsduInfo, IN P_BSS_INFO_T prBssInfo, IN PUINT_8 pucDestAddr)
{
	PUINT_8 pucBuffer;
	UINT_8 ucSupRatesLen;

	ASSERT(prMsduInfo);
	ASSERT(prBssInfo);

	pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (ULONG) prMsduInfo->u2FrameLength);
	ASSERT(pucBuffer);

	/* Compose the frame body of the Probe Response frame. */
	/* 4 <1> Fill the SSID element. */
	SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID;
#if 0
	SSID_IE(pucBuffer)->ucLength = prBssInfo->ucSSIDLen;
	if (prBssInfo->ucSSIDLen)
		kalMemCopy(SSID_IE(pucBuffer)->aucSSID, prBssInfo->aucSSID, prBssInfo->ucSSIDLen);
#else
	if (prBssInfo->eHiddenSsidType == ENUM_HIDDEN_SSID_LEN) {
		if ((!pucDestAddr) &&	/* For Beacon only. */
		    (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) {
			SSID_IE(pucBuffer)->ucLength = 0;
		} else {	/* probe response */
			SSID_IE(pucBuffer)->ucLength = prBssInfo->ucSSIDLen;
			if (prBssInfo->ucSSIDLen)
				kalMemCopy(SSID_IE(pucBuffer)->aucSSID, prBssInfo->aucSSID, prBssInfo->ucSSIDLen);
		}
	} else {
		SSID_IE(pucBuffer)->ucLength = prBssInfo->ucSSIDLen;
		if (prBssInfo->ucSSIDLen)
			kalMemCopy(SSID_IE(pucBuffer)->aucSSID, prBssInfo->aucSSID, prBssInfo->ucSSIDLen);
	}
#endif

	prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
	pucBuffer += IE_SIZE(pucBuffer);

	/* 4 <2> Fill the Supported Rates element. */
	if (prBssInfo->ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES)

		ucSupRatesLen = ELEM_MAX_LEN_SUP_RATES;
	else
		ucSupRatesLen = prBssInfo->ucAllSupportedRatesLen;

	if (ucSupRatesLen) {
		SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_SUP_RATES;
		SUP_RATES_IE(pucBuffer)->ucLength = ucSupRatesLen;
		kalMemCopy(SUP_RATES_IE(pucBuffer)->aucSupportedRates, prBssInfo->aucAllSupportedRates, ucSupRatesLen);

		prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
		pucBuffer += IE_SIZE(pucBuffer);
	}

	/* 4 <3> Fill the DS Parameter Set element. */
	if (prBssInfo->eBand == BAND_2G4) {
		DS_PARAM_IE(pucBuffer)->ucId = ELEM_ID_DS_PARAM_SET;
		DS_PARAM_IE(pucBuffer)->ucLength = ELEM_MAX_LEN_DS_PARAMETER_SET;
		DS_PARAM_IE(pucBuffer)->ucCurrChnl = prBssInfo->ucPrimaryChannel;

		prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
		pucBuffer += IE_SIZE(pucBuffer);
	}

	/* 4 <4> IBSS Parameter Set element, ID: 6 */
	if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) {
		IBSS_PARAM_IE(pucBuffer)->ucId = ELEM_ID_IBSS_PARAM_SET;
		IBSS_PARAM_IE(pucBuffer)->ucLength = ELEM_MAX_LEN_IBSS_PARAMETER_SET;
		WLAN_SET_FIELD_16(&(IBSS_PARAM_IE(pucBuffer)->u2ATIMWindow), prBssInfo->u2ATIMWindow);

		prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
		pucBuffer += IE_SIZE(pucBuffer);
	}

	/* 4 <5> TIM element, ID: 5 */
	if ((!pucDestAddr) &&	/* For Beacon only. */
	    (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) {

#if CFG_ENABLE_WIFI_DIRECT
		/*no fgIsP2PRegistered protect */
		if (prBssInfo->eNetworkType == NETWORK_TYPE_P2P) {
#if 0
			P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo;
			UINT_8 ucBitmapControl = 0;
			UINT_32 u4N1, u4N2;

			prP2pSpecificBssInfo = &(prAdapter->rWifiVar.rP2pSpecificBssInfo);

			/* Clear existing value. */
			prP2pSpecificBssInfo->ucBitmapCtrl = 0;
			kalMemZero(prP2pSpecificBssInfo->aucPartialVirtualBitmap,
				   sizeof(prP2pSpecificBssInfo->aucPartialVirtualBitmap));

			/* IEEE 802.11 2007 - 7.3.2.6 */
			TIM_IE(pucBuffer)->ucId = ELEM_ID_TIM;
			TIM_IE(pucBuffer)->ucDTIMCount = prBssInfo->ucDTIMCount;
			TIM_IE(pucBuffer)->ucDTIMPeriod = prBssInfo->ucDTIMPeriod;

			/* Setup DTIM Count for next TBTT. */
			if (prBssInfo->ucDTIMCount == 0)
				/* 3 *** pmQueryBufferedBCAST(); */

				/* 3 *** pmQueryBufferedPSNode(); */
				/* TODO(Kevin): Call PM Module here to loop all STA_RECORD_Ts and it
				 * will call bssSetTIMBitmap to toggle the Bitmap.
				 */

				/* Set Virtual Bitmap for UCAST */
				/* Find the smallest number. */
				/* Find the largest even number. */
				u4N1 = (prP2pSpecificBssInfo->u2SmallestAID >> 4) << 1;
			u4N2 = prP2pSpecificBssInfo->u2LargestAID >> 3;

			ASSERT(u4N2 >= u4N1);

			kalMemCopy(TIM_IE(pucBuffer)->aucPartialVirtualMap,
				   &prP2pSpecificBssInfo->aucPartialVirtualBitmap[u4N1], ((u4N2 - u4N1) + 1));

			/* Set Virtual Bitmap for BMCAST */
			/* BMC bit only indicated when DTIM count == 0. */
			if (prBssInfo->ucDTIMCount == 0)
				ucBitmapControl = prP2pSpecificBssInfo->ucBitmapCtrl;

			TIM_IE(pucBuffer)->ucBitmapControl = ucBitmapControl | (UINT_8) u4N1;

			TIM_IE(pucBuffer)->ucLength = ((u4N2 - u4N1) + 4);

			prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
#else

			/* IEEE 802.11 2007 - 7.3.2.6 */
			TIM_IE(pucBuffer)->ucId = ELEM_ID_TIM;
			/* NOTE: fixed PVB length (AID is allocated from 8 ~ 15 only) */
			TIM_IE(pucBuffer)->ucLength = (3 + MAX_LEN_TIM_PARTIAL_BMP) /*((u4N2 - u4N1) + 4) */;
			TIM_IE(pucBuffer)->ucDTIMCount = 0 /*prBssInfo->ucDTIMCount */;
			/* will be overwritten by FW */
			TIM_IE(pucBuffer)->ucDTIMPeriod = prBssInfo->ucDTIMPeriod;
			/* will be overwritten by FW */
			TIM_IE(pucBuffer)->ucBitmapControl = 0 /*ucBitmapControl | (UINT_8)u4N1 */;

			prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);

#endif

		} else
#endif /* CFG_ENABLE_WIFI_DIRECT */
		{
			/* NOTE(Kevin): 1. AIS - Didn't Support AP Mode.
			 *              2. BOW - Didn't Support BCAST and PS.
			 */
		}

	}
}				/* end of bssBuildBeaconProbeRespFrameCommonIEs() */

/*----------------------------------------------------------------------------*/
/*!
* @brief This function will compose the Beacon/Probe Response frame header and
*        its fixed fields.
*
* @param[in] pucBuffer              Pointer to the frame buffer.
* @param[in] pucDestAddr            Pointer to the Destination Address, if NULL, means Beacon.
* @param[in] pucOwnMACAddress       Given Our MAC Address.
* @param[in] pucBSSID               Given BSSID of the BSS.
* @param[in] u2BeaconInterval       Given Beacon Interval.
* @param[in] u2CapInfo              Given Capability Info.
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
VOID
bssComposeBeaconProbeRespFrameHeaderAndFF(IN PUINT_8 pucBuffer,
					  IN PUINT_8 pucDestAddr,
					  IN PUINT_8 pucOwnMACAddress,
					  IN PUINT_8 pucBSSID, IN UINT_16 u2BeaconInterval, IN UINT_16 u2CapInfo)
{
	P_WLAN_BEACON_FRAME_T prBcnProbRspFrame;
	UINT_8 aucBCAddr[] = BC_MAC_ADDR;
	UINT_16 u2FrameCtrl;

	DEBUGFUNC("bssComposeBeaconProbeRespFrameHeaderAndFF");
	/* DBGLOG(INIT, LOUD, ("\n")); */

	ASSERT(pucBuffer);
	ASSERT(pucOwnMACAddress);
	ASSERT(pucBSSID);

	prBcnProbRspFrame = (P_WLAN_BEACON_FRAME_T) pucBuffer;

	/* 4 <1> Compose the frame header of the Beacon /ProbeResp frame. */
	/* Fill the Frame Control field. */
	if (pucDestAddr) {
		u2FrameCtrl = MAC_FRAME_PROBE_RSP;
	} else {
		u2FrameCtrl = MAC_FRAME_BEACON;
		pucDestAddr = aucBCAddr;
	}
	/* WLAN_SET_FIELD_16(&prBcnProbRspFrame->u2FrameCtrl, u2FrameCtrl); */
	prBcnProbRspFrame->u2FrameCtrl = u2FrameCtrl;	/* NOTE(Kevin): Optimized for ARM */

	/* Fill the DA field with BCAST MAC ADDR or TA of ProbeReq. */
	COPY_MAC_ADDR(prBcnProbRspFrame->aucDestAddr, pucDestAddr);

	/* Fill the SA field with our MAC Address. */
	COPY_MAC_ADDR(prBcnProbRspFrame->aucSrcAddr, pucOwnMACAddress);

	/* Fill the BSSID field with current BSSID. */
	COPY_MAC_ADDR(prBcnProbRspFrame->aucBSSID, pucBSSID);

	/* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */
	prBcnProbRspFrame->u2SeqCtrl = 0;

	/* 4 <2> Compose the frame body's common fixed field part of the Beacon /ProbeResp frame. */
	/* MAC will update TimeStamp field */

	/* Fill the Beacon Interval field. */
	/* WLAN_SET_FIELD_16(&prBcnProbRspFrame->u2BeaconInterval, u2BeaconInterval); */
	prBcnProbRspFrame->u2BeaconInterval = u2BeaconInterval;	/* NOTE(Kevin): Optimized for ARM */

	/* Fill the Capability Information field. */
	/* WLAN_SET_FIELD_16(&prBcnProbRspFrame->u2CapInfo, u2CapInfo); */
	prBcnProbRspFrame->u2CapInfo = u2CapInfo;	/* NOTE(Kevin): Optimized for ARM */
}				/* end of bssComposeBeaconProbeRespFrameHeaderAndFF() */

/*----------------------------------------------------------------------------*/
/*!
* @brief Update the Beacon Frame Template to FW for AIS AdHoc and P2P GO.
*
* @param[in] prAdapter          Pointer to the Adapter structure.
* @param[in] ucBssIndex         Specify which network reply the Probe Response.
*
* @retval WLAN_STATUS_SUCCESS   Success.
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS bssUpdateBeaconContent(IN P_ADAPTER_T prAdapter, IN UINT_8 ucBssIndex)
{
	P_BSS_INFO_T prBssInfo;
	P_MSDU_INFO_T prMsduInfo;
	P_WLAN_BEACON_FRAME_T prBcnFrame;
	UINT_32 i;

	DEBUGFUNC("bssUpdateBeaconContent");
	DBGLOG(INIT, LOUD, "\n");

	ASSERT(ucBssIndex <= MAX_BSS_INDEX);

	prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex);

	/* 4 <1> Allocate a PKT_INFO_T for Beacon Frame */
	/* Allocate a MSDU_INFO_T */
	/* For Beacon */
	prMsduInfo = prBssInfo->prBeacon;

	/* beacon prMsduInfo will be NULLify once BSS deactivated, so skip if it is */
	if (prMsduInfo == NULL)
		return WLAN_STATUS_SUCCESS;

	/* 4 <2> Compose header */
	bssComposeBeaconProbeRespFrameHeaderAndFF((PUINT_8)
						  ((ULONG) (prMsduInfo->prPacket) +
						   MAC_TX_RESERVED_FIELD), NULL,
						  prBssInfo->aucOwnMacAddr, prBssInfo->aucBSSID,
						  prBssInfo->u2BeaconInterval, prBssInfo->u2CapInfo);

	prMsduInfo->u2FrameLength = (WLAN_MAC_MGMT_HEADER_LEN +
				     (TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN));

	prMsduInfo->ucBssIndex = ucBssIndex;

	/* 4 <3> Compose the frame body's Common IEs of the Beacon frame. */
	bssBuildBeaconProbeRespFrameCommonIEs(prMsduInfo, prBssInfo, NULL);

	/* 4 <4> Compose IEs in MSDU_INFO_T */

	/* Append IE for Beacon */
	for (i = 0; i < sizeof(txBcnIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) {
		if (txBcnIETable[i].pfnAppendIE)
			txBcnIETable[i].pfnAppendIE(prAdapter, prMsduInfo);

	}

	prBcnFrame = (P_WLAN_BEACON_FRAME_T) prMsduInfo->prPacket;

	return nicUpdateBeaconIETemplate(prAdapter,
					 IE_UPD_METHOD_UPDATE_ALL,
					 ucBssIndex,
					 prBssInfo->u2CapInfo,
					 (PUINT_8) prBcnFrame->aucInfoElem,
					 prMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem));

}				/* end of bssUpdateBeaconContent() */

/*----------------------------------------------------------------------------*/
/*!
* @brief Send the Beacon Frame(for BOW) or Probe Response Frame according to the given
*        Destination Address.
*
* @param[in] prAdapter          Pointer to the Adapter structure.
* @param[in] ucBssIndex         Specify which network reply the Probe Response.
* @param[in] pucDestAddr        Pointer to the Destination Address to reply
* @param[in] u4ControlFlags     Control flags for information on Probe Response.
*
* @retval WLAN_STATUS_RESOURCE  No available resources to send frame.
* @retval WLAN_STATUS_SUCCESS   Success.
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS
bssSendBeaconProbeResponse(IN P_ADAPTER_T prAdapter,
			   IN UINT_8 ucBssIndex, IN PUINT_8 pucDestAddr, IN UINT_32 u4ControlFlags)
{
	P_BSS_INFO_T prBssInfo;
	P_MSDU_INFO_T prMsduInfo;
	UINT_16 u2EstimatedFrameLen;
	UINT_16 u2EstimatedFixedIELen;
	UINT_16 u2EstimatedExtraIELen;
	P_APPEND_VAR_IE_ENTRY_T prIeArray = NULL;
	UINT_32 u4IeArraySize = 0;
	UINT_32 i;

	ASSERT(ucBssIndex <= MAX_BSS_INDEX);

	prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex);

	if (!pucDestAddr) {	/* For Beacon */
		prIeArray = &txBcnIETable[0];
		u4IeArraySize = sizeof(txBcnIETable) / sizeof(APPEND_VAR_IE_ENTRY_T);
	} else {
		prIeArray = &txProbRspIETable[0];
		u4IeArraySize = sizeof(txProbRspIETable) / sizeof(APPEND_VAR_IE_ENTRY_T);
	}

	/* 4 <1> Allocate a PKT_INFO_T for Beacon /Probe Response Frame */
	/* Allocate a MSDU_INFO_T */

	/* Init with MGMT Header Length + Length of Fixed Fields + Common IE Fields */
	u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD +
	    WLAN_MAC_MGMT_HEADER_LEN +
	    TIMESTAMP_FIELD_LEN +
	    BEACON_INTERVAL_FIELD_LEN +
	    CAP_INFO_FIELD_LEN +
	    (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) +
	    (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) +
	    (ELEM_HDR_LEN + ELEM_MAX_LEN_DS_PARAMETER_SET) +
	    (ELEM_HDR_LEN + ELEM_MAX_LEN_IBSS_PARAMETER_SET) + (ELEM_HDR_LEN + (3 + MAX_LEN_TIM_PARTIAL_BMP));

	/* + Extra IE Length */
	u2EstimatedExtraIELen = 0;

	for (i = 0; i < u4IeArraySize; i++) {
		u2EstimatedFixedIELen = prIeArray[i].u2EstimatedFixedIELen;

		if (u2EstimatedFixedIELen) {
			u2EstimatedExtraIELen += u2EstimatedFixedIELen;
		} else {
			ASSERT(prIeArray[i].pfnCalculateVariableIELen);

			u2EstimatedExtraIELen += (UINT_16)
			    prIeArray[i].pfnCalculateVariableIELen(prAdapter, ucBssIndex, NULL);
		}
	}

	u2EstimatedFrameLen += u2EstimatedExtraIELen;
	prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen);
	if (prMsduInfo == NULL) {
		DBGLOG(BSS, WARN, "No PKT_INFO_T for sending %s.\n", ((!pucDestAddr) ? "Beacon" : "Probe Response"));
		return WLAN_STATUS_RESOURCES;
	}

	/* 4 <2> Compose Beacon/Probe Response frame header and fixed fields in MSDU_INfO_T. */
	/* Compose Header and Fixed Field */
#if CFG_ENABLE_WIFI_DIRECT
	if (u4ControlFlags & BSS_PROBE_RESP_USE_P2P_DEV_ADDR) {
		if (prAdapter->fgIsP2PRegistered) {
			bssComposeBeaconProbeRespFrameHeaderAndFF((PUINT_8)
								  ((ULONG) (prMsduInfo->prPacket)
								   + MAC_TX_RESERVED_FIELD),
								  pucDestAddr,
								  prAdapter->rWifiVar.aucDeviceAddress,
								  prAdapter->rWifiVar.aucDeviceAddress,
								  DOT11_BEACON_PERIOD_DEFAULT,
								  (prBssInfo->u2CapInfo & ~(CAP_INFO_ESS |
											    CAP_INFO_IBSS)));
		}
	} else
#endif /* CFG_ENABLE_WIFI_DIRECT */
	{
		bssComposeBeaconProbeRespFrameHeaderAndFF((PUINT_8)
							  ((ULONG) (prMsduInfo->prPacket) +
							   MAC_TX_RESERVED_FIELD), pucDestAddr,
							  prBssInfo->aucOwnMacAddr,
							  prBssInfo->aucBSSID,
							  prBssInfo->u2BeaconInterval, prBssInfo->u2CapInfo);
	}

	/* 4 <3> Update information of MSDU_INFO_T */

	TX_SET_MMPDU(prAdapter,
		     prMsduInfo,
		     ucBssIndex,
		     STA_REC_INDEX_NOT_FOUND,
		     WLAN_MAC_MGMT_HEADER_LEN,
		     (WLAN_MAC_MGMT_HEADER_LEN + TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN +
		      CAP_INFO_FIELD_LEN), NULL, MSDU_RATE_MODE_AUTO);

	/* 4 <4> Compose the frame body's Common IEs of the Beacon/ProbeResp  frame. */
	bssBuildBeaconProbeRespFrameCommonIEs(prMsduInfo, prBssInfo, pucDestAddr);

	/* 4 <5> Compose IEs in MSDU_INFO_T */

	/* Append IE */
	for (i = 0; i < u4IeArraySize; i++) {
		if (prIeArray[i].pfnAppendIE)
			prIeArray[i].pfnAppendIE(prAdapter, prMsduInfo);

	}

	/* Set limited retry count and lifetime for Probe Resp is reasonable */
	nicTxSetPktLifeTime(prMsduInfo, 100);
	nicTxSetPktRetryLimit(prMsduInfo, 2);

	/* TODO(Kevin): Also release the unused tail room of the composed MMPDU */

	/* 4 <6> Inform TXM  to send this Beacon /Probe Response frame. */
	nicTxEnqueueMsdu(prAdapter, prMsduInfo);

	return WLAN_STATUS_SUCCESS;

}				/* end of bssSendBeaconProbeResponse() */

/*----------------------------------------------------------------------------*/
/*!
* @brief This function will process the Rx Probe Request Frame and then send
*        back the corresponding Probe Response Frame if the specified conditions
*        were matched.
*
* @param[in] prAdapter          Pointer to the Adapter structure.
* @param[in] prSwRfb            Pointer to SW RFB data structure.
*
* @retval WLAN_STATUS_SUCCESS   Always return success
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS bssProcessProbeRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
{
	P_WLAN_MAC_MGMT_HEADER_T prMgtHdr;
	P_BSS_INFO_T prBssInfo;
	UINT_8 ucBssIndex;
	UINT_8 aucBCBSSID[] = BC_BSSID;
	BOOLEAN fgIsBcBssid;
	BOOLEAN fgReplyProbeResp;
	UINT_32 u4CtrlFlagsForProbeResp = 0;
	ENUM_BAND_T eBand;
	UINT_8 ucHwChannelNum;

	ASSERT(prSwRfb);

	/* 4 <1> Parse Probe Req and Get BSSID */
	prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader;

	if (EQUAL_MAC_ADDR(aucBCBSSID, prMgtHdr->aucBSSID))
		fgIsBcBssid = TRUE;
	else
		fgIsBcBssid = FALSE;

	/* 4 <2> Check network conditions before reply Probe Response Frame (Consider Concurrent) */
	for (ucBssIndex = 0; ucBssIndex <= P2P_DEV_BSS_INDEX; ucBssIndex++) {

		if (!IS_NET_ACTIVE(prAdapter, ucBssIndex))
			continue;

		prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex);

		if ((!fgIsBcBssid) && UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prMgtHdr->aucBSSID))
			continue;

		eBand = HAL_RX_STATUS_GET_RF_BAND(prSwRfb->prRxStatus);
		ucHwChannelNum = HAL_RX_STATUS_GET_CHNL_NUM(prSwRfb->prRxStatus);

		if (prBssInfo->eBand != eBand)
			continue;

		if (prBssInfo->ucPrimaryChannel != ucHwChannelNum)
			continue;

		fgReplyProbeResp = FALSE;

		if (prBssInfo->eNetworkType == NETWORK_TYPE_AIS) {

#if CFG_SUPPORT_ADHOC
			fgReplyProbeResp = aisValidateProbeReq(prAdapter, prSwRfb, &u4CtrlFlagsForProbeResp);
#endif
		}
#if CFG_ENABLE_WIFI_DIRECT
		else if ((prAdapter->fgIsP2PRegistered) && (prBssInfo->eNetworkType == NETWORK_TYPE_P2P)) {

			fgReplyProbeResp =
			    p2pFuncValidateProbeReq(prAdapter, prSwRfb, &u4CtrlFlagsForProbeResp,
						    (prBssInfo->ucBssIndex == P2P_DEV_BSS_INDEX),
						    (UINT_8) prBssInfo->u4PrivateData);
		}
#endif
#if CFG_ENABLE_BT_OVER_WIFI
		else if (prBssInfo->eNetworkType == NETWORK_TYPE_BOW)
			fgReplyProbeResp = bowValidateProbeReq(prAdapter, prSwRfb, &u4CtrlFlagsForProbeResp);
#endif

		if (fgReplyProbeResp) {
			if (nicTxGetFreeCmdCount(prAdapter) > (CFG_TX_MAX_CMD_PKT_NUM / 2)) {
				/* Resource margin is enough */
				bssSendBeaconProbeResponse(prAdapter, ucBssIndex,
							   prMgtHdr->aucSrcAddr, u4CtrlFlagsForProbeResp);
			}
		}
	}

	return WLAN_STATUS_SUCCESS;

}				/* end of bssProcessProbeRequest() */

#if 0				/* NOTE(Kevin): condition check should move to P2P_FSM.c */
/*----------------------------------------------------------------------------*/
/*!
* @brief This function will process the Rx Probe Request Frame and then send
*        back the corresponding Probe Response Frame if the specified conditions
*        were matched.
*
* @param[in] prSwRfb            Pointer to SW RFB data structure.
*
* @retval WLAN_STATUS_SUCCESS   Always return success
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS bssProcessProbeRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
{
	P_WLAN_MAC_MGMT_HEADER_T prMgtHdr;
	P_BSS_INFO_T prBssInfo;
	P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL;
	P_IE_SUPPORTED_RATE_T prIeSupportedRate = (P_IE_SUPPORTED_RATE_T) NULL;
	P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate = (P_IE_EXT_SUPPORTED_RATE_T) NULL;
	PUINT_8 pucIE;
	UINT_16 u2IELength;
	UINT_16 u2Offset = 0;
	UINT_8 aucBCBSSID[] = BC_BSSID;
	ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex;
	BOOLEAN fgReplyProbeResp;
#if CFG_ENABLE_WIFI_DIRECT
	BOOLEAN fgP2PTargetDeviceFound;
	UINT_8 aucP2PWildcardSSID[] = P2P_WILDCARD_SSID;
#endif

	ASSERT(prSwRfb);

	/* 4 <1> Parse Probe Req and Get SSID IE ptr */
	prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader;

	u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen;
	pucIE = (PUINT_8) ((UINT_32) prSwRfb->pvHeader + prSwRfb->u2HeaderLen);

	prIeSsid = (P_IE_SSID_T) NULL;

	IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
		switch (IE_ID(pucIE)) {
		case ELEM_ID_SSID:
			if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID))
				prIeSsid = (P_IE_SSID_T) pucIE;

			break;

		case ELEM_ID_SUP_RATES:
			/* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8.
			 * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B),
			 * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)"
			 */
			/* if (IE_LEN(pucIE) <= ELEM_MAX_LEN_SUP_RATES) { */
			if (IE_LEN(pucIE) <= RATE_NUM_SW)
				prIeSupportedRate = SUP_RATES_IE(pucIE);

			break;

		case ELEM_ID_EXTENDED_SUP_RATES:
			prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE);
			break;

#if CFG_ENABLE_WIFI_DIRECT
			/* TODO: P2P IE & WCS IE parsing for P2P. */
		case ELEM_ID_P2P:

			break;
#endif

			/* no default */
		}
	}			/* end of IE_FOR_EACH */

	/* 4 <2> Check network conditions before reply Probe Response Frame (Consider Concurrent) */
	for (eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; eNetTypeIndex < NETWORK_TYPE_INDEX_NUM; eNetTypeIndex++) {

		if (!IS_NET_ACTIVE(prAdapter, eNetTypeIndex))
			continue;

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

		if (UNEQUAL_MAC_ADDR(aucBCBSSID, prMgtHdr->aucBSSID) &&
		    UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prMgtHdr->aucBSSID)) {
			/* BSSID not Wildcard BSSID. */
			continue;
		}

		fgReplyProbeResp = FALSE;

		if (eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) {

			if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) {

				/* TODO(Kevin): Check if we are IBSS Master. */

				if (prIeSsid) {
					if ((prIeSsid->ucLength == BC_SSID_LEN) ||	/* WILDCARD SSID */
					    EQUAL_SSID(prBssInfo->aucSSID,
						       prBssInfo->ucSSIDLen, prIeSsid->aucSSID, prIeSsid->ucLength))
						fgReplyProbeResp = TRUE;

				}

			}
		}
#if CFG_ENABLE_WIFI_DIRECT
		else if (eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) {

			/* TODO(Kevin): Move following lines to p2p_fsm.c */

			if ((prIeSsid) &&
			    ((prIeSsid->ucLength == BC_SSID_LEN) ||
			     (EQUAL_SSID(aucP2PWildcardSSID,
					 P2P_WILDCARD_SSID_LEN, prIeSsid->aucSSID, prIeSsid->ucLength)))) {
				if (p2pFsmRunEventRxProbeRequestFrame(prAdapter, prSwRfb)) {
					/* Extand channel request time & cancel scan request. */
					P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL;

					/* TODO: RX probe request may not caused by LISTEN state. */
					/* TODO: It can be GO. */
					/* Generally speaking, cancel a non-exist scan request is fine.
					 * We can check P2P FSM here for only LISTEN state.
					 */

					P_MSG_SCN_SCAN_CANCEL prScanCancelMsg;

					prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;

					/* Abort JOIN process. */
					prScanCancelMsg =
					    (P_MSG_SCN_SCAN_CANCEL) cnmMemAlloc(prAdapter,
										RAM_TYPE_MSG,
										sizeof(MSG_SCN_SCAN_CANCEL));
					if (!prScanCancelMsg) {
						ASSERT(0);	/* Can't abort SCN FSM */
						continue;
					}

					prScanCancelMsg->rMsgHdr.eMsgId = MID_P2P_SCN_SCAN_CANCEL;
					prScanCancelMsg->ucSeqNum = prP2pFsmInfo->ucSeqNumOfScnMsg;
					prScanCancelMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_P2P_INDEX;
					prScanCancelMsg->fgIsChannelExt = TRUE;

					mboxSendMsg(prAdapter,
						    MBOX_ID_0, (P_MSG_HDR_T) prScanCancelMsg, MSG_SEND_METHOD_BUF);
				}
			} else {
				/* 1. Probe Request without SSID.
				 * 2. Probe Request with SSID not Wildcard SSID & not P2P Wildcard SSID.
				 */
				continue;
			}

#if 0				/* Frog */
			if (prAdapter->rWifiVar.prP2pFsmInfo->eCurrentState == P2P_STATE_LISTEN) {

				if (prIeSupportedRate || prIeExtSupportedRate) {
					UINT_16 u2OperationalRateSet, u2BSSBasicRateSet;
					BOOLEAN fgIsUnknownBssBasicRate;
					/* Ignore any Basic Bit */
					rateGetRateSetFromIEs(prIeSupportedRate, prIeExtSupportedRate,
							      &u2OperationalRateSet,
							      &u2BSSBasicRateSet, &fgIsUnknownBssBasicRate);

					if (u2OperationalRateSet & ~RATE_SET_HR_DSSS)
						continue;

				}
			}
			/* TODO: Check channel time before first check point to: */
			/* If Target device is selected:
			 *     1. Send XXXX request frame.
			 * else
			 *     1. Send Probe Response frame.
			 */

			if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) {
				/* TODO(Kevin): During PROVISION state, can we reply Probe Response ? */

				/* TODO(Kevin):
				 * If we are GO, accept legacy client --> accept Wildcard SSID
				 * If we are in Listen State, accept only P2P Device --> check P2P IE and WPS IE
				 */

				if (prIeSsid) {
					UINT_8 aucSSID[] = P2P_WILDCARD_SSID;

					if ((prIeSsid->ucLength == BC_SSID_LEN) ||	/* WILDCARD SSID */
					    EQUAL_SSID(prBssInfo->aucSSID,
						       prBssInfo->ucSSIDLen, prIeSsid->aucSSID, prIeSsid->ucLength)
					    || EQUAL_SSID(aucSSID, P2P_WILDCARD_SSID_LEN,
							  prIeSsid->aucSSID, prIeSsid->ucLength)) {
						fgReplyProbeResp = TRUE;
					}
				}

/* else if (FALSE) { */
/* } */

				/* TODO(Kevin): Check P2P IE and WPS IE */
			}
#endif
		}
#endif
		else
			ASSERT(eNetTypeIndex < NETWORK_TYPE_INDEX_NUM);

		if (fgReplyProbeResp)
			bssSendBeaconProbeResponse(prAdapter, eNetTypeIndex, prMgtHdr->aucSrcAddr);

	}

	return WLAN_STATUS_SUCCESS;

}				/* end of bssProcessProbeRequest() */
#endif

/*----------------------------------------------------------------------------*/
/*!
* @brief This function is used to initialize the client list for AdHoc or AP Mode
*
* @param[in] prAdapter              Pointer to the Adapter structure.
* @param[in] prBssInfo              Given related BSS_INFO_T.
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
VOID bssInitializeClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo)
{
	P_LINK_T prStaRecOfClientList;

	ASSERT(prBssInfo);

	prStaRecOfClientList = &prBssInfo->rStaRecOfClientList;

	if (!LINK_IS_EMPTY(prStaRecOfClientList))
		LINK_INITIALIZE(prStaRecOfClientList);

	DBGLOG(BSS, INFO, "Init BSS[%u] Client List\n", prBssInfo->ucBssIndex);

	bssCheckClientList(prAdapter, prBssInfo);
}				/* end of bssClearClientList() */

/*----------------------------------------------------------------------------*/
/*!
* @brief This function is used to Add a STA_RECORD_T to the client list for AdHoc or AP Mode
*
* @param[in] prAdapter              Pointer to the Adapter structure.
* @param[in] prBssInfo              Given related BSS_INFO_T.
* @param[in] prStaRec               Pointer to the STA_RECORD_T
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
VOID bssAddClient(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec)
{
	P_LINK_T prClientList;
	P_STA_RECORD_T prCurrStaRec;

	ASSERT(prBssInfo);

	prClientList = &prBssInfo->rStaRecOfClientList;

	LINK_FOR_EACH_ENTRY(prCurrStaRec, prClientList, rLinkEntry, STA_RECORD_T) {

		if (prCurrStaRec == prStaRec) {
			DBGLOG(BSS, WARN,
			       "Current Client List already contains that STA_RECORD_T[" MACSTR "]\n",
			       MAC2STR(prStaRec->aucMacAddr));
			return;
		}
	}

	LINK_INSERT_TAIL(prClientList, &prStaRec->rLinkEntry);

	bssCheckClientList(prAdapter, prBssInfo);
}				/* end of bssAddStaRecToClientList() */

/*----------------------------------------------------------------------------*/
/*!
* @brief This function is used to Remove a STA_RECORD_T from the client list for AdHoc or AP Mode
*
* @param[in] prAdapter              Pointer to the Adapter structure.
* @param[in] prStaRec               Pointer to the STA_RECORD_T
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
BOOLEAN bssRemoveClient(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec)
{
	P_LINK_T prClientList;
	P_STA_RECORD_T prCurrStaRec;

	ASSERT(prBssInfo);

	prClientList = &prBssInfo->rStaRecOfClientList;

	LINK_FOR_EACH_ENTRY(prCurrStaRec, prClientList, rLinkEntry, STA_RECORD_T) {

		if (prCurrStaRec == prStaRec) {

			LINK_REMOVE_KNOWN_ENTRY(prClientList, &prStaRec->rLinkEntry);

			return TRUE;
		}
	}

	DBGLOG(BSS, INFO, "Current Client List didn't contain that STA_RECORD_T["
	       MACSTR "] before removing.\n", MAC2STR(prStaRec->aucMacAddr));

	bssCheckClientList(prAdapter, prBssInfo);

	return FALSE;
}				/* end of bssRemoveStaRecFromClientList() */

P_STA_RECORD_T bssRemoveClientByMac(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN PUINT_8 pucMac)
{
	P_LINK_T prClientList;
	P_STA_RECORD_T prCurrStaRec;

	ASSERT(prBssInfo);

	prClientList = &prBssInfo->rStaRecOfClientList;

	LINK_FOR_EACH_ENTRY(prCurrStaRec, prClientList, rLinkEntry, STA_RECORD_T) {

		if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, pucMac)) {

			LINK_REMOVE_KNOWN_ENTRY(prClientList, &prCurrStaRec->rLinkEntry);

			return prCurrStaRec;
		}
	}

	DBGLOG(BSS, INFO, "Current Client List didn't contain that STA_RECORD_T["
	       MACSTR "] before removing.\n", MAC2STR(pucMac));

	bssCheckClientList(prAdapter, prBssInfo);

	return NULL;
}

P_STA_RECORD_T bssGetClientByMac(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN PUINT_8 pucMac)
{
	P_LINK_T prClientList;
	P_STA_RECORD_T prCurrStaRec;

	ASSERT(prBssInfo);

	prClientList = &prBssInfo->rStaRecOfClientList;

	LINK_FOR_EACH_ENTRY(prCurrStaRec, prClientList, rLinkEntry, STA_RECORD_T) {

		if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, pucMac))
			return prCurrStaRec;
	}

	DBGLOG(BSS, INFO, "Current Client List didn't contain that STA_RECORD_T["
	       MACSTR "] before removing.\n", MAC2STR(pucMac));

	bssCheckClientList(prAdapter, prBssInfo);

	return NULL;
}

P_STA_RECORD_T bssRemoveHeadClient(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo)
{
	P_LINK_T prStaRecOfClientList;
	P_STA_RECORD_T prStaRec = NULL;

	ASSERT(prBssInfo);

	prStaRecOfClientList = &prBssInfo->rStaRecOfClientList;

	if (!LINK_IS_EMPTY(prStaRecOfClientList))
		LINK_REMOVE_HEAD(prStaRecOfClientList, prStaRec, P_STA_RECORD_T);

	bssCheckClientList(prAdapter, prBssInfo);

	return prStaRec;
}

UINT_32 bssGetClientCount(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo)
{
	return prBssInfo->rStaRecOfClientList.u4NumElem;
}

VOID bssDumpClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo)
{
	P_LINK_T prClientList;
	P_STA_RECORD_T prCurrStaRec;
	UINT_8 ucCount = 0;

	ASSERT(prBssInfo);

	prClientList = &prBssInfo->rStaRecOfClientList;

	DBGLOG(SW4, INFO, "Dump BSS[%u] Client List NUM[%u]\n", prBssInfo->ucBssIndex, prClientList->u4NumElem);

	LINK_FOR_EACH_ENTRY(prCurrStaRec, prClientList, rLinkEntry, STA_RECORD_T) {

		if (!prCurrStaRec) {
			DBGLOG(SW4, INFO, "[%2u] is NULL STA_REC\n", ucCount);
			break;
		}
		DBGLOG(SW4, INFO, "[%2u] STA[%u] [" MACSTR "]\n", ucCount,
		       prCurrStaRec->ucIndex, MAC2STR(prCurrStaRec->aucMacAddr));

		ucCount++;
	}
}

VOID bssCheckClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo)
{
	P_LINK_T prClientList;
	P_STA_RECORD_T prCurrStaRec;
	UINT_8 ucCount = 0;
	BOOLEAN fgError = FALSE;

	ASSERT(prBssInfo);

	prClientList = &prBssInfo->rStaRecOfClientList;

	/* Check MAX number */
	if (prClientList->u4NumElem > P2P_MAXIMUM_CLIENT_COUNT) {
		DBGLOG(SW4, INFO, "BSS[%u] Client List NUM[%u] ERR\n", prBssInfo->ucBssIndex, prClientList->u4NumElem);

		fgError = TRUE;
	}

	/* Check default list status */
	if (prClientList->u4NumElem == 0) {
		if ((PVOID) prClientList->prNext != (PVOID) prClientList)
			fgError = TRUE;
		if ((PVOID) prClientList->prPrev != (PVOID) prClientList)
			fgError = TRUE;

		if (fgError) {
			DBGLOG(SW4, INFO, "BSS[%u] Client List PTR next/prev[%p/%p] ERR\n",
			       prBssInfo->ucBssIndex, prClientList->prNext, prClientList->prPrev);
		}
	}

	/* Traverse list */
	LINK_FOR_EACH_ENTRY(prCurrStaRec, prClientList, rLinkEntry, STA_RECORD_T) {
		if (!prCurrStaRec) {
			fgError = TRUE;
			DBGLOG(SW4, INFO, "BSS[%u] Client List NULL PTR ERR\n", prBssInfo->ucBssIndex);

			break;
		}

		ucCount++;
	}

	/* Check real count and list number */
	if (ucCount != prClientList->u4NumElem) {
		DBGLOG(SW4, INFO, "BSS[%u] Client List NUM[%u] REAL CNT[%u] ERR\n",
		       prBssInfo->ucBssIndex, prClientList->u4NumElem, ucCount);

		fgError = TRUE;
	}

	if (fgError)
		bssDumpClientList(prAdapter, prBssInfo);

}

#endif /* CFG_SUPPORT_ADHOC || CFG_SUPPORT_AAA */

#if CFG_SUPPORT_ADHOC
/*----------------------------------------------------------------------------*/
/* Routines for IBSS(AdHoc) only                                              */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/*!
* @brief This function is used to process Beacons from current Ad-Hoc network peers.
*        We also process Beacons from other Ad-Hoc network during SCAN. If it has
*        the same SSID and we'll decide to merge into it if it has a larger TSF.
*
* @param[in] prAdapter  Pointer to the Adapter structure.
* @param[in] prBssInfo  Pointer to the BSS_INFO_T.
* @param[in] prBSSDesc  Pointer to the BSS Descriptor.
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
VOID
ibssProcessMatchedBeacon(IN P_ADAPTER_T prAdapter,
			 IN P_BSS_INFO_T prBssInfo, IN P_BSS_DESC_T prBssDesc, IN UINT_8 ucRCPI)
{
	P_STA_RECORD_T prStaRec = NULL;

	BOOLEAN fgIsCheckCapability = FALSE;
	BOOLEAN fgIsCheckTSF = FALSE;
	BOOLEAN fgIsGoingMerging = FALSE;
	BOOLEAN fgIsSameBSSID;

	ASSERT(prBssInfo);
	ASSERT(prBssDesc);

	/* 4 <1> Process IBSS Beacon only after we create or merge with other IBSS. */
	if (!prBssInfo->fgIsBeaconActivated)
		return;

	/* 4 <2> Get the STA_RECORD_T of TA. */
	prStaRec = cnmGetStaRecByAddress(prAdapter, prAdapter->prAisBssInfo->ucBssIndex, prBssDesc->aucSrcAddr);

	fgIsSameBSSID = UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID) ? FALSE : TRUE;

	/* 4 <3> IBSS Merge Decision Flow for Processing Beacon. */
	if (fgIsSameBSSID) {

		/* Same BSSID:
		 * Case I.  This is a new TA and it has decide to merged with us.
		 *      a)  If fgIsMerging == FALSE - we will send msg to notify AIS.
		 *      b)  If fgIsMerging == TRUE - already notify AIS.
		 * Case II. This is an old TA and we've already merged together.
		 */
		if (!prStaRec) {

			/* For Case I - Check this IBSS's capability first before adding this Sta Record. */
			fgIsCheckCapability = TRUE;

			/* If check is passed, then we perform merging with this new IBSS */
			fgIsGoingMerging = TRUE;

		} else {

			ASSERT((prStaRec->ucBssIndex == prAdapter->prAisBssInfo->ucBssIndex) && IS_ADHOC_STA(prStaRec));

			if (prStaRec->ucStaState != STA_STATE_3) {

				if (!prStaRec->fgIsMerging) {

					/* For Case I - */
					/* Check this IBSS's capability first before */
					/* adding this Sta Record. */
					fgIsCheckCapability = TRUE;

					/* If check is passed, then we perform merging with this new IBSS */
					fgIsGoingMerging = TRUE;
				} else {
					/* For Case II - Update rExpirationTime of Sta Record */
					GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime);
				}
			} else {
				/* For Case II - Update rExpirationTime of Sta Record */
				GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime);
			}

		}
	} else {

		/* Unequal BSSID:
		 * Case III. This is a new TA and we need to compare the TSF and get the winner.
		 * Case IV.  This is an old TA and it merge into a new IBSS before we do the same thing.
		 *           We need to compare the TSF to get the winner.
		 * Case V.   This is an old TA and it restart a new IBSS. We also need to
		 *           compare the TSF to get the winner.
		 */

		/* For Case III, IV & V - We'll always check this new IBSS's capability first
		 * before merging into new IBSS.
		 */
		fgIsCheckCapability = TRUE;

		/* If check is passed, we need to perform TSF check to decide the major BSSID */
		fgIsCheckTSF = TRUE;

		/* For Case IV & V - We won't update rExpirationTime of Sta Record */
	}

	/* 4 <7> Check this BSS_DESC_T's capability. */
	if (fgIsCheckCapability) {
		BOOLEAN fgIsCapabilityMatched = FALSE;

		do {
			if (!(prBssDesc->ucPhyTypeSet & (prAdapter->rWifiVar.ucAvailablePhyTypeSet))) {
				DBGLOG(BSS, LOUD,
				       "IBSS MERGE: Ignore Peer MAC: " MACSTR
				       " - Unsupported Phy.\n", MAC2STR(prBssDesc->aucSrcAddr));

				break;
			}

			if (prBssDesc->fgIsUnknownBssBasicRate) {
				DBGLOG(BSS, LOUD,
				       "IBSS MERGE: Ignore Peer MAC: " MACSTR
				       " - Unknown Basic Rate.\n", MAC2STR(prBssDesc->aucSrcAddr));

				break;
			}

			if (ibssCheckCapabilityForAdHocMode(prAdapter, prBssDesc) == WLAN_STATUS_FAILURE) {
				DBGLOG(BSS, LOUD,
				       "IBSS MERGE: Ignore Peer MAC: " MACSTR
				       " - Capability is not matched.\n", MAC2STR(prBssDesc->aucSrcAddr));

				break;
			}

			fgIsCapabilityMatched = TRUE;
		} while (FALSE);

		if (!fgIsCapabilityMatched) {

			if (prStaRec) {
				/* For Case II - We merge this STA_RECORD in RX Path.
				 *     Case IV & V - They change their BSSID after we merge with them.
				 */

				DBGLOG(BSS, LOUD,
				       "IBSS MERGE: Ignore Peer MAC: " MACSTR
				       " - Capability is not matched.\n", MAC2STR(prBssDesc->aucSrcAddr));
			}

			return;
		}

		DBGLOG(BSS, LOUD,
		       "IBSS MERGE: Peer MAC: " MACSTR " - Check capability was passed.\n",
		       MAC2STR(prBssDesc->aucSrcAddr));
	}

	if (fgIsCheckTSF) {
#if CFG_SLT_SUPPORT
		fgIsGoingMerging = TRUE;
#else
		if (prBssDesc->fgIsLargerTSF)
			fgIsGoingMerging = TRUE;
		else
			return;

#endif
	}

	if (fgIsGoingMerging) {
		P_MSG_AIS_IBSS_PEER_FOUND_T prAisIbssPeerFoundMsg;

		/* 4 <1> We will merge with to this BSS immediately. */
		prBssDesc->fgIsConnecting = TRUE;
		prBssDesc->fgIsConnected = FALSE;

		/* 4 <2> Setup corresponding STA_RECORD_T */
		prStaRec = bssCreateStaRecFromBssDesc(prAdapter,
						      STA_TYPE_ADHOC_PEER,
						      prAdapter->prAisBssInfo->ucBssIndex, prBssDesc);

		if (!prStaRec) {
			/* no memory ? */
			return;
		}

		prStaRec->fgIsMerging = TRUE;

		/* update RCPI */
		prStaRec->ucRCPI = ucRCPI;

		/* 4 <3> Send Merge Msg to CNM to obtain the channel privilege. */
		prAisIbssPeerFoundMsg = (P_MSG_AIS_IBSS_PEER_FOUND_T)
		    cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_IBSS_PEER_FOUND_T));

		if (!prAisIbssPeerFoundMsg) {

			ASSERT(0);	/* Can't send Merge Msg */
			return;
		}

		prAisIbssPeerFoundMsg->rMsgHdr.eMsgId = MID_SCN_AIS_FOUND_IBSS;
		prAisIbssPeerFoundMsg->ucBssIndex = prAdapter->prAisBssInfo->ucBssIndex;
		prAisIbssPeerFoundMsg->prStaRec = prStaRec;

		/* Inform AIS to do STATE TRANSITION
		 * For Case I - If AIS in IBSS_ALONE, let it jump to NORMAL_TR after we know the new member.
		 * For Case III, IV - Now this new BSSID wins the TSF, follow it.
		 */
		if (fgIsSameBSSID) {
			prAisIbssPeerFoundMsg->fgIsMergeIn = TRUE;
		} else {
#if CFG_SLT_SUPPORT
			prAisIbssPeerFoundMsg->fgIsMergeIn = TRUE;
#else
			prAisIbssPeerFoundMsg->fgIsMergeIn = (prBssDesc->fgIsLargerTSF) ? FALSE : TRUE;
#endif
		}

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

	}
}				/* end of ibssProcessMatchedBeacon() */

/*----------------------------------------------------------------------------*/
/*!
* @brief This function will check the Capability for Ad-Hoc to decide if we are
*        able to merge with(same capability).
*
* @param[in] prBSSDesc  Pointer to the BSS Descriptor.
*
* @retval WLAN_STATUS_FAILURE   Can't pass the check of Capability.
* @retval WLAN_STATUS_SUCCESS   Pass the check of Capability.
*/
/*----------------------------------------------------------------------------*/
WLAN_STATUS ibssCheckCapabilityForAdHocMode(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc)
{
	P_CONNECTION_SETTINGS_T prConnSettings;
	WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;

	ASSERT(prBssDesc);
	prConnSettings = &(prAdapter->rWifiVar.rConnSettings);

	do {
		/* 4 <1> Check the BSS Basic Rate Set for current AdHoc Mode */
		if ((prConnSettings->eAdHocMode == AD_HOC_MODE_11B) &&
		    (prBssDesc->u2BSSBasicRateSet & ~RATE_SET_HR_DSSS)) {
			break;
		} else if ((prConnSettings->eAdHocMode == AD_HOC_MODE_11A) &&
			   (prBssDesc->u2BSSBasicRateSet & ~RATE_SET_OFDM)) {
			break;
		}
		/* 4 <2> Check the Short Slot Time. */
#if 0				/* Do not check ShortSlotTime until Wi-Fi define such policy */
		if (prConnSettings->eAdHocMode == AD_HOC_MODE_11G) {
			if (((prConnSettings->fgIsShortSlotTimeOptionEnable) &&
			     !(prBssDesc->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME)) ||
			    (!(prConnSettings->fgIsShortSlotTimeOptionEnable) &&
			     (prBssDesc->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME))) {
				break;
			}
		}
#endif

		/* 4 <3> Check the ATIM window setting. */
		if (prBssDesc->u2ATIMWindow) {
			DBGLOG(BSS, INFO, "AdHoc PS was not supported(ATIM Window: %d)\n", prBssDesc->u2ATIMWindow);
			break;
		}
		/* 4 <4> Check the Security setting. */
		if (!rsnPerformPolicySelection(prAdapter, prBssDesc))
			break;

		rStatus = WLAN_STATUS_SUCCESS;
	} while (FALSE);

	return rStatus;

}				/* end of ibssCheckCapabilityForAdHocMode() */

/*----------------------------------------------------------------------------*/
/*!
* @brief This function will initial the BSS_INFO_T for IBSS Mode.
*
* @param[in] prBssInfo      Pointer to the BSS_INFO_T.
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
VOID ibssInitForAdHoc(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo)
{
	UINT_8 aucBSSID[MAC_ADDR_LEN];
	PUINT_16 pu2BSSID = (PUINT_16) &aucBSSID[0];
	UINT_32 i;

	ASSERT(prBssInfo);
	ASSERT(prBssInfo->eCurrentOPMode == OP_MODE_IBSS);

	/* 4 <1> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */
	prBssInfo->ucNonHTBasicPhyType = (UINT_8)
	    rNonHTAdHocModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex;
	prBssInfo->u2BSSBasicRateSet = rNonHTAdHocModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet;

	prBssInfo->u2OperationalRateSet = rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet;

	rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet,
				    prBssInfo->u2BSSBasicRateSet,
				    prBssInfo->aucAllSupportedRates, &prBssInfo->ucAllSupportedRatesLen);

	/* 4 <2> Setup BSSID */
	if (!prBssInfo->fgHoldSameBssidForIBSS) {

		for (i = 0; i < sizeof(aucBSSID) / sizeof(UINT_16); i++)
			pu2BSSID[i] = (UINT_16) (kalRandomNumber() & 0xFFFF);

		aucBSSID[0] &= ~0x01;	/* 7.1.3.3.3 - The individual/group bit of the address is set to 0. */
		aucBSSID[0] |= 0x02;	/* 7.1.3.3.3 - The universal/local bit of the address is set to 1. */

		COPY_MAC_ADDR(prBssInfo->aucBSSID, aucBSSID);
	}

	/* 4 <3> Setup Capability - Short Preamble */
	if (rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].fgIsShortPreambleOptionImplemented &&
	    /* Short Preamble Option Enable is TRUE */
	    ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) ||
	     (prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO))) {

		prBssInfo->fgIsShortPreambleAllowed = TRUE;
		prBssInfo->fgUseShortPreamble = TRUE;
	} else {
		prBssInfo->fgIsShortPreambleAllowed = FALSE;
		prBssInfo->fgUseShortPreamble = FALSE;
	}

	/* 4 <4> Setup Capability - Short Slot Time */
	/* 7.3.1.4 For IBSS, the Short Slot Time subfield shall be set to 0. */
	prBssInfo->fgUseShortSlotTime = FALSE;	/* Set to FALSE for AdHoc */

	/* 4 <5> Compoase Capability */
	prBssInfo->u2CapInfo = CAP_INFO_IBSS;

	if (prBssInfo->fgIsProtection)
		prBssInfo->u2CapInfo |= CAP_INFO_PRIVACY;

	if (prBssInfo->fgIsShortPreambleAllowed)
		prBssInfo->u2CapInfo |= CAP_INFO_SHORT_PREAMBLE;

	if (prBssInfo->fgUseShortSlotTime)
		prBssInfo->u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME;

	/* 4 <6> Find Lowest Basic Rate Index for default TX Rate of MMPDU */
	nicTxUpdateBssDefaultRate(prBssInfo);
}				/* end of ibssInitForAdHoc() */

#endif /* CFG_SUPPORT_ADHOC */

#if CFG_SUPPORT_AAA

/*----------------------------------------------------------------------------*/
/* Routines for BSS(AP) only                                                  */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/*!
* @brief This function will initial the BSS_INFO_T for AP Mode.
*
* @param[in] prBssInfo              Given related BSS_INFO_T.
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
VOID bssInitForAP(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN BOOLEAN fgIsRateUpdate)
{
	P_AC_QUE_PARMS_T prACQueParms;

	ENUM_WMM_ACI_T eAci;

	UINT_8 auCWminLog2ForBcast[WMM_AC_INDEX_NUM] = { 4 /*BE*/, 4 /*BK*/, 3 /*VO*/, 2 /*VI*/ };
	UINT_8 auCWmaxLog2ForBcast[WMM_AC_INDEX_NUM] = { 10, 10, 4, 3 };
	UINT_8 auAifsForBcast[WMM_AC_INDEX_NUM] = { 3, 7, 2, 2 };
	UINT_8 auTxopForBcast[WMM_AC_INDEX_NUM] = { 0, 0, 94, 47 };	/* If the AP is OFDM */

	UINT_8 auCWminLog2[WMM_AC_INDEX_NUM] = { 4 /*BE*/, 4 /*BK*/, 3 /*VO*/, 2 /*VI*/ };
	UINT_8 auCWmaxLog2[WMM_AC_INDEX_NUM] = { 6, 10, 4, 3 };
	UINT_8 auAifs[WMM_AC_INDEX_NUM] = { 3, 7, 1, 1 };
	UINT_8 auTxop[WMM_AC_INDEX_NUM] = { 0, 0, 94, 47 };	/* If the AP is OFDM */

	DEBUGFUNC("bssInitForAP");
	DBGLOG(BSS, LOUD, "\n");

	ASSERT(prBssInfo);
	ASSERT((prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)
	       || (prBssInfo->eCurrentOPMode == OP_MODE_BOW));

#if 0
	prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled = TRUE;
	prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode = CONFIG_BW_20M;
	prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode = CONFIG_BW_20M;
#endif

	/* 4 <1> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */
	prBssInfo->ucNonHTBasicPhyType = (UINT_8)
	    rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex;
	prBssInfo->u2BSSBasicRateSet = rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet;

	/* 4 <1.1> Mask CCK 1M For Sco scenario except FDD mode */
	if (prAdapter->u4FddMode == FALSE)
		prBssInfo->u2BSSBasicRateSet &= ~RATE_SET_BIT_1M;
	/* prBssInfo->u2OperationalRateSet &= ~RATE_SET_BIT_1M; */

	prBssInfo->u2OperationalRateSet = rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet;

	if (fgIsRateUpdate) {
		rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet,
					    prBssInfo->u2BSSBasicRateSet,
					    prBssInfo->aucAllSupportedRates, &prBssInfo->ucAllSupportedRatesLen);
	}
	/* 4 <2> Setup BSSID */
	COPY_MAC_ADDR(prBssInfo->aucBSSID, prBssInfo->aucOwnMacAddr);

	/* 4 <3> Setup Capability - Short Preamble */
	if (rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].fgIsShortPreambleOptionImplemented &&
	    /* Short Preamble Option Enable is TRUE */
	    ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) ||
	     (prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO))) {

		prBssInfo->fgIsShortPreambleAllowed = TRUE;
		prBssInfo->fgUseShortPreamble = TRUE;
	} else {
		prBssInfo->fgIsShortPreambleAllowed = FALSE;
		prBssInfo->fgUseShortPreamble = FALSE;
	}

	/* 4 <4> Setup Capability - Short Slot Time */
	prBssInfo->fgUseShortSlotTime = TRUE;

	/* 4 <5> Compoase Capability */
	prBssInfo->u2CapInfo = CAP_INFO_ESS;

	if (prBssInfo->fgIsProtection)
		prBssInfo->u2CapInfo |= CAP_INFO_PRIVACY;

	if (prBssInfo->fgIsShortPreambleAllowed)
		prBssInfo->u2CapInfo |= CAP_INFO_SHORT_PREAMBLE;

	if (prBssInfo->fgUseShortSlotTime)
		prBssInfo->u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME;

	/* 4 <6> Find Lowest Basic Rate Index for default TX Rate of MMPDU */
	nicTxUpdateBssDefaultRate(prBssInfo);

	/* 4 <7> Fill the EDCA */

	prACQueParms = prBssInfo->arACQueParmsForBcast;

	for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) {

		prACQueParms[eAci].ucIsACMSet = FALSE;
		prACQueParms[eAci].u2Aifsn = auAifsForBcast[eAci];
		prACQueParms[eAci].u2CWmin = BIT(auCWminLog2ForBcast[eAci]) - 1;
		prACQueParms[eAci].u2CWmax = BIT(auCWmaxLog2ForBcast[eAci]) - 1;
		prACQueParms[eAci].u2TxopLimit = auTxopForBcast[eAci];

		prBssInfo->aucCWminLog2ForBcast[eAci] = auCWminLog2ForBcast[eAci];	/* used to send WMM IE */
		prBssInfo->aucCWmaxLog2ForBcast[eAci] = auCWmaxLog2ForBcast[eAci];

		DBGLOG(BSS, INFO,
		       "Bcast: eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n",
		       eAci, prACQueParms[eAci].ucIsACMSet, prACQueParms[eAci].u2Aifsn,
		       prACQueParms[eAci].u2CWmin, prACQueParms[eAci].u2CWmax, prACQueParms[eAci].u2TxopLimit);

	}

	prACQueParms = prBssInfo->arACQueParms;

	for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) {

		prACQueParms[eAci].ucIsACMSet = FALSE;
		prACQueParms[eAci].u2Aifsn = auAifs[eAci];
		prACQueParms[eAci].u2CWmin = BIT(auCWminLog2[eAci]) - 1;
		prACQueParms[eAci].u2CWmax = BIT(auCWmaxLog2[eAci]) - 1;
		prACQueParms[eAci].u2TxopLimit = auTxop[eAci];

		DBGLOG(BSS, INFO,
		       "eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n",
		       eAci, prACQueParms[eAci].ucIsACMSet, prACQueParms[eAci].u2Aifsn,
		       prACQueParms[eAci].u2CWmin, prACQueParms[eAci].u2CWmax, prACQueParms[eAci].u2TxopLimit);
	}

	/* Note: Caller should update the EDCA setting to HW by nicQmUpdateWmmParms() it there is no AIS network */
	/* Note: In E2, only 4 HW queues. The the Edca parameters should be folow by AIS network */
	/* Note: In E3, 8 HW queues.  the Wmm parameters should be updated to right queues  according to BSS */
}				/* end of bssInitForAP() */

#if 0
/*----------------------------------------------------------------------------*/
/*!
* @brief Update DTIM Count
*
* @param[in] eNetTypeIndex      Specify which network to update
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
VOID bssUpdateDTIMCount(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex)
{
	P_BSS_INFO_T prBssInfo;

	ASSERT(eNetTypeIndex < NETWORK_TYPE_INDEX_NUM);

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

	if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) {

		/* Setup DTIM Count for next TBTT. */
		if (prBssInfo->ucDTIMCount > 0) {
			prBssInfo->ucDTIMCount--;
		} else {

			ASSERT(prBssInfo->ucDTIMPeriod > 0);

			prBssInfo->ucDTIMCount = prBssInfo->ucDTIMPeriod - 1;
		}
	}
}				/* end of bssUpdateDTIMIE() */

/*----------------------------------------------------------------------------*/
/*!
* @brief This function is used to set the Virtual Bitmap in TIM Information Elements
*
* @param[in] prBssInfo      Pointer to the BSS_INFO_T.
* @param[in] u2AssocId      The association id to set in Virtual Bitmap.
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
VOID bssSetTIMBitmap(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN UINT_16 u2AssocId)
{

	ASSERT(prBssInfo);

	if (prBssInfo->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) {
		P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo;

		prP2pSpecificBssInfo = &(prAdapter->rWifiVar.rP2pSpecificBssInfo);

		/* Use Association ID == 0 for BMCAST indication */
		if (u2AssocId == 0) {

			prP2pSpecificBssInfo->ucBitmapCtrl |= (UINT_8) BIT(0);
		} else {
			PUINT_8 pucPartialVirtualBitmap;
			UINT_8 ucBitmapToSet;

			pucPartialVirtualBitmap = &prP2pSpecificBssInfo->aucPartialVirtualBitmap[(u2AssocId >> 3)];
			ucBitmapToSet = (UINT_8) BIT((u2AssocId % 8));

			if (*pucPartialVirtualBitmap & ucBitmapToSet) {
				/* The virtual bitmap has been set */
				return;
			}

			*pucPartialVirtualBitmap |= ucBitmapToSet;

			/* Update u2SmallestAID and u2LargestAID */
			if ((u2AssocId < prP2pSpecificBssInfo->u2SmallestAID) ||
			    (prP2pSpecificBssInfo->u2SmallestAID == 0)) {
				prP2pSpecificBssInfo->u2SmallestAID = u2AssocId;
			}

			if ((u2AssocId > prP2pSpecificBssInfo->u2LargestAID) ||
			    (prP2pSpecificBssInfo->u2LargestAID == 0)) {
				prP2pSpecificBssInfo->u2LargestAID = u2AssocId;
			}
		}
	}
}				/* end of bssSetTIMBitmap() */
#endif

#endif /* CFG_SUPPORT_AAA */

VOID bssCreateStaRecFromAuth(IN P_ADAPTER_T prAdapter)
{

}

VOID bssUpdateStaRecFromAssocReq(IN P_ADAPTER_T prAdapter)
{

}

VOID bssDumpBssInfo(IN P_ADAPTER_T prAdapter, IN UINT_8 ucBssIndex)
{
	P_BSS_INFO_T prBssInfo;
	/* P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL; */
	/* P_STA_RECORD_T prCurrStaRec = (P_STA_RECORD_T) NULL; */

	if (ucBssIndex > MAX_BSS_INDEX) {
		DBGLOG(SW4, INFO, "Invalid BssInfo index[%u], skip dump!\n", ucBssIndex);
		return;
	}

	prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex);

	if (!prBssInfo) {
		DBGLOG(SW4, INFO, "Invalid BssInfo index[%u], skip dump!\n", ucBssIndex);
		return;
	}

	DBGLOG(SW4, INFO, "OWNMAC[" MACSTR "] BSSID[" MACSTR "] SSID[%s]\n",
	       MAC2STR(prBssInfo->aucOwnMacAddr), MAC2STR(prBssInfo->aucBSSID), prBssInfo->aucSSID);

	DBGLOG(SW4, INFO, "BSS IDX[%u] Type[%s] OPMode[%s] ConnState[%u] Absent[%u]\n",
	       prBssInfo->ucBssIndex,
	       apucNetworkType[prBssInfo->eNetworkType],
	       apucNetworkOpMode[prBssInfo->eCurrentOPMode], prBssInfo->eConnectionState, prBssInfo->fgIsNetAbsent);

	DBGLOG(SW4, INFO,
	       "Channel[%u] Band[%u] SCO[%u] Assoc40mBwAllowed[%u] 40mBwAllowed[%u] MaxBw[%u] Nss[%u] eDBDCBand[%u]\n",
	       prBssInfo->ucPrimaryChannel, prBssInfo->eBand, prBssInfo->eBssSCO,
	       prBssInfo->fgAssoc40mBwAllowed, prBssInfo->fg40mBwAllowed,
	       cnmGetBssMaxBw(prAdapter, prBssInfo->ucBssIndex),
	       prBssInfo->ucNss, prBssInfo->eDBDCBand);

	DBGLOG(SW4, INFO, "QBSS[%u] CapInfo[0x%04x] AID[%u]\n",
	       prBssInfo->fgIsQBSS, prBssInfo->u2CapInfo, prBssInfo->u2AssocId);

	DBGLOG(SW4, INFO, "ShortPreamble Allowed[%u] EN[%u], ShortSlotTime[%u]\n",
	       prBssInfo->fgIsShortPreambleAllowed, prBssInfo->fgUseShortPreamble, prBssInfo->fgUseShortSlotTime);

	DBGLOG(SW4, INFO, "PhyTypeSet: Basic[0x%02x] NonHtBasic[0x%02x]\n",
	       prBssInfo->ucPhyTypeSet, prBssInfo->ucNonHTBasicPhyType);

	DBGLOG(SW4, INFO, "RateSet: BssBasic[0x%04x] Operational[0x%04x]\n",
	       prBssInfo->u2BSSBasicRateSet, prBssInfo->u2OperationalRateSet);

	DBGLOG(SW4, INFO, "ATIMWindow[%u] DTIM Period[%u] Count[%u]\n",
	       prBssInfo->u2ATIMWindow, prBssInfo->ucDTIMPeriod, prBssInfo->ucDTIMCount);

	DBGLOG(SW4, INFO, "HT Operation Info1[0x%02x] Info2[0x%04x] Info3[0x%04x]\n",
	       prBssInfo->ucHtOpInfo1, prBssInfo->u2HtOpInfo2, prBssInfo->u2HtOpInfo3);

	DBGLOG(SW4, INFO, "ProtectMode HT[%u] ERP[%u], OperationMode GF[%u] RIFS[%u]\n",
	       prBssInfo->eHtProtectMode,
	       prBssInfo->fgErpProtectMode, prBssInfo->eGfOperationMode, prBssInfo->eRifsOperationMode);

	DBGLOG(SW4, INFO, "(OBSS) ProtectMode HT[%u] ERP[%u], OperationMode GF[%u] RIFS[%u]\n",
	       prBssInfo->eObssHtProtectMode,
	       prBssInfo->fgObssErpProtectMode, prBssInfo->eObssGfOperationMode, prBssInfo->fgObssRifsOperationMode);

	DBGLOG(SW4, INFO, "VhtChannelWidth[%u] OpChangeChannelWidth[%u], IsOpChangeChannelWidth[%u]\n",
	       prBssInfo->ucVhtChannelWidth,
	       prBssInfo->ucOpChangeChannelWidth, prBssInfo->fgIsOpChangeChannelWidth);

	DBGLOG(SW4, INFO, "======== Dump Connected Client ========\n");

#if 0
	DBGLOG(SW4, INFO, "NumOfClient[%u]\n", bssGetClientCount(prAdapter, prBssInfo));

	prStaRecOfClientList = &prBssInfo->rStaRecOfClientList;

	LINK_FOR_EACH_ENTRY(prCurrStaRec, prStaRecOfClientList, rLinkEntry, STA_RECORD_T) {
		DBGLOG(SW4, INFO, "STA[%u] [" MACSTR "]\n", prCurrStaRec->ucIndex, MAC2STR(prCurrStaRec->aucMacAddr));
	}
#else
	bssDumpClientList(prAdapter, prBssInfo);
#endif

	DBGLOG(SW4, INFO, "============== Dump Done ==============\n");
}
