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

📄 rtusb_data.c

📁 r73模块的无线网卡在Linux下的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	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;	PUCHAR			pWirelessPacket;	ULONG			NextMpduSize;	BOOLEAN			bRTS_CTSFrame = FALSE;	unsigned long flags;	// For 'Ndis' spin lock    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);    }	if (pAd->PortCfg.BssType == BSS_MONITOR && pAd->bAcceptRFMONTx == TRUE)	{		DBGPRINT(RT_DEBUG_INFO,"==>INJECT\n");		pTxContext	= &pAd->TxContext[QueIdx][pAd->NextTxIndex[QueIdx]];		if (pAd->TxRingTotalNumber[QueIdx] >= TX_RING_SIZE)		{			//Modified by Thomas			DBGPRINT_ERR("RTUSBHardTransmit: TX RING full\n");			//pAd->RalinkCounters.TxRingErrCount++;			//return (NDIS_STATUS_RESOURCES);			return (NDIS_STATUS_RINGFULL);		}		pTxContext->InUse	= TRUE;		pTxContext->LastOne	= 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;		TxD = *pDestTxD;		pTxD = &TxD;		RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);#endif		memset(pTxD, 0, sizeof(TXD_STRUC));		pWirelessPacket = pTxContext->TransferBuffer->WirelessPacket;		memcpy( pWirelessPacket, pSkb->data, pSkb->len );		TxSize = pSkb->len;				//+FCS		/*for (i=0; i<TxSize; i++)			DBGPRINT(RT_DEBUG_INFO,"RTUSBHardTransmit --> byte %u is %x\n", i, pWirelessPacket[i]);*/		RTUSBWriteTxDescriptor(pAd, pTxD, CIPHER_NONE /*CipherAlg*/, 0, 0xff /*KeyIdx*/,					FALSE /*bAckRequired*/, FALSE, FALSE, 4 /*RetryMode*/,					IFS_BACKOFF /*FrameGap*/, RTMP_GET_PACKET_TXRATE(pSkb) /*TxRate*/,					TxSize, QueIdx, 0, FALSE /*bRTS_CTSFrame*/);		TransferBufferLength = TxSize + sizeof(TXD_STRUC);		if ((TransferBufferLength % 4) == 1)			TransferBufferLength  += 3;		else if ((TransferBufferLength % 4) == 2)			TransferBufferLength  += 2;		else if ((TransferBufferLength % 4) == 3)			TransferBufferLength  += 1;		if ((TransferBufferLength % pAd->BulkOutMaxPacketSize) == 0)			TransferBufferLength += 4;		pTxContext->BulkOutSize = TransferBufferLength;		pTxContext->bWaitingBulkOut = TRUE;		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));		pAd->TxRingTotalNumber[QueIdx]++;	// sync. to PendingTx		RELEASE_NDIS_PACKET(pAd, pSkb);		return (NDIS_STATUS_SUCCESS);	}	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(RT_DEBUG_TRACE, "pSrcBufVA == NULL\n");		return(NDIS_STATUS_RESOURCES);	}	if (SrcBufLen < 14)	{		DBGPRINT(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 WPA_SUPPLICANT_SUPPORT		  || (pAd->PortCfg.IEEE8021X == TRUE)#endif         ) &&		((pAd->PortCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) || (pAd->PortCfg.MicErrCnt >= 2)) &&		(bEAPOLFrame == FALSE))	{		DBGPRINT(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);		Cipher = pAd->PortCfg.GroupCipher; // Cipher for Multicast or Broadcast	}	else	{		bAckRequired = TRUE;		Cipher = 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);#if 0	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))		Header_802_11.FC.SubType = SUBTYPE_QDATA;#endif	// --------------------------------------------------------	// 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;	if (bEAPOLFrame)	{        ASSERT(pAd->SharedKey[0].CipherAlg <= CIPHER_CKIP128);        if ((pAd->SharedKey[0].CipherAlg) &&            (pAd->SharedKey[0].KeyLen) )        {            CipherAlg = pAd->SharedKey[0].CipherAlg;            KeyIdx = 0;        }    }	else if (Cipher == Ndis802_11Encryption1Enabled)	{			// standard WEP64 or WEP128		KeyIdx = pAd->PortCfg.DefaultKeyId;	}	else if ((Cipher == Ndis802_11Encryption2Enabled) ||			 (Cipher == 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;	}	if (KeyIdx == 0xff)		CipherAlg = CIPHER_NONE;	else if (pAd->SharedKey[KeyIdx].KeyLen == 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	// 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))		{			//Modified by Thomas			DBGPRINT_ERR("RTUSBHardTransmit: TX RING full\n");			//pAd->RalinkCounters.TxRingErrCount++;			//return (NDIS_STATUS_RESOURCES);			return (NDIS_STATUS_RINGFULL);		}		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;		TxD = *pDestTxD;		pTxD = &TxD;		RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);#endif		memset(pTxD, 0, sizeof(TXD_STRUC));		pWirelessPacket = pTxContext->TransferBuffer->WirelessPacket;		//		// STEP 5.2 PUT IVOFFSET, IV, EIV INTO TXD		//		pTxD->IvOffset	= LENGTH_802_11;#if 0		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))			pTxD->IvOffset += 2;  // add QOS CONTROL bytes#endif		if ((CipherAlg == CIPHER_WEP64) || (CipherAlg == CIPHER_WEP128))		{			PUCHAR pTmp;			pTmp = (PUCHAR) &pTxD->Iv;			*pTmp		= RandomByte(pAd);			*(pTmp + 1) = RandomByte(pAd);			*(pTmp + 2) = RandomByte(pAd);			*(pTmp + 3) = (KeyIdx << 6);		}		else if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC))		{			RTMPInitTkipEngine(				pAd,				pKey->Key,				KeyIdx,		// This might cause problem when using peer key				Header_802_11.Addr2,				pKey->TxMic,				pKey->TxTsc,				&Iv16,				&Iv32);			memcpy(&pTxD->Iv, &Iv16, 4);   // Copy IV			memcpy(&pTxD->Eiv, &Iv32, 4);  // Copy EIV			INC_TX_TSC(pKey->TxTsc);			   // Increase TxTsc for next transmission

⌨️ 快捷键说明

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