1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2009-2012  Realtek Corporation.*/
3 
4 #include "../wifi.h"
5 #include "../base.h"
6 #include "../pci.h"
7 #include "../core.h"
8 #include "reg.h"
9 #include "def.h"
10 #include "phy.h"
11 #include "dm.h"
12 #include "../rtl8723com/dm_common.h"
13 #include "fw.h"
14 #include "hal_btc.h"
15 
16 static u8 rtl8723e_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw)
17 {
18 	struct rtl_priv *rtlpriv = rtl_priv(hw);
19 	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
20 	struct rtl_mac *mac = rtl_mac(rtlpriv);
21 	long rssi_val_min = 0;
22 
23 	if (mac->link_state == MAC80211_LINKED &&
24 	    mac->opmode == NL80211_IFTYPE_STATION &&
25 	    rtlpriv->link_info.bcn_rx_inperiod == 0)
26 		return 0;
27 
28 	if ((dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) &&
29 	    (dm_digtable->cursta_cstate == DIG_STA_CONNECT)) {
30 		if (rtlpriv->dm.entry_min_undec_sm_pwdb != 0)
31 			rssi_val_min =
32 			    (rtlpriv->dm.entry_min_undec_sm_pwdb >
33 			     rtlpriv->dm.undec_sm_pwdb) ?
34 			    rtlpriv->dm.undec_sm_pwdb :
35 			    rtlpriv->dm.entry_min_undec_sm_pwdb;
36 		else
37 			rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
38 	} else if (dm_digtable->cursta_cstate == DIG_STA_CONNECT ||
39 		   dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT) {
40 		rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
41 	} else if (dm_digtable->curmultista_cstate ==
42 		DIG_MULTISTA_CONNECT) {
43 		rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb;
44 	}
45 
46 	return (u8) rssi_val_min;
47 }
48 
49 static void rtl8723e_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
50 {
51 	u32 ret_value;
52 	struct rtl_priv *rtlpriv = rtl_priv(hw);
53 	struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
54 
55 	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
56 	falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
57 
58 	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
59 	falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
60 	falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
61 
62 	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
63 	falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
64 	falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
65 	    falsealm_cnt->cnt_rate_illegal +
66 	    falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail;
67 
68 	rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1);
69 	ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0);
70 	falsealm_cnt->cnt_cck_fail = ret_value;
71 
72 	ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3);
73 	falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
74 	falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail +
75 				 falsealm_cnt->cnt_rate_illegal +
76 				 falsealm_cnt->cnt_crc8_fail +
77 				 falsealm_cnt->cnt_mcs_fail +
78 				 falsealm_cnt->cnt_cck_fail);
79 
80 	rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1);
81 	rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0);
82 	rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0);
83 	rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2);
84 
85 	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
86 		 "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
87 		 falsealm_cnt->cnt_parity_fail,
88 		 falsealm_cnt->cnt_rate_illegal,
89 		 falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail);
90 
91 	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
92 		 "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
93 		 falsealm_cnt->cnt_ofdm_fail,
94 		 falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all);
95 }
96 
97 static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw)
98 {
99 	struct rtl_priv *rtlpriv = rtl_priv(hw);
100 	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
101 	u8 value_igi = dm_digtable->cur_igvalue;
102 
103 	if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
104 		value_igi--;
105 	else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1)
106 		value_igi += 0;
107 	else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2)
108 		value_igi++;
109 	else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2)
110 		value_igi += 2;
111 	if (value_igi > DM_DIG_FA_UPPER)
112 		value_igi = DM_DIG_FA_UPPER;
113 	else if (value_igi < DM_DIG_FA_LOWER)
114 		value_igi = DM_DIG_FA_LOWER;
115 	if (rtlpriv->falsealm_cnt.cnt_all > 10000)
116 		value_igi = 0x32;
117 
118 	dm_digtable->cur_igvalue = value_igi;
119 	rtl8723e_dm_write_dig(hw);
120 }
121 
122 static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw)
123 {
124 	struct rtl_priv *rtlpriv = rtl_priv(hw);
125 	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
126 
127 	if (rtlpriv->falsealm_cnt.cnt_all > dm_digtable->fa_highthresh) {
128 		if ((dm_digtable->back_val - 2) <
129 		    dm_digtable->back_range_min)
130 			dm_digtable->back_val =
131 			    dm_digtable->back_range_min;
132 		else
133 			dm_digtable->back_val -= 2;
134 	} else if (rtlpriv->falsealm_cnt.cnt_all < dm_digtable->fa_lowthresh) {
135 		if ((dm_digtable->back_val + 2) >
136 		    dm_digtable->back_range_max)
137 			dm_digtable->back_val =
138 			    dm_digtable->back_range_max;
139 		else
140 			dm_digtable->back_val += 2;
141 	}
142 
143 	if ((dm_digtable->rssi_val_min + 10 - dm_digtable->back_val) >
144 	    dm_digtable->rx_gain_max)
145 		dm_digtable->cur_igvalue = dm_digtable->rx_gain_max;
146 	else if ((dm_digtable->rssi_val_min + 10 -
147 		  dm_digtable->back_val) < dm_digtable->rx_gain_min)
148 		dm_digtable->cur_igvalue = dm_digtable->rx_gain_min;
149 	else
150 		dm_digtable->cur_igvalue = dm_digtable->rssi_val_min + 10 -
151 		    dm_digtable->back_val;
152 
153 	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
154 		 "rssi_val_min = %x back_val %x\n",
155 		  dm_digtable->rssi_val_min, dm_digtable->back_val);
156 
157 	rtl8723e_dm_write_dig(hw);
158 }
159 
160 static void rtl8723e_dm_initial_gain_multi_sta(struct ieee80211_hw *hw)
161 {
162 	static u8 binitialized;
163 	struct rtl_priv *rtlpriv = rtl_priv(hw);
164 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
165 	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
166 	long rssi_strength = rtlpriv->dm.entry_min_undec_sm_pwdb;
167 	bool multi_sta = false;
168 
169 	if (mac->opmode == NL80211_IFTYPE_ADHOC)
170 		multi_sta = true;
171 
172 	if (!multi_sta || (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT)) {
173 		binitialized = false;
174 		dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
175 		return;
176 	} else if (!binitialized) {
177 		binitialized = true;
178 		dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0;
179 		dm_digtable->cur_igvalue = 0x20;
180 		rtl8723e_dm_write_dig(hw);
181 	}
182 
183 	if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) {
184 		if ((rssi_strength < dm_digtable->rssi_lowthresh) &&
185 		    (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) {
186 
187 			if (dm_digtable->dig_ext_port_stage ==
188 			    DIG_EXT_PORT_STAGE_2) {
189 				dm_digtable->cur_igvalue = 0x20;
190 				rtl8723e_dm_write_dig(hw);
191 			}
192 
193 			dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_1;
194 		} else if (rssi_strength > dm_digtable->rssi_highthresh) {
195 			dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_2;
196 			rtl92c_dm_ctrl_initgain_by_fa(hw);
197 		}
198 	} else if (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) {
199 		dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0;
200 		dm_digtable->cur_igvalue = 0x20;
201 		rtl8723e_dm_write_dig(hw);
202 	}
203 
204 	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
205 		 "curmultista_cstate = %x dig_ext_port_stage %x\n",
206 		 dm_digtable->curmultista_cstate,
207 		 dm_digtable->dig_ext_port_stage);
208 }
209 
210 static void rtl8723e_dm_initial_gain_sta(struct ieee80211_hw *hw)
211 {
212 	struct rtl_priv *rtlpriv = rtl_priv(hw);
213 	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
214 
215 	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
216 		 "presta_cstate = %x, cursta_cstate = %x\n",
217 		  dm_digtable->presta_cstate,
218 		  dm_digtable->cursta_cstate);
219 
220 	if (dm_digtable->presta_cstate == dm_digtable->cursta_cstate ||
221 	    dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT ||
222 	    dm_digtable->cursta_cstate == DIG_STA_CONNECT) {
223 		if (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) {
224 			dm_digtable->rssi_val_min =
225 			    rtl8723e_dm_initial_gain_min_pwdb(hw);
226 			rtl92c_dm_ctrl_initgain_by_rssi(hw);
227 		}
228 	} else {
229 		dm_digtable->rssi_val_min = 0;
230 		dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
231 		dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
232 		dm_digtable->cur_igvalue = 0x20;
233 		dm_digtable->pre_igvalue = 0;
234 		rtl8723e_dm_write_dig(hw);
235 	}
236 }
237 
238 static void rtl8723e_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
239 {
240 	struct rtl_priv *rtlpriv = rtl_priv(hw);
241 	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
242 
243 	if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) {
244 		dm_digtable->rssi_val_min = rtl8723e_dm_initial_gain_min_pwdb(hw);
245 
246 		if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LOWRSSI) {
247 			if (dm_digtable->rssi_val_min <= 25)
248 				dm_digtable->cur_cck_pd_state =
249 				    CCK_PD_STAGE_LOWRSSI;
250 			else
251 				dm_digtable->cur_cck_pd_state =
252 				    CCK_PD_STAGE_HIGHRSSI;
253 		} else {
254 			if (dm_digtable->rssi_val_min <= 20)
255 				dm_digtable->cur_cck_pd_state =
256 				    CCK_PD_STAGE_LOWRSSI;
257 			else
258 				dm_digtable->cur_cck_pd_state =
259 				    CCK_PD_STAGE_HIGHRSSI;
260 		}
261 	} else {
262 		dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX;
263 	}
264 
265 	if (dm_digtable->pre_cck_pd_state != dm_digtable->cur_cck_pd_state) {
266 		if (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI) {
267 			if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800)
268 				dm_digtable->cur_cck_fa_state =
269 				    CCK_FA_STAGE_HIGH;
270 			else
271 				dm_digtable->cur_cck_fa_state =
272 				    CCK_FA_STAGE_LOW;
273 			if (dm_digtable->pre_cck_fa_state !=
274 			    dm_digtable->cur_cck_fa_state) {
275 				if (dm_digtable->cur_cck_fa_state ==
276 				    CCK_FA_STAGE_LOW)
277 					rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
278 						      0x83);
279 				else
280 					rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
281 						      0xcd);
282 
283 				dm_digtable->pre_cck_fa_state =
284 				    dm_digtable->cur_cck_fa_state;
285 			}
286 
287 			rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40);
288 
289 		} else {
290 			rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
291 			rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47);
292 			dm_digtable->pre_cck_fa_state = 0;
293 			dm_digtable->cur_cck_fa_state = 0;
294 
295 		}
296 		dm_digtable->pre_cck_pd_state = dm_digtable->cur_cck_pd_state;
297 	}
298 
299 	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
300 		 "CCKPDStage=%x\n", dm_digtable->cur_cck_pd_state);
301 
302 }
303 
304 static void rtl8723e_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)
305 {
306 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
307 	struct rtl_priv *rtlpriv = rtl_priv(hw);
308 	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
309 
310 	if (mac->act_scanning)
311 		return;
312 
313 	if (mac->link_state >= MAC80211_LINKED)
314 		dm_digtable->cursta_cstate = DIG_STA_CONNECT;
315 	else
316 		dm_digtable->cursta_cstate = DIG_STA_DISCONNECT;
317 
318 	rtl8723e_dm_initial_gain_sta(hw);
319 	rtl8723e_dm_initial_gain_multi_sta(hw);
320 	rtl8723e_dm_cck_packet_detection_thresh(hw);
321 
322 	dm_digtable->presta_cstate = dm_digtable->cursta_cstate;
323 
324 }
325 
326 static void rtl8723e_dm_dig(struct ieee80211_hw *hw)
327 {
328 	struct rtl_priv *rtlpriv = rtl_priv(hw);
329 	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
330 
331 	if (!rtlpriv->dm.dm_initialgain_enable)
332 		return;
333 	if (!dm_digtable->dig_enable_flag)
334 		return;
335 
336 	rtl8723e_dm_ctrl_initgain_by_twoport(hw);
337 
338 }
339 
340 static void rtl8723e_dm_dynamic_txpower(struct ieee80211_hw *hw)
341 {
342 	struct rtl_priv *rtlpriv = rtl_priv(hw);
343 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
344 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
345 	long undec_sm_pwdb;
346 
347 	if (!rtlpriv->dm.dynamic_txpower_enable)
348 		return;
349 
350 	if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
351 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
352 		return;
353 	}
354 
355 	if ((mac->link_state < MAC80211_LINKED) &&
356 	    (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
357 		RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
358 			 "Not connected to any\n");
359 
360 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
361 
362 		rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
363 		return;
364 	}
365 
366 	if (mac->link_state >= MAC80211_LINKED) {
367 		if (mac->opmode == NL80211_IFTYPE_ADHOC) {
368 			undec_sm_pwdb =
369 			    rtlpriv->dm.entry_min_undec_sm_pwdb;
370 			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
371 				 "AP Client PWDB = 0x%lx\n",
372 				  undec_sm_pwdb);
373 		} else {
374 			undec_sm_pwdb =
375 			    rtlpriv->dm.undec_sm_pwdb;
376 			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
377 				 "STA Default Port PWDB = 0x%lx\n",
378 				  undec_sm_pwdb);
379 		}
380 	} else {
381 		undec_sm_pwdb =
382 		    rtlpriv->dm.entry_min_undec_sm_pwdb;
383 
384 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
385 			 "AP Ext Port PWDB = 0x%lx\n",
386 			  undec_sm_pwdb);
387 	}
388 
389 	if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
390 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
391 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
392 			 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n");
393 	} else if ((undec_sm_pwdb <
394 		    (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
395 		   (undec_sm_pwdb >=
396 		    TX_POWER_NEAR_FIELD_THRESH_LVL1)) {
397 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
398 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
399 			 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n");
400 	} else if (undec_sm_pwdb <
401 		   (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
402 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
403 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
404 			 "TXHIGHPWRLEVEL_NORMAL\n");
405 	}
406 
407 	if (rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl) {
408 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
409 			 "PHY_SetTxPowerLevel8192S() Channel = %d\n",
410 			  rtlphy->current_channel);
411 		rtl8723e_phy_set_txpower_level(hw, rtlphy->current_channel);
412 	}
413 
414 	rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
415 }
416 
417 void rtl8723e_dm_write_dig(struct ieee80211_hw *hw)
418 {
419 	struct rtl_priv *rtlpriv = rtl_priv(hw);
420 	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
421 
422 	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
423 		 "cur_igvalue = 0x%x, pre_igvalue = 0x%x, back_val = %d\n",
424 		  dm_digtable->cur_igvalue, dm_digtable->pre_igvalue,
425 		  dm_digtable->back_val);
426 
427 	if (dm_digtable->pre_igvalue != dm_digtable->cur_igvalue) {
428 		rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
429 			      dm_digtable->cur_igvalue);
430 		rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f,
431 			      dm_digtable->cur_igvalue);
432 
433 		dm_digtable->pre_igvalue = dm_digtable->cur_igvalue;
434 	}
435 }
436 
437 static void rtl8723e_dm_pwdb_monitor(struct ieee80211_hw *hw)
438 {
439 }
440 
441 static void rtl8723e_dm_check_edca_turbo(struct ieee80211_hw *hw)
442 {
443 	struct rtl_priv *rtlpriv = rtl_priv(hw);
444 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
445 
446 	static u64 last_txok_cnt;
447 	static u64 last_rxok_cnt;
448 	static u32 last_bt_edca_ul;
449 	static u32 last_bt_edca_dl;
450 	u64 cur_txok_cnt = 0;
451 	u64 cur_rxok_cnt = 0;
452 	u32 edca_be_ul = 0x5ea42b;
453 	u32 edca_be_dl = 0x5ea42b;
454 	bool bt_change_edca = false;
455 
456 	if ((last_bt_edca_ul != rtlpriv->btcoexist.bt_edca_ul) ||
457 	    (last_bt_edca_dl != rtlpriv->btcoexist.bt_edca_dl)) {
458 		rtlpriv->dm.current_turbo_edca = false;
459 		last_bt_edca_ul = rtlpriv->btcoexist.bt_edca_ul;
460 		last_bt_edca_dl = rtlpriv->btcoexist.bt_edca_dl;
461 	}
462 
463 	if (rtlpriv->btcoexist.bt_edca_ul != 0) {
464 		edca_be_ul = rtlpriv->btcoexist.bt_edca_ul;
465 		bt_change_edca = true;
466 	}
467 
468 	if (rtlpriv->btcoexist.bt_edca_dl != 0) {
469 		edca_be_ul = rtlpriv->btcoexist.bt_edca_dl;
470 		bt_change_edca = true;
471 	}
472 
473 	if (mac->link_state != MAC80211_LINKED) {
474 		rtlpriv->dm.current_turbo_edca = false;
475 		return;
476 	}
477 	if ((bt_change_edca) || ((!rtlpriv->dm.is_any_nonbepkts) &&
478 	     (!rtlpriv->dm.disable_framebursting))) {
479 
480 		cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
481 		cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
482 
483 		if (cur_rxok_cnt > 4 * cur_txok_cnt) {
484 			if (!rtlpriv->dm.is_cur_rdlstate ||
485 			    !rtlpriv->dm.current_turbo_edca) {
486 				rtl_write_dword(rtlpriv,
487 						REG_EDCA_BE_PARAM,
488 						edca_be_dl);
489 				rtlpriv->dm.is_cur_rdlstate = true;
490 			}
491 		} else {
492 			if (rtlpriv->dm.is_cur_rdlstate ||
493 			    !rtlpriv->dm.current_turbo_edca) {
494 				rtl_write_dword(rtlpriv,
495 						REG_EDCA_BE_PARAM,
496 						edca_be_ul);
497 				rtlpriv->dm.is_cur_rdlstate = false;
498 			}
499 		}
500 		rtlpriv->dm.current_turbo_edca = true;
501 	} else {
502 		if (rtlpriv->dm.current_turbo_edca) {
503 			u8 tmp = AC0_BE;
504 			rtlpriv->cfg->ops->set_hw_reg(hw,
505 						      HW_VAR_AC_PARAM,
506 						      (u8 *)(&tmp));
507 			rtlpriv->dm.current_turbo_edca = false;
508 		}
509 	}
510 
511 	rtlpriv->dm.is_any_nonbepkts = false;
512 	last_txok_cnt = rtlpriv->stats.txbytesunicast;
513 	last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
514 }
515 
516 static void rtl8723e_dm_initialize_txpower_tracking_thermalmeter(
517 				struct ieee80211_hw *hw)
518 {
519 	struct rtl_priv *rtlpriv = rtl_priv(hw);
520 
521 	rtlpriv->dm.txpower_tracking = true;
522 	rtlpriv->dm.txpower_trackinginit = false;
523 
524 	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
525 		 "pMgntInfo->txpower_tracking = %d\n",
526 		  rtlpriv->dm.txpower_tracking);
527 }
528 
529 static void rtl8723e_dm_initialize_txpower_tracking(struct ieee80211_hw *hw)
530 {
531 	rtl8723e_dm_initialize_txpower_tracking_thermalmeter(hw);
532 }
533 
534 void rtl8723e_dm_check_txpower_tracking(struct ieee80211_hw *hw)
535 {
536 	return;
537 }
538 
539 void rtl8723e_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
540 {
541 	struct rtl_priv *rtlpriv = rtl_priv(hw);
542 	struct rate_adaptive *p_ra = &rtlpriv->ra;
543 
544 	p_ra->ratr_state = DM_RATR_STA_INIT;
545 	p_ra->pre_ratr_state = DM_RATR_STA_INIT;
546 
547 	if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
548 		rtlpriv->dm.useramask = true;
549 	else
550 		rtlpriv->dm.useramask = false;
551 
552 }
553 
554 static void rtl8723e_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
555 {
556 	struct rtl_priv *rtlpriv = rtl_priv(hw);
557 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
558 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
559 	struct rate_adaptive *p_ra = &rtlpriv->ra;
560 	u32 low_rssithresh_for_ra, high_rssithresh_for_ra;
561 	struct ieee80211_sta *sta = NULL;
562 
563 	if (is_hal_stop(rtlhal)) {
564 		RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
565 			 " driver is going to unload\n");
566 		return;
567 	}
568 
569 	if (!rtlpriv->dm.useramask) {
570 		RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
571 			 " driver does not control rate adaptive mask\n");
572 		return;
573 	}
574 
575 	if (mac->link_state == MAC80211_LINKED &&
576 	    mac->opmode == NL80211_IFTYPE_STATION) {
577 		switch (p_ra->pre_ratr_state) {
578 		case DM_RATR_STA_HIGH:
579 			high_rssithresh_for_ra = 50;
580 			low_rssithresh_for_ra = 20;
581 			break;
582 		case DM_RATR_STA_MIDDLE:
583 			high_rssithresh_for_ra = 55;
584 			low_rssithresh_for_ra = 20;
585 			break;
586 		case DM_RATR_STA_LOW:
587 			high_rssithresh_for_ra = 60;
588 			low_rssithresh_for_ra = 25;
589 			break;
590 		default:
591 			high_rssithresh_for_ra = 50;
592 			low_rssithresh_for_ra = 20;
593 			break;
594 		}
595 
596 		if (rtlpriv->link_info.bcn_rx_inperiod == 0)
597 			switch (p_ra->pre_ratr_state) {
598 			case DM_RATR_STA_HIGH:
599 			default:
600 				p_ra->ratr_state = DM_RATR_STA_MIDDLE;
601 				break;
602 			case DM_RATR_STA_MIDDLE:
603 			case DM_RATR_STA_LOW:
604 				p_ra->ratr_state = DM_RATR_STA_LOW;
605 				break;
606 			}
607 		else if (rtlpriv->dm.undec_sm_pwdb > high_rssithresh_for_ra)
608 			p_ra->ratr_state = DM_RATR_STA_HIGH;
609 		else if (rtlpriv->dm.undec_sm_pwdb > low_rssithresh_for_ra)
610 			p_ra->ratr_state = DM_RATR_STA_MIDDLE;
611 		else
612 			p_ra->ratr_state = DM_RATR_STA_LOW;
613 
614 		if (p_ra->pre_ratr_state != p_ra->ratr_state) {
615 			RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
616 				 "RSSI = %ld\n",
617 				 rtlpriv->dm.undec_sm_pwdb);
618 			RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
619 				 "RSSI_LEVEL = %d\n", p_ra->ratr_state);
620 			RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
621 				 "PreState = %d, CurState = %d\n",
622 				 p_ra->pre_ratr_state, p_ra->ratr_state);
623 
624 			rcu_read_lock();
625 			sta = rtl_find_sta(hw, mac->bssid);
626 			if (sta)
627 				rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
628 							   p_ra->ratr_state,
629 								      true);
630 			rcu_read_unlock();
631 
632 			p_ra->pre_ratr_state = p_ra->ratr_state;
633 		}
634 	}
635 }
636 
637 void rtl8723e_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal)
638 {
639 	struct rtl_priv *rtlpriv = rtl_priv(hw);
640 	struct ps_t *dm_pstable = &rtlpriv->dm_pstable;
641 	static u8 initialize;
642 	static u32 reg_874, reg_c70, reg_85c, reg_a74;
643 
644 	if (initialize == 0) {
645 		reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
646 					 MASKDWORD) & 0x1CC000) >> 14;
647 
648 		reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1,
649 					 MASKDWORD) & BIT(3)) >> 3;
650 
651 		reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
652 					 MASKDWORD) & 0xFF000000) >> 24;
653 
654 		reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & 0xF000) >> 12;
655 
656 		initialize = 1;
657 	}
658 
659 	if (!bforce_in_normal) {
660 		if (dm_pstable->rssi_val_min != 0) {
661 			if (dm_pstable->pre_rfstate == RF_NORMAL) {
662 				if (dm_pstable->rssi_val_min >= 30)
663 					dm_pstable->cur_rfstate = RF_SAVE;
664 				else
665 					dm_pstable->cur_rfstate = RF_NORMAL;
666 			} else {
667 				if (dm_pstable->rssi_val_min <= 25)
668 					dm_pstable->cur_rfstate = RF_NORMAL;
669 				else
670 					dm_pstable->cur_rfstate = RF_SAVE;
671 			}
672 		} else {
673 			dm_pstable->cur_rfstate = RF_MAX;
674 		}
675 	} else {
676 		dm_pstable->cur_rfstate = RF_NORMAL;
677 	}
678 
679 	if (dm_pstable->pre_rfstate != dm_pstable->cur_rfstate) {
680 		if (dm_pstable->cur_rfstate == RF_SAVE) {
681 			rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
682 				      BIT(5), 0x1);
683 			rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
684 				      0x1C0000, 0x2);
685 			rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0);
686 			rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
687 				      0xFF000000, 0x63);
688 			rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
689 				      0xC000, 0x2);
690 			rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3);
691 			rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
692 			rtl_set_bbreg(hw, 0x818, BIT(28), 0x1);
693 		} else {
694 			rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
695 				      0x1CC000, reg_874);
696 			rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3),
697 				      reg_c70);
698 			rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000,
699 				      reg_85c);
700 			rtl_set_bbreg(hw, 0xa74, 0xF000, reg_a74);
701 			rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
702 			rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
703 				      BIT(5), 0x0);
704 		}
705 
706 		dm_pstable->pre_rfstate = dm_pstable->cur_rfstate;
707 	}
708 }
709 
710 static void rtl8723e_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw)
711 {
712 	struct rtl_priv *rtlpriv = rtl_priv(hw);
713 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
714 	struct ps_t *dm_pstable = &rtlpriv->dm_pstable;
715 
716 	if (((mac->link_state == MAC80211_NOLINK)) &&
717 	    (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
718 		dm_pstable->rssi_val_min = 0;
719 		RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
720 			 "Not connected to any\n");
721 	}
722 
723 	if (mac->link_state == MAC80211_LINKED) {
724 		if (mac->opmode == NL80211_IFTYPE_ADHOC) {
725 			dm_pstable->rssi_val_min =
726 			    rtlpriv->dm.entry_min_undec_sm_pwdb;
727 			RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
728 				 "AP Client PWDB = 0x%lx\n",
729 				  dm_pstable->rssi_val_min);
730 		} else {
731 			dm_pstable->rssi_val_min =
732 			    rtlpriv->dm.undec_sm_pwdb;
733 			RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
734 				 "STA Default Port PWDB = 0x%lx\n",
735 				  dm_pstable->rssi_val_min);
736 		}
737 	} else {
738 		dm_pstable->rssi_val_min =
739 		    rtlpriv->dm.entry_min_undec_sm_pwdb;
740 
741 		RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
742 			 "AP Ext Port PWDB = 0x%lx\n",
743 			  dm_pstable->rssi_val_min);
744 	}
745 
746 	rtl8723e_dm_rf_saving(hw, false);
747 }
748 
749 void rtl8723e_dm_init(struct ieee80211_hw *hw)
750 {
751 	struct rtl_priv *rtlpriv = rtl_priv(hw);
752 
753 	rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
754 	rtl_dm_diginit(hw, 0x20);
755 	rtl8723_dm_init_dynamic_txpower(hw);
756 	rtl8723_dm_init_edca_turbo(hw);
757 	rtl8723e_dm_init_rate_adaptive_mask(hw);
758 	rtl8723e_dm_initialize_txpower_tracking(hw);
759 	rtl8723_dm_init_dynamic_bb_powersaving(hw);
760 }
761 
762 void rtl8723e_dm_watchdog(struct ieee80211_hw *hw)
763 {
764 	struct rtl_priv *rtlpriv = rtl_priv(hw);
765 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
766 	bool fw_current_inpsmode = false;
767 	bool fw_ps_awake = true;
768 	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
769 				      (u8 *)(&fw_current_inpsmode));
770 	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
771 				      (u8 *)(&fw_ps_awake));
772 
773 	if (ppsc->p2p_ps_info.p2p_ps_mode)
774 		fw_ps_awake = false;
775 
776 	spin_lock(&rtlpriv->locks.rf_ps_lock);
777 	if ((ppsc->rfpwr_state == ERFON) &&
778 	    ((!fw_current_inpsmode) && fw_ps_awake) &&
779 	    (!ppsc->rfchange_inprogress)) {
780 		rtl8723e_dm_pwdb_monitor(hw);
781 		rtl8723e_dm_dig(hw);
782 		rtl8723e_dm_false_alarm_counter_statistics(hw);
783 		rtl8723e_dm_dynamic_bb_powersaving(hw);
784 		rtl8723e_dm_dynamic_txpower(hw);
785 		rtl8723e_dm_check_txpower_tracking(hw);
786 		rtl8723e_dm_refresh_rate_adaptive_mask(hw);
787 		rtl8723e_dm_bt_coexist(hw);
788 		rtl8723e_dm_check_edca_turbo(hw);
789 	}
790 	spin_unlock(&rtlpriv->locks.rf_ps_lock);
791 	if (rtlpriv->btcoexist.init_set)
792 		rtl_write_byte(rtlpriv, 0x76e, 0xc);
793 }
794 
795 static void rtl8723e_dm_init_bt_coexist(struct ieee80211_hw *hw)
796 {
797 	struct rtl_priv *rtlpriv = rtl_priv(hw);
798 
799 	rtlpriv->btcoexist.bt_rfreg_origin_1e
800 		= rtl_get_rfreg(hw, (enum radio_path)0, RF_RCK1, 0xfffff);
801 	rtlpriv->btcoexist.bt_rfreg_origin_1f
802 		= rtl_get_rfreg(hw, (enum radio_path)0, RF_RCK2, 0xf0);
803 
804 	rtlpriv->btcoexist.cstate = 0;
805 	rtlpriv->btcoexist.previous_state = 0;
806 	rtlpriv->btcoexist.cstate_h = 0;
807 	rtlpriv->btcoexist.previous_state_h = 0;
808 	rtlpriv->btcoexist.lps_counter = 0;
809 
810 	/*  Enable counter statistics */
811 	rtl_write_byte(rtlpriv, 0x76e, 0x4);
812 	rtl_write_byte(rtlpriv, 0x778, 0x3);
813 	rtl_write_byte(rtlpriv, 0x40, 0x20);
814 
815 	rtlpriv->btcoexist.init_set = true;
816 }
817 
818 void rtl8723e_dm_bt_coexist(struct ieee80211_hw *hw)
819 {
820 	struct rtl_priv *rtlpriv = rtl_priv(hw);
821 	u8 tmp_byte = 0;
822 	if (!rtlpriv->btcoexist.bt_coexistence) {
823 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
824 			 "[DM]{BT], BT not exist!!\n");
825 		return;
826 	}
827 
828 	if (!rtlpriv->btcoexist.init_set) {
829 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
830 			 "[DM][BT], rtl8723e_dm_bt_coexist()\n");
831 		rtl8723e_dm_init_bt_coexist(hw);
832 	}
833 
834 	tmp_byte = rtl_read_byte(rtlpriv, 0x40);
835 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
836 		 "[DM][BT], 0x40 is 0x%x\n", tmp_byte);
837 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
838 		 "[DM][BT], bt_dm_coexist start\n");
839 	rtl8723e_dm_bt_coexist_8723(hw);
840 }
841