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

📄 rtusb_data.c

📁 华硕无线网卡 167G linux 驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************  * RT2x00 SourceForge Project - http://rt2x00.sourceforge.net              *  *                                                                         *  *   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: * *	Revision History: *	Who		When		What *	--------	----------	------------------------------- *	Name		Date		Modification logs *	Jan Lee		2005-06-01	Release *	RobinC		02-06-2005	RFMON Mode added *	MathiasK	04-07-2005	big endian fix from gglomm ***************************************************************************/#include	"rt_config.h"static  UCHAR PlcpSignal[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.14static	UINT	_11G_RATES[12] = { 0, 0, 0, 0, 6, 9, 12, 18, 24, 36, 48, 54 };static	UCHAR	SNAP_802_1H[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};static	UCHAR	SNAP_BRIDGE_TUNNEL[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8};static	UCHAR	EAPOL[] = {0x88, 0x8e};static	UCHAR	IPX[] = {0x81, 0x37};static	UCHAR	APPLE_TALK[] = {0x80, 0xf3};UCHAR	ARP[]={0x08, 0x06};////////////////////////////////////////////////////////////////////////////////	FUNCTION//		RTUSBSendPackets//		//	DESCRIPTION//	  VNETMultipleSend handler is called by NDIS to transmit packets//	  through the adapter. If there are packets in the Q and the device//	  can accept the Tx requests initiate a transmission and queue the//	  rest of the packets (if any...). If we can not transmit or the//	  station is not ready we imediatelly complete the request//		//	INPUT//	  MiniportAdapterContext		Context registered with the wrapper//									(Ptr to to the Adapter object)//	  PacketArray					Array of Ptrs to NDIS_PACKET structs//	  NumberOfPackets				Number of packets in PacketArray//		//	OUTPUT//		-//		////////////////////////////////////////////////////////////////////////////int RTUSBSendPackets(struct sk_buff *skb, struct net_device *net_dev){	NDIS_STATUS 	Status = NDIS_STATUS_SUCCESS;	PRT2570ADAPTER	pAdapter = net_dev->priv;		skb->data_len = skb->len;	if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||		RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_REMOVE_IN_PROGRESS) ||		RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF) ||		RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_HALT_IN_PROGRESS))	{		RTUSBFreeSkbBuffer(skb);		return 0;	}	// Drop packets if no associations	else if (!INFRA_ON(pAdapter) && !ADHOC_ON(pAdapter) && 		   !( pAdapter->PortCfg.BssType == BSS_MONITOR && pAdapter->PortCfg.MallowRFMONTx == TRUE )		 )	{		RTUSBFreeSkbBuffer(skb);		return 0;	}	else	{		Status = RTUSBSendPacket(pAdapter, skb);	        if (Status != NDIS_STATUS_SUCCESS)	        {			// Errors before enqueue stage			RTUSBFreeSkbBuffer(skb);			DBGPRINT(RT_DEBUG_TRACE,"<---RTUSBSendPackets not dequeue\n");			return 0;	        }	}	// Dequeue one frame from SendTxWait queue and process it	// There are two place calling dequeue for TX ring.	// 1. Here, right after queueing the frame.	// 2. At the end of TxRingTxDone service routine.	if ((!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) && 		(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF)) &&		(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&		(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_REMOVE_IN_PROGRESS)) &&		(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_HALT_IN_PROGRESS)))	{	    //RTMPDeQueuePacket(pAdapter, &pAdapter->TxSwQueue0);	    // Call dequeue without selected queue, let the subroutine select the right priority	    // Tx software queue	    RTUSBDeQueuePacket(pAdapter);	}	// Kick bulk out	RTUSBKickBulkOut(pAdapter);	return 0;}NDIS_STATUS	RTUSBSendPacket(	IN	PRT2570ADAPTER	pAdapter,	IN  struct sk_buff  *skb){	PVOID			pVirtualAddress;	struct sk_buff_head     *pTxQueue;	ULONG					Priority;	UCHAR			NumberOfFrag;	UCHAR			RTSRequired;	UINT			AllowFragSize;	UCHAR                   AccessCategory;	NDIS_STATUS		Status = NDIS_STATUS_FAILURE;	UCHAR			PsMode;	// Init priority value	Priority = 0;	AccessCategory = 0;	if (skb && pAdapter->PortCfg.BssType == BSS_MONITOR &&		   pAdapter->PortCfg.MallowRFMONTx == TRUE)	{		NdisAcquireSpinLock(&pAdapter->SendTxWaitQueueLock);		skb_queue_tail(&pAdapter->SendTxWaitQueue, skb);		NdisReleaseSpinLock(&pAdapter->SendTxWaitQueueLock);		return (NDIS_STATUS_SUCCESS);	}		if (skb)	{		Priority = skb->priority;		// 802.11e/d4.4 June, 2003		if (Priority <=2)		    AccessCategory = 0;		else if (Priority == 3)		    AccessCategory = 1;		else if (Priority <= 5)		    AccessCategory = 2;		else		    AccessCategory = 3;		DBGPRINT(RT_DEBUG_INFO, "Priority = %d, AC = %d\n", Priority, AccessCategory);	}	// For TKIP, MIC value is treated as payload, it might be fragmented through	// different MPDUs.	if (pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled)	{		skb->data_len += 8;	}	pVirtualAddress = (PVOID)skb->data;	// Check for virtual address allocation, it might fail !!!	if (pVirtualAddress == NULL)	{		DBGPRINT(RT_DEBUG_TRACE,"<---RTUSBSendPacket NULL pVirtualAddress\n");		// Resourece is low, system did not allocation virtual address		// return NDIS_STATUS_FAILURE directly to upper layer		return (Status);	}	//	// Check for multicast or broadcast (First byte of DA)	//	if ((*((PUCHAR) pVirtualAddress) & 0x01) != 0)	{		// For multicast & broadcast, there is no fragment allowed		NumberOfFrag = 1;	}	else	{		// Check for payload allowed for each fragment		AllowFragSize = (pAdapter->PortCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;		// Calculate fragments required		NumberOfFrag = ((skb->data_len - LENGTH_802_3 + LENGTH_802_1_H) / AllowFragSize) + 1;		// Minus 1 if the size just match to allowable fragment size		if (((skb->data_len - LENGTH_802_3 + LENGTH_802_1_H) % AllowFragSize) == 0)		{			NumberOfFrag--;		}	}		// Check for requirement of RTS 	if (NumberOfFrag > 1)	{		// If multiple fragment required, RTS is required only for the first fragment		// if the fragment size large than RTS threshold		RTSRequired = (pAdapter->PortCfg.FragmentThreshold > pAdapter->PortCfg.RtsThreshold) ? 1 : 0;	}	else	{		RTSRequired = (skb->data_len > pAdapter->PortCfg.RtsThreshold) ? 1 : 0;	}	// RTS/CTS may also be required in order to protect OFDM frame	if ((pAdapter->PortCfg.TxRate >= RATE_FIRST_OFDM_RATE) && pAdapter->PortCfg.BGProtectionInUsed)		RTSRequired = 1;	//DBGPRINT(RT_DEBUG_TEMP, "Number of fragments :%d , include RTS :%d\n", NumberOfFrag, NumberOfFrag + RTSRequired);        	// Save framnet number to Ndis packet reserved field	RTMP_SET_PACKET_FRAGMENTS(skb, NumberOfFrag);	     	// Save RTS requirement to Ndis packet reserved field	RTMP_SET_PACKET_RTS(skb, RTSRequired);	// Make sure SendTxWait queue resource won't be used by other threads	NdisAcquireSpinLock(&pAdapter->SendTxWaitQueueLock);	pTxQueue = &pAdapter->SendTxWaitQueue;	if (INFRA_ON(pAdapter))	{		// 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, skb);		Status = NDIS_STATUS_SUCCESS;	}	else	{		// In IBSS mode, power state of destination should be considered.		PsMode = PWR_ACTIVE;		// Faked		if (PsMode == PWR_ACTIVE)		{			// Enqueue Ndis packet to end of Tx wait queue			skb_queue_tail(pTxQueue, skb);			Status = NDIS_STATUS_SUCCESS;		}	}		NdisReleaseSpinLock(&pAdapter->SendTxWaitQueueLock);	return Status;}VOID	RTUSBDeQueuePacket(	IN	PRT2570ADAPTER	pAdapter){	UCHAR			FragmentRequired;	NDIS_STATUS		Status = NDIS_STATUS_SUCCESS;	struct sk_buff  	*skb;	struct sk_buff_head     *pQueue;	UCHAR			Count = 0;	// Make sure SendTxWait queue resource won't be used by other threads	NdisAcquireSpinLock(&pAdapter->SendTxWaitQueueLock);	// Select Queue	pQueue = &pAdapter->SendTxWaitQueue;	// Check queue before dequeue	while (!skb_queue_empty(pQueue) && (Count < MAX_TX_PROCESS))	{		// Reset is in progress, stop immediately		if ( RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||			 RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_REMOVE_IN_PROGRESS) ||		     RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_HALT_IN_PROGRESS))		{			break;		}					// Dequeue the first entry from head of queue list		skb = skb_dequeue(pQueue);		// RTS or CTS-to-self for B/G protection mode has been set already.		// There is no need to re-do it here. 		// Total fragment required = number of fragment + RST if required		FragmentRequired = RTMP_GET_PACKET_FRAGMENTS(skb) + RTMP_GET_PACKET_RTS(skb);				if (RTUSBFreeDescriptorRequest(pAdapter, TX_RING, FragmentRequired) == NDIS_STATUS_SUCCESS)		{			// Avaliable ring descriptors are enough for this frame			// Call hard transmit			// Nitro mode / Normal mode selection			NdisReleaseSpinLock(&pAdapter->SendTxWaitQueueLock);			if (pAdapter->PortCfg.EnableTxBurst == 1)				Status = RTUSBHardEncrypt(pAdapter, skb, FragmentRequired, TRUE);			else								Status = RTUSBHardEncrypt(pAdapter, skb, FragmentRequired, FALSE);			//			// Acquire the resource again, snice we may need to process it in this while-loop.			//			NdisAcquireSpinLock(&pAdapter->SendTxWaitQueueLock);			if (Status == NDIS_STATUS_FAILURE)			{				// Packet failed due to various Ndis Packet error				RTUSBFreeSkbBuffer(skb);				break;			}			else if (Status == NDIS_STATUS_RESOURCES)			{				// Not enough free tx ring, it might happen due to free descriptor inquery might be not correct				// It also might change to NDIS_STATUS_FAILURE to simply drop the frame				// Put the frame back into head of queue				skb_queue_head(pQueue, skb);				break;			}						Count++;		}			else		{			skb_queue_head(pQueue, skb);			break;		}	}		NdisReleaseSpinLock(&pAdapter->SendTxWaitQueueLock);	return;	}NDIS_STATUS	RTUSBFreeDescriptorRequest(	IN		PRT2570ADAPTER	pAdapter,	IN		UCHAR			RingType,	IN		UCHAR			NumberRequired){	UCHAR			FreeNumber = 0;	UINT			Index;	NDIS_STATUS		Status = NDIS_STATUS_FAILURE;	switch (RingType)	{		case TX_RING:			Index = pAdapter->NextTxIndex;			do			{				PTX_CONTEXT	pTxD  = &pAdapter->TxContext[Index];								// While Owner bit is NIC, obviously ASIC still need it.				// If valid bit is TRUE, indicate that TxDone has not process yet				// We should not use it until TxDone finish cleanup job				if (pTxD->InUse == FALSE)				{					// This one is free					FreeNumber++;				}				else				{					break;				}									Index = (Index + 1) % TX_RING_SIZE;							}	while (FreeNumber < NumberRequired);	// Quit here ! Free number is enough !						if (FreeNumber >= NumberRequired)			{				Status = NDIS_STATUS_SUCCESS;			}						break;					case PRIO_RING:			Index = pAdapter->NextMLMEIndex;			do			{				PTX_CONTEXT	pTxD  = &pAdapter->MLMEContext[Index];								// While Owner bit is NIC, obviously ASIC still need it.				// If valid bit is TRUE, indicate that TxDone has not process yet				// We should not use it until TxDone finish cleanup job				if (pTxD->InUse == FALSE)				{					// This one is free					FreeNumber++;				}				else				{					break;				}									Index = (Index + 1) % PRIO_RING_SIZE;							}	while (FreeNumber < NumberRequired);	// Quit here ! Free number is enough !						if (FreeNumber >= NumberRequired)			{				Status = NDIS_STATUS_SUCCESS;			}			break;		default:			break;		}	return (Status);}/*	========================================================================		Routine Description:	Arguments:	Return Value:	IRQL = 	

⌨️ 快捷键说明

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