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

📄 cmm_data.c

📁 Linux下的RT系列无线网卡驱动,可以直接在x86平台上编译
💻 C
📖 第 1 页 / 共 5 页
字号:
	// to the first scatter buffer size	//	// Initialize TX Descriptor	// For inter-frame gap, the number is for this frame and next frame	// For MLME rate, we will fix as 2Mb to match other vendor's implement//	pAd->CommonCfg.MlmeTransmit.field.MODE = 1;	// management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.	// Only beacon use Nseq=TRUE. So here we use Nseq=FALSE.	RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE, 		0, RESERVED_WCID, (SrcBufLen - TXWI_SIZE), PID_MGMT, 0,  (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);	pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket = pPacket;	pAd->TxRing[QueIdx].Cell[SwIdx].pNextNdisPacket = NULL;//	pFirstTxWI->MPDUtotalByteCount = SrcBufLen - TXWI_SIZE;#ifdef BIG_ENDIAN	RTMPWIEndianChange((PUCHAR)pFirstTxWI, TYPE_TXWI);#endif	SrcBufPA = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, PCI_DMA_TODEVICE);	RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_EDCA);	pTxD->LastSec0 = 1;	pTxD->LastSec1 = 1;	pTxD->SDLen0 = SrcBufLen;	pTxD->SDLen1 = 0;	pTxD->SDPtr0 = SrcBufPA;	pTxD->DMADONE = 0;#ifdef BIG_ENDIAN    RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);    WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);#endif	pAd->RalinkCounters.KickTxCount++;	pAd->RalinkCounters.OneSecTxDoneCount++;   	// Increase TX_CTX_IDX, but write to register later.	INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE);	RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx*0x10,  pAd->TxRing[QueIdx].TxCpuIdx);	   	// Make sure to release MGMT ring resource//	NdisReleaseSpinLock(&pAd->TxRingLock);	return NDIS_STATUS_SUCCESS;}NDIS_STATUS MlmeHardTransmitMgmtRing(	IN	PRTMP_ADAPTER	pAd,	IN	UCHAR	QueIdx,	IN	PNDIS_PACKET	pPacket){	PACKET_INFO 	PacketInfo;	PUCHAR			pSrcBufVA;	UINT			SrcBufLen;	PTXD_STRUC		pTxD;#ifdef BIG_ENDIAN    PTXD_STRUC      pDestTxD;    TXD_STRUC       TxD;#endif	PHEADER_802_11	pHeader_802_11;	BOOLEAN 		bAckRequired, bInsertTimestamp;	ULONG			SrcBufPA;	//UCHAR			TxBufIdx;	UCHAR			MlmeRate;	ULONG			SwIdx = pAd->MgmtRing.TxCpuIdx;	PTXWI_STRUC 	pFirstTxWI;	UCHAR			IrqState;	//ULONG	i;	//HTTRANSMIT_SETTING	MlmeTransmit;   //Rate for this MGMT frame.	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);		// Make sure MGMT ring resource won't be used by other threads	IrqState = pAd->irq_disabled;	if (!IrqState)		RTMP_SEM_LOCK(&pAd->MgmtRingLock);#ifndef BIG_ENDIAN			pTxD  = (PTXD_STRUC) pAd->MgmtRing.Cell[SwIdx].AllocVa;#else    pDestTxD  = (PTXD_STRUC)pAd->MgmtRing.Cell[SwIdx].AllocVa;    TxD = *pDestTxD;    pTxD = &TxD;    RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);#endif	if (pSrcBufVA == NULL)	{		// The buffer shouldn't be NULL		if (!IrqState)			RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);		return NDIS_STATUS_FAILURE;	}	// outgoing frame always wakeup PHY to prevent frame lost 	// if (pAd->StaCfg.Psm == PWR_SAVE)	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))		AsicForceWakeup(pAd);	pFirstTxWI	=(PTXWI_STRUC)pSrcBufVA;		pHeader_802_11			 = (PHEADER_802_11) (pSrcBufVA + TXWI_SIZE);	if (pHeader_802_11->Addr1[0] & 0x01)	{		MlmeRate = pAd->CommonCfg.BasicMlmeRate;	}	else	{		MlmeRate = pAd->CommonCfg.MlmeRate;	}		// Verify Mlme rate for a / g bands.		if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band		MlmeRate = RATE_6;	//	// Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE)	// Snice it's been set to 0 while on MgtMacHeaderInit	// By the way this will cause frame to be send on PWR_SAVE failed.	// 	// pHeader_802_11->FC.PwrMgmt = 0; // (pAd->StaCfg.Psm == PWR_SAVE);	//	// In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame#ifdef CONFIG_STA_SUPPORT	    // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD    	if (pHeader_802_11->FC.Type != BTYPE_DATA)	{#endif // CONFIG_STA_SUPPORT //	    	if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ) || !(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))    	{    		pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;    	}    	else    	{    		pHeader_802_11->FC.PwrMgmt = pAd->CommonCfg.bAPSDForcePowerSave;    	}#ifdef CONFIG_STA_SUPPORT     }#endif // CONFIG_STA_SUPPORT //		bInsertTimestamp = FALSE;	if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL	{		bAckRequired = FALSE;	}	else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)	{		//pAd->Sequence++;		//pHeader_802_11->Sequence = pAd->Sequence;		if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST		{			bAckRequired = FALSE;			pHeader_802_11->Duration = 0;		}		else		{			bAckRequired = TRUE;			pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);			if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)			{				bInsertTimestamp = TRUE;			}		}	}	pHeader_802_11->Sequence = pAd->Sequence++;	if (pAd->Sequence >0xfff)		pAd->Sequence = 0;	// Before radar detection done, mgmt frame can not be sent but probe req	// Because we need to use probe req to trigger driver to send probe req in passive scan	if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)		&& (pAd->CommonCfg.bIEEE80211H == 1)		&& (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE))	{		DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n"));		if (!IrqState)			RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);		return (NDIS_STATUS_FAILURE);	}#ifdef BIG_ENDIAN	RTMPFrameEndianChange(pAd, (PUCHAR)pHeader_802_11, DIR_WRITE, FALSE);#endif	//	// fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET	// should always has only one ohysical buffer, and the whole frame size equals	// to the first scatter buffer size	//	// Initialize TX Descriptor	// For inter-frame gap, the number is for this frame and next frame	// For MLME rate, we will fix as 2Mb to match other vendor's implement//	pAd->CommonCfg.MlmeTransmit.field.MODE = 1;	// management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.	RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE, 		0, RESERVED_WCID, (SrcBufLen - TXWI_SIZE), PID_MGMT, 0,  (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);//	pFirstTxWI->MPDUtotalByteCount = SrcBufLen - TXWI_SIZE;pAd->MgmtRing.Cell[SwIdx].pNdisPacket = pPacket;			  	pAd->MgmtRing.Cell[SwIdx].pNextNdisPacket = NULL;	  //	pFirstTxWI->MPDUtotalByteCount = SrcBufLen - TXWI_SIZE;#ifdef BIG_ENDIAN	RTMPWIEndianChange((PUCHAR)pFirstTxWI, TYPE_TXWI);#endif	SrcBufPA = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, PCI_DMA_TODEVICE);	RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_MGMT);	pTxD->LastSec0 = 1;	pTxD->LastSec1 = 1;	pTxD->DMADONE = 0;	pTxD->SDLen0 = SrcBufLen;	pTxD->SDLen1 = 0;	pTxD->SDPtr0 = SrcBufPA;#ifdef BIG_ENDIAN	RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);    WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);#endif	//==================================================================/*	DBGPRINT_RAW(RT_DEBUG_TRACE, ("MLMEHardTransmit\n"));	for (i = 0; i < (TXWI_SIZE+24); i++)	{			DBGPRINT_RAW(RT_DEBUG_TRACE, ("%x:", *(pSrcBufVA+i)));		if ( i%4 == 3)			DBGPRINT_RAW(RT_DEBUG_TRACE, (" :: "));		if ( i%16 == 15)			DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n      "));	}	DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n      "));*///=======================================================================	pAd->RalinkCounters.KickTxCount++;	pAd->RalinkCounters.OneSecTxDoneCount++;	// Increase TX_CTX_IDX, but write to register later.	INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);	RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX,  pAd->MgmtRing.TxCpuIdx);	// Make sure to release MGMT ring resource	if (!IrqState)		RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);	return NDIS_STATUS_SUCCESS;}/*	========================================================================	Routine Description:		To do the enqueue operation and extract the first item of waiting 		list. If a number of available shared memory segments could meet 		the request of extracted item, the extracted item will be fragmented		into shared memory segments.		Arguments:		pAd Pointer to our adapter		pQueue		Pointer to Waiting Queue			Return Value:		None	IRQL = DISPATCH_LEVEL		Note:		========================================================================*/VOID    RTMPDeQueuePacket(						 IN  PRTMP_ADAPTER   pAd,						 IN  BOOLEAN         bIntContext,						 IN  UCHAR           Max_Tx_Packets){	PQUEUE_ENTRY    pEntry;	PNDIS_PACKET pPacket;	UCHAR           MpduRequired;	NDIS_STATUS     Status;	UCHAR           Count=0;	PQUEUE_HEADER   pQueue;	ULONG           FreeNumber[NUM_OF_TX_RING]; //Number, FreeNumber[NUM_OF_TX_RING];	CHAR			QueIdx;	unsigned long	IrqFlags = 0;	UCHAR 			TxRate;	DBGPRINT(RT_DEBUG_INFO,("RTMPDeQueuePacket (Tx:%d)--> \n", Max_Tx_Packets));	//Max_Tx_Packets = 32;	for (QueIdx=0; QueIdx<=3; QueIdx++) 	{		Count=0;	while (1)	{		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)))			return;		if (Count >= Max_Tx_Packets)		{			break;		}		if (bIntContext == FALSE)			RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);    		//if ((pQueue = RTMPCheckTxSwQueue(pAd, &QueIdx)) != NULL)    		pQueue = &pAd->TxSwQueue[QueIdx];     		if (pQueue->Head != NULL)		{			// probe the Queue Head			pEntry = pQueue->Head;		}		else		{			if (bIntContext == FALSE)				RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);			break;		}       		// static rate also need NICUpdateFifoStaCounters() function.		//if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))			NICUpdateFifoStaCounters(pAd);    		FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);		pPacket = QUEUE_ENTRY_TO_PKT(pEntry);		// RTS or CTS-to-self for B/G protection mode has been set already.		// There is no need to re-do it here. 		// Total fragment required = number of fragment  if required		MpduRequired = RTMP_GET_PACKET_FRAGMENTS(pPacket);		TxRate = RTMP_GET_PACKET_TXRATE(pPacket);    		if (FreeNumber[QueIdx] <= 5)    		{    			// free Tx(QueIdx) resources    			RTMPFreeTXDUponTxDmaDone(pAd, QueIdx);    			FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);    		}		// rough estimate we will use 3 more descriptor.     		if (FreeNumber[QueIdx] >= (ULONG)(MpduRequired+3))		{			pEntry = RemoveHeadQueue(pQueue);			// Enhance SW Aggregation Mechanism//			if (pAd->CommonCfg.BACapability.field.AmsduEnable && ((FreeNumber[QueIdx] != (TX_RING_SIZE-1) && pAd->TxSwQueue[QueIdx].Number == 0) || (FreeNumber[QueIdx]<3)))			if (((FreeNumber[QueIdx] != (TX_RING_SIZE-1)) && (pAd->TxSwQueue[QueIdx].Number == 0)) 			     || (FreeNumber[QueIdx]<3))			{				if ((pAd->CommonCfg.BACapability.field.AmsduEnable)					 || (pAd->CommonCfg.bAggregationCapable && (TxRate >= RATE_6) && (TxRate <= RATE_54)))			{				InsertHeadQueue(pQueue, PACKET_TO_QUEUE_ENTRY(pPacket));				DBGPRINT(RT_DEBUG_LOUD, ("Hw Q(%d) Free = %lu, Sw Qlen = %lu\n", QueIdx, FreeNumber[QueIdx],										 pAd->TxSwQueue[QueIdx].Number));				if (bIntContext == FALSE)					RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);				break;				} 			}#ifdef CONFIG_STA_SUPPORT //			else			Status = RTMPHardTransmit(pAd, pPacket, QueIdx, &FreeNumber[QueIdx]);#endif // CONFIG_STA_SUPPORT // 			if (Status != NDIS_STATUS_SUCCESS)			{				DBGPRINT(RT_DEBUG_INFO,("RTMPHardTransmit return failed!!!\n"));				if (bIntContext == FALSE)					RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);				break;			}		}		else		{			pAd->PrivateInfo.TxRingFullCnt++;			DBGPRINT(RT_DEBUG_LOUD, ("Sw Q(%d) len = %lu\n", QueIdx, pAd->TxSwQueue[QueIdx].Number));			DBGPRINT(RT_DEBUG_INFO,("DeqPkt -> Not enough free TxD[%d] (TX_CTX_IDX=%lu, TxSwFreeIdx=%lu)!!!\n",									QueIdx, pAd->TxRing[QueIdx].TxCpuIdx, pAd->TxRing[QueIdx].TxSwFreeIdx));			if (bIntContext == FALSE)				RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);			break;		}		if (bIntContext == FALSE)			RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);		Count++;    	}#ifdef BLOCK_NET_IF		if ((pAd->blockQueueTab[QueIdx].SwTxQueueBlockFlag == TRUE)			&& (pAd->TxSwQueue[QueIdx].Number < 1))		{			releaseNetIf(&pAd->blockQueueTab[QueIdx]);		}#endif // BLOCK_NET_IF //	}}BOOLEAN  RTMPFreeTXDUponTxDmaDone(	IN PRTMP_ADAPTER	pAd, 	IN UCHAR			QueIdx){	PRTMP_TX_RING pTxRing;	PTXD_STRUC	  pTxD;#ifdef	BIG_ENDIAN    PTXD_STRUC      pDestTxD;#endif	PNDIS_PACKET  pPacket;	UCHAR	FREE = 0;	TXD_STRUC	TxD, *pOriTxD;	//ULONG		IrqFlags;	BOOLEAN			bReschedule = FALSE;	ASSERT(QueIdx < NUM_OF_TX_RING);	pTxRing = &pAd->TxRing[QueIdx];	RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF, &pTxRing->TxDmaIdx);	while (pTxRing->TxSwFreeIdx != pTxRing->TxDmaIdx)	{//		RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);#ifdef RALINK_ATE#ifdef RALINK_2860_QA		PHEADER_802_11	pHeader80211;		if ((pAd->ate.Mode != ATE_STOP) && (pAd->ate.bQATxStart == TRUE))		{			if (pAd->ate.QID == QueIdx)			{				pAd->ate.TxDoneCount++;				//pAd->ate.Repeat++;				pAd->RalinkCounters.KickTxCount++;				if (pAd->ate.QID == 0)					pAd->ate.TxAc0++;				else if (pAd->ate.QID == 1)					pAd->ate.TxAc1++;				else if (pAd->ate.QID == 2)					pAd->ate.TxAc2++;				else if (pAd->ate.QID == 3)					pAd->ate.TxAc3++;				else if (pAd->ate.QID == 4)					pAd->ate.TxHCCA++;				else if (pAd->ate.QID == 5)					pAd->ate.TxMgmt++;        					pTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);				pHeader80211 = pTxRing->Cell[pTxRing->TxSwFreeIdx].DmaBuf.AllocVa + sizeof(TXWI_STRUC);

⌨️ 快捷键说明

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