/*
 * Copyright (c) 2007-2008 Atheros Communications Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
/*                                                                      */
/*  Module Name : cmd.c                                                 */
/*                                                                      */
/*  Abstract                                                            */
/*      This module contains command interface functions.               */
/*                                                                      */
/*  NOTES                                                               */
/*      None                                                            */
/*                                                                      */
/************************************************************************/
#include "cprecomp.h"
#include "../hal/hpreg.h"


u16_t zfWlanReset(zdev_t* dev);
u32_t zfUpdateRxRate(zdev_t* dev);


extern void zfiUsbRecv(zdev_t *dev, zbuf_t *buf);
extern void zfiUsbRegIn(zdev_t* dev, u32_t* rsp, u16_t rspLen);
extern void zfiUsbOutComplete(zdev_t* dev, zbuf_t *buf, u8_t status, u8_t *hdr);
extern void zfiUsbRegOutComplete(zdev_t* dev);
extern u16_t zfHpReinit(zdev_t* dev, u32_t frequency);

/* Get size (byte) of driver core global data structure.    */
/* This size will be used by driver wrapper to allocate     */
/* a memory space for driver core to store global variables */
u16_t zfiGlobalDataSize(zdev_t* dev)
{
    u32_t ret;
    ret = (sizeof(struct zsWlanDev));
    zm_assert((ret>>16) == 0);
    return (u16_t)ret;
}


/* Initialize WLAN hardware and software, resource will be allocated */
/* for WLAN operation, must be called first before other function.   */
extern u16_t zfiWlanOpen(zdev_t* dev, struct zsCbFuncTbl* cbFuncTbl)
{
    //u16_t ret;
    //u32_t i;
    //u8_t* ch;
    //u8_t  bPassive;
    u32_t devSize;
    struct zfCbUsbFuncTbl cbUsbFuncTbl;
    zmw_get_wlan_dev(dev);

    zm_debug_msg0("start");

    devSize = sizeof(struct zsWlanDev);
    /* Zeroize zsWlanDev struct */
    zfZeroMemory((u8_t*)wd, (u16_t)devSize);

#ifdef ZM_ENABLE_AGGREGATION
    zfAggInit(dev);
#endif

    zfCwmInit(dev);

    wd->commTally.RateCtrlTxMPDU = 0;
    wd->commTally.RateCtrlBAFail = 0;
    wd->preambleTypeInUsed = ZM_PREAMBLE_TYPE_SHORT;

    if (cbFuncTbl == NULL)
    {
        /* zfcbRecvEth() is mandatory */
        zm_assert(0);
    }
    else
    {
        if (cbFuncTbl->zfcbRecvEth == NULL)
        {
            /* zfcbRecvEth() is mandatory */
            zm_assert(0);
        }
        wd->zfcbAuthNotify = cbFuncTbl->zfcbAuthNotify;
        wd->zfcbAuthNotify = cbFuncTbl->zfcbAuthNotify;
        wd->zfcbAsocNotify = cbFuncTbl->zfcbAsocNotify;
        wd->zfcbDisAsocNotify = cbFuncTbl->zfcbDisAsocNotify;
        wd->zfcbApConnectNotify = cbFuncTbl->zfcbApConnectNotify;
        wd->zfcbConnectNotify = cbFuncTbl->zfcbConnectNotify;
        wd->zfcbScanNotify = cbFuncTbl->zfcbScanNotify;
        wd->zfcbMicFailureNotify = cbFuncTbl->zfcbMicFailureNotify;
        wd->zfcbApMicFailureNotify = cbFuncTbl->zfcbApMicFailureNotify;
        wd->zfcbIbssPartnerNotify = cbFuncTbl->zfcbIbssPartnerNotify;
        wd->zfcbMacAddressNotify = cbFuncTbl->zfcbMacAddressNotify;
        wd->zfcbSendCompleteIndication = cbFuncTbl->zfcbSendCompleteIndication;
        wd->zfcbRecvEth = cbFuncTbl->zfcbRecvEth;
        wd->zfcbRestoreBufData = cbFuncTbl->zfcbRestoreBufData;
        wd->zfcbRecv80211 = cbFuncTbl->zfcbRecv80211;
#ifdef ZM_ENABLE_CENC
        wd->zfcbCencAsocNotify = cbFuncTbl->zfcbCencAsocNotify;
#endif //ZM_ENABLE_CENC
        wd->zfcbClassifyTxPacket = cbFuncTbl->zfcbClassifyTxPacket;
        wd->zfcbHwWatchDogNotify = cbFuncTbl->zfcbHwWatchDogNotify;
    }

    //add by honda 0330
    cbUsbFuncTbl.zfcbUsbRecv = zfiUsbRecv;
    cbUsbFuncTbl.zfcbUsbRegIn = zfiUsbRegIn;
    cbUsbFuncTbl.zfcbUsbOutComplete = zfiUsbOutComplete;
    cbUsbFuncTbl.zfcbUsbRegOutComplete = zfiUsbRegOutComplete;
    zfwUsbRegisterCallBack(dev, &cbUsbFuncTbl);
    /* Init OWN MAC address */
    wd->macAddr[0] = 0x8000;
    wd->macAddr[1] = 0x0000;
    wd->macAddr[2] = 0x0000;

    wd->regulationTable.regionCode = 0xffff;

    zfHpInit(dev, wd->frequency);

    /* init region code */
    //wd->regulationTable.regionCode = NULL1_WORLD; //Only 2.4g RegCode
    //zfHpGetRegulationTablefromRegionCode(dev, NULL1_WORLD);
    //zfiWlanSetDot11DMode(dev , 1); // Enable 802.11d
    /* Get the first channel */
    //wd->frequency = zfChGetFirstChannel(dev, &bPassive);
#ifdef ZM_AP_DEBUG
    //wd->frequency = 2437;
#endif

    //STA mode
    wd->sta.mTxRate = 0x0;
    wd->sta.uTxRate = 0x3;
    wd->sta.mmTxRate = 0x0;
    wd->sta.adapterState = ZM_STA_STATE_DISCONNECT;
    wd->sta.capability[0] = 0x01;
    wd->sta.capability[1] = 0x00;

    wd->sta.preambleTypeHT = 0;
    wd->sta.htCtrlBandwidth = 0;
    wd->sta.htCtrlSTBC = 0;
    wd->sta.htCtrlSG = 0;
    wd->sta.defaultTA = 0;
    //wd->sta.activescanTickPerChannel = ZM_TIME_ACTIVE_SCAN/ZM_MS_PER_TICK;
	{
		u8_t Dur = ZM_TIME_ACTIVE_SCAN;
		zfwGetActiveScanDur(dev, &Dur);
		wd->sta.activescanTickPerChannel = Dur/ZM_MS_PER_TICK;

	}
    wd->sta.passiveScanTickPerChannel = ZM_TIME_PASSIVE_SCAN/ZM_MS_PER_TICK;
    wd->sta.bAutoReconnect = TRUE;
    wd->sta.dropUnencryptedPkts = FALSE;

    /* set default to bypass all multicast packet for linux, window XP would set 0 by wrapper initialization */
	wd->sta.bAllMulticast = 1;

    /* Initial the RIFS Status / RIFS-like frame count / RIFS count */
    wd->sta.rifsState = ZM_RIFS_STATE_DETECTING;
    wd->sta.rifsLikeFrameCnt = 0;
    wd->sta.rifsCount = 0;

    wd->sta.osRxFilter = 0;
    wd->sta.bSafeMode = 0;

    //Common
    zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_DISCONNECT);
    wd->beaconInterval = 100;
    wd->rtsThreshold = 2346;
    wd->fragThreshold = 32767;
    wd->wlanMode = ZM_MODE_INFRASTRUCTURE;
    wd->txMCS = 0xff;    //AUTO
    wd->dtim = 1;
    //wd->txMT = 1;       //OFDM
    wd->tick = 1;
    wd->maxTxPower2 = 0xff;
    wd->maxTxPower5 = 0xff;
    wd->supportMode = 0xffffffff;
    wd->ws.adhocMode = ZM_ADHOCBAND_G;
    wd->ws.autoSetFrequency = 0xff;

    //AP mode
    //wd->bgMode = wd->ws.bgMode;
    wd->ap.ssidLen[0] = 6;
    wd->ap.ssid[0][0] = 'Z';
    wd->ap.ssid[0][1] = 'D';
    wd->ap.ssid[0][2] = '1';
    wd->ap.ssid[0][3] = '2';
    wd->ap.ssid[0][4] = '2';
    wd->ap.ssid[0][5] = '1';

    // Init the country iso name as NA
    wd->ws.countryIsoName[0] = 0;
    wd->ws.countryIsoName[1] = 0;
    wd->ws.countryIsoName[2] = '\0';

	/* init fragmentation is disabled */
	//zfiWlanSetFragThreshold(dev, 0);

	/* airopeek : swSniffer 1=>on  0=>off */
	wd->swSniffer = 0;
    wd->XLinkMode = 0;

// jhlee HT 0
#if 1
    /* AP Mode*/
    /* Init HT Capability Info */
    wd->ap.HTCap.Data.ElementID = ZM_WLAN_EID_HT_CAPABILITY;
    wd->ap.HTCap.Data.Length = 26;
    //wd->ap.HTCap.Data.SupChannelWidthSet = 0;
    //wd->ap.HTCap.Data.MIMOPowerSave = 3;
    //wd->ap.HTCap.Data.ShortGIfor40MHz = 0;
    //wd->ap.HTCap.Data.ShortGIfor20MHz = 0;
    //wd->ap.HTCap.Data.DSSSandCCKin40MHz = 0;
    wd->ap.HTCap.Data.AMPDUParam |= HTCAP_MaxRxAMPDU3;
    wd->ap.HTCap.Data.MCSSet[0] = 0xFF; // MCS 0 ~  7
    wd->ap.HTCap.Data.MCSSet[1] = 0xFF; // MCS 8 ~ 15

    /* Init Extended HT Capability Info */
    wd->ap.ExtHTCap.Data.ElementID = ZM_WLAN_EID_EXTENDED_HT_CAPABILITY;
    wd->ap.ExtHTCap.Data.Length = 22;
    wd->ap.ExtHTCap.Data.ControlChannel = 6;
    //wd->ap.ExtHTCap.Data.ExtChannelOffset = 3;
    wd->ap.ExtHTCap.Data.ChannelInfo |= ExtHtCap_RecomTxWidthSet;
    //wd->ap.ExtHTCap.Data.RIFSMode = 1;
    wd->ap.ExtHTCap.Data.OperatingInfo |= 1;

    /* STA Mode*/
    /* Init HT Capability Info */
    wd->sta.HTCap.Data.ElementID = ZM_WLAN_EID_HT_CAPABILITY;
    wd->sta.HTCap.Data.Length = 26;

    /* Test with 5G-AP : 7603 */
    //wd->sta.HTCap.Data.SupChannelWidthSet = 1;
    wd->sta.HTCap.Data.HtCapInfo |= HTCAP_SMEnabled;
    wd->sta.HTCap.Data.HtCapInfo |= HTCAP_SupChannelWidthSet;
    wd->sta.HTCap.Data.HtCapInfo |= HTCAP_ShortGIfor40MHz;
    wd->sta.HTCap.Data.HtCapInfo |= HTCAP_DSSSandCCKin40MHz;
#ifndef ZM_DISABLE_AMSDU8K_SUPPORT
    wd->sta.HTCap.Data.HtCapInfo |= HTCAP_MaxAMSDULength;
#endif
    //wd->sta.HTCap.Data.MIMOPowerSave = 0;
    //wd->sta.HTCap.Data.ShortGIfor40MHz = 0;
    //wd->sta.HTCap.Data.ShortGIfor20MHz = 0;
    //wd->sta.HTCap.Data.DSSSandCCKin40MHz = 0;
    wd->sta.HTCap.Data.AMPDUParam |= HTCAP_MaxRxAMPDU3;
    wd->sta.HTCap.Data.MCSSet[0] = 0xFF; // MCS 0 ~  7
    wd->sta.HTCap.Data.MCSSet[1] = 0xFF; // MCS 8 ~ 15
    wd->sta.HTCap.Data.PCO |= HTCAP_TransmissionTime3;
    //wd->sta.HTCap.Data.TransmissionTime = 0;
    /* Init Extended HT Capability Info */
    wd->sta.ExtHTCap.Data.ElementID = ZM_WLAN_EID_EXTENDED_HT_CAPABILITY;
    wd->sta.ExtHTCap.Data.Length = 22;
    wd->sta.ExtHTCap.Data.ControlChannel = 6;

    //wd->sta.ExtHTCap.Data.ExtChannelOffset |= 3;
    wd->sta.ExtHTCap.Data.ChannelInfo |= ExtHtCap_ExtChannelOffsetBelow;

    //wd->sta.ExtHTCap.Data.RecomTxWidthSet = 1;
    //wd->sta.ExtHTCap.Data.RIFSMode = 1;
    wd->sta.ExtHTCap.Data.OperatingInfo |= 1;
#endif

#if 0
    /* WME test code */
    wd->ap.qosMode[0] = 1;
#endif

    wd->ledStruct.ledMode[0] = 0x2221;
    wd->ledStruct.ledMode[1] = 0x2221;

    zfTimerInit(dev);

    ZM_PERFORMANCE_INIT(dev);

    zfBssInfoCreate(dev);
    zfScanMgrInit(dev);
    zfPowerSavingMgrInit(dev);

#if 0
    /* Test code */
    {
        u32_t key[4] = {0xffffffff, 0xff, 0, 0};
        u16_t addr[3] = {0x8000, 0x01ab, 0x0000};
        //zfSetKey(dev, 0, 0, ZM_WEP64, addr, key);
        //zfSetKey(dev, 0, 0, ZM_AES, addr, key);
        //zfSetKey(dev, 64, 0, 1, wd->macAddr, key);
    }
#endif

    // WME settings
    wd->ws.staWmeEnabled = 1;           // Enable WME by default
    #define ZM_UAPSD_Q_SIZE 32 //2^N
    wd->ap.uapsdQ = zfQueueCreate(dev, ZM_UAPSD_Q_SIZE);
    zm_assert(wd->ap.uapsdQ != NULL);
    wd->sta.uapsdQ = zfQueueCreate(dev, ZM_UAPSD_Q_SIZE);
    zm_assert(wd->sta.uapsdQ != NULL);

    //zfHpInit(dev, wd->frequency);

    /* MAC address */
    //zfHpSetMacAddress(dev, wd->macAddr, 0);
    zfHpGetMacAddress(dev);

    zfCoreSetFrequency(dev, wd->frequency);

#if ZM_PCI_LOOP_BACK == 1
    zfwWriteReg(dev, ZM_REG_PCI_CONTROL, 6);
#endif /* #if ZM_PCI_LOOP_BACK == 1 */

    //zfiWlanSetDot11DMode(dev , 1); // Enable 802.11d
    //zfiWlanSetDot11HDFSMode(dev , 1); // Enable 802.11h DFS
    wd->sta.DFSEnable = 1;
    wd->sta.capability[1] |= ZM_BIT_0;

    //zfiWlanSetFrequency(dev, 5260000, TRUE);
    //zfiWlanSetAniMode(dev , 1); // Enable ANI

    /* Trgger Rx DMA */
    zfHpStartRecv(dev);

    zm_debug_msg0("end");

    return 0;
}

/* WLAN hardware will be shutdown and all resource will be release */
u16_t zfiWlanClose(zdev_t* dev)
{
    zmw_get_wlan_dev(dev);

    zm_msg0_init(ZM_LV_0, "enter");

    wd->state = ZM_WLAN_STATE_CLOSEDED;

    //zfiWlanDisable(dev, 1);
    zfWlanReset(dev);

    zfHpStopRecv(dev);

    /* Disable MAC */
    /* Disable PHY */
    /* Disable RF */

    zfHpRelease(dev);

    zfQueueDestroy(dev, wd->ap.uapsdQ);
    zfQueueDestroy(dev, wd->sta.uapsdQ);

    zfBssInfoDestroy(dev);

#ifdef ZM_ENABLE_AGGREGATION
    /* add by honda */
    zfAggRxFreeBuf(dev, 1);  //1 for release structure memory
    /* end of add by honda */
#endif

    zm_msg0_init(ZM_LV_0, "exit");

    return 0;
}

void zfGetWrapperSetting(zdev_t* dev)
{
    u8_t   bPassive;
    u16_t vapId = 0;

    zmw_get_wlan_dev(dev);

    zmw_declare_for_critical_section();
#if 0
    if ( (wd->ws.countryIsoName[0] != 0)
         || (wd->ws.countryIsoName[1] != 0)
         || (wd->ws.countryIsoName[2] != '\0') )
    {
        zfHpGetRegulationTablefromRegionCode(
            dev,
            zfHpGetRegionCodeFromIsoName(dev, wd->ws.countryIsoName) );
    }
#endif
    zmw_enter_critical_section(dev);

    wd->wlanMode = wd->ws.wlanMode;

    /* set channel */
    if ( wd->ws.frequency )
    {
        wd->frequency = wd->ws.frequency;
        wd->ws.frequency = 0;
    }
    else
    {
        wd->frequency = zfChGetFirstChannel(dev, &bPassive);

        if ( wd->wlanMode == ZM_MODE_IBSS )
        {
            if (wd->ws.adhocMode == ZM_ADHOCBAND_A)
            {
                wd->frequency = ZM_CH_A_36;
            }
            else
            {
            wd->frequency = ZM_CH_G_6;
            }
        }
    }
#ifdef ZM_AP_DEBUG
    /* honda add for debug, 2437 channel 6, 2452 channel 9 */
    wd->frequency = 2437;
    /* end of add by honda */
#endif

    /* set preamble type */
    switch (wd->ws.preambleType)
    {
    case ZM_PREAMBLE_TYPE_AUTO:
    case ZM_PREAMBLE_TYPE_SHORT:
    case ZM_PREAMBLE_TYPE_LONG:
        wd->preambleType = wd->ws.preambleType;
        break;
    default:
        wd->preambleType = ZM_PREAMBLE_TYPE_SHORT;
        break;
    }
    wd->ws.preambleType = 0;

    if ( wd->wlanMode == ZM_MODE_AP )
    {
        vapId = zfwGetVapId(dev);

        if (vapId == 0xffff)
        {
            wd->ap.authAlgo[0] = wd->ws.authMode;
            wd->ap.encryMode[0] = wd->ws.encryMode;
        }
        else
        {
            wd->ap.authAlgo[vapId + 1] = wd->ws.authMode;
            wd->ap.encryMode[vapId + 1] = wd->ws.encryMode;
        }
        wd->ws.authMode = 0;
        wd->ws.encryMode = ZM_NO_WEP;

        /* Get beaconInterval from WrapperSetting */
        if ((wd->ws.beaconInterval >= 20) && (wd->ws.beaconInterval <= 1000))
        {
            wd->beaconInterval = wd->ws.beaconInterval;
        }
        else
        {
            wd->beaconInterval = 100; //100ms
        }

        if (wd->ws.dtim > 0)
        {
            wd->dtim = wd->ws.dtim;
        }
        else
        {
            wd->dtim = 1;
        }

        wd->ap.qosMode = wd->ws.apWmeEnabled & 0x1;
        wd->ap.uapsdEnabled = (wd->ws.apWmeEnabled & 0x2) >> 1;
    }
    else
    {
        wd->sta.authMode = wd->ws.authMode;
        wd->sta.currentAuthMode = wd->ws.authMode;
        wd->sta.wepStatus = wd->ws.wepStatus;

        if ( wd->ws.beaconInterval )
        {
            wd->beaconInterval = wd->ws.beaconInterval;
        }
        else
        {
            wd->beaconInterval = 0x64;
        }

        if ( wd->wlanMode == ZM_MODE_IBSS )
        {
            /* 1. Set default channel 6 (2437MHz) */
//            wd->frequency = 2437;

            /* 2. Otus support 802.11g Mode */
            if ((wd->ws.adhocMode == ZM_ADHOCBAND_G) ||
                (wd->ws.adhocMode == ZM_ADHOCBAND_BG) ||
                (wd->ws.adhocMode == ZM_ADHOCBAND_ABG) ) {
                wd->wfc.bIbssGMode = 1;
            } else {
                wd->wfc.bIbssGMode = 0;
            }

            /* 3. set short preamble  */
            //wd->sta.preambleType = ZM_PREAMBLE_TYPE_SHORT ;
        }

        /* set ATIM window */
        if ( wd->ws.atimWindow )
        {
            wd->sta.atimWindow = wd->ws.atimWindow;
        }
        else
        {
            //wd->sta.atimWindow = 0x0a;
            wd->sta.atimWindow = 0;
        }

        //wd->sta.connectingHiddenAP = 1;//wd->ws.connectingHiddenAP;
        wd->sta.dropUnencryptedPkts = wd->ws.dropUnencryptedPkts;
        wd->sta.ibssJoinOnly = wd->ws.ibssJoinOnly;

        if ( wd->ws.bDesiredBssid )
        {
            zfMemoryCopy(wd->sta.desiredBssid, wd->ws.desiredBssid, 6);
            wd->sta.bDesiredBssid = TRUE;
            wd->ws.bDesiredBssid = FALSE;
        }
        else
        {
            wd->sta.bDesiredBssid = FALSE;
        }

        /* check ssid */
        if ( wd->ws.ssidLen != 0 )
        {
            if ( (!zfMemoryIsEqual(wd->ws.ssid, wd->sta.ssid,
                                   wd->sta.ssidLen))||
                 (wd->ws.ssidLen != wd->sta.ssidLen)||
                 (wd->sta.authMode == ZM_AUTH_MODE_WPA)||
                 (wd->sta.authMode == ZM_AUTH_MODE_WPAPSK) ||
                 (wd->ws.staWmeQosInfo!= 0) )
            {
                /*if u-APSD test(set QosInfo), clear connectByReasso to do association (not reassociation)*/
                wd->sta.connectByReasso = FALSE;
                wd->sta.failCntOfReasso = 0;
                wd->sta.pmkidInfo.bssidCount = 0;

                wd->sta.ssidLen = wd->ws.ssidLen;
                zfMemoryCopy(wd->sta.ssid, wd->ws.ssid, wd->sta.ssidLen);

                if ( wd->sta.ssidLen < 32 )
                {
                    wd->sta.ssid[wd->sta.ssidLen] = 0;
                }
            }
        }
        else
        {   /* ANY BSS */
            wd->sta.ssid[0] = 0;
            wd->sta.ssidLen = 0;
        }

        wd->sta.wmeEnabled = wd->ws.staWmeEnabled;
        wd->sta.wmeQosInfo = wd->ws.staWmeQosInfo;

    }

    zmw_leave_critical_section(dev);
}

u16_t zfWlanEnable(zdev_t* dev)
{
    u8_t     bssid[6] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
    u16_t i;

    zmw_get_wlan_dev(dev);

    zmw_declare_for_critical_section();

    if ( wd->wlanMode == ZM_MODE_UNKNOWN )
    {
        zm_debug_msg0("Unknown Mode...Skip...");
        return 0;
    }

    if (wd->wlanMode == ZM_MODE_AP)
    {
        u16_t vapId;

        vapId = zfwGetVapId(dev);

        if (vapId == 0xffff)
        {
            /* AP mode */
            zfApInitStaTbl(dev);

            /* AP default parameters */
            wd->bRate = 0xf;
            wd->gRate = 0xff;
            wd->bRateBasic = 0xf;
            wd->gRateBasic = 0x0;
            //wd->beaconInterval = 100;
            wd->ap.apBitmap = 1;
            wd->ap.beaconCounter = 0;
            //wd->ap.vapNumber = 1;    //mark by ygwei for Vap

            wd->ap.hideSsid[0] = 0;
            wd->ap.staAgingTimeSec = 10*60;
            wd->ap.staProbingTimeSec = 60;

            for (i=0; i<ZM_MAX_AP_SUPPORT; i++)
            {
                wd->ap.bcmcHead[i] = wd->ap.bcmcTail[i] = 0;
            }

            //wd->ap.uniHead = wd->ap.uniTail = 0;

            /* load AP parameters */
            wd->bRateBasic = wd->ws.bRateBasic;
            wd->gRateBasic = wd->ws.gRateBasic;
            wd->bgMode = wd->ws.bgMode;
            if ((wd->ws.ssidLen <= 32) && (wd->ws.ssidLen != 0))
            {
                wd->ap.ssidLen[0] = wd->ws.ssidLen;
                for(i=0; i<wd->ws.ssidLen; i++)
                {
                    wd->ap.ssid[0][i] = wd->ws.ssid[i];
                }
                wd->ws.ssidLen = 0; // Reset Wrapper Variable
            }

            if (wd->ap.encryMode[0] == 0)
            {
                wd->ap.capab[0] = 0x001;
            }
            else
            {
                wd->ap.capab[0] = 0x011;
            }
            /* set Short Slot Time bit if not 11b */
            if (wd->ap.wlanType[0] != ZM_WLAN_TYPE_PURE_B)
            {
              wd->ap.capab[0] |= 0x400;
            }

            // wd->ap.vapNumber = 1;    // mark by ygwei for Vap Test
        }
        else
        {
#if 0
            /* VAP Test Code */
            wd->ap.apBitmap = 0x3;
            wd->ap.capab[1] = 0x401;
            wd->ap.ssidLen[1] = 4;
            wd->ap.ssid[1][0] = 'v';
            wd->ap.ssid[1][1] = 'a';
            wd->ap.ssid[1][2] = 'p';
            wd->ap.ssid[1][3] = '1';
            wd->ap.authAlgo[1] = wd->ws.authMode;
            wd->ap.encryMode[1] = wd->ws.encryMode;
            wd->ap.vapNumber = 2;
#else
            /* VAP Test Code */
            wd->ap.apBitmap = 0x1 | (0x01 << (vapId+1));

            if ((wd->ws.ssidLen <= 32) && (wd->ws.ssidLen != 0))
            {
                wd->ap.ssidLen[vapId+1] = wd->ws.ssidLen;
                for(i=0; i<wd->ws.ssidLen; i++)
                {
                    wd->ap.ssid[vapId+1][i] = wd->ws.ssid[i];
                }
                wd->ws.ssidLen = 0; // Reset Wrapper Variable
            }

            if (wd->ap.encryMode[vapId+1] == 0)
            {
                wd->ap.capab[vapId+1] = 0x401;
            }
            else
            {
                wd->ap.capab[vapId+1] = 0x411;
            }

            wd->ap.authAlgo[vapId+1] = wd->ws.authMode;
            wd->ap.encryMode[vapId+1] = wd->ws.encryMode;

            /* Need to be modified when VAP is used */
            //wd->ap.vapNumber = 2;
#endif
        }

        wd->ap.vapNumber++;

        zfCoreSetFrequency(dev, wd->frequency);

        zfInitMacApMode(dev);

        /* Disable protection mode */
        zfApSetProtectionMode(dev, 0);

        zfApSendBeacon(dev);
    } /*if (wd->wlanMode == ZM_MODE_AP) */
    else
    {
        zfScanMgrScanStop(dev, ZM_SCAN_MGR_SCAN_INTERNAL);
        zfScanMgrScanStop(dev, ZM_SCAN_MGR_SCAN_EXTERNAL);

        zmw_enter_critical_section(dev);
        wd->sta.oppositeCount = 0;    /* reset opposite count */
        //wd->sta.bAutoReconnect = wd->sta.bAutoReconnectEnabled;
        //wd->sta.scanWithSSID = 0;
        zfStaInitOppositeInfo(dev);
        zmw_leave_critical_section(dev);

        zfStaResetStatus(dev, 0);

        if ( (wd->sta.cmDisallowSsidLength != 0)&&
             (wd->sta.ssidLen == wd->sta.cmDisallowSsidLength)&&
             (zfMemoryIsEqual(wd->sta.ssid, wd->sta.cmDisallowSsid,
                              wd->sta.ssidLen)) &&
             (wd->sta.wepStatus == ZM_ENCRYPTION_TKIP))
        {   /* countermeasures */
            zm_debug_msg0("countermeasures disallow association");

        }
        else
        {
            switch( wd->wlanMode )
            {
                case ZM_MODE_IBSS:
                    /* some registers may be set here */
                    if ( wd->sta.authMode == ZM_AUTH_MODE_WPA2PSK )
                    {
                        zfHpSetApStaMode(dev, ZM_HAL_80211_MODE_IBSS_WPA2PSK);
                    }
                    else
                    {
                        zfHpSetApStaMode(dev, ZM_HAL_80211_MODE_IBSS_GENERAL);
                    }

                    zm_msg0_mm(ZM_LV_0, "ZM_MODE_IBSS");
                    zfIbssConnectNetwork(dev);
                    break;

                case ZM_MODE_INFRASTRUCTURE:
                    /* some registers may be set here */
                    zfHpSetApStaMode(dev, ZM_HAL_80211_MODE_STA);

                    zfInfraConnectNetwork(dev);
                    break;

                case ZM_MODE_PSEUDO:
                    /* some registers may be set here */
                    zfHpSetApStaMode(dev, ZM_HAL_80211_MODE_STA);

                    zfUpdateBssid(dev, bssid);
                    zfCoreSetFrequency(dev, wd->frequency);
                    break;

                default:
                    break;
            }
        }

    }


    //if ( (wd->wlanMode != ZM_MODE_INFRASTRUCTURE)&&
    //     (wd->wlanMode != ZM_MODE_AP) )
    if ( wd->wlanMode == ZM_MODE_PSEUDO )
    {
        /* Reset Wlan status */
        zfWlanReset(dev);

        if (wd->zfcbConnectNotify != NULL)
        {
            wd->zfcbConnectNotify(dev, ZM_STATUS_MEDIA_CONNECT, wd->sta.bssid);
        }
        zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTED);
    }


    if(wd->wlanMode == ZM_MODE_AP)
    {
        if (wd->zfcbConnectNotify != NULL)
        {
            wd->zfcbConnectNotify(dev, ZM_STATUS_MEDIA_CONNECT, wd->sta.bssid);
        }
        //zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTED);
    }

    // Assign default Tx Rate
    if ( wd->sta.EnableHT )
    {
		u32_t oneTxStreamCap;
		oneTxStreamCap = (zfHpCapability(dev) & ZM_HP_CAP_11N_ONE_TX_STREAM);
		if(oneTxStreamCap)
			wd->CurrentTxRateKbps = 135000;
		else
			wd->CurrentTxRateKbps = 270000;
        wd->CurrentRxRateKbps = 270000;
    }
    else
    {
        wd->CurrentTxRateKbps = 54000;
        wd->CurrentRxRateKbps = 54000;
    }

    wd->state = ZM_WLAN_STATE_ENABLED;

    return 0;
}

/* Enable/disable Wlan operation */
u16_t zfiWlanEnable(zdev_t* dev)
{
    u16_t ret;

    zmw_get_wlan_dev(dev);

    zm_msg0_mm(ZM_LV_1, "Enable Wlan");

    zfGetWrapperSetting(dev);

    zfZeroMemory((u8_t*) &wd->trafTally, sizeof(struct zsTrafTally));

    // Reset cmMicFailureCount to 0 for new association request
    if ( wd->sta.cmMicFailureCount == 1 )
    {
        zfTimerCancel(dev, ZM_EVENT_CM_TIMER);
        wd->sta.cmMicFailureCount = 0;
    }

    zfFlushVtxq(dev);
    if ((wd->queueFlushed & 0x10) != 0)
    {
        zfHpUsbReset(dev);
    }
    ret = zfWlanEnable(dev);

    return ret;
}
/* Add a flag named ResetKeyCache to show if KeyCache should be cleared.
   for hostapd in AP mode, if driver receives iwconfig ioctl
   after setting group key, it shouldn't clear KeyCache.                 */
u16_t zfiWlanDisable(zdev_t* dev, u8_t ResetKeyCache)
{
    u16_t  i;
    u8_t isConnected;

    zmw_get_wlan_dev(dev);

#ifdef ZM_ENABLE_IBSS_WPA2PSK
    zmw_declare_for_critical_section();
#endif
    wd->state = ZM_WLAN_STATE_DISABLED;

    zm_msg0_mm(ZM_LV_1, "Disable Wlan");

    if ( wd->wlanMode != ZM_MODE_AP )
    {
        isConnected = zfStaIsConnected(dev);

        if ( (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)&&
             (wd->sta.currentAuthMode != ZM_AUTH_MODE_WPA2) )
        {
            /* send deauthentication frame */
            if (isConnected)
            {
                //zfiWlanDeauth(dev, NULL, 0);
                zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, wd->sta.bssid, 3, 0, 0);
                //zmw_debug_msg0("send a Deauth frame!");
            }
        }

        // Remove all the connected peer stations
        if ( wd->wlanMode == ZM_MODE_IBSS )
        {
            wd->sta.ibssBssIsCreator = 0;
            zfTimerCancel(dev, ZM_EVENT_IBSS_MONITOR);
            zfStaIbssMonitoring(dev, 1);
        }

#ifdef ZM_ENABLE_IBSS_WPA2PSK
        zmw_enter_critical_section(dev);
        wd->sta.ibssWpa2Psk = 0;
        zmw_leave_critical_section(dev);
#endif

        wd->sta.wpaState = ZM_STA_WPA_STATE_INIT;

        /* reset connect timeout counter */
        wd->sta.connectTimeoutCount = 0;

        /* reset connectState to None */
        wd->sta.connectState = ZM_STA_CONN_STATE_NONE;

        /* reset leap enable variable */
        wd->sta.leapEnabled = 0;

        /* Disable the RIFS Status / RIFS-like frame count / RIFS count */
        if( wd->sta.rifsState == ZM_RIFS_STATE_DETECTED )
            zfHpDisableRifs(dev);
        wd->sta.rifsState = ZM_RIFS_STATE_DETECTING;
        wd->sta.rifsLikeFrameCnt = 0;
        wd->sta.rifsCount = 0;

        wd->sta.osRxFilter = 0;
        wd->sta.bSafeMode = 0;

        zfChangeAdapterState(dev, ZM_STA_STATE_DISCONNECT);
        if (ResetKeyCache)
            zfHpResetKeyCache(dev);

        if (isConnected)
        {
            if (wd->zfcbConnectNotify != NULL)
            {
                wd->zfcbConnectNotify(dev, ZM_STATUS_MEDIA_CONNECTION_DISABLED, wd->sta.bssid);
            }
        }
        else
        {
            if (wd->zfcbConnectNotify != NULL)
            {
                wd->zfcbConnectNotify(dev, ZM_STATUS_MEDIA_DISABLED, wd->sta.bssid);
            }
        }
    }
    else //if (wd->wlanMode == ZM_MODE_AP)
    {
        for (i=0; i<ZM_MAX_STA_SUPPORT; i++)
        {
            /* send deauthentication frame */
            if (wd->ap.staTable[i].valid == 1)
            {
                /* Reason : Sending station is leaving */
                zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH,
                        wd->ap.staTable[i].addr, 3, 0, 0);
            }
        }

        if (ResetKeyCache)
            zfHpResetKeyCache(dev);

        wd->ap.vapNumber--;
    }

    /* stop beacon */
    zfHpDisableBeacon(dev);

    /* Flush VTxQ and MmQ */
    zfFlushVtxq(dev);
    /* Flush AP PS queues */
    zfApFlushBufferedPsFrame(dev);
    /* Free buffer in defragment list*/
    zfAgingDefragList(dev, 1);

    #ifdef ZM_ENABLE_AGGREGATION
    /* add by honda */
    zfAggRxFreeBuf(dev, 0);  //1 for release structure memory
    /* end of add by honda */
    #endif

    // Clear the information for the peer stations of IBSS or AP of Station mode
    zfZeroMemory((u8_t*)wd->sta.oppositeInfo, sizeof(struct zsOppositeInfo) * ZM_MAX_OPPOSITE_COUNT);

    /* Turn off Software WEP/TKIP */
    if (wd->sta.SWEncryptEnable != 0)
    {
        zm_debug_msg0("Disable software encryption");
        zfStaDisableSWEncryption(dev);
    }

    /* Improve WEP/TKIP performace with HT AP, detail information please look bug#32495 */
    //zfHpSetTTSIFSTime(dev, 0x8);

    return 0;
}

u16_t zfiWlanSuspend(zdev_t* dev)
{
    zmw_get_wlan_dev(dev);
    zmw_declare_for_critical_section();

    // Change the HAL state to init so that any packet can't be transmitted between
    // resume & HAL reinit. This would cause the chip hang issue in OTUS.
    zmw_enter_critical_section(dev);
    wd->halState = ZM_HAL_STATE_INIT;
    zmw_leave_critical_section(dev);

    return 0;
}

u16_t zfiWlanResume(zdev_t* dev, u8_t doReconn)
{
    u16_t ret;
    zmw_get_wlan_dev(dev);
    zmw_declare_for_critical_section();

    /* Redownload firmware, Reinit MAC,PHY,RF */
    zfHpReinit(dev, wd->frequency);

    //Set channel according to AP's configuration
    zfCoreSetFrequencyExV2(dev, wd->frequency, wd->BandWidth40,
            wd->ExtOffset, NULL, 1);

    zfHpSetMacAddress(dev, wd->macAddr, 0);

    /* Start Rx */
    zfHpStartRecv(dev);

    zfFlushVtxq(dev);

    if ( wd->wlanMode != ZM_MODE_INFRASTRUCTURE &&
         wd->wlanMode != ZM_MODE_IBSS )
    {
        return 1;
    }

    zm_msg0_mm(ZM_LV_1, "Resume Wlan");
    if ( (zfStaIsConnected(dev)) || (zfStaIsConnecting(dev)) )
    {
        if (doReconn == 1)
        {
            zm_msg0_mm(ZM_LV_1, "Re-connect...");
            zmw_enter_critical_section(dev);
            wd->sta.connectByReasso = FALSE;
            zmw_leave_critical_section(dev);

            zfWlanEnable(dev);
        }
        else if (doReconn == 0)
        {
            zfHpSetRollCallTable(dev);
        }
    }

    ret = 0;

    return ret;
}

/************************************************************************/
/*                                                                      */
/*    FUNCTION DESCRIPTION                 zfiWlanFlushAllQueuedBuffers */
/*      Flush Virtual TxQ, MmQ, PS frames and defragment list           */
/*                                                                      */
/*    INPUTS                                                            */
/*      dev : device pointer                                            */
/*                                                                      */
/*    OUTPUTS                                                           */
/*      None                                                            */
/*                                                                      */
/*    AUTHOR                                                            */
/*      Stephen Chen        Atheros Communications, INC.    2007.1      */
/*                                                                      */
/************************************************************************/
void zfiWlanFlushAllQueuedBuffers(zdev_t* dev)
{
    /* Flush VTxQ and MmQ */
    zfFlushVtxq(dev);
    /* Flush AP PS queues */
    zfApFlushBufferedPsFrame(dev);
    /* Free buffer in defragment list*/
    zfAgingDefragList(dev, 1);
}

/* Do WLAN site survey */
u16_t zfiWlanScan(zdev_t* dev)
{
    u16_t ret = 1;
    zmw_get_wlan_dev(dev);

    zm_debug_msg0("");

    zmw_declare_for_critical_section();

    zmw_enter_critical_section(dev);

    if (wd->wlanMode == ZM_MODE_AP)
    {
        wd->heartBeatNotification |= ZM_BSSID_LIST_SCAN;
        wd->sta.scanFrequency = 0;
        //wd->sta.pUpdateBssList->bssCount = 0;
        ret = 0;
    }
    else
    {
        #if 0
        if ( !zfStaBlockWlanScan(dev) )
        {
            zm_debug_msg0("scan request");
            //zfTimerSchedule(dev, ZM_EVENT_SCAN, ZM_TICK_ZERO);
            ret = 0;
            goto start_scan;
        }
        #else
            goto start_scan;
        #endif
    }

    zmw_leave_critical_section(dev);

    return ret;

start_scan:
    zmw_leave_critical_section(dev);

    if(wd->ledStruct.LEDCtrlFlagFromReg & ZM_LED_CTRL_FLAG_ALPHA)   // flag for Alpha
        wd->ledStruct.LEDCtrlFlag |= ZM_LED_CTRL_FLAG_ALPHA;

    ret = zfScanMgrScanStart(dev, ZM_SCAN_MGR_SCAN_EXTERNAL);

    zm_debug_msg1("ret = ", ret);

    return ret;
}


/* rate         */
/*    0 : AUTO  */
/*    1 : CCK 1M */
/*    2 : CCK 2M */
/*    3 : CCK 5.5M */
/*    4 : CCK 11M */
/*    5 : OFDM 6M */
/*    6 : OFDM 9M */
/*    7 : OFDM 12M */
/*    8 : OFDM 18M */
/*    9 : OFDM 24M */
/*    10 : OFDM 36M */
/*    11 : OFDM 48M */
/*    12 : OFDM 54M */
/*    13 : MCS 0 */
/*    28 : MCS 15 */
u16_t zcRateToMCS[] =
    {0xff, 0, 1, 2, 3, 0xb, 0xf, 0xa, 0xe, 0x9, 0xd, 0x8, 0xc};
u16_t zcRateToMT[] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1};

u16_t zfiWlanSetTxRate(zdev_t* dev, u16_t rate)
{   // jhlee HT 0
    zmw_get_wlan_dev(dev);

    if (rate <=12)
    {
        wd->txMCS = zcRateToMCS[rate];
        wd->txMT = zcRateToMT[rate];
        return ZM_SUCCESS;
    }
    else if ((rate<=28)||(rate==13+32))
    {
        wd->txMCS = rate - 12 - 1;
        wd->txMT = 2;
        return ZM_SUCCESS;
    }

    return ZM_ERR_INVALID_TX_RATE;
}

const u32_t zcRateIdToKbps40M[] =
    {
        1000, 2000, 5500, 11000,                  /* 1M, 2M, 5M, 11M          ,  0  1  2  3*/
        6000, 9000, 12000, 18000,                 /* 6M  9M  12M  18M         ,  4  5  6  7*/
        24000, 36000, 48000, 54000,               /* 24M  36M  48M  54M       ,  8  9 10 11*/
        13500, 27000, 40500, 54000,               /* MCS0 MCS1 MCS2 MCS3      , 12 13 14 15*/
        81000, 108000, 121500, 135000,            /* MCS4 MCS5 MCS6 MCS7      , 16 17 18 19*/
        27000, 54000, 81000, 108000,              /* MCS8 MCS9 MCS10 MCS11    , 20 21 22 23*/
        162000, 216000, 243000, 270000,           /* MCS12 MCS13 MCS14 MCS15  , 24 25 26 27*/
        270000, 300000, 150000                    /* MCS14SG, MCS15SG, MCS7SG , 28 29 30*/
    };

const u32_t zcRateIdToKbps20M[] =
    {
        1000, 2000, 5500, 11000,                  /* 1M, 2M, 5M, 11M          ,  0  1  2  3*/
        6000, 9000, 12000, 18000,                 /* 6M  9M  12M  18M         ,  4  5  6  7*/
        24000, 36000, 48000, 54000,               /* 24M  36M  48M  54M       ,  8  9 10 11*/
        6500, 13000, 19500, 26000,                /* MCS0 MCS1 MCS2 MCS3      , 12 13 14 15*/
        39000, 52000, 58500, 65000,               /* MCS4 MCS5 MCS6 MCS7      , 16 17 18 19*/
        13000, 26000, 39000, 52000,               /* MCS8 MCS9 MCS10 MCS11    , 20 21 22 23*/
        78000, 104000, 117000, 130000,            /* MCS12 MCS13 MCS14 MCS15  , 24 25 26 27*/
        130000, 144400, 72200                     /* MCS14SG, MCS15SG, MSG7SG , 28 29 30*/
    };

u32_t zfiWlanQueryTxRate(zdev_t* dev)
{
    u8_t rateId = 0xff;
    zmw_get_wlan_dev(dev);
    zmw_declare_for_critical_section();

    /* If Tx rate had not been trained, return maximum Tx rate instead */
    if ((wd->wlanMode == ZM_MODE_INFRASTRUCTURE) && (zfStaIsConnected(dev)))
    {
        zmw_enter_critical_section(dev);
        //Not in fixed rate mode
        if (wd->txMCS == 0xff)
        {
            if ((wd->sta.oppositeInfo[0].rcCell.flag & ZM_RC_TRAINED_BIT) == 0)
            {
                rateId = wd->sta.oppositeInfo[0].rcCell.operationRateSet[wd->sta.oppositeInfo[0].rcCell.operationRateCount-1];
            }
            else
            {
                rateId = wd->sta.oppositeInfo[0].rcCell.operationRateSet[wd->sta.oppositeInfo[0].rcCell.currentRateIndex];
            }
        }
        zmw_leave_critical_section(dev);
    }
    if (rateId != 0xff)
    {
        if (wd->sta.htCtrlBandwidth)
        {
            return zcRateIdToKbps40M[rateId];
        }
        else
        {
            return zcRateIdToKbps20M[rateId];
        }
    }
    else
    {
        return wd->CurrentTxRateKbps;
    }
}

void zfWlanUpdateRxRate(zdev_t* dev, struct zsAdditionInfo* addInfo)
{
    u32_t rxRateKbps;
    zmw_get_wlan_dev(dev);
    //zm_msg1_mm(ZM_LV_0, "addInfo->Tail.Data.RxMacStatus =", addInfo->Tail.Data.RxMacStatus & 0x03);

    /* b5~b4: MPDU indication.                */
    /*        00: Single MPDU.                */
    /*        10: First MPDU of A-MPDU.       */
    /*        11: Middle MPDU of A-MPDU.      */
    /*        01: Last MPDU of A-MPDU.        */
    /* Only First MPDU and Single MPDU have PLCP header */
    /* First MPDU  : (mpduInd & 0x30) == 0x00 */
    /* Single MPDU : (mpduInd & 0x30) == 0x20 */
    if ((addInfo->Tail.Data.RxMacStatus & 0x10) == 0)
    {
        /* Modulation type */
        wd->modulationType = addInfo->Tail.Data.RxMacStatus & 0x03;
        switch(wd->modulationType)
        {
    		case 0x0: wd->rateField = addInfo->PlcpHeader[0] & 0xff; //CCK mode
                      wd->rxInfo = 0;
                      break;
    		case 0x1: wd->rateField = addInfo->PlcpHeader[0] & 0x0f; //Legacy-OFDM mode
                      wd->rxInfo = 0;
                      break;
    		case 0x2: wd->rateField = addInfo->PlcpHeader[3]; //HT-OFDM mode
    		          wd->rxInfo = addInfo->PlcpHeader[6];
                      break;
            default: break;
         }

        rxRateKbps = zfUpdateRxRate(dev);
        if (wd->CurrentRxRateUpdated == 1)
        {
            if (rxRateKbps > wd->CurrentRxRateKbps)
            {
                wd->CurrentRxRateKbps = rxRateKbps;
            }
        }
        else
        {
            wd->CurrentRxRateKbps = rxRateKbps;
            wd->CurrentRxRateUpdated = 1;
        }
    }
}
#if 0
u16_t zcIndextoRateBG[16] = {1000, 2000, 5500, 11000, 0, 0, 0, 0, 48000,
                               24000, 12000, 6000, 54000, 36000, 18000, 9000};
u32_t zcIndextoRateN20L[16] = {6500, 13000, 19500, 26000, 39000, 52000, 58500,
                              65000, 13000, 26000, 39000, 52000, 78000, 104000,
                              117000, 130000};
u32_t zcIndextoRateN20S[16] = {7200, 14400, 21700, 28900, 43300, 57800, 65000,
                              72200, 14400, 28900, 43300, 57800, 86700, 115600,
                              130000, 144400};
u32_t zcIndextoRateN40L[16] = {13500, 27000, 40500, 54000, 81000, 108000, 121500,
                              135000, 27000, 54000, 81000, 108000, 162000, 216000,
                              243000, 270000};
u32_t zcIndextoRateN40S[16] = {15000, 30000, 45000, 60000, 90000, 120000, 135000,
                              150000, 30000, 60000, 90000, 120000, 180000, 240000,
                              270000, 300000};
#endif

extern u16_t zcIndextoRateBG[16];
extern u32_t zcIndextoRateN20L[16];
extern u32_t zcIndextoRateN20S[16];
extern u32_t zcIndextoRateN40L[16];
extern u32_t zcIndextoRateN40S[16];

u32_t zfiWlanQueryRxRate(zdev_t* dev)
{
    zmw_get_wlan_dev(dev);

    wd->CurrentRxRateUpdated = 0;
    return wd->CurrentRxRateKbps;
}

u32_t zfUpdateRxRate(zdev_t* dev)
{
    u8_t mcs, bandwidth;
    u32_t rxRateKbps = 130000;
    zmw_get_wlan_dev(dev);

    switch (wd->modulationType)
    {
		case 0x0: //CCK mode
                  switch (wd->rateField)
                  {
                      case 0x0a: rxRateKbps = 1000;
                            break;
                      case 0x14: rxRateKbps = 2000;

                      case 0x37: rxRateKbps = 5500;
                            break;
                      case 0x6e: rxRateKbps = 11000;
                            break;
                      default:
                            break;
                  }
                  break;
		case 0x1: //Legacy-OFDM mode
                  if (wd->rateField <= 15)
                  {
                      rxRateKbps = zcIndextoRateBG[wd->rateField];
                  }
                  break;
		case 0x2: //HT-OFDM mode
		          mcs = wd->rateField & 0x7F;
		          bandwidth = wd->rateField & 0x80;
                  if (mcs <= 15)
                  {
                      if (bandwidth != 0)
                      {
                          if((wd->rxInfo & 0x80) != 0)
                          {
                              /* Short GI 40 MHz MIMO Rate */
                              rxRateKbps = zcIndextoRateN40S[mcs];
                          }
                          else
                          {
                              /* Long GI 40 MHz MIMO Rate */
                              rxRateKbps = zcIndextoRateN40L[mcs];
                          }
                      }
                      else
                      {
                          if((wd->rxInfo & 0x80) != 0)
                          {
                              /* Short GI 20 MHz MIMO Rate */
                              rxRateKbps = zcIndextoRateN20S[mcs];
                          }
                          else
                          {
                              /* Long GI 20 MHz MIMO Rate */
                              rxRateKbps = zcIndextoRateN20L[mcs];
                          }
                      }
                  }
                  break;
        default:
                  break;
    }
    //zm_msg1_mm(ZM_LV_0, "wd->CurrentRxRateKbps=", wd->CurrentRxRateKbps);

     // ToDo: use bandwith field to define 40MB
    return rxRateKbps;
}

/* Get WLAN stastics */
u16_t zfiWlanGetStatistics(zdev_t* dev)
{
    /* Return link statistics */
    return 0;
}

u16_t zfiWlanReset(zdev_t* dev)
{
    zmw_get_wlan_dev(dev);

    wd->state = ZM_WLAN_STATE_DISABLED;

    return zfWlanReset(dev);
}

/* Reset WLAN */
u16_t zfWlanReset(zdev_t* dev)
{
    u8_t isConnected;
    zmw_get_wlan_dev(dev);

    zmw_declare_for_critical_section();

    zm_debug_msg0("zfWlanReset");

    isConnected = zfStaIsConnected(dev);

    //if ( wd->wlanMode != ZM_MODE_AP )
    {
        if ( (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)&&
             (wd->sta.currentAuthMode != ZM_AUTH_MODE_WPA2) )
        {
            /* send deauthentication frame */
            if (isConnected)
            {
                //zfiWlanDeauth(dev, NULL, 0);
                zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, wd->sta.bssid, 3, 0, 0);
                //zmw_debug_msg0("send a Deauth frame!");
            }
        }
    }

    zfChangeAdapterState(dev, ZM_STA_STATE_DISCONNECT);
    zfHpResetKeyCache(dev);

    if (isConnected)
    {
        //zfiWlanDisable(dev);
        if (wd->zfcbConnectNotify != NULL)
        {
            wd->zfcbConnectNotify(dev, ZM_STATUS_MEDIA_CONNECTION_RESET, wd->sta.bssid);
        }
    }
    else
    {
        if (wd->zfcbConnectNotify != NULL)
        {
            wd->zfcbConnectNotify(dev, ZM_STATUS_MEDIA_RESET, wd->sta.bssid);
        }
    }

    /* stop beacon */
    zfHpDisableBeacon(dev);

    /* Free buffer in defragment list*/
    zfAgingDefragList(dev, 1);

    /* Flush VTxQ and MmQ */
    zfFlushVtxq(dev);

    #ifdef ZM_ENABLE_AGGREGATION
    /* add by honda */
    zfAggRxFreeBuf(dev, 0);  //1 for release structure memory
    /* end of add by honda */
    #endif

    zfStaRefreshBlockList(dev, 1);

    zmw_enter_critical_section(dev);

    zfTimerCancel(dev, ZM_EVENT_IBSS_MONITOR);
    zfTimerCancel(dev, ZM_EVENT_CM_BLOCK_TIMER);
    zfTimerCancel(dev, ZM_EVENT_CM_DISCONNECT);

    wd->sta.connectState = ZM_STA_CONN_STATE_NONE;
    wd->sta.connectByReasso = FALSE;
    wd->sta.cmDisallowSsidLength = 0;
    wd->sta.bAutoReconnect = 0;
    wd->sta.InternalScanReq = 0;
    wd->sta.encryMode = ZM_NO_WEP;
    wd->sta.wepStatus = ZM_ENCRYPTION_WEP_DISABLED;
    wd->sta.wpaState = ZM_STA_WPA_STATE_INIT;
    wd->sta.cmMicFailureCount = 0;
    wd->sta.ibssBssIsCreator = 0;
#ifdef ZM_ENABLE_IBSS_WPA2PSK
    wd->sta.ibssWpa2Psk = 0;
#endif
    /* reset connect timeout counter */
    wd->sta.connectTimeoutCount = 0;

    /* reset leap enable variable */
    wd->sta.leapEnabled = 0;

    /* Reset the RIFS Status / RIFS-like frame count / RIFS count */
    if( wd->sta.rifsState == ZM_RIFS_STATE_DETECTED )
        zfHpDisableRifs(dev);
    wd->sta.rifsState = ZM_RIFS_STATE_DETECTING;
    wd->sta.rifsLikeFrameCnt = 0;
    wd->sta.rifsCount = 0;

    wd->sta.osRxFilter = 0;
    wd->sta.bSafeMode = 0;

    // Clear the information for the peer stations of IBSS or AP of Station mode
    zfZeroMemory((u8_t*)wd->sta.oppositeInfo, sizeof(struct zsOppositeInfo) * ZM_MAX_OPPOSITE_COUNT);

    zmw_leave_critical_section(dev);

    zfScanMgrScanStop(dev, ZM_SCAN_MGR_SCAN_INTERNAL);
    zfScanMgrScanStop(dev, ZM_SCAN_MGR_SCAN_EXTERNAL);

    /* Turn off Software WEP/TKIP */
    if (wd->sta.SWEncryptEnable != 0)
    {
        zm_debug_msg0("Disable software encryption");
        zfStaDisableSWEncryption(dev);
    }

    /* Improve WEP/TKIP performace with HT AP, detail information please look bug#32495 */
    //zfHpSetTTSIFSTime(dev, 0x8);

    /* Keep Pseudo mode */
    if ( wd->wlanMode != ZM_MODE_PSEUDO )
    {
        wd->wlanMode = ZM_MODE_INFRASTRUCTURE;
    }
    return 0;
}

/* Deauthenticate a STA */
u16_t zfiWlanDeauth(zdev_t* dev, u16_t* macAddr, u16_t reason)
{
    zmw_get_wlan_dev(dev);

    if ( wd->wlanMode == ZM_MODE_AP )
    {
        //u16_t id;

        /*
         * we will reset all key in zfHpResetKeyCache() when call
         * zfiWlanDisable(), if we want to reset PairwiseKey for each sta,
         * need to use a nullAddr to let keyindex not match.
         * otherwise hardware will still find PairwiseKey when AP change
         * encryption mode from WPA to WEP
         */

        /*
        if ((id = zfApFindSta(dev, macAddr)) != 0xffff)
        {
            u32_t key[8];
            u16_t nullAddr[3] = { 0x0, 0x0, 0x0 };

            if (wd->ap.staTable[i].encryMode != ZM_NO_WEP)
            {
                zfHpSetApPairwiseKey(dev, nullAddr,
                        ZM_NO_WEP, &key[0], &key[4], i+1);
            }
            //zfHpSetApPairwiseKey(dev, (u16_t *)macAddr,
            //        ZM_NO_WEP, &key[0], &key[4], id+1);
            wd->ap.staTable[id].encryMode = ZM_NO_WEP;
            wd->ap.staTable[id].keyIdx = 0xff;
        }
        */

        zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, macAddr, reason, 0, 0);
    }
    else
    {
        zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, wd->sta.bssid, 3, 0, 0);
    }

    /* Issue DEAUTH command to FW */
    return 0;
}


/* XP packet filter feature : */
/* 1=>enable: All multicast address packets, not just the ones enumerated in the multicast address list. */
/* 0=>disable */
void zfiWlanSetAllMulticast(zdev_t* dev, u32_t setting)
{
    zmw_get_wlan_dev(dev);
    zm_msg1_mm(ZM_LV_0, "sta.bAllMulticast = ", setting);
    wd->sta.bAllMulticast = (u8_t)setting;
}


/* HT configure API */
void zfiWlanSetHTCtrl(zdev_t* dev, u32_t *setting, u32_t forceTxTPC)
{
    zmw_get_wlan_dev(dev);

    wd->preambleType        = (u8_t)setting[0];
    wd->sta.preambleTypeHT  = (u8_t)setting[1];
    wd->sta.htCtrlBandwidth = (u8_t)setting[2];
    wd->sta.htCtrlSTBC      = (u8_t)setting[3];
    wd->sta.htCtrlSG        = (u8_t)setting[4];
    wd->sta.defaultTA       = (u8_t)setting[5];
    wd->enableAggregation   = (u8_t)setting[6];
    wd->enableWDS           = (u8_t)setting[7];

    wd->forceTxTPC          = forceTxTPC;
}

/* FB50 in OS XP, RD private test code */
void zfiWlanQueryHTCtrl(zdev_t* dev, u32_t *setting, u32_t *forceTxTPC)
{
    zmw_get_wlan_dev(dev);

    setting[0] = wd->preambleType;
    setting[1] = wd->sta.preambleTypeHT;
    setting[2] = wd->sta.htCtrlBandwidth;
    setting[3] = wd->sta.htCtrlSTBC;
    setting[4] = wd->sta.htCtrlSG;
    setting[5] = wd->sta.defaultTA;
    setting[6] = wd->enableAggregation;
    setting[7] = wd->enableWDS;

    *forceTxTPC = wd->forceTxTPC;
}

void zfiWlanDbg(zdev_t* dev, u8_t setting)
{
    zmw_get_wlan_dev(dev);

    wd->enableHALDbgInfo = setting;
}

/* FB50 in OS XP, RD private test code */
void zfiWlanSetRxPacketDump(zdev_t* dev, u32_t setting)
{
    zmw_get_wlan_dev(dev);
    if (setting)
    {
        wd->rxPacketDump = 1;   /* enable */
    }
    else
    {
        wd->rxPacketDump = 0;   /* disable */
    }
}


/* FB50 in OS XP, RD private test code */
/* Tally */
void zfiWlanResetTally(zdev_t* dev)
{
    zmw_get_wlan_dev(dev);

    zmw_declare_for_critical_section();

    zmw_enter_critical_section(dev);

	   wd->commTally.txUnicastFrm = 0;		//txUnicastFrames
	   wd->commTally.txMulticastFrm = 0;		//txMulticastFrames
	   wd->commTally.txUnicastOctets = 0;	//txUniOctets  byte size
	   wd->commTally.txMulticastOctets = 0;	//txMultiOctets  byte size
	   wd->commTally.txFrmUpperNDIS = 0;
	   wd->commTally.txFrmDrvMgt = 0;
	   wd->commTally.RetryFailCnt = 0;
	   wd->commTally.Hw_TotalTxFrm = 0;		//Hardware total Tx Frame
	   wd->commTally.Hw_RetryCnt = 0;		//txMultipleRetriesFrames
	   wd->commTally.Hw_UnderrunCnt = 0;//
	   wd->commTally.DriverRxFrmCnt = 0;//
	   wd->commTally.rxUnicastFrm = 0;		//rxUnicastFrames
	   wd->commTally.rxMulticastFrm = 0;	//rxMulticastFrames
	   wd->commTally.NotifyNDISRxFrmCnt = 0;//
	   wd->commTally.rxUnicastOctets = 0;	//rxUniOctets  byte size
	   wd->commTally.rxMulticastOctets = 0;	//rxMultiOctets  byte size
	   wd->commTally.DriverDiscardedFrm = 0;// Discard by ValidateFrame
	   wd->commTally.LessThanDataMinLen = 0;//
	   wd->commTally.GreaterThanMaxLen = 0;//
	   wd->commTally.DriverDiscardedFrmCauseByMulticastList = 0;
	   wd->commTally.DriverDiscardedFrmCauseByFrmCtrl = 0;
	   wd->commTally.rxNeedFrgFrm = 0;		// need more frg frm
	   wd->commTally.DriverRxMgtFrmCnt = 0;
	   wd->commTally.rxBroadcastFrm = 0;	//Receive broadcast frame count
	   wd->commTally.rxBroadcastOctets = 0;	//Receive broadcast frame byte size
	   wd->commTally.Hw_TotalRxFrm = 0;//
	   wd->commTally.Hw_CRC16Cnt = 0;		//rxPLCPCRCErrCnt
	   wd->commTally.Hw_CRC32Cnt = 0;		//rxCRC32ErrCnt
	   wd->commTally.Hw_DecrypErr_UNI = 0;//
	   wd->commTally.Hw_DecrypErr_Mul = 0;//
	   wd->commTally.Hw_RxFIFOOverrun = 0;//
	   wd->commTally.Hw_RxTimeOut = 0;
	   wd->commTally.LossAP = 0;//

	   wd->commTally.Tx_MPDU = 0;
	   wd->commTally.BA_Fail = 0;
	   wd->commTally.Hw_Tx_AMPDU = 0;
	   wd->commTally.Hw_Tx_MPDU = 0;

    wd->commTally.txQosDropCount[0] = 0;
    wd->commTally.txQosDropCount[1] = 0;
    wd->commTally.txQosDropCount[2] = 0;
    wd->commTally.txQosDropCount[3] = 0;
    wd->commTally.txQosDropCount[4] = 0;

    wd->commTally.Hw_RxMPDU = 0;
    wd->commTally.Hw_RxDropMPDU = 0;
    wd->commTally.Hw_RxDelMPDU = 0;

    wd->commTally.Hw_RxPhyMiscError = 0;
    wd->commTally.Hw_RxPhyXRError = 0;
    wd->commTally.Hw_RxPhyOFDMError = 0;
    wd->commTally.Hw_RxPhyCCKError = 0;
    wd->commTally.Hw_RxPhyHTError = 0;
    wd->commTally.Hw_RxPhyTotalCount = 0;

#if	(defined(GCCK) && defined(OFDM))
	   wd->commTally.rx11bDataFrame = 0;
	   wd->commTally.rxOFDMDataFrame = 0;
#endif

    zmw_leave_critical_section(dev);
}

/* FB50 in OS XP, RD private test code */
void zfiWlanQueryTally(zdev_t* dev, struct zsCommTally *tally)
{
    zmw_get_wlan_dev(dev);

    zmw_declare_for_critical_section();

    zmw_enter_critical_section(dev);
    zfMemoryCopy((u8_t*)tally, (u8_t*)&wd->commTally, sizeof(struct zsCommTally));
    zmw_leave_critical_section(dev);
}
void zfiWlanQueryTrafTally(zdev_t* dev, struct zsTrafTally *tally)
{
    zmw_get_wlan_dev(dev);

    zmw_declare_for_critical_section();

    zmw_enter_critical_section(dev);
    zfMemoryCopy((u8_t*)tally, (u8_t*)&wd->trafTally, sizeof(struct zsTrafTally));
    zmw_leave_critical_section(dev);
}

void zfiWlanQueryMonHalRxInfo(zdev_t* dev, struct zsMonHalRxInfo *monHalRxInfo)
{
    zfHpQueryMonHalRxInfo(dev, (u8_t *)monHalRxInfo);
}

/* parse the modeMDKEnable to DrvCore */
void zfiDKEnable(zdev_t* dev, u32_t enable)
{
    zmw_get_wlan_dev(dev);

    wd->modeMDKEnable = enable;
    zm_debug_msg1("modeMDKEnable = ", wd->modeMDKEnable);
}

/* airoPeek */
u32_t zfiWlanQueryPacketTypePromiscuous(zdev_t* dev)
{
    zmw_get_wlan_dev(dev);

    return wd->swSniffer;
}

/* airoPeek */
void zfiWlanSetPacketTypePromiscuous(zdev_t* dev, u32_t setValue)
{
    zmw_get_wlan_dev(dev);

	   wd->swSniffer = setValue;
	   zm_msg1_mm(ZM_LV_0, "wd->swSniffer ", wd->swSniffer);
	   if (setValue)
	   {
	       	/* write register for sniffer mode */
            zfHpSetSnifferMode(dev, 1);
            zm_msg0_mm(ZM_LV_1, "enalbe sniffer mode");
	   }
	   else
	   {
            zfHpSetSnifferMode(dev, 0);
            zm_msg0_mm(ZM_LV_0, "disalbe sniffer mode");
	   }
}

void zfiWlanSetXLinkMode(zdev_t* dev, u32_t setValue)
{
    zmw_get_wlan_dev(dev);

    wd->XLinkMode = setValue;
    if (setValue)
    {
        /* write register for sniffer mode */
        zfHpSetSnifferMode(dev, 1);
    }
    else
    {
        zfHpSetSnifferMode(dev, 0);
    }
}

extern void zfStaChannelManagement(zdev_t* dev, u8_t scan);
void zfiSetChannelManagement(zdev_t* dev, u32_t setting)
{
    zmw_get_wlan_dev(dev);

    switch (setting)
    {
        case 1:
            wd->sta.EnableHT = 1;
            wd->BandWidth40 = 1;
            wd->ExtOffset   = 1;
            break;
        case 3:
            wd->sta.EnableHT = 1;
            wd->BandWidth40 = 1;
            wd->ExtOffset   = 3;
            break;
        case 0:
            wd->sta.EnableHT = 1;
            wd->BandWidth40 = 0;
            wd->ExtOffset   = 0;
            break;
        default:
            wd->BandWidth40 = 0;
            wd->ExtOffset   = 0;
            break;

    }
    zfCoreSetFrequencyEx(dev, wd->frequency, wd->BandWidth40,
                    wd->ExtOffset, NULL);
}

void zfiSetRifs(zdev_t* dev, u16_t setting)
{
    zmw_get_wlan_dev(dev);

    wd->sta.ie.HtInfo.ChannelInfo |= ExtHtCap_RIFSMode;
    wd->sta.EnableHT = 1;
    switch (setting)
    {
        case 0:
            wd->sta.HT2040 = 0;
//            zfHpSetRifs(dev, 1, 0, (wd->sta.currentFrequency < 3000)? 1:0);
            break;
        case 1:
            wd->sta.HT2040 = 1;
//            zfHpSetRifs(dev, 1, 1, (wd->sta.currentFrequency < 3000)? 1:0);
            break;
        default:
            wd->sta.HT2040 = 0;
//            zfHpSetRifs(dev, 1, 0, (wd->sta.currentFrequency < 3000)? 1:0);
            break;
    }
}

void zfiCheckRifs(zdev_t* dev)
{
    zmw_get_wlan_dev(dev);

    if(wd->sta.ie.HtInfo.ChannelInfo & ExtHtCap_RIFSMode)
    {
//        zfHpSetRifs(dev, wd->sta.EnableHT, wd->sta.HT2040, (wd->sta.currentFrequency < 3000)? 1:0);
    }
}

void zfiSetReorder(zdev_t* dev, u16_t value)
{
    zmw_get_wlan_dev(dev);

    wd->reorder = value;
}

void zfiSetSeqDebug(zdev_t* dev, u16_t value)
{
    zmw_get_wlan_dev(dev);

    wd->seq_debug = value;
}
