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

📄 rtusb_data.c

📁 TP Link 321 Linux Driver
💻 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-2006, Ralink Technology, Inc. * * All rights reserved.	Ralink's source	code is	an unpublished work	and	the * use of a	copyright notice does not imply	otherwise. This	source code * contains	confidential trade secret material of Ralink Tech. Any attemp * or participation	in deciphering,	decoding, reverse engineering or in	any * way altering	the	source code	is stricitly prohibited, unless	the	prior * written consent of Ralink Technology, Inc. is obtained. ***************************************************************************	Module Name:	rtmp_data.c	Abstract:	Ralink USB driver Tx/Rx functions	Revision History:	Who			When			What	--------	----------		----------------------------------------------*/#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};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;#ifdef RTMP_EMBEDDED	if ((pSkb = __dev_alloc_skb(DataSize + LENGTH_802_3 + 2, GFP_DMA|GFP_ATOMIC)) != NULL)#else	if ((pSkb = dev_alloc_skb(DataSize + LENGTH_802_3 + 2)) != NULL)#endif	{		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++;	}}NDIS_STATUS	RTMPDecryptPktBySoftware(	IN	PRTMP_ADAPTER	pAd,	IN	PUCHAR			pData,		IN	PRXD_STRUC		pRxD){	UCHAR	KeyIdx = pAd->PortCfg.DefaultKeyId;	DBGPRINT(RT_DEBUG_INFO, "RTMPDecryptPktBySoftware ==>\n");		// handle WEP decryption	if(pAd->PortCfg.WepStatus == Ndis802_11WEPEnabled)	{		UCHAR *pPayload = (UCHAR *)pData + LENGTH_802_11;		if (RTMPDecryptData(pAd, pPayload, pRxD->DataByteCnt - LENGTH_802_11) == FALSE)		{			DBGPRINT(RT_DEBUG_ERROR, "ERROR : Software decrypt WEP data fails.\n");				return (NDIS_STATUS_FAILURE);		}		else		{			pRxD->DataByteCnt -= 8;  //Minus IV[4] & ICV[4]						pRxD->CipherAlg = CIPHER_WEP64;		}								DBGPRINT(RT_DEBUG_INFO, "RTMPDecryptData WEP data Complete \n");							}	// handle TKIP decryption	else if(pAd->PortCfg.WepStatus == Ndis802_11Encryption2Enabled)	{			if (RTMPSoftDecryptTKIP(pAd, pData, pRxD->DataByteCnt, 0, &pAd->SharedKey[KeyIdx]))		{											DBGPRINT(RT_DEBUG_INFO, "RTMPSoftDecryptTKIP Complete \n");									pRxD->DataByteCnt -= 20;  //Minus 8 bytes MIC, 8 bytes IV/EIV, 4 bytes ICV			pRxD->CipherAlg = CIPHER_TKIP;		}		else		{			DBGPRINT(RT_DEBUG_ERROR, "ERROR : RTMPSoftDecryptTKIP Failed\n");			return (NDIS_STATUS_FAILURE);		}	}	// handle AES decryption	else if(pAd->PortCfg.WepStatus == Ndis802_11Encryption3Enabled)	{		if (RTMPSoftDecryptAES(pAd, pData, pRxD->DataByteCnt, &pAd->SharedKey[KeyIdx]))		{										DBGPRINT(RT_DEBUG_INFO, "RTMPSoftDecryptAES Complete \n");										pRxD->DataByteCnt -= 16;  //8 bytes MIC, 8 bytes IV/EIV (CCMP Header)			pRxD->CipherAlg = CIPHER_AES;		}		else		{			DBGPRINT(RT_DEBUG_ERROR, "ERROR : RTMPSoftDecryptAES Failed\n");			return (NDIS_STATUS_FAILURE);		}	}	else	{		return (NDIS_STATUS_FAILURE);	}		            			return (NDIS_STATUS_SUCCESS);}// 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// edit by johnli, fix WPAPSK/WPA2PSK bugs for receiving EAPoL fragmentation packets/* #define REPORT_MGMT_FRAME_TO_MLME(_pAd, _pFrame, _FrameSize, _Rssi, _PlcpSignal)		\{																						\	MlmeEnqueueForRecv(_pAd, (UCHAR)_Rssi, _FrameSize, _pFrame, (UCHAR)_PlcpSignal);   \}*/#define REPORT_MGMT_FRAME_TO_MLME(_pAd, _p80211hdr, _pFrame, _FrameSize, _Rssi, _PlcpSignal)		\{																						\	MlmeEnqueueForRecv(_pAd, (PFRAME_802_11)_p80211hdr, (UCHAR)_Rssi, _FrameSize, _pFrame, (UCHAR)_PlcpSignal);   \}// end johnli// 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;	PQUEUE_HEADER	pTxQueue;	UCHAR			PsMode;	unsigned long	IrqFlags;		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;	}    	//	// Check for multicast or broadcast (First byte of DA)	//	if ((*((PUCHAR) pSrcBufVA) & 0x01) != 0)	{		// For multicast & broadcast, there is no fragment allowed		NumberOfFrag = 1;	}	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);	// Make sure SendTxWait queue resource won't be used by other threads	NdisAcquireSpinLock(&pAd->SendTxWaitQueueLock[QueIdx], IrqFlags);	pTxQueue = &pAd->SendTxWaitQueue[QueIdx];	if (pTxQueue->Number > pAd->MaxTxQueueSize)	{#ifdef BLOCK_NET_IF		StopNetIfQueue(pAd, QueIdx, pSkb);#endif // BLOCK_NET_IF //		NdisReleaseSpinLock(&pAd->SendTxWaitQueueLock[QueIdx], IrqFlags);		return NDIS_STATUS_FAILURE;	}	//	// 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		InsertTailQueue(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			InsertTailQueue(pTxQueue, pSkb);			Status = NDIS_STATUS_SUCCESS;#ifdef DBG            pAd->RalinkCounters.OneSecOsTxCount[QueIdx]++;  // TODO: for debug only. to be removed#endif					}	}	NdisReleaseSpinLock(&pAd->SendTxWaitQueueLock[QueIdx], IrqFlags);	DBGPRINT(RT_DEBUG_INFO, "<==== RTMPSendPacket\n");	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");#ifdef RALINK_ATE	if (pAd->ate.Mode != ATE_STASTART)	{		RTUSBFreeSkbBuffer(pSkb);		return 0;	}#endif	 	 	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) )	{		RTUSBFreeSkbBuffer(pSkb);		return 0;	}	else	{		// Record that orignal packet source is from protocol layer,so that 		// later on driver knows how to release this skb buffer

⌨️ 快捷键说明

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