/*
 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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 the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * File: bssdb.c
 *
 * Purpose: Handles the Basic Service Set & Node Database functions
 *
 * Functions:
 *      BSSpSearchBSSList - Search known BSS list for Desire SSID or BSSID
 *      BSSvClearBSSList - Clear BSS List
 *      BSSbInsertToBSSList - Insert a BSS set into known BSS list
 *      BSSbUpdateToBSSList - Update BSS set in known BSS list
 *      BSSDBbIsSTAInNodeDB - Search Node DB table to find the index of matched DstAddr
 *      BSSvCreateOneNode - Allocate an Node for Node DB
 *      BSSvUpdateAPNode - Update AP Node content in Index 0 of KnownNodeDB
 *      BSSvSecondCallBack - One second timer callback function to update Node DB info & AP link status
 *      BSSvUpdateNodeTxCounter - Update Tx attemps, Tx failure counter in Node DB for auto-fall back rate control
 *
 * Revision History:
 *
 * Author: Lyndon Chen
 *
 * Date: July 17, 2002
 *
 */

#include "ttype.h"
#include "tmacro.h"
#include "tether.h"
#include "device.h"
#include "80211hdr.h"
#include "bssdb.h"
#include "wmgr.h"
#include "datarate.h"
#include "desc.h"
#include "wcmd.h"
#include "wpa.h"
#include "baseband.h"
#include "rf.h"
#include "card.h"
#include "channel.h"
#include "mac.h"
#include "wpa2.h"
#include "iowpa.h"

/*---------------------  Static Definitions -------------------------*/

/*---------------------  Static Classes  ----------------------------*/

/*---------------------  Static Variables  --------------------------*/
static int msglevel = MSG_LEVEL_INFO;
//static int          msglevel                =MSG_LEVEL_DEBUG;

const unsigned short awHWRetry0[5][5] = {
	{RATE_18M, RATE_18M, RATE_12M, RATE_12M, RATE_12M},
	{RATE_24M, RATE_24M, RATE_18M, RATE_12M, RATE_12M},
	{RATE_36M, RATE_36M, RATE_24M, RATE_18M, RATE_18M},
	{RATE_48M, RATE_48M, RATE_36M, RATE_24M, RATE_24M},
	{RATE_54M, RATE_54M, RATE_48M, RATE_36M, RATE_36M}
};
const unsigned short awHWRetry1[5][5] = {
	{RATE_18M, RATE_18M, RATE_12M, RATE_6M, RATE_6M},
	{RATE_24M, RATE_24M, RATE_18M, RATE_6M, RATE_6M},
	{RATE_36M, RATE_36M, RATE_24M, RATE_12M, RATE_12M},
	{RATE_48M, RATE_48M, RATE_24M, RATE_12M, RATE_12M},
	{RATE_54M, RATE_54M, RATE_36M, RATE_18M, RATE_18M}
};

/*---------------------  Static Functions  --------------------------*/

void s_vCheckSensitivity(
	void *hDeviceContext
);

#ifdef Calcu_LinkQual
void s_uCalculateLinkQual(
	void *hDeviceContext
);
#endif

void s_vCheckPreEDThreshold(
	void *hDeviceContext
);
/*---------------------  Export Variables  --------------------------*/

/*---------------------  Export Functions  --------------------------*/

/*+
 *
 * Routine Description:
 *    Search known BSS list for Desire SSID or BSSID.
 *
 * Return Value:
 *    PTR to KnownBSS or NULL
 *
 -*/

PKnownBSS
BSSpSearchBSSList(
	void *hDeviceContext,
	unsigned char *pbyDesireBSSID,
	unsigned char *pbyDesireSSID,
	CARD_PHY_TYPE  ePhyType
)
{
	PSDevice        pDevice = (PSDevice)hDeviceContext;
	PSMgmtObject    pMgmt = pDevice->pMgmt;
	unsigned char *pbyBSSID = NULL;
	PWLAN_IE_SSID   pSSID = NULL;
	PKnownBSS       pCurrBSS = NULL;
	PKnownBSS       pSelect = NULL;
	unsigned char ZeroBSSID[WLAN_BSSID_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
	unsigned int ii = 0;

	if (pbyDesireBSSID != NULL) {
		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
			"BSSpSearchBSSList BSSID[%pM]\n", pbyDesireBSSID);
		if ((!is_broadcast_ether_addr(pbyDesireBSSID)) &&
		    (memcmp(pbyDesireBSSID, ZeroBSSID, 6) != 0)) {
			pbyBSSID = pbyDesireBSSID;
		}
	}
	if (pbyDesireSSID != NULL) {
		if (((PWLAN_IE_SSID)pbyDesireSSID)->len != 0) {
			pSSID = (PWLAN_IE_SSID) pbyDesireSSID;
		}
	}

	if (pbyBSSID != NULL) {
		// match BSSID first
		for (ii = 0; ii < MAX_BSS_NUM; ii++) {
			pCurrBSS = &(pMgmt->sBSSList[ii]);
			if (pDevice->bLinkPass == false) pCurrBSS->bSelected = false;
			if ((pCurrBSS->bActive) &&
			    (pCurrBSS->bSelected == false)) {
				if (!compare_ether_addr(pCurrBSS->abyBSSID, pbyBSSID)) {
					if (pSSID != NULL) {
						// compare ssid
						if (!memcmp(pSSID->abySSID,
							    ((PWLAN_IE_SSID)pCurrBSS->abySSID)->abySSID,
							    pSSID->len)) {
							if ((pMgmt->eConfigMode == WMAC_CONFIG_AUTO) ||
							    ((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) ||
							    ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo))
) {
								pCurrBSS->bSelected = true;
								return pCurrBSS;
							}
						}
					} else {
						if ((pMgmt->eConfigMode == WMAC_CONFIG_AUTO) ||
						    ((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) ||
						    ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo))
) {
							pCurrBSS->bSelected = true;
							return pCurrBSS;
						}
					}
				}
			}
		}
	} else {
		// ignore BSSID
		for (ii = 0; ii < MAX_BSS_NUM; ii++) {
			pCurrBSS = &(pMgmt->sBSSList[ii]);
			//2007-0721-01<Add>by MikeLiu
			pCurrBSS->bSelected = false;
			if (pCurrBSS->bActive) {
				if (pSSID != NULL) {
					// matched SSID
					if (!!memcmp(pSSID->abySSID,
						     ((PWLAN_IE_SSID)pCurrBSS->abySSID)->abySSID,
						     pSSID->len) ||
					    (pSSID->len != ((PWLAN_IE_SSID)pCurrBSS->abySSID)->len)) {
						// SSID not match skip this BSS
						continue;
					}
				}
				if (((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo)) ||
				    ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo))
) {
					// Type not match skip this BSS
					DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSS type mismatch.... Config[%d] BSS[0x%04x]\n", pMgmt->eConfigMode, pCurrBSS->wCapInfo);
					continue;
				}

				if (ePhyType != PHY_TYPE_AUTO) {
					if (((ePhyType == PHY_TYPE_11A) && (PHY_TYPE_11A != pCurrBSS->eNetworkTypeInUse)) ||
					    ((ePhyType != PHY_TYPE_11A) && (PHY_TYPE_11A == pCurrBSS->eNetworkTypeInUse))) {
						// PhyType not match skip this BSS
						DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Physical type mismatch.... ePhyType[%d] BSS[%d]\n", ePhyType, pCurrBSS->eNetworkTypeInUse);
						continue;
					}
				}
/*
  if (pMgmt->eAuthenMode < WMAC_AUTH_WPA) {
  if (pCurrBSS->bWPAValid == true) {
  // WPA AP will reject connection of station without WPA enable.
  continue;
  }
  } else if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
  (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)) {
  if (pCurrBSS->bWPAValid == false) {
  // station with WPA enable can't join NonWPA AP.
  continue;
  }
  } else if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
  (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {
  if (pCurrBSS->bWPA2Valid == false) {
  // station with WPA2 enable can't join NonWPA2 AP.
  continue;
  }
  }
*/
				if (pSelect == NULL) {
					pSelect = pCurrBSS;
				} else {
					// compare RSSI, select signal strong one
					if (pCurrBSS->uRSSI < pSelect->uRSSI) {
						pSelect = pCurrBSS;
					}
				}
			}
		}
		if (pSelect != NULL) {
			pSelect->bSelected = true;
/*
  if (pDevice->bRoaming == false)  {
  //       Einsn Add @20070907
  memset(pbyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
  memcpy(pbyDesireSSID,pCurrBSS->abySSID,WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
  }*/

			return pSelect;
		}
	}
	return NULL;
}

/*+
 *
 * Routine Description:
 *    Clear BSS List
 *
 * Return Value:
 *    None.
 *
 -*/

void
BSSvClearBSSList(
	void *hDeviceContext,
	bool bKeepCurrBSSID
)
{
	PSDevice     pDevice = (PSDevice)hDeviceContext;
	PSMgmtObject    pMgmt = pDevice->pMgmt;
	unsigned int ii;

	for (ii = 0; ii < MAX_BSS_NUM; ii++) {
		if (bKeepCurrBSSID) {
			if (pMgmt->sBSSList[ii].bActive &&
			    !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, pMgmt->abyCurrBSSID)) {
				// bKeepCurrBSSID = false;
				continue;
			}
		}

		if ((pMgmt->sBSSList[ii].bActive) && (pMgmt->sBSSList[ii].uClearCount < BSS_CLEAR_COUNT)) {
			pMgmt->sBSSList[ii].uClearCount++;
			continue;
		}

		pMgmt->sBSSList[ii].bActive = false;
		memset(&pMgmt->sBSSList[ii], 0, sizeof(KnownBSS));
	}
	BSSvClearAnyBSSJoinRecord(pDevice);

	return;
}

/*+
 *
 * Routine Description:
 *    search BSS list by BSSID & SSID if matched
 *
 * Return Value:
 *    true if found.
 *
 -*/
PKnownBSS
BSSpAddrIsInBSSList(
	void *hDeviceContext,
	unsigned char *abyBSSID,
	PWLAN_IE_SSID pSSID
)
{
	PSDevice     pDevice = (PSDevice)hDeviceContext;
	PSMgmtObject    pMgmt = pDevice->pMgmt;
	PKnownBSS       pBSSList = NULL;
	unsigned int ii;

	for (ii = 0; ii < MAX_BSS_NUM; ii++) {
		pBSSList = &(pMgmt->sBSSList[ii]);
		if (pBSSList->bActive) {
			if (!compare_ether_addr(pBSSList->abyBSSID, abyBSSID)) {
				if (pSSID->len == ((PWLAN_IE_SSID)pBSSList->abySSID)->len) {
					if (memcmp(pSSID->abySSID,
						   ((PWLAN_IE_SSID)pBSSList->abySSID)->abySSID,
						   pSSID->len) == 0)
						return pBSSList;
				}
			}
		}
	}

	return NULL;
};

/*+
 *
 * Routine Description:
 *    Insert a BSS set into known BSS list
 *
 * Return Value:
 *    true if success.
 *
 -*/

bool
BSSbInsertToBSSList(
	void *hDeviceContext,
	unsigned char *abyBSSIDAddr,
	QWORD qwTimestamp,
	unsigned short wBeaconInterval,
	unsigned short wCapInfo,
	unsigned char byCurrChannel,
	PWLAN_IE_SSID pSSID,
	PWLAN_IE_SUPP_RATES pSuppRates,
	PWLAN_IE_SUPP_RATES pExtSuppRates,
	PERPObject psERP,
	PWLAN_IE_RSN pRSN,
	PWLAN_IE_RSN_EXT pRSNWPA,
	PWLAN_IE_COUNTRY pIE_Country,
	PWLAN_IE_QUIET pIE_Quiet,
	unsigned int uIELength,
	unsigned char *pbyIEs,
	void *pRxPacketContext
)
{
	PSDevice     pDevice = (PSDevice)hDeviceContext;
	PSMgmtObject    pMgmt = pDevice->pMgmt;
	PSRxMgmtPacket  pRxPacket = (PSRxMgmtPacket)pRxPacketContext;
	PKnownBSS       pBSSList = NULL;
	unsigned int ii;
	bool bParsingQuiet = false;
	PWLAN_IE_QUIET  pQuiet = NULL;

	pBSSList = (PKnownBSS)&(pMgmt->sBSSList[0]);

	for (ii = 0; ii < MAX_BSS_NUM; ii++) {
		pBSSList = (PKnownBSS)&(pMgmt->sBSSList[ii]);
		if (!pBSSList->bActive)
			break;
	}

	if (ii == MAX_BSS_NUM) {
		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Get free KnowBSS node failed.\n");
		return false;
	}
	// save the BSS info
	pBSSList->bActive = true;
	memcpy(pBSSList->abyBSSID, abyBSSIDAddr, WLAN_BSSID_LEN);
	HIDWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(HIDWORD(qwTimestamp));
	LODWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(LODWORD(qwTimestamp));
	pBSSList->wBeaconInterval = cpu_to_le16(wBeaconInterval);
	pBSSList->wCapInfo = cpu_to_le16(wCapInfo);
	pBSSList->uClearCount = 0;

	if (pSSID->len > WLAN_SSID_MAXLEN)
		pSSID->len = WLAN_SSID_MAXLEN;
	memcpy(pBSSList->abySSID, pSSID, pSSID->len + WLAN_IEHDR_LEN);

	pBSSList->uChannel = byCurrChannel;

	if (pSuppRates->len > WLAN_RATES_MAXLEN)
		pSuppRates->len = WLAN_RATES_MAXLEN;
	memcpy(pBSSList->abySuppRates, pSuppRates, pSuppRates->len + WLAN_IEHDR_LEN);

	if (pExtSuppRates != NULL) {
		if (pExtSuppRates->len > WLAN_RATES_MAXLEN)
			pExtSuppRates->len = WLAN_RATES_MAXLEN;
		memcpy(pBSSList->abyExtSuppRates, pExtSuppRates, pExtSuppRates->len + WLAN_IEHDR_LEN);
		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSSbInsertToBSSList: pExtSuppRates->len = %d\n", pExtSuppRates->len);

	} else {
		memset(pBSSList->abyExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
	}
	pBSSList->sERP.byERP = psERP->byERP;
	pBSSList->sERP.bERPExist = psERP->bERPExist;

	// Check if BSS is 802.11a/b/g
	if (pBSSList->uChannel > CB_MAX_CHANNEL_24G) {
		pBSSList->eNetworkTypeInUse = PHY_TYPE_11A;
	} else {
		if (pBSSList->sERP.bERPExist == true) {
			pBSSList->eNetworkTypeInUse = PHY_TYPE_11G;
		} else {
			pBSSList->eNetworkTypeInUse = PHY_TYPE_11B;
		}
	}

	pBSSList->byRxRate = pRxPacket->byRxRate;
	pBSSList->qwLocalTSF = pRxPacket->qwLocalTSF;
	pBSSList->uRSSI = pRxPacket->uRSSI;
	pBSSList->bySQ = pRxPacket->bySQ;

	if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
	    (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
		// assoc with BSS
		if (pBSSList == pMgmt->pCurrBSS) {
			bParsingQuiet = true;
		}
	}

	WPA_ClearRSN(pBSSList);

	if (pRSNWPA != NULL) {
		unsigned int uLen = pRSNWPA->len + 2;

		if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSNWPA - pbyIEs))) {
			pBSSList->wWPALen = uLen;
			memcpy(pBSSList->byWPAIE, pRSNWPA, uLen);
			WPA_ParseRSN(pBSSList, pRSNWPA);
		}
	}

	WPA2_ClearRSN(pBSSList);

	if (pRSN != NULL) {
		unsigned int uLen = pRSN->len + 2;
		if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSN - pbyIEs))) {
			pBSSList->wRSNLen = uLen;
			memcpy(pBSSList->byRSNIE, pRSN, uLen);
			WPA2vParseRSN(pBSSList, pRSN);
		}
	}

	if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || (pBSSList->bWPA2Valid == true)) {
		PSKeyItem  pTransmitKey = NULL;
		bool bIs802_1x = false;

		for (ii = 0; ii < pBSSList->wAKMSSAuthCount; ii++) {
			if (pBSSList->abyAKMSSAuthType[ii] == WLAN_11i_AKMSS_802_1X) {
				bIs802_1x = true;
				break;
			}
		}
		if ((bIs802_1x == true) && (pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len) &&
		    (!memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID, pSSID->len))) {
			bAdd_PMKID_Candidate((void *)pDevice, pBSSList->abyBSSID, &pBSSList->sRSNCapObj);

			if ((pDevice->bLinkPass == true) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
				if ((KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, PAIRWISE_KEY, &pTransmitKey) == true) ||
				    (KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, GROUP_KEY, &pTransmitKey) == true)) {
					pDevice->gsPMKIDCandidate.StatusType = Ndis802_11StatusType_PMKID_CandidateList;
					pDevice->gsPMKIDCandidate.Version = 1;

				}

			}
		}
	}

	if (pDevice->bUpdateBBVGA) {
		// Moniter if RSSI is too strong.
		pBSSList->byRSSIStatCnt = 0;
		RFvRSSITodBm(pDevice, (unsigned char)(pRxPacket->uRSSI), &pBSSList->ldBmMAX);
		pBSSList->ldBmAverage[0] = pBSSList->ldBmMAX;
		for (ii = 1; ii < RSSI_STAT_COUNT; ii++)
			pBSSList->ldBmAverage[ii] = 0;
	}

	if ((pIE_Country != NULL) &&
	    (pMgmt->b11hEnable == true)) {
		set_country_info(pMgmt->pAdapter, pBSSList->eNetworkTypeInUse,
				 pIE_Country);
	}

	if ((bParsingQuiet == true) && (pIE_Quiet != NULL)) {
		if ((((PWLAN_IE_QUIET)pIE_Quiet)->len == 8) &&
		    (((PWLAN_IE_QUIET)pIE_Quiet)->byQuietCount != 0)) {
			// valid EID
			if (pQuiet == NULL) {
				pQuiet = (PWLAN_IE_QUIET)pIE_Quiet;
				CARDbSetQuiet(pMgmt->pAdapter,
					      true,
					      pQuiet->byQuietCount,
					      pQuiet->byQuietPeriod,
					      *((unsigned short *)pQuiet->abyQuietDuration),
					      *((unsigned short *)pQuiet->abyQuietOffset)
);
			} else {
				pQuiet = (PWLAN_IE_QUIET)pIE_Quiet;
				CARDbSetQuiet(pMgmt->pAdapter,
					      false,
					      pQuiet->byQuietCount,
					      pQuiet->byQuietPeriod,
					      *((unsigned short *)pQuiet->abyQuietDuration),
					      *((unsigned short *)pQuiet->abyQuietOffset)
					);
			}
		}
	}

	if ((bParsingQuiet == true) &&
	    (pQuiet != NULL)) {
		CARDbStartQuiet(pMgmt->pAdapter);
	}

	pBSSList->uIELength = uIELength;
	if (pBSSList->uIELength > WLAN_BEACON_FR_MAXLEN)
		pBSSList->uIELength = WLAN_BEACON_FR_MAXLEN;
	memcpy(pBSSList->abyIEs, pbyIEs, pBSSList->uIELength);

	return true;
}

/*+
 *
 * Routine Description:
 *    Update BSS set in known BSS list
 *
 * Return Value:
 *    true if success.
 *
 -*/
// TODO: input structure modify

bool
BSSbUpdateToBSSList(
	void *hDeviceContext,
	QWORD qwTimestamp,
	unsigned short wBeaconInterval,
	unsigned short wCapInfo,
	unsigned char byCurrChannel,
	bool bChannelHit,
	PWLAN_IE_SSID pSSID,
	PWLAN_IE_SUPP_RATES pSuppRates,
	PWLAN_IE_SUPP_RATES pExtSuppRates,
	PERPObject psERP,
	PWLAN_IE_RSN pRSN,
	PWLAN_IE_RSN_EXT pRSNWPA,
	PWLAN_IE_COUNTRY pIE_Country,
	PWLAN_IE_QUIET pIE_Quiet,
	PKnownBSS pBSSList,
	unsigned int uIELength,
	unsigned char *pbyIEs,
	void *pRxPacketContext
)
{
	int             ii;
	PSDevice        pDevice = (PSDevice)hDeviceContext;
	PSMgmtObject    pMgmt = pDevice->pMgmt;
	PSRxMgmtPacket  pRxPacket = (PSRxMgmtPacket)pRxPacketContext;
	long            ldBm;
	bool bParsingQuiet = false;
	PWLAN_IE_QUIET  pQuiet = NULL;

	if (pBSSList == NULL)
		return false;

	HIDWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(HIDWORD(qwTimestamp));
	LODWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(LODWORD(qwTimestamp));
	pBSSList->wBeaconInterval = cpu_to_le16(wBeaconInterval);
	pBSSList->wCapInfo = cpu_to_le16(wCapInfo);
	pBSSList->uClearCount = 0;
	pBSSList->uChannel = byCurrChannel;
//    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSSbUpdateToBSSList: pBSSList->uChannel: %d\n", pBSSList->uChannel);

	if (pSSID->len > WLAN_SSID_MAXLEN)
		pSSID->len = WLAN_SSID_MAXLEN;

	if ((pSSID->len != 0) && (pSSID->abySSID[0] != 0))
		memcpy(pBSSList->abySSID, pSSID, pSSID->len + WLAN_IEHDR_LEN);
	memcpy(pBSSList->abySuppRates, pSuppRates, pSuppRates->len + WLAN_IEHDR_LEN);

	if (pExtSuppRates != NULL) {
		memcpy(pBSSList->abyExtSuppRates, pExtSuppRates, pExtSuppRates->len + WLAN_IEHDR_LEN);
	} else {
		memset(pBSSList->abyExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
	}
	pBSSList->sERP.byERP = psERP->byERP;
	pBSSList->sERP.bERPExist = psERP->bERPExist;

	// Check if BSS is 802.11a/b/g
	if (pBSSList->uChannel > CB_MAX_CHANNEL_24G) {
		pBSSList->eNetworkTypeInUse = PHY_TYPE_11A;
	} else {
		if (pBSSList->sERP.bERPExist == true) {
			pBSSList->eNetworkTypeInUse = PHY_TYPE_11G;
		} else {
			pBSSList->eNetworkTypeInUse = PHY_TYPE_11B;
		}
	}

	pBSSList->byRxRate = pRxPacket->byRxRate;
	pBSSList->qwLocalTSF = pRxPacket->qwLocalTSF;
	if (bChannelHit)
		pBSSList->uRSSI = pRxPacket->uRSSI;
	pBSSList->bySQ = pRxPacket->bySQ;

	if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
	    (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
		// assoc with BSS
		if (pBSSList == pMgmt->pCurrBSS) {
			bParsingQuiet = true;
		}
	}

	WPA_ClearRSN(pBSSList);         //mike update

	if (pRSNWPA != NULL) {
		unsigned int uLen = pRSNWPA->len + 2;
		if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSNWPA - pbyIEs))) {
			pBSSList->wWPALen = uLen;
			memcpy(pBSSList->byWPAIE, pRSNWPA, uLen);
			WPA_ParseRSN(pBSSList, pRSNWPA);
		}
	}

	WPA2_ClearRSN(pBSSList);  //mike update

	if (pRSN != NULL) {
		unsigned int uLen = pRSN->len + 2;
		if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSN - pbyIEs))) {
			pBSSList->wRSNLen = uLen;
			memcpy(pBSSList->byRSNIE, pRSN, uLen);
			WPA2vParseRSN(pBSSList, pRSN);
		}
	}

	if (pRxPacket->uRSSI != 0) {
		RFvRSSITodBm(pDevice, (unsigned char)(pRxPacket->uRSSI), &ldBm);
		// Moniter if RSSI is too strong.
		pBSSList->byRSSIStatCnt++;
		pBSSList->byRSSIStatCnt %= RSSI_STAT_COUNT;
		pBSSList->ldBmAverage[pBSSList->byRSSIStatCnt] = ldBm;
		for (ii = 0; ii < RSSI_STAT_COUNT; ii++) {
			if (pBSSList->ldBmAverage[ii] != 0) {
				pBSSList->ldBmMAX = max(pBSSList->ldBmAverage[ii], ldBm);
			}
		}
	}

	if ((pIE_Country != NULL) &&
	    (pMgmt->b11hEnable == true)) {
		set_country_info(pMgmt->pAdapter, pBSSList->eNetworkTypeInUse,
				 pIE_Country);
	}

	if ((bParsingQuiet == true) && (pIE_Quiet != NULL)) {
		if ((((PWLAN_IE_QUIET)pIE_Quiet)->len == 8) &&
		    (((PWLAN_IE_QUIET)pIE_Quiet)->byQuietCount != 0)) {
			// valid EID
			if (pQuiet == NULL) {
				pQuiet = (PWLAN_IE_QUIET)pIE_Quiet;
				CARDbSetQuiet(pMgmt->pAdapter,
					      true,
					      pQuiet->byQuietCount,
					      pQuiet->byQuietPeriod,
					      *((unsigned short *)pQuiet->abyQuietDuration),
					      *((unsigned short *)pQuiet->abyQuietOffset)
);
			} else {
				pQuiet = (PWLAN_IE_QUIET)pIE_Quiet;
				CARDbSetQuiet(pMgmt->pAdapter,
					      false,
					      pQuiet->byQuietCount,
					      pQuiet->byQuietPeriod,
					      *((unsigned short *)pQuiet->abyQuietDuration),
					      *((unsigned short *)pQuiet->abyQuietOffset)
					);
			}
		}
	}

	if ((bParsingQuiet == true) &&
	    (pQuiet != NULL)) {
		CARDbStartQuiet(pMgmt->pAdapter);
	}

	pBSSList->uIELength = uIELength;
	if (pBSSList->uIELength > WLAN_BEACON_FR_MAXLEN)
		pBSSList->uIELength = WLAN_BEACON_FR_MAXLEN;
	memcpy(pBSSList->abyIEs, pbyIEs, pBSSList->uIELength);

	return true;
}

/*+
 *
 * Routine Description:
 *    Search Node DB table to find the index of matched DstAddr
 *
 * Return Value:
 *    None
 *
 -*/

bool
BSSDBbIsSTAInNodeDB(void *pMgmtObject, unsigned char *abyDstAddr,
		    unsigned int *puNodeIndex)
{
	PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtObject;
	unsigned int ii;

	// Index = 0 reserved for AP Node
	for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
		if (pMgmt->sNodeDBTable[ii].bActive) {
			if (!compare_ether_addr(abyDstAddr, pMgmt->sNodeDBTable[ii].abyMACAddr)) {
				*puNodeIndex = ii;
				return true;
			}
		}
	}

	return false;
};

/*+
 *
 * Routine Description:
 *    Find an empty node and allocat it; if there is no empty node,
 *    then use the most inactive one.
 *
 * Return Value:
 *    None
 *
 -*/
void
BSSvCreateOneNode(void *hDeviceContext, unsigned int *puNodeIndex)
{
	PSDevice     pDevice = (PSDevice)hDeviceContext;
	PSMgmtObject    pMgmt = pDevice->pMgmt;
	unsigned int ii;
	unsigned int BigestCount = 0;
	unsigned int SelectIndex;
	struct sk_buff  *skb;
	// Index = 0 reserved for AP Node (In STA mode)
	// Index = 0 reserved for Broadcast/MultiCast (In AP mode)
	SelectIndex = 1;
	for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
		if (pMgmt->sNodeDBTable[ii].bActive) {
			if (pMgmt->sNodeDBTable[ii].uInActiveCount > BigestCount) {
				BigestCount = pMgmt->sNodeDBTable[ii].uInActiveCount;
				SelectIndex = ii;
			}
		} else {
			break;
		}
	}

	// if not found replace uInActiveCount is largest one.
	if (ii == (MAX_NODE_NUM + 1)) {
		*puNodeIndex = SelectIndex;
		DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Replace inactive node = %d\n", SelectIndex);
		// clear ps buffer
		if (pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue.next != NULL) {
			while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue)) != NULL)
				dev_kfree_skb(skb);
		}
	} else {
		*puNodeIndex = ii;
	}

	memset(&pMgmt->sNodeDBTable[*puNodeIndex], 0, sizeof(KnownNodeDB));
	pMgmt->sNodeDBTable[*puNodeIndex].bActive = true;
	pMgmt->sNodeDBTable[*puNodeIndex].uRatePollTimeout = FALLBACK_POLL_SECOND;
	// for AP mode PS queue
	skb_queue_head_init(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue);
	pMgmt->sNodeDBTable[*puNodeIndex].byAuthSequence = 0;
	pMgmt->sNodeDBTable[*puNodeIndex].wEnQueueCnt = 0;
	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Create node index = %d\n", ii);
	return;
};

/*+
 *
 * Routine Description:
 *    Remove Node by NodeIndex
 *
 *
 * Return Value:
 *    None
 *
 -*/
void
BSSvRemoveOneNode(
	void *hDeviceContext,
	unsigned int uNodeIndex
)
{
	PSDevice        pDevice = (PSDevice)hDeviceContext;
	PSMgmtObject    pMgmt = pDevice->pMgmt;
	unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
	struct sk_buff  *skb;

	while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue)) != NULL)
		dev_kfree_skb(skb);
	// clear context
	memset(&pMgmt->sNodeDBTable[uNodeIndex], 0, sizeof(KnownNodeDB));
	// clear tx bit map
	pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[uNodeIndex].wAID >> 3] &=  ~byMask[pMgmt->sNodeDBTable[uNodeIndex].wAID & 7];

	return;
};
/*+
 *
 * Routine Description:
 *    Update AP Node content in Index 0 of KnownNodeDB
 *
 *
 * Return Value:
 *    None
 *
 -*/

void
BSSvUpdateAPNode(
	void *hDeviceContext,
	unsigned short *pwCapInfo,
	PWLAN_IE_SUPP_RATES pSuppRates,
	PWLAN_IE_SUPP_RATES pExtSuppRates
)
{
	PSDevice     pDevice = (PSDevice)hDeviceContext;
	PSMgmtObject    pMgmt = pDevice->pMgmt;
	unsigned int uRateLen = WLAN_RATES_MAXLEN;

	memset(&pMgmt->sNodeDBTable[0], 0, sizeof(KnownNodeDB));

	pMgmt->sNodeDBTable[0].bActive = true;
	if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
		uRateLen = WLAN_RATES_MAXLEN_11B;
	}
	pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pSuppRates,
						(PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
						uRateLen);
	pMgmt->abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pExtSuppRates,
						   (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
						   uRateLen);
	RATEvParseMaxRate((void *)pDevice,
			  (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
			  (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
			  true,
			  &(pMgmt->sNodeDBTable[0].wMaxBasicRate),
			  &(pMgmt->sNodeDBTable[0].wMaxSuppRate),
			  &(pMgmt->sNodeDBTable[0].wSuppRate),
			  &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate),
			  &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate)
);
	memcpy(pMgmt->sNodeDBTable[0].abyMACAddr, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN);
	pMgmt->sNodeDBTable[0].wTxDataRate = pMgmt->sNodeDBTable[0].wMaxSuppRate;
	pMgmt->sNodeDBTable[0].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*pwCapInfo);
	pMgmt->sNodeDBTable[0].uRatePollTimeout = FALLBACK_POLL_SECOND;
#ifdef	PLICE_DEBUG
	printk("BSSvUpdateAPNode:MaxSuppRate is %d\n", pMgmt->sNodeDBTable[0].wMaxSuppRate);
#endif
	// Auto rate fallback function initiation.
	// RATEbInit(pDevice);
	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->sNodeDBTable[0].wTxDataRate = %d \n", pMgmt->sNodeDBTable[0].wTxDataRate);
};

/*+
 *
 * Routine Description:
 *    Add Multicast Node content in Index 0 of KnownNodeDB
 *
 *
 * Return Value:
 *    None
 *
 -*/

void
BSSvAddMulticastNode(
	void *hDeviceContext
)
{
	PSDevice     pDevice = (PSDevice)hDeviceContext;
	PSMgmtObject    pMgmt = pDevice->pMgmt;

	if (!pDevice->bEnableHostWEP)
		memset(&pMgmt->sNodeDBTable[0], 0, sizeof(KnownNodeDB));
	memset(pMgmt->sNodeDBTable[0].abyMACAddr, 0xff, WLAN_ADDR_LEN);
	pMgmt->sNodeDBTable[0].bActive = true;
	pMgmt->sNodeDBTable[0].bPSEnable = false;
	skb_queue_head_init(&pMgmt->sNodeDBTable[0].sTxPSQueue);
	RATEvParseMaxRate((void *)pDevice,
			  (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
			  (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
			  true,
			  &(pMgmt->sNodeDBTable[0].wMaxBasicRate),
			  &(pMgmt->sNodeDBTable[0].wMaxSuppRate),
			  &(pMgmt->sNodeDBTable[0].wSuppRate),
			  &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate),
			  &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate)
);
	pMgmt->sNodeDBTable[0].wTxDataRate = pMgmt->sNodeDBTable[0].wMaxBasicRate;
#ifdef	PLICE_DEBUG
	printk("BSSvAddMultiCastNode:pMgmt->sNodeDBTable[0].wTxDataRate is %d\n", pMgmt->sNodeDBTable[0].wTxDataRate);
#endif
	pMgmt->sNodeDBTable[0].uRatePollTimeout = FALLBACK_POLL_SECOND;
};

/*+
 *
 * Routine Description:
 *
 *
 *  Second call back function to update Node DB info & AP link status
 *
 *
 * Return Value:
 *    none.
 *
 -*/
//2008-4-14 <add> by chester for led issue
#ifdef FOR_LED_ON_NOTEBOOK
bool cc = false;
unsigned int status;
#endif
void
BSSvSecondCallBack(
	void *hDeviceContext
)
{
	PSDevice        pDevice = (PSDevice)hDeviceContext;
	PSMgmtObject    pMgmt = pDevice->pMgmt;
	unsigned int ii;
	PWLAN_IE_SSID   pItemSSID, pCurrSSID;
	unsigned int uSleepySTACnt = 0;
	unsigned int uNonShortSlotSTACnt = 0;
	unsigned int uLongPreambleSTACnt = 0;
	viawget_wpa_header *wpahdr;  //DavidWang

	spin_lock_irq(&pDevice->lock);

	pDevice->uAssocCount = 0;

	pDevice->byERPFlag &=
		~(WLAN_SET_ERP_BARKER_MODE(1) | WLAN_SET_ERP_NONERP_PRESENT(1));
	//2008-4-14 <add> by chester for led issue
#ifdef FOR_LED_ON_NOTEBOOK
	MACvGPIOIn(pDevice->PortOffset, &pDevice->byGPIO);
	if (((!(pDevice->byGPIO & GPIO0_DATA) && (pDevice->bHWRadioOff == false)) || ((pDevice->byGPIO & GPIO0_DATA) && (pDevice->bHWRadioOff == true))) && (cc == false)) {
		cc = true;
	} else if (cc == true) {
		if (pDevice->bHWRadioOff == true) {
			if (!(pDevice->byGPIO & GPIO0_DATA))
//||(!(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV)))
			{
				if (status == 1) goto start;
				status = 1;
				CARDbRadioPowerOff(pDevice);
				pMgmt->sNodeDBTable[0].bActive = false;
				pMgmt->eCurrMode = WMAC_MODE_STANDBY;
				pMgmt->eCurrState = WMAC_STATE_IDLE;
				//netif_stop_queue(pDevice->dev);
				pDevice->bLinkPass = false;

			}
			if (pDevice->byGPIO & GPIO0_DATA)
//||(!(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV)))
			{
				if (status == 2) goto start;
				status = 2;
				CARDbRadioPowerOn(pDevice);
			}
		} else {
			if (pDevice->byGPIO & GPIO0_DATA)
//||(!(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV)))
			{
				if (status == 3) goto start;
				status = 3;
				CARDbRadioPowerOff(pDevice);
				pMgmt->sNodeDBTable[0].bActive = false;
				pMgmt->eCurrMode = WMAC_MODE_STANDBY;
				pMgmt->eCurrState = WMAC_STATE_IDLE;
				//netif_stop_queue(pDevice->dev);
				pDevice->bLinkPass = false;

			}
			if (!(pDevice->byGPIO & GPIO0_DATA))
//||(!(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV)))
			{
				if (status == 4) goto start;
				status = 4;
				CARDbRadioPowerOn(pDevice);
			}
		}
	}
start:
#endif

	if (pDevice->wUseProtectCntDown > 0) {
		pDevice->wUseProtectCntDown--;
	} else {
		// disable protect mode
		pDevice->byERPFlag &= ~(WLAN_SET_ERP_USE_PROTECTION(1));
	}

	if (pDevice->eCommandState == WLAN_ASSOCIATE_WAIT) {
		pDevice->byReAssocCount++;
		if ((pDevice->byReAssocCount > 10) && (pDevice->bLinkPass != true)) {  //10 sec timeout
			printk("Re-association timeout!!!\n");
			pDevice->byReAssocCount = 0;
#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
			{
				union iwreq_data  wrqu;
				memset(&wrqu, 0, sizeof(wrqu));
				wrqu.ap_addr.sa_family = ARPHRD_ETHER;
				PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
				wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
			}
#endif
		} else if (pDevice->bLinkPass == true)
			pDevice->byReAssocCount = 0;
	}

#ifdef Calcu_LinkQual
	s_uCalculateLinkQual((void *)pDevice);
#endif

	for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) {
		if (pMgmt->sNodeDBTable[ii].bActive) {
			// Increase in-activity counter
			pMgmt->sNodeDBTable[ii].uInActiveCount++;

			if (ii > 0) {
				if (pMgmt->sNodeDBTable[ii].uInActiveCount > MAX_INACTIVE_COUNT) {
					BSSvRemoveOneNode(pDevice, ii);
					DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
						"Inactive timeout [%d] sec, STA index = [%d] remove\n", MAX_INACTIVE_COUNT, ii);
					continue;
				}

				if (pMgmt->sNodeDBTable[ii].eNodeState >= NODE_ASSOC) {
					pDevice->uAssocCount++;

					// check if Non ERP exist
					if (pMgmt->sNodeDBTable[ii].uInActiveCount < ERP_RECOVER_COUNT) {
						if (!pMgmt->sNodeDBTable[ii].bShortPreamble) {
							pDevice->byERPFlag |= WLAN_SET_ERP_BARKER_MODE(1);
							uLongPreambleSTACnt++;
						}
						if (!pMgmt->sNodeDBTable[ii].bERPExist) {
							pDevice->byERPFlag |= WLAN_SET_ERP_NONERP_PRESENT(1);
							pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1);
						}
						if (!pMgmt->sNodeDBTable[ii].bShortSlotTime)
							uNonShortSlotSTACnt++;
					}
				}

				// check if any STA in PS mode
				if (pMgmt->sNodeDBTable[ii].bPSEnable)
					uSleepySTACnt++;

			}

			// Rate fallback check
			if (!pDevice->bFixRate) {
/*
  if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (ii == 0))
  RATEvTxRateFallBack(pDevice, &(pMgmt->sNodeDBTable[ii]));
*/
				if (ii > 0) {
					// ii = 0 for multicast node (AP & Adhoc)
					RATEvTxRateFallBack((void *)pDevice, &(pMgmt->sNodeDBTable[ii]));
				} else {
					// ii = 0 reserved for unicast AP node (Infra STA)
					if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)
#ifdef	PLICE_DEBUG
						printk("SecondCallback:Before:TxDataRate is %d\n", pMgmt->sNodeDBTable[0].wTxDataRate);
#endif
					RATEvTxRateFallBack((void *)pDevice, &(pMgmt->sNodeDBTable[ii]));
#ifdef	PLICE_DEBUG
					printk("SecondCallback:After:TxDataRate is %d\n", pMgmt->sNodeDBTable[0].wTxDataRate);
#endif

				}

			}

			// check if pending PS queue
			if (pMgmt->sNodeDBTable[ii].wEnQueueCnt != 0) {
				DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index= %d, Queue = %d pending \n",
					ii, pMgmt->sNodeDBTable[ii].wEnQueueCnt);
				if ((ii > 0) && (pMgmt->sNodeDBTable[ii].wEnQueueCnt > 15)) {
					BSSvRemoveOneNode(pDevice, ii);
					DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Pending many queues PS STA Index = %d remove \n", ii);
					continue;
				}
			}
		}

	}

	if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->eCurrentPHYType == PHY_TYPE_11G)) {
		// on/off protect mode
		if (WLAN_GET_ERP_USE_PROTECTION(pDevice->byERPFlag)) {
			if (!pDevice->bProtectMode) {
				MACvEnableProtectMD(pDevice->PortOffset);
				pDevice->bProtectMode = true;
			}
		} else {
			if (pDevice->bProtectMode) {
				MACvDisableProtectMD(pDevice->PortOffset);
				pDevice->bProtectMode = false;
			}
		}
		// on/off short slot time

		if (uNonShortSlotSTACnt > 0) {
			if (pDevice->bShortSlotTime) {
				pDevice->bShortSlotTime = false;
				BBvSetShortSlotTime(pDevice);
				vUpdateIFS((void *)pDevice);
			}
		} else {
			if (!pDevice->bShortSlotTime) {
				pDevice->bShortSlotTime = true;
				BBvSetShortSlotTime(pDevice);
				vUpdateIFS((void *)pDevice);
			}
		}

		// on/off barker long preamble mode

		if (uLongPreambleSTACnt > 0) {
			if (!pDevice->bBarkerPreambleMd) {
				MACvEnableBarkerPreambleMd(pDevice->PortOffset);
				pDevice->bBarkerPreambleMd = true;
			}
		} else {
			if (pDevice->bBarkerPreambleMd) {
				MACvDisableBarkerPreambleMd(pDevice->PortOffset);
				pDevice->bBarkerPreambleMd = false;
			}
		}

	}

	// Check if any STA in PS mode, enable DTIM multicast deliver
	if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
		if (uSleepySTACnt > 0)
			pMgmt->sNodeDBTable[0].bPSEnable = true;
		else
			pMgmt->sNodeDBTable[0].bPSEnable = false;
	}

	pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
	pCurrSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;

	if ((pMgmt->eCurrMode == WMAC_MODE_STANDBY) ||
	    (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)) {
		if (pMgmt->sNodeDBTable[0].bActive) { // Assoc with BSS
			if (pDevice->bUpdateBBVGA) {
				// s_vCheckSensitivity((void *) pDevice);
				s_vCheckPreEDThreshold((void *)pDevice);
			}

			if ((pMgmt->sNodeDBTable[0].uInActiveCount >= (LOST_BEACON_COUNT/2)) &&
			    (pDevice->byBBVGACurrent != pDevice->abyBBVGA[0])) {
				pDevice->byBBVGANew = pDevice->abyBBVGA[0];
				bScheduleCommand((void *)pDevice, WLAN_CMD_CHANGE_BBSENSITIVITY, NULL);
			}

			if (pMgmt->sNodeDBTable[0].uInActiveCount >= LOST_BEACON_COUNT) {
				pMgmt->sNodeDBTable[0].bActive = false;
				pMgmt->eCurrMode = WMAC_MODE_STANDBY;
				pMgmt->eCurrState = WMAC_STATE_IDLE;
				netif_stop_queue(pDevice->dev);
				pDevice->bLinkPass = false;
				pDevice->bRoaming = true;
				DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost AP beacon [%d] sec, disconnected !\n", pMgmt->sNodeDBTable[0].uInActiveCount);
				if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
					wpahdr = (viawget_wpa_header *)pDevice->skb->data;
					wpahdr->type = VIAWGET_DISASSOC_MSG;
					wpahdr->resp_ie_len = 0;
					wpahdr->req_ie_len = 0;
					skb_put(pDevice->skb, sizeof(viawget_wpa_header));
					pDevice->skb->dev = pDevice->wpadev;
					skb_reset_mac_header(pDevice->skb);
					pDevice->skb->pkt_type = PACKET_HOST;
					pDevice->skb->protocol = htons(ETH_P_802_2);
					memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
					netif_rx(pDevice->skb);
					pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
				}
#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
				{
					union iwreq_data  wrqu;
					memset(&wrqu, 0, sizeof(wrqu));
					wrqu.ap_addr.sa_family = ARPHRD_ETHER;
					PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
					wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
				}
#endif
			}
		} else if (pItemSSID->len != 0) {
			if (pDevice->uAutoReConnectTime < 10) {
				pDevice->uAutoReConnectTime++;
#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
				//network manager support need not do Roaming scan???
				if (pDevice->bWPASuppWextEnabled == true)
					pDevice->uAutoReConnectTime = 0;
#endif
			} else {
				//mike use old encryption status for wpa reauthen
				if (pDevice->bWPADEVUp)
					pDevice->eEncryptionStatus = pDevice->eOldEncryptionStatus;

				DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Roaming ...\n");
				BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass);
				pMgmt->eScanType = WMAC_SCAN_ACTIVE;
				bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
				bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID);
				pDevice->uAutoReConnectTime = 0;
			}
		}
	}

	if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
		// if adhoc started which essid is NULL string, rescanning.
		if ((pMgmt->eCurrState == WMAC_STATE_STARTED) && (pCurrSSID->len == 0)) {
			if (pDevice->uAutoReConnectTime < 10) {
				pDevice->uAutoReConnectTime++;
			} else {
				DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Adhoc re-scanning ...\n");
				pMgmt->eScanType = WMAC_SCAN_ACTIVE;
				bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL);
				bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL);
				pDevice->uAutoReConnectTime = 0;
			};
		}
		if (pMgmt->eCurrState == WMAC_STATE_JOINTED) {
			if (pDevice->bUpdateBBVGA) {
				//s_vCheckSensitivity((void *) pDevice);
				s_vCheckPreEDThreshold((void *)pDevice);
			}
			if (pMgmt->sNodeDBTable[0].uInActiveCount >= ADHOC_LOST_BEACON_COUNT) {
				DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost other STA beacon [%d] sec, started !\n", pMgmt->sNodeDBTable[0].uInActiveCount);
				pMgmt->sNodeDBTable[0].uInActiveCount = 0;
				pMgmt->eCurrState = WMAC_STATE_STARTED;
				netif_stop_queue(pDevice->dev);
				pDevice->bLinkPass = false;
			}
		}
	}

	spin_unlock_irq(&pDevice->lock);

	pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ);
	add_timer(&pMgmt->sTimerSecondCallback);
	return;
}

/*+
 *
 * Routine Description:
 *
 *
 *  Update Tx attemps, Tx failure counter in Node DB
 *
 *
 * Return Value:
 *    none.
 *
 -*/

void
BSSvUpdateNodeTxCounter(
	void *hDeviceContext,
	unsigned char byTsr0,
	unsigned char byTsr1,
	unsigned char *pbyBuffer,
	unsigned int uFIFOHeaderSize
)
{
	PSDevice        pDevice = (PSDevice)hDeviceContext;
	PSMgmtObject    pMgmt = pDevice->pMgmt;
	unsigned int uNodeIndex = 0;
	unsigned char byTxRetry = (byTsr0 & TSR0_NCR);
	PSTxBufHead     pTxBufHead;
	PS802_11Header  pMACHeader;
	unsigned short wRate;
	unsigned short wFallBackRate = RATE_1M;
	unsigned char byFallBack;
	unsigned int ii;
//	unsigned int txRetryTemp;
//PLICE_DEBUG->
	//txRetryTemp = byTxRetry;
//PLICE_DEBUG <-
	pTxBufHead = (PSTxBufHead) pbyBuffer;
	if (pTxBufHead->wFIFOCtl & FIFOCTL_AUTO_FB_0) {
		byFallBack = AUTO_FB_0;
	} else if (pTxBufHead->wFIFOCtl & FIFOCTL_AUTO_FB_1) {
		byFallBack = AUTO_FB_1;
	} else {
		byFallBack = AUTO_FB_NONE;
	}
	wRate = pTxBufHead->wReserved; //?wRate

	// Only Unicast using support rates
	if (pTxBufHead->wFIFOCtl & FIFOCTL_NEEDACK) {
		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wRate %04X, byTsr0 %02X, byTsr1 %02X\n", wRate, byTsr0, byTsr1);
		if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) {
			pMgmt->sNodeDBTable[0].uTxAttempts += 1;
			if ((byTsr1 & TSR1_TERR) == 0) {
				// transmit success, TxAttempts at least plus one
				pMgmt->sNodeDBTable[0].uTxOk[MAX_RATE]++;
				if ((byFallBack == AUTO_FB_NONE) ||
				    (wRate < RATE_18M)) {
					wFallBackRate = wRate;
				} else if (byFallBack == AUTO_FB_0) {
//PLICE_DEBUG
					if (byTxRetry < 5)
						wFallBackRate = awHWRetry0[wRate-RATE_18M][byTxRetry];
					//wFallBackRate = awHWRetry0[wRate-RATE_12M][byTxRetry];
					//wFallBackRate = awHWRetry0[wRate-RATE_18M][txRetryTemp] +1;
					else
						wFallBackRate = awHWRetry0[wRate-RATE_18M][4];
					//wFallBackRate = awHWRetry0[wRate-RATE_12M][4];
				} else if (byFallBack == AUTO_FB_1) {
					if (byTxRetry < 5)
						wFallBackRate = awHWRetry1[wRate-RATE_18M][byTxRetry];
					else
						wFallBackRate = awHWRetry1[wRate-RATE_18M][4];
				}
				pMgmt->sNodeDBTable[0].uTxOk[wFallBackRate]++;
			} else {
				pMgmt->sNodeDBTable[0].uTxFailures++;
			}
			pMgmt->sNodeDBTable[0].uTxRetry += byTxRetry;
			if (byTxRetry != 0) {
				pMgmt->sNodeDBTable[0].uTxFail[MAX_RATE] += byTxRetry;
				if ((byFallBack == AUTO_FB_NONE) ||
				    (wRate < RATE_18M)) {
					pMgmt->sNodeDBTable[0].uTxFail[wRate] += byTxRetry;
				} else if (byFallBack == AUTO_FB_0) {
//PLICE_DEBUG
					for (ii = 0; ii < byTxRetry; ii++)
						//for (ii=0;ii<txRetryTemp;ii++)
					{
						if (ii < 5) {
//PLICE_DEBUG
							wFallBackRate = awHWRetry0[wRate-RATE_18M][ii];
							//wFallBackRate = awHWRetry0[wRate-RATE_12M][ii];
						} else {
							wFallBackRate = awHWRetry0[wRate-RATE_18M][4];
							//wFallBackRate = awHWRetry0[wRate-RATE_12M][4];
						}
						pMgmt->sNodeDBTable[0].uTxFail[wFallBackRate]++;
					}
				} else if (byFallBack == AUTO_FB_1) {
					for (ii = 0; ii < byTxRetry; ii++) {
						if (ii < 5)
							wFallBackRate = awHWRetry1[wRate-RATE_18M][ii];
						else
							wFallBackRate = awHWRetry1[wRate-RATE_18M][4];
						pMgmt->sNodeDBTable[0].uTxFail[wFallBackRate]++;
					}
				}
			}
		}

		if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ||
		    (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) {
			pMACHeader = (PS802_11Header)(pbyBuffer + uFIFOHeaderSize);

			if (BSSDBbIsSTAInNodeDB((void *)pMgmt,  &(pMACHeader->abyAddr1[0]), &uNodeIndex)) {
				pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts += 1;
				if ((byTsr1 & TSR1_TERR) == 0) {
					// transmit success, TxAttempts at least plus one
					pMgmt->sNodeDBTable[uNodeIndex].uTxOk[MAX_RATE]++;
					if ((byFallBack == AUTO_FB_NONE) ||
					    (wRate < RATE_18M)) {
						wFallBackRate = wRate;
					} else if (byFallBack == AUTO_FB_0) {
						if (byTxRetry < 5)
							wFallBackRate = awHWRetry0[wRate-RATE_18M][byTxRetry];
						else
							wFallBackRate = awHWRetry0[wRate-RATE_18M][4];
					} else if (byFallBack == AUTO_FB_1) {
						if (byTxRetry < 5)
							wFallBackRate = awHWRetry1[wRate-RATE_18M][byTxRetry];
						else
							wFallBackRate = awHWRetry1[wRate-RATE_18M][4];
					}
					pMgmt->sNodeDBTable[uNodeIndex].uTxOk[wFallBackRate]++;
				} else {
					pMgmt->sNodeDBTable[uNodeIndex].uTxFailures++;
				}
				pMgmt->sNodeDBTable[uNodeIndex].uTxRetry += byTxRetry;
				if (byTxRetry != 0) {
					pMgmt->sNodeDBTable[uNodeIndex].uTxFail[MAX_RATE] += byTxRetry;
					if ((byFallBack == AUTO_FB_NONE) ||
					    (wRate < RATE_18M)) {
						pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wRate] += byTxRetry;
					} else if (byFallBack == AUTO_FB_0) {
						for (ii = 0; ii < byTxRetry; ii++) {
							if (ii < 5)
								wFallBackRate = awHWRetry0[wRate - RATE_18M][ii];
							else
								wFallBackRate = awHWRetry0[wRate - RATE_18M][4];
							pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wFallBackRate]++;
						}
					} else if (byFallBack == AUTO_FB_1) {
						for (ii = 0; ii < byTxRetry; ii++) {
							if (ii < 5)
								wFallBackRate = awHWRetry1[wRate-RATE_18M][ii];
							else
								wFallBackRate = awHWRetry1[wRate-RATE_18M][4];
							pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wFallBackRate]++;
						}
					}
				}
			}
		}
	}

	return;
}

/*+
 *
 * Routine Description:
 *    Clear Nodes & skb in DB Table
 *
 *
 * Parameters:
 *  In:
 *      hDeviceContext        - The adapter context.
 *      uStartIndex           - starting index
 *  Out:
 *      none
 *
 * Return Value:
 *    None.
 *
 -*/

void
BSSvClearNodeDBTable(
	void *hDeviceContext,
	unsigned int uStartIndex
)

{
	PSDevice     pDevice = (PSDevice)hDeviceContext;
	PSMgmtObject    pMgmt = pDevice->pMgmt;
	struct sk_buff  *skb;
	unsigned int ii;

	for (ii = uStartIndex; ii < (MAX_NODE_NUM + 1); ii++) {
		if (pMgmt->sNodeDBTable[ii].bActive) {
			// check if sTxPSQueue has been initial
			if (pMgmt->sNodeDBTable[ii].sTxPSQueue.next != NULL) {
				while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL) {
					DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS skb != NULL %d\n", ii);
					dev_kfree_skb(skb);
				}
			}
			memset(&pMgmt->sNodeDBTable[ii], 0, sizeof(KnownNodeDB));
		}
	}

	return;
};

void s_vCheckSensitivity(
	void *hDeviceContext
)
{
	PSDevice        pDevice = (PSDevice)hDeviceContext;
	PKnownBSS       pBSSList = NULL;
	PSMgmtObject    pMgmt = pDevice->pMgmt;
	int             ii;

	if ((pDevice->byLocalID <= REV_ID_VT3253_A1) && (pDevice->byRFType == RF_RFMD2959) &&
	    (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) {
		return;
	}

	if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) ||
	    ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) {
		pBSSList = BSSpAddrIsInBSSList(pDevice, pMgmt->abyCurrBSSID, (PWLAN_IE_SSID)pMgmt->abyCurrSSID);
		if (pBSSList != NULL) {
			// Updata BB Reg if RSSI is too strong.
			long    LocalldBmAverage = 0;
			long    uNumofdBm = 0;
			for (ii = 0; ii < RSSI_STAT_COUNT; ii++) {
				if (pBSSList->ldBmAverage[ii] != 0) {
					uNumofdBm++;
					LocalldBmAverage += pBSSList->ldBmAverage[ii];
				}
			}
			if (uNumofdBm > 0) {
				LocalldBmAverage = LocalldBmAverage/uNumofdBm;
				for (ii = 0; ii < BB_VGA_LEVEL; ii++) {
					DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "LocalldBmAverage:%ld, %ld %02x\n", LocalldBmAverage, pDevice->ldBmThreshold[ii], pDevice->abyBBVGA[ii]);
					if (LocalldBmAverage < pDevice->ldBmThreshold[ii]) {
						pDevice->byBBVGANew = pDevice->abyBBVGA[ii];
						break;
					}
				}
				if (pDevice->byBBVGANew != pDevice->byBBVGACurrent) {
					pDevice->uBBVGADiffCount++;
					if (pDevice->uBBVGADiffCount >= BB_VGA_CHANGE_THRESHOLD)
						bScheduleCommand((void *)pDevice, WLAN_CMD_CHANGE_BBSENSITIVITY, NULL);
				} else {
					pDevice->uBBVGADiffCount = 0;
				}
			}
		}
	}
}

void
BSSvClearAnyBSSJoinRecord(
	void *hDeviceContext
)
{
	PSDevice        pDevice = (PSDevice)hDeviceContext;
	PSMgmtObject    pMgmt = pDevice->pMgmt;
	unsigned int ii;

	for (ii = 0; ii < MAX_BSS_NUM; ii++) {
		pMgmt->sBSSList[ii].bSelected = false;
	}
	return;
}

#ifdef Calcu_LinkQual
void s_uCalculateLinkQual(
	void *hDeviceContext
)
{
	PSDevice        pDevice = (PSDevice)hDeviceContext;
	unsigned long TxOkRatio, TxCnt;
	unsigned long RxOkRatio, RxCnt;
	unsigned long RssiRatio;
	long ldBm;

	TxCnt = pDevice->scStatistic.TxNoRetryOkCount +
		pDevice->scStatistic.TxRetryOkCount +
		pDevice->scStatistic.TxFailCount;
	RxCnt = pDevice->scStatistic.RxFcsErrCnt +
		pDevice->scStatistic.RxOkCnt;
	TxOkRatio = (TxCnt < 6) ? 4000 : ((pDevice->scStatistic.TxNoRetryOkCount * 4000) / TxCnt);
	RxOkRatio = (RxCnt < 6) ? 2000 : ((pDevice->scStatistic.RxOkCnt * 2000) / RxCnt);
//decide link quality
	if (pDevice->bLinkPass != true) {
		pDevice->scStatistic.LinkQuality = 0;
		pDevice->scStatistic.SignalStren = 0;
	} else {
		RFvRSSITodBm(pDevice, (unsigned char)(pDevice->uCurrRSSI), &ldBm);
		if (-ldBm < 50)  {
			RssiRatio = 4000;
		} else if (-ldBm > 90) {
			RssiRatio = 0;
		} else {
			RssiRatio = (40-(-ldBm-50))*4000/40;
		}
		pDevice->scStatistic.SignalStren = RssiRatio/40;
		pDevice->scStatistic.LinkQuality = (RssiRatio+TxOkRatio+RxOkRatio)/100;
	}
	pDevice->scStatistic.RxFcsErrCnt = 0;
	pDevice->scStatistic.RxOkCnt = 0;
	pDevice->scStatistic.TxFailCount = 0;
	pDevice->scStatistic.TxNoRetryOkCount = 0;
	pDevice->scStatistic.TxRetryOkCount = 0;
	return;
}
#endif

void s_vCheckPreEDThreshold(
	void *hDeviceContext
)
{
	PSDevice        pDevice = (PSDevice)hDeviceContext;
	PKnownBSS       pBSSList = NULL;
	PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);

	if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) ||
	    ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) {
		pBSSList = BSSpAddrIsInBSSList(pDevice, pMgmt->abyCurrBSSID, (PWLAN_IE_SSID)pMgmt->abyCurrSSID);
		if (pBSSList != NULL) {
			pDevice->byBBPreEDRSSI = (unsigned char) (~(pBSSList->ldBmAverRange) + 1);
			//BBvUpdatePreEDThreshold(pDevice, false);
		}
	}
	return;
}
