wlan_bearer/wlanldd/wlan_common/umac_common/src/UmacTxRateAdaptation.cpp
changeset 0 c40eb8fe8501
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 WlanTxRateAdaptation class
       
    15 *
       
    16 */
       
    17 
       
    18 /*
       
    19 * %version: 21 %
       
    20 */
       
    21 
       
    22 #include "config.h"
       
    23 #include "UmacTxRateAdaptation.h"
       
    24 #include "UmacContextImpl.h"
       
    25 #include "wha_mibDefaultvalues.h"
       
    26 
       
    27 
       
    28 // ============================ MEMBER FUNCTIONS ===============================
       
    29 
       
    30 WlanTxRateAdaptation::WlanTxRateAdaptation()
       
    31     {
       
    32     OsTracePrint( KTxRateAdapt, (TUint8*)
       
    33         ("UMAC: WlanTxRateAdaptation::WlanTxRateAdaptation()"));
       
    34 
       
    35     // default values for the rate adaptation algorithm parameters
       
    36     //
       
    37     const TUint8 KDefaultMinStepUpCheckpoint        = 10;
       
    38     const TUint8 KDefaultMaxStepUpCheckpoint        = 60;
       
    39     const TUint8 KDefaultStepUpCheckpointFactor     = 2;
       
    40     const TUint8 KDefaultStepDownCheckpoint         = 3;
       
    41     const TUint8 KDefaultMinStepUpThreshold         = 70;
       
    42     const TUint8 KDefaultMaxStepUpThreshold         = 90;
       
    43     const TUint8 KDefaultStepUpThresholdIncrement   = 10;
       
    44     const TUint8 KDefaultStepDownThreshold          = 50;  
       
    45     
       
    46     iAlgorithmParam.iMinStepUpCheckpoint =
       
    47         KDefaultMinStepUpCheckpoint;
       
    48 
       
    49     iAlgorithmParam.iMaxStepUpCheckpoint =
       
    50         KDefaultMaxStepUpCheckpoint;
       
    51 
       
    52     iAlgorithmParam.iStepUpCheckpointFactor =
       
    53         KDefaultStepUpCheckpointFactor;
       
    54 
       
    55     iAlgorithmParam.iStepDownCheckpoint =
       
    56         KDefaultStepDownCheckpoint;
       
    57 
       
    58     iAlgorithmParam.iMinStepUpThreshold = 
       
    59         KDefaultMinStepUpThreshold;
       
    60 
       
    61     iAlgorithmParam.iMaxStepUpThreshold = 
       
    62         KDefaultMaxStepUpThreshold;
       
    63 
       
    64     iAlgorithmParam.iStepUpThresholdIncrement = 
       
    65         KDefaultStepUpThresholdIncrement;
       
    66 
       
    67     iAlgorithmParam.iStepDownThreshold = 
       
    68         KDefaultStepDownThreshold;
       
    69         
       
    70     iAlgorithmParam.iDisableProbeHandling = EFalse;
       
    71 
       
    72     for ( TUint32 j = 0; j != WHA::EQueueIdMax; ++j )
       
    73         {
       
    74         // initially every Tx queue is mapped to the same (general) Tx
       
    75         // policy
       
    76         iQueue2Policy[j] = WHA::KDefaultTxRatePolicyId;
       
    77         }
       
    78 
       
    79     for ( TUint32 i = 0; i != KMaxRatePolicyCount; ++i )
       
    80         {
       
    81         iPolicy[i].iCurrentTxRate = NULL;
       
    82         iPolicy[i].iHead = NULL;
       
    83         iPolicy[i].iTail = NULL;
       
    84         iPolicy[i].iNumOfRates = 0;
       
    85         
       
    86         iPolicy[i].iProbe = EFalse;
       
    87         iPolicy[i].iTxCount = 0;
       
    88         iPolicy[i].iTxFailCount = 0;
       
    89         iPolicy[i].iStepUpCheckpoint = KDefaultMinStepUpCheckpoint;
       
    90         iPolicy[i].iStepUpThreshold = KDefaultMinStepUpThreshold;
       
    91         }
       
    92     }
       
    93 
       
    94 // ---------------------------------------------------------------------------
       
    95 // 
       
    96 // ---------------------------------------------------------------------------
       
    97 //
       
    98 void WlanTxRateAdaptation::RateStepDown( SPolicy& aPolicy ) const
       
    99     {
       
   100     OsTracePrint( KTxRateAdapt, 
       
   101         (TUint8*)("UMAC: WlanTxRateAdaptation::RateStepDown(): old rate: 0x%08x"), 
       
   102         aPolicy.iCurrentTxRate->iBitRate);
       
   103 
       
   104     if ( aPolicy.iCurrentTxRate->iPrev )
       
   105         {
       
   106         // descent rate
       
   107         aPolicy.iCurrentTxRate = aPolicy.iCurrentTxRate->iPrev;
       
   108 
       
   109         OsTracePrint( KTxRateAdapt, 
       
   110             (TUint8*)("UMAC: WlanTxRateAdaptation::RateStepDown(): new rate: 0x%08x"), 
       
   111             aPolicy.iCurrentTxRate->iBitRate);
       
   112         }
       
   113     else
       
   114         {
       
   115         // we are already using the lowest rate
       
   116         // nothing to do
       
   117         OsTracePrint( KTxRateAdapt, (TUint8*)
       
   118             ("UMAC: WlanTxRateAdaptation::RateStepDown(): already using the lowest rate") );
       
   119         }
       
   120     }
       
   121 
       
   122 // ---------------------------------------------------------------------------
       
   123 // 
       
   124 // ---------------------------------------------------------------------------
       
   125 //
       
   126 TBool WlanTxRateAdaptation::RateStepUp( SPolicy& aPolicy ) const
       
   127     {
       
   128     OsTracePrint( KTxRateAdapt, 
       
   129         (TUint8*)("UMAC: WlanTxRateAdaptation::RateStepUp(): old rate: 0x%08x"), 
       
   130         aPolicy.iCurrentTxRate->iBitRate);
       
   131 
       
   132     TBool status( ETrue );
       
   133 
       
   134     if ( aPolicy.iCurrentTxRate->iNext )
       
   135         {
       
   136         // ascend rate
       
   137         aPolicy.iCurrentTxRate = aPolicy.iCurrentTxRate->iNext;
       
   138 
       
   139         OsTracePrint( KTxRateAdapt, 
       
   140             (TUint8*)("UMAC: WlanTxRateAdaptation::RateStepUp(): new rate: 0x%08x"), 
       
   141             aPolicy.iCurrentTxRate->iBitRate);
       
   142         }
       
   143     else
       
   144         {
       
   145         // we are already using the highest rate.
       
   146         // Indicate that to the caller
       
   147         status = EFalse;
       
   148 
       
   149         OsTracePrint( KTxRateAdapt, (TUint8*)
       
   150             ("UMAC: WlanTxRateAdaptation::RateStepUp(): already using the highest rate") );
       
   151         }
       
   152         
       
   153     return status;
       
   154     }
       
   155 
       
   156 // ---------------------------------------------------------------------------
       
   157 // 
       
   158 // ---------------------------------------------------------------------------
       
   159 //
       
   160 void WlanTxRateAdaptation::InsertRate( 
       
   161     TUint8 aPolicyIndex, SBitRate* aBlock ) const
       
   162     {
       
   163     OsTracePrint( KTxRateAdapt, (TUint8*)
       
   164         ("UMAC:  WlanTxRateAdaptation::InsertRate(): aPolicyIndex: %d"), 
       
   165         aPolicyIndex);
       
   166     OsTracePrint( KTxRateAdapt, 
       
   167         (TUint8*)("UMAC:  WlanTxRateAdaptation::InsertRate(): rate: 0x%08x"), 
       
   168         aBlock->iBitRate);
       
   169 
       
   170     // traverse our single linked list of rate entrys
       
   171     // and locate the correct place for the new rate
       
   172     SBitRate* ptr = iPolicy[aPolicyIndex].iHead;
       
   173     SBitRate* prev = ptr;
       
   174 
       
   175     do
       
   176         {
       
   177         if ( aBlock->iBitRate < ptr->iBitRate )
       
   178             {
       
   179             // rate to be inserted is smaller than 
       
   180             // the "current" rate
       
   181             break;
       
   182             }
       
   183 
       
   184         prev = ptr;
       
   185         ptr = ptr->iNext;
       
   186         } 
       
   187         while ( ptr );
       
   188     
       
   189     if ( ptr )
       
   190         {
       
   191         // correct slot found
       
   192         // link the new rate
       
   193         prev->iNext = aBlock;
       
   194         aBlock->iPrev = prev;
       
   195         aBlock->iNext = ptr;
       
   196         }    
       
   197     }
       
   198 
       
   199 // ---------------------------------------------------------------------------
       
   200 // 
       
   201 // ---------------------------------------------------------------------------
       
   202 //
       
   203 TBool WlanTxRateAdaptation::AppendRate( 
       
   204     TUint8 aPolicyIndex,
       
   205     WHA::TRate aRate )
       
   206     {
       
   207     OsTracePrint( KTxRateAdapt, (TUint8*)
       
   208         ("UMAC:  WlanTxRateAdaptation::AppendRate(): aPolicyIndex: %d"), 
       
   209         aPolicyIndex);
       
   210     OsTracePrint( KTxRateAdapt, (TUint8*)
       
   211         ("UMAC:  WlanTxRateAdaptation::AppendRate(): rate: 0x%08x"), aRate);
       
   212 
       
   213     // allocate a new block for the rate
       
   214     SBitRate* block 
       
   215         = static_cast<SBitRate*>(os_alloc( sizeof(SBitRate) ));
       
   216 
       
   217     if ( !block )
       
   218         {
       
   219         // alloc failure; we cannot continue
       
   220         OsTracePrint( KErrorLevel, 
       
   221             (TUint8*)("UMAC: WlanTxRateAdaptation::AppendRate(): alloc failure"));        
       
   222 
       
   223         return EFalse;
       
   224         }
       
   225 
       
   226     block->iBitRate = aRate;
       
   227     block->iNext = NULL;
       
   228     block->iPrev = NULL;
       
   229 
       
   230     if ( !iPolicy[aPolicyIndex].iHead )
       
   231         {
       
   232         // this is the first append
       
   233         
       
   234         iPolicy[aPolicyIndex].iHead = block;
       
   235         iPolicy[aPolicyIndex].iTail = iPolicy[aPolicyIndex].iHead;
       
   236         iPolicy[aPolicyIndex].iCurrentTxRate = block;
       
   237         ++iPolicy[aPolicyIndex].iNumOfRates;
       
   238         }
       
   239     else
       
   240         {
       
   241         // not the first rate to append
       
   242         
       
   243         if ( block->iBitRate > iPolicy[aPolicyIndex].iTail->iBitRate )
       
   244             {
       
   245             // new rate bigger than the last one
       
   246             // append to rear
       
   247             iPolicy[aPolicyIndex].iTail->iNext = block;
       
   248             block->iPrev = iPolicy[aPolicyIndex].iTail;
       
   249             // new tail
       
   250             iPolicy[aPolicyIndex].iTail = block;
       
   251             ++iPolicy[aPolicyIndex].iNumOfRates;
       
   252             }
       
   253         else if( block->iBitRate < iPolicy[aPolicyIndex].iTail->iBitRate )
       
   254             {
       
   255             // new rate smaller than the last one
       
   256             // insert the rate to the correct slot
       
   257             InsertRate( aPolicyIndex, block );
       
   258             ++iPolicy[aPolicyIndex].iNumOfRates;
       
   259             }
       
   260         else
       
   261             {
       
   262             // new rate equal to the last one
       
   263             // this cannot happen as we are setting the rates only once
       
   264             // and from a rate bitmask
       
   265             }
       
   266         }
       
   267 
       
   268     OsTracePrint( KTxRateAdapt, (TUint8*)
       
   269         ("UMAC: WlanTxRateAdaptation::AppendRate(): num of existing rates: %d"), 
       
   270         iPolicy[aPolicyIndex].iNumOfRates);
       
   271 
       
   272     return ETrue;
       
   273     }
       
   274 
       
   275 // ---------------------------------------------------------------------------
       
   276 // 
       
   277 // ---------------------------------------------------------------------------
       
   278 //
       
   279 void WlanTxRateAdaptation::Reset( SPolicy& aPolicy ) const
       
   280     {
       
   281     OsTracePrint( KTxRateAdapt, 
       
   282         (TUint8*)("UMAC: WlanTxRateAdaptation::Reset() a policy"));
       
   283 
       
   284     // dealloc all rates
       
   285     SBitRate* ptr =  aPolicy.iHead;
       
   286     SBitRate* cache =  ptr;
       
   287 
       
   288     while ( ptr )
       
   289         {
       
   290         cache = ptr;
       
   291         ptr = ptr->iNext;
       
   292 
       
   293         // free the previous one
       
   294         os_free( cache );        
       
   295         }
       
   296 
       
   297     aPolicy.iCurrentTxRate = NULL;
       
   298     aPolicy.iHead = NULL;
       
   299     aPolicy.iTail = NULL;
       
   300     aPolicy.iNumOfRates = 0;
       
   301     
       
   302     aPolicy.iProbe = EFalse;
       
   303     aPolicy.iTxCount = 0;
       
   304     aPolicy.iTxFailCount = 0;
       
   305     aPolicy.iStepUpCheckpoint = iAlgorithmParam.iMinStepUpCheckpoint;
       
   306     aPolicy.iStepUpThreshold = iAlgorithmParam.iMinStepUpThreshold;
       
   307     }
       
   308 
       
   309 // ---------------------------------------------------------------------------
       
   310 // 
       
   311 // ---------------------------------------------------------------------------
       
   312 //
       
   313 TBool WlanTxRateAdaptation::SetRates( 
       
   314     TUint8 aPolicyId,
       
   315     WHA::TRate aRateBitmask )
       
   316     {
       
   317     OsTracePrint( KTxRateAdapt, (TUint8*)
       
   318         ("UMAC: WlanTxRateAdaptation::SetRates(): aPolicyId: 0x%08x"), aPolicyId);
       
   319     OsTracePrint( KTxRateAdapt, (TUint8*)
       
   320         ("UMAC: WlanTxRateAdaptation::SetRates(): aRateBitmask: 0x%08x"), aRateBitmask);
       
   321 
       
   322     // make the list of rates; but 1st clear the list
       
   323     Reset( iPolicy[aPolicyId - 1] );
       
   324 
       
   325     // make rates from bitmask
       
   326     const TUint32 cntr_end( 32 );
       
   327     TUint32 cntr( 0 );
       
   328 
       
   329     for ( TUint32 bit = 1 ; cntr != cntr_end ; (bit <<= 1) )
       
   330         {
       
   331         if ( aRateBitmask & bit )
       
   332             {
       
   333             // rate is to be set
       
   334             if ( !AppendRate( aPolicyId - 1, aRateBitmask & bit ) )
       
   335                 {
       
   336                 return EFalse;
       
   337                 }
       
   338             }
       
   339 
       
   340         ++cntr;
       
   341         }
       
   342 
       
   343     // if we got this far, the rates are now in the list
       
   344     
       
   345     return ETrue;
       
   346     }
       
   347 
       
   348 // ---------------------------------------------------------------------------
       
   349 // 
       
   350 // ---------------------------------------------------------------------------
       
   351 //
       
   352 void WlanTxRateAdaptation::SetPolicy( 
       
   353     WHA::TQueueId aQueueId, 
       
   354     TUint8 aPolicyId )
       
   355     {
       
   356     OsTracePrint( KTxRateAdapt, 
       
   357         (TUint8*)("UMAC: WlanTxRateAdaptation::SetPolicy(): aQueueId: %d"), 
       
   358         aQueueId);
       
   359     OsTracePrint( KTxRateAdapt, 
       
   360         (TUint8*)("UMAC: WlanTxRateAdaptation::SetPolicy(): aPolicyId: %d"), 
       
   361         aPolicyId);
       
   362 
       
   363     iQueue2Policy[aQueueId] = aPolicyId;
       
   364     }
       
   365 
       
   366 // ---------------------------------------------------------------------------
       
   367 // 
       
   368 // ---------------------------------------------------------------------------
       
   369 //
       
   370 void WlanTxRateAdaptation::SetCurrentMaxTxRate( 
       
   371     TUint8 aPolicyId, 
       
   372     WHA::TRate aRate )
       
   373     {
       
   374     OsTracePrint( KTxRateAdapt, (TUint8*)
       
   375         ("UMAC:  WlanTxRateAdaptation::SetCurrentMaxTxRate(): aPolicyId: %d"), 
       
   376         aPolicyId );
       
   377     OsTracePrint( KTxRateAdapt, (TUint8*)
       
   378         ("UMAC:  WlanTxRateAdaptation::SetCurrentMaxTxRate(): aRate: 0x%08x"), 
       
   379         aRate );
       
   380 
       
   381     if ( !iPolicy[aPolicyId - 1].iNumOfRates )
       
   382         {
       
   383         // catch implementation error
       
   384         OsAssert( (TUint8*)("UMAC: panic: no rates defined"),
       
   385             (TUint8*)(WLAN_FILE), __LINE__ );
       
   386         }
       
   387 
       
   388     // traverse our single linked list of rate entrys from rear (i.e. from 
       
   389     // the highest) to front (i.e. to the lowest) and try to locate the 
       
   390     // provided rate entry, or the next lower one, so that it can be set as 
       
   391     // the current max tx rate
       
   392 
       
   393     SBitRate* ptr = iPolicy[aPolicyId - 1].iTail;
       
   394 
       
   395     do
       
   396         {
       
   397         if ( ptr->iBitRate <= aRate )
       
   398             {
       
   399             // found
       
   400             break;
       
   401             }
       
   402         else
       
   403             {
       
   404             ptr = ptr->iPrev;            
       
   405             }
       
   406         } 
       
   407         while ( ptr );
       
   408     
       
   409     if ( ptr )
       
   410         {
       
   411         // usable rate was found. Set it as the current rate
       
   412         iPolicy[aPolicyId - 1].iCurrentTxRate = ptr;        
       
   413         }
       
   414     else
       
   415         {
       
   416         // the provided max Tx rate is lower than any of the
       
   417         // rates in this rate policy. In this case we have to set the 
       
   418         // lowest rate in the policy as the current rate (even 
       
   419         // though it is higher than what was requested)
       
   420         iPolicy[aPolicyId - 1].iCurrentTxRate = iPolicy[aPolicyId - 1].iHead;
       
   421         }
       
   422 
       
   423     OsTracePrint( KTxRateAdapt, (TUint8*)
       
   424         ("UMAC:  WlanTxRateAdaptation::SetCurrentMaxTxRate(): current rate now set to: 0x%08x"), 
       
   425         iPolicy[aPolicyId - 1].iCurrentTxRate->iBitRate );
       
   426     }
       
   427 
       
   428 // ---------------------------------------------------------------------------
       
   429 // 
       
   430 // ---------------------------------------------------------------------------
       
   431 //
       
   432 void WlanTxRateAdaptation::SetAlgorithmParameters( 
       
   433     TUint8 aMinStepUpCheckpoint,
       
   434     TUint8 aMaxStepUpCheckpoint,
       
   435     TUint8 aStepUpCheckpointFactor,
       
   436     TUint8 aStepDownCheckpoint,
       
   437     TUint8 aMinStepUpThreshold,
       
   438     TUint8 aMaxStepUpThreshold,
       
   439     TUint8 aStepUpThresholdIncrement,
       
   440     TUint8 aStepDownThreshold,
       
   441     TBool aDisableProbeHandling )
       
   442     {
       
   443     OsTracePrint( KTxRateAdapt, (TUint8*)
       
   444         ("UMAC: WlanTxRateAdaptation::SetAlgorithmParameters") );
       
   445 
       
   446     iAlgorithmParam.iMinStepUpCheckpoint = aMinStepUpCheckpoint;
       
   447     iAlgorithmParam.iMaxStepUpCheckpoint = aMaxStepUpCheckpoint;
       
   448     iAlgorithmParam.iStepUpCheckpointFactor = aStepUpCheckpointFactor;
       
   449     iAlgorithmParam.iStepDownCheckpoint = aStepDownCheckpoint;
       
   450     iAlgorithmParam.iMinStepUpThreshold = aMinStepUpThreshold;
       
   451     iAlgorithmParam.iMaxStepUpThreshold = aMaxStepUpThreshold;
       
   452     iAlgorithmParam.iStepUpThresholdIncrement = aStepUpThresholdIncrement;
       
   453     iAlgorithmParam.iStepDownThreshold = aStepDownThreshold;
       
   454     iAlgorithmParam.iDisableProbeHandling = aDisableProbeHandling;
       
   455     }
       
   456 
       
   457 // ---------------------------------------------------------------------------
       
   458 // 
       
   459 // ---------------------------------------------------------------------------
       
   460 //
       
   461 void WlanTxRateAdaptation::RatePolicy( 
       
   462     const WlanContextImpl& aCtxImpl,
       
   463     WHA::TQueueId aQueueId,
       
   464     TBool aUseSpecialRatePolicy,
       
   465     WHA::TRate& aRate, 
       
   466     TUint8& aPolicyId ) const
       
   467     {
       
   468     aPolicyId = iQueue2Policy[aQueueId];
       
   469 
       
   470     if ( aCtxImpl.WHASettings().iCapability & 
       
   471          WHA::SSettings::KAutonomousRateAdapt )
       
   472         {
       
   473         // autonomous rate adaptation is being used, i.e. rate adaptation is
       
   474         // handled by lower layers. In this case it's not relevant to specify
       
   475         // a Max Tx Rate and the whole value is not applicable. So we return
       
   476         // zero        
       
   477         const WHA::TRate notRelevant( 0 );
       
   478         aRate = notRelevant;
       
   479         
       
   480         const TUint8 KSpecialTxAutoRatePolicy = 
       
   481             aCtxImpl.SpecialTxAutoRatePolicy();
       
   482         
       
   483         if ( aUseSpecialRatePolicy && KSpecialTxAutoRatePolicy )
       
   484             {
       
   485             aPolicyId = KSpecialTxAutoRatePolicy;
       
   486             }
       
   487         }
       
   488     else
       
   489         {
       
   490         // rate adaptation is handled by this object
       
   491         
       
   492         if ( !iPolicy[aPolicyId - 1].iNumOfRates )
       
   493             {
       
   494             OsAssert( (TUint8*)
       
   495                 ("UMAC: WlanTxRateAdaptation::RatePolicy(): panic: no rates defined"),
       
   496                 (TUint8*)(WLAN_FILE), __LINE__ );
       
   497             }
       
   498 
       
   499         if ( !iPolicy[aPolicyId - 1].iCurrentTxRate )
       
   500             {
       
   501             // catch implementation error
       
   502 
       
   503             OsTracePrint( KErrorLevel, 
       
   504                 (TUint8*)("UMAC: no current rate specified for policy id: %d"), 
       
   505                 aPolicyId );        
       
   506             OsAssert( (TUint8*)("UMAC: panic"), (TUint8*)(WLAN_FILE), __LINE__ );
       
   507             }
       
   508             
       
   509         // return the current Max Tx Rate
       
   510         aRate = iPolicy[aPolicyId - 1].iCurrentTxRate->iBitRate;    
       
   511         }
       
   512     }
       
   513 
       
   514 // ---------------------------------------------------------------------------
       
   515 // 
       
   516 // ---------------------------------------------------------------------------
       
   517 //
       
   518 void WlanTxRateAdaptation::OnTxCompleted( 
       
   519     WHA::TRate aRate, 
       
   520     TBool aSuccess,
       
   521     WHA::TQueueId aQueueId,
       
   522     WHA::TRate aRequestedRate )
       
   523     {
       
   524     OsTracePrint( KTxRateAdapt, (TUint8*)
       
   525         ("UMAC: WlanTxRateAdaptation::OnTxCompleted(): aRate: 0x%08x"), 
       
   526         aRate);
       
   527     OsTracePrint( KTxRateAdapt, (TUint8*)
       
   528         ("UMAC: WlanTxRateAdaptation::OnTxCompleted(): aSuccess: %d"), 
       
   529         aSuccess);
       
   530     OsTracePrint( KTxRateAdapt, (TUint8*)
       
   531         ("UMAC: WlanTxRateAdaptation::OnTxCompleted(): aQueueId: %d"), 
       
   532         aQueueId);
       
   533     OsTracePrint( KTxRateAdapt, (TUint8*)
       
   534         ("UMAC: WlanTxRateAdaptation::OnTxCompleted(): aRequestedRate: 0x%08x"), 
       
   535         aRequestedRate);
       
   536 
       
   537     TBool success( aSuccess );
       
   538 
       
   539     TUint8 policyId = iQueue2Policy[aQueueId];
       
   540     OsTracePrint( KTxRateAdapt, 
       
   541         (TUint8*)("UMAC: WlanTxRateAdaptation::OnTxCompleted(): policyId: %d"), 
       
   542         policyId);    
       
   543 
       
   544     if ( iPolicy[policyId - 1].iCurrentTxRate )
       
   545         {
       
   546         // as Current Tx Rate is defined for this policy, it means that
       
   547         // this rate adaptation object is configured and we can handle this 
       
   548         // event
       
   549            
       
   550         if ( aSuccess )
       
   551             {
       
   552             // the frame was successfully delivered to nw
       
   553             
       
   554             // from rate adaptation point of view we are interested in the 
       
   555             // actual Tx rate of the frame only if the current rate for the Tx
       
   556             // policy in question is still the same as the originally requested Tx
       
   557             // rate for this frame.
       
   558             // (After we have switched the curent rate to something else, we may
       
   559             // still receive Tx completions for frames which we have requested to 
       
   560             // be sent with the previous rate. We are not interested in their 
       
   561             // actual Tx rate any more.)
       
   562             if ( aRequestedRate == iPolicy[policyId - 1].iCurrentTxRate->iBitRate )
       
   563                 {
       
   564                 if ( aRate != aRequestedRate )
       
   565                     {
       
   566                     // actual Tx rate was different than the originally requested
       
   567                     // rate. This is a Tx "failure" from Tx rate adaptation point
       
   568                     // of view
       
   569                     OsTracePrint( KTxRateAdapt, (TUint8*)
       
   570                         ("UMAC: WlanTxRateAdaptation::OnTxCompleted(): succeeded with a different rate than requested"));
       
   571                     success = EFalse;
       
   572                     }
       
   573                 }
       
   574             else
       
   575                 {
       
   576                 // curent rate of the Tx policy in question not the same any more
       
   577                 // as the originally requested rate for this frame. The frame is
       
   578                 // ignored from Tx rate adaptation considerations            
       
   579                 OsTracePrint( KTxRateAdapt, (TUint8*)
       
   580                     ("UMAC: WlanTxRateAdaptation::OnTxCompleted(): current rate for this Tx policy not same any more as originally requested rate for this frame"));
       
   581                 OsTracePrint( KTxRateAdapt, (TUint8*)
       
   582                     ("UMAC: WlanTxRateAdaptation::OnTxCompleted(): frame ignored from Tx rate adaptation considerations"));
       
   583                 return;
       
   584                 }
       
   585             }
       
   586                 
       
   587         TRateStep rateStep = OnTxCompleted( success, iPolicy[policyId - 1] );
       
   588         
       
   589         switch ( rateStep )
       
   590             {
       
   591             case EStepUp:
       
   592                 if ( RateStepUp( iPolicy[policyId - 1] ) )
       
   593                     {
       
   594                     // step up succeeded (i.e. there was a higher rate to switch to)
       
   595 
       
   596                     // if probe frame handling hasn't been disabled, the next 
       
   597                     // transmitted frame will be handled as a probe frame
       
   598                     if ( !iAlgorithmParam.iDisableProbeHandling )
       
   599                         {
       
   600                         iPolicy[policyId - 1].iProbe = ETrue;                    
       
   601                         }                
       
   602                     }                
       
   603                 break;
       
   604             case EStepDown:
       
   605                 RateStepDown( iPolicy[policyId - 1] );
       
   606                 break;
       
   607             case EKeepCurrent:
       
   608                 // nothing to do here
       
   609                 break;
       
   610             default:
       
   611                 OsTracePrint( KErrorLevel, 
       
   612                     (TUint8*)("UMAC: unkown rate step: %d"), 
       
   613                     rateStep );        
       
   614                 OsAssert( (TUint8*)("UMAC: panic"), (TUint8*)(WLAN_FILE), __LINE__ );                        
       
   615             }    
       
   616         }
       
   617     else
       
   618         {
       
   619         // Current Tx Rate is not defined for this policy, which means that
       
   620         // this rate adaptation object is not configured (it has been
       
   621         // reset) and cannot handle the event. So we just discard it
       
   622         OsTracePrint( KTxRateAdapt, (TUint8*)
       
   623             ("UMAC: WlanTxRateAdaptation::OnTxCompleted(): Rate adaptation not configured. Tx complete event discarded"));
       
   624         }
       
   625     }
       
   626 
       
   627 // ---------------------------------------------------------------------------
       
   628 // 
       
   629 // ---------------------------------------------------------------------------
       
   630 //
       
   631 void WlanTxRateAdaptation::Reset()
       
   632     {
       
   633     OsTracePrint( KTxRateAdapt, 
       
   634         (TUint8*)("UMAC: WlanTxRateAdaptation::Reset() the whole object"));
       
   635 
       
   636     for ( TUint32 j = 0; j != WHA::EQueueIdMax; ++j )
       
   637         {
       
   638         // every Tx queue is mapped to the same (general) Tx policy
       
   639         iQueue2Policy[j] = WHA::KDefaultTxRatePolicyId;
       
   640         }
       
   641 
       
   642     for ( TUint32 i = 0; i != KMaxRatePolicyCount; ++i )
       
   643         {
       
   644         // reset the state of every individual Tx policy
       
   645         Reset( iPolicy[i] );
       
   646         }        
       
   647     }
       
   648 
       
   649 // ---------------------------------------------------------------------------
       
   650 // Note: The rate adaptation algorithm requires that:
       
   651 // iStepDownCheckpoint <= iStepUpCheckpoint and
       
   652 // iStepDownCheckpoint > 1 (or it can also be == 1 if iDisableProbeHandling
       
   653 // is ETrue)
       
   654 // ---------------------------------------------------------------------------
       
   655 //
       
   656 WlanTxRateAdaptation::TRateStep WlanTxRateAdaptation::OnTxCompleted( 
       
   657     TBool aSuccess,
       
   658     SPolicy& aPolicy ) const
       
   659     {
       
   660     TRateStep rateStep( EKeepCurrent );
       
   661 
       
   662     ++aPolicy.iTxCount;
       
   663 
       
   664     if ( !aSuccess )
       
   665         {
       
   666         ++aPolicy.iTxFailCount;
       
   667         }
       
   668 
       
   669     OsTracePrint( KTxRateAdapt, (TUint8*)
       
   670         ("UMAC: WlanTxRateAdaptation::OnTxCompleted(): iProbe (0 no/1 yes): %d"),
       
   671         aPolicy.iProbe );
       
   672     OsTracePrint( KTxRateAdapt, (TUint8*)
       
   673         ("UMAC: WlanTxRateAdaptation::OnTxCompleted(): iTxCount after counting this frame: %d"),
       
   674         aPolicy.iTxCount );
       
   675     OsTracePrint( KTxRateAdapt, (TUint8*)
       
   676         ("UMAC: WlanTxRateAdaptation::OnTxCompleted(): iTxFailCount after counting this frame: %d"),
       
   677         aPolicy.iTxFailCount );
       
   678     OsTracePrint( KTxRateAdapt, 
       
   679         (TUint8*)("UMAC: WlanTxRateAdaptation::OnTxCompleted(): iCurrentTxRate: 0x%08x"), 
       
   680         aPolicy.iCurrentTxRate->iBitRate);
       
   681     OsTracePrint( KTxRateAdapt, (TUint8*)
       
   682         ("UMAC: WlanTxRateAdaptation::OnTxCompleted(): iStepUpCheckpoint: %d"),
       
   683         aPolicy.iStepUpCheckpoint  );
       
   684     OsTracePrint( KTxRateAdapt, (TUint8*)
       
   685         ("UMAC: WlanTxRateAdaptation::OnTxCompleted(): iStepUpThreshold: %d"),
       
   686         aPolicy.iStepUpThreshold  );
       
   687 
       
   688     if ( aPolicy.iProbe )
       
   689         {
       
   690         // this was a probe frame; check if a rate change is needed
       
   691         
       
   692         if ( !aSuccess )
       
   693             {
       
   694             // either the Tx failed completely or it succeeded at a lower 
       
   695             // rate than requested
       
   696 
       
   697             OsTracePrint( KTxRateAdapt, (TUint8*)
       
   698                 ("UMAC: WlanTxRateAdaptation::OnTxCompleted(): probe failure"));
       
   699             
       
   700             // decrement the rate
       
   701             rateStep = EStepDown;
       
   702 
       
   703             aPolicy.iStepUpCheckpoint = 
       
   704                 ( aPolicy.iStepUpCheckpoint * 
       
   705                   iAlgorithmParam.iStepUpCheckpointFactor 
       
   706                   > iAlgorithmParam.iMaxStepUpCheckpoint ) ? 
       
   707                  iAlgorithmParam.iMaxStepUpCheckpoint :
       
   708                  aPolicy.iStepUpCheckpoint * 
       
   709                  iAlgorithmParam.iStepUpCheckpointFactor;
       
   710             
       
   711             aPolicy.iStepUpThreshold = 
       
   712                 ( aPolicy.iStepUpThreshold + 
       
   713                   iAlgorithmParam.iStepUpThresholdIncrement
       
   714                 > iAlgorithmParam.iMaxStepUpThreshold ) ?
       
   715                 iAlgorithmParam.iMaxStepUpThreshold :
       
   716                 aPolicy.iStepUpThreshold + 
       
   717                 iAlgorithmParam.iStepUpThresholdIncrement;
       
   718             
       
   719             OsTracePrint( KTxRateAdapt, (TUint8*)
       
   720                 ("UMAC: WlanTxRateAdaptation::OnTxCompleted(): new iStepUpCheckpoint: %d"),
       
   721                 aPolicy.iStepUpCheckpoint  );
       
   722             OsTracePrint( KTxRateAdapt, (TUint8*)
       
   723                 ("UMAC: WlanTxRateAdaptation::OnTxCompleted(): new iStepUpThreshold: %d"),
       
   724                 aPolicy.iStepUpThreshold  );
       
   725 
       
   726             aPolicy.iTxCount = 0;
       
   727             aPolicy.iTxFailCount = 0;                
       
   728             }
       
   729         else
       
   730             {
       
   731             // Tx success with requested rate; nothing more to do
       
   732             }  
       
   733                           
       
   734         // in any case clear the probe flag
       
   735         aPolicy.iProbe = EFalse;
       
   736         }
       
   737     else 
       
   738         {        
       
   739         if ( aPolicy.iTxCount % iAlgorithmParam.iStepDownCheckpoint == 0 )
       
   740             {
       
   741             // check if the rate should be decremented
       
   742             OsTracePrint( KTxRateAdapt, (TUint8*)
       
   743                 ("UMAC: WlanTxRateAdaptation::OnTxCompleted(): check for decrement need"));
       
   744 
       
   745             if ( aPolicy.iTxFailCount * 100 
       
   746                  >= iAlgorithmParam.iStepDownThreshold * aPolicy.iTxCount )
       
   747                 {
       
   748                 // at least iStepDownThreshold % of iTxCount frames have 
       
   749                 // "failed" => decrement rate
       
   750                 //
       
   751                 rateStep = EStepDown;                  
       
   752                 aPolicy.iStepUpCheckpoint = 
       
   753                     iAlgorithmParam.iMinStepUpCheckpoint;
       
   754                 aPolicy.iStepUpThreshold = 
       
   755                     iAlgorithmParam.iMinStepUpThreshold;
       
   756 
       
   757                 aPolicy.iTxCount = 0;
       
   758                 aPolicy.iTxFailCount = 0;
       
   759                 }            
       
   760             }
       
   761 
       
   762         if ( rateStep != EStepDown && 
       
   763             aPolicy.iTxCount >= aPolicy.iStepUpCheckpoint )
       
   764             {
       
   765             // check if the rate should be incremented
       
   766             OsTracePrint( KTxRateAdapt, (TUint8*)
       
   767                 ("UMAC: WlanTxRateAdaptation::OnTxCompleted(): check for increment need"));
       
   768             
       
   769             if ( ( aPolicy.iTxCount - aPolicy.iTxFailCount ) * 100 
       
   770                  >= aPolicy.iStepUpThreshold *  aPolicy.iTxCount )
       
   771                 {
       
   772                 // at least iStepUpThreshold % of iTxCount frames have 
       
   773                 // "succeeded" => increment rate
       
   774                 //
       
   775                 rateStep = EStepUp;
       
   776                 }
       
   777                 
       
   778             aPolicy.iTxCount = 0;
       
   779             aPolicy.iTxFailCount = 0;
       
   780             }
       
   781         }
       
   782         
       
   783     OsTracePrint( KTxRateAdapt, (TUint8*)
       
   784         ("UMAC: WlanTxRateAdaptation::OnTxCompleted(): rateStep: %d (keep = 0, down, up)"),
       
   785         rateStep );
       
   786 
       
   787     return rateStep;
       
   788     }