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