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

📄 rtmp_data.c

📁 Linux下的RT系列无线网卡驱动,可以直接在x86平台上编译
💻 C
📖 第 1 页 / 共 5 页
字号:
		{			// can't aggregate. put next packe back to TxSwQueue			InsertHeadQueue(&pAd->TxSwQueue[QueIdx], pNextEntry);			pNextPacket = NULL;  		}	}	// Decide if Packet Cloning is required -	// 1. when fragmentation && TKIP is inused, we have to clone it into a single buffer	//	  NDIS_PACKET so that driver can pre-cluculate and append TKIP MIC at tail of the	//	  source packet before hardware fragmentation can be performed	// 2. when CKIP MIC format is inused, we have to walk through the source NDIS packet to	//	  pre-calculate CMIC and insert at front of 1st output MPDU	if ((RTMP_GET_PACKET_SOURCE(pPacket) == PKTSRC_NDIS) && (bClonePacket == FALSE))	{		pScatterGatherList = (PRTMP_SCATTER_GATHER_LIST) 			GET_SG_LIST_FROM_PACKET(pPacket, &LocalScatterGatherList);		ASSERT(pScatterGatherList);				}	// Clone then release the original NDIS packet	if (bClonePacket)	{		PNDIS_PACKET pOutPacket;		NDIS_STATUS  Status;		printk("### Buggy: clone a fragmented packet as a linear packet ###\n");		Status = RTMPCloneNdisPacket(pAd, bAMSDU, pPacket, &pOutPacket);		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);		if (Status != NDIS_STATUS_SUCCESS)		{			if (pNextPacket)				RELEASE_NDIS_PACKET(pAd, pNextPacket, NDIS_STATUS_SUCCESS);			return Status;		}		// Use the new cloned packet from now on		pPacket = pOutPacket;		RTMP_SET_PACKET_UP(pPacket, UserPriority);		RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);	}    // if orginal Ethernet frame contains no LLC/SNAP, then an extra LLC/SNAP encap is required 	EXTRA_LLCSNAP_ENCAP(pSrcBufVA, pExtraLlcSnapEncap);	// link next MSDU into scatter list, if any	if (pNextPacket)	{		//		// A-MSDU or A-Ralink		// 		if (CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_AMSDU_INUSED))		{            USHORT subMSDULen;			if (pExtraLlcSnapEncap)				subMSDULen = SrcBufLen - LENGTH_802_3 + LENGTH_802_1_H;			else				subMSDULen = SrcBufLen - LENGTH_802_3;			// 2.1. Make sub-AMSDU header,						RTMPMoveMemory(&AMSDUsubheader[0], pSrcBufVA, 12);			AMSDUsubheader[12] = (subMSDULen & 0xFF00) >> 8;			AMSDUsubheader[13]= subMSDULen & 0xFF;			// This is a A-MSDU frame			bAMSDU = TRUE;		}		else		{			bARALINK = TRUE;// Ralink Aggregation 			pAd->RalinkCounters.OneSecTxAggregationCount++;		}		bAllowFrag = FALSE;		//		// set local scatter gather list 		// 		LocalScatterGatherList.NumberOfElements = 2;		LocalScatterGatherList.Elements[1].Length = NextPacketBufLen;		LocalScatterGatherList.Elements[1].Address = pNextPacketBufVA;		PacketInfo.TotalPacketLength += NextPacketBufLen;	}	pScatterGatherList = &LocalScatterGatherList;	// ------------------------------------------	// STEP 0.1 Add 802.1x protocol check.	// ------------------------------------------		if (NdisEqualMemory(EAPOL, pSrcBufVA + 12, 2))	{		bEAPOLFrame = TRUE;	}	else		bEAPOLFrame = FALSE;	// we using lowest basic rate when DHCP and EAPOL packet	if ((bDHCPFrame == TRUE) || (bEAPOLFrame == TRUE))		bHTRate = FALSE;	//	// WPA 802.1x secured port control - drop all non-802.1x frame before port secured	//	if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || 		 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||		 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || 		 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)#ifdef WPA_SUPPLICANT_SUPPORT		  || (pAd->StaCfg.IEEE8021X == TRUE) #endif // WPA_SUPPLICANT_SUPPORT //     		 		  ) &&		((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) || (pAd->StaCfg.MicErrCnt >= 2)) &&		(bEAPOLFrame == FALSE))	{    		DBGPRINT(RT_DEBUG_TRACE,("RTMPHardTransmit --> Drop packet before port secured !!!\n"));		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);		if (pNextPacket)		{			RELEASE_NDIS_PACKET(pAd, pNextPacket, NDIS_STATUS_FAILURE);		}		return (NDIS_STATUS_FAILURE);	}	// allow to use A-MPDU and A-MSDU altogether.	if (((pAd->MacTab.Content[RAWcid].TXBAbitmap&(1<<UserPriority)) != 0) 		&& (((INFRA_ON(pAd))) || ((*pSrcBufVA & 0x01) == 0))        && (bDHCPFrame == FALSE))		// only unicast RA use Block Ack.	{		bTXBA = TRUE;		bAllowFrag = FALSE;	}		if (pAd->CommonCfg.AckPolicy[QueIdx] != NORMAL_ACK)	{		bAckRequired = FALSE;		PID = 0;		Cipher = pAd->StaCfg.PairCipher; // Cipher for Unicast	}	else if (bTXBA)	{		bAckRequired = TRUE;		Cipher = pAd->StaCfg.PairCipher; // Cipher for Unicast	}	else if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd))) // Multicast or Broadcast	{		bAckRequired = FALSE;		INC_COUNTER64(pAd->WlanCounters.MulticastTransmittedFrameCount);		Cipher = pAd->StaCfg.GroupCipher; // Cipher for Multicast or Broadcast	}	else	{		bAckRequired = TRUE;		PID = 0;		Cipher = pAd->StaCfg.PairCipher; // Cipher for Unicast		if (letusprint == TRUE)			DBGPRINT_RAW(RT_DEBUG_TRACE, ("Use PairCipher = %d ", Cipher));	}	// When HT rate, always use IFS_HTTXOP	if (bHTRate == TRUE)		FrameGap = IFS_HTTXOP;	// When RTS enable, always use IFS_HTTXOP, or ASIC will not help send RTS frame	else if (PacketInfo.TotalPacketLength > pAd->CommonCfg.RtsThreshold)		FrameGap = IFS_HTTXOP;	// When B/G protection enable, always use IFS_HTTXOP, or ASIC will not help send CTS frame	else if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))		FrameGap = IFS_HTTXOP;	else if(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))	{		if (!pAd->CommonCfg.APEdcaParm.Txop[QueIdx])			FrameGap = IFS_HTTXOP;		else			FrameGap = IFS_BACKOFF;	}	// Tx burst mode	else if (pAd->CommonCfg.bEnableTxBurst)		FrameGap = IFS_HTTXOP;	// otherwise, always BACKOFF before transmission	else		FrameGap = IFS_BACKOFF; 	// Default frame gap mode	// ------------------------------------------------------------------	// STEP 1. WAKE UP PHY	//		outgoing frame always wakeup PHY to prevent frame lost and 	//		turn off PSM bit to improve performance	// ------------------------------------------------------------------	// not to change PSM bit, just send this frame out?	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))		AsicForceWakeup(pAd);	// It should not change PSM bit, when APSD turn on.	if ((!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable) && (pAd->CommonCfg.bAPSDForcePowerSave == FALSE)) || bEAPOLFrame)	{		if (pAd->StaCfg.Psm == PWR_SAVE)			MlmeSetPsmBit(pAd, PWR_ACTIVE);	}	// -----------------------------------------------------------------	// STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later. 	// -----------------------------------------------------------------	MAKE_802_11_HEADER(pAd, Header_802_11, pSrcBufVA);	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))	{		Header_802_11.FC.SubType = SUBTYPE_QDATA;		bWMM = TRUE;		if ((pAd->MacTab.Content[BSSID_WCID].HTCapability.ExtHtCapInfo.PlusHTC == TRUE) && (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE >= MODE_HTMIX) && (bDHCPFrame == FALSE))		{			Header_802_11.FC.Order = 1;	// HTC bit share with order bit			bHTC = TRUE;		}	}	// --------------------------------------------------------	// 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[BSS0][0].CipherAlg <= CIPHER_CKIP128);				// 4-way handshaking frame must be clear		if (!(bWPA4WAYFrame) && (pAd->SharedKey[BSS0][0].CipherAlg) &&			(pAd->SharedKey[BSS0][0].KeyLen))		{			CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;			KeyIdx = 0;		}	}	else if (Cipher == Ndis802_11Encryption1Enabled)	{#ifdef LEAP_SUPPORT				if (pAd->StaCfg.CkipFlag & 0x10) // Cisco CKIP KP is on		{			if (LEAP_CCKM_ON(pAd))			{				if (Header_802_11.Addr1[0] & 0x01)					KeyIdx = 1;				else					KeyIdx = 0;			}			else				KeyIdx = pAd->StaCfg.DefaultKeyId;		}		else if (pAd->StaCfg.CkipFlag & 0x08) // only CKIP CMIC			KeyIdx = pAd->StaCfg.DefaultKeyId;		else if (LEAP_CCKM_ON(pAd))		{			if (Header_802_11.Addr1[0] & 0x01)				KeyIdx = 1;			else				KeyIdx = 0;		}		else	// standard WEP64 or WEP128#endif // LEAP_SUPPORT //					KeyIdx = pAd->StaCfg.DefaultKeyId;	}	else if ((Cipher == Ndis802_11Encryption2Enabled) ||			 (Cipher == Ndis802_11Encryption3Enabled))	{		if (Header_802_11.Addr1[0] & 0x01) // multicast			KeyIdx = pAd->StaCfg.DefaultKeyId;		else if (pAd->SharedKey[BSS0][0].KeyLen)			KeyIdx = 0;		else			KeyIdx = pAd->StaCfg.DefaultKeyId;	}	if (KeyIdx == 0xff)		CipherAlg = CIPHER_NONE;	else if ((Cipher == Ndis802_11EncryptionDisabled) || (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 0))		CipherAlg = CIPHER_NONE;#ifdef WPA_SUPPLICANT_SUPPORT    else if ( pAd->StaCfg.WpaSupplicantUP &&              (Cipher == Ndis802_11Encryption1Enabled) &&             (pAd->StaCfg.IEEE8021X == TRUE) &&             (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))        CipherAlg = CIPHER_NONE;#endif // WPA_SUPPLICANT_SUPPORT //	else	{		Header_802_11.FC.Wep = 1;		CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;		pKey = &pAd->SharedKey[BSS0][KeyIdx];	}	// 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 NDIS PACKET). 	//			MAC ASIC will only perform IV/EIV/ICV insertion but no TKIP MIC	if ((MpduRequired > 1) && (CipherAlg == CIPHER_TKIP))	{		ASSERT(pScatterGatherList->NumberOfElements == 1);		RTMPCalculateMICValue(pAd, pPacket, pExtraLlcSnapEncap, pKey, 0);		NdisMoveMemory(pSrcBufVA + SrcBufLen, pAd->PrivateInfo.Tx.MIC, 8);		SrcBufLen += 8;		PacketInfo.TotalPacketLength += 8;		CipherAlg = CIPHER_TKIP_NO_MIC;	}	else	{		//		// Snice the ScatterGather may allocate on the contiguous range of the base physical address		// In that case, the pScatterGatherList->Elements[0].Length will equal to PacketInfo.TotalPacketLength		// And the pScatterGatherList->NumberOfElements will be reduce one snice the contiguous range of the data.		// So we need to reset the SrcBufLen as pScatterGatherList->Elements[0].Length as our first Packet length.		// Otherwise will not get the next pScatterGatherList Elements's length and cause TxRing Full.		// This is ok on PKTSRC_NDIS case or not the PKTSRC_NDIS case.		//			ASSERT(pScatterGatherList);		SrcBufLen		  = pScatterGatherList->Elements[0].Length;	}		// ----------------------------------------------------------------	// 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->CommonCfg.ExpectedACKRate[TxRate], 14);	if (RtsRequired)	{		// Leave this because maybe need driver send RTS/CTS future.	}	// --------------------------------------------------------	// STEP 5. SEARCH BA PEER(s). As Sta, always use MacTab.Content[BSSID_WCID]	// --------------------------------------------------------{    if (RAWcid != MCAST_WCID) 	{		MAC_TABLE_ENTRY *pMacEntry;		pMacEntry = &pAd->MacTab.Content[RAWcid];		        if (bTXBA)        {	            RABAOriIdx = pMacEntry->BAOriWcidArray[UserPriority];            TXWIBAWinSize = pAd->BATable.BAOriEntry[RABAOriIdx].BAWinSize;                        TXWIAMPDU = TRUE;            Header_802_11.Frag = 0;        }        Header_802_11.Sequence = pMacEntry->TxSeq[UserPriority];        pMacEntry->TxSeq[UserPriority] = (pMacEntry->TxSeq[UserPriority]+1) & 0x0FFF;    }    else    {		Header_802_11.Sequence = pAd->Sequence;		pAd->Sequence = (pAd->Sequence+1) & 0x0FFFF; // next sequence 		    }}		// --------------------------------------------------------	// STEP 6. 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	// --------------------------------------------------------		SrcBufIdx		  = 0;	SrcRemainingBytes = PacketInfo.TotalPacketLength;	{		ULONG	OffsetSrcVA = (ULONG)pScatterGatherList->Elements[0].Address;		OffsetSrcVA 	+= LENGTH_802_3;	// skip 802.3 header		SrcBufLen		-= LENGTH_802_3;	// skip 802.3 header												SrcBufPA		= (ULONG)PCI_MAP_SINGLE(pAd, (char *)OffsetSrcVA,							SrcBufLen, PCI_DMA_TODEVICE);		OrgSrcBufPA = SrcBufPA - LENGTH_802_3;		// update accurate payload size		SrcRemainingBytes = PacketInfo.TotalPacketLength - LENGTH_802_3;	}	//NdisAcquireSpinLock(&pAd->TxRingLock);	//TxIdx =pAd->TxRing[QueIdx].TxCpuIdx;	// Update SW_TX_IDX[QueIdx] and *pFreeTXDLeft after finish the copy while-loop	// FreeTXDLeft is used to record current Free TXD.	If return middle way, real *pFreeTXDLeft don't change.	FreeTXDLeft = *pFreeTXDLeft;		// Outer while loop loops for fragment packet. At beginning of outer loop, it's a complete wireless MPDU.	do	{		ULONG  BufBasePaLow;		if (FreeTXDLeft == 0)		{			DBGPRINT(RT_DEBUG_ERROR,("RTMPHardTransmit: No Free TXD Left\n"));			pAd->RalinkCounters.TxRingErrCount++;			//NdisReleaseSpinLock(&pAd->TxRingLock);			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);			if (pNextPacket)			{				RELEASE_NDIS_PACKET(pAd, pNextPacket, NDIS_STATUS_FAILURE);			}			return (NDIS_STATUS_RESOURCES);		}				//

⌨️ 快捷键说明

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