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

📄 rtusb_data.c

📁 无线网卡驱动。大家看看
💻 C
📖 第 1 页 / 共 5 页
字号:
		// 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);

	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				
			{
				// 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, pAd->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);

//#if 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
					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;
								for (idx=0; idx < 4; idx++)
								{
									DBGPRINT_RAW(RT_DEBUG_TRACE, "Set WEP key to Asic again =>\n");
						     
									if(pAd->PortCfg.DesireSharedKey[idx].KeyLen != 0)
									{
						                union 
						                {
		                                    char buf[sizeof(NDIS_802_11_WEP)+MAX_LEN_OF_KEY- 1];
		                                    NDIS_802_11_WEP keyinfo;
                                        }   WepKey;
                                        int len;

                                        
	                                    NdisZeroMemory(&WepKey, sizeof(WepKey));
                                        len =pAd->PortCfg.DesireSharedKey[idx].KeyLen;
                                        
			              			    NdisMoveMemory(WepKey.keyinfo.KeyMaterial, 
			              			                    pAd->PortCfg.DesireSharedKey[idx].Key, 
			              			                    pAd->PortCfg.DesireSharedKey[idx].KeyLen);
			              			                        
                                        WepKey.keyinfo.KeyIndex = 0x80000000 + idx; 
			                            WepKey.keyinfo.KeyLength = len;
			                            pAd->SharedKey[idx].KeyLen =(UCHAR) (len <= WEP_SMALL_KEY_LEN ? WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN);
			
		                                // need to enqueue cmd to thread
			                            RTUSBEnqueueCmdFromNdis(pAd, OID_802_11_ADD_WEP, TRUE, &WepKey, sizeof(WepKey.keyinfo) + len - 1);
									}
								}														
							}																																				
						}
						
						break;
					}
				    }
			else 
			{
//#else	
						// Special DATA frame that has to pass to MLME
						//	 1. EAPOL handshaking frames when driver supplicant enabled, pass to MLME for special process
						if (NdisEqualMemory(EAPOL_LLC_SNAP, pData, LENGTH_802_1_H) && (pAd->PortCfg.WpaState != SS_NOTUSE))
						{
							DataSize += LENGTH_802_11;
							REPORT_MGMT_FRAME_TO_MLME(pAd, pHeader, DataSize, pRxD->PlcpRssi, pRxD->PlcpSignal);
							DBGPRINT_RAW(RT_DEBUG_TRACE, "!!! report EAPOL/AIRONET DATA to MLME (len=%d) !!!\n", DataSize);
							break;	// end of processing this frame
						}
//#endif
                    }
						if (pHeader->Frag == 0) 	// First or Only fragment
						{
							PUCHAR pRemovedLLCSNAP;

							CONVERT_TO_802_3(Header802_3, pDA, pSA,

⌨️ 快捷键说明

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