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

📄 rtusb_data.c

📁 台湾RALink公司的 rt2570无线 802.11g 网卡的 驱动的源代码 ,支持linux2.4以上的 内河
💻 C
📖 第 1 页 / 共 5 页
字号:
}
/*
	========================================================================
	
	Routine Description:

	Arguments:

	Return Value:

	IRQL = 
	
	Note:
	
	========================================================================
*/
VOID	RTUSBRejectPendingPackets(
	IN	PRT2570ADAPTER	pAdapter)
{
	PQUEUE_HEADER	pQueue = &(pAdapter->SendTxWaitQueue);
	struct sk_buff  *skb;
	DBGPRINT_RAW(RT_DEBUG_TRACE, "--->RejectPendingPackets\n");

	NdisAcquireSpinLock(&pAdapter->SendTxWaitQueueLock);
	while (pAdapter->SendTxWaitQueue.Head != NULL)
	{
		DBGPRINT_RAW(RT_DEBUG_TRACE, " Remove 1 from SendTxWaitQueue\n");
		skb = (struct sk_buff *)RemoveHeadQueue(pQueue);
		RTUSBFreeSkbBuffer(skb);
	}
	NdisReleaseSpinLock(&pAdapter->SendTxWaitQueueLock);

	DBGPRINT_RAW(RT_DEBUG_TRACE, "<---RejectPendingPackets\n");
}

/*
	========================================================================

	Routine	Description:
		Suspend MSDU transmission
		
	Arguments:
		pAdapter		Pointer	to our adapter
		
	Return Value:
		None
		
	Note:
	
	========================================================================
*/
VOID    RTUSBSuspendMsduTransmission(
	IN	PRT2570ADAPTER	pAdapter)
{
	DBGPRINT(RT_DEBUG_TRACE,"SCANNING, suspend MSDU transmission ...\n");
	RTMP_SET_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
}

/*
	========================================================================

	Routine	Description:
		Resume MSDU transmission
		
	Arguments:
		pAdapter		Pointer	to our adapter
		
	Return Value:
		None
		
	Note:
	
	========================================================================
*/
VOID    RTUSBResumeMsduTransmission(
	IN	PRT2570ADAPTER	pAdapter)
{
	DBGPRINT(RT_DEBUG_TRACE,"SCANNING, resume MSDU transmission ...\n");
	RTMP_CLEAR_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
	if ((!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
		(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
		(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_REMOVE_IN_PROGRESS)) &&
		(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF)))
	{
		// Call dequeue without selected queue, let the subroutine select the right priority
		// Tx software queue
		RTUSBDeQueuePacket(pAdapter);
	}

	// Kick bulk out
	RTUSBKickBulkOut(pAdapter);

}
/*
	========================================================================

	Routine	Description:
		
	Arguments:
		
	Return Value:
		
	Note:
	
	========================================================================
*/
USHORT	RTUSBCalcDuration(
	IN	PRT2570ADAPTER	pAdapter,
	IN	UCHAR			Rate,
	IN	ULONG			Size)
{
	ULONG	Duration = 0;

	if (Rate < RATE_FIRST_OFDM_RATE) // CCK
	{
	    if ((Rate > RATE_1) && (pAdapter->PortCfg.TxPreambleInUsed == Rt802_11PreambleShort))
		Duration = 96;  // 72+24 preamble+plcp
		else
	    Duration = 192; // 144+48 preamble+plcp
		
		Duration += (USHORT)((Size << 4) / RateIdTo500Kbps[Rate]);
		if ((Size << 4) % RateIdTo500Kbps[Rate])
			Duration ++;
	}
	else // OFDM rates
	{
		Duration = 20 + 6;      // 16+4 preamble+plcp + Signal Extension
		Duration += 4 * (USHORT)((11 + Size * 4) / RateIdTo500Kbps[Rate]);
		if ((11 + Size * 4) % RateIdTo500Kbps[Rate])
			Duration += 4;
	}
	
	return (USHORT)Duration;	
}

/*
	========================================================================
	
	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
		
	Return Value:
		None
		
	========================================================================
*/
VOID	RTUSBWriteTxDescriptor(
	IN	PTXD_STRUC	pTxD,
	IN	BOOLEAN		Fragment,
	IN	UCHAR		RetryLimit,
	IN	BOOLEAN		Ack,
	IN  BOOLEAN     InsTimestamp,
	IN  BOOLEAN     new_seq,
	IN	UCHAR		Ifs,
	IN	UINT		Length,
	IN	BOOLEAN		Cipher,
	IN	UCHAR		KeyID,
	IN	UCHAR		CWMin,
	IN	UCHAR		CWMax,
	IN	UINT		PLCPLength,
	IN	UINT		Rate,
	IN	UCHAR		Service,
	IN  USHORT      TxPreamble)
{
	UINT	Residual;

	pTxD->RetryLimit  = RetryLimit;
	pTxD->MoreFrag    = Fragment;
	pTxD->ACK         = Ack;
	pTxD->Timestamp   = InsTimestamp;
	pTxD->newseq      = new_seq;
	pTxD->IFS         = Ifs;
	pTxD->DataByteCnt = Length;
	pTxD->Cipher	  = Cipher;
	pTxD->KeyID		  = KeyID;
	pTxD->CWmin       = CWMin;   // 2^5-1 = 31
	pTxD->CWmax       = CWMax;  // 2^10 -1 = 1023
	pTxD->Aifs        = 2;   // TC0: SIFS + 2*Slot + Random(CWmin,CWmax)*Slot
		
	if (Rate < RATE_FIRST_OFDM_RATE)
		pTxD->Ofdm = 0;
	else
		pTxD->Ofdm = 1;

	// fill up PLCP SIGNAL field
	pTxD->PlcpSignal = PlcpSignal[Rate];
	if (((Rate == RATE_2) || (Rate == RATE_5_5) || (Rate == RATE_11)) && (TxPreamble == Rt802_11PreambleShort)) // no short preamble for RATE_1
	{
		pTxD->PlcpSignal |= 0x0008;
	}

	// fill up PLCP SERVICE field, not used for OFDM rates
	pTxD->PlcpService = Service;

	// file up PLCP LENGTH_LOW and LENGTH_HIGH fields
	if (Rate < RATE_FIRST_OFDM_RATE)    // 11b - RATE_1, RATE_2, RATE_5_5, RATE_11
	{
		if ((Rate == RATE_1) || ( Rate == RATE_2))
		{
			PLCPLength = PLCPLength * 8 / (Rate + 1);
		}
		else
		{
			Residual = ((PLCPLength * 16) % (11 * (1 + Rate - RATE_5_5)));
			PLCPLength = PLCPLength * 16 / (11 * (1 + Rate - RATE_5_5));
			if (Residual != 0)
			{
				PLCPLength++;
			}
			if (Rate == RATE_11)
			{
			if ((Residual <= (3 * (1 + Rate - RATE_5_5))) && (Residual != 0))
			{
				pTxD->PlcpService |= 0x80; // 11b's PLCP Length extension bit
			}
			}
		}

		pTxD->PlcpLengthHigh = PLCPLength / 256;
		pTxD->PlcpLengthLow = PLCPLength % 256;
	}
	else    // OFDM - RATE_6, RATE_9, RATE_12, RATE_18, RATE_24, RATE_36, RATE_48, RATE_54
	{
		pTxD->PlcpLengthHigh = PLCPLength / 64;  // high 6-bit of total byte count
		pTxD->PlcpLengthLow = PLCPLength % 64;   // low 6-bit of total byte count
	}
}

/*
	========================================================================
	
	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
		
	Return Value:
		None
		
	========================================================================
*/
VOID	RTUSBWriteBeaconDescriptor(
	IN	PTXD_STRUC	pTxD,
	IN	UINT		Length,
	IN	UINT		PLCPLength,
	IN	UINT		Rate,
	IN	UCHAR		Service,
	IN  USHORT      TxPreamble)
{
	UINT	Residual;

	pTxD->RetryLimit	= 0;
	pTxD->MoreFrag    = 0;
	pTxD->ACK         = 0;
	pTxD->Timestamp   = 1;
	pTxD->newseq      = 1;
	pTxD->IFS         = IFS_NEW_BACKOFF;
	pTxD->DataByteCnt = Length;
	pTxD->Cipher	  = 0;
	pTxD->KeyID		  = 0;
	pTxD->CWmin       = BEACON_CW_IN_BITS;   // 2^5-1 = 31
	pTxD->CWmax       = BEACON_CW_IN_BITS;  // 2^10 -1 = 1023
	pTxD->Aifs        = 2;   // TC0: SIFS + 2*Slot + Random(CWmin,CWmax)*Slot
		
	if (Rate < RATE_FIRST_OFDM_RATE)
		pTxD->Ofdm = 0;
	else
		pTxD->Ofdm = 1;

	// fill up PLCP SIGNAL field
	pTxD->PlcpSignal = PlcpSignal[Rate];
	if (((Rate == RATE_2) || (Rate == RATE_5_5) || (Rate == RATE_11)) && (TxPreamble == Rt802_11PreambleShort)) // no short preamble for RATE_1
	{
		pTxD->PlcpSignal |= 0x0008;
	}

	// fill up PLCP SERVICE field, not used for OFDM rates
	pTxD->PlcpService = Service;

	// file up PLCP LENGTH_LOW and LENGTH_HIGH fields
	if (Rate < RATE_FIRST_OFDM_RATE)    // 11b - RATE_1, RATE_2, RATE_5_5, RATE_11
	{
		if ((Rate == RATE_1) || ( Rate == RATE_2))
		{
			PLCPLength = PLCPLength * 8 / (Rate + 1);
		}
		else
		{
			Residual = ((PLCPLength * 16) % (11 * (1 + Rate - RATE_5_5)));
			PLCPLength = PLCPLength * 16 / (11 * (1 + Rate - RATE_5_5));
			if (Residual != 0)
			{
				PLCPLength++;
			}
			if ((Residual <= (3 * (1 + Rate - RATE_5_5))) && (Residual != 0))
			{
				pTxD->PlcpService |= 0x80; // 11b's PLCP Length extension bit
			}
		}

		pTxD->PlcpLengthHigh = PLCPLength / 256;
		pTxD->PlcpLengthLow = PLCPLength % 256;
	}
	else    // OFDM - RATE_6, RATE_9, RATE_12, RATE_18, RATE_24, RATE_36, RATE_48, RATE_54
	{
		pTxD->PlcpLengthHigh = PLCPLength / 64;  // high 6-bit of total byte count
		pTxD->PlcpLengthLow = PLCPLength % 64;   // low 6-bit of total byte count
	}
}

/*
	========================================================================

	Routine	Description:
		Copy frame from waiting queue into relative ring buffer and set 
	appropriate ASIC register to kick hardware encryption before really
	sent out to air.
		
	Arguments:
		pAdapter		Pointer	to our adapter
		PNDIS_PACKET	Pointer to outgoing Ndis frame
		NumberOfFrag	Number of fragment required
		
	Return Value:
		None

	IRQL = DISPATCH_LEVEL
	
	Note:
	
	========================================================================
*/
NDIS_STATUS	RTUSBHardEncrypt(
	IN	PRT2570ADAPTER	pAdapter,
	IN  struct sk_buff  *skb,
	IN	UCHAR			NumberRequired,
	IN	ULONG			EnableTxBurst)
{
	PVOID			pVirtualAddress;
	UINT			NdisBufferLength;
	UINT			BytesCopied;
	UINT			TxSize, PLCPLength;
	UINT			FreeFragSize;
	UINT			RemainSize;
	USHORT			Protocol;
	UCHAR			FrameGap;
	HEADER_802_11	Header_802_11;
	PUCHAR			pDest;
	PUCHAR			pSrc;
	PUCHAR			pEncap = NULL;
	PTX_CONTEXT		pTxContext;
	PTXD_STRUC		pTxD;
	BOOLEAN			StartOfFrame;
	BOOLEAN			EAPOLFrame;
	BOOLEAN			Encapped;
	ULONG			Iv16;
	ULONG			Iv32;
	BOOLEAN			MICFrag;
	PWPA_KEY		pWpaKey = (PWPA_KEY) NULL;
	BOOLEAN			Cipher;
	UCHAR			KeyID = 0;
	ULONG			TransferBufferLength;
	BOOLEAN			MoreFragment;
    UCHAR           AckRate = RATE_2;
    USHORT          AckDuration = 0;
    USHORT          EncryptionOverhead = 0;
	BOOLEAN			Bcast_8023;
	BOOLEAN			SingleFrag;
//for re-calculating the number of Fragment required.
	UINT			AllowFragSize;
	UCHAR			NumberOfFrag;
	UINT			TotalPacketLength; 
	// To indicate cipher used for this packet
	NDIS_802_11_ENCRYPTION_STATUS	CipherSuite;
	
	CipherSuite = pAdapter->PortCfg.WepStatus;
	if (EnableTxBurst == 1)
		FrameGap = IFS_SIFS;
	else
		FrameGap = IFS_BACKOFF;		// Default frame gap mode
	// Sequence Number is identical for all fragments belonged to the same frame
	// Sequence is 0 - 4095
	pAdapter->Sequence = ((pAdapter->Sequence) + 1) & (MAX_SEQ_NUMBER);
	AckRate = pAdapter->PortCfg.ExpectedACKRate[pAdapter->PortCfg.TxRate];
	AckDuration = RTUSBCalcDuration(pAdapter, AckRate, 14);

	pVirtualAddress = skb->data;
	NdisBufferLength = skb->len;
	if(pVirtualAddress == NULL)
	{
		DBGPRINT(RT_DEBUG_ERROR, "Error, Null skb data buffer!!!\n");
		return (NDIS_STATUS_FAILURE);
	}
	if (NdisBufferLength < 14)
	{

⌨️ 快捷键说明

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