Example #1
0
//static
void ba_flush_reordering_timeout_mpdus(
									IN PRTMP_ADAPTER    pAd,
									IN PBA_REC_ENTRY    pBAEntry,
									IN ULONG            Now32)

{
	USHORT Sequence;

//	if ((RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+REORDERING_PACKET_TIMEOUT)) &&
//		 (pBAEntry->list.qlen > ((pBAEntry->BAWinSize*7)/8))) //||
//		(RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(10*REORDERING_PACKET_TIMEOUT))) &&
//		 (pBAEntry->list.qlen > (pBAEntry->BAWinSize/8)))
	if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(MAX_REORDERING_PACKET_TIMEOUT/6)))
		 &&(pBAEntry->list.qlen > 1)
		)
	{
		DBGPRINT(RT_DEBUG_TRACE,("timeout[%d] (%08lx-%08lx = %d > %d): %x, flush all!\n ", pBAEntry->list.qlen, Now32, (pBAEntry->LastIndSeqAtTimer),
			   (int)((long) Now32 - (long)(pBAEntry->LastIndSeqAtTimer)), MAX_REORDERING_PACKET_TIMEOUT,
			   pBAEntry->LastIndSeq));
		ba_refresh_reordering_mpdus(pAd, pBAEntry);
		pBAEntry->LastIndSeqAtTimer = Now32;
	}
	else
	if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT)))
		&& (pBAEntry->list.qlen > 0)
	   )
		{
    		//
		// force LastIndSeq to shift to LastIndSeq+1
    		//
    		Sequence = (pBAEntry->LastIndSeq+1) & MAXSEQ;
    		ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);
    		pBAEntry->LastIndSeqAtTimer = Now32;
			pBAEntry->LastIndSeq = Sequence;
    		//
    		// indicate in-order mpdus
    		//
    		Sequence = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, Sequence);
    		if (Sequence != RESET_RCV_SEQ)
    		{
    			pBAEntry->LastIndSeq = Sequence;
    		}

	}
#if 0
	else if (
			 (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(MAX_REORDERING_PACKET_TIMEOUT))) &&
			  (pBAEntry->list.qlen > 1))
			)
		{
		DBGPRINT(RT_DEBUG_TRACE,("timeout[%d] (%lx-%lx = %d > %d): %x\n ", pBAEntry->list.qlen, Now32, (pBAEntry->LastIndSeqAtTimer),
			   (int)((long) Now32 - (long)(pBAEntry->LastIndSeqAtTimer)), MAX_REORDERING_PACKET_TIMEOUT,
			   pBAEntry->LastIndSeq));
		ba_refresh_reordering_mpdus(pAd, pBAEntry);
			pBAEntry->LastIndSeqAtTimer = Now32;
				}
#endif
}
Example #2
0
/*
	==========================================================================
	Description:
		Retry sending ADDBA Reqest.
		
	IRQL = DISPATCH_LEVEL
	
	Parametrs:
	p8023Header: if this is already 802.3 format, p8023Header is NULL
	
	Return	: TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
				FALSE , then continue indicaterx at this moment.
	==========================================================================
 */
VOID BARecSessionIdleTimeout(
    IN PVOID SystemSpecific1, 
    IN PVOID FunctionContext, 
    IN PVOID SystemSpecific2, 
    IN PVOID SystemSpecific3) 
{
	
	BA_REC_ENTRY    *pBAEntry = (BA_REC_ENTRY *)FunctionContext;
	PRTMP_ADAPTER   pAd;
	ULONG           Now32;
	
	if (pBAEntry == NULL)
		return;

	if ((pBAEntry->REC_BA_Status == Recipient_Accept))
	{
		NdisGetSystemUpTime(&Now32);

		if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer + REC_BA_SESSION_IDLE_TIMEOUT)))
		{
			pAd = pBAEntry->pAdapter;
			// flush all pending reordering mpdus 
			ba_refresh_reordering_mpdus(pAd, pBAEntry); 
			DBGPRINT(RT_DEBUG_OFF, ("%ld: REC BA session Timeout\n", Now32));
		}
	}
}
Example #3
0
/*
	==========================================================================
	Description:
		Retry sending ADDBA Reqest.

	IRQL = DISPATCH_LEVEL

	Parametrs:
	p8023Header: if this is already 802.3 format, p8023Header is NULL

	Return	: TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
				FALSE , then continue indicaterx at this moment.
	==========================================================================
 */
void BARecSessionIdleTimeout(void *SystemSpecific1,
			     void *FunctionContext,
			     void *SystemSpecific2, void *SystemSpecific3)
{

	struct rt_ba_rec_entry *pBAEntry = (struct rt_ba_rec_entry *)FunctionContext;
	struct rt_rtmp_adapter *pAd;
	unsigned long Now32;

	if (pBAEntry == NULL)
		return;

	if ((pBAEntry->REC_BA_Status == Recipient_Accept)) {
		NdisGetSystemUpTime(&Now32);

		if (RTMP_TIME_AFTER
		    ((unsigned long)Now32,
		     (unsigned long)(pBAEntry->LastIndSeqAtTimer +
				     REC_BA_SESSION_IDLE_TIMEOUT))) {
			pAd = pBAEntry->pAdapter;
			/* flush all pending reordering mpdus */
			ba_refresh_reordering_mpdus(pAd, pBAEntry);
			DBGPRINT(RT_DEBUG_OFF,
				 ("%ld: REC BA session Timeout\n", Now32));
		}
	}
}
Example #4
0
/*static */
void ba_flush_reordering_timeout_mpdus(struct rt_rtmp_adapter *pAd,
				       struct rt_ba_rec_entry *pBAEntry,
				       unsigned long Now32)
{
	u16 Sequence;

/*      if ((RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+REORDERING_PACKET_TIMEOUT)) && */
/*               (pBAEntry->list.qlen > ((pBAEntry->BAWinSize*7)/8))) //|| */
/*              (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(10*REORDERING_PACKET_TIMEOUT))) && */
/*               (pBAEntry->list.qlen > (pBAEntry->BAWinSize/8))) */
	if (RTMP_TIME_AFTER
	    ((unsigned long)Now32,
	     (unsigned long)(pBAEntry->LastIndSeqAtTimer +
			     (MAX_REORDERING_PACKET_TIMEOUT / 6)))
	    && (pBAEntry->list.qlen > 1)
	    ) {
		DBGPRINT(RT_DEBUG_TRACE,
			 ("timeout[%d] (%08lx-%08lx = %d > %d): %x, flush all!\n ",
			  pBAEntry->list.qlen, Now32,
			  (pBAEntry->LastIndSeqAtTimer),
			  (int)((long)Now32 -
				(long)(pBAEntry->LastIndSeqAtTimer)),
			  MAX_REORDERING_PACKET_TIMEOUT, pBAEntry->LastIndSeq));
		ba_refresh_reordering_mpdus(pAd, pBAEntry);
		pBAEntry->LastIndSeqAtTimer = Now32;
	} else
	    if (RTMP_TIME_AFTER
		((unsigned long)Now32,
		 (unsigned long)(pBAEntry->LastIndSeqAtTimer +
				 (REORDERING_PACKET_TIMEOUT)))
		&& (pBAEntry->list.qlen > 0)
	    ) {
		/* */
		/* force LastIndSeq to shift to LastIndSeq+1 */
		/* */
		Sequence = (pBAEntry->LastIndSeq + 1) & MAXSEQ;
		ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);
		pBAEntry->LastIndSeqAtTimer = Now32;
		pBAEntry->LastIndSeq = Sequence;
		/* */
		/* indicate in-order mpdus */
		/* */
		Sequence =
		    ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry,
							  Sequence);
		if (Sequence != RESET_RCV_SEQ) {
			pBAEntry->LastIndSeq = Sequence;
		}

		DBGPRINT(RT_DEBUG_OFF,
			 ("%x, flush one!\n", pBAEntry->LastIndSeq));

	}
}
Example #5
0
VOID BARecSessionTearDown(
						 IN OUT  PRTMP_ADAPTER   pAd, 
						 IN      UCHAR           Wcid,
						 IN      UCHAR           TID,
						 IN      BOOLEAN         bPassive)
{
	ULONG           Idx = 0;
	BA_REC_ENTRY    *pBAEntry;

	if (Wcid >= MAX_LEN_OF_MAC_TABLE)
	{
		return;
	}

	//
	//  Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID).
	//
	Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
	if (Idx == 0)
		return;

	DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __FUNCTION__, Wcid, TID));
	

	pBAEntry = &pAd->BATable.BARecEntry[Idx];
	DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, REC_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->REC_BA_Status));
	//
	// Prepare DelBA action frame and send to the peer.
	//
	if ((TID == pBAEntry->TID) && (pBAEntry->REC_BA_Status == Recipient_Accept))
	{
		MLME_DELBA_REQ_STRUCT   DelbaReq;
		BOOLEAN 				Cancelled;
		//ULONG   offset; 
		//UINT32  VALUE;
				
		RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);         

		//
		// 1. Send DELBA Action Frame
		//
		if (bPassive == FALSE)
		{
			MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
			if (Elem != NULL)
			{
				NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
				NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
			
				COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
				DelbaReq.Wcid = Wcid;
				DelbaReq.TID = TID;
				DelbaReq.Initiator = RECIPIENT;
				Elem->MsgLen  = sizeof(DelbaReq);			
				NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
				MlmeDELBAAction(pAd, Elem);
				kfree(Elem);
			}
			else
			{
				DBGPRINT(RT_DEBUG_ERROR, ("%s():alloc memory failed!\n", __FUNCTION__));
				return;
			}
		}


		//
		// 2. Free resource of BA session
		//
		// flush all pending reordering mpdus 
		ba_refresh_reordering_mpdus(pAd, pBAEntry);

		NdisAcquireSpinLock(&pAd->BATabLock);

		// Erase Bitmap flag.
		pBAEntry->LastIndSeq = RESET_RCV_SEQ;
		pBAEntry->BAWinSize = 0;
		// Erase Bitmap flag at software mactable
		pAd->MacTab.Content[Wcid].RXBAbitmap &= (~(1<<(pBAEntry->TID)));
		pAd->MacTab.Content[Wcid].BARecWcidArray[TID] = 0;

		RTMP_DEL_BA_SESSION_FROM_ASIC(pAd, Wcid, TID);

		NdisReleaseSpinLock(&pAd->BATabLock);

	}

	BATableFreeRecEntry(pAd, Idx);
}
Example #6
0
BOOLEAN BARecSessionAdd(
					   IN PRTMP_ADAPTER    pAd, 
					   IN MAC_TABLE_ENTRY  *pEntry,
					   IN PFRAME_ADDBA_REQ pFrame)
{
	BA_REC_ENTRY            *pBAEntry = NULL;
	BOOLEAN                 Status = TRUE;
	BOOLEAN                 Cancelled;
	USHORT                  Idx;
	UCHAR                   TID;
	UCHAR                   BAWinSize;
	//UINT32                  Value;
	//UINT                    offset;


	ASSERT(pEntry);

	// find TID
	TID = pFrame->BaParm.TID;

	BAWinSize = min(((UCHAR)pFrame->BaParm.BufSize), (UCHAR)pAd->CommonCfg.BACapability.field.RxBAWinLimit);

	// Intel patch
	if (BAWinSize == 0)
	{
		BAWinSize = 64;
	}

	Idx = pEntry->BARecWcidArray[TID];


	if (Idx == 0)
	{
		pBAEntry = BATableAllocRecEntry(pAd, &Idx);     
	}
	else
	{
		pBAEntry = &pAd->BATable.BARecEntry[Idx];
		// flush all pending reordering mpdus
		ba_refresh_reordering_mpdus(pAd, pBAEntry);
	}

	DBGPRINT(RT_DEBUG_TRACE,("%s(%ld): Idx = %d, BAWinSize(req %d) = %d\n", __FUNCTION__, pAd->BATable.numAsRecipient, Idx, 
							 pFrame->BaParm.BufSize, BAWinSize));

	// Start fill in parameters.
	if (pBAEntry != NULL)
	{
		ASSERT(pBAEntry->list.qlen == 0);

		pBAEntry->REC_BA_Status = Recipient_HandleRes;
		pBAEntry->BAWinSize = BAWinSize;
		pBAEntry->Wcid = pEntry->Aid;
		pBAEntry->TID = TID;
		pBAEntry->TimeOutValue = pFrame->TimeOutValue;
		pBAEntry->REC_BA_Status = Recipient_Accept;
		// initial sequence number 
		pBAEntry->LastIndSeq = RESET_RCV_SEQ; //pFrame->BaStartSeq.field.StartSeq;

		DBGPRINT(RT_DEBUG_OFF, ("Start Seq = %08x\n",  pFrame->BaStartSeq.field.StartSeq));

		if (pEntry->RXBAbitmap & (1<<TID))
		{
			RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);
		}
		else
		{
			RTMPInitTimer(pAd, &pBAEntry->RECBATimer, GET_TIMER_FUNCTION(BARecSessionIdleTimeout), pBAEntry, TRUE);
		}


		// Set Bitmap flag.
		pEntry->RXBAbitmap |= (1<<TID);
		pEntry->BARecWcidArray[TID] = Idx;

		pEntry->BADeclineBitmap &= ~(1<<TID);

		// Set BA session mask in WCID table.
		RTMP_ADD_BA_SESSION_TO_ASIC(pAd, pEntry->Aid, TID);

		DBGPRINT(RT_DEBUG_TRACE,("MACEntry[%d]RXBAbitmap = 0x%x. BARecWcidArray=%d\n", 
				pEntry->Aid, pEntry->RXBAbitmap, pEntry->BARecWcidArray[TID]));
	}
	else
	{
		Status = FALSE;
		DBGPRINT(RT_DEBUG_TRACE,("Can't Accept ADDBA for %02x:%02x:%02x:%02x:%02x:%02x TID = %d\n", 
				PRINT_MAC(pEntry->Addr), TID));
	}
	return(Status);
}
Example #7
0
void BARecSessionTearDown(struct rt_rtmp_adapter *pAd,
			  u8 Wcid, u8 TID, IN BOOLEAN bPassive)
{
	unsigned long Idx = 0;
	struct rt_ba_rec_entry *pBAEntry;

	if (Wcid >= MAX_LEN_OF_MAC_TABLE) {
		return;
	}
	/* */
	/*  Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID). */
	/* */
	Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
	if (Idx == 0)
		return;

	DBGPRINT(RT_DEBUG_TRACE,
		 ("%s===>Wcid=%d.TID=%d \n", __func__, Wcid, TID));

	pBAEntry = &pAd->BATable.BARecEntry[Idx];
	DBGPRINT(RT_DEBUG_TRACE,
		 ("\t===>Idx = %ld, Wcid=%d.TID=%d, REC_BA_Status = %d \n", Idx,
		  Wcid, TID, pBAEntry->REC_BA_Status));
	/* */
	/* Prepare DelBA action frame and send to the peer. */
	/* */
	if ((TID == pBAEntry->TID)
	    && (pBAEntry->REC_BA_Status == Recipient_Accept)) {
		struct rt_mlme_delba_req DelbaReq;
		BOOLEAN Cancelled;
		/*unsigned long   offset; */
		/*u32  VALUE; */

		RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);

		/* */
		/* 1. Send DELBA Action Frame */
		/* */
		if (bPassive == FALSE) {
			struct rt_mlme_queue_elem *Elem =
				kmalloc(sizeof(struct rt_mlme_queue_elem),
					MEM_ALLOC_FLAG);
			if (Elem != NULL) {
				NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
				NdisZeroMemory(Elem, sizeof(struct rt_mlme_queue_elem));

				COPY_MAC_ADDR(DelbaReq.Addr,
					      pAd->MacTab.Content[Wcid].Addr);
				DelbaReq.Wcid = Wcid;
				DelbaReq.TID = TID;
				DelbaReq.Initiator = RECIPIENT;
				Elem->MsgLen = sizeof(DelbaReq);
				NdisMoveMemory(Elem->Msg, &DelbaReq,
					       sizeof(DelbaReq));
				MlmeDELBAAction(pAd, Elem);
				kfree(Elem);
			} else {
				DBGPRINT(RT_DEBUG_ERROR,
					 ("%s():alloc memory failed!\n",
					  __func__));
				return;
			}
		}

		/* */
		/* 2. Free resource of BA session */
		/* */
		/* flush all pending reordering mpdus */
		ba_refresh_reordering_mpdus(pAd, pBAEntry);

		NdisAcquireSpinLock(&pAd->BATabLock);

		/* Erase Bitmap flag. */
		pBAEntry->LastIndSeq = RESET_RCV_SEQ;
		pBAEntry->BAWinSize = 0;
		/* Erase Bitmap flag at software mactable */
		pAd->MacTab.Content[Wcid].RXBAbitmap &=
		    (~(1 << (pBAEntry->TID)));
		pAd->MacTab.Content[Wcid].BARecWcidArray[TID] = 0;

		RTMP_DEL_BA_SESSION_FROM_ASIC(pAd, Wcid, TID);

		NdisReleaseSpinLock(&pAd->BATabLock);

	}

	BATableFreeRecEntry(pAd, Idx);
}
Example #8
0
BOOLEAN BARecSessionAdd(struct rt_rtmp_adapter *pAd,
			struct rt_mac_table_entry *pEntry, struct rt_frame_addba_req * pFrame)
{
	struct rt_ba_rec_entry *pBAEntry = NULL;
	BOOLEAN Status = TRUE;
	BOOLEAN Cancelled;
	u16 Idx;
	u8 TID;
	u8 BAWinSize;
	/*u32                  Value; */
	/*u32                    offset; */

	ASSERT(pEntry);

	/* find TID */
	TID = pFrame->BaParm.TID;

	BAWinSize =
	    min(((u8)pFrame->BaParm.BufSize),
		(u8)pAd->CommonCfg.BACapability.field.RxBAWinLimit);

	/* Intel patch */
	if (BAWinSize == 0) {
		BAWinSize = 64;
	}

	Idx = pEntry->BARecWcidArray[TID];

	if (Idx == 0) {
		pBAEntry = BATableAllocRecEntry(pAd, &Idx);
	} else {
		pBAEntry = &pAd->BATable.BARecEntry[Idx];
		/* flush all pending reordering mpdus */
		ba_refresh_reordering_mpdus(pAd, pBAEntry);
	}

	DBGPRINT(RT_DEBUG_TRACE,
		 ("%s(%ld): Idx = %d, BAWinSize(req %d) = %d\n", __func__,
		  pAd->BATable.numAsRecipient, Idx, pFrame->BaParm.BufSize,
		  BAWinSize));

	/* Start fill in parameters. */
	if (pBAEntry != NULL) {
		ASSERT(pBAEntry->list.qlen == 0);

		pBAEntry->REC_BA_Status = Recipient_HandleRes;
		pBAEntry->BAWinSize = BAWinSize;
		pBAEntry->Wcid = pEntry->Aid;
		pBAEntry->TID = TID;
		pBAEntry->TimeOutValue = pFrame->TimeOutValue;
		pBAEntry->REC_BA_Status = Recipient_Accept;
		/* initial sequence number */
		pBAEntry->LastIndSeq = RESET_RCV_SEQ;	/*pFrame->BaStartSeq.field.StartSeq; */

		DBGPRINT(RT_DEBUG_OFF,
			 ("Start Seq = %08x\n",
			  pFrame->BaStartSeq.field.StartSeq));

		if (pEntry->RXBAbitmap & (1 << TID)) {
			RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);
		} else {
			RTMPInitTimer(pAd, &pBAEntry->RECBATimer,
				      GET_TIMER_FUNCTION
				      (BARecSessionIdleTimeout), pBAEntry,
				      TRUE);
		}

		/* Set Bitmap flag. */
		pEntry->RXBAbitmap |= (1 << TID);
		pEntry->BARecWcidArray[TID] = Idx;

		pEntry->BADeclineBitmap &= ~(1 << TID);

		/* Set BA session mask in WCID table. */
		RTMP_ADD_BA_SESSION_TO_ASIC(pAd, pEntry->Aid, TID);

		DBGPRINT(RT_DEBUG_TRACE,
			 ("MACEntry[%d]RXBAbitmap = 0x%x. BARecWcidArray=%d\n",
			  pEntry->Aid, pEntry->RXBAbitmap,
			  pEntry->BARecWcidArray[TID]));
	} else {
		Status = FALSE;
		DBGPRINT(RT_DEBUG_TRACE,
			("Can't Accept ADDBA for %pM TID = %d\n",
				pEntry->Addr, TID));
	}
	return (Status);
}