/*
 * 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: wcmd.c
 *
 * Purpose: Handles the management command interface functions
 *
 * Author: Lyndon Chen
 *
 * Date: May 8, 2003
 *
 * Functions:
 *      s_vProbeChannel - Active scan channel
 *      s_MgrMakeProbeRequest - Make ProbeRequest packet
 *      CommandTimer - Timer function to handle command
 *      s_bCommandComplete - Command Complete function
 *      bScheduleCommand - Push Command and wait Command Scheduler to do
 *      vCommandTimer- Command call back functions
 *      vCommandTimerWait- Call back timer
 *      bClearBSSID_SCAN- Clear BSSID_SCAN cmd in CMD Queue
 *
 * Revision History:
 *
 */

#include "ttype.h"
#include "tmacro.h"
#include "device.h"
#include "mac.h"
#include "card.h"
#include "80211hdr.h"
#include "wcmd.h"
#include "wmgr.h"
#include "power.h"
#include "wctl.h"
#include "baseband.h"
#include "rxtx.h"
#include "rf.h"
#include "iowpa.h"
#include "channel.h"

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

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

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

static
void
s_vProbeChannel(
	struct vnt_private *pDevice
);

static
PSTxMgmtPacket
s_MgrMakeProbeRequest(
	struct vnt_private *pDevice,
	PSMgmtObject pMgmt,
	unsigned char *pScanBSSID,
	PWLAN_IE_SSID pSSID,
	PWLAN_IE_SUPP_RATES pCurrRates,
	PWLAN_IE_SUPP_RATES pCurrExtSuppRates
);

static
bool
s_bCommandComplete(
	struct vnt_private *pDevice
);

/*---------------------  Export Variables  --------------------------*/

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

/*
 * Description:
 *      Stop AdHoc beacon during scan process
 *
 * Parameters:
 *  In:
 *      pDevice     - Pointer to the adapter
 *  Out:
 *      none
 *
 * Return Value: none
 *
 */
static
void
vAdHocBeaconStop(struct vnt_private *pDevice)
{
	PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
	bool bStop;

	/*
	 * temporarily stop Beacon packet for AdHoc Server
	 * if all of the following conditions are met:
	 *  (1) STA is in AdHoc mode
	 *  (2) VT3253 is programmed as automatic Beacon Transmitting
	 *  (3) One of the following conditions is met
	 *      (3.1) AdHoc channel is in B/G band and the
	 *      current scan channel is in A band
	 *      or
	 *      (3.2) AdHoc channel is in A mode
	 */
	bStop = false;
	if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
	    (pMgmt->eCurrState >= WMAC_STATE_STARTED)) {
		if ((pMgmt->uIBSSChannel <=  CB_MAX_CHANNEL_24G) &&
		    (pMgmt->uScanChannel > CB_MAX_CHANNEL_24G)) {
			bStop = true;
		}
		if (pMgmt->uIBSSChannel >  CB_MAX_CHANNEL_24G)
			bStop = true;

	}

	if (bStop)
		MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
} /* vAdHocBeaconStop */

/*
 * Description:
 *      Restart AdHoc beacon after scan process complete
 *
 * Parameters:
 *  In:
 *      pDevice     - Pointer to the adapter
 *  Out:
 *      none
 *
 * Return Value: none
 *
 */
static
void
vAdHocBeaconRestart(struct vnt_private *pDevice)
{
	PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);

	/*
	 * Restart Beacon packet for AdHoc Server
	 * if all of the following coditions are met:
	 *  (1) STA is in AdHoc mode
	 *  (2) VT3253 is programmed as automatic Beacon Transmitting
	 */
	if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
	    (pMgmt->eCurrState >= WMAC_STATE_STARTED)) {
		MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
	}
}

/*+
 *
 * Routine Description:
 *   Prepare and send probe request management frames.
 *
 *
 * Return Value:
 *    none.
 *
 -*/

static
void
s_vProbeChannel(
	struct vnt_private *pDevice
)
{
	//1M,   2M,   5M,   11M,  18M,  24M,  36M,  54M
	unsigned char abyCurrSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C};
	unsigned char abyCurrExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60};
	//6M,   9M,   12M,  48M
	unsigned char abyCurrSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
	unsigned char abyCurrSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16};
	unsigned char *pbyRate;
	PSTxMgmtPacket  pTxPacket;
	PSMgmtObject    pMgmt = pDevice->pMgmt;
	unsigned int ii;

	if (pDevice->eCurrentPHYType == PHY_TYPE_11A)
		pbyRate = &abyCurrSuppRatesA[0];
	else if (pDevice->eCurrentPHYType == PHY_TYPE_11B)
		pbyRate = &abyCurrSuppRatesB[0];
	else
		pbyRate = &abyCurrSuppRatesG[0];

	// build an assocreq frame and send it
	pTxPacket = s_MgrMakeProbeRequest
		(
			pDevice,
			pMgmt,
			pMgmt->abyScanBSSID,
			(PWLAN_IE_SSID)pMgmt->abyScanSSID,
			(PWLAN_IE_SUPP_RATES)pbyRate,
			(PWLAN_IE_SUPP_RATES)abyCurrExtSuppRatesG
			);

	if (pTxPacket != NULL) {
		for (ii = 0; ii < 2; ii++) {
			if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING)
				pr_debug("Probe request sending fail..\n");
			else
				pr_debug("Probe request is sending..\n");
		}
	}
}

/*+
 *
 * Routine Description:
 *  Constructs an probe request frame
 *
 *
 * Return Value:
 *    A ptr to Tx frame or NULL on allocation failure
 *
 -*/

static PSTxMgmtPacket
s_MgrMakeProbeRequest(
	struct vnt_private *pDevice,
	PSMgmtObject pMgmt,
	unsigned char *pScanBSSID,
	PWLAN_IE_SSID pSSID,
	PWLAN_IE_SUPP_RATES pCurrRates,
	PWLAN_IE_SUPP_RATES pCurrExtSuppRates

)
{
	PSTxMgmtPacket      pTxPacket = NULL;
	WLAN_FR_PROBEREQ    sFrame;

	pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
	memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_PROBEREQ_FR_MAXLEN);
	pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
	sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
	sFrame.len = WLAN_PROBEREQ_FR_MAXLEN;
	vMgrEncodeProbeRequest(&sFrame);
	sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
		(
			WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
			WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PROBEREQ)
));
	memcpy(sFrame.pHdr->sA3.abyAddr1, pScanBSSID, WLAN_ADDR_LEN);
	memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
	memcpy(sFrame.pHdr->sA3.abyAddr3, pScanBSSID, WLAN_BSSID_LEN);
	// Copy the SSID, pSSID->len=0 indicate broadcast SSID
	sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
	sFrame.len += pSSID->len + WLAN_IEHDR_LEN;
	memcpy(sFrame.pSSID, pSSID, pSSID->len + WLAN_IEHDR_LEN);
	sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
	sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN;
	memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
	// Copy the extension rate set
	if (pDevice->eCurrentPHYType == PHY_TYPE_11G) {
		sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
		sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN;
		memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN);
	}
	pTxPacket->cbMPDULen = sFrame.len;
	pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;

	return pTxPacket;
}

void
vCommandTimerWait(
	void *hDeviceContext,
	unsigned int MSecond
)
{
	struct vnt_private *pDevice = hDeviceContext;

	init_timer(&pDevice->sTimerCommand);
	pDevice->sTimerCommand.data = (unsigned long) pDevice;
	pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer;
	// RUN_AT :1 msec ~= (HZ/1024)
	pDevice->sTimerCommand.expires = (unsigned int)RUN_AT((MSecond * HZ) >> 10);
	add_timer(&pDevice->sTimerCommand);
}

void
vCommandTimer(
	void *hDeviceContext
)
{
	struct vnt_private *pDevice = hDeviceContext;
	PSMgmtObject    pMgmt = pDevice->pMgmt;
	PWLAN_IE_SSID   pItemSSID;
	PWLAN_IE_SSID   pItemSSIDCurr;
	CMD_STATUS      Status;
	unsigned int ii;
	unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
	struct sk_buff  *skb;

	if (pDevice->dwDiagRefCount != 0)
		return;
	if (!pDevice->bCmdRunning)
		return;

	spin_lock_irq(&pDevice->lock);

	switch (pDevice->eCommandState) {
	case WLAN_CMD_SCAN_START:

		pDevice->byReAssocCount = 0;
		if (pDevice->bRadioOff) {
			s_bCommandComplete(pDevice);
			spin_unlock_irq(&pDevice->lock);
			return;
		}

		if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
			s_bCommandComplete(pDevice);
			CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, NL80211_IFTYPE_AP);
			spin_unlock_irq(&pDevice->lock);
			return;
		}

		pr_debug("eCommandState= WLAN_CMD_SCAN_START\n");
		pItemSSID = (PWLAN_IE_SSID)pMgmt->abyScanSSID;
		// wait all Data TD complete
		if (pDevice->iTDUsed[TYPE_AC0DMA] != 0) {
			spin_unlock_irq(&pDevice->lock);
			vCommandTimerWait((void *)pDevice, 10);
			return;
		}

		if (pMgmt->uScanChannel == 0) {
			pMgmt->uScanChannel = pDevice->byMinChannel;
			// Set Baseband to be more sensitive.

		}
		if (pMgmt->uScanChannel > pDevice->byMaxChannel) {
			pMgmt->eScanState = WMAC_NO_SCANNING;

			// Set Baseband's sensitivity back.
			// Set channel back
			set_channel(pMgmt->pAdapter, pMgmt->uCurrChannel);
			pr_debug("Scanning, set back to channel: [%d]\n",
				 pMgmt->uCurrChannel);
			if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)
				CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, NL80211_IFTYPE_ADHOC);
			else
				CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, NL80211_IFTYPE_STATION);

			vAdHocBeaconRestart(pDevice);
			s_bCommandComplete(pDevice);

		} else {
//2008-8-4 <add> by chester
			if (!is_channel_valid(pMgmt->uScanChannel)) {
				pr_debug("Invalid channel pMgmt->uScanChannel = %d\n",
					 pMgmt->uScanChannel);
				s_bCommandComplete(pDevice);
				spin_unlock_irq(&pDevice->lock);
				return;
			}
			if (pMgmt->uScanChannel == pDevice->byMinChannel) {
				pMgmt->abyScanBSSID[0] = 0xFF;
				pMgmt->abyScanBSSID[1] = 0xFF;
				pMgmt->abyScanBSSID[2] = 0xFF;
				pMgmt->abyScanBSSID[3] = 0xFF;
				pMgmt->abyScanBSSID[4] = 0xFF;
				pMgmt->abyScanBSSID[5] = 0xFF;
				pItemSSID->byElementID = WLAN_EID_SSID;
				pMgmt->eScanState = WMAC_IS_SCANNING;

			}

			vAdHocBeaconStop(pDevice);

			if (set_channel(pMgmt->pAdapter, pMgmt->uScanChannel))
				pr_debug("SCAN Channel: %d\n",
					 pMgmt->uScanChannel);
			else
				pr_debug("SET SCAN Channel Fail: %d\n",
					 pMgmt->uScanChannel);

			CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, NL80211_IFTYPE_UNSPECIFIED);
			pMgmt->uScanChannel++;
//2008-8-4 <modify> by chester
			if (!is_channel_valid(pMgmt->uScanChannel) &&
			    pMgmt->uScanChannel <= pDevice->byMaxChannel) {
				pMgmt->uScanChannel = pDevice->byMaxChannel + 1;
				pMgmt->eCommandState = WLAN_CMD_SCAN_END;

			}

			if (!pMgmt->b11hEnable ||
			    (pMgmt->uScanChannel < CB_MAX_CHANNEL_24G)) {
				s_vProbeChannel(pDevice);
				spin_unlock_irq(&pDevice->lock);
				vCommandTimerWait((void *)pDevice, WCMD_ACTIVE_SCAN_TIME);
				return;
			} else {
				spin_unlock_irq(&pDevice->lock);
				vCommandTimerWait((void *)pDevice, WCMD_PASSIVE_SCAN_TIME);
				return;
			}

		}

		break;

	case WLAN_CMD_SCAN_END:

		// Set Baseband's sensitivity back.
		// Set channel back
		set_channel(pMgmt->pAdapter, pMgmt->uCurrChannel);
		pr_debug("Scanning, set back to channel: [%d]\n",
			 pMgmt->uCurrChannel);
		if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)
			CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, NL80211_IFTYPE_ADHOC);
		else
			CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, NL80211_IFTYPE_STATION);

		pMgmt->eScanState = WMAC_NO_SCANNING;
		vAdHocBeaconRestart(pDevice);
//2008-0409-07, <Add> by Einsn Liu
#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
		if (pMgmt->eScanType == WMAC_SCAN_PASSIVE) {
			//send scan event to wpa_Supplicant
			union iwreq_data wrqu;

			memset(&wrqu, 0, sizeof(wrqu));
			wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL);
		}
#endif
		s_bCommandComplete(pDevice);
		break;

	case WLAN_CMD_DISASSOCIATE_START:
		pDevice->byReAssocCount = 0;
		if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
		    (pMgmt->eCurrState != WMAC_STATE_ASSOC)) {
			s_bCommandComplete(pDevice);
			spin_unlock_irq(&pDevice->lock);
			return;
		} else {
			pr_debug("Send Disassociation Packet..\n");
			// reason = 8 : disassoc because sta has left
			vMgrDisassocBeginSta((void *)pDevice, pMgmt, pMgmt->abyCurrBSSID, (8), &Status);
			pDevice->bLinkPass = false;
			// unlock command busy
			pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
			pItemSSID->len = 0;
			memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN);
			pMgmt->eCurrState = WMAC_STATE_IDLE;
			pMgmt->sNodeDBTable[0].bActive = false;
		}
		netif_stop_queue(pDevice->dev);
		pDevice->eCommandState = WLAN_DISASSOCIATE_WAIT;
		// wait all Control TD complete
		if (pDevice->iTDUsed[TYPE_TXDMA0] != 0) {
			vCommandTimerWait((void *)pDevice, 10);
			spin_unlock_irq(&pDevice->lock);
			return;
		}
		pr_debug(" CARDbRadioPowerOff\n");
		//2008-09-02  <mark>	by chester
		s_bCommandComplete(pDevice);
		break;

	case WLAN_DISASSOCIATE_WAIT:
		// wait all Control TD complete
		if (pDevice->iTDUsed[TYPE_TXDMA0] != 0) {
			vCommandTimerWait((void *)pDevice, 10);
			spin_unlock_irq(&pDevice->lock);
			return;
		}
//2008-09-02  <mark> by chester
		s_bCommandComplete(pDevice);
		break;

	case WLAN_CMD_SSID_START:
		pDevice->byReAssocCount = 0;
		if (pDevice->bRadioOff) {
			s_bCommandComplete(pDevice);
			spin_unlock_irq(&pDevice->lock);
			return;
		}
		pr_debug("chester-abyDesireSSID=%s\n", ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID);
		pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
		pItemSSIDCurr = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
		pr_debug(" cmd: desire ssid = %s\n", pItemSSID->abySSID);
		pr_debug(" cmd: curr ssid = %s\n", pItemSSIDCurr->abySSID);

		if (pMgmt->eCurrState == WMAC_STATE_ASSOC) {
			pr_debug(" Cmd pMgmt->eCurrState == WMAC_STATE_ASSOC\n");
			pr_debug(" pItemSSID->len =%d\n", pItemSSID->len);
			pr_debug(" pItemSSIDCurr->len = %d\n",
				 pItemSSIDCurr->len);
			pr_debug(" desire ssid = %s\n", pItemSSID->abySSID);
			pr_debug(" curr ssid = %s\n", pItemSSIDCurr->abySSID);
		}

		if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) ||
		    ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) {
			if (pItemSSID->len == pItemSSIDCurr->len) {
				if (memcmp(pItemSSID->abySSID, pItemSSIDCurr->abySSID, pItemSSID->len) == 0) {
					s_bCommandComplete(pDevice);
					spin_unlock_irq(&pDevice->lock);
					return;
				}
			}

			netif_stop_queue(pDevice->dev);
			pDevice->bLinkPass = false;
		}
		// set initial state
		pMgmt->eCurrState = WMAC_STATE_IDLE;
		pMgmt->eCurrMode = WMAC_MODE_STANDBY;
		PSvDisablePowerSaving((void *)pDevice);
		BSSvClearNodeDBTable(pDevice, 0);

		vMgrJoinBSSBegin((void *)pDevice, &Status);
		// if Infra mode
		if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED)) {
			// Call mgr to begin the deauthentication
			// reason = (3) because sta has left ESS
			if (pMgmt->eCurrState >= WMAC_STATE_AUTH)
				vMgrDeAuthenBeginSta((void *)pDevice, pMgmt, pMgmt->abyCurrBSSID, (3), &Status);

			// Call mgr to begin the authentication
			vMgrAuthenBeginSta((void *)pDevice, pMgmt, &Status);
			if (Status == CMD_STATUS_SUCCESS) {
				pDevice->byLinkWaitCount = 0;
				pDevice->eCommandState = WLAN_AUTHENTICATE_WAIT;
				vCommandTimerWait((void *)pDevice, AUTHENTICATE_TIMEOUT);
				spin_unlock_irq(&pDevice->lock);
				pr_debug(" Set eCommandState = WLAN_AUTHENTICATE_WAIT\n");
				return;
			}
		}
		// if Adhoc mode
		else if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
			if (pMgmt->eCurrState == WMAC_STATE_JOINTED) {
				if (netif_queue_stopped(pDevice->dev))
					netif_wake_queue(pDevice->dev);

				pDevice->bLinkPass = true;

				pMgmt->sNodeDBTable[0].bActive = true;
				pMgmt->sNodeDBTable[0].uInActiveCount = 0;
				bClearBSSID_SCAN(pDevice);
			} else {
				// start own IBSS
				vMgrCreateOwnIBSS((void *)pDevice, &Status);
				if (Status != CMD_STATUS_SUCCESS)
					pr_debug(" WLAN_CMD_IBSS_CREATE fail !\n");

				BSSvAddMulticastNode(pDevice);
			}
		}
		// if SSID not found
		else if (pMgmt->eCurrMode == WMAC_MODE_STANDBY) {
			if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA ||
			    pMgmt->eConfigMode == WMAC_CONFIG_AUTO) {
				// start own IBSS
				vMgrCreateOwnIBSS((void *)pDevice, &Status);
				if (Status != CMD_STATUS_SUCCESS)
					pr_debug(" WLAN_CMD_IBSS_CREATE fail !\n");

				BSSvAddMulticastNode(pDevice);
				if (netif_queue_stopped(pDevice->dev))
					netif_wake_queue(pDevice->dev);

				pDevice->bLinkPass = true;
			} else {
				pr_debug("Disconnect SSID none\n");
#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
				{
					union iwreq_data  wrqu;

					memset(&wrqu, 0, sizeof(wrqu));
					wrqu.ap_addr.sa_family = ARPHRD_ETHER;
					pr_debug("wireless_send_event--->SIOCGIWAP(disassociated:vMgrJoinBSSBegin Fail !!)\n");
					wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
				}
#endif

			}
		}
		s_bCommandComplete(pDevice);
		break;

	case WLAN_AUTHENTICATE_WAIT:
		pr_debug("eCommandState == WLAN_AUTHENTICATE_WAIT\n");
		if (pMgmt->eCurrState == WMAC_STATE_AUTH) {
			// Call mgr to begin the association
			pDevice->byLinkWaitCount = 0;
			pr_debug("eCurrState == WMAC_STATE_AUTH\n");
			vMgrAssocBeginSta((void *)pDevice, pMgmt, &Status);
			if (Status == CMD_STATUS_SUCCESS) {
				pDevice->byLinkWaitCount = 0;
				pr_debug("eCommandState = WLAN_ASSOCIATE_WAIT\n");
				pDevice->eCommandState = WLAN_ASSOCIATE_WAIT;
				vCommandTimerWait((void *)pDevice, ASSOCIATE_TIMEOUT);
				spin_unlock_irq(&pDevice->lock);
				return;
			}
		}

		else if (pMgmt->eCurrState < WMAC_STATE_AUTHPENDING) {
			pr_debug("WLAN_AUTHENTICATE_WAIT:Authen Fail???\n");
		} else if (pDevice->byLinkWaitCount <= 4) {    //mike add:wait another 2 sec if authenticated_frame delay!
			pDevice->byLinkWaitCount++;
			pr_debug("WLAN_AUTHENTICATE_WAIT:wait %d times!!\n", pDevice->byLinkWaitCount);
			spin_unlock_irq(&pDevice->lock);
			vCommandTimerWait((void *)pDevice, AUTHENTICATE_TIMEOUT/2);
			return;
		}
		pDevice->byLinkWaitCount = 0;
		s_bCommandComplete(pDevice);
		break;

	case WLAN_ASSOCIATE_WAIT:
		if (pMgmt->eCurrState == WMAC_STATE_ASSOC) {
			pr_debug("eCurrState == WMAC_STATE_ASSOC\n");
			if (pDevice->ePSMode != WMAC_POWER_CAM)
				PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval);

			if (pMgmt->eAuthenMode >= WMAC_AUTH_WPA)
				KeybRemoveAllKey(&(pDevice->sKey), pDevice->abyBSSID, pDevice->PortOffset);

			pDevice->bLinkPass = true;
			pDevice->byLinkWaitCount = 0;
			pDevice->byReAssocCount = 0;
			bClearBSSID_SCAN(pDevice);
			if (pDevice->byFOETuning) {
				BBvSetFOE(pDevice->PortOffset);
				PSbSendNullPacket(pDevice);
			}
			if (netif_queue_stopped(pDevice->dev))
				netif_wake_queue(pDevice->dev);

			if (pDevice->IsTxDataTrigger) {    //TxDataTimer is not triggered at the first time
				del_timer(&pDevice->sTimerTxData);
				init_timer(&pDevice->sTimerTxData);
				pDevice->sTimerTxData.data = (unsigned long) pDevice;
				pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData;
				pDevice->sTimerTxData.expires = RUN_AT(10*HZ);      //10s callback
				pDevice->fTxDataInSleep = false;
				pDevice->nTxDataTimeCout = 0;
			}

			pDevice->IsTxDataTrigger = true;
			add_timer(&pDevice->sTimerTxData);

		} else if (pMgmt->eCurrState < WMAC_STATE_ASSOCPENDING) {
			printk("WLAN_ASSOCIATE_WAIT:Association Fail???\n");
		} else if (pDevice->byLinkWaitCount <= 4) {    //mike add:wait another 2 sec if associated_frame delay!
			pDevice->byLinkWaitCount++;
			pr_debug("WLAN_ASSOCIATE_WAIT:wait %d times!!\n", pDevice->byLinkWaitCount);
			spin_unlock_irq(&pDevice->lock);
			vCommandTimerWait((void *)pDevice, ASSOCIATE_TIMEOUT/2);
			return;
		}
		pDevice->byLinkWaitCount = 0;

		s_bCommandComplete(pDevice);
		break;

	case WLAN_CMD_AP_MODE_START:
		pr_debug("eCommandState == WLAN_CMD_AP_MODE_START\n");

		if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
			del_timer(&pMgmt->sTimerSecondCallback);
			pMgmt->eCurrState = WMAC_STATE_IDLE;
			pMgmt->eCurrMode = WMAC_MODE_STANDBY;
			pDevice->bLinkPass = false;
			if (pDevice->bEnableHostWEP)
				BSSvClearNodeDBTable(pDevice, 1);
			else
				BSSvClearNodeDBTable(pDevice, 0);
			pDevice->uAssocCount = 0;
			pMgmt->eCurrState = WMAC_STATE_IDLE;
			pDevice->bFixRate = false;

			vMgrCreateOwnIBSS((void *)pDevice, &Status);
			if (Status != CMD_STATUS_SUCCESS)
				pr_debug(" vMgrCreateOwnIBSS fail !\n");

			// alway turn off unicast bit
			MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_UNICAST);
			pDevice->byRxMode &= ~RCR_UNICAST;
			pr_debug("wcmd: rx_mode = %x\n", pDevice->byRxMode);
			BSSvAddMulticastNode(pDevice);
			if (netif_queue_stopped(pDevice->dev))
				netif_wake_queue(pDevice->dev);

			pDevice->bLinkPass = true;
			add_timer(&pMgmt->sTimerSecondCallback);
		}
		s_bCommandComplete(pDevice);
		break;

	case WLAN_CMD_TX_PSPACKET_START:
		// DTIM Multicast tx
		if (pMgmt->sNodeDBTable[0].bRxPSPoll) {
			while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[0].sTxPSQueue)) != NULL) {
				if (skb_queue_empty(&pMgmt->sNodeDBTable[0].sTxPSQueue)) {
					pMgmt->abyPSTxMap[0] &= ~byMask[0];
					pDevice->bMoreData = false;
				} else {
					pDevice->bMoreData = true;
				}
				if (!device_dma0_xmit(pDevice, skb, 0))
					pr_debug("Multicast ps tx fail\n");

				pMgmt->sNodeDBTable[0].wEnQueueCnt--;
			}
		}

		// PS nodes tx
		for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
			if (pMgmt->sNodeDBTable[ii].bActive &&
			    pMgmt->sNodeDBTable[ii].bRxPSPoll) {
				pr_debug("Index=%d Enqueu Cnt= %d\n",
					 ii,
					 pMgmt->sNodeDBTable[ii].wEnQueueCnt);
				while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL) {
					if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) {
						// clear tx map
						pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &=
							~byMask[pMgmt->sNodeDBTable[ii].wAID & 7];
						pDevice->bMoreData = false;
					} else {
						pDevice->bMoreData = true;
					}
					if (!device_dma0_xmit(pDevice, skb, ii))
						pr_debug("sta ps tx fail\n");

					pMgmt->sNodeDBTable[ii].wEnQueueCnt--;
					// check if sta ps enabled, and wait next pspoll.
					// if sta ps disable, then send all pending buffers.
					if (pMgmt->sNodeDBTable[ii].bPSEnable)
						break;
				}
				if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) {
					// clear tx map
					pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &=
						~byMask[pMgmt->sNodeDBTable[ii].wAID & 7];
					pr_debug("Index=%d PS queue clear\n",
						 ii);
				}
				pMgmt->sNodeDBTable[ii].bRxPSPoll = false;
			}
		}

		s_bCommandComplete(pDevice);
		break;

	case WLAN_CMD_RADIO_START:
		pr_debug("eCommandState == WLAN_CMD_RADIO_START\n");
		if (pDevice->bRadioCmd)
			CARDbRadioPowerOn(pDevice);
		else
			CARDbRadioPowerOff(pDevice);

		s_bCommandComplete(pDevice);
		break;

	case WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE:
		// wait all TD complete
		if (pDevice->iTDUsed[TYPE_AC0DMA] != 0) {
			vCommandTimerWait((void *)pDevice, 10);
			spin_unlock_irq(&pDevice->lock);
			return;
		}
		if (pDevice->iTDUsed[TYPE_TXDMA0] != 0) {
			vCommandTimerWait((void *)pDevice, 10);
			spin_unlock_irq(&pDevice->lock);
			return;
		}
		pDevice->byBBVGACurrent = pDevice->byBBVGANew;
		BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent);
		pr_debug("SetVGAGainOffset %02X\n", pDevice->byBBVGACurrent);
		s_bCommandComplete(pDevice);
		break;

	default:
		s_bCommandComplete(pDevice);
		break;

	} //switch
	spin_unlock_irq(&pDevice->lock);
}

static
bool
s_bCommandComplete(
	struct vnt_private *pDevice
)
{
	PWLAN_IE_SSID pSSID;
	bool bRadioCmd = false;
	bool bForceSCAN = true;
	PSMgmtObject  pMgmt = pDevice->pMgmt;

	pDevice->eCommandState = WLAN_CMD_IDLE;
	if (pDevice->cbFreeCmdQueue == CMD_Q_SIZE) {
		//Command Queue Empty
		pDevice->bCmdRunning = false;
		return true;
	} else {
		pDevice->eCommand = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].eCmd;
		pSSID = (PWLAN_IE_SSID)pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].abyCmdDesireSSID;
		bRadioCmd = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bRadioCmd;
		bForceSCAN = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bForceSCAN;
		ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdDequeueIdx, CMD_Q_SIZE);
		pDevice->cbFreeCmdQueue++;
		pDevice->bCmdRunning = true;
		switch (pDevice->eCommand) {
		case WLAN_CMD_BSSID_SCAN:
			pr_debug("eCommandState= WLAN_CMD_BSSID_SCAN\n");
			pDevice->eCommandState = WLAN_CMD_SCAN_START;
			pMgmt->uScanChannel = 0;
			if (pSSID->len != 0)
				memcpy(pMgmt->abyScanSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
			else
				memset(pMgmt->abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);

			break;
		case WLAN_CMD_SSID:
			pDevice->eCommandState = WLAN_CMD_SSID_START;
			if (pSSID->len > WLAN_SSID_MAXLEN)
				pSSID->len = WLAN_SSID_MAXLEN;
			if (pSSID->len != 0)
				memcpy(pDevice->pMgmt->abyDesireSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
			pr_debug("eCommandState= WLAN_CMD_SSID_START\n");
			break;
		case WLAN_CMD_DISASSOCIATE:
			pDevice->eCommandState = WLAN_CMD_DISASSOCIATE_START;
			break;
		case WLAN_CMD_RX_PSPOLL:
			pDevice->eCommandState = WLAN_CMD_TX_PSPACKET_START;
			break;
		case WLAN_CMD_RUN_AP:
			pDevice->eCommandState = WLAN_CMD_AP_MODE_START;
			break;
		case WLAN_CMD_RADIO:
			pDevice->eCommandState = WLAN_CMD_RADIO_START;
			pDevice->bRadioCmd = bRadioCmd;
			break;
		case WLAN_CMD_CHANGE_BBSENSITIVITY:
			pDevice->eCommandState = WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE;
			break;

		default:
			break;

		}

		vCommandTimerWait((void *)pDevice, 0);
	}

	return true;
}

bool bScheduleCommand(
	void *hDeviceContext,
	CMD_CODE    eCommand,
	unsigned char *pbyItem0
)
{
	struct vnt_private *pDevice = hDeviceContext;

	if (pDevice->cbFreeCmdQueue == 0)
		return false;

	pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].eCmd = eCommand;
	pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = true;
	memset(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, 0 , WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);

	if (pbyItem0 != NULL) {
		switch (eCommand) {
		case WLAN_CMD_BSSID_SCAN:
			memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID,
			       pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
			pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = false;
			break;

		case WLAN_CMD_SSID:
			memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID,
			       pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
			break;

		case WLAN_CMD_DISASSOCIATE:
			pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bNeedRadioOFF = *((int *)pbyItem0);
			break;

		case WLAN_CMD_RX_PSPOLL:
			break;

		case WLAN_CMD_RADIO:
			pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bRadioCmd = *((int *)pbyItem0);
			break;

		case WLAN_CMD_CHANGE_BBSENSITIVITY:
			pDevice->eCommandState = WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE;
			break;

		default:
			break;
		}
	}

	ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdEnqueueIdx, CMD_Q_SIZE);
	pDevice->cbFreeCmdQueue--;

	if (!pDevice->bCmdRunning)
		s_bCommandComplete(pDevice);

	return true;
}

/*
 * Description:
 *      Clear BSSID_SCAN cmd in CMD Queue
 *
 * Parameters:
 *  In:
 *      hDeviceContext  - Pointer to the adapter
 *      eCommand        - Command
 *  Out:
 *      none
 *
 * Return Value: true if success; otherwise false
 *
 */
bool bClearBSSID_SCAN(
	void *hDeviceContext
)
{
	struct vnt_private *pDevice = hDeviceContext;
	unsigned int uCmdDequeueIdx = pDevice->uCmdDequeueIdx;
	unsigned int ii;

	if ((pDevice->cbFreeCmdQueue < CMD_Q_SIZE) && (uCmdDequeueIdx != pDevice->uCmdEnqueueIdx)) {
		for (ii = 0; ii < (CMD_Q_SIZE - pDevice->cbFreeCmdQueue); ii++) {
			if (pDevice->eCmdQueue[uCmdDequeueIdx].eCmd == WLAN_CMD_BSSID_SCAN)
				pDevice->eCmdQueue[uCmdDequeueIdx].eCmd = WLAN_CMD_IDLE;
			ADD_ONE_WITH_WRAP_AROUND(uCmdDequeueIdx, CMD_Q_SIZE);
			if (uCmdDequeueIdx == pDevice->uCmdEnqueueIdx)
				break;
		}
	}
	return true;
}

//mike add:reset command timer
void
vResetCommandTimer(
	void *hDeviceContext
)
{
	struct vnt_private *pDevice = hDeviceContext;

	//delete timer
	del_timer(&pDevice->sTimerCommand);
	//init timer
	init_timer(&pDevice->sTimerCommand);
	pDevice->sTimerCommand.data = (unsigned long) pDevice;
	pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer;
	pDevice->sTimerCommand.expires = RUN_AT(HZ);
	pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
	pDevice->uCmdDequeueIdx = 0;
	pDevice->uCmdEnqueueIdx = 0;
	pDevice->eCommandState = WLAN_CMD_IDLE;
	pDevice->bCmdRunning = false;
	pDevice->bCmdClear = false;
}

void
BSSvSecondTxData(
	void *hDeviceContext
)
{
	struct vnt_private *pDevice = hDeviceContext;
	PSMgmtObject  pMgmt = &(pDevice->sMgmtObj);

	pDevice->nTxDataTimeCout++;

	if (pDevice->nTxDataTimeCout < 4)     //don't tx data if timer less than 40s
	{
		pDevice->sTimerTxData.expires = RUN_AT(10*HZ);      //10s callback
		add_timer(&pDevice->sTimerTxData);
		return;
	}

	spin_lock_irq(&pDevice->lock);

	/* open && sharekey linking */
	if ((pDevice->bLinkPass && (pMgmt->eAuthenMode < WMAC_AUTH_WPA)) ||
	    pDevice->fWPA_Authened) {   /* wpa linking */
		pDevice->fTxDataInSleep = true;
		PSbSendNullPacket(pDevice);	/* send null packet */
		pDevice->fTxDataInSleep = false;
	}

	spin_unlock_irq(&pDevice->lock);

	pDevice->sTimerTxData.expires = RUN_AT(10*HZ); /* 10s callback */
	add_timer(&pDevice->sTimerTxData);
}
