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