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