Exemple #1
0
/*
	We can do copy the frame into pTxContext when match following conditions.
		=>
		=>
		=>
*/
static inline int RtmpUSBCanDoWrite(struct rt_rtmp_adapter *pAd,
					    u8 QueIdx,
					    struct rt_ht_tx_context *pHTTXContext)
{
	int canWrite = NDIS_STATUS_RESOURCES;

	if (((pHTTXContext->CurWritePosition) <
	     pHTTXContext->NextBulkOutPosition)
	    && (pHTTXContext->CurWritePosition + LOCAL_TXBUF_SIZE) >
	    pHTTXContext->NextBulkOutPosition) {
		DBGPRINT(RT_DEBUG_ERROR, ("RtmpUSBCanDoWrite c1!\n"));
		RTUSB_SET_BULK_FLAG(pAd,
				    (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
	} else if ((pHTTXContext->CurWritePosition == 8)
		   && (pHTTXContext->NextBulkOutPosition < LOCAL_TXBUF_SIZE)) {
		DBGPRINT(RT_DEBUG_ERROR, ("RtmpUSBCanDoWrite c2!\n"));
		RTUSB_SET_BULK_FLAG(pAd,
				    (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
	} else if (pHTTXContext->bCurWriting == TRUE) {
		DBGPRINT(RT_DEBUG_ERROR, ("RtmpUSBCanDoWrite c3!\n"));
	} else {
		canWrite = NDIS_STATUS_SUCCESS;
	}

	return canWrite;
}
Exemple #2
0
static inline NDIS_STATUS RtmpUSBCanDoWrite(
	IN RTMP_ADAPTER		*pAd,
	IN UCHAR			QueIdx,
	IN HT_TX_CONTEXT 	*pHTTXContext)
{
	NDIS_STATUS	canWrite = NDIS_STATUS_RESOURCES;

	if (((pHTTXContext->CurWritePosition) < pHTTXContext->NextBulkOutPosition) && (pHTTXContext->CurWritePosition + LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition)
	{
		DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c1!\n"));
		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
	}
	else if ((pHTTXContext->CurWritePosition == 8) && (pHTTXContext->NextBulkOutPosition < LOCAL_TXBUF_SIZE))
	{
		DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c2!\n"));
		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
	}
	else if (pHTTXContext->bCurWriting == TRUE)
	{
		DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c3!\n"));
	}
	else
	{
		canWrite = NDIS_STATUS_SUCCESS;
	}


	return canWrite;
}
Exemple #3
0
/*
	========================================================================

	Routine	Description:
		This subroutine will scan through releative ring descriptor to find
		out avaliable free ring descriptor and compare with request size.
		
	Arguments:
		pAd	Pointer	to our adapter
		RingType	Selected Ring
		
	Return Value:
		NDIS_STATUS_FAILURE		Not enough free descriptor
		NDIS_STATUS_SUCCESS		Enough free descriptor

	Note:
	
	========================================================================
*/
NDIS_STATUS	RTUSBFreeDescriptorRequest(
	IN	PRTMP_ADAPTER	pAd,
	IN	UCHAR			BulkOutPipeId,
	IN	UINT32			NumberRequired)
{
/*	UCHAR			FreeNumber = 0;*/
/*	UINT			Index;*/
	NDIS_STATUS		Status = NDIS_STATUS_FAILURE;
	unsigned long   IrqFlags;
	HT_TX_CONTEXT	*pHTTXContext;


	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
#ifdef USB_BULK_BUF_ALIGMENT
	if( ((pHTTXContext->CurWriteIdx< pHTTXContext->NextBulkIdx  ) &&   (pHTTXContext->NextBulkIdx - pHTTXContext->CurWriteIdx == 1)) 
		|| ((pHTTXContext->CurWriteIdx ==(BUF_ALIGMENT_RINGSIZE -1) ) &&  (pHTTXContext->NextBulkIdx == 0 )))
	{
		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));

	}
	else if (pHTTXContext->bCurWriting == TRUE)
	{
		DBGPRINT(RT_DEBUG_TRACE,("BUF_ALIGMENT RTUSBFreeD c3 --> QueIdx=%d, CWPos=%ld, NBOutPos=%ld!\n", BulkOutPipeId, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition));
		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
	}

#else
	if ((pHTTXContext->CurWritePosition < pHTTXContext->NextBulkOutPosition) && ((pHTTXContext->CurWritePosition + NumberRequired + LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition))
	{
		
		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
	}
	else if ((pHTTXContext->CurWritePosition == 8) && (pHTTXContext->NextBulkOutPosition < (NumberRequired + LOCAL_TXBUF_SIZE)))
	{
		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
	}
	else if (pHTTXContext->bCurWriting == TRUE)
	{
		DBGPRINT(RT_DEBUG_TRACE,("RTUSBFreeD c3 --> QueIdx=%d, CWPos=%ld, NBOutPos=%ld!\n", BulkOutPipeId, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition));
		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
	}
#endif /* USB_BULK_BUF_ALIGMENT */
	else
	{
		Status = NDIS_STATUS_SUCCESS;
	}
	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);

	
	return (Status);
}
/*
	We can do copy the frame into pTxContext when match following conditions.
		=>
		=>
		=>
*/
static inline NDIS_STATUS RtmpUSBCanDoWrite(
	IN RTMP_ADAPTER *pAd,
	IN UCHAR QueIdx,
	IN HT_TX_CONTEXT *pHTTXContext)
{
	NDIS_STATUS	canWrite = NDIS_STATUS_RESOURCES;

#ifdef USB_BULK_BUF_ALIGMENT
	if( ((pHTTXContext->CurWriteIdx< pHTTXContext->NextBulkIdx  ) &&   (pHTTXContext->NextBulkIdx - pHTTXContext->CurWriteIdx == 1)) 
		|| ((pHTTXContext->CurWriteIdx ==(BUF_ALIGMENT_RINGSIZE -1) ) &&  (pHTTXContext->NextBulkIdx == 0 )))
	{
		DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite USB_BULK_BUF_ALIGMENT c1!\n"));
		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));		
	}
	else if (pHTTXContext->bCurWriting == TRUE)
	{
		DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite USB_BULK_BUF_ALIGMENT c3!!\n"));

	}
#else

	if (((pHTTXContext->CurWritePosition) < pHTTXContext->NextBulkOutPosition) && (pHTTXContext->CurWritePosition + LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition)
	{
		DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c1!\n"));
		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
	}
	else if ((pHTTXContext->CurWritePosition == 8) && (pHTTXContext->NextBulkOutPosition < LOCAL_TXBUF_SIZE))
	{
		DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c2!\n"));
		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
	}
	else if (pHTTXContext->bCurWriting == TRUE)
	{
		DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c3!\n"));
	}
	else if ((pHTTXContext->ENextBulkOutPosition == 8)  && ((pHTTXContext->CurWritePosition + 7912 ) > MAX_TXBULK_LIMIT)  )
	{
		DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c4!\n"));
		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
	}

#endif /* USB_BULK_BUF_ALIGMENT */
	else
	{
		canWrite = NDIS_STATUS_SUCCESS;
	}
	

	return canWrite;
}
Exemple #5
0
/*
	When can do bulk-out:
		1. TxSwFreeIdx < TX_RING_SIZE;
			It means has at least one Ring entity is ready for bulk-out, kick it out.
		2. If TxSwFreeIdx == TX_RING_SIZE
			Check if the CurWriting flag is FALSE, if it's FALSE, we can do kick out.

*/
void RtmpUSBDataKickOut(struct rt_rtmp_adapter *pAd,
			struct rt_tx_blk *pTxBlk, u8 QueIdx)
{
	RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
	RTUSBKickBulkOut(pAd);

}
Exemple #6
0
VOID RtmpUSBDataKickOut(
	IN	PRTMP_ADAPTER	pAd,
	IN	TX_BLK			*pTxBlk,
	IN	UCHAR			QueIdx)
{
	RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
	RTUSBKickBulkOut(pAd);

}
/*
	========================================================================

	Routine	Description:
		This subroutine will scan through releative ring descriptor to find
		out avaliable free ring descriptor and compare with request size.

	Arguments:
		pAd	Pointer	to our adapter
		RingType	Selected Ring

	Return Value:
		NDIS_STATUS_FAILURE		Not enough free descriptor
		NDIS_STATUS_SUCCESS		Enough free descriptor

	Note:

	========================================================================
*/
int RTUSBFreeDescriptorRequest(struct rt_rtmp_adapter *pAd,
				       u8 BulkOutPipeId,
				       u32 NumberRequired)
{
/*      u8                   FreeNumber = 0; */
/*      u32                    Index; */
	int Status = NDIS_STATUS_FAILURE;
	unsigned long IrqFlags;
	struct rt_ht_tx_context *pHTTXContext;

	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
	if ((pHTTXContext->CurWritePosition < pHTTXContext->NextBulkOutPosition)
	    &&
	    ((pHTTXContext->CurWritePosition + NumberRequired +
	      LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition)) {

		RTUSB_SET_BULK_FLAG(pAd,
				    (fRTUSB_BULK_OUT_DATA_NORMAL <<
				     BulkOutPipeId));
	} else if ((pHTTXContext->CurWritePosition == 8)
		   && (pHTTXContext->NextBulkOutPosition <
		       (NumberRequired + LOCAL_TXBUF_SIZE))) {
		RTUSB_SET_BULK_FLAG(pAd,
				    (fRTUSB_BULK_OUT_DATA_NORMAL <<
				     BulkOutPipeId));
	} else if (pHTTXContext->bCurWriting == TRUE) {
		DBGPRINT(RT_DEBUG_TRACE,
			 ("RTUSBFreeD c3 --> QueIdx=%d, CWPos=%ld, NBOutPos=%ld!\n",
			  BulkOutPipeId, pHTTXContext->CurWritePosition,
			  pHTTXContext->NextBulkOutPosition));
		RTUSB_SET_BULK_FLAG(pAd,
				    (fRTUSB_BULK_OUT_DATA_NORMAL <<
				     BulkOutPipeId));
	} else {
		Status = NDIS_STATUS_SUCCESS;
	}
	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);

	return (Status);
}
Exemple #8
0
static void rtusb_hcca_dma_done_tasklet(unsigned long data)
{
	PRTMP_ADAPTER		pAd;
	PHT_TX_CONTEXT		pHTTXContext;
	UCHAR				BulkOutPipeId = 4;
	purbb_t				pUrb;

	
	DBGPRINT_RAW(RT_DEBUG_ERROR, ("--->hcca_dma_done_tasklet\n"));


	pUrb			= (purbb_t)data;
/*	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context; */
	pHTTXContext	= (PHT_TX_CONTEXT)RTMP_USB_URB_DATA_GET(pUrb);
	pAd				= pHTTXContext->pAd;

	rtusb_dataout_complete((unsigned long)pUrb);

	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | 
								fRTMP_ADAPTER_HALT_IN_PROGRESS | 
								fRTMP_ADAPTER_NIC_NOT_EXIST)))) 
	{
		/* do nothing and return directly. */
	}
	else 
	{	
		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
		{
			RTEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);	
		}
		else
		{	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) && 
				/*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
				(pAd->DeQueueRunning[BulkOutPipeId] == FALSE) && 
				(pHTTXContext->bCurWriting == FALSE))
			{
				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
			}
			
			RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL);
			RTUSBKickBulkOut(pAd);
		}
	}
	
	DBGPRINT_RAW(RT_DEBUG_ERROR, ("<---hcca_dma_done_tasklet\n"));

		return;
}
VOID RtmpUSBNullFrameKickOut(
	IN RTMP_ADAPTER *pAd,
	IN UCHAR QueIdx,
	IN UCHAR *pNullFrame,
	IN UINT32 frameLen)
{
	if (pAd->NullContext.InUse == FALSE)
	{
		PTX_CONTEXT pNullContext;
		TXINFO_STRUC *pTxInfo;
		TXWI_STRUC *pTxWI;
		UCHAR *pWirelessPkt;
		UINT8 TXWISize = pAd->chipCap.TXWISize;

		pNullContext = &(pAd->NullContext);

		/* Set the in use bit*/
		pNullContext->InUse = TRUE;
		pWirelessPkt = (PUCHAR)&pNullContext->TransferBuffer->field.WirelessPacket[0];

		RTMPZeroMemory(&pWirelessPkt[0], 100);
		pTxInfo = (TXINFO_STRUC *)&pWirelessPkt[0];
		rlt_usb_write_txinfo(pAd, pTxInfo, (USHORT)(frameLen + TXWISize + TSO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE,  FALSE);
		pTxInfo->TxInfoQSEL = FIFO_EDCA;
		pTxWI = (TXWI_STRUC *)&pWirelessPkt[TXINFO_SIZE];
		RTMPWriteTxWI(pAd, pTxWI,  FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, frameLen,
			0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
#ifdef RT_BIG_ENDIAN
		RTMPWIEndianChange(pAd, (PUCHAR)pTxWI, TYPE_TXWI);
#endif /* RT_BIG_ENDIAN */
		RTMPMoveMemory(&pWirelessPkt[TXWISize + TXINFO_SIZE + TSO_SIZE], pNullFrame, frameLen);
#ifdef RT_BIG_ENDIAN
		RTMPFrameEndianChange(pAd, (PUCHAR)&pWirelessPkt[TXINFO_SIZE + TXWISize + TSO_SIZE], DIR_WRITE, FALSE);
#endif /* RT_BIG_ENDIAN */
		pAd->NullContext.BulkOutSize =  TXINFO_SIZE + TXWISize + TSO_SIZE + frameLen + 4;
		pAd->NullContext.BulkOutSize = ( pAd->NullContext.BulkOutSize + 3) & (~3);

		/* Fill out frame length information for global Bulk out arbitor*/
		/*pNullContext->BulkOutSize = TransferBufferLength;*/
		DBGPRINT(RT_DEBUG_TRACE, ("%s - Send NULL Frame @%d Mbps...\n", __FUNCTION__, RateIdToMbps[pAd->CommonCfg.TxRate]));
		RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);

		pAd->Sequence = (pAd->Sequence+1) & MAXSEQ;
		
		/* Kick bulk out */
		RTUSBKickBulkOut(pAd);
	}

}
Exemple #10
0
/*
	When can do bulk-out:
		1. TxSwFreeIdx < TX_RING_SIZE;
			It means has at least one Ring entity is ready for bulk-out, kick it out.
		2. If TxSwFreeIdx == TX_RING_SIZE
			Check if the CurWriting flag is FALSE, if it's FALSE, we can do kick out.

*/
VOID RtmpUSBDataKickOut(
	IN RTMP_ADAPTER *pAd,
	IN TX_BLK *pTxBlk,
	IN UCHAR QueIdx)
{

#ifdef CONFIG_MULTI_CHANNEL
	if ((pAd->MultiChannelFlowCtl & (1 << QueIdx)) == (1 << QueIdx))
	{
		return;
	}
#endif /* CONFIG_MULTI_CHANNEL */
	RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
	RTUSBKickBulkOut(pAd);

}
Exemple #11
0
void RtmpUSBNullFrameKickOut(struct rt_rtmp_adapter *pAd,
			     u8 QueIdx,
			     u8 * pNullFrame, u32 frameLen)
{
	if (pAd->NullContext.InUse == FALSE) {
		struct rt_tx_context *pNullContext;
		struct rt_txinfo *pTxInfo;
		struct rt_txwi * pTxWI;
		u8 *pWirelessPkt;

		pNullContext = &(pAd->NullContext);

		/* Set the in use bit */
		pNullContext->InUse = TRUE;
		pWirelessPkt =
		    (u8 *)& pNullContext->TransferBuffer->field.
		    WirelessPacket[0];

		RTMPZeroMemory(&pWirelessPkt[0], 100);
		pTxInfo = (struct rt_txinfo *)& pWirelessPkt[0];
		RTMPWriteTxInfo(pAd, pTxInfo,
				(u16)(sizeof(struct rt_header_802_11) + TXWI_SIZE),
				TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
		pTxInfo->QSEL = FIFO_EDCA;
		pTxWI = (struct rt_txwi *) & pWirelessPkt[TXINFO_SIZE];
		RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE,
			      FALSE, 0, BSSID_WCID, (sizeof(struct rt_header_802_11)), 0,
			      0, (u8)pAd->CommonCfg.MlmeTransmit.field.MCS,
			      IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);

		RTMPMoveMemory(&pWirelessPkt[TXWI_SIZE + TXINFO_SIZE],
			       &pAd->NullFrame, sizeof(struct rt_header_802_11));
		pAd->NullContext.BulkOutSize =
		    TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;

		/* Fill out frame length information for global Bulk out arbitor */
		/*pNullContext->BulkOutSize = TransferBufferLength; */
		DBGPRINT(RT_DEBUG_TRACE,
			 ("SYNC - send NULL Frame @%d Mbps...\n",
			  RateIdToMbps[pAd->CommonCfg.TxRate]));
		RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);

		/* Kick bulk out */
		RTUSBKickBulkOut(pAd);
	}

}
VOID RtmpUSBNullFrameKickOut(
	IN RTMP_ADAPTER *pAd,
	IN UCHAR		QueIdx,
	IN UCHAR		*pNullFrame,
	IN UINT32		frameLen)
{
	if (pAd->NullContext.InUse == FALSE)
	{
		PTX_CONTEXT		pNullContext;
		PTXINFO_STRUC	pTxInfo;
		PTXWI_STRUC		pTxWI;
		PUCHAR			pWirelessPkt;

		pNullContext = &(pAd->NullContext);

		// Set the in use bit
		pNullContext->InUse = TRUE;
		pWirelessPkt = (PUCHAR)&pNullContext->TransferBuffer->field.WirelessPacket[0];

		RTMPZeroMemory(&pWirelessPkt[0], 100);
		pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[0];
		RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE,  FALSE);
		pTxInfo->QSEL = FIFO_EDCA;
		pTxWI = (PTXWI_STRUC)&pWirelessPkt[TXINFO_SIZE];
		RTMPWriteTxWI(pAd, pTxWI,  FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)),
			0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
#ifdef RT_BIG_ENDIAN
		RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
#endif // RT_BIG_ENDIAN //

		RTMPMoveMemory(&pWirelessPkt[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
#ifdef RT_BIG_ENDIAN
		RTMPFrameEndianChange(pAd, (PUCHAR)&pWirelessPkt[TXINFO_SIZE + TXWI_SIZE], DIR_WRITE, FALSE);
#endif // RT_BIG_ENDIAN //
		pAd->NullContext.BulkOutSize =  TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;

		// Fill out frame length information for global Bulk out arbitor
		//pNullContext->BulkOutSize = TransferBufferLength;
		DBGPRINT(RT_DEBUG_TRACE, ("SYNC - send NULL Frame @%d Mbps...\n", RateIdToMbps[pAd->CommonCfg.TxRate]));
		RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);

		// Kick bulk out
		RTUSBKickBulkOut(pAd);
	}

}
static void rt2870_ac1_dma_done_tasklet(unsigned long data)
{
	PRTMP_ADAPTER		pAd;
	PHT_TX_CONTEXT		pHTTXContext;
	UCHAR				BulkOutPipeId = 1;
	purbb_t				pUrb;


	pUrb			= (purbb_t)data;
	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
	pAd				= pHTTXContext->pAd;

	rt2870_dataout_complete_tasklet((unsigned long)pUrb);

	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | 
								fRTMP_ADAPTER_HALT_IN_PROGRESS | 
								fRTMP_ADAPTER_NIC_NOT_EXIST)))) 
	{
		// do nothing and return directly.
	}
	else 
	{	
		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
		{
			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);	
		}
		else
		{	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) && 
				/*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
				(pAd->DeQueueRunning[BulkOutPipeId] == FALSE) && 
				(pHTTXContext->bCurWriting == FALSE))
			{
				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
			}
			
			RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<1);
			RTUSBKickBulkOut(pAd);
		}
	}


	return;
}
Exemple #14
0
VOID RtmpUSBNullFrameKickOut(
	IN RTMP_ADAPTER *pAd,
	IN UCHAR		QueIdx,
	IN UCHAR		*pNullFrame,
	IN UINT32		frameLen)
{
	if (pAd->NullContext.InUse == FALSE)
	{
		PTX_CONTEXT		pNullContext;
		PTXINFO_STRUC	pTxInfo;
		PTXWI_STRUC		pTxWI;
		PUCHAR			pWirelessPkt;

		pNullContext = &(pAd->NullContext);

		
		pNullContext->InUse = TRUE;
		pWirelessPkt = (PUCHAR)&pNullContext->TransferBuffer->field.WirelessPacket[0];

		RTMPZeroMemory(&pWirelessPkt[0], 100);
		pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[0];
		RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE,  FALSE);
		pTxInfo->QSEL = FIFO_EDCA;
		pTxWI = (PTXWI_STRUC)&pWirelessPkt[TXINFO_SIZE];
		RTMPWriteTxWI(pAd, pTxWI,  FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)),
			0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
		RTMPMoveMemory(&pWirelessPkt[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
		pAd->NullContext.BulkOutSize =  TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;

		
		
		DBGPRINT(RT_DEBUG_TRACE, ("SYNC - send NULL Frame @%d Mbps...\n", RateIdToMbps[pAd->CommonCfg.TxRate]));
		RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);

		
		RTUSBKickBulkOut(pAd);
	}

}
Exemple #15
0
int RtmpUSBMgmtKickOut(
	IN RTMP_ADAPTER 	*pAd,
	IN UCHAR 			QueIdx,
	IN PNDIS_PACKET		pPacket,
	IN PUCHAR			pSrcBufVA,
	IN UINT 			SrcBufLen)
{
	PTXINFO_STRUC	pTxInfo;
	ULONG			BulkOutSize;
	UCHAR			padLen;
	PUCHAR			pDest;
	ULONG			SwIdx = pAd->MgmtRing.TxCpuIdx;
	PTX_CONTEXT		pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[SwIdx].AllocVa;
	unsigned long	IrqFlags;


	pTxInfo = (PTXINFO_STRUC)(pSrcBufVA);

	
	BulkOutSize = SrcBufLen;
	BulkOutSize = (BulkOutSize + 3) & (~3);
	RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(BulkOutSize - TXINFO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE,  FALSE);

	BulkOutSize += 4; 

	
	if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0)
		BulkOutSize += 4;

	padLen = BulkOutSize - SrcBufLen;
	ASSERT((padLen <= RTMP_PKT_TAIL_PADDING));

	
	pDest = (PUCHAR)(pSrcBufVA + SrcBufLen);
	skb_put(GET_OS_PKT_TYPE(pPacket), padLen);
	NdisZeroMemory(pDest, padLen);

	RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);

	pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket;
	pMLMEContext->TransferBuffer = (PTX_BUFFER)(GET_OS_PKT_DATAPTR(pPacket));

	
	pMLMEContext->BulkOutSize = BulkOutSize;
	pMLMEContext->InUse = TRUE;
	pMLMEContext->bWaitingBulkOut = TRUE;


	
	

	
	

	
	

	
	pAd->MgmtRing.TxSwFreeIdx--;
	INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);

	RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);

	RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
	
	RTUSBKickBulkOut(pAd);

	return 0;
}
Exemple #16
0
/*
	Must be run in Interrupt context
	This function handle RT2870 specific TxDesc and cpu index update and kick the packet out.
 */
int RtmpUSBMgmtKickOut(struct rt_rtmp_adapter *pAd,
		       u8 QueIdx,
		       void *pPacket,
		       u8 *pSrcBufVA, u32 SrcBufLen)
{
	struct rt_txinfo *pTxInfo;
	unsigned long BulkOutSize;
	u8 padLen;
	u8 *pDest;
	unsigned long SwIdx = pAd->MgmtRing.TxCpuIdx;
	struct rt_tx_context *pMLMEContext =
	    (struct rt_tx_context *)pAd->MgmtRing.Cell[SwIdx].AllocVa;
	unsigned long IrqFlags;

	pTxInfo = (struct rt_txinfo *)(pSrcBufVA);

	/* Build our URB for USBD */
	BulkOutSize = SrcBufLen;
	BulkOutSize = (BulkOutSize + 3) & (~3);
	RTMPWriteTxInfo(pAd, pTxInfo, (u16)(BulkOutSize - TXINFO_SIZE),
			TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);

	BulkOutSize += 4;	/* Always add 4 extra bytes at every packet. */

	/* If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again. */
	if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0)
		BulkOutSize += 4;

	padLen = BulkOutSize - SrcBufLen;
	ASSERT((padLen <= RTMP_PKT_TAIL_PADDING));

	/* Now memzero all extra padding bytes. */
	pDest = (u8 *)(pSrcBufVA + SrcBufLen);
	skb_put(GET_OS_PKT_TYPE(pPacket), padLen);
	NdisZeroMemory(pDest, padLen);

	RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);

	pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket;
	pMLMEContext->TransferBuffer =
	    (struct rt_tx_buffer *)(GET_OS_PKT_DATAPTR(pPacket));

	/* Length in TxInfo should be 8 less than bulkout size. */
	pMLMEContext->BulkOutSize = BulkOutSize;
	pMLMEContext->InUse = TRUE;
	pMLMEContext->bWaitingBulkOut = TRUE;

	/*for debug */
	/*hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize)); */

	/*pAd->RalinkCounters.KickTxCount++; */
	/*pAd->RalinkCounters.OneSecTxDoneCount++; */

	/*if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE) */
	/*      needKickOut = TRUE; */

	/* Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX */
	pAd->MgmtRing.TxSwFreeIdx--;
	INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);

	RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);

	RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
	/*if (needKickOut) */
	RTUSBKickBulkOut(pAd);

	return 0;
}
static void rt2870_dataout_complete_tasklet(unsigned long data)
{
	PRTMP_ADAPTER		pAd;
	purbb_t				pUrb;
	POS_COOKIE			pObj;
	PHT_TX_CONTEXT		pHTTXContext;
	UCHAR				BulkOutPipeId;
	NTSTATUS			Status;
	unsigned long		IrqFlags;


	pUrb			= (purbb_t)data;
	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
	pAd				= pHTTXContext->pAd;
	pObj 			= (POS_COOKIE) pAd->OS_Cookie;
	Status			= pUrb->status;

	// Store BulkOut PipeId
	BulkOutPipeId = pHTTXContext->BulkOutPipeId;
	pAd->BulkOutDataOneSecCount++;

	//DBGPRINT(RT_DEBUG_LOUD, ("Done-B(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", BulkOutPipeId, in_interrupt(), pHTTXContext->CurWritePosition, 
	//		pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));

	RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
	pAd->BulkOutPending[BulkOutPipeId] = FALSE;
	pHTTXContext->IRPPending = FALSE;
	pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
	
	if (Status == USB_ST_NOERROR)
	{	
		pAd->BulkOutComplete++;

		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
	
		pAd->Counters8023.GoodTransmits++;
		//RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
		FREE_HTTX_RING(pAd, BulkOutPipeId, pHTTXContext);			
		//RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);


	}
	else	// STATUS_OTHER
	{
		PUCHAR	pBuf;
		
		pAd->BulkOutCompleteOther++;
		
		pBuf = &pHTTXContext->TransferBuffer->field.WirelessPacket[pHTTXContext->NextBulkOutPosition];
		
		if (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
									fRTMP_ADAPTER_HALT_IN_PROGRESS |
									fRTMP_ADAPTER_NIC_NOT_EXIST |
									fRTMP_ADAPTER_BULKOUT_RESET)))
		{
			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
			pAd->bulkResetPipeid = BulkOutPipeId;
			pAd->bulkResetReq[BulkOutPipeId] = pAd->BulkOutReq;
		}
		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);

		DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkOutDataPacket failed: ReasonCode=%d!\n", Status));
		DBGPRINT_RAW(RT_DEBUG_ERROR, ("\t>>BulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
		DBGPRINT_RAW(RT_DEBUG_ERROR, ("\t>>BulkOut Header:%x %x %x %x %x %x %x %x\n", pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4], pBuf[5], pBuf[6], pBuf[7]));
		//DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOutCompleteCancel=0x%x, BulkOutCompleteOther=0x%x\n", pAd->BulkOutCompleteCancel, pAd->BulkOutCompleteOther));
		
	}

	//
	// bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut
	// bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out. 
	//
	//RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
	if ((pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition) && 
		(pHTTXContext->ENextBulkOutPosition != (pHTTXContext->CurWritePosition+8)) && 
		!RTUSB_TEST_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)))
	{
		// Indicate There is data avaliable
		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
	}
	//RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);

	// Always call Bulk routine, even reset bulk.
	// The protection of rest bulk should be in BulkOut routine
	RTUSBKickBulkOut(pAd);
}
Exemple #18
0
// MLME use BulkOutPipeId = 0
VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
{
	PTX_CONTEXT			pMLMEContext;
	PRTMP_ADAPTER		pAd;
	NTSTATUS			status;
	unsigned long	IrqFlags;
	
	pMLMEContext= (PTX_CONTEXT)pUrb->context;
	pAd = pMLMEContext->pAd;
	status = pUrb->status;

	pAd->PrioRingTxCnt--;
	if (pAd->PrioRingTxCnt < 0)
		pAd->PrioRingTxCnt = 0;

	pAd->PrioRingFirstIndex++;
	if (pAd->PrioRingFirstIndex >= PRIO_RING_SIZE)
	{
		pAd->PrioRingFirstIndex = 0;
	}	

	DBGPRINT(RT_DEBUG_INFO, "RTUSBBulkOutMLMEPacketComplete::PrioRingFirstIndex = %d, PrioRingTxCnt = %d, PopMgmtIndex = %d, PushMgmtIndex = %d, NextMLMEIndex = %d\n", 
			pAd->PrioRingFirstIndex, 
			pAd->PrioRingTxCnt, pAd->PopMgmtIndex, pAd->PushMgmtIndex, pAd->NextMLMEIndex);

	DBGPRINT_RAW(RT_DEBUG_INFO, "--->RTUSBBulkOutMLMEPacketComplete\n");
	
	// Reset MLME context flags
	pMLMEContext->IRPPending	= FALSE;
	pMLMEContext->InUse 		= FALSE;
	pMLMEContext->bWaitingBulkOut =FALSE;
	
	if (status == USB_ST_NOERROR)
	{
		// Don't worry about the queue is empty or not, this function will check itself
		RTUSBDequeueMLMEPacket(pAd);
	}
#if 1	// STATUS_OTHER
	else
	{
		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
		{
			DBGPRINT_RAW(RT_DEBUG_ERROR, "Bulk Out MLME Failed\n");
			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
			RTUSBEnqueueInternalCmd(pAd, RT_OID_USB_RESET_BULK_OUT);
		}
	}
#endif
	pMLMEContext = &pAd->MLMEContext[pAd->PrioRingFirstIndex];

	if ( (pAd->PrioRingTxCnt >= 1) && (pMLMEContext->bWaitingBulkOut == TRUE))
		RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);

	NdisAcquireSpinLock(&pAd->BulkOutLock[0], IrqFlags);
	pAd->BulkOutPending[0] = FALSE;
	NdisReleaseSpinLock(&pAd->BulkOutLock[0], IrqFlags);

	// Always call Bulk routine, even reset bulk.
	// The protectioon of rest bulk should be in BulkOut routine
	RTUSBKickBulkOut(pAd);

	DBGPRINT_RAW(RT_DEBUG_INFO, "<---RTUSBBulkOutMLMEPacketComplete\n");

}
Exemple #19
0
VOID ATE_RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
{
	PRTMP_ADAPTER	pAd;
	PTX_CONTEXT		pNullContext;
	NTSTATUS		status;
	unsigned long	IrqFlags;
	ULONG			OldValue;
	
	pNullContext= (PTX_CONTEXT)pUrb->context;
	pAd = pNullContext->pAd;

	DBGPRINT_RAW(RT_DEBUG_INFO, "--->ATE_RTUSBBulkOutDataPacketComplete\n");

	// Reset Null frame context flags
	pNullContext->IRPPending = FALSE;
	pNullContext->InUse = FALSE;
	
	status = pUrb->status;
	
	if (status == USB_ST_NOERROR)
	{
		// Don't worry about the queue is empty or not, this function will check itself
		RTMPDeQueuePacket(pAd, 0);
	}
#if 1	// STATUS_OTHER
	else
	{
		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
		{
			DBGPRINT_RAW(RT_DEBUG_ERROR, "Bulk Out Null Frame Failed\n");
			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
			RTUSBEnqueueInternalCmd(pAd, RT_OID_USB_RESET_BULK_OUT);
		}
	}
#endif	

	if (atomic_read(&pAd->BulkOutRemained) > 0)
	{			
		atomic_dec(&pAd->BulkOutRemained);
		DBGPRINT(RT_DEBUG_INFO, "Bulk Out Remained = %d\n", atomic_read(&pAd->BulkOutRemained));
	}
	
	// 1st - Transmit Success
	OldValue = pAd->WlanCounters.TransmittedFragmentCount.vv.LowPart;
	pAd->WlanCounters.TransmittedFragmentCount.vv.LowPart++;
	if (pAd->WlanCounters.TransmittedFragmentCount.vv.LowPart < OldValue)
	{
		pAd->WlanCounters.TransmittedFragmentCount.vv.HighPart++;
	}
	
	if(((pAd->ContinBulkOut == TRUE ) ||(atomic_read(&pAd->BulkOutRemained) > 0)) && (pAd->ate.Mode != ATE_STASTART))
	{	
	
		DBGPRINT(RT_DEBUG_INFO, "ContinBulkOut = TRUE \n");
		RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
	}	
	else
	{
		RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
	}

	NdisAcquireSpinLock(&pAd->BulkOutLock[0], IrqFlags);
	pAd->BulkOutPending[0] = FALSE;
	NdisReleaseSpinLock(&pAd->BulkOutLock[0], IrqFlags);	
	// Always call Bulk routine, even reset bulk.
	// The protectioon of rest bulk should be in BulkOut routine
	RTUSBKickBulkOut(pAd);

	DBGPRINT_RAW(RT_DEBUG_INFO, "<---ATE_RTUSBBulkOutDataPacketComplete\n");

}
/*
	Must be run in Interrupt context
	This function handle RT2870 specific TxDesc and cpu index update and kick the packet out.
 */
int RtmpUSBMgmtKickOut(
	IN RTMP_ADAPTER *pAd, 
	IN UCHAR QueIdx,
	IN PNDIS_PACKET pPacket,
	IN UCHAR *pSrcBufVA,
	IN UINT SrcBufLen)
{
	TXINFO_STRUC *pTxInfo;
	ULONG BulkOutSize;
	UCHAR padLen;
	PUCHAR pDest;
	ULONG SwIdx = pAd->MgmtRing.TxCpuIdx;
	TX_CONTEXT *pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[SwIdx].AllocVa;
	ULONG IrqFlags;

	
	pTxInfo = (TXINFO_STRUC *)(pSrcBufVA);

	/* Build our URB for USBD*/
	BulkOutSize = (SrcBufLen + 3) & (~3);
	rlt_usb_write_txinfo(pAd, pTxInfo, (USHORT)(BulkOutSize - TXINFO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE,  FALSE);
	
	BulkOutSize += 4; /* Always add 4 extra bytes at every packet.*/

//+++Add by shiang for debug
if (0) {
	DBGPRINT(RT_DEBUG_OFF, ("-->%s():shiang-6590, QueIdx=%d, SrcBufLen=%d\n", __FUNCTION__, QueIdx, SrcBufLen));
	dump_txinfo(pAd, pTxInfo);
	dumpTxWI(pAd, (TXWI_STRUC *)(pSrcBufVA + TXINFO_SIZE));
}
//---Add by shiang for debug

/* WY , it cause Tx hang on Amazon_SE , Max said the padding is useless*/
	/* If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again.*/
/*	if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0)*/
/*		BulkOutSize += 4;*/

	padLen = BulkOutSize - SrcBufLen;
	ASSERT((padLen <= RTMP_PKT_TAIL_PADDING));
	
	/* Now memzero all extra padding bytes.*/
	pDest = (PUCHAR)(pSrcBufVA + SrcBufLen);
	OS_PKT_TAIL_BUF_EXTEND(pPacket, padLen);
	NdisZeroMemory(pDest, padLen);

	RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
	
	pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket;
	pMLMEContext->TransferBuffer = (PTX_BUFFER)(GET_OS_PKT_DATAPTR(pPacket));

	/* Length in TxInfo should be 8 less than bulkout size.*/
	pMLMEContext->BulkOutSize = BulkOutSize;
	pMLMEContext->InUse = TRUE;
	pMLMEContext->bWaitingBulkOut = TRUE;

#ifdef UAPSD_SUPPORT
		/*
			If the packet is QoS Null frame, we mark the packet with its WCID;
			If not, we mark the packet with bc/mc WCID = 0.

			We will handle it in rtusb_mgmt_dma_done_tasklet().

			Even AP send a QoS Null frame but not EOSP frame in USB mode,
			then we will call UAPSD_SP_Close() and we will check
			pEntry->bAPSDFlagSPStart() so do not worry about it.
		*/
#endif /* UAPSD_SUPPORT */

	/*hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize));*/

/*
	pAd->RalinkCounters.KickTxCount++;
	pAd->RalinkCounters.OneSecTxDoneCount++;

	if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE)
		needKickOut = TRUE;
*/

	/* Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX*/
	pAd->MgmtRing.TxSwFreeIdx--;
	INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
	
	RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);	
	
	RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
	/*if (needKickOut)*/
	RTUSBKickBulkOut(pAd);
	
	return 0;
}
Exemple #21
0
VOID CMDHandler(                                                                                                                                                
    IN PRTMP_ADAPTER pAd)                                                                                                                                       
{                                                                                                                                                               
	PCmdQElmt		cmdqelmt;                                                                                                                                       
	PUCHAR			pData;                                                                                                                                          
	NDIS_STATUS		NdisStatus = NDIS_STATUS_SUCCESS;                                                                                                               
//	ULONG			Now = 0;
	NTSTATUS		ntStatus;
//	unsigned long	IrqFlags;
	
	while (pAd && pAd->CmdQ.size > 0)	
	{                                                                                                                                                           
		NdisStatus = NDIS_STATUS_SUCCESS;
		                                                                                                                      
		NdisAcquireSpinLock(&pAd->CmdQLock);
		RTThreadDequeueCmd(&pAd->CmdQ, &cmdqelmt);
		NdisReleaseSpinLock(&pAd->CmdQLock);
		                                                                                                        
		if (cmdqelmt == NULL)                                                                                                                                   
			break; 
			                                                                                                                                             
		pData = cmdqelmt->buffer;                                      
		                                                                                         
		if(!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
		{
			switch (cmdqelmt->command)
			{
				case CMDTHREAD_CHECK_GPIO:
					{
#ifdef CONFIG_STA_SUPPORT
						UINT32 data;
#endif // CONFIG_STA_SUPPORT //

#ifdef RALINK_ATE			
       					if(ATE_ON(pAd))
						{
							ATEDBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
							break;
						}	
#endif // RALINK_ATE //

#ifdef CONFIG_STA_SUPPORT


						IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
						{
							// Read GPIO pin2 as Hardware controlled radio state

							RTUSBReadMACRegister( pAd, GPIO_CTRL_CFG, &data);

							if (data & 0x04)
							{
								pAd->StaCfg.bHwRadio = TRUE;                                                                                                            
							} 
							else
							{
								pAd->StaCfg.bHwRadio = FALSE;                                                                                                           
							}                                                                                                                                               
	        	                                                                                                                                                        
							if(pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))                                                                    
							{                                                                                                                                               
								pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);                                                                    
								if(pAd->StaCfg.bRadio == TRUE)                                                                                                          
								{                                                                                                                                           
									DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio On !!!\n"));  
	                                                                                                                            
									MlmeRadioOn(pAd);                                                                                                                       
									// Update extra information                                                                                                             
									pAd->ExtraInfo = EXTRA_INFO_CLEAR;                                                                                                      
								}                                                                                                                                           
								else                                                                                                                                        
								{                                                                                                                                           
									DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio Off !!!\n"));
	                                                                                                                                    
									MlmeRadioOff(pAd);                                                                                                                      
									// Update extra information                                                                                                             
									pAd->ExtraInfo = HW_RADIO_OFF;                                                                                                          
								}                                                                                                                                           
							}
						}
#endif // CONFIG_STA_SUPPORT //
					}
					break;                                                                                                                                         
                                                                                                                                            
#ifdef CONFIG_STA_SUPPORT
				case CMDTHREAD_QKERIODIC_EXECUT:
					{
						StaQuickResponeForRateUpExec(NULL, pAd, NULL, NULL);
					}
					break;
#endif // CONFIG_STA_SUPPORT //

				case CMDTHREAD_RESET_BULK_OUT:                                                                                                                     
					{
						UINT32		MACValue;
						UCHAR		Index;
						int			ret=0;
						PHT_TX_CONTEXT	pHTTXContext;
//						RTMP_TX_RING *pTxRing;
						unsigned long IrqFlags;
						
						DBGPRINT(RT_DEBUG_TRACE, ("CMDTHREAD_RESET_BULK_OUT(ResetPipeid=0x%0x)===>\n", 
									pAd->bulkResetPipeid));
						// All transfers must be aborted or cancelled before attempting to reset the pipe.						
						//RTUSBCancelPendingBulkOutIRP(pAd);
						// Wait 10ms to let previous packet that are already in HW FIFO to clear. by MAXLEE 12-25-2007
						Index = 0;
						do 
						{
							if(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))								
								break;
							
							RTUSBReadMACRegister(pAd, TXRXQ_PCNT, &MACValue);
							if ((MACValue & 0xf00000/*0x800000*/) == 0)
								break;
							Index++;
							RTMPusecDelay(10000);
						}while(Index < 100);
						MACValue = 0;
						RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
						// 2nd, to prevent Read Register error, we check the validity.
						if ((MACValue & 0xc00000) == 0)
							RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
						// 3rd, to prevent Read Register error, we check the validity.
						if ((MACValue & 0xc00000) == 0)
							RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
						MACValue |= 0x80000;
						RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue);

						// Wait 1ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007
						RTMPusecDelay(1000);

						MACValue &= (~0x80000);
						RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue);
						DBGPRINT(RT_DEBUG_TRACE, ("\tSet 0x2a0 bit19. Clear USB DMA TX path\n"));
						
						// Wait 5ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007
						//RTMPusecDelay(5000);

						if ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG)
						{
							RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
							if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */)
							{
								RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
							}
							RTUSBKickBulkOut(pAd);
							
							DBGPRINT(RT_DEBUG_TRACE, ("\tTX MGMT RECOVER Done!\n"));
						}
						else
						{
							pHTTXContext = &(pAd->TxContext[pAd->bulkResetPipeid]);
							//NdisAcquireSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
							RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
							if ( pAd->BulkOutPending[pAd->bulkResetPipeid] == FALSE)
							{
								pAd->BulkOutPending[pAd->bulkResetPipeid] = TRUE;
								pHTTXContext->IRPPending = TRUE;
								pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 1;
								
								// no matter what, clean the flag
								RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
								
								//NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
								RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
#ifdef RALINK_ATE
								if(ATE_ON(pAd))				
							    {
									ret = ATEResetBulkOut(pAd);
								}
								else
#endif // RALINK_ATE //
								{
									RTUSBInitHTTxDesc(pAd, pHTTXContext, pAd->bulkResetPipeid, 
														pHTTXContext->BulkOutSize, 
														(usb_complete_t)RTUSBBulkOutDataPacketComplete);
								if((ret = RTUSB_SUBMIT_URB(pHTTXContext->pUrb))!=0)
								{
										RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
									pAd->BulkOutPending[pAd->bulkResetPipeid] = FALSE;
									pHTTXContext->IRPPending = FALSE;
										pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 0;
										RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);

										DBGPRINT(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_OUT:Submit Tx URB failed %d\n", ret));
								} 
									else
									{
										RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
										DBGPRINT(RT_DEBUG_TRACE,("\tCMDTHREAD_RESET_BULK_OUT: TxContext[%d]:CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, pending=%d!\n", 
												pAd->bulkResetPipeid, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, 
												pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, 
												pAd->BulkOutPending[pAd->bulkResetPipeid]));
										DBGPRINT(RT_DEBUG_TRACE,("\t\tBulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", 
															pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
										RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
										DBGPRINT(RT_DEBUG_TRACE, ("\tCMDTHREAD_RESET_BULK_OUT: Submit Tx DATA URB for failed BulkReq(0x%lx) Done, status=%d!\n", 
												pAd->bulkResetReq[pAd->bulkResetPipeid], 
												pHTTXContext->pUrb->rtusb_urb_status));
									}
								}
							}
							else
							{
								//NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
								//RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
								
								DBGPRINT(RT_DEBUG_ERROR, ("CmdThread : TX DATA RECOVER FAIL for BulkReq(0x%lx) because BulkOutPending[%d] is TRUE!\n", 
											pAd->bulkResetReq[pAd->bulkResetPipeid], pAd->bulkResetPipeid));
								if (pAd->bulkResetPipeid == 0)
								{
									UCHAR	pendingContext = 0;
									PHT_TX_CONTEXT pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[pAd->bulkResetPipeid ]);
									PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
									PTX_CONTEXT pNULLContext = (PTX_CONTEXT)(&pAd->PsPollContext);
									PTX_CONTEXT pPsPollContext = (PTX_CONTEXT)(&pAd->NullContext);

									if (pHTTXContext->IRPPending)
										pendingContext |= 1;
									else if (pMLMEContext->IRPPending)
										pendingContext |= 2;
									else if (pNULLContext->IRPPending)
										pendingContext |= 4;
									else if (pPsPollContext->IRPPending)
										pendingContext |= 8;
									else
										pendingContext = 0;
									
									DBGPRINT(RT_DEBUG_ERROR, ("\tTX Occupied by %d!\n", pendingContext));
								}

								// no matter what, clean the flag
								RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);

								RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
								
								RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << pAd->bulkResetPipeid));
							}

							RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
							//RTUSBKickBulkOut(pAd);
						}

					}
					/*
						// Don't cancel BULKIN.	
						while ((atomic_read(&pAd->PendingRx) > 0) && 
								(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) 
						{
							if (atomic_read(&pAd->PendingRx) > 0)
							{
								DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!cancel it!\n"));
								RTUSBCancelPendingBulkInIRP(pAd);
							}
							RTMPusecDelay(100000);
						}
						
						if ((atomic_read(&pAd->PendingRx) == 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
						{
							UCHAR	i;
							RTUSBRxPacket(pAd);
							pAd->NextRxBulkInReadIndex = 0;	// Next Rx Read index
							pAd->NextRxBulkInIndex		= 0;	// Rx Bulk pointer
							for (i = 0; i < (RX_RING_SIZE); i++)
							{
								PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);

								pRxContext->pAd	= pAd;
								pRxContext->InUse		= FALSE;
								pRxContext->IRPPending	= FALSE;
								pRxContext->Readable	= FALSE;
								pRxContext->ReorderInUse = FALSE;
							
							}
							RTUSBBulkReceive(pAd);
							DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTUSBBulkReceive\n"));
						}*/
					DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT<===\n"));
    	   			break;                                                                                                                                              
            	                                                                                                                                                    
				case CMDTHREAD_RESET_BULK_IN:                                                                                                                      
					DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN === >\n"));

					// All transfers must be aborted or cancelled before attempting to reset the pipe.
					{
						UINT32		MACValue;

#ifdef RALINK_ATE
						if (ATE_ON(pAd))
						{
							ATEResetBulkIn(pAd);
						}
						else
#endif // RALINK_ATE //
						{
						//while ((atomic_read(&pAd->PendingRx) > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) 
						if((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
						{
							DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!!\n"));
							RTUSBCancelPendingBulkInIRP(pAd);
							RTMPusecDelay(100000);
							pAd->PendingRx = 0;
						}
						}						
						
						// Wait 10ms before reading register.
						RTMPusecDelay(10000);
						ntStatus = RTUSBReadMACRegister(pAd, MAC_CSR0, &MACValue);

						if ((NT_SUCCESS(ntStatus) == TRUE) && 
							(!(RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF | 
													fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))))
						{		
							UCHAR	i;

							if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF | 
														fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))
								break;
							pAd->NextRxBulkInPosition = pAd->RxContext[pAd->NextRxBulkInIndex].BulkInOffset;
							DBGPRINT(RT_DEBUG_TRACE, ("BULK_IN_RESET: NBIIdx=0x%x,NBIRIdx=0x%x, BIRPos=0x%lx. BIReq=x%lx, BIComplete=0x%lx, BICFail0x%lx\n", 
									pAd->NextRxBulkInIndex,  pAd->NextRxBulkInReadIndex, pAd->NextRxBulkInPosition, pAd->BulkInReq, pAd->BulkInComplete, pAd->BulkInCompleteFail));
							for (i = 0; i < RX_RING_SIZE; i++)
							{
 								DBGPRINT(RT_DEBUG_TRACE, ("\tRxContext[%d]: IRPPending=%d, InUse=%d, Readable=%d!\n"
									, i, pAd->RxContext[i].IRPPending, pAd->RxContext[i].InUse, pAd->RxContext[i].Readable));
							}
 							/*

							DBGPRINT_RAW(RT_DEBUG_ERROR, ("==========================================\n"));

							pAd->NextRxBulkInReadIndex = 0;	// Next Rx Read index
							pAd->NextRxBulkInIndex		= 0;	// Rx Bulk pointer
							for (i = 0; i < (RX_RING_SIZE); i++)
							{
								PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);

								pRxContext->pAd	= pAd;
								pRxContext->InUse		= FALSE;
								pRxContext->IRPPending	= FALSE;
								pRxContext->Readable	= FALSE;
								pRxContext->ReorderInUse = FALSE;
									
							}*/
							RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
							for (i = 0; i < pAd->CommonCfg.NumOfBulkInIRP; i++)
							{
								//RTUSBBulkReceive(pAd);
								PRX_CONTEXT		pRxContext;
								PURB			pUrb;
								int				ret = 0;
								unsigned long	IrqFlags;

	
								RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
								pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
								if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))
								{
									RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
									break;
								}
								pRxContext->InUse = TRUE;
								pRxContext->IRPPending = TRUE;
								pAd->PendingRx++;
								pAd->BulkInReq++;
								RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);

								// Init Rx context descriptor
								RTUSBInitRxDesc(pAd, pRxContext);
								pUrb = pRxContext->pUrb;
								if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
								{	// fail
								
									RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
									pRxContext->InUse = FALSE;
									pRxContext->IRPPending = FALSE;
									pAd->PendingRx--;
									pAd->BulkInReq--;
									RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
									DBGPRINT(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB failed(%d), status=%d\n", ret, pUrb->rtusb_urb_status));
								}
								else
								{	// success
									//DBGPRINT(RT_DEBUG_TRACE, ("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", 
									//							pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex));
									DBGPRINT_RAW(RT_DEBUG_TRACE, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB Done, status=%d!\n", pUrb->rtusb_urb_status));
									ASSERT((pRxContext->InUse == pRxContext->IRPPending));
								}
							}					

						}
						else
						{
							// Card must be removed
							if (NT_SUCCESS(ntStatus) != TRUE)
							{
								RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
								DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Read Register Failed!Card must be removed!!\n\n"));
							}
							else
							{
								DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Cannot do bulk in because flags(0x%lx) on !\n", pAd->Flags));
							}
						}                                                                                                                                                   
					}
					DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN <===\n"));
					break;                                                                                                                                              
            	                                                                                                                                                    
				case CMDTHREAD_SET_ASIC_WCID:
					{
						RT_SET_ASIC_WCID	SetAsicWcid;
						USHORT		offset;
						UINT32		MACValue, MACRValue = 0;
						SetAsicWcid = *((PRT_SET_ASIC_WCID)(pData));
						
						if (SetAsicWcid.WCID >= MAX_LEN_OF_MAC_TABLE)
							return;
						
						offset = MAC_WCID_BASE + ((UCHAR)SetAsicWcid.WCID)*HW_WCID_ENTRY_SIZE;

						DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_SET_ASIC_WCID : WCID = %ld, SetTid  = %lx, DeleteTid = %lx.\n", SetAsicWcid.WCID, SetAsicWcid.SetTid, SetAsicWcid.DeleteTid));
						MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[3]<<24)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[2]<<16)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[1]<<8)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[0]);
						DBGPRINT_RAW(RT_DEBUG_TRACE, ("1-MACValue= %x,\n", MACValue));
						RTUSBWriteMACRegister(pAd, offset, MACValue);
						// Read bitmask
						RTUSBReadMACRegister(pAd, offset+4, &MACRValue);
						if ( SetAsicWcid.DeleteTid != 0xffffffff)
							MACRValue &= (~SetAsicWcid.DeleteTid);
						if (SetAsicWcid.SetTid != 0xffffffff)
							MACRValue |= (SetAsicWcid.SetTid);
						MACRValue &= 0xffff0000;
					
						MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[5]<<8)+pAd->MacTab.Content[SetAsicWcid.WCID].Addr[4];
						MACValue |= MACRValue;
						RTUSBWriteMACRegister(pAd, offset+4, MACValue);
						
						DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-MACValue= %x,\n", MACValue));
					}
					break;

				/* Security Related for Asic command */	
				case CMDTHREAD_SET_WCID_SEC_INFO:
					{
						PRT_ASIC_WCID_SEC_INFO pInfo;

						pInfo = (PRT_ASIC_WCID_SEC_INFO)pData;
						RTMPSetWcidSecurityInfo(pAd, 
												pInfo->BssIdx, 
												pInfo->KeyIdx, 
												pInfo->CipherAlg, 
												pInfo->Wcid, 
												pInfo->KeyTabFlag);
					}
					break;
				
				case CMDTHREAD_SET_ASIC_WCID_IVEIV:
					{
						PRT_ASIC_WCID_IVEIV_ENTRY pInfo;

						pInfo = (PRT_ASIC_WCID_IVEIV_ENTRY)pData;
						AsicUpdateWCIDIVEIV(pAd, 
											pInfo->Wcid, 
											pInfo->Iv, 
											pInfo->Eiv);				
					}
					break;

				case CMDTHREAD_SET_ASIC_WCID_ATTR:
					{						
						PRT_ASIC_WCID_ATTR_ENTRY pInfo;

						pInfo = (PRT_ASIC_WCID_ATTR_ENTRY)pData;
						AsicUpdateWcidAttributeEntry(pAd, 
													 pInfo->BssIdx, 
													 pInfo->KeyIdx, 
													 pInfo->CipherAlg, 
													 pInfo->Wcid, 
													 pInfo->KeyTabFlag);
					}
					break;

				case CMDTHREAD_SET_ASIC_SHARED_KEY:
					{
						PRT_ASIC_SHARED_KEY pInfo;

						pInfo = (PRT_ASIC_SHARED_KEY)pData;
						AsicAddSharedKeyEntry(pAd, 
											  pInfo->BssIndex, 
											  pInfo->KeyIdx, 
											  &pInfo->CipherKey);
					}
					break;

				case CMDTHREAD_SET_ASIC_PAIRWISE_KEY:
					{
						PRT_ASIC_PAIRWISE_KEY pInfo;

						pInfo = (PRT_ASIC_PAIRWISE_KEY)pData;
						AsicAddPairwiseKeyEntry(pAd, 
												pInfo->WCID, 
												&pInfo->CipherKey);
					}
					break;

				case CMDTHREAD_SET_PORT_SECURED:
					{
#ifdef CONFIG_STA_SUPPORT
						STA_PORT_SECURED(pAd);
#endif // CONFIG_STA_SUPPORT //
					}
					break;
					
				case CMDTHREAD_REMOVE_PAIRWISE_KEY:
					{
						UCHAR Wcid = *((PUCHAR)(pData));	
						AsicRemovePairwiseKeyEntry(pAd, Wcid);						
					}
					break;
					
				case CMDTHREAD_SET_CLIENT_MAC_ENTRY:
					{
						PRT_SET_ASIC_WCID pInfo;

						pInfo = (PRT_SET_ASIC_WCID)pData;						
						AsicUpdateRxWCIDTable(pAd, pInfo->WCID, pInfo->Addr);
					}
					break;

// add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
				case CMDTHREAD_UPDATE_PROTECT:
					{
						AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT), TRUE, 0);
					}
					break;
// end johnli

				case CMDTHREAD_802_11_COUNTER_MEASURE:
					break;
					
#ifdef CONFIG_STA_SUPPORT
				case CMDTHREAD_SET_PSM_BIT:
					IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
					{
						USHORT *pPsm = (USHORT *)pData;
						MlmeSetPsmBit(pAd, *pPsm);
					}
					break;
				case CMDTHREAD_FORCE_WAKE_UP:
					IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
						AsicForceWakeup(pAd, TRUE);
					break;
				case CMDTHREAD_FORCE_SLEEP_AUTO_WAKEUP:
				{
					USHORT  TbttNumToNextWakeUp;
					USHORT  NextDtim = pAd->StaCfg.DtimPeriod;
					ULONG   Now;

					NdisGetSystemUpTime(&Now);
					NextDtim -= (USHORT)(Now - pAd->StaCfg.LastBeaconRxTime)/pAd->CommonCfg.BeaconPeriod;

					TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount;
					if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim))
						TbttNumToNextWakeUp = NextDtim;

					RTMP_SET_PSM_BIT(pAd, PWR_SAVE);
					// if WMM-APSD is failed, try to disable following line
					AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
				}
					break;
#endif // CONFIG_STA_SUPPORT //




				default:
					DBGPRINT(RT_DEBUG_ERROR, ("--> Control Thread !! ERROR !! Unknown(cmdqelmt->command=0x%x) !! \n", cmdqelmt->command));
					break;                                                                                                                                              
			}                                                                                                                                                       
		}                                                                                                                                                          
                                                                                                                                                                
		if (cmdqelmt->CmdFromNdis == TRUE)
		{
			if (cmdqelmt->buffer != NULL)
				os_free_mem(pAd, cmdqelmt->buffer);
			os_free_mem(pAd, cmdqelmt);
		}
		else
		{
			if ((cmdqelmt->buffer != NULL) && (cmdqelmt->bufferlength != 0))
				os_free_mem(pAd, cmdqelmt->buffer);
			os_free_mem(pAd, cmdqelmt);
		}
	}	/* end of while */
}
Exemple #22
0
VOID CMDHandler(
    IN PRTMP_ADAPTER pAd)
{
	PCmdQElmt		cmdqelmt;
	PUCHAR			pData;
	NDIS_STATUS		NdisStatus = NDIS_STATUS_SUCCESS;
//	ULONG			Now = 0;
	NTSTATUS		ntStatus;
//	unsigned long	IrqFlags;

	while (pAd->CmdQ.size > 0)
	{
		NdisStatus = NDIS_STATUS_SUCCESS;

		NdisAcquireSpinLock(&pAd->CmdQLock);
		RTUSBDequeueCmd(&pAd->CmdQ, &cmdqelmt);
		NdisReleaseSpinLock(&pAd->CmdQLock);

		if (cmdqelmt == NULL)
			break;

		pData = cmdqelmt->buffer;

		if(!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
		{
			switch (cmdqelmt->command)
			{
				case CMDTHREAD_CHECK_GPIO:
					{
						UINT32 data;

						{
							// Read GPIO pin2 as Hardware controlled radio state

							RTUSBReadMACRegister( pAd, GPIO_CTRL_CFG, &data);

							if (data & 0x04)
							{
								pAd->StaCfg.bHwRadio = TRUE;
							}
							else
							{
								pAd->StaCfg.bHwRadio = FALSE;
							}

							if(pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
							{
								pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
								if(pAd->StaCfg.bRadio == TRUE)
								{
									DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio On !!!\n"));

									MlmeRadioOn(pAd);
									// Update extra information
									pAd->ExtraInfo = EXTRA_INFO_CLEAR;
								}
								else
								{
									DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio Off !!!\n"));

									MlmeRadioOff(pAd);
									// Update extra information
									pAd->ExtraInfo = HW_RADIO_OFF;
								}
							}
						}
					}
					break;

				case CMDTHREAD_QKERIODIC_EXECUT:
					{
						StaQuickResponeForRateUpExec(NULL, pAd, NULL, NULL);
					}
					break;

				case CMDTHREAD_RESET_BULK_OUT:
					{
						UINT32		MACValue;
						UCHAR		Index;
						int			ret=0;
						PHT_TX_CONTEXT	pHTTXContext;
//						RTMP_TX_RING *pTxRing;
						unsigned long IrqFlags;

						DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT(ResetPipeid=0x%0x)===>\n", pAd->bulkResetPipeid));
						// All transfers must be aborted or cancelled before attempting to reset the pipe.
						//RTUSBCancelPendingBulkOutIRP(pAd);
						// Wait 10ms to let previous packet that are already in HW FIFO to clear. by MAXLEE 12-25-2007
						Index = 0;
						do
						{
							RTUSBReadMACRegister(pAd, TXRXQ_PCNT, &MACValue);
							if ((MACValue & 0xf00000/*0x800000*/) == 0)
								break;
							Index++;
							RTMPusecDelay(10000);
						}while(Index < 100);
						MACValue = 0;
						RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
						// To prevent Read Register error, we 2nd check the validity.
						if ((MACValue & 0xc00000) == 0)
							RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
						// To prevent Read Register error, we 3rd check the validity.
						if ((MACValue & 0xc00000) == 0)
							RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
						MACValue |= 0x80000;
						RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue);

						// Wait 1ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007
						RTMPusecDelay(1000);

						MACValue &= (~0x80000);
						RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue);
						DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tSet 0x2a0 bit19. Clear USB DMA TX path\n"));

						// Wait 5ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007
						//RTMPusecDelay(5000);

						if ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG)
						{
							RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
							if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */)
							{
								RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
							}
							RTUSBKickBulkOut(pAd);

							DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tTX MGMT RECOVER Done!\n"));
						}
						else
						{
							pHTTXContext = &(pAd->TxContext[pAd->bulkResetPipeid]);
							//NdisAcquireSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
							RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
							if ( pAd->BulkOutPending[pAd->bulkResetPipeid] == FALSE)
							{
								pAd->BulkOutPending[pAd->bulkResetPipeid] = TRUE;
								pHTTXContext->IRPPending = TRUE;
								pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 1;

								// no matter what, clean the flag
								RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);

								//NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
								RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
/*-----------------------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------------------*/
								{
								RTUSBInitHTTxDesc(pAd, pHTTXContext, pAd->bulkResetPipeid, pHTTXContext->BulkOutSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete);

								if((ret = RTUSB_SUBMIT_URB(pHTTXContext->pUrb))!=0)
								{
										RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
									pAd->BulkOutPending[pAd->bulkResetPipeid] = FALSE;
									pHTTXContext->IRPPending = FALSE;
										pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 0;
										RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);

										DBGPRINT(RT_DEBUG_ERROR, ("CmdThread : CMDTHREAD_RESET_BULK_OUT: Submit Tx URB failed %d\n", ret));
								}
									else
									{
										RTMP_IRQ_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
										DBGPRINT_RAW(RT_DEBUG_TRACE,("\tCMDTHREAD_RESET_BULK_OUT: TxContext[%d]:CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, pending=%d!\n",
												pAd->bulkResetPipeid, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition,
															pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, pAd->BulkOutPending[pAd->bulkResetPipeid]));
										DBGPRINT_RAW(RT_DEBUG_TRACE,("\t\tBulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n",
															pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
										RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
										DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tCMDTHREAD_RESET_BULK_OUT: Submit Tx DATA URB for failed BulkReq(0x%lx) Done, status=%d!\n", pAd->bulkResetReq[pAd->bulkResetPipeid], pHTTXContext->pUrb->status));

									}
								}
							}
							else
							{
								//NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
								//RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);

								DBGPRINT_RAW(RT_DEBUG_ERROR, ("CmdThread : TX DATA RECOVER FAIL for BulkReq(0x%lx) because BulkOutPending[%d] is TRUE!\n", pAd->bulkResetReq[pAd->bulkResetPipeid], pAd->bulkResetPipeid));
								if (pAd->bulkResetPipeid == 0)
								{
									UCHAR	pendingContext = 0;
									PHT_TX_CONTEXT pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[pAd->bulkResetPipeid ]);
									PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
									PTX_CONTEXT pNULLContext = (PTX_CONTEXT)(&pAd->PsPollContext);
									PTX_CONTEXT pPsPollContext = (PTX_CONTEXT)(&pAd->NullContext);

									if (pHTTXContext->IRPPending)
										pendingContext |= 1;
									else if (pMLMEContext->IRPPending)
										pendingContext |= 2;
									else if (pNULLContext->IRPPending)
										pendingContext |= 4;
									else if (pPsPollContext->IRPPending)
										pendingContext |= 8;
									else
										pendingContext = 0;

									DBGPRINT_RAW(RT_DEBUG_ERROR, ("\tTX Occupied by %d!\n", pendingContext));
								}

							// no matter what, clean the flag
							RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);

								RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);

								RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << pAd->bulkResetPipeid));
							}

							RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
							//RTUSBKickBulkOut(pAd);
						}

					}
					/*
						// Don't cancel BULKIN.
						while ((atomic_read(&pAd->PendingRx) > 0) &&
								(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
						{
							if (atomic_read(&pAd->PendingRx) > 0)
							{
								DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!cancel it!\n"));
								RTUSBCancelPendingBulkInIRP(pAd);
							}
							RTMPusecDelay(100000);
						}

						if ((atomic_read(&pAd->PendingRx) == 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
						{
							UCHAR	i;
							RTUSBRxPacket(pAd);
							pAd->NextRxBulkInReadIndex = 0;	// Next Rx Read index
							pAd->NextRxBulkInIndex		= 0;	// Rx Bulk pointer
							for (i = 0; i < (RX_RING_SIZE); i++)
							{
								PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);

								pRxContext->pAd	= pAd;
								pRxContext->InUse		= FALSE;
								pRxContext->IRPPending	= FALSE;
								pRxContext->Readable	= FALSE;
								pRxContext->ReorderInUse = FALSE;

							}
							RTUSBBulkReceive(pAd);
							DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTUSBBulkReceive\n"));
						}*/
					DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT<===\n"));
    	   			break;

				case CMDTHREAD_RESET_BULK_IN:
					DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN === >\n"));

					// All transfers must be aborted or cancelled before attempting to reset the pipe.
					{
						UINT32		MACValue;
/*-----------------------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------------------*/
						{
						//while ((atomic_read(&pAd->PendingRx) > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
						if((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
						{
							DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!!\n"));
							RTUSBCancelPendingBulkInIRP(pAd);
							RTMPusecDelay(100000);
							pAd->PendingRx = 0;
						}
						}

						// Wait 10ms before reading register.
						RTMPusecDelay(10000);
						ntStatus = RTUSBReadMACRegister(pAd, MAC_CSR0, &MACValue);

						if ((NT_SUCCESS(ntStatus) == TRUE) &&
							(!(RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF |
													fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))))
						{
							UCHAR	i;

							if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF |
														fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))
								break;
							pAd->NextRxBulkInPosition = pAd->RxContext[pAd->NextRxBulkInIndex].BulkInOffset;
							DBGPRINT(RT_DEBUG_TRACE, ("BULK_IN_RESET: NBIIdx=0x%x,NBIRIdx=0x%x, BIRPos=0x%lx. BIReq=x%lx, BIComplete=0x%lx, BICFail0x%lx\n",
									pAd->NextRxBulkInIndex,  pAd->NextRxBulkInReadIndex, pAd->NextRxBulkInPosition, pAd->BulkInReq, pAd->BulkInComplete, pAd->BulkInCompleteFail));
							for (i = 0; i < RX_RING_SIZE; i++)
							{
 								DBGPRINT(RT_DEBUG_TRACE, ("\tRxContext[%d]: IRPPending=%d, InUse=%d, Readable=%d!\n"
									, i, pAd->RxContext[i].IRPPending, pAd->RxContext[i].InUse, pAd->RxContext[i].Readable));
							}
 							/*

							DBGPRINT_RAW(RT_DEBUG_ERROR, ("==========================================\n"));

							pAd->NextRxBulkInReadIndex = 0;	// Next Rx Read index
							pAd->NextRxBulkInIndex		= 0;	// Rx Bulk pointer
							for (i = 0; i < (RX_RING_SIZE); i++)
							{
								PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);

								pRxContext->pAd	= pAd;
								pRxContext->InUse		= FALSE;
								pRxContext->IRPPending	= FALSE;
								pRxContext->Readable	= FALSE;
								pRxContext->ReorderInUse = FALSE;

							}*/
							RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
							for (i = 0; i < pAd->CommonCfg.NumOfBulkInIRP; i++)
							{
								//RTUSBBulkReceive(pAd);
								PRX_CONTEXT		pRxContext;
								PURB			pUrb;
								int				ret = 0;
								unsigned long	IrqFlags;


								RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
								pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
								if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))
								{
									RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
									break;
								}
								pRxContext->InUse = TRUE;
								pRxContext->IRPPending = TRUE;
								pAd->PendingRx++;
								pAd->BulkInReq++;
								RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);

								// Init Rx context descriptor
								RTUSBInitRxDesc(pAd, pRxContext);
								pUrb = pRxContext->pUrb;
								if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
								{	// fail

									RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
									pRxContext->InUse = FALSE;
									pRxContext->IRPPending = FALSE;
									pAd->PendingRx--;
									pAd->BulkInReq--;
									RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
									DBGPRINT(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB failed(%d), status=%d\n", ret, pUrb->status));
								}
								else
								{	// success
									DBGPRINT_RAW(RT_DEBUG_TRACE, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB Done, status=%d!\n", pUrb->status));
									ASSERT((pRxContext->InUse == pRxContext->IRPPending));
								}
							}

						}
						else
						{
							// Card must be removed
							if (NT_SUCCESS(ntStatus) != TRUE)
							{
							RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
								DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Read Register Failed!Card must be removed!!\n\n"));
							}
							else
							{
								DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Cannot do bulk in because flags(0x%lx) on !\n", pAd->Flags));
						}
					}
					}
					DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN <===\n"));
					break;

				case CMDTHREAD_SET_ASIC_WCID:
					{
						RT_SET_ASIC_WCID	SetAsicWcid;
						USHORT		offset;
						UINT32		MACValue, MACRValue = 0;
						SetAsicWcid = *((PRT_SET_ASIC_WCID)(pData));

						if (SetAsicWcid.WCID >= MAX_LEN_OF_MAC_TABLE)
							return;

						offset = MAC_WCID_BASE + ((UCHAR)SetAsicWcid.WCID)*HW_WCID_ENTRY_SIZE;

						DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_SET_ASIC_WCID : WCID = %ld, SetTid  = %lx, DeleteTid = %lx.\n", SetAsicWcid.WCID, SetAsicWcid.SetTid, SetAsicWcid.DeleteTid));
						MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[3]<<24)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[2]<<16)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[1]<<8)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[0]);
						DBGPRINT_RAW(RT_DEBUG_TRACE, ("1-MACValue= %x,\n", MACValue));
						RTUSBWriteMACRegister(pAd, offset, MACValue);
						// Read bitmask
						RTUSBReadMACRegister(pAd, offset+4, &MACRValue);
						if ( SetAsicWcid.DeleteTid != 0xffffffff)
							MACRValue &= (~SetAsicWcid.DeleteTid);
						if (SetAsicWcid.SetTid != 0xffffffff)
							MACRValue |= (SetAsicWcid.SetTid);
						MACRValue &= 0xffff0000;

						MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[5]<<8)+pAd->MacTab.Content[SetAsicWcid.WCID].Addr[4];
						MACValue |= MACRValue;
						RTUSBWriteMACRegister(pAd, offset+4, MACValue);

						DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-MACValue= %x,\n", MACValue));
					}
					break;

				case CMDTHREAD_SET_ASIC_WCID_CIPHER:
					{
						RT_SET_ASIC_WCID_ATTRI	SetAsicWcidAttri;
						USHORT		offset;
						UINT32		MACRValue = 0;
						SHAREDKEY_MODE_STRUC csr1;
						SetAsicWcidAttri = *((PRT_SET_ASIC_WCID_ATTRI)(pData));

						if (SetAsicWcidAttri.WCID >= MAX_LEN_OF_MAC_TABLE)
							return;

						offset = MAC_WCID_ATTRIBUTE_BASE + ((UCHAR)SetAsicWcidAttri.WCID)*HW_WCID_ATTRI_SIZE;

						DBGPRINT_RAW(RT_DEBUG_TRACE, ("Cmd : CMDTHREAD_SET_ASIC_WCID_CIPHER : WCID = %ld, Cipher = %lx.\n", SetAsicWcidAttri.WCID, SetAsicWcidAttri.Cipher));
						// Read bitmask
						RTUSBReadMACRegister(pAd, offset, &MACRValue);
						MACRValue = 0;
						MACRValue |= (((UCHAR)SetAsicWcidAttri.Cipher) << 1);

						RTUSBWriteMACRegister(pAd, offset, MACRValue);
						DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-offset = %x , MACValue= %x,\n", offset, MACRValue));

						offset = PAIRWISE_IVEIV_TABLE_BASE + ((UCHAR)SetAsicWcidAttri.WCID)*HW_IVEIV_ENTRY_SIZE;
						MACRValue = 0;
						if ( (SetAsicWcidAttri.Cipher <= CIPHER_WEP128))
							MACRValue |= ( pAd->StaCfg.DefaultKeyId << 30);
						else
							MACRValue |= (0x20000000);
						RTUSBWriteMACRegister(pAd, offset, MACRValue);
						DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-offset = %x , MACValue= %x,\n", offset, MACRValue));

						//
						// Update cipher algorithm. WSTA always use BSS0
						//
						// for adhoc mode only ,because wep status slow than add key, when use zero config
						if (pAd->StaCfg.BssType == BSS_ADHOC )
						{
							offset = MAC_WCID_ATTRIBUTE_BASE;

							RTUSBReadMACRegister(pAd, offset, &MACRValue);
							MACRValue &= (~0xe);
							MACRValue |= (((UCHAR)SetAsicWcidAttri.Cipher) << 1);

							RTUSBWriteMACRegister(pAd, offset, MACRValue);

							//Update group key cipher,,because wep status slow than add key, when use zero config
							RTUSBReadMACRegister(pAd, SHARED_KEY_MODE_BASE+4*(0/2), &csr1.word);

							csr1.field.Bss0Key0CipherAlg = SetAsicWcidAttri.Cipher;
							csr1.field.Bss0Key1CipherAlg = SetAsicWcidAttri.Cipher;

							RTUSBWriteMACRegister(pAd, SHARED_KEY_MODE_BASE+4*(0/2), csr1.word);
						}
					}
					break;

#ifdef RT30xx
//Benson modified for USB interface, avoid in interrupt when write key, 20080724 -->
				case RT_CMD_SET_KEY_TABLE: //General call for AsicAddPairwiseKeyEntry()
				{
					RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo;
					KeyInfo = *((PRT_ADD_PAIRWISE_KEY_ENTRY)(pData));
					AsicAddPairwiseKeyEntry(pAd,
											KeyInfo.MacAddr,
											(UCHAR)KeyInfo.MacTabMatchWCID,
											&KeyInfo.CipherKey);
				}
					break;
				case RT_CMD_SET_RX_WCID_TABLE: //General call for RTMPAddWcidAttributeEntry()
				{
					PMAC_TABLE_ENTRY pEntry;
					UCHAR KeyIdx;
					UCHAR CipherAlg;
					UCHAR ApIdx;

					pEntry = (PMAC_TABLE_ENTRY)(pData);

						RTMPAddWcidAttributeEntry(
										  pAd,
										  ApIdx,
										  KeyIdx,
										  CipherAlg,
										  pEntry);
					}
						break;
//Benson modified for USB interface, avoid in interrupt when write key, 20080724 <--
#endif

				case CMDTHREAD_SET_CLIENT_MAC_ENTRY:
					{
						MAC_TABLE_ENTRY *pEntry;
						pEntry = (MAC_TABLE_ENTRY *)pData;

						{
							AsicRemovePairwiseKeyEntry(pAd, pEntry->apidx, (UCHAR)pEntry->Aid);
							if ((pEntry->AuthMode <= Ndis802_11AuthModeAutoSwitch) && (pEntry->WepStatus == Ndis802_11Encryption1Enabled))
							{
								UINT32 uIV = 0;
								PUCHAR  ptr;

								ptr = (PUCHAR) &uIV;
								*(ptr + 3) = (pAd->StaCfg.DefaultKeyId << 6);
								AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, uIV, 0);
								AsicUpdateWCIDAttribute(pAd, pEntry->Aid, BSS0, pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, FALSE);
							}
							else if (pEntry->AuthMode == Ndis802_11AuthModeWPANone)
							{
								UINT32 uIV = 0;
								PUCHAR  ptr;

								ptr = (PUCHAR) &uIV;
								*(ptr + 3) = (pAd->StaCfg.DefaultKeyId << 6);
								AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, uIV, 0);
								AsicUpdateWCIDAttribute(pAd, pEntry->Aid, BSS0, pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, FALSE);
							}
							else
							{
								//
								// Other case, disable engine.
								// Don't worry WPA key, we will add WPA Key after 4-Way handshaking.
								//
								USHORT   offset;
								offset = MAC_WCID_ATTRIBUTE_BASE + (pEntry->Aid * HW_WCID_ATTRI_SIZE);
								// RX_PKEY_MODE:0 for no security; RX_KEY_TAB:0 for shared key table; BSS_IDX:0
								RTUSBWriteMACRegister(pAd, offset, 0);
							}
						}

						AsicUpdateRxWCIDTable(pAd, pEntry->Aid, pEntry->Addr);
						printk("UpdateRxWCIDTable(): Aid=%d, Addr=%02x:%02x:%02x:%02x:%02x:%02x!\n", pEntry->Aid,
								pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
					}
					break;

#ifdef RT30xx
// add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
				case CMDTHREAD_UPDATE_PROTECT:
					{
						AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT), TRUE, 0);
					}
					break;
// end johnli
#endif

				case OID_802_11_ADD_WEP:
					{
						UINT	i;
						UINT32	KeyIdx;
						PNDIS_802_11_WEP	pWepKey;

						DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::OID_802_11_ADD_WEP  \n"));

						pWepKey = (PNDIS_802_11_WEP)pData;
						KeyIdx = pWepKey->KeyIndex & 0x0fffffff;

						// it is a shared key
						if ((KeyIdx >= 4) || ((pWepKey->KeyLength != 5) && (pWepKey->KeyLength != 13)))
						{
							NdisStatus = NDIS_STATUS_INVALID_DATA;
							DBGPRINT(RT_DEBUG_ERROR, ("CmdThread::OID_802_11_ADD_WEP, INVALID_DATA!!\n"));
						}
						else
						{
							UCHAR CipherAlg;
							pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
							NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
							CipherAlg = (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 5)? CIPHER_WEP64 : CIPHER_WEP128;

							//
							// Change the WEP cipher to CKIP cipher if CKIP KP on.
							// Funk UI or Meetinghouse UI will add ckip key from this path.
							//

							if (pAd->OpMode == OPMODE_STA)
						 	{
								pAd->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
								pAd->MacTab.Content[BSSID_WCID].PairwiseKey.KeyLen = pAd->SharedKey[BSS0][KeyIdx].KeyLen;
						 	}
							pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CipherAlg;
							if (pWepKey->KeyIndex & 0x80000000)
							{
								// Default key for tx (shared key)
								UCHAR	IVEIV[8];
								UINT32	WCIDAttri, Value;
								USHORT	offset, offset2;
								NdisZeroMemory(IVEIV, 8);
								pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
								// Add BSSID to WCTable. because this is Tx wep key.
								// WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0
								WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;

								offset = MAC_WCID_ATTRIBUTE_BASE + (BSSID_WCID* HW_WCID_ATTRI_SIZE);
								RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
								// 1. IV/EIV
								// Specify key index to find shared key.
								IVEIV[3] = (UCHAR)(KeyIdx<< 6);	//WEP Eiv bit off. groupkey index is not 0
								offset = PAIRWISE_IVEIV_TABLE_BASE + (BSS0Mcast_WCID * HW_IVEIV_ENTRY_SIZE);
								offset2 = PAIRWISE_IVEIV_TABLE_BASE + (BSSID_WCID* HW_IVEIV_ENTRY_SIZE);
								for (i=0; i<8;)
								{
									Value = IVEIV[i];
									Value += (IVEIV[i+1]<<8);
									Value += (IVEIV[i+2]<<16);
									Value += (IVEIV[i+3]<<24);
									RTUSBWriteMACRegister(pAd, offset+i, Value);
									RTUSBWriteMACRegister(pAd, offset2+i, Value);
									i+=4;
								}

								// 2. WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:use share key, BSSIdx is 0
								WCIDAttri = (pAd->SharedKey[BSS0][KeyIdx].CipherAlg<<1)|SHAREDKEYTABLE;
								offset = MAC_WCID_ATTRIBUTE_BASE + (BSS0Mcast_WCID* HW_WCID_ATTRI_SIZE);
							        DBGPRINT(RT_DEBUG_TRACE, ("BSS0Mcast_WCID : offset = %x, WCIDAttri = %x\n", offset, WCIDAttri));
								RTUSBWriteMACRegister(pAd, offset, WCIDAttri);

							}
							AsicAddSharedKeyEntry(pAd, BSS0, (UCHAR)KeyIdx, CipherAlg, pWepKey->KeyMaterial, NULL, NULL);
							DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::OID_802_11_ADD_WEP (KeyIdx=%d, Len=%d-byte)\n", KeyIdx, pWepKey->KeyLength));
						}
					}
					break;

				case CMDTHREAD_802_11_COUNTER_MEASURE:
					break;
				default:
					DBGPRINT(RT_DEBUG_ERROR, ("--> Control Thread !! ERROR !! Unknown(cmdqelmt->command=0x%x) !! \n", cmdqelmt->command));
					break;
			}
		}

		if (cmdqelmt->CmdFromNdis == TRUE)
		{
				if (cmdqelmt->buffer != NULL)
					NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);

			NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
		}
		else
		{
			if ((cmdqelmt->buffer != NULL) && (cmdqelmt->bufferlength != 0))
				NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
            {
				NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
			}
		}
	}	/* end of while */
}
static void rt2870_mgmt_dma_done_tasklet(unsigned long data)
{
	PRTMP_ADAPTER 	pAd;
	PTX_CONTEXT		pMLMEContext;
	int				index;
	PNDIS_PACKET	pPacket;
	purbb_t			pUrb;
	NTSTATUS		Status;
	unsigned long	IrqFlags;


	pUrb			= (purbb_t)data;
	pMLMEContext	= (PTX_CONTEXT)pUrb->context;
	pAd 			= pMLMEContext->pAd;
	Status			= pUrb->status;
	index 			= pMLMEContext->SelfIdx;

	ASSERT((pAd->MgmtRing.TxDmaIdx == index));

	RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);


	if (Status != USB_ST_NOERROR)
	{
		//Bulk-Out fail status handle
		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
		{
			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out MLME Failed, Status=%d!\n", Status));
			// TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt?
			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
			pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
		}
	}

	pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
	RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);

	RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
	// Reset MLME context flags	
	pMLMEContext->IRPPending = FALSE;
	pMLMEContext->InUse = FALSE;
	pMLMEContext->bWaitingBulkOut = FALSE;
	pMLMEContext->BulkOutSize = 0;

	pPacket = pAd->MgmtRing.Cell[index].pNdisPacket;
	pAd->MgmtRing.Cell[index].pNdisPacket = NULL;

	// Increase MgmtRing Index
	INC_RING_INDEX(pAd->MgmtRing.TxDmaIdx, MGMT_RING_SIZE);
	pAd->MgmtRing.TxSwFreeIdx++;
	RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);

	// No-matter success or fail, we free the mgmt packet.
	if (pPacket)
		RTMPFreeNdisPacket(pAd, pPacket);

	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | 
								fRTMP_ADAPTER_HALT_IN_PROGRESS | 
								fRTMP_ADAPTER_NIC_NOT_EXIST))))
	{
		// do nothing and return directly.
	}
	else
	{
		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET) && 
			((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG))
		{	// For Mgmt Bulk-Out failed, ignore it now.
			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
		}
		else
		{

			// Always call Bulk routine, even reset bulk.
			// The protectioon of rest bulk should be in BulkOut routine
			if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */)
			{
				RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
			}
				RTUSBKickBulkOut(pAd);
			}
		}

}
Exemple #24
0
// ************************ Completion Func ************************ //
VOID RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
{
	PTX_CONTEXT 	pTxContext;
	PRTMP_ADAPTER	pAd;
	NTSTATUS		status;
	UCHAR			BulkOutPipeId;
	unsigned long	IrqFlags;
	
	DBGPRINT_RAW(RT_DEBUG_INFO, "--->RTUSBBulkOutDataPacketComplete\n");
	pTxContext= (PTX_CONTEXT)pUrb->context;
	pAd = pTxContext->pAd;
	status = pUrb->status;

	// Store BulkOut PipeId
	BulkOutPipeId = pTxContext->BulkOutPipeId;
	pAd->BulkOutDataOneSecCount++;
	
	if (status == USB_ST_NOERROR)
	{	
		DBGPRINT_RAW(RT_DEBUG_INFO, "BulkOutDataPacketComplete %d (STATUS_SUCCESS)\n", BulkOutPipeId);

		if (pTxContext->LastOne == TRUE)
		{
			pAd->Counters.GoodTransmits++;
			FREE_TX_RING(pAd, BulkOutPipeId, pTxContext);
            pAd->TxRingTotalNumber[BulkOutPipeId]--;    // sync. to TxCount

			if (pAd->SendTxWaitQueue[BulkOutPipeId].Number > 0)
			{
				RTMPDeQueuePacket(pAd, BulkOutPipeId);
			}
		}
		else
		{
			if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
				(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
				(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
				(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
			{
				FREE_TX_RING(pAd, BulkOutPipeId, pTxContext);
				pAd->TxRingTotalNumber[BulkOutPipeId]--;    // sync. to TxCount
				// Indicate next one is frag data which has highest priority
				RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
			}
			else
			{
				while (pTxContext->LastOne != TRUE)
				{
					FREE_TX_RING(pAd, BulkOutPipeId, pTxContext);
					pAd->TxRingTotalNumber[BulkOutPipeId]--;    // sync. to TxCount
					pTxContext = &(pAd->TxContext[BulkOutPipeId][pAd->NextBulkOutIndex[BulkOutPipeId]]);
				}
				
				FREE_TX_RING(pAd, BulkOutPipeId, pTxContext);
				pAd->TxRingTotalNumber[BulkOutPipeId]--;    // sync. to TxCount
			}
		}
	}
#if 1	// STATUS_OTHER
	else
	{
		DBGPRINT_RAW(RT_DEBUG_ERROR, "BulkOutDataPacketComplete %d (STATUS_OTHER)\n", BulkOutPipeId);

		while (pTxContext->LastOne != TRUE)
		{
			FREE_TX_RING(pAd, BulkOutPipeId, pTxContext);
			pAd->TxRingTotalNumber[BulkOutPipeId]--;    // sync. to TxCount
			pTxContext = &(pAd->TxContext[BulkOutPipeId][pAd->NextBulkOutIndex[BulkOutPipeId]]);
		}
		FREE_TX_RING(pAd, BulkOutPipeId, pTxContext);
		pAd->TxRingTotalNumber[BulkOutPipeId]--;    // sync. to TxCount

		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
		{
			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);

			RTUSBEnqueueInternalCmd(pAd, RT_OID_USB_RESET_BULK_OUT);
		}

	}
#endif


	pTxContext = &(pAd->TxContext[BulkOutPipeId][pAd->NextBulkOutIndex[BulkOutPipeId]]);
	//
	// bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut
	// bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out. 
	//
	if ((pTxContext->bWaitingBulkOut == TRUE) && !RTUSB_TEST_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)))
	{
		// Indicate There is data avaliable
		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
	}


	NdisAcquireSpinLock(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
	pAd->BulkOutPending[BulkOutPipeId] = FALSE;
	NdisReleaseSpinLock(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
	// Always call Bulk routine, even reset bulk.
	// The protectioon of rest bulk should be in BulkOut routine
	RTUSBKickBulkOut(pAd);
}
/*
	Must be run in Interrupt context
	This function handle RT2870 specific TxDesc and cpu index update and kick the packet out.
 */
int RtmpUSBMgmtKickOut(
	IN RTMP_ADAPTER 	*pAd,
	IN UCHAR 			QueIdx,
	IN PNDIS_PACKET		pPacket,
	IN PUCHAR			pSrcBufVA,
	IN UINT 			SrcBufLen)
{
	PTXINFO_STRUC	pTxInfo;
	ULONG			BulkOutSize;
	UCHAR			padLen;
	PUCHAR			pDest;
	ULONG			SwIdx = pAd->MgmtRing.TxCpuIdx;
	PTX_CONTEXT		pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[SwIdx].AllocVa;
	unsigned long	IrqFlags;


	pTxInfo = (PTXINFO_STRUC)(pSrcBufVA);

	// Build our URB for USBD
	BulkOutSize = SrcBufLen;
	BulkOutSize = (BulkOutSize + 3) & (~3);
	RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(BulkOutSize - TXINFO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE,  FALSE);

	BulkOutSize += 4; // Always add 4 extra bytes at every packet.

	// If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again.
	if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0)
		BulkOutSize += 4;

	padLen = BulkOutSize - SrcBufLen;
	ASSERT((padLen <= RTMP_PKT_TAIL_PADDING));

	// Now memzero all extra padding bytes.
	pDest = (PUCHAR)(pSrcBufVA + SrcBufLen);
	skb_put(GET_OS_PKT_TYPE(pPacket), padLen);
	NdisZeroMemory(pDest, padLen);

	RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);

	pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket;
	pMLMEContext->TransferBuffer = (PTX_BUFFER)(GET_OS_PKT_DATAPTR(pPacket));

	// Length in TxInfo should be 8 less than bulkout size.
	pMLMEContext->BulkOutSize = BulkOutSize;
	pMLMEContext->InUse = TRUE;
	pMLMEContext->bWaitingBulkOut = TRUE;


	//for debug
	//hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize));

	//pAd->RalinkCounters.KickTxCount++;
	//pAd->RalinkCounters.OneSecTxDoneCount++;

	//if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE)
	//	needKickOut = TRUE;

	// Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX
	pAd->MgmtRing.TxSwFreeIdx--;
	INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);

	RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);

	RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
	//if (needKickOut)
	RTUSBKickBulkOut(pAd);

	return 0;
}