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[TX_BB_GAIN_TABLE_LEN] = {
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[CCK_TX_BB_GAIN_TABLE_LEN][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[CCK_TX_BB_GAIN_TABLE_LEN][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_rx_path_sel_table;
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 static	void	_rtl92e_dm_check_tx_power_tracking(struct net_device *dev);
163 
164 static void _rtl92e_dm_dig_init(struct net_device *dev);
165 static void _rtl92e_dm_ctrl_initgain_byrssi(struct net_device *dev);
166 static void _rtl92e_dm_ctrl_initgain_byrssi_driver(struct net_device *dev);
167 static void _rtl92e_dm_initial_gain(struct net_device *dev);
168 static void _rtl92e_dm_pd_th(struct net_device *dev);
169 static void _rtl92e_dm_cs_ratio(struct net_device *dev);
170 
171 static	void _rtl92e_dm_init_cts_to_self(struct net_device *dev);
172 
173 static void _rtl92e_dm_check_edca_turbo(struct net_device *dev);
174 static void _rtl92e_dm_check_rx_path_selection(struct net_device *dev);
175 static void _rtl92e_dm_init_rx_path_selection(struct net_device *dev);
176 static void _rtl92e_dm_rx_path_sel_byrssi(struct net_device *dev);
177 
178 static void _rtl92e_dm_init_fsync(struct net_device *dev);
179 static void _rtl92e_dm_deinit_fsync(struct net_device *dev);
180 
181 static	void _rtl92e_dm_check_txrateandretrycount(struct net_device *dev);
182 static void _rtl92e_dm_check_fsync(struct net_device *dev);
183 static void _rtl92e_dm_check_rf_ctrl_gpio(void *data);
184 static void _rtl92e_dm_fsync_timer_callback(struct timer_list *t);
185 
186 /*---------------------Define local function prototype-----------------------*/
187 
188 static	void	_rtl92e_dm_init_dynamic_tx_power(struct net_device *dev);
189 static void _rtl92e_dm_dynamic_tx_power(struct net_device *dev);
190 
191 static void _rtl92e_dm_send_rssi_to_fw(struct net_device *dev);
192 static void _rtl92e_dm_cts_to_self(struct net_device *dev);
193 /*---------------------------Define function prototype------------------------*/
194 
195 void rtl92e_dm_init(struct net_device *dev)
196 {
197 	struct r8192_priv *priv = rtllib_priv(dev);
198 
199 	priv->undecorated_smoothed_pwdb = -1;
200 
201 	_rtl92e_dm_init_dynamic_tx_power(dev);
202 
203 	rtl92e_init_adaptive_rate(dev);
204 
205 	_rtl92e_dm_dig_init(dev);
206 	rtl92e_dm_init_edca_turbo(dev);
207 	_rtl92e_dm_init_bandwidth_autoswitch(dev);
208 	_rtl92e_dm_init_fsync(dev);
209 	_rtl92e_dm_init_rx_path_selection(dev);
210 	_rtl92e_dm_init_cts_to_self(dev);
211 
212 	INIT_DELAYED_WORK(&priv->gpio_change_rf_wq, (void *)_rtl92e_dm_check_rf_ctrl_gpio);
213 }
214 
215 void rtl92e_dm_deinit(struct net_device *dev)
216 {
217 	_rtl92e_dm_deinit_fsync(dev);
218 }
219 
220 void rtl92e_dm_watchdog(struct net_device *dev)
221 {
222 	struct r8192_priv *priv = rtllib_priv(dev);
223 
224 	if (priv->being_init_adapter)
225 		return;
226 
227 	_rtl92e_dm_check_txrateandretrycount(dev);
228 	_rtl92e_dm_check_edca_turbo(dev);
229 
230 	_rtl92e_dm_check_rate_adaptive(dev);
231 	_rtl92e_dm_dynamic_tx_power(dev);
232 	_rtl92e_dm_check_tx_power_tracking(dev);
233 
234 	_rtl92e_dm_ctrl_initgain_byrssi(dev);
235 	_rtl92e_dm_bandwidth_autoswitch(dev);
236 
237 	_rtl92e_dm_check_rx_path_selection(dev);
238 	_rtl92e_dm_check_fsync(dev);
239 
240 	_rtl92e_dm_send_rssi_to_fw(dev);
241 	_rtl92e_dm_cts_to_self(dev);
242 }
243 
244 void rtl92e_init_adaptive_rate(struct net_device *dev)
245 {
246 	struct r8192_priv *priv = rtllib_priv(dev);
247 	struct rate_adaptive *pra = &priv->rate_adaptive;
248 
249 	pra->ratr_state = DM_RATR_STA_MAX;
250 	pra->high2low_rssi_thresh_for_ra = RATE_ADAPTIVE_TH_HIGH;
251 	pra->low2high_rssi_thresh_for_ra20M = RATE_ADAPTIVE_TH_LOW_20M + 5;
252 	pra->low2high_rssi_thresh_for_ra40M = RATE_ADAPTIVE_TH_LOW_40M + 5;
253 
254 	pra->high_rssi_thresh_for_ra = RATE_ADAPTIVE_TH_HIGH + 5;
255 	pra->low_rssi_thresh_for_ra20M = RATE_ADAPTIVE_TH_LOW_20M;
256 	pra->low_rssi_thresh_for_ra40M = RATE_ADAPTIVE_TH_LOW_40M;
257 
258 	if (priv->customer_id == RT_CID_819X_NETCORE)
259 		pra->ping_rssi_enable = 1;
260 	else
261 		pra->ping_rssi_enable = 0;
262 	pra->ping_rssi_thresh_for_ra = 15;
263 
264 	pra->upper_rssi_threshold_ratr		=	0x000fc000;
265 	pra->middle_rssi_threshold_ratr		=	0x000ff000;
266 	pra->low_rssi_threshold_ratr		=	0x000ff001;
267 	pra->low_rssi_threshold_ratr_40M	=	0x000ff005;
268 	pra->low_rssi_threshold_ratr_20M	=	0x000ff001;
269 	pra->ping_rssi_ratr	=	0x0000000d;
270 }
271 
272 static void _rtl92e_dm_check_rate_adaptive(struct net_device *dev)
273 {
274 	struct r8192_priv *priv = rtllib_priv(dev);
275 	struct rt_hi_throughput *ht_info = priv->rtllib->ht_info;
276 	struct rate_adaptive *pra = &priv->rate_adaptive;
277 	u32 current_ratr, target_ratr = 0;
278 	u32 low_rssi_thresh_for_ra = 0, high_rssi_thresh_for_ra = 0;
279 	bool bshort_gi_enabled = false;
280 	static u8 ping_rssi_state;
281 
282 	if (!priv->up)
283 		return;
284 
285 	if (priv->rtllib->mode != WIRELESS_MODE_N_24G)
286 		return;
287 
288 	if (priv->rtllib->link_state == MAC80211_LINKED) {
289 		bshort_gi_enabled = (ht_info->cur_tx_bw40mhz &&
290 				     ht_info->cur_short_gi_40mhz) ||
291 				    (!ht_info->cur_tx_bw40mhz &&
292 				     ht_info->cur_short_gi_20mhz);
293 
294 		pra->upper_rssi_threshold_ratr =
295 				(pra->upper_rssi_threshold_ratr & (~BIT(31))) |
296 				((bshort_gi_enabled) ? BIT(31) : 0);
297 
298 		pra->middle_rssi_threshold_ratr =
299 				(pra->middle_rssi_threshold_ratr & (~BIT(31))) |
300 				((bshort_gi_enabled) ? BIT(31) : 0);
301 
302 		if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) {
303 			pra->low_rssi_threshold_ratr =
304 				(pra->low_rssi_threshold_ratr_40M & (~BIT(31))) |
305 				((bshort_gi_enabled) ? BIT(31) : 0);
306 		} else {
307 			pra->low_rssi_threshold_ratr =
308 				(pra->low_rssi_threshold_ratr_20M & (~BIT(31))) |
309 				((bshort_gi_enabled) ? BIT(31) : 0);
310 		}
311 		pra->ping_rssi_ratr =
312 				(pra->ping_rssi_ratr & (~BIT(31))) |
313 				((bshort_gi_enabled) ? BIT(31) : 0);
314 
315 		if (pra->ratr_state == DM_RATR_STA_HIGH) {
316 			high_rssi_thresh_for_ra = pra->high2low_rssi_thresh_for_ra;
317 			low_rssi_thresh_for_ra = (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) ?
318 					(pra->low_rssi_thresh_for_ra40M) : (pra->low_rssi_thresh_for_ra20M);
319 		} else if (pra->ratr_state == DM_RATR_STA_LOW) {
320 			high_rssi_thresh_for_ra = pra->high_rssi_thresh_for_ra;
321 			low_rssi_thresh_for_ra = (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) ?
322 					(pra->low2high_rssi_thresh_for_ra40M) : (pra->low2high_rssi_thresh_for_ra20M);
323 		} else {
324 			high_rssi_thresh_for_ra = pra->high_rssi_thresh_for_ra;
325 			low_rssi_thresh_for_ra = (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20) ?
326 					(pra->low_rssi_thresh_for_ra40M) : (pra->low_rssi_thresh_for_ra20M);
327 		}
328 
329 		if (priv->undecorated_smoothed_pwdb >=
330 		    (long)high_rssi_thresh_for_ra) {
331 			pra->ratr_state = DM_RATR_STA_HIGH;
332 			target_ratr = pra->upper_rssi_threshold_ratr;
333 		} else if (priv->undecorated_smoothed_pwdb >=
334 			   (long)low_rssi_thresh_for_ra) {
335 			pra->ratr_state = DM_RATR_STA_MIDDLE;
336 			target_ratr = pra->middle_rssi_threshold_ratr;
337 		} else {
338 			pra->ratr_state = DM_RATR_STA_LOW;
339 			target_ratr = pra->low_rssi_threshold_ratr;
340 		}
341 
342 		if (pra->ping_rssi_enable) {
343 			if (priv->undecorated_smoothed_pwdb <
344 			    (long)(pra->ping_rssi_thresh_for_ra + 5)) {
345 				if ((priv->undecorated_smoothed_pwdb <
346 				     (long)pra->ping_rssi_thresh_for_ra) ||
347 				    ping_rssi_state) {
348 					pra->ratr_state = DM_RATR_STA_LOW;
349 					target_ratr = pra->ping_rssi_ratr;
350 					ping_rssi_state = 1;
351 				}
352 			} else {
353 				ping_rssi_state = 0;
354 			}
355 		}
356 
357 		if (priv->rtllib->get_half_nmode_support_by_aps_handler(dev))
358 			target_ratr &=  0xf00fffff;
359 
360 		current_ratr = rtl92e_readl(dev, RATR0);
361 		if (target_ratr !=  current_ratr) {
362 			u32 ratr_value;
363 
364 			ratr_value = target_ratr;
365 			ratr_value &= ~(RATE_ALL_OFDM_2SS);
366 			rtl92e_writel(dev, RATR0, ratr_value);
367 			rtl92e_writeb(dev, UFWP, 1);
368 		}
369 
370 	} else {
371 		pra->ratr_state = DM_RATR_STA_MAX;
372 	}
373 }
374 
375 static void _rtl92e_dm_init_bandwidth_autoswitch(struct net_device *dev)
376 {
377 	struct r8192_priv *priv = rtllib_priv(dev);
378 
379 	priv->rtllib->bandwidth_auto_switch.threshold_20Mhzto40Mhz = BW_AUTO_SWITCH_LOW_HIGH;
380 	priv->rtllib->bandwidth_auto_switch.threshold_40Mhzto20Mhz = BW_AUTO_SWITCH_HIGH_LOW;
381 	priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz = false;
382 	priv->rtllib->bandwidth_auto_switch.bautoswitch_enable = false;
383 }
384 
385 static void _rtl92e_dm_bandwidth_autoswitch(struct net_device *dev)
386 {
387 	struct r8192_priv *priv = rtllib_priv(dev);
388 
389 	if (priv->current_chnl_bw == HT_CHANNEL_WIDTH_20 ||
390 	    !priv->rtllib->bandwidth_auto_switch.bautoswitch_enable)
391 		return;
392 	if (!priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz) {
393 		if (priv->undecorated_smoothed_pwdb <=
394 		    priv->rtllib->bandwidth_auto_switch.threshold_40Mhzto20Mhz)
395 			priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz = true;
396 	} else {
397 		if (priv->undecorated_smoothed_pwdb >=
398 		    priv->rtllib->bandwidth_auto_switch.threshold_20Mhzto40Mhz)
399 			priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz = false;
400 	}
401 }
402 
403 static u32 OFDMSwingTable[OFDM_TABLE_LEN] = {
404 	0x7f8001fe,
405 	0x71c001c7,
406 	0x65400195,
407 	0x5a400169,
408 	0x50800142,
409 	0x47c0011f,
410 	0x40000100,
411 	0x390000e4,
412 	0x32c000cb,
413 	0x2d4000b5,
414 	0x288000a2,
415 	0x24000090,
416 	0x20000080,
417 	0x1c800072,
418 	0x19800066,
419 	0x26c0005b,
420 	0x24400051,
421 	0x12000048,
422 	0x10000040
423 };
424 
425 static u8	CCKSwingTable_Ch1_Ch13[CCK_TABLE_LEN][8] = {
426 	{0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},
427 	{0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},
428 	{0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},
429 	{0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},
430 	{0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},
431 	{0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},
432 	{0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},
433 	{0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},
434 	{0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},
435 	{0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},
436 	{0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
437 	{0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}
438 };
439 
440 static u8	CCKSwingTable_Ch14[CCK_TABLE_LEN][8] = {
441 	{0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},
442 	{0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},
443 	{0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},
444 	{0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},
445 	{0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},
446 	{0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},
447 	{0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},
448 	{0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},
449 	{0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},
450 	{0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},
451 	{0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
452 	{0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}
453 };
454 
455 #define		Pw_Track_Flag				0x11d
456 #define		Tssi_Mea_Value				0x13c
457 #define		Tssi_Report_Value1			0x134
458 #define		Tssi_Report_Value2			0x13e
459 #define		FW_Busy_Flag				0x13f
460 
461 static void _rtl92e_dm_tx_update_tssi_weak_signal(struct net_device *dev)
462 {
463 	struct r8192_priv *p = rtllib_priv(dev);
464 
465 	if (p->rfa_txpowertrackingindex > 0) {
466 		p->rfa_txpowertrackingindex--;
467 		if (p->rfa_txpowertrackingindex_real > 4) {
468 			p->rfa_txpowertrackingindex_real--;
469 			rtl92e_set_bb_reg(dev,
470 					  rOFDM0_XATxIQImbalance,
471 					  bMaskDWord,
472 					  dm_tx_bb_gain[p->rfa_txpowertrackingindex_real]);
473 		}
474 	} else {
475 		rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance,
476 				  bMaskDWord, dm_tx_bb_gain[4]);
477 	}
478 }
479 
480 static void _rtl92e_dm_tx_update_tssi_strong_signal(struct net_device *dev)
481 {
482 	struct r8192_priv *p = rtllib_priv(dev);
483 
484 	if (p->rfa_txpowertrackingindex < (TX_BB_GAIN_TABLE_LEN - 1)) {
485 		p->rfa_txpowertrackingindex++;
486 		p->rfa_txpowertrackingindex_real++;
487 		rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance,
488 				  bMaskDWord,
489 				  dm_tx_bb_gain[p->rfa_txpowertrackingindex_real]);
490 	} else {
491 		rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance,
492 				  bMaskDWord,
493 				  dm_tx_bb_gain[TX_BB_GAIN_TABLE_LEN - 1]);
494 	}
495 }
496 
497 static void _rtl92e_dm_tx_power_tracking_callback_tssi(struct net_device *dev)
498 {
499 	struct r8192_priv *priv = rtllib_priv(dev);
500 	bool	viviflag = false;
501 	struct dcmd_txcmd tx_cmd;
502 	int	i = 0, j = 0, k = 0;
503 	u8	tmp_report[5] = {0, 0, 0, 0, 0};
504 	u8	Pwr_Flag;
505 	u16	Avg_TSSI_Meas, tssi_13dBm, Avg_TSSI_Meas_from_driver = 0;
506 	u32	delta = 0;
507 
508 	rtl92e_writeb(dev, Pw_Track_Flag, 0);
509 	rtl92e_writeb(dev, FW_Busy_Flag, 0);
510 	priv->rtllib->bdynamic_txpower_enable = false;
511 
512 	for (j = 0; j <= 30; j++) {
513 		tx_cmd.op	= TXCMD_SET_TX_PWR_TRACKING;
514 		tx_cmd.length	= 4;
515 		tx_cmd.value	= priv->pwr_track >> 24;
516 		rtl92e_send_cmd_pkt(dev, DESC_PACKET_TYPE_NORMAL, (u8 *)&tx_cmd,
517 				    sizeof(struct dcmd_txcmd));
518 		mdelay(1);
519 		for (i = 0; i <= 30; i++) {
520 			Pwr_Flag = rtl92e_readb(dev, Pw_Track_Flag);
521 
522 			if (Pwr_Flag == 0) {
523 				mdelay(1);
524 
525 				if (priv->rtllib->rf_power_state != rf_on) {
526 					rtl92e_writeb(dev, Pw_Track_Flag, 0);
527 					rtl92e_writeb(dev, FW_Busy_Flag, 0);
528 					return;
529 				}
530 
531 				continue;
532 			}
533 
534 			Avg_TSSI_Meas = rtl92e_readw(dev, Tssi_Mea_Value);
535 
536 			if (Avg_TSSI_Meas == 0) {
537 				rtl92e_writeb(dev, Pw_Track_Flag, 0);
538 				rtl92e_writeb(dev, FW_Busy_Flag, 0);
539 				return;
540 			}
541 
542 			for (k = 0; k < 5; k++) {
543 				if (k != 4)
544 					tmp_report[k] = rtl92e_readb(dev,
545 							 Tssi_Report_Value1 + k);
546 				else
547 					tmp_report[k] = rtl92e_readb(dev,
548 							 Tssi_Report_Value2);
549 
550 				if (tmp_report[k] <= 20) {
551 					viviflag = true;
552 					break;
553 				}
554 			}
555 
556 			if (viviflag) {
557 				rtl92e_writeb(dev, Pw_Track_Flag, 0);
558 				viviflag = false;
559 				for (k = 0; k < 5; k++)
560 					tmp_report[k] = 0;
561 				break;
562 			}
563 
564 			for (k = 0; k < 5; k++)
565 				Avg_TSSI_Meas_from_driver += tmp_report[k];
566 
567 			Avg_TSSI_Meas_from_driver *= 100 / 5;
568 			tssi_13dBm = priv->tssi_13dBm;
569 
570 			if (Avg_TSSI_Meas_from_driver > tssi_13dBm)
571 				delta = Avg_TSSI_Meas_from_driver - tssi_13dBm;
572 			else
573 				delta = tssi_13dBm - Avg_TSSI_Meas_from_driver;
574 
575 			if (delta <= E_FOR_TX_POWER_TRACK) {
576 				priv->rtllib->bdynamic_txpower_enable = true;
577 				rtl92e_writeb(dev, Pw_Track_Flag, 0);
578 				rtl92e_writeb(dev, FW_Busy_Flag, 0);
579 				return;
580 			}
581 			if (Avg_TSSI_Meas_from_driver < tssi_13dBm - E_FOR_TX_POWER_TRACK)
582 				_rtl92e_dm_tx_update_tssi_weak_signal(dev);
583 			else
584 				_rtl92e_dm_tx_update_tssi_strong_signal(dev);
585 
586 			priv->cck_present_attn_diff
587 				= priv->rfa_txpowertrackingindex_real - priv->rfa_txpowertracking_default;
588 
589 			if (priv->current_chnl_bw == HT_CHANNEL_WIDTH_20)
590 				priv->cck_present_attn =
591 					 priv->cck_present_attn_20m_def +
592 					 priv->cck_present_attn_diff;
593 			else
594 				priv->cck_present_attn =
595 					 priv->cck_present_attn_40m_def +
596 					 priv->cck_present_attn_diff;
597 
598 			if (priv->cck_present_attn > (CCK_TX_BB_GAIN_TABLE_LEN - 1))
599 				priv->cck_present_attn = CCK_TX_BB_GAIN_TABLE_LEN - 1;
600 			if (priv->cck_present_attn < 0)
601 				priv->cck_present_attn = 0;
602 
603 			if (priv->cck_present_attn > -1 &&
604 			    priv->cck_present_attn < CCK_TX_BB_GAIN_TABLE_LEN) {
605 				if (priv->rtllib->current_network.channel == 14 &&
606 				    !priv->bcck_in_ch14) {
607 					priv->bcck_in_ch14 = true;
608 					rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
609 				} else if (priv->rtllib->current_network.channel != 14 && priv->bcck_in_ch14) {
610 					priv->bcck_in_ch14 = false;
611 					rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
612 				} else {
613 					rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
614 				}
615 			}
616 
617 			if (priv->cck_present_attn_diff <= -12 ||
618 			    priv->cck_present_attn_diff >= 24) {
619 				priv->rtllib->bdynamic_txpower_enable = true;
620 				rtl92e_writeb(dev, Pw_Track_Flag, 0);
621 				rtl92e_writeb(dev, FW_Busy_Flag, 0);
622 				return;
623 			}
624 
625 			rtl92e_writeb(dev, Pw_Track_Flag, 0);
626 			Avg_TSSI_Meas_from_driver = 0;
627 			for (k = 0; k < 5; k++)
628 				tmp_report[k] = 0;
629 			break;
630 		}
631 		rtl92e_writeb(dev, FW_Busy_Flag, 0);
632 	}
633 	priv->rtllib->bdynamic_txpower_enable = true;
634 	rtl92e_writeb(dev, Pw_Track_Flag, 0);
635 }
636 
637 static void _rtl92e_dm_tx_power_tracking_cb_thermal(struct net_device *dev)
638 {
639 #define ThermalMeterVal	9
640 	struct r8192_priv *priv = rtllib_priv(dev);
641 	u32 tmp_reg, tmp_cck;
642 	u8 tmp_ofdm_index, tmp_cck_index, tmp_cck_20m_index, tmp_cck_40m_index, tmpval;
643 	int i = 0, CCKSwingNeedUpdate = 0;
644 
645 	if (!priv->tx_pwr_tracking_init) {
646 		tmp_reg = rtl92e_get_bb_reg(dev, rOFDM0_XATxIQImbalance,
647 					    bMaskDWord);
648 		for (i = 0; i < OFDM_TABLE_LEN; i++) {
649 			if (tmp_reg == OFDMSwingTable[i])
650 				priv->ofdm_index[0] = i;
651 		}
652 
653 		tmp_cck = rtl92e_get_bb_reg(dev, rCCK0_TxFilter1, bMaskByte2);
654 		for (i = 0; i < CCK_TABLE_LEN; i++) {
655 			if (tmp_cck == (u32)CCKSwingTable_Ch1_Ch13[i][0]) {
656 				priv->cck_index = i;
657 				break;
658 			}
659 		}
660 		priv->tx_pwr_tracking_init = true;
661 		return;
662 	}
663 
664 	tmp_reg = rtl92e_get_rf_reg(dev, RF90_PATH_A, 0x12, 0x078);
665 	if (tmp_reg < 3 || tmp_reg > 13)
666 		return;
667 	if (tmp_reg >= 12)
668 		tmp_reg = 12;
669 	priv->thermal_meter[0] = ThermalMeterVal;
670 	priv->thermal_meter[1] = ThermalMeterVal;
671 
672 	if (priv->thermal_meter[0] >= (u8)tmp_reg) {
673 		tmp_ofdm_index = 6 + (priv->thermal_meter[0] - (u8)tmp_reg);
674 		tmp_cck_20m_index = tmp_ofdm_index;
675 		tmp_cck_40m_index = tmp_cck_20m_index - 6;
676 		if (tmp_ofdm_index >= OFDM_TABLE_LEN)
677 			tmp_ofdm_index = OFDM_TABLE_LEN - 1;
678 		if (tmp_cck_20m_index >= CCK_TABLE_LEN)
679 			tmp_cck_20m_index = CCK_TABLE_LEN - 1;
680 		if (tmp_cck_40m_index >= CCK_TABLE_LEN)
681 			tmp_cck_40m_index = CCK_TABLE_LEN - 1;
682 	} else {
683 		tmpval = (u8)tmp_reg - priv->thermal_meter[0];
684 		if (tmpval >= 6) {
685 			tmp_ofdm_index = 0;
686 			tmp_cck_20m_index = 0;
687 		} else {
688 			tmp_ofdm_index = 6 - tmpval;
689 			tmp_cck_20m_index = 6 - tmpval;
690 		}
691 		tmp_cck_40m_index = 0;
692 	}
693 	if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20)
694 		tmp_cck_index = tmp_cck_40m_index;
695 	else
696 		tmp_cck_index = tmp_cck_20m_index;
697 
698 	priv->rec_cck_20m_idx = tmp_cck_20m_index;
699 	priv->rec_cck_40m_idx = tmp_cck_40m_index;
700 
701 	if (priv->rtllib->current_network.channel == 14 &&
702 	    !priv->bcck_in_ch14) {
703 		priv->bcck_in_ch14 = true;
704 		CCKSwingNeedUpdate = 1;
705 	} else if (priv->rtllib->current_network.channel != 14 &&
706 		   priv->bcck_in_ch14) {
707 		priv->bcck_in_ch14 = false;
708 		CCKSwingNeedUpdate = 1;
709 	}
710 
711 	if (priv->cck_index != tmp_cck_index) {
712 		priv->cck_index = tmp_cck_index;
713 		CCKSwingNeedUpdate = 1;
714 	}
715 
716 	if (CCKSwingNeedUpdate)
717 		rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
718 	if (priv->ofdm_index[0] != tmp_ofdm_index) {
719 		priv->ofdm_index[0] = tmp_ofdm_index;
720 		rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance, bMaskDWord,
721 				  OFDMSwingTable[priv->ofdm_index[0]]);
722 	}
723 	priv->txpower_count = 0;
724 }
725 
726 void rtl92e_dm_txpower_tracking_wq(void *data)
727 {
728 	struct r8192_priv *priv = container_of_dwork_rsl(data,
729 				  struct r8192_priv, txpower_tracking_wq);
730 	struct net_device *dev = priv->rtllib->dev;
731 
732 	if (priv->ic_cut >= IC_VersionCut_D)
733 		_rtl92e_dm_tx_power_tracking_callback_tssi(dev);
734 	else
735 		_rtl92e_dm_tx_power_tracking_cb_thermal(dev);
736 }
737 
738 static void _rtl92e_dm_initialize_tx_power_tracking_tssi(struct net_device *dev)
739 {
740 	struct r8192_priv *priv = rtllib_priv(dev);
741 
742 	priv->btxpower_tracking = true;
743 	priv->txpower_count       = 0;
744 	priv->tx_pwr_tracking_init = false;
745 }
746 
747 static void _rtl92e_dm_init_tx_power_tracking_thermal(struct net_device *dev)
748 {
749 	struct r8192_priv *priv = rtllib_priv(dev);
750 
751 	if (priv->rtllib->FwRWRF)
752 		priv->btxpower_tracking = true;
753 	else
754 		priv->btxpower_tracking = false;
755 	priv->txpower_count       = 0;
756 	priv->tx_pwr_tracking_init = false;
757 }
758 
759 void rtl92e_dm_init_txpower_tracking(struct net_device *dev)
760 {
761 	struct r8192_priv *priv = rtllib_priv(dev);
762 
763 	if (priv->ic_cut >= IC_VersionCut_D)
764 		_rtl92e_dm_initialize_tx_power_tracking_tssi(dev);
765 	else
766 		_rtl92e_dm_init_tx_power_tracking_thermal(dev);
767 }
768 
769 static void _rtl92e_dm_check_tx_power_tracking_tssi(struct net_device *dev)
770 {
771 	struct r8192_priv *priv = rtllib_priv(dev);
772 	static u32 tx_power_track_counter;
773 
774 	if (rtl92e_readb(dev, 0x11e) == 1)
775 		return;
776 	if (!priv->btxpower_tracking)
777 		return;
778 	tx_power_track_counter++;
779 
780 	if (tx_power_track_counter >= 180) {
781 		schedule_delayed_work(&priv->txpower_tracking_wq, 0);
782 		tx_power_track_counter = 0;
783 	}
784 }
785 
786 static void _rtl92e_dm_check_tx_power_tracking_thermal(struct net_device *dev)
787 {
788 	struct r8192_priv *priv = rtllib_priv(dev);
789 	static u8	TM_Trigger;
790 	u8		TxPowerCheckCnt = 0;
791 
792 	TxPowerCheckCnt = 2;
793 	if (!priv->btxpower_tracking)
794 		return;
795 
796 	if (priv->txpower_count  <= TxPowerCheckCnt) {
797 		priv->txpower_count++;
798 		return;
799 	}
800 
801 	if (!TM_Trigger) {
802 		rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
803 		rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
804 		rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
805 		rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
806 		TM_Trigger = 1;
807 		return;
808 	}
809 	netdev_info(dev, "===============>Schedule TxPowerTrackingWorkItem\n");
810 	schedule_delayed_work(&priv->txpower_tracking_wq, 0);
811 	TM_Trigger = 0;
812 }
813 
814 static void _rtl92e_dm_check_tx_power_tracking(struct net_device *dev)
815 {
816 	struct r8192_priv *priv = rtllib_priv(dev);
817 
818 	if (priv->ic_cut >= IC_VersionCut_D)
819 		_rtl92e_dm_check_tx_power_tracking_tssi(dev);
820 	else
821 		_rtl92e_dm_check_tx_power_tracking_thermal(dev);
822 }
823 
824 static void _rtl92e_dm_cck_tx_power_adjust_tssi(struct net_device *dev,
825 						bool bInCH14)
826 {
827 	u32 TempVal;
828 	struct r8192_priv *priv = rtllib_priv(dev);
829 	u8 attenuation = priv->cck_present_attn;
830 
831 	TempVal = 0;
832 	if (!bInCH14) {
833 		TempVal = (u32)(dm_cck_tx_bb_gain[attenuation][0] +
834 			  (dm_cck_tx_bb_gain[attenuation][1] << 8));
835 
836 		rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
837 		TempVal = (u32)((dm_cck_tx_bb_gain[attenuation][2]) +
838 			  (dm_cck_tx_bb_gain[attenuation][3] << 8) +
839 			  (dm_cck_tx_bb_gain[attenuation][4] << 16) +
840 			  (dm_cck_tx_bb_gain[attenuation][5] << 24));
841 		rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
842 		TempVal = (u32)(dm_cck_tx_bb_gain[attenuation][6] +
843 			  (dm_cck_tx_bb_gain[attenuation][7] << 8));
844 
845 		rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
846 	} else {
847 		TempVal = (u32)((dm_cck_tx_bb_gain_ch14[attenuation][0]) +
848 			  (dm_cck_tx_bb_gain_ch14[attenuation][1] << 8));
849 
850 		rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
851 		TempVal = (u32)((dm_cck_tx_bb_gain_ch14[attenuation][2]) +
852 			  (dm_cck_tx_bb_gain_ch14[attenuation][3] << 8) +
853 			  (dm_cck_tx_bb_gain_ch14[attenuation][4] << 16) +
854 			  (dm_cck_tx_bb_gain_ch14[attenuation][5] << 24));
855 		rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
856 		TempVal = (u32)((dm_cck_tx_bb_gain_ch14[attenuation][6]) +
857 			  (dm_cck_tx_bb_gain_ch14[attenuation][7] << 8));
858 
859 		rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
860 	}
861 }
862 
863 static void _rtl92e_dm_cck_tx_power_adjust_thermal_meter(struct net_device *dev,
864 							 bool bInCH14)
865 {
866 	u32 TempVal;
867 	struct r8192_priv *priv = rtllib_priv(dev);
868 
869 	TempVal = 0;
870 	if (!bInCH14) {
871 		TempVal = CCKSwingTable_Ch1_Ch13[priv->cck_index][0] +
872 			  (CCKSwingTable_Ch1_Ch13[priv->cck_index][1] << 8);
873 		rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
874 		TempVal = CCKSwingTable_Ch1_Ch13[priv->cck_index][2] +
875 			  (CCKSwingTable_Ch1_Ch13[priv->cck_index][3] << 8) +
876 			  (CCKSwingTable_Ch1_Ch13[priv->cck_index][4] << 16) +
877 			  (CCKSwingTable_Ch1_Ch13[priv->cck_index][5] << 24);
878 		rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
879 		TempVal = CCKSwingTable_Ch1_Ch13[priv->cck_index][6] +
880 			  (CCKSwingTable_Ch1_Ch13[priv->cck_index][7] << 8);
881 
882 		rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
883 	} else {
884 		TempVal = CCKSwingTable_Ch14[priv->cck_index][0] +
885 			  (CCKSwingTable_Ch14[priv->cck_index][1] << 8);
886 
887 		rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
888 		TempVal = CCKSwingTable_Ch14[priv->cck_index][2] +
889 			  (CCKSwingTable_Ch14[priv->cck_index][3] << 8) +
890 			  (CCKSwingTable_Ch14[priv->cck_index][4] << 16) +
891 			  (CCKSwingTable_Ch14[priv->cck_index][5] << 24);
892 		rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
893 		TempVal = CCKSwingTable_Ch14[priv->cck_index][6] +
894 			  (CCKSwingTable_Ch14[priv->cck_index][7] << 8);
895 
896 		rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
897 	}
898 }
899 
900 void rtl92e_dm_cck_txpower_adjust(struct net_device *dev, bool binch14)
901 {
902 	struct r8192_priv *priv = rtllib_priv(dev);
903 
904 	if (priv->ic_cut >= IC_VersionCut_D)
905 		_rtl92e_dm_cck_tx_power_adjust_tssi(dev, binch14);
906 	else
907 		_rtl92e_dm_cck_tx_power_adjust_thermal_meter(dev, binch14);
908 }
909 
910 static void _rtl92e_dm_dig_init(struct net_device *dev)
911 {
912 	struct r8192_priv *priv = rtllib_priv(dev);
913 
914 	dm_digtable.cur_sta_connect_state = DIG_STA_DISCONNECT;
915 	dm_digtable.pre_sta_connect_state = DIG_STA_DISCONNECT;
916 
917 	dm_digtable.rssi_low_thresh	= DM_DIG_THRESH_LOW;
918 	dm_digtable.rssi_high_thresh	= DM_DIG_THRESH_HIGH;
919 
920 	dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
921 	dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
922 
923 	dm_digtable.rssi_val = 50;
924 	dm_digtable.backoff_val = DM_DIG_BACKOFF;
925 	dm_digtable.rx_gain_range_max = DM_DIG_MAX;
926 	if (priv->customer_id == RT_CID_819X_NETCORE)
927 		dm_digtable.rx_gain_range_min = DM_DIG_MIN_Netcore;
928 	else
929 		dm_digtable.rx_gain_range_min = DM_DIG_MIN;
930 }
931 
932 static void _rtl92e_dm_ctrl_initgain_byrssi(struct net_device *dev)
933 {
934 	_rtl92e_dm_ctrl_initgain_byrssi_driver(dev);
935 }
936 
937 /*-----------------------------------------------------------------------------
938  * Function:	dm_CtrlInitGainBeforeConnectByRssiAndFalseAlarm()
939  *
940  * Overview:	Driver monitor RSSI and False Alarm to change initial gain.
941 			Only change initial gain during link in progress.
942  *
943  * Input:		IN	PADAPTER	pAdapter
944  *
945  * Output:		NONE
946  *
947  * Return:		NONE
948  *
949  * Revised History:
950  *	When		Who		Remark
951  *	03/04/2009	hpfan	Create Version 0.
952  *
953  ******************************************************************************/
954 
955 static void _rtl92e_dm_ctrl_initgain_byrssi_driver(struct net_device *dev)
956 {
957 	struct r8192_priv *priv = rtllib_priv(dev);
958 	u8 i;
959 	static u8	fw_dig;
960 
961 	if (fw_dig <= 3) {
962 		for (i = 0; i < 3; i++)
963 			rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8);
964 		fw_dig++;
965 	}
966 
967 	if (priv->rtllib->link_state == MAC80211_LINKED)
968 		dm_digtable.cur_sta_connect_state = DIG_STA_CONNECT;
969 	else
970 		dm_digtable.cur_sta_connect_state = DIG_STA_DISCONNECT;
971 
972 	dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb;
973 	_rtl92e_dm_initial_gain(dev);
974 	_rtl92e_dm_pd_th(dev);
975 	_rtl92e_dm_cs_ratio(dev);
976 	dm_digtable.pre_sta_connect_state = dm_digtable.cur_sta_connect_state;
977 }
978 
979 static void _rtl92e_dm_initial_gain(struct net_device *dev)
980 {
981 	struct r8192_priv *priv = rtllib_priv(dev);
982 	u8 initial_gain = 0;
983 	static u8 initialized, force_write;
984 
985 	if (rtllib_act_scanning(priv->rtllib, true)) {
986 		force_write = 1;
987 		return;
988 	}
989 
990 	if (dm_digtable.pre_sta_connect_state == dm_digtable.cur_sta_connect_state) {
991 		if (dm_digtable.cur_sta_connect_state == DIG_STA_CONNECT) {
992 			long gain_range = dm_digtable.rssi_val + 10 -
993 					  dm_digtable.backoff_val;
994 			gain_range = clamp_t(long, gain_range,
995 					     dm_digtable.rx_gain_range_min,
996 					     dm_digtable.rx_gain_range_max);
997 			dm_digtable.cur_ig_value = gain_range;
998 		} else {
999 			if (dm_digtable.cur_ig_value == 0)
1000 				dm_digtable.cur_ig_value = priv->def_initial_gain[0];
1001 			else
1002 				dm_digtable.cur_ig_value = dm_digtable.pre_ig_value;
1003 		}
1004 	} else {
1005 		dm_digtable.cur_ig_value = priv->def_initial_gain[0];
1006 		dm_digtable.pre_ig_value = 0;
1007 	}
1008 
1009 	if (dm_digtable.pre_ig_value != rtl92e_readb(dev, rOFDM0_XAAGCCore1))
1010 		force_write = 1;
1011 
1012 	if ((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value)
1013 	    || !initialized || force_write) {
1014 		initial_gain = dm_digtable.cur_ig_value;
1015 		rtl92e_writeb(dev, rOFDM0_XAAGCCore1, initial_gain);
1016 		rtl92e_writeb(dev, rOFDM0_XBAGCCore1, initial_gain);
1017 		rtl92e_writeb(dev, rOFDM0_XCAGCCore1, initial_gain);
1018 		rtl92e_writeb(dev, rOFDM0_XDAGCCore1, initial_gain);
1019 		dm_digtable.pre_ig_value = dm_digtable.cur_ig_value;
1020 		initialized = 1;
1021 		force_write = 0;
1022 	}
1023 }
1024 
1025 static void _rtl92e_dm_pd_th(struct net_device *dev)
1026 {
1027 	struct r8192_priv *priv = rtllib_priv(dev);
1028 	static u8 initialized, force_write;
1029 
1030 	if (dm_digtable.pre_sta_connect_state == dm_digtable.cur_sta_connect_state) {
1031 		if (dm_digtable.cur_sta_connect_state == DIG_STA_CONNECT) {
1032 			if (dm_digtable.rssi_val >=
1033 			    dm_digtable.rssi_high_power_highthresh)
1034 				dm_digtable.curpd_thstate =
1035 							DIG_PD_AT_HIGH_POWER;
1036 			else if (dm_digtable.rssi_val <=
1037 				 dm_digtable.rssi_low_thresh)
1038 				dm_digtable.curpd_thstate =
1039 							DIG_PD_AT_LOW_POWER;
1040 			else if ((dm_digtable.rssi_val >=
1041 				  dm_digtable.rssi_high_thresh) &&
1042 				 (dm_digtable.rssi_val <
1043 				  dm_digtable.rssi_high_power_lowthresh))
1044 				dm_digtable.curpd_thstate =
1045 							DIG_PD_AT_NORMAL_POWER;
1046 			else
1047 				dm_digtable.curpd_thstate =
1048 						dm_digtable.prepd_thstate;
1049 		} else {
1050 			dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
1051 		}
1052 	} else {
1053 		dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
1054 	}
1055 
1056 	if ((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) ||
1057 	    (initialized <= 3) || force_write) {
1058 		if (dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER) {
1059 			if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20)
1060 				rtl92e_writeb(dev, (rOFDM0_XATxAFE + 3), 0x00);
1061 			else
1062 				rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x42);
1063 		} else if (dm_digtable.curpd_thstate ==
1064 			   DIG_PD_AT_NORMAL_POWER) {
1065 			if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20)
1066 				rtl92e_writeb(dev, (rOFDM0_XATxAFE + 3), 0x20);
1067 			else
1068 				rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x44);
1069 		} else if (dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER) {
1070 			if (priv->current_chnl_bw != HT_CHANNEL_WIDTH_20)
1071 				rtl92e_writeb(dev, (rOFDM0_XATxAFE + 3), 0x10);
1072 			else
1073 				rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x43);
1074 		}
1075 		dm_digtable.prepd_thstate = dm_digtable.curpd_thstate;
1076 		if (initialized <= 3)
1077 			initialized++;
1078 		force_write = 0;
1079 	}
1080 }
1081 
1082 static void _rtl92e_dm_cs_ratio(struct net_device *dev)
1083 {
1084 	static u8 initialized, force_write;
1085 
1086 	if (dm_digtable.pre_sta_connect_state == dm_digtable.cur_sta_connect_state) {
1087 		if (dm_digtable.cur_sta_connect_state == DIG_STA_CONNECT) {
1088 			if (dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh)
1089 				dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
1090 			else if (dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh)
1091 				dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER;
1092 			else
1093 				dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state;
1094 		} else {
1095 			dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
1096 		}
1097 	} else {
1098 		dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
1099 	}
1100 
1101 	if ((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
1102 	    !initialized || force_write) {
1103 		if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER)
1104 			rtl92e_writeb(dev, 0xa0a, 0x08);
1105 		else if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER)
1106 			rtl92e_writeb(dev, 0xa0a, 0xcd);
1107 		dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state;
1108 		initialized = 1;
1109 		force_write = 0;
1110 	}
1111 }
1112 
1113 void rtl92e_dm_init_edca_turbo(struct net_device *dev)
1114 {
1115 	struct r8192_priv *priv = rtllib_priv(dev);
1116 
1117 	priv->bcurrent_turbo_EDCA = false;
1118 	priv->rtllib->bis_any_nonbepkts = false;
1119 	priv->bis_cur_rdlstate = false;
1120 }
1121 
1122 static void _rtl92e_dm_check_edca_turbo(struct net_device *dev)
1123 {
1124 	struct r8192_priv *priv = rtllib_priv(dev);
1125 	struct rt_hi_throughput *ht_info = priv->rtllib->ht_info;
1126 
1127 	static unsigned long lastTxOkCnt;
1128 	static unsigned long lastRxOkCnt;
1129 	unsigned long curTxOkCnt = 0;
1130 	unsigned long curRxOkCnt = 0;
1131 
1132 	if (priv->rtllib->link_state != MAC80211_LINKED)
1133 		goto dm_CheckEdcaTurbo_EXIT;
1134 	if (priv->rtllib->ht_info->iot_action & HT_IOT_ACT_DISABLE_EDCA_TURBO)
1135 		goto dm_CheckEdcaTurbo_EXIT;
1136 
1137 	if (!priv->rtllib->bis_any_nonbepkts) {
1138 		curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
1139 		curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
1140 		if (ht_info->iot_action & HT_IOT_ACT_EDCA_BIAS_ON_RX) {
1141 			if (curTxOkCnt > 4 * curRxOkCnt) {
1142 				if (priv->bis_cur_rdlstate ||
1143 				    !priv->bcurrent_turbo_EDCA) {
1144 					rtl92e_writel(dev, EDCAPARA_BE,
1145 						      edca_setting_UL[ht_info->iot_peer]);
1146 					priv->bis_cur_rdlstate = false;
1147 				}
1148 			} else {
1149 				if (!priv->bis_cur_rdlstate ||
1150 				    !priv->bcurrent_turbo_EDCA) {
1151 					if (priv->rtllib->mode == WIRELESS_MODE_G)
1152 						rtl92e_writel(dev, EDCAPARA_BE,
1153 							      edca_setting_DL_GMode[ht_info->iot_peer]);
1154 					else
1155 						rtl92e_writel(dev, EDCAPARA_BE,
1156 							      edca_setting_DL[ht_info->iot_peer]);
1157 					priv->bis_cur_rdlstate = true;
1158 				}
1159 			}
1160 			priv->bcurrent_turbo_EDCA = true;
1161 		} else {
1162 			if (curRxOkCnt > 4 * curTxOkCnt) {
1163 				if (!priv->bis_cur_rdlstate ||
1164 				    !priv->bcurrent_turbo_EDCA) {
1165 					if (priv->rtllib->mode == WIRELESS_MODE_G)
1166 						rtl92e_writel(dev, EDCAPARA_BE,
1167 							      edca_setting_DL_GMode[ht_info->iot_peer]);
1168 					else
1169 						rtl92e_writel(dev, EDCAPARA_BE,
1170 							      edca_setting_DL[ht_info->iot_peer]);
1171 					priv->bis_cur_rdlstate = true;
1172 				}
1173 			} else {
1174 				if (priv->bis_cur_rdlstate ||
1175 				    !priv->bcurrent_turbo_EDCA) {
1176 					rtl92e_writel(dev, EDCAPARA_BE,
1177 						      edca_setting_UL[ht_info->iot_peer]);
1178 					priv->bis_cur_rdlstate = false;
1179 				}
1180 			}
1181 
1182 			priv->bcurrent_turbo_EDCA = true;
1183 		}
1184 	} else {
1185 		if (priv->bcurrent_turbo_EDCA) {
1186 			u8 tmp = AC0_BE;
1187 
1188 			priv->rtllib->set_hw_reg_handler(dev, HW_VAR_AC_PARAM,
1189 						      (u8 *)(&tmp));
1190 			priv->bcurrent_turbo_EDCA = false;
1191 		}
1192 	}
1193 
1194 dm_CheckEdcaTurbo_EXIT:
1195 	priv->rtllib->bis_any_nonbepkts = false;
1196 	lastTxOkCnt = priv->stats.txbytesunicast;
1197 	lastRxOkCnt = priv->stats.rxbytesunicast;
1198 }
1199 
1200 static void _rtl92e_dm_init_cts_to_self(struct net_device *dev)
1201 {
1202 	struct r8192_priv *priv = rtllib_priv((struct net_device *)dev);
1203 
1204 	priv->rtllib->bCTSToSelfEnable = true;
1205 }
1206 
1207 static void _rtl92e_dm_cts_to_self(struct net_device *dev)
1208 {
1209 	struct r8192_priv *priv = rtllib_priv((struct net_device *)dev);
1210 	struct rt_hi_throughput *ht_info = priv->rtllib->ht_info;
1211 	static unsigned long lastTxOkCnt;
1212 	static unsigned long lastRxOkCnt;
1213 	unsigned long curTxOkCnt = 0;
1214 	unsigned long curRxOkCnt = 0;
1215 
1216 	if (!priv->rtllib->bCTSToSelfEnable) {
1217 		ht_info->iot_action &= ~HT_IOT_ACT_FORCED_CTS2SELF;
1218 		return;
1219 	}
1220 	if (ht_info->iot_peer == HT_IOT_PEER_BROADCOM) {
1221 		curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
1222 		curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
1223 		if (curRxOkCnt > 4 * curTxOkCnt)
1224 			ht_info->iot_action &= ~HT_IOT_ACT_FORCED_CTS2SELF;
1225 		else
1226 			ht_info->iot_action |= HT_IOT_ACT_FORCED_CTS2SELF;
1227 
1228 		lastTxOkCnt = priv->stats.txbytesunicast;
1229 		lastRxOkCnt = priv->stats.rxbytesunicast;
1230 	}
1231 }
1232 
1233 static void _rtl92e_dm_check_rf_ctrl_gpio(void *data)
1234 {
1235 	struct r8192_priv *priv = container_of_dwork_rsl(data,
1236 				  struct r8192_priv, gpio_change_rf_wq);
1237 	struct net_device *dev = priv->rtllib->dev;
1238 	u8 tmp1byte;
1239 	enum rt_rf_power_state rf_power_state_to_set;
1240 	bool bActuallySet = false;
1241 
1242 	if ((priv->up_first_time == 1) || (priv->being_init_adapter))
1243 		return;
1244 
1245 	if (priv->bfirst_after_down)
1246 		return;
1247 
1248 	tmp1byte = rtl92e_readb(dev, GPI);
1249 
1250 	rf_power_state_to_set = (tmp1byte & BIT(1)) ?  rf_on : rf_off;
1251 
1252 	if (priv->hw_radio_off && (rf_power_state_to_set == rf_on)) {
1253 		netdev_info(dev, "gpiochangeRF  - HW Radio ON\n");
1254 		priv->hw_radio_off = false;
1255 		bActuallySet = true;
1256 	} else if (!priv->hw_radio_off && (rf_power_state_to_set == rf_off)) {
1257 		netdev_info(dev, "gpiochangeRF  - HW Radio OFF\n");
1258 		priv->hw_radio_off = true;
1259 		bActuallySet = true;
1260 	}
1261 
1262 	if (bActuallySet) {
1263 		mdelay(1000);
1264 		priv->hw_rf_off_action = 1;
1265 		rtl92e_set_rf_state(dev, rf_power_state_to_set, RF_CHANGE_BY_HW);
1266 	}
1267 }
1268 
1269 void rtl92e_dm_rf_pathcheck_wq(void *data)
1270 {
1271 	struct r8192_priv *priv = container_of_dwork_rsl(data,
1272 				  struct r8192_priv,
1273 				  rfpath_check_wq);
1274 	struct net_device *dev = priv->rtllib->dev;
1275 	u8 rfpath, i;
1276 
1277 	rfpath = rtl92e_readb(dev, 0xc04);
1278 
1279 	for (i = 0; i < RF90_PATH_MAX; i++) {
1280 		if (rfpath & (0x01 << i))
1281 			priv->brfpath_rxenable[i] = true;
1282 		else
1283 			priv->brfpath_rxenable[i] = false;
1284 	}
1285 	if (!dm_rx_path_sel_table.enable)
1286 		return;
1287 
1288 	_rtl92e_dm_rx_path_sel_byrssi(dev);
1289 }
1290 
1291 static void _rtl92e_dm_init_rx_path_selection(struct net_device *dev)
1292 {
1293 	u8 i;
1294 	struct r8192_priv *priv = rtllib_priv(dev);
1295 
1296 	dm_rx_path_sel_table.enable = 1;
1297 	dm_rx_path_sel_table.ss_th_low = RX_PATH_SEL_SS_TH_LOW;
1298 	dm_rx_path_sel_table.diff_th = RX_PATH_SEL_DIFF_TH;
1299 	if (priv->customer_id == RT_CID_819X_NETCORE)
1300 		dm_rx_path_sel_table.cck_method = CCK_Rx_Version_2;
1301 	else
1302 		dm_rx_path_sel_table.cck_method = CCK_Rx_Version_1;
1303 	dm_rx_path_sel_table.disabled_rf = 0;
1304 	for (i = 0; i < 4; i++) {
1305 		dm_rx_path_sel_table.rf_rssi[i] = 50;
1306 		dm_rx_path_sel_table.cck_pwdb_sta[i] = -64;
1307 		dm_rx_path_sel_table.rf_enable_rssi_th[i] = 100;
1308 	}
1309 }
1310 
1311 #define PWDB_IN_RANGE	((cur_cck_pwdb < tmp_cck_max_pwdb) &&	\
1312 			(cur_cck_pwdb > tmp_cck_sec_pwdb))
1313 
1314 static void _rtl92e_dm_rx_path_sel_byrssi(struct net_device *dev)
1315 {
1316 	struct r8192_priv *priv = rtllib_priv(dev);
1317 	u8 i, max_rssi_index = 0, min_rssi_index = 0;
1318 	u8 sec_rssi_index = 0, rf_num = 0;
1319 	u8 tmp_max_rssi = 0, tmp_min_rssi = 0, tmp_sec_rssi = 0;
1320 	u8 cck_default_Rx = 0x2;
1321 	u8 cck_optional_Rx = 0x3;
1322 	long tmp_cck_max_pwdb = 0, tmp_cck_min_pwdb = 0, tmp_cck_sec_pwdb = 0;
1323 	u8 cck_rx_ver2_max_index = 0;
1324 	u8 cck_rx_ver2_sec_index = 0;
1325 	u8 cur_rf_rssi;
1326 	long cur_cck_pwdb;
1327 	static u8 disabled_rf_cnt, cck_Rx_Path_initialized;
1328 	u8 update_cck_rx_path;
1329 
1330 	if (!cck_Rx_Path_initialized) {
1331 		dm_rx_path_sel_table.cck_rx_path = (rtl92e_readb(dev, 0xa07) & 0xf);
1332 		cck_Rx_Path_initialized = 1;
1333 	}
1334 
1335 	dm_rx_path_sel_table.disabled_rf = 0xf;
1336 	dm_rx_path_sel_table.disabled_rf &= ~(rtl92e_readb(dev, 0xc04));
1337 
1338 	if (priv->rtllib->mode == WIRELESS_MODE_B)
1339 		dm_rx_path_sel_table.cck_method = CCK_Rx_Version_2;
1340 
1341 	for (i = 0; i < RF90_PATH_MAX; i++) {
1342 		dm_rx_path_sel_table.rf_rssi[i] = priv->stats.rx_rssi_percentage[i];
1343 
1344 		if (priv->brfpath_rxenable[i]) {
1345 			rf_num++;
1346 			cur_rf_rssi = dm_rx_path_sel_table.rf_rssi[i];
1347 
1348 			if (rf_num == 1) {
1349 				max_rssi_index = min_rssi_index = sec_rssi_index = i;
1350 				tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi;
1351 			} else if (rf_num == 2) {
1352 				if (cur_rf_rssi >= tmp_max_rssi) {
1353 					tmp_max_rssi = cur_rf_rssi;
1354 					max_rssi_index = i;
1355 				} else {
1356 					tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi;
1357 					sec_rssi_index = min_rssi_index = i;
1358 				}
1359 			} else {
1360 				if (cur_rf_rssi > tmp_max_rssi) {
1361 					tmp_sec_rssi = tmp_max_rssi;
1362 					sec_rssi_index = max_rssi_index;
1363 					tmp_max_rssi = cur_rf_rssi;
1364 					max_rssi_index = i;
1365 				} else if (cur_rf_rssi == tmp_max_rssi) {
1366 					tmp_sec_rssi = cur_rf_rssi;
1367 					sec_rssi_index = i;
1368 				} else if ((cur_rf_rssi < tmp_max_rssi) &&
1369 					   (cur_rf_rssi > tmp_sec_rssi)) {
1370 					tmp_sec_rssi = cur_rf_rssi;
1371 					sec_rssi_index = i;
1372 				} else if (cur_rf_rssi == tmp_sec_rssi) {
1373 					if (tmp_sec_rssi == tmp_min_rssi) {
1374 						tmp_sec_rssi = cur_rf_rssi;
1375 						sec_rssi_index = i;
1376 					}
1377 				} else if ((cur_rf_rssi < tmp_sec_rssi) &&
1378 					   (cur_rf_rssi > tmp_min_rssi)) {
1379 					;
1380 				} else if (cur_rf_rssi == tmp_min_rssi) {
1381 					if (tmp_sec_rssi == tmp_min_rssi) {
1382 						tmp_min_rssi = cur_rf_rssi;
1383 						min_rssi_index = i;
1384 					}
1385 				} else if (cur_rf_rssi < tmp_min_rssi) {
1386 					tmp_min_rssi = cur_rf_rssi;
1387 					min_rssi_index = i;
1388 				}
1389 			}
1390 		}
1391 	}
1392 
1393 	rf_num = 0;
1394 	if (dm_rx_path_sel_table.cck_method == CCK_Rx_Version_2) {
1395 		for (i = 0; i < RF90_PATH_MAX; i++) {
1396 			if (priv->brfpath_rxenable[i]) {
1397 				rf_num++;
1398 				cur_cck_pwdb =
1399 					 dm_rx_path_sel_table.cck_pwdb_sta[i];
1400 
1401 				if (rf_num == 1) {
1402 					cck_rx_ver2_max_index = i;
1403 					cck_rx_ver2_sec_index = i;
1404 					tmp_cck_max_pwdb = cur_cck_pwdb;
1405 					tmp_cck_min_pwdb = cur_cck_pwdb;
1406 					tmp_cck_sec_pwdb = cur_cck_pwdb;
1407 				} else if (rf_num == 2) {
1408 					if (cur_cck_pwdb >= tmp_cck_max_pwdb) {
1409 						tmp_cck_max_pwdb = cur_cck_pwdb;
1410 						cck_rx_ver2_max_index = i;
1411 					} else {
1412 						tmp_cck_sec_pwdb = cur_cck_pwdb;
1413 						tmp_cck_min_pwdb = cur_cck_pwdb;
1414 						cck_rx_ver2_sec_index = i;
1415 					}
1416 				} else {
1417 					if (cur_cck_pwdb > tmp_cck_max_pwdb) {
1418 						tmp_cck_sec_pwdb =
1419 							 tmp_cck_max_pwdb;
1420 						cck_rx_ver2_sec_index =
1421 							 cck_rx_ver2_max_index;
1422 						tmp_cck_max_pwdb = cur_cck_pwdb;
1423 						cck_rx_ver2_max_index = i;
1424 					} else if (cur_cck_pwdb ==
1425 						   tmp_cck_max_pwdb) {
1426 						tmp_cck_sec_pwdb = cur_cck_pwdb;
1427 						cck_rx_ver2_sec_index = i;
1428 					} else if (PWDB_IN_RANGE) {
1429 						tmp_cck_sec_pwdb = cur_cck_pwdb;
1430 						cck_rx_ver2_sec_index = i;
1431 					} else if (cur_cck_pwdb ==
1432 						   tmp_cck_sec_pwdb) {
1433 						if (tmp_cck_sec_pwdb ==
1434 						    tmp_cck_min_pwdb) {
1435 							tmp_cck_sec_pwdb =
1436 								 cur_cck_pwdb;
1437 							cck_rx_ver2_sec_index =
1438 								 i;
1439 						}
1440 					} else if ((cur_cck_pwdb < tmp_cck_sec_pwdb) &&
1441 						   (cur_cck_pwdb > tmp_cck_min_pwdb)) {
1442 						;
1443 					} else if (cur_cck_pwdb == tmp_cck_min_pwdb) {
1444 						if (tmp_cck_sec_pwdb == tmp_cck_min_pwdb)
1445 							tmp_cck_min_pwdb = cur_cck_pwdb;
1446 					} else if (cur_cck_pwdb < tmp_cck_min_pwdb) {
1447 						tmp_cck_min_pwdb = cur_cck_pwdb;
1448 					}
1449 				}
1450 			}
1451 		}
1452 	}
1453 
1454 	update_cck_rx_path = 0;
1455 	if (dm_rx_path_sel_table.cck_method == CCK_Rx_Version_2) {
1456 		cck_default_Rx = cck_rx_ver2_max_index;
1457 		cck_optional_Rx = cck_rx_ver2_sec_index;
1458 		if (tmp_cck_max_pwdb != -64)
1459 			update_cck_rx_path = 1;
1460 	}
1461 
1462 	if (tmp_min_rssi < dm_rx_path_sel_table.ss_th_low && disabled_rf_cnt < 2) {
1463 		if ((tmp_max_rssi - tmp_min_rssi) >=
1464 		     dm_rx_path_sel_table.diff_th) {
1465 			dm_rx_path_sel_table.rf_enable_rssi_th[min_rssi_index] =
1466 				 tmp_max_rssi + 5;
1467 			rtl92e_set_bb_reg(dev, rOFDM0_TRxPathEnable,
1468 					  0x1 << min_rssi_index, 0x0);
1469 			rtl92e_set_bb_reg(dev, rOFDM1_TRxPathEnable,
1470 					  0x1 << min_rssi_index, 0x0);
1471 			disabled_rf_cnt++;
1472 		}
1473 		if (dm_rx_path_sel_table.cck_method == CCK_Rx_Version_1) {
1474 			cck_default_Rx = max_rssi_index;
1475 			cck_optional_Rx = sec_rssi_index;
1476 			if (tmp_max_rssi)
1477 				update_cck_rx_path = 1;
1478 		}
1479 	}
1480 
1481 	if (update_cck_rx_path) {
1482 		dm_rx_path_sel_table.cck_rx_path = (cck_default_Rx << 2) |
1483 						(cck_optional_Rx);
1484 		rtl92e_set_bb_reg(dev, rCCK0_AFESetting, 0x0f000000,
1485 				  dm_rx_path_sel_table.cck_rx_path);
1486 	}
1487 
1488 	if (dm_rx_path_sel_table.disabled_rf) {
1489 		for (i = 0; i < 4; i++) {
1490 			if ((dm_rx_path_sel_table.disabled_rf >> i) & 0x1) {
1491 				if (tmp_max_rssi >=
1492 				    dm_rx_path_sel_table.rf_enable_rssi_th[i]) {
1493 					rtl92e_set_bb_reg(dev,
1494 							  rOFDM0_TRxPathEnable,
1495 							  0x1 << i, 0x1);
1496 					rtl92e_set_bb_reg(dev,
1497 							  rOFDM1_TRxPathEnable,
1498 							  0x1 << i, 0x1);
1499 					dm_rx_path_sel_table.rf_enable_rssi_th[i]
1500 						 = 100;
1501 					disabled_rf_cnt--;
1502 				}
1503 			}
1504 		}
1505 	}
1506 }
1507 
1508 static void _rtl92e_dm_check_rx_path_selection(struct net_device *dev)
1509 {
1510 	struct r8192_priv *priv = rtllib_priv(dev);
1511 
1512 	schedule_delayed_work(&priv->rfpath_check_wq, 0);
1513 }
1514 
1515 static void _rtl92e_dm_init_fsync(struct net_device *dev)
1516 {
1517 	struct r8192_priv *priv = rtllib_priv(dev);
1518 
1519 	priv->rtllib->fsync_time_interval = 500;
1520 	priv->rtllib->fsync_rate_bitmap = 0x0f000800;
1521 	priv->rtllib->fsync_rssi_threshold = 30;
1522 	priv->rtllib->bfsync_enable = false;
1523 	priv->rtllib->fsync_multiple_timeinterval = 3;
1524 	priv->rtllib->fsync_firstdiff_ratethreshold = 100;
1525 	priv->rtllib->fsync_seconddiff_ratethreshold = 200;
1526 	priv->rtllib->fsync_state = DEFAULT_FSYNC;
1527 
1528 	timer_setup(&priv->fsync_timer, _rtl92e_dm_fsync_timer_callback, 0);
1529 }
1530 
1531 static void _rtl92e_dm_deinit_fsync(struct net_device *dev)
1532 {
1533 	struct r8192_priv *priv = rtllib_priv(dev);
1534 
1535 	del_timer_sync(&priv->fsync_timer);
1536 }
1537 
1538 static void _rtl92e_dm_fsync_timer_callback(struct timer_list *t)
1539 {
1540 	struct r8192_priv *priv = from_timer(priv, t, fsync_timer);
1541 	struct net_device *dev = priv->rtllib->dev;
1542 	u32 rate_index, rate_count = 0, rate_count_diff = 0;
1543 	bool		bSwitchFromCountDiff = false;
1544 	bool		bDoubleTimeInterval = false;
1545 
1546 	if (priv->rtllib->link_state == MAC80211_LINKED &&
1547 	    priv->rtllib->bfsync_enable &&
1548 	    (priv->rtllib->ht_info->iot_action & HT_IOT_ACT_CDD_FSYNC)) {
1549 		u32 rate_bitmap;
1550 
1551 		for (rate_index = 0; rate_index <= 27; rate_index++) {
1552 			rate_bitmap  = 1 << rate_index;
1553 			if (priv->rtllib->fsync_rate_bitmap &  rate_bitmap)
1554 				rate_count +=
1555 				   priv->stats.received_rate_histogram[1]
1556 				   [rate_index];
1557 		}
1558 
1559 		if (rate_count < priv->rate_record)
1560 			rate_count_diff = 0xffffffff - rate_count +
1561 					  priv->rate_record;
1562 		else
1563 			rate_count_diff = rate_count - priv->rate_record;
1564 		if (rate_count_diff < priv->rate_count_diff_rec) {
1565 			u32 DiffNum = priv->rate_count_diff_rec -
1566 				      rate_count_diff;
1567 			if (DiffNum >=
1568 			    priv->rtllib->fsync_seconddiff_ratethreshold)
1569 				priv->continue_diff_count++;
1570 			else
1571 				priv->continue_diff_count = 0;
1572 
1573 			if (priv->continue_diff_count >= 2) {
1574 				bSwitchFromCountDiff = true;
1575 				priv->continue_diff_count = 0;
1576 			}
1577 		} else {
1578 			priv->continue_diff_count = 0;
1579 		}
1580 
1581 		if (rate_count_diff <=
1582 		    priv->rtllib->fsync_firstdiff_ratethreshold) {
1583 			bSwitchFromCountDiff = true;
1584 			priv->continue_diff_count = 0;
1585 		}
1586 		priv->rate_record = rate_count;
1587 		priv->rate_count_diff_rec = rate_count_diff;
1588 		if (priv->undecorated_smoothed_pwdb >
1589 		    priv->rtllib->fsync_rssi_threshold &&
1590 		    bSwitchFromCountDiff) {
1591 			bDoubleTimeInterval = true;
1592 			priv->bswitch_fsync = !priv->bswitch_fsync;
1593 			if (priv->bswitch_fsync) {
1594 				rtl92e_writeb(dev, 0xC36, 0x1c);
1595 				rtl92e_writeb(dev, 0xC3e, 0x90);
1596 			} else {
1597 				rtl92e_writeb(dev, 0xC36, 0x5c);
1598 				rtl92e_writeb(dev, 0xC3e, 0x96);
1599 			}
1600 		} else if (priv->undecorated_smoothed_pwdb <=
1601 			   priv->rtllib->fsync_rssi_threshold) {
1602 			if (priv->bswitch_fsync) {
1603 				priv->bswitch_fsync  = false;
1604 				rtl92e_writeb(dev, 0xC36, 0x5c);
1605 				rtl92e_writeb(dev, 0xC3e, 0x96);
1606 			}
1607 		}
1608 		if (bDoubleTimeInterval) {
1609 			if (timer_pending(&priv->fsync_timer))
1610 				del_timer_sync(&priv->fsync_timer);
1611 			priv->fsync_timer.expires = jiffies +
1612 				 msecs_to_jiffies(priv->rtllib->fsync_time_interval *
1613 				 priv->rtllib->fsync_multiple_timeinterval);
1614 			add_timer(&priv->fsync_timer);
1615 		} else {
1616 			if (timer_pending(&priv->fsync_timer))
1617 				del_timer_sync(&priv->fsync_timer);
1618 			priv->fsync_timer.expires = jiffies +
1619 				 msecs_to_jiffies(priv->rtllib->fsync_time_interval);
1620 			add_timer(&priv->fsync_timer);
1621 		}
1622 	} else {
1623 		if (priv->bswitch_fsync) {
1624 			priv->bswitch_fsync  = false;
1625 			rtl92e_writeb(dev, 0xC36, 0x5c);
1626 			rtl92e_writeb(dev, 0xC3e, 0x96);
1627 		}
1628 		priv->continue_diff_count = 0;
1629 		rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c52cd);
1630 	}
1631 }
1632 
1633 static void _rtl92e_dm_start_hw_fsync(struct net_device *dev)
1634 {
1635 	u8 rf_timing = 0x77;
1636 	struct r8192_priv *priv = rtllib_priv(dev);
1637 
1638 	rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c12cf);
1639 	priv->rtllib->set_hw_reg_handler(dev, HW_VAR_RF_TIMING,
1640 				      (u8 *)(&rf_timing));
1641 	rtl92e_writeb(dev, 0xc3b, 0x41);
1642 }
1643 
1644 static void _rtl92e_dm_end_hw_fsync(struct net_device *dev)
1645 {
1646 	u8 rf_timing = 0xaa;
1647 	struct r8192_priv *priv = rtllib_priv(dev);
1648 
1649 	rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c52cd);
1650 	priv->rtllib->set_hw_reg_handler(dev, HW_VAR_RF_TIMING, (u8 *)
1651 				     (&rf_timing));
1652 	rtl92e_writeb(dev, 0xc3b, 0x49);
1653 }
1654 
1655 static void _rtl92e_dm_end_sw_fsync(struct net_device *dev)
1656 {
1657 	struct r8192_priv *priv = rtllib_priv(dev);
1658 
1659 	del_timer_sync(&(priv->fsync_timer));
1660 
1661 	if (priv->bswitch_fsync) {
1662 		priv->bswitch_fsync  = false;
1663 
1664 		rtl92e_writeb(dev, 0xC36, 0x5c);
1665 
1666 		rtl92e_writeb(dev, 0xC3e, 0x96);
1667 	}
1668 
1669 	priv->continue_diff_count = 0;
1670 	rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c52cd);
1671 }
1672 
1673 static void _rtl92e_dm_start_sw_fsync(struct net_device *dev)
1674 {
1675 	struct r8192_priv *priv = rtllib_priv(dev);
1676 	u32 rate_index;
1677 	u32 rate_bitmap;
1678 
1679 	priv->rate_record = 0;
1680 	priv->continue_diff_count = 0;
1681 	priv->rate_count_diff_rec = 0;
1682 	priv->bswitch_fsync  = false;
1683 
1684 	if (priv->rtllib->mode == WIRELESS_MODE_N_24G) {
1685 		priv->rtllib->fsync_firstdiff_ratethreshold = 600;
1686 		priv->rtllib->fsync_seconddiff_ratethreshold = 0xffff;
1687 	} else {
1688 		priv->rtllib->fsync_firstdiff_ratethreshold = 200;
1689 		priv->rtllib->fsync_seconddiff_ratethreshold = 200;
1690 	}
1691 	for (rate_index = 0; rate_index <= 27; rate_index++) {
1692 		rate_bitmap  = 1 << rate_index;
1693 		if (priv->rtllib->fsync_rate_bitmap & rate_bitmap)
1694 			priv->rate_record +=
1695 				 priv->stats.received_rate_histogram[1]
1696 				[rate_index];
1697 	}
1698 	if (timer_pending(&priv->fsync_timer))
1699 		del_timer_sync(&priv->fsync_timer);
1700 	priv->fsync_timer.expires = jiffies +
1701 				    msecs_to_jiffies(priv->rtllib->fsync_time_interval);
1702 	add_timer(&priv->fsync_timer);
1703 
1704 	rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c12cd);
1705 }
1706 
1707 static void _rtl92e_dm_check_fsync(struct net_device *dev)
1708 {
1709 #define	RegC38_Default			0
1710 #define	RegC38_NonFsync_Other_AP	1
1711 #define	RegC38_Fsync_AP_BCM		2
1712 	struct r8192_priv *priv = rtllib_priv(dev);
1713 	static u8 reg_c38_State = RegC38_Default;
1714 
1715 	if (priv->rtllib->link_state == MAC80211_LINKED &&
1716 	    priv->rtllib->ht_info->iot_peer == HT_IOT_PEER_BROADCOM) {
1717 		if (priv->rtllib->bfsync_enable == 0) {
1718 			switch (priv->rtllib->fsync_state) {
1719 			case DEFAULT_FSYNC:
1720 				_rtl92e_dm_start_hw_fsync(dev);
1721 				priv->rtllib->fsync_state = HW_FSYNC;
1722 				break;
1723 			case SW_FSYNC:
1724 				_rtl92e_dm_end_sw_fsync(dev);
1725 				_rtl92e_dm_start_hw_fsync(dev);
1726 				priv->rtllib->fsync_state = HW_FSYNC;
1727 				break;
1728 			default:
1729 				break;
1730 			}
1731 		} else {
1732 			switch (priv->rtllib->fsync_state) {
1733 			case DEFAULT_FSYNC:
1734 				_rtl92e_dm_start_sw_fsync(dev);
1735 				priv->rtllib->fsync_state = SW_FSYNC;
1736 				break;
1737 			case HW_FSYNC:
1738 				_rtl92e_dm_end_hw_fsync(dev);
1739 				_rtl92e_dm_start_sw_fsync(dev);
1740 				priv->rtllib->fsync_state = SW_FSYNC;
1741 				break;
1742 			default:
1743 				break;
1744 			}
1745 		}
1746 		if (reg_c38_State != RegC38_Fsync_AP_BCM) {
1747 			rtl92e_writeb(dev, rOFDM0_RxDetector3, 0x95);
1748 
1749 			reg_c38_State = RegC38_Fsync_AP_BCM;
1750 		}
1751 	} else {
1752 		switch (priv->rtllib->fsync_state) {
1753 		case HW_FSYNC:
1754 			_rtl92e_dm_end_hw_fsync(dev);
1755 			priv->rtllib->fsync_state = DEFAULT_FSYNC;
1756 			break;
1757 		case SW_FSYNC:
1758 			_rtl92e_dm_end_sw_fsync(dev);
1759 			priv->rtllib->fsync_state = DEFAULT_FSYNC;
1760 			break;
1761 		default:
1762 			break;
1763 		}
1764 
1765 		if (priv->rtllib->link_state == MAC80211_LINKED) {
1766 			if (priv->undecorated_smoothed_pwdb <=
1767 			    RegC38_TH) {
1768 				if (reg_c38_State !=
1769 				    RegC38_NonFsync_Other_AP) {
1770 					rtl92e_writeb(dev,
1771 						      rOFDM0_RxDetector3,
1772 						      0x90);
1773 
1774 					reg_c38_State =
1775 					     RegC38_NonFsync_Other_AP;
1776 				}
1777 			} else if (priv->undecorated_smoothed_pwdb >=
1778 				   (RegC38_TH + 5)) {
1779 				if (reg_c38_State) {
1780 					rtl92e_writeb(dev,
1781 						rOFDM0_RxDetector3,
1782 						priv->framesync);
1783 					reg_c38_State = RegC38_Default;
1784 				}
1785 			}
1786 		} else {
1787 			if (reg_c38_State) {
1788 				rtl92e_writeb(dev, rOFDM0_RxDetector3,
1789 					      priv->framesync);
1790 				reg_c38_State = RegC38_Default;
1791 			}
1792 		}
1793 	}
1794 }
1795 
1796 /*---------------------------Define function prototype------------------------*/
1797 static void _rtl92e_dm_init_dynamic_tx_power(struct net_device *dev)
1798 {
1799 	struct r8192_priv *priv = rtllib_priv(dev);
1800 
1801 	priv->rtllib->bdynamic_txpower_enable = true;
1802 	priv->last_dtp_flag_high = false;
1803 	priv->last_dtp_flag_low = false;
1804 	priv->dynamic_tx_high_pwr = false;
1805 	priv->dynamic_tx_low_pwr = false;
1806 }
1807 
1808 static void _rtl92e_dm_dynamic_tx_power(struct net_device *dev)
1809 {
1810 	struct r8192_priv *priv = rtllib_priv(dev);
1811 	unsigned int txhipower_threshold = 0;
1812 	unsigned int txlowpower_threshold = 0;
1813 
1814 	if (!priv->rtllib->bdynamic_txpower_enable) {
1815 		priv->dynamic_tx_high_pwr = false;
1816 		priv->dynamic_tx_low_pwr = false;
1817 		return;
1818 	}
1819 	if ((priv->rtllib->ht_info->iot_peer == HT_IOT_PEER_ATHEROS) &&
1820 	    (priv->rtllib->mode == WIRELESS_MODE_G)) {
1821 		txhipower_threshold = TX_POWER_ATHEROAP_THRESH_HIGH;
1822 		txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW;
1823 	} else {
1824 		txhipower_threshold = TX_POWER_NEAR_FIELD_THRESH_HIGH;
1825 		txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW;
1826 	}
1827 
1828 	if (priv->rtllib->link_state == MAC80211_LINKED) {
1829 		if (priv->undecorated_smoothed_pwdb >= txhipower_threshold) {
1830 			priv->dynamic_tx_high_pwr = true;
1831 			priv->dynamic_tx_low_pwr = false;
1832 		} else {
1833 			if (priv->undecorated_smoothed_pwdb <
1834 			    txlowpower_threshold && priv->dynamic_tx_high_pwr)
1835 				priv->dynamic_tx_high_pwr = false;
1836 			if (priv->undecorated_smoothed_pwdb < 35)
1837 				priv->dynamic_tx_low_pwr = true;
1838 			else if (priv->undecorated_smoothed_pwdb >= 40)
1839 				priv->dynamic_tx_low_pwr = false;
1840 		}
1841 	} else {
1842 		priv->dynamic_tx_high_pwr = false;
1843 		priv->dynamic_tx_low_pwr = false;
1844 	}
1845 
1846 	if ((priv->dynamic_tx_high_pwr != priv->last_dtp_flag_high) ||
1847 	    (priv->dynamic_tx_low_pwr != priv->last_dtp_flag_low)) {
1848 		rtl92e_set_tx_power(dev, priv->rtllib->current_network.channel);
1849 	}
1850 	priv->last_dtp_flag_high = priv->dynamic_tx_high_pwr;
1851 	priv->last_dtp_flag_low = priv->dynamic_tx_low_pwr;
1852 }
1853 
1854 static void _rtl92e_dm_check_txrateandretrycount(struct net_device *dev)
1855 {
1856 	struct r8192_priv *priv = rtllib_priv(dev);
1857 	struct rtllib_device *ieee = priv->rtllib;
1858 
1859 	ieee->softmac_stats.CurrentShowTxate = rtl92e_readb(dev, CURRENT_TX_RATE_REG);
1860 	ieee->softmac_stats.last_packet_rate = rtl92e_readb(dev, INITIAL_TX_RATE_REG);
1861 	ieee->softmac_stats.txretrycount = rtl92e_readl(dev, TX_RETRY_COUNT_REG);
1862 }
1863 
1864 static void _rtl92e_dm_send_rssi_to_fw(struct net_device *dev)
1865 {
1866 	struct r8192_priv *priv = rtllib_priv(dev);
1867 
1868 	rtl92e_writeb(dev, DRIVER_RSSI, priv->undecorated_smoothed_pwdb);
1869 }
1870