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