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