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