NDIS_STATUS RTMPAllocTxRxRingMemory( IN PRTMP_ADAPTER pAd) { NDIS_STATUS Status = NDIS_STATUS_SUCCESS; ULONG RingBasePaHigh; ULONG RingBasePaLow; PVOID RingBaseVa; INT index, num; PTXD_STRUC pTxD; PRXD_STRUC pRxD; ULONG ErrorValue = 0; PRTMP_TX_RING pTxRing; PRTMP_DMABUF pDmaBuf; PNDIS_PACKET pPacket; DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n")); do { for (num=0; num<NUM_OF_TX_RING; num++) { ULONG BufBasePaHigh; ULONG BufBasePaLow; PVOID BufBaseVa; pAd->TxDescRing[num].AllocSize = TX_RING_SIZE * TXD_SIZE; RTMP_AllocateTxDescMemory( pAd, num, pAd->TxDescRing[num].AllocSize, FALSE, &pAd->TxDescRing[num].AllocVa, &pAd->TxDescRing[num].AllocPa); if (pAd->TxDescRing[num].AllocVa == NULL) { ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; DBGPRINT_ERR(("Failed to allocate a big buffer\n")); Status = NDIS_STATUS_RESOURCES; break; } NdisZeroMemory(pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocSize); RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxDescRing[num].AllocPa); RingBasePaLow = RTMP_GetPhysicalAddressLow (pAd->TxDescRing[num].AllocPa); RingBaseVa = pAd->TxDescRing[num].AllocVa; pAd->TxBufSpace[num].AllocSize = TX_RING_SIZE * TX_DMA_1ST_BUFFER_SIZE; RTMP_AllocateFirstTxBuffer( pAd, num, pAd->TxBufSpace[num].AllocSize, FALSE, &pAd->TxBufSpace[num].AllocVa, &pAd->TxBufSpace[num].AllocPa); if (pAd->TxBufSpace[num].AllocVa == NULL) { ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; DBGPRINT_ERR(("Failed to allocate a big buffer\n")); Status = NDIS_STATUS_RESOURCES; break; } NdisZeroMemory(pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocSize); BufBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxBufSpace[num].AllocPa); BufBasePaLow = RTMP_GetPhysicalAddressLow (pAd->TxBufSpace[num].AllocPa); BufBaseVa = pAd->TxBufSpace[num].AllocVa; pTxRing = &pAd->TxRing[num]; for (index = 0; index < TX_RING_SIZE; index++) { pTxRing->Cell[index].pNdisPacket = NULL; pTxRing->Cell[index].pNextNdisPacket = NULL; pTxRing->Cell[index].AllocSize = TXD_SIZE; pTxRing->Cell[index].AllocVa = RingBaseVa; RTMP_SetPhysicalAddressHigh(pTxRing->Cell[index].AllocPa, RingBasePaHigh); RTMP_SetPhysicalAddressLow (pTxRing->Cell[index].AllocPa, RingBasePaLow); pDmaBuf = &pTxRing->Cell[index].DmaBuf; pDmaBuf->AllocSize = TX_DMA_1ST_BUFFER_SIZE; pDmaBuf->AllocVa = BufBaseVa; RTMP_SetPhysicalAddressHigh(pDmaBuf->AllocPa, BufBasePaHigh); RTMP_SetPhysicalAddressLow(pDmaBuf->AllocPa, BufBasePaLow); pTxD = (PTXD_STRUC) pTxRing->Cell[index].AllocVa; pTxD->SDPtr0 = BufBasePaLow; pTxD->DMADONE = 1; RingBasePaLow += TXD_SIZE; RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE; BufBasePaLow += TX_DMA_1ST_BUFFER_SIZE; BufBaseVa = (PUCHAR) BufBaseVa + TX_DMA_1ST_BUFFER_SIZE; } DBGPRINT(RT_DEBUG_TRACE, ("TxRing[%d]: total %d entry allocated\n", num, index)); } if (Status == NDIS_STATUS_RESOURCES) break; pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * TXD_SIZE; RTMP_AllocateMgmtDescMemory( pAd, pAd->MgmtDescRing.AllocSize, FALSE, &pAd->MgmtDescRing.AllocVa, &pAd->MgmtDescRing.AllocPa); if (pAd->MgmtDescRing.AllocVa == NULL) { ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; DBGPRINT_ERR(("Failed to allocate a big buffer\n")); Status = NDIS_STATUS_RESOURCES; break; } NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize); RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->MgmtDescRing.AllocPa); RingBasePaLow = RTMP_GetPhysicalAddressLow (pAd->MgmtDescRing.AllocPa); RingBaseVa = pAd->MgmtDescRing.AllocVa; for (index = 0; index < MGMT_RING_SIZE; index++) { pAd->MgmtRing.Cell[index].pNdisPacket = NULL; pAd->MgmtRing.Cell[index].pNextNdisPacket = NULL; pAd->MgmtRing.Cell[index].AllocSize = TXD_SIZE; pAd->MgmtRing.Cell[index].AllocVa = RingBaseVa; RTMP_SetPhysicalAddressHigh(pAd->MgmtRing.Cell[index].AllocPa, RingBasePaHigh); RTMP_SetPhysicalAddressLow (pAd->MgmtRing.Cell[index].AllocPa, RingBasePaLow); RingBasePaLow += TXD_SIZE; RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE; pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[index].AllocVa; pTxD->DMADONE = 1; } DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", index)); pAd->RxDescRing.AllocSize = RX_RING_SIZE * RXD_SIZE; RTMP_AllocateRxDescMemory( pAd, pAd->RxDescRing.AllocSize, FALSE, &pAd->RxDescRing.AllocVa, &pAd->RxDescRing.AllocPa); if (pAd->RxDescRing.AllocVa == NULL) { ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; DBGPRINT_ERR(("Failed to allocate a big buffer\n")); Status = NDIS_STATUS_RESOURCES; break; } NdisZeroMemory(pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocSize); printk("RX DESC %p size = %ld\n", pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocSize); RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->RxDescRing.AllocPa); RingBasePaLow = RTMP_GetPhysicalAddressLow (pAd->RxDescRing.AllocPa); RingBaseVa = pAd->RxDescRing.AllocVa; for (index = 0; index < RX_RING_SIZE; index++) { pAd->RxRing.Cell[index].AllocSize = RXD_SIZE; pAd->RxRing.Cell[index].AllocVa = RingBaseVa; RTMP_SetPhysicalAddressHigh(pAd->RxRing.Cell[index].AllocPa, RingBasePaHigh); RTMP_SetPhysicalAddressLow (pAd->RxRing.Cell[index].AllocPa, RingBasePaLow); RingBasePaLow += RXD_SIZE; RingBaseVa = (PUCHAR) RingBaseVa + RXD_SIZE; pDmaBuf = &pAd->RxRing.Cell[index].DmaBuf; pDmaBuf->AllocSize = RX_BUFFER_AGGRESIZE; pPacket = RTMP_AllocateRxPacketBuffer( pAd, pDmaBuf->AllocSize, FALSE, &pDmaBuf->AllocVa, &pDmaBuf->AllocPa); pAd->RxRing.Cell[index].pNdisPacket = pPacket; if (pDmaBuf->AllocVa == NULL) { ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; DBGPRINT_ERR(("Failed to allocate RxRing's 1st buffer\n")); Status = NDIS_STATUS_RESOURCES; break; } NdisZeroMemory(pDmaBuf->AllocVa, pDmaBuf->AllocSize); pRxD = (PRXD_STRUC) pAd->RxRing.Cell[index].AllocVa; pRxD->SDP0 = RTMP_GetPhysicalAddressLow(pDmaBuf->AllocPa); pRxD->DDONE = 0; } DBGPRINT(RT_DEBUG_TRACE, ("Rx Ring: total %d entry allocated\n", index)); } while (FALSE); NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME)); pAd->FragFrame.pFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE); if (pAd->FragFrame.pFragPacket == NULL) { Status = NDIS_STATUS_RESOURCES; } if (Status != NDIS_STATUS_SUCCESS) { NdisWriteErrorLogEntry( pAd->AdapterHandle, NDIS_ERROR_CODE_OUT_OF_RESOURCES, 1, ErrorValue); } DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status)); return Status; }
/* ======================================================================== Routine Description: Allocate DMA memory blocks for send, receive Arguments: Adapter Pointer to our adapter Return Value: NDIS_STATUS_SUCCESS NDIS_STATUS_FAILURE NDIS_STATUS_RESOURCES IRQL = PASSIVE_LEVEL Note: ======================================================================== */ NDIS_STATUS RTMPAllocTxRxRingMemory( IN PRTMP_ADAPTER pAd) { NDIS_STATUS Status = NDIS_STATUS_SUCCESS; ULONG RingBasePaHigh; ULONG RingBasePaLow; PVOID RingBaseVa; INT index, num; PTXD_STRUC pTxD; PRXD_STRUC pRxD; ULONG ErrorValue = 0; PRTMP_TX_RING pTxRing; PRTMP_DMABUF pDmaBuf; PNDIS_PACKET pPacket; DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n")); do { // // Allocate all ring descriptors, include TxD, RxD, MgmtD. // Although each size is different, to prevent cacheline and alignment // issue, I intentional set them all to 64 bytes. // for (num=0; num<NUM_OF_TX_RING; num++) { ULONG BufBasePaHigh; ULONG BufBasePaLow; PVOID BufBaseVa; // // Allocate Tx ring descriptor's memory (5 TX rings = 4 ACs + 1 HCCA) // pAd->TxDescRing[num].AllocSize = TX_RING_SIZE * TXD_SIZE; RTMP_AllocateTxDescMemory( pAd, num, pAd->TxDescRing[num].AllocSize, FALSE, &pAd->TxDescRing[num].AllocVa, &pAd->TxDescRing[num].AllocPa); if (pAd->TxDescRing[num].AllocVa == NULL) { ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; DBGPRINT_ERR(("Failed to allocate a big buffer\n")); Status = NDIS_STATUS_RESOURCES; break; } // Zero init this memory block NdisZeroMemory(pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocSize); // Save PA & VA for further operation RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxDescRing[num].AllocPa); RingBasePaLow = RTMP_GetPhysicalAddressLow (pAd->TxDescRing[num].AllocPa); RingBaseVa = pAd->TxDescRing[num].AllocVa; // // Allocate all 1st TXBuf's memory for this TxRing // pAd->TxBufSpace[num].AllocSize = TX_RING_SIZE * TX_DMA_1ST_BUFFER_SIZE; RTMP_AllocateFirstTxBuffer( pAd, num, pAd->TxBufSpace[num].AllocSize, FALSE, &pAd->TxBufSpace[num].AllocVa, &pAd->TxBufSpace[num].AllocPa); if (pAd->TxBufSpace[num].AllocVa == NULL) { ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; DBGPRINT_ERR(("Failed to allocate a big buffer\n")); Status = NDIS_STATUS_RESOURCES; break; } // Zero init this memory block NdisZeroMemory(pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocSize); // Save PA & VA for further operation BufBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxBufSpace[num].AllocPa); BufBasePaLow = RTMP_GetPhysicalAddressLow (pAd->TxBufSpace[num].AllocPa); BufBaseVa = pAd->TxBufSpace[num].AllocVa; // // Initialize Tx Ring Descriptor and associated buffer memory // pTxRing = &pAd->TxRing[num]; for (index = 0; index < TX_RING_SIZE; index++) { pTxRing->Cell[index].pNdisPacket = NULL; pTxRing->Cell[index].pNextNdisPacket = NULL; // Init Tx Ring Size, Va, Pa variables pTxRing->Cell[index].AllocSize = TXD_SIZE; pTxRing->Cell[index].AllocVa = RingBaseVa; RTMP_SetPhysicalAddressHigh(pTxRing->Cell[index].AllocPa, RingBasePaHigh); RTMP_SetPhysicalAddressLow (pTxRing->Cell[index].AllocPa, RingBasePaLow); // Setup Tx Buffer size & address. only 802.11 header will store in this space pDmaBuf = &pTxRing->Cell[index].DmaBuf; pDmaBuf->AllocSize = TX_DMA_1ST_BUFFER_SIZE; pDmaBuf->AllocVa = BufBaseVa; RTMP_SetPhysicalAddressHigh(pDmaBuf->AllocPa, BufBasePaHigh); RTMP_SetPhysicalAddressLow(pDmaBuf->AllocPa, BufBasePaLow); // link the pre-allocated TxBuf to TXD pTxD = (PTXD_STRUC) pTxRing->Cell[index].AllocVa; pTxD->SDPtr0 = BufBasePaLow; // advance to next ring descriptor address pTxD->DMADONE = 1; RingBasePaLow += TXD_SIZE; RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE; // advance to next TxBuf address BufBasePaLow += TX_DMA_1ST_BUFFER_SIZE; BufBaseVa = (PUCHAR) BufBaseVa + TX_DMA_1ST_BUFFER_SIZE; } DBGPRINT(RT_DEBUG_TRACE, ("TxRing[%d]: total %d entry allocated\n", num, index)); } if (Status == NDIS_STATUS_RESOURCES) break; // // Allocate MGMT ring descriptor's memory except Tx ring which allocated eariler // pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * TXD_SIZE; RTMP_AllocateMgmtDescMemory( pAd, pAd->MgmtDescRing.AllocSize, FALSE, &pAd->MgmtDescRing.AllocVa, &pAd->MgmtDescRing.AllocPa); if (pAd->MgmtDescRing.AllocVa == NULL) { ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; DBGPRINT_ERR(("Failed to allocate a big buffer\n")); Status = NDIS_STATUS_RESOURCES; break; } // Zero init this memory block NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize); // Save PA & VA for further operation RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->MgmtDescRing.AllocPa); RingBasePaLow = RTMP_GetPhysicalAddressLow (pAd->MgmtDescRing.AllocPa); RingBaseVa = pAd->MgmtDescRing.AllocVa; // // Initialize MGMT Ring and associated buffer memory // for (index = 0; index < MGMT_RING_SIZE; index++) { pAd->MgmtRing.Cell[index].pNdisPacket = NULL; pAd->MgmtRing.Cell[index].pNextNdisPacket = NULL; // Init MGMT Ring Size, Va, Pa variables pAd->MgmtRing.Cell[index].AllocSize = TXD_SIZE; pAd->MgmtRing.Cell[index].AllocVa = RingBaseVa; RTMP_SetPhysicalAddressHigh(pAd->MgmtRing.Cell[index].AllocPa, RingBasePaHigh); RTMP_SetPhysicalAddressLow (pAd->MgmtRing.Cell[index].AllocPa, RingBasePaLow); // Offset to next ring descriptor address RingBasePaLow += TXD_SIZE; RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE; // link the pre-allocated TxBuf to TXD pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[index].AllocVa; pTxD->DMADONE = 1; // no pre-allocated buffer required in MgmtRing for scatter-gather case } DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", index)); // // Allocate RX ring descriptor's memory except Tx ring which allocated eariler // pAd->RxDescRing.AllocSize = RX_RING_SIZE * RXD_SIZE; RTMP_AllocateRxDescMemory( pAd, pAd->RxDescRing.AllocSize, FALSE, &pAd->RxDescRing.AllocVa, &pAd->RxDescRing.AllocPa); if (pAd->RxDescRing.AllocVa == NULL) { ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; DBGPRINT_ERR(("Failed to allocate a big buffer\n")); Status = NDIS_STATUS_RESOURCES; break; } // Zero init this memory block NdisZeroMemory(pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocSize); printk("RX DESC %p size = %ld\n", pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocSize); // Save PA & VA for further operation RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->RxDescRing.AllocPa); RingBasePaLow = RTMP_GetPhysicalAddressLow (pAd->RxDescRing.AllocPa); RingBaseVa = pAd->RxDescRing.AllocVa; // // Initialize Rx Ring and associated buffer memory // for (index = 0; index < RX_RING_SIZE; index++) { // Init RX Ring Size, Va, Pa variables pAd->RxRing.Cell[index].AllocSize = RXD_SIZE; pAd->RxRing.Cell[index].AllocVa = RingBaseVa; RTMP_SetPhysicalAddressHigh(pAd->RxRing.Cell[index].AllocPa, RingBasePaHigh); RTMP_SetPhysicalAddressLow (pAd->RxRing.Cell[index].AllocPa, RingBasePaLow); // Offset to next ring descriptor address RingBasePaLow += RXD_SIZE; RingBaseVa = (PUCHAR) RingBaseVa + RXD_SIZE; // Setup Rx associated Buffer size & allocate share memory pDmaBuf = &pAd->RxRing.Cell[index].DmaBuf; pDmaBuf->AllocSize = RX_BUFFER_AGGRESIZE; pPacket = RTMP_AllocateRxPacketBuffer( pAd, pDmaBuf->AllocSize, FALSE, &pDmaBuf->AllocVa, &pDmaBuf->AllocPa); /* keep allocated rx packet */ pAd->RxRing.Cell[index].pNdisPacket = pPacket; // Error handling if (pDmaBuf->AllocVa == NULL) { ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; DBGPRINT_ERR(("Failed to allocate RxRing's 1st buffer\n")); Status = NDIS_STATUS_RESOURCES; break; } // Zero init this memory block NdisZeroMemory(pDmaBuf->AllocVa, pDmaBuf->AllocSize); // Write RxD buffer address & allocated buffer length pRxD = (PRXD_STRUC) pAd->RxRing.Cell[index].AllocVa; pRxD->SDP0 = RTMP_GetPhysicalAddressLow(pDmaBuf->AllocPa); pRxD->DDONE = 0; } DBGPRINT(RT_DEBUG_TRACE, ("Rx Ring: total %d entry allocated\n", index)); } while (FALSE); NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME)); pAd->FragFrame.pFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE); if (pAd->FragFrame.pFragPacket == NULL) { Status = NDIS_STATUS_RESOURCES; } if (Status != NDIS_STATUS_SUCCESS) { // Log error inforamtion NdisWriteErrorLogEntry( pAd->AdapterHandle, NDIS_ERROR_CODE_OUT_OF_RESOURCES, 1, ErrorValue); } DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status)); return Status; }