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

📄 rtusb_data.c

📁 r73模块的无线网卡在Linux下的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
		}		else if (CipherAlg == CIPHER_AES)		{			PUCHAR	pTmp;			pTmp = (PUCHAR) &Iv16;			*pTmp		= pKey->TxTsc[0];			*(pTmp + 1) = pKey->TxTsc[1];			*(pTmp + 2) = 0;			*(pTmp + 3) = (pAd->PortCfg.DefaultKeyId << 6) | 0x20;			Iv32 = *(PULONG)(&pKey->TxTsc[2]);			memcpy(&pTxD->Iv, &Iv16, 4);	// Copy IV			memcpy(&pTxD->Eiv, &Iv32, 4);	// Copy EIV			INC_TX_TSC(pKey->TxTsc);				// Increase TxTsc for next transmission		}		//		// STEP 5.3 COPY 802.11 HEADER INTO 1ST DMA BUFFER		//		pDest = pWirelessPacket;		memcpy(pDest, &Header_802_11, sizeof(Header_802_11));		pDest		+= sizeof(Header_802_11);		//		// Fragmentation is not allowed on multicast & broadcast		// So, we need to used the MAX_FRAG_THRESHOLD instead of pAd->PortCfg.FragmentThreshold		// otherwise if pSkb->len > pAd->PortCfg.FragmentThreshold then		// packet will be fragment on multicast & broadcast.		//		// MpduRequired equals to 1 means this could be Aggretaion case.		//		if ((Header_802_11.Addr1[0] & 0x01) || MpduRequired == 1)		{			FreeMpduSize = MAX_FRAG_THRESHOLD - sizeof(Header_802_11) - LENGTH_CRC;		}		else		{			FreeMpduSize = pAd->PortCfg.FragmentThreshold - sizeof(Header_802_11) - LENGTH_CRC;		}#if 0		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))		{			// copy QOS CONTROL bytes			*pDest		  =  (UserPriority & 0x0f) | pAd->PortCfg.AckPolicy[QueIdx];			*(pDest+1)	  =  0;			pDest		  += 2;			FreeMpduSize  -= 2;			if (pAd->PortCfg.AckPolicy[QueIdx] != NORMAL_ACK)			{				bAckRequired = FALSE;			}		}#endif		//		// 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)			{				if ((CipherAlg == CIPHER_TKIP_NO_MIC) && (pKey != NULL))				{					// Calculate MSDU MIC Value					RTMPCalculateMICValue(pAd, pSkb, pExtraLlcSnapEncap, pKey);				}				// Insert LLC-SNAP encapsulation				memcpy(pDest, pExtraLlcSnapEncap, 6);				pDest += 6;				memcpy(pDest, pSrcBufVA + 12, 2);				pDest += 2;				pSrcBufVA += LENGTH_802_3;				FreeMpduSize -= LENGTH_802_1_H;			}			else			{				if ((CipherAlg == CIPHER_TKIP_NO_MIC) && (pKey != NULL))				{					// Calculate MSDU MIC Value					RTMPCalculateMICValue(pAd, pSkb, pExtraLlcSnapEncap, pKey);				}				pSrcBufVA += LENGTH_802_3;			}		}		// Start copying payload		BytesCopied = 0;		do		{			if (SrcBufLen >= FreeMpduSize)			{				// Copy only the free fragment size, and save the pointer				// of current buffer descriptor for next fragment buffer.				memcpy(pDest, pSrcBufVA, FreeMpduSize);				BytesCopied += FreeMpduSize;				pSrcBufVA	+= FreeMpduSize;				pDest		+= FreeMpduSize;				SrcBufLen	-= FreeMpduSize;				break;			}			else			{				// Copy the rest of this buffer descriptor pointed data				// into ring buffer.				memcpy(pDest, pSrcBufVA, SrcBufLen);				BytesCopied  += SrcBufLen;				pDest		 += SrcBufLen;				FreeMpduSize -= SrcBufLen;			}			// No more buffer descriptor			// Add MIC value if needed			//if ((pAd->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) &&			//	(MICFrag == FALSE) &&			//	(pKey != NULL))			if((CipherAlg == CIPHER_TKIP_NO_MIC) &&			   (MICFrag == FALSE) &&				(pKey != NULL))			{				// Fregment and TKIP//				INT i;				SrcBufLen = 8;		// Set length to MIC length				DBGPRINT(RT_DEBUG_INFO, "Calculated TX MIC value =");				for (i = 0; i < 8; i++)				{					DBGPRINT_RAW(RT_DEBUG_INFO, "%02x:", pAd->PrivateInfo.Tx.MIC[i]);				}				DBGPRINT_RAW(RT_DEBUG_INFO, "\n");				if (FreeMpduSize >= SrcBufLen)				{					memcpy(pDest, pAd->PrivateInfo.Tx.MIC, SrcBufLen);					BytesCopied  += SrcBufLen;					pDest		 += SrcBufLen;					FreeMpduSize -= SrcBufLen;					SrcBufLen = 0;				}				else				{					memcpy(pDest, pAd->PrivateInfo.Tx.MIC, FreeMpduSize);					BytesCopied  += FreeMpduSize;					pSrcBufVA	  = pAd->PrivateInfo.Tx.MIC + FreeMpduSize;					pDest		 += FreeMpduSize;					SrcBufLen	 -= FreeMpduSize;					MICFrag 	  = TRUE;				}			}		}	while (FALSE); // End of copying payload		// Real packet size, No 802.1H header for fragments except the first one.		if ((StartOfFrame == TRUE) && (pExtraLlcSnapEncap != NULL))		{			TxSize = BytesCopied + LENGTH_802_11 + LENGTH_802_1_H + LengthQosPAD;		}		else		{			TxSize = BytesCopied + LENGTH_802_11 + LengthQosPAD;		}		SrcRemainingBytes -=  BytesCopied;		//		// STEP 5.6 MODIFY MORE_FRAGMENT BIT & DURATION FIELD. WRITE TXD		//		pHeader80211 = (PHEADER_802_11)pWirelessPacket;		if (SrcRemainingBytes > 0) // more fragment is required		{			 ULONG NextMpduSize;			 pHeader80211->FC.MoreFrag = 1;			 NextMpduSize = min((ULONG)SrcRemainingBytes, (ULONG)pAd->PortCfg.FragmentThreshold);			 if (NextMpduSize < pAd->PortCfg.FragmentThreshold)			 {				// In this case, we need to include LENGTH_802_11 and LENGTH_CRC for calculating Duration.				pHeader80211->Duration = (3 * pAd->PortCfg.Dsifs) +									(2 * AckDuration) +									RTMPCalcDuration(pAd, TxRate, NextMpduSize + EncryptionOverhead + LENGTH_802_11 + LENGTH_CRC);			 }			 else			 {				pHeader80211->Duration = (3 * pAd->PortCfg.Dsifs) +								(2 * AckDuration) +								RTMPCalcDuration(pAd, TxRate, NextMpduSize + EncryptionOverhead);			 }#ifdef BIG_ENDIAN			RTMPFrameEndianChange(pAd, (PUCHAR)pHeader80211, DIR_WRITE, FALSE);			RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);			*pDestTxD = TxD;			pTxD = pDestTxD;#endif			RTUSBWriteTxDescriptor(pAd, pTxD, CipherAlg, 0, KeyIdx, bAckRequired, TRUE, FALSE,					RetryMode, FrameGap, TxRate, TxSize, QueIdx, 0, bRTS_CTSFrame);			FrameGap = IFS_SIFS;	 // use SIFS for all subsequent fragments			Header_802_11.Frag ++;	 // increase Frag #		}		else		{			pHeader80211->FC.MoreFrag = 0;			if (pHeader80211->Addr1[0] & 0x01) // multicast/broadcast				pHeader80211->Duration = 0;			else				pHeader80211->Duration = pAd->PortCfg.Dsifs + AckDuration;			if ((bEAPOLFrame) && (TxRate > RATE_6))				TxRate = RATE_6;#ifdef BIG_ENDIAN			RTMPFrameEndianChange(pAd, (PUCHAR)pHeader80211, DIR_WRITE, FALSE);			RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);			*pDestTxD = TxD;			pTxD = pDestTxD;#endif			RTUSBWriteTxDescriptor(pAd, pTxD, CipherAlg, 0, KeyIdx, bAckRequired, FALSE, FALSE,					RetryMode, FrameGap, TxRate, TxSize, QueIdx, 0, bRTS_CTSFrame);			if (skb_queue_len(&pAd->SendTxWaitQueue[QueIdx]) > 1)				pTxD->Burst = 1;		}		TransferBufferLength = TxSize + sizeof(TXD_STRUC);		if ((TransferBufferLength % 4) == 1)			TransferBufferLength  += 3;		else if ((TransferBufferLength % 4) == 2)			TransferBufferLength  += 2;		else if ((TransferBufferLength % 4) == 3)			TransferBufferLength  += 1;		if ((TransferBufferLength % pAd->BulkOutMaxPacketSize) == 0)			TransferBufferLength += 4;		pTxContext->BulkOutSize = TransferBufferLength;		pTxContext->bWaitingBulkOut = TRUE;		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));		// Set frame gap for the rest of fragment burst.		// It won't matter if there is only one fragment (single fragment frame).		StartOfFrame = FALSE;		NumberRequired--;		if (NumberRequired == 0)		{			pTxContext->LastOne = TRUE;		}		else		{			pTxContext->LastOne = FALSE;		}		pAd->TxRingTotalNumber[QueIdx]++;	// sync. to PendingTx	}	while (NumberRequired > 0);	//	// Check if MIC error twice within 60 seconds and send EAPOL MIC error to TX queue	// then we enqueue a message for disasociating with the current AP	//	// Check for EAPOL frame sent after MIC countermeasures	if (pAd->PortCfg.MicErrCnt >= 3)	{		MLME_DISASSOC_REQ_STRUCT	DisassocReq;		// disassoc from current AP first		DBGPRINT(RT_DEBUG_INFO, "- (%s) disassociate with current AP after"				" sending second continuous EAPOL frame\n",				__FUNCTION__);		DisassocParmFill(pAd, &DisassocReq, pAd->PortCfg.Bssid, REASON_MIC_FAILURE);		MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,					sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;		pAd->PortCfg.bBlockAssoc = TRUE;	}	// release the skb buffer	RELEASE_NDIS_PACKET(pAd, pSkb);	return (NDIS_STATUS_SUCCESS);}/*	========================================================================	Routine	Description:		Copy frame from waiting queue into relative ring buffer and set	appropriate ASIC register to kick hardware transmit function	Arguments:		pAd			Pointer	to our adapter		pBuffer		Pointer to	memory of outgoing frame		Length		Size of outgoing management frame	Return Value:		NDIS_STATUS_FAILURE		NDIS_STATUS_PENDING		NDIS_STATUS_SUCCESS	Note:	========================================================================*/VOID	RTUSBMlmeHardTransmit(	IN	PRTMP_ADAPTER	pAd,	IN	PMGMT_STRUC		pMgmt){	PTX_CONTEXT		pMLMEContext;	PTXD_STRUC		pTxD;#ifdef BIG_ENDIAN	PTXD_STRUC		pDestTxD;	TXD_STRUC		TxD;#endif	PUCHAR			pDest;	PHEADER_802_11	pHeader_802_11;	BOOLEAN 		AckRequired, InsertTimestamp;	ULONG			TransferBufferLength;	PVOID			pBuffer = pMgmt->pBuffer;	ULONG			Length = pMgmt->Length;	UCHAR			QueIdx;	UCHAR			MlmeRate;	unsigned long flags;	// For 'Ndis' spin lock	DBGPRINT(RT_DEBUG_INFO, "--->MlmeHardTransmit\n");	pAd->PrioRingTxCnt++;	pMLMEContext = &pAd->MLMEContext[pAd->NextMLMEIndex];	pMLMEContext->InUse = TRUE;	// Increase & maintain Tx Ring Index	pAd->NextMLMEIndex++;	if (pAd->NextMLMEIndex >= PRIO_RING_SIZE)	{		pAd->NextMLMEIndex = 0;	}	pDest = pMLMEContext->TransferBuffer->WirelessPacket;#ifndef BIG_ENDIAN	pTxD = (PTXD_STRUC)(pMLMEContext->TransferBuffer);#else	pDestTxD  = (PTXD_STRUC)(pMLMEContext->TransferBuffer);	TxD = *pDestTxD;	pTxD = &TxD;	RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);#endif	memset(pTxD, 0, sizeof(TXD_STRUC));	pHeader_802_11 = (PHEADER_802_11) pBuffer;	// Verify Mlme rate for a / g bands.    if (pHeader_802_11->Addr1[0] & 0x01)	{		MlmeRate = pAd->PortCfg.BasicMlmeRate;	}	else	{		MlmeRate = pAd->PortCfg.MlmeRate;	}	if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band		MlmeRate = RATE_6;	DBGPRINT(RT_DEBUG_INFO, "- %s: Rate %d Channel %d\n",			__FUNCTION__, MlmeRate, pAd->LatchRfRegs.Channel );    // 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->PortCfg.bIEEE80211H == 1) && (pAd->PortCfg.RadarDetect.RDMode != RD_NORMAL_MODE))	{		DBGPRINT(RT_DEBUG_ERROR, "RTUSBMlmeHardTransmit --> radar detect not in normal mode !!!\n");		return;	}	if (pHeader_802_11->FC.PwrMgmt != PWR_SAVE)	{		pHeader_802_11->FC.PwrMgmt = (pAd->PortCfg.Psm == PWR_SAVE);	}	InsertTimestamp = FALSE;	if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL	{		AckRequired = FALSE;	}	else // BTYPE_MGMT or BMGMT_DATA(must be NULL frame)	{		pAd->Sequence		= ((pAd->Sequence) + 1) & (MAX_SEQ_NUMBER);		pHeader_802_11->Sequence = pAd->Sequence;		if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST		{			INC_COUNTER64(pAd->WlanCounters.MulticastTransmittedFrameCount);			AckRequired = FALSE;			pHeader_802_11->Duration = 0;		}		else		{			AckRequired = TRUE;			pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);			if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)			{				InsertTimestamp = TRUE;			}		}	}	memcpy(pDest, pBuffer, Length);	// Initialize Priority 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	QueIdx = QID_AC_BE;#ifdef BIG_ENDIAN	RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);	*pDestTxD = TxD;	pTxD = pDestTxD;#endif	RTUSBWriteTxDescriptor(pAd, pTxD, CIPHER_NONE, 0,0, AckRequired, FALSE, FALSE, SHORT_RETRY,			IFS_BACKOFF, MlmeRate, /*Length+4*/ Length, QueIdx, PID_MGMT_FRAME, FALSE);	// Build our URB for USBD	TransferBufferLength = sizeof(TXD_STRUC) + Length;	if ((TransferBufferLength % 2) == 1)

⌨️ 快捷键说明

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