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

📄 rtusb_data.c

📁 r73模块的无线网卡在Linux下的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
}/*	========================================================================	 Description:		This is the completion routine for the USB_RxPacket which submits		a URB to USBD for a transmission.	Note:		Called in process context.	========================================================================*/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;	wlan_ng_prism2_header	*ph;	int				i;	pRxContext = (PRX_CONTEXT)pUrb->context;	pAd = pRxContext->pAd;	net_dev = pAd->net_dev;	Status = pUrb->status;	DBGPRINT(RT_DEBUG_TRACE, "--> RTUSBRxPacket len=%d, status=%d\n",			pRxContext->pUrb->actual_length, Status);	if(Status || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) ) {		DBGPRINT(RT_DEBUG_TRACE, "<-- RTUSBRxPacket disconnected\n");		return;	}	do	{		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		DBGPRINT(RT_DEBUG_INFO, "-   %s: Frame type %d subtype %d\n",				__FUNCTION__, pHeader->FC.Type, pHeader->FC.SubType);		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);		}		/* Only recieve valid packets in to monitor mode */		if (pAd->PortCfg.BssType == BSS_MONITOR && Status == NDIS_STATUS_SUCCESS)         	{ 	        	struct sk_buff  *skb; 	       		if ((skb = __dev_alloc_skb(2048, GFP_DMA|GFP_KERNEL)) != NULL) 	        	{				if (pAd->bAcceptRFMONTx == TRUE) {					if (pAd->ForcePrismHeader != 1)						goto rfmontx_80211_receive;				} else {					if (pAd->ForcePrismHeader == 2)						goto rfmontx_80211_receive;				}					// setup the wlan-ng prismheader				if (skb_headroom(skb) < sizeof(wlan_ng_prism2_header))					pskb_expand_head(skb, sizeof(wlan_ng_prism2_header), 0, GFP_KERNEL);				ph = (wlan_ng_prism2_header *)					skb_push(skb, sizeof(wlan_ng_prism2_header));				memset(ph, 0, sizeof(wlan_ng_prism2_header));				ph->msgcode	= DIDmsg_lnxind_wlansniffrm;				ph->msglen	= sizeof(wlan_ng_prism2_header);				strcpy(ph->devname, pAd->net_dev->name);				ph->hosttime.did	= DIDmsg_lnxind_wlansniffrm_hosttime;				ph->mactime.did		= DIDmsg_lnxind_wlansniffrm_mactime;				ph->channel.did		= DIDmsg_lnxind_wlansniffrm_channel;				ph->rssi.did		= DIDmsg_lnxind_wlansniffrm_rssi;				ph->signal.did		= DIDmsg_lnxind_wlansniffrm_signal;				ph->noise.did		= DIDmsg_lnxind_wlansniffrm_noise;				ph->rate.did		= DIDmsg_lnxind_wlansniffrm_rate;				ph->istx.did		= DIDmsg_lnxind_wlansniffrm_istx;				ph->frmlen.did		= DIDmsg_lnxind_wlansniffrm_frmlen;				ph->hosttime.len	= 4;				ph->mactime.len		= 4;				ph->channel.len		= 4;				ph->rssi.len		= 4;				ph->signal.len		= 4;				ph->noise.len		= 4;				ph->rate.len		= 4;				ph->istx.len		= 4;				ph->frmlen.len		= 4;				ph->hosttime.data	= jiffies;				ph->channel.data	= pAd->PortCfg.Channel;				ph->signal.data		= pRxD->PlcpRssi;				ph->noise.data		= (pAd->BbpWriteLatch[17] > pAd->BbpTuning.R17UpperBoundG) ?									pAd->BbpTuning.R17UpperBoundG : ((ULONG) pAd->BbpWriteLatch[17]);				ph->rssi.data		= ph->signal.data - ph->noise.data;				ph->frmlen.data		= pRxD->DataByteCnt;				if (pRxD->Ofdm == 1)				{					for (i = 4; i < 12; i++)						if (pRxD->PlcpSignal == RateIdToPlcpSignal[i])							ph->rate.data = _11G_RATES[i] * 2;				}				else					ph->rate.data = pRxD->PlcpSignal / 5;					// end prismheader setup			rfmontx_80211_receive:      				skb->dev = pAd->net_dev;      				memcpy(skb_put(skb, pRxD->DataByteCnt), pHeader, pRxD->DataByteCnt);					skb_reset_mac_header(skb);      				skb->pkt_type = PACKET_OTHERHOST;     				skb->protocol = htons(ETH_P_802_2);        			skb->ip_summed = CHECKSUM_NONE;	               		netif_rx(skb);       			}         	continue;		}		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(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)				{					DBGPRINT(RT_DEBUG_INFO, "-  %s: data frame\n", __FUNCTION__);					// 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)) {						DBGPRINT(RT_DEBUG_INFO, "-  %s: !MyBss || !EAPOL\n",								__FUNCTION__);						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						{							DBGPRINT(RT_DEBUG_INFO, "-  %s: nonsup cipher\n", __FUNCTION__);							break; // give up this frame						}						else if (pAd->SharedKey[pRxD->KeyIndex].KeyLen == 0)						{							DBGPRINT(RT_DEBUG_INFO, "-  %s: keylen=0\n", __FUNCTION__);							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)))						{							DBGPRINT(RT_DEBUG_INFO, "-  %s: clear text\n", __FUNCTION__);							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)						{							DBGPRINT(RT_DEBUG_INFO, "-  %s: mcast w/more\n", __FUNCTION__);							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))						{							DBGPRINT(RT_DEBUG_INFO, "-  %s: relay mcast\n", __FUNCTION__);							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(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(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(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;	                                    memset(&WepKey, 0, sizeof(WepKey));                                        len =pAd->PortCfg.DesireSharedKey[idx].KeyLen;			              			    memcpy(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;					}				    } /* End (pAd->PortCfg.WPA_Supplicant == TRUE) */			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(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 pRemove

⌨️ 快捷键说明

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