⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rt_ate.c

📁 Linux下的RT系列无线网卡驱动,可以直接在x86平台上编译
💻 C
📖 第 1 页 / 共 5 页
字号:
/* ************************************************************************* * Ralink Tech Inc. * 4F, No. 2 Technology 5th Rd. * Science-based Industrial Park * Hsin-chu, 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 RALINK_ATEUCHAR TemplateFrame[24] = {0x08,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;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 INT RtmpRfIoWrite(	IN PRTMP_ADAPTER pAd);static INT ATE_TxDInit(	IN PRTMP_ADAPTER pAd,	IN ULONG TxIdx);static INT ATE_TxPwrHandler(	IN PRTMP_ADAPTER pAd,	IN char index);static inline INT set_ate_proc_inline(	IN	PRTMP_ADAPTER	pAd, 	IN	PUCHAR			arg);static int checkMCSValid(	IN UCHAR Mode,	IN UCHAR Mcs);static VOID ATEWriteTxWI(	IN	PRTMP_ADAPTER	pAd,	IN	PTXWI_STRUC 	pOutTxWI,		IN	BOOLEAN			FRAG,		IN	BOOLEAN			CFACK,	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			TID,	IN	UCHAR			TxRate,	IN	UCHAR			Txopmode,		IN	BOOLEAN			CfAck,		IN	HTTRANSMIT_SETTING	*pTransmit);static VOID SetJapanFilter(	IN	PRTMP_ADAPTER	pAd);static INT TxDmaBusy(	IN PRTMP_ADAPTER pAd){	INT result;	WPDMA_GLO_CFG_STRUC GloCfg;	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);	// disable DMA	if (GloCfg.field.TxDMABusy)		result = 1;	else		result = 0;	return result;}static INT RxDmaBusy(	IN PRTMP_ADAPTER pAd){	INT result;	WPDMA_GLO_CFG_STRUC GloCfg;	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);	// disable DMA	if (GloCfg.field.RxDMABusy)		result = 1;	else		result = 0;	return result;}static VOID RtmpDmaEnable(	IN PRTMP_ADAPTER pAd,	IN INT Enable){	BOOLEAN value;	ULONG WaitCnt;	WPDMA_GLO_CFG_STRUC GloCfg;		value = Enable > 0 ? 1 : 0;	// check DMA is in busy mode.	WaitCnt = 0;	while (TxDmaBusy(pAd) || RxDmaBusy(pAd))	{		RTMPusecDelay(10);		if (WaitCnt++ > 100)			break;	}		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);	// disable DMA	GloCfg.field.EnableTxDMA = value;	GloCfg.field.EnableRxDMA = value;	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);	// abort all TX rings	RTMPusecDelay(5000);	return;}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 INT 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 0;}static INT ATE_TxDInit(	IN PRTMP_ADAPTER pAd,	IN ULONG TxIdx){	UINT j;	PTXD_STRUC pTxD;	PNDIS_PACKET pPacket;	PUCHAR pDest;	PVOID AllocVa;	NDIS_PHYSICAL_ADDRESS AllocPa;	HTTRANSMIT_SETTING	TxHTPhyMode;	PRTMP_TX_RING pTxRing = &pAd->TxRing[QID_AC_BE];	PTXWI_STRUC pTxWI = (PTXWI_STRUC) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;	PUCHAR pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;#ifdef	BIG_ENDIAN    PTXD_STRUC      pDestTxD;    TXD_STRUC       TxD;#endif#ifdef RALINK_2860_QA	PHEADER_802_11	pHeader80211;#endif // RALINK_2860_QA //	if (pAd->ate.bQATxStart == TRUE) 	{// decide Queue(not support yet)// always use QID_AC_BE and FIFO_EDCA		// fill TxWI		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.CFACK, pAd->ate.TxWI.TS,  pAd->ate.TxWI.AMPDU, pAd->ate.TxWI.ACK, pAd->ate.TxWI.NSEQ, 			pAd->ate.TxWI.BAWinSize, 0, pAd->ate.TxWI.MPDUtotalByteCount, pAd->ate.TxWI.PacketId, 0, 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, FALSE, FALSE, 			4, 0, pAd->ate.TxLength, 0, 0, 0, IFS_HTTXOP, FALSE, &TxHTPhyMode);	}	#ifdef BIG_ENDIAN	RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);#endif	// fill 802.11 header.#ifdef RALINK_2860_QA	if (pAd->ate.bQATxStart == TRUE) 	{		NdisMoveMemory(pDMAHeaderBufVA+TXWI_SIZE, pAd->ate.Header, pAd->ate.HLen);	}	else#endif // RALINK_2860_QA //	{		NdisMoveMemory(pDMAHeaderBufVA+TXWI_SIZE, TemplateFrame, LENGTH_802_11);		NdisMoveMemory(pDMAHeaderBufVA+TXWI_SIZE+4, pAd->ate.Addr1, ETH_LENGTH_OF_ADDRESS);		NdisMoveMemory(pDMAHeaderBufVA+TXWI_SIZE+10, pAd->ate.Addr2, ETH_LENGTH_OF_ADDRESS);		NdisMoveMemory(pDMAHeaderBufVA+TXWI_SIZE+16, pAd->ate.Addr3, ETH_LENGTH_OF_ADDRESS);	}#ifdef BIG_ENDIAN	RTMPFrameEndianChange(pAd, (PUCHAR)(pDMAHeaderBufVA+TXWI_SIZE), DIR_WRITE, FALSE);#endif	// alloc buffer for payload#ifdef RALINK_2860_QA	if (pAd->ate.bQATxStart == TRUE) 	{		pPacket = RTMP_AllocateRxPacketBuffer(pAd, pAd->ate.DLen + 0x100, FALSE, &AllocVa, &AllocPa);	}	else#endif // RALINK_2860_QA //	{		pPacket = RTMP_AllocateRxPacketBuffer(pAd, pAd->ate.TxLength, FALSE, &AllocVa, &AllocPa);	}	if (pPacket == NULL)	{		pAd->ate.TxCount = 0;		DBGPRINT(RT_DEBUG_TRACE, ("%s fail to alloc packet space.\n", __FUNCTION__));		return -1;	}	pTxRing->Cell[TxIdx].pNextNdisPacket = pPacket;	pDest = (PUCHAR) AllocVa;#ifdef RALINK_2860_QA	if (pAd->ate.bQATxStart == TRUE) 	{		RTPKT_TO_OSPKT(pPacket)->len = pAd->ate.DLen;	}	else#endif // RALINK_2860_QA //	{		RTPKT_TO_OSPKT(pPacket)->len = pAd->ate.TxLength - LENGTH_802_11;	}	// Prepare frame payload#ifdef RALINK_2860_QA	if (pAd->ate.bQATxStart == TRUE) 	{		// copy pattern		if ((pAd->ate.PLen != 0))		{			int j;						for (j = 0; j < pAd->ate.DLen; j+=pAd->ate.PLen)			{				memcpy(RTPKT_TO_OSPKT(pPacket)->data + j, pAd->ate.Pattern, pAd->ate.PLen);			}					}	}	else#endif // RALINK_2860_QA //	{		for(j = 0; j < RTPKT_TO_OSPKT(pPacket)->len; j++)			pDest[j] = 0xA5;	}#ifndef BIG_ENDIAN	pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;#else    pDestTxD  = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa;    TxD = *pDestTxD;    pTxD = &TxD;#endif#ifdef RALINK_2860_QA	if (pAd->ate.bQATxStart == TRUE)	{		// prepare TxD		NdisZeroMemory(pTxD, TXD_SIZE);		RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);		// build TX DESC		pTxD->SDPtr0 = RTMP_GetPhysicalAddressLow (pTxRing->Cell[TxIdx].DmaBuf.AllocPa);		pTxD->SDLen0 = TXWI_SIZE + pAd->ate.HLen;		pTxD->LastSec0 = 0;		pTxD->SDPtr1 = AllocPa;		pTxD->SDLen1 = RTPKT_TO_OSPKT(pPacket)->len;		pTxD->LastSec1 = 1;		pDest = (PUCHAR)pTxWI;		pDest += TXWI_SIZE;		pHeader80211 = (PHEADER_802_11)pDest;				// modify sequence number....		if (pAd->ate.TxDoneCount == 0)		{			pAd->ate.seq = pHeader80211->Sequence;		}		else			pHeader80211->Sequence = ++pAd->ate.seq;	}	else#endif // RALINK_2860_QA //	{		NdisZeroMemory(pTxD, TXD_SIZE);		RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);		// build TX DESC		pTxD->SDPtr0 = RTMP_GetPhysicalAddressLow (pTxRing->Cell[TxIdx].DmaBuf.AllocPa);		pTxD->SDLen0 = TXWI_SIZE + LENGTH_802_11;		pTxD->LastSec0 = 0;		pTxD->SDPtr1 = AllocPa;		pTxD->SDLen1 = RTPKT_TO_OSPKT(pPacket)->len;		pTxD->LastSec1 = 1;	}#ifdef BIG_ENDIAN    RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);    WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);#endif	return 0;}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: 			DBGPRINT(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;}static INT ATE_TxPwrHandler(	IN PRTMP_ADAPTER pAd,	IN char index){	ULONG R;	CHAR TxPower;	UCHAR Bbp94 = 0;	#ifdef RALINK_2860_QA	if ((pAd->ate.bQATxStart == TRUE) || (pAd->ate.bQARxStart == TRUE))	{		// todo - peter : how to get current TxPower0/1 from pAd->LatchRfRegs.//		if (pAd->ate.Channel != pAd->LatchRfRegs.Channel)			//		{//			pAd->ate.Channel = pAd->LatchRfRegs.Channel;//		}		return 0;	}	else#endif // RALINK_2860_QA //	{	if(index == 0)		TxPower = pAd->ate.TxPower0;	else		TxPower = 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;	}	DBGPRINT(RT_DEBUG_TRACE, ("%s (TxPower=%d, R3=%ld, BBP_R94=%d)\n", __FUNCTION__, TxPower, R, Bbp94));	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;	}	RtmpRfIoWrite(pAd);	return 0;	}}/*    ==========================================================================    Description:        Set ATE operation mode to        0. ATESTART  = Start ATE Mode

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -