/*
 * 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: card.c
 * Purpose: Provide functions to setup NIC operation mode
 * Functions:
 *      s_vSafeResetTx - Rest Tx
 *      CARDvSetRSPINF - Set RSPINF
 *      vUpdateIFS - Update slotTime,SIFS,DIFS, and EIFS
 *      CARDvUpdateBasicTopRate - Update BasicTopRate
 *      CARDbAddBasicRate - Add to BasicRateSet
 *      CARDbSetBasicRate - Set Basic Tx Rate
 *      CARDbIsOFDMinBasicRate - Check if any OFDM rate is in BasicRateSet
 *      CARDvSetLoopbackMode - Set Loopback mode
 *      CARDbSoftwareReset - Sortware reset NIC
 *      CARDqGetTSFOffset - Calculate TSFOffset
 *      CARDbGetCurrentTSF - Read Current NIC TSF counter
 *      CARDqGetNextTBTT - Calculate Next Beacon TSF counter
 *      CARDvSetFirstNextTBTT - Set NIC Beacon time
 *      CARDvUpdateNextTBTT - Sync. NIC Beacon time
 *      CARDbRadioPowerOff - Turn Off NIC Radio Power
 *      CARDbRadioPowerOn - Turn On NIC Radio Power
 *      CARDbSetWEPMode - Set NIC Wep mode
 *      CARDbSetTxPower - Set NIC tx power
 *
 * Revision History:
 *      06-10-2003 Bryan YC Fan:  Re-write codes to support VT3253 spec.
 *      08-26-2003 Kyle Hsu:      Modify the defination type of dwIoBase.
 *      09-01-2003 Bryan YC Fan:  Add vUpdateIFS().
 *
 */

#include "tmacro.h"
#include "card.h"
#include "baseband.h"
#include "mac.h"
#include "desc.h"
#include "rf.h"
#include "vntwifi.h"
#include "power.h"
#include "key.h"
#include "rc4.h"
#include "country.h"
#include "channel.h"

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

//static int          msglevel                =MSG_LEVEL_DEBUG;
static int msglevel = MSG_LEVEL_INFO;

#define C_SIFS_A        16      // micro sec.
#define C_SIFS_BG       10

#define C_EIFS          80      // micro sec.

#define C_SLOT_SHORT    9       // micro sec.
#define C_SLOT_LONG     20

#define C_CWMIN_A       15      // slot time
#define C_CWMIN_B       31

#define C_CWMAX         1023    // slot time

#define WAIT_BEACON_TX_DOWN_TMO         3    // Times

//1M,   2M,   5M,  11M,  18M,  24M,  36M,  54M
static unsigned char abyDefaultSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C};
//6M,   9M,  12M,  48M
static unsigned char abyDefaultExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60};
//6M,   9M,  12M,  18M,  24M,  36M,  48M,  54M
static unsigned char abyDefaultSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
//1M,   2M,   5M,  11M,
static unsigned char abyDefaultSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16};

/*---------------------  Static Variables  --------------------------*/

const unsigned short cwRXBCNTSFOff[MAX_RATE] =
{17, 17, 17, 17, 34, 23, 17, 11, 8, 5, 4, 3};

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

static
void
s_vCalculateOFDMRParameter(
	unsigned char byRate,
	CARD_PHY_TYPE ePHYType,
	unsigned char *pbyTxRate,
	unsigned char *pbyRsvTime
);

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

/*
 * Description: Calculate TxRate and RsvTime fields for RSPINF in OFDM mode.
 *
 * Parameters:
 *  In:
 *      wRate           - Tx Rate
 *      byPktType       - Tx Packet type
 *  Out:
 *      pbyTxRate       - pointer to RSPINF TxRate field
 *      pbyRsvTime      - pointer to RSPINF RsvTime field
 *
 * Return Value: none
 *
 */
static
void
s_vCalculateOFDMRParameter(
	unsigned char byRate,
	CARD_PHY_TYPE ePHYType,
	unsigned char *pbyTxRate,
	unsigned char *pbyRsvTime
)
{
	switch (byRate) {
	case RATE_6M:
		if (ePHYType == PHY_TYPE_11A) {//5GHZ
			*pbyTxRate = 0x9B;
			*pbyRsvTime = 44;
		} else {
			*pbyTxRate = 0x8B;
			*pbyRsvTime = 50;
		}
		break;

	case RATE_9M:
		if (ePHYType == PHY_TYPE_11A) {//5GHZ
			*pbyTxRate = 0x9F;
			*pbyRsvTime = 36;
		} else {
			*pbyTxRate = 0x8F;
			*pbyRsvTime = 42;
		}
		break;

	case RATE_12M:
		if (ePHYType == PHY_TYPE_11A) {//5GHZ
			*pbyTxRate = 0x9A;
			*pbyRsvTime = 32;
		} else {
			*pbyTxRate = 0x8A;
			*pbyRsvTime = 38;
		}
		break;

	case RATE_18M:
		if (ePHYType == PHY_TYPE_11A) {//5GHZ
			*pbyTxRate = 0x9E;
			*pbyRsvTime = 28;
		} else {
			*pbyTxRate = 0x8E;
			*pbyRsvTime = 34;
		}
		break;

	case RATE_36M:
		if (ePHYType == PHY_TYPE_11A) {//5GHZ
			*pbyTxRate = 0x9D;
			*pbyRsvTime = 24;
		} else {
			*pbyTxRate = 0x8D;
			*pbyRsvTime = 30;
		}
		break;

	case RATE_48M:
		if (ePHYType == PHY_TYPE_11A) {//5GHZ
			*pbyTxRate = 0x98;
			*pbyRsvTime = 24;
		} else {
			*pbyTxRate = 0x88;
			*pbyRsvTime = 30;
		}
		break;

	case RATE_54M:
		if (ePHYType == PHY_TYPE_11A) {//5GHZ
			*pbyTxRate = 0x9C;
			*pbyRsvTime = 24;
		} else {
			*pbyTxRate = 0x8C;
			*pbyRsvTime = 30;
		}
		break;

	case RATE_24M:
	default:
		if (ePHYType == PHY_TYPE_11A) {//5GHZ
			*pbyTxRate = 0x99;
			*pbyRsvTime = 28;
		} else {
			*pbyTxRate = 0x89;
			*pbyRsvTime = 34;
		}
		break;
	}
}

/*
 * Description: Set RSPINF
 *
 * Parameters:
 *  In:
 *      pDevice             - The adapter to be set
 *  Out:
 *      none
 *
 * Return Value: None.
 *
 */
static
void
s_vSetRSPINF(PSDevice pDevice, CARD_PHY_TYPE ePHYType, void *pvSupportRateIEs, void *pvExtSupportRateIEs)
{
	unsigned char byServ = 0, bySignal = 0; // For CCK
	unsigned short wLen = 0;
	unsigned char byTxRate = 0, byRsvTime = 0;    // For OFDM

	//Set to Page1
	MACvSelectPage1(pDevice->PortOffset);

	//RSPINF_b_1
	BBvCalculateParameter(pDevice,
			      14,
			      VNTWIFIbyGetACKTxRate(RATE_1M, pvSupportRateIEs, pvExtSupportRateIEs),
			      PK_TYPE_11B,
			      &wLen,
			      &byServ,
			      &bySignal
);

	VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_1, MAKEDWORD(wLen, MAKEWORD(bySignal, byServ)));
	///RSPINF_b_2
	BBvCalculateParameter(pDevice,
			      14,
			      VNTWIFIbyGetACKTxRate(RATE_2M, pvSupportRateIEs, pvExtSupportRateIEs),
			      PK_TYPE_11B,
			      &wLen,
			      &byServ,
			      &bySignal
);

	VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_2, MAKEDWORD(wLen, MAKEWORD(bySignal, byServ)));
	//RSPINF_b_5
	BBvCalculateParameter(pDevice,
			      14,
			      VNTWIFIbyGetACKTxRate(RATE_5M, pvSupportRateIEs, pvExtSupportRateIEs),
			      PK_TYPE_11B,
			      &wLen,
			      &byServ,
			      &bySignal
);

	VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_5, MAKEDWORD(wLen, MAKEWORD(bySignal, byServ)));
	//RSPINF_b_11
	BBvCalculateParameter(pDevice,
			      14,
			      VNTWIFIbyGetACKTxRate(RATE_11M, pvSupportRateIEs, pvExtSupportRateIEs),
			      PK_TYPE_11B,
			      &wLen,
			      &byServ,
			      &bySignal
);

	VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_11, MAKEDWORD(wLen, MAKEWORD(bySignal, byServ)));
	//RSPINF_a_6
	s_vCalculateOFDMRParameter(RATE_6M,
				   ePHYType,
				   &byTxRate,
				   &byRsvTime);
	VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_6, MAKEWORD(byTxRate, byRsvTime));
	//RSPINF_a_9
	s_vCalculateOFDMRParameter(RATE_9M,
				   ePHYType,
				   &byTxRate,
				   &byRsvTime);
	VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_9, MAKEWORD(byTxRate, byRsvTime));
	//RSPINF_a_12
	s_vCalculateOFDMRParameter(RATE_12M,
				   ePHYType,
				   &byTxRate,
				   &byRsvTime);
	VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_12, MAKEWORD(byTxRate, byRsvTime));
	//RSPINF_a_18
	s_vCalculateOFDMRParameter(RATE_18M,
				   ePHYType,
				   &byTxRate,
				   &byRsvTime);
	VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_18, MAKEWORD(byTxRate, byRsvTime));
	//RSPINF_a_24
	s_vCalculateOFDMRParameter(RATE_24M,
				   ePHYType,
				   &byTxRate,
				   &byRsvTime);
	VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_24, MAKEWORD(byTxRate, byRsvTime));
	//RSPINF_a_36
	s_vCalculateOFDMRParameter(
		VNTWIFIbyGetACKTxRate(RATE_36M, pvSupportRateIEs, pvExtSupportRateIEs),
		ePHYType,
		&byTxRate,
		&byRsvTime);
	VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_36, MAKEWORD(byTxRate, byRsvTime));
	//RSPINF_a_48
	s_vCalculateOFDMRParameter(
		VNTWIFIbyGetACKTxRate(RATE_48M, pvSupportRateIEs, pvExtSupportRateIEs),
		ePHYType,
		&byTxRate,
		&byRsvTime);
	VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_48, MAKEWORD(byTxRate, byRsvTime));
	//RSPINF_a_54
	s_vCalculateOFDMRParameter(
		VNTWIFIbyGetACKTxRate(RATE_54M, pvSupportRateIEs, pvExtSupportRateIEs),
		ePHYType,
		&byTxRate,
		&byRsvTime);
	VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_54, MAKEWORD(byTxRate, byRsvTime));
	//RSPINF_a_72
	VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_72, MAKEWORD(byTxRate, byRsvTime));
	//Set to Page0
	MACvSelectPage0(pDevice->PortOffset);
}

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

/*
 * Description: Card Send packet function
 *
 * Parameters:
 *  In:
 *      pDeviceHandler      - The adapter to be set
 *      pPacket             - Packet buffer pointer
 *      ePktType            - Packet type
 *      uLength             - Packet length
 *  Out:
 *      none
 *
 * Return Value: true if succeeded; false if failed.
 *
 */
/*
  bool CARDbSendPacket (void *pDeviceHandler, void *pPacket, CARD_PKT_TYPE ePktType, unsigned int uLength) {
  PSDevice    pDevice = (PSDevice) pDeviceHandler;
  if (ePktType == PKT_TYPE_802_11_MNG) {
  return TXbTD0Send(pDevice, pPacket, uLength);
  } else if (ePktType == PKT_TYPE_802_11_BCN) {
  return TXbBeaconSend(pDevice, pPacket, uLength);
  } if (ePktType == PKT_TYPE_802_11_DATA) {
  return TXbTD1Send(pDevice, pPacket, uLength);
  }

  return true;
  }
*/

/*
 * Description: Get Card short preamble option value
 *
 * Parameters:
 *  In:
 *      pDevice             - The adapter to be set
 *  Out:
 *      none
 *
 * Return Value: true if short preamble; otherwise false
 *
 */
bool CARDbIsShortPreamble(void *pDeviceHandler)
{
	PSDevice    pDevice = (PSDevice) pDeviceHandler;
	if (pDevice->byPreambleType == 0) {
		return false;
	}
	return true;
}

/*
 * Description: Get Card short slot time option value
 *
 * Parameters:
 *  In:
 *      pDevice             - The adapter to be set
 *  Out:
 *      none
 *
 * Return Value: true if short slot time; otherwise false
 *
 */
bool CARDbIsShorSlotTime(void *pDeviceHandler)
{
	PSDevice    pDevice = (PSDevice) pDeviceHandler;
	return pDevice->bShortSlotTime;
}

/*
 * Description: Update IFS
 *
 * Parameters:
 *  In:
 *      pDevice             - The adapter to be set
 *  Out:
 *      none
 *
 * Return Value: None.
 *
 */
bool CARDbSetPhyParameter(void *pDeviceHandler, CARD_PHY_TYPE ePHYType, unsigned short wCapInfo, unsigned char byERPField, void *pvSupportRateIEs, void *pvExtSupportRateIEs)
{
	PSDevice    pDevice = (PSDevice) pDeviceHandler;
	unsigned char byCWMaxMin = 0;
	unsigned char bySlot = 0;
	unsigned char bySIFS = 0;
	unsigned char byDIFS = 0;
	unsigned char byData;
//    PWLAN_IE_SUPP_RATES pRates = NULL;
	PWLAN_IE_SUPP_RATES pSupportRates = (PWLAN_IE_SUPP_RATES) pvSupportRateIEs;
	PWLAN_IE_SUPP_RATES pExtSupportRates = (PWLAN_IE_SUPP_RATES) pvExtSupportRateIEs;

	//Set SIFS, DIFS, EIFS, SlotTime, CwMin
	if (ePHYType == PHY_TYPE_11A) {
		if (pSupportRates == NULL) {
			pSupportRates = (PWLAN_IE_SUPP_RATES) abyDefaultSuppRatesA;
		}
		if (pDevice->byRFType == RF_AIROHA7230) {
			// AL7230 use single PAPE and connect to PAPE_2.4G
			MACvSetBBType(pDevice->PortOffset, BB_TYPE_11G);
			pDevice->abyBBVGA[0] = 0x20;
			pDevice->abyBBVGA[2] = 0x10;
			pDevice->abyBBVGA[3] = 0x10;
			BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData);
			if (byData == 0x1C) {
				BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]);
			}
		} else if (pDevice->byRFType == RF_UW2452) {
			MACvSetBBType(pDevice->PortOffset, BB_TYPE_11A);
			pDevice->abyBBVGA[0] = 0x18;
			BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData);
			if (byData == 0x14) {
				BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]);
				BBbWriteEmbedded(pDevice->PortOffset, 0xE1, 0x57);
			}
		} else {
			MACvSetBBType(pDevice->PortOffset, BB_TYPE_11A);
		}
		BBbWriteEmbedded(pDevice->PortOffset, 0x88, 0x03);
		bySlot = C_SLOT_SHORT;
		bySIFS = C_SIFS_A;
		byDIFS = C_SIFS_A + 2*C_SLOT_SHORT;
		byCWMaxMin = 0xA4;
	} else if (ePHYType == PHY_TYPE_11B) {
		if (pSupportRates == NULL) {
			pSupportRates = (PWLAN_IE_SUPP_RATES) abyDefaultSuppRatesB;
		}
		MACvSetBBType(pDevice->PortOffset, BB_TYPE_11B);
		if (pDevice->byRFType == RF_AIROHA7230) {
			pDevice->abyBBVGA[0] = 0x1C;
			pDevice->abyBBVGA[2] = 0x00;
			pDevice->abyBBVGA[3] = 0x00;
			BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData);
			if (byData == 0x20) {
				BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]);
			}
		} else if (pDevice->byRFType == RF_UW2452) {
			pDevice->abyBBVGA[0] = 0x14;
			BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData);
			if (byData == 0x18) {
				BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]);
				BBbWriteEmbedded(pDevice->PortOffset, 0xE1, 0xD3);
			}
		}
		BBbWriteEmbedded(pDevice->PortOffset, 0x88, 0x02);
		bySlot = C_SLOT_LONG;
		bySIFS = C_SIFS_BG;
		byDIFS = C_SIFS_BG + 2*C_SLOT_LONG;
		byCWMaxMin = 0xA5;
	} else {// PK_TYPE_11GA & PK_TYPE_11GB
		if (pSupportRates == NULL) {
			pSupportRates = (PWLAN_IE_SUPP_RATES) abyDefaultSuppRatesG;
			pExtSupportRates = (PWLAN_IE_SUPP_RATES) abyDefaultExtSuppRatesG;
		}
		MACvSetBBType(pDevice->PortOffset, BB_TYPE_11G);
		if (pDevice->byRFType == RF_AIROHA7230) {
			pDevice->abyBBVGA[0] = 0x1C;
			pDevice->abyBBVGA[2] = 0x00;
			pDevice->abyBBVGA[3] = 0x00;
			BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData);
			if (byData == 0x20) {
				BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]);
			}
		} else if (pDevice->byRFType == RF_UW2452) {
			pDevice->abyBBVGA[0] = 0x14;
			BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byData);
			if (byData == 0x18) {
				BBbWriteEmbedded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]);
				BBbWriteEmbedded(pDevice->PortOffset, 0xE1, 0xD3);
			}
		}
		BBbWriteEmbedded(pDevice->PortOffset, 0x88, 0x08);
		bySIFS = C_SIFS_BG;
		if (VNTWIFIbIsShortSlotTime(wCapInfo)) {
			bySlot = C_SLOT_SHORT;
			byDIFS = C_SIFS_BG + 2*C_SLOT_SHORT;
		} else {
			bySlot = C_SLOT_LONG;
			byDIFS = C_SIFS_BG + 2*C_SLOT_LONG;
		}
		if (VNTWIFIbyGetMaxSupportRate(pSupportRates, pExtSupportRates) > RATE_11M) {
			byCWMaxMin = 0xA4;
		} else {
			byCWMaxMin = 0xA5;
		}
		if (pDevice->bProtectMode != VNTWIFIbIsProtectMode(byERPField)) {
			pDevice->bProtectMode = VNTWIFIbIsProtectMode(byERPField);
			if (pDevice->bProtectMode) {
				MACvEnableProtectMD(pDevice->PortOffset);
			} else {
				MACvDisableProtectMD(pDevice->PortOffset);
			}
		}
		if (pDevice->bBarkerPreambleMd != VNTWIFIbIsBarkerMode(byERPField)) {
			pDevice->bBarkerPreambleMd = VNTWIFIbIsBarkerMode(byERPField);
			if (pDevice->bBarkerPreambleMd) {
				MACvEnableBarkerPreambleMd(pDevice->PortOffset);
			} else {
				MACvDisableBarkerPreambleMd(pDevice->PortOffset);
			}
		}
	}

	if (pDevice->byRFType == RF_RFMD2959) {
		// bcs TX_PE will reserve 3 us
		// hardware's processing time here is 2 us.
		bySIFS -= 3;
		byDIFS -= 3;
		//{{ RobertYu: 20041202
		//// TX_PE will reserve 3 us for MAX2829 A mode only, it is for better TX throughput
		//// MAC will need 2 us to process, so the SIFS, DIFS can be shorter by 2 us.
	}

	if (pDevice->bySIFS != bySIFS) {
		pDevice->bySIFS = bySIFS;
		VNSvOutPortB(pDevice->PortOffset + MAC_REG_SIFS, pDevice->bySIFS);
	}
	if (pDevice->byDIFS != byDIFS) {
		pDevice->byDIFS = byDIFS;
		VNSvOutPortB(pDevice->PortOffset + MAC_REG_DIFS, pDevice->byDIFS);
	}
	if (pDevice->byEIFS != C_EIFS) {
		pDevice->byEIFS = C_EIFS;
		VNSvOutPortB(pDevice->PortOffset + MAC_REG_EIFS, pDevice->byEIFS);
	}
	if (pDevice->bySlot != bySlot) {
		pDevice->bySlot = bySlot;
		VNSvOutPortB(pDevice->PortOffset + MAC_REG_SLOT, pDevice->bySlot);
		if (pDevice->bySlot == C_SLOT_SHORT) {
			pDevice->bShortSlotTime = true;
		} else {
			pDevice->bShortSlotTime = false;
		}
		BBvSetShortSlotTime(pDevice);
	}
	if (pDevice->byCWMaxMin != byCWMaxMin) {
		pDevice->byCWMaxMin = byCWMaxMin;
		VNSvOutPortB(pDevice->PortOffset + MAC_REG_CWMAXMIN0, pDevice->byCWMaxMin);
	}
	if (VNTWIFIbIsShortPreamble(wCapInfo)) {
		pDevice->byPreambleType = pDevice->byShortPreamble;
	} else {
		pDevice->byPreambleType = 0;
	}
	s_vSetRSPINF(pDevice, ePHYType, pSupportRates, pExtSupportRates);
	pDevice->eCurrentPHYType = ePHYType;
	// set for NDIS OID_802_11SUPPORTED_RATES
	return true;
}

/*
 * Description: Sync. TSF counter to BSS
 *              Get TSF offset and write to HW
 *
 * Parameters:
 *  In:
 *      pDevice         - The adapter to be sync.
 *      byRxRate        - data rate of receive beacon
 *      qwBSSTimestamp  - Rx BCN's TSF
 *      qwLocalTSF      - Local TSF
 *  Out:
 *      none
 *
 * Return Value: none
 *
 */
bool CARDbUpdateTSF(void *pDeviceHandler, unsigned char byRxRate, QWORD qwBSSTimestamp, QWORD qwLocalTSF)
{
	PSDevice    pDevice = (PSDevice) pDeviceHandler;
	QWORD       qwTSFOffset;

	HIDWORD(qwTSFOffset) = 0;
	LODWORD(qwTSFOffset) = 0;

	if ((HIDWORD(qwBSSTimestamp) != HIDWORD(qwLocalTSF)) ||
	    (LODWORD(qwBSSTimestamp) != LODWORD(qwLocalTSF))) {
		qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp, qwLocalTSF);
		// adjust TSF
		// HW's TSF add TSF Offset reg
		VNSvOutPortD(pDevice->PortOffset + MAC_REG_TSFOFST, LODWORD(qwTSFOffset));
		VNSvOutPortD(pDevice->PortOffset + MAC_REG_TSFOFST + 4, HIDWORD(qwTSFOffset));
		MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_TSFSYNCEN);
	}
	return true;
}

/*
 * Description: Set NIC TSF counter for first Beacon time
 *              Get NEXTTBTT from adjusted TSF and Beacon Interval
 *
 * Parameters:
 *  In:
 *      pDevice         - The adapter to be set.
 *      wBeaconInterval - Beacon Interval
 *  Out:
 *      none
 *
 * Return Value: true if succeed; otherwise false
 *
 */
bool CARDbSetBeaconPeriod(void *pDeviceHandler, unsigned short wBeaconInterval)
{
	PSDevice    pDevice = (PSDevice) pDeviceHandler;
	unsigned int uBeaconInterval = 0;
	unsigned int uLowNextTBTT = 0;
	unsigned int uHighRemain = 0;
	unsigned int uLowRemain = 0;
	QWORD       qwNextTBTT;

	HIDWORD(qwNextTBTT) = 0;
	LODWORD(qwNextTBTT) = 0;
	CARDbGetCurrentTSF(pDevice->PortOffset, &qwNextTBTT); //Get Local TSF counter
	uBeaconInterval = wBeaconInterval * 1024;
	// Next TBTT = ((local_current_TSF / beacon_interval) + 1) * beacon_interval
	uLowNextTBTT = (LODWORD(qwNextTBTT) >> 10) << 10;
	uLowRemain = (uLowNextTBTT) % uBeaconInterval;
	// high dword (mod) bcn
	uHighRemain = (((0xffffffff % uBeaconInterval) + 1) * HIDWORD(qwNextTBTT))
		% uBeaconInterval;
	uLowRemain = (uHighRemain + uLowRemain) % uBeaconInterval;
	uLowRemain = uBeaconInterval - uLowRemain;

	// check if carry when add one beacon interval
	if ((~uLowNextTBTT) < uLowRemain) {
		HIDWORD(qwNextTBTT)++;
	}
	LODWORD(qwNextTBTT) = uLowNextTBTT + uLowRemain;

	// set HW beacon interval
	VNSvOutPortW(pDevice->PortOffset + MAC_REG_BI, wBeaconInterval);
	pDevice->wBeaconInterval = wBeaconInterval;
	// Set NextTBTT
	VNSvOutPortD(pDevice->PortOffset + MAC_REG_NEXTTBTT, LODWORD(qwNextTBTT));
	VNSvOutPortD(pDevice->PortOffset + MAC_REG_NEXTTBTT + 4, HIDWORD(qwNextTBTT));
	MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);

	return true;
}

/*
 * Description: Card Stop Hardware Tx
 *
 * Parameters:
 *  In:
 *      pDeviceHandler      - The adapter to be set
 *      ePktType            - Packet type to stop
 *  Out:
 *      none
 *
 * Return Value: true if all data packet complete; otherwise false.
 *
 */
bool CARDbStopTxPacket(void *pDeviceHandler, CARD_PKT_TYPE ePktType)
{
	PSDevice    pDevice = (PSDevice) pDeviceHandler;

	if (ePktType == PKT_TYPE_802_11_ALL) {
		pDevice->bStopBeacon = true;
		pDevice->bStopTx0Pkt = true;
		pDevice->bStopDataPkt = true;
	} else if (ePktType == PKT_TYPE_802_11_BCN) {
		pDevice->bStopBeacon = true;
	} else if (ePktType == PKT_TYPE_802_11_MNG) {
		pDevice->bStopTx0Pkt = true;
	} else if (ePktType == PKT_TYPE_802_11_DATA) {
		pDevice->bStopDataPkt = true;
	}

	if (pDevice->bStopBeacon == true) {
		if (pDevice->bIsBeaconBufReadySet == true) {
			if (pDevice->cbBeaconBufReadySetCnt < WAIT_BEACON_TX_DOWN_TMO) {
				pDevice->cbBeaconBufReadySetCnt++;
				return false;
			}
		}
		pDevice->bIsBeaconBufReadySet = false;
		pDevice->cbBeaconBufReadySetCnt = 0;
		MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
	}
	// wait all TD0 complete
	if (pDevice->bStopTx0Pkt == true) {
		if (pDevice->iTDUsed[TYPE_TXDMA0] != 0) {
			return false;
		}
	}
	// wait all Data TD complete
	if (pDevice->bStopDataPkt == true) {
		if (pDevice->iTDUsed[TYPE_AC0DMA] != 0) {
			return false;
		}
	}

	return true;
}

/*
 * Description: Card Start Hardware Tx
 *
 * Parameters:
 *  In:
 *      pDeviceHandler      - The adapter to be set
 *      ePktType            - Packet type to start
 *  Out:
 *      none
 *
 * Return Value: true if success; false if failed.
 *
 */
bool CARDbStartTxPacket(void *pDeviceHandler, CARD_PKT_TYPE ePktType)
{
	PSDevice    pDevice = (PSDevice) pDeviceHandler;

	if (ePktType == PKT_TYPE_802_11_ALL) {
		pDevice->bStopBeacon = false;
		pDevice->bStopTx0Pkt = false;
		pDevice->bStopDataPkt = false;
	} else if (ePktType == PKT_TYPE_802_11_BCN) {
		pDevice->bStopBeacon = false;
	} else if (ePktType == PKT_TYPE_802_11_MNG) {
		pDevice->bStopTx0Pkt = false;
	} else if (ePktType == PKT_TYPE_802_11_DATA) {
		pDevice->bStopDataPkt = false;
	}

	if ((pDevice->bStopBeacon == false) &&
	    (pDevice->bBeaconBufReady == true) &&
	    (pDevice->eOPMode == OP_MODE_ADHOC)) {
		MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
	}

	return true;
}

/*
 * Description: Card Set BSSID value
 *
 * Parameters:
 *  In:
 *      pDeviceHandler      - The adapter to be set
 *      pbyBSSID            - pointer to BSSID field
 *      bAdhoc              - flag to indicate IBSS
 *  Out:
 *      none
 *
 * Return Value: true if success; false if failed.
 *
 */
bool CARDbSetBSSID(void *pDeviceHandler, unsigned char *pbyBSSID, CARD_OP_MODE eOPMode)
{
	PSDevice    pDevice = (PSDevice) pDeviceHandler;

	MACvWriteBSSIDAddress(pDevice->PortOffset, pbyBSSID);
	memcpy(pDevice->abyBSSID, pbyBSSID, WLAN_BSSID_LEN);
	if (eOPMode == OP_MODE_ADHOC) {
		MACvRegBitsOn(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_ADHOC);
	} else {
		MACvRegBitsOff(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_ADHOC);
	}
	if (eOPMode == OP_MODE_AP) {
		MACvRegBitsOn(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_AP);
	} else {
		MACvRegBitsOff(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_AP);
	}
	if (eOPMode == OP_MODE_UNKNOWN) {
		MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_BSSID);
		pDevice->bBSSIDFilter = false;
		pDevice->byRxMode &= ~RCR_BSSID;
		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wcmd: rx_mode = %x\n", pDevice->byRxMode);
	} else {
		if (is_zero_ether_addr(pDevice->abyBSSID) == false) {
			MACvRegBitsOn(pDevice->PortOffset, MAC_REG_RCR, RCR_BSSID);
			pDevice->bBSSIDFilter = true;
			pDevice->byRxMode |= RCR_BSSID;
		}
		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: rx_mode = %x\n", pDevice->byRxMode);
	}
	// Adopt BSS state in Adapter Device Object
	pDevice->eOPMode = eOPMode;
	return true;
}

/*
 * Description: Card indicate status
 *
 * Parameters:
 *  In:
 *      pDeviceHandler      - The adapter to be set
 *      eStatus             - Status
 *  Out:
 *      none
 *
 * Return Value: true if success; false if failed.
 *
 */

/*
 * Description: Save Assoc info. contain in assoc. response frame
 *
 * Parameters:
 *  In:
 *      pDevice             - The adapter to be set
 *      wCapabilityInfo     - Capability information
 *      wStatus             - Status code
 *      wAID                - Assoc. ID
 *      uLen                - Length of IEs
 *      pbyIEs              - pointer to IEs
 *  Out:
 *      none
 *
 * Return Value: true if succeed; otherwise false
 *
 */
bool CARDbSetTxDataRate(
	void *pDeviceHandler,
	unsigned short wDataRate
)
{
	PSDevice    pDevice = (PSDevice) pDeviceHandler;

	pDevice->wCurrentRate = wDataRate;
	return true;
}

/*+
 *
 * Routine Description:
 *      Consider to power down when no more packets to tx or rx.
 *
 * Parameters:
 *  In:
 *      pDevice             - The adapter to be set
 *  Out:
 *      none
 *
 * Return Value: true if power down success; otherwise false
 *
 -*/
bool
CARDbPowerDown(
	void *pDeviceHandler
)
{
	PSDevice        pDevice = (PSDevice)pDeviceHandler;
	unsigned int uIdx;

	// check if already in Doze mode
	if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS))
		return true;

	// Froce PSEN on
	MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN);

	// check if all TD are empty,

	for (uIdx = 0; uIdx < TYPE_MAXTD; uIdx++) {
		if (pDevice->iTDUsed[uIdx] != 0)
			return false;
	}

	MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_GO2DOZE);
	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Go to Doze ZZZZZZZZZZZZZZZ\n");
	return true;
}

/*
 * Description: Turn off Radio power
 *
 * Parameters:
 *  In:
 *      pDevice         - The adapter to be turned off
 *  Out:
 *      none
 *
 * Return Value: true if success; otherwise false
 *
 */
bool CARDbRadioPowerOff(void *pDeviceHandler)
{
	PSDevice    pDevice = (PSDevice)pDeviceHandler;
	bool bResult = true;

	if (pDevice->bRadioOff == true)
		return true;

	switch (pDevice->byRFType) {
	case RF_RFMD2959:
		MACvWordRegBitsOff(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_TXPEINV);
		MACvWordRegBitsOn(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE1);
		break;

	case RF_AIROHA:
	case RF_AL2230S:
	case RF_AIROHA7230: //RobertYu:20050104
		MACvWordRegBitsOff(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE2);
		MACvWordRegBitsOff(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3);
		break;

	}

	MACvRegBitsOff(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_RXON);

	BBvSetDeepSleep(pDevice->PortOffset, pDevice->byLocalID);

	pDevice->bRadioOff = true;
	//2007-0409-03,<Add> by chester
	printk("chester power off\n");
	MACvRegBitsOn(pDevice->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET);  //LED issue
	return bResult;
}

/*
 * Description: Turn on Radio power
 *
 * Parameters:
 *  In:
 *      pDevice         - The adapter to be turned on
 *  Out:
 *      none
 *
 * Return Value: true if success; otherwise false
 *
 */
bool CARDbRadioPowerOn(void *pDeviceHandler)
{
	PSDevice    pDevice = (PSDevice) pDeviceHandler;
	bool bResult = true;
	printk("chester power on\n");
	if (pDevice->bRadioControlOff == true) {
		if (pDevice->bHWRadioOff == true) printk("chester bHWRadioOff\n");
		if (pDevice->bRadioControlOff == true) printk("chester bRadioControlOff\n");
		return false; }

	if (pDevice->bRadioOff == false) {
		printk("chester pbRadioOff\n");
		return true; }

	BBvExitDeepSleep(pDevice->PortOffset, pDevice->byLocalID);

	MACvRegBitsOn(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_RXON);

	switch (pDevice->byRFType) {
	case RF_RFMD2959:
		MACvWordRegBitsOn(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_TXPEINV);
		MACvWordRegBitsOff(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE1);
		break;

	case RF_AIROHA:
	case RF_AL2230S:
	case RF_AIROHA7230: //RobertYu:20050104
		MACvWordRegBitsOn(pDevice->PortOffset, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE2 |
									    SOFTPWRCTL_SWPE3));
		break;

	}

	pDevice->bRadioOff = false;
//  2007-0409-03,<Add> by chester
	printk("chester power on\n");
	MACvRegBitsOff(pDevice->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET); //LED issue
	return bResult;
}

bool CARDbRemoveKey(void *pDeviceHandler, unsigned char *pbyBSSID)
{
	PSDevice    pDevice = (PSDevice) pDeviceHandler;

	KeybRemoveAllKey(&(pDevice->sKey), pbyBSSID, pDevice->PortOffset);
	return true;
}

/*
 *
 * Description:
 *    Add BSSID in PMKID Candidate list.
 *
 * Parameters:
 *  In:
 *      hDeviceContext - device structure point
 *      pbyBSSID - BSSID address for adding
 *      wRSNCap - BSS's RSN capability
 *  Out:
 *      none
 *
 * Return Value: none.
 *
 -*/
bool
CARDbAdd_PMKID_Candidate(
	void *pDeviceHandler,
	unsigned char *pbyBSSID,
	bool bRSNCapExist,
	unsigned short wRSNCap
)
{
	PSDevice            pDevice = (PSDevice) pDeviceHandler;
	PPMKID_CANDIDATE    pCandidateList;
	unsigned int ii = 0;

	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bAdd_PMKID_Candidate START: (%d)\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);

	if (pDevice->gsPMKIDCandidate.NumCandidates >= MAX_PMKIDLIST) {
		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vFlush_PMKID_Candidate: 3\n");
		memset(&pDevice->gsPMKIDCandidate, 0, sizeof(SPMKIDCandidateEvent));
	}

	for (ii = 0; ii < 6; ii++) {
		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02X ", *(pbyBSSID + ii));
	}
	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n");

	// Update Old Candidate
	for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) {
		pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii];
		if (!memcmp(pCandidateList->BSSID, pbyBSSID, ETH_ALEN)) {
			if ((bRSNCapExist == true) && (wRSNCap & BIT0)) {
				pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
			} else {
				pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
			}
			return true;
		}
	}

	// New Candidate
	pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[pDevice->gsPMKIDCandidate.NumCandidates];
	if ((bRSNCapExist == true) && (wRSNCap & BIT0)) {
		pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
	} else {
		pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
	}
	memcpy(pCandidateList->BSSID, pbyBSSID, ETH_ALEN);
	pDevice->gsPMKIDCandidate.NumCandidates++;
	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "NumCandidates:%d\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
	return true;
}

void *
CARDpGetCurrentAddress(
	void *pDeviceHandler
)
{
	PSDevice            pDevice = (PSDevice) pDeviceHandler;

	return pDevice->abyCurrentNetAddr;
}

/*
 *
 * Description:
 *    Start Spectrum Measure defined in 802.11h
 *
 * Parameters:
 *  In:
 *      hDeviceContext - device structure point
 *  Out:
 *      none
 *
 * Return Value: none.
 *
 -*/
bool
CARDbStartMeasure(
	void *pDeviceHandler,
	void *pvMeasureEIDs,
	unsigned int uNumOfMeasureEIDs
)
{
	PSDevice                pDevice = (PSDevice) pDeviceHandler;
	PWLAN_IE_MEASURE_REQ    pEID = (PWLAN_IE_MEASURE_REQ) pvMeasureEIDs;
	QWORD                   qwCurrTSF;
	QWORD                   qwStartTSF;
	bool bExpired = true;
	unsigned short wDuration = 0;

	if ((pEID == NULL) ||
	    (uNumOfMeasureEIDs == 0)) {
		return true;
	}
	CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF);
	if (pDevice->bMeasureInProgress == true) {
		pDevice->bMeasureInProgress = false;
		VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byOrgRCR);
		MACvSelectPage1(pDevice->PortOffset);
		VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, pDevice->dwOrgMAR0);
		VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR4, pDevice->dwOrgMAR4);
		// clear measure control
		MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN);
		MACvSelectPage0(pDevice->PortOffset);
		set_channel(pDevice, pDevice->byOrgChannel);
		MACvSelectPage1(pDevice->PortOffset);
		MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
		MACvSelectPage0(pDevice->PortOffset);
	}
	pDevice->uNumOfMeasureEIDs = uNumOfMeasureEIDs;

	do {
		pDevice->pCurrMeasureEID = pEID;
		pEID++;
		pDevice->uNumOfMeasureEIDs--;

		if (pDevice->byLocalID > REV_ID_VT3253_B1) {
			HIDWORD(qwStartTSF) = HIDWORD(*((PQWORD)(pDevice->pCurrMeasureEID->sReq.abyStartTime)));
			LODWORD(qwStartTSF) = LODWORD(*((PQWORD)(pDevice->pCurrMeasureEID->sReq.abyStartTime)));
			wDuration = *((unsigned short *)(pDevice->pCurrMeasureEID->sReq.abyDuration));
			wDuration += 1; // 1 TU for channel switching

			if ((LODWORD(qwStartTSF) == 0) && (HIDWORD(qwStartTSF) == 0)) {
				// start immediately by setting start TSF == current TSF + 2 TU
				LODWORD(qwStartTSF) = LODWORD(qwCurrTSF) + 2048;
				HIDWORD(qwStartTSF) = HIDWORD(qwCurrTSF);
				if (LODWORD(qwCurrTSF) > LODWORD(qwStartTSF)) {
					HIDWORD(qwStartTSF)++;
				}
				bExpired = false;
				break;
			} else {
				// start at setting start TSF - 1TU(for channel switching)
				if (LODWORD(qwStartTSF) < 1024) {
					HIDWORD(qwStartTSF)--;
				}
				LODWORD(qwStartTSF) -= 1024;
			}

			if ((HIDWORD(qwCurrTSF) < HIDWORD(qwStartTSF)) ||
			    ((HIDWORD(qwCurrTSF) == HIDWORD(qwStartTSF)) &&
			     (LODWORD(qwCurrTSF) < LODWORD(qwStartTSF)))
) {
				bExpired = false;
				break;
			}
			VNTWIFIbMeasureReport(pDevice->pMgmt,
					      false,
					      pDevice->pCurrMeasureEID,
					      MEASURE_MODE_LATE,
					      pDevice->byBasicMap,
					      pDevice->byCCAFraction,
					      pDevice->abyRPIs
				);
		} else {
			// hardware do not support measure
			VNTWIFIbMeasureReport(pDevice->pMgmt,
					      false,
					      pDevice->pCurrMeasureEID,
					      MEASURE_MODE_INCAPABLE,
					      pDevice->byBasicMap,
					      pDevice->byCCAFraction,
					      pDevice->abyRPIs
				);
		}
	} while (pDevice->uNumOfMeasureEIDs != 0);

	if (bExpired == false) {
		MACvSelectPage1(pDevice->PortOffset);
		VNSvOutPortD(pDevice->PortOffset + MAC_REG_MSRSTART, LODWORD(qwStartTSF));
		VNSvOutPortD(pDevice->PortOffset + MAC_REG_MSRSTART + 4, HIDWORD(qwStartTSF));
		VNSvOutPortW(pDevice->PortOffset + MAC_REG_MSRDURATION, wDuration);
		MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_EN);
		MACvSelectPage0(pDevice->PortOffset);
	} else {
		// all measure start time expired we should complete action
		VNTWIFIbMeasureReport(pDevice->pMgmt,
				      true,
				      NULL,
				      0,
				      pDevice->byBasicMap,
				      pDevice->byCCAFraction,
				      pDevice->abyRPIs
			);
	}
	return true;
}

/*
 *
 * Description:
 *    Do Channel Switch defined in 802.11h
 *
 * Parameters:
 *  In:
 *      hDeviceContext - device structure point
 *  Out:
 *      none
 *
 * Return Value: none.
 *
 -*/
bool
CARDbChannelSwitch(
	void *pDeviceHandler,
	unsigned char byMode,
	unsigned char byNewChannel,
	unsigned char byCount
)
{
	PSDevice    pDevice = (PSDevice) pDeviceHandler;
	bool bResult = true;

	if (byCount == 0) {
		bResult = set_channel(pDevice, byNewChannel);
		VNTWIFIbChannelSwitch(pDevice->pMgmt, byNewChannel);
		MACvSelectPage1(pDevice->PortOffset);
		MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
		MACvSelectPage0(pDevice->PortOffset);
		return bResult;
	}
	pDevice->byChannelSwitchCount = byCount;
	pDevice->byNewChannel = byNewChannel;
	pDevice->bChannelSwitch = true;
	if (byMode == 1) {
		bResult = CARDbStopTxPacket(pDevice, PKT_TYPE_802_11_ALL);
	}
	return bResult;
}

/*
 *
 * Description:
 *    Handle Quiet EID defined in 802.11h
 *
 * Parameters:
 *  In:
 *      hDeviceContext - device structure point
 *  Out:
 *      none
 *
 * Return Value: none.
 *
 -*/
bool
CARDbSetQuiet(
	void *pDeviceHandler,
	bool bResetQuiet,
	unsigned char byQuietCount,
	unsigned char byQuietPeriod,
	unsigned short wQuietDuration,
	unsigned short wQuietOffset
)
{
	PSDevice    pDevice = (PSDevice) pDeviceHandler;
	unsigned int ii = 0;

	if (bResetQuiet == true) {
		MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN));
		for (ii = 0; ii < MAX_QUIET_COUNT; ii++) {
			pDevice->sQuiet[ii].bEnable = false;
		}
		pDevice->uQuietEnqueue = 0;
		pDevice->bEnableFirstQuiet = false;
		pDevice->bQuietEnable = false;
		pDevice->byQuietStartCount = byQuietCount;
	}
	if (pDevice->sQuiet[pDevice->uQuietEnqueue].bEnable == false) {
		pDevice->sQuiet[pDevice->uQuietEnqueue].bEnable = true;
		pDevice->sQuiet[pDevice->uQuietEnqueue].byPeriod = byQuietPeriod;
		pDevice->sQuiet[pDevice->uQuietEnqueue].wDuration = wQuietDuration;
		pDevice->sQuiet[pDevice->uQuietEnqueue].dwStartTime = (unsigned long) byQuietCount;
		pDevice->sQuiet[pDevice->uQuietEnqueue].dwStartTime *= pDevice->wBeaconInterval;
		pDevice->sQuiet[pDevice->uQuietEnqueue].dwStartTime += wQuietOffset;
		pDevice->uQuietEnqueue++;
		pDevice->uQuietEnqueue %= MAX_QUIET_COUNT;
		if (pDevice->byQuietStartCount < byQuietCount) {
			pDevice->byQuietStartCount = byQuietCount;
		}
	} else {
		// we can not handle Quiet EID more
	}
	return true;
}

/*
 *
 * Description:
 *    Do Quiet, It will be called by either ISR(after start)
 *    or VNTWIFI(before start) so we do not need a SPINLOCK
 *
 * Parameters:
 *  In:
 *      hDeviceContext - device structure point
 *  Out:
 *      none
 *
 * Return Value: none.
 *
 -*/
bool
CARDbStartQuiet(
	void *pDeviceHandler
)
{
	PSDevice    pDevice = (PSDevice) pDeviceHandler;
	unsigned int ii = 0;
	unsigned long dwStartTime = 0xFFFFFFFF;
	unsigned int uCurrentQuietIndex = 0;
	unsigned long dwNextTime = 0;
	unsigned long dwGap = 0;
	unsigned long dwDuration = 0;

	for (ii = 0; ii < MAX_QUIET_COUNT; ii++) {
		if ((pDevice->sQuiet[ii].bEnable == true) &&
		    (dwStartTime > pDevice->sQuiet[ii].dwStartTime)) {
			dwStartTime = pDevice->sQuiet[ii].dwStartTime;
			uCurrentQuietIndex = ii;
		}
	}
	if (dwStartTime == 0xFFFFFFFF) {
		// no more quiet
		pDevice->bQuietEnable = false;
		MACvRegBitsOff(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN));
	} else {
		if (pDevice->bQuietEnable == false) {
			// first quiet
			pDevice->byQuietStartCount--;
			dwNextTime = pDevice->sQuiet[uCurrentQuietIndex].dwStartTime;
			dwNextTime %= pDevice->wBeaconInterval;
			MACvSelectPage1(pDevice->PortOffset);
			VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETINIT, (unsigned short) dwNextTime);
			VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETDUR, (unsigned short) pDevice->sQuiet[uCurrentQuietIndex].wDuration);
			if (pDevice->byQuietStartCount == 0) {
				pDevice->bEnableFirstQuiet = false;
				MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, (MSRCTL_QUIETTXCHK | MSRCTL_QUIETEN));
			} else {
				pDevice->bEnableFirstQuiet = true;
			}
			MACvSelectPage0(pDevice->PortOffset);
		} else {
			if (pDevice->dwCurrentQuietEndTime > pDevice->sQuiet[uCurrentQuietIndex].dwStartTime) {
				// overlap with previous Quiet
				dwGap =  pDevice->dwCurrentQuietEndTime - pDevice->sQuiet[uCurrentQuietIndex].dwStartTime;
				if (dwGap >= pDevice->sQuiet[uCurrentQuietIndex].wDuration) {
					// return false to indicate next quiet expired, should call this function again
					return false;
				}
				dwDuration = pDevice->sQuiet[uCurrentQuietIndex].wDuration - dwGap;
				dwGap = 0;
			} else {
				dwGap = pDevice->sQuiet[uCurrentQuietIndex].dwStartTime - pDevice->dwCurrentQuietEndTime;
				dwDuration = pDevice->sQuiet[uCurrentQuietIndex].wDuration;
			}
			// set GAP and Next duration
			MACvSelectPage1(pDevice->PortOffset);
			VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETGAP, (unsigned short) dwGap);
			VNSvOutPortW(pDevice->PortOffset + MAC_REG_QUIETDUR, (unsigned short) dwDuration);
			MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL, MSRCTL_QUIETRPT);
			MACvSelectPage0(pDevice->PortOffset);
		}
		pDevice->bQuietEnable = true;
		pDevice->dwCurrentQuietEndTime = pDevice->sQuiet[uCurrentQuietIndex].dwStartTime;
		pDevice->dwCurrentQuietEndTime += pDevice->sQuiet[uCurrentQuietIndex].wDuration;
		if (pDevice->sQuiet[uCurrentQuietIndex].byPeriod == 0) {
			// not period disable current quiet element
			pDevice->sQuiet[uCurrentQuietIndex].bEnable = false;
		} else {
			// set next period start time
			dwNextTime = (unsigned long) pDevice->sQuiet[uCurrentQuietIndex].byPeriod;
			dwNextTime *= pDevice->wBeaconInterval;
			pDevice->sQuiet[uCurrentQuietIndex].dwStartTime = dwNextTime;
		}
		if (pDevice->dwCurrentQuietEndTime > 0x80010000) {
			// decreament all time to avoid wrap around
			for (ii = 0; ii < MAX_QUIET_COUNT; ii++) {
				if (pDevice->sQuiet[ii].bEnable == true) {
					pDevice->sQuiet[ii].dwStartTime -= 0x80000000;
				}
			}
			pDevice->dwCurrentQuietEndTime -= 0x80000000;
		}
	}
	return true;
}

/*
 *
 * Description:
 *    Set Local Power Constraint
 *
 * Parameters:
 *  In:
 *      hDeviceContext - device structure point
 *  Out:
 *      none
 *
 * Return Value: none.
 *
 -*/
void
CARDvSetPowerConstraint(
	void *pDeviceHandler,
	unsigned char byChannel,
	char byPower
)
{
	PSDevice    pDevice = (PSDevice) pDeviceHandler;

	if (byChannel > CB_MAX_CHANNEL_24G) {
		if (pDevice->bCountryInfo5G == true) {
			pDevice->abyLocalPwr[byChannel] = pDevice->abyRegPwr[byChannel] - byPower;
		}
	} else {
		if (pDevice->bCountryInfo24G == true) {
			pDevice->abyLocalPwr[byChannel] = pDevice->abyRegPwr[byChannel] - byPower;
		}
	}
}

/*
 *
 * Description:
 *    Set Local Power Constraint
 *
 * Parameters:
 *  In:
 *      hDeviceContext - device structure point
 *  Out:
 *      none
 *
 * Return Value: none.
 *
 -*/
void
CARDvGetPowerCapability(
	void *pDeviceHandler,
	unsigned char *pbyMinPower,
	unsigned char *pbyMaxPower
)
{
	PSDevice    pDevice = (PSDevice) pDeviceHandler;
	unsigned char byDec = 0;

	*pbyMaxPower = pDevice->abyOFDMDefaultPwr[pDevice->byCurrentCh];
	byDec = pDevice->abyOFDMPwrTbl[pDevice->byCurrentCh];
	if (pDevice->byRFType == RF_UW2452) {
		byDec *= 3;
		byDec >>= 1;
	} else {
		byDec <<= 1;
	}
	*pbyMinPower = pDevice->abyOFDMDefaultPwr[pDevice->byCurrentCh] - byDec;
}

/*
 *
 * Description:
 *    Get Current Tx Power
 *
 * Parameters:
 *  In:
 *      hDeviceContext - device structure point
 *  Out:
 *      none
 *
 * Return Value: none.
 *
 */
char
CARDbyGetTransmitPower(
	void *pDeviceHandler
)
{
	PSDevice    pDevice = (PSDevice) pDeviceHandler;

	return pDevice->byCurPwrdBm;
}

//xxx
void
CARDvSafeResetTx(
	void *pDeviceHandler
)
{
	PSDevice    pDevice = (PSDevice) pDeviceHandler;
	unsigned int uu;
	PSTxDesc    pCurrTD;

	// initialize TD index
	pDevice->apTailTD[0] = pDevice->apCurrTD[0] = &(pDevice->apTD0Rings[0]);
	pDevice->apTailTD[1] = pDevice->apCurrTD[1] = &(pDevice->apTD1Rings[0]);

	for (uu = 0; uu < TYPE_MAXTD; uu++)
		pDevice->iTDUsed[uu] = 0;

	for (uu = 0; uu < pDevice->sOpts.nTxDescs[0]; uu++) {
		pCurrTD = &(pDevice->apTD0Rings[uu]);
		pCurrTD->m_td0TD0.f1Owner = OWNED_BY_HOST;
		// init all Tx Packet pointer to NULL
	}
	for (uu = 0; uu < pDevice->sOpts.nTxDescs[1]; uu++) {
		pCurrTD = &(pDevice->apTD1Rings[uu]);
		pCurrTD->m_td0TD0.f1Owner = OWNED_BY_HOST;
		// init all Tx Packet pointer to NULL
	}

	// set MAC TD pointer
	MACvSetCurrTXDescAddr(TYPE_TXDMA0, pDevice->PortOffset,
			      (pDevice->td0_pool_dma));

	MACvSetCurrTXDescAddr(TYPE_AC0DMA, pDevice->PortOffset,
			      (pDevice->td1_pool_dma));

	// set MAC Beacon TX pointer
	MACvSetCurrBCNTxDescAddr(pDevice->PortOffset,
				 (pDevice->tx_beacon_dma));
}

/*+
 *
 * Description:
 *      Reset Rx
 *
 * Parameters:
 *  In:
 *      pDevice     - Pointer to the adapter
 *  Out:
 *      none
 *
 * Return Value: none
 *
 -*/
void
CARDvSafeResetRx(
	void *pDeviceHandler
)
{
	PSDevice    pDevice = (PSDevice) pDeviceHandler;
	unsigned int uu;
	PSRxDesc    pDesc;

	// initialize RD index
	pDevice->pCurrRD[0] = &(pDevice->aRD0Ring[0]);
	pDevice->pCurrRD[1] = &(pDevice->aRD1Ring[0]);

	// init state, all RD is chip's
	for (uu = 0; uu < pDevice->sOpts.nRxDescs0; uu++) {
		pDesc = &(pDevice->aRD0Ring[uu]);
		pDesc->m_rd0RD0.wResCount = (unsigned short)(pDevice->rx_buf_sz);
		pDesc->m_rd0RD0.f1Owner = OWNED_BY_NIC;
		pDesc->m_rd1RD1.wReqCount = (unsigned short)(pDevice->rx_buf_sz);
	}

	// init state, all RD is chip's
	for (uu = 0; uu < pDevice->sOpts.nRxDescs1; uu++) {
		pDesc = &(pDevice->aRD1Ring[uu]);
		pDesc->m_rd0RD0.wResCount = (unsigned short)(pDevice->rx_buf_sz);
		pDesc->m_rd0RD0.f1Owner = OWNED_BY_NIC;
		pDesc->m_rd1RD1.wReqCount = (unsigned short)(pDevice->rx_buf_sz);
	}

	pDevice->cbDFCB = CB_MAX_RX_FRAG;
	pDevice->cbFreeDFCB = pDevice->cbDFCB;

	// set perPkt mode
	MACvRx0PerPktMode(pDevice->PortOffset);
	MACvRx1PerPktMode(pDevice->PortOffset);
	// set MAC RD pointer
	MACvSetCurrRx0DescAddr(pDevice->PortOffset,
			       pDevice->rd0_pool_dma);

	MACvSetCurrRx1DescAddr(pDevice->PortOffset,
			       pDevice->rd1_pool_dma);
}

/*
 * Description: Get response Control frame rate in CCK mode
 *
 * Parameters:
 *  In:
 *      pDevice             - The adapter to be set
 *      wRateIdx            - Receiving data rate
 *  Out:
 *      none
 *
 * Return Value: response Control frame rate
 *
 */
unsigned short CARDwGetCCKControlRate(void *pDeviceHandler, unsigned short wRateIdx)
{
	PSDevice    pDevice = (PSDevice) pDeviceHandler;
	unsigned int ui = (unsigned int) wRateIdx;

	while (ui > RATE_1M) {
		if (pDevice->wBasicRate & ((unsigned short)1 << ui)) {
			return (unsigned short)ui;
		}
		ui--;
	}
	return (unsigned short)RATE_1M;
}

/*
 * Description: Get response Control frame rate in OFDM mode
 *
 * Parameters:
 *  In:
 *      pDevice             - The adapter to be set
 *      wRateIdx            - Receiving data rate
 *  Out:
 *      none
 *
 * Return Value: response Control frame rate
 *
 */
unsigned short CARDwGetOFDMControlRate(void *pDeviceHandler, unsigned short wRateIdx)
{
	PSDevice pDevice = (PSDevice) pDeviceHandler;
	unsigned int ui = (unsigned int) wRateIdx;

	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BASIC RATE: %X\n", pDevice->wBasicRate);

	if (!CARDbIsOFDMinBasicRate((void *)pDevice)) {
		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "CARDwGetOFDMControlRate:(NO OFDM) %d\n", wRateIdx);
		if (wRateIdx > RATE_24M)
			wRateIdx = RATE_24M;
		return wRateIdx;
	}
	while (ui > RATE_11M) {
		if (pDevice->wBasicRate & ((unsigned short)1 << ui)) {
			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "CARDwGetOFDMControlRate : %d\n", ui);
			return (unsigned short)ui;
		}
		ui--;
	}
	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "CARDwGetOFDMControlRate: 6M\n");
	return (unsigned short)RATE_24M;
}

/*
 * Description: Set RSPINF
 *
 * Parameters:
 *  In:
 *      pDevice             - The adapter to be set
 *  Out:
 *      none
 *
 * Return Value: None.
 *
 */
void CARDvSetRSPINF(void *pDeviceHandler, CARD_PHY_TYPE ePHYType)
{
	PSDevice pDevice = (PSDevice) pDeviceHandler;
	unsigned char byServ = 0x00, bySignal = 0x00; //For CCK
	unsigned short wLen = 0x0000;
	unsigned char byTxRate, byRsvTime;             //For OFDM

	//Set to Page1
	MACvSelectPage1(pDevice->PortOffset);

	//RSPINF_b_1
	BBvCalculateParameter(pDevice,
			      14,
			      CARDwGetCCKControlRate((void *)pDevice, RATE_1M),
			      PK_TYPE_11B,
			      &wLen,
			      &byServ,
			      &bySignal
);

	VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_1, MAKEDWORD(wLen, MAKEWORD(bySignal, byServ)));
	///RSPINF_b_2
	BBvCalculateParameter(pDevice,
			      14,
			      CARDwGetCCKControlRate((void *)pDevice, RATE_2M),
			      PK_TYPE_11B,
			      &wLen,
			      &byServ,
			      &bySignal
);

	VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_2, MAKEDWORD(wLen, MAKEWORD(bySignal, byServ)));
	//RSPINF_b_5
	BBvCalculateParameter(pDevice,
			      14,
			      CARDwGetCCKControlRate((void *)pDevice, RATE_5M),
			      PK_TYPE_11B,
			      &wLen,
			      &byServ,
			      &bySignal
);

	VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_5, MAKEDWORD(wLen, MAKEWORD(bySignal, byServ)));
	//RSPINF_b_11
	BBvCalculateParameter(pDevice,
			      14,
			      CARDwGetCCKControlRate((void *)pDevice, RATE_11M),
			      PK_TYPE_11B,
			      &wLen,
			      &byServ,
			      &bySignal
);

	VNSvOutPortD(pDevice->PortOffset + MAC_REG_RSPINF_B_11, MAKEDWORD(wLen, MAKEWORD(bySignal, byServ)));
	//RSPINF_a_6
	s_vCalculateOFDMRParameter(RATE_6M,
				   ePHYType,
				   &byTxRate,
				   &byRsvTime);
	VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_6, MAKEWORD(byTxRate, byRsvTime));
	//RSPINF_a_9
	s_vCalculateOFDMRParameter(RATE_9M,
				   ePHYType,
				   &byTxRate,
				   &byRsvTime);
	VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_9, MAKEWORD(byTxRate, byRsvTime));
	//RSPINF_a_12
	s_vCalculateOFDMRParameter(RATE_12M,
				   ePHYType,
				   &byTxRate,
				   &byRsvTime);
	VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_12, MAKEWORD(byTxRate, byRsvTime));
	//RSPINF_a_18
	s_vCalculateOFDMRParameter(RATE_18M,
				   ePHYType,
				   &byTxRate,
				   &byRsvTime);
	VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_18, MAKEWORD(byTxRate, byRsvTime));
	//RSPINF_a_24
	s_vCalculateOFDMRParameter(RATE_24M,
				   ePHYType,
				   &byTxRate,
				   &byRsvTime);
	VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_24, MAKEWORD(byTxRate, byRsvTime));
	//RSPINF_a_36
	s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_36M),
				   ePHYType,
				   &byTxRate,
				   &byRsvTime);
	VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_36, MAKEWORD(byTxRate, byRsvTime));
	//RSPINF_a_48
	s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_48M),
				   ePHYType,
				   &byTxRate,
				   &byRsvTime);
	VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_48, MAKEWORD(byTxRate, byRsvTime));
	//RSPINF_a_54
	s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_54M),
				   ePHYType,
				   &byTxRate,
				   &byRsvTime);
	VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_54, MAKEWORD(byTxRate, byRsvTime));

	//RSPINF_a_72
	s_vCalculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_54M),
				   ePHYType,
				   &byTxRate,
				   &byRsvTime);
	VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_72, MAKEWORD(byTxRate, byRsvTime));
	//Set to Page0
	MACvSelectPage0(pDevice->PortOffset);
}

/*
 * Description: Update IFS
 *
 * Parameters:
 *  In:
 *      pDevice             - The adapter to be set
 *  Out:
 *      none
 *
 * Return Value: None.
 *
 */
void vUpdateIFS(void *pDeviceHandler)
{
	//Set SIFS, DIFS, EIFS, SlotTime, CwMin
	PSDevice pDevice = (PSDevice) pDeviceHandler;

	unsigned char byMaxMin = 0;
	if (pDevice->byPacketType == PK_TYPE_11A) {//0000 0000 0000 0000,11a
		pDevice->uSlot = C_SLOT_SHORT;
		pDevice->uSIFS = C_SIFS_A;
		pDevice->uDIFS = C_SIFS_A + 2*C_SLOT_SHORT;
		pDevice->uCwMin = C_CWMIN_A;
		byMaxMin = 4;
	} else if (pDevice->byPacketType == PK_TYPE_11B) {//0000 0001 0000 0000,11b
		pDevice->uSlot = C_SLOT_LONG;
		pDevice->uSIFS = C_SIFS_BG;
		pDevice->uDIFS = C_SIFS_BG + 2*C_SLOT_LONG;
		pDevice->uCwMin = C_CWMIN_B;
		byMaxMin = 5;
	} else { // PK_TYPE_11GA & PK_TYPE_11GB
		pDevice->uSIFS = C_SIFS_BG;
		if (pDevice->bShortSlotTime) {
			pDevice->uSlot = C_SLOT_SHORT;
		} else {
			pDevice->uSlot = C_SLOT_LONG;
		}
		pDevice->uDIFS = C_SIFS_BG + 2*pDevice->uSlot;
		if (pDevice->wBasicRate & 0x0150) { //0000 0001 0101 0000,24M,12M,6M
			pDevice->uCwMin = C_CWMIN_A;
			byMaxMin = 4;
		} else {
			pDevice->uCwMin = C_CWMIN_B;
			byMaxMin = 5;
		}
	}

	pDevice->uCwMax = C_CWMAX;
	pDevice->uEIFS = C_EIFS;
	if (pDevice->byRFType == RF_RFMD2959) {
		// bcs TX_PE will reserve 3 us
		VNSvOutPortB(pDevice->PortOffset + MAC_REG_SIFS, (unsigned char)(pDevice->uSIFS - 3));
		VNSvOutPortB(pDevice->PortOffset + MAC_REG_DIFS, (unsigned char)(pDevice->uDIFS - 3));
	} else {
		VNSvOutPortB(pDevice->PortOffset + MAC_REG_SIFS, (unsigned char)pDevice->uSIFS);
		VNSvOutPortB(pDevice->PortOffset + MAC_REG_DIFS, (unsigned char)pDevice->uDIFS);
	}
	VNSvOutPortB(pDevice->PortOffset + MAC_REG_EIFS, (unsigned char)pDevice->uEIFS);
	VNSvOutPortB(pDevice->PortOffset + MAC_REG_SLOT, (unsigned char)pDevice->uSlot);
	byMaxMin |= 0xA0;//1010 1111,C_CWMAX = 1023
	VNSvOutPortB(pDevice->PortOffset + MAC_REG_CWMAXMIN0, (unsigned char)byMaxMin);
}

void CARDvUpdateBasicTopRate(void *pDeviceHandler)
{
	PSDevice pDevice = (PSDevice) pDeviceHandler;
	unsigned char byTopOFDM = RATE_24M, byTopCCK = RATE_1M;
	unsigned char ii;

	//Determines the highest basic rate.
	for (ii = RATE_54M; ii >= RATE_6M; ii--) {
		if ((pDevice->wBasicRate) & ((unsigned short)(1<<ii))) {
			byTopOFDM = ii;
			break;
		}
	}
	pDevice->byTopOFDMBasicRate = byTopOFDM;

	for (ii = RATE_11M;; ii--) {
		if ((pDevice->wBasicRate) & ((unsigned short)(1<<ii))) {
			byTopCCK = ii;
			break;
		}
		if (ii == RATE_1M)
			break;
	}
	pDevice->byTopCCKBasicRate = byTopCCK;
}

/*
 * Description: Set NIC Tx Basic Rate
 *
 * Parameters:
 *  In:
 *      pDevice         - The adapter to be set
 *      wBasicRate      - Basic Rate to be set
 *  Out:
 *      none
 *
 * Return Value: true if succeeded; false if failed.
 *
 */
bool CARDbAddBasicRate(void *pDeviceHandler, unsigned short wRateIdx)
{
	PSDevice pDevice = (PSDevice) pDeviceHandler;
	unsigned short wRate = (unsigned short)(1<<wRateIdx);

	pDevice->wBasicRate |= wRate;

	//Determines the highest basic rate.
	CARDvUpdateBasicTopRate((void *)pDevice);

	return true;
}

bool CARDbIsOFDMinBasicRate(void *pDeviceHandler)
{
	PSDevice pDevice = (PSDevice)pDeviceHandler;
	int ii;

	for (ii = RATE_54M; ii >= RATE_6M; ii--) {
		if ((pDevice->wBasicRate) & ((unsigned short)(1 << ii)))
			return true;
	}
	return false;
}

unsigned char CARDbyGetPktType(void *pDeviceHandler)
{
	PSDevice pDevice = (PSDevice) pDeviceHandler;

	if (pDevice->byBBType == BB_TYPE_11A || pDevice->byBBType == BB_TYPE_11B) {
		return (unsigned char)pDevice->byBBType;
	} else if (CARDbIsOFDMinBasicRate((void *)pDevice)) {
		return PK_TYPE_11GA;
	} else {
		return PK_TYPE_11GB;
	}
}

/*
 * Description: Set NIC Loopback mode
 *
 * Parameters:
 *  In:
 *      pDevice         - The adapter to be set
 *      wLoopbackMode   - Loopback mode to be set
 *  Out:
 *      none
 *
 * Return Value: none
 *
 */
void CARDvSetLoopbackMode(unsigned long dwIoBase, unsigned short wLoopbackMode)
{
	switch (wLoopbackMode) {
	case CARD_LB_NONE:
	case CARD_LB_MAC:
	case CARD_LB_PHY:
		break;
	default:
		ASSERT(false);
		break;
	}
	// set MAC loopback
	MACvSetLoopbackMode(dwIoBase, LOBYTE(wLoopbackMode));
	// set Baseband loopback
}

/*
 * Description: Software Reset NIC
 *
 * Parameters:
 *  In:
 *      pDevice         - The adapter to be reset
 *  Out:
 *      none
 *
 * Return Value: none
 *
 */
bool CARDbSoftwareReset(void *pDeviceHandler)
{
	PSDevice pDevice = (PSDevice) pDeviceHandler;

	// reset MAC
	if (!MACbSafeSoftwareReset(pDevice->PortOffset))
		return false;

	return true;
}

/*
 * Description: Calculate TSF offset of two TSF input
 *              Get TSF Offset from RxBCN's TSF and local TSF
 *
 * Parameters:
 *  In:
 *      pDevice         - The adapter to be sync.
 *      qwTSF1          - Rx BCN's TSF
 *      qwTSF2          - Local TSF
 *  Out:
 *      none
 *
 * Return Value: TSF Offset value
 *
 */
QWORD CARDqGetTSFOffset(unsigned char byRxRate, QWORD qwTSF1, QWORD qwTSF2)
{
	QWORD   qwTSFOffset;
	unsigned short wRxBcnTSFOffst = 0;

	HIDWORD(qwTSFOffset) = 0;
	LODWORD(qwTSFOffset) = 0;
	wRxBcnTSFOffst = cwRXBCNTSFOff[byRxRate%MAX_RATE];
	(qwTSF2).u.dwLowDword += (unsigned long)(wRxBcnTSFOffst);
	if ((qwTSF2).u.dwLowDword < (unsigned long)(wRxBcnTSFOffst)) {
		(qwTSF2).u.dwHighDword++;
	}
	LODWORD(qwTSFOffset) = LODWORD(qwTSF1) - LODWORD(qwTSF2);
	if (LODWORD(qwTSF1) < LODWORD(qwTSF2)) {
		// if borrow needed
		HIDWORD(qwTSFOffset) = HIDWORD(qwTSF1) - HIDWORD(qwTSF2) - 1;
	} else {
		HIDWORD(qwTSFOffset) = HIDWORD(qwTSF1) - HIDWORD(qwTSF2);
	};
	return qwTSFOffset;
}

/*
 * Description: Read NIC TSF counter
 *              Get local TSF counter
 *
 * Parameters:
 *  In:
 *      pDevice         - The adapter to be read
 *  Out:
 *      qwCurrTSF       - Current TSF counter
 *
 * Return Value: true if success; otherwise false
 *
 */
bool CARDbGetCurrentTSF(unsigned long dwIoBase, PQWORD pqwCurrTSF)
{
	unsigned short ww;
	unsigned char byData;

	MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TSFCNTRRD);
	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
		VNSvInPortB(dwIoBase + MAC_REG_TFTCTL, &byData);
		if (!(byData & TFTCTL_TSFCNTRRD))
			break;
	}
	if (ww == W_MAX_TIMEOUT)
		return false;
	VNSvInPortD(dwIoBase + MAC_REG_TSFCNTR, &LODWORD(*pqwCurrTSF));
	VNSvInPortD(dwIoBase + MAC_REG_TSFCNTR + 4, &HIDWORD(*pqwCurrTSF));

	return true;
}

/*
 * Description: Read NIC TSF counter
 *              Get NEXTTBTT from adjusted TSF and Beacon Interval
 *
 * Parameters:
 *  In:
 *      qwTSF           - Current TSF counter
 *      wbeaconInterval - Beacon Interval
 *  Out:
 *      qwCurrTSF       - Current TSF counter
 *
 * Return Value: TSF value of next Beacon
 *
 */
QWORD CARDqGetNextTBTT(QWORD qwTSF, unsigned short wBeaconInterval)
{
	unsigned int uLowNextTBTT;
	unsigned int uHighRemain, uLowRemain;
	unsigned int uBeaconInterval;

	uBeaconInterval = wBeaconInterval * 1024;
	// Next TBTT = ((local_current_TSF / beacon_interval) + 1) * beacon_interval
	uLowNextTBTT = (LODWORD(qwTSF) >> 10) << 10;
	// low dword (mod) bcn
	uLowRemain = (uLowNextTBTT) % uBeaconInterval;
//    uHighRemain = ((0x80000000 % uBeaconInterval)* 2 * HIDWORD(qwTSF))
//                  % uBeaconInterval;
	// high dword (mod) bcn
	uHighRemain = (((0xffffffff % uBeaconInterval) + 1) * HIDWORD(qwTSF))
		% uBeaconInterval;
	uLowRemain = (uHighRemain + uLowRemain) % uBeaconInterval;
	uLowRemain = uBeaconInterval - uLowRemain;

	// check if carry when add one beacon interval
	if ((~uLowNextTBTT) < uLowRemain)
		HIDWORD(qwTSF)++;

	LODWORD(qwTSF) = uLowNextTBTT + uLowRemain;

	return qwTSF;
}

/*
 * Description: Set NIC TSF counter for first Beacon time
 *              Get NEXTTBTT from adjusted TSF and Beacon Interval
 *
 * Parameters:
 *  In:
 *      dwIoBase        - IO Base
 *      wBeaconInterval - Beacon Interval
 *  Out:
 *      none
 *
 * Return Value: none
 *
 */
void CARDvSetFirstNextTBTT(unsigned long dwIoBase, unsigned short wBeaconInterval)
{
	QWORD   qwNextTBTT;

	HIDWORD(qwNextTBTT) = 0;
	LODWORD(qwNextTBTT) = 0;
	CARDbGetCurrentTSF(dwIoBase, &qwNextTBTT); //Get Local TSF counter
	qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval);
	// Set NextTBTT
	VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, LODWORD(qwNextTBTT));
	VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, HIDWORD(qwNextTBTT));
	MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
	//DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Card:First Next TBTT[%8xh:%8xh] \n", HIDWORD(qwNextTBTT), LODWORD(qwNextTBTT));
	return;
}

/*
 * Description: Sync NIC TSF counter for Beacon time
 *              Get NEXTTBTT and write to HW
 *
 * Parameters:
 *  In:
 *      pDevice         - The adapter to be set
 *      qwTSF           - Current TSF counter
 *      wBeaconInterval - Beacon Interval
 *  Out:
 *      none
 *
 * Return Value: none
 *
 */
void CARDvUpdateNextTBTT(unsigned long dwIoBase, QWORD qwTSF, unsigned short wBeaconInterval)
{
	qwTSF = CARDqGetNextTBTT(qwTSF, wBeaconInterval);
	// Set NextTBTT
	VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, LODWORD(qwTSF));
	VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, HIDWORD(qwTSF));
	MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Card:Update Next TBTT[%8xh:%8xh] \n",
		(unsigned int) HIDWORD(qwTSF), (unsigned int) LODWORD(qwTSF));

	return;
}
