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

📄 cmm_data_2870.c

📁 ralink最新rt3070 usb wifi 无线网卡驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * Taiwan, R.O.C. * * (c) Copyright 2002-2007, Ralink Technology, Inc. * * This program is free software; you can redistribute it and/or modify  *  * it under the terms of the GNU General Public License as published by  *  * the Free Software Foundation; either version 2 of the License, or     *  * (at your option) any later version.                                   *  *                                                                       *  * This program is distributed in the hope that it will be useful,       *  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *  * GNU General Public License for more details.                          *  *                                                                       *  * You should have received a copy of the GNU General Public License     *  * along with this program; if not, write to the                         *  * Free Software Foundation, Inc.,                                       *  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *  *                                                                       *  **************************************************************************/ /*   All functions in this file must be USB-depended, or you should out your function	in other files.*/#include	"rt_config.h"/*	We can do copy the frame into pTxContext when match following conditions.		=>		=>		=>*/static inline NDIS_STATUS RtmpUSBCanDoWrite(	IN RTMP_ADAPTER		*pAd,	IN UCHAR			QueIdx,	IN HT_TX_CONTEXT 	*pHTTXContext){	NDIS_STATUS	canWrite = NDIS_STATUS_RESOURCES;	if (((pHTTXContext->CurWritePosition) < pHTTXContext->NextBulkOutPosition) && (pHTTXContext->CurWritePosition + LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition)	{		DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c1!\n"));		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));	}	else if ((pHTTXContext->CurWritePosition == 8) && (pHTTXContext->NextBulkOutPosition < LOCAL_TXBUF_SIZE))	{		DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c2!\n"));		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));	}	else if (pHTTXContext->bCurWriting == TRUE)	{		DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c3!\n"));	}	else	{		canWrite = NDIS_STATUS_SUCCESS;	}		return canWrite;}USHORT RtmpUSB_WriteSubTxResource(	IN	PRTMP_ADAPTER	pAd,	IN	TX_BLK			*pTxBlk,	IN	BOOLEAN			bIsLast,	OUT	USHORT			*FreeNumber){	// Dummy function. Should be removed in the future.	return 0;	}USHORT	RtmpUSB_WriteFragTxResource(	IN	PRTMP_ADAPTER	pAd,	IN	TX_BLK			*pTxBlk,	IN	UCHAR			fragNum,	OUT	USHORT			*FreeNumber){	HT_TX_CONTEXT	*pHTTXContext;	USHORT			hwHdrLen;	// The hwHdrLen consist of 802.11 header length plus the header padding length.	UINT32			fillOffset;	TXINFO_STRUC	*pTxInfo;	TXWI_STRUC		*pTxWI;	PUCHAR			pWirelessPacket = NULL;	UCHAR			QueIdx;	NDIS_STATUS		Status;	unsigned long	IrqFlags;	UINT32			USBDMApktLen = 0, DMAHdrLen, padding;	BOOLEAN			TxQLastRound = FALSE;		//	// get Tx Ring Resource & Dma Buffer address	//	QueIdx = pTxBlk->QueIdx;	pHTTXContext  = &pAd->TxContext[QueIdx];	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);		pHTTXContext  = &pAd->TxContext[QueIdx];	fillOffset = pHTTXContext->CurWritePosition;	if(fragNum == 0)	{		// Check if we have enough space for this bulk-out batch.		Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);		if (Status == NDIS_STATUS_SUCCESS)		{			pHTTXContext->bCurWriting = TRUE;						// Reserve space for 8 bytes padding.			if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))			{				pHTTXContext->ENextBulkOutPosition += 8;				pHTTXContext->CurWritePosition += 8;				fillOffset += 8;			}			pTxBlk->Priv = 0;			pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;		}		else		{			RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);						RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);			return(Status);		}	}	else 	{		// For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer.		Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);		if (Status == NDIS_STATUS_SUCCESS)		{			fillOffset += pTxBlk->Priv;		}		else 		{			RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);						RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);			return(Status);		}	}		NdisZeroMemory((PUCHAR)(&pTxBlk->HeaderBuf[0]), TXINFO_SIZE);	pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);	pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);	pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];	// copy TXWI + WLAN Header + LLC into DMA Header Buffer	//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);	hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;	// Build our URB for USBD	DMAHdrLen = TXWI_SIZE + hwHdrLen;	USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;	padding = (4 - (USBDMApktLen % 4)) & 0x03;	// round up to 4 byte alignment	USBDMApktLen += padding;	pTxBlk->Priv += (TXINFO_SIZE + USBDMApktLen);	// For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload	RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/,  FALSE);		if (fragNum == pTxBlk->TotalFragNum) 	{		pTxInfo->USBDMATxburst = 0;		if ((pHTTXContext->CurWritePosition + pTxBlk->Priv + 3906)> MAX_TXBULK_LIMIT)		{			pTxInfo->SwUseLastRound = 1;			TxQLastRound = TRUE;		}	}	else	{		pTxInfo->USBDMATxburst = 1;	}	NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen); #ifdef RT_BIG_ENDIAN	RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket + TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);#endif // RT_BIG_ENDIAN //	pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);	pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);		RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);		NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);	//	Zero the last padding.	pWirelessPacket += pTxBlk->SrcBufLen;	NdisZeroMemory(pWirelessPacket, padding + 8);	if (fragNum == pTxBlk->TotalFragNum)	{		RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);				// Update the pHTTXContext->CurWritePosition. 3906 used to prevent the NextBulkOut is a A-RALINK/A-MSDU Frame.		pHTTXContext->CurWritePosition += pTxBlk->Priv;		if (TxQLastRound == TRUE)			pHTTXContext->CurWritePosition = 8;		pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;		// Finally, set bCurWriting as FALSE	pHTTXContext->bCurWriting = FALSE;		RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);		// succeed and release the skb buffer		RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);	}			return(Status);	}USHORT RtmpUSB_WriteSingleTxResource(	IN	PRTMP_ADAPTER	pAd,	IN	TX_BLK			*pTxBlk,	IN	BOOLEAN			bIsLast,	OUT	USHORT			*FreeNumber){	HT_TX_CONTEXT	*pHTTXContext;	USHORT			hwHdrLen;	UINT32			fillOffset;	TXINFO_STRUC	*pTxInfo;	TXWI_STRUC		*pTxWI;	PUCHAR			pWirelessPacket;	UCHAR			QueIdx;	unsigned long	IrqFlags;	NDIS_STATUS		Status;	UINT32			USBDMApktLen = 0, DMAHdrLen, padding;	BOOLEAN			bTxQLastRound = FALSE;			// For USB, didn't need PCI_MAP_SINGLE()	//SrcBufPA = PCI_MAP_SINGLE(pAd, (char *) pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, PCI_DMA_TODEVICE);	//	// get Tx Ring Resource & Dma Buffer address	//	QueIdx = pTxBlk->QueIdx;	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);	pHTTXContext  = &pAd->TxContext[QueIdx];	fillOffset = pHTTXContext->CurWritePosition;		// Check ring full.	Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);	if(Status == NDIS_STATUS_SUCCESS)	{		pHTTXContext->bCurWriting = TRUE;				pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);		pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);		// Reserve space for 8 bytes padding.		if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))		{			pHTTXContext->ENextBulkOutPosition += 8;			pHTTXContext->CurWritePosition += 8;			fillOffset += 8;		}		pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;				pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];						// copy TXWI + WLAN Header + LLC into DMA Header Buffer		//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);		hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;		// Build our URB for USBD		DMAHdrLen = TXWI_SIZE + hwHdrLen;		USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;		padding = (4 - (USBDMApktLen % 4)) & 0x03;	// round up to 4 byte alignment		USBDMApktLen += padding;		pTxBlk->Priv = (TXINFO_SIZE + USBDMApktLen);				// For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload		//PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)#ifdef CONFIG_STA_SUPPORT		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)		RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/,  FALSE);#endif // CONFIG_STA_SUPPORT //		if ((pHTTXContext->CurWritePosition + 3906 + pTxBlk->Priv) > MAX_TXBULK_LIMIT)		{			pTxInfo->SwUseLastRound = 1;			bTxQLastRound = TRUE;		}		NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen); #ifdef RT_BIG_ENDIAN		RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket + TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);#endif // RT_BIG_ENDIAN //		pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);		// We unlock it here to prevent the first 8 bytes maybe over-writed issue.		//	1. First we got CurWritePosition but the first 8 bytes still not write to the pTxcontext.		//	2. An interrupt break our routine and handle bulk-out complete.		//	3. In the bulk-out compllete, it need to do another bulk-out, 		//			if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition,		//			but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE.		//	4. Interrupt complete.		//  5. Our interrupted routine go back and fill the first 8 bytes to pTxContext.		//	6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition.		//		and the packet will wrong.		pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);		RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);				NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);		pWirelessPacket += pTxBlk->SrcBufLen;		NdisZeroMemory(pWirelessPacket, padding + 8);		RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);		pHTTXContext->CurWritePosition += pTxBlk->Priv;		if (bTxQLastRound)			pHTTXContext->CurWritePosition = 8;		pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;			pHTTXContext->bCurWriting = FALSE;	}		RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);		// succeed and release the skb buffer	RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);		return(Status);}USHORT RtmpUSB_WriteMultiTxResource(	IN	PRTMP_ADAPTER	pAd,	IN	TX_BLK			*pTxBlk,	IN	UCHAR			frameNum,	OUT	USHORT			*FreeNumber){	HT_TX_CONTEXT	*pHTTXContext;	USHORT			hwHdrLen;	// The hwHdrLen consist of 802.11 header length plus the header padding length.	UINT32			fillOffset;	TXINFO_STRUC	*pTxInfo;	TXWI_STRUC		*pTxWI;	PUCHAR			pWirelessPacket = NULL;	UCHAR			QueIdx;	NDIS_STATUS		Status;	unsigned long	IrqFlags;	//UINT32			USBDMApktLen = 0, DMAHdrLen, padding;	//	// get Tx Ring Resource & Dma Buffer address	//	QueIdx = pTxBlk->QueIdx;	pHTTXContext  = &pAd->TxContext[QueIdx];	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);		if(frameNum == 0)		{			// Check if we have enough space for this bulk-out batch.		Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);		if (Status == NDIS_STATUS_SUCCESS)		{			pHTTXContext->bCurWriting = TRUE;			pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);			pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);							// Reserve space for 8 bytes padding.			if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))			{								pHTTXContext->CurWritePosition += 8;				pHTTXContext->ENextBulkOutPosition += 8;			}			fillOffset = pHTTXContext->CurWritePosition;			pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;			pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];			//			// Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer			//			if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)				//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD;				hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;			else if (pTxBlk->TxFrameType == TX_RALINK_FRAME)				//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD;				hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen + LENGTH_ARALINK_HEADER_FIELD;			else				//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);				hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;			// Update the pTxBlk->Priv.			pTxBlk->Priv = TXINFO_SIZE + TXWI_SIZE + hwHdrLen;			//	pTxInfo->USBDMApktLen now just a temp value and will to correct latter.			RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(pTxBlk->Priv), FALSE, FIFO_EDCA, FALSE /*NextValid*/,  FALSE);						// Copy it.			NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->Priv); #ifdef RT_BIG_ENDIAN			RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket+ TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);#endif // RT_BIG_ENDIAN //			pHTTXContext->CurWriteRealPos += pTxBlk->Priv;			pWirelessPacket += pTxBlk->Priv;		}	}	else	{	// For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer.			Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);		if (Status == NDIS_STATUS_SUCCESS)		{			fillOffset =  (pHTTXContext->CurWritePosition + pTxBlk->Priv);			pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];			//hwHdrLen = pTxBlk->MpduHeaderLen;			NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->MpduHeaderLen);			pWirelessPacket += (pTxBlk->MpduHeaderLen);			pTxBlk->Priv += pTxBlk->MpduHeaderLen;		}		else		{	// It should not happened now unless we are going to shutdown.			DBGPRINT(RT_DEBUG_ERROR, ("WriteMultiTxResource():bCurWriting is FALSE when handle sub-sequent frames.\n"));			Status = NDIS_STATUS_FAILURE;		}	}	// We unlock it here to prevent the first 8 bytes maybe over-write issue.	//	1. First we got CurWritePosition but the first 8 bytes still not write to the pTxContext.	//	2. An interrupt break our routine and handle bulk-out complete.	//	3. In the bulk-out compllete, it need to do another bulk-out, 	//			if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition,	//			but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE.	//	4. Interrupt complete.	//  5. Our interrupted routine go back and fill the first 8 bytes to pTxContext.	//	6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition.	//		and the packet will wrong.	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);	if (Status != NDIS_STATUS_SUCCESS)	{		DBGPRINT(RT_DEBUG_ERROR,("WriteMultiTxResource: CWPos = %ld, NBOutPos = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition));		goto done;	}	// Copy the frame content into DMA buffer and update the pTxBlk->Priv	NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);	pWirelessPacket += pTxBlk->SrcBufLen;	pTxBlk->Priv += pTxBlk->SrcBufLen;done:		// Release the skb buffer here	RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);		return(Status);}VOID RtmpUSB_FinalWriteTxResource(	IN	PRTMP_ADAPTER	pAd,	IN	TX_BLK			*pTxBlk,	IN	USHORT			totalMPDUSize,	IN	USHORT			TxIdx){	UCHAR			QueIdx;

⌨️ 快捷键说明

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