--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/wlan_bearer/wlanldd/wlan_symbian/wlanldd_symbian/src/WlanLogicalChannel.cpp Tue Feb 02 02:03:13 2010 +0200
@@ -0,0 +1,2946 @@
+/*
+* Copyright (c) 2005-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 DWlanLogicalChannel class.
+*
+*/
+
+/*
+* %version: 56 %
+*/
+
+#include "WlLddWlanLddConfig.h"
+#include "wlanlddcommon.h"
+#include "WlanLogicalChannel.h"
+#include "EthernetFrameMemMngr.h"
+#include "EtherCardIoc.h"
+#include "RWlanLogicalChannel.h"
+#include "Umac.h"
+#include "wllddoidmsgstorage.h"
+#include "WlanLogicalDevice.h"
+#include "osachunk.h"
+
+#ifdef RD_WLAN_DDK
+#include "osa.h"
+#include "wlanpddiface.h"
+#endif
+
+extern TAny* os_alloc( const TUint32 );
+extern void os_free( const TAny* );
+
+// Tx memory for frames created by UMAC
+const TUint32 KDmaTxMemSize = 4096; // equals to 1 MMU page on most systems
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+#ifndef RD_WLAN_DDK
+DWlanLogicalChannel::DWlanLogicalChannel(
+ DWlanLogicalDevice& aParent,
+ Umac& aUmac,
+ TDynamicDfcQue& aDfcQ,
+ DMutex& aMutex,
+ DChunk*& aSharedMemoryChunk,
+ WlanChunk*& aRxFrameMemoryPool )
+#else
+DWlanLogicalChannel::DWlanLogicalChannel(
+ DWlanLogicalDevice& aParent,
+ Umac& aUmac,
+ TDynamicDfcQue& aDfcQ,
+ WlanOsa*& aOsa,
+ DChunk*& aSharedMemoryChunk,
+ WlanChunk*& aRxFrameMemoryPool )
+#endif
+ :
+ iClient( NULL ),
+ iUnit( KUnitMax ),
+ iUmac( aUmac ),
+ iDfcQ ( &aDfcQ ),
+ iParent( aParent ),
+ iWlanGeneralRequestStatus( NULL ),
+ iWlanRequestNotifyStatus( NULL ),
+ iWlanReceiveFrameStatus( NULL ),
+ iWlanSendFrameStatus( NULL ),
+ iIndicationBuffer( NULL ),
+ iIndicationListHead( NULL ),
+ iFreeIndicationListHead( NULL ),
+ iResumeTxStatus( NULL ),
+ iEthernetReceiveFrameStatus( NULL ),
+ iEthernetFrameMemMngr( NULL ),
+ iTimerDfc( TimerDfcDoToggle, this, 0 ),
+ iTimer( OnTimeOut, this ),
+ iVoiceCallEntryTimer( OnVoiceCallEntryTimerTimeOut, this ),
+ iVoiceCallEntryTimerDfc( VoiceCallEntryTimerDfcDoToggle, this, 0 ),
+ iNullTimer( OnNullTimerTimeOut, this ),
+ iNullTimerDfc( NullTimerDfcDoToggle, this, 0 ),
+ iNoVoiceTimer( OnNoVoiceTimerTimeOut, this ),
+ iNoVoiceTimerDfc( NoVoiceTimerDfcDoToggle, this, 0 ),
+ iKeepAliveTimer( OnKeepAliveTimerTimeOut, this ),
+ iKeepAliveTimerDfc( KeepAliveTimerDfcDoToggle, this, 0 ),
+ iActiveToLightPsTimer( OnActiveToLightPsTimerTimeOut, this ),
+ iActiveToLightPsTimerDfc( ActiveToLightPsTimerDfcDoToggle, this, 0 ),
+ iLightPsToActiveTimer( OnLightPsToActiveTimerTimeOut, this ),
+ iLightPsToActiveTimerDfc( LightPsToActiveTimerDfcDoToggle, this, 0 ),
+ iLightPsToDeepPsTimer( OnLightPsToDeepPsTimerTimeOut, this ),
+ iLightPsToDeepPsTimerDfc( LightPsToDeepPsTimerDfcDoToggle, this, 0 ),
+ iDfc( DfcDoToggle, this, 0 ),
+ iTxTriggerDfc( TxTriggerDfcDoToggle, this, 0 ),
+ iFlags( 0 ),
+ iPowerHandler( *this, aDfcQ ),
+ iPoweringDown( EFalse ),
+ iDfcCtx( NULL ),
+#ifndef RD_WLAN_DDK
+ iMutex( aMutex ),
+#else
+ iOsa( aOsa ),
+#endif
+ iSharedMemoryChunk( aSharedMemoryChunk ),
+ iRxFrameMemoryPool( aRxFrameMemoryPool ),
+ iTxActive( EFalse ),
+ iAddTxFrameAllowed( ETrue )
+ {
+ TraceDump(INIT_LEVEL, (("WLANLDD: DWlanLogicalChannel Ctor: 0x%08x"), this));
+
+ iTimerDfc.SetDfcQ( iDfcQ );
+ iVoiceCallEntryTimerDfc.SetDfcQ( iDfcQ );
+ iNullTimerDfc.SetDfcQ( iDfcQ );
+ iNoVoiceTimerDfc.SetDfcQ( iDfcQ );
+ iKeepAliveTimerDfc.SetDfcQ( iDfcQ );
+ iActiveToLightPsTimerDfc.SetDfcQ( iDfcQ );
+ iLightPsToActiveTimerDfc.SetDfcQ( iDfcQ );
+ iLightPsToDeepPsTimerDfc.SetDfcQ( iDfcQ );
+ iDfc.SetDfcQ( iDfcQ );
+ iTxTriggerDfc.SetDfcQ( iDfcQ );
+
+ // store client thread ID
+ iClient = &Kern::CurrentThread();
+
+ TraceDump(INIT_LEVEL, (("WLANLDD: current thread 0x%08x"), iClient));
+
+ // open a refernce to client thread, so we don't get out of scope
+ ((DObject*)iClient)->Open();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+DWlanLogicalChannel::~DWlanLogicalChannel()
+ {
+ TraceDump(INIT_LEVEL, (("WLANLDD: DWlanLogicalChannel Dtor: 0x%08x"), this));
+
+ if ( iUnit == KUnitWlan )
+ {
+ iTimerDfc.Cancel();
+ iVoiceCallEntryTimerDfc.Cancel();
+ iNullTimerDfc.Cancel();
+ iNoVoiceTimerDfc.Cancel();
+ iKeepAliveTimerDfc.Cancel();
+ iActiveToLightPsTimerDfc.Cancel();
+ iLightPsToActiveTimerDfc.Cancel();
+ iLightPsToDeepPsTimerDfc.Cancel();
+ iDfc.Cancel();
+
+ // if there are any indication items currently pending, free them by
+ // moving them to the free list
+ PurgeIndicationList();
+ // delete all indication items from the free list
+ FreeIndicationList();
+ // detach management side callback
+ TraceDump(INIT_LEVEL, ("WLANLDD: detach managemement side callback from UMAC"));
+ iUmac.Detach();
+
+ if ( iFlags & KPowerHandlerRegistered )
+ {
+ // we have registered our power handler
+
+ // if we stopping operations because of a power down request from power
+ // manager, acknowledge back to power manager that we are now done
+ if ( iPoweringDown )
+ {
+ TraceDump(INIT_LEVEL,
+ (("WLANLDD: DWlanLogicalChannel::~DWlanLogicalChannel(): signalling powerDownDone")));
+ iPowerHandler.OnPowerDownDone();
+ }
+
+ // de-register our power handler from the power manager
+ TraceDump(INIT_LEVEL,
+ (("WLANLDD: DWlanLogicalChannel::~DWlanLogicalChannel(): de-register our powerhandler")));
+ iPowerHandler.Remove();
+
+ // destroy UMAC internal Tx memory buffer
+ iDmaTxMemory.Finit();
+ }
+ }
+ else if ( iUnit == KUnitEthernet )
+ {
+ iTxTriggerDfc.Cancel();
+
+ // detach protocol stack side callback
+ TraceDump(INIT_LEVEL,
+ ("WLANLDD: detach protocol stack side callback from UMAC"));
+ iUmac.DetachProtocolStackSideUmacCb();
+ }
+
+ if ( iEthernetFrameMemMngr )
+ {
+ TraceDump(INIT_LEVEL, ("WLANLDD: deallocate ethernet frame memory pool"));
+ TraceDump(MEMORY, (("WLANLDD: delete DEthernetFrameMemMngr: 0x%08x"),
+ reinterpret_cast<TUint32>(iEthernetFrameMemMngr)));
+
+ delete iEthernetFrameMemMngr;
+ iEthernetFrameMemMngr = NULL;
+ }
+
+ iDfcQ = NULL; // destroyed elsewhere (by the owner)
+
+ // close our refernce to client thread as the very last thing we do
+ Kern::SafeClose( reinterpret_cast<DObject*&>(iClient), NULL);
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+DChunk*& DWlanLogicalChannel::SharedMemoryChunk()
+ {
+ return iSharedMemoryChunk;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::SetRxBufAlignmentPadding(
+ TInt aRxBufAlignmentPadding )
+ {
+ iParent.SetRxBufAlignmentPadding( aRxBufAlignmentPadding );
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TInt DWlanLogicalChannel::RxBufAlignmentPadding() const
+ {
+ return iParent.RxBufAlignmentPadding();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TBool DWlanLogicalChannel::InitIndicationListEntries()
+ {
+ // Initialize indication list entries
+ TBool ret( ETrue ); // true for success
+
+ for ( TUint32 i = 0 ; i < KMaxIndicationListEntries; ++i )
+ {
+ TIndicationListEntry* tmp = new TIndicationListEntry;
+
+ if ( tmp )
+ {
+ TraceDump(MEMORY, (("WLANLDD: new TIndicationListEntry: 0x%08x"),
+ reinterpret_cast<TUint32>(tmp)));
+
+ // The ReleaseIndicationListEntry
+ // function can also be used for initialization
+ ReleaseIndicationListEntry( tmp );
+ }
+ else
+ {
+ // alloc failed no use to continue
+ ret = EFalse;
+ break;
+ }
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// If an error occurs in this method, we set iPdd to NULL to prevent
+// PDD object destruction in base class (DLogicalChannelBase) destructor.
+// DLogicalChannelBase destructor gets called as this logical channel instance
+// gets destoyed when this method returns with an error.
+// The PDD object gets destructed elsewhere.
+// ---------------------------------------------------------------------------
+//
+TInt DWlanLogicalChannel::DoCreate(
+ TInt aUnit,
+ const TDesC8* /*aInfo*/,
+ const TVersion& /*aVer*/ )
+ {
+ TraceDump(INIT_LEVEL, ("WLANLDD: DWlanLogicalChannel::DoCreate"));
+ TraceDump(INIT_LEVEL,
+ (("WLANLDD: current thread 0x%08x"), &Kern::CurrentThread()));
+ TraceDump(INIT_LEVEL, (("WLANLDD: aUnit %d"), aUnit));
+
+ if ( !Kern::CurrentThreadHasCapability(
+ ECapabilityCommDD,
+ __PLATSEC_DIAGNOSTIC_STRING( "Checked by wlan.ldd")))
+ {
+ iPdd = NULL;
+ return KErrPermissionDenied;
+ }
+
+ // enable reception of requests from user mode
+ SetDfcQ(iDfcQ);
+ iMsgQ.Receive();
+
+ // length of the allocation unit to be used for OSA interconnect
+ // (DMA capable) memory and frame Rx/Tx buffers.
+ // If WLAN DDK is used and the WLAN PDD capabilities query below
+ // returns a non-NULL response and the PDD indicates support for
+ // cached memory, we use the length of the processor's cache line
+ // - returned in that response - as the allocation unit length.
+ // Otherwise we use this default value
+ TInt allocationUnit ( 32 );
+
+ iUnit = aUnit; // store the unit
+
+ // PDD has been loaded and created by the framework at this point
+
+ if ( iUnit == KUnitWlan )
+ {
+ if ( !InitIndicationListEntries() )
+ {
+ iPdd = NULL;
+ return KErrNoMemory;
+ }
+
+ // attach management side callback
+ TraceDump(INIT_LEVEL, ("WLANLDD: attach managemement side callback to UMAC"));
+ iUmac.Attach( *this );
+
+#ifndef RD_WLAN_DDK
+ WHA::Wha* wha( reinterpret_cast<WHA::Wha*>(iPdd) );
+ // attach the WHA object to UMAC
+ TraceDump(INIT_LEVEL, ("WLANLDD: attach WHA object to UMAC"));
+ iUmac.AttachWsa( wha );
+#else
+
+ MWlanPddIface* pdd( reinterpret_cast<MWlanPddIface*>(iPdd) );
+
+ TraceDump(INIT_LEVEL,
+ (("WLANLDD: DWlanLogicalChannel::DoCreate: wlanpdd addr: 0x%08x"),
+ pdd));
+
+ // determine PDD capabilities
+
+ MWlanPddIface::SCapabilities* pddCapabilities ( NULL );
+
+ pdd->GetCapabilities( pddCapabilities );
+
+ TraceDump(INIT_LEVEL,
+ (("WLANLDD: DWlanLogicalChannel::DoCreate: pddCapabilities ptr: 0x%08x"),
+ reinterpret_cast<TUint32>(pddCapabilities)));
+
+ if ( pddCapabilities )
+ {
+ TraceDump(INIT_LEVEL,
+ (("WLANLDD: DWlanLogicalChannel::DoCreate: wlanpdd iCapabilities: 0x%08x"),
+ pddCapabilities->iCapabilities));
+
+ if ( pddCapabilities->iCapabilities &
+ MWlanPddIface::SCapabilities::KCachedMemory )
+ {
+ TraceDump(INIT_LEVEL,
+ ("WLANLDD: DWlanLogicalChannel::DoCreate: use cached memory"));
+
+ iParent.UseCachedMemory( ETrue );
+
+ TraceDump(INIT_LEVEL,
+ (("WLANLDD: DWlanLogicalChannel::DoCreate: wlanpdd iCacheLineLength: %d"),
+ pddCapabilities->iCacheLineLength));
+
+ allocationUnit = pddCapabilities->iCacheLineLength;
+ }
+ delete pddCapabilities;
+ pddCapabilities = NULL;
+ }
+
+ // initialize OSA
+ if ( !iOsa->Initialize(
+ iParent.UseCachedMemory(),
+ allocationUnit,
+ iDfcQ ) )
+ {
+ // init failed. We cannot continue
+
+ TraceDump(ERROR_LEVEL,
+ ("WLANLDD: DWlanLogicalChannel::DoCreate: osa init failed, abort"));
+
+ iPdd = NULL;
+ return KErrGeneral;
+ }
+
+ TraceDump(INIT_LEVEL,
+ ("WLANLDD: DWlanLogicalChannel::DoCreate: attach osa and osaext to wlanpdd"));
+ TraceDump(INIT_LEVEL,
+ (("WLANLDD: DWlanLogicalChannel::DoCreate: osa and osaext addr: 0x%08x"),
+ reinterpret_cast<TUint32>(iOsa)));
+
+ // pass interfaces to PDD
+ const TBool ret( pdd->Attach( *iOsa, *iOsa ) );
+ if ( ret )
+ {
+ TraceDump(INIT_LEVEL,
+ ("WLANLDD: DWlanLogicalChannel::DoCreate: extract WHA and attach it to UMAC"));
+ // extract wha and attach it to UMAC
+ iUmac.AttachWsa( &(pdd->Extract()) );
+ }
+ else
+ {
+ // attach failure abort
+ TraceDump(WARNING_LEVEL, ("WLANLDD: PDD attach failure -> abort"));
+ iPdd = NULL;
+ return KErrNoMemory;
+ }
+#endif
+
+#ifndef RD_WLAN_DDK
+ // pass the mutex to WHA
+ wha->Mutex( reinterpret_cast<WHA::TMutexHandle>(&iMutex) );
+#endif
+
+ // register our power handler with the power manager
+ TraceDump(INIT_LEVEL,
+ (("WLANLDD: DWlanLogicalChannel::DoCreate: register our powerhandler")));
+ iPowerHandler.Add();
+ iFlags |= KPowerHandlerRegistered; // note that we have registered
+
+ // create UMAC internal Tx memory buffer
+ if ( iDmaTxMemory.Init( KDmaTxMemSize, iParent.UseCachedMemory() )
+ == KDmaTxMemSize )
+ {
+ // success; no further action needed
+ }
+ else
+ {
+ // failure
+ iPdd = NULL;
+ return KErrNoMemory;
+ }
+ }
+ else if ( iUnit == KUnitEthernet )
+ {
+ // attach protocol stack side callbac
+ iUmac.AttachProtocolStackSideUmacCb( *this );
+ }
+ else
+ {
+ // unknown unit
+
+ TraceDump(ERROR_LEVEL,
+ (("WLANLDD: DWlanLogicalChannel::DoCreate: ERROR: unknown unit: %d"),
+ iUnit));
+ iPdd = NULL;
+ return KErrPermissionDenied;
+ }
+
+ // init ethernet frame memory pool manager
+ iEthernetFrameMemMngr = DEthernetFrameMemMngr::Init(
+ aUnit,
+ *this,
+ iRxFrameMemoryPool,
+ iParent.UseCachedMemory(),
+ allocationUnit );
+
+ if ( iEthernetFrameMemMngr )
+ {
+ // init success -> continue
+ TraceDump(INIT_LEVEL, (("WLANLDD: ethernet memory pool allocated: 0x%08x"),
+ iEthernetFrameMemMngr));
+ }
+ else
+ {
+ // init failure no use to continue
+ TraceDump(WARNING_LEVEL,
+ ("WLANLDD: ethernet memory pool allocation failure"));
+
+ iPdd = NULL;
+ return KErrNoMemory;
+ }
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::HandleMsg(TMessageBase* aMsg)
+ {
+ TraceDump(WLM_CMD, ("WLANLDD: DWlanLogicalChannel::HandleMsg"));
+
+ // we are now executing in a DFC thread context
+ // acquire mutex
+#ifndef RD_WLAN_DDK
+ Kern::MutexWait( iMutex );
+#else
+ iOsa->MutexAcquire();
+#endif
+
+ TraceDump(MUTEX,
+ (("WLANLDD: DWlanLogicalChannel::HandleMsg: mutex acquired")));
+
+ TThreadMessage& m = *reinterpret_cast<TThreadMessage*>( aMsg );
+
+ TraceDump(WLM_CMD_DETAILS, (("WLANLDD: current thread 0x%08x"),
+ &Kern::CurrentThread()));
+ TraceDump(WLM_CMD_DETAILS, (("WLANLDD: client thread 0x%08x"), m.Client()));
+ TraceDump(WLM_CMD_DETAILS, (("WLANLDD: channel creator thread 0x%08x"),
+ iClient));
+
+ // Get message type
+ TInt id = m.iValue;
+
+ TraceDump(WLM_CMD_DETAILS, (("WLANLDD: message id: %d"), id));
+
+ // Decode the message type and dispatch it to the relevent handler function...
+
+ // A logical channel can be closed either explicitly by its user-side client,
+ // or implicitly if the client thread dies. In the latter case, the channel
+ // is closed in the context of the kernel supervisor thread.
+ if ( id == ECloseMsg )
+ {
+ TraceDump(WLM_CMD_DETAILS, ("WLANLDD: close message"));
+
+ if( m.Client() == iClient )
+ {
+ // channel closed by client
+
+ // trick to disable PDD object dealloc
+ // as this logical channel gets destoyed after this
+ // and iPdd is deallocated in DLogicalChannelBase
+ iPdd = NULL;
+ }
+
+ // release mutex
+ // Note that in this case we release the mutex before completing the
+ // client message. Reason: When SMP is used, doing these actions in
+ // the reverse order could, in principle, lead to a situation where
+ // the channel instance has already been destroyed (by another thread)
+ // when the mutex is tried to be released.
+
+#ifndef RD_WLAN_DDK
+ Kern::MutexSignal( iMutex );
+#else
+ iOsa->MutexRelease();
+#endif
+
+ TraceDump(MUTEX,
+ (("WLANLDD: DWlanLogicalChannel::HandleMsg: mutex released")));
+
+ m.Complete( KErrNone, EFalse );
+
+ return;
+ }
+
+ // For all other message types, we check that the message is from the thread
+ // that created us.
+ if ( m.Client() != iClient )
+ {
+ TraceDump(SERIOUS_LEVEL, (("WLANLDD: ERROR: requesting thread: 0x%08x"),
+ m.Client()));
+ TraceDump(SERIOUS_LEVEL, ("WLANLDD: ERROR: request from wrong thread"));
+
+ m.Complete( KErrPermissionDenied, ETrue );
+ }
+ else if ( id == KMaxTInt )
+ {
+ TraceDump(WLM_CMD_DETAILS, ("WLANLDD: DoCancel"));
+
+ // DoCancel
+ DoCancel( m.Int0() );
+ m.Complete( KErrNone,ETrue );
+ }
+ else if ( id < 0 )
+ {
+ TraceDump(WLM_CMD_DETAILS, ("WLANLDD: DoRequest"));
+
+ // DoRequest
+ TRequestStatus* req_status = reinterpret_cast<TRequestStatus*>( m.Ptr0() );
+ const TInt r = DoRequest( ~id, req_status, m.Ptr1(), m.Ptr2() );
+ if ( r != KErrNone)
+ {
+ // this branch means that an error of somekind has occurred
+ // we complete the request synchronously
+ Kern::RequestComplete( m.Client(), req_status, r );
+ }
+
+ m.Complete( KErrNone, ETrue );
+ }
+ else
+ {
+ TraceDump(WLM_CMD_DETAILS, ("WLANLDD: DoControl"));
+
+ // DoControl
+ const TInt r = DoControl( id, m.Ptr0(), m.Ptr1() );
+ m.Complete( r, ETrue );
+ }
+
+ // release mutex
+
+#ifndef RD_WLAN_DDK
+ Kern::MutexSignal( iMutex );
+#else
+ iOsa->MutexRelease();
+#endif
+
+ TraceDump(MUTEX,
+ (("WLANLDD: DWlanLogicalChannel::HandleMsg: mutex released")));
+ }
+
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TAny* DWlanLogicalChannel::DoControlFast( TInt aFunction, TAny* param )
+ {
+ TAny* ret( NULL );
+ TBool triggerTx ( EFalse );
+
+ TraceDump(WLM_CMD_DETAILS,
+ (("WLANLDD: DWlanLogicalChannel::DoControlFast: current thread 0x%08x"),
+ &Kern::CurrentThread()));
+ TraceDump(WLM_CMD_DETAILS, (("WLANLDD: channel creator thread: 0x%08x"),
+ iClient));
+ TraceDump(WLM_CMD_DETAILS, (("WLANLDD: function: 0x%x"), aFunction));
+
+ // Note! We are executing in the context of the client's thread, but
+ // in supervisor mode
+
+ // acquire mutex
+#ifndef RD_WLAN_DDK
+ Kern::MutexWait( iMutex );
+#else
+ iOsa->MutexAcquire();
+#endif
+
+ TraceDump(MUTEX,
+ (("WLANLDD: DWlanLogicalChannel::DoControlFast: mutex acquired")));
+
+ switch ( aFunction )
+ {
+ case RPcmNetCardIf::EControlFastAllocTxBuffer:
+ ret = iEthernetFrameMemMngr->AllocTxBuffer(
+ reinterpret_cast<TUint>(param) );
+
+ if ( !ret && iAddTxFrameAllowed )
+ {
+ iAddTxFrameAllowed = EFalse;
+
+ TraceDump( NWSA_TX,
+ ("WLANLDD: DWlanLogicalChannel::DoControlFast: stop flow from protocol stack") );
+ }
+ break;
+
+ case RPcmNetCardIf::EControlFastAddTxFrame:
+ {
+#ifndef NDEBUG
+ if ( !iAddTxFrameAllowed )
+ {
+ TraceDump(ERROR_LEVEL,
+ ("WLANLDD: DWlanLogicalChannel::DoControlFast: WARNING: AddTxFrame req. when flow ctrl is on"));
+ }
+#endif
+ if ( iEthernetFrameMemMngr->AllTxQueuesEmpty() )
+ {
+ triggerTx = ETrue;
+ }
+
+ TDataBuffer* discardFrame ( NULL );
+
+ ret = reinterpret_cast<TAny*>(iEthernetFrameMemMngr->AddTxFrame(
+ reinterpret_cast<TDataBuffer*>(param),
+ discardFrame,
+ iUmac.UserDataTxEnabled() ));
+
+ if ( discardFrame )
+ {
+ TraceDump( NWSA_TX_DETAILS,
+ (("WLANLDD: DWlanLogicalChannel::DoControlFast: have to drop tx frame of UP: %d"),
+ reinterpret_cast<TDataBuffer*>(param)->UserPriority()) );
+
+ iEthernetFrameMemMngr->FreeTxPacket( discardFrame );
+ }
+
+ if ( !ret )
+ {
+ iAddTxFrameAllowed = EFalse;
+
+ TraceDump( NWSA_TX,
+ ("WLANLDD: DWlanLogicalChannel::DoControlFast: stop flow from protocol stack") );
+ }
+ break;
+ }
+ default:
+#ifndef NDEBUG
+ TraceDump(ERROR_LEVEL, (("WLANLDD: unknown request: %d"),
+ aFunction));
+ os_assert(
+ (TUint8*)("WLANLDD: panic"),
+ (TUint8*)(WLAN_FILE),
+ __LINE__ );
+#endif
+ break;
+ }
+
+ // release mutex
+#ifndef RD_WLAN_DDK
+ Kern::MutexSignal( iMutex );
+#else
+ iOsa->MutexRelease();
+#endif
+
+ TraceDump(MUTEX,
+ ("WLANLDD: DWlanLogicalChannel::DoControlFast: mutex released"));
+
+ if ( triggerTx )
+ {
+ // Trigger a new Tx - via a DFC.
+ // Note that we do this outside of mutex protection, as this block of
+ // code is executed by a lower priority (user side) thread, and the
+ // DFC by a higher priority (kernel side) thread, and the latter will
+ // also need to acquire the same mutex before it can proceed. So, as
+ // the lower priority thread will get paused and the higher priority
+ // thread will get scheduled (to execute the DFC), we don't want the
+ // higher priority thread to need to wait for the mutex. So we
+ // released the mutex first in this code block and after that enque
+ // the DFC request.
+ if ( !( iFlags & KTxTriggerArmed ) )
+ {
+ iFlags |= KTxTriggerArmed;
+ iTxTriggerDfc.Enque();
+ }
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::DoCancel( TInt aMask )
+ {
+ if ( iUnit == KUnitWlan )
+ {
+ if ( aMask & ( 1 << EWlanRequestNotify ) )
+ {
+ TraceDump(INFO_LEVEL,
+ ("WLANLDD: DWlanLogicalChannel::DoCancel: mgmt side notify cancel"));
+
+ CancelIndicationRequest();
+ Kern::RequestComplete(
+ iClient, iWlanRequestNotifyStatus, KErrServerTerminated );
+ iWlanRequestNotifyStatus = NULL;
+ }
+ else if ( aMask & ( 1 << EWlanRequestFrame ) )
+ {
+ TraceDump(INFO_LEVEL,
+ ("WLANLDD: DWlanLogicalChannel::DoCancel: mgmt side frame read cancel"));
+
+ Kern::RequestComplete(
+ iClient, iWlanReceiveFrameStatus, KErrServerTerminated );
+ iWlanReceiveFrameStatus = NULL;
+ }
+ else
+ {
+ TraceDump(ERROR_LEVEL,
+ (("WLANLDD: DWlanLogicalChannel::DoCancel: mgmt side unhandled mask panic: 0x%08x"),
+ aMask));
+ os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
+ }
+ }
+ else if ( iUnit == KUnitEthernet )
+ {
+ if ( aMask & ( 1 << RPcmNetCardIf::EControlResumeTxCancel ) )
+ {
+ TraceDump(INFO_LEVEL,
+ ("WLANLDD: DWlanLogicalChannel::DoCancel: user side resume Tx cancel"));
+
+ Kern::RequestComplete(
+ iClient, iResumeTxStatus, KErrServerTerminated );
+ iResumeTxStatus = NULL;
+ }
+ else if ( aMask & ( 1 << RPcmNetCardIf::EControlReadCancel ) )
+ {
+ TraceDump(INFO_LEVEL,
+ ("WLANLDD: DWlanLogicalChannel::DoCancel: user side frame read cancel"));
+
+ Kern::RequestComplete(
+ iClient, iEthernetReceiveFrameStatus, KErrServerTerminated );
+ iEthernetReceiveFrameStatus = NULL;
+ }
+ else
+ {
+ TraceDump(ERROR_LEVEL,
+ (("WLANLDD: DWlanLogicalChannel::DoCancel: user side unhandled mask panic: 0x%08x"),
+ aMask));
+ os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
+ }
+ }
+ else
+ {
+ TraceDump(ERROR_LEVEL, (("WLANLDD: DoCancel unknown unit panic: %d"),
+ iUnit));
+ os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TBool DWlanLogicalChannel::ProtocolStackDataReceiveComplete(
+ const TDataBuffer*& aBufferStart,
+ TUint32 aNumOfBuffers )
+ {
+ if ( iEthernetFrameMemMngr->OnEthernetFrameRxComplete( aBufferStart,
+ aNumOfBuffers ) )
+ {
+ Kern::RequestComplete( iClient, iEthernetReceiveFrameStatus, KErrNone );
+ iEthernetReceiveFrameStatus = NULL;
+ }
+
+ return ETrue; // indicate always successful processing
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+TBool DWlanLogicalChannel::ProtocolStackSideClientReady() const
+ {
+ TBool status ( EFalse );
+
+ if ( iEthernetFrameMemMngr && iEthernetFrameMemMngr->IsMemInUse() )
+ {
+ status = ETrue;
+ }
+
+ return status;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::UserDataReEnabled()
+ {
+ if ( !( iFlags & KTxTriggerArmed ) )
+ {
+ iFlags |= KTxTriggerArmed;
+ iTxTriggerDfc.Enque();
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TUint8* DWlanLogicalChannel::DmaPrivateTxMemory()
+ {
+ return reinterpret_cast<TUint8*>(iDmaTxMemory.Addr());
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::SetProtocolStackTxOffset(
+ TUint32 aEthernetFrameTxOffset )
+ {
+ const TUint32 KNotRelevant ( 0 );
+
+ if ( iEthernetFrameMemMngr )
+ {
+ TraceDump(NWSA_TX_DETAILS,
+ (("WLANLDD: DWlanLogicalChannel::SetProtocolStackTxOffset: aEthernetFrameTxOffset: %d"),
+ aEthernetFrameTxOffset ));
+
+ iEthernetFrameMemMngr->SetTxOffsets(
+ aEthernetFrameTxOffset,
+ KNotRelevant,
+ KNotRelevant );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::OnTxProtocolStackDataComplete(
+ TInt aCompletionCode,
+ TDataBuffer* aMetaHeader )
+ {
+ TraceDump(UMAC_PROTO_CALLBACK,
+ ("WLANLDD: DWlanLogicalChannel::OnTxProtocolStackDataComplete"));
+ TraceDump(UMAC_PROTO_CALLBACK,
+ (("WLANLDD: aCompletionCode: %d"), aCompletionCode));
+
+ iEthernetFrameMemMngr->FreeTxPacket( aMetaHeader );
+
+ TxProtocolStackData();
+
+ if ( !iAddTxFrameAllowed )
+ {
+ if ( iResumeTxStatus &&
+ iEthernetFrameMemMngr->ResumeClientTx(
+ iUmac.UserDataTxEnabled() ) )
+ {
+ // resume Tx flow from protocol stack
+
+ TraceDump(NWSA_TX_DETAILS,
+ ("WLANLDD: DWlanLogicalChannel::OnTxProtocolStackDataComplete: complete client Tx resume req"));
+
+ // complete the pending request to user mode
+ Kern::RequestComplete(
+ iClient, iResumeTxStatus, aCompletionCode );
+ // mark request as non-pending
+ iResumeTxStatus = NULL;
+
+ iAddTxFrameAllowed = ETrue;
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::OnOtherTxDataComplete()
+ {
+ TraceDump(UMAC_PROTO_CALLBACK,
+ ("WLANLDD: DWlanLogicalChannel::OnOtherTxDataComplete"));
+
+ // We try to submit Protocol Stack side frames also when this event occurs
+ // a) to speed up new Tx submission in the case that a frame submitted by
+ // someone else than the Protocol Stack Side Client unblocks the WHA Tx
+ // pipeline and
+ // b) to avoid the Tx pipe from getting stuck even temporarily
+ if ( !( iFlags & KTxTriggerArmed ) )
+ {
+ iFlags |= KTxTriggerArmed;
+ iTxTriggerDfc.Enque(); // we do this via a DFC
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::OnTxDataSent()
+ {
+ TraceDump(UMAC_PROTO_CALLBACK,
+ ("WLANLDD: DWlanLogicalChannel::OnTxDataSent"));
+
+ // We try to submit Protocol Stack side frames also when this event occurs
+ // a) to speed up new Tx submission in the case that a frame, submitted by
+ // someone else than the Protocol Stack Side Client, gets transmitted &
+ // makes a WHA Txqueue - for which there are packets pending in our Tx
+ // queues - non-full
+ // b) to avoid the Tx pipe from getting stuck even temporarily
+ if ( !( iFlags & KTxTriggerArmed ) )
+ {
+ iFlags |= KTxTriggerArmed;
+ iTxTriggerDfc.Enque(); // we do this via a DFC
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::TxManagementData()
+ {
+ TDataBuffer* buffer = iEthernetFrameMemMngr->OnWriteEthernetFrame();
+
+ if ( !buffer )
+ {
+ TraceDump(ERROR_LEVEL,
+ ("WLANLDD: DWlanLogicalChannel::TxManagementData: "
+ "panic, no buffer"));
+ os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
+ }
+ else
+ {
+ iUmac.WriteMgmtFrame( *buffer );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::TxProtocolStackData()
+ {
+#ifndef NDEBUG
+ TUint packetsSubmitted ( 0 );
+#endif
+
+ if ( !iTxActive )
+ {
+ TWhaTxQueueState txQueueState;
+ TBool morePackets ( EFalse );
+ iTxActive = ETrue;
+
+ while ( iUmac.TxPermitted( txQueueState ) )
+ {
+ TDataBuffer* metaHeader =
+ iEthernetFrameMemMngr->GetTxFrame( txQueueState, morePackets );
+
+ if ( metaHeader )
+ {
+ TraceDump( NWSA_TX_DETAILS,
+ (("WLANLDD: DWlanLogicalChannel::TxProtocolStackData: submitting packet %d"),
+ ++packetsSubmitted) );
+
+ iUmac.TxProtocolStackData(
+ *metaHeader,
+ morePackets );
+ }
+ else
+ {
+ TraceDump(NWSA_TX_DETAILS,
+ ("WLANLDD: DWlanLogicalChannel::TxProtocolStackData: no packet that could be submitted"));
+
+ break;
+ }
+ }
+
+ iTxActive = EFalse;
+ }
+
+ TraceDump( NWSA_TX_DETAILS,
+ (("WLANLDD: DWlanLogicalChannel::TxProtocolStackData: %d packet(s) submitted"),
+ packetsSubmitted) );
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TBool DWlanLogicalChannel::OnReadEthernetFrameRequest()
+ {
+ const TBool ret = iEthernetFrameMemMngr->OnReadRequest();
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TInt DWlanLogicalChannel::OnEthernetSideRequest(
+ TInt aReqNo,
+ TRequestStatus* aStatus,
+ TAny* /*a1*/,
+ TAny* /*a2*/ )
+ {
+ const TInt ret( KErrNone );
+
+ switch (aReqNo)
+ {
+ case RPcmNetCardIf::ERequestRead:
+ // Read request
+ if ( OnReadEthernetFrameRequest() )
+ {
+ // rx data to be completed exists
+ // complete it directly
+ Kern::RequestComplete(
+ iClient,
+ aStatus,
+ KErrNone );
+ }
+ else
+ {
+ // no rx data for completion exists
+ // store the pending request
+ iEthernetReceiveFrameStatus = aStatus;
+ }
+ break;
+ case RPcmNetCardIf::EResumeTx:
+ // request to get notified once Tx can again be resumed
+ iResumeTxStatus = aStatus;
+ break;
+ default:
+ // unknown request
+
+ TraceDump(ERROR_LEVEL,
+ ("WLANLDD: unknown protocol stack request"));
+ TraceDump(ERROR_LEVEL, (("WLANLDD: request id: %d"), aReqNo));
+ os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
+ break;
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::FinitSystem()
+ {
+ TraceDump(INIT_LEVEL, ("WLANLDD * finit system"));
+ iUmac.FinitSystem();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::InitSystem(
+ TAny* aInputBuffer,
+ TUint aInputLength )
+ {
+ // read the USER mode parameters to internal storage
+ TInt ret = Kern::ThreadRawRead(
+ iClient,
+ aInputBuffer,
+ &iOpenParam,
+ aInputLength );
+ if ( ret != KErrNone )
+ {
+ TraceDump(ERROR_LEVEL,
+ ("WLANLDD: DWlanLogicalChannel::InitSystem(): ThreadRawRead panic"));
+ TraceDump(ERROR_LEVEL, (("WLANLDD: ret: %d"), ret));
+ os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
+ }
+
+ // backup pointers
+ const TAny* pda( iOpenParam.iPda );
+ const TAny* fw( iOpenParam.iFirmWare );
+
+ // allocate kernel memory for the pda and firmware
+ iOpenParam.iPda = os_alloc( iOpenParam.iPdaLength );
+ iOpenParam.iFirmWare = os_alloc( iOpenParam.iFirmWareLength );
+
+ if ( iOpenParam.iPda && iOpenParam.iFirmWare )
+ {
+ // allocation success
+ // read the parameters to allocated storage
+ ret = Kern::ThreadRawRead(
+ iClient,
+ pda,
+ iOpenParam.iPda,
+ iOpenParam.iPdaLength );
+ if ( ret != KErrNone )
+ {
+ TraceDump(ERROR_LEVEL,
+ ("WLANLDD: DWlanLogicalChannel::InitSystem(): ThreadRawRead panic"));
+ TraceDump(ERROR_LEVEL, (("WLANLDD: ret: %d"), ret));
+ os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
+ }
+ ret = Kern::ThreadRawRead(
+ iClient,
+ fw,
+ iOpenParam.iFirmWare,
+ iOpenParam.iFirmWareLength );
+ if ( ret != KErrNone )
+ {
+ TraceDump(ERROR_LEVEL,
+ ("WLANLDD: DWlanLogicalChannel::InitSystem(): ThreadRawRead panic"));
+ TraceDump(ERROR_LEVEL, (("WLANLDD: ret: %d"), ret));
+ os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
+ }
+
+ // check this in completion method
+ iFlags |= KFreeOpenParamsMask;
+
+ iUmac.BootUp(
+ static_cast<TUint8*>(iOpenParam.iPda),
+ iOpenParam.iPdaLength,
+ static_cast<TUint8*>(iOpenParam.iFirmWare),
+ iOpenParam.iFirmWareLength );
+ }
+ else
+ {
+ // allocation failure
+ // make sure all is released
+ os_free( iOpenParam.iPda );
+ os_free( iOpenParam.iFirmWare );
+
+ TraceDump(ERROR_LEVEL,
+ ("WLANLDD: DWlanLogicalChannel::InitSystem: ERROR: PDA and/or firmware memory allocation failure"));
+
+ // complete the pending request with error code to user mode
+ Kern::RequestComplete(
+ iClient,
+ iWlanGeneralRequestStatus,
+ KErrNoMemory );
+ // mark request as non pending
+ iWlanGeneralRequestStatus = NULL;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TBool DWlanLogicalChannel::HandlePointerParameters()
+ {
+ TraceDump(WLM_CMD_DETAILS,
+ (("WLANLDD: DWlanLogicalChannel::HandlePointerParameters")));
+
+ if ( !HandleScanResponseFrameBodyCase() )
+ {
+ // memory allocation failure
+
+ return EFalse;
+ }
+
+ if ( !CheckAndHandleIeDataCase() )
+ {
+ // memory allocation failure
+
+ // free memory allocated in the previous step
+ FreeScanResponseFramebody();
+
+ return EFalse;
+ }
+
+ return ETrue;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TBool DWlanLogicalChannel::HandleScanResponseFrameBodyCase()
+ {
+ TBool ret( ETrue );
+
+ // handle scan response frame body case
+ if ( (reinterpret_cast<const TOIDHeader*>
+ (&iOidMsgStorage))->oid_id == E802_11_CONNECT )
+ {
+ if ( iOidMsgStorage.iOidMsgs.iConnectMsg.scanResponseFrameBody )
+ {
+ // scan response frame body exists
+ // we must allocate kernel storage for it here
+
+ TraceDump(WLM_CMD_DETAILS,
+ (("WLANLDD: DWlanLogicalChannel::HandleScanResponseFrameBodyCase: allocate memory & copy data; length: %d"),
+ iOidMsgStorage.iOidMsgs
+ .iConnectMsg.scanResponseFrameBodyLength ));
+
+ const TUint8* user_mode_address(
+ iOidMsgStorage.iOidMsgs.iConnectMsg.scanResponseFrameBody );
+
+ iOidMsgStorage.iOidMsgs.iConnectMsg.scanResponseFrameBody
+ = static_cast<TUint8*>(os_alloc(
+ iOidMsgStorage.iOidMsgs
+ .iConnectMsg.scanResponseFrameBodyLength ));
+
+ if ( iOidMsgStorage.iOidMsgs.iConnectMsg.scanResponseFrameBody )
+ {
+ // allocation success
+ // read the parameters to the allocated storage
+ const TInt local( Kern::ThreadRawRead(
+ iClient,
+ user_mode_address,
+ const_cast<TUint8*>(iOidMsgStorage.iOidMsgs
+ .iConnectMsg.scanResponseFrameBody),
+ iOidMsgStorage.iOidMsgs
+ .iConnectMsg.scanResponseFrameBodyLength ) );
+
+ if ( local != KErrNone )
+ {
+ TraceDump(ERROR_LEVEL,
+ ("WLANLDD: ThreadRawRead panic"));
+ TraceDump(ERROR_LEVEL, (("WLANLDD: local: %d"), ret));
+ os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
+ }
+
+ // mark memory deallocation event
+ iFlags |= KFreeScanResponseFramebodyMask;
+ }
+ else
+ {
+ // allocation failure
+ ret = EFalse;
+ }
+ }
+ else // --- scan response frame body does not exist ---
+ {
+ // this is a usage error
+
+ TraceDump(ERROR_LEVEL,
+ ("WLANLDD: scan response frame body is null in connect OID"));
+ os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
+ }
+ }
+ else // --- connect not issued ---
+ {
+ // do nothing
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TBool DWlanLogicalChannel::CheckAndHandleIeDataCase()
+ {
+ TBool ret( ETrue );
+
+ // handle Tx IE case
+ if ( (reinterpret_cast<const TOIDHeader*>
+ (&iOidMsgStorage))->oid_id == E802_11_CONNECT )
+ {
+ if ( iOidMsgStorage.iOidMsgs.iConnectMsg.ieData )
+ {
+ // Tx IE exists
+ // we must allocate kernel storage for it here
+
+ TraceDump(WLM_CMD_DETAILS,
+ (("WLANLDD: DWlanLogicalChannel::CheckAndHandleIeDataCase: allocate memory & copy data; length: %d"),
+ iOidMsgStorage.iOidMsgs.iConnectMsg.ieDataLength ));
+
+ const TUint8* user_mode_address(
+ iOidMsgStorage.iOidMsgs.iConnectMsg.ieData );
+
+ iOidMsgStorage.iOidMsgs.iConnectMsg.ieData
+ = static_cast<TUint8*>(os_alloc(
+ iOidMsgStorage.iOidMsgs.iConnectMsg.ieDataLength ));
+
+ if ( iOidMsgStorage.iOidMsgs.iConnectMsg.ieData )
+ {
+ // allocation success
+ // read the parameters to the allocated storage
+ const TInt local( Kern::ThreadRawRead(
+ iClient,
+ user_mode_address,
+ const_cast<TUint8*>(iOidMsgStorage.iOidMsgs
+ .iConnectMsg.ieData),
+ iOidMsgStorage.iOidMsgs
+ .iConnectMsg.ieDataLength ) );
+
+ if ( local != KErrNone )
+ {
+ TraceDump(ERROR_LEVEL,
+ ("WLANLDD: ThreadRawRead panic"));
+ TraceDump(ERROR_LEVEL, (("WLANLDD: local: %d"), ret));
+ os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
+ }
+
+ // mark memory deallocation event
+ iFlags |= KFreeIeDataMask;
+ }
+ else
+ {
+ // allocation failure
+ ret = EFalse;
+ }
+ }
+ else // --- RSN IE does not exists ---
+ {
+ // do nothing
+ }
+ }
+ else // --- connect not issued ---
+ {
+ // do nothing
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::FreeScanResponseFramebody()
+ {
+ if ( iFlags & KFreeScanResponseFramebodyMask )
+ {
+ // free scan response frame
+
+ TraceDump(WLM_CMD_DETAILS,
+ (("WLANLDD: DWlanLogicalChannel::FreeScanResponseFramebody: freeing memory")));
+
+ os_free( iOidMsgStorage.iOidMsgs.iConnectMsg.scanResponseFrameBody );
+ iOidMsgStorage.iOidMsgs.iConnectMsg.scanResponseFrameBody = NULL;
+ iFlags &= ~KFreeScanResponseFramebodyMask;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::FreeIeData()
+ {
+ if ( iFlags & KFreeIeDataMask )
+ {
+ // free Tx IE
+
+ TraceDump(WLM_CMD_DETAILS,
+ (("WLANLDD: DWlanLogicalChannel::FreeIeData: freeing memory")));
+
+ os_free( iOidMsgStorage.iOidMsgs.iConnectMsg.ieData );
+ iOidMsgStorage.iOidMsgs.iConnectMsg.ieData = NULL;
+ iFlags &= ~KFreeIeDataMask;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TInt DWlanLogicalChannel::OnMgmtSideDoRequest(
+ TInt aReqNo,
+ TRequestStatus* aStatus,
+ TAny* a1,
+ TAny* a2 )
+ {
+ TraceDump(WLM_CMD,
+ (("WLANLDD: DWlanLogicalChannel::OnMgmtSideDoRequest(): request: %d"),
+ aReqNo));
+ TraceDump(WLM_CMD_DETAILS, (("WLANLDD: a1 0x%08x"), a1));
+ TraceDump(WLM_CMD_DETAILS, (("WLANLDD: a2 0x%08x"), a2));
+
+ TInt ret( KErrNone );
+
+ SOutputBuffer output_buffer = { NULL, 0 };
+ if ( a2 )
+ {
+ // read the USER mode output parameters to internal storage
+ ret = Kern::ThreadRawRead(
+ iClient,
+ a2,
+ &output_buffer,
+ sizeof(output_buffer) );
+ if ( ret != KErrNone )
+ {
+ TraceDump(ERROR_LEVEL,
+ ("WLANLDD: OnMgmtSideDoRequest(): ThreadRawRead panic"));
+ TraceDump(ERROR_LEVEL, (("WLANLDD: ret: %d"), ret));
+ os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
+ }
+ }
+
+ switch ( aReqNo )
+ {
+ case EWlanInitSystem:
+ // bootup the chip and the system
+ iWlanGeneralRequestStatus = aStatus;
+ InitSystem( a1, sizeof(TOpenParam) );
+ break;
+ case EWlanFinitSystem:
+ // power down the chip and the system
+ iWlanGeneralRequestStatus = aStatus;
+ FinitSystem();
+ break;
+ case EWlanCommand:
+ // management command
+ iWlanGeneralRequestStatus = aStatus;
+
+ // read the USER mode parameters to internal storage
+ ret = Kern::ThreadRawRead(
+ iClient,
+ a1,
+ &iOidMsgStorage,
+ sizeof(iOidMsgStorage) );
+ if ( ret != KErrNone )
+ {
+ TraceDump(ERROR_LEVEL,
+ ("WLANLDD: DWlanLogicalChannel::OnMgmtSideDoRequest(): ThreadRawRead panic"));
+ TraceDump(ERROR_LEVEL, (("WLANLDD: ret: %d"), ret));
+ os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
+ }
+
+ // read also parameters pointed to by pointers from USER mode to
+ // internal storage; when such parameters exist
+ if ( !HandlePointerParameters() )
+ {
+ // memory allocation failure
+ // complete the pending request with error code to user mode
+ Kern::RequestComplete(
+ iClient,
+ iWlanGeneralRequestStatus,
+ KErrNoMemory );
+ // mark request as non pending
+ iWlanGeneralRequestStatus = NULL;
+ break;
+ }
+
+ iUmac.HandleOid(
+ reinterpret_cast<const TOIDHeader*>(&iOidMsgStorage),
+ // we can pass output buffer pointer as is
+ // because it is not accessed by UMAC and the
+ // actual user mode writing is done by OnOidCompleted method
+ output_buffer.iData,
+ output_buffer.iLen );
+ break;
+ case EWlanRequestNotify:
+ // store the USER mode indication address;
+ iIndicationBuffer = static_cast<TIndication*>(a1);
+ iWlanRequestNotifyStatus = aStatus;
+ IndicationRequest( static_cast<TIndication*>(a1) );
+ break;
+ case EWlanRequestFrame:
+ if ( OnReadEthernetFrameRequest() )
+ {
+ // rx data to be completed exists
+ // complete it directly
+ Kern::RequestComplete(
+ iClient,
+ aStatus,
+ KErrNone );
+ }
+ else
+ {
+ // no rx data for completion exists
+ // store the pending request
+ iWlanReceiveFrameStatus = aStatus;
+ }
+ break;
+ case EWlanRequestSend:
+ iWlanSendFrameStatus = aStatus;
+
+ TxManagementData();
+ break;
+ default:
+ // unknown request
+ TraceDump(ERROR_LEVEL,
+ ("WLANLDD: unhandled management request panic"));
+ TraceDump(ERROR_LEVEL, (("WLANLDD: request id: %d"), aReqNo));
+ os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
+ break;
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TInt DWlanLogicalChannel::DoRequest(
+ TInt aReqNo,
+ TRequestStatus* aStatus,
+ TAny* a1,
+ TAny* a2 )
+ {
+ TInt ret( KErrNone );
+ if ( iUnit == KUnitWlan )
+ {
+ ret = OnMgmtSideDoRequest( aReqNo, aStatus, a1, a2 );
+ }
+ else if ( iUnit == KUnitEthernet )
+ {
+ ret = OnEthernetSideRequest( aReqNo, aStatus, a1, a2 );
+ }
+ else
+ {
+ // unknown unit
+
+ TraceDump(ERROR_LEVEL,
+ ("WLANLDD: DWlanLogicalChannel::DoRequest(): unknown request unit panic"));
+ TraceDump(ERROR_LEVEL, (("WLANLDD: request id: %d"), aReqNo));
+ TraceDump(ERROR_LEVEL, (("WLANLDD: unit: %d"), iUnit));
+ os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TInt DWlanLogicalChannel::OnInitialiseEthernetFrameBuffers(
+ TSharedChunkInfo* aSharedChunkInfo )
+ {
+ TInt ret( KErrNoMemory );
+
+ if ( iEthernetFrameMemMngr )
+ {
+ TUint8 notRelevant( 0 );
+ TUint8 vendorTxHdrLen ( 0 );
+ TUint8 vendorTxTrailerLen ( 0 );
+
+ iUmac.GetFrameExtraSpaceForVendor(
+ notRelevant,
+ vendorTxHdrLen,
+ vendorTxTrailerLen );
+
+ ret = iEthernetFrameMemMngr->OnInitialiseMemory(
+ *iClient,
+ aSharedChunkInfo,
+ vendorTxHdrLen,
+ vendorTxTrailerLen );
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::OnReleaseEthernetFrameBuffers()
+ {
+ if ( iEthernetFrameMemMngr )
+ {
+ iEthernetFrameMemMngr->OnReleaseMemory();
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TInt DWlanLogicalChannel::OnEthernetSideControl(
+ TInt aFunction,
+ TAny* a1,
+ TAny* /*a2*/ )
+ {
+ TInt ret(KErrNone);
+
+ switch (aFunction)
+ {
+ case RPcmNetCardIf::EControlGetConfig:
+ {
+ const TMacAddress& mac = iUmac.StationId();
+ TEtherConfig ethercfg = { NULL };
+
+ // 0x00 - card is ready, 0xff - card not ready.
+ ethercfg.iStatus = 0;
+ // Speed setting (0x00 to 0x03).
+ ethercfg.iEthSpeed = 0;
+ // Duplex setting (0x00 to 0x03)
+ ethercfg.iEthDuplex = 0;
+
+ // set STA MAC
+ os_memcpy( ethercfg.iEthAddress, &mac, KMacAddressLength );
+
+ // write config to USER mode
+ ret = Kern::ThreadRawWrite(
+ iClient,
+ a1,
+ ðercfg,
+ sizeof(ethercfg) );
+ 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__ );
+ }
+ break;
+ }
+ case RPcmNetCardIf::ESvControlInitBuffers:
+ // instruct initiliaze buffers for data xfer
+ if ( a1 )
+ {
+ // call
+ TraceDump(INIT_LEVEL,
+ ("WLANLDD * init protocol shared IO-buffer memory pool"));
+
+ TraceDump(INIT_LEVEL,
+ (("WLANLDD: DWlanLogicalChannel::OnEthernetSideControl: chunk info addr: 0x%08x"),
+ a1));
+ ret = OnInitialiseEthernetFrameBuffers(
+ static_cast<TSharedChunkInfo*>(a1) );
+
+ // set frame Tx offset for protocol stack side
+ iUmac.SetTxOffset();
+ }
+ else
+ {
+ TraceDump(ERROR_LEVEL,
+ ("WLANLDD: DWlanLogicalChannel::OnEthernetSideControl(): init protocol stack buffer pool panic"));
+ os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
+ }
+ break;
+ case RPcmNetCardIf::ESvControlFreeBuffers:
+ {
+ // instruct free buffers for data xfer
+ OnReleaseEthernetFrameBuffers();
+ break;
+ }
+ default:
+ // unhadled panic
+ TraceDump(ERROR_LEVEL,
+ ("WLANLDD: DWlanLogicalChannel::OnEthernetSideControl(): protocol stack side control panic"));
+ TraceDump(ERROR_LEVEL, (("function id: %d"), aFunction));
+ os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
+ break;
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TInt DWlanLogicalChannel::OnMgmtSideControl(
+ TInt aFunction,
+ TAny* a1,
+ TAny* /*a2*/ )
+ {
+ TInt ret( KErrNone );
+ if ( aFunction == EWlanSvControlInitBuffers )
+ {
+ // initiliaze buffers for wlan mgmt client data xfer
+ if ( a1 )
+ {
+ TraceDump(INIT_LEVEL,
+ ("WLANLDD: DWlanLogicalChannel::OnMgmtSideControl(): init management client shared IO-buffer memory pool"));
+
+ TraceDump(INIT_LEVEL,
+ (("WLANLDD: DWlanLogicalChannel::OnMgmtSideControl: chunk info addr: 0x%08x"),
+ a1));
+ ret = OnInitialiseEthernetFrameBuffers(
+ static_cast<TSharedChunkInfo*>(a1) );
+ }
+ else
+ {
+ TraceDump(ERROR_LEVEL,
+ ("WLANLDD: DWlanLogicalChannel::OnMgmtSideControl(): init management client buffer pool panic"));
+ os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
+ }
+ }
+ else if ( aFunction == EWlanSvControlFreeBuffers )
+ {
+ // free wlan mgmt client data xfer buffers
+ OnReleaseEthernetFrameBuffers();
+ }
+ else
+ {
+ // unknown request
+
+ TraceDump(ERROR_LEVEL,
+ ("WLANLDD: DWlanLogicalChannel::OnMgmtSideControl(): management side control panic"));
+ TraceDump(ERROR_LEVEL, (("WLANLDD: function id: %d"), aFunction));
+ os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TInt DWlanLogicalChannel::DoControl( TInt aFunction, TAny* a1, TAny* a2)
+ {
+ TInt ret( KErrNone );
+ if ( iUnit == KUnitWlan )
+ {
+ ret = OnMgmtSideControl( aFunction, a1, a2 );
+ }
+ else if ( iUnit == KUnitEthernet )
+ {
+ ret = OnEthernetSideControl( aFunction, a1, a2 );
+ }
+ else
+ {
+ // unknown unit
+
+ TraceDump(ERROR_LEVEL, ("WLANLDD: unhandled control unit panic"));
+ TraceDump(ERROR_LEVEL, (("WLANLDD: function id: %d"), aFunction));
+ TraceDump(ERROR_LEVEL, (("WLANLDD: unit: %d"), iUnit));
+ os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::OnOidCompleted(
+ TInt aReason,
+ SOidOutputData& OidOutputData )
+ {
+ if ( iFlags & KFreeOpenParamsMask )
+ {
+ // free open params
+ os_free( iOpenParam.iPda );
+ iOpenParam.iPda = NULL;
+ os_free( iOpenParam.iFirmWare );
+ iOpenParam.iFirmWare = NULL;
+ iFlags &= ~KFreeOpenParamsMask;
+ }
+ else
+ {
+ // check if there are other command parameter related memory blocks
+ // to be released
+ // Note! We check the flags already here to avoid unnecessary
+ // FreeXXX function calls
+
+ if ( iFlags & KFreeScanResponseFramebodyMask )
+ {
+ // free scan response frame body
+ FreeScanResponseFramebody();
+
+ // the following flags can be set only at the same time with
+ // KFreeScanResponseFramebodyMask
+
+ if ( iFlags & KFreeIeDataMask )
+ {
+ // free IE(s)
+ FreeIeData();
+ }
+ }
+ }
+
+ TraceDump(UMAC_MGMT_CALLBACK,
+ ("WLANLDD: DWlanLogicalChannel::OnOidCompleted()"));
+ TraceDump(UMAC_MGMT_CALLBACK, (("WLANLDD: OID: 0x%08x"),
+ OidOutputData.iOidId));
+ TraceDump(UMAC_MGMT_CALLBACK, (("WLANLDD: aReason: %d"), aReason));
+
+ if ( iWlanGeneralRequestStatus )
+ {
+ // write data to user mode if this happened to be a read request
+ if ( OidOutputData.iOidData )
+ {
+ TraceDump(UMAC_MGMT_CALLBACK, ("WLANLDD: write data to USER mode"));
+ TraceDump(UMAC_MGMT_CALLBACK, (("WLANLDD: length: %d"),
+ OidOutputData.iLengthOfDataInBytes));
+
+ const TInt ret
+ = Kern::ThreadRawWrite(
+ iClient,
+ OidOutputData.iBufferSupplied,
+ OidOutputData.iOidData,
+ OidOutputData.iLengthOfDataInBytes );
+
+ 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__ );
+ }
+ }
+
+ // complete the pending request to user mode
+ Kern::RequestComplete( iClient, iWlanGeneralRequestStatus, aReason );
+ // mark request as non pending
+ iWlanGeneralRequestStatus = NULL;
+ }
+ else // iReqStatus
+ {
+ // no pending request exists, so it must have been cancelled
+ // Nothing more to do here
+ TraceDump(UMAC_MGMT_CALLBACK,
+ ("WLANLDD: DWlanLogicalChannel::OnOidCompleted(): no pending request"));
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::SetMgmtSideTxOffsets(
+ TUint32 aEthernetFrameTxOffset,
+ TUint32 aDot11FrameTxOffset,
+ TUint32 aSnapFrameTxOffset )
+ {
+ if ( iEthernetFrameMemMngr )
+ {
+ TraceDump(NWSA_TX_DETAILS,
+ (("WLANLDD: DWlanLogicalChannel::SetMgmtSideTxOffsets: aEthernetFrameTxOffset: %d"),
+ aEthernetFrameTxOffset ));
+ TraceDump(NWSA_TX_DETAILS,
+ (("WLANLDD: DWlanLogicalChannel::SetMgmtSideTxOffsets: aDot11FrameTxOffset: %d"),
+ aDot11FrameTxOffset ));
+ TraceDump(NWSA_TX_DETAILS,
+ (("WLANLDD: DWlanLogicalChannel::SetMgmtSideTxOffsets: aSnapFrameTxOffset: %d"),
+ aSnapFrameTxOffset ));
+
+ iEthernetFrameMemMngr->SetTxOffsets(
+ aEthernetFrameTxOffset,
+ aDot11FrameTxOffset,
+ aSnapFrameTxOffset );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TUint8* DWlanLogicalChannel::GetBufferForRxData(
+ TUint aLengthinBytes )
+ {
+ TUint8* ret ( NULL );
+ if ( iEthernetFrameMemMngr )
+ {
+ ret = iEthernetFrameMemMngr->OnGetEthernetFrameRxBuffer(
+ aLengthinBytes );
+ }
+ else
+ {
+ TraceDump(RX_FRAME | WARNING_LEVEL,
+ ("WLANLDD: DWlanLogicalChannel::GetBufferForRxData: WARNING: no frame mgr => failed"));
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::MgmtDataReceiveComplete(
+ const TDataBuffer*& aBufferStart,
+ TUint32 aNumOfBuffers )
+ {
+ if ( iEthernetFrameMemMngr->OnEthernetFrameRxComplete(
+ aBufferStart,
+ aNumOfBuffers ) )
+ {
+ Kern::RequestComplete( iClient, iWlanReceiveFrameStatus, KErrNone );
+ iWlanReceiveFrameStatus = NULL;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::MgmtPathWriteComplete( TInt aErr )
+ {
+ TraceDump(UMAC_MGMT_CALLBACK,
+ ("WLANLDD: DWlanLogicalChannel::MgmtPathWriteComplete()"));
+ TraceDump(UMAC_MGMT_CALLBACK,
+ (("WLANLDD: aCompletionCode: %d"), aErr));
+
+ if ( iWlanSendFrameStatus )
+ {
+ // complete the pending request to user mode
+ Kern::RequestComplete(
+ iClient, iWlanSendFrameStatus, aErr );
+ // mark request as non pending
+ iWlanSendFrameStatus = NULL;
+ }
+ else // iReqStatus
+ {
+ // no pending request exists, so it must have been cancelled
+ // Nothing to do here
+ TraceDump(UMAC_MGMT_CALLBACK,
+ ("WLANLDD: DWlanLogicalChannel::MgmtPathWriteComplete(): no pending request"));
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+DWlanLogicalChannel::TIndicationListEntry*
+DWlanLogicalChannel::GetFreeIndicationListEntry()
+ {
+ TIndicationListEntry* newEntry = NULL;
+
+ if ( iFreeIndicationListHead )
+ {
+ newEntry = iFreeIndicationListHead;
+ iFreeIndicationListHead = newEntry->next;
+ newEntry->next = NULL;
+ }
+
+ return newEntry;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::StoreIndication( TIndication aIndication )
+ {
+ TIndicationListEntry* newEntry = GetFreeIndicationListEntry();
+
+ if ( !newEntry )
+ {
+ return;
+ }
+
+ newEntry->indication = aIndication;
+ newEntry->next = NULL;
+
+ if ( !iIndicationListHead )
+ {
+ iIndicationListHead = newEntry;
+ }
+ else
+ {
+ TIndicationListEntry *tmp = iIndicationListHead;
+
+ while ( tmp->next )
+ {
+ tmp = tmp->next;
+ }
+
+ tmp->next = newEntry;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::IndicationComplete()
+ {
+ Kern::RequestComplete(
+ iClient, iWlanRequestNotifyStatus, KErrNone );
+ iWlanRequestNotifyStatus = NULL;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TBool DWlanLogicalChannel::GetStoredIndication()
+ {
+ TIndicationListEntry *tmp = NULL;
+
+ if ( !iIndicationListHead )
+ {
+ return EFalse;
+ }
+
+ TraceDump(WLM_INDICATION,
+ (("WLANLDD: DWlanLogicalChannel::GetStoredIndication(): indication complete: %d"),
+ iIndicationListHead->indication));
+
+ const TInt ret = Kern::ThreadRawWrite( iClient, iIndicationBuffer,
+ &( iIndicationListHead->indication ),
+ sizeof(iIndicationListHead->indication) );
+
+ 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__ );
+ }
+
+ tmp = iIndicationListHead;
+ iIndicationListHead = tmp->next;
+
+ ReleaseIndicationListEntry( tmp );
+
+ return ETrue;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::TryToCompleteIndicationRequest()
+ {
+ if ( iIndicationBuffer )
+ {
+ if ( GetStoredIndication() )
+ {
+ IndicationComplete();
+ iIndicationBuffer = NULL;
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::OnInDicationEvent( TIndication aIndication )
+ {
+ StoreIndication( aIndication );
+ TryToCompleteIndicationRequest();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::FreeIndicationList()
+ {
+ // Free the indication list entries
+ TIndicationListEntry *iter = iFreeIndicationListHead;
+ TIndicationListEntry *next = NULL;
+
+ while ( iter )
+ {
+ next = iter->next;
+
+ TraceDump(MEMORY, (("WLANLDD: delete TIndicationListEntry: 0x%08x"),
+ reinterpret_cast<TUint32>(iter)));
+
+ delete iter;
+
+ iter = next;
+ }
+
+ iFreeIndicationListHead = NULL;
+ iIndicationListHead = NULL;
+ iIndicationBuffer = NULL;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::CancelIndicationRequest()
+ {
+ iIndicationBuffer = NULL;
+ PurgeIndicationList();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::PurgeIndicationList()
+ {
+ TIndicationListEntry* iter = iIndicationListHead;
+ TIndicationListEntry* next = NULL;
+
+ while ( iter )
+ {
+ next = iter->next;
+
+ ReleaseIndicationListEntry( iter );
+
+ iter = next;
+ }
+
+ iIndicationListHead = NULL;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::IndicationRequest( TIndication* aBuffer )
+ {
+ iIndicationBuffer = aBuffer;
+ TryToCompleteIndicationRequest();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::ReleaseIndicationListEntry(
+ TIndicationListEntry* aEntry )
+ {
+ aEntry->next = NULL;
+
+ if ( !iFreeIndicationListHead )
+ {
+ iFreeIndicationListHead = aEntry;
+ }
+ else
+ {
+ TIndicationListEntry* tmp = iFreeIndicationListHead;
+
+ while ( tmp->next )
+ {
+ tmp = tmp->next;
+ }
+
+ tmp->next = aEntry;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::MarkRxBufFree( TUint8* aBufferToFree )
+ {
+ if ( iEthernetFrameMemMngr )
+ {
+ iEthernetFrameMemMngr->DoMarkRxBufFree( aBufferToFree );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::RealTimerDfc()
+ {
+ // acquire mutex
+
+#ifndef RD_WLAN_DDK
+ Kern::MutexWait( iMutex );
+#else
+ iOsa->MutexAcquire();
+#endif
+
+ TraceDump(MUTEX,
+ (("WLANLDD: DWlanLogicalChannel::RealTimerDfc(): mutex acquired")));
+
+ iUmac.OnTimeout( EWlanDefaultTimer );
+
+ // release mutex
+
+#ifndef RD_WLAN_DDK
+ Kern::MutexSignal( iMutex );
+#else
+ iOsa->MutexRelease();
+#endif
+
+ TraceDump(MUTEX,
+ (("WLANLDD: DWlanLogicalChannel::RealTimerDfc(): mutex released")));
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::TimerDfcDoToggle( TAny* aPtr )
+ {
+ DWlanLogicalChannel* ptr = static_cast<DWlanLogicalChannel*>(aPtr);
+ ptr->RealTimerDfc();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::RealDfc()
+ {
+ // acquire mutex
+
+#ifndef RD_WLAN_DDK
+ Kern::MutexWait( iMutex );
+#else
+ iOsa->MutexAcquire();
+#endif
+
+ TraceDump(MUTEX,
+ (("WLANLDD: DWlanLogicalChannel::RealDfc: mutex acquired")));
+
+ if ( !(iFlags & KDfcCancelledMask) )
+ {
+ iUmac.OnDfc( iDfcCtx );
+ }
+
+ // release mutex
+
+#ifndef RD_WLAN_DDK
+ Kern::MutexSignal( iMutex );
+#else
+ iOsa->MutexRelease();
+#endif
+
+ TraceDump(MUTEX,
+ (("WLANLDD: DWlanLogicalChannel::RealDfc: mutex released")));
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::DfcDoToggle( TAny* aPtr )
+ {
+ DWlanLogicalChannel* ptr( static_cast<DWlanLogicalChannel*>(aPtr) );
+ ptr->RealDfc();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::OnTimeOut( TAny *aPtr )
+ {
+ DWlanLogicalChannel* p = static_cast<DWlanLogicalChannel*>(aPtr);
+
+ // queue to a DFC for completion
+ p->iTimerDfc.Add();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::RealVoiceCallEntryTimerDfc()
+ {
+ // acquire mutex
+
+#ifndef RD_WLAN_DDK
+ Kern::MutexWait( iMutex );
+#else
+ iOsa->MutexAcquire();
+#endif
+
+ TraceDump(MUTEX,
+ (("WLANLDD: DWlanLogicalChannel::RealVoiceCallEntryTimerDfc(): mutex acquired")));
+
+ iUmac.OnTimeout( EWlanVoiceCallEntryTimer );
+
+ // release mutex
+
+#ifndef RD_WLAN_DDK
+ Kern::MutexSignal( iMutex );
+#else
+ iOsa->MutexRelease();
+#endif
+
+ TraceDump(MUTEX,
+ (("WLANLDD: DWlanLogicalChannel::RealVoiceCallEntryTimerDfc(): mutex released")));
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::VoiceCallEntryTimerDfcDoToggle( TAny* aPtr )
+ {
+ DWlanLogicalChannel* ptr = static_cast<DWlanLogicalChannel*>(aPtr);
+ ptr->RealVoiceCallEntryTimerDfc();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::OnVoiceCallEntryTimerTimeOut( TAny *aPtr )
+ {
+ DWlanLogicalChannel* p = static_cast<DWlanLogicalChannel*>(aPtr);
+
+ // queue to a DFC for completion
+ p->iVoiceCallEntryTimerDfc.Add();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::RealNullTimerDfc()
+ {
+ // acquire mutex
+
+#ifndef RD_WLAN_DDK
+ Kern::MutexWait( iMutex );
+#else
+ iOsa->MutexAcquire();
+#endif
+
+ TraceDump(MUTEX,
+ (("WLANLDD: DWlanLogicalChannel::RealNullTimerDfc(): mutex acquired")));
+
+ iUmac.OnTimeout( EWlanNullTimer );
+
+ // release mutex
+
+#ifndef RD_WLAN_DDK
+ Kern::MutexSignal( iMutex );
+#else
+ iOsa->MutexRelease();
+#endif
+
+ TraceDump(MUTEX,
+ (("WLANLDD: DWlanLogicalChannel::RealNullTimerDfc(): mutex released")));
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::NullTimerDfcDoToggle( TAny* aPtr )
+ {
+ DWlanLogicalChannel* ptr = static_cast<DWlanLogicalChannel*>(aPtr);
+ ptr->RealNullTimerDfc();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::OnNullTimerTimeOut( TAny *aPtr )
+ {
+ DWlanLogicalChannel* p = static_cast<DWlanLogicalChannel*>(aPtr);
+
+ // queue to a DFC for completion
+ p->iNullTimerDfc.Add();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::RealNoVoiceTimerDfc()
+ {
+ // acquire mutex
+
+#ifndef RD_WLAN_DDK
+ Kern::MutexWait( iMutex );
+#else
+ iOsa->MutexAcquire();
+#endif
+
+ TraceDump(MUTEX,
+ (("WLANLDD: DWlanLogicalChannel::RealNoVoiceTimerDfc: mutex acquired")));
+
+ iUmac.OnTimeout( EWlanNoVoiceTimer );
+
+ // release mutex
+
+#ifndef RD_WLAN_DDK
+ Kern::MutexSignal( iMutex );
+#else
+ iOsa->MutexRelease();
+#endif
+
+ TraceDump(MUTEX,
+ (("WLANLDD: DWlanLogicalChannel::RealNoVoiceTimerDfc: mutex released")));
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::NoVoiceTimerDfcDoToggle( TAny* aPtr )
+ {
+ DWlanLogicalChannel* ptr = static_cast<DWlanLogicalChannel*>(aPtr);
+ ptr->RealNoVoiceTimerDfc();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::OnNoVoiceTimerTimeOut( TAny *aPtr )
+ {
+ DWlanLogicalChannel* p = static_cast<DWlanLogicalChannel*>(aPtr);
+
+ // queue to a DFC for completion
+ p->iNoVoiceTimerDfc.Add();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::RealKeepAliveTimerDfc()
+ {
+ // acquire mutex
+
+#ifndef RD_WLAN_DDK
+ Kern::MutexWait( iMutex );
+#else
+ iOsa->MutexAcquire();
+#endif
+
+ TraceDump(MUTEX,
+ (("WLANLDD: DWlanLogicalChannel::RealKeepAliveTimerDfc: mutex acquired")));
+
+ iUmac.OnTimeout( EWlanKeepAliveTimer );
+
+ // release mutex
+
+#ifndef RD_WLAN_DDK
+ Kern::MutexSignal( iMutex );
+#else
+ iOsa->MutexRelease();
+#endif
+
+ TraceDump(MUTEX,
+ (("WLANLDD: DWlanLogicalChannel::RealKeepAliveTimerDfc: mutex released")));
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::KeepAliveTimerDfcDoToggle( TAny* aPtr )
+ {
+ DWlanLogicalChannel* ptr = static_cast<DWlanLogicalChannel*>(aPtr);
+ ptr->RealKeepAliveTimerDfc();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::OnKeepAliveTimerTimeOut( TAny *aPtr )
+ {
+ DWlanLogicalChannel* p = static_cast<DWlanLogicalChannel*>(aPtr);
+
+ // queue to a DFC for completion
+ p->iKeepAliveTimerDfc.Add();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::RealActiveToLightPsTimerDfc()
+ {
+ // acquire mutex
+
+#ifndef RD_WLAN_DDK
+ Kern::MutexWait( iMutex );
+#else
+ iOsa->MutexAcquire();
+#endif
+
+ TraceDump(MUTEX,
+ (("WLANLDD: DWlanLogicalChannel::RealActiveToLightPsTimerDfc: mutex acquired")));
+
+ iUmac.OnTimeout( EWlanActiveToLightPsTimer );
+
+ // release mutex
+
+#ifndef RD_WLAN_DDK
+ Kern::MutexSignal( iMutex );
+#else
+ iOsa->MutexRelease();
+#endif
+
+ TraceDump(MUTEX,
+ (("WLANLDD: DWlanLogicalChannel::RealActiveToLightPsTimerDfc: mutex released")));
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::ActiveToLightPsTimerDfcDoToggle( TAny* aPtr )
+ {
+ DWlanLogicalChannel* ptr = static_cast<DWlanLogicalChannel*>(aPtr);
+ ptr->RealActiveToLightPsTimerDfc();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::OnActiveToLightPsTimerTimeOut( TAny *aPtr )
+ {
+ DWlanLogicalChannel* p = static_cast<DWlanLogicalChannel*>(aPtr);
+
+ // queue to a DFC for completion
+ p->iActiveToLightPsTimerDfc.Add();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::RealLightPsToActiveTimerDfc()
+ {
+ // acquire mutex
+
+#ifndef RD_WLAN_DDK
+ Kern::MutexWait( iMutex );
+#else
+ iOsa->MutexAcquire();
+#endif
+
+ TraceDump(MUTEX,
+ (("WLANLDD: DWlanLogicalChannel::RealLightPsToActiveTimerDfc: mutex acquired")));
+
+ iUmac.OnTimeout( EWlanLightPsToActiveTimer );
+
+ // release mutex
+
+#ifndef RD_WLAN_DDK
+ Kern::MutexSignal( iMutex );
+#else
+ iOsa->MutexRelease();
+#endif
+
+ TraceDump(MUTEX,
+ (("WLANLDD: DWlanLogicalChannel::RealLightPsToActiveTimerDfc: mutex released")));
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::LightPsToActiveTimerDfcDoToggle( TAny* aPtr )
+ {
+ DWlanLogicalChannel* ptr = static_cast<DWlanLogicalChannel*>(aPtr);
+ ptr->RealLightPsToActiveTimerDfc();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::OnLightPsToActiveTimerTimeOut( TAny *aPtr )
+ {
+ DWlanLogicalChannel* p = static_cast<DWlanLogicalChannel*>(aPtr);
+
+ // queue to a DFC for completion
+ p->iLightPsToActiveTimerDfc.Add();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::RealLightPsToDeepPsTimerDfc()
+ {
+ // acquire mutex
+
+#ifndef RD_WLAN_DDK
+ Kern::MutexWait( iMutex );
+#else
+ iOsa->MutexAcquire();
+#endif
+
+ TraceDump(MUTEX,
+ (("WLANLDD: DWlanLogicalChannel::RealLightPsToDeepPsTimerDfc: mutex acquired")));
+
+ iUmac.OnTimeout( EWlanLightPsToDeepPsTimer );
+
+ // release mutex
+
+#ifndef RD_WLAN_DDK
+ Kern::MutexSignal( iMutex );
+#else
+ iOsa->MutexRelease();
+#endif
+
+ TraceDump(MUTEX,
+ (("WLANLDD: DWlanLogicalChannel::RealLightPsToDeepPsTimerDfc: mutex released")));
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::LightPsToDeepPsTimerDfcDoToggle( TAny* aPtr )
+ {
+ DWlanLogicalChannel* ptr = static_cast<DWlanLogicalChannel*>(aPtr);
+ ptr->RealLightPsToDeepPsTimerDfc();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::OnLightPsToDeepPsTimerTimeOut( TAny *aPtr )
+ {
+ DWlanLogicalChannel* p = static_cast<DWlanLogicalChannel*>(aPtr);
+
+ // queue to a DFC for completion
+ p->iLightPsToDeepPsTimerDfc.Add();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::RegisterTimeout(
+ TUint32 aTimeoutInMicroSeconds,
+ TWlanTimer aTimer )
+ {
+ TraceDump(INFO_LEVEL,
+ (("WLANLDD: DWlanLogicalChannel::RegisterTimeout: timer: %d"),
+ aTimer));
+ TraceDump(INFO_LEVEL,
+ (("WLANLDD: DWlanLogicalChannel::RegisterTimeout: aTimeoutInMicroSeconds: %d"),
+ aTimeoutInMicroSeconds));
+
+ const TInt KThousand = 1000;
+
+ switch ( aTimer )
+ {
+ case EWlanDefaultTimer:
+ iTimer.OneShot(
+ // convert timeout 1st to milliseconds & then to NKern ticks
+ NKern::TimerTicks( aTimeoutInMicroSeconds / KThousand ),
+ // request completion in ISR context
+ EFalse );
+ break;
+ case EWlanVoiceCallEntryTimer:
+ iVoiceCallEntryTimer.OneShot(
+ // convert timeout 1st to milliseconds & then to NKern ticks
+ NKern::TimerTicks( aTimeoutInMicroSeconds / KThousand ),
+ // request completion in ISR context
+ EFalse );
+ break;
+ case EWlanNullTimer:
+ iNullTimer.OneShot(
+ // convert timeout 1st to milliseconds & then to NKern ticks
+ NKern::TimerTicks( aTimeoutInMicroSeconds / KThousand ),
+ // request completion in ISR context
+ EFalse );
+ break;
+ case EWlanNoVoiceTimer:
+ iNoVoiceTimer.OneShot(
+ // convert timeout 1st to milliseconds & then to NKern ticks
+ NKern::TimerTicks( aTimeoutInMicroSeconds / KThousand ),
+ // request completion in ISR context
+ EFalse );
+ break;
+ case EWlanKeepAliveTimer:
+ iKeepAliveTimer.OneShot(
+ // convert timeout 1st to milliseconds & then to NKern ticks
+ NKern::TimerTicks( aTimeoutInMicroSeconds / KThousand ),
+ // request completion in ISR context
+ EFalse );
+ break;
+ case EWlanActiveToLightPsTimer:
+ iActiveToLightPsTimer.OneShot(
+ // convert timeout 1st to milliseconds & then to NKern ticks
+ NKern::TimerTicks( aTimeoutInMicroSeconds / KThousand ),
+ // request completion in ISR context
+ EFalse );
+ break;
+ case EWlanLightPsToActiveTimer:
+ iLightPsToActiveTimer.OneShot(
+ // convert timeout 1st to milliseconds & then to NKern ticks
+ NKern::TimerTicks( aTimeoutInMicroSeconds / KThousand ),
+ // request completion in ISR context
+ EFalse );
+ break;
+ case EWlanLightPsToDeepPsTimer:
+ iLightPsToDeepPsTimer.OneShot(
+ // convert timeout 1st to milliseconds & then to NKern ticks
+ NKern::TimerTicks( aTimeoutInMicroSeconds / KThousand ),
+ // request completion in ISR context
+ EFalse );
+ break;
+ default:
+ TraceDump(ERROR_LEVEL,
+ (("WLANLDD: DWlanLogicalChannel::RegisterTimeout: panic, unknown timer: %d"),
+ aTimer));
+ os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::CancelTimeout( TWlanTimer aTimer )
+ {
+ TraceDump(INFO_LEVEL,
+ (("WLANLDD: DWlanLogicalChannel::CancelTimeout: timer: %d"),
+ aTimer));
+
+ switch ( aTimer )
+ {
+ case EWlanDefaultTimer:
+ iTimer.Cancel();
+ iTimerDfc.Cancel();
+ break;
+ case EWlanVoiceCallEntryTimer:
+ iVoiceCallEntryTimer.Cancel();
+ iVoiceCallEntryTimerDfc.Cancel();
+ break;
+ case EWlanNullTimer:
+ iNullTimer.Cancel();
+ iNullTimerDfc.Cancel();
+ break;
+ case EWlanNoVoiceTimer:
+ iNoVoiceTimer.Cancel();
+ iNoVoiceTimerDfc.Cancel();
+ break;
+ case EWlanKeepAliveTimer:
+ iKeepAliveTimer.Cancel();
+ iKeepAliveTimerDfc.Cancel();
+ break;
+ case EWlanActiveToLightPsTimer:
+ iActiveToLightPsTimer.Cancel();
+ iActiveToLightPsTimerDfc.Cancel();
+ break;
+ case EWlanLightPsToActiveTimer:
+ iLightPsToActiveTimer.Cancel();
+ iLightPsToActiveTimerDfc.Cancel();
+ break;
+ case EWlanLightPsToDeepPsTimer:
+ iLightPsToDeepPsTimer.Cancel();
+ iLightPsToDeepPsTimerDfc.Cancel();
+ break;
+ default:
+ TraceDump(ERROR_LEVEL,
+ (("WLANLDD: DWlanLogicalChannel::CancelTimeout: panic, unknown timer: %d"),
+ aTimer));
+ os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::RegisterDfc( TAny* aCntx )
+ {
+ iFlags &= ~KDfcCancelledMask;
+ iDfcCtx = aCntx;
+ iDfc.Enque();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::CancelDfc()
+ {
+ iFlags |= KDfcCancelledMask;
+ iDfc.Cancel();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::RealTxTriggerDfc()
+ {
+ // acquire mutex
+
+#ifndef RD_WLAN_DDK
+ Kern::MutexWait( iMutex );
+#else
+ iOsa->MutexAcquire();
+#endif
+
+ TraceDump(MUTEX,
+ ("WLANLDD: DWlanLogicalChannel::RealTxTriggerDfc: mutex acquired"));
+
+ iFlags &= ~KTxTriggerArmed;
+ TxProtocolStackData();
+
+ // release mutex
+
+#ifndef RD_WLAN_DDK
+ Kern::MutexSignal( iMutex );
+#else
+ iOsa->MutexRelease();
+#endif
+
+ TraceDump(MUTEX,
+ ("WLANLDD: DWlanLogicalChannel::RealTxTriggerDfc: mutex released"));
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::TxTriggerDfcDoToggle( TAny* aPtr )
+ {
+ DWlanLogicalChannel* ptr( static_cast<DWlanLogicalChannel*>(aPtr) );
+ ptr->RealTxTriggerDfc();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+TDataBuffer* DWlanLogicalChannel::GetRxFrameMetaHeader()
+ {
+ TDataBuffer* metaHdr ( NULL );
+ if ( iEthernetFrameMemMngr )
+ {
+ metaHdr = iEthernetFrameMemMngr->GetRxFrameMetaHeader();
+ }
+ else
+ {
+ TraceDump(RX_FRAME | WARNING_LEVEL,
+ ("WLANLDD: DWlanLogicalChannel::GetRxFrameMetaHeader: WARNING: no frame mgr => failed"));
+ }
+
+ return metaHdr;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::FreeRxFrameMetaHeader( TDataBuffer* aMetaHeader )
+ {
+ if ( iEthernetFrameMemMngr )
+ {
+ iEthernetFrameMemMngr->FreeRxFrameMetaHeader( aMetaHeader );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::OnPowerUp()
+ {
+ // acquire mutex
+
+#ifndef RD_WLAN_DDK
+ Kern::MutexWait( iMutex );
+#else
+ iOsa->MutexAcquire();
+#endif
+
+ TraceDump(MUTEX,
+ (("WLANLDD: DWlanLogicalChannel::OnPowerUp: mutex acquired")));
+
+ // No real action in this case; so just inform that we are done
+ iPowerHandler.OnPowerUpDone();
+
+ // release mutex
+
+#ifndef RD_WLAN_DDK
+ Kern::MutexSignal( iMutex );
+#else
+ iOsa->MutexRelease();
+#endif
+
+ TraceDump(MUTEX,
+ (("WLANLDD: DWlanLogicalChannel::OnPowerUp: mutex released")));
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//
+void DWlanLogicalChannel::OnPowerDown()
+ {
+ TraceDump(INIT_LEVEL,
+ (("WLANLDD: DWlanLogicalChannel::OnPowerDown")));
+
+ iPoweringDown = ETrue;
+
+ // acquire mutex
+
+#ifndef RD_WLAN_DDK
+ Kern::MutexWait( iMutex );
+#else
+ iOsa->MutexAcquire();
+#endif
+
+ TraceDump(MUTEX,
+ (("WLANLDD: DWlanLogicalChannel::OnPowerDown: mutex acquired")));
+
+ // Trigger power down indication to wlanengine
+ iUmac.OnInDicationEvent( EOsPowerStandby );
+
+ // release mutex
+
+#ifndef RD_WLAN_DDK
+ Kern::MutexSignal( iMutex );
+#else
+ iOsa->MutexRelease();
+#endif
+
+ TraceDump(MUTEX,
+ (("WLANLDD: DWlanLogicalChannel::OnPowerDown: mutex released")));
+ }