1
2#include "r8180_dm.h"
3#include "r8180_hw.h"
4#include "r8180_93cx6.h"
5
6
7
8
9
10
11
12#define RATE_ADAPTIVE_TIMER_PERIOD 300
13
14bool 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
34
35
36
37
38
39
40
41
42
43void
44DoTxHighPower(
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
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
67 OfdmTxPwrIdx = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel];
68 CckTxPwrIdx = priv->chtxpwr[priv->ieee80211->current_network.channel];
69
70
71
72 if((priv->UndecoratedSmoothedSS > HiPwrUpperTh) ||
73 (priv->bCurCCKPkt && (priv->CurCCKRSSI > RSSIHiPwrUpperTh)))
74 {
75
76
77
78 priv->bToUpdateTxPwr = true;
79 u1bTmp= read_nic_byte(dev, CCK_TXAGC);
80
81
82 if( CckTxPwrIdx == u1bTmp)
83 {
84 u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0;
85 write_nic_byte(dev, CCK_TXAGC, u1bTmp);
86
87 u1bTmp= read_nic_byte(dev, OFDM_TXAGC);
88 u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0;
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
97 if(priv->bToUpdateTxPwr)
98 {
99 priv->bToUpdateTxPwr = false;
100
101 u1bTmp= read_nic_byte(dev, CCK_TXAGC);
102 if(u1bTmp < CckTxPwrIdx)
103 {
104
105
106 write_nic_byte(dev, CCK_TXAGC, CckTxPwrIdx);
107 }
108
109 u1bTmp= read_nic_byte(dev, OFDM_TXAGC);
110 if(u1bTmp < OfdmTxPwrIdx)
111 {
112
113
114 write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);
115 }
116 }
117 }
118
119
120}
121
122
123
124
125
126
127
128
129void rtl8180_tx_pw_wq (struct work_struct *work)
130{
131
132
133
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
139
140 DoTxHighPower(dev);
141
142
143}
144
145
146
147
148
149
150bool
151CheckDig(
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
165 if((priv->ieee80211->rate/5) < 36)
166 return false;
167 return true;
168}
169
170
171
172
173void
174DIG_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;
182 int LowestGainStage = 4;
183 u32 AwakePeriodIn2Sec=0;
184
185
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
193
194
195
196 if (priv->InitialGain == 0 )
197 {
198 priv->InitialGain = 4;
199 }
200 {
201 OfdmFA1 = 0x20;
202 }
203
204#if 1
205 AwakePeriodIn2Sec = (2000-priv ->DozePeriodInPast2Sec);
206
207 priv ->DozePeriodInPast2Sec=0;
208
209 if(AwakePeriodIn2Sec)
210 {
211
212
213 OfdmFA1 = (u16)((OfdmFA1*AwakePeriodIn2Sec) / 2000) ;
214 OfdmFA2 = (u16)((OfdmFA2*AwakePeriodIn2Sec) / 2000) ;
215
216 }
217 else
218 {
219 ;
220 }
221#endif
222
223 InitialGainStep = 8;
224 LowestGainStage = priv->RegBModeGainStage;
225
226 if (OFDMFalseAlarm > OfdmFA1)
227 {
228 if (OFDMFalseAlarm > OfdmFA2)
229 {
230 priv->DIG_NumberFallbackVote++;
231 if (priv->DIG_NumberFallbackVote >1)
232 {
233
234 if (priv->InitialGain < InitialGainStep)
235 {
236 priv->InitialGainBackUp= priv->InitialGain;
237
238 priv->InitialGain = (priv->InitialGain + 1);
239
240
241 UpdateInitialGain(dev);
242 }
243 priv->DIG_NumberFallbackVote = 0;
244 priv->DIG_NumberUpgradeVote=0;
245 }
246 }
247 else
248 {
249 if (priv->DIG_NumberFallbackVote)
250 priv->DIG_NumberFallbackVote--;
251 }
252 priv->DIG_NumberUpgradeVote=0;
253 }
254 else
255 {
256 if (priv->DIG_NumberFallbackVote)
257 priv->DIG_NumberFallbackVote--;
258 priv->DIG_NumberUpgradeVote++;
259
260 if (priv->DIG_NumberUpgradeVote>9)
261 {
262 if (priv->InitialGain > LowestGainStage)
263 {
264 priv->InitialGainBackUp= priv->InitialGain;
265
266 priv->InitialGain = (priv->InitialGain - 1);
267
268
269 UpdateInitialGain(dev);
270 }
271 priv->DIG_NumberFallbackVote = 0;
272 priv->DIG_NumberUpgradeVote=0;
273 }
274 }
275
276
277
278}
279
280
281
282
283
284void
285DynamicInitGain(struct net_device *dev)
286{
287 DIG_Zebra(dev);
288}
289
290void rtl8180_hw_dig_wq (struct work_struct *work)
291{
292 struct delayed_work *dwork = to_delayed_work(work);
293 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_dig_wq);
294 struct net_device *dev = ieee->dev;
295 struct r8180_priv *priv = ieee80211_priv(dev);
296
297
298 priv->FalseAlarmRegValue = read_nic_dword(dev, CCK_FALSE_ALARM);
299
300
301
302 DynamicInitGain(dev);
303
304}
305
306int
307IncludedInSupportedRates(
308 struct r8180_priv *priv,
309 u8 TxRate )
310{
311 u8 rate_len;
312 u8 rate_ex_len;
313 u8 RateMask = 0x7F;
314 u8 idx;
315 unsigned short Found = 0;
316 u8 NaiveTxRate = TxRate&RateMask;
317
318 rate_len = priv->ieee80211->current_network.rates_len;
319 rate_ex_len = priv->ieee80211->current_network.rates_ex_len;
320 for( idx=0; idx< rate_len; idx++ )
321 {
322 if( (priv->ieee80211->current_network.rates[idx] & RateMask) == NaiveTxRate )
323 {
324 Found = 1;
325 goto found_rate;
326 }
327 }
328 for( idx=0; idx< rate_ex_len; idx++ )
329 {
330 if( (priv->ieee80211->current_network.rates_ex[idx] & RateMask) == NaiveTxRate )
331 {
332 Found = 1;
333 goto found_rate;
334 }
335 }
336 return Found;
337 found_rate:
338 return Found;
339}
340
341
342
343
344
345
346
347u8
348GetUpgradeTxRate(
349 struct net_device *dev,
350 u8 rate
351 )
352{
353 struct r8180_priv *priv = ieee80211_priv(dev);
354 u8 UpRate;
355
356
357 switch(rate)
358 {
359 case 108:
360 UpRate = 108;
361 break;
362
363 case 96:
364 UpRate = 108;
365 break;
366
367 case 72:
368 UpRate = 96;
369 break;
370
371 case 48:
372 UpRate = 72;
373 break;
374
375 case 36:
376 UpRate = 48;
377 break;
378
379 case 22:
380 UpRate = 36;
381 break;
382
383 case 11:
384 UpRate = 22;
385 break;
386
387 case 4:
388 UpRate = 11;
389 break;
390
391 case 2:
392 UpRate = 4;
393 break;
394
395 default:
396 printk("GetUpgradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
397 return rate;
398 }
399
400 if(IncludedInSupportedRates(priv, UpRate))
401 {
402
403 return UpRate;
404 }
405 else
406 {
407
408 return rate;
409 }
410 return rate;
411}
412
413
414
415
416
417
418u8
419GetDegradeTxRate(
420 struct net_device *dev,
421 u8 rate
422 )
423{
424 struct r8180_priv *priv = ieee80211_priv(dev);
425 u8 DownRate;
426
427
428 switch(rate)
429 {
430 case 108:
431 DownRate = 96;
432 break;
433
434 case 96:
435 DownRate = 72;
436 break;
437
438 case 72:
439 DownRate = 48;
440 break;
441
442 case 48:
443 DownRate = 36;
444 break;
445
446 case 36:
447 DownRate = 22;
448 break;
449
450 case 22:
451 DownRate = 11;
452 break;
453
454 case 11:
455 DownRate = 4;
456 break;
457
458 case 4:
459 DownRate = 2;
460 break;
461
462 case 2:
463 DownRate = 2;
464 break;
465
466 default:
467 printk("GetDegradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
468 return rate;
469 }
470
471 if(IncludedInSupportedRates(priv, DownRate))
472 {
473
474 return DownRate;
475 }
476 else
477 {
478
479 return rate;
480 }
481 return rate;
482}
483
484
485
486
487
488bool
489MgntIsCckRate(
490 u16 rate
491 )
492{
493 bool bReturn = false;
494
495 if((rate <= 22) && (rate != 12) && (rate != 18))
496 {
497 bReturn = true;
498 }
499
500 return bReturn;
501}
502
503
504
505
506
507void
508TxPwrTracking87SE(
509 struct net_device *dev
510)
511{
512 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
513 u8 tmpu1Byte, CurrentThermal, Idx;
514 char CckTxPwrIdx, OfdmTxPwrIdx;
515
516
517 tmpu1Byte = read_nic_byte(dev, EN_LPF_CAL);
518 CurrentThermal = (tmpu1Byte & 0xf0)>>4;
519 CurrentThermal = (CurrentThermal>0x0c)? 0x0c:CurrentThermal;
520
521
522
523 if( CurrentThermal != priv->ThermalMeter)
524 {
525
526
527
528 for(Idx = 1; Idx<15; Idx++)
529 {
530 CckTxPwrIdx = priv->chtxpwr[Idx];
531 OfdmTxPwrIdx = priv->chtxpwr_ofdm[Idx];
532
533 if( CurrentThermal > priv->ThermalMeter )
534 {
535 CckTxPwrIdx += (CurrentThermal - priv->ThermalMeter)*2;
536 OfdmTxPwrIdx += (CurrentThermal - priv->ThermalMeter)*2;
537
538 if(CckTxPwrIdx >35)
539 CckTxPwrIdx = 35;
540 if(OfdmTxPwrIdx >35)
541 OfdmTxPwrIdx = 35;
542 }
543 else
544 {
545 CckTxPwrIdx -= (priv->ThermalMeter - CurrentThermal)*2;
546 OfdmTxPwrIdx -= (priv->ThermalMeter - CurrentThermal)*2;
547
548 if(CckTxPwrIdx <0)
549 CckTxPwrIdx = 0;
550 if(OfdmTxPwrIdx <0)
551 OfdmTxPwrIdx = 0;
552 }
553
554
555 priv->chtxpwr[Idx] = CckTxPwrIdx;
556 priv->chtxpwr_ofdm[Idx] = OfdmTxPwrIdx;
557 }
558
559
560 rtl8225z2_SetTXPowerLevel(dev, priv->ieee80211->current_network.channel);
561 }
562 priv->ThermalMeter = CurrentThermal;
563}
564void
565StaRateAdaptive87SE(
566 struct net_device *dev
567 )
568{
569 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
570 unsigned long CurrTxokCnt;
571 u16 CurrRetryCnt;
572 u16 CurrRetryRate;
573
574 unsigned long CurrRxokCnt;
575 bool bTryUp = false;
576 bool bTryDown = false;
577 u8 TryUpTh = 1;
578 u8 TryDownTh = 2;
579 u32 TxThroughput;
580 long CurrSignalStrength;
581 bool bUpdateInitialGain = false;
582 u8 u1bOfdm=0, u1bCck = 0;
583 char OfdmTxPwrIdx, CckTxPwrIdx;
584
585 priv->RateAdaptivePeriod= RATE_ADAPTIVE_TIMER_PERIOD;
586
587
588 CurrRetryCnt = priv->CurrRetryCnt;
589 CurrTxokCnt = priv->NumTxOkTotal - priv->LastTxokCnt;
590 CurrRxokCnt = priv->ieee80211->NumRxOkTotal - priv->LastRxokCnt;
591 CurrSignalStrength = priv->Stats_RecvSignalPower;
592 TxThroughput = (u32)(priv->NumTxOkBytesTotal - priv->LastTxOKBytes);
593 priv->LastTxOKBytes = priv->NumTxOkBytesTotal;
594 priv->CurrentOperaRate = priv->ieee80211->rate/5;
595
596
597 if (CurrTxokCnt>0)
598 {
599 CurrRetryRate = (u16)(CurrRetryCnt*100/CurrTxokCnt);
600 }
601 else
602 {
603 CurrRetryRate = (u16)(CurrRetryCnt*100/1);
604 }
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619 priv->LastRetryCnt = priv->CurrRetryCnt;
620 priv->LastTxokCnt = priv->NumTxOkTotal;
621 priv->LastRxokCnt = priv->ieee80211->NumRxOkTotal;
622 priv->CurrRetryCnt = 0;
623
624
625 if (CurrRetryRate==0 && CurrTxokCnt == 0)
626 {
627
628
629
630 priv->TryupingCountNoData++;
631
632
633
634 if (priv->TryupingCountNoData>30)
635 {
636 priv->TryupingCountNoData = 0;
637 priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
638
639 priv->LastFailTxRate = 0;
640 priv->LastFailTxRateSS = -200;
641 priv->FailTxRateCount = 0;
642 }
643 goto SetInitialGain;
644 }
645 else
646 {
647 priv->TryupingCountNoData=0;
648 }
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673 if(priv->CurrentOperaRate == 22 || priv->CurrentOperaRate == 72)
674 {
675 TryUpTh += 9;
676 }
677
678
679
680 if(MgntIsCckRate(priv->CurrentOperaRate) || priv->CurrentOperaRate == 36)
681 {
682 TryDownTh += 1;
683 }
684
685
686 if (priv->bTryuping == true)
687 {
688
689
690
691
692
693
694
695 if ( (CurrRetryRate > 25) && TxThroughput < priv->LastTxThroughput)
696 {
697
698 bTryDown = true;
699
700
701
702 }
703 else
704 {
705 priv->bTryuping = false;
706 }
707 }
708 else if (CurrSignalStrength > -47 && (CurrRetryRate < 50))
709 {
710
711
712
713
714
715
716
717
718 if(priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate )
719 {
720 bTryUp = true;
721
722 priv->TryupingCount += TryUpTh;
723 }
724
725
726 }
727 else if(CurrTxokCnt > 9 && CurrTxokCnt< 100 && CurrRetryRate >= 600)
728 {
729
730
731
732
733 bTryDown = true;
734
735 priv->TryDownCountLowData += TryDownTh;
736
737 }
738 else if ( priv->CurrentOperaRate == 108 )
739 {
740
741
742 if ( (CurrRetryRate>26)&&(priv->LastRetryRate>25))
743
744 {
745
746 bTryDown = true;
747 }
748
749 else if ( (CurrRetryRate>17)&&(priv->LastRetryRate>16) && (CurrSignalStrength > -72))
750
751 {
752
753 bTryDown = true;
754 }
755
756 if(bTryDown && (CurrSignalStrength < -75))
757 {
758 priv->TryDownCountLowData += TryDownTh;
759 }
760
761
762 }
763 else if ( priv->CurrentOperaRate == 96 )
764 {
765
766
767 if ( ((CurrRetryRate>48) && (priv->LastRetryRate>47)))
768
769
770 {
771
772 bTryDown = true;
773 }
774
775 else if ( ((CurrRetryRate>21) && (priv->LastRetryRate>20)) && (CurrSignalStrength > -74))
776 {
777
778 bTryDown = true;
779 }
780 else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
781
782 {
783 bTryDown = true;
784 priv->TryDownCountLowData += TryDownTh;
785 }
786 else if ( (CurrRetryRate<8) && (priv->LastRetryRate<8) )
787
788 {
789 bTryUp = true;
790 }
791
792 if(bTryDown && (CurrSignalStrength < -75))
793 {
794 priv->TryDownCountLowData += TryDownTh;
795 }
796
797 }
798 else if ( priv->CurrentOperaRate == 72 )
799 {
800
801 if ( (CurrRetryRate>43) && (priv->LastRetryRate>41))
802
803 {
804
805 bTryDown = true;
806 }
807 else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
808
809 {
810 bTryDown = true;
811 priv->TryDownCountLowData += TryDownTh;
812 }
813 else if ( (CurrRetryRate<15) && (priv->LastRetryRate<16))
814
815 {
816 bTryUp = true;
817 }
818
819 if(bTryDown && (CurrSignalStrength < -80))
820 {
821 priv->TryDownCountLowData += TryDownTh;
822 }
823
824 }
825 else if ( priv->CurrentOperaRate == 48 )
826 {
827
828
829 if ( ((CurrRetryRate>63) && (priv->LastRetryRate>62)))
830
831 {
832
833 bTryDown = true;
834 }
835
836 else if ( ((CurrRetryRate>33) && (priv->LastRetryRate>32)) && (CurrSignalStrength > -82) )
837
838 {
839
840 bTryDown = true;
841 }
842 else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
843
844
845 {
846 bTryDown = true;
847 priv->TryDownCountLowData += TryDownTh;
848 }
849 else if ( (CurrRetryRate<20) && (priv->LastRetryRate<21))
850
851 {
852 bTryUp = true;
853 }
854
855 if(bTryDown && (CurrSignalStrength < -82))
856 {
857 priv->TryDownCountLowData += TryDownTh;
858 }
859
860 }
861 else if ( priv->CurrentOperaRate == 36 )
862 {
863
864
865
866
867 if ( ((CurrRetryRate>85) && (priv->LastRetryRate>86)))
868
869 {
870
871 bTryDown = true;
872 }
873
874 else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
875
876 {
877 bTryDown = true;
878 priv->TryDownCountLowData += TryDownTh;
879 }
880 else if ( (CurrRetryRate<22) && (priv->LastRetryRate<23))
881
882 {
883 bTryUp = true;
884 }
885
886 }
887 else if ( priv->CurrentOperaRate == 22 )
888 {
889
890 if (CurrRetryRate>95)
891
892 {
893 bTryDown = true;
894 }
895 else if ( (CurrRetryRate<29) && (priv->LastRetryRate <30) )
896
897 {
898 bTryUp = true;
899 }
900
901 }
902 else if ( priv->CurrentOperaRate == 11 )
903 {
904
905 if (CurrRetryRate>149)
906
907 {
908 bTryDown = true;
909 }
910 else if ( (CurrRetryRate<60) && (priv->LastRetryRate < 65))
911
912
913 {
914 bTryUp = true;
915 }
916
917 }
918 else if ( priv->CurrentOperaRate == 4 )
919 {
920
921 if((CurrRetryRate>99) && (priv->LastRetryRate>99))
922
923 {
924 bTryDown = true;
925 }
926 else if ( (CurrRetryRate < 65) && (priv->LastRetryRate < 70))
927
928 {
929 bTryUp = true;
930 }
931
932 }
933 else if ( priv->CurrentOperaRate == 2 )
934 {
935
936 if( (CurrRetryRate<70) && (priv->LastRetryRate<75))
937
938 {
939 bTryUp = true;
940 }
941
942 }
943
944 if(bTryUp && bTryDown)
945 printk("StaRateAdaptive87B(): Tx Rate tried upping and downing simultaneously!\n");
946
947
948
949
950 if(!bTryUp && !bTryDown && (priv->TryupingCount == 0) && (priv->TryDownCountLowData == 0)
951 && priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate && priv->FailTxRateCount < 2)
952 {
953 if(jiffies% (CurrRetryRate + 101) == 0)
954 {
955 bTryUp = true;
956 priv->bTryuping = true;
957
958 }
959 }
960
961
962 if(bTryUp)
963 {
964 priv->TryupingCount++;
965 priv->TryDownCountLowData = 0;
966
967 {
968
969
970
971
972
973 }
974
975
976
977
978
979
980
981
982 if((priv->TryupingCount > (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount)) ||
983 (CurrSignalStrength > priv->LastFailTxRateSS) || priv->bTryuping)
984 {
985 priv->TryupingCount = 0;
986
987
988
989 if(priv->CurrentOperaRate == 22)
990 bUpdateInitialGain = true;
991
992
993
994
995 if( ((priv->CurrentOperaRate == 72) || (priv->CurrentOperaRate == 48) || (priv->CurrentOperaRate == 36)) &&
996 (priv->FailTxRateCount > 2) )
997 priv->RateAdaptivePeriod= (RATE_ADAPTIVE_TIMER_PERIOD/2);
998
999
1000
1001
1002 priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
1003
1004
1005
1006 if(priv->CurrentOperaRate ==36)
1007 {
1008 priv->bUpdateARFR=true;
1009 write_nic_word(dev, ARFR, 0x0F8F);
1010
1011 }
1012 else if(priv->bUpdateARFR)
1013 {
1014 priv->bUpdateARFR=false;
1015 write_nic_word(dev, ARFR, 0x0FFF);
1016
1017 }
1018
1019
1020 if(priv->LastFailTxRate != priv->CurrentOperaRate)
1021 {
1022 priv->LastFailTxRate = priv->CurrentOperaRate;
1023 priv->FailTxRateCount = 0;
1024 priv->LastFailTxRateSS = -200;
1025 }
1026 }
1027 }
1028 else
1029 {
1030 if(priv->TryupingCount > 0)
1031 priv->TryupingCount --;
1032 }
1033
1034 if(bTryDown)
1035 {
1036 priv->TryDownCountLowData++;
1037 priv->TryupingCount = 0;
1038 {
1039
1040
1041
1042 }
1043
1044
1045 if(priv->TryDownCountLowData > TryDownTh || priv->bTryuping)
1046 {
1047 priv->TryDownCountLowData = 0;
1048 priv->bTryuping = false;
1049
1050 if(priv->LastFailTxRate == priv->CurrentOperaRate)
1051 {
1052 priv->FailTxRateCount ++;
1053
1054 if(CurrSignalStrength > priv->LastFailTxRateSS)
1055 {
1056 priv->LastFailTxRateSS = CurrSignalStrength;
1057 }
1058 }
1059 else
1060 {
1061 priv->LastFailTxRate = priv->CurrentOperaRate;
1062 priv->FailTxRateCount = 1;
1063 priv->LastFailTxRateSS = CurrSignalStrength;
1064 }
1065 priv->CurrentOperaRate = GetDegradeTxRate(dev, priv->CurrentOperaRate);
1066
1067
1068
1069 if( (CurrSignalStrength < -80) && (priv->CurrentOperaRate > 72 ))
1070 {
1071 priv->CurrentOperaRate = 72;
1072
1073 }
1074
1075
1076 if(priv->CurrentOperaRate ==36)
1077 {
1078 priv->bUpdateARFR=true;
1079 write_nic_word(dev, ARFR, 0x0F8F);
1080
1081 }
1082 else if(priv->bUpdateARFR)
1083 {
1084 priv->bUpdateARFR=false;
1085 write_nic_word(dev, ARFR, 0x0FFF);
1086
1087 }
1088
1089
1090
1091
1092 if(MgntIsCckRate(priv->CurrentOperaRate))
1093 {
1094 bUpdateInitialGain = true;
1095 }
1096
1097 }
1098 }
1099 else
1100 {
1101 if(priv->TryDownCountLowData > 0)
1102 priv->TryDownCountLowData --;
1103 }
1104
1105
1106
1107 if(priv->FailTxRateCount >= 0x15 ||
1108 (!bTryUp && !bTryDown && priv->TryDownCountLowData == 0 && priv->TryupingCount && priv->FailTxRateCount > 0x6))
1109 {
1110 priv->FailTxRateCount --;
1111 }
1112
1113
1114 OfdmTxPwrIdx = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel];
1115 CckTxPwrIdx = priv->chtxpwr[priv->ieee80211->current_network.channel];
1116
1117
1118 if((priv->CurrentOperaRate < 96) &&(priv->CurrentOperaRate > 22))
1119 {
1120 u1bCck = read_nic_byte(dev, CCK_TXAGC);
1121 u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);
1122
1123
1124 if(u1bCck == CckTxPwrIdx )
1125 {
1126 if(u1bOfdm != (OfdmTxPwrIdx+2) )
1127 {
1128 priv->bEnhanceTxPwr= true;
1129 u1bOfdm = ((u1bOfdm+2) > 35) ? 35: (u1bOfdm+2);
1130 write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
1131
1132 }
1133 }
1134
1135 else if(u1bCck < CckTxPwrIdx)
1136 {
1137 if(!priv->bEnhanceTxPwr)
1138 {
1139 priv->bEnhanceTxPwr= true;
1140 u1bOfdm = ((u1bOfdm+2) > 35) ? 35: (u1bOfdm+2);
1141 write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
1142
1143 }
1144 }
1145 }
1146 else if(priv->bEnhanceTxPwr)
1147 {
1148 u1bCck = read_nic_byte(dev, CCK_TXAGC);
1149 u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);
1150
1151
1152 if(u1bCck == CckTxPwrIdx )
1153 {
1154 priv->bEnhanceTxPwr= false;
1155 write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);
1156
1157 }
1158
1159 else if(u1bCck < CckTxPwrIdx)
1160 {
1161 priv->bEnhanceTxPwr= false;
1162 u1bOfdm = ((u1bOfdm-2) > 0) ? (u1bOfdm-2): 0;
1163 write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
1164
1165
1166 }
1167 }
1168
1169
1170
1171
1172
1173SetInitialGain:
1174 if(bUpdateInitialGain)
1175 {
1176 if(MgntIsCckRate(priv->CurrentOperaRate))
1177 {
1178 if(priv->InitialGain > priv->RegBModeGainStage)
1179 {
1180 priv->InitialGainBackUp= priv->InitialGain;
1181
1182 if(CurrSignalStrength < -85)
1183 {
1184
1185 priv->InitialGain = priv->RegBModeGainStage;
1186 }
1187 else if(priv->InitialGain > priv->RegBModeGainStage + 1)
1188 {
1189 priv->InitialGain -= 2;
1190 }
1191 else
1192 {
1193 priv->InitialGain --;
1194 }
1195 printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate);
1196 UpdateInitialGain(dev);
1197 }
1198 }
1199 else
1200 {
1201 if(priv->InitialGain < 4)
1202 {
1203 priv->InitialGainBackUp= priv->InitialGain;
1204
1205 priv->InitialGain ++;
1206 printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate);
1207 UpdateInitialGain(dev);
1208 }
1209 }
1210 }
1211
1212
1213 priv->LastRetryRate = CurrRetryRate;
1214 priv->LastTxThroughput = TxThroughput;
1215 priv->ieee80211->rate = priv->CurrentOperaRate * 5;
1216}
1217
1218void rtl8180_rate_adapter(struct work_struct * work)
1219{
1220 struct delayed_work *dwork = to_delayed_work(work);
1221 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,rate_adapter_wq);
1222 struct net_device *dev = ieee->dev;
1223
1224
1225 StaRateAdaptive87SE(dev);
1226
1227}
1228void timer_rate_adaptive(unsigned long data)
1229{
1230 struct r8180_priv* priv = ieee80211_priv((struct net_device *)data);
1231
1232 if(!priv->up)
1233 {
1234
1235 return;
1236 }
1237 if((priv->ieee80211->iw_mode != IW_MODE_MASTER)
1238 && (priv->ieee80211->state == IEEE80211_LINKED) &&
1239 (priv->ForcedDataRate == 0) )
1240 {
1241
1242 queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->rate_adapter_wq);
1243
1244 }
1245 priv->rateadapter_timer.expires = jiffies + MSECS(priv->RateAdaptivePeriod);
1246 add_timer(&priv->rateadapter_timer);
1247
1248}
1249
1250void
1251SwAntennaDiversityRxOk8185(
1252 struct net_device *dev,
1253 u8 SignalStrength
1254 )
1255{
1256 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1257
1258
1259
1260 priv->AdRxOkCnt++;
1261
1262 if( priv->AdRxSignalStrength != -1)
1263 {
1264 priv->AdRxSignalStrength = ((priv->AdRxSignalStrength*7) + (SignalStrength*3)) / 10;
1265 }
1266 else
1267 {
1268 priv->AdRxSignalStrength = SignalStrength;
1269 }
1270
1271 if( priv->LastRxPktAntenna )
1272 priv->AdMainAntennaRxOkCnt++;
1273 else
1274 priv->AdAuxAntennaRxOkCnt++;
1275
1276
1277}
1278
1279
1280
1281
1282bool
1283SetAntenna8185(
1284 struct net_device *dev,
1285 u8 u1bAntennaIndex
1286 )
1287{
1288 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1289 bool bAntennaSwitched = false;
1290
1291
1292
1293 switch(u1bAntennaIndex)
1294 {
1295 case 0:
1296
1297 write_nic_byte(dev, ANTSEL, 0x03);
1298
1299 write_phy_cck(dev, 0x11, 0x9b);
1300 write_phy_ofdm(dev, 0x0d, 0x5c);
1301
1302 bAntennaSwitched = true;
1303 break;
1304
1305 case 1:
1306
1307 write_nic_byte(dev, ANTSEL, 0x00);
1308
1309 write_phy_cck(dev, 0x11, 0xbb);
1310 write_phy_ofdm(dev, 0x0d, 0x54);
1311
1312 bAntennaSwitched = true;
1313
1314 break;
1315
1316 default:
1317 printk("SetAntenna8185: unknown u1bAntennaIndex(%d)\n", u1bAntennaIndex);
1318 break;
1319 }
1320
1321 if(bAntennaSwitched)
1322 {
1323 priv->CurrAntennaIndex = u1bAntennaIndex;
1324 }
1325
1326
1327
1328 return bAntennaSwitched;
1329}
1330
1331
1332
1333
1334bool
1335SwitchAntenna(
1336 struct net_device *dev
1337 )
1338{
1339 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1340
1341 bool bResult;
1342
1343 if(priv->CurrAntennaIndex == 0)
1344 {
1345 bResult = SetAntenna8185(dev, 1);
1346
1347
1348
1349 }
1350 else
1351 {
1352 bResult = SetAntenna8185(dev, 0);
1353
1354
1355
1356 }
1357
1358 return bResult;
1359}
1360
1361
1362
1363
1364
1365
1366
1367
1368void
1369SwAntennaDiversity(
1370 struct net_device *dev
1371 )
1372{
1373 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1374 bool bSwCheckSS=false;
1375
1376
1377
1378 if(bSwCheckSS)
1379 {
1380 priv->AdTickCount++;
1381
1382 printk("(1) AdTickCount: %d, AdCheckPeriod: %d\n",
1383 priv->AdTickCount, priv->AdCheckPeriod);
1384 printk("(2) AdRxSignalStrength: %ld, AdRxSsThreshold: %ld\n",
1385 priv->AdRxSignalStrength, priv->AdRxSsThreshold);
1386 }
1387
1388
1389
1390 if(priv->ieee80211->state != IEEE80211_LINKED)
1391 {
1392
1393
1394 priv->bAdSwitchedChecking = false;
1395
1396 SwitchAntenna(dev);
1397 }
1398
1399 else if(priv->AdRxOkCnt == 0)
1400 {
1401
1402
1403 priv->bAdSwitchedChecking = false;
1404 SwitchAntenna(dev);
1405 }
1406
1407 else if(priv->bAdSwitchedChecking == true)
1408 {
1409
1410
1411 priv->bAdSwitchedChecking = false;
1412
1413
1414 priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2;
1415
1416 priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
1417 priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;
1418 if(priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched)
1419 {
1420
1421
1422
1423
1424 priv->AdCheckPeriod *= 2;
1425
1426
1427 if(priv->AdCheckPeriod > priv->AdMaxCheckPeriod)
1428 priv->AdCheckPeriod = priv->AdMaxCheckPeriod;
1429
1430
1431 SwitchAntenna(dev);
1432 }
1433 else
1434 {
1435
1436
1437
1438
1439 priv->AdCheckPeriod = priv->AdMinCheckPeriod;
1440 }
1441
1442
1443
1444 }
1445
1446
1447 else
1448 {
1449
1450
1451 priv->AdTickCount = 0;
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465 if((priv->AdMainAntennaRxOkCnt < priv->AdAuxAntennaRxOkCnt)
1466 && (priv->CurrAntennaIndex == 0))
1467 {
1468
1469
1470
1471
1472
1473 SwitchAntenna(dev);
1474 priv->bHWAdSwitched = true;
1475 }
1476 else if((priv->AdAuxAntennaRxOkCnt < priv->AdMainAntennaRxOkCnt)
1477 && (priv->CurrAntennaIndex == 1))
1478 {
1479
1480
1481
1482
1483
1484 SwitchAntenna(dev);
1485 priv->bHWAdSwitched = true;
1486 }
1487 else
1488 {
1489
1490
1491
1492
1493
1494 priv->bHWAdSwitched = false;
1495 }
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507 if( (!priv->bHWAdSwitched) && (bSwCheckSS))
1508 {
1509
1510
1511 if(priv->AdRxSignalStrength < priv->AdRxSsThreshold)
1512 {
1513
1514
1515
1516 priv->AdRxSsBeforeSwitched = priv->AdRxSignalStrength;
1517 priv->bAdSwitchedChecking = true;
1518
1519 SwitchAntenna(dev);
1520 }
1521 else
1522 {
1523
1524
1525
1526 priv->bAdSwitchedChecking = false;
1527
1528 if( (priv->AdRxSignalStrength > (priv->AdRxSsThreshold + 10)) &&
1529 priv->AdRxSsThreshold <= priv->AdMaxRxSsThreshold)
1530 {
1531 priv->AdRxSsThreshold = (priv->AdRxSsThreshold + priv->AdRxSignalStrength) / 2;
1532 priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
1533 priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;
1534 }
1535
1536
1537 if( priv->AdCheckPeriod > priv->AdMinCheckPeriod )
1538 {
1539 priv->AdCheckPeriod /= 2;
1540 }
1541 }
1542 }
1543 }
1544
1545
1546 priv->AdRxOkCnt = 0;
1547 priv->AdMainAntennaRxOkCnt = 0;
1548 priv->AdAuxAntennaRxOkCnt = 0;
1549
1550
1551
1552
1553
1554}
1555
1556
1557
1558
1559
1560bool
1561CheckTxPwrTracking( struct net_device *dev)
1562{
1563 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1564
1565 if(!priv->bTxPowerTrack)
1566 {
1567 return false;
1568 }
1569
1570
1571
1572
1573
1574
1575
1576
1577 if(priv->bToUpdateTxPwr)
1578 {
1579 return false;
1580 }
1581
1582 return true;
1583}
1584
1585
1586
1587
1588
1589
1590void
1591SwAntennaDiversityTimerCallback(
1592 struct net_device *dev
1593 )
1594{
1595 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1596 RT_RF_POWER_STATE rtState;
1597
1598
1599
1600
1601
1602
1603
1604 rtState = priv->eRFPowerState;
1605 do{
1606 if (rtState == eRfOff)
1607 {
1608
1609 break;
1610 }
1611 else if (rtState == eRfSleep)
1612 {
1613
1614
1615 break;
1616 }
1617 SwAntennaDiversity(dev);
1618
1619 }while(false);
1620
1621 if(priv->up)
1622 {
1623 priv->SwAntennaDiversityTimer.expires = jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD);
1624 add_timer(&priv->SwAntennaDiversityTimer);
1625 }
1626
1627
1628}
1629
1630