rtusb_bulk.c
来自「ralink最新rt3070 usb wifi 无线网卡驱动程序」· C语言 代码 · 共 1,383 行 · 第 1/3 页
C
1,383 行
#ifdef RT_BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO); RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI); #endif // RT_BIG_ENDIAN // break; } #ifdef RT_BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO); RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);#endif // RT_BIG_ENDIAN // }while (TRUE); // adjust the pTxInfo->USBDMANextVLD value of last pTxInfo. if (pLastTxInfo) {#ifdef RT_BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR)pLastTxInfo, TYPE_TXINFO);#endif // RT_BIG_ENDIAN // pLastTxInfo->USBDMANextVLD = 0;#ifdef RT_BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR)pLastTxInfo, TYPE_TXINFO);#endif // RT_BIG_ENDIAN // } /* We need to copy SavedPad when following condition matched! 1. Not the last round of the TxQueue and 2. any match of following cases: (1). The End Position of this bulk out is reach to the Currenct Write position and the TxInfo and related header already write to the CurWritePosition. =>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition) (2). The EndPosition of the bulk out is not reach to the Current Write Position. =>(ENextBulkOutPosition != CurWritePosition) */ if ((bTxQLastRound == FALSE) && (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) && (pHTTXContext->CurWriteRealPos > pHTTXContext->CurWritePosition)) || (pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition)) ) { NdisMoveMemory(pHTTXContext->SavedPad, &pWirelessPkt[pHTTXContext->ENextBulkOutPosition], 8); pHTTXContext->bCopySavePad = TRUE; if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4)) { PUCHAR pBuf = &pHTTXContext->SavedPad[0]; DBGPRINT_RAW(RT_DEBUG_ERROR,("WARNING-Zero-3:%02x%02x%02x%02x%02x%02x%02x%02x,CWPos=%ld, CWRPos=%ld, bCW=%d, NBPos=%ld, TBPos=%ld, TBSize=%ld\n", pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7], pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCurWriting, pHTTXContext->NextBulkOutPosition, TmpBulkEndPos, ThisBulkSize)); pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition]; DBGPRINT_RAW(RT_DEBUG_ERROR,("\tCWPos=%02x%02x%02x%02x%02x%02x%02x%02x\n", pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7])); } //DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad)); } if (pAd->bForcePrintTX == TRUE) DBGPRINT(RT_DEBUG_TRACE,("BulkOut-A:Size=%ld, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad)); //DBGPRINT(RT_DEBUG_LOUD,("BulkOut-A:Size=%ld, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, bLRound=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, bTxQLastRound)); // USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize. pAppendant = &pWirelessPkt[TmpBulkEndPos]; NdisZeroMemory(pAppendant, 8); ThisBulkSize += 4; pHTTXContext->LastOne = TRUE; if ((ThisBulkSize % pAd->BulkOutMaxPacketSize) == 0) ThisBulkSize += 4; pHTTXContext->BulkOutSize = ThisBulkSize; pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1; BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); // Init Tx context descriptor RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete); pUrb = pHTTXContext->pUrb; if((ret = RTUSB_SUBMIT_URB(pUrb))!=0) { DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret)); BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pAd->BulkOutPending[BulkOutPipeId] = FALSE; pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0; BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pHTTXContext->IRPPending = TRUE; BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pAd->BulkOutReq++;}VOID RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs){ PHT_TX_CONTEXT pHTTXContext; PRTMP_ADAPTER pAd; POS_COOKIE pObj; UCHAR BulkOutPipeId; pHTTXContext = (PHT_TX_CONTEXT)pUrb->context; pAd = pHTTXContext->pAd; pObj = (POS_COOKIE) pAd->OS_Cookie; // Store BulkOut PipeId BulkOutPipeId = pHTTXContext->BulkOutPipeId; pAd->BulkOutDataOneSecCount++; switch (BulkOutPipeId) { case 0: pObj->ac0_dma_done_task.data = (unsigned long)pUrb; tasklet_hi_schedule(&pObj->ac0_dma_done_task); break; case 1: pObj->ac1_dma_done_task.data = (unsigned long)pUrb; tasklet_hi_schedule(&pObj->ac1_dma_done_task); break; case 2: pObj->ac2_dma_done_task.data = (unsigned long)pUrb; tasklet_hi_schedule(&pObj->ac2_dma_done_task); break; case 3: pObj->ac3_dma_done_task.data = (unsigned long)pUrb; tasklet_hi_schedule(&pObj->ac3_dma_done_task); break; case 4: pObj->hcca_dma_done_task.data = (unsigned long)pUrb; tasklet_hi_schedule(&pObj->hcca_dma_done_task); break; }}/* ======================================================================== 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; unsigned long IrqFlags; RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags); if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) { RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); return; } pAd->BulkOutPending[0] = TRUE; pAd->watchDogTxPendingCnt[0] = 1; pNullContext->IRPPending = TRUE; RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); // Increase Total transmit byte counter pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize; // Clear Null frame bulk flag RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);#ifdef RT_BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR)pNullContext->TransferBuffer, TYPE_TXINFO);#endif // RT_BIG_ENDIAN // // Init Tx context descriptor RTUSBInitTxDesc(pAd, pNullContext, 0, (usb_complete_t)RTUSBBulkOutNullFrameComplete); pUrb = pNullContext->pUrb; if((ret = RTUSB_SUBMIT_URB(pUrb))!=0) { RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags); pAd->BulkOutPending[0] = FALSE; pAd->watchDogTxPendingCnt[0] = 0; pNullContext->IRPPending = FALSE; RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n", ret)); return; } }// NULL frame use BulkOutPipeId = 0VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs){ PRTMP_ADAPTER pAd; PTX_CONTEXT pNullContext; NTSTATUS Status; POS_COOKIE pObj; pNullContext = (PTX_CONTEXT)pUrb->context; pAd = pNullContext->pAd; Status = pUrb->status; pObj = (POS_COOKIE) pAd->OS_Cookie; pObj->null_frame_complete_task.data = (unsigned long)pUrb; tasklet_hi_schedule(&pObj->null_frame_complete_task);}/* ======================================================================== 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; unsigned long IrqFlags; pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa; pUrb = pMLMEContext->pUrb; if ((pAd->MgmtRing.TxSwFreeIdx >= MGMT_RING_SIZE) || (pMLMEContext->InUse == FALSE) || (pMLMEContext->bWaitingBulkOut == FALSE)) { // Clear MLME bulk flag RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); return; } RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) { RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); return; } pAd->BulkOutPending[MGMTPIPEIDX] = TRUE; pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 1; pMLMEContext->IRPPending = TRUE; pMLMEContext->bWaitingBulkOut = FALSE; RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); // Increase Total transmit byte counter pAd->RalinkCounters.TransmittedByteCount += pMLMEContext->BulkOutSize; // Clear MLME bulk flag RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);#ifdef RT_BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR)pMLMEContext->TransferBuffer, TYPE_TXINFO);#endif // RT_BIG_ENDIAN // // Init Tx context descriptor RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutMLMEPacketComplete);#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) //For mgmt urb buffer, because we use sk_buff, so we need to notify the USB controller do dma mapping. pUrb->transfer_dma = 0; pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP);#endif pUrb = pMLMEContext->pUrb; if((ret = RTUSB_SUBMIT_URB(pUrb))!=0) { DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n", ret)); RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); pAd->BulkOutPending[MGMTPIPEIDX] = FALSE; pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 0; pMLMEContext->IRPPending = FALSE; pMLMEContext->bWaitingBulkOut = TRUE; RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); return; } //DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacket \n"));// printk("<---RTUSBBulkOutMLMEPacket,Cpu=%d!, Dma=%d, SwIdx=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);}VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs){ PTX_CONTEXT pMLMEContext; PRTMP_ADAPTER pAd; NTSTATUS Status; POS_COOKIE pObj; int index; //DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacketComplete\n")); pMLMEContext = (PTX_CONTEXT)pUrb->context; pAd = pMLMEContext->pAd; pObj = (POS_COOKIE)pAd->OS_Cookie; Status = pUrb->status; index = pMLMEContext->SelfIdx; pObj->mgmt_dma_done_task.data = (unsigned long)pUrb; tasklet_hi_schedule(&pObj->mgmt_dma_done_task);}/* ======================================================================== 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; unsigned long IrqFlags; RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags); if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) { RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); return; } pAd->BulkOutPending[0] = TRUE; pAd->watchDogTxPendingCnt[0] = 1; pPsPollContext->IRPPending = TRUE; RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); // Clear PS-Poll bulk flag RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);#ifdef RT_BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR)pPsPollContext->TransferBuffer, TYPE_TXINFO);#endif // RT_BIG_ENDIAN // // Init Tx context descriptor RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutPsPollComplete); pUrb = pPsPollContext->pUrb; if((ret = RTUSB_SUBMIT_URB(pUrb))!=0) { RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags); pAd->BulkOutPending[0] = FALSE; pAd->watchDogTxPendingCnt[0] = 0; pPsPollContext->IRPPending = FALSE; RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags); DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n", ret)); return; } }// PS-Poll frame use BulkOutPipeId = 0VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb,struct pt_regs *pt_regs){ PRTMP_ADAPTER pAd; PTX_CONTEXT pPsPollContext; NTSTATUS Status; POS_COOKIE pObj; pPsPollContext= (PTX_CONTEXT)pUrb->context; pAd = pPsPollContext->pAd; Status = pUrb->status; pObj = (POS_COOKIE) pAd->OS_Cookie; pObj->pspoll_frame_complete_task.data = (unsigned long)pUrb; tasklet_hi_schedule(&pObj->pspoll_frame_complete_task);}VOID DoBulkIn(IN RTMP_ADAPTER *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); return; } pRxContext->InUse = TRUE; pRxContext->IRPPending = TRUE; pAd->PendingRx++; pAd->BulkInReq++; RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); // Init Rx context descriptor NdisZeroMemory(pRxContext->TransferBuffer, pRxContext->BulkInOffset); 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, ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret)); } else { // success ASSERT((pRxContext->InUse == pRxContext->IRPPending)); //printk("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex); }}/* ======================================================================== 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. Arguments:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?