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

📄 rtusb_data.c

📁 r73模块的无线网卡在Linux下的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/*************************************************************************** * RT2x00 SourceForge Project - http://rt2x00.serialmonkey.com             * *                                                                         * *   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.             * *                                                                         * *   Licensed under the GNU GPL                                            * *   Original code supplied under license from RaLink Inc, 2004.           * ***************************************************************************//*************************************************************************** *	Module Name:	rtusb_data.c * *	Abstract: Ralink USB driver Tx/Rx functions * *	Revision History: *	Who		When		What *	--------	----------	----------------------------- *	idamlaj		05-10-2006	Import rfmon implementation *	idamlaj		14-10-2006	RFMONTx (based on MarkW's code) * ***************************************************************************/#include "rt_config.h"#include <net/iw_handler.h>extern	UCHAR Phy11BGNextRateUpward[]; // defined in mlme.cUCHAR	SNAP_802_1H[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};UCHAR	SNAP_BRIDGE_TUNNEL[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8};UCHAR	EAPOL_LLC_SNAP[]= {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e};UCHAR	EAPOL[] = {0x88, 0x8e};UCHAR	IPX[] = {0x81, 0x37};UCHAR	APPLE_TALK[] = {0x80, 0xf3};UINT	_11G_RATES[12] = { 0, 0, 0, 0, 6, 9, 12, 18, 24, 36, 48, 54 };UCHAR	RateIdToPlcpSignal[12] = {	 0, /* RATE_1 */	1, /* RATE_2 */ 	2, /* RATE_5_5 */	3, /* RATE_11 */	// see BBP spec	11, /* RATE_6 */   15, /* RATE_9 */    10, /* RATE_12 */   14, /* RATE_18 */	// see IEEE802.11a-1999 p.14	 9, /* RATE_24 */  13, /* RATE_36 */	8, /* RATE_48 */   12  /* RATE_54 */ }; // see IEEE802.11a-1999 p.14UCHAR	 OfdmSignalToRateId[16] = {	RATE_54,  RATE_54,	RATE_54,  RATE_54,	// OFDM PLCP Signal = 0,  1,  2,  3 respectively	RATE_54,  RATE_54,	RATE_54,  RATE_54,	// OFDM PLCP Signal = 4,  5,  6,  7 respectively	RATE_48,  RATE_24,	RATE_12,  RATE_6,	// OFDM PLCP Signal = 8,  9,  10, 11 respectively	RATE_54,  RATE_36,	RATE_18,  RATE_9,	// OFDM PLCP Signal = 12, 13, 14, 15 respectively};UCHAR default_cwmin[]={CW_MIN_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1, CW_MIN_IN_BITS-2};UCHAR default_cwmax[]={CW_MAX_IN_BITS, CW_MAX_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1};UCHAR default_sta_aifsn[]={3,7,2,2};UCHAR MapUserPriorityToAccessCategory[8] = {QID_AC_BE, QID_AC_BK, QID_AC_BK, QID_AC_BE, QID_AC_VI, QID_AC_VI, QID_AC_VO, QID_AC_VO};// Macro for rx indicationVOID REPORT_ETHERNET_FRAME_TO_LLC(	IN	PRTMP_ADAPTER	pAd,	IN	PUCHAR			p8023hdr,	IN	PUCHAR			pData,	IN	ULONG			DataSize,	IN	struct net_device	*net_dev){	struct sk_buff	*pSkb;	if ((pSkb = __dev_alloc_skb(DataSize + LENGTH_802_3 + 2, MEM_ALLOC_FLAG)) != NULL)	{		pSkb->dev = net_dev;		skb_reserve(pSkb, 2);	// 16 byte align the IP header		memcpy(skb_put(pSkb, LENGTH_802_3), p8023hdr, LENGTH_802_3);		memcpy(skb_put(pSkb, DataSize), pData, DataSize);		pSkb->protocol = eth_type_trans(pSkb, net_dev);		netif_rx(pSkb);		pAd->net_dev->last_rx = jiffies;		pAd->stats.rx_packets++;		pAd->Counters8023.GoodReceives++;	}	//DBGPRINT(RT_DEBUG_TRACE, "<-- %s: pSkb %s\n", __FUNCTION__,			//pSkb? "found": "n/a");}// Enqueue this frame to MLME engine// We need to enqueue the whole frame because MLME need to pass data type// information from 802.11 header#define REPORT_MGMT_FRAME_TO_MLME(_pAd, _pFrame, _FrameSize, _Rssi, _PlcpSignal)		\{																						\	MlmeEnqueueForRecv(_pAd, (UCHAR)_Rssi, _FrameSize, _pFrame, (UCHAR)_PlcpSignal);   \}// NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same//		 scatter gather bufferNDIS_STATUS Sniff2BytesFromNdisBuffer(	IN	struct sk_buff	*pFirstSkb,	IN	UCHAR			DesiredOffset,	OUT PUCHAR			pByte0,	OUT PUCHAR			pByte1){	PUCHAR pBufferVA;	ULONG  BufferLen, AccumulateBufferLen, BufferBeginOffset;	pBufferVA = (PVOID)pFirstSkb->data;	BufferLen = pFirstSkb->len;	BufferBeginOffset	= 0;	AccumulateBufferLen = BufferLen;	*pByte0 = *(PUCHAR)(pBufferVA + DesiredOffset - BufferBeginOffset);	*pByte1 = *(PUCHAR)(pBufferVA + DesiredOffset - BufferBeginOffset + 1);	return NDIS_STATUS_SUCCESS;}/*	========================================================================	Routine	Description:		This routine classifies outgoing frames into several AC (Access		Category) and enqueue them into corresponding s/w waiting queues.	Arguments:		pAd	Pointer	to our adapter		pPacket		Pointer to send packet	Return Value:		None	Note:	========================================================================*/NDIS_STATUS	RTMPSendPacket(	IN	PRTMP_ADAPTER	pAd,	IN	struct sk_buff	*pSkb){	PUCHAR			pSrcBufVA;	UINT			AllowFragSize;	UCHAR			NumberOfFrag;	UCHAR			RTSRequired;	UCHAR			QueIdx, UserPriority;	NDIS_STATUS 	Status = NDIS_STATUS_SUCCESS;	struct sk_buff_head	*pTxQueue;	UCHAR			PsMode;	DBGPRINT(RT_DEBUG_INFO, "====> RTMPSendPacket\n");	// Prepare packet information structure for buffer descriptor	pSrcBufVA = (PVOID)pSkb->data;	// STEP 1. Check for virtual address allocation, it might fail !!!	if (pSrcBufVA == NULL)	{		// Resourece is low, system did not allocate virtual address		// return NDIS_STATUS_FAILURE directly to upper layer		return NDIS_STATUS_FAILURE;	}	if (pSkb && pAd->PortCfg.BssType == BSS_MONITOR &&		   pAd->bAcceptRFMONTx == TRUE)	{		skb_queue_tail(&pAd->SendTxWaitQueue[QID_AC_BE], pSkb);		return (NDIS_STATUS_SUCCESS);	}	//	// Check for multicast or broadcast (First byte of DA)	//	if ((*((PUCHAR) pSrcBufVA) & 0x01) != 0)	{		// For multicast & broadcast, there is no fragment allowed		NumberOfFrag = 1;	}#if 0 //AGGREGATION_SUPPORT	else if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED))	{		NumberOfFrag = 1;	// Aggregation overwhelms fragmentation	}#endif	else	{		// Check for payload allowed for each fragment		AllowFragSize = (pAd->PortCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;		// Calculate fragments required		NumberOfFrag = ((pSkb->len - LENGTH_802_3 + LENGTH_802_1_H) / AllowFragSize) + 1;		// Minus 1 if the size just match to allowable fragment size		if (((pSkb->len - LENGTH_802_3 + LENGTH_802_1_H) % AllowFragSize) == 0)		{			NumberOfFrag--;		}	}	// Save fragment number to Ndis packet reserved field	RTMP_SET_PACKET_FRAGMENTS(pSkb, NumberOfFrag);	// STEP 2. Check the requirement of RTS:	//	   If multiple fragment required, RTS is required only for the first fragment	//	   if the fragment size large than RTS threshold	if (NumberOfFrag > 1)		RTSRequired = (pAd->PortCfg.FragmentThreshold > pAd->PortCfg.RtsThreshold) ? 1 : 0;	else		RTSRequired = (pSkb->len > pAd->PortCfg.RtsThreshold) ? 1 : 0;    //	// Remove the following lines to avoid confusion.	// CTS requirement will not use Flag "RTSRequired", instead moveing the	// following lines to RTUSBHardTransmit(..)	//	// RTS/CTS may also be required in order to protect OFDM frame	//if ((pAd->PortCfg.TxRate >= RATE_FIRST_OFDM_RATE) &&	//	OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))	//	RTSRequired = 1;	// Save RTS requirement to Ndis packet reserved field	RTMP_SET_PACKET_RTS(pSkb, RTSRequired);	RTMP_SET_PACKET_TXRATE(pSkb, pAd->PortCfg.TxRate);	//	// STEP 3. Traffic classification. outcome = <UserPriority, QueIdx>	//	UserPriority = 0;	QueIdx		 = QID_AC_BE;	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))	{		USHORT Protocol;		UCHAR  LlcSnapLen = 0, Byte0, Byte1;		do		{			// get Ethernet protocol field			Protocol = (USHORT)((pSrcBufVA[12] << 8) + pSrcBufVA[13]);			if (Protocol <= 1500)			{				// get Ethernet protocol field from LLC/SNAP				if (Sniff2BytesFromNdisBuffer(pSkb, LENGTH_802_3 + 6, &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)					break;				Protocol = (USHORT)((Byte0 << 8) + Byte1);				LlcSnapLen = 8;			}			// always AC_BE for non-IP packet			if (Protocol != 0x0800)				break;			// get IP header			if (Sniff2BytesFromNdisBuffer(pSkb, LENGTH_802_3 + LlcSnapLen, &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)				break;			// return AC_BE if packet is not IPv4			if ((Byte0 & 0xf0) != 0x40)				break;			UserPriority = (Byte1 & 0xe0) >> 5;			QueIdx = MapUserPriorityToAccessCategory[UserPriority];			// TODO: have to check ACM bit. apply TSPEC if ACM is ON			// TODO: downgrade UP & QueIdx before passing ACM			if (pAd->PortCfg.APEdcaParm.bACM[QueIdx])			{				UserPriority = 0;				QueIdx		 = QID_AC_BE;			}		} while (FALSE);	}	RTMP_SET_PACKET_UP(pSkb, UserPriority);	pTxQueue = &pAd->SendTxWaitQueue[QueIdx];	//	// For infrastructure mode, enqueue this frame immediately to sendwaitqueue	// For Ad-hoc mode, check the DA power state, then decide which queue to enqueue	//	if (INFRA_ON(pAd))	{		// In infrastructure mode, simply enqueue the packet into Tx waiting queue.		DBGPRINT(RT_DEBUG_INFO, "Infrastructure -> Enqueue one frame\n");		// Enqueue Ndis packet to end of Tx wait queue		skb_queue_tail(pTxQueue, pSkb);		Status = NDIS_STATUS_SUCCESS;#ifdef DBG        pAd->RalinkCounters.OneSecOsTxCount[QueIdx]++;  // TODO: for debug only. to be removed#endif	}	else	{		// In IBSS mode, power state of destination should be considered.		PsMode = PWR_ACTIVE;		// Faked		if (PsMode == PWR_ACTIVE)		{			DBGPRINT(RT_DEBUG_INFO,"Ad-Hoc -> Enqueue one frame\n");			// Enqueue Ndis packet to end of Tx wait queue			skb_queue_tail(pTxQueue, pSkb);			Status = NDIS_STATUS_SUCCESS;#ifdef DBG            pAd->RalinkCounters.OneSecOsTxCount[QueIdx]++;   // TODO: for debug only. to be removed#endif		}	}	return (Status);}/*	========================================================================	Routine Description:		SendPackets handler	Arguments:		skb 			point to sk_buf which upper layer transmit		net_dev 		point to net_dev	Return Value:		None	Note:	========================================================================*/INT RTMPSendPackets(	IN	struct sk_buff		*pSkb,	IN	struct net_device	*net_dev){	PRTMP_ADAPTER	pAd = net_dev->priv;	NDIS_STATUS 	Status = NDIS_STATUS_SUCCESS;	//INT 			Index;	DBGPRINT(RT_DEBUG_INFO, "===> RTMPSendPackets\n");	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||		RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))	{		// Drop send request since hardware is in reset state		RTUSBFreeSkbBuffer(pSkb);		return 0;	}	// Drop packets if no associations	else if (!INFRA_ON(pAd) && !ADHOC_ON(pAd) && !(pAd->PortCfg.BssType == BSS_MONITOR && pAd->bAcceptRFMONTx == TRUE))	{		RTUSBFreeSkbBuffer(pSkb);		return 0;	}	else	{		// initial pSkb->data_len=0, we will use this variable to store data size when fragment(in TKIP)		// and pSkb->len is actual data len		pSkb->data_len = pSkb->len;		// Record that orignal packet source is from protocol layer,so that		// later on driver knows how to release this skb buffer		RTMP_SET_PACKET_SOURCE(pSkb, PKTSRC_NDIS);		pAd->RalinkCounters.PendingNdisPacketCount ++;		Status = RTMPSendPacket(pAd, pSkb);		if (Status != NDIS_STATUS_SUCCESS)		{			// Errors before enqueue stage			RELEASE_NDIS_PACKET(pAd, pSkb);			DBGPRINT(RT_DEBUG_TRACE,"<---RTUSBSendPackets not dequeue\n");			return 0;		}	}	RTUSBMlmeUp(pAd);	return 0;}/*	========================================================================	Routine	Description:		Copy frame from waiting queue into relative ring buffer and set	appropriate ASIC register to kick hardware encryption before really	sent out to air.	Arguments:		pAd				Pointer	to our adapter		PNDIS_PACKET	Pointer to outgoing Ndis frame		NumberOfFrag	Number of fragment required	Return Value:		None	Note:	========================================================================*/#ifdef BIG_ENDIANstatic inline#endifNDIS_STATUS RTUSBHardTransmit(	IN	PRTMP_ADAPTER	pAd,	IN	struct sk_buff	*pSkb,	IN	UCHAR			NumberRequired,	IN	UCHAR			QueIdx){	UINT			LengthQosPAD =0;	UINT			BytesCopied;	UINT			TxSize;	UINT			FreeMpduSize;	UINT			SrcRemainingBytes;	USHORT			Protocol;	UCHAR			FrameGap;	HEADER_802_11	Header_802_11;	PHEADER_802_11	pHeader80211;	PUCHAR			pDest;//	PUCHAR			pSrc;	PTX_CONTEXT		pTxContext;	PTXD_STRUC		pTxD;#ifdef BIG_ENDIAN	PTXD_STRUC		pDestTxD;	TXD_STRUC		TxD;#endif//	PURB			pUrb;	BOOLEAN			StartOfFrame;	BOOLEAN			bEAPOLFrame;	ULONG			Iv16;	ULONG			Iv32;	BOOLEAN			MICFrag;//	PCIPHER_KEY		pWpaKey = NULL;	BOOLEAN			Cipher;	ULONG			TransferBufferLength;

⌨️ 快捷键说明

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