📄 rtusb_bulk.c
字号:
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 + -