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

📄 rtmp_data.c

📁 Linux下的RT系列无线网卡驱动,可以直接在x86平台上编译
💻 C
📖 第 1 页 / 共 5 页
字号:
		// STEP 6.1 And 1ST DMA BUFFER		//		//Save FirstTxWI.  Need to fill MPDUtotlabytecount when finish 		pFirstTxWI = (PTXWI_STRUC)pTxRing->Cell[TxIdx].DmaBuf.AllocVa;		pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;		 		BufBasePaLow  = RTMP_GetPhysicalAddressLow (pTxRing->Cell[TxIdx].DmaBuf.AllocPa);		// need to fill MPDU total byte count field at last step		pDMAHeaderBufPtr = pDMAHeaderBufVA;		//		// STEP 6.2 COPY TXWI and 802.11 HEADER INTO 1ST DMA BUFFER. IV/EIV will set by ASIC after searching on-chip WC table		//		NdisZeroMemory(pFirstTxWI, TXWI_SIZE);				// bWIV==FALSE, then Driver doesn't need to fill IV/EIV, which is filled by FCE.		//as Sta, the RA always is BSSID. So always use BSSID_WCID.		// DHCP uses low rate		if ((bDHCPFrame == TRUE) || (bEAPOLFrame == TRUE))		{			RTMPWriteTxWI(pAd, pFirstTxWI,  FALSE, FALSE, FALSE, TXWIAMPDU, bAckRequired, FALSE, 				TXWIBAWinSize, RAWcid, 0,PID, UserPriority,  TxRate, 				IFS_BACKOFF, bPiggyBack, &pAd->MacTab.Content[MCAST_WCID].HTPhyMode);			pAd->LastTxRate = (USHORT)(pAd->MacTab.Content[MCAST_WCID].HTPhyMode.word);			DBGPRINT_RAW(RT_DEBUG_INFO,("RTMPHardTransmit-DHCP packet uses MCS=%d, STBC=%d, ShortGI=%d, Mode=%d, BW=%d \n",				pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS, pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.STBC, pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.ShortGI,				pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MODE, pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.BW));		}		else if ((ADHOC_ON(pAd)) && (RAWcid > BSSID_WCID))	// for different adhoc STA, we use the same HTPhyMode as (RAWcid=BSSID_WCID)		{			RTMPWriteTxWI(pAd, pFirstTxWI,  FALSE, FALSE, FALSE, TXWIAMPDU, bAckRequired, FALSE, 				TXWIBAWinSize, RAWcid, 0,PID, UserPriority,  TxRate, 				FrameGap, bPiggyBack, &pAd->MacTab.Content[BSSID_WCID].HTPhyMode);			pAd->LastTxRate = (USHORT)(pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word);		}		else		{			RTMPWriteTxWI(pAd, pFirstTxWI,  FALSE, FALSE, FALSE, TXWIAMPDU, bAckRequired, FALSE, 				TXWIBAWinSize, RAWcid, 0,PID, UserPriority,  TxRate, 				FrameGap, bPiggyBack, &pAd->MacTab.Content[RAWcid].HTPhyMode);			pAd->LastTxRate = (USHORT)(pAd->MacTab.Content[RAWcid].HTPhyMode.word);		}		pDMAHeaderBufPtr += TXWI_SIZE;		NdisMoveMemory(pDMAHeaderBufPtr, &Header_802_11, sizeof(Header_802_11));		pDMAHeaderBufPtr		+= sizeof(Header_802_11);		MpduSize = sizeof(Header_802_11);							//		// STEP 6.3 ACQUIRE TXD. Init Ndispacket = NULL. Because it TxD is not necessarily the lastsec		//#ifndef BIG_ENDIAN		pTxD  = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;#else		pDestTxD  = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa;		TxD = *pDestTxD;		pTxD = &TxD;#endif        		RING_PACKET_INIT(pTxRing, TxIdx);		NdisZeroMemory(pTxD, TXD_SIZE);		pTxD->DMADONE = 1;		ptemp = (PULONG)pTxD;//		RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);		// 1st Buf always has TXWI+802.11header. This is preallocated DMABuf. But we need to reassign it every beginning of MPDU.		//pTxD->SDPtr0 = BufBasePaLow;		FreeTXDLeft--;		//		// Fragmentation is not allowed on multicast & broadcast. and is nether used in HT rate.		// So, we need to used the MAX_FRAG_THRESHOLD instead of pAd->CommonCfg.FragmentThreshold		// otherwise if PacketInfo.TotalPacketLength > pAd->CommonCfg.FragmentThreshold then		// packet will be fragment on multicast & broadcast.		//		if ((*pSrcBufVA & 0x01) || (bAllowFrag == FALSE)) //(pAd->CommonCfg.HTPhyMode.field.MODE >= MODE_HTMIX))		{			FreeMpduSize = MAX_AGGREGATION_SIZE - sizeof(Header_802_11) - LENGTH_CRC;		}		else		{			FreeMpduSize = pAd->CommonCfg.FragmentThreshold - sizeof(Header_802_11) - LENGTH_CRC;		}		// Note: if HT rate, WMM must inused.		//if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))		if (bWMM)		{			// HT rate must has QOS CONTROL bytes			if (bTXBA)				*pDMAHeaderBufPtr		  =  (UserPriority & 0x0f) ;			else				*pDMAHeaderBufPtr		  =  (UserPriority & 0x0f) | pAd->CommonCfg.AckPolicy[QueIdx];			if (bAMSDU == TRUE)			{				*pDMAHeaderBufPtr |= 0x80;			}			*(pDMAHeaderBufPtr+1)	  =  0;			pDMAHeaderBufPtr		  += 2;			MpduSize += 2;			FreeMpduSize  -= 2;			// Pad 2 bytes to make 802.11 header 4-byte alignment			if (bHTC == TRUE)			{				// HTC Control field(4 bytes) is following QOS field, padding 2 bytes				NdisZeroMemory(pDMAHeaderBufPtr, 6);				if (pAd->CommonCfg.bRdg == TRUE)					*(pDMAHeaderBufPtr+4)|=0x80;				if (pAd->bLinkAdapt == TRUE)				{	//bit2MRQ=1. Request for MCS feedback					*(pDMAHeaderBufPtr) |=0x4;					// Set identifier as 2					*(pDMAHeaderBufPtr) |= ((pAd->MRS)<<3);				}				pDMAHeaderBufPtr		  += 6;				MpduSize += 4;			}			else			{			    // padding 2 bytes				NdisZeroMemory(pDMAHeaderBufPtr, 2);				pDMAHeaderBufPtr		  += 2;			}		}		if (pNextPacket && (bAMSDU == FALSE))		{			FreeMpduSize  = MAX_AGGREGATION_SIZE;            //software aggregation puts the 2nd MSDU length(extra 2-byte field) after QOS_CONTROL. little endian		    // Handle Aggregation (A-MSUD for 11n station in HTMode or A-Ralink in Legacy 11g Ralink station, )			if (bARALINK)            {         			    // For RA Aggregation, 			    // put the 2nd MSDU length(extra 2-byte field) after QOS_CONTROL in little endian format				*pDMAHeaderBufPtr		  =  (UCHAR)NextPacketBufLen & 0xff;				*(pDMAHeaderBufPtr+1)	  =  (UCHAR)(NextPacketBufLen >> 8);                				pDMAHeaderBufPtr		  += 2;                MpduSize += 2;				Header_802_11.FC.Order = 1; // steal "order" bit to mark "aggregation"			}		}        if (bAMSDU)		{			/* A-MSDU format: DA + SA + Length + MSDU + Padding */     		//     		// use 1st dma buffer to store subframe header      		// DA(6)+SA(6)+Len(2)     		// 							     		// build subframe header     		NdisMoveMemory(pDMAHeaderBufPtr, &AMSDUsubheader[0], 14);     		pDMAHeaderBufPtr += 14;			MpduSize += 14;		}        		//		// STEP 5.4 COPY LLC/SNAP, CKIP MIC INTO 1ST DMA BUFFER ONLY WHEN THIS 		//			MPDU IS THE 1ST OR ONLY FRAGMENT 		//		if (Header_802_11.Frag == 0)		{			//if (pExtraLlcSnapEncap && (bAMSDU == FALSE))			if (pExtraLlcSnapEncap)			{#ifdef CONFIG_CKIP_SUPPORT				if ((pAd->StaCfg.CkipFlag & 0x08) && (bEAPOLFrame == FALSE))				{					// CKIP_LLC_SNAP is inused. The frame format must be -					//	   802.11 header + CKIP_LLCSNAP(8) + MIC(4) + TxSEQ(4) + Proto(2) + Payload					NdisMoveMemory(pDMAHeaderBufPtr, CKIP_LLC_SNAP, sizeof(CKIP_LLC_SNAP));					pDMAHeaderBufPtr += sizeof(CKIP_LLC_SNAP);					//					// 1.) Insert MIC [4]					//					RTMPCkipInsertCMIC(pAd, pDMAHeaderBufPtr, (PUCHAR)&Header_802_11, pPacket, pKey, CKIP_LLC_SNAP);					pDMAHeaderBufPtr += 4 ;					//					// 2.) Insert TX Sequence.					//					NdisMoveMemory(pDMAHeaderBufPtr, pAd->StaCfg.TxSEQ, 4);					pDMAHeaderBufPtr += 4;					NdisMoveMemory(pDMAHeaderBufPtr, pSrcBufVA + 12, 2);					pDMAHeaderBufPtr += 2;					MpduSize += 10;					FreeMpduSize -= (sizeof(CKIP_LLC_SNAP) + 10);					// Update TxSEQ for next TX					{ 						int i = 3;						pAd->StaCfg.TxSEQ[i] = pAd->StaCfg.TxSEQ[i] + 2;						while (pAd->StaCfg.TxSEQ[i] == 0x00)						{							i--;							if (i < 0) break;							pAd->StaCfg.TxSEQ[i] ++;						}					}				}				else#endif /* CONFIG_CKIP_SUPPORT */				{					// Insert LLC-SNAP encapsulation					NdisMoveMemory(pDMAHeaderBufPtr, pExtraLlcSnapEncap, 6);					pDMAHeaderBufPtr += 6;					NdisMoveMemory(pDMAHeaderBufPtr, pSrcBufVA + 12, 2);					pDMAHeaderBufPtr += 2;					MpduSize += LENGTH_802_1_H;					FreeMpduSize -= LENGTH_802_1_H;				}			}		}		//		// set 1st header size into TX DESC		//   --- TxWI + 802.11 Header		//   --- if (!A-MSDU)		// 			+ LLC/SNAP Encap		// 		 else		// 			+ DA(6)+SA(6)+Len(2)		// 				pTxD->SDPtr0 = BufBasePaLow;		pTxD->SDLen0 = (ULONG)(pDMAHeaderBufPtr - pDMAHeaderBufVA);		//		// STEP 5.5 TRAVERSE NDIS PACKET TO BUILD THE MPDU PAYLOAD		//		SrcBytesCopied	 = 0;		// Inner while loop is for getting enough TXD to send this MPDU. 		// SDPNowUsed starts from 1 because WI and 802.11Header already use SDP0 of 1st TXD.		SDPNowUsed = 1;		IsSD0 = TRUE;		do		{			// Assign Currently used TxD.  			SDPNowUsed ++;			if (SrcBufLen <= FreeMpduSize)			{				// scatter-gather buffer still fit into current MPDU				if (SrcBufLen != 0)				{					switch (SDPNowUsed%2) 					{						case 1:  {							PUCHAR pSubHeader;                            UCHAR   SDLen0 = 0;							ASSERT(FreeTXDLeft);							ASSERT(bAMSDU);							ASSERT(pNextPacket);							FreeTXDLeft--;							INC_RING_INDEX(TxIdx, TX_RING_SIZE);							//							// AMSDU packet: 2nd subframe							// 							// Init TxRing#ifndef BIG_ENDIAN							pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;#else							//Swap the endian of old pTxD and prepare to handle next pTxD.							RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);							WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);									pDestTxD  = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa;							TxD = *pDestTxD;							pTxD = &TxD;#endif                            							NdisZeroMemory(pTxD, TXD_SIZE);							pTxD->DMADONE = 1;							//RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);							//							// use 1st dma buffer to store sub-frame header							// pervious sub-frame padding + DA(6) + SA(6) + Len(2)							// 							BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);							pSubHeader = pTxRing->Cell[TxIdx].DmaBuf.AllocVa;                            if (bAMSDU)                            {    							ASSERT(padding < 4);    							pSubHeader += padding;    							// build sub-frame header    							NdisMoveMemory(pSubHeader, pNextPacketBufVA, 12);                                // if orginal Ethernet frame contains no LLC/SNAP, then an extra LLC/SNAP encap is required                                 EXTRA_LLCSNAP_ENCAP(pNextPacketBufVA, pExtraLlcSnapEncap);                                SDLen0 = padding + 14;                                NextPacketBufLen -= LENGTH_802_3;    							if (pExtraLlcSnapEncap)    							{    								NextPacketBufLen += LENGTH_802_1_H;    								NdisMoveMemory(pSubHeader+14, pExtraLlcSnapEncap, 6);    							    NdisMoveMemory(pSubHeader+14+6, pNextPacketBufVA+12, 2); 								    								SDLen0 += LENGTH_802_1_H;    							}                                    							pSubHeader[12] = (NextPacketBufLen & 0xFF00) >> 8;    							pSubHeader[13] = NextPacketBufLen & 0xFF;                            }                            else if (bARALINK)                            {                                NdisMoveMemory(pSubHeader , pNextPacketBufVA, 12);								NdisMoveMemory(pSubHeader+12, pNextPacketBufVA+12, 2);								SDLen0 = LENGTH_802_3;								//Here we didn't need to subtract the VLAN tag length, because we do it in previous.								NextPacketBufLen -= LENGTH_802_3;                            }							// update MPDU size							MpduSize += SDLen0;							// build TX Desc							pTxD->SDPtr0 = BufBasePaLow;							pTxD->SDLen0 = SDLen0;							pTxD->SDPtr1 = SrcBufPA;							pTxD->SDLen1 = SrcBufLen;                            //RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);							//pTxD->DMADONE = 0;							break;}						case 0: 							pTxD->SDPtr1 = SrcBufPA;							pTxD->SDLen1 = SrcBufLen;														if (bAMSDU || bARALINK)							{							                                pTxRing->Cell[TxIdx].pNdisPacket = pPacket;    							pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;                                RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);							} 							else							{								ASSERT(OrgSrcBufPA != SrcBufPA);							}							IsSD0 = FALSE;							if (letusprint == TRUE)							{								ptemp = (PULONG)pTxD;								DBGPRINT(RT_DEBUG_TRACE,("HardTx TxD[%ld]  SDPtr1 =%d,  SDLen1 = %08lx: %08lx: %08lx: %08lx  \n", TxIdx, pTxD->SDLen1,  *ptemp, *(ptemp+1), *(ptemp+2), *(ptemp+3)));							}							break;						default:	// should never happen							break;					}				}				else				{					SDPNowUsed--;	// not use this segment.				} 				 				SrcBytesCopied	+= SrcBufLen;				//pDMAHeaderBufPtr			+= SrcBufLen;				FreeMpduSize	-= SrcBufLen;				MpduSize		+= SrcBufLen;				SrcBufPA		+= SrcBufLen;				//SrcBufLen		 = 0;				//				// calcuate padding bytes for sub-frame				// put the padding bytes into 1st DMA buffer of next Tx DESC				// 				if (bAMSDU && (SrcBufIdx == 0))				{					ULONG AlignLen;					AlignLen = ((14+SrcBufLen)+3) & ~(0x3);					padding = AlignLen - (14+SrcBufLen);				}				// advance to next scatter-gather BUFFER				SrcBufIdx++;                if (SrcBufIdx < pScatterGatherList->NumberOfElements)				{					pTxD->LastSec0 = 0;					pTxD->LastSec1 = 0;					{						ULONG	OffsetSrcVA = (ULONG) pScatterGatherList->Elements[SrcBufIdx].Address;						//UCHAR   *Header = (UCHAR *)OffsetSrcVA;						SrcBufLen = pScatterGatherList->Elements[SrcBufIdx].Length;											OffsetSrcVA      += LENGTH_802_3;  // skip 802.3 header						SrcBufLen        -= LENGTH_802_3;  // skip 802.3 header					    						SrcBufPA          = PCI_MAP_SINGLE(pAd, (char *)OffsetSrcVA,												SrcBufLen, PCI_DMA_TODEVICE);  						SrcRemainingBytes -= LENGTH_802_3;					} 				}				else 				{					// Set Last Data Segment					pTxD->LastSec0 = 0;					pTxD->LastSec1 = 1;					SrcBufLen = 0;				}				if (SrcBufLen == 0)					break;			}			else			{				//scatter-gather buffer exceed current MPDU. leave some of the buffer to next MPDU				switch (SDPNowUsed%2) 				{					case 1: 		// Init TxRing 							NdisZeroMemory(pTxD, sizeof(pTxD));							pTxD->SDPtr0 = SrcBufPA;							pTxD->SDLen0 = FreeMpduSize;							pTxD->LastSec0 = 1;							DBGPRINT(RT_DEBUG_INFO,("Last Fraged TXD. Use pTxD[] SDPtr0, SDLen0

⌨️ 快捷键说明

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