/* ========================================================================== Description: Setup Frame format. NOTE: This routine should only be used in ATE mode. ========================================================================== */ INT ATESetUpFrame( IN PRTMP_ADAPTER pAd, IN UINT32 TxIdx) { PATE_INFO pATEInfo = &(pAd->ate); UINT pos = 0; PTXD_STRUC pTxD; #ifdef RT_BIG_ENDIAN PTXD_STRUC pDestTxD; TXD_STRUC TxD; #endif PNDIS_PACKET pPacket=NULL; PUCHAR pDest=NULL; PVOID AllocVa=NULL; NDIS_PHYSICAL_ADDRESS AllocPa; HTTRANSMIT_SETTING TxHTPhyMode; PRTMP_TX_RING pTxRing = &pAd->TxRing[QID_AC_BE]; PTXWI_STRUC pTxWI = (PTXWI_STRUC) pTxRing->Cell[TxIdx].DmaBuf.AllocVa; PUCHAR pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa; UINT8 TXWISize = pAd->chipCap.TXWISize; #ifdef RALINK_QA PHEADER_802_11 pHeader80211; #endif /* RALINK_QA */ /* fill TxWI */ TxHTPhyMode.field.BW = pATEInfo->TxWI.BW; TxHTPhyMode.field.ShortGI = pATEInfo->TxWI.ShortGI; TxHTPhyMode.field.STBC = pATEInfo->TxWI.STBC; TxHTPhyMode.field.MCS = pATEInfo->TxWI.MCS; TxHTPhyMode.field.MODE = pATEInfo->TxWI.PHYMODE; if (pATEInfo->bQATxStart == TRUE) { /* always use QID_AC_BE and FIFO_EDCA */ ATEWriteTxWI(pAd, pTxWI, pATEInfo->TxWI.FRAG, pATEInfo->TxWI.CFACK, pATEInfo->TxWI.TS, pATEInfo->TxWI.AMPDU, pATEInfo->TxWI.ACK, pATEInfo->TxWI.NSEQ, pATEInfo->TxWI.BAWinSize, 0, pATEInfo->TxWI.MPDUtotalByteCount, pATEInfo->TxWI.PacketId, 0, 0, pATEInfo->TxWI.txop/*IFS_HTTXOP*/, pATEInfo->TxWI.CFACK/*FALSE*/, &TxHTPhyMode); } else { ATEWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 4, 0, pATEInfo->TxLength, 0, 0, 0, IFS_HTTXOP, FALSE, &TxHTPhyMode); } /* fill 802.11 header */ #ifdef RALINK_QA if (pATEInfo->bQATxStart == TRUE) { NdisMoveMemory(pDMAHeaderBufVA + TXWISize, pATEInfo->Header, pATEInfo->HLen); } else #endif /* RALINK_QA */ { pATEInfo->HLen = LENGTH_802_11; NdisMoveMemory(pDMAHeaderBufVA + TXWISize, TemplateFrame, pATEInfo->HLen); NdisMoveMemory(pDMAHeaderBufVA + TXWISize + 4, pATEInfo->Addr1, ETH_LENGTH_OF_ADDRESS); NdisMoveMemory(pDMAHeaderBufVA + TXWISize + 10, pATEInfo->Addr2, ETH_LENGTH_OF_ADDRESS); NdisMoveMemory(pDMAHeaderBufVA + TXWISize + 16, pATEInfo->Addr3, ETH_LENGTH_OF_ADDRESS); } #ifdef RT_BIG_ENDIAN RTMPFrameEndianChange(pAd, (((PUCHAR)pDMAHeaderBufVA) + TXWISize), DIR_READ, FALSE); #endif /* RT_BIG_ENDIAN */ /* alloc buffer for payload */ #ifdef RALINK_QA if ((pATEInfo->bQATxStart == TRUE) && (pATEInfo->DLen != 0)) { pPacket = RTMP_AllocateRxPacketBuffer(pAd, ((POS_COOKIE)(pAd->OS_Cookie))->pci_dev, pATEInfo->DLen + 0x100, FALSE, &AllocVa, &AllocPa); } else #endif /* RALINK_QA */ { pPacket = RTMP_AllocateRxPacketBuffer(pAd, ((POS_COOKIE)(pAd->OS_Cookie))->pci_dev, pATEInfo->TxLength, FALSE, &AllocVa, &AllocPa); } if (pPacket == NULL) { pATEInfo->TxCount = 0; DBGPRINT_ERR(("%s : fail to alloc packet space.\n", __FUNCTION__)); return -1; } pTxRing->Cell[TxIdx].pNextNdisPacket = pPacket; pDest = (PUCHAR) AllocVa; #ifdef RALINK_QA if ((pATEInfo->bQATxStart == TRUE) && (pATEInfo->DLen != 0)) { GET_OS_PKT_LEN(pPacket) = pATEInfo->DLen; GET_OS_PKT_TOTAL_LEN(pPacket) = pATEInfo->DLen; } else #endif /* RALINK_QA */ { GET_OS_PKT_LEN(pPacket) = pATEInfo->TxLength - LENGTH_802_11; GET_OS_PKT_TOTAL_LEN(pPacket) = pATEInfo->TxLength - LENGTH_802_11; } /* prepare frame payload */ #ifdef RALINK_QA if ((pATEInfo->bQATxStart == TRUE) && (pATEInfo->DLen != 0)) { /* copy pattern to payload */ if ((pATEInfo->PLen != 0)) { for (pos = 0; pos < pATEInfo->DLen; pos += pATEInfo->PLen) { memcpy(GET_OS_PKT_DATAPTR(pPacket) + pos, pATEInfo->Pattern, pATEInfo->PLen); } } } else #endif /* RALINK_QA */ { for (pos = 0; pos < GET_OS_PKT_LEN(pPacket); pos++) { /* default payload is 0xA5 */ pDest[pos] = pATEInfo->Payload; } } /* build Tx descriptor */ #ifndef RT_BIG_ENDIAN pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa; #else pDestTxD = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa; TxD = *pDestTxD; pTxD = &TxD; #endif /* !RT_BIG_ENDIAN */ #ifdef RALINK_QA if (pATEInfo->bQATxStart == TRUE) { /* prepare TxD */ NdisZeroMemory(pTxD, TXD_SIZE); RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA); /* build Tx descriptor */ pTxD->SDPtr0 = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa); pTxD->SDLen0 = TXWISize + pATEInfo->HLen; pTxD->SDPtr1 = AllocPa; pTxD->SDLen1 = GET_OS_PKT_LEN(pPacket); pTxD->LastSec0 = (pTxD->SDLen1 == 0) ? 1 : 0; pTxD->LastSec1 = 1; pDest = (PUCHAR)pTxWI; pDest += TXWISize; pHeader80211 = (PHEADER_802_11)pDest; /* modify sequence number... */ if (pATEInfo->TxDoneCount == 0) pATEInfo->seq = pHeader80211->Sequence; else pHeader80211->Sequence = ++pATEInfo->seq; } else #endif /* RALINK_QA */ { NdisZeroMemory(pTxD, TXD_SIZE); RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA); /* build Tx descriptor */ pTxD->SDPtr0 = RTMP_GetPhysicalAddressLow (pTxRing->Cell[TxIdx].DmaBuf.AllocPa); pTxD->SDLen0 = TXWISize + LENGTH_802_11; pTxD->LastSec0 = 0; pTxD->SDPtr1 = AllocPa; pTxD->SDLen1 = GET_OS_PKT_LEN(pPacket); pTxD->LastSec1 = 1; } #ifdef RT_BIG_ENDIAN RTMPWIEndianChange(pAd, (PUCHAR)pTxWI, TYPE_TXWI); RTMPFrameEndianChange(pAd, (((PUCHAR)pDMAHeaderBufVA) + TXWISize), DIR_WRITE, FALSE); RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD); #endif /* RT_BIG_ENDIAN */ 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; }
/* ========================================================================== Description: Setup Frame format. NOTE: This routine should only be used in ATE mode. ========================================================================== */ INT ATESetUpFrame( IN PRTMP_ADAPTER pAd, IN UINT32 TxIdx) { PATE_INFO pATEInfo = &(pAd->ate); UINT pos = 0; TXINFO_STRUC *pTxInfo; TXD_STRUC *pTxD; #ifdef RT_BIG_ENDIAN TXD_STRUC *pDestTxD; UCHAR tx_hw_info[TXD_SIZE]; #endif /* RT_BIG_ENDIAN */ PNDIS_PACKET pPacket=NULL; PUCHAR pDest=NULL; PVOID AllocVa=NULL; NDIS_PHYSICAL_ADDRESS AllocPa; HTTRANSMIT_SETTING TxHTPhyMode; RTMP_TX_RING *pTxRing = &pAd->TxRing[QID_AC_BE]; TXWI_STRUC *pTxWI = (TXWI_STRUC *)pTxRing->Cell[TxIdx].DmaBuf.AllocVa; PUCHAR pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa; UINT8 TXWISize = pAd->chipCap.TXWISize; #ifdef RALINK_QA PHEADER_802_11 pHeader80211; #endif /* RALINK_QA */ UCHAR bw, sgi, stbc, mcs, phy_mode, frag, cfack, ts, ampdu, ack, nseq, bawinsize, pkt_id, txop; USHORT byte_cnt; bw = sgi = stbc = mcs = phy_mode = frag = cfack = ts =0; ampdu = ack = nseq = bawinsize = pkt_id = txop = 0; byte_cnt = 0; #ifdef RLT_MAC if (pAd->chipCap.hif_type == HIF_RLT) { bw = pATEInfo->TxWI.TXWI_N.BW; sgi = pATEInfo->TxWI.TXWI_N.ShortGI; stbc = pATEInfo->TxWI.TXWI_N.STBC; mcs = pATEInfo->TxWI.TXWI_N.MCS; phy_mode = pATEInfo->TxWI.TXWI_N.PHYMODE; frag = pATEInfo->TxWI.TXWI_N.FRAG; cfack = pATEInfo->TxWI.TXWI_N.CFACK, ts = pATEInfo->TxWI.TXWI_N.TS; ampdu = pATEInfo->TxWI.TXWI_N.AMPDU; ack = pATEInfo->TxWI.TXWI_N.ACK; nseq = pATEInfo->TxWI.TXWI_N.NSEQ; bawinsize =pATEInfo->TxWI.TXWI_N.BAWinSize; byte_cnt = pATEInfo->TxWI.TXWI_N.MPDUtotalByteCnt; pkt_id = pATEInfo->TxWI.TXWI_N.TxPktId; txop = pATEInfo->TxWI.TXWI_N.txop; cfack = pATEInfo->TxWI.TXWI_N.CFACK; } #endif /* RLT_MAC */ /* fill TxWI */ TxHTPhyMode.field.BW = bw; TxHTPhyMode.field.ShortGI = sgi; TxHTPhyMode.field.STBC = stbc; TxHTPhyMode.field.MCS = mcs; TxHTPhyMode.field.MODE = phy_mode; if (pATEInfo->bQATxStart == TRUE) { /* always use QID_AC_BE and FIFO_EDCA */ ATEWriteTxWI(pAd, pTxWI, frag, cfack, ts, ampdu, ack, nseq, bawinsize, 0, byte_cnt, pkt_id, 0, 0, txop, cfack, &TxHTPhyMode); #ifdef TXBF_SUPPORT #ifdef RELEASE_EXCLUDE /* It will affect transmit data rate ??? But QA is tested... */ #endif /* RELEASE_EXCLUDE */ #ifdef RLT_MAC if (IS_MT76x0(pAd)) { /* Must copy rsv bits to actual TxWI */ // pTxWI->TXWI_N.rsv = pATEInfo->TxWI.TXWI_N.rsv; pTxWI->TXWI_N.iTxBF = pATEInfo->TxWI.TXWI_N.iTxBF; pTxWI->TXWI_N.Sounding = pATEInfo->TxWI.TXWI_N.Sounding; pTxWI->TXWI_N.eTxBF = pATEInfo->TxWI.TXWI_N.eTxBF; // pTxWI->TXWI_N.Autofallback = pATEInfo->TxWI.TXWI_N.Autofallback; pTxWI->TXWI_N.NDPSndBW = pATEInfo->TxWI.TXWI_N.NDPSndBW; pTxWI->TXWI_N.NDPSndRate = pATEInfo->TxWI.TXWI_N.NDPSndRate; } #endif /* RLT_MAC */ #endif /* TXBF_SUPPORT */ } else { ATEWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 4, 0, pATEInfo->TxLength, 0, 0, 0, IFS_HTTXOP, FALSE, &TxHTPhyMode); } /* fill 802.11 header */ #ifdef RALINK_QA if (pATEInfo->bQATxStart == TRUE) { NdisMoveMemory(pDMAHeaderBufVA + TXWISize, pATEInfo->Header, pATEInfo->HLen); } else #endif /* RALINK_QA */ { pATEInfo->HLen = LENGTH_802_11; #ifdef TXBF_SUPPORT TemplateFrame[0] = 0x08; /* Data */ TemplateFrame[1] = 0x00; if (pATEInfo->bTxBF && pATEInfo->txSoundingMode!=0) { /* QoS Data */ pATEInfo->HLen = 32; TemplateFrame[0] = 0x88; TemplateFrame[1] = 0x80; switch (pATEInfo->txSoundingMode) { case 1: /* Data Sounding */ TemplateFrame[28] = pAd->CommonCfg.ETxBfNoncompress? 0x80: 0xc0; TemplateFrame[29] = 0x00; break; case 2: case 3: /* 2 or 3 Stream NDP */ TemplateFrame[28] = pAd->CommonCfg.ETxBfNoncompress? 0x80: 0xc0; TemplateFrame[29] = 0x01; /* NDP Announce */ break; default: TemplateFrame[28] = TemplateFrame[29] = 0x0; } } #endif /* TXBF_SUPPORT */ NdisMoveMemory(pDMAHeaderBufVA + TXWISize, TemplateFrame, pATEInfo->HLen); NdisMoveMemory(pDMAHeaderBufVA + TXWISize + 4, pATEInfo->Addr1, MAC_ADDR_LEN); NdisMoveMemory(pDMAHeaderBufVA + TXWISize + 10, pATEInfo->Addr2, MAC_ADDR_LEN); NdisMoveMemory(pDMAHeaderBufVA + TXWISize + 16, pATEInfo->Addr3, MAC_ADDR_LEN); } #ifdef RT_BIG_ENDIAN RTMPFrameEndianChange(pAd, (((PUCHAR)pDMAHeaderBufVA) + TXWISize), DIR_READ, FALSE); #endif /* RT_BIG_ENDIAN */ /* alloc buffer for payload */ #ifdef RALINK_QA if ((pATEInfo->bQATxStart == TRUE) && (pATEInfo->DLen != 0)) { pPacket = RTMP_AllocateRxPacketBuffer(pAd, ((POS_COOKIE)(pAd->OS_Cookie))->pci_dev, pATEInfo->DLen + 0x100, FALSE, &AllocVa, &AllocPa); } else #endif /* RALINK_QA */ { pPacket = RTMP_AllocateRxPacketBuffer(pAd, ((POS_COOKIE)(pAd->OS_Cookie))->pci_dev, pATEInfo->TxLength, FALSE, &AllocVa, &AllocPa); } /* error check */ if (pPacket == NULL) { pATEInfo->TxCount = 0; DBGPRINT_ERR(("%s : fail to alloc packet space.\n", __FUNCTION__)); return -1; } pTxRing->Cell[TxIdx].pNdisPacket = pPacket; pDest = (PUCHAR) AllocVa; #ifdef RALINK_QA if ((pATEInfo->bQATxStart == TRUE) && (pATEInfo->DLen != 0)) { GET_OS_PKT_LEN(pPacket) = pATEInfo->DLen; #ifndef LINUX GET_OS_PKT_TOTAL_LEN(pPacket) = pATEInfo->DLen; #endif /* LIMUX */ } else #endif /* RALINK_QA */ { GET_OS_PKT_LEN(pPacket) = pATEInfo->TxLength - pATEInfo->HLen; #ifndef LINUX GET_OS_PKT_TOTAL_LEN(pPacket) = pATEInfo->TxLength - pATEInfo->HLen; #endif /* LINUX */ } /* prepare frame payload */ #ifdef RALINK_QA if ((pATEInfo->bQATxStart == TRUE) && (pATEInfo->DLen != 0)) { /* copy pattern to payload */ if ((pATEInfo->PLen != 0)) { for (pos = 0; pos < pATEInfo->DLen; pos += pATEInfo->PLen) { memcpy(GET_OS_PKT_DATAPTR(pPacket) + pos, pATEInfo->Pattern, pATEInfo->PLen); } } } else #endif /* RALINK_QA */ { for (pos = 0; pos < GET_OS_PKT_LEN(pPacket); pos++) { #ifdef RELEASE_EXCLUDE /* kurtis: 0xAA ATE test EVM will be positive */ #endif /* RELEASE_EXCLUDE */ /* default payload is 0xA5 */ pDest[pos] = pATEInfo->Payload; } } /* build Tx descriptor */ #ifndef RT_BIG_ENDIAN pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa; pTxInfo = (TXINFO_STRUC *)(pTxRing->Cell[TxIdx].AllocVa + sizeof(TXD_STRUC)); #else pDestTxD = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa; NdisMoveMemory(&tx_hw_info[0], (UCHAR *)pDestTxD, TXD_SIZE); pTxD = (TXD_STRUC *)&tx_hw_info[0]; pTxInfo = (TXINFO_STRUC *)(&tx_hw_info[0] + sizeof(TXD_STRUC)); #endif /* !RT_BIG_ENDIAN */ { /* prepare TxD */ TX_BLK txblk; txblk.SrcBufLen = GET_OS_PKT_LEN(pPacket); txblk.pSrcBufData = AllocVa; NdisZeroMemory(pTxD, TXD_SIZE); /* build Tx descriptor */ pTxD->SDPtr0 = RTMP_GetPhysicalAddressLow (pTxRing->Cell[TxIdx].DmaBuf.AllocPa); pTxD->SDLen0 = TXWISize + pATEInfo->HLen; pTxD->LastSec0 = 0; pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, &txblk, 0, 1, RTMP_PCI_DMA_TODEVICE); pTxD->SDLen1 = GET_OS_PKT_LEN(pPacket); pTxD->LastSec1 = 1; ral_write_txd(pAd, pTxD, pTxInfo, FALSE, FIFO_EDCA); } #ifdef RALINK_QA if (pATEInfo->bQATxStart == TRUE) { pDest = (PUCHAR)pTxWI; pDest += TXWISize; pHeader80211 = (PHEADER_802_11)pDest; /* modify sequence number... */ if (pATEInfo->TxDoneCount == 0) pATEInfo->seq = pHeader80211->Sequence; else pHeader80211->Sequence = ++pATEInfo->seq; } #endif /* RALINK_QA */ #ifdef RT_BIG_ENDIAN RTMPWIEndianChange(pAd, (PUCHAR)pTxWI, TYPE_TXWI); RTMPFrameEndianChange(pAd, (((PUCHAR)pDMAHeaderBufVA) + TXWISize), DIR_WRITE, FALSE); RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD); #endif /* RT_BIG_ENDIAN */ return 0; }
/* ========================================================================== Description: Setup Frame format. NOTE: This routine should only be used in ATE mode. ========================================================================== */ INT ATESetUpFrame( IN PRTMP_ADAPTER pAd, IN UINT32 TxIdx) { PATE_INFO pATEInfo = &(pAd->ate); UINT pos = 0; PTXD_STRUC pTxD; #ifdef RT_BIG_ENDIAN PTXD_STRUC pDestTxD; TXD_STRUC TxD; #endif PNDIS_PACKET pPacket=NULL; PUCHAR pDest=NULL; PVOID AllocVa=NULL; NDIS_PHYSICAL_ADDRESS AllocPa; HTTRANSMIT_SETTING TxHTPhyMode; PRTMP_TX_RING pTxRing = &pAd->TxRing[QID_AC_BE]; PTXWI_STRUC pTxWI = (PTXWI_STRUC) pTxRing->Cell[TxIdx].DmaBuf.AllocVa; PUCHAR pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa; UINT8 TXWISize = pAd->chipCap.TXWISize; #ifdef RALINK_QA PHEADER_802_11 pHeader80211; #endif /* RALINK_QA */ /* fill TxWI */ TxHTPhyMode.field.BW = pATEInfo->TxWI.BW; TxHTPhyMode.field.ShortGI = pATEInfo->TxWI.ShortGI; TxHTPhyMode.field.STBC = pATEInfo->TxWI.STBC; TxHTPhyMode.field.MCS = pATEInfo->TxWI.MCS; TxHTPhyMode.field.MODE = pATEInfo->TxWI.PHYMODE; if (pATEInfo->bQATxStart == TRUE) { /* always use QID_AC_BE and FIFO_EDCA */ ATEWriteTxWI(pAd, pTxWI, pATEInfo->TxWI.FRAG, pATEInfo->TxWI.CFACK, pATEInfo->TxWI.TS, pATEInfo->TxWI.AMPDU, pATEInfo->TxWI.ACK, pATEInfo->TxWI.NSEQ, pATEInfo->TxWI.BAWinSize, 0, pATEInfo->TxWI.MPDUtotalByteCount, pATEInfo->TxWI.PacketId, 0, 0, pATEInfo->TxWI.txop/*IFS_HTTXOP*/, pATEInfo->TxWI.CFACK/*FALSE*/, &TxHTPhyMode); #ifdef TXBF_SUPPORT if (IS_RT2883(pAd) || IS_RT3883(pAd)) { /* Must copy rsv bits to actual TxWI */ pTxWI->rsv = pATEInfo->TxWI.rsv; pTxWI->iTxBF = pATEInfo->TxWI.iTxBF; pTxWI->Sounding = pATEInfo->TxWI.Sounding; pTxWI->eTxBF = pATEInfo->TxWI.eTxBF; pTxWI->Autofallback = pATEInfo->TxWI.Autofallback; pTxWI->NDPSndBW = pATEInfo->TxWI.NDPSndBW; pTxWI->NDPSndRate = pATEInfo->TxWI.NDPSndRate; } #endif /* TXBF_SUPPORT */ } else { ATEWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 4, 0, pATEInfo->TxLength, 0, 0, 0, IFS_HTTXOP, FALSE, &TxHTPhyMode); #ifdef TXBF_SUPPORT if (pATEInfo->bTxBF == 1) { if (IS_RT2883(pAd) || IS_RT3883(pAd)) { pTxWI->rsv = 0; pTxWI->iTxBF = pATEInfo->TxWI.iTxBF; pTxWI->Sounding = (pATEInfo->txSoundingMode == 1 ? 1 : 0); pTxWI->eTxBF = pATEInfo->TxWI.eTxBF; pTxWI->Autofallback = pATEInfo->TxWI.Autofallback; pTxWI->NDPSndBW = pATEInfo->TxWI.BW; if (pATEInfo->txSoundingMode == 3) pTxWI->NDPSndRate = 2; else if (pATEInfo->txSoundingMode == 2) pTxWI->NDPSndRate = 1; else pTxWI->NDPSndRate = 0; } } #endif /* TXBF_SUPPORT */ } /* fill 802.11 header */ #ifdef RALINK_QA if (pATEInfo->bQATxStart == TRUE) { NdisMoveMemory(pDMAHeaderBufVA + TXWISize, pATEInfo->Header, pATEInfo->HLen); } else #endif /* RALINK_QA */ { pATEInfo->HLen = LENGTH_802_11; #ifdef TXBF_SUPPORT TemplateFrame[0] = 0x08; /* Data */ TemplateFrame[1] = 0x00; if (pATEInfo->bTxBF && pATEInfo->txSoundingMode!=0) { /* QoS Data */ pATEInfo->HLen = 32; TemplateFrame[0] = 0x88; TemplateFrame[1] = 0x80; switch (pATEInfo->txSoundingMode) { case 1: /* Data Sounding */ TemplateFrame[28] = pAd->CommonCfg.ETxBfNoncompress? 0x80: 0xc0; TemplateFrame[29] = 0x00; break; case 2: case 3: /* 2 or 3 Stream NDP */ TemplateFrame[28] = pAd->CommonCfg.ETxBfNoncompress? 0x80: 0xc0; TemplateFrame[29] = 0x01; /* NDP Announce */ break; default: TemplateFrame[28] = TemplateFrame[29] = 0x0; } } #endif /* TXBF_SUPPORT */ NdisMoveMemory(pDMAHeaderBufVA + TXWISize, TemplateFrame, pATEInfo->HLen); NdisMoveMemory(pDMAHeaderBufVA + TXWISize + 4, pATEInfo->Addr1, ETH_LENGTH_OF_ADDRESS); NdisMoveMemory(pDMAHeaderBufVA + TXWISize + 10, pATEInfo->Addr2, ETH_LENGTH_OF_ADDRESS); NdisMoveMemory(pDMAHeaderBufVA + TXWISize + 16, pATEInfo->Addr3, ETH_LENGTH_OF_ADDRESS); } #ifdef RT_BIG_ENDIAN RTMPFrameEndianChange(pAd, (((PUCHAR)pDMAHeaderBufVA) + TXWISize), DIR_READ, FALSE); #endif /* RT_BIG_ENDIAN */ /* alloc buffer for payload */ #ifdef RALINK_QA if ((pATEInfo->bQATxStart == TRUE) && (pATEInfo->DLen != 0)) { pPacket = RTMP_AllocateRxPacketBuffer(pAd, ((POS_COOKIE)(pAd->OS_Cookie))->pci_dev, pATEInfo->DLen + 0x100, FALSE, &AllocVa, &AllocPa); } else #endif /* RALINK_QA */ { pPacket = RTMP_AllocateRxPacketBuffer(pAd, ((POS_COOKIE)(pAd->OS_Cookie))->pci_dev, pATEInfo->TxLength, FALSE, &AllocVa, &AllocPa); } if (pPacket == NULL) { pATEInfo->TxCount = 0; DBGPRINT_ERR(("%s : fail to alloc packet space.\n", __FUNCTION__)); return -1; } pTxRing->Cell[TxIdx].pNextNdisPacket = pPacket; pDest = (PUCHAR) AllocVa; #ifdef RALINK_QA if ((pATEInfo->bQATxStart == TRUE) && (pATEInfo->DLen != 0)) { GET_OS_PKT_LEN(pPacket) = pATEInfo->DLen; #ifndef LINUX GET_OS_PKT_TOTAL_LEN(pPacket) = pATEInfo->DLen; #endif /* LIMUX */ } else #endif /* RALINK_QA */ { GET_OS_PKT_LEN(pPacket) = pATEInfo->TxLength - LENGTH_802_11; #ifndef LINUX GET_OS_PKT_TOTAL_LEN(pPacket) = pATEInfo->TxLength - LENGTH_802_11; #endif /* LINUX */ } /* prepare frame payload */ #ifdef RALINK_QA if ((pATEInfo->bQATxStart == TRUE) && (pATEInfo->DLen != 0)) { /* copy pattern to payload */ if ((pATEInfo->PLen != 0)) { for (pos = 0; pos < pATEInfo->DLen; pos += pATEInfo->PLen) { memcpy(GET_OS_PKT_DATAPTR(pPacket) + pos, pATEInfo->Pattern, pATEInfo->PLen); } } } else #endif /* RALINK_QA */ { for (pos = 0; pos < GET_OS_PKT_LEN(pPacket); pos++) { /* default payload is 0xA5 */ pDest[pos] = pATEInfo->Payload; } } /* build Tx descriptor */ #ifndef RT_BIG_ENDIAN pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa; #else pDestTxD = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa; TxD = *pDestTxD; pTxD = &TxD; #endif /* !RT_BIG_ENDIAN */ #ifdef RALINK_QA if (pATEInfo->bQATxStart == TRUE) { /* prepare TxD */ NdisZeroMemory(pTxD, TXD_SIZE); RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA); /* build Tx descriptor */ pTxD->SDPtr0 = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa); pTxD->SDLen0 = TXWISize + pATEInfo->HLen; pTxD->SDPtr1 = AllocPa; pTxD->SDLen1 = GET_OS_PKT_LEN(pPacket); pTxD->LastSec0 = (pTxD->SDLen1 == 0) ? 1 : 0; pTxD->LastSec1 = 1; pDest = (PUCHAR)pTxWI; pDest += TXWISize; pHeader80211 = (PHEADER_802_11)pDest; /* modify sequence number... */ if (pATEInfo->TxDoneCount == 0) pATEInfo->seq = pHeader80211->Sequence; else pHeader80211->Sequence = ++pATEInfo->seq; } else #endif /* RALINK_QA */ { NdisZeroMemory(pTxD, TXD_SIZE); RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA); /* build Tx descriptor */ pTxD->SDPtr0 = RTMP_GetPhysicalAddressLow (pTxRing->Cell[TxIdx].DmaBuf.AllocPa); pTxD->SDLen0 = TXWISize + LENGTH_802_11; pTxD->LastSec0 = 0; pTxD->SDPtr1 = AllocPa; pTxD->SDLen1 = GET_OS_PKT_LEN(pPacket); pTxD->LastSec1 = 1; } #ifdef RT_BIG_ENDIAN RTMPWIEndianChange(pAd, (PUCHAR)pTxWI, TYPE_TXWI); RTMPFrameEndianChange(pAd, (((PUCHAR)pDMAHeaderBufVA) + TXWISize), DIR_WRITE, FALSE); RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD); #endif /* RT_BIG_ENDIAN */ return 0; }
INT ATESetUpNDPAFrame( IN PRTMP_ADAPTER pAd, IN UINT32 TxIdx) { PATE_INFO pATEInfo = &(pAd->ate); UINT pos = 0; TXINFO_STRUC *pTxInfo; TXD_STRUC *pTxD; #ifdef RT_BIG_ENDIAN TXD_STRUC *pDestTxD; UCHAR tx_hw_info[TXD_SIZE]; #endif /* RT_BIG_ENDIAN */ PNDIS_PACKET pPacket=NULL; PUCHAR pDest=NULL; PVOID AllocVa=NULL; NDIS_PHYSICAL_ADDRESS AllocPa; HTTRANSMIT_SETTING TxHTPhyMode; UCHAR *buf; VHT_NDPA_FRAME *vht_ndpa; SNDING_STA_INFO *sta_info; RTMP_TX_RING *pTxRing = &pAd->TxRing[QID_AC_BE]; TXWI_STRUC *pTxWI = (TXWI_STRUC *)pTxRing->Cell[TxIdx].DmaBuf.AllocVa; PUCHAR pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa; UINT8 TXWISize = pAd->chipCap.TXWISize; #ifdef RALINK_QA PHEADER_802_11 pHeader80211; #endif /* RALINK_QA */ UCHAR bw, sgi, stbc, mcs, phy_mode, frag, cfack, ts, ampdu, ack, nseq, bawinsize, pkt_id, txop; USHORT byte_cnt; bw = sgi = stbc = mcs = phy_mode = frag = cfack = ts =0; ampdu = ack = nseq = bawinsize = pkt_id = txop = 0; byte_cnt = 0; #ifdef RLT_MAC if (pAd->chipCap.hif_type == HIF_RLT) { bw = pATEInfo->TxWI.TXWI_N.BW; sgi = pATEInfo->TxWI.TXWI_N.ShortGI; stbc = pATEInfo->TxWI.TXWI_N.STBC; mcs = pATEInfo->TxWI.TXWI_N.MCS; phy_mode = pATEInfo->TxWI.TXWI_N.PHYMODE; frag = pATEInfo->TxWI.TXWI_N.FRAG; cfack = pATEInfo->TxWI.TXWI_N.CFACK, ts = pATEInfo->TxWI.TXWI_N.TS; ampdu = pATEInfo->TxWI.TXWI_N.AMPDU; ack = pATEInfo->TxWI.TXWI_N.ACK; nseq = pATEInfo->TxWI.TXWI_N.NSEQ; bawinsize =pATEInfo->TxWI.TXWI_N.BAWinSize; byte_cnt = pATEInfo->TxWI.TXWI_N.MPDUtotalByteCnt; pkt_id = pATEInfo->TxWI.TXWI_N.TxPktId; txop = pATEInfo->TxWI.TXWI_N.txop; cfack = pATEInfo->TxWI.TXWI_N.CFACK; } #endif /* RLT_MAC */ #ifdef RTMP_MAC if (pAd->chipCap.hif_type == HIF_RTMP) { bw = pATEInfo->TxWI.TXWI_O.BW; sgi = pATEInfo->TxWI.TXWI_O.ShortGI; stbc = pATEInfo->TxWI.TXWI_O.STBC; mcs = pATEInfo->TxWI.TXWI_O.MCS; phy_mode = pATEInfo->TxWI.TXWI_O.PHYMODE; frag = pATEInfo->TxWI.TXWI_O.FRAG; cfack = pATEInfo->TxWI.TXWI_O.CFACK, ts = pATEInfo->TxWI.TXWI_O.TS; ampdu = pATEInfo->TxWI.TXWI_O.AMPDU; ack = pATEInfo->TxWI.TXWI_O.ACK; nseq = pATEInfo->TxWI.TXWI_O.NSEQ; bawinsize =pATEInfo->TxWI.TXWI_O.BAWinSize; byte_cnt = pATEInfo->TxWI.TXWI_O.MPDUtotalByteCnt; pkt_id = pATEInfo->TxWI.TXWI_O.PacketId; txop = pATEInfo->TxWI.TXWI_O.txop; cfack = pATEInfo->TxWI.TXWI_O.CFACK; } #endif /* RTMP_MAC */ /* fill TxWI */ TxHTPhyMode.field.BW = bw; TxHTPhyMode.field.ShortGI = sgi; TxHTPhyMode.field.STBC = stbc; TxHTPhyMode.field.MCS = mcs; TxHTPhyMode.field.MODE = phy_mode; if (pATEInfo->bQATxStart == TRUE) { /* always use QID_AC_BE and FIFO_EDCA */ ATEWriteTxWI(pAd, pTxWI, frag, cfack, ts, ampdu, ack, nseq, bawinsize, 0, byte_cnt, pkt_id, 0, 0, txop, cfack, &TxHTPhyMode); #ifdef TXBF_SUPPORT #ifdef RTMP_MAC if (IS_RT2883(pAd) || IS_RT3883(pAd) || IS_RT3593(pAd)) { /* Must copy rsv bits to actual TxWI */ //pTxWI->TXWI_O.rsv = pATEInfo->TxWI.TXWI_O.rsv; pTxWI->TXWI_O.iTxBF = pATEInfo->TxWI.TXWI_O.iTxBF; pTxWI->TXWI_O.Sounding = pATEInfo->TxWI.TXWI_O.Sounding; pTxWI->TXWI_O.eTxBF = pATEInfo->TxWI.TXWI_O.eTxBF; pTxWI->TXWI_O.Autofallback = pATEInfo->TxWI.TXWI_O.Autofallback; pTxWI->TXWI_O.NDPSndBW = pATEInfo->TxWI.TXWI_O.NDPSndBW; pTxWI->TXWI_O.NDPSndRate = pATEInfo->TxWI.TXWI_O.NDPSndRate; } #endif #ifdef RLT_MAC if (IS_MT76x2(pAd)) { /* Must copy rsv bits to actual TxWI */ pTxWI->TXWI_N.Rsv4 = pATEInfo->TxWI.TXWI_N.Rsv4; pTxWI->TXWI_N.iTxBF = pATEInfo->TxWI.TXWI_N.iTxBF; pTxWI->TXWI_N.Sounding = pATEInfo->TxWI.TXWI_N.Sounding; pTxWI->TXWI_N.eTxBF = pATEInfo->TxWI.TXWI_N.eTxBF; //pTxWI->TXWI_N.Autofallback = pATEInfo->TxWI.TXWI_N.Autofallback; pTxWI->TXWI_N.NDPSndBW = pATEInfo->TxWI.TXWI_N.NDPSndBW; pTxWI->TXWI_N.NDPSndRate = pATEInfo->TxWI.TXWI_N.NDPSndRate; pTxWI->TXWI_N.TXBF_PT_SCA = pATEInfo->TxWI.TXWI_N.TXBF_PT_SCA; } #endif #endif /* TXBF_SUPPORT */ } else { ATEWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 4, 0, pATEInfo->TxLength, 0, 0, 0, IFS_HTTXOP, FALSE, &TxHTPhyMode); #ifdef TXBF_SUPPORT if (pATEInfo->bTxBF == 1) { #ifdef RTMP_MAC if (IS_RT2883(pAd) || IS_RT3883(pAd) || IS_RT3593(pAd)) { //pTxWI->TXWI_O.rsv = 0; pTxWI->TXWI_O.iTxBF = pATEInfo->TxWI.TXWI_O.iTxBF; pTxWI->TXWI_O.Sounding = (pATEInfo->txSoundingMode == 1 ? 1 : 0); pTxWI->TXWI_O.eTxBF = pATEInfo->TxWI.TXWI_O.eTxBF; pTxWI->TXWI_O.Autofallback = pATEInfo->TxWI.TXWI_O.Autofallback; pTxWI->TXWI_O.NDPSndBW = pATEInfo->TxWI.TXWI_O.BW; if (pATEInfo->txSoundingMode == 3) pTxWI->TXWI_O.NDPSndRate = 2; else if (pATEInfo->txSoundingMode == 2) pTxWI->TXWI_O.NDPSndRate = 1; else pTxWI->TXWI_O.NDPSndRate = 0; } #endif #ifdef RLT_MAC if (IS_MT76x2(pAd)) { pTxWI->TXWI_N.Rsv4 = 0; pTxWI->TXWI_N.iTxBF = pATEInfo->TxWI.TXWI_N.iTxBF; pTxWI->TXWI_N.Sounding = (pATEInfo->txSoundingMode == 1 ? 1 : 0); pTxWI->TXWI_N.eTxBF = pATEInfo->TxWI.TXWI_N.eTxBF; //pTxWI->TXWI_N.Autofallback = pATEInfo->TxWI.TXWI_N.Autofallback; pTxWI->TXWI_N.NDPSndBW = pATEInfo->TxWI.TXWI_N.BW; if (pATEInfo->txSoundingMode == 3) pTxWI->TXWI_N.NDPSndRate = 2; else if (pATEInfo->txSoundingMode == 2) pTxWI->TXWI_N.NDPSndRate = 1; else pTxWI->TXWI_N.NDPSndRate = 0; pTxWI->TXWI_N.TXBF_PT_SCA = pATEInfo->TxWI.TXWI_N.TXBF_PT_SCA; } #endif } #endif /* TXBF_SUPPORT */ } /* fill 802.11 header */ #ifdef RALINK_QA if (pATEInfo->bQATxStart == TRUE) { NdisMoveMemory(pDMAHeaderBufVA + TXWISize, pATEInfo->Header, pATEInfo->HLen); } else #endif /* RALINK_QA */ { buf = (pDMAHeaderBufVA + TXWISize); vht_ndpa = (VHT_NDPA_FRAME *)buf; pATEInfo->HLen = sizeof(VHT_NDPA_FRAME); vht_ndpa->fc.Type = FC_TYPE_CNTL; vht_ndpa->fc.SubType = SUBTYPE_VHT_NDPA; COPY_MAC_ADDR(vht_ndpa->ra, pATEInfo->Addr1); COPY_MAC_ADDR(vht_ndpa->ta, pATEInfo->Addr3); hex_dump("NDPA Frame",buf,pATEInfo->HLen); /* Currnetly we only support 1 STA for a VHT DNPA */ sta_info = vht_ndpa->sta_info; sta_info->aid12 = 1; sta_info->fb_type = SNDING_FB_SU; sta_info->nc_idx = 0; vht_ndpa->token.token_num = 0; vht_ndpa->duration = 100; } #ifdef RT_BIG_ENDIAN RTMPFrameEndianChange(pAd, (((PUCHAR)pDMAHeaderBufVA) + TXWISize), DIR_READ, FALSE); #endif /* RT_BIG_ENDIAN */ /* alloc buffer for payload */ #ifdef RALINK_QA if ((pATEInfo->bQATxStart == TRUE) && (pATEInfo->DLen != 0)) { pPacket = RTMP_AllocateRxPacketBuffer(pAd, ((POS_COOKIE)(pAd->OS_Cookie))->pci_dev, pATEInfo->DLen + 0x100, FALSE, &AllocVa, &AllocPa); } else #endif /* RALINK_QA */ { pPacket = RTMP_AllocateRxPacketBuffer(pAd, ((POS_COOKIE)(pAd->OS_Cookie))->pci_dev, pATEInfo->TxLength, FALSE, &AllocVa, &AllocPa); } if (pPacket == NULL) { pATEInfo->TxCount = 0; DBGPRINT_ERR(("%s : fail to alloc packet space.\n", __FUNCTION__)); return -1; } pTxRing->Cell[TxIdx].pNextNdisPacket = pPacket; pDest = (PUCHAR) AllocVa; #ifdef RALINK_QA if ((pATEInfo->bQATxStart == TRUE) && (pATEInfo->DLen != 0)) { GET_OS_PKT_LEN(pPacket) = pATEInfo->DLen; #ifndef LINUX GET_OS_PKT_TOTAL_LEN(pPacket) = pATEInfo->DLen; #endif /* LIMUX */ } else #endif /* RALINK_QA */ { GET_OS_PKT_LEN(pPacket) = pATEInfo->TxLength - pATEInfo->HLen; #ifndef LINUX GET_OS_PKT_TOTAL_LEN(pPacket) = pATEInfo->TxLength - pATEInfo->HLen; #endif /* LINUX */ } /* prepare frame payload */ #ifdef RALINK_QA if ((pATEInfo->bQATxStart == TRUE) && (pATEInfo->DLen != 0)) { /* copy pattern to payload */ if ((pATEInfo->PLen != 0)) { for (pos = 0; pos < pATEInfo->DLen; pos += pATEInfo->PLen) { memcpy(GET_OS_PKT_DATAPTR(pPacket) + pos, pATEInfo->Pattern, pATEInfo->PLen); } } } else #endif /* RALINK_QA */ { for (pos = 0; pos < GET_OS_PKT_LEN(pPacket); pos++) { pDest[pos] = 0x00; } } /* build Tx descriptor */ #ifndef RT_BIG_ENDIAN pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa; pTxInfo = (TXINFO_STRUC *)(pTxRing->Cell[TxIdx].AllocVa + sizeof(TXD_STRUC)); #else pDestTxD = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa; NdisMoveMemory(&tx_hw_info[0], (UCHAR *)pDestTxD, TXD_SIZE); pTxD = (TXD_STRUC *)&tx_hw_info[0]; pTxInfo = (TXINFO_STRUC *)(&tx_hw_info[0] + sizeof(TXD_STRUC)); #endif /* !RT_BIG_ENDIAN */ #ifdef RALINK_QA if (pATEInfo->bQATxStart == TRUE) { /* prepare TxD */ NdisZeroMemory(pTxD, TXD_SIZE); /* build Tx descriptor */ pTxD->SDPtr0 = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa); pTxD->SDLen0 = TXWISize + pATEInfo->HLen; pTxD->SDPtr1 = AllocPa; pTxD->SDLen1 = GET_OS_PKT_LEN(pPacket); pTxD->LastSec0 = (pTxD->SDLen1 == 0) ? 1 : 0; pTxD->LastSec1 = 1; ral_write_txd(pAd, pTxD, pTxInfo, FALSE, FIFO_EDCA); pDest = (PUCHAR)pTxWI; pDest += TXWISize; pHeader80211 = (PHEADER_802_11)pDest; /* modify sequence number... */ if (pATEInfo->TxDoneCount == 0) pATEInfo->seq = pHeader80211->Sequence; else pHeader80211->Sequence = ++pATEInfo->seq; } else #endif /* RALINK_QA */ { TX_BLK txblk; txblk.SrcBufLen = GET_OS_PKT_LEN(pPacket); txblk.pSrcBufData = AllocVa; NdisZeroMemory(pTxD, TXD_SIZE); /* build Tx descriptor */ pTxD->SDPtr0 = RTMP_GetPhysicalAddressLow (pTxRing->Cell[TxIdx].DmaBuf.AllocPa); pTxD->SDLen0 = TXWISize + pATEInfo->HLen /* LENGTH_802_11 */; pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, &txblk, 0, 1, RTMP_PCI_DMA_TODEVICE); pTxD->SDLen1 = GET_OS_PKT_LEN(pPacket); pTxD->LastSec0 = (pTxD->SDLen1 == 0) ? 1 : 0; pTxD->LastSec1 = 1; ral_write_txd(pAd, pTxD, pTxInfo, FALSE, FIFO_EDCA); } #ifdef RT_BIG_ENDIAN RTMPWIEndianChange(pAd, (PUCHAR)pTxWI, TYPE_TXWI); RTMPFrameEndianChange(pAd, (((PUCHAR)pDMAHeaderBufVA) + TXWISize), DIR_WRITE, FALSE); RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD); #endif /* RT_BIG_ENDIAN */ return 0; }