/* ========================================================================== 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; TXINFO_STRUC *pTxInfo; TXD_STRUC *pTxD; #ifdef RT_BIG_ENDIAN TXD_STRUC *pDestTxD; UCHAR tx_hw_info[TXD_SIZE]; // TXD_STRUC TxD; #endif /* RT_BIG_ENDIAN */ 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]; 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 */ /* fill TxWI */ 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; if (pATEInfo->bQATxStart == TRUE) { /* always use QID_AC_BE and FIFO_EDCA */ ATEWriteTxWI(pAd, pTxWI, pATEInfo->TxWI.TxWIFRAG, pATEInfo->TxWI.TxWICFACK, pATEInfo->TxWI.TxWITS, pATEInfo->TxWI.TxWIAMPDU, pATEInfo->TxWI.TxWIACK, pATEInfo->TxWI.TxWINSEQ, pATEInfo->TxWI.TxWIBAWinSize, 0, pATEInfo->TxWI.TxWIMPDUByteCnt, pATEInfo->TxWI.TxWIPacketId, 0, 0, pATEInfo->TxWI.TxWITXOP/*IFS_HTTXOP*/, pATEInfo->TxWI.TxWICFACK/*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.TxWIBW; 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++) { if (IS_MT7610E(pAd)) { /* random payload */ pDest[pos] = RandomByte2(pAd); } else { /* fixed payload */ 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)); // TxD = *pDestTxD; // pTxD = &TxD; #endif /* !RT_BIG_ENDIAN */ // pTxInfo = (TXINFO_STRUC *)(pTxD + 1); #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, NULL, 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 */ { 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, NULL, 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; }
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; }