wlan_bearer/wlanldd/wlan_symbian/wlanldd_symbian/src/DataFrameMemMngr.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 DataFrameMemMngr class.
       
    15 *
       
    16 */
       
    17 
       
    18 /*
       
    19 * %version: 17 %
       
    20 */
       
    21 
       
    22 #include "WlLddWlanLddConfig.h"
       
    23 #include "DataFrameMemMngr.h"
       
    24 #include "osachunk.h"
       
    25 #include <kernel.h> 
       
    26 #include <kern_priv.h>
       
    27 
       
    28 // ---------------------------------------------------------------------------
       
    29 // 
       
    30 // ---------------------------------------------------------------------------
       
    31 //
       
    32 TInt DataFrameMemMngr::DoOpenHandle(
       
    33     DThread& aThread,
       
    34     TSharedChunkInfo& aSharedChunkInfo,
       
    35     DChunk* aSharedMemoryChunk )
       
    36     {
       
    37     TInt ret ( KErrGeneral );
       
    38 
       
    39     if ( aSharedMemoryChunk )
       
    40         {
       
    41         
       
    42         // Need to be in critical section while creating handles
       
    43         NKern::ThreadEnterCS();
       
    44 
       
    45         // Make handle to shared memory chunk for client thread
       
    46         TInt r = Kern::MakeHandleAndOpen( &aThread, aSharedMemoryChunk );
       
    47 
       
    48         // Leave critical section 
       
    49         NKern::ThreadLeaveCS();
       
    50 
       
    51         // r: positive value is a handle, negative value is an error code
       
    52         if( r >= 0 )
       
    53             {
       
    54             // mapping success
       
    55 
       
    56             TraceDump( INIT_LEVEL, 
       
    57                 (("WLANLDD: DataFrameMemMngr::DoOpenHandle: Handle create & open ok: handle: %d"),
       
    58                 r ) );
       
    59     
       
    60             // store the handle & chunk size
       
    61             aSharedChunkInfo.iChunkHandle = r;
       
    62             aSharedChunkInfo.iSize = aSharedMemoryChunk->Size();
       
    63 
       
    64             // store the kernel addresses
       
    65 
       
    66             TLinAddr start_of_mem_linear( 0 );
       
    67             aSharedMemoryChunk->Address( 0, aSharedChunkInfo.iSize, start_of_mem_linear );
       
    68 
       
    69             TraceDump( INIT_LEVEL, 
       
    70                 (("WLANLDD: DataFrameMemMngr::DoOpenHandle: chunk kernel mode start addr: 0x%08x"),
       
    71                 start_of_mem_linear ) );
       
    72 
       
    73             TUint8* start_of_mem = reinterpret_cast<TUint8*>(start_of_mem_linear );
       
    74 
       
    75             const TUint KRxDataChunkSize( 
       
    76                 aSharedChunkInfo.iSize 
       
    77                 - ( sizeof( TDataBuffer )
       
    78                     + KMgmtSideTxBufferLength
       
    79                     + KProtocolStackSideTxDataChunkSize
       
    80                     + sizeof( RFrameXferBlock )
       
    81                     + sizeof( RFrameXferBlockProtocolStack ) ) );
       
    82 
       
    83             TraceDump( INIT_LEVEL, 
       
    84                 (("WLANLDD: DataFrameMemMngr::DoOpenHandle: KRxDataChunkSize: %d"),
       
    85                 KRxDataChunkSize ) );
       
    86 
       
    87             iRxDataChunk = start_of_mem;
       
    88 
       
    89             TraceDump( INIT_LEVEL, 
       
    90                 (("WLANLDD: DataFrameMemMngr::DoOpenHandle: iRxDataChunk start addr: 0x%08x"),
       
    91                 reinterpret_cast<TUint32>(iRxDataChunk) ) );
       
    92             TraceDump( INIT_LEVEL, 
       
    93                 (("WLANLDD: DataFrameMemMngr::DoOpenHandle: iRxDataChunk end addr: 0x%08x"),
       
    94                 reinterpret_cast<TUint32>(iRxDataChunk + KRxDataChunkSize) ) );
       
    95 
       
    96             iTxDataChunk = 
       
    97                 start_of_mem  
       
    98                 + KRxDataChunkSize 
       
    99                 + sizeof( TDataBuffer ) 
       
   100                 + KMgmtSideTxBufferLength;
       
   101 
       
   102             TraceDump( INIT_LEVEL, 
       
   103                 (("WLANLDD: DataFrameMemMngr::DoOpenHandle: iTxDataChunk start addr: 0x%08x"),
       
   104                 reinterpret_cast<TUint32>(iTxDataChunk) ) );
       
   105             TraceDump( INIT_LEVEL, 
       
   106                 (("WLANLDD: DataFrameMemMngr::DoOpenHandle: iTxDataChunk end addr: 0x%08x"),
       
   107                 reinterpret_cast<TUint32>(
       
   108                     iTxDataChunk + KProtocolStackSideTxDataChunkSize) ) );
       
   109 
       
   110             // create the Tx frame memory pool manager to manage the Tx Data
       
   111             // chunk
       
   112             iTxFrameMemoryPool = new WlanChunk( 
       
   113                 iTxDataChunk, 
       
   114                 iTxDataChunk + KProtocolStackSideTxDataChunkSize,
       
   115                 iTxFrameBufAllocationUnit );
       
   116             
       
   117             if ( iTxFrameMemoryPool && iTxFrameMemoryPool->IsValid() )
       
   118                 {
       
   119                 TraceDump(MEMORY, (("WLANLDD: new WlanChunk: 0x%08x"), 
       
   120                     reinterpret_cast<TUint32>(iTxFrameMemoryPool)));
       
   121 
       
   122                 iFrameXferBlock = reinterpret_cast<RFrameXferBlock*>(
       
   123                     start_of_mem  
       
   124                     + KRxDataChunkSize 
       
   125                     + sizeof( TDataBuffer ) 
       
   126                     + KMgmtSideTxBufferLength
       
   127                     + KProtocolStackSideTxDataChunkSize
       
   128                     + sizeof( RFrameXferBlock ) );
       
   129                 
       
   130                 iFrameXferBlockProtoStack = 
       
   131                     static_cast<RFrameXferBlockProtocolStack*>(iFrameXferBlock);
       
   132                 
       
   133                 TraceDump( INIT_LEVEL, 
       
   134                     (("WLANLDD: DataFrameMemMngr::DoOpenHandle: Nif RFrameXferBlock addr: 0x%08x"),
       
   135                     reinterpret_cast<TUint32>(iFrameXferBlockProtoStack) ) );
       
   136     
       
   137                 // initiliase xfer block
       
   138                 iFrameXferBlockProtoStack->Initialise();
       
   139                 
       
   140                 iRxBufAlignmentPadding = iParent.RxBufAlignmentPadding();
       
   141                 
       
   142                 ret = KErrNone;
       
   143                 }
       
   144             else
       
   145                 {
       
   146                 // create failed
       
   147                 delete iTxFrameMemoryPool;
       
   148                 iTxFrameMemoryPool = NULL;
       
   149                 // error is returned
       
   150                 }
       
   151             }
       
   152         else
       
   153             {
       
   154             // handle creation & open failed. Error is returned
       
   155 
       
   156             TraceDump( INIT_LEVEL | ERROR_LEVEL, 
       
   157                 (("WLANLDD: DataFrameMemMngr::OnInitialiseMemory: Handle create & open error: %d"),
       
   158                 r ) );            
       
   159             }
       
   160         }
       
   161     else
       
   162         {
       
   163         // at this point the shared memory chunk should always exist. However,
       
   164         // as it doesn't exist in this case, we return an error
       
   165 
       
   166         TraceDump( INIT_LEVEL | ERROR_LEVEL, 
       
   167             ("WLANLDD: DataFrameMemMngr::OnInitialiseMemory: Error aSharedMemoryChunk is NULL") );
       
   168         }    
       
   169     
       
   170     return ret;    
       
   171     }
       
   172 
       
   173 // ---------------------------------------------------------------------------
       
   174 // 
       
   175 // ---------------------------------------------------------------------------
       
   176 //
       
   177 void DataFrameMemMngr::DoFreeRxBuffers()
       
   178     {
       
   179     for ( TUint i = 0; i < iCountCompleted; ++i )
       
   180         {
       
   181         TDataBuffer* metaHdr ( reinterpret_cast<TDataBuffer*>(
       
   182             iRxDataChunk + iCompletedBuffers[i]) );  
       
   183         
       
   184         // first free the actual Rx frame buffer if relevant
       
   185         if ( metaHdr->KeFlags() & TDataBuffer::KDontReleaseBuffer )
       
   186             {
       
   187             // this buffer shall not be freed yet, so no action here
       
   188             
       
   189             TraceDump( RX_FRAME, 
       
   190                 (("WLANLDD: DataFrameMemMngr::DoFreeRxBuffers: don't free yet Rx buf at addr: 0x%08x"),
       
   191                 reinterpret_cast<TUint32>(metaHdr->KeGetBufferStart()) ) );            
       
   192             }
       
   193         else
       
   194             {
       
   195             TraceDump( RX_FRAME, 
       
   196                 (("WLANLDD: DataFrameMemMngr::DoFreeRxBuffers: free Rx buf at addr: 0x%08x"),
       
   197                 reinterpret_cast<TUint32>(metaHdr->KeGetBufferStart()) ) );
       
   198     
       
   199             iRxFrameMemoryPool->Free( 
       
   200                 metaHdr->KeGetBufferStart()
       
   201                 // take into account the alignment padding 
       
   202                 - iRxBufAlignmentPadding );
       
   203             }
       
   204         
       
   205         // free the Rx frame meta header
       
   206 
       
   207         TraceDump( RX_FRAME, 
       
   208             (("WLANLDD: DataFrameMemMngr::DoFreeRxBuffers: free Rx meta header at addr: 0x%08x"),
       
   209             reinterpret_cast<TUint32>(metaHdr)) );
       
   210 
       
   211         iRxFrameMemoryPool->Free( metaHdr );        
       
   212         }
       
   213     }
       
   214 
       
   215 // ---------------------------------------------------------------------------
       
   216 // 
       
   217 // ---------------------------------------------------------------------------
       
   218 //
       
   219 TBool DataFrameMemMngr::DoEthernetFrameRxComplete( 
       
   220     const TDataBuffer*& aBufferStart, 
       
   221     TUint32 aNumOfBuffers )
       
   222     {
       
   223     TraceDump( RX_FRAME, 
       
   224         (("WLANLDD: DataFrameMemMngr::DoEthernetFrameRxComplete: aNumOfBuffers: %d"), 
       
   225         aNumOfBuffers) );
       
   226 
       
   227     if ( aNumOfBuffers + iCountTobeCompleted > KMaxToBeCompletedRxBufs )
       
   228         {
       
   229         // too little space reserved for Rx buffer handles
       
   230         os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
       
   231         }
       
   232 
       
   233     TBool ret( EFalse );
       
   234 
       
   235     if ( iReadStatus == EPending )
       
   236         {
       
   237         // read pending
       
   238         if ( !iCountTobeCompleted )
       
   239             {
       
   240             // no existing Rx buffers to complete in queue
       
   241             // we may complete these ones on the fly
       
   242             
       
   243             // note the completed Rx buffers first so that we can change
       
   244             // their addresses to offsets
       
   245             assign( 
       
   246                 reinterpret_cast<TUint32*>(&aBufferStart), 
       
   247                 iCompletedBuffers, 
       
   248                 aNumOfBuffers );
       
   249 
       
   250             // update the new Rx buffer start addresses added above to be 
       
   251             // offsets from the Rx memory pool beginning
       
   252             for( TUint i = 0; i < aNumOfBuffers; ++i )
       
   253                 {
       
   254                 TraceDump( RX_FRAME, 
       
   255                     (("WLANLDD: DataFrameMemMngr::DoEthernetFrameRxComplete: supplied Rx buf addr: 0x%08x"), 
       
   256                     iCompletedBuffers[i]) );        
       
   257                 
       
   258                 iCompletedBuffers[i] 
       
   259                     -= reinterpret_cast<TUint32>(iRxDataChunk);
       
   260 
       
   261                 TraceDump( RX_FRAME, 
       
   262                     (("WLANLDD: DataFrameMemMngr::DoEthernetFrameRxComplete: Rx buf offset addr: 0x%08x"), 
       
   263                     iCompletedBuffers[i]) );        
       
   264                 }
       
   265 
       
   266             iCountCompleted = aNumOfBuffers;
       
   267 
       
   268             iFrameXferBlock->KeRxComplete( iCompletedBuffers, iCountCompleted);
       
   269             }
       
   270         else
       
   271             {
       
   272             // existing rx buffers to complete in queue.
       
   273             // We must append these at the rear and after that 
       
   274             // complete the existing read request
       
   275             assign( 
       
   276                 reinterpret_cast<TUint32*>(&aBufferStart),
       
   277                 iTobeCompletedBuffers + iCountTobeCompleted, 
       
   278                 aNumOfBuffers );
       
   279 
       
   280             // update the new Rx buffer start addresses added above to be 
       
   281             // offsets from the Rx memory pool beginning
       
   282             for( TUint i = 0; i < aNumOfBuffers; ++i )
       
   283                 {
       
   284                 TraceDump( RX_FRAME, 
       
   285                     (("WLANLDD: DataFrameMemMngr::DoEthernetFrameRxComplete: supplied Rx buf addr: 0x%08x"), 
       
   286                     iTobeCompletedBuffers[iCountTobeCompleted + i]) );
       
   287 
       
   288                 iTobeCompletedBuffers[iCountTobeCompleted + i] 
       
   289                     -= reinterpret_cast<TUint32>(iRxDataChunk);
       
   290 
       
   291                 TraceDump( RX_FRAME, 
       
   292                     (("WLANLDD: DataFrameMemMngr::DoEthernetFrameRxComplete: Rx buf offset addr: 0x%08x"), 
       
   293                     iTobeCompletedBuffers[iCountTobeCompleted + i]) );
       
   294                 }
       
   295 
       
   296             iCountCompleted = iCountTobeCompleted + aNumOfBuffers;
       
   297 
       
   298             iFrameXferBlock->KeRxComplete( 
       
   299                 iTobeCompletedBuffers, 
       
   300                 iCountCompleted );  
       
   301 
       
   302             // note the completed Rx buffers
       
   303             assign( iTobeCompletedBuffers, iCompletedBuffers, iCountCompleted );
       
   304             iCountTobeCompleted = 0;
       
   305             }
       
   306 
       
   307         ret = ETrue;
       
   308         }
       
   309     else
       
   310         {
       
   311         // no read pending
       
   312         // append at the rear
       
   313         assign( 
       
   314             reinterpret_cast<TUint32*>(&aBufferStart),
       
   315             iTobeCompletedBuffers + iCountTobeCompleted, 
       
   316             aNumOfBuffers );
       
   317 
       
   318         // update the new Rx buffer start addresses added above to be 
       
   319         // offsets from the Rx memory pool beginning
       
   320         for( TUint i = 0; i < aNumOfBuffers; ++i )
       
   321             {
       
   322             TraceDump( RX_FRAME, 
       
   323                 (("WLANLDD: DataFrameMemMngr::DoEthernetFrameRxComplete: supplied Rx buf addr: 0x%08x"), 
       
   324                 iTobeCompletedBuffers[iCountTobeCompleted + i]) );        
       
   325                 
       
   326             iTobeCompletedBuffers[iCountTobeCompleted + i] 
       
   327                 -= reinterpret_cast<TUint32>(iRxDataChunk);
       
   328 
       
   329             TraceDump( RX_FRAME, 
       
   330                 (("WLANLDD: DataFrameMemMngr::DoEthernetFrameRxComplete: Rx buf offset addr: 0x%08x"), 
       
   331                 iTobeCompletedBuffers[iCountTobeCompleted + i]) );        
       
   332             }
       
   333         
       
   334         iCountTobeCompleted += aNumOfBuffers;
       
   335         }
       
   336     
       
   337     TraceDump( RX_FRAME, 
       
   338         (("WLANLDD: DataFrameMemMngr::DoEthernetFrameRxComplete: end: iCountCompleted: %d"), 
       
   339         iCountCompleted) );
       
   340 
       
   341     TraceDump( RX_FRAME, 
       
   342         (("WLANLDD: DataFrameMemMngr::DoEthernetFrameRxComplete: end: iCountTobeCompleted: %d"), 
       
   343         iCountTobeCompleted) );
       
   344 
       
   345     return ret;
       
   346     }
       
   347 
       
   348 // ---------------------------------------------------------------------------
       
   349 // 
       
   350 // ---------------------------------------------------------------------------
       
   351 //
       
   352 TUint32* DataFrameMemMngr::DoGetTobeCompletedBuffersStart()
       
   353     {
       
   354     return iTobeCompletedBuffers;
       
   355     }
       
   356 
       
   357 // ---------------------------------------------------------------------------
       
   358 // 
       
   359 // ---------------------------------------------------------------------------
       
   360 //
       
   361 TUint32* DataFrameMemMngr::DoGetCompletedBuffersStart()
       
   362     {
       
   363     return iCompletedBuffers;
       
   364     }
       
   365 
       
   366 // ---------------------------------------------------------------------------
       
   367 // 
       
   368 // ---------------------------------------------------------------------------
       
   369 //
       
   370 TDataBuffer* DataFrameMemMngr::AllocTxBuffer( TUint aLength )
       
   371     {
       
   372     TraceDump( NWSA_TX_DETAILS, 
       
   373         (("WLANLDD: DataFrameMemMngr::AllocTxBuffer: aLength: %d"), 
       
   374         aLength) );
       
   375     
       
   376     TDataBuffer* metaHdr ( NULL );
       
   377 
       
   378     if ( aLength > KMaxEthernetFrameLength )
       
   379         {
       
   380 #ifndef NDEBUG
       
   381         TraceDump( NWSA_TX_DETAILS, 
       
   382             ("WLANLDD: DataFrameMemMngr::AllocTxBuffer: WARNING: max size exceeded; req. denied") );
       
   383         os_assert( 
       
   384             (TUint8*)("WLANLDD: panic"), 
       
   385             (TUint8*)(WLAN_FILE), 
       
   386             __LINE__ );                    
       
   387 #endif        
       
   388         
       
   389         return metaHdr;
       
   390         }
       
   391     
       
   392     const TUint bufLen ( Align4(
       
   393         iVendorTxHdrLen +
       
   394         KHtQoSMacHeaderLength +  
       
   395         KMaxDot11SecurityEncapsulationLength +
       
   396         sizeof( SSnapHeader ) +
       
   397         aLength +
       
   398         KSpaceForAlignment +
       
   399         iVendorTxTrailerLen ) ); 
       
   400     
       
   401     TUint8* buf = reinterpret_cast<TUint8*>(
       
   402         iTxFrameMemoryPool->Alloc( bufLen, EFalse ));
       
   403     
       
   404     if ( buf )
       
   405         {
       
   406         TraceDump( NWSA_TX_DETAILS, 
       
   407             (("WLANLDD: DataFrameMemMngr::AllocTxBuffer: tx buf kern addr: 0x%08x"), 
       
   408             reinterpret_cast<TUint32>(buf) ) );
       
   409         
       
   410         metaHdr = iFrameXferBlockProtoStack->AllocTxBuffer( 
       
   411             buf, 
       
   412             static_cast<TUint16>(aLength) );
       
   413         
       
   414         if ( !metaHdr )
       
   415             {
       
   416             iTxFrameMemoryPool->Free( buf );
       
   417             }
       
   418         }
       
   419     
       
   420     return metaHdr;
       
   421     }
       
   422 
       
   423 // ---------------------------------------------------------------------------
       
   424 // 
       
   425 // ---------------------------------------------------------------------------
       
   426 //
       
   427 void DataFrameMemMngr::FreeTxPacket( TDataBuffer*& aPacket )
       
   428     {
       
   429     if ( IsMemInUse() )
       
   430         {
       
   431         // free the actual Tx buffer
       
   432         iTxFrameMemoryPool->Free( aPacket->KeGetBufferStart() );
       
   433         // free the meta header
       
   434         iFrameXferBlockProtoStack->FreeTxPacket( aPacket );
       
   435         }
       
   436     }
       
   437 
       
   438 // ---------------------------------------------------------------------------
       
   439 // 
       
   440 // ---------------------------------------------------------------------------
       
   441 //
       
   442 void DataFrameMemMngr::OnReleaseMemory()
       
   443     {
       
   444     TraceDump(INIT_LEVEL, ("WLANLDD: DataFrameMemMngr::OnReleaseMemory"));
       
   445 
       
   446     if ( iTxFrameMemoryPool )
       
   447         {
       
   448         TraceDump(MEMORY, (("WLANLDD: delete WlanChunk: 0x%08x"), 
       
   449             reinterpret_cast<TUint32>(iTxFrameMemoryPool)));        
       
   450     
       
   451         delete iTxFrameMemoryPool;
       
   452         iTxFrameMemoryPool = NULL;
       
   453         iTxDataChunk = NULL;
       
   454         
       
   455         MarkMemFree();            
       
   456         }
       
   457     }