/* ======================================================================== Routine Description: Arguments: Return Value: IRQL = Note: ======================================================================== */ VOID RTUSBRejectPendingPackets( IN PRTMP_ADAPTER pAd) { UCHAR Index; PQUEUE_ENTRY pEntry; PNDIS_PACKET pPacket; PQUEUE_HEADER pQueue; #ifdef RELEASE_EXCLUDE DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RejectPendingPackets\n")); #endif // RELEASE_EXCLUDE // for (Index = 0; Index < 4; Index++) { NdisAcquireSpinLock(&pAd->TxSwQueueLock[Index]); while (pAd->TxSwQueue[Index].Head != NULL) { pQueue = (PQUEUE_HEADER) &(pAd->TxSwQueue[Index]); pEntry = RemoveHeadQueue(pQueue); pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); } NdisReleaseSpinLock(&pAd->TxSwQueueLock[Index]); } #ifdef RELEASE_EXCLUDE DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RejectPendingPackets\n")); #endif // RELEASE_EXCLUDE // }
VOID TxSwQDepthAdjust(IN RTMP_ADAPTER *pAd, IN UINT32 qLen) { ULONG IrqFlags; INT qIdx; QUEUE_HEADER *pTxQ, *pEntry; PNDIS_PACKET pPacket; RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); pAd->TxSwQMaxLen = qLen; for (qIdx = 0; qIdx < NUM_OF_TX_RING; qIdx++) { pTxQ = &pAd->TxSwQueue[qIdx]; while(pTxQ->Number >= pAd->TxSwQMaxLen) { pEntry = RemoveHeadQueue(pTxQ); if (pEntry) { pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); } else break; } } RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); DBGPRINT(RT_DEBUG_OFF, ("%s():Set TxSwQMaxLen as %d\n", __FUNCTION__, pAd->TxSwQMaxLen)); }
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; }
/* ========================================================================== Description: This routine is used to clean up a specified power-saving queue. It's used whenever a wireless client is deleted. ========================================================================== */ VOID RtmpCleanupPsQueue(RTMP_ADAPTER *pAd, QUEUE_HEADER *pQueue) { QUEUE_ENTRY *pQEntry; PNDIS_PACKET pPacket; DBGPRINT(RT_DEBUG_TRACE, ("RtmpCleanupPsQueue (0x%08lx)...\n", (ULONG)pQueue)); while (pQueue->Head) { DBGPRINT(RT_DEBUG_TRACE, ("RtmpCleanupPsQueue %ld...\n",pQueue->Number)); pQEntry = RemoveHeadQueue(pQueue); /*pPacket = CONTAINING_RECORD(pEntry, NDIS_PACKET, MiniportReservedEx); */ pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry); RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); DBGPRINT(RT_DEBUG_TRACE, ("RtmpCleanupPsQueue pkt = %lx...\n", (ULONG)pPacket)); } }
/* ======================================================================== Routine Description: Arguments: Return Value: IRQL = Note: ======================================================================== */ void RTUSBRejectPendingPackets(struct rt_rtmp_adapter *pAd) { u8 Index; struct rt_queue_entry *pEntry; void *pPacket; struct rt_queue_header *pQueue; for (Index = 0; Index < 4; Index++) { NdisAcquireSpinLock(&pAd->TxSwQueueLock[Index]); while (pAd->TxSwQueue[Index].Head != NULL) { pQueue = (struct rt_queue_header *)& (pAd->TxSwQueue[Index]); pEntry = RemoveHeadQueue(pQueue); pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); } NdisReleaseSpinLock(&pAd->TxSwQueueLock[Index]); } }
/* ======================================================================== Routine Description: Arguments: Return Value: IRQL = Note: ======================================================================== */ VOID RTUSBRejectPendingPackets( IN PRTMP_ADAPTER pAd) { UCHAR Index; PQUEUE_ENTRY pEntry; PNDIS_PACKET pPacket; PQUEUE_HEADER pQueue; for (Index = 0; Index < 4; Index++) { NdisAcquireSpinLock(&pAd->TxSwQueueLock[Index]); while (pAd->TxSwQueue[Index].Head != NULL) { pQueue = (PQUEUE_HEADER) &(pAd->TxSwQueue[Index]); pEntry = RemoveHeadQueue(pQueue); pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); } NdisReleaseSpinLock(&pAd->TxSwQueueLock[Index]); } }
VOID RTMPFreeTxRxRingMemory( IN PRTMP_ADAPTER pAd) { int index, num , j; PRTMP_TX_RING pTxRing; PTXD_STRUC pTxD; PNDIS_PACKET pPacket; unsigned int IrqFlags; POS_COOKIE pObj =(POS_COOKIE) pAd->OS_Cookie; DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPFreeTxRxRingMemory\n")); for (index=0; index <NUM_OF_TX_RING; index++) { PQUEUE_ENTRY pEntry; PNDIS_PACKET pPacket; PQUEUE_HEADER pQueue; RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); pQueue = &pAd->TxSwQueue[index]; while (pQueue->Head) { pEntry = RemoveHeadQueue(pQueue); pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); } RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); } for (index=0;index< NUM_OF_TX_RING;index++) { pTxRing = &pAd->TxRing[index]; for (j=0; j< TX_RING_SIZE; j++) { pTxD = (PTXD_STRUC) (pTxRing->Cell[j].AllocVa); pPacket = pTxRing->Cell[j].pNdisPacket; if (pPacket) { PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE); RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); } pTxRing->Cell[j].pNdisPacket = NULL; pPacket = pTxRing->Cell[j].pNextNdisPacket; if (pPacket) { PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE); RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); } pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = NULL; } } for (index = RX_RING_SIZE - 1 ; index >= 0; index--) { if ((pAd->RxRing.Cell[index].DmaBuf.AllocVa) && (pAd->RxRing.Cell[index].pNdisPacket)) { PCI_UNMAP_SINGLE(pObj->pci_dev, pAd->RxRing.Cell[index].DmaBuf.AllocPa, pAd->RxRing.Cell[index].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE); RELEASE_NDIS_PACKET(pAd, pAd->RxRing.Cell[index].pNdisPacket, NDIS_STATUS_SUCCESS); } } NdisZeroMemory(pAd->RxRing.Cell, RX_RING_SIZE * sizeof(RTMP_DMACB)); if (pAd->RxDescRing.AllocVa) { PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->RxDescRing.AllocSize, pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocPa); } NdisZeroMemory(&pAd->RxDescRing, sizeof(RTMP_DMABUF)); if (pAd->MgmtDescRing.AllocVa) { PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->MgmtDescRing.AllocSize, pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocPa); } NdisZeroMemory(&pAd->MgmtDescRing, sizeof(RTMP_DMABUF)); for (num = 0; num < NUM_OF_TX_RING; num++) { if (pAd->TxBufSpace[num].AllocVa) { PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->TxBufSpace[num].AllocSize, pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocPa); } NdisZeroMemory(&pAd->TxBufSpace[num], sizeof(RTMP_DMABUF)); if (pAd->TxDescRing[num].AllocVa) { PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->TxDescRing[num].AllocSize, pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocPa); } NdisZeroMemory(&pAd->TxDescRing[num], sizeof(RTMP_DMABUF)); } if (pAd->FragFrame.pFragPacket) RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS); DBGPRINT(RT_DEBUG_TRACE, ("<-- RTMPFreeTxRxRingMemory\n")); }
VOID RTMPRingCleanUp( IN PRTMP_ADAPTER pAd, IN UCHAR RingType) { PTXD_STRUC pTxD; PRXD_STRUC pRxD; PQUEUE_ENTRY pEntry; PNDIS_PACKET pPacket; int i; PRTMP_TX_RING pTxRing; unsigned long IrqFlags; DBGPRINT(RT_DEBUG_TRACE,("RTMPRingCleanUp(RingIdx=%d, Pending-NDIS=%ld)\n", RingType, pAd->RalinkCounters.PendingNdisPacketCount)); switch (RingType) { case QID_AC_BK: case QID_AC_BE: case QID_AC_VI: case QID_AC_VO: case QID_HCCA: RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); pTxRing = &pAd->TxRing[RingType]; for (i=0; i<TX_RING_SIZE; i++) { pTxD = (PTXD_STRUC) pTxRing->Cell[i].AllocVa; pPacket = (PNDIS_PACKET) pTxRing->Cell[i].pNdisPacket; if (pPacket) { RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); pTxRing->Cell[i].pNdisPacket = NULL; } pPacket = (PNDIS_PACKET) pTxRing->Cell[i].pNextNdisPacket; if (pPacket) { RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); pTxRing->Cell[i].pNextNdisPacket = NULL; } } RTMP_IO_READ32(pAd, TX_DTX_IDX0 + RingType * 0x10, &pTxRing->TxDmaIdx); pTxRing->TxSwFreeIdx = pTxRing->TxDmaIdx; pTxRing->TxCpuIdx = pTxRing->TxDmaIdx; RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + RingType * 0x10, pTxRing->TxCpuIdx); RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); while (pAd->TxSwQueue[RingType].Head != NULL) { pEntry = RemoveHeadQueue(&pAd->TxSwQueue[RingType]); pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); DBGPRINT(RT_DEBUG_TRACE,("Release 1 NDIS packet from s/w backlog queue\n")); } RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); break; case QID_MGMT: NdisAcquireSpinLock(&pAd->MgmtRingLock); for (i=0; i<MGMT_RING_SIZE; i++) { pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[i].AllocVa; pPacket = (PNDIS_PACKET) pAd->MgmtRing.Cell[i].pNdisPacket; if (pPacket) { PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE); RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); } pAd->MgmtRing.Cell[i].pNdisPacket = NULL; pPacket = (PNDIS_PACKET) pAd->MgmtRing.Cell[i].pNextNdisPacket; if (pPacket) { PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE); RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); } pAd->MgmtRing.Cell[i].pNextNdisPacket = NULL; } RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pAd->MgmtRing.TxDmaIdx); pAd->MgmtRing.TxSwFreeIdx = pAd->MgmtRing.TxDmaIdx; pAd->MgmtRing.TxCpuIdx = pAd->MgmtRing.TxDmaIdx; RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx); NdisReleaseSpinLock(&pAd->MgmtRingLock); pAd->RalinkCounters.MgmtRingFullCount = 0; break; case QID_RX: NdisAcquireSpinLock(&pAd->RxRingLock); for (i=0; i<RX_RING_SIZE; i++) { pRxD = (PRXD_STRUC) pAd->RxRing.Cell[i].AllocVa; pRxD->DDONE = 0 ; } RTMP_IO_READ32(pAd, RX_DRX_IDX, &pAd->RxRing.RxDmaIdx); pAd->RxRing.RxSwReadIdx = pAd->RxRing.RxDmaIdx; pAd->RxRing.RxCpuIdx = ((pAd->RxRing.RxDmaIdx == 0) ? (RX_RING_SIZE-1) : (pAd->RxRing.RxDmaIdx-1)); RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx); NdisReleaseSpinLock(&pAd->RxRingLock); break; default: break; } }