/* ======================================================================== Routine Description: Process MGMT ring DMA done interrupt, running in DPC level Arguments: pAd Pointer to our adapter Return Value: None IRQL = DISPATCH_LEVEL Note: ======================================================================== */ VOID RTMPHandleMgmtRingDmaDoneInterrupt( IN PRTMP_ADAPTER pAd) { PTXD_STRUC pTxD; #ifdef RT_BIG_ENDIAN PTXD_STRUC pDestTxD; TXD_STRUC TxD; #endif PNDIS_PACKET pPacket; // int i; UCHAR FREE = 0; PRTMP_MGMT_RING pMgmtRing = &pAd->MgmtRing; NdisAcquireSpinLock(&pAd->MgmtRingLock); RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pMgmtRing->TxDmaIdx); while (pMgmtRing->TxSwFreeIdx!= pMgmtRing->TxDmaIdx) { FREE++; #ifdef RT_BIG_ENDIAN pDestTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa); TxD = *pDestTxD; pTxD = &TxD; RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); #else pTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa); #endif pTxD->DMADONE = 0; pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket; if (pPacket == NULL) continue; #ifdef CONFIG_AP_SUPPORT #define LMR_FRAME_GET() (GET_OS_PKT_DATAPTR(pPacket)+TXWI_SIZE) #ifdef UAPSD_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { UAPSD_QoSNullTxMgmtTxDoneHandle(pAd, pPacket, LMR_FRAME_GET()); } #endif // UAPSD_AP_SUPPORT // #ifdef WMM_ACM_SUPPORT { HEADER_802_11 *pHeader; /* handle Power Save ADDTS Response */ pHeader = (HEADER_802_11 *)(LMR_FRAME_GET()); if ((pHeader->FC.Type == BTYPE_MGMT) && (pHeader->FC.SubType == SUBTYPE_ACTION)) { ACMP_PsRspDeltsSentOutHandle(pAd, MacTableLookup(pAd, pHeader->Addr1), ((UCHAR *)pHeader)+sizeof(HEADER_802_11)); } } #endif // WMM_ACM_SUPPORT // #endif // CONFIG_AP_SUPPORT // if (pPacket) { PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE); RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); } pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket = NULL; pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket; if (pPacket) { PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE); RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); } pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket = NULL; INC_RING_INDEX(pMgmtRing->TxSwFreeIdx, MGMT_RING_SIZE); #ifdef RT_BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, TRUE, TYPE_TXD); #endif } NdisReleaseSpinLock(&pAd->MgmtRingLock); #ifdef CONFIG_STA_SUPPORT #ifdef WMM_ACM_SUPPORT /* return power save right if possible, ex: 0. sta enter PS mode; 1. sta enters ACTIVE mode; 2. sta sends ADDTS request frame; 3. sta receives ADDTS response frame; 4. sta enter PS mode; (ACMP_StaPsCtrlRightReturn) */ if (ACMR_IS_ENABLED(pAd)) ACMP_StaPsCtrlRightReturn(pAd); /* End of if */ #endif // WMM_ACM_SUPPORT // #endif // CONFIG_STA_SUPPORT // }
/* ======================================================================== Routine Description: Process MGMT ring DMA done interrupt, running in DPC level Arguments: pAd Pointer to our adapter Return Value: None IRQL = DISPATCH_LEVEL Note: ======================================================================== */ VOID RTMPHandleMgmtRingDmaDoneInterrupt( IN PRTMP_ADAPTER pAd) { PTXD_STRUC pTxD; #ifdef RT_BIG_ENDIAN PTXD_STRUC pDestTxD; TXD_STRUC TxD; #endif PNDIS_PACKET pPacket; /* int i;*/ UCHAR FREE = 0; PRTMP_MGMT_RING pMgmtRing = &pAd->MgmtRing; UINT8 TXWISize = pAd->chipCap.TXWISize; NdisAcquireSpinLock(&pAd->MgmtRingLock); RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pMgmtRing->TxDmaIdx); while (pMgmtRing->TxSwFreeIdx!= pMgmtRing->TxDmaIdx) { FREE++; #ifdef RT_BIG_ENDIAN pDestTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa); TxD = *pDestTxD; pTxD = &TxD; RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); #else pTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa); #endif /* pTxD->DMADONE = 0; */ pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket; if (pPacket == NULL) { INC_RING_INDEX(pMgmtRing->TxSwFreeIdx, MGMT_RING_SIZE); continue; } #define LMR_FRAME_GET() (GET_OS_PKT_DATAPTR(pPacket) + TXWISize) #ifdef UAPSD_SUPPORT #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { UAPSD_QoSNullTxMgmtTxDoneHandle(pAd, pPacket, LMR_FRAME_GET()); } #endif /* CONFIG_AP_SUPPORT */ #endif /* UAPSD_SUPPORT */ #ifdef CONFIG_AP_SUPPORT #endif /* CONFIG_AP_SUPPORT */ if (pPacket) { PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, RTMP_PCI_DMA_TODEVICE); RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); } pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket = NULL; pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket; if (pPacket) { PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, RTMP_PCI_DMA_TODEVICE); RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); } pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket = NULL; /* flush dcache if no consistent memory is supported */ RTMP_DCACHE_FLUSH(pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocPa, RXD_SIZE); INC_RING_INDEX(pMgmtRing->TxSwFreeIdx, MGMT_RING_SIZE); #ifdef RT_BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, TRUE, TYPE_TXD); #endif } NdisReleaseSpinLock(&pAd->MgmtRingLock); }