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

📄 rtusb_data.c

📁 TP Link 321 Linux Driver
💻 C
📖 第 1 页 / 共 5 页
字号:
		TxD = *pDestTxD;		pTxD = &TxD;		RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);#endif					NdisZeroMemory(pTxD, sizeof(TXD_STRUC));		pWirelessPacket = pTxContext->TransferBuffer->u.WirelessPacket;		//		// STEP 5.2 PUT IVOFFSET, IV, EIV INTO TXD		//			pTxD->IvOffset	= LENGTH_802_11;#if 0		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))			pTxD->IvOffset += 2;  // add QOS CONTROL bytes#endif			if ((CipherAlg == CIPHER_WEP64) || (CipherAlg == CIPHER_WEP128))		{			PUCHAR pTmp;			pTmp = (PUCHAR) &pTxD->Iv;			*pTmp		= RandomByte(pAd);			*(pTmp + 1) = RandomByte(pAd);			*(pTmp + 2) = RandomByte(pAd);			*(pTmp + 3) = (KeyIdx << 6);		}		else if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC))		{			UCHAR	kidx;							kidx = KeyIdx;								RTMPInitTkipEngine(				pAd,				pKey->Key,				kidx,			//KeyIdx,		// This might cause problem when using peer key				Header_802_11.Addr2,				pKey->TxMic,				pKey->TxTsc,				&Iv16,				&Iv32);						NdisMoveMemory(&pTxD->Iv, &Iv16, 4);   // Copy IV			NdisMoveMemory(&pTxD->Eiv, &Iv32, 4);  // Copy EIV			INC_TX_TSC(pKey->TxTsc);			   // Increase TxTsc for next transmission		}		else if (CipherAlg == CIPHER_AES)		{			PUCHAR	pTmp;			UCHAR	kidx;							kidx = KeyIdx;			pTmp = (PUCHAR) &Iv16;			*pTmp		= pKey->TxTsc[0];			*(pTmp + 1) = pKey->TxTsc[1];			*(pTmp + 2) = 0;			*(pTmp + 3) = (/*pAd->PortCfg.DefaultKeyId*/kidx << 6) | 0x20;			Iv32 = *(PULONG)(&pKey->TxTsc[2]);						NdisMoveMemory(&pTxD->Iv, &Iv16, 4);	// Copy IV			NdisMoveMemory(&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;		NdisMoveMemory(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;		}		//		// 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				NdisMoveMemory(pDest, pExtraLlcSnapEncap, 6);				pDest += 6;				NdisMoveMemory(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.				NdisMoveMemory(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.				NdisMoveMemory(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_RAW(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)				{					NdisMoveMemory(pDest, pAd->PrivateInfo.Tx.MIC, SrcBufLen);					BytesCopied  += SrcBufLen;					pDest		 += SrcBufLen;					FreeMpduSize -= SrcBufLen;					SrcBufLen = 0;				}				else				{					NdisMoveMemory(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, KeyTable/*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, KeyTable/*0*/, KeyIdx, bAckRequired, FALSE, FALSE, 					RetryMode, FrameGap, TxRate, TxSize, QueIdx, 0, bRTS_CTSFrame);			if (pAd->SendTxWaitQueue[QueIdx].Number > 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 TxCount		atomic_inc(&pAd->TxCount);			}	while (NumberRequired > 0);	NdisReleaseSpinLock(&pAd->TxRingLock, IrqFlags);//BensonLiu modify	//		// 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              printk("<0>MLME - disassociate with current AP after sending second continuous EAPOL frame\n");		DBGPRINT(RT_DEBUG_TRACE, "MLME - disassociate with current AP after sending second continuous EAPOL frame\n");		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;		printk("<0>bBlockAssoc = %d\n", pAd->PortCfg.bBlockAssoc);	}	// release the skb buffer	RELEASE_NDIS_PACKET(pAd, pSkb);	DBGPRINT(RT_DEBUG_INFO, "<==== RTUSBHardTransmit\n");	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;		DBGPRINT_RAW(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->u.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	NdisZeroMemory(pTxD, 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_TRACE, "<---MlmeRate %d	Channel %d\n",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;

⌨️ 快捷键说明

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