VOID MtEnqTxSwqFromPsQueue(RTMP_ADAPTER *pAd, UCHAR qidx, STA_TR_ENTRY *tr_entry) { ULONG IrqFlags = 0; //struct tx_swq_fifo *fifo_swq; QUEUE_ENTRY *pQEntry; QUEUE_HEADER *pAcPsQue; QUEUE_HEADER *pAcTxQue; #ifdef UAPSD_SUPPORT MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[tr_entry->wcid]; #endif /* UAPSD_SUPPORT */ //fifo_swq = &pAd->tx_swq[qidx]; pAcPsQue = &tr_entry->ps_queue; pAcTxQue = &tr_entry->tx_queue[qidx]; RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); #ifdef UAPSD_SUPPORT if (UAPSD_MR_IS_UAPSD_AC(pEntry, qidx)) { while(pAcPsQue->Head) { pQEntry = RemoveTailQueue(pAcPsQue); UAPSD_PacketEnqueue(pAd, pEntry, PACKET_TO_QUEUE_ENTRY(pQEntry), qidx, TRUE); } } else #endif /* UAPSD_SUPPORT */ { /*check and insert PS Token queue*/ if(pAcPsQue->Number > 0 && tr_entry->wcid > 0 && tr_entry->wcid < MAX_LEN_OF_TR_TABLE) { rtmp_ps_enq(pAd,tr_entry); DBGPRINT(RT_DEBUG_TRACE | DBG_FUNC_PS, ("pAcPsQue->Number=%d,PS:%d\n",pAcPsQue->Number,tr_entry->PsTokenFlag)); } while(pAcPsQue->Head) { pQEntry = RemoveTailQueue(pAcPsQue); if(tr_entry->enqCount > SQ_ENQ_NORMAL_MAX) { RELEASE_NDIS_PACKET(pAd, QUEUE_ENTRY_TO_PACKET(pQEntry), NDIS_STATUS_FAILURE); continue; } InsertHeadQueue(pAcTxQue, pQEntry); #ifdef LIMIT_GLOBAL_SW_QUEUE TR_ENQ_COUNT_INC(tr_entry, &pAd->TxSwQueue[qidx]); #else /* LIMIT_GLOBAL_SW_QUEUE */ TR_ENQ_COUNT_INC(tr_entry); #endif /* ! LIMIT_GLOBAL_SW_QUEUE */ } } RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); return; }
void tbtt_tasklet(unsigned long data) { //#define MAX_TX_IN_TBTT (16) #ifdef CONFIG_AP_SUPPORT PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data; #ifdef RTMP_MAC_PCI if (pAd->OpMode == OPMODE_AP) { #ifdef AP_QLOAD_SUPPORT /* update channel utilization */ QBSS_LoadUpdate(pAd, 0); #endif // AP_QLOAD_SUPPORT // } #endif // RTMP_MAC_PCI // if (pAd->OpMode == OPMODE_AP) { // // step 7 - if DTIM, then move backlogged bcast/mcast frames from PSQ to TXQ whenever DtimCount==0 #ifdef RTMP_MAC_PCI // NOTE: This updated BEACON frame will be sent at "next" TBTT instead of at cureent TBTT. The reason is // because ASIC already fetch the BEACON content down to TX FIFO before driver can make any // modification. To compenstate this effect, the actual time to deilver PSQ frames will be // at the time that we wrapping around DtimCount from 0 to DtimPeriod-1 if (pAd->ApCfg.DtimCount == 0) #endif // RTMP_MAC_PCI // { PQUEUE_ENTRY pEntry; BOOLEAN bPS = FALSE; UINT count = 0; unsigned long IrqFlags; // NdisAcquireSpinLock(&pAd->MacTabLock); // NdisAcquireSpinLock(&pAd->TxSwQueueLock); RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); while (pAd->MacTab.McastPsQueue.Head) { bPS = TRUE; if (pAd->TxSwQueue[QID_AC_BE].Number <= (MAX_PACKETS_IN_QUEUE + MAX_PACKETS_IN_MCAST_PS_QUEUE)) { pEntry = RemoveHeadQueue(&pAd->MacTab.McastPsQueue); //if(pAd->MacTab.McastPsQueue.Number) if (count) { RTMP_SET_PACKET_MOREDATA(pEntry, TRUE); } InsertHeadQueue(&pAd->TxSwQueue[QID_AC_BE], pEntry); count++; } else { break; } } RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); // NdisReleaseSpinLock(&pAd->TxSwQueueLock); // NdisReleaseSpinLock(&pAd->MacTabLock); if (pAd->MacTab.McastPsQueue.Number == 0) { UINT bss_index; /* clear MCAST/BCAST backlog bit for all BSS */ for(bss_index=BSS0; bss_index<pAd->ApCfg.BssidNum; bss_index++) WLAN_MR_TIM_BCMC_CLEAR(bss_index); /* End of for */ } pAd->MacTab.PsQIdleCount = 0; // Dequeue outgoing framea from TxSwQueue0..3 queue and process it if (bPS == TRUE) { RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, /*MAX_TX_IN_TBTT*/MAX_PACKETS_IN_MCAST_PS_QUEUE); } } } #endif // CONFIG_AP_SUPPORT // }