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