wlan_bearer/wlanldd/wlan_symbian/wlanldd_symbian/src/EthernetFrameMemMngr.cpp
changeset 0 c40eb8fe8501
child 3 6524e815f76f
equal deleted inserted replaced
-1:000000000000 0:c40eb8fe8501
       
     1 /*
       
     2 * Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:   Implementation of the DEthernetFrameMemMngr class.
       
    15 *
       
    16 */
       
    17 
       
    18 /*
       
    19 * %version: 23 %
       
    20 */
       
    21 
       
    22 #include "WlLddWlanLddConfig.h"
       
    23 #include "DataFrameMemMngr.h"
       
    24 #include "MgmtFrameMemMngr.h"
       
    25 #include "osachunk.h"
       
    26 #include <kernel.h> 
       
    27 #include <kern_priv.h>
       
    28 
       
    29 #include "EtherCardApi.h"
       
    30 
       
    31 extern void os_free( const TAny* );
       
    32 
       
    33 // ---------------------------------------------------------------------------
       
    34 // 
       
    35 // ---------------------------------------------------------------------------
       
    36 //
       
    37 DEthernetFrameMemMngr* DEthernetFrameMemMngr::Init( 
       
    38     TInt aUnit, 
       
    39     DWlanLogicalChannel& aParent,
       
    40     WlanChunk*& aRxFrameMemoryPool,
       
    41     TBool aUseCachedMemory,
       
    42     TInt aFrameBufAllocationUnit )
       
    43     {
       
    44     DEthernetFrameMemMngr* ret = NULL;
       
    45 
       
    46     if ( aUnit == KUnitEthernet )
       
    47         {
       
    48         ret = new DataFrameMemMngr( 
       
    49             aParent, 
       
    50             aRxFrameMemoryPool,
       
    51             aFrameBufAllocationUnit );
       
    52         }
       
    53     else if ( aUnit == KUnitWlan )
       
    54         {
       
    55         ret = new MgmtFrameMemMngr( 
       
    56             aParent, 
       
    57             aRxFrameMemoryPool,
       
    58             aUseCachedMemory,
       
    59             aFrameBufAllocationUnit );
       
    60         }
       
    61     else
       
    62         {
       
    63         TraceDump(ERROR_LEVEL, 
       
    64         (("WLANLDD: DEthernetFrameMemMngr::Init: ERROR: unknown unit: %d"), 
       
    65             aUnit));
       
    66         // No action. NULL is returned
       
    67         }
       
    68 
       
    69     if ( ret )
       
    70         {
       
    71         TraceDump(MEMORY, (("WLANLDD: new FrameMemMngr: 0x%08x"), 
       
    72             reinterpret_cast<TUint32>(ret)));
       
    73         }
       
    74 
       
    75     return ret;
       
    76     }
       
    77 
       
    78 // ---------------------------------------------------------------------------
       
    79 // 
       
    80 // ---------------------------------------------------------------------------
       
    81 //
       
    82 TInt DEthernetFrameMemMngr::OnInitialiseMemory( 
       
    83     DThread& aThread,
       
    84     TSharedChunkInfo* aSharedChunkInfo,
       
    85     TUint aVendorTxHdrLen,
       
    86     TUint aVendorTxTrailerLen )
       
    87     {    
       
    88     TraceDump( INIT_LEVEL, 
       
    89         (("WLANLDD: DEthernetFrameMemMngr::OnInitialiseMemory: aVendorTxHdrLen: %d"),
       
    90         aVendorTxHdrLen ) );
       
    91     TraceDump( INIT_LEVEL, 
       
    92         (("WLANLDD: aVendorTxTrailerLen: %d"),
       
    93         aVendorTxTrailerLen ) );
       
    94     
       
    95     TInt ret( KErrGeneral );
       
    96     
       
    97     iVendorTxHdrLen = aVendorTxHdrLen;
       
    98     iVendorTxTrailerLen = aVendorTxTrailerLen;    
       
    99     
       
   100     // Local info structure we will fill in
       
   101     TSharedChunkInfo info;
       
   102 
       
   103     if( !IsMemInUse() )
       
   104         {
       
   105         ret = DoAllocate( iParent.SharedMemoryChunk() );
       
   106         
       
   107         if ( ret == KErrNone )
       
   108             {
       
   109             ret = DoOpenHandle( aThread, info, iParent.SharedMemoryChunk() );
       
   110             
       
   111             if ( ret == KErrNone )
       
   112                 {
       
   113                 MarkMemInUSe();     // mark as in use
       
   114                 ret = KErrNone;
       
   115                 }
       
   116             else
       
   117                 {
       
   118                 // handle creation & open failed
       
   119 
       
   120                 TraceDump( INIT_LEVEL, 
       
   121                     (("WLANLDD: DEthernetFrameMemMngr::OnInitialiseMemory: Handle create & open error: status: %d"),
       
   122                     ret ) );
       
   123 
       
   124                 // zero contents of info structure.
       
   125                 // (Zero is usually a safe value to return on error for most data types,
       
   126                 // and for object handles this is same as KNullHandle)
       
   127                 memclr( &info, sizeof( info ) );
       
   128 
       
   129                 // need to enter critical section for chunk closing
       
   130                 NKern::ThreadEnterCS();
       
   131                 
       
   132                 // schedule the shared memory chunk for destruction
       
   133                 Kern::ChunkClose( iParent.SharedMemoryChunk() );
       
   134 
       
   135                 // leave critical section 
       
   136                 NKern::ThreadLeaveCS();
       
   137                 }
       
   138 
       
   139             // write handle info to client memory
       
   140             ret = Kern::ThreadRawWrite( 
       
   141                 &aThread, 
       
   142                 aSharedChunkInfo, 
       
   143                 &info,
       
   144                 sizeof( info ) );
       
   145             if ( ret != KErrNone )
       
   146                 {
       
   147                 TraceDump(ERROR_LEVEL, ("WLANLDD: ThreadRawWrite panic"));
       
   148                 TraceDump(ERROR_LEVEL, (("WLANLDD: ret: %d"), ret));
       
   149                 os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
       
   150                 }
       
   151             }
       
   152         else
       
   153             {
       
   154             // allocation failed; error code will be returned
       
   155             }
       
   156         }
       
   157     else
       
   158         {
       
   159         ret = KErrAlreadyExists;
       
   160         }
       
   161 
       
   162     return ret;
       
   163     }
       
   164 
       
   165 // ---------------------------------------------------------------------------
       
   166 // 
       
   167 // ---------------------------------------------------------------------------
       
   168 //
       
   169 DEthernetFrameMemMngr::~DEthernetFrameMemMngr()
       
   170     {
       
   171     OnReleaseMemory();
       
   172     
       
   173     iFrameXferBlock = NULL;
       
   174     iTxDataBuffer = NULL;
       
   175     iRxDataChunk = NULL;
       
   176     }
       
   177 
       
   178 // ---------------------------------------------------------------------------
       
   179 // 
       
   180 // ---------------------------------------------------------------------------
       
   181 //
       
   182 void DEthernetFrameMemMngr::OnReleaseMemory()
       
   183     {
       
   184     MarkMemFree();      // mark as free
       
   185     }
       
   186 
       
   187 // ---------------------------------------------------------------------------
       
   188 // 
       
   189 // ---------------------------------------------------------------------------
       
   190 //
       
   191 TDataBuffer* DEthernetFrameMemMngr::OnWriteEthernetFrame() const
       
   192     {
       
   193     if ( iTxDataBuffer->GetLength() >= sizeof( SEthernetHeader ) )
       
   194         {
       
   195         return iTxDataBuffer;
       
   196         }
       
   197     else
       
   198         {
       
   199         os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
       
   200         return NULL;
       
   201         }
       
   202     }
       
   203 
       
   204 // ---------------------------------------------------------------------------
       
   205 // 
       
   206 // ---------------------------------------------------------------------------
       
   207 //
       
   208 TBool DEthernetFrameMemMngr::OnReadRequest()
       
   209     {
       
   210     TBool ret( EFalse );
       
   211 
       
   212     if ( IsMemInUse() )
       
   213         {
       
   214         if ( iCountCompleted )
       
   215             {
       
   216             // free relevant buffers
       
   217             DoFreeRxBuffers();
       
   218             iCountCompleted = 0; // no buffers anymore in process in user mode
       
   219             
       
   220             // make sure that the same buffers are not tried to be
       
   221             // freed again thru the incremental freeing method
       
   222             iFrameXferBlock->KeAllUserSideRxBuffersFreed();
       
   223             }
       
   224 
       
   225         if ( iCountTobeCompleted )
       
   226             {
       
   227             // there are Rx buffers to be completed
       
   228             
       
   229             iFrameXferBlock->KeRxComplete( DoGetTobeCompletedBuffersStart(), 
       
   230                 iCountTobeCompleted );  
       
   231             // mark the completed buffers
       
   232             assign( DoGetTobeCompletedBuffersStart(), 
       
   233                 DoGetCompletedBuffersStart(), 
       
   234                 iCountTobeCompleted );
       
   235             iCountCompleted = iCountTobeCompleted;
       
   236             iCountTobeCompleted = 0;
       
   237 
       
   238             ret = ETrue;
       
   239              // the frame Rx request won't be pending as the callee shall 
       
   240              // complete it
       
   241             iReadStatus = ENotPending;
       
   242             }
       
   243         else
       
   244             {
       
   245             // there are no Rx buffers to be completed. The Rx request is
       
   246             // left pending
       
   247             iReadStatus = EPending;
       
   248             }
       
   249         }
       
   250     else
       
   251         {
       
   252         os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
       
   253         }
       
   254 
       
   255     return ret;
       
   256     }
       
   257 
       
   258 // ---------------------------------------------------------------------------
       
   259 // 
       
   260 // ---------------------------------------------------------------------------
       
   261 //
       
   262 void DEthernetFrameMemMngr::DoMarkRxBufFree( TUint8* /*aBufferToFree*/ )
       
   263     {
       
   264     // not supported in default handler
       
   265     os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
       
   266     }
       
   267 
       
   268 // ---------------------------------------------------------------------------
       
   269 // 
       
   270 // ---------------------------------------------------------------------------
       
   271 //
       
   272 void DEthernetFrameMemMngr::SetTxOffsets( 
       
   273     TUint32 aEthernetFrameTxOffset,
       
   274     TUint32 aDot11FrameTxOffset,
       
   275     TUint32 aSnapFrameTxOffset )
       
   276     {
       
   277     if ( IsMemInUse() )
       
   278         {
       
   279         iFrameXferBlock->KeSetTxOffsets(
       
   280             aEthernetFrameTxOffset,
       
   281             aDot11FrameTxOffset,
       
   282             aSnapFrameTxOffset );
       
   283         }
       
   284     }
       
   285 
       
   286 // ---------------------------------------------------------------------------
       
   287 // 
       
   288 // ---------------------------------------------------------------------------
       
   289 //
       
   290 TUint8* DEthernetFrameMemMngr::OnGetEthernetFrameRxBuffer( 
       
   291     TUint aLengthinBytes )
       
   292     {
       
   293     TUint8* buffer ( NULL );
       
   294 
       
   295     if ( IsMemInUse() )
       
   296         {
       
   297         buffer = DoGetNextFreeRxBuffer( aLengthinBytes );
       
   298         }
       
   299     else
       
   300         {
       
   301         // we are trying to acquire an Rx buffer but our user mode client 
       
   302         // has not asked for the memorybuffer pool to be initialized. In this
       
   303         // case NULL is returned, as no buffers are available
       
   304          TraceDump(RX_FRAME, 
       
   305             ("WLANLDD: DEthernetFrameMemMngr::OnGetEthernetFrameRxBuffer: not initialized => failed"));       
       
   306         }
       
   307 
       
   308     return buffer;
       
   309     }
       
   310 
       
   311 // ---------------------------------------------------------------------------
       
   312 // 
       
   313 // ---------------------------------------------------------------------------
       
   314 //
       
   315 TDataBuffer* DEthernetFrameMemMngr::GetRxFrameMetaHeader()
       
   316     {
       
   317     TDataBuffer* buffer ( NULL );
       
   318 
       
   319     if ( IsMemInUse() )
       
   320         {
       
   321         buffer = reinterpret_cast<TDataBuffer*>(
       
   322             iRxFrameMemoryPool->Alloc( sizeof( TDataBuffer ), ETrue ) );
       
   323 
       
   324         TraceDump(RX_FRAME, 
       
   325            (("WLANLDD: DEthernetFrameMemMngr::GetRxFrameMetaHeader: addr: 0x%08x"),
       
   326            reinterpret_cast<TUint32>(buffer)) );        
       
   327         }
       
   328     else
       
   329         {
       
   330         // we are trying to acquire memory for Rx frame meta header but our 
       
   331         // user mode client has not asked for the memorybuffer pool to be 
       
   332         // initialized. In this case NULL is returned, as no memory is 
       
   333         // available
       
   334          TraceDump(RX_FRAME, 
       
   335             ("WLANLDD: DEthernetFrameMemMngr::GetRxFrameMetaHeader: not initialized => failed"));       
       
   336         }
       
   337 
       
   338     return buffer;
       
   339     }
       
   340 
       
   341 // ---------------------------------------------------------------------------
       
   342 // 
       
   343 // ---------------------------------------------------------------------------
       
   344 //
       
   345 void DEthernetFrameMemMngr::FreeRxFrameMetaHeader( TDataBuffer* aMetaHeader )
       
   346     {
       
   347     if ( IsMemInUse() )
       
   348         {
       
   349         iRxFrameMemoryPool->Free( aMetaHeader );
       
   350         }
       
   351     else
       
   352         {
       
   353         // the whole Rx memory pool - including aMetaHeader - has already
       
   354         // been deallocated, so nothing is done in this case
       
   355         TraceDump( RX_FRAME, 
       
   356             ("WLANLDD: MgmtFrameMemMngr::FreeRxFrameMetaHeader: Rx memory pool already deallocated; no action needed") );                
       
   357         }    
       
   358     }
       
   359 
       
   360 // ---------------------------------------------------------------------------
       
   361 // 
       
   362 // ---------------------------------------------------------------------------
       
   363 //
       
   364 TBool DEthernetFrameMemMngr::OnEthernetFrameRxComplete( 
       
   365     const TDataBuffer*& aBufferStart, 
       
   366     TUint32 aNumOfBuffers )
       
   367     {
       
   368     TBool ret( EFalse );
       
   369 
       
   370     if ( IsMemInUse() && 
       
   371          DoEthernetFrameRxComplete( aBufferStart, aNumOfBuffers ) )
       
   372         {
       
   373         iReadStatus = ENotPending;
       
   374         ret = ETrue;
       
   375         }
       
   376 
       
   377     return ret;
       
   378     }
       
   379 
       
   380 // ---------------------------------------------------------------------------
       
   381 // this default implementation always returns KErrNone
       
   382 // ---------------------------------------------------------------------------
       
   383 //
       
   384 TInt DEthernetFrameMemMngr::DoAllocate( DChunk*& /*aSharedMemoryChunk*/ )
       
   385     {
       
   386     TraceDump( INIT_LEVEL, 
       
   387         ("WLANLDD: DEthernetFrameMemMngr::DoAllocate") );
       
   388 
       
   389     return KErrNone;
       
   390     }
       
   391 
       
   392 // ---------------------------------------------------------------------------
       
   393 // this default implementation always returns NULL
       
   394 // ---------------------------------------------------------------------------
       
   395 //
       
   396 TUint8* DEthernetFrameMemMngr::DoGetNextFreeRxBuffer( 
       
   397     TUint /*aLengthinBytes*/ )
       
   398     {
       
   399     TraceDump( RX_FRAME, 
       
   400         ("WLANLDD: DEthernetFrameMemMngr::DoGetNextFreeRxBuffer") );
       
   401 
       
   402     return NULL;
       
   403     }
       
   404 
       
   405 // ---------------------------------------------------------------------------
       
   406 // This default implementation always returns NULL
       
   407 // ---------------------------------------------------------------------------
       
   408 //
       
   409 TDataBuffer* DEthernetFrameMemMngr::AllocTxBuffer( TUint aLength )
       
   410     {
       
   411     return NULL;
       
   412     }
       
   413 
       
   414 // ---------------------------------------------------------------------------
       
   415 // 
       
   416 // ---------------------------------------------------------------------------
       
   417 //
       
   418 TBool DEthernetFrameMemMngr::AddTxFrame( 
       
   419     TDataBuffer* aPacketInUserSpace, 
       
   420     TDataBuffer*& aPacketInKernSpace,
       
   421     TBool aUserDataTxEnabled )
       
   422     {
       
   423     return (static_cast<RFrameXferBlockProtocolStack*>(
       
   424         iFrameXferBlock))->AddTxFrame( 
       
   425             aPacketInUserSpace, 
       
   426             aPacketInKernSpace,
       
   427             aUserDataTxEnabled );
       
   428     }
       
   429 
       
   430 // ---------------------------------------------------------------------------
       
   431 // 
       
   432 // ---------------------------------------------------------------------------
       
   433 //
       
   434 TDataBuffer* DEthernetFrameMemMngr::GetTxFrame( 
       
   435     const TWhaTxQueueState& aTxQueueState,
       
   436     TBool& aMore )
       
   437     {
       
   438     if ( IsMemInUse() )
       
   439         {
       
   440         return (static_cast<RFrameXferBlockProtocolStack*>(
       
   441             iFrameXferBlock))->GetTxFrame( aTxQueueState, aMore );
       
   442         }
       
   443     else
       
   444         return NULL;
       
   445     }
       
   446 
       
   447 // ---------------------------------------------------------------------------
       
   448 // 
       
   449 // ---------------------------------------------------------------------------
       
   450 //
       
   451 void DEthernetFrameMemMngr::FreeTxPacket( TDataBuffer*& /*aPacket*/ )
       
   452     {
       
   453     // not suported in this default implementation 
       
   454     os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
       
   455     }
       
   456 
       
   457 // ---------------------------------------------------------------------------
       
   458 // 
       
   459 // ---------------------------------------------------------------------------
       
   460 //
       
   461 TBool DEthernetFrameMemMngr::ResumeClientTx( TBool aUserDataTxEnabled ) const 
       
   462     {
       
   463     return (static_cast<RFrameXferBlockProtocolStack*>(
       
   464         iFrameXferBlock))->ResumeClientTx( aUserDataTxEnabled );
       
   465     }
       
   466 
       
   467 // ---------------------------------------------------------------------------
       
   468 // 
       
   469 // ---------------------------------------------------------------------------
       
   470 //
       
   471 TBool DEthernetFrameMemMngr::AllTxQueuesEmpty() const
       
   472     {
       
   473     return (static_cast<RFrameXferBlockProtocolStack*>(
       
   474             iFrameXferBlock))->AllTxQueuesEmpty();
       
   475     }