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 			 "<---- %s: driver is going to unload\n", __func__);
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	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 
636 	powerlevelOFDM24G = (u8)(priv->Pwr_Track>>24);
637 	RF_Type = priv->rf_type;
638 	Value = (RF_Type<<8) | powerlevelOFDM24G;
639 
640 	RT_TRACE(COMP_POWER_TRACKING, "powerlevelOFDM24G = %x\n",
641 		 powerlevelOFDM24G);
642 
643 
644 	for (j = 0; j <= 30; j++) {
645 
646 		tx_cmd.Op		= TXCMD_SET_TX_PWR_TRACKING;
647 		tx_cmd.Length	= 4;
648 		tx_cmd.Value		= Value;
649 		rtl92e_send_cmd_pkt(dev, DESC_PACKET_TYPE_NORMAL, (u8 *)&tx_cmd,
650 				    sizeof(struct dcmd_txcmd));
651 		mdelay(1);
652 		for (i = 0; i <= 30; i++) {
653 			Pwr_Flag = rtl92e_readb(dev, Pw_Track_Flag);
654 
655 			if (Pwr_Flag == 0) {
656 				mdelay(1);
657 
658 				if (priv->bResetInProgress) {
659 					RT_TRACE(COMP_POWER_TRACKING,
660 						 "we are in silent reset progress, so return\n");
661 					rtl92e_writeb(dev, Pw_Track_Flag, 0);
662 					rtl92e_writeb(dev, FW_Busy_Flag, 0);
663 					return;
664 				}
665 				if (priv->rtllib->eRFPowerState != eRfOn) {
666 					RT_TRACE(COMP_POWER_TRACKING,
667 						 "we are in power save, so return\n");
668 					rtl92e_writeb(dev, Pw_Track_Flag, 0);
669 					rtl92e_writeb(dev, FW_Busy_Flag, 0);
670 					return;
671 				}
672 
673 				continue;
674 			}
675 
676 			Avg_TSSI_Meas = rtl92e_readw(dev, Tssi_Mea_Value);
677 
678 			if (Avg_TSSI_Meas == 0) {
679 				rtl92e_writeb(dev, Pw_Track_Flag, 0);
680 				rtl92e_writeb(dev, FW_Busy_Flag, 0);
681 				return;
682 			}
683 
684 			for (k = 0; k < 5; k++) {
685 				if (k != 4)
686 					tmp_report[k] = rtl92e_readb(dev,
687 							 Tssi_Report_Value1+k);
688 				else
689 					tmp_report[k] = rtl92e_readb(dev,
690 							 Tssi_Report_Value2);
691 
692 				RT_TRACE(COMP_POWER_TRACKING,
693 					 "TSSI_report_value = %d\n",
694 					 tmp_report[k]);
695 
696 				if (tmp_report[k] <= 20) {
697 					viviflag = true;
698 					break;
699 				}
700 			}
701 
702 			if (viviflag) {
703 				rtl92e_writeb(dev, Pw_Track_Flag, 0);
704 				viviflag = false;
705 				RT_TRACE(COMP_POWER_TRACKING,
706 					 "we filted this data\n");
707 				for (k = 0; k < 5; k++)
708 					tmp_report[k] = 0;
709 				break;
710 			}
711 
712 			for (k = 0; k < 5; k++)
713 				Avg_TSSI_Meas_from_driver += tmp_report[k];
714 
715 			Avg_TSSI_Meas_from_driver *= 100 / 5;
716 			RT_TRACE(COMP_POWER_TRACKING,
717 				 "Avg_TSSI_Meas_from_driver = %d\n",
718 				 Avg_TSSI_Meas_from_driver);
719 			TSSI_13dBm = priv->TSSI_13dBm;
720 			RT_TRACE(COMP_POWER_TRACKING, "TSSI_13dBm = %d\n",
721 				 TSSI_13dBm);
722 
723 			if (Avg_TSSI_Meas_from_driver > TSSI_13dBm)
724 				delta = Avg_TSSI_Meas_from_driver - TSSI_13dBm;
725 			else
726 				delta = TSSI_13dBm - Avg_TSSI_Meas_from_driver;
727 
728 			if (delta <= E_FOR_TX_POWER_TRACK) {
729 				priv->rtllib->bdynamic_txpower_enable = true;
730 				rtl92e_writeb(dev, Pw_Track_Flag, 0);
731 				rtl92e_writeb(dev, FW_Busy_Flag, 0);
732 				RT_TRACE(COMP_POWER_TRACKING,
733 					 "tx power track is done\n");
734 				RT_TRACE(COMP_POWER_TRACKING,
735 					 "priv->rfa_txpowertrackingindex = %d\n",
736 					 priv->rfa_txpowertrackingindex);
737 				RT_TRACE(COMP_POWER_TRACKING,
738 					 "priv->rfa_txpowertrackingindex_real = %d\n",
739 					 priv->rfa_txpowertrackingindex_real);
740 				RT_TRACE(COMP_POWER_TRACKING,
741 					 "priv->CCKPresentAttentuation_difference = %d\n",
742 					 priv->CCKPresentAttentuation_difference);
743 				RT_TRACE(COMP_POWER_TRACKING,
744 					 "priv->CCKPresentAttentuation = %d\n",
745 					 priv->CCKPresentAttentuation);
746 				return;
747 			}
748 			if (Avg_TSSI_Meas_from_driver < TSSI_13dBm - E_FOR_TX_POWER_TRACK)
749 				_rtl92e_dm_tx_update_tssi_weak_signal(dev,
750 								      RF_Type);
751 			else
752 				_rtl92e_dm_tx_update_tssi_strong_signal(dev, RF_Type);
753 
754 			if (RF_Type == RF_2T4R) {
755 				priv->CCKPresentAttentuation_difference
756 					= priv->rfa_txpowertrackingindex - priv->rfa_txpowertracking_default;
757 			} else {
758 				priv->CCKPresentAttentuation_difference
759 					= priv->rfa_txpowertrackingindex_real - priv->rfa_txpowertracking_default;
760 			}
761 
762 			if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
763 				priv->CCKPresentAttentuation =
764 					 priv->CCKPresentAttentuation_20Mdefault +
765 					 priv->CCKPresentAttentuation_difference;
766 			else
767 				priv->CCKPresentAttentuation =
768 					 priv->CCKPresentAttentuation_40Mdefault +
769 					 priv->CCKPresentAttentuation_difference;
770 
771 			if (priv->CCKPresentAttentuation > (CCKTxBBGainTableLength-1))
772 				priv->CCKPresentAttentuation = CCKTxBBGainTableLength-1;
773 			if (priv->CCKPresentAttentuation < 0)
774 				priv->CCKPresentAttentuation = 0;
775 
776 			if (priv->CCKPresentAttentuation > -1 &&
777 			    priv->CCKPresentAttentuation < CCKTxBBGainTableLength) {
778 				if (priv->rtllib->current_network.channel == 14 &&
779 				    !priv->bcck_in_ch14) {
780 					priv->bcck_in_ch14 = true;
781 					rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
782 				} else if (priv->rtllib->current_network.channel != 14 && priv->bcck_in_ch14) {
783 					priv->bcck_in_ch14 = false;
784 					rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
785 				} else
786 					rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
787 			}
788 			RT_TRACE(COMP_POWER_TRACKING,
789 				 "priv->rfa_txpowertrackingindex = %d\n",
790 				 priv->rfa_txpowertrackingindex);
791 			RT_TRACE(COMP_POWER_TRACKING,
792 				 "priv->rfa_txpowertrackingindex_real = %d\n",
793 				 priv->rfa_txpowertrackingindex_real);
794 			RT_TRACE(COMP_POWER_TRACKING,
795 				 "priv->CCKPresentAttentuation_difference = %d\n",
796 				 priv->CCKPresentAttentuation_difference);
797 			RT_TRACE(COMP_POWER_TRACKING,
798 				 "priv->CCKPresentAttentuation = %d\n",
799 				 priv->CCKPresentAttentuation);
800 
801 			if (priv->CCKPresentAttentuation_difference <= -12 ||
802 			    priv->CCKPresentAttentuation_difference >= 24) {
803 				priv->rtllib->bdynamic_txpower_enable = true;
804 				rtl92e_writeb(dev, Pw_Track_Flag, 0);
805 				rtl92e_writeb(dev, FW_Busy_Flag, 0);
806 				RT_TRACE(COMP_POWER_TRACKING,
807 					 "tx power track--->limited\n");
808 				return;
809 			}
810 
811 			rtl92e_writeb(dev, Pw_Track_Flag, 0);
812 			Avg_TSSI_Meas_from_driver = 0;
813 			for (k = 0; k < 5; k++)
814 				tmp_report[k] = 0;
815 			break;
816 		}
817 		rtl92e_writeb(dev, FW_Busy_Flag, 0);
818 	}
819 	priv->rtllib->bdynamic_txpower_enable = true;
820 	rtl92e_writeb(dev, Pw_Track_Flag, 0);
821 }
822 
823 static void _rtl92e_dm_tx_power_tracking_cb_thermal(struct net_device *dev)
824 {
825 #define ThermalMeterVal	9
826 	struct r8192_priv *priv = rtllib_priv(dev);
827 	u32 tmpRegA, TempCCk;
828 	u8 tmpOFDMindex, tmpCCKindex, tmpCCK20Mindex, tmpCCK40Mindex, tmpval;
829 	int i = 0, CCKSwingNeedUpdate = 0;
830 
831 	if (!priv->btxpower_trackingInit) {
832 		tmpRegA = rtl92e_get_bb_reg(dev, rOFDM0_XATxIQImbalance,
833 					    bMaskDWord);
834 		for (i = 0; i < OFDM_Table_Length; i++) {
835 			if (tmpRegA == OFDMSwingTable[i]) {
836 				priv->OFDM_index[0] = (u8)i;
837 				RT_TRACE(COMP_POWER_TRACKING,
838 					 "Initial reg0x%x = 0x%x, OFDM_index = 0x%x\n",
839 					 rOFDM0_XATxIQImbalance, tmpRegA,
840 					 priv->OFDM_index[0]);
841 			}
842 		}
843 
844 		TempCCk = rtl92e_get_bb_reg(dev, rCCK0_TxFilter1, bMaskByte2);
845 		for (i = 0; i < CCK_Table_length; i++) {
846 			if (TempCCk == (u32)CCKSwingTable_Ch1_Ch13[i][0]) {
847 				priv->CCK_index = (u8) i;
848 				RT_TRACE(COMP_POWER_TRACKING,
849 					 "Initial reg0x%x = 0x%x, CCK_index = 0x%x\n",
850 					 rCCK0_TxFilter1, TempCCk,
851 					 priv->CCK_index);
852 				break;
853 			}
854 		}
855 		priv->btxpower_trackingInit = true;
856 		return;
857 	}
858 
859 	tmpRegA = rtl92e_get_rf_reg(dev, RF90_PATH_A, 0x12, 0x078);
860 	RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d\n", tmpRegA);
861 	if (tmpRegA < 3 || tmpRegA > 13)
862 		return;
863 	if (tmpRegA >= 12)
864 		tmpRegA = 12;
865 	RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d\n", tmpRegA);
866 	priv->ThermalMeter[0] = ThermalMeterVal;
867 	priv->ThermalMeter[1] = ThermalMeterVal;
868 
869 	if (priv->ThermalMeter[0] >= (u8)tmpRegA) {
870 		tmpOFDMindex = tmpCCK20Mindex = 6+(priv->ThermalMeter[0] -
871 			      (u8)tmpRegA);
872 		tmpCCK40Mindex = tmpCCK20Mindex - 6;
873 		if (tmpOFDMindex >= OFDM_Table_Length)
874 			tmpOFDMindex = OFDM_Table_Length-1;
875 		if (tmpCCK20Mindex >= CCK_Table_length)
876 			tmpCCK20Mindex = CCK_Table_length-1;
877 		if (tmpCCK40Mindex >= CCK_Table_length)
878 			tmpCCK40Mindex = CCK_Table_length-1;
879 	} else {
880 		tmpval = (u8)tmpRegA - priv->ThermalMeter[0];
881 		if (tmpval >= 6) {
882 			tmpOFDMindex = 0;
883 			tmpCCK20Mindex = 0;
884 		} else {
885 			tmpOFDMindex = 6 - tmpval;
886 			tmpCCK20Mindex = 6 - tmpval;
887 		}
888 		tmpCCK40Mindex = 0;
889 	}
890 	if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
891 		tmpCCKindex = tmpCCK40Mindex;
892 	else
893 		tmpCCKindex = tmpCCK20Mindex;
894 
895 	priv->Record_CCK_20Mindex = tmpCCK20Mindex;
896 	priv->Record_CCK_40Mindex = tmpCCK40Mindex;
897 	RT_TRACE(COMP_POWER_TRACKING,
898 		 "Record_CCK_20Mindex / Record_CCK_40Mindex = %d / %d.\n",
899 		 priv->Record_CCK_20Mindex, priv->Record_CCK_40Mindex);
900 
901 	if (priv->rtllib->current_network.channel == 14 &&
902 	    !priv->bcck_in_ch14) {
903 		priv->bcck_in_ch14 = true;
904 		CCKSwingNeedUpdate = 1;
905 	} else if (priv->rtllib->current_network.channel != 14 &&
906 		   priv->bcck_in_ch14) {
907 		priv->bcck_in_ch14 = false;
908 		CCKSwingNeedUpdate = 1;
909 	}
910 
911 	if (priv->CCK_index != tmpCCKindex) {
912 		priv->CCK_index = tmpCCKindex;
913 		CCKSwingNeedUpdate = 1;
914 	}
915 
916 	if (CCKSwingNeedUpdate)
917 		rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
918 	if (priv->OFDM_index[0] != tmpOFDMindex) {
919 		priv->OFDM_index[0] = tmpOFDMindex;
920 		rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance, bMaskDWord,
921 				  OFDMSwingTable[priv->OFDM_index[0]]);
922 		RT_TRACE(COMP_POWER_TRACKING, "Update OFDMSwing[%d] = 0x%x\n",
923 			 priv->OFDM_index[0],
924 			 OFDMSwingTable[priv->OFDM_index[0]]);
925 	}
926 	priv->txpower_count = 0;
927 }
928 
929 void rtl92e_dm_txpower_tracking_wq(void *data)
930 {
931 	struct r8192_priv *priv = container_of_dwork_rsl(data,
932 				  struct r8192_priv, txpower_tracking_wq);
933 	struct net_device *dev = priv->rtllib->dev;
934 
935 	if (priv->IC_Cut >= IC_VersionCut_D)
936 		_rtl92e_dm_tx_power_tracking_callback_tssi(dev);
937 	else
938 		_rtl92e_dm_tx_power_tracking_cb_thermal(dev);
939 }
940 
941 static void _rtl92e_dm_initialize_tx_power_tracking_tssi(struct net_device *dev)
942 {
943 
944 	struct r8192_priv *priv = rtllib_priv(dev);
945 
946 	priv->btxpower_tracking = true;
947 	priv->txpower_count       = 0;
948 	priv->btxpower_trackingInit = false;
949 
950 }
951 
952 static void _rtl92e_dm_init_tx_power_tracking_thermal(struct net_device *dev)
953 {
954 	struct r8192_priv *priv = rtllib_priv(dev);
955 
956 
957 	if (priv->rtllib->FwRWRF)
958 		priv->btxpower_tracking = true;
959 	else
960 		priv->btxpower_tracking = false;
961 	priv->txpower_count       = 0;
962 	priv->btxpower_trackingInit = false;
963 	RT_TRACE(COMP_POWER_TRACKING, "pMgntInfo->bTXPowerTracking = %d\n",
964 		 priv->btxpower_tracking);
965 }
966 
967 void rtl92e_dm_init_txpower_tracking(struct net_device *dev)
968 {
969 	struct r8192_priv *priv = rtllib_priv(dev);
970 
971 	if (priv->IC_Cut >= IC_VersionCut_D)
972 		_rtl92e_dm_initialize_tx_power_tracking_tssi(dev);
973 	else
974 		_rtl92e_dm_init_tx_power_tracking_thermal(dev);
975 }
976 
977 static void _rtl92e_dm_check_tx_power_tracking_tssi(struct net_device *dev)
978 {
979 	struct r8192_priv *priv = rtllib_priv(dev);
980 	static u32 tx_power_track_counter;
981 
982 	RT_TRACE(COMP_POWER_TRACKING, "%s()\n", __func__);
983 	if (rtl92e_readb(dev, 0x11e) == 1)
984 		return;
985 	if (!priv->btxpower_tracking)
986 		return;
987 	tx_power_track_counter++;
988 
989 
990 	if (tx_power_track_counter >= 180) {
991 		schedule_delayed_work(&priv->txpower_tracking_wq, 0);
992 		tx_power_track_counter = 0;
993 	}
994 
995 }
996 
997 static void _rtl92e_dm_check_tx_power_tracking_thermal(struct net_device *dev)
998 {
999 	struct r8192_priv *priv = rtllib_priv(dev);
1000 	static u8	TM_Trigger;
1001 	u8		TxPowerCheckCnt = 0;
1002 
1003 	if (IS_HARDWARE_TYPE_8192SE(dev))
1004 		TxPowerCheckCnt = 5;
1005 	else
1006 		TxPowerCheckCnt = 2;
1007 	if (!priv->btxpower_tracking)
1008 		return;
1009 
1010 	if (priv->txpower_count  <= TxPowerCheckCnt) {
1011 		priv->txpower_count++;
1012 		return;
1013 	}
1014 
1015 	if (!TM_Trigger) {
1016 		rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
1017 		rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
1018 		rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
1019 		rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
1020 		TM_Trigger = 1;
1021 		return;
1022 	}
1023 	netdev_info(dev, "===============>Schedule TxPowerTrackingWorkItem\n");
1024 	schedule_delayed_work(&priv->txpower_tracking_wq, 0);
1025 	TM_Trigger = 0;
1026 
1027 }
1028 
1029 static void _rtl92e_dm_check_tx_power_tracking(struct net_device *dev)
1030 {
1031 	struct r8192_priv *priv = rtllib_priv(dev);
1032 
1033 	if (priv->IC_Cut >= IC_VersionCut_D)
1034 		_rtl92e_dm_check_tx_power_tracking_tssi(dev);
1035 	else
1036 		_rtl92e_dm_check_tx_power_tracking_thermal(dev);
1037 }
1038 
1039 static void _rtl92e_dm_cck_tx_power_adjust_tssi(struct net_device *dev,
1040 						bool bInCH14)
1041 {
1042 	u32 TempVal;
1043 	struct r8192_priv *priv = rtllib_priv(dev);
1044 	u8 attenuation = (u8)priv->CCKPresentAttentuation;
1045 
1046 	TempVal = 0;
1047 	if (!bInCH14) {
1048 		TempVal = (u32)(dm_cck_tx_bb_gain[attenuation][0] +
1049 			  (dm_cck_tx_bb_gain[attenuation][1] << 8));
1050 
1051 		rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1052 		TempVal = (u32)((dm_cck_tx_bb_gain[attenuation][2]) +
1053 			  (dm_cck_tx_bb_gain[attenuation][3] << 8) +
1054 			  (dm_cck_tx_bb_gain[attenuation][4] << 16)+
1055 			  (dm_cck_tx_bb_gain[attenuation][5] << 24));
1056 		rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1057 		TempVal = (u32)(dm_cck_tx_bb_gain[attenuation][6] +
1058 			  (dm_cck_tx_bb_gain[attenuation][7] << 8));
1059 
1060 		rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1061 	} else {
1062 		TempVal = (u32)((dm_cck_tx_bb_gain_ch14[attenuation][0]) +
1063 			  (dm_cck_tx_bb_gain_ch14[attenuation][1] << 8));
1064 
1065 		rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1066 		TempVal = (u32)((dm_cck_tx_bb_gain_ch14[attenuation][2]) +
1067 			  (dm_cck_tx_bb_gain_ch14[attenuation][3] << 8) +
1068 			  (dm_cck_tx_bb_gain_ch14[attenuation][4] << 16)+
1069 			  (dm_cck_tx_bb_gain_ch14[attenuation][5] << 24));
1070 		rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1071 		TempVal = (u32)((dm_cck_tx_bb_gain_ch14[attenuation][6]) +
1072 			  (dm_cck_tx_bb_gain_ch14[attenuation][7] << 8));
1073 
1074 		rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1075 	}
1076 }
1077 
1078 static void _rtl92e_dm_cck_tx_power_adjust_thermal_meter(struct net_device *dev,
1079 							 bool bInCH14)
1080 {
1081 	u32 TempVal;
1082 	struct r8192_priv *priv = rtllib_priv(dev);
1083 
1084 	TempVal = 0;
1085 	if (!bInCH14) {
1086 		TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] +
1087 			  (CCKSwingTable_Ch1_Ch13[priv->CCK_index][1] << 8);
1088 		rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1089 		RT_TRACE(COMP_POWER_TRACKING,
1090 			 "CCK not chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter1,
1091 			 TempVal);
1092 		TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] +
1093 			  (CCKSwingTable_Ch1_Ch13[priv->CCK_index][3] << 8) +
1094 			  (CCKSwingTable_Ch1_Ch13[priv->CCK_index][4] << 16)+
1095 			  (CCKSwingTable_Ch1_Ch13[priv->CCK_index][5] << 24);
1096 		rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1097 		RT_TRACE(COMP_POWER_TRACKING,
1098 			 "CCK not chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter2,
1099 			 TempVal);
1100 		TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] +
1101 			  (CCKSwingTable_Ch1_Ch13[priv->CCK_index][7] << 8);
1102 
1103 		rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1104 		RT_TRACE(COMP_POWER_TRACKING,
1105 			 "CCK not chnl 14, reg 0x%x = 0x%x\n", rCCK0_DebugPort,
1106 			 TempVal);
1107 	} else {
1108 		TempVal = CCKSwingTable_Ch14[priv->CCK_index][0] +
1109 			  (CCKSwingTable_Ch14[priv->CCK_index][1] << 8);
1110 
1111 		rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1112 		RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1113 			rCCK0_TxFilter1, TempVal);
1114 		TempVal = CCKSwingTable_Ch14[priv->CCK_index][2] +
1115 			  (CCKSwingTable_Ch14[priv->CCK_index][3] << 8) +
1116 			  (CCKSwingTable_Ch14[priv->CCK_index][4] << 16)+
1117 			  (CCKSwingTable_Ch14[priv->CCK_index][5] << 24);
1118 		rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1119 		RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1120 			rCCK0_TxFilter2, TempVal);
1121 		TempVal = CCKSwingTable_Ch14[priv->CCK_index][6] +
1122 			  (CCKSwingTable_Ch14[priv->CCK_index][7]<<8);
1123 
1124 		rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1125 		RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1126 			rCCK0_DebugPort, TempVal);
1127 	}
1128 }
1129 
1130 void rtl92e_dm_cck_txpower_adjust(struct net_device *dev, bool binch14)
1131 {
1132 	struct r8192_priv *priv = rtllib_priv(dev);
1133 
1134 	if (priv->IC_Cut >= IC_VersionCut_D)
1135 		_rtl92e_dm_cck_tx_power_adjust_tssi(dev, binch14);
1136 	else
1137 		_rtl92e_dm_cck_tx_power_adjust_thermal_meter(dev, binch14);
1138 }
1139 
1140 static void _rtl92e_dm_tx_power_reset_recovery(struct net_device *dev)
1141 {
1142 	struct r8192_priv *priv = rtllib_priv(dev);
1143 
1144 	RT_TRACE(COMP_POWER_TRACKING, "Start Reset Recovery ==>\n");
1145 	rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance, bMaskDWord,
1146 			  dm_tx_bb_gain[priv->rfa_txpowertrackingindex]);
1147 	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc80 is %08x\n",
1148 		 dm_tx_bb_gain[priv->rfa_txpowertrackingindex]);
1149 	RT_TRACE(COMP_POWER_TRACKING,
1150 		 "Reset Recovery: Fill in RFA_txPowerTrackingIndex is %x\n",
1151 		 priv->rfa_txpowertrackingindex);
1152 	RT_TRACE(COMP_POWER_TRACKING,
1153 		 "Reset Recovery : RF A I/Q Amplify Gain is %d\n",
1154 		 dm_tx_bb_gain_idx_to_amplify(priv->rfa_txpowertrackingindex));
1155 	RT_TRACE(COMP_POWER_TRACKING,
1156 		 "Reset Recovery: CCK Attenuation is %d dB\n",
1157 		 priv->CCKPresentAttentuation);
1158 	rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
1159 
1160 	rtl92e_set_bb_reg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord,
1161 			  dm_tx_bb_gain[priv->rfc_txpowertrackingindex]);
1162 	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc90 is %08x\n",
1163 		 dm_tx_bb_gain[priv->rfc_txpowertrackingindex]);
1164 	RT_TRACE(COMP_POWER_TRACKING,
1165 		 "Reset Recovery: Fill in RFC_txPowerTrackingIndex is %x\n",
1166 		 priv->rfc_txpowertrackingindex);
1167 	RT_TRACE(COMP_POWER_TRACKING,
1168 		 "Reset Recovery : RF C I/Q Amplify Gain is %d\n",
1169 		 dm_tx_bb_gain_idx_to_amplify(priv->rfc_txpowertrackingindex));
1170 }
1171 
1172 void rtl92e_dm_restore_state(struct net_device *dev)
1173 {
1174 	struct r8192_priv *priv = rtllib_priv(dev);
1175 	u32	reg_ratr = priv->rate_adaptive.last_ratr;
1176 	u32 ratr_value;
1177 
1178 	if (!priv->up) {
1179 		RT_TRACE(COMP_RATE,
1180 			 "<---- %s: driver is going to unload\n", __func__);
1181 		return;
1182 	}
1183 
1184 	if (priv->rate_adaptive.rate_adaptive_disabled)
1185 		return;
1186 	if (!(priv->rtllib->mode == WIRELESS_MODE_N_24G ||
1187 	      priv->rtllib->mode == WIRELESS_MODE_N_5G))
1188 		return;
1189 	ratr_value = reg_ratr;
1190 	if (priv->rf_type == RF_1T2R)
1191 		ratr_value &= ~(RATE_ALL_OFDM_2SS);
1192 	rtl92e_writel(dev, RATR0, ratr_value);
1193 	rtl92e_writeb(dev, UFWP, 1);
1194 	if (priv->btxpower_trackingInit && priv->btxpower_tracking)
1195 		_rtl92e_dm_tx_power_reset_recovery(dev);
1196 
1197 	_rtl92e_dm_bb_initialgain_restore(dev);
1198 
1199 }
1200 
1201 static void _rtl92e_dm_bb_initialgain_restore(struct net_device *dev)
1202 {
1203 	struct r8192_priv *priv = rtllib_priv(dev);
1204 	u32 bit_mask = 0x7f;
1205 
1206 	if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1207 		return;
1208 
1209 	rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8);
1210 	rtl92e_set_bb_reg(dev, rOFDM0_XAAGCCore1, bit_mask,
1211 			  (u32)priv->initgain_backup.xaagccore1);
1212 	rtl92e_set_bb_reg(dev, rOFDM0_XBAGCCore1, bit_mask,
1213 			  (u32)priv->initgain_backup.xbagccore1);
1214 	rtl92e_set_bb_reg(dev, rOFDM0_XCAGCCore1, bit_mask,
1215 			  (u32)priv->initgain_backup.xcagccore1);
1216 	rtl92e_set_bb_reg(dev, rOFDM0_XDAGCCore1, bit_mask,
1217 			  (u32)priv->initgain_backup.xdagccore1);
1218 	bit_mask  = bMaskByte2;
1219 	rtl92e_set_bb_reg(dev, rCCK0_CCA, bit_mask,
1220 			  (u32)priv->initgain_backup.cca);
1221 
1222 	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc50 is %x\n",
1223 		 priv->initgain_backup.xaagccore1);
1224 	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc58 is %x\n",
1225 		 priv->initgain_backup.xbagccore1);
1226 	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc60 is %x\n",
1227 		 priv->initgain_backup.xcagccore1);
1228 	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc68 is %x\n",
1229 		 priv->initgain_backup.xdagccore1);
1230 	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xa0a is %x\n",
1231 		 priv->initgain_backup.cca);
1232 	rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x1);
1233 
1234 }
1235 
1236 void rtl92e_dm_backup_state(struct net_device *dev)
1237 {
1238 	struct r8192_priv *priv = rtllib_priv(dev);
1239 	u32 bit_mask = bMaskByte0;
1240 
1241 	priv->bswitch_fsync  = false;
1242 	priv->bfsync_processing = false;
1243 
1244 	if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1245 		return;
1246 
1247 	rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8);
1248 	priv->initgain_backup.xaagccore1 = (u8)rtl92e_get_bb_reg(dev, rOFDM0_XAAGCCore1, bit_mask);
1249 	priv->initgain_backup.xbagccore1 = (u8)rtl92e_get_bb_reg(dev, rOFDM0_XBAGCCore1, bit_mask);
1250 	priv->initgain_backup.xcagccore1 = (u8)rtl92e_get_bb_reg(dev, rOFDM0_XCAGCCore1, bit_mask);
1251 	priv->initgain_backup.xdagccore1 = (u8)rtl92e_get_bb_reg(dev, rOFDM0_XDAGCCore1, bit_mask);
1252 	bit_mask  = bMaskByte2;
1253 	priv->initgain_backup.cca = (u8)rtl92e_get_bb_reg(dev, rCCK0_CCA, bit_mask);
1254 
1255 	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc50 is %x\n",
1256 		 priv->initgain_backup.xaagccore1);
1257 	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc58 is %x\n",
1258 		 priv->initgain_backup.xbagccore1);
1259 	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc60 is %x\n",
1260 		 priv->initgain_backup.xcagccore1);
1261 	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc68 is %x\n",
1262 		 priv->initgain_backup.xdagccore1);
1263 	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xa0a is %x\n",
1264 		 priv->initgain_backup.cca);
1265 }
1266 
1267 static void _rtl92e_dm_dig_init(struct net_device *dev)
1268 {
1269 	struct r8192_priv *priv = rtllib_priv(dev);
1270 
1271 	dm_digtable.dig_enable_flag	= true;
1272 
1273 	dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI;
1274 
1275 	dm_digtable.dig_algorithm_switch = 0;
1276 
1277 	dm_digtable.dig_state		= DM_STA_DIG_MAX;
1278 	dm_digtable.dig_highpwr_state	= DM_STA_DIG_MAX;
1279 	dm_digtable.CurSTAConnectState = DIG_STA_DISCONNECT;
1280 	dm_digtable.PreSTAConnectState = DIG_STA_DISCONNECT;
1281 
1282 	dm_digtable.rssi_low_thresh	= DM_DIG_THRESH_LOW;
1283 	dm_digtable.rssi_high_thresh	= DM_DIG_THRESH_HIGH;
1284 
1285 	dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
1286 	dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
1287 
1288 	dm_digtable.rssi_val = 50;
1289 	dm_digtable.backoff_val = DM_DIG_BACKOFF;
1290 	dm_digtable.rx_gain_range_max = DM_DIG_MAX;
1291 	if (priv->CustomerID == RT_CID_819x_Netcore)
1292 		dm_digtable.rx_gain_range_min = DM_DIG_MIN_Netcore;
1293 	else
1294 		dm_digtable.rx_gain_range_min = DM_DIG_MIN;
1295 }
1296 
1297 static void _rtl92e_dm_ctrl_initgain_byrssi(struct net_device *dev)
1298 {
1299 
1300 	if (dm_digtable.dig_enable_flag == false)
1301 		return;
1302 
1303 	if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
1304 		_rtl92e_dm_ctrl_initgain_byrssi_false_alarm(dev);
1305 	else if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1306 		_rtl92e_dm_ctrl_initgain_byrssi_driver(dev);
1307 	else
1308 		return;
1309 }
1310 
1311 /*-----------------------------------------------------------------------------
1312  * Function:	dm_CtrlInitGainBeforeConnectByRssiAndFalseAlarm()
1313  *
1314  * Overview:	Driver monitor RSSI and False Alarm to change initial gain.
1315 			Only change initial gain during link in progress.
1316  *
1317  * Input:		IN	PADAPTER	pAdapter
1318  *
1319  * Output:		NONE
1320  *
1321  * Return:		NONE
1322  *
1323  * Revised History:
1324  *	When		Who		Remark
1325  *	03/04/2009	hpfan	Create Version 0.
1326  *
1327  ******************************************************************************/
1328 
1329 static void _rtl92e_dm_ctrl_initgain_byrssi_driver(struct net_device *dev)
1330 {
1331 	struct r8192_priv *priv = rtllib_priv(dev);
1332 	u8 i;
1333 	static u8	fw_dig;
1334 
1335 	if (dm_digtable.dig_enable_flag == false)
1336 		return;
1337 
1338 	if (dm_digtable.dig_algorithm_switch)
1339 		fw_dig = 0;
1340 	if (fw_dig <= 3) {
1341 		for (i = 0; i < 3; i++)
1342 			rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8);
1343 		fw_dig++;
1344 		dm_digtable.dig_state = DM_STA_DIG_OFF;
1345 	}
1346 
1347 	if (priv->rtllib->state == RTLLIB_LINKED)
1348 		dm_digtable.CurSTAConnectState = DIG_STA_CONNECT;
1349 	else
1350 		dm_digtable.CurSTAConnectState = DIG_STA_DISCONNECT;
1351 
1352 
1353 	dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb;
1354 	_rtl92e_dm_initial_gain(dev);
1355 	_rtl92e_dm_pd_th(dev);
1356 	_rtl92e_dm_cs_ratio(dev);
1357 	if (dm_digtable.dig_algorithm_switch)
1358 		dm_digtable.dig_algorithm_switch = 0;
1359 	dm_digtable.PreSTAConnectState = dm_digtable.CurSTAConnectState;
1360 
1361 }
1362 
1363 static void _rtl92e_dm_ctrl_initgain_byrssi_false_alarm(struct net_device *dev)
1364 {
1365 	struct r8192_priv *priv = rtllib_priv(dev);
1366 	static u32 reset_cnt;
1367 	u8 i;
1368 
1369 	if (dm_digtable.dig_enable_flag == false)
1370 		return;
1371 
1372 	if (dm_digtable.dig_algorithm_switch) {
1373 		dm_digtable.dig_state = DM_STA_DIG_MAX;
1374 		for (i = 0; i < 3; i++)
1375 			rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x1);
1376 		dm_digtable.dig_algorithm_switch = 0;
1377 	}
1378 
1379 	if (priv->rtllib->state != RTLLIB_LINKED)
1380 		return;
1381 
1382 	if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) &&
1383 		(priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh))
1384 		return;
1385 	if (priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh) {
1386 		if (dm_digtable.dig_state == DM_STA_DIG_OFF &&
1387 			(priv->reset_count == reset_cnt))
1388 			return;
1389 		reset_cnt = priv->reset_count;
1390 
1391 		dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
1392 		dm_digtable.dig_state = DM_STA_DIG_OFF;
1393 
1394 		rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8);
1395 
1396 		rtl92e_writeb(dev, rOFDM0_XAAGCCore1, 0x17);
1397 		rtl92e_writeb(dev, rOFDM0_XBAGCCore1, 0x17);
1398 		rtl92e_writeb(dev, rOFDM0_XCAGCCore1, 0x17);
1399 		rtl92e_writeb(dev, rOFDM0_XDAGCCore1, 0x17);
1400 
1401 		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1402 			rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x00);
1403 		else
1404 			rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x42);
1405 
1406 		rtl92e_writeb(dev, 0xa0a, 0x08);
1407 
1408 		return;
1409 	}
1410 
1411 	if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) {
1412 		u8 reset_flag = 0;
1413 
1414 		if (dm_digtable.dig_state == DM_STA_DIG_ON &&
1415 		    (priv->reset_count == reset_cnt)) {
1416 			_rtl92e_dm_ctrl_initgain_byrssi_highpwr(dev);
1417 			return;
1418 		}
1419 		if (priv->reset_count != reset_cnt)
1420 			reset_flag = 1;
1421 
1422 		reset_cnt = priv->reset_count;
1423 
1424 		dm_digtable.dig_state = DM_STA_DIG_ON;
1425 
1426 		if (reset_flag == 1) {
1427 			rtl92e_writeb(dev, rOFDM0_XAAGCCore1, 0x2c);
1428 			rtl92e_writeb(dev, rOFDM0_XBAGCCore1, 0x2c);
1429 			rtl92e_writeb(dev, rOFDM0_XCAGCCore1, 0x2c);
1430 			rtl92e_writeb(dev, rOFDM0_XDAGCCore1, 0x2c);
1431 		} else {
1432 			rtl92e_writeb(dev, rOFDM0_XAAGCCore1, 0x20);
1433 			rtl92e_writeb(dev, rOFDM0_XBAGCCore1, 0x20);
1434 			rtl92e_writeb(dev, rOFDM0_XCAGCCore1, 0x20);
1435 			rtl92e_writeb(dev, rOFDM0_XDAGCCore1, 0x20);
1436 		}
1437 
1438 		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1439 			rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x20);
1440 		else
1441 			rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x44);
1442 
1443 		rtl92e_writeb(dev, 0xa0a, 0xcd);
1444 
1445 		rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x1);
1446 	}
1447 	_rtl92e_dm_ctrl_initgain_byrssi_highpwr(dev);
1448 }
1449 
1450 
1451 static void _rtl92e_dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev)
1452 {
1453 	struct r8192_priv *priv = rtllib_priv(dev);
1454 	static u32 reset_cnt_highpwr;
1455 
1456 	if ((priv->undecorated_smoothed_pwdb >
1457 	     dm_digtable.rssi_high_power_lowthresh) &&
1458 	    (priv->undecorated_smoothed_pwdb <
1459 	     dm_digtable.rssi_high_power_highthresh))
1460 		return;
1461 
1462 	if (priv->undecorated_smoothed_pwdb >=
1463 	    dm_digtable.rssi_high_power_highthresh) {
1464 		if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON &&
1465 			(priv->reset_count == reset_cnt_highpwr))
1466 			return;
1467 		dm_digtable.dig_highpwr_state = DM_STA_DIG_ON;
1468 
1469 		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1470 			rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x10);
1471 		else
1472 			rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x43);
1473 	} else {
1474 		if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF &&
1475 			(priv->reset_count == reset_cnt_highpwr))
1476 			return;
1477 		dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF;
1478 
1479 		if ((priv->undecorated_smoothed_pwdb <
1480 		     dm_digtable.rssi_high_power_lowthresh) &&
1481 		    (priv->undecorated_smoothed_pwdb >=
1482 		    dm_digtable.rssi_high_thresh)) {
1483 			if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1484 				rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x20);
1485 			else
1486 				rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x44);
1487 		}
1488 	}
1489 	reset_cnt_highpwr = priv->reset_count;
1490 }
1491 
1492 static void _rtl92e_dm_initial_gain(struct net_device *dev)
1493 {
1494 	struct r8192_priv *priv = rtllib_priv(dev);
1495 	u8 initial_gain = 0;
1496 	static u8 initialized, force_write;
1497 	static u32 reset_cnt;
1498 
1499 	if (dm_digtable.dig_algorithm_switch) {
1500 		initialized = 0;
1501 		reset_cnt = 0;
1502 	}
1503 
1504 	if (rtllib_act_scanning(priv->rtllib, true) == true) {
1505 		force_write = 1;
1506 		return;
1507 	}
1508 
1509 	if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) {
1510 		if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) {
1511 			long gain_range = dm_digtable.rssi_val + 10 -
1512 					  dm_digtable.backoff_val;
1513 			gain_range = clamp_t(long, gain_range,
1514 					     dm_digtable.rx_gain_range_min,
1515 					     dm_digtable.rx_gain_range_max);
1516 			dm_digtable.cur_ig_value = gain_range;
1517 		} else {
1518 			if (dm_digtable.cur_ig_value == 0)
1519 				dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
1520 			else
1521 				dm_digtable.cur_ig_value = dm_digtable.pre_ig_value;
1522 		}
1523 	} else {
1524 		dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
1525 		dm_digtable.pre_ig_value = 0;
1526 	}
1527 
1528 	if (priv->reset_count != reset_cnt) {
1529 		force_write = 1;
1530 		reset_cnt = priv->reset_count;
1531 	}
1532 
1533 	if (dm_digtable.pre_ig_value != rtl92e_readb(dev, rOFDM0_XAAGCCore1))
1534 		force_write = 1;
1535 
1536 	if ((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value)
1537 	    || !initialized || force_write) {
1538 		initial_gain = (u8)dm_digtable.cur_ig_value;
1539 		rtl92e_writeb(dev, rOFDM0_XAAGCCore1, initial_gain);
1540 		rtl92e_writeb(dev, rOFDM0_XBAGCCore1, initial_gain);
1541 		rtl92e_writeb(dev, rOFDM0_XCAGCCore1, initial_gain);
1542 		rtl92e_writeb(dev, rOFDM0_XDAGCCore1, initial_gain);
1543 		dm_digtable.pre_ig_value = dm_digtable.cur_ig_value;
1544 		initialized = 1;
1545 		force_write = 0;
1546 	}
1547 }
1548 
1549 static void _rtl92e_dm_pd_th(struct net_device *dev)
1550 {
1551 	struct r8192_priv *priv = rtllib_priv(dev);
1552 	static u8 initialized, force_write;
1553 	static u32 reset_cnt;
1554 
1555 	if (dm_digtable.dig_algorithm_switch) {
1556 		initialized = 0;
1557 		reset_cnt = 0;
1558 	}
1559 
1560 	if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) {
1561 		if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) {
1562 			if (dm_digtable.rssi_val >=
1563 			    dm_digtable.rssi_high_power_highthresh)
1564 				dm_digtable.curpd_thstate =
1565 							DIG_PD_AT_HIGH_POWER;
1566 			else if (dm_digtable.rssi_val <=
1567 				 dm_digtable.rssi_low_thresh)
1568 				dm_digtable.curpd_thstate =
1569 							DIG_PD_AT_LOW_POWER;
1570 			else if ((dm_digtable.rssi_val >=
1571 				  dm_digtable.rssi_high_thresh) &&
1572 				 (dm_digtable.rssi_val <
1573 				  dm_digtable.rssi_high_power_lowthresh))
1574 				dm_digtable.curpd_thstate =
1575 							DIG_PD_AT_NORMAL_POWER;
1576 			else
1577 				dm_digtable.curpd_thstate =
1578 						dm_digtable.prepd_thstate;
1579 		} else {
1580 			dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
1581 		}
1582 	} else {
1583 		dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
1584 	}
1585 
1586 	if (priv->reset_count != reset_cnt) {
1587 		force_write = 1;
1588 		reset_cnt = priv->reset_count;
1589 	}
1590 
1591 	if ((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) ||
1592 	    (initialized <= 3) || force_write) {
1593 		if (dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER) {
1594 			if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1595 				rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x00);
1596 			else
1597 				rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x42);
1598 		} else if (dm_digtable.curpd_thstate ==
1599 			   DIG_PD_AT_NORMAL_POWER) {
1600 			if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1601 				rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x20);
1602 			else
1603 				rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x44);
1604 		} else if (dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER) {
1605 			if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1606 				rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x10);
1607 			else
1608 				rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x43);
1609 		}
1610 		dm_digtable.prepd_thstate = dm_digtable.curpd_thstate;
1611 		if (initialized <= 3)
1612 			initialized++;
1613 		force_write = 0;
1614 	}
1615 }
1616 
1617 static void _rtl92e_dm_cs_ratio(struct net_device *dev)
1618 {
1619 	struct r8192_priv *priv = rtllib_priv(dev);
1620 	static u8 initialized, force_write;
1621 	static u32 reset_cnt;
1622 
1623 	if (dm_digtable.dig_algorithm_switch) {
1624 		initialized = 0;
1625 		reset_cnt = 0;
1626 	}
1627 
1628 	if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) {
1629 		if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) {
1630 			if (dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh)
1631 				dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
1632 			else if (dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh)
1633 				dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER;
1634 			else
1635 				dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state;
1636 		} else {
1637 			dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
1638 		}
1639 	} else {
1640 		dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
1641 	}
1642 
1643 	if (priv->reset_count != reset_cnt) {
1644 		force_write = 1;
1645 		reset_cnt = priv->reset_count;
1646 	}
1647 
1648 
1649 	if ((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
1650 	    !initialized || force_write) {
1651 		if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER)
1652 			rtl92e_writeb(dev, 0xa0a, 0x08);
1653 		else if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER)
1654 			rtl92e_writeb(dev, 0xa0a, 0xcd);
1655 		dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state;
1656 		initialized = 1;
1657 		force_write = 0;
1658 	}
1659 }
1660 
1661 void rtl92e_dm_init_edca_turbo(struct net_device *dev)
1662 {
1663 	struct r8192_priv *priv = rtllib_priv(dev);
1664 
1665 	priv->bcurrent_turbo_EDCA = false;
1666 	priv->rtllib->bis_any_nonbepkts = false;
1667 	priv->bis_cur_rdlstate = false;
1668 }
1669 
1670 static void _rtl92e_dm_check_edca_turbo(struct net_device *dev)
1671 {
1672 	struct r8192_priv *priv = rtllib_priv(dev);
1673 	struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo;
1674 
1675 	static unsigned long lastTxOkCnt;
1676 	static unsigned long lastRxOkCnt;
1677 	unsigned long curTxOkCnt = 0;
1678 	unsigned long curRxOkCnt = 0;
1679 
1680 	if (priv->rtllib->iw_mode == IW_MODE_ADHOC)
1681 		goto dm_CheckEdcaTurbo_EXIT;
1682 	if (priv->rtllib->state != RTLLIB_LINKED)
1683 		goto dm_CheckEdcaTurbo_EXIT;
1684 	if (priv->rtllib->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO)
1685 		goto dm_CheckEdcaTurbo_EXIT;
1686 
1687 	if (!priv->rtllib->bis_any_nonbepkts) {
1688 		curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
1689 		curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
1690 		if (pHTInfo->IOTAction & HT_IOT_ACT_EDCA_BIAS_ON_RX) {
1691 			if (curTxOkCnt > 4*curRxOkCnt) {
1692 				if (priv->bis_cur_rdlstate ||
1693 				    !priv->bcurrent_turbo_EDCA) {
1694 					rtl92e_writel(dev, EDCAPARA_BE,
1695 						      edca_setting_UL[pHTInfo->IOTPeer]);
1696 					priv->bis_cur_rdlstate = false;
1697 				}
1698 			} else {
1699 				if (!priv->bis_cur_rdlstate ||
1700 				    !priv->bcurrent_turbo_EDCA) {
1701 					if (priv->rtllib->mode == WIRELESS_MODE_G)
1702 						rtl92e_writel(dev, EDCAPARA_BE,
1703 							      edca_setting_DL_GMode[pHTInfo->IOTPeer]);
1704 					else
1705 						rtl92e_writel(dev, EDCAPARA_BE,
1706 							      edca_setting_DL[pHTInfo->IOTPeer]);
1707 					priv->bis_cur_rdlstate = true;
1708 				}
1709 			}
1710 			priv->bcurrent_turbo_EDCA = true;
1711 		} else {
1712 			if (curRxOkCnt > 4*curTxOkCnt) {
1713 				if (!priv->bis_cur_rdlstate ||
1714 				    !priv->bcurrent_turbo_EDCA) {
1715 					if (priv->rtllib->mode == WIRELESS_MODE_G)
1716 						rtl92e_writel(dev, EDCAPARA_BE,
1717 							      edca_setting_DL_GMode[pHTInfo->IOTPeer]);
1718 					else
1719 						rtl92e_writel(dev, EDCAPARA_BE,
1720 							      edca_setting_DL[pHTInfo->IOTPeer]);
1721 					priv->bis_cur_rdlstate = true;
1722 				}
1723 			} else {
1724 				if (priv->bis_cur_rdlstate ||
1725 				    !priv->bcurrent_turbo_EDCA) {
1726 					rtl92e_writel(dev, EDCAPARA_BE,
1727 						      edca_setting_UL[pHTInfo->IOTPeer]);
1728 					priv->bis_cur_rdlstate = false;
1729 				}
1730 
1731 			}
1732 
1733 			priv->bcurrent_turbo_EDCA = true;
1734 		}
1735 	} else {
1736 		 if (priv->bcurrent_turbo_EDCA) {
1737 			u8 tmp = AC0_BE;
1738 
1739 			priv->rtllib->SetHwRegHandler(dev, HW_VAR_AC_PARAM,
1740 						      (u8 *)(&tmp));
1741 			priv->bcurrent_turbo_EDCA = false;
1742 		}
1743 	}
1744 
1745 
1746 dm_CheckEdcaTurbo_EXIT:
1747 	priv->rtllib->bis_any_nonbepkts = false;
1748 	lastTxOkCnt = priv->stats.txbytesunicast;
1749 	lastRxOkCnt = priv->stats.rxbytesunicast;
1750 }
1751 
1752 static void _rtl92e_dm_init_cts_to_self(struct net_device *dev)
1753 {
1754 	struct r8192_priv *priv = rtllib_priv((struct net_device *)dev);
1755 
1756 	priv->rtllib->bCTSToSelfEnable = true;
1757 }
1758 
1759 static void _rtl92e_dm_cts_to_self(struct net_device *dev)
1760 {
1761 	struct r8192_priv *priv = rtllib_priv((struct net_device *)dev);
1762 	struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo;
1763 	static unsigned long lastTxOkCnt;
1764 	static unsigned long lastRxOkCnt;
1765 	unsigned long curTxOkCnt = 0;
1766 	unsigned long curRxOkCnt = 0;
1767 
1768 	if (priv->rtllib->bCTSToSelfEnable != true) {
1769 		pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
1770 		return;
1771 	}
1772 	if (pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) {
1773 		curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
1774 		curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
1775 		if (curRxOkCnt > 4*curTxOkCnt)
1776 			pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
1777 		else
1778 			pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
1779 
1780 		lastTxOkCnt = priv->stats.txbytesunicast;
1781 		lastRxOkCnt = priv->stats.rxbytesunicast;
1782 	}
1783 }
1784 
1785 
1786 static void _rtl92e_dm_init_wa_broadcom_iot(struct net_device *dev)
1787 {
1788 	struct r8192_priv *priv = rtllib_priv((struct net_device *)dev);
1789 	struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo;
1790 
1791 	pHTInfo->bWAIotBroadcom = false;
1792 	pHTInfo->WAIotTH = WAIotTHVal;
1793 }
1794 
1795 static void _rtl92e_dm_check_rf_ctrl_gpio(void *data)
1796 {
1797 	struct r8192_priv *priv = container_of_dwork_rsl(data,
1798 				  struct r8192_priv, gpio_change_rf_wq);
1799 	struct net_device *dev = priv->rtllib->dev;
1800 	u8 tmp1byte;
1801 	enum rt_rf_power_state eRfPowerStateToSet;
1802 	bool bActuallySet = false;
1803 	char *argv[3];
1804 	static char const RadioPowerPath[] = "/etc/acpi/events/RadioPower.sh";
1805 	static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin",
1806 			       NULL};
1807 
1808 	bActuallySet = false;
1809 
1810 	if ((priv->up_first_time == 1) || (priv->being_init_adapter))
1811 		return;
1812 
1813 	if (priv->bfirst_after_down) {
1814 		priv->bfirst_after_down = true;
1815 		return;
1816 	}
1817 
1818 	tmp1byte = rtl92e_readb(dev, GPI);
1819 
1820 	eRfPowerStateToSet = (tmp1byte&BIT1) ?  eRfOn : eRfOff;
1821 
1822 	if (priv->bHwRadioOff && (eRfPowerStateToSet == eRfOn)) {
1823 		RT_TRACE(COMP_RF, "gpiochangeRF  - HW Radio ON\n");
1824 		netdev_info(dev, "gpiochangeRF  - HW Radio ON\n");
1825 		priv->bHwRadioOff = false;
1826 		bActuallySet = true;
1827 	} else if (!priv->bHwRadioOff && (eRfPowerStateToSet == eRfOff)) {
1828 		RT_TRACE(COMP_RF, "gpiochangeRF  - HW Radio OFF\n");
1829 		netdev_info(dev, "gpiochangeRF  - HW Radio OFF\n");
1830 		priv->bHwRadioOff = true;
1831 		bActuallySet = true;
1832 	}
1833 
1834 	if (bActuallySet) {
1835 		mdelay(1000);
1836 		priv->bHwRfOffAction = 1;
1837 		rtl92e_set_rf_state(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
1838 		if (priv->bHwRadioOff)
1839 			argv[1] = "RFOFF";
1840 		else
1841 			argv[1] = "RFON";
1842 
1843 		argv[0] = (char *)RadioPowerPath;
1844 		argv[2] = NULL;
1845 		call_usermodehelper(RadioPowerPath, argv, envp, UMH_WAIT_PROC);
1846 	}
1847 }
1848 
1849 void rtl92e_dm_rf_pathcheck_wq(void *data)
1850 {
1851 	struct r8192_priv *priv = container_of_dwork_rsl(data,
1852 				  struct r8192_priv,
1853 				  rfpath_check_wq);
1854 	struct net_device *dev = priv->rtllib->dev;
1855 	u8 rfpath, i;
1856 
1857 	rfpath = rtl92e_readb(dev, 0xc04);
1858 
1859 	for (i = 0; i < RF90_PATH_MAX; i++) {
1860 		if (rfpath & (0x01<<i))
1861 			priv->brfpath_rxenable[i] = true;
1862 		else
1863 			priv->brfpath_rxenable[i] = false;
1864 	}
1865 	if (!DM_RxPathSelTable.Enable)
1866 		return;
1867 
1868 	_rtl92e_dm_rx_path_sel_byrssi(dev);
1869 }
1870 
1871 static void _rtl92e_dm_init_rx_path_selection(struct net_device *dev)
1872 {
1873 	u8 i;
1874 	struct r8192_priv *priv = rtllib_priv(dev);
1875 
1876 	DM_RxPathSelTable.Enable = 1;
1877 	DM_RxPathSelTable.SS_TH_low = RxPathSelection_SS_TH_low;
1878 	DM_RxPathSelTable.diff_TH = RxPathSelection_diff_TH;
1879 	if (priv->CustomerID == RT_CID_819x_Netcore)
1880 		DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;
1881 	else
1882 		DM_RxPathSelTable.cck_method = CCK_Rx_Version_1;
1883 	DM_RxPathSelTable.disabledRF = 0;
1884 	for (i = 0; i < 4; i++) {
1885 		DM_RxPathSelTable.rf_rssi[i] = 50;
1886 		DM_RxPathSelTable.cck_pwdb_sta[i] = -64;
1887 		DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
1888 	}
1889 }
1890 
1891 #define PWDB_IN_RANGE	((cur_cck_pwdb < tmp_cck_max_pwdb) &&	\
1892 			(cur_cck_pwdb > tmp_cck_sec_pwdb))
1893 
1894 static void _rtl92e_dm_rx_path_sel_byrssi(struct net_device *dev)
1895 {
1896 	struct r8192_priv *priv = rtllib_priv(dev);
1897 	u8 i, max_rssi_index = 0, min_rssi_index = 0;
1898 	u8 sec_rssi_index = 0, rf_num = 0;
1899 	u8 tmp_max_rssi = 0, tmp_min_rssi = 0, tmp_sec_rssi = 0;
1900 	u8 cck_default_Rx = 0x2;
1901 	u8 cck_optional_Rx = 0x3;
1902 	long tmp_cck_max_pwdb = 0, tmp_cck_min_pwdb = 0, tmp_cck_sec_pwdb = 0;
1903 	u8 cck_rx_ver2_max_index = 0;
1904 	u8 cck_rx_ver2_sec_index = 0;
1905 	u8 cur_rf_rssi;
1906 	long cur_cck_pwdb;
1907 	static u8 disabled_rf_cnt, cck_Rx_Path_initialized;
1908 	u8 update_cck_rx_path;
1909 
1910 	if (priv->rf_type != RF_2T4R)
1911 		return;
1912 
1913 	if (!cck_Rx_Path_initialized) {
1914 		DM_RxPathSelTable.cck_Rx_path = (rtl92e_readb(dev, 0xa07)&0xf);
1915 		cck_Rx_Path_initialized = 1;
1916 	}
1917 
1918 	DM_RxPathSelTable.disabledRF = 0xf;
1919 	DM_RxPathSelTable.disabledRF &= ~(rtl92e_readb(dev, 0xc04));
1920 
1921 	if (priv->rtllib->mode == WIRELESS_MODE_B)
1922 		DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;
1923 
1924 	for (i = 0; i < RF90_PATH_MAX; i++) {
1925 		DM_RxPathSelTable.rf_rssi[i] = priv->stats.rx_rssi_percentage[i];
1926 
1927 		if (priv->brfpath_rxenable[i]) {
1928 			rf_num++;
1929 			cur_rf_rssi = DM_RxPathSelTable.rf_rssi[i];
1930 
1931 			if (rf_num == 1) {
1932 				max_rssi_index = min_rssi_index = sec_rssi_index = i;
1933 				tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi;
1934 			} else if (rf_num == 2) {
1935 				if (cur_rf_rssi >= tmp_max_rssi) {
1936 					tmp_max_rssi = cur_rf_rssi;
1937 					max_rssi_index = i;
1938 				} else {
1939 					tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi;
1940 					sec_rssi_index = min_rssi_index = i;
1941 				}
1942 			} else {
1943 				if (cur_rf_rssi > tmp_max_rssi) {
1944 					tmp_sec_rssi = tmp_max_rssi;
1945 					sec_rssi_index = max_rssi_index;
1946 					tmp_max_rssi = cur_rf_rssi;
1947 					max_rssi_index = i;
1948 				} else if (cur_rf_rssi == tmp_max_rssi) {
1949 					tmp_sec_rssi = cur_rf_rssi;
1950 					sec_rssi_index = i;
1951 				} else if ((cur_rf_rssi < tmp_max_rssi) &&
1952 					   (cur_rf_rssi > tmp_sec_rssi)) {
1953 					tmp_sec_rssi = cur_rf_rssi;
1954 					sec_rssi_index = i;
1955 				} else if (cur_rf_rssi == tmp_sec_rssi) {
1956 					if (tmp_sec_rssi == tmp_min_rssi) {
1957 						tmp_sec_rssi = cur_rf_rssi;
1958 						sec_rssi_index = i;
1959 					}
1960 				} else if ((cur_rf_rssi < tmp_sec_rssi) &&
1961 					   (cur_rf_rssi > tmp_min_rssi)) {
1962 					;
1963 				} else if (cur_rf_rssi == tmp_min_rssi) {
1964 					if (tmp_sec_rssi == tmp_min_rssi) {
1965 						tmp_min_rssi = cur_rf_rssi;
1966 						min_rssi_index = i;
1967 					}
1968 				} else if (cur_rf_rssi < tmp_min_rssi) {
1969 					tmp_min_rssi = cur_rf_rssi;
1970 					min_rssi_index = i;
1971 				}
1972 			}
1973 		}
1974 	}
1975 
1976 	rf_num = 0;
1977 	if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) {
1978 		for (i = 0; i < RF90_PATH_MAX; i++) {
1979 			if (priv->brfpath_rxenable[i]) {
1980 				rf_num++;
1981 				cur_cck_pwdb =
1982 					 DM_RxPathSelTable.cck_pwdb_sta[i];
1983 
1984 				if (rf_num == 1) {
1985 					cck_rx_ver2_max_index = i;
1986 					cck_rx_ver2_sec_index = i;
1987 					tmp_cck_max_pwdb = cur_cck_pwdb;
1988 					tmp_cck_min_pwdb = cur_cck_pwdb;
1989 					tmp_cck_sec_pwdb = cur_cck_pwdb;
1990 				} else if (rf_num == 2) {
1991 					if (cur_cck_pwdb >= tmp_cck_max_pwdb) {
1992 						tmp_cck_max_pwdb = cur_cck_pwdb;
1993 						cck_rx_ver2_max_index = i;
1994 					} else {
1995 						tmp_cck_sec_pwdb = cur_cck_pwdb;
1996 						tmp_cck_min_pwdb = cur_cck_pwdb;
1997 						cck_rx_ver2_sec_index = i;
1998 					}
1999 				} else {
2000 					if (cur_cck_pwdb > tmp_cck_max_pwdb) {
2001 						tmp_cck_sec_pwdb =
2002 							 tmp_cck_max_pwdb;
2003 						cck_rx_ver2_sec_index =
2004 							 cck_rx_ver2_max_index;
2005 						tmp_cck_max_pwdb = cur_cck_pwdb;
2006 						cck_rx_ver2_max_index = i;
2007 					} else if (cur_cck_pwdb ==
2008 						   tmp_cck_max_pwdb) {
2009 						tmp_cck_sec_pwdb = cur_cck_pwdb;
2010 						cck_rx_ver2_sec_index = i;
2011 					} else if (PWDB_IN_RANGE) {
2012 						tmp_cck_sec_pwdb = cur_cck_pwdb;
2013 						cck_rx_ver2_sec_index = i;
2014 					} else if (cur_cck_pwdb ==
2015 						   tmp_cck_sec_pwdb) {
2016 						if (tmp_cck_sec_pwdb ==
2017 						    tmp_cck_min_pwdb) {
2018 							tmp_cck_sec_pwdb =
2019 								 cur_cck_pwdb;
2020 							cck_rx_ver2_sec_index =
2021 								 i;
2022 						}
2023 					} else if ((cur_cck_pwdb < tmp_cck_sec_pwdb) &&
2024 						   (cur_cck_pwdb > tmp_cck_min_pwdb)) {
2025 						;
2026 					} else if (cur_cck_pwdb == tmp_cck_min_pwdb) {
2027 						if (tmp_cck_sec_pwdb == tmp_cck_min_pwdb)
2028 							tmp_cck_min_pwdb = cur_cck_pwdb;
2029 					} else if (cur_cck_pwdb < tmp_cck_min_pwdb) {
2030 						tmp_cck_min_pwdb = cur_cck_pwdb;
2031 					}
2032 				}
2033 
2034 			}
2035 		}
2036 	}
2037 
2038 	update_cck_rx_path = 0;
2039 	if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) {
2040 		cck_default_Rx = cck_rx_ver2_max_index;
2041 		cck_optional_Rx = cck_rx_ver2_sec_index;
2042 		if (tmp_cck_max_pwdb != -64)
2043 			update_cck_rx_path = 1;
2044 	}
2045 
2046 	if (tmp_min_rssi < DM_RxPathSelTable.SS_TH_low && disabled_rf_cnt < 2) {
2047 		if ((tmp_max_rssi - tmp_min_rssi) >=
2048 		     DM_RxPathSelTable.diff_TH) {
2049 			DM_RxPathSelTable.rf_enable_rssi_th[min_rssi_index] =
2050 				 tmp_max_rssi+5;
2051 			rtl92e_set_bb_reg(dev, rOFDM0_TRxPathEnable,
2052 					  0x1<<min_rssi_index, 0x0);
2053 			rtl92e_set_bb_reg(dev, rOFDM1_TRxPathEnable,
2054 					  0x1<<min_rssi_index, 0x0);
2055 			disabled_rf_cnt++;
2056 		}
2057 		if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_1) {
2058 			cck_default_Rx = max_rssi_index;
2059 			cck_optional_Rx = sec_rssi_index;
2060 			if (tmp_max_rssi)
2061 				update_cck_rx_path = 1;
2062 		}
2063 	}
2064 
2065 	if (update_cck_rx_path) {
2066 		DM_RxPathSelTable.cck_Rx_path = (cck_default_Rx<<2) |
2067 						(cck_optional_Rx);
2068 		rtl92e_set_bb_reg(dev, rCCK0_AFESetting, 0x0f000000,
2069 				  DM_RxPathSelTable.cck_Rx_path);
2070 	}
2071 
2072 	if (DM_RxPathSelTable.disabledRF) {
2073 		for (i = 0; i < 4; i++) {
2074 			if ((DM_RxPathSelTable.disabledRF>>i) & 0x1) {
2075 				if (tmp_max_rssi >=
2076 				    DM_RxPathSelTable.rf_enable_rssi_th[i]) {
2077 					rtl92e_set_bb_reg(dev,
2078 							  rOFDM0_TRxPathEnable,
2079 							  0x1 << i, 0x1);
2080 					rtl92e_set_bb_reg(dev,
2081 							  rOFDM1_TRxPathEnable,
2082 							  0x1 << i, 0x1);
2083 					DM_RxPathSelTable.rf_enable_rssi_th[i]
2084 						 = 100;
2085 					disabled_rf_cnt--;
2086 				}
2087 			}
2088 		}
2089 	}
2090 }
2091 
2092 static void _rtl92e_dm_check_rx_path_selection(struct net_device *dev)
2093 {
2094 	struct r8192_priv *priv = rtllib_priv(dev);
2095 
2096 	schedule_delayed_work(&priv->rfpath_check_wq, 0);
2097 }
2098 
2099 
2100 static void _rtl92e_dm_init_fsync(struct net_device *dev)
2101 {
2102 	struct r8192_priv *priv = rtllib_priv(dev);
2103 
2104 	priv->rtllib->fsync_time_interval = 500;
2105 	priv->rtllib->fsync_rate_bitmap = 0x0f000800;
2106 	priv->rtllib->fsync_rssi_threshold = 30;
2107 	priv->rtllib->bfsync_enable = false;
2108 	priv->rtllib->fsync_multiple_timeinterval = 3;
2109 	priv->rtllib->fsync_firstdiff_ratethreshold = 100;
2110 	priv->rtllib->fsync_seconddiff_ratethreshold = 200;
2111 	priv->rtllib->fsync_state = Default_Fsync;
2112 	priv->framesyncMonitor = 1;
2113 
2114 	timer_setup(&priv->fsync_timer, _rtl92e_dm_fsync_timer_callback, 0);
2115 }
2116 
2117 
2118 static void _rtl92e_dm_deinit_fsync(struct net_device *dev)
2119 {
2120 	struct r8192_priv *priv = rtllib_priv(dev);
2121 
2122 	del_timer_sync(&priv->fsync_timer);
2123 }
2124 
2125 static void _rtl92e_dm_fsync_timer_callback(struct timer_list *t)
2126 {
2127 	struct r8192_priv *priv = from_timer(priv, t, fsync_timer);
2128 	struct net_device *dev = priv->rtllib->dev;
2129 	u32 rate_index, rate_count = 0, rate_count_diff = 0;
2130 	bool		bSwitchFromCountDiff = false;
2131 	bool		bDoubleTimeInterval = false;
2132 
2133 	if (priv->rtllib->state == RTLLIB_LINKED &&
2134 	    priv->rtllib->bfsync_enable &&
2135 	    (priv->rtllib->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC)) {
2136 		u32 rate_bitmap;
2137 
2138 		for (rate_index = 0; rate_index <= 27; rate_index++) {
2139 			rate_bitmap  = 1 << rate_index;
2140 			if (priv->rtllib->fsync_rate_bitmap &  rate_bitmap)
2141 				rate_count +=
2142 				   priv->stats.received_rate_histogram[1]
2143 				   [rate_index];
2144 		}
2145 
2146 		if (rate_count < priv->rate_record)
2147 			rate_count_diff = 0xffffffff - rate_count +
2148 					  priv->rate_record;
2149 		else
2150 			rate_count_diff = rate_count - priv->rate_record;
2151 		if (rate_count_diff < priv->rateCountDiffRecord) {
2152 
2153 			u32 DiffNum = priv->rateCountDiffRecord -
2154 				      rate_count_diff;
2155 			if (DiffNum >=
2156 			    priv->rtllib->fsync_seconddiff_ratethreshold)
2157 				priv->ContinueDiffCount++;
2158 			else
2159 				priv->ContinueDiffCount = 0;
2160 
2161 			if (priv->ContinueDiffCount >= 2) {
2162 				bSwitchFromCountDiff = true;
2163 				priv->ContinueDiffCount = 0;
2164 			}
2165 		} else {
2166 			priv->ContinueDiffCount = 0;
2167 		}
2168 
2169 		if (rate_count_diff <=
2170 		    priv->rtllib->fsync_firstdiff_ratethreshold) {
2171 			bSwitchFromCountDiff = true;
2172 			priv->ContinueDiffCount = 0;
2173 		}
2174 		priv->rate_record = rate_count;
2175 		priv->rateCountDiffRecord = rate_count_diff;
2176 		RT_TRACE(COMP_HALDM,
2177 			 "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n",
2178 			 priv->rate_record, rate_count, rate_count_diff,
2179 			 priv->bswitch_fsync);
2180 		if (priv->undecorated_smoothed_pwdb >
2181 		    priv->rtllib->fsync_rssi_threshold &&
2182 		    bSwitchFromCountDiff) {
2183 			bDoubleTimeInterval = true;
2184 			priv->bswitch_fsync = !priv->bswitch_fsync;
2185 			if (priv->bswitch_fsync) {
2186 				rtl92e_writeb(dev, 0xC36, 0x1c);
2187 				rtl92e_writeb(dev, 0xC3e, 0x90);
2188 			} else {
2189 				rtl92e_writeb(dev, 0xC36, 0x5c);
2190 				rtl92e_writeb(dev, 0xC3e, 0x96);
2191 			}
2192 		} else if (priv->undecorated_smoothed_pwdb <=
2193 			   priv->rtllib->fsync_rssi_threshold) {
2194 			if (priv->bswitch_fsync) {
2195 				priv->bswitch_fsync  = false;
2196 				rtl92e_writeb(dev, 0xC36, 0x5c);
2197 				rtl92e_writeb(dev, 0xC3e, 0x96);
2198 			}
2199 		}
2200 		if (bDoubleTimeInterval) {
2201 			if (timer_pending(&priv->fsync_timer))
2202 				del_timer_sync(&priv->fsync_timer);
2203 			priv->fsync_timer.expires = jiffies +
2204 				 msecs_to_jiffies(priv->rtllib->fsync_time_interval *
2205 				 priv->rtllib->fsync_multiple_timeinterval);
2206 			add_timer(&priv->fsync_timer);
2207 		} else {
2208 			if (timer_pending(&priv->fsync_timer))
2209 				del_timer_sync(&priv->fsync_timer);
2210 			priv->fsync_timer.expires = jiffies +
2211 				 msecs_to_jiffies(priv->rtllib->fsync_time_interval);
2212 			add_timer(&priv->fsync_timer);
2213 		}
2214 	} else {
2215 		if (priv->bswitch_fsync) {
2216 			priv->bswitch_fsync  = false;
2217 			rtl92e_writeb(dev, 0xC36, 0x5c);
2218 			rtl92e_writeb(dev, 0xC3e, 0x96);
2219 		}
2220 		priv->ContinueDiffCount = 0;
2221 		rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c52cd);
2222 	}
2223 	RT_TRACE(COMP_HALDM, "ContinueDiffCount %d\n", priv->ContinueDiffCount);
2224 	RT_TRACE(COMP_HALDM,
2225 		 "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n",
2226 		 priv->rate_record, rate_count, rate_count_diff,
2227 		 priv->bswitch_fsync);
2228 }
2229 
2230 static void _rtl92e_dm_start_hw_fsync(struct net_device *dev)
2231 {
2232 	u8 rf_timing = 0x77;
2233 	struct r8192_priv *priv = rtllib_priv(dev);
2234 
2235 	RT_TRACE(COMP_HALDM, "%s\n", __func__);
2236 	rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c12cf);
2237 	priv->rtllib->SetHwRegHandler(dev, HW_VAR_RF_TIMING,
2238 				      (u8 *)(&rf_timing));
2239 	rtl92e_writeb(dev, 0xc3b, 0x41);
2240 }
2241 
2242 static void _rtl92e_dm_end_hw_fsync(struct net_device *dev)
2243 {
2244 	u8 rf_timing = 0xaa;
2245 	struct r8192_priv *priv = rtllib_priv(dev);
2246 
2247 	RT_TRACE(COMP_HALDM, "%s\n", __func__);
2248 	rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c52cd);
2249 	priv->rtllib->SetHwRegHandler(dev, HW_VAR_RF_TIMING, (u8 *)
2250 				     (&rf_timing));
2251 	rtl92e_writeb(dev, 0xc3b, 0x49);
2252 }
2253 
2254 static void _rtl92e_dm_end_sw_fsync(struct net_device *dev)
2255 {
2256 	struct r8192_priv *priv = rtllib_priv(dev);
2257 
2258 	RT_TRACE(COMP_HALDM, "%s\n", __func__);
2259 	del_timer_sync(&(priv->fsync_timer));
2260 
2261 	if (priv->bswitch_fsync) {
2262 		priv->bswitch_fsync  = false;
2263 
2264 		rtl92e_writeb(dev, 0xC36, 0x5c);
2265 
2266 		rtl92e_writeb(dev, 0xC3e, 0x96);
2267 	}
2268 
2269 	priv->ContinueDiffCount = 0;
2270 	rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c52cd);
2271 }
2272 
2273 static void _rtl92e_dm_start_sw_fsync(struct net_device *dev)
2274 {
2275 	struct r8192_priv *priv = rtllib_priv(dev);
2276 	u32			rateIndex;
2277 	u32			rateBitmap;
2278 
2279 	RT_TRACE(COMP_HALDM, "%s\n", __func__);
2280 	priv->rate_record = 0;
2281 	priv->ContinueDiffCount = 0;
2282 	priv->rateCountDiffRecord = 0;
2283 	priv->bswitch_fsync  = false;
2284 
2285 	if (priv->rtllib->mode == WIRELESS_MODE_N_24G) {
2286 		priv->rtllib->fsync_firstdiff_ratethreshold = 600;
2287 		priv->rtllib->fsync_seconddiff_ratethreshold = 0xffff;
2288 	} else {
2289 		priv->rtllib->fsync_firstdiff_ratethreshold = 200;
2290 		priv->rtllib->fsync_seconddiff_ratethreshold = 200;
2291 	}
2292 	for (rateIndex = 0; rateIndex <= 27; rateIndex++) {
2293 		rateBitmap  = 1 << rateIndex;
2294 		if (priv->rtllib->fsync_rate_bitmap & rateBitmap)
2295 			priv->rate_record +=
2296 				 priv->stats.received_rate_histogram[1]
2297 				[rateIndex];
2298 	}
2299 	if (timer_pending(&priv->fsync_timer))
2300 		del_timer_sync(&priv->fsync_timer);
2301 	priv->fsync_timer.expires = jiffies +
2302 				    msecs_to_jiffies(priv->rtllib->fsync_time_interval);
2303 	add_timer(&priv->fsync_timer);
2304 
2305 	rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c12cd);
2306 
2307 }
2308 
2309 static void _rtl92e_dm_check_fsync(struct net_device *dev)
2310 {
2311 #define	RegC38_Default			0
2312 #define	RegC38_NonFsync_Other_AP	1
2313 #define	RegC38_Fsync_AP_BCM		2
2314 	struct r8192_priv *priv = rtllib_priv(dev);
2315 	static u8 reg_c38_State = RegC38_Default;
2316 	static u32 reset_cnt;
2317 
2318 	RT_TRACE(COMP_HALDM,
2319 		 "RSSI %d TimeInterval %d MultipleTimeInterval %d\n",
2320 		 priv->rtllib->fsync_rssi_threshold,
2321 		 priv->rtllib->fsync_time_interval,
2322 		 priv->rtllib->fsync_multiple_timeinterval);
2323 	RT_TRACE(COMP_HALDM,
2324 		 "RateBitmap 0x%x FirstDiffRateThreshold %d SecondDiffRateThreshold %d\n",
2325 		 priv->rtllib->fsync_rate_bitmap,
2326 		 priv->rtllib->fsync_firstdiff_ratethreshold,
2327 		 priv->rtllib->fsync_seconddiff_ratethreshold);
2328 
2329 	if (priv->rtllib->state == RTLLIB_LINKED &&
2330 	    priv->rtllib->pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) {
2331 		if (priv->rtllib->bfsync_enable == 0) {
2332 			switch (priv->rtllib->fsync_state) {
2333 			case Default_Fsync:
2334 				_rtl92e_dm_start_hw_fsync(dev);
2335 				priv->rtllib->fsync_state = HW_Fsync;
2336 				break;
2337 			case SW_Fsync:
2338 				_rtl92e_dm_end_sw_fsync(dev);
2339 				_rtl92e_dm_start_hw_fsync(dev);
2340 				priv->rtllib->fsync_state = HW_Fsync;
2341 				break;
2342 			case HW_Fsync:
2343 			default:
2344 				break;
2345 			}
2346 		} else {
2347 			switch (priv->rtllib->fsync_state) {
2348 			case Default_Fsync:
2349 				_rtl92e_dm_start_sw_fsync(dev);
2350 				priv->rtllib->fsync_state = SW_Fsync;
2351 				break;
2352 			case HW_Fsync:
2353 				_rtl92e_dm_end_hw_fsync(dev);
2354 				_rtl92e_dm_start_sw_fsync(dev);
2355 				priv->rtllib->fsync_state = SW_Fsync;
2356 				break;
2357 			case SW_Fsync:
2358 			default:
2359 				break;
2360 
2361 			}
2362 		}
2363 		if (priv->framesyncMonitor) {
2364 			if (reg_c38_State != RegC38_Fsync_AP_BCM) {
2365 				rtl92e_writeb(dev, rOFDM0_RxDetector3, 0x95);
2366 
2367 				reg_c38_State = RegC38_Fsync_AP_BCM;
2368 			}
2369 		}
2370 	} else {
2371 		switch (priv->rtllib->fsync_state) {
2372 		case HW_Fsync:
2373 			_rtl92e_dm_end_hw_fsync(dev);
2374 			priv->rtllib->fsync_state = Default_Fsync;
2375 			break;
2376 		case SW_Fsync:
2377 			_rtl92e_dm_end_sw_fsync(dev);
2378 			priv->rtllib->fsync_state = Default_Fsync;
2379 			break;
2380 		case Default_Fsync:
2381 		default:
2382 			break;
2383 		}
2384 
2385 		if (priv->framesyncMonitor) {
2386 			if (priv->rtllib->state == RTLLIB_LINKED) {
2387 				if (priv->undecorated_smoothed_pwdb <=
2388 				    RegC38_TH) {
2389 					if (reg_c38_State !=
2390 					    RegC38_NonFsync_Other_AP) {
2391 						rtl92e_writeb(dev,
2392 							      rOFDM0_RxDetector3,
2393 							      0x90);
2394 
2395 						reg_c38_State =
2396 						     RegC38_NonFsync_Other_AP;
2397 					}
2398 				} else if (priv->undecorated_smoothed_pwdb >=
2399 					   (RegC38_TH+5)) {
2400 					if (reg_c38_State) {
2401 						rtl92e_writeb(dev,
2402 							rOFDM0_RxDetector3,
2403 							priv->framesync);
2404 						reg_c38_State = RegC38_Default;
2405 					}
2406 				}
2407 			} else {
2408 				if (reg_c38_State) {
2409 					rtl92e_writeb(dev, rOFDM0_RxDetector3,
2410 						      priv->framesync);
2411 					reg_c38_State = RegC38_Default;
2412 				}
2413 			}
2414 		}
2415 	}
2416 	if (priv->framesyncMonitor) {
2417 		if (priv->reset_count != reset_cnt) {
2418 			rtl92e_writeb(dev, rOFDM0_RxDetector3,
2419 				       priv->framesync);
2420 			reg_c38_State = RegC38_Default;
2421 			reset_cnt = priv->reset_count;
2422 		}
2423 	} else {
2424 		if (reg_c38_State) {
2425 			rtl92e_writeb(dev, rOFDM0_RxDetector3,
2426 				       priv->framesync);
2427 			reg_c38_State = RegC38_Default;
2428 		}
2429 	}
2430 }
2431 
2432 /*---------------------------Define function prototype------------------------*/
2433 static void _rtl92e_dm_init_dynamic_tx_power(struct net_device *dev)
2434 {
2435 	struct r8192_priv *priv = rtllib_priv(dev);
2436 
2437 	priv->rtllib->bdynamic_txpower_enable = true;
2438 	priv->bLastDTPFlag_High = false;
2439 	priv->bLastDTPFlag_Low = false;
2440 	priv->bDynamicTxHighPower = false;
2441 	priv->bDynamicTxLowPower = false;
2442 }
2443 
2444 static void _rtl92e_dm_dynamic_tx_power(struct net_device *dev)
2445 {
2446 	struct r8192_priv *priv = rtllib_priv(dev);
2447 	unsigned int txhipower_threshhold = 0;
2448 	unsigned int txlowpower_threshold = 0;
2449 
2450 	if (priv->rtllib->bdynamic_txpower_enable != true) {
2451 		priv->bDynamicTxHighPower = false;
2452 		priv->bDynamicTxLowPower = false;
2453 		return;
2454 	}
2455 	if ((priv->rtllib->pHTInfo->IOTPeer == HT_IOT_PEER_ATHEROS) &&
2456 	    (priv->rtllib->mode == IEEE_G)) {
2457 		txhipower_threshhold = TX_POWER_ATHEROAP_THRESH_HIGH;
2458 		txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW;
2459 	} else {
2460 		txhipower_threshhold = TX_POWER_NEAR_FIELD_THRESH_HIGH;
2461 		txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW;
2462 	}
2463 
2464 	RT_TRACE(COMP_TXAGC, "priv->undecorated_smoothed_pwdb = %ld\n",
2465 		 priv->undecorated_smoothed_pwdb);
2466 
2467 	if (priv->rtllib->state == RTLLIB_LINKED) {
2468 		if (priv->undecorated_smoothed_pwdb >= txhipower_threshhold) {
2469 			priv->bDynamicTxHighPower = true;
2470 			priv->bDynamicTxLowPower = false;
2471 		} else {
2472 			if (priv->undecorated_smoothed_pwdb <
2473 			    txlowpower_threshold && priv->bDynamicTxHighPower)
2474 				priv->bDynamicTxHighPower = false;
2475 			if (priv->undecorated_smoothed_pwdb < 35)
2476 				priv->bDynamicTxLowPower = true;
2477 			else if (priv->undecorated_smoothed_pwdb >= 40)
2478 				priv->bDynamicTxLowPower = false;
2479 		}
2480 	} else {
2481 		priv->bDynamicTxHighPower = false;
2482 		priv->bDynamicTxLowPower = false;
2483 	}
2484 
2485 	if ((priv->bDynamicTxHighPower != priv->bLastDTPFlag_High) ||
2486 	    (priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low)) {
2487 		RT_TRACE(COMP_TXAGC, "SetTxPowerLevel8190()  channel = %d\n",
2488 			 priv->rtllib->current_network.channel);
2489 
2490 		rtl92e_set_tx_power(dev, priv->rtllib->current_network.channel);
2491 	}
2492 	priv->bLastDTPFlag_High = priv->bDynamicTxHighPower;
2493 	priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower;
2494 
2495 }
2496 
2497 static void _rtl92e_dm_check_txrateandretrycount(struct net_device *dev)
2498 {
2499 	struct r8192_priv *priv = rtllib_priv(dev);
2500 	struct rtllib_device *ieee = priv->rtllib;
2501 
2502 	ieee->softmac_stats.CurrentShowTxate = rtl92e_readb(dev,
2503 						 Current_Tx_Rate_Reg);
2504 
2505 	ieee->softmac_stats.last_packet_rate = rtl92e_readb(dev,
2506 						 Initial_Tx_Rate_Reg);
2507 
2508 	ieee->softmac_stats.txretrycount = rtl92e_readl(dev,
2509 						 Tx_Retry_Count_Reg);
2510 }
2511 
2512 static void _rtl92e_dm_send_rssi_to_fw(struct net_device *dev)
2513 {
2514 	struct r8192_priv *priv = rtllib_priv(dev);
2515 
2516 	rtl92e_writeb(dev, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb);
2517 }
2518