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