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