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

📄 rtusb_data.c

📁 r73模块的无线网卡在Linux下的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
		TransferBufferLength++;	if ((TransferBufferLength % pAd->BulkOutMaxPacketSize) == 0)		TransferBufferLength += 2;	pMLMEContext->BulkOutSize = TransferBufferLength;	RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);	DBGPRINT(RT_DEBUG_INFO, "<---MlmeHardTransmit\n");}/*	========================================================================	Routine	Description:		This subroutine will scan through releative ring descriptor to find		out avaliable free ring descriptor and compare with request size.	Arguments:		pAd			Pointer	to our adapter		RingType	Selected Ring	Return Value:		NDIS_STATUS_FAILURE		Not enough free descriptor		NDIS_STATUS_SUCCESS		Enough free descriptor	Note:	========================================================================*/NDIS_STATUS	RTUSBFreeDescriptorRequest(	IN	PRTMP_ADAPTER	pAd,	IN	UCHAR			RingType,	IN	UCHAR			BulkOutPipeId,	IN	UCHAR			NumberRequired){	UCHAR			FreeNumber = 0;	UINT			Index;	NDIS_STATUS		Status = NDIS_STATUS_FAILURE;	switch (RingType)	{		case TX_RING:			Index = (pAd->NextTxIndex[BulkOutPipeId] + 1) % TX_RING_SIZE;			do			{				PTX_CONTEXT	pTxD  = &pAd->TxContext[BulkOutPipeId][Index];				// While Owner bit is NIC, obviously ASIC still need it.				// If valid bit is TRUE, indicate that TxDone has not process yet				// We should not use it until TxDone finish cleanup job				if (pTxD->InUse == FALSE)				{					// This one is free					FreeNumber++;				}				else				{					break;				}				Index = (Index + 1) % TX_RING_SIZE;			}	while (FreeNumber < NumberRequired);	// Quit here ! Free number is enough !			if (FreeNumber >= NumberRequired)			{				Status = NDIS_STATUS_SUCCESS;			}			break;		case PRIO_RING:			Index = pAd->NextMLMEIndex;			do			{				PTX_CONTEXT	pTxD  = &pAd->MLMEContext[Index];				// While Owner bit is NIC, obviously ASIC still need it.				// If valid bit is TRUE, indicate that TxDone has not process yet				// We should not use it until TxDone finish cleanup job				if (pTxD->InUse == FALSE)				{					// This one is free					FreeNumber++;				}				else				{					break;				}				Index = (Index + 1) % PRIO_RING_SIZE;			}	while (FreeNumber < NumberRequired);	// Quit here ! Free number is enough !			if (FreeNumber >= NumberRequired)			{				Status = NDIS_STATUS_SUCCESS;			}			break;		default:			DBGPRINT(RT_DEBUG_ERROR, "--->RTUSBFreeDescriptorRequest() -----!! \n");			break;	}	return (Status);}/*	========================================================================	Routine Description:	Arguments:	Return Value:	Note:	========================================================================*/VOID	RTUSBRejectPendingPackets(	IN	PRTMP_ADAPTER	pAd){	UCHAR			Index;	DBGPRINT(RT_DEBUG_TRACE, "--->RejectPendingPackets\n");	for (Index = 0; Index < 4; Index++)	{		skb_queue_purge(&pAd->SendTxWaitQueue[Index]);	}	DBGPRINT(RT_DEBUG_TRACE, "<---RejectPendingPackets\n");}/*	========================================================================	Routine	Description:		Calculates the duration which is required to transmit out frames	with given size and specified rate.	Arguments:		pTxD		Pointer to transmit descriptor		Ack			Setting for Ack requirement bit		Fragment	Setting for Fragment bit		RetryMode	Setting for retry mode		Ifs			Setting for IFS gap		Rate		Setting for transmit rate		Service		Setting for service		Length		Frame length		TxPreamble	Short or Long preamble when using CCK rates		QueIdx - 0-3, according to 802.11e/d4.4 June/2003	Return Value:		None	========================================================================*/VOID	RTUSBWriteTxDescriptor(	IN	PRTMP_ADAPTER pAd,	IN	PTXD_STRUC	pSourceTxD,	IN	UCHAR		CipherAlg,	IN	UCHAR		KeyTable,	IN	UCHAR		KeyIdx,	IN	BOOLEAN		Ack,	IN	BOOLEAN		Fragment,	IN	BOOLEAN 	InsTimestamp,	IN	UCHAR		RetryMode,	IN	UCHAR		Ifs,	IN	UINT		Rate,	IN	ULONG		Length,	IN	UCHAR		QueIdx,	IN	UCHAR		PID,	IN	BOOLEAN		bAfterRTSCTS){	UINT	Residual;	PTXD_STRUC		pTxD;#ifndef BIG_ENDIAN	pTxD = pSourceTxD;#else	TXD_STRUC		TxD;	TxD = *pSourceTxD;	pTxD = &TxD;	RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);#endif	pTxD->HostQId	  = QueIdx;	pTxD->MoreFrag	  = Fragment;	pTxD->ACK		  = Ack;	pTxD->Timestamp   = InsTimestamp;	pTxD->RetryMd	  = RetryMode;	pTxD->Ofdm		  = (Rate < RATE_FIRST_OFDM_RATE)? 0:1;	pTxD->IFS		  = Ifs;	pTxD->PktId 	  = PID;	pTxD->Drop		  = 1;	 // 1:valid, 0:drop	pTxD->HwSeq 	  = 1;	  // (QueIdx == QID_MGMT)? 1:0;	pTxD->BbpTxPower  = DEFAULT_BBP_TX_POWER; // TODO: to be modified	pTxD->DataByteCnt = Length;	RTMPCckBbpTuning(pAd, Rate);	// fill encryption related information, if required	pTxD->CipherAlg   = CipherAlg;	if (CipherAlg != CIPHER_NONE)	{		pTxD->KeyTable	  = KeyTable;		pTxD->KeyIndex	  = KeyIdx;		pTxD->TkipMic	  = 1;	}	// In TKIP+fragmentation. TKIP MIC is already appended by driver. MAC needs not generate MIC	if (CipherAlg == CIPHER_TKIP_NO_MIC)	{		pTxD->CipherAlg   = CIPHER_TKIP;		pTxD->TkipMic	  = 0;	 // tell MAC need not insert TKIP MIC	}	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))	{		if ((pAd->PortCfg.APEdcaParm.bValid) && (QueIdx <= QID_AC_VO))		{			pTxD->Cwmin = pAd->PortCfg.APEdcaParm.Cwmin[QueIdx];			pTxD->Cwmax = pAd->PortCfg.APEdcaParm.Cwmax[QueIdx];			pTxD->Aifsn = pAd->PortCfg.APEdcaParm.Aifsn[QueIdx];		}		else		{			DBGPRINT(RT_DEBUG_ERROR," WMM in used but EDCA not valid ERROR !!\n)");		}	}	else	{        if (bAfterRTSCTS)        {            // After RTS/CTS frame, data frame should use SIFS time.            // To patch this code, add the following code.            // Recommended by Jerry 2005/07/25 for WiFi testing with Proxim AP            pTxD->Cwmin = 0;            pTxD->Cwmax = 0;            pTxD->Aifsn = 1;            pTxD->IFS = IFS_BACKOFF;        }        else        {            pTxD->Cwmin = CW_MIN_IN_BITS;            pTxD->Cwmax = CW_MAX_IN_BITS;            pTxD->Aifsn = 2;	    }	}	// fill up PLCP SIGNAL field	pTxD->PlcpSignal = RateIdToPlcpSignal[Rate];	if (((Rate == RATE_2) || (Rate == RATE_5_5) || (Rate == RATE_11)) &&		(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED)))	{		pTxD->PlcpSignal |= 0x0008;	}	// fill up PLCP SERVICE field, not used for OFDM rates	pTxD->PlcpService = 4; // Service;	// file up PLCP LENGTH_LOW and LENGTH_HIGH fields	Length += LENGTH_CRC;	// CRC length	switch (CipherAlg)	{		case CIPHER_WEP64:		 Length += 8;	 break;  // IV + ICV		case CIPHER_WEP128: 	 Length += 8;	 break;  // IV + ICV		case CIPHER_TKIP:		 Length += 20;	 break;  // IV + EIV + MIC + ICV		case CIPHER_AES:		 Length += 16;	 break;  // IV + EIV + MIC		case CIPHER_CKIP64: 	 Length += 8;	 break;  // IV + CMIC + ICV, but CMIC already inserted by driver		case CIPHER_CKIP128:	 Length += 8;	 break;  // IV + CMIC + ICV, but CMIC already inserted by driver		case CIPHER_TKIP_NO_MIC: Length += 12;	 break;  // IV + EIV + ICV		default:								 break;	}	if (Rate < RATE_FIRST_OFDM_RATE)	// 11b - RATE_1, RATE_2, RATE_5_5, RATE_11	{		if ((Rate == RATE_1) || ( Rate == RATE_2))		{			Length = Length * 8 / (Rate + 1);		}		else		{			Residual = ((Length * 16) % (11 * (1 + Rate - RATE_5_5)));			Length = Length * 16 / (11 * (1 + Rate - RATE_5_5));			if (Residual != 0)			{				Length++;			}			if ((Residual <= (3 * (1 + Rate - RATE_5_5))) && (Residual != 0))			{				if (Rate == RATE_11)			// Only 11Mbps require length extension bit					pTxD->PlcpService |= 0x80; // 11b's PLCP Length extension bit			}		}		pTxD->PlcpLengthHigh = Length >> 8; // 256;		pTxD->PlcpLengthLow = Length % 256;	}	else	// OFDM - RATE_6, RATE_9, RATE_12, RATE_18, RATE_24, RATE_36, RATE_48, RATE_54	{		pTxD->PlcpLengthHigh = Length >> 6; // 64;	// high 6-bit of total byte count		pTxD->PlcpLengthLow = Length % 64;	 // low 6-bit of total byte count	}	pTxD->Burst  = Fragment;	pTxD->Burst2 = pTxD->Burst;#ifdef BIG_ENDIAN	RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);	WriteBackToDescriptor((PUCHAR)pSourceTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);#endif}/*	========================================================================	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	Note:		Called only from process context, protected by the usb semaphore.	========================================================================*/VOID	RTMPDeQueuePacket(	IN	PRTMP_ADAPTER	pAd,	IN	UCHAR			BulkOutPipeId){	struct sk_buff	*pSkb;	UCHAR			FragmentRequired;	NDIS_STATUS		Status;	UCHAR			Count = 0;	struct sk_buff_head	*pQueue;	UCHAR			QueIdx;	QueIdx = BulkOutPipeId;	if (pAd->TxRingTotalNumber[BulkOutPipeId])		DBGPRINT(RT_DEBUG_INFO,"--RTMPDeQueuePacket %d TxRingTotalNumber= %d !!--\n", BulkOutPipeId, (INT)pAd->TxRingTotalNumber[BulkOutPipeId]);	// Select Queue	pQueue = &pAd->SendTxWaitQueue[BulkOutPipeId];	// Check queue before dequeue	while (!skb_queue_empty(pQueue) && (Count < MAX_TX_PROCESS))	{		// Reset is in progress, stop immediately		if ( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||			 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))		{			DBGPRINT(RT_DEBUG_ERROR,"--RTMPDeQueuePacket %d reset-in-progress !!--\n", BulkOutPipeId);			RTUSBFreeSkbBuffer(skb_dequeue(pQueue));			continue;		}		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) {			DBGPRINT(RT_DEBUG_TRACE,				 "RTUSBDeQueuePacket scanning. Flags = 0x%x\n",				 pAd->Flags);			break;		}		// Dequeue the first entry from head of queue list		pSkb = skb_dequeue(pQueue);		// 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 + RST if required		FragmentRequired = RTMP_GET_PACKET_FRAGMENTS(pSkb) + RTMP_GET_PACKET_RTS(pSkb);		if ((RTUSBFreeDescriptorRequest(pAd, TX_RING, BulkOutPipeId, FragmentRequired) == NDIS_STATUS_SUCCESS))		{			// Avaliable ring descriptors are enough for this frame			// Call hard transmit			// Nitro mode / Normal mode selection			Status = RTUSBHardTransmit(pAd, pSkb, FragmentRequired, QueIdx);			if (Status == NDIS_STATUS_FAILURE)			{				// Packet failed due to various Ndis Packet error				RTUSBFreeSkbBuffer(pSkb);				break;			}			else if (Status == NDIS_STATUS_RESOURCES)			{				// Not enough free tx ring, it might happen due to free descriptor inquery might be not correct				// It also might change to NDIS_STATUS_FAILURE to simply drop the frame				// Put the frame back into head of queue				skb_queue_head(pQueue, pSkb);				break;			}else if(Status == NDIS_STATUS_RINGFULL){//Thomas add				pAd->TxRingTotalNumber[QueIdx]= 0;				RTUSBFreeSkbBuffer(pSkb);				break;			}			Count++;		}		else		{			DBGPRINT(RT_DEBUG_INFO,"--RTMPDeQueuePacket %d queue full !! TxRingTotalNumber= %d !! FragmentRequired=%d !!\n", BulkOutPipeId, (INT)pAd->TxRingTotalNumber[BulkOutPipeId], FragmentRequired);			skb_queue_head(pQueue, pSkb);		    pAd->PrivateInfo.TxRingFullCnt++;			break;		}	}}VOID	RTMPDeQueuePackets(IN	PRTMP_ADAPTER	pAd){	int	Index;	for (Index = 0; Index < 4; Index++)	{		if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) &&			!skb_queue_empty(&pAd->SendTxWaitQueue[Index]))		{			RTMPDeQueuePacket(pAd, Index);		}	}

⌨️ 快捷键说明

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