/*
 *************************************************************************
 * Ralink Tech Inc.
 * 5F., No.36, Taiyuan St., Jhubei City,
 * Hsinchu County 302,
 * Taiwan, R.O.C.
 *
 * (c) Copyright 2002-2007, Ralink Technology, Inc.
 *
 * 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.,                                       *
 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 *                                                                       *
 *************************************************************************

	Module Name:
	rtusb_io.c

	Abstract:

	Revision History:
	Who			When	    What
	--------	----------  ----------------------------------------------
	Name		Date	    Modification logs
	Paul Lin    06-25-2004  created
*/

#ifdef RTMP_MAC_USB

#include "../rt_config.h"

/*
	========================================================================

	Routine Description: NIC initialization complete

	Arguments:

	Return Value:

	IRQL =

	Note:

	========================================================================
*/

static int RTUSBFirmwareRun(struct rt_rtmp_adapter *pAd)
{
	int Status;

	Status = RTUSB_VendorRequest(pAd,
				     USBD_TRANSFER_DIRECTION_OUT,
				     DEVICE_VENDOR_REQUEST_OUT,
				     0x01, 0x8, 0, NULL, 0);

	return Status;
}

/*
	========================================================================

	Routine Description: Write Firmware to NIC.

	Arguments:

	Return Value:

	IRQL =

	Note:

	========================================================================
*/
int RTUSBFirmwareWrite(struct rt_rtmp_adapter *pAd,
		       const u8 *pFwImage, unsigned long FwLen)
{
	u32 MacReg;
	int Status;
/*      unsigned long           i; */
	u16 writeLen;

	Status = RTUSBReadMACRegister(pAd, MAC_CSR0, &MacReg);

	writeLen = FwLen;
	RTUSBMultiWrite(pAd, FIRMWARE_IMAGE_BASE, pFwImage, writeLen);

	Status = RTUSBWriteMACRegister(pAd, 0x7014, 0xffffffff);
	Status = RTUSBWriteMACRegister(pAd, 0x701c, 0xffffffff);
	Status = RTUSBFirmwareRun(pAd);

	/*2008/11/28:KH add to fix the dead rf frequency offset bug<-- */
	RTMPusecDelay(10000);
	RTUSBWriteMACRegister(pAd, H2M_MAILBOX_CSR, 0);
	AsicSendCommandToMcu(pAd, 0x72, 0x00, 0x00, 0x00);	/*reset rf by MCU supported by new firmware */
	/*2008/11/28:KH add to fix the dead rf frequency offset bug--> */

	return Status;
}

int RTUSBVenderReset(struct rt_rtmp_adapter *pAd)
{
	int Status;
	DBGPRINT_RAW(RT_DEBUG_ERROR, ("-->RTUSBVenderReset\n"));
	Status = RTUSB_VendorRequest(pAd,
				     USBD_TRANSFER_DIRECTION_OUT,
				     DEVICE_VENDOR_REQUEST_OUT,
				     0x01, 0x1, 0, NULL, 0);

	DBGPRINT_RAW(RT_DEBUG_ERROR, ("<--RTUSBVenderReset\n"));
	return Status;
}

/*
	========================================================================

	Routine Description: Read various length data from RT2573

	Arguments:

	Return Value:

	IRQL =

	Note:

	========================================================================
*/
int RTUSBMultiRead(struct rt_rtmp_adapter *pAd,
			u16 Offset, u8 *pData, u16 length)
{
	int Status;

	Status = RTUSB_VendorRequest(pAd,
				     (USBD_TRANSFER_DIRECTION_IN |
				      USBD_SHORT_TRANSFER_OK),
				     DEVICE_VENDOR_REQUEST_IN, 0x7, 0, Offset,
				     pData, length);

	return Status;
}

/*
	========================================================================

	Routine Description: Write various length data to RT2573

	Arguments:

	Return Value:

	IRQL =

	Note:

	========================================================================
*/
int RTUSBMultiWrite_OneByte(struct rt_rtmp_adapter *pAd,
			    u16 Offset, const u8 *pData)
{
	int Status;

	/* TODO: In 2870, use this funciton carefully cause it's not stable. */
	Status = RTUSB_VendorRequest(pAd,
				     USBD_TRANSFER_DIRECTION_OUT,
				     DEVICE_VENDOR_REQUEST_OUT,
				     0x6, 0, Offset, (u8 *)pData, 1);

	return Status;
}

int RTUSBMultiWrite(struct rt_rtmp_adapter *pAd,
		    u16 Offset, const u8 *pData, u16 length)
{
	int Status;

	u16 index = 0, Value;
	const u8 *pSrc = pData;
	u16 resude = 0;

	resude = length % 2;
	length += resude;
	do {
		Value = (u16)(*pSrc | (*(pSrc + 1) << 8));
		Status = RTUSBSingleWrite(pAd, Offset + index, Value);
		index += 2;
		length -= 2;
		pSrc = pSrc + 2;
	} while (length > 0);

	return Status;
}

int RTUSBSingleWrite(struct rt_rtmp_adapter *pAd,
			  u16 Offset, u16 Value)
{
	int Status;

	Status = RTUSB_VendorRequest(pAd,
				     USBD_TRANSFER_DIRECTION_OUT,
				     DEVICE_VENDOR_REQUEST_OUT,
				     0x2, Value, Offset, NULL, 0);

	return Status;

}

/*
	========================================================================

	Routine Description: Read 32-bit MAC register

	Arguments:

	Return Value:

	IRQL =

	Note:

	========================================================================
*/
int RTUSBReadMACRegister(struct rt_rtmp_adapter *pAd,
			      u16 Offset, u32 *pValue)
{
	int Status = 0;
	u32 localVal;

	Status = RTUSB_VendorRequest(pAd,
				     (USBD_TRANSFER_DIRECTION_IN |
				      USBD_SHORT_TRANSFER_OK),
				     DEVICE_VENDOR_REQUEST_IN, 0x7, 0, Offset,
				     &localVal, 4);

	*pValue = le2cpu32(localVal);

	if (Status < 0)
		*pValue = 0xffffffff;

	return Status;
}

/*
	========================================================================

	Routine Description: Write 32-bit MAC register

	Arguments:

	Return Value:

	IRQL =

	Note:

	========================================================================
*/
int RTUSBWriteMACRegister(struct rt_rtmp_adapter *pAd,
			       u16 Offset, u32 Value)
{
	int Status;
	u32 localVal;

	localVal = Value;

	Status = RTUSBSingleWrite(pAd, Offset, (u16)(localVal & 0xffff));
	Status =
	    RTUSBSingleWrite(pAd, Offset + 2,
			     (u16)((localVal & 0xffff0000) >> 16));

	return Status;
}

/*
	========================================================================

	Routine Description: Read 8-bit BBP register

	Arguments:

	Return Value:

	IRQL =

	Note:

	========================================================================
*/
int RTUSBReadBBPRegister(struct rt_rtmp_adapter *pAd,
			      u8 Id, u8 *pValue)
{
	BBP_CSR_CFG_STRUC BbpCsr;
	u32 i = 0;
	int status;

	/* Verify the busy condition */
	do {
		status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
		if (status >= 0) {
			if (!(BbpCsr.field.Busy == BUSY))
				break;
		}
		DBGPRINT(RT_DEBUG_TRACE,
			 ("RTUSBReadBBPRegister(BBP_CSR_CFG_1):retry count=%d!\n",
			  i));
		i++;
	} while ((i < RETRY_LIMIT)
		 && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));

	if ((i == RETRY_LIMIT)
	    || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) {
		/* */
		/* Read failed then Return Default value. */
		/* */
		*pValue = pAd->BbpWriteLatch[Id];

		DBGPRINT_RAW(RT_DEBUG_ERROR,
			     ("Retry count exhausted or device removed!!!\n"));
		return STATUS_UNSUCCESSFUL;
	}
	/* Prepare for write material */
	BbpCsr.word = 0;
	BbpCsr.field.fRead = 1;
	BbpCsr.field.Busy = 1;
	BbpCsr.field.RegNum = Id;
	RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word);

	i = 0;
	/* Verify the busy condition */
	do {
		status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
		if (status >= 0) {
			if (!(BbpCsr.field.Busy == BUSY)) {
				*pValue = (u8)BbpCsr.field.Value;
				break;
			}
		}
		DBGPRINT(RT_DEBUG_TRACE,
			 ("RTUSBReadBBPRegister(BBP_CSR_CFG_2):retry count=%d!\n",
			  i));
		i++;
	} while ((i < RETRY_LIMIT)
		 && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));

	if ((i == RETRY_LIMIT)
	    || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) {
		/* */
		/* Read failed then Return Default value. */
		/* */
		*pValue = pAd->BbpWriteLatch[Id];

		DBGPRINT_RAW(RT_DEBUG_ERROR,
			     ("Retry count exhausted or device removed!!!\n"));
		return STATUS_UNSUCCESSFUL;
	}

	return STATUS_SUCCESS;
}

/*
	========================================================================

	Routine Description: Write 8-bit BBP register

	Arguments:

	Return Value:

	IRQL =

	Note:

	========================================================================
*/
int RTUSBWriteBBPRegister(struct rt_rtmp_adapter *pAd,
			       u8 Id, u8 Value)
{
	BBP_CSR_CFG_STRUC BbpCsr;
	u32 i = 0;
	int status;
	/* Verify the busy condition */
	do {
		status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
		if (status >= 0) {
			if (!(BbpCsr.field.Busy == BUSY))
				break;
		}
		DBGPRINT(RT_DEBUG_TRACE,
			 ("RTUSBWriteBBPRegister(BBP_CSR_CFG):retry count=%d!\n",
			  i));
		i++;
	} while ((i < RETRY_LIMIT)
	       && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));

	if ((i == RETRY_LIMIT)
	    || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) {
		DBGPRINT_RAW(RT_DEBUG_ERROR,
			     ("Retry count exhausted or device removed!!!\n"));
		return STATUS_UNSUCCESSFUL;
	}
	/* Prepare for write material */
	BbpCsr.word = 0;
	BbpCsr.field.fRead = 0;
	BbpCsr.field.Value = Value;
	BbpCsr.field.Busy = 1;
	BbpCsr.field.RegNum = Id;
	RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word);

	pAd->BbpWriteLatch[Id] = Value;

	return STATUS_SUCCESS;
}

/*
	========================================================================

	Routine Description: Write RF register through MAC

	Arguments:

	Return Value:

	IRQL =

	Note:

	========================================================================
*/
int RTUSBWriteRFRegister(struct rt_rtmp_adapter *pAd, u32 Value)
{
	PHY_CSR4_STRUC PhyCsr4;
	u32 i = 0;
	int status;

	NdisZeroMemory(&PhyCsr4, sizeof(PHY_CSR4_STRUC));
	do {
		status = RTUSBReadMACRegister(pAd, RF_CSR_CFG0, &PhyCsr4.word);
		if (status >= 0) {
			if (!(PhyCsr4.field.Busy))
				break;
		}
		DBGPRINT(RT_DEBUG_TRACE,
			 ("RTUSBWriteRFRegister(RF_CSR_CFG0):retry count=%d!\n",
			  i));
		i++;
	} while ((i < RETRY_LIMIT)
	       && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));

	if ((i == RETRY_LIMIT)
	    || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) {
		DBGPRINT_RAW(RT_DEBUG_ERROR,
			     ("Retry count exhausted or device removed!!!\n"));
		return STATUS_UNSUCCESSFUL;
	}

	RTUSBWriteMACRegister(pAd, RF_CSR_CFG0, Value);

	return STATUS_SUCCESS;
}

/*
	========================================================================

	Routine Description:

	Arguments:

	Return Value:

	IRQL =

	Note:

	========================================================================
*/
int RTUSBReadEEPROM(struct rt_rtmp_adapter *pAd,
			 u16 Offset, u8 *pData, u16 length)
{
	int Status = STATUS_SUCCESS;

	Status = RTUSB_VendorRequest(pAd,
				     (USBD_TRANSFER_DIRECTION_IN |
				      USBD_SHORT_TRANSFER_OK),
				     DEVICE_VENDOR_REQUEST_IN, 0x9, 0, Offset,
				     pData, length);

	return Status;
}

/*
	========================================================================

	Routine Description:

	Arguments:

	Return Value:

	IRQL =

	Note:

	========================================================================
*/
int RTUSBWriteEEPROM(struct rt_rtmp_adapter *pAd,
			  u16 Offset, u8 *pData, u16 length)
{
	int Status = STATUS_SUCCESS;

	Status = RTUSB_VendorRequest(pAd,
				     USBD_TRANSFER_DIRECTION_OUT,
				     DEVICE_VENDOR_REQUEST_OUT,
				     0x8, 0, Offset, pData, length);

	return Status;
}

int RTUSBReadEEPROM16(struct rt_rtmp_adapter *pAd,
			   u16 offset, u16 *pData)
{
	int status;
	u16 localData;

	status = RTUSBReadEEPROM(pAd, offset, (u8 *)(&localData), 2);
	if (status == STATUS_SUCCESS)
		*pData = le2cpu16(localData);

	return status;

}

/*
	========================================================================

	Routine Description:

	Arguments:

	Return Value:

	IRQL =

	Note:

	========================================================================
*/
void RTUSBPutToSleep(struct rt_rtmp_adapter *pAd)
{
	u32 value;

	/* Timeout 0x40 x 50us */
	value = (SLEEPCID << 16) + (OWNERMCU << 24) + (0x40 << 8) + 1;
	RTUSBWriteMACRegister(pAd, 0x7010, value);
	RTUSBWriteMACRegister(pAd, 0x404, 0x30);
	/*RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); */
	DBGPRINT_RAW(RT_DEBUG_ERROR, ("Sleep Mailbox testvalue %x\n", value));

}

/*
	========================================================================

	Routine Description:

	Arguments:

	Return Value:

	IRQL =

	Note:

	========================================================================
*/
int RTUSBWakeUp(struct rt_rtmp_adapter *pAd)
{
	int Status;

	Status = RTUSB_VendorRequest(pAd,
				     USBD_TRANSFER_DIRECTION_OUT,
				     DEVICE_VENDOR_REQUEST_OUT,
				     0x01, 0x09, 0, NULL, 0);

	return Status;
}

/*
	========================================================================

	Routine Description:

	Arguments:

	Return Value:

	IRQL =

	Note:

	========================================================================
*/
void RTUSBInitializeCmdQ(struct rt_cmdq *cmdq)
{
	cmdq->head = NULL;
	cmdq->tail = NULL;
	cmdq->size = 0;
	cmdq->CmdQState = RTMP_TASK_STAT_INITED;
}

/*
	========================================================================

	Routine Description:

	Arguments:

	Return Value:

	IRQL =

	Note:

	========================================================================
*/
int RTUSBEnqueueCmdFromNdis(struct rt_rtmp_adapter *pAd,
				    IN NDIS_OID Oid,
				    IN BOOLEAN SetInformation,
				    void *pInformationBuffer,
				    u32 InformationBufferLength)
{
	int status;
	struct rt_cmdqelmt *cmdqelmt = NULL;
	struct rt_rtmp_os_task *pTask = &pAd->cmdQTask;

#ifdef KTHREAD_SUPPORT
	if (pTask->kthread_task == NULL)
#else
	CHECK_PID_LEGALITY(pTask->taskPID) {
	}
	else
#endif
	return NDIS_STATUS_RESOURCES;

	status = os_alloc_mem(pAd, (u8 **) (&cmdqelmt), sizeof(struct rt_cmdqelmt));
	if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL))
		return NDIS_STATUS_RESOURCES;

	cmdqelmt->buffer = NULL;
	if (pInformationBuffer != NULL) {
		status =
		    os_alloc_mem(pAd, (u8 **) & cmdqelmt->buffer,
				 InformationBufferLength);
		if ((status != NDIS_STATUS_SUCCESS)
		    || (cmdqelmt->buffer == NULL)) {
			kfree(cmdqelmt);
			return NDIS_STATUS_RESOURCES;
		} else {
			NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer,
				       InformationBufferLength);
			cmdqelmt->bufferlength = InformationBufferLength;
		}
	} else
		cmdqelmt->bufferlength = 0;

	cmdqelmt->command = Oid;
	cmdqelmt->CmdFromNdis = TRUE;
	if (SetInformation == TRUE)
		cmdqelmt->SetOperation = TRUE;
	else
		cmdqelmt->SetOperation = FALSE;

	NdisAcquireSpinLock(&pAd->CmdQLock);
	if (pAd->CmdQ.CmdQState & RTMP_TASK_CAN_DO_INSERT) {
		EnqueueCmd((&pAd->CmdQ), cmdqelmt);
		status = NDIS_STATUS_SUCCESS;
	} else {
		status = NDIS_STATUS_FAILURE;
	}
	NdisReleaseSpinLock(&pAd->CmdQLock);

	if (status == NDIS_STATUS_FAILURE) {
		if (cmdqelmt->buffer)
			os_free_mem(pAd, cmdqelmt->buffer);
		os_free_mem(pAd, cmdqelmt);
	} else
		RTUSBCMDUp(pAd);

	return NDIS_STATUS_SUCCESS;
}

/*
	========================================================================

	Routine Description:

	Arguments:

	Return Value:

	IRQL =

	Note:

	========================================================================
*/
int RTUSBEnqueueInternalCmd(struct rt_rtmp_adapter *pAd,
				    IN NDIS_OID Oid,
				    void *pInformationBuffer,
				    u32 InformationBufferLength)
{
	int status;
	struct rt_cmdqelmt *cmdqelmt = NULL;

	status = os_alloc_mem(pAd, (u8 **) & cmdqelmt, sizeof(struct rt_cmdqelmt));
	if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL))
		return NDIS_STATUS_RESOURCES;
	NdisZeroMemory(cmdqelmt, sizeof(struct rt_cmdqelmt));

	if (InformationBufferLength > 0) {
		status =
		    os_alloc_mem(pAd, (u8 **) & cmdqelmt->buffer,
				 InformationBufferLength);
		if ((status != NDIS_STATUS_SUCCESS)
		    || (cmdqelmt->buffer == NULL)) {
			os_free_mem(pAd, cmdqelmt);
			return NDIS_STATUS_RESOURCES;
		} else {
			NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer,
				       InformationBufferLength);
			cmdqelmt->bufferlength = InformationBufferLength;
		}
	} else {
		cmdqelmt->buffer = NULL;
		cmdqelmt->bufferlength = 0;
	}

	cmdqelmt->command = Oid;
	cmdqelmt->CmdFromNdis = FALSE;

	if (cmdqelmt != NULL) {
		NdisAcquireSpinLock(&pAd->CmdQLock);
		if (pAd->CmdQ.CmdQState & RTMP_TASK_CAN_DO_INSERT) {
			EnqueueCmd((&pAd->CmdQ), cmdqelmt);
			status = NDIS_STATUS_SUCCESS;
		} else {
			status = NDIS_STATUS_FAILURE;
		}
		NdisReleaseSpinLock(&pAd->CmdQLock);

		if (status == NDIS_STATUS_FAILURE) {
			if (cmdqelmt->buffer)
				os_free_mem(pAd, cmdqelmt->buffer);
			os_free_mem(pAd, cmdqelmt);
		} else
			RTUSBCMDUp(pAd);
	}
	return NDIS_STATUS_SUCCESS;
}

/*
	========================================================================

	Routine Description:

	Arguments:

	Return Value:

	IRQL =

	Note:

	========================================================================
*/
void RTUSBDequeueCmd(struct rt_cmdq *cmdq, struct rt_cmdqelmt * * pcmdqelmt)
{
	*pcmdqelmt = cmdq->head;

	if (*pcmdqelmt != NULL) {
		cmdq->head = cmdq->head->next;
		cmdq->size--;
		if (cmdq->size == 0)
			cmdq->tail = NULL;
	}
}

/*
    ========================================================================
	  usb_control_msg - Builds a control urb, sends it off and waits for completion
	  @dev: pointer to the usb device to send the message to
	  @pipe: endpoint "pipe" to send the message to
	  @request: USB message request value
	  @requesttype: USB message request type value
	  @value: USB message value
	  @index: USB message index value
	  @data: pointer to the data to send
	  @size: length in bytes of the data to send
	  @timeout: time in jiffies to wait for the message to complete before
			  timing out (if 0 the wait is forever)
	  Context: !in_interrupt ()

	  This function sends a simple control message to a specified endpoint
	  and waits for the message to complete, or timeout.
	  If successful, it returns the number of bytes transferred, otherwise a negative error number.

	 Don't use this function from within an interrupt context, like a
	  bottom half handler.	If you need an asynchronous message, or need to send
	  a message from within interrupt context, use usb_submit_urb()
	  If a thread in your driver uses this call, make sure your disconnect()
	  method can wait for it to complete.  Since you don't have a handle on
	  the URB used, you can't cancel the request.

	Routine Description:

	Arguments:

	Return Value:

	Note:

	========================================================================
*/
int RTUSB_VendorRequest(struct rt_rtmp_adapter *pAd,
			     u32 TransferFlags,
			     u8 RequestType,
			     u8 Request,
			     u16 Value,
			     u16 Index,
			     void *TransferBuffer,
			     u32 TransferBufferLength)
{
	int ret = 0;
	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;

	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) {
		DBGPRINT(RT_DEBUG_ERROR, ("device disconnected\n"));
		return -1;
	} else if (in_interrupt()) {
		DBGPRINT(RT_DEBUG_ERROR,
			 ("in_interrupt, RTUSB_VendorRequest Request%02x Value%04x Offset%04x\n",
			  Request, Value, Index));

		return -1;
	} else {
#define MAX_RETRY_COUNT  10

		int retryCount = 0;
		void *tmpBuf = TransferBuffer;

		ret = down_interruptible(&(pAd->UsbVendorReq_semaphore));
		if (pAd->UsbVendorReqBuf) {
			ASSERT(TransferBufferLength < MAX_PARAM_BUFFER_SIZE);

			tmpBuf = (void *)pAd->UsbVendorReqBuf;
			NdisZeroMemory(pAd->UsbVendorReqBuf,
				       TransferBufferLength);

			if (RequestType == DEVICE_VENDOR_REQUEST_OUT)
				NdisMoveMemory(tmpBuf, TransferBuffer,
					       TransferBufferLength);
		}

		do {
			if (RequestType == DEVICE_VENDOR_REQUEST_OUT)
				ret =
				    usb_control_msg(pObj->pUsb_Dev,
						    usb_sndctrlpipe(pObj->
								    pUsb_Dev,
								    0), Request,
						    RequestType, Value, Index,
						    tmpBuf,
						    TransferBufferLength,
						    CONTROL_TIMEOUT_JIFFIES);
			else if (RequestType == DEVICE_VENDOR_REQUEST_IN)
				ret =
				    usb_control_msg(pObj->pUsb_Dev,
						    usb_rcvctrlpipe(pObj->
								    pUsb_Dev,
								    0), Request,
						    RequestType, Value, Index,
						    tmpBuf,
						    TransferBufferLength,
						    CONTROL_TIMEOUT_JIFFIES);
			else {
				DBGPRINT(RT_DEBUG_ERROR,
					 ("vendor request direction is failed\n"));
				ret = -1;
			}

			retryCount++;
			if (ret < 0) {
				DBGPRINT(RT_DEBUG_OFF, ("#\n"));
				RTMPusecDelay(5000);
			}
		} while ((ret < 0) && (retryCount < MAX_RETRY_COUNT));

		if ((pAd->UsbVendorReqBuf)
		    && (RequestType == DEVICE_VENDOR_REQUEST_IN))
			NdisMoveMemory(TransferBuffer, tmpBuf,
				       TransferBufferLength);
		up(&(pAd->UsbVendorReq_semaphore));

		if (ret < 0) {
			DBGPRINT(RT_DEBUG_ERROR,
				 ("RTUSB_VendorRequest failed(%d),TxFlags=0x%x, ReqType=%s, Req=0x%x, Index=0x%x\n",
				  ret, TransferFlags,
				  (RequestType ==
				   DEVICE_VENDOR_REQUEST_OUT ? "OUT" : "IN"),
				  Request, Index));
			if (Request == 0x2)
				DBGPRINT(RT_DEBUG_ERROR,
					 ("\tRequest Value=0x%04x!\n", Value));

			if ((TransferBuffer != NULL)
			    && (TransferBufferLength > 0))
				hex_dump("Failed TransferBuffer value",
					 TransferBuffer, TransferBufferLength);
		}

	}

	if (ret != -1)
		return STATUS_SUCCESS;
	else
		return STATUS_UNSUCCESSFUL;
}

/*
	========================================================================

	Routine Description:
	  Creates an IRP to submite an IOCTL_INTERNAL_USB_RESET_PORT
	  synchronously. Callers of this function must be running at
	  PASSIVE LEVEL.

	Arguments:

	Return Value:

	Note:

	========================================================================
*/
int RTUSB_ResetDevice(struct rt_rtmp_adapter *pAd)
{
	int Status = TRUE;

	DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->USB_ResetDevice\n"));
	/*RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS); */
	return Status;
}

void CMDHandler(struct rt_rtmp_adapter *pAd)
{
	struct rt_cmdqelmt *cmdqelmt;
	u8 *pData;
	int NdisStatus = NDIS_STATUS_SUCCESS;
/*      unsigned long                   Now = 0; */
	int ntStatus;
/*      unsigned long   IrqFlags; */

	while (pAd && pAd->CmdQ.size > 0) {
		NdisStatus = NDIS_STATUS_SUCCESS;

		NdisAcquireSpinLock(&pAd->CmdQLock);
		RTUSBDequeueCmd(&pAd->CmdQ, &cmdqelmt);
		NdisReleaseSpinLock(&pAd->CmdQLock);

		if (cmdqelmt == NULL)
			break;

		pData = cmdqelmt->buffer;

		if (!
		    (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)
		     || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) {
			switch (cmdqelmt->command) {
			case CMDTHREAD_CHECK_GPIO:
				{
					u32 data;

					{
						/* Read GPIO pin2 as Hardware controlled radio state */

						RTUSBReadMACRegister(pAd,
								     GPIO_CTRL_CFG,
								     &data);

						if (data & 0x04) {
							pAd->StaCfg.bHwRadio =
							    TRUE;
						} else {
							pAd->StaCfg.bHwRadio =
							    FALSE;
						}

						if (pAd->StaCfg.bRadio !=
						    (pAd->StaCfg.bHwRadio
						     && pAd->StaCfg.bSwRadio)) {
							pAd->StaCfg.bRadio =
							    (pAd->StaCfg.
							     bHwRadio
							     && pAd->StaCfg.
							     bSwRadio);
							if (pAd->StaCfg.
							    bRadio == TRUE) {
								DBGPRINT_RAW
								    (RT_DEBUG_ERROR,
								     ("!!! Radio On !!!\n"));

								MlmeRadioOn
								    (pAd);
								/* Update extra information */
								pAd->ExtraInfo =
								    EXTRA_INFO_CLEAR;
							} else {
								DBGPRINT_RAW
								    (RT_DEBUG_ERROR,
								     ("!!! Radio Off !!!\n"));

								MlmeRadioOff
								    (pAd);
								/* Update extra information */
								pAd->ExtraInfo =
								    HW_RADIO_OFF;
							}
						}
					}
				}
				break;

			case CMDTHREAD_QKERIODIC_EXECUT:
				{
					StaQuickResponeForRateUpExec(NULL, pAd,
								     NULL,
								     NULL);
				}
				break;

			case CMDTHREAD_RESET_BULK_OUT:
				{
					u32 MACValue;
					u8 Index;
					int ret = 0;
					struct rt_ht_tx_context *pHTTXContext;
/*                                              struct rt_rtmp_tx_ring *pTxRing; */
					unsigned long IrqFlags;

					DBGPRINT_RAW(RT_DEBUG_TRACE,
						     ("CmdThread : CMDTHREAD_RESET_BULK_OUT(ResetPipeid=0x%0x)===>\n",
						      pAd->bulkResetPipeid));
					/* All transfers must be aborted or cancelled before attempting to reset the pipe. */
					/*RTUSBCancelPendingBulkOutIRP(pAd); */
					/* Wait 10ms to let previous packet that are already in HW FIFO to clear. by MAXLEE 12-25-2007 */
					Index = 0;
					do {
						RTUSBReadMACRegister(pAd,
								     TXRXQ_PCNT,
								     &MACValue);
						if ((MACValue & 0xf00000
						     /*0x800000 */) == 0)
							break;
						Index++;
						RTMPusecDelay(10000);
					} while (Index < 100);
					MACValue = 0;
					RTUSBReadMACRegister(pAd, USB_DMA_CFG,
							     &MACValue);
					/* To prevent Read Register error, we 2nd check the validity. */
					if ((MACValue & 0xc00000) == 0)
						RTUSBReadMACRegister(pAd,
								     USB_DMA_CFG,
								     &MACValue);
					/* To prevent Read Register error, we 3rd check the validity. */
					if ((MACValue & 0xc00000) == 0)
						RTUSBReadMACRegister(pAd,
								     USB_DMA_CFG,
								     &MACValue);
					MACValue |= 0x80000;
					RTUSBWriteMACRegister(pAd, USB_DMA_CFG,
							      MACValue);

					/* Wait 1ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007 */
					RTMPusecDelay(1000);

					MACValue &= (~0x80000);
					RTUSBWriteMACRegister(pAd, USB_DMA_CFG,
							      MACValue);
					DBGPRINT_RAW(RT_DEBUG_TRACE,
						     ("\tSet 0x2a0 bit19. Clear USB DMA TX path\n"));

					/* Wait 5ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007 */
					/*RTMPusecDelay(5000); */

					if ((pAd->
					     bulkResetPipeid &
					     BULKOUT_MGMT_RESET_FLAG) ==
					    BULKOUT_MGMT_RESET_FLAG) {
						RTMP_CLEAR_FLAG(pAd,
								fRTMP_ADAPTER_BULKOUT_RESET);
						if (pAd->MgmtRing.TxSwFreeIdx <
						    MGMT_RING_SIZE
						    /* pMLMEContext->bWaitingBulkOut == TRUE */
						    ) {
							RTUSB_SET_BULK_FLAG(pAd,
									    fRTUSB_BULK_OUT_MLME);
						}
						RTUSBKickBulkOut(pAd);

						DBGPRINT_RAW(RT_DEBUG_TRACE,
							     ("\tTX MGMT RECOVER Done!\n"));
					} else {
						pHTTXContext =
						    &(pAd->
						      TxContext[pAd->
								bulkResetPipeid]);
						/*NdisAcquireSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]); */
						RTMP_INT_LOCK(&pAd->
							      BulkOutLock[pAd->
									  bulkResetPipeid],
							      IrqFlags);
						if (pAd->
						    BulkOutPending[pAd->
								   bulkResetPipeid]
						    == FALSE) {
							pAd->
							    BulkOutPending[pAd->
									   bulkResetPipeid]
							    = TRUE;
							pHTTXContext->
							    IRPPending = TRUE;
							pAd->
							    watchDogTxPendingCnt
							    [pAd->
							     bulkResetPipeid] =
							    1;

							/* no matter what, clean the flag */
							RTMP_CLEAR_FLAG(pAd,
									fRTMP_ADAPTER_BULKOUT_RESET);

							/*NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]); */
							RTMP_INT_UNLOCK(&pAd->
									BulkOutLock
									[pAd->
									 bulkResetPipeid],
									IrqFlags);
							{
								RTUSBInitHTTxDesc
								    (pAd,
								     pHTTXContext,
								     pAd->
								     bulkResetPipeid,
								     pHTTXContext->
								     BulkOutSize,
								     (usb_complete_t)
								     RTUSBBulkOutDataPacketComplete);

								ret = RTUSB_SUBMIT_URB
								     (pHTTXContext->
								      pUrb);
								if (ret != 0) {
									RTMP_INT_LOCK
									    (&pAd->
									     BulkOutLock
									     [pAd->
									      bulkResetPipeid],
									     IrqFlags);
									pAd->
									    BulkOutPending
									    [pAd->
									     bulkResetPipeid]
									    =
									    FALSE;
									pHTTXContext->
									    IRPPending
									    =
									    FALSE;
									pAd->
									    watchDogTxPendingCnt
									    [pAd->
									     bulkResetPipeid]
									    = 0;
									RTMP_INT_UNLOCK
									    (&pAd->
									     BulkOutLock
									     [pAd->
									      bulkResetPipeid],
									     IrqFlags);

									DBGPRINT
									    (RT_DEBUG_ERROR,
									     ("CmdThread : CMDTHREAD_RESET_BULK_OUT: Submit Tx URB failed %d\n",
									      ret));
								} else {
									RTMP_IRQ_LOCK
									    (&pAd->
									     BulkOutLock
									     [pAd->
									      bulkResetPipeid],
									     IrqFlags);
									DBGPRINT_RAW
									    (RT_DEBUG_TRACE,
									     ("\tCMDTHREAD_RESET_BULK_OUT: TxContext[%d]:CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, pending=%d!\n",
									      pAd->
									      bulkResetPipeid,
									      pHTTXContext->
									      CurWritePosition,
									      pHTTXContext->
									      NextBulkOutPosition,
									      pHTTXContext->
									      ENextBulkOutPosition,
									      pHTTXContext->
									      bCopySavePad,
									      pAd->
									      BulkOutPending
									      [pAd->
									       bulkResetPipeid]));
									DBGPRINT_RAW
									    (RT_DEBUG_TRACE,
									     ("\t\tBulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n",
									      pAd->
									      BulkOutReq,
									      pAd->
									      BulkOutComplete,
									      pAd->
									      BulkOutCompleteOther));
									RTMP_IRQ_UNLOCK
									    (&pAd->
									     BulkOutLock
									     [pAd->
									      bulkResetPipeid],
									     IrqFlags);
									DBGPRINT_RAW
									    (RT_DEBUG_TRACE,
									     ("\tCMDTHREAD_RESET_BULK_OUT: Submit Tx DATA URB for failed BulkReq(0x%lx) Done, status=%d!\n",
									      pAd->
									      bulkResetReq
									      [pAd->
									       bulkResetPipeid],
									      pHTTXContext->
									      pUrb->
									      status));

								}
							}
						} else {
							/*NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]); */
							/*RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); */

							DBGPRINT_RAW
							    (RT_DEBUG_ERROR,
							     ("CmdThread : TX DATA RECOVER FAIL for BulkReq(0x%lx) because BulkOutPending[%d] is TRUE!\n",
							      pAd->
							      bulkResetReq[pAd->
									   bulkResetPipeid],
							      pAd->
							      bulkResetPipeid));
							if (pAd->
							    bulkResetPipeid ==
							    0) {
								u8
								    pendingContext
								    = 0;
								struct rt_ht_tx_context *
								    pHTTXContext
								    =
								    (struct rt_ht_tx_context *)
								    (&pAd->
								     TxContext
								     [pAd->
								      bulkResetPipeid]);
								struct rt_tx_context *
								    pMLMEContext
								    =
								    (struct rt_tx_context *)
								    (pAd->
								     MgmtRing.
								     Cell[pAd->
									  MgmtRing.
									  TxDmaIdx].
								     AllocVa);
								struct rt_tx_context *
								    pNULLContext
								    =
								    (struct rt_tx_context *)
								    (&pAd->
								     PsPollContext);
								struct rt_tx_context *
								    pPsPollContext
								    =
								    (struct rt_tx_context *)
								    (&pAd->
								     NullContext);

								if (pHTTXContext->IRPPending)
									pendingContext
									    |=
									    1;
								else if
								    (pMLMEContext->
								     IRPPending)
									pendingContext
									    |=
									    2;
								else if
								    (pNULLContext->
								     IRPPending)
									pendingContext
									    |=
									    4;
								else if
								    (pPsPollContext->
								     IRPPending)
									pendingContext
									    |=
									    8;
								else
									pendingContext
									    = 0;

								DBGPRINT_RAW
								    (RT_DEBUG_ERROR,
								     ("\tTX Occupied by %d!\n",
								      pendingContext));
							}
							/* no matter what, clean the flag */
							RTMP_CLEAR_FLAG(pAd,
									fRTMP_ADAPTER_BULKOUT_RESET);

							RTMP_INT_UNLOCK(&pAd->
									BulkOutLock
									[pAd->
									 bulkResetPipeid],
									IrqFlags);

							RTUSB_SET_BULK_FLAG(pAd,
									    (fRTUSB_BULK_OUT_DATA_NORMAL
									     <<
									     pAd->
									     bulkResetPipeid));
						}

						RTMPDeQueuePacket(pAd, FALSE,
								  NUM_OF_TX_RING,
								  MAX_TX_PROCESS);
						/*RTUSBKickBulkOut(pAd); */
					}

				}
				/*
				   // Don't cancel BULKIN.
				   while ((atomic_read(&pAd->PendingRx) > 0) &&
				   (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
				   {
				   if (atomic_read(&pAd->PendingRx) > 0)
				   {
				   DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!cancel it!\n"));
				   RTUSBCancelPendingBulkInIRP(pAd);
				   }
				   RTMPusecDelay(100000);
				   }

				   if ((atomic_read(&pAd->PendingRx) == 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
				   {
				   u8        i;
				   RTUSBRxPacket(pAd);
				   pAd->NextRxBulkInReadIndex = 0;      // Next Rx Read index
				   pAd->NextRxBulkInIndex               = 0;    // Rx Bulk pointer
				   for (i = 0; i < (RX_RING_SIZE); i++)
				   {
				   struct rt_rx_context *pRxContext = &(pAd->RxContext[i]);

				   pRxContext->pAd      = pAd;
				   pRxContext->InUse            = FALSE;
				   pRxContext->IRPPending       = FALSE;
				   pRxContext->Readable = FALSE;
				   pRxContext->ReorderInUse = FALSE;

				   }
				   RTUSBBulkReceive(pAd);
				   DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTUSBBulkReceive\n"));
				   } */
				DBGPRINT_RAW(RT_DEBUG_TRACE,
					     ("CmdThread : CMDTHREAD_RESET_BULK_OUT<===\n"));
				break;

			case CMDTHREAD_RESET_BULK_IN:
				DBGPRINT_RAW(RT_DEBUG_TRACE,
					     ("CmdThread : CMDTHREAD_RESET_BULK_IN === >\n"));

				/* All transfers must be aborted or cancelled before attempting to reset the pipe. */
				{
					u32 MACValue;
					{
						/*while ((atomic_read(&pAd->PendingRx) > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) */
						if ((pAd->PendingRx > 0)
						    &&
						    (!RTMP_TEST_FLAG
						     (pAd,
						      fRTMP_ADAPTER_NIC_NOT_EXIST))) {
							DBGPRINT_RAW
							    (RT_DEBUG_ERROR,
							     ("BulkIn IRP Pending!!!\n"));
							RTUSBCancelPendingBulkInIRP
							    (pAd);
							RTMPusecDelay(100000);
							pAd->PendingRx = 0;
						}
					}
					/* Wait 10ms before reading register. */
					RTMPusecDelay(10000);
					ntStatus =
					    RTUSBReadMACRegister(pAd, MAC_CSR0,
								 &MACValue);

					if ((NT_SUCCESS(ntStatus) == TRUE) &&
					    (!(RTMP_TEST_FLAG
					       (pAd,
						(fRTMP_ADAPTER_RESET_IN_PROGRESS
						 | fRTMP_ADAPTER_RADIO_OFF |
						 fRTMP_ADAPTER_HALT_IN_PROGRESS
						 |
						 fRTMP_ADAPTER_NIC_NOT_EXIST)))))
					{
						u8 i;

						if (RTMP_TEST_FLAG
						    (pAd,
						     (fRTMP_ADAPTER_RESET_IN_PROGRESS
						      | fRTMP_ADAPTER_RADIO_OFF
						      |
						      fRTMP_ADAPTER_HALT_IN_PROGRESS
						      |
						      fRTMP_ADAPTER_NIC_NOT_EXIST)))
							break;
						pAd->NextRxBulkInPosition =
						    pAd->RxContext[pAd->
								   NextRxBulkInIndex].
						    BulkInOffset;
						DBGPRINT(RT_DEBUG_TRACE,
							 ("BULK_IN_RESET: NBIIdx=0x%x,NBIRIdx=0x%x, BIRPos=0x%lx. BIReq=x%lx, BIComplete=0x%lx, BICFail0x%lx\n",
							  pAd->
							  NextRxBulkInIndex,
							  pAd->
							  NextRxBulkInReadIndex,
							  pAd->
							  NextRxBulkInPosition,
							  pAd->BulkInReq,
							  pAd->BulkInComplete,
							  pAd->
							  BulkInCompleteFail));
						for (i = 0; i < RX_RING_SIZE;
						     i++) {
							DBGPRINT(RT_DEBUG_TRACE,
								 ("\tRxContext[%d]: IRPPending=%d, InUse=%d, Readable=%d!\n",
								  i,
								  pAd->
								  RxContext[i].
								  IRPPending,
								  pAd->
								  RxContext[i].
								  InUse,
								  pAd->
								  RxContext[i].
								  Readable));
						}
						/*

						   DBGPRINT_RAW(RT_DEBUG_ERROR, ("==========================================\n"));

						   pAd->NextRxBulkInReadIndex = 0;      // Next Rx Read index
						   pAd->NextRxBulkInIndex               = 0;    // Rx Bulk pointer
						   for (i = 0; i < (RX_RING_SIZE); i++)
						   {
						   struct rt_rx_context *pRxContext = &(pAd->RxContext[i]);

						   pRxContext->pAd      = pAd;
						   pRxContext->InUse            = FALSE;
						   pRxContext->IRPPending       = FALSE;
						   pRxContext->Readable = FALSE;
						   pRxContext->ReorderInUse = FALSE;

						   } */
						RTMP_CLEAR_FLAG(pAd,
								fRTMP_ADAPTER_BULKIN_RESET);
						for (i = 0;
						     i <
						     pAd->CommonCfg.
						     NumOfBulkInIRP; i++) {
							/*RTUSBBulkReceive(pAd); */
							struct rt_rx_context *pRxContext;
							PURB pUrb;
							int ret = 0;
							unsigned long IrqFlags;

							RTMP_IRQ_LOCK(&pAd->
								      BulkInLock,
								      IrqFlags);
							pRxContext =
							    &(pAd->
							      RxContext[pAd->
									NextRxBulkInIndex]);
							if ((pAd->PendingRx > 0)
							    || (pRxContext->
								Readable ==
								TRUE)
							    || (pRxContext->
								InUse ==
								TRUE)) {
								RTMP_IRQ_UNLOCK
								    (&pAd->
								     BulkInLock,
								     IrqFlags);
								break;
							}
							pRxContext->InUse =
							    TRUE;
							pRxContext->IRPPending =
							    TRUE;
							pAd->PendingRx++;
							pAd->BulkInReq++;
							RTMP_IRQ_UNLOCK(&pAd->
									BulkInLock,
									IrqFlags);

							/* Init Rx context descriptor */
							RTUSBInitRxDesc(pAd,
									pRxContext);
							pUrb = pRxContext->pUrb;
							ret = RTUSB_SUBMIT_URB(pUrb);
							if (ret != 0) {	/* fail */

								RTMP_IRQ_LOCK
								    (&pAd->
								     BulkInLock,
								     IrqFlags);
								pRxContext->
								    InUse =
								    FALSE;
								pRxContext->
								    IRPPending =
								    FALSE;
								pAd->
								    PendingRx--;
								pAd->
								    BulkInReq--;
								RTMP_IRQ_UNLOCK
								    (&pAd->
								     BulkInLock,
								     IrqFlags);
								DBGPRINT
								    (RT_DEBUG_ERROR,
								     ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB failed(%d), status=%d\n",
								      ret,
								      pUrb->
								      status));
							} else {	/* success */
								/*DBGPRINT(RT_DEBUG_TRACE, ("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", */
								/*                                                      pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex)); */
								DBGPRINT_RAW
								    (RT_DEBUG_TRACE,
								     ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB Done, status=%d!\n",
								      pUrb->
								      status));
								ASSERT((pRxContext->InUse == pRxContext->IRPPending));
							}
						}

					} else {
						/* Card must be removed */
						if (NT_SUCCESS(ntStatus) !=
						    TRUE) {
							RTMP_SET_FLAG(pAd,
								      fRTMP_ADAPTER_NIC_NOT_EXIST);
							DBGPRINT_RAW
							    (RT_DEBUG_ERROR,
							     ("CMDTHREAD_RESET_BULK_IN: Read Register Failed!Card must be removed!!\n\n"));
						} else {
							DBGPRINT_RAW
							    (RT_DEBUG_ERROR,
							     ("CMDTHREAD_RESET_BULK_IN: Cannot do bulk in because flags(0x%lx) on !\n",
							      pAd->Flags));
						}
					}
				}
				DBGPRINT_RAW(RT_DEBUG_TRACE,
					     ("CmdThread : CMDTHREAD_RESET_BULK_IN <===\n"));
				break;

			case CMDTHREAD_SET_ASIC_WCID:
				{
					struct rt_set_asic_wcid SetAsicWcid;
					u16 offset;
					u32 MACValue, MACRValue = 0;
					SetAsicWcid =
					    *((struct rt_set_asic_wcid *)(pData));

					if (SetAsicWcid.WCID >=
					    MAX_LEN_OF_MAC_TABLE)
						return;

					offset =
					    MAC_WCID_BASE +
					    ((u8)SetAsicWcid.WCID) *
					    HW_WCID_ENTRY_SIZE;

					DBGPRINT_RAW(RT_DEBUG_TRACE,
						     ("CmdThread : CMDTHREAD_SET_ASIC_WCID : WCID = %ld, SetTid  = %lx, DeleteTid = %lx.\n",
						      SetAsicWcid.WCID,
						      SetAsicWcid.SetTid,
						      SetAsicWcid.DeleteTid));
					MACValue =
					    (pAd->MacTab.
					     Content[SetAsicWcid.WCID].
					     Addr[3] << 24) +
					    (pAd->MacTab.
					     Content[SetAsicWcid.WCID].
					     Addr[2] << 16) +
					    (pAd->MacTab.
					     Content[SetAsicWcid.WCID].
					     Addr[1] << 8) +
					    (pAd->MacTab.
					     Content[SetAsicWcid.WCID].Addr[0]);
					DBGPRINT_RAW(RT_DEBUG_TRACE,
						     ("1-MACValue= %x,\n",
						      MACValue));
					RTUSBWriteMACRegister(pAd, offset,
							      MACValue);
					/* Read bitmask */
					RTUSBReadMACRegister(pAd, offset + 4,
							     &MACRValue);
					if (SetAsicWcid.DeleteTid != 0xffffffff)
						MACRValue &=
						    (~SetAsicWcid.DeleteTid);
					if (SetAsicWcid.SetTid != 0xffffffff)
						MACRValue |=
						    (SetAsicWcid.SetTid);
					MACRValue &= 0xffff0000;

					MACValue =
					    (pAd->MacTab.
					     Content[SetAsicWcid.WCID].
					     Addr[5] << 8) +
					    pAd->MacTab.Content[SetAsicWcid.
								WCID].Addr[4];
					MACValue |= MACRValue;
					RTUSBWriteMACRegister(pAd, offset + 4,
							      MACValue);

					DBGPRINT_RAW(RT_DEBUG_TRACE,
						     ("2-MACValue= %x,\n",
						      MACValue));
				}
				break;

			case CMDTHREAD_SET_ASIC_WCID_CIPHER:
				{
					struct rt_set_asic_wcid_attri SetAsicWcidAttri;
					u16 offset;
					u32 MACRValue = 0;
					SHAREDKEY_MODE_STRUC csr1;
					SetAsicWcidAttri =
					    *((struct rt_set_asic_wcid_attri *)
					      (pData));

					if (SetAsicWcidAttri.WCID >=
					    MAX_LEN_OF_MAC_TABLE)
						return;

					offset =
					    MAC_WCID_ATTRIBUTE_BASE +
					    ((u8)SetAsicWcidAttri.WCID) *
					    HW_WCID_ATTRI_SIZE;

					DBGPRINT_RAW(RT_DEBUG_TRACE,
						     ("Cmd : CMDTHREAD_SET_ASIC_WCID_CIPHER : WCID = %ld, Cipher = %lx.\n",
						      SetAsicWcidAttri.WCID,
						      SetAsicWcidAttri.Cipher));
					/* Read bitmask */
					RTUSBReadMACRegister(pAd, offset,
							     &MACRValue);
					MACRValue = 0;
					MACRValue |=
					    (((u8)SetAsicWcidAttri.
					      Cipher) << 1);

					RTUSBWriteMACRegister(pAd, offset,
							      MACRValue);
					DBGPRINT_RAW(RT_DEBUG_TRACE,
						     ("2-offset = %x , MACValue= %x,\n",
						      offset, MACRValue));

					offset =
					    PAIRWISE_IVEIV_TABLE_BASE +
					    ((u8)SetAsicWcidAttri.WCID) *
					    HW_IVEIV_ENTRY_SIZE;
					MACRValue = 0;
					if ((SetAsicWcidAttri.Cipher <=
					     CIPHER_WEP128))
						MACRValue |=
						    (pAd->StaCfg.
						     DefaultKeyId << 30);
					else
						MACRValue |= (0x20000000);
					RTUSBWriteMACRegister(pAd, offset,
							      MACRValue);
					DBGPRINT_RAW(RT_DEBUG_TRACE,
						     ("2-offset = %x , MACValue= %x,\n",
						      offset, MACRValue));

					/* */
					/* Update cipher algorithm. WSTA always use BSS0 */
					/* */
					/* for adhoc mode only ,because wep status slow than add key, when use zero config */
					if (pAd->StaCfg.BssType == BSS_ADHOC) {
						offset =
						    MAC_WCID_ATTRIBUTE_BASE;

						RTUSBReadMACRegister(pAd,
								     offset,
								     &MACRValue);
						MACRValue &= (~0xe);
						MACRValue |=
						    (((u8)SetAsicWcidAttri.
						      Cipher) << 1);

						RTUSBWriteMACRegister(pAd,
								      offset,
								      MACRValue);

						/*Update group key cipher,,because wep status slow than add key, when use zero config */
						RTUSBReadMACRegister(pAd,
								     SHARED_KEY_MODE_BASE
								     +
								     4 * (0 /
									  2),
								     &csr1.
								     word);

						csr1.field.Bss0Key0CipherAlg =
						    SetAsicWcidAttri.Cipher;
						csr1.field.Bss0Key1CipherAlg =
						    SetAsicWcidAttri.Cipher;

						RTUSBWriteMACRegister(pAd,
								      SHARED_KEY_MODE_BASE
								      +
								      4 * (0 /
									   2),
								      csr1.
								      word);
					}
				}
				break;

/*Benson modified for USB interface, avoid in interrupt when write key, 20080724 --> */
			case RT_CMD_SET_KEY_TABLE:	/*General call for AsicAddPairwiseKeyEntry() */
				{
					struct rt_add_pairwise_key_entry KeyInfo;
					KeyInfo =
					    *((struct rt_add_pairwise_key_entry *)
					      (pData));
					AsicAddPairwiseKeyEntry(pAd,
								KeyInfo.MacAddr,
								(u8)KeyInfo.
								MacTabMatchWCID,
								&KeyInfo.
								CipherKey);
				}
				break;

			case RT_CMD_SET_RX_WCID_TABLE:	/*General call for RTMPAddWcidAttributeEntry() */
				{
					struct rt_mac_table_entry *pEntry;
					u8 KeyIdx = 0;
					u8 CipherAlg = CIPHER_NONE;
					u8 ApIdx = BSS0;

					pEntry = (struct rt_mac_table_entry *)(pData);

					RTMPAddWcidAttributeEntry(pAd,
								  ApIdx,
								  KeyIdx,
								  CipherAlg,
								  pEntry);
				}
				break;
/*Benson modified for USB interface, avoid in interrupt when write key, 20080724 <-- */

			case CMDTHREAD_SET_CLIENT_MAC_ENTRY:
				{
					struct rt_mac_table_entry *pEntry;
					pEntry = (struct rt_mac_table_entry *)pData;

					{
						AsicRemovePairwiseKeyEntry(pAd,
									   pEntry->
									   apidx,
									   (u8)
									   pEntry->
									   Aid);
						if ((pEntry->AuthMode <=
						     Ndis802_11AuthModeAutoSwitch)
						    && (pEntry->WepStatus ==
							Ndis802_11Encryption1Enabled))
						{
							u32 uIV = 1;
							u8 *ptr;

							ptr = (u8 *)& uIV;
							*(ptr + 3) =
							    (pAd->StaCfg.
							     DefaultKeyId << 6);
							AsicUpdateWCIDIVEIV(pAd,
									    pEntry->
									    Aid,
									    uIV,
									    0);
							AsicUpdateWCIDAttribute
							    (pAd, pEntry->Aid,
							     BSS0,
							     pAd->
							     SharedKey[BSS0]
							     [pAd->StaCfg.
							      DefaultKeyId].
							     CipherAlg, FALSE);
						} else if (pEntry->AuthMode ==
							   Ndis802_11AuthModeWPANone)
						{
							u32 uIV = 1;
							u8 *ptr;

							ptr = (u8 *)& uIV;
							*(ptr + 3) =
							    (pAd->StaCfg.
							     DefaultKeyId << 6);
							AsicUpdateWCIDIVEIV(pAd,
									    pEntry->
									    Aid,
									    uIV,
									    0);
							AsicUpdateWCIDAttribute
							    (pAd, pEntry->Aid,
							     BSS0,
							     pAd->
							     SharedKey[BSS0]
							     [pAd->StaCfg.
							      DefaultKeyId].
							     CipherAlg, FALSE);
						} else {
							/* */
							/* Other case, disable engine. */
							/* Don't worry WPA key, we will add WPA Key after 4-Way handshaking. */
							/* */
							u16 offset;
							offset =
							    MAC_WCID_ATTRIBUTE_BASE
							    +
							    (pEntry->Aid *
							     HW_WCID_ATTRI_SIZE);
							/* RX_PKEY_MODE:0 for no security; RX_KEY_TAB:0 for shared key table; BSS_IDX:0 */
							RTUSBWriteMACRegister
							    (pAd, offset, 0);
						}
					}

					AsicUpdateRxWCIDTable(pAd, pEntry->Aid,
							      pEntry->Addr);
					DBGPRINT(RT_DEBUG_TRACE,
						("UpdateRxWCIDTable(): Aid=%d, "
							"Addr=%pM!\n",
							pEntry->Aid,
							pEntry->Addr));
				}
				break;

/* add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet */
			case CMDTHREAD_UPDATE_PROTECT:
				{
					AsicUpdateProtect(pAd, 0,
							  (ALLN_SETPROTECT),
							  TRUE, 0);
				}
				break;
/* end johnli */

			case OID_802_11_ADD_WEP:
				{
					u32 i;
					u32 KeyIdx;
					struct rt_ndis_802_11_wep *pWepKey;

					DBGPRINT(RT_DEBUG_TRACE,
						 ("CmdThread::OID_802_11_ADD_WEP  \n"));

					pWepKey = (struct rt_ndis_802_11_wep *)pData;
					KeyIdx = pWepKey->KeyIndex & 0x0fffffff;

					/* it is a shared key */
					if ((KeyIdx >= 4)
					    || ((pWepKey->KeyLength != 5)
						&& (pWepKey->KeyLength !=
						    13))) {
						NdisStatus =
						    NDIS_STATUS_INVALID_DATA;
						DBGPRINT(RT_DEBUG_ERROR,
							 ("CmdThread::OID_802_11_ADD_WEP, INVALID_DATA!!\n"));
					} else {
						u8 CipherAlg;
						pAd->SharedKey[BSS0][KeyIdx].
						    KeyLen =
						    (u8)pWepKey->KeyLength;
						NdisMoveMemory(pAd->
							       SharedKey[BSS0]
							       [KeyIdx].Key,
							       &pWepKey->
							       KeyMaterial,
							       pWepKey->
							       KeyLength);
						CipherAlg =
						    (pAd->
						     SharedKey[BSS0][KeyIdx].
						     KeyLen ==
						     5) ? CIPHER_WEP64 :
						    CIPHER_WEP128;

						/* */
						/* Change the WEP cipher to CKIP cipher if CKIP KP on. */
						/* Funk UI or Meetinghouse UI will add ckip key from this path. */
						/* */

						if (pAd->OpMode == OPMODE_STA) {
							pAd->MacTab.
							    Content[BSSID_WCID].
							    PairwiseKey.
							    CipherAlg =
							    pAd->
							    SharedKey[BSS0]
							    [KeyIdx].CipherAlg;
							pAd->MacTab.
							    Content[BSSID_WCID].
							    PairwiseKey.KeyLen =
							    pAd->
							    SharedKey[BSS0]
							    [KeyIdx].KeyLen;
						}
						pAd->SharedKey[BSS0][KeyIdx].
						    CipherAlg = CipherAlg;
						if (pWepKey->
						    KeyIndex & 0x80000000) {
							/* Default key for tx (shared key) */
							u8 IVEIV[8];
							u32 WCIDAttri, Value;
							u16 offset, offset2;
							NdisZeroMemory(IVEIV,
								       8);
							pAd->StaCfg.
							    DefaultKeyId =
							    (u8)KeyIdx;
							/* Add BSSID to WCTable. because this is Tx wep key. */
							/* WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0 */
							WCIDAttri =
							    (CipherAlg << 1) |
							    SHAREDKEYTABLE;

							offset =
							    MAC_WCID_ATTRIBUTE_BASE
							    +
							    (BSSID_WCID *
							     HW_WCID_ATTRI_SIZE);
							RTUSBWriteMACRegister
							    (pAd, offset,
							     WCIDAttri);
							/* 1. IV/EIV */
							/* Specify key index to find shared key. */
							IVEIV[3] = (u8)(KeyIdx << 6);	/*WEP Eiv bit off. groupkey index is not 0 */
							offset =
							    PAIRWISE_IVEIV_TABLE_BASE
							    +
							    (BSS0Mcast_WCID *
							     HW_IVEIV_ENTRY_SIZE);
							offset2 =
							    PAIRWISE_IVEIV_TABLE_BASE
							    +
							    (BSSID_WCID *
							     HW_IVEIV_ENTRY_SIZE);
							for (i = 0; i < 8;) {
								Value =
								    IVEIV[i];
								Value +=
								    (IVEIV
								     [i +
								      1] << 8);
								Value +=
								    (IVEIV
								     [i +
								      2] << 16);
								Value +=
								    (IVEIV
								     [i +
								      3] << 24);
								RTUSBWriteMACRegister
								    (pAd,
								     offset + i,
								     Value);
								RTUSBWriteMACRegister
								    (pAd,
								     offset2 +
								     i, Value);
								i += 4;
							}

							/* 2. WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:use share key, BSSIdx is 0 */
							WCIDAttri =
							    (pAd->
							     SharedKey[BSS0]
							     [KeyIdx].
							     CipherAlg << 1) |
							    SHAREDKEYTABLE;
							offset =
							    MAC_WCID_ATTRIBUTE_BASE
							    +
							    (BSS0Mcast_WCID *
							     HW_WCID_ATTRI_SIZE);
							DBGPRINT(RT_DEBUG_TRACE,
								 ("BSS0Mcast_WCID : offset = %x, WCIDAttri = %x\n",
								  offset,
								  WCIDAttri));
							RTUSBWriteMACRegister
							    (pAd, offset,
							     WCIDAttri);

						}
						AsicAddSharedKeyEntry(pAd, BSS0,
								      (u8)
								      KeyIdx,
								      CipherAlg,
								      pWepKey->
								      KeyMaterial,
								      NULL,
								      NULL);
						DBGPRINT(RT_DEBUG_TRACE,
							 ("CmdThread::OID_802_11_ADD_WEP (KeyIdx=%d, Len=%d-byte)\n",
							  KeyIdx,
							  pWepKey->KeyLength));
					}
				}
				break;

			case CMDTHREAD_802_11_COUNTER_MEASURE:
				break;

			case CMDTHREAD_SET_GROUP_KEY:
				WpaStaGroupKeySetting(pAd);
				break;

			case CMDTHREAD_SET_PAIRWISE_KEY:
				WpaStaPairwiseKeySetting(pAd);
				break;

			case CMDTHREAD_SET_PSM_BIT:
				{
					u16 *pPsm = (u16 *) pData;
					MlmeSetPsmBit(pAd, *pPsm);
				}
				break;
			case CMDTHREAD_FORCE_WAKE_UP:
				AsicForceWakeup(pAd, TRUE);
				break;

			default:
				DBGPRINT(RT_DEBUG_ERROR,
					 ("--> Control Thread !! ERROR !! Unknown(cmdqelmt->command=0x%x) !! \n",
					  cmdqelmt->command));
				break;
			}
		}

		if (cmdqelmt->CmdFromNdis == TRUE) {
			if (cmdqelmt->buffer != NULL)
				os_free_mem(pAd, cmdqelmt->buffer);
			os_free_mem(pAd, cmdqelmt);
		} else {
			if ((cmdqelmt->buffer != NULL)
			    && (cmdqelmt->bufferlength != 0))
				os_free_mem(pAd, cmdqelmt->buffer);
			os_free_mem(pAd, cmdqelmt);
		}
	}			/* end of while */
}

#endif /* RTMP_MAC_USB // */
