Staging: rtl8187se: r8180_dm.c: Fix spacing issues
[linux-2.6/libata-dev.git] / drivers / staging / rtl8187se / r8180_dm.c
blob02bffa9bddc7ef0969c58dee044643312222b741
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)
20 return false;
22 if(ieee->state == IEEE80211_LINKED_SCANNING)
23 return false;
25 return true;
29 // Description:
30 // Update Tx power level if necessary.
31 // See also DoRxHighPower() and SetTxPowerLevel8185() for reference.
33 // Note:
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);
42 u16 HiPwrUpperTh = 0;
43 u16 HiPwrLowerTh = 0;
44 u8 RSSIHiPwrUpperTh;
45 u8 RSSIHiPwrLowerTh;
46 u8 u1bTmp;
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;
59 //lzm add 080826
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;
88 //SD3 required.
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");
110 // Description:
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");
126 DoTxHighPower(dev);
128 // printk("<---- UpdateTxPowerWorkItemCallback()\n");
133 // Description:
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)
142 return false;
144 if (ieee->state != IEEE80211_LINKED)
145 return false;
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.
149 return false;
150 return true;
153 // Description:
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);
169 OfdmFA1 = 0x15;
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
181 OfdmFA1 = 0x20;
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));
194 } else {
195 ;//RT_TRACE(COMP_DIG, DBG_WARNING, ("ERROR!! AwakePeriodIn2Sec should not be ZERO!!\n"));
197 #endif
199 InitialGainStep = 8;
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;
218 } else {
219 if (priv->DIG_NumberFallbackVote)
220 priv->DIG_NumberFallbackVote--;
222 priv->DIG_NumberUpgradeVote = 0;
223 } else {
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");
247 // Description:
248 // Dispatch DIG implementation according to RF.
250 void DynamicInitGain(struct net_device *dev)
252 DIG_Zebra(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)
273 u8 rate_len;
274 u8 rate_ex_len;
275 u8 RateMask = 0x7F;
276 u8 idx;
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) {
284 Found = 1;
285 goto found_rate;
288 for (idx = 0; idx < rate_ex_len; idx++) {
289 if ((priv->ieee80211->current_network.rates_ex[idx] & RateMask) == NaiveTxRate) {
290 Found = 1;
291 goto found_rate;
294 return Found;
295 found_rate:
296 return Found;
300 // Description:
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);
308 u8 UpRate;
310 // Upgrade 1 degree.
311 switch (rate) {
312 case 108: // Up to 54Mbps.
313 UpRate = 108;
314 break;
316 case 96: // Up to 54Mbps.
317 UpRate = 108;
318 break;
320 case 72: // Up to 48Mbps.
321 UpRate = 96;
322 break;
324 case 48: // Up to 36Mbps.
325 UpRate = 72;
326 break;
328 case 36: // Up to 24Mbps.
329 UpRate = 48;
330 break;
332 case 22: // Up to 18Mbps.
333 UpRate = 36;
334 break;
336 case 11: // Up to 11Mbps.
337 UpRate = 22;
338 break;
340 case 4: // Up to 5.5Mbps.
341 UpRate = 11;
342 break;
344 case 2: // Up to 2Mbps.
345 UpRate = 4;
346 break;
348 default:
349 printk("GetUpgradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
350 return 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);
355 return UpRate;
356 } else {
357 //printk("GetUpgradeTxRate(): Tx rate (%d) is not in supported rates\n", UpRate);
358 return rate;
360 return rate;
363 // Description:
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);
371 u8 DownRate;
373 // Upgrade 1 degree.
374 switch (rate) {
375 case 108: // Down to 48Mbps.
376 DownRate = 96;
377 break;
379 case 96: // Down to 36Mbps.
380 DownRate = 72;
381 break;
383 case 72: // Down to 24Mbps.
384 DownRate = 48;
385 break;
387 case 48: // Down to 18Mbps.
388 DownRate = 36;
389 break;
391 case 36: // Down to 11Mbps.
392 DownRate = 22;
393 break;
395 case 22: // Down to 5.5Mbps.
396 DownRate = 11;
397 break;
399 case 11: // Down to 2Mbps.
400 DownRate = 4;
401 break;
403 case 4: // Down to 1Mbps.
404 DownRate = 2;
405 break;
407 case 2: // Down to 1Mbps.
408 DownRate = 2;
409 break;
411 default:
412 printk("GetDegradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
413 return 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);
418 return DownRate;
419 } else {
420 //printk("GetDegradeTxRate(): Tx rate (%d) is not in supported rates\n", DownRate);
421 return rate;
423 return rate;
426 // Helper function to determine if specified data rate is
427 // CCK rate.
428 // 2005.01.25, by rcnjko.
430 bool MgntIsCckRate(u16 rate)
432 bool bReturn = false;
434 if ((rate <= 22) && (rate != 12) && (rate != 18)) {
435 bReturn = true;
438 return bReturn;
441 // Description:
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;
450 //u32 u4bRfReg;
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)
474 OfdmTxPwrIdx = 35;
475 } else {
476 // lower thermal meter.
477 CckTxPwrIdx -= (priv->ThermalMeter - CurrentThermal) * 2;
478 OfdmTxPwrIdx -= (priv->ThermalMeter - CurrentThermal) * 2;
480 if (CckTxPwrIdx < 0)
481 CckTxPwrIdx = 0;
482 if (OfdmTxPwrIdx < 0)
483 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;
500 u16 CurrRetryCnt;
501 u16 CurrRetryRate;
502 //u16 i,idx;
503 unsigned long CurrRxokCnt;
504 bool bTryUp = false;
505 bool bTryDown = false;
506 u8 TryUpTh = 1;
507 u8 TryDownTh = 2;
508 u32 TxThroughput;
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);
528 } else {
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);
563 // Reset Fail Record
564 priv->LastFailTxRate = 0;
565 priv->LastFailTxRateSS = -200;
566 priv->FailTxRateCount = 0;
568 goto SetInitialGain;
569 } else {
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
584 // and retry rate.
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.
593 // 11Mbps or 36Mbps
594 // Check more times in these rate(key rates).
596 if (priv->CurrentOperaRate == 22 || priv->CurrentOperaRate == 72)
597 TryUpTh += 9;
599 // Let these rates down more difficult.
601 if (MgntIsCckRate(priv->CurrentOperaRate) || priv->CurrentOperaRate == 36)
602 TryDownTh += 1;
604 //1 Adjust Rate.
605 if (priv->bTryuping == true) {
606 //2 For Test Upgrading mechanism
607 // Note:
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.
615 bTryDown = true;
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);
619 } else {
620 priv->bTryuping = false;
622 } else if (CurrSignalStrength > -47 && (CurrRetryRate < 50)) {
623 //2For High Power
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) {
632 bTryUp = true;
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.
643 bTryDown = true;
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) {
648 //2For 54Mbps
649 // Air Link
650 if ((CurrRetryRate > 26) && (priv->LastRetryRate > 25)) {
651 // if ((CurrRetryRate>40)&&(priv->LastRetryRate>39))
652 //Down to rate 48Mbps.
653 bTryDown = true;
655 // Cable Link
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.
659 bTryDown = true;
662 if (bTryDown && (CurrSignalStrength < -75)) //cable link
663 priv->TryDownCountLowData += TryDownTh;
664 //printk("case4---54M \n");
667 else if (priv->CurrentOperaRate == 96) {
668 //2For 48Mbps
669 //Air Link
670 if (((CurrRetryRate > 48) && (priv->LastRetryRate > 47))) {
671 // if ( ((CurrRetryRate>65) && (priv->LastRetryRate>64)))
672 //Down to rate 36Mbps.
673 bTryDown = true;
674 } else if (((CurrRetryRate > 21) && (priv->LastRetryRate > 20)) && (CurrSignalStrength > -74)) { //Cable Link
675 //Down to rate 36Mbps.
676 bTryDown = true;
677 } else if ((CurrRetryRate > (priv->LastRetryRate + 50)) && (priv->FailTxRateCount > 2)) {
678 // else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
679 bTryDown = true;
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) )
683 bTryUp = true;
686 if (bTryDown && (CurrSignalStrength < -75)){
687 priv->TryDownCountLowData += TryDownTh;
689 //printk("case5---48M \n");
690 } else if (priv->CurrentOperaRate == 72) {
691 //2For 36Mbps
692 if ((CurrRetryRate > 43) && (priv->LastRetryRate > 41)) {
693 // if ( (CurrRetryRate>60) && (priv->LastRetryRate>59))
694 //Down to rate 24Mbps.
695 bTryDown = true;
696 } else if ((CurrRetryRate > (priv->LastRetryRate + 50)) && (priv->FailTxRateCount > 2)) {
697 // else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
698 bTryDown = true;
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))
702 bTryUp = true;
705 if (bTryDown && (CurrSignalStrength < -80))
706 priv->TryDownCountLowData += TryDownTh;
708 //printk("case6---36M \n");
709 } else if (priv->CurrentOperaRate == 48) {
710 //2For 24Mbps
711 // Air Link
712 if (((CurrRetryRate > 63) && (priv->LastRetryRate > 62))) {
713 // if ( ((CurrRetryRate>83) && (priv->LastRetryRate>82)))
714 //Down to rate 18Mbps.
715 bTryDown = true;
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.
719 bTryDown = true;
720 } else if ((CurrRetryRate > (priv->LastRetryRate + 50)) && (priv->FailTxRateCount > 2 )) {
721 // else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
722 bTryDown = true;
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))
726 bTryUp = true;
729 if (bTryDown && (CurrSignalStrength < -82))
730 priv->TryDownCountLowData += TryDownTh;
732 //printk("case7---24M \n");
733 } else if (priv->CurrentOperaRate == 36) {
734 //2For 18Mbps
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.
741 bTryDown = true;
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 ))
746 bTryDown = true;
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))
750 bTryUp = true;
752 //printk("case8---18M \n");
753 } else if (priv->CurrentOperaRate == 22) {
754 //2For 11Mbps
755 if (CurrRetryRate > 95) {
756 // if (CurrRetryRate>155)
757 bTryDown = true;
759 else if ((CurrRetryRate < 29) && (priv->LastRetryRate < 30)) { //TO DO: need to consider (RSSI)
760 // else if ( (CurrRetryRate<49) && (priv->LastRetryRate <50) )
761 bTryUp = true;
763 //printk("case9---11M \n");
764 } else if (priv->CurrentOperaRate == 11) {
765 //2For 5.5Mbps
766 if (CurrRetryRate > 149) {
767 // if (CurrRetryRate>189)
768 bTryDown = true;
769 } else if ((CurrRetryRate < 60) && (priv->LastRetryRate < 65)) {
770 // else if ( (CurrRetryRate<80) && (priv->LastRetryRate < 85))
771 bTryUp = true;
773 //printk("case10---5.5M \n");
774 } else if (priv->CurrentOperaRate == 4) {
775 //2For 2 Mbps
776 if ((CurrRetryRate > 99) && (priv->LastRetryRate > 99)) {
777 // if((CurrRetryRate>199) && (priv->LastRetryRate>199))
778 bTryDown = true;
779 } else if ((CurrRetryRate < 65) && (priv->LastRetryRate < 70)) {
780 // else if ( (CurrRetryRate < 85) && (priv->LastRetryRate < 90))
781 bTryUp = true;
783 //printk("case11---2M \n");
784 } else if (priv->CurrentOperaRate == 2) {
785 //2For 1 Mbps
786 if ((CurrRetryRate < 70) && (priv->LastRetryRate < 75)) {
787 // if( (CurrRetryRate<90) && (priv->LastRetryRate<95))
788 bTryUp = true;
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) {
802 bTryUp = true;
803 priv->bTryuping = true;
804 //printk("StaRateAdaptive87SE(): Randomly try upgrading...\n");
808 //1 Rate Mechanism
809 if (bTryUp) {
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.
865 } else {
866 if (priv->TryupingCount > 0)
867 priv->TryupingCount --;
870 if (bTryDown) {
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;
889 } else {
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);
922 } else {
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".
984 SetInitialGain:
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;
997 else
998 priv->InitialGain--;
1000 printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate);
1001 UpdateInitialGain(dev);
1003 } else { // OFDM
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");
1034 if (!priv->up) {
1035 // DMESG("<----timer_rate_adaptive():driver is not up!\n");
1036 return;
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");
1049 //by amy 080312}
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);
1056 priv->AdRxOkCnt++;
1058 if (priv->AdRxSignalStrength != -1) {
1059 priv->AdRxSignalStrength = ((priv->AdRxSignalStrength * 7) + (SignalStrength * 3)) / 10;
1060 } else { // Initialization case.
1061 priv->AdRxSignalStrength = SignalStrength;
1063 //{+by amy 080312
1064 if (priv->LastRxPktAntenna) //Main antenna.
1065 priv->AdMainAntennaRxOkCnt++;
1066 else // Aux antenna.
1067 priv->AdAuxAntennaRxOkCnt++;
1068 //+by amy 080312
1069 // printk("-SwAntennaDiversityRxOk8185: AdRxOkCnt: %d AdRxSignalStrength: %d\n", priv->AdRxOkCnt, priv->AdRxSignalStrength);
1072 // Description:
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) {
1083 case 0:
1084 /* Mac register, main antenna */
1085 write_nic_byte(dev, ANTSEL, 0x03);
1086 /* base band */
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;
1091 break;
1093 case 1:
1094 /* Mac register, aux antenna */
1095 write_nic_byte(dev, ANTSEL, 0x00);
1096 /* base band */
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;
1102 break;
1104 default:
1105 printk("SetAntenna8185: unknown u1bAntennaIndex(%d)\n", u1bAntennaIndex);
1106 break;
1109 if(bAntennaSwitched)
1110 priv->CurrAntennaIndex = u1bAntennaIndex;
1112 // printk("-SetAntenna8185(): return (%#X)\n", bAntennaSwitched);
1114 return bAntennaSwitched;
1117 // Description:
1118 // Toggle Antenna switch.
1120 bool SwitchAntenna(struct net_device *dev)
1122 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1124 bool bResult;
1126 if (priv->CurrAntennaIndex == 0) {
1127 bResult = SetAntenna8185(dev, 1);
1128 //by amy 080312
1129 // printk("SwitchAntenna(): switching to antenna 1 ......\n");
1130 // bResult = SetAntenna8185(dev, 1);//-by amy 080312
1131 } else {
1132 bResult = SetAntenna8185(dev, 0);
1133 //by amy 080312
1134 // printk("SwitchAntenna(): switching to antenna 0 ......\n");
1135 // bResult = SetAntenna8185(dev, 0);//-by amy 080312
1138 return bResult;
1141 // Description:
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);
1154 //by amy 080312
1155 if (bSwCheckSS) {
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
1165 // Case 1. No Link.
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..
1171 SwitchAntenna(dev);
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;
1178 SwitchAntenna(dev);
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);
1195 //by amy 080312
1196 // Increase Antenna Diversity checking period due to bad decision.
1197 priv->AdCheckPeriod *= 2;
1198 //by amy 080312
1199 // Increase Antenna Diversity checking period.
1200 if (priv->AdCheckPeriod > priv->AdMaxCheckPeriod)
1201 priv->AdCheckPeriod = priv->AdMaxCheckPeriod;
1203 // Wrong deceision => switch back.
1204 SwitchAntenna(dev);
1205 } else {
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.
1229 // 2008.01.30.
1233 // Evaluate RxOk count from each antenna if we shall switch default antenna now.
1234 // Added by Roger, 2008.02.21.
1235 //{by amy 080312
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.
1244 SwitchAntenna(dev);
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.
1254 SwitchAntenna(dev);
1255 priv->bHWAdSwitched = true;
1256 } else {
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.
1268 // 2008.02.27.
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)) {
1277 //by amy 080312}
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;
1287 SwitchAntenna(dev);
1288 } else {
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;
1309 //by amy 080312
1310 // Reset antenna diversity Rx related statistics.
1311 priv->AdRxOkCnt = 0;
1312 priv->AdMainAntennaRxOkCnt = 0;
1313 priv->AdAuxAntennaRxOkCnt = 0;
1314 //by amy 080312
1316 // priv->AdRxOkCnt = 0;//-by amy 080312
1318 // printk("-SwAntennaDiversity()\n");
1322 // Description:
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)
1330 return false;
1332 //lzm reserved 080826
1333 //if(priv->bScanInProgress)
1335 // return false;
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)
1340 return false;
1342 return true;
1347 // Description:
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;
1362 do {
1363 if (rtState == eRfOff) {
1364 // printk("SwAntennaDiversityTimer - RF is OFF.\n");
1365 break;
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"));
1369 break;
1371 SwAntennaDiversity(dev);
1373 } while (false);
1375 if (priv->up) {
1376 priv->SwAntennaDiversityTimer.expires = jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD);
1377 add_timer(&priv->SwAntennaDiversityTimer);
1380 //printk("-SwAntennaDiversityTimerCallback()\n");