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