/* 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 UCHAR *pSrcBufVA, IN UINT SrcBufLen) { TXINFO_STRUC *pTxInfo; ULONG BulkOutSize; UCHAR padLen; PUCHAR pDest; ULONG SwIdx = pAd->MgmtRing.TxCpuIdx; TX_CONTEXT *pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[SwIdx].AllocVa; ULONG IrqFlags; pTxInfo = (TXINFO_STRUC *)(pSrcBufVA); /* Build our URB for USBD*/ BulkOutSize = (SrcBufLen + 3) & (~3); rlt_usb_write_txinfo(pAd, pTxInfo, (USHORT)(BulkOutSize - TXINFO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE); BulkOutSize += 4; /* Always add 4 extra bytes at every packet.*/ //+++Add by shiang for debug if (0) { DBGPRINT(RT_DEBUG_OFF, ("-->%s():shiang-6590, QueIdx=%d, SrcBufLen=%d\n", __FUNCTION__, QueIdx, SrcBufLen)); dump_txinfo(pAd, pTxInfo); dumpTxWI(pAd, (TXWI_STRUC *)(pSrcBufVA + TXINFO_SIZE)); } //---Add by shiang for debug /* WY , it cause Tx hang on Amazon_SE , Max said the padding is useless*/ /* 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); OS_PKT_TAIL_BUF_EXTEND(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; #ifdef UAPSD_SUPPORT /* If the packet is QoS Null frame, we mark the packet with its WCID; If not, we mark the packet with bc/mc WCID = 0. We will handle it in rtusb_mgmt_dma_done_tasklet(). Even AP send a QoS Null frame but not EOSP frame in USB mode, then we will call UAPSD_SP_Close() and we will check pEntry->bAPSDFlagSPStart() so do not worry about it. */ #endif /* UAPSD_SUPPORT */ /*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); return 0; }
INT ATESetUpFrame( IN PRTMP_ADAPTER pAd, IN UINT32 TxIdx) { PATE_INFO pATEInfo = &(pAd->ate); UINT pos = 0; PTX_CONTEXT pNullContext; PUCHAR pDest; HTTRANSMIT_SETTING TxHTPhyMode; TXWI_STRUC *pTxWI; TXINFO_STRUC *pTxInfo; UINT32 TransferBufferLength, OrgBufferLength = 0; UCHAR padLen = 0; UINT8 TXWISize = pAd->chipCap.TXWISize; #ifdef RALINK_QA PHEADER_802_11 pHeader80211 = NULL; #endif /* RALINK_QA */ if ((RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) { return -1; } /* We always use QID_AC_BE and FIFO_EDCA in ATE mode. */ pNullContext = &(pAd->NullContext); ASSERT(pNullContext != NULL); if (pNullContext->InUse == FALSE) { /* set the in use bit */ pNullContext->InUse = TRUE; NdisZeroMemory(&(pAd->NullFrame), sizeof(HEADER_802_11)); /* fill 802.11 header */ #ifdef RALINK_QA if (pATEInfo->bQATxStart == TRUE) { pHeader80211 = NdisMoveMemory(&(pAd->NullFrame), pATEInfo->Header, pATEInfo->HLen); } else #endif /* RALINK_QA */ { NdisMoveMemory(&(pAd->NullFrame), TemplateFrame, sizeof(HEADER_802_11)); } #ifdef RT_BIG_ENDIAN RTMPFrameEndianChange(pAd, (PUCHAR)&(pAd->NullFrame), DIR_READ, FALSE); #endif /* RT_BIG_ENDIAN */ #ifdef RALINK_QA if (pATEInfo->bQATxStart == TRUE) { /* modify sequence number... */ if (pATEInfo->TxDoneCount == 0) { pATEInfo->seq = pHeader80211->Sequence; } else { pHeader80211->Sequence = ++pATEInfo->seq; } /* We already got all the address fields from QA GUI. */ } else #endif /* RALINK_QA */ { COPY_MAC_ADDR(pAd->NullFrame.Addr1, pATEInfo->Addr1); COPY_MAC_ADDR(pAd->NullFrame.Addr2, pATEInfo->Addr2); COPY_MAC_ADDR(pAd->NullFrame.Addr3, pATEInfo->Addr3); } RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[0], TX_BUFFER_NORMSIZE); pTxInfo = (TXINFO_STRUC *)&pAd->NullContext.TransferBuffer->field.WirelessPacket[0]; #ifdef RALINK_QA if (pATEInfo->bQATxStart == TRUE) { /* Avoid to exceed the range of WirelessPacket[]. */ ASSERT(pATEInfo->TxInfo.TxInfoPktLen <= (MAX_FRAME_SIZE - 34/* == 2312 */)); NdisMoveMemory(pTxInfo, &(pATEInfo->TxInfo), sizeof(pATEInfo->TxInfo)); } else #endif /* RALINK_QA */ { /* Avoid to exceed the range of WirelessPacket[]. */ ASSERT(pATEInfo->TxLength <= (MAX_FRAME_SIZE - 34/* == 2312 */)); /* pTxInfo->TxInfoPktLen will be updated to include padding later */ ATEWriteTxInfo(pAd, pTxInfo, (USHORT)(TXWISize + pATEInfo->TxLength) , TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE); pTxInfo->TxInfoQSEL = FIFO_EDCA; } pTxWI = (TXWI_STRUC *)&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE]; /* fill TxWI */ if (pATEInfo->bQATxStart == TRUE) { TxHTPhyMode.field.BW = pATEInfo->TxWI.TxWIBW; TxHTPhyMode.field.ShortGI = pATEInfo->TxWI.TxWIShortGI; TxHTPhyMode.field.STBC = pATEInfo->TxWI.TxWISTBC; TxHTPhyMode.field.MCS = pATEInfo->TxWI.TxWIMCS; TxHTPhyMode.field.MODE = pATEInfo->TxWI.TxWIPHYMODE; ATEWriteTxWI(pAd, pTxWI, pATEInfo->TxWI.TxWIFRAG, pATEInfo->TxWI.TxWITS, pATEInfo->TxWI.TxWIAMPDU, pATEInfo->TxWI.TxWIACK, pATEInfo->TxWI.TxWINSEQ, pATEInfo->TxWI.TxWIBAWinSize, BSSID_WCID, pATEInfo->TxWI.TxWIMPDUByteCnt/* include 802.11 header */, pATEInfo->TxWI.TxWIPacketId, 0, pATEInfo->TxWI.TxWITXOP/*IFS_HTTXOP*/, pATEInfo->TxWI.TxWICFACK /*FALSE*/, TxHTPhyMode); } else { TxHTPhyMode.field.BW = pATEInfo->TxWI.TxWIBW; TxHTPhyMode.field.ShortGI = pATEInfo->TxWI.TxWIShortGI; TxHTPhyMode.field.STBC = 0; TxHTPhyMode.field.MCS = pATEInfo->TxWI.TxWIMCS; TxHTPhyMode.field.MODE = pATEInfo->TxWI.TxWIPHYMODE; ATEWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE /* No ack required. */, FALSE, 0, BSSID_WCID, pATEInfo->TxLength, 0, 0, IFS_HTTXOP, FALSE, TxHTPhyMode); } hex_dump("ATE", pAd->NullContext.TransferBuffer->field.WirelessPacket, 24); dump_txinfo(pAd, pTxInfo); dumpTxWI(pAd, pTxWI); RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE + TXWISize], &pAd->NullFrame, sizeof(HEADER_802_11)); pDest = &(pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE + TXWISize + sizeof(HEADER_802_11)]); /* prepare frame payload */ #ifdef RALINK_QA if (pATEInfo->bQATxStart == TRUE) { /* copy the pattern one by one to the frame payload */ if ((pATEInfo->PLen != 0) && (pATEInfo->DLen != 0)) { for (pos = 0; pos < pATEInfo->DLen; pos += pATEInfo->PLen) { RTMPMoveMemory(pDest, pATEInfo->Pattern, pATEInfo->PLen); pDest += pATEInfo->PLen; } } TransferBufferLength = TXINFO_SIZE + TXWISize + pATEInfo->TxWI.TxWIMPDUByteCnt; } else #endif /* RALINK_QA */ { for (pos = 0; pos < (pATEInfo->TxLength - sizeof(HEADER_802_11)); pos++) { /* default payload is 0xA5 */ *pDest = pATEInfo->Payload; pDest += 1; } TransferBufferLength = TXINFO_SIZE + TXWISize + pATEInfo->TxLength; } OrgBufferLength = TransferBufferLength; TransferBufferLength = (TransferBufferLength + 3) & (~3); /* Always add 4 extra bytes at every packet. */ padLen = TransferBufferLength - OrgBufferLength + 4;/* 4 == last packet padding */ /* RTMP_PKT_TAIL_PADDING == 11. [11 == 3(max 4 byte padding) + 4(last packet padding) + 4(MaxBulkOutsize align padding)] */ ASSERT((padLen <= (RTMP_PKT_TAIL_PADDING - 4/* 4 == MaxBulkOutsize alignment padding */))); /* Now memzero all extra padding bytes. */ NdisZeroMemory(pDest, padLen); pDest += padLen; /* Update pTxInfo->TxInfoPktLen to include padding. */ pTxInfo->TxInfoPktLen = TransferBufferLength - TXINFO_SIZE; TransferBufferLength += 4; /* If TransferBufferLength is multiple of 64, add extra 4 bytes again. */ if ((TransferBufferLength % pAd->BulkOutMaxPacketSize) == 0) { NdisZeroMemory(pDest, 4); TransferBufferLength += 4; } /* Fill out frame length information for global Bulk out arbitor. */ pAd->NullContext.BulkOutSize = TransferBufferLength; } #ifdef RT_BIG_ENDIAN RTMPWIEndianChange(pAd, (PUCHAR)pTxWI, TYPE_TXWI); RTMPFrameEndianChange(pAd, (((PUCHAR)pTxInfo) + TXWISize + TXINFO_SIZE), DIR_WRITE, FALSE); RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO); #endif /* RT_BIG_ENDIAN */ hex_dump("ATE TX", &pAd->NullContext.TransferBuffer->field.WirelessPacket[0], TXWISize + TXINFO_SIZE); return 0; }