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