1 // SPDX-License-Identifier: GPL-2.0
2 /*++
3 Copyright-c Realtek Semiconductor Corp. All rights reserved.
4 
5 Module Name:
6 	r8192U_dm.c
7 
8 Abstract:
9 	HW dynamic mechanism.
10 
11 Major Change History:
12 	When		Who				What
13 	----------	--------------- -------------------------------
14 	2008-05-14	amy                     create version 0 porting from windows code.
15 
16 --*/
17 #include "r8192U.h"
18 #include "r8192U_dm.h"
19 #include "r8192U_hw.h"
20 #include "r819xU_phy.h"
21 #include "r819xU_phyreg.h"
22 #include "r8190_rtl8256.h"
23 #include "r819xU_cmdpkt.h"
24 /*---------------------------Define Local Constant---------------------------*/
25 /* Indicate different AP vendor for IOT issue. */
26 static u32 edca_setting_DL[HT_IOT_PEER_MAX] = {
27 	0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0x00a44f, 0x5ea44f
28 };
29 
30 static u32 edca_setting_UL[HT_IOT_PEER_MAX] = {
31 	0x5e4322, 0x00a44f, 0x5e4322, 0x604322, 0x5ea44f, 0x5ea44f
32 };
33 
34 #define RTK_UL_EDCA 0xa44f
35 #define RTK_DL_EDCA 0x5e4322
36 /*---------------------------Define Local Constant---------------------------*/
37 
38 
39 /*------------------------Define global variable-----------------------------*/
40 /* Debug variable ? */
41 struct dig dm_digtable;
42 /* Store current software write register content for MAC PHY. */
43 u8		dm_shadow[16][256] = { {0} };
44 /* For Dynamic Rx Path Selection by Signal Strength */
45 static struct dynamic_rx_path_sel DM_RxPathSelTable;
46 
47 extern	void dm_check_fsync(struct net_device *dev);
48 
49 /* DM --> Rate Adaptive */
50 static	void	dm_check_rate_adaptive(struct net_device *dev);
51 
52 /* DM --> Bandwidth switch */
53 static	void	dm_init_bandwidth_autoswitch(struct net_device *dev);
54 static	void	dm_bandwidth_autoswitch(struct net_device *dev);
55 
56 /* DM --> TX power control */
57 /*static	void	dm_initialize_txpower_tracking(struct net_device *dev);*/
58 
59 static	void	dm_check_txpower_tracking(struct net_device *dev);
60 
61 /*static	void	dm_txpower_reset_recovery(struct net_device *dev);*/
62 
63 /* DM --> Dynamic Init Gain by RSSI */
64 static	void	dm_dig_init(struct net_device *dev);
65 static	void	dm_ctrl_initgain_byrssi(struct net_device *dev);
66 static	void	dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev);
67 static	void	dm_ctrl_initgain_byrssi_by_driverrssi(struct net_device *dev);
68 static	void	dm_ctrl_initgain_byrssi_by_fwfalse_alarm(struct net_device *dev);
69 static	void	dm_initial_gain(struct net_device *dev);
70 static	void	dm_pd_th(struct net_device *dev);
71 static	void	dm_cs_ratio(struct net_device *dev);
72 
73 static	void dm_init_ctstoself(struct net_device *dev);
74 /* DM --> EDCA turbo mode control */
75 static	void	dm_check_edca_turbo(struct net_device *dev);
76 
77 /*static	void	dm_gpio_change_rf(struct net_device *dev);*/
78 /* DM --> Check PBC */
79 static	void dm_check_pbc_gpio(struct net_device *dev);
80 
81 /* DM --> Check current RX RF path state */
82 static	void	dm_check_rx_path_selection(struct net_device *dev);
83 static	void dm_init_rxpath_selection(struct net_device *dev);
84 static	void dm_rxpath_sel_byrssi(struct net_device *dev);
85 
86 /* DM --> Fsync for broadcom ap */
87 static void dm_init_fsync(struct net_device *dev);
88 static void dm_deInit_fsync(struct net_device *dev);
89 
90 /* Added by vivi, 20080522 */
91 static	void	dm_check_txrateandretrycount(struct net_device *dev);
92 
93 /*---------------------Define local function prototype-----------------------*/
94 
95 /*---------------------Define of Tx Power Control For Near/Far Range --------*/   /*Add by Jacken 2008/02/18 */
96 static	void	dm_init_dynamic_txpower(struct net_device *dev);
97 static	void	dm_dynamic_txpower(struct net_device *dev);
98 
99 /* DM --> For rate adaptive and DIG, we must send RSSI to firmware */
100 static	void dm_send_rssi_tofw(struct net_device *dev);
101 static	void	dm_ctstoself(struct net_device *dev);
102 /*---------------------------Define function prototype------------------------*/
103 /* ================================================================================
104  *	HW Dynamic mechanism interface.
105  * ================================================================================
106  *
107  *
108  *	Description:
109  *		Prepare SW resource for HW dynamic mechanism.
110  *
111  *	Assumption:
112  *		This function is only invoked at driver initialization once.
113  */
114 void init_hal_dm(struct net_device *dev)
115 {
116 	struct r8192_priv *priv = ieee80211_priv(dev);
117 
118 	/* Undecorated Smoothed Signal Strength, it can utilized to dynamic mechanism. */
119 	priv->undecorated_smoothed_pwdb = -1;
120 
121 	/* Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code. */
122 	dm_init_dynamic_txpower(dev);
123 	init_rate_adaptive(dev);
124 	/*dm_initialize_txpower_tracking(dev);*/
125 	dm_dig_init(dev);
126 	dm_init_edca_turbo(dev);
127 	dm_init_bandwidth_autoswitch(dev);
128 	dm_init_fsync(dev);
129 	dm_init_rxpath_selection(dev);
130 	dm_init_ctstoself(dev);
131 
132 }	/* InitHalDm */
133 
134 void deinit_hal_dm(struct net_device *dev)
135 {
136 	dm_deInit_fsync(dev);
137 }
138 
139 #ifdef USB_RX_AGGREGATION_SUPPORT
140 void dm_CheckRxAggregation(struct net_device *dev)
141 {
142 	struct r8192_priv *priv = ieee80211_priv(dev);
143 	PRT_HIGH_THROUGHPUT	pHTInfo = priv->ieee80211->pHTInfo;
144 	static unsigned long	lastTxOkCnt;
145 	static unsigned long	lastRxOkCnt;
146 	unsigned long		curTxOkCnt = 0;
147 	unsigned long		curRxOkCnt = 0;
148 
149 /*
150 	if (pHalData->bForcedUsbRxAggr) {
151 		if (pHalData->ForcedUsbRxAggrInfo == 0) {
152 			if (pHalData->bCurrentRxAggrEnable) {
153 				Adapter->HalFunc.HalUsbRxAggrHandler(Adapter, FALSE);
154 			}
155 		} else {
156 			if (!pHalData->bCurrentRxAggrEnable || (pHalData->ForcedUsbRxAggrInfo != pHalData->LastUsbRxAggrInfoSetting)) {
157 				Adapter->HalFunc.HalUsbRxAggrHandler(Adapter, TRUE);
158 			}
159 		}
160 		return;
161 	}
162 
163 */
164 	curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
165 	curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
166 
167 	if ((curTxOkCnt + curRxOkCnt) < 15000000)
168 		return;
169 
170 	if (curTxOkCnt > 4*curRxOkCnt) {
171 		if (priv->bCurrentRxAggrEnable) {
172 			write_nic_dword(dev, 0x1a8, 0);
173 			priv->bCurrentRxAggrEnable = false;
174 		}
175 	} else {
176 		if (!priv->bCurrentRxAggrEnable && !pHTInfo->bCurrentRT2RTAggregation) {
177 			u32 ulValue;
178 
179 			ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
180 				(pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
181 			/* If usb rx firmware aggregation is enabled,
182 			 * when anyone of three threshold conditions above is reached,
183 			 * firmware will send aggregated packet to driver.
184 			 */
185 			write_nic_dword(dev, 0x1a8, ulValue);
186 			priv->bCurrentRxAggrEnable = true;
187 		}
188 	}
189 
190 	lastTxOkCnt = priv->stats.txbytesunicast;
191 	lastRxOkCnt = priv->stats.rxbytesunicast;
192 }	/* dm_CheckEdcaTurbo */
193 #endif
194 
195 void hal_dm_watchdog(struct net_device *dev)
196 {
197 	/*struct r8192_priv *priv = ieee80211_priv(dev);*/
198 
199 	/*static u8	previous_bssid[6] ={0};*/
200 
201 	/*Add by amy 2008/05/15 ,porting from windows code.*/
202 	dm_check_rate_adaptive(dev);
203 	dm_dynamic_txpower(dev);
204 	dm_check_txrateandretrycount(dev);
205 	dm_check_txpower_tracking(dev);
206 	dm_ctrl_initgain_byrssi(dev);
207 	dm_check_edca_turbo(dev);
208 	dm_bandwidth_autoswitch(dev);
209 	dm_check_rx_path_selection(dev);
210 	dm_check_fsync(dev);
211 
212 	/* Add by amy 2008-05-15 porting from windows code. */
213 	dm_check_pbc_gpio(dev);
214 	dm_send_rssi_tofw(dev);
215 	dm_ctstoself(dev);
216 #ifdef USB_RX_AGGREGATION_SUPPORT
217 	dm_CheckRxAggregation(dev);
218 #endif
219 }	/* HalDmWatchDog */
220 
221 /* Decide Rate Adaptive Set according to distance (signal strength)
222  *	01/11/2008	MHC		Modify input arguments and RATR table level.
223  *	01/16/2008	MHC		RF_Type is assigned in ReadAdapterInfo(). We must call
224  *						the function after making sure RF_Type.
225  */
226 void init_rate_adaptive(struct net_device *dev)
227 {
228 	struct r8192_priv *priv = ieee80211_priv(dev);
229 	prate_adaptive	pra = (prate_adaptive)&priv->rate_adaptive;
230 
231 	pra->ratr_state = DM_RATR_STA_MAX;
232 	pra->high2low_rssi_thresh_for_ra = RATE_ADAPTIVE_TH_HIGH;
233 	pra->low2high_rssi_thresh_for_ra20M = RATE_ADAPTIVE_TH_LOW_20M + 5;
234 	pra->low2high_rssi_thresh_for_ra40M = RATE_ADAPTIVE_TH_LOW_40M + 5;
235 
236 	pra->high_rssi_thresh_for_ra = RATE_ADAPTIVE_TH_HIGH + 5;
237 	pra->low_rssi_thresh_for_ra20M = RATE_ADAPTIVE_TH_LOW_20M;
238 	pra->low_rssi_thresh_for_ra40M = RATE_ADAPTIVE_TH_LOW_40M;
239 
240 	if (priv->CustomerID == RT_CID_819x_Netcore)
241 		pra->ping_rssi_enable = 1;
242 	else
243 		pra->ping_rssi_enable = 0;
244 	pra->ping_rssi_thresh_for_ra = 15;
245 
246 	if (priv->rf_type == RF_2T4R) {
247 		/* 07/10/08 MH Modify for RA smooth scheme.
248 		 * 2008/01/11 MH Modify 2T RATR table for different RSSI. 080515 porting by amy from windows code.
249 		 */
250 		pra->upper_rssi_threshold_ratr		=	0x8f0f0000;
251 		pra->middle_rssi_threshold_ratr		=	0x8f0ff000;
252 		pra->low_rssi_threshold_ratr		=	0x8f0ff001;
253 		pra->low_rssi_threshold_ratr_40M	=	0x8f0ff005;
254 		pra->low_rssi_threshold_ratr_20M	=	0x8f0ff001;
255 		pra->ping_rssi_ratr	=	0x0000000d;/* cosa add for test */
256 	} else if (priv->rf_type == RF_1T2R) {
257 		pra->upper_rssi_threshold_ratr		=	0x000f0000;
258 		pra->middle_rssi_threshold_ratr		=	0x000ff000;
259 		pra->low_rssi_threshold_ratr		=	0x000ff001;
260 		pra->low_rssi_threshold_ratr_40M	=	0x000ff005;
261 		pra->low_rssi_threshold_ratr_20M	=	0x000ff001;
262 		pra->ping_rssi_ratr	=	0x0000000d;/* cosa add for test */
263 	}
264 
265 }	/* InitRateAdaptive */
266 
267 /*-----------------------------------------------------------------------------
268  * Function:	dm_check_rate_adaptive()
269  *
270  * Overview:
271  *
272  * Input:		NONE
273  *
274  * Output:		NONE
275  *
276  * Return:		NONE
277  *
278  * Revised History:
279  *	When		Who		Remark
280  *	05/26/08	amy	Create version 0 porting from windows code.
281  *
282  *---------------------------------------------------------------------------*/
283 static void dm_check_rate_adaptive(struct net_device *dev)
284 {
285 	struct r8192_priv *priv = ieee80211_priv(dev);
286 	PRT_HIGH_THROUGHPUT	pHTInfo = priv->ieee80211->pHTInfo;
287 	prate_adaptive			pra = (prate_adaptive)&priv->rate_adaptive;
288 	u32						currentRATR, targetRATR = 0;
289 	u32						LowRSSIThreshForRA = 0, HighRSSIThreshForRA = 0;
290 	bool						bshort_gi_enabled = false;
291 	static u8					ping_rssi_state;
292 
293 	if (!priv->up) {
294 		RT_TRACE(COMP_RATE, "<---- dm_check_rate_adaptive(): driver is going to unload\n");
295 		return;
296 	}
297 
298 	if (pra->rate_adaptive_disabled) /* this variable is set by ioctl. */
299 		return;
300 
301 	/* TODO: Only 11n mode is implemented currently, */
302 	if (!(priv->ieee80211->mode == WIRELESS_MODE_N_24G ||
303 	      priv->ieee80211->mode == WIRELESS_MODE_N_5G))
304 		return;
305 
306 	if (priv->ieee80211->state == IEEE80211_LINKED) {
307 		/*RT_TRACE(COMP_RATE, "dm_CheckRateAdaptive(): \t");*/
308 
309 		/* Check whether Short GI is enabled */
310 		bshort_gi_enabled = (pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI40MHz) ||
311 			(!pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI20MHz);
312 
313 		pra->upper_rssi_threshold_ratr =
314 				(pra->upper_rssi_threshold_ratr & (~BIT(31))) |
315 				((bshort_gi_enabled) ? BIT(31) : 0);
316 
317 		pra->middle_rssi_threshold_ratr =
318 				(pra->middle_rssi_threshold_ratr & (~BIT(31))) |
319 				((bshort_gi_enabled) ? BIT(31) : 0);
320 
321 		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
322 			pra->low_rssi_threshold_ratr =
323 			      (pra->low_rssi_threshold_ratr_40M & (~BIT(31))) |
324 			      ((bshort_gi_enabled) ? BIT(31) : 0);
325 		} else {
326 			pra->low_rssi_threshold_ratr =
327 			(pra->low_rssi_threshold_ratr_20M & (~BIT(31))) |
328 			((bshort_gi_enabled) ? BIT(31) : 0);
329 		}
330 		/* cosa add for test */
331 		pra->ping_rssi_ratr =
332 				(pra->ping_rssi_ratr & (~BIT(31))) |
333 				((bshort_gi_enabled) ? BIT(31) : 0);
334 
335 		/* 2007/10/08 MH We support RA smooth scheme now. When it is the first
336 		 * time to link with AP. We will not change upper/lower threshold. If
337 		 * STA stay in high or low level, we must change two different threshold
338 		 * to prevent jumping frequently.
339 		 */
340 		if (pra->ratr_state == DM_RATR_STA_HIGH) {
341 			HighRSSIThreshForRA	= pra->high2low_rssi_thresh_for_ra;
342 			LowRSSIThreshForRA	= (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ?
343 					(pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M);
344 		} else if (pra->ratr_state == DM_RATR_STA_LOW) {
345 			HighRSSIThreshForRA	= pra->high_rssi_thresh_for_ra;
346 			LowRSSIThreshForRA	= (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ?
347 					(pra->low2high_rssi_thresh_for_ra40M):(pra->low2high_rssi_thresh_for_ra20M);
348 		} else {
349 			HighRSSIThreshForRA	= pra->high_rssi_thresh_for_ra;
350 			LowRSSIThreshForRA	= (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ?
351 					(pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M);
352 		}
353 
354 		/*DbgPrint("[DM] THresh H/L=%d/%d\n\r", RATR.HighRSSIThreshForRA, RATR.LowRSSIThreshForRA);*/
355 		if (priv->undecorated_smoothed_pwdb >= (long)HighRSSIThreshForRA) {
356 			/*DbgPrint("[DM] RSSI=%d STA=HIGH\n\r", pHalData->UndecoratedSmoothedPWDB);*/
357 			pra->ratr_state = DM_RATR_STA_HIGH;
358 			targetRATR = pra->upper_rssi_threshold_ratr;
359 		} else if (priv->undecorated_smoothed_pwdb >= (long)LowRSSIThreshForRA) {
360 			/*DbgPrint("[DM] RSSI=%d STA=Middle\n\r", pHalData->UndecoratedSmoothedPWDB);*/
361 			pra->ratr_state = DM_RATR_STA_MIDDLE;
362 			targetRATR = pra->middle_rssi_threshold_ratr;
363 		} else {
364 			/*DbgPrint("[DM] RSSI=%d STA=LOW\n\r", pHalData->UndecoratedSmoothedPWDB);*/
365 			pra->ratr_state = DM_RATR_STA_LOW;
366 			targetRATR = pra->low_rssi_threshold_ratr;
367 		}
368 
369 		/* cosa add for test */
370 		if (pra->ping_rssi_enable) {
371 			/*pHalData->UndecoratedSmoothedPWDB = 19;*/
372 			if (priv->undecorated_smoothed_pwdb < (long)(pra->ping_rssi_thresh_for_ra+5)) {
373 				if ((priv->undecorated_smoothed_pwdb < (long)pra->ping_rssi_thresh_for_ra) ||
374 					ping_rssi_state) {
375 					/*DbgPrint("TestRSSI = %d, set RATR to 0x%x\n", pHalData->UndecoratedSmoothedPWDB, pRA->TestRSSIRATR);*/
376 					pra->ratr_state = DM_RATR_STA_LOW;
377 					targetRATR = pra->ping_rssi_ratr;
378 					ping_rssi_state = 1;
379 				}
380 				/*else
381 					DbgPrint("TestRSSI is between the range.\n");*/
382 			} else {
383 				/*DbgPrint("TestRSSI Recover to 0x%x\n", targetRATR);*/
384 				ping_rssi_state = 0;
385 			}
386 		}
387 
388 		/* 2008.04.01
389 		 * For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7.
390 		 */
391 		if (priv->ieee80211->GetHalfNmodeSupportByAPsHandler(dev))
392 			targetRATR &= 0xf00fffff;
393 
394 		/* Check whether updating of RATR0 is required */
395 		read_nic_dword(dev, RATR0, &currentRATR);
396 		if (targetRATR !=  currentRATR) {
397 			u32 ratr_value;
398 
399 			ratr_value = targetRATR;
400 			RT_TRACE(COMP_RATE, "currentRATR = %x, targetRATR = %x\n", currentRATR, targetRATR);
401 			if (priv->rf_type == RF_1T2R)
402 				ratr_value &= ~(RATE_ALL_OFDM_2SS);
403 			write_nic_dword(dev, RATR0, ratr_value);
404 			write_nic_byte(dev, UFWP, 1);
405 
406 			pra->last_ratr = targetRATR;
407 		}
408 
409 	} else {
410 		pra->ratr_state = DM_RATR_STA_MAX;
411 	}
412 
413 }	/* dm_CheckRateAdaptive */
414 
415 static void dm_init_bandwidth_autoswitch(struct net_device *dev)
416 {
417 	struct r8192_priv *priv = ieee80211_priv(dev);
418 
419 	priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz = BW_AUTO_SWITCH_LOW_HIGH;
420 	priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz = BW_AUTO_SWITCH_HIGH_LOW;
421 	priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
422 	priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable = false;
423 
424 }	/* dm_init_bandwidth_autoswitch */
425 
426 static void dm_bandwidth_autoswitch(struct net_device *dev)
427 {
428 	struct r8192_priv *priv = ieee80211_priv(dev);
429 
430 	if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 || !priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable)
431 		return;
432 	if (!priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz) { /* If send packets in 40 Mhz in 20/40 */
433 		if (priv->undecorated_smoothed_pwdb <= priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz)
434 			priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = true;
435 	} else { /* in force send packets in 20 Mhz in 20/40 */
436 		if (priv->undecorated_smoothed_pwdb >= priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz)
437 			priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
438 	}
439 }	/* dm_BandwidthAutoSwitch */
440 
441 /* OFDM default at 0db, index=6. */
442 static u32 OFDMSwingTable[OFDM_Table_Length] = {
443 	0x7f8001fe,	/* 0, +6db */
444 	0x71c001c7,	/* 1, +5db */
445 	0x65400195,	/* 2, +4db */
446 	0x5a400169,	/* 3, +3db */
447 	0x50800142,	/* 4, +2db */
448 	0x47c0011f,	/* 5, +1db */
449 	0x40000100,	/* 6, +0db ===> default, upper for higher temperature, lower for low temperature */
450 	0x390000e4,	/* 7, -1db */
451 	0x32c000cb,	/* 8, -2db */
452 	0x2d4000b5,	/* 9, -3db */
453 	0x288000a2,	/* 10, -4db */
454 	0x24000090,	/* 11, -5db */
455 	0x20000080,	/* 12, -6db */
456 	0x1c800072,	/* 13, -7db */
457 	0x19800066,	/* 14, -8db */
458 	0x26c0005b,	/* 15, -9db */
459 	0x24400051,	/* 16, -10db */
460 	0x12000048,	/* 17, -11db */
461 	0x10000040	/* 18, -12db */
462 };
463 
464 static u8	CCKSwingTable_Ch1_Ch13[CCK_Table_length][8] = {
465 	{0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},	/* 0, +0db ===> CCK40M default */
466 	{0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},	/* 1, -1db */
467 	{0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},	/* 2, -2db */
468 	{0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},	/* 3, -3db */
469 	{0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},	/* 4, -4db */
470 	{0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},	/* 5, -5db */
471 	{0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},	/* 6, -6db ===> CCK20M default */
472 	{0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},	/* 7, -7db */
473 	{0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},	/* 8, -8db */
474 	{0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},	/* 9, -9db */
475 	{0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},	/* 10, -10db */
476 	{0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}	/* 11, -11db */
477 };
478 
479 static u8	CCKSwingTable_Ch14[CCK_Table_length][8] = {
480 	{0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},	/* 0, +0db  ===> CCK40M default */
481 	{0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},	/* 1, -1db */
482 	{0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},	/* 2, -2db */
483 	{0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},	/* 3, -3db */
484 	{0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},	/* 4, -4db */
485 	{0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},	/* 5, -5db */
486 	{0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},	/* 6, -6db  ===> CCK20M default */
487 	{0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},	/* 7, -7db */
488 	{0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},	/* 8, -8db */
489 	{0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},	/* 9, -9db */
490 	{0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},	/* 10, -10db */
491 	{0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}	/* 11, -11db */
492 };
493 
494 static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
495 {
496 	struct r8192_priv *priv = ieee80211_priv(dev);
497 	bool						viviflag = false;
498 	struct tx_config_cmd			        tx_cmd;
499 	u8						powerlevelOFDM24G;
500 	int						i = 0, j = 0, k = 0;
501 	u8						RF_Type, tmp_report[5] = {0, 0, 0, 0, 0};
502 	u32						Value;
503 	u8						Pwr_Flag;
504 	u16						Avg_TSSI_Meas, TSSI_13dBm, Avg_TSSI_Meas_from_driver = 0;
505 	/*RT_STATUS				rtStatus = RT_STATUS_SUCCESS;*/
506 	bool rtStatus = true;
507 	u32						delta = 0;
508 
509 	write_nic_byte(dev, 0x1ba, 0);
510 
511 	priv->ieee80211->bdynamic_txpower_enable = false;
512 
513 	powerlevelOFDM24G = (u8)(priv->Pwr_Track>>24);
514 	RF_Type = priv->rf_type;
515 	Value = (RF_Type<<8) | powerlevelOFDM24G;
516 
517 	RT_TRACE(COMP_POWER_TRACKING, "powerlevelOFDM24G = %x\n", powerlevelOFDM24G);
518 
519 	for (j = 0; j <= 30; j++) { /* fill tx_cmd */
520 		tx_cmd.cmd_op = TXCMD_SET_TX_PWR_TRACKING;
521 		tx_cmd.cmd_length = sizeof(tx_cmd.cmd_op);
522 		tx_cmd.cmd_value = Value;
523 		rtStatus = SendTxCommandPacket(dev, &tx_cmd, sizeof(struct tx_config_cmd));
524 		if (rtStatus == RT_STATUS_FAILURE)
525 			RT_TRACE(COMP_POWER_TRACKING, "Set configuration with tx cmd queue fail!\n");
526 		usleep_range(1000, 2000);
527 		/*DbgPrint("hi, vivi, strange\n");*/
528 		for (i = 0; i <= 30; i++) {
529 			read_nic_byte(dev, 0x1ba, &Pwr_Flag);
530 
531 			if (Pwr_Flag == 0) {
532 				usleep_range(1000, 2000);
533 				continue;
534 			}
535 			read_nic_word(dev, 0x13c, &Avg_TSSI_Meas);
536 			if (Avg_TSSI_Meas == 0) {
537 				write_nic_byte(dev, 0x1ba, 0);
538 				break;
539 			}
540 
541 			for (k = 0; k < 5; k++) {
542 				if (k != 4)
543 					read_nic_byte(dev, 0x134+k, &tmp_report[k]);
544 				else
545 					read_nic_byte(dev, 0x13e, &tmp_report[k]);
546 				RT_TRACE(COMP_POWER_TRACKING, "TSSI_report_value = %d\n", tmp_report[k]);
547 			}
548 
549 			/* check if the report value is right */
550 			for (k = 0; k < 5; k++) {
551 				if (tmp_report[k] <= 20) {
552 					viviflag = true;
553 					break;
554 				}
555 			}
556 			if (viviflag) {
557 				write_nic_byte(dev, 0x1ba, 0);
558 				viviflag = false;
559 				RT_TRACE(COMP_POWER_TRACKING, "we filtered the data\n");
560 				for (k = 0; k < 5; k++)
561 					tmp_report[k] = 0;
562 				break;
563 			}
564 
565 			for (k = 0; k < 5; k++)
566 				Avg_TSSI_Meas_from_driver += tmp_report[k];
567 
568 			Avg_TSSI_Meas_from_driver = Avg_TSSI_Meas_from_driver*100/5;
569 			RT_TRACE(COMP_POWER_TRACKING, "Avg_TSSI_Meas_from_driver = %d\n", Avg_TSSI_Meas_from_driver);
570 			TSSI_13dBm = priv->TSSI_13dBm;
571 			RT_TRACE(COMP_POWER_TRACKING, "TSSI_13dBm = %d\n", TSSI_13dBm);
572 
573 			/*if (abs(Avg_TSSI_Meas_from_driver - TSSI_13dBm) <= E_FOR_TX_POWER_TRACK)*/
574 			/* For MacOS-compatible */
575 			if (Avg_TSSI_Meas_from_driver > TSSI_13dBm)
576 				delta = Avg_TSSI_Meas_from_driver - TSSI_13dBm;
577 			else
578 				delta = TSSI_13dBm - Avg_TSSI_Meas_from_driver;
579 
580 			if (delta <= E_FOR_TX_POWER_TRACK) {
581 				priv->ieee80211->bdynamic_txpower_enable = true;
582 				write_nic_byte(dev, 0x1ba, 0);
583 				RT_TRACE(COMP_POWER_TRACKING, "tx power track is done\n");
584 				RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
585 				RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
586 				RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attenuation_difference = %d\n", priv->cck_present_attenuation_difference);
587 				RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attenuation = %d\n", priv->cck_present_attenuation);
588 				return;
589 			}
590 			if (Avg_TSSI_Meas_from_driver < TSSI_13dBm - E_FOR_TX_POWER_TRACK) {
591 				if (priv->rfa_txpowertrackingindex > 0) {
592 					priv->rfa_txpowertrackingindex--;
593 					if (priv->rfa_txpowertrackingindex_real > 4) {
594 						priv->rfa_txpowertrackingindex_real--;
595 						rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
596 					}
597 				}
598 			} else {
599 				if (priv->rfa_txpowertrackingindex < 36) {
600 					priv->rfa_txpowertrackingindex++;
601 					priv->rfa_txpowertrackingindex_real++;
602 					rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
603 				}
604 			}
605 			priv->cck_present_attenuation_difference
606 				= priv->rfa_txpowertrackingindex - priv->rfa_txpowertracking_default;
607 
608 			if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
609 				priv->cck_present_attenuation
610 					= priv->cck_present_attenuation_20Mdefault + priv->cck_present_attenuation_difference;
611 			else
612 				priv->cck_present_attenuation
613 					= priv->cck_present_attenuation_40Mdefault + priv->cck_present_attenuation_difference;
614 
615 			if (priv->cck_present_attenuation > -1 && priv->cck_present_attenuation < 23) {
616 				if (priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14) {
617 					priv->bcck_in_ch14 = true;
618 					dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
619 				} else if (priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14) {
620 					priv->bcck_in_ch14 = false;
621 					dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
622 				} else
623 					dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
624 			}
625 			RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
626 			RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
627 			RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attenuation_difference = %d\n", priv->cck_present_attenuation_difference);
628 			RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attenuation = %d\n", priv->cck_present_attenuation);
629 
630 			if (priv->cck_present_attenuation_difference <= -12 || priv->cck_present_attenuation_difference >= 24) {
631 				priv->ieee80211->bdynamic_txpower_enable = true;
632 				write_nic_byte(dev, 0x1ba, 0);
633 				RT_TRACE(COMP_POWER_TRACKING, "tx power track--->limited\n");
634 				return;
635 			}
636 
637 			write_nic_byte(dev, 0x1ba, 0);
638 			Avg_TSSI_Meas_from_driver = 0;
639 			for (k = 0; k < 5; k++)
640 				tmp_report[k] = 0;
641 			break;
642 		}
643 	}
644 	priv->ieee80211->bdynamic_txpower_enable = true;
645 	write_nic_byte(dev, 0x1ba, 0);
646 }
647 
648 static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device *dev)
649 {
650 #define ThermalMeterVal	9
651 	struct r8192_priv *priv = ieee80211_priv(dev);
652 	u32 tmpRegA, TempCCk;
653 	u8 tmpOFDMindex, tmpCCKindex, tmpCCK20Mindex, tmpCCK40Mindex, tmpval;
654 	int i = 0, CCKSwingNeedUpdate = 0;
655 
656 	if (!priv->btxpower_trackingInit) {
657 		/* Query OFDM default setting */
658 		tmpRegA = rtl8192_QueryBBReg(dev, rOFDM0_XATxIQImbalance, bMaskDWord);
659 		for (i = 0; i < OFDM_Table_Length; i++) { /* find the index */
660 			if (tmpRegA == OFDMSwingTable[i]) {
661 				priv->OFDM_index = (u8)i;
662 				RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, OFDM_index=0x%x\n",
663 					rOFDM0_XATxIQImbalance, tmpRegA, priv->OFDM_index);
664 			}
665 		}
666 
667 		/* Query CCK default setting From 0xa22 */
668 		TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
669 		for (i = 0; i < CCK_Table_length; i++) {
670 			if (TempCCk == (u32)CCKSwingTable_Ch1_Ch13[i][0]) {
671 				priv->CCK_index = (u8) i;
672 				RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, CCK_index=0x%x\n",
673 					rCCK0_TxFilter1, TempCCk, priv->CCK_index);
674 				break;
675 			}
676 		}
677 		priv->btxpower_trackingInit = true;
678 		/*pHalData->TXPowercount = 0;*/
679 		return;
680 	}
681 
682 	/* ==========================
683 	 * this is only for test, should be masked
684 	 * ==========================
685 	 */
686 
687 	/* read and filter out unreasonable value */
688 	tmpRegA = rtl8192_phy_QueryRFReg(dev, RF90_PATH_A, 0x12, 0x078);	/* 0x12: RF Reg[10:7] */
689 	RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d\n", tmpRegA);
690 	if (tmpRegA < 3 || tmpRegA > 13)
691 		return;
692 	if (tmpRegA >= 12)	/* if over 12, TP will be bad when high temperature */
693 		tmpRegA = 12;
694 	RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d\n", tmpRegA);
695 	priv->ThermalMeter[0] = ThermalMeterVal;	/* We use fixed value by Bryant's suggestion */
696 	priv->ThermalMeter[1] = ThermalMeterVal;	/* We use fixed value by Bryant's suggestion */
697 
698 	/* Get current RF-A temperature index */
699 	if (priv->ThermalMeter[0] >= (u8)tmpRegA) {	/* lower temperature */
700 		tmpOFDMindex = tmpCCK20Mindex = 6+(priv->ThermalMeter[0]-(u8)tmpRegA);
701 		tmpCCK40Mindex = tmpCCK20Mindex - 6;
702 		if (tmpOFDMindex >= OFDM_Table_Length)
703 			tmpOFDMindex = OFDM_Table_Length-1;
704 		if (tmpCCK20Mindex >= CCK_Table_length)
705 			tmpCCK20Mindex = CCK_Table_length-1;
706 		if (tmpCCK40Mindex >= CCK_Table_length)
707 			tmpCCK40Mindex = CCK_Table_length-1;
708 	} else {
709 		tmpval = (u8)tmpRegA - priv->ThermalMeter[0];
710 
711 		if (tmpval >= 6) {
712 			/* higher temperature */
713 			tmpOFDMindex = 0;
714 			tmpCCK20Mindex = 0;
715 		} else {
716 			/* max to +6dB */
717 			tmpOFDMindex = 6 - tmpval;
718 			tmpCCK20Mindex = 6 - tmpval;
719 		}
720 		tmpCCK40Mindex = 0;
721 	}
722 	/*DbgPrint("%ddb, tmpOFDMindex = %d, tmpCCK20Mindex = %d, tmpCCK40Mindex = %d",
723 		((u1Byte)tmpRegA - pHalData->ThermalMeter[0]),
724 		tmpOFDMindex, tmpCCK20Mindex, tmpCCK40Mindex);*/
725 	if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)	/* 40M */
726 		tmpCCKindex = tmpCCK40Mindex;
727 	else
728 		tmpCCKindex = tmpCCK20Mindex;
729 
730 	if (priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14) {
731 		priv->bcck_in_ch14 = true;
732 		CCKSwingNeedUpdate = 1;
733 	} else if (priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14) {
734 		priv->bcck_in_ch14 = false;
735 		CCKSwingNeedUpdate = 1;
736 	}
737 
738 	if (priv->CCK_index != tmpCCKindex) {
739 		priv->CCK_index = tmpCCKindex;
740 		CCKSwingNeedUpdate = 1;
741 	}
742 
743 	if (CCKSwingNeedUpdate) {
744 		/*DbgPrint("Update CCK Swing, CCK_index = %d\n", pHalData->CCK_index);*/
745 		dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
746 	}
747 	if (priv->OFDM_index != tmpOFDMindex) {
748 		priv->OFDM_index = tmpOFDMindex;
749 		rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable[priv->OFDM_index]);
750 		RT_TRACE(COMP_POWER_TRACKING, "Update OFDMSwing[%d] = 0x%x\n",
751 			priv->OFDM_index, OFDMSwingTable[priv->OFDM_index]);
752 	}
753 	priv->txpower_count = 0;
754 }
755 
756 void dm_txpower_trackingcallback(struct work_struct *work)
757 {
758 	struct delayed_work *dwork = to_delayed_work(work);
759 	struct r8192_priv *priv = container_of(dwork, struct r8192_priv, txpower_tracking_wq);
760 	struct net_device *dev = priv->ieee80211->dev;
761 
762 	if (priv->bDcut)
763 		dm_TXPowerTrackingCallback_TSSI(dev);
764 	else
765 		dm_TXPowerTrackingCallback_ThermalMeter(dev);
766 }
767 
768 static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev)
769 {
770 	struct r8192_priv *priv = ieee80211_priv(dev);
771 
772 	/* Initial the Tx BB index and mapping value */
773 	priv->txbbgain_table[0].txbb_iq_amplifygain =			12;
774 	priv->txbbgain_table[0].txbbgain_value = 0x7f8001fe;
775 	priv->txbbgain_table[1].txbb_iq_amplifygain =			11;
776 	priv->txbbgain_table[1].txbbgain_value = 0x788001e2;
777 	priv->txbbgain_table[2].txbb_iq_amplifygain =			10;
778 	priv->txbbgain_table[2].txbbgain_value = 0x71c001c7;
779 	priv->txbbgain_table[3].txbb_iq_amplifygain =			9;
780 	priv->txbbgain_table[3].txbbgain_value = 0x6b8001ae;
781 	priv->txbbgain_table[4].txbb_iq_amplifygain =		       8;
782 	priv->txbbgain_table[4].txbbgain_value = 0x65400195;
783 	priv->txbbgain_table[5].txbb_iq_amplifygain =		       7;
784 	priv->txbbgain_table[5].txbbgain_value = 0x5fc0017f;
785 	priv->txbbgain_table[6].txbb_iq_amplifygain =		       6;
786 	priv->txbbgain_table[6].txbbgain_value = 0x5a400169;
787 	priv->txbbgain_table[7].txbb_iq_amplifygain =		       5;
788 	priv->txbbgain_table[7].txbbgain_value = 0x55400155;
789 	priv->txbbgain_table[8].txbb_iq_amplifygain =		       4;
790 	priv->txbbgain_table[8].txbbgain_value = 0x50800142;
791 	priv->txbbgain_table[9].txbb_iq_amplifygain =		       3;
792 	priv->txbbgain_table[9].txbbgain_value = 0x4c000130;
793 	priv->txbbgain_table[10].txbb_iq_amplifygain =		       2;
794 	priv->txbbgain_table[10].txbbgain_value = 0x47c0011f;
795 	priv->txbbgain_table[11].txbb_iq_amplifygain =		       1;
796 	priv->txbbgain_table[11].txbbgain_value = 0x43c0010f;
797 	priv->txbbgain_table[12].txbb_iq_amplifygain =		       0;
798 	priv->txbbgain_table[12].txbbgain_value = 0x40000100;
799 	priv->txbbgain_table[13].txbb_iq_amplifygain =		       -1;
800 	priv->txbbgain_table[13].txbbgain_value = 0x3c8000f2;
801 	priv->txbbgain_table[14].txbb_iq_amplifygain =		     -2;
802 	priv->txbbgain_table[14].txbbgain_value = 0x390000e4;
803 	priv->txbbgain_table[15].txbb_iq_amplifygain =		     -3;
804 	priv->txbbgain_table[15].txbbgain_value = 0x35c000d7;
805 	priv->txbbgain_table[16].txbb_iq_amplifygain =		     -4;
806 	priv->txbbgain_table[16].txbbgain_value = 0x32c000cb;
807 	priv->txbbgain_table[17].txbb_iq_amplifygain =		     -5;
808 	priv->txbbgain_table[17].txbbgain_value = 0x300000c0;
809 	priv->txbbgain_table[18].txbb_iq_amplifygain =			    -6;
810 	priv->txbbgain_table[18].txbbgain_value = 0x2d4000b5;
811 	priv->txbbgain_table[19].txbb_iq_amplifygain =		     -7;
812 	priv->txbbgain_table[19].txbbgain_value = 0x2ac000ab;
813 	priv->txbbgain_table[20].txbb_iq_amplifygain =		     -8;
814 	priv->txbbgain_table[20].txbbgain_value = 0x288000a2;
815 	priv->txbbgain_table[21].txbb_iq_amplifygain =		     -9;
816 	priv->txbbgain_table[21].txbbgain_value = 0x26000098;
817 	priv->txbbgain_table[22].txbb_iq_amplifygain =		     -10;
818 	priv->txbbgain_table[22].txbbgain_value = 0x24000090;
819 	priv->txbbgain_table[23].txbb_iq_amplifygain =		     -11;
820 	priv->txbbgain_table[23].txbbgain_value = 0x22000088;
821 	priv->txbbgain_table[24].txbb_iq_amplifygain =		     -12;
822 	priv->txbbgain_table[24].txbbgain_value = 0x20000080;
823 	priv->txbbgain_table[25].txbb_iq_amplifygain =		     -13;
824 	priv->txbbgain_table[25].txbbgain_value = 0x1a00006c;
825 	priv->txbbgain_table[26].txbb_iq_amplifygain =		     -14;
826 	priv->txbbgain_table[26].txbbgain_value = 0x1c800072;
827 	priv->txbbgain_table[27].txbb_iq_amplifygain =		     -15;
828 	priv->txbbgain_table[27].txbbgain_value = 0x18000060;
829 	priv->txbbgain_table[28].txbb_iq_amplifygain =		     -16;
830 	priv->txbbgain_table[28].txbbgain_value = 0x19800066;
831 	priv->txbbgain_table[29].txbb_iq_amplifygain =		     -17;
832 	priv->txbbgain_table[29].txbbgain_value = 0x15800056;
833 	priv->txbbgain_table[30].txbb_iq_amplifygain =		     -18;
834 	priv->txbbgain_table[30].txbbgain_value = 0x26c0005b;
835 	priv->txbbgain_table[31].txbb_iq_amplifygain =		     -19;
836 	priv->txbbgain_table[31].txbbgain_value = 0x14400051;
837 	priv->txbbgain_table[32].txbb_iq_amplifygain =		     -20;
838 	priv->txbbgain_table[32].txbbgain_value = 0x24400051;
839 	priv->txbbgain_table[33].txbb_iq_amplifygain =		     -21;
840 	priv->txbbgain_table[33].txbbgain_value = 0x1300004c;
841 	priv->txbbgain_table[34].txbb_iq_amplifygain =		     -22;
842 	priv->txbbgain_table[34].txbbgain_value = 0x12000048;
843 	priv->txbbgain_table[35].txbb_iq_amplifygain =		     -23;
844 	priv->txbbgain_table[35].txbbgain_value = 0x11000044;
845 	priv->txbbgain_table[36].txbb_iq_amplifygain =		     -24;
846 	priv->txbbgain_table[36].txbbgain_value = 0x10000040;
847 
848 	/* ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
849 	 * This Table is for CH1~CH13
850 	 */
851 	priv->cck_txbbgain_table[0].ccktxbb_valuearray[0] = 0x36;
852 	priv->cck_txbbgain_table[0].ccktxbb_valuearray[1] = 0x35;
853 	priv->cck_txbbgain_table[0].ccktxbb_valuearray[2] = 0x2e;
854 	priv->cck_txbbgain_table[0].ccktxbb_valuearray[3] = 0x25;
855 	priv->cck_txbbgain_table[0].ccktxbb_valuearray[4] = 0x1c;
856 	priv->cck_txbbgain_table[0].ccktxbb_valuearray[5] = 0x12;
857 	priv->cck_txbbgain_table[0].ccktxbb_valuearray[6] = 0x09;
858 	priv->cck_txbbgain_table[0].ccktxbb_valuearray[7] = 0x04;
859 
860 	priv->cck_txbbgain_table[1].ccktxbb_valuearray[0] = 0x33;
861 	priv->cck_txbbgain_table[1].ccktxbb_valuearray[1] = 0x32;
862 	priv->cck_txbbgain_table[1].ccktxbb_valuearray[2] = 0x2b;
863 	priv->cck_txbbgain_table[1].ccktxbb_valuearray[3] = 0x23;
864 	priv->cck_txbbgain_table[1].ccktxbb_valuearray[4] = 0x1a;
865 	priv->cck_txbbgain_table[1].ccktxbb_valuearray[5] = 0x11;
866 	priv->cck_txbbgain_table[1].ccktxbb_valuearray[6] = 0x08;
867 	priv->cck_txbbgain_table[1].ccktxbb_valuearray[7] = 0x04;
868 
869 	priv->cck_txbbgain_table[2].ccktxbb_valuearray[0] = 0x30;
870 	priv->cck_txbbgain_table[2].ccktxbb_valuearray[1] = 0x2f;
871 	priv->cck_txbbgain_table[2].ccktxbb_valuearray[2] = 0x29;
872 	priv->cck_txbbgain_table[2].ccktxbb_valuearray[3] = 0x21;
873 	priv->cck_txbbgain_table[2].ccktxbb_valuearray[4] = 0x19;
874 	priv->cck_txbbgain_table[2].ccktxbb_valuearray[5] = 0x10;
875 	priv->cck_txbbgain_table[2].ccktxbb_valuearray[6] = 0x08;
876 	priv->cck_txbbgain_table[2].ccktxbb_valuearray[7] = 0x03;
877 
878 	priv->cck_txbbgain_table[3].ccktxbb_valuearray[0] = 0x2d;
879 	priv->cck_txbbgain_table[3].ccktxbb_valuearray[1] = 0x2d;
880 	priv->cck_txbbgain_table[3].ccktxbb_valuearray[2] = 0x27;
881 	priv->cck_txbbgain_table[3].ccktxbb_valuearray[3] = 0x1f;
882 	priv->cck_txbbgain_table[3].ccktxbb_valuearray[4] = 0x18;
883 	priv->cck_txbbgain_table[3].ccktxbb_valuearray[5] = 0x0f;
884 	priv->cck_txbbgain_table[3].ccktxbb_valuearray[6] = 0x08;
885 	priv->cck_txbbgain_table[3].ccktxbb_valuearray[7] = 0x03;
886 
887 	priv->cck_txbbgain_table[4].ccktxbb_valuearray[0] = 0x2b;
888 	priv->cck_txbbgain_table[4].ccktxbb_valuearray[1] = 0x2a;
889 	priv->cck_txbbgain_table[4].ccktxbb_valuearray[2] = 0x25;
890 	priv->cck_txbbgain_table[4].ccktxbb_valuearray[3] = 0x1e;
891 	priv->cck_txbbgain_table[4].ccktxbb_valuearray[4] = 0x16;
892 	priv->cck_txbbgain_table[4].ccktxbb_valuearray[5] = 0x0e;
893 	priv->cck_txbbgain_table[4].ccktxbb_valuearray[6] = 0x07;
894 	priv->cck_txbbgain_table[4].ccktxbb_valuearray[7] = 0x03;
895 
896 	priv->cck_txbbgain_table[5].ccktxbb_valuearray[0] = 0x28;
897 	priv->cck_txbbgain_table[5].ccktxbb_valuearray[1] = 0x28;
898 	priv->cck_txbbgain_table[5].ccktxbb_valuearray[2] = 0x22;
899 	priv->cck_txbbgain_table[5].ccktxbb_valuearray[3] = 0x1c;
900 	priv->cck_txbbgain_table[5].ccktxbb_valuearray[4] = 0x15;
901 	priv->cck_txbbgain_table[5].ccktxbb_valuearray[5] = 0x0d;
902 	priv->cck_txbbgain_table[5].ccktxbb_valuearray[6] = 0x07;
903 	priv->cck_txbbgain_table[5].ccktxbb_valuearray[7] = 0x03;
904 
905 	priv->cck_txbbgain_table[6].ccktxbb_valuearray[0] = 0x26;
906 	priv->cck_txbbgain_table[6].ccktxbb_valuearray[1] = 0x25;
907 	priv->cck_txbbgain_table[6].ccktxbb_valuearray[2] = 0x21;
908 	priv->cck_txbbgain_table[6].ccktxbb_valuearray[3] = 0x1b;
909 	priv->cck_txbbgain_table[6].ccktxbb_valuearray[4] = 0x14;
910 	priv->cck_txbbgain_table[6].ccktxbb_valuearray[5] = 0x0d;
911 	priv->cck_txbbgain_table[6].ccktxbb_valuearray[6] = 0x06;
912 	priv->cck_txbbgain_table[6].ccktxbb_valuearray[7] = 0x03;
913 
914 	priv->cck_txbbgain_table[7].ccktxbb_valuearray[0] = 0x24;
915 	priv->cck_txbbgain_table[7].ccktxbb_valuearray[1] = 0x23;
916 	priv->cck_txbbgain_table[7].ccktxbb_valuearray[2] = 0x1f;
917 	priv->cck_txbbgain_table[7].ccktxbb_valuearray[3] = 0x19;
918 	priv->cck_txbbgain_table[7].ccktxbb_valuearray[4] = 0x13;
919 	priv->cck_txbbgain_table[7].ccktxbb_valuearray[5] = 0x0c;
920 	priv->cck_txbbgain_table[7].ccktxbb_valuearray[6] = 0x06;
921 	priv->cck_txbbgain_table[7].ccktxbb_valuearray[7] = 0x03;
922 
923 	priv->cck_txbbgain_table[8].ccktxbb_valuearray[0] = 0x22;
924 	priv->cck_txbbgain_table[8].ccktxbb_valuearray[1] = 0x21;
925 	priv->cck_txbbgain_table[8].ccktxbb_valuearray[2] = 0x1d;
926 	priv->cck_txbbgain_table[8].ccktxbb_valuearray[3] = 0x18;
927 	priv->cck_txbbgain_table[8].ccktxbb_valuearray[4] = 0x11;
928 	priv->cck_txbbgain_table[8].ccktxbb_valuearray[5] = 0x0b;
929 	priv->cck_txbbgain_table[8].ccktxbb_valuearray[6] = 0x06;
930 	priv->cck_txbbgain_table[8].ccktxbb_valuearray[7] = 0x02;
931 
932 	priv->cck_txbbgain_table[9].ccktxbb_valuearray[0] = 0x20;
933 	priv->cck_txbbgain_table[9].ccktxbb_valuearray[1] = 0x20;
934 	priv->cck_txbbgain_table[9].ccktxbb_valuearray[2] = 0x1b;
935 	priv->cck_txbbgain_table[9].ccktxbb_valuearray[3] = 0x16;
936 	priv->cck_txbbgain_table[9].ccktxbb_valuearray[4] = 0x11;
937 	priv->cck_txbbgain_table[9].ccktxbb_valuearray[5] = 0x08;
938 	priv->cck_txbbgain_table[9].ccktxbb_valuearray[6] = 0x05;
939 	priv->cck_txbbgain_table[9].ccktxbb_valuearray[7] = 0x02;
940 
941 	priv->cck_txbbgain_table[10].ccktxbb_valuearray[0] = 0x1f;
942 	priv->cck_txbbgain_table[10].ccktxbb_valuearray[1] = 0x1e;
943 	priv->cck_txbbgain_table[10].ccktxbb_valuearray[2] = 0x1a;
944 	priv->cck_txbbgain_table[10].ccktxbb_valuearray[3] = 0x15;
945 	priv->cck_txbbgain_table[10].ccktxbb_valuearray[4] = 0x10;
946 	priv->cck_txbbgain_table[10].ccktxbb_valuearray[5] = 0x0a;
947 	priv->cck_txbbgain_table[10].ccktxbb_valuearray[6] = 0x05;
948 	priv->cck_txbbgain_table[10].ccktxbb_valuearray[7] = 0x02;
949 
950 	priv->cck_txbbgain_table[11].ccktxbb_valuearray[0] = 0x1d;
951 	priv->cck_txbbgain_table[11].ccktxbb_valuearray[1] = 0x1c;
952 	priv->cck_txbbgain_table[11].ccktxbb_valuearray[2] = 0x18;
953 	priv->cck_txbbgain_table[11].ccktxbb_valuearray[3] = 0x14;
954 	priv->cck_txbbgain_table[11].ccktxbb_valuearray[4] = 0x0f;
955 	priv->cck_txbbgain_table[11].ccktxbb_valuearray[5] = 0x0a;
956 	priv->cck_txbbgain_table[11].ccktxbb_valuearray[6] = 0x05;
957 	priv->cck_txbbgain_table[11].ccktxbb_valuearray[7] = 0x02;
958 
959 	priv->cck_txbbgain_table[12].ccktxbb_valuearray[0] = 0x1b;
960 	priv->cck_txbbgain_table[12].ccktxbb_valuearray[1] = 0x1a;
961 	priv->cck_txbbgain_table[12].ccktxbb_valuearray[2] = 0x17;
962 	priv->cck_txbbgain_table[12].ccktxbb_valuearray[3] = 0x13;
963 	priv->cck_txbbgain_table[12].ccktxbb_valuearray[4] = 0x0e;
964 	priv->cck_txbbgain_table[12].ccktxbb_valuearray[5] = 0x09;
965 	priv->cck_txbbgain_table[12].ccktxbb_valuearray[6] = 0x04;
966 	priv->cck_txbbgain_table[12].ccktxbb_valuearray[7] = 0x02;
967 
968 	priv->cck_txbbgain_table[13].ccktxbb_valuearray[0] = 0x1a;
969 	priv->cck_txbbgain_table[13].ccktxbb_valuearray[1] = 0x19;
970 	priv->cck_txbbgain_table[13].ccktxbb_valuearray[2] = 0x16;
971 	priv->cck_txbbgain_table[13].ccktxbb_valuearray[3] = 0x12;
972 	priv->cck_txbbgain_table[13].ccktxbb_valuearray[4] = 0x0d;
973 	priv->cck_txbbgain_table[13].ccktxbb_valuearray[5] = 0x09;
974 	priv->cck_txbbgain_table[13].ccktxbb_valuearray[6] = 0x04;
975 	priv->cck_txbbgain_table[13].ccktxbb_valuearray[7] = 0x02;
976 
977 	priv->cck_txbbgain_table[14].ccktxbb_valuearray[0] = 0x18;
978 	priv->cck_txbbgain_table[14].ccktxbb_valuearray[1] = 0x17;
979 	priv->cck_txbbgain_table[14].ccktxbb_valuearray[2] = 0x15;
980 	priv->cck_txbbgain_table[14].ccktxbb_valuearray[3] = 0x11;
981 	priv->cck_txbbgain_table[14].ccktxbb_valuearray[4] = 0x0c;
982 	priv->cck_txbbgain_table[14].ccktxbb_valuearray[5] = 0x08;
983 	priv->cck_txbbgain_table[14].ccktxbb_valuearray[6] = 0x04;
984 	priv->cck_txbbgain_table[14].ccktxbb_valuearray[7] = 0x02;
985 
986 	priv->cck_txbbgain_table[15].ccktxbb_valuearray[0] = 0x17;
987 	priv->cck_txbbgain_table[15].ccktxbb_valuearray[1] = 0x16;
988 	priv->cck_txbbgain_table[15].ccktxbb_valuearray[2] = 0x13;
989 	priv->cck_txbbgain_table[15].ccktxbb_valuearray[3] = 0x10;
990 	priv->cck_txbbgain_table[15].ccktxbb_valuearray[4] = 0x0c;
991 	priv->cck_txbbgain_table[15].ccktxbb_valuearray[5] = 0x08;
992 	priv->cck_txbbgain_table[15].ccktxbb_valuearray[6] = 0x04;
993 	priv->cck_txbbgain_table[15].ccktxbb_valuearray[7] = 0x02;
994 
995 	priv->cck_txbbgain_table[16].ccktxbb_valuearray[0] = 0x16;
996 	priv->cck_txbbgain_table[16].ccktxbb_valuearray[1] = 0x15;
997 	priv->cck_txbbgain_table[16].ccktxbb_valuearray[2] = 0x12;
998 	priv->cck_txbbgain_table[16].ccktxbb_valuearray[3] = 0x0f;
999 	priv->cck_txbbgain_table[16].ccktxbb_valuearray[4] = 0x0b;
1000 	priv->cck_txbbgain_table[16].ccktxbb_valuearray[5] = 0x07;
1001 	priv->cck_txbbgain_table[16].ccktxbb_valuearray[6] = 0x04;
1002 	priv->cck_txbbgain_table[16].ccktxbb_valuearray[7] = 0x01;
1003 
1004 	priv->cck_txbbgain_table[17].ccktxbb_valuearray[0] = 0x14;
1005 	priv->cck_txbbgain_table[17].ccktxbb_valuearray[1] = 0x14;
1006 	priv->cck_txbbgain_table[17].ccktxbb_valuearray[2] = 0x11;
1007 	priv->cck_txbbgain_table[17].ccktxbb_valuearray[3] = 0x0e;
1008 	priv->cck_txbbgain_table[17].ccktxbb_valuearray[4] = 0x0b;
1009 	priv->cck_txbbgain_table[17].ccktxbb_valuearray[5] = 0x07;
1010 	priv->cck_txbbgain_table[17].ccktxbb_valuearray[6] = 0x03;
1011 	priv->cck_txbbgain_table[17].ccktxbb_valuearray[7] = 0x02;
1012 
1013 	priv->cck_txbbgain_table[18].ccktxbb_valuearray[0] = 0x13;
1014 	priv->cck_txbbgain_table[18].ccktxbb_valuearray[1] = 0x13;
1015 	priv->cck_txbbgain_table[18].ccktxbb_valuearray[2] = 0x10;
1016 	priv->cck_txbbgain_table[18].ccktxbb_valuearray[3] = 0x0d;
1017 	priv->cck_txbbgain_table[18].ccktxbb_valuearray[4] = 0x0a;
1018 	priv->cck_txbbgain_table[18].ccktxbb_valuearray[5] = 0x06;
1019 	priv->cck_txbbgain_table[18].ccktxbb_valuearray[6] = 0x03;
1020 	priv->cck_txbbgain_table[18].ccktxbb_valuearray[7] = 0x01;
1021 
1022 	priv->cck_txbbgain_table[19].ccktxbb_valuearray[0] = 0x12;
1023 	priv->cck_txbbgain_table[19].ccktxbb_valuearray[1] = 0x12;
1024 	priv->cck_txbbgain_table[19].ccktxbb_valuearray[2] = 0x0f;
1025 	priv->cck_txbbgain_table[19].ccktxbb_valuearray[3] = 0x0c;
1026 	priv->cck_txbbgain_table[19].ccktxbb_valuearray[4] = 0x09;
1027 	priv->cck_txbbgain_table[19].ccktxbb_valuearray[5] = 0x06;
1028 	priv->cck_txbbgain_table[19].ccktxbb_valuearray[6] = 0x03;
1029 	priv->cck_txbbgain_table[19].ccktxbb_valuearray[7] = 0x01;
1030 
1031 	priv->cck_txbbgain_table[20].ccktxbb_valuearray[0] = 0x11;
1032 	priv->cck_txbbgain_table[20].ccktxbb_valuearray[1] = 0x11;
1033 	priv->cck_txbbgain_table[20].ccktxbb_valuearray[2] = 0x0f;
1034 	priv->cck_txbbgain_table[20].ccktxbb_valuearray[3] = 0x0c;
1035 	priv->cck_txbbgain_table[20].ccktxbb_valuearray[4] = 0x09;
1036 	priv->cck_txbbgain_table[20].ccktxbb_valuearray[5] = 0x06;
1037 	priv->cck_txbbgain_table[20].ccktxbb_valuearray[6] = 0x03;
1038 	priv->cck_txbbgain_table[20].ccktxbb_valuearray[7] = 0x01;
1039 
1040 	priv->cck_txbbgain_table[21].ccktxbb_valuearray[0] = 0x10;
1041 	priv->cck_txbbgain_table[21].ccktxbb_valuearray[1] = 0x10;
1042 	priv->cck_txbbgain_table[21].ccktxbb_valuearray[2] = 0x0e;
1043 	priv->cck_txbbgain_table[21].ccktxbb_valuearray[3] = 0x0b;
1044 	priv->cck_txbbgain_table[21].ccktxbb_valuearray[4] = 0x08;
1045 	priv->cck_txbbgain_table[21].ccktxbb_valuearray[5] = 0x05;
1046 	priv->cck_txbbgain_table[21].ccktxbb_valuearray[6] = 0x03;
1047 	priv->cck_txbbgain_table[21].ccktxbb_valuearray[7] = 0x01;
1048 
1049 	priv->cck_txbbgain_table[22].ccktxbb_valuearray[0] = 0x0f;
1050 	priv->cck_txbbgain_table[22].ccktxbb_valuearray[1] = 0x0f;
1051 	priv->cck_txbbgain_table[22].ccktxbb_valuearray[2] = 0x0d;
1052 	priv->cck_txbbgain_table[22].ccktxbb_valuearray[3] = 0x0b;
1053 	priv->cck_txbbgain_table[22].ccktxbb_valuearray[4] = 0x08;
1054 	priv->cck_txbbgain_table[22].ccktxbb_valuearray[5] = 0x05;
1055 	priv->cck_txbbgain_table[22].ccktxbb_valuearray[6] = 0x03;
1056 	priv->cck_txbbgain_table[22].ccktxbb_valuearray[7] = 0x01;
1057 
1058 	/* ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
1059 	 * This Table is for CH14
1060 	 */
1061 	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[0] = 0x36;
1062 	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[1] = 0x35;
1063 	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[2] = 0x2e;
1064 	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[3] = 0x1b;
1065 	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[4] = 0x00;
1066 	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[5] = 0x00;
1067 	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[6] = 0x00;
1068 	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[7] = 0x00;
1069 
1070 	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[0] = 0x33;
1071 	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[1] = 0x32;
1072 	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[2] = 0x2b;
1073 	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[3] = 0x19;
1074 	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[4] = 0x00;
1075 	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[5] = 0x00;
1076 	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[6] = 0x00;
1077 	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[7] = 0x00;
1078 
1079 	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[0] = 0x30;
1080 	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[1] = 0x2f;
1081 	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[2] = 0x29;
1082 	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[3] = 0x18;
1083 	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[4] = 0x00;
1084 	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[5] = 0x00;
1085 	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[6] = 0x00;
1086 	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[7] = 0x00;
1087 
1088 	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[0] = 0x2d;
1089 	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[1] = 0x2d;
1090 	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[2] = 0x27;
1091 	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[3] = 0x17;
1092 	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[4] = 0x00;
1093 	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[5] = 0x00;
1094 	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[6] = 0x00;
1095 	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[7] = 0x00;
1096 
1097 	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[0] = 0x2b;
1098 	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[1] = 0x2a;
1099 	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[2] = 0x25;
1100 	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[3] = 0x15;
1101 	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[4] = 0x00;
1102 	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[5] = 0x00;
1103 	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[6] = 0x00;
1104 	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[7] = 0x00;
1105 
1106 	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[0] = 0x28;
1107 	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[1] = 0x28;
1108 	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[2] = 0x22;
1109 	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[3] = 0x14;
1110 	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[4] = 0x00;
1111 	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[5] = 0x00;
1112 	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[6] = 0x00;
1113 	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[7] = 0x00;
1114 
1115 	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[0] = 0x26;
1116 	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[1] = 0x25;
1117 	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[2] = 0x21;
1118 	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[3] = 0x13;
1119 	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[4] = 0x00;
1120 	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[5] = 0x00;
1121 	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[6] = 0x00;
1122 	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[7] = 0x00;
1123 
1124 	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[0] = 0x24;
1125 	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[1] = 0x23;
1126 	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[2] = 0x1f;
1127 	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[3] = 0x12;
1128 	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[4] = 0x00;
1129 	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[5] = 0x00;
1130 	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[6] = 0x00;
1131 	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[7] = 0x00;
1132 
1133 	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[0] = 0x22;
1134 	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[1] = 0x21;
1135 	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[2] = 0x1d;
1136 	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[3] = 0x11;
1137 	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[4] = 0x00;
1138 	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[5] = 0x00;
1139 	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[6] = 0x00;
1140 	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[7] = 0x00;
1141 
1142 	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[0] = 0x20;
1143 	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[1] = 0x20;
1144 	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[2] = 0x1b;
1145 	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[3] = 0x10;
1146 	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[4] = 0x00;
1147 	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[5] = 0x00;
1148 	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[6] = 0x00;
1149 	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[7] = 0x00;
1150 
1151 	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[0] = 0x1f;
1152 	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[1] = 0x1e;
1153 	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[2] = 0x1a;
1154 	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[3] = 0x0f;
1155 	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[4] = 0x00;
1156 	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[5] = 0x00;
1157 	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[6] = 0x00;
1158 	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[7] = 0x00;
1159 
1160 	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[0] = 0x1d;
1161 	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[1] = 0x1c;
1162 	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[2] = 0x18;
1163 	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[3] = 0x0e;
1164 	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[4] = 0x00;
1165 	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[5] = 0x00;
1166 	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[6] = 0x00;
1167 	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[7] = 0x00;
1168 
1169 	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[0] = 0x1b;
1170 	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[1] = 0x1a;
1171 	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[2] = 0x17;
1172 	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[3] = 0x0e;
1173 	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[4] = 0x00;
1174 	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[5] = 0x00;
1175 	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[6] = 0x00;
1176 	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[7] = 0x00;
1177 
1178 	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[0] = 0x1a;
1179 	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[1] = 0x19;
1180 	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[2] = 0x16;
1181 	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[3] = 0x0d;
1182 	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[4] = 0x00;
1183 	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[5] = 0x00;
1184 	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[6] = 0x00;
1185 	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[7] = 0x00;
1186 
1187 	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[0] = 0x18;
1188 	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[1] = 0x17;
1189 	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[2] = 0x15;
1190 	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[3] = 0x0c;
1191 	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[4] = 0x00;
1192 	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[5] = 0x00;
1193 	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[6] = 0x00;
1194 	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[7] = 0x00;
1195 
1196 	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[0] = 0x17;
1197 	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[1] = 0x16;
1198 	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[2] = 0x13;
1199 	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[3] = 0x0b;
1200 	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[4] = 0x00;
1201 	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[5] = 0x00;
1202 	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[6] = 0x00;
1203 	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[7] = 0x00;
1204 
1205 	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[0] = 0x16;
1206 	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[1] = 0x15;
1207 	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[2] = 0x12;
1208 	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[3] = 0x0b;
1209 	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[4] = 0x00;
1210 	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[5] = 0x00;
1211 	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[6] = 0x00;
1212 	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[7] = 0x00;
1213 
1214 	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[0] = 0x14;
1215 	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[1] = 0x14;
1216 	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[2] = 0x11;
1217 	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[3] = 0x0a;
1218 	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[4] = 0x00;
1219 	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[5] = 0x00;
1220 	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[6] = 0x00;
1221 	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[7] = 0x00;
1222 
1223 	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[0] = 0x13;
1224 	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[1] = 0x13;
1225 	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[2] = 0x10;
1226 	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[3] = 0x0a;
1227 	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[4] = 0x00;
1228 	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[5] = 0x00;
1229 	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[6] = 0x00;
1230 	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[7] = 0x00;
1231 
1232 	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[0] = 0x12;
1233 	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[1] = 0x12;
1234 	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[2] = 0x0f;
1235 	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[3] = 0x09;
1236 	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[4] = 0x00;
1237 	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[5] = 0x00;
1238 	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[6] = 0x00;
1239 	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[7] = 0x00;
1240 
1241 	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[0] = 0x11;
1242 	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[1] = 0x11;
1243 	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[2] = 0x0f;
1244 	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[3] = 0x09;
1245 	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[4] = 0x00;
1246 	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[5] = 0x00;
1247 	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[6] = 0x00;
1248 	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[7] = 0x00;
1249 
1250 	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[0] = 0x10;
1251 	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[1] = 0x10;
1252 	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[2] = 0x0e;
1253 	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[3] = 0x08;
1254 	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[4] = 0x00;
1255 	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[5] = 0x00;
1256 	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[6] = 0x00;
1257 	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[7] = 0x00;
1258 
1259 	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[0] = 0x0f;
1260 	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[1] = 0x0f;
1261 	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[2] = 0x0d;
1262 	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[3] = 0x08;
1263 	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[4] = 0x00;
1264 	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[5] = 0x00;
1265 	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[6] = 0x00;
1266 	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[7] = 0x00;
1267 
1268 	priv->btxpower_tracking = true;
1269 	priv->txpower_count       = 0;
1270 	priv->btxpower_trackingInit = false;
1271 }
1272 
1273 static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev)
1274 {
1275 	struct r8192_priv *priv = ieee80211_priv(dev);
1276 
1277 	/* Tx Power tracking by Thermal Meter requires Firmware R/W 3-wire. This mechanism
1278 	 * can be enabled only when Firmware R/W 3-wire is enabled. Otherwise, frequent r/w
1279 	 * 3-wire by driver causes RF to go into a wrong state.
1280 	 */
1281 	if (priv->ieee80211->FwRWRF)
1282 		priv->btxpower_tracking = true;
1283 	else
1284 		priv->btxpower_tracking = false;
1285 	priv->txpower_count       = 0;
1286 	priv->btxpower_trackingInit = false;
1287 }
1288 
1289 void dm_initialize_txpower_tracking(struct net_device *dev)
1290 {
1291 	struct r8192_priv *priv = ieee80211_priv(dev);
1292 
1293 	if (priv->bDcut)
1294 		dm_InitializeTXPowerTracking_TSSI(dev);
1295 	else
1296 		dm_InitializeTXPowerTracking_ThermalMeter(dev);
1297 } /* dm_InitializeTXPowerTracking */
1298 
1299 static void dm_CheckTXPowerTracking_TSSI(struct net_device *dev)
1300 {
1301 	struct r8192_priv *priv = ieee80211_priv(dev);
1302 	static u32 tx_power_track_counter;
1303 
1304 	if (!priv->btxpower_tracking)
1305 		return;
1306 	if ((tx_power_track_counter % 30 == 0) && (tx_power_track_counter != 0))
1307 		queue_delayed_work(priv->priv_wq, &priv->txpower_tracking_wq, 0);
1308 	tx_power_track_counter++;
1309 }
1310 
1311 static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev)
1312 {
1313 	struct r8192_priv *priv = ieee80211_priv(dev);
1314 	static u8	TM_Trigger;
1315 	/*DbgPrint("dm_CheckTXPowerTracking()\n");*/
1316 	if (!priv->btxpower_tracking)
1317 		return;
1318 	if (priv->txpower_count  <= 2) {
1319 		priv->txpower_count++;
1320 		return;
1321 	}
1322 
1323 	if (!TM_Trigger) {
1324 		/* Attention!! You have to write all 12bits of data to RF, or it may cause RF to crash
1325 		 * actually write reg0x02 bit1=0, then bit1=1.
1326 		 * DbgPrint("Trigger ThermalMeter, write RF reg0x2 = 0x4d to 0x4f\n");
1327 		 */
1328 		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
1329 		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
1330 		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
1331 		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
1332 		TM_Trigger = 1;
1333 		return;
1334 	}
1335 	/*DbgPrint("Schedule TxPowerTrackingWorkItem\n");*/
1336 	queue_delayed_work(priv->priv_wq, &priv->txpower_tracking_wq, 0);
1337 	TM_Trigger = 0;
1338 }
1339 
1340 static void dm_check_txpower_tracking(struct net_device *dev)
1341 {
1342 	struct r8192_priv *priv = ieee80211_priv(dev);
1343 	/*static u32 tx_power_track_counter = 0;*/
1344 
1345 #ifdef RTL8190P
1346 	dm_CheckTXPowerTracking_TSSI(dev);
1347 #else
1348 	if (priv->bDcut)
1349 		dm_CheckTXPowerTracking_TSSI(dev);
1350 	else
1351 		dm_CheckTXPowerTracking_ThermalMeter(dev);
1352 #endif
1353 
1354 }	/* dm_CheckTXPowerTracking */
1355 
1356 static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool  bInCH14)
1357 {
1358 	u32 TempVal;
1359 	struct r8192_priv *priv = ieee80211_priv(dev);
1360 
1361 	/* Write 0xa22 0xa23 */
1362 	TempVal = 0;
1363 	if (!bInCH14) {
1364 		/* Write 0xa22 0xa23 */
1365 		TempVal =	priv->cck_txbbgain_table[priv->cck_present_attenuation].ccktxbb_valuearray[0] +
1366 					(priv->cck_txbbgain_table[priv->cck_present_attenuation].ccktxbb_valuearray[1]<<8);
1367 
1368 		rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1369 		/* Write 0xa24 ~ 0xa27 */
1370 		TempVal =	priv->cck_txbbgain_table[priv->cck_present_attenuation].ccktxbb_valuearray[2] +
1371 					(priv->cck_txbbgain_table[priv->cck_present_attenuation].ccktxbb_valuearray[3]<<8) +
1372 					(priv->cck_txbbgain_table[priv->cck_present_attenuation].ccktxbb_valuearray[4]<<16)+
1373 					(priv->cck_txbbgain_table[priv->cck_present_attenuation].ccktxbb_valuearray[5]<<24);
1374 		rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1375 		/* Write 0xa28  0xa29 */
1376 		TempVal =	priv->cck_txbbgain_table[priv->cck_present_attenuation].ccktxbb_valuearray[6] +
1377 					(priv->cck_txbbgain_table[priv->cck_present_attenuation].ccktxbb_valuearray[7]<<8);
1378 
1379 		rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1380 	} else {
1381 		TempVal =	priv->cck_txbbgain_ch14_table[priv->cck_present_attenuation].ccktxbb_valuearray[0] +
1382 					(priv->cck_txbbgain_ch14_table[priv->cck_present_attenuation].ccktxbb_valuearray[1]<<8);
1383 
1384 		rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1385 		/* Write 0xa24 ~ 0xa27 */
1386 		TempVal =	priv->cck_txbbgain_ch14_table[priv->cck_present_attenuation].ccktxbb_valuearray[2] +
1387 					(priv->cck_txbbgain_ch14_table[priv->cck_present_attenuation].ccktxbb_valuearray[3]<<8) +
1388 					(priv->cck_txbbgain_ch14_table[priv->cck_present_attenuation].ccktxbb_valuearray[4]<<16)+
1389 					(priv->cck_txbbgain_ch14_table[priv->cck_present_attenuation].ccktxbb_valuearray[5]<<24);
1390 		rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1391 		/* Write 0xa28  0xa29 */
1392 		TempVal =	priv->cck_txbbgain_ch14_table[priv->cck_present_attenuation].ccktxbb_valuearray[6] +
1393 					(priv->cck_txbbgain_ch14_table[priv->cck_present_attenuation].ccktxbb_valuearray[7]<<8);
1394 
1395 		rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1396 	}
1397 }
1398 
1399 static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool  bInCH14)
1400 {
1401 	u32 TempVal;
1402 	struct r8192_priv *priv = ieee80211_priv(dev);
1403 
1404 	TempVal = 0;
1405 	if (!bInCH14) {
1406 		/* Write 0xa22 0xa23 */
1407 		TempVal =	CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] +
1408 					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][1]<<8);
1409 		rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1410 		RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1411 			rCCK0_TxFilter1, TempVal);
1412 		/* Write 0xa24 ~ 0xa27 */
1413 		TempVal =	CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] +
1414 					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][3]<<8) +
1415 					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][4]<<16)+
1416 					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][5]<<24);
1417 		rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1418 		RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1419 			rCCK0_TxFilter2, TempVal);
1420 		/* Write 0xa28  0xa29 */
1421 		TempVal =	CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] +
1422 					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8);
1423 
1424 		rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1425 		RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1426 			rCCK0_DebugPort, TempVal);
1427 	} else {
1428 		/*priv->CCKTxPowerAdjustCntNotCh14++;	cosa add for debug.*/
1429 		/* Write 0xa22 0xa23 */
1430 		TempVal =	CCKSwingTable_Ch14[priv->CCK_index][0] +
1431 					(CCKSwingTable_Ch14[priv->CCK_index][1]<<8);
1432 
1433 		rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1434 		RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1435 			 rCCK0_TxFilter1, TempVal);
1436 		/* Write 0xa24 ~ 0xa27 */
1437 		TempVal =	CCKSwingTable_Ch14[priv->CCK_index][2] +
1438 					(CCKSwingTable_Ch14[priv->CCK_index][3]<<8) +
1439 					(CCKSwingTable_Ch14[priv->CCK_index][4]<<16)+
1440 					(CCKSwingTable_Ch14[priv->CCK_index][5]<<24);
1441 		rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1442 		RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1443 			 rCCK0_TxFilter2, TempVal);
1444 		/* Write 0xa28  0xa29 */
1445 		TempVal =	CCKSwingTable_Ch14[priv->CCK_index][6] +
1446 					(CCKSwingTable_Ch14[priv->CCK_index][7]<<8);
1447 
1448 		rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1449 		RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1450 			 rCCK0_DebugPort, TempVal);
1451 	}
1452 }
1453 
1454 void dm_cck_txpower_adjust(struct net_device *dev, bool binch14)
1455 {	/*  dm_CCKTxPowerAdjust */
1456 	struct r8192_priv *priv = ieee80211_priv(dev);
1457 
1458 	if (priv->bDcut)
1459 		dm_CCKTxPowerAdjust_TSSI(dev, binch14);
1460 	else
1461 		dm_CCKTxPowerAdjust_ThermalMeter(dev, binch14);
1462 }
1463 
1464 #ifndef RTL8192U
1465 static void dm_txpower_reset_recovery(
1466 	struct net_device *dev
1467 )
1468 {
1469 	struct r8192_priv *priv = ieee80211_priv(dev);
1470 
1471 	RT_TRACE(COMP_POWER_TRACKING, "Start Reset Recovery ==>\n");
1472 	rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value);
1473 	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc80 is %08x\n", priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value);
1474 	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFA_txPowerTrackingIndex is %x\n", priv->rfa_txpowertrackingindex);
1475 	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);
1476 	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: CCK Attenuation is %d dB\n", priv->cck_present_attenuation);
1477 	dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
1478 
1479 	rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value);
1480 	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc90 is %08x\n", priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value);
1481 	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFC_txPowerTrackingIndex is %x\n", priv->rfc_txpowertrackingindex);
1482 	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);
1483 
1484 }	/* dm_TXPowerResetRecovery */
1485 
1486 void dm_restore_dynamic_mechanism_state(struct net_device *dev)
1487 {
1488 	struct r8192_priv *priv = ieee80211_priv(dev);
1489 	u32	reg_ratr = priv->rate_adaptive.last_ratr;
1490 
1491 	if (!priv->up) {
1492 		RT_TRACE(COMP_RATE, "<---- dm_restore_dynamic_mechanism_state(): driver is going to unload\n");
1493 		return;
1494 	}
1495 
1496 	/* Restore previous state for rate adaptive */
1497 	if (priv->rate_adaptive.rate_adaptive_disabled)
1498 		return;
1499 	/* TODO: Only 11n mode is implemented currently, */
1500 	if (!(priv->ieee80211->mode == WIRELESS_MODE_N_24G ||
1501 	      priv->ieee80211->mode == WIRELESS_MODE_N_5G))
1502 		return;
1503 
1504 	{
1505 			/* 2007/11/15 MH Copy from 8190PCI. */
1506 			u32 ratr_value;
1507 
1508 			ratr_value = reg_ratr;
1509 			if (priv->rf_type == RF_1T2R) {	/* 1T2R, Spatial Stream 2 should be disabled */
1510 				ratr_value &= ~(RATE_ALL_OFDM_2SS);
1511 				/*DbgPrint("HW_VAR_TATR_0 from 0x%x ==> 0x%x\n", ((pu4Byte)(val))[0], ratr_value);*/
1512 			}
1513 			/*DbgPrint("set HW_VAR_TATR_0 = 0x%x\n", ratr_value);*/
1514 			/*cosa PlatformEFIOWrite4Byte(Adapter, RATR0, ((pu4Byte)(val))[0]);*/
1515 			write_nic_dword(dev, RATR0, ratr_value);
1516 			write_nic_byte(dev, UFWP, 1);
1517 	}
1518 	/* Restore TX Power Tracking Index */
1519 	if (priv->btxpower_trackingInit && priv->btxpower_tracking)
1520 		dm_txpower_reset_recovery(dev);
1521 
1522 	/* Restore BB Initial Gain */
1523 	dm_bb_initialgain_restore(dev);
1524 
1525 }	/* DM_RestoreDynamicMechanismState */
1526 
1527 static void dm_bb_initialgain_restore(struct net_device *dev)
1528 {
1529 	struct r8192_priv *priv = ieee80211_priv(dev);
1530 	u32 bit_mask = 0x7f; /* Bit0~ Bit6 */
1531 
1532 	if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1533 		return;
1534 
1535 	/* Disable Initial Gain */
1536 	/*PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800);*/
1537 	rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	/* Only clear byte 1 and rewrite. */
1538 	rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bit_mask, (u32)priv->initgain_backup.xaagccore1);
1539 	rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bit_mask, (u32)priv->initgain_backup.xbagccore1);
1540 	rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, bit_mask, (u32)priv->initgain_backup.xcagccore1);
1541 	rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, bit_mask, (u32)priv->initgain_backup.xdagccore1);
1542 	bit_mask  = bMaskByte2;
1543 	rtl8192_setBBreg(dev, rCCK0_CCA, bit_mask, (u32)priv->initgain_backup.cca);
1544 
1545 	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc50 is %x\n", priv->initgain_backup.xaagccore1);
1546 	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc58 is %x\n", priv->initgain_backup.xbagccore1);
1547 	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc60 is %x\n", priv->initgain_backup.xcagccore1);
1548 	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc68 is %x\n", priv->initgain_backup.xdagccore1);
1549 	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xa0a is %x\n", priv->initgain_backup.cca);
1550 	/* Enable Initial Gain */
1551 	/*PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x100);*/
1552 	rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);	/* Only clear byte 1 and rewrite. */
1553 
1554 }	/* dm_BBInitialGainRestore */
1555 
1556 static void dm_bb_initialgain_backup(struct net_device *dev)
1557 {
1558 	struct r8192_priv *priv = ieee80211_priv(dev);
1559 	u32 bit_mask = bMaskByte0; /* Bit0~ Bit6 */
1560 
1561 	if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1562 		return;
1563 
1564 	/*PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800);*/
1565 	rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	/* Only clear byte 1 and rewrite. */
1566 	priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, bit_mask);
1567 	priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, bit_mask);
1568 	priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, bit_mask);
1569 	priv->initgain_backup.xdagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, bit_mask);
1570 	bit_mask  = bMaskByte2;
1571 	priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, bit_mask);
1572 
1573 	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc50 is %x\n", priv->initgain_backup.xaagccore1);
1574 	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc58 is %x\n", priv->initgain_backup.xbagccore1);
1575 	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc60 is %x\n", priv->initgain_backup.xcagccore1);
1576 	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc68 is %x\n", priv->initgain_backup.xdagccore1);
1577 	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xa0a is %x\n", priv->initgain_backup.cca);
1578 
1579 }   /* dm_BBInitialGainBakcup */
1580 
1581 #endif
1582 /*-----------------------------------------------------------------------------
1583  * Function:	dm_dig_init()
1584  *
1585  * Overview:	Set DIG scheme init value.
1586  *
1587  * Input:		NONE
1588  *
1589  * Output:		NONE
1590  *
1591  * Return:		NONE
1592  *
1593  * Revised History:
1594  *	When		Who		Remark
1595  *	05/15/2008	amy		Create Version 0 porting from windows code.
1596  *
1597  *---------------------------------------------------------------------------*/
1598 static void dm_dig_init(struct net_device *dev)
1599 {
1600 	struct r8192_priv *priv = ieee80211_priv(dev);
1601 	/* 2007/10/05 MH Disable DIG scheme now. Not tested. */
1602 	dm_digtable.dig_enable_flag	= true;
1603 	dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI;
1604 	dm_digtable.dig_algorithm_switch = 0;
1605 
1606 	/* 2007/10/04 MH Define init gain threshold. */
1607 	dm_digtable.dig_state		= DM_STA_DIG_MAX;
1608 	dm_digtable.dig_highpwr_state	= DM_STA_DIG_MAX;
1609 
1610 	dm_digtable.rssi_low_thresh	= DM_DIG_THRESH_LOW;
1611 	dm_digtable.rssi_high_thresh	= DM_DIG_THRESH_HIGH;
1612 
1613 	dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
1614 	dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
1615 
1616 	dm_digtable.rssi_val = 50;	/* for new dig debug rssi value */
1617 	dm_digtable.backoff_val = DM_DIG_BACKOFF;
1618 	if (priv->CustomerID == RT_CID_819x_Netcore)
1619 		dm_digtable.rx_gain_range_min = DM_DIG_MIN_NETCORE;
1620 	else
1621 		dm_digtable.rx_gain_range_min = DM_DIG_MIN;
1622 
1623 }	/* dm_dig_init */
1624 
1625 /*-----------------------------------------------------------------------------
1626  * Function:	dm_ctrl_initgain_byrssi()
1627  *
1628  * Overview:	Driver must monitor RSSI and notify firmware to change initial
1629  *				gain according to different threshold. BB team provide the
1630  *				suggested solution.
1631  *
1632  * Input:			struct net_device *dev
1633  *
1634  * Output:		NONE
1635  *
1636  * Return:		NONE
1637  *
1638  * Revised History:
1639  *	When		Who		Remark
1640  *	05/27/2008	amy		Create Version 0 porting from windows code.
1641  *---------------------------------------------------------------------------*/
1642 static void dm_ctrl_initgain_byrssi(struct net_device *dev)
1643 {
1644 	if (!dm_digtable.dig_enable_flag)
1645 		return;
1646 
1647 	if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
1648 		dm_ctrl_initgain_byrssi_by_fwfalse_alarm(dev);
1649 	else if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1650 		dm_ctrl_initgain_byrssi_by_driverrssi(dev);
1651 	/* ; */
1652 	else
1653 		return;
1654 }
1655 
1656 static void dm_ctrl_initgain_byrssi_by_driverrssi(
1657 	struct net_device *dev)
1658 {
1659 	struct r8192_priv *priv = ieee80211_priv(dev);
1660 	u8 i;
1661 	static u8	fw_dig;
1662 
1663 	if (!dm_digtable.dig_enable_flag)
1664 		return;
1665 
1666 	/*DbgPrint("Dig by Sw Rssi\n");*/
1667 	if (dm_digtable.dig_algorithm_switch)	/* if switched algorithm, we have to disable FW Dig. */
1668 		fw_dig = 0;
1669 
1670 	if (fw_dig <= 3) { /* execute several times to make sure the FW Dig is disabled */
1671 		/* FW DIG Off */
1672 		for (i = 0; i < 3; i++)
1673 			rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	/* Only clear byte 1 and rewrite. */
1674 		fw_dig++;
1675 		dm_digtable.dig_state = DM_STA_DIG_OFF;	/* fw dig off. */
1676 	}
1677 
1678 	if (priv->ieee80211->state == IEEE80211_LINKED)
1679 		dm_digtable.cur_connect_state = DIG_CONNECT;
1680 	else
1681 		dm_digtable.cur_connect_state = DIG_DISCONNECT;
1682 
1683 	/*DbgPrint("DM_DigTable.PreConnectState = %d, DM_DigTable.CurConnectState = %d\n",
1684 		DM_DigTable.PreConnectState, DM_DigTable.CurConnectState);*/
1685 
1686 	dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb;
1687 	/*DbgPrint("DM_DigTable.Rssi_val = %d\n", DM_DigTable.Rssi_val);*/
1688 	dm_initial_gain(dev);
1689 	dm_pd_th(dev);
1690 	dm_cs_ratio(dev);
1691 	if (dm_digtable.dig_algorithm_switch)
1692 		dm_digtable.dig_algorithm_switch = 0;
1693 	dm_digtable.pre_connect_state = dm_digtable.cur_connect_state;
1694 
1695 }	/* dm_CtrlInitGainByRssi */
1696 
1697 static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(
1698 	struct net_device *dev)
1699 {
1700 	struct r8192_priv *priv = ieee80211_priv(dev);
1701 	static u32 reset_cnt;
1702 	u8 i;
1703 
1704 	if (!dm_digtable.dig_enable_flag)
1705 		return;
1706 
1707 	if (dm_digtable.dig_algorithm_switch) {
1708 		dm_digtable.dig_state = DM_STA_DIG_MAX;
1709 		/* Fw DIG On. */
1710 		for (i = 0; i < 3; i++)
1711 			rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);	/* Only clear byte 1 and rewrite.*/
1712 		dm_digtable.dig_algorithm_switch = 0;
1713 	}
1714 
1715 	if (priv->ieee80211->state != IEEE80211_LINKED)
1716 		return;
1717 
1718 	/* For smooth, we can not change DIG state. */
1719 	if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) &&
1720 	    (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh))
1721 		return;
1722 
1723 	/*DbgPrint("Dig by Fw False Alarm\n");*/
1724 	/*if (DM_DigTable.Dig_State == DM_STA_DIG_OFF)*/
1725 	/*DbgPrint("DIG Check\n\r RSSI=%d LOW=%d HIGH=%d STATE=%d",
1726 	pHalData->UndecoratedSmoothedPWDB, DM_DigTable.RssiLowThresh,
1727 	DM_DigTable.RssiHighThresh, DM_DigTable.Dig_State);*/
1728 	/* 1. When RSSI decrease, We have to judge if it is smaller than a threshold
1729 	 * and then execute the step below.
1730 	 */
1731 	if (priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh) {
1732 		/* 2008/02/05 MH When we execute silent reset, the DIG PHY parameters
1733 		 * will be reset to init value. We must prevent the condition.
1734 		 */
1735 		if (dm_digtable.dig_state == DM_STA_DIG_OFF &&
1736 		    (priv->reset_count == reset_cnt)) {
1737 			return;
1738 		}
1739 		reset_cnt = priv->reset_count;
1740 
1741 		/* If DIG is off, DIG high power state must reset. */
1742 		dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
1743 		dm_digtable.dig_state = DM_STA_DIG_OFF;
1744 
1745 		/*  1.1 DIG Off. */
1746 		rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	/*  Only clear byte 1 and rewrite. */
1747 
1748 		/*  1.2 Set initial gain. */
1749 		write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x17);
1750 		write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x17);
1751 		write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x17);
1752 		write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x17);
1753 
1754 		/*  1.3 Lower PD_TH for OFDM. */
1755 		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
1756 			/* 2008/01/11 MH 40MHZ 90/92 register are not the same.
1757 			 * 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
1758 			 */
1759 			write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
1760 			/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
1761 				write_nic_byte(pAdapter, rOFDM0_RxDetector1, 0x40);
1762 			else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E)
1763 			else
1764 				PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x40);
1765 			*/
1766 		} else
1767 			write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
1768 
1769 		/* 1.4 Lower CS ratio for CCK. */
1770 		write_nic_byte(dev, 0xa0a, 0x08);
1771 
1772 		/* 1.5 Higher EDCCA. */
1773 		/*PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x325);*/
1774 		return;
1775 	}
1776 
1777 	/* 2. When RSSI increase, We have to judge if it is larger than a threshold
1778 	 * and then execute the step below.
1779 	 */
1780 	if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) {
1781 		u8 reset_flag = 0;
1782 
1783 		if (dm_digtable.dig_state == DM_STA_DIG_ON &&
1784 		    (priv->reset_count == reset_cnt)) {
1785 			dm_ctrl_initgain_byrssi_highpwr(dev);
1786 			return;
1787 		}
1788 		if (priv->reset_count != reset_cnt)
1789 			reset_flag = 1;
1790 
1791 		reset_cnt = priv->reset_count;
1792 
1793 		dm_digtable.dig_state = DM_STA_DIG_ON;
1794 		/*DbgPrint("DIG ON\n\r");*/
1795 
1796 		/* 2.1 Set initial gain.
1797 		 * 2008/02/26 MH SD3-Jerry suggest to prevent dirty environment.
1798 		 */
1799 		if (reset_flag == 1) {
1800 			write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x2c);
1801 			write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x2c);
1802 			write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x2c);
1803 			write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x2c);
1804 		} else {
1805 			write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x20);
1806 			write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x20);
1807 			write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x20);
1808 			write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x20);
1809 		}
1810 
1811 		/* 2.2 Higher PD_TH for OFDM. */
1812 		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
1813 			/* 2008/01/11 MH 40MHZ 90/92 register are not the same.
1814 			 * 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
1815 			 */
1816 			write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
1817 			/*
1818 			else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
1819 				write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
1820 			else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E)
1821 			else
1822 				PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x42);
1823 			*/
1824 		} else
1825 			write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
1826 
1827 		/* 2.3 Higher CS ratio for CCK. */
1828 		write_nic_byte(dev, 0xa0a, 0xcd);
1829 
1830 		/* 2.4 Lower EDCCA.
1831 		 * 2008/01/11 MH 90/92 series are the same.
1832 		 */
1833 		/*PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x346);*/
1834 
1835 		/* 2.5 DIG On. */
1836 		rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);	/*  Only clear byte 1 and rewrite. */
1837 	}
1838 
1839 	dm_ctrl_initgain_byrssi_highpwr(dev);
1840 
1841 }	/* dm_CtrlInitGainByRssi */
1842 
1843 /*-----------------------------------------------------------------------------
1844  * Function:	dm_ctrl_initgain_byrssi_highpwr()
1845  *
1846  * Overview:
1847  *
1848  * Input:		NONE
1849  *
1850  * Output:		NONE
1851  *
1852  * Return:		NONE
1853  *
1854  * Revised History:
1855  *	When		Who		Remark
1856  *	05/28/2008	amy		Create Version 0 porting from windows code.
1857  *
1858  *---------------------------------------------------------------------------*/
1859 static void dm_ctrl_initgain_byrssi_highpwr(
1860 	struct net_device *dev)
1861 {
1862 	struct r8192_priv *priv = ieee80211_priv(dev);
1863 	static u32 reset_cnt_highpwr;
1864 
1865 	/*  For smooth, we can not change high power DIG state in the range. */
1866 	if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_high_power_lowthresh) &&
1867 		(priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_highthresh))
1868 		return;
1869 
1870 	/* 3. When RSSI >75% or <70%, it is a high power issue. We have to judge if
1871 	 *    it is larger than a threshold and then execute the step below.
1872 	 *
1873 	 * 2008/02/05 MH SD3-Jerry Modify PD_TH for high power issue.
1874 	 */
1875 	if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh) {
1876 		if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON &&
1877 		    (priv->reset_count == reset_cnt_highpwr))
1878 			return;
1879 		dm_digtable.dig_highpwr_state = DM_STA_DIG_ON;
1880 
1881 		/* 3.1 Higher PD_TH for OFDM for high power state. */
1882 		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
1883 			write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
1884 
1885 			/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
1886 				write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
1887 			*/
1888 
1889 		} else
1890 			write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
1891 	} else {
1892 		if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF &&
1893 		    (priv->reset_count == reset_cnt_highpwr))
1894 			return;
1895 		dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF;
1896 
1897 		if (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_lowthresh &&
1898 			 priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) {
1899 			/*  3.2 Recover PD_TH for OFDM for normal power region. */
1900 			if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
1901 				write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
1902 				/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
1903 					write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
1904 				*/
1905 
1906 			} else
1907 				write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
1908 		}
1909 	}
1910 
1911 	reset_cnt_highpwr = priv->reset_count;
1912 
1913 }	/* dm_CtrlInitGainByRssiHighPwr */
1914 
1915 static void dm_initial_gain(
1916 	struct net_device *dev)
1917 {
1918 	struct r8192_priv *priv = ieee80211_priv(dev);
1919 	u8					initial_gain = 0;
1920 	static u8				initialized, force_write;
1921 	static u32			reset_cnt;
1922 	u8				tmp;
1923 
1924 	if (dm_digtable.dig_algorithm_switch) {
1925 		initialized = 0;
1926 		reset_cnt = 0;
1927 	}
1928 
1929 	if (dm_digtable.pre_connect_state == dm_digtable.cur_connect_state) {
1930 		if (dm_digtable.cur_connect_state == DIG_CONNECT) {
1931 			if ((dm_digtable.rssi_val + 10 - dm_digtable.backoff_val) > DM_DIG_MAX)
1932 				dm_digtable.cur_ig_value = DM_DIG_MAX;
1933 			else if ((dm_digtable.rssi_val+10-dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min)
1934 				dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_min;
1935 			else
1936 				dm_digtable.cur_ig_value = dm_digtable.rssi_val+10-dm_digtable.backoff_val;
1937 		} else {	/* current state is disconnected */
1938 			if (dm_digtable.cur_ig_value == 0)
1939 				dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
1940 			else
1941 				dm_digtable.cur_ig_value = dm_digtable.pre_ig_value;
1942 		}
1943 	} else { /*  disconnected -> connected or connected -> disconnected */
1944 		dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
1945 		dm_digtable.pre_ig_value = 0;
1946 	}
1947 	/*DbgPrint("DM_DigTable.CurIGValue = 0x%x, DM_DigTable.PreIGValue = 0x%x\n", DM_DigTable.CurIGValue, DM_DigTable.PreIGValue);*/
1948 
1949 	/* if silent reset happened, we should rewrite the values back */
1950 	if (priv->reset_count != reset_cnt) {
1951 		force_write = 1;
1952 		reset_cnt = priv->reset_count;
1953 	}
1954 
1955 	read_nic_byte(dev, rOFDM0_XAAGCCore1, &tmp);
1956 	if (dm_digtable.pre_ig_value != tmp)
1957 		force_write = 1;
1958 
1959 	{
1960 		if ((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value)
1961 			|| !initialized || force_write) {
1962 			initial_gain = (u8)dm_digtable.cur_ig_value;
1963 			/*DbgPrint("Write initial gain = 0x%x\n", initial_gain);*/
1964 			/*  Set initial gain. */
1965 			write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain);
1966 			write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain);
1967 			write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain);
1968 			write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain);
1969 			dm_digtable.pre_ig_value = dm_digtable.cur_ig_value;
1970 			initialized = 1;
1971 			force_write = 0;
1972 		}
1973 	}
1974 }
1975 
1976 static void dm_pd_th(
1977 	struct net_device *dev)
1978 {
1979 	struct r8192_priv *priv = ieee80211_priv(dev);
1980 	static u8				initialized, force_write;
1981 	static u32			reset_cnt;
1982 
1983 	if (dm_digtable.dig_algorithm_switch) {
1984 		initialized = 0;
1985 		reset_cnt = 0;
1986 	}
1987 
1988 	if (dm_digtable.pre_connect_state == dm_digtable.cur_connect_state) {
1989 		if (dm_digtable.cur_connect_state == DIG_CONNECT) {
1990 			if (dm_digtable.rssi_val >= dm_digtable.rssi_high_power_highthresh)
1991 				dm_digtable.curpd_thstate = DIG_PD_AT_HIGH_POWER;
1992 			else if (dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh)
1993 				dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
1994 			else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) &&
1995 					(dm_digtable.rssi_val < dm_digtable.rssi_high_power_lowthresh))
1996 				dm_digtable.curpd_thstate = DIG_PD_AT_NORMAL_POWER;
1997 			else
1998 				dm_digtable.curpd_thstate = dm_digtable.prepd_thstate;
1999 		} else {
2000 			dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
2001 		}
2002 	} else { /* disconnected -> connected or connected -> disconnected */
2003 		dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
2004 	}
2005 
2006 	/*  if silent reset happened, we should rewrite the values back */
2007 	if (priv->reset_count != reset_cnt) {
2008 		force_write = 1;
2009 		reset_cnt = priv->reset_count;
2010 	}
2011 
2012 	{
2013 		if ((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) ||
2014 		    (initialized <= 3) || force_write) {
2015 			/*DbgPrint("Write PD_TH state = %d\n", DM_DigTable.CurPD_THState);*/
2016 			if (dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER) {
2017 				/*  Lower PD_TH for OFDM. */
2018 				if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
2019 					/* 2008/01/11 MH 40MHZ 90/92 register are not the same.
2020 					 * 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
2021 					 */
2022 					write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
2023 					/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2024 						write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
2025 					*/
2026 				} else
2027 					write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2028 			} else if (dm_digtable.curpd_thstate == DIG_PD_AT_NORMAL_POWER) {
2029 				/* Higher PD_TH for OFDM. */
2030 				if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
2031 					/* 2008/01/11 MH 40MHZ 90/92 register are not the same.
2032 					 * 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
2033 					 */
2034 					write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
2035 					/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2036 						write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2037 					*/
2038 				} else
2039 					write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
2040 			} else if (dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER) {
2041 				/* Higher PD_TH for OFDM for high power state. */
2042 				if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
2043 					write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
2044 					/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2045 						write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
2046 					*/
2047 				} else
2048 					write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
2049 			}
2050 			dm_digtable.prepd_thstate = dm_digtable.curpd_thstate;
2051 			if (initialized <= 3)
2052 				initialized++;
2053 			force_write = 0;
2054 		}
2055 	}
2056 }
2057 
2058 static	void dm_cs_ratio(
2059 	struct net_device *dev)
2060 {
2061 	struct r8192_priv *priv = ieee80211_priv(dev);
2062 	static u8				initialized, force_write;
2063 	static u32			reset_cnt;
2064 
2065 	if (dm_digtable.dig_algorithm_switch) {
2066 		initialized = 0;
2067 		reset_cnt = 0;
2068 	}
2069 
2070 	if (dm_digtable.pre_connect_state == dm_digtable.cur_connect_state) {
2071 		if (dm_digtable.cur_connect_state == DIG_CONNECT) {
2072 			if (dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh)
2073 				dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
2074 			else if (dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh)
2075 				dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER;
2076 			else
2077 				dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state;
2078 		} else {
2079 			dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
2080 		}
2081 	} else	/* disconnected -> connected or connected -> disconnected */
2082 		dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
2083 
2084 	/* if silent reset happened, we should rewrite the values back */
2085 	if (priv->reset_count != reset_cnt) {
2086 		force_write = 1;
2087 		reset_cnt = priv->reset_count;
2088 	}
2089 
2090 	{
2091 		if ((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
2092 		    !initialized || force_write) {
2093 			/*DbgPrint("Write CS_ratio state = %d\n", DM_DigTable.CurCS_ratioState);*/
2094 			if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER) {
2095 				/*  Lower CS ratio for CCK. */
2096 				write_nic_byte(dev, 0xa0a, 0x08);
2097 			} else if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER) {
2098 				/*  Higher CS ratio for CCK. */
2099 				write_nic_byte(dev, 0xa0a, 0xcd);
2100 			}
2101 			dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state;
2102 			initialized = 1;
2103 			force_write = 0;
2104 		}
2105 	}
2106 }
2107 
2108 void dm_init_edca_turbo(struct net_device *dev)
2109 {
2110 	struct r8192_priv *priv = ieee80211_priv(dev);
2111 
2112 	priv->bcurrent_turbo_EDCA = false;
2113 	priv->ieee80211->bis_any_nonbepkts = false;
2114 	priv->bis_cur_rdlstate = false;
2115 }	/* dm_init_edca_turbo */
2116 
2117 static void dm_check_edca_turbo(
2118 	struct net_device *dev)
2119 {
2120 	struct r8192_priv *priv = ieee80211_priv(dev);
2121 	PRT_HIGH_THROUGHPUT	pHTInfo = priv->ieee80211->pHTInfo;
2122 	/*PSTA_QOS			pStaQos = pMgntInfo->pStaQos;*/
2123 
2124 	/* Keep past Tx/Rx packet count for RT-to-RT EDCA turbo. */
2125 	static unsigned long			lastTxOkCnt;
2126 	static unsigned long			lastRxOkCnt;
2127 	unsigned long				curTxOkCnt = 0;
2128 	unsigned long				curRxOkCnt = 0;
2129 
2130 	/* Do not be Turbo if it's under WiFi config and Qos Enabled, because the EDCA parameters
2131 	 * should follow the settings from QAP. By Bruce, 2007-12-07.
2132 	 */
2133 	if (priv->ieee80211->state != IEEE80211_LINKED)
2134 		goto dm_CheckEdcaTurbo_EXIT;
2135 	/* We do not turn on EDCA turbo mode for some AP that has IOT issue */
2136 	if (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO)
2137 		goto dm_CheckEdcaTurbo_EXIT;
2138 
2139 	/*printk("========>%s():bis_any_nonbepkts is %d\n", __func__, priv->bis_any_nonbepkts);*/
2140 	/* Check the status for current condition. */
2141 	if (!priv->ieee80211->bis_any_nonbepkts) {
2142 		curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
2143 		curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
2144 		/* For RT-AP, we needs to turn it on when Rx>Tx */
2145 		if (curRxOkCnt > 4*curTxOkCnt) {
2146 			/*printk("%s():curRxOkCnt > 4*curTxOkCnt\n");*/
2147 			if (!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) {
2148 				write_nic_dword(dev, EDCAPARA_BE, edca_setting_DL[pHTInfo->IOTPeer]);
2149 				priv->bis_cur_rdlstate = true;
2150 			}
2151 		} else {
2152 			/*printk("%s():curRxOkCnt < 4*curTxOkCnt\n");*/
2153 			if (priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) {
2154 				write_nic_dword(dev, EDCAPARA_BE, edca_setting_UL[pHTInfo->IOTPeer]);
2155 				priv->bis_cur_rdlstate = false;
2156 			}
2157 		}
2158 
2159 		priv->bcurrent_turbo_EDCA = true;
2160 	} else {
2161 		/* Turn Off EDCA turbo here.
2162 		 * Restore original EDCA according to the declaration of AP.
2163 		 */
2164 		if (priv->bcurrent_turbo_EDCA) {
2165 			u8	u1bAIFS;
2166 			u32	u4bAcParam, op_limit, cw_max, cw_min;
2167 
2168 			struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
2169 			u8 mode = priv->ieee80211->mode;
2170 
2171 			/*  For Each time updating EDCA parameter, reset EDCA turbo mode status. */
2172 			dm_init_edca_turbo(dev);
2173 
2174 			u1bAIFS = qos_parameters->aifs[0] * ((mode & (IEEE_G | IEEE_N_24G)) ? 9 : 20) + aSifsTime;
2175 
2176 			op_limit = (u32)le16_to_cpu(qos_parameters->tx_op_limit[0]);
2177 			cw_max   = (u32)le16_to_cpu(qos_parameters->cw_max[0]);
2178 			cw_min   = (u32)le16_to_cpu(qos_parameters->cw_min[0]);
2179 
2180 			op_limit <<= AC_PARAM_TXOP_LIMIT_OFFSET;
2181 			cw_max   <<= AC_PARAM_ECW_MAX_OFFSET;
2182 			cw_min   <<= AC_PARAM_ECW_MIN_OFFSET;
2183 			u1bAIFS  <<= AC_PARAM_AIFS_OFFSET;
2184 
2185 			u4bAcParam = op_limit | cw_max | cw_min | u1bAIFS;
2186 			cpu_to_le32s(&u4bAcParam);
2187 
2188 			write_nic_dword(dev, EDCAPARA_BE, u4bAcParam);
2189 
2190 			/* Check ACM bit.
2191 			 * If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13.
2192 			 */
2193 			{
2194 				/*  TODO:  Modified this part and try to set acm control in only 1 IO processing!! */
2195 
2196 				struct aci_aifsn *pAciAifsn = (struct aci_aifsn *)&(qos_parameters->aifs[0]);
2197 				u8		AcmCtrl;
2198 
2199 				read_nic_byte(dev, AcmHwCtrl, &AcmCtrl);
2200 
2201 				if (pAciAifsn->acm) { /*  acm bit is 1. */
2202 					AcmCtrl |= AcmHw_BeqEn;
2203 				} else {	/* ACM bit is 0. */
2204 					AcmCtrl &= (~AcmHw_BeqEn);
2205 				}
2206 
2207 				RT_TRACE(COMP_QOS, "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl);
2208 				write_nic_byte(dev, AcmHwCtrl, AcmCtrl);
2209 			}
2210 			priv->bcurrent_turbo_EDCA = false;
2211 		}
2212 	}
2213 
2214 dm_CheckEdcaTurbo_EXIT:
2215 	/* Set variables for next time. */
2216 	priv->ieee80211->bis_any_nonbepkts = false;
2217 	lastTxOkCnt = priv->stats.txbytesunicast;
2218 	lastRxOkCnt = priv->stats.rxbytesunicast;
2219 }	/* dm_CheckEdcaTurbo */
2220 
2221 static void dm_init_ctstoself(struct net_device *dev)
2222 {
2223 	struct r8192_priv *priv = ieee80211_priv(dev);
2224 
2225 	priv->ieee80211->bCTSToSelfEnable = true;
2226 	priv->ieee80211->CTSToSelfTH = CTS_TO_SELF_TH_VAL;
2227 }
2228 
2229 static void dm_ctstoself(struct net_device *dev)
2230 {
2231 	struct r8192_priv *priv = ieee80211_priv(dev);
2232 	PRT_HIGH_THROUGHPUT	pHTInfo = priv->ieee80211->pHTInfo;
2233 	static unsigned long				lastTxOkCnt;
2234 	static unsigned long				lastRxOkCnt;
2235 	unsigned long						curTxOkCnt = 0;
2236 	unsigned long						curRxOkCnt = 0;
2237 
2238 	if (!priv->ieee80211->bCTSToSelfEnable) {
2239 		pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
2240 		return;
2241 	}
2242 	/* 1. Uplink
2243 	 * 2. Linksys350/Linksys300N
2244 	 * 3. <50 disable, >55 enable
2245 	 */
2246 
2247 	if (pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) {
2248 		curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
2249 		curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
2250 		if (curRxOkCnt > 4*curTxOkCnt) { /* downlink, disable CTS to self */
2251 			pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
2252 			/*DbgPrint("dm_CTSToSelf() ==> CTS to self disabled -- downlink\n");*/
2253 		} else { /* uplink */
2254 			pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
2255 		}
2256 
2257 		lastTxOkCnt = priv->stats.txbytesunicast;
2258 		lastRxOkCnt = priv->stats.rxbytesunicast;
2259 	}
2260 }
2261 
2262 /*-----------------------------------------------------------------------------
2263  * Function:	dm_check_pbc_gpio()
2264  *
2265  * Overview:	Check if PBC button is pressed.
2266  *
2267  * Input:		NONE
2268  *
2269  * Output:		NONE
2270  *
2271  * Return:		NONE
2272  *
2273  * Revised History:
2274  *	When		Who		Remark
2275  *	05/28/2008	amy	Create Version 0 porting from windows code.
2276  *
2277  *---------------------------------------------------------------------------*/
2278 static	void	dm_check_pbc_gpio(struct net_device *dev)
2279 {
2280 	struct r8192_priv *priv = ieee80211_priv(dev);
2281 	u8 tmp1byte;
2282 
2283 	read_nic_byte(dev, GPI, &tmp1byte);
2284 	if (tmp1byte == 0xff)
2285 		return;
2286 
2287 	if (tmp1byte & BIT(6) || tmp1byte & BIT(0)) {
2288 		/* Here we only set bPbcPressed to TRUE
2289 		 * After trigger PBC, the variable will be set to FALSE
2290 		 */
2291 		RT_TRACE(COMP_IO, "CheckPbcGPIO - PBC is pressed\n");
2292 		priv->bpbc_pressed = true;
2293 	}
2294 }
2295 
2296 /*-----------------------------------------------------------------------------
2297  * Function:	DM_RFPathCheckWorkItemCallBack()
2298  *
2299  * Overview:	Check if Current RF RX path is enabled
2300  *
2301  * Input:		NONE
2302  *
2303  * Output:		NONE
2304  *
2305  * Return:		NONE
2306  *
2307  * Revised History:
2308  *	When		Who		Remark
2309  *	01/30/2008	MHC		Create Version 0.
2310  *
2311  *---------------------------------------------------------------------------*/
2312 void dm_rf_pathcheck_workitemcallback(struct work_struct *work)
2313 {
2314 	struct delayed_work *dwork = to_delayed_work(work);
2315 	struct r8192_priv *priv = container_of(dwork, struct r8192_priv, rfpath_check_wq);
2316 	struct net_device *dev = priv->ieee80211->dev;
2317 	/*bool bactually_set = false;*/
2318 	u8 rfpath = 0, i;
2319 
2320 	/* 2008/01/30 MH After discussing with SD3 Jerry, 0xc04/0xd04 register will
2321 	 * always be the same. We only read 0xc04 now.
2322 	 */
2323 	read_nic_byte(dev, 0xc04, &rfpath);
2324 
2325 	/* Check Bit 0-3, it means if RF A-D is enabled. */
2326 	for (i = 0; i < RF90_PATH_MAX; i++) {
2327 		if (rfpath & (0x01<<i))
2328 			priv->brfpath_rxenable[i] = true;
2329 		else
2330 			priv->brfpath_rxenable[i] = false;
2331 	}
2332 
2333 	dm_rxpath_sel_byrssi(dev);
2334 }	/* DM_RFPathCheckWorkItemCallBack */
2335 
2336 static void dm_init_rxpath_selection(struct net_device *dev)
2337 {
2338 	u8 i;
2339 	struct r8192_priv *priv = ieee80211_priv(dev);
2340 
2341 	if (priv->CustomerID == RT_CID_819x_Netcore)
2342 		DM_RxPathSelTable.cck_method = CCK_RX_VERSION_2;
2343 	else
2344 		DM_RxPathSelTable.cck_method = CCK_RX_VERSION_1;
2345 	DM_RxPathSelTable.disabled_rf = 0;
2346 	for (i = 0; i < 4; i++) {
2347 		DM_RxPathSelTable.rf_rssi[i] = 50;
2348 		DM_RxPathSelTable.cck_pwdb_sta[i] = -64;
2349 		DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
2350 	}
2351 }
2352 
2353 static void dm_rxpath_sel_byrssi(struct net_device *dev)
2354 {
2355 	struct r8192_priv *priv = ieee80211_priv(dev);
2356 	u8				i, max_rssi_index = 0, min_rssi_index = 0, sec_rssi_index = 0, rf_num = 0;
2357 	u8				tmp_max_rssi = 0, tmp_min_rssi = 0, tmp_sec_rssi = 0;
2358 	u8				cck_default_Rx = 0x2;  /* RF-C */
2359 	u8				cck_optional_Rx = 0x3; /* RF-D */
2360 	long				tmp_cck_max_pwdb = 0, tmp_cck_min_pwdb = 0, tmp_cck_sec_pwdb = 0;
2361 	u8				cck_rx_ver2_max_index = 0, cck_rx_ver2_min_index = 0, cck_rx_ver2_sec_index = 0;
2362 	u8				cur_rf_rssi;
2363 	long				cur_cck_pwdb;
2364 	static u8			disabled_rf_cnt, cck_Rx_Path_initialized;
2365 	u8				update_cck_rx_path;
2366 
2367 	if (priv->rf_type != RF_2T4R)
2368 		return;
2369 
2370 	if (!cck_Rx_Path_initialized) {
2371 		read_nic_byte(dev, 0xa07, &DM_RxPathSelTable.cck_rx_path);
2372 		DM_RxPathSelTable.cck_rx_path &= 0xf;
2373 		cck_Rx_Path_initialized = 1;
2374 	}
2375 
2376 	read_nic_byte(dev, 0xc04, &DM_RxPathSelTable.disabled_rf);
2377 	DM_RxPathSelTable.disabled_rf = ~DM_RxPathSelTable.disabled_rf & 0xf;
2378 
2379 	if (priv->ieee80211->mode == WIRELESS_MODE_B) {
2380 		DM_RxPathSelTable.cck_method = CCK_RX_VERSION_2;	/* pure B mode, fixed cck version2 */
2381 		/*DbgPrint("Pure B mode, use cck rx version2\n");*/
2382 	}
2383 
2384 	/* decide max/sec/min rssi index */
2385 	for (i = 0; i < RF90_PATH_MAX; i++) {
2386 		DM_RxPathSelTable.rf_rssi[i] = priv->stats.rx_rssi_percentage[i];
2387 
2388 		if (priv->brfpath_rxenable[i]) {
2389 			rf_num++;
2390 			cur_rf_rssi = DM_RxPathSelTable.rf_rssi[i];
2391 
2392 			if (rf_num == 1) { /* find first enabled rf path and the rssi values */
2393 				/* initialize, set all rssi index to the same one */
2394 				max_rssi_index = min_rssi_index = sec_rssi_index = i;
2395 				tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi;
2396 			} else if (rf_num == 2) { /* we pick up the max index first, and let sec and min to be the same one */
2397 				if (cur_rf_rssi >= tmp_max_rssi) {
2398 					tmp_max_rssi = cur_rf_rssi;
2399 					max_rssi_index = i;
2400 				} else {
2401 					tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi;
2402 					sec_rssi_index = min_rssi_index = i;
2403 				}
2404 			} else {
2405 				if (cur_rf_rssi > tmp_max_rssi) {
2406 					tmp_sec_rssi = tmp_max_rssi;
2407 					sec_rssi_index = max_rssi_index;
2408 					tmp_max_rssi = cur_rf_rssi;
2409 					max_rssi_index = i;
2410 				} else if (cur_rf_rssi == tmp_max_rssi) {	/* let sec and min point to the different index */
2411 					tmp_sec_rssi = cur_rf_rssi;
2412 					sec_rssi_index = i;
2413 				} else if ((cur_rf_rssi < tmp_max_rssi) && (cur_rf_rssi > tmp_sec_rssi)) {
2414 					tmp_sec_rssi = cur_rf_rssi;
2415 					sec_rssi_index = i;
2416 				} else if (cur_rf_rssi == tmp_sec_rssi) {
2417 					if (tmp_sec_rssi == tmp_min_rssi) {
2418 						/* let sec and min point to the different index */
2419 						tmp_sec_rssi = cur_rf_rssi;
2420 						sec_rssi_index = i;
2421 					} else {
2422 						/* This case we don't need to set any index */
2423 					}
2424 				} else if ((cur_rf_rssi < tmp_sec_rssi) && (cur_rf_rssi > tmp_min_rssi)) {
2425 					/* This case we don't need to set any index */
2426 				} else if (cur_rf_rssi == tmp_min_rssi) {
2427 					if (tmp_sec_rssi == tmp_min_rssi) {
2428 						/* let sec and min point to the different index */
2429 						tmp_min_rssi = cur_rf_rssi;
2430 						min_rssi_index = i;
2431 					} else {
2432 						/* This case we don't need to set any index */
2433 					}
2434 				} else if (cur_rf_rssi < tmp_min_rssi) {
2435 					tmp_min_rssi = cur_rf_rssi;
2436 					min_rssi_index = i;
2437 				}
2438 			}
2439 		}
2440 	}
2441 
2442 	rf_num = 0;
2443 	/* decide max/sec/min cck pwdb index */
2444 	if (DM_RxPathSelTable.cck_method == CCK_RX_VERSION_2) {
2445 		for (i = 0; i < RF90_PATH_MAX; i++) {
2446 			if (priv->brfpath_rxenable[i]) {
2447 				rf_num++;
2448 				cur_cck_pwdb =  DM_RxPathSelTable.cck_pwdb_sta[i];
2449 
2450 				if (rf_num == 1) {	/* find first enabled rf path and the rssi values */
2451 					/* initialize, set all rssi index to the same one */
2452 					cck_rx_ver2_max_index = cck_rx_ver2_min_index = cck_rx_ver2_sec_index = i;
2453 					tmp_cck_max_pwdb = tmp_cck_min_pwdb = tmp_cck_sec_pwdb = cur_cck_pwdb;
2454 				} else if (rf_num == 2) {	/* we pick up the max index first, and let sec and min to be the same one */
2455 					if (cur_cck_pwdb >= tmp_cck_max_pwdb) {
2456 						tmp_cck_max_pwdb = cur_cck_pwdb;
2457 						cck_rx_ver2_max_index = i;
2458 					} else {
2459 						tmp_cck_sec_pwdb = tmp_cck_min_pwdb = cur_cck_pwdb;
2460 						cck_rx_ver2_sec_index = cck_rx_ver2_min_index = i;
2461 					}
2462 				} else {
2463 					if (cur_cck_pwdb > tmp_cck_max_pwdb) {
2464 						tmp_cck_sec_pwdb = tmp_cck_max_pwdb;
2465 						cck_rx_ver2_sec_index = cck_rx_ver2_max_index;
2466 						tmp_cck_max_pwdb = cur_cck_pwdb;
2467 						cck_rx_ver2_max_index = i;
2468 					} else if (cur_cck_pwdb == tmp_cck_max_pwdb) {
2469 						/* let sec and min point to the different index */
2470 						tmp_cck_sec_pwdb = cur_cck_pwdb;
2471 						cck_rx_ver2_sec_index = i;
2472 					} else if ((cur_cck_pwdb < tmp_cck_max_pwdb) && (cur_cck_pwdb > tmp_cck_sec_pwdb)) {
2473 						tmp_cck_sec_pwdb = cur_cck_pwdb;
2474 						cck_rx_ver2_sec_index = i;
2475 					} else if (cur_cck_pwdb == tmp_cck_sec_pwdb && tmp_cck_sec_pwdb == tmp_cck_min_pwdb) {
2476 						/* let sec and min point to the different index */
2477 						tmp_cck_sec_pwdb = cur_cck_pwdb;
2478 						cck_rx_ver2_sec_index = i;
2479 						/* otherwise we don't need to set any index */
2480 					} else if ((cur_cck_pwdb < tmp_cck_sec_pwdb) && (cur_cck_pwdb > tmp_cck_min_pwdb)) {
2481 						/*  This case we don't need to set any index */
2482 					} else if (cur_cck_pwdb == tmp_cck_min_pwdb && tmp_cck_sec_pwdb == tmp_cck_min_pwdb) {
2483 						/*  let sec and min point to the different index */
2484 						tmp_cck_min_pwdb = cur_cck_pwdb;
2485 						cck_rx_ver2_min_index = i;
2486 						/* otherwise we don't need to set any index */
2487 					} else if (cur_cck_pwdb < tmp_cck_min_pwdb) {
2488 						tmp_cck_min_pwdb = cur_cck_pwdb;
2489 						cck_rx_ver2_min_index = i;
2490 					}
2491 				}
2492 			}
2493 		}
2494 	}
2495 
2496 	/* Set CCK Rx path
2497 	 * reg0xA07[3:2]=cck default rx path, reg0xa07[1:0]=cck optional rx path.
2498 	 */
2499 	update_cck_rx_path = 0;
2500 	if (DM_RxPathSelTable.cck_method == CCK_RX_VERSION_2) {
2501 		cck_default_Rx = cck_rx_ver2_max_index;
2502 		cck_optional_Rx = cck_rx_ver2_sec_index;
2503 		if (tmp_cck_max_pwdb != -64)
2504 			update_cck_rx_path = 1;
2505 	}
2506 
2507 	if (tmp_min_rssi < RX_PATH_SELECTION_SS_TH_LOW && disabled_rf_cnt < 2) {
2508 		if ((tmp_max_rssi - tmp_min_rssi) >= RX_PATH_SELECTION_DIFF_TH) {
2509 			/* record the enabled rssi threshold */
2510 			DM_RxPathSelTable.rf_enable_rssi_th[min_rssi_index] = tmp_max_rssi+5;
2511 			/* disable the BB Rx path, OFDM */
2512 			rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<min_rssi_index, 0x0);	/* 0xc04[3:0] */
2513 			rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<min_rssi_index, 0x0);	/* 0xd04[3:0] */
2514 			disabled_rf_cnt++;
2515 		}
2516 		if (DM_RxPathSelTable.cck_method == CCK_RX_VERSION_1) {
2517 			cck_default_Rx = max_rssi_index;
2518 			cck_optional_Rx = sec_rssi_index;
2519 			if (tmp_max_rssi)
2520 				update_cck_rx_path = 1;
2521 		}
2522 	}
2523 
2524 	if (update_cck_rx_path) {
2525 		DM_RxPathSelTable.cck_rx_path = (cck_default_Rx<<2)|(cck_optional_Rx);
2526 		rtl8192_setBBreg(dev, rCCK0_AFESetting, 0x0f000000, DM_RxPathSelTable.cck_rx_path);
2527 	}
2528 
2529 	if (DM_RxPathSelTable.disabled_rf) {
2530 		for (i = 0; i < 4; i++) {
2531 			if ((DM_RxPathSelTable.disabled_rf >> i) & 0x1) {	/* disabled rf */
2532 				if (tmp_max_rssi >= DM_RxPathSelTable.rf_enable_rssi_th[i]) {
2533 					/* enable the BB Rx path */
2534 					/*DbgPrint("RF-%d is enabled.\n", 0x1<<i);*/
2535 					rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<i, 0x1);	/* 0xc04[3:0] */
2536 					rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<i, 0x1);	/* 0xd04[3:0] */
2537 					DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
2538 					disabled_rf_cnt--;
2539 				}
2540 			}
2541 		}
2542 	}
2543 }
2544 
2545 /*-----------------------------------------------------------------------------
2546  * Function:	dm_check_rx_path_selection()
2547  *
2548  * Overview:	Call a workitem to check current RXRF path and Rx Path selection by RSSI.
2549  *
2550  * Input:		NONE
2551  *
2552  * Output:		NONE
2553  *
2554  * Return:		NONE
2555  *
2556  * Revised History:
2557  *	When		Who		Remark
2558  *	05/28/2008	amy		Create Version 0 porting from windows code.
2559  *
2560  *---------------------------------------------------------------------------*/
2561 static void dm_check_rx_path_selection(struct net_device *dev)
2562 {
2563 	struct r8192_priv *priv = ieee80211_priv(dev);
2564 
2565 	queue_delayed_work(priv->priv_wq, &priv->rfpath_check_wq, 0);
2566 }	/* dm_CheckRxRFPath */
2567 
2568 static void dm_init_fsync(struct net_device *dev)
2569 {
2570 	struct r8192_priv *priv = ieee80211_priv(dev);
2571 
2572 	priv->ieee80211->fsync_time_interval = 500;
2573 	priv->ieee80211->fsync_rate_bitmap = 0x0f000800;
2574 	priv->ieee80211->fsync_rssi_threshold = 30;
2575 	priv->ieee80211->bfsync_enable = false;
2576 	priv->ieee80211->fsync_multiple_timeinterval = 3;
2577 	priv->ieee80211->fsync_firstdiff_ratethreshold = 100;
2578 	priv->ieee80211->fsync_seconddiff_ratethreshold = 200;
2579 	priv->ieee80211->fsync_state = Default_Fsync;
2580 	priv->framesyncMonitor = 1;	/* current default 0xc38 monitor on */
2581 	timer_setup(&priv->fsync_timer, dm_fsync_timer_callback, 0);
2582 }
2583 
2584 static void dm_deInit_fsync(struct net_device *dev)
2585 {
2586 	struct r8192_priv *priv = ieee80211_priv(dev);
2587 
2588 	del_timer_sync(&priv->fsync_timer);
2589 }
2590 
2591 void dm_fsync_timer_callback(struct timer_list *t)
2592 {
2593 	struct r8192_priv *priv = from_timer(priv, t, fsync_timer);
2594 	struct net_device *dev = priv->ieee80211->dev;
2595 	u32 rate_index, rate_count = 0, rate_count_diff = 0;
2596 	bool		bSwitchFromCountDiff = false;
2597 	bool		bDoubleTimeInterval = false;
2598 
2599 	if (priv->ieee80211->state == IEEE80211_LINKED &&
2600 	    priv->ieee80211->bfsync_enable &&
2601 		(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC)) {
2602 		/* Count rate 54, MCS [7], [12, 13, 14, 15] */
2603 		u32 rate_bitmap;
2604 
2605 		for (rate_index = 0; rate_index <= 27; rate_index++) {
2606 			rate_bitmap  = 1 << rate_index;
2607 			if (priv->ieee80211->fsync_rate_bitmap &  rate_bitmap)
2608 				rate_count += priv->stats.received_rate_histogram[1][rate_index];
2609 		}
2610 
2611 		if (rate_count < priv->rate_record)
2612 			rate_count_diff = 0xffffffff - rate_count + priv->rate_record;
2613 		else
2614 			rate_count_diff = rate_count - priv->rate_record;
2615 		if (rate_count_diff < priv->rateCountDiffRecord) {
2616 			u32 DiffNum = priv->rateCountDiffRecord - rate_count_diff;
2617 			/* Continue count */
2618 			if (DiffNum >= priv->ieee80211->fsync_seconddiff_ratethreshold)
2619 				priv->ContinueDiffCount++;
2620 			else
2621 				priv->ContinueDiffCount = 0;
2622 
2623 			/* Continue count over */
2624 			if (priv->ContinueDiffCount >= 2) {
2625 				bSwitchFromCountDiff = true;
2626 				priv->ContinueDiffCount = 0;
2627 			}
2628 		} else {
2629 			/* Stop the continued count */
2630 			priv->ContinueDiffCount = 0;
2631 		}
2632 
2633 		/* If Count diff <= FsyncRateCountThreshold */
2634 		if (rate_count_diff <= priv->ieee80211->fsync_firstdiff_ratethreshold) {
2635 			bSwitchFromCountDiff = true;
2636 			priv->ContinueDiffCount = 0;
2637 		}
2638 		priv->rate_record = rate_count;
2639 		priv->rateCountDiffRecord = rate_count_diff;
2640 		RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff, priv->bswitch_fsync);
2641 		/* if we never receive those mcs rate and rssi > 30 % then switch fsyn */
2642 		if (priv->undecorated_smoothed_pwdb > priv->ieee80211->fsync_rssi_threshold && bSwitchFromCountDiff) {
2643 			bDoubleTimeInterval = true;
2644 			priv->bswitch_fsync = !priv->bswitch_fsync;
2645 			if (priv->bswitch_fsync) {
2646 				write_nic_byte(dev, 0xC36, 0x1c);
2647 				write_nic_byte(dev, 0xC3e, 0x90);
2648 			} else {
2649 				write_nic_byte(dev, 0xC36, 0x5c);
2650 				write_nic_byte(dev, 0xC3e, 0x96);
2651 			}
2652 		} else if (priv->undecorated_smoothed_pwdb <= priv->ieee80211->fsync_rssi_threshold) {
2653 			if (priv->bswitch_fsync) {
2654 				priv->bswitch_fsync  = false;
2655 				write_nic_byte(dev, 0xC36, 0x5c);
2656 				write_nic_byte(dev, 0xC3e, 0x96);
2657 			}
2658 		}
2659 		if (bDoubleTimeInterval) {
2660 			if (timer_pending(&priv->fsync_timer))
2661 				del_timer_sync(&priv->fsync_timer);
2662 			priv->fsync_timer.expires = jiffies +
2663 				msecs_to_jiffies(priv->ieee80211->fsync_time_interval*priv->ieee80211->fsync_multiple_timeinterval);
2664 			add_timer(&priv->fsync_timer);
2665 		} else {
2666 			if (timer_pending(&priv->fsync_timer))
2667 				del_timer_sync(&priv->fsync_timer);
2668 			priv->fsync_timer.expires = jiffies +
2669 				msecs_to_jiffies(priv->ieee80211->fsync_time_interval);
2670 			add_timer(&priv->fsync_timer);
2671 		}
2672 	} else {
2673 		/* Let Register return to default value; */
2674 		if (priv->bswitch_fsync) {
2675 			priv->bswitch_fsync  = false;
2676 			write_nic_byte(dev, 0xC36, 0x5c);
2677 			write_nic_byte(dev, 0xC3e, 0x96);
2678 		}
2679 		priv->ContinueDiffCount = 0;
2680 		write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
2681 	}
2682 	RT_TRACE(COMP_HALDM, "ContinueDiffCount %d\n", priv->ContinueDiffCount);
2683 	RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff, priv->bswitch_fsync);
2684 }
2685 
2686 static void dm_StartHWFsync(struct net_device *dev)
2687 {
2688 	RT_TRACE(COMP_HALDM, "%s\n", __func__);
2689 	write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cf);
2690 	write_nic_byte(dev, 0xc3b, 0x41);
2691 }
2692 
2693 static void dm_EndSWFsync(struct net_device *dev)
2694 {
2695 	struct r8192_priv *priv = ieee80211_priv(dev);
2696 
2697 	RT_TRACE(COMP_HALDM, "%s\n", __func__);
2698 	del_timer_sync(&(priv->fsync_timer));
2699 
2700 	/* Let Register return to default value; */
2701 	if (priv->bswitch_fsync) {
2702 		priv->bswitch_fsync  = false;
2703 
2704 		write_nic_byte(dev, 0xC36, 0x5c);
2705 
2706 		write_nic_byte(dev, 0xC3e, 0x96);
2707 	}
2708 
2709 	priv->ContinueDiffCount = 0;
2710 	write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
2711 }
2712 
2713 static void dm_StartSWFsync(struct net_device *dev)
2714 {
2715 	struct r8192_priv *priv = ieee80211_priv(dev);
2716 	u32			rateIndex;
2717 	u32			rateBitmap;
2718 
2719 	RT_TRACE(COMP_HALDM, "%s\n", __func__);
2720 	/* Initial rate record to zero, start to record. */
2721 	priv->rate_record = 0;
2722 	/* Initialize continue diff count to zero, start to record. */
2723 	priv->ContinueDiffCount = 0;
2724 	priv->rateCountDiffRecord = 0;
2725 	priv->bswitch_fsync  = false;
2726 
2727 	if (priv->ieee80211->mode == WIRELESS_MODE_N_24G) {
2728 		priv->ieee80211->fsync_firstdiff_ratethreshold = 600;
2729 		priv->ieee80211->fsync_seconddiff_ratethreshold = 0xffff;
2730 	} else {
2731 		priv->ieee80211->fsync_firstdiff_ratethreshold = 200;
2732 		priv->ieee80211->fsync_seconddiff_ratethreshold = 200;
2733 	}
2734 	for (rateIndex = 0; rateIndex <= 27; rateIndex++) {
2735 		rateBitmap = 1 << rateIndex;
2736 		if (priv->ieee80211->fsync_rate_bitmap &  rateBitmap)
2737 			priv->rate_record += priv->stats.received_rate_histogram[1][rateIndex];
2738 	}
2739 	if (timer_pending(&priv->fsync_timer))
2740 		del_timer_sync(&priv->fsync_timer);
2741 	priv->fsync_timer.expires = jiffies +
2742 			msecs_to_jiffies(priv->ieee80211->fsync_time_interval);
2743 	add_timer(&priv->fsync_timer);
2744 
2745 	write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cd);
2746 }
2747 
2748 static void dm_EndHWFsync(struct net_device *dev)
2749 {
2750 	RT_TRACE(COMP_HALDM, "%s\n", __func__);
2751 	write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
2752 	write_nic_byte(dev, 0xc3b, 0x49);
2753 }
2754 
2755 void dm_check_fsync(struct net_device *dev)
2756 {
2757 #define	RegC38_Default				0
2758 #define	RegC38_NonFsync_Other_AP		1
2759 #define	RegC38_Fsync_AP_BCM			2
2760 	struct r8192_priv *priv = ieee80211_priv(dev);
2761 	/*u32			framesyncC34;*/
2762 	static u8		reg_c38_State = RegC38_Default;
2763 	static u32	reset_cnt;
2764 
2765 	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);
2766 	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);
2767 
2768 	if (priv->ieee80211->state == IEEE80211_LINKED &&
2769 		(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC)) {
2770 		if (priv->ieee80211->bfsync_enable == 0) {
2771 			switch (priv->ieee80211->fsync_state) {
2772 			case Default_Fsync:
2773 				dm_StartHWFsync(dev);
2774 				priv->ieee80211->fsync_state = HW_Fsync;
2775 				break;
2776 			case SW_Fsync:
2777 				dm_EndSWFsync(dev);
2778 				dm_StartHWFsync(dev);
2779 				priv->ieee80211->fsync_state = HW_Fsync;
2780 				break;
2781 			case HW_Fsync:
2782 			default:
2783 				break;
2784 			}
2785 		} else {
2786 			switch (priv->ieee80211->fsync_state) {
2787 			case Default_Fsync:
2788 				dm_StartSWFsync(dev);
2789 				priv->ieee80211->fsync_state = SW_Fsync;
2790 				break;
2791 			case HW_Fsync:
2792 				dm_EndHWFsync(dev);
2793 				dm_StartSWFsync(dev);
2794 				priv->ieee80211->fsync_state = SW_Fsync;
2795 				break;
2796 			case SW_Fsync:
2797 			default:
2798 				break;
2799 			}
2800 		}
2801 		if (priv->framesyncMonitor) {
2802 			if (reg_c38_State != RegC38_Fsync_AP_BCM) {
2803 				/* For broadcom AP we write different default value */
2804 				write_nic_byte(dev, rOFDM0_RxDetector3, 0x95);
2805 
2806 				reg_c38_State = RegC38_Fsync_AP_BCM;
2807 			}
2808 		}
2809 	} else {
2810 		switch (priv->ieee80211->fsync_state) {
2811 		case HW_Fsync:
2812 			dm_EndHWFsync(dev);
2813 			priv->ieee80211->fsync_state = Default_Fsync;
2814 			break;
2815 		case SW_Fsync:
2816 			dm_EndSWFsync(dev);
2817 			priv->ieee80211->fsync_state = Default_Fsync;
2818 			break;
2819 		case Default_Fsync:
2820 		default:
2821 			break;
2822 		}
2823 
2824 		if (priv->framesyncMonitor) {
2825 			if (priv->ieee80211->state == IEEE80211_LINKED) {
2826 				if (priv->undecorated_smoothed_pwdb <= REG_C38_TH) {
2827 					if (reg_c38_State != RegC38_NonFsync_Other_AP) {
2828 						write_nic_byte(dev, rOFDM0_RxDetector3, 0x90);
2829 
2830 						reg_c38_State = RegC38_NonFsync_Other_AP;
2831 					}
2832 				} else if (priv->undecorated_smoothed_pwdb >= (REG_C38_TH + 5)) {
2833 					if (reg_c38_State) {
2834 						write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
2835 						reg_c38_State = RegC38_Default;
2836 						/*DbgPrint("Fsync is idle, rssi>=40, write 0xc38 = 0x%x\n", pHalData->framesync);*/
2837 					}
2838 				}
2839 			} else {
2840 				if (reg_c38_State) {
2841 					write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
2842 					reg_c38_State = RegC38_Default;
2843 					/*DbgPrint("Fsync is idle, not connected, write 0xc38 = 0x%x\n", pHalData->framesync);*/
2844 				}
2845 			}
2846 		}
2847 	}
2848 	if (priv->framesyncMonitor) {
2849 		if (priv->reset_count != reset_cnt) { /* After silent reset, the reg_c38_State will be returned to default value */
2850 			write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
2851 			reg_c38_State = RegC38_Default;
2852 			reset_cnt = priv->reset_count;
2853 			/*DbgPrint("reg_c38_State = 0 for silent reset.\n");*/
2854 		}
2855 	} else {
2856 		if (reg_c38_State) {
2857 			write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
2858 			reg_c38_State = RegC38_Default;
2859 			/*DbgPrint("framesync no monitor, write 0xc38 = 0x%x\n", pHalData->framesync);*/
2860 		}
2861 	}
2862 }
2863 
2864 /*-----------------------------------------------------------------------------
2865  * Function:	dm_shadow_init()
2866  *
2867  * Overview:	Store all NIC MAC/BB register content.
2868  *
2869  * Input:		NONE
2870  *
2871  * Output:		NONE
2872  *
2873  * Return:		NONE
2874  *
2875  * Revised History:
2876  *	When		Who		Remark
2877  *	05/29/2008	amy		Create Version 0 porting from windows code.
2878  *
2879  *---------------------------------------------------------------------------
2880  */
2881 void dm_shadow_init(struct net_device *dev)
2882 {
2883 	u8	page;
2884 	u16	offset;
2885 
2886 	for (page = 0; page < 5; page++)
2887 		for (offset = 0; offset < 256; offset++) {
2888 			read_nic_byte(dev, offset + page * 256, &dm_shadow[page][offset]);
2889 			/*DbgPrint("P-%d/O-%02x=%02x\r\n", page, offset, DM_Shadow[page][offset]);*/
2890 		}
2891 
2892 	for (page = 8; page < 11; page++)
2893 		for (offset = 0; offset < 256; offset++)
2894 			read_nic_byte(dev, offset + page * 256, &dm_shadow[page][offset]);
2895 
2896 	for (page = 12; page < 15; page++)
2897 		for (offset = 0; offset < 256; offset++)
2898 			read_nic_byte(dev, offset + page * 256, &dm_shadow[page][offset]);
2899 
2900 }   /* dm_shadow_init */
2901 
2902 /*---------------------------Define function prototype------------------------*/
2903 /*-----------------------------------------------------------------------------
2904  * Function:	DM_DynamicTxPower()
2905  *
2906  * Overview:	Detect Signal strength to control TX Registry
2907 			Tx Power Control For Near/Far Range
2908  *
2909  * Input:		NONE
2910  *
2911  * Output:		NONE
2912  *
2913  * Return:		NONE
2914  *
2915  * Revised History:
2916  *	When		Who		Remark
2917  *	03/06/2008	Jacken	Create Version 0.
2918  *
2919  *---------------------------------------------------------------------------
2920  */
2921 static void dm_init_dynamic_txpower(struct net_device *dev)
2922 {
2923 	struct r8192_priv *priv = ieee80211_priv(dev);
2924 
2925 	/* Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code. */
2926 	priv->ieee80211->bdynamic_txpower_enable = true;    /* Default to enable Tx Power Control */
2927 	priv->bLastDTPFlag_High = false;
2928 	priv->bLastDTPFlag_Low = false;
2929 	priv->bDynamicTxHighPower = false;
2930 	priv->bDynamicTxLowPower = false;
2931 }
2932 
2933 static void dm_dynamic_txpower(struct net_device *dev)
2934 {
2935 	struct r8192_priv *priv = ieee80211_priv(dev);
2936 	unsigned int txhipower_threshold = 0;
2937 	unsigned int txlowpower_threshold = 0;
2938 
2939 	if (!priv->ieee80211->bdynamic_txpower_enable) {
2940 		priv->bDynamicTxHighPower = false;
2941 		priv->bDynamicTxLowPower = false;
2942 		return;
2943 	}
2944 	/*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);*/
2945 	if ((priv->ieee80211->current_network.atheros_cap_exist) && (priv->ieee80211->mode == IEEE_G)) {
2946 		txhipower_threshold = TX_POWER_ATHEROAP_THRESH_HIGH;
2947 		txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW;
2948 	} else {
2949 		txhipower_threshold = TX_POWER_NEAR_FIELD_THRESH_HIGH;
2950 		txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW;
2951 	}
2952 
2953 	/*printk("=======>%s(): txhipower_threshold is %d, txlowpower_threshold is %d\n", __func__, txhipower_threshold, txlowpower_threshold);*/
2954 	RT_TRACE(COMP_TXAGC, "priv->undecorated_smoothed_pwdb = %ld\n", priv->undecorated_smoothed_pwdb);
2955 
2956 	if (priv->ieee80211->state == IEEE80211_LINKED) {
2957 		if (priv->undecorated_smoothed_pwdb >= txhipower_threshold) {
2958 			priv->bDynamicTxHighPower = true;
2959 			priv->bDynamicTxLowPower = false;
2960 		} else {
2961 			/* high power state check */
2962 			if (priv->undecorated_smoothed_pwdb < txlowpower_threshold && priv->bDynamicTxHighPower)
2963 				priv->bDynamicTxHighPower = false;
2964 
2965 			/* low power state check */
2966 			if (priv->undecorated_smoothed_pwdb < 35)
2967 				priv->bDynamicTxLowPower = true;
2968 			else if (priv->undecorated_smoothed_pwdb >= 40)
2969 				priv->bDynamicTxLowPower = false;
2970 		}
2971 	} else {
2972 		/*pHalData->bTXPowerCtrlforNearFarRange = !pHalData->bTXPowerCtrlforNearFarRange;*/
2973 		priv->bDynamicTxHighPower = false;
2974 		priv->bDynamicTxLowPower = false;
2975 	}
2976 
2977 	if ((priv->bDynamicTxHighPower != priv->bLastDTPFlag_High) ||
2978 		(priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low)) {
2979 		RT_TRACE(COMP_TXAGC, "SetTxPowerLevel8190()  channel = %d\n", priv->ieee80211->current_network.channel);
2980 
2981 #if  defined(RTL8190P) || defined(RTL8192E)
2982 		SetTxPowerLevel8190(Adapter, pHalData->CurrentChannel);
2983 #endif
2984 
2985 		rtl8192_phy_setTxPower(dev, priv->ieee80211->current_network.channel);
2986 		/*pHalData->bStartTxCtrlByTPCNFR = FALSE;    Clear th flag of Set TX Power from Sitesurvey*/
2987 	}
2988 	priv->bLastDTPFlag_High = priv->bDynamicTxHighPower;
2989 	priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower;
2990 
2991 }	/* dm_dynamic_txpower */
2992 
2993 /* added by vivi, for read tx rate and retrycount */
2994 static void dm_check_txrateandretrycount(struct net_device *dev)
2995 {
2996 	struct r8192_priv *priv = ieee80211_priv(dev);
2997 	struct ieee80211_device *ieee = priv->ieee80211;
2998 	/* for 11n tx rate */
2999 	/*priv->stats.CurrentShowTxate = read_nic_byte(dev, CURRENT_TX_RATE_REG);*/
3000 	read_nic_byte(dev, CURRENT_TX_RATE_REG, &ieee->softmac_stats.CurrentShowTxate);
3001 	/*printk("=============>tx_rate_reg:%x\n", ieee->softmac_stats.CurrentShowTxate);*/
3002 	/* for initial tx rate */
3003 	/*priv->stats.last_packet_rate = read_nic_byte(dev, INITIAL_TX_RATE_REG);*/
3004 	read_nic_byte(dev, INITIAL_TX_RATE_REG, &ieee->softmac_stats.last_packet_rate);
3005 	/* for tx tx retry count */
3006 	/*priv->stats.txretrycount = read_nic_dword(dev, TX_RETRY_COUNT_REG);*/
3007 	read_nic_dword(dev, TX_RETRY_COUNT_REG, &ieee->softmac_stats.txretrycount);
3008 }
3009 
3010 static void dm_send_rssi_tofw(struct net_device *dev)
3011 {
3012 	struct r8192_priv *priv = ieee80211_priv(dev);
3013 
3014 	/* If we test chariot, we should stop the TX command ?
3015 	 * Because 92E will always silent reset when we send tx command. We use register
3016 	 * 0x1e0(byte) to notify driver.
3017 	 */
3018 	write_nic_byte(dev, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb);
3019 }
3020 
3021 /*---------------------------Define function prototype------------------------*/
3022