/*
 * 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 - Caculate TSFOffset
 *      CARDbGetCurrentTSF - Read Current NIC TSF counter
 *      CARDqGetNextTBTT - Caculate 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_vCaculateOFDMRParameter(
    unsigned char byRate,
    CARD_PHY_TYPE ePHYType,
    unsigned char *pbyTxRate,
    unsigned char *pbyRsvTime
    );


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

/*
 * Description: Caculate 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_vCaculateOFDMRParameter (
    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
    BBvCaculateParameter(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
    BBvCaculateParameter(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
    BBvCaculateParameter(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
    BBvCaculateParameter(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_vCaculateOFDMRParameter(RATE_6M,
                              ePHYType,
                              &byTxRate,
                              &byRsvTime);
    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_6, MAKEWORD(byTxRate,byRsvTime));
    //RSPINF_a_9
    s_vCaculateOFDMRParameter(RATE_9M,
                              ePHYType,
                              &byTxRate,
                              &byRsvTime);
    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_9, MAKEWORD(byTxRate,byRsvTime));
    //RSPINF_a_12
    s_vCaculateOFDMRParameter(RATE_12M,
                              ePHYType,
                              &byTxRate,
                              &byRsvTime);
    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_12, MAKEWORD(byTxRate,byRsvTime));
    //RSPINF_a_18
    s_vCaculateOFDMRParameter(RATE_18M,
                              ePHYType,
                              &byTxRate,
                              &byRsvTime);
    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_18, MAKEWORD(byTxRate,byRsvTime));
    //RSPINF_a_24
    s_vCaculateOFDMRParameter(RATE_24M,
                              ePHYType,
                              &byTxRate,
                              &byRsvTime);
    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_24, MAKEWORD(byTxRate,byRsvTime));
    //RSPINF_a_36
    s_vCaculateOFDMRParameter(
                              VNTWIFIbyGetACKTxRate(RATE_36M, pvSupportRateIEs, pvExtSupportRateIEs),
                              ePHYType,
                              &byTxRate,
                              &byRsvTime);
    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_36, MAKEWORD(byTxRate,byRsvTime));
    //RSPINF_a_48
    s_vCaculateOFDMRParameter(
                              VNTWIFIbyGetACKTxRate(RATE_48M, pvSupportRateIEs, pvExtSupportRateIEs),
                              ePHYType,
                              &byTxRate,
                              &byRsvTime);
    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_48, MAKEWORD(byTxRate,byRsvTime));
    //RSPINF_a_54
    s_vCaculateOFDMRParameter(
                              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;
            BBbReadEmbeded(pDevice->PortOffset, 0xE7, &byData);
            if (byData == 0x1C) {
                BBbWriteEmbeded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]);
            }
        } else if (pDevice->byRFType == RF_UW2452) {
            MACvSetBBType(pDevice->PortOffset, BB_TYPE_11A);
            pDevice->abyBBVGA[0] = 0x18;
            BBbReadEmbeded(pDevice->PortOffset, 0xE7, &byData);
            if (byData == 0x14) {
                BBbWriteEmbeded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]);
                BBbWriteEmbeded(pDevice->PortOffset, 0xE1, 0x57);
            }
        } else {
            MACvSetBBType(pDevice->PortOffset, BB_TYPE_11A);
        }
        BBbWriteEmbeded(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;
            BBbReadEmbeded(pDevice->PortOffset, 0xE7, &byData);
            if (byData == 0x20) {
                BBbWriteEmbeded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]);
            }
        } else if (pDevice->byRFType == RF_UW2452) {
            pDevice->abyBBVGA[0] = 0x14;
            BBbReadEmbeded(pDevice->PortOffset, 0xE7, &byData);
            if (byData == 0x18) {
                BBbWriteEmbeded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]);
                BBbWriteEmbeded(pDevice->PortOffset, 0xE1, 0xD3);
            }
        }
        BBbWriteEmbeded(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;
            BBbReadEmbeded(pDevice->PortOffset, 0xE7, &byData);
            if (byData == 0x20) {
                BBbWriteEmbeded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]);
            }
        } else if (pDevice->byRFType == RF_UW2452) {
            pDevice->abyBBVGA[0] = 0x14;
            BBbReadEmbeded(pDevice->PortOffset, 0xE7, &byData);
            if (byData == 0x18) {
                BBbWriteEmbeded(pDevice->PortOffset, 0xE7, pDevice->abyBBVGA[0]);
                BBbWriteEmbeded(pDevice->PortOffset, 0xE1, 0xD3);
            }
        }
        BBbWriteEmbeded(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 imediately 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 called by either ISR (after start) or VNTWIFI (before start) so do not need 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
    BBvCaculateParameter(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
    BBvCaculateParameter(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
    BBvCaculateParameter(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
    BBvCaculateParameter(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_vCaculateOFDMRParameter(RATE_6M,
                              ePHYType,
                              &byTxRate,
                              &byRsvTime);
    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_6, MAKEWORD(byTxRate,byRsvTime));
    //RSPINF_a_9
    s_vCaculateOFDMRParameter(RATE_9M,
                              ePHYType,
                              &byTxRate,
                              &byRsvTime);
    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_9, MAKEWORD(byTxRate,byRsvTime));
    //RSPINF_a_12
    s_vCaculateOFDMRParameter(RATE_12M,
                              ePHYType,
                              &byTxRate,
                              &byRsvTime);
    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_12, MAKEWORD(byTxRate,byRsvTime));
    //RSPINF_a_18
    s_vCaculateOFDMRParameter(RATE_18M,
                              ePHYType,
                              &byTxRate,
                              &byRsvTime);
   VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_18, MAKEWORD(byTxRate,byRsvTime));
    //RSPINF_a_24
    s_vCaculateOFDMRParameter(RATE_24M,
                              ePHYType,
                              &byTxRate,
                              &byRsvTime);
    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_24, MAKEWORD(byTxRate,byRsvTime));
    //RSPINF_a_36
    s_vCaculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_36M),
                              ePHYType,
                              &byTxRate,
                              &byRsvTime);
    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_36, MAKEWORD(byTxRate,byRsvTime));
    //RSPINF_a_48
    s_vCaculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_48M),
                              ePHYType,
                              &byTxRate,
                              &byRsvTime);
    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_48, MAKEWORD(byTxRate,byRsvTime));
    //RSPINF_a_54
    s_vCaculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_54M),
                              ePHYType,
                              &byTxRate,
                              &byRsvTime);
    VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_54, MAKEWORD(byTxRate,byRsvTime));

    //RSPINF_a_72
    s_vCaculateOFDMRParameter(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: Caculate 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;
}







