linux/drivers/staging/rtl8188eu/hal/Hal8188ERateAdaptive.c
<<
>>
Prefs
   1/*++
   2Copyright (c) Realtek Semiconductor Corp. All rights reserved.
   3
   4Module Name:
   5        RateAdaptive.c
   6
   7Abstract:
   8        Implement Rate Adaptive functions for common operations.
   9
  10Major Change History:
  11        When       Who               What
  12        ---------- ---------------   -------------------------------
  13        2011-08-12 Page            Create.
  14
  15--*/
  16#include "odm_precomp.h"
  17
  18/*  Rate adaptive parameters */
  19
  20static u8 RETRY_PENALTY[PERENTRY][RETRYSIZE+1] = {
  21                {5, 4, 3, 2, 0, 3},      /* 92 , idx = 0 */
  22                {6, 5, 4, 3, 0, 4},      /* 86 , idx = 1 */
  23                {6, 5, 4, 2, 0, 4},      /* 81 , idx = 2 */
  24                {8, 7, 6, 4, 0, 6},      /* 75 , idx = 3 */
  25                {10, 9, 8, 6, 0, 8},     /* 71  , idx = 4 */
  26                {10, 9, 8, 4, 0, 8},     /* 66  , idx = 5 */
  27                {10, 9, 8, 2, 0, 8},     /* 62  , idx = 6 */
  28                {10, 9, 8, 0, 0, 8},     /* 59  , idx = 7 */
  29                {18, 17, 16, 8, 0, 16},  /* 53 , idx = 8 */
  30                {26, 25, 24, 16, 0, 24}, /* 50  , idx = 9 */
  31                {34, 33, 32, 24, 0, 32}, /* 47  , idx = 0x0a */
  32                {34, 31, 28, 20, 0, 32}, /* 43  , idx = 0x0b */
  33                {34, 31, 27, 18, 0, 32}, /* 40 , idx = 0x0c */
  34                {34, 31, 26, 16, 0, 32}, /* 37 , idx = 0x0d */
  35                {34, 30, 22, 16, 0, 32}, /* 32 , idx = 0x0e */
  36                {34, 30, 24, 16, 0, 32}, /* 26 , idx = 0x0f */
  37                {49, 46, 40, 16, 0, 48}, /* 20  , idx = 0x10 */
  38                {49, 45, 32, 0, 0, 48},  /* 17 , idx = 0x11 */
  39                {49, 45, 22, 18, 0, 48}, /* 15  , idx = 0x12 */
  40                {49, 40, 24, 16, 0, 48}, /* 12  , idx = 0x13 */
  41                {49, 32, 18, 12, 0, 48}, /* 9 , idx = 0x14 */
  42                {49, 22, 18, 14, 0, 48}, /* 6 , idx = 0x15 */
  43                {49, 16, 16, 0, 0, 48}
  44        }; /* 3, idx = 0x16 */
  45
  46static u8 PT_PENALTY[RETRYSIZE+1] = {34, 31, 30, 24, 0, 32};
  47
  48/*  wilson modify */
  49static u8 RETRY_PENALTY_IDX[2][RATESIZE] = {
  50                {4, 4, 4, 5, 4, 4, 5, 7, 7, 7, 8, 0x0a,        /*  SS>TH */
  51                4, 4, 4, 4, 6, 0x0a, 0x0b, 0x0d,
  52                5, 5, 7, 7, 8, 0x0b, 0x0d, 0x0f},                          /*  0329 R01 */
  53                {0x0a, 0x0a, 0x0b, 0x0c, 0x0a,
  54                0x0a, 0x0b, 0x0c, 0x0d, 0x10, 0x13, 0x14,          /*  SS<TH */
  55                0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x11, 0x13, 0x15,
  56                9, 9, 9, 9, 0x0c, 0x0e, 0x11, 0x13}
  57        };
  58
  59static u8 RETRY_PENALTY_UP_IDX[RATESIZE] = {
  60                0x0c, 0x0d, 0x0d, 0x0f, 0x0d, 0x0e,
  61                0x0f, 0x0f, 0x10, 0x12, 0x13, 0x14,            /*  SS>TH */
  62                0x0f, 0x10, 0x10, 0x12, 0x12, 0x13, 0x14, 0x15,
  63                0x11, 0x11, 0x12, 0x13, 0x13, 0x13, 0x14, 0x15};
  64
  65static u8 RSSI_THRESHOLD[RATESIZE] = {
  66                0, 0, 0, 0,
  67                0, 0, 0, 0, 0, 0x24, 0x26, 0x2a,
  68                0x18, 0x1a, 0x1d, 0x1f, 0x21, 0x27, 0x29, 0x2a,
  69                0, 0, 0, 0x1f, 0x23, 0x28, 0x2a, 0x2c};
  70
  71static u16 N_THRESHOLD_HIGH[RATESIZE] = {
  72                4, 4, 8, 16,
  73                24, 36, 48, 72, 96, 144, 192, 216,
  74                60, 80, 100, 160, 240, 400, 560, 640,
  75                300, 320, 480, 720, 1000, 1200, 1600, 2000};
  76static u16 N_THRESHOLD_LOW[RATESIZE] = {
  77                2, 2, 4, 8,
  78                12, 18, 24, 36, 48, 72, 96, 108,
  79                30, 40, 50, 80, 120, 200, 280, 320,
  80                150, 160, 240, 360, 500, 600, 800, 1000};
  81
  82static u8 DROPING_NECESSARY[RATESIZE] = {
  83                1, 1, 1, 1,
  84                1, 2, 3, 4, 5, 6, 7, 8,
  85                1, 2, 3, 4, 5, 6, 7, 8,
  86                5, 6, 7, 8, 9, 10, 11, 12};
  87
  88static u8 PendingForRateUpFail[5] = {2, 10, 24, 40, 60};
  89static u16 DynamicTxRPTTiming[6] = {
  90        0x186a, 0x30d4, 0x493e, 0x61a8, 0x7a12, 0x927c}; /*  200ms-1200ms */
  91
  92/*  End Rate adaptive parameters */
  93
  94static void odm_SetTxRPTTiming_8188E(
  95                struct odm_dm_struct *dm_odm,
  96                struct odm_ra_info *pRaInfo,
  97                u8 extend
  98        )
  99{
 100        u8 idx = 0;
 101
 102        for (idx = 0; idx < 5; idx++)
 103                if (DynamicTxRPTTiming[idx] == pRaInfo->RptTime)
 104                        break;
 105
 106        if (extend == 0) { /*  back to default timing */
 107                idx = 0;  /* 200ms */
 108        } else if (extend == 1) {/*  increase the timing */
 109                idx += 1;
 110                if (idx > 5)
 111                        idx = 5;
 112        } else if (extend == 2) {/*  decrease the timing */
 113                if (idx != 0)
 114                        idx -= 1;
 115        }
 116        pRaInfo->RptTime = DynamicTxRPTTiming[idx];
 117
 118        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
 119                        ("pRaInfo->RptTime = 0x%x\n", pRaInfo->RptTime));
 120}
 121
 122static int odm_RateDown_8188E(struct odm_dm_struct *dm_odm,
 123                                struct odm_ra_info *pRaInfo)
 124{
 125        u8 RateID, LowestRate, HighestRate;
 126        u8 i;
 127
 128        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE,
 129                        ODM_DBG_TRACE, ("=====>odm_RateDown_8188E()\n"));
 130        if (!pRaInfo) {
 131                ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
 132                                ("odm_RateDown_8188E(): pRaInfo is NULL\n"));
 133                return -1;
 134        }
 135        RateID = pRaInfo->PreRate;
 136        LowestRate = pRaInfo->LowestRate;
 137        HighestRate = pRaInfo->HighestRate;
 138
 139        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
 140                     (" RateID =%d LowestRate =%d HighestRate =%d RateSGI =%d\n",
 141                     RateID, LowestRate, HighestRate, pRaInfo->RateSGI));
 142        if (RateID > HighestRate) {
 143                RateID = HighestRate;
 144        } else if (pRaInfo->RateSGI) {
 145                pRaInfo->RateSGI = 0;
 146        } else if (RateID > LowestRate) {
 147                if (RateID > 0) {
 148                        for (i = RateID-1; i > LowestRate; i--) {
 149                                if (pRaInfo->RAUseRate & BIT(i)) {
 150                                        RateID = i;
 151                                        goto RateDownFinish;
 152                                }
 153                        }
 154                }
 155        } else if (RateID <= LowestRate) {
 156                RateID = LowestRate;
 157        }
 158RateDownFinish:
 159        if (pRaInfo->RAWaitingCounter == 1) {
 160                pRaInfo->RAWaitingCounter += 1;
 161                pRaInfo->RAPendingCounter += 1;
 162        } else if (pRaInfo->RAWaitingCounter == 0) {
 163                ;
 164        } else {
 165                pRaInfo->RAWaitingCounter = 0;
 166                pRaInfo->RAPendingCounter = 0;
 167        }
 168
 169        if (pRaInfo->RAPendingCounter >= 4)
 170                pRaInfo->RAPendingCounter = 4;
 171
 172        pRaInfo->DecisionRate = RateID;
 173        odm_SetTxRPTTiming_8188E(dm_odm, pRaInfo, 2);
 174        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE,
 175                        ODM_DBG_LOUD, ("Rate down, RPT Timing default\n"));
 176        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
 177                        ("RAWaitingCounter %d, RAPendingCounter %d",
 178                         pRaInfo->RAWaitingCounter, pRaInfo->RAPendingCounter));
 179        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
 180                        ("Rate down to RateID %d RateSGI %d\n", RateID, pRaInfo->RateSGI));
 181        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
 182                        ("<===== odm_RateDown_8188E()\n"));
 183        return 0;
 184}
 185
 186static int odm_RateUp_8188E(
 187                struct odm_dm_struct *dm_odm,
 188                struct odm_ra_info *pRaInfo
 189        )
 190{
 191        u8 RateID, HighestRate;
 192        u8 i;
 193
 194        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE,
 195                        ODM_DBG_TRACE, ("=====>odm_RateUp_8188E()\n"));
 196        if (!pRaInfo) {
 197                ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
 198                                ("odm_RateUp_8188E(): pRaInfo is NULL\n"));
 199                return -1;
 200        }
 201        RateID = pRaInfo->PreRate;
 202        HighestRate = pRaInfo->HighestRate;
 203        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
 204                     (" RateID =%d HighestRate =%d\n",
 205                     RateID, HighestRate));
 206        if (pRaInfo->RAWaitingCounter == 1) {
 207                pRaInfo->RAWaitingCounter = 0;
 208                pRaInfo->RAPendingCounter = 0;
 209        } else if (pRaInfo->RAWaitingCounter > 1) {
 210                pRaInfo->PreRssiStaRA = pRaInfo->RssiStaRA;
 211                goto RateUpfinish;
 212        }
 213        odm_SetTxRPTTiming_8188E(dm_odm, pRaInfo, 0);
 214        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
 215                        ("odm_RateUp_8188E():Decrease RPT Timing\n"));
 216
 217        if (RateID < HighestRate) {
 218                for (i = RateID+1; i <= HighestRate; i++) {
 219                        if (pRaInfo->RAUseRate & BIT(i)) {
 220                                RateID = i;
 221                                goto RateUpfinish;
 222                        }
 223                }
 224        } else if (RateID == HighestRate) {
 225                if (pRaInfo->SGIEnable && (pRaInfo->RateSGI != 1))
 226                        pRaInfo->RateSGI = 1;
 227                else if ((pRaInfo->SGIEnable) != 1)
 228                        pRaInfo->RateSGI = 0;
 229        } else {
 230                RateID = HighestRate;
 231        }
 232RateUpfinish:
 233        if (pRaInfo->RAWaitingCounter ==
 234                (4+PendingForRateUpFail[pRaInfo->RAPendingCounter]))
 235                pRaInfo->RAWaitingCounter = 0;
 236        else
 237                pRaInfo->RAWaitingCounter++;
 238
 239        pRaInfo->DecisionRate = RateID;
 240        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
 241                        ("Rate up to RateID %d\n", RateID));
 242        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
 243                        ("RAWaitingCounter %d, RAPendingCounter %d",
 244                         pRaInfo->RAWaitingCounter, pRaInfo->RAPendingCounter));
 245        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE,
 246                        ODM_DBG_TRACE, ("<===== odm_RateUp_8188E()\n"));
 247        return 0;
 248}
 249
 250static void odm_ResetRaCounter_8188E(struct odm_ra_info *pRaInfo)
 251{
 252        u8 RateID;
 253
 254        RateID = pRaInfo->DecisionRate;
 255        pRaInfo->NscUp = (N_THRESHOLD_HIGH[RateID]+N_THRESHOLD_LOW[RateID])>>1;
 256        pRaInfo->NscDown = (N_THRESHOLD_HIGH[RateID]+N_THRESHOLD_LOW[RateID])>>1;
 257}
 258
 259static void odm_RateDecision_8188E(struct odm_dm_struct *dm_odm,
 260                struct odm_ra_info *pRaInfo
 261        )
 262{
 263        u8 RateID = 0, RtyPtID = 0, PenaltyID1 = 0, PenaltyID2 = 0, i = 0;
 264        /* u32 pool_retry; */
 265        static u8 DynamicTxRPTTimingCounter;
 266
 267        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
 268                        ("=====>odm_RateDecision_8188E()\n"));
 269
 270        if (pRaInfo->Active && (pRaInfo->TOTAL > 0)) { /*  STA used and data packet exits */
 271                if ((pRaInfo->RssiStaRA < (pRaInfo->PreRssiStaRA - 3)) ||
 272                    (pRaInfo->RssiStaRA > (pRaInfo->PreRssiStaRA + 3))) {
 273                        pRaInfo->RAWaitingCounter = 0;
 274                        pRaInfo->RAPendingCounter = 0;
 275                }
 276                /*  Start RA decision */
 277                if (pRaInfo->PreRate > pRaInfo->HighestRate)
 278                        RateID = pRaInfo->HighestRate;
 279                else
 280                        RateID = pRaInfo->PreRate;
 281                if (pRaInfo->RssiStaRA > RSSI_THRESHOLD[RateID])
 282                        RtyPtID = 0;
 283                else
 284                        RtyPtID = 1;
 285                PenaltyID1 = RETRY_PENALTY_IDX[RtyPtID][RateID]; /* TODO by page */
 286
 287                ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
 288                             (" NscDown init is %d\n", pRaInfo->NscDown));
 289
 290                for (i = 0 ; i <= 4 ; i++)
 291                        pRaInfo->NscDown += pRaInfo->RTY[i] * RETRY_PENALTY[PenaltyID1][i];
 292
 293                ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
 294                             (" NscDown is %d, total*penalty[5] is %d\n", pRaInfo->NscDown,
 295                              (pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID1][5])));
 296
 297                if (pRaInfo->NscDown > (pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID1][5]))
 298                        pRaInfo->NscDown -= pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID1][5];
 299                else
 300                        pRaInfo->NscDown = 0;
 301
 302                /*  rate up */
 303                PenaltyID2 = RETRY_PENALTY_UP_IDX[RateID];
 304                ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
 305                             (" NscUp init is %d\n", pRaInfo->NscUp));
 306
 307                for (i = 0 ; i <= 4 ; i++)
 308                        pRaInfo->NscUp += pRaInfo->RTY[i] * RETRY_PENALTY[PenaltyID2][i];
 309
 310                ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
 311                             ("NscUp is %d, total*up[5] is %d\n",
 312                             pRaInfo->NscUp, (pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID2][5])));
 313
 314                if (pRaInfo->NscUp > (pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID2][5]))
 315                        pRaInfo->NscUp -= pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID2][5];
 316                else
 317                        pRaInfo->NscUp = 0;
 318
 319                ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE|ODM_COMP_INIT, ODM_DBG_LOUD,
 320                             (" RssiStaRa = %d RtyPtID =%d PenaltyID1 = 0x%x  PenaltyID2 = 0x%x RateID =%d NscDown =%d NscUp =%d SGI =%d\n",
 321                             pRaInfo->RssiStaRA, RtyPtID, PenaltyID1, PenaltyID2, RateID, pRaInfo->NscDown, pRaInfo->NscUp, pRaInfo->RateSGI));
 322                if ((pRaInfo->NscDown < N_THRESHOLD_LOW[RateID]) ||
 323                    (pRaInfo->DROP > DROPING_NECESSARY[RateID]))
 324                        odm_RateDown_8188E(dm_odm, pRaInfo);
 325                else if (pRaInfo->NscUp > N_THRESHOLD_HIGH[RateID])
 326                        odm_RateUp_8188E(dm_odm, pRaInfo);
 327
 328                if (pRaInfo->DecisionRate > pRaInfo->HighestRate)
 329                        pRaInfo->DecisionRate = pRaInfo->HighestRate;
 330
 331                if ((pRaInfo->DecisionRate) == (pRaInfo->PreRate))
 332                        DynamicTxRPTTimingCounter += 1;
 333                else
 334                        DynamicTxRPTTimingCounter = 0;
 335
 336                if (DynamicTxRPTTimingCounter >= 4) {
 337                        odm_SetTxRPTTiming_8188E(dm_odm, pRaInfo, 1);
 338                        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE,
 339                                     ODM_DBG_LOUD, ("<===== Rate don't change 4 times, Extend RPT Timing\n"));
 340                        DynamicTxRPTTimingCounter = 0;
 341                }
 342
 343                pRaInfo->PreRate = pRaInfo->DecisionRate;  /* YJ, add, 120120 */
 344
 345                odm_ResetRaCounter_8188E(pRaInfo);
 346        }
 347        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, ("<===== odm_RateDecision_8188E()\n"));
 348}
 349
 350static int odm_ARFBRefresh_8188E(struct odm_dm_struct *dm_odm, struct odm_ra_info *pRaInfo)
 351{  /*  Wilson 2011/10/26 */
 352        struct adapter *adapt = dm_odm->Adapter;
 353        u32 MaskFromReg;
 354        s8 i;
 355
 356        switch (pRaInfo->RateID) {
 357        case RATR_INX_WIRELESS_NGB:
 358                pRaInfo->RAUseRate = (pRaInfo->RateMask)&0x0f8ff015;
 359                break;
 360        case RATR_INX_WIRELESS_NG:
 361                pRaInfo->RAUseRate = (pRaInfo->RateMask)&0x0f8ff010;
 362                break;
 363        case RATR_INX_WIRELESS_NB:
 364                pRaInfo->RAUseRate = (pRaInfo->RateMask)&0x0f8ff005;
 365                break;
 366        case RATR_INX_WIRELESS_N:
 367                pRaInfo->RAUseRate = (pRaInfo->RateMask)&0x0f8ff000;
 368                break;
 369        case RATR_INX_WIRELESS_GB:
 370                pRaInfo->RAUseRate = (pRaInfo->RateMask)&0x00000ff5;
 371                break;
 372        case RATR_INX_WIRELESS_G:
 373                pRaInfo->RAUseRate = (pRaInfo->RateMask)&0x00000ff0;
 374                break;
 375        case RATR_INX_WIRELESS_B:
 376                pRaInfo->RAUseRate = (pRaInfo->RateMask)&0x0000000d;
 377                break;
 378        case 12:
 379                MaskFromReg = usb_read32(adapt, REG_ARFR0);
 380                pRaInfo->RAUseRate = (pRaInfo->RateMask)&MaskFromReg;
 381                break;
 382        case 13:
 383                MaskFromReg = usb_read32(adapt, REG_ARFR1);
 384                pRaInfo->RAUseRate = (pRaInfo->RateMask)&MaskFromReg;
 385                break;
 386        case 14:
 387                MaskFromReg = usb_read32(adapt, REG_ARFR2);
 388                pRaInfo->RAUseRate = (pRaInfo->RateMask)&MaskFromReg;
 389                break;
 390        case 15:
 391                MaskFromReg = usb_read32(adapt, REG_ARFR3);
 392                pRaInfo->RAUseRate = (pRaInfo->RateMask)&MaskFromReg;
 393                break;
 394        default:
 395                pRaInfo->RAUseRate = (pRaInfo->RateMask);
 396                break;
 397        }
 398        /*  Highest rate */
 399        if (pRaInfo->RAUseRate) {
 400                for (i = RATESIZE; i >= 0; i--) {
 401                        if ((pRaInfo->RAUseRate)&BIT(i)) {
 402                                pRaInfo->HighestRate = i;
 403                                break;
 404                        }
 405                }
 406        } else {
 407                pRaInfo->HighestRate = 0;
 408        }
 409        /*  Lowest rate */
 410        if (pRaInfo->RAUseRate) {
 411                for (i = 0; i < RATESIZE; i++) {
 412                        if ((pRaInfo->RAUseRate) & BIT(i)) {
 413                                pRaInfo->LowestRate = i;
 414                                break;
 415                        }
 416                }
 417        } else {
 418                pRaInfo->LowestRate = 0;
 419        }
 420                if (pRaInfo->HighestRate > 0x13)
 421                        pRaInfo->PTModeSS = 3;
 422                else if (pRaInfo->HighestRate > 0x0b)
 423                        pRaInfo->PTModeSS = 2;
 424                else if (pRaInfo->HighestRate > 0x0b)
 425                        pRaInfo->PTModeSS = 1;
 426                else
 427                        pRaInfo->PTModeSS = 0;
 428        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
 429                     ("ODM_ARFBRefresh_8188E(): PTModeSS =%d\n", pRaInfo->PTModeSS));
 430
 431        if (pRaInfo->DecisionRate > pRaInfo->HighestRate)
 432                pRaInfo->DecisionRate = pRaInfo->HighestRate;
 433
 434        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
 435                     ("ODM_ARFBRefresh_8188E(): RateID =%d RateMask =%8.8x RAUseRate =%8.8x HighestRate =%d, DecisionRate =%d\n",
 436                     pRaInfo->RateID, pRaInfo->RateMask, pRaInfo->RAUseRate, pRaInfo->HighestRate, pRaInfo->DecisionRate));
 437        return 0;
 438}
 439
 440static void odm_PTTryState_8188E(struct odm_ra_info *pRaInfo)
 441{
 442        pRaInfo->PTTryState = 0;
 443        switch (pRaInfo->PTModeSS) {
 444        case 3:
 445                if (pRaInfo->DecisionRate >= 0x19)
 446                        pRaInfo->PTTryState = 1;
 447                break;
 448        case 2:
 449                if (pRaInfo->DecisionRate >= 0x11)
 450                        pRaInfo->PTTryState = 1;
 451                break;
 452        case 1:
 453                if (pRaInfo->DecisionRate >= 0x0a)
 454                        pRaInfo->PTTryState = 1;
 455                break;
 456        case 0:
 457                if (pRaInfo->DecisionRate >= 0x03)
 458                        pRaInfo->PTTryState = 1;
 459                break;
 460        default:
 461                pRaInfo->PTTryState = 0;
 462                break;
 463        }
 464
 465        if (pRaInfo->RssiStaRA < 48) {
 466                pRaInfo->PTStage = 0;
 467        } else if (pRaInfo->PTTryState == 1) {
 468                if ((pRaInfo->PTStopCount >= 10) ||
 469                    (pRaInfo->PTPreRssi > pRaInfo->RssiStaRA + 5) ||
 470                    (pRaInfo->PTPreRssi < pRaInfo->RssiStaRA - 5) ||
 471                    (pRaInfo->DecisionRate != pRaInfo->PTPreRate)) {
 472                        if (pRaInfo->PTStage == 0)
 473                                pRaInfo->PTStage = 1;
 474                        else if (pRaInfo->PTStage == 1)
 475                                pRaInfo->PTStage = 3;
 476                        else
 477                                pRaInfo->PTStage = 5;
 478
 479                        pRaInfo->PTPreRssi = pRaInfo->RssiStaRA;
 480                        pRaInfo->PTStopCount = 0;
 481                } else {
 482                        pRaInfo->RAstage = 0;
 483                        pRaInfo->PTStopCount++;
 484                }
 485        } else {
 486                pRaInfo->PTStage = 0;
 487                pRaInfo->RAstage = 0;
 488        }
 489        pRaInfo->PTPreRate = pRaInfo->DecisionRate;
 490}
 491
 492static void odm_PTDecision_8188E(struct odm_ra_info *pRaInfo)
 493{
 494        u8 j;
 495        u8 temp_stage;
 496        u32 numsc;
 497        u32 num_total;
 498        u8 stage_id;
 499
 500        numsc  = 0;
 501        num_total = pRaInfo->TOTAL * PT_PENALTY[5];
 502        for (j = 0; j <= 4; j++) {
 503                numsc += pRaInfo->RTY[j] * PT_PENALTY[j];
 504                if (numsc > num_total)
 505                        break;
 506        }
 507
 508        j >>= 1;
 509        temp_stage = (pRaInfo->PTStage + 1) >> 1;
 510        if (temp_stage > j)
 511                stage_id = temp_stage-j;
 512        else
 513                stage_id = 0;
 514
 515        pRaInfo->PTSmoothFactor = (pRaInfo->PTSmoothFactor>>1) + (pRaInfo->PTSmoothFactor>>2) + stage_id*16+2;
 516        if (pRaInfo->PTSmoothFactor > 192)
 517                pRaInfo->PTSmoothFactor = 192;
 518        stage_id = pRaInfo->PTSmoothFactor >> 6;
 519        temp_stage = stage_id*2;
 520        if (temp_stage != 0)
 521                temp_stage -= 1;
 522        if (pRaInfo->DROP > 3)
 523                temp_stage = 0;
 524        pRaInfo->PTStage = temp_stage;
 525}
 526
 527static void
 528odm_RATxRPTTimerSetting(
 529                struct odm_dm_struct *dm_odm,
 530                u16 minRptTime
 531)
 532{
 533        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, (" =====>odm_RATxRPTTimerSetting()\n"));
 534
 535        if (dm_odm->CurrminRptTime != minRptTime) {
 536                ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
 537                             (" CurrminRptTime = 0x%04x minRptTime = 0x%04x\n", dm_odm->CurrminRptTime, minRptTime));
 538                rtw_rpt_timer_cfg_cmd(dm_odm->Adapter, minRptTime);
 539                dm_odm->CurrminRptTime = minRptTime;
 540        }
 541        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, (" <===== odm_RATxRPTTimerSetting()\n"));
 542}
 543
 544void
 545ODM_RASupport_Init(
 546                struct odm_dm_struct *dm_odm
 547        )
 548{
 549        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("=====>ODM_RASupport_Init()\n"));
 550
 551        dm_odm->RaSupport88E = true;
 552}
 553
 554int ODM_RAInfo_Init(struct odm_dm_struct *dm_odm, u8 macid)
 555{
 556        struct odm_ra_info *pRaInfo = &dm_odm->RAInfo[macid];
 557        u8 WirelessMode = 0xFF; /* invalid value */
 558        u8 max_rate_idx = 0x13; /* MCS7 */
 559
 560        if (dm_odm->pWirelessMode)
 561                WirelessMode = *(dm_odm->pWirelessMode);
 562
 563        if (WirelessMode != 0xFF) {
 564                if (WirelessMode & ODM_WM_N24G)
 565                        max_rate_idx = 0x13;
 566                else if (WirelessMode & ODM_WM_G)
 567                        max_rate_idx = 0x0b;
 568                else if (WirelessMode & ODM_WM_B)
 569                        max_rate_idx = 0x03;
 570        }
 571
 572        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
 573                     ("ODM_RAInfo_Init(): WirelessMode:0x%08x , max_raid_idx:0x%02x\n",
 574                     WirelessMode, max_rate_idx));
 575
 576        pRaInfo->DecisionRate = max_rate_idx;
 577        pRaInfo->PreRate = max_rate_idx;
 578        pRaInfo->HighestRate = max_rate_idx;
 579        pRaInfo->LowestRate = 0;
 580        pRaInfo->RateID = 0;
 581        pRaInfo->RateMask = 0xffffffff;
 582        pRaInfo->RssiStaRA = 0;
 583        pRaInfo->PreRssiStaRA = 0;
 584        pRaInfo->SGIEnable = 0;
 585        pRaInfo->RAUseRate = 0xffffffff;
 586        pRaInfo->NscDown = (N_THRESHOLD_HIGH[0x13]+N_THRESHOLD_LOW[0x13])/2;
 587        pRaInfo->NscUp = (N_THRESHOLD_HIGH[0x13]+N_THRESHOLD_LOW[0x13])/2;
 588        pRaInfo->RateSGI = 0;
 589        pRaInfo->Active = 1;    /* Active is not used at present. by page, 110819 */
 590        pRaInfo->RptTime = 0x927c;
 591        pRaInfo->DROP = 0;
 592        pRaInfo->RTY[0] = 0;
 593        pRaInfo->RTY[1] = 0;
 594        pRaInfo->RTY[2] = 0;
 595        pRaInfo->RTY[3] = 0;
 596        pRaInfo->RTY[4] = 0;
 597        pRaInfo->TOTAL = 0;
 598        pRaInfo->RAWaitingCounter = 0;
 599        pRaInfo->RAPendingCounter = 0;
 600        pRaInfo->PTActive = 1;   /*  Active when this STA is use */
 601        pRaInfo->PTTryState = 0;
 602        pRaInfo->PTStage = 5; /*  Need to fill into HW_PWR_STATUS */
 603        pRaInfo->PTSmoothFactor = 192;
 604        pRaInfo->PTStopCount = 0;
 605        pRaInfo->PTPreRate = 0;
 606        pRaInfo->PTPreRssi = 0;
 607        pRaInfo->PTModeSS = 0;
 608        pRaInfo->RAstage = 0;
 609        return 0;
 610}
 611
 612int ODM_RAInfo_Init_all(struct odm_dm_struct *dm_odm)
 613{
 614        u8 macid = 0;
 615
 616        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("=====>\n"));
 617        dm_odm->CurrminRptTime = 0;
 618
 619        for (macid = 0; macid < ODM_ASSOCIATE_ENTRY_NUM; macid++)
 620                ODM_RAInfo_Init(dm_odm, macid);
 621
 622        return 0;
 623}
 624
 625u8 ODM_RA_GetShortGI_8188E(struct odm_dm_struct *dm_odm, u8 macid)
 626{
 627        if ((!dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM))
 628                return 0;
 629        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
 630                     ("macid =%d SGI =%d\n", macid, dm_odm->RAInfo[macid].RateSGI));
 631        return dm_odm->RAInfo[macid].RateSGI;
 632}
 633
 634u8 ODM_RA_GetDecisionRate_8188E(struct odm_dm_struct *dm_odm, u8 macid)
 635{
 636        u8 DecisionRate = 0;
 637
 638        if ((!dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM))
 639                return 0;
 640        DecisionRate = dm_odm->RAInfo[macid].DecisionRate;
 641        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
 642                (" macid =%d DecisionRate = 0x%x\n", macid, DecisionRate));
 643        return DecisionRate;
 644}
 645
 646u8 ODM_RA_GetHwPwrStatus_8188E(struct odm_dm_struct *dm_odm, u8 macid)
 647{
 648        u8 PTStage = 5;
 649
 650        if ((!dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM))
 651                return 0;
 652        PTStage = dm_odm->RAInfo[macid].PTStage;
 653        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
 654                     ("macid =%d PTStage = 0x%x\n", macid, PTStage));
 655        return PTStage;
 656}
 657
 658void ODM_RA_UpdateRateInfo_8188E(struct odm_dm_struct *dm_odm, u8 macid, u8 RateID, u32 RateMask, u8 SGIEnable)
 659{
 660        struct odm_ra_info *pRaInfo = NULL;
 661
 662        if ((!dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM))
 663                return;
 664        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
 665                     ("macid =%d RateID = 0x%x RateMask = 0x%x SGIEnable =%d\n",
 666                     macid, RateID, RateMask, SGIEnable));
 667
 668        pRaInfo = &(dm_odm->RAInfo[macid]);
 669        pRaInfo->RateID = RateID;
 670        pRaInfo->RateMask = RateMask;
 671        pRaInfo->SGIEnable = SGIEnable;
 672        odm_ARFBRefresh_8188E(dm_odm, pRaInfo);
 673}
 674
 675void ODM_RA_SetRSSI_8188E(struct odm_dm_struct *dm_odm, u8 macid, u8 Rssi)
 676{
 677        struct odm_ra_info *pRaInfo = NULL;
 678
 679        if ((!dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM))
 680                return;
 681        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
 682                     (" macid =%d Rssi =%d\n", macid, Rssi));
 683
 684        pRaInfo = &(dm_odm->RAInfo[macid]);
 685        pRaInfo->RssiStaRA = Rssi;
 686}
 687
 688void ODM_RA_Set_TxRPT_Time(struct odm_dm_struct *dm_odm, u16 minRptTime)
 689{
 690        struct adapter *adapt = dm_odm->Adapter;
 691
 692        usb_write16(adapt, REG_TX_RPT_TIME, minRptTime);
 693}
 694
 695void ODM_RA_TxRPT2Handle_8188E(struct odm_dm_struct *dm_odm, u8 *TxRPT_Buf, u16 TxRPT_Len, u32 macid_entry0, u32 macid_entry1)
 696{
 697        struct odm_ra_info *pRAInfo = NULL;
 698        u8 MacId = 0;
 699        u8 *pBuffer = NULL;
 700        u32 valid = 0, ItemNum = 0;
 701        u16 minRptTime = 0x927c;
 702
 703        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
 704                     ("=====>ODM_RA_TxRPT2Handle_8188E(): valid0 =%d valid1 =%d BufferLength =%d\n",
 705                     macid_entry0, macid_entry1, TxRPT_Len));
 706
 707        ItemNum = TxRPT_Len >> 3;
 708        pBuffer = TxRPT_Buf;
 709
 710        do {
 711                if (MacId >= ASSOCIATE_ENTRY_NUM)
 712                        valid = 0;
 713                else if (MacId >= 32)
 714                        valid = (1 << (MacId - 32)) & macid_entry1;
 715                else
 716                        valid = (1 << MacId) & macid_entry0;
 717
 718                pRAInfo = &(dm_odm->RAInfo[MacId]);
 719                if (valid) {
 720                        pRAInfo->RTY[0] = (u16)GET_TX_REPORT_TYPE1_RERTY_0(pBuffer);
 721                        pRAInfo->RTY[1] = (u16)GET_TX_REPORT_TYPE1_RERTY_1(pBuffer);
 722                        pRAInfo->RTY[2] = (u16)GET_TX_REPORT_TYPE1_RERTY_2(pBuffer);
 723                        pRAInfo->RTY[3] = (u16)GET_TX_REPORT_TYPE1_RERTY_3(pBuffer);
 724                        pRAInfo->RTY[4] = (u16)GET_TX_REPORT_TYPE1_RERTY_4(pBuffer);
 725                        pRAInfo->DROP =   (u16)GET_TX_REPORT_TYPE1_DROP_0(pBuffer);
 726                        pRAInfo->TOTAL = pRAInfo->RTY[0] + pRAInfo->RTY[1] +
 727                                         pRAInfo->RTY[2] + pRAInfo->RTY[3] +
 728                                         pRAInfo->RTY[4] + pRAInfo->DROP;
 729                        if (pRAInfo->TOTAL != 0) {
 730                                ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
 731                                             ("macid =%d Total =%d R0 =%d R1 =%d R2 =%d R3 =%d R4 =%d D0 =%d valid0 =%x valid1 =%x\n",
 732                                             MacId, pRAInfo->TOTAL,
 733                                             pRAInfo->RTY[0], pRAInfo->RTY[1],
 734                                             pRAInfo->RTY[2], pRAInfo->RTY[3],
 735                                             pRAInfo->RTY[4], pRAInfo->DROP,
 736                                             macid_entry0 , macid_entry1));
 737                                if (pRAInfo->PTActive) {
 738                                        if (pRAInfo->RAstage < 5)
 739                                                odm_RateDecision_8188E(dm_odm, pRAInfo);
 740                                        else if (pRAInfo->RAstage == 5) /*  Power training try state */
 741                                                odm_PTTryState_8188E(pRAInfo);
 742                                        else /*  RAstage == 6 */
 743                                                odm_PTDecision_8188E(pRAInfo);
 744
 745                                        /*  Stage_RA counter */
 746                                        if (pRAInfo->RAstage <= 5)
 747                                                pRAInfo->RAstage++;
 748                                        else
 749                                                pRAInfo->RAstage = 0;
 750                                } else {
 751                                        odm_RateDecision_8188E(dm_odm, pRAInfo);
 752                                }
 753                                ODM_RT_TRACE(dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD,
 754                                             ("macid =%d R0 =%d R1 =%d R2 =%d R3 =%d R4 =%d drop =%d valid0 =%x RateID =%d SGI =%d\n",
 755                                             MacId,
 756                                             pRAInfo->RTY[0],
 757                                             pRAInfo->RTY[1],
 758                                             pRAInfo->RTY[2],
 759                                             pRAInfo->RTY[3],
 760                                             pRAInfo->RTY[4],
 761                                             pRAInfo->DROP,
 762                                             macid_entry0,
 763                                             pRAInfo->DecisionRate,
 764                                             pRAInfo->RateSGI));
 765                        } else {
 766                                ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, (" TOTAL = 0!!!!\n"));
 767                        }
 768                }
 769
 770                if (minRptTime > pRAInfo->RptTime)
 771                        minRptTime = pRAInfo->RptTime;
 772
 773                pBuffer += TX_RPT2_ITEM_SIZE;
 774                MacId++;
 775        } while (MacId < ItemNum);
 776
 777        odm_RATxRPTTimerSetting(dm_odm, minRptTime);
 778
 779        ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("<===== ODM_RA_TxRPT2Handle_8188E()\n"));
 780}
 781