1//#include "r8180.h" 2#include "r8180_dm.h" 3#include "r8180_hw.h" 4#include "r8180_93cx6.h" 5//{by amy 080312 6 7// 8// Description: 9// Return TRUE if we shall perform High Power Mecahnism, FALSE otherwise. 10// 11//+by amy 080312 12#define RATE_ADAPTIVE_TIMER_PERIOD 300 13 14bool CheckHighPower(struct net_device *dev) 15{ 16 struct r8180_priv *priv = ieee80211_priv(dev); 17 struct ieee80211_device *ieee = priv->ieee80211; 18 19 if(!priv->bRegHighPowerMechanism) 20 { 21 return false; 22 } 23 24 if(ieee->state == IEEE80211_LINKED_SCANNING) 25 { 26 return false; 27 } 28 29 return true; 30} 31 32// 33// Description: 34// Update Tx power level if necessary. 35// See also DoRxHighPower() and SetTxPowerLevel8185() for reference. 36// 37// Note: 38// The reason why we udpate Tx power level here instead of DoRxHighPower() 39// is the number of IO to change Tx power is much more than channel TR switch 40// and they are related to OFDM and MAC registers. 41// So, we don't want to update it so frequently in per-Rx packet base. 42// 43void 44DoTxHighPower( 45 struct net_device *dev 46 ) 47{ 48 struct r8180_priv *priv = ieee80211_priv(dev); 49 u16 HiPwrUpperTh = 0; 50 u16 HiPwrLowerTh = 0; 51 u8 RSSIHiPwrUpperTh; 52 u8 RSSIHiPwrLowerTh; 53 u8 u1bTmp; 54 char OfdmTxPwrIdx, CckTxPwrIdx; 55 56 //printk("----> DoTxHighPower()\n"); 57 58 HiPwrUpperTh = priv->RegHiPwrUpperTh; 59 HiPwrLowerTh = priv->RegHiPwrLowerTh; 60 61 HiPwrUpperTh = HiPwrUpperTh * 10; 62 HiPwrLowerTh = HiPwrLowerTh * 10; 63 RSSIHiPwrUpperTh = priv->RegRSSIHiPwrUpperTh; 64 RSSIHiPwrLowerTh = priv->RegRSSIHiPwrLowerTh; 65 66 //lzm add 080826 67 OfdmTxPwrIdx = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel]; 68 CckTxPwrIdx = priv->chtxpwr[priv->ieee80211->current_network.channel]; 69 70 // printk("DoTxHighPower() - UndecoratedSmoothedSS:%d, CurCCKRSSI = %d , bCurCCKPkt= %d \n", priv->UndecoratedSmoothedSS, priv->CurCCKRSSI, priv->bCurCCKPkt ); 71 72 if((priv->UndecoratedSmoothedSS > HiPwrUpperTh) || 73 (priv->bCurCCKPkt && (priv->CurCCKRSSI > RSSIHiPwrUpperTh))) 74 { 75 // Stevenl suggested that degrade 8dbm in high power sate. 2007-12-04 Isaiah 76 77 // printk("=====>DoTxHighPower() - High Power - UndecoratedSmoothedSS:%d, HiPwrUpperTh = %d \n", priv->UndecoratedSmoothedSS, HiPwrUpperTh ); 78 priv->bToUpdateTxPwr = true; 79 u1bTmp= read_nic_byte(dev, CCK_TXAGC); 80 81 // If it never enter High Power. 82 if( CckTxPwrIdx == u1bTmp) 83 { 84 u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0; // 8dbm 85 write_nic_byte(dev, CCK_TXAGC, u1bTmp); 86 87 u1bTmp= read_nic_byte(dev, OFDM_TXAGC); 88 u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0; // 8dbm 89 write_nic_byte(dev, OFDM_TXAGC, u1bTmp); 90 } 91 92 } 93 else if((priv->UndecoratedSmoothedSS < HiPwrLowerTh) && 94 (!priv->bCurCCKPkt || priv->CurCCKRSSI < RSSIHiPwrLowerTh)) 95 { 96 // printk("DoTxHighPower() - lower Power - UndecoratedSmoothedSS:%d, HiPwrUpperTh = %d \n", priv->UndecoratedSmoothedSS, HiPwrLowerTh ); 97 if(priv->bToUpdateTxPwr) 98 { 99 priv->bToUpdateTxPwr = false; 100 //SD3 required. 101 u1bTmp= read_nic_byte(dev, CCK_TXAGC); 102 if(u1bTmp < CckTxPwrIdx) 103 { 104 //u1bTmp = ((u1bTmp+16) > 35) ? 35: (u1bTmp+16); // 8dbm 105 //write_nic_byte(dev, CCK_TXAGC, u1bTmp); 106 write_nic_byte(dev, CCK_TXAGC, CckTxPwrIdx); 107 } 108 109 u1bTmp= read_nic_byte(dev, OFDM_TXAGC); 110 if(u1bTmp < OfdmTxPwrIdx) 111 { 112 //u1bTmp = ((u1bTmp+16) > 35) ? 35: (u1bTmp+16); // 8dbm 113 //write_nic_byte(dev, OFDM_TXAGC, u1bTmp); 114 write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx); 115 } 116 } 117 } 118 119 //printk("<---- DoTxHighPower()\n"); 120} 121 122 123// 124// Description: 125// Callback function of UpdateTxPowerWorkItem. 126// Because of some event happend, e.g. CCX TPC, High Power Mechanism, 127// We update Tx power of current channel again. 128// 129void rtl8180_tx_pw_wq (struct work_struct *work) 130{ 131// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq); 132// struct ieee80211_device * ieee = (struct ieee80211_device*) 133// container_of(work, struct ieee80211_device, watch_dog_wq); 134 struct delayed_work *dwork = to_delayed_work(work); 135 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,tx_pw_wq); 136 struct net_device *dev = ieee->dev; 137 138// printk("----> UpdateTxPowerWorkItemCallback()\n"); 139 140 DoTxHighPower(dev); 141 142// printk("<---- UpdateTxPowerWorkItemCallback()\n"); 143} 144 145 146// 147// Description: 148// Return TRUE if we shall perform DIG Mecahnism, FALSE otherwise. 149// 150bool 151CheckDig( 152 struct net_device *dev 153 ) 154{ 155 struct r8180_priv *priv = ieee80211_priv(dev); 156 struct ieee80211_device *ieee = priv->ieee80211; 157 158 if(!priv->bDigMechanism) 159 return false; 160 161 if(ieee->state != IEEE80211_LINKED) 162 return false; 163 164 //if(priv->CurrentOperaRate < 36) // Schedule Dig under all OFDM rates. By Bruce, 2007-06-01. 165 if((priv->ieee80211->rate/5) < 36) // Schedule Dig under all OFDM rates. By Bruce, 2007-06-01. 166 return false; 167 return true; 168} 169// 170// Description: 171// Implementation of DIG for Zebra and Zebra2. 172// 173void 174DIG_Zebra( 175 struct net_device *dev 176 ) 177{ 178 struct r8180_priv *priv = ieee80211_priv(dev); 179 u16 CCKFalseAlarm, OFDMFalseAlarm; 180 u16 OfdmFA1, OfdmFA2; 181 int InitialGainStep = 7; // The number of initial gain stages. 182 int LowestGainStage = 4; // The capable lowest stage of performing dig workitem. 183 u32 AwakePeriodIn2Sec=0; 184 185 //printk("---------> DIG_Zebra()\n"); 186 187 CCKFalseAlarm = (u16)(priv->FalseAlarmRegValue & 0x0000ffff); 188 OFDMFalseAlarm = (u16)((priv->FalseAlarmRegValue >> 16) & 0x0000ffff); 189 OfdmFA1 = 0x15; 190 OfdmFA2 = ((u16)(priv->RegDigOfdmFaUpTh)) << 8; 191 192// printk("DIG**********CCK False Alarm: %#X \n",CCKFalseAlarm); 193// printk("DIG**********OFDM False Alarm: %#X \n",OFDMFalseAlarm); 194 195 // The number of initial gain steps is different, by Bruce, 2007-04-13. 196 if (priv->InitialGain == 0 ) //autoDIG 197 { // Advised from SD3 DZ 198 priv->InitialGain = 4; // In 87B, m74dBm means State 4 (m82dBm) 199 } 200 { // Advised from SD3 DZ 201 OfdmFA1 = 0x20; 202 } 203 204 AwakePeriodIn2Sec = (2000-priv ->DozePeriodInPast2Sec); 205 //printk("&&& DozePeriod=%d AwakePeriod=%d\n", priv->DozePeriodInPast2Sec, AwakePeriodIn2Sec); 206 priv ->DozePeriodInPast2Sec=0; 207 208 if(AwakePeriodIn2Sec) 209 { 210 //RT_TRACE(COMP_DIG, DBG_TRACE, ("DIG: AwakePeriodIn2Sec(%d) - FATh(0x%X , 0x%X) ->",AwakePeriodIn2Sec, OfdmFA1, OfdmFA2)); 211 // adjuest DIG threshold. 212 OfdmFA1 = (u16)((OfdmFA1*AwakePeriodIn2Sec) / 2000) ; 213 OfdmFA2 = (u16)((OfdmFA2*AwakePeriodIn2Sec) / 2000) ; 214 //RT_TRACE(COMP_DIG, DBG_TRACE, ("( 0x%X , 0x%X)\n", OfdmFA1, OfdmFA2)); 215 } 216 else 217 { 218 ;//RT_TRACE(COMP_DIG, DBG_WARNING, ("ERROR!! AwakePeriodIn2Sec should not be ZERO!!\n")); 219 } 220 221 InitialGainStep = 8; 222 LowestGainStage = priv->RegBModeGainStage; // Lowest gain stage. 223 224 if (OFDMFalseAlarm > OfdmFA1) 225 { 226 if (OFDMFalseAlarm > OfdmFA2) 227 { 228 priv->DIG_NumberFallbackVote++; 229 if (priv->DIG_NumberFallbackVote >1) 230 { 231 //serious OFDM False Alarm, need fallback 232 if (priv->InitialGain < InitialGainStep) 233 { 234 priv->InitialGainBackUp= priv->InitialGain; 235 236 priv->InitialGain = (priv->InitialGain + 1); 237// printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2); 238// printk("DIG+++++++ fallback OFDM:%d \n", priv->InitialGain); 239 UpdateInitialGain(dev); 240 } 241 priv->DIG_NumberFallbackVote = 0; 242 priv->DIG_NumberUpgradeVote=0; 243 } 244 } 245 else 246 { 247 if (priv->DIG_NumberFallbackVote) 248 priv->DIG_NumberFallbackVote--; 249 } 250 priv->DIG_NumberUpgradeVote=0; 251 } 252 else 253 { 254 if (priv->DIG_NumberFallbackVote) 255 priv->DIG_NumberFallbackVote--; 256 priv->DIG_NumberUpgradeVote++; 257 258 if (priv->DIG_NumberUpgradeVote>9) 259 { 260 if (priv->InitialGain > LowestGainStage) // In 87B, m78dBm means State 4 (m864dBm) 261 { 262 priv->InitialGainBackUp= priv->InitialGain; 263 264 priv->InitialGain = (priv->InitialGain - 1); 265// printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2); 266// printk("DIG--------- Upgrade OFDM:%d \n", priv->InitialGain); 267 UpdateInitialGain(dev); 268 } 269 priv->DIG_NumberFallbackVote = 0; 270 priv->DIG_NumberUpgradeVote=0; 271 } 272 } 273 274// printk("DIG+++++++ OFDM:%d\n", priv->InitialGain); 275 //printk("<--------- DIG_Zebra()\n"); 276} 277 278// 279// Description: 280// Dispatch DIG implementation according to RF. 281// 282void 283DynamicInitGain(struct net_device *dev) 284{ 285 DIG_Zebra(dev); 286} 287 288void rtl8180_hw_dig_wq (struct work_struct *work) 289{ 290 struct delayed_work *dwork = to_delayed_work(work); 291 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_dig_wq); 292 struct net_device *dev = ieee->dev; 293 struct r8180_priv *priv = ieee80211_priv(dev); 294 295 // Read CCK and OFDM False Alarm. 296 priv->FalseAlarmRegValue = read_nic_dword(dev, CCK_FALSE_ALARM); 297 298 299 // Adjust Initial Gain dynamically. 300 DynamicInitGain(dev); 301 302} 303 304int 305IncludedInSupportedRates( 306 struct r8180_priv *priv, 307 u8 TxRate ) 308{ 309 u8 rate_len; 310 u8 rate_ex_len; 311 u8 RateMask = 0x7F; 312 u8 idx; 313 unsigned short Found = 0; 314 u8 NaiveTxRate = TxRate&RateMask; 315 316 rate_len = priv->ieee80211->current_network.rates_len; 317 rate_ex_len = priv->ieee80211->current_network.rates_ex_len; 318 for( idx=0; idx< rate_len; idx++ ) 319 { 320 if( (priv->ieee80211->current_network.rates[idx] & RateMask) == NaiveTxRate ) 321 { 322 Found = 1; 323 goto found_rate; 324 } 325 } 326 for( idx=0; idx< rate_ex_len; idx++ ) 327 { 328 if( (priv->ieee80211->current_network.rates_ex[idx] & RateMask) == NaiveTxRate ) 329 { 330 Found = 1; 331 goto found_rate; 332 } 333 } 334 return Found; 335 found_rate: 336 return Found; 337} 338 339// 340// Description: 341// Get the Tx rate one degree up form the input rate in the supported rates. 342// Return the upgrade rate if it is successed, otherwise return the input rate. 343// By Bruce, 2007-06-05. 344// 345u8 346GetUpgradeTxRate( 347 struct net_device *dev, 348 u8 rate 349 ) 350{ 351 struct r8180_priv *priv = ieee80211_priv(dev); 352 u8 UpRate; 353 354 // Upgrade 1 degree. 355 switch(rate) 356 { 357 case 108: // Up to 54Mbps. 358 UpRate = 108; 359 break; 360 361 case 96: // Up to 54Mbps. 362 UpRate = 108; 363 break; 364 365 case 72: // Up to 48Mbps. 366 UpRate = 96; 367 break; 368 369 case 48: // Up to 36Mbps. 370 UpRate = 72; 371 break; 372 373 case 36: // Up to 24Mbps. 374 UpRate = 48; 375 break; 376 377 case 22: // Up to 18Mbps. 378 UpRate = 36; 379 break; 380 381 case 11: // Up to 11Mbps. 382 UpRate = 22; 383 break; 384 385 case 4: // Up to 5.5Mbps. 386 UpRate = 11; 387 break; 388 389 case 2: // Up to 2Mbps. 390 UpRate = 4; 391 break; 392 393 default: 394 printk("GetUpgradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate); 395 return rate; 396 } 397 // Check if the rate is valid. 398 if(IncludedInSupportedRates(priv, UpRate)) 399 { 400// printk("GetUpgradeTxRate(): GetUpgrade Tx rate(%d) from %d !\n", UpRate, priv->CurrentOperaRate); 401 return UpRate; 402 } 403 else 404 { 405 //printk("GetUpgradeTxRate(): Tx rate (%d) is not in supported rates\n", UpRate); 406 return rate; 407 } 408 return rate; 409} 410// 411// Description: 412// Get the Tx rate one degree down form the input rate in the supported rates. 413// Return the degrade rate if it is successed, otherwise return the input rate. 414// By Bruce, 2007-06-05. 415// 416u8 417GetDegradeTxRate( 418 struct net_device *dev, 419 u8 rate 420 ) 421{ 422 struct r8180_priv *priv = ieee80211_priv(dev); 423 u8 DownRate; 424 425 // Upgrade 1 degree. 426 switch(rate) 427 { 428 case 108: // Down to 48Mbps. 429 DownRate = 96; 430 break; 431 432 case 96: // Down to 36Mbps. 433 DownRate = 72; 434 break; 435 436 case 72: // Down to 24Mbps. 437 DownRate = 48; 438 break; 439 440 case 48: // Down to 18Mbps. 441 DownRate = 36; 442 break; 443 444 case 36: // Down to 11Mbps. 445 DownRate = 22; 446 break; 447 448 case 22: // Down to 5.5Mbps. 449 DownRate = 11; 450 break; 451 452 case 11: // Down to 2Mbps. 453 DownRate = 4; 454 break; 455 456 case 4: // Down to 1Mbps. 457 DownRate = 2; 458 break; 459 460 case 2: // Down to 1Mbps. 461 DownRate = 2; 462 break; 463 464 default: 465 printk("GetDegradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate); 466 return rate; 467 } 468 // Check if the rate is valid. 469 if(IncludedInSupportedRates(priv, DownRate)) 470 { 471// printk("GetDegradeTxRate(): GetDegrade Tx rate(%d) from %d!\n", DownRate, priv->CurrentOperaRate); 472 return DownRate; 473 } 474 else 475 { 476 //printk("GetDegradeTxRate(): Tx rate (%d) is not in supported rates\n", DownRate); 477 return rate; 478 } 479 return rate; 480} 481// 482// Helper function to determine if specified data rate is 483// CCK rate. 484// 2005.01.25, by rcnjko. 485// 486bool 487MgntIsCckRate( 488 u16 rate 489 ) 490{ 491 bool bReturn = false; 492 493 if((rate <= 22) && (rate != 12) && (rate != 18)) 494 { 495 bReturn = true; 496 } 497 498 return bReturn; 499} 500// 501// Description: 502// Tx Power tracking mechanism routine on 87SE. 503// Created by Roger, 2007.12.11. 504// 505void 506TxPwrTracking87SE( 507 struct net_device *dev 508) 509{ 510 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); 511 u8 tmpu1Byte, CurrentThermal, Idx; 512 char CckTxPwrIdx, OfdmTxPwrIdx; 513 //u32 u4bRfReg; 514 515 tmpu1Byte = read_nic_byte(dev, EN_LPF_CAL); 516 CurrentThermal = (tmpu1Byte & 0xf0)>>4; //[ 7:4]: thermal meter indication. 517 CurrentThermal = (CurrentThermal>0x0c)? 0x0c:CurrentThermal;//lzm add 080826 518 519 //printk("TxPwrTracking87SE(): CurrentThermal(%d)\n", CurrentThermal); 520 521 if( CurrentThermal != priv->ThermalMeter) 522 { 523// printk("TxPwrTracking87SE(): Thermal meter changed!!!\n"); 524 525 // Update Tx Power level on each channel. 526 for(Idx = 1; Idx<15; Idx++) 527 { 528 CckTxPwrIdx = priv->chtxpwr[Idx]; 529 OfdmTxPwrIdx = priv->chtxpwr_ofdm[Idx]; 530 531 if( CurrentThermal > priv->ThermalMeter ) 532 { // higher thermal meter. 533 CckTxPwrIdx += (CurrentThermal - priv->ThermalMeter)*2; 534 OfdmTxPwrIdx += (CurrentThermal - priv->ThermalMeter)*2; 535 536 if(CckTxPwrIdx >35) 537 CckTxPwrIdx = 35; // Force TxPower to maximal index. 538 if(OfdmTxPwrIdx >35) 539 OfdmTxPwrIdx = 35; 540 } 541 else 542 { // lower thermal meter. 543 CckTxPwrIdx -= (priv->ThermalMeter - CurrentThermal)*2; 544 OfdmTxPwrIdx -= (priv->ThermalMeter - CurrentThermal)*2; 545 546 if(CckTxPwrIdx <0) 547 CckTxPwrIdx = 0; 548 if(OfdmTxPwrIdx <0) 549 OfdmTxPwrIdx = 0; 550 } 551 552 // Update TxPower level on CCK and OFDM resp. 553 priv->chtxpwr[Idx] = CckTxPwrIdx; 554 priv->chtxpwr_ofdm[Idx] = OfdmTxPwrIdx; 555 } 556 557 // Update TxPower level immediately. 558 rtl8225z2_SetTXPowerLevel(dev, priv->ieee80211->current_network.channel); 559 } 560 priv->ThermalMeter = CurrentThermal; 561} 562void 563StaRateAdaptive87SE( 564 struct net_device *dev 565 ) 566{ 567 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); 568 unsigned long CurrTxokCnt; 569 u16 CurrRetryCnt; 570 u16 CurrRetryRate; 571 //u16 i,idx; 572 unsigned long CurrRxokCnt; 573 bool bTryUp = false; 574 bool bTryDown = false; 575 u8 TryUpTh = 1; 576 u8 TryDownTh = 2; 577 u32 TxThroughput; 578 long CurrSignalStrength; 579 bool bUpdateInitialGain = false; 580 u8 u1bOfdm=0, u1bCck = 0; 581 char OfdmTxPwrIdx, CckTxPwrIdx; 582 583 priv->RateAdaptivePeriod= RATE_ADAPTIVE_TIMER_PERIOD; 584 585 586 CurrRetryCnt = priv->CurrRetryCnt; 587 CurrTxokCnt = priv->NumTxOkTotal - priv->LastTxokCnt; 588 CurrRxokCnt = priv->ieee80211->NumRxOkTotal - priv->LastRxokCnt; 589 CurrSignalStrength = priv->Stats_RecvSignalPower; 590 TxThroughput = (u32)(priv->NumTxOkBytesTotal - priv->LastTxOKBytes); 591 priv->LastTxOKBytes = priv->NumTxOkBytesTotal; 592 priv->CurrentOperaRate = priv->ieee80211->rate/5; 593 //printk("priv->CurrentOperaRate is %d\n",priv->CurrentOperaRate); 594 //2 Compute retry ratio. 595 if (CurrTxokCnt>0) 596 { 597 CurrRetryRate = (u16)(CurrRetryCnt*100/CurrTxokCnt); 598 } 599 else 600 { // It may be serious retry. To distinguish serious retry or no packets modified by Bruce 601 CurrRetryRate = (u16)(CurrRetryCnt*100/1); 602 } 603 604 605 // 606 // Added by Roger, 2007.01.02. 607 // For debug information. 608 // 609 //printk("\n(1) pHalData->LastRetryRate: %d \n",priv->LastRetryRate); 610 //printk("(2) RetryCnt = %d \n", CurrRetryCnt); 611 //printk("(3) TxokCnt = %d \n", CurrTxokCnt); 612 //printk("(4) CurrRetryRate = %d \n", CurrRetryRate); 613 //printk("(5) CurrSignalStrength = %d \n",CurrSignalStrength); 614 //printk("(6) TxThroughput is %d\n",TxThroughput); 615 //printk("priv->NumTxOkBytesTotal is %d\n",priv->NumTxOkBytesTotal); 616 617 priv->LastRetryCnt = priv->CurrRetryCnt; 618 priv->LastTxokCnt = priv->NumTxOkTotal; 619 priv->LastRxokCnt = priv->ieee80211->NumRxOkTotal; 620 priv->CurrRetryCnt = 0; 621 622 //2No Tx packets, return to init_rate or not? 623 if (CurrRetryRate==0 && CurrTxokCnt == 0) 624 { 625 // 626 //After 9 (30*300ms) seconds in this condition, we try to raise rate. 627 // 628 priv->TryupingCountNoData++; 629 630// printk("No Tx packets, TryupingCountNoData(%d)\n", priv->TryupingCountNoData); 631 //[TRC Dell Lab] Extend raised period from 4.5sec to 9sec, Isaiah 2008-02-15 18:00 632 if (priv->TryupingCountNoData>30) 633 { 634 priv->TryupingCountNoData = 0; 635 priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate); 636 // Reset Fail Record 637 priv->LastFailTxRate = 0; 638 priv->LastFailTxRateSS = -200; 639 priv->FailTxRateCount = 0; 640 } 641 goto SetInitialGain; 642 } 643 else 644 { 645 priv->TryupingCountNoData=0; //Reset trying up times. 646 } 647 648 649 // 650 // For Netgear case, I comment out the following signal strength estimation, 651 // which can results in lower rate to transmit when sample is NOT enough (e.g. PING request). 652 // 2007.04.09, by Roger. 653 // 654 655 // 656 // Restructure rate adaptive as the following main stages: 657 // (1) Add retry threshold in 54M upgrading condition with signal strength. 658 // (2) Add the mechanism to degrade to CCK rate according to signal strength 659 // and retry rate. 660 // (3) Remove all Initial Gain Updates over OFDM rate. To avoid the complicated 661 // situation, Initial Gain Update is upon on DIG mechanism except CCK rate. 662 // (4) Add the mehanism of trying to upgrade tx rate. 663 // (5) Record the information of upping tx rate to avoid trying upping tx rate constantly. 664 // By Bruce, 2007-06-05. 665 // 666 // 667 668 // 11Mbps or 36Mbps 669 // Check more times in these rate(key rates). 670 // 671 if(priv->CurrentOperaRate == 22 || priv->CurrentOperaRate == 72) 672 { 673 TryUpTh += 9; 674 } 675 // 676 // Let these rates down more difficult. 677 // 678 if(MgntIsCckRate(priv->CurrentOperaRate) || priv->CurrentOperaRate == 36) 679 { 680 TryDownTh += 1; 681 } 682 683 //1 Adjust Rate. 684 if (priv->bTryuping == true) 685 { 686 //2 For Test Upgrading mechanism 687 // Note: 688 // Sometimes the throughput is upon on the capability bwtween the AP and NIC, 689 // thus the low data rate does not improve the performance. 690 // We randomly upgrade the data rate and check if the retry rate is improved. 691 692 // Upgrading rate did not improve the retry rate, fallback to the original rate. 693 if ( (CurrRetryRate > 25) && TxThroughput < priv->LastTxThroughput) 694 { 695 //Not necessary raising rate, fall back rate. 696 bTryDown = true; 697 //printk("case1-1: Not necessary raising rate, fall back rate....\n"); 698 //printk("case1-1: pMgntInfo->CurrentOperaRate =%d, TxThroughput = %d, LastThroughput = %d\n", 699 // priv->CurrentOperaRate, TxThroughput, priv->LastTxThroughput); 700 } 701 else 702 { 703 priv->bTryuping = false; 704 } 705 } 706 else if (CurrSignalStrength > -47 && (CurrRetryRate < 50)) 707 { 708 //2For High Power 709 // 710 // Added by Roger, 2007.04.09. 711 // Return to highest data rate, if signal strength is good enough. 712 // SignalStrength threshold(-50dbm) is for RTL8186. 713 // Revise SignalStrength threshold to -51dbm. 714 // 715 // Also need to check retry rate for safety, by Bruce, 2007-06-05. 716 if(priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate ) 717 { 718 bTryUp = true; 719 // Upgrade Tx Rate directly. 720 priv->TryupingCount += TryUpTh; 721 } 722// printk("case2: StaRateAdaptive87SE: Power(%d) is high enough!!. \n", CurrSignalStrength); 723 724 } 725 else if(CurrTxokCnt > 9 && CurrTxokCnt< 100 && CurrRetryRate >= 600) 726 { 727 //2 For Serious Retry 728 // 729 // Traffic is not busy but our Tx retry is serious. 730 // 731 bTryDown = true; 732 // Let Rate Mechanism to degrade tx rate directly. 733 priv->TryDownCountLowData += TryDownTh; 734// printk("case3: RA: Tx Retry is serious. Degrade Tx Rate to %d directly...\n", priv->CurrentOperaRate); 735 } 736 else if ( priv->CurrentOperaRate == 108 ) 737 { 738 //2For 54Mbps 739 // Air Link 740 if ( (CurrRetryRate>26)&&(priv->LastRetryRate>25)) 741// if ( (CurrRetryRate>40)&&(priv->LastRetryRate>39)) 742 { 743 //Down to rate 48Mbps. 744 bTryDown = true; 745 } 746 // Cable Link 747 else if ( (CurrRetryRate>17)&&(priv->LastRetryRate>16) && (CurrSignalStrength > -72)) 748// else if ( (CurrRetryRate>17)&&(priv->LastRetryRate>16) && (CurrSignalStrength > -72)) 749 { 750 //Down to rate 48Mbps. 751 bTryDown = true; 752 } 753 754 if(bTryDown && (CurrSignalStrength < -75)) //cable link 755 { 756 priv->TryDownCountLowData += TryDownTh; 757 } 758 //printk("case4---54M \n"); 759 760 } 761 else if ( priv->CurrentOperaRate == 96 ) 762 { 763 //2For 48Mbps 764 //Air Link 765 if ( ((CurrRetryRate>48) && (priv->LastRetryRate>47))) 766// if ( ((CurrRetryRate>65) && (priv->LastRetryRate>64))) 767 768 { 769 //Down to rate 36Mbps. 770 bTryDown = true; 771 } 772 //Cable Link 773 else if ( ((CurrRetryRate>21) && (priv->LastRetryRate>20)) && (CurrSignalStrength > -74)) 774 { 775 //Down to rate 36Mbps. 776 bTryDown = true; 777 } 778 else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 )) 779// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 )) 780 { 781 bTryDown = true; 782 priv->TryDownCountLowData += TryDownTh; 783 } 784 else if ( (CurrRetryRate<8) && (priv->LastRetryRate<8) ) //TO DO: need to consider (RSSI) 785// else if ( (CurrRetryRate<28) && (priv->LastRetryRate<8) ) 786 { 787 bTryUp = true; 788 } 789 790 if(bTryDown && (CurrSignalStrength < -75)) 791 { 792 priv->TryDownCountLowData += TryDownTh; 793 } 794 //printk("case5---48M \n"); 795 } 796 else if ( priv->CurrentOperaRate == 72 ) 797 { 798 //2For 36Mbps 799 if ( (CurrRetryRate>43) && (priv->LastRetryRate>41)) 800// if ( (CurrRetryRate>60) && (priv->LastRetryRate>59)) 801 { 802 //Down to rate 24Mbps. 803 bTryDown = true; 804 } 805 else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 )) 806// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 )) 807 { 808 bTryDown = true; 809 priv->TryDownCountLowData += TryDownTh; 810 } 811 else if ( (CurrRetryRate<15) && (priv->LastRetryRate<16)) //TO DO: need to consider (RSSI) 812// else if ( (CurrRetryRate<35) && (priv->LastRetryRate<36)) 813 { 814 bTryUp = true; 815 } 816 817 if(bTryDown && (CurrSignalStrength < -80)) 818 { 819 priv->TryDownCountLowData += TryDownTh; 820 } 821 //printk("case6---36M \n"); 822 } 823 else if ( priv->CurrentOperaRate == 48 ) 824 { 825 //2For 24Mbps 826 // Air Link 827 if ( ((CurrRetryRate>63) && (priv->LastRetryRate>62))) 828// if ( ((CurrRetryRate>83) && (priv->LastRetryRate>82))) 829 { 830 //Down to rate 18Mbps. 831 bTryDown = true; 832 } 833 //Cable Link 834 else if ( ((CurrRetryRate>33) && (priv->LastRetryRate>32)) && (CurrSignalStrength > -82) ) 835// else if ( ((CurrRetryRate>50) && (priv->LastRetryRate>49)) && (CurrSignalStrength > -82) ) 836 { 837 //Down to rate 18Mbps. 838 bTryDown = true; 839 } 840 else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 )) 841// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 )) 842 843 { 844 bTryDown = true; 845 priv->TryDownCountLowData += TryDownTh; 846 } 847 else if ( (CurrRetryRate<20) && (priv->LastRetryRate<21)) //TO DO: need to consider (RSSI) 848// else if ( (CurrRetryRate<40) && (priv->LastRetryRate<41)) 849 { 850 bTryUp = true; 851 } 852 853 if(bTryDown && (CurrSignalStrength < -82)) 854 { 855 priv->TryDownCountLowData += TryDownTh; 856 } 857 //printk("case7---24M \n"); 858 } 859 else if ( priv->CurrentOperaRate == 36 ) 860 { 861 //2For 18Mbps 862 // original (109, 109) 863 //[TRC Dell Lab] (90, 91), Isaiah 2008-02-18 23:24 864 // (85, 86), Isaiah 2008-02-18 24:00 865 if ( ((CurrRetryRate>85) && (priv->LastRetryRate>86))) 866// if ( ((CurrRetryRate>115) && (priv->LastRetryRate>116))) 867 { 868 //Down to rate 11Mbps. 869 bTryDown = true; 870 } 871 //[TRC Dell Lab] Isaiah 2008-02-18 23:24 872 else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 )) 873// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 )) 874 { 875 bTryDown = true; 876 priv->TryDownCountLowData += TryDownTh; 877 } 878 else if ( (CurrRetryRate<22) && (priv->LastRetryRate<23)) //TO DO: need to consider (RSSI) 879// else if ( (CurrRetryRate<42) && (priv->LastRetryRate<43)) 880 { 881 bTryUp = true; 882 } 883 //printk("case8---18M \n"); 884 } 885 else if ( priv->CurrentOperaRate == 22 ) 886 { 887 //2For 11Mbps 888 if (CurrRetryRate>95) 889// if (CurrRetryRate>155) 890 { 891 bTryDown = true; 892 } 893 else if ( (CurrRetryRate<29) && (priv->LastRetryRate <30) )//TO DO: need to consider (RSSI) 894// else if ( (CurrRetryRate<49) && (priv->LastRetryRate <50) ) 895 { 896 bTryUp = true; 897 } 898 //printk("case9---11M \n"); 899 } 900 else if ( priv->CurrentOperaRate == 11 ) 901 { 902 //2For 5.5Mbps 903 if (CurrRetryRate>149) 904// if (CurrRetryRate>189) 905 { 906 bTryDown = true; 907 } 908 else if ( (CurrRetryRate<60) && (priv->LastRetryRate < 65)) 909// else if ( (CurrRetryRate<80) && (priv->LastRetryRate < 85)) 910 911 { 912 bTryUp = true; 913 } 914 //printk("case10---5.5M \n"); 915 } 916 else if ( priv->CurrentOperaRate == 4 ) 917 { 918 //2For 2 Mbps 919 if((CurrRetryRate>99) && (priv->LastRetryRate>99)) 920// if((CurrRetryRate>199) && (priv->LastRetryRate>199)) 921 { 922 bTryDown = true; 923 } 924 else if ( (CurrRetryRate < 65) && (priv->LastRetryRate < 70)) 925// else if ( (CurrRetryRate < 85) && (priv->LastRetryRate < 90)) 926 { 927 bTryUp = true; 928 } 929 //printk("case11---2M \n"); 930 } 931 else if ( priv->CurrentOperaRate == 2 ) 932 { 933 //2For 1 Mbps 934 if( (CurrRetryRate<70) && (priv->LastRetryRate<75)) 935// if( (CurrRetryRate<90) && (priv->LastRetryRate<95)) 936 { 937 bTryUp = true; 938 } 939 //printk("case12---1M \n"); 940 } 941 942 if(bTryUp && bTryDown) 943 printk("StaRateAdaptive87B(): Tx Rate tried upping and downing simultaneously!\n"); 944 945 //1 Test Upgrading Tx Rate 946 // Sometimes the cause of the low throughput (high retry rate) is the compatibility between the AP and NIC. 947 // To test if the upper rate may cause lower retry rate, this mechanism randomly occurs to test upgrading tx rate. 948 if(!bTryUp && !bTryDown && (priv->TryupingCount == 0) && (priv->TryDownCountLowData == 0) 949 && priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate && priv->FailTxRateCount < 2) 950 { 951 if(jiffies% (CurrRetryRate + 101) == 0) 952 { 953 bTryUp = true; 954 priv->bTryuping = true; 955 //printk("StaRateAdaptive87SE(): Randomly try upgrading...\n"); 956 } 957 } 958 959 //1 Rate Mechanism 960 if(bTryUp) 961 { 962 priv->TryupingCount++; 963 priv->TryDownCountLowData = 0; 964 965 { 966// printk("UP: pHalData->TryupingCount = %d\n", priv->TryupingCount); 967// printk("UP: TryUpTh(%d)+ (FailTxRateCount(%d))^2 =%d\n", 968// TryUpTh, priv->FailTxRateCount, (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount) ); 969// printk("UP: pHalData->bTryuping=%d\n", priv->bTryuping); 970 971 } 972 973 // 974 // Check more times if we need to upgrade indeed. 975 // Because the largest value of pHalData->TryupingCount is 0xFFFF and 976 // the largest value of pHalData->FailTxRateCount is 0x14, 977 // this condition will be satisfied at most every 2 min. 978 // 979 980 if((priv->TryupingCount > (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount)) || 981 (CurrSignalStrength > priv->LastFailTxRateSS) || priv->bTryuping) 982 { 983 priv->TryupingCount = 0; 984 // 985 // When transfering from CCK to OFDM, DIG is an important issue. 986 // 987 if(priv->CurrentOperaRate == 22) 988 bUpdateInitialGain = true; 989 990 // The difference in throughput between 48Mbps and 36Mbps is 8M. 991 // So, we must be carefully in this rate scale. Isaiah 2008-02-15. 992 // 993 if( ((priv->CurrentOperaRate == 72) || (priv->CurrentOperaRate == 48) || (priv->CurrentOperaRate == 36)) && 994 (priv->FailTxRateCount > 2) ) 995 priv->RateAdaptivePeriod= (RATE_ADAPTIVE_TIMER_PERIOD/2); 996 997 // (1)To avoid upgrade frequently to the fail tx rate, add the FailTxRateCount into the threshold. 998 // (2)If the signal strength is increased, it may be able to upgrade. 999 1000 priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate); 1001// printk("StaRateAdaptive87SE(): Upgrade Tx Rate to %d\n", priv->CurrentOperaRate); 1002 1003 //[TRC Dell Lab] Bypass 12/9/6, Isaiah 2008-02-18 20:00 1004 if(priv->CurrentOperaRate ==36) 1005 { 1006 priv->bUpdateARFR=true; 1007 write_nic_word(dev, ARFR, 0x0F8F); //bypass 12/9/6 1008// printk("UP: ARFR=0xF8F\n"); 1009 } 1010 else if(priv->bUpdateARFR) 1011 { 1012 priv->bUpdateARFR=false; 1013 write_nic_word(dev, ARFR, 0x0FFF); //set 1M ~ 54Mbps. 1014// printk("UP: ARFR=0xFFF\n"); 1015 } 1016 1017 // Update Fail Tx rate and count. 1018 if(priv->LastFailTxRate != priv->CurrentOperaRate) 1019 { 1020 priv->LastFailTxRate = priv->CurrentOperaRate; 1021 priv->FailTxRateCount = 0; 1022 priv->LastFailTxRateSS = -200; // Set lowest power. 1023 } 1024 } 1025 } 1026 else 1027 { 1028 if(priv->TryupingCount > 0) 1029 priv->TryupingCount --; 1030 } 1031 1032 if(bTryDown) 1033 { 1034 priv->TryDownCountLowData++; 1035 priv->TryupingCount = 0; 1036 { 1037// printk("DN: pHalData->TryDownCountLowData = %d\n",priv->TryDownCountLowData); 1038// printk("DN: TryDownTh =%d\n", TryDownTh); 1039// printk("DN: pHalData->bTryuping=%d\n", priv->bTryuping); 1040 } 1041 1042 //Check if Tx rate can be degraded or Test trying upgrading should fallback. 1043 if(priv->TryDownCountLowData > TryDownTh || priv->bTryuping) 1044 { 1045 priv->TryDownCountLowData = 0; 1046 priv->bTryuping = false; 1047 // Update fail information. 1048 if(priv->LastFailTxRate == priv->CurrentOperaRate) 1049 { 1050 priv->FailTxRateCount ++; 1051 // Record the Tx fail rate signal strength. 1052 if(CurrSignalStrength > priv->LastFailTxRateSS) 1053 { 1054 priv->LastFailTxRateSS = CurrSignalStrength; 1055 } 1056 } 1057 else 1058 { 1059 priv->LastFailTxRate = priv->CurrentOperaRate; 1060 priv->FailTxRateCount = 1; 1061 priv->LastFailTxRateSS = CurrSignalStrength; 1062 } 1063 priv->CurrentOperaRate = GetDegradeTxRate(dev, priv->CurrentOperaRate); 1064 1065 // Reduce chariot training time at weak signal strength situation. SD3 ED demand. 1066 //[TRC Dell Lab] Revise Signal Threshold from -75 to -80 , Isaiah 2008-02-18 20:00 1067 if( (CurrSignalStrength < -80) && (priv->CurrentOperaRate > 72 )) 1068 { 1069 priv->CurrentOperaRate = 72; 1070// printk("DN: weak signal strength (%d), degrade to 36Mbps\n", CurrSignalStrength); 1071 } 1072 1073 //[TRC Dell Lab] Bypass 12/9/6, Isaiah 2008-02-18 20:00 1074 if(priv->CurrentOperaRate ==36) 1075 { 1076 priv->bUpdateARFR=true; 1077 write_nic_word(dev, ARFR, 0x0F8F); //bypass 12/9/6 1078// printk("DN: ARFR=0xF8F\n"); 1079 } 1080 else if(priv->bUpdateARFR) 1081 { 1082 priv->bUpdateARFR=false; 1083 write_nic_word(dev, ARFR, 0x0FFF); //set 1M ~ 54Mbps. 1084// printk("DN: ARFR=0xFFF\n"); 1085 } 1086 1087 // 1088 // When it is CCK rate, it may need to update initial gain to receive lower power packets. 1089 // 1090 if(MgntIsCckRate(priv->CurrentOperaRate)) 1091 { 1092 bUpdateInitialGain = true; 1093 } 1094// printk("StaRateAdaptive87SE(): Degrade Tx Rate to %d\n", priv->CurrentOperaRate); 1095 } 1096 } 1097 else 1098 { 1099 if(priv->TryDownCountLowData > 0) 1100 priv->TryDownCountLowData --; 1101 } 1102 1103 // Keep the Tx fail rate count to equal to 0x15 at most. 1104 // Reduce the fail count at least to 10 sec if tx rate is tending stable. 1105 if(priv->FailTxRateCount >= 0x15 || 1106 (!bTryUp && !bTryDown && priv->TryDownCountLowData == 0 && priv->TryupingCount && priv->FailTxRateCount > 0x6)) 1107 { 1108 priv->FailTxRateCount --; 1109 } 1110 1111 1112 OfdmTxPwrIdx = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel]; 1113 CckTxPwrIdx = priv->chtxpwr[priv->ieee80211->current_network.channel]; 1114 1115 //[TRC Dell Lab] Mac0x9e increase 2 level in 36M~18M situation, Isaiah 2008-02-18 24:00 1116 if((priv->CurrentOperaRate < 96) &&(priv->CurrentOperaRate > 22)) 1117 { 1118 u1bCck = read_nic_byte(dev, CCK_TXAGC); 1119 u1bOfdm = read_nic_byte(dev, OFDM_TXAGC); 1120 1121 // case 1: Never enter High power 1122 if(u1bCck == CckTxPwrIdx ) 1123 { 1124 if(u1bOfdm != (OfdmTxPwrIdx+2) ) 1125 { 1126 priv->bEnhanceTxPwr= true; 1127 u1bOfdm = ((u1bOfdm+2) > 35) ? 35: (u1bOfdm+2); 1128 write_nic_byte(dev, OFDM_TXAGC, u1bOfdm); 1129// printk("Enhance OFDM_TXAGC : +++++ u1bOfdm= 0x%x\n", u1bOfdm); 1130 } 1131 } 1132 // case 2: enter high power 1133 else if(u1bCck < CckTxPwrIdx) 1134 { 1135 if(!priv->bEnhanceTxPwr) 1136 { 1137 priv->bEnhanceTxPwr= true; 1138 u1bOfdm = ((u1bOfdm+2) > 35) ? 35: (u1bOfdm+2); 1139 write_nic_byte(dev, OFDM_TXAGC, u1bOfdm); 1140 //RT_TRACE(COMP_RATE, DBG_TRACE, ("Enhance OFDM_TXAGC(2) : +++++ u1bOfdm= 0x%x\n", u1bOfdm)); 1141 } 1142 } 1143 } 1144 else if(priv->bEnhanceTxPwr) //54/48/11/5.5/2/1 1145 { 1146 u1bCck = read_nic_byte(dev, CCK_TXAGC); 1147 u1bOfdm = read_nic_byte(dev, OFDM_TXAGC); 1148 1149 // case 1: Never enter High power 1150 if(u1bCck == CckTxPwrIdx ) 1151 { 1152 priv->bEnhanceTxPwr= false; 1153 write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx); 1154 //printk("Recover OFDM_TXAGC : ===== u1bOfdm= 0x%x\n", OfdmTxPwrIdx); 1155 } 1156 // case 2: enter high power 1157 else if(u1bCck < CckTxPwrIdx) 1158 { 1159 priv->bEnhanceTxPwr= false; 1160 u1bOfdm = ((u1bOfdm-2) > 0) ? (u1bOfdm-2): 0; 1161 write_nic_byte(dev, OFDM_TXAGC, u1bOfdm); 1162 //RT_TRACE(COMP_RATE, DBG_TRACE, ("Recover OFDM_TXAGC(2): ===== u1bOfdm= 0x%x\n", u1bOfdm)); 1163 1164 } 1165 } 1166 1167 // 1168 // We need update initial gain when we set tx rate "from OFDM to CCK" or 1169 // "from CCK to OFDM". 1170 // 1171SetInitialGain: 1172 if(bUpdateInitialGain) 1173 { 1174 if(MgntIsCckRate(priv->CurrentOperaRate)) // CCK 1175 { 1176 if(priv->InitialGain > priv->RegBModeGainStage) 1177 { 1178 priv->InitialGainBackUp= priv->InitialGain; 1179 1180 if(CurrSignalStrength < -85) // Low power, OFDM [0x17] = 26. 1181 { 1182 //SD3 SYs suggest that CurrSignalStrength < -65, ofdm 0x17=26. 1183 priv->InitialGain = priv->RegBModeGainStage; 1184 } 1185 else if(priv->InitialGain > priv->RegBModeGainStage + 1) 1186 { 1187 priv->InitialGain -= 2; 1188 } 1189 else 1190 { 1191 priv->InitialGain --; 1192 } 1193 printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate); 1194 UpdateInitialGain(dev); 1195 } 1196 } 1197 else // OFDM 1198 { 1199 if(priv->InitialGain < 4) 1200 { 1201 priv->InitialGainBackUp= priv->InitialGain; 1202 1203 priv->InitialGain ++; 1204 printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate); 1205 UpdateInitialGain(dev); 1206 } 1207 } 1208 } 1209 1210 //Record the related info 1211 priv->LastRetryRate = CurrRetryRate; 1212 priv->LastTxThroughput = TxThroughput; 1213 priv->ieee80211->rate = priv->CurrentOperaRate * 5; 1214} 1215 1216void rtl8180_rate_adapter(struct work_struct * work) 1217{ 1218 struct delayed_work *dwork = to_delayed_work(work); 1219 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,rate_adapter_wq); 1220 struct net_device *dev = ieee->dev; 1221 //struct r8180_priv *priv = ieee80211_priv(dev); 1222// DMESG("---->rtl8180_rate_adapter"); 1223 StaRateAdaptive87SE(dev); 1224// DMESG("<----rtl8180_rate_adapter"); 1225} 1226void timer_rate_adaptive(unsigned long data) 1227{ 1228 struct r8180_priv* priv = ieee80211_priv((struct net_device *)data); 1229 //DMESG("---->timer_rate_adaptive()\n"); 1230 if(!priv->up) 1231 { 1232// DMESG("<----timer_rate_adaptive():driver is not up!\n"); 1233 return; 1234 } 1235 if((priv->ieee80211->iw_mode != IW_MODE_MASTER) 1236 && (priv->ieee80211->state == IEEE80211_LINKED) && 1237 (priv->ForcedDataRate == 0) ) 1238 { 1239// DMESG("timer_rate_adaptive():schedule rate_adapter_wq\n"); 1240 queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->rate_adapter_wq); 1241// StaRateAdaptive87SE((struct net_device *)data); 1242 } 1243 priv->rateadapter_timer.expires = jiffies + MSECS(priv->RateAdaptivePeriod); 1244 add_timer(&priv->rateadapter_timer); 1245 //DMESG("<----timer_rate_adaptive()\n"); 1246} 1247//by amy 080312} 1248void 1249SwAntennaDiversityRxOk8185( 1250 struct net_device *dev, 1251 u8 SignalStrength 1252 ) 1253{ 1254 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); 1255 1256// printk("+SwAntennaDiversityRxOk8185: RxSs: %d\n", SignalStrength); 1257 1258 priv->AdRxOkCnt++; 1259 1260 if( priv->AdRxSignalStrength != -1) 1261 { 1262 priv->AdRxSignalStrength = ((priv->AdRxSignalStrength*7) + (SignalStrength*3)) / 10; 1263 } 1264 else 1265 { // Initialization case. 1266 priv->AdRxSignalStrength = SignalStrength; 1267 } 1268//{+by amy 080312 1269 if( priv->LastRxPktAntenna ) //Main antenna. 1270 priv->AdMainAntennaRxOkCnt++; 1271 else // Aux antenna. 1272 priv->AdAuxAntennaRxOkCnt++; 1273//+by amy 080312 1274// printk("-SwAntennaDiversityRxOk8185: AdRxOkCnt: %d AdRxSignalStrength: %d\n", priv->AdRxOkCnt, priv->AdRxSignalStrength); 1275} 1276// 1277// Description: 1278// Change Antenna Switch. 1279// 1280bool 1281SetAntenna8185( 1282 struct net_device *dev, 1283 u8 u1bAntennaIndex 1284 ) 1285{ 1286 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); 1287 bool bAntennaSwitched = false; 1288 1289// printk("+SetAntenna8185(): Antenna is switching to: %d \n", u1bAntennaIndex); 1290 1291 switch(u1bAntennaIndex) 1292 { 1293 case 0: 1294 /* Mac register, main antenna */ 1295 write_nic_byte(dev, ANTSEL, 0x03); 1296 /* base band */ 1297 write_phy_cck(dev, 0x11, 0x9b); /* Config CCK RX antenna. */ 1298 write_phy_ofdm(dev, 0x0d, 0x5c); /* Config OFDM RX antenna. */ 1299 1300 bAntennaSwitched = true; 1301 break; 1302 1303 case 1: 1304 /* Mac register, aux antenna */ 1305 write_nic_byte(dev, ANTSEL, 0x00); 1306 /* base band */ 1307 write_phy_cck(dev, 0x11, 0xbb); /* Config CCK RX antenna. */ 1308 write_phy_ofdm(dev, 0x0d, 0x54); /* Config OFDM RX antenna. */ 1309 1310 bAntennaSwitched = true; 1311 1312 break; 1313 1314 default: 1315 printk("SetAntenna8185: unknown u1bAntennaIndex(%d)\n", u1bAntennaIndex); 1316 break; 1317 } 1318 1319 if(bAntennaSwitched) 1320 { 1321 priv->CurrAntennaIndex = u1bAntennaIndex; 1322 } 1323 1324// printk("-SetAntenna8185(): return (%#X)\n", bAntennaSwitched); 1325 1326 return bAntennaSwitched; 1327} 1328// 1329// Description: 1330// Toggle Antenna switch. 1331// 1332bool 1333SwitchAntenna( 1334 struct net_device *dev 1335 ) 1336{ 1337 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); 1338 1339 bool bResult; 1340 1341 if(priv->CurrAntennaIndex == 0) 1342 { 1343 bResult = SetAntenna8185(dev, 1); 1344//by amy 080312 1345// printk("SwitchAntenna(): switching to antenna 1 ......\n"); 1346// bResult = SetAntenna8185(dev, 1);//-by amy 080312 1347 } 1348 else 1349 { 1350 bResult = SetAntenna8185(dev, 0); 1351//by amy 080312 1352// printk("SwitchAntenna(): switching to antenna 0 ......\n"); 1353// bResult = SetAntenna8185(dev, 0);//-by amy 080312 1354 } 1355 1356 return bResult; 1357} 1358// 1359// Description: 1360// Engine of SW Antenna Diversity mechanism. 1361// Since 8187 has no Tx part information, 1362// this implementation is only dependend on Rx part information. 1363// 1364// 2006.04.17, by rcnjko. 1365// 1366void 1367SwAntennaDiversity( 1368 struct net_device *dev 1369 ) 1370{ 1371 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); 1372 bool bSwCheckSS=false; 1373// printk("+SwAntennaDiversity(): CurrAntennaIndex: %d\n", priv->CurrAntennaIndex); 1374// printk("AdTickCount is %d\n",priv->AdTickCount); 1375//by amy 080312 1376 if(bSwCheckSS) 1377 { 1378 priv->AdTickCount++; 1379 1380 printk("(1) AdTickCount: %d, AdCheckPeriod: %d\n", 1381 priv->AdTickCount, priv->AdCheckPeriod); 1382 printk("(2) AdRxSignalStrength: %ld, AdRxSsThreshold: %ld\n", 1383 priv->AdRxSignalStrength, priv->AdRxSsThreshold); 1384 } 1385// priv->AdTickCount++;//-by amy 080312 1386 1387 // Case 1. No Link. 1388 if(priv->ieee80211->state != IEEE80211_LINKED) 1389 { 1390 // printk("SwAntennaDiversity(): Case 1. No Link.\n"); 1391 1392 priv->bAdSwitchedChecking = false; 1393 // I switch antenna here to prevent any one of antenna is broken before link established, 2006.04.18, by rcnjko.. 1394 SwitchAntenna(dev); 1395 } 1396 // Case 2. Linked but no packet received. 1397 else if(priv->AdRxOkCnt == 0) 1398 { 1399 // printk("SwAntennaDiversity(): Case 2. Linked but no packet received.\n"); 1400 1401 priv->bAdSwitchedChecking = false; 1402 SwitchAntenna(dev); 1403 } 1404 // Case 3. Evaluate last antenna switch action and undo it if necessary. 1405 else if(priv->bAdSwitchedChecking == true) 1406 { 1407 // printk("SwAntennaDiversity(): Case 3. Evaluate last antenna switch action.\n"); 1408 1409 priv->bAdSwitchedChecking = false; 1410 1411 // Adjust Rx signal strength threshold. 1412 priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2; 1413 1414 priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ? 1415 priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold; 1416 if(priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched) 1417 { // Rx signal strength is not improved after we swtiched antenna. => Swich back. 1418// printk("SwAntennaDiversity(): Rx Signal Strength is not improved, CurrRxSs: %d, LastRxSs: %d\n", 1419// priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched); 1420//by amy 080312 1421 // Increase Antenna Diversity checking period due to bad decision. 1422 priv->AdCheckPeriod *= 2; 1423//by amy 080312 1424 // Increase Antenna Diversity checking period. 1425 if(priv->AdCheckPeriod > priv->AdMaxCheckPeriod) 1426 priv->AdCheckPeriod = priv->AdMaxCheckPeriod; 1427 1428 // Wrong deceision => switch back. 1429 SwitchAntenna(dev); 1430 } 1431 else 1432 { // Rx Signal Strength is improved. 1433// printk("SwAntennaDiversity(): Rx Signal Strength is improved, CurrRxSs: %d, LastRxSs: %d\n", 1434// priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched); 1435 1436 // Reset Antenna Diversity checking period to its min value. 1437 priv->AdCheckPeriod = priv->AdMinCheckPeriod; 1438 } 1439 1440// printk("SwAntennaDiversity(): AdRxSsThreshold: %d, AdCheckPeriod: %d\n", 1441// priv->AdRxSsThreshold, priv->AdCheckPeriod); 1442 } 1443 // Case 4. Evaluate if we shall switch antenna now. 1444 // Cause Table Speed is very fast in TRC Dell Lab, we check it every time. 1445 else// if(priv->AdTickCount >= priv->AdCheckPeriod)//-by amy 080312 1446 { 1447// printk("SwAntennaDiversity(): Case 4. Evaluate if we shall switch antenna now.\n"); 1448 1449 priv->AdTickCount = 0; 1450 1451 // 1452 // <Roger_Notes> We evaluate RxOk counts for each antenna first and than 1453 // evaluate signal strength. 1454 // The following operation can overcome the disability of CCA on both two antennas 1455 // When signal strength was extremely low or high. 1456 // 2008.01.30. 1457 // 1458 1459 // 1460 // Evaluate RxOk count from each antenna if we shall switch default antenna now. 1461 // Added by Roger, 2008.02.21. 1462//{by amy 080312 1463 if((priv->AdMainAntennaRxOkCnt < priv->AdAuxAntennaRxOkCnt) 1464 && (priv->CurrAntennaIndex == 0)) 1465 { // We set Main antenna as default but RxOk count was less than Aux ones. 1466 1467 // printk("SwAntennaDiversity(): Main antenna RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n", 1468 // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt); 1469 1470 // Switch to Aux antenna. 1471 SwitchAntenna(dev); 1472 priv->bHWAdSwitched = true; 1473 } 1474 else if((priv->AdAuxAntennaRxOkCnt < priv->AdMainAntennaRxOkCnt) 1475 && (priv->CurrAntennaIndex == 1)) 1476 { // We set Aux antenna as default but RxOk count was less than Main ones. 1477 1478 // printk("SwAntennaDiversity(): Aux antenna RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n", 1479 // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt); 1480 1481 // Switch to Main antenna. 1482 SwitchAntenna(dev); 1483 priv->bHWAdSwitched = true; 1484 } 1485 else 1486 {// Default antenna is better. 1487 1488 // printk("SwAntennaDiversity(): Default antenna is better., AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n", 1489 // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt); 1490 1491 // Still need to check current signal strength. 1492 priv->bHWAdSwitched = false; 1493 } 1494 // 1495 // <Roger_Notes> We evaluate Rx signal strength ONLY when default antenna 1496 // didn't changed by HW evaluation. 1497 // 2008.02.27. 1498 // 1499 // [TRC Dell Lab] SignalStrength is inaccuracy. Isaiah 2008-03-05 1500 // For example, Throughput of aux is better than main antenna(about 10M v.s 2M), 1501 // but AdRxSignalStrength is less than main. 1502 // Our guess is that main antenna have lower throughput and get many change 1503 // to receive more CCK packets(ex.Beacon) which have stronger SignalStrength. 1504 // 1505 if( (!priv->bHWAdSwitched) && (bSwCheckSS)) 1506 { 1507//by amy 080312} 1508 // Evaluate Rx signal strength if we shall switch antenna now. 1509 if(priv->AdRxSignalStrength < priv->AdRxSsThreshold) 1510 { // Rx signal strength is weak => Switch Antenna. 1511// printk("SwAntennaDiversity(): Rx Signal Strength is weak, CurrRxSs: %d, RxSsThreshold: %d\n", 1512// priv->AdRxSignalStrength, priv->AdRxSsThreshold); 1513 1514 priv->AdRxSsBeforeSwitched = priv->AdRxSignalStrength; 1515 priv->bAdSwitchedChecking = true; 1516 1517 SwitchAntenna(dev); 1518 } 1519 else 1520 { // Rx signal strength is OK. 1521// printk("SwAntennaDiversity(): Rx Signal Strength is OK, CurrRxSs: %d, RxSsThreshold: %d\n", 1522// priv->AdRxSignalStrength, priv->AdRxSsThreshold); 1523 1524 priv->bAdSwitchedChecking = false; 1525 // Increase Rx signal strength threshold if necessary. 1526 if( (priv->AdRxSignalStrength > (priv->AdRxSsThreshold + 10)) && // Signal is much stronger than current threshold 1527 priv->AdRxSsThreshold <= priv->AdMaxRxSsThreshold) // Current threhold is not yet reach upper limit. 1528 { 1529 priv->AdRxSsThreshold = (priv->AdRxSsThreshold + priv->AdRxSignalStrength) / 2; 1530 priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ? 1531 priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;//+by amy 080312 1532 } 1533 1534 // Reduce Antenna Diversity checking period if possible. 1535 if( priv->AdCheckPeriod > priv->AdMinCheckPeriod ) 1536 { 1537 priv->AdCheckPeriod /= 2; 1538 } 1539 } 1540 } 1541 } 1542//by amy 080312 1543 // Reset antenna diversity Rx related statistics. 1544 priv->AdRxOkCnt = 0; 1545 priv->AdMainAntennaRxOkCnt = 0; 1546 priv->AdAuxAntennaRxOkCnt = 0; 1547//by amy 080312 1548 1549// priv->AdRxOkCnt = 0;//-by amy 080312 1550 1551// printk("-SwAntennaDiversity()\n"); 1552} 1553 1554// 1555// Description: 1556// Return TRUE if we shall perform Tx Power Tracking Mecahnism, FALSE otherwise. 1557// 1558bool 1559CheckTxPwrTracking( struct net_device *dev) 1560{ 1561 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); 1562 1563 if(!priv->bTxPowerTrack) 1564 { 1565 return false; 1566 } 1567 1568//lzm reserved 080826 1569 //if(priv->bScanInProgress) 1570 //{ 1571 // return false; 1572 //} 1573 1574 //if 87SE is in High Power , don't do Tx Power Tracking. asked by SD3 ED. 2008-08-08 Isaiah 1575 if(priv->bToUpdateTxPwr) 1576 { 1577 return false; 1578 } 1579 1580 return true; 1581} 1582 1583 1584// 1585// Description: 1586// Timer callback function of SW Antenna Diversity. 1587// 1588void 1589SwAntennaDiversityTimerCallback( 1590 struct net_device *dev 1591 ) 1592{ 1593 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); 1594 RT_RF_POWER_STATE rtState; 1595 1596 //printk("+SwAntennaDiversityTimerCallback()\n"); 1597 1598 // 1599 // We do NOT need to switch antenna while RF is off. 1600 // 2007.05.09, added by Roger. 1601 // 1602 rtState = priv->eRFPowerState; 1603 do{ 1604 if (rtState == eRfOff) 1605 { 1606// printk("SwAntennaDiversityTimer - RF is OFF.\n"); 1607 break; 1608 } 1609 else if (rtState == eRfSleep) 1610 { 1611 // Don't access BB/RF under Disable PLL situation. 1612 //RT_TRACE((COMP_RF|COMP_ANTENNA), DBG_LOUD, ("SwAntennaDiversityTimerCallback(): RF is Sleep => skip it\n")); 1613 break; 1614 } 1615 SwAntennaDiversity(dev); 1616 1617 }while(false); 1618 1619 if(priv->up) 1620 { 1621 priv->SwAntennaDiversityTimer.expires = jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD); 1622 add_timer(&priv->SwAntennaDiversityTimer); 1623 } 1624 1625 //printk("-SwAntennaDiversityTimerCallback()\n"); 1626} 1627