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

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)
				pCurrBSS->bSelected = false;
			if ((pCurrBSS->bActive) &&
			    (!pCurrBSS->bSelected)) {
				if (ether_addr_equal(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 (pSelect == NULL) {
					pSelect = pCurrBSS;
				} else {
					/* compare RSSI, select signal strong one */
					if (pCurrBSS->uRSSI < pSelect->uRSSI)
						pSelect = pCurrBSS;
				}
			}
		}
		if (pSelect != NULL) {
			pSelect->bSelected = true;
			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 &&
			    ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID,
					     pMgmt->abyCurrBSSID)) {
				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 (ether_addr_equal(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)
			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) {
		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 && (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 && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
				if (KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, PAIRWISE_KEY, &pTransmitKey) ||
				    KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, GROUP_KEY, &pTransmitKey)) {
					pDevice->gsPMKIDCandidate.StatusType = Ndis802_11StatusType_PMKID_CandidateList;
					pDevice->gsPMKIDCandidate.Version = 1;

				}

			}
		}
	}

	if (pDevice->bUpdateBBVGA) {
		/* monitor 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) {
		set_country_info(pMgmt->pAdapter, pBSSList->eNetworkTypeInUse,
				 pIE_Country);
	}

	if (bParsingQuiet && (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 && (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;

	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)
			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);
		/* monitor 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) {
		set_country_info(pMgmt->pAdapter, pBSSList->eNetworkTypeInUse,
				 pIE_Country);
	}

	if (bParsingQuiet && (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 && (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 (ether_addr_equal(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;
	netdev_dbg(pDevice->dev, "BSSvUpdateAPNode:MaxSuppRate is %d\n",
		   pMgmt->sNodeDBTable[0].wMaxSuppRate);
	/* auto rate fallback function initiation */
	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;
	netdev_dbg(pDevice->dev,
		   "BSSvAddMultiCastNode:pMgmt->sNodeDBTable[0].wTxDataRate is %d\n",
		   pMgmt->sNodeDBTable[0].wTxDataRate);
	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)) ||
	     ((pDevice->byGPIO & GPIO0_DATA) && pDevice->bHWRadioOff)) &&
	    (!cc)) {
		cc = true;
	} else if (cc) {
		if (pDevice->bHWRadioOff) {
			if (!(pDevice->byGPIO & GPIO0_DATA)) {
				if (status == 1)
					goto start;
				status = 1;
				CARDbRadioPowerOff(pDevice);
				pMgmt->sNodeDBTable[0].bActive = false;
				pMgmt->eCurrMode = WMAC_MODE_STANDBY;
				pMgmt->eCurrState = WMAC_STATE_IDLE;
				pDevice->bLinkPass = false;

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

			}
			if (!(pDevice->byGPIO & GPIO0_DATA)) {
				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));
	}

	{
		pDevice->byReAssocCount++;
		/* 10 sec timeout */
		if ((pDevice->byReAssocCount > 10) && (!pDevice->bLinkPass)) {
			netdev_info(pDevice->dev, "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)
			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 (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)
						netdev_dbg(pDevice->dev,
							   "SecondCallback:Before:TxDataRate is %d\n",
							   pMgmt->sNodeDBTable[0].wTxDataRate);
					RATEvTxRateFallBack((void *)pDevice, &(pMgmt->sNodeDBTable[ii]));
					netdev_dbg(pDevice->dev,
						   "SecondCallback:After:TxDataRate is %d\n",
						   pMgmt->sNodeDBTable[0].wTxDataRate);

				}

			}

			/* 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)) {
		/* assoc with BSS */
		if (pMgmt->sNodeDBTable[0].bActive) {
			if (pDevice->bUpdateBBVGA)
				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)
					pDevice->uAutoReConnectTime = 0;
#endif
			} else {
				/*
				 * mike use old encryption status
				 * for wpa reauthentication
				 */
				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_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;
	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;

	/* 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) {
					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[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) {
					for (ii = 0; ii < byTxRetry; ii++) {
						if (ii < 5)
							wFallBackRate = awHWRetry0[wRate-RATE_18M][ii];
						else
							wFallBackRate = awHWRetry0[wRate-RATE_18M][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) {
			/* Update 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) {
		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);
	}
	return;
}
