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

📄 rtusb_data.c

📁 经过修改的在uClinux2.6上正常运行的ralink rt2571芯片组的设备驱动程序.
💻 C
📖 第 1 页 / 共 5 页
字号:
			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++;
		}
		
		// 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_TRACE,"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, pData, DataSize, pRemovedLLCSNAP);
							pAd->FragFrame.Flags &= 0xFFFFFFFE;

							// Firt Fragment & LLC/SNAP been removed. Keep the removed LLC/SNAP for later on
							// TKIP MIC verification.
							if (pHeader->FC.MoreFrag && pRemovedLLCSNAP)
							{
								NdisMoveMemory(pAd->FragFrame.Header_LLC, pRemovedLLCSNAP, LENGTH_802_1_H);
								pAd->FragFrame.Flags |= 0x01;								
							}

							// One & The only fragment
							if (pHeader->FC.MoreFrag == FALSE)
							{
								if ((pHeader->FC.Order == 1)  && (Msdu2Size > 0)) // this is an aggregation
								{
									USHORT Payload1Size, Payload2Size;
									PUCHAR pData2;

									pAd->RalinkCounters.OneSecRxAggregationCount ++;
									Payload1Size = DataSize - Msdu2Size;
									Payload2Size = Msdu2Size - LENGTH_802_3;

									REPORT_ETHERNET_FRAME_TO_LLC(pAd, Header802_3, pData, Payload1Size, pAd->net_dev);
									DBGPRINT(RT_DEBUG_TRACE, "!!! report segregated MSDU1 to LLC (len=%d, proto=%02x:%02x) %02x:%02x:%02x:%02x-%02x:%02x:%02x:%02x\n",
															LENGTH_802_3+Payload1Size, Header802_3[12], Header802_3[13],
															*pData, *(pData+1),*(pData+2),*(pData+3),*(pData+4),*(pData+5),*(pData+6),*(pData+7));									

									pData2 = pData + Payload1Size + LENGTH_802_3;
									REPORT_ETHERNET_FRAME_TO_LLC(pAd, pData + Payload1Size, pData2, Payload2Size, pAd->net_dev);
									DBGPRINT_RAW(RT_DEBUG_INFO, "!!! report segregated MSDU2 to LLC (len=%d, proto=%02x:%02x) %02x:%02x:%02x:%02x-%02x:%02x:%02x:%02x\n",
															LENGTH_802_3+Payload2Size, *(pData2 -2), *(pData2 - 1),
															*pData2, *(pData2+1),*(pData2+2),*(pData2+3),*(pData2+4),*(pData2+5),*(pData2+6),*(pData2+7));									
								}
								else
								{
									REPORT_ETHERNET_FRAME_TO_LLC(pAd, H

⌨️ 快捷键说明

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