diff options
Diffstat (limited to 'drivers/staging/rt3070/rt_ate.c')
-rw-r--r-- | drivers/staging/rt3070/rt_ate.c | 6506 |
1 files changed, 6506 insertions, 0 deletions
diff --git a/drivers/staging/rt3070/rt_ate.c b/drivers/staging/rt3070/rt_ate.c new file mode 100644 index 0000000..9238d96 --- /dev/null +++ b/drivers/staging/rt3070/rt_ate.c @@ -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 // + |