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