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
34static bool bt_operation_on;
35
36void rtl8723e_dm_bt_reject_ap_aggregated_packet(struct ieee80211_hw *hw,
37						bool b_reject)
38{
39}
40
41void _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
101u8 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
229u8 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
355long 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
374void 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
401void 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
448void 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
464void 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
479void 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
495void 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
512void 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
519bool 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
530bool 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