wlan_bearer/wlanldd/wlan_symbian/wlanldd_symbian/src/EthernetFrameMemMngr.cpp
changeset 0 c40eb8fe8501
child 3 6524e815f76f
--- /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 <kernel.h> 
+#include <kern_priv.h>
+
+#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<TUint32>(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<TDataBuffer*>(
+            iRxFrameMemoryPool->Alloc( sizeof( TDataBuffer ), ETrue ) );
+
+        TraceDump(RX_FRAME, 
+           (("WLANLDD: DEthernetFrameMemMngr::GetRxFrameMetaHeader: addr: 0x%08x"),
+           reinterpret_cast<TUint32>(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<RFrameXferBlockProtocolStack*>(
+        iFrameXferBlock))->AddTxFrame( 
+            aPacketInUserSpace, 
+            aPacketInKernSpace,
+            aUserDataTxEnabled );
+    }
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+TDataBuffer* DEthernetFrameMemMngr::GetTxFrame( 
+    const TWhaTxQueueState& aTxQueueState,
+    TBool& aMore )
+    {
+    if ( IsMemInUse() )
+        {
+        return (static_cast<RFrameXferBlockProtocolStack*>(
+            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<RFrameXferBlockProtocolStack*>(
+        iFrameXferBlock))->ResumeClientTx( aUserDataTxEnabled );
+    }
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+TBool DEthernetFrameMemMngr::AllTxQueuesEmpty() const
+    {
+    return (static_cast<RFrameXferBlockProtocolStack*>(
+            iFrameXferBlock))->AllTxQueuesEmpty();
+    }