/* ======================================================================== Routine Description: Arguments: Return Value: Note: ======================================================================== */ VOID RTUSBBulkOutRTSFrame( IN PRTMP_ADAPTER pAd) { PTX_CONTEXT pRTSContext = &(pAd->RTSContext); PURB pUrb; int ret = 0; unsigned long IrqFlags; UCHAR PipeID=0; if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4)) PipeID= 3; else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3)) PipeID= 2; else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2)) PipeID= 1; else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL)) PipeID= 0; NdisAcquireSpinLock(&pAd->BulkOutLock[PipeID], IrqFlags); if (pAd->BulkOutPending[PipeID] == TRUE) { NdisReleaseSpinLock(&pAd->BulkOutLock[PipeID], IrqFlags); return; } pAd->BulkOutPending[PipeID] = TRUE; NdisReleaseSpinLock(&pAd->BulkOutLock[PipeID], 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, PipeID, 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: 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*/ #ifdef CONFIG_MULTI_CHANNEL if (pAd->Multi_Channel_Enable == TRUE) RTUSBInitTxDesc(pAd, pPsPollContext, 0, (usb_complete_t)RtmpUsbBulkOutPsPollComplete); else #endif /* CONFIG_MULTI_CHANNEL */ RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX, (usb_complete_t)RtmpUsbBulkOutPsPollComplete); 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; } }
/* ======================================================================== 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); DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutNullFrame: IN STOP_TX STATUS %d\n")); 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)RtmpUsbBulkOutNullFrameComplete); 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; } }
/* ======================================================================== 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 = &pAd->MLMEContext[Index]; NdisAcquireSpinLock(&pAd->BulkOutLock[0], IrqFlags); if (pAd->BulkOutPending[0] == TRUE) { NdisReleaseSpinLock(&pAd->BulkOutLock[0], IrqFlags); return; } pAd->BulkOutPending[0] = TRUE; NdisReleaseSpinLock(&pAd->BulkOutLock[0], 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: None Note: ======================================================================== */ VOID ATE_RTUSBBulkOutDataPacket( IN PRTMP_ADAPTER pAd, IN UCHAR BulkOutPipeId) { PTX_CONTEXT pNullContext = &(pAd->NullContext); PURB pUrb; INT ret = 0; ULONG IrqFlags; ASSERT(BulkOutPipeId == 0); /* Build up the frame first. */ BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); if (pAd->BulkOutPending[BulkOutPipeId] == TRUE) { BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } pAd->BulkOutPending[BulkOutPipeId] = TRUE; BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); /* Increase total transmit byte counter. */ pAd->RalinkCounters.OneSecTransmittedByteCount += pNullContext->BulkOutSize; pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize; /* Clear ATE frame bulk out flag. */ RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE); /* Init Tx context descriptor. */ pNullContext->IRPPending = TRUE; RTUSBInitTxDesc(pAd, pNullContext, BulkOutPipeId, (usb_complete_t)RTUSBBulkOutDataPacketComplete); pUrb = pNullContext->pUrb; if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0) { DBGPRINT_ERR(("ATE_RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret)); return; } pAd->BulkOutReq++; return; }
VOID ATE_RTUSBBulkOutDataPacket( IN PRTMP_ADAPTER pAd) { PTX_CONTEXT pNullContext = &(pAd->NullContext); PURB pUrb; int ret = 0; unsigned long IrqFlags; ATE_RTMPSendNullFrame(pAd); DBGPRINT_RAW(RT_DEBUG_INFO, "--->ATE_RTUSBBulkOutDataPacket \n"); NdisAcquireSpinLock(&pAd->BulkOutLock[0], IrqFlags); if (pAd->BulkOutPending[0] == TRUE) { DBGPRINT_RAW(RT_DEBUG_INFO, "--->ATE_RTUSBBulkOutDataPacket BulkOutPending \n"); NdisReleaseSpinLock(&pAd->BulkOutLock[0], IrqFlags); return; } pAd->BulkOutPending[0] = TRUE; NdisReleaseSpinLock(&pAd->BulkOutLock[0], IrqFlags); // Increase Total transmit byte counter pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize; DBGPRINT_RAW(RT_DEBUG_INFO, "--->ATE_RTUSBBulkOutDataPacket \n"); // Clear Null frame bulk flag RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE); // Init Tx context descriptor RTUSBInitTxDesc(pAd, pNullContext, 0, ATE_RTUSBBulkOutDataPacketComplete); 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, "<---ATE_RTUSBBulkOutDataPacket \n"); return; }
/* ======================================================================== Routine Description: Arguments: Return Value: Note: NULL frame use BulkOutPipeId = 0 ======================================================================== */ void RTUSBBulkOutNullFrame(struct rt_rtmp_adapter *pAd) { struct rt_tx_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); /* Init Tx context descriptor */ RTUSBInitTxDesc(pAd, pNullContext, 0, (usb_complete_t) RTUSBBulkOutNullFrameComplete); pUrb = pNullContext->pUrb; ret = RTUSB_SUBMIT_URB(pUrb); if (ret != 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; } }
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); pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize; RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL); 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; } }
/* ======================================================================== Routine Description: Arguments: Return Value: Note: PsPoll use BulkOutPipeId = 0 ======================================================================== */ void RTUSBBulkOutPsPoll(struct rt_rtmp_adapter *pAd) { struct rt_tx_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); /* Init Tx context descriptor */ RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX, (usb_complete_t) RTUSBBulkOutPsPollComplete); pUrb = pPsPollContext->pUrb; ret = RTUSB_SUBMIT_URB(pUrb); if (ret != 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; } }
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); RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL); 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; } }
/* ======================================================================== 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; NdisAcquireSpinLock(&pAd->BulkOutLock[0], IrqFlags); if (pAd->BulkOutPending[0] == TRUE) { NdisReleaseSpinLock(&pAd->BulkOutLock[0], IrqFlags); return; } pAd->BulkOutPending[0] = TRUE; NdisReleaseSpinLock(&pAd->BulkOutLock[0], 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: 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); // Init Tx context descriptor RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutMLMEPacketComplete); //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); 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 RTUSBBulkOutDataPacket( IN PRTMP_ADAPTER pAd, IN UCHAR BulkOutPipeId, IN UCHAR Index) { PHT_TX_CONTEXT pHTTXContext; PURB pUrb; int ret = 0; PTXINFO_STRUC pTxInfo, pLastTxInfo = NULL; PTXWI_STRUC pTxWI; ULONG TmpBulkEndPos, ThisBulkSize; unsigned long IrqFlags = 0, IrqFlags2 = 0; PUCHAR pWirelessPkt, pAppendant; BOOLEAN bTxQLastRound = FALSE; UCHAR allzero[4]= {0x0,0x0,0x0,0x0}; BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) { BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } pAd->BulkOutPending[BulkOutPipeId] = TRUE; if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) ) { pAd->BulkOutPending[BulkOutPipeId] = FALSE; BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pHTTXContext = &(pAd->TxContext[BulkOutPipeId]); BULK_OUT_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition)) { BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pAd->BulkOutPending[BulkOutPipeId] = FALSE; RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)); RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId)); BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)); RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId)); pHTTXContext->NextBulkOutPosition = pHTTXContext->ENextBulkOutPosition; ThisBulkSize = 0; TmpBulkEndPos = pHTTXContext->NextBulkOutPosition; pWirelessPkt = &pHTTXContext->TransferBuffer->field.WirelessPacket[0]; if ((pHTTXContext->bCopySavePad == TRUE)) { if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4)) { DBGPRINT_RAW(RT_DEBUG_ERROR,("e1, allzero : %x %x %x %x %x %x %x %x \n", pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3] ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7])); } NdisMoveMemory(&pWirelessPkt[TmpBulkEndPos], pHTTXContext->SavedPad, 8); pHTTXContext->bCopySavePad = FALSE; if (pAd->bForcePrintTX == TRUE) DBGPRINT(RT_DEBUG_TRACE,("RTUSBBulkOutDataPacket --> COPY PAD. CurWrite = %ld, NextBulk = %ld. ENextBulk = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition)); } do { pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[TmpBulkEndPos]; pTxWI = (PTXWI_STRUC)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE]; if (pAd->bForcePrintTX == TRUE) DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkOutDataPacket AMPDU = %d.\n", pTxWI->AMPDU)); if ((ThisBulkSize != 0) && (pTxWI->PHYMODE == MODE_CCK)) { if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000)) { pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) ) { pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } } else { if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000)) { pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) ) { pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } } if (TmpBulkEndPos == pHTTXContext->CurWritePosition) { pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } if (pTxInfo->QSEL != FIFO_EDCA) { printk("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __func__, pTxInfo->QSEL); printk("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad); hex_dump("Wrong QSel Pkt:", (PUCHAR)&pWirelessPkt[TmpBulkEndPos], (pHTTXContext->CurWritePosition - pHTTXContext->NextBulkOutPosition)); } if (pTxInfo->USBDMATxPktLen <= 8) { BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); DBGPRINT(RT_DEBUG_ERROR ,("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n", pHTTXContext->BulkOutSize, pHTTXContext->bCopySavePad, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->CurWriteRealPos)); { DBGPRINT_RAW(RT_DEBUG_ERROR ,("%x %x %x %x %x %x %x %x \n", pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3] ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7])); } pAd->bForcePrintTX = TRUE; BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pAd->BulkOutPending[BulkOutPipeId] = FALSE; BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } pAd->RalinkCounters.OneSecTransmittedByteCount += pTxWI->MPDUtotalByteCount; pAd->RalinkCounters.TransmittedByteCount += pTxWI->MPDUtotalByteCount; pLastTxInfo = pTxInfo; pTxInfo->QSEL = FIFO_EDCA; ThisBulkSize += (pTxInfo->USBDMATxPktLen+4); TmpBulkEndPos += (pTxInfo->USBDMATxPktLen+4); if (TmpBulkEndPos != pHTTXContext->CurWritePosition) pTxInfo->USBDMANextVLD = 1; if (pTxInfo->SwUseLastRound == 1) { if (pHTTXContext->CurWritePosition == 8) pTxInfo->USBDMANextVLD = 0; pTxInfo->SwUseLastRound = 0; bTxQLastRound = TRUE; pHTTXContext->ENextBulkOutPosition = 8; break; } }while (TRUE); if (pLastTxInfo) { pLastTxInfo->USBDMANextVLD = 0; } 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])); } } 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)); 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); 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++; }
/* ======================================================================== Routine Description: Calls USB_InterfaceStop and frees memory allocated for the URBs calls NdisMDeregisterDevice and frees the memory allocated in VNetInitialize for the Adapter Object Arguments: *pAd the raxx interface data pointer Return Value: None Note: ======================================================================== */ VOID RTMPFreeTxRxRingMemory( IN PRTMP_ADAPTER pAd) { #define LM_URB_FREE(pObj, Context, BufferSize) \ if (NULL != Context->pUrb) { \ RTUSB_UNLINK_URB(Context->pUrb); \ RTUSB_FREE_URB(Context->pUrb); \ Context->pUrb = NULL; } \ if (NULL != Context->TransferBuffer) { \ RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \ Context->TransferBuffer, \ Context->data_dma); \ Context->TransferBuffer = NULL; } UINT i, acidx; PTX_CONTEXT pNullContext = &pAd->NullContext; PTX_CONTEXT pPsPollContext = &pAd->PsPollContext; PTX_CONTEXT pRTSContext = &pAd->RTSContext; // PHT_TX_CONTEXT pHTTXContext; //PRTMP_REORDERBUF pReorderBuf; POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; // RTMP_TX_RING *pTxRing; DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n")); pObj = pObj; // Free all resources for the RECEIVE buffer queue. for(i=0; i<(RX_RING_SIZE); i++) { PRX_CONTEXT pRxContext = &(pAd->RxContext[i]); if (pRxContext) LM_URB_FREE(pObj, pRxContext, MAX_RXBULK_SIZE); } // Free PsPoll frame resource LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER)); // Free NULL frame resource LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER)); // Free RTS frame resource LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER)); // Free beacon frame resource for(i=0; i<BEACON_RING_SIZE; i++) { PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]); if (pBeaconContext) LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER)); } // Free mgmt frame resource for(i = 0; i < MGMT_RING_SIZE; i++) { PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa; //LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER)); if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket) { RTMPFreeNdisPacket(pAd, pAd->MgmtRing.Cell[i].pNdisPacket); pAd->MgmtRing.Cell[i].pNdisPacket = NULL; pMLMEContext->TransferBuffer = NULL; } if (pMLMEContext) { if (NULL != pMLMEContext->pUrb) { RTUSB_UNLINK_URB(pMLMEContext->pUrb); RTUSB_FREE_URB(pMLMEContext->pUrb); pMLMEContext->pUrb = NULL; } } } if (pAd->MgmtDescRing.AllocVa) NdisFreeMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize, 0); // Free Tx frame resource #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) for(acidx=0; acidx<4; acidx++) #endif // CONFIG_STA_SUPPORT // { PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]); if (pHTTXContext) LM_URB_FREE(pObj, pHTTXContext, sizeof(HTTX_BUFFER)); } if (pAd->FragFrame.pFragPacket) RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS); for(i=0; i<6; i++) { NdisFreeSpinLock(&pAd->BulkOutLock[i]); } NdisFreeSpinLock(&pAd->BulkInLock); NdisFreeSpinLock(&pAd->MLMEBulkOutLock); NdisFreeSpinLock(&pAd->CmdQLock); #ifdef RALINK_ATE NdisFreeSpinLock(&pAd->GenericLock); #endif // RALINK_ATE // // Clear all pending bulk-out request flags. RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff); // NdisFreeSpinLock(&pAd->MacTabLock); // for(i=0; i<MAX_LEN_OF_BA_REC_TABLE; i++) // { // NdisFreeSpinLock(&pAd->BATable.BARecEntry[i].RxReRingLock); // } DBGPRINT(RT_DEBUG_ERROR, ("<--- ReleaseAdapter\n")); }
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)) { 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); pAd->RalinkCounters.TransmittedByteCount += pMLMEContext->BulkOutSize; RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutMLMEPacketComplete); pUrb->transfer_dma = 0; pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP); 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; } }
/* ======================================================================== 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; unsigned long IrqFlags; NdisAcquireSpinLock(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); if (pAd->BulkOutPending[BulkOutPipeId] == TRUE) { NdisReleaseSpinLock(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } pAd->BulkOutPending[BulkOutPipeId] = TRUE; NdisReleaseSpinLock(&pAd->BulkOutLock[BulkOutPipeId], 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], IrqFlags); pAd->BulkOutPending[BulkOutPipeId] = FALSE; NdisReleaseSpinLock(&pAd->BulkOutLock[BulkOutPipeId], 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], 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], 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); pAd->TxRingTotalNumber[BulkOutPipeId]--; // sync. to TxCount pTxContext = &(pAd->TxContext[BulkOutPipeId][pAd->NextBulkOutIndex[BulkOutPipeId]]); } NdisAcquireSpinLock(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pAd->BulkOutPending[BulkOutPipeId] = FALSE; NdisReleaseSpinLock(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } // Init Tx context descriptor RTUSBInitTxDesc(pAd, pTxContext, BulkOutPipeId, RTUSBBulkOutDataPacketComplete); pTxContext->IRPPending = TRUE; 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; }
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"); }
/* ======================================================================== 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)RtmpUsbBulkOutMLMEPacketComplete); RTUSB_URB_DMA_MAPPING(pUrb); 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; } }
/* ======================================================================== Routine Description: Arguments: Return Value: Note: NULL frame use BulkOutPipeId = 0 ======================================================================== */ VOID RTUSBBulkOutNullFrame( IN PRTMP_ADAPTER pAd, IN UCHAR BulkOutPipeId) { PTX_CONTEXT pNullContext; PURB pUrb; int ret = 0; unsigned long IrqFlags; if (BulkOutPipeId == EDCA_AC0_PIPE) pNullContext = &pAd->NullContext[0]; else if (BulkOutPipeId == HCCA_PIPE) pNullContext = &pAd->NullContext[1]; else DBGPRINT(RT_DEBUG_ERROR, ("%s: Unknow BulkOut Pipe\n", __FUNCTION__)); RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) { RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } pAd->BulkOutPending[BulkOutPipeId] = TRUE; pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1; pNullContext->IRPPending = TRUE; RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); /* Increase Total transmit byte counter*/ pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize; /* Clear Null frame bulk flag*/ if (BulkOutPipeId == EDCA_AC0_PIPE) RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL); else if (BulkOutPipeId == HCCA_PIPE) RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL_HCCA); else DBGPRINT(RT_DEBUG_ERROR, ("%s: Unknow BulkOut Pipe\n", __FUNCTION__)); #ifdef RT_BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR)pNullContext->TransferBuffer, TYPE_TXINFO); #endif /* RT_BIG_ENDIAN */ /* Init Tx context descriptor*/ /* Init Tx context descriptor*/ if (BulkOutPipeId == EDCA_AC0_PIPE) RTUSBInitTxDesc(pAd, pNullContext, BulkOutPipeId, (usb_complete_t)RtmpUsbBulkOutNullFrameComplete); #if defined(CONFIG_MULTI_CHANNEL) || defined(DOT11Z_TDLS_SUPPORT) else if (BulkOutPipeId == HCCA_PIPE) RTUSBInitTxDesc(pAd, pNullContext, BulkOutPipeId, (usb_complete_t)RtmpUsbBulkOutHCCANullFrameComplete); #endif /* defined(CONFIG_MULTI_CHANNEL) || defined(DOT11Z_TDLS_SUPPORT) */ pUrb = pNullContext->pUrb; if((ret = RTUSB_SUBMIT_URB(pUrb))!=0) { RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pAd->BulkOutPending[BulkOutPipeId] = FALSE; pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0; pNullContext->IRPPending = FALSE; RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n", ret)); return; } }
VOID RTUSBBulkOutDataPacket( IN PRTMP_ADAPTER pAd, IN UCHAR BulkOutPipeId, IN UCHAR Index) { PHT_TX_CONTEXT pHTTXContext; PURB pUrb; int ret = 0; PTXINFO_STRUC pTxInfo, pLastTxInfo = NULL; PTXWI_STRUC pTxWI; ULONG TmpBulkEndPos, ThisBulkSize; unsigned long IrqFlags = 0, IrqFlags2 = 0; PUCHAR pWirelessPkt, pAppendant; #ifdef USB_BULK_BUF_ALIGMENT BOOLEAN bLasAlignmentsectiontRound = FALSE; #else BOOLEAN bTxQLastRound = FALSE; UCHAR allzero[4]= {0x0,0x0,0x0,0x0}; #endif /* USB_BULK_BUF_ALIGMENT */ BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) { BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } pAd->BulkOutPending[BulkOutPipeId] = TRUE; if (((!OPSTATUS_TEST_FLAG(pAd, fOP_AP_STATUS_MEDIA_STATE_CONNECTED)) && ( !OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))) ) { pAd->BulkOutPending[BulkOutPipeId] = FALSE; BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pHTTXContext = &(pAd->TxContext[BulkOutPipeId]); BULK_OUT_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); #ifdef USB_BULK_BUF_ALIGMENT if ( (pHTTXContext->NextBulkIdx != pHTTXContext->CurtBulkIdx) || ((pHTTXContext->CurWriteRealPos > pHTTXContext->CurWritePosition) &&(pHTTXContext->NextBulkIdx == pHTTXContext->CurWriteIdx)) || ((pHTTXContext->CurWriteRealPos == 0) && (pHTTXContext->NextBulkIdx == pHTTXContext->CurWriteIdx)) ) #else if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition)) #endif /* USB_BULK_BUF_ALIGMENT */ /* druing writing. */ { BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pAd->BulkOutPending[BulkOutPipeId] = FALSE; /* 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)); BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } /* 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)); /*DBGPRINT(RT_DEBUG_TRACE,("BulkOut-B:I=0x%lx, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", in_interrupt(), */ /* pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, */ /* pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));*/ pHTTXContext->NextBulkOutPosition = pHTTXContext->ENextBulkOutPosition; ThisBulkSize = 0; TmpBulkEndPos = pHTTXContext->NextBulkOutPosition; #ifdef USB_BULK_BUF_ALIGMENT INT idx; idx = pHTTXContext->NextBulkIdx; pWirelessPkt = &pHTTXContext->TransferBuffer[idx]->field.WirelessPacket[0]; #else pWirelessPkt = &pHTTXContext->TransferBuffer->field.WirelessPacket[0]; #endif /* USB_BULK_BUF_ALIGMENT */ #ifndef USB_BULK_BUF_ALIGMENT if ((pHTTXContext->bCopySavePad == TRUE)) { if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4)) { DBGPRINT_RAW(RT_DEBUG_ERROR,("e1, allzero : %x %x %x %x %x %x %x %x \n", pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3] ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7])); } NdisMoveMemory(&pWirelessPkt[TmpBulkEndPos], pHTTXContext->SavedPad, 8); pHTTXContext->bCopySavePad = FALSE; if (pAd->bForcePrintTX == TRUE) DBGPRINT(RT_DEBUG_TRACE,("RTUSBBulkOutDataPacket --> COPY PAD. CurWrite = %ld, NextBulk = %ld. ENextBulk = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition)); } #endif /* USB_BULK_BUF_ALIGMENT */ do { pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[TmpBulkEndPos]; pTxWI = (PTXWI_STRUC)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE]; if (pAd->bForcePrintTX == TRUE) DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkOutDataPacket AMPDU = %d.\n", pTxWI->AMPDU)); /* add by Iverson, limit BulkOut size to 4k to pass WMM b mode 2T1R test items*/ /*if ((ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/ if ((ThisBulkSize != 0) && (pTxWI->PHYMODE == MODE_CCK)) { #ifdef INF_AMAZON_SE /*Iverson Add for AMAZON USB (RT2070 && RT3070) to pass WMM A2-T4 ~ A2-T10*/ if(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)) { /*Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate*/ if(pTxWI->PacketId == 6) { pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&pAd->BulkOutDataSizeLimit[BulkOutPipeId]) == pAd->BulkOutDataSizeLimit[BulkOutPipeId])) { /*printk("===Bulkout size limit :%d ===\n",MaxBulkOutSize);*/ /*DBGPRINT(RT_DEBUG_TRACE,("b mode BulkOutPipeId %d pAd->BulkOutDataSizeLimit[BulkOutPipeId] %d \n",BulkOutPipeId,pAd->BulkOutDataSizeLimit[BulkOutPipeId]));*/ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } } else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000)) { /* Limit BulkOut size to about 4k bytes.*/ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } #endif /* INF_AMAZON_SE */ #ifndef INF_AMAZON_SE #ifndef USB_BULK_BUF_ALIGMENT if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000)) { /* Limit BulkOut size to about 4k bytes.*/ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } #else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&BULKOUT_SIZE) == BULKOUT_SIZE)) { /* Limit BulkOut size to about 24k bytes.*/ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; /* when bulk size is > 6000, it mean that this is the lasttround at this alignmnet section. */ bLasAlignmentsectiontRound = TRUE; break; } #endif /* USB_BULK_BUF_ALIGMENT */ #endif /* INF_AMAZON_SE */ #ifndef USB_BULK_BUF_ALIGMENT else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/) { /* For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. */ /* For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04.*/ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } #else else if (((pAd->BulkOutMaxPacketSize < 512) && (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&BULKOUT_SIZE) == BULKOUT_SIZE)) )) { /* Limit BulkOut size to about 24k bytes.*/ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; /* when bulk size is > 6000, it mean that this is the lasttround at this alignmnet section. */ bLasAlignmentsectiontRound = TRUE; break; } #endif /* USB_BULK_BUF_ALIGMENT */ } /* end Iverson*/ else { #ifdef USB_BULK_BUF_ALIGMENT if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&BULKOUT_SIZE) == BULKOUT_SIZE)) #else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000)) #endif /* USB_BULK_BUF_ALIGMENT */ { /* Limit BulkOut size to about 24k bytes.*/ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; #ifdef USB_BULK_BUF_ALIGMENT /* when bulk size is > 0x6000, it mean that this is the lasttround at this alignmnet section. */ bLasAlignmentsectiontRound = TRUE; /* printk("data bulk out bLasAlignmentsectiontRound \n");*/ #endif /* USB_BULK_BUF_ALIGMENT */ break; } #ifdef INF_AMAZON_SE else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&pAd->BulkOutDataSizeLimit[BulkOutPipeId]) == pAd->BulkOutDataSizeLimit[BulkOutPipeId])) { /*printk("===Bulkout size limit :%d ===\n",ThisBulkSize);*/ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } #endif /* INF_AMAZON_SE */ #ifndef USB_BULK_BUF_ALIGMENT else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/) { /* For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. */ /* For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04.*/ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } #else else if (((pAd->BulkOutMaxPacketSize < 512) && (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&BULKOUT_SIZE) == BULKOUT_SIZE)) )) { /* Limit BulkOut size to about 24k bytes.*/ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; /* when bulk size is > 6000, it mean that this is the lasttround at this alignmnet section. */ bLasAlignmentsectiontRound = TRUE; break; } #endif /* USB_BULK_BUF_ALIGMENT */ } #ifdef USB_BULK_BUF_ALIGMENT if ((TmpBulkEndPos == pHTTXContext->CurWritePosition) && (pHTTXContext->NextBulkIdx == pHTTXContext->CurWriteIdx)) #else if (TmpBulkEndPos == pHTTXContext->CurWritePosition) #endif /* USB_BULK_BUF_ALIGMENT */ { pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } #if !defined(CONFIG_MULTI_CHANNEL) && !defined(DOT11Z_TDLS_SUPPORT) if (pTxInfo->QSEL != FIFO_EDCA) { DBGPRINT(RT_DEBUG_ERROR, ("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __FUNCTION__, pTxInfo->QSEL)); DBGPRINT(RT_DEBUG_ERROR, ("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad)); hex_dump("Wrong QSel Pkt:", (PUCHAR)&pWirelessPkt[TmpBulkEndPos], (pHTTXContext->CurWritePosition - pHTTXContext->NextBulkOutPosition)); } #endif /* !defined(CONFIG_MULTI_CHANNEL) && !defined(DOT11Z_TDLS_SUPPORT) */ if (pTxInfo->USBDMATxPktLen <= 8) { BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); DBGPRINT(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n", pHTTXContext->BulkOutSize, pHTTXContext->bCopySavePad, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->CurWriteRealPos)); { DBGPRINT_RAW(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("%x %x %x %x %x %x %x %x \n", pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3] ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7])); } pAd->bForcePrintTX = TRUE; BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pAd->BulkOutPending[BulkOutPipeId] = FALSE; BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); /*DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->USBDMATxPktLen=%d!\n", pTxInfo->USBDMATxPktLen));*/ return; } /* Increase Total transmit byte counter*/ pAd->RalinkCounters.OneSecTransmittedByteCount += pTxWI->MPDUtotalByteCount; pAd->RalinkCounters.TransmittedByteCount += pTxWI->MPDUtotalByteCount; pLastTxInfo = pTxInfo; #if !defined(CONFIG_MULTI_CHANNEL) && !defined(DOT11Z_TDLS_SUPPORT) /* Make sure we use EDCA QUEUE. */ pTxInfo->QSEL = FIFO_EDCA; #endif /* !defined(CONFIG_MULTI_CHANNEL) && !defined(DOT11Z_TDLS_SUPPORT) */ ThisBulkSize += (pTxInfo->USBDMATxPktLen+4); TmpBulkEndPos += (pTxInfo->USBDMATxPktLen+4); if (TmpBulkEndPos != pHTTXContext->CurWritePosition) pTxInfo->USBDMANextVLD = 1; #ifdef USB_BULK_BUF_ALIGMENT /* this is for frag packet , because it will finish this section when ((((pHTTXContext->CurWritePosition + 3906)& 0x00007fff) & 0xffff6000) == 0x00006000) */ if (pTxInfo->SwRingUseLastRound == 1) { bLasAlignmentsectiontRound = TRUE; #ifdef RT_BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO); RTMPWIEndianChange(pAd, (PUCHAR)pTxWI, TYPE_TXWI); #endif /* RT_BIG_ENDIAN */ break; } #else if (pTxInfo->SwRingUseLastRound == 1) { if (pHTTXContext->CurWritePosition == 8) pTxInfo->USBDMANextVLD = 0; pTxInfo->SwRingUseLastRound = 0; bTxQLastRound = TRUE; pHTTXContext->ENextBulkOutPosition = 8; #ifdef RT_BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO); RTMPWIEndianChange(pAd, (PUCHAR)pTxWI, TYPE_TXWI); #endif /* RT_BIG_ENDIAN */ break; } #endif /* USB_BULK_BUF_ALIGMENT */ #ifdef RT_BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO); RTMPWIEndianChange(pAd, (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) */ #ifndef USB_BULK_BUF_ALIGMENT 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));*/ } #endif /* USB_BULK_BUF_ALIGMENT */ 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; pHTTXContext->BulkOutSize = ThisBulkSize; #ifdef USB_BULK_BUF_ALIGMENT /* if it is the last alignment section round,that we just need to add nextbulkindex, otherwise we both need to add nextbulkindex and CurWriteIdx (because when alignment section round happened, the CurWriteIdx is added at function writing resource.) */ if(bLasAlignmentsectiontRound == TRUE) { CUR_WRITE_IDX_INC(pHTTXContext->NextBulkIdx, BUF_ALIGMENT_RINGSIZE); pHTTXContext->ENextBulkOutPosition = 0; } else { CUR_WRITE_IDX_INC(pHTTXContext->NextBulkIdx, BUF_ALIGMENT_RINGSIZE); pHTTXContext->ENextBulkOutPosition = 0; CUR_WRITE_IDX_INC(pHTTXContext->CurWriteIdx, BUF_ALIGMENT_RINGSIZE); pHTTXContext->CurWritePosition = 0; } #endif /* USB_BULK_BUF_ALIGMENT */ pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1; BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); /* Init Tx context descriptor*/ RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize, (usb_complete_t)RtmpUsbBulkOutDataPacketComplete); #ifdef USB_BULK_BUF_ALIGMENT pUrb = pHTTXContext->pUrb[pHTTXContext->CurtBulkIdx]; #else pUrb = pHTTXContext->pUrb; #endif /* USB_BULK_BUF_ALIGMENT */ 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 RTUSBBulkOutDataPacket( IN PRTMP_ADAPTER pAd, IN UCHAR BulkOutPipeId, IN UCHAR Index) { PHT_TX_CONTEXT pHTTXContext; PURB pUrb; int ret = 0; PTXINFO_STRUC pTxInfo, pLastTxInfo = NULL; PTXWI_STRUC pTxWI; ULONG TmpBulkEndPos, ThisBulkSize; unsigned long IrqFlags = 0, IrqFlags2 = 0; PUCHAR pWirelessPkt, pAppendant; BOOLEAN bTxQLastRound = FALSE; UCHAR allzero[4]= {0x0,0x0,0x0,0x0}; BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) { BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } pAd->BulkOutPending[BulkOutPipeId] = TRUE; if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) ) { pAd->BulkOutPending[BulkOutPipeId] = FALSE; BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pHTTXContext = &(pAd->TxContext[BulkOutPipeId]); BULK_OUT_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition)) { BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pAd->BulkOutPending[BulkOutPipeId] = FALSE; // 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)); BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } // 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)); //DBGPRINT(RT_DEBUG_TRACE,("BulkOut-B:I=0x%lx, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", in_interrupt(), // pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, // pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad)); pHTTXContext->NextBulkOutPosition = pHTTXContext->ENextBulkOutPosition; ThisBulkSize = 0; TmpBulkEndPos = pHTTXContext->NextBulkOutPosition; pWirelessPkt = &pHTTXContext->TransferBuffer->field.WirelessPacket[0]; if ((pHTTXContext->bCopySavePad == TRUE)) { if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4)) { DBGPRINT_RAW(RT_DEBUG_ERROR,("e1, allzero : %x %x %x %x %x %x %x %x \n", pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3] ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7])); } NdisMoveMemory(&pWirelessPkt[TmpBulkEndPos], pHTTXContext->SavedPad, 8); pHTTXContext->bCopySavePad = FALSE; if (pAd->bForcePrintTX == TRUE) DBGPRINT(RT_DEBUG_TRACE,("RTUSBBulkOutDataPacket --> COPY PAD. CurWrite = %ld, NextBulk = %ld. ENextBulk = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition)); } do { pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[TmpBulkEndPos]; pTxWI = (PTXWI_STRUC)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE]; if (pAd->bForcePrintTX == TRUE) DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkOutDataPacket AMPDU = %d.\n", pTxWI->AMPDU)); // add by Iverson, limit BulkOut size to 4k to pass WMM b mode 2T1R test items //if ((ThisBulkSize != 0) && (pTxWI->AMPDU == 0)) if ((ThisBulkSize != 0) && (pTxWI->PHYMODE == MODE_CCK)) { if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000)) { // Limit BulkOut size to about 4k bytes. pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/) { // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. // For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04. pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } } // end Iverson else { if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000)) { // Limit BulkOut size to about 24k bytes. pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/) { // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. // For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04. pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } } if (TmpBulkEndPos == pHTTXContext->CurWritePosition) { pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA) if (pTxInfo->QSEL != FIFO_EDCA) { printk("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __func__, pTxInfo->QSEL); printk("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad); hex_dump("Wrong QSel Pkt:", (PUCHAR)&pWirelessPkt[TmpBulkEndPos], (pHTTXContext->CurWritePosition - pHTTXContext->NextBulkOutPosition)); } if (pTxInfo->USBDMATxPktLen <= 8) { BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); DBGPRINT(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n", pHTTXContext->BulkOutSize, pHTTXContext->bCopySavePad, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->CurWriteRealPos)); { DBGPRINT_RAW(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("%x %x %x %x %x %x %x %x \n", pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3] ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7])); } pAd->bForcePrintTX = TRUE; BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pAd->BulkOutPending[BulkOutPipeId] = FALSE; BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); //DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->USBDMATxPktLen=%d!\n", pTxInfo->USBDMATxPktLen)); return; } // Increase Total transmit byte counter pAd->RalinkCounters.OneSecTransmittedByteCount += pTxWI->MPDUtotalByteCount; pAd->RalinkCounters.TransmittedByteCount += pTxWI->MPDUtotalByteCount; pLastTxInfo = pTxInfo; // Make sure we use EDCA QUEUE. pTxInfo->QSEL = FIFO_EDCA; //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA) ThisBulkSize += (pTxInfo->USBDMATxPktLen+4); TmpBulkEndPos += (pTxInfo->USBDMATxPktLen+4); if (TmpBulkEndPos != pHTTXContext->CurWritePosition) pTxInfo->USBDMANextVLD = 1; if (pTxInfo->SwUseLastRound == 1) { if (pHTTXContext->CurWritePosition == 8) pTxInfo->USBDMANextVLD = 0; pTxInfo->SwUseLastRound = 0; bTxQLastRound = TRUE; pHTTXContext->ENextBulkOutPosition = 8; break; } }while (TRUE); // adjust the pTxInfo->USBDMANextVLD value of last pTxInfo. if (pLastTxInfo) { pLastTxInfo->USBDMANextVLD = 0; } /* 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++; }