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

📄 ba_action.c

📁 Linux下的RT系列无线网卡驱动,可以直接在x86平台上编译
💻 C
📖 第 1 页 / 共 3 页
字号:
			if (BARecSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pAddreqFrame))				Status = 0;			else				Status = 38; // more parameters have invalid values		}		else		{			Status = 37; // the request has been declined.		}	}	if (pAd->MacTab.Content[Elem->Wcid].ValidAsCLI)	ASSERT(pAd->MacTab.Content[Elem->Wcid].Sst == SST_ASSOC);	pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]);	// 2. Always send back ADDBA Response 	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	 //Get an unused nonpaged memory	if (NStatus != NDIS_STATUS_SUCCESS)	{		DBGPRINT(RT_DEBUG_TRACE,("ACTION - PeerBAAction() allocate memory failed \n"));		return;	}	NdisZeroMemory(&ADDframe, sizeof(FRAME_ADDBA_RSP));	// 2-1. Prepare ADDBA Response frame.#ifdef CONFIG_STA_SUPPORT	ActHeaderInit(pAd, &ADDframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr);#endif // CONFIG_STA_SUPPORT //	ADDframe.Category = CATEGORY_BA;	ADDframe.Action = ADDBA_RESP;	ADDframe.Token = pAddreqFrame->Token;	// What is the Status code??  need to check.	ADDframe.StatusCode = Status;	ADDframe.BaParm.BAPolicy = IMMED_BA;	ADDframe.BaParm.AMSDUSupported = 0;	ADDframe.BaParm.TID = pAddreqFrame->BaParm.TID;	ADDframe.BaParm.BufSize = min(((UCHAR)pAddreqFrame->BaParm.BufSize), (UCHAR)pAd->CommonCfg.BACapability.field.RxBAWinLimit);	if (ADDframe.BaParm.BufSize == 0)	{		ADDframe.BaParm.BufSize = 64; 	}	ADDframe.TimeOutValue = 0; //pAddreqFrame->TimeOutValue;#ifdef BIG_ENDIAN	*(USHORT *)(&ADDframe.BaParm) = SWAP16(*(USHORT *)(&ADDframe.BaParm));	ADDframe.StatusCode = SWAP16(ADDframe.StatusCode);	ADDframe.TimeOutValue = SWAP16(ADDframe.TimeOutValue);#endif	MakeOutgoingFrame(pOutBuffer,               &FrameLen,					  sizeof(FRAME_ADDBA_RSP),  &ADDframe,					  END_OF_ARGS);	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);	MlmeFreeMemory(pAd, pOutBuffer);	DBGPRINT(RT_DEBUG_TRACE, ("%s(%d): TID(%d), BufSize(%d) <== \n", __FUNCTION__, Elem->Wcid, ADDframe.BaParm.TID, 							  ADDframe.BaParm.BufSize));}VOID PeerAddBARspAction(					   IN PRTMP_ADAPTER pAd, 					   IN MLME_QUEUE_ELEM *Elem) {	//UCHAR		Idx, i;	//PUCHAR		   pOutBuffer = NULL;	PFRAME_ADDBA_RSP    pFrame = NULL;	//PBA_ORI_ENTRY		pBAEntry;	//ADDBA Response from unknown peer, ignore this.	if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)		return;	DBGPRINT(RT_DEBUG_TRACE, ("%s ==> Wcid(%d)\n", __FUNCTION__, Elem->Wcid));	//hex_dump("AddBARsp, Elem->Msg, Elem->MsgLen);	if (PeerAddBARspActionSanity(pAd, Elem->Msg, Elem->MsgLen))	{		pFrame = (PFRAME_ADDBA_RSP)(&Elem->Msg[0]);		DBGPRINT(RT_DEBUG_TRACE, ("\t\t StatusCode = %d\n", pFrame->StatusCode));		switch (pFrame->StatusCode)		{			case 0:				// I want a BAsession with this peer as an originator. 				BAOriSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pFrame);				break;			default:				// check status == USED ??? 				BAOriSessionTearDown(pAd, Elem->Wcid, pFrame->BaParm.TID, TRUE, FALSE);				break;		}		// Rcv Decline StatusCode		if (pFrame->StatusCode == 37) 		{			pAd->MacTab.Content[Elem->Wcid].BADeclineBitmap |= 1<<pFrame->BaParm.TID;		}	}}VOID PeerDelBAAction(					IN PRTMP_ADAPTER pAd, 					IN MLME_QUEUE_ELEM *Elem) {	//UCHAR				Idx;	//PUCHAR				pOutBuffer = NULL;	PFRAME_DELBA_REQ    pDelFrame = NULL;	DBGPRINT(RT_DEBUG_TRACE,("%s ==>\n", __FUNCTION__));	//DELBA Request from unknown peer, ignore this.	if (PeerDelBAActionSanity(pAd, Elem->Wcid, Elem->Msg, Elem->MsgLen))	{		pDelFrame = (PFRAME_DELBA_REQ)(&Elem->Msg[0]);		if (pDelFrame->DelbaParm.Initiator == ORIGINATOR)		{			DBGPRINT(RT_DEBUG_TRACE,("BA - PeerDelBAAction----> ORIGINATOR\n"));			BARecSessionTearDown(pAd, Elem->Wcid, pDelFrame->DelbaParm.TID, TRUE);		}		else		{			DBGPRINT(RT_DEBUG_TRACE,("BA - PeerDelBAAction----> RECIPIENT, Reason = %d\n",  pDelFrame->ReasonCode));			//hex_dump("DelBA Frame", pDelFrame, Elem->MsgLen);			BAOriSessionTearDown(pAd, Elem->Wcid, pDelFrame->DelbaParm.TID, TRUE, FALSE);		}	}}BOOLEAN CntlEnqueueForRecv(						  IN PRTMP_ADAPTER		pAd, 						  IN ULONG				Wcid, 						  IN ULONG				MsgLen, 						  IN PFRAME_BA_REQ		pMsg) {	PFRAME_BA_REQ   pFrame = pMsg;	//PRTMP_REORDERBUF	pBuffer;	//PRTMP_REORDERBUF	pDmaBuf;	PBA_REC_ENTRY pBAEntry;	//BOOLEAN 	Result;	ULONG   Idx;	//UCHAR	NumRxPkt;	UCHAR	TID;//, i;	TID = (UCHAR)pFrame->BARControl.TID;	DBGPRINT(RT_DEBUG_ERROR, ("BAR(%ld) : Tid (%d)\n", Wcid, TID));	//hex_dump("BAR", (PCHAR) pFrame, MsgLen);	// Do nothing if the driver is starting halt state.	// This might happen when timer already been fired before cancel timer with mlmehalt	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))		return FALSE;	// First check the size, it MUST not exceed the mlme queue size	if (MsgLen > MGMT_DMA_BUFFER_SIZE)	{		DBGPRINT_ERR(("CntlEnqueueForRecv: frame too large, size = %ld \n", MsgLen));		return FALSE;	}	else if (MsgLen != sizeof(FRAME_BA_REQ))	{		DBGPRINT_ERR(("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen));		return FALSE;	}	else if (MsgLen != sizeof(FRAME_BA_REQ))	{		DBGPRINT_ERR(("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen));		return FALSE;	}	if ((Wcid < MAX_LEN_OF_MAC_TABLE) && (TID < 8))	{		// if this receiving packet is from SA that is in our OriEntry. Since WCID <9 has direct mapping. no need search.		Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];		pBAEntry = &pAd->BATable.BARecEntry[Idx];	}	else	{		return FALSE;	}	//printk("BAR Seq = %x, LastIndSeq = %x\n", pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq);	ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, pFrame->BAStartingSeq.field.StartSeq);	pBAEntry->LastIndSeq = (pFrame->BAStartingSeq.field.StartSeq == 0) ? MAXSEQ :(pFrame->BAStartingSeq.field.StartSeq -1);	//ba_refresh_reordering_mpdus(pAd, pBAEntry);	return TRUE;}/*Description : Send PSMP Action frame If PSMP mode switches.*/VOID SendPSMPAction(				   IN PRTMP_ADAPTER		pAd,				   IN UCHAR				Wcid,				   IN UCHAR				Psmp) {	PUCHAR          pOutBuffer = NULL;	NDIS_STATUS     NStatus;	//ULONG           Idx;	FRAME_PSMP_ACTION   Frame;	ULONG           FrameLen;	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	 //Get an unused nonpaged memory	if (NStatus != NDIS_STATUS_SUCCESS)	{		DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n"));		return;	}	#ifdef CONFIG_STA_SUPPORT	ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[Wcid].Addr);#endif // CONFIG_STA_SUPPORT //	Frame.Category = CATEGORY_HT;	Frame.Action = SMPS_ACTION;	switch (Psmp)	{		case MMPS_ENABLE:			Frame.Psmp = 0;			break;		case MMPS_DYNAMIC:			Frame.Psmp = 3;			break;		case MMPS_STATIC:			Frame.Psmp = 1;			break;	}	MakeOutgoingFrame(pOutBuffer,               &FrameLen,					  sizeof(FRAME_PSMP_ACTION),      &Frame,					  END_OF_ARGS);	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);	MlmeFreeMemory(pAd, pOutBuffer);	DBGPRINT(RT_DEBUG_ERROR,("HT - SendPSMPAction( %d )  \n", Frame.Psmp));}#define RADIO_MEASUREMENT_REQUEST_ACTION	0typedef struct PACKED{	UCHAR	RegulatoryClass;	UCHAR	ChannelNumber;	USHORT	RandomInterval;	USHORT	MeasurementDuration;	UCHAR	MeasurementMode;	UCHAR   BSSID[MAC_ADDR_LEN];	UCHAR	ReportingCondition;	UCHAR	Threshold;	UCHAR   SSIDIE[2];			// 2 byte} BEACON_REQUEST;typedef struct PACKED{	UCHAR	ID;	UCHAR	Length;	UCHAR	Token;	UCHAR	RequestMode;	UCHAR	Type;} MEASUREMENT_REQ;void convert_reordering_packet_to_preAMSDU_or_802_3_packet(	IN	PRTMP_ADAPTER	pAd, 	IN	RX_BLK			*pRxBlk,	IN  UCHAR			FromWhichBSSID){	PNDIS_PACKET	pRxPkt;	UCHAR			Header802_3[LENGTH_802_3];	// 1. get 802.3 Header	// 2. remove LLC 	// 		a. pointer pRxBlk->pData to payload 	//      b. modify pRxBlk->DataSize	RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);	ASSERT(pRxBlk->pRxPacket);	pRxPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);	RTPKT_TO_OSPKT(pRxPkt)->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); 	RTPKT_TO_OSPKT(pRxPkt)->data = pRxBlk->pData;	RTPKT_TO_OSPKT(pRxPkt)->len = pRxBlk->DataSize;	RTPKT_TO_OSPKT(pRxPkt)->tail = RTPKT_TO_OSPKT(pRxPkt)->data + RTPKT_TO_OSPKT(pRxPkt)->len;	//	// copy 802.3 header, if necessary	// 	if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))	{#ifdef CONFIG_STA_SUPPORT#ifdef LINUX		NdisMoveMemory(skb_push(pRxPkt, LENGTH_802_3), Header802_3, LENGTH_802_3);#endif#ifdef UCOS		NdisMoveMemory(net_pkt_push(pRxPkt, LENGTH_802_3), Header802_3, LENGTH_802_3);#endif #endif // CONFIG_STA_SUPPORT //	}}#define INDICATE_LEGACY_OR_AMSDU(_pAd, _pRxBlk, _fromWhichBSSID)		\	do																	\	{																	\    	if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_AMSDU))						\    	{																\    		Indicate_AMSDU_Packet(_pAd, _pRxBlk, _fromWhichBSSID);		\    	}																\    	else															\    	{																\    		Indicate_Legacy_Packet(_pAd, _pRxBlk, _fromWhichBSSID);		\    	}																\	} while (0);static VOID ba_enqueue_reordering_packet(	IN	PRTMP_ADAPTER	pAd,	IN	PBA_REC_ENTRY	pBAEntry,	IN	RX_BLK			*pRxBlk,	IN	UCHAR			FromWhichBSSID){	struct reordering_mpdu *mpdu_blk;	UINT16	Sequence = (UINT16) pRxBlk->pHeader->Sequence;	mpdu_blk = ba_mpdu_blk_alloc(pAd);	if (mpdu_blk != NULL)	{		// Write RxD buffer address & allocated buffer length		NdisAcquireSpinLock(&pBAEntry->RxReRingLock);		mpdu_blk->Sequence = Sequence;		mpdu_blk->bAMSDU = RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU);		convert_reordering_packet_to_preAMSDU_or_802_3_packet(pAd, pRxBlk, FromWhichBSSID);		STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);        //		// it is necessary for reordering packet to record 		// which BSS it come from		// 		RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);		mpdu_blk->pPacket = pRxBlk->pRxPacket;		if (ba_reordering_mpdu_insertsorted(&pBAEntry->list, mpdu_blk) == FALSE)		{			// had been already within reordering list			// don't indicate 			RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_SUCCESS);                     			ba_mpdu_blk_free(pAd, mpdu_blk);		}		ASSERT((0<= pBAEntry->list.qlen)  && (pBAEntry->list.qlen <= pBAEntry->BAWinSize));		NdisReleaseSpinLock(&pBAEntry->RxReRingLock);	}	else	{		DBGPRINT(RT_DEBUG_ERROR,  ("!!! (%d:%d) Can't allocate reordering mpdu blk\n",								   blk_count, pBAEntry->list.qlen));		/* 		 * flush all pending reordering mpdus 		 * and receving mpdu to upper layer		 * make tcp/ip to take care reordering mechanism		 */		//ba_refresh_reordering_mpdus(pAd, pBAEntry);		ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);		pBAEntry->LastIndSeq = Sequence;		INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);	}}/*	==========================================================================	Description:		Indicate this packet to upper layer or put it into reordering buffer			Parametrs:		pRxBlk         : carry necessary packet info 802.11 format		FromWhichBSSID : the packet received from which BSS	Return	: 			  none	Note    :	          the packet queued into reordering buffer need to cover to 802.3 format 			  or pre_AMSDU format	========================================================================== */VOID Indicate_AMPDU_Packet(	IN	PRTMP_ADAPTER	pAd,	IN	RX_BLK			*pRxBlk,	IN	UCHAR			FromWhichBSSID){	USHORT				Idx;	PBA_REC_ENTRY		pBAEntry = NULL;	UINT16				Sequence = pRxBlk->pHeader->Sequence;	ULONG				Now32;	UCHAR				Wcid = pRxBlk->pRxWI->WirelessCliID;	UCHAR				TID = pRxBlk->pRxWI->TID;	if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU) &&  (pRxBlk->DataSize > 1520))	{		static int err_size;		err_size++;		if (err_size > 20) {			 printk("AMPDU DataSize = %d\n", pRxBlk->DataSize);			 hex_dump("802.11 Header", (UCHAR *)pRxBlk->pHeader, 24);			 hex_dump("Payload", pRxBlk->pData, 64);			 err_size = 0;		}		// release packet		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);		return;	}	if (Wcid < MAX_LEN_OF_MAC_TABLE)	{		Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];		if (Idx == 0)		{			/* Rec BA Session had been torn down */			INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID); 			return;		}		pBAEntry = &pAd->BATable.BARecEntry[Idx];	}	else	{		// impossible !!!		ASSERT(0);		// release packet		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);		return;	}	ASSERT(pBAEntry);	// update last rx time	NdisGetSystemUpTime(&Now32);	pBAEntry->rcvSeq = Sequence;	ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);	pBAEntry->LastIndSeqAtTimer = Now32;	//	// Reset Last Indicate Sequence	// 	if (pBAEntry->LastIndSeq == RESET_RCV_SEQ)	{		ASSERT((pBAEntry->list.qlen == 0) && (pBAEntry->list.next == NULL));		// reset rcv sequence of BA session 		pBAEntry->LastIndSeq = Sequence;		pBAEntry->LastIndSeqAtTimer = Now32;		INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);		return;	}	//	// I. Check if in order.	// 	if (SEQ_STEPONE(Sequence, pBAEntry->LastIndSeq, MAXSEQ))	{		USHORT  LastIndSeq;		pBAEntry->LastIndSeq = Sequence;		INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID); 		LastIndSeq = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, pBAEntry->LastIndSeq);		if (LastIndSeq != RESET_RCV_SEQ)		{			pBAEntry->LastIndSeq = LastIndSeq;		}		pBAEntry->LastIndSeqAtTimer = Now32;	}	//	// II. Drop Duplicated Packet	// 	else if (Sequence == pBAEntry->LastIndSeq)	{		DBGPRINT(RT_DEBUG_INFO, ("Duplicated receive pHeader->Sequence = 0x%x ,LastIndSeq = 0x%x. drop \n" , Sequence, pBAEntry->LastIndSeq));		// drop and release packet		pBAEntry->nDropPacket++;		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);	}	//	// III. Drop Old Received Packet	// 	else if (SEQ_SMALLER(Sequence, pBAEntry->LastIndSeq, MAXSEQ))	{		DBGPRINT(RT_DEBUG_INFO, ("Rcv old pHeader->Sequence = 0x%x ,LastIndSeq = 0x%x. drop \n" , Sequence, pBAEntry->LastIndSeq));		// drop and release packet		pBAEntry->nDropPacket++;		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);	}	//	// IV. Receive Sequence within Window Size	// 	else if (SEQ_SMALLER(Sequence, (((pBAEntry->LastIndSeq+pBAEntry->BAWinSize+1)) & MAXSEQ), MAXSEQ))	{		ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk, FromWhichBSSID);	}	//	// V. Receive seq surpasses Win(lastseq + nMSDU). So refresh all reorder buffer	// 	else	{		LONG WinStartSeq, TmpSeq;		DBGPRINT(RT_DEBUG_INFO, ("%lu: Refresh. Sequence=0x%x, #RxPkt = %d.  LastIndSeq  = 0x%x.\n", Now32, Sequence, pBAEntry->list.qlen, pBAEntry->LastIndSeq));		TmpSeq = Sequence - (pBAEntry->BAWinSize) -1;		if (TmpSeq < 0)		{			TmpSeq = (MAXSEQ+1) + TmpSeq;		}		WinStartSeq = (TmpSeq+1) & MAXSEQ;		ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, WinStartSeq);		pBAEntry->LastIndSeq = WinStartSeq; //TmpSeq;          		pBAEntry->LastIndSeqAtTimer = Now32;		ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk, FromWhichBSSID);		TmpSeq = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, pBAEntry->LastIndSeq);		if (TmpSeq != RESET_RCV_SEQ)		{			pBAEntry->LastIndSeq = TmpSeq;		}	}}

⌨️ 快捷键说明

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