omap: i2c: add a timeout to the busy waiting
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / rtl8187se / r8180_dm.c
blobfc4907839c58956f78dfebb300c6859c2d0a6a78
1 //#include "r8180.h"
2 #include "r8180_dm.h"
3 #include "r8180_hw.h"
4 #include "r8180_93cx6.h"
5 //{by amy 080312
7 //
8 // Description:
9 // Return TRUE if we shall perform High Power Mecahnism, FALSE otherwise.
11 //+by amy 080312
12 #define RATE_ADAPTIVE_TIMER_PERIOD 300
14 bool CheckHighPower(struct net_device *dev)
16 struct r8180_priv *priv = ieee80211_priv(dev);
17 struct ieee80211_device *ieee = priv->ieee80211;
19 if(!priv->bRegHighPowerMechanism)
21 return false;
24 if(ieee->state == IEEE80211_LINKED_SCANNING)
26 return false;
29 return true;
33 // Description:
34 // Update Tx power level if necessary.
35 // See also DoRxHighPower() and SetTxPowerLevel8185() for reference.
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.
43 void
44 DoTxHighPower(
45 struct net_device *dev
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;
56 //printk("----> DoTxHighPower()\n");
58 HiPwrUpperTh = priv->RegHiPwrUpperTh;
59 HiPwrLowerTh = priv->RegHiPwrLowerTh;
61 HiPwrUpperTh = HiPwrUpperTh * 10;
62 HiPwrLowerTh = HiPwrLowerTh * 10;
63 RSSIHiPwrUpperTh = priv->RegRSSIHiPwrUpperTh;
64 RSSIHiPwrLowerTh = priv->RegRSSIHiPwrLowerTh;
66 //lzm add 080826
67 OfdmTxPwrIdx = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel];
68 CckTxPwrIdx = priv->chtxpwr[priv->ieee80211->current_network.channel];
70 // printk("DoTxHighPower() - UndecoratedSmoothedSS:%d, CurCCKRSSI = %d , bCurCCKPkt= %d \n", priv->UndecoratedSmoothedSS, priv->CurCCKRSSI, priv->bCurCCKPkt );
72 if((priv->UndecoratedSmoothedSS > HiPwrUpperTh) ||
73 (priv->bCurCCKPkt && (priv->CurCCKRSSI > RSSIHiPwrUpperTh)))
75 // Stevenl suggested that degrade 8dbm in high power sate. 2007-12-04 Isaiah
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);
81 // If it never enter High Power.
82 if( CckTxPwrIdx == u1bTmp)
84 u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0; // 8dbm
85 write_nic_byte(dev, CCK_TXAGC, u1bTmp);
87 u1bTmp= read_nic_byte(dev, OFDM_TXAGC);
88 u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0; // 8dbm
89 write_nic_byte(dev, OFDM_TXAGC, u1bTmp);
93 else if((priv->UndecoratedSmoothedSS < HiPwrLowerTh) &&
94 (!priv->bCurCCKPkt || priv->CurCCKRSSI < RSSIHiPwrLowerTh))
96 // printk("DoTxHighPower() - lower Power - UndecoratedSmoothedSS:%d, HiPwrUpperTh = %d \n", priv->UndecoratedSmoothedSS, HiPwrLowerTh );
97 if(priv->bToUpdateTxPwr)
99 priv->bToUpdateTxPwr = false;
100 //SD3 required.
101 u1bTmp= read_nic_byte(dev, CCK_TXAGC);
102 if(u1bTmp < CckTxPwrIdx)
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);
109 u1bTmp= read_nic_byte(dev, OFDM_TXAGC);
110 if(u1bTmp < OfdmTxPwrIdx)
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);
119 //printk("<---- DoTxHighPower()\n");
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.
129 void rtl8180_tx_pw_wq (struct work_struct *work)
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;
138 // printk("----> UpdateTxPowerWorkItemCallback()\n");
140 DoTxHighPower(dev);
142 // printk("<---- UpdateTxPowerWorkItemCallback()\n");
147 // Description:
148 // Return TRUE if we shall perform DIG Mecahnism, FALSE otherwise.
150 bool
151 CheckDig(
152 struct net_device *dev
155 struct r8180_priv *priv = ieee80211_priv(dev);
156 struct ieee80211_device *ieee = priv->ieee80211;
158 if(!priv->bDigMechanism)
159 return false;
161 if(ieee->state != IEEE80211_LINKED)
162 return false;
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;
170 // Description:
171 // Implementation of DIG for Zebra and Zebra2.
173 void
174 DIG_Zebra(
175 struct net_device *dev
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;
185 //printk("---------> DIG_Zebra()\n");
187 CCKFalseAlarm = (u16)(priv->FalseAlarmRegValue & 0x0000ffff);
188 OFDMFalseAlarm = (u16)((priv->FalseAlarmRegValue >> 16) & 0x0000ffff);
189 OfdmFA1 = 0x15;
190 OfdmFA2 = ((u16)(priv->RegDigOfdmFaUpTh)) << 8;
192 // printk("DIG**********CCK False Alarm: %#X \n",CCKFalseAlarm);
193 // printk("DIG**********OFDM False Alarm: %#X \n",OFDMFalseAlarm);
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)
200 { // Advised from SD3 DZ
201 OfdmFA1 = 0x20;
204 #if 1 //lzm reserved 080826
205 AwakePeriodIn2Sec = (2000-priv ->DozePeriodInPast2Sec);
206 //printk("&&& DozePeriod=%d AwakePeriod=%d\n", priv->DozePeriodInPast2Sec, AwakePeriodIn2Sec);
207 priv ->DozePeriodInPast2Sec=0;
209 if(AwakePeriodIn2Sec)
211 //RT_TRACE(COMP_DIG, DBG_TRACE, ("DIG: AwakePeriodIn2Sec(%d) - FATh(0x%X , 0x%X) ->",AwakePeriodIn2Sec, OfdmFA1, OfdmFA2));
212 // adjuest DIG threshold.
213 OfdmFA1 = (u16)((OfdmFA1*AwakePeriodIn2Sec) / 2000) ;
214 OfdmFA2 = (u16)((OfdmFA2*AwakePeriodIn2Sec) / 2000) ;
215 //RT_TRACE(COMP_DIG, DBG_TRACE, ("( 0x%X , 0x%X)\n", OfdmFA1, OfdmFA2));
217 else
219 ;//RT_TRACE(COMP_DIG, DBG_WARNING, ("ERROR!! AwakePeriodIn2Sec should not be ZERO!!\n"));
221 #endif
223 InitialGainStep = 8;
224 LowestGainStage = priv->RegBModeGainStage; // Lowest gain stage.
226 if (OFDMFalseAlarm > OfdmFA1)
228 if (OFDMFalseAlarm > OfdmFA2)
230 priv->DIG_NumberFallbackVote++;
231 if (priv->DIG_NumberFallbackVote >1)
233 //serious OFDM False Alarm, need fallback
234 if (priv->InitialGain < InitialGainStep)
236 priv->InitialGainBackUp= priv->InitialGain;
238 priv->InitialGain = (priv->InitialGain + 1);
239 // printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);
240 // printk("DIG+++++++ fallback OFDM:%d \n", priv->InitialGain);
241 UpdateInitialGain(dev);
243 priv->DIG_NumberFallbackVote = 0;
244 priv->DIG_NumberUpgradeVote=0;
247 else
249 if (priv->DIG_NumberFallbackVote)
250 priv->DIG_NumberFallbackVote--;
252 priv->DIG_NumberUpgradeVote=0;
254 else
256 if (priv->DIG_NumberFallbackVote)
257 priv->DIG_NumberFallbackVote--;
258 priv->DIG_NumberUpgradeVote++;
260 if (priv->DIG_NumberUpgradeVote>9)
262 if (priv->InitialGain > LowestGainStage) // In 87B, m78dBm means State 4 (m864dBm)
264 priv->InitialGainBackUp= priv->InitialGain;
266 priv->InitialGain = (priv->InitialGain - 1);
267 // printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);
268 // printk("DIG--------- Upgrade OFDM:%d \n", priv->InitialGain);
269 UpdateInitialGain(dev);
271 priv->DIG_NumberFallbackVote = 0;
272 priv->DIG_NumberUpgradeVote=0;
276 // printk("DIG+++++++ OFDM:%d\n", priv->InitialGain);
277 //printk("<--------- DIG_Zebra()\n");
281 // Description:
282 // Dispatch DIG implementation according to RF.
284 void
285 DynamicInitGain(struct net_device *dev)
287 DIG_Zebra(dev);
290 void rtl8180_hw_dig_wq (struct work_struct *work)
292 struct delayed_work *dwork = to_delayed_work(work);
293 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_dig_wq);
294 struct net_device *dev = ieee->dev;
295 struct r8180_priv *priv = ieee80211_priv(dev);
297 // Read CCK and OFDM False Alarm.
298 priv->FalseAlarmRegValue = read_nic_dword(dev, CCK_FALSE_ALARM);
301 // Adjust Initial Gain dynamically.
302 DynamicInitGain(dev);
307 IncludedInSupportedRates(
308 struct r8180_priv *priv,
309 u8 TxRate )
311 u8 rate_len;
312 u8 rate_ex_len;
313 u8 RateMask = 0x7F;
314 u8 idx;
315 unsigned short Found = 0;
316 u8 NaiveTxRate = TxRate&RateMask;
318 rate_len = priv->ieee80211->current_network.rates_len;
319 rate_ex_len = priv->ieee80211->current_network.rates_ex_len;
320 for( idx=0; idx< rate_len; idx++ )
322 if( (priv->ieee80211->current_network.rates[idx] & RateMask) == NaiveTxRate )
324 Found = 1;
325 goto found_rate;
328 for( idx=0; idx< rate_ex_len; idx++ )
330 if( (priv->ieee80211->current_network.rates_ex[idx] & RateMask) == NaiveTxRate )
332 Found = 1;
333 goto found_rate;
336 return Found;
337 found_rate:
338 return Found;
342 // Description:
343 // Get the Tx rate one degree up form the input rate in the supported rates.
344 // Return the upgrade rate if it is successed, otherwise return the input rate.
345 // By Bruce, 2007-06-05.
348 GetUpgradeTxRate(
349 struct net_device *dev,
350 u8 rate
353 struct r8180_priv *priv = ieee80211_priv(dev);
354 u8 UpRate;
356 // Upgrade 1 degree.
357 switch(rate)
359 case 108: // Up to 54Mbps.
360 UpRate = 108;
361 break;
363 case 96: // Up to 54Mbps.
364 UpRate = 108;
365 break;
367 case 72: // Up to 48Mbps.
368 UpRate = 96;
369 break;
371 case 48: // Up to 36Mbps.
372 UpRate = 72;
373 break;
375 case 36: // Up to 24Mbps.
376 UpRate = 48;
377 break;
379 case 22: // Up to 18Mbps.
380 UpRate = 36;
381 break;
383 case 11: // Up to 11Mbps.
384 UpRate = 22;
385 break;
387 case 4: // Up to 5.5Mbps.
388 UpRate = 11;
389 break;
391 case 2: // Up to 2Mbps.
392 UpRate = 4;
393 break;
395 default:
396 printk("GetUpgradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
397 return rate;
399 // Check if the rate is valid.
400 if(IncludedInSupportedRates(priv, UpRate))
402 // printk("GetUpgradeTxRate(): GetUpgrade Tx rate(%d) from %d !\n", UpRate, priv->CurrentOperaRate);
403 return UpRate;
405 else
407 //printk("GetUpgradeTxRate(): Tx rate (%d) is not in supported rates\n", UpRate);
408 return rate;
410 return rate;
413 // Description:
414 // Get the Tx rate one degree down form the input rate in the supported rates.
415 // Return the degrade rate if it is successed, otherwise return the input rate.
416 // By Bruce, 2007-06-05.
419 GetDegradeTxRate(
420 struct net_device *dev,
421 u8 rate
424 struct r8180_priv *priv = ieee80211_priv(dev);
425 u8 DownRate;
427 // Upgrade 1 degree.
428 switch(rate)
430 case 108: // Down to 48Mbps.
431 DownRate = 96;
432 break;
434 case 96: // Down to 36Mbps.
435 DownRate = 72;
436 break;
438 case 72: // Down to 24Mbps.
439 DownRate = 48;
440 break;
442 case 48: // Down to 18Mbps.
443 DownRate = 36;
444 break;
446 case 36: // Down to 11Mbps.
447 DownRate = 22;
448 break;
450 case 22: // Down to 5.5Mbps.
451 DownRate = 11;
452 break;
454 case 11: // Down to 2Mbps.
455 DownRate = 4;
456 break;
458 case 4: // Down to 1Mbps.
459 DownRate = 2;
460 break;
462 case 2: // Down to 1Mbps.
463 DownRate = 2;
464 break;
466 default:
467 printk("GetDegradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
468 return rate;
470 // Check if the rate is valid.
471 if(IncludedInSupportedRates(priv, DownRate))
473 // printk("GetDegradeTxRate(): GetDegrade Tx rate(%d) from %d!\n", DownRate, priv->CurrentOperaRate);
474 return DownRate;
476 else
478 //printk("GetDegradeTxRate(): Tx rate (%d) is not in supported rates\n", DownRate);
479 return rate;
481 return rate;
484 // Helper function to determine if specified data rate is
485 // CCK rate.
486 // 2005.01.25, by rcnjko.
488 bool
489 MgntIsCckRate(
490 u16 rate
493 bool bReturn = false;
495 if((rate <= 22) && (rate != 12) && (rate != 18))
497 bReturn = true;
500 return bReturn;
503 // Description:
504 // Tx Power tracking mechanism routine on 87SE.
505 // Created by Roger, 2007.12.11.
507 void
508 TxPwrTracking87SE(
509 struct net_device *dev
512 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
513 u8 tmpu1Byte, CurrentThermal, Idx;
514 char CckTxPwrIdx, OfdmTxPwrIdx;
515 //u32 u4bRfReg;
517 tmpu1Byte = read_nic_byte(dev, EN_LPF_CAL);
518 CurrentThermal = (tmpu1Byte & 0xf0)>>4; //[ 7:4]: thermal meter indication.
519 CurrentThermal = (CurrentThermal>0x0c)? 0x0c:CurrentThermal;//lzm add 080826
521 //printk("TxPwrTracking87SE(): CurrentThermal(%d)\n", CurrentThermal);
523 if( CurrentThermal != priv->ThermalMeter)
525 // printk("TxPwrTracking87SE(): Thermal meter changed!!!\n");
527 // Update Tx Power level on each channel.
528 for(Idx = 1; Idx<15; Idx++)
530 CckTxPwrIdx = priv->chtxpwr[Idx];
531 OfdmTxPwrIdx = priv->chtxpwr_ofdm[Idx];
533 if( CurrentThermal > priv->ThermalMeter )
534 { // higher thermal meter.
535 CckTxPwrIdx += (CurrentThermal - priv->ThermalMeter)*2;
536 OfdmTxPwrIdx += (CurrentThermal - priv->ThermalMeter)*2;
538 if(CckTxPwrIdx >35)
539 CckTxPwrIdx = 35; // Force TxPower to maximal index.
540 if(OfdmTxPwrIdx >35)
541 OfdmTxPwrIdx = 35;
543 else
544 { // lower thermal meter.
545 CckTxPwrIdx -= (priv->ThermalMeter - CurrentThermal)*2;
546 OfdmTxPwrIdx -= (priv->ThermalMeter - CurrentThermal)*2;
548 if(CckTxPwrIdx <0)
549 CckTxPwrIdx = 0;
550 if(OfdmTxPwrIdx <0)
551 OfdmTxPwrIdx = 0;
554 // Update TxPower level on CCK and OFDM resp.
555 priv->chtxpwr[Idx] = CckTxPwrIdx;
556 priv->chtxpwr_ofdm[Idx] = OfdmTxPwrIdx;
559 // Update TxPower level immediately.
560 rtl8225z2_SetTXPowerLevel(dev, priv->ieee80211->current_network.channel);
562 priv->ThermalMeter = CurrentThermal;
564 void
565 StaRateAdaptive87SE(
566 struct net_device *dev
569 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
570 unsigned long CurrTxokCnt;
571 u16 CurrRetryCnt;
572 u16 CurrRetryRate;
573 //u16 i,idx;
574 unsigned long CurrRxokCnt;
575 bool bTryUp = false;
576 bool bTryDown = false;
577 u8 TryUpTh = 1;
578 u8 TryDownTh = 2;
579 u32 TxThroughput;
580 long CurrSignalStrength;
581 bool bUpdateInitialGain = false;
582 u8 u1bOfdm=0, u1bCck = 0;
583 char OfdmTxPwrIdx, CckTxPwrIdx;
585 priv->RateAdaptivePeriod= RATE_ADAPTIVE_TIMER_PERIOD;
588 CurrRetryCnt = priv->CurrRetryCnt;
589 CurrTxokCnt = priv->NumTxOkTotal - priv->LastTxokCnt;
590 CurrRxokCnt = priv->ieee80211->NumRxOkTotal - priv->LastRxokCnt;
591 CurrSignalStrength = priv->Stats_RecvSignalPower;
592 TxThroughput = (u32)(priv->NumTxOkBytesTotal - priv->LastTxOKBytes);
593 priv->LastTxOKBytes = priv->NumTxOkBytesTotal;
594 priv->CurrentOperaRate = priv->ieee80211->rate/5;
595 //printk("priv->CurrentOperaRate is %d\n",priv->CurrentOperaRate);
596 //2 Compute retry ratio.
597 if (CurrTxokCnt>0)
599 CurrRetryRate = (u16)(CurrRetryCnt*100/CurrTxokCnt);
601 else
602 { // It may be serious retry. To distinguish serious retry or no packets modified by Bruce
603 CurrRetryRate = (u16)(CurrRetryCnt*100/1);
608 // Added by Roger, 2007.01.02.
609 // For debug information.
611 //printk("\n(1) pHalData->LastRetryRate: %d \n",priv->LastRetryRate);
612 //printk("(2) RetryCnt = %d \n", CurrRetryCnt);
613 //printk("(3) TxokCnt = %d \n", CurrTxokCnt);
614 //printk("(4) CurrRetryRate = %d \n", CurrRetryRate);
615 //printk("(5) CurrSignalStrength = %d \n",CurrSignalStrength);
616 //printk("(6) TxThroughput is %d\n",TxThroughput);
617 //printk("priv->NumTxOkBytesTotal is %d\n",priv->NumTxOkBytesTotal);
619 priv->LastRetryCnt = priv->CurrRetryCnt;
620 priv->LastTxokCnt = priv->NumTxOkTotal;
621 priv->LastRxokCnt = priv->ieee80211->NumRxOkTotal;
622 priv->CurrRetryCnt = 0;
624 //2No Tx packets, return to init_rate or not?
625 if (CurrRetryRate==0 && CurrTxokCnt == 0)
628 //After 9 (30*300ms) seconds in this condition, we try to raise rate.
630 priv->TryupingCountNoData++;
632 // printk("No Tx packets, TryupingCountNoData(%d)\n", priv->TryupingCountNoData);
633 //[TRC Dell Lab] Extend raised period from 4.5sec to 9sec, Isaiah 2008-02-15 18:00
634 if (priv->TryupingCountNoData>30)
636 priv->TryupingCountNoData = 0;
637 priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
638 // Reset Fail Record
639 priv->LastFailTxRate = 0;
640 priv->LastFailTxRateSS = -200;
641 priv->FailTxRateCount = 0;
643 goto SetInitialGain;
645 else
647 priv->TryupingCountNoData=0; //Reset trying up times.
652 // For Netgear case, I comment out the following signal strength estimation,
653 // which can results in lower rate to transmit when sample is NOT enough (e.g. PING request).
654 // 2007.04.09, by Roger.
658 // Restructure rate adaptive as the following main stages:
659 // (1) Add retry threshold in 54M upgrading condition with signal strength.
660 // (2) Add the mechanism to degrade to CCK rate according to signal strength
661 // and retry rate.
662 // (3) Remove all Initial Gain Updates over OFDM rate. To avoid the complicated
663 // situation, Initial Gain Update is upon on DIG mechanism except CCK rate.
664 // (4) Add the mehanism of trying to upgrade tx rate.
665 // (5) Record the information of upping tx rate to avoid trying upping tx rate constantly.
666 // By Bruce, 2007-06-05.
670 // 11Mbps or 36Mbps
671 // Check more times in these rate(key rates).
673 if(priv->CurrentOperaRate == 22 || priv->CurrentOperaRate == 72)
675 TryUpTh += 9;
678 // Let these rates down more difficult.
680 if(MgntIsCckRate(priv->CurrentOperaRate) || priv->CurrentOperaRate == 36)
682 TryDownTh += 1;
685 //1 Adjust Rate.
686 if (priv->bTryuping == true)
688 //2 For Test Upgrading mechanism
689 // Note:
690 // Sometimes the throughput is upon on the capability bwtween the AP and NIC,
691 // thus the low data rate does not improve the performance.
692 // We randomly upgrade the data rate and check if the retry rate is improved.
694 // Upgrading rate did not improve the retry rate, fallback to the original rate.
695 if ( (CurrRetryRate > 25) && TxThroughput < priv->LastTxThroughput)
697 //Not necessary raising rate, fall back rate.
698 bTryDown = true;
699 //printk("case1-1: Not necessary raising rate, fall back rate....\n");
700 //printk("case1-1: pMgntInfo->CurrentOperaRate =%d, TxThroughput = %d, LastThroughput = %d\n",
701 // priv->CurrentOperaRate, TxThroughput, priv->LastTxThroughput);
703 else
705 priv->bTryuping = false;
708 else if (CurrSignalStrength > -47 && (CurrRetryRate < 50))
710 //2For High Power
712 // Added by Roger, 2007.04.09.
713 // Return to highest data rate, if signal strength is good enough.
714 // SignalStrength threshold(-50dbm) is for RTL8186.
715 // Revise SignalStrength threshold to -51dbm.
717 // Also need to check retry rate for safety, by Bruce, 2007-06-05.
718 if(priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate )
720 bTryUp = true;
721 // Upgrade Tx Rate directly.
722 priv->TryupingCount += TryUpTh;
724 // printk("case2: StaRateAdaptive87SE: Power(%d) is high enough!!. \n", CurrSignalStrength);
727 else if(CurrTxokCnt > 9 && CurrTxokCnt< 100 && CurrRetryRate >= 600)
729 //2 For Serious Retry
731 // Traffic is not busy but our Tx retry is serious.
733 bTryDown = true;
734 // Let Rate Mechanism to degrade tx rate directly.
735 priv->TryDownCountLowData += TryDownTh;
736 // printk("case3: RA: Tx Retry is serious. Degrade Tx Rate to %d directly...\n", priv->CurrentOperaRate);
738 else if ( priv->CurrentOperaRate == 108 )
740 //2For 54Mbps
741 // Air Link
742 if ( (CurrRetryRate>26)&&(priv->LastRetryRate>25))
743 // if ( (CurrRetryRate>40)&&(priv->LastRetryRate>39))
745 //Down to rate 48Mbps.
746 bTryDown = true;
748 // Cable Link
749 else if ( (CurrRetryRate>17)&&(priv->LastRetryRate>16) && (CurrSignalStrength > -72))
750 // else if ( (CurrRetryRate>17)&&(priv->LastRetryRate>16) && (CurrSignalStrength > -72))
752 //Down to rate 48Mbps.
753 bTryDown = true;
756 if(bTryDown && (CurrSignalStrength < -75)) //cable link
758 priv->TryDownCountLowData += TryDownTh;
760 //printk("case4---54M \n");
763 else if ( priv->CurrentOperaRate == 96 )
765 //2For 48Mbps
766 //Air Link
767 if ( ((CurrRetryRate>48) && (priv->LastRetryRate>47)))
768 // if ( ((CurrRetryRate>65) && (priv->LastRetryRate>64)))
771 //Down to rate 36Mbps.
772 bTryDown = true;
774 //Cable Link
775 else if ( ((CurrRetryRate>21) && (priv->LastRetryRate>20)) && (CurrSignalStrength > -74))
777 //Down to rate 36Mbps.
778 bTryDown = true;
780 else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
781 // else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
783 bTryDown = true;
784 priv->TryDownCountLowData += TryDownTh;
786 else if ( (CurrRetryRate<8) && (priv->LastRetryRate<8) ) //TO DO: need to consider (RSSI)
787 // else if ( (CurrRetryRate<28) && (priv->LastRetryRate<8) )
789 bTryUp = true;
792 if(bTryDown && (CurrSignalStrength < -75))
794 priv->TryDownCountLowData += TryDownTh;
796 //printk("case5---48M \n");
798 else if ( priv->CurrentOperaRate == 72 )
800 //2For 36Mbps
801 if ( (CurrRetryRate>43) && (priv->LastRetryRate>41))
802 // if ( (CurrRetryRate>60) && (priv->LastRetryRate>59))
804 //Down to rate 24Mbps.
805 bTryDown = true;
807 else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
808 // else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
810 bTryDown = true;
811 priv->TryDownCountLowData += TryDownTh;
813 else if ( (CurrRetryRate<15) && (priv->LastRetryRate<16)) //TO DO: need to consider (RSSI)
814 // else if ( (CurrRetryRate<35) && (priv->LastRetryRate<36))
816 bTryUp = true;
819 if(bTryDown && (CurrSignalStrength < -80))
821 priv->TryDownCountLowData += TryDownTh;
823 //printk("case6---36M \n");
825 else if ( priv->CurrentOperaRate == 48 )
827 //2For 24Mbps
828 // Air Link
829 if ( ((CurrRetryRate>63) && (priv->LastRetryRate>62)))
830 // if ( ((CurrRetryRate>83) && (priv->LastRetryRate>82)))
832 //Down to rate 18Mbps.
833 bTryDown = true;
835 //Cable Link
836 else if ( ((CurrRetryRate>33) && (priv->LastRetryRate>32)) && (CurrSignalStrength > -82) )
837 // else if ( ((CurrRetryRate>50) && (priv->LastRetryRate>49)) && (CurrSignalStrength > -82) )
839 //Down to rate 18Mbps.
840 bTryDown = true;
842 else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
843 // else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
846 bTryDown = true;
847 priv->TryDownCountLowData += TryDownTh;
849 else if ( (CurrRetryRate<20) && (priv->LastRetryRate<21)) //TO DO: need to consider (RSSI)
850 // else if ( (CurrRetryRate<40) && (priv->LastRetryRate<41))
852 bTryUp = true;
855 if(bTryDown && (CurrSignalStrength < -82))
857 priv->TryDownCountLowData += TryDownTh;
859 //printk("case7---24M \n");
861 else if ( priv->CurrentOperaRate == 36 )
863 //2For 18Mbps
864 // original (109, 109)
865 //[TRC Dell Lab] (90, 91), Isaiah 2008-02-18 23:24
866 // (85, 86), Isaiah 2008-02-18 24:00
867 if ( ((CurrRetryRate>85) && (priv->LastRetryRate>86)))
868 // if ( ((CurrRetryRate>115) && (priv->LastRetryRate>116)))
870 //Down to rate 11Mbps.
871 bTryDown = true;
873 //[TRC Dell Lab] Isaiah 2008-02-18 23:24
874 else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
875 // else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
877 bTryDown = true;
878 priv->TryDownCountLowData += TryDownTh;
880 else if ( (CurrRetryRate<22) && (priv->LastRetryRate<23)) //TO DO: need to consider (RSSI)
881 // else if ( (CurrRetryRate<42) && (priv->LastRetryRate<43))
883 bTryUp = true;
885 //printk("case8---18M \n");
887 else if ( priv->CurrentOperaRate == 22 )
889 //2For 11Mbps
890 if (CurrRetryRate>95)
891 // if (CurrRetryRate>155)
893 bTryDown = true;
895 else if ( (CurrRetryRate<29) && (priv->LastRetryRate <30) )//TO DO: need to consider (RSSI)
896 // else if ( (CurrRetryRate<49) && (priv->LastRetryRate <50) )
898 bTryUp = true;
900 //printk("case9---11M \n");
902 else if ( priv->CurrentOperaRate == 11 )
904 //2For 5.5Mbps
905 if (CurrRetryRate>149)
906 // if (CurrRetryRate>189)
908 bTryDown = true;
910 else if ( (CurrRetryRate<60) && (priv->LastRetryRate < 65))
911 // else if ( (CurrRetryRate<80) && (priv->LastRetryRate < 85))
914 bTryUp = true;
916 //printk("case10---5.5M \n");
918 else if ( priv->CurrentOperaRate == 4 )
920 //2For 2 Mbps
921 if((CurrRetryRate>99) && (priv->LastRetryRate>99))
922 // if((CurrRetryRate>199) && (priv->LastRetryRate>199))
924 bTryDown = true;
926 else if ( (CurrRetryRate < 65) && (priv->LastRetryRate < 70))
927 // else if ( (CurrRetryRate < 85) && (priv->LastRetryRate < 90))
929 bTryUp = true;
931 //printk("case11---2M \n");
933 else if ( priv->CurrentOperaRate == 2 )
935 //2For 1 Mbps
936 if( (CurrRetryRate<70) && (priv->LastRetryRate<75))
937 // if( (CurrRetryRate<90) && (priv->LastRetryRate<95))
939 bTryUp = true;
941 //printk("case12---1M \n");
944 if(bTryUp && bTryDown)
945 printk("StaRateAdaptive87B(): Tx Rate tried upping and downing simultaneously!\n");
947 //1 Test Upgrading Tx Rate
948 // Sometimes the cause of the low throughput (high retry rate) is the compatibility between the AP and NIC.
949 // To test if the upper rate may cause lower retry rate, this mechanism randomly occurs to test upgrading tx rate.
950 if(!bTryUp && !bTryDown && (priv->TryupingCount == 0) && (priv->TryDownCountLowData == 0)
951 && priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate && priv->FailTxRateCount < 2)
953 if(jiffies% (CurrRetryRate + 101) == 0)
955 bTryUp = true;
956 priv->bTryuping = true;
957 //printk("StaRateAdaptive87SE(): Randomly try upgrading...\n");
961 //1 Rate Mechanism
962 if(bTryUp)
964 priv->TryupingCount++;
965 priv->TryDownCountLowData = 0;
968 // printk("UP: pHalData->TryupingCount = %d\n", priv->TryupingCount);
969 // printk("UP: TryUpTh(%d)+ (FailTxRateCount(%d))^2 =%d\n",
970 // TryUpTh, priv->FailTxRateCount, (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount) );
971 // printk("UP: pHalData->bTryuping=%d\n", priv->bTryuping);
976 // Check more times if we need to upgrade indeed.
977 // Because the largest value of pHalData->TryupingCount is 0xFFFF and
978 // the largest value of pHalData->FailTxRateCount is 0x14,
979 // this condition will be satisfied at most every 2 min.
982 if((priv->TryupingCount > (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount)) ||
983 (CurrSignalStrength > priv->LastFailTxRateSS) || priv->bTryuping)
985 priv->TryupingCount = 0;
987 // When transfering from CCK to OFDM, DIG is an important issue.
989 if(priv->CurrentOperaRate == 22)
990 bUpdateInitialGain = true;
992 // The difference in throughput between 48Mbps and 36Mbps is 8M.
993 // So, we must be carefully in this rate scale. Isaiah 2008-02-15.
995 if( ((priv->CurrentOperaRate == 72) || (priv->CurrentOperaRate == 48) || (priv->CurrentOperaRate == 36)) &&
996 (priv->FailTxRateCount > 2) )
997 priv->RateAdaptivePeriod= (RATE_ADAPTIVE_TIMER_PERIOD/2);
999 // (1)To avoid upgrade frequently to the fail tx rate, add the FailTxRateCount into the threshold.
1000 // (2)If the signal strength is increased, it may be able to upgrade.
1002 priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
1003 // printk("StaRateAdaptive87SE(): Upgrade Tx Rate to %d\n", priv->CurrentOperaRate);
1005 //[TRC Dell Lab] Bypass 12/9/6, Isaiah 2008-02-18 20:00
1006 if(priv->CurrentOperaRate ==36)
1008 priv->bUpdateARFR=true;
1009 write_nic_word(dev, ARFR, 0x0F8F); //bypass 12/9/6
1010 // printk("UP: ARFR=0xF8F\n");
1012 else if(priv->bUpdateARFR)
1014 priv->bUpdateARFR=false;
1015 write_nic_word(dev, ARFR, 0x0FFF); //set 1M ~ 54Mbps.
1016 // printk("UP: ARFR=0xFFF\n");
1019 // Update Fail Tx rate and count.
1020 if(priv->LastFailTxRate != priv->CurrentOperaRate)
1022 priv->LastFailTxRate = priv->CurrentOperaRate;
1023 priv->FailTxRateCount = 0;
1024 priv->LastFailTxRateSS = -200; // Set lowest power.
1028 else
1030 if(priv->TryupingCount > 0)
1031 priv->TryupingCount --;
1034 if(bTryDown)
1036 priv->TryDownCountLowData++;
1037 priv->TryupingCount = 0;
1039 // printk("DN: pHalData->TryDownCountLowData = %d\n",priv->TryDownCountLowData);
1040 // printk("DN: TryDownTh =%d\n", TryDownTh);
1041 // printk("DN: pHalData->bTryuping=%d\n", priv->bTryuping);
1044 //Check if Tx rate can be degraded or Test trying upgrading should fallback.
1045 if(priv->TryDownCountLowData > TryDownTh || priv->bTryuping)
1047 priv->TryDownCountLowData = 0;
1048 priv->bTryuping = false;
1049 // Update fail information.
1050 if(priv->LastFailTxRate == priv->CurrentOperaRate)
1052 priv->FailTxRateCount ++;
1053 // Record the Tx fail rate signal strength.
1054 if(CurrSignalStrength > priv->LastFailTxRateSS)
1056 priv->LastFailTxRateSS = CurrSignalStrength;
1059 else
1061 priv->LastFailTxRate = priv->CurrentOperaRate;
1062 priv->FailTxRateCount = 1;
1063 priv->LastFailTxRateSS = CurrSignalStrength;
1065 priv->CurrentOperaRate = GetDegradeTxRate(dev, priv->CurrentOperaRate);
1067 // Reduce chariot training time at weak signal strength situation. SD3 ED demand.
1068 //[TRC Dell Lab] Revise Signal Threshold from -75 to -80 , Isaiah 2008-02-18 20:00
1069 if( (CurrSignalStrength < -80) && (priv->CurrentOperaRate > 72 ))
1071 priv->CurrentOperaRate = 72;
1072 // printk("DN: weak signal strength (%d), degrade to 36Mbps\n", CurrSignalStrength);
1075 //[TRC Dell Lab] Bypass 12/9/6, Isaiah 2008-02-18 20:00
1076 if(priv->CurrentOperaRate ==36)
1078 priv->bUpdateARFR=true;
1079 write_nic_word(dev, ARFR, 0x0F8F); //bypass 12/9/6
1080 // printk("DN: ARFR=0xF8F\n");
1082 else if(priv->bUpdateARFR)
1084 priv->bUpdateARFR=false;
1085 write_nic_word(dev, ARFR, 0x0FFF); //set 1M ~ 54Mbps.
1086 // printk("DN: ARFR=0xFFF\n");
1090 // When it is CCK rate, it may need to update initial gain to receive lower power packets.
1092 if(MgntIsCckRate(priv->CurrentOperaRate))
1094 bUpdateInitialGain = true;
1096 // printk("StaRateAdaptive87SE(): Degrade Tx Rate to %d\n", priv->CurrentOperaRate);
1099 else
1101 if(priv->TryDownCountLowData > 0)
1102 priv->TryDownCountLowData --;
1105 // Keep the Tx fail rate count to equal to 0x15 at most.
1106 // Reduce the fail count at least to 10 sec if tx rate is tending stable.
1107 if(priv->FailTxRateCount >= 0x15 ||
1108 (!bTryUp && !bTryDown && priv->TryDownCountLowData == 0 && priv->TryupingCount && priv->FailTxRateCount > 0x6))
1110 priv->FailTxRateCount --;
1114 OfdmTxPwrIdx = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel];
1115 CckTxPwrIdx = priv->chtxpwr[priv->ieee80211->current_network.channel];
1117 //[TRC Dell Lab] Mac0x9e increase 2 level in 36M~18M situation, Isaiah 2008-02-18 24:00
1118 if((priv->CurrentOperaRate < 96) &&(priv->CurrentOperaRate > 22))
1120 u1bCck = read_nic_byte(dev, CCK_TXAGC);
1121 u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);
1123 // case 1: Never enter High power
1124 if(u1bCck == CckTxPwrIdx )
1126 if(u1bOfdm != (OfdmTxPwrIdx+2) )
1128 priv->bEnhanceTxPwr= true;
1129 u1bOfdm = ((u1bOfdm+2) > 35) ? 35: (u1bOfdm+2);
1130 write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
1131 // printk("Enhance OFDM_TXAGC : +++++ u1bOfdm= 0x%x\n", u1bOfdm);
1134 // case 2: enter high power
1135 else if(u1bCck < CckTxPwrIdx)
1137 if(!priv->bEnhanceTxPwr)
1139 priv->bEnhanceTxPwr= true;
1140 u1bOfdm = ((u1bOfdm+2) > 35) ? 35: (u1bOfdm+2);
1141 write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
1142 //RT_TRACE(COMP_RATE, DBG_TRACE, ("Enhance OFDM_TXAGC(2) : +++++ u1bOfdm= 0x%x\n", u1bOfdm));
1146 else if(priv->bEnhanceTxPwr) //54/48/11/5.5/2/1
1148 u1bCck = read_nic_byte(dev, CCK_TXAGC);
1149 u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);
1151 // case 1: Never enter High power
1152 if(u1bCck == CckTxPwrIdx )
1154 priv->bEnhanceTxPwr= false;
1155 write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);
1156 //printk("Recover OFDM_TXAGC : ===== u1bOfdm= 0x%x\n", OfdmTxPwrIdx);
1158 // case 2: enter high power
1159 else if(u1bCck < CckTxPwrIdx)
1161 priv->bEnhanceTxPwr= false;
1162 u1bOfdm = ((u1bOfdm-2) > 0) ? (u1bOfdm-2): 0;
1163 write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
1164 //RT_TRACE(COMP_RATE, DBG_TRACE, ("Recover OFDM_TXAGC(2): ===== u1bOfdm= 0x%x\n", u1bOfdm));
1170 // We need update initial gain when we set tx rate "from OFDM to CCK" or
1171 // "from CCK to OFDM".
1173 SetInitialGain:
1174 if(bUpdateInitialGain)
1176 if(MgntIsCckRate(priv->CurrentOperaRate)) // CCK
1178 if(priv->InitialGain > priv->RegBModeGainStage)
1180 priv->InitialGainBackUp= priv->InitialGain;
1182 if(CurrSignalStrength < -85) // Low power, OFDM [0x17] = 26.
1184 //SD3 SYs suggest that CurrSignalStrength < -65, ofdm 0x17=26.
1185 priv->InitialGain = priv->RegBModeGainStage;
1187 else if(priv->InitialGain > priv->RegBModeGainStage + 1)
1189 priv->InitialGain -= 2;
1191 else
1193 priv->InitialGain --;
1195 printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate);
1196 UpdateInitialGain(dev);
1199 else // OFDM
1201 if(priv->InitialGain < 4)
1203 priv->InitialGainBackUp= priv->InitialGain;
1205 priv->InitialGain ++;
1206 printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate);
1207 UpdateInitialGain(dev);
1212 //Record the related info
1213 priv->LastRetryRate = CurrRetryRate;
1214 priv->LastTxThroughput = TxThroughput;
1215 priv->ieee80211->rate = priv->CurrentOperaRate * 5;
1218 void rtl8180_rate_adapter(struct work_struct * work)
1220 struct delayed_work *dwork = to_delayed_work(work);
1221 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,rate_adapter_wq);
1222 struct net_device *dev = ieee->dev;
1223 //struct r8180_priv *priv = ieee80211_priv(dev);
1224 // DMESG("---->rtl8180_rate_adapter");
1225 StaRateAdaptive87SE(dev);
1226 // DMESG("<----rtl8180_rate_adapter");
1228 void timer_rate_adaptive(unsigned long data)
1230 struct r8180_priv* priv = ieee80211_priv((struct net_device *)data);
1231 //DMESG("---->timer_rate_adaptive()\n");
1232 if(!priv->up)
1234 // DMESG("<----timer_rate_adaptive():driver is not up!\n");
1235 return;
1237 if((priv->ieee80211->iw_mode != IW_MODE_MASTER)
1238 && (priv->ieee80211->state == IEEE80211_LINKED) &&
1239 (priv->ForcedDataRate == 0) )
1241 // DMESG("timer_rate_adaptive():schedule rate_adapter_wq\n");
1242 queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->rate_adapter_wq);
1243 // StaRateAdaptive87SE((struct net_device *)data);
1245 priv->rateadapter_timer.expires = jiffies + MSECS(priv->RateAdaptivePeriod);
1246 add_timer(&priv->rateadapter_timer);
1247 //DMESG("<----timer_rate_adaptive()\n");
1249 //by amy 080312}
1250 void
1251 SwAntennaDiversityRxOk8185(
1252 struct net_device *dev,
1253 u8 SignalStrength
1256 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1258 // printk("+SwAntennaDiversityRxOk8185: RxSs: %d\n", SignalStrength);
1260 priv->AdRxOkCnt++;
1262 if( priv->AdRxSignalStrength != -1)
1264 priv->AdRxSignalStrength = ((priv->AdRxSignalStrength*7) + (SignalStrength*3)) / 10;
1266 else
1267 { // Initialization case.
1268 priv->AdRxSignalStrength = SignalStrength;
1270 //{+by amy 080312
1271 if( priv->LastRxPktAntenna ) //Main antenna.
1272 priv->AdMainAntennaRxOkCnt++;
1273 else // Aux antenna.
1274 priv->AdAuxAntennaRxOkCnt++;
1275 //+by amy 080312
1276 // printk("-SwAntennaDiversityRxOk8185: AdRxOkCnt: %d AdRxSignalStrength: %d\n", priv->AdRxOkCnt, priv->AdRxSignalStrength);
1279 // Description:
1280 // Change Antenna Switch.
1282 bool
1283 SetAntenna8185(
1284 struct net_device *dev,
1285 u8 u1bAntennaIndex
1288 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1289 bool bAntennaSwitched = false;
1291 // printk("+SetAntenna8185(): Antenna is switching to: %d \n", u1bAntennaIndex);
1293 switch(u1bAntennaIndex)
1295 case 0:
1296 /* Mac register, main antenna */
1297 write_nic_byte(dev, ANTSEL, 0x03);
1298 /* base band */
1299 write_phy_cck(dev, 0x11, 0x9b); /* Config CCK RX antenna. */
1300 write_phy_ofdm(dev, 0x0d, 0x5c); /* Config OFDM RX antenna. */
1302 bAntennaSwitched = true;
1303 break;
1305 case 1:
1306 /* Mac register, aux antenna */
1307 write_nic_byte(dev, ANTSEL, 0x00);
1308 /* base band */
1309 write_phy_cck(dev, 0x11, 0xbb); /* Config CCK RX antenna. */
1310 write_phy_ofdm(dev, 0x0d, 0x54); /* Config OFDM RX antenna. */
1312 bAntennaSwitched = true;
1314 break;
1316 default:
1317 printk("SetAntenna8185: unknown u1bAntennaIndex(%d)\n", u1bAntennaIndex);
1318 break;
1321 if(bAntennaSwitched)
1323 priv->CurrAntennaIndex = u1bAntennaIndex;
1326 // printk("-SetAntenna8185(): return (%#X)\n", bAntennaSwitched);
1328 return bAntennaSwitched;
1331 // Description:
1332 // Toggle Antenna switch.
1334 bool
1335 SwitchAntenna(
1336 struct net_device *dev
1339 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1341 bool bResult;
1343 if(priv->CurrAntennaIndex == 0)
1345 bResult = SetAntenna8185(dev, 1);
1346 //by amy 080312
1347 // printk("SwitchAntenna(): switching to antenna 1 ......\n");
1348 // bResult = SetAntenna8185(dev, 1);//-by amy 080312
1350 else
1352 bResult = SetAntenna8185(dev, 0);
1353 //by amy 080312
1354 // printk("SwitchAntenna(): switching to antenna 0 ......\n");
1355 // bResult = SetAntenna8185(dev, 0);//-by amy 080312
1358 return bResult;
1361 // Description:
1362 // Engine of SW Antenna Diversity mechanism.
1363 // Since 8187 has no Tx part information,
1364 // this implementation is only dependend on Rx part information.
1366 // 2006.04.17, by rcnjko.
1368 void
1369 SwAntennaDiversity(
1370 struct net_device *dev
1373 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1374 bool bSwCheckSS=false;
1375 // printk("+SwAntennaDiversity(): CurrAntennaIndex: %d\n", priv->CurrAntennaIndex);
1376 // printk("AdTickCount is %d\n",priv->AdTickCount);
1377 //by amy 080312
1378 if(bSwCheckSS)
1380 priv->AdTickCount++;
1382 printk("(1) AdTickCount: %d, AdCheckPeriod: %d\n",
1383 priv->AdTickCount, priv->AdCheckPeriod);
1384 printk("(2) AdRxSignalStrength: %ld, AdRxSsThreshold: %ld\n",
1385 priv->AdRxSignalStrength, priv->AdRxSsThreshold);
1387 // priv->AdTickCount++;//-by amy 080312
1389 // Case 1. No Link.
1390 if(priv->ieee80211->state != IEEE80211_LINKED)
1392 // printk("SwAntennaDiversity(): Case 1. No Link.\n");
1394 priv->bAdSwitchedChecking = false;
1395 // I switch antenna here to prevent any one of antenna is broken before link established, 2006.04.18, by rcnjko..
1396 SwitchAntenna(dev);
1398 // Case 2. Linked but no packet received.
1399 else if(priv->AdRxOkCnt == 0)
1401 // printk("SwAntennaDiversity(): Case 2. Linked but no packet received.\n");
1403 priv->bAdSwitchedChecking = false;
1404 SwitchAntenna(dev);
1406 // Case 3. Evaluate last antenna switch action and undo it if necessary.
1407 else if(priv->bAdSwitchedChecking == true)
1409 // printk("SwAntennaDiversity(): Case 3. Evaluate last antenna switch action.\n");
1411 priv->bAdSwitchedChecking = false;
1413 // Adjust Rx signal strength threshold.
1414 priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2;
1416 priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
1417 priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;
1418 if(priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched)
1419 { // Rx signal strength is not improved after we swtiched antenna. => Swich back.
1420 // printk("SwAntennaDiversity(): Rx Signal Strength is not improved, CurrRxSs: %d, LastRxSs: %d\n",
1421 // priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);
1422 //by amy 080312
1423 // Increase Antenna Diversity checking period due to bad decision.
1424 priv->AdCheckPeriod *= 2;
1425 //by amy 080312
1426 // Increase Antenna Diversity checking period.
1427 if(priv->AdCheckPeriod > priv->AdMaxCheckPeriod)
1428 priv->AdCheckPeriod = priv->AdMaxCheckPeriod;
1430 // Wrong deceision => switch back.
1431 SwitchAntenna(dev);
1433 else
1434 { // Rx Signal Strength is improved.
1435 // printk("SwAntennaDiversity(): Rx Signal Strength is improved, CurrRxSs: %d, LastRxSs: %d\n",
1436 // priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);
1438 // Reset Antenna Diversity checking period to its min value.
1439 priv->AdCheckPeriod = priv->AdMinCheckPeriod;
1442 // printk("SwAntennaDiversity(): AdRxSsThreshold: %d, AdCheckPeriod: %d\n",
1443 // priv->AdRxSsThreshold, priv->AdCheckPeriod);
1445 // Case 4. Evaluate if we shall switch antenna now.
1446 // Cause Table Speed is very fast in TRC Dell Lab, we check it every time.
1447 else// if(priv->AdTickCount >= priv->AdCheckPeriod)//-by amy 080312
1449 // printk("SwAntennaDiversity(): Case 4. Evaluate if we shall switch antenna now.\n");
1451 priv->AdTickCount = 0;
1454 // <Roger_Notes> We evaluate RxOk counts for each antenna first and than
1455 // evaluate signal strength.
1456 // The following operation can overcome the disability of CCA on both two antennas
1457 // When signal strength was extremely low or high.
1458 // 2008.01.30.
1462 // Evaluate RxOk count from each antenna if we shall switch default antenna now.
1463 // Added by Roger, 2008.02.21.
1464 //{by amy 080312
1465 if((priv->AdMainAntennaRxOkCnt < priv->AdAuxAntennaRxOkCnt)
1466 && (priv->CurrAntennaIndex == 0))
1467 { // We set Main antenna as default but RxOk count was less than Aux ones.
1469 // printk("SwAntennaDiversity(): Main antenna RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
1470 // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
1472 // Switch to Aux antenna.
1473 SwitchAntenna(dev);
1474 priv->bHWAdSwitched = true;
1476 else if((priv->AdAuxAntennaRxOkCnt < priv->AdMainAntennaRxOkCnt)
1477 && (priv->CurrAntennaIndex == 1))
1478 { // We set Aux antenna as default but RxOk count was less than Main ones.
1480 // printk("SwAntennaDiversity(): Aux antenna RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
1481 // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
1483 // Switch to Main antenna.
1484 SwitchAntenna(dev);
1485 priv->bHWAdSwitched = true;
1487 else
1488 {// Default antenna is better.
1490 // printk("SwAntennaDiversity(): Default antenna is better., AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
1491 // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
1493 // Still need to check current signal strength.
1494 priv->bHWAdSwitched = false;
1497 // <Roger_Notes> We evaluate Rx signal strength ONLY when default antenna
1498 // didn't changed by HW evaluation.
1499 // 2008.02.27.
1501 // [TRC Dell Lab] SignalStrength is inaccuracy. Isaiah 2008-03-05
1502 // For example, Throughput of aux is better than main antenna(about 10M v.s 2M),
1503 // but AdRxSignalStrength is less than main.
1504 // Our guess is that main antenna have lower throughput and get many change
1505 // to receive more CCK packets(ex.Beacon) which have stronger SignalStrength.
1507 if( (!priv->bHWAdSwitched) && (bSwCheckSS))
1509 //by amy 080312}
1510 // Evaluate Rx signal strength if we shall switch antenna now.
1511 if(priv->AdRxSignalStrength < priv->AdRxSsThreshold)
1512 { // Rx signal strength is weak => Switch Antenna.
1513 // printk("SwAntennaDiversity(): Rx Signal Strength is weak, CurrRxSs: %d, RxSsThreshold: %d\n",
1514 // priv->AdRxSignalStrength, priv->AdRxSsThreshold);
1516 priv->AdRxSsBeforeSwitched = priv->AdRxSignalStrength;
1517 priv->bAdSwitchedChecking = true;
1519 SwitchAntenna(dev);
1521 else
1522 { // Rx signal strength is OK.
1523 // printk("SwAntennaDiversity(): Rx Signal Strength is OK, CurrRxSs: %d, RxSsThreshold: %d\n",
1524 // priv->AdRxSignalStrength, priv->AdRxSsThreshold);
1526 priv->bAdSwitchedChecking = false;
1527 // Increase Rx signal strength threshold if necessary.
1528 if( (priv->AdRxSignalStrength > (priv->AdRxSsThreshold + 10)) && // Signal is much stronger than current threshold
1529 priv->AdRxSsThreshold <= priv->AdMaxRxSsThreshold) // Current threhold is not yet reach upper limit.
1531 priv->AdRxSsThreshold = (priv->AdRxSsThreshold + priv->AdRxSignalStrength) / 2;
1532 priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
1533 priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;//+by amy 080312
1536 // Reduce Antenna Diversity checking period if possible.
1537 if( priv->AdCheckPeriod > priv->AdMinCheckPeriod )
1539 priv->AdCheckPeriod /= 2;
1544 //by amy 080312
1545 // Reset antenna diversity Rx related statistics.
1546 priv->AdRxOkCnt = 0;
1547 priv->AdMainAntennaRxOkCnt = 0;
1548 priv->AdAuxAntennaRxOkCnt = 0;
1549 //by amy 080312
1551 // priv->AdRxOkCnt = 0;//-by amy 080312
1553 // printk("-SwAntennaDiversity()\n");
1557 // Description:
1558 // Return TRUE if we shall perform Tx Power Tracking Mecahnism, FALSE otherwise.
1560 bool
1561 CheckTxPwrTracking( struct net_device *dev)
1563 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1565 if(!priv->bTxPowerTrack)
1567 return false;
1570 //lzm reserved 080826
1571 //if(priv->bScanInProgress)
1573 // return false;
1576 //if 87SE is in High Power , don't do Tx Power Tracking. asked by SD3 ED. 2008-08-08 Isaiah
1577 if(priv->bToUpdateTxPwr)
1579 return false;
1582 return true;
1587 // Description:
1588 // Timer callback function of SW Antenna Diversity.
1590 void
1591 SwAntennaDiversityTimerCallback(
1592 struct net_device *dev
1595 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1596 RT_RF_POWER_STATE rtState;
1598 //printk("+SwAntennaDiversityTimerCallback()\n");
1601 // We do NOT need to switch antenna while RF is off.
1602 // 2007.05.09, added by Roger.
1604 rtState = priv->eRFPowerState;
1606 if (rtState == eRfOff)
1608 // printk("SwAntennaDiversityTimer - RF is OFF.\n");
1609 break;
1611 else if (rtState == eRfSleep)
1613 // Don't access BB/RF under Disable PLL situation.
1614 //RT_TRACE((COMP_RF|COMP_ANTENNA), DBG_LOUD, ("SwAntennaDiversityTimerCallback(): RF is Sleep => skip it\n"));
1615 break;
1617 SwAntennaDiversity(dev);
1619 }while(false);
1621 if(priv->up)
1623 priv->SwAntennaDiversityTimer.expires = jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD);
1624 add_timer(&priv->SwAntennaDiversityTimer);
1627 //printk("-SwAntennaDiversityTimerCallback()\n");