Exemple #1
0
static void ba_enqueue_reordering_packet(struct rt_rtmp_adapter *pAd,
					 struct rt_ba_rec_entry *pBAEntry,
					 struct rt_rx_blk *pRxBlk,
					 u8 FromWhichBSSID)
{
	struct reordering_mpdu *mpdu_blk;
	u16 Sequence = (u16)pRxBlk->pHeader->Sequence;

	mpdu_blk = ba_mpdu_blk_alloc(pAd);
	if ((mpdu_blk != NULL) && (!RX_BLK_TEST_FLAG(pRxBlk, fRX_EAP))) {
		/* 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) Can't allocate reordering mpdu blk\n",
			  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);
	}
}
Exemple #2
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
}
Exemple #3
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));

	}
}
Exemple #4
0
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_TRACE, ("%s(): BAR-Wcid(%ld), Tid (%d)\n", __FUNCTION__, 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 | fRTMP_ADAPTER_NIC_NOT_EXIST))
		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;
	}

	DBGPRINT(RT_DEBUG_TRACE, ("BAR(%ld) : Tid (%d) - %04x:%04x\n", Wcid, TID, pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq ));

	if (SEQ_SMALLER(pBAEntry->LastIndSeq, pFrame->BAStartingSeq.field.StartSeq, MAXSEQ))
	{
		//DBGPRINT(RT_DEBUG_TRACE, ("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;
}
Exemple #5
0
void Indicate_AMPDU_Packet(struct rt_rtmp_adapter *pAd,
			   struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
{
	u16 Idx;
	struct rt_ba_rec_entry *pBAEntry = NULL;
	u16 Sequence = pRxBlk->pHeader->Sequence;
	unsigned long Now32;
	u8 Wcid = pRxBlk->pRxWI->WirelessCliID;
	u8 TID = pRxBlk->pRxWI->TID;

	if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU)
	    && (pRxBlk->DataSize > MAX_RX_PKT_LEN)) {
		/* 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)) {
		u16 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) {

		/* 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)) {

		/* 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;

		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;
		}
	}
}
Exemple #6
0
BOOLEAN CntlEnqueueForRecv(struct rt_rtmp_adapter *pAd,
			   unsigned long Wcid,
			   unsigned long MsgLen, struct rt_frame_ba_req * pMsg)
{
	struct rt_frame_ba_req * pFrame = pMsg;
	/*PRTMP_REORDERBUF      pBuffer; */
	/*PRTMP_REORDERBUF      pDmaBuf; */
	struct rt_ba_rec_entry *pBAEntry;
	/*BOOLEAN       Result; */
	unsigned long Idx;
	/*u8 NumRxPkt; */
	u8 TID;		/*, i; */

	TID = (u8)pFrame->BARControl.TID;

	DBGPRINT(RT_DEBUG_TRACE,
		 ("%s(): BAR-Wcid(%ld), Tid (%d)\n", __func__, Wcid, TID));
	/*hex_dump("BAR", (char *)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 | fRTMP_ADAPTER_NIC_NOT_EXIST))
		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(struct rt_frame_ba_req)) {
		DBGPRINT_ERR("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen);
		return FALSE;
	} else if (MsgLen != sizeof(struct rt_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;
	}

	DBGPRINT(RT_DEBUG_TRACE,
		 ("BAR(%ld) : Tid (%d) - %04x:%04x\n", Wcid, TID,
		  pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq));

	if (SEQ_SMALLER
	    (pBAEntry->LastIndSeq, pFrame->BAStartingSeq.field.StartSeq,
	     MAXSEQ)) {
		/*DBGPRINT(RT_DEBUG_TRACE, ("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;
}