diff -r 000000000000 -r c40eb8fe8501 wlan_bearer/wlanldd/wlan_symbian/wlanldd_symbian/src/EthernetFrameMemMngr.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlan_bearer/wlanldd/wlan_symbian/wlanldd_symbian/src/EthernetFrameMemMngr.cpp Tue Feb 02 02:03:13 2010 +0200 @@ -0,0 +1,475 @@ +/* +* Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of the DEthernetFrameMemMngr class. +* +*/ + +/* +* %version: 23 % +*/ + +#include "WlLddWlanLddConfig.h" +#include "DataFrameMemMngr.h" +#include "MgmtFrameMemMngr.h" +#include "osachunk.h" +#include +#include + +#include "EtherCardApi.h" + +extern void os_free( const TAny* ); + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +DEthernetFrameMemMngr* DEthernetFrameMemMngr::Init( + TInt aUnit, + DWlanLogicalChannel& aParent, + WlanChunk*& aRxFrameMemoryPool, + TBool aUseCachedMemory, + TInt aFrameBufAllocationUnit ) + { + DEthernetFrameMemMngr* ret = NULL; + + if ( aUnit == KUnitEthernet ) + { + ret = new DataFrameMemMngr( + aParent, + aRxFrameMemoryPool, + aFrameBufAllocationUnit ); + } + else if ( aUnit == KUnitWlan ) + { + ret = new MgmtFrameMemMngr( + aParent, + aRxFrameMemoryPool, + aUseCachedMemory, + aFrameBufAllocationUnit ); + } + else + { + TraceDump(ERROR_LEVEL, + (("WLANLDD: DEthernetFrameMemMngr::Init: ERROR: unknown unit: %d"), + aUnit)); + // No action. NULL is returned + } + + if ( ret ) + { + TraceDump(MEMORY, (("WLANLDD: new FrameMemMngr: 0x%08x"), + reinterpret_cast(ret))); + } + + return ret; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TInt DEthernetFrameMemMngr::OnInitialiseMemory( + DThread& aThread, + TSharedChunkInfo* aSharedChunkInfo, + TUint aVendorTxHdrLen, + TUint aVendorTxTrailerLen ) + { + TraceDump( INIT_LEVEL, + (("WLANLDD: DEthernetFrameMemMngr::OnInitialiseMemory: aVendorTxHdrLen: %d"), + aVendorTxHdrLen ) ); + TraceDump( INIT_LEVEL, + (("WLANLDD: aVendorTxTrailerLen: %d"), + aVendorTxTrailerLen ) ); + + TInt ret( KErrGeneral ); + + iVendorTxHdrLen = aVendorTxHdrLen; + iVendorTxTrailerLen = aVendorTxTrailerLen; + + // Local info structure we will fill in + TSharedChunkInfo info; + + if( !IsMemInUse() ) + { + ret = DoAllocate( iParent.SharedMemoryChunk() ); + + if ( ret == KErrNone ) + { + ret = DoOpenHandle( aThread, info, iParent.SharedMemoryChunk() ); + + if ( ret == KErrNone ) + { + MarkMemInUSe(); // mark as in use + ret = KErrNone; + } + else + { + // handle creation & open failed + + TraceDump( INIT_LEVEL, + (("WLANLDD: DEthernetFrameMemMngr::OnInitialiseMemory: Handle create & open error: status: %d"), + ret ) ); + + // zero contents of info structure. + // (Zero is usually a safe value to return on error for most data types, + // and for object handles this is same as KNullHandle) + memclr( &info, sizeof( info ) ); + + // need to enter critical section for chunk closing + NKern::ThreadEnterCS(); + + // schedule the shared memory chunk for destruction + Kern::ChunkClose( iParent.SharedMemoryChunk() ); + + // leave critical section + NKern::ThreadLeaveCS(); + } + + // write handle info to client memory + ret = Kern::ThreadRawWrite( + &aThread, + aSharedChunkInfo, + &info, + sizeof( info ) ); + if ( ret != KErrNone ) + { + TraceDump(ERROR_LEVEL, ("WLANLDD: ThreadRawWrite panic")); + TraceDump(ERROR_LEVEL, (("WLANLDD: ret: %d"), ret)); + os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ ); + } + } + else + { + // allocation failed; error code will be returned + } + } + else + { + ret = KErrAlreadyExists; + } + + return ret; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +DEthernetFrameMemMngr::~DEthernetFrameMemMngr() + { + OnReleaseMemory(); + + iFrameXferBlock = NULL; + iTxDataBuffer = NULL; + iRxDataChunk = NULL; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void DEthernetFrameMemMngr::OnReleaseMemory() + { + MarkMemFree(); // mark as free + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TDataBuffer* DEthernetFrameMemMngr::OnWriteEthernetFrame() const + { + if ( iTxDataBuffer->GetLength() >= sizeof( SEthernetHeader ) ) + { + return iTxDataBuffer; + } + else + { + os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ ); + return NULL; + } + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TBool DEthernetFrameMemMngr::OnReadRequest() + { + TBool ret( EFalse ); + + if ( IsMemInUse() ) + { + if ( iCountCompleted ) + { + // free relevant buffers + DoFreeRxBuffers(); + iCountCompleted = 0; // no buffers anymore in process in user mode + + // make sure that the same buffers are not tried to be + // freed again thru the incremental freeing method + iFrameXferBlock->KeAllUserSideRxBuffersFreed(); + } + + if ( iCountTobeCompleted ) + { + // there are Rx buffers to be completed + + iFrameXferBlock->KeRxComplete( DoGetTobeCompletedBuffersStart(), + iCountTobeCompleted ); + // mark the completed buffers + assign( DoGetTobeCompletedBuffersStart(), + DoGetCompletedBuffersStart(), + iCountTobeCompleted ); + iCountCompleted = iCountTobeCompleted; + iCountTobeCompleted = 0; + + ret = ETrue; + // the frame Rx request won't be pending as the callee shall + // complete it + iReadStatus = ENotPending; + } + else + { + // there are no Rx buffers to be completed. The Rx request is + // left pending + iReadStatus = EPending; + } + } + else + { + os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ ); + } + + return ret; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void DEthernetFrameMemMngr::DoMarkRxBufFree( TUint8* /*aBufferToFree*/ ) + { + // not supported in default handler + os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ ); + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void DEthernetFrameMemMngr::SetTxOffsets( + TUint32 aEthernetFrameTxOffset, + TUint32 aDot11FrameTxOffset, + TUint32 aSnapFrameTxOffset ) + { + if ( IsMemInUse() ) + { + iFrameXferBlock->KeSetTxOffsets( + aEthernetFrameTxOffset, + aDot11FrameTxOffset, + aSnapFrameTxOffset ); + } + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TUint8* DEthernetFrameMemMngr::OnGetEthernetFrameRxBuffer( + TUint aLengthinBytes ) + { + TUint8* buffer ( NULL ); + + if ( IsMemInUse() ) + { + buffer = DoGetNextFreeRxBuffer( aLengthinBytes ); + } + else + { + // we are trying to acquire an Rx buffer but our user mode client + // has not asked for the memorybuffer pool to be initialized. In this + // case NULL is returned, as no buffers are available + TraceDump(RX_FRAME, + ("WLANLDD: DEthernetFrameMemMngr::OnGetEthernetFrameRxBuffer: not initialized => failed")); + } + + return buffer; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TDataBuffer* DEthernetFrameMemMngr::GetRxFrameMetaHeader() + { + TDataBuffer* buffer ( NULL ); + + if ( IsMemInUse() ) + { + buffer = reinterpret_cast( + iRxFrameMemoryPool->Alloc( sizeof( TDataBuffer ), ETrue ) ); + + TraceDump(RX_FRAME, + (("WLANLDD: DEthernetFrameMemMngr::GetRxFrameMetaHeader: addr: 0x%08x"), + reinterpret_cast(buffer)) ); + } + else + { + // we are trying to acquire memory for Rx frame meta header but our + // user mode client has not asked for the memorybuffer pool to be + // initialized. In this case NULL is returned, as no memory is + // available + TraceDump(RX_FRAME, + ("WLANLDD: DEthernetFrameMemMngr::GetRxFrameMetaHeader: not initialized => failed")); + } + + return buffer; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void DEthernetFrameMemMngr::FreeRxFrameMetaHeader( TDataBuffer* aMetaHeader ) + { + if ( IsMemInUse() ) + { + iRxFrameMemoryPool->Free( aMetaHeader ); + } + else + { + // the whole Rx memory pool - including aMetaHeader - has already + // been deallocated, so nothing is done in this case + TraceDump( RX_FRAME, + ("WLANLDD: MgmtFrameMemMngr::FreeRxFrameMetaHeader: Rx memory pool already deallocated; no action needed") ); + } + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TBool DEthernetFrameMemMngr::OnEthernetFrameRxComplete( + const TDataBuffer*& aBufferStart, + TUint32 aNumOfBuffers ) + { + TBool ret( EFalse ); + + if ( IsMemInUse() && + DoEthernetFrameRxComplete( aBufferStart, aNumOfBuffers ) ) + { + iReadStatus = ENotPending; + ret = ETrue; + } + + return ret; + } + +// --------------------------------------------------------------------------- +// this default implementation always returns KErrNone +// --------------------------------------------------------------------------- +// +TInt DEthernetFrameMemMngr::DoAllocate( DChunk*& /*aSharedMemoryChunk*/ ) + { + TraceDump( INIT_LEVEL, + ("WLANLDD: DEthernetFrameMemMngr::DoAllocate") ); + + return KErrNone; + } + +// --------------------------------------------------------------------------- +// this default implementation always returns NULL +// --------------------------------------------------------------------------- +// +TUint8* DEthernetFrameMemMngr::DoGetNextFreeRxBuffer( + TUint /*aLengthinBytes*/ ) + { + TraceDump( RX_FRAME, + ("WLANLDD: DEthernetFrameMemMngr::DoGetNextFreeRxBuffer") ); + + return NULL; + } + +// --------------------------------------------------------------------------- +// This default implementation always returns NULL +// --------------------------------------------------------------------------- +// +TDataBuffer* DEthernetFrameMemMngr::AllocTxBuffer( TUint aLength ) + { + return NULL; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TBool DEthernetFrameMemMngr::AddTxFrame( + TDataBuffer* aPacketInUserSpace, + TDataBuffer*& aPacketInKernSpace, + TBool aUserDataTxEnabled ) + { + return (static_cast( + iFrameXferBlock))->AddTxFrame( + aPacketInUserSpace, + aPacketInKernSpace, + aUserDataTxEnabled ); + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TDataBuffer* DEthernetFrameMemMngr::GetTxFrame( + const TWhaTxQueueState& aTxQueueState, + TBool& aMore ) + { + if ( IsMemInUse() ) + { + return (static_cast( + iFrameXferBlock))->GetTxFrame( aTxQueueState, aMore ); + } + else + return NULL; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void DEthernetFrameMemMngr::FreeTxPacket( TDataBuffer*& /*aPacket*/ ) + { + // not suported in this default implementation + os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ ); + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TBool DEthernetFrameMemMngr::ResumeClientTx( TBool aUserDataTxEnabled ) const + { + return (static_cast( + iFrameXferBlock))->ResumeClientTx( aUserDataTxEnabled ); + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TBool DEthernetFrameMemMngr::AllTxQueuesEmpty() const + { + return (static_cast( + iFrameXferBlock))->AllTxQueuesEmpty(); + }