1 /******************************************************************************
2  *
3  * Copyright(c) 2009-2012  Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * The full GNU General Public License is included in this distribution in the
15  * file called LICENSE.
16  *
17  * Contact Information:
18  * wlanfae <wlanfae@realtek.com>
19  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20  * Hsinchu 300, Taiwan.
21  *
22  * Larry Finger <Larry.Finger@lwfinger.net>
23  *
24  *****************************************************************************/
25 
26 #include "hal_bt_coexist.h"
27 #include "../pci.h"
28 #include "dm.h"
29 #include "fw.h"
30 #include "phy.h"
31 #include "reg.h"
32 #include "hal_btc.h"
33 
34 static bool bt_operation_on;
35 
36 void rtl8723e_dm_bt_reject_ap_aggregated_packet(struct ieee80211_hw *hw,
37 						bool b_reject)
38 {
39 }
40 
41 void _rtl8723_dm_bt_check_wifi_state(struct ieee80211_hw *hw)
42 {
43 	struct rtl_priv *rtlpriv = rtl_priv(hw);
44 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
45 
46 	if (rtlpriv->link_info.busytraffic) {
47 		rtlpriv->btcoexist.cstate &=
48 			~BT_COEX_STATE_WIFI_IDLE;
49 
50 		if (rtlpriv->link_info.tx_busy_traffic)
51 			rtlpriv->btcoexist.cstate |=
52 				BT_COEX_STATE_WIFI_UPLINK;
53 		else
54 			rtlpriv->btcoexist.cstate &=
55 				~BT_COEX_STATE_WIFI_UPLINK;
56 
57 		if (rtlpriv->link_info.rx_busy_traffic)
58 			rtlpriv->btcoexist.cstate |=
59 				BT_COEX_STATE_WIFI_DOWNLINK;
60 		else
61 			rtlpriv->btcoexist.cstate &=
62 				~BT_COEX_STATE_WIFI_DOWNLINK;
63 	} else {
64 		rtlpriv->btcoexist.cstate |= BT_COEX_STATE_WIFI_IDLE;
65 		rtlpriv->btcoexist.cstate &=
66 			~BT_COEX_STATE_WIFI_UPLINK;
67 		rtlpriv->btcoexist.cstate &=
68 			~BT_COEX_STATE_WIFI_DOWNLINK;
69 	}
70 
71 	if (rtlpriv->mac80211.mode == WIRELESS_MODE_G ||
72 	    rtlpriv->mac80211.mode == WIRELESS_MODE_B) {
73 		rtlpriv->btcoexist.cstate |=
74 			BT_COEX_STATE_WIFI_LEGACY;
75 		rtlpriv->btcoexist.cstate &=
76 			~BT_COEX_STATE_WIFI_HT20;
77 		rtlpriv->btcoexist.cstate &=
78 			~BT_COEX_STATE_WIFI_HT40;
79 	} else {
80 		rtlpriv->btcoexist.cstate &=
81 			~BT_COEX_STATE_WIFI_LEGACY;
82 		if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
83 			rtlpriv->btcoexist.cstate |=
84 				BT_COEX_STATE_WIFI_HT40;
85 			rtlpriv->btcoexist.cstate &=
86 				~BT_COEX_STATE_WIFI_HT20;
87 		} else {
88 			rtlpriv->btcoexist.cstate |=
89 				BT_COEX_STATE_WIFI_HT20;
90 			rtlpriv->btcoexist.cstate &=
91 				~BT_COEX_STATE_WIFI_HT40;
92 		}
93 	}
94 
95 	if (bt_operation_on)
96 		rtlpriv->btcoexist.cstate |= BT_COEX_STATE_BT30;
97 	else
98 		rtlpriv->btcoexist.cstate &= ~BT_COEX_STATE_BT30;
99 }
100 
101 u8 rtl8723e_dm_bt_check_coex_rssi_state1(struct ieee80211_hw *hw,
102 					 u8 level_num, u8 rssi_thresh,
103 					 u8 rssi_thresh1)
104 
105 {
106 	struct rtl_priv *rtlpriv = rtl_priv(hw);
107 	long undecoratedsmoothed_pwdb;
108 	u8 bt_rssi_state = 0;
109 
110 	undecoratedsmoothed_pwdb = rtl8723e_dm_bt_get_rx_ss(hw);
111 
112 	if (level_num == 2) {
113 		rtlpriv->btcoexist.cstate &=
114 			~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
115 
116 		if ((rtlpriv->btcoexist.bt_pre_rssi_state ==
117 		     BT_RSSI_STATE_LOW) ||
118 		    (rtlpriv->btcoexist.bt_pre_rssi_state ==
119 		     BT_RSSI_STATE_STAY_LOW)) {
120 			if (undecoratedsmoothed_pwdb >=
121 			    (rssi_thresh + BT_FW_COEX_THRESH_TOL)) {
122 				bt_rssi_state = BT_RSSI_STATE_HIGH;
123 				rtlpriv->btcoexist.cstate |=
124 					BT_COEX_STATE_WIFI_RSSI_1_HIGH;
125 				rtlpriv->btcoexist.cstate &=
126 					~BT_COEX_STATE_WIFI_RSSI_1_LOW;
127 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
128 					 "[DM][BT], RSSI_1 state switch to High\n");
129 			} else {
130 				bt_rssi_state = BT_RSSI_STATE_STAY_LOW;
131 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
132 					 "[DM][BT], RSSI_1 state stay at Low\n");
133 			}
134 		} else {
135 			if (undecoratedsmoothed_pwdb < rssi_thresh) {
136 				bt_rssi_state = BT_RSSI_STATE_LOW;
137 				rtlpriv->btcoexist.cstate |=
138 					BT_COEX_STATE_WIFI_RSSI_1_LOW;
139 				rtlpriv->btcoexist.cstate &=
140 					~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
141 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
142 					 "[DM][BT], RSSI_1 state switch to Low\n");
143 			} else {
144 				bt_rssi_state = BT_RSSI_STATE_STAY_HIGH;
145 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
146 					 "[DM][BT], RSSI_1 state stay at High\n");
147 			}
148 		}
149 	} else if (level_num == 3) {
150 		if (rssi_thresh > rssi_thresh1) {
151 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
152 				 "[DM][BT], RSSI_1 thresh error!!\n");
153 			return rtlpriv->btcoexist.bt_pre_rssi_state;
154 		}
155 
156 		if ((rtlpriv->btcoexist.bt_pre_rssi_state ==
157 		     BT_RSSI_STATE_LOW) ||
158 		    (rtlpriv->btcoexist.bt_pre_rssi_state ==
159 		     BT_RSSI_STATE_STAY_LOW)) {
160 			if (undecoratedsmoothed_pwdb >=
161 			    (rssi_thresh+BT_FW_COEX_THRESH_TOL)) {
162 				bt_rssi_state = BT_RSSI_STATE_MEDIUM;
163 				rtlpriv->btcoexist.cstate |=
164 					BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
165 				rtlpriv->btcoexist.cstate &=
166 					~BT_COEX_STATE_WIFI_RSSI_1_LOW;
167 				rtlpriv->btcoexist.cstate &=
168 					~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
169 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
170 					 "[DM][BT], RSSI_1 state switch to Medium\n");
171 			} else {
172 				bt_rssi_state = BT_RSSI_STATE_STAY_LOW;
173 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
174 					 "[DM][BT], RSSI_1 state stay at Low\n");
175 			}
176 		} else if ((rtlpriv->btcoexist.bt_pre_rssi_state ==
177 			    BT_RSSI_STATE_MEDIUM) ||
178 			   (rtlpriv->btcoexist.bt_pre_rssi_state ==
179 			    BT_RSSI_STATE_STAY_MEDIUM)) {
180 			if (undecoratedsmoothed_pwdb >=
181 			    (rssi_thresh1 + BT_FW_COEX_THRESH_TOL)) {
182 				bt_rssi_state = BT_RSSI_STATE_HIGH;
183 				rtlpriv->btcoexist.cstate |=
184 					BT_COEX_STATE_WIFI_RSSI_1_HIGH;
185 				rtlpriv->btcoexist.cstate &=
186 					~BT_COEX_STATE_WIFI_RSSI_1_LOW;
187 				rtlpriv->btcoexist.cstate &=
188 					~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
189 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
190 					 "[DM][BT], RSSI_1 state switch to High\n");
191 			} else if (undecoratedsmoothed_pwdb < rssi_thresh) {
192 				bt_rssi_state = BT_RSSI_STATE_LOW;
193 				rtlpriv->btcoexist.cstate |=
194 					BT_COEX_STATE_WIFI_RSSI_1_LOW;
195 				rtlpriv->btcoexist.cstate &=
196 					~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
197 				rtlpriv->btcoexist.cstate &=
198 					~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
199 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
200 					 "[DM][BT], RSSI_1 state switch to Low\n");
201 			} else {
202 				bt_rssi_state = BT_RSSI_STATE_STAY_MEDIUM;
203 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
204 					 "[DM][BT], RSSI_1 state stay at Medium\n");
205 			}
206 		} else {
207 			if (undecoratedsmoothed_pwdb < rssi_thresh1) {
208 				bt_rssi_state = BT_RSSI_STATE_MEDIUM;
209 				rtlpriv->btcoexist.cstate |=
210 					BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
211 				rtlpriv->btcoexist.cstate &=
212 					~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
213 				rtlpriv->btcoexist.cstate &=
214 					~BT_COEX_STATE_WIFI_RSSI_1_LOW;
215 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
216 					 "[DM][BT], RSSI_1 state switch to Medium\n");
217 			} else {
218 				bt_rssi_state = BT_RSSI_STATE_STAY_HIGH;
219 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
220 					 "[DM][BT], RSSI_1 state stay at High\n");
221 			}
222 		}
223 	}
224 	rtlpriv->btcoexist.bt_pre_rssi_state1 = bt_rssi_state;
225 
226 	return bt_rssi_state;
227 }
228 
229 u8 rtl8723e_dm_bt_check_coex_rssi_state(struct ieee80211_hw *hw,
230 					u8 level_num,
231 					u8 rssi_thresh,
232 					u8 rssi_thresh1)
233 {
234 	struct rtl_priv *rtlpriv = rtl_priv(hw);
235 	long undecoratedsmoothed_pwdb = 0;
236 	u8 bt_rssi_state = 0;
237 
238 	undecoratedsmoothed_pwdb = rtl8723e_dm_bt_get_rx_ss(hw);
239 
240 	if (level_num == 2) {
241 		rtlpriv->btcoexist.cstate &=
242 			~BT_COEX_STATE_WIFI_RSSI_MEDIUM;
243 
244 		if ((rtlpriv->btcoexist.bt_pre_rssi_state ==
245 		     BT_RSSI_STATE_LOW) ||
246 		    (rtlpriv->btcoexist.bt_pre_rssi_state ==
247 		     BT_RSSI_STATE_STAY_LOW)) {
248 			if (undecoratedsmoothed_pwdb >=
249 			    (rssi_thresh + BT_FW_COEX_THRESH_TOL)) {
250 				bt_rssi_state = BT_RSSI_STATE_HIGH;
251 				rtlpriv->btcoexist.cstate
252 					|= BT_COEX_STATE_WIFI_RSSI_HIGH;
253 				rtlpriv->btcoexist.cstate
254 					&= ~BT_COEX_STATE_WIFI_RSSI_LOW;
255 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
256 					 "[DM][BT], RSSI state switch to High\n");
257 			} else {
258 				bt_rssi_state = BT_RSSI_STATE_STAY_LOW;
259 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
260 					 "[DM][BT], RSSI state stay at Low\n");
261 			}
262 		} else {
263 			if (undecoratedsmoothed_pwdb < rssi_thresh) {
264 				bt_rssi_state = BT_RSSI_STATE_LOW;
265 				rtlpriv->btcoexist.cstate
266 					|= BT_COEX_STATE_WIFI_RSSI_LOW;
267 				rtlpriv->btcoexist.cstate
268 					&= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
269 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
270 					 "[DM][BT], RSSI state switch to Low\n");
271 			} else {
272 				bt_rssi_state = BT_RSSI_STATE_STAY_HIGH;
273 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
274 					 "[DM][BT], RSSI state stay at High\n");
275 			}
276 		}
277 	} else if (level_num == 3) {
278 		if (rssi_thresh > rssi_thresh1) {
279 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
280 				 "[DM][BT], RSSI thresh error!!\n");
281 			return rtlpriv->btcoexist.bt_pre_rssi_state;
282 		}
283 		if ((rtlpriv->btcoexist.bt_pre_rssi_state ==
284 		     BT_RSSI_STATE_LOW) ||
285 		    (rtlpriv->btcoexist.bt_pre_rssi_state ==
286 		     BT_RSSI_STATE_STAY_LOW)) {
287 			if (undecoratedsmoothed_pwdb >=
288 			    (rssi_thresh + BT_FW_COEX_THRESH_TOL)) {
289 				bt_rssi_state = BT_RSSI_STATE_MEDIUM;
290 				rtlpriv->btcoexist.cstate
291 					|= BT_COEX_STATE_WIFI_RSSI_MEDIUM;
292 				rtlpriv->btcoexist.cstate
293 					&= ~BT_COEX_STATE_WIFI_RSSI_LOW;
294 				rtlpriv->btcoexist.cstate
295 					&= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
296 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
297 					 "[DM][BT], RSSI state switch to Medium\n");
298 			} else {
299 				bt_rssi_state = BT_RSSI_STATE_STAY_LOW;
300 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
301 					 "[DM][BT], RSSI state stay at Low\n");
302 			}
303 		} else if ((rtlpriv->btcoexist.bt_pre_rssi_state ==
304 				BT_RSSI_STATE_MEDIUM) ||
305 			(rtlpriv->btcoexist.bt_pre_rssi_state ==
306 				BT_RSSI_STATE_STAY_MEDIUM)) {
307 			if (undecoratedsmoothed_pwdb >=
308 			    (rssi_thresh1 + BT_FW_COEX_THRESH_TOL)) {
309 				bt_rssi_state = BT_RSSI_STATE_HIGH;
310 				rtlpriv->btcoexist.cstate
311 					|= BT_COEX_STATE_WIFI_RSSI_HIGH;
312 				rtlpriv->btcoexist.cstate
313 					&= ~BT_COEX_STATE_WIFI_RSSI_LOW;
314 				rtlpriv->btcoexist.cstate
315 					&= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM;
316 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
317 					 "[DM][BT], RSSI state switch to High\n");
318 			} else if (undecoratedsmoothed_pwdb < rssi_thresh) {
319 				bt_rssi_state = BT_RSSI_STATE_LOW;
320 				rtlpriv->btcoexist.cstate
321 					|= BT_COEX_STATE_WIFI_RSSI_LOW;
322 				rtlpriv->btcoexist.cstate
323 					&= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
324 				rtlpriv->btcoexist.cstate
325 					&= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM;
326 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
327 					 "[DM][BT], RSSI state switch to Low\n");
328 			} else {
329 				bt_rssi_state = BT_RSSI_STATE_STAY_MEDIUM;
330 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
331 					 "[DM][BT], RSSI state stay at Medium\n");
332 			}
333 		} else {
334 			if (undecoratedsmoothed_pwdb < rssi_thresh1) {
335 				bt_rssi_state = BT_RSSI_STATE_MEDIUM;
336 				rtlpriv->btcoexist.cstate
337 					|= BT_COEX_STATE_WIFI_RSSI_MEDIUM;
338 				rtlpriv->btcoexist.cstate
339 					&= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
340 				rtlpriv->btcoexist.cstate
341 					&= ~BT_COEX_STATE_WIFI_RSSI_LOW;
342 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
343 					 "[DM][BT], RSSI state switch to Medium\n");
344 			} else {
345 				bt_rssi_state = BT_RSSI_STATE_STAY_HIGH;
346 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
347 					 "[DM][BT], RSSI state stay at High\n");
348 			}
349 		}
350 	}
351 	rtlpriv->btcoexist.bt_pre_rssi_state = bt_rssi_state;
352 	return bt_rssi_state;
353 }
354 
355 long rtl8723e_dm_bt_get_rx_ss(struct ieee80211_hw *hw)
356 {
357 	struct rtl_priv *rtlpriv = rtl_priv(hw);
358 	long undecoratedsmoothed_pwdb = 0;
359 
360 	if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
361 		undecoratedsmoothed_pwdb =
362 			GET_UNDECORATED_AVERAGE_RSSI(rtlpriv);
363 	} else {
364 		undecoratedsmoothed_pwdb
365 			= rtlpriv->dm.entry_min_undec_sm_pwdb;
366 	}
367 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
368 		 "rtl8723e_dm_bt_get_rx_ss() = %ld\n",
369 		 undecoratedsmoothed_pwdb);
370 
371 	return undecoratedsmoothed_pwdb;
372 }
373 
374 void rtl8723e_dm_bt_balance(struct ieee80211_hw *hw,
375 			    bool balance_on, u8 ms0, u8 ms1)
376 {
377 	struct rtl_priv *rtlpriv = rtl_priv(hw);
378 	u8 h2c_parameter[3] = {0};
379 
380 	if (balance_on) {
381 		h2c_parameter[2] = 1;
382 		h2c_parameter[1] = ms1;
383 		h2c_parameter[0] = ms0;
384 		rtlpriv->btcoexist.fw_coexist_all_off = false;
385 	} else {
386 		h2c_parameter[2] = 0;
387 		h2c_parameter[1] = 0;
388 		h2c_parameter[0] = 0;
389 	}
390 	rtlpriv->btcoexist.balance_on = balance_on;
391 
392 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
393 		 "[DM][BT], Balance=[%s:%dms:%dms], write 0xc=0x%x\n",
394 		 balance_on ? "ON" : "OFF", ms0, ms1, h2c_parameter[0]<<16 |
395 		 h2c_parameter[1]<<8 | h2c_parameter[2]);
396 
397 	rtl8723e_fill_h2c_cmd(hw, 0xc, 3, h2c_parameter);
398 }
399 
400 
401 void rtl8723e_dm_bt_agc_table(struct ieee80211_hw *hw, u8 type)
402 {
403 	struct rtl_priv *rtlpriv = rtl_priv(hw);
404 
405 	if (type == BT_AGCTABLE_OFF) {
406 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
407 			 "[BT]AGCTable Off!\n");
408 		rtl_write_dword(rtlpriv, 0xc78, 0x641c0001);
409 		rtl_write_dword(rtlpriv, 0xc78, 0x631d0001);
410 		rtl_write_dword(rtlpriv, 0xc78, 0x621e0001);
411 		rtl_write_dword(rtlpriv, 0xc78, 0x611f0001);
412 		rtl_write_dword(rtlpriv, 0xc78, 0x60200001);
413 
414 		rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A,
415 					RF_RX_AGC_HP, 0xfffff, 0x32000);
416 		rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A,
417 					RF_RX_AGC_HP, 0xfffff, 0x71000);
418 		rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A,
419 					RF_RX_AGC_HP, 0xfffff, 0xb0000);
420 		rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A,
421 					RF_RX_AGC_HP, 0xfffff, 0xfc000);
422 		rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A,
423 					RF_RX_G1, 0xfffff, 0x30355);
424 	} else if (type == BT_AGCTABLE_ON) {
425 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
426 			 "[BT]AGCTable On!\n");
427 		rtl_write_dword(rtlpriv, 0xc78, 0x4e1c0001);
428 		rtl_write_dword(rtlpriv, 0xc78, 0x4d1d0001);
429 		rtl_write_dword(rtlpriv, 0xc78, 0x4c1e0001);
430 		rtl_write_dword(rtlpriv, 0xc78, 0x4b1f0001);
431 		rtl_write_dword(rtlpriv, 0xc78, 0x4a200001);
432 
433 		rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A,
434 					RF_RX_AGC_HP, 0xfffff, 0xdc000);
435 		rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A,
436 					RF_RX_AGC_HP, 0xfffff, 0x90000);
437 		rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A,
438 					RF_RX_AGC_HP, 0xfffff, 0x51000);
439 		rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A,
440 					RF_RX_AGC_HP, 0xfffff, 0x12000);
441 		rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A,
442 					RF_RX_G1, 0xfffff, 0x00355);
443 
444 		rtlpriv->btcoexist.sw_coexist_all_off = false;
445 	}
446 }
447 
448 void rtl8723e_dm_bt_bb_back_off_level(struct ieee80211_hw *hw, u8 type)
449 {
450 	struct rtl_priv *rtlpriv = rtl_priv(hw);
451 
452 	if (type == BT_BB_BACKOFF_OFF) {
453 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
454 			 "[BT]BBBackOffLevel Off!\n");
455 		rtl_write_dword(rtlpriv, 0xc04, 0x3a05611);
456 	} else if (type == BT_BB_BACKOFF_ON) {
457 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
458 			 "[BT]BBBackOffLevel On!\n");
459 		rtl_write_dword(rtlpriv, 0xc04, 0x3a07611);
460 		rtlpriv->btcoexist.sw_coexist_all_off = false;
461 	}
462 }
463 
464 void rtl8723e_dm_bt_fw_coex_all_off(struct ieee80211_hw *hw)
465 {
466 	struct rtl_priv *rtlpriv = rtl_priv(hw);
467 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
468 		 "rtl8723e_dm_bt_fw_coex_all_off()\n");
469 
470 	if (rtlpriv->btcoexist.fw_coexist_all_off)
471 		return;
472 
473 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
474 		 "rtl8723e_dm_bt_fw_coex_all_off(), real Do\n");
475 	rtl8723e_dm_bt_fw_coex_all_off_8723a(hw);
476 	rtlpriv->btcoexist.fw_coexist_all_off = true;
477 }
478 
479 void rtl8723e_dm_bt_sw_coex_all_off(struct ieee80211_hw *hw)
480 {
481 	struct rtl_priv *rtlpriv = rtl_priv(hw);
482 
483 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
484 		 "rtl8723e_dm_bt_sw_coex_all_off()\n");
485 
486 	if (rtlpriv->btcoexist.sw_coexist_all_off)
487 		return;
488 
489 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
490 		 "rtl8723e_dm_bt_sw_coex_all_off(), real Do\n");
491 	rtl8723e_dm_bt_sw_coex_all_off_8723a(hw);
492 	rtlpriv->btcoexist.sw_coexist_all_off = true;
493 }
494 
495 void rtl8723e_dm_bt_hw_coex_all_off(struct ieee80211_hw *hw)
496 {
497 	struct rtl_priv *rtlpriv = rtl_priv(hw);
498 
499 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
500 		 "rtl8723e_dm_bt_hw_coex_all_off()\n");
501 
502 	if (rtlpriv->btcoexist.hw_coexist_all_off)
503 		return;
504 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
505 		 "rtl8723e_dm_bt_hw_coex_all_off(), real Do\n");
506 
507 	rtl8723e_dm_bt_hw_coex_all_off_8723a(hw);
508 
509 	rtlpriv->btcoexist.hw_coexist_all_off = true;
510 }
511 
512 void rtl8723e_btdm_coex_all_off(struct ieee80211_hw *hw)
513 {
514 	rtl8723e_dm_bt_fw_coex_all_off(hw);
515 	rtl8723e_dm_bt_sw_coex_all_off(hw);
516 	rtl8723e_dm_bt_hw_coex_all_off(hw);
517 }
518 
519 bool rtl8723e_dm_bt_is_coexist_state_changed(struct ieee80211_hw *hw)
520 {
521 	struct rtl_priv *rtlpriv = rtl_priv(hw);
522 
523 	if ((rtlpriv->btcoexist.previous_state == rtlpriv->btcoexist.cstate) &&
524 	    (rtlpriv->btcoexist.previous_state_h ==
525 	     rtlpriv->btcoexist.cstate_h))
526 		return false;
527 	return true;
528 }
529 
530 bool rtl8723e_dm_bt_is_wifi_up_link(struct ieee80211_hw *hw)
531 {
532 	struct rtl_priv *rtlpriv = rtl_priv(hw);
533 
534 	if (rtlpriv->link_info.tx_busy_traffic)
535 		return true;
536 	return false;
537 }
538