📄 cmm_data.c
字号:
the same policy to handle it. Force LowRate, //pTxBlk->bForceLowRate = TRUE; 11N Rate : No piggyback, //pTxBlk->bPiggyBack = FALSE; (1).AMSDU pTxBlk->bWMM = TRUE; (2).AMPDU pTxBlk->bWMM = TRUE; (3).Normal B/G Rate : (1).ARALINK (2).Normal ========================================================================*/static UCHAR TxPktClassification( IN RTMP_ADAPTER *pAd, IN PNDIS_PACKET pPacket){ UCHAR TxFrameType = TX_UNKOWN_FRAME; UCHAR Wcid; MAC_TABLE_ENTRY *pMacEntry = NULL;#ifdef DOT11_N_SUPPORT BOOLEAN bHTRate = FALSE;#endif // DOT11_N_SUPPORT // Wcid = RTMP_GET_PACKET_WCID(pPacket); if (Wcid == MCAST_WCID) { // Handle for RA is Broadcast/Multicast Address. return TX_MCAST_FRAME; } // Handle for unicast packets pMacEntry = &pAd->MacTab.Content[Wcid]; if (RTMP_GET_PACKET_LOWRATE(pPacket)) { // It's a specific packet need to force low rate, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame TxFrameType = TX_LEGACY_FRAME; }#ifdef DOT11_N_SUPPORT else if (IS_HT_RATE(pMacEntry)) { // it's a 11n capable packet // Depends on HTPhyMode to check if the peer support the HTRate transmission. // Currently didn't support A-MSDU embedded in A-MPDU bHTRate = TRUE; if (RTMP_GET_PACKET_MOREDATA(pPacket) || (pMacEntry->PsMode == PWR_SAVE)) TxFrameType = TX_LEGACY_FRAME;#ifdef UAPSD_AP_SUPPORT else if (RTMP_GET_PACKET_EOSP(pPacket)) TxFrameType = TX_LEGACY_FRAME;#endif // UAPSD_AP_SUPPORT // else if((pMacEntry->TXBAbitmap & (1<<(RTMP_GET_PACKET_UP(pPacket)))) != 0) return TX_AMPDU_FRAME; else if(CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AMSDU_INUSED)) return TX_AMSDU_FRAME; else TxFrameType = TX_LEGACY_FRAME; }#endif // DOT11_N_SUPPORT // else { // it's a legacy b/g packet. if ((CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE) && pAd->CommonCfg.bAggregationCapable) && (RTMP_GET_PACKET_TXRATE(pPacket) >= RATE_6) && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE)))) { // if peer support Ralink Aggregation, we use it. TxFrameType = TX_RALINK_FRAME; } else { TxFrameType = TX_LEGACY_FRAME; } } // Currently, our fragment only support when a unicast packet send as NOT-ARALINK, NOT-AMSDU and NOT-AMPDU. if ((RTMP_GET_PACKET_FRAGMENTS(pPacket) > 1) && (TxFrameType == TX_LEGACY_FRAME)) TxFrameType = TX_FRAG_FRAME; return TxFrameType;}BOOLEAN RTMP_FillTxBlkInfo( IN RTMP_ADAPTER *pAd, IN TX_BLK *pTxBlk){ PACKET_INFO PacketInfo; PNDIS_PACKET pPacket; PMAC_TABLE_ENTRY pMacEntry = NULL; pPacket = pTxBlk->pPacket; RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen); pTxBlk->Wcid = RTMP_GET_PACKET_WCID(pPacket); pTxBlk->apidx = RTMP_GET_PACKET_IF(pPacket); pTxBlk->UserPriority = RTMP_GET_PACKET_UP(pPacket); pTxBlk->FrameGap = IFS_HTTXOP; // ASIC determine Frame Gap if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(pTxBlk->pPacket)) TX_BLK_SET_FLAG(pTxBlk, fTX_bClearEAPFrame); else TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bClearEAPFrame); // Default to clear this flag TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bForceNonQoS); if (pTxBlk->Wcid == MCAST_WCID) { pTxBlk->pMacEntry = NULL; {#ifdef MCAST_RATE_SPECIFIC PUCHAR pDA = GET_OS_PKT_DATAPTR(pPacket); if (((*pDA & 0x01) == 0x01) && (*pDA != 0xff)) pTxBlk->pTransmit = &pAd->CommonCfg.MCastPhyMode; else#endif // MCAST_RATE_SPECIFIC // pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode; } TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); // AckRequired = FALSE, when broadcast packet in Adhoc mode. //TX_BLK_SET_FLAG(pTxBlk, fTX_bForceLowRate); TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAllowFrag); TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM); if (RTMP_GET_PACKET_MOREDATA(pPacket)) { TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData); } } else { pTxBlk->pMacEntry = &pAd->MacTab.Content[pTxBlk->Wcid]; pTxBlk->pTransmit = &pTxBlk->pMacEntry->HTPhyMode; pMacEntry = pTxBlk->pMacEntry; // For all unicast packets, need Ack unless the Ack Policy is not set as NORMAL_ACK. if (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx] != NORMAL_ACK) TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); else TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired);#ifdef CONFIG_STA_SUPPORT if ((pAd->OpMode == OPMODE_STA) && (ADHOC_ON(pAd)) && (RX_FILTER_TEST_FLAG(pAd, fRX_FILTER_ACCEPT_PROMISCUOUS))) { if(pAd->CommonCfg.PSPXlink) TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); }#endif // CONFIG_STA_SUPPORT // {#ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { // If support WMM, enable it. if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE)) TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM); // if (pAd->StaCfg.bAutoTxRateSwitch)// TX_BLK_SET_FLAG(pTxBlk, fTX_AutoRateSwitch); }#endif // CONFIG_STA_SUPPORT // } if (pTxBlk->TxFrameType == TX_LEGACY_FRAME) { if ( (RTMP_GET_PACKET_LOWRATE(pPacket)) || ((pAd->OpMode == OPMODE_AP) && (pMacEntry->MaxHTPhyMode.field.MODE == MODE_CCK) && (pMacEntry->MaxHTPhyMode.field.MCS == RATE_1))) { // Specific packet, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame, need force low rate. pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;#ifdef DOT11_N_SUPPORT // Modify the WMM bit for ICV issue. If we have a packet with EOSP field need to set as 1, how to handle it??? if (IS_HT_STA(pTxBlk->pMacEntry) && (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RALINK_CHIPSET)) && ((pAd->CommonCfg.bRdg == TRUE) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RDG_CAPABLE))) { TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM); TX_BLK_SET_FLAG(pTxBlk, fTX_bForceNonQoS); }#endif // DOT11_N_SUPPORT // } #ifdef DOT11_N_SUPPORT if ( (IS_HT_RATE(pMacEntry) == FALSE) && (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE))) { // Currently piggy-back only support when peer is operate in b/g mode. TX_BLK_SET_FLAG(pTxBlk, fTX_bPiggyBack); }#endif // DOT11_N_SUPPORT // if (RTMP_GET_PACKET_MOREDATA(pPacket)) { TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData); }#ifdef UAPSD_AP_SUPPORT if (RTMP_GET_PACKET_EOSP(pPacket)) { TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP); }#endif // UAPSD_AP_SUPPORT // } else if (pTxBlk->TxFrameType == TX_FRAG_FRAME) { TX_BLK_SET_FLAG(pTxBlk, fTX_bAllowFrag); } pMacEntry->DebugTxCount++; } return TRUE;}BOOLEAN CanDoAggregateTransmit( IN RTMP_ADAPTER *pAd, IN NDIS_PACKET *pPacket, IN TX_BLK *pTxBlk){ //DBGPRINT(RT_DEBUG_TRACE, ("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType)); if (RTMP_GET_PACKET_WCID(pPacket) == MCAST_WCID) return FALSE; if (RTMP_GET_PACKET_DHCP(pPacket) || RTMP_GET_PACKET_EAPOL(pPacket) || RTMP_GET_PACKET_WAI(pPacket)) return FALSE; if ((pTxBlk->TxFrameType == TX_AMSDU_FRAME) && ((pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))> (RX_BUFFER_AGGRESIZE - 100))) { // For AMSDU, allow the packets with total length < max-amsdu size return FALSE; } if ((pTxBlk->TxFrameType == TX_RALINK_FRAME) && (pTxBlk->TxPacketList.Number == 2)) { // For RALINK-Aggregation, allow two frames in one batch. return FALSE; }#ifdef CONFIG_STA_SUPPORT if ((INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) // must be unicast to AP return TRUE; else#endif // CONFIG_STA_SUPPORT // return FALSE; }/* ======================================================================== Routine Description: To do the enqueue operation and extract the first item of waiting list. If a number of available shared memory segments could meet the request of extracted item, the extracted item will be fragmented into shared memory segments. Arguments: pAd Pointer to our adapter pQueue Pointer to Waiting Queue Return Value: None IRQL = DISPATCH_LEVEL Note: ========================================================================*/VOID RTMPDeQueuePacket( IN PRTMP_ADAPTER pAd, IN BOOLEAN bIntContext, IN UCHAR QIdx, /* BulkOutPipeId */ IN UCHAR Max_Tx_Packets){ PQUEUE_ENTRY pEntry = NULL; PNDIS_PACKET pPacket; NDIS_STATUS Status = NDIS_STATUS_SUCCESS; UCHAR Count=0; PQUEUE_HEADER pQueue; ULONG FreeNumber[NUM_OF_TX_RING]; UCHAR QueIdx, sQIdx, eQIdx; unsigned long IrqFlags = 0; BOOLEAN hasTxDesc = FALSE; TX_BLK TxBlk; TX_BLK *pTxBlk;#ifdef DBG_DIAGNOSE BOOLEAN firstRound; RtmpDiagStruct *pDiagStruct = &pAd->DiagStruct;#endif if (QIdx == NUM_OF_TX_RING) { sQIdx = 0; eQIdx = 3; // 4 ACs, start from 0. } else { sQIdx = eQIdx = QIdx; } for (QueIdx=sQIdx; QueIdx <= eQIdx; QueIdx++) { Count=0; RTMP_START_DEQUEUE(pAd, QueIdx, IrqFlags);#ifdef DBG_DIAGNOSE firstRound = ((QueIdx == 0) ? TRUE : FALSE);#endif // DBG_DIAGNOSE // while (1) { if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))) { RTMP_STOP_DEQUEUE(pAd, QueIdx, IrqFlags); return; } if (Count >= Max_Tx_Packets) break; DEQUEUE_LOCK(&pAd->irq_lock, bIntContext, IrqFlags); if (&pAd->TxSwQueue[QueIdx] == NULL) {#ifdef DBG_DIAGNOSE if (firstRound == TRUE) pDiagStruct->TxSWQueCnt[pDiagStruct->ArrayCurIdx][0]++;#endif // DBG_DIAGNOSE // DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags); break; } // probe the Queue Head pQueue = &pAd->TxSwQueue[QueIdx]; if ((pEntry = pQueue->Head) == NULL) { DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags); break; } pTxBlk = &TxBlk; NdisZeroMemory((PUCHAR)pTxBlk, sizeof(TX_BLK)); //InitializeQueueHeader(&pTxBlk->TxPacketList); // Didn't need it because we already memzero it. pTxBlk->QueIdx = QueIdx; pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); // Early check to make sure we have enoguh Tx Resource. hasTxDesc = RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket); if (!hasTxDesc) { pAd->PrivateInfo.TxRingFullCnt++; DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags); break; } pTxBlk->TxFrameType = TxPktClassification(pAd, pPacket); pEntry = RemoveHeadQueue(pQueue); pTxBlk->TotalFrameNum++; pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); // The real fragment number maybe vary pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket); pTxBlk->pPacket = pPacket; InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket)); if (pTxBlk->TxFrameType == TX_RALINK_FRAME || pTxBlk->TxFrameType == TX_AMSDU_FRAME) { // Enhance SW Aggregation Mechanism if (NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, FreeNumber[QueIdx], pTxBlk->TxFrameType)) { InsertHeadQueue(pQueue, PACKET_TO_QUEUE_ENTRY(pPacket)); DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags); break; } do{ if((pEntry = pQueue->Head) == NULL) break; // For TX_AMSDU_FRAME/TX_RALINK_FRAME, Need to check if next pakcet can do aggregation. pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx); hasTxDesc = RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket); if ((hasTxDesc == FALSE) || (CanDoAggregateTransmit(pAd, pPacket, pTxBlk) == FALSE)) break; //Remove the packet from the TxSwQueue and insert into pTxBlk pEntry = RemoveHeadQueue(pQueue); ASSERT(pEntry); pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); pTxBlk->TotalFrameNum++; pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); // The real fragment number maybe vary pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket); InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket)); }while(1); if (pTxBlk->TxPacketList.Number == 1) pTxBlk->TxFrameType = TX_LEGACY_FRAME; }#ifdef RTMP_MAC_USB DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);#endif // RTMP_MAC_USB // Count += pTxBlk->TxPacketList.Number; // Do HardTransmit now.#ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) Status = STAHardTransmit(pAd, pTxBlk, QueIdx);#endif // CONFIG_STA_SUPPORT // } RTMP_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);#ifdef RTMP_MAC_USB if (!hasTxDesc) RTUSBKickBulkOut(pAd);#endif // RTMP_MAC_USB // #ifdef BLOCK_NET_IF if ((pAd->blockQueueTab[QueIdx].SwTxQueueBlockFlag == TRUE) && (pAd->TxSwQueue[QueIdx].Number < 1)) { releaseNetIf(&pAd->blockQueueTab[QueIdx]); }#endif // BLOCK_NET_IF // }}/* ======================================================================== 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -