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

📄 rtusb_data.c

📁 TP Link 321 Linux Driver
💻 C
📖 第 1 页 / 共 5 页
字号:
	{		pAd->DeQueueRunning[BulkOutPipeId] = TRUE;		NdisReleaseSpinLock(&pAd->DeQueueLock[BulkOutPipeId], IrqFlags);	}	QueIdx = BulkOutPipeId;		if (pAd->TxRingTotalNumber[BulkOutPipeId])		DBGPRINT(RT_DEBUG_INFO,"--RTMPDeQueuePacket %d TxRingTotalNumber= %d !!--\n", BulkOutPipeId, (INT)pAd->TxRingTotalNumber[BulkOutPipeId]);			// Make sure SendTxWait queue resource won't be used by other threads 	NdisAcquireSpinLock(&pAd->SendTxWaitQueueLock[BulkOutPipeId], IrqFlags);	// Select Queue	pQueue = &pAd->SendTxWaitQueue[BulkOutPipeId];			// Check queue before dequeue	while ((pQueue->Head != NULL) && (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_BSS_SCAN_IN_PROGRESS) ||			 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))		{			DBGPRINT(RT_DEBUG_ERROR,"--RTMPDeQueuePacket %d reset-in-progress !!--\n", BulkOutPipeId);			break;		}					// Dequeue the first entry from head of queue list		pSkb = (struct sk_buff*)RemoveHeadQueue(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			NdisReleaseSpinLock(&pAd->SendTxWaitQueueLock[BulkOutPipeId], IrqFlags);						Status = RTUSBHardTransmit(pAd, pSkb, FragmentRequired, QueIdx);			// Acquire the resource again, snice we may need to process it in this while-loop.			NdisAcquireSpinLock(&pAd->SendTxWaitQueueLock[BulkOutPipeId], IrqFlags);						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				InsertHeadQueue(pQueue, pSkb);				break;			}						Count++;		}		else		{			DBGPRINT(RT_DEBUG_INFO,"--RTMPDeQueuePacket %d queue full !! TxRingTotalNumber= %d !! FragmentRequired=%d !!\n", BulkOutPipeId, (INT)pAd->TxRingTotalNumber[BulkOutPipeId], FragmentRequired);			InsertHeadQueue(pQueue, pSkb);		    pAd->PrivateInfo.TxRingFullCnt++;			break;		}	}	// Release TxSwQueue0 resources	NdisReleaseSpinLock(&pAd->SendTxWaitQueueLock[BulkOutPipeId],  IrqFlags);#ifdef BLOCK_NET_IF	if ((pAd->blockQueueTab[QueIdx].SwTxQueueBlockFlag == TRUE)		&& (pAd->TxSwQueue[QueIdx].Number < 1))	{		releaseNetIf(&pAd->blockQueueTab[QueIdx]);	}#endif // BLOCK_NET_IF //	NdisAcquireSpinLock(&pAd->DeQueueLock[BulkOutPipeId],  IrqFlags);	pAd->DeQueueRunning[BulkOutPipeId] = FALSE;	NdisReleaseSpinLock(&pAd->DeQueueLock[BulkOutPipeId],  IrqFlags);	}/*	========================================================================	 Description:		This is the completion routine for the USB_RxPacket which submits		a URB to USBD for a transmission. 	========================================================================*/VOID	RTUSBRxPacket(	IN	 unsigned long data){	purbb_t 			pUrb = (purbb_t)data;	PRTMP_ADAPTER		pAd;	PRX_CONTEXT 		pRxContext;	PRXD_STRUC			pRxD;#ifdef BIG_ENDIAN	PRXD_STRUC			pDestRxD;	RXD_STRUC			RxD;#endif	PHEADER_802_11		pHeader;	PUCHAR				pData;	PUCHAR				pDA, pSA;	NDIS_STATUS			Status;	USHORT				DataSize, Msdu2Size;	UCHAR				Header802_3[14];	PCIPHER_KEY 		pWpaKey;//	  struct sk_buff	  *pSkb;	BOOLEAN				EAPOLFrame;	struct net_device			*net_dev;	DBGPRINT_RAW(RT_DEBUG_INFO, "--->RTUSBRxPacket\n");		pRxContext = (PRX_CONTEXT)pUrb->context;	pAd = pRxContext->pAd;	net_dev = pAd->net_dev;	if( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) )		return;	do	{		DBGPRINT_RAW(RT_DEBUG_INFO, "BulkIn actual length(%d)\n", pRxContext->pUrb->actual_length);		if (pRxContext->pUrb->actual_length >= sizeof(RXD_STRUC)+ LENGTH_802_11)		{		pData = pRxContext->TransferBuffer;#ifndef BIG_ENDIAN		pRxD = (PRXD_STRUC) pData;#else		pDestRxD = (PRXD_STRUC) pData;		RxD = *pDestRxD;		pRxD = &RxD;		RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD);#endif				// Cast to 802.11 header for flags checking		pHeader	= (PHEADER_802_11) (pData + sizeof(RXD_STRUC) );		#ifdef BIG_ENDIAN		RTMPFrameEndianChange(pAd, (PUCHAR)pHeader, DIR_READ, FALSE);#endif		if (pRxD->DataByteCnt < 4)			Status = NDIS_STATUS_FAILURE;		else		{			// Increase Total receive byte counter after real data received no mater any error or not			pAd->RalinkCounters.ReceivedByteCount += (pRxD->DataByteCnt - 4);			pAd->RalinkCounters.RxCount ++;					// Check for all RxD errors			Status = RTMPCheckRxDescriptor(pAd, pHeader, pRxD);				}		if (Status == NDIS_STATUS_SUCCESS)		{			// Apply packet filtering rule based on microsoft requirements.			Status = RTMPApplyPacketFilter(pAd, pRxD, pHeader);		}			// Add receive counters		if (Status == NDIS_STATUS_SUCCESS)		{			// Increase 802.11 counters & general receive counters			INC_COUNTER64(pAd->WlanCounters.ReceivedFragmentCount);		}		else		{			// Increase general counters			pAd->Counters.RxErrors++;		}		#ifdef RALINK_ATE		    if((!pRxD->U2M) && pAd->ate.Mode != ATE_STASTART)		    {	            CHAR RealRssi;	                    	            RealRssi = ConvertToRssi(pAd, (UCHAR)pRxD->PlcpRssi, RSSI_NO_1);	            pAd->PortCfg.LastRssi  = RealRssi + pAd->BbpRssiToDbmDelta;	            pAd->PortCfg.AvgRssiX8  = (pAd->PortCfg.AvgRssiX8 - pAd->PortCfg.AvgRssi) + pAd->PortCfg.LastRssi;	            pAd->PortCfg.AvgRssi = pAd->PortCfg.AvgRssiX8 >> 3;// for smart antenna//	            if ((pAd->RfIcType == RFIC_5325) || (pAd->RfIcType == RFIC_2529))//                {//                    pAd->PortCfg.LastRssi2  = ConvertToRssi(pAd, (UCHAR)pRxD->PlcpSignal, RSSI_NO_2) + pAd->BbpRssiToDbmDelta;//                }		    }#endif	// RALINK_ATE				// Check for retry bit, if this bit is on, search the cache with SA & sequence		// as index, if matched, discard this frame, otherwise, update cache		// This check only apply to unicast data & management frames		if ((pRxD->U2M) && (Status == NDIS_STATUS_SUCCESS) && (pHeader->FC.Type != BTYPE_CNTL))		{			if (pHeader->FC.Retry)			{				if (RTMPSearchTupleCache(pAd, pHeader) == TRUE)				{					// Found retry frame in tuple cache, Discard this frame / fragment					// Increase 802.11 counters					INC_COUNTER64(pAd->WlanCounters.FrameDuplicateCount);					DBGPRINT_RAW(RT_DEBUG_INFO, "duplicate frame %d\n", pHeader->Sequence);					Status = NDIS_STATUS_FAILURE;				}				else				{					RTMPUpdateTupleCache(pAd, pHeader);				}			}			else	// Update Tuple Cache			{				RTMPUpdateTupleCache(pAd, pHeader);			}		}				if ((pRxD->U2M)	|| ((pHeader->FC.SubType == SUBTYPE_BEACON) && (MAC_ADDR_EQUAL(&pAd->PortCfg.Bssid, &pHeader->Addr2))))		{			if ((pAd->Antenna.field.NumOfAntenna == 2) && (pAd->Antenna.field.TxDefaultAntenna == 0) && (pAd->Antenna.field.RxDefaultAntenna == 0))			{				COLLECT_RX_ANTENNA_AVERAGE_RSSI(pAd, ConvertToRssi(pAd, (UCHAR)pRxD->PlcpRssi, RSSI_NO_1), 0); //Note: RSSI2 not used on RT73				pAd->PortCfg.NumOfAvgRssiSample ++;			}		}		//		// Do RxD release operation	for	all	failure	frames		//		if (Status == NDIS_STATUS_SUCCESS)		{			do							{							if (VIRTUAL_IF_NUM(pAd)==0)					break;				// pData : Pointer skip	the RxD Descriptior and the first 24 bytes,	802.11 HEADER				pData += LENGTH_802_11 + sizeof(RXD_STRUC);				DataSize = (USHORT) pRxD->DataByteCnt - LENGTH_802_11;				//				// CASE I. receive a DATA frame				//								if (pHeader->FC.Type == BTYPE_DATA)				{					// before LINK UP, all DATA frames are rejected					if ( !OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) )					{						DBGPRINT(RT_DEBUG_INFO,"RxDone- drop DATA frame before LINK UP(len=%d)\n",pRxD->DataByteCnt);						break;					}					                    pAd->BulkInDataOneSecCount++;					// remove the 2 extra QOS CNTL bytes					if (pHeader->FC.SubType & 0x08)					{						pData += 2;						DataSize -= 2;					}					// remove the 2 extra AGGREGATION bytes					Msdu2Size = 0;					if (pHeader->FC.Order)					{						Msdu2Size = *pData + (*(pData+1) << 8);						if ((Msdu2Size <= 1536) && (Msdu2Size < DataSize))						{							pData += 2;							DataSize -= 2;						}						else							Msdu2Size = 0;					}					// Drop not my BSS frame					//					// Not drop EAPOL frame, since this have happen on the first time that we link up					// And need some more time to set BSSID to asic					// So pRxD->MyBss may be 0					//							        if (RTMPEqualMemory(EAPOL, pData + 6, 2))						EAPOLFrame = TRUE;					else						EAPOLFrame = FALSE;					if ((pRxD->MyBss == 0) && (EAPOLFrame != TRUE))						break; // give up this frame					// Drop NULL (+CF-POLL) (+CF-ACK) data frame					if ((pHeader->FC.SubType & 0x04) == 0x04)					{						DBGPRINT(RT_DEBUG_TRACE,"RxDone- drop NULL frame(subtype=%d)\n",pHeader->FC.SubType);						break;					}					// prepare 802.3 header: DA=addr1; SA=addr3 in INFRA mode, DA=addr2 in ADHOC mode					pDA = pHeader->Addr1; 					if (INFRA_ON(pAd))						pSA	= pHeader->Addr3;					else						pSA	= pHeader->Addr2;					if (pHeader->FC.Wep) // frame received in encrypted format					{						if (pRxD->CipherAlg == CIPHER_NONE) // unsupported cipher suite						{							break; // give up this frame						}						else if (pAd->SharedKey[pRxD->KeyIndex].KeyLen == 0)						{							break; // give up this frame since the keylen is invalid.						}									}					else					{	// frame received in clear text						// encryption in-use but receive a non-EAPOL clear text frame, drop it							if (((pAd->PortCfg.WepStatus == Ndis802_11Encryption1Enabled) ||								(pAd->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) ||								(pAd->PortCfg.WepStatus == Ndis802_11Encryption3Enabled)) &&								(pAd->PortCfg.PrivacyFilter == Ndis802_11PrivFilter8021xWEP) &&								(!NdisEqualMemory(EAPOL_LLC_SNAP, pData, LENGTH_802_1_H)))							{								break; // give up this frame							}									}					// 					// Case I.1  Process Broadcast & Multicast data frame					//					if (pRxD->Bcast || pRxD->Mcast)					{						PUCHAR pRemovedLLCSNAP;						INC_COUNTER64(pAd->WlanCounters.MulticastReceivedFrameCount);						// Drop Mcast/Bcast frame with fragment bit on						if (pHeader->FC.MoreFrag)						{							break; // give up this frame						}						// Filter out Bcast frame which AP relayed for us						if (pHeader->FC.FrDs && MAC_ADDR_EQUAL(pHeader->Addr3, pAd->CurrentAddress))						{							break; // give up this frame						}						// build 802.3 header and decide if remove the 8-byte LLC/SNAP encapsulation						CONVERT_TO_802_3(Header802_3, pDA, pSA, pData, DataSize, pRemovedLLCSNAP);						REPORT_ETHERNET_FRAME_TO_LLC(pAd,Header802_3, pData, DataSize, net_dev);						DBGPRINT(RT_DEBUG_TRACE, "!!! report BCAST DATA to LLC (len=%d) !!!\n", DataSize);					}					//					// Case I.2  Process unicast-to-me DATA frame					//					else if	(pRxD->U2M)					{						RECORD_LATEST_RX_DATA_RATE(pAd, pRxD);//#ifdef RALINK_WPA_SUPPLICANT_SUPPORT                    if (pAd->PortCfg.WPA_Supplicant == TRUE) 					{						// All EAPoL frames have to pass to upper layer (ex. WPA_SUPPLICANT daemon)						// TBD : process fragmented EAPol frames						//2007/12/21:Carella add to fix fragmentation bugs in 802.1x(start)						if (pHeader->Frag == 0)						{		// First or Only fragment								if (pHeader->FC.MoreFrag == FALSE)								{		// One & The only fragment									if(NdisEqualMemory(EAPOL_LLC_SNAP, pData, LENGTH_802_1_H))									{										PUCHAR pRemovedLLCSNAP;										int		success = 0;																// In 802.1x mode, if the received frame is EAP-SUCCESS packet, turn on the PortSecured variable										if ( pAd->PortCfg.IEEE8021X == TRUE 										    && (EAP_CODE_SUCCESS == RTMPCheckWPAframeForEapCode(pAd, pData, DataSize, LENGTH_802_1_H)))										{											DBGPRINT_RAW(RT_DEBUG_TRACE, "Receive EAP-SUCCESS Packet\n");											pAd->PortCfg.PortSecured = WPA_802_1X_PORT_SECURED;														success = 1;										}																			// build 802.3 header and decide if remove the 8-byte LLC/SNAP encapsulation										CONVERT_TO_802_3(Header802_3, pDA, pSA, pData, DataSize, pRemovedLLCSNAP);	                    							REPORT_ETHERNET_FRAME_TO_LLC(pAd, Header802_3, pData, DataSize, net_dev);										DBGPRINT_RAW(RT_DEBUG_TRACE, "!!! report EAPoL DATA to LLC (len=%d) !!!\n", DataSize);																	if(success)										{											// For static wep mode, need to set wep key to Asic again											if(pAd->PortCfg.IEEE8021x_required_keys == 0)											{											 	int idx;												idx = pAd->PortCfg.DefaultKeyId;																					DBGPRINT_RAW(RT_DEBUG_TRACE, "Set WEP key to Asic again =>\n");												if(pAd->PortCfg.DesireSharedKey[idx].KeyLen != 0)												{													pAd->SharedKey[idx].KeyLen = pAd->PortCfg.DesireSharedKey[idx].KeyLen;													NdisMoveMemory(pAd->SharedKey[idx].Key, pAd->PortCfg.DesireSharedKey[idx].Key, pAd->SharedKey[idx].KeyLen);													pAd->SharedKey[idx].CipherAlg = pAd->PortCfg.DesireSharedKey[idx].CipherAlg;													AsicAddSharedKeyEntry(pAd, 0, (UCHAR)idx, pAd->SharedKey[idx].CipherAlg, pAd->SharedKey[idx].Key, NULL, NULL); 												}											}																								}																																														break;	//After reporting to LLC, must break									}								}//End of One & The only fragment								else								{		// First fragment - record the 802.3 header and frame body																	if (NdisEqualMemory(EAPOL_LLC_SNAP, pData, LENGTH_802_1_H))										{											NdisMoveMemory(&pAd->FragFrame.Buffer[LENGTH_802_3], pData, DataSize);											NdisMoveMemory(pAd->FragFrame.Header802_3, Header802_3, LENGTH_802_3);											pAd->FragFrame.RxSize	 = DataSize;											pAd->FragFrame.Sequence = pHeader->Sequence;											pAd->FragFrame.LastFrag = pHeader->Frag;		// Should be 0											break;										}								}						}//End of First or Only fragment						else						{											// Middle & End of fragment burst fragments												// No LLC-SNAP header in except the first fragment frame											// Here only handle the EAPOL middle or final fragment							if (RTMPEqualMemory(SNAP_802_1H, (PUCHAR)&pAd->FragFrame.Buffer[LENGTH_802_3], 6))							{								if ((pHeader->Sequence != pAd->FragFrame.Sequence) ||(pHeader->Frag != (pAd->FragFrame.LastFrag + 1)))								{		// Fragment is not the same sequence or out of fragment number order										// Clear Fragment frame contents													NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME));										break; // give up this frame

⌨️ 快捷键说明

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