[go: nahoru, domu]

1/******************************************************************************
2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
3 *
4 * This program is distributed in the hope that it will be useful, but WITHOUT
5 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
7 * more details.
8 *
9 * You should have received a copy of the GNU General Public License along with
10 * this program; if not, write to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
12 *
13 * The full GNU General Public License is included in this distribution in the
14 * file called LICENSE.
15 *
16 * Contact Information:
17 * wlanfae <wlanfae@realtek.com>
18******************************************************************************/
19#include "rtl_core.h"
20#include "rtl_dm.h"
21#include "r8192E_hw.h"
22#include "r8192E_phy.h"
23#include "r8192E_phyreg.h"
24#include "r8190P_rtl8256.h"
25#include "r8192E_cmdpkt.h"
26
27/*---------------------------Define Local Constant---------------------------*/
28static u32 edca_setting_DL[HT_IOT_PEER_MAX] = {
29	0x5e4322,
30	0x5e4322,
31	0x5ea44f,
32	0x5e4322,
33	0x604322,
34	0xa44f,
35	0x5e4322,
36	0x5e4332
37};
38
39static u32 edca_setting_DL_GMode[HT_IOT_PEER_MAX] = {
40	0x5e4322,
41	0x5e4322,
42	0x5e4322,
43	0x5e4322,
44	0x604322,
45	0xa44f,
46	0x5e4322,
47	0x5e4322
48};
49
50static u32 edca_setting_UL[HT_IOT_PEER_MAX] = {
51	0x5e4322,
52	0xa44f,
53	0x5ea44f,
54	0x5e4322,
55	0x604322,
56	0x5e4322,
57	0x5e4322,
58	0x5e4332
59};
60
61#define RTK_UL_EDCA 0xa44f
62#define RTK_DL_EDCA 0x5e4322
63/*---------------------------Define Local Constant---------------------------*/
64
65
66/*------------------------Define global variable-----------------------------*/
67struct dig_t dm_digtable;
68u8 dm_shadow[16][256] = {
69	{0}
70};
71
72struct drx_path_sel DM_RxPathSelTable;
73/*------------------------Define global variable-----------------------------*/
74
75
76/*------------------------Define local variable------------------------------*/
77/*------------------------Define local variable------------------------------*/
78
79
80
81/*---------------------Define local function prototype-----------------------*/
82static	void	dm_check_rate_adaptive(struct net_device *dev);
83
84static	void	dm_init_bandwidth_autoswitch(struct net_device *dev);
85static	void	dm_bandwidth_autoswitch(struct net_device *dev);
86
87
88static	void	dm_check_txpower_tracking(struct net_device *dev);
89
90
91
92
93
94static	void	dm_bb_initialgain_restore(struct net_device *dev);
95
96
97static	void	dm_bb_initialgain_backup(struct net_device *dev);
98
99static	void dm_dig_init(struct net_device *dev);
100static	void dm_ctrl_initgain_byrssi(struct net_device *dev);
101static	void dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev);
102static	void dm_ctrl_initgain_byrssi_by_driverrssi(struct net_device *dev);
103static	void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(struct net_device *dev);
104static	void dm_initial_gain(struct net_device *dev);
105static	void dm_pd_th(struct net_device *dev);
106static	void dm_cs_ratio(struct net_device *dev);
107
108static	void dm_init_ctstoself(struct net_device *dev);
109static	void dm_Init_WA_Broadcom_IOT(struct net_device *dev);
110
111static	void	dm_check_edca_turbo(struct net_device *dev);
112
113static	void dm_check_pbc_gpio(struct net_device *dev);
114
115
116static	void dm_check_rx_path_selection(struct net_device *dev);
117static	void dm_init_rxpath_selection(struct net_device *dev);
118static	void dm_rxpath_sel_byrssi(struct net_device *dev);
119
120
121static void dm_init_fsync(struct net_device *dev);
122static void dm_deInit_fsync(struct net_device *dev);
123
124static	void dm_check_txrateandretrycount(struct net_device *dev);
125static  void dm_check_ac_dc_power(struct net_device *dev);
126
127/*---------------------Define local function prototype-----------------------*/
128
129static	void	dm_init_dynamic_txpower(struct net_device *dev);
130static	void	dm_dynamic_txpower(struct net_device *dev);
131
132
133static	void dm_send_rssi_tofw(struct net_device *dev);
134static	void	dm_ctstoself(struct net_device *dev);
135/*---------------------------Define function prototype------------------------*/
136
137void init_hal_dm(struct net_device *dev)
138{
139	struct r8192_priv *priv = rtllib_priv(dev);
140
141	priv->DM_Type = DM_Type_ByDriver;
142
143	priv->undecorated_smoothed_pwdb = -1;
144
145	dm_init_dynamic_txpower(dev);
146
147	init_rate_adaptive(dev);
148
149	dm_dig_init(dev);
150	dm_init_edca_turbo(dev);
151	dm_init_bandwidth_autoswitch(dev);
152	dm_init_fsync(dev);
153	dm_init_rxpath_selection(dev);
154	dm_init_ctstoself(dev);
155	if (IS_HARDWARE_TYPE_8192SE(dev))
156		dm_Init_WA_Broadcom_IOT(dev);
157
158	INIT_DELAYED_WORK_RSL(&priv->gpio_change_rf_wq, (void *)dm_CheckRfCtrlGPIO, dev);
159}
160
161void deinit_hal_dm(struct net_device *dev)
162{
163
164	dm_deInit_fsync(dev);
165
166}
167
168void hal_dm_watchdog(struct net_device *dev)
169{
170	struct r8192_priv *priv = rtllib_priv(dev);
171
172	if (priv->being_init_adapter)
173		return;
174
175	dm_check_ac_dc_power(dev);
176
177	dm_check_pbc_gpio(dev);
178	dm_check_txrateandretrycount(dev);
179	dm_check_edca_turbo(dev);
180
181	dm_check_rate_adaptive(dev);
182	dm_dynamic_txpower(dev);
183	dm_check_txpower_tracking(dev);
184
185	dm_ctrl_initgain_byrssi(dev);
186	dm_bandwidth_autoswitch(dev);
187
188	dm_check_rx_path_selection(dev);
189	dm_check_fsync(dev);
190
191	dm_send_rssi_tofw(dev);
192	dm_ctstoself(dev);
193}
194
195static void dm_check_ac_dc_power(struct net_device *dev)
196{
197	struct r8192_priv *priv = rtllib_priv(dev);
198	static char *ac_dc_check_script_path = "/etc/acpi/wireless-rtl-ac-dc-power.sh";
199	char *argv[] = {ac_dc_check_script_path, DRV_NAME, NULL};
200	static char *envp[] = {"HOME=/",
201			"TERM=linux",
202			"PATH=/usr/bin:/bin",
203			 NULL};
204
205	if (priv->ResetProgress == RESET_TYPE_SILENT) {
206		RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF),
207			 "GPIOChangeRFWorkItemCallBack(): Silent Reset!!!!!!!\n");
208		return;
209	}
210
211	if (priv->rtllib->state != RTLLIB_LINKED)
212		return;
213	call_usermodehelper(ac_dc_check_script_path, argv, envp, UMH_WAIT_PROC);
214
215	return;
216};
217
218
219void init_rate_adaptive(struct net_device *dev)
220{
221
222	struct r8192_priv *priv = rtllib_priv(dev);
223	struct rate_adaptive *pra = (struct rate_adaptive *)&priv->rate_adaptive;
224
225	pra->ratr_state = DM_RATR_STA_MAX;
226	pra->high2low_rssi_thresh_for_ra = RateAdaptiveTH_High;
227	pra->low2high_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M+5;
228	pra->low2high_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M+5;
229
230	pra->high_rssi_thresh_for_ra = RateAdaptiveTH_High+5;
231	pra->low_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M;
232	pra->low_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M;
233
234	if (priv->CustomerID == RT_CID_819x_Netcore)
235		pra->ping_rssi_enable = 1;
236	else
237		pra->ping_rssi_enable = 0;
238	pra->ping_rssi_thresh_for_ra = 15;
239
240
241	if (priv->rf_type == RF_2T4R) {
242		pra->upper_rssi_threshold_ratr		=	0x8f0f0000;
243		pra->middle_rssi_threshold_ratr		=	0x8f0ff000;
244		pra->low_rssi_threshold_ratr		=	0x8f0ff001;
245		pra->low_rssi_threshold_ratr_40M	=	0x8f0ff005;
246		pra->low_rssi_threshold_ratr_20M	=	0x8f0ff001;
247		pra->ping_rssi_ratr	=	0x0000000d;
248	} else if (priv->rf_type == RF_1T2R) {
249		pra->upper_rssi_threshold_ratr		=	0x000fc000;
250		pra->middle_rssi_threshold_ratr		=	0x000ff000;
251		pra->low_rssi_threshold_ratr		=	0x000ff001;
252		pra->low_rssi_threshold_ratr_40M	=	0x000ff005;
253		pra->low_rssi_threshold_ratr_20M	=	0x000ff001;
254		pra->ping_rssi_ratr	=	0x0000000d;
255	}
256
257}
258
259
260static void dm_check_rate_adaptive(struct net_device *dev)
261{
262	struct r8192_priv *priv = rtllib_priv(dev);
263	struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo;
264	struct rate_adaptive *pra = (struct rate_adaptive *)&priv->rate_adaptive;
265	u32 currentRATR, targetRATR = 0;
266	u32 LowRSSIThreshForRA = 0, HighRSSIThreshForRA = 0;
267	bool bshort_gi_enabled = false;
268	static u8 ping_rssi_state;
269
270	if (IS_NIC_DOWN(priv)) {
271		RT_TRACE(COMP_RATE, "<---- dm_check_rate_adaptive(): driver is going to unload\n");
272		return;
273	}
274
275	if (pra->rate_adaptive_disabled)
276		return;
277
278	if (!(priv->rtllib->mode == WIRELESS_MODE_N_24G ||
279	    priv->rtllib->mode == WIRELESS_MODE_N_5G))
280		return;
281
282	if (priv->rtllib->state == RTLLIB_LINKED) {
283
284		bshort_gi_enabled = (pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI40MHz) ||
285			(!pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI20MHz);
286
287
288		pra->upper_rssi_threshold_ratr =
289				(pra->upper_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled) ? BIT31 : 0);
290
291		pra->middle_rssi_threshold_ratr =
292				(pra->middle_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled) ? BIT31 : 0);
293
294		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
295			pra->low_rssi_threshold_ratr =
296				(pra->low_rssi_threshold_ratr_40M & (~BIT31)) | ((bshort_gi_enabled) ? BIT31 : 0);
297		} else {
298			pra->low_rssi_threshold_ratr =
299			(pra->low_rssi_threshold_ratr_20M & (~BIT31)) | ((bshort_gi_enabled) ? BIT31 : 0);
300		}
301		pra->ping_rssi_ratr =
302				(pra->ping_rssi_ratr & (~BIT31)) | ((bshort_gi_enabled) ? BIT31 : 0);
303
304		if (pra->ratr_state == DM_RATR_STA_HIGH) {
305			HighRSSIThreshForRA	= pra->high2low_rssi_thresh_for_ra;
306			LowRSSIThreshForRA	= (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ?
307					(pra->low_rssi_thresh_for_ra40M) : (pra->low_rssi_thresh_for_ra20M);
308		} else if (pra->ratr_state == DM_RATR_STA_LOW) {
309			HighRSSIThreshForRA	= pra->high_rssi_thresh_for_ra;
310			LowRSSIThreshForRA	= (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ?
311					(pra->low2high_rssi_thresh_for_ra40M) : (pra->low2high_rssi_thresh_for_ra20M);
312		} else {
313			HighRSSIThreshForRA	= pra->high_rssi_thresh_for_ra;
314			LowRSSIThreshForRA	= (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ?
315					(pra->low_rssi_thresh_for_ra40M) : (pra->low_rssi_thresh_for_ra20M);
316		}
317
318		if (priv->undecorated_smoothed_pwdb >= (long)HighRSSIThreshForRA) {
319			pra->ratr_state = DM_RATR_STA_HIGH;
320			targetRATR = pra->upper_rssi_threshold_ratr;
321		} else if (priv->undecorated_smoothed_pwdb >= (long)LowRSSIThreshForRA) {
322			pra->ratr_state = DM_RATR_STA_MIDDLE;
323			targetRATR = pra->middle_rssi_threshold_ratr;
324		} else {
325			pra->ratr_state = DM_RATR_STA_LOW;
326			targetRATR = pra->low_rssi_threshold_ratr;
327		}
328
329		if (pra->ping_rssi_enable) {
330			if (priv->undecorated_smoothed_pwdb < (long)(pra->ping_rssi_thresh_for_ra+5)) {
331				if ((priv->undecorated_smoothed_pwdb < (long)pra->ping_rssi_thresh_for_ra) ||
332				    ping_rssi_state) {
333					pra->ratr_state = DM_RATR_STA_LOW;
334					targetRATR = pra->ping_rssi_ratr;
335					ping_rssi_state = 1;
336				}
337			} else {
338				ping_rssi_state = 0;
339			}
340		}
341
342		if (priv->rtllib->GetHalfNmodeSupportByAPsHandler(dev))
343			targetRATR &=  0xf00fffff;
344
345		currentRATR = read_nic_dword(dev, RATR0);
346		if (targetRATR !=  currentRATR) {
347			u32 ratr_value;
348
349			ratr_value = targetRATR;
350			RT_TRACE(COMP_RATE,
351				 "currentRATR = %x, targetRATR = %x\n",
352				 currentRATR, targetRATR);
353			if (priv->rf_type == RF_1T2R)
354				ratr_value &= ~(RATE_ALL_OFDM_2SS);
355			write_nic_dword(dev, RATR0, ratr_value);
356			write_nic_byte(dev, UFWP, 1);
357
358			pra->last_ratr = targetRATR;
359		}
360
361	} else {
362		pra->ratr_state = DM_RATR_STA_MAX;
363	}
364}
365
366static void dm_init_bandwidth_autoswitch(struct net_device *dev)
367{
368	struct r8192_priv *priv = rtllib_priv(dev);
369
370	priv->rtllib->bandwidth_auto_switch.threshold_20Mhzto40Mhz = BW_AUTO_SWITCH_LOW_HIGH;
371	priv->rtllib->bandwidth_auto_switch.threshold_40Mhzto20Mhz = BW_AUTO_SWITCH_HIGH_LOW;
372	priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz = false;
373	priv->rtllib->bandwidth_auto_switch.bautoswitch_enable = false;
374}
375
376static void dm_bandwidth_autoswitch(struct net_device *dev)
377{
378	struct r8192_priv *priv = rtllib_priv(dev);
379
380	if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 ||
381	   !priv->rtllib->bandwidth_auto_switch.bautoswitch_enable) {
382		return;
383	} else {
384		if (priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz == false) {
385			if (priv->undecorated_smoothed_pwdb <=
386			    priv->rtllib->bandwidth_auto_switch.threshold_40Mhzto20Mhz)
387				priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz = true;
388		} else {
389			if (priv->undecorated_smoothed_pwdb >=
390			    priv->rtllib->bandwidth_auto_switch.threshold_20Mhzto40Mhz)
391				priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz = false;
392
393		}
394	}
395}
396
397static u32 OFDMSwingTable[OFDM_Table_Length] = {
398	0x7f8001fe,
399	0x71c001c7,
400	0x65400195,
401	0x5a400169,
402	0x50800142,
403	0x47c0011f,
404	0x40000100,
405	0x390000e4,
406	0x32c000cb,
407	0x2d4000b5,
408	0x288000a2,
409	0x24000090,
410	0x20000080,
411	0x1c800072,
412	0x19800066,
413	0x26c0005b,
414	0x24400051,
415	0x12000048,
416	0x10000040
417};
418
419static u8	CCKSwingTable_Ch1_Ch13[CCK_Table_length][8] = {
420	{0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},
421	{0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},
422	{0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},
423	{0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},
424	{0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},
425	{0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},
426	{0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},
427	{0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},
428	{0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},
429	{0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},
430	{0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
431	{0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}
432};
433
434static u8	CCKSwingTable_Ch14[CCK_Table_length][8] = {
435	{0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},
436	{0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},
437	{0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},
438	{0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},
439	{0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},
440	{0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},
441	{0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},
442	{0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},
443	{0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},
444	{0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},
445	{0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
446	{0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}
447};
448
449#define		Pw_Track_Flag				0x11d
450#define		Tssi_Mea_Value				0x13c
451#define		Tssi_Report_Value1			0x134
452#define		Tssi_Report_Value2			0x13e
453#define		FW_Busy_Flag				0x13f
454
455static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
456{
457	struct r8192_priv *priv = rtllib_priv(dev);
458	bool	bHighpowerstate, viviflag = false;
459	struct dcmd_txcmd tx_cmd;
460	u8	powerlevelOFDM24G;
461	int	i = 0, j = 0, k = 0;
462	u8	RF_Type, tmp_report[5] = {0, 0, 0, 0, 0};
463	u32	Value;
464	u8	Pwr_Flag;
465	u16	Avg_TSSI_Meas, TSSI_13dBm, Avg_TSSI_Meas_from_driver = 0;
466	u32	delta = 0;
467
468	RT_TRACE(COMP_POWER_TRACKING, "%s()\n", __func__);
469	write_nic_byte(dev, Pw_Track_Flag, 0);
470	write_nic_byte(dev, FW_Busy_Flag, 0);
471	priv->rtllib->bdynamic_txpower_enable = false;
472	bHighpowerstate = priv->bDynamicTxHighPower;
473
474	powerlevelOFDM24G = (u8)(priv->Pwr_Track>>24);
475	RF_Type = priv->rf_type;
476	Value = (RF_Type<<8) | powerlevelOFDM24G;
477
478	RT_TRACE(COMP_POWER_TRACKING, "powerlevelOFDM24G = %x\n",
479		 powerlevelOFDM24G);
480
481
482	for (j = 0; j <= 30; j++) {
483
484		tx_cmd.Op		= TXCMD_SET_TX_PWR_TRACKING;
485		tx_cmd.Length	= 4;
486		tx_cmd.Value		= Value;
487		cmpk_message_handle_tx(dev, (u8 *)&tx_cmd,
488				       DESC_PACKET_TYPE_INIT,
489				       sizeof(struct dcmd_txcmd));
490		mdelay(1);
491		for (i = 0; i <= 30; i++) {
492			Pwr_Flag = read_nic_byte(dev, Pw_Track_Flag);
493
494			if (Pwr_Flag == 0) {
495				mdelay(1);
496
497				if (priv->bResetInProgress) {
498					RT_TRACE(COMP_POWER_TRACKING,
499						 "we are in silent reset progress, so return\n");
500					write_nic_byte(dev, Pw_Track_Flag, 0);
501					write_nic_byte(dev, FW_Busy_Flag, 0);
502					return;
503				}
504				if ((priv->rtllib->eRFPowerState != eRfOn)) {
505					RT_TRACE(COMP_POWER_TRACKING,
506						 "we are in power save, so return\n");
507					write_nic_byte(dev, Pw_Track_Flag, 0);
508					write_nic_byte(dev, FW_Busy_Flag, 0);
509					return;
510				}
511
512				continue;
513			}
514
515			Avg_TSSI_Meas = read_nic_word(dev, Tssi_Mea_Value);
516
517			if (Avg_TSSI_Meas == 0) {
518				write_nic_byte(dev, Pw_Track_Flag, 0);
519				write_nic_byte(dev, FW_Busy_Flag, 0);
520				return;
521			}
522
523			for (k = 0; k < 5; k++) {
524				if (k != 4)
525					tmp_report[k] = read_nic_byte(dev,
526							 Tssi_Report_Value1+k);
527				else
528					tmp_report[k] = read_nic_byte(dev,
529							 Tssi_Report_Value2);
530
531				RT_TRACE(COMP_POWER_TRACKING,
532					 "TSSI_report_value = %d\n",
533					 tmp_report[k]);
534
535			       if (tmp_report[k] <= 20) {
536					viviflag = true;
537					break;
538				}
539			}
540
541			if (viviflag) {
542				write_nic_byte(dev, Pw_Track_Flag, 0);
543				viviflag = false;
544				RT_TRACE(COMP_POWER_TRACKING, "we filted this data\n");
545				for (k = 0; k < 5; k++)
546					tmp_report[k] = 0;
547				break;
548			}
549
550			for (k = 0; k < 5; k++)
551				Avg_TSSI_Meas_from_driver += tmp_report[k];
552
553			Avg_TSSI_Meas_from_driver = Avg_TSSI_Meas_from_driver*100/5;
554			RT_TRACE(COMP_POWER_TRACKING,
555				 "Avg_TSSI_Meas_from_driver = %d\n",
556				 Avg_TSSI_Meas_from_driver);
557			TSSI_13dBm = priv->TSSI_13dBm;
558			RT_TRACE(COMP_POWER_TRACKING, "TSSI_13dBm = %d\n", TSSI_13dBm);
559
560			if (Avg_TSSI_Meas_from_driver > TSSI_13dBm)
561				delta = Avg_TSSI_Meas_from_driver - TSSI_13dBm;
562			else
563				delta = TSSI_13dBm - Avg_TSSI_Meas_from_driver;
564
565			if (delta <= E_FOR_TX_POWER_TRACK) {
566				priv->rtllib->bdynamic_txpower_enable = true;
567				write_nic_byte(dev, Pw_Track_Flag, 0);
568				write_nic_byte(dev, FW_Busy_Flag, 0);
569				RT_TRACE(COMP_POWER_TRACKING,
570					 "tx power track is done\n");
571				RT_TRACE(COMP_POWER_TRACKING,
572					 "priv->rfa_txpowertrackingindex = %d\n",
573					 priv->rfa_txpowertrackingindex);
574				RT_TRACE(COMP_POWER_TRACKING,
575					 "priv->rfa_txpowertrackingindex_real = %d\n",
576					 priv->rfa_txpowertrackingindex_real);
577				RT_TRACE(COMP_POWER_TRACKING,
578					 "priv->CCKPresentAttentuation_difference = %d\n",
579					 priv->CCKPresentAttentuation_difference);
580				RT_TRACE(COMP_POWER_TRACKING,
581					 "priv->CCKPresentAttentuation = %d\n",
582					 priv->CCKPresentAttentuation);
583				return;
584			} else {
585				if (Avg_TSSI_Meas_from_driver < TSSI_13dBm - E_FOR_TX_POWER_TRACK) {
586					if (RF_Type == RF_2T4R) {
587
588						if ((priv->rfa_txpowertrackingindex > 0) &&
589						    (priv->rfc_txpowertrackingindex > 0)) {
590							priv->rfa_txpowertrackingindex--;
591							if (priv->rfa_txpowertrackingindex_real > 4) {
592								priv->rfa_txpowertrackingindex_real--;
593								rtl8192_setBBreg(dev,
594									 rOFDM0_XATxIQImbalance,
595									 bMaskDWord,
596									 priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
597							}
598
599							priv->rfc_txpowertrackingindex--;
600							if (priv->rfc_txpowertrackingindex_real > 4) {
601								priv->rfc_txpowertrackingindex_real--;
602								rtl8192_setBBreg(dev,
603									 rOFDM0_XCTxIQImbalance,
604									 bMaskDWord,
605									 priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
606							}
607						} else {
608							rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance,
609									 bMaskDWord,
610									 priv->txbbgain_table[4].txbbgain_value);
611							rtl8192_setBBreg(dev,
612									 rOFDM0_XCTxIQImbalance,
613									 bMaskDWord, priv->txbbgain_table[4].txbbgain_value);
614						}
615					} else {
616						if (priv->rfa_txpowertrackingindex > 0) {
617							priv->rfa_txpowertrackingindex--;
618							if (priv->rfa_txpowertrackingindex_real > 4) {
619								priv->rfa_txpowertrackingindex_real--;
620								rtl8192_setBBreg(dev,
621										 rOFDM0_XATxIQImbalance,
622										 bMaskDWord,
623										 priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
624							}
625						} else
626							rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance,
627									 bMaskDWord, priv->txbbgain_table[4].txbbgain_value);
628
629					}
630				} else {
631					if (RF_Type == RF_2T4R) {
632						if ((priv->rfa_txpowertrackingindex <
633						    TxBBGainTableLength - 1) &&
634						    (priv->rfc_txpowertrackingindex <
635						    TxBBGainTableLength - 1)) {
636							priv->rfa_txpowertrackingindex++;
637							priv->rfa_txpowertrackingindex_real++;
638							rtl8192_setBBreg(dev,
639								 rOFDM0_XATxIQImbalance,
640								 bMaskDWord,
641								 priv->txbbgain_table
642								 [priv->rfa_txpowertrackingindex_real].txbbgain_value);
643							priv->rfc_txpowertrackingindex++;
644							priv->rfc_txpowertrackingindex_real++;
645							rtl8192_setBBreg(dev,
646								 rOFDM0_XCTxIQImbalance,
647								 bMaskDWord,
648								 priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
649						} else {
650							rtl8192_setBBreg(dev,
651								 rOFDM0_XATxIQImbalance,
652								 bMaskDWord,
653								 priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value);
654							rtl8192_setBBreg(dev,
655								 rOFDM0_XCTxIQImbalance,
656								 bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value);
657						}
658					} else {
659						if (priv->rfa_txpowertrackingindex < (TxBBGainTableLength - 1)) {
660							priv->rfa_txpowertrackingindex++;
661							priv->rfa_txpowertrackingindex_real++;
662							rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance,
663									 bMaskDWord,
664									 priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
665						} else
666							rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance,
667									 bMaskDWord,
668									 priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value);
669					}
670				}
671				if (RF_Type == RF_2T4R) {
672					priv->CCKPresentAttentuation_difference
673						= priv->rfa_txpowertrackingindex - priv->rfa_txpowertracking_default;
674				} else {
675					priv->CCKPresentAttentuation_difference
676						= priv->rfa_txpowertrackingindex_real - priv->rfa_txpowertracking_default;
677				}
678
679				if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
680					priv->CCKPresentAttentuation =
681						 priv->CCKPresentAttentuation_20Mdefault +
682						 priv->CCKPresentAttentuation_difference;
683				else
684					priv->CCKPresentAttentuation =
685						 priv->CCKPresentAttentuation_40Mdefault +
686						 priv->CCKPresentAttentuation_difference;
687
688				if (priv->CCKPresentAttentuation > (CCKTxBBGainTableLength-1))
689					priv->CCKPresentAttentuation = CCKTxBBGainTableLength-1;
690				if (priv->CCKPresentAttentuation < 0)
691					priv->CCKPresentAttentuation = 0;
692
693				if (priv->CCKPresentAttentuation > -1 &&
694				    priv->CCKPresentAttentuation < CCKTxBBGainTableLength) {
695					if (priv->rtllib->current_network.channel == 14 &&
696					    !priv->bcck_in_ch14) {
697						priv->bcck_in_ch14 = true;
698						dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
699					} else if (priv->rtllib->current_network.channel != 14 && priv->bcck_in_ch14) {
700						priv->bcck_in_ch14 = false;
701						dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
702					} else
703						dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
704				}
705				RT_TRACE(COMP_POWER_TRACKING,
706					 "priv->rfa_txpowertrackingindex = %d\n",
707					 priv->rfa_txpowertrackingindex);
708				RT_TRACE(COMP_POWER_TRACKING,
709					 "priv->rfa_txpowertrackingindex_real = %d\n",
710					 priv->rfa_txpowertrackingindex_real);
711				RT_TRACE(COMP_POWER_TRACKING,
712					 "priv->CCKPresentAttentuation_difference = %d\n",
713					 priv->CCKPresentAttentuation_difference);
714				RT_TRACE(COMP_POWER_TRACKING,
715					 "priv->CCKPresentAttentuation = %d\n",
716					 priv->CCKPresentAttentuation);
717
718				if (priv->CCKPresentAttentuation_difference <= -12 || priv->CCKPresentAttentuation_difference >= 24) {
719					priv->rtllib->bdynamic_txpower_enable = true;
720					write_nic_byte(dev, Pw_Track_Flag, 0);
721					write_nic_byte(dev, FW_Busy_Flag, 0);
722					RT_TRACE(COMP_POWER_TRACKING, "tx power track--->limited\n");
723					return;
724				}
725			}
726			write_nic_byte(dev, Pw_Track_Flag, 0);
727			Avg_TSSI_Meas_from_driver = 0;
728			for (k = 0; k < 5; k++)
729				tmp_report[k] = 0;
730			break;
731		}
732		write_nic_byte(dev, FW_Busy_Flag, 0);
733	}
734	priv->rtllib->bdynamic_txpower_enable = true;
735	write_nic_byte(dev, Pw_Track_Flag, 0);
736}
737
738static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device *dev)
739{
740#define ThermalMeterVal	9
741	struct r8192_priv *priv = rtllib_priv(dev);
742	u32 tmpRegA, TempCCk;
743	u8 tmpOFDMindex, tmpCCKindex, tmpCCK20Mindex, tmpCCK40Mindex, tmpval;
744	int i = 0, CCKSwingNeedUpdate = 0;
745
746	if (!priv->btxpower_trackingInit) {
747		tmpRegA = rtl8192_QueryBBReg(dev, rOFDM0_XATxIQImbalance, bMaskDWord);
748		for (i = 0; i < OFDM_Table_Length; i++) {
749			if (tmpRegA == OFDMSwingTable[i]) {
750				priv->OFDM_index[0] = (u8)i;
751				RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, OFDM_index = 0x%x\n",
752					rOFDM0_XATxIQImbalance, tmpRegA, priv->OFDM_index[0]);
753			}
754		}
755
756		TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
757		for (i = 0; i < CCK_Table_length; i++) {
758			if (TempCCk == (u32)CCKSwingTable_Ch1_Ch13[i][0]) {
759				priv->CCK_index = (u8) i;
760				RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x"
761					 " = 0x%x, CCK_index = 0x%x\n",
762					 rCCK0_TxFilter1, TempCCk,
763					 priv->CCK_index);
764				break;
765			}
766		}
767		priv->btxpower_trackingInit = true;
768		return;
769	}
770
771	tmpRegA = rtl8192_phy_QueryRFReg(dev, RF90_PATH_A, 0x12, 0x078);
772	RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d\n", tmpRegA);
773	if (tmpRegA < 3 || tmpRegA > 13)
774		return;
775	if (tmpRegA >= 12)
776		tmpRegA = 12;
777	RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d\n", tmpRegA);
778	priv->ThermalMeter[0] = ThermalMeterVal;
779	priv->ThermalMeter[1] = ThermalMeterVal;
780
781	if (priv->ThermalMeter[0] >= (u8)tmpRegA) {
782		tmpOFDMindex = tmpCCK20Mindex = 6+(priv->ThermalMeter[0] -
783			      (u8)tmpRegA);
784		tmpCCK40Mindex = tmpCCK20Mindex - 6;
785		if (tmpOFDMindex >= OFDM_Table_Length)
786			tmpOFDMindex = OFDM_Table_Length-1;
787		if (tmpCCK20Mindex >= CCK_Table_length)
788			tmpCCK20Mindex = CCK_Table_length-1;
789		if (tmpCCK40Mindex >= CCK_Table_length)
790			tmpCCK40Mindex = CCK_Table_length-1;
791	} else {
792		tmpval = ((u8)tmpRegA - priv->ThermalMeter[0]);
793		if (tmpval >= 6)
794			tmpOFDMindex = tmpCCK20Mindex = 0;
795		else
796			tmpOFDMindex = tmpCCK20Mindex = 6 - tmpval;
797		tmpCCK40Mindex = 0;
798	}
799	if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
800		tmpCCKindex = tmpCCK40Mindex;
801	else
802		tmpCCKindex = tmpCCK20Mindex;
803
804	priv->Record_CCK_20Mindex = tmpCCK20Mindex;
805	priv->Record_CCK_40Mindex = tmpCCK40Mindex;
806	RT_TRACE(COMP_POWER_TRACKING, "Record_CCK_20Mindex / Record_CCK_40"
807		 "Mindex = %d / %d.\n",
808		 priv->Record_CCK_20Mindex, priv->Record_CCK_40Mindex);
809
810	if (priv->rtllib->current_network.channel == 14 &&
811	    !priv->bcck_in_ch14) {
812		priv->bcck_in_ch14 = true;
813		CCKSwingNeedUpdate = 1;
814	} else if (priv->rtllib->current_network.channel != 14 &&
815		   priv->bcck_in_ch14) {
816		priv->bcck_in_ch14 = false;
817		CCKSwingNeedUpdate = 1;
818	}
819
820	if (priv->CCK_index != tmpCCKindex) {
821		priv->CCK_index = tmpCCKindex;
822		CCKSwingNeedUpdate = 1;
823	}
824
825	if (CCKSwingNeedUpdate)
826		dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
827	if (priv->OFDM_index[0] != tmpOFDMindex) {
828		priv->OFDM_index[0] = tmpOFDMindex;
829		rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord,
830				 OFDMSwingTable[priv->OFDM_index[0]]);
831		RT_TRACE(COMP_POWER_TRACKING, "Update OFDMSwing[%d] = 0x%x\n",
832			 priv->OFDM_index[0],
833			 OFDMSwingTable[priv->OFDM_index[0]]);
834	}
835	priv->txpower_count = 0;
836}
837
838void	dm_txpower_trackingcallback(void *data)
839{
840	struct r8192_priv *priv = container_of_dwork_rsl(data,
841				  struct r8192_priv, txpower_tracking_wq);
842	struct net_device *dev = priv->rtllib->dev;
843
844	if (priv->IC_Cut >= IC_VersionCut_D)
845		dm_TXPowerTrackingCallback_TSSI(dev);
846	else
847		dm_TXPowerTrackingCallback_ThermalMeter(dev);
848}
849
850static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev)
851{
852
853	struct r8192_priv *priv = rtllib_priv(dev);
854
855	priv->txbbgain_table[0].txbb_iq_amplifygain = 12;
856	priv->txbbgain_table[0].txbbgain_value = 0x7f8001fe;
857	priv->txbbgain_table[1].txbb_iq_amplifygain = 11;
858	priv->txbbgain_table[1].txbbgain_value = 0x788001e2;
859	priv->txbbgain_table[2].txbb_iq_amplifygain = 10;
860	priv->txbbgain_table[2].txbbgain_value = 0x71c001c7;
861	priv->txbbgain_table[3].txbb_iq_amplifygain = 9;
862	priv->txbbgain_table[3].txbbgain_value = 0x6b8001ae;
863	priv->txbbgain_table[4].txbb_iq_amplifygain = 8;
864	priv->txbbgain_table[4].txbbgain_value = 0x65400195;
865	priv->txbbgain_table[5].txbb_iq_amplifygain = 7;
866	priv->txbbgain_table[5].txbbgain_value = 0x5fc0017f;
867	priv->txbbgain_table[6].txbb_iq_amplifygain = 6;
868	priv->txbbgain_table[6].txbbgain_value = 0x5a400169;
869	priv->txbbgain_table[7].txbb_iq_amplifygain = 5;
870	priv->txbbgain_table[7].txbbgain_value = 0x55400155;
871	priv->txbbgain_table[8].txbb_iq_amplifygain = 4;
872	priv->txbbgain_table[8].txbbgain_value = 0x50800142;
873	priv->txbbgain_table[9].txbb_iq_amplifygain = 3;
874	priv->txbbgain_table[9].txbbgain_value = 0x4c000130;
875	priv->txbbgain_table[10].txbb_iq_amplifygain = 2;
876	priv->txbbgain_table[10].txbbgain_value = 0x47c0011f;
877	priv->txbbgain_table[11].txbb_iq_amplifygain = 1;
878	priv->txbbgain_table[11].txbbgain_value = 0x43c0010f;
879	priv->txbbgain_table[12].txbb_iq_amplifygain = 0;
880	priv->txbbgain_table[12].txbbgain_value = 0x40000100;
881	priv->txbbgain_table[13].txbb_iq_amplifygain = -1;
882	priv->txbbgain_table[13].txbbgain_value = 0x3c8000f2;
883	priv->txbbgain_table[14].txbb_iq_amplifygain = -2;
884	priv->txbbgain_table[14].txbbgain_value = 0x390000e4;
885	priv->txbbgain_table[15].txbb_iq_amplifygain = -3;
886	priv->txbbgain_table[15].txbbgain_value = 0x35c000d7;
887	priv->txbbgain_table[16].txbb_iq_amplifygain = -4;
888	priv->txbbgain_table[16].txbbgain_value = 0x32c000cb;
889	priv->txbbgain_table[17].txbb_iq_amplifygain = -5;
890	priv->txbbgain_table[17].txbbgain_value = 0x300000c0;
891	priv->txbbgain_table[18].txbb_iq_amplifygain = -6;
892	priv->txbbgain_table[18].txbbgain_value = 0x2d4000b5;
893	priv->txbbgain_table[19].txbb_iq_amplifygain = -7;
894	priv->txbbgain_table[19].txbbgain_value = 0x2ac000ab;
895	priv->txbbgain_table[20].txbb_iq_amplifygain = -8;
896	priv->txbbgain_table[20].txbbgain_value = 0x288000a2;
897	priv->txbbgain_table[21].txbb_iq_amplifygain = -9;
898	priv->txbbgain_table[21].txbbgain_value = 0x26000098;
899	priv->txbbgain_table[22].txbb_iq_amplifygain = -10;
900	priv->txbbgain_table[22].txbbgain_value = 0x24000090;
901	priv->txbbgain_table[23].txbb_iq_amplifygain = -11;
902	priv->txbbgain_table[23].txbbgain_value = 0x22000088;
903	priv->txbbgain_table[24].txbb_iq_amplifygain = -12;
904	priv->txbbgain_table[24].txbbgain_value = 0x20000080;
905	priv->txbbgain_table[25].txbb_iq_amplifygain = -13;
906	priv->txbbgain_table[25].txbbgain_value = 0x1a00006c;
907	priv->txbbgain_table[26].txbb_iq_amplifygain = -14;
908	priv->txbbgain_table[26].txbbgain_value = 0x1c800072;
909	priv->txbbgain_table[27].txbb_iq_amplifygain = -15;
910	priv->txbbgain_table[27].txbbgain_value = 0x18000060;
911	priv->txbbgain_table[28].txbb_iq_amplifygain = -16;
912	priv->txbbgain_table[28].txbbgain_value = 0x19800066;
913	priv->txbbgain_table[29].txbb_iq_amplifygain = -17;
914	priv->txbbgain_table[29].txbbgain_value = 0x15800056;
915	priv->txbbgain_table[30].txbb_iq_amplifygain = -18;
916	priv->txbbgain_table[30].txbbgain_value = 0x26c0005b;
917	priv->txbbgain_table[31].txbb_iq_amplifygain = -19;
918	priv->txbbgain_table[31].txbbgain_value = 0x14400051;
919	priv->txbbgain_table[32].txbb_iq_amplifygain = -20;
920	priv->txbbgain_table[32].txbbgain_value = 0x24400051;
921	priv->txbbgain_table[33].txbb_iq_amplifygain = -21;
922	priv->txbbgain_table[33].txbbgain_value = 0x1300004c;
923	priv->txbbgain_table[34].txbb_iq_amplifygain = -22;
924	priv->txbbgain_table[34].txbbgain_value = 0x12000048;
925	priv->txbbgain_table[35].txbb_iq_amplifygain = -23;
926	priv->txbbgain_table[35].txbbgain_value = 0x11000044;
927	priv->txbbgain_table[36].txbb_iq_amplifygain = -24;
928	priv->txbbgain_table[36].txbbgain_value = 0x10000040;
929
930	priv->cck_txbbgain_table[0].ccktxbb_valuearray[0] = 0x36;
931	priv->cck_txbbgain_table[0].ccktxbb_valuearray[1] = 0x35;
932	priv->cck_txbbgain_table[0].ccktxbb_valuearray[2] = 0x2e;
933	priv->cck_txbbgain_table[0].ccktxbb_valuearray[3] = 0x25;
934	priv->cck_txbbgain_table[0].ccktxbb_valuearray[4] = 0x1c;
935	priv->cck_txbbgain_table[0].ccktxbb_valuearray[5] = 0x12;
936	priv->cck_txbbgain_table[0].ccktxbb_valuearray[6] = 0x09;
937	priv->cck_txbbgain_table[0].ccktxbb_valuearray[7] = 0x04;
938
939	priv->cck_txbbgain_table[1].ccktxbb_valuearray[0] = 0x33;
940	priv->cck_txbbgain_table[1].ccktxbb_valuearray[1] = 0x32;
941	priv->cck_txbbgain_table[1].ccktxbb_valuearray[2] = 0x2b;
942	priv->cck_txbbgain_table[1].ccktxbb_valuearray[3] = 0x23;
943	priv->cck_txbbgain_table[1].ccktxbb_valuearray[4] = 0x1a;
944	priv->cck_txbbgain_table[1].ccktxbb_valuearray[5] = 0x11;
945	priv->cck_txbbgain_table[1].ccktxbb_valuearray[6] = 0x08;
946	priv->cck_txbbgain_table[1].ccktxbb_valuearray[7] = 0x04;
947
948	priv->cck_txbbgain_table[2].ccktxbb_valuearray[0] = 0x30;
949	priv->cck_txbbgain_table[2].ccktxbb_valuearray[1] = 0x2f;
950	priv->cck_txbbgain_table[2].ccktxbb_valuearray[2] = 0x29;
951	priv->cck_txbbgain_table[2].ccktxbb_valuearray[3] = 0x21;
952	priv->cck_txbbgain_table[2].ccktxbb_valuearray[4] = 0x19;
953	priv->cck_txbbgain_table[2].ccktxbb_valuearray[5] = 0x10;
954	priv->cck_txbbgain_table[2].ccktxbb_valuearray[6] = 0x08;
955	priv->cck_txbbgain_table[2].ccktxbb_valuearray[7] = 0x03;
956
957	priv->cck_txbbgain_table[3].ccktxbb_valuearray[0] = 0x2d;
958	priv->cck_txbbgain_table[3].ccktxbb_valuearray[1] = 0x2d;
959	priv->cck_txbbgain_table[3].ccktxbb_valuearray[2] = 0x27;
960	priv->cck_txbbgain_table[3].ccktxbb_valuearray[3] = 0x1f;
961	priv->cck_txbbgain_table[3].ccktxbb_valuearray[4] = 0x18;
962	priv->cck_txbbgain_table[3].ccktxbb_valuearray[5] = 0x0f;
963	priv->cck_txbbgain_table[3].ccktxbb_valuearray[6] = 0x08;
964	priv->cck_txbbgain_table[3].ccktxbb_valuearray[7] = 0x03;
965
966	priv->cck_txbbgain_table[4].ccktxbb_valuearray[0] = 0x2b;
967	priv->cck_txbbgain_table[4].ccktxbb_valuearray[1] = 0x2a;
968	priv->cck_txbbgain_table[4].ccktxbb_valuearray[2] = 0x25;
969	priv->cck_txbbgain_table[4].ccktxbb_valuearray[3] = 0x1e;
970	priv->cck_txbbgain_table[4].ccktxbb_valuearray[4] = 0x16;
971	priv->cck_txbbgain_table[4].ccktxbb_valuearray[5] = 0x0e;
972	priv->cck_txbbgain_table[4].ccktxbb_valuearray[6] = 0x07;
973	priv->cck_txbbgain_table[4].ccktxbb_valuearray[7] = 0x03;
974
975	priv->cck_txbbgain_table[5].ccktxbb_valuearray[0] = 0x28;
976	priv->cck_txbbgain_table[5].ccktxbb_valuearray[1] = 0x28;
977	priv->cck_txbbgain_table[5].ccktxbb_valuearray[2] = 0x22;
978	priv->cck_txbbgain_table[5].ccktxbb_valuearray[3] = 0x1c;
979	priv->cck_txbbgain_table[5].ccktxbb_valuearray[4] = 0x15;
980	priv->cck_txbbgain_table[5].ccktxbb_valuearray[5] = 0x0d;
981	priv->cck_txbbgain_table[5].ccktxbb_valuearray[6] = 0x07;
982	priv->cck_txbbgain_table[5].ccktxbb_valuearray[7] = 0x03;
983
984	priv->cck_txbbgain_table[6].ccktxbb_valuearray[0] = 0x26;
985	priv->cck_txbbgain_table[6].ccktxbb_valuearray[1] = 0x25;
986	priv->cck_txbbgain_table[6].ccktxbb_valuearray[2] = 0x21;
987	priv->cck_txbbgain_table[6].ccktxbb_valuearray[3] = 0x1b;
988	priv->cck_txbbgain_table[6].ccktxbb_valuearray[4] = 0x14;
989	priv->cck_txbbgain_table[6].ccktxbb_valuearray[5] = 0x0d;
990	priv->cck_txbbgain_table[6].ccktxbb_valuearray[6] = 0x06;
991	priv->cck_txbbgain_table[6].ccktxbb_valuearray[7] = 0x03;
992
993	priv->cck_txbbgain_table[7].ccktxbb_valuearray[0] = 0x24;
994	priv->cck_txbbgain_table[7].ccktxbb_valuearray[1] = 0x23;
995	priv->cck_txbbgain_table[7].ccktxbb_valuearray[2] = 0x1f;
996	priv->cck_txbbgain_table[7].ccktxbb_valuearray[3] = 0x19;
997	priv->cck_txbbgain_table[7].ccktxbb_valuearray[4] = 0x13;
998	priv->cck_txbbgain_table[7].ccktxbb_valuearray[5] = 0x0c;
999	priv->cck_txbbgain_table[7].ccktxbb_valuearray[6] = 0x06;
1000	priv->cck_txbbgain_table[7].ccktxbb_valuearray[7] = 0x03;
1001
1002	priv->cck_txbbgain_table[8].ccktxbb_valuearray[0] = 0x22;
1003	priv->cck_txbbgain_table[8].ccktxbb_valuearray[1] = 0x21;
1004	priv->cck_txbbgain_table[8].ccktxbb_valuearray[2] = 0x1d;
1005	priv->cck_txbbgain_table[8].ccktxbb_valuearray[3] = 0x18;
1006	priv->cck_txbbgain_table[8].ccktxbb_valuearray[4] = 0x11;
1007	priv->cck_txbbgain_table[8].ccktxbb_valuearray[5] = 0x0b;
1008	priv->cck_txbbgain_table[8].ccktxbb_valuearray[6] = 0x06;
1009	priv->cck_txbbgain_table[8].ccktxbb_valuearray[7] = 0x02;
1010
1011	priv->cck_txbbgain_table[9].ccktxbb_valuearray[0] = 0x20;
1012	priv->cck_txbbgain_table[9].ccktxbb_valuearray[1] = 0x20;
1013	priv->cck_txbbgain_table[9].ccktxbb_valuearray[2] = 0x1b;
1014	priv->cck_txbbgain_table[9].ccktxbb_valuearray[3] = 0x16;
1015	priv->cck_txbbgain_table[9].ccktxbb_valuearray[4] = 0x11;
1016	priv->cck_txbbgain_table[9].ccktxbb_valuearray[5] = 0x08;
1017	priv->cck_txbbgain_table[9].ccktxbb_valuearray[6] = 0x05;
1018	priv->cck_txbbgain_table[9].ccktxbb_valuearray[7] = 0x02;
1019
1020	priv->cck_txbbgain_table[10].ccktxbb_valuearray[0] = 0x1f;
1021	priv->cck_txbbgain_table[10].ccktxbb_valuearray[1] = 0x1e;
1022	priv->cck_txbbgain_table[10].ccktxbb_valuearray[2] = 0x1a;
1023	priv->cck_txbbgain_table[10].ccktxbb_valuearray[3] = 0x15;
1024	priv->cck_txbbgain_table[10].ccktxbb_valuearray[4] = 0x10;
1025	priv->cck_txbbgain_table[10].ccktxbb_valuearray[5] = 0x0a;
1026	priv->cck_txbbgain_table[10].ccktxbb_valuearray[6] = 0x05;
1027	priv->cck_txbbgain_table[10].ccktxbb_valuearray[7] = 0x02;
1028
1029	priv->cck_txbbgain_table[11].ccktxbb_valuearray[0] = 0x1d;
1030	priv->cck_txbbgain_table[11].ccktxbb_valuearray[1] = 0x1c;
1031	priv->cck_txbbgain_table[11].ccktxbb_valuearray[2] = 0x18;
1032	priv->cck_txbbgain_table[11].ccktxbb_valuearray[3] = 0x14;
1033	priv->cck_txbbgain_table[11].ccktxbb_valuearray[4] = 0x0f;
1034	priv->cck_txbbgain_table[11].ccktxbb_valuearray[5] = 0x0a;
1035	priv->cck_txbbgain_table[11].ccktxbb_valuearray[6] = 0x05;
1036	priv->cck_txbbgain_table[11].ccktxbb_valuearray[7] = 0x02;
1037
1038	priv->cck_txbbgain_table[12].ccktxbb_valuearray[0] = 0x1b;
1039	priv->cck_txbbgain_table[12].ccktxbb_valuearray[1] = 0x1a;
1040	priv->cck_txbbgain_table[12].ccktxbb_valuearray[2] = 0x17;
1041	priv->cck_txbbgain_table[12].ccktxbb_valuearray[3] = 0x13;
1042	priv->cck_txbbgain_table[12].ccktxbb_valuearray[4] = 0x0e;
1043	priv->cck_txbbgain_table[12].ccktxbb_valuearray[5] = 0x09;
1044	priv->cck_txbbgain_table[12].ccktxbb_valuearray[6] = 0x04;
1045	priv->cck_txbbgain_table[12].ccktxbb_valuearray[7] = 0x02;
1046
1047	priv->cck_txbbgain_table[13].ccktxbb_valuearray[0] = 0x1a;
1048	priv->cck_txbbgain_table[13].ccktxbb_valuearray[1] = 0x19;
1049	priv->cck_txbbgain_table[13].ccktxbb_valuearray[2] = 0x16;
1050	priv->cck_txbbgain_table[13].ccktxbb_valuearray[3] = 0x12;
1051	priv->cck_txbbgain_table[13].ccktxbb_valuearray[4] = 0x0d;
1052	priv->cck_txbbgain_table[13].ccktxbb_valuearray[5] = 0x09;
1053	priv->cck_txbbgain_table[13].ccktxbb_valuearray[6] = 0x04;
1054	priv->cck_txbbgain_table[13].ccktxbb_valuearray[7] = 0x02;
1055
1056	priv->cck_txbbgain_table[14].ccktxbb_valuearray[0] = 0x18;
1057	priv->cck_txbbgain_table[14].ccktxbb_valuearray[1] = 0x17;
1058	priv->cck_txbbgain_table[14].ccktxbb_valuearray[2] = 0x15;
1059	priv->cck_txbbgain_table[14].ccktxbb_valuearray[3] = 0x11;
1060	priv->cck_txbbgain_table[14].ccktxbb_valuearray[4] = 0x0c;
1061	priv->cck_txbbgain_table[14].ccktxbb_valuearray[5] = 0x08;
1062	priv->cck_txbbgain_table[14].ccktxbb_valuearray[6] = 0x04;
1063	priv->cck_txbbgain_table[14].ccktxbb_valuearray[7] = 0x02;
1064
1065	priv->cck_txbbgain_table[15].ccktxbb_valuearray[0] = 0x17;
1066	priv->cck_txbbgain_table[15].ccktxbb_valuearray[1] = 0x16;
1067	priv->cck_txbbgain_table[15].ccktxbb_valuearray[2] = 0x13;
1068	priv->cck_txbbgain_table[15].ccktxbb_valuearray[3] = 0x10;
1069	priv->cck_txbbgain_table[15].ccktxbb_valuearray[4] = 0x0c;
1070	priv->cck_txbbgain_table[15].ccktxbb_valuearray[5] = 0x08;
1071	priv->cck_txbbgain_table[15].ccktxbb_valuearray[6] = 0x04;
1072	priv->cck_txbbgain_table[15].ccktxbb_valuearray[7] = 0x02;
1073
1074	priv->cck_txbbgain_table[16].ccktxbb_valuearray[0] = 0x16;
1075	priv->cck_txbbgain_table[16].ccktxbb_valuearray[1] = 0x15;
1076	priv->cck_txbbgain_table[16].ccktxbb_valuearray[2] = 0x12;
1077	priv->cck_txbbgain_table[16].ccktxbb_valuearray[3] = 0x0f;
1078	priv->cck_txbbgain_table[16].ccktxbb_valuearray[4] = 0x0b;
1079	priv->cck_txbbgain_table[16].ccktxbb_valuearray[5] = 0x07;
1080	priv->cck_txbbgain_table[16].ccktxbb_valuearray[6] = 0x04;
1081	priv->cck_txbbgain_table[16].ccktxbb_valuearray[7] = 0x01;
1082
1083	priv->cck_txbbgain_table[17].ccktxbb_valuearray[0] = 0x14;
1084	priv->cck_txbbgain_table[17].ccktxbb_valuearray[1] = 0x14;
1085	priv->cck_txbbgain_table[17].ccktxbb_valuearray[2] = 0x11;
1086	priv->cck_txbbgain_table[17].ccktxbb_valuearray[3] = 0x0e;
1087	priv->cck_txbbgain_table[17].ccktxbb_valuearray[4] = 0x0b;
1088	priv->cck_txbbgain_table[17].ccktxbb_valuearray[5] = 0x07;
1089	priv->cck_txbbgain_table[17].ccktxbb_valuearray[6] = 0x03;
1090	priv->cck_txbbgain_table[17].ccktxbb_valuearray[7] = 0x02;
1091
1092	priv->cck_txbbgain_table[18].ccktxbb_valuearray[0] = 0x13;
1093	priv->cck_txbbgain_table[18].ccktxbb_valuearray[1] = 0x13;
1094	priv->cck_txbbgain_table[18].ccktxbb_valuearray[2] = 0x10;
1095	priv->cck_txbbgain_table[18].ccktxbb_valuearray[3] = 0x0d;
1096	priv->cck_txbbgain_table[18].ccktxbb_valuearray[4] = 0x0a;
1097	priv->cck_txbbgain_table[18].ccktxbb_valuearray[5] = 0x06;
1098	priv->cck_txbbgain_table[18].ccktxbb_valuearray[6] = 0x03;
1099	priv->cck_txbbgain_table[18].ccktxbb_valuearray[7] = 0x01;
1100
1101	priv->cck_txbbgain_table[19].ccktxbb_valuearray[0] = 0x12;
1102	priv->cck_txbbgain_table[19].ccktxbb_valuearray[1] = 0x12;
1103	priv->cck_txbbgain_table[19].ccktxbb_valuearray[2] = 0x0f;
1104	priv->cck_txbbgain_table[19].ccktxbb_valuearray[3] = 0x0c;
1105	priv->cck_txbbgain_table[19].ccktxbb_valuearray[4] = 0x09;
1106	priv->cck_txbbgain_table[19].ccktxbb_valuearray[5] = 0x06;
1107	priv->cck_txbbgain_table[19].ccktxbb_valuearray[6] = 0x03;
1108	priv->cck_txbbgain_table[19].ccktxbb_valuearray[7] = 0x01;
1109
1110	priv->cck_txbbgain_table[20].ccktxbb_valuearray[0] = 0x11;
1111	priv->cck_txbbgain_table[20].ccktxbb_valuearray[1] = 0x11;
1112	priv->cck_txbbgain_table[20].ccktxbb_valuearray[2] = 0x0f;
1113	priv->cck_txbbgain_table[20].ccktxbb_valuearray[3] = 0x0c;
1114	priv->cck_txbbgain_table[20].ccktxbb_valuearray[4] = 0x09;
1115	priv->cck_txbbgain_table[20].ccktxbb_valuearray[5] = 0x06;
1116	priv->cck_txbbgain_table[20].ccktxbb_valuearray[6] = 0x03;
1117	priv->cck_txbbgain_table[20].ccktxbb_valuearray[7] = 0x01;
1118
1119	priv->cck_txbbgain_table[21].ccktxbb_valuearray[0] = 0x10;
1120	priv->cck_txbbgain_table[21].ccktxbb_valuearray[1] = 0x10;
1121	priv->cck_txbbgain_table[21].ccktxbb_valuearray[2] = 0x0e;
1122	priv->cck_txbbgain_table[21].ccktxbb_valuearray[3] = 0x0b;
1123	priv->cck_txbbgain_table[21].ccktxbb_valuearray[4] = 0x08;
1124	priv->cck_txbbgain_table[21].ccktxbb_valuearray[5] = 0x05;
1125	priv->cck_txbbgain_table[21].ccktxbb_valuearray[6] = 0x03;
1126	priv->cck_txbbgain_table[21].ccktxbb_valuearray[7] = 0x01;
1127
1128	priv->cck_txbbgain_table[22].ccktxbb_valuearray[0] = 0x0f;
1129	priv->cck_txbbgain_table[22].ccktxbb_valuearray[1] = 0x0f;
1130	priv->cck_txbbgain_table[22].ccktxbb_valuearray[2] = 0x0d;
1131	priv->cck_txbbgain_table[22].ccktxbb_valuearray[3] = 0x0b;
1132	priv->cck_txbbgain_table[22].ccktxbb_valuearray[4] = 0x08;
1133	priv->cck_txbbgain_table[22].ccktxbb_valuearray[5] = 0x05;
1134	priv->cck_txbbgain_table[22].ccktxbb_valuearray[6] = 0x03;
1135	priv->cck_txbbgain_table[22].ccktxbb_valuearray[7] = 0x01;
1136
1137	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[0] = 0x36;
1138	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[1] = 0x35;
1139	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[2] = 0x2e;
1140	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[3] = 0x1b;
1141	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[4] = 0x00;
1142	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[5] = 0x00;
1143	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[6] = 0x00;
1144	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[7] = 0x00;
1145
1146	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[0] = 0x33;
1147	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[1] = 0x32;
1148	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[2] = 0x2b;
1149	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[3] = 0x19;
1150	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[4] = 0x00;
1151	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[5] = 0x00;
1152	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[6] = 0x00;
1153	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[7] = 0x00;
1154
1155	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[0] = 0x30;
1156	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[1] = 0x2f;
1157	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[2] = 0x29;
1158	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[3] = 0x18;
1159	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[4] = 0x00;
1160	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[5] = 0x00;
1161	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[6] = 0x00;
1162	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[7] = 0x00;
1163
1164	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[0] = 0x2d;
1165	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[1] = 0x2d;
1166	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[2] = 0x27;
1167	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[3] = 0x17;
1168	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[4] = 0x00;
1169	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[5] = 0x00;
1170	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[6] = 0x00;
1171	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[7] = 0x00;
1172
1173	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[0] = 0x2b;
1174	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[1] = 0x2a;
1175	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[2] = 0x25;
1176	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[3] = 0x15;
1177	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[4] = 0x00;
1178	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[5] = 0x00;
1179	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[6] = 0x00;
1180	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[7] = 0x00;
1181
1182	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[0] = 0x28;
1183	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[1] = 0x28;
1184	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[2] = 0x22;
1185	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[3] = 0x14;
1186	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[4] = 0x00;
1187	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[5] = 0x00;
1188	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[6] = 0x00;
1189	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[7] = 0x00;
1190
1191	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[0] = 0x26;
1192	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[1] = 0x25;
1193	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[2] = 0x21;
1194	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[3] = 0x13;
1195	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[4] = 0x00;
1196	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[5] = 0x00;
1197	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[6] = 0x00;
1198	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[7] = 0x00;
1199
1200	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[0] = 0x24;
1201	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[1] = 0x23;
1202	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[2] = 0x1f;
1203	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[3] = 0x12;
1204	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[4] = 0x00;
1205	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[5] = 0x00;
1206	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[6] = 0x00;
1207	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[7] = 0x00;
1208
1209	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[0] = 0x22;
1210	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[1] = 0x21;
1211	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[2] = 0x1d;
1212	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[3] = 0x11;
1213	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[4] = 0x00;
1214	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[5] = 0x00;
1215	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[6] = 0x00;
1216	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[7] = 0x00;
1217
1218	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[0] = 0x20;
1219	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[1] = 0x20;
1220	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[2] = 0x1b;
1221	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[3] = 0x10;
1222	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[4] = 0x00;
1223	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[5] = 0x00;
1224	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[6] = 0x00;
1225	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[7] = 0x00;
1226
1227	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[0] = 0x1f;
1228	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[1] = 0x1e;
1229	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[2] = 0x1a;
1230	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[3] = 0x0f;
1231	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[4] = 0x00;
1232	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[5] = 0x00;
1233	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[6] = 0x00;
1234	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[7] = 0x00;
1235
1236	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[0] = 0x1d;
1237	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[1] = 0x1c;
1238	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[2] = 0x18;
1239	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[3] = 0x0e;
1240	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[4] = 0x00;
1241	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[5] = 0x00;
1242	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[6] = 0x00;
1243	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[7] = 0x00;
1244
1245	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[0] = 0x1b;
1246	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[1] = 0x1a;
1247	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[2] = 0x17;
1248	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[3] = 0x0e;
1249	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[4] = 0x00;
1250	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[5] = 0x00;
1251	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[6] = 0x00;
1252	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[7] = 0x00;
1253
1254	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[0] = 0x1a;
1255	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[1] = 0x19;
1256	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[2] = 0x16;
1257	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[3] = 0x0d;
1258	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[4] = 0x00;
1259	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[5] = 0x00;
1260	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[6] = 0x00;
1261	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[7] = 0x00;
1262
1263	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[0] = 0x18;
1264	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[1] = 0x17;
1265	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[2] = 0x15;
1266	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[3] = 0x0c;
1267	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[4] = 0x00;
1268	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[5] = 0x00;
1269	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[6] = 0x00;
1270	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[7] = 0x00;
1271
1272	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[0] = 0x17;
1273	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[1] = 0x16;
1274	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[2] = 0x13;
1275	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[3] = 0x0b;
1276	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[4] = 0x00;
1277	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[5] = 0x00;
1278	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[6] = 0x00;
1279	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[7] = 0x00;
1280
1281	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[0] = 0x16;
1282	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[1] = 0x15;
1283	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[2] = 0x12;
1284	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[3] = 0x0b;
1285	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[4] = 0x00;
1286	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[5] = 0x00;
1287	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[6] = 0x00;
1288	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[7] = 0x00;
1289
1290	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[0] = 0x14;
1291	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[1] = 0x14;
1292	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[2] = 0x11;
1293	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[3] = 0x0a;
1294	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[4] = 0x00;
1295	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[5] = 0x00;
1296	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[6] = 0x00;
1297	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[7] = 0x00;
1298
1299	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[0] = 0x13;
1300	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[1] = 0x13;
1301	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[2] = 0x10;
1302	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[3] = 0x0a;
1303	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[4] = 0x00;
1304	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[5] = 0x00;
1305	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[6] = 0x00;
1306	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[7] = 0x00;
1307
1308	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[0] = 0x12;
1309	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[1] = 0x12;
1310	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[2] = 0x0f;
1311	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[3] = 0x09;
1312	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[4] = 0x00;
1313	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[5] = 0x00;
1314	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[6] = 0x00;
1315	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[7] = 0x00;
1316
1317	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[0] = 0x11;
1318	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[1] = 0x11;
1319	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[2] = 0x0f;
1320	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[3] = 0x09;
1321	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[4] = 0x00;
1322	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[5] = 0x00;
1323	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[6] = 0x00;
1324	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[7] = 0x00;
1325
1326	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[0] = 0x10;
1327	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[1] = 0x10;
1328	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[2] = 0x0e;
1329	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[3] = 0x08;
1330	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[4] = 0x00;
1331	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[5] = 0x00;
1332	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[6] = 0x00;
1333	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[7] = 0x00;
1334
1335	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[0] = 0x0f;
1336	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[1] = 0x0f;
1337	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[2] = 0x0d;
1338	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[3] = 0x08;
1339	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[4] = 0x00;
1340	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[5] = 0x00;
1341	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[6] = 0x00;
1342	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[7] = 0x00;
1343
1344	priv->btxpower_tracking = true;
1345	priv->txpower_count       = 0;
1346	priv->btxpower_trackingInit = false;
1347
1348}
1349
1350static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev)
1351{
1352	struct r8192_priv *priv = rtllib_priv(dev);
1353
1354
1355	if (priv->rtllib->FwRWRF)
1356		priv->btxpower_tracking = true;
1357	else
1358		priv->btxpower_tracking = false;
1359	priv->txpower_count       = 0;
1360	priv->btxpower_trackingInit = false;
1361	RT_TRACE(COMP_POWER_TRACKING, "pMgntInfo->bTXPowerTracking = %d\n",
1362		 priv->btxpower_tracking);
1363}
1364
1365void dm_initialize_txpower_tracking(struct net_device *dev)
1366{
1367	struct r8192_priv *priv = rtllib_priv(dev);
1368
1369	if (priv->IC_Cut >= IC_VersionCut_D)
1370		dm_InitializeTXPowerTracking_TSSI(dev);
1371	else
1372		dm_InitializeTXPowerTracking_ThermalMeter(dev);
1373}
1374
1375static void dm_CheckTXPowerTracking_TSSI(struct net_device *dev)
1376{
1377	struct r8192_priv *priv = rtllib_priv(dev);
1378	static u32 tx_power_track_counter;
1379
1380	RT_TRACE(COMP_POWER_TRACKING, "%s()\n", __func__);
1381	if (read_nic_byte(dev, 0x11e) == 1)
1382		return;
1383	if (!priv->btxpower_tracking)
1384		return;
1385	tx_power_track_counter++;
1386
1387
1388	 if (tx_power_track_counter >= 180) {
1389		queue_delayed_work_rsl(priv->priv_wq, &priv->txpower_tracking_wq, 0);
1390		tx_power_track_counter = 0;
1391	}
1392
1393}
1394static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev)
1395{
1396	struct r8192_priv *priv = rtllib_priv(dev);
1397	static u8	TM_Trigger;
1398	u8		TxPowerCheckCnt = 0;
1399
1400	if (IS_HARDWARE_TYPE_8192SE(dev))
1401		TxPowerCheckCnt = 5;
1402	else
1403		TxPowerCheckCnt = 2;
1404	if (!priv->btxpower_tracking) {
1405		return;
1406	} else {
1407		if (priv->txpower_count  <= TxPowerCheckCnt) {
1408			priv->txpower_count++;
1409			return;
1410		}
1411	}
1412
1413	if (!TM_Trigger) {
1414		{
1415		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
1416		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
1417		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
1418		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
1419		}
1420		TM_Trigger = 1;
1421		return;
1422	} else {
1423	    printk(KERN_INFO "===============>Schedule TxPowerTrackingWorkItem\n");
1424
1425		queue_delayed_work_rsl(priv->priv_wq, &priv->txpower_tracking_wq, 0);
1426		TM_Trigger = 0;
1427		}
1428
1429	}
1430
1431static void dm_check_txpower_tracking(struct net_device *dev)
1432{
1433	struct r8192_priv *priv = rtllib_priv(dev);
1434
1435	if (priv->IC_Cut >= IC_VersionCut_D)
1436		dm_CheckTXPowerTracking_TSSI(dev);
1437	else
1438		dm_CheckTXPowerTracking_ThermalMeter(dev);
1439}
1440
1441static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool  bInCH14)
1442{
1443	u32 TempVal;
1444	struct r8192_priv *priv = rtllib_priv(dev);
1445
1446	TempVal = 0;
1447	if (!bInCH14) {
1448		TempVal = (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[0] +
1449			  (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[1]<<8)) ;
1450
1451		rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1452		TempVal = 0;
1453		TempVal = (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[2] +
1454			  (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[3]<<8) +
1455			  (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[4]<<16)+
1456			  (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[5]<<24));
1457		rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1458		TempVal = 0;
1459		TempVal = (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[6] +
1460			  (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[7]<<8)) ;
1461
1462		rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1463	} else {
1464		TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[0] +
1465			  (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[1]<<8)) ;
1466
1467		rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1468		TempVal = 0;
1469		TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[2] +
1470			  (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[3]<<8) +
1471			  (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[4]<<16)+
1472			  (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[5]<<24));
1473		rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1474		TempVal = 0;
1475		TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[6] +
1476			  (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[7]<<8)) ;
1477
1478		rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1479	}
1480
1481
1482}
1483
1484static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev,	bool  bInCH14)
1485{
1486	u32 TempVal;
1487	struct r8192_priv *priv = rtllib_priv(dev);
1488
1489	TempVal = 0;
1490	if (!bInCH14) {
1491		TempVal =	CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] +
1492					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][1]<<8) ;
1493		rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1494		RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1495			rCCK0_TxFilter1, TempVal);
1496		TempVal = 0;
1497		TempVal =	CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] +
1498					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][3]<<8) +
1499					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][4]<<16)+
1500					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][5]<<24);
1501		rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1502		RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1503			rCCK0_TxFilter2, TempVal);
1504		TempVal = 0;
1505		TempVal =	CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] +
1506					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8) ;
1507
1508		rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1509		RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1510			rCCK0_DebugPort, TempVal);
1511	} else {
1512		TempVal =	CCKSwingTable_Ch14[priv->CCK_index][0] +
1513					(CCKSwingTable_Ch14[priv->CCK_index][1]<<8) ;
1514
1515		rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1516		RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1517			rCCK0_TxFilter1, TempVal);
1518		TempVal = 0;
1519		TempVal =	CCKSwingTable_Ch14[priv->CCK_index][2] +
1520					(CCKSwingTable_Ch14[priv->CCK_index][3]<<8) +
1521					(CCKSwingTable_Ch14[priv->CCK_index][4]<<16)+
1522					(CCKSwingTable_Ch14[priv->CCK_index][5]<<24);
1523		rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1524		RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1525			rCCK0_TxFilter2, TempVal);
1526		TempVal = 0;
1527		TempVal =	CCKSwingTable_Ch14[priv->CCK_index][6] +
1528					(CCKSwingTable_Ch14[priv->CCK_index][7]<<8) ;
1529
1530		rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1531		RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1532			rCCK0_DebugPort, TempVal);
1533	}
1534	}
1535
1536void dm_cck_txpower_adjust(struct net_device *dev, bool  binch14)
1537{
1538	struct r8192_priv *priv = rtllib_priv(dev);
1539
1540	if (priv->IC_Cut >= IC_VersionCut_D)
1541		dm_CCKTxPowerAdjust_TSSI(dev, binch14);
1542	else
1543		dm_CCKTxPowerAdjust_ThermalMeter(dev, binch14);
1544}
1545
1546static void dm_txpower_reset_recovery(struct net_device *dev)
1547{
1548	struct r8192_priv *priv = rtllib_priv(dev);
1549
1550	RT_TRACE(COMP_POWER_TRACKING, "Start Reset Recovery ==>\n");
1551	rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord,
1552			 priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value);
1553	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc80 is %08x\n",
1554		 priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value);
1555	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFA_txPowerTrackingIndex is %x\n",
1556		 priv->rfa_txpowertrackingindex);
1557	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF A I/Q Amplify Gain is %ld\n",
1558		 priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbb_iq_amplifygain);
1559	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: CCK Attenuation is %d dB\n",
1560		 priv->CCKPresentAttentuation);
1561	dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
1562
1563	rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord,
1564			 priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value);
1565	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc90 is %08x\n",
1566		 priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value);
1567	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFC_txPowerTrackingIndex is %x\n",
1568		 priv->rfc_txpowertrackingindex);
1569	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF C I/Q Amplify Gain is %ld\n",
1570		 priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbb_iq_amplifygain);
1571
1572}
1573
1574void dm_restore_dynamic_mechanism_state(struct net_device *dev)
1575{
1576	struct r8192_priv *priv = rtllib_priv(dev);
1577	u32	reg_ratr = priv->rate_adaptive.last_ratr;
1578	u32 ratr_value;
1579
1580	if (IS_NIC_DOWN(priv)) {
1581		RT_TRACE(COMP_RATE, "<---- dm_restore_dynamic_mechanism_state(): driver is going to unload\n");
1582		return;
1583	}
1584
1585	if (priv->rate_adaptive.rate_adaptive_disabled)
1586		return;
1587	if (!(priv->rtllib->mode == WIRELESS_MODE_N_24G ||
1588	      priv->rtllib->mode == WIRELESS_MODE_N_5G))
1589		return;
1590	ratr_value = reg_ratr;
1591	if (priv->rf_type == RF_1T2R)
1592		ratr_value &= ~(RATE_ALL_OFDM_2SS);
1593	write_nic_dword(dev, RATR0, ratr_value);
1594	write_nic_byte(dev, UFWP, 1);
1595	if (priv->btxpower_trackingInit && priv->btxpower_tracking)
1596		dm_txpower_reset_recovery(dev);
1597
1598	dm_bb_initialgain_restore(dev);
1599
1600}
1601
1602static void dm_bb_initialgain_restore(struct net_device *dev)
1603{
1604	struct r8192_priv *priv = rtllib_priv(dev);
1605	u32 bit_mask = 0x7f;
1606
1607	if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1608		return;
1609
1610	rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);
1611	rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bit_mask, (u32)priv->initgain_backup.xaagccore1);
1612	rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bit_mask, (u32)priv->initgain_backup.xbagccore1);
1613	rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, bit_mask, (u32)priv->initgain_backup.xcagccore1);
1614	rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, bit_mask, (u32)priv->initgain_backup.xdagccore1);
1615	bit_mask  = bMaskByte2;
1616	rtl8192_setBBreg(dev, rCCK0_CCA, bit_mask, (u32)priv->initgain_backup.cca);
1617
1618	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc50 is %x\n", priv->initgain_backup.xaagccore1);
1619	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc58 is %x\n", priv->initgain_backup.xbagccore1);
1620	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc60 is %x\n", priv->initgain_backup.xcagccore1);
1621	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc68 is %x\n", priv->initgain_backup.xdagccore1);
1622	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xa0a is %x\n", priv->initgain_backup.cca);
1623	rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);
1624
1625}
1626
1627
1628void dm_backup_dynamic_mechanism_state(struct net_device *dev)
1629{
1630	struct r8192_priv *priv = rtllib_priv(dev);
1631
1632	priv->bswitch_fsync  = false;
1633	priv->bfsync_processing = false;
1634	dm_bb_initialgain_backup(dev);
1635
1636}
1637
1638
1639static void dm_bb_initialgain_backup(struct net_device *dev)
1640{
1641	struct r8192_priv *priv = rtllib_priv(dev);
1642	u32 bit_mask = bMaskByte0;
1643
1644	if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1645		return;
1646
1647	rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);
1648	priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, bit_mask);
1649	priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, bit_mask);
1650	priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, bit_mask);
1651	priv->initgain_backup.xdagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, bit_mask);
1652	bit_mask  = bMaskByte2;
1653	priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, bit_mask);
1654
1655	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc50 is %x\n", priv->initgain_backup.xaagccore1);
1656	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc58 is %x\n", priv->initgain_backup.xbagccore1);
1657	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc60 is %x\n", priv->initgain_backup.xcagccore1);
1658	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc68 is %x\n", priv->initgain_backup.xdagccore1);
1659	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xa0a is %x\n", priv->initgain_backup.cca);
1660
1661}
1662
1663void dm_change_dynamic_initgain_thresh(struct net_device *dev,
1664				       u32 dm_type, u32 dm_value)
1665{
1666	if (dm_type == DIG_TYPE_THRESH_HIGH) {
1667		dm_digtable.rssi_high_thresh = dm_value;
1668	} else if (dm_type == DIG_TYPE_THRESH_LOW) {
1669		dm_digtable.rssi_low_thresh = dm_value;
1670	} else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH) {
1671		dm_digtable.rssi_high_power_highthresh = dm_value;
1672	} else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH) {
1673		dm_digtable.rssi_high_power_highthresh = dm_value;
1674	} else if (dm_type == DIG_TYPE_ENABLE) {
1675		dm_digtable.dig_state		= DM_STA_DIG_MAX;
1676		dm_digtable.dig_enable_flag	= true;
1677	} else if (dm_type == DIG_TYPE_DISABLE) {
1678		dm_digtable.dig_state		= DM_STA_DIG_MAX;
1679		dm_digtable.dig_enable_flag	= false;
1680	} else if (dm_type == DIG_TYPE_DBG_MODE) {
1681		if (dm_value >= DM_DBG_MAX)
1682			dm_value = DM_DBG_OFF;
1683		dm_digtable.dbg_mode		= (u8)dm_value;
1684	} else if (dm_type == DIG_TYPE_RSSI) {
1685		if (dm_value > 100)
1686			dm_value = 30;
1687		dm_digtable.rssi_val			= (long)dm_value;
1688	} else if (dm_type == DIG_TYPE_ALGORITHM) {
1689		if (dm_value >= DIG_ALGO_MAX)
1690			dm_value = DIG_ALGO_BY_FALSE_ALARM;
1691		if (dm_digtable.dig_algorithm != (u8)dm_value)
1692			dm_digtable.dig_algorithm_switch = 1;
1693		dm_digtable.dig_algorithm	= (u8)dm_value;
1694	} else if (dm_type == DIG_TYPE_BACKOFF) {
1695		if (dm_value > 30)
1696			dm_value = 30;
1697		dm_digtable.backoff_val		= (u8)dm_value;
1698	} else if (dm_type == DIG_TYPE_RX_GAIN_MIN) {
1699		if (dm_value == 0)
1700			dm_value = 0x1;
1701		dm_digtable.rx_gain_range_min = (u8)dm_value;
1702	} else if (dm_type == DIG_TYPE_RX_GAIN_MAX) {
1703		if (dm_value > 0x50)
1704			dm_value = 0x50;
1705		dm_digtable.rx_gain_range_max = (u8)dm_value;
1706	}
1707}
1708
1709static void dm_dig_init(struct net_device *dev)
1710{
1711	struct r8192_priv *priv = rtllib_priv(dev);
1712
1713	dm_digtable.dig_enable_flag	= true;
1714	dm_digtable.Backoff_Enable_Flag = true;
1715
1716	dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI;
1717
1718	dm_digtable.Dig_TwoPort_Algorithm = DIG_TWO_PORT_ALGO_RSSI;
1719	dm_digtable.Dig_Ext_Port_Stage = DIG_EXT_PORT_STAGE_MAX;
1720	dm_digtable.dbg_mode = DM_DBG_OFF;
1721	dm_digtable.dig_algorithm_switch = 0;
1722
1723	dm_digtable.dig_state		= DM_STA_DIG_MAX;
1724	dm_digtable.dig_highpwr_state	= DM_STA_DIG_MAX;
1725	dm_digtable.CurSTAConnectState = dm_digtable.PreSTAConnectState = DIG_STA_DISCONNECT;
1726	dm_digtable.CurAPConnectState = dm_digtable.PreAPConnectState = DIG_AP_DISCONNECT;
1727	dm_digtable.initialgain_lowerbound_state = false;
1728
1729	dm_digtable.rssi_low_thresh	= DM_DIG_THRESH_LOW;
1730	dm_digtable.rssi_high_thresh	= DM_DIG_THRESH_HIGH;
1731
1732	dm_digtable.FALowThresh	= DM_FALSEALARM_THRESH_LOW;
1733	dm_digtable.FAHighThresh	= DM_FALSEALARM_THRESH_HIGH;
1734
1735	dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
1736	dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
1737
1738	dm_digtable.rssi_val = 50;
1739	dm_digtable.backoff_val = DM_DIG_BACKOFF;
1740	dm_digtable.rx_gain_range_max = DM_DIG_MAX;
1741	if (priv->CustomerID == RT_CID_819x_Netcore)
1742		dm_digtable.rx_gain_range_min = DM_DIG_MIN_Netcore;
1743	else
1744		dm_digtable.rx_gain_range_min = DM_DIG_MIN;
1745
1746	dm_digtable.BackoffVal_range_max = DM_DIG_BACKOFF_MAX;
1747	dm_digtable.BackoffVal_range_min = DM_DIG_BACKOFF_MIN;
1748}
1749
1750static void dm_ctrl_initgain_byrssi(struct net_device *dev)
1751{
1752
1753	if (dm_digtable.dig_enable_flag == false)
1754		return;
1755
1756	if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
1757		dm_ctrl_initgain_byrssi_by_fwfalse_alarm(dev);
1758	else if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1759		dm_ctrl_initgain_byrssi_by_driverrssi(dev);
1760	else
1761		return;
1762}
1763
1764/*-----------------------------------------------------------------------------
1765 * Function:	dm_CtrlInitGainBeforeConnectByRssiAndFalseAlarm()
1766 *
1767 * Overview:	Driver monitor RSSI and False Alarm to change initial gain.
1768			Only change initial gain during link in progress.
1769 *
1770 * Input:		IN	PADAPTER	pAdapter
1771 *
1772 * Output:		NONE
1773 *
1774 * Return:		NONE
1775 *
1776 * Revised History:
1777 *	When		Who		Remark
1778 *	03/04/2009	hpfan	Create Version 0.
1779 *
1780 *---------------------------------------------------------------------------*/
1781
1782static void dm_ctrl_initgain_byrssi_by_driverrssi(
1783	struct net_device *dev)
1784{
1785	struct r8192_priv *priv = rtllib_priv(dev);
1786	u8 i;
1787	static u8	fw_dig;
1788
1789	if (dm_digtable.dig_enable_flag == false)
1790		return;
1791
1792	if (dm_digtable.dig_algorithm_switch)
1793		fw_dig = 0;
1794	if (fw_dig <= 3) {
1795		for (i = 0; i < 3; i++)
1796			rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);
1797		fw_dig++;
1798		dm_digtable.dig_state = DM_STA_DIG_OFF;
1799	}
1800
1801	if (priv->rtllib->state == RTLLIB_LINKED)
1802		dm_digtable.CurSTAConnectState = DIG_STA_CONNECT;
1803	else
1804		dm_digtable.CurSTAConnectState = DIG_STA_DISCONNECT;
1805
1806
1807	if (dm_digtable.dbg_mode == DM_DBG_OFF)
1808		dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb;
1809	dm_initial_gain(dev);
1810	dm_pd_th(dev);
1811	dm_cs_ratio(dev);
1812	if (dm_digtable.dig_algorithm_switch)
1813		dm_digtable.dig_algorithm_switch = 0;
1814	dm_digtable.PreSTAConnectState = dm_digtable.CurSTAConnectState;
1815
1816}
1817
1818static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(
1819	struct net_device *dev)
1820{
1821	struct r8192_priv *priv = rtllib_priv(dev);
1822	static u32 reset_cnt;
1823	u8 i;
1824
1825	if (dm_digtable.dig_enable_flag == false)
1826		return;
1827
1828	if (dm_digtable.dig_algorithm_switch) {
1829		dm_digtable.dig_state = DM_STA_DIG_MAX;
1830		for (i = 0; i < 3; i++)
1831			rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);
1832		dm_digtable.dig_algorithm_switch = 0;
1833	}
1834
1835	if (priv->rtllib->state != RTLLIB_LINKED)
1836		return;
1837
1838	if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) &&
1839		(priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh))
1840		return;
1841	if ((priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh)) {
1842		if (dm_digtable.dig_state == DM_STA_DIG_OFF &&
1843			(priv->reset_count == reset_cnt))
1844			return;
1845		else
1846			reset_cnt = priv->reset_count;
1847
1848		dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
1849		dm_digtable.dig_state = DM_STA_DIG_OFF;
1850
1851		rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);
1852
1853		write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x17);
1854		write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x17);
1855		write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x17);
1856		write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x17);
1857
1858		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1859			write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
1860		else
1861			write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
1862
1863		write_nic_byte(dev, 0xa0a, 0x08);
1864
1865		return;
1866	}
1867
1868	if ((priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh)) {
1869		u8 reset_flag = 0;
1870
1871		if (dm_digtable.dig_state == DM_STA_DIG_ON &&
1872		    (priv->reset_count == reset_cnt)) {
1873			dm_ctrl_initgain_byrssi_highpwr(dev);
1874			return;
1875		} else {
1876			if (priv->reset_count != reset_cnt)
1877				reset_flag = 1;
1878
1879			reset_cnt = priv->reset_count;
1880		}
1881
1882		dm_digtable.dig_state = DM_STA_DIG_ON;
1883
1884		if (reset_flag == 1) {
1885			write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x2c);
1886			write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x2c);
1887			write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x2c);
1888			write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x2c);
1889		} else {
1890			write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x20);
1891			write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x20);
1892			write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x20);
1893			write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x20);
1894		}
1895
1896		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1897			write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
1898		else
1899			write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
1900
1901		write_nic_byte(dev, 0xa0a, 0xcd);
1902
1903		rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);
1904	}
1905	dm_ctrl_initgain_byrssi_highpwr(dev);
1906}
1907
1908
1909static void dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev)
1910{
1911	struct r8192_priv *priv = rtllib_priv(dev);
1912	static u32 reset_cnt_highpwr;
1913
1914	if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_high_power_lowthresh) &&
1915		(priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_highthresh))
1916		return;
1917
1918	if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh) {
1919		if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON &&
1920			(priv->reset_count == reset_cnt_highpwr))
1921			return;
1922		else
1923			dm_digtable.dig_highpwr_state = DM_STA_DIG_ON;
1924
1925		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1926				write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
1927		else
1928			write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
1929	} else {
1930		if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF &&
1931			(priv->reset_count == reset_cnt_highpwr))
1932			return;
1933		else
1934			dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF;
1935
1936		if (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_lowthresh &&
1937			 priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) {
1938			if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1939				write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
1940			else
1941				write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
1942		}
1943	}
1944	reset_cnt_highpwr = priv->reset_count;
1945}
1946
1947static void dm_initial_gain(struct net_device *dev)
1948{
1949	struct r8192_priv *priv = rtllib_priv(dev);
1950	u8 initial_gain = 0;
1951	static u8 initialized, force_write;
1952	static u32 reset_cnt;
1953
1954	if (dm_digtable.dig_algorithm_switch) {
1955		initialized = 0;
1956		reset_cnt = 0;
1957	}
1958
1959	if (rtllib_act_scanning(priv->rtllib, true) == true) {
1960		force_write = 1;
1961		return;
1962	}
1963
1964	if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) {
1965		if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) {
1966			if ((dm_digtable.rssi_val+10-dm_digtable.backoff_val) > dm_digtable.rx_gain_range_max)
1967				dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_max;
1968			else if ((dm_digtable.rssi_val+10-dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min)
1969				dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_min;
1970			else
1971				dm_digtable.cur_ig_value = dm_digtable.rssi_val+10-dm_digtable.backoff_val;
1972		} else {
1973			if (dm_digtable.cur_ig_value == 0)
1974				dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
1975			else
1976				dm_digtable.cur_ig_value = dm_digtable.pre_ig_value;
1977		}
1978	} else {
1979		dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
1980		dm_digtable.pre_ig_value = 0;
1981	}
1982
1983	if (priv->reset_count != reset_cnt) {
1984		force_write = 1;
1985		reset_cnt = priv->reset_count;
1986	}
1987
1988	if (dm_digtable.pre_ig_value != read_nic_byte(dev, rOFDM0_XAAGCCore1))
1989		force_write = 1;
1990
1991	if ((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value)
1992	    || !initialized || force_write) {
1993		initial_gain = (u8)dm_digtable.cur_ig_value;
1994		write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain);
1995		write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain);
1996		write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain);
1997		write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain);
1998		dm_digtable.pre_ig_value = dm_digtable.cur_ig_value;
1999		initialized = 1;
2000		force_write = 0;
2001	}
2002}
2003
2004static void dm_pd_th(struct net_device *dev)
2005{
2006	struct r8192_priv *priv = rtllib_priv(dev);
2007	static u8 initialized, force_write;
2008	static u32 reset_cnt;
2009
2010	if (dm_digtable.dig_algorithm_switch) {
2011		initialized = 0;
2012		reset_cnt = 0;
2013	}
2014
2015	if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) {
2016		if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) {
2017			if (dm_digtable.rssi_val >= dm_digtable.rssi_high_power_highthresh)
2018				dm_digtable.curpd_thstate = DIG_PD_AT_HIGH_POWER;
2019			else if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh))
2020				dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
2021			else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) &&
2022					(dm_digtable.rssi_val < dm_digtable.rssi_high_power_lowthresh))
2023				dm_digtable.curpd_thstate = DIG_PD_AT_NORMAL_POWER;
2024			else
2025				dm_digtable.curpd_thstate = dm_digtable.prepd_thstate;
2026		} else {
2027			dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
2028		}
2029	} else {
2030		dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
2031	}
2032
2033	if (priv->reset_count != reset_cnt) {
2034		force_write = 1;
2035		reset_cnt = priv->reset_count;
2036	}
2037
2038	if ((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) ||
2039	    (initialized <= 3) || force_write) {
2040		if (dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER) {
2041			if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2042				write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
2043			else
2044				write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2045		} else if (dm_digtable.curpd_thstate == DIG_PD_AT_NORMAL_POWER) {
2046			if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2047				write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
2048			else
2049				write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
2050		} else if (dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER) {
2051			if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2052				write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
2053			else
2054				write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
2055		}
2056		dm_digtable.prepd_thstate = dm_digtable.curpd_thstate;
2057		if (initialized <= 3)
2058			initialized++;
2059		force_write = 0;
2060	}
2061}
2062
2063static	void dm_cs_ratio(struct net_device *dev)
2064{
2065	struct r8192_priv *priv = rtllib_priv(dev);
2066	static u8 initialized, force_write;
2067	static u32 reset_cnt;
2068
2069	if (dm_digtable.dig_algorithm_switch) {
2070		initialized = 0;
2071		reset_cnt = 0;
2072	}
2073
2074	if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) {
2075		if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) {
2076			if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh))
2077				dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
2078			else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh))
2079				dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER;
2080			else
2081				dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state;
2082		} else {
2083			dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
2084		}
2085	} else {
2086		dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
2087	}
2088
2089	if (priv->reset_count != reset_cnt) {
2090		force_write = 1;
2091		reset_cnt = priv->reset_count;
2092	}
2093
2094
2095	if ((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
2096	    !initialized || force_write) {
2097		if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER)
2098			write_nic_byte(dev, 0xa0a, 0x08);
2099		else if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER)
2100			write_nic_byte(dev, 0xa0a, 0xcd);
2101		dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state;
2102		initialized = 1;
2103		force_write = 0;
2104	}
2105}
2106
2107void dm_init_edca_turbo(struct net_device *dev)
2108{
2109	struct r8192_priv *priv = rtllib_priv(dev);
2110
2111	priv->bcurrent_turbo_EDCA = false;
2112	priv->rtllib->bis_any_nonbepkts = false;
2113	priv->bis_cur_rdlstate = false;
2114}
2115
2116static void dm_check_edca_turbo(struct net_device *dev)
2117{
2118	struct r8192_priv *priv = rtllib_priv(dev);
2119	struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo;
2120
2121	static unsigned long lastTxOkCnt;
2122	static unsigned long lastRxOkCnt;
2123	unsigned long curTxOkCnt = 0;
2124	unsigned long curRxOkCnt = 0;
2125
2126	if (priv->rtllib->iw_mode == IW_MODE_ADHOC)
2127		goto dm_CheckEdcaTurbo_EXIT;
2128	if (priv->rtllib->state != RTLLIB_LINKED)
2129		goto dm_CheckEdcaTurbo_EXIT;
2130	if (priv->rtllib->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO)
2131		goto dm_CheckEdcaTurbo_EXIT;
2132
2133	{
2134		u8 *peername[11] = {
2135			"unknown", "realtek_90", "realtek_92se", "broadcom",
2136			"ralink", "atheros", "cisco", "marvell", "92u_softap",
2137			"self_softap"
2138		};
2139		static int wb_tmp;
2140
2141		if (wb_tmp == 0) {
2142			printk(KERN_INFO "%s():iot peer is %s, bssid:"
2143			       " %pM\n", __func__,
2144			       peername[pHTInfo->IOTPeer],
2145			       priv->rtllib->current_network.bssid);
2146			wb_tmp = 1;
2147		}
2148	}
2149	if (!priv->rtllib->bis_any_nonbepkts) {
2150		curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
2151		curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
2152		if (pHTInfo->IOTAction & HT_IOT_ACT_EDCA_BIAS_ON_RX) {
2153			if (curTxOkCnt > 4*curRxOkCnt) {
2154				if (priv->bis_cur_rdlstate ||
2155				    !priv->bcurrent_turbo_EDCA) {
2156					write_nic_dword(dev, EDCAPARA_BE,
2157						 edca_setting_UL[pHTInfo->IOTPeer]);
2158					priv->bis_cur_rdlstate = false;
2159				}
2160			} else {
2161				if (!priv->bis_cur_rdlstate ||
2162				    !priv->bcurrent_turbo_EDCA) {
2163					if (priv->rtllib->mode == WIRELESS_MODE_G)
2164						write_nic_dword(dev, EDCAPARA_BE,
2165							 edca_setting_DL_GMode[pHTInfo->IOTPeer]);
2166					else
2167						write_nic_dword(dev, EDCAPARA_BE,
2168							 edca_setting_DL[pHTInfo->IOTPeer]);
2169					priv->bis_cur_rdlstate = true;
2170				}
2171			}
2172			priv->bcurrent_turbo_EDCA = true;
2173		} else {
2174			if (curRxOkCnt > 4*curTxOkCnt) {
2175				if (!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) {
2176					if (priv->rtllib->mode == WIRELESS_MODE_G)
2177						write_nic_dword(dev, EDCAPARA_BE,
2178							 edca_setting_DL_GMode[pHTInfo->IOTPeer]);
2179					else
2180						write_nic_dword(dev, EDCAPARA_BE,
2181							 edca_setting_DL[pHTInfo->IOTPeer]);
2182					priv->bis_cur_rdlstate = true;
2183				}
2184			} else {
2185				if (priv->bis_cur_rdlstate ||
2186				    !priv->bcurrent_turbo_EDCA) {
2187					write_nic_dword(dev, EDCAPARA_BE,
2188							edca_setting_UL[pHTInfo->IOTPeer]);
2189					priv->bis_cur_rdlstate = false;
2190				}
2191
2192			}
2193
2194			priv->bcurrent_turbo_EDCA = true;
2195		}
2196	} else {
2197		 if (priv->bcurrent_turbo_EDCA) {
2198			u8 tmp = AC0_BE;
2199
2200			priv->rtllib->SetHwRegHandler(dev, HW_VAR_AC_PARAM, (u8 *)(&tmp));
2201			priv->bcurrent_turbo_EDCA = false;
2202		}
2203	}
2204
2205
2206dm_CheckEdcaTurbo_EXIT:
2207	priv->rtllib->bis_any_nonbepkts = false;
2208	lastTxOkCnt = priv->stats.txbytesunicast;
2209	lastRxOkCnt = priv->stats.rxbytesunicast;
2210}
2211
2212static void dm_init_ctstoself(struct net_device *dev)
2213{
2214	struct r8192_priv *priv = rtllib_priv((struct net_device *)dev);
2215
2216	priv->rtllib->bCTSToSelfEnable = true;
2217	priv->rtllib->CTSToSelfTH = CTSToSelfTHVal;
2218}
2219
2220static void dm_ctstoself(struct net_device *dev)
2221{
2222	struct r8192_priv *priv = rtllib_priv((struct net_device *)dev);
2223	struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo;
2224	static unsigned long lastTxOkCnt;
2225	static unsigned long lastRxOkCnt;
2226	unsigned long curTxOkCnt = 0;
2227	unsigned long curRxOkCnt = 0;
2228
2229	if (priv->rtllib->bCTSToSelfEnable != true) {
2230		pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
2231		return;
2232	}
2233	if (pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) {
2234		curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
2235		curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
2236		if (curRxOkCnt > 4*curTxOkCnt)
2237			pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
2238		else
2239			pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
2240
2241		lastTxOkCnt = priv->stats.txbytesunicast;
2242		lastRxOkCnt = priv->stats.rxbytesunicast;
2243	}
2244}
2245
2246
2247static	void dm_Init_WA_Broadcom_IOT(struct net_device *dev)
2248{
2249	struct r8192_priv *priv = rtllib_priv((struct net_device *)dev);
2250	struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo;
2251
2252	pHTInfo->bWAIotBroadcom = false;
2253	pHTInfo->WAIotTH = WAIotTHVal;
2254}
2255
2256static	void	dm_check_pbc_gpio(struct net_device *dev)
2257{
2258}
2259
2260void dm_CheckRfCtrlGPIO(void *data)
2261{
2262	struct r8192_priv *priv = container_of_dwork_rsl(data,
2263				  struct r8192_priv, gpio_change_rf_wq);
2264	struct net_device *dev = priv->rtllib->dev;
2265	u8 tmp1byte;
2266	enum rt_rf_power_state eRfPowerStateToSet;
2267	bool bActuallySet = false;
2268	char *argv[3];
2269	static char *RadioPowerPath = "/etc/acpi/events/RadioPower.sh";
2270	static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", NULL};
2271
2272	bActuallySet = false;
2273
2274	if ((priv->up_first_time == 1) || (priv->being_init_adapter))
2275		return;
2276
2277	if (priv->bfirst_after_down) {
2278		priv->bfirst_after_down = true;
2279		return;
2280	}
2281
2282	tmp1byte = read_nic_byte(dev, GPI);
2283
2284	eRfPowerStateToSet = (tmp1byte&BIT1) ?  eRfOn : eRfOff;
2285
2286	if (priv->bHwRadioOff && (eRfPowerStateToSet == eRfOn)) {
2287		RT_TRACE(COMP_RF, "gpiochangeRF  - HW Radio ON\n");
2288		netdev_info(dev, "gpiochangeRF  - HW Radio ON\n");
2289		priv->bHwRadioOff = false;
2290		bActuallySet = true;
2291	} else if (!priv->bHwRadioOff && (eRfPowerStateToSet == eRfOff)) {
2292		RT_TRACE(COMP_RF, "gpiochangeRF  - HW Radio OFF\n");
2293		netdev_info(dev, "gpiochangeRF  - HW Radio OFF\n");
2294		priv->bHwRadioOff = true;
2295		bActuallySet = true;
2296	}
2297
2298	if (bActuallySet) {
2299		mdelay(1000);
2300		priv->bHwRfOffAction = 1;
2301		MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW, true);
2302		if (priv->bHwRadioOff)
2303			argv[1] = "RFOFF";
2304		else
2305			argv[1] = "RFON";
2306
2307		argv[0] = RadioPowerPath;
2308		argv[2] = NULL;
2309		call_usermodehelper(RadioPowerPath, argv, envp, UMH_WAIT_PROC);
2310	}
2311}
2312
2313void	dm_rf_pathcheck_workitemcallback(void *data)
2314{
2315	struct r8192_priv *priv = container_of_dwork_rsl(data,
2316				  struct r8192_priv,
2317				  rfpath_check_wq);
2318	struct net_device *dev = priv->rtllib->dev;
2319	u8 rfpath = 0, i;
2320
2321	rfpath = read_nic_byte(dev, 0xc04);
2322
2323	for (i = 0; i < RF90_PATH_MAX; i++) {
2324		if (rfpath & (0x01<<i))
2325			priv->brfpath_rxenable[i] = true;
2326		else
2327			priv->brfpath_rxenable[i] = false;
2328	}
2329	if (!DM_RxPathSelTable.Enable)
2330		return;
2331
2332	dm_rxpath_sel_byrssi(dev);
2333}
2334
2335static void dm_init_rxpath_selection(struct net_device *dev)
2336{
2337	u8 i;
2338	struct r8192_priv *priv = rtllib_priv(dev);
2339
2340	DM_RxPathSelTable.Enable = 1;
2341	DM_RxPathSelTable.SS_TH_low = RxPathSelection_SS_TH_low;
2342	DM_RxPathSelTable.diff_TH = RxPathSelection_diff_TH;
2343	if (priv->CustomerID == RT_CID_819x_Netcore)
2344		DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;
2345	else
2346		DM_RxPathSelTable.cck_method = CCK_Rx_Version_1;
2347	DM_RxPathSelTable.DbgMode = DM_DBG_OFF;
2348	DM_RxPathSelTable.disabledRF = 0;
2349	for (i = 0; i < 4; i++) {
2350		DM_RxPathSelTable.rf_rssi[i] = 50;
2351		DM_RxPathSelTable.cck_pwdb_sta[i] = -64;
2352		DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
2353	}
2354}
2355
2356#define PWDB_IN_RANGE	((cur_cck_pwdb < tmp_cck_max_pwdb) &&	\
2357			(cur_cck_pwdb > tmp_cck_sec_pwdb))
2358
2359static void dm_rxpath_sel_byrssi(struct net_device *dev)
2360{
2361	struct r8192_priv *priv = rtllib_priv(dev);
2362	u8 i, max_rssi_index = 0, min_rssi_index = 0;
2363	u8 sec_rssi_index = 0, rf_num = 0;
2364	u8 tmp_max_rssi = 0, tmp_min_rssi = 0, tmp_sec_rssi = 0;
2365	u8 cck_default_Rx = 0x2;
2366	u8 cck_optional_Rx = 0x3;
2367	long tmp_cck_max_pwdb = 0, tmp_cck_min_pwdb = 0, tmp_cck_sec_pwdb = 0;
2368	u8 cck_rx_ver2_max_index = 0, cck_rx_ver2_min_index = 0;
2369	u8 cck_rx_ver2_sec_index = 0;
2370	u8 cur_rf_rssi;
2371	long cur_cck_pwdb;
2372	static u8 disabled_rf_cnt, cck_Rx_Path_initialized;
2373	u8 update_cck_rx_path;
2374
2375	if (priv->rf_type != RF_2T4R)
2376		return;
2377
2378	if (!cck_Rx_Path_initialized) {
2379		DM_RxPathSelTable.cck_Rx_path = (read_nic_byte(dev, 0xa07)&0xf);
2380		cck_Rx_Path_initialized = 1;
2381	}
2382
2383	DM_RxPathSelTable.disabledRF = 0xf;
2384	DM_RxPathSelTable.disabledRF &= ~(read_nic_byte(dev, 0xc04));
2385
2386	if (priv->rtllib->mode == WIRELESS_MODE_B)
2387		DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;
2388
2389	for (i = 0; i < RF90_PATH_MAX; i++) {
2390		if (!DM_RxPathSelTable.DbgMode)
2391			DM_RxPathSelTable.rf_rssi[i] = priv->stats.rx_rssi_percentage[i];
2392
2393		if (priv->brfpath_rxenable[i]) {
2394			rf_num++;
2395			cur_rf_rssi = DM_RxPathSelTable.rf_rssi[i];
2396
2397			if (rf_num == 1) {
2398				max_rssi_index = min_rssi_index = sec_rssi_index = i;
2399				tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi;
2400			} else if (rf_num == 2) {
2401				if (cur_rf_rssi >= tmp_max_rssi) {
2402					tmp_max_rssi = cur_rf_rssi;
2403					max_rssi_index = i;
2404				} else {
2405					tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi;
2406					sec_rssi_index = min_rssi_index = i;
2407				}
2408			} else {
2409				if (cur_rf_rssi > tmp_max_rssi) {
2410					tmp_sec_rssi = tmp_max_rssi;
2411					sec_rssi_index = max_rssi_index;
2412					tmp_max_rssi = cur_rf_rssi;
2413					max_rssi_index = i;
2414				} else if (cur_rf_rssi == tmp_max_rssi) {
2415					tmp_sec_rssi = cur_rf_rssi;
2416					sec_rssi_index = i;
2417				} else if ((cur_rf_rssi < tmp_max_rssi) &&
2418					   (cur_rf_rssi > tmp_sec_rssi)) {
2419					tmp_sec_rssi = cur_rf_rssi;
2420					sec_rssi_index = i;
2421				} else if (cur_rf_rssi == tmp_sec_rssi) {
2422					if (tmp_sec_rssi == tmp_min_rssi) {
2423						tmp_sec_rssi = cur_rf_rssi;
2424						sec_rssi_index = i;
2425					}
2426				} else if ((cur_rf_rssi < tmp_sec_rssi) &&
2427					   (cur_rf_rssi > tmp_min_rssi)) {
2428					;
2429				} else if (cur_rf_rssi == tmp_min_rssi) {
2430					if (tmp_sec_rssi == tmp_min_rssi) {
2431						tmp_min_rssi = cur_rf_rssi;
2432						min_rssi_index = i;
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	if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) {
2444		for (i = 0; i < RF90_PATH_MAX; i++) {
2445			if (priv->brfpath_rxenable[i]) {
2446				rf_num++;
2447				cur_cck_pwdb =
2448					 DM_RxPathSelTable.cck_pwdb_sta[i];
2449
2450				if (rf_num == 1) {
2451					cck_rx_ver2_max_index = i;
2452					cck_rx_ver2_min_index = i;
2453					cck_rx_ver2_sec_index = i;
2454					tmp_cck_max_pwdb = cur_cck_pwdb;
2455					tmp_cck_min_pwdb = cur_cck_pwdb;
2456					tmp_cck_sec_pwdb = cur_cck_pwdb;
2457				} else if (rf_num == 2) {
2458					if (cur_cck_pwdb >= tmp_cck_max_pwdb) {
2459						tmp_cck_max_pwdb = cur_cck_pwdb;
2460						cck_rx_ver2_max_index = i;
2461					} else {
2462						tmp_cck_sec_pwdb = cur_cck_pwdb;
2463						tmp_cck_min_pwdb = cur_cck_pwdb;
2464						cck_rx_ver2_sec_index = i;
2465						cck_rx_ver2_min_index = i;
2466					}
2467				} else {
2468					if (cur_cck_pwdb > tmp_cck_max_pwdb) {
2469						tmp_cck_sec_pwdb =
2470							 tmp_cck_max_pwdb;
2471						cck_rx_ver2_sec_index =
2472							 cck_rx_ver2_max_index;
2473						tmp_cck_max_pwdb = cur_cck_pwdb;
2474						cck_rx_ver2_max_index = i;
2475					} else if (cur_cck_pwdb ==
2476						   tmp_cck_max_pwdb) {
2477						tmp_cck_sec_pwdb = cur_cck_pwdb;
2478						cck_rx_ver2_sec_index = i;
2479					} else if (PWDB_IN_RANGE) {
2480						tmp_cck_sec_pwdb = cur_cck_pwdb;
2481						cck_rx_ver2_sec_index = i;
2482					} else if (cur_cck_pwdb ==
2483						   tmp_cck_sec_pwdb) {
2484						if (tmp_cck_sec_pwdb ==
2485						    tmp_cck_min_pwdb) {
2486							tmp_cck_sec_pwdb =
2487								 cur_cck_pwdb;
2488							cck_rx_ver2_sec_index =
2489								 i;
2490						}
2491					} else if ((cur_cck_pwdb < tmp_cck_sec_pwdb) &&
2492						   (cur_cck_pwdb > tmp_cck_min_pwdb)) {
2493						;
2494					} else if (cur_cck_pwdb == tmp_cck_min_pwdb) {
2495						if (tmp_cck_sec_pwdb == tmp_cck_min_pwdb) {
2496							tmp_cck_min_pwdb = cur_cck_pwdb;
2497							cck_rx_ver2_min_index = i;
2498						}
2499					} else if (cur_cck_pwdb < tmp_cck_min_pwdb) {
2500						tmp_cck_min_pwdb = cur_cck_pwdb;
2501						cck_rx_ver2_min_index = i;
2502					}
2503				}
2504
2505			}
2506		}
2507	}
2508
2509	update_cck_rx_path = 0;
2510	if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) {
2511		cck_default_Rx = cck_rx_ver2_max_index;
2512		cck_optional_Rx = cck_rx_ver2_sec_index;
2513		if (tmp_cck_max_pwdb != -64)
2514			update_cck_rx_path = 1;
2515	}
2516
2517	if (tmp_min_rssi < DM_RxPathSelTable.SS_TH_low && disabled_rf_cnt < 2) {
2518		if ((tmp_max_rssi - tmp_min_rssi) >=
2519		     DM_RxPathSelTable.diff_TH) {
2520			DM_RxPathSelTable.rf_enable_rssi_th[min_rssi_index] =
2521				 tmp_max_rssi+5;
2522			rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable,
2523				 0x1<<min_rssi_index, 0x0);
2524			rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable,
2525				 0x1<<min_rssi_index, 0x0);
2526			disabled_rf_cnt++;
2527		}
2528		if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_1) {
2529			cck_default_Rx = max_rssi_index;
2530			cck_optional_Rx = sec_rssi_index;
2531			if (tmp_max_rssi)
2532				update_cck_rx_path = 1;
2533		}
2534	}
2535
2536	if (update_cck_rx_path) {
2537		DM_RxPathSelTable.cck_Rx_path = (cck_default_Rx<<2) |
2538						(cck_optional_Rx);
2539		rtl8192_setBBreg(dev, rCCK0_AFESetting, 0x0f000000,
2540				 DM_RxPathSelTable.cck_Rx_path);
2541	}
2542
2543	if (DM_RxPathSelTable.disabledRF) {
2544		for (i = 0; i < 4; i++) {
2545			if ((DM_RxPathSelTable.disabledRF>>i) & 0x1) {
2546				if (tmp_max_rssi >=
2547				    DM_RxPathSelTable.rf_enable_rssi_th[i]) {
2548					rtl8192_setBBreg(dev,
2549						 rOFDM0_TRxPathEnable, 0x1 << i,
2550						 0x1);
2551					rtl8192_setBBreg(dev,
2552						 rOFDM1_TRxPathEnable,
2553						 0x1 << i, 0x1);
2554					DM_RxPathSelTable.rf_enable_rssi_th[i]
2555						 = 100;
2556					disabled_rf_cnt--;
2557				}
2558			}
2559		}
2560	}
2561}
2562
2563static	void	dm_check_rx_path_selection(struct net_device *dev)
2564{
2565	struct r8192_priv *priv = rtllib_priv(dev);
2566
2567	queue_delayed_work_rsl(priv->priv_wq, &priv->rfpath_check_wq, 0);
2568}
2569
2570
2571static void dm_init_fsync(struct net_device *dev)
2572{
2573	struct r8192_priv *priv = rtllib_priv(dev);
2574
2575	priv->rtllib->fsync_time_interval = 500;
2576	priv->rtllib->fsync_rate_bitmap = 0x0f000800;
2577	priv->rtllib->fsync_rssi_threshold = 30;
2578	priv->rtllib->bfsync_enable = false;
2579	priv->rtllib->fsync_multiple_timeinterval = 3;
2580	priv->rtllib->fsync_firstdiff_ratethreshold = 100;
2581	priv->rtllib->fsync_seconddiff_ratethreshold = 200;
2582	priv->rtllib->fsync_state = Default_Fsync;
2583	priv->framesyncMonitor = 1;
2584
2585	init_timer(&priv->fsync_timer);
2586	setup_timer(&priv->fsync_timer, dm_fsync_timer_callback,
2587		   (unsigned long) dev);
2588}
2589
2590
2591static void dm_deInit_fsync(struct net_device *dev)
2592{
2593	struct r8192_priv *priv = rtllib_priv(dev);
2594
2595	del_timer_sync(&priv->fsync_timer);
2596}
2597
2598void dm_fsync_timer_callback(unsigned long data)
2599{
2600	struct net_device *dev = (struct net_device *)data;
2601	struct r8192_priv *priv = rtllib_priv((struct net_device *)data);
2602	u32 rate_index, rate_count = 0, rate_count_diff = 0;
2603	bool		bSwitchFromCountDiff = false;
2604	bool		bDoubleTimeInterval = false;
2605
2606	if (priv->rtllib->state == RTLLIB_LINKED &&
2607	    priv->rtllib->bfsync_enable &&
2608	    (priv->rtllib->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC)) {
2609		u32 rate_bitmap;
2610
2611		for (rate_index = 0; rate_index <= 27; rate_index++) {
2612			rate_bitmap  = 1 << rate_index;
2613			if (priv->rtllib->fsync_rate_bitmap &  rate_bitmap)
2614				rate_count +=
2615				   priv->stats.received_rate_histogram[1]
2616				   [rate_index];
2617		}
2618
2619		if (rate_count < priv->rate_record)
2620			rate_count_diff = 0xffffffff - rate_count +
2621					  priv->rate_record;
2622		else
2623			rate_count_diff = rate_count - priv->rate_record;
2624		if (rate_count_diff < priv->rateCountDiffRecord) {
2625
2626			u32 DiffNum = priv->rateCountDiffRecord -
2627				      rate_count_diff;
2628			if (DiffNum >=
2629			    priv->rtllib->fsync_seconddiff_ratethreshold)
2630				priv->ContinueDiffCount++;
2631			else
2632				priv->ContinueDiffCount = 0;
2633
2634			if (priv->ContinueDiffCount >= 2) {
2635				bSwitchFromCountDiff = true;
2636				priv->ContinueDiffCount = 0;
2637			}
2638		} else {
2639			priv->ContinueDiffCount = 0;
2640		}
2641
2642		if (rate_count_diff <=
2643		    priv->rtllib->fsync_firstdiff_ratethreshold) {
2644			bSwitchFromCountDiff = true;
2645			priv->ContinueDiffCount = 0;
2646		}
2647		priv->rate_record = rate_count;
2648		priv->rateCountDiffRecord = rate_count_diff;
2649		RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rate"
2650			 "Countdiff %d bSwitchFsync %d\n", priv->rate_record,
2651			 rate_count, rate_count_diff, priv->bswitch_fsync);
2652		if (priv->undecorated_smoothed_pwdb >
2653		    priv->rtllib->fsync_rssi_threshold &&
2654		    bSwitchFromCountDiff) {
2655			bDoubleTimeInterval = true;
2656			priv->bswitch_fsync = !priv->bswitch_fsync;
2657			if (priv->bswitch_fsync) {
2658				write_nic_byte(dev, 0xC36, 0x1c);
2659				write_nic_byte(dev, 0xC3e, 0x90);
2660			} else {
2661				write_nic_byte(dev, 0xC36, 0x5c);
2662				write_nic_byte(dev, 0xC3e, 0x96);
2663			}
2664		} else if (priv->undecorated_smoothed_pwdb <=
2665			   priv->rtllib->fsync_rssi_threshold) {
2666			if (priv->bswitch_fsync) {
2667				priv->bswitch_fsync  = false;
2668				write_nic_byte(dev, 0xC36, 0x5c);
2669				write_nic_byte(dev, 0xC3e, 0x96);
2670			}
2671		}
2672		if (bDoubleTimeInterval) {
2673			if (timer_pending(&priv->fsync_timer))
2674				del_timer_sync(&priv->fsync_timer);
2675			priv->fsync_timer.expires = jiffies +
2676				 MSECS(priv->rtllib->fsync_time_interval *
2677				 priv->rtllib->fsync_multiple_timeinterval);
2678			add_timer(&priv->fsync_timer);
2679		} else {
2680			if (timer_pending(&priv->fsync_timer))
2681				del_timer_sync(&priv->fsync_timer);
2682			priv->fsync_timer.expires = jiffies +
2683				 MSECS(priv->rtllib->fsync_time_interval);
2684			add_timer(&priv->fsync_timer);
2685		}
2686	} else {
2687		if (priv->bswitch_fsync) {
2688			priv->bswitch_fsync  = false;
2689			write_nic_byte(dev, 0xC36, 0x5c);
2690			write_nic_byte(dev, 0xC3e, 0x96);
2691		}
2692		priv->ContinueDiffCount = 0;
2693		write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
2694	}
2695	RT_TRACE(COMP_HALDM, "ContinueDiffCount %d\n", priv->ContinueDiffCount);
2696	RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d "
2697		 "bSwitchFsync %d\n", priv->rate_record, rate_count,
2698		 rate_count_diff, priv->bswitch_fsync);
2699}
2700
2701static void dm_StartHWFsync(struct net_device *dev)
2702{
2703	u8 rf_timing = 0x77;
2704	struct r8192_priv *priv = rtllib_priv(dev);
2705
2706	RT_TRACE(COMP_HALDM, "%s\n", __func__);
2707	write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cf);
2708	priv->rtllib->SetHwRegHandler(dev, HW_VAR_RF_TIMING,
2709				      (u8 *)(&rf_timing));
2710	write_nic_byte(dev, 0xc3b, 0x41);
2711}
2712
2713static void dm_EndHWFsync(struct net_device *dev)
2714{
2715	u8 rf_timing = 0xaa;
2716	struct r8192_priv *priv = rtllib_priv(dev);
2717
2718	RT_TRACE(COMP_HALDM, "%s\n", __func__);
2719	write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
2720	priv->rtllib->SetHwRegHandler(dev, HW_VAR_RF_TIMING, (u8 *)
2721				     (&rf_timing));
2722	write_nic_byte(dev, 0xc3b, 0x49);
2723}
2724
2725static void dm_EndSWFsync(struct net_device *dev)
2726{
2727	struct r8192_priv *priv = rtllib_priv(dev);
2728
2729	RT_TRACE(COMP_HALDM, "%s\n", __func__);
2730	del_timer_sync(&(priv->fsync_timer));
2731
2732	if (priv->bswitch_fsync) {
2733		priv->bswitch_fsync  = false;
2734
2735		write_nic_byte(dev, 0xC36, 0x5c);
2736
2737		write_nic_byte(dev, 0xC3e, 0x96);
2738	}
2739
2740	priv->ContinueDiffCount = 0;
2741	write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
2742}
2743
2744static void dm_StartSWFsync(struct net_device *dev)
2745{
2746	struct r8192_priv *priv = rtllib_priv(dev);
2747	u32			rateIndex;
2748	u32			rateBitmap;
2749
2750	RT_TRACE(COMP_HALDM, "%s\n", __func__);
2751	priv->rate_record = 0;
2752	priv->ContinueDiffCount = 0;
2753	priv->rateCountDiffRecord = 0;
2754	priv->bswitch_fsync  = false;
2755
2756	if (priv->rtllib->mode == WIRELESS_MODE_N_24G) {
2757		priv->rtllib->fsync_firstdiff_ratethreshold = 600;
2758		priv->rtllib->fsync_seconddiff_ratethreshold = 0xffff;
2759	} else {
2760		priv->rtllib->fsync_firstdiff_ratethreshold = 200;
2761		priv->rtllib->fsync_seconddiff_ratethreshold = 200;
2762	}
2763	for (rateIndex = 0; rateIndex <= 27; rateIndex++) {
2764		rateBitmap  = 1 << rateIndex;
2765		if (priv->rtllib->fsync_rate_bitmap & rateBitmap)
2766			priv->rate_record +=
2767				 priv->stats.received_rate_histogram[1]
2768				[rateIndex];
2769	}
2770	if (timer_pending(&priv->fsync_timer))
2771		del_timer_sync(&priv->fsync_timer);
2772	priv->fsync_timer.expires = jiffies +
2773				    MSECS(priv->rtllib->fsync_time_interval);
2774	add_timer(&priv->fsync_timer);
2775
2776	write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cd);
2777
2778}
2779
2780void dm_check_fsync(struct net_device *dev)
2781{
2782#define	RegC38_Default			0
2783#define	RegC38_NonFsync_Other_AP	1
2784#define	RegC38_Fsync_AP_BCM		2
2785	struct r8192_priv *priv = rtllib_priv(dev);
2786	static u8 reg_c38_State = RegC38_Default;
2787	static u32 reset_cnt;
2788
2789	RT_TRACE(COMP_HALDM, "RSSI %d TimeInterval %d MultipleTimeInterval "
2790		 "%d\n", priv->rtllib->fsync_rssi_threshold,
2791		 priv->rtllib->fsync_time_interval,
2792		 priv->rtllib->fsync_multiple_timeinterval);
2793	RT_TRACE(COMP_HALDM, "RateBitmap 0x%x FirstDiffRateThreshold %d Second"
2794		 "DiffRateThreshold %d\n", priv->rtllib->fsync_rate_bitmap,
2795		 priv->rtllib->fsync_firstdiff_ratethreshold,
2796		 priv->rtllib->fsync_seconddiff_ratethreshold);
2797
2798	if (priv->rtllib->state == RTLLIB_LINKED &&
2799	    priv->rtllib->pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) {
2800		if (priv->rtllib->bfsync_enable == 0) {
2801			switch (priv->rtllib->fsync_state) {
2802			case Default_Fsync:
2803				dm_StartHWFsync(dev);
2804				priv->rtllib->fsync_state = HW_Fsync;
2805				break;
2806			case SW_Fsync:
2807				dm_EndSWFsync(dev);
2808				dm_StartHWFsync(dev);
2809				priv->rtllib->fsync_state = HW_Fsync;
2810				break;
2811			case HW_Fsync:
2812			default:
2813				break;
2814			}
2815		} else {
2816			switch (priv->rtllib->fsync_state) {
2817			case Default_Fsync:
2818				dm_StartSWFsync(dev);
2819				priv->rtllib->fsync_state = SW_Fsync;
2820				break;
2821			case HW_Fsync:
2822				dm_EndHWFsync(dev);
2823				dm_StartSWFsync(dev);
2824				priv->rtllib->fsync_state = SW_Fsync;
2825				break;
2826			case SW_Fsync:
2827			default:
2828				break;
2829
2830			}
2831		}
2832		if (priv->framesyncMonitor) {
2833			if (reg_c38_State != RegC38_Fsync_AP_BCM) {
2834				write_nic_byte(dev, rOFDM0_RxDetector3, 0x95);
2835
2836				reg_c38_State = RegC38_Fsync_AP_BCM;
2837			}
2838		}
2839	} else {
2840		switch (priv->rtllib->fsync_state) {
2841		case HW_Fsync:
2842			dm_EndHWFsync(dev);
2843			priv->rtllib->fsync_state = Default_Fsync;
2844			break;
2845		case SW_Fsync:
2846			dm_EndSWFsync(dev);
2847			priv->rtllib->fsync_state = Default_Fsync;
2848			break;
2849		case Default_Fsync:
2850		default:
2851			break;
2852		}
2853
2854		if (priv->framesyncMonitor) {
2855			if (priv->rtllib->state == RTLLIB_LINKED) {
2856				if (priv->undecorated_smoothed_pwdb <=
2857				    RegC38_TH) {
2858					if (reg_c38_State !=
2859					    RegC38_NonFsync_Other_AP) {
2860							write_nic_byte(dev,
2861							    rOFDM0_RxDetector3,
2862							    0x90);
2863
2864						reg_c38_State =
2865						     RegC38_NonFsync_Other_AP;
2866					}
2867				} else if (priv->undecorated_smoothed_pwdb >=
2868					   (RegC38_TH+5)) {
2869					if (reg_c38_State) {
2870						write_nic_byte(dev,
2871							rOFDM0_RxDetector3,
2872							priv->framesync);
2873						reg_c38_State = RegC38_Default;
2874					}
2875				}
2876			} else {
2877				if (reg_c38_State) {
2878					write_nic_byte(dev, rOFDM0_RxDetector3,
2879						       priv->framesync);
2880					reg_c38_State = RegC38_Default;
2881				}
2882			}
2883		}
2884	}
2885	if (priv->framesyncMonitor) {
2886		if (priv->reset_count != reset_cnt) {
2887			write_nic_byte(dev, rOFDM0_RxDetector3,
2888				       priv->framesync);
2889			reg_c38_State = RegC38_Default;
2890			reset_cnt = priv->reset_count;
2891		}
2892	} else {
2893		if (reg_c38_State) {
2894			write_nic_byte(dev, rOFDM0_RxDetector3,
2895				       priv->framesync);
2896			reg_c38_State = RegC38_Default;
2897		}
2898	}
2899}
2900
2901void dm_shadow_init(struct net_device *dev)
2902{
2903	u8	page;
2904	u16	offset;
2905
2906	for (page = 0; page < 5; page++)
2907		for (offset = 0; offset < 256; offset++)
2908			dm_shadow[page][offset] = read_nic_byte(dev,
2909						  offset+page * 256);
2910
2911	for (page = 8; page < 11; page++)
2912		for (offset = 0; offset < 256; offset++)
2913			dm_shadow[page][offset] = read_nic_byte(dev,
2914						  offset+page * 256);
2915
2916	for (page = 12; page < 15; page++)
2917		for (offset = 0; offset < 256; offset++)
2918			dm_shadow[page][offset] = read_nic_byte(dev,
2919						  offset+page*256);
2920
2921}
2922
2923/*---------------------------Define function prototype------------------------*/
2924static void dm_init_dynamic_txpower(struct net_device *dev)
2925{
2926	struct r8192_priv *priv = rtllib_priv(dev);
2927
2928	priv->rtllib->bdynamic_txpower_enable = true;
2929	priv->bLastDTPFlag_High = false;
2930	priv->bLastDTPFlag_Low = false;
2931	priv->bDynamicTxHighPower = false;
2932	priv->bDynamicTxLowPower = false;
2933}
2934
2935static void dm_dynamic_txpower(struct net_device *dev)
2936{
2937	struct r8192_priv *priv = rtllib_priv(dev);
2938	unsigned int txhipower_threshhold = 0;
2939	unsigned int txlowpower_threshold = 0;
2940
2941	if (priv->rtllib->bdynamic_txpower_enable != true) {
2942		priv->bDynamicTxHighPower = false;
2943		priv->bDynamicTxLowPower = false;
2944		return;
2945	}
2946	if ((priv->rtllib->pHTInfo->IOTPeer == HT_IOT_PEER_ATHEROS) &&
2947	    (priv->rtllib->mode == IEEE_G)) {
2948		txhipower_threshhold = TX_POWER_ATHEROAP_THRESH_HIGH;
2949		txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW;
2950	} else {
2951		txhipower_threshhold = TX_POWER_NEAR_FIELD_THRESH_HIGH;
2952		txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW;
2953	}
2954
2955	RT_TRACE(COMP_TXAGC, "priv->undecorated_smoothed_pwdb = %ld\n",
2956		 priv->undecorated_smoothed_pwdb);
2957
2958	if (priv->rtllib->state == RTLLIB_LINKED) {
2959		if (priv->undecorated_smoothed_pwdb >= txhipower_threshhold) {
2960			priv->bDynamicTxHighPower = true;
2961			priv->bDynamicTxLowPower = false;
2962		} else {
2963			if (priv->undecorated_smoothed_pwdb <
2964			    txlowpower_threshold && priv->bDynamicTxHighPower)
2965				priv->bDynamicTxHighPower = false;
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		priv->bDynamicTxHighPower = false;
2973		priv->bDynamicTxLowPower = false;
2974	}
2975
2976	if ((priv->bDynamicTxHighPower != priv->bLastDTPFlag_High) ||
2977	    (priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low)) {
2978		RT_TRACE(COMP_TXAGC, "SetTxPowerLevel8190()  channel = %d\n",
2979			 priv->rtllib->current_network.channel);
2980
2981		rtl8192_phy_setTxPower(dev,
2982				 priv->rtllib->current_network.channel);
2983	}
2984	priv->bLastDTPFlag_High = priv->bDynamicTxHighPower;
2985	priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower;
2986
2987}
2988
2989static void dm_check_txrateandretrycount(struct net_device *dev)
2990{
2991	struct r8192_priv *priv = rtllib_priv(dev);
2992	struct rtllib_device *ieee = priv->rtllib;
2993
2994	ieee->softmac_stats.CurrentShowTxate = read_nic_byte(dev,
2995						 Current_Tx_Rate_Reg);
2996
2997	ieee->softmac_stats.last_packet_rate = read_nic_byte(dev,
2998						 Initial_Tx_Rate_Reg);
2999
3000	ieee->softmac_stats.txretrycount = read_nic_dword(dev,
3001						 Tx_Retry_Count_Reg);
3002}
3003
3004static void dm_send_rssi_tofw(struct net_device *dev)
3005{
3006	struct r8192_priv *priv = rtllib_priv(dev);
3007
3008	write_nic_byte(dev, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb);
3009}
3010