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 != NULL) 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