linux/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/hal_btc.c
<<
>>
Prefs
   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
  33static struct bt_coexist_8723 hal_coex_8723;
  34
  35void 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
  54static 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
  66void 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
  99static 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
 110static 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
 130static 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
 146static 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
 164static 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
 183static 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
 198static 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
 219static 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
 241static 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
 284static 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
 293static 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
 375static 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
 395static 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
 415static 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
 436static 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
 503static 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
 526static 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
 580static 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
 595static 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
 614static 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
 629static 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
 652void 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 */
 927static 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
 936static 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
 945static 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
 988static 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
1164static 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
1378static 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
1412static 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
1426static 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
1492static void _rtl8723e_dm_bt_coexist_1_ant(struct ieee80211_hw *hw)
1493{
1494        return;
1495}
1496
1497void 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
1503void 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
1519void 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
1530static 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
1545static 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
1584static 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
1637void 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
1669static 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}
1714void 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}
1781