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