4 #include "r8180_93cx6.h"
9 // Return TRUE if we shall perform High Power Mecahnism, FALSE otherwise.
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
)
22 if(ieee
->state
== IEEE80211_LINKED_SCANNING
)
30 // Update Tx power level if necessary.
31 // See also DoRxHighPower() and SetTxPowerLevel8185() for reference.
34 // The reason why we udpate Tx power level here instead of DoRxHighPower()
35 // is the number of IO to change Tx power is much more than channel TR switch
36 // and they are related to OFDM and MAC registers.
37 // So, we don't want to update it so frequently in per-Rx packet base.
39 void DoTxHighPower(struct net_device
*dev
)
41 struct r8180_priv
*priv
= ieee80211_priv(dev
);
47 char OfdmTxPwrIdx
, CckTxPwrIdx
;
49 //printk("----> DoTxHighPower()\n");
51 HiPwrUpperTh
= priv
->RegHiPwrUpperTh
;
52 HiPwrLowerTh
= priv
->RegHiPwrLowerTh
;
54 HiPwrUpperTh
= HiPwrUpperTh
* 10;
55 HiPwrLowerTh
= HiPwrLowerTh
* 10;
56 RSSIHiPwrUpperTh
= priv
->RegRSSIHiPwrUpperTh
;
57 RSSIHiPwrLowerTh
= priv
->RegRSSIHiPwrLowerTh
;
60 OfdmTxPwrIdx
= priv
->chtxpwr_ofdm
[priv
->ieee80211
->current_network
.channel
];
61 CckTxPwrIdx
= priv
->chtxpwr
[priv
->ieee80211
->current_network
.channel
];
63 // printk("DoTxHighPower() - UndecoratedSmoothedSS:%d, CurCCKRSSI = %d , bCurCCKPkt= %d \n", priv->UndecoratedSmoothedSS, priv->CurCCKRSSI, priv->bCurCCKPkt );
65 if ((priv
->UndecoratedSmoothedSS
> HiPwrUpperTh
) ||
66 (priv
->bCurCCKPkt
&& (priv
->CurCCKRSSI
> RSSIHiPwrUpperTh
))) {
67 // Stevenl suggested that degrade 8dbm in high power sate. 2007-12-04 Isaiah
69 // printk("=====>DoTxHighPower() - High Power - UndecoratedSmoothedSS:%d, HiPwrUpperTh = %d \n", priv->UndecoratedSmoothedSS, HiPwrUpperTh );
70 priv
->bToUpdateTxPwr
= true;
71 u1bTmp
= read_nic_byte(dev
, CCK_TXAGC
);
73 // If it never enter High Power.
74 if (CckTxPwrIdx
== u1bTmp
) {
75 u1bTmp
= (u1bTmp
> 16) ? (u1bTmp
-16): 0; // 8dbm
76 write_nic_byte(dev
, CCK_TXAGC
, u1bTmp
);
78 u1bTmp
= read_nic_byte(dev
, OFDM_TXAGC
);
79 u1bTmp
= (u1bTmp
> 16) ? (u1bTmp
-16): 0; // 8dbm
80 write_nic_byte(dev
, OFDM_TXAGC
, u1bTmp
);
83 } else if ((priv
->UndecoratedSmoothedSS
< HiPwrLowerTh
) &&
84 (!priv
->bCurCCKPkt
|| priv
->CurCCKRSSI
< RSSIHiPwrLowerTh
)) {
85 // printk("DoTxHighPower() - lower Power - UndecoratedSmoothedSS:%d, HiPwrUpperTh = %d \n", priv->UndecoratedSmoothedSS, HiPwrLowerTh );
86 if (priv
->bToUpdateTxPwr
) {
87 priv
->bToUpdateTxPwr
= false;
89 u1bTmp
= read_nic_byte(dev
, CCK_TXAGC
);
90 if (u1bTmp
< CckTxPwrIdx
) {
91 //u1bTmp = ((u1bTmp+16) > 35) ? 35: (u1bTmp+16); // 8dbm
92 //write_nic_byte(dev, CCK_TXAGC, u1bTmp);
93 write_nic_byte(dev
, CCK_TXAGC
, CckTxPwrIdx
);
96 u1bTmp
= read_nic_byte(dev
, OFDM_TXAGC
);
97 if (u1bTmp
< OfdmTxPwrIdx
) {
98 //u1bTmp = ((u1bTmp+16) > 35) ? 35: (u1bTmp+16); // 8dbm
99 //write_nic_byte(dev, OFDM_TXAGC, u1bTmp);
100 write_nic_byte(dev
, OFDM_TXAGC
, OfdmTxPwrIdx
);
105 //printk("<---- DoTxHighPower()\n");
111 // Callback function of UpdateTxPowerWorkItem.
112 // Because of some event happened, e.g. CCX TPC, High Power Mechanism,
113 // We update Tx power of current channel again.
115 void rtl8180_tx_pw_wq(struct work_struct
*work
)
117 // struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
118 // struct ieee80211_device * ieee = (struct ieee80211_device*)
119 // container_of(work, struct ieee80211_device, watch_dog_wq);
120 struct delayed_work
*dwork
= to_delayed_work(work
);
121 struct ieee80211_device
*ieee
= container_of(dwork
,struct ieee80211_device
,tx_pw_wq
);
122 struct net_device
*dev
= ieee
->dev
;
124 // printk("----> UpdateTxPowerWorkItemCallback()\n");
128 // printk("<---- UpdateTxPowerWorkItemCallback()\n");
134 // Return TRUE if we shall perform DIG Mecahnism, FALSE otherwise.
136 bool CheckDig(struct net_device
*dev
)
138 struct r8180_priv
*priv
= ieee80211_priv(dev
);
139 struct ieee80211_device
*ieee
= priv
->ieee80211
;
141 if (!priv
->bDigMechanism
)
144 if (ieee
->state
!= IEEE80211_LINKED
)
147 //if(priv->CurrentOperaRate < 36) // Schedule Dig under all OFDM rates. By Bruce, 2007-06-01.
148 if ((priv
->ieee80211
->rate
/ 5) < 36) // Schedule Dig under all OFDM rates. By Bruce, 2007-06-01.
154 // Implementation of DIG for Zebra and Zebra2.
156 void DIG_Zebra(struct net_device
*dev
)
158 struct r8180_priv
*priv
= ieee80211_priv(dev
);
159 u16 CCKFalseAlarm
, OFDMFalseAlarm
;
160 u16 OfdmFA1
, OfdmFA2
;
161 int InitialGainStep
= 7; // The number of initial gain stages.
162 int LowestGainStage
= 4; // The capable lowest stage of performing dig workitem.
163 u32 AwakePeriodIn2Sec
= 0;
165 //printk("---------> DIG_Zebra()\n");
167 CCKFalseAlarm
= (u16
)(priv
->FalseAlarmRegValue
& 0x0000ffff);
168 OFDMFalseAlarm
= (u16
)((priv
->FalseAlarmRegValue
>> 16) & 0x0000ffff);
170 OfdmFA2
= ((u16
)(priv
->RegDigOfdmFaUpTh
)) << 8;
172 // printk("DIG**********CCK False Alarm: %#X \n",CCKFalseAlarm);
173 // printk("DIG**********OFDM False Alarm: %#X \n",OFDMFalseAlarm);
175 // The number of initial gain steps is different, by Bruce, 2007-04-13.
176 if (priv
->InitialGain
== 0) { //autoDIG
177 // Advised from SD3 DZ
178 priv
->InitialGain
= 4; // In 87B, m74dBm means State 4 (m82dBm)
180 // Advised from SD3 DZ
183 #if 1 //lzm reserved 080826
184 AwakePeriodIn2Sec
= (2000 - priv
->DozePeriodInPast2Sec
);
185 //printk("&&& DozePeriod=%d AwakePeriod=%d\n", priv->DozePeriodInPast2Sec, AwakePeriodIn2Sec);
186 priv
->DozePeriodInPast2Sec
= 0;
188 if (AwakePeriodIn2Sec
) {
189 //RT_TRACE(COMP_DIG, DBG_TRACE, ("DIG: AwakePeriodIn2Sec(%d) - FATh(0x%X , 0x%X) ->",AwakePeriodIn2Sec, OfdmFA1, OfdmFA2));
190 // adjuest DIG threshold.
191 OfdmFA1
= (u16
)((OfdmFA1
* AwakePeriodIn2Sec
) / 2000) ;
192 OfdmFA2
= (u16
)((OfdmFA2
* AwakePeriodIn2Sec
) / 2000) ;
193 //RT_TRACE(COMP_DIG, DBG_TRACE, ("( 0x%X , 0x%X)\n", OfdmFA1, OfdmFA2));
195 ;//RT_TRACE(COMP_DIG, DBG_WARNING, ("ERROR!! AwakePeriodIn2Sec should not be ZERO!!\n"));
200 LowestGainStage
= priv
->RegBModeGainStage
; // Lowest gain stage.
202 if (OFDMFalseAlarm
> OfdmFA1
) {
203 if (OFDMFalseAlarm
> OfdmFA2
) {
204 priv
->DIG_NumberFallbackVote
++;
205 if (priv
->DIG_NumberFallbackVote
> 1) {
206 //serious OFDM False Alarm, need fallback
207 if (priv
->InitialGain
< InitialGainStep
) {
208 priv
->InitialGainBackUp
= priv
->InitialGain
;
210 priv
->InitialGain
= (priv
->InitialGain
+ 1);
211 // printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);
212 // printk("DIG+++++++ fallback OFDM:%d \n", priv->InitialGain);
213 UpdateInitialGain(dev
);
215 priv
->DIG_NumberFallbackVote
= 0;
216 priv
->DIG_NumberUpgradeVote
= 0;
219 if (priv
->DIG_NumberFallbackVote
)
220 priv
->DIG_NumberFallbackVote
--;
222 priv
->DIG_NumberUpgradeVote
= 0;
224 if (priv
->DIG_NumberFallbackVote
)
225 priv
->DIG_NumberFallbackVote
--;
226 priv
->DIG_NumberUpgradeVote
++;
228 if (priv
->DIG_NumberUpgradeVote
> 9) {
229 if (priv
->InitialGain
> LowestGainStage
) { // In 87B, m78dBm means State 4 (m864dBm)
230 priv
->InitialGainBackUp
= priv
->InitialGain
;
232 priv
->InitialGain
= (priv
->InitialGain
- 1);
233 // printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);
234 // printk("DIG--------- Upgrade OFDM:%d \n", priv->InitialGain);
235 UpdateInitialGain(dev
);
237 priv
->DIG_NumberFallbackVote
= 0;
238 priv
->DIG_NumberUpgradeVote
= 0;
242 // printk("DIG+++++++ OFDM:%d\n", priv->InitialGain);
243 //printk("<--------- DIG_Zebra()\n");
248 // Dispatch DIG implementation according to RF.
250 void DynamicInitGain(struct net_device
*dev
)
255 void rtl8180_hw_dig_wq(struct work_struct
*work
)
257 struct delayed_work
*dwork
= to_delayed_work(work
);
258 struct ieee80211_device
*ieee
= container_of(dwork
,struct ieee80211_device
,hw_dig_wq
);
259 struct net_device
*dev
= ieee
->dev
;
260 struct r8180_priv
*priv
= ieee80211_priv(dev
);
262 // Read CCK and OFDM False Alarm.
263 priv
->FalseAlarmRegValue
= read_nic_dword(dev
, CCK_FALSE_ALARM
);
266 // Adjust Initial Gain dynamically.
267 DynamicInitGain(dev
);
271 int IncludedInSupportedRates(struct r8180_priv
*priv
, u8 TxRate
)
277 unsigned short Found
= 0;
278 u8 NaiveTxRate
= TxRate
&RateMask
;
280 rate_len
= priv
->ieee80211
->current_network
.rates_len
;
281 rate_ex_len
= priv
->ieee80211
->current_network
.rates_ex_len
;
282 for (idx
=0; idx
< rate_len
; idx
++) {
283 if ((priv
->ieee80211
->current_network
.rates
[idx
] & RateMask
) == NaiveTxRate
) {
288 for (idx
= 0; idx
< rate_ex_len
; idx
++) {
289 if ((priv
->ieee80211
->current_network
.rates_ex
[idx
] & RateMask
) == NaiveTxRate
) {
301 // Get the Tx rate one degree up form the input rate in the supported rates.
302 // Return the upgrade rate if it is successed, otherwise return the input rate.
303 // By Bruce, 2007-06-05.
305 u8
GetUpgradeTxRate(struct net_device
*dev
, u8 rate
)
307 struct r8180_priv
*priv
= ieee80211_priv(dev
);
312 case 108: // Up to 54Mbps.
316 case 96: // Up to 54Mbps.
320 case 72: // Up to 48Mbps.
324 case 48: // Up to 36Mbps.
328 case 36: // Up to 24Mbps.
332 case 22: // Up to 18Mbps.
336 case 11: // Up to 11Mbps.
340 case 4: // Up to 5.5Mbps.
344 case 2: // Up to 2Mbps.
349 printk("GetUpgradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate
);
352 // Check if the rate is valid.
353 if (IncludedInSupportedRates(priv
, UpRate
)) {
354 // printk("GetUpgradeTxRate(): GetUpgrade Tx rate(%d) from %d !\n", UpRate, priv->CurrentOperaRate);
357 //printk("GetUpgradeTxRate(): Tx rate (%d) is not in supported rates\n", UpRate);
364 // Get the Tx rate one degree down form the input rate in the supported rates.
365 // Return the degrade rate if it is successed, otherwise return the input rate.
366 // By Bruce, 2007-06-05.
368 u8
GetDegradeTxRate(struct net_device
*dev
, u8 rate
)
370 struct r8180_priv
*priv
= ieee80211_priv(dev
);
375 case 108: // Down to 48Mbps.
379 case 96: // Down to 36Mbps.
383 case 72: // Down to 24Mbps.
387 case 48: // Down to 18Mbps.
391 case 36: // Down to 11Mbps.
395 case 22: // Down to 5.5Mbps.
399 case 11: // Down to 2Mbps.
403 case 4: // Down to 1Mbps.
407 case 2: // Down to 1Mbps.
412 printk("GetDegradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate
);
415 // Check if the rate is valid.
416 if (IncludedInSupportedRates(priv
, DownRate
)) {
417 // printk("GetDegradeTxRate(): GetDegrade Tx rate(%d) from %d!\n", DownRate, priv->CurrentOperaRate);
420 //printk("GetDegradeTxRate(): Tx rate (%d) is not in supported rates\n", DownRate);
426 // Helper function to determine if specified data rate is
428 // 2005.01.25, by rcnjko.
430 bool MgntIsCckRate(u16 rate
)
432 bool bReturn
= false;
434 if ((rate
<= 22) && (rate
!= 12) && (rate
!= 18)) {
442 // Tx Power tracking mechanism routine on 87SE.
443 // Created by Roger, 2007.12.11.
445 void TxPwrTracking87SE(struct net_device
*dev
)
447 struct r8180_priv
*priv
= (struct r8180_priv
*)ieee80211_priv(dev
);
448 u8 tmpu1Byte
, CurrentThermal
, Idx
;
449 char CckTxPwrIdx
, OfdmTxPwrIdx
;
452 tmpu1Byte
= read_nic_byte(dev
, EN_LPF_CAL
);
453 CurrentThermal
= (tmpu1Byte
& 0xf0) >> 4; //[ 7:4]: thermal meter indication.
454 CurrentThermal
= (CurrentThermal
> 0x0c) ? 0x0c:CurrentThermal
;//lzm add 080826
456 //printk("TxPwrTracking87SE(): CurrentThermal(%d)\n", CurrentThermal);
458 if (CurrentThermal
!= priv
->ThermalMeter
) {
459 // printk("TxPwrTracking87SE(): Thermal meter changed!!!\n");
461 // Update Tx Power level on each channel.
462 for (Idx
= 1; Idx
< 15; Idx
++) {
463 CckTxPwrIdx
= priv
->chtxpwr
[Idx
];
464 OfdmTxPwrIdx
= priv
->chtxpwr_ofdm
[Idx
];
466 if (CurrentThermal
> priv
->ThermalMeter
) {
467 // higher thermal meter.
468 CckTxPwrIdx
+= (CurrentThermal
- priv
->ThermalMeter
) * 2;
469 OfdmTxPwrIdx
+= (CurrentThermal
- priv
->ThermalMeter
) * 2;
471 if (CckTxPwrIdx
> 35)
472 CckTxPwrIdx
= 35; // Force TxPower to maximal index.
473 if (OfdmTxPwrIdx
> 35)
476 // lower thermal meter.
477 CckTxPwrIdx
-= (priv
->ThermalMeter
- CurrentThermal
) * 2;
478 OfdmTxPwrIdx
-= (priv
->ThermalMeter
- CurrentThermal
) * 2;
482 if (OfdmTxPwrIdx
< 0)
486 // Update TxPower level on CCK and OFDM resp.
487 priv
->chtxpwr
[Idx
] = CckTxPwrIdx
;
488 priv
->chtxpwr_ofdm
[Idx
] = OfdmTxPwrIdx
;
491 // Update TxPower level immediately.
492 rtl8225z2_SetTXPowerLevel(dev
, priv
->ieee80211
->current_network
.channel
);
494 priv
->ThermalMeter
= CurrentThermal
;
496 void StaRateAdaptive87SE(struct net_device
*dev
)
498 struct r8180_priv
*priv
= (struct r8180_priv
*)ieee80211_priv(dev
);
499 unsigned long CurrTxokCnt
;
503 unsigned long CurrRxokCnt
;
505 bool bTryDown
= false;
509 long CurrSignalStrength
;
510 bool bUpdateInitialGain
= false;
511 u8 u1bOfdm
= 0, u1bCck
= 0;
512 char OfdmTxPwrIdx
, CckTxPwrIdx
;
514 priv
->RateAdaptivePeriod
= RATE_ADAPTIVE_TIMER_PERIOD
;
517 CurrRetryCnt
= priv
->CurrRetryCnt
;
518 CurrTxokCnt
= priv
->NumTxOkTotal
- priv
->LastTxokCnt
;
519 CurrRxokCnt
= priv
->ieee80211
->NumRxOkTotal
- priv
->LastRxokCnt
;
520 CurrSignalStrength
= priv
->Stats_RecvSignalPower
;
521 TxThroughput
= (u32
)(priv
->NumTxOkBytesTotal
- priv
->LastTxOKBytes
);
522 priv
->LastTxOKBytes
= priv
->NumTxOkBytesTotal
;
523 priv
->CurrentOperaRate
= priv
->ieee80211
->rate
/ 5;
524 //printk("priv->CurrentOperaRate is %d\n",priv->CurrentOperaRate);
525 //2 Compute retry ratio.
526 if (CurrTxokCnt
> 0) {
527 CurrRetryRate
= (u16
)(CurrRetryCnt
* 100 / CurrTxokCnt
);
529 // It may be serious retry. To distinguish serious retry or no packets modified by Bruce
530 CurrRetryRate
= (u16
)(CurrRetryCnt
* 100 / 1);
535 // Added by Roger, 2007.01.02.
536 // For debug information.
538 //printk("\n(1) pHalData->LastRetryRate: %d \n",priv->LastRetryRate);
539 //printk("(2) RetryCnt = %d \n", CurrRetryCnt);
540 //printk("(3) TxokCnt = %d \n", CurrTxokCnt);
541 //printk("(4) CurrRetryRate = %d \n", CurrRetryRate);
542 //printk("(5) CurrSignalStrength = %d \n",CurrSignalStrength);
543 //printk("(6) TxThroughput is %d\n",TxThroughput);
544 //printk("priv->NumTxOkBytesTotal is %d\n",priv->NumTxOkBytesTotal);
546 priv
->LastRetryCnt
= priv
->CurrRetryCnt
;
547 priv
->LastTxokCnt
= priv
->NumTxOkTotal
;
548 priv
->LastRxokCnt
= priv
->ieee80211
->NumRxOkTotal
;
549 priv
->CurrRetryCnt
= 0;
551 //2No Tx packets, return to init_rate or not?
552 if (CurrRetryRate
== 0 && CurrTxokCnt
== 0) {
554 //After 9 (30*300ms) seconds in this condition, we try to raise rate.
556 priv
->TryupingCountNoData
++;
558 // printk("No Tx packets, TryupingCountNoData(%d)\n", priv->TryupingCountNoData);
559 //[TRC Dell Lab] Extend raised period from 4.5sec to 9sec, Isaiah 2008-02-15 18:00
560 if (priv
->TryupingCountNoData
> 30) {
561 priv
->TryupingCountNoData
= 0;
562 priv
->CurrentOperaRate
= GetUpgradeTxRate(dev
, priv
->CurrentOperaRate
);
564 priv
->LastFailTxRate
= 0;
565 priv
->LastFailTxRateSS
= -200;
566 priv
->FailTxRateCount
= 0;
570 priv
->TryupingCountNoData
= 0; //Reset trying up times.
575 // For Netgear case, I comment out the following signal strength estimation,
576 // which can results in lower rate to transmit when sample is NOT enough (e.g. PING request).
577 // 2007.04.09, by Roger.
581 // Restructure rate adaptive as the following main stages:
582 // (1) Add retry threshold in 54M upgrading condition with signal strength.
583 // (2) Add the mechanism to degrade to CCK rate according to signal strength
585 // (3) Remove all Initial Gain Updates over OFDM rate. To avoid the complicated
586 // situation, Initial Gain Update is upon on DIG mechanism except CCK rate.
587 // (4) Add the mehanism of trying to upgrade tx rate.
588 // (5) Record the information of upping tx rate to avoid trying upping tx rate constantly.
589 // By Bruce, 2007-06-05.
594 // Check more times in these rate(key rates).
596 if (priv
->CurrentOperaRate
== 22 || priv
->CurrentOperaRate
== 72)
599 // Let these rates down more difficult.
601 if (MgntIsCckRate(priv
->CurrentOperaRate
) || priv
->CurrentOperaRate
== 36)
605 if (priv
->bTryuping
== true) {
606 //2 For Test Upgrading mechanism
608 // Sometimes the throughput is upon on the capability bwtween the AP and NIC,
609 // thus the low data rate does not improve the performance.
610 // We randomly upgrade the data rate and check if the retry rate is improved.
612 // Upgrading rate did not improve the retry rate, fallback to the original rate.
613 if ((CurrRetryRate
> 25) && TxThroughput
< priv
->LastTxThroughput
) {
614 //Not necessary raising rate, fall back rate.
616 //printk("case1-1: Not necessary raising rate, fall back rate....\n");
617 //printk("case1-1: pMgntInfo->CurrentOperaRate =%d, TxThroughput = %d, LastThroughput = %d\n",
618 // priv->CurrentOperaRate, TxThroughput, priv->LastTxThroughput);
620 priv
->bTryuping
= false;
622 } else if (CurrSignalStrength
> -47 && (CurrRetryRate
< 50)) {
625 // Added by Roger, 2007.04.09.
626 // Return to highest data rate, if signal strength is good enough.
627 // SignalStrength threshold(-50dbm) is for RTL8186.
628 // Revise SignalStrength threshold to -51dbm.
630 // Also need to check retry rate for safety, by Bruce, 2007-06-05.
631 if (priv
->CurrentOperaRate
!= priv
->ieee80211
->current_network
.HighestOperaRate
) {
633 // Upgrade Tx Rate directly.
634 priv
->TryupingCount
+= TryUpTh
;
636 // printk("case2: StaRateAdaptive87SE: Power(%d) is high enough!!. \n", CurrSignalStrength);
638 } else if (CurrTxokCnt
> 9 && CurrTxokCnt
< 100 && CurrRetryRate
>= 600) {
639 //2 For Serious Retry
641 // Traffic is not busy but our Tx retry is serious.
644 // Let Rate Mechanism to degrade tx rate directly.
645 priv
->TryDownCountLowData
+= TryDownTh
;
646 // printk("case3: RA: Tx Retry is serious. Degrade Tx Rate to %d directly...\n", priv->CurrentOperaRate);
647 } else if (priv
->CurrentOperaRate
== 108) {
650 if ((CurrRetryRate
> 26) && (priv
->LastRetryRate
> 25)) {
651 // if ((CurrRetryRate>40)&&(priv->LastRetryRate>39))
652 //Down to rate 48Mbps.
656 else if ((CurrRetryRate
> 17) && (priv
->LastRetryRate
> 16) && (CurrSignalStrength
> -72)) {
657 // else if ((CurrRetryRate>17)&&(priv->LastRetryRate>16) && (CurrSignalStrength > -72))
658 //Down to rate 48Mbps.
662 if (bTryDown
&& (CurrSignalStrength
< -75)) //cable link
663 priv
->TryDownCountLowData
+= TryDownTh
;
664 //printk("case4---54M \n");
667 else if (priv
->CurrentOperaRate
== 96) {
670 if (((CurrRetryRate
> 48) && (priv
->LastRetryRate
> 47))) {
671 // if ( ((CurrRetryRate>65) && (priv->LastRetryRate>64)))
672 //Down to rate 36Mbps.
674 } else if (((CurrRetryRate
> 21) && (priv
->LastRetryRate
> 20)) && (CurrSignalStrength
> -74)) { //Cable Link
675 //Down to rate 36Mbps.
677 } else if ((CurrRetryRate
> (priv
->LastRetryRate
+ 50)) && (priv
->FailTxRateCount
> 2)) {
678 // else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
680 priv
->TryDownCountLowData
+= TryDownTh
;
681 } else if ((CurrRetryRate
< 8) && (priv
->LastRetryRate
< 8)) { //TO DO: need to consider (RSSI)
682 // else if ( (CurrRetryRate<28) && (priv->LastRetryRate<8) )
686 if (bTryDown
&& (CurrSignalStrength
< -75)){
687 priv
->TryDownCountLowData
+= TryDownTh
;
689 //printk("case5---48M \n");
690 } else if (priv
->CurrentOperaRate
== 72) {
692 if ((CurrRetryRate
> 43) && (priv
->LastRetryRate
> 41)) {
693 // if ( (CurrRetryRate>60) && (priv->LastRetryRate>59))
694 //Down to rate 24Mbps.
696 } else if ((CurrRetryRate
> (priv
->LastRetryRate
+ 50)) && (priv
->FailTxRateCount
> 2)) {
697 // else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
699 priv
->TryDownCountLowData
+= TryDownTh
;
700 } else if ((CurrRetryRate
< 15) && (priv
->LastRetryRate
< 16)) { //TO DO: need to consider (RSSI)
701 // else if ( (CurrRetryRate<35) && (priv->LastRetryRate<36))
705 if (bTryDown
&& (CurrSignalStrength
< -80))
706 priv
->TryDownCountLowData
+= TryDownTh
;
708 //printk("case6---36M \n");
709 } else if (priv
->CurrentOperaRate
== 48) {
712 if (((CurrRetryRate
> 63) && (priv
->LastRetryRate
> 62))) {
713 // if ( ((CurrRetryRate>83) && (priv->LastRetryRate>82)))
714 //Down to rate 18Mbps.
716 } else if (((CurrRetryRate
> 33) && (priv
->LastRetryRate
> 32)) && (CurrSignalStrength
> -82)) { //Cable Link
717 // else if ( ((CurrRetryRate>50) && (priv->LastRetryRate>49)) && (CurrSignalStrength > -82) )
718 //Down to rate 18Mbps.
720 } else if ((CurrRetryRate
> (priv
->LastRetryRate
+ 50)) && (priv
->FailTxRateCount
> 2 )) {
721 // else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
723 priv
->TryDownCountLowData
+= TryDownTh
;
724 } else if ((CurrRetryRate
< 20) && (priv
->LastRetryRate
< 21)) { //TO DO: need to consider (RSSI)
725 // else if ( (CurrRetryRate<40) && (priv->LastRetryRate<41))
729 if (bTryDown
&& (CurrSignalStrength
< -82))
730 priv
->TryDownCountLowData
+= TryDownTh
;
732 //printk("case7---24M \n");
733 } else if (priv
->CurrentOperaRate
== 36) {
735 // original (109, 109)
736 //[TRC Dell Lab] (90, 91), Isaiah 2008-02-18 23:24
737 // (85, 86), Isaiah 2008-02-18 24:00
738 if (((CurrRetryRate
> 85) && (priv
->LastRetryRate
> 86))) {
739 // if ( ((CurrRetryRate>115) && (priv->LastRetryRate>116)))
740 //Down to rate 11Mbps.
743 //[TRC Dell Lab] Isaiah 2008-02-18 23:24
744 } else if ((CurrRetryRate
> (priv
->LastRetryRate
+ 50)) && (priv
->FailTxRateCount
> 2)) {
745 // else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
747 priv
->TryDownCountLowData
+= TryDownTh
;
748 } else if ((CurrRetryRate
< 22) && (priv
->LastRetryRate
< 23)) { //TO DO: need to consider (RSSI)
749 // else if ( (CurrRetryRate<42) && (priv->LastRetryRate<43))
752 //printk("case8---18M \n");
753 } else if (priv
->CurrentOperaRate
== 22) {
755 if (CurrRetryRate
> 95) {
756 // if (CurrRetryRate>155)
759 else if ((CurrRetryRate
< 29) && (priv
->LastRetryRate
< 30)) { //TO DO: need to consider (RSSI)
760 // else if ( (CurrRetryRate<49) && (priv->LastRetryRate <50) )
763 //printk("case9---11M \n");
764 } else if (priv
->CurrentOperaRate
== 11) {
766 if (CurrRetryRate
> 149) {
767 // if (CurrRetryRate>189)
769 } else if ((CurrRetryRate
< 60) && (priv
->LastRetryRate
< 65)) {
770 // else if ( (CurrRetryRate<80) && (priv->LastRetryRate < 85))
773 //printk("case10---5.5M \n");
774 } else if (priv
->CurrentOperaRate
== 4) {
776 if ((CurrRetryRate
> 99) && (priv
->LastRetryRate
> 99)) {
777 // if((CurrRetryRate>199) && (priv->LastRetryRate>199))
779 } else if ((CurrRetryRate
< 65) && (priv
->LastRetryRate
< 70)) {
780 // else if ( (CurrRetryRate < 85) && (priv->LastRetryRate < 90))
783 //printk("case11---2M \n");
784 } else if (priv
->CurrentOperaRate
== 2) {
786 if ((CurrRetryRate
< 70) && (priv
->LastRetryRate
< 75)) {
787 // if( (CurrRetryRate<90) && (priv->LastRetryRate<95))
790 //printk("case12---1M \n");
793 if (bTryUp
&& bTryDown
)
794 printk("StaRateAdaptive87B(): Tx Rate tried upping and downing simultaneously!\n");
796 //1 Test Upgrading Tx Rate
797 // Sometimes the cause of the low throughput (high retry rate) is the compatibility between the AP and NIC.
798 // To test if the upper rate may cause lower retry rate, this mechanism randomly occurs to test upgrading tx rate.
799 if (!bTryUp
&& !bTryDown
&& (priv
->TryupingCount
== 0) && (priv
->TryDownCountLowData
== 0)
800 && priv
->CurrentOperaRate
!= priv
->ieee80211
->current_network
.HighestOperaRate
&& priv
->FailTxRateCount
< 2) {
801 if (jiffies
% (CurrRetryRate
+ 101) == 0) {
803 priv
->bTryuping
= true;
804 //printk("StaRateAdaptive87SE(): Randomly try upgrading...\n");
810 priv
->TryupingCount
++;
811 priv
->TryDownCountLowData
= 0;
813 // printk("UP: pHalData->TryupingCount = %d\n", priv->TryupingCount);
814 // printk("UP: TryUpTh(%d)+ (FailTxRateCount(%d))^2 =%d\n",
815 // TryUpTh, priv->FailTxRateCount, (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount) );
816 // printk("UP: pHalData->bTryuping=%d\n", priv->bTryuping);}
819 // Check more times if we need to upgrade indeed.
820 // Because the largest value of pHalData->TryupingCount is 0xFFFF and
821 // the largest value of pHalData->FailTxRateCount is 0x14,
822 // this condition will be satisfied at most every 2 min.
825 if ((priv
->TryupingCount
> (TryUpTh
+ priv
->FailTxRateCount
* priv
->FailTxRateCount
)) ||
826 (CurrSignalStrength
> priv
->LastFailTxRateSS
) || priv
->bTryuping
) {
827 priv
->TryupingCount
= 0;
829 // When transferring from CCK to OFDM, DIG is an important issue.
831 if (priv
->CurrentOperaRate
== 22)
832 bUpdateInitialGain
= true;
834 // The difference in throughput between 48Mbps and 36Mbps is 8M.
835 // So, we must be carefully in this rate scale. Isaiah 2008-02-15.
837 if (((priv
->CurrentOperaRate
== 72) || (priv
->CurrentOperaRate
== 48) || (priv
->CurrentOperaRate
== 36)) &&
838 (priv
->FailTxRateCount
> 2))
839 priv
->RateAdaptivePeriod
= (RATE_ADAPTIVE_TIMER_PERIOD
/ 2);
841 // (1)To avoid upgrade frequently to the fail tx rate, add the FailTxRateCount into the threshold.
842 // (2)If the signal strength is increased, it may be able to upgrade.
844 priv
->CurrentOperaRate
= GetUpgradeTxRate(dev
, priv
->CurrentOperaRate
);
845 // printk("StaRateAdaptive87SE(): Upgrade Tx Rate to %d\n", priv->CurrentOperaRate);
847 //[TRC Dell Lab] Bypass 12/9/6, Isaiah 2008-02-18 20:00
848 if (priv
->CurrentOperaRate
== 36) {
849 priv
->bUpdateARFR
= true;
850 write_nic_word(dev
, ARFR
, 0x0F8F); //bypass 12/9/6
851 // printk("UP: ARFR=0xF8F\n");
852 } else if(priv
->bUpdateARFR
) {
853 priv
->bUpdateARFR
= false;
854 write_nic_word(dev
, ARFR
, 0x0FFF); //set 1M ~ 54Mbps.
855 // printk("UP: ARFR=0xFFF\n");
858 // Update Fail Tx rate and count.
859 if (priv
->LastFailTxRate
!= priv
->CurrentOperaRate
) {
860 priv
->LastFailTxRate
= priv
->CurrentOperaRate
;
861 priv
->FailTxRateCount
= 0;
862 priv
->LastFailTxRateSS
= -200; // Set lowest power.
866 if (priv
->TryupingCount
> 0)
867 priv
->TryupingCount
--;
871 priv
->TryDownCountLowData
++;
872 priv
->TryupingCount
= 0;
874 // printk("DN: pHalData->TryDownCountLowData = %d\n",priv->TryDownCountLowData);
875 // printk("DN: TryDownTh =%d\n", TryDownTh);
876 // printk("DN: pHalData->bTryuping=%d\n", priv->bTryuping);
879 //Check if Tx rate can be degraded or Test trying upgrading should fallback.
880 if (priv
->TryDownCountLowData
> TryDownTh
|| priv
->bTryuping
) {
881 priv
->TryDownCountLowData
= 0;
882 priv
->bTryuping
= false;
883 // Update fail information.
884 if (priv
->LastFailTxRate
== priv
->CurrentOperaRate
) {
885 priv
->FailTxRateCount
++;
886 // Record the Tx fail rate signal strength.
887 if (CurrSignalStrength
> priv
->LastFailTxRateSS
)
888 priv
->LastFailTxRateSS
= CurrSignalStrength
;
890 priv
->LastFailTxRate
= priv
->CurrentOperaRate
;
891 priv
->FailTxRateCount
= 1;
892 priv
->LastFailTxRateSS
= CurrSignalStrength
;
894 priv
->CurrentOperaRate
= GetDegradeTxRate(dev
, priv
->CurrentOperaRate
);
896 // Reduce chariot training time at weak signal strength situation. SD3 ED demand.
897 //[TRC Dell Lab] Revise Signal Threshold from -75 to -80 , Isaiah 2008-02-18 20:00
898 if ((CurrSignalStrength
< -80) && (priv
->CurrentOperaRate
> 72 )) {
899 priv
->CurrentOperaRate
= 72;
900 // printk("DN: weak signal strength (%d), degrade to 36Mbps\n", CurrSignalStrength);
903 //[TRC Dell Lab] Bypass 12/9/6, Isaiah 2008-02-18 20:00
904 if (priv
->CurrentOperaRate
== 36) {
905 priv
->bUpdateARFR
= true;
906 write_nic_word(dev
, ARFR
, 0x0F8F); //bypass 12/9/6
907 // printk("DN: ARFR=0xF8F\n");
908 } else if (priv
->bUpdateARFR
) {
909 priv
->bUpdateARFR
= false;
910 write_nic_word(dev
, ARFR
, 0x0FFF); //set 1M ~ 54Mbps.
911 // printk("DN: ARFR=0xFFF\n");
915 // When it is CCK rate, it may need to update initial gain to receive lower power packets.
917 if (MgntIsCckRate(priv
->CurrentOperaRate
)) {
918 bUpdateInitialGain
= true;
920 // printk("StaRateAdaptive87SE(): Degrade Tx Rate to %d\n", priv->CurrentOperaRate);
923 if (priv
->TryDownCountLowData
> 0)
924 priv
->TryDownCountLowData
--;
927 // Keep the Tx fail rate count to equal to 0x15 at most.
928 // Reduce the fail count at least to 10 sec if tx rate is tending stable.
929 if (priv
->FailTxRateCount
>= 0x15 ||
930 (!bTryUp
&& !bTryDown
&& priv
->TryDownCountLowData
== 0 && priv
->TryupingCount
&& priv
->FailTxRateCount
> 0x6)) {
931 priv
->FailTxRateCount
--;
935 OfdmTxPwrIdx
= priv
->chtxpwr_ofdm
[priv
->ieee80211
->current_network
.channel
];
936 CckTxPwrIdx
= priv
->chtxpwr
[priv
->ieee80211
->current_network
.channel
];
938 //[TRC Dell Lab] Mac0x9e increase 2 level in 36M~18M situation, Isaiah 2008-02-18 24:00
939 if ((priv
->CurrentOperaRate
< 96) && (priv
->CurrentOperaRate
> 22)) {
940 u1bCck
= read_nic_byte(dev
, CCK_TXAGC
);
941 u1bOfdm
= read_nic_byte(dev
, OFDM_TXAGC
);
943 // case 1: Never enter High power
944 if (u1bCck
== CckTxPwrIdx
) {
945 if (u1bOfdm
!= (OfdmTxPwrIdx
+ 2)) {
946 priv
->bEnhanceTxPwr
= true;
947 u1bOfdm
= ((u1bOfdm
+ 2) > 35) ? 35: (u1bOfdm
+ 2);
948 write_nic_byte(dev
, OFDM_TXAGC
, u1bOfdm
);
949 // printk("Enhance OFDM_TXAGC : +++++ u1bOfdm= 0x%x\n", u1bOfdm);
951 } else if (u1bCck
< CckTxPwrIdx
) {
952 // case 2: enter high power
953 if (!priv
->bEnhanceTxPwr
) {
954 priv
->bEnhanceTxPwr
= true;
955 u1bOfdm
= ((u1bOfdm
+ 2) > 35) ? 35: (u1bOfdm
+ 2);
956 write_nic_byte(dev
, OFDM_TXAGC
, u1bOfdm
);
957 //RT_TRACE(COMP_RATE, DBG_TRACE, ("Enhance OFDM_TXAGC(2) : +++++ u1bOfdm= 0x%x\n", u1bOfdm));
960 } else if (priv
->bEnhanceTxPwr
) { //54/48/11/5.5/2/1
961 u1bCck
= read_nic_byte(dev
, CCK_TXAGC
);
962 u1bOfdm
= read_nic_byte(dev
, OFDM_TXAGC
);
964 // case 1: Never enter High power
965 if (u1bCck
== CckTxPwrIdx
) {
966 priv
->bEnhanceTxPwr
= false;
967 write_nic_byte(dev
, OFDM_TXAGC
, OfdmTxPwrIdx
);
968 //printk("Recover OFDM_TXAGC : ===== u1bOfdm= 0x%x\n", OfdmTxPwrIdx);
970 // case 2: enter high power
971 else if (u1bCck
< CckTxPwrIdx
) {
972 priv
->bEnhanceTxPwr
= false;
973 u1bOfdm
= ((u1bOfdm
- 2) > 0) ? (u1bOfdm
- 2): 0;
974 write_nic_byte(dev
, OFDM_TXAGC
, u1bOfdm
);
975 //RT_TRACE(COMP_RATE, DBG_TRACE, ("Recover OFDM_TXAGC(2): ===== u1bOfdm= 0x%x\n", u1bOfdm));
981 // We need update initial gain when we set tx rate "from OFDM to CCK" or
982 // "from CCK to OFDM".
985 if (bUpdateInitialGain
) {
986 if (MgntIsCckRate(priv
->CurrentOperaRate
)) { // CCK
987 if (priv
->InitialGain
> priv
->RegBModeGainStage
) {
988 priv
->InitialGainBackUp
= priv
->InitialGain
;
990 if (CurrSignalStrength
< -85) // Low power, OFDM [0x17] = 26.
991 //SD3 SYs suggest that CurrSignalStrength < -65, ofdm 0x17=26.
992 priv
->InitialGain
= priv
->RegBModeGainStage
;
994 else if (priv
->InitialGain
> priv
->RegBModeGainStage
+ 1)
995 priv
->InitialGain
-= 2;
1000 printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv
->InitialGain
, priv
->CurrentOperaRate
);
1001 UpdateInitialGain(dev
);
1004 if (priv
->InitialGain
< 4) {
1005 priv
->InitialGainBackUp
= priv
->InitialGain
;
1007 priv
->InitialGain
++;
1008 printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv
->InitialGain
, priv
->CurrentOperaRate
);
1009 UpdateInitialGain(dev
);
1014 //Record the related info
1015 priv
->LastRetryRate
= CurrRetryRate
;
1016 priv
->LastTxThroughput
= TxThroughput
;
1017 priv
->ieee80211
->rate
= priv
->CurrentOperaRate
* 5;
1020 void rtl8180_rate_adapter(struct work_struct
*work
)
1022 struct delayed_work
*dwork
= to_delayed_work(work
);
1023 struct ieee80211_device
*ieee
= container_of(dwork
, struct ieee80211_device
, rate_adapter_wq
);
1024 struct net_device
*dev
= ieee
->dev
;
1025 //struct r8180_priv *priv = ieee80211_priv(dev);
1026 // DMESG("---->rtl8180_rate_adapter");
1027 StaRateAdaptive87SE(dev
);
1028 // DMESG("<----rtl8180_rate_adapter");
1030 void timer_rate_adaptive(unsigned long data
)
1032 struct r8180_priv
*priv
= ieee80211_priv((struct net_device
*)data
);
1033 //DMESG("---->timer_rate_adaptive()\n");
1035 // DMESG("<----timer_rate_adaptive():driver is not up!\n");
1038 if ((priv
->ieee80211
->iw_mode
!= IW_MODE_MASTER
)
1039 && (priv
->ieee80211
->state
== IEEE80211_LINKED
) &&
1040 (priv
->ForcedDataRate
== 0)) {
1041 // DMESG("timer_rate_adaptive():schedule rate_adapter_wq\n");
1042 queue_work(priv
->ieee80211
->wq
, (void *)&priv
->ieee80211
->rate_adapter_wq
);
1043 // StaRateAdaptive87SE((struct net_device *)data);
1045 priv
->rateadapter_timer
.expires
= jiffies
+ MSECS(priv
->RateAdaptivePeriod
);
1046 add_timer(&priv
->rateadapter_timer
);
1047 //DMESG("<----timer_rate_adaptive()\n");
1050 void SwAntennaDiversityRxOk8185(struct net_device
*dev
, u8 SignalStrength
)
1052 struct r8180_priv
*priv
= (struct r8180_priv
*)ieee80211_priv(dev
);
1054 // printk("+SwAntennaDiversityRxOk8185: RxSs: %d\n", SignalStrength);
1058 if (priv
->AdRxSignalStrength
!= -1) {
1059 priv
->AdRxSignalStrength
= ((priv
->AdRxSignalStrength
* 7) + (SignalStrength
* 3)) / 10;
1060 } else { // Initialization case.
1061 priv
->AdRxSignalStrength
= SignalStrength
;
1064 if (priv
->LastRxPktAntenna
) //Main antenna.
1065 priv
->AdMainAntennaRxOkCnt
++;
1066 else // Aux antenna.
1067 priv
->AdAuxAntennaRxOkCnt
++;
1069 // printk("-SwAntennaDiversityRxOk8185: AdRxOkCnt: %d AdRxSignalStrength: %d\n", priv->AdRxOkCnt, priv->AdRxSignalStrength);
1073 // Change Antenna Switch.
1075 bool SetAntenna8185(struct net_device
*dev
, u8 u1bAntennaIndex
)
1077 struct r8180_priv
*priv
= (struct r8180_priv
*)ieee80211_priv(dev
);
1078 bool bAntennaSwitched
= false;
1080 // printk("+SetAntenna8185(): Antenna is switching to: %d \n", u1bAntennaIndex);
1082 switch (u1bAntennaIndex
) {
1084 /* Mac register, main antenna */
1085 write_nic_byte(dev
, ANTSEL
, 0x03);
1087 write_phy_cck(dev
, 0x11, 0x9b); /* Config CCK RX antenna. */
1088 write_phy_ofdm(dev
, 0x0d, 0x5c); /* Config OFDM RX antenna. */
1090 bAntennaSwitched
= true;
1094 /* Mac register, aux antenna */
1095 write_nic_byte(dev
, ANTSEL
, 0x00);
1097 write_phy_cck(dev
, 0x11, 0xbb); /* Config CCK RX antenna. */
1098 write_phy_ofdm(dev
, 0x0d, 0x54); /* Config OFDM RX antenna. */
1100 bAntennaSwitched
= true;
1105 printk("SetAntenna8185: unknown u1bAntennaIndex(%d)\n", u1bAntennaIndex
);
1109 if(bAntennaSwitched
)
1110 priv
->CurrAntennaIndex
= u1bAntennaIndex
;
1112 // printk("-SetAntenna8185(): return (%#X)\n", bAntennaSwitched);
1114 return bAntennaSwitched
;
1118 // Toggle Antenna switch.
1120 bool SwitchAntenna(struct net_device
*dev
)
1122 struct r8180_priv
*priv
= (struct r8180_priv
*)ieee80211_priv(dev
);
1126 if (priv
->CurrAntennaIndex
== 0) {
1127 bResult
= SetAntenna8185(dev
, 1);
1129 // printk("SwitchAntenna(): switching to antenna 1 ......\n");
1130 // bResult = SetAntenna8185(dev, 1);//-by amy 080312
1132 bResult
= SetAntenna8185(dev
, 0);
1134 // printk("SwitchAntenna(): switching to antenna 0 ......\n");
1135 // bResult = SetAntenna8185(dev, 0);//-by amy 080312
1142 // Engine of SW Antenna Diversity mechanism.
1143 // Since 8187 has no Tx part information,
1144 // this implementation is only dependend on Rx part information.
1146 // 2006.04.17, by rcnjko.
1148 void SwAntennaDiversity(struct net_device
*dev
)
1150 struct r8180_priv
*priv
= (struct r8180_priv
*)ieee80211_priv(dev
);
1151 bool bSwCheckSS
= false;
1152 // printk("+SwAntennaDiversity(): CurrAntennaIndex: %d\n", priv->CurrAntennaIndex);
1153 // printk("AdTickCount is %d\n",priv->AdTickCount);
1156 priv
->AdTickCount
++;
1158 printk("(1) AdTickCount: %d, AdCheckPeriod: %d\n",
1159 priv
->AdTickCount
, priv
->AdCheckPeriod
);
1160 printk("(2) AdRxSignalStrength: %ld, AdRxSsThreshold: %ld\n",
1161 priv
->AdRxSignalStrength
, priv
->AdRxSsThreshold
);
1163 // priv->AdTickCount++;//-by amy 080312
1166 if (priv
->ieee80211
->state
!= IEEE80211_LINKED
) {
1167 // printk("SwAntennaDiversity(): Case 1. No Link.\n");
1169 priv
->bAdSwitchedChecking
= false;
1170 // I switch antenna here to prevent any one of antenna is broken before link established, 2006.04.18, by rcnjko..
1173 // Case 2. Linked but no packet receive.d
1174 } else if (priv
->AdRxOkCnt
== 0) {
1175 // printk("SwAntennaDiversity(): Case 2. Linked but no packet received.\n");
1177 priv
->bAdSwitchedChecking
= false;
1180 // Case 3. Evaluate last antenna switch action and undo it if necessary.
1181 } else if (priv
->bAdSwitchedChecking
== true) {
1182 // printk("SwAntennaDiversity(): Case 3. Evaluate last antenna switch action.\n");
1184 priv
->bAdSwitchedChecking
= false;
1186 // Adjust Rx signal strength threshold.
1187 priv
->AdRxSsThreshold
= (priv
->AdRxSignalStrength
+ priv
->AdRxSsBeforeSwitched
) / 2;
1189 priv
->AdRxSsThreshold
= (priv
->AdRxSsThreshold
> priv
->AdMaxRxSsThreshold
) ?
1190 priv
->AdMaxRxSsThreshold
: priv
->AdRxSsThreshold
;
1191 if(priv
->AdRxSignalStrength
< priv
->AdRxSsBeforeSwitched
) {
1192 // Rx signal strength is not improved after we swtiched antenna. => Swich back.
1193 // printk("SwAntennaDiversity(): Rx Signal Strength is not improved, CurrRxSs: %d, LastRxSs: %d\n",
1194 // priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);
1196 // Increase Antenna Diversity checking period due to bad decision.
1197 priv
->AdCheckPeriod
*= 2;
1199 // Increase Antenna Diversity checking period.
1200 if (priv
->AdCheckPeriod
> priv
->AdMaxCheckPeriod
)
1201 priv
->AdCheckPeriod
= priv
->AdMaxCheckPeriod
;
1203 // Wrong deceision => switch back.
1206 // Rx Signal Strength is improved.
1207 // printk("SwAntennaDiversity(): Rx Signal Strength is improved, CurrRxSs: %d, LastRxSs: %d\n",
1208 // priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);
1210 // Reset Antenna Diversity checking period to its min value.
1211 priv
->AdCheckPeriod
= priv
->AdMinCheckPeriod
;
1214 // printk("SwAntennaDiversity(): AdRxSsThreshold: %d, AdCheckPeriod: %d\n",
1215 // priv->AdRxSsThreshold, priv->AdCheckPeriod);
1217 // Case 4. Evaluate if we shall switch antenna now.
1218 // Cause Table Speed is very fast in TRC Dell Lab, we check it every time.
1219 else { // if(priv->AdTickCount >= priv->AdCheckPeriod)//-by amy 080312
1220 // printk("SwAntennaDiversity(): Case 4. Evaluate if we shall switch antenna now.\n");
1222 priv
->AdTickCount
= 0;
1225 // <Roger_Notes> We evaluate RxOk counts for each antenna first and than
1226 // evaluate signal strength.
1227 // The following operation can overcome the disability of CCA on both two antennas
1228 // When signal strength was extremely low or high.
1233 // Evaluate RxOk count from each antenna if we shall switch default antenna now.
1234 // Added by Roger, 2008.02.21.
1236 if ((priv
->AdMainAntennaRxOkCnt
< priv
->AdAuxAntennaRxOkCnt
)
1237 && (priv
->CurrAntennaIndex
== 0)) {
1238 // We set Main antenna as default but RxOk count was less than Aux ones.
1240 // printk("SwAntennaDiversity(): Main antenna RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
1241 // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
1243 // Switch to Aux antenna.
1245 priv
->bHWAdSwitched
= true;
1246 } else if ((priv
->AdAuxAntennaRxOkCnt
< priv
->AdMainAntennaRxOkCnt
)
1247 && (priv
->CurrAntennaIndex
== 1)) {
1248 // We set Aux antenna as default but RxOk count was less than Main ones.
1250 // printk("SwAntennaDiversity(): Aux antenna RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
1251 // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
1253 // Switch to Main antenna.
1255 priv
->bHWAdSwitched
= true;
1257 // Default antenna is better.
1259 // printk("SwAntennaDiversity(): Default antenna is better., AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
1260 // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
1262 // Still need to check current signal strength.
1263 priv
->bHWAdSwitched
= false;
1266 // <Roger_Notes> We evaluate Rx signal strength ONLY when default antenna
1267 // didn't changed by HW evaluation.
1270 // [TRC Dell Lab] SignalStrength is inaccuracy. Isaiah 2008-03-05
1271 // For example, Throughput of aux is better than main antenna(about 10M v.s 2M),
1272 // but AdRxSignalStrength is less than main.
1273 // Our guess is that main antenna have lower throughput and get many change
1274 // to receive more CCK packets(ex.Beacon) which have stronger SignalStrength.
1276 if ((!priv
->bHWAdSwitched
) && (bSwCheckSS
)) {
1278 // Evaluate Rx signal strength if we shall switch antenna now.
1279 if (priv
->AdRxSignalStrength
< priv
->AdRxSsThreshold
) {
1280 // Rx signal strength is weak => Switch Antenna.
1281 // printk("SwAntennaDiversity(): Rx Signal Strength is weak, CurrRxSs: %d, RxSsThreshold: %d\n",
1282 // priv->AdRxSignalStrength, priv->AdRxSsThreshold);
1284 priv
->AdRxSsBeforeSwitched
= priv
->AdRxSignalStrength
;
1285 priv
->bAdSwitchedChecking
= true;
1289 // Rx signal strength is OK.
1290 // printk("SwAntennaDiversity(): Rx Signal Strength is OK, CurrRxSs: %d, RxSsThreshold: %d\n",
1291 // priv->AdRxSignalStrength, priv->AdRxSsThreshold);
1293 priv
->bAdSwitchedChecking
= false;
1294 // Increase Rx signal strength threshold if necessary.
1295 if ((priv
->AdRxSignalStrength
> (priv
->AdRxSsThreshold
+ 10)) && // Signal is much stronger than current threshold
1296 priv
->AdRxSsThreshold
<= priv
->AdMaxRxSsThreshold
) { // Current threhold is not yet reach upper limit.
1298 priv
->AdRxSsThreshold
= (priv
->AdRxSsThreshold
+ priv
->AdRxSignalStrength
) / 2;
1299 priv
->AdRxSsThreshold
= (priv
->AdRxSsThreshold
> priv
->AdMaxRxSsThreshold
) ?
1300 priv
->AdMaxRxSsThreshold
: priv
->AdRxSsThreshold
;//+by amy 080312
1303 // Reduce Antenna Diversity checking period if possible.
1304 if (priv
->AdCheckPeriod
> priv
->AdMinCheckPeriod
)
1305 priv
->AdCheckPeriod
/= 2;
1310 // Reset antenna diversity Rx related statistics.
1311 priv
->AdRxOkCnt
= 0;
1312 priv
->AdMainAntennaRxOkCnt
= 0;
1313 priv
->AdAuxAntennaRxOkCnt
= 0;
1316 // priv->AdRxOkCnt = 0;//-by amy 080312
1318 // printk("-SwAntennaDiversity()\n");
1323 // Return TRUE if we shall perform Tx Power Tracking Mecahnism, FALSE otherwise.
1325 bool CheckTxPwrTracking(struct net_device
*dev
)
1327 struct r8180_priv
*priv
= (struct r8180_priv
*)ieee80211_priv(dev
);
1329 if (!priv
->bTxPowerTrack
)
1332 //lzm reserved 080826
1333 //if(priv->bScanInProgress)
1338 //if 87SE is in High Power , don't do Tx Power Tracking. asked by SD3 ED. 2008-08-08 Isaiah
1339 if (priv
->bToUpdateTxPwr
)
1348 // Timer callback function of SW Antenna Diversity.
1350 void SwAntennaDiversityTimerCallback(struct net_device
*dev
)
1352 struct r8180_priv
*priv
= (struct r8180_priv
*)ieee80211_priv(dev
);
1353 RT_RF_POWER_STATE rtState
;
1355 //printk("+SwAntennaDiversityTimerCallback()\n");
1358 // We do NOT need to switch antenna while RF is off.
1359 // 2007.05.09, added by Roger.
1361 rtState
= priv
->eRFPowerState
;
1363 if (rtState
== eRfOff
) {
1364 // printk("SwAntennaDiversityTimer - RF is OFF.\n");
1366 } else if (rtState
== eRfSleep
) {
1367 // Don't access BB/RF under Disable PLL situation.
1368 //RT_TRACE((COMP_RF|COMP_ANTENNA), DBG_LOUD, ("SwAntennaDiversityTimerCallback(): RF is Sleep => skip it\n"));
1371 SwAntennaDiversity(dev
);
1376 priv
->SwAntennaDiversityTimer
.expires
= jiffies
+ MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD
);
1377 add_timer(&priv
->SwAntennaDiversityTimer
);
1380 //printk("-SwAntennaDiversityTimerCallback()\n");