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