📄 cmm_data.c
字号:
pHeader80211->Sequence = ++pAd->ate.seq; pTxD->DMADONE = 0; if ((pAd->ate.bQATxStart == TRUE) && (pAd->ate.Mode & ATE_TXFRAME) && (pAd->ate.TxDoneCount < pAd->ate.TxCount)) { pAd->RalinkCounters.TransmittedByteCount += (pTxD->SDLen1 + pTxD->SDLen0); pAd->RalinkCounters.OneSecDmaDoneCount[QueIdx] ++; INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE); /* get tx_tdx_idx again */ RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF , &pTxRing->TxDmaIdx); goto kick_out; } else if (pAd->ate.TxDoneCount == pAd->ate.TxCount) { DBGPRINT(RT_DEBUG_TRACE,("all Tx is done\n")); // Tx status enters idle mode. pAd->ate.TxStatus = 0; } else if (!(pAd->ate.Mode & ATE_TXFRAME)) { DBGPRINT(RT_DEBUG_TRACE,("not complete sending yet, but someone pressed the Stop TX bottom\n")); } else { DBGPRINT(RT_DEBUG_TRACE,("pTxRing->TxSwFreeIdx = %ld\n", pTxRing->TxSwFreeIdx)); } INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE); continue; } }#endif // RALINK_2860_QA //#endif // RALINK_ATE // // static rate also need NICUpdateFifoStaCounters() function. //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) NICUpdateFifoStaCounters(pAd); FREE++; #ifndef BIG_ENDIAN pTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa); pOriTxD = pTxD; NdisMoveMemory(&TxD, pTxD, sizeof(TXD_STRUC)); pTxD = &TxD;#else pDestTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa); pOriTxD = pDestTxD ; TxD = *pDestTxD; pTxD = &TxD; RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);#endif pTxD->DMADONE = 0;#ifdef RALINK_ATE if (pAd->ate.Mode == ATE_STOP)#endif // RALINK_ATE // { pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket; if (pPacket) {#ifdef CONFIG_5VT_ENHANCE if (RTMP_GET_PACKET_5VT(pPacket)) PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, 16, PCI_DMA_TODEVICE); else#endif // CONFIG_5VT_ENHANCE // PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE); RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); } //Always assign pNdisPacket as NULL after clear pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket = NULL; pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket; ASSERT(pPacket == NULL); if (pPacket) {#ifdef CONFIG_5VT_ENHANCE if (RTMP_GET_PACKET_5VT(pPacket)) PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, 16, PCI_DMA_TODEVICE); else#endif // CONFIG_5VT_ENHANCE // PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE); RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); } //Always assign pNextNdisPacket as NULL after clear pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = NULL; } pAd->RalinkCounters.TransmittedByteCount += (pTxD->SDLen1 + pTxD->SDLen0); pAd->RalinkCounters.OneSecDmaDoneCount[QueIdx] ++; INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE); /* get tx_tdx_idx again */ RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF , &pTxRing->TxDmaIdx);#ifndef BIG_ENDIAN NdisMoveMemory(pOriTxD, pTxD, sizeof(TXD_STRUC));#else RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); *pDestTxD = TxD;#endif#ifdef RALINK_ATE#ifdef RALINK_2860_QAkick_out:#endif // RALINK_2860_QA // // // ATE_TXCONT mode also need to send some normal frames, so let it in. // ATE_STOP must be changed not to be 0xff // to prevent it from running into this block. // if ((pAd->ate.Mode & ATE_TXFRAME) && (pAd->ate.QID == QueIdx)) { // TxDoneCount++ has been done if QA is used. if (pAd->ate.bQATxStart == FALSE) { pAd->ate.TxDoneCount++; } if (((pAd->ate.TxCount - pAd->ate.TxDoneCount + 1) >= TX_RING_SIZE)) { INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE); pTxD = (PTXD_STRUC) (pTxRing->Cell[pAd->TxRing[QueIdx].TxCpuIdx].AllocVa); pTxD->DMADONE = 0; // kick Tx-Ring. RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx * RINGREG_DIFF, pAd->TxRing[QueIdx].TxCpuIdx); pAd->RalinkCounters.KickTxCount++; } }#endif // RALINK_ATE //// RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); } DBGPRINT(RT_DEBUG_LOUD, ("RTMPFreeTXDUponTxDmaDone %d.\n", FREE)); return bReschedule;} /* ======================================================================== Routine Description: Calculates the duration which is required to transmit out frames with given size and specified rate. Arguments: pAd Pointer to our adapter Rate Transmit rate Size Frame size in units of byte Return Value: Duration number in units of usec IRQL = PASSIVE_LEVEL IRQL = DISPATCH_LEVEL Note: ========================================================================*/USHORT RTMPCalcDuration( IN PRTMP_ADAPTER pAd, IN UCHAR Rate, IN ULONG Size){ ULONG Duration = 0; if (Rate < RATE_FIRST_OFDM_RATE) // CCK { if ((Rate > RATE_1) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED)) Duration = 96; // 72+24 preamble+plcp else Duration = 192; // 144+48 preamble+plcp Duration += (USHORT)((Size << 4) / RateIdTo500Kbps[Rate]); if ((Size << 4) % RateIdTo500Kbps[Rate]) Duration ++; } else if (Rate <= RATE_LAST_OFDM_RATE)// OFDM rates { Duration = 20 + 6; // 16+4 preamble+plcp + Signal Extension Duration += 4 * (USHORT)((11 + Size * 4) / RateIdTo500Kbps[Rate]); if ((11 + Size * 4) % RateIdTo500Kbps[Rate]) Duration += 4; } else //mimo rate { Duration = 20 + 6; // 16+4 preamble+plcp + Signal Extension } return (USHORT)Duration;}/* ======================================================================== Routine Description: Calculates the duration which is required to transmit out frames with given size and specified rate. Arguments: pTxWI Pointer to head of each MPDU to HW. Ack Setting for Ack requirement bit Fragment Setting for Fragment bit RetryMode Setting for retry mode Ifs Setting for IFS gap Rate Setting for transmit rate Service Setting for service Length Frame length TxPreamble Short or Long preamble when using CCK rates QueIdx - 0-3, according to 802.11e/d4.4 June/2003 Return Value: None IRQL = PASSIVE_LEVEL IRQL = DISPATCH_LEVEL See also : BASmartHardTransmit() !!! ========================================================================*/VOID RTMPWriteTxWI( IN PRTMP_ADAPTER pAd, IN PTXWI_STRUC pOutTxWI, IN BOOLEAN FRAG, IN BOOLEAN CFACK, IN BOOLEAN InsTimestamp, IN BOOLEAN AMPDU, IN BOOLEAN Ack, IN BOOLEAN NSeq, // HW new a sequence. IN UCHAR BASize, IN UCHAR WCID, IN ULONG Length, IN UCHAR PID, IN UCHAR TID, IN UCHAR TxRate, IN UCHAR Txopmode, IN BOOLEAN CfAck, IN HTTRANSMIT_SETTING *pTransmit){ PMAC_TABLE_ENTRY pMac = NULL; TXWI_STRUC TxWI; PTXWI_STRUC pTxWI; if (WCID < MAX_LEN_OF_MAC_TABLE) pMac = &pAd->MacTab.Content[WCID]; // // Always use Long preamble before verifiation short preamble functionality works well. // Todo: remove the following line if short preamble functionality works // OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED); NdisZeroMemory(&TxWI, TXWI_SIZE); pTxWI = &TxWI; pTxWI->FRAG= FRAG; pTxWI->CFACK = CFACK; pTxWI->TS= InsTimestamp; pTxWI->AMPDU = AMPDU; pTxWI->ACK = Ack; pTxWI->txop= Txopmode; pTxWI->NSEQ = NSeq; // John tune the performace with Intel Client in 20 MHz performance BASize = pAd->CommonCfg.TxBASize; if( BASize >7 ) BASize =7; pTxWI->BAWinSize = BASize; pTxWI->WirelessCliID = WCID; pTxWI->MPDUtotalByteCount = Length; pTxWI->PacketId = PID; // If CCK or OFDM, BW must be 20 pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_40) : (pTransmit->field.BW); pTxWI->ShortGI = pTransmit->field.ShortGI; pTxWI->STBC = pTransmit->field.STBC; pTxWI->MCS = pTransmit->field.MCS; pTxWI->PHYMODE = pTransmit->field.MODE; pTxWI->CFACK = CfAck; if (pMac) { if (pAd->CommonCfg.bMIMOPSEnable) { if ((pMac->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7)) { // Dynamic MIMO Power Save Mode pTxWI->MIMOps = 1; } else if (pMac->MmpsMode == MMPS_STATIC) { // Static MIMO Power Save Mode if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7) { pTxWI->MCS = 7; pTxWI->MIMOps = 0; } } } //pTxWI->MIMOps = (pMac->PsMode == PWR_MMPS)? 1:0; pTxWI->MpduDensity = pMac->MpduDensity; } pTxWI->PacketId = pTxWI->MCS; NdisMoveMemory(pOutTxWI, &TxWI, sizeof(TXWI_STRUC));}/* ======================================================================== Routine Description: Calculates the duration which is required to transmit out frames with given size and specified rate. Arguments: pTxD Pointer to transmit descriptor Ack Setting for Ack requirement bit Fragment Setting for Fragment bit RetryMode Setting for retry mode Ifs Setting for IFS gap Rate Setting for transmit rate Service Setting for service Length Frame length TxPreamble Short or Long preamble when using CCK rates QueIdx - 0-3, according to 802.11e/d4.4 June/2003 Return Value: None IRQL = PASSIVE_LEVEL IRQL = DISPATCH_LEVEL ========================================================================*/VOID RTMPWriteTxDescriptor( IN PRTMP_ADAPTER pAd, IN PTXD_STRUC pTxD, IN BOOLEAN bWIV, IN UCHAR QueueSEL){ // // Always use Long preamble before verifiation short preamble functionality works well. // Todo: remove the following line if short preamble functionality works // OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED); pTxD->WIV = (bWIV) ? 1: 0; pTxD->QSEL= (QueueSEL); //RT2860c?? fixed using EDCA queue for test... We doubt Queue1 has problem. 2006-09-26 Jan //pTxD->QSEL= FIFO_EDCA; if (pAd->bGenOneHCCA == TRUE) pTxD->QSEL= FIFO_HCCA; pTxD->DMADONE = 0;}// should be called only when -// 1. MEADIA_CONNECTED// 2. AGGREGATION_IN_USED// 3. Fragmentation not in used// 4. either no previous frame (pPrevAddr1=NULL) .OR. previoud frame is aggregatibleBOOLEAN TxFrameIsAggregatible( IN PRTMP_ADAPTER pAd, IN PUCHAR pPrevAddr1, IN PUCHAR p8023hdr){ // can't aggregate EAPOL (802.1x) frame if ((p8023hdr[12] == 0x88) && (p8023hdr[13] == 0x8e)) return FALSE; // can't aggregate multicast/broadcast frame if (p8023hdr[0] & 0x01) return FALSE; if (INFRA_ON(pAd)) // must be unicast to AP return TRUE; else if ((pPrevAddr1 == NULL) || MAC_ADDR_EQUAL(pPrevAddr1, p8023hdr)) // unicast to same STA return TRUE; else return FALSE;}/* ======================================================================== Routine Description: Check the MSDU Aggregation policy 1.HT aggregation is A-MSDU 2.legaacy rate aggregation is software aggregation by Ralink. Arguments: Return Value: Note: ========================================================================*/BOOLEAN PeerIsAggreOn( IN PRTMP_ADAPTER pAd, IN ULONG TxRate, IN PMAC_TABLE_ENTRY pMacEntry){ ULONG AFlags = (fCLIENT_STATUS_AMSDU_INUSED | fCLIENT_STATUS_AGGREGATION_CAPABLE); if (pMacEntry != NULL && CLIENT_STATUS_TEST_FLAG(pMacEntry, AFlags)) { //if (TxRate >= RATE_6) if (pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX) { return TRUE; }#ifdef AGGREGATION_SUPPORT else if (TxRate >= RATE_6 && pAd->CommonCfg.bAggregationCapable && (!(CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE)))) { // legacy Ralink Aggregation support return TRUE; }#endif // AGGREGATION_SUPPORT // } return FALSE;}/* ======================================================================== Routine Description: Check and fine the packet waiting in SW queue with highest priority Arguments: pAd Pointer to our adapter Return Value: pQueue Pointer to Waiting Queue IRQL = DISPATCH_LEVEL Note: ========================================================================*/PQUEUE_HEADER RTMPCheckTxSwQueue( IN PRTMP_ADAPTER pAd, OUT PUCHAR pQueIdx){ ULONG Number; // 2004-11-15 to be removed. test aggregation only// if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)) && (*pNumber < 2))// return NULL; Number = pAd->TxSwQueue[QID_AC_BK].Number + pAd->TxSwQueue[QID_AC_BE].Number + pAd->TxSwQueue[QID_AC_VI].Number + pAd->TxSwQueue[QID_AC_VO].Number + pAd->TxSwQueue[QID_HCCA].Number; if (pAd->TxSwQueue[QID_AC_VO].Head != NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -