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

📄 rtusb_bulk.c

📁 D-link 无线usb网卡的Linux无线网卡驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
		case 0:
			 if ((status == USB_ST_NOERROR) && (atomic_read(&pRxContext->IrpLock) != IRPLOCK_CANCE_START))
			{
				//RTUSBRxPacket(pUrb);
				pAd->rx_bh.data = (unsigned long)pUrb;
				tasklet_schedule(&pAd->rx_bh);
				break;
				
			}// STATUS_SUCCESS
			DBGPRINT(RT_DEBUG_INFO,"==> RTUSBBulkRxComplete  (IrpLock) = %d\n", atomic_read(&pRxContext->IrpLock));
			break;
		
		case -ECONNRESET:		// async unlink
		case -ESHUTDOWN:		// hardware gone = -108
			pUrb = NULL;
			DBGPRINT(RT_DEBUG_ERROR,"==> RTUSBBulkRxComplete Error code = %d\n", status);
			//tasklet_schedule(&pAd->rx_bh);
			break;

	}
#if 0
	 if ((status == USB_ST_NOERROR) && (atomic_read(&pRxContext->IrpLock) != IRPLOCK_CANCE_START))
	{
		RTUSBRxPacket(pUrb);
		//tasklet_schedule(&pAd->rx_bh);
		
	}// STATUS_SUCCESS
	else
	{
		DBGPRINT(RT_DEBUG_TEMP,"==> RTUSBBulkRxComplete Error code = %d\n", status);
		pRxContext->InUse = FALSE;

		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
		{
			DBGPRINT_RAW(RT_DEBUG_ERROR, "Bulk In Failed\n");
			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
			RTUSBEnqueueInternalCmd(pAd, RT_OID_USB_RESET_BULK_IN);
		}
	}

#endif
}

VOID	RTUSBInitTxDesc(
	IN	PRTMP_ADAPTER	pAd,
	IN	PTX_CONTEXT 	pTxContext,
	IN	UCHAR			BulkOutPipeId,
	IN	usb_complete_t	Func)
{
	PURB				pUrb;
	PUCHAR				pSrc = NULL;

	pUrb = pTxContext->pUrb;
	ASSERT(pUrb);

	// Store BulkOut PipeId
	pTxContext->BulkOutPipeId = BulkOutPipeId;
	
    pSrc = (PUCHAR) &pTxContext->TransferBuffer->TxDesc;


	//Initialize a tx bulk urb
	RTusb_fill_bulk_urb(pUrb,
						pAd->pUsb_Dev,
						usb_sndbulkpipe(pAd->pUsb_Dev, 1),
						pSrc,
						pTxContext->BulkOutSize,
						Func,
						pTxContext);
		
}

VOID	RTUSBInitRxDesc(
	IN	PRTMP_ADAPTER	pAd,
	IN	PRX_CONTEXT		pRxContext)
{
	PURB				pUrb;
	
	pUrb = pRxContext->pUrb;
	ASSERT(pUrb);

	//Initialize a rx bulk urb
	RTusb_fill_bulk_urb(pUrb,
						pAd->pUsb_Dev,
						usb_rcvbulkpipe(pAd->pUsb_Dev, 1),
						pRxContext->TransferBuffer,
						BUFFER_SIZE,
						RTUSBBulkRxComplete,
						pRxContext);
}

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

	Arguments:

	Return Value:

	Note:
	
	========================================================================
*/
VOID	RTUSBBulkOutDataPacket(
	IN	PRTMP_ADAPTER	pAd,
	IN	UCHAR			BulkOutPipeId,
	IN	UCHAR			Index)
{
	PTX_CONTEXT	pTxContext;
	PURB		pUrb;
	int 		ret = 0;
	ULONG		IrqFlags;
	
	NdisAcquireSpinLock(&pAd->BulkOutLock[BulkOutPipeId], (unsigned long)IrqFlags);
	if (pAd->BulkOutPending[BulkOutPipeId] == TRUE)
	{
		NdisReleaseSpinLock(&pAd->BulkOutLock[BulkOutPipeId], (unsigned long)IrqFlags);
		return;
	}
	pAd->BulkOutPending[BulkOutPipeId] = TRUE;
	NdisReleaseSpinLock(&pAd->BulkOutLock[BulkOutPipeId], (unsigned long)IrqFlags);

	pTxContext = &(pAd->TxContext[BulkOutPipeId][Index]);

	// Increase Total transmit byte counter
	pAd->RalinkCounters.TransmittedByteCount +=  pTxContext->BulkOutSize;


	// Clear Data flag
	RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
	RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));

	if (pTxContext->bWaitingBulkOut	!= TRUE)
	{
		DBGPRINT(RT_DEBUG_ERROR, "RTUSBBulkOutDataPacket failed, pTxContext->bWaitingBulkOut != TRUE, Index %d, NextBulkOutIndex %d\n", 
			Index, pAd->NextBulkOutIndex[BulkOutPipeId]);
		NdisAcquireSpinLock(&pAd->BulkOutLock[BulkOutPipeId], (unsigned long)IrqFlags);
		pAd->BulkOutPending[BulkOutPipeId] = FALSE;
		NdisReleaseSpinLock(&pAd->BulkOutLock[BulkOutPipeId], (unsigned long)IrqFlags);
		return;
	}
	else if (pTxContext->BulkOutSize == 0)
	{
		//
		// This may happen on CCX Leap Ckip or Cmic
		// When the Key was been set not on time.
		// We will break it when the Key was Zero on RTUSBHardTransmit
		// And this will cause deadlock that the TxContext always InUse.
		//
		NdisAcquireSpinLock(&pAd->BulkOutLock[BulkOutPipeId], (unsigned long)IrqFlags);
		
		pTxContext->InUse	   = FALSE;
		pTxContext->LastOne    = FALSE;
		pTxContext->IRPPending = FALSE;
		pTxContext->bWaitingBulkOut = FALSE;
		pTxContext->BulkOutSize= 0;
		pAd->NextBulkOutIndex[BulkOutPipeId] = (pAd->NextBulkOutIndex[BulkOutPipeId] + 1) % TX_RING_SIZE;
		pAd->BulkOutPending[BulkOutPipeId] = FALSE;
		NdisReleaseSpinLock(&pAd->BulkOutLock[BulkOutPipeId], (unsigned long)IrqFlags);

		return;		
	}
	else if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
	{
		//
		// Since there is no connection, so we need to empty the Tx Bulk out Ring.
		//
		while (atomic_read(&pAd->TxCount) > 0)
		{
			DBGPRINT(RT_DEBUG_ERROR, "RTUSBBulkOutDataPacket failed, snice NdisMediaStateDisconnected discard NextBulkOutIndex %d, NextIndex = %d\n", 
				pAd->NextBulkOutIndex[BulkOutPipeId], pAd->NextTxIndex[BulkOutPipeId]);
				
			FREE_TX_RING(pAd, BulkOutPipeId, pTxContext);			
			pTxContext = &(pAd->TxContext[BulkOutPipeId][pAd->NextBulkOutIndex[BulkOutPipeId]]);
		}

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

		return;
	}
	

	// Init Tx context descriptor
	RTUSBInitTxDesc(pAd, pTxContext, BulkOutPipeId, RTUSBBulkOutDataPacketComplete);
		
	pTxContext->IRPPending = TRUE;
	pAd->TxRingTotalNumber[BulkOutPipeId]--;

	pUrb = pTxContext->pUrb;
	if((ret = rtusb_submit_urb(pUrb))!=0)
	{
		DBGPRINT(RT_DEBUG_ERROR, "Submit Tx URB failed %d\n", ret);
		return;
	}

	DBGPRINT_RAW(RT_DEBUG_INFO, "<---RTUSBBulkOutDataPacket \n");
	return;
}

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

	Arguments:

	Return Value:

	Note: NULL frame use BulkOutPipeId = 0
	
	========================================================================
*/
VOID	RTUSBBulkOutNullFrame(
	IN	PRTMP_ADAPTER	pAd)
{
	PTX_CONTEXT	pNullContext = &(pAd->NullContext);
	PURB		pUrb;
	int 		ret = 0;
	ULONG		IrqFlags;
	
	NdisAcquireSpinLock(&pAd->BulkOutLock[0], (unsigned long)IrqFlags);
	if (pAd->BulkOutPending[0] == TRUE)
	{
		NdisReleaseSpinLock(&pAd->BulkOutLock[0], (unsigned long)IrqFlags);
		return;
	}
	pAd->BulkOutPending[0] = TRUE;
	NdisReleaseSpinLock(&pAd->BulkOutLock[0], (unsigned long)IrqFlags);

	// Increase Total transmit byte counter
	pAd->RalinkCounters.TransmittedByteCount +=  pNullContext->BulkOutSize;

	DBGPRINT_RAW(RT_DEBUG_INFO, "--->RTUSBBulkOutNullFrame \n");
	
	// Clear Null frame bulk flag
	RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);


	// Init Tx context descriptor
	RTUSBInitTxDesc(pAd, pNullContext, 0, RTUSBBulkOutNullFrameComplete);
	pNullContext->IRPPending = TRUE;

	pUrb = pNullContext->pUrb;
	if((ret = rtusb_submit_urb(pUrb))!=0)
	{
		DBGPRINT(RT_DEBUG_ERROR,"Submit Tx URB failed %d\n", ret);
		return;
	}	
	
	DBGPRINT_RAW(RT_DEBUG_INFO, "<---RTUSBBulkOutNullFrame \n");
	return;
}

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

	Arguments:

	Return Value:

	Note: RTS frame use BulkOutPipeId = 0
	
	========================================================================
*/
VOID	RTUSBBulkOutRTSFrame(
	IN	PRTMP_ADAPTER	pAd)
{
	PTX_CONTEXT	pRTSContext = &(pAd->RTSContext);
	PURB		pUrb;
	int 		ret = 0;
	ULONG		IrqFlags;
	
	NdisAcquireSpinLock(&pAd->BulkOutLock[0], (unsigned long)IrqFlags);
	if (pAd->BulkOutPending[0] == TRUE)
	{
		NdisReleaseSpinLock(&pAd->BulkOutLock[0], (unsigned long)IrqFlags);
		return;
	}
	pAd->BulkOutPending[0] = TRUE;
	NdisReleaseSpinLock(&pAd->BulkOutLock[0], (unsigned long)IrqFlags);

	// Increase Total transmit byte counter
	pAd->RalinkCounters.TransmittedByteCount +=  pRTSContext->BulkOutSize;

	DBGPRINT_RAW(RT_DEBUG_INFO, "--->RTUSBBulkOutRTSFrame \n");
	
	// Clear RTS frame bulk flag
	RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_RTS);

	// Init Tx context descriptor
	RTUSBInitTxDesc(pAd, pRTSContext, 0, RTUSBBulkOutRTSFrameComplete);
	pRTSContext->IRPPending = TRUE;
	
	pUrb = pRTSContext->pUrb;
	if((ret = rtusb_submit_urb(pUrb))!=0)
	{
		DBGPRINT(RT_DEBUG_ERROR,"Submit Tx URB failed %d\n", ret);
		return;
	}	
	
	DBGPRINT_RAW(RT_DEBUG_INFO, "<---RTUSBBulkOutRTSFrame \n");
	return;
}

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

	Arguments:

	Return Value:

	Note: MLME use BulkOutPipeId = 0
	
	========================================================================
*/
VOID	RTUSBBulkOutMLMEPacket(
	IN	PRTMP_ADAPTER	pAd,
	IN	UCHAR			Index)
{
	PTX_CONTEXT		pMLMEContext;
	PURB			pUrb;
	int 			ret = 0;
	ULONG			IrqFlags;
	
	pMLMEContext = &pAd->MLMEContext[Index];
	
	NdisAcquireSpinLock(&pAd->BulkOutLock[0], (unsigned long)IrqFlags);
	if (pAd->BulkOutPending[0] == TRUE)
	{
		NdisReleaseSpinLock(&pAd->BulkOutLock[0], (unsigned long)IrqFlags);
		return;
	}
	pAd->BulkOutPending[0] = TRUE;
	NdisReleaseSpinLock(&pAd->BulkOutLock[0], (unsigned long)IrqFlags);

	// Increase Total transmit byte counter
	pAd->RalinkCounters.TransmittedByteCount +=  pMLMEContext->BulkOutSize;

	// Clear MLME bulk flag
	RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);

	DBGPRINT_RAW(RT_DEBUG_INFO, "RTUSBBulkOutMLMEPacket::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, "--->RTUSBBulkOutMLMEPacket\n");


	// Init Tx context descriptor
	RTUSBInitTxDesc(pAd, pMLMEContext, 0, RTUSBBulkOutMLMEPacketComplete);
	pMLMEContext->IRPPending = TRUE;


	pUrb = pMLMEContext->pUrb;
	if((ret = rtusb_submit_urb(pUrb))!=0)
	{
		DBGPRINT(RT_DEBUG_ERROR,"Submit MLME URB failed %d\n", ret);
		return;
	}
	
	DBGPRINT_RAW(RT_DEBUG_INFO, "<---RTUSBBulkOutMLMEPacket \n");
	return;
}

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

	Arguments:

	Return Value:

	Note: PsPoll use BulkOutPipeId = 0
	
	========================================================================
*/
VOID	RTUSBBulkOutPsPoll(
	IN	PRTMP_ADAPTER	pAd)
{
	PTX_CONTEXT		pPsPollContext = &(pAd->PsPollContext);
	PURB			pUrb;
	int 			ret = 0;
	ULONG			IrqFlags;
	
	NdisAcquireSpinLock(&pAd->BulkOutLock[0], (unsigned long)IrqFlags);
	if (pAd->BulkOutPending[0] == TRUE)
	{
		NdisReleaseSpinLock(&pAd->BulkOutLock[0], (unsigned long)IrqFlags);
		return;
	}
	pAd->BulkOutPending[0] = TRUE;
	NdisReleaseSpinLock(&pAd->BulkOutLock[0], (unsigned long)IrqFlags);

	DBGPRINT_RAW(RT_DEBUG_INFO, "--->RTUSBBulkOutPsPoll \n");
	
	// Clear PS-Poll bulk flag
	RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);


	// Init Tx context descriptor
	RTUSBInitTxDesc(pAd, pPsPollContext, 0, RTUSBBulkOutPsPollComplete);
	pPsPollContext->IRPPending = TRUE;
	
	pUrb = pPsPollContext->pUrb;
	if((ret = rtusb_submit_urb(pUrb))!=0)
	{
		DBGPRINT(RT_DEBUG_ERROR,"Submit Tx URB failed %d\n", ret);
		return;
	}
	
	DBGPRINT_RAW(RT_DEBUG_INFO, "<---RTUSBBulkOutPsPoll \n");
	return;
}

/*
	========================================================================

	Routine Description:
	USB_RxPacket initializes a URB and uses the Rx IRP to submit it
	to USB. It checks if an Rx Descriptor is available and passes the
	the coresponding buffer to be filled. If no descriptor is available
	fails the request. When setting the completion routine we pass our
	Adapter Object as Context.

⌨️ 快捷键说明

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