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

📄 rtusb_data.c

📁 TP Link 321 Linux Driver
💻 C
📖 第 1 页 / 共 5 页
字号:
		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;			}			}	// 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(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) && 		(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) &&		(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&		(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))	{		for (Index = 0; Index < 4; Index++)		{			if(pAd->SendTxWaitQueue[Index].Number > 0)			{				RTMPDeQueuePacket(pAd, Index);			}		}	}	// Kick bulk out	RTUSBKickBulkOut(pAd);	DBGPRINT(RT_DEBUG_INFO, "<=== RTMPSendPackets\n");	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_ENDIAN	static 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;	NDIS_802_11_WEP_STATUS	EncryptType = Ndis802_11EncryptionDisabled;	ULONG			TransferBufferLength;	USHORT			AckDuration = 0;	USHORT			EncryptionOverhead = 0;	UCHAR			CipherAlg;	BOOLEAN			bAckRequired;	UCHAR			RetryMode = SHORT_RETRY;	UCHAR			UserPriority;	UCHAR			MpduRequired, RtsRequired;	UCHAR			TxRate;			PCIPHER_KEY		pKey = NULL ;	PUCHAR			pSrcBufVA = NULL;	ULONG			SrcBufLen;	PUCHAR			pExtraLlcSnapEncap = NULL; // NULL: no extra LLC/SNAP is required	UCHAR			KeyIdx, KeyLength = 0;	UCHAR			KeyTable = SHARED_KEY_TABLE;	PUCHAR			pWirelessPacket;	ULONG			NextMpduSize;	BOOLEAN			bRTS_CTSFrame = FALSE;	unsigned long   IrqFlags; //BensonLiu modify	DBGPRINT(RT_DEBUG_INFO, "====> RTUSBHardTransmit\n");    if ((pAd->PortCfg.bIEEE80211H == 1) && (pAd->PortCfg.RadarDetect.RDMode != RD_NORMAL_MODE))    {        DBGPRINT(RT_DEBUG_INFO,"RTUSBHardTransmit --> radar detect not in normal mode !!!\n");        return (NDIS_STATUS_FAILURE);    }	TxRate		 = RTMP_GET_PACKET_TXRATE(pSkb);	MpduRequired = RTMP_GET_PACKET_FRAGMENTS(pSkb);	RtsRequired  = RTMP_GET_PACKET_RTS(pSkb);	UserPriority = RTMP_GET_PACKET_UP(pSkb);		//	// Prepare packet information structure which will be query for buffer descriptor	//	pSrcBufVA = (PVOID)pSkb->data;	SrcBufLen = pSkb->len;	// Check for virtual address allocation, it might fail !!!	if (pSrcBufVA == NULL)	{		DBGPRINT_RAW(RT_DEBUG_TRACE, "pSrcBufVA == NULL\n");		return(NDIS_STATUS_RESOURCES);	}	if (SrcBufLen < 14)	{		DBGPRINT_RAW(RT_DEBUG_ERROR, "RTUSBHardTransmit --> Skb buffer error !!!\n");		return (NDIS_STATUS_FAILURE);	}	//	// If DHCP datagram or ARP datagram , we need to send it as Low rates.	//	if (pAd->PortCfg.Channel <= 14)	{		//		// Case 802.11 b/g		// basic channel means that we can use CCKM's low rate as RATE_1.		//				if ((TxRate != RATE_1) && RTMPCheckDHCPFrame(pAd, pSkb))			TxRate = RATE_1;	}	else	{		//		// Case 802.11a		// We must used OFDM's low rate as RATE_6, note RATE_1 is not allow		// Only OFDM support on Channel > 14		//		if ((TxRate != RATE_6) && RTMPCheckDHCPFrame(pAd, pSkb))			TxRate = RATE_6;	}		// ------------------------------------------	// STEP 0.1 Add 802.1x protocol check.	// ------------------------------------------	// For non-WPA network, 802.1x message should not encrypt even privacy is on.	if (NdisEqualMemory(EAPOL, pSrcBufVA + 12, 2))	{		bEAPOLFrame = TRUE;		if (pAd->PortCfg.MicErrCnt >= 2)			pAd->PortCfg.MicErrCnt++;	}	else		bEAPOLFrame = FALSE;	//	// WPA 802.1x secured port control - drop all non-802.1x frame before port secured	//	{		if (((pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPA)	 || 			 (pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||			 (pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPA2)	 ||			 (pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)#if defined(RALINK_WPA_SUPPLICANT_SUPPORT) || defined(NATIVE_WPA_SUPPLICANT_SUPPORT)			  || (pAd->PortCfg.IEEE8021X == TRUE)		#endif 		             	     ) &&			((pAd->PortCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) || (pAd->PortCfg.MicErrCnt >= 2)) &&			(bEAPOLFrame == FALSE))		{			DBGPRINT_RAW(RT_DEBUG_INFO, "RTUSBHardTransmit --> Drop packet before port secured !!!\n");			return (NDIS_STATUS_FAILURE);		}	}	if (*pSrcBufVA & 0x01) // Multicast or Broadcast	{			bAckRequired = FALSE;			INC_COUNTER64(pAd->WlanCounters.MulticastTransmittedFrameCount);			EncryptType = pAd->PortCfg.GroupCipher; // Cipher for Multicast or Broadcast	}	else	{			bAckRequired = TRUE;			EncryptType = pAd->PortCfg.PairCipher; // Cipher for Unicast	}	// 1. traditional TX burst	if (pAd->PortCfg.bEnableTxBurst && (pAd->Sequence & 0x7))		FrameGap = IFS_SIFS;  	// 2. frame belonging to AC that has non-zero TXOP	else if (pAd->PortCfg.APEdcaParm.bValid && pAd->PortCfg.APEdcaParm.Txop[QueIdx])		FrameGap = IFS_SIFS;	// 3. otherwise, always BACKOFF before transmission	else		FrameGap = IFS_BACKOFF;		// Default frame gap mode	Protocol = *(pSrcBufVA + 12) * 256 + *(pSrcBufVA + 13);	// if orginal Ethernet frame contains no LLC/SNAP, then an extra LLC/SNAP encap is required 	if (Protocol > 1500)	{		pExtraLlcSnapEncap = SNAP_802_1H;		if (NdisEqualMemory(IPX, pSrcBufVA + 12, 2) || 			NdisEqualMemory(APPLE_TALK, pSrcBufVA + 12, 2))		{			pExtraLlcSnapEncap = SNAP_BRIDGE_TUNNEL;		}	}	else		pExtraLlcSnapEncap = NULL;    // Update software power save state	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);	pAd->PortCfg.Psm = PWR_ACTIVE;		// -----------------------------------------------------------------	// STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST.	// -----------------------------------------------------------------	pAd->Sequence = ((pAd->Sequence) + 1) & (MAX_SEQ_NUMBER);	MAKE_802_11_HEADER(pAd, Header_802_11, pSrcBufVA, pAd->Sequence);	// --------------------------------------------------------	// STEP 3. FIND ENCRYPT KEY AND DECIDE CIPHER ALGORITHM	//		Find the WPA key, either Group or Pairwise Key	//		LEAP + TKIP also use WPA key.	// --------------------------------------------------------	// Decide WEP bit and cipher suite to be used. Same cipher suite should be used for whole fragment burst	// In Cisco CCX 2.0 Leap Authentication	//		   WepStatus is Ndis802_11Encryption1Enabled but the key will use PairwiseKey	//		   Instead of the SharedKey, SharedKey Length may be Zero.	KeyIdx = 0xff;	KeyTable = SHARED_KEY_TABLE;	if (bEAPOLFrame)	{        ASSERT(pAd->SharedKey[0].CipherAlg <= CIPHER_CKIP128);        if ((pAd->SharedKey[0].CipherAlg) &&            (pAd->SharedKey[0].KeyLen)	&& 			            ((pAd->PortCfg.PortSecured == WPA_802_1X_PORT_PASS_4_WAY) || 			 (pAd->PortCfg.PortSecured == WPA_802_1X_PORT_SECURED)))        {            CipherAlg = pAd->SharedKey[0].CipherAlg;            KeyIdx = 0;			KeyLength = pAd->SharedKey[KeyIdx].KeyLen;        }    }	else if (EncryptType == Ndis802_11Encryption1Enabled)	{		// standard WEP64 or WEP128		KeyIdx = pAd->PortCfg.DefaultKeyId;		KeyLength = pAd->SharedKey[KeyIdx].KeyLen;		}	else if ((EncryptType == Ndis802_11Encryption2Enabled) ||			 (EncryptType == Ndis802_11Encryption3Enabled))	{		if (Header_802_11.Addr1[0] & 0x01) // multicast			KeyIdx = pAd->PortCfg.DefaultKeyId;		else if (pAd->SharedKey[0].KeyLen)			KeyIdx = 0;		else			KeyIdx = pAd->PortCfg.DefaultKeyId;		KeyLength = pAd->SharedKey[KeyIdx].KeyLen;	}	if (KeyIdx == 0xff)		CipherAlg = CIPHER_NONE;	else if ((EncryptType == Ndis802_11EncryptionDisabled) || (KeyLength == 0))		CipherAlg = CIPHER_NONE;	else	{		Header_802_11.FC.Wep = 1;		CipherAlg = pAd->SharedKey[KeyIdx].CipherAlg;		pKey = &pAd->SharedKey[KeyIdx];		}	DBGPRINT(RT_DEBUG_INFO,"RTUSBHardTransmit(bEAP=%d) - %s key#%d, KeyLen=%d\n", 		bEAPOLFrame, CipherName[CipherAlg], KeyIdx, pAd->SharedKey[KeyIdx].KeyLen);	// STEP 3.1 if TKIP is used and fragmentation is required. Driver has to	//			append TKIP MIC at tail of the scatter buffer (This must be the	//			ONLY scatter buffer in the skb buffer). 	//			MAC ASIC will only perform IV/EIV/ICV insertion but no TKIP MIC	if ((MpduRequired > 1) && (CipherAlg == CIPHER_TKIP))	{		pSkb->len += 8;		CipherAlg = CIPHER_TKIP_NO_MIC;		}	// ----------------------------------------------------------------	// STEP 4. Make RTS frame or CTS-to-self frame if required	// ----------------------------------------------------------------	//	// calcuate the overhead bytes that encryption algorithm may add. This	// affects the calculate of "duration" field	//	if ((CipherAlg == CIPHER_WEP64) || (CipherAlg == CIPHER_WEP128)) 		EncryptionOverhead = 8; //WEP: IV[4] + ICV[4];	else if (CipherAlg == CIPHER_TKIP_NO_MIC)		EncryptionOverhead = 12;//TKIP: IV[4] + EIV[4] + ICV[4], MIC will be added to TotalPacketLength	else if (CipherAlg == CIPHER_TKIP)		EncryptionOverhead = 20;//TKIP: IV[4] + EIV[4] + ICV[4] + MIC[8]	else if (CipherAlg == CIPHER_AES)		EncryptionOverhead = 16;	// AES: IV[4] + EIV[4] + MIC[8]	else		EncryptionOverhead = 0;	// decide how much time an ACK/CTS frame will consume in the air	AckDuration = RTMPCalcDuration(pAd, pAd->PortCfg.ExpectedACKRate[TxRate], 14);	// If fragment required, MPDU size is maximum fragment size	// Else, MPDU size should be frame with 802.11 header & CRC	if (MpduRequired > 1)		NextMpduSize = pAd->PortCfg.FragmentThreshold;	else	{		NextMpduSize = pSkb->len + LENGTH_802_11 + LENGTH_CRC - LENGTH_802_3;		if (pExtraLlcSnapEncap)			NextMpduSize += LENGTH_802_1_H;	}	if (RtsRequired || OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RTS_PROTECTION_ENABLE))	{		RTMPSendRTSCTSFrame(pAd, 							Header_802_11.Addr1, 							NextMpduSize + EncryptionOverhead, 							TxRate,							pAd->PortCfg.RtsRate, 							AckDuration,							QueIdx,							FrameGap,							SUBTYPE_RTS);				// RTS/CTS-protected frame should use LONG_RETRY (=4) and SIFS		RetryMode = LONG_RETRY;		FrameGap = IFS_SIFS;		bRTS_CTSFrame = TRUE;				if (RtsRequired)			NumberRequired--;	}	else if ((pAd->PortCfg.TxRate >= RATE_FIRST_OFDM_RATE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))	{		RTMPSendRTSCTSFrame(pAd, 							Header_802_11.Addr1, 							NextMpduSize + EncryptionOverhead, 							TxRate,							pAd->PortCfg.RtsRate, 							AckDuration,							QueIdx,							FrameGap,							SUBTYPE_CTS);				// RTS/CTS-protected frame should use LONG_RETRY (=4) and SIFS		RetryMode = LONG_RETRY;		FrameGap = IFS_SIFS;		bRTS_CTSFrame = TRUE;	}	// --------------------------------------------------------	// STEP 5. START MAKING MPDU(s)	//		Start Copy Ndis Packet into Ring buffer.	//		For frame required more than one ring buffer (fragment), all ring buffers	//		have to be filled before kicking start tx bit.	//		Make sure TX ring resource won't be used by other threads	// --------------------------------------------------------	SrcRemainingBytes = pSkb->len - LENGTH_802_3;	SrcBufLen		 -= LENGTH_802_3;  // skip 802.3 header	StartOfFrame = TRUE;	MICFrag = FALSE;	// Flag to indicate MIC shall spread into two MPDUs	NdisAcquireSpinLock(&pAd->TxRingLock, IrqFlags);//BensonLiu modify		// Start Copy Ndis Packet into Ring buffer.	// For frame required more than one ring buffer (fragment), all ring buffers	// have to be filled before kicking start tx bit.	do	{		//		// STEP 5.1 Get the Tx Ring descriptor & Dma Buffer address		//		pTxContext	= &pAd->TxContext[QueIdx][pAd->NextTxIndex[QueIdx]];				if ((pTxContext->bWaitingBulkOut == TRUE) || (pTxContext->InUse == TRUE) ||			(pAd->TxRingTotalNumber[QueIdx] >= TX_RING_SIZE))		{			DBGPRINT_ERR("RTUSBHardTransmit: TX RING full\n");			pAd->RalinkCounters.TxRingErrCount++;			NdisReleaseSpinLock(&pAd->TxRingLock, IrqFlags);//BensonLiu modify			return (NDIS_STATUS_RESOURCES);		}				pTxContext->InUse	= TRUE;						// Increase & maintain Tx Ring Index		pAd->NextTxIndex[QueIdx]++;		if (pAd->NextTxIndex[QueIdx] >= TX_RING_SIZE)		{			pAd->NextTxIndex[QueIdx] = 0;		}#ifndef BIG_ENDIAN		pTxD  = (PTXD_STRUC) &pTxContext->TransferBuffer->TxDesc;#else		pDestTxD = (PTXD_STRUC) &pTxContext->TransferBuffer->TxDesc;

⌨️ 快捷键说明

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