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