📄 cmm_data_usb.c
字号:
RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); pHTTXContext->CurWritePosition += pTxBlk->Priv; if (bTxQLastRound) pHTTXContext->CurWritePosition = 8; pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; pHTTXContext->bCurWriting = FALSE; } RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); // succeed and release the skb buffer RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS); return(Status);}USHORT RtmpUSB_WriteMultiTxResource( IN PRTMP_ADAPTER pAd, IN TX_BLK *pTxBlk, IN UCHAR frameNum, OUT USHORT *FreeNumber){ HT_TX_CONTEXT *pHTTXContext; USHORT hwHdrLen; // The hwHdrLen consist of 802.11 header length plus the header padding length. UINT32 fillOffset; TXINFO_STRUC *pTxInfo; TXWI_STRUC *pTxWI; PUCHAR pWirelessPacket = NULL; UCHAR QueIdx; NDIS_STATUS Status; unsigned long IrqFlags; //UINT32 USBDMApktLen = 0, DMAHdrLen, padding; // // get Tx Ring Resource & Dma Buffer address // QueIdx = pTxBlk->QueIdx; pHTTXContext = &pAd->TxContext[QueIdx]; RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); if(frameNum == 0) { // Check if we have enough space for this bulk-out batch. Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext); if (Status == NDIS_STATUS_SUCCESS) { pHTTXContext->bCurWriting = TRUE; pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]); pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]); // Reserve space for 8 bytes padding. if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition)) { pHTTXContext->CurWritePosition += 8; pHTTXContext->ENextBulkOutPosition += 8; } fillOffset = pHTTXContext->CurWritePosition; pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]; // // Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer // if (pTxBlk->TxFrameType == TX_AMSDU_FRAME) //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD; hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD; else if (pTxBlk->TxFrameType == TX_RALINK_FRAME) //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD; hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen + LENGTH_ARALINK_HEADER_FIELD; else //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; // Update the pTxBlk->Priv. pTxBlk->Priv = TXINFO_SIZE + TXWI_SIZE + hwHdrLen; // pTxInfo->USBDMApktLen now just a temp value and will to correct latter. RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(pTxBlk->Priv), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE); // Copy it. NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->Priv); #ifdef RT_BIG_ENDIAN RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket+ TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);#endif // RT_BIG_ENDIAN // pHTTXContext->CurWriteRealPos += pTxBlk->Priv; pWirelessPacket += pTxBlk->Priv; } } else { // For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer. Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE); if (Status == NDIS_STATUS_SUCCESS) { fillOffset = (pHTTXContext->CurWritePosition + pTxBlk->Priv); pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]; //hwHdrLen = pTxBlk->MpduHeaderLen; NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->MpduHeaderLen); pWirelessPacket += (pTxBlk->MpduHeaderLen); pTxBlk->Priv += pTxBlk->MpduHeaderLen; } else { // It should not happened now unless we are going to shutdown. DBGPRINT(RT_DEBUG_ERROR, ("WriteMultiTxResource():bCurWriting is FALSE when handle sub-sequent frames.\n")); Status = NDIS_STATUS_FAILURE; } } // We unlock it here to prevent the first 8 bytes maybe over-write issue. // 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxContext. // 2. An interrupt break our routine and handle bulk-out complete. // 3. In the bulk-out compllete, it need to do another bulk-out, // if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition, // but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE. // 4. Interrupt complete. // 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext. // 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition. // and the packet will wrong. RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_ERROR,("WriteMultiTxResource: CWPos = %ld, NBOutPos = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition)); goto done; } // Copy the frame content into DMA buffer and update the pTxBlk->Priv NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen); pWirelessPacket += pTxBlk->SrcBufLen; pTxBlk->Priv += pTxBlk->SrcBufLen;done: // Release the skb buffer here RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS); return(Status);}VOID RtmpUSB_FinalWriteTxResource( IN PRTMP_ADAPTER pAd, IN TX_BLK *pTxBlk, IN USHORT totalMPDUSize, IN USHORT TxIdx){ UCHAR QueIdx; HT_TX_CONTEXT *pHTTXContext; UINT32 fillOffset; TXINFO_STRUC *pTxInfo; TXWI_STRUC *pTxWI; UINT32 USBDMApktLen, padding; unsigned long IrqFlags; PUCHAR pWirelessPacket; QueIdx = pTxBlk->QueIdx; pHTTXContext = &pAd->TxContext[QueIdx]; RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); if (pHTTXContext->bCurWriting == TRUE) { fillOffset = pHTTXContext->CurWritePosition; if (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition)) && (pHTTXContext->bCopySavePad == TRUE)) pWirelessPacket = (PUCHAR)(&pHTTXContext->SavedPad[0]); else pWirelessPacket = (PUCHAR)(&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]); // // Update TxInfo->USBDMApktLen , // the length = TXWI_SIZE + 802.11_hdr + 802.11_hdr_pad + payload_of_all_batch_frames + Bulk-Out-padding // pTxInfo = (PTXINFO_STRUC)(pWirelessPacket); // Calculate the bulk-out padding USBDMApktLen = pTxBlk->Priv - TXINFO_SIZE; padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment USBDMApktLen += padding; pTxInfo->USBDMATxPktLen = USBDMApktLen; // // Update TXWI->MPDUtotalByteCount , // the length = 802.11 header + payload_of_all_batch_frames pTxWI= (PTXWI_STRUC)(pWirelessPacket + TXINFO_SIZE); pTxWI->MPDUtotalByteCount = totalMPDUSize; // // Update the pHTTXContext->CurWritePosition // pHTTXContext->CurWritePosition += (TXINFO_SIZE + USBDMApktLen); if ((pHTTXContext->CurWritePosition + 3906)> MAX_TXBULK_LIMIT) { // Add 3906 for prevent the NextBulkOut packet size is a A-RALINK/A-MSDU Frame. pHTTXContext->CurWritePosition = 8; pTxInfo->SwUseLastRound = 1; } pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; // // Zero the last padding. // pWirelessPacket = (&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset + pTxBlk->Priv]); NdisZeroMemory(pWirelessPacket, padding + 8); // Finally, set bCurWriting as FALSE pHTTXContext->bCurWriting = FALSE; } else { // It should not happened now unless we are going to shutdown. DBGPRINT(RT_DEBUG_ERROR, ("FinalWriteTxResource():bCurWriting is FALSE when handle last frames.\n")); } RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);}VOID RtmpUSBDataLastTxIdx( IN PRTMP_ADAPTER pAd, IN UCHAR QueIdx, IN USHORT TxIdx){ // DO nothing for USB.}/* When can do bulk-out: 1. TxSwFreeIdx < TX_RING_SIZE; It means has at least one Ring entity is ready for bulk-out, kick it out. 2. If TxSwFreeIdx == TX_RING_SIZE Check if the CurWriting flag is FALSE, if it's FALSE, we can do kick out.*/VOID RtmpUSBDataKickOut( IN PRTMP_ADAPTER pAd, IN TX_BLK *pTxBlk, IN UCHAR QueIdx){ RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx)); RTUSBKickBulkOut(pAd);}/* Must be run in Interrupt context This function handle RT2870 specific TxDesc and cpu index update and kick the packet out. */int RtmpUSBMgmtKickOut( IN RTMP_ADAPTER *pAd, IN UCHAR QueIdx, IN PNDIS_PACKET pPacket, IN PUCHAR pSrcBufVA, IN UINT SrcBufLen){ PTXINFO_STRUC pTxInfo; ULONG BulkOutSize; UCHAR padLen; PUCHAR pDest; ULONG SwIdx = pAd->MgmtRing.TxCpuIdx; PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[SwIdx].AllocVa; unsigned long IrqFlags; pTxInfo = (PTXINFO_STRUC)(pSrcBufVA); // Build our URB for USBD BulkOutSize = SrcBufLen; BulkOutSize = (BulkOutSize + 3) & (~3); RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(BulkOutSize - TXINFO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE); BulkOutSize += 4; // Always add 4 extra bytes at every packet. // If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again. if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0) BulkOutSize += 4; padLen = BulkOutSize - SrcBufLen; ASSERT((padLen <= RTMP_PKT_TAIL_PADDING)); // Now memzero all extra padding bytes. pDest = (PUCHAR)(pSrcBufVA + SrcBufLen); skb_put(GET_OS_PKT_TYPE(pPacket), padLen); NdisZeroMemory(pDest, padLen); RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags); pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket; pMLMEContext->TransferBuffer = (PTX_BUFFER)(GET_OS_PKT_DATAPTR(pPacket)); // Length in TxInfo should be 8 less than bulkout size. pMLMEContext->BulkOutSize = BulkOutSize; pMLMEContext->InUse = TRUE; pMLMEContext->bWaitingBulkOut = TRUE; //for debug //hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize)); //pAd->RalinkCounters.KickTxCount++; //pAd->RalinkCounters.OneSecTxDoneCount++; //if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE) // needKickOut = TRUE; // Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX pAd->MgmtRing.TxSwFreeIdx--; INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE); RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags); RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); //if (needKickOut) RTUSBKickBulkOut(pAd);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -