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