1 /****************************************************************************** 2 * 3 * Copyright(c) 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 26 /*************************************************************** 27 * Description: 28 * 29 * This file is for RTL8723B Co-exist mechanism 30 * 31 * History 32 * 2012/11/15 Cosa first check in. 33 * 34 ***************************************************************/ 35 36 /*************************************************************** 37 * include files 38 ***************************************************************/ 39 #include "halbt_precomp.h" 40 /*************************************************************** 41 * Global variables, these are static variables 42 ***************************************************************/ 43 static struct coex_dm_8723b_1ant glcoex_dm_8723b_1ant; 44 static struct coex_dm_8723b_1ant *coex_dm = &glcoex_dm_8723b_1ant; 45 static struct coex_sta_8723b_1ant glcoex_sta_8723b_1ant; 46 static struct coex_sta_8723b_1ant *coex_sta = &glcoex_sta_8723b_1ant; 47 48 static const char *const glbt_info_src_8723b_1ant[] = { 49 "BT Info[wifi fw]", 50 "BT Info[bt rsp]", 51 "BT Info[bt auto report]", 52 }; 53 54 static u32 glcoex_ver_date_8723b_1ant = 20130918; 55 static u32 glcoex_ver_8723b_1ant = 0x47; 56 57 /*************************************************************** 58 * local function proto type if needed 59 ***************************************************************/ 60 /*************************************************************** 61 * local function start with halbtc8723b1ant_ 62 ***************************************************************/ 63 64 static void halbtc8723b1ant_updatera_mask(struct btc_coexist *btcoexist, 65 bool force_exec, u32 dis_rate_mask) 66 { 67 coex_dm->curra_mask = dis_rate_mask; 68 69 if (force_exec || (coex_dm->prera_mask != coex_dm->curra_mask)) 70 btcoexist->btc_set(btcoexist, BTC_SET_ACT_UPDATE_RAMASK, 71 &coex_dm->curra_mask); 72 73 coex_dm->prera_mask = coex_dm->curra_mask; 74 } 75 76 static void btc8723b1ant_auto_rate_fb_retry(struct btc_coexist *btcoexist, 77 bool force_exec, u8 type) 78 { 79 bool wifi_under_bmode = false; 80 81 coex_dm->cur_arfr_type = type; 82 83 if (force_exec || (coex_dm->pre_arfr_type != coex_dm->cur_arfr_type)) { 84 switch (coex_dm->cur_arfr_type) { 85 case 0: /* normal mode */ 86 btcoexist->btc_write_4byte(btcoexist, 0x430, 87 coex_dm->backup_arfr_cnt1); 88 btcoexist->btc_write_4byte(btcoexist, 0x434, 89 coex_dm->backup_arfr_cnt2); 90 break; 91 case 1: 92 btcoexist->btc_get(btcoexist, 93 BTC_GET_BL_WIFI_UNDER_B_MODE, 94 &wifi_under_bmode); 95 if (wifi_under_bmode) { 96 btcoexist->btc_write_4byte(btcoexist, 97 0x430, 0x0); 98 btcoexist->btc_write_4byte(btcoexist, 99 0x434, 0x01010101); 100 } else { 101 btcoexist->btc_write_4byte(btcoexist, 102 0x430, 0x0); 103 btcoexist->btc_write_4byte(btcoexist, 104 0x434, 0x04030201); 105 } 106 break; 107 default: 108 break; 109 } 110 } 111 112 coex_dm->pre_arfr_type = coex_dm->cur_arfr_type; 113 } 114 115 static void halbtc8723b1ant_retry_limit(struct btc_coexist *btcoexist, 116 bool force_exec, u8 type) 117 { 118 coex_dm->cur_retry_limit_type = type; 119 120 if (force_exec || (coex_dm->pre_retry_limit_type != 121 coex_dm->cur_retry_limit_type)) { 122 switch (coex_dm->cur_retry_limit_type) { 123 case 0: /* normal mode */ 124 btcoexist->btc_write_2byte(btcoexist, 0x42a, 125 coex_dm->backup_retry_limit); 126 break; 127 case 1: /* retry limit = 8 */ 128 btcoexist->btc_write_2byte(btcoexist, 0x42a, 0x0808); 129 break; 130 default: 131 break; 132 } 133 } 134 135 coex_dm->pre_retry_limit_type = coex_dm->cur_retry_limit_type; 136 } 137 138 static void halbtc8723b1ant_ampdu_maxtime(struct btc_coexist *btcoexist, 139 bool force_exec, u8 type) 140 { 141 coex_dm->cur_ampdu_time_type = type; 142 143 if (force_exec || (coex_dm->pre_ampdu_time_type != 144 coex_dm->cur_ampdu_time_type)) { 145 switch (coex_dm->cur_ampdu_time_type) { 146 case 0: /* normal mode */ 147 btcoexist->btc_write_1byte(btcoexist, 0x456, 148 coex_dm->backup_ampdu_max_time); 149 break; 150 case 1: /* AMPDU timw = 0x38 * 32us */ 151 btcoexist->btc_write_1byte(btcoexist, 0x456, 0x38); 152 break; 153 default: 154 break; 155 } 156 } 157 158 coex_dm->pre_ampdu_time_type = coex_dm->cur_ampdu_time_type; 159 } 160 161 static void halbtc8723b1ant_limited_tx(struct btc_coexist *btcoexist, 162 bool force_exec, u8 ra_masktype, 163 u8 arfr_type, u8 retry_limit_type, 164 u8 ampdu_time_type) 165 { 166 switch (ra_masktype) { 167 case 0: /* normal mode */ 168 halbtc8723b1ant_updatera_mask(btcoexist, force_exec, 0x0); 169 break; 170 case 1: /* disable cck 1/2 */ 171 halbtc8723b1ant_updatera_mask(btcoexist, force_exec, 172 0x00000003); 173 break; 174 /* disable cck 1/2/5.5, ofdm 6/9/12/18/24, mcs 0/1/2/3/4 */ 175 case 2: 176 halbtc8723b1ant_updatera_mask(btcoexist, force_exec, 177 0x0001f1f7); 178 break; 179 default: 180 break; 181 } 182 183 btc8723b1ant_auto_rate_fb_retry(btcoexist, force_exec, arfr_type); 184 halbtc8723b1ant_retry_limit(btcoexist, force_exec, retry_limit_type); 185 halbtc8723b1ant_ampdu_maxtime(btcoexist, force_exec, ampdu_time_type); 186 } 187 188 static void halbtc8723b1ant_limited_rx(struct btc_coexist *btcoexist, 189 bool force_exec, bool rej_ap_agg_pkt, 190 bool bt_ctrl_agg_buf_size, 191 u8 agg_buf_size) 192 { 193 bool reject_rx_agg = rej_ap_agg_pkt; 194 bool bt_ctrl_rx_agg_size = bt_ctrl_agg_buf_size; 195 u8 rxaggsize = agg_buf_size; 196 197 /********************************************** 198 * Rx Aggregation related setting 199 **********************************************/ 200 btcoexist->btc_set(btcoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT, 201 &reject_rx_agg); 202 /* decide BT control aggregation buf size or not */ 203 btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE, 204 &bt_ctrl_rx_agg_size); 205 /* aggregation buf size, only work 206 * when BT control Rx aggregation size. 207 */ 208 btcoexist->btc_set(btcoexist, BTC_SET_U1_AGG_BUF_SIZE, &rxaggsize); 209 /* real update aggregation setting */ 210 btcoexist->btc_set(btcoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL); 211 } 212 213 static void halbtc8723b1ant_query_bt_info(struct btc_coexist *btcoexist) 214 { 215 u8 h2c_parameter[1] = {0}; 216 217 coex_sta->c2h_bt_info_req_sent = true; 218 219 /* trigger */ 220 h2c_parameter[0] |= BIT(0); 221 222 btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter); 223 } 224 225 static void halbtc8723b1ant_monitor_bt_ctr(struct btc_coexist *btcoexist) 226 { 227 u32 reg_hp_txrx, reg_lp_txrx, u32tmp; 228 u32 reg_hp_tx = 0, reg_hp_rx = 0; 229 u32 reg_lp_tx = 0, reg_lp_rx = 0; 230 static u32 num_of_bt_counter_chk; 231 232 reg_hp_txrx = 0x770; 233 reg_lp_txrx = 0x774; 234 235 u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_hp_txrx); 236 reg_hp_tx = u32tmp & MASKLWORD; 237 reg_hp_rx = (u32tmp & MASKHWORD) >> 16; 238 239 u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_lp_txrx); 240 reg_lp_tx = u32tmp & MASKLWORD; 241 reg_lp_rx = (u32tmp & MASKHWORD) >> 16; 242 243 coex_sta->high_priority_tx = reg_hp_tx; 244 coex_sta->high_priority_rx = reg_hp_rx; 245 coex_sta->low_priority_tx = reg_lp_tx; 246 coex_sta->low_priority_rx = reg_lp_rx; 247 248 if ((coex_sta->low_priority_tx > 1050) && 249 (!coex_sta->c2h_bt_inquiry_page)) 250 coex_sta->pop_event_cnt++; 251 252 /* reset counter */ 253 btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc); 254 255 /* This part is for wifi FW and driver to update BT's status as 256 * disabled. 257 * 258 * The flow is as the following 259 * 1. disable BT 260 * 2. if all BT Tx/Rx counter = 0, after 6 sec we query bt info 261 * 3. Because BT will not rsp from mailbox, so wifi fw will know BT is 262 * disabled 263 * 264 * 4. FW will rsp c2h for BT that driver will know BT is disabled. 265 */ 266 if ((reg_hp_tx == 0) && (reg_hp_rx == 0) && (reg_lp_tx == 0) && 267 (reg_lp_rx == 0)) { 268 num_of_bt_counter_chk++; 269 if (num_of_bt_counter_chk == 3) 270 halbtc8723b1ant_query_bt_info(btcoexist); 271 } else { 272 num_of_bt_counter_chk = 0; 273 } 274 } 275 276 static void halbtc8723b1ant_monitor_wifi_ctr(struct btc_coexist *btcoexist) 277 { 278 s32 wifi_rssi = 0; 279 bool wifi_busy = false, wifi_under_b_mode = false; 280 static u8 cck_lock_counter; 281 u32 total_cnt; 282 283 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); 284 btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); 285 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, 286 &wifi_under_b_mode); 287 288 if (coex_sta->under_ips) { 289 coex_sta->crc_ok_cck = 0; 290 coex_sta->crc_ok_11g = 0; 291 coex_sta->crc_ok_11n = 0; 292 coex_sta->crc_ok_11n_agg = 0; 293 294 coex_sta->crc_err_cck = 0; 295 coex_sta->crc_err_11g = 0; 296 coex_sta->crc_err_11n = 0; 297 coex_sta->crc_err_11n_agg = 0; 298 } else { 299 coex_sta->crc_ok_cck = 300 btcoexist->btc_read_4byte(btcoexist, 0xf88); 301 coex_sta->crc_ok_11g = 302 btcoexist->btc_read_2byte(btcoexist, 0xf94); 303 coex_sta->crc_ok_11n = 304 btcoexist->btc_read_2byte(btcoexist, 0xf90); 305 coex_sta->crc_ok_11n_agg = 306 btcoexist->btc_read_2byte(btcoexist, 0xfb8); 307 308 coex_sta->crc_err_cck = 309 btcoexist->btc_read_4byte(btcoexist, 0xf84); 310 coex_sta->crc_err_11g = 311 btcoexist->btc_read_2byte(btcoexist, 0xf96); 312 coex_sta->crc_err_11n = 313 btcoexist->btc_read_2byte(btcoexist, 0xf92); 314 coex_sta->crc_err_11n_agg = 315 btcoexist->btc_read_2byte(btcoexist, 0xfba); 316 } 317 318 /* reset counter */ 319 btcoexist->btc_write_1byte_bitmask(btcoexist, 0xf16, 0x1, 0x1); 320 btcoexist->btc_write_1byte_bitmask(btcoexist, 0xf16, 0x1, 0x0); 321 322 if ((wifi_busy) && (wifi_rssi >= 30) && (!wifi_under_b_mode)) { 323 total_cnt = coex_sta->crc_ok_cck + coex_sta->crc_ok_11g + 324 coex_sta->crc_ok_11n + coex_sta->crc_ok_11n_agg; 325 326 if ((coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_BUSY) || 327 (coex_dm->bt_status == 328 BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY) || 329 (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_SCO_BUSY)) { 330 if (coex_sta->crc_ok_cck > 331 (total_cnt - coex_sta->crc_ok_cck)) { 332 if (cck_lock_counter < 3) 333 cck_lock_counter++; 334 } else { 335 if (cck_lock_counter > 0) 336 cck_lock_counter--; 337 } 338 339 } else { 340 if (cck_lock_counter > 0) 341 cck_lock_counter--; 342 } 343 } else { 344 if (cck_lock_counter > 0) 345 cck_lock_counter--; 346 } 347 348 if (!coex_sta->pre_ccklock) { 349 if (cck_lock_counter >= 3) 350 coex_sta->cck_lock = true; 351 else 352 coex_sta->cck_lock = false; 353 } else { 354 if (cck_lock_counter == 0) 355 coex_sta->cck_lock = false; 356 else 357 coex_sta->cck_lock = true; 358 } 359 360 if (coex_sta->cck_lock) 361 coex_sta->cck_ever_lock = true; 362 363 coex_sta->pre_ccklock = coex_sta->cck_lock; 364 } 365 366 static bool btc8723b1ant_is_wifi_status_changed(struct btc_coexist *btcoexist) 367 { 368 static bool pre_wifi_busy; 369 static bool pre_under_4way, pre_bt_hs_on; 370 bool wifi_busy = false, under_4way = false, bt_hs_on = false; 371 bool wifi_connected = false; 372 373 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, 374 &wifi_connected); 375 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); 376 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); 377 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, 378 &under_4way); 379 380 if (wifi_connected) { 381 if (wifi_busy != pre_wifi_busy) { 382 pre_wifi_busy = wifi_busy; 383 return true; 384 } 385 if (under_4way != pre_under_4way) { 386 pre_under_4way = under_4way; 387 return true; 388 } 389 if (bt_hs_on != pre_bt_hs_on) { 390 pre_bt_hs_on = bt_hs_on; 391 return true; 392 } 393 } 394 395 return false; 396 } 397 398 static void halbtc8723b1ant_update_bt_link_info(struct btc_coexist *btcoexist) 399 { 400 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; 401 bool bt_hs_on = false; 402 403 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); 404 405 bt_link_info->bt_link_exist = coex_sta->bt_link_exist; 406 bt_link_info->sco_exist = coex_sta->sco_exist; 407 bt_link_info->a2dp_exist = coex_sta->a2dp_exist; 408 bt_link_info->pan_exist = coex_sta->pan_exist; 409 bt_link_info->hid_exist = coex_sta->hid_exist; 410 bt_link_info->bt_hi_pri_link_exist = coex_sta->bt_hi_pri_link_exist; 411 412 /* work around for HS mode. */ 413 if (bt_hs_on) { 414 bt_link_info->pan_exist = true; 415 bt_link_info->bt_link_exist = true; 416 } 417 418 /* check if Sco only */ 419 if (bt_link_info->sco_exist && !bt_link_info->a2dp_exist && 420 !bt_link_info->pan_exist && !bt_link_info->hid_exist) 421 bt_link_info->sco_only = true; 422 else 423 bt_link_info->sco_only = false; 424 425 /* check if A2dp only */ 426 if (!bt_link_info->sco_exist && bt_link_info->a2dp_exist && 427 !bt_link_info->pan_exist && !bt_link_info->hid_exist) 428 bt_link_info->a2dp_only = true; 429 else 430 bt_link_info->a2dp_only = false; 431 432 /* check if Pan only */ 433 if (!bt_link_info->sco_exist && !bt_link_info->a2dp_exist && 434 bt_link_info->pan_exist && !bt_link_info->hid_exist) 435 bt_link_info->pan_only = true; 436 else 437 bt_link_info->pan_only = false; 438 439 /* check if Hid only */ 440 if (!bt_link_info->sco_exist && !bt_link_info->a2dp_exist && 441 !bt_link_info->pan_exist && bt_link_info->hid_exist) 442 bt_link_info->hid_only = true; 443 else 444 bt_link_info->hid_only = false; 445 } 446 447 static void halbtc8723b1ant_set_bt_auto_report(struct btc_coexist *btcoexist, 448 bool enable_auto_report) 449 { 450 u8 h2c_parameter[1] = {0}; 451 452 h2c_parameter[0] = 0; 453 454 if (enable_auto_report) 455 h2c_parameter[0] |= BIT(0); 456 457 btcoexist->btc_fill_h2c(btcoexist, 0x68, 1, h2c_parameter); 458 } 459 460 static void halbtc8723b1ant_bt_auto_report(struct btc_coexist *btcoexist, 461 bool force_exec, 462 bool enable_auto_report) 463 { 464 coex_dm->cur_bt_auto_report = enable_auto_report; 465 466 if (!force_exec) { 467 if (coex_dm->pre_bt_auto_report == coex_dm->cur_bt_auto_report) 468 return; 469 } 470 halbtc8723b1ant_set_bt_auto_report(btcoexist, 471 coex_dm->cur_bt_auto_report); 472 473 coex_dm->pre_bt_auto_report = coex_dm->cur_bt_auto_report; 474 } 475 476 static void btc8723b1ant_set_sw_pen_tx_rate_adapt(struct btc_coexist *btcoexist, 477 bool low_penalty_ra) 478 { 479 struct rtl_priv *rtlpriv = btcoexist->adapter; 480 u8 h2c_parameter[6] = {0}; 481 482 h2c_parameter[0] = 0x6; /* opCode, 0x6= Retry_Penalty */ 483 484 if (low_penalty_ra) { 485 h2c_parameter[1] |= BIT0; 486 /* normal rate except MCS7/6/5, OFDM54/48/36 */ 487 h2c_parameter[2] = 0x00; 488 h2c_parameter[3] = 0xf7; /* MCS7 or OFDM54 */ 489 h2c_parameter[4] = 0xf8; /* MCS6 or OFDM48 */ 490 h2c_parameter[5] = 0xf9; /* MCS5 or OFDM36 */ 491 } 492 493 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 494 "[BTCoex], set WiFi Low-Penalty Retry: %s", 495 (low_penalty_ra ? "ON!!" : "OFF!!")); 496 497 btcoexist->btc_fill_h2c(btcoexist, 0x69, 6, h2c_parameter); 498 } 499 500 static void halbtc8723b1ant_low_penalty_ra(struct btc_coexist *btcoexist, 501 bool force_exec, bool low_penalty_ra) 502 { 503 coex_dm->cur_low_penalty_ra = low_penalty_ra; 504 505 if (!force_exec) { 506 if (coex_dm->pre_low_penalty_ra == coex_dm->cur_low_penalty_ra) 507 return; 508 } 509 btc8723b1ant_set_sw_pen_tx_rate_adapt(btcoexist, 510 coex_dm->cur_low_penalty_ra); 511 512 coex_dm->pre_low_penalty_ra = coex_dm->cur_low_penalty_ra; 513 } 514 515 static void halbtc8723b1ant_set_coex_table(struct btc_coexist *btcoexist, 516 u32 val0x6c0, u32 val0x6c4, 517 u32 val0x6c8, u8 val0x6cc) 518 { 519 struct rtl_priv *rtlpriv = btcoexist->adapter; 520 521 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 522 "[BTCoex], set coex table, set 0x6c0 = 0x%x\n", val0x6c0); 523 btcoexist->btc_write_4byte(btcoexist, 0x6c0, val0x6c0); 524 525 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 526 "[BTCoex], set coex table, set 0x6c4 = 0x%x\n", val0x6c4); 527 btcoexist->btc_write_4byte(btcoexist, 0x6c4, val0x6c4); 528 529 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 530 "[BTCoex], set coex table, set 0x6c8 = 0x%x\n", val0x6c8); 531 btcoexist->btc_write_4byte(btcoexist, 0x6c8, val0x6c8); 532 533 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 534 "[BTCoex], set coex table, set 0x6cc = 0x%x\n", val0x6cc); 535 btcoexist->btc_write_1byte(btcoexist, 0x6cc, val0x6cc); 536 } 537 538 static void halbtc8723b1ant_coex_table(struct btc_coexist *btcoexist, 539 bool force_exec, u32 val0x6c0, 540 u32 val0x6c4, u32 val0x6c8, 541 u8 val0x6cc) 542 { 543 struct rtl_priv *rtlpriv = btcoexist->adapter; 544 545 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 546 "[BTCoex], %s write Coex Table 0x6c0 = 0x%x, 0x6c4 = 0x%x, 0x6cc = 0x%x\n", 547 (force_exec ? "force to" : ""), 548 val0x6c0, val0x6c4, val0x6cc); 549 coex_dm->cur_val0x6c0 = val0x6c0; 550 coex_dm->cur_val0x6c4 = val0x6c4; 551 coex_dm->cur_val0x6c8 = val0x6c8; 552 coex_dm->cur_val0x6cc = val0x6cc; 553 554 if (!force_exec) { 555 if ((coex_dm->pre_val0x6c0 == coex_dm->cur_val0x6c0) && 556 (coex_dm->pre_val0x6c4 == coex_dm->cur_val0x6c4) && 557 (coex_dm->pre_val0x6c8 == coex_dm->cur_val0x6c8) && 558 (coex_dm->pre_val0x6cc == coex_dm->cur_val0x6cc)) 559 return; 560 } 561 halbtc8723b1ant_set_coex_table(btcoexist, val0x6c0, val0x6c4, 562 val0x6c8, val0x6cc); 563 564 coex_dm->pre_val0x6c0 = coex_dm->cur_val0x6c0; 565 coex_dm->pre_val0x6c4 = coex_dm->cur_val0x6c4; 566 coex_dm->pre_val0x6c8 = coex_dm->cur_val0x6c8; 567 coex_dm->pre_val0x6cc = coex_dm->cur_val0x6cc; 568 } 569 570 static void halbtc8723b1ant_coex_table_with_type(struct btc_coexist *btcoexist, 571 bool force_exec, u8 type) 572 { 573 coex_sta->coex_table_type = type; 574 575 switch (type) { 576 case 0: 577 halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555, 578 0x55555555, 0xffffff, 0x3); 579 break; 580 case 1: 581 halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555, 582 0x5a5a5a5a, 0xffffff, 0x3); 583 break; 584 case 2: 585 halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a, 586 0x5a5a5a5a, 0xffffff, 0x3); 587 break; 588 case 3: 589 halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555, 590 0x5a5a5a5a, 0xffffff, 0x3); 591 break; 592 case 4: 593 if ((coex_sta->cck_ever_lock) && (coex_sta->scan_ap_num <= 5)) 594 halbtc8723b1ant_coex_table(btcoexist, force_exec, 595 0x55555555, 0xaaaa5a5a, 596 0xffffff, 0x3); 597 else 598 halbtc8723b1ant_coex_table(btcoexist, force_exec, 599 0x55555555, 0x5a5a5a5a, 600 0xffffff, 0x3); 601 break; 602 case 5: 603 halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a, 604 0x5aaa5a5a, 0xffffff, 0x3); 605 break; 606 case 6: 607 halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555, 608 0xaaaaaaaa, 0xffffff, 0x3); 609 break; 610 case 7: 611 halbtc8723b1ant_coex_table(btcoexist, force_exec, 0xaaaaaaaa, 612 0xaaaaaaaa, 0xffffff, 0x3); 613 break; 614 case 8: 615 halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55dd55dd, 616 0x5ada5ada, 0xffffff, 0x3); 617 break; 618 case 9: 619 halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55dd55dd, 620 0x5ada5ada, 0xffffff, 0x3); 621 break; 622 case 10: 623 halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55dd55dd, 624 0x5ada5ada, 0xffffff, 0x3); 625 break; 626 case 11: 627 halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55dd55dd, 628 0x5ada5ada, 0xffffff, 0x3); 629 break; 630 case 12: 631 halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55dd55dd, 632 0x5ada5ada, 0xffffff, 0x3); 633 break; 634 case 13: 635 halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x5fff5fff, 636 0xaaaaaaaa, 0xffffff, 0x3); 637 break; 638 case 14: 639 halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x5fff5fff, 640 0x5ada5ada, 0xffffff, 0x3); 641 break; 642 case 15: 643 halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55dd55dd, 644 0xaaaaaaaa, 0xffffff, 0x3); 645 break; 646 default: 647 break; 648 } 649 } 650 651 static void 652 halbtc8723b1ant_set_fw_ignore_wlan_act(struct btc_coexist *btcoexist, 653 bool enable) 654 { 655 struct rtl_priv *rtlpriv = btcoexist->adapter; 656 u8 h2c_parameter[1] = {0}; 657 658 if (enable) 659 h2c_parameter[0] |= BIT0; /* function enable */ 660 661 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 662 "[BTCoex], set FW for BT Ignore Wlan_Act, FW write 0x63 = 0x%x\n", 663 h2c_parameter[0]); 664 665 btcoexist->btc_fill_h2c(btcoexist, 0x63, 1, h2c_parameter); 666 } 667 668 static void halbtc8723b1ant_ignore_wlan_act(struct btc_coexist *btcoexist, 669 bool force_exec, bool enable) 670 { 671 struct rtl_priv *rtlpriv = btcoexist->adapter; 672 673 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 674 "[BTCoex], %s turn Ignore WlanAct %s\n", 675 (force_exec ? "force to" : ""), (enable ? "ON" : "OFF")); 676 coex_dm->cur_ignore_wlan_act = enable; 677 678 if (!force_exec) { 679 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 680 "[BTCoex], bPreIgnoreWlanAct = %d, bCurIgnoreWlanAct = %d!!\n", 681 coex_dm->pre_ignore_wlan_act, 682 coex_dm->cur_ignore_wlan_act); 683 684 if (coex_dm->pre_ignore_wlan_act == 685 coex_dm->cur_ignore_wlan_act) 686 return; 687 } 688 halbtc8723b1ant_set_fw_ignore_wlan_act(btcoexist, enable); 689 690 coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act; 691 } 692 693 static void halbtc8723b1ant_set_fw_ps_tdma(struct btc_coexist *btcoexist, 694 u8 byte1, u8 byte2, u8 byte3, 695 u8 byte4, u8 byte5) 696 { 697 struct rtl_priv *rtlpriv = btcoexist->adapter; 698 u8 h2c_parameter[5] = {0}; 699 u8 real_byte1 = byte1, real_byte5 = byte5; 700 bool ap_enable = false; 701 702 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, 703 &ap_enable); 704 705 if (ap_enable) { 706 if ((byte1 & BIT4) && !(byte1 & BIT5)) { 707 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 708 "[BTCoex], FW for 1Ant AP mode\n"); 709 real_byte1 &= ~BIT4; 710 real_byte1 |= BIT5; 711 712 real_byte5 |= BIT5; 713 real_byte5 &= ~BIT6; 714 } 715 } 716 717 h2c_parameter[0] = real_byte1; 718 h2c_parameter[1] = byte2; 719 h2c_parameter[2] = byte3; 720 h2c_parameter[3] = byte4; 721 h2c_parameter[4] = real_byte5; 722 723 coex_dm->ps_tdma_para[0] = real_byte1; 724 coex_dm->ps_tdma_para[1] = byte2; 725 coex_dm->ps_tdma_para[2] = byte3; 726 coex_dm->ps_tdma_para[3] = byte4; 727 coex_dm->ps_tdma_para[4] = real_byte5; 728 729 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 730 "[BTCoex], PS-TDMA H2C cmd =0x%x%08x\n", 731 h2c_parameter[0], 732 h2c_parameter[1] << 24 | 733 h2c_parameter[2] << 16 | 734 h2c_parameter[3] << 8 | 735 h2c_parameter[4]); 736 737 btcoexist->btc_fill_h2c(btcoexist, 0x60, 5, h2c_parameter); 738 } 739 740 static void halbtc8723b1ant_set_lps_rpwm(struct btc_coexist *btcoexist, 741 u8 lps_val, u8 rpwm_val) 742 { 743 u8 lps = lps_val; 744 u8 rpwm = rpwm_val; 745 746 btcoexist->btc_set(btcoexist, BTC_SET_U1_LPS_VAL, &lps); 747 btcoexist->btc_set(btcoexist, BTC_SET_U1_RPWM_VAL, &rpwm); 748 } 749 750 static void halbtc8723b1ant_lps_rpwm(struct btc_coexist *btcoexist, 751 bool force_exec, 752 u8 lps_val, u8 rpwm_val) 753 { 754 struct rtl_priv *rtlpriv = btcoexist->adapter; 755 756 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 757 "[BTCoex], %s set lps/rpwm = 0x%x/0x%x\n", 758 (force_exec ? "force to" : ""), lps_val, rpwm_val); 759 coex_dm->cur_lps = lps_val; 760 coex_dm->cur_rpwm = rpwm_val; 761 762 if (!force_exec) { 763 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 764 "[BTCoex], LPS-RxBeaconMode = 0x%x , LPS-RPWM = 0x%x!!\n", 765 coex_dm->cur_lps, coex_dm->cur_rpwm); 766 767 if ((coex_dm->pre_lps == coex_dm->cur_lps) && 768 (coex_dm->pre_rpwm == coex_dm->cur_rpwm)) { 769 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 770 "[BTCoex], LPS-RPWM_Last = 0x%x , LPS-RPWM_Now = 0x%x!!\n", 771 coex_dm->pre_rpwm, coex_dm->cur_rpwm); 772 773 return; 774 } 775 } 776 halbtc8723b1ant_set_lps_rpwm(btcoexist, lps_val, rpwm_val); 777 778 coex_dm->pre_lps = coex_dm->cur_lps; 779 coex_dm->pre_rpwm = coex_dm->cur_rpwm; 780 } 781 782 static void halbtc8723b1ant_sw_mechanism(struct btc_coexist *btcoexist, 783 bool low_penalty_ra) 784 { 785 struct rtl_priv *rtlpriv = btcoexist->adapter; 786 787 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 788 "[BTCoex], SM[LpRA] = %d\n", low_penalty_ra); 789 790 halbtc8723b1ant_low_penalty_ra(btcoexist, NORMAL_EXEC, low_penalty_ra); 791 } 792 793 static void halbtc8723b1ant_set_ant_path(struct btc_coexist *btcoexist, 794 u8 ant_pos_type, bool force_exec, 795 bool init_hw_cfg, bool wifi_off) 796 { 797 struct rtl_priv *rtlpriv = btcoexist->adapter; 798 struct btc_board_info *board_info = &btcoexist->board_info; 799 u32 fw_ver = 0, u32tmp = 0, cnt_bt_cal_chk = 0; 800 bool pg_ext_switch = false; 801 bool use_ext_switch = false; 802 bool is_in_mp_mode = false; 803 u8 h2c_parameter[2] = {0}, u8tmp = 0; 804 805 coex_dm->cur_ant_pos_type = ant_pos_type; 806 807 btcoexist->btc_get(btcoexist, BTC_GET_BL_EXT_SWITCH, &pg_ext_switch); 808 /* [31:16] = fw ver, [15:0] = fw sub ver */ 809 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); 810 811 if ((fw_ver < 0xc0000) || pg_ext_switch) 812 use_ext_switch = true; 813 814 if (init_hw_cfg) { 815 /* WiFi TRx Mask on */ 816 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 817 0x780); 818 /* remove due to interrupt is disabled that polling c2h will 819 * fail and delay 100ms. 820 */ 821 822 if (fw_ver >= 0x180000) { 823 /* Use H2C to set GNT_BT to HIGH */ 824 h2c_parameter[0] = 1; 825 btcoexist->btc_fill_h2c(btcoexist, 0x6E, 1, 826 h2c_parameter); 827 } else { 828 /* set grant_bt to high */ 829 btcoexist->btc_write_1byte(btcoexist, 0x765, 0x18); 830 } 831 /* set wlan_act control by PTA */ 832 btcoexist->btc_write_1byte(btcoexist, 0x76e, 0x4); 833 834 /* BT select s0/s1 is controlled by BT */ 835 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, 0x20, 0x0); 836 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x39, 0x8, 0x1); 837 btcoexist->btc_write_1byte(btcoexist, 0x974, 0xff); 838 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x944, 0x3, 0x3); 839 btcoexist->btc_write_1byte(btcoexist, 0x930, 0x77); 840 } else if (wifi_off) { 841 if (fw_ver >= 0x180000) { 842 /* Use H2C to set GNT_BT to HIGH */ 843 h2c_parameter[0] = 1; 844 btcoexist->btc_fill_h2c(btcoexist, 0x6E, 1, 845 h2c_parameter); 846 } else { 847 /* set grant_bt to high */ 848 btcoexist->btc_write_1byte(btcoexist, 0x765, 0x18); 849 } 850 /* set wlan_act to always low */ 851 btcoexist->btc_write_1byte(btcoexist, 0x76e, 0x4); 852 853 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_IS_IN_MP_MODE, 854 &is_in_mp_mode); 855 if (!is_in_mp_mode) 856 /* BT select s0/s1 is controlled by BT */ 857 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, 858 0x20, 0x0); 859 else 860 /* BT select s0/s1 is controlled by WiFi */ 861 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, 862 0x20, 0x1); 863 864 /* 0x4c[24:23]=00, Set Antenna control by BT_RFE_CTRL 865 * BT Vendor 0xac=0xf002 866 */ 867 u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c); 868 u32tmp &= ~BIT23; 869 u32tmp &= ~BIT24; 870 btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp); 871 } else { 872 /* Use H2C to set GNT_BT to LOW */ 873 if (fw_ver >= 0x180000) { 874 if (btcoexist->btc_read_1byte(btcoexist, 0x765) != 0) { 875 h2c_parameter[0] = 0; 876 btcoexist->btc_fill_h2c(btcoexist, 0x6E, 1, 877 h2c_parameter); 878 } 879 } else { 880 /* BT calibration check */ 881 while (cnt_bt_cal_chk <= 20) { 882 u8tmp = btcoexist->btc_read_1byte(btcoexist, 883 0x49d); 884 cnt_bt_cal_chk++; 885 if (u8tmp & BIT(0)) { 886 RT_TRACE(rtlpriv, COMP_BT_COEXIST, 887 DBG_LOUD, 888 "[BTCoex], ########### BT is calibrating (wait cnt=%d) ###########\n", 889 cnt_bt_cal_chk); 890 mdelay(50); 891 } else { 892 RT_TRACE(rtlpriv, COMP_BT_COEXIST, 893 DBG_LOUD, 894 "[BTCoex], ********** BT is NOT calibrating (wait cnt=%d)**********\n", 895 cnt_bt_cal_chk); 896 break; 897 } 898 } 899 900 /* set grant_bt to PTA */ 901 btcoexist->btc_write_1byte(btcoexist, 0x765, 0x0); 902 } 903 904 if (btcoexist->btc_read_1byte(btcoexist, 0x76e) != 0xc) { 905 /* set wlan_act control by PTA */ 906 btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc); 907 } 908 909 btcoexist->btc_write_1byte_bitmask( 910 btcoexist, 0x67, 0x20, 911 0x1); /* BT select s0/s1 is controlled by WiFi */ 912 } 913 914 if (use_ext_switch) { 915 if (init_hw_cfg) { 916 /* 0x4c[23] = 0, 0x4c[24] = 1 917 * Antenna control by WL/BT 918 */ 919 u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c); 920 u32tmp &= ~BIT23; 921 u32tmp |= BIT24; 922 btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp); 923 924 /* fixed internal switch S1->WiFi, S0->BT */ 925 btcoexist->btc_write_4byte(btcoexist, 0x948, 0x0); 926 927 if (board_info->btdm_ant_pos == 928 BTC_ANTENNA_AT_MAIN_PORT) { 929 /* tell firmware "no antenna inverse" */ 930 h2c_parameter[0] = 0; 931 /* ext switch type */ 932 h2c_parameter[1] = 1; 933 btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, 934 h2c_parameter); 935 } else { 936 /* tell firmware "antenna inverse" */ 937 h2c_parameter[0] = 1; 938 /* ext switch type */ 939 h2c_parameter[1] = 1; 940 btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, 941 h2c_parameter); 942 } 943 } 944 945 if (force_exec || 946 (coex_dm->cur_ant_pos_type != coex_dm->pre_ant_pos_type)) { 947 /* ext switch setting */ 948 switch (ant_pos_type) { 949 case BTC_ANT_PATH_WIFI: 950 if (board_info->btdm_ant_pos == 951 BTC_ANTENNA_AT_MAIN_PORT) 952 btcoexist->btc_write_1byte_bitmask( 953 btcoexist, 0x92c, 0x3, 0x1); 954 else 955 btcoexist->btc_write_1byte_bitmask( 956 btcoexist, 0x92c, 0x3, 0x2); 957 break; 958 case BTC_ANT_PATH_BT: 959 if (board_info->btdm_ant_pos == 960 BTC_ANTENNA_AT_MAIN_PORT) 961 btcoexist->btc_write_1byte_bitmask( 962 btcoexist, 0x92c, 0x3, 0x2); 963 else 964 btcoexist->btc_write_1byte_bitmask( 965 btcoexist, 0x92c, 0x3, 0x1); 966 break; 967 default: 968 case BTC_ANT_PATH_PTA: 969 if (board_info->btdm_ant_pos == 970 BTC_ANTENNA_AT_MAIN_PORT) 971 btcoexist->btc_write_1byte_bitmask( 972 btcoexist, 0x92c, 0x3, 0x1); 973 else 974 btcoexist->btc_write_1byte_bitmask( 975 btcoexist, 0x92c, 0x3, 0x2); 976 break; 977 } 978 } 979 } else { 980 if (init_hw_cfg) { 981 /* 0x4c[23] = 1, 0x4c[24] = 0, 982 * Antenna control by 0x64 983 */ 984 u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c); 985 u32tmp |= BIT23; 986 u32tmp &= ~BIT24; 987 btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp); 988 989 /* Fix Ext switch Main->S1, Aux->S0 */ 990 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x64, 0x1, 991 0x0); 992 993 if (board_info->btdm_ant_pos == 994 BTC_ANTENNA_AT_MAIN_PORT) { 995 /* tell firmware "no antenna inverse" */ 996 h2c_parameter[0] = 0; 997 /* internal switch type */ 998 h2c_parameter[1] = 0; 999 btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, 1000 h2c_parameter); 1001 } else { 1002 /* tell firmware "antenna inverse" */ 1003 h2c_parameter[0] = 1; 1004 /* internal switch type */ 1005 h2c_parameter[1] = 0; 1006 btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, 1007 h2c_parameter); 1008 } 1009 } 1010 1011 if (force_exec || 1012 (coex_dm->cur_ant_pos_type != coex_dm->pre_ant_pos_type)) { 1013 /* internal switch setting */ 1014 switch (ant_pos_type) { 1015 case BTC_ANT_PATH_WIFI: 1016 if (board_info->btdm_ant_pos == 1017 BTC_ANTENNA_AT_MAIN_PORT) 1018 btcoexist->btc_write_4byte(btcoexist, 1019 0x948, 0x0); 1020 else 1021 btcoexist->btc_write_4byte(btcoexist, 1022 0x948, 0x280); 1023 break; 1024 case BTC_ANT_PATH_BT: 1025 if (board_info->btdm_ant_pos == 1026 BTC_ANTENNA_AT_MAIN_PORT) 1027 btcoexist->btc_write_4byte(btcoexist, 1028 0x948, 0x280); 1029 else 1030 btcoexist->btc_write_4byte(btcoexist, 1031 0x948, 0x0); 1032 break; 1033 default: 1034 case BTC_ANT_PATH_PTA: 1035 if (board_info->btdm_ant_pos == 1036 BTC_ANTENNA_AT_MAIN_PORT) 1037 btcoexist->btc_write_4byte(btcoexist, 1038 0x948, 0x200); 1039 else 1040 btcoexist->btc_write_4byte(btcoexist, 1041 0x948, 0x80); 1042 break; 1043 } 1044 } 1045 } 1046 1047 coex_dm->pre_ant_pos_type = coex_dm->cur_ant_pos_type; 1048 } 1049 1050 static void halbtc8723b1ant_ps_tdma(struct btc_coexist *btcoexist, 1051 bool force_exec, bool turn_on, u8 type) 1052 { 1053 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; 1054 bool wifi_busy = false; 1055 u8 rssi_adjust_val = 0; 1056 u8 ps_tdma_byte0_val = 0x51; 1057 u8 ps_tdma_byte3_val = 0x10; 1058 u8 ps_tdma_byte4_val = 0x50; 1059 s8 wifi_duration_adjust = 0x0; 1060 static bool pre_wifi_busy; 1061 1062 coex_dm->cur_ps_tdma_on = turn_on; 1063 coex_dm->cur_ps_tdma = type; 1064 1065 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); 1066 1067 if (wifi_busy != pre_wifi_busy) { 1068 force_exec = true; 1069 pre_wifi_busy = wifi_busy; 1070 } 1071 1072 if (!force_exec) { 1073 if ((coex_dm->pre_ps_tdma_on == coex_dm->cur_ps_tdma_on) && 1074 (coex_dm->pre_ps_tdma == coex_dm->cur_ps_tdma)) 1075 return; 1076 } 1077 1078 if (coex_sta->scan_ap_num <= 5) { 1079 wifi_duration_adjust = 5; 1080 1081 if (coex_sta->a2dp_bit_pool >= 35) 1082 wifi_duration_adjust = -10; 1083 else if (coex_sta->a2dp_bit_pool >= 45) 1084 wifi_duration_adjust = -15; 1085 } else if (coex_sta->scan_ap_num >= 40) { 1086 wifi_duration_adjust = -15; 1087 1088 if (coex_sta->a2dp_bit_pool < 35) 1089 wifi_duration_adjust = -5; 1090 else if (coex_sta->a2dp_bit_pool < 45) 1091 wifi_duration_adjust = -10; 1092 } else if (coex_sta->scan_ap_num >= 20) { 1093 wifi_duration_adjust = -10; 1094 1095 if (coex_sta->a2dp_bit_pool >= 45) 1096 wifi_duration_adjust = -15; 1097 } else { 1098 wifi_duration_adjust = 0; 1099 1100 if (coex_sta->a2dp_bit_pool >= 35) 1101 wifi_duration_adjust = -10; 1102 else if (coex_sta->a2dp_bit_pool >= 45) 1103 wifi_duration_adjust = -15; 1104 } 1105 1106 if ((type == 1) || (type == 2) || (type == 9) || (type == 11) || 1107 (type == 101) || (type == 102) || (type == 109) || (type == 111)) { 1108 if (!coex_sta->force_lps_on) { 1109 /* Native power save TDMA, only for A2DP-only case 1110 * 1/2/9/11 while wifi noisy threshold > 30 1111 */ 1112 1113 /* no null-pkt */ 1114 ps_tdma_byte0_val = 0x61; 1115 /* no tx-pause at BT-slot */ 1116 ps_tdma_byte3_val = 0x11; 1117 /* 0x778 = d/1 toggle, no dynamic slot */ 1118 ps_tdma_byte4_val = 0x10; 1119 } else { 1120 /* null-pkt */ 1121 ps_tdma_byte0_val = 0x51; 1122 /* tx-pause at BT-slot */ 1123 ps_tdma_byte3_val = 0x10; 1124 /* 0x778 = d/1 toggle, dynamic slot */ 1125 ps_tdma_byte4_val = 0x50; 1126 } 1127 } else if ((type == 3) || (type == 13) || (type == 14) || 1128 (type == 103) || (type == 113) || (type == 114)) { 1129 /* null-pkt */ 1130 ps_tdma_byte0_val = 0x51; 1131 /* tx-pause at BT-slot */ 1132 ps_tdma_byte3_val = 0x10; 1133 /* 0x778 = d/1 toggle, no dynamic slot */ 1134 ps_tdma_byte4_val = 0x10; 1135 } else { /* native power save case */ 1136 /* no null-pkt */ 1137 ps_tdma_byte0_val = 0x61; 1138 /* no tx-pause at BT-slot */ 1139 ps_tdma_byte3_val = 0x11; 1140 /* 0x778 = d/1 toggle, no dynamic slot */ 1141 ps_tdma_byte4_val = 0x11; 1142 /* psTdmaByte4Va is not define for 0x778 = d/1, 1/1 case */ 1143 } 1144 1145 /* if (bt_link_info->slave_role) */ 1146 if ((bt_link_info->slave_role) && (bt_link_info->a2dp_exist)) 1147 /* 0x778 = 0x1 at wifi slot (no blocking BT Low-Pri pkts) */ 1148 ps_tdma_byte4_val = ps_tdma_byte4_val | 0x1; 1149 1150 if (type > 100) { 1151 /* set antenna control by SW */ 1152 ps_tdma_byte0_val = ps_tdma_byte0_val | 0x82; 1153 /* set antenna no toggle, control by antenna diversity */ 1154 ps_tdma_byte3_val = ps_tdma_byte3_val | 0x60; 1155 } 1156 1157 if (turn_on) { 1158 switch (type) { 1159 default: 1160 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x1a, 1161 0x1a, 0x0, 1162 ps_tdma_byte4_val); 1163 break; 1164 case 1: 1165 halbtc8723b1ant_set_fw_ps_tdma( 1166 btcoexist, ps_tdma_byte0_val, 1167 0x3a + wifi_duration_adjust, 0x03, 1168 ps_tdma_byte3_val, ps_tdma_byte4_val); 1169 1170 rssi_adjust_val = 11; 1171 break; 1172 case 2: 1173 halbtc8723b1ant_set_fw_ps_tdma( 1174 btcoexist, ps_tdma_byte0_val, 1175 0x2d + wifi_duration_adjust, 0x03, 1176 ps_tdma_byte3_val, ps_tdma_byte4_val); 1177 break; 1178 case 3: 1179 halbtc8723b1ant_set_fw_ps_tdma( 1180 btcoexist, ps_tdma_byte0_val, 0x30, 0x03, 1181 ps_tdma_byte3_val, ps_tdma_byte4_val); 1182 break; 1183 case 4: 1184 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x15, 1185 0x3, 0x14, 0x0); 1186 break; 1187 case 5: 1188 halbtc8723b1ant_set_fw_ps_tdma( 1189 btcoexist, ps_tdma_byte0_val, 0x1f, 0x3, 1190 ps_tdma_byte3_val, 0x11); 1191 break; 1192 case 6: 1193 halbtc8723b1ant_set_fw_ps_tdma( 1194 btcoexist, ps_tdma_byte0_val, 0x20, 0x3, 1195 ps_tdma_byte3_val, 0x11); 1196 break; 1197 case 7: 1198 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xc, 1199 0x5, 0x0, 0x0); 1200 break; 1201 case 8: 1202 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x25, 1203 0x3, 0x10, 0x0); 1204 break; 1205 case 9: 1206 halbtc8723b1ant_set_fw_ps_tdma( 1207 btcoexist, ps_tdma_byte0_val, 0x21, 0x3, 1208 ps_tdma_byte3_val, ps_tdma_byte4_val); 1209 break; 1210 case 10: 1211 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xa, 1212 0xa, 0x0, 0x40); 1213 break; 1214 case 11: 1215 halbtc8723b1ant_set_fw_ps_tdma( 1216 btcoexist, ps_tdma_byte0_val, 0x21, 0x03, 1217 ps_tdma_byte3_val, ps_tdma_byte4_val); 1218 break; 1219 case 12: 1220 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x0a, 1221 0x0a, 0x0, 0x50); 1222 break; 1223 case 13: 1224 if (coex_sta->scan_ap_num <= 3) 1225 halbtc8723b1ant_set_fw_ps_tdma( 1226 btcoexist, ps_tdma_byte0_val, 0x40, 0x3, 1227 ps_tdma_byte3_val, ps_tdma_byte4_val); 1228 else 1229 halbtc8723b1ant_set_fw_ps_tdma( 1230 btcoexist, ps_tdma_byte0_val, 0x21, 0x3, 1231 ps_tdma_byte3_val, ps_tdma_byte4_val); 1232 break; 1233 case 14: 1234 if (coex_sta->scan_ap_num <= 3) 1235 halbtc8723b1ant_set_fw_ps_tdma( 1236 btcoexist, 0x51, 0x30, 0x3, 0x10, 0x50); 1237 else 1238 halbtc8723b1ant_set_fw_ps_tdma( 1239 btcoexist, ps_tdma_byte0_val, 0x21, 0x3, 1240 ps_tdma_byte3_val, ps_tdma_byte4_val); 1241 break; 1242 case 15: 1243 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xa, 1244 0x3, 0x8, 0x0); 1245 break; 1246 case 16: 1247 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x15, 1248 0x3, 0x10, 0x0); 1249 break; 1250 case 18: 1251 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x25, 1252 0x3, 0x10, 0x0); 1253 break; 1254 case 20: 1255 halbtc8723b1ant_set_fw_ps_tdma( 1256 btcoexist, ps_tdma_byte0_val, 0x3f, 0x03, 1257 ps_tdma_byte3_val, 0x10); 1258 break; 1259 case 21: 1260 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x25, 1261 0x03, 0x11, 0x11); 1262 break; 1263 case 22: 1264 halbtc8723b1ant_set_fw_ps_tdma( 1265 btcoexist, ps_tdma_byte0_val, 0x25, 0x03, 1266 ps_tdma_byte3_val, 0x10); 1267 break; 1268 case 23: 1269 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25, 1270 0x3, 0x31, 0x18); 1271 break; 1272 case 24: 1273 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x15, 1274 0x3, 0x31, 0x18); 1275 break; 1276 case 25: 1277 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa, 1278 0x3, 0x31, 0x18); 1279 break; 1280 case 26: 1281 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa, 1282 0x3, 0x31, 0x18); 1283 break; 1284 case 27: 1285 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25, 1286 0x3, 0x31, 0x98); 1287 break; 1288 case 28: 1289 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x69, 0x25, 1290 0x3, 0x31, 0x0); 1291 break; 1292 case 29: 1293 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xab, 0x1a, 1294 0x1a, 0x1, 0x10); 1295 break; 1296 case 30: 1297 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x30, 1298 0x3, 0x10, 0x10); 1299 break; 1300 case 31: 1301 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x1a, 1302 0x1a, 0, 0x58); 1303 break; 1304 case 32: 1305 halbtc8723b1ant_set_fw_ps_tdma( 1306 btcoexist, ps_tdma_byte0_val, 0x35, 0x3, 1307 ps_tdma_byte3_val, ps_tdma_byte4_val); 1308 break; 1309 case 33: 1310 halbtc8723b1ant_set_fw_ps_tdma( 1311 btcoexist, ps_tdma_byte0_val, 0x35, 0x3, 1312 ps_tdma_byte3_val, 0x10); 1313 break; 1314 case 34: 1315 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x53, 0x1a, 1316 0x1a, 0x0, 0x10); 1317 break; 1318 case 35: 1319 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x63, 0x1a, 1320 0x1a, 0x0, 0x10); 1321 break; 1322 case 36: 1323 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x12, 1324 0x3, 0x14, 0x50); 1325 break; 1326 case 40: 1327 /* SoftAP only with no sta associated,BT disable ,TDMA 1328 * mode for power saving 1329 * 1330 * here softap mode screen off will cost 70-80mA for 1331 * phone 1332 */ 1333 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x23, 0x18, 1334 0x00, 0x10, 0x24); 1335 break; 1336 1337 case 101: 1338 /* for 1-Ant translate to 2-Ant */ 1339 halbtc8723b1ant_set_fw_ps_tdma( 1340 btcoexist, ps_tdma_byte0_val, 1341 0x3a + wifi_duration_adjust, 0x03, 1342 ps_tdma_byte3_val, ps_tdma_byte4_val); 1343 break; 1344 case 102: 1345 halbtc8723b1ant_set_fw_ps_tdma( 1346 btcoexist, ps_tdma_byte0_val, 1347 0x2d + wifi_duration_adjust, 0x03, 1348 ps_tdma_byte3_val, ps_tdma_byte4_val); 1349 break; 1350 case 103: 1351 halbtc8723b1ant_set_fw_ps_tdma( 1352 btcoexist, ps_tdma_byte0_val, 0x3a, 0x03, 1353 ps_tdma_byte3_val, ps_tdma_byte4_val); 1354 break; 1355 case 105: 1356 halbtc8723b1ant_set_fw_ps_tdma( 1357 btcoexist, ps_tdma_byte0_val, 0x15, 0x3, 1358 ps_tdma_byte3_val, 0x11); 1359 break; 1360 case 106: 1361 halbtc8723b1ant_set_fw_ps_tdma( 1362 btcoexist, ps_tdma_byte0_val, 0x20, 0x3, 1363 ps_tdma_byte3_val, 0x11); 1364 break; 1365 case 109: 1366 halbtc8723b1ant_set_fw_ps_tdma( 1367 btcoexist, ps_tdma_byte0_val, 0x21, 0x3, 1368 ps_tdma_byte3_val, ps_tdma_byte4_val); 1369 break; 1370 case 111: 1371 halbtc8723b1ant_set_fw_ps_tdma( 1372 btcoexist, ps_tdma_byte0_val, 0x21, 0x03, 1373 ps_tdma_byte3_val, ps_tdma_byte4_val); 1374 break; 1375 case 113: 1376 halbtc8723b1ant_set_fw_ps_tdma( 1377 btcoexist, ps_tdma_byte0_val, 0x21, 0x3, 1378 ps_tdma_byte3_val, ps_tdma_byte4_val); 1379 break; 1380 case 114: 1381 halbtc8723b1ant_set_fw_ps_tdma( 1382 btcoexist, ps_tdma_byte0_val, 0x21, 0x3, 1383 ps_tdma_byte3_val, ps_tdma_byte4_val); 1384 break; 1385 case 120: 1386 halbtc8723b1ant_set_fw_ps_tdma( 1387 btcoexist, ps_tdma_byte0_val, 0x3f, 0x03, 1388 ps_tdma_byte3_val, 0x10); 1389 break; 1390 case 122: 1391 halbtc8723b1ant_set_fw_ps_tdma( 1392 btcoexist, ps_tdma_byte0_val, 0x25, 0x03, 1393 ps_tdma_byte3_val, 0x10); 1394 break; 1395 case 132: 1396 halbtc8723b1ant_set_fw_ps_tdma( 1397 btcoexist, ps_tdma_byte0_val, 0x25, 0x03, 1398 ps_tdma_byte3_val, ps_tdma_byte4_val); 1399 break; 1400 case 133: 1401 halbtc8723b1ant_set_fw_ps_tdma( 1402 btcoexist, ps_tdma_byte0_val, 0x25, 0x03, 1403 ps_tdma_byte3_val, 0x11); 1404 break; 1405 } 1406 } else { 1407 /* disable PS tdma */ 1408 switch (type) { 1409 case 8: /* PTA Control */ 1410 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x8, 0x0, 1411 0x0, 0x0, 0x0); 1412 halbtc8723b1ant_set_ant_path(btcoexist, 1413 BTC_ANT_PATH_PTA, 1414 FORCE_EXEC, 1415 false, false); 1416 break; 1417 case 0: 1418 default: 1419 /* Software control, Antenna at BT side */ 1420 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 1421 0x0, 0x0, 0x0); 1422 break; 1423 case 1: /* 2-Ant, 0x778=3, antenna control by ant diversity */ 1424 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0, 1425 0x48, 0x0); 1426 break; 1427 } 1428 } 1429 rssi_adjust_val = 0; 1430 btcoexist->btc_set(btcoexist, 1431 BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE, 1432 &rssi_adjust_val); 1433 1434 /* update pre state */ 1435 coex_dm->pre_ps_tdma_on = coex_dm->cur_ps_tdma_on; 1436 coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma; 1437 } 1438 1439 static 1440 void btc8723b1ant_tdma_dur_adj_for_acl(struct btc_coexist *btcoexist, 1441 u8 wifi_status) 1442 { 1443 struct rtl_priv *rtlpriv = btcoexist->adapter; 1444 static s32 up, dn, m, n, wait_count; 1445 /* 0: no change, +1: increase WiFi duration, 1446 * -1: decrease WiFi duration 1447 */ 1448 s32 result; 1449 u8 retry_count = 0, bt_info_ext; 1450 bool wifi_busy = false; 1451 1452 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 1453 "[BTCoex], TdmaDurationAdjustForAcl()\n"); 1454 1455 if (wifi_status == BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY) 1456 wifi_busy = true; 1457 else 1458 wifi_busy = false; 1459 1460 if ((wifi_status == 1461 BT_8723B_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN) || 1462 (wifi_status == BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN) || 1463 (wifi_status == BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT)) { 1464 if (coex_dm->cur_ps_tdma != 1 && coex_dm->cur_ps_tdma != 2 && 1465 coex_dm->cur_ps_tdma != 3 && coex_dm->cur_ps_tdma != 9) { 1466 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1467 true, 9); 1468 coex_dm->ps_tdma_du_adj_type = 9; 1469 1470 up = 0; 1471 dn = 0; 1472 m = 1; 1473 n = 3; 1474 result = 0; 1475 wait_count = 0; 1476 } 1477 return; 1478 } 1479 1480 if (!coex_dm->auto_tdma_adjust) { 1481 coex_dm->auto_tdma_adjust = true; 1482 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 1483 "[BTCoex], first run TdmaDurationAdjust()!!\n"); 1484 1485 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 2); 1486 coex_dm->ps_tdma_du_adj_type = 2; 1487 1488 up = 0; 1489 dn = 0; 1490 m = 1; 1491 n = 3; 1492 result = 0; 1493 wait_count = 0; 1494 } else { 1495 /* acquire the BT TRx retry count from BT_Info byte2 */ 1496 retry_count = coex_sta->bt_retry_cnt; 1497 bt_info_ext = coex_sta->bt_info_ext; 1498 1499 if ((coex_sta->low_priority_tx) > 1050 || 1500 (coex_sta->low_priority_rx) > 1250) 1501 retry_count++; 1502 1503 result = 0; 1504 wait_count++; 1505 /* no retry in the last 2-second duration */ 1506 if (retry_count == 0) { 1507 up++; 1508 dn--; 1509 1510 if (dn <= 0) 1511 dn = 0; 1512 1513 if (up >= n) { 1514 /* if retry count during continuous n*2 seconds 1515 * is 0, enlarge WiFi duration 1516 */ 1517 wait_count = 0; 1518 n = 3; 1519 up = 0; 1520 dn = 0; 1521 result = 1; 1522 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 1523 "[BTCoex], Increase wifi duration!!\n"); 1524 } 1525 } else if (retry_count <= 3) { 1526 /* <=3 retry in the last 2-second duration */ 1527 up--; 1528 dn++; 1529 1530 if (up <= 0) 1531 up = 0; 1532 1533 if (dn == 2) { 1534 /* if continuous 2 retry count(every 2 seconds) 1535 * >0 and < 3, reduce WiFi duration 1536 */ 1537 if (wait_count <= 2) 1538 /* avoid loop between the two levels */ 1539 m++; 1540 else 1541 m = 1; 1542 1543 if (m >= 20) 1544 /* maximum of m = 20 ' will recheck if 1545 * need to adjust wifi duration in 1546 * maximum time interval 120 seconds 1547 */ 1548 m = 20; 1549 1550 n = 3 * m; 1551 up = 0; 1552 dn = 0; 1553 wait_count = 0; 1554 result = -1; 1555 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 1556 "[BTCoex], Decrease wifi duration for retryCounter<3!!\n"); 1557 } 1558 } else { 1559 /* retry count > 3, once retry count > 3, to reduce 1560 * WiFi duration 1561 */ 1562 if (wait_count == 1) 1563 /* to avoid loop between the two levels */ 1564 m++; 1565 else 1566 m = 1; 1567 1568 if (m >= 20) 1569 /* maximum of m = 20 ' will recheck if need to 1570 * adjust wifi duration in maximum time interval 1571 * 120 seconds 1572 */ 1573 m = 20; 1574 1575 n = 3 * m; 1576 up = 0; 1577 dn = 0; 1578 wait_count = 0; 1579 result = -1; 1580 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 1581 "[BTCoex], Decrease wifi duration for retryCounter>3!!\n"); 1582 } 1583 1584 if (result == -1) { 1585 if (coex_dm->cur_ps_tdma == 1) { 1586 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1587 true, 2); 1588 coex_dm->ps_tdma_du_adj_type = 2; 1589 } else if (coex_dm->cur_ps_tdma == 2) { 1590 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1591 true, 9); 1592 coex_dm->ps_tdma_du_adj_type = 9; 1593 } else if (coex_dm->cur_ps_tdma == 9) { 1594 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1595 true, 11); 1596 coex_dm->ps_tdma_du_adj_type = 11; 1597 } 1598 } else if (result == 1) { 1599 if (coex_dm->cur_ps_tdma == 11) { 1600 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1601 true, 9); 1602 coex_dm->ps_tdma_du_adj_type = 9; 1603 } else if (coex_dm->cur_ps_tdma == 9) { 1604 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1605 true, 2); 1606 coex_dm->ps_tdma_du_adj_type = 2; 1607 } else if (coex_dm->cur_ps_tdma == 2) { 1608 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1609 true, 1); 1610 coex_dm->ps_tdma_du_adj_type = 1; 1611 } 1612 } 1613 1614 if (coex_dm->cur_ps_tdma != 1 && coex_dm->cur_ps_tdma != 2 && 1615 coex_dm->cur_ps_tdma != 9 && coex_dm->cur_ps_tdma != 11) { 1616 /* recover to previous adjust type */ 1617 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 1618 coex_dm->ps_tdma_du_adj_type); 1619 } 1620 } 1621 } 1622 1623 static void halbtc8723b1ant_ps_tdma_chk_pwr_save(struct btc_coexist *btcoexist, 1624 bool new_ps_state) 1625 { 1626 u8 lps_mode = 0x0; 1627 1628 btcoexist->btc_get(btcoexist, BTC_GET_U1_LPS_MODE, &lps_mode); 1629 1630 if (lps_mode) { 1631 /* already under LPS state */ 1632 if (new_ps_state) { 1633 /* keep state under LPS, do nothing. */ 1634 } else { 1635 /* will leave LPS state, turn off psTdma first */ 1636 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1637 false, 0); 1638 } 1639 } else { 1640 /* NO PS state */ 1641 if (new_ps_state) { 1642 /* will enter LPS state, turn off psTdma first */ 1643 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1644 false, 0); 1645 } else { 1646 /* keep state under NO PS state, do nothing. */ 1647 } 1648 } 1649 } 1650 1651 static void halbtc8723b1ant_power_save_state(struct btc_coexist *btcoexist, 1652 u8 ps_type, u8 lps_val, 1653 u8 rpwm_val) 1654 { 1655 bool low_pwr_disable = false; 1656 1657 switch (ps_type) { 1658 case BTC_PS_WIFI_NATIVE: 1659 /* recover to original 32k low power setting */ 1660 low_pwr_disable = false; 1661 btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, 1662 &low_pwr_disable); 1663 btcoexist->btc_set(btcoexist, BTC_SET_ACT_NORMAL_LPS, NULL); 1664 coex_sta->force_lps_on = false; 1665 break; 1666 case BTC_PS_LPS_ON: 1667 halbtc8723b1ant_ps_tdma_chk_pwr_save(btcoexist, true); 1668 halbtc8723b1ant_lps_rpwm(btcoexist, NORMAL_EXEC, lps_val, 1669 rpwm_val); 1670 /* when coex force to enter LPS, do not enter 32k low power */ 1671 low_pwr_disable = true; 1672 btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, 1673 &low_pwr_disable); 1674 /* power save must executed before psTdma */ 1675 btcoexist->btc_set(btcoexist, BTC_SET_ACT_ENTER_LPS, NULL); 1676 coex_sta->force_lps_on = true; 1677 break; 1678 case BTC_PS_LPS_OFF: 1679 halbtc8723b1ant_ps_tdma_chk_pwr_save(btcoexist, false); 1680 btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL); 1681 coex_sta->force_lps_on = false; 1682 break; 1683 default: 1684 break; 1685 } 1686 } 1687 1688 static void halbtc8723b1ant_action_wifi_only(struct btc_coexist *btcoexist) 1689 { 1690 halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0); 1691 halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8); 1692 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, 1693 FORCE_EXEC, false, false); 1694 } 1695 1696 /* check if BT is disabled */ 1697 static void halbtc8723b1ant_monitor_bt_enable_disable(struct btc_coexist 1698 *btcoexist) 1699 { 1700 struct rtl_priv *rtlpriv = btcoexist->adapter; 1701 static u32 bt_disable_cnt; 1702 bool bt_active = true, bt_disabled = false; 1703 1704 if (coex_sta->high_priority_tx == 0 && 1705 coex_sta->high_priority_rx == 0 && coex_sta->low_priority_tx == 0 && 1706 coex_sta->low_priority_rx == 0) 1707 bt_active = false; 1708 if (coex_sta->high_priority_tx == 0xffff && 1709 coex_sta->high_priority_rx == 0xffff && 1710 coex_sta->low_priority_tx == 0xffff && 1711 coex_sta->low_priority_rx == 0xffff) 1712 bt_active = false; 1713 if (bt_active) { 1714 bt_disable_cnt = 0; 1715 bt_disabled = false; 1716 } else { 1717 bt_disable_cnt++; 1718 if (bt_disable_cnt >= 2) 1719 bt_disabled = true; 1720 } 1721 if (coex_sta->bt_disabled != bt_disabled) { 1722 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 1723 "[BTCoex], BT is from %s to %s!!\n", 1724 (coex_sta->bt_disabled ? "disabled" : "enabled"), 1725 (bt_disabled ? "disabled" : "enabled")); 1726 1727 coex_sta->bt_disabled = bt_disabled; 1728 btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_DISABLE, 1729 &bt_disabled); 1730 if (bt_disabled) { 1731 halbtc8723b1ant_action_wifi_only(btcoexist); 1732 btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, 1733 NULL); 1734 btcoexist->btc_set(btcoexist, BTC_SET_ACT_NORMAL_LPS, 1735 NULL); 1736 } 1737 } 1738 } 1739 1740 /***************************************************** 1741 * 1742 * Non-Software Coex Mechanism start 1743 * 1744 *****************************************************/ 1745 1746 static void halbtc8723b1ant_action_bt_whck_test(struct btc_coexist *btcoexist) 1747 { 1748 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 1749 0x0); 1750 1751 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); 1752 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, 1753 false, false); 1754 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); 1755 } 1756 1757 static void halbtc8723b1ant_action_wifi_multiport(struct btc_coexist *btcoexist) 1758 { 1759 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 1760 0x0, 0x0); 1761 1762 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); 1763 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, 1764 false, false); 1765 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); 1766 } 1767 1768 static void halbtc8723b1ant_action_hs(struct btc_coexist *btcoexist) 1769 { 1770 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5); 1771 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); 1772 } 1773 1774 static void halbtc8723b1ant_action_bt_inquiry(struct btc_coexist *btcoexist) 1775 { 1776 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; 1777 bool wifi_connected = false, ap_enable = false; 1778 bool wifi_busy = false, bt_busy = false; 1779 1780 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, 1781 &ap_enable); 1782 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, 1783 &wifi_connected); 1784 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); 1785 btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy); 1786 1787 if (coex_sta->bt_abnormal_scan) { 1788 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 33); 1789 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7); 1790 } else if (!wifi_connected && !coex_sta->wifi_is_high_pri_task) { 1791 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 1792 0x0, 0x0); 1793 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); 1794 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, 1795 NORMAL_EXEC, false, false); 1796 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); 1797 } else if (bt_link_info->sco_exist || bt_link_info->hid_exist || 1798 bt_link_info->a2dp_exist) { 1799 /* SCO/HID/A2DP busy */ 1800 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 1801 0x0, 0x0); 1802 if (coex_sta->c2h_bt_remote_name_req) 1803 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 1804 33); 1805 else 1806 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 1807 32); 1808 1809 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); 1810 } else if (bt_link_info->pan_exist || wifi_busy) { 1811 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 1812 0x0, 0x0); 1813 if (coex_sta->c2h_bt_remote_name_req) 1814 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 1815 33); 1816 else 1817 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 1818 32); 1819 1820 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); 1821 } else { 1822 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 1823 0x0, 0x0); 1824 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); 1825 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, 1826 NORMAL_EXEC, false, false); 1827 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7); 1828 } 1829 } 1830 1831 static void btc8723b1ant_act_bt_sco_hid_only_busy(struct btc_coexist *btcoexist, 1832 u8 wifi_status) 1833 { 1834 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; 1835 bool wifi_connected = false; 1836 1837 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, 1838 &wifi_connected); 1839 1840 /* tdma and coex table */ 1841 if (bt_link_info->sco_exist) { 1842 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5); 1843 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 5); 1844 } else { 1845 /* HID */ 1846 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 6); 1847 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 5); 1848 } 1849 } 1850 1851 static void halbtc8723b1ant_action_wifi_connected_bt_acl_busy( 1852 struct btc_coexist *btcoexist, 1853 u8 wifi_status) 1854 { 1855 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; 1856 1857 if ((coex_sta->low_priority_rx >= 950) && (!coex_sta->under_ips)) 1858 bt_link_info->slave_role = true; 1859 else 1860 bt_link_info->slave_role = false; 1861 1862 if (bt_link_info->hid_only) { /* HID */ 1863 btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist, wifi_status); 1864 coex_dm->auto_tdma_adjust = false; 1865 return; 1866 } else if (bt_link_info->a2dp_only) { /* A2DP */ 1867 if (wifi_status == BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE) { 1868 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1869 true, 32); 1870 halbtc8723b1ant_coex_table_with_type(btcoexist, 1871 NORMAL_EXEC, 4); 1872 coex_dm->auto_tdma_adjust = false; 1873 } else { 1874 btc8723b1ant_tdma_dur_adj_for_acl(btcoexist, 1875 wifi_status); 1876 halbtc8723b1ant_coex_table_with_type(btcoexist, 1877 NORMAL_EXEC, 1); 1878 coex_dm->auto_tdma_adjust = true; 1879 } 1880 } else if (((bt_link_info->a2dp_exist) && (bt_link_info->pan_exist)) || 1881 (bt_link_info->hid_exist && bt_link_info->a2dp_exist && 1882 bt_link_info->pan_exist)) { 1883 /* A2DP + PAN(OPP,FTP), HID + A2DP + PAN(OPP,FTP) */ 1884 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 13); 1885 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); 1886 coex_dm->auto_tdma_adjust = false; 1887 } else if (bt_link_info->hid_exist && bt_link_info->a2dp_exist) { 1888 /* HID + A2DP */ 1889 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14); 1890 coex_dm->auto_tdma_adjust = false; 1891 1892 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); 1893 } else if (bt_link_info->pan_only || 1894 (bt_link_info->hid_exist && bt_link_info->pan_exist)) { 1895 /* PAN(OPP,FTP), HID + PAN(OPP,FTP) */ 1896 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); 1897 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); 1898 coex_dm->auto_tdma_adjust = false; 1899 } else { 1900 /* BT no-profile busy (0x9) */ 1901 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 33); 1902 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); 1903 coex_dm->auto_tdma_adjust = false; 1904 } 1905 } 1906 1907 static void btc8723b1ant_action_wifi_not_conn(struct btc_coexist *btcoexist) 1908 { 1909 /* power save state */ 1910 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 1911 0x0, 0x0); 1912 1913 /* tdma and coex table */ 1914 halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8); 1915 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, 1916 false, false); 1917 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); 1918 } 1919 1920 static void 1921 btc8723b1ant_action_wifi_not_conn_scan(struct btc_coexist *btcoexist) 1922 { 1923 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; 1924 1925 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 1926 0x0, 0x0); 1927 1928 /* tdma and coex table */ 1929 if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_BUSY) { 1930 if (bt_link_info->a2dp_exist) { 1931 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1932 true, 32); 1933 halbtc8723b1ant_coex_table_with_type(btcoexist, 1934 NORMAL_EXEC, 4); 1935 } else if (bt_link_info->a2dp_exist) { 1936 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1937 true, 22); 1938 halbtc8723b1ant_coex_table_with_type(btcoexist, 1939 NORMAL_EXEC, 4); 1940 } else { 1941 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1942 true, 20); 1943 halbtc8723b1ant_coex_table_with_type(btcoexist, 1944 NORMAL_EXEC, 1); 1945 } 1946 } else if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_SCO_BUSY || 1947 coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY){ 1948 btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist, 1949 BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN); 1950 } else { 1951 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); 1952 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, 1953 NORMAL_EXEC, false, false); 1954 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); 1955 } 1956 } 1957 1958 static void 1959 btc8723b1ant_act_wifi_not_conn_asso_auth(struct btc_coexist *btcoexist) 1960 { 1961 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; 1962 1963 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 1964 0x0, 0x0); 1965 1966 /* tdma and coex table */ 1967 if ((bt_link_info->sco_exist) || (bt_link_info->hid_exist) || 1968 (bt_link_info->a2dp_exist)) { 1969 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32); 1970 halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 4); 1971 } else if (bt_link_info->pan_exist) { 1972 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20); 1973 halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 4); 1974 } else { 1975 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); 1976 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, 1977 NORMAL_EXEC, false, false); 1978 halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 2); 1979 } 1980 } 1981 1982 static void btc8723b1ant_action_wifi_conn_scan(struct btc_coexist *btcoexist) 1983 { 1984 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; 1985 1986 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 1987 0x0, 0x0); 1988 1989 /* tdma and coex table */ 1990 if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_BUSY) { 1991 if (bt_link_info->a2dp_exist) { 1992 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1993 true, 32); 1994 halbtc8723b1ant_coex_table_with_type(btcoexist, 1995 NORMAL_EXEC, 4); 1996 } else if (bt_link_info->a2dp_exist && 1997 bt_link_info->pan_exist) { 1998 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1999 true, 22); 2000 halbtc8723b1ant_coex_table_with_type(btcoexist, 2001 NORMAL_EXEC, 4); 2002 } else { 2003 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 2004 true, 20); 2005 halbtc8723b1ant_coex_table_with_type(btcoexist, 2006 NORMAL_EXEC, 4); 2007 } 2008 } else if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_SCO_BUSY || 2009 coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY) { 2010 btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist, 2011 BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN); 2012 } else { 2013 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); 2014 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, 2015 NORMAL_EXEC, false, false); 2016 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); 2017 } 2018 } 2019 2020 static void halbtc8723b1ant_action_wifi_connected_special_packet( 2021 struct btc_coexist *btcoexist) 2022 { 2023 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; 2024 bool wifi_busy = false; 2025 2026 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); 2027 2028 /* no special packet process for both WiFi and BT very busy */ 2029 if ((wifi_busy) && 2030 ((bt_link_info->pan_exist) || (coex_sta->num_of_profile >= 2))) 2031 return; 2032 2033 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 2034 0x0, 0x0); 2035 2036 /* tdma and coex table */ 2037 if ((bt_link_info->sco_exist) || (bt_link_info->hid_exist)) { 2038 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32); 2039 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 5); 2040 } else if (bt_link_info->a2dp_exist) { 2041 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32); 2042 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); 2043 } else if (bt_link_info->pan_exist) { 2044 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20); 2045 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); 2046 } else { 2047 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); 2048 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, 2049 NORMAL_EXEC, false, false); 2050 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); 2051 } 2052 } 2053 2054 static void halbtc8723b1ant_action_wifi_connected(struct btc_coexist *btcoexist) 2055 { 2056 struct rtl_priv *rtlpriv = btcoexist->adapter; 2057 bool wifi_busy = false; 2058 bool scan = false, link = false, roam = false; 2059 bool under_4way = false, ap_enable = false; 2060 2061 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2062 "[BTCoex], CoexForWifiConnect()===>\n"); 2063 2064 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, 2065 &under_4way); 2066 if (under_4way) { 2067 halbtc8723b1ant_action_wifi_connected_special_packet(btcoexist); 2068 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2069 "[BTCoex], CoexForWifiConnect(), return for wifi is under 4way<===\n"); 2070 return; 2071 } 2072 2073 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); 2074 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); 2075 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); 2076 2077 if (scan || link || roam) { 2078 if (scan) 2079 btc8723b1ant_action_wifi_conn_scan(btcoexist); 2080 else 2081 halbtc8723b1ant_action_wifi_connected_special_packet( 2082 btcoexist); 2083 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2084 "[BTCoex], CoexForWifiConnect(), return for wifi is under scan<===\n"); 2085 return; 2086 } 2087 2088 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, 2089 &ap_enable); 2090 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); 2091 /* power save state */ 2092 if (!ap_enable && 2093 coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_BUSY && 2094 !btcoexist->bt_link_info.hid_only) { 2095 if (btcoexist->bt_link_info.a2dp_only) { 2096 if (!wifi_busy) { 2097 halbtc8723b1ant_power_save_state(btcoexist, 2098 BTC_PS_WIFI_NATIVE, 2099 0x0, 0x0); 2100 } else { /* busy */ 2101 if (coex_sta->scan_ap_num >= 2102 BT_8723B_1ANT_WIFI_NOISY_THRESH) 2103 /* no force LPS, no PS-TDMA, 2104 * use pure TDMA 2105 */ 2106 halbtc8723b1ant_power_save_state( 2107 btcoexist, BTC_PS_WIFI_NATIVE, 2108 0x0, 0x0); 2109 else 2110 halbtc8723b1ant_power_save_state( 2111 btcoexist, BTC_PS_LPS_ON, 0x50, 2112 0x4); 2113 } 2114 } else if ((!coex_sta->pan_exist) && (!coex_sta->a2dp_exist) && 2115 (!coex_sta->hid_exist)) 2116 halbtc8723b1ant_power_save_state( 2117 btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); 2118 else 2119 halbtc8723b1ant_power_save_state(btcoexist, 2120 BTC_PS_LPS_ON, 2121 0x50, 0x4); 2122 } else { 2123 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 2124 0x0, 0x0); 2125 } 2126 /* tdma and coex table */ 2127 if (!wifi_busy) { 2128 if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_BUSY) { 2129 halbtc8723b1ant_action_wifi_connected_bt_acl_busy( 2130 btcoexist, 2131 BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE); 2132 } else if (coex_dm->bt_status == 2133 BT_8723B_1ANT_BT_STATUS_SCO_BUSY || 2134 coex_dm->bt_status == 2135 BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY) { 2136 btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist, 2137 BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE); 2138 } else { 2139 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 2140 false, 8); 2141 halbtc8723b1ant_set_ant_path(btcoexist, 2142 BTC_ANT_PATH_PTA, 2143 NORMAL_EXEC, false, false); 2144 halbtc8723b1ant_coex_table_with_type(btcoexist, 2145 NORMAL_EXEC, 2); 2146 } 2147 } else { 2148 if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_BUSY) { 2149 halbtc8723b1ant_action_wifi_connected_bt_acl_busy( 2150 btcoexist, 2151 BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY); 2152 } else if (coex_dm->bt_status == 2153 BT_8723B_1ANT_BT_STATUS_SCO_BUSY || 2154 coex_dm->bt_status == 2155 BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY) { 2156 btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist, 2157 BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY); 2158 } else { 2159 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 2160 true, 32); 2161 halbtc8723b1ant_set_ant_path(btcoexist, 2162 BTC_ANT_PATH_PTA, 2163 NORMAL_EXEC, false, false); 2164 halbtc8723b1ant_coex_table_with_type(btcoexist, 2165 NORMAL_EXEC, 4); 2166 } 2167 } 2168 } 2169 2170 static void halbtc8723b1ant_run_coexist_mechanism(struct btc_coexist *btcoexist) 2171 { 2172 struct rtl_priv *rtlpriv = btcoexist->adapter; 2173 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; 2174 bool wifi_connected = false, bt_hs_on = false, wifi_busy = false; 2175 bool increase_scan_dev_num = false; 2176 bool bt_ctrl_agg_buf_size = false; 2177 bool miracast_plus_bt = false; 2178 u8 agg_buf_size = 5; 2179 u8 iot_peer = BTC_IOT_PEER_UNKNOWN; 2180 u32 wifi_link_status = 0; 2181 u32 num_of_wifi_link = 0; 2182 u32 wifi_bw; 2183 2184 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2185 "[BTCoex], RunCoexistMechanism()===>\n"); 2186 2187 if (btcoexist->manual_control) { 2188 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2189 "[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n"); 2190 return; 2191 } 2192 2193 if (btcoexist->stop_coex_dm) { 2194 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2195 "[BTCoex], RunCoexistMechanism(), return for Stop Coex DM <===\n"); 2196 return; 2197 } 2198 2199 if (coex_sta->under_ips) { 2200 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2201 "[BTCoex], wifi is under IPS !!!\n"); 2202 return; 2203 } 2204 2205 if (coex_sta->bt_whck_test) { 2206 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2207 "[BTCoex], wifi is under IPS !!!\n"); 2208 halbtc8723b1ant_action_bt_whck_test(btcoexist); 2209 return; 2210 } 2211 2212 if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_BUSY || 2213 coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_SCO_BUSY || 2214 coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY) 2215 increase_scan_dev_num = true; 2216 2217 btcoexist->btc_set(btcoexist, BTC_SET_BL_INC_SCAN_DEV_NUM, 2218 &increase_scan_dev_num); 2219 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, 2220 &wifi_connected); 2221 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); 2222 2223 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, 2224 &wifi_link_status); 2225 num_of_wifi_link = wifi_link_status >> 16; 2226 2227 if (num_of_wifi_link >= 2 || 2228 wifi_link_status & WIFI_P2P_GO_CONNECTED) { 2229 if (bt_link_info->bt_link_exist) { 2230 halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 1, 1, 2231 0, 1); 2232 miracast_plus_bt = true; 2233 } else { 2234 halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 2235 0, 0); 2236 miracast_plus_bt = false; 2237 } 2238 btcoexist->btc_set(btcoexist, BTC_SET_BL_MIRACAST_PLUS_BT, 2239 &miracast_plus_bt); 2240 halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false, 2241 bt_ctrl_agg_buf_size, agg_buf_size); 2242 2243 if ((bt_link_info->a2dp_exist || wifi_busy) && 2244 (coex_sta->c2h_bt_inquiry_page)) 2245 halbtc8723b1ant_action_bt_inquiry(btcoexist); 2246 else 2247 halbtc8723b1ant_action_wifi_multiport(btcoexist); 2248 2249 return; 2250 } 2251 2252 miracast_plus_bt = false; 2253 btcoexist->btc_set(btcoexist, BTC_SET_BL_MIRACAST_PLUS_BT, 2254 &miracast_plus_bt); 2255 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); 2256 2257 if (bt_link_info->bt_link_exist && wifi_connected) { 2258 halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 1, 1, 0, 1); 2259 2260 btcoexist->btc_get(btcoexist, BTC_GET_U1_IOT_PEER, &iot_peer); 2261 2262 if (iot_peer != BTC_IOT_PEER_CISCO && 2263 iot_peer != BTC_IOT_PEER_BROADCOM) { 2264 bool sco_exist = bt_link_info->sco_exist; 2265 2266 halbtc8723b1ant_limited_rx(btcoexist, 2267 NORMAL_EXEC, sco_exist, 2268 false, 0x5); 2269 } else { 2270 if (bt_link_info->sco_exist) { 2271 halbtc8723b1ant_limited_rx(btcoexist, 2272 NORMAL_EXEC, true, 2273 false, 0x5); 2274 } else { 2275 if (wifi_bw == BTC_WIFI_BW_HT40) 2276 halbtc8723b1ant_limited_rx( 2277 btcoexist, NORMAL_EXEC, false, 2278 true, 0x10); 2279 else 2280 halbtc8723b1ant_limited_rx( 2281 btcoexist, NORMAL_EXEC, false, 2282 true, 0x8); 2283 } 2284 } 2285 2286 halbtc8723b1ant_sw_mechanism(btcoexist, true); 2287 } else { 2288 halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0); 2289 2290 halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 2291 0x5); 2292 2293 halbtc8723b1ant_sw_mechanism(btcoexist, false); 2294 } 2295 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); 2296 2297 if (coex_sta->c2h_bt_inquiry_page) { 2298 halbtc8723b1ant_action_bt_inquiry(btcoexist); 2299 return; 2300 } else if (bt_hs_on) { 2301 halbtc8723b1ant_action_hs(btcoexist); 2302 return; 2303 } 2304 2305 if (!wifi_connected) { 2306 bool scan = false, link = false, roam = false; 2307 2308 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2309 "[BTCoex], wifi is non connected-idle !!!\n"); 2310 2311 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); 2312 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); 2313 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); 2314 2315 if (scan || link || roam) { 2316 if (scan) 2317 btc8723b1ant_action_wifi_not_conn_scan( 2318 btcoexist); 2319 else 2320 btc8723b1ant_act_wifi_not_conn_asso_auth( 2321 btcoexist); 2322 } else { 2323 btc8723b1ant_action_wifi_not_conn(btcoexist); 2324 } 2325 } else { /* wifi LPS/Busy */ 2326 halbtc8723b1ant_action_wifi_connected(btcoexist); 2327 } 2328 } 2329 2330 /* force coex mechanism to reset */ 2331 static void halbtc8723b1ant_init_coex_dm(struct btc_coexist *btcoexist) 2332 { 2333 /* sw all off */ 2334 halbtc8723b1ant_sw_mechanism(btcoexist, false); 2335 2336 coex_sta->pop_event_cnt = 0; 2337 } 2338 2339 static void halbtc8723b1ant_init_hw_config(struct btc_coexist *btcoexist, 2340 bool backup, bool wifi_only) 2341 { 2342 struct rtl_priv *rtlpriv = btcoexist->adapter; 2343 u32 u32tmp = 0; 2344 u8 u8tmpa = 0, u8tmpb = 0; 2345 2346 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2347 "[BTCoex], 1Ant Init HW Config!!\n"); 2348 2349 /* 0xf0[15:12] --> Chip Cut information */ 2350 coex_sta->cut_version = 2351 (btcoexist->btc_read_1byte(btcoexist, 0xf1) & 0xf0) >> 4; 2352 /* enable TBTT interrupt */ 2353 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x550, 0x8, 0x1); 2354 2355 /* 0x790[5:0] = 0x5 */ 2356 btcoexist->btc_write_1byte(btcoexist, 0x790, 0x5); 2357 2358 /* Enable counter statistics */ 2359 btcoexist->btc_write_1byte(btcoexist, 0x778, 0x1); 2360 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x40, 0x20, 0x1); 2361 2362 halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8); 2363 2364 /* Antenna config */ 2365 if (wifi_only) 2366 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_WIFI, 2367 FORCE_EXEC, true, false); 2368 else 2369 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, 2370 FORCE_EXEC, true, false); 2371 2372 /* PTA parameter */ 2373 halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0); 2374 2375 u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x948); 2376 u8tmpa = btcoexist->btc_read_1byte(btcoexist, 0x765); 2377 u8tmpb = btcoexist->btc_read_1byte(btcoexist, 0x67); 2378 2379 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2380 "############# [BTCoex], 0x948=0x%x, 0x765=0x%x, 0x67=0x%x\n", 2381 u32tmp, u8tmpa, u8tmpb); 2382 } 2383 2384 /************************************************************** 2385 * extern function start with ex_btc8723b1ant_ 2386 **************************************************************/ 2387 void ex_btc8723b1ant_power_on_setting(struct btc_coexist *btcoexist) 2388 { 2389 struct rtl_priv *rtlpriv = btcoexist->adapter; 2390 struct btc_board_info *board_info = &btcoexist->board_info; 2391 u8 u8tmp = 0x0; 2392 u16 u16tmp = 0x0; 2393 u32 value; 2394 2395 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2396 "xxxxxxxxxxxxxxxx Execute 8723b 1-Ant PowerOn Setting xxxxxxxxxxxxxxxx!!\n"); 2397 2398 btcoexist->stop_coex_dm = true; 2399 2400 btcoexist->btc_write_1byte(btcoexist, 0x67, 0x20); 2401 2402 /* enable BB, REG_SYS_FUNC_EN such that we can write 0x948 correctly. */ 2403 u16tmp = btcoexist->btc_read_2byte(btcoexist, 0x2); 2404 btcoexist->btc_write_2byte(btcoexist, 0x2, u16tmp | BIT0 | BIT1); 2405 2406 /* set GRAN_BT = 1 */ 2407 btcoexist->btc_write_1byte(btcoexist, 0x765, 0x18); 2408 /* set WLAN_ACT = 0 */ 2409 btcoexist->btc_write_1byte(btcoexist, 0x76e, 0x4); 2410 2411 /* S0 or S1 setting and Local register setting(By the setting fw can get 2412 * ant number, S0/S1, ... info) 2413 * 2414 * Local setting bit define 2415 * BIT0: "0" for no antenna inverse; "1" for antenna inverse 2416 * BIT1: "0" for internal switch; "1" for external switch 2417 * BIT2: "0" for one antenna; "1" for two antenna 2418 * NOTE: here default all internal switch and 1-antenna ==> BIT1=0 and 2419 * BIT2 = 0 2420 */ 2421 if (btcoexist->chip_interface == BTC_INTF_USB) { 2422 /* fixed at S0 for USB interface */ 2423 btcoexist->btc_write_4byte(btcoexist, 0x948, 0x0); 2424 2425 u8tmp |= 0x1; /* antenna inverse */ 2426 btcoexist->btc_write_local_reg_1byte(btcoexist, 0xfe08, u8tmp); 2427 2428 board_info->btdm_ant_pos = BTC_ANTENNA_AT_AUX_PORT; 2429 } else { 2430 /* for PCIE and SDIO interface, we check efuse 0xc3[6] */ 2431 if (board_info->single_ant_path == 0) { 2432 /* set to S1 */ 2433 btcoexist->btc_write_4byte(btcoexist, 0x948, 0x280); 2434 board_info->btdm_ant_pos = BTC_ANTENNA_AT_MAIN_PORT; 2435 value = 1; 2436 } else if (board_info->single_ant_path == 1) { 2437 /* set to S0 */ 2438 btcoexist->btc_write_4byte(btcoexist, 0x948, 0x0); 2439 u8tmp |= 0x1; /* antenna inverse */ 2440 board_info->btdm_ant_pos = BTC_ANTENNA_AT_AUX_PORT; 2441 value = 0; 2442 } 2443 2444 btcoexist->btc_set(btcoexist, BTC_SET_ACT_ANTPOSREGRISTRY_CTRL, 2445 &value); 2446 2447 if (btcoexist->chip_interface == BTC_INTF_PCI) 2448 btcoexist->btc_write_local_reg_1byte(btcoexist, 0x384, 2449 u8tmp); 2450 else if (btcoexist->chip_interface == BTC_INTF_SDIO) 2451 btcoexist->btc_write_local_reg_1byte(btcoexist, 0x60, 2452 u8tmp); 2453 } 2454 } 2455 2456 2457 void ex_btc8723b1ant_init_hwconfig(struct btc_coexist *btcoexist, 2458 bool wifi_only) 2459 { 2460 halbtc8723b1ant_init_hw_config(btcoexist, true, wifi_only); 2461 btcoexist->stop_coex_dm = false; 2462 } 2463 2464 void ex_btc8723b1ant_init_coex_dm(struct btc_coexist *btcoexist) 2465 { 2466 struct rtl_priv *rtlpriv = btcoexist->adapter; 2467 2468 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2469 "[BTCoex], Coex Mechanism Init!!\n"); 2470 2471 btcoexist->stop_coex_dm = false; 2472 2473 halbtc8723b1ant_init_coex_dm(btcoexist); 2474 2475 halbtc8723b1ant_query_bt_info(btcoexist); 2476 } 2477 2478 void ex_btc8723b1ant_display_coex_info(struct btc_coexist *btcoexist, 2479 struct seq_file *m) 2480 { 2481 struct btc_board_info *board_info = &btcoexist->board_info; 2482 struct btc_stack_info *stack_info = &btcoexist->stack_info; 2483 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; 2484 u8 u8tmp[4], i, bt_info_ext, pstdmacase = 0; 2485 u16 u16tmp[4]; 2486 u32 u32tmp[4]; 2487 bool roam = false, scan = false; 2488 bool link = false, wifi_under_5g = false; 2489 bool bt_hs_on = false, wifi_busy = false; 2490 s32 wifi_rssi = 0, bt_hs_rssi = 0; 2491 u32 wifi_bw, wifi_traffic_dir, fa_ofdm, fa_cck, wifi_link_status; 2492 u8 wifi_dot11_chnl, wifi_hs_chnl; 2493 u32 fw_ver = 0, bt_patch_ver = 0; 2494 2495 seq_puts(m, "\n ============[BT Coexist info]============"); 2496 2497 if (btcoexist->manual_control) { 2498 seq_puts(m, "\n ============[Under Manual Control]=========="); 2499 seq_puts(m, "\n =========================================="); 2500 } 2501 if (btcoexist->stop_coex_dm) { 2502 seq_puts(m, "\n ============[Coex is STOPPED]============"); 2503 seq_puts(m, "\n =========================================="); 2504 } 2505 2506 seq_printf(m, "\n %-35s = %d/ %d/ %d", 2507 "Ant PG Num/ Ant Mech/ Ant Pos:", 2508 board_info->pg_ant_num, board_info->btdm_ant_num, 2509 board_info->btdm_ant_pos); 2510 2511 seq_printf(m, "\n %-35s = %s / %d", 2512 "BT stack/ hci ext ver", 2513 ((stack_info->profile_notified) ? "Yes" : "No"), 2514 stack_info->hci_version); 2515 2516 btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver); 2517 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); 2518 seq_printf(m, "\n %-35s = %d_%x/ 0x%x/ 0x%x(%d)", 2519 "CoexVer/ FwVer/ PatchVer", 2520 glcoex_ver_date_8723b_1ant, glcoex_ver_8723b_1ant, 2521 fw_ver, bt_patch_ver, bt_patch_ver); 2522 2523 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); 2524 btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL, 2525 &wifi_dot11_chnl); 2526 btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl); 2527 seq_printf(m, "\n %-35s = %d / %d(%d)", 2528 "Dot11 channel / HsChnl(HsMode)", 2529 wifi_dot11_chnl, wifi_hs_chnl, bt_hs_on); 2530 2531 seq_printf(m, "\n %-35s = %3ph ", 2532 "H2C Wifi inform bt chnl Info", 2533 coex_dm->wifi_chnl_info); 2534 2535 btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); 2536 btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi); 2537 seq_printf(m, "\n %-35s = %d/ %d", 2538 "Wifi rssi/ HS rssi", wifi_rssi, bt_hs_rssi); 2539 2540 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); 2541 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); 2542 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); 2543 seq_printf(m, "\n %-35s = %d/ %d/ %d ", 2544 "Wifi link/ roam/ scan", link, roam, scan); 2545 2546 btcoexist->btc_get(btcoexist , BTC_GET_BL_WIFI_UNDER_5G, 2547 &wifi_under_5g); 2548 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); 2549 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); 2550 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, 2551 &wifi_traffic_dir); 2552 2553 seq_printf(m, "\n %-35s = %s / %s/ %s ", 2554 "Wifi status", (wifi_under_5g ? "5G" : "2.4G"), 2555 ((wifi_bw == BTC_WIFI_BW_LEGACY) ? "Legacy" : 2556 ((wifi_bw == BTC_WIFI_BW_HT40) ? "HT40" : "HT20")), 2557 ((!wifi_busy) ? "idle" : 2558 ((wifi_traffic_dir == BTC_WIFI_TRAFFIC_TX) ? 2559 "uplink" : "downlink"))); 2560 2561 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, 2562 &wifi_link_status); 2563 seq_printf(m, "\n %-35s = %d/ %d/ %d/ %d/ %d", 2564 "sta/vwifi/hs/p2pGo/p2pGc", 2565 ((wifi_link_status & WIFI_STA_CONNECTED) ? 1 : 0), 2566 ((wifi_link_status & WIFI_AP_CONNECTED) ? 1 : 0), 2567 ((wifi_link_status & WIFI_HS_CONNECTED) ? 1 : 0), 2568 ((wifi_link_status & WIFI_P2P_GO_CONNECTED) ? 1 : 0), 2569 ((wifi_link_status & WIFI_P2P_GC_CONNECTED) ? 1 : 0)); 2570 2571 seq_printf(m, "\n %-35s = [%s/ %d/ %d] ", 2572 "BT [status/ rssi/ retryCnt]", 2573 ((coex_sta->bt_disabled) ? ("disabled") : 2574 ((coex_sta->c2h_bt_inquiry_page) ? ("inquiry/page scan") : 2575 ((BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE == 2576 coex_dm->bt_status) ? 2577 "non-connected idle" : 2578 ((BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE == 2579 coex_dm->bt_status) ? 2580 "connected-idle" : "busy")))), 2581 coex_sta->bt_rssi, coex_sta->bt_retry_cnt); 2582 2583 seq_printf(m, "\n %-35s = %d / %d / %d / %d", 2584 "SCO/HID/PAN/A2DP", bt_link_info->sco_exist, 2585 bt_link_info->hid_exist, bt_link_info->pan_exist, 2586 bt_link_info->a2dp_exist); 2587 btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_LINK_INFO, m); 2588 2589 bt_info_ext = coex_sta->bt_info_ext; 2590 seq_printf(m, "\n %-35s = %s", 2591 "BT Info A2DP rate", 2592 (bt_info_ext & BIT0) ? "Basic rate" : "EDR rate"); 2593 2594 for (i = 0; i < BT_INFO_SRC_8723B_1ANT_MAX; i++) { 2595 if (coex_sta->bt_info_c2h_cnt[i]) { 2596 seq_printf(m, "\n %-35s = %7ph(%d)", 2597 glbt_info_src_8723b_1ant[i], 2598 coex_sta->bt_info_c2h[i], 2599 coex_sta->bt_info_c2h_cnt[i]); 2600 } 2601 } 2602 seq_printf(m, "\n %-35s = %s/%s, (0x%x/0x%x)", 2603 "PS state, IPS/LPS, (lps/rpwm)", 2604 ((coex_sta->under_ips ? "IPS ON" : "IPS OFF")), 2605 ((coex_sta->under_lps ? "LPS ON" : "LPS OFF")), 2606 btcoexist->bt_info.lps_val, 2607 btcoexist->bt_info.rpwm_val); 2608 btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD, m); 2609 2610 if (!btcoexist->manual_control) { 2611 /* Sw mechanism */ 2612 seq_printf(m, "\n %-35s", 2613 "============[Sw mechanism]============"); 2614 2615 seq_printf(m, "\n %-35s = %d/", 2616 "SM[LowPenaltyRA]", coex_dm->cur_low_penalty_ra); 2617 2618 seq_printf(m, "\n %-35s = %s/ %s/ %d ", 2619 "DelBA/ BtCtrlAgg/ AggSize", 2620 (btcoexist->bt_info.reject_agg_pkt ? "Yes" : "No"), 2621 (btcoexist->bt_info.bt_ctrl_buf_size ? "Yes" : "No"), 2622 btcoexist->bt_info.agg_buf_size); 2623 2624 seq_printf(m, "\n %-35s = 0x%x ", 2625 "Rate Mask", btcoexist->bt_info.ra_mask); 2626 2627 /* Fw mechanism */ 2628 seq_printf(m, "\n %-35s", 2629 "============[Fw mechanism]============"); 2630 2631 pstdmacase = coex_dm->cur_ps_tdma; 2632 seq_printf(m, "\n %-35s = %5ph case-%d (auto:%d)", 2633 "PS TDMA", coex_dm->ps_tdma_para, 2634 pstdmacase, coex_dm->auto_tdma_adjust); 2635 2636 seq_printf(m, "\n %-35s = %d ", 2637 "IgnWlanAct", coex_dm->cur_ignore_wlan_act); 2638 2639 seq_printf(m, "\n %-35s = 0x%x ", 2640 "Latest error condition(should be 0)", 2641 coex_dm->error_condition); 2642 } 2643 2644 seq_printf(m, "\n %-35s = %d", 2645 "Coex Table Type", coex_sta->coex_table_type); 2646 2647 /* Hw setting */ 2648 seq_printf(m, "\n %-35s", 2649 "============[Hw setting]============"); 2650 2651 seq_printf(m, "\n %-35s = 0x%x/0x%x/0x%x/0x%x", 2652 "backup ARFR1/ARFR2/RL/AMaxTime", coex_dm->backup_arfr_cnt1, 2653 coex_dm->backup_arfr_cnt2, coex_dm->backup_retry_limit, 2654 coex_dm->backup_ampdu_max_time); 2655 2656 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x430); 2657 u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x434); 2658 u16tmp[0] = btcoexist->btc_read_2byte(btcoexist, 0x42a); 2659 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x456); 2660 seq_printf(m, "\n %-35s = 0x%x/0x%x/0x%x/0x%x", 2661 "0x430/0x434/0x42a/0x456", 2662 u32tmp[0], u32tmp[1], u16tmp[0], u8tmp[0]); 2663 2664 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778); 2665 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6cc); 2666 u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x880); 2667 seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x", 2668 "0x778/0x6cc/0x880[29:25]", u8tmp[0], u32tmp[0], 2669 (u32tmp[1] & 0x3e000000) >> 25); 2670 2671 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x948); 2672 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x67); 2673 u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x765); 2674 seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x", 2675 "0x948/ 0x67[5] / 0x765", 2676 u32tmp[0], ((u8tmp[0] & 0x20) >> 5), u8tmp[1]); 2677 2678 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x92c); 2679 u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x930); 2680 u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x944); 2681 seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x", 2682 "0x92c[1:0]/ 0x930[7:0]/0x944[1:0]", 2683 u32tmp[0] & 0x3, u32tmp[1] & 0xff, u32tmp[2] & 0x3); 2684 2685 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x39); 2686 u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x40); 2687 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c); 2688 u8tmp[2] = btcoexist->btc_read_1byte(btcoexist, 0x64); 2689 seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", 2690 "0x38[11]/0x40/0x4c[24:23]/0x64[0]", 2691 ((u8tmp[0] & 0x8) >> 3), u8tmp[1], 2692 ((u32tmp[0] & 0x01800000) >> 23), u8tmp[2] & 0x1); 2693 2694 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550); 2695 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522); 2696 seq_printf(m, "\n %-35s = 0x%x/ 0x%x", 2697 "0x550(bcn ctrl)/0x522", u32tmp[0], u8tmp[0]); 2698 2699 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50); 2700 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x49c); 2701 seq_printf(m, "\n %-35s = 0x%x/ 0x%x", 2702 "0xc50(dig)/0x49c(null-drop)", u32tmp[0] & 0xff, u8tmp[0]); 2703 2704 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xda0); 2705 u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0xda4); 2706 u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0xda8); 2707 u32tmp[3] = btcoexist->btc_read_4byte(btcoexist, 0xcf0); 2708 2709 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xa5b); 2710 u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0xa5c); 2711 2712 fa_ofdm = ((u32tmp[0] & 0xffff0000) >> 16) + 2713 ((u32tmp[1] & 0xffff0000) >> 16) + 2714 (u32tmp[1] & 0xffff) + 2715 (u32tmp[2] & 0xffff) + 2716 ((u32tmp[3] & 0xffff0000) >> 16) + 2717 (u32tmp[3] & 0xffff); 2718 fa_cck = (u8tmp[0] << 8) + u8tmp[1]; 2719 2720 seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x", 2721 "OFDM-CCA/OFDM-FA/CCK-FA", 2722 u32tmp[0] & 0xffff, fa_ofdm, fa_cck); 2723 2724 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0); 2725 u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4); 2726 u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8); 2727 seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x", 2728 "0x6c0/0x6c4/0x6c8(coexTable)", 2729 u32tmp[0], u32tmp[1], u32tmp[2]); 2730 2731 seq_printf(m, "\n %-35s = %d/ %d", 2732 "0x770(high-pri rx/tx)", coex_sta->high_priority_rx, 2733 coex_sta->high_priority_tx); 2734 seq_printf(m, "\n %-35s = %d/ %d", 2735 "0x774(low-pri rx/tx)", coex_sta->low_priority_rx, 2736 coex_sta->low_priority_tx); 2737 if (btcoexist->auto_report_1ant) 2738 halbtc8723b1ant_monitor_bt_ctr(btcoexist); 2739 btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_COEX_STATISTICS, m); 2740 } 2741 2742 void ex_btc8723b1ant_ips_notify(struct btc_coexist *btcoexist, u8 type) 2743 { 2744 struct rtl_priv *rtlpriv = btcoexist->adapter; 2745 2746 if (btcoexist->manual_control || btcoexist->stop_coex_dm) 2747 return; 2748 2749 if (BTC_IPS_ENTER == type) { 2750 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2751 "[BTCoex], IPS ENTER notify\n"); 2752 coex_sta->under_ips = true; 2753 2754 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, 2755 FORCE_EXEC, false, true); 2756 /* set PTA control */ 2757 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0); 2758 halbtc8723b1ant_coex_table_with_type(btcoexist, 2759 NORMAL_EXEC, 0); 2760 } else if (BTC_IPS_LEAVE == type) { 2761 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2762 "[BTCoex], IPS LEAVE notify\n"); 2763 coex_sta->under_ips = false; 2764 2765 halbtc8723b1ant_init_hw_config(btcoexist, false, false); 2766 halbtc8723b1ant_init_coex_dm(btcoexist); 2767 halbtc8723b1ant_query_bt_info(btcoexist); 2768 } 2769 } 2770 2771 void ex_btc8723b1ant_lps_notify(struct btc_coexist *btcoexist, u8 type) 2772 { 2773 struct rtl_priv *rtlpriv = btcoexist->adapter; 2774 2775 if (btcoexist->manual_control || btcoexist->stop_coex_dm) 2776 return; 2777 2778 if (BTC_LPS_ENABLE == type) { 2779 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2780 "[BTCoex], LPS ENABLE notify\n"); 2781 coex_sta->under_lps = true; 2782 } else if (BTC_LPS_DISABLE == type) { 2783 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2784 "[BTCoex], LPS DISABLE notify\n"); 2785 coex_sta->under_lps = false; 2786 } 2787 } 2788 2789 void ex_btc8723b1ant_scan_notify(struct btc_coexist *btcoexist, u8 type) 2790 { 2791 struct rtl_priv *rtlpriv = btcoexist->adapter; 2792 bool wifi_connected = false, bt_hs_on = false; 2793 u8 u8tmpa, u8tmpb; 2794 u32 u32tmp; 2795 u32 wifi_link_status = 0; 2796 u32 num_of_wifi_link = 0; 2797 bool bt_ctrl_agg_buf_size = false; 2798 u8 agg_buf_size = 5; 2799 2800 if (btcoexist->manual_control || btcoexist->stop_coex_dm) 2801 return; 2802 2803 if (type == BTC_SCAN_START) { 2804 coex_sta->wifi_is_high_pri_task = true; 2805 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2806 "[BTCoex], SCAN START notify\n"); 2807 /* Force antenna setup for no scan result issue */ 2808 halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8); 2809 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, 2810 FORCE_EXEC, false, false); 2811 u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x948); 2812 u8tmpa = btcoexist->btc_read_1byte(btcoexist, 0x765); 2813 u8tmpb = btcoexist->btc_read_1byte(btcoexist, 0x67); 2814 2815 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2816 "[BTCoex], 0x948=0x%x, 0x765=0x%x, 0x67=0x%x\n", 2817 u32tmp, u8tmpa, u8tmpb); 2818 } else { 2819 coex_sta->wifi_is_high_pri_task = false; 2820 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2821 "[BTCoex], SCAN FINISH notify\n"); 2822 2823 btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM, 2824 &coex_sta->scan_ap_num); 2825 } 2826 2827 if (coex_sta->bt_disabled) 2828 return; 2829 2830 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); 2831 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, 2832 &wifi_connected); 2833 2834 halbtc8723b1ant_query_bt_info(btcoexist); 2835 2836 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, 2837 &wifi_link_status); 2838 num_of_wifi_link = wifi_link_status >> 16; 2839 if (num_of_wifi_link >= 2) { 2840 halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0); 2841 halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false, 2842 bt_ctrl_agg_buf_size, agg_buf_size); 2843 halbtc8723b1ant_action_wifi_multiport(btcoexist); 2844 return; 2845 } 2846 2847 if (coex_sta->c2h_bt_inquiry_page) { 2848 halbtc8723b1ant_action_bt_inquiry(btcoexist); 2849 return; 2850 } else if (bt_hs_on) { 2851 halbtc8723b1ant_action_hs(btcoexist); 2852 return; 2853 } 2854 2855 if (BTC_SCAN_START == type) { 2856 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2857 "[BTCoex], SCAN START notify\n"); 2858 if (!wifi_connected) 2859 /* non-connected scan */ 2860 btc8723b1ant_action_wifi_not_conn_scan(btcoexist); 2861 else 2862 /* wifi is connected */ 2863 btc8723b1ant_action_wifi_conn_scan(btcoexist); 2864 } else if (BTC_SCAN_FINISH == type) { 2865 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2866 "[BTCoex], SCAN FINISH notify\n"); 2867 if (!wifi_connected) 2868 /* non-connected scan */ 2869 btc8723b1ant_action_wifi_not_conn(btcoexist); 2870 else 2871 halbtc8723b1ant_action_wifi_connected(btcoexist); 2872 } 2873 } 2874 2875 void ex_btc8723b1ant_connect_notify(struct btc_coexist *btcoexist, u8 type) 2876 { 2877 struct rtl_priv *rtlpriv = btcoexist->adapter; 2878 bool wifi_connected = false, bt_hs_on = false; 2879 u32 wifi_link_status = 0; 2880 u32 num_of_wifi_link = 0; 2881 bool bt_ctrl_agg_buf_size = false, under_4way = false; 2882 u8 agg_buf_size = 5; 2883 2884 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, 2885 &under_4way); 2886 2887 if (btcoexist->manual_control || btcoexist->stop_coex_dm || 2888 coex_sta->bt_disabled) 2889 return; 2890 2891 if (type == BTC_ASSOCIATE_START) { 2892 coex_sta->wifi_is_high_pri_task = true; 2893 2894 /* Force antenna setup for no scan result issue */ 2895 halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8); 2896 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, 2897 FORCE_EXEC, false, false); 2898 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2899 "[BTCoex], CONNECT START notify\n"); 2900 coex_dm->arp_cnt = 0; 2901 } else { 2902 coex_sta->wifi_is_high_pri_task = false; 2903 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2904 "[BTCoex], CONNECT FINISH notify\n"); 2905 } 2906 2907 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, 2908 &wifi_link_status); 2909 num_of_wifi_link = wifi_link_status>>16; 2910 if (num_of_wifi_link >= 2) { 2911 halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0); 2912 halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false, 2913 bt_ctrl_agg_buf_size, agg_buf_size); 2914 halbtc8723b1ant_action_wifi_multiport(btcoexist); 2915 return; 2916 } 2917 2918 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); 2919 if (coex_sta->c2h_bt_inquiry_page) { 2920 halbtc8723b1ant_action_bt_inquiry(btcoexist); 2921 return; 2922 } else if (bt_hs_on) { 2923 halbtc8723b1ant_action_hs(btcoexist); 2924 return; 2925 } 2926 2927 if (BTC_ASSOCIATE_START == type) { 2928 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2929 "[BTCoex], CONNECT START notify\n"); 2930 btc8723b1ant_act_wifi_not_conn_asso_auth(btcoexist); 2931 } else if (BTC_ASSOCIATE_FINISH == type) { 2932 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2933 "[BTCoex], CONNECT FINISH notify\n"); 2934 2935 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, 2936 &wifi_connected); 2937 if (!wifi_connected) 2938 /* non-connected scan */ 2939 btc8723b1ant_action_wifi_not_conn(btcoexist); 2940 else 2941 halbtc8723b1ant_action_wifi_connected(btcoexist); 2942 } 2943 } 2944 2945 void ex_btc8723b1ant_media_status_notify(struct btc_coexist *btcoexist, 2946 u8 type) 2947 { 2948 struct rtl_priv *rtlpriv = btcoexist->adapter; 2949 u8 h2c_parameter[3] = {0}; 2950 u32 wifi_bw; 2951 u8 wifi_central_chnl; 2952 bool wifi_under_b_mode = false; 2953 2954 if (btcoexist->manual_control || btcoexist->stop_coex_dm || 2955 coex_sta->bt_disabled) 2956 return; 2957 2958 if (type == BTC_MEDIA_CONNECT) { 2959 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2960 "[BTCoex], MEDIA connect notify\n"); 2961 /* Force antenna setup for no scan result issue */ 2962 halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8); 2963 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, 2964 FORCE_EXEC, false, false); 2965 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, 2966 &wifi_under_b_mode); 2967 2968 /* Set CCK Tx/Rx high Pri except 11b mode */ 2969 if (wifi_under_b_mode) { 2970 btcoexist->btc_write_1byte(btcoexist, 0x6cd, 2971 0x00); /* CCK Tx */ 2972 btcoexist->btc_write_1byte(btcoexist, 0x6cf, 2973 0x00); /* CCK Rx */ 2974 } else { 2975 btcoexist->btc_write_1byte(btcoexist, 0x6cd, 2976 0x00); /* CCK Tx */ 2977 btcoexist->btc_write_1byte(btcoexist, 0x6cf, 2978 0x10); /* CCK Rx */ 2979 } 2980 2981 coex_dm->backup_arfr_cnt1 = 2982 btcoexist->btc_read_4byte(btcoexist, 0x430); 2983 coex_dm->backup_arfr_cnt2 = 2984 btcoexist->btc_read_4byte(btcoexist, 0x434); 2985 coex_dm->backup_retry_limit = 2986 btcoexist->btc_read_2byte(btcoexist, 0x42a); 2987 coex_dm->backup_ampdu_max_time = 2988 btcoexist->btc_read_1byte(btcoexist, 0x456); 2989 } else { 2990 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2991 "[BTCoex], MEDIA disconnect notify\n"); 2992 coex_dm->arp_cnt = 0; 2993 2994 btcoexist->btc_write_1byte(btcoexist, 0x6cd, 0x0); /* CCK Tx */ 2995 btcoexist->btc_write_1byte(btcoexist, 0x6cf, 0x0); /* CCK Rx */ 2996 2997 coex_sta->cck_ever_lock = false; 2998 } 2999 3000 /* only 2.4G we need to inform bt the chnl mask */ 3001 btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL, 3002 &wifi_central_chnl); 3003 3004 if (type == BTC_MEDIA_CONNECT && wifi_central_chnl <= 14) { 3005 h2c_parameter[0] = 0x0; 3006 h2c_parameter[1] = wifi_central_chnl; 3007 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); 3008 if (BTC_WIFI_BW_HT40 == wifi_bw) 3009 h2c_parameter[2] = 0x30; 3010 else 3011 h2c_parameter[2] = 0x20; 3012 } 3013 3014 coex_dm->wifi_chnl_info[0] = h2c_parameter[0]; 3015 coex_dm->wifi_chnl_info[1] = h2c_parameter[1]; 3016 coex_dm->wifi_chnl_info[2] = h2c_parameter[2]; 3017 3018 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3019 "[BTCoex], FW write 0x66 = 0x%x\n", 3020 h2c_parameter[0] << 16 | h2c_parameter[1] << 8 | 3021 h2c_parameter[2]); 3022 3023 btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter); 3024 } 3025 3026 void ex_btc8723b1ant_special_packet_notify(struct btc_coexist *btcoexist, 3027 u8 type) 3028 { 3029 struct rtl_priv *rtlpriv = btcoexist->adapter; 3030 bool bt_hs_on = false; 3031 u32 wifi_link_status = 0; 3032 u32 num_of_wifi_link = 0; 3033 bool bt_ctrl_agg_buf_size = false, under_4way = false; 3034 u8 agg_buf_size = 5; 3035 3036 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, 3037 &under_4way); 3038 3039 if (btcoexist->manual_control || btcoexist->stop_coex_dm || 3040 coex_sta->bt_disabled) 3041 return; 3042 3043 if (type == BTC_PACKET_DHCP || type == BTC_PACKET_EAPOL || 3044 type == BTC_PACKET_ARP) { 3045 if (type == BTC_PACKET_ARP) { 3046 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3047 "[BTCoex], special Packet ARP notify\n"); 3048 3049 coex_dm->arp_cnt++; 3050 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3051 "[BTCoex], ARP Packet Count = %d\n", 3052 coex_dm->arp_cnt); 3053 3054 if ((coex_dm->arp_cnt >= 10) && (!under_4way)) 3055 /* if APR PKT > 10 after connect, do not go to 3056 * ActionWifiConnectedSpecificPacket(btcoexist) 3057 */ 3058 coex_sta->wifi_is_high_pri_task = false; 3059 else 3060 coex_sta->wifi_is_high_pri_task = true; 3061 } else { 3062 coex_sta->wifi_is_high_pri_task = true; 3063 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3064 "[BTCoex], special Packet DHCP or EAPOL notify\n"); 3065 } 3066 } else { 3067 coex_sta->wifi_is_high_pri_task = false; 3068 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3069 "[BTCoex], special Packet [Type = %d] notify\n", 3070 type); 3071 } 3072 3073 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, 3074 &wifi_link_status); 3075 num_of_wifi_link = wifi_link_status >> 16; 3076 if (num_of_wifi_link >= 2) { 3077 halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0); 3078 halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false, 3079 bt_ctrl_agg_buf_size, agg_buf_size); 3080 halbtc8723b1ant_action_wifi_multiport(btcoexist); 3081 return; 3082 } 3083 3084 coex_sta->special_pkt_period_cnt = 0; 3085 3086 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); 3087 if (coex_sta->c2h_bt_inquiry_page) { 3088 halbtc8723b1ant_action_bt_inquiry(btcoexist); 3089 return; 3090 } else if (bt_hs_on) { 3091 halbtc8723b1ant_action_hs(btcoexist); 3092 return; 3093 } 3094 3095 if (BTC_PACKET_DHCP == type || 3096 BTC_PACKET_EAPOL == type) { 3097 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3098 "[BTCoex], special Packet(%d) notify\n", type); 3099 halbtc8723b1ant_action_wifi_connected_special_packet(btcoexist); 3100 } 3101 } 3102 3103 void ex_btc8723b1ant_bt_info_notify(struct btc_coexist *btcoexist, 3104 u8 *tmp_buf, u8 length) 3105 { 3106 struct rtl_priv *rtlpriv = btcoexist->adapter; 3107 u8 bt_info = 0; 3108 u8 i, rsp_source = 0; 3109 bool wifi_connected = false; 3110 bool bt_busy = false; 3111 3112 coex_sta->c2h_bt_info_req_sent = false; 3113 3114 rsp_source = tmp_buf[0] & 0xf; 3115 if (rsp_source >= BT_INFO_SRC_8723B_1ANT_MAX) 3116 rsp_source = BT_INFO_SRC_8723B_1ANT_WIFI_FW; 3117 coex_sta->bt_info_c2h_cnt[rsp_source]++; 3118 3119 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3120 "[BTCoex], Bt info[%d], length=%d, hex data = [", 3121 rsp_source, length); 3122 for (i = 0; i < length; i++) { 3123 coex_sta->bt_info_c2h[rsp_source][i] = tmp_buf[i]; 3124 if (i == 1) 3125 bt_info = tmp_buf[i]; 3126 if (i == length - 1) 3127 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3128 "0x%02x]\n", tmp_buf[i]); 3129 else 3130 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3131 "0x%02x, ", tmp_buf[i]); 3132 } 3133 3134 /* if 0xff, it means BT is under WHCK test */ 3135 if (bt_info == 0xff) 3136 coex_sta->bt_whck_test = true; 3137 else 3138 coex_sta->bt_whck_test = false; 3139 3140 if (rsp_source != BT_INFO_SRC_8723B_1ANT_WIFI_FW) { 3141 coex_sta->bt_retry_cnt = /* [3:0] */ 3142 coex_sta->bt_info_c2h[rsp_source][2] & 0xf; 3143 3144 if (coex_sta->bt_retry_cnt >= 1) 3145 coex_sta->pop_event_cnt++; 3146 3147 if (coex_sta->bt_info_c2h[rsp_source][2] & 0x20) 3148 coex_sta->c2h_bt_remote_name_req = true; 3149 else 3150 coex_sta->c2h_bt_remote_name_req = false; 3151 3152 coex_sta->bt_rssi = 3153 coex_sta->bt_info_c2h[rsp_source][3] * 2 - 90; 3154 3155 coex_sta->bt_info_ext = 3156 coex_sta->bt_info_c2h[rsp_source][4]; 3157 3158 if (coex_sta->bt_info_c2h[rsp_source][1] == 0x49) { 3159 coex_sta->a2dp_bit_pool = 3160 coex_sta->bt_info_c2h[rsp_source][6]; 3161 } else { 3162 coex_sta->a2dp_bit_pool = 0; 3163 } 3164 3165 coex_sta->bt_tx_rx_mask = 3166 (coex_sta->bt_info_c2h[rsp_source][2] & 0x40); 3167 btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TX_RX_MASK, 3168 &coex_sta->bt_tx_rx_mask); 3169 3170 if (!coex_sta->bt_tx_rx_mask) { 3171 /* BT into is responded by BT FW and BT RF REG 3172 * 0x3C != 0x15 => Need to switch BT TRx Mask 3173 */ 3174 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3175 "[BTCoex], Switch BT TRx Mask since BT RF REG 0x3C != 0x15\n"); 3176 btcoexist->btc_set_bt_reg(btcoexist, BTC_BT_REG_RF, 3177 0x3c, 0x15); 3178 3179 /* BT TRx Mask lock 0x2c[0], 0x30[0] = 0 */ 3180 btcoexist->btc_set_bt_reg(btcoexist, BTC_BT_REG_RF, 3181 0x2c, 0x7c44); 3182 btcoexist->btc_set_bt_reg(btcoexist, BTC_BT_REG_RF, 3183 0x30, 0x7c44); 3184 } 3185 3186 /* Here we need to resend some wifi info to BT 3187 * because bt is reset and loss of the info. 3188 */ 3189 if (coex_sta->bt_info_ext & BIT1) { 3190 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3191 "[BTCoex], BT ext info bit1 check, send wifi BW&Chnl to BT!!\n"); 3192 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, 3193 &wifi_connected); 3194 if (wifi_connected) 3195 ex_btc8723b1ant_media_status_notify(btcoexist, 3196 BTC_MEDIA_CONNECT); 3197 else 3198 ex_btc8723b1ant_media_status_notify(btcoexist, 3199 BTC_MEDIA_DISCONNECT); 3200 } 3201 3202 if (coex_sta->bt_info_ext & BIT3) { 3203 if (!btcoexist->manual_control && 3204 !btcoexist->stop_coex_dm) { 3205 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3206 "[BTCoex], BT ext info bit3 check, set BT NOT ignore Wlan active!!\n"); 3207 halbtc8723b1ant_ignore_wlan_act(btcoexist, 3208 FORCE_EXEC, 3209 false); 3210 } 3211 } else { 3212 /* BT already NOT ignore Wlan active, do nothing here.*/ 3213 } 3214 if (!btcoexist->auto_report_1ant) { 3215 if (coex_sta->bt_info_ext & BIT4) { 3216 /* BT auto report already enabled, do nothing */ 3217 } else { 3218 halbtc8723b1ant_bt_auto_report(btcoexist, 3219 FORCE_EXEC, 3220 true); 3221 } 3222 } 3223 } 3224 3225 /* check BIT2 first ==> check if bt is under inquiry or page scan */ 3226 if (bt_info & BT_INFO_8723B_1ANT_B_INQ_PAGE) 3227 coex_sta->c2h_bt_inquiry_page = true; 3228 else 3229 coex_sta->c2h_bt_inquiry_page = false; 3230 3231 coex_sta->num_of_profile = 0; 3232 3233 /* set link exist status */ 3234 if (!(bt_info & BT_INFO_8723B_1ANT_B_CONNECTION)) { 3235 coex_sta->bt_link_exist = false; 3236 coex_sta->pan_exist = false; 3237 coex_sta->a2dp_exist = false; 3238 coex_sta->hid_exist = false; 3239 coex_sta->sco_exist = false; 3240 3241 coex_sta->bt_hi_pri_link_exist = false; 3242 } else { 3243 /* connection exists */ 3244 coex_sta->bt_link_exist = true; 3245 if (bt_info & BT_INFO_8723B_1ANT_B_FTP) { 3246 coex_sta->pan_exist = true; 3247 coex_sta->num_of_profile++; 3248 } else { 3249 coex_sta->pan_exist = false; 3250 } 3251 if (bt_info & BT_INFO_8723B_1ANT_B_A2DP) { 3252 coex_sta->a2dp_exist = true; 3253 coex_sta->num_of_profile++; 3254 } else { 3255 coex_sta->a2dp_exist = false; 3256 } 3257 if (bt_info & BT_INFO_8723B_1ANT_B_HID) { 3258 coex_sta->hid_exist = true; 3259 coex_sta->num_of_profile++; 3260 } else { 3261 coex_sta->hid_exist = false; 3262 } 3263 if (bt_info & BT_INFO_8723B_1ANT_B_SCO_ESCO) { 3264 coex_sta->sco_exist = true; 3265 coex_sta->num_of_profile++; 3266 } else { 3267 coex_sta->sco_exist = false; 3268 } 3269 3270 if ((!coex_sta->hid_exist) && 3271 (!coex_sta->c2h_bt_inquiry_page) && 3272 (!coex_sta->sco_exist)) { 3273 if (coex_sta->high_priority_tx + 3274 coex_sta->high_priority_rx >= 3275 160) { 3276 coex_sta->hid_exist = true; 3277 coex_sta->wrong_profile_notification++; 3278 coex_sta->num_of_profile++; 3279 bt_info = bt_info | 0x28; 3280 } 3281 } 3282 3283 /* Add Hi-Pri Tx/Rx counter to avoid false detection */ 3284 if (((coex_sta->hid_exist) || (coex_sta->sco_exist)) && 3285 (coex_sta->high_priority_tx + coex_sta->high_priority_rx >= 3286 160) && 3287 (!coex_sta->c2h_bt_inquiry_page)) 3288 coex_sta->bt_hi_pri_link_exist = true; 3289 3290 if ((bt_info & BT_INFO_8723B_1ANT_B_ACL_BUSY) && 3291 (coex_sta->num_of_profile == 0)) { 3292 if (coex_sta->low_priority_tx + 3293 coex_sta->low_priority_rx >= 3294 160) { 3295 coex_sta->pan_exist = true; 3296 coex_sta->num_of_profile++; 3297 coex_sta->wrong_profile_notification++; 3298 bt_info = bt_info | 0x88; 3299 } 3300 } 3301 } 3302 3303 halbtc8723b1ant_update_bt_link_info(btcoexist); 3304 3305 /* mask profile bit for connect-ilde identification 3306 * ( for CSR case: A2DP idle --> 0x41) 3307 */ 3308 bt_info = bt_info & 0x1f; 3309 3310 if (!(bt_info & BT_INFO_8723B_1ANT_B_CONNECTION)) { 3311 coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE; 3312 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3313 "[BTCoex], BtInfoNotify(), BT Non-Connected idle!\n"); 3314 /* connection exists but no busy */ 3315 } else if (bt_info == BT_INFO_8723B_1ANT_B_CONNECTION) { 3316 coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE; 3317 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3318 "[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n"); 3319 } else if ((bt_info & BT_INFO_8723B_1ANT_B_SCO_ESCO) || 3320 (bt_info & BT_INFO_8723B_1ANT_B_SCO_BUSY)) { 3321 coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_SCO_BUSY; 3322 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3323 "[BTCoex], BtInfoNotify(), BT SCO busy!!!\n"); 3324 } else if (bt_info & BT_INFO_8723B_1ANT_B_ACL_BUSY) { 3325 if (BT_8723B_1ANT_BT_STATUS_ACL_BUSY != coex_dm->bt_status) 3326 coex_dm->auto_tdma_adjust = false; 3327 3328 coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_ACL_BUSY; 3329 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3330 "[BTCoex], BtInfoNotify(), BT ACL busy!!!\n"); 3331 } else { 3332 coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_MAX; 3333 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3334 "[BTCoex], BtInfoNotify(), BT Non-Defined state!!\n"); 3335 } 3336 3337 if ((BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) || 3338 (BT_8723B_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) || 3339 (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status)) 3340 bt_busy = true; 3341 else 3342 bt_busy = false; 3343 btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy); 3344 3345 halbtc8723b1ant_run_coexist_mechanism(btcoexist); 3346 } 3347 3348 void ex_btc8723b1ant_rf_status_notify(struct btc_coexist *btcoexist, u8 type) 3349 { 3350 struct rtl_priv *rtlpriv = btcoexist->adapter; 3351 u32 u32tmp; 3352 u8 u8tmpa, u8tmpb, u8tmpc; 3353 3354 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3355 "[BTCoex], RF Status notify\n"); 3356 3357 if (type == BTC_RF_ON) { 3358 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3359 "[BTCoex], RF is turned ON!!\n"); 3360 btcoexist->stop_coex_dm = false; 3361 } else if (type == BTC_RF_OFF) { 3362 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3363 "[BTCoex], RF is turned OFF!!\n"); 3364 3365 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 3366 0x0, 0x0); 3367 halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 0); 3368 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, 3369 FORCE_EXEC, false, true); 3370 3371 halbtc8723b1ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true); 3372 btcoexist->stop_coex_dm = true; 3373 3374 u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x948); 3375 u8tmpa = btcoexist->btc_read_1byte(btcoexist, 0x765); 3376 u8tmpb = btcoexist->btc_read_1byte(btcoexist, 0x67); 3377 u8tmpc = btcoexist->btc_read_1byte(btcoexist, 0x76e); 3378 3379 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3380 "############# [BTCoex], 0x948=0x%x, 0x765=0x%x, 0x67=0x%x, 0x76e=0x%x\n", 3381 u32tmp, u8tmpa, u8tmpb, u8tmpc); 3382 } 3383 } 3384 3385 void ex_btc8723b1ant_halt_notify(struct btc_coexist *btcoexist) 3386 { 3387 struct rtl_priv *rtlpriv = btcoexist->adapter; 3388 3389 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, "[BTCoex], Halt notify\n"); 3390 3391 btcoexist->stop_coex_dm = true; 3392 3393 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, FORCE_EXEC, 3394 false, true); 3395 3396 halbtc8723b1ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true); 3397 3398 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 3399 0x0, 0x0); 3400 halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 0); 3401 3402 ex_btc8723b1ant_media_status_notify(btcoexist, BTC_MEDIA_DISCONNECT); 3403 3404 btcoexist->stop_coex_dm = true; 3405 } 3406 3407 void ex_btc8723b1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state) 3408 { 3409 struct rtl_priv *rtlpriv = btcoexist->adapter; 3410 3411 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, "[BTCoex], Pnp notify\n"); 3412 3413 if (BTC_WIFI_PNP_SLEEP == pnp_state) { 3414 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3415 "[BTCoex], Pnp notify to SLEEP\n"); 3416 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, 3417 FORCE_EXEC, false, true); 3418 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 3419 0x0, 0x0); 3420 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0); 3421 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); 3422 3423 /* Driver do not leave IPS/LPS when driver is going to sleep, so 3424 * BTCoexistence think wifi is still under IPS/LPS 3425 * 3426 * BT should clear UnderIPS/UnderLPS state to avoid mismatch 3427 * state after wakeup. 3428 */ 3429 coex_sta->under_ips = false; 3430 coex_sta->under_lps = false; 3431 btcoexist->stop_coex_dm = true; 3432 } else if (BTC_WIFI_PNP_WAKE_UP == pnp_state) { 3433 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3434 "[BTCoex], Pnp notify to WAKE UP\n"); 3435 btcoexist->stop_coex_dm = false; 3436 halbtc8723b1ant_init_hw_config(btcoexist, false, false); 3437 halbtc8723b1ant_init_coex_dm(btcoexist); 3438 halbtc8723b1ant_query_bt_info(btcoexist); 3439 } 3440 } 3441 3442 void ex_btc8723b1ant_coex_dm_reset(struct btc_coexist *btcoexist) 3443 { 3444 struct rtl_priv *rtlpriv = btcoexist->adapter; 3445 3446 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3447 "[BTCoex], *****************Coex DM Reset****************\n"); 3448 3449 halbtc8723b1ant_init_hw_config(btcoexist, false, false); 3450 halbtc8723b1ant_init_coex_dm(btcoexist); 3451 } 3452 3453 void ex_btc8723b1ant_periodical(struct btc_coexist *btcoexist) 3454 { 3455 struct rtl_priv *rtlpriv = btcoexist->adapter; 3456 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; 3457 3458 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3459 "[BTCoex], ==========================Periodical===========================\n"); 3460 3461 if (!btcoexist->auto_report_1ant) { 3462 halbtc8723b1ant_query_bt_info(btcoexist); 3463 halbtc8723b1ant_monitor_bt_enable_disable(btcoexist); 3464 } else { 3465 halbtc8723b1ant_monitor_bt_ctr(btcoexist); 3466 halbtc8723b1ant_monitor_wifi_ctr(btcoexist); 3467 3468 if ((coex_sta->high_priority_tx + coex_sta->high_priority_rx < 50) && 3469 bt_link_info->hid_exist) 3470 bt_link_info->hid_exist = false; 3471 3472 if (btc8723b1ant_is_wifi_status_changed(btcoexist) || 3473 coex_dm->auto_tdma_adjust) { 3474 halbtc8723b1ant_run_coexist_mechanism(btcoexist); 3475 } 3476 coex_sta->special_pkt_period_cnt++; 3477 } 3478 } 3479