⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtusb_bulk.c

📁 D-link 无线usb网卡的Linux无线网卡驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
		
	Arguments:
		
	Return Value:
		TRUE			found matched tuple cache
		FALSE			no matched found

	Note:
	
	========================================================================
*/
VOID	RTUSBBulkReceive(
	IN	PRTMP_ADAPTER	pAd)
{
	PRX_CONTEXT pRxContext;
	PURB		pUrb;
	int 		ret = 0;
	
	if ((RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))||
		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))||
		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_PIPE_IN_PROGRESS)))
	{
		return;
	}

	DBGPRINT(RT_DEBUG_INFO,"RTUSBBulkReceive:: pAd->NextRxBulkInIndex = %d\n",pAd->NextRxBulkInIndex);
 
	pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
	pRxContext->InUse = TRUE;
	pAd->NextRxBulkInIndex = (pAd->NextRxBulkInIndex + 1) % RX_RING_SIZE;
	
	atomic_set(&pRxContext->IrpLock, IRPLOCK_CANCELABLE);	
	atomic_inc(&pAd->PendingRx);

	// Init Rx context descriptor
	NdisZeroMemory(pRxContext->TransferBuffer, BUFFER_SIZE);
	RTUSBInitRxDesc(pAd, pRxContext);
	
	pUrb = pRxContext->pUrb;
	if((ret = rtusb_submit_urb(pUrb))!=0)
	{
		DBGPRINT(RT_DEBUG_ERROR,"Submit Rx URB failed %d\n", ret);
		return;
	}

	return;
}

/*
	========================================================================
	
	Routine Description:

	Arguments:

	Return Value:

	Note:
	
	========================================================================
*/
VOID	RTUSBKickBulkOut(
	IN	PRTMP_ADAPTER pAd)
{
	int	RoundOver = 0;
	
	DBGPRINT_RAW(RT_DEBUG_INFO, "--->RTUSBKickBulkOut\n");
	
	do
	{
		// greedy to bulk out. protection are in BulkOut function using InUse parameter
		if (++RoundOver > 2)
			break;
	
	if (!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
		!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
		!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
		!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) &&
		!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)))
	{

		// 1. Data Fragment has highest priority
		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_FRAG))
		{
			if ((!LOCAL_TX_RING_EMPTY(pAd, 0)) && 
				((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) || 
				(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))))
			{				
				RTUSBBulkOutDataPacket(pAd, 0, pAd->NextBulkOutIndex[0]);
			}
		}
		
		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_FRAG_2))
		{
			if ((!LOCAL_TX_RING_EMPTY(pAd, 1)) && 
				((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) || 
				(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))))
			{
				RTUSBBulkOutDataPacket(pAd, 1, pAd->NextBulkOutIndex[1]);
			}
		}
		
		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_FRAG_3))
		{
			if ((!LOCAL_TX_RING_EMPTY(pAd, 2)) && 
				((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) || 
				(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))))
			{
				RTUSBBulkOutDataPacket(pAd, 2, pAd->NextBulkOutIndex[2]);
			}
		}
		
		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_FRAG_4))
		{		
			if ((!LOCAL_TX_RING_EMPTY(pAd, 3)) && 
				((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) || 
				(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))))
			{
				RTUSBBulkOutDataPacket(pAd, 3, pAd->NextBulkOutIndex[3]);
			}
		}
		
		// 2. PS-Poll frame is next
		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL))
		{
			RTUSBBulkOutPsPoll(pAd);
		}		
		
		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_RTS))
		{
			RTUSBBulkOutRTSFrame(pAd);
		}
		// 5. Mlme frame is next
		else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME))
		{
			RTUSBBulkOutMLMEPacket(pAd, pAd->PrioRingFirstIndex);
		}
		// 6. Data frame normal is next
		else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL))
		{
			if ((!LOCAL_TX_RING_EMPTY(pAd, 0)) && 
				((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) || 
				(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))))
            {
				RTUSBBulkOutDataPacket(pAd, 0, pAd->NextBulkOutIndex[0]);			
            }
		}
		else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2))
		{		
			if ((!LOCAL_TX_RING_EMPTY(pAd, 1)) && 
				((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) || 
				(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))))
			{
				RTUSBBulkOutDataPacket(pAd, 1, pAd->NextBulkOutIndex[1]);
			}
		}

		else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3))
		{
			if ((!LOCAL_TX_RING_EMPTY(pAd, 2)) && 
				((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) || 
				(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))))
			{
				RTUSBBulkOutDataPacket(pAd, 2, pAd->NextBulkOutIndex[2]);
			}
		}
		else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4))
		{		
		
			if ((!LOCAL_TX_RING_EMPTY(pAd, 3)) && 
				((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) || 
				(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))))
			{
				RTUSBBulkOutDataPacket(pAd, 3, pAd->NextBulkOutIndex[3]);
			}
		}
		// 7. Null frame is the last
		else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL))
		{
			if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
			{
				RTUSBBulkOutNullFrame(pAd);
			}
		}
		
		// 8. No data avaliable
		else
		{
			
		}
	}
   }  while (FALSE);
	
	DBGPRINT_RAW(RT_DEBUG_INFO, "<---RTUSBKickBulkOut\n");
}

/*
	========================================================================
	
	Routine Description:

	Arguments:

	Return Value:

	Note:
	
	========================================================================
*/
VOID	RTUSBCleanUpDataBulkOutQueue(
	IN	PRTMP_ADAPTER	pAd)
{
	UCHAR			Idx;
	PTX_CONTEXT 	pTxContext;			
	ULONG			IrqFlags;
	
	DBGPRINT(RT_DEBUG_TRACE, "--->CleanUpDataBulkOutQueue\n");

	for (Idx = 0; Idx < 4; Idx++)
	{
		while (!LOCAL_TX_RING_EMPTY(pAd, Idx))
		{			
			pTxContext						= &(pAd->TxContext[Idx][pAd->NextBulkOutIndex[Idx]]);
			pTxContext->LastOne 			= FALSE;
			pTxContext->InUse				= FALSE;
			pTxContext->bWaitingBulkOut		= FALSE;
			pAd->NextBulkOutIndex[Idx] = (pAd->NextBulkOutIndex[Idx] + 1) % TX_RING_SIZE;
		}
		NdisAcquireSpinLock(&pAd->BulkOutLock[Idx], (unsigned long)IrqFlags);
		pAd->BulkOutPending[Idx] = FALSE;
		NdisReleaseSpinLock(&pAd->BulkOutLock[Idx], (unsigned long)IrqFlags);
	}
	
	DBGPRINT(RT_DEBUG_TRACE, "<---CleanUpDataBulkOutQueue\n");
}

/*
	========================================================================
	
	Routine Description:

	Arguments:

	Return Value:
	
	Note:
	
	========================================================================
*/
VOID	RTUSBCleanUpMLMEBulkOutQueue(
	IN	PRTMP_ADAPTER	pAd)
{
	ULONG			IrqFlags;
	
	DBGPRINT(RT_DEBUG_TRACE, "--->CleanUpMLMEBulkOutQueue\n");

	NdisAcquireSpinLock(&pAd->MLMEQLock, (unsigned long)IrqFlags);
	while (pAd->PrioRingTxCnt > 0)
	{
		pAd->MLMEContext[pAd->PrioRingFirstIndex].InUse = FALSE;
			
		pAd->PrioRingFirstIndex++;
		if (pAd->PrioRingFirstIndex >= PRIO_RING_SIZE)
		{
			pAd->PrioRingFirstIndex = 0;
		}

		pAd->PrioRingTxCnt--;
	}
	NdisReleaseSpinLock(&pAd->MLMEQLock, (unsigned long)IrqFlags);

	DBGPRINT(RT_DEBUG_TRACE, "<---CleanUpMLMEBulkOutQueue\n");
}

/*
	========================================================================
	
	Routine Description:

	Arguments:

	Return Value:

	Note:
	
	========================================================================
*/
VOID	RTUSBCancelPendingBulkInIRP(
	IN	PRTMP_ADAPTER	pAd)
{
	PRX_CONTEXT	pRxContext;
	UINT		i;

	DBGPRINT_RAW(RT_DEBUG_TRACE,"--->RTUSBCancelPendingBulkInIRP\n");
	for ( i = 0; i < RX_RING_SIZE; i++)
	{
		pRxContext = &(pAd->RxContext[i]);
		if(atomic_read(&pRxContext->IrpLock) == IRPLOCK_CANCELABLE)
		{
			RTUSB_UNLINK_URB(pRxContext->pUrb);
		}
		atomic_set(&pRxContext->IrpLock, IRPLOCK_CANCE_START);
	}
	DBGPRINT_RAW(RT_DEBUG_TRACE,"<---RTUSBCancelPendingBulkInIRP\n");
}

/*
	========================================================================
	
	Routine Description:

	Arguments:

	Return Value:

	Note:
	
	========================================================================
*/
VOID	RTUSBCancelPendingBulkOutIRP(
	IN	PRTMP_ADAPTER	pAd)
{
	PTX_CONTEXT		pTxContext;
	PTX_CONTEXT		pMLMEContext;
	PTX_CONTEXT		pBeaconContext;
	PTX_CONTEXT		pNullContext;
	PTX_CONTEXT		pPsPollContext;
	PTX_CONTEXT		pRTSContext;
	UINT			i, Idx;
	ULONG			IrqFlags;

	for (Idx = 0; Idx < 4; Idx++)
	{
		for (i = 0; i < TX_RING_SIZE; i++)
		{
			pTxContext = &(pAd->TxContext[Idx][i]);

			if (pTxContext->IRPPending == TRUE)
			{

				// Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
				// remove it from the HeadPendingSendList and NULL out HeadPendingSendList
				//	when the last IRP on the list has been	cancelled; that's how we exit this loop
				//

				RTUSB_UNLINK_URB(pTxContext->pUrb);

				// Sleep 200 microseconds to give cancellation time to work
				RTMPusecDelay(200);
			}
		}
	}

	for (i = 0; i < PRIO_RING_SIZE; i++)
	{
		pMLMEContext = &(pAd->MLMEContext[i]);

		if(pMLMEContext->IRPPending == TRUE)
		{

			// Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
			// remove it from the HeadPendingSendList and NULL out HeadPendingSendList
			//	when the last IRP on the list has been	cancelled; that's how we exit this loop
			//

			RTUSB_UNLINK_URB(pMLMEContext->pUrb);

			// Sleep 200 microsecs to give cancellation time to work
			RTMPusecDelay(200);
		}
	}

	for (i = 0; i < BEACON_RING_SIZE; i++)
	{
		pBeaconContext = &(pAd->BeaconContext[i]);

		if(pBeaconContext->IRPPending == TRUE)
		{

			// Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
			// remove it from the HeadPendingSendList and NULL out HeadPendingSendList
			//	when the last IRP on the list has been	cancelled; that's how we exit this loop
			//

			RTUSB_UNLINK_URB(pBeaconContext->pUrb);

			// Sleep 200 microsecs to give cancellation time to work
			RTMPusecDelay(200);
		}
	}

	pNullContext = &(pAd->NullContext);
	if (pNullContext->IRPPending == TRUE)
		RTUSB_UNLINK_URB(pNullContext->pUrb);

	pRTSContext = &(pAd->RTSContext);
	if (pRTSContext->IRPPending == TRUE)
		RTUSB_UNLINK_URB(pRTSContext->pUrb);
		
	pPsPollContext = &(pAd->PsPollContext);
	if (pPsPollContext->IRPPending == TRUE)
		RTUSB_UNLINK_URB(pPsPollContext->pUrb);

	for (Idx = 0; Idx < 4; Idx++)
	{
		NdisAcquireSpinLock(&pAd->BulkOutLock[Idx], (unsigned long)IrqFlags);
		pAd->BulkOutPending[Idx] = FALSE;
		NdisReleaseSpinLock(&pAd->BulkOutLock[Idx], (unsigned long)IrqFlags);
	}
}

/*
	========================================================================
	
	Routine Description:

	Arguments:

	Return Value:

	Note:
	
	========================================================================
*/
VOID	RTUSBCancelPendingIRPs(
	IN	PRTMP_ADAPTER	pAd)
{
	RTUSBCancelPendingBulkInIRP(pAd);
	RTUSBCancelPendingBulkOutIRP(pAd);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -