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 == 101)) { 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 void btc8723b1ant_tdma_dur_adj_for_acl(struct btc_coexist *btcoexist, 1440 u8 wifi_status) 1441 { 1442 struct rtl_priv *rtlpriv = btcoexist->adapter; 1443 static s32 up, dn, m, n, wait_count; 1444 /* 0: no change, +1: increase WiFi duration, 1445 * -1: decrease WiFi duration 1446 */ 1447 s32 result; 1448 u8 retry_count = 0, bt_info_ext; 1449 bool wifi_busy = false; 1450 1451 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 1452 "[BTCoex], TdmaDurationAdjustForAcl()\n"); 1453 1454 if (wifi_status == BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY) 1455 wifi_busy = true; 1456 else 1457 wifi_busy = false; 1458 1459 if ((wifi_status == 1460 BT_8723B_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN) || 1461 (wifi_status == BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN) || 1462 (wifi_status == BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT)) { 1463 if (coex_dm->cur_ps_tdma != 1 && coex_dm->cur_ps_tdma != 2 && 1464 coex_dm->cur_ps_tdma != 3 && coex_dm->cur_ps_tdma != 9) { 1465 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1466 true, 9); 1467 coex_dm->ps_tdma_du_adj_type = 9; 1468 1469 up = 0; 1470 dn = 0; 1471 m = 1; 1472 n = 3; 1473 result = 0; 1474 wait_count = 0; 1475 } 1476 return; 1477 } 1478 1479 if (!coex_dm->auto_tdma_adjust) { 1480 coex_dm->auto_tdma_adjust = true; 1481 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 1482 "[BTCoex], first run TdmaDurationAdjust()!!\n"); 1483 1484 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 2); 1485 coex_dm->ps_tdma_du_adj_type = 2; 1486 1487 up = 0; 1488 dn = 0; 1489 m = 1; 1490 n = 3; 1491 result = 0; 1492 wait_count = 0; 1493 } else { 1494 /* acquire the BT TRx retry count from BT_Info byte2 */ 1495 retry_count = coex_sta->bt_retry_cnt; 1496 bt_info_ext = coex_sta->bt_info_ext; 1497 1498 if ((coex_sta->low_priority_tx) > 1050 || 1499 (coex_sta->low_priority_rx) > 1250) 1500 retry_count++; 1501 1502 result = 0; 1503 wait_count++; 1504 /* no retry in the last 2-second duration */ 1505 if (retry_count == 0) { 1506 up++; 1507 dn--; 1508 1509 if (dn <= 0) 1510 dn = 0; 1511 1512 if (up >= n) { 1513 /* if retry count during continuous n*2 seconds 1514 * is 0, enlarge WiFi duration 1515 */ 1516 wait_count = 0; 1517 n = 3; 1518 up = 0; 1519 dn = 0; 1520 result = 1; 1521 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 1522 "[BTCoex], Increase wifi duration!!\n"); 1523 } 1524 } else if (retry_count <= 3) { 1525 /* <=3 retry in the last 2-second duration */ 1526 up--; 1527 dn++; 1528 1529 if (up <= 0) 1530 up = 0; 1531 1532 if (dn == 2) { 1533 /* if continuous 2 retry count(every 2 seconds) 1534 * >0 and < 3, reduce WiFi duration 1535 */ 1536 if (wait_count <= 2) 1537 /* avoid loop between the two levels */ 1538 m++; 1539 else 1540 m = 1; 1541 1542 if (m >= 20) 1543 /* maximum of m = 20 ' will recheck if 1544 * need to adjust wifi duration in 1545 * maximum time interval 120 seconds 1546 */ 1547 m = 20; 1548 1549 n = 3 * m; 1550 up = 0; 1551 dn = 0; 1552 wait_count = 0; 1553 result = -1; 1554 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 1555 "[BTCoex], Decrease wifi duration for retryCounter<3!!\n"); 1556 } 1557 } else { 1558 /* retry count > 3, once retry count > 3, to reduce 1559 * WiFi duration 1560 */ 1561 if (wait_count == 1) 1562 /* to avoid loop between the two levels */ 1563 m++; 1564 else 1565 m = 1; 1566 1567 if (m >= 20) 1568 /* maximum of m = 20 ' will recheck if need to 1569 * adjust wifi duration in maximum time interval 1570 * 120 seconds 1571 */ 1572 m = 20; 1573 1574 n = 3 * m; 1575 up = 0; 1576 dn = 0; 1577 wait_count = 0; 1578 result = -1; 1579 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 1580 "[BTCoex], Decrease wifi duration for retryCounter>3!!\n"); 1581 } 1582 1583 if (result == -1) { 1584 if (coex_dm->cur_ps_tdma == 1) { 1585 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1586 true, 2); 1587 coex_dm->ps_tdma_du_adj_type = 2; 1588 } else if (coex_dm->cur_ps_tdma == 2) { 1589 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1590 true, 9); 1591 coex_dm->ps_tdma_du_adj_type = 9; 1592 } else if (coex_dm->cur_ps_tdma == 9) { 1593 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1594 true, 11); 1595 coex_dm->ps_tdma_du_adj_type = 11; 1596 } 1597 } else if (result == 1) { 1598 if (coex_dm->cur_ps_tdma == 11) { 1599 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1600 true, 9); 1601 coex_dm->ps_tdma_du_adj_type = 9; 1602 } else if (coex_dm->cur_ps_tdma == 9) { 1603 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1604 true, 2); 1605 coex_dm->ps_tdma_du_adj_type = 2; 1606 } else if (coex_dm->cur_ps_tdma == 2) { 1607 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1608 true, 1); 1609 coex_dm->ps_tdma_du_adj_type = 1; 1610 } 1611 } 1612 1613 if (coex_dm->cur_ps_tdma != 1 && coex_dm->cur_ps_tdma != 2 && 1614 coex_dm->cur_ps_tdma != 9 && coex_dm->cur_ps_tdma != 11) { 1615 /* recover to previous adjust type */ 1616 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 1617 coex_dm->ps_tdma_du_adj_type); 1618 } 1619 } 1620 } 1621 1622 static void halbtc8723b1ant_ps_tdma_chk_pwr_save(struct btc_coexist *btcoexist, 1623 bool new_ps_state) 1624 { 1625 u8 lps_mode = 0x0; 1626 1627 btcoexist->btc_get(btcoexist, BTC_GET_U1_LPS_MODE, &lps_mode); 1628 1629 if (lps_mode) { 1630 /* already under LPS state */ 1631 if (new_ps_state) { 1632 /* keep state under LPS, do nothing. */ 1633 } else { 1634 /* will leave LPS state, turn off psTdma first */ 1635 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1636 false, 0); 1637 } 1638 } else { 1639 /* NO PS state */ 1640 if (new_ps_state) { 1641 /* will enter LPS state, turn off psTdma first */ 1642 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1643 false, 0); 1644 } else { 1645 /* keep state under NO PS state, do nothing. */ 1646 } 1647 } 1648 } 1649 1650 static void halbtc8723b1ant_power_save_state(struct btc_coexist *btcoexist, 1651 u8 ps_type, u8 lps_val, 1652 u8 rpwm_val) 1653 { 1654 bool low_pwr_disable = false; 1655 1656 switch (ps_type) { 1657 case BTC_PS_WIFI_NATIVE: 1658 /* recover to original 32k low power setting */ 1659 low_pwr_disable = false; 1660 btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, 1661 &low_pwr_disable); 1662 btcoexist->btc_set(btcoexist, BTC_SET_ACT_NORMAL_LPS, NULL); 1663 coex_sta->force_lps_on = false; 1664 break; 1665 case BTC_PS_LPS_ON: 1666 halbtc8723b1ant_ps_tdma_chk_pwr_save(btcoexist, true); 1667 halbtc8723b1ant_lps_rpwm(btcoexist, NORMAL_EXEC, lps_val, 1668 rpwm_val); 1669 /* when coex force to enter LPS, do not enter 32k low power */ 1670 low_pwr_disable = true; 1671 btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, 1672 &low_pwr_disable); 1673 /* power save must executed before psTdma */ 1674 btcoexist->btc_set(btcoexist, BTC_SET_ACT_ENTER_LPS, NULL); 1675 coex_sta->force_lps_on = true; 1676 break; 1677 case BTC_PS_LPS_OFF: 1678 halbtc8723b1ant_ps_tdma_chk_pwr_save(btcoexist, false); 1679 btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL); 1680 coex_sta->force_lps_on = false; 1681 break; 1682 default: 1683 break; 1684 } 1685 } 1686 1687 static void halbtc8723b1ant_action_wifi_only(struct btc_coexist *btcoexist) 1688 { 1689 halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0); 1690 halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8); 1691 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, 1692 FORCE_EXEC, false, false); 1693 } 1694 1695 /* check if BT is disabled */ 1696 static void halbtc8723b1ant_monitor_bt_enable_disable(struct btc_coexist 1697 *btcoexist) 1698 { 1699 struct rtl_priv *rtlpriv = btcoexist->adapter; 1700 static u32 bt_disable_cnt; 1701 bool bt_active = true, bt_disabled = false; 1702 1703 if (coex_sta->high_priority_tx == 0 && 1704 coex_sta->high_priority_rx == 0 && coex_sta->low_priority_tx == 0 && 1705 coex_sta->low_priority_rx == 0) 1706 bt_active = false; 1707 if (coex_sta->high_priority_tx == 0xffff && 1708 coex_sta->high_priority_rx == 0xffff && 1709 coex_sta->low_priority_tx == 0xffff && 1710 coex_sta->low_priority_rx == 0xffff) 1711 bt_active = false; 1712 if (bt_active) { 1713 bt_disable_cnt = 0; 1714 bt_disabled = false; 1715 } else { 1716 bt_disable_cnt++; 1717 if (bt_disable_cnt >= 2) 1718 bt_disabled = true; 1719 } 1720 if (coex_sta->bt_disabled != bt_disabled) { 1721 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 1722 "[BTCoex], BT is from %s to %s!!\n", 1723 (coex_sta->bt_disabled ? "disabled" : "enabled"), 1724 (bt_disabled ? "disabled" : "enabled")); 1725 1726 coex_sta->bt_disabled = bt_disabled; 1727 btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_DISABLE, 1728 &bt_disabled); 1729 if (bt_disabled) { 1730 halbtc8723b1ant_action_wifi_only(btcoexist); 1731 btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, 1732 NULL); 1733 btcoexist->btc_set(btcoexist, BTC_SET_ACT_NORMAL_LPS, 1734 NULL); 1735 } 1736 } 1737 } 1738 1739 /***************************************************** 1740 * 1741 * Non-Software Coex Mechanism start 1742 * 1743 *****************************************************/ 1744 1745 static void halbtc8723b1ant_action_bt_whck_test(struct btc_coexist *btcoexist) 1746 { 1747 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 1748 0x0); 1749 1750 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); 1751 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, 1752 false, false); 1753 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); 1754 } 1755 1756 static void halbtc8723b1ant_action_wifi_multiport(struct btc_coexist *btcoexist) 1757 { 1758 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 1759 0x0, 0x0); 1760 1761 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); 1762 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, 1763 false, false); 1764 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); 1765 } 1766 1767 static void halbtc8723b1ant_action_hs(struct btc_coexist *btcoexist) 1768 { 1769 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5); 1770 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); 1771 } 1772 1773 static void halbtc8723b1ant_action_bt_inquiry(struct btc_coexist *btcoexist) 1774 { 1775 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; 1776 bool wifi_connected = false, ap_enable = false; 1777 bool wifi_busy = false, bt_busy = false; 1778 1779 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, 1780 &ap_enable); 1781 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, 1782 &wifi_connected); 1783 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); 1784 btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy); 1785 1786 if (coex_sta->bt_abnormal_scan) { 1787 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 33); 1788 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7); 1789 } else if (!wifi_connected && !coex_sta->wifi_is_high_pri_task) { 1790 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 1791 0x0, 0x0); 1792 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); 1793 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, 1794 NORMAL_EXEC, false, false); 1795 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); 1796 } else if (bt_link_info->sco_exist || bt_link_info->hid_exist || 1797 bt_link_info->a2dp_exist) { 1798 /* SCO/HID/A2DP busy */ 1799 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 1800 0x0, 0x0); 1801 if (coex_sta->c2h_bt_remote_name_req) 1802 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 1803 33); 1804 else 1805 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 1806 32); 1807 1808 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); 1809 } else if (bt_link_info->pan_exist || wifi_busy) { 1810 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 1811 0x0, 0x0); 1812 if (coex_sta->c2h_bt_remote_name_req) 1813 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 1814 33); 1815 else 1816 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 1817 32); 1818 1819 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); 1820 } else { 1821 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 1822 0x0, 0x0); 1823 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); 1824 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, 1825 NORMAL_EXEC, false, false); 1826 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7); 1827 } 1828 } 1829 1830 static void btc8723b1ant_act_bt_sco_hid_only_busy(struct btc_coexist *btcoexist, 1831 u8 wifi_status) 1832 { 1833 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; 1834 bool wifi_connected = false; 1835 1836 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, 1837 &wifi_connected); 1838 1839 /* tdma and coex table */ 1840 if (bt_link_info->sco_exist) { 1841 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5); 1842 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 5); 1843 } else { 1844 /* HID */ 1845 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 6); 1846 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 5); 1847 } 1848 } 1849 1850 static void halbtc8723b1ant_action_wifi_connected_bt_acl_busy( 1851 struct btc_coexist *btcoexist, 1852 u8 wifi_status) 1853 { 1854 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; 1855 1856 if ((coex_sta->low_priority_rx >= 950) && (!coex_sta->under_ips)) 1857 bt_link_info->slave_role = true; 1858 else 1859 bt_link_info->slave_role = false; 1860 1861 if (bt_link_info->hid_only) { /* HID */ 1862 btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist, wifi_status); 1863 coex_dm->auto_tdma_adjust = false; 1864 return; 1865 } else if (bt_link_info->a2dp_only) { /* A2DP */ 1866 if (wifi_status == BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE) { 1867 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1868 true, 32); 1869 halbtc8723b1ant_coex_table_with_type(btcoexist, 1870 NORMAL_EXEC, 4); 1871 coex_dm->auto_tdma_adjust = false; 1872 } else { 1873 btc8723b1ant_tdma_dur_adj_for_acl(btcoexist, 1874 wifi_status); 1875 halbtc8723b1ant_coex_table_with_type(btcoexist, 1876 NORMAL_EXEC, 1); 1877 coex_dm->auto_tdma_adjust = true; 1878 } 1879 } else if (((bt_link_info->a2dp_exist) && (bt_link_info->pan_exist)) || 1880 (bt_link_info->hid_exist && bt_link_info->a2dp_exist && 1881 bt_link_info->pan_exist)) { 1882 /* A2DP + PAN(OPP,FTP), HID + A2DP + PAN(OPP,FTP) */ 1883 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 13); 1884 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); 1885 coex_dm->auto_tdma_adjust = false; 1886 } else if (bt_link_info->hid_exist && bt_link_info->a2dp_exist) { 1887 /* HID + A2DP */ 1888 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14); 1889 coex_dm->auto_tdma_adjust = false; 1890 1891 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); 1892 } else if (bt_link_info->pan_only || 1893 (bt_link_info->hid_exist && bt_link_info->pan_exist)) { 1894 /* PAN(OPP,FTP), HID + PAN(OPP,FTP) */ 1895 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); 1896 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); 1897 coex_dm->auto_tdma_adjust = false; 1898 } else { 1899 /* BT no-profile busy (0x9) */ 1900 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 33); 1901 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); 1902 coex_dm->auto_tdma_adjust = false; 1903 } 1904 } 1905 1906 static void btc8723b1ant_action_wifi_not_conn(struct btc_coexist *btcoexist) 1907 { 1908 /* power save state */ 1909 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 1910 0x0, 0x0); 1911 1912 /* tdma and coex table */ 1913 halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8); 1914 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC, 1915 false, false); 1916 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); 1917 } 1918 1919 static void 1920 btc8723b1ant_action_wifi_not_conn_scan(struct btc_coexist *btcoexist) 1921 { 1922 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; 1923 1924 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 1925 0x0, 0x0); 1926 1927 /* tdma and coex table */ 1928 if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_BUSY) { 1929 if (bt_link_info->a2dp_exist) { 1930 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1931 true, 32); 1932 halbtc8723b1ant_coex_table_with_type(btcoexist, 1933 NORMAL_EXEC, 4); 1934 } else if (bt_link_info->a2dp_exist) { 1935 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1936 true, 22); 1937 halbtc8723b1ant_coex_table_with_type(btcoexist, 1938 NORMAL_EXEC, 4); 1939 } else { 1940 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1941 true, 20); 1942 halbtc8723b1ant_coex_table_with_type(btcoexist, 1943 NORMAL_EXEC, 1); 1944 } 1945 } else if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_SCO_BUSY || 1946 coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY){ 1947 btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist, 1948 BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN); 1949 } else { 1950 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); 1951 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, 1952 NORMAL_EXEC, false, false); 1953 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); 1954 } 1955 } 1956 1957 static void 1958 btc8723b1ant_act_wifi_not_conn_asso_auth(struct btc_coexist *btcoexist) 1959 { 1960 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; 1961 1962 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 1963 0x0, 0x0); 1964 1965 /* tdma and coex table */ 1966 if ((bt_link_info->sco_exist) || (bt_link_info->hid_exist) || 1967 (bt_link_info->a2dp_exist)) { 1968 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32); 1969 halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 4); 1970 } else if (bt_link_info->pan_exist) { 1971 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20); 1972 halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 4); 1973 } else { 1974 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); 1975 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, 1976 NORMAL_EXEC, false, false); 1977 halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 2); 1978 } 1979 } 1980 1981 static void btc8723b1ant_action_wifi_conn_scan(struct btc_coexist *btcoexist) 1982 { 1983 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; 1984 1985 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 1986 0x0, 0x0); 1987 1988 /* tdma and coex table */ 1989 if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_BUSY) { 1990 if (bt_link_info->a2dp_exist) { 1991 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1992 true, 32); 1993 halbtc8723b1ant_coex_table_with_type(btcoexist, 1994 NORMAL_EXEC, 4); 1995 } else if (bt_link_info->a2dp_exist && 1996 bt_link_info->pan_exist) { 1997 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 1998 true, 22); 1999 halbtc8723b1ant_coex_table_with_type(btcoexist, 2000 NORMAL_EXEC, 4); 2001 } else { 2002 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 2003 true, 20); 2004 halbtc8723b1ant_coex_table_with_type(btcoexist, 2005 NORMAL_EXEC, 4); 2006 } 2007 } else if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_SCO_BUSY || 2008 coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY) { 2009 btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist, 2010 BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN); 2011 } else { 2012 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); 2013 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, 2014 NORMAL_EXEC, false, false); 2015 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); 2016 } 2017 } 2018 2019 static void halbtc8723b1ant_action_wifi_connected_special_packet( 2020 struct btc_coexist *btcoexist) 2021 { 2022 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; 2023 bool wifi_busy = false; 2024 2025 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); 2026 2027 /* no special packet process for both WiFi and BT very busy */ 2028 if ((wifi_busy) && 2029 ((bt_link_info->pan_exist) || (coex_sta->num_of_profile >= 2))) 2030 return; 2031 2032 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 2033 0x0, 0x0); 2034 2035 /* tdma and coex table */ 2036 if ((bt_link_info->sco_exist) || (bt_link_info->hid_exist)) { 2037 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32); 2038 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 5); 2039 } else if (bt_link_info->a2dp_exist) { 2040 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32); 2041 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); 2042 } else if (bt_link_info->pan_exist) { 2043 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20); 2044 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4); 2045 } else { 2046 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); 2047 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, 2048 NORMAL_EXEC, false, false); 2049 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); 2050 } 2051 } 2052 2053 static void halbtc8723b1ant_action_wifi_connected(struct btc_coexist *btcoexist) 2054 { 2055 struct rtl_priv *rtlpriv = btcoexist->adapter; 2056 bool wifi_busy = false; 2057 bool scan = false, link = false, roam = false; 2058 bool under_4way = false, ap_enable = false; 2059 2060 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2061 "[BTCoex], CoexForWifiConnect()===>\n"); 2062 2063 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, 2064 &under_4way); 2065 if (under_4way) { 2066 halbtc8723b1ant_action_wifi_connected_special_packet(btcoexist); 2067 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2068 "[BTCoex], CoexForWifiConnect(), return for wifi is under 4way<===\n"); 2069 return; 2070 } 2071 2072 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); 2073 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); 2074 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); 2075 2076 if (scan || link || roam) { 2077 if (scan) 2078 btc8723b1ant_action_wifi_conn_scan(btcoexist); 2079 else 2080 halbtc8723b1ant_action_wifi_connected_special_packet( 2081 btcoexist); 2082 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2083 "[BTCoex], CoexForWifiConnect(), return for wifi is under scan<===\n"); 2084 return; 2085 } 2086 2087 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, 2088 &ap_enable); 2089 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); 2090 /* power save state */ 2091 if (!ap_enable && 2092 coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_BUSY && 2093 !btcoexist->bt_link_info.hid_only) { 2094 if (btcoexist->bt_link_info.a2dp_only) { 2095 if (!wifi_busy) { 2096 halbtc8723b1ant_power_save_state(btcoexist, 2097 BTC_PS_WIFI_NATIVE, 2098 0x0, 0x0); 2099 } else { /* busy */ 2100 if (coex_sta->scan_ap_num >= 2101 BT_8723B_1ANT_WIFI_NOISY_THRESH) 2102 /* no force LPS, no PS-TDMA, 2103 * use pure TDMA 2104 */ 2105 halbtc8723b1ant_power_save_state( 2106 btcoexist, BTC_PS_WIFI_NATIVE, 2107 0x0, 0x0); 2108 else 2109 halbtc8723b1ant_power_save_state( 2110 btcoexist, BTC_PS_LPS_ON, 0x50, 2111 0x4); 2112 } 2113 } else if ((!coex_sta->pan_exist) && (!coex_sta->a2dp_exist) && 2114 (!coex_sta->hid_exist)) 2115 halbtc8723b1ant_power_save_state( 2116 btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0); 2117 else 2118 halbtc8723b1ant_power_save_state(btcoexist, 2119 BTC_PS_LPS_ON, 2120 0x50, 0x4); 2121 } else { 2122 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 2123 0x0, 0x0); 2124 } 2125 /* tdma and coex table */ 2126 if (!wifi_busy) { 2127 if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_BUSY) { 2128 halbtc8723b1ant_action_wifi_connected_bt_acl_busy( 2129 btcoexist, 2130 BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE); 2131 } else if (coex_dm->bt_status == 2132 BT_8723B_1ANT_BT_STATUS_SCO_BUSY || 2133 coex_dm->bt_status == 2134 BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY) { 2135 btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist, 2136 BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE); 2137 } else { 2138 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 2139 false, 8); 2140 halbtc8723b1ant_set_ant_path(btcoexist, 2141 BTC_ANT_PATH_PTA, 2142 NORMAL_EXEC, false, false); 2143 halbtc8723b1ant_coex_table_with_type(btcoexist, 2144 NORMAL_EXEC, 2); 2145 } 2146 } else { 2147 if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_BUSY) { 2148 halbtc8723b1ant_action_wifi_connected_bt_acl_busy( 2149 btcoexist, 2150 BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY); 2151 } else if (coex_dm->bt_status == 2152 BT_8723B_1ANT_BT_STATUS_SCO_BUSY || 2153 coex_dm->bt_status == 2154 BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY) { 2155 btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist, 2156 BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY); 2157 } else { 2158 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, 2159 true, 32); 2160 halbtc8723b1ant_set_ant_path(btcoexist, 2161 BTC_ANT_PATH_PTA, 2162 NORMAL_EXEC, false, false); 2163 halbtc8723b1ant_coex_table_with_type(btcoexist, 2164 NORMAL_EXEC, 4); 2165 } 2166 } 2167 } 2168 2169 static void halbtc8723b1ant_run_coexist_mechanism(struct btc_coexist *btcoexist) 2170 { 2171 struct rtl_priv *rtlpriv = btcoexist->adapter; 2172 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; 2173 bool wifi_connected = false, bt_hs_on = false, wifi_busy = false; 2174 bool increase_scan_dev_num = false; 2175 bool bt_ctrl_agg_buf_size = false; 2176 bool miracast_plus_bt = false; 2177 u8 agg_buf_size = 5; 2178 u8 iot_peer = BTC_IOT_PEER_UNKNOWN; 2179 u32 wifi_link_status = 0; 2180 u32 num_of_wifi_link = 0; 2181 u32 wifi_bw; 2182 2183 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2184 "[BTCoex], RunCoexistMechanism()===>\n"); 2185 2186 if (btcoexist->manual_control) { 2187 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2188 "[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n"); 2189 return; 2190 } 2191 2192 if (btcoexist->stop_coex_dm) { 2193 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2194 "[BTCoex], RunCoexistMechanism(), return for Stop Coex DM <===\n"); 2195 return; 2196 } 2197 2198 if (coex_sta->under_ips) { 2199 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2200 "[BTCoex], wifi is under IPS !!!\n"); 2201 return; 2202 } 2203 2204 if (coex_sta->bt_whck_test) { 2205 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2206 "[BTCoex], wifi is under IPS !!!\n"); 2207 halbtc8723b1ant_action_bt_whck_test(btcoexist); 2208 return; 2209 } 2210 2211 if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_BUSY || 2212 coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_SCO_BUSY || 2213 coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY) 2214 increase_scan_dev_num = true; 2215 2216 btcoexist->btc_set(btcoexist, BTC_SET_BL_INC_SCAN_DEV_NUM, 2217 &increase_scan_dev_num); 2218 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, 2219 &wifi_connected); 2220 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); 2221 2222 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, 2223 &wifi_link_status); 2224 num_of_wifi_link = wifi_link_status >> 16; 2225 2226 if (num_of_wifi_link >= 2 || 2227 wifi_link_status & WIFI_P2P_GO_CONNECTED) { 2228 if (bt_link_info->bt_link_exist) { 2229 halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 1, 1, 2230 0, 1); 2231 miracast_plus_bt = true; 2232 } else { 2233 halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 2234 0, 0); 2235 miracast_plus_bt = false; 2236 } 2237 btcoexist->btc_set(btcoexist, BTC_SET_BL_MIRACAST_PLUS_BT, 2238 &miracast_plus_bt); 2239 halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false, 2240 bt_ctrl_agg_buf_size, agg_buf_size); 2241 2242 if ((bt_link_info->a2dp_exist || wifi_busy) && 2243 (coex_sta->c2h_bt_inquiry_page)) 2244 halbtc8723b1ant_action_bt_inquiry(btcoexist); 2245 else 2246 halbtc8723b1ant_action_wifi_multiport(btcoexist); 2247 2248 return; 2249 } 2250 2251 miracast_plus_bt = false; 2252 btcoexist->btc_set(btcoexist, BTC_SET_BL_MIRACAST_PLUS_BT, 2253 &miracast_plus_bt); 2254 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); 2255 2256 if (bt_link_info->bt_link_exist && wifi_connected) { 2257 halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 1, 1, 0, 1); 2258 2259 btcoexist->btc_get(btcoexist, BTC_GET_U1_IOT_PEER, &iot_peer); 2260 2261 if (iot_peer != BTC_IOT_PEER_CISCO && 2262 iot_peer != BTC_IOT_PEER_BROADCOM) { 2263 bool sco_exist = bt_link_info->sco_exist; 2264 2265 halbtc8723b1ant_limited_rx(btcoexist, 2266 NORMAL_EXEC, sco_exist, 2267 false, 0x5); 2268 } else { 2269 if (bt_link_info->sco_exist) { 2270 halbtc8723b1ant_limited_rx(btcoexist, 2271 NORMAL_EXEC, true, 2272 false, 0x5); 2273 } else { 2274 if (wifi_bw == BTC_WIFI_BW_HT40) 2275 halbtc8723b1ant_limited_rx( 2276 btcoexist, NORMAL_EXEC, false, 2277 true, 0x10); 2278 else 2279 halbtc8723b1ant_limited_rx( 2280 btcoexist, NORMAL_EXEC, false, 2281 true, 0x8); 2282 } 2283 } 2284 2285 halbtc8723b1ant_sw_mechanism(btcoexist, true); 2286 } else { 2287 halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0); 2288 2289 halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 2290 0x5); 2291 2292 halbtc8723b1ant_sw_mechanism(btcoexist, false); 2293 } 2294 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); 2295 2296 if (coex_sta->c2h_bt_inquiry_page) { 2297 halbtc8723b1ant_action_bt_inquiry(btcoexist); 2298 return; 2299 } else if (bt_hs_on) { 2300 halbtc8723b1ant_action_hs(btcoexist); 2301 return; 2302 } 2303 2304 if (!wifi_connected) { 2305 bool scan = false, link = false, roam = false; 2306 2307 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2308 "[BTCoex], wifi is non connected-idle !!!\n"); 2309 2310 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); 2311 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); 2312 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); 2313 2314 if (scan || link || roam) { 2315 if (scan) 2316 btc8723b1ant_action_wifi_not_conn_scan( 2317 btcoexist); 2318 else 2319 btc8723b1ant_act_wifi_not_conn_asso_auth( 2320 btcoexist); 2321 } else { 2322 btc8723b1ant_action_wifi_not_conn(btcoexist); 2323 } 2324 } else { /* wifi LPS/Busy */ 2325 halbtc8723b1ant_action_wifi_connected(btcoexist); 2326 } 2327 } 2328 2329 /* force coex mechanism to reset */ 2330 static void halbtc8723b1ant_init_coex_dm(struct btc_coexist *btcoexist) 2331 { 2332 /* sw all off */ 2333 halbtc8723b1ant_sw_mechanism(btcoexist, false); 2334 2335 coex_sta->pop_event_cnt = 0; 2336 } 2337 2338 static void halbtc8723b1ant_init_hw_config(struct btc_coexist *btcoexist, 2339 bool backup, bool wifi_only) 2340 { 2341 struct rtl_priv *rtlpriv = btcoexist->adapter; 2342 u32 u32tmp = 0; 2343 u8 u8tmpa = 0, u8tmpb = 0; 2344 2345 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2346 "[BTCoex], 1Ant Init HW Config!!\n"); 2347 2348 /* 0xf0[15:12] --> Chip Cut information */ 2349 coex_sta->cut_version = 2350 (btcoexist->btc_read_1byte(btcoexist, 0xf1) & 0xf0) >> 4; 2351 /* enable TBTT interrupt */ 2352 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x550, 0x8, 0x1); 2353 2354 /* 0x790[5:0] = 0x5 */ 2355 btcoexist->btc_write_1byte(btcoexist, 0x790, 0x5); 2356 2357 /* Enable counter statistics */ 2358 btcoexist->btc_write_1byte(btcoexist, 0x778, 0x1); 2359 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x40, 0x20, 0x1); 2360 2361 halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8); 2362 2363 /* Antenna config */ 2364 if (wifi_only) 2365 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_WIFI, 2366 FORCE_EXEC, true, false); 2367 else 2368 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, 2369 FORCE_EXEC, true, false); 2370 2371 /* PTA parameter */ 2372 halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0); 2373 2374 u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x948); 2375 u8tmpa = btcoexist->btc_read_1byte(btcoexist, 0x765); 2376 u8tmpb = btcoexist->btc_read_1byte(btcoexist, 0x67); 2377 2378 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2379 "############# [BTCoex], 0x948=0x%x, 0x765=0x%x, 0x67=0x%x\n", 2380 u32tmp, u8tmpa, u8tmpb); 2381 } 2382 2383 /************************************************************** 2384 * extern function start with ex_btc8723b1ant_ 2385 **************************************************************/ 2386 void ex_btc8723b1ant_power_on_setting(struct btc_coexist *btcoexist) 2387 { 2388 struct rtl_priv *rtlpriv = btcoexist->adapter; 2389 struct btc_board_info *board_info = &btcoexist->board_info; 2390 u8 u8tmp = 0x0; 2391 u16 u16tmp = 0x0; 2392 u32 value; 2393 2394 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2395 "xxxxxxxxxxxxxxxx Execute 8723b 1-Ant PowerOn Setting xxxxxxxxxxxxxxxx!!\n"); 2396 2397 btcoexist->stop_coex_dm = true; 2398 2399 btcoexist->btc_write_1byte(btcoexist, 0x67, 0x20); 2400 2401 /* enable BB, REG_SYS_FUNC_EN such that we can write 0x948 correctly. */ 2402 u16tmp = btcoexist->btc_read_2byte(btcoexist, 0x2); 2403 btcoexist->btc_write_2byte(btcoexist, 0x2, u16tmp | BIT0 | BIT1); 2404 2405 /* set GRAN_BT = 1 */ 2406 btcoexist->btc_write_1byte(btcoexist, 0x765, 0x18); 2407 /* set WLAN_ACT = 0 */ 2408 btcoexist->btc_write_1byte(btcoexist, 0x76e, 0x4); 2409 2410 /* S0 or S1 setting and Local register setting(By the setting fw can get 2411 * ant number, S0/S1, ... info) 2412 * 2413 * Local setting bit define 2414 * BIT0: "0" for no antenna inverse; "1" for antenna inverse 2415 * BIT1: "0" for internal switch; "1" for external switch 2416 * BIT2: "0" for one antenna; "1" for two antenna 2417 * NOTE: here default all internal switch and 1-antenna ==> BIT1=0 and 2418 * BIT2 = 0 2419 */ 2420 if (btcoexist->chip_interface == BTC_INTF_USB) { 2421 /* fixed at S0 for USB interface */ 2422 btcoexist->btc_write_4byte(btcoexist, 0x948, 0x0); 2423 2424 u8tmp |= 0x1; /* antenna inverse */ 2425 btcoexist->btc_write_local_reg_1byte(btcoexist, 0xfe08, u8tmp); 2426 2427 board_info->btdm_ant_pos = BTC_ANTENNA_AT_AUX_PORT; 2428 } else { 2429 /* for PCIE and SDIO interface, we check efuse 0xc3[6] */ 2430 if (board_info->single_ant_path == 0) { 2431 /* set to S1 */ 2432 btcoexist->btc_write_4byte(btcoexist, 0x948, 0x280); 2433 board_info->btdm_ant_pos = BTC_ANTENNA_AT_MAIN_PORT; 2434 value = 1; 2435 } else if (board_info->single_ant_path == 1) { 2436 /* set to S0 */ 2437 btcoexist->btc_write_4byte(btcoexist, 0x948, 0x0); 2438 u8tmp |= 0x1; /* antenna inverse */ 2439 board_info->btdm_ant_pos = BTC_ANTENNA_AT_AUX_PORT; 2440 value = 0; 2441 } 2442 2443 btcoexist->btc_set(btcoexist, BTC_SET_ACT_ANTPOSREGRISTRY_CTRL, 2444 &value); 2445 2446 if (btcoexist->chip_interface == BTC_INTF_PCI) 2447 btcoexist->btc_write_local_reg_1byte(btcoexist, 0x384, 2448 u8tmp); 2449 else if (btcoexist->chip_interface == BTC_INTF_SDIO) 2450 btcoexist->btc_write_local_reg_1byte(btcoexist, 0x60, 2451 u8tmp); 2452 } 2453 } 2454 2455 2456 void ex_btc8723b1ant_init_hwconfig(struct btc_coexist *btcoexist, 2457 bool wifi_only) 2458 { 2459 halbtc8723b1ant_init_hw_config(btcoexist, true, wifi_only); 2460 btcoexist->stop_coex_dm = false; 2461 } 2462 2463 void ex_btc8723b1ant_init_coex_dm(struct btc_coexist *btcoexist) 2464 { 2465 struct rtl_priv *rtlpriv = btcoexist->adapter; 2466 2467 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2468 "[BTCoex], Coex Mechanism Init!!\n"); 2469 2470 btcoexist->stop_coex_dm = false; 2471 2472 halbtc8723b1ant_init_coex_dm(btcoexist); 2473 2474 halbtc8723b1ant_query_bt_info(btcoexist); 2475 } 2476 2477 void ex_btc8723b1ant_display_coex_info(struct btc_coexist *btcoexist, 2478 struct seq_file *m) 2479 { 2480 struct btc_board_info *board_info = &btcoexist->board_info; 2481 struct btc_stack_info *stack_info = &btcoexist->stack_info; 2482 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; 2483 u8 u8tmp[4], i, bt_info_ext, pstdmacase = 0; 2484 u16 u16tmp[4]; 2485 u32 u32tmp[4]; 2486 bool roam = false, scan = false; 2487 bool link = false, wifi_under_5g = false; 2488 bool bt_hs_on = false, wifi_busy = false; 2489 s32 wifi_rssi = 0, bt_hs_rssi = 0; 2490 u32 wifi_bw, wifi_traffic_dir, fa_ofdm, fa_cck, wifi_link_status; 2491 u8 wifi_dot11_chnl, wifi_hs_chnl; 2492 u32 fw_ver = 0, bt_patch_ver = 0; 2493 2494 seq_puts(m, "\n ============[BT Coexist info]============"); 2495 2496 if (btcoexist->manual_control) { 2497 seq_puts(m, "\n ============[Under Manual Control]=========="); 2498 seq_puts(m, "\n =========================================="); 2499 } 2500 if (btcoexist->stop_coex_dm) { 2501 seq_puts(m, "\n ============[Coex is STOPPED]============"); 2502 seq_puts(m, "\n =========================================="); 2503 } 2504 2505 seq_printf(m, "\n %-35s = %d/ %d/ %d", 2506 "Ant PG Num/ Ant Mech/ Ant Pos:", 2507 board_info->pg_ant_num, board_info->btdm_ant_num, 2508 board_info->btdm_ant_pos); 2509 2510 seq_printf(m, "\n %-35s = %s / %d", 2511 "BT stack/ hci ext ver", 2512 ((stack_info->profile_notified) ? "Yes" : "No"), 2513 stack_info->hci_version); 2514 2515 btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver); 2516 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); 2517 seq_printf(m, "\n %-35s = %d_%x/ 0x%x/ 0x%x(%d)", 2518 "CoexVer/ FwVer/ PatchVer", 2519 glcoex_ver_date_8723b_1ant, glcoex_ver_8723b_1ant, 2520 fw_ver, bt_patch_ver, bt_patch_ver); 2521 2522 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); 2523 btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL, 2524 &wifi_dot11_chnl); 2525 btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl); 2526 seq_printf(m, "\n %-35s = %d / %d(%d)", 2527 "Dot11 channel / HsChnl(HsMode)", 2528 wifi_dot11_chnl, wifi_hs_chnl, bt_hs_on); 2529 2530 seq_printf(m, "\n %-35s = %3ph ", 2531 "H2C Wifi inform bt chnl Info", 2532 coex_dm->wifi_chnl_info); 2533 2534 btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); 2535 btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi); 2536 seq_printf(m, "\n %-35s = %d/ %d", 2537 "Wifi rssi/ HS rssi", wifi_rssi, bt_hs_rssi); 2538 2539 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); 2540 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); 2541 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); 2542 seq_printf(m, "\n %-35s = %d/ %d/ %d ", 2543 "Wifi link/ roam/ scan", link, roam, scan); 2544 2545 btcoexist->btc_get(btcoexist , BTC_GET_BL_WIFI_UNDER_5G, 2546 &wifi_under_5g); 2547 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); 2548 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); 2549 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, 2550 &wifi_traffic_dir); 2551 2552 seq_printf(m, "\n %-35s = %s / %s/ %s ", 2553 "Wifi status", (wifi_under_5g ? "5G" : "2.4G"), 2554 ((wifi_bw == BTC_WIFI_BW_LEGACY) ? "Legacy" : 2555 ((wifi_bw == BTC_WIFI_BW_HT40) ? "HT40" : "HT20")), 2556 ((!wifi_busy) ? "idle" : 2557 ((wifi_traffic_dir == BTC_WIFI_TRAFFIC_TX) ? 2558 "uplink" : "downlink"))); 2559 2560 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, 2561 &wifi_link_status); 2562 seq_printf(m, "\n %-35s = %d/ %d/ %d/ %d/ %d", 2563 "sta/vwifi/hs/p2pGo/p2pGc", 2564 ((wifi_link_status & WIFI_STA_CONNECTED) ? 1 : 0), 2565 ((wifi_link_status & WIFI_AP_CONNECTED) ? 1 : 0), 2566 ((wifi_link_status & WIFI_HS_CONNECTED) ? 1 : 0), 2567 ((wifi_link_status & WIFI_P2P_GO_CONNECTED) ? 1 : 0), 2568 ((wifi_link_status & WIFI_P2P_GC_CONNECTED) ? 1 : 0)); 2569 2570 seq_printf(m, "\n %-35s = [%s/ %d/ %d] ", 2571 "BT [status/ rssi/ retryCnt]", 2572 ((coex_sta->bt_disabled) ? ("disabled") : 2573 ((coex_sta->c2h_bt_inquiry_page) ? ("inquiry/page scan") : 2574 ((BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE == 2575 coex_dm->bt_status) ? 2576 "non-connected idle" : 2577 ((BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE == 2578 coex_dm->bt_status) ? 2579 "connected-idle" : "busy")))), 2580 coex_sta->bt_rssi, coex_sta->bt_retry_cnt); 2581 2582 seq_printf(m, "\n %-35s = %d / %d / %d / %d", 2583 "SCO/HID/PAN/A2DP", bt_link_info->sco_exist, 2584 bt_link_info->hid_exist, bt_link_info->pan_exist, 2585 bt_link_info->a2dp_exist); 2586 btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_LINK_INFO, m); 2587 2588 bt_info_ext = coex_sta->bt_info_ext; 2589 seq_printf(m, "\n %-35s = %s", 2590 "BT Info A2DP rate", 2591 (bt_info_ext & BIT0) ? "Basic rate" : "EDR rate"); 2592 2593 for (i = 0; i < BT_INFO_SRC_8723B_1ANT_MAX; i++) { 2594 if (coex_sta->bt_info_c2h_cnt[i]) { 2595 seq_printf(m, "\n %-35s = %7ph(%d)", 2596 glbt_info_src_8723b_1ant[i], 2597 coex_sta->bt_info_c2h[i], 2598 coex_sta->bt_info_c2h_cnt[i]); 2599 } 2600 } 2601 seq_printf(m, "\n %-35s = %s/%s, (0x%x/0x%x)", 2602 "PS state, IPS/LPS, (lps/rpwm)", 2603 ((coex_sta->under_ips ? "IPS ON" : "IPS OFF")), 2604 ((coex_sta->under_lps ? "LPS ON" : "LPS OFF")), 2605 btcoexist->bt_info.lps_val, 2606 btcoexist->bt_info.rpwm_val); 2607 btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD, m); 2608 2609 if (!btcoexist->manual_control) { 2610 /* Sw mechanism */ 2611 seq_printf(m, "\n %-35s", 2612 "============[Sw mechanism]============"); 2613 2614 seq_printf(m, "\n %-35s = %d/", 2615 "SM[LowPenaltyRA]", coex_dm->cur_low_penalty_ra); 2616 2617 seq_printf(m, "\n %-35s = %s/ %s/ %d ", 2618 "DelBA/ BtCtrlAgg/ AggSize", 2619 (btcoexist->bt_info.reject_agg_pkt ? "Yes" : "No"), 2620 (btcoexist->bt_info.bt_ctrl_buf_size ? "Yes" : "No"), 2621 btcoexist->bt_info.agg_buf_size); 2622 2623 seq_printf(m, "\n %-35s = 0x%x ", 2624 "Rate Mask", btcoexist->bt_info.ra_mask); 2625 2626 /* Fw mechanism */ 2627 seq_printf(m, "\n %-35s", 2628 "============[Fw mechanism]============"); 2629 2630 pstdmacase = coex_dm->cur_ps_tdma; 2631 seq_printf(m, "\n %-35s = %5ph case-%d (auto:%d)", 2632 "PS TDMA", coex_dm->ps_tdma_para, 2633 pstdmacase, coex_dm->auto_tdma_adjust); 2634 2635 seq_printf(m, "\n %-35s = %d ", 2636 "IgnWlanAct", coex_dm->cur_ignore_wlan_act); 2637 2638 seq_printf(m, "\n %-35s = 0x%x ", 2639 "Latest error condition(should be 0)", 2640 coex_dm->error_condition); 2641 } 2642 2643 seq_printf(m, "\n %-35s = %d", 2644 "Coex Table Type", coex_sta->coex_table_type); 2645 2646 /* Hw setting */ 2647 seq_printf(m, "\n %-35s", 2648 "============[Hw setting]============"); 2649 2650 seq_printf(m, "\n %-35s = 0x%x/0x%x/0x%x/0x%x", 2651 "backup ARFR1/ARFR2/RL/AMaxTime", coex_dm->backup_arfr_cnt1, 2652 coex_dm->backup_arfr_cnt2, coex_dm->backup_retry_limit, 2653 coex_dm->backup_ampdu_max_time); 2654 2655 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x430); 2656 u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x434); 2657 u16tmp[0] = btcoexist->btc_read_2byte(btcoexist, 0x42a); 2658 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x456); 2659 seq_printf(m, "\n %-35s = 0x%x/0x%x/0x%x/0x%x", 2660 "0x430/0x434/0x42a/0x456", 2661 u32tmp[0], u32tmp[1], u16tmp[0], u8tmp[0]); 2662 2663 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778); 2664 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6cc); 2665 u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x880); 2666 seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x", 2667 "0x778/0x6cc/0x880[29:25]", u8tmp[0], u32tmp[0], 2668 (u32tmp[1] & 0x3e000000) >> 25); 2669 2670 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x948); 2671 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x67); 2672 u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x765); 2673 seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x", 2674 "0x948/ 0x67[5] / 0x765", 2675 u32tmp[0], ((u8tmp[0] & 0x20) >> 5), u8tmp[1]); 2676 2677 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x92c); 2678 u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x930); 2679 u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x944); 2680 seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x", 2681 "0x92c[1:0]/ 0x930[7:0]/0x944[1:0]", 2682 u32tmp[0] & 0x3, u32tmp[1] & 0xff, u32tmp[2] & 0x3); 2683 2684 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x39); 2685 u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x40); 2686 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c); 2687 u8tmp[2] = btcoexist->btc_read_1byte(btcoexist, 0x64); 2688 seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", 2689 "0x38[11]/0x40/0x4c[24:23]/0x64[0]", 2690 ((u8tmp[0] & 0x8) >> 3), u8tmp[1], 2691 ((u32tmp[0] & 0x01800000) >> 23), u8tmp[2] & 0x1); 2692 2693 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550); 2694 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522); 2695 seq_printf(m, "\n %-35s = 0x%x/ 0x%x", 2696 "0x550(bcn ctrl)/0x522", u32tmp[0], u8tmp[0]); 2697 2698 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50); 2699 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x49c); 2700 seq_printf(m, "\n %-35s = 0x%x/ 0x%x", 2701 "0xc50(dig)/0x49c(null-drop)", u32tmp[0] & 0xff, u8tmp[0]); 2702 2703 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xda0); 2704 u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0xda4); 2705 u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0xda8); 2706 u32tmp[3] = btcoexist->btc_read_4byte(btcoexist, 0xcf0); 2707 2708 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xa5b); 2709 u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0xa5c); 2710 2711 fa_ofdm = ((u32tmp[0] & 0xffff0000) >> 16) + 2712 ((u32tmp[1] & 0xffff0000) >> 16) + 2713 (u32tmp[1] & 0xffff) + 2714 (u32tmp[2] & 0xffff) + 2715 ((u32tmp[3] & 0xffff0000) >> 16) + 2716 (u32tmp[3] & 0xffff); 2717 fa_cck = (u8tmp[0] << 8) + u8tmp[1]; 2718 2719 seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x", 2720 "OFDM-CCA/OFDM-FA/CCK-FA", 2721 u32tmp[0] & 0xffff, fa_ofdm, fa_cck); 2722 2723 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0); 2724 u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4); 2725 u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8); 2726 seq_printf(m, "\n %-35s = 0x%x/ 0x%x/ 0x%x", 2727 "0x6c0/0x6c4/0x6c8(coexTable)", 2728 u32tmp[0], u32tmp[1], u32tmp[2]); 2729 2730 seq_printf(m, "\n %-35s = %d/ %d", 2731 "0x770(high-pri rx/tx)", coex_sta->high_priority_rx, 2732 coex_sta->high_priority_tx); 2733 seq_printf(m, "\n %-35s = %d/ %d", 2734 "0x774(low-pri rx/tx)", coex_sta->low_priority_rx, 2735 coex_sta->low_priority_tx); 2736 if (btcoexist->auto_report_1ant) 2737 halbtc8723b1ant_monitor_bt_ctr(btcoexist); 2738 btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_COEX_STATISTICS, m); 2739 } 2740 2741 void ex_btc8723b1ant_ips_notify(struct btc_coexist *btcoexist, u8 type) 2742 { 2743 struct rtl_priv *rtlpriv = btcoexist->adapter; 2744 2745 if (btcoexist->manual_control || btcoexist->stop_coex_dm) 2746 return; 2747 2748 if (BTC_IPS_ENTER == type) { 2749 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2750 "[BTCoex], IPS ENTER notify\n"); 2751 coex_sta->under_ips = true; 2752 2753 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, 2754 FORCE_EXEC, false, true); 2755 /* set PTA control */ 2756 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0); 2757 halbtc8723b1ant_coex_table_with_type(btcoexist, 2758 NORMAL_EXEC, 0); 2759 } else if (BTC_IPS_LEAVE == type) { 2760 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2761 "[BTCoex], IPS LEAVE notify\n"); 2762 coex_sta->under_ips = false; 2763 2764 halbtc8723b1ant_init_hw_config(btcoexist, false, false); 2765 halbtc8723b1ant_init_coex_dm(btcoexist); 2766 halbtc8723b1ant_query_bt_info(btcoexist); 2767 } 2768 } 2769 2770 void ex_btc8723b1ant_lps_notify(struct btc_coexist *btcoexist, u8 type) 2771 { 2772 struct rtl_priv *rtlpriv = btcoexist->adapter; 2773 2774 if (btcoexist->manual_control || btcoexist->stop_coex_dm) 2775 return; 2776 2777 if (BTC_LPS_ENABLE == type) { 2778 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2779 "[BTCoex], LPS ENABLE notify\n"); 2780 coex_sta->under_lps = true; 2781 } else if (BTC_LPS_DISABLE == type) { 2782 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2783 "[BTCoex], LPS DISABLE notify\n"); 2784 coex_sta->under_lps = false; 2785 } 2786 } 2787 2788 void ex_btc8723b1ant_scan_notify(struct btc_coexist *btcoexist, u8 type) 2789 { 2790 struct rtl_priv *rtlpriv = btcoexist->adapter; 2791 bool wifi_connected = false, bt_hs_on = false; 2792 u8 u8tmpa, u8tmpb; 2793 u32 u32tmp; 2794 u32 wifi_link_status = 0; 2795 u32 num_of_wifi_link = 0; 2796 bool bt_ctrl_agg_buf_size = false; 2797 u8 agg_buf_size = 5; 2798 2799 if (btcoexist->manual_control || btcoexist->stop_coex_dm) 2800 return; 2801 2802 if (type == BTC_SCAN_START) { 2803 coex_sta->wifi_is_high_pri_task = true; 2804 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2805 "[BTCoex], SCAN START notify\n"); 2806 /* Force antenna setup for no scan result issue */ 2807 halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8); 2808 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, 2809 FORCE_EXEC, false, false); 2810 u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x948); 2811 u8tmpa = btcoexist->btc_read_1byte(btcoexist, 0x765); 2812 u8tmpb = btcoexist->btc_read_1byte(btcoexist, 0x67); 2813 2814 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2815 "[BTCoex], 0x948=0x%x, 0x765=0x%x, 0x67=0x%x\n", 2816 u32tmp, u8tmpa, u8tmpb); 2817 } else { 2818 coex_sta->wifi_is_high_pri_task = false; 2819 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2820 "[BTCoex], SCAN FINISH notify\n"); 2821 2822 btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM, 2823 &coex_sta->scan_ap_num); 2824 } 2825 2826 if (coex_sta->bt_disabled) 2827 return; 2828 2829 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); 2830 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, 2831 &wifi_connected); 2832 2833 halbtc8723b1ant_query_bt_info(btcoexist); 2834 2835 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, 2836 &wifi_link_status); 2837 num_of_wifi_link = wifi_link_status >> 16; 2838 if (num_of_wifi_link >= 2) { 2839 halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0); 2840 halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false, 2841 bt_ctrl_agg_buf_size, agg_buf_size); 2842 halbtc8723b1ant_action_wifi_multiport(btcoexist); 2843 return; 2844 } 2845 2846 if (coex_sta->c2h_bt_inquiry_page) { 2847 halbtc8723b1ant_action_bt_inquiry(btcoexist); 2848 return; 2849 } else if (bt_hs_on) { 2850 halbtc8723b1ant_action_hs(btcoexist); 2851 return; 2852 } 2853 2854 if (BTC_SCAN_START == type) { 2855 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2856 "[BTCoex], SCAN START notify\n"); 2857 if (!wifi_connected) 2858 /* non-connected scan */ 2859 btc8723b1ant_action_wifi_not_conn_scan(btcoexist); 2860 else 2861 /* wifi is connected */ 2862 btc8723b1ant_action_wifi_conn_scan(btcoexist); 2863 } else if (BTC_SCAN_FINISH == type) { 2864 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2865 "[BTCoex], SCAN FINISH notify\n"); 2866 if (!wifi_connected) 2867 /* non-connected scan */ 2868 btc8723b1ant_action_wifi_not_conn(btcoexist); 2869 else 2870 halbtc8723b1ant_action_wifi_connected(btcoexist); 2871 } 2872 } 2873 2874 void ex_btc8723b1ant_connect_notify(struct btc_coexist *btcoexist, u8 type) 2875 { 2876 struct rtl_priv *rtlpriv = btcoexist->adapter; 2877 bool wifi_connected = false, bt_hs_on = false; 2878 u32 wifi_link_status = 0; 2879 u32 num_of_wifi_link = 0; 2880 bool bt_ctrl_agg_buf_size = false, under_4way = false; 2881 u8 agg_buf_size = 5; 2882 2883 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, 2884 &under_4way); 2885 2886 if (btcoexist->manual_control || btcoexist->stop_coex_dm || 2887 coex_sta->bt_disabled) 2888 return; 2889 2890 if (type == BTC_ASSOCIATE_START) { 2891 coex_sta->wifi_is_high_pri_task = true; 2892 2893 /* Force antenna setup for no scan result issue */ 2894 halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8); 2895 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, 2896 FORCE_EXEC, false, false); 2897 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2898 "[BTCoex], CONNECT START notify\n"); 2899 coex_dm->arp_cnt = 0; 2900 } else { 2901 coex_sta->wifi_is_high_pri_task = false; 2902 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2903 "[BTCoex], CONNECT FINISH notify\n"); 2904 } 2905 2906 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, 2907 &wifi_link_status); 2908 num_of_wifi_link = wifi_link_status>>16; 2909 if (num_of_wifi_link >= 2) { 2910 halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0); 2911 halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false, 2912 bt_ctrl_agg_buf_size, agg_buf_size); 2913 halbtc8723b1ant_action_wifi_multiport(btcoexist); 2914 return; 2915 } 2916 2917 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); 2918 if (coex_sta->c2h_bt_inquiry_page) { 2919 halbtc8723b1ant_action_bt_inquiry(btcoexist); 2920 return; 2921 } else if (bt_hs_on) { 2922 halbtc8723b1ant_action_hs(btcoexist); 2923 return; 2924 } 2925 2926 if (BTC_ASSOCIATE_START == type) { 2927 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2928 "[BTCoex], CONNECT START notify\n"); 2929 btc8723b1ant_act_wifi_not_conn_asso_auth(btcoexist); 2930 } else if (BTC_ASSOCIATE_FINISH == type) { 2931 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2932 "[BTCoex], CONNECT FINISH notify\n"); 2933 2934 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, 2935 &wifi_connected); 2936 if (!wifi_connected) 2937 /* non-connected scan */ 2938 btc8723b1ant_action_wifi_not_conn(btcoexist); 2939 else 2940 halbtc8723b1ant_action_wifi_connected(btcoexist); 2941 } 2942 } 2943 2944 void ex_btc8723b1ant_media_status_notify(struct btc_coexist *btcoexist, 2945 u8 type) 2946 { 2947 struct rtl_priv *rtlpriv = btcoexist->adapter; 2948 u8 h2c_parameter[3] = {0}; 2949 u32 wifi_bw; 2950 u8 wifi_central_chnl; 2951 bool wifi_under_b_mode = false; 2952 2953 if (btcoexist->manual_control || btcoexist->stop_coex_dm || 2954 coex_sta->bt_disabled) 2955 return; 2956 2957 if (type == BTC_MEDIA_CONNECT) { 2958 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2959 "[BTCoex], MEDIA connect notify\n"); 2960 /* Force antenna setup for no scan result issue */ 2961 halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8); 2962 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, 2963 FORCE_EXEC, false, false); 2964 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_B_MODE, 2965 &wifi_under_b_mode); 2966 2967 /* Set CCK Tx/Rx high Pri except 11b mode */ 2968 if (wifi_under_b_mode) { 2969 btcoexist->btc_write_1byte(btcoexist, 0x6cd, 2970 0x00); /* CCK Tx */ 2971 btcoexist->btc_write_1byte(btcoexist, 0x6cf, 2972 0x00); /* CCK Rx */ 2973 } else { 2974 btcoexist->btc_write_1byte(btcoexist, 0x6cd, 2975 0x00); /* CCK Tx */ 2976 btcoexist->btc_write_1byte(btcoexist, 0x6cf, 2977 0x10); /* CCK Rx */ 2978 } 2979 2980 coex_dm->backup_arfr_cnt1 = 2981 btcoexist->btc_read_4byte(btcoexist, 0x430); 2982 coex_dm->backup_arfr_cnt2 = 2983 btcoexist->btc_read_4byte(btcoexist, 0x434); 2984 coex_dm->backup_retry_limit = 2985 btcoexist->btc_read_2byte(btcoexist, 0x42a); 2986 coex_dm->backup_ampdu_max_time = 2987 btcoexist->btc_read_1byte(btcoexist, 0x456); 2988 } else { 2989 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 2990 "[BTCoex], MEDIA disconnect notify\n"); 2991 coex_dm->arp_cnt = 0; 2992 2993 btcoexist->btc_write_1byte(btcoexist, 0x6cd, 0x0); /* CCK Tx */ 2994 btcoexist->btc_write_1byte(btcoexist, 0x6cf, 0x0); /* CCK Rx */ 2995 2996 coex_sta->cck_ever_lock = false; 2997 } 2998 2999 /* only 2.4G we need to inform bt the chnl mask */ 3000 btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL, 3001 &wifi_central_chnl); 3002 3003 if (type == BTC_MEDIA_CONNECT && wifi_central_chnl <= 14) { 3004 h2c_parameter[0] = 0x0; 3005 h2c_parameter[1] = wifi_central_chnl; 3006 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); 3007 if (BTC_WIFI_BW_HT40 == wifi_bw) 3008 h2c_parameter[2] = 0x30; 3009 else 3010 h2c_parameter[2] = 0x20; 3011 } 3012 3013 coex_dm->wifi_chnl_info[0] = h2c_parameter[0]; 3014 coex_dm->wifi_chnl_info[1] = h2c_parameter[1]; 3015 coex_dm->wifi_chnl_info[2] = h2c_parameter[2]; 3016 3017 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3018 "[BTCoex], FW write 0x66 = 0x%x\n", 3019 h2c_parameter[0] << 16 | h2c_parameter[1] << 8 | 3020 h2c_parameter[2]); 3021 3022 btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter); 3023 } 3024 3025 void ex_btc8723b1ant_special_packet_notify(struct btc_coexist *btcoexist, 3026 u8 type) 3027 { 3028 struct rtl_priv *rtlpriv = btcoexist->adapter; 3029 bool bt_hs_on = false; 3030 u32 wifi_link_status = 0; 3031 u32 num_of_wifi_link = 0; 3032 bool bt_ctrl_agg_buf_size = false, under_4way = false; 3033 u8 agg_buf_size = 5; 3034 3035 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, 3036 &under_4way); 3037 3038 if (btcoexist->manual_control || btcoexist->stop_coex_dm || 3039 coex_sta->bt_disabled) 3040 return; 3041 3042 if (type == BTC_PACKET_DHCP || type == BTC_PACKET_EAPOL || 3043 type == BTC_PACKET_ARP) { 3044 if (type == BTC_PACKET_ARP) { 3045 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3046 "[BTCoex], special Packet ARP notify\n"); 3047 3048 coex_dm->arp_cnt++; 3049 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3050 "[BTCoex], ARP Packet Count = %d\n", 3051 coex_dm->arp_cnt); 3052 3053 if ((coex_dm->arp_cnt >= 10) && (!under_4way)) 3054 /* if APR PKT > 10 after connect, do not go to 3055 * ActionWifiConnectedSpecificPacket(btcoexist) 3056 */ 3057 coex_sta->wifi_is_high_pri_task = false; 3058 else 3059 coex_sta->wifi_is_high_pri_task = true; 3060 } else { 3061 coex_sta->wifi_is_high_pri_task = true; 3062 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3063 "[BTCoex], special Packet DHCP or EAPOL notify\n"); 3064 } 3065 } else { 3066 coex_sta->wifi_is_high_pri_task = false; 3067 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3068 "[BTCoex], special Packet [Type = %d] notify\n", 3069 type); 3070 } 3071 3072 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, 3073 &wifi_link_status); 3074 num_of_wifi_link = wifi_link_status >> 16; 3075 if (num_of_wifi_link >= 2) { 3076 halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0); 3077 halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false, 3078 bt_ctrl_agg_buf_size, agg_buf_size); 3079 halbtc8723b1ant_action_wifi_multiport(btcoexist); 3080 return; 3081 } 3082 3083 coex_sta->special_pkt_period_cnt = 0; 3084 3085 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); 3086 if (coex_sta->c2h_bt_inquiry_page) { 3087 halbtc8723b1ant_action_bt_inquiry(btcoexist); 3088 return; 3089 } else if (bt_hs_on) { 3090 halbtc8723b1ant_action_hs(btcoexist); 3091 return; 3092 } 3093 3094 if (BTC_PACKET_DHCP == type || 3095 BTC_PACKET_EAPOL == type) { 3096 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3097 "[BTCoex], special Packet(%d) notify\n", type); 3098 halbtc8723b1ant_action_wifi_connected_special_packet(btcoexist); 3099 } 3100 } 3101 3102 void ex_btc8723b1ant_bt_info_notify(struct btc_coexist *btcoexist, 3103 u8 *tmp_buf, u8 length) 3104 { 3105 struct rtl_priv *rtlpriv = btcoexist->adapter; 3106 u8 bt_info = 0; 3107 u8 i, rsp_source = 0; 3108 bool wifi_connected = false; 3109 bool bt_busy = false; 3110 3111 coex_sta->c2h_bt_info_req_sent = false; 3112 3113 rsp_source = tmp_buf[0] & 0xf; 3114 if (rsp_source >= BT_INFO_SRC_8723B_1ANT_MAX) 3115 rsp_source = BT_INFO_SRC_8723B_1ANT_WIFI_FW; 3116 coex_sta->bt_info_c2h_cnt[rsp_source]++; 3117 3118 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3119 "[BTCoex], Bt info[%d], length=%d, hex data = [", 3120 rsp_source, length); 3121 for (i = 0; i < length; i++) { 3122 coex_sta->bt_info_c2h[rsp_source][i] = tmp_buf[i]; 3123 if (i == 1) 3124 bt_info = tmp_buf[i]; 3125 if (i == length - 1) 3126 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3127 "0x%02x]\n", tmp_buf[i]); 3128 else 3129 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3130 "0x%02x, ", tmp_buf[i]); 3131 } 3132 3133 /* if 0xff, it means BT is under WHCK test */ 3134 if (bt_info == 0xff) 3135 coex_sta->bt_whck_test = true; 3136 else 3137 coex_sta->bt_whck_test = false; 3138 3139 if (rsp_source != BT_INFO_SRC_8723B_1ANT_WIFI_FW) { 3140 coex_sta->bt_retry_cnt = /* [3:0] */ 3141 coex_sta->bt_info_c2h[rsp_source][2] & 0xf; 3142 3143 if (coex_sta->bt_retry_cnt >= 1) 3144 coex_sta->pop_event_cnt++; 3145 3146 if (coex_sta->bt_info_c2h[rsp_source][2] & 0x20) 3147 coex_sta->c2h_bt_remote_name_req = true; 3148 else 3149 coex_sta->c2h_bt_remote_name_req = false; 3150 3151 coex_sta->bt_rssi = 3152 coex_sta->bt_info_c2h[rsp_source][3] * 2 - 90; 3153 3154 coex_sta->bt_info_ext = 3155 coex_sta->bt_info_c2h[rsp_source][4]; 3156 3157 if (coex_sta->bt_info_c2h[rsp_source][1] == 0x49) { 3158 coex_sta->a2dp_bit_pool = 3159 coex_sta->bt_info_c2h[rsp_source][6]; 3160 } else { 3161 coex_sta->a2dp_bit_pool = 0; 3162 } 3163 3164 coex_sta->bt_tx_rx_mask = 3165 (coex_sta->bt_info_c2h[rsp_source][2] & 0x40); 3166 btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TX_RX_MASK, 3167 &coex_sta->bt_tx_rx_mask); 3168 3169 if (!coex_sta->bt_tx_rx_mask) { 3170 /* BT into is responded by BT FW and BT RF REG 3171 * 0x3C != 0x15 => Need to switch BT TRx Mask 3172 */ 3173 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3174 "[BTCoex], Switch BT TRx Mask since BT RF REG 0x3C != 0x15\n"); 3175 btcoexist->btc_set_bt_reg(btcoexist, BTC_BT_REG_RF, 3176 0x3c, 0x15); 3177 3178 /* BT TRx Mask lock 0x2c[0], 0x30[0] = 0 */ 3179 btcoexist->btc_set_bt_reg(btcoexist, BTC_BT_REG_RF, 3180 0x2c, 0x7c44); 3181 btcoexist->btc_set_bt_reg(btcoexist, BTC_BT_REG_RF, 3182 0x30, 0x7c44); 3183 } 3184 3185 /* Here we need to resend some wifi info to BT 3186 * because bt is reset and loss of the info. 3187 */ 3188 if (coex_sta->bt_info_ext & BIT1) { 3189 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3190 "[BTCoex], BT ext info bit1 check, send wifi BW&Chnl to BT!!\n"); 3191 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, 3192 &wifi_connected); 3193 if (wifi_connected) 3194 ex_btc8723b1ant_media_status_notify(btcoexist, 3195 BTC_MEDIA_CONNECT); 3196 else 3197 ex_btc8723b1ant_media_status_notify(btcoexist, 3198 BTC_MEDIA_DISCONNECT); 3199 } 3200 3201 if (coex_sta->bt_info_ext & BIT3) { 3202 if (!btcoexist->manual_control && 3203 !btcoexist->stop_coex_dm) { 3204 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3205 "[BTCoex], BT ext info bit3 check, set BT NOT ignore Wlan active!!\n"); 3206 halbtc8723b1ant_ignore_wlan_act(btcoexist, 3207 FORCE_EXEC, 3208 false); 3209 } 3210 } else { 3211 /* BT already NOT ignore Wlan active, do nothing here.*/ 3212 } 3213 if (!btcoexist->auto_report_1ant) { 3214 if (coex_sta->bt_info_ext & BIT4) { 3215 /* BT auto report already enabled, do nothing */ 3216 } else { 3217 halbtc8723b1ant_bt_auto_report(btcoexist, 3218 FORCE_EXEC, 3219 true); 3220 } 3221 } 3222 } 3223 3224 /* check BIT2 first ==> check if bt is under inquiry or page scan */ 3225 if (bt_info & BT_INFO_8723B_1ANT_B_INQ_PAGE) 3226 coex_sta->c2h_bt_inquiry_page = true; 3227 else 3228 coex_sta->c2h_bt_inquiry_page = false; 3229 3230 coex_sta->num_of_profile = 0; 3231 3232 /* set link exist status */ 3233 if (!(bt_info & BT_INFO_8723B_1ANT_B_CONNECTION)) { 3234 coex_sta->bt_link_exist = false; 3235 coex_sta->pan_exist = false; 3236 coex_sta->a2dp_exist = false; 3237 coex_sta->hid_exist = false; 3238 coex_sta->sco_exist = false; 3239 3240 coex_sta->bt_hi_pri_link_exist = false; 3241 } else { 3242 /* connection exists */ 3243 coex_sta->bt_link_exist = true; 3244 if (bt_info & BT_INFO_8723B_1ANT_B_FTP) { 3245 coex_sta->pan_exist = true; 3246 coex_sta->num_of_profile++; 3247 } else { 3248 coex_sta->pan_exist = false; 3249 } 3250 if (bt_info & BT_INFO_8723B_1ANT_B_A2DP) { 3251 coex_sta->a2dp_exist = true; 3252 coex_sta->num_of_profile++; 3253 } else { 3254 coex_sta->a2dp_exist = false; 3255 } 3256 if (bt_info & BT_INFO_8723B_1ANT_B_HID) { 3257 coex_sta->hid_exist = true; 3258 coex_sta->num_of_profile++; 3259 } else { 3260 coex_sta->hid_exist = false; 3261 } 3262 if (bt_info & BT_INFO_8723B_1ANT_B_SCO_ESCO) { 3263 coex_sta->sco_exist = true; 3264 coex_sta->num_of_profile++; 3265 } else { 3266 coex_sta->sco_exist = false; 3267 } 3268 3269 if ((!coex_sta->hid_exist) && 3270 (!coex_sta->c2h_bt_inquiry_page) && 3271 (!coex_sta->sco_exist)) { 3272 if (coex_sta->high_priority_tx + 3273 coex_sta->high_priority_rx >= 3274 160) { 3275 coex_sta->hid_exist = true; 3276 coex_sta->wrong_profile_notification++; 3277 coex_sta->num_of_profile++; 3278 bt_info = bt_info | 0x28; 3279 } 3280 } 3281 3282 /* Add Hi-Pri Tx/Rx counter to avoid false detection */ 3283 if (((coex_sta->hid_exist) || (coex_sta->sco_exist)) && 3284 (coex_sta->high_priority_tx + coex_sta->high_priority_rx >= 3285 160) && 3286 (!coex_sta->c2h_bt_inquiry_page)) 3287 coex_sta->bt_hi_pri_link_exist = true; 3288 3289 if ((bt_info & BT_INFO_8723B_1ANT_B_ACL_BUSY) && 3290 (coex_sta->num_of_profile == 0)) { 3291 if (coex_sta->low_priority_tx + 3292 coex_sta->low_priority_rx >= 3293 160) { 3294 coex_sta->pan_exist = true; 3295 coex_sta->num_of_profile++; 3296 coex_sta->wrong_profile_notification++; 3297 bt_info = bt_info | 0x88; 3298 } 3299 } 3300 } 3301 3302 halbtc8723b1ant_update_bt_link_info(btcoexist); 3303 3304 /* mask profile bit for connect-ilde identification 3305 * ( for CSR case: A2DP idle --> 0x41) 3306 */ 3307 bt_info = bt_info & 0x1f; 3308 3309 if (!(bt_info & BT_INFO_8723B_1ANT_B_CONNECTION)) { 3310 coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE; 3311 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3312 "[BTCoex], BtInfoNotify(), BT Non-Connected idle!\n"); 3313 /* connection exists but no busy */ 3314 } else if (bt_info == BT_INFO_8723B_1ANT_B_CONNECTION) { 3315 coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE; 3316 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3317 "[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n"); 3318 } else if ((bt_info & BT_INFO_8723B_1ANT_B_SCO_ESCO) || 3319 (bt_info & BT_INFO_8723B_1ANT_B_SCO_BUSY)) { 3320 coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_SCO_BUSY; 3321 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3322 "[BTCoex], BtInfoNotify(), BT SCO busy!!!\n"); 3323 } else if (bt_info & BT_INFO_8723B_1ANT_B_ACL_BUSY) { 3324 if (BT_8723B_1ANT_BT_STATUS_ACL_BUSY != coex_dm->bt_status) 3325 coex_dm->auto_tdma_adjust = false; 3326 3327 coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_ACL_BUSY; 3328 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3329 "[BTCoex], BtInfoNotify(), BT ACL busy!!!\n"); 3330 } else { 3331 coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_MAX; 3332 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3333 "[BTCoex], BtInfoNotify(), BT Non-Defined state!!\n"); 3334 } 3335 3336 if ((BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) || 3337 (BT_8723B_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) || 3338 (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status)) 3339 bt_busy = true; 3340 else 3341 bt_busy = false; 3342 btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy); 3343 3344 halbtc8723b1ant_run_coexist_mechanism(btcoexist); 3345 } 3346 3347 void ex_btc8723b1ant_rf_status_notify(struct btc_coexist *btcoexist, u8 type) 3348 { 3349 struct rtl_priv *rtlpriv = btcoexist->adapter; 3350 u32 u32tmp; 3351 u8 u8tmpa, u8tmpb, u8tmpc; 3352 3353 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3354 "[BTCoex], RF Status notify\n"); 3355 3356 if (type == BTC_RF_ON) { 3357 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3358 "[BTCoex], RF is turned ON!!\n"); 3359 btcoexist->stop_coex_dm = false; 3360 } else if (type == BTC_RF_OFF) { 3361 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3362 "[BTCoex], RF is turned OFF!!\n"); 3363 3364 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 3365 0x0, 0x0); 3366 halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 0); 3367 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, 3368 FORCE_EXEC, false, true); 3369 3370 halbtc8723b1ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true); 3371 btcoexist->stop_coex_dm = true; 3372 3373 u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x948); 3374 u8tmpa = btcoexist->btc_read_1byte(btcoexist, 0x765); 3375 u8tmpb = btcoexist->btc_read_1byte(btcoexist, 0x67); 3376 u8tmpc = btcoexist->btc_read_1byte(btcoexist, 0x76e); 3377 3378 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3379 "############# [BTCoex], 0x948=0x%x, 0x765=0x%x, 0x67=0x%x, 0x76e=0x%x\n", 3380 u32tmp, u8tmpa, u8tmpb, u8tmpc); 3381 } 3382 } 3383 3384 void ex_btc8723b1ant_halt_notify(struct btc_coexist *btcoexist) 3385 { 3386 struct rtl_priv *rtlpriv = btcoexist->adapter; 3387 3388 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, "[BTCoex], Halt notify\n"); 3389 3390 btcoexist->stop_coex_dm = true; 3391 3392 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, FORCE_EXEC, 3393 false, true); 3394 3395 halbtc8723b1ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true); 3396 3397 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 3398 0x0, 0x0); 3399 halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 0); 3400 3401 ex_btc8723b1ant_media_status_notify(btcoexist, BTC_MEDIA_DISCONNECT); 3402 3403 btcoexist->stop_coex_dm = true; 3404 } 3405 3406 void ex_btc8723b1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state) 3407 { 3408 struct rtl_priv *rtlpriv = btcoexist->adapter; 3409 3410 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, "[BTCoex], Pnp notify\n"); 3411 3412 if (BTC_WIFI_PNP_SLEEP == pnp_state) { 3413 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3414 "[BTCoex], Pnp notify to SLEEP\n"); 3415 halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, 3416 FORCE_EXEC, false, true); 3417 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 3418 0x0, 0x0); 3419 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0); 3420 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); 3421 3422 /* Driver do not leave IPS/LPS when driver is going to sleep, so 3423 * BTCoexistence think wifi is still under IPS/LPS 3424 * 3425 * BT should clear UnderIPS/UnderLPS state to avoid mismatch 3426 * state after wakeup. 3427 */ 3428 coex_sta->under_ips = false; 3429 coex_sta->under_lps = false; 3430 btcoexist->stop_coex_dm = true; 3431 } else if (BTC_WIFI_PNP_WAKE_UP == pnp_state) { 3432 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3433 "[BTCoex], Pnp notify to WAKE UP\n"); 3434 btcoexist->stop_coex_dm = false; 3435 halbtc8723b1ant_init_hw_config(btcoexist, false, false); 3436 halbtc8723b1ant_init_coex_dm(btcoexist); 3437 halbtc8723b1ant_query_bt_info(btcoexist); 3438 } 3439 } 3440 3441 void ex_btc8723b1ant_coex_dm_reset(struct btc_coexist *btcoexist) 3442 { 3443 struct rtl_priv *rtlpriv = btcoexist->adapter; 3444 3445 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3446 "[BTCoex], *****************Coex DM Reset****************\n"); 3447 3448 halbtc8723b1ant_init_hw_config(btcoexist, false, false); 3449 halbtc8723b1ant_init_coex_dm(btcoexist); 3450 } 3451 3452 void ex_btc8723b1ant_periodical(struct btc_coexist *btcoexist) 3453 { 3454 struct rtl_priv *rtlpriv = btcoexist->adapter; 3455 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; 3456 3457 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 3458 "[BTCoex], ==========================Periodical===========================\n"); 3459 3460 if (!btcoexist->auto_report_1ant) { 3461 halbtc8723b1ant_query_bt_info(btcoexist); 3462 halbtc8723b1ant_monitor_bt_enable_disable(btcoexist); 3463 } else { 3464 halbtc8723b1ant_monitor_bt_ctr(btcoexist); 3465 halbtc8723b1ant_monitor_wifi_ctr(btcoexist); 3466 3467 if ((coex_sta->high_priority_tx + coex_sta->high_priority_rx < 50) && 3468 bt_link_info->hid_exist) 3469 bt_link_info->hid_exist = false; 3470 3471 if (btc8723b1ant_is_wifi_status_changed(btcoexist) || 3472 coex_dm->auto_tdma_adjust) { 3473 halbtc8723b1ant_run_coexist_mechanism(btcoexist); 3474 } 3475 coex_sta->special_pkt_period_cnt++; 3476 } 3477 } 3478