]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/staging/rt3070/rt_ate.c
Merge branch 'omap-pool'
[linux-2.6-omap-h63xx.git] / drivers / staging / rt3070 / rt_ate.c
diff --git a/drivers/staging/rt3070/rt_ate.c b/drivers/staging/rt3070/rt_ate.c
new file mode 100644 (file)
index 0000000..9238d96
--- /dev/null
@@ -0,0 +1,6506 @@
+/*
+ *************************************************************************
+ * 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.             *
+ *                                                                       *
+ *************************************************************************
+ */
+
+#include "rt_config.h"
+
+#ifdef UCOS
+INT IoctlResponse(PUCHAR payload, PUCHAR msg, INT len);
+#endif // UCOS //
+
+#define ATE_BBP_REG_NUM        168
+UCHAR restore_BBP[ATE_BBP_REG_NUM]={0};
+
+#ifdef RALINK_ATE
+UCHAR TemplateFrame[24] = {0x08/* Data type */,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0xAA,0xBB,0x12,0x34,0x56,0x00,0x11,0x22,0xAA,0xBB,0xCC,0x00,0x00};    // 802.11 MAC Header, Type:Data, Length:24bytes
+extern RTMP_RF_REGS RF2850RegTable[];
+extern UCHAR NUM_OF_2850_CHNL;
+
+#ifdef RT2870
+extern UCHAR EpToQueue[];
+extern VOID    RTUSBRejectPendingPackets(      IN      PRTMP_ADAPTER   pAd);
+#endif // RT2870 //
+
+#ifdef RT30xx
+//2008/07/10:KH adds to support 3070 ATE<--
+extern FREQUENCY_ITEM FreqItems3020[];
+extern UCHAR NUM_OF_3020_CHNL;
+//2008/07/10:KH adds to support 3070 ATE-->
+#endif // RT30xx //
+
+#ifdef UCOS
+extern INT ConsoleResponse(IN PUCHAR buff);
+extern int (*remote_display)(char *);
+#endif // UCOS //
+
+static CHAR CCKRateTable[] = {0, 1, 2, 3, 8, 9, 10, 11, -1}; /* CCK Mode. */
+static CHAR OFDMRateTable[] = {0, 1, 2, 3, 4, 5, 6, 7, -1}; /* OFDM Mode. */
+static CHAR HTMIXRateTable[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}; /* HT Mix Mode. */
+
+static INT TxDmaBusy(
+       IN PRTMP_ADAPTER pAd);
+
+static INT RxDmaBusy(
+       IN PRTMP_ADAPTER pAd);
+
+static VOID RtmpDmaEnable(
+       IN PRTMP_ADAPTER pAd,
+       IN INT Enable);
+
+static VOID BbpSoftReset(
+       IN PRTMP_ADAPTER pAd);
+
+static VOID RtmpRfIoWrite(
+       IN PRTMP_ADAPTER pAd);
+
+static INT ATESetUpFrame(
+       IN PRTMP_ADAPTER pAd,
+       IN UINT32 TxIdx);
+
+static INT ATETxPwrHandler(
+       IN PRTMP_ADAPTER pAd,
+       IN char index);
+
+static INT ATECmdHandler(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg);
+
+static int CheckMCSValid(
+       IN UCHAR Mode,
+       IN UCHAR Mcs);
+
+
+#ifdef RT2870
+static VOID ATEWriteTxInfo(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PTXINFO_STRUC   pTxInfo,
+       IN        USHORT                USBDMApktLen,
+       IN        BOOLEAN               bWiv,
+       IN        UCHAR                 QueueSel,
+       IN        UCHAR                 NextValid,
+       IN        UCHAR                 TxBurst);
+
+static VOID ATEWriteTxWI(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PTXWI_STRUC     pTxWI,
+       IN      BOOLEAN                 FRAG,
+       IN      BOOLEAN                 InsTimestamp,
+       IN      BOOLEAN                 AMPDU,
+       IN      BOOLEAN                 Ack,
+       IN      BOOLEAN                 NSeq,           // HW new a sequence.
+       IN      UCHAR                   BASize,
+       IN      UCHAR                   WCID,
+       IN      ULONG                   Length,
+       IN      UCHAR                   PID,
+       IN      UCHAR                   MIMOps,
+       IN      UCHAR                   Txopmode,
+       IN      BOOLEAN                 CfAck,
+       IN      HTTRANSMIT_SETTING      Transmit);
+
+#endif // RT2870 //
+
+static VOID SetJapanFilter(
+       IN      PRTMP_ADAPTER   pAd);
+
+/*=========================end of prototype=========================*/
+
+
+#ifdef RT2870
+static INT TxDmaBusy(
+       IN PRTMP_ADAPTER pAd)
+{
+       INT result;
+       USB_DMA_CFG_STRUC UsbCfg;
+
+       RTMP_IO_READ32(pAd, USB_DMA_CFG, &UsbCfg.word); // disable DMA
+       if (UsbCfg.field.TxBusy)
+               result = 1;
+       else
+               result = 0;
+
+       return result;
+}
+
+static INT RxDmaBusy(
+       IN PRTMP_ADAPTER pAd)
+{
+       INT result;
+       USB_DMA_CFG_STRUC UsbCfg;
+
+       RTMP_IO_READ32(pAd, USB_DMA_CFG, &UsbCfg.word); // disable DMA
+       if (UsbCfg.field.RxBusy)
+               result = 1;
+       else
+               result = 0;
+
+       return result;
+}
+
+static VOID RtmpDmaEnable(
+       IN PRTMP_ADAPTER pAd,
+       IN INT Enable)
+{
+       BOOLEAN value;
+       ULONG WaitCnt;
+       USB_DMA_CFG_STRUC UsbCfg;
+
+       value = Enable > 0 ? 1 : 0;
+
+       // check DMA is in busy mode.
+       WaitCnt = 0;
+       while (TxDmaBusy(pAd) || RxDmaBusy(pAd))
+       {
+               RTMPusecDelay(10);
+               if (WaitCnt++ > 100)
+                       break;
+       }
+
+       //Why not to clear USB DMA TX path first ???
+       RTMP_IO_READ32(pAd, USB_DMA_CFG, &UsbCfg.word); // disable DMA
+       UsbCfg.field.TxBulkEn = value;
+       UsbCfg.field.RxBulkEn = value;
+       RTMP_IO_WRITE32(pAd, USB_DMA_CFG, UsbCfg.word); // abort all TX rings
+       RTMPusecDelay(5000);
+
+       return;
+}
+#endif // RT2870 //
+
+static VOID BbpSoftReset(
+       IN PRTMP_ADAPTER pAd)
+{
+       UCHAR BbpData = 0;
+
+       // Soft reset, set BBP R21 bit0=1->0
+       ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R21, &BbpData);
+       BbpData |= 0x00000001; //set bit0=1
+       ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21, BbpData);
+
+       ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R21, &BbpData);
+       BbpData &= ~(0x00000001); //set bit0=0
+       ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21, BbpData);
+
+       return;
+}
+
+static VOID RtmpRfIoWrite(
+       IN PRTMP_ADAPTER pAd)
+{
+       // Set RF value 1's set R3[bit2] = [0]
+       RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
+       RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
+       RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
+       RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
+
+       RTMPusecDelay(200);
+
+       // Set RF value 2's set R3[bit2] = [1]
+       RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
+       RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
+       RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04));
+       RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
+
+       RTMPusecDelay(200);
+
+       // Set RF value 3's set R3[bit2] = [0]
+       RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
+       RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
+       RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
+       RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
+
+       return;
+}
+
+static int CheckMCSValid(
+       UCHAR Mode,
+       UCHAR Mcs)
+{
+       int i;
+       PCHAR pRateTab;
+
+       switch(Mode)
+       {
+               case 0:
+                       pRateTab = CCKRateTable;
+                       break;
+               case 1:
+                       pRateTab = OFDMRateTable;
+                       break;
+               case 2:
+               case 3:
+                       pRateTab = HTMIXRateTable;
+                       break;
+               default:
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("unrecognizable Tx Mode %d\n", Mode));
+                       return -1;
+                       break;
+       }
+
+       i = 0;
+       while(pRateTab[i] != -1)
+       {
+               if (pRateTab[i] == Mcs)
+                       return 0;
+               i++;
+       }
+
+       return -1;
+}
+
+#if 1
+static INT ATETxPwrHandler(
+       IN PRTMP_ADAPTER pAd,
+       IN char index)
+{
+       ULONG R;
+       CHAR TxPower;
+       UCHAR Bbp94 = 0;
+       BOOLEAN bPowerReduce = FALSE;
+#ifdef RT30xx
+       UCHAR RFValue;
+#endif // RT30xx //
+#ifdef RALINK_28xx_QA
+       if ((pAd->ate.bQATxStart == TRUE) || (pAd->ate.bQARxStart == TRUE))
+       {
+               /* When QA is used for Tx, pAd->ate.TxPower0/1 and real tx power
+               ** are not synchronized.
+               */
+/*
+               pAd->ate.TxPower0 = pAd->LatchRfRegs.xxx;
+               pAd->ate.TxPower1 = pAd->LatchRfRegs.xxx;
+*/
+               return 0;
+       }
+       else
+#endif // RALINK_28xx_QA //
+       {
+               TxPower = index == 0 ? pAd->ate.TxPower0 : pAd->ate.TxPower1;
+
+               if (pAd->ate.Channel <= 14)
+               {
+                       if (TxPower > 31)
+                       {
+                               //
+                               // R3, R4 can't large than 31 (0x24), 31 ~ 36 used by BBP 94
+                               //
+                               R = 31;
+                               if (TxPower <= 36)
+                                       Bbp94 = BBPR94_DEFAULT + (UCHAR)(TxPower - 31);
+                       }
+                       else if (TxPower < 0)
+                       {
+                               //
+                               // R3, R4 can't less than 0, -1 ~ -6 used by BBP 94
+                               //
+                               R = 0;
+                               if (TxPower >= -6)
+                                       Bbp94 = BBPR94_DEFAULT + TxPower;
+                       }
+                       else
+                       {
+                               // 0 ~ 31
+                               R = (ULONG) TxPower;
+                               Bbp94 = BBPR94_DEFAULT;
+                       }
+
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("%s (TxPower=%d, R=%ld, BBP_R94=%d)\n", __FUNCTION__, TxPower, R, Bbp94));
+               }
+               else// 5.5 GHz
+               {
+                       if (TxPower > 15)
+                       {
+                               //
+                               // R3, R4 can't large than 15 (0x0F)
+                               //
+                               R = 15;
+                       }
+                       else if (TxPower < 0)
+                       {
+                               //
+                               // R3, R4 can't less than 0
+                               //
+                               // -1 ~ -7
+                               ASSERT((TxPower >= -7));
+                               R = (ULONG)(TxPower + 7);
+                               bPowerReduce = TRUE;
+                       }
+                       else
+                       {
+                               // 0 ~ 15
+                               R = (ULONG) TxPower;
+                       }
+
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("%s (TxPower=%d, R=%lu)\n", __FUNCTION__, TxPower, R));
+               }
+//2008/09/10:KH adds to support 3070 ATE TX Power tunning real time<--
+#ifdef RT30xx
+               if(IS_RT30xx(pAd))
+               {
+                       // Set Tx Power
+
+                                       RT30xxReadRFRegister(pAd, RF_R12, (PUCHAR)&RFValue);
+                                       RFValue = (RFValue & 0xE0) | TxPower;
+                                       RT30xxWriteRFRegister(pAd, RF_R12, (UCHAR)RFValue);
+                                       ATEDBGPRINT(RT_DEBUG_TRACE, ("3070 or 2070:%s (TxPower=%d, RFValue=%x)\n", __FUNCTION__, TxPower, RFValue));
+
+               }
+               else
+#endif // RT30xx //
+             {
+               if (pAd->ate.Channel <= 14)
+               {
+                       if (index == 0)
+                       {
+                               R = R << 9;             // shift TX power control to correct RF(R3) register bit position
+                               R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
+                               pAd->LatchRfRegs.R3 = R;
+                       }
+                       else
+                       {
+                               R = R << 6;             // shift TX power control to correct RF(R4) register bit position
+                               R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
+                               pAd->LatchRfRegs.R4 = R;
+                       }
+               }
+               else// 5.5GHz
+               {
+                       if (bPowerReduce == FALSE)
+                       {
+                               if (index == 0)
+                               {
+                                       R = (R << 10) | (1 << 9);               // shift TX power control to correct RF(R3) register bit position
+                                       R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
+                                       pAd->LatchRfRegs.R3 = R;
+                               }
+                               else
+                               {
+                                       R = (R << 7) | (1 << 6);                // shift TX power control to correct RF(R4) register bit position
+                                       R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
+                                       pAd->LatchRfRegs.R4 = R;
+                               }
+                       }
+                       else
+                       {
+                               if (index == 0)
+                               {
+                                       R = (R << 10);          // shift TX power control to correct RF(R3) register bit position
+                                       R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
+
+                                       /* Clear bit 9 of R3 to reduce 7dB. */
+                                       pAd->LatchRfRegs.R3 = (R & (~(1 << 9)));
+                               }
+                               else
+                               {
+                                       R = (R << 7);           // shift TX power control to correct RF(R4) register bit position
+                                       R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
+
+                                       /* Clear bit 6 of R4 to reduce 7dB. */
+                                       pAd->LatchRfRegs.R4 = (R & (~(1 << 6)));
+                               }
+                       }
+               }
+               RtmpRfIoWrite(pAd);
+           }
+//2008/09/10:KH adds to support 3070 ATE TX Power tunning real time-->
+
+               return 0;
+       }
+}
+#else// 1 //
+static INT ATETxPwrHandler(
+       IN PRTMP_ADAPTER pAd,
+       IN char index)
+{
+       ULONG R;
+       CHAR TxPower;
+       UCHAR Bbp94 = 0;
+
+#ifdef RALINK_28xx_QA
+       if ((pAd->ate.bQATxStart == TRUE) || (pAd->ate.bQARxStart == TRUE))
+       {
+               // TODO: how to get current TxPower0/1 from pAd->LatchRfRegs ?
+               /* When QA is used for Tx, pAd->ate.TxPower0/1 and real tx power
+               ** are not synchronized.
+               */
+/*
+               pAd->ate.TxPower0 = pAd->LatchRfRegs.xxx;
+               pAd->ate.TxPower1 = pAd->LatchRfRegs.xxx;
+*/
+               return 0;
+       }
+       else
+#endif // RALINK_28xx_QA //
+       {
+               TxPower = index == 0 ? pAd->ate.TxPower0 : pAd->ate.TxPower1;
+
+       if (TxPower > 31)
+       {
+               //
+               // R3, R4 can't large than 36 (0x24), 31 ~ 36 used by BBP 94
+               //
+               R = 31;
+               if (TxPower <= 36)
+                       Bbp94 = BBPR94_DEFAULT + (UCHAR)(TxPower - 31);
+       }
+       else if (TxPower < 0)
+       {
+               //
+               // R3, R4 can't less than 0, -1 ~ -6 used by BBP 94
+               //
+               R = 0;
+               if (TxPower >= -6)
+                       Bbp94 = BBPR94_DEFAULT + TxPower;
+       }
+       else
+       {
+               // 0 ~ 31
+               R = (ULONG) TxPower;
+               Bbp94 = BBPR94_DEFAULT;
+       }
+
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("%s (TxPower=%d, R3=%ld, BBP_R94=%d)\n", __FUNCTION__, TxPower, R, Bbp94));
+
+               if (pAd->ate.Channel <= 14)
+               {
+       if (index == 0)
+       {
+               R = R << 9;             // shift TX power control to correct RF(R3) register bit position
+               R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
+               pAd->LatchRfRegs.R3 = R;
+       }
+       else
+       {
+               R = R << 6;             // shift TX power control to correct RF(R4) register bit position
+               R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
+               pAd->LatchRfRegs.R4 = R;
+       }
+               }
+               else
+               {
+                       if (index == 0)
+                       {
+                               R = (R << 10) | (1 << 9);               // shift TX power control to correct RF(R3) register bit position
+                               R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
+                               pAd->LatchRfRegs.R3 = R;
+                       }
+                       else
+                       {
+                               R = (R << 7) | (1 << 6);                // shift TX power control to correct RF(R4) register bit position
+                               R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
+                               pAd->LatchRfRegs.R4 = R;
+                       }
+               }
+
+       RtmpRfIoWrite(pAd);
+
+       return 0;
+       }
+}
+#endif // 1 //
+/*
+    ==========================================================================
+    Description:
+        Set ATE operation mode to
+        0. ATESTART  = Start ATE Mode
+        1. ATESTOP   = Stop ATE Mode
+        2. TXCONT    = Continuous Transmit
+        3. TXCARR    = Transmit Carrier
+        4. TXFRAME   = Transmit Frames
+        5. RXFRAME   = Receive Frames
+#ifdef RALINK_28xx_QA
+        6. TXSTOP    = Stop Any Type of Transmition
+        7. RXSTOP    = Stop Receiving Frames
+#endif // RALINK_28xx_QA //
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+/*                                                           */
+/*                                                           */
+/*=======================End of RT2860=======================*/
+
+
+/*======================Start of RT2870======================*/
+/*                                                           */
+/*                                                           */
+
+#ifdef RT2870
+static INT     ATECmdHandler(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+       UINT32                  Value;
+       UCHAR                   BbpData;
+       UINT32          MacData;
+       UINT                    i=0, atemode;
+       //NDIS_STATUS           Status = NDIS_STATUS_SUCCESS;
+       //PUCHAR                        pDest;
+       UINT32                  temp;
+       ULONG                   IrqFlags;
+
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("===> ATECmdHandler()\n"));
+       ATEAsicSwitchChannel(pAd);
+       /* AsicLockChannel() is empty function so far in fact */
+       AsicLockChannel(pAd, pAd->ate.Channel);
+
+       RTMPusecDelay(5000);
+
+       // Default value in BBP R22 is 0x0.
+       BbpData = 0;
+
+       /* Enter ATE mode and set Tx/Rx Idle */
+       if (!strcmp(arg, "ATESTART"))
+       {
+#ifdef CONFIG_STA_SUPPORT
+               BOOLEAN       Cancelled;
+#endif // CONFIG_STA_SUPPORT //
+               ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: ATESTART\n"));
+
+               netif_stop_queue(pAd->net_dev);
+
+               atemode = pAd->ate.Mode;
+               pAd->ate.Mode = ATE_START;
+//             pAd->ate.TxDoneCount = pAd->ate.TxCount;
+               // Disable Rx
+               RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+               Value &= ~(1 << 3);
+               RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+               // Disable auto responder
+               RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &temp);
+               temp = temp & 0xFFFFFFFE;
+               RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, temp);
+
+               // read MAC_SYS_CTRL and backup MAC_SYS_CTRL value.
+               RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+               // clean bit4 to stop continuous Tx production test.
+               MacData &= 0xFFFFFFEF;
+               // Stop continuous TX production test.
+               RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);//disable or cancel pending irp first ???
+
+        if (atemode & ATE_TXCARR
+#ifdef RT30xx
+ || atemode & ATE_TXCONT
+#endif // RT30xx //
+)
+               {
+#ifdef RT30xx
+                       //Hardware Reset BBP
+                       RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &temp);
+                       temp = temp |0x00000002;
+                       RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, temp);
+                       RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &temp);
+                       temp = temp & ~(0x00000002);
+                       RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, temp);
+                       //Restore All BBP Value
+                       for(i=0;i<ATE_BBP_REG_NUM;i++)
+                       ATE_BBP_IO_WRITE8_BY_REG_ID(pAd,i,restore_BBP[i]);
+#endif // RT30xx //
+
+                       // No Carrier Test set BBP R22 bit7=0, bit6=0, bit[5~0]=0x0
+                       ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+                       BbpData &= 0xFFFFFF00; //clear bit7, bit6, bit[5~0]
+                   ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+               }
+               else if (atemode & ATE_TXCARRSUPP)
+               {
+#ifdef RT30xx
+                       //Hardware Reset BBP
+                       RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &temp);
+                       temp = temp |0x00000002;
+                       RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, temp);
+                       RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &temp);
+                       temp = temp & ~(0x00000002);
+                       RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, temp);
+                       //Restore All BBP Value
+                       for(i=0;i<ATE_BBP_REG_NUM;i++)
+                       ATE_BBP_IO_WRITE8_BY_REG_ID(pAd,i,restore_BBP[i]);
+#endif // RT30xx //
+
+                       // No Cont. TX set BBP R22 bit7=0
+                       ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+                       BbpData &= ~(1 << 7); //set bit7=0
+                       ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+
+                       // No Carrier Suppression set BBP R24 bit0=0
+                       ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R24, &BbpData);
+                       BbpData &= 0xFFFFFFFE; //clear bit0
+                   ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, BbpData);
+               }
+               // We should free some resource which allocate when ATE_TXFRAME , ATE_STOP, and ATE_TXCONT.
+               // TODO:Should we free some resource which was allocated when LoopBack and ATE_STOP ?
+               else if ((atemode & ATE_TXFRAME) || (atemode == ATE_STOP))
+               {
+                       if (atemode & ATE_TXCONT)
+                       {
+                               // Not Cont. TX anymore, so set BBP R22 bit7=0
+                               ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+                               BbpData &= ~(1 << 7); //set bit7=0
+                               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+                       }
+                       // Abort Tx, Rx DMA.
+                       RtmpDmaEnable(pAd, 0);
+
+                       {
+                               // It seems nothing to free,
+                               // because we didn't allocate any resource when we entered ATE_TXFRAME mode latestly.
+                       }
+
+                       // Start Tx, RX DMA
+                       RtmpDmaEnable(pAd, 1);
+               }
+
+               RTUSBRejectPendingPackets(pAd);
+               RTUSBCleanUpDataBulkOutQueue(pAd);
+
+#ifdef CONFIG_STA_SUPPORT
+               //
+               // It will be called in MlmeSuspend().
+               //
+               // Cancel pending timers
+               RTMPCancelTimer(&pAd->MlmeAux.AssocTimer,     &Cancelled);
+               RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer,   &Cancelled);
+               RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer,   &Cancelled);
+               RTMPCancelTimer(&pAd->MlmeAux.AuthTimer,       &Cancelled);
+               RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer,     &Cancelled);
+               RTMPCancelTimer(&pAd->MlmeAux.ScanTimer,       &Cancelled);
+#endif // CONFIG_STA_SUPPORT //
+
+               //RTUSBCleanUpMLMEWaitQueue(pAd);       /* not used in RT28xx */
+               RTUSBCleanUpMLMEBulkOutQueue(pAd);
+
+               // Sometimes kernel will hang on, so we avoid calling MlmeSuspend().
+//             MlmeSuspend(pAd, TRUE);
+               //RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled);
+
+               // Disable Rx
+               RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+               Value &= ~(1 << 3);
+               RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+               // Abort Tx, RX DMA.
+               RtmpDmaEnable(pAd, 0);
+
+               // Disable Tx
+               RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+               Value &= ~(1 << 2);
+               RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+               // Make sure there are no pending bulk in/out IRPs before we go on.
+/*=========================================================================*/
+               /* pAd->PendingRx is not of type atomic_t anymore in 28xx */
+//             while ((atomic_read(&pAd->PendingRx) > 0))      //pAd->BulkFlags != 0 wait bulk out finish
+               while ((pAd->PendingRx > 0))    //pAd->BulkFlags != 0 wait bulk out finish
+               {
+#if 1
+                       ATE_RTUSBCancelPendingBulkInIRP(pAd);
+#else
+                       NdisInterlockedDecrement(&pAd->PendingRx);
+#endif
+                       /* delay 0.5 seconds */
+                       RTMPusecDelay(500000);
+                       pAd->PendingRx = 0;
+               }
+               /* peter : why don't we have to get BulkOutLock first ? */
+               while (((pAd->BulkOutPending[0] == TRUE) ||
+                               (pAd->BulkOutPending[1] == TRUE) ||
+                               (pAd->BulkOutPending[2] == TRUE) ||
+                               (pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0))     //pAd->BulkFlags != 0 wait bulk out finish
+               {
+                       do
+                       {
+                               /* pAd->BulkOutPending[y] will be set to FALSE in RTUSBCancelPendingBulkOutIRP(pAd) */
+                               RTUSBCancelPendingBulkOutIRP(pAd);
+                       } while (FALSE);
+
+                       /* we have enough time delay in RTUSBCancelPendingBulkOutIRP(pAd)
+                       ** so this is not necessary
+                       */
+//                     RTMPusecDelay(500000);
+               }
+
+               /* pAd->PendingRx is not of type atomic_t anymore in 28xx */
+//             ASSERT(atomic_read(&pAd->PendingRx) == 0);
+               ASSERT(pAd->PendingRx == 0);
+/*=========================================================================*/
+
+               // reset Rx statistics.
+               pAd->ate.LastSNR0 = 0;
+               pAd->ate.LastSNR1 = 0;
+               pAd->ate.LastRssi0 = 0;
+               pAd->ate.LastRssi1 = 0;
+               pAd->ate.LastRssi2 = 0;
+               pAd->ate.AvgRssi0 = 0;
+               pAd->ate.AvgRssi1 = 0;
+               pAd->ate.AvgRssi2 = 0;
+               pAd->ate.AvgRssi0X8 = 0;
+               pAd->ate.AvgRssi1X8 = 0;
+               pAd->ate.AvgRssi2X8 = 0;
+               pAd->ate.NumOfAvgRssiSample = 0;
+
+#ifdef RALINK_28xx_QA
+               // Tx frame
+               pAd->ate.bQATxStart = FALSE;
+               pAd->ate.bQARxStart = FALSE;
+               pAd->ate.seq = 0;
+
+               // counters
+               pAd->ate.U2M = 0;
+               pAd->ate.OtherData = 0;
+               pAd->ate.Beacon = 0;
+               pAd->ate.OtherCount = 0;
+               pAd->ate.TxAc0 = 0;
+               pAd->ate.TxAc1 = 0;
+               pAd->ate.TxAc2 = 0;
+               pAd->ate.TxAc3 = 0;
+               pAd->ate.TxHCCA = 0;
+               pAd->ate.TxMgmt = 0;
+               pAd->ate.RSSI0 = 0;
+               pAd->ate.RSSI1 = 0;
+               pAd->ate.RSSI2 = 0;
+               pAd->ate.SNR0 = 0;
+               pAd->ate.SNR1 = 0;
+
+               // control
+               pAd->ate.TxDoneCount = 0;
+               pAd->ate.TxStatus = 0; // task Tx status // 0 --> task is idle, 1 --> task is running
+#endif // RALINK_28xx_QA //
+
+               // Soft reset BBP.
+               BbpSoftReset(pAd);
+
+
+#ifdef CONFIG_STA_SUPPORT
+               AsicDisableSync(pAd);
+
+               /*
+               ** If we skip "LinkDown()", we should disable protection
+               ** to prevent from sending out RTS or CTS-to-self.
+               */
+               ATEDisableAsicProtect(pAd);
+               RTMPStationStop(pAd);
+#endif // CONFIG_STA_SUPPORT //
+
+               // Default value in BBP R22 is 0x0.
+               BbpData = 0;
+               RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+
+               // Clean bit4 to stop continuous Tx production test.
+               MacData &= 0xFFFFFFEF;
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+               RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+               //Clean ATE Bulk in/out counter and continue setup
+               InterlockedExchange(&pAd->BulkOutRemained, 0);
+
+               /* NdisAcquireSpinLock()/NdisReleaseSpinLock() need only one argument in RT28xx */
+               NdisAcquireSpinLock(&pAd->GenericLock);
+               pAd->ContinBulkOut = FALSE;
+               pAd->ContinBulkIn = FALSE;
+               NdisReleaseSpinLock(&pAd->GenericLock);
+
+               RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+       }
+       else if (!strcmp(arg, "ATESTOP"))
+       {
+               ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE : ATESTOP ===>\n"));
+
+               // Default value in BBP R22 is 0x0.
+               BbpData = 0;
+               RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);//0820
+               // Clean bit4 to stop continuous Tx production test.
+               MacData &= 0xFFFFFFEF;
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+               RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); // recover the MAC_SYS_CTRL register back.
+
+               // Disable Rx
+               RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+               Value &= ~(1 << 3);
+               RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+               /*
+               ** Abort Tx, RX DMA.
+               ** Q   : How to do the following I/O if Tx, Rx DMA is aborted ?
+               ** Ans : Bulk endpoints are aborted, while the control endpoint is not.
+               */
+               RtmpDmaEnable(pAd, 0);
+
+               // Disable Tx
+               RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+               Value &= ~(1 << 2);
+               RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+               /* Make sure there are no pending bulk in/out IRPs before we go on. */
+/*=========================================================================*/
+//             while ((atomic_read(&pAd->PendingRx) > 0))      //pAd->BulkFlags != 0 wait bulk out finish
+               while (pAd->PendingRx > 0)
+               {
+#if 1
+                       ATE_RTUSBCancelPendingBulkInIRP(pAd);
+#else
+//                     NdisInterlockedDecrement(&pAd->PendingRx);
+                       pAd->PendingRx--;
+#endif
+                       RTMPusecDelay(500000);
+               }
+
+               while (((pAd->BulkOutPending[0] == TRUE) ||
+                               (pAd->BulkOutPending[1] == TRUE) ||
+                               (pAd->BulkOutPending[2] == TRUE) ||
+                               (pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0))     //pAd->BulkFlags != 0 wait bulk out finish
+               {
+                       do
+                       {
+                               RTUSBCancelPendingBulkOutIRP(pAd);
+                       } while (FALSE);
+
+                       RTMPusecDelay(500000);
+               }
+
+//             ASSERT(atomic_read(&pAd->PendingRx) == 0);
+               ASSERT(pAd->PendingRx == 0);
+/*=========================================================================*/
+/*      Reset Rx RING                                                      */
+/*=========================================================================*/
+//             InterlockedExchange(&pAd->PendingRx, 0);
+               pAd->PendingRx = 0;
+               pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
+               pAd->NextRxBulkInIndex = RX_RING_SIZE - 1;      // Rx Bulk pointer
+               pAd->NextRxBulkInPosition = 0;
+               for (i = 0; i < (RX_RING_SIZE); i++)
+               {
+                       PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
+                       NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE);
+                       /* peter : why don't we have to get BulkInLock first ? */
+                       pRxContext->pAd = pAd;
+                       pRxContext->pIrp = NULL;
+            /* peter debug ++ */
+                       pRxContext->BulkInOffset = 0;
+                       pRxContext->bRxHandling = FALSE;
+            /* peter debug -- */
+                       pRxContext->InUse               = FALSE;
+                       pRxContext->IRPPending  = FALSE;
+                       pRxContext->Readable    = FALSE;
+//                     pRxContext->ReorderInUse = FALSE;
+//                     pRxContext->ReadPosOffset = 0;
+               }
+
+/*=========================================================================*/
+/*      Reset Tx RING                                                      */
+/*=========================================================================*/
+               do
+               {
+                       RTUSBCancelPendingBulkOutIRP(pAd);
+               } while (FALSE);
+
+/*=========================================================================*/
+               // Enable auto responder.
+               RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &temp);
+               temp = temp | (0x01);
+               RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, temp);
+
+/*================================================*/
+               AsicEnableBssSync(pAd);
+
+               /* Soft reset BBP.*/
+               /* In 2870 chipset, ATE_BBP_IO_READ8_BY_REG_ID() == RTMP_BBP_IO_READ8_BY_REG_ID() */
+               /* Both rt2870ap and rt2870sta use BbpSoftReset(pAd) to do BBP soft reset */
+               BbpSoftReset(pAd);
+/*================================================*/
+               {
+#ifdef CONFIG_STA_SUPPORT
+                       // Set all state machines back IDLE
+                       pAd->Mlme.CntlMachine.CurrState    = CNTL_IDLE;
+                       pAd->Mlme.AssocMachine.CurrState   = ASSOC_IDLE;
+                       pAd->Mlme.AuthMachine.CurrState    = AUTH_REQ_IDLE;
+                       pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE;
+                       pAd->Mlme.SyncMachine.CurrState    = SYNC_IDLE;
+                       pAd->Mlme.ActMachine.CurrState    = ACT_IDLE;
+#endif // CONFIG_STA_SUPPORT //
+
+                       //
+                       // ===> refer to MlmeRestartStateMachine().
+                       // When we entered ATE_START mode, PeriodicTimer was not cancelled.
+                       // So we don't have to set it here.
+                       //
+                       //RTMPSetTimer(pAd, &pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);
+
+                       ASSERT(pAd->CommonCfg.Channel != 0);
+
+                       AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+                       AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+
+
+#ifdef CONFIG_STA_SUPPORT
+                   RTMPStationStart(pAd);
+#endif // CONFIG_STA_SUPPORT //
+               }
+//
+// These two steps have been done when entering ATE_STOP mode.
+//
+               // Clean ATE Bulk in/out counter and continue setup.
+               InterlockedExchange(&pAd->BulkOutRemained, 0);
+               NdisAcquireSpinLock(&pAd->GenericLock);
+               pAd->ContinBulkOut = FALSE;
+               pAd->ContinBulkIn = FALSE;
+               NdisReleaseSpinLock(&pAd->GenericLock);
+
+               /* Wait 50ms to prevent next URB to bulkout during HW reset. */
+               /* todo : remove this if not necessary */
+               NdisMSleep(50000);
+
+               pAd->ate.Mode = ATE_STOP;
+
+               // Enable Tx
+               RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+               Value |= (1 << 2);
+               RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+/*=========================================================================*/
+               /* restore RX_FILTR_CFG */
+#ifdef CONFIG_STA_SUPPORT
+               /* restore RX_FILTR_CFG in order that QA maybe set it to 0x3 */
+               RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL);
+#endif // CONFIG_STA_SUPPORT //
+/*=========================================================================*/
+
+               // Enable Tx, RX DMA.
+               RtmpDmaEnable(pAd, 1);
+
+               // Enable Rx
+               RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+               Value |= (1 << 3);
+               RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+               // Wait 10ms to wait all of the bulk-in URBs to complete.
+               /* todo : remove this if not necessary */
+               NdisMSleep(10000);
+
+               // Everything is ready to start normal Tx/Rx.
+               RTUSBBulkReceive(pAd);
+               netif_start_queue(pAd->net_dev);
+
+               ATEDBGPRINT(RT_DEBUG_TRACE, ("<=== ATE : ATESTOP \n"));
+       }
+       else if (!strcmp(arg, "TXCARR"))        // Tx Carrier
+       {
+               ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXCARR\n"));
+               pAd->ate.Mode |= ATE_TXCARR;
+
+#ifdef RT30xx
+                       for(i=0;i<ATE_BBP_REG_NUM;i++)
+                               restore_BBP[i]=0;
+                       //Record All BBP Value
+                       for(i=0;i<ATE_BBP_REG_NUM;i++)
+                       ATE_BBP_IO_READ8_BY_REG_ID(pAd,i,&restore_BBP[i]);
+#endif // RT30xx //
+
+               // Disable Rx
+               // May be we need not to do this, because these have been done in ATE_START mode ???
+               RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+               Value &= ~(1 << 3);
+               RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+               // QA has done the following steps if it is used.
+               if (pAd->ate.bQATxStart == FALSE)
+               {
+                       // Soft reset BBP.
+                       BbpSoftReset(pAd);
+
+                       // Carrier Test set BBP R22 bit7=1, bit6=1, bit[5~0]=0x01
+                       ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+                       BbpData &= 0xFFFFFF00; //clear bit7, bit6, bit[5~0]
+                       BbpData |= 0x000000C1; //set bit7=1, bit6=1, bit[5~0]=0x01
+                       ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+
+                       // set MAC_SYS_CTRL(0x1004) Continuous Tx Production Test (bit4) = 1
+                       RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+                       Value = Value | 0x00000010;
+                       RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+               }
+       }
+       else if (!strcmp(arg, "TXCONT"))        // Tx Continue
+       {
+               if (pAd->ate.bQATxStart == TRUE)
+               {
+                       /* set MAC_SYS_CTRL(0x1004) bit4(Continuous Tx Production Test)
+                          and bit2(MAC TX enable) back to zero. */
+                       RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+                       MacData &= 0xFFFFFFEB;
+                       RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+
+                       // set BBP R22 bit7=0
+                       ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+                       BbpData &= 0xFFFFFF7F; //set bit7=0
+                       ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+               }
+
+               /* for TxCont mode.
+               ** Step 1: Send 50 packets first then wait for a moment.
+               ** Step 2: Send more 50 packet then start continue mode.
+               */
+               ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXCONT\n"));
+
+#ifdef RT30xx
+                               for(i=0;i<ATE_BBP_REG_NUM;i++)
+                               restore_BBP[i]=0;
+                       //Record All BBP Value
+                       for(i=0;i<ATE_BBP_REG_NUM;i++)
+                       ATE_BBP_IO_READ8_BY_REG_ID(pAd,i,&restore_BBP[i]);
+#endif // RT30xx //
+
+               // Step 1: send 50 packets first.
+               pAd->ate.Mode |= ATE_TXCONT;
+               pAd->ate.TxCount = 50;
+               pAd->ate.TxDoneCount = 0;
+
+               // Soft reset BBP.
+               BbpSoftReset(pAd);
+
+               // Abort Tx, RX DMA.
+               RtmpDmaEnable(pAd, 0);
+
+
+               /* Only needed if we have to send some normal frames. */
+               SetJapanFilter(pAd);
+
+               // Setup frame format.
+               ATESetUpFrame(pAd, 0);
+
+               // Enable Tx
+               RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+               Value |= (1 << 2);
+               RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+               // Disable Rx
+               RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+               Value &= ~(1 << 3);
+               RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+               // Start Tx, RX DMA.
+               RtmpDmaEnable(pAd, 1);
+
+               InterlockedExchange(&pAd->BulkOutRemained, pAd->ate.TxCount);
+
+#ifdef RALINK_28xx_QA
+               if (pAd->ate.bQATxStart == TRUE)
+               {
+                       pAd->ate.TxStatus = 1;
+                       //pAd->ate.Repeat = 0;
+               }
+#endif // RALINK_28xx_QA //
+
+               NdisAcquireSpinLock(&pAd->GenericLock);//0820
+               pAd->ContinBulkOut = FALSE;
+               NdisReleaseSpinLock(&pAd->GenericLock);
+
+               RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+
+               // Kick bulk out
+               RTUSBKickBulkOut(pAd);
+
+               /* To make sure all the 50 frames have been bulk out before executing step 2 */
+               while (atomic_read(&pAd->BulkOutRemained) > 0)
+               {
+                       RTMPusecDelay(5000);
+               }
+
+               // Step 2: send more 50 packets then start continue mode.
+               // Abort Tx, RX DMA.
+               RtmpDmaEnable(pAd, 0);
+
+               // Cont. TX set BBP R22 bit7=1
+               ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+               BbpData |= 0x00000080; //set bit7=1
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+
+               pAd->ate.TxCount = 50;
+               pAd->ate.TxDoneCount = 0;
+
+               SetJapanFilter(pAd);
+
+               // Setup frame format.
+               ATESetUpFrame(pAd, 0);
+
+               // Enable Tx
+               RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+               Value |= (1 << 2);
+               RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+               // Disable Rx
+               RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+               Value &= ~(1 << 3);
+
+               // Start Tx, RX DMA.
+               RtmpDmaEnable(pAd, 1);
+
+               InterlockedExchange(&pAd->BulkOutRemained, pAd->ate.TxCount);
+
+#ifdef RALINK_28xx_QA
+               if (pAd->ate.bQATxStart == TRUE)
+               {
+                       pAd->ate.TxStatus = 1;
+                       //pAd->ate.Repeat = 0;
+               }
+#endif // RALINK_28xx_QA //
+
+               NdisAcquireSpinLock(&pAd->GenericLock);//0820
+               pAd->ContinBulkOut = FALSE;
+               NdisReleaseSpinLock(&pAd->GenericLock);
+
+               RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+               // Kick bulk out
+               RTUSBKickBulkOut(pAd);
+
+#if 1
+               RTMPusecDelay(500);
+#else
+               while (atomic_read(&pAd->BulkOutRemained) > 0)
+               {
+                       RTMPusecDelay(5000);
+               }
+#endif // 1 //
+
+               // Set MAC_SYS_CTRL(0x1004) Continuous Tx Production Test (bit4) = 1.
+               RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+               MacData |= 0x00000010;
+               RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+       }
+       else if (!strcmp(arg, "TXFRAME"))       // Tx Frames
+       {
+               ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXFRAME(Count=0x%08x)\n", pAd->ate.TxCount));
+               pAd->ate.Mode |= ATE_TXFRAME;
+
+               // Soft reset BBP.
+               BbpSoftReset(pAd);
+
+               // Default value in BBP R22 is 0x0.
+               BbpData = 0;
+
+               RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+
+               // Clean bit4 to stop continuous Tx production test.
+               MacData &= 0xFFFFFFEF;
+
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+               RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+
+#ifdef RALINK_28xx_QA
+               // add this for LoopBack mode
+               if (pAd->ate.bQARxStart == FALSE)
+               {
+                       // Disable Rx
+                       RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+                       Value &= ~(1 << 3);
+                       RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+               }
+
+               if (pAd->ate.bQATxStart == TRUE)
+               {
+                       pAd->ate.TxStatus = 1;
+                       //pAd->ate.Repeat = 0;
+               }
+#else
+               // Disable Rx
+               RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+               Value &= ~(1 << 3);
+               RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+#endif // RALINK_28xx_QA //
+
+               // Enable Tx
+               RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+               Value |= (1 << 2);
+               RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+        SetJapanFilter(pAd);
+
+               // Abort Tx, RX DMA.
+               RtmpDmaEnable(pAd, 0);
+
+               pAd->ate.TxDoneCount = 0;
+
+        // Setup frame format
+               ATESetUpFrame(pAd, 0);
+
+               // Start Tx, RX DMA.
+               RtmpDmaEnable(pAd, 1);
+
+               // Check count is continuous or not yet.
+               //
+               // Due to the type mismatch between "pAd->BulkOutRemained"(atomic_t) and "pAd->ate.TxCount"(UINT32)
+               //
+               if (pAd->ate.TxCount == 0)
+               {
+                       InterlockedExchange(&pAd->BulkOutRemained, 0);
+               }
+               else
+               {
+                       InterlockedExchange(&pAd->BulkOutRemained, pAd->ate.TxCount);
+               }
+               ATEDBGPRINT(RT_DEBUG_TRACE, ("bulk out count = %d\n", atomic_read(&pAd->BulkOutRemained)));
+               ASSERT((atomic_read(&pAd->BulkOutRemained) >= 0));
+
+               if (atomic_read(&pAd->BulkOutRemained) == 0)
+               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("Send packet countinuously\n"));
+
+                       /* In 28xx, NdisAcquireSpinLock() == spin_lock_bh() */
+                       /* NdisAcquireSpinLock only need one argument in 28xx. */
+                       NdisAcquireSpinLock(&pAd->GenericLock);
+                       pAd->ContinBulkOut = TRUE;
+                       NdisReleaseSpinLock(&pAd->GenericLock);
+
+                       /* In 28xx, BULK_OUT_LOCK() == spin_lock_irqsave() */
+                       BULK_OUT_LOCK(&pAd->BulkOutLock[0], IrqFlags);// peter : NdisAcquireSpinLock ==> BULK_OUT_LOCK
+                       pAd->BulkOutPending[0] = FALSE;
+                       BULK_OUT_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);// peter : NdisAcquireSpinLock ==> BULK_OUT_LOCK
+               }
+               else
+               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("Send packets depend on counter\n"));
+
+                       NdisAcquireSpinLock(&pAd->GenericLock);
+                       pAd->ContinBulkOut = FALSE;
+                       NdisReleaseSpinLock(&pAd->GenericLock);
+
+                       BULK_OUT_LOCK(&pAd->BulkOutLock[0], IrqFlags);
+                       pAd->BulkOutPending[0] = FALSE;
+                       BULK_OUT_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
+               }
+
+               RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+
+               // Kick bulk out
+               RTUSBKickBulkOut(pAd);
+       }
+#ifdef RALINK_28xx_QA
+       else if (!strcmp(arg, "TXSTOP"))                //Enter ATE mode and set Tx/Rx Idle
+       {
+               ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXSTOP\n"));
+
+               atemode = pAd->ate.Mode;
+               pAd->ate.Mode &= ATE_TXSTOP;
+               pAd->ate.bQATxStart = FALSE;
+//             pAd->ate.TxDoneCount = pAd->ate.TxCount;
+
+/*=========================================================================*/
+               if (atemode & ATE_TXCARR)
+               {
+                       // No Carrier Test set BBP R22 bit7=0, bit6=0, bit[5~0]=0x0
+                       ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+                       BbpData &= 0xFFFFFF00; //clear bit7, bit6, bit[5~0]
+                   ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+               }
+               else if (atemode & ATE_TXCARRSUPP)
+               {
+                       // No Cont. TX set BBP R22 bit7=0
+                       ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+                       BbpData &= ~(1 << 7); //set bit7=0
+                       ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+
+                       // No Carrier Suppression set BBP R24 bit0=0
+                       ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R24, &BbpData);
+                       BbpData &= 0xFFFFFFFE; //clear bit0
+                   ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, BbpData);
+               }
+               else if ((atemode & ATE_TXFRAME) || (atemode == ATE_STOP))
+               {
+                       if (atemode & ATE_TXCONT)
+                       {
+                               // No Cont. TX set BBP R22 bit7=0
+                               ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+                               BbpData &= ~(1 << 7); //set bit7=0
+                               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+                       }
+               }
+
+/*=========================================================================*/
+               RTUSBRejectPendingPackets(pAd);
+               RTUSBCleanUpDataBulkOutQueue(pAd);
+
+               /* not used in RT28xx */
+               //RTUSBCleanUpMLMEWaitQueue(pAd);
+               /* empty function so far */
+               RTUSBCleanUpMLMEBulkOutQueue(pAd);
+/*=========================================================================*/
+               // Abort Tx, RX DMA.
+               RtmpDmaEnable(pAd, 0);
+/*=========================================================================*/
+
+               /* In 28xx, pAd->PendingRx is not of type atomic_t anymore */
+//             while ((atomic_read(&pAd->PendingRx) > 0))      //pAd->BulkFlags != 0 wait bulk out finish
+               /* peter todo : BulkInLock */
+               while (pAd->PendingRx > 0)
+               {
+#if 1
+                       ATE_RTUSBCancelPendingBulkInIRP(pAd);
+#else
+//                     NdisInterlockedDecrement(&pAd->PendingRx);
+                       pAd->PendingRx--;
+#endif
+                       RTMPusecDelay(500000);
+               }
+
+               while (((pAd->BulkOutPending[0] == TRUE) ||
+                               (pAd->BulkOutPending[1] == TRUE) ||
+                               (pAd->BulkOutPending[2] == TRUE) ||
+                               (pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0))     //pAd->BulkFlags != 0 wait bulk out finish
+               {
+                       do
+                       {
+                               RTUSBCancelPendingBulkOutIRP(pAd);
+                       } while (FALSE);
+
+                       RTMPusecDelay(500000);
+               }
+
+               ASSERT(pAd->PendingRx == 0);
+/*=========================================================================*/
+               // Enable Tx, Rx DMA.
+               RtmpDmaEnable(pAd, 1);
+
+               /* task Tx status : 0 --> task is idle, 1 --> task is running */
+               pAd->ate.TxStatus = 0;
+
+               // Soft reset BBP.
+               BbpSoftReset(pAd);
+
+               // Disable Tx
+               RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+               MacData &= (0xfffffffb);
+               RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+
+               //Clean ATE Bulk in/out counter and continue setup
+               InterlockedExchange(&pAd->BulkOutRemained, 0);
+
+               pAd->ContinBulkOut = FALSE;
+       }
+       else if (!strcmp(arg, "RXSTOP"))
+       {
+               ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: RXSTOP\n"));
+               atemode = pAd->ate.Mode;
+
+               // Disable Rx
+               RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+               Value &= ~(1 << 3);
+               RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+               pAd->ate.Mode &= ATE_RXSTOP;
+               pAd->ate.bQARxStart = FALSE;
+//             pAd->ate.TxDoneCount = pAd->ate.TxCount;
+
+/*=========================================================================*/
+               RTUSBRejectPendingPackets(pAd);
+               RTUSBCleanUpDataBulkOutQueue(pAd);
+
+               /* not used in RT28xx */
+               //RTUSBCleanUpMLMEWaitQueue(pAd);
+               RTUSBCleanUpMLMEBulkOutQueue(pAd);
+/*=========================================================================*/
+
+               // Abort Tx, RX DMA.
+               RtmpDmaEnable(pAd, 0);
+/*=========================================================================*/
+//             while ((atomic_read(&pAd->PendingRx) > 0))
+               while (pAd->PendingRx > 0)
+               {
+#if 1
+                       ATE_RTUSBCancelPendingBulkInIRP(pAd);
+#else
+//                     NdisInterlockedDecrement(&pAd->PendingRx);
+                       pAd->PendingRx--;
+#endif
+                       RTMPusecDelay(500000);
+               }
+
+               while (((pAd->BulkOutPending[0] == TRUE) ||
+                               (pAd->BulkOutPending[1] == TRUE) ||
+                               (pAd->BulkOutPending[2] == TRUE) ||
+                               (pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0))     //pAd->BulkFlags != 0 wait bulk out finish
+               {
+                       do
+                       {
+                               RTUSBCancelPendingBulkOutIRP(pAd);
+                       } while (FALSE);
+
+                       RTMPusecDelay(500000);
+               }
+
+               ASSERT(pAd->PendingRx == 0);
+/*=========================================================================*/
+
+               // Soft reset BBP.
+               BbpSoftReset(pAd);
+               pAd->ContinBulkIn = FALSE;
+       }
+#endif // RALINK_28xx_QA //
+       else if (!strcmp(arg, "RXFRAME")) // Rx Frames
+       {
+               ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: RXFRAME\n"));
+
+               // Disable Rx of MAC block
+               RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+               Value &= ~(1 << 3);
+               RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+               // Default value in BBP R22 is 0x0.
+               BbpData = 0;
+
+               RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+               // Clean bit4 to stop continuous Tx production test.
+               MacData &= 0xFFFFFFEF;
+
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+               RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+
+               pAd->ate.Mode |= ATE_RXFRAME;
+
+               // Abort Tx, RX DMA.
+               RtmpDmaEnable(pAd, 0);
+
+               // Disable TX of MAC block
+               RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+               Value &= ~(1 << 2);
+               RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+        // Reset Rx RING.
+               for ( i = 0; i < (RX_RING_SIZE); i++)
+               {
+                       PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
+
+                       pRxContext->InUse = FALSE;
+                       pRxContext->IRPPending = FALSE;
+                       pRxContext->Readable = FALSE;
+
+                       //
+                       // Get the urb from kernel back to driver.
+                       //
+                       RTUSB_UNLINK_URB(pRxContext->pUrb);
+
+                       /* Sleep 200 microsecs to give cancellation time to work. */
+                       NdisMSleep(200);
+                       pAd->BulkInReq = 0;
+
+//                     InterlockedExchange(&pAd->PendingRx, 0);
+                       pAd->PendingRx = 0;
+                       pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
+                       pAd->NextRxBulkInIndex          = RX_RING_SIZE - 1;     // Rx Bulk pointer
+                       pAd->NextRxBulkInPosition = 0;
+               }
+
+               // read to clear counters
+               RTUSBReadMACRegister(pAd, RX_STA_CNT0, &temp); //RX PHY & RX CRC count
+               RTUSBReadMACRegister(pAd, RX_STA_CNT1, &temp); //RX PLCP error count & CCA false alarm count
+               RTUSBReadMACRegister(pAd, RX_STA_CNT2, &temp); //RX FIFO overflow frame count & RX duplicated filtered frame count
+
+               pAd->ContinBulkIn = TRUE;
+
+               // Enable Tx, RX DMA.
+               RtmpDmaEnable(pAd, 1);
+
+               // Enable RX of MAC block
+               RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+               Value |= (1 << 3);
+               RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+               // Kick bulk in
+               RTUSBBulkReceive(pAd);
+       }
+       else
+       {
+               ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: Invalid arg!\n"));
+               return FALSE;
+       }
+       RTMPusecDelay(5000);
+
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("<=== ATECmdHandler()\n"));
+
+       return TRUE;
+}
+#endif // RT2870 //
+
+INT    Set_ATE_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+       if (ATECmdHandler(pAd, arg))
+       {
+               ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_Proc Success\n"));
+
+
+               return TRUE;
+       }
+       else
+       {
+               ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_Proc Failed\n"));
+               return FALSE;
+       }
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE ADDR1=DA for TxFrame(AP  : To DS = 0 ; From DS = 1)
+        or
+        Set ATE ADDR3=DA for TxFrame(STA : To DS = 1 ; From DS = 0)
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT    Set_ATE_DA_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+       CHAR                            *value;
+       INT                                     i;
+
+       if(strlen(arg) != 17)  //Mac address acceptable format 01:02:03:04:05:06 length 17
+               return FALSE;
+
+    for (i=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
+       {
+               if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
+                       return FALSE;  //Invalid
+
+
+#ifdef CONFIG_STA_SUPPORT
+               AtoH(value, &pAd->ate.Addr3[i++], 1);
+#endif // CONFIG_STA_SUPPORT //
+       }
+
+       if(i != 6)
+               return FALSE;  //Invalid
+
+
+#ifdef CONFIG_STA_SUPPORT
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_DA_Proc (DA = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAd->ate.Addr3[0],
+               pAd->ate.Addr3[1], pAd->ate.Addr3[2], pAd->ate.Addr3[3], pAd->ate.Addr3[4], pAd->ate.Addr3[5]));
+#endif // CONFIG_STA_SUPPORT //
+
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_DA_Proc Success\n"));
+
+       return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE ADDR3=SA for TxFrame(AP  : To DS = 0 ; From DS = 1)
+        or
+        Set ATE ADDR2=SA for TxFrame(STA : To DS = 1 ; From DS = 0)
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT    Set_ATE_SA_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+       CHAR                            *value;
+       INT                                     i;
+
+       if(strlen(arg) != 17)  //Mac address acceptable format 01:02:03:04:05:06 length 17
+               return FALSE;
+
+    for (i=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
+       {
+               if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
+                       return FALSE;  //Invalid
+
+
+#ifdef CONFIG_STA_SUPPORT
+               AtoH(value, &pAd->ate.Addr2[i++], 1);
+#endif // CONFIG_STA_SUPPORT //
+       }
+
+       if(i != 6)
+               return FALSE;  //Invalid
+
+
+#ifdef CONFIG_STA_SUPPORT
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_SA_Proc (SA = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAd->ate.Addr2[0],
+               pAd->ate.Addr2[1], pAd->ate.Addr2[2], pAd->ate.Addr2[3], pAd->ate.Addr2[4], pAd->ate.Addr2[5]));
+#endif // CONFIG_STA_SUPPORT //
+
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_SA_Proc Success\n"));
+
+       return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE ADDR2=BSSID for TxFrame(AP  : To DS = 0 ; From DS = 1)
+        or
+        Set ATE ADDR1=BSSID for TxFrame(STA : To DS = 1 ; From DS = 0)
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT    Set_ATE_BSSID_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+       CHAR                            *value;
+       INT                                     i;
+
+       if(strlen(arg) != 17)  //Mac address acceptable format 01:02:03:04:05:06 length 17
+               return FALSE;
+
+    for (i=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
+       {
+               if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
+                       return FALSE;  //Invalid
+
+
+#ifdef CONFIG_STA_SUPPORT
+               AtoH(value, &pAd->ate.Addr1[i++], 1);
+#endif // CONFIG_STA_SUPPORT //
+       }
+
+       if(i != 6)
+               return FALSE;  //Invalid
+
+
+#ifdef CONFIG_STA_SUPPORT
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_BSSID_Proc (BSSID = %2X:%2X:%2X:%2X:%2X:%2X)\n",  pAd->ate.Addr1[0],
+               pAd->ate.Addr1[1], pAd->ate.Addr1[2], pAd->ate.Addr1[3], pAd->ate.Addr1[4], pAd->ate.Addr1[5]));
+#endif // CONFIG_STA_SUPPORT //
+
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_BSSID_Proc Success\n"));
+
+       return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE Tx Channel
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT    Set_ATE_CHANNEL_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+       UCHAR channel;
+
+       channel = simple_strtol(arg, 0, 10);
+
+       if ((channel < 1) || (channel > 216))// to allow A band channel : ((channel < 1) || (channel > 14))
+       {
+               ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_CHANNEL_Proc::Out of range, it should be in range of 1~14.\n"));
+               return FALSE;
+       }
+       pAd->ate.Channel = channel;
+
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_CHANNEL_Proc (ATE Channel = %d)\n", pAd->ate.Channel));
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_CHANNEL_Proc Success\n"));
+
+
+       return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE Tx Power0
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT    Set_ATE_TX_POWER0_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+       CHAR TxPower;
+
+       TxPower = simple_strtol(arg, 0, 10);
+
+       if (pAd->ate.Channel <= 14)
+       {
+               if ((TxPower > 31) || (TxPower < 0))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER0_Proc::Out of range (Value=%d)\n", TxPower));
+                       return FALSE;
+               }
+       }
+       else// 5.5GHz
+       {
+               if ((TxPower > 15) || (TxPower < -7))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER0_Proc::Out of range (Value=%d)\n", TxPower));
+                       return FALSE;
+               }
+       }
+
+       pAd->ate.TxPower0 = TxPower;
+       ATETxPwrHandler(pAd, 0);
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_POWER0_Proc Success\n"));
+
+
+       return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE Tx Power1
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT    Set_ATE_TX_POWER1_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+       CHAR TxPower;
+
+       TxPower = simple_strtol(arg, 0, 10);
+
+       if (pAd->ate.Channel <= 14)
+       {
+       if ((TxPower > 31) || (TxPower < 0))
+       {
+               ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER1_Proc::Out of range (Value=%d)\n", TxPower));
+               return FALSE;
+       }
+       }
+       else
+       {
+               if ((TxPower > 15) || (TxPower < -7))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER1_Proc::Out of range (Value=%d)\n", TxPower));
+                       return FALSE;
+               }
+       }
+
+       pAd->ate.TxPower1 = TxPower;
+       ATETxPwrHandler(pAd, 1);
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_POWER1_Proc Success\n"));
+
+
+       return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE Tx Antenna
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT    Set_ATE_TX_Antenna_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+       CHAR value;
+
+       value = simple_strtol(arg, 0, 10);
+
+       if ((value > 2) || (value < 0))
+       {
+               ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_Antenna_Proc::Out of range (Value=%d)\n", value));
+               return FALSE;
+       }
+
+       pAd->ate.TxAntennaSel = value;
+
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_Antenna_Proc (Antenna = %d)\n", pAd->ate.TxAntennaSel));
+       ATEDBGPRINT(RT_DEBUG_TRACE,("Ralink: Set_ATE_TX_Antenna_Proc Success\n"));
+
+
+       return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE Rx Antenna
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT    Set_ATE_RX_Antenna_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+       CHAR value;
+
+       value = simple_strtol(arg, 0, 10);
+
+       if ((value > 3) || (value < 0))
+       {
+               ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_RX_Antenna_Proc::Out of range (Value=%d)\n", value));
+               return FALSE;
+       }
+
+       pAd->ate.RxAntennaSel = value;
+
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_RX_Antenna_Proc (Antenna = %d)\n", pAd->ate.RxAntennaSel));
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_RX_Antenna_Proc Success\n"));
+
+
+       return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE RF frequence offset
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT    Set_ATE_TX_FREQOFFSET_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+       UCHAR RFFreqOffset;
+       ULONG R4;
+
+       RFFreqOffset = simple_strtol(arg, 0, 10);
+#ifndef RT30xx
+       if(RFFreqOffset >= 64)
+#endif // RT30xx //
+#ifdef RT30xx
+//2008/08/06: KH modified the limit of offset value from 65 to 95(0x5F)
+       if(RFFreqOffset >= 95)
+#endif // RT30xx //
+       {
+               ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_FREQOFFSET_Proc::Out of range, it should be in range of 0~63.\n"));
+               return FALSE;
+       }
+
+       pAd->ate.RFFreqOffset = RFFreqOffset;
+#ifdef RT30xx
+       if(IS_RT30xx(pAd))
+       {
+               // Set RF offset
+               UCHAR RFValue;
+               RT30xxReadRFRegister(pAd, RF_R23, (PUCHAR)&RFValue);
+                               //2008/08/06: KH modified "pAd->RFFreqOffset" to "pAd->ate.RFFreqOffset"
+                               RFValue = (RFValue & 0x80) | pAd->ate.RFFreqOffset;
+               RT30xxWriteRFRegister(pAd, RF_R23, (UCHAR)RFValue);
+       }
+       else
+#endif // RT30xx //
+       {
+
+               R4 = pAd->ate.RFFreqOffset << 15;               // shift TX power control to correct RF register bit position
+               R4 |= (pAd->LatchRfRegs.R4 & ((~0x001f8000)));
+               pAd->LatchRfRegs.R4 = R4;
+
+               RtmpRfIoWrite(pAd);
+       }
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_FREQOFFSET_Proc (RFFreqOffset = %d)\n", pAd->ate.RFFreqOffset));
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_FREQOFFSET_Proc Success\n"));
+
+
+       return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE RF BW
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT    Set_ATE_TX_BW_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+       int i;
+       UCHAR value = 0;
+       UCHAR BBPCurrentBW;
+
+       BBPCurrentBW = simple_strtol(arg, 0, 10);
+
+       if(BBPCurrentBW == 0)
+               pAd->ate.TxWI.BW = BW_20;
+       else
+               pAd->ate.TxWI.BW = BW_40;
+
+       if(pAd->ate.TxWI.BW == BW_20)
+       {
+               if(pAd->ate.Channel <= 14)
+               {
+               for (i=0; i<5; i++)
+               {
+                               if (pAd->Tx20MPwrCfgGBand[i] != 0xffffffff)
+                               {
+                                       RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx20MPwrCfgGBand[i]);
+                                       RTMPusecDelay(5000);
+                               }
+                       }
+               }
+               else
+               {
+                       for (i=0; i<5; i++)
+                       {
+                               if (pAd->Tx20MPwrCfgABand[i] != 0xffffffff)
+                       {
+                                       RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx20MPwrCfgABand[i]);
+                               RTMPusecDelay(5000);
+                       }
+               }
+               }
+
+               //Set BBP R4 bit[4:3]=0:0
+               ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &value);
+               value &= (~0x18);
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value);
+
+               //Set BBP R66=0x3C
+               value = 0x3C;
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, value);
+               //Set BBP R68=0x0B
+               //to improve Rx sensitivity.
+               value = 0x0B;
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R68, value);
+               //Set BBP R69=0x16
+               value = 0x16;
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, value);
+               //Set BBP R70=0x08
+               value = 0x08;
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, value);
+               //Set BBP R73=0x11
+               value = 0x11;
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, value);
+
+           // If Channel=14, Bandwidth=20M and Mode=CCK, Set BBP R4 bit5=1
+           // (Japan filter coefficients)
+           // This segment of code will only works when ATETXMODE and ATECHANNEL
+           // were set to MODE_CCK and 14 respectively before ATETXBW is set to 0.
+           //=====================================================================
+               if (pAd->ate.Channel == 14)
+               {
+                       int TxMode = pAd->ate.TxWI.PHYMODE;
+                       if (TxMode == MODE_CCK)
+                       {
+                               // when Channel==14 && Mode==CCK && BandWidth==20M, BBP R4 bit5=1
+                               ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &value);
+                               value |= 0x20; //set bit5=1
+                               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value);
+                       }
+               }
+
+           //=====================================================================
+               // If bandwidth != 40M, RF Reg4 bit 21 = 0.
+#ifdef RT30xx
+       // Set BW
+               if(IS_RT30xx(pAd))
+                       RT30xxWriteRFRegister(pAd, RF_R24, (UCHAR) pAd->Mlme.CaliBW20RfR24);
+               else
+#endif // RT30xx //
+               {
+               pAd->LatchRfRegs.R4 &= ~0x00200000;
+               RtmpRfIoWrite(pAd);
+       }
+
+       }
+       else if(pAd->ate.TxWI.BW == BW_40)
+       {
+               if(pAd->ate.Channel <= 14)
+               {
+                       for (i=0; i<5; i++)
+                       {
+                               if (pAd->Tx40MPwrCfgGBand[i] != 0xffffffff)
+                               {
+                                       RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx40MPwrCfgGBand[i]);
+                                       RTMPusecDelay(5000);
+                               }
+                       }
+               }
+               else
+               {
+                       for (i=0; i<5; i++)
+                       {
+                               if (pAd->Tx40MPwrCfgABand[i] != 0xffffffff)
+                               {
+                                       RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx40MPwrCfgABand[i]);
+                                       RTMPusecDelay(5000);
+                               }
+                       }
+#ifdef DOT11_N_SUPPORT
+                       if ((pAd->ate.TxWI.PHYMODE >= MODE_HTMIX) && (pAd->ate.TxWI.MCS == 7))
+                       {
+                       value = 0x28;
+                       ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R67, value);
+                       }
+#endif // DOT11_N_SUPPORT //
+               }
+
+               //Set BBP R4 bit[4:3]=1:0
+               ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &value);
+               value &= (~0x18);
+               value |= 0x10;
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value);
+
+               //Set BBP R66=0x3C
+               value = 0x3C;
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, value);
+               //Set BBP R68=0x0C
+               //to improve Rx sensitivity.
+               value = 0x0C;
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R68, value);
+               //Set BBP R69=0x1A
+               value = 0x1A;
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, value);
+               //Set BBP R70=0x0A
+               value = 0x0A;
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, value);
+               //Set BBP R73=0x16
+               value = 0x16;
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, value);
+
+               // If bandwidth = 40M, set RF Reg4 bit 21 = 1.
+#ifdef RT30xx
+       // Set BW
+               if(IS_RT30xx(pAd))
+                       RT30xxWriteRFRegister(pAd, RF_R24, (UCHAR) pAd->Mlme.CaliBW40RfR24);
+               else
+#endif // RT30xx //
+               {
+                       pAd->LatchRfRegs.R4 |= 0x00200000;
+                       RtmpRfIoWrite(pAd);
+               }
+       }
+
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_BW_Proc (BBPCurrentBW = %d)\n", pAd->ate.TxWI.BW));
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_BW_Proc Success\n"));
+
+
+       return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE Tx frame length
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT    Set_ATE_TX_LENGTH_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+       pAd->ate.TxLength = simple_strtol(arg, 0, 10);
+
+       if((pAd->ate.TxLength < 24) || (pAd->ate.TxLength > (MAX_FRAME_SIZE - 34/* == 2312 */)))
+       {
+               pAd->ate.TxLength = (MAX_FRAME_SIZE - 34/* == 2312 */);
+               ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_LENGTH_Proc::Out of range, it should be in range of 24~%d.\n", (MAX_FRAME_SIZE - 34/* == 2312 */)));
+               return FALSE;
+       }
+
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_LENGTH_Proc (TxLength = %d)\n", pAd->ate.TxLength));
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_LENGTH_Proc Success\n"));
+
+
+       return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE Tx frame count
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT    Set_ATE_TX_COUNT_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+       pAd->ate.TxCount = simple_strtol(arg, 0, 10);
+
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_COUNT_Proc (TxCount = %d)\n", pAd->ate.TxCount));
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_COUNT_Proc Success\n"));
+
+
+       return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE Tx frame MCS
+
+        Return:
+               TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT    Set_ATE_TX_MCS_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+       UCHAR MCS;
+       int result;
+
+       MCS = simple_strtol(arg, 0, 10);
+       result = CheckMCSValid(pAd->ate.TxWI.PHYMODE, MCS);
+
+       if (result != -1)
+       {
+               pAd->ate.TxWI.MCS = (UCHAR)MCS;
+       }
+       else
+       {
+               ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_MCS_Proc::Out of range, refer to rate table.\n"));
+               return FALSE;
+       }
+
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_MCS_Proc (MCS = %d)\n", pAd->ate.TxWI.MCS));
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_MCS_Proc Success\n"));
+
+
+       return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE Tx frame Mode
+        0: MODE_CCK
+        1: MODE_OFDM
+        2: MODE_HTMIX
+        3: MODE_HTGREENFIELD
+
+        Return:
+               TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT    Set_ATE_TX_MODE_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+       pAd->ate.TxWI.PHYMODE = simple_strtol(arg, 0, 10);
+
+       if(pAd->ate.TxWI.PHYMODE > 3)
+       {
+               pAd->ate.TxWI.PHYMODE = 0;
+               ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_MODE_Proc::Out of range. it should be in range of 0~3\n"));
+               ATEDBGPRINT(RT_DEBUG_ERROR, ("0: CCK, 1: OFDM, 2: HT_MIX, 3: HT_GREEN_FIELD.\n"));
+               return FALSE;
+       }
+
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_MODE_Proc (TxMode = %d)\n", pAd->ate.TxWI.PHYMODE));
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_MODE_Proc Success\n"));
+
+
+       return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE Tx frame GI
+
+        Return:
+               TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT    Set_ATE_TX_GI_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+       pAd->ate.TxWI.ShortGI = simple_strtol(arg, 0, 10);
+
+       if(pAd->ate.TxWI.ShortGI > 1)
+       {
+               pAd->ate.TxWI.ShortGI = 0;
+               ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_GI_Proc::Out of range\n"));
+               return FALSE;
+       }
+
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_GI_Proc (GI = %d)\n", pAd->ate.TxWI.ShortGI));
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_GI_Proc Success\n"));
+
+
+       return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+    ==========================================================================
+ */
+INT    Set_ATE_RX_FER_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+       pAd->ate.bRxFer = simple_strtol(arg, 0, 10);
+
+       if (pAd->ate.bRxFer == 1)
+       {
+               pAd->ate.RxCntPerSec = 0;
+               pAd->ate.RxTotalCnt = 0;
+       }
+
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_RX_FER_Proc (bRxFer = %d)\n", pAd->ate.bRxFer));
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_RX_FER_Proc Success\n"));
+
+
+       return TRUE;
+}
+
+INT Set_ATE_Read_RF_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+#ifdef RT30xx
+//2008/07/10:KH add to support RT30xx ATE<--
+       if(IS_RT30xx(pAd))
+       {
+                       /* modify by WY for Read RF Reg. error */
+               UCHAR RFValue;
+               INT index=0;
+               for (index = 0; index < 32; index++)
+               {
+                       RT30xxReadRFRegister(pAd, index, (PUCHAR)&RFValue);
+                       printk("R%d=%d\n",index,RFValue);
+               }
+       }
+       else
+//2008/07/10:KH add to support RT30xx ATE-->
+#endif // RT30xx //
+       {
+               ate_print(KERN_EMERG "R1 = %lx\n", pAd->LatchRfRegs.R1);
+               ate_print(KERN_EMERG "R2 = %lx\n", pAd->LatchRfRegs.R2);
+               ate_print(KERN_EMERG "R3 = %lx\n", pAd->LatchRfRegs.R3);
+               ate_print(KERN_EMERG "R4 = %lx\n", pAd->LatchRfRegs.R4);
+       }
+       return TRUE;
+}
+
+INT Set_ATE_Write_RF1_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+#ifdef RT30xx
+//2008/07/10:KH add to support 3070 ATE<--
+       if(IS_RT30xx(pAd))
+       {
+               printk("Warning!! RT30xx Don't Support\n");
+               return FALSE;
+
+       }
+       else
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RT30xx //
+       {
+               UINT32 value = simple_strtol(arg, 0, 16);
+
+               pAd->LatchRfRegs.R1 = value;
+               RtmpRfIoWrite(pAd);
+       }
+       return TRUE;
+
+}
+
+INT Set_ATE_Write_RF2_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+#ifdef RT30xx
+//2008/07/10:KH add to support 3070 ATE<--
+       if(IS_RT30xx(pAd))
+       {
+               printk("Warning!! RT30xx Don't Support\n");
+               return FALSE;
+
+       }
+       else
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RT30xx //
+       {
+               UINT32 value = simple_strtol(arg, 0, 16);
+
+               pAd->LatchRfRegs.R2 = value;
+               RtmpRfIoWrite(pAd);
+       }
+       return TRUE;
+}
+
+INT Set_ATE_Write_RF3_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+#ifdef RT30xx
+//2008/07/10:KH add to support 3070 ATE<--
+       if(IS_RT30xx(pAd))
+       {
+               printk("Warning!! RT30xx Don't Support\n");
+               return FALSE;
+
+       }
+       else
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RT30xx //
+       {
+               UINT32 value = simple_strtol(arg, 0, 16);
+
+               pAd->LatchRfRegs.R3 = value;
+               RtmpRfIoWrite(pAd);
+       }
+       return TRUE;
+}
+
+INT Set_ATE_Write_RF4_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+#ifdef RT30xx
+//2008/07/10:KH add to support 3070 ATE<--
+       if(IS_RT30xx(pAd))
+       {
+               printk("Warning!! RT30xx Don't Support\n");
+               return FALSE;
+
+       }
+       else
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RT30xx //
+       {
+               UINT32 value = simple_strtol(arg, 0, 16);
+
+               pAd->LatchRfRegs.R4 = value;
+               RtmpRfIoWrite(pAd);
+       }
+       return TRUE;
+}
+#ifdef RT30xx
+//2008/07/10:KH add to support 3070 ATE<--
+INT    SET_ATE_3070RF_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+       CHAR *this_char;
+       CHAR *value;
+       UINT32 Reg,RFValue;
+       if(IS_RT30xx(pAd))
+       {
+               printk("SET_ATE_3070RF_Proc=%s\n",arg);
+               this_char =arg;
+               if ((value = strchr(this_char, ':')) != NULL)
+                       *value++ = 0;
+               Reg= simple_strtol(this_char, 0, 16);
+               RFValue= simple_strtol(value, 0, 16);
+               printk("RF Reg[%d]=%d\n",Reg,RFValue);
+               RT30xxWriteRFRegister(pAd, Reg,RFValue);
+       }
+       else
+               printk("Warning!! Only 3070 Support\n");
+       return TRUE;
+}
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RT30xx //
+/*
+    ==========================================================================
+    Description:
+        Load and Write EEPROM from a binary file prepared in advance.
+
+        Return:
+               TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+#ifndef UCOS
+INT Set_ATE_Load_E2P_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+       BOOLEAN             ret = FALSE;
+       PUCHAR                  src = EEPROM_BIN_FILE_NAME;
+       struct file             *srcf;
+       INT32                   retval, orgfsuid, orgfsgid;
+       mm_segment_t    orgfs;
+       USHORT                  WriteEEPROM[(EEPROM_SIZE/2)];
+       UINT32                  FileLength = 0;
+       UINT32                  value = simple_strtol(arg, 0, 10);
+
+       ATEDBGPRINT(RT_DEBUG_ERROR, ("===> %s (value=%d)\n\n", __FUNCTION__, value));
+
+       if (value > 0)
+       {
+               /* zero the e2p buffer */
+               NdisZeroMemory((PUCHAR)WriteEEPROM, EEPROM_SIZE);
+
+               /* save uid and gid used for filesystem access.
+           ** set user and group to 0 (root)
+           */
+               orgfsuid = current->fsuid;
+               orgfsgid = current->fsgid;
+               /* as root */
+               current->fsuid = current->fsgid = 0;
+       orgfs = get_fs();
+       set_fs(KERNEL_DS);
+
+               do
+               {
+                       /* open the bin file */
+                       srcf = filp_open(src, O_RDONLY, 0);
+
+                       if (IS_ERR(srcf))
+                       {
+                               ate_print("%s - Error %ld opening %s\n", __FUNCTION__, -PTR_ERR(srcf), src);
+                               break;
+                       }
+
+                       /* the object must have a read method */
+                       if ((srcf->f_op == NULL) || (srcf->f_op->read == NULL))
+                       {
+                               ate_print("%s - %s does not have a read method\n", __FUNCTION__, src);
+                               break;
+                       }
+
+                       /* read the firmware from the file *.bin */
+                       FileLength = srcf->f_op->read(srcf,
+                                                                                 (PUCHAR)WriteEEPROM,
+                                                                                 EEPROM_SIZE,
+                                                                                 &srcf->f_pos);
+
+                       if (FileLength != EEPROM_SIZE)
+                       {
+                               ate_print("%s: error file length (=%d) in e2p.bin\n",
+                                          __FUNCTION__, FileLength);
+                               break;
+                       }
+                       else
+                       {
+                               /* write the content of .bin file to EEPROM */
+                               rt_ee_write_all(pAd, WriteEEPROM);
+                               ret = TRUE;
+                       }
+                       break;
+               } while(TRUE);
+
+               /* close firmware file */
+               if (IS_ERR(srcf))
+               {
+                               ;
+               }
+               else
+               {
+                       retval = filp_close(srcf, NULL);
+                       if (retval)
+                       {
+                               ATEDBGPRINT(RT_DEBUG_ERROR, ("--> Error %d closing %s\n", -retval, src));
+
+                       }
+               }
+
+               /* restore */
+               set_fs(orgfs);
+               current->fsuid = orgfsuid;
+               current->fsgid = orgfsgid;
+       }
+    ATEDBGPRINT(RT_DEBUG_ERROR, ("<=== %s (ret=%d)\n", __FUNCTION__, ret));
+
+    return ret;
+
+}
+#else
+INT Set_ATE_Load_E2P_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+       USHORT                  WriteEEPROM[(EEPROM_SIZE/2)];
+       struct iwreq    *wrq = (struct iwreq *)arg;
+
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("===> %s (wrq->u.data.length = %d)\n\n", __FUNCTION__, wrq->u.data.length));
+
+       if (wrq->u.data.length != EEPROM_SIZE)
+       {
+               ate_print("%s: error length (=%d) from host\n",
+                          __FUNCTION__, wrq->u.data.length);
+               return FALSE;
+       }
+       else/* (wrq->u.data.length == EEPROM_SIZE) */
+       {
+               /* zero the e2p buffer */
+               NdisZeroMemory((PUCHAR)WriteEEPROM, EEPROM_SIZE);
+
+               /* fill the local buffer */
+               NdisMoveMemory((PUCHAR)WriteEEPROM, wrq->u.data.pointer, wrq->u.data.length);
+
+               do
+               {
+                               /* write the content of .bin file to EEPROM */
+                               rt_ee_write_all(pAd, WriteEEPROM);
+
+               } while(FALSE);
+               }
+
+    ATEDBGPRINT(RT_DEBUG_TRACE, ("<=== %s\n", __FUNCTION__));
+
+    return TRUE;
+
+}
+#endif // !UCOS //
+
+INT Set_ATE_Read_E2P_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+       USHORT buffer[EEPROM_SIZE/2];
+       USHORT *p;
+       int i;
+
+       rt_ee_read_all(pAd, (USHORT *)buffer);
+       p = buffer;
+       for (i = 0; i < (EEPROM_SIZE/2); i++)
+       {
+               ate_print("%4.4x ", *p);
+               if (((i+1) % 16) == 0)
+                       ate_print("\n");
+               p++;
+       }
+       return TRUE;
+}
+
+INT    Set_ATE_Show_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+       ate_print("Mode=%d\n", pAd->ate.Mode);
+       ate_print("TxPower0=%d\n", pAd->ate.TxPower0);
+       ate_print("TxPower1=%d\n", pAd->ate.TxPower1);
+       ate_print("TxAntennaSel=%d\n", pAd->ate.TxAntennaSel);
+       ate_print("RxAntennaSel=%d\n", pAd->ate.RxAntennaSel);
+       ate_print("BBPCurrentBW=%d\n", pAd->ate.TxWI.BW);
+       ate_print("GI=%d\n", pAd->ate.TxWI.ShortGI);
+       ate_print("MCS=%d\n", pAd->ate.TxWI.MCS);
+       ate_print("TxMode=%d\n", pAd->ate.TxWI.PHYMODE);
+       ate_print("Addr1=%02x:%02x:%02x:%02x:%02x:%02x\n",
+               pAd->ate.Addr1[0], pAd->ate.Addr1[1], pAd->ate.Addr1[2], pAd->ate.Addr1[3], pAd->ate.Addr1[4], pAd->ate.Addr1[5]);
+       ate_print("Addr2=%02x:%02x:%02x:%02x:%02x:%02x\n",
+               pAd->ate.Addr2[0], pAd->ate.Addr2[1], pAd->ate.Addr2[2], pAd->ate.Addr2[3], pAd->ate.Addr2[4], pAd->ate.Addr2[5]);
+       ate_print("Addr3=%02x:%02x:%02x:%02x:%02x:%02x\n",
+               pAd->ate.Addr3[0], pAd->ate.Addr3[1], pAd->ate.Addr3[2], pAd->ate.Addr3[3], pAd->ate.Addr3[4], pAd->ate.Addr3[5]);
+       ate_print("Channel=%d\n", pAd->ate.Channel);
+       ate_print("TxLength=%d\n", pAd->ate.TxLength);
+       ate_print("TxCount=%u\n", pAd->ate.TxCount);
+       ate_print("RFFreqOffset=%d\n", pAd->ate.RFFreqOffset);
+       ate_print(KERN_EMERG "Set_ATE_Show_Proc Success\n");
+       return TRUE;
+}
+
+INT    Set_ATE_Help_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+       ate_print("ATE=ATESTART, ATESTOP, TXCONT, TXCARR, TXFRAME, RXFRAME\n");
+       ate_print("ATEDA\n");
+       ate_print("ATESA\n");
+       ate_print("ATEBSSID\n");
+       ate_print("ATECHANNEL, range:0~14(unless A band !)\n");
+       ate_print("ATETXPOW0, set power level of antenna 1.\n");
+       ate_print("ATETXPOW1, set power level of antenna 2.\n");
+       ate_print("ATETXANT, set TX antenna. 0:all, 1:antenna one, 2:antenna two.\n");
+       ate_print("ATERXANT, set RX antenna.0:all, 1:antenna one, 2:antenna two, 3:antenna three.\n");
+       ate_print("ATETXFREQOFFSET, set frequency offset, range 0~63\n");
+       ate_print("ATETXBW, set BandWidth, 0:20MHz, 1:40MHz.\n");
+       ate_print("ATETXLEN, set Frame length, range 24~%d\n", (MAX_FRAME_SIZE - 34/* == 2312 */));
+       ate_print("ATETXCNT, set how many frame going to transmit.\n");
+       ate_print("ATETXMCS, set MCS, reference to rate table.\n");
+       ate_print("ATETXMODE, set Mode 0:CCK, 1:OFDM, 2:HT-Mix, 3:GreenField, reference to rate table.\n");
+       ate_print("ATETXGI, set GI interval, 0:Long, 1:Short\n");
+       ate_print("ATERXFER, 0:disable Rx Frame error rate. 1:enable Rx Frame error rate.\n");
+       ate_print("ATERRF, show all RF registers.\n");
+       ate_print("ATEWRF1, set RF1 register.\n");
+       ate_print("ATEWRF2, set RF2 register.\n");
+       ate_print("ATEWRF3, set RF3 register.\n");
+       ate_print("ATEWRF4, set RF4 register.\n");
+       ate_print("ATELDE2P, load EEPROM from .bin file.\n");
+       ate_print("ATERE2P, display all EEPROM content.\n");
+       ate_print("ATESHOW, display all parameters of ATE.\n");
+       ate_print("ATEHELP, online help.\n");
+
+       return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+
+       AsicSwitchChannel() dedicated for ATE.
+
+    ==========================================================================
+*/
+VOID ATEAsicSwitchChannel(
+    IN PRTMP_ADAPTER pAd)
+{
+       UINT32 R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0, Value = 0;
+       CHAR TxPwer = 0, TxPwer2 = 0;
+       UCHAR index, BbpValue = 0, R66 = 0x30;
+       RTMP_RF_REGS *RFRegTable;
+       UCHAR Channel;
+
+#ifdef RALINK_28xx_QA
+       if ((pAd->ate.bQATxStart == TRUE) || (pAd->ate.bQARxStart == TRUE))
+       {
+               if (pAd->ate.Channel != pAd->LatchRfRegs.Channel)
+               {
+                       pAd->ate.Channel = pAd->LatchRfRegs.Channel;
+               }
+               return;
+       }
+       else
+#endif // RALINK_28xx_QA //
+       Channel = pAd->ate.Channel;
+
+       // Select antenna
+       AsicAntennaSelect(pAd, Channel);
+
+       // fill Tx power value
+       TxPwer = pAd->ate.TxPower0;
+       TxPwer2 = pAd->ate.TxPower1;
+#ifdef RT30xx
+//2008/07/10:KH add to support 3070 ATE<--
+
+       // The RF programming sequence is difference between 3xxx and 2xxx
+       // The 3070 is 1T1R. Therefore, we don't need to set the number of Tx/Rx path and the only job is to set the parameters of channels.
+       if (IS_RT30xx(pAd) && ((pAd->RfIcType == RFIC_3020) ||
+(pAd->RfIcType == RFIC_3021) || (pAd->RfIcType == RFIC_3022) ||
+(pAd->RfIcType == RFIC_2020)))
+       {
+               /* modify by WY for Read RF Reg. error */
+               UCHAR RFValue;
+
+               for (index = 0; index < NUM_OF_3020_CHNL; index++)
+               {
+                       if (Channel == FreqItems3020[index].Channel)
+                       {
+                               // Programming channel parameters
+                               RT30xxWriteRFRegister(pAd, RF_R02, FreqItems3020[index].N);
+                               RT30xxWriteRFRegister(pAd, RF_R03, FreqItems3020[index].K);
+
+                               RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RFValue);
+                               RFValue = (RFValue & 0xFC) | FreqItems3020[index].R;
+                               RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RFValue);
+
+                               // Set Tx Power
+                               RT30xxReadRFRegister(pAd, RF_R12, (PUCHAR)&RFValue);
+                               RFValue = (RFValue & 0xE0) | TxPwer;
+                               RT30xxWriteRFRegister(pAd, RF_R12, (UCHAR)RFValue);
+
+                               // Set RF offset
+                               RT30xxReadRFRegister(pAd, RF_R23, (PUCHAR)&RFValue);
+                               //2008/08/06: KH modified "pAd->RFFreqOffset" to "pAd->ate.RFFreqOffset"
+                               RFValue = (RFValue & 0x80) | pAd->ate.RFFreqOffset;
+                               RT30xxWriteRFRegister(pAd, RF_R23, (UCHAR)RFValue);
+
+                               // Set BW
+                               if (pAd->ate.TxWI.BW == BW_40)
+                               {
+                                       RFValue = pAd->Mlme.CaliBW40RfR24;
+                                       //DISABLE_11N_CHECK(pAd);
+                               }
+                               else
+                               {
+                                       RFValue = pAd->Mlme.CaliBW20RfR24;
+                               }
+                               RT30xxWriteRFRegister(pAd, RF_R24, (UCHAR)RFValue);
+
+                               // Enable RF tuning
+                               RT30xxReadRFRegister(pAd, RF_R07, (PUCHAR)&RFValue);
+                               RFValue = RFValue | 0x1;
+                               RT30xxWriteRFRegister(pAd, RF_R07, (UCHAR)RFValue);
+
+                               // latch channel for future usage.
+                               pAd->LatchRfRegs.Channel = Channel;
+
+                               break;
+                       }
+               }
+
+               DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
+                       Channel,
+                       pAd->RfIcType,
+                       TxPwer,
+                       TxPwer2,
+                       pAd->Antenna.field.TxPath,
+                       FreqItems3020[index].N,
+                       FreqItems3020[index].K,
+                       FreqItems3020[index].R));
+       }
+       else
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RT30xx //
+{
+       RFRegTable = RF2850RegTable;
+
+       switch (pAd->RfIcType)
+       {
+               /* But only 2850 and 2750 support 5.5GHz band... */
+               case RFIC_2820:
+               case RFIC_2850:
+               case RFIC_2720:
+               case RFIC_2750:
+
+                       for (index = 0; index < NUM_OF_2850_CHNL; index++)
+                       {
+                               if (Channel == RFRegTable[index].Channel)
+                               {
+                                       R2 = RFRegTable[index].R2;
+                                       if (pAd->Antenna.field.TxPath == 1)
+                                       {
+                                               R2 |= 0x4000;   // If TXpath is 1, bit 14 = 1;
+                                       }
+
+                                       if (pAd->Antenna.field.RxPath == 2)
+                                       {
+                                               switch (pAd->ate.RxAntennaSel)
+                                               {
+                                                       case 1:
+                                                               R2 |= 0x20040;
+                                                               ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+                                                               BbpValue &= 0xE4;
+                                                               BbpValue |= 0x00;
+                                                               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+                                                               break;
+                                                       case 2:
+                                                               R2 |= 0x10040;
+                                                               ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+                                                               BbpValue &= 0xE4;
+                                                               BbpValue |= 0x01;
+                                                               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+                                                               break;
+                                                       default:
+                                                               R2 |= 0x40;
+                                                               ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+                                                               BbpValue &= 0xE4;
+                                                               /* Only enable two Antenna to receive. */
+                                                               BbpValue |= 0x08;
+                                                               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+                                                               break;
+                                               }
+                                       }
+                                       else if (pAd->Antenna.field.RxPath == 1)
+                                       {
+                                               R2 |= 0x20040;  // write 1 to off RxPath
+                                       }
+
+                                       if (pAd->Antenna.field.TxPath == 2)
+                                       {
+                                               if (pAd->ate.TxAntennaSel == 1)
+                                               {
+                                                       R2 |= 0x4000;   // If TX Antenna select is 1 , bit 14 = 1; Disable Ant 2
+                                                       ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue);
+                                                       BbpValue &= 0xE7;               //11100111B
+                                                       ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue);
+                                               }
+                                               else if (pAd->ate.TxAntennaSel == 2)
+                                               {
+                                                       R2 |= 0x8000;   // If TX Antenna select is 2 , bit 15 = 1; Disable Ant 1
+                                                       ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue);
+                                                       BbpValue &= 0xE7;
+                                                       BbpValue |= 0x08;
+                                                       ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue);
+                                               }
+                                               else
+                                               {
+                                                       ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue);
+                                                       BbpValue &= 0xE7;
+                                                       BbpValue |= 0x10;
+                                                       ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue);
+                                               }
+                                       }
+                                       if (pAd->Antenna.field.RxPath == 3)
+                                       {
+                                               switch (pAd->ate.RxAntennaSel)
+                                               {
+                                                       case 1:
+                                                               R2 |= 0x20040;
+                                                               ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+                                                               BbpValue &= 0xE4;
+                                                               BbpValue |= 0x00;
+                                                               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+                                                               break;
+                                                       case 2:
+                                                               R2 |= 0x10040;
+                                                               ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+                                                               BbpValue &= 0xE4;
+                                                               BbpValue |= 0x01;
+                                                               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+                                                               break;
+                                                       case 3:
+                                                               R2 |= 0x30000;
+                                                               ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+                                                               BbpValue &= 0xE4;
+                                                               BbpValue |= 0x02;
+                                                               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+                                                               break;
+                                                       default:
+                                                               ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+                                                               BbpValue &= 0xE4;
+                                                               BbpValue |= 0x10;
+                                                               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+                                                               break;
+                                               }
+                                       }
+
+                                       if (Channel > 14)
+                                       {
+                                               // initialize R3, R4
+                                               R3 = (RFRegTable[index].R3 & 0xffffc1ff);
+                                               R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->ate.RFFreqOffset << 15);
+
+                        // According the Rory's suggestion to solve the middle range issue.
+                                               // 5.5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB
+                                               // R3
+                                               if ((TxPwer >= -7) && (TxPwer < 0))
+                                               {
+                                                       TxPwer = (7+TxPwer);
+                                                       TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
+                                                       R3 |= (TxPwer << 10);
+                                                       ATEDBGPRINT(RT_DEBUG_TRACE, ("ATEAsicSwitchChannel: TxPwer=%d \n", TxPwer));
+                                               }
+                                               else
+                                               {
+                                                       TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
+                                                       R3 |= (TxPwer << 10) | (1 << 9);
+                                               }
+
+                                               // R4
+                                               if ((TxPwer2 >= -7) && (TxPwer2 < 0))
+                                               {
+                                                       TxPwer2 = (7+TxPwer2);
+                                                       TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
+                                                       R4 |= (TxPwer2 << 7);
+                                                       ATEDBGPRINT(RT_DEBUG_TRACE, ("ATEAsicSwitchChannel: TxPwer2=%d \n", TxPwer2));
+                                               }
+                                               else
+                                               {
+                                                       TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
+                                                       R4 |= (TxPwer2 << 7) | (1 << 6);
+                                               }
+                                       }
+                                       else
+                                       {
+                                               R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); // set TX power0
+                                               R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->ate.RFFreqOffset << 15) | (TxPwer2 <<6);// Set freq offset & TxPwr1
+                                       }
+
+                                       // Based on BBP current mode before changing RF channel.
+                                       if (pAd->ate.TxWI.BW == BW_40)
+                                       {
+                                               R4 |=0x200000;
+                                       }
+
+                                       // Update variables
+                                       pAd->LatchRfRegs.Channel = Channel;
+                                       pAd->LatchRfRegs.R1 = RFRegTable[index].R1;
+                                       pAd->LatchRfRegs.R2 = R2;
+                                       pAd->LatchRfRegs.R3 = R3;
+                                       pAd->LatchRfRegs.R4 = R4;
+
+                                       RtmpRfIoWrite(pAd);
+
+                                       break;
+                               }
+                       }
+                       break;
+
+               default:
+                       break;
+       }
+}
+       // Change BBP setting during switch from a->g, g->a
+       if (Channel <= 14)
+       {
+           ULONG       TxPinCfg = 0x00050F0A;// 2007.10.09 by Brian : 0x0005050A ==> 0x00050F0A
+
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
+
+               /* For 1T/2R chip only... */
+           if (pAd->NicConfig2.field.ExternalLNAForG)
+           {
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
+           }
+           else
+           {
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
+           }
+
+        // According the Rory's suggestion to solve the middle range issue.
+               ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R86, &BbpValue);
+               ASSERT((BbpValue == 0x00));
+               if ((BbpValue != 0x00))
+               {
+                       ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x00);
+               }
+
+               // 5.5GHz band selection PIN, bit1 and bit2 are complement
+               RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
+               Value &= (~0x6);
+               Value |= (0x04);
+               RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
+
+        // Turn off unused PA or LNA when only 1T or 1R.
+               if (pAd->Antenna.field.TxPath == 1)
+               {
+                       TxPinCfg &= 0xFFFFFFF3;
+               }
+               if (pAd->Antenna.field.RxPath == 1)
+               {
+                       TxPinCfg &= 0xFFFFF3FF;
+               }
+
+               RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+       }
+       else
+       {
+           ULONG       TxPinCfg = 0x00050F05;//2007.10.09 by Brian : 0x00050505 ==> 0x00050F05
+
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
+
+        // According the Rory's suggestion to solve the middle range issue.
+               ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R86, &BbpValue);
+               ASSERT((BbpValue == 0x00));
+               if ((BbpValue != 0x00))
+               {
+                       ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x00);
+               }
+               ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R91, &BbpValue);
+               ASSERT((BbpValue == 0x04));
+
+               ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R92, &BbpValue);
+               ASSERT((BbpValue == 0x00));
+
+               // 5.5GHz band selection PIN, bit1 and bit2 are complement
+               RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
+               Value &= (~0x6);
+               Value |= (0x02);
+               RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
+
+        // Turn off unused PA or LNA when only 1T or 1R.
+               if (pAd->Antenna.field.TxPath == 1)
+               {
+                       TxPinCfg &= 0xFFFFFFF3;
+           }
+               if (pAd->Antenna.field.RxPath == 1)
+               {
+                       TxPinCfg &= 0xFFFFF3FF;
+               }
+
+               RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+       }
+
+    // R66 should be set according to Channel and use 20MHz when scanning
+       if (Channel <= 14)
+       {
+               // BG band
+               R66 = 0x2E + GET_LNA_GAIN(pAd);
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+       }
+       else
+       {
+               // 5.5 GHz band
+               if (pAd->ate.TxWI.BW == BW_20)
+               {
+                       R66 = (UCHAR)(0x32 + (GET_LNA_GAIN(pAd)*5)/3);
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+               }
+               else
+               {
+                       R66 = (UCHAR)(0x3A + (GET_LNA_GAIN(pAd)*5)/3);
+                       ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+               }
+       }
+
+       //
+       // On 11A, We should delay and wait RF/BBP to be stable
+       // and the appropriate time should be 1000 micro seconds
+       // 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.
+       //
+       RTMPusecDelay(1000);
+
+       if (Channel > 14)
+       {
+               // When 5.5GHz band the LSB of TxPwr will be used to reduced 7dB or not.
+               ATEDBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
+                                                                 Channel,
+                                                                 pAd->RfIcType,
+                                                                 pAd->Antenna.field.TxPath,
+                                                                 pAd->LatchRfRegs.R1,
+                                                                 pAd->LatchRfRegs.R2,
+                                                                 pAd->LatchRfRegs.R3,
+                                                                 pAd->LatchRfRegs.R4));
+       }
+       else
+       {
+               ATEDBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%u, Pwr1=%u, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
+                                                                 Channel,
+                                                                 pAd->RfIcType,
+                                                                 (R3 & 0x00003e00) >> 9,
+                                                                 (R4 & 0x000007c0) >> 6,
+                                                                 pAd->Antenna.field.TxPath,
+                                                                 pAd->LatchRfRegs.R1,
+                                                                 pAd->LatchRfRegs.R2,
+                                                                 pAd->LatchRfRegs.R3,
+                                                                 pAd->LatchRfRegs.R4));
+    }
+}
+
+//
+// In fact, no one will call this routine so far !
+//
+/*
+       ==========================================================================
+       Description:
+               Gives CCK TX rate 2 more dB TX power.
+               This routine works only in ATE mode.
+
+               calculate desired Tx power in RF R3.Tx0~5,      should consider -
+               0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
+               1. TxPowerPercentage
+               2. auto calibration based on TSSI feedback
+               3. extra 2 db for CCK
+               4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
+
+       NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
+               it should be called AFTER MlmeDynamicTxRateSwitching()
+       ==========================================================================
+ */
+VOID ATEAsicAdjustTxPower(
+       IN PRTMP_ADAPTER pAd)
+{
+       INT                     i, j;
+       CHAR            DeltaPwr = 0;
+       BOOLEAN         bAutoTxAgc = FALSE;
+       UCHAR           TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
+       UCHAR           BbpR49 = 0, idx;
+       PCHAR           pTxAgcCompensate;
+       ULONG           TxPwr[5];
+       CHAR            Value;
+
+       /* no one calls this procedure so far */
+       if (pAd->ate.TxWI.BW == BW_40)
+       {
+               if (pAd->ate.Channel > 14)
+               {
+                       TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
+                       TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
+                       TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
+                       TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
+                       TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
+               }
+               else
+               {
+                       TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
+                       TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
+                       TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
+                       TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
+                       TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
+               }
+       }
+       else
+       {
+               if (pAd->ate.Channel > 14)
+               {
+                       TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
+                       TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
+                       TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
+                       TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
+                       TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
+               }
+               else
+               {
+                       TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
+                       TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
+                       TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
+                       TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
+                       TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
+               }
+       }
+
+       // TX power compensation for temperature variation based on TSSI.
+       // Do it per 4 seconds.
+       if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
+       {
+               if (pAd->ate.Channel <= 14)
+               {
+                       /* bg channel */
+                       bAutoTxAgc         = pAd->bAutoTxAgcG;
+                       TssiRef            = pAd->TssiRefG;
+                       pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
+                       pTssiPlusBoundary  = &pAd->TssiPlusBoundaryG[0];
+                       TxAgcStep          = pAd->TxAgcStepG;
+                       pTxAgcCompensate   = &pAd->TxAgcCompensateG;
+               }
+               else
+               {
+                       /* a channel */
+                       bAutoTxAgc         = pAd->bAutoTxAgcA;
+                       TssiRef            = pAd->TssiRefA;
+                       pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
+                       pTssiPlusBoundary  = &pAd->TssiPlusBoundaryA[0];
+                       TxAgcStep          = pAd->TxAgcStepA;
+                       pTxAgcCompensate   = &pAd->TxAgcCompensateA;
+               }
+
+               if (bAutoTxAgc)
+               {
+                       /* BbpR49 is unsigned char */
+                       ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
+
+                       /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
+                       /* compensate: +4     +3   +2   +1    0   -1   -2   -3   -4 * steps */
+                       /* step value is defined in pAd->TxAgcStepG for tx power value */
+
+                       /* [4]+1+[4]   p4     p3   p2   p1   o1   m1   m2   m3   m4 */
+                       /* ex:         0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
+                          above value are examined in mass factory production */
+                       /*             [4]    [3]  [2]  [1]  [0]  [1]  [2]  [3]  [4] */
+
+                       /* plus is 0x10 ~ 0x40, minus is 0x60 ~ 0x90 */
+                       /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
+                       /* if value is 0x65, tx power will be -= TxAgcStep*(2-1) */
+
+                       if (BbpR49 > pTssiMinusBoundary[1])
+                       {
+                               // Reading is larger than the reference value.
+                               // Check for how large we need to decrease the Tx power.
+                               for (idx = 1; idx < 5; idx++)
+                               {
+                                       if (BbpR49 <= pTssiMinusBoundary[idx])  // Found the range
+                                               break;
+                               }
+                               // The index is the step we should decrease, idx = 0 means there is nothing to compensate
+//                             if (R3 > (ULONG) (TxAgcStep * (idx-1)))
+                                       *pTxAgcCompensate = -(TxAgcStep * (idx-1));
+//                             else
+//                                     *pTxAgcCompensate = -((UCHAR)R3);
+
+                               DeltaPwr += (*pTxAgcCompensate);
+                               ATEDBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
+                                       BbpR49, TssiRef, TxAgcStep, idx-1));
+                       }
+                       else if (BbpR49 < pTssiPlusBoundary[1])
+                       {
+                               // Reading is smaller than the reference value
+                               // check for how large we need to increase the Tx power
+                               for (idx = 1; idx < 5; idx++)
+                               {
+                                       if (BbpR49 >= pTssiPlusBoundary[idx])   // Found the range
+                                               break;
+                               }
+                               // The index is the step we should increase, idx = 0 means there is nothing to compensate
+                               *pTxAgcCompensate = TxAgcStep * (idx-1);
+                               DeltaPwr += (*pTxAgcCompensate);
+                               ATEDBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
+                                       BbpR49, TssiRef, TxAgcStep, idx-1));
+                       }
+                       else
+                       {
+                               *pTxAgcCompensate = 0;
+                               ATEDBGPRINT(RT_DEBUG_TRACE, ("   Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
+                                       BbpR49, TssiRef, TxAgcStep, 0));
+                       }
+               }
+       }
+       else
+       {
+               if (pAd->ate.Channel <= 14)
+               {
+                       bAutoTxAgc         = pAd->bAutoTxAgcG;
+                       pTxAgcCompensate   = &pAd->TxAgcCompensateG;
+               }
+               else
+               {
+                       bAutoTxAgc         = pAd->bAutoTxAgcA;
+                       pTxAgcCompensate   = &pAd->TxAgcCompensateA;
+               }
+
+               if (bAutoTxAgc)
+                       DeltaPwr += (*pTxAgcCompensate);
+       }
+
+       /* calculate delta power based on the percentage specified from UI */
+       // E2PROM setting is calibrated for maximum TX power (i.e. 100%)
+       // We lower TX power here according to the percentage specified from UI
+       if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff)       // AUTO TX POWER control
+               ;
+       else if (pAd->CommonCfg.TxPowerPercentage > 90)  // 91 ~ 100% & AUTO, treat as 100% in terms of mW
+               ;
+       else if (pAd->CommonCfg.TxPowerPercentage > 60)  // 61 ~ 90%, treat as 75% in terms of mW
+       {
+               DeltaPwr -= 1;
+       }
+       else if (pAd->CommonCfg.TxPowerPercentage > 30)  // 31 ~ 60%, treat as 50% in terms of mW
+       {
+               DeltaPwr -= 3;
+       }
+       else if (pAd->CommonCfg.TxPowerPercentage > 15)  // 16 ~ 30%, treat as 25% in terms of mW
+       {
+               DeltaPwr -= 6;
+       }
+       else if (pAd->CommonCfg.TxPowerPercentage > 9)   // 10 ~ 15%, treat as 12.5% in terms of mW
+       {
+               DeltaPwr -= 9;
+       }
+       else                                           // 0 ~ 9 %, treat as MIN(~3%) in terms of mW
+       {
+               DeltaPwr -= 12;
+       }
+
+       /* reset different new tx power for different TX rate */
+       for(i=0; i<5; i++)
+       {
+               if (TxPwr[i] != 0xffffffff)
+               {
+                       for (j=0; j<8; j++)
+                       {
+                               Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F); /* 0 ~ 15 */
+
+                               if ((Value + DeltaPwr) < 0)
+                               {
+                                       Value = 0; /* min */
+                               }
+                               else if ((Value + DeltaPwr) > 0xF)
+                               {
+                                       Value = 0xF; /* max */
+                               }
+                               else
+                               {
+                                       Value += DeltaPwr; /* temperature compensation */
+                               }
+
+                               /* fill new value to CSR offset */
+                               TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
+                       }
+
+                       /* write tx power value to CSR */
+                       /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M
+                                                                                       TX power for OFDM 6M/9M
+                                                                                       TX power for CCK5.5M/11M
+                                                                                       TX power for CCK1M/2M */
+                       /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
+                       RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, TxPwr[i]);
+
+
+               }
+       }
+
+}
+
+/*
+       ========================================================================
+       Routine Description:
+               Write TxWI for ATE mode.
+
+       Return Value:
+               None
+       ========================================================================
+*/
+
+#ifdef RT2870
+static VOID ATEWriteTxWI(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PTXWI_STRUC     pTxWI,
+       IN      BOOLEAN                 FRAG,
+       IN      BOOLEAN                 InsTimestamp,
+       IN      BOOLEAN                 AMPDU,
+       IN      BOOLEAN                 Ack,
+       IN      BOOLEAN                 NSeq,           // HW new a sequence.
+       IN      UCHAR                   BASize,
+       IN      UCHAR                   WCID,
+       IN      ULONG                   Length,
+       IN      UCHAR                   PID,
+       IN      UCHAR                   MIMOps,
+       IN      UCHAR                   Txopmode,
+       IN      BOOLEAN                 CfAck,
+       IN      HTTRANSMIT_SETTING      Transmit)
+{
+       //
+       // Always use Long preamble before verifiation short preamble functionality works well.
+       // Todo: remove the following line if short preamble functionality works
+       //
+       OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
+       pTxWI->FRAG= FRAG;
+       pTxWI->TS= InsTimestamp;
+       pTxWI->AMPDU = AMPDU;
+
+       pTxWI->MIMOps = PWR_ACTIVE;
+       pTxWI->MpduDensity = 4;
+       pTxWI->ACK = Ack;
+       pTxWI->txop = Txopmode;
+       pTxWI->NSEQ = NSeq;
+       pTxWI->BAWinSize = BASize;
+
+       pTxWI->WirelessCliID = WCID;
+       pTxWI->MPDUtotalByteCount = Length;
+       pTxWI->PacketId = PID;
+
+       pTxWI->BW = Transmit.field.BW;
+       pTxWI->ShortGI = Transmit.field.ShortGI;
+       pTxWI->STBC= Transmit.field.STBC;
+
+       pTxWI->MCS = Transmit.field.MCS;
+       pTxWI->PHYMODE= Transmit.field.MODE;
+
+#ifdef DOT11_N_SUPPORT
+       //
+       // MMPS is 802.11n features. Because TxWI->MCS > 7 must be HT mode,
+       // so need not check if it's HT rate.
+       //
+       if ((MIMOps == MMPS_STATIC) && (pTxWI->MCS > 7))
+               pTxWI->MCS = 7;
+
+       if ((MIMOps == MMPS_DYNAMIC) && (pTxWI->MCS > 7)) // SMPS protect 2 spatial.
+               pTxWI->MIMOps = 1;
+#endif // DOT11_N_SUPPORT //
+
+       pTxWI->CFACK = CfAck;
+
+       return;
+}
+#endif // RT2870 //
+/*
+       ========================================================================
+
+       Routine Description:
+               Disable protection for ATE.
+       ========================================================================
+*/
+VOID ATEDisableAsicProtect(
+       IN              PRTMP_ADAPTER   pAd)
+{
+       PROT_CFG_STRUC  ProtCfg, ProtCfg4;
+       UINT32 Protect[6];
+       USHORT                  offset;
+       UCHAR                   i;
+       UINT32 MacReg = 0;
+
+       // Config ASIC RTS threshold register
+       RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
+       MacReg &= 0xFF0000FF;
+       MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
+       RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
+
+       // Initial common protection settings
+       RTMPZeroMemory(Protect, sizeof(Protect));
+       ProtCfg4.word = 0;
+       ProtCfg.word = 0;
+       ProtCfg.field.TxopAllowGF40 = 1;
+       ProtCfg.field.TxopAllowGF20 = 1;
+       ProtCfg.field.TxopAllowMM40 = 1;
+       ProtCfg.field.TxopAllowMM20 = 1;
+       ProtCfg.field.TxopAllowOfdm = 1;
+       ProtCfg.field.TxopAllowCck = 1;
+       ProtCfg.field.RTSThEn = 1;
+       ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+
+       // Handle legacy(B/G) protection
+       ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
+       ProtCfg.field.ProtectCtrl = 0;
+       Protect[0] = ProtCfg.word;
+       Protect[1] = ProtCfg.word;
+
+       // NO PROTECT
+       // 1.All STAs in the BSS are 20/40 MHz HT
+       // 2. in ai 20/40MHz BSS
+       // 3. all STAs are 20MHz in a 20MHz BSS
+       // Pure HT. no protection.
+
+       // MM20_PROT_CFG
+       //      Reserved (31:27)
+       //      PROT_TXOP(25:20) -- 010111
+       //      PROT_NAV(19:18)  -- 01 (Short NAV protection)
+       //  PROT_CTRL(17:16) -- 00 (None)
+       //      PROT_RATE(15:0)  -- 0x4004 (OFDM 24M)
+       Protect[2] = 0x01744004;
+
+       // MM40_PROT_CFG
+       //      Reserved (31:27)
+       //      PROT_TXOP(25:20) -- 111111
+       //      PROT_NAV(19:18)  -- 01 (Short NAV protection)
+       //  PROT_CTRL(17:16) -- 00 (None)
+       //      PROT_RATE(15:0)  -- 0x4084 (duplicate OFDM 24M)
+       Protect[3] = 0x03f44084;
+
+       // CF20_PROT_CFG
+       //      Reserved (31:27)
+       //      PROT_TXOP(25:20) -- 010111
+       //      PROT_NAV(19:18)  -- 01 (Short NAV protection)
+       //  PROT_CTRL(17:16) -- 00 (None)
+       //      PROT_RATE(15:0)  -- 0x4004 (OFDM 24M)
+       Protect[4] = 0x01744004;
+
+       // CF40_PROT_CFG
+       //      Reserved (31:27)
+       //      PROT_TXOP(25:20) -- 111111
+       //      PROT_NAV(19:18)  -- 01 (Short NAV protection)
+       //  PROT_CTRL(17:16) -- 00 (None)
+       //      PROT_RATE(15:0)  -- 0x4084 (duplicate OFDM 24M)
+       Protect[5] = 0x03f44084;
+
+       pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
+
+       offset = CCK_PROT_CFG;
+       for (i = 0;i < 6;i++)
+               RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]);
+
+}
+
+#ifdef RT2870
+/*
+       ========================================================================
+       Routine Description:
+               Write TxInfo for ATE mode.
+
+       Return Value:
+               None
+       ========================================================================
+*/
+static VOID ATEWriteTxInfo(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PTXINFO_STRUC   pTxInfo,
+       IN      USHORT          USBDMApktLen,
+       IN      BOOLEAN         bWiv,
+       IN      UCHAR                   QueueSel,
+       IN      UCHAR                   NextValid,
+       IN      UCHAR                   TxBurst)
+{
+       pTxInfo->USBDMATxPktLen = USBDMApktLen;
+       pTxInfo->QSEL = QueueSel;
+
+       if (QueueSel != FIFO_EDCA)
+               ATEDBGPRINT(RT_DEBUG_TRACE, ("=======> QueueSel != FIFO_EDCA<=======\n"));
+
+       pTxInfo->USBDMANextVLD = NextValid;
+       pTxInfo->USBDMATxburst = TxBurst;
+       pTxInfo->WIV = bWiv;
+       pTxInfo->SwUseLastRound = 0;
+       pTxInfo->rsv = 0;
+       pTxInfo->rsv2 = 0;
+
+       return;
+}
+#endif // RT2870 //
+
+/* There are two ways to convert Rssi */
+#if 1
+//
+// The way used with GET_LNA_GAIN().
+//
+CHAR ATEConvertToRssi(
+       IN PRTMP_ADAPTER pAd,
+       IN      CHAR    Rssi,
+       IN  UCHAR   RssiNumber)
+{
+       UCHAR   RssiOffset, LNAGain;
+
+       // Rssi equals to zero should be an invalid value
+       if (Rssi == 0)
+               return -99;
+
+       LNAGain = GET_LNA_GAIN(pAd);
+       if (pAd->LatchRfRegs.Channel > 14)
+       {
+               if (RssiNumber == 0)
+                       RssiOffset = pAd->ARssiOffset0;
+               else if (RssiNumber == 1)
+                       RssiOffset = pAd->ARssiOffset1;
+               else
+                       RssiOffset = pAd->ARssiOffset2;
+       }
+       else
+       {
+               if (RssiNumber == 0)
+                       RssiOffset = pAd->BGRssiOffset0;
+               else if (RssiNumber == 1)
+                       RssiOffset = pAd->BGRssiOffset1;
+               else
+                       RssiOffset = pAd->BGRssiOffset2;
+       }
+
+       return (-12 - RssiOffset - LNAGain - Rssi);
+}
+#else
+//
+// The way originally used in ATE of rt2860ap.
+//
+CHAR ATEConvertToRssi(
+       IN PRTMP_ADAPTER pAd,
+       IN      CHAR                    Rssi,
+       IN  UCHAR   RssiNumber)
+{
+       UCHAR   RssiOffset, LNAGain;
+
+       // Rssi equals to zero should be an invalid value
+       if (Rssi == 0)
+               return -99;
+
+    if (pAd->LatchRfRegs.Channel > 14)
+    {
+        LNAGain = pAd->ALNAGain;
+        if (RssiNumber == 0)
+                       RssiOffset = pAd->ARssiOffset0;
+               else if (RssiNumber == 1)
+                       RssiOffset = pAd->ARssiOffset1;
+               else
+                       RssiOffset = pAd->ARssiOffset2;
+    }
+    else
+    {
+        LNAGain = pAd->BLNAGain;
+        if (RssiNumber == 0)
+                       RssiOffset = pAd->BGRssiOffset0;
+               else if (RssiNumber == 1)
+                       RssiOffset = pAd->BGRssiOffset1;
+               else
+                       RssiOffset = pAd->BGRssiOffset2;
+    }
+
+    return (-32 - RssiOffset + LNAGain - Rssi);
+}
+#endif /* end of #if 1 */
+
+/*
+       ========================================================================
+
+       Routine Description:
+               Set Japan filter coefficients if needed.
+       Note:
+               This routine should only be called when
+               entering TXFRAME mode or TXCONT mode.
+
+       ========================================================================
+*/
+static VOID SetJapanFilter(
+       IN              PRTMP_ADAPTER   pAd)
+{
+       UCHAR                   BbpData = 0;
+
+       //
+       // If Channel=14 and Bandwidth=20M and Mode=CCK, set BBP R4 bit5=1
+       // (Japan Tx filter coefficients)when (TXFRAME or TXCONT).
+       //
+       ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BbpData);
+
+    if ((pAd->ate.TxWI.PHYMODE == MODE_CCK) && (pAd->ate.Channel == 14) && (pAd->ate.TxWI.BW == BW_20))
+    {
+        BbpData |= 0x20;    // turn on
+        ATEDBGPRINT(RT_DEBUG_TRACE, ("SetJapanFilter!!!\n"));
+    }
+    else
+    {
+               BbpData &= 0xdf;    // turn off
+               ATEDBGPRINT(RT_DEBUG_TRACE, ("ClearJapanFilter!!!\n"));
+    }
+
+       ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BbpData);
+}
+
+VOID ATESampleRssi(
+       IN PRTMP_ADAPTER        pAd,
+       IN PRXWI_STRUC          pRxWI)
+{
+       /* There are two ways to collect RSSI. */
+#if 1
+       //pAd->LastRxRate = (USHORT)((pRxWI->MCS) + (pRxWI->BW <<7) + (pRxWI->ShortGI <<8)+ (pRxWI->PHYMODE <<14)) ;
+       if (pRxWI->RSSI0 != 0)
+       {
+               pAd->ate.LastRssi0      = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI0, RSSI_0);
+               pAd->ate.AvgRssi0X8     = (pAd->ate.AvgRssi0X8 - pAd->ate.AvgRssi0) + pAd->ate.LastRssi0;
+               pAd->ate.AvgRssi0       = pAd->ate.AvgRssi0X8 >> 3;
+       }
+       if (pRxWI->RSSI1 != 0)
+       {
+               pAd->ate.LastRssi1      = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI1, RSSI_1);
+               pAd->ate.AvgRssi1X8     = (pAd->ate.AvgRssi1X8 - pAd->ate.AvgRssi1) + pAd->ate.LastRssi1;
+               pAd->ate.AvgRssi1       = pAd->ate.AvgRssi1X8 >> 3;
+       }
+       if (pRxWI->RSSI2 != 0)
+       {
+               pAd->ate.LastRssi2      = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI2, RSSI_2);
+               pAd->ate.AvgRssi2X8     = (pAd->ate.AvgRssi2X8 - pAd->ate.AvgRssi2) + pAd->ate.LastRssi2;
+               pAd->ate.AvgRssi2       = pAd->ate.AvgRssi2X8 >> 3;
+       }
+
+       pAd->ate.LastSNR0 = (CHAR)(pRxWI->SNR0);// CHAR ==> UCHAR ?
+       pAd->ate.LastSNR1 = (CHAR)(pRxWI->SNR1);// CHAR ==> UCHAR ?
+
+       pAd->ate.NumOfAvgRssiSample ++;
+#else
+       pAd->ate.LastSNR0 = (CHAR)(pRxWI->SNR0);
+       pAd->ate.LastSNR1 = (CHAR)(pRxWI->SNR1);
+       pAd->ate.RxCntPerSec++;
+       pAd->ate.LastRssi0 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI0, RSSI_0);
+       pAd->ate.LastRssi1 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI1, RSSI_1);
+       pAd->ate.LastRssi2 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI2, RSSI_2);
+       pAd->ate.AvgRssi0X8 = (pAd->ate.AvgRssi0X8 - pAd->ate.AvgRssi0) + pAd->ate.LastRssi0;
+       pAd->ate.AvgRssi0 = pAd->ate.AvgRssi0X8 >> 3;
+       pAd->ate.AvgRssi1X8 = (pAd->ate.AvgRssi1X8 - pAd->ate.AvgRssi1) + pAd->ate.LastRssi1;
+       pAd->ate.AvgRssi1 = pAd->ate.AvgRssi1X8 >> 3;
+       pAd->ate.AvgRssi2X8 = (pAd->ate.AvgRssi2X8 - pAd->ate.AvgRssi2) + pAd->ate.LastRssi2;
+       pAd->ate.AvgRssi2 = pAd->ate.AvgRssi2X8 >> 3;
+       pAd->ate.NumOfAvgRssiSample ++;
+#endif
+}
+
+#ifdef CONFIG_STA_SUPPORT
+VOID RTMPStationStop(
+    IN  PRTMP_ADAPTER   pAd)
+{
+//     BOOLEAN       Cancelled;
+
+    ATEDBGPRINT(RT_DEBUG_TRACE, ("==> RTMPStationStop\n"));
+
+       // For rx statistics, we need to keep this timer running.
+//     RTMPCancelTimer(&pAd->Mlme.PeriodicTimer,      &Cancelled);
+
+    ATEDBGPRINT(RT_DEBUG_TRACE, ("<== RTMPStationStop\n"));
+}
+
+VOID RTMPStationStart(
+    IN  PRTMP_ADAPTER   pAd)
+{
+    ATEDBGPRINT(RT_DEBUG_TRACE, ("==> RTMPStationStart\n"));
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("<== RTMPStationStart\n"));
+}
+#endif // CONFIG_STA_SUPPORT //
+
+/*
+       ==========================================================================
+       Description:
+               Setup Frame format.
+       NOTE:
+               This routine should only be used in ATE mode.
+       ==========================================================================
+ */
+
+#ifdef RT2870
+/*======================Start of RT2870======================*/
+/*                                                           */
+/*                                                           */
+static INT ATESetUpFrame(
+       IN PRTMP_ADAPTER pAd,
+       IN UINT32 TxIdx)
+{
+       UINT j;
+       PTX_CONTEXT     pNullContext;
+       PUCHAR                  pDest;
+       HTTRANSMIT_SETTING      TxHTPhyMode;
+       PTXWI_STRUC             pTxWI;
+       PTXINFO_STRUC           pTxInfo;
+       UINT32                  TransferBufferLength, OrgBufferLength = 0;
+       UCHAR                   padLen = 0;
+#ifdef RALINK_28xx_QA
+       PHEADER_802_11  pHeader80211 = NULL;
+#endif // RALINK_28xx_QA //
+
+       if ((RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) ||
+               (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) ||
+               (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) ||
+               (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+       {
+               return -1;
+       }
+
+       /* We always use QID_AC_BE and FIFO_EDCA in ATE mode. */
+
+       pNullContext = &(pAd->NullContext);
+       ASSERT(pNullContext != NULL);
+
+       if (pNullContext->InUse == FALSE)
+       {
+               // Set the in use bit
+               pNullContext->InUse = TRUE;
+               NdisZeroMemory(&(pAd->NullFrame), sizeof(HEADER_802_11));
+
+               // Fill 802.11 header.
+#ifdef RALINK_28xx_QA
+               if (pAd->ate.bQATxStart == TRUE)
+               {
+                       pHeader80211 = NdisMoveMemory(&(pAd->NullFrame), pAd->ate.Header, pAd->ate.HLen);
+//                     pDest = NdisMoveMemory(&(pAd->NullFrame), pAd->ate.Header, pAd->ate.HLen);
+//                     pHeader80211 = (PHEADER_802_11)pDest;
+               }
+               else
+#endif // RALINK_28xx_QA //
+               {
+                       // Fill 802.11 header.
+                       NdisMoveMemory(&(pAd->NullFrame), TemplateFrame, sizeof(HEADER_802_11));
+               }
+#ifdef RT_BIG_ENDIAN
+               RTMPFrameEndianChange(pAd, (PUCHAR)&(pAd->NullFrame), DIR_READ, FALSE);
+#endif // RT_BIG_ENDIAN //
+
+#ifdef RALINK_28xx_QA
+               if (pAd->ate.bQATxStart == TRUE)
+               {
+                       /* modify sequence number.... */
+                       if (pAd->ate.TxDoneCount == 0)
+                       {
+                               pAd->ate.seq = pHeader80211->Sequence;
+                       }
+                       else
+                       {
+                               pHeader80211->Sequence = ++pAd->ate.seq;
+                       }
+                       /* We already got all the addr. fields from QA GUI. */
+               }
+               else
+#endif // RALINK_28xx_QA //
+               {
+                       COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->ate.Addr1);
+                       COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->ate.Addr2);
+                       COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->ate.Addr3);
+               }
+
+               RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[0], TX_BUFFER_NORMSIZE);//???
+               pTxInfo = (PTXINFO_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[0];
+
+#ifdef RALINK_28xx_QA
+               if (pAd->ate.bQATxStart == TRUE)
+               {
+                       // Avoid to exceed the range of WirelessPacket[].
+                       ASSERT(pAd->ate.TxInfo.USBDMATxPktLen <= (MAX_FRAME_SIZE - 34/* == 2312 */));
+                       NdisMoveMemory(pTxInfo, &(pAd->ate.TxInfo), sizeof(pAd->ate.TxInfo));
+               }
+               else
+#endif // RALINK_28xx_QA //
+               {
+                       // Avoid to exceed the range of WirelessPacket[].
+                       ASSERT(pAd->ate.TxLength <= (MAX_FRAME_SIZE - 34/* == 2312 */));
+
+                       // pTxInfo->USBDMATxPktLen will be updated to include padding later.
+                       ATEWriteTxInfo(pAd, pTxInfo, (USHORT)(TXWI_SIZE + pAd->ate.TxLength), TRUE, EpToQueue[MGMTPIPEIDX], FALSE,  FALSE);
+                       pTxInfo->QSEL = FIFO_EDCA;
+               }
+
+               pTxWI = (PTXWI_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
+
+               // Fill TxWI.
+               if (pAd->ate.bQATxStart == TRUE)
+               {
+                       TxHTPhyMode.field.BW = pAd->ate.TxWI.BW;
+                       TxHTPhyMode.field.ShortGI = pAd->ate.TxWI.ShortGI;
+                       TxHTPhyMode.field.STBC = pAd->ate.TxWI.STBC;
+                       TxHTPhyMode.field.MCS = pAd->ate.TxWI.MCS;
+                       TxHTPhyMode.field.MODE = pAd->ate.TxWI.PHYMODE;
+                       ATEWriteTxWI(pAd, pTxWI, pAd->ate.TxWI.FRAG, pAd->ate.TxWI.TS, pAd->ate.TxWI.AMPDU, pAd->ate.TxWI.ACK, pAd->ate.TxWI.NSEQ,
+                               pAd->ate.TxWI.BAWinSize, BSSID_WCID, pAd->ate.TxWI.MPDUtotalByteCount/* include 802.11 header */, pAd->ate.TxWI.PacketId, 0, pAd->ate.TxWI.txop/*IFS_HTTXOP*/, pAd->ate.TxWI.CFACK/*FALSE*/, TxHTPhyMode);
+               }
+               else
+               {
+                       TxHTPhyMode.field.BW = pAd->ate.TxWI.BW;
+                       TxHTPhyMode.field.ShortGI = pAd->ate.TxWI.ShortGI;
+                       TxHTPhyMode.field.STBC = 0;
+                       TxHTPhyMode.field.MCS = pAd->ate.TxWI.MCS;
+                       TxHTPhyMode.field.MODE = pAd->ate.TxWI.PHYMODE;
+
+                       ATEWriteTxWI(pAd, pTxWI,  FALSE, FALSE, FALSE, FALSE/* No ack required. */, FALSE, 0, BSSID_WCID, pAd->ate.TxLength,
+                               0, 0, IFS_HTTXOP, FALSE, TxHTPhyMode);// "MMPS_STATIC" instead of "MMPS_DYNAMIC" ???
+               }
+
+               RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE+TXWI_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
+
+               pDest = &(pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE+TXWI_SIZE+sizeof(HEADER_802_11)]);
+
+               // Prepare frame payload
+#ifdef RALINK_28xx_QA
+               if (pAd->ate.bQATxStart == TRUE)
+               {
+                       // copy pattern
+                       if ((pAd->ate.PLen != 0))
+                       {
+                               for (j = 0; j < pAd->ate.DLen; j+=pAd->ate.PLen)
+                               {
+                                       RTMPMoveMemory(pDest, pAd->ate.Pattern, pAd->ate.PLen);
+                                       pDest += pAd->ate.PLen;
+                               }
+                       }
+                       TransferBufferLength = TXINFO_SIZE + TXWI_SIZE + pAd->ate.TxWI.MPDUtotalByteCount;
+               }
+               else
+#endif // RALINK_28xx_QA //
+               {
+                   for (j = 0; j < (pAd->ate.TxLength - sizeof(HEADER_802_11)); j++)
+                   {
+                               *pDest = 0xA5;
+                               pDest += 1;
+                   }
+                       TransferBufferLength = TXINFO_SIZE + TXWI_SIZE + pAd->ate.TxLength;
+               }
+
+#if 1
+               OrgBufferLength = TransferBufferLength;
+               TransferBufferLength = (TransferBufferLength + 3) & (~3);
+
+               // Always add 4 extra bytes at every packet.
+               padLen = TransferBufferLength - OrgBufferLength + 4;/* 4 == last packet padding */
+               ASSERT((padLen <= (RTMP_PKT_TAIL_PADDING - 4/* 4 == MaxBulkOutsize alignment padding */)));
+
+               /* Now memzero all extra padding bytes. */
+               NdisZeroMemory(pDest, padLen);
+               pDest += padLen;
+#else
+               if ((TransferBufferLength % 4) == 1)
+               {
+                       NdisZeroMemory(pDest, 7);
+                       pDest += 7;
+                       TransferBufferLength  += 3;
+               }
+               else if ((TransferBufferLength % 4) == 2)
+               {
+                       NdisZeroMemory(pDest, 6);
+                       pDest += 6;
+                       TransferBufferLength  += 2;
+               }
+               else if ((TransferBufferLength % 4) == 3)
+               {
+                       NdisZeroMemory(pDest, 5);
+                       pDest += 5;
+                       TransferBufferLength  += 1;
+               }
+#endif // 1 //
+
+               // Update pTxInfo->USBDMATxPktLen to include padding.
+               pTxInfo->USBDMATxPktLen = TransferBufferLength - TXINFO_SIZE;
+
+               TransferBufferLength += 4;
+
+               // If TransferBufferLength is multiple of 64, add extra 4 bytes again.
+               if ((TransferBufferLength % pAd->BulkOutMaxPacketSize) == 0)
+               {
+                       NdisZeroMemory(pDest, 4);
+                       TransferBufferLength += 4;
+               }
+
+               // Fill out frame length information for global Bulk out arbitor
+               pAd->NullContext.BulkOutSize = TransferBufferLength;
+       }
+#ifdef RT_BIG_ENDIAN
+       RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
+       RTMPFrameEndianChange(pAd, (((PUCHAR)pTxInfo)+TXWI_SIZE+TXINFO_SIZE), DIR_WRITE, FALSE);
+    RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);
+#endif // RT_BIG_ENDIAN //
+       return 0;
+}
+
+VOID ATE_RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
+{
+       PRTMP_ADAPTER           pAd;
+       PTX_CONTEXT                 pNullContext;
+       UCHAR                           BulkOutPipeId;
+       NTSTATUS                        Status;
+       unsigned long           IrqFlags;
+       ULONG                       OldValue;
+
+       pNullContext = (PTX_CONTEXT)pUrb->context;
+       pAd = pNullContext->pAd;
+
+
+       // Reset Null frame context flags
+       pNullContext->IRPPending = FALSE;
+       pNullContext->InUse = FALSE;
+       Status = pUrb->status;
+
+       // Store BulkOut PipeId
+       BulkOutPipeId = pNullContext->BulkOutPipeId;
+       pAd->BulkOutDataOneSecCount++;
+
+       if (Status == USB_ST_NOERROR)
+       {
+#ifdef RALINK_28xx_QA
+               if ((ATE_ON(pAd)) && (pAd->ate.bQATxStart == TRUE))
+               {
+                       if (pAd->ate.QID == BulkOutPipeId)
+                       {
+                               // Let Rx can have a chance to break in during Tx process,
+                               // especially for loopback mode in QA ATE.
+                               // To trade off between tx performance and loopback mode integrity.
+                               /* Q   : Now Rx is handled by tasklet, do we still need this delay ? */
+                               /* Ans : Even tasklet is used, Rx/Tx < 1 if we do not delay for a while right here. */
+                               RTMPusecDelay(500);
+                               pAd->ate.TxDoneCount++;
+                               pAd->RalinkCounters.KickTxCount++;
+                               ASSERT(pAd->ate.QID == 0);
+                               pAd->ate.TxAc0++;
+                       }
+               }
+#endif // RALINK_28xx_QA //
+               pAd->BulkOutComplete++;
+
+               pAd->Counters8023.GoodTransmits++;
+
+               /* Don't worry about the queue is empty or not. This function will check itself. */
+               RTMPDeQueuePacket(pAd, TRUE, BulkOutPipeId, MAX_TX_PROCESS);
+
+               /* In 28xx, SendTxWaitQueue ==> TxSwQueue  */
+/*
+               if (pAd->SendTxWaitQueue[BulkOutPipeId].Number > 0)
+               {
+                       RTMPDeQueuePacket(pAd, BulkOutPipeId);
+               }
+*/
+       }
+       else    // STATUS_OTHER
+       {
+               pAd->BulkOutCompleteOther++;
+
+               ATEDBGPRINT(RT_DEBUG_ERROR, ("BulkOutDataPacket Failed STATUS_OTHER = 0x%x . \n", Status));
+               ATEDBGPRINT(RT_DEBUG_ERROR, (">>BulkOutReq=0x%lx, BulkOutComplete=0x%lx\n", pAd->BulkOutReq, pAd->BulkOutComplete));
+
+               if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
+                       (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
+                       (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
+                       (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
+               {
+                       RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+                       /* In 28xx, RT_OID_USB_RESET_BULK_OUT ==> CMDTHREAD_RESET_BULK_OUT */
+                       RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+                       // Check
+                       BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+                       pAd->BulkOutPending[BulkOutPipeId] = FALSE;
+                       pAd->bulkResetPipeid = BulkOutPipeId;
+                       BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+                       return;
+               }
+       }
+
+
+
+       if (atomic_read(&pAd->BulkOutRemained) > 0)
+       {
+               atomic_dec(&pAd->BulkOutRemained);
+       }
+
+       // 1st - Transmit Success
+       OldValue = pAd->WlanCounters.TransmittedFragmentCount.u.LowPart;
+       pAd->WlanCounters.TransmittedFragmentCount.u.LowPart++;
+
+       if (pAd->WlanCounters.TransmittedFragmentCount.u.LowPart < OldValue)
+       {
+               pAd->WlanCounters.TransmittedFragmentCount.u.HighPart++;
+       }
+
+       if(((pAd->ContinBulkOut == TRUE ) ||(atomic_read(&pAd->BulkOutRemained) > 0)) && (pAd->ate.Mode & ATE_TXFRAME))
+       {
+               RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+       }
+       else
+       {
+               RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+#ifdef RALINK_28xx_QA
+               pAd->ate.TxStatus = 0;
+#endif // RALINK_28xx_QA //
+       }
+
+       BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+       pAd->BulkOutPending[BulkOutPipeId] = FALSE;
+       BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+       // Always call Bulk routine, even reset bulk.
+       // The protection of rest bulk should be in BulkOut routine.
+       RTUSBKickBulkOut(pAd);
+}
+
+/*
+       ========================================================================
+
+       Routine Description:
+
+       Arguments:
+
+       Return Value:
+
+       Note:
+
+       ========================================================================
+*/
+VOID   ATE_RTUSBBulkOutDataPacket(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      UCHAR                   BulkOutPipeId)
+{
+       PTX_CONTEXT             pNullContext = &(pAd->NullContext);
+       PURB                    pUrb;
+       int                             ret = 0;
+       unsigned long   IrqFlags;
+
+
+       ASSERT(BulkOutPipeId == 0);
+
+       /* Build up the frame first. */
+//     ATESetUpFrame(pAd, 0);
+
+       BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+       if (pAd->BulkOutPending[BulkOutPipeId] == TRUE)
+       {
+               BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+               return;
+       }
+
+       pAd->BulkOutPending[BulkOutPipeId] = TRUE;
+       BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+       // Increase Total transmit byte counter
+       pAd->RalinkCounters.OneSecTransmittedByteCount +=  pNullContext->BulkOutSize;
+       pAd->RalinkCounters.TransmittedByteCount +=  pNullContext->BulkOutSize;
+
+       // Clear ATE frame bulk out flag
+       RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+
+       // Init Tx context descriptor
+       pNullContext->IRPPending = TRUE;
+       RTUSBInitTxDesc(pAd, pNullContext, BulkOutPipeId, (usb_complete_t)ATE_RTUSBBulkOutDataPacketComplete);
+       pUrb = pNullContext->pUrb;
+
+       if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
+       {
+               ATEDBGPRINT(RT_DEBUG_ERROR, ("ATE_RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
+               return;
+       }
+
+       pAd->BulkOutReq++;
+       return;
+
+}
+
+/*
+       ========================================================================
+
+       Routine Description:
+
+       Arguments:
+
+       Return Value:
+
+       Note:
+
+       ========================================================================
+*/
+VOID   ATE_RTUSBCancelPendingBulkInIRP(
+       IN      PRTMP_ADAPTER   pAd)
+{
+       PRX_CONTEXT             pRxContext;
+       UINT                    i;
+
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("--->ATE_RTUSBCancelPendingBulkInIRP\n"));
+#if 1
+       for ( i = 0; i < (RX_RING_SIZE); i++)
+       {
+               pRxContext = &(pAd->RxContext[i]);
+               if(pRxContext->IRPPending == TRUE)
+               {
+                       RTUSB_UNLINK_URB(pRxContext->pUrb);
+                       pRxContext->IRPPending = FALSE;
+                       pRxContext->InUse = FALSE;
+                       //NdisInterlockedDecrement(&pAd->PendingRx);
+                       //pAd->PendingRx--;
+               }
+       }
+#else
+       for ( i = 0; i < (RX_RING_SIZE); i++)
+       {
+               pRxContext = &(pAd->RxContext[i]);
+               if(atomic_read(&pRxContext->IrpLock) == IRPLOCK_CANCELABLE)
+               {
+                       RTUSB_UNLINK_URB(pRxContext->pUrb);
+               }
+               InterlockedExchange(&pRxContext->IrpLock, IRPLOCK_CANCE_START);
+       }
+#endif // 1 //
+       ATEDBGPRINT(RT_DEBUG_TRACE, ("<---ATE_RTUSBCancelPendingBulkInIRP\n"));
+       return;
+}
+#endif // RT2870 //
+
+VOID rt_ee_read_all(PRTMP_ADAPTER pAd, USHORT *Data)
+{
+       USHORT i;
+       USHORT value;
+
+       for (i = 0 ; i < EEPROM_SIZE/2 ; )
+       {
+               /* "value" is expecially for some compilers... */
+               RT28xx_EEPROM_READ16(pAd, i*2, value);
+               Data[i] = value;
+               i++;
+       }
+}
+
+VOID rt_ee_write_all(PRTMP_ADAPTER pAd, USHORT *Data)
+{
+       USHORT i;
+       USHORT value;
+
+       for (i = 0 ; i < EEPROM_SIZE/2 ; )
+       {
+               /* "value" is expecially for some compilers... */
+               value = Data[i];
+               RT28xx_EEPROM_WRITE16(pAd, i*2, value);
+               i ++;
+       }
+}
+#ifdef RALINK_28xx_QA
+VOID ATE_QA_Statistics(
+       IN PRTMP_ADAPTER                        pAd,
+       IN PRXWI_STRUC                          pRxWI,
+       IN PRT28XX_RXD_STRUC            pRxD,
+       IN PHEADER_802_11                       pHeader)
+{
+       // update counter first
+       if (pHeader != NULL)
+       {
+               if (pHeader->FC.Type == BTYPE_DATA)
+               {
+                       if (pRxD->U2M)
+                               pAd->ate.U2M++;
+                       else
+                               pAd->ate.OtherData++;
+               }
+               else if (pHeader->FC.Type == BTYPE_MGMT)
+               {
+                       if (pHeader->FC.SubType == SUBTYPE_BEACON)
+                               pAd->ate.Beacon++;
+                       else
+                               pAd->ate.OtherCount++;
+               }
+               else if (pHeader->FC.Type == BTYPE_CNTL)
+               {
+                       pAd->ate.OtherCount++;
+               }
+       }
+       pAd->ate.RSSI0 = pRxWI->RSSI0;
+       pAd->ate.RSSI1 = pRxWI->RSSI1;
+       pAd->ate.RSSI2 = pRxWI->RSSI2;
+       pAd->ate.SNR0 = pRxWI->SNR0;
+       pAd->ate.SNR1 = pRxWI->SNR1;
+}
+
+/* command id with Cmd Type == 0x0008(for 28xx)/0x0005(for iNIC) */
+#define RACFG_CMD_RF_WRITE_ALL         0x0000
+#define RACFG_CMD_E2PROM_READ16                0x0001
+#define RACFG_CMD_E2PROM_WRITE16       0x0002
+#define RACFG_CMD_E2PROM_READ_ALL      0x0003
+#define RACFG_CMD_E2PROM_WRITE_ALL     0x0004
+#define RACFG_CMD_IO_READ                      0x0005
+#define RACFG_CMD_IO_WRITE                     0x0006
+#define RACFG_CMD_IO_READ_BULK         0x0007
+#define RACFG_CMD_BBP_READ8                    0x0008
+#define RACFG_CMD_BBP_WRITE8           0x0009
+#define RACFG_CMD_BBP_READ_ALL         0x000a
+#define RACFG_CMD_GET_COUNTER          0x000b
+#define RACFG_CMD_CLEAR_COUNTER                0x000c
+
+#define RACFG_CMD_RSV1                         0x000d
+#define RACFG_CMD_RSV2                         0x000e
+#define RACFG_CMD_RSV3                         0x000f
+
+#define RACFG_CMD_TX_START                     0x0010
+#define RACFG_CMD_GET_TX_STATUS                0x0011
+#define RACFG_CMD_TX_STOP                      0x0012
+#define RACFG_CMD_RX_START                     0x0013
+#define RACFG_CMD_RX_STOP                      0x0014
+#define RACFG_CMD_GET_NOISE_LEVEL      0x0015
+
+#define RACFG_CMD_ATE_START                    0x0080
+#define RACFG_CMD_ATE_STOP                     0x0081
+
+#define RACFG_CMD_ATE_START_TX_CARRIER         0x0100
+#define RACFG_CMD_ATE_START_TX_CONT                    0x0101
+#define RACFG_CMD_ATE_START_TX_FRAME           0x0102
+#define RACFG_CMD_ATE_SET_BW               0x0103
+#define RACFG_CMD_ATE_SET_TX_POWER0            0x0104
+#define RACFG_CMD_ATE_SET_TX_POWER1                    0x0105
+#define RACFG_CMD_ATE_SET_FREQ_OFFSET          0x0106
+#define RACFG_CMD_ATE_GET_STATISTICS           0x0107
+#define RACFG_CMD_ATE_RESET_COUNTER                    0x0108
+#define RACFG_CMD_ATE_SEL_TX_ANTENNA           0x0109
+#define RACFG_CMD_ATE_SEL_RX_ANTENNA           0x010a
+#define RACFG_CMD_ATE_SET_PREAMBLE                     0x010b
+#define RACFG_CMD_ATE_SET_CHANNEL                      0x010c
+#define RACFG_CMD_ATE_SET_ADDR1                                0x010d
+#define RACFG_CMD_ATE_SET_ADDR2                                0x010e
+#define RACFG_CMD_ATE_SET_ADDR3                                0x010f
+#define RACFG_CMD_ATE_SET_RATE                         0x0110
+#define RACFG_CMD_ATE_SET_TX_FRAME_LEN         0x0111
+#define RACFG_CMD_ATE_SET_TX_FRAME_COUNT       0x0112
+#define RACFG_CMD_ATE_START_RX_FRAME           0x0113
+#define RACFG_CMD_ATE_E2PROM_READ_BULK 0x0114
+#define RACFG_CMD_ATE_E2PROM_WRITE_BULK        0x0115
+#define RACFG_CMD_ATE_IO_WRITE_BULK            0x0116
+#define RACFG_CMD_ATE_BBP_READ_BULK            0x0117
+#define RACFG_CMD_ATE_BBP_WRITE_BULK   0x0118
+#define RACFG_CMD_ATE_RF_READ_BULK             0x0119
+#define RACFG_CMD_ATE_RF_WRITE_BULK            0x011a
+
+
+
+#define A2Hex(_X, _p)                          \
+{                                                                      \
+       UCHAR *p;                                               \
+       _X = 0;                                                 \
+       p = _p;                                                 \
+       while (((*p >= 'a') && (*p <= 'f')) || ((*p >= 'A') && (*p <= 'F')) || ((*p >= '0') && (*p <= '9')))            \
+       {                                                                                               \
+               if ((*p >= 'a') && (*p <= 'f'))                         \
+                       _X = _X * 16 + *p - 87;                                 \
+               else if ((*p >= 'A') && (*p <= 'F'))            \
+                       _X = _X * 16 + *p - 55;                                 \
+               else if ((*p >= '0') && (*p <= '9'))            \
+                       _X = _X * 16 + *p - 48;                                 \
+               p++;                                                                            \
+       }                                                                                               \
+}
+
+
+static VOID memcpy_exl(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len);
+static VOID memcpy_exs(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len);
+static VOID RTMP_IO_READ_BULK(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, UINT32 len);
+
+#ifdef UCOS
+int ate_copy_to_user(
+       IN PUCHAR payload,
+       IN PUCHAR msg,
+       IN INT    len)
+{
+       memmove(payload, msg, len);
+       return 0;
+}
+
+#undef copy_to_user
+#define copy_to_user(x,y,z) ate_copy_to_user((PUCHAR)x, (PUCHAR)y, z)
+#endif // UCOS //
+
+#define        LEN_OF_ARG 16
+
+VOID RtmpDoAte(
+       IN      PRTMP_ADAPTER   pAdapter,
+       IN      struct iwreq    *wrq)
+{
+       unsigned short Command_Id;
+       struct ate_racfghdr *pRaCfg;
+       INT     Status = NDIS_STATUS_SUCCESS;
+
+
+
+       if((pRaCfg = kmalloc(sizeof(struct ate_racfghdr), GFP_KERNEL)) == NULL)
+       {
+               Status = -EINVAL;
+               return;
+       }
+
+       NdisZeroMemory(pRaCfg, sizeof(struct ate_racfghdr));
+
+    if (copy_from_user((PUCHAR)pRaCfg, wrq->u.data.pointer, wrq->u.data.length))
+       {
+               Status = -EFAULT;
+               kfree(pRaCfg);
+               return;
+       }
+
+
+       Command_Id = ntohs(pRaCfg->command_id);
+
+       ATEDBGPRINT(RT_DEBUG_TRACE,("\n%s: Command_Id = 0x%04x !\n", __FUNCTION__, Command_Id));
+
+       switch (Command_Id)
+       {
+               // We will get this command when QA starts.
+               case RACFG_CMD_ATE_START:
+                       {
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START\n"));
+
+                               // prepare feedback as soon as we can to avoid QA timeout.
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+                               ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("copy_to_user() fail in case RACFG_CMD_ATE_START\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START is done !\n"));
+                               }
+                               Set_ATE_Proc(pAdapter, "ATESTART");
+                       }
+                       break;
+
+               // We will get this command either QA is closed or ated is killed by user.
+               case RACFG_CMD_ATE_STOP:
+                       {
+#ifndef UCOS
+                               INT32 ret;
+#endif // !UCOS //
+
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_STOP\n"));
+
+                               // Distinguish this command came from QA(via ated)
+                               // or ate daemon according to the existence of pid in payload.
+                               // No need to prepare feedback if this cmd came directly from ate daemon.
+                               pRaCfg->length = ntohs(pRaCfg->length);
+
+                               if (pRaCfg->length == sizeof(pAdapter->ate.AtePid))
+                               {
+                                       // This command came from QA.
+                                       // Get the pid of ATE daemon.
+                                       memcpy((UCHAR *)&pAdapter->ate.AtePid,
+                                               (&pRaCfg->data[0]) - 2/* == &(pRaCfg->status) */,
+                                               sizeof(pAdapter->ate.AtePid));
+
+                                       // prepare feedback as soon as we can to avoid QA timeout.
+                                       pRaCfg->length = htons(2);
+                                       pRaCfg->status = htons(0);
+
+                                       wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                               + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                               + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+                                       ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+
+                       if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+                       {
+                               ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_STOP\n"));
+                           Status = -EFAULT;
+                       }
+
+                                       //
+                                       // kill ATE daemon when leaving ATE mode.
+                                       // We must kill ATE daemon first before setting ATESTOP,
+                                       // or Microsoft will report sth. wrong.
+#ifndef UCOS
+                                       ret = kill_proc(pAdapter->ate.AtePid, SIGTERM, 1);
+                                       if (ret)
+                                       {
+                                               ATEDBGPRINT(RT_DEBUG_ERROR, ("%s: unable to signal thread\n", pAdapter->net_dev->name));
+                                       }
+#endif // !UCOS //
+                               }
+
+#ifdef UCOS
+                               // Roger add to avoid error message after close QA
+                               if (pAdapter->CSRBaseAddress == RT2860_CSR_ADDR)
+                               {
+
+                                       // prepare feedback as soon as we can to avoid QA timeout.
+                                       pRaCfg->length = htons(2);
+                                       pRaCfg->status = htons(0);
+
+                                       wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                               + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                               + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+                                       ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+                       if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+                       {
+                               ATEDBGPRINT(RT_DEBUG_TRACE, ("copy_to_user() fail in case RACFG_CMD_AP_START\n"));
+                           Status = -EFAULT;
+                       }
+                               }
+#endif // UCOS //
+
+                               // AP might have in ATE_STOP mode due to cmd from QA.
+                               if (ATE_ON(pAdapter))
+                               {
+                                       // Someone has killed ate daemon while QA GUI is still open.
+                                       Set_ATE_Proc(pAdapter, "ATESTOP");
+                                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_AP_START is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_RF_WRITE_ALL:
+                       {
+                               UINT32 R1, R2, R3, R4;
+                               USHORT channel;
+
+                               memcpy(&R1, pRaCfg->data-2, 4);
+                               memcpy(&R2, pRaCfg->data+2, 4);
+                               memcpy(&R3, pRaCfg->data+6, 4);
+                               memcpy(&R4, pRaCfg->data+10, 4);
+                               memcpy(&channel, pRaCfg->data+14, 2);
+
+                               pAdapter->LatchRfRegs.R1 = ntohl(R1);
+                               pAdapter->LatchRfRegs.R2 = ntohl(R2);
+                               pAdapter->LatchRfRegs.R3 = ntohl(R3);
+                               pAdapter->LatchRfRegs.R4 = ntohl(R4);
+                               pAdapter->LatchRfRegs.Channel = ntohs(channel);
+
+                               RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R1);
+                               RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R2);
+                               RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R3);
+                               RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R4);
+
+                               // prepare feedback
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+                               ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RF_WRITE_ALL\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RF_WRITE_ALL is done !\n"));
+                               }
+                       }
+            break;
+
+               case RACFG_CMD_E2PROM_READ16:
+                       {
+                               USHORT  offset, value, tmp;
+
+                               offset = ntohs(pRaCfg->status);
+                               /* "tmp" is expecially for some compilers... */
+                               RT28xx_EEPROM_READ16(pAdapter, offset, tmp);
+                               value = tmp;
+                               value = htons(value);
+
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("EEPROM Read offset = 0x%04x, value = 0x%04x\n", offset, value));
+
+                               // prepare feedback
+                               pRaCfg->length = htons(4);
+                               pRaCfg->status = htons(0);
+                               memcpy(pRaCfg->data, &value, 2);
+
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+                               ATEDBGPRINT(RT_DEBUG_TRACE, ("sizeof(struct ate_racfghdr) = %d\n", sizeof(struct ate_racfghdr)));
+                               ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_READ16\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_E2PROM_READ16 is done !\n"));
+                               }
+               }
+                       break;
+
+               case RACFG_CMD_E2PROM_WRITE16:
+                       {
+                               USHORT  offset, value;
+
+                               offset = ntohs(pRaCfg->status);
+                               memcpy(&value, pRaCfg->data, 2);
+                               value = ntohs(value);
+                               RT28xx_EEPROM_WRITE16(pAdapter, offset, value);
+
+                               // prepare feedback
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_WRITE16\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_E2PROM_WRITE16 is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_E2PROM_READ_ALL:
+                       {
+                               USHORT buffer[EEPROM_SIZE/2];
+
+                               rt_ee_read_all(pAdapter,(USHORT *)buffer);
+                               memcpy_exs(pAdapter, pRaCfg->data, (UCHAR *)buffer, EEPROM_SIZE);
+
+                               // prepare feedback
+                               pRaCfg->length = htons(2+EEPROM_SIZE);
+                               pRaCfg->status = htons(0);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_READ_ALL\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_E2PROM_READ_ALL is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_E2PROM_WRITE_ALL:
+                       {
+                               USHORT buffer[EEPROM_SIZE/2];
+
+                               NdisZeroMemory((UCHAR *)buffer, EEPROM_SIZE);
+                               memcpy_exs(pAdapter, (UCHAR *)buffer, (UCHAR *)&pRaCfg->status, EEPROM_SIZE);
+                               rt_ee_write_all(pAdapter,(USHORT *)buffer);
+
+                               // prepare feedback
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_WRITE_ALL\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("RACFG_CMD_E2PROM_WRITE_ALL is done !\n"));
+                               }
+
+                       }
+                       break;
+
+               case RACFG_CMD_IO_READ:
+                       {
+                               UINT32  offset;
+                               UINT32  value;
+
+                               memcpy(&offset, &pRaCfg->status, 4);
+                               offset = ntohl(offset);
+
+                               // We do not need the base address.
+                               // So just extract the offset out.
+                               offset &= 0x0000FFFF;
+                               RTMP_IO_READ32(pAdapter, offset, &value);
+                               value = htonl(value);
+
+                               // prepare feedback
+                               pRaCfg->length = htons(6);
+                               pRaCfg->status = htons(0);
+                               memcpy(pRaCfg->data, &value, 4);
+
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_IO_READ\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_IO_READ is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_IO_WRITE:
+                       {
+                               UINT32  offset, value;
+
+                               memcpy(&offset, pRaCfg->data-2, 4);
+                               memcpy(&value, pRaCfg->data+2, 4);
+
+                               offset = ntohl(offset);
+
+                               // We do not need the base address.
+                               // So just extract out the offset.
+                               offset &= 0x0000FFFF;
+                               value = ntohl(value);
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_IO_WRITE: offset = %x, value = %x\n", offset, value));
+                               RTMP_IO_WRITE32(pAdapter, offset, value);
+
+                               // prepare feedback
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_IO_WRITE\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_IO_WRITE is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_IO_READ_BULK:
+                       {
+                               UINT32  offset;
+                               USHORT  len;
+
+                               memcpy(&offset, &pRaCfg->status, 4);
+                               offset = ntohl(offset);
+
+                               // We do not need the base address.
+                               // So just extract the offset.
+                               offset &= 0x0000FFFF;
+                               memcpy(&len, pRaCfg->data+2, 2);
+                               len = ntohs(len);
+
+                               if (len > 371)
+                               {
+                                       ATEDBGPRINT(RT_DEBUG_TRACE,("len is too large, make it smaller\n"));
+                                       pRaCfg->length = htons(2);
+                                       pRaCfg->status = htons(1);
+                                       break;
+                               }
+
+                               RTMP_IO_READ_BULK(pAdapter, pRaCfg->data, (UCHAR *)offset, len*4);// unit in four bytes
+
+                               // prepare feedback
+                               pRaCfg->length = htons(2+len*4);// unit in four bytes
+                               pRaCfg->status = htons(0);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_IO_READ_BULK\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_IO_READ_BULK is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_BBP_READ8:
+                       {
+                               USHORT  offset;
+                               UCHAR   value;
+
+                               value = 0;
+                               offset = ntohs(pRaCfg->status);
+
+                               if (ATE_ON(pAdapter))
+                               {
+                                       ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, offset,  &value);
+                               }
+                               else
+                               {
+                                       RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, offset,  &value);
+                               }
+                               // prepare feedback
+                               pRaCfg->length = htons(3);
+                               pRaCfg->status = htons(0);
+                               pRaCfg->data[0] = value;
+
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("BBP value = %x\n", value));
+
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_BBP_READ8\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_BBP_READ8 is done !\n"));
+                               }
+                       }
+                       break;
+               case RACFG_CMD_BBP_WRITE8:
+                       {
+                               USHORT  offset;
+                               UCHAR   value;
+
+                               offset = ntohs(pRaCfg->status);
+                               memcpy(&value, pRaCfg->data, 1);
+
+                               if (ATE_ON(pAdapter))
+                               {
+                                       ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, offset,  value);
+                               }
+                               else
+                               {
+                                       RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, offset,  value);
+                               }
+
+                               if ((offset == BBP_R1) || (offset == BBP_R3))
+                               {
+                                       SyncTxRxConfig(pAdapter, offset, value);
+                               }
+
+                               // prepare feedback
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_BBP_WRITE8\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_BBP_WRITE8 is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_BBP_READ_ALL:
+                       {
+                               USHORT j;
+
+                               for (j = 0; j < 137; j++)
+                               {
+                                       pRaCfg->data[j] = 0;
+
+                                       if (ATE_ON(pAdapter))
+                                       {
+                                               ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, j,  &pRaCfg->data[j]);
+                                       }
+                                       else
+                                       {
+                                               RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, j,  &pRaCfg->data[j]);
+                                       }
+                               }
+
+                               // prepare feedback
+                               pRaCfg->length = htons(2+137);
+                               pRaCfg->status = htons(0);
+
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_BBP_READ_ALL\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_BBP_READ_ALL is done !\n"));
+                               }
+                       }
+
+                       break;
+
+               case RACFG_CMD_ATE_E2PROM_READ_BULK:
+               {
+                       USHORT offset;
+                       USHORT len;
+                       USHORT buffer[EEPROM_SIZE/2];
+
+                       offset = ntohs(pRaCfg->status);
+                       memcpy(&len, pRaCfg->data, 2);
+                       len = ntohs(len);
+
+                       rt_ee_read_all(pAdapter,(USHORT *)buffer);
+                       if (offset + len <= EEPROM_SIZE)
+                               memcpy_exs(pAdapter, pRaCfg->data, (UCHAR *)buffer+offset, len);
+                       else
+                               ATEDBGPRINT(RT_DEBUG_ERROR, ("exceed EEPROM size\n"));
+
+                       // prepare feedback
+                       pRaCfg->length = htons(2+len);
+                       pRaCfg->status = htons(0);
+                       wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            {
+               ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_E2PROM_READ_BULK\n"));
+                Status = -EFAULT;
+            }
+                       else
+                       {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_E2PROM_READ_BULK is done !\n"));
+                       }
+
+               }
+                       break;
+
+               case RACFG_CMD_ATE_E2PROM_WRITE_BULK:
+               {
+                       USHORT offset;
+                       USHORT len;
+                       USHORT buffer[EEPROM_SIZE/2];
+
+                       offset = ntohs(pRaCfg->status);
+                       memcpy(&len, pRaCfg->data, 2);
+                       len = ntohs(len);
+
+                       rt_ee_read_all(pAdapter,(USHORT *)buffer);
+                       memcpy_exs(pAdapter, (UCHAR *)buffer + offset, (UCHAR *)pRaCfg->data + 2, len);
+                       rt_ee_write_all(pAdapter,(USHORT *)buffer);
+
+                       // prepare feedback
+                       pRaCfg->length = htons(2);
+                       pRaCfg->status = htons(0);
+                       wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                               + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                               + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+            if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            {
+               ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_E2PROM_WRITE_BULK\n"));
+                   Status = -EFAULT;
+            }
+                       else
+                       {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("RACFG_CMD_ATE_E2PROM_WRITE_BULK is done !\n"));
+                       }
+
+               }
+                       break;
+
+               case RACFG_CMD_ATE_IO_WRITE_BULK:
+               {
+                       UINT32 offset, i, value;
+                       USHORT len;
+
+                       memcpy(&offset, &pRaCfg->status, 4);
+                       offset = ntohl(offset);
+                       memcpy(&len, pRaCfg->data+2, 2);
+                       len = ntohs(len);
+
+                       for (i = 0; i < len; i += 4)
+                       {
+                               memcpy_exl(pAdapter, (UCHAR *)&value, pRaCfg->data+4+i, 4);
+                               printk("Write %x %x\n", offset + i, value);
+                               RTMP_IO_WRITE32(pAdapter, (offset +i) & 0xffff, value);
+                       }
+
+                       // prepare feedback
+                       pRaCfg->length = htons(2);
+                       pRaCfg->status = htons(0);
+                       wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                               + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                               + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+            if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            {
+               ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_IO_WRITE_BULK\n"));
+                   Status = -EFAULT;
+            }
+                       else
+                       {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("RACFG_CMD_ATE_IO_WRITE_BULK is done !\n"));
+                       }
+
+               }
+                       break;
+
+               case RACFG_CMD_ATE_BBP_READ_BULK:
+               {
+                       USHORT offset;
+                       USHORT len;
+                       USHORT j;
+
+                       offset = ntohs(pRaCfg->status);
+                       memcpy(&len, pRaCfg->data, 2);
+                       len = ntohs(len);
+
+
+                       for (j = offset; j < (offset+len); j++)
+                       {
+                               pRaCfg->data[j - offset] = 0;
+
+                               if (pAdapter->ate.Mode == ATE_STOP)
+                               {
+                                       RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, j,  &pRaCfg->data[j - offset]);
+                               }
+                               else
+                               {
+                                       ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, j,  &pRaCfg->data[j - offset]);
+                               }
+                       }
+
+                       // prepare feedback
+                       pRaCfg->length = htons(2+len);
+                       pRaCfg->status = htons(0);
+                       wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                               + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                               + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            {
+               ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_BBP_READ_BULK\n"));
+                   Status = -EFAULT;
+            }
+                       else
+                       {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_BBP_READ_BULK is done !\n"));
+                       }
+
+               }
+                       break;
+
+               case RACFG_CMD_ATE_BBP_WRITE_BULK:
+               {
+                       USHORT offset;
+                       USHORT len;
+                       USHORT j;
+                       UCHAR *value;
+
+                       offset = ntohs(pRaCfg->status);
+                       memcpy(&len, pRaCfg->data, 2);
+                       len = ntohs(len);
+
+                       for (j = offset; j < (offset+len); j++)
+                       {
+                               value = pRaCfg->data + 2 + (j - offset);
+                               if (pAdapter->ate.Mode == ATE_STOP)
+                               {
+                                       RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, j,  *value);
+                               }
+                               else
+                               {
+                                       ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, j,  *value);
+                               }
+                       }
+
+                       // prepare feedback
+                       pRaCfg->length = htons(2);
+                       pRaCfg->status = htons(0);
+                       wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                               + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                               + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            {
+               ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_BBP_WRITE_BULK\n"));
+                   Status = -EFAULT;
+            }
+                       else
+                       {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_BBP_WRITE_BULK is done !\n"));
+                       }
+               }
+                       break;
+
+#ifdef CONFIG_RALINK_RT3052
+               case RACFG_CMD_ATE_RF_READ_BULK:
+               {
+                       USHORT offset;
+                       USHORT len;
+                       USHORT j;
+
+                       offset = ntohs(pRaCfg->status);
+                       memcpy(&len, pRaCfg->data, 2);
+                       len = ntohs(len);
+
+                       for (j = offset; j < (offset+len); j++)
+                       {
+                               pRaCfg->data[j - offset] = 0;
+                               RT30xxReadRFRegister(pAdapter, j,  &pRaCfg->data[j - offset]);
+                       }
+
+                       // prepare feedback
+                       pRaCfg->length = htons(2+len);
+                       pRaCfg->status = htons(0);
+                       wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                               + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                               + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            {
+               ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_RF_READ_BULK\n"));
+                   Status = -EFAULT;
+            }
+                       else
+                       {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_RF_READ_BULK is done !\n"));
+                       }
+
+               }
+                       break;
+
+               case RACFG_CMD_ATE_RF_WRITE_BULK:
+               {
+                       USHORT offset;
+                       USHORT len;
+                       USHORT j;
+                       UCHAR *value;
+
+                       offset = ntohs(pRaCfg->status);
+                       memcpy(&len, pRaCfg->data, 2);
+                       len = ntohs(len);
+
+                       for (j = offset; j < (offset+len); j++)
+                       {
+                               value = pRaCfg->data + 2 + (j - offset);
+                               RT30xxWriteRFRegister(pAdapter, j,  *value);
+                       }
+
+                       // prepare feedback
+                       pRaCfg->length = htons(2);
+                       pRaCfg->status = htons(0);
+                       wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                               + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                               + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            {
+               ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_RF_WRITE_BULK\n"));
+                   Status = -EFAULT;
+            }
+                       else
+                       {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_RF_WRITE_BULK is done !\n"));
+                       }
+
+               }
+                       break;
+#endif
+
+
+               case RACFG_CMD_GET_NOISE_LEVEL:
+                       {
+                               UCHAR   channel;
+                               INT32   buffer[3][10];/* 3 : RxPath ; 10 : no. of per rssi samples */
+
+                               channel = (ntohs(pRaCfg->status) & 0x00FF);
+                               CalNoiseLevel(pAdapter, channel, buffer);
+                               memcpy_exl(pAdapter, (UCHAR *)pRaCfg->data, (UCHAR *)&(buffer[0][0]), (sizeof(INT32)*3*10));
+
+                               // prepare feedback
+                               pRaCfg->length = htons(2 + (sizeof(INT32)*3*10));
+                               pRaCfg->status = htons(0);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_GET_NOISE_LEVEL\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_GET_NOISE_LEVEL is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_GET_COUNTER:
+                       {
+                               memcpy_exl(pAdapter, &pRaCfg->data[0], (UCHAR *)&pAdapter->ate.U2M, 4);
+                               memcpy_exl(pAdapter, &pRaCfg->data[4], (UCHAR *)&pAdapter->ate.OtherData, 4);
+                               memcpy_exl(pAdapter, &pRaCfg->data[8], (UCHAR *)&pAdapter->ate.Beacon, 4);
+                               memcpy_exl(pAdapter, &pRaCfg->data[12], (UCHAR *)&pAdapter->ate.OtherCount, 4);
+                               memcpy_exl(pAdapter, &pRaCfg->data[16], (UCHAR *)&pAdapter->ate.TxAc0, 4);
+                               memcpy_exl(pAdapter, &pRaCfg->data[20], (UCHAR *)&pAdapter->ate.TxAc1, 4);
+                               memcpy_exl(pAdapter, &pRaCfg->data[24], (UCHAR *)&pAdapter->ate.TxAc2, 4);
+                               memcpy_exl(pAdapter, &pRaCfg->data[28], (UCHAR *)&pAdapter->ate.TxAc3, 4);
+                               memcpy_exl(pAdapter, &pRaCfg->data[32], (UCHAR *)&pAdapter->ate.TxHCCA, 4);
+                               memcpy_exl(pAdapter, &pRaCfg->data[36], (UCHAR *)&pAdapter->ate.TxMgmt, 4);
+                               memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&pAdapter->ate.RSSI0, 4);
+                               memcpy_exl(pAdapter, &pRaCfg->data[44], (UCHAR *)&pAdapter->ate.RSSI1, 4);
+                               memcpy_exl(pAdapter, &pRaCfg->data[48], (UCHAR *)&pAdapter->ate.RSSI2, 4);
+                               memcpy_exl(pAdapter, &pRaCfg->data[52], (UCHAR *)&pAdapter->ate.SNR0, 4);
+                               memcpy_exl(pAdapter, &pRaCfg->data[56], (UCHAR *)&pAdapter->ate.SNR1, 4);
+
+                               pRaCfg->length = htons(2+60);
+                               pRaCfg->status = htons(0);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_GET_COUNTER\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_GET_COUNTER is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_CLEAR_COUNTER:
+                       {
+                               pAdapter->ate.U2M = 0;
+                               pAdapter->ate.OtherData = 0;
+                               pAdapter->ate.Beacon = 0;
+                               pAdapter->ate.OtherCount = 0;
+                               pAdapter->ate.TxAc0 = 0;
+                               pAdapter->ate.TxAc1 = 0;
+                               pAdapter->ate.TxAc2 = 0;
+                               pAdapter->ate.TxAc3 = 0;
+                               pAdapter->ate.TxHCCA = 0;
+                               pAdapter->ate.TxMgmt = 0;
+                               pAdapter->ate.TxDoneCount = 0;
+
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_CLEAR_COUNTER\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_CLEAR_COUNTER is done !\n"));
+                               }
+                       }
+
+                       break;
+
+               case RACFG_CMD_TX_START:
+                       {
+                               USHORT *p;
+                               USHORT  err = 1;
+                               UCHAR   Bbp22Value = 0, Bbp24Value = 0;
+
+                               if ((pAdapter->ate.TxStatus != 0) && (pAdapter->ate.Mode & ATE_TXFRAME))
+                               {
+                                       ATEDBGPRINT(RT_DEBUG_TRACE,("Ate Tx is already running, to run next Tx, you must stop it first\n"));
+                                       err = 2;
+                                       goto TX_START_ERROR;
+                               }
+                               else if ((pAdapter->ate.TxStatus != 0) && !(pAdapter->ate.Mode & ATE_TXFRAME))
+                               {
+                                       int i = 0;
+
+                                       while ((i++ < 10) && (pAdapter->ate.TxStatus != 0))
+                                       {
+                                               RTMPusecDelay(5000);
+                                       }
+
+                                       // force it to stop
+                                       pAdapter->ate.TxStatus = 0;
+                                       pAdapter->ate.TxDoneCount = 0;
+                                       //pAdapter->ate.Repeat = 0;
+                                       pAdapter->ate.bQATxStart = FALSE;
+                               }
+
+                               // If pRaCfg->length == 0, this "RACFG_CMD_TX_START" is for Carrier test or Carrier Suppression.
+                               if (ntohs(pRaCfg->length) != 0)
+                               {
+                                       // Get frame info
+#ifdef RT2870
+                                       NdisMoveMemory(&pAdapter->ate.TxInfo, pRaCfg->data - 2, 4);
+#ifdef RT_BIG_ENDIAN
+                                       RTMPDescriptorEndianChange((PUCHAR) &pAdapter->ate.TxInfo, TYPE_TXINFO);
+#endif // RT_BIG_ENDIAN //
+#endif // RT2870 //
+
+                                       NdisMoveMemory(&pAdapter->ate.TxWI, pRaCfg->data + 2, 16);
+#ifdef RT_BIG_ENDIAN
+                                       RTMPWIEndianChange((PUCHAR)&pAdapter->ate.TxWI, TYPE_TXWI);
+#endif // RT_BIG_ENDIAN //
+
+                                       NdisMoveMemory(&pAdapter->ate.TxCount, pRaCfg->data + 18, 4);
+                                       pAdapter->ate.TxCount = ntohl(pAdapter->ate.TxCount);
+
+                                       p = (USHORT *)(&pRaCfg->data[22]);
+                                       //p = pRaCfg->data + 22;
+                                       // always use QID_AC_BE
+                                       pAdapter->ate.QID = 0;
+                                       p = (USHORT *)(&pRaCfg->data[24]);
+                                       //p = pRaCfg->data + 24;
+                                       pAdapter->ate.HLen = ntohs(*p);
+
+                                       if (pAdapter->ate.HLen > 32)
+                                       {
+                                               ATEDBGPRINT(RT_DEBUG_ERROR,("pAdapter->ate.HLen > 32\n"));
+                                               err = 3;
+                                               goto TX_START_ERROR;
+                                       }
+
+                                       NdisMoveMemory(&pAdapter->ate.Header, pRaCfg->data + 26, pAdapter->ate.HLen);
+
+
+                                       pAdapter->ate.PLen = ntohs(pRaCfg->length) - (pAdapter->ate.HLen + 28);
+
+                                       if (pAdapter->ate.PLen > 32)
+                                       {
+                                               ATEDBGPRINT(RT_DEBUG_ERROR,("pAdapter->ate.PLen > 32\n"));
+                                               err = 4;
+                                               goto TX_START_ERROR;
+                                       }
+
+                                       NdisMoveMemory(&pAdapter->ate.Pattern, pRaCfg->data + 26 + pAdapter->ate.HLen, pAdapter->ate.PLen);
+                                       pAdapter->ate.DLen = pAdapter->ate.TxWI.MPDUtotalByteCount - pAdapter->ate.HLen;
+                               }
+
+                               ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R22, &Bbp22Value);
+
+                               switch (Bbp22Value)
+                               {
+                                       case BBP22_TXFRAME:
+                                               {
+                                                       if (pAdapter->ate.TxCount == 0)
+                                                       {
+                                                       }
+                                                       ATEDBGPRINT(RT_DEBUG_TRACE,("START TXFRAME\n"));
+                                                       pAdapter->ate.bQATxStart = TRUE;
+                                                       Set_ATE_Proc(pAdapter, "TXFRAME");
+                                               }
+                                               break;
+
+                                       case BBP22_TXCONT_OR_CARRSUPP:
+                                               {
+                                                       ATEDBGPRINT(RT_DEBUG_TRACE,("BBP22_TXCONT_OR_CARRSUPP\n"));
+                                                       ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, 24, &Bbp24Value);
+
+                                                       switch (Bbp24Value)
+                                                       {
+                                                               case BBP24_TXCONT:
+                                                                       {
+                                                                               ATEDBGPRINT(RT_DEBUG_TRACE,("START TXCONT\n"));
+                                                                               pAdapter->ate.bQATxStart = TRUE;
+                                                                               Set_ATE_Proc(pAdapter, "TXCONT");
+                                                                       }
+                                                                       break;
+
+                                                               case BBP24_CARRSUPP:
+                                                                       {
+                                                                               ATEDBGPRINT(RT_DEBUG_TRACE,("START TXCARRSUPP\n"));
+                                                                               pAdapter->ate.bQATxStart = TRUE;
+                                                                               pAdapter->ate.Mode |= ATE_TXCARRSUPP;
+                                                                       }
+                                                                       break;
+
+                                                               default:
+                                                                       {
+                                                                               ATEDBGPRINT(RT_DEBUG_ERROR,("Unknown Start TX subtype !"));
+                                                                       }
+                                                                       break;
+                                                       }
+                                               }
+                                               break;
+
+                                       case BBP22_TXCARR:
+                                               {
+                                                       ATEDBGPRINT(RT_DEBUG_TRACE,("START TXCARR\n"));
+                                                       pAdapter->ate.bQATxStart = TRUE;
+                                                       Set_ATE_Proc(pAdapter, "TXCARR");
+                                               }
+                                               break;
+
+                                       default:
+                                               {
+                                                       ATEDBGPRINT(RT_DEBUG_ERROR,("Unknown Start TX subtype !"));
+                                               }
+                                               break;
+                               }
+
+                               if (pAdapter->ate.bQATxStart == TRUE)
+                               {
+                                       // prepare feedback
+                                       pRaCfg->length = htons(2);
+                                       pRaCfg->status = htons(0);
+
+                                       wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                               + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                               + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+                       if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+                       {
+                               ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() was failed in case RACFG_CMD_TX_START\n"));
+                           Status = -EFAULT;
+                       }
+                                       else
+                                       {
+                               ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_TX_START is done !\n"));
+                                       }
+                                       break;
+                               }
+
+TX_START_ERROR:
+                               // prepare feedback
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(err);
+
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_TX_START\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("feedback of TX_START_ERROR is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_GET_TX_STATUS:
+                       {
+                               UINT32 count;
+
+                               // prepare feedback
+                               pRaCfg->length = htons(6);
+                               pRaCfg->status = htons(0);
+                               count = htonl(pAdapter->ate.TxDoneCount);
+                               NdisMoveMemory(pRaCfg->data, &count, 4);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_GET_TX_STATUS\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_GET_TX_STATUS is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_TX_STOP:
+                       {
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_TX_STOP\n"));
+
+                               Set_ATE_Proc(pAdapter, "TXSTOP");
+
+                               // prepare feedback
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("copy_to_user() fail in case RACFG_CMD_TX_STOP\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_TX_STOP is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_RX_START:
+                       {
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_START\n"));
+
+                               pAdapter->ate.bQARxStart = TRUE;
+                               Set_ATE_Proc(pAdapter, "RXFRAME");
+
+                               // prepare feedback
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RX_START\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RX_START is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_RX_STOP:
+                       {
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_STOP\n"));
+
+                               Set_ATE_Proc(pAdapter, "RXSTOP");
+
+                               // prepare feedback
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RX_STOP\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RX_STOP is done !\n"));
+                               }
+                       }
+                       break;
+
+               /* The following cases are for new ATE GUI(not QA). */
+               /*==================================================*/
+               case RACFG_CMD_ATE_START_TX_CARRIER:
+                       {
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_CARRIER\n"));
+
+                               Set_ATE_Proc(pAdapter, "TXCARR");
+
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+                               ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_START_TX_CARRIER\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START_TX_CARRIER is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_ATE_START_TX_CONT:
+                       {
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_CONT\n"));
+
+                               Set_ATE_Proc(pAdapter, "TXCONT");
+
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+                               ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_START_TX_CONT\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START_TX_CONT is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_ATE_START_TX_FRAME:
+                       {
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_FRAME\n"));
+
+                               Set_ATE_Proc(pAdapter, "TXFRAME");
+
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+                               ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_START_TX_FRAME\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START_TX_FRAME is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_ATE_SET_BW:
+                       {
+                               SHORT    value = 0;
+                               UCHAR    str[LEN_OF_ARG];
+
+                               NdisZeroMemory(str, LEN_OF_ARG);
+
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_BW\n"));
+
+                               memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+                               value = ntohs(value);
+                               sprintf((PCHAR)str, "%d", value);
+
+                               Set_ATE_TX_BW_Proc(pAdapter, str);
+
+                               // prepare feedback
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_BW\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_BW is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_ATE_SET_TX_POWER0:
+                       {
+                               SHORT    value = 0;
+                               UCHAR    str[LEN_OF_ARG];
+
+                               NdisZeroMemory(str, LEN_OF_ARG);
+
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_POWER0\n"));
+
+                               memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+                               value = ntohs(value);
+                               sprintf((PCHAR)str, "%d", value);
+                               Set_ATE_TX_POWER0_Proc(pAdapter, str);
+
+                               // prepare feedback
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_TX_POWER0\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_POWER0 is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_ATE_SET_TX_POWER1:
+                       {
+                               SHORT    value = 0;
+                               UCHAR    str[LEN_OF_ARG];
+
+                               NdisZeroMemory(str, LEN_OF_ARG);
+
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_POWER1\n"));
+
+                               memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+                               value = ntohs(value);
+                               sprintf((PCHAR)str, "%d", value);
+                               Set_ATE_TX_POWER1_Proc(pAdapter, str);
+
+                               // prepare feedback
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_TX_POWER1\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_POWER1 is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_ATE_SET_FREQ_OFFSET:
+                       {
+                               SHORT    value = 0;
+                               UCHAR    str[LEN_OF_ARG];
+
+                               NdisZeroMemory(str, LEN_OF_ARG);
+
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_FREQ_OFFSET\n"));
+
+                               memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+                               value = ntohs(value);
+                               sprintf((PCHAR)str, "%d", value);
+                               Set_ATE_TX_FREQOFFSET_Proc(pAdapter, str);
+
+                               // prepare feedback
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_FREQ_OFFSET\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_FREQ_OFFSET is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_ATE_GET_STATISTICS:
+                       {
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_GET_STATISTICS\n"));
+
+                               memcpy_exl(pAdapter, &pRaCfg->data[0], (UCHAR *)&pAdapter->ate.TxDoneCount, 4);
+                               memcpy_exl(pAdapter, &pRaCfg->data[4], (UCHAR *)&pAdapter->WlanCounters.RetryCount.u.LowPart, 4);
+                               memcpy_exl(pAdapter, &pRaCfg->data[8], (UCHAR *)&pAdapter->WlanCounters.FailedCount.u.LowPart, 4);
+                               memcpy_exl(pAdapter, &pRaCfg->data[12], (UCHAR *)&pAdapter->WlanCounters.RTSSuccessCount.u.LowPart, 4);
+                               memcpy_exl(pAdapter, &pRaCfg->data[16], (UCHAR *)&pAdapter->WlanCounters.RTSFailureCount.u.LowPart, 4);
+                               memcpy_exl(pAdapter, &pRaCfg->data[20], (UCHAR *)&pAdapter->WlanCounters.ReceivedFragmentCount.QuadPart, 4);
+                               memcpy_exl(pAdapter, &pRaCfg->data[24], (UCHAR *)&pAdapter->WlanCounters.FCSErrorCount.u.LowPart, 4);
+                               memcpy_exl(pAdapter, &pRaCfg->data[28], (UCHAR *)&pAdapter->Counters8023.RxNoBuffer, 4);
+                               memcpy_exl(pAdapter, &pRaCfg->data[32], (UCHAR *)&pAdapter->WlanCounters.FrameDuplicateCount.u.LowPart, 4);
+                               memcpy_exl(pAdapter, &pRaCfg->data[36], (UCHAR *)&pAdapter->RalinkCounters.OneSecFalseCCACnt, 4);
+
+                               if (pAdapter->ate.RxAntennaSel == 0)
+                               {
+                                       INT32 RSSI0 = 0;
+                                       INT32 RSSI1 = 0;
+                                       INT32 RSSI2 = 0;
+
+                                       RSSI0 = (INT32)(pAdapter->ate.LastRssi0 - pAdapter->BbpRssiToDbmDelta);
+                                       RSSI1 = (INT32)(pAdapter->ate.LastRssi1 - pAdapter->BbpRssiToDbmDelta);
+                                       RSSI2 = (INT32)(pAdapter->ate.LastRssi2 - pAdapter->BbpRssiToDbmDelta);
+                                       memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&RSSI0, 4);
+                                       memcpy_exl(pAdapter, &pRaCfg->data[44], (UCHAR *)&RSSI1, 4);
+                                       memcpy_exl(pAdapter, &pRaCfg->data[48], (UCHAR *)&RSSI2, 4);
+                                       pRaCfg->length = htons(2+52);
+                               }
+                               else
+                               {
+                                       INT32 RSSI0 = 0;
+
+                                       RSSI0 = (INT32)(pAdapter->ate.LastRssi0 - pAdapter->BbpRssiToDbmDelta);
+                                       memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&RSSI0, 4);
+                                       pRaCfg->length = htons(2+44);
+                               }
+                               pRaCfg->status = htons(0);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_GET_STATISTICS\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_GET_STATISTICS is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_ATE_RESET_COUNTER:
+                       {
+                               SHORT    value = 1;
+                               UCHAR    str[LEN_OF_ARG];
+
+                               NdisZeroMemory(str, LEN_OF_ARG);
+
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_RESET_COUNTER\n"));
+
+                               sprintf((PCHAR)str, "%d", value);
+                               Set_ResetStatCounter_Proc(pAdapter, str);
+
+                               pAdapter->ate.TxDoneCount = 0;
+
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_RESET_COUNTER\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_RESET_COUNTER is done !\n"));
+                               }
+                       }
+
+                       break;
+
+               case RACFG_CMD_ATE_SEL_TX_ANTENNA:
+                       {
+                               SHORT    value = 0;
+                               UCHAR    str[LEN_OF_ARG];
+
+                               NdisZeroMemory(str, LEN_OF_ARG);
+
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SEL_TX_ANTENNA\n"));
+
+                               memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+                               value = ntohs(value);
+                               sprintf((PCHAR)str, "%d", value);
+                               Set_ATE_TX_Antenna_Proc(pAdapter, str);
+
+                               // prepare feedback
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SEL_TX_ANTENNA\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SEL_TX_ANTENNA is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_ATE_SEL_RX_ANTENNA:
+                       {
+                               SHORT    value = 0;
+                               UCHAR    str[LEN_OF_ARG];
+
+                               NdisZeroMemory(str, LEN_OF_ARG);
+
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SEL_RX_ANTENNA\n"));
+
+                               memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+                               value = ntohs(value);
+                               sprintf((PCHAR)str, "%d", value);
+                               Set_ATE_RX_Antenna_Proc(pAdapter, str);
+
+                               // prepare feedback
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SEL_RX_ANTENNA\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SEL_RX_ANTENNA is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_ATE_SET_PREAMBLE:
+                       {
+                               SHORT    value = 0;
+                               UCHAR    str[LEN_OF_ARG];
+
+                               NdisZeroMemory(str, LEN_OF_ARG);
+
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_PREAMBLE\n"));
+
+                               memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+                               value = ntohs(value);
+                               sprintf((PCHAR)str, "%d", value);
+                               Set_ATE_TX_MODE_Proc(pAdapter, str);
+
+                               // prepare feedback
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_PREAMBLE\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_PREAMBLE is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_ATE_SET_CHANNEL:
+                       {
+                               SHORT    value = 0;
+                               UCHAR    str[LEN_OF_ARG];
+
+                               NdisZeroMemory(str, LEN_OF_ARG);
+
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_CHANNEL\n"));
+
+                               memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+                               value = ntohs(value);
+                               sprintf((PCHAR)str, "%d", value);
+                               Set_ATE_CHANNEL_Proc(pAdapter, str);
+
+                               // prepare feedback
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_CHANNEL\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_CHANNEL is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_ATE_SET_ADDR1:
+                       {
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR1\n"));
+
+                               // Addr is an array of UCHAR,
+                               // so no need to perform endian swap.
+                               memcpy(pAdapter->ate.Addr1, (PUCHAR)(pRaCfg->data - 2), MAC_ADDR_LEN);
+
+                               // prepare feedback
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_ADDR1\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_ADDR1 is done !\n (ADDR1 = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAdapter->ate.Addr1[0],
+                                               pAdapter->ate.Addr1[1], pAdapter->ate.Addr1[2], pAdapter->ate.Addr1[3], pAdapter->ate.Addr1[4], pAdapter->ate.Addr1[5]));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_ATE_SET_ADDR2:
+                       {
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR2\n"));
+
+                               // Addr is an array of UCHAR,
+                               // so no need to perform endian swap.
+                               memcpy(pAdapter->ate.Addr2, (PUCHAR)(pRaCfg->data - 2), MAC_ADDR_LEN);
+
+                               // prepare feedback
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_ADDR2\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_ADDR2 is done !\n (ADDR2 = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAdapter->ate.Addr2[0],
+                                               pAdapter->ate.Addr2[1], pAdapter->ate.Addr2[2], pAdapter->ate.Addr2[3], pAdapter->ate.Addr2[4], pAdapter->ate.Addr2[5]));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_ATE_SET_ADDR3:
+                       {
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR3\n"));
+
+                               // Addr is an array of UCHAR,
+                               // so no need to perform endian swap.
+                               memcpy(pAdapter->ate.Addr3, (PUCHAR)(pRaCfg->data - 2), MAC_ADDR_LEN);
+
+                               // prepare feedback
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_ADDR3\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_ADDR3 is done !\n (ADDR3 = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAdapter->ate.Addr3[0],
+                                               pAdapter->ate.Addr3[1], pAdapter->ate.Addr3[2], pAdapter->ate.Addr3[3], pAdapter->ate.Addr3[4], pAdapter->ate.Addr3[5]));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_ATE_SET_RATE:
+                       {
+                               SHORT    value = 0;
+                               UCHAR    str[LEN_OF_ARG];
+
+                               NdisZeroMemory(str, LEN_OF_ARG);
+
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_RATE\n"));
+
+                               memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+                               value = ntohs(value);
+                               sprintf((PCHAR)str, "%d", value);
+                               Set_ATE_TX_MCS_Proc(pAdapter, str);
+
+                               // prepare feedback
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_RATE\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_RATE is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_ATE_SET_TX_FRAME_LEN:
+                       {
+                               SHORT    value = 0;
+                               UCHAR    str[LEN_OF_ARG];
+
+                               NdisZeroMemory(str, LEN_OF_ARG);
+
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_FRAME_LEN\n"));
+
+                               memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+                               value = ntohs(value);
+                               sprintf((PCHAR)str, "%d", value);
+                               Set_ATE_TX_LENGTH_Proc(pAdapter, str);
+
+                               // prepare feedback
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_TX_FRAME_LEN\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_FRAME_LEN is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_ATE_SET_TX_FRAME_COUNT:
+                       {
+                               USHORT    value = 0;
+                               UCHAR    str[LEN_OF_ARG];
+
+                               NdisZeroMemory(str, LEN_OF_ARG);
+
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_FRAME_COUNT\n"));
+
+                               memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+                               value = ntohs(value);
+                               {
+                                       sprintf((PCHAR)str, "%d", value);
+                                       Set_ATE_TX_COUNT_Proc(pAdapter, str);
+                               }
+
+                               // prepare feedback
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_TX_FRAME_COUNT\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_FRAME_COUNT is done !\n"));
+                               }
+                       }
+                       break;
+
+               case RACFG_CMD_ATE_START_RX_FRAME:
+                       {
+                               ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_START\n"));
+
+                               Set_ATE_Proc(pAdapter, "RXFRAME");
+
+                               // prepare feedback
+                               pRaCfg->length = htons(2);
+                               pRaCfg->status = htons(0);
+                               wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+                                                                       + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+                                                                       + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+               if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+               {
+                       ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RX_START\n"));
+                    Status = -EFAULT;
+               }
+                               else
+                               {
+                       ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RX_START is done !\n"));
+                               }
+                       }
+                       break;
+               default:
+                       break;
+       }
+    ASSERT(pRaCfg != NULL);
+    if (pRaCfg != NULL)
+    {
+    kfree(pRaCfg);
+    }
+       return;
+}
+
+VOID BubbleSort(INT32 n, INT32 a[])
+{
+       INT32 k, j, temp;
+
+       for (k = n-1;  k>0;  k--)
+       {
+               for (j = 0; j<k; j++)
+               {
+                       if(a[j] > a[j+1])
+                       {
+                               temp = a[j];
+                               a[j]=a[j+1];
+                               a[j+1]=temp;
+                       }
+               }
+       }
+}
+
+VOID CalNoiseLevel(PRTMP_ADAPTER pAd, UCHAR channel, INT32 RSSI[3][10])
+{
+       INT32           RSSI0, RSSI1, RSSI2;
+       CHAR            Rssi0Offset, Rssi1Offset, Rssi2Offset;
+       UCHAR           BbpR50Rssi0 = 0, BbpR51Rssi1 = 0, BbpR52Rssi2 = 0;
+       UCHAR           Org_BBP66value = 0, Org_BBP69value = 0, Org_BBP70value = 0, data = 0;
+       USHORT          LNA_Gain = 0;
+       INT32       j = 0;
+       UCHAR           Org_Channel = pAd->ate.Channel;
+       USHORT      GainValue = 0, OffsetValue = 0;
+
+       ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &Org_BBP66value);
+       ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R69, &Org_BBP69value);
+       ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R70, &Org_BBP70value);
+
+       //**********************************************************************
+       // Read the value of LNA gain and Rssi offset
+       //**********************************************************************
+       RT28xx_EEPROM_READ16(pAd, EEPROM_LNA_OFFSET, GainValue);
+
+       // for Noise Level
+       if (channel <= 14)
+       {
+               LNA_Gain = GainValue & 0x00FF;
+
+               RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET, OffsetValue);
+               Rssi0Offset = OffsetValue & 0x00FF;
+               Rssi1Offset = (OffsetValue & 0xFF00) >> 8;
+               RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_BG_OFFSET + 2)/* 0x48 */, OffsetValue);
+               Rssi2Offset = OffsetValue & 0x00FF;
+       }
+       else
+       {
+               LNA_Gain = (GainValue & 0xFF00) >> 8;
+
+               RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_A_OFFSET, OffsetValue);
+               Rssi0Offset = OffsetValue & 0x00FF;
+               Rssi1Offset = (OffsetValue & 0xFF00) >> 8;
+               RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_A_OFFSET + 2)/* 0x4C */, OffsetValue);
+               Rssi2Offset = OffsetValue & 0x00FF;
+       }
+       //**********************************************************************
+       {
+               pAd->ate.Channel = channel;
+               ATEAsicSwitchChannel(pAd);
+               mdelay(5);
+
+               data = 0x10;
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, data);
+               data = 0x40;
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, data);
+               data = 0x40;
+               ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, data);
+               mdelay(5);
+
+               // Start Rx
+               pAd->ate.bQARxStart = TRUE;
+               Set_ATE_Proc(pAd, "RXFRAME");
+
+               mdelay(5);
+
+               for (j = 0; j < 10; j++)
+               {
+                       ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R50, &BbpR50Rssi0);
+                       ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R51, &BbpR51Rssi1);
+                       ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R52, &BbpR52Rssi2);
+
+                       mdelay(10);
+
+                       // Calculate RSSI 0
+                       if (BbpR50Rssi0 == 0)
+                       {
+                               RSSI0 = -100;
+                       }
+                       else
+                       {
+                               RSSI0 = (INT32)(-12 - BbpR50Rssi0 - LNA_Gain - Rssi0Offset);
+                       }
+                       RSSI[0][j] = RSSI0;
+
+                       if ( pAd->Antenna.field.RxPath >= 2 ) // 2R
+                       {
+                               // Calculate RSSI 1
+                               if (BbpR51Rssi1 == 0)
+                               {
+                                       RSSI1 = -100;
+                               }
+                               else
+                               {
+                                       RSSI1 = (INT32)(-12 - BbpR51Rssi1 - LNA_Gain - Rssi1Offset);
+                               }
+                               RSSI[1][j] = RSSI1;
+                       }
+
+                       if ( pAd->Antenna.field.RxPath >= 3 ) // 3R
+                       {
+                               // Calculate RSSI 2
+                               if (BbpR52Rssi2 == 0)
+                                       RSSI2 = -100;
+                               else
+                                       RSSI2 = (INT32)(-12 - BbpR52Rssi2 - LNA_Gain - Rssi2Offset);
+
+                               RSSI[2][j] = RSSI2;
+                       }
+               }
+
+               // Stop Rx
+               Set_ATE_Proc(pAd, "RXSTOP");
+
+               mdelay(5);
+
+               BubbleSort(10, RSSI[0]);        // 1R
+
+               if ( pAd->Antenna.field.RxPath >= 2 ) // 2R
+               {
+                       BubbleSort(10, RSSI[1]);
+               }
+
+               if ( pAd->Antenna.field.RxPath >= 3 ) // 3R
+               {
+                       BubbleSort(10, RSSI[2]);
+               }
+
+       }
+
+       pAd->ate.Channel = Org_Channel;
+       ATEAsicSwitchChannel(pAd);
+
+       // Restore original value
+    ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, Org_BBP66value);
+    ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, Org_BBP69value);
+    ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, Org_BBP70value);
+
+       return;
+}
+
+BOOLEAN SyncTxRxConfig(PRTMP_ADAPTER pAd, USHORT offset, UCHAR value)
+{
+       UCHAR tmp = 0, bbp_data = 0;
+
+       if (ATE_ON(pAd))
+       {
+               ATE_BBP_IO_READ8_BY_REG_ID(pAd, offset, &bbp_data);
+       }
+       else
+       {
+               RTMP_BBP_IO_READ8_BY_REG_ID(pAd, offset, &bbp_data);
+       }
+
+       /* confirm again */
+       ASSERT(bbp_data == value);
+
+       switch(offset)
+       {
+               case BBP_R1:
+                       /* Need to sync. tx configuration with legacy ATE. */
+                       tmp = (bbp_data & ((1 << 4) | (1 << 3))/* 0x18 */) >> 3;
+                   switch(tmp)
+                   {
+                               /* The BBP R1 bit[4:3] = 2 :: Both DACs will be used by QA. */
+                       case 2:
+                                       /* All */
+                                       pAd->ate.TxAntennaSel = 0;
+                           break;
+                               /* The BBP R1 bit[4:3] = 0 :: DAC 0 will be used by QA. */
+                       case 0:
+                                       /* Antenna one */
+                                       pAd->ate.TxAntennaSel = 1;
+                           break;
+                               /* The BBP R1 bit[4:3] = 1 :: DAC 1 will be used by QA. */
+                       case 1:
+                                       /* Antenna two */
+                                       pAd->ate.TxAntennaSel = 2;
+                           break;
+                       default:
+                           DBGPRINT(RT_DEBUG_TRACE, ("%s -- Sth. wrong!  : return FALSE; \n", __FUNCTION__));
+                           return FALSE;
+                   }
+                       break;/* case BBP_R1 */
+
+               case BBP_R3:
+                       /* Need to sync. rx configuration with legacy ATE. */
+                       tmp = (bbp_data & ((1 << 1) | (1 << 0))/* 0x03 */);
+                   switch(tmp)
+                   {
+                               /* The BBP R3 bit[1:0] = 3 :: All ADCs will be used by QA. */
+                       case 3:
+                                       /* All */
+                                       pAd->ate.RxAntennaSel = 0;
+                           break;
+                               /* The BBP R3 bit[1:0] = 0 :: ADC 0 will be used by QA, */
+                               /* unless the BBP R3 bit[4:3] = 2 */
+                       case 0:
+                                       /* Antenna one */
+                                       pAd->ate.RxAntennaSel = 1;
+                                       tmp = ((bbp_data & ((1 << 4) | (1 << 3))/* 0x03 */) >> 3);
+                                       if (tmp == 2)// 3R
+                                       {
+                                               /* Default : All ADCs will be used by QA */
+                                               pAd->ate.RxAntennaSel = 0;
+                                       }
+                           break;
+                               /* The BBP R3 bit[1:0] = 1 :: ADC 1 will be used by QA. */
+                       case 1:
+                                       /* Antenna two */
+                                       pAd->ate.RxAntennaSel = 2;
+                           break;
+                               /* The BBP R3 bit[1:0] = 2 :: ADC 2 will be used by QA. */
+                       case 2:
+                                       /* Antenna three */
+                                       pAd->ate.RxAntennaSel = 3;
+                           break;
+                       default:
+                           DBGPRINT(RT_DEBUG_ERROR, ("%s -- Impossible!  : return FALSE; \n", __FUNCTION__));
+                           return FALSE;
+                   }
+                       break;/* case BBP_R3 */
+
+        default:
+            DBGPRINT(RT_DEBUG_ERROR, ("%s -- Sth. wrong!  : return FALSE; \n", __FUNCTION__));
+            return FALSE;
+
+       }
+       return TRUE;
+}
+
+static VOID memcpy_exl(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len)
+{
+       ULONG i, Value = 0;
+       ULONG *pDst, *pSrc;
+       UCHAR *p8;
+
+       p8 = src;
+       pDst = (ULONG *) dst;
+       pSrc = (ULONG *) src;
+
+       for (i = 0 ; i < (len/4); i++)
+       {
+               /* For alignment issue, we need a variable "Value". */
+               memmove(&Value, pSrc, 4);
+               Value = htonl(Value);
+               memmove(pDst, &Value, 4);
+               pDst++;
+               pSrc++;
+       }
+       if ((len % 4) != 0)
+       {
+               /* wish that it will never reach here */
+               memmove(&Value, pSrc, (len % 4));
+               Value = htonl(Value);
+               memmove(pDst, &Value, (len % 4));
+       }
+}
+
+static VOID memcpy_exs(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len)
+{
+       ULONG i;
+       UCHAR *pDst, *pSrc;
+
+       pDst = dst;
+       pSrc = src;
+
+       for (i = 0; i < (len/2); i++)
+       {
+               memmove(pDst, pSrc, 2);
+               *((USHORT *)pDst) = htons(*((USHORT *)pDst));
+               pDst+=2;
+               pSrc+=2;
+       }
+
+       if ((len % 2) != 0)
+       {
+               memmove(pDst, pSrc, 1);
+       }
+}
+
+static VOID RTMP_IO_READ_BULK(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, UINT32 len)
+{
+       UINT32 i, Value;
+       UINT32 *pDst, *pSrc;
+
+       pDst = (UINT32 *) dst;
+       pSrc = (UINT32 *) src;
+
+       for (i = 0 ; i < (len/4); i++)
+       {
+               RTMP_IO_READ32(pAd, (ULONG)pSrc, &Value);
+               Value = htonl(Value);
+               memmove(pDst, &Value, 4);
+               pDst++;
+               pSrc++;
+       }
+       return;
+}
+
+INT Set_TxStop_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+       ATEDBGPRINT(RT_DEBUG_TRACE,("Set_TxStop_Proc\n"));
+
+       if (Set_ATE_Proc(pAd, "TXSTOP"))
+       {
+       return TRUE;
+}
+       else
+       {
+               return FALSE;
+       }
+}
+
+INT Set_RxStop_Proc(
+       IN      PRTMP_ADAPTER   pAd,
+       IN      PUCHAR                  arg)
+{
+       ATEDBGPRINT(RT_DEBUG_TRACE,("Set_RxStop_Proc\n"));
+
+       if (Set_ATE_Proc(pAd, "RXSTOP"))
+       {
+       return TRUE;
+}
+       else
+       {
+               return FALSE;
+       }
+}
+#endif // RALINK_28xx_QA //
+#endif // RALINK_ATE //
+