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 #include "hal_btc.h"
26 #include "../pci.h"
27 #include "phy.h"
28 #include "fw.h"
29 #include "reg.h"
30 #include "def.h"
31 #include "../rtl8723com/phy_common.h"
32 
33 static struct bt_coexist_8723 hal_coex_8723;
34 
35 void rtl8723e_dm_bt_turn_off_bt_coexist_before_enter_lps(struct ieee80211_hw *hw)
36 {
37 	struct rtl_priv *rtlpriv = rtl_priv(hw);
38 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
39 
40 	if (!rtlpriv->btcoexist.bt_coexistence)
41 		return;
42 
43 	if (ppsc->inactiveps) {
44 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
45 			"[BT][DM], Before enter IPS, turn off all Coexist DM\n");
46 		rtlpriv->btcoexist.cstate = 0;
47 		rtlpriv->btcoexist.previous_state = 0;
48 		rtlpriv->btcoexist.cstate_h = 0;
49 		rtlpriv->btcoexist.previous_state_h = 0;
50 		rtl8723e_btdm_coex_all_off(hw);
51 	}
52 }
53 
54 static enum rt_media_status mgnt_link_status_query(struct ieee80211_hw *hw)
55 {
56 	struct rtl_priv *rtlpriv = rtl_priv(hw);
57 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
58 	enum rt_media_status    m_status = RT_MEDIA_DISCONNECT;
59 	u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0;
60 	if (bibss || rtlpriv->mac80211.link_state >= MAC80211_LINKED)
61 		m_status = RT_MEDIA_CONNECT;
62 
63 	return m_status;
64 }
65 
66 void rtl_8723e_bt_wifi_media_status_notify(struct ieee80211_hw *hw,
67 						bool mstatus)
68 {
69 	struct rtl_priv *rtlpriv = rtl_priv(hw);
70 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
71 	u8 h2c_parameter[3] = {0};
72 	u8 chnl;
73 
74 	if (!rtlpriv->btcoexist.bt_coexistence)
75 		return;
76 
77 	if (RT_MEDIA_CONNECT == mstatus)
78 		h2c_parameter[0] = 0x1; /* 0: disconnected, 1:connected */
79 	else
80 		h2c_parameter[0] = 0x0;
81 
82 	if (mgnt_link_status_query(hw))	{
83 		chnl = rtlphy->current_channel;
84 		h2c_parameter[1] = chnl;
85 	}
86 
87 	if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40)
88 		h2c_parameter[2] = 0x30;
89 	else
90 		h2c_parameter[2] = 0x20;
91 
92 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
93 		 "[BTCoex], FW write 0x19=0x%x\n",
94 		 h2c_parameter[0]<<16|h2c_parameter[1]<<8|h2c_parameter[2]);
95 
96 	rtl8723e_fill_h2c_cmd(hw, 0x19, 3, h2c_parameter);
97 }
98 
99 static bool rtl8723e_dm_bt_is_wifi_busy(struct ieee80211_hw *hw)
100 {
101 	struct rtl_priv *rtlpriv = rtl_priv(hw);
102 	if (rtlpriv->link_info.busytraffic ||
103 		rtlpriv->link_info.rx_busy_traffic ||
104 		rtlpriv->link_info.tx_busy_traffic)
105 		return true;
106 	else
107 		return false;
108 }
109 
110 static void rtl8723e_dm_bt_set_fw_3a(struct ieee80211_hw *hw,
111 				     u8 byte1, u8 byte2, u8 byte3, u8 byte4,
112 				     u8 byte5)
113 {
114 	struct rtl_priv *rtlpriv = rtl_priv(hw);
115 	u8 h2c_parameter[5];
116 
117 	h2c_parameter[0] = byte1;
118 	h2c_parameter[1] = byte2;
119 	h2c_parameter[2] = byte3;
120 	h2c_parameter[3] = byte4;
121 	h2c_parameter[4] = byte5;
122 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
123 		"[BTCoex], FW write 0x3a(4bytes)=0x%x%8x\n",
124 		h2c_parameter[0], h2c_parameter[1]<<24 |
125 		h2c_parameter[2]<<16 | h2c_parameter[3]<<8 |
126 		h2c_parameter[4]);
127 	rtl8723e_fill_h2c_cmd(hw, 0x3a, 5, h2c_parameter);
128 }
129 
130 static bool rtl8723e_dm_bt_need_to_dec_bt_pwr(struct ieee80211_hw *hw)
131 {
132 	struct rtl_priv *rtlpriv = rtl_priv(hw);
133 
134 	if (mgnt_link_status_query(hw) == RT_MEDIA_CONNECT) {
135 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
136 			"Need to decrease bt power\n");
137 		rtlpriv->btcoexist.cstate |=
138 		BT_COEX_STATE_DEC_BT_POWER;
139 		return true;
140 	}
141 
142 	rtlpriv->btcoexist.cstate &= ~BT_COEX_STATE_DEC_BT_POWER;
143 	return false;
144 }
145 
146 static bool rtl8723e_dm_bt_is_same_coexist_state(struct ieee80211_hw *hw)
147 {
148 	struct rtl_priv *rtlpriv = rtl_priv(hw);
149 
150 	if ((rtlpriv->btcoexist.previous_state ==
151 	     rtlpriv->btcoexist.cstate) &&
152 	    (rtlpriv->btcoexist.previous_state_h ==
153 	     rtlpriv->btcoexist.cstate_h)) {
154 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
155 			 "[DM][BT], Coexist state do not chang!!\n");
156 		return true;
157 	} else {
158 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
159 			 "[DM][BT], Coexist state changed!!\n");
160 		return false;
161 	}
162 }
163 
164 static void rtl8723e_dm_bt_set_coex_table(struct ieee80211_hw *hw,
165 					  u32 val_0x6c0, u32 val_0x6c8,
166 					  u32 val_0x6cc)
167 {
168 	struct rtl_priv *rtlpriv = rtl_priv(hw);
169 
170 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
171 		 "set coex table, set 0x6c0=0x%x\n", val_0x6c0);
172 	rtl_write_dword(rtlpriv, 0x6c0, val_0x6c0);
173 
174 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
175 		 "set coex table, set 0x6c8=0x%x\n", val_0x6c8);
176 	rtl_write_dword(rtlpriv, 0x6c8, val_0x6c8);
177 
178 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
179 		 "set coex table, set 0x6cc=0x%x\n", val_0x6cc);
180 	rtl_write_byte(rtlpriv, 0x6cc, val_0x6cc);
181 }
182 
183 static void rtl8723e_dm_bt_set_hw_pta_mode(struct ieee80211_hw *hw, bool b_mode)
184 {
185 	struct rtl_priv *rtlpriv = rtl_priv(hw);
186 
187 	if (BT_PTA_MODE_ON == b_mode) {
188 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, "PTA mode on\n");
189 		/*  Enable GPIO 0/1/2/3/8 pins for bt */
190 		rtl_write_byte(rtlpriv, 0x40, 0x20);
191 		rtlpriv->btcoexist.hw_coexist_all_off = false;
192 	} else {
193 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, "PTA mode off\n");
194 		rtl_write_byte(rtlpriv, 0x40, 0x0);
195 	}
196 }
197 
198 static void rtl8723e_dm_bt_set_sw_rf_rx_lpf_corner(struct ieee80211_hw *hw,
199 						   u8 type)
200 {
201 	struct rtl_priv *rtlpriv = rtl_priv(hw);
202 
203 	if (BT_RF_RX_LPF_CORNER_SHRINK == type) {
204 		/* Shrink RF Rx LPF corner, 0x1e[7:4]=1111 ==> [11:4] */
205 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
206 			 "Shrink RF Rx LPF corner!!\n");
207 		rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A, 0x1e,
208 					0xfffff, 0xf0ff7);
209 		rtlpriv->btcoexist.sw_coexist_all_off = false;
210 	} else if (BT_RF_RX_LPF_CORNER_RESUME == type) {
211 		/*Resume RF Rx LPF corner*/
212 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
213 			 "Resume RF Rx LPF corner!!\n");
214 		rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A, 0x1e, 0xfffff,
215 					rtlpriv->btcoexist.bt_rfreg_origin_1e);
216 	}
217 }
218 
219 static void dm_bt_set_sw_penalty_tx_rate_adapt(struct ieee80211_hw *hw,
220 					       u8 ra_type)
221 {
222 	struct rtl_priv *rtlpriv = rtl_priv(hw);
223 	u8 tmp_u1;
224 
225 	tmp_u1 = rtl_read_byte(rtlpriv, 0x4fd);
226 	tmp_u1 |= BIT(0);
227 	if (BT_TX_RATE_ADAPTIVE_LOW_PENALTY == ra_type) {
228 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
229 			"Tx rate adaptive, set low penalty!!\n");
230 		tmp_u1 &= ~BIT(2);
231 		rtlpriv->btcoexist.sw_coexist_all_off = false;
232 	} else if (BT_TX_RATE_ADAPTIVE_NORMAL == ra_type) {
233 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
234 			"Tx rate adaptive, set normal!!\n");
235 		tmp_u1 |= BIT(2);
236 	}
237 
238 	rtl_write_byte(rtlpriv, 0x4fd, tmp_u1);
239 }
240 
241 static void rtl8723e_dm_bt_btdm_structure_reload(struct ieee80211_hw *hw,
242 						 struct btdm_8723 *btdm)
243 {
244 	btdm->all_off = false;
245 	btdm->agc_table_en = false;
246 	btdm->adc_back_off_on = false;
247 	btdm->b2_ant_hid_en = false;
248 	btdm->low_penalty_rate_adaptive = false;
249 	btdm->rf_rx_lpf_shrink = false;
250 	btdm->reject_aggre_pkt = false;
251 
252 	btdm->tdma_on = false;
253 	btdm->tdma_ant = TDMA_2ANT;
254 	btdm->tdma_nav = TDMA_NAV_OFF;
255 	btdm->tdma_dac_swing = TDMA_DAC_SWING_OFF;
256 	btdm->fw_dac_swing_lvl = 0x20;
257 
258 	btdm->tra_tdma_on = false;
259 	btdm->tra_tdma_ant = TDMA_2ANT;
260 	btdm->tra_tdma_nav = TDMA_NAV_OFF;
261 	btdm->ignore_wlan_act = false;
262 
263 	btdm->ps_tdma_on = false;
264 	btdm->ps_tdma_byte[0] = 0x0;
265 	btdm->ps_tdma_byte[1] = 0x0;
266 	btdm->ps_tdma_byte[2] = 0x0;
267 	btdm->ps_tdma_byte[3] = 0x8;
268 	btdm->ps_tdma_byte[4] = 0x0;
269 
270 	btdm->pta_on = true;
271 	btdm->val_0x6c0 = 0x5a5aaaaa;
272 	btdm->val_0x6c8 = 0xcc;
273 	btdm->val_0x6cc = 0x3;
274 
275 	btdm->sw_dac_swing_on = false;
276 	btdm->sw_dac_swing_lvl = 0xc0;
277 	btdm->wlan_act_hi = 0x20;
278 	btdm->wlan_act_lo = 0x10;
279 	btdm->bt_retry_index = 2;
280 
281 	btdm->dec_bt_pwr = false;
282 }
283 
284 static void rtl8723e_dm_bt_btdm_structure_reload_all_off(struct ieee80211_hw *hw,
285 							 struct btdm_8723 *btdm)
286 {
287 	rtl8723e_dm_bt_btdm_structure_reload(hw, btdm);
288 	btdm->all_off = true;
289 	btdm->pta_on = false;
290 	btdm->wlan_act_hi = 0x10;
291 }
292 
293 static bool rtl8723e_dm_bt_is_2_ant_common_action(struct ieee80211_hw *hw)
294 {
295 	struct rtl_priv *rtlpriv = rtl_priv(hw);
296 	struct btdm_8723 btdm8723;
297 	bool b_common = false;
298 
299 	rtl8723e_dm_bt_btdm_structure_reload(hw, &btdm8723);
300 
301 	if (!rtl8723e_dm_bt_is_wifi_busy(hw) &&
302 	    !rtlpriv->btcoexist.bt_busy) {
303 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
304 			 "Wifi idle + Bt idle, bt coex mechanism always off!!\n");
305 		rtl8723e_dm_bt_btdm_structure_reload_all_off(hw, &btdm8723);
306 		b_common = true;
307 	} else if (rtl8723e_dm_bt_is_wifi_busy(hw) &&
308 		   !rtlpriv->btcoexist.bt_busy) {
309 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
310 			 "Wifi non-idle + Bt disabled/idle!!\n");
311 		btdm8723.low_penalty_rate_adaptive = true;
312 		btdm8723.rf_rx_lpf_shrink = false;
313 		btdm8723.reject_aggre_pkt = false;
314 
315 		/* sw mechanism */
316 		btdm8723.agc_table_en = false;
317 		btdm8723.adc_back_off_on = false;
318 		btdm8723.sw_dac_swing_on = false;
319 
320 		btdm8723.pta_on = true;
321 		btdm8723.val_0x6c0 = 0x5a5aaaaa;
322 		btdm8723.val_0x6c8 = 0xcccc;
323 		btdm8723.val_0x6cc = 0x3;
324 
325 		btdm8723.tdma_on = false;
326 		btdm8723.tdma_dac_swing = TDMA_DAC_SWING_OFF;
327 		btdm8723.b2_ant_hid_en = false;
328 
329 		b_common = true;
330 	} else if (rtlpriv->btcoexist.bt_busy) {
331 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
332 			"Bt non-idle!\n");
333 		if (mgnt_link_status_query(hw) == RT_MEDIA_CONNECT) {
334 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
335 				"Wifi connection exist\n");
336 			b_common = false;
337 		} else {
338 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
339 				"No Wifi connection!\n");
340 			btdm8723.rf_rx_lpf_shrink = true;
341 			btdm8723.low_penalty_rate_adaptive = false;
342 			btdm8723.reject_aggre_pkt = false;
343 
344 			/* sw mechanism */
345 			btdm8723.agc_table_en = false;
346 			btdm8723.adc_back_off_on = false;
347 			btdm8723.sw_dac_swing_on = false;
348 
349 			btdm8723.pta_on = true;
350 			btdm8723.val_0x6c0 = 0x55555555;
351 			btdm8723.val_0x6c8 = 0x0000ffff;
352 			btdm8723.val_0x6cc = 0x3;
353 
354 			btdm8723.tdma_on = false;
355 			btdm8723.tdma_dac_swing = TDMA_DAC_SWING_OFF;
356 			btdm8723.b2_ant_hid_en = false;
357 
358 			b_common = true;
359 		}
360 	}
361 
362 	if (rtl8723e_dm_bt_need_to_dec_bt_pwr(hw))
363 		btdm8723.dec_bt_pwr = true;
364 
365 	if (b_common)
366 		rtlpriv->btcoexist.cstate |=
367 			BT_COEX_STATE_BTINFO_COMMON;
368 
369 	if (b_common && rtl8723e_dm_bt_is_coexist_state_changed(hw))
370 		rtl8723e_dm_bt_set_bt_dm(hw, &btdm8723);
371 
372 	return b_common;
373 }
374 
375 static void rtl8723e_dm_bt_set_sw_full_time_dac_swing(
376 		struct ieee80211_hw *hw,
377 		bool sw_dac_swing_on,
378 		u32 sw_dac_swing_lvl)
379 {
380 	struct rtl_priv *rtlpriv = rtl_priv(hw);
381 
382 	if (sw_dac_swing_on) {
383 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
384 			 "[BTCoex], SwDacSwing = 0x%x\n", sw_dac_swing_lvl);
385 		rtl8723_phy_set_bb_reg(hw, 0x880, 0xff000000,
386 				       sw_dac_swing_lvl);
387 		rtlpriv->btcoexist.sw_coexist_all_off = false;
388 	} else {
389 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
390 			 "[BTCoex], SwDacSwing Off!\n");
391 		rtl8723_phy_set_bb_reg(hw, 0x880, 0xff000000, 0xc0);
392 	}
393 }
394 
395 static void rtl8723e_dm_bt_set_fw_dec_bt_pwr(
396 		struct ieee80211_hw *hw, bool dec_bt_pwr)
397 {
398 	struct rtl_priv *rtlpriv = rtl_priv(hw);
399 	u8 h2c_parameter[1] = {0};
400 
401 	h2c_parameter[0] = 0;
402 
403 	if (dec_bt_pwr) {
404 		h2c_parameter[0] |= BIT(1);
405 		rtlpriv->btcoexist.fw_coexist_all_off = false;
406 	}
407 
408 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
409 		 "[BTCoex], decrease Bt Power : %s, write 0x21=0x%x\n",
410 		 (dec_bt_pwr ? "Yes!!" : "No!!"), h2c_parameter[0]);
411 
412 	rtl8723e_fill_h2c_cmd(hw, 0x21, 1, h2c_parameter);
413 }
414 
415 static void rtl8723e_dm_bt_set_fw_2_ant_hid(struct ieee80211_hw *hw,
416 					    bool b_enable, bool b_dac_swing_on)
417 {
418 	struct rtl_priv *rtlpriv = rtl_priv(hw);
419 	u8 h2c_parameter[1] = {0};
420 
421 	if (b_enable) {
422 		h2c_parameter[0] |= BIT(0);
423 		rtlpriv->btcoexist.fw_coexist_all_off = false;
424 	}
425 	if (b_dac_swing_on)
426 		h2c_parameter[0] |= BIT(1); /* Dac Swing default enable */
427 
428 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
429 		 "[BTCoex], turn 2-Ant+HID mode %s, DACSwing:%s, write 0x15=0x%x\n",
430 		 (b_enable ? "ON!!" : "OFF!!"), (b_dac_swing_on ? "ON" : "OFF"),
431 		 h2c_parameter[0]);
432 
433 	rtl8723e_fill_h2c_cmd(hw, 0x15, 1, h2c_parameter);
434 }
435 
436 static void rtl8723e_dm_bt_set_fw_tdma_ctrl(struct ieee80211_hw *hw,
437 					    bool b_enable, u8 ant_num,
438 					    u8 nav_en, u8 dac_swing_en)
439 {
440 	struct rtl_priv *rtlpriv = rtl_priv(hw);
441 	u8 h2c_parameter[1] = {0};
442 	u8 h2c_parameter1[1] = {0};
443 
444 	h2c_parameter[0] = 0;
445 	h2c_parameter1[0] = 0;
446 
447 	if (b_enable) {
448 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
449 			 "[BTCoex], set BT PTA update manager to trigger update!!\n");
450 		h2c_parameter1[0] |= BIT(0);
451 
452 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
453 			"[BTCoex], turn TDMA mode ON!!\n");
454 		h2c_parameter[0] |= BIT(0);		/* function enable */
455 		if (TDMA_1ANT == ant_num) {
456 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
457 			"[BTCoex], TDMA_1ANT\n");
458 			h2c_parameter[0] |= BIT(1);
459 		} else if (TDMA_2ANT == ant_num) {
460 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
461 			"[BTCoex], TDMA_2ANT\n");
462 		} else {
463 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
464 			"[BTCoex], Unknown Ant\n");
465 		}
466 
467 		if (TDMA_NAV_OFF == nav_en) {
468 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
469 			"[BTCoex], TDMA_NAV_OFF\n");
470 		} else if (TDMA_NAV_ON == nav_en) {
471 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
472 			"[BTCoex], TDMA_NAV_ON\n");
473 			h2c_parameter[0] |= BIT(2);
474 		}
475 
476 		if (TDMA_DAC_SWING_OFF == dac_swing_en) {
477 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
478 				"[BTCoex], TDMA_DAC_SWING_OFF\n");
479 		} else if (TDMA_DAC_SWING_ON == dac_swing_en) {
480 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
481 				"[BTCoex], TDMA_DAC_SWING_ON\n");
482 			h2c_parameter[0] |= BIT(4);
483 		}
484 		rtlpriv->btcoexist.fw_coexist_all_off = false;
485 	} else {
486 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
487 			 "[BTCoex], set BT PTA update manager to no update!!\n");
488 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
489 			 "[BTCoex], turn TDMA mode OFF!!\n");
490 	}
491 
492 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
493 		 "[BTCoex], FW2AntTDMA, write 0x26=0x%x\n",
494 		 h2c_parameter1[0]);
495 	rtl8723e_fill_h2c_cmd(hw, 0x26, 1, h2c_parameter1);
496 
497 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
498 		"[BTCoex], FW2AntTDMA, write 0x14=0x%x\n",
499 		h2c_parameter[0]);
500 	rtl8723e_fill_h2c_cmd(hw, 0x14, 1, h2c_parameter);
501 }
502 
503 static void rtl8723e_dm_bt_set_fw_ignore_wlan_act(struct ieee80211_hw *hw,
504 						  bool b_enable)
505 {
506 	struct rtl_priv *rtlpriv = rtl_priv(hw);
507 	u8 h2c_parameter[1] = {0};
508 
509 	if (b_enable) {
510 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
511 			"[BTCoex], BT Ignore Wlan_Act !!\n");
512 		h2c_parameter[0] |= BIT(0);		/* function enable */
513 		rtlpriv->btcoexist.fw_coexist_all_off = false;
514 	} else {
515 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
516 			"[BTCoex], BT don't ignore Wlan_Act !!\n");
517 	}
518 
519 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
520 		 "[BTCoex], set FW for BT Ignore Wlan_Act, write 0x25=0x%x\n",
521 		 h2c_parameter[0]);
522 
523 	rtl8723e_fill_h2c_cmd(hw, 0x25, 1, h2c_parameter);
524 }
525 
526 static void rtl8723e_dm_bt_set_fw_tra_tdma_ctrl(struct ieee80211_hw *hw,
527 						bool b_enable, u8 ant_num,
528 						u8 nav_en)
529 {
530 	struct rtl_priv *rtlpriv = rtl_priv(hw);
531 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
532 
533 	u8 h2c_parameter[2] = {0};
534 
535 	/* Only 8723 B cut should do this */
536 	if (IS_VENDOR_8723_A_CUT(rtlhal->version)) {
537 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
538 			 "[BTCoex], not 8723B cut, don't set Traditional TDMA!!\n");
539 		return;
540 	}
541 
542 	if (b_enable) {
543 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
544 			 "[BTCoex], turn TTDMA mode ON!!\n");
545 		h2c_parameter[0] |= BIT(0);	/* function enable */
546 		if (TDMA_1ANT == ant_num) {
547 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
548 				 "[BTCoex], TTDMA_1ANT\n");
549 			h2c_parameter[0] |= BIT(1);
550 		} else if (TDMA_2ANT == ant_num) {
551 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
552 			"[BTCoex], TTDMA_2ANT\n");
553 		} else {
554 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
555 			"[BTCoex], Unknown Ant\n");
556 		}
557 
558 		if (TDMA_NAV_OFF == nav_en) {
559 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
560 			"[BTCoex], TTDMA_NAV_OFF\n");
561 		} else if (TDMA_NAV_ON == nav_en) {
562 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
563 			"[BTCoex], TTDMA_NAV_ON\n");
564 			h2c_parameter[1] |= BIT(0);
565 		}
566 
567 		rtlpriv->btcoexist.fw_coexist_all_off = false;
568 	} else {
569 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
570 			"[BTCoex], turn TTDMA mode OFF!!\n");
571 	}
572 
573 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
574 		"[BTCoex], FW Traditional TDMA, write 0x33=0x%x\n",
575 		h2c_parameter[0] << 8 | h2c_parameter[1]);
576 
577 	rtl8723e_fill_h2c_cmd(hw, 0x33, 2, h2c_parameter);
578 }
579 
580 static void rtl8723e_dm_bt_set_fw_dac_swing_level(struct ieee80211_hw *hw,
581 						  u8 dac_swing_lvl)
582 {
583 	struct rtl_priv *rtlpriv = rtl_priv(hw);
584 	u8 h2c_parameter[1] = {0};
585 	h2c_parameter[0] = dac_swing_lvl;
586 
587 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
588 		"[BTCoex], Set Dac Swing Level=0x%x\n", dac_swing_lvl);
589 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
590 		"[BTCoex], write 0x29=0x%x\n", h2c_parameter[0]);
591 
592 	rtl8723e_fill_h2c_cmd(hw, 0x29, 1, h2c_parameter);
593 }
594 
595 static void rtl8723e_dm_bt_set_fw_bt_hid_info(struct ieee80211_hw *hw,
596 					      bool b_enable)
597 {
598 	struct rtl_priv *rtlpriv = rtl_priv(hw);
599 	u8 h2c_parameter[1] = {0};
600 	h2c_parameter[0] = 0;
601 
602 	if (b_enable) {
603 		h2c_parameter[0] |= BIT(0);
604 		rtlpriv->btcoexist.fw_coexist_all_off = false;
605 	}
606 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
607 		"[BTCoex], Set BT HID information=0x%x\n", b_enable);
608 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
609 		"[BTCoex], write 0x24=0x%x\n", h2c_parameter[0]);
610 
611 	rtl8723e_fill_h2c_cmd(hw, 0x24, 1, h2c_parameter);
612 }
613 
614 static void rtl8723e_dm_bt_set_fw_bt_retry_index(struct ieee80211_hw *hw,
615 						 u8 retry_index)
616 {
617 	struct rtl_priv *rtlpriv = rtl_priv(hw);
618 	u8 h2c_parameter[1] = {0};
619 	h2c_parameter[0] = retry_index;
620 
621 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
622 		"[BTCoex], Set BT Retry Index=%d\n", retry_index);
623 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
624 		"[BTCoex], write 0x23=0x%x\n", h2c_parameter[0]);
625 
626 	rtl8723e_fill_h2c_cmd(hw, 0x23, 1, h2c_parameter);
627 }
628 
629 static void rtl8723e_dm_bt_set_fw_wlan_act(struct ieee80211_hw *hw,
630 					   u8 wlan_act_hi, u8 wlan_act_lo)
631 {
632 	struct rtl_priv *rtlpriv = rtl_priv(hw);
633 	u8 h2c_parameter_hi[1] = {0};
634 	u8 h2c_parameter_lo[1] = {0};
635 	h2c_parameter_hi[0] = wlan_act_hi;
636 	h2c_parameter_lo[0] = wlan_act_lo;
637 
638 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
639 		"[BTCoex], Set WLAN_ACT Hi:Lo=0x%x/0x%x\n",
640 		wlan_act_hi, wlan_act_lo);
641 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
642 		"[BTCoex], write 0x22=0x%x\n", h2c_parameter_hi[0]);
643 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
644 		"[BTCoex], write 0x11=0x%x\n", h2c_parameter_lo[0]);
645 
646 	/* WLAN_ACT = High duration, unit:ms */
647 	rtl8723e_fill_h2c_cmd(hw, 0x22, 1, h2c_parameter_hi);
648 	/*  WLAN_ACT = Low duration, unit:3*625us */
649 	rtl8723e_fill_h2c_cmd(hw, 0x11, 1, h2c_parameter_lo);
650 }
651 
652 void rtl8723e_dm_bt_set_bt_dm(struct ieee80211_hw *hw,
653 			      struct btdm_8723 *btdm)
654 {
655 	struct rtl_priv	*rtlpriv = rtl_priv(hw);
656 	struct btdm_8723 *btdm_8723 = &hal_coex_8723.btdm;
657 	u8 i;
658 
659 	bool fw_current_inpsmode = false;
660 	bool fw_ps_awake = true;
661 
662 	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
663 					      (u8 *)(&fw_current_inpsmode));
664 	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
665 					      (u8 *)(&fw_ps_awake));
666 
667 	/* check new setting is different with the old one, */
668 	/* if all the same, don't do the setting again. */
669 	if (memcmp(btdm_8723, btdm, sizeof(struct btdm_8723)) == 0) {
670 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
671 			"[BTCoex], the same coexist setting, return!!\n");
672 		return;
673 	} else {	/* save the new coexist setting */
674 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
675 			"[BTCoex], UPDATE TO NEW COEX SETTING!!\n");
676 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
677 			"[BTCoex], original/new bAllOff=0x%x/ 0x%x\n",
678 			btdm_8723->all_off, btdm->all_off);
679 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
680 			"[BTCoex], original/new agc_table_en=0x%x/ 0x%x\n",
681 			btdm_8723->agc_table_en, btdm->agc_table_en);
682 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
683 			 "[BTCoex], original/new adc_back_off_on=0x%x/ 0x%x\n",
684 			 btdm_8723->adc_back_off_on,
685 			 btdm->adc_back_off_on);
686 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
687 			 "[BTCoex], original/new b2_ant_hid_en=0x%x/ 0x%x\n",
688 			 btdm_8723->b2_ant_hid_en, btdm->b2_ant_hid_en);
689 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
690 			 "[BTCoex], original/new bLowPenaltyRateAdaptive=0x%x/ 0x%x\n",
691 			 btdm_8723->low_penalty_rate_adaptive,
692 			 btdm->low_penalty_rate_adaptive);
693 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
694 			 "[BTCoex], original/new bRfRxLpfShrink=0x%x/ 0x%x\n",
695 			 btdm_8723->rf_rx_lpf_shrink,
696 			 btdm->rf_rx_lpf_shrink);
697 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
698 			 "[BTCoex], original/new bRejectAggrePkt=0x%x/ 0x%x\n",
699 			 btdm_8723->reject_aggre_pkt,
700 			 btdm->reject_aggre_pkt);
701 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
702 			 "[BTCoex], original/new tdma_on=0x%x/ 0x%x\n",
703 			 btdm_8723->tdma_on, btdm->tdma_on);
704 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
705 			 "[BTCoex], original/new tdmaAnt=0x%x/ 0x%x\n",
706 			 btdm_8723->tdma_ant, btdm->tdma_ant);
707 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
708 			 "[BTCoex], original/new tdmaNav=0x%x/ 0x%x\n",
709 			 btdm_8723->tdma_nav, btdm->tdma_nav);
710 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
711 			 "[BTCoex], original/new tdma_dac_swing=0x%x/ 0x%x\n",
712 			 btdm_8723->tdma_dac_swing, btdm->tdma_dac_swing);
713 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
714 			 "[BTCoex], original/new fw_dac_swing_lvl=0x%x/ 0x%x\n",
715 			 btdm_8723->fw_dac_swing_lvl,
716 			 btdm->fw_dac_swing_lvl);
717 
718 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
719 			 "[BTCoex], original/new bTraTdmaOn=0x%x/ 0x%x\n",
720 			 btdm_8723->tra_tdma_on, btdm->tra_tdma_on);
721 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
722 			 "[BTCoex], original/new traTdmaAnt=0x%x/ 0x%x\n",
723 			 btdm_8723->tra_tdma_ant, btdm->tra_tdma_ant);
724 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
725 			 "[BTCoex], original/new traTdmaNav=0x%x/ 0x%x\n",
726 			 btdm_8723->tra_tdma_nav, btdm->tra_tdma_nav);
727 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
728 			 "[BTCoex], original/new bPsTdmaOn=0x%x/ 0x%x\n",
729 			 btdm_8723->ps_tdma_on, btdm->ps_tdma_on);
730 		for (i = 0; i < 5; i++) {
731 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
732 				 "[BTCoex], original/new psTdmaByte[i]=0x%x/ 0x%x\n",
733 				 btdm_8723->ps_tdma_byte[i],
734 				 btdm->ps_tdma_byte[i]);
735 		}
736 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
737 			"[BTCoex], original/new bIgnoreWlanAct=0x%x/ 0x%x\n",
738 			btdm_8723->ignore_wlan_act,
739 			btdm->ignore_wlan_act);
740 
741 
742 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
743 			"[BTCoex], original/new bPtaOn=0x%x/ 0x%x\n",
744 			btdm_8723->pta_on, btdm->pta_on);
745 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
746 			"[BTCoex], original/new val_0x6c0=0x%x/ 0x%x\n",
747 			btdm_8723->val_0x6c0, btdm->val_0x6c0);
748 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
749 			"[BTCoex], original/new val_0x6c8=0x%x/ 0x%x\n",
750 			btdm_8723->val_0x6c8, btdm->val_0x6c8);
751 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
752 			"[BTCoex], original/new val_0x6cc=0x%x/ 0x%x\n",
753 			btdm_8723->val_0x6cc, btdm->val_0x6cc);
754 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
755 			 "[BTCoex], original/new sw_dac_swing_on=0x%x/ 0x%x\n",
756 			 btdm_8723->sw_dac_swing_on,
757 			 btdm->sw_dac_swing_on);
758 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
759 			 "[BTCoex], original/new sw_dac_swing_lvl=0x%x/ 0x%x\n",
760 			 btdm_8723->sw_dac_swing_lvl,
761 			 btdm->sw_dac_swing_lvl);
762 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
763 			 "[BTCoex], original/new wlanActHi=0x%x/ 0x%x\n",
764 			 btdm_8723->wlan_act_hi, btdm->wlan_act_hi);
765 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
766 			 "[BTCoex], original/new wlanActLo=0x%x/ 0x%x\n",
767 			 btdm_8723->wlan_act_lo, btdm->wlan_act_lo);
768 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
769 			 "[BTCoex], original/new btRetryIndex=0x%x/ 0x%x\n",
770 			 btdm_8723->bt_retry_index, btdm->bt_retry_index);
771 
772 		memcpy(btdm_8723, btdm, sizeof(struct btdm_8723));
773 	}
774 	/* Here we only consider when Bt Operation
775 	 * inquiry/paging/pairing is ON
776 	 * we only need to turn off TDMA
777 	 */
778 
779 	if (rtlpriv->btcoexist.hold_for_bt_operation) {
780 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
781 			"[BTCoex], set to ignore wlanAct for BT OP!!\n");
782 		rtl8723e_dm_bt_set_fw_ignore_wlan_act(hw, true);
783 		return;
784 	}
785 
786 	if (btdm->all_off) {
787 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
788 			"[BTCoex], disable all coexist mechanism !!\n");
789 		rtl8723e_btdm_coex_all_off(hw);
790 		return;
791 	}
792 
793 	rtl8723e_dm_bt_reject_ap_aggregated_packet(hw, btdm->reject_aggre_pkt);
794 
795 	if (btdm->low_penalty_rate_adaptive)
796 		dm_bt_set_sw_penalty_tx_rate_adapt(hw, BT_TX_RATE_ADAPTIVE_LOW_PENALTY);
797 	else
798 		dm_bt_set_sw_penalty_tx_rate_adapt(hw,
799 						   BT_TX_RATE_ADAPTIVE_NORMAL);
800 
801 	if (btdm->rf_rx_lpf_shrink)
802 		rtl8723e_dm_bt_set_sw_rf_rx_lpf_corner(hw,
803 				BT_RF_RX_LPF_CORNER_SHRINK);
804 	else
805 		rtl8723e_dm_bt_set_sw_rf_rx_lpf_corner(hw,
806 				BT_RF_RX_LPF_CORNER_RESUME);
807 
808 	if (btdm->agc_table_en)
809 		rtl8723e_dm_bt_agc_table(hw, BT_AGCTABLE_ON);
810 	else
811 		rtl8723e_dm_bt_agc_table(hw, BT_AGCTABLE_OFF);
812 
813 	if (btdm->adc_back_off_on)
814 		rtl8723e_dm_bt_bb_back_off_level(hw, BT_BB_BACKOFF_ON);
815 	else
816 		rtl8723e_dm_bt_bb_back_off_level(hw, BT_BB_BACKOFF_OFF);
817 
818 	rtl8723e_dm_bt_set_fw_bt_retry_index(hw, btdm->bt_retry_index);
819 
820 	rtl8723e_dm_bt_set_fw_dac_swing_level(hw, btdm->fw_dac_swing_lvl);
821 	rtl8723e_dm_bt_set_fw_wlan_act(hw, btdm->wlan_act_hi,
822 				       btdm->wlan_act_lo);
823 
824 	rtl8723e_dm_bt_set_coex_table(hw, btdm->val_0x6c0,
825 				      btdm->val_0x6c8, btdm->val_0x6cc);
826 	rtl8723e_dm_bt_set_hw_pta_mode(hw, btdm->pta_on);
827 
828 	/* Note: There is a constraint between TDMA and 2AntHID
829 	 * Only one of 2AntHid and tdma can be turn on
830 	 * We should turn off those mechanisms should be turned off first
831 	 * and then turn on those mechanisms should be turned on.
832 	*/
833 	if (btdm->b2_ant_hid_en) {
834 		/* turn off tdma */
835 		rtl8723e_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on,
836 						    btdm->tra_tdma_ant,
837 						    btdm->tra_tdma_nav);
838 		rtl8723e_dm_bt_set_fw_tdma_ctrl(hw, false, btdm->tdma_ant,
839 						btdm->tdma_nav,
840 						btdm->tdma_dac_swing);
841 
842 		/* turn off Pstdma */
843 		rtl8723e_dm_bt_set_fw_ignore_wlan_act(hw,
844 						      btdm->ignore_wlan_act);
845 		/* Antenna control by PTA, 0x870 = 0x300. */
846 		rtl8723e_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0);
847 
848 		/* turn on 2AntHid */
849 		rtl8723e_dm_bt_set_fw_bt_hid_info(hw, true);
850 		rtl8723e_dm_bt_set_fw_2_ant_hid(hw, true, true);
851 	} else if (btdm->tdma_on) {
852 		/* turn off 2AntHid */
853 		rtl8723e_dm_bt_set_fw_bt_hid_info(hw, false);
854 		rtl8723e_dm_bt_set_fw_2_ant_hid(hw, false, false);
855 
856 		/* turn off pstdma */
857 		rtl8723e_dm_bt_set_fw_ignore_wlan_act(hw,
858 						      btdm->ignore_wlan_act);
859 		/* Antenna control by PTA, 0x870 = 0x300. */
860 		rtl8723e_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0);
861 
862 		/* turn on tdma */
863 		rtl8723e_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on,
864 						    btdm->tra_tdma_ant,
865 						    btdm->tra_tdma_nav);
866 		rtl8723e_dm_bt_set_fw_tdma_ctrl(hw, true, btdm->tdma_ant,
867 						btdm->tdma_nav,
868 						btdm->tdma_dac_swing);
869 	} else if (btdm->ps_tdma_on) {
870 		/* turn off 2AntHid */
871 		rtl8723e_dm_bt_set_fw_bt_hid_info(hw, false);
872 		rtl8723e_dm_bt_set_fw_2_ant_hid(hw, false, false);
873 
874 		/* turn off tdma */
875 		rtl8723e_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on,
876 						    btdm->tra_tdma_ant,
877 						    btdm->tra_tdma_nav);
878 		rtl8723e_dm_bt_set_fw_tdma_ctrl(hw, false, btdm->tdma_ant,
879 						btdm->tdma_nav,
880 						btdm->tdma_dac_swing);
881 
882 		/* turn on pstdma */
883 		rtl8723e_dm_bt_set_fw_ignore_wlan_act(hw,
884 						      btdm->ignore_wlan_act);
885 		rtl8723e_dm_bt_set_fw_3a(hw, btdm->ps_tdma_byte[0],
886 					 btdm->ps_tdma_byte[1],
887 					 btdm->ps_tdma_byte[2],
888 					 btdm->ps_tdma_byte[3],
889 					 btdm->ps_tdma_byte[4]);
890 	} else {
891 		/* turn off 2AntHid */
892 		rtl8723e_dm_bt_set_fw_bt_hid_info(hw, false);
893 		rtl8723e_dm_bt_set_fw_2_ant_hid(hw, false, false);
894 
895 		/* turn off tdma */
896 		rtl8723e_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on,
897 						    btdm->tra_tdma_ant,
898 						    btdm->tra_tdma_nav);
899 		rtl8723e_dm_bt_set_fw_tdma_ctrl(hw, false, btdm->tdma_ant,
900 						btdm->tdma_nav,
901 						btdm->tdma_dac_swing);
902 
903 		/* turn off pstdma */
904 		rtl8723e_dm_bt_set_fw_ignore_wlan_act(hw,
905 						btdm->ignore_wlan_act);
906 		/* Antenna control by PTA, 0x870 = 0x300. */
907 		rtl8723e_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0);
908 	}
909 
910 	/* Note:
911 	 * We should add delay for making sure
912 	 *	sw DacSwing can be set sucessfully.
913 	 * because of that rtl8723e_dm_bt_set_fw_2_ant_hid()
914 	 *	and rtl8723e_dm_bt_set_fw_tdma_ctrl()
915 	 * will overwrite the reg 0x880.
916 	*/
917 	mdelay(30);
918 	rtl8723e_dm_bt_set_sw_full_time_dac_swing(hw, btdm->sw_dac_swing_on,
919 						  btdm->sw_dac_swing_lvl);
920 	rtl8723e_dm_bt_set_fw_dec_bt_pwr(hw, btdm->dec_bt_pwr);
921 }
922 
923 /* ============================================================ */
924 /* extern function start with BTDM_ */
925 /* ============================================================i
926  */
927 static u32 rtl8723e_dm_bt_tx_rx_couter_h(struct ieee80211_hw *hw)
928 {
929 	u32	counters = 0;
930 
931 	counters = hal_coex_8723.high_priority_tx +
932 			hal_coex_8723.high_priority_rx;
933 	return counters;
934 }
935 
936 static u32 rtl8723e_dm_bt_tx_rx_couter_l(struct ieee80211_hw *hw)
937 {
938 	u32 counters = 0;
939 
940 	counters = hal_coex_8723.low_priority_tx +
941 			hal_coex_8723.low_priority_rx;
942 	return counters;
943 }
944 
945 static u8 rtl8723e_dm_bt_bt_tx_rx_counter_level(struct ieee80211_hw *hw)
946 {
947 	struct rtl_priv *rtlpriv = rtl_priv(hw);
948 	u32	bt_tx_rx_cnt = 0;
949 	u8	bt_tx_rx_cnt_lvl = 0;
950 
951 	bt_tx_rx_cnt = rtl8723e_dm_bt_tx_rx_couter_h(hw)
952 				+ rtl8723e_dm_bt_tx_rx_couter_l(hw);
953 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
954 		 "[BTCoex], BT TxRx Counters = %d\n", bt_tx_rx_cnt);
955 
956 	rtlpriv->btcoexist.cstate_h &= ~
957 		 (BT_COEX_STATE_BT_CNT_LEVEL_0 | BT_COEX_STATE_BT_CNT_LEVEL_1|
958 		  BT_COEX_STATE_BT_CNT_LEVEL_2);
959 
960 	if (bt_tx_rx_cnt >= BT_TXRX_CNT_THRES_3) {
961 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
962 			 "[BTCoex], BT TxRx Counters at level 3\n");
963 		bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_3;
964 		rtlpriv->btcoexist.cstate_h |=
965 			BT_COEX_STATE_BT_CNT_LEVEL_3;
966 	} else if (bt_tx_rx_cnt >= BT_TXRX_CNT_THRES_2) {
967 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
968 			 "[BTCoex], BT TxRx Counters at level 2\n");
969 		bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_2;
970 		rtlpriv->btcoexist.cstate_h |=
971 			BT_COEX_STATE_BT_CNT_LEVEL_2;
972 	} else if (bt_tx_rx_cnt >= BT_TXRX_CNT_THRES_1) {
973 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
974 			 "[BTCoex], BT TxRx Counters at level 1\n");
975 		bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_1;
976 		rtlpriv->btcoexist.cstate_h  |=
977 			BT_COEX_STATE_BT_CNT_LEVEL_1;
978 	} else {
979 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
980 			 "[BTCoex], BT TxRx Counters at level 0\n");
981 		bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_0;
982 		rtlpriv->btcoexist.cstate_h |=
983 			BT_COEX_STATE_BT_CNT_LEVEL_0;
984 	}
985 	return bt_tx_rx_cnt_lvl;
986 }
987 
988 static void rtl8723e_dm_bt_2_ant_hid_sco_esco(struct ieee80211_hw *hw)
989 {
990 	struct rtl_priv *rtlpriv = rtl_priv(hw);
991 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
992 	struct btdm_8723 btdm8723;
993 	u8 bt_rssi_state, bt_rssi_state1;
994 	u8	bt_tx_rx_cnt_lvl = 0;
995 
996 	rtl8723e_dm_bt_btdm_structure_reload(hw, &btdm8723);
997 
998 	btdm8723.rf_rx_lpf_shrink = true;
999 	btdm8723.low_penalty_rate_adaptive = true;
1000 	btdm8723.reject_aggre_pkt = false;
1001 
1002 	bt_tx_rx_cnt_lvl = rtl8723e_dm_bt_bt_tx_rx_counter_level(hw);
1003 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1004 		 "[BTCoex], BT TxRx Counters = %d\n", bt_tx_rx_cnt_lvl);
1005 
1006 	if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
1007 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, "HT40\n");
1008 		/* coex table */
1009 		btdm8723.val_0x6c0 = 0x55555555;
1010 		btdm8723.val_0x6c8 = 0xffff;
1011 		btdm8723.val_0x6cc = 0x3;
1012 
1013 		/* sw mechanism */
1014 		btdm8723.agc_table_en = false;
1015 		btdm8723.adc_back_off_on = false;
1016 		btdm8723.sw_dac_swing_on = false;
1017 
1018 		/* fw mechanism */
1019 		btdm8723.ps_tdma_on = true;
1020 		if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) {
1021 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1022 				 "[BTCoex], BT TxRx Counters >= 1400\n");
1023 			btdm8723.ps_tdma_byte[0] = 0xa3;
1024 			btdm8723.ps_tdma_byte[1] = 0x5;
1025 			btdm8723.ps_tdma_byte[2] = 0x5;
1026 			btdm8723.ps_tdma_byte[3] = 0x2;
1027 			btdm8723.ps_tdma_byte[4] = 0x80;
1028 		} else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) {
1029 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1030 				 "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n");
1031 			btdm8723.ps_tdma_byte[0] = 0xa3;
1032 			btdm8723.ps_tdma_byte[1] = 0xa;
1033 			btdm8723.ps_tdma_byte[2] = 0xa;
1034 			btdm8723.ps_tdma_byte[3] = 0x2;
1035 			btdm8723.ps_tdma_byte[4] = 0x80;
1036 		} else {
1037 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1038 				 "[BTCoex], BT TxRx Counters < 1200\n");
1039 			btdm8723.ps_tdma_byte[0] = 0xa3;
1040 			btdm8723.ps_tdma_byte[1] = 0xf;
1041 			btdm8723.ps_tdma_byte[2] = 0xf;
1042 			btdm8723.ps_tdma_byte[3] = 0x2;
1043 			btdm8723.ps_tdma_byte[4] = 0x80;
1044 		}
1045 	} else {
1046 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1047 			 "HT20 or Legacy\n");
1048 		bt_rssi_state =
1049 		  rtl8723e_dm_bt_check_coex_rssi_state(hw, 2, 47, 0);
1050 		bt_rssi_state1 =
1051 		  rtl8723e_dm_bt_check_coex_rssi_state1(hw, 2, 27, 0);
1052 
1053 		/* coex table */
1054 		btdm8723.val_0x6c0 = 0x55555555;
1055 		btdm8723.val_0x6c8 = 0xffff;
1056 		btdm8723.val_0x6cc = 0x3;
1057 
1058 		/* sw mechanism */
1059 		if ((bt_rssi_state == BT_RSSI_STATE_HIGH) ||
1060 			(bt_rssi_state == BT_RSSI_STATE_STAY_HIGH)) {
1061 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1062 					"Wifi rssi high\n");
1063 			btdm8723.agc_table_en = true;
1064 			btdm8723.adc_back_off_on = true;
1065 			btdm8723.sw_dac_swing_on = false;
1066 		} else {
1067 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1068 					"Wifi rssi low\n");
1069 			btdm8723.agc_table_en = false;
1070 			btdm8723.adc_back_off_on = false;
1071 			btdm8723.sw_dac_swing_on = false;
1072 		}
1073 
1074 		/* fw mechanism */
1075 		btdm8723.ps_tdma_on = true;
1076 		if ((bt_rssi_state1 == BT_RSSI_STATE_HIGH) ||
1077 			(bt_rssi_state1 == BT_RSSI_STATE_STAY_HIGH)) {
1078 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1079 				 "Wifi rssi-1 high\n");
1080 			/* only rssi high we need to do this, */
1081 			/* when rssi low, the value will modified by fw */
1082 			rtl_write_byte(rtlpriv, 0x883, 0x40);
1083 			if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) {
1084 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1085 				"[BTCoex], BT TxRx Counters >= 1400\n");
1086 				btdm8723.ps_tdma_byte[0] = 0xa3;
1087 				btdm8723.ps_tdma_byte[1] = 0x5;
1088 				btdm8723.ps_tdma_byte[2] = 0x5;
1089 				btdm8723.ps_tdma_byte[3] = 0x83;
1090 				btdm8723.ps_tdma_byte[4] = 0x80;
1091 			} else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) {
1092 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1093 					 "[BTCoex], BT TxRx Counters>= 1200 && < 1400\n");
1094 				btdm8723.ps_tdma_byte[0] = 0xa3;
1095 				btdm8723.ps_tdma_byte[1] = 0xa;
1096 				btdm8723.ps_tdma_byte[2] = 0xa;
1097 				btdm8723.ps_tdma_byte[3] = 0x83;
1098 				btdm8723.ps_tdma_byte[4] = 0x80;
1099 			} else {
1100 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1101 					 "[BTCoex], BT TxRx Counters < 1200\n");
1102 				btdm8723.ps_tdma_byte[0] = 0xa3;
1103 				btdm8723.ps_tdma_byte[1] = 0xf;
1104 				btdm8723.ps_tdma_byte[2] = 0xf;
1105 				btdm8723.ps_tdma_byte[3] = 0x83;
1106 				btdm8723.ps_tdma_byte[4] = 0x80;
1107 			}
1108 		} else {
1109 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1110 					"Wifi rssi-1 low\n");
1111 			if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) {
1112 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1113 					 "[BTCoex], BT TxRx Counters >= 1400\n");
1114 				btdm8723.ps_tdma_byte[0] = 0xa3;
1115 				btdm8723.ps_tdma_byte[1] = 0x5;
1116 				btdm8723.ps_tdma_byte[2] = 0x5;
1117 				btdm8723.ps_tdma_byte[3] = 0x2;
1118 				btdm8723.ps_tdma_byte[4] = 0x80;
1119 			} else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) {
1120 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1121 					 "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n");
1122 				btdm8723.ps_tdma_byte[0] = 0xa3;
1123 				btdm8723.ps_tdma_byte[1] = 0xa;
1124 				btdm8723.ps_tdma_byte[2] = 0xa;
1125 				btdm8723.ps_tdma_byte[3] = 0x2;
1126 				btdm8723.ps_tdma_byte[4] = 0x80;
1127 			} else {
1128 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1129 					 "[BTCoex], BT TxRx Counters < 1200\n");
1130 				btdm8723.ps_tdma_byte[0] = 0xa3;
1131 				btdm8723.ps_tdma_byte[1] = 0xf;
1132 				btdm8723.ps_tdma_byte[2] = 0xf;
1133 				btdm8723.ps_tdma_byte[3] = 0x2;
1134 				btdm8723.ps_tdma_byte[4] = 0x80;
1135 			}
1136 		}
1137 	}
1138 
1139 	if (rtl8723e_dm_bt_need_to_dec_bt_pwr(hw))
1140 		btdm8723.dec_bt_pwr = true;
1141 
1142 	/* Always ignore WlanAct if bHid|bSCOBusy|bSCOeSCO */
1143 
1144 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1145 		 "[BTCoex], BT btInqPageStartTime = 0x%x, btTxRxCntLvl = %d\n",
1146 		 hal_coex_8723.bt_inq_page_start_time, bt_tx_rx_cnt_lvl);
1147 	if ((hal_coex_8723.bt_inq_page_start_time) ||
1148 	    (BT_TXRX_CNT_LEVEL_3 == bt_tx_rx_cnt_lvl)) {
1149 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1150 			 "[BTCoex], Set BT inquiry / page scan 0x3a setting\n");
1151 		btdm8723.ps_tdma_on = true;
1152 		btdm8723.ps_tdma_byte[0] = 0xa3;
1153 		btdm8723.ps_tdma_byte[1] = 0x5;
1154 		btdm8723.ps_tdma_byte[2] = 0x5;
1155 		btdm8723.ps_tdma_byte[3] = 0x2;
1156 		btdm8723.ps_tdma_byte[4] = 0x80;
1157 	}
1158 
1159 	if (rtl8723e_dm_bt_is_coexist_state_changed(hw))
1160 		rtl8723e_dm_bt_set_bt_dm(hw, &btdm8723);
1161 
1162 }
1163 
1164 static void rtl8723e_dm_bt_2_ant_ftp_a2dp(struct ieee80211_hw *hw)
1165 {
1166 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1167 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
1168 	struct btdm_8723 btdm8723;
1169 
1170 	u8 bt_rssi_state, bt_rssi_state1;
1171 	u32 bt_tx_rx_cnt_lvl = 0;
1172 
1173 	rtl8723e_dm_bt_btdm_structure_reload(hw, &btdm8723);
1174 
1175 	btdm8723.rf_rx_lpf_shrink = true;
1176 	btdm8723.low_penalty_rate_adaptive = true;
1177 	btdm8723.reject_aggre_pkt = false;
1178 
1179 	bt_tx_rx_cnt_lvl = rtl8723e_dm_bt_bt_tx_rx_counter_level(hw);
1180 
1181 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1182 	"[BTCoex], BT TxRx Counters = %d\n", bt_tx_rx_cnt_lvl);
1183 
1184 	if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
1185 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, "HT40\n");
1186 		bt_rssi_state =
1187 		  rtl8723e_dm_bt_check_coex_rssi_state(hw, 2, 37, 0);
1188 
1189 		/* coex table */
1190 		btdm8723.val_0x6c0 = 0x55555555;
1191 		btdm8723.val_0x6c8 = 0xffff;
1192 		btdm8723.val_0x6cc = 0x3;
1193 
1194 		/* sw mechanism */
1195 		btdm8723.agc_table_en = false;
1196 		btdm8723.adc_back_off_on = true;
1197 		btdm8723.sw_dac_swing_on = false;
1198 
1199 		/* fw mechanism */
1200 		btdm8723.ps_tdma_on = true;
1201 		if ((bt_rssi_state == BT_RSSI_STATE_HIGH) ||
1202 			(bt_rssi_state == BT_RSSI_STATE_STAY_HIGH)) {
1203 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1204 						"Wifi rssi high\n");
1205 			if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) {
1206 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1207 				"[BTCoex], BT TxRx Counters >= 1400\n");
1208 				btdm8723.ps_tdma_byte[0] = 0xa3;
1209 				btdm8723.ps_tdma_byte[1] = 0x5;
1210 				btdm8723.ps_tdma_byte[2] = 0x5;
1211 				btdm8723.ps_tdma_byte[3] = 0x81;
1212 				btdm8723.ps_tdma_byte[4] = 0x80;
1213 			} else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) {
1214 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1215 					 "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n");
1216 				btdm8723.ps_tdma_byte[0] = 0xa3;
1217 				btdm8723.ps_tdma_byte[1] = 0xa;
1218 				btdm8723.ps_tdma_byte[2] = 0xa;
1219 				btdm8723.ps_tdma_byte[3] = 0x81;
1220 				btdm8723.ps_tdma_byte[4] = 0x80;
1221 			} else {
1222 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1223 					 "[BTCoex], BT TxRx Counters < 1200\n");
1224 				btdm8723.ps_tdma_byte[0] = 0xa3;
1225 				btdm8723.ps_tdma_byte[1] = 0xf;
1226 				btdm8723.ps_tdma_byte[2] = 0xf;
1227 				btdm8723.ps_tdma_byte[3] = 0x81;
1228 				btdm8723.ps_tdma_byte[4] = 0x80;
1229 			}
1230 		} else {
1231 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1232 				 "Wifi rssi low\n");
1233 			if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) {
1234 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1235 					 "[BTCoex], BT TxRx Counters >= 1400\n");
1236 				btdm8723.ps_tdma_byte[0] = 0xa3;
1237 				btdm8723.ps_tdma_byte[1] = 0x5;
1238 				btdm8723.ps_tdma_byte[2] = 0x5;
1239 				btdm8723.ps_tdma_byte[3] = 0x0;
1240 				btdm8723.ps_tdma_byte[4] = 0x80;
1241 			} else if (bt_tx_rx_cnt_lvl ==
1242 				BT_TXRX_CNT_LEVEL_1) {
1243 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1244 					 "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n");
1245 				btdm8723.ps_tdma_byte[0] = 0xa3;
1246 				btdm8723.ps_tdma_byte[1] = 0xa;
1247 				btdm8723.ps_tdma_byte[2] = 0xa;
1248 				btdm8723.ps_tdma_byte[3] = 0x0;
1249 				btdm8723.ps_tdma_byte[4] = 0x80;
1250 			} else {
1251 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1252 					 "[BTCoex], BT TxRx Counters < 1200\n");
1253 				btdm8723.ps_tdma_byte[0] = 0xa3;
1254 				btdm8723.ps_tdma_byte[1] = 0xf;
1255 				btdm8723.ps_tdma_byte[2] = 0xf;
1256 				btdm8723.ps_tdma_byte[3] = 0x0;
1257 				btdm8723.ps_tdma_byte[4] = 0x80;
1258 			}
1259 		}
1260 	} else {
1261 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1262 			 "HT20 or Legacy\n");
1263 		bt_rssi_state =
1264 		  rtl8723e_dm_bt_check_coex_rssi_state(hw, 2, 47, 0);
1265 		bt_rssi_state1 =
1266 		  rtl8723e_dm_bt_check_coex_rssi_state1(hw, 2, 27, 0);
1267 
1268 		/* coex table */
1269 		btdm8723.val_0x6c0 = 0x55555555;
1270 		btdm8723.val_0x6c8 = 0xffff;
1271 		btdm8723.val_0x6cc = 0x3;
1272 
1273 		/* sw mechanism */
1274 		if ((bt_rssi_state == BT_RSSI_STATE_HIGH) ||
1275 			(bt_rssi_state == BT_RSSI_STATE_STAY_HIGH)) {
1276 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1277 				 "Wifi rssi high\n");
1278 			btdm8723.agc_table_en = true;
1279 			btdm8723.adc_back_off_on = true;
1280 			btdm8723.sw_dac_swing_on = false;
1281 		} else {
1282 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1283 				 "Wifi rssi low\n");
1284 			btdm8723.agc_table_en = false;
1285 			btdm8723.adc_back_off_on = false;
1286 			btdm8723.sw_dac_swing_on = false;
1287 		}
1288 
1289 		/* fw mechanism */
1290 		btdm8723.ps_tdma_on = true;
1291 		if ((bt_rssi_state1 == BT_RSSI_STATE_HIGH) ||
1292 			(bt_rssi_state1 == BT_RSSI_STATE_STAY_HIGH)) {
1293 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1294 				 "Wifi rssi-1 high\n");
1295 			/* only rssi high we need to do this, */
1296 			/* when rssi low, the value will modified by fw */
1297 			rtl_write_byte(rtlpriv, 0x883, 0x40);
1298 			if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) {
1299 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1300 					 "[BTCoex], BT TxRx Counters >= 1400\n");
1301 				btdm8723.ps_tdma_byte[0] = 0xa3;
1302 				btdm8723.ps_tdma_byte[1] = 0x5;
1303 				btdm8723.ps_tdma_byte[2] = 0x5;
1304 				btdm8723.ps_tdma_byte[3] = 0x81;
1305 				btdm8723.ps_tdma_byte[4] = 0x80;
1306 			} else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) {
1307 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1308 					 "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n");
1309 				btdm8723.ps_tdma_byte[0] = 0xa3;
1310 				btdm8723.ps_tdma_byte[1] = 0xa;
1311 				btdm8723.ps_tdma_byte[2] = 0xa;
1312 				btdm8723.ps_tdma_byte[3] = 0x81;
1313 				btdm8723.ps_tdma_byte[4] = 0x80;
1314 			} else {
1315 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1316 					 "[BTCoex], BT TxRx Counters < 1200\n");
1317 				btdm8723.ps_tdma_byte[0] = 0xa3;
1318 				btdm8723.ps_tdma_byte[1] = 0xf;
1319 				btdm8723.ps_tdma_byte[2] = 0xf;
1320 				btdm8723.ps_tdma_byte[3] = 0x81;
1321 				btdm8723.ps_tdma_byte[4] = 0x80;
1322 			}
1323 		} else {
1324 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1325 				 "Wifi rssi-1 low\n");
1326 			if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) {
1327 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1328 					 "[BTCoex], BT TxRx Counters >= 1400\n");
1329 				btdm8723.ps_tdma_byte[0] = 0xa3;
1330 				btdm8723.ps_tdma_byte[1] = 0x5;
1331 				btdm8723.ps_tdma_byte[2] = 0x5;
1332 				btdm8723.ps_tdma_byte[3] = 0x0;
1333 				btdm8723.ps_tdma_byte[4] = 0x80;
1334 			} else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) {
1335 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1336 					 "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n");
1337 				btdm8723.ps_tdma_byte[0] = 0xa3;
1338 				btdm8723.ps_tdma_byte[1] = 0xa;
1339 				btdm8723.ps_tdma_byte[2] = 0xa;
1340 				btdm8723.ps_tdma_byte[3] = 0x0;
1341 				btdm8723.ps_tdma_byte[4] = 0x80;
1342 			} else {
1343 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1344 					 "[BTCoex], BT TxRx Counters < 1200\n");
1345 				btdm8723.ps_tdma_byte[0] = 0xa3;
1346 				btdm8723.ps_tdma_byte[1] = 0xf;
1347 				btdm8723.ps_tdma_byte[2] = 0xf;
1348 				btdm8723.ps_tdma_byte[3] = 0x0;
1349 				btdm8723.ps_tdma_byte[4] = 0x80;
1350 			}
1351 		}
1352 	}
1353 
1354 	if (rtl8723e_dm_bt_need_to_dec_bt_pwr(hw))
1355 		btdm8723.dec_bt_pwr = true;
1356 
1357 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1358 		 "[BTCoex], BT btInqPageStartTime = 0x%x, btTxRxCntLvl = %d\n",
1359 		 hal_coex_8723.bt_inq_page_start_time, bt_tx_rx_cnt_lvl);
1360 
1361 	if ((hal_coex_8723.bt_inq_page_start_time) ||
1362 	    (BT_TXRX_CNT_LEVEL_3 == bt_tx_rx_cnt_lvl)) {
1363 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1364 			 "[BTCoex], Set BT inquiry / page scan 0x3a setting\n");
1365 		btdm8723.ps_tdma_on = true;
1366 		btdm8723.ps_tdma_byte[0] = 0xa3;
1367 		btdm8723.ps_tdma_byte[1] = 0x5;
1368 		btdm8723.ps_tdma_byte[2] = 0x5;
1369 		btdm8723.ps_tdma_byte[3] = 0x83;
1370 		btdm8723.ps_tdma_byte[4] = 0x80;
1371 	}
1372 
1373 	if (rtl8723e_dm_bt_is_coexist_state_changed(hw))
1374 		rtl8723e_dm_bt_set_bt_dm(hw, &btdm8723);
1375 
1376 }
1377 
1378 static void rtl8723e_dm_bt_inq_page_monitor(struct ieee80211_hw *hw)
1379 {
1380 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1381 	u32 cur_time;
1382 
1383 	cur_time = jiffies;
1384 	if (hal_coex_8723.c2h_bt_inquiry_page) {
1385 		/* bt inquiry or page is started. */
1386 		if (hal_coex_8723.bt_inq_page_start_time == 0) {
1387 			rtlpriv->btcoexist.cstate  |=
1388 			BT_COEX_STATE_BT_INQ_PAGE;
1389 			hal_coex_8723.bt_inq_page_start_time = cur_time;
1390 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1391 				 "[BTCoex], BT Inquiry/page is started at time : 0x%x\n",
1392 				 hal_coex_8723.bt_inq_page_start_time);
1393 		}
1394 	}
1395 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1396 		 "[BTCoex], BT Inquiry/page started time : 0x%x, cur_time : 0x%x\n",
1397 		 hal_coex_8723.bt_inq_page_start_time, cur_time);
1398 
1399 	if (hal_coex_8723.bt_inq_page_start_time) {
1400 		if ((((long)cur_time -
1401 			(long)hal_coex_8723.bt_inq_page_start_time) / HZ)
1402 			>= 10) {
1403 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1404 				"[BTCoex], BT Inquiry/page >= 10sec!!!\n");
1405 			hal_coex_8723.bt_inq_page_start_time = 0;
1406 			rtlpriv->btcoexist.cstate &=
1407 				~BT_COEX_STATE_BT_INQ_PAGE;
1408 		}
1409 	}
1410 }
1411 
1412 static void rtl8723e_dm_bt_reset_action_profile_state(struct ieee80211_hw *hw)
1413 {
1414 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1415 
1416 	rtlpriv->btcoexist.cstate &= ~
1417 		(BT_COEX_STATE_PROFILE_HID | BT_COEX_STATE_PROFILE_A2DP|
1418 		BT_COEX_STATE_PROFILE_PAN | BT_COEX_STATE_PROFILE_SCO);
1419 
1420 	rtlpriv->btcoexist.cstate &= ~
1421 		(BT_COEX_STATE_BTINFO_COMMON |
1422 		BT_COEX_STATE_BTINFO_B_HID_SCOESCO|
1423 		BT_COEX_STATE_BTINFO_B_FTP_A2DP);
1424 }
1425 
1426 static void _rtl8723e_dm_bt_coexist_2_ant(struct ieee80211_hw *hw)
1427 {
1428 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1429 	u8 bt_retry_cnt;
1430 	u8 bt_info_original;
1431 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1432 		"[BTCoex] Get bt info by fw!!\n");
1433 
1434 	_rtl8723_dm_bt_check_wifi_state(hw);
1435 
1436 	if (hal_coex_8723.c2h_bt_info_req_sent) {
1437 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
1438 				"[BTCoex] c2h for bt_info not rcvd yet!!\n");
1439 	}
1440 
1441 	bt_retry_cnt = hal_coex_8723.bt_retry_cnt;
1442 	bt_info_original = hal_coex_8723.c2h_bt_info_original;
1443 
1444 	/* when bt inquiry or page scan, we have to set h2c 0x25 */
1445 	/* ignore wlanact for continuous 4x2secs */
1446 	rtl8723e_dm_bt_inq_page_monitor(hw);
1447 	rtl8723e_dm_bt_reset_action_profile_state(hw);
1448 
1449 	if (rtl8723e_dm_bt_is_2_ant_common_action(hw)) {
1450 		rtlpriv->btcoexist.bt_profile_case = BT_COEX_MECH_COMMON;
1451 		rtlpriv->btcoexist.bt_profile_action = BT_COEX_MECH_COMMON;
1452 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1453 		"Action 2-Ant common.\n");
1454 	} else {
1455 		if ((bt_info_original & BTINFO_B_HID) ||
1456 			(bt_info_original & BTINFO_B_SCO_BUSY) ||
1457 			(bt_info_original & BTINFO_B_SCO_ESCO)) {
1458 				rtlpriv->btcoexist.cstate |=
1459 					BT_COEX_STATE_BTINFO_B_HID_SCOESCO;
1460 				rtlpriv->btcoexist.bt_profile_case =
1461 					BT_COEX_MECH_HID_SCO_ESCO;
1462 				rtlpriv->btcoexist.bt_profile_action =
1463 					BT_COEX_MECH_HID_SCO_ESCO;
1464 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1465 					 "[BTCoex], BTInfo: bHid|bSCOBusy|bSCOeSCO\n");
1466 				rtl8723e_dm_bt_2_ant_hid_sco_esco(hw);
1467 		} else if ((bt_info_original & BTINFO_B_FTP) ||
1468 				(bt_info_original & BTINFO_B_A2DP)) {
1469 				rtlpriv->btcoexist.cstate |=
1470 					BT_COEX_STATE_BTINFO_B_FTP_A2DP;
1471 				rtlpriv->btcoexist.bt_profile_case =
1472 					BT_COEX_MECH_FTP_A2DP;
1473 				rtlpriv->btcoexist.bt_profile_action =
1474 					BT_COEX_MECH_FTP_A2DP;
1475 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1476 					 "BTInfo: bFTP|bA2DP\n");
1477 				rtl8723e_dm_bt_2_ant_ftp_a2dp(hw);
1478 		} else {
1479 				rtlpriv->btcoexist.cstate |=
1480 					BT_COEX_STATE_BTINFO_B_HID_SCOESCO;
1481 				rtlpriv->btcoexist.bt_profile_case =
1482 					BT_COEX_MECH_NONE;
1483 				rtlpriv->btcoexist.bt_profile_action =
1484 					BT_COEX_MECH_NONE;
1485 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1486 					 "[BTCoex], BTInfo: undefined case!!!!\n");
1487 				rtl8723e_dm_bt_2_ant_hid_sco_esco(hw);
1488 		}
1489 	}
1490 }
1491 
1492 static void _rtl8723e_dm_bt_coexist_1_ant(struct ieee80211_hw *hw)
1493 {
1494 	return;
1495 }
1496 
1497 void rtl8723e_dm_bt_hw_coex_all_off_8723a(struct ieee80211_hw *hw)
1498 {
1499 	rtl8723e_dm_bt_set_coex_table(hw, 0x5a5aaaaa, 0xcc, 0x3);
1500 	rtl8723e_dm_bt_set_hw_pta_mode(hw, true);
1501 }
1502 
1503 void rtl8723e_dm_bt_fw_coex_all_off_8723a(struct ieee80211_hw *hw)
1504 {
1505 	rtl8723e_dm_bt_set_fw_ignore_wlan_act(hw, false);
1506 	rtl8723e_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0);
1507 	rtl8723e_dm_bt_set_fw_2_ant_hid(hw, false, false);
1508 	rtl8723e_dm_bt_set_fw_tra_tdma_ctrl(hw, false, TDMA_2ANT,
1509 					    TDMA_NAV_OFF);
1510 	rtl8723e_dm_bt_set_fw_tdma_ctrl(hw, false, TDMA_2ANT, TDMA_NAV_OFF,
1511 					TDMA_DAC_SWING_OFF);
1512 	rtl8723e_dm_bt_set_fw_dac_swing_level(hw, 0);
1513 	rtl8723e_dm_bt_set_fw_bt_hid_info(hw, false);
1514 	rtl8723e_dm_bt_set_fw_bt_retry_index(hw, 2);
1515 	rtl8723e_dm_bt_set_fw_wlan_act(hw, 0x10, 0x10);
1516 	rtl8723e_dm_bt_set_fw_dec_bt_pwr(hw, false);
1517 }
1518 
1519 void rtl8723e_dm_bt_sw_coex_all_off_8723a(struct ieee80211_hw *hw)
1520 {
1521 	rtl8723e_dm_bt_agc_table(hw, BT_AGCTABLE_OFF);
1522 	rtl8723e_dm_bt_bb_back_off_level(hw, BT_BB_BACKOFF_OFF);
1523 	rtl8723e_dm_bt_reject_ap_aggregated_packet(hw, false);
1524 
1525 	dm_bt_set_sw_penalty_tx_rate_adapt(hw, BT_TX_RATE_ADAPTIVE_NORMAL);
1526 	rtl8723e_dm_bt_set_sw_rf_rx_lpf_corner(hw, BT_RF_RX_LPF_CORNER_RESUME);
1527 	rtl8723e_dm_bt_set_sw_full_time_dac_swing(hw, false, 0xc0);
1528 }
1529 
1530 static void rtl8723e_dm_bt_query_bt_information(struct ieee80211_hw *hw)
1531 {
1532 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1533 	u8 h2c_parameter[1] = {0};
1534 
1535 	hal_coex_8723.c2h_bt_info_req_sent = true;
1536 
1537 	h2c_parameter[0] |=  BIT(0);
1538 
1539 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
1540 		"Query Bt information, write 0x38=0x%x\n", h2c_parameter[0]);
1541 
1542 	rtl8723e_fill_h2c_cmd(hw, 0x38, 1, h2c_parameter);
1543 }
1544 
1545 static void rtl8723e_dm_bt_bt_hw_counters_monitor(struct ieee80211_hw *hw)
1546 {
1547 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1548 	u32 reg_hp_tx_rx, reg_lp_tx_rx, u32_tmp;
1549 	u32 reg_hp_tx = 0, reg_hp_rx = 0, reg_lp_tx = 0, reg_lp_rx = 0;
1550 
1551 	reg_hp_tx_rx = REG_HIGH_PRIORITY_TXRX;
1552 	reg_lp_tx_rx = REG_LOW_PRIORITY_TXRX;
1553 
1554 	u32_tmp = rtl_read_dword(rtlpriv, reg_hp_tx_rx);
1555 	reg_hp_tx = u32_tmp & MASKLWORD;
1556 	reg_hp_rx = (u32_tmp & MASKHWORD)>>16;
1557 
1558 	u32_tmp = rtl_read_dword(rtlpriv, reg_lp_tx_rx);
1559 	reg_lp_tx = u32_tmp & MASKLWORD;
1560 	reg_lp_rx = (u32_tmp & MASKHWORD)>>16;
1561 
1562 	if (rtlpriv->btcoexist.lps_counter > 1) {
1563 		reg_hp_tx %= rtlpriv->btcoexist.lps_counter;
1564 		reg_hp_rx %= rtlpriv->btcoexist.lps_counter;
1565 		reg_lp_tx %= rtlpriv->btcoexist.lps_counter;
1566 		reg_lp_rx %= rtlpriv->btcoexist.lps_counter;
1567 	}
1568 
1569 	hal_coex_8723.high_priority_tx = reg_hp_tx;
1570 	hal_coex_8723.high_priority_rx = reg_hp_rx;
1571 	hal_coex_8723.low_priority_tx = reg_lp_tx;
1572 	hal_coex_8723.low_priority_rx = reg_lp_rx;
1573 
1574 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1575 		"High Priority Tx/Rx (reg 0x%x)=%x(%d)/%x(%d)\n",
1576 		reg_hp_tx_rx, reg_hp_tx, reg_hp_tx, reg_hp_rx, reg_hp_rx);
1577 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1578 		"Low Priority Tx/Rx (reg 0x%x)=%x(%d)/%x(%d)\n",
1579 		reg_lp_tx_rx, reg_lp_tx, reg_lp_tx, reg_lp_rx, reg_lp_rx);
1580 	rtlpriv->btcoexist.lps_counter = 0;
1581 	/* rtl_write_byte(rtlpriv, 0x76e, 0xc); */
1582 }
1583 
1584 static void rtl8723e_dm_bt_bt_enable_disable_check(struct ieee80211_hw *hw)
1585 {
1586 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1587 	bool bt_alife = true;
1588 
1589 	if (hal_coex_8723.high_priority_tx == 0 &&
1590 	    hal_coex_8723.high_priority_rx == 0 &&
1591 	    hal_coex_8723.low_priority_tx == 0 &&
1592 	    hal_coex_8723.low_priority_rx == 0) {
1593 		bt_alife = false;
1594 	}
1595 	if (hal_coex_8723.high_priority_tx == 0xeaea &&
1596 	    hal_coex_8723.high_priority_rx == 0xeaea &&
1597 	    hal_coex_8723.low_priority_tx == 0xeaea &&
1598 	    hal_coex_8723.low_priority_rx == 0xeaea) {
1599 		bt_alife = false;
1600 	}
1601 	if (hal_coex_8723.high_priority_tx == 0xffff &&
1602 	    hal_coex_8723.high_priority_rx == 0xffff &&
1603 	    hal_coex_8723.low_priority_tx == 0xffff &&
1604 	    hal_coex_8723.low_priority_rx == 0xffff) {
1605 		bt_alife = false;
1606 	}
1607 	if (bt_alife) {
1608 		rtlpriv->btcoexist.bt_active_zero_cnt = 0;
1609 		rtlpriv->btcoexist.cur_bt_disabled = false;
1610 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
1611 			 "8723A BT is enabled !!\n");
1612 	} else {
1613 		rtlpriv->btcoexist.bt_active_zero_cnt++;
1614 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
1615 			 "8723A bt all counters=0, %d times!!\n",
1616 			 rtlpriv->btcoexist.bt_active_zero_cnt);
1617 		if (rtlpriv->btcoexist.bt_active_zero_cnt >= 2) {
1618 			rtlpriv->btcoexist.cur_bt_disabled = true;
1619 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
1620 				 "8723A BT is disabled !!\n");
1621 		}
1622 	}
1623 	if (rtlpriv->btcoexist.pre_bt_disabled !=
1624 		rtlpriv->btcoexist.cur_bt_disabled) {
1625 		RT_TRACE(rtlpriv, COMP_BT_COEXIST,
1626 			 DBG_TRACE, "8723A BT is from %s to %s!!\n",
1627 			 (rtlpriv->btcoexist.pre_bt_disabled ?
1628 				"disabled" : "enabled"),
1629 			 (rtlpriv->btcoexist.cur_bt_disabled ?
1630 				"disabled" : "enabled"));
1631 		rtlpriv->btcoexist.pre_bt_disabled
1632 			= rtlpriv->btcoexist.cur_bt_disabled;
1633 	}
1634 }
1635 
1636 
1637 void rtl8723e_dm_bt_coexist_8723(struct ieee80211_hw *hw)
1638 {
1639 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1640 
1641 	rtl8723e_dm_bt_query_bt_information(hw);
1642 	rtl8723e_dm_bt_bt_hw_counters_monitor(hw);
1643 	rtl8723e_dm_bt_bt_enable_disable_check(hw);
1644 
1645 	if (rtlpriv->btcoexist.bt_ant_num == ANT_X2) {
1646 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1647 			"[BTCoex], 2 Ant mechanism\n");
1648 		_rtl8723e_dm_bt_coexist_2_ant(hw);
1649 	} else {
1650 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
1651 			"[BTCoex], 1 Ant mechanism\n");
1652 		_rtl8723e_dm_bt_coexist_1_ant(hw);
1653 	}
1654 
1655 	if (!rtl8723e_dm_bt_is_same_coexist_state(hw)) {
1656 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1657 			 "[BTCoex], Coexist State[bitMap] change from 0x%x%8x to 0x%x%8x\n",
1658 			 rtlpriv->btcoexist.previous_state_h,
1659 			 rtlpriv->btcoexist.previous_state,
1660 			 rtlpriv->btcoexist.cstate_h,
1661 			 rtlpriv->btcoexist.cstate);
1662 		rtlpriv->btcoexist.previous_state
1663 			= rtlpriv->btcoexist.cstate;
1664 		rtlpriv->btcoexist.previous_state_h
1665 			= rtlpriv->btcoexist.cstate_h;
1666 	}
1667 }
1668 
1669 static void rtl8723e_dm_bt_parse_bt_info(struct ieee80211_hw *hw,
1670 					 u8 *tmp_buf, u8 len)
1671 {
1672 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1673 	u8 bt_info;
1674 	u8 i;
1675 
1676 	hal_coex_8723.c2h_bt_info_req_sent = false;
1677 	hal_coex_8723.bt_retry_cnt = 0;
1678 	for (i = 0; i < len; i++) {
1679 		if (i == 0)
1680 			hal_coex_8723.c2h_bt_info_original = tmp_buf[i];
1681 		else if (i == 1)
1682 			hal_coex_8723.bt_retry_cnt = tmp_buf[i];
1683 		if (i == len-1)
1684 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
1685 				 "0x%2x]", tmp_buf[i]);
1686 		else
1687 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
1688 				 "0x%2x, ", tmp_buf[i]);
1689 
1690 	}
1691 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1692 		"BT info bt_info (Data)= 0x%x\n",
1693 			hal_coex_8723.c2h_bt_info_original);
1694 	bt_info = hal_coex_8723.c2h_bt_info_original;
1695 
1696 	if (bt_info & BIT(2))
1697 		hal_coex_8723.c2h_bt_inquiry_page = true;
1698 	else
1699 		hal_coex_8723.c2h_bt_inquiry_page = false;
1700 
1701 
1702 	if (bt_info & BTINFO_B_CONNECTION) {
1703 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1704 			"[BTC2H], BTInfo: bConnect=true\n");
1705 		rtlpriv->btcoexist.bt_busy = true;
1706 		rtlpriv->btcoexist.cstate &= ~BT_COEX_STATE_BT_IDLE;
1707 	} else {
1708 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
1709 			"[BTC2H], BTInfo: bConnect=false\n");
1710 		rtlpriv->btcoexist.bt_busy = false;
1711 		rtlpriv->btcoexist.cstate |= BT_COEX_STATE_BT_IDLE;
1712 	}
1713 }
1714 void rtl_8723e_c2h_command_handle(struct ieee80211_hw *hw)
1715 {
1716 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1717 	struct c2h_evt_hdr c2h_event;
1718 	u8 *ptmp_buf = NULL;
1719 	u8 index = 0;
1720 	u8 u1b_tmp = 0;
1721 	memset(&c2h_event, 0, sizeof(c2h_event));
1722 	u1b_tmp = rtl_read_byte(rtlpriv, REG_C2HEVT_MSG_NORMAL);
1723 	RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
1724 		"&&&&&&: REG_C2HEVT_MSG_NORMAL is 0x%x\n", u1b_tmp);
1725 	c2h_event.cmd_id = u1b_tmp & 0xF;
1726 	c2h_event.cmd_len = (u1b_tmp & 0xF0) >> 4;
1727 	c2h_event.cmd_seq = rtl_read_byte(rtlpriv, REG_C2HEVT_MSG_NORMAL + 1);
1728 	RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
1729 		 "cmd_id: %d, cmd_len: %d, cmd_seq: %d\n",
1730 		 c2h_event.cmd_id , c2h_event.cmd_len, c2h_event.cmd_seq);
1731 	u1b_tmp = rtl_read_byte(rtlpriv, 0x01AF);
1732 	if (u1b_tmp == C2H_EVT_HOST_CLOSE) {
1733 		return;
1734 	} else if (u1b_tmp != C2H_EVT_FW_CLOSE) {
1735 		rtl_write_byte(rtlpriv, 0x1AF, 0x00);
1736 		return;
1737 	}
1738 	ptmp_buf = kzalloc(c2h_event.cmd_len, GFP_KERNEL);
1739 	if (ptmp_buf == NULL) {
1740 		RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
1741 			 "malloc cmd buf failed\n");
1742 		return;
1743 	}
1744 
1745 	/* Read the content */
1746 	for (index = 0; index < c2h_event.cmd_len; index++)
1747 		ptmp_buf[index] = rtl_read_byte(rtlpriv,
1748 					REG_C2HEVT_MSG_NORMAL + 2 + index);
1749 
1750 
1751 	switch (c2h_event.cmd_id) {
1752 	case C2H_V0_BT_RSSI:
1753 			break;
1754 
1755 	case C2H_V0_BT_OP_MODE:
1756 			break;
1757 
1758 	case C2H_V0_BT_INFO:
1759 		RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
1760 			"BT info Byte[0] (ID) is 0x%x\n",
1761 			c2h_event.cmd_id);
1762 		RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
1763 			"BT info Byte[1] (Seq) is 0x%x\n",
1764 			c2h_event.cmd_seq);
1765 		RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
1766 			"BT info Byte[2] (Data)= 0x%x\n", ptmp_buf[0]);
1767 
1768 		rtl8723e_dm_bt_parse_bt_info(hw, ptmp_buf, c2h_event.cmd_len);
1769 
1770 		if (rtlpriv->cfg->ops->get_btc_status())
1771 			rtlpriv->btcoexist.btc_ops->btc_periodical(rtlpriv);
1772 
1773 		break;
1774 	default:
1775 		break;
1776 	}
1777 	kfree(ptmp_buf);
1778 
1779 	rtl_write_byte(rtlpriv, 0x01AF, C2H_EVT_HOST_CLOSE);
1780 }
1781