Esempio n. 1
0
/********************************************************************************************************************
 *function:  I still not understand this function, so wait for further implementation
 *   input:  unsigned long	 data		//acturally we send struct tx_ts_record or struct rx_ts_record to these timer
 *  return:  NULL
 *  notice:
 ********************************************************************************************************************/
static void RxPktPendingTimeout(struct timer_list *t)
{
	struct rx_ts_record     *pRxTs = from_timer(pRxTs, t, rx_pkt_pending_timer);
	struct ieee80211_device *ieee = container_of(pRxTs, struct ieee80211_device, RxTsRecord[pRxTs->num]);

	PRX_REORDER_ENTRY	pReorderEntry = NULL;

	//u32 flags = 0;
	unsigned long flags = 0;
	u8 index = 0;
	bool bPktInBuf = false;

	spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
	IEEE80211_DEBUG(IEEE80211_DL_REORDER, "==================>%s()\n", __func__);
	if(pRxTs->rx_timeout_indicate_seq != 0xffff) {
		// Indicate the pending packets sequentially according to SeqNum until meet the gap.
		while(!list_empty(&pRxTs->rx_pending_pkt_list)) {
			pReorderEntry = (PRX_REORDER_ENTRY)list_entry(pRxTs->rx_pending_pkt_list.prev, RX_REORDER_ENTRY, List);
			if(index == 0)
				pRxTs->rx_indicate_seq = pReorderEntry->SeqNum;

			if( SN_LESS(pReorderEntry->SeqNum, pRxTs->rx_indicate_seq) ||
				SN_EQUAL(pReorderEntry->SeqNum, pRxTs->rx_indicate_seq)	) {
				list_del_init(&pReorderEntry->List);

				if(SN_EQUAL(pReorderEntry->SeqNum, pRxTs->rx_indicate_seq))
					pRxTs->rx_indicate_seq = (pRxTs->rx_indicate_seq + 1) % 4096;

				IEEE80211_DEBUG(IEEE80211_DL_REORDER, "RxPktPendingTimeout(): IndicateSeq: %d\n", pReorderEntry->SeqNum);
				ieee->stats_IndicateArray[index] = pReorderEntry->prxb;
				index++;

				list_add_tail(&pReorderEntry->List, &ieee->RxReorder_Unused_List);
			} else {
				bPktInBuf = true;
				break;
			}
		}
	}

	if(index>0) {
		// Set rx_timeout_indicate_seq to 0xffff to indicate no pending packets in buffer now.
		pRxTs->rx_timeout_indicate_seq = 0xffff;

		// Indicate packets
		if(index > REORDER_WIN_SIZE) {
			IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Rx Reorder buffer full!! \n");
			spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
			return;
		}
		ieee80211_indicate_packets(ieee, ieee->stats_IndicateArray, index);
	}

	if(bPktInBuf && (pRxTs->rx_timeout_indicate_seq == 0xffff)) {
		pRxTs->rx_timeout_indicate_seq = pRxTs->rx_indicate_seq;
		mod_timer(&pRxTs->rx_pkt_pending_timer,
			  jiffies + msecs_to_jiffies(ieee->pHTInfo->RxReorderPendingTime));
	}
	spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
}
Esempio n. 2
0
BOOLEAN
InsertRxReorderList(
	IN	PADAPTER		Adapter,
	IN	PRT_RFD			pRfd,
	IN	PRX_TS_RECORD	pTS,
	IN	u2Byte			SeqNum
	)
{
	PMGNT_INFO			pMgntInfo = &Adapter->MgntInfo;
	PRX_REORDER_ENTRY 	pReorderEntry;
	PRT_LIST_ENTRY	pList = &pTS->RxPendingPktList;

	if(!RTIsListEmpty(&pMgntInfo->RxReorder_Unused_List))
	{
		pReorderEntry = (PRX_REORDER_ENTRY)RTRemoveHeadList(&pMgntInfo->RxReorder_Unused_List);

		// Make a reorder entry and insert into a the packet list.
		pReorderEntry->SeqNum = SeqNum;
		pReorderEntry->pRfd = pRfd;

		while(pList->Blink != &pTS->RxPendingPktList)
		{
			if( SN_LESS(pReorderEntry->SeqNum, ((PRX_REORDER_ENTRY)pList->Blink)->SeqNum) )
			{
				// Not reach correct position yet!!
				pList = pList->Blink;
			}
			else if( SN_EQUAL(pReorderEntry->SeqNum, ((PRX_REORDER_ENTRY)pList->Blink)->SeqNum) )
			{
				// Duplicate entry is found!! Do not insert current entry.
				RT_TRACE(COMP_RX_REORDER, DBG_WARNING, ("InsertRxReorderList(): Duplicate packet is dropped!! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, SeqNum));

				RTInsertTailList(&pMgntInfo->RxReorder_Unused_List, &pReorderEntry->List);
				return FALSE;
			}
			else
			{
				break;
			}
		}

		pReorderEntry->List.Blink = pList->Blink;
		pReorderEntry->List.Blink->Flink = &pReorderEntry->List;
		pReorderEntry->List.Flink = pList;
		pList->Blink = &pReorderEntry->List;

		RT_TRACE(COMP_RX_REORDER, DBG_TRACE, ("InsertRxReorderList(): Pkt insert into buffer!! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, SeqNum));
		return TRUE;
	}
	else
	{
		// This part shall be modified!! We can just indicate all the packets in buffer and get reorder entries.
		RT_TRACE(COMP_RX_REORDER, DBG_WARNING, ("InsertRxReorderList(): There is no reorder entry!! Packet is dropped!!\n"));
		return FALSE;
	}
}
Esempio n. 3
0
BOOLEAN
CheckRxTsIndicateSeq(
	IN	PADAPTER		Adapter,
	IN	PRX_TS_RECORD	pTS,
	IN	u2Byte			NewSeqNum
	)
{
	PRT_HIGH_THROUGHPUT 	pHTInfo = Adapter->MgntInfo.pHTInfo;
	u1Byte					WinSize = pHTInfo->RxReorderWinSize;
	u2Byte					WinEnd = (pTS->RxIndicateSeq + WinSize -1)%4096;

	// Rx Reorder initialize condition.
	if(pTS->RxIndicateSeq == 0xffff)
		pTS->RxIndicateSeq = NewSeqNum;

	// Drop out the packet which SeqNum is smaller than WinStart
	if( SN_LESS(NewSeqNum, pTS->RxIndicateSeq ) )
	{
		RT_TRACE(COMP_RX_REORDER, DBG_WARNING, ("CheckRxTsIndicateSeq(): Packet Drop! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, NewSeqNum));
		return FALSE;
	}

	//
	//	SeqNum "MUST" in Window Size !!
	//
	if( !ISinWindow(NewSeqNum ,  pTS->RxIndicateSeq ) )
	{
		RT_TRACE(COMP_RX_REORDER, DBG_WARNING, ("CheckRxTsIndicateSeq(): out-off squence !! Packet Drop! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, NewSeqNum));
		return FALSE;
	}
	
	//
	// Sliding window manipulation. Conditions includes:
	// 1. Incoming SeqNum is equal to WinStart =>Window shift 1
	// 2. Incoming SeqNum is larger than the WinEnd => Window shift N
	//
	if( SN_EQUAL(NewSeqNum, pTS->RxIndicateSeq) )
	{
		pTS->RxIndicateSeq = (pTS->RxIndicateSeq + 1) % 4096;
	}
	else if(SN_LESS(WinEnd, NewSeqNum))
	{
		RT_TRACE(COMP_RX_REORDER, DBG_WARNING, ("CheckRxTsIndicateSeq(): Window Shift! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, NewSeqNum));
		if(NewSeqNum >= (WinSize - 1))
			pTS->RxIndicateSeq = NewSeqNum + 1 -WinSize;
		else
			pTS->RxIndicateSeq = 4095 - (WinSize - (NewSeqNum +1)) + 1;
	}

	return TRUE;
}
Esempio n. 4
0
void RxPktPendingTimeout(unsigned long data)
{
	PRX_TS_RECORD	pRxTs = (PRX_TS_RECORD)data;
	struct rtllib_device *ieee = container_of(pRxTs, struct rtllib_device, RxTsRecord[pRxTs->num]);
	
	PRX_REORDER_ENTRY 	pReorderEntry = NULL;

	unsigned long flags = 0;
	struct rtllib_rxb *stats_IndicateArray[REORDER_WIN_SIZE];
	u8 index = 0;
	bool bPktInBuf = false;


	spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
	RTLLIB_DEBUG(RTLLIB_DL_REORDER,"==================>%s()\n",__FUNCTION__);
	if(pRxTs->RxTimeoutIndicateSeq != 0xffff)
	{
		while(!list_empty(&pRxTs->RxPendingPktList))
		{
			pReorderEntry = (PRX_REORDER_ENTRY)list_entry(pRxTs->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
			if(index == 0)
				pRxTs->RxIndicateSeq = pReorderEntry->SeqNum;

			if( SN_LESS(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq) || 
				SN_EQUAL(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq)	)
			{
				list_del_init(&pReorderEntry->List);
			
				if(SN_EQUAL(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq))
					pRxTs->RxIndicateSeq = (pRxTs->RxIndicateSeq + 1) % 4096;

				RTLLIB_DEBUG(RTLLIB_DL_REORDER,"RxPktPendingTimeout(): IndicateSeq: %d\n", pReorderEntry->SeqNum);
				stats_IndicateArray[index] = pReorderEntry->prxb;
				index++;
				
				list_add_tail(&pReorderEntry->List, &ieee->RxReorder_Unused_List);
			}
			else
			{
				bPktInBuf = true;
				break;
			}
		}
	}

	if(index>0)
	{
		pRxTs->RxTimeoutIndicateSeq = 0xffff;
	
		if(index > REORDER_WIN_SIZE){
			RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket(): Rx Reorer buffer full!! \n");
			spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
			return;
		}
		rtllib_indicate_packets(ieee, stats_IndicateArray, index);
		 bPktInBuf = false;

	}

	if(bPktInBuf && (pRxTs->RxTimeoutIndicateSeq==0xffff))
	{
		pRxTs->RxTimeoutIndicateSeq = pRxTs->RxIndicateSeq;
#if 0   
		if(timer_pending(&pTS->RxPktPendingTimer))
			del_timer_sync(&pTS->RxPktPendingTimer);
		pTS->RxPktPendingTimer.expires = jiffies + MSECS(pHTInfo->RxReorderPendingTime);
		add_timer(&pTS->RxPktPendingTimer);
#else
		mod_timer(&pRxTs->RxPktPendingTimer,  jiffies + MSECS(ieee->pHTInfo->RxReorderPendingTime));
#endif

#if 0		
		if(timer_pending(&pRxTs->RxPktPendingTimer))
			del_timer_sync(&pRxTs->RxPktPendingTimer);
		pRxTs->RxPktPendingTimer.expires = jiffies + ieee->pHTInfo->RxReorderPendingTime;
		add_timer(&pRxTs->RxPktPendingTimer);
#endif
	}
	spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
}
Esempio n. 5
0
VOID
IndicateRxReorderList(
	IN	PADAPTER				Adapter,
	IN	PRX_TS_RECORD			pTS,
	IN	BOOLEAN					bForced
	)
{
	PMGNT_INFO			pMgntInfo = &Adapter->MgntInfo;
	PRT_HIGH_THROUGHPUT	pHTInfo = pMgntInfo->pHTInfo;
	PRX_REORDER_ENTRY 	pReorderEntry = NULL;
	u2Byte				index = 0;
	BOOLEAN				bPktInBuf = FALSE;
//	PRT_RFD				pRfdIndicateArray[REORDER_WIN_SIZE];
	PRT_RFD				*pRfdIndicateArray;
	PRT_GEN_TEMP_BUFFER 	pGenBuf;

	Adapter->rxReorderIndEnterCnt++;

	if(PlatformAtomicExchange(&Adapter->rxReorderRefCount, TRUE) == TRUE)
	{
		Adapter->rxReorderIndRejectCnt[0]++;
		RT_TRACE(COMP_INIT, DBG_LOUD, ("IndicateRxReorderList(): There is already another thread running by AtomicExchange, happened %d times!!!\n", Adapter->rxReorderIndRejectCnt[0]));
		return;
	}

	// Check if there is any other indication thread running.
	if(pTS->RxIndicateState == RXTS_INDICATE_PROCESSING)
	{
		PlatformAtomicExchange(&Adapter->rxReorderRefCount, FALSE);
		Adapter->rxReorderIndRejectCnt[1]++;
		RT_TRACE(COMP_INIT, DBG_LOUD, ("IndicateRxReorderList(): There is already another thread running by RXTS_INDICATE_PROCESSING, happened %d times!!!\n", Adapter->rxReorderIndRejectCnt[1]));
		return;
	}

	// Handling some condition for forced indicate case.
	if(bForced)
	{
		if(RTIsListEmpty(&pTS->RxPendingPktList))
		{
			PlatformAtomicExchange(&Adapter->rxReorderRefCount, FALSE);
			Adapter->rxReorderIndRejectCnt[2]++;
			RT_TRACE(COMP_INIT, DBG_LOUD, ("IndicateRxReorderList(): There is already another thread running by ListEmpty, happened %d times!!!\n", Adapter->rxReorderIndRejectCnt[2]));
			return;
		}
		else
		{
			pReorderEntry = (PRX_REORDER_ENTRY)RTGetHeadList(&pTS->RxPendingPktList);
			pTS->RxIndicateSeq = pReorderEntry->SeqNum;
		}
	}

	Adapter->rxReorderIndAllowCnt++;

	pGenBuf = GetGenTempBuffer (Adapter, sizeof(PRT_RFD)*REORDER_WIN_SIZE);
	pRfdIndicateArray = (PRT_RFD *)pGenBuf->Buffer.Ptr;

	// Prepare indication list and indication.
	do{
		// Check if there is any packet need indicate.
		while(!RTIsListEmpty(&pTS->RxPendingPktList))
		{
			pReorderEntry = (PRX_REORDER_ENTRY)RTGetHeadList(&pTS->RxPendingPktList);

			if(!SN_LESS(pTS->RxIndicateSeq, pReorderEntry->SeqNum))
			{
				// This protect buffer from overflow.
				if(index >= REORDER_WIN_SIZE)
				{
					RT_ASSERT(FALSE, ("IndicateRxReorderList(): Buffer overflow!! \n"));
					bPktInBuf = TRUE;
					break;
				}
				if(index > 0)
				{
					if(PlatformCompareMemory(pReorderEntry->pRfd->Address3,pRfdIndicateArray[index-1]->Address3,6) != 0)		
					{
						bPktInBuf = TRUE;
						break;
					}
				}
			
				pReorderEntry = (PRX_REORDER_ENTRY)RTRemoveHeadList(&pTS->RxPendingPktList);

				if(SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq))
					pTS->RxIndicateSeq = (pTS->RxIndicateSeq + 1) % 4096;

				RT_TRACE(COMP_RX_REORDER, DBG_LOUD, ("RxReorderIndicatePacket(): Packets indication!! IndicateSeq: %d\n",  pReorderEntry->SeqNum));
				pRfdIndicateArray[index] = pReorderEntry->pRfd;
				index++;
				
				RTInsertTailList(&pMgntInfo->RxReorder_Unused_List, &pReorderEntry->List);
			}
			else
			{
				bPktInBuf = TRUE;
				break;
			}
		}

		// Handling pending timer. Set this timer to prevent from long time Rx buffering.
		if(index>0)
		{
			// Cancel previous pending timer.
			{
				PlatformCancelTimer(Adapter, &pTS->RxPktPendingTimer);

				// Set this as a lock to make sure that only one thread is indicating packet.
				pTS->RxIndicateState = RXTS_INDICATE_PROCESSING;
			}

			// Indicate packets
			RT_ASSERT((index<=REORDER_WIN_SIZE), ("RxReorderIndicatePacket(): Rx Reorder buffer full!! \n"));

			// Packets indication.
			DrvIFIndicatePackets(Adapter, pRfdIndicateArray, index);

			// Update local variables.
			//bPktInBuf = FALSE;
			index = 0;
		}
		else
		{
			break;
		}
	}while(TRUE);

	ReturnGenTempBuffer(Adapter, pGenBuf);

	// Release the indication lock and set to new indication step.
	if(bPktInBuf)
	{
		u1Byte	set_penf_timer=FALSE;
		
		{
			if(pTS->RxIndicateState != RXTS_INDICATE_REORDER)
				set_penf_timer = TRUE;
		}

		if (set_penf_timer == TRUE)
		{
			// Set new pending timer.
			pTS->RxIndicateState = RXTS_INDICATE_REORDER;
			PlatformSetTimer(Adapter, &pTS->RxPktPendingTimer, pHTInfo->RxReorderPendingTime);
		}
	}
	else
	{
		pTS->RxIndicateState = RXTS_INDICATE_IDLE;
	}

	PlatformAtomicExchange(&Adapter->rxReorderRefCount, FALSE);
}