Beispiel #1
0
static void ba_indicate_reordering_mpdus_le_seq(
											   IN PRTMP_ADAPTER    pAd, 
											   IN PBA_REC_ENTRY    pBAEntry,
											   IN USHORT           Sequence)
{
	struct reordering_mpdu *mpdu_blk;

	NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
	while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list)))
		{
			/* find in-order frame */
		if ((mpdu_blk->Sequence == Sequence) || SEQ_SMALLER(mpdu_blk->Sequence, Sequence, MAXSEQ))
		{
			/* dequeue in-order frame from reodering list */
			mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list);
			/* pass this frame up */
			ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
			/* free mpdu_blk */
			ba_mpdu_blk_free(pAd, mpdu_blk);            
		}
		else
			{
				break;
			}
	}
	NdisReleaseSpinLock(&pBAEntry->RxReRingLock);   
}
Beispiel #2
0
/*
 * Insert a reordering mpdu into sorted linked list by sequence no.
 */
BOOLEAN ba_reordering_mpdu_insertsorted(struct reordering_list *list, struct reordering_mpdu *mpdu)
{

	struct reordering_mpdu **ppScan = &list->next;

	while (*ppScan != NULL)
	{
		if (SEQ_SMALLER((*ppScan)->Sequence, mpdu->Sequence, MAXSEQ))
		{
			ppScan = &(*ppScan)->next;          
		}
		else if ((*ppScan)->Sequence == mpdu->Sequence)
		{
			/* give up this duplicated frame */
			return(FALSE);         
		}
		else
		{
			/* find position */
			break;
		}
	}

	mpdu->next = *ppScan;
	*ppScan = mpdu;
	list->qlen++;
	return TRUE;
}
Beispiel #3
0
static void ba_indicate_reordering_mpdus_le_seq(struct rt_rtmp_adapter *pAd,
						struct rt_ba_rec_entry *pBAEntry,
						u16 Sequence)
{
	struct reordering_mpdu *mpdu_blk;

	NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
	while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list))) {
		/* find in-order frame */
		if ((mpdu_blk->Sequence == Sequence)
		    || SEQ_SMALLER(mpdu_blk->Sequence, Sequence, MAXSEQ)) {
			/* dequeue in-order frame from reodering list */
			mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list);
			/* pass this frame up */
			ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
			/* free mpdu_blk */
			ba_mpdu_blk_free(pAd, mpdu_blk);
		} else {
			break;
		}
	}
	NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
}
Beispiel #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;
}
Beispiel #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;
		}
	}
}
Beispiel #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;
}