void RTMP_QueryNextPacketInfo( IN PNDIS_PACKET *ppPacket, OUT PACKET_INFO *pPacketInfo, OUT PUCHAR *pSrcBufVA, OUT UINT *pSrcBufLen) { PNDIS_PACKET pPacket = NULL; if (*ppPacket) pPacket = GET_OS_PKT_NEXT(*ppPacket); if (pPacket) { pPacketInfo->BufferCount = 1; pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket); pPacketInfo->PhysicalBufferCount = 1; pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket); *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket); *pSrcBufLen = GET_OS_PKT_LEN(pPacket); *ppPacket = GET_OS_PKT_NEXT(pPacket); } else { pPacketInfo->BufferCount = 0; pPacketInfo->pFirstBuffer = NULL; pPacketInfo->PhysicalBufferCount = 0; pPacketInfo->TotalPacketLength = 0; *pSrcBufVA = NULL; *pSrcBufLen = 0; *ppPacket = NULL; } }
/* ======================================================================== Routine Description: clone an input NDIS PACKET to another one. The new internally created NDIS PACKET must have only one NDIS BUFFER return - byte copied. 0 means can't create NDIS PACKET NOTE: internally created NDIS_PACKET should be destroyed by RTMPFreeNdisPacket Arguments: pAd Pointer to our adapter pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU. *pSrcTotalLen return total packet length. This lenght is calculated with 802.3 format packet. Return Value: NDIS_STATUS_SUCCESS NDIS_STATUS_FAILURE Note: ======================================================================== */ NDIS_STATUS RTMPCloneNdisPacket( IN PRTMP_ADAPTER pAd, IN BOOLEAN pInsAMSDUHdr, IN PNDIS_PACKET pInPacket, OUT PNDIS_PACKET *ppOutPacket) { struct sk_buff *pkt; ASSERT(pInPacket); ASSERT(ppOutPacket); // 1. Allocate a packet pkt = dev_alloc_skb(2048); if (pkt == NULL) { return NDIS_STATUS_FAILURE; } skb_put(pkt, GET_OS_PKT_LEN(pInPacket)); NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket), GET_OS_PKT_LEN(pInPacket)); *ppOutPacket = OSPKT_TO_RTPKT(pkt); RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS); printk("###Clone###\n"); return NDIS_STATUS_SUCCESS; }
void RTMP_QueryPacketInfo( IN PNDIS_PACKET pPacket, OUT PACKET_INFO *pPacketInfo, OUT PUCHAR *pSrcBufVA, OUT UINT *pSrcBufLen) { pPacketInfo->BufferCount = 1; pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket); pPacketInfo->PhysicalBufferCount = 1; pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket); *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket); *pSrcBufLen = GET_OS_PKT_LEN(pPacket); }
PNDIS_PACKET DuplicatePacket( IN PRTMP_ADAPTER pAd, IN PNDIS_PACKET pPacket, IN UCHAR FromWhichBSSID) { struct sk_buff *skb; PNDIS_PACKET pRetPacket = NULL; USHORT DataSize; UCHAR *pData; DataSize = (USHORT) GET_OS_PKT_LEN(pPacket); pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket); skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG); if (skb) { skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); pRetPacket = OSPKT_TO_RTPKT(skb); } #if 0 if ((skb = __dev_alloc_skb(DataSize + 2+32, MEM_ALLOC_FLAG)) != NULL) { skb_reserve(skb, 2+32); NdisMoveMemory(skb->tail, pData, DataSize); skb_put(skb, DataSize); skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); pRetPacket = OSPKT_TO_RTPKT(skb); } #endif return pRetPacket; }
PRTMP_SCATTER_GATHER_LIST rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg) { sg->NumberOfElements = 1; sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket); sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket); return (sg); }
/* Delayed TCP Ack */ BOOLEAN delay_tcp_ack(RTMP_ADAPTER *pAd, UCHAR wcid, PNDIS_PACKET pPacket) { PUCHAR pSrcBuf; UINT32 pktLen, qlen; PMAC_TABLE_ENTRY pEntry; BOOLEAN bDelay = FALSE; pEntry = &pAd->MacTab.Content[wcid]; pSrcBuf = GET_OS_PKT_DATAPTR(pPacket); pktLen = GET_OS_PKT_LEN(pPacket); if (pAd->CommonCfg.ACKQEN == 1) { /* get Ethernet protocol field*/ USHORT TypeLen = OS_NTOHS(*((UINT16 *)(pSrcBuf + 12))); /* bypass VALN 802.1Q field */ if(TypeLen == 0x8100) pSrcBuf += 4; else if ((TypeLen==0x9100) || (TypeLen==0x9200) || (TypeLen==0x9300)) pSrcBuf += 8; if ((TypeLen == 0x0800) /* Type: IP (0x0800) */ && (pSrcBuf[23] == 0x06) /* Protocol: TCP (0x06) */ && (pktLen >= 48) && ((pSrcBuf[47]&0x10) == 0x10)) /* Flags: Ack bit is set */ { skb_queue_tail(&pEntry->ack_queue, pPacket); qlen = skb_queue_len(&pEntry->ack_queue); bDelay = TRUE; if (qlen == 1) { if (pEntry->QueueAckTimerRunning == FALSE) { DBGPRINT(RT_DEBUG_LOUD, ("found tcp ack..\n")); RTMPSetTimer(&pEntry->QueueAckTimer, pAd->CommonCfg.AckWaitTime); pEntry->QueueAckTimerRunning = TRUE; } } else if ((qlen >= pAd->CommonCfg.Acklen) || ((pSrcBuf[47]&0x03) != 0) /* Flags: FIN(bit0) or SYN(bit1) is set */ || (pktLen > 66)) /* TCP ACK with other payload in IPv4 format */ { pAd->CommonCfg.AckNOTimeout += flush_tcp_ack_queue(pAd, pEntry, TRUE); } } } else { flush_tcp_ack_queue(pAd, pEntry, TRUE); } return bDelay; }
void announce_802_3_packet( IN VOID *pAdSrc, IN PNDIS_PACKET pPacket, IN UCHAR OpMode) { RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)pAdSrc; PNDIS_PACKET pRxPkt = pPacket; ASSERT(pPacket); MEM_DBG_PKT_FREE_INC(pPacket); #ifdef CONFIG_STA_SUPPORT #endif /* CONFIG_STA_SUPPORT */ /* Push up the protocol stack */ #ifdef IKANOS_VX_1X0 { IKANOS_DataFrameRx(pAd, pRxPkt); return; } #endif /* IKANOS_VX_1X0 */ #ifdef INF_PPA_SUPPORT if (ppa_hook_directpath_send_fn && pAd->PPAEnable==TRUE ) { RtmpOsPktInfPpaSend(pRxPkt); pRxPkt=NULL; return; } #endif /* INF_PPA_SUPPORT */ //+++Add by shiang for debug if (0) { hex_dump("announce_802_3_packet", GET_OS_PKT_DATAPTR(pRxPkt), GET_OS_PKT_LEN(pRxPkt)); } //---Add by shiang for debug RtmpOsPktProtocolAssign(pRxPkt); RtmpOsPktRcvHandle(pRxPkt); }
PNDIS_PACKET DuplicatePacket( IN PRTMP_ADAPTER pAd, IN PNDIS_PACKET pPacket, IN UCHAR FromWhichBSSID) { struct sk_buff *skb; PNDIS_PACKET pRetPacket = NULL; USHORT DataSize; UCHAR *pData; DataSize = (USHORT) GET_OS_PKT_LEN(pPacket); pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket); skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG); if (skb) { skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); pRetPacket = OSPKT_TO_RTPKT(skb); } return pRetPacket; }
/* ========================================================================== 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; }
/* ========================================================================== 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; }
/* ======================================================================== Routine Description: Early checking and OS-depened parsing for Tx packet to AP device. Arguments: NDIS_HANDLE MiniportAdapterContext Pointer refer to the device handle, i.e., the pAd. PPNDIS_PACKET ppPacketArray The packet array need to do transmission. UINT NumberOfPackets Number of packet in packet array. Return Value: NONE Note: This function do early checking and classification for send-out packet. You only can put OS-depened & AP related code in here. ======================================================================== */ INT wdev_tx_pkts(NDIS_HANDLE dev_hnd, PPNDIS_PACKET pkt_list, UINT pkt_cnt, struct wifi_dev *wdev) { RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)dev_hnd; PNDIS_PACKET pPacket; BOOLEAN allowToSend; UCHAR wcid = MAX_LEN_OF_MAC_TABLE; UINT Index; #ifdef CONFIG_FPGA_MODE BOOLEAN force_tx; #endif /* CONFIG_FPGA_MODE */ for (Index = 0; Index < pkt_cnt; Index++) { pPacket = pkt_list[Index]; if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))) { /* Drop send request since hardware is in reset state */ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); continue; } #ifdef CONFIG_FPGA_MODE force_tx = FALSE; if (pAd->fpga_ctl.fpga_on & 0x1) { if (pAd->fpga_ctl.tx_kick_cnt > 0) { if (pAd->fpga_ctl.tx_kick_cnt < 0xffff) { pAd->fpga_ctl.tx_kick_cnt--; } force_tx = TRUE; } } #endif /* CONFIG_FPGA_MODE */ if (((wdev->allow_data_tx == TRUE) #ifdef CONFIG_FPGA_MODE || (force_tx == TRUE) #endif /* CONFIG_FPGA_MODE */ ) && (wdev->tx_pkt_allowed)) { allowToSend = wdev->tx_pkt_allowed(pAd, wdev, pPacket, &wcid); } else { allowToSend = FALSE; //RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); } #ifdef CONFIG_FPGA_MODE if (force_tx == TRUE && allowToSend == TRUE) { //int dump_len = GET_OS_PKT_LEN(pPacket); DBGPRINT(RT_DEBUG_INFO, ("%s():send Packet!wcid=%d, wdev_idx=%d, pktLen=%d\n", __FUNCTION__, wcid, wdev->wdev_idx, GET_OS_PKT_LEN(pPacket))); //hex_dump("wdev_tx_pkts():802.3 packet", GET_OS_PKT_DATAPTR(pPacket), dump_len > 255 ? 255 : dump_len); } #endif /* CONFIG_FPGA_MODE */ if (allowToSend == TRUE) { RTMP_SET_PACKET_WCID(pPacket, wcid); RTMP_SET_PACKET_WDEV(pPacket, wdev->wdev_idx); NDIS_SET_PACKET_STATUS(pPacket, NDIS_STATUS_PENDING); pAd->RalinkCounters.PendingNdisPacketCount++; if (wdev->tx_pkt_handle) wdev->tx_pkt_handle(pAd, pPacket); else { DBGPRINT(RT_DEBUG_ERROR, ("%s():tx_pkt_handle not assigned!\n", __FUNCTION__)); RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); } } else RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); } RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, WCID_ALL, MAX_TX_PROCESS); 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; }
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; }