• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/staging/rtl8192e/
1/*++
2Copyright-c Realtek Semiconductor Corp. All rights reserved.
3
4Module Name:
5	r8192U_dm.c
6
7Abstract:
8	HW dynamic mechanism.
9
10Major Change History:
11	When      	Who				What
12	----------	--------------- -------------------------------
13	2008-05-14	amy                     create version 0 porting from windows code.
14
15--*/
16#include "r8192E.h"
17#include "r8192E_dm.h"
18#include "r8192E_hw.h"
19#include "r819xE_phy.h"
20#include "r819xE_phyreg.h"
21#include "r8190_rtl8256.h"
22
23#define DRV_NAME "rtl819xE"
24/*---------------------------Define Local Constant---------------------------*/
25//
26// Indicate different AP vendor for IOT issue.
27//
28#ifdef  RTL8190P
29static const u32 edca_setting_DL[HT_IOT_PEER_MAX] =
30{ 0x5e4322, 	0x5e4322, 	0x5e4322,  	0x604322, 	0xa44f, 	0x5e4322,	0x5e4322};
31static const u32 edca_setting_UL[HT_IOT_PEER_MAX] =
32{ 0x5e4322, 	0xa44f, 	0x5e4322,  	0x604322, 	0x5e4322, 	0x5e4322,	0x5e4322};
33#else
34#ifdef RTL8192E
35static const u32 edca_setting_DL[HT_IOT_PEER_MAX] =
36{ 0x5e4322, 	0x5e4322, 	0x5e4322, 	0x604322, 	0xa44f, 	0x5e4322,	0x5e4322};
37static const u32 edca_setting_UL[HT_IOT_PEER_MAX] =
38{ 0x5e4322, 	0xa44f,		0x5e4322,  	0x604322, 	0x5e4322, 	0x5e4322, 	0x5e4322};
39#else
40static const u32 edca_setting_DL[HT_IOT_PEER_MAX] =
41{ 0x5e4322, 	0x5e4322, 	0x5e4322, 	0x604322, 	0xa44f, 	0x5ea44f, 	0x5e4322};
42static const u32 edca_setting_UL[HT_IOT_PEER_MAX] =
43{ 0x5e4322, 	0xa44f, 	0x5e4322, 	0x604322, 	0x5ea44f, 	0x5ea44f, 	0x5e4322};
44#endif
45#endif
46
47#define RTK_UL_EDCA 0xa44f
48#define RTK_DL_EDCA 0x5e4322
49/*---------------------------Define Local Constant---------------------------*/
50
51
52/*------------------------Define global variable-----------------------------*/
53// Debug variable ?
54dig_t	dm_digtable;
55// Store current shoftware write register content for MAC PHY.
56u8		dm_shadow[16][256] = {{0}};
57// For Dynamic Rx Path Selection by Signal Strength
58DRxPathSel	DM_RxPathSelTable;
59/*------------------------Define global variable-----------------------------*/
60
61
62/*------------------------Define local variable------------------------------*/
63/*------------------------Define local variable------------------------------*/
64
65
66/*--------------------Define export function prototype-----------------------*/
67extern	void	init_hal_dm(struct net_device *dev);
68extern	void deinit_hal_dm(struct net_device *dev);
69
70extern void hal_dm_watchdog(struct net_device *dev);
71
72
73extern	void	init_rate_adaptive(struct net_device *dev);
74extern	void	dm_txpower_trackingcallback(struct work_struct *work);
75
76extern	void	dm_cck_txpower_adjust(struct net_device *dev,bool  binch14);
77extern	void	dm_restore_dynamic_mechanism_state(struct net_device *dev);
78extern	void	dm_backup_dynamic_mechanism_state(struct net_device *dev);
79extern	void	dm_change_dynamic_initgain_thresh(struct net_device *dev,
80								u32		dm_type,
81								u32		dm_value);
82extern	void	DM_ChangeFsyncSetting(struct net_device *dev,
83												s32		DM_Type,
84												s32		DM_Value);
85extern	void dm_force_tx_fw_info(struct net_device *dev,
86										u32		force_type,
87										u32		force_value);
88extern	void	dm_init_edca_turbo(struct net_device *dev);
89extern	void	dm_rf_operation_test_callback(unsigned long data);
90extern	void	dm_rf_pathcheck_workitemcallback(struct work_struct *work);
91extern	void dm_fsync_timer_callback(unsigned long data);
92extern	void dm_check_fsync(struct net_device *dev);
93extern	void	dm_shadow_init(struct net_device *dev);
94extern	void dm_initialize_txpower_tracking(struct net_device *dev);
95
96#ifdef RTL8192E
97extern  void    dm_gpio_change_rf_callback(struct work_struct *work);
98#endif
99
100
101
102/*--------------------Define export function prototype-----------------------*/
103
104
105/*---------------------Define local function prototype-----------------------*/
106// DM --> Rate Adaptive
107static	void	dm_check_rate_adaptive(struct net_device *dev);
108
109// DM --> Bandwidth switch
110static	void	dm_init_bandwidth_autoswitch(struct net_device *dev);
111static	void	dm_bandwidth_autoswitch(	struct net_device *dev);
112
113// DM --> TX power control
114//static	void	dm_initialize_txpower_tracking(struct net_device *dev);
115
116static	void	dm_check_txpower_tracking(struct net_device *dev);
117
118
119
120//static	void	dm_txpower_reset_recovery(struct net_device *dev);
121
122
123// DM --> BB init gain restore
124#ifndef RTL8192U
125static	void	dm_bb_initialgain_restore(struct net_device *dev);
126
127
128// DM --> BB init gain backup
129static	void	dm_bb_initialgain_backup(struct net_device *dev);
130#endif
131
132// DM --> Dynamic Init Gain by RSSI
133static	void	dm_dig_init(struct net_device *dev);
134static	void	dm_ctrl_initgain_byrssi(struct net_device *dev);
135static	void	dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev);
136static	void	dm_ctrl_initgain_byrssi_by_driverrssi(	struct net_device *dev);
137static	void	dm_ctrl_initgain_byrssi_by_fwfalse_alarm(struct net_device *dev);
138static	void	dm_initial_gain(struct net_device *dev);
139static	void	dm_pd_th(struct net_device *dev);
140static	void	dm_cs_ratio(struct net_device *dev);
141
142static	void dm_init_ctstoself(struct net_device *dev);
143// DM --> EDCA turboe mode control
144static	void	dm_check_edca_turbo(struct net_device *dev);
145
146// DM --> HW RF control
147static	void	dm_check_rfctrl_gpio(struct net_device *dev);
148
149#ifndef RTL8190P
150//static	void	dm_gpio_change_rf(struct net_device *dev);
151#endif
152// DM --> Check PBC
153static	void dm_check_pbc_gpio(struct net_device *dev);
154
155
156// DM --> Check current RX RF path state
157static	void	dm_check_rx_path_selection(struct net_device *dev);
158static 	void dm_init_rxpath_selection(struct net_device *dev);
159static	void dm_rxpath_sel_byrssi(struct net_device *dev);
160
161
162// DM --> Fsync for broadcom ap
163static void dm_init_fsync(struct net_device *dev);
164static void dm_deInit_fsync(struct net_device *dev);
165
166//Added by vivi, 20080522
167static	void	dm_check_txrateandretrycount(struct net_device *dev);
168
169/*---------------------Define local function prototype-----------------------*/
170
171/*---------------------Define of Tx Power Control For Near/Far Range --------*/   //Add by Jacken 2008/02/18
172static	void	dm_init_dynamic_txpower(struct net_device *dev);
173static	void	dm_dynamic_txpower(struct net_device *dev);
174
175
176// DM --> For rate adaptive and DIG, we must send RSSI to firmware
177static	void dm_send_rssi_tofw(struct net_device *dev);
178static	void	dm_ctstoself(struct net_device *dev);
179/*---------------------------Define function prototype------------------------*/
180//================================================================================
181//	HW Dynamic mechanism interface.
182//================================================================================
183
184//
185//	Description:
186//		Prepare SW resource for HW dynamic mechanism.
187//
188//	Assumption:
189//		This function is only invoked at driver intialization once.
190//
191//
192void init_hal_dm(struct net_device *dev)
193{
194	struct r8192_priv *priv = ieee80211_priv(dev);
195
196	// Undecorated Smoothed Signal Strength, it can utilized to dynamic mechanism.
197	priv->undecorated_smoothed_pwdb = -1;
198
199	//Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code.
200	dm_init_dynamic_txpower(dev);
201	init_rate_adaptive(dev);
202	//dm_initialize_txpower_tracking(dev);
203	dm_dig_init(dev);
204	dm_init_edca_turbo(dev);
205	dm_init_bandwidth_autoswitch(dev);
206	dm_init_fsync(dev);
207	dm_init_rxpath_selection(dev);
208	dm_init_ctstoself(dev);
209#ifdef RTL8192E
210	INIT_DELAYED_WORK(&priv->gpio_change_rf_wq,  dm_gpio_change_rf_callback);
211#endif
212
213}	// InitHalDm
214
215void deinit_hal_dm(struct net_device *dev)
216{
217
218	dm_deInit_fsync(dev);
219
220}
221
222
223#ifdef USB_RX_AGGREGATION_SUPPORT
224void dm_CheckRxAggregation(struct net_device *dev) {
225	struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
226	PRT_HIGH_THROUGHPUT	pHTInfo = priv->ieee80211->pHTInfo;
227	static unsigned long	lastTxOkCnt = 0;
228	static unsigned long	lastRxOkCnt = 0;
229	unsigned long		curTxOkCnt = 0;
230	unsigned long		curRxOkCnt = 0;
231
232/*
233	if (pHalData->bForcedUsbRxAggr) {
234		if (pHalData->ForcedUsbRxAggrInfo == 0) {
235			if (pHalData->bCurrentRxAggrEnable) {
236				Adapter->HalFunc.HalUsbRxAggrHandler(Adapter, FALSE);
237			}
238		} else {
239			if (!pHalData->bCurrentRxAggrEnable || (pHalData->ForcedUsbRxAggrInfo != pHalData->LastUsbRxAggrInfoSetting)) {
240				Adapter->HalFunc.HalUsbRxAggrHandler(Adapter, TRUE);
241			}
242		}
243		return;
244	}
245
246*/
247	curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
248	curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
249
250	if((curTxOkCnt + curRxOkCnt) < 15000000) {
251		return;
252	}
253
254	if(curTxOkCnt > 4*curRxOkCnt) {
255		if (priv->bCurrentRxAggrEnable) {
256			write_nic_dword(dev, 0x1a8, 0);
257			priv->bCurrentRxAggrEnable = false;
258		}
259	}else{
260		if (!priv->bCurrentRxAggrEnable && !pHTInfo->bCurrentRT2RTAggregation) {
261			u32 ulValue;
262			ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
263				(pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
264			/*
265			 * If usb rx firmware aggregation is enabled,
266			 * when anyone of three threshold conditions above is reached,
267			 * firmware will send aggregated packet to driver.
268			 */
269			write_nic_dword(dev, 0x1a8, ulValue);
270			priv->bCurrentRxAggrEnable = true;
271		}
272	}
273
274	lastTxOkCnt = priv->stats.txbytesunicast;
275	lastRxOkCnt = priv->stats.rxbytesunicast;
276}	// dm_CheckEdcaTurbo
277#endif
278
279
280// call the script file to enable
281void dm_check_ac_dc_power(struct net_device *dev)
282{
283	struct r8192_priv *priv = ieee80211_priv(dev);
284	static char *ac_dc_check_script_path = "/etc/acpi/wireless-rtl-ac-dc-power.sh";
285	char *argv[] = {ac_dc_check_script_path,DRV_NAME,NULL};
286	static char *envp[] = {"HOME=/",
287			"TERM=linux",
288			"PATH=/usr/bin:/bin",
289			 NULL};
290
291	if(priv->ResetProgress == RESET_TYPE_SILENT)
292	{
293		RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF), "GPIOChangeRFWorkItemCallBack(): Silent Reseting!!!!!!!\n");
294		return;
295	}
296
297	if(priv->ieee80211->state != IEEE80211_LINKED) {
298		return;
299	}
300	call_usermodehelper(ac_dc_check_script_path,argv,envp,1);
301
302	return;
303};
304
305void hal_dm_watchdog(struct net_device *dev)
306{
307        //struct r8192_priv *priv = ieee80211_priv(dev);
308
309	//static u8 	previous_bssid[6] ={0};
310
311	dm_check_ac_dc_power(dev);
312
313	/*Add by amy 2008/05/15 ,porting from windows code.*/
314	dm_check_rate_adaptive(dev);
315	dm_dynamic_txpower(dev);
316	dm_check_txrateandretrycount(dev);
317
318	dm_check_txpower_tracking(dev);
319
320	dm_ctrl_initgain_byrssi(dev);
321	dm_check_edca_turbo(dev);
322	dm_bandwidth_autoswitch(dev);
323
324	dm_check_rfctrl_gpio(dev);
325	dm_check_rx_path_selection(dev);
326	dm_check_fsync(dev);
327
328	// Add by amy 2008-05-15 porting from windows code.
329	dm_check_pbc_gpio(dev);
330	dm_send_rssi_tofw(dev);
331	dm_ctstoself(dev);
332
333#ifdef USB_RX_AGGREGATION_SUPPORT
334	dm_CheckRxAggregation(dev);
335#endif
336}	//HalDmWatchDog
337
338
339/*
340  * Decide Rate Adaptive Set according to distance (signal strength)
341  *	01/11/2008	MHC		Modify input arguments and RATR table level.
342  *	01/16/2008	MHC		RF_Type is assigned in ReadAdapterInfo(). We must call
343  *						the function after making sure RF_Type.
344  */
345void init_rate_adaptive(struct net_device * dev)
346{
347
348	struct r8192_priv *priv = ieee80211_priv(dev);
349	prate_adaptive			pra = (prate_adaptive)&priv->rate_adaptive;
350
351	pra->ratr_state = DM_RATR_STA_MAX;
352	pra->high2low_rssi_thresh_for_ra = RateAdaptiveTH_High;
353	pra->low2high_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M+5;
354	pra->low2high_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M+5;
355
356	pra->high_rssi_thresh_for_ra = RateAdaptiveTH_High+5;
357	pra->low_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M;
358	pra->low_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M;
359
360	if(priv->CustomerID == RT_CID_819x_Netcore)
361		pra->ping_rssi_enable = 1;
362	else
363		pra->ping_rssi_enable = 0;
364	pra->ping_rssi_thresh_for_ra = 15;
365
366
367	if (priv->rf_type == RF_2T4R)
368	{
369		// 07/10/08 MH Modify for RA smooth scheme.
370		/* 2008/01/11 MH Modify 2T RATR table for different RSSI. 080515 porting by amy from windows code.*/
371		pra->upper_rssi_threshold_ratr		= 	0x8f0f0000;
372		pra->middle_rssi_threshold_ratr		= 	0x8f0ff000;
373		pra->low_rssi_threshold_ratr		= 	0x8f0ff001;
374		pra->low_rssi_threshold_ratr_40M	= 	0x8f0ff005;
375		pra->low_rssi_threshold_ratr_20M	= 	0x8f0ff001;
376		pra->ping_rssi_ratr	= 	0x0000000d;//cosa add for test
377	}
378	else if (priv->rf_type == RF_1T2R)
379	{
380		pra->upper_rssi_threshold_ratr		= 	0x000f0000;
381		pra->middle_rssi_threshold_ratr		= 	0x000ff000;
382		pra->low_rssi_threshold_ratr		= 	0x000ff001;
383		pra->low_rssi_threshold_ratr_40M	= 	0x000ff005;
384		pra->low_rssi_threshold_ratr_20M	= 	0x000ff001;
385		pra->ping_rssi_ratr	= 	0x0000000d;//cosa add for test
386	}
387
388}	// InitRateAdaptive
389
390
391/*-----------------------------------------------------------------------------
392 * Function:	dm_check_rate_adaptive()
393 *
394 * Overview:
395 *
396 * Input:		NONE
397 *
398 * Output:		NONE
399 *
400 * Return:		NONE
401 *
402 * Revised History:
403 *	When		Who		Remark
404 *	05/26/08	amy 	Create version 0 proting from windows code.
405 *
406 *---------------------------------------------------------------------------*/
407static void dm_check_rate_adaptive(struct net_device * dev)
408{
409	struct r8192_priv *priv = ieee80211_priv(dev);
410	PRT_HIGH_THROUGHPUT	pHTInfo = priv->ieee80211->pHTInfo;
411	prate_adaptive			pra = (prate_adaptive)&priv->rate_adaptive;
412	u32						currentRATR, targetRATR = 0;
413	u32						LowRSSIThreshForRA = 0, HighRSSIThreshForRA = 0;
414	bool						bshort_gi_enabled = false;
415	static u8					ping_rssi_state=0;
416
417
418	if(!priv->up)
419	{
420		RT_TRACE(COMP_RATE, "<---- dm_check_rate_adaptive(): driver is going to unload\n");
421		return;
422	}
423
424	if(pra->rate_adaptive_disabled)//this variable is set by ioctl.
425		return;
426
427	// TODO: Only 11n mode is implemented currently,
428	if( !(priv->ieee80211->mode == WIRELESS_MODE_N_24G ||
429		 priv->ieee80211->mode == WIRELESS_MODE_N_5G))
430		 return;
431
432	if( priv->ieee80211->state == IEEE80211_LINKED )
433	{
434	//	RT_TRACE(COMP_RATE, "dm_CheckRateAdaptive(): \t");
435
436		//
437		// Check whether Short GI is enabled
438		//
439		bshort_gi_enabled = (pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI40MHz) ||
440			(!pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI20MHz);
441
442
443		pra->upper_rssi_threshold_ratr =
444				(pra->upper_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
445
446		pra->middle_rssi_threshold_ratr =
447				(pra->middle_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
448
449		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
450		{
451			pra->low_rssi_threshold_ratr =
452				(pra->low_rssi_threshold_ratr_40M & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
453		}
454		else
455		{
456			pra->low_rssi_threshold_ratr =
457			(pra->low_rssi_threshold_ratr_20M & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
458		}
459		//cosa add for test
460		pra->ping_rssi_ratr =
461				(pra->ping_rssi_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
462
463		/* 2007/10/08 MH We support RA smooth scheme now. When it is the first
464		   time to link with AP. We will not change upper/lower threshold. If
465		   STA stay in high or low level, we must change two different threshold
466		   to prevent jumping frequently. */
467		if (pra->ratr_state == DM_RATR_STA_HIGH)
468		{
469			HighRSSIThreshForRA 	= pra->high2low_rssi_thresh_for_ra;
470			LowRSSIThreshForRA	= (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)?
471					(pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M);
472		}
473		else if (pra->ratr_state == DM_RATR_STA_LOW)
474		{
475			HighRSSIThreshForRA	= pra->high_rssi_thresh_for_ra;
476			LowRSSIThreshForRA 	= (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)?
477					(pra->low2high_rssi_thresh_for_ra40M):(pra->low2high_rssi_thresh_for_ra20M);
478		}
479		else
480		{
481			HighRSSIThreshForRA	= pra->high_rssi_thresh_for_ra;
482			LowRSSIThreshForRA	= (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)?
483					(pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M);
484		}
485
486		//DbgPrint("[DM] Thresh H/L=%d/%d\n\r", RATR.HighRSSIThreshForRA, RATR.LowRSSIThreshForRA);
487		if(priv->undecorated_smoothed_pwdb >= (long)HighRSSIThreshForRA)
488		{
489			//DbgPrint("[DM] RSSI=%d STA=HIGH\n\r", pHalData->UndecoratedSmoothedPWDB);
490			pra->ratr_state = DM_RATR_STA_HIGH;
491			targetRATR = pra->upper_rssi_threshold_ratr;
492		}else if(priv->undecorated_smoothed_pwdb >= (long)LowRSSIThreshForRA)
493		{
494			//DbgPrint("[DM] RSSI=%d STA=Middle\n\r", pHalData->UndecoratedSmoothedPWDB);
495			pra->ratr_state = DM_RATR_STA_MIDDLE;
496			targetRATR = pra->middle_rssi_threshold_ratr;
497		}else
498		{
499			//DbgPrint("[DM] RSSI=%d STA=LOW\n\r", pHalData->UndecoratedSmoothedPWDB);
500			pra->ratr_state = DM_RATR_STA_LOW;
501			targetRATR = pra->low_rssi_threshold_ratr;
502		}
503
504			//cosa add for test
505		if(pra->ping_rssi_enable)
506		{
507			//pHalData->UndecoratedSmoothedPWDB = 19;
508			if(priv->undecorated_smoothed_pwdb < (long)(pra->ping_rssi_thresh_for_ra+5))
509			{
510				if( (priv->undecorated_smoothed_pwdb < (long)pra->ping_rssi_thresh_for_ra) ||
511					ping_rssi_state )
512				{
513					//DbgPrint("TestRSSI = %d, set RATR to 0x%x \n", pHalData->UndecoratedSmoothedPWDB, pRA->TestRSSIRATR);
514					pra->ratr_state = DM_RATR_STA_LOW;
515					targetRATR = pra->ping_rssi_ratr;
516					ping_rssi_state = 1;
517				}
518				//else
519				//	DbgPrint("TestRSSI is between the range. \n");
520			}
521			else
522			{
523				//DbgPrint("TestRSSI Recover to 0x%x \n", targetRATR);
524				ping_rssi_state = 0;
525			}
526		}
527
528		// 2008.04.01
529		// For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7.
530		if(priv->ieee80211->GetHalfNmodeSupportByAPsHandler(dev))
531			targetRATR &=  0xf00fffff;
532
533		//
534		// Check whether updating of RATR0 is required
535		//
536		currentRATR = read_nic_dword(dev, RATR0);
537		if( targetRATR !=  currentRATR )
538		{
539			u32 ratr_value;
540			ratr_value = targetRATR;
541			RT_TRACE(COMP_RATE,"currentRATR = %x, targetRATR = %x\n", currentRATR, targetRATR);
542			if(priv->rf_type == RF_1T2R)
543			{
544				ratr_value &= ~(RATE_ALL_OFDM_2SS);
545			}
546			write_nic_dword(dev, RATR0, ratr_value);
547			write_nic_byte(dev, UFWP, 1);
548
549			pra->last_ratr = targetRATR;
550		}
551
552	}
553	else
554	{
555		pra->ratr_state = DM_RATR_STA_MAX;
556	}
557
558}	// dm_CheckRateAdaptive
559
560
561static void dm_init_bandwidth_autoswitch(struct net_device * dev)
562{
563	struct r8192_priv *priv = ieee80211_priv(dev);
564
565	priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz = BW_AUTO_SWITCH_LOW_HIGH;
566	priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz = BW_AUTO_SWITCH_HIGH_LOW;
567	priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
568	priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable = false;
569
570}	// dm_init_bandwidth_autoswitch
571
572
573static void dm_bandwidth_autoswitch(struct net_device * dev)
574{
575	struct r8192_priv *priv = ieee80211_priv(dev);
576
577	if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 ||!priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable){
578		return;
579	}else{
580		if(priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz == false){//If send packets in 40 Mhz in 20/40
581			if(priv->undecorated_smoothed_pwdb <= priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz)
582				priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = true;
583		}else{//in force send packets in 20 Mhz in 20/40
584			if(priv->undecorated_smoothed_pwdb >= priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz)
585				priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
586
587		}
588	}
589}	// dm_BandwidthAutoSwitch
590
591//OFDM default at 0db, index=6.
592#ifndef RTL8190P
593static const u32 OFDMSwingTable[OFDM_Table_Length] = {
594	0x7f8001fe,	// 0, +6db
595	0x71c001c7,	// 1, +5db
596	0x65400195,	// 2, +4db
597	0x5a400169,	// 3, +3db
598	0x50800142,	// 4, +2db
599	0x47c0011f,	// 5, +1db
600	0x40000100,	// 6, +0db ===> default, upper for higher temperature, lower for low temperature
601	0x390000e4,	// 7, -1db
602	0x32c000cb,	// 8, -2db
603	0x2d4000b5,	// 9, -3db
604	0x288000a2,	// 10, -4db
605	0x24000090,	// 11, -5db
606	0x20000080,	// 12, -6db
607	0x1c800072,	// 13, -7db
608	0x19800066,	// 14, -8db
609	0x26c0005b,	// 15, -9db
610	0x24400051,	// 16, -10db
611	0x12000048,	// 17, -11db
612	0x10000040	// 18, -12db
613};
614static const u8 CCKSwingTable_Ch1_Ch13[CCK_Table_length][8] = {
615	{0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},	// 0, +0db ===> CCK40M default
616	{0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},	// 1, -1db
617	{0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},	// 2, -2db
618	{0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},	// 3, -3db
619	{0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},	// 4, -4db
620	{0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},	// 5, -5db
621	{0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},	// 6, -6db ===> CCK20M default
622	{0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},	// 7, -7db
623	{0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},	// 8, -8db
624	{0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},	// 9, -9db
625	{0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},	// 10, -10db
626	{0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}	// 11, -11db
627};
628
629static const u8 CCKSwingTable_Ch14[CCK_Table_length][8] = {
630	{0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},	// 0, +0db  ===> CCK40M default
631	{0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},	// 1, -1db
632	{0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},	// 2, -2db
633	{0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},	// 3, -3db
634	{0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},	// 4, -4db
635	{0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},	// 5, -5db
636	{0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},	// 6, -6db  ===> CCK20M default
637	{0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},	// 7, -7db
638	{0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},	// 8, -8db
639	{0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},	// 9, -9db
640	{0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},	// 10, -10db
641	{0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}	// 11, -11db
642};
643#endif
644#define		Pw_Track_Flag				0x11d
645#define		Tssi_Mea_Value				0x13c
646#define		Tssi_Report_Value1			0x134
647#define		Tssi_Report_Value2			0x13e
648#define		FW_Busy_Flag				0x13f
649static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev)
650	{
651	struct r8192_priv *priv = ieee80211_priv(dev);
652	bool						bHighpowerstate, viviflag = FALSE;
653	DCMD_TXCMD_T			tx_cmd;
654	u8					powerlevelOFDM24G;
655	int	    				i =0, j = 0, k = 0;
656	u8						RF_Type, tmp_report[5]={0, 0, 0, 0, 0};
657	u32						Value;
658	u8						Pwr_Flag;
659	u16					Avg_TSSI_Meas, TSSI_13dBm, Avg_TSSI_Meas_from_driver=0;
660#ifdef RTL8192U
661	RT_STATUS 				rtStatus = RT_STATUS_SUCCESS;
662#endif
663//	bool rtStatus = true;
664	u32						delta=0;
665	RT_TRACE(COMP_POWER_TRACKING,"%s()\n",__FUNCTION__);
666//	write_nic_byte(dev, 0x1ba, 0);
667	write_nic_byte(dev, Pw_Track_Flag, 0);
668	write_nic_byte(dev, FW_Busy_Flag, 0);
669	priv->ieee80211->bdynamic_txpower_enable = false;
670	bHighpowerstate = priv->bDynamicTxHighPower;
671
672	powerlevelOFDM24G = (u8)(priv->Pwr_Track>>24);
673	RF_Type = priv->rf_type;
674	Value = (RF_Type<<8) | powerlevelOFDM24G;
675
676	RT_TRACE(COMP_POWER_TRACKING, "powerlevelOFDM24G = %x\n", powerlevelOFDM24G);
677
678	for(j = 0; j<=30; j++)
679{	//fill tx_cmd
680
681	tx_cmd.Op		= TXCMD_SET_TX_PWR_TRACKING;
682	tx_cmd.Length	= 4;
683	tx_cmd.Value		= Value;
684#ifdef RTL8192U
685	rtStatus = SendTxCommandPacket(dev, &tx_cmd, 12);
686	if (rtStatus == RT_STATUS_FAILURE)
687	{
688		RT_TRACE(COMP_POWER_TRACKING, "Set configuration with tx cmd queue fail!\n");
689	}
690#else
691	cmpk_message_handle_tx(dev, (u8*)&tx_cmd, DESC_PACKET_TYPE_INIT, sizeof(DCMD_TXCMD_T));
692#endif
693	mdelay(1);
694	//DbgPrint("hi, vivi, strange\n");
695	for(i = 0;i <= 30; i++)
696	{
697		Pwr_Flag = read_nic_byte(dev, Pw_Track_Flag);
698
699		if (Pwr_Flag == 0)
700		{
701			mdelay(1);
702			continue;
703		}
704
705		Avg_TSSI_Meas = read_nic_word(dev, Tssi_Mea_Value);
706
707		if(Avg_TSSI_Meas == 0)
708		{
709			write_nic_byte(dev, Pw_Track_Flag, 0);
710			write_nic_byte(dev, FW_Busy_Flag, 0);
711			return;
712		}
713
714		for(k = 0;k < 5; k++)
715		{
716			if(k !=4)
717				tmp_report[k] = read_nic_byte(dev, Tssi_Report_Value1+k);
718			else
719				tmp_report[k] = read_nic_byte(dev, Tssi_Report_Value2);
720
721			RT_TRACE(COMP_POWER_TRACKING, "TSSI_report_value = %d\n", tmp_report[k]);
722		}
723
724		//check if the report value is right
725		for(k = 0;k < 5; k++)
726		{
727			if(tmp_report[k] <= 20)
728			{
729				viviflag =TRUE;
730				break;
731			}
732		}
733		if(viviflag ==TRUE)
734		{
735			write_nic_byte(dev, Pw_Track_Flag, 0);
736			viviflag = FALSE;
737			RT_TRACE(COMP_POWER_TRACKING, "we filted this data\n");
738			for(k = 0;k < 5; k++)
739				tmp_report[k] = 0;
740			break;
741		}
742
743		for(k = 0;k < 5; k++)
744		{
745			Avg_TSSI_Meas_from_driver += tmp_report[k];
746		}
747
748		Avg_TSSI_Meas_from_driver = Avg_TSSI_Meas_from_driver*100/5;
749		RT_TRACE(COMP_POWER_TRACKING, "Avg_TSSI_Meas_from_driver = %d\n", Avg_TSSI_Meas_from_driver);
750		TSSI_13dBm = priv->TSSI_13dBm;
751		RT_TRACE(COMP_POWER_TRACKING, "TSSI_13dBm = %d\n", TSSI_13dBm);
752
753		//if(abs(Avg_TSSI_Meas_from_driver - TSSI_13dBm) <= E_FOR_TX_POWER_TRACK)
754		// For MacOS-compatible
755		if(Avg_TSSI_Meas_from_driver > TSSI_13dBm)
756			delta = Avg_TSSI_Meas_from_driver - TSSI_13dBm;
757		else
758			delta = TSSI_13dBm - Avg_TSSI_Meas_from_driver;
759
760		if(delta <= E_FOR_TX_POWER_TRACK)
761		{
762			priv->ieee80211->bdynamic_txpower_enable = TRUE;
763			write_nic_byte(dev, Pw_Track_Flag, 0);
764			write_nic_byte(dev, FW_Busy_Flag, 0);
765			RT_TRACE(COMP_POWER_TRACKING, "tx power track is done\n");
766			RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
767			RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
768#ifdef RTL8190P
769			RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex = %d\n", priv->rfc_txpowertrackingindex);
770			RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real = %d\n", priv->rfc_txpowertrackingindex_real);
771#endif
772			RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference = %d\n", priv->CCKPresentAttentuation_difference);
773			RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation = %d\n", priv->CCKPresentAttentuation);
774			return;
775		}
776		else
777		{
778			if(Avg_TSSI_Meas_from_driver < TSSI_13dBm - E_FOR_TX_POWER_TRACK)
779			{
780				if (RF_Type == RF_2T4R)
781				{
782
783						if((priv->rfa_txpowertrackingindex > 0) &&(priv->rfc_txpowertrackingindex > 0))
784				{
785					priv->rfa_txpowertrackingindex--;
786					if(priv->rfa_txpowertrackingindex_real > 4)
787					{
788						priv->rfa_txpowertrackingindex_real--;
789						rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
790					}
791
792					priv->rfc_txpowertrackingindex--;
793					if(priv->rfc_txpowertrackingindex_real > 4)
794					{
795						priv->rfc_txpowertrackingindex_real--;
796						rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
797					}
798						}
799						else
800						{
801								rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[4].txbbgain_value);
802								rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[4].txbbgain_value);
803				}
804			}
805			else
806			{
807						if(priv->rfc_txpowertrackingindex > 0)
808						{
809							priv->rfc_txpowertrackingindex--;
810							if(priv->rfc_txpowertrackingindex_real > 4)
811							{
812								priv->rfc_txpowertrackingindex_real--;
813								rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
814							}
815						}
816						else
817							rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[4].txbbgain_value);
818				}
819			}
820			else
821			{
822				if (RF_Type == RF_2T4R)
823				{
824					if((priv->rfa_txpowertrackingindex < TxBBGainTableLength - 1) &&(priv->rfc_txpowertrackingindex < TxBBGainTableLength - 1))
825				{
826					priv->rfa_txpowertrackingindex++;
827					priv->rfa_txpowertrackingindex_real++;
828					rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
829					priv->rfc_txpowertrackingindex++;
830					priv->rfc_txpowertrackingindex_real++;
831					rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
832				}
833					else
834					{
835						rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value);
836						rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value);
837			}
838				}
839				else
840				{
841					if(priv->rfc_txpowertrackingindex < (TxBBGainTableLength - 1))
842					{
843							priv->rfc_txpowertrackingindex++;
844							priv->rfc_txpowertrackingindex_real++;
845							rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
846					}
847					else
848							rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value);
849				}
850			}
851			if (RF_Type == RF_2T4R)
852			priv->CCKPresentAttentuation_difference
853				= priv->rfa_txpowertrackingindex - priv->rfa_txpowertracking_default;
854			else
855				priv->CCKPresentAttentuation_difference
856					= priv->rfc_txpowertrackingindex - priv->rfc_txpowertracking_default;
857
858			if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
859				priv->CCKPresentAttentuation
860				= priv->CCKPresentAttentuation_20Mdefault + priv->CCKPresentAttentuation_difference;
861			else
862				priv->CCKPresentAttentuation
863				= priv->CCKPresentAttentuation_40Mdefault + priv->CCKPresentAttentuation_difference;
864
865			if(priv->CCKPresentAttentuation > (CCKTxBBGainTableLength-1))
866					priv->CCKPresentAttentuation = CCKTxBBGainTableLength-1;
867			if(priv->CCKPresentAttentuation < 0)
868					priv->CCKPresentAttentuation = 0;
869
870			if(1)
871			{
872				if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14)
873				{
874					priv->bcck_in_ch14 = TRUE;
875					dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
876				}
877				else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14)
878				{
879					priv->bcck_in_ch14 = FALSE;
880					dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
881				}
882				else
883					dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
884			}
885		RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
886		RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
887#ifdef RTL8190P
888		RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex = %d\n", priv->rfc_txpowertrackingindex);
889		RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real = %d\n", priv->rfc_txpowertrackingindex_real);
890#endif
891		RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference = %d\n", priv->CCKPresentAttentuation_difference);
892		RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation = %d\n", priv->CCKPresentAttentuation);
893
894		if (priv->CCKPresentAttentuation_difference <= -12||priv->CCKPresentAttentuation_difference >= 24)
895		{
896			priv->ieee80211->bdynamic_txpower_enable = TRUE;
897			write_nic_byte(dev, Pw_Track_Flag, 0);
898			write_nic_byte(dev, FW_Busy_Flag, 0);
899			RT_TRACE(COMP_POWER_TRACKING, "tx power track--->limited\n");
900			return;
901		}
902
903
904	}
905		write_nic_byte(dev, Pw_Track_Flag, 0);
906		Avg_TSSI_Meas_from_driver = 0;
907		for(k = 0;k < 5; k++)
908			tmp_report[k] = 0;
909		break;
910	}
911	write_nic_byte(dev, FW_Busy_Flag, 0);
912}
913		priv->ieee80211->bdynamic_txpower_enable = TRUE;
914		write_nic_byte(dev, Pw_Track_Flag, 0);
915}
916#ifndef RTL8190P
917static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device * dev)
918{
919#define ThermalMeterVal	9
920	struct r8192_priv *priv = ieee80211_priv(dev);
921	u32 tmpRegA, TempCCk;
922	u8 tmpOFDMindex, tmpCCKindex, tmpCCK20Mindex, tmpCCK40Mindex, tmpval;
923	int i =0, CCKSwingNeedUpdate=0;
924
925	if(!priv->btxpower_trackingInit)
926	{
927		//Query OFDM default setting
928		tmpRegA= rtl8192_QueryBBReg(dev, rOFDM0_XATxIQImbalance, bMaskDWord);
929		for(i=0; i<OFDM_Table_Length; i++)	//find the index
930		{
931			if(tmpRegA == OFDMSwingTable[i])
932			{
933				priv->OFDM_index= (u8)i;
934				RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, OFDM_index=0x%x\n",
935					rOFDM0_XATxIQImbalance, tmpRegA, priv->OFDM_index);
936			}
937		}
938
939		//Query CCK default setting From 0xa22
940		TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
941		for(i=0 ; i<CCK_Table_length ; i++)
942		{
943			if(TempCCk == (u32)CCKSwingTable_Ch1_Ch13[i][0])
944			{
945				priv->CCK_index =(u8) i;
946				RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, CCK_index=0x%x\n",
947					rCCK0_TxFilter1, TempCCk, priv->CCK_index);
948		break;
949	}
950}
951		priv->btxpower_trackingInit = TRUE;
952		//pHalData->TXPowercount = 0;
953		return;
954	}
955
956	// read and filter out unreasonable value
957	tmpRegA = rtl8192_phy_QueryRFReg(dev, RF90_PATH_A, 0x12, 0x078);	// 0x12: RF Reg[10:7]
958	RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d \n", tmpRegA);
959	if(tmpRegA < 3 || tmpRegA > 13)
960		return;
961	if(tmpRegA >= 12)	// if over 12, TP will be bad when high temperature
962		tmpRegA = 12;
963	RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d \n", tmpRegA);
964	priv->ThermalMeter[0] = ThermalMeterVal;	//We use fixed value by Bryant's suggestion
965	priv->ThermalMeter[1] = ThermalMeterVal;	//We use fixed value by Bryant's suggestion
966
967	//Get current RF-A temperature index
968	if(priv->ThermalMeter[0] >= (u8)tmpRegA)	//lower temperature
969	{
970		tmpOFDMindex = tmpCCK20Mindex = 6+(priv->ThermalMeter[0]-(u8)tmpRegA);
971		tmpCCK40Mindex = tmpCCK20Mindex - 6;
972		if(tmpOFDMindex >= OFDM_Table_Length)
973			tmpOFDMindex = OFDM_Table_Length-1;
974		if(tmpCCK20Mindex >= CCK_Table_length)
975			tmpCCK20Mindex = CCK_Table_length-1;
976		if(tmpCCK40Mindex >= CCK_Table_length)
977			tmpCCK40Mindex = CCK_Table_length-1;
978	}
979	else
980	{
981		tmpval = ((u8)tmpRegA - priv->ThermalMeter[0]);
982		if(tmpval >= 6)								// higher temperature
983			tmpOFDMindex = tmpCCK20Mindex = 0;		// max to +6dB
984		else
985			tmpOFDMindex = tmpCCK20Mindex = 6 - tmpval;
986		tmpCCK40Mindex = 0;
987	}
988	//DbgPrint("%ddb, tmpOFDMindex = %d, tmpCCK20Mindex = %d, tmpCCK40Mindex = %d",
989		//((u1Byte)tmpRegA - pHalData->ThermalMeter[0]),
990		//tmpOFDMindex, tmpCCK20Mindex, tmpCCK40Mindex);
991	if(priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)	//40M
992		tmpCCKindex = tmpCCK40Mindex;
993	else
994		tmpCCKindex = tmpCCK20Mindex;
995
996	//record for bandwidth swith
997	priv->Record_CCK_20Mindex = tmpCCK20Mindex;
998	priv->Record_CCK_40Mindex = tmpCCK40Mindex;
999	RT_TRACE(COMP_POWER_TRACKING, "Record_CCK_20Mindex / Record_CCK_40Mindex = %d / %d.\n",
1000		priv->Record_CCK_20Mindex, priv->Record_CCK_40Mindex);
1001
1002	if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14)
1003	{
1004		priv->bcck_in_ch14 = TRUE;
1005		CCKSwingNeedUpdate = 1;
1006	}
1007	else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14)
1008	{
1009		priv->bcck_in_ch14 = FALSE;
1010		CCKSwingNeedUpdate = 1;
1011	}
1012
1013	if(priv->CCK_index != tmpCCKindex)
1014{
1015		priv->CCK_index = tmpCCKindex;
1016		CCKSwingNeedUpdate = 1;
1017	}
1018
1019	if(CCKSwingNeedUpdate)
1020	{
1021		//DbgPrint("Update CCK Swing, CCK_index = %d\n", pHalData->CCK_index);
1022		dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
1023	}
1024	if(priv->OFDM_index != tmpOFDMindex)
1025	{
1026		priv->OFDM_index = tmpOFDMindex;
1027		rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable[priv->OFDM_index]);
1028		RT_TRACE(COMP_POWER_TRACKING, "Update OFDMSwing[%d] = 0x%x\n",
1029			priv->OFDM_index, OFDMSwingTable[priv->OFDM_index]);
1030	}
1031	priv->txpower_count = 0;
1032}
1033#endif
1034void dm_txpower_trackingcallback(struct work_struct *work)
1035{
1036	struct delayed_work *dwork = container_of(work,struct delayed_work,work);
1037       struct r8192_priv *priv = container_of(dwork,struct r8192_priv,txpower_tracking_wq);
1038       struct net_device *dev = priv->ieee80211->dev;
1039
1040#ifdef RTL8190P
1041	dm_TXPowerTrackingCallback_TSSI(dev);
1042#else
1043	//if(priv->bDcut == TRUE)
1044	if(priv->IC_Cut >= IC_VersionCut_D)
1045		dm_TXPowerTrackingCallback_TSSI(dev);
1046	else
1047		dm_TXPowerTrackingCallback_ThermalMeter(dev);
1048#endif
1049}
1050
1051
1052static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev)
1053{
1054
1055	struct r8192_priv *priv = ieee80211_priv(dev);
1056
1057	//Initial the Tx BB index and mapping value
1058	priv->txbbgain_table[0].txbb_iq_amplifygain = 	 		12;
1059	priv->txbbgain_table[0].txbbgain_value=0x7f8001fe;
1060	priv->txbbgain_table[1].txbb_iq_amplifygain = 	 		11;
1061	priv->txbbgain_table[1].txbbgain_value=0x788001e2;
1062	priv->txbbgain_table[2].txbb_iq_amplifygain = 	 		10;
1063	priv->txbbgain_table[2].txbbgain_value=0x71c001c7;
1064	priv->txbbgain_table[3].txbb_iq_amplifygain = 	 		9;
1065	priv->txbbgain_table[3].txbbgain_value=0x6b8001ae;
1066	priv->txbbgain_table[4].txbb_iq_amplifygain = 		       8;
1067	priv->txbbgain_table[4].txbbgain_value=0x65400195;
1068	priv->txbbgain_table[5].txbb_iq_amplifygain = 		       7;
1069	priv->txbbgain_table[5].txbbgain_value=0x5fc0017f;
1070	priv->txbbgain_table[6].txbb_iq_amplifygain = 		       6;
1071	priv->txbbgain_table[6].txbbgain_value=0x5a400169;
1072	priv->txbbgain_table[7].txbb_iq_amplifygain = 		       5;
1073	priv->txbbgain_table[7].txbbgain_value=0x55400155;
1074	priv->txbbgain_table[8].txbb_iq_amplifygain = 		       4;
1075	priv->txbbgain_table[8].txbbgain_value=0x50800142;
1076	priv->txbbgain_table[9].txbb_iq_amplifygain = 		       3;
1077	priv->txbbgain_table[9].txbbgain_value=0x4c000130;
1078	priv->txbbgain_table[10].txbb_iq_amplifygain = 		       2;
1079	priv->txbbgain_table[10].txbbgain_value=0x47c0011f;
1080	priv->txbbgain_table[11].txbb_iq_amplifygain = 		       1;
1081	priv->txbbgain_table[11].txbbgain_value=0x43c0010f;
1082	priv->txbbgain_table[12].txbb_iq_amplifygain = 		       0;
1083	priv->txbbgain_table[12].txbbgain_value=0x40000100;
1084	priv->txbbgain_table[13].txbb_iq_amplifygain = 		       -1;
1085	priv->txbbgain_table[13].txbbgain_value=0x3c8000f2;
1086	priv->txbbgain_table[14].txbb_iq_amplifygain = 		     -2;
1087	priv->txbbgain_table[14].txbbgain_value=0x390000e4;
1088	priv->txbbgain_table[15].txbb_iq_amplifygain = 		     -3;
1089	priv->txbbgain_table[15].txbbgain_value=0x35c000d7;
1090	priv->txbbgain_table[16].txbb_iq_amplifygain = 		     -4;
1091	priv->txbbgain_table[16].txbbgain_value=0x32c000cb;
1092	priv->txbbgain_table[17].txbb_iq_amplifygain = 		     -5;
1093	priv->txbbgain_table[17].txbbgain_value=0x300000c0;
1094	priv->txbbgain_table[18].txbb_iq_amplifygain = 		 	    -6;
1095	priv->txbbgain_table[18].txbbgain_value=0x2d4000b5;
1096	priv->txbbgain_table[19].txbb_iq_amplifygain = 		     -7;
1097	priv->txbbgain_table[19].txbbgain_value=0x2ac000ab;
1098	priv->txbbgain_table[20].txbb_iq_amplifygain = 		     -8;
1099	priv->txbbgain_table[20].txbbgain_value=0x288000a2;
1100	priv->txbbgain_table[21].txbb_iq_amplifygain = 		     -9;
1101	priv->txbbgain_table[21].txbbgain_value=0x26000098;
1102	priv->txbbgain_table[22].txbb_iq_amplifygain = 		     -10;
1103	priv->txbbgain_table[22].txbbgain_value=0x24000090;
1104	priv->txbbgain_table[23].txbb_iq_amplifygain = 		     -11;
1105	priv->txbbgain_table[23].txbbgain_value=0x22000088;
1106	priv->txbbgain_table[24].txbb_iq_amplifygain = 		     -12;
1107	priv->txbbgain_table[24].txbbgain_value=0x20000080;
1108	priv->txbbgain_table[25].txbb_iq_amplifygain = 		     -13;
1109	priv->txbbgain_table[25].txbbgain_value=0x1a00006c;
1110	priv->txbbgain_table[26].txbb_iq_amplifygain = 		     -14;
1111	priv->txbbgain_table[26].txbbgain_value=0x1c800072;
1112	priv->txbbgain_table[27].txbb_iq_amplifygain = 		     -15;
1113	priv->txbbgain_table[27].txbbgain_value=0x18000060;
1114	priv->txbbgain_table[28].txbb_iq_amplifygain = 		     -16;
1115	priv->txbbgain_table[28].txbbgain_value=0x19800066;
1116	priv->txbbgain_table[29].txbb_iq_amplifygain = 		     -17;
1117	priv->txbbgain_table[29].txbbgain_value=0x15800056;
1118	priv->txbbgain_table[30].txbb_iq_amplifygain = 		     -18;
1119	priv->txbbgain_table[30].txbbgain_value=0x26c0005b;
1120	priv->txbbgain_table[31].txbb_iq_amplifygain = 		     -19;
1121	priv->txbbgain_table[31].txbbgain_value=0x14400051;
1122	priv->txbbgain_table[32].txbb_iq_amplifygain = 		     -20;
1123	priv->txbbgain_table[32].txbbgain_value=0x24400051;
1124	priv->txbbgain_table[33].txbb_iq_amplifygain = 		     -21;
1125	priv->txbbgain_table[33].txbbgain_value=0x1300004c;
1126	priv->txbbgain_table[34].txbb_iq_amplifygain = 		     -22;
1127	priv->txbbgain_table[34].txbbgain_value=0x12000048;
1128	priv->txbbgain_table[35].txbb_iq_amplifygain = 		     -23;
1129	priv->txbbgain_table[35].txbbgain_value=0x11000044;
1130	priv->txbbgain_table[36].txbb_iq_amplifygain = 		     -24;
1131	priv->txbbgain_table[36].txbbgain_value=0x10000040;
1132
1133	//ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
1134	//This Table is for CH1~CH13
1135	priv->cck_txbbgain_table[0].ccktxbb_valuearray[0] = 0x36;
1136	priv->cck_txbbgain_table[0].ccktxbb_valuearray[1] = 0x35;
1137	priv->cck_txbbgain_table[0].ccktxbb_valuearray[2] = 0x2e;
1138	priv->cck_txbbgain_table[0].ccktxbb_valuearray[3] = 0x25;
1139	priv->cck_txbbgain_table[0].ccktxbb_valuearray[4] = 0x1c;
1140	priv->cck_txbbgain_table[0].ccktxbb_valuearray[5] = 0x12;
1141	priv->cck_txbbgain_table[0].ccktxbb_valuearray[6] = 0x09;
1142	priv->cck_txbbgain_table[0].ccktxbb_valuearray[7] = 0x04;
1143
1144	priv->cck_txbbgain_table[1].ccktxbb_valuearray[0] = 0x33;
1145	priv->cck_txbbgain_table[1].ccktxbb_valuearray[1] = 0x32;
1146	priv->cck_txbbgain_table[1].ccktxbb_valuearray[2] = 0x2b;
1147	priv->cck_txbbgain_table[1].ccktxbb_valuearray[3] = 0x23;
1148	priv->cck_txbbgain_table[1].ccktxbb_valuearray[4] = 0x1a;
1149	priv->cck_txbbgain_table[1].ccktxbb_valuearray[5] = 0x11;
1150	priv->cck_txbbgain_table[1].ccktxbb_valuearray[6] = 0x08;
1151	priv->cck_txbbgain_table[1].ccktxbb_valuearray[7] = 0x04;
1152
1153	priv->cck_txbbgain_table[2].ccktxbb_valuearray[0] = 0x30;
1154	priv->cck_txbbgain_table[2].ccktxbb_valuearray[1] = 0x2f;
1155	priv->cck_txbbgain_table[2].ccktxbb_valuearray[2] = 0x29;
1156	priv->cck_txbbgain_table[2].ccktxbb_valuearray[3] = 0x21;
1157	priv->cck_txbbgain_table[2].ccktxbb_valuearray[4] = 0x19;
1158	priv->cck_txbbgain_table[2].ccktxbb_valuearray[5] = 0x10;
1159	priv->cck_txbbgain_table[2].ccktxbb_valuearray[6] = 0x08;
1160	priv->cck_txbbgain_table[2].ccktxbb_valuearray[7] = 0x03;
1161
1162	priv->cck_txbbgain_table[3].ccktxbb_valuearray[0] = 0x2d;
1163	priv->cck_txbbgain_table[3].ccktxbb_valuearray[1] = 0x2d;
1164	priv->cck_txbbgain_table[3].ccktxbb_valuearray[2] = 0x27;
1165	priv->cck_txbbgain_table[3].ccktxbb_valuearray[3] = 0x1f;
1166	priv->cck_txbbgain_table[3].ccktxbb_valuearray[4] = 0x18;
1167	priv->cck_txbbgain_table[3].ccktxbb_valuearray[5] = 0x0f;
1168	priv->cck_txbbgain_table[3].ccktxbb_valuearray[6] = 0x08;
1169	priv->cck_txbbgain_table[3].ccktxbb_valuearray[7] = 0x03;
1170
1171	priv->cck_txbbgain_table[4].ccktxbb_valuearray[0] = 0x2b;
1172	priv->cck_txbbgain_table[4].ccktxbb_valuearray[1] = 0x2a;
1173	priv->cck_txbbgain_table[4].ccktxbb_valuearray[2] = 0x25;
1174	priv->cck_txbbgain_table[4].ccktxbb_valuearray[3] = 0x1e;
1175	priv->cck_txbbgain_table[4].ccktxbb_valuearray[4] = 0x16;
1176	priv->cck_txbbgain_table[4].ccktxbb_valuearray[5] = 0x0e;
1177	priv->cck_txbbgain_table[4].ccktxbb_valuearray[6] = 0x07;
1178	priv->cck_txbbgain_table[4].ccktxbb_valuearray[7] = 0x03;
1179
1180	priv->cck_txbbgain_table[5].ccktxbb_valuearray[0] = 0x28;
1181	priv->cck_txbbgain_table[5].ccktxbb_valuearray[1] = 0x28;
1182	priv->cck_txbbgain_table[5].ccktxbb_valuearray[2] = 0x22;
1183	priv->cck_txbbgain_table[5].ccktxbb_valuearray[3] = 0x1c;
1184	priv->cck_txbbgain_table[5].ccktxbb_valuearray[4] = 0x15;
1185	priv->cck_txbbgain_table[5].ccktxbb_valuearray[5] = 0x0d;
1186	priv->cck_txbbgain_table[5].ccktxbb_valuearray[6] = 0x07;
1187	priv->cck_txbbgain_table[5].ccktxbb_valuearray[7] = 0x03;
1188
1189	priv->cck_txbbgain_table[6].ccktxbb_valuearray[0] = 0x26;
1190	priv->cck_txbbgain_table[6].ccktxbb_valuearray[1] = 0x25;
1191	priv->cck_txbbgain_table[6].ccktxbb_valuearray[2] = 0x21;
1192	priv->cck_txbbgain_table[6].ccktxbb_valuearray[3] = 0x1b;
1193	priv->cck_txbbgain_table[6].ccktxbb_valuearray[4] = 0x14;
1194	priv->cck_txbbgain_table[6].ccktxbb_valuearray[5] = 0x0d;
1195	priv->cck_txbbgain_table[6].ccktxbb_valuearray[6] = 0x06;
1196	priv->cck_txbbgain_table[6].ccktxbb_valuearray[7] = 0x03;
1197
1198	priv->cck_txbbgain_table[7].ccktxbb_valuearray[0] = 0x24;
1199	priv->cck_txbbgain_table[7].ccktxbb_valuearray[1] = 0x23;
1200	priv->cck_txbbgain_table[7].ccktxbb_valuearray[2] = 0x1f;
1201	priv->cck_txbbgain_table[7].ccktxbb_valuearray[3] = 0x19;
1202	priv->cck_txbbgain_table[7].ccktxbb_valuearray[4] = 0x13;
1203	priv->cck_txbbgain_table[7].ccktxbb_valuearray[5] = 0x0c;
1204	priv->cck_txbbgain_table[7].ccktxbb_valuearray[6] = 0x06;
1205	priv->cck_txbbgain_table[7].ccktxbb_valuearray[7] = 0x03;
1206
1207	priv->cck_txbbgain_table[8].ccktxbb_valuearray[0] = 0x22;
1208	priv->cck_txbbgain_table[8].ccktxbb_valuearray[1] = 0x21;
1209	priv->cck_txbbgain_table[8].ccktxbb_valuearray[2] = 0x1d;
1210	priv->cck_txbbgain_table[8].ccktxbb_valuearray[3] = 0x18;
1211	priv->cck_txbbgain_table[8].ccktxbb_valuearray[4] = 0x11;
1212	priv->cck_txbbgain_table[8].ccktxbb_valuearray[5] = 0x0b;
1213	priv->cck_txbbgain_table[8].ccktxbb_valuearray[6] = 0x06;
1214	priv->cck_txbbgain_table[8].ccktxbb_valuearray[7] = 0x02;
1215
1216	priv->cck_txbbgain_table[9].ccktxbb_valuearray[0] = 0x20;
1217	priv->cck_txbbgain_table[9].ccktxbb_valuearray[1] = 0x20;
1218	priv->cck_txbbgain_table[9].ccktxbb_valuearray[2] = 0x1b;
1219	priv->cck_txbbgain_table[9].ccktxbb_valuearray[3] = 0x16;
1220	priv->cck_txbbgain_table[9].ccktxbb_valuearray[4] = 0x11;
1221	priv->cck_txbbgain_table[9].ccktxbb_valuearray[5] = 0x08;
1222	priv->cck_txbbgain_table[9].ccktxbb_valuearray[6] = 0x05;
1223	priv->cck_txbbgain_table[9].ccktxbb_valuearray[7] = 0x02;
1224
1225	priv->cck_txbbgain_table[10].ccktxbb_valuearray[0] = 0x1f;
1226	priv->cck_txbbgain_table[10].ccktxbb_valuearray[1] = 0x1e;
1227	priv->cck_txbbgain_table[10].ccktxbb_valuearray[2] = 0x1a;
1228	priv->cck_txbbgain_table[10].ccktxbb_valuearray[3] = 0x15;
1229	priv->cck_txbbgain_table[10].ccktxbb_valuearray[4] = 0x10;
1230	priv->cck_txbbgain_table[10].ccktxbb_valuearray[5] = 0x0a;
1231	priv->cck_txbbgain_table[10].ccktxbb_valuearray[6] = 0x05;
1232	priv->cck_txbbgain_table[10].ccktxbb_valuearray[7] = 0x02;
1233
1234	priv->cck_txbbgain_table[11].ccktxbb_valuearray[0] = 0x1d;
1235	priv->cck_txbbgain_table[11].ccktxbb_valuearray[1] = 0x1c;
1236	priv->cck_txbbgain_table[11].ccktxbb_valuearray[2] = 0x18;
1237	priv->cck_txbbgain_table[11].ccktxbb_valuearray[3] = 0x14;
1238	priv->cck_txbbgain_table[11].ccktxbb_valuearray[4] = 0x0f;
1239	priv->cck_txbbgain_table[11].ccktxbb_valuearray[5] = 0x0a;
1240	priv->cck_txbbgain_table[11].ccktxbb_valuearray[6] = 0x05;
1241	priv->cck_txbbgain_table[11].ccktxbb_valuearray[7] = 0x02;
1242
1243	priv->cck_txbbgain_table[12].ccktxbb_valuearray[0] = 0x1b;
1244	priv->cck_txbbgain_table[12].ccktxbb_valuearray[1] = 0x1a;
1245	priv->cck_txbbgain_table[12].ccktxbb_valuearray[2] = 0x17;
1246	priv->cck_txbbgain_table[12].ccktxbb_valuearray[3] = 0x13;
1247	priv->cck_txbbgain_table[12].ccktxbb_valuearray[4] = 0x0e;
1248	priv->cck_txbbgain_table[12].ccktxbb_valuearray[5] = 0x09;
1249	priv->cck_txbbgain_table[12].ccktxbb_valuearray[6] = 0x04;
1250	priv->cck_txbbgain_table[12].ccktxbb_valuearray[7] = 0x02;
1251
1252	priv->cck_txbbgain_table[13].ccktxbb_valuearray[0] = 0x1a;
1253	priv->cck_txbbgain_table[13].ccktxbb_valuearray[1] = 0x19;
1254	priv->cck_txbbgain_table[13].ccktxbb_valuearray[2] = 0x16;
1255	priv->cck_txbbgain_table[13].ccktxbb_valuearray[3] = 0x12;
1256	priv->cck_txbbgain_table[13].ccktxbb_valuearray[4] = 0x0d;
1257	priv->cck_txbbgain_table[13].ccktxbb_valuearray[5] = 0x09;
1258	priv->cck_txbbgain_table[13].ccktxbb_valuearray[6] = 0x04;
1259	priv->cck_txbbgain_table[13].ccktxbb_valuearray[7] = 0x02;
1260
1261	priv->cck_txbbgain_table[14].ccktxbb_valuearray[0] = 0x18;
1262	priv->cck_txbbgain_table[14].ccktxbb_valuearray[1] = 0x17;
1263	priv->cck_txbbgain_table[14].ccktxbb_valuearray[2] = 0x15;
1264	priv->cck_txbbgain_table[14].ccktxbb_valuearray[3] = 0x11;
1265	priv->cck_txbbgain_table[14].ccktxbb_valuearray[4] = 0x0c;
1266	priv->cck_txbbgain_table[14].ccktxbb_valuearray[5] = 0x08;
1267	priv->cck_txbbgain_table[14].ccktxbb_valuearray[6] = 0x04;
1268	priv->cck_txbbgain_table[14].ccktxbb_valuearray[7] = 0x02;
1269
1270	priv->cck_txbbgain_table[15].ccktxbb_valuearray[0] = 0x17;
1271	priv->cck_txbbgain_table[15].ccktxbb_valuearray[1] = 0x16;
1272	priv->cck_txbbgain_table[15].ccktxbb_valuearray[2] = 0x13;
1273	priv->cck_txbbgain_table[15].ccktxbb_valuearray[3] = 0x10;
1274	priv->cck_txbbgain_table[15].ccktxbb_valuearray[4] = 0x0c;
1275	priv->cck_txbbgain_table[15].ccktxbb_valuearray[5] = 0x08;
1276	priv->cck_txbbgain_table[15].ccktxbb_valuearray[6] = 0x04;
1277	priv->cck_txbbgain_table[15].ccktxbb_valuearray[7] = 0x02;
1278
1279	priv->cck_txbbgain_table[16].ccktxbb_valuearray[0] = 0x16;
1280	priv->cck_txbbgain_table[16].ccktxbb_valuearray[1] = 0x15;
1281	priv->cck_txbbgain_table[16].ccktxbb_valuearray[2] = 0x12;
1282	priv->cck_txbbgain_table[16].ccktxbb_valuearray[3] = 0x0f;
1283	priv->cck_txbbgain_table[16].ccktxbb_valuearray[4] = 0x0b;
1284	priv->cck_txbbgain_table[16].ccktxbb_valuearray[5] = 0x07;
1285	priv->cck_txbbgain_table[16].ccktxbb_valuearray[6] = 0x04;
1286	priv->cck_txbbgain_table[16].ccktxbb_valuearray[7] = 0x01;
1287
1288	priv->cck_txbbgain_table[17].ccktxbb_valuearray[0] = 0x14;
1289	priv->cck_txbbgain_table[17].ccktxbb_valuearray[1] = 0x14;
1290	priv->cck_txbbgain_table[17].ccktxbb_valuearray[2] = 0x11;
1291	priv->cck_txbbgain_table[17].ccktxbb_valuearray[3] = 0x0e;
1292	priv->cck_txbbgain_table[17].ccktxbb_valuearray[4] = 0x0b;
1293	priv->cck_txbbgain_table[17].ccktxbb_valuearray[5] = 0x07;
1294	priv->cck_txbbgain_table[17].ccktxbb_valuearray[6] = 0x03;
1295	priv->cck_txbbgain_table[17].ccktxbb_valuearray[7] = 0x02;
1296
1297	priv->cck_txbbgain_table[18].ccktxbb_valuearray[0] = 0x13;
1298	priv->cck_txbbgain_table[18].ccktxbb_valuearray[1] = 0x13;
1299	priv->cck_txbbgain_table[18].ccktxbb_valuearray[2] = 0x10;
1300	priv->cck_txbbgain_table[18].ccktxbb_valuearray[3] = 0x0d;
1301	priv->cck_txbbgain_table[18].ccktxbb_valuearray[4] = 0x0a;
1302	priv->cck_txbbgain_table[18].ccktxbb_valuearray[5] = 0x06;
1303	priv->cck_txbbgain_table[18].ccktxbb_valuearray[6] = 0x03;
1304	priv->cck_txbbgain_table[18].ccktxbb_valuearray[7] = 0x01;
1305
1306	priv->cck_txbbgain_table[19].ccktxbb_valuearray[0] = 0x12;
1307	priv->cck_txbbgain_table[19].ccktxbb_valuearray[1] = 0x12;
1308	priv->cck_txbbgain_table[19].ccktxbb_valuearray[2] = 0x0f;
1309	priv->cck_txbbgain_table[19].ccktxbb_valuearray[3] = 0x0c;
1310	priv->cck_txbbgain_table[19].ccktxbb_valuearray[4] = 0x09;
1311	priv->cck_txbbgain_table[19].ccktxbb_valuearray[5] = 0x06;
1312	priv->cck_txbbgain_table[19].ccktxbb_valuearray[6] = 0x03;
1313	priv->cck_txbbgain_table[19].ccktxbb_valuearray[7] = 0x01;
1314
1315	priv->cck_txbbgain_table[20].ccktxbb_valuearray[0] = 0x11;
1316	priv->cck_txbbgain_table[20].ccktxbb_valuearray[1] = 0x11;
1317	priv->cck_txbbgain_table[20].ccktxbb_valuearray[2] = 0x0f;
1318	priv->cck_txbbgain_table[20].ccktxbb_valuearray[3] = 0x0c;
1319	priv->cck_txbbgain_table[20].ccktxbb_valuearray[4] = 0x09;
1320	priv->cck_txbbgain_table[20].ccktxbb_valuearray[5] = 0x06;
1321	priv->cck_txbbgain_table[20].ccktxbb_valuearray[6] = 0x03;
1322	priv->cck_txbbgain_table[20].ccktxbb_valuearray[7] = 0x01;
1323
1324	priv->cck_txbbgain_table[21].ccktxbb_valuearray[0] = 0x10;
1325	priv->cck_txbbgain_table[21].ccktxbb_valuearray[1] = 0x10;
1326	priv->cck_txbbgain_table[21].ccktxbb_valuearray[2] = 0x0e;
1327	priv->cck_txbbgain_table[21].ccktxbb_valuearray[3] = 0x0b;
1328	priv->cck_txbbgain_table[21].ccktxbb_valuearray[4] = 0x08;
1329	priv->cck_txbbgain_table[21].ccktxbb_valuearray[5] = 0x05;
1330	priv->cck_txbbgain_table[21].ccktxbb_valuearray[6] = 0x03;
1331	priv->cck_txbbgain_table[21].ccktxbb_valuearray[7] = 0x01;
1332
1333	priv->cck_txbbgain_table[22].ccktxbb_valuearray[0] = 0x0f;
1334	priv->cck_txbbgain_table[22].ccktxbb_valuearray[1] = 0x0f;
1335	priv->cck_txbbgain_table[22].ccktxbb_valuearray[2] = 0x0d;
1336	priv->cck_txbbgain_table[22].ccktxbb_valuearray[3] = 0x0b;
1337	priv->cck_txbbgain_table[22].ccktxbb_valuearray[4] = 0x08;
1338	priv->cck_txbbgain_table[22].ccktxbb_valuearray[5] = 0x05;
1339	priv->cck_txbbgain_table[22].ccktxbb_valuearray[6] = 0x03;
1340	priv->cck_txbbgain_table[22].ccktxbb_valuearray[7] = 0x01;
1341
1342	//ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
1343	//This Table is for CH14
1344	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[0] = 0x36;
1345	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[1] = 0x35;
1346	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[2] = 0x2e;
1347	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[3] = 0x1b;
1348	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[4] = 0x00;
1349	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[5] = 0x00;
1350	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[6] = 0x00;
1351	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[7] = 0x00;
1352
1353	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[0] = 0x33;
1354	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[1] = 0x32;
1355	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[2] = 0x2b;
1356	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[3] = 0x19;
1357	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[4] = 0x00;
1358	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[5] = 0x00;
1359	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[6] = 0x00;
1360	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[7] = 0x00;
1361
1362	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[0] = 0x30;
1363	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[1] = 0x2f;
1364	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[2] = 0x29;
1365	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[3] = 0x18;
1366	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[4] = 0x00;
1367	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[5] = 0x00;
1368	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[6] = 0x00;
1369	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[7] = 0x00;
1370
1371	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[0] = 0x2d;
1372	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[1] = 0x2d;
1373	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[2] = 0x27;
1374	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[3] = 0x17;
1375	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[4] = 0x00;
1376	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[5] = 0x00;
1377	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[6] = 0x00;
1378	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[7] = 0x00;
1379
1380	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[0] = 0x2b;
1381	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[1] = 0x2a;
1382	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[2] = 0x25;
1383	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[3] = 0x15;
1384	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[4] = 0x00;
1385	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[5] = 0x00;
1386	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[6] = 0x00;
1387	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[7] = 0x00;
1388
1389	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[0] = 0x28;
1390	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[1] = 0x28;
1391	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[2] = 0x22;
1392	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[3] = 0x14;
1393	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[4] = 0x00;
1394	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[5] = 0x00;
1395	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[6] = 0x00;
1396	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[7] = 0x00;
1397
1398	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[0] = 0x26;
1399	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[1] = 0x25;
1400	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[2] = 0x21;
1401	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[3] = 0x13;
1402	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[4] = 0x00;
1403	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[5] = 0x00;
1404	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[6] = 0x00;
1405	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[7] = 0x00;
1406
1407	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[0] = 0x24;
1408	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[1] = 0x23;
1409	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[2] = 0x1f;
1410	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[3] = 0x12;
1411	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[4] = 0x00;
1412	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[5] = 0x00;
1413	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[6] = 0x00;
1414	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[7] = 0x00;
1415
1416	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[0] = 0x22;
1417	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[1] = 0x21;
1418	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[2] = 0x1d;
1419	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[3] = 0x11;
1420	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[4] = 0x00;
1421	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[5] = 0x00;
1422	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[6] = 0x00;
1423	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[7] = 0x00;
1424
1425	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[0] = 0x20;
1426	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[1] = 0x20;
1427	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[2] = 0x1b;
1428	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[3] = 0x10;
1429	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[4] = 0x00;
1430	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[5] = 0x00;
1431	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[6] = 0x00;
1432	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[7] = 0x00;
1433
1434	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[0] = 0x1f;
1435	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[1] = 0x1e;
1436	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[2] = 0x1a;
1437	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[3] = 0x0f;
1438	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[4] = 0x00;
1439	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[5] = 0x00;
1440	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[6] = 0x00;
1441	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[7] = 0x00;
1442
1443	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[0] = 0x1d;
1444	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[1] = 0x1c;
1445	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[2] = 0x18;
1446	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[3] = 0x0e;
1447	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[4] = 0x00;
1448	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[5] = 0x00;
1449	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[6] = 0x00;
1450	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[7] = 0x00;
1451
1452	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[0] = 0x1b;
1453	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[1] = 0x1a;
1454	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[2] = 0x17;
1455	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[3] = 0x0e;
1456	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[4] = 0x00;
1457	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[5] = 0x00;
1458	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[6] = 0x00;
1459	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[7] = 0x00;
1460
1461	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[0] = 0x1a;
1462	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[1] = 0x19;
1463	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[2] = 0x16;
1464	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[3] = 0x0d;
1465	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[4] = 0x00;
1466	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[5] = 0x00;
1467	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[6] = 0x00;
1468	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[7] = 0x00;
1469
1470	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[0] = 0x18;
1471	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[1] = 0x17;
1472	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[2] = 0x15;
1473	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[3] = 0x0c;
1474	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[4] = 0x00;
1475	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[5] = 0x00;
1476	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[6] = 0x00;
1477	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[7] = 0x00;
1478
1479	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[0] = 0x17;
1480	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[1] = 0x16;
1481	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[2] = 0x13;
1482	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[3] = 0x0b;
1483	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[4] = 0x00;
1484	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[5] = 0x00;
1485	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[6] = 0x00;
1486	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[7] = 0x00;
1487
1488	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[0] = 0x16;
1489	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[1] = 0x15;
1490	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[2] = 0x12;
1491	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[3] = 0x0b;
1492	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[4] = 0x00;
1493	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[5] = 0x00;
1494	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[6] = 0x00;
1495	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[7] = 0x00;
1496
1497	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[0] = 0x14;
1498	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[1] = 0x14;
1499	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[2] = 0x11;
1500	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[3] = 0x0a;
1501	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[4] = 0x00;
1502	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[5] = 0x00;
1503	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[6] = 0x00;
1504	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[7] = 0x00;
1505
1506	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[0] = 0x13;
1507	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[1] = 0x13;
1508	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[2] = 0x10;
1509	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[3] = 0x0a;
1510	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[4] = 0x00;
1511	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[5] = 0x00;
1512	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[6] = 0x00;
1513	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[7] = 0x00;
1514
1515	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[0] = 0x12;
1516	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[1] = 0x12;
1517	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[2] = 0x0f;
1518	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[3] = 0x09;
1519	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[4] = 0x00;
1520	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[5] = 0x00;
1521	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[6] = 0x00;
1522	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[7] = 0x00;
1523
1524	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[0] = 0x11;
1525	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[1] = 0x11;
1526	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[2] = 0x0f;
1527	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[3] = 0x09;
1528	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[4] = 0x00;
1529	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[5] = 0x00;
1530	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[6] = 0x00;
1531	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[7] = 0x00;
1532
1533	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[0] = 0x10;
1534	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[1] = 0x10;
1535	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[2] = 0x0e;
1536	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[3] = 0x08;
1537	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[4] = 0x00;
1538	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[5] = 0x00;
1539	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[6] = 0x00;
1540	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[7] = 0x00;
1541
1542	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[0] = 0x0f;
1543	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[1] = 0x0f;
1544	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[2] = 0x0d;
1545	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[3] = 0x08;
1546	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[4] = 0x00;
1547	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[5] = 0x00;
1548	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[6] = 0x00;
1549	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[7] = 0x00;
1550
1551	priv->btxpower_tracking = TRUE;
1552	priv->txpower_count       = 0;
1553	priv->btxpower_trackingInit = FALSE;
1554
1555}
1556#ifndef RTL8190P
1557static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev)
1558{
1559	struct r8192_priv *priv = ieee80211_priv(dev);
1560
1561	// Tx Power tracking by Theremal Meter require Firmware R/W 3-wire. This mechanism
1562	// can be enabled only when Firmware R/W 3-wire is enabled. Otherwise, frequent r/w
1563	// 3-wire by driver cause RF goes into wrong state.
1564	if(priv->ieee80211->FwRWRF)
1565		priv->btxpower_tracking = TRUE;
1566	else
1567		priv->btxpower_tracking = FALSE;
1568	priv->txpower_count       = 0;
1569	priv->btxpower_trackingInit = FALSE;
1570}
1571#endif
1572
1573void dm_initialize_txpower_tracking(struct net_device *dev)
1574{
1575#ifndef RTL8190P
1576	struct r8192_priv *priv = ieee80211_priv(dev);
1577#endif
1578#ifdef RTL8190P
1579	dm_InitializeTXPowerTracking_TSSI(dev);
1580#else
1581	//if(priv->bDcut == TRUE)
1582	if(priv->IC_Cut >= IC_VersionCut_D)
1583		dm_InitializeTXPowerTracking_TSSI(dev);
1584	else
1585		dm_InitializeTXPowerTracking_ThermalMeter(dev);
1586#endif
1587}	// dm_InitializeTXPowerTracking
1588
1589
1590static void dm_CheckTXPowerTracking_TSSI(struct net_device *dev)
1591{
1592	struct r8192_priv *priv = ieee80211_priv(dev);
1593	static u32 tx_power_track_counter = 0;
1594	RT_TRACE(COMP_POWER_TRACKING,"%s()\n",__FUNCTION__);
1595	if(read_nic_byte(dev, 0x11e) ==1)
1596		return;
1597	if(!priv->btxpower_tracking)
1598		return;
1599	tx_power_track_counter++;
1600
1601
1602	 if(tx_power_track_counter > 90)
1603	 	{
1604				queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0);
1605		tx_power_track_counter =0;
1606	 	}
1607
1608}
1609
1610#ifndef RTL8190P
1611static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev)
1612{
1613	struct r8192_priv *priv = ieee80211_priv(dev);
1614	static u8 	TM_Trigger=0;
1615
1616	//DbgPrint("dm_CheckTXPowerTracking() \n");
1617	if(!priv->btxpower_tracking)
1618		return;
1619	else
1620	{
1621		if(priv->txpower_count  <= 2)
1622		{
1623			priv->txpower_count++;
1624			return;
1625		}
1626	}
1627
1628	if(!TM_Trigger)
1629	{
1630		//Attention!! You have to wirte all 12bits data to RF, or it may cause RF to crash
1631		//actually write reg0x02 bit1=0, then bit1=1.
1632		//DbgPrint("Trigger ThermalMeter, write RF reg0x2 = 0x4d to 0x4f\n");
1633		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
1634		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
1635		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
1636		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
1637		TM_Trigger = 1;
1638		return;
1639	}
1640	else
1641		{
1642		//DbgPrint("Schedule TxPowerTrackingWorkItem\n");
1643			queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0);
1644		TM_Trigger = 0;
1645		}
1646}
1647#endif
1648
1649static void dm_check_txpower_tracking(struct net_device *dev)
1650{
1651#ifndef RTL8190P
1652	struct r8192_priv *priv = ieee80211_priv(dev);
1653	//static u32 tx_power_track_counter = 0;
1654#endif
1655#ifdef  RTL8190P
1656	dm_CheckTXPowerTracking_TSSI(dev);
1657#else
1658	//if(priv->bDcut == TRUE)
1659	if(priv->IC_Cut >= IC_VersionCut_D)
1660		dm_CheckTXPowerTracking_TSSI(dev);
1661	else
1662		dm_CheckTXPowerTracking_ThermalMeter(dev);
1663#endif
1664
1665}	// dm_CheckTXPowerTracking
1666
1667
1668static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool  bInCH14)
1669{
1670	u32 TempVal;
1671	struct r8192_priv *priv = ieee80211_priv(dev);
1672	//Write 0xa22 0xa23
1673	TempVal = 0;
1674	if(!bInCH14){
1675		//Write 0xa22 0xa23
1676		TempVal = 	(u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[0] +
1677					(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[1]<<8)) ;
1678
1679		rtl8192_setBBreg(dev, rCCK0_TxFilter1,bMaskHWord, TempVal);
1680		//Write 0xa24 ~ 0xa27
1681		TempVal = 0;
1682		TempVal = 	(u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[2] +
1683					(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[3]<<8) +
1684					(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[4]<<16 )+
1685					(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[5]<<24));
1686		rtl8192_setBBreg(dev, rCCK0_TxFilter2,bMaskDWord, TempVal);
1687		//Write 0xa28  0xa29
1688		TempVal = 0;
1689		TempVal = 	(u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[6] +
1690					(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[7]<<8)) ;
1691
1692		rtl8192_setBBreg(dev, rCCK0_DebugPort,bMaskLWord, TempVal);
1693	}
1694	else
1695	{
1696		TempVal = 	(u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[0] +
1697					(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[1]<<8)) ;
1698
1699		rtl8192_setBBreg(dev, rCCK0_TxFilter1,bMaskHWord, TempVal);
1700		//Write 0xa24 ~ 0xa27
1701		TempVal = 0;
1702		TempVal = 	(u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[2] +
1703					(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[3]<<8) +
1704					(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[4]<<16 )+
1705					(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[5]<<24));
1706		rtl8192_setBBreg(dev, rCCK0_TxFilter2,bMaskDWord, TempVal);
1707		//Write 0xa28  0xa29
1708		TempVal = 0;
1709		TempVal = 	(u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[6] +
1710					(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[7]<<8)) ;
1711
1712		rtl8192_setBBreg(dev, rCCK0_DebugPort,bMaskLWord, TempVal);
1713	}
1714
1715
1716}
1717#ifndef RTL8190P
1718static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev,	bool  bInCH14)
1719{
1720	u32 TempVal;
1721	struct r8192_priv *priv = ieee80211_priv(dev);
1722
1723	TempVal = 0;
1724	if(!bInCH14)
1725	{
1726		//Write 0xa22 0xa23
1727		TempVal = 	CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] +
1728					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][1]<<8) ;
1729		rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1730		RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1731			rCCK0_TxFilter1, TempVal);
1732		//Write 0xa24 ~ 0xa27
1733		TempVal = 0;
1734		TempVal = 	CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] +
1735					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][3]<<8) +
1736					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][4]<<16 )+
1737					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][5]<<24);
1738		rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1739		RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1740			rCCK0_TxFilter2, TempVal);
1741		//Write 0xa28  0xa29
1742		TempVal = 0;
1743		TempVal = 	CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] +
1744					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8) ;
1745
1746		rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1747		RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1748			rCCK0_DebugPort, TempVal);
1749	}
1750	else
1751	{
1752//		priv->CCKTxPowerAdjustCntNotCh14++;	//cosa add for debug.
1753		//Write 0xa22 0xa23
1754		TempVal = 	CCKSwingTable_Ch14[priv->CCK_index][0] +
1755					(CCKSwingTable_Ch14[priv->CCK_index][1]<<8) ;
1756
1757		rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1758		RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1759			rCCK0_TxFilter1, TempVal);
1760		//Write 0xa24 ~ 0xa27
1761		TempVal = 0;
1762		TempVal = 	CCKSwingTable_Ch14[priv->CCK_index][2] +
1763					(CCKSwingTable_Ch14[priv->CCK_index][3]<<8) +
1764					(CCKSwingTable_Ch14[priv->CCK_index][4]<<16 )+
1765					(CCKSwingTable_Ch14[priv->CCK_index][5]<<24);
1766		rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1767		RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1768			rCCK0_TxFilter2, TempVal);
1769		//Write 0xa28  0xa29
1770		TempVal = 0;
1771		TempVal = 	CCKSwingTable_Ch14[priv->CCK_index][6] +
1772					(CCKSwingTable_Ch14[priv->CCK_index][7]<<8) ;
1773
1774		rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1775		RT_TRACE(COMP_POWER_TRACKING,"CCK chnl 14, reg 0x%x = 0x%x\n",
1776			rCCK0_DebugPort, TempVal);
1777	}
1778	}
1779#endif
1780
1781
1782void dm_cck_txpower_adjust(struct net_device *dev, bool binch14)
1783{	// dm_CCKTxPowerAdjust
1784#ifndef RTL8190P
1785	struct r8192_priv *priv = ieee80211_priv(dev);
1786#endif
1787#ifdef RTL8190P
1788	dm_CCKTxPowerAdjust_TSSI(dev, binch14);
1789#else
1790	//if(priv->bDcut == TRUE)
1791	if(priv->IC_Cut >= IC_VersionCut_D)
1792		dm_CCKTxPowerAdjust_TSSI(dev, binch14);
1793	else
1794		dm_CCKTxPowerAdjust_ThermalMeter(dev, binch14);
1795#endif
1796}
1797
1798
1799#ifndef  RTL8192U
1800static void dm_txpower_reset_recovery(
1801	struct net_device *dev
1802)
1803{
1804	struct r8192_priv *priv = ieee80211_priv(dev);
1805
1806	RT_TRACE(COMP_POWER_TRACKING, "Start Reset Recovery ==>\n");
1807	rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value);
1808	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc80 is %08x\n",priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value);
1809	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFA_txPowerTrackingIndex is %x\n",priv->rfa_txpowertrackingindex);
1810	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF A I/Q Amplify Gain is %ld\n",priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbb_iq_amplifygain);
1811	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: CCK Attenuation is %d dB\n",priv->CCKPresentAttentuation);
1812	dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
1813
1814	rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value);
1815	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc90 is %08x\n",priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value);
1816	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFC_txPowerTrackingIndex is %x\n",priv->rfc_txpowertrackingindex);
1817	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF C I/Q Amplify Gain is %ld\n",priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbb_iq_amplifygain);
1818
1819}	// dm_TXPowerResetRecovery
1820
1821void dm_restore_dynamic_mechanism_state(struct net_device *dev)
1822{
1823	struct r8192_priv *priv = ieee80211_priv(dev);
1824	u32 	reg_ratr = priv->rate_adaptive.last_ratr;
1825
1826	if(!priv->up)
1827	{
1828		RT_TRACE(COMP_RATE, "<---- dm_restore_dynamic_mechanism_state(): driver is going to unload\n");
1829		return;
1830	}
1831
1832	//
1833	// Restore previous state for rate adaptive
1834	//
1835	if(priv->rate_adaptive.rate_adaptive_disabled)
1836		return;
1837	// TODO: Only 11n mode is implemented currently,
1838	if( !(priv->ieee80211->mode==WIRELESS_MODE_N_24G ||
1839		 priv->ieee80211->mode==WIRELESS_MODE_N_5G))
1840		 return;
1841	{
1842			/* 2007/11/15 MH Copy from 8190PCI. */
1843			u32 ratr_value;
1844			ratr_value = reg_ratr;
1845			if(priv->rf_type == RF_1T2R)	// 1T2R, Spatial Stream 2 should be disabled
1846			{
1847				ratr_value &=~ (RATE_ALL_OFDM_2SS);
1848				//DbgPrint("HW_VAR_TATR_0 from 0x%x ==> 0x%x\n", ((pu4Byte)(val))[0], ratr_value);
1849			}
1850			//DbgPrint("set HW_VAR_TATR_0 = 0x%x\n", ratr_value);
1851			//cosa PlatformEFIOWrite4Byte(Adapter, RATR0, ((pu4Byte)(val))[0]);
1852			write_nic_dword(dev, RATR0, ratr_value);
1853			write_nic_byte(dev, UFWP, 1);
1854	}
1855	//Resore TX Power Tracking Index
1856	if(priv->btxpower_trackingInit && priv->btxpower_tracking){
1857		dm_txpower_reset_recovery(dev);
1858	}
1859
1860	//
1861	//Restore BB Initial Gain
1862	//
1863	dm_bb_initialgain_restore(dev);
1864
1865}	// DM_RestoreDynamicMechanismState
1866
1867static void dm_bb_initialgain_restore(struct net_device *dev)
1868{
1869	struct r8192_priv *priv = ieee80211_priv(dev);
1870	u32 bit_mask = 0x7f; //Bit0~ Bit6
1871
1872	if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1873		return;
1874
1875	//Disable Initial Gain
1876	//PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800);
1877	rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	// Only clear byte 1 and rewrite.
1878	rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bit_mask, (u32)priv->initgain_backup.xaagccore1);
1879	rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bit_mask, (u32)priv->initgain_backup.xbagccore1);
1880	rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, bit_mask, (u32)priv->initgain_backup.xcagccore1);
1881	rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, bit_mask, (u32)priv->initgain_backup.xdagccore1);
1882	bit_mask  = bMaskByte2;
1883	rtl8192_setBBreg(dev, rCCK0_CCA, bit_mask, (u32)priv->initgain_backup.cca);
1884
1885	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc50 is %x\n",priv->initgain_backup.xaagccore1);
1886	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc58 is %x\n",priv->initgain_backup.xbagccore1);
1887	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc60 is %x\n",priv->initgain_backup.xcagccore1);
1888	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc68 is %x\n",priv->initgain_backup.xdagccore1);
1889	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xa0a is %x\n",priv->initgain_backup.cca);
1890	//Enable Initial Gain
1891	//PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x100);
1892	rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);	// Only clear byte 1 and rewrite.
1893
1894}	// dm_BBInitialGainRestore
1895
1896
1897void dm_backup_dynamic_mechanism_state(struct net_device *dev)
1898{
1899	struct r8192_priv *priv = ieee80211_priv(dev);
1900
1901	// Fsync to avoid reset
1902	priv->bswitch_fsync  = false;
1903	priv->bfsync_processing = false;
1904	//Backup BB InitialGain
1905	dm_bb_initialgain_backup(dev);
1906
1907}	// DM_BackupDynamicMechanismState
1908
1909
1910static void dm_bb_initialgain_backup(struct net_device *dev)
1911{
1912	struct r8192_priv *priv = ieee80211_priv(dev);
1913	u32 bit_mask = bMaskByte0; //Bit0~ Bit6
1914
1915	if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1916		return;
1917
1918	//PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800);
1919	rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	// Only clear byte 1 and rewrite.
1920	priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, bit_mask);
1921	priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, bit_mask);
1922	priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, bit_mask);
1923	priv->initgain_backup.xdagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, bit_mask);
1924	bit_mask  = bMaskByte2;
1925	priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, bit_mask);
1926
1927	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc50 is %x\n",priv->initgain_backup.xaagccore1);
1928	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc58 is %x\n",priv->initgain_backup.xbagccore1);
1929	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc60 is %x\n",priv->initgain_backup.xcagccore1);
1930	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc68 is %x\n",priv->initgain_backup.xdagccore1);
1931	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xa0a is %x\n",priv->initgain_backup.cca);
1932
1933}   // dm_BBInitialGainBakcup
1934
1935#endif
1936/*-----------------------------------------------------------------------------
1937 * Function:	dm_change_dynamic_initgain_thresh()
1938 *
1939 * Overview:
1940 *
1941 * Input:		NONE
1942 *
1943 * Output:		NONE
1944 *
1945 * Return:		NONE
1946 *
1947 * Revised History:
1948 *	When		Who		Remark
1949 *	05/29/2008	amy		Create Version 0 porting from windows code.
1950 *
1951 *---------------------------------------------------------------------------*/
1952void dm_change_dynamic_initgain_thresh(struct net_device *dev, u32 dm_type, u32	dm_value)
1953{
1954	if (dm_type == DIG_TYPE_THRESH_HIGH)
1955	{
1956		dm_digtable.rssi_high_thresh = dm_value;
1957	}
1958	else if (dm_type == DIG_TYPE_THRESH_LOW)
1959	{
1960		dm_digtable.rssi_low_thresh = dm_value;
1961	}
1962	else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH)
1963	{
1964		dm_digtable.rssi_high_power_highthresh = dm_value;
1965	}
1966	else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH)
1967	{
1968		dm_digtable.rssi_high_power_highthresh = dm_value;
1969	}
1970	else if (dm_type == DIG_TYPE_ENABLE)
1971	{
1972		dm_digtable.dig_state		= DM_STA_DIG_MAX;
1973		dm_digtable.dig_enable_flag	= true;
1974	}
1975	else if (dm_type == DIG_TYPE_DISABLE)
1976	{
1977		dm_digtable.dig_state		= DM_STA_DIG_MAX;
1978		dm_digtable.dig_enable_flag	= false;
1979	}
1980	else if (dm_type == DIG_TYPE_DBG_MODE)
1981	{
1982		if(dm_value >= DM_DBG_MAX)
1983			dm_value = DM_DBG_OFF;
1984		dm_digtable.dbg_mode		= (u8)dm_value;
1985	}
1986	else if (dm_type == DIG_TYPE_RSSI)
1987	{
1988		if(dm_value > 100)
1989			dm_value = 30;
1990		dm_digtable.rssi_val			= (long)dm_value;
1991	}
1992	else if (dm_type == DIG_TYPE_ALGORITHM)
1993	{
1994		if (dm_value >= DIG_ALGO_MAX)
1995			dm_value = DIG_ALGO_BY_FALSE_ALARM;
1996		if(dm_digtable.dig_algorithm != (u8)dm_value)
1997			dm_digtable.dig_algorithm_switch = 1;
1998		dm_digtable.dig_algorithm	= (u8)dm_value;
1999	}
2000	else if (dm_type == DIG_TYPE_BACKOFF)
2001	{
2002		if(dm_value > 30)
2003			dm_value = 30;
2004		dm_digtable.backoff_val		= (u8)dm_value;
2005	}
2006	else if(dm_type == DIG_TYPE_RX_GAIN_MIN)
2007	{
2008		if(dm_value == 0)
2009			dm_value = 0x1;
2010		dm_digtable.rx_gain_range_min = (u8)dm_value;
2011	}
2012	else if(dm_type == DIG_TYPE_RX_GAIN_MAX)
2013	{
2014		if(dm_value > 0x50)
2015			dm_value = 0x50;
2016		dm_digtable.rx_gain_range_max = (u8)dm_value;
2017	}
2018}	/* DM_ChangeDynamicInitGainThresh */
2019
2020
2021/*-----------------------------------------------------------------------------
2022 * Function:	dm_dig_init()
2023 *
2024 * Overview:	Set DIG scheme init value.
2025 *
2026 * Input:		NONE
2027 *
2028 * Output:		NONE
2029 *
2030 * Return:		NONE
2031 *
2032 * Revised History:
2033 *	When		Who		Remark
2034 *	05/15/2008	amy		Create Version 0 porting from windows code.
2035 *
2036 *---------------------------------------------------------------------------*/
2037static void dm_dig_init(struct net_device *dev)
2038{
2039	struct r8192_priv *priv = ieee80211_priv(dev);
2040	/* 2007/10/05 MH Disable DIG scheme now. Not tested. */
2041	dm_digtable.dig_enable_flag	= true;
2042	dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI;
2043	dm_digtable.dbg_mode = DM_DBG_OFF;	//off=by real rssi value, on=by DM_DigTable.Rssi_val for new dig
2044	dm_digtable.dig_algorithm_switch = 0;
2045
2046	/* 2007/10/04 MH Define init gain threshold. */
2047	dm_digtable.dig_state		= DM_STA_DIG_MAX;
2048	dm_digtable.dig_highpwr_state	= DM_STA_DIG_MAX;
2049	dm_digtable.initialgain_lowerbound_state = false;
2050
2051	dm_digtable.rssi_low_thresh 	= DM_DIG_THRESH_LOW;
2052	dm_digtable.rssi_high_thresh 	= DM_DIG_THRESH_HIGH;
2053
2054	dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
2055	dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
2056
2057	dm_digtable.rssi_val = 50;	//for new dig debug rssi value
2058	dm_digtable.backoff_val = DM_DIG_BACKOFF;
2059	dm_digtable.rx_gain_range_max = DM_DIG_MAX;
2060	if(priv->CustomerID == RT_CID_819x_Netcore)
2061		dm_digtable.rx_gain_range_min = DM_DIG_MIN_Netcore;
2062	else
2063		dm_digtable.rx_gain_range_min = DM_DIG_MIN;
2064
2065}	/* dm_dig_init */
2066
2067
2068/*-----------------------------------------------------------------------------
2069 * Function:	dm_ctrl_initgain_byrssi()
2070 *
2071 * Overview:	Driver must monitor RSSI and notify firmware to change initial
2072 *				gain according to different threshold. BB team provide the
2073 *				suggested solution.
2074 *
2075 * Input:			struct net_device *dev
2076 *
2077 * Output:		NONE
2078 *
2079 * Return:		NONE
2080 *
2081 * Revised History:
2082 *	When		Who		Remark
2083 *	05/27/2008	amy		Create Version 0 porting from windows code.
2084 *---------------------------------------------------------------------------*/
2085static void dm_ctrl_initgain_byrssi(struct net_device *dev)
2086{
2087
2088	if (dm_digtable.dig_enable_flag == false)
2089		return;
2090
2091	if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
2092		dm_ctrl_initgain_byrssi_by_fwfalse_alarm(dev);
2093	else if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
2094		dm_ctrl_initgain_byrssi_by_driverrssi(dev);
2095}
2096
2097
2098static void dm_ctrl_initgain_byrssi_by_driverrssi(
2099	struct net_device *dev)
2100{
2101	struct r8192_priv *priv = ieee80211_priv(dev);
2102	u8 i;
2103	static u8 	fw_dig=0;
2104
2105	if (dm_digtable.dig_enable_flag == false)
2106		return;
2107
2108	//DbgPrint("Dig by Sw Rssi \n");
2109	if(dm_digtable.dig_algorithm_switch)	// if swithed algorithm, we have to disable FW Dig.
2110		fw_dig = 0;
2111	if(fw_dig <= 3)	// execute several times to make sure the FW Dig is disabled
2112	{// FW DIG Off
2113		for(i=0; i<3; i++)
2114			rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	// Only clear byte 1 and rewrite.
2115		fw_dig++;
2116		dm_digtable.dig_state = DM_STA_DIG_OFF;	//fw dig off.
2117	}
2118
2119	if(priv->ieee80211->state == IEEE80211_LINKED)
2120		dm_digtable.cur_connect_state = DIG_CONNECT;
2121	else
2122		dm_digtable.cur_connect_state = DIG_DISCONNECT;
2123
2124	//DbgPrint("DM_DigTable.PreConnectState = %d, DM_DigTable.CurConnectState = %d \n",
2125		//DM_DigTable.PreConnectState, DM_DigTable.CurConnectState);
2126
2127	if(dm_digtable.dbg_mode == DM_DBG_OFF)
2128		dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb;
2129	//DbgPrint("DM_DigTable.Rssi_val = %d \n", DM_DigTable.Rssi_val);
2130	dm_initial_gain(dev);
2131	dm_pd_th(dev);
2132	dm_cs_ratio(dev);
2133	if(dm_digtable.dig_algorithm_switch)
2134		dm_digtable.dig_algorithm_switch = 0;
2135	dm_digtable.pre_connect_state = dm_digtable.cur_connect_state;
2136
2137}	/* dm_CtrlInitGainByRssi */
2138
2139static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(
2140	struct net_device *dev)
2141{
2142	struct r8192_priv *priv = ieee80211_priv(dev);
2143	static u32 reset_cnt = 0;
2144	u8 i;
2145
2146	if (dm_digtable.dig_enable_flag == false)
2147		return;
2148
2149	if(dm_digtable.dig_algorithm_switch)
2150	{
2151		dm_digtable.dig_state = DM_STA_DIG_MAX;
2152		// Fw DIG On.
2153		for(i=0; i<3; i++)
2154			rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);	// Only clear byte 1 and rewrite.
2155		dm_digtable.dig_algorithm_switch = 0;
2156	}
2157
2158	if (priv->ieee80211->state != IEEE80211_LINKED)
2159		return;
2160
2161	// For smooth, we can not change DIG state.
2162	if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) &&
2163		(priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh))
2164	{
2165		return;
2166	}
2167	//DbgPrint("Dig by Fw False Alarm\n");
2168	//if (DM_DigTable.Dig_State == DM_STA_DIG_OFF)
2169	/*DbgPrint("DIG Check\n\r RSSI=%d LOW=%d HIGH=%d STATE=%d",
2170	pHalData->UndecoratedSmoothedPWDB, DM_DigTable.RssiLowThresh,
2171	DM_DigTable.RssiHighThresh, DM_DigTable.Dig_State);*/
2172	/* 1. When RSSI decrease, We have to judge if it is smaller than a threshold
2173		  and then execute below step. */
2174	if ((priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh))
2175	{
2176		/* 2008/02/05 MH When we execute silent reset, the DIG PHY parameters
2177		   will be reset to init value. We must prevent the condition. */
2178		if (dm_digtable.dig_state == DM_STA_DIG_OFF &&
2179			(priv->reset_count == reset_cnt))
2180		{
2181			return;
2182		}
2183		else
2184		{
2185			reset_cnt = priv->reset_count;
2186		}
2187
2188		// If DIG is off, DIG high power state must reset.
2189		dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
2190		dm_digtable.dig_state = DM_STA_DIG_OFF;
2191
2192		// 1.1 DIG Off.
2193		rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	// Only clear byte 1 and rewrite.
2194
2195		// 1.2 Set initial gain.
2196		write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x17);
2197		write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x17);
2198		write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x17);
2199		write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x17);
2200
2201		// 1.3 Lower PD_TH for OFDM.
2202		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2203		{
2204			/* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
2205			// 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
2206			#ifdef RTL8190P
2207			write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
2208			#else
2209				write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
2210				#endif
2211			/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2212				write_nic_byte(pAdapter, rOFDM0_RxDetector1, 0x40);
2213			*/
2214			//else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E)
2215
2216
2217			//else
2218				//PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x40);
2219		}
2220		else
2221			write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2222
2223		// 1.4 Lower CS ratio for CCK.
2224		write_nic_byte(dev, 0xa0a, 0x08);
2225
2226		// 1.5 Higher EDCCA.
2227		//PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x325);
2228		return;
2229
2230	}
2231
2232	/* 2. When RSSI increase, We have to judge if it is larger than a threshold
2233		  and then execute below step.  */
2234	if ((priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) )
2235	{
2236		u8 reset_flag = 0;
2237
2238		if (dm_digtable.dig_state == DM_STA_DIG_ON &&
2239			(priv->reset_count == reset_cnt))
2240		{
2241			dm_ctrl_initgain_byrssi_highpwr(dev);
2242			return;
2243		}
2244		else
2245		{
2246			if (priv->reset_count != reset_cnt)
2247				reset_flag = 1;
2248
2249			reset_cnt = priv->reset_count;
2250		}
2251
2252		dm_digtable.dig_state = DM_STA_DIG_ON;
2253		//DbgPrint("DIG ON\n\r");
2254
2255		// 2.1 Set initial gain.
2256		// 2008/02/26 MH SD3-Jerry suggest to prevent dirty environment.
2257		if (reset_flag == 1)
2258		{
2259			write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x2c);
2260			write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x2c);
2261			write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x2c);
2262			write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x2c);
2263		}
2264		else
2265		{
2266		write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x20);
2267		write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x20);
2268		write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x20);
2269		write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x20);
2270		}
2271
2272		// 2.2 Higher PD_TH for OFDM.
2273		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2274		{
2275			/* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
2276			// 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
2277			#ifdef RTL8190P
2278			write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2279			#else
2280				write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
2281				#endif
2282			/*
2283			else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2284				write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2285			*/
2286			//else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E)
2287
2288			//else
2289				//PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x42);
2290		}
2291		else
2292			write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
2293
2294		// 2.3 Higher CS ratio for CCK.
2295		write_nic_byte(dev, 0xa0a, 0xcd);
2296
2297		// 2.4 Lower EDCCA.
2298		/* 2008/01/11 MH 90/92 series are the same. */
2299		//PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x346);
2300
2301		// 2.5 DIG On.
2302		rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);	// Only clear byte 1 and rewrite.
2303
2304	}
2305
2306	dm_ctrl_initgain_byrssi_highpwr(dev);
2307
2308}	/* dm_CtrlInitGainByRssi */
2309
2310
2311/*-----------------------------------------------------------------------------
2312 * Function:	dm_ctrl_initgain_byrssi_highpwr()
2313 *
2314 * Overview:
2315 *
2316 * Input:		NONE
2317 *
2318 * Output:		NONE
2319 *
2320 * Return:		NONE
2321 *
2322 * Revised History:
2323 *	When		Who		Remark
2324 *	05/28/2008	amy		Create Version 0 porting from windows code.
2325 *
2326 *---------------------------------------------------------------------------*/
2327static void dm_ctrl_initgain_byrssi_highpwr(
2328	struct net_device * dev)
2329{
2330	struct r8192_priv *priv = ieee80211_priv(dev);
2331	static u32 reset_cnt_highpwr = 0;
2332
2333	// For smooth, we can not change high power DIG state in the range.
2334	if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_high_power_lowthresh) &&
2335		(priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_highthresh))
2336	{
2337		return;
2338	}
2339
2340	/* 3. When RSSI >75% or <70%, it is a high power issue. We have to judge if
2341		  it is larger than a threshold and then execute below step.  */
2342	// 2008/02/05 MH SD3-Jerry Modify PD_TH for high power issue.
2343	if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh)
2344	{
2345		if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON &&
2346			(priv->reset_count == reset_cnt_highpwr))
2347			return;
2348		else
2349			dm_digtable.dig_highpwr_state = DM_STA_DIG_ON;
2350
2351		// 3.1 Higher PD_TH for OFDM for high power state.
2352		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2353		{
2354			#ifdef RTL8190P
2355			write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
2356			#else
2357				write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
2358				#endif
2359
2360			/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2361				write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
2362			*/
2363
2364		}
2365		else
2366			write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
2367	}
2368	else
2369	{
2370		if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF&&
2371			(priv->reset_count == reset_cnt_highpwr))
2372			return;
2373		else
2374			dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF;
2375
2376		if (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_lowthresh &&
2377			 priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh)
2378		{
2379			// 3.2 Recover PD_TH for OFDM for normal power region.
2380			if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2381			{
2382				#ifdef RTL8190P
2383				write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2384				#else
2385					write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
2386					#endif
2387				/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2388					write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2389				*/
2390
2391			}
2392			else
2393				write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
2394		}
2395	}
2396
2397	reset_cnt_highpwr = priv->reset_count;
2398
2399}	/* dm_CtrlInitGainByRssiHighPwr */
2400
2401
2402static void dm_initial_gain(
2403	struct net_device * dev)
2404{
2405	struct r8192_priv *priv = ieee80211_priv(dev);
2406	u8					initial_gain=0;
2407	static u8				initialized=0, force_write=0;
2408	static u32			reset_cnt=0;
2409
2410	if(dm_digtable.dig_algorithm_switch)
2411	{
2412		initialized = 0;
2413		reset_cnt = 0;
2414	}
2415
2416	if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
2417	{
2418		if(dm_digtable.cur_connect_state == DIG_CONNECT)
2419		{
2420			if((dm_digtable.rssi_val+10-dm_digtable.backoff_val) > dm_digtable.rx_gain_range_max)
2421				dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_max;
2422			else if((dm_digtable.rssi_val+10-dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min)
2423				dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_min;
2424			else
2425				dm_digtable.cur_ig_value = dm_digtable.rssi_val+10-dm_digtable.backoff_val;
2426		}
2427		else		//current state is disconnected
2428		{
2429			if(dm_digtable.cur_ig_value == 0)
2430				dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
2431			else
2432				dm_digtable.cur_ig_value = dm_digtable.pre_ig_value;
2433		}
2434	}
2435	else	// disconnected -> connected or connected -> disconnected
2436	{
2437		dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
2438		dm_digtable.pre_ig_value = 0;
2439	}
2440	//DbgPrint("DM_DigTable.CurIGValue = 0x%x, DM_DigTable.PreIGValue = 0x%x\n", DM_DigTable.CurIGValue, DM_DigTable.PreIGValue);
2441
2442	// if silent reset happened, we should rewrite the values back
2443	if(priv->reset_count != reset_cnt)
2444	{
2445		force_write = 1;
2446		reset_cnt = priv->reset_count;
2447	}
2448
2449	if(dm_digtable.pre_ig_value != read_nic_byte(dev, rOFDM0_XAAGCCore1))
2450		force_write = 1;
2451
2452	{
2453		if((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value)
2454			|| !initialized || force_write)
2455		{
2456			initial_gain = (u8)dm_digtable.cur_ig_value;
2457			//DbgPrint("Write initial gain = 0x%x\n", initial_gain);
2458			// Set initial gain.
2459			write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain);
2460			write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain);
2461			write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain);
2462			write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain);
2463			dm_digtable.pre_ig_value = dm_digtable.cur_ig_value;
2464			initialized = 1;
2465			force_write = 0;
2466		}
2467	}
2468}
2469
2470static void dm_pd_th(
2471	struct net_device * dev)
2472{
2473	struct r8192_priv *priv = ieee80211_priv(dev);
2474	static u8				initialized=0, force_write=0;
2475	static u32			reset_cnt = 0;
2476
2477	if(dm_digtable.dig_algorithm_switch)
2478	{
2479		initialized = 0;
2480		reset_cnt = 0;
2481	}
2482
2483	if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
2484	{
2485		if(dm_digtable.cur_connect_state == DIG_CONNECT)
2486		{
2487			if (dm_digtable.rssi_val >= dm_digtable.rssi_high_power_highthresh)
2488				dm_digtable.curpd_thstate = DIG_PD_AT_HIGH_POWER;
2489			else if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh))
2490				dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
2491			else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) &&
2492					(dm_digtable.rssi_val < dm_digtable.rssi_high_power_lowthresh))
2493				dm_digtable.curpd_thstate = DIG_PD_AT_NORMAL_POWER;
2494			else
2495				dm_digtable.curpd_thstate = dm_digtable.prepd_thstate;
2496		}
2497		else
2498		{
2499			dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
2500		}
2501	}
2502	else	// disconnected -> connected or connected -> disconnected
2503	{
2504		dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
2505	}
2506
2507	// if silent reset happened, we should rewrite the values back
2508	if(priv->reset_count != reset_cnt)
2509	{
2510		force_write = 1;
2511		reset_cnt = priv->reset_count;
2512	}
2513
2514	{
2515		if((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) ||
2516			(initialized<=3) || force_write)
2517		{
2518			//DbgPrint("Write PD_TH state = %d\n", DM_DigTable.CurPD_THState);
2519			if(dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER)
2520			{
2521				// Lower PD_TH for OFDM.
2522				if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2523				{
2524					/* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
2525					// 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
2526					#ifdef RTL8190P
2527					write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
2528					#else
2529						write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
2530						#endif
2531					/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2532						write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
2533					*/
2534				}
2535				else
2536					write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2537			}
2538			else if(dm_digtable.curpd_thstate == DIG_PD_AT_NORMAL_POWER)
2539			{
2540				// Higher PD_TH for OFDM.
2541				if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2542				{
2543					/* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
2544					// 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
2545					#ifdef RTL8190P
2546					write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2547					#else
2548						write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
2549						#endif
2550					/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2551						write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2552					*/
2553				}
2554				else
2555					write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
2556			}
2557			else if(dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER)
2558			{
2559				// Higher PD_TH for OFDM for high power state.
2560				if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2561				{
2562					#ifdef RTL8190P
2563					write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
2564					#else
2565						write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
2566						#endif
2567					/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2568						write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
2569					*/
2570				}
2571				else
2572					write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
2573			}
2574			dm_digtable.prepd_thstate = dm_digtable.curpd_thstate;
2575			if(initialized <= 3)
2576				initialized++;
2577			force_write = 0;
2578		}
2579	}
2580}
2581
2582static	void dm_cs_ratio(
2583	struct net_device * dev)
2584{
2585	struct r8192_priv *priv = ieee80211_priv(dev);
2586	static u8				initialized=0,force_write=0;
2587	static u32			reset_cnt = 0;
2588
2589	if(dm_digtable.dig_algorithm_switch)
2590	{
2591		initialized = 0;
2592		reset_cnt = 0;
2593	}
2594
2595	if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
2596	{
2597		if(dm_digtable.cur_connect_state == DIG_CONNECT)
2598		{
2599			if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh))
2600				dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
2601			else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) )
2602				dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER;
2603			else
2604				dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state;
2605		}
2606		else
2607		{
2608			dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
2609		}
2610	}
2611	else	// disconnected -> connected or connected -> disconnected
2612	{
2613		dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
2614	}
2615
2616	// if silent reset happened, we should rewrite the values back
2617	if(priv->reset_count != reset_cnt)
2618	{
2619		force_write = 1;
2620		reset_cnt = priv->reset_count;
2621	}
2622
2623
2624	{
2625		if((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
2626			!initialized || force_write)
2627		{
2628			//DbgPrint("Write CS_ratio state = %d\n", DM_DigTable.CurCS_ratioState);
2629			if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER)
2630			{
2631				// Lower CS ratio for CCK.
2632				write_nic_byte(dev, 0xa0a, 0x08);
2633			}
2634			else if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER)
2635			{
2636				// Higher CS ratio for CCK.
2637				write_nic_byte(dev, 0xa0a, 0xcd);
2638			}
2639			dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state;
2640			initialized = 1;
2641			force_write = 0;
2642		}
2643	}
2644}
2645
2646void dm_init_edca_turbo(struct net_device *dev)
2647{
2648	struct r8192_priv *priv = ieee80211_priv(dev);
2649
2650	priv->bcurrent_turbo_EDCA = false;
2651	priv->ieee80211->bis_any_nonbepkts = false;
2652	priv->bis_cur_rdlstate = false;
2653}	// dm_init_edca_turbo
2654
2655static void dm_check_edca_turbo(
2656	struct net_device * dev)
2657{
2658	struct r8192_priv *priv = ieee80211_priv(dev);
2659	PRT_HIGH_THROUGHPUT	pHTInfo = priv->ieee80211->pHTInfo;
2660	//PSTA_QOS			pStaQos = pMgntInfo->pStaQos;
2661
2662	// Keep past Tx/Rx packet count for RT-to-RT EDCA turbo.
2663	static unsigned long			lastTxOkCnt = 0;
2664	static unsigned long			lastRxOkCnt = 0;
2665	unsigned long				curTxOkCnt = 0;
2666	unsigned long				curRxOkCnt = 0;
2667
2668	//
2669	// Do not be Turbo if it's under WiFi config and Qos Enabled, because the EDCA parameters
2670	// should follow the settings from QAP. By Bruce, 2007-12-07.
2671	//
2672	if(priv->ieee80211->state != IEEE80211_LINKED)
2673		goto dm_CheckEdcaTurbo_EXIT;
2674	// We do not turn on EDCA turbo mode for some AP that has IOT issue
2675	if(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO)
2676		goto dm_CheckEdcaTurbo_EXIT;
2677
2678//	printk("========>%s():bis_any_nonbepkts is %d\n",__FUNCTION__,priv->bis_any_nonbepkts);
2679	// Check the status for current condition.
2680	if(!priv->ieee80211->bis_any_nonbepkts)
2681	{
2682		curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
2683		curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
2684		// For RT-AP, we needs to turn it on when Rx>Tx
2685		if(curRxOkCnt > 4*curTxOkCnt)
2686		{
2687			//printk("%s():curRxOkCnt > 4*curTxOkCnt\n");
2688			if(!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
2689			{
2690				write_nic_dword(dev, EDCAPARA_BE, edca_setting_DL[pHTInfo->IOTPeer]);
2691				priv->bis_cur_rdlstate = true;
2692			}
2693		}
2694		else
2695		{
2696
2697			//printk("%s():curRxOkCnt < 4*curTxOkCnt\n");
2698			if(priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
2699			{
2700				write_nic_dword(dev, EDCAPARA_BE, edca_setting_UL[pHTInfo->IOTPeer]);
2701				priv->bis_cur_rdlstate = false;
2702			}
2703
2704		}
2705
2706		priv->bcurrent_turbo_EDCA = true;
2707	}
2708	else
2709	{
2710		//
2711		// Turn Off EDCA turbo here.
2712		// Restore original EDCA according to the declaration of AP.
2713		//
2714		 if(priv->bcurrent_turbo_EDCA)
2715		{
2716
2717			{
2718				u8		u1bAIFS;
2719				u32		u4bAcParam;
2720				struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
2721				u8 mode = priv->ieee80211->mode;
2722
2723			// For Each time updating EDCA parameter, reset EDCA turbo mode status.
2724				dm_init_edca_turbo(dev);
2725				u1bAIFS = qos_parameters->aifs[0] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
2726				u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[0]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
2727					(((u32)(qos_parameters->cw_max[0]))<< AC_PARAM_ECW_MAX_OFFSET)|
2728					(((u32)(qos_parameters->cw_min[0]))<< AC_PARAM_ECW_MIN_OFFSET)|
2729					((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
2730				printk("===>u4bAcParam:%x, ", u4bAcParam);
2731			//write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
2732				write_nic_dword(dev, EDCAPARA_BE,  u4bAcParam);
2733
2734			// Check ACM bit.
2735			// If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13.
2736				{
2737			// TODO:  Modified this part and try to set acm control in only 1 IO processing!!
2738
2739					PACI_AIFSN	pAciAifsn = (PACI_AIFSN)&(qos_parameters->aifs[0]);
2740					u8		AcmCtrl = read_nic_byte( dev, AcmHwCtrl );
2741					if( pAciAifsn->f.ACM )
2742					{ // ACM bit is 1.
2743						AcmCtrl |= AcmHw_BeqEn;
2744					}
2745					else
2746					{ // ACM bit is 0.
2747						AcmCtrl &= (~AcmHw_BeqEn);
2748					}
2749
2750					RT_TRACE( COMP_QOS,"SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl ) ;
2751					write_nic_byte(dev, AcmHwCtrl, AcmCtrl );
2752				}
2753			}
2754			priv->bcurrent_turbo_EDCA = false;
2755		}
2756	}
2757
2758
2759dm_CheckEdcaTurbo_EXIT:
2760	// Set variables for next time.
2761	priv->ieee80211->bis_any_nonbepkts = false;
2762	lastTxOkCnt = priv->stats.txbytesunicast;
2763	lastRxOkCnt = priv->stats.rxbytesunicast;
2764}	// dm_CheckEdcaTurbo
2765
2766static void dm_init_ctstoself(struct net_device * dev)
2767{
2768	struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
2769
2770	priv->ieee80211->bCTSToSelfEnable = TRUE;
2771	priv->ieee80211->CTSToSelfTH = CTSToSelfTHVal;
2772}
2773
2774static void dm_ctstoself(struct net_device *dev)
2775{
2776	struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
2777	PRT_HIGH_THROUGHPUT	pHTInfo = priv->ieee80211->pHTInfo;
2778	static unsigned long				lastTxOkCnt = 0;
2779	static unsigned long				lastRxOkCnt = 0;
2780	unsigned long						curTxOkCnt = 0;
2781	unsigned long						curRxOkCnt = 0;
2782
2783	if(priv->ieee80211->bCTSToSelfEnable != TRUE)
2784	{
2785		pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
2786		return;
2787	}
2788	/*
2789	1. Uplink
2790	2. Linksys350/Linksys300N
2791	3. <50 disable, >55 enable
2792	*/
2793
2794	if(pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM)
2795	{
2796		curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
2797		curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
2798		if(curRxOkCnt > 4*curTxOkCnt)	//downlink, disable CTS to self
2799		{
2800			pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
2801			//DbgPrint("dm_CTSToSelf() ==> CTS to self disabled -- downlink\n");
2802		}
2803		else	//uplink
2804		{
2805			pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
2806		}
2807
2808		lastTxOkCnt = priv->stats.txbytesunicast;
2809		lastRxOkCnt = priv->stats.rxbytesunicast;
2810	}
2811}
2812
2813
2814
2815/*-----------------------------------------------------------------------------
2816 * Function:	dm_check_rfctrl_gpio()
2817 *
2818 * Overview:	Copy 8187B template for 9xseries.
2819 *
2820 * Input:		NONE
2821 *
2822 * Output:		NONE
2823 *
2824 * Return:		NONE
2825 *
2826 * Revised History:
2827 *	When		Who		Remark
2828 *	05/28/2008	amy		Create Version 0 porting from windows code.
2829 *
2830 *---------------------------------------------------------------------------*/
2831static void dm_check_rfctrl_gpio(struct net_device * dev)
2832{
2833#ifdef RTL8192E
2834	struct r8192_priv *priv = ieee80211_priv(dev);
2835#endif
2836
2837	// Walk around for DTM test, we will not enable HW - radio on/off because r/w
2838	// page 1 register before Lextra bus is enabled cause system fails when resuming
2839	// from S4. 20080218, Emily
2840
2841	// Stop to execute workitem to prevent S3/S4 bug.
2842#ifdef RTL8190P
2843	return;
2844#endif
2845#ifdef RTL8192U
2846	return;
2847#endif
2848#ifdef RTL8192E
2849		queue_delayed_work(priv->priv_wq,&priv->gpio_change_rf_wq,0);
2850#endif
2851
2852}	/* dm_CheckRfCtrlGPIO */
2853/*-----------------------------------------------------------------------------
2854 * Function:	dm_check_pbc_gpio()
2855 *
2856 * Overview:	Check if PBC button is pressed.
2857 *
2858 * Input:		NONE
2859 *
2860 * Output:		NONE
2861 *
2862 * Return:		NONE
2863 *
2864 * Revised History:
2865 *	When		Who		Remark
2866 *	05/28/2008	amy 	Create Version 0 porting from windows code.
2867 *
2868 *---------------------------------------------------------------------------*/
2869static	void	dm_check_pbc_gpio(struct net_device *dev)
2870{
2871#ifdef RTL8192U
2872	struct r8192_priv *priv = ieee80211_priv(dev);
2873	u8 tmp1byte;
2874
2875
2876	tmp1byte = read_nic_byte(dev,GPI);
2877	if(tmp1byte == 0xff)
2878	return;
2879
2880	if (tmp1byte&BIT6 || tmp1byte&BIT0)
2881	{
2882		// Here we only set bPbcPressed to TRUE
2883		// After trigger PBC, the variable will be set to FALSE
2884		RT_TRACE(COMP_IO, "CheckPbcGPIO - PBC is pressed\n");
2885		priv->bpbc_pressed = true;
2886	}
2887#endif
2888
2889}
2890
2891#ifdef RTL8192E
2892
2893/*-----------------------------------------------------------------------------
2894 * Function:	dm_GPIOChangeRF
2895 * Overview:	PCI will not support workitem call back HW radio on-off control.
2896 *
2897 * Input:		NONE
2898 *
2899 * Output:		NONE
2900 *
2901 * Return:		NONE
2902 *
2903 * Revised History:
2904 *	When		Who		Remark
2905 *	02/21/2008	MHC		Create Version 0.
2906 *
2907 *---------------------------------------------------------------------------*/
2908void dm_gpio_change_rf_callback(struct work_struct *work)
2909{
2910	struct delayed_work *dwork = container_of(work,struct delayed_work,work);
2911       struct r8192_priv *priv = container_of(dwork,struct r8192_priv,gpio_change_rf_wq);
2912       struct net_device *dev = priv->ieee80211->dev;
2913	u8 tmp1byte;
2914	RT_RF_POWER_STATE	eRfPowerStateToSet;
2915	bool bActuallySet = false;
2916
2917		if(!priv->up)
2918		{
2919		RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF),"dm_gpio_change_rf_callback(): Callback function breaks out!!\n");
2920		}
2921		else
2922		{
2923			// 0x108 GPIO input register is read only
2924			//set 0x108 B1= 1: RF-ON; 0: RF-OFF.
2925			tmp1byte = read_nic_byte(dev,GPI);
2926
2927			eRfPowerStateToSet = (tmp1byte&BIT1) ?  eRfOn : eRfOff;
2928
2929			if( (priv->bHwRadioOff == true) && (eRfPowerStateToSet == eRfOn))
2930			{
2931			RT_TRACE(COMP_RF, "gpiochangeRF  - HW Radio ON\n");
2932
2933				priv->bHwRadioOff = false;
2934				bActuallySet = true;
2935			}
2936			else if ( (priv->bHwRadioOff == false) && (eRfPowerStateToSet == eRfOff))
2937			{
2938			RT_TRACE(COMP_RF, "gpiochangeRF  - HW Radio OFF\n");
2939				priv->bHwRadioOff = true;
2940				bActuallySet = true;
2941			}
2942
2943			if(bActuallySet)
2944			{
2945			priv->bHwRfOffAction = 1;
2946				MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
2947				//DrvIFIndicateCurrentPhyStatus(pAdapter);
2948
2949		}
2950		else
2951		{
2952			msleep(2000);
2953			}
2954
2955		}
2956
2957}	/* dm_GPIOChangeRF */
2958
2959#endif
2960/*-----------------------------------------------------------------------------
2961 * Function:	DM_RFPathCheckWorkItemCallBack()
2962 *
2963 * Overview:	Check if Current RF RX path is enabled
2964 *
2965 * Input:		NONE
2966 *
2967 * Output:		NONE
2968 *
2969 * Return:		NONE
2970 *
2971 * Revised History:
2972 *	When		Who		Remark
2973 *	01/30/2008	MHC		Create Version 0.
2974 *
2975 *---------------------------------------------------------------------------*/
2976void dm_rf_pathcheck_workitemcallback(struct work_struct *work)
2977{
2978	struct delayed_work *dwork = container_of(work,struct delayed_work,work);
2979       struct r8192_priv *priv = container_of(dwork,struct r8192_priv,rfpath_check_wq);
2980       struct net_device *dev =priv->ieee80211->dev;
2981	//bool bactually_set = false;
2982	u8 rfpath = 0, i;
2983
2984
2985	/* 2008/01/30 MH After discussing with SD3 Jerry, 0xc04/0xd04 register will
2986	   always be the same. We only read 0xc04 now. */
2987	rfpath = read_nic_byte(dev, 0xc04);
2988
2989	// Check Bit 0-3, it means if RF A-D is enabled.
2990	for (i = 0; i < RF90_PATH_MAX; i++)
2991	{
2992		if (rfpath & (0x01<<i))
2993			priv->brfpath_rxenable[i] = 1;
2994		else
2995			priv->brfpath_rxenable[i] = 0;
2996	}
2997	if(!DM_RxPathSelTable.Enable)
2998		return;
2999
3000	dm_rxpath_sel_byrssi(dev);
3001}	/* DM_RFPathCheckWorkItemCallBack */
3002
3003static void dm_init_rxpath_selection(struct net_device * dev)
3004{
3005	u8 i;
3006	struct r8192_priv *priv = ieee80211_priv(dev);
3007	DM_RxPathSelTable.Enable = 1;	//default enabled
3008	DM_RxPathSelTable.SS_TH_low = RxPathSelection_SS_TH_low;
3009	DM_RxPathSelTable.diff_TH = RxPathSelection_diff_TH;
3010	if(priv->CustomerID == RT_CID_819x_Netcore)
3011		DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;
3012	else
3013		DM_RxPathSelTable.cck_method = CCK_Rx_Version_1;
3014	DM_RxPathSelTable.DbgMode = DM_DBG_OFF;
3015	DM_RxPathSelTable.disabledRF = 0;
3016	for(i=0; i<4; i++)
3017	{
3018		DM_RxPathSelTable.rf_rssi[i] = 50;
3019		DM_RxPathSelTable.cck_pwdb_sta[i] = -64;
3020		DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
3021	}
3022}
3023
3024static void dm_rxpath_sel_byrssi(struct net_device * dev)
3025{
3026	struct r8192_priv *priv = ieee80211_priv(dev);
3027	u8				i, max_rssi_index=0, min_rssi_index=0, sec_rssi_index=0, rf_num=0;
3028	u8				tmp_max_rssi=0, tmp_min_rssi=0, tmp_sec_rssi=0;
3029	u8				cck_default_Rx=0x2;	//RF-C
3030	u8				cck_optional_Rx=0x3;//RF-D
3031	long				tmp_cck_max_pwdb=0, tmp_cck_min_pwdb=0, tmp_cck_sec_pwdb=0;
3032	u8				cck_rx_ver2_max_index=0, cck_rx_ver2_min_index=0, cck_rx_ver2_sec_index=0;
3033	u8				cur_rf_rssi;
3034	long				cur_cck_pwdb;
3035	static u8			disabled_rf_cnt=0, cck_Rx_Path_initialized=0;
3036	u8				update_cck_rx_path;
3037
3038	if(priv->rf_type != RF_2T4R)
3039		return;
3040
3041	if(!cck_Rx_Path_initialized)
3042	{
3043		DM_RxPathSelTable.cck_Rx_path = (read_nic_byte(dev, 0xa07)&0xf);
3044		cck_Rx_Path_initialized = 1;
3045	}
3046
3047	DM_RxPathSelTable.disabledRF = 0xf;
3048	DM_RxPathSelTable.disabledRF &=~ (read_nic_byte(dev, 0xc04));
3049
3050	if(priv->ieee80211->mode == WIRELESS_MODE_B)
3051	{
3052		DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;	//pure B mode, fixed cck version2
3053		//DbgPrint("Pure B mode, use cck rx version2 \n");
3054	}
3055
3056	//decide max/sec/min rssi index
3057	for (i=0; i<RF90_PATH_MAX; i++)
3058	{
3059		if(!DM_RxPathSelTable.DbgMode)
3060			DM_RxPathSelTable.rf_rssi[i] = priv->stats.rx_rssi_percentage[i];
3061
3062		if(priv->brfpath_rxenable[i])
3063		{
3064			rf_num++;
3065			cur_rf_rssi = DM_RxPathSelTable.rf_rssi[i];
3066
3067			if(rf_num == 1)	// find first enabled rf path and the rssi values
3068			{	//initialize, set all rssi index to the same one
3069				max_rssi_index = min_rssi_index = sec_rssi_index = i;
3070				tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi;
3071			}
3072			else if(rf_num == 2)
3073			{	// we pick up the max index first, and let sec and min to be the same one
3074				if(cur_rf_rssi >= tmp_max_rssi)
3075				{
3076					tmp_max_rssi = cur_rf_rssi;
3077					max_rssi_index = i;
3078				}
3079				else
3080				{
3081					tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi;
3082					sec_rssi_index = min_rssi_index = i;
3083				}
3084			}
3085			else
3086			{
3087				if(cur_rf_rssi > tmp_max_rssi)
3088				{
3089					tmp_sec_rssi = tmp_max_rssi;
3090					sec_rssi_index = max_rssi_index;
3091					tmp_max_rssi = cur_rf_rssi;
3092					max_rssi_index = i;
3093				}
3094				else if(cur_rf_rssi == tmp_max_rssi)
3095				{	// let sec and min point to the different index
3096					tmp_sec_rssi = cur_rf_rssi;
3097					sec_rssi_index = i;
3098				}
3099				else if((cur_rf_rssi < tmp_max_rssi) &&(cur_rf_rssi > tmp_sec_rssi))
3100				{
3101					tmp_sec_rssi = cur_rf_rssi;
3102					sec_rssi_index = i;
3103				}
3104				else if(cur_rf_rssi == tmp_sec_rssi)
3105				{
3106					if(tmp_sec_rssi == tmp_min_rssi)
3107					{	// let sec and min point to the different index
3108						tmp_sec_rssi = cur_rf_rssi;
3109						sec_rssi_index = i;
3110					}
3111					else
3112					{
3113						// This case we don't need to set any index
3114					}
3115				}
3116				else if((cur_rf_rssi < tmp_sec_rssi) && (cur_rf_rssi > tmp_min_rssi))
3117				{
3118					// This case we don't need to set any index
3119				}
3120				else if(cur_rf_rssi == tmp_min_rssi)
3121				{
3122					if(tmp_sec_rssi == tmp_min_rssi)
3123					{	// let sec and min point to the different index
3124						tmp_min_rssi = cur_rf_rssi;
3125						min_rssi_index = i;
3126					}
3127					else
3128					{
3129						// This case we don't need to set any index
3130					}
3131				}
3132				else if(cur_rf_rssi < tmp_min_rssi)
3133				{
3134					tmp_min_rssi = cur_rf_rssi;
3135					min_rssi_index = i;
3136				}
3137			}
3138		}
3139	}
3140
3141	rf_num = 0;
3142	// decide max/sec/min cck pwdb index
3143	if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_2)
3144	{
3145		for (i=0; i<RF90_PATH_MAX; i++)
3146		{
3147			if(priv->brfpath_rxenable[i])
3148			{
3149				rf_num++;
3150				cur_cck_pwdb =  DM_RxPathSelTable.cck_pwdb_sta[i];
3151
3152				if(rf_num == 1)	// find first enabled rf path and the rssi values
3153				{	//initialize, set all rssi index to the same one
3154					cck_rx_ver2_max_index = cck_rx_ver2_min_index = cck_rx_ver2_sec_index = i;
3155					tmp_cck_max_pwdb = tmp_cck_min_pwdb = tmp_cck_sec_pwdb = cur_cck_pwdb;
3156				}
3157				else if(rf_num == 2)
3158				{	// we pick up the max index first, and let sec and min to be the same one
3159					if(cur_cck_pwdb >= tmp_cck_max_pwdb)
3160					{
3161						tmp_cck_max_pwdb = cur_cck_pwdb;
3162						cck_rx_ver2_max_index = i;
3163					}
3164					else
3165					{
3166						tmp_cck_sec_pwdb = tmp_cck_min_pwdb = cur_cck_pwdb;
3167						cck_rx_ver2_sec_index = cck_rx_ver2_min_index = i;
3168					}
3169				}
3170				else
3171				{
3172					if(cur_cck_pwdb > tmp_cck_max_pwdb)
3173					{
3174						tmp_cck_sec_pwdb = tmp_cck_max_pwdb;
3175						cck_rx_ver2_sec_index = cck_rx_ver2_max_index;
3176						tmp_cck_max_pwdb = cur_cck_pwdb;
3177						cck_rx_ver2_max_index = i;
3178					}
3179					else if(cur_cck_pwdb == tmp_cck_max_pwdb)
3180					{	// let sec and min point to the different index
3181						tmp_cck_sec_pwdb = cur_cck_pwdb;
3182						cck_rx_ver2_sec_index = i;
3183					}
3184					else if((cur_cck_pwdb < tmp_cck_max_pwdb) &&(cur_cck_pwdb > tmp_cck_sec_pwdb))
3185					{
3186						tmp_cck_sec_pwdb = cur_cck_pwdb;
3187						cck_rx_ver2_sec_index = i;
3188					}
3189					else if(cur_cck_pwdb == tmp_cck_sec_pwdb)
3190					{
3191						if(tmp_cck_sec_pwdb == tmp_cck_min_pwdb)
3192						{	// let sec and min point to the different index
3193							tmp_cck_sec_pwdb = cur_cck_pwdb;
3194							cck_rx_ver2_sec_index = i;
3195						}
3196						else
3197						{
3198							// This case we don't need to set any index
3199						}
3200					}
3201					else if((cur_cck_pwdb < tmp_cck_sec_pwdb) && (cur_cck_pwdb > tmp_cck_min_pwdb))
3202					{
3203						// This case we don't need to set any index
3204					}
3205					else if(cur_cck_pwdb == tmp_cck_min_pwdb)
3206					{
3207						if(tmp_cck_sec_pwdb == tmp_cck_min_pwdb)
3208						{	// let sec and min point to the different index
3209							tmp_cck_min_pwdb = cur_cck_pwdb;
3210							cck_rx_ver2_min_index = i;
3211						}
3212						else
3213						{
3214							// This case we don't need to set any index
3215						}
3216					}
3217					else if(cur_cck_pwdb < tmp_cck_min_pwdb)
3218					{
3219						tmp_cck_min_pwdb = cur_cck_pwdb;
3220						cck_rx_ver2_min_index = i;
3221					}
3222				}
3223
3224			}
3225		}
3226	}
3227
3228
3229	// Set CCK Rx path
3230	// reg0xA07[3:2]=cck default rx path, reg0xa07[1:0]=cck optional rx path.
3231	update_cck_rx_path = 0;
3232	if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_2)
3233	{
3234		cck_default_Rx = cck_rx_ver2_max_index;
3235		cck_optional_Rx = cck_rx_ver2_sec_index;
3236		if(tmp_cck_max_pwdb != -64)
3237			update_cck_rx_path = 1;
3238	}
3239
3240	if(tmp_min_rssi < DM_RxPathSelTable.SS_TH_low && disabled_rf_cnt < 2)
3241	{
3242		if((tmp_max_rssi - tmp_min_rssi) >= DM_RxPathSelTable.diff_TH)
3243		{
3244			//record the enabled rssi threshold
3245			DM_RxPathSelTable.rf_enable_rssi_th[min_rssi_index] = tmp_max_rssi+5;
3246			//disable the BB Rx path, OFDM
3247			rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<min_rssi_index, 0x0);	// 0xc04[3:0]
3248			rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<min_rssi_index, 0x0);	// 0xd04[3:0]
3249			disabled_rf_cnt++;
3250		}
3251		if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_1)
3252		{
3253			cck_default_Rx = max_rssi_index;
3254			cck_optional_Rx = sec_rssi_index;
3255			if(tmp_max_rssi)
3256				update_cck_rx_path = 1;
3257		}
3258	}
3259
3260	if(update_cck_rx_path)
3261	{
3262		DM_RxPathSelTable.cck_Rx_path = (cck_default_Rx<<2)|(cck_optional_Rx);
3263		rtl8192_setBBreg(dev, rCCK0_AFESetting, 0x0f000000, DM_RxPathSelTable.cck_Rx_path);
3264	}
3265
3266	if(DM_RxPathSelTable.disabledRF)
3267	{
3268		for(i=0; i<4; i++)
3269		{
3270			if((DM_RxPathSelTable.disabledRF>>i) & 0x1)	//disabled rf
3271			{
3272				if(tmp_max_rssi >= DM_RxPathSelTable.rf_enable_rssi_th[i])
3273				{
3274					//enable the BB Rx path
3275					//DbgPrint("RF-%d is enabled. \n", 0x1<<i);
3276					rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<i, 0x1);	// 0xc04[3:0]
3277					rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<i, 0x1);	// 0xd04[3:0]
3278					DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
3279					disabled_rf_cnt--;
3280				}
3281			}
3282		}
3283	}
3284}
3285
3286/*-----------------------------------------------------------------------------
3287 * Function:	dm_check_rx_path_selection()
3288 *
3289 * Overview:	Call a workitem to check current RXRF path and Rx Path selection by RSSI.
3290 *
3291 * Input:		NONE
3292 *
3293 * Output:		NONE
3294 *
3295 * Return:		NONE
3296 *
3297 * Revised History:
3298 *	When		Who		Remark
3299 *	05/28/2008	amy		Create Version 0 porting from windows code.
3300 *
3301 *---------------------------------------------------------------------------*/
3302static	void	dm_check_rx_path_selection(struct net_device *dev)
3303{
3304	struct r8192_priv *priv = ieee80211_priv(dev);
3305	queue_delayed_work(priv->priv_wq,&priv->rfpath_check_wq,0);
3306}	/* dm_CheckRxRFPath */
3307
3308
3309static void dm_init_fsync (struct net_device *dev)
3310{
3311	struct r8192_priv *priv = ieee80211_priv(dev);
3312
3313	priv->ieee80211->fsync_time_interval = 500;
3314	priv->ieee80211->fsync_rate_bitmap = 0x0f000800;
3315	priv->ieee80211->fsync_rssi_threshold = 30;
3316#ifdef RTL8190P
3317	priv->ieee80211->bfsync_enable = true;
3318#else
3319	priv->ieee80211->bfsync_enable = false;
3320#endif
3321	priv->ieee80211->fsync_multiple_timeinterval = 3;
3322	priv->ieee80211->fsync_firstdiff_ratethreshold= 100;
3323	priv->ieee80211->fsync_seconddiff_ratethreshold= 200;
3324	priv->ieee80211->fsync_state = Default_Fsync;
3325	priv->framesyncMonitor = 1;	// current default 0xc38 monitor on
3326
3327	init_timer(&priv->fsync_timer);
3328	priv->fsync_timer.data = (unsigned long)dev;
3329	priv->fsync_timer.function = dm_fsync_timer_callback;
3330}
3331
3332
3333static void dm_deInit_fsync(struct net_device *dev)
3334{
3335	struct r8192_priv *priv = ieee80211_priv(dev);
3336	del_timer_sync(&priv->fsync_timer);
3337}
3338
3339void dm_fsync_timer_callback(unsigned long data)
3340{
3341	struct net_device *dev = (struct net_device *)data;
3342	struct r8192_priv *priv = ieee80211_priv((struct net_device *)data);
3343	u32 rate_index, rate_count = 0, rate_count_diff=0;
3344	bool		bSwitchFromCountDiff = false;
3345	bool		bDoubleTimeInterval = false;
3346
3347	if(	priv->ieee80211->state == IEEE80211_LINKED &&
3348		priv->ieee80211->bfsync_enable &&
3349		(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC))
3350	{
3351		 // Count rate 54, MCS [7], [12, 13, 14, 15]
3352		u32 rate_bitmap;
3353		for(rate_index = 0; rate_index <= 27; rate_index++)
3354		{
3355			rate_bitmap  = 1 << rate_index;
3356			if(priv->ieee80211->fsync_rate_bitmap &  rate_bitmap)
3357		 		rate_count+= priv->stats.received_rate_histogram[1][rate_index];
3358		}
3359
3360		if(rate_count < priv->rate_record)
3361			rate_count_diff = 0xffffffff - rate_count + priv->rate_record;
3362		else
3363			rate_count_diff = rate_count - priv->rate_record;
3364		if(rate_count_diff < priv->rateCountDiffRecord)
3365		{
3366
3367			u32 DiffNum = priv->rateCountDiffRecord - rate_count_diff;
3368			// Contiune count
3369			if(DiffNum >= priv->ieee80211->fsync_seconddiff_ratethreshold)
3370				priv->ContiuneDiffCount++;
3371			else
3372				priv->ContiuneDiffCount = 0;
3373
3374			// Contiune count over
3375			if(priv->ContiuneDiffCount >=2)
3376			{
3377				bSwitchFromCountDiff = true;
3378				priv->ContiuneDiffCount = 0;
3379			}
3380		}
3381		else
3382		{
3383			// Stop contiune count
3384			priv->ContiuneDiffCount = 0;
3385		}
3386
3387		//If Count diff <= FsyncRateCountThreshold
3388		if(rate_count_diff <= priv->ieee80211->fsync_firstdiff_ratethreshold)
3389		{
3390			bSwitchFromCountDiff = true;
3391			priv->ContiuneDiffCount = 0;
3392		}
3393		priv->rate_record = rate_count;
3394		priv->rateCountDiffRecord = rate_count_diff;
3395		RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync);
3396		// if we never receive those mcs rate and rssi > 30 % then switch fsyn
3397		if(priv->undecorated_smoothed_pwdb > priv->ieee80211->fsync_rssi_threshold && bSwitchFromCountDiff)
3398		{
3399			bDoubleTimeInterval = true;
3400			priv->bswitch_fsync = !priv->bswitch_fsync;
3401			if(priv->bswitch_fsync)
3402			{
3403			#ifdef RTL8190P
3404				write_nic_byte(dev,0xC36, 0x00);
3405			#else
3406				write_nic_byte(dev,0xC36, 0x1c);
3407			#endif
3408				write_nic_byte(dev, 0xC3e, 0x90);
3409			}
3410			else
3411			{
3412			#ifdef RTL8190P
3413				write_nic_byte(dev, 0xC36, 0x40);
3414			#else
3415				write_nic_byte(dev, 0xC36, 0x5c);
3416			#endif
3417				write_nic_byte(dev, 0xC3e, 0x96);
3418			}
3419		}
3420		else if(priv->undecorated_smoothed_pwdb <= priv->ieee80211->fsync_rssi_threshold)
3421		{
3422			if(priv->bswitch_fsync)
3423			{
3424				priv->bswitch_fsync  = false;
3425			#ifdef RTL8190P
3426				write_nic_byte(dev, 0xC36, 0x40);
3427			#else
3428				write_nic_byte(dev, 0xC36, 0x5c);
3429			#endif
3430				write_nic_byte(dev, 0xC3e, 0x96);
3431			}
3432		}
3433		if(bDoubleTimeInterval){
3434			if(timer_pending(&priv->fsync_timer))
3435				del_timer_sync(&priv->fsync_timer);
3436			priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval*priv->ieee80211->fsync_multiple_timeinterval);
3437			add_timer(&priv->fsync_timer);
3438		}
3439		else{
3440			if(timer_pending(&priv->fsync_timer))
3441				del_timer_sync(&priv->fsync_timer);
3442			priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval);
3443			add_timer(&priv->fsync_timer);
3444		}
3445	}
3446	else
3447	{
3448		// Let Register return to default value;
3449		if(priv->bswitch_fsync)
3450		{
3451			priv->bswitch_fsync  = false;
3452		#ifdef RTL8190P
3453			write_nic_byte(dev, 0xC36, 0x40);
3454		#else
3455			write_nic_byte(dev, 0xC36, 0x5c);
3456		#endif
3457			write_nic_byte(dev, 0xC3e, 0x96);
3458		}
3459		priv->ContiuneDiffCount = 0;
3460	#ifdef RTL8190P
3461		write_nic_dword(dev, rOFDM0_RxDetector2, 0x164052cd);
3462	#else
3463		write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
3464	#endif
3465	}
3466	RT_TRACE(COMP_HALDM, "ContiuneDiffCount %d\n", priv->ContiuneDiffCount);
3467	RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync);
3468}
3469
3470static void dm_StartHWFsync(struct net_device *dev)
3471{
3472	RT_TRACE(COMP_HALDM, "%s\n", __FUNCTION__);
3473	write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cf);
3474	write_nic_byte(dev, 0xc3b, 0x41);
3475}
3476
3477static void dm_EndSWFsync(struct net_device *dev)
3478{
3479	struct r8192_priv *priv = ieee80211_priv(dev);
3480
3481	RT_TRACE(COMP_HALDM, "%s\n", __FUNCTION__);
3482	del_timer_sync(&(priv->fsync_timer));
3483
3484	// Let Register return to default value;
3485	if(priv->bswitch_fsync)
3486	{
3487		priv->bswitch_fsync  = false;
3488
3489		#ifdef RTL8190P
3490			write_nic_byte(dev, 0xC36, 0x40);
3491		#else
3492		write_nic_byte(dev, 0xC36, 0x5c);
3493#endif
3494
3495		write_nic_byte(dev, 0xC3e, 0x96);
3496	}
3497
3498	priv->ContiuneDiffCount = 0;
3499#ifndef RTL8190P
3500	write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
3501#endif
3502
3503}
3504
3505static void dm_StartSWFsync(struct net_device *dev)
3506{
3507	struct r8192_priv *priv = ieee80211_priv(dev);
3508	u32 			rateIndex;
3509	u32 			rateBitmap;
3510
3511	RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__);
3512	// Initial rate record to zero, start to record.
3513	priv->rate_record = 0;
3514	// Initial contiune diff count to zero, start to record.
3515	priv->ContiuneDiffCount = 0;
3516	priv->rateCountDiffRecord = 0;
3517	priv->bswitch_fsync  = false;
3518
3519	if(priv->ieee80211->mode == WIRELESS_MODE_N_24G)
3520	{
3521		priv->ieee80211->fsync_firstdiff_ratethreshold= 600;
3522		priv->ieee80211->fsync_seconddiff_ratethreshold = 0xffff;
3523	}
3524	else
3525	{
3526		priv->ieee80211->fsync_firstdiff_ratethreshold= 200;
3527		priv->ieee80211->fsync_seconddiff_ratethreshold = 200;
3528	}
3529	for(rateIndex = 0; rateIndex <= 27; rateIndex++)
3530	{
3531		rateBitmap  = 1 << rateIndex;
3532		if(priv->ieee80211->fsync_rate_bitmap &  rateBitmap)
3533			priv->rate_record += priv->stats.received_rate_histogram[1][rateIndex];
3534	}
3535	if(timer_pending(&priv->fsync_timer))
3536		del_timer_sync(&priv->fsync_timer);
3537	priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval);
3538	add_timer(&priv->fsync_timer);
3539
3540#ifndef RTL8190P
3541	write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cd);
3542#endif
3543
3544}
3545
3546static void dm_EndHWFsync(struct net_device *dev)
3547{
3548	RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__);
3549	write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
3550	write_nic_byte(dev, 0xc3b, 0x49);
3551
3552}
3553
3554void dm_check_fsync(struct net_device *dev)
3555{
3556#define	RegC38_Default				0
3557#define	RegC38_NonFsync_Other_AP	1
3558#define	RegC38_Fsync_AP_BCM		2
3559	struct r8192_priv *priv = ieee80211_priv(dev);
3560	//u32 			framesyncC34;
3561	static u8		reg_c38_State=RegC38_Default;
3562	static u32	reset_cnt=0;
3563
3564	RT_TRACE(COMP_HALDM, "RSSI %d TimeInterval %d MultipleTimeInterval %d\n", priv->ieee80211->fsync_rssi_threshold, priv->ieee80211->fsync_time_interval, priv->ieee80211->fsync_multiple_timeinterval);
3565	RT_TRACE(COMP_HALDM, "RateBitmap 0x%x FirstDiffRateThreshold %d SecondDiffRateThreshold %d\n", priv->ieee80211->fsync_rate_bitmap, priv->ieee80211->fsync_firstdiff_ratethreshold, priv->ieee80211->fsync_seconddiff_ratethreshold);
3566
3567	if(	priv->ieee80211->state == IEEE80211_LINKED &&
3568		(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC))
3569	{
3570		if(priv->ieee80211->bfsync_enable == 0)
3571		{
3572			switch(priv->ieee80211->fsync_state)
3573			{
3574				case Default_Fsync:
3575					dm_StartHWFsync(dev);
3576					priv->ieee80211->fsync_state = HW_Fsync;
3577					break;
3578				case SW_Fsync:
3579					dm_EndSWFsync(dev);
3580					dm_StartHWFsync(dev);
3581					priv->ieee80211->fsync_state = HW_Fsync;
3582					break;
3583				case HW_Fsync:
3584				default:
3585					break;
3586			}
3587		}
3588		else
3589		{
3590			switch(priv->ieee80211->fsync_state)
3591			{
3592				case Default_Fsync:
3593					dm_StartSWFsync(dev);
3594					priv->ieee80211->fsync_state = SW_Fsync;
3595					break;
3596				case HW_Fsync:
3597					dm_EndHWFsync(dev);
3598					dm_StartSWFsync(dev);
3599					priv->ieee80211->fsync_state = SW_Fsync;
3600					break;
3601				case SW_Fsync:
3602				default:
3603					break;
3604
3605			}
3606		}
3607		if(priv->framesyncMonitor)
3608		{
3609			if(reg_c38_State != RegC38_Fsync_AP_BCM)
3610			{	//For broadcom AP we write different default value
3611				#ifdef RTL8190P
3612					write_nic_byte(dev, rOFDM0_RxDetector3, 0x15);
3613				#else
3614					write_nic_byte(dev, rOFDM0_RxDetector3, 0x95);
3615				#endif
3616
3617				reg_c38_State = RegC38_Fsync_AP_BCM;
3618			}
3619		}
3620	}
3621	else
3622	{
3623		switch(priv->ieee80211->fsync_state)
3624		{
3625			case HW_Fsync:
3626				dm_EndHWFsync(dev);
3627				priv->ieee80211->fsync_state = Default_Fsync;
3628				break;
3629			case SW_Fsync:
3630				dm_EndSWFsync(dev);
3631				priv->ieee80211->fsync_state = Default_Fsync;
3632				break;
3633			case Default_Fsync:
3634			default:
3635				break;
3636		}
3637
3638		if(priv->framesyncMonitor)
3639		{
3640			if(priv->ieee80211->state == IEEE80211_LINKED)
3641			{
3642				if(priv->undecorated_smoothed_pwdb <= RegC38_TH)
3643				{
3644					if(reg_c38_State != RegC38_NonFsync_Other_AP)
3645					{
3646						#ifdef RTL8190P
3647							write_nic_byte(dev, rOFDM0_RxDetector3, 0x10);
3648						#else
3649							write_nic_byte(dev, rOFDM0_RxDetector3, 0x90);
3650						#endif
3651
3652						reg_c38_State = RegC38_NonFsync_Other_AP;
3653					#if 0//cosa
3654						if (Adapter->HardwareType == HARDWARE_TYPE_RTL8190P)
3655							DbgPrint("Fsync is idle, rssi<=35, write 0xc38 = 0x%x \n", 0x10);
3656						else
3657							DbgPrint("Fsync is idle, rssi<=35, write 0xc38 = 0x%x \n", 0x90);
3658					#endif
3659					}
3660				}
3661				else if(priv->undecorated_smoothed_pwdb >= (RegC38_TH+5))
3662				{
3663					if(reg_c38_State)
3664					{
3665						write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
3666						reg_c38_State = RegC38_Default;
3667						//DbgPrint("Fsync is idle, rssi>=40, write 0xc38 = 0x%x \n", pHalData->framesync);
3668					}
3669				}
3670			}
3671			else
3672			{
3673				if(reg_c38_State)
3674				{
3675					write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
3676					reg_c38_State = RegC38_Default;
3677					//DbgPrint("Fsync is idle, not connected, write 0xc38 = 0x%x \n", pHalData->framesync);
3678				}
3679			}
3680		}
3681	}
3682	if(priv->framesyncMonitor)
3683	{
3684		if(priv->reset_count != reset_cnt)
3685		{	//After silent reset, the reg_c38_State will be returned to default value
3686			write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
3687			reg_c38_State = RegC38_Default;
3688			reset_cnt = priv->reset_count;
3689			//DbgPrint("reg_c38_State = 0 for silent reset. \n");
3690		}
3691	}
3692	else
3693	{
3694		if(reg_c38_State)
3695		{
3696			write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
3697			reg_c38_State = RegC38_Default;
3698			//DbgPrint("framesync no monitor, write 0xc38 = 0x%x \n", pHalData->framesync);
3699		}
3700	}
3701}
3702
3703
3704/*-----------------------------------------------------------------------------
3705 * Function:	dm_shadow_init()
3706 *
3707 * Overview:	Store all NIC MAC/BB register content.
3708 *
3709 * Input:		NONE
3710 *
3711 * Output:		NONE
3712 *
3713 * Return:		NONE
3714 *
3715 * Revised History:
3716 *	When		Who		Remark
3717 *	05/29/2008	amy		Create Version 0 porting from windows code.
3718 *
3719 *---------------------------------------------------------------------------*/
3720void dm_shadow_init(struct net_device *dev)
3721{
3722	u8	page;
3723	u16	offset;
3724
3725	for (page = 0; page < 5; page++)
3726		for (offset = 0; offset < 256; offset++)
3727		{
3728			dm_shadow[page][offset] = read_nic_byte(dev, offset+page*256);
3729			//DbgPrint("P-%d/O-%02x=%02x\r\n", page, offset, DM_Shadow[page][offset]);
3730		}
3731
3732	for (page = 8; page < 11; page++)
3733		for (offset = 0; offset < 256; offset++)
3734			dm_shadow[page][offset] = read_nic_byte(dev, offset+page*256);
3735
3736	for (page = 12; page < 15; page++)
3737		for (offset = 0; offset < 256; offset++)
3738			dm_shadow[page][offset] = read_nic_byte(dev, offset+page*256);
3739
3740}   /* dm_shadow_init */
3741
3742/*---------------------------Define function prototype------------------------*/
3743/*-----------------------------------------------------------------------------
3744 * Function:	DM_DynamicTxPower()
3745 *
3746 * Overview:	Detect Signal strength to control TX Registry
3747 			Tx Power Control For Near/Far Range
3748 *
3749 * Input:		NONE
3750 *
3751 * Output:		NONE
3752 *
3753 * Return:		NONE
3754 *
3755 * Revised History:
3756 *	When		Who		Remark
3757 *	03/06/2008	Jacken	Create Version 0.
3758 *
3759 *---------------------------------------------------------------------------*/
3760static void dm_init_dynamic_txpower(struct net_device *dev)
3761{
3762	struct r8192_priv *priv = ieee80211_priv(dev);
3763
3764	//Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code.
3765	priv->ieee80211->bdynamic_txpower_enable = true;    //Default to enable Tx Power Control
3766	priv->bLastDTPFlag_High = false;
3767	priv->bLastDTPFlag_Low = false;
3768	priv->bDynamicTxHighPower = false;
3769	priv->bDynamicTxLowPower = false;
3770}
3771
3772static void dm_dynamic_txpower(struct net_device *dev)
3773{
3774	struct r8192_priv *priv = ieee80211_priv(dev);
3775	unsigned int txhipower_threshhold=0;
3776        unsigned int txlowpower_threshold=0;
3777	if(priv->ieee80211->bdynamic_txpower_enable != true)
3778	{
3779		priv->bDynamicTxHighPower = false;
3780		priv->bDynamicTxLowPower = false;
3781		return;
3782	}
3783	//printk("priv->ieee80211->current_network.unknown_cap_exist is %d ,priv->ieee80211->current_network.broadcom_cap_exist is %d\n",priv->ieee80211->current_network.unknown_cap_exist,priv->ieee80211->current_network.broadcom_cap_exist);
3784        if((priv->ieee80211->current_network.atheros_cap_exist ) && (priv->ieee80211->mode == IEEE_G)){
3785		txhipower_threshhold = TX_POWER_ATHEROAP_THRESH_HIGH;
3786		txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW;
3787	}
3788	else
3789	{
3790		txhipower_threshhold = TX_POWER_NEAR_FIELD_THRESH_HIGH;
3791		txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW;
3792	}
3793
3794//	printk("=======>%s(): txhipower_threshhold is %d,txlowpower_threshold is %d\n",__FUNCTION__,txhipower_threshhold,txlowpower_threshold);
3795
3796	RT_TRACE(COMP_TXAGC,"priv->undecorated_smoothed_pwdb = %ld \n" , priv->undecorated_smoothed_pwdb);
3797
3798	if(priv->ieee80211->state == IEEE80211_LINKED)
3799	{
3800		if(priv->undecorated_smoothed_pwdb >= txhipower_threshhold)
3801		{
3802			priv->bDynamicTxHighPower = true;
3803			priv->bDynamicTxLowPower = false;
3804		}
3805		else
3806		{
3807			// high power state check
3808			if(priv->undecorated_smoothed_pwdb < txlowpower_threshold && priv->bDynamicTxHighPower == true)
3809			{
3810				priv->bDynamicTxHighPower = false;
3811			}
3812			// low power state check
3813			if(priv->undecorated_smoothed_pwdb < 35)
3814			{
3815				priv->bDynamicTxLowPower = true;
3816			}
3817			else if(priv->undecorated_smoothed_pwdb >= 40)
3818			{
3819				priv->bDynamicTxLowPower = false;
3820			}
3821		}
3822	}
3823	else
3824	{
3825		//pHalData->bTXPowerCtrlforNearFarRange = !pHalData->bTXPowerCtrlforNearFarRange;
3826		priv->bDynamicTxHighPower = false;
3827		priv->bDynamicTxLowPower = false;
3828	}
3829
3830	if( (priv->bDynamicTxHighPower != priv->bLastDTPFlag_High ) ||
3831		(priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low ) )
3832	{
3833		RT_TRACE(COMP_TXAGC,"SetTxPowerLevel8190()  channel = %d \n" , priv->ieee80211->current_network.channel);
3834
3835
3836		rtl8192_phy_setTxPower(dev,priv->ieee80211->current_network.channel);
3837
3838	}
3839	priv->bLastDTPFlag_High = priv->bDynamicTxHighPower;
3840	priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower;
3841
3842}	/* dm_dynamic_txpower */
3843
3844//added by vivi, for read tx rate and retrycount
3845static void dm_check_txrateandretrycount(struct net_device * dev)
3846{
3847	struct r8192_priv *priv = ieee80211_priv(dev);
3848	struct ieee80211_device* ieee = priv->ieee80211;
3849	//for 11n tx rate
3850//	priv->stats.CurrentShowTxate = read_nic_byte(dev, Current_Tx_Rate_Reg);
3851	ieee->softmac_stats.CurrentShowTxate = read_nic_byte(dev, Current_Tx_Rate_Reg);
3852	//printk("=============>tx_rate_reg:%x\n", ieee->softmac_stats.CurrentShowTxate);
3853	//for initial tx rate
3854//	priv->stats.last_packet_rate = read_nic_byte(dev, Initial_Tx_Rate_Reg);
3855	ieee->softmac_stats.last_packet_rate = read_nic_byte(dev ,Initial_Tx_Rate_Reg);
3856	//for tx tx retry count
3857//	priv->stats.txretrycount = read_nic_dword(dev, Tx_Retry_Count_Reg);
3858	ieee->softmac_stats.txretrycount = read_nic_dword(dev, Tx_Retry_Count_Reg);
3859}
3860
3861static void dm_send_rssi_tofw(struct net_device *dev)
3862{
3863	DCMD_TXCMD_T			tx_cmd;
3864	struct r8192_priv *priv = ieee80211_priv(dev);
3865
3866	// If we test chariot, we should stop the TX command ?
3867	// Because 92E will always silent reset when we send tx command. We use register
3868	// 0x1e0(byte) to botify driver.
3869	write_nic_byte(dev, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb);
3870	return;
3871	tx_cmd.Op		= TXCMD_SET_RX_RSSI;
3872	tx_cmd.Length	= 4;
3873	tx_cmd.Value		= priv->undecorated_smoothed_pwdb;
3874
3875	cmpk_message_handle_tx(dev, (u8*)&tx_cmd,
3876								DESC_PACKET_TYPE_INIT, sizeof(DCMD_TXCMD_T));
3877}
3878
3879/*---------------------------Define function prototype------------------------*/
3880