aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c')
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c2087
1 files changed, 1572 insertions, 515 deletions
diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c
index 2003c8c51dcc..03998d2e9eb8 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b1ant.c
@@ -210,11 +210,24 @@ static void halbtc8723b1ant_limited_rx(struct btc_coexist *btcoexist,
btcoexist->btc_set(btcoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL);
}
+static void halbtc8723b1ant_query_bt_info(struct btc_coexist *btcoexist)
+{
+ u8 h2c_parameter[1] = {0};
+
+ coex_sta->c2h_bt_info_req_sent = true;
+
+ /* trigger */
+ h2c_parameter[0] |= BIT(0);
+
+ btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter);
+}
+
static void halbtc8723b1ant_monitor_bt_ctr(struct btc_coexist *btcoexist)
{
u32 reg_hp_txrx, reg_lp_txrx, u32tmp;
u32 reg_hp_tx = 0, reg_hp_rx = 0;
u32 reg_lp_tx = 0, reg_lp_rx = 0;
+ static u32 num_of_bt_counter_chk;
reg_hp_txrx = 0x770;
reg_lp_txrx = 0x774;
@@ -232,25 +245,122 @@ static void halbtc8723b1ant_monitor_bt_ctr(struct btc_coexist *btcoexist)
coex_sta->low_priority_tx = reg_lp_tx;
coex_sta->low_priority_rx = reg_lp_rx;
+ if ((coex_sta->low_priority_tx > 1050) &&
+ (!coex_sta->c2h_bt_inquiry_page))
+ coex_sta->pop_event_cnt++;
+
/* reset counter */
btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc);
+
+ /* This part is for wifi FW and driver to update BT's status as
+ * disabled.
+ *
+ * The flow is as the following
+ * 1. disable BT
+ * 2. if all BT Tx/Rx counter = 0, after 6 sec we query bt info
+ * 3. Because BT will not rsp from mailbox, so wifi fw will know BT is
+ * disabled
+ *
+ * 4. FW will rsp c2h for BT that driver will know BT is disabled.
+ */
+ if ((reg_hp_tx == 0) && (reg_hp_rx == 0) && (reg_lp_tx == 0) &&
+ (reg_lp_rx == 0)) {
+ num_of_bt_counter_chk++;
+ if (num_of_bt_counter_chk == 3)
+ halbtc8723b1ant_query_bt_info(btcoexist);
+ } else {
+ num_of_bt_counter_chk = 0;
+ }
}
-static void halbtc8723b1ant_query_bt_info(struct btc_coexist *btcoexist)
+static void halbtc8723b1ant_monitor_wifi_ctr(struct btc_coexist *btcoexist)
{
- struct rtl_priv *rtlpriv = btcoexist->adapter;
- u8 h2c_parameter[1] = {0};
+ s32 wifi_rssi = 0;
+ bool wifi_busy = false, wifi_under_b_mode = false;
+ static u8 cck_lock_counter;
+ u32 total_cnt;
- coex_sta->c2h_bt_info_req_sent = true;
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+ btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_B_MODE,
+ &wifi_under_b_mode);
- /* trigger */
- h2c_parameter[0] |= BIT0;
+ if (coex_sta->under_ips) {
+ coex_sta->crc_ok_cck = 0;
+ coex_sta->crc_ok_11g = 0;
+ coex_sta->crc_ok_11n = 0;
+ coex_sta->crc_ok_11n_agg = 0;
+
+ coex_sta->crc_err_cck = 0;
+ coex_sta->crc_err_11g = 0;
+ coex_sta->crc_err_11n = 0;
+ coex_sta->crc_err_11n_agg = 0;
+ } else {
+ coex_sta->crc_ok_cck =
+ btcoexist->btc_read_4byte(btcoexist, 0xf88);
+ coex_sta->crc_ok_11g =
+ btcoexist->btc_read_2byte(btcoexist, 0xf94);
+ coex_sta->crc_ok_11n =
+ btcoexist->btc_read_2byte(btcoexist, 0xf90);
+ coex_sta->crc_ok_11n_agg =
+ btcoexist->btc_read_2byte(btcoexist, 0xfb8);
+
+ coex_sta->crc_err_cck =
+ btcoexist->btc_read_4byte(btcoexist, 0xf84);
+ coex_sta->crc_err_11g =
+ btcoexist->btc_read_2byte(btcoexist, 0xf96);
+ coex_sta->crc_err_11n =
+ btcoexist->btc_read_2byte(btcoexist, 0xf92);
+ coex_sta->crc_err_11n_agg =
+ btcoexist->btc_read_2byte(btcoexist, 0xfba);
+ }
- RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
- "[BTCoex], Query Bt Info, FW write 0x61 = 0x%x\n",
- h2c_parameter[0]);
+ /* reset counter */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xf16, 0x1, 0x1);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xf16, 0x1, 0x0);
+
+ if ((wifi_busy) && (wifi_rssi >= 30) && (!wifi_under_b_mode)) {
+ total_cnt = coex_sta->crc_ok_cck + coex_sta->crc_ok_11g +
+ coex_sta->crc_ok_11n + coex_sta->crc_ok_11n_agg;
+
+ if ((coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_BUSY) ||
+ (coex_dm->bt_status ==
+ BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY) ||
+ (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_SCO_BUSY)) {
+ if (coex_sta->crc_ok_cck >
+ (total_cnt - coex_sta->crc_ok_cck)) {
+ if (cck_lock_counter < 3)
+ cck_lock_counter++;
+ } else {
+ if (cck_lock_counter > 0)
+ cck_lock_counter--;
+ }
- btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter);
+ } else {
+ if (cck_lock_counter > 0)
+ cck_lock_counter--;
+ }
+ } else {
+ if (cck_lock_counter > 0)
+ cck_lock_counter--;
+ }
+
+ if (!coex_sta->pre_ccklock) {
+ if (cck_lock_counter >= 3)
+ coex_sta->cck_lock = true;
+ else
+ coex_sta->cck_lock = false;
+ } else {
+ if (cck_lock_counter == 0)
+ coex_sta->cck_lock = false;
+ else
+ coex_sta->cck_lock = true;
+ }
+
+ if (coex_sta->cck_lock)
+ coex_sta->cck_ever_lock = true;
+
+ coex_sta->pre_ccklock = coex_sta->cck_lock;
}
static bool btc8723b1ant_is_wifi_status_changed(struct btc_coexist *btcoexist)
@@ -297,6 +407,7 @@ static void halbtc8723b1ant_update_bt_link_info(struct btc_coexist *btcoexist)
bt_link_info->a2dp_exist = coex_sta->a2dp_exist;
bt_link_info->pan_exist = coex_sta->pan_exist;
bt_link_info->hid_exist = coex_sta->hid_exist;
+ bt_link_info->bt_hi_pri_link_exist = coex_sta->bt_hi_pri_link_exist;
/* work around for HS mode. */
if (bt_hs_on) {
@@ -333,6 +444,35 @@ static void halbtc8723b1ant_update_bt_link_info(struct btc_coexist *btcoexist)
bt_link_info->hid_only = false;
}
+static void halbtc8723b1ant_set_bt_auto_report(struct btc_coexist *btcoexist,
+ bool enable_auto_report)
+{
+ u8 h2c_parameter[1] = {0};
+
+ h2c_parameter[0] = 0;
+
+ if (enable_auto_report)
+ h2c_parameter[0] |= BIT(0);
+
+ btcoexist->btc_fill_h2c(btcoexist, 0x68, 1, h2c_parameter);
+}
+
+static void halbtc8723b1ant_bt_auto_report(struct btc_coexist *btcoexist,
+ bool force_exec,
+ bool enable_auto_report)
+{
+ coex_dm->cur_bt_auto_report = enable_auto_report;
+
+ if (!force_exec) {
+ if (coex_dm->pre_bt_auto_report == coex_dm->cur_bt_auto_report)
+ return;
+ }
+ halbtc8723b1ant_set_bt_auto_report(btcoexist,
+ coex_dm->cur_bt_auto_report);
+
+ coex_dm->pre_bt_auto_report = coex_dm->cur_bt_auto_report;
+}
+
static void btc8723b1ant_set_sw_pen_tx_rate_adapt(struct btc_coexist *btcoexist,
bool low_penalty_ra)
{
@@ -430,6 +570,8 @@ static void halbtc8723b1ant_coex_table(struct btc_coexist *btcoexist,
static void halbtc8723b1ant_coex_table_with_type(struct btc_coexist *btcoexist,
bool force_exec, u8 type)
{
+ coex_sta->coex_table_type = type;
+
switch (type) {
case 0:
halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555,
@@ -445,24 +587,68 @@ static void halbtc8723b1ant_coex_table_with_type(struct btc_coexist *btcoexist,
break;
case 3:
halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555,
- 0xaaaaaaaa, 0xffffff, 0x3);
+ 0x5a5a5a5a, 0xffffff, 0x3);
break;
case 4:
- halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555,
- 0x5aaa5aaa, 0xffffff, 0x3);
+ if ((coex_sta->cck_ever_lock) && (coex_sta->scan_ap_num <= 5))
+ halbtc8723b1ant_coex_table(btcoexist, force_exec,
+ 0x55555555, 0xaaaa5a5a,
+ 0xffffff, 0x3);
+ else
+ halbtc8723b1ant_coex_table(btcoexist, force_exec,
+ 0x55555555, 0x5a5a5a5a,
+ 0xffffff, 0x3);
break;
case 5:
- halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a,
- 0xaaaa5a5a, 0xffffff, 0x3);
+ if ((coex_sta->cck_ever_lock) && (coex_sta->scan_ap_num <= 5))
+ halbtc8723b1ant_coex_table(btcoexist, force_exec,
+ 0x5a5a5a5a, 0x5aaa5a5a,
+ 0xffffff, 0x3);
+ else
+ halbtc8723b1ant_coex_table(btcoexist, force_exec,
+ 0x5a5a5a5a, 0x5aaa5a5a,
+ 0xffffff, 0x3);
break;
case 6:
halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555,
- 0xaaaa5a5a, 0xffffff, 0x3);
+ 0xaaaaaaaa, 0xffffff, 0x3);
break;
case 7:
halbtc8723b1ant_coex_table(btcoexist, force_exec, 0xaaaaaaaa,
0xaaaaaaaa, 0xffffff, 0x3);
break;
+ case 8:
+ halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55dd55dd,
+ 0x5ada5ada, 0xffffff, 0x3);
+ break;
+ case 9:
+ halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55dd55dd,
+ 0x5ada5ada, 0xffffff, 0x3);
+ break;
+ case 10:
+ halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55dd55dd,
+ 0x5ada5ada, 0xffffff, 0x3);
+ break;
+ case 11:
+ halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55dd55dd,
+ 0x5ada5ada, 0xffffff, 0x3);
+ break;
+ case 12:
+ halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55dd55dd,
+ 0x5ada5ada, 0xffffff, 0x3);
+ break;
+ case 13:
+ halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x5fff5fff,
+ 0xaaaaaaaa, 0xffffff, 0x3);
+ break;
+ case 14:
+ halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x5fff5fff,
+ 0x5ada5ada, 0xffffff, 0x3);
+ break;
+ case 15:
+ halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55dd55dd,
+ 0xaaaaaaaa, 0xffffff, 0x3);
+ break;
default:
break;
}
@@ -611,14 +797,18 @@ static void halbtc8723b1ant_sw_mechanism(struct btc_coexist *btcoexist,
}
static void halbtc8723b1ant_set_ant_path(struct btc_coexist *btcoexist,
- u8 ant_pos_type, bool init_hw_cfg,
- bool wifi_off)
+ u8 ant_pos_type, bool force_exec,
+ bool init_hw_cfg, bool wifi_off)
{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
struct btc_board_info *board_info = &btcoexist->board_info;
- u32 fw_ver = 0, u32tmp = 0;
+ u32 fw_ver = 0, u32tmp = 0, cnt_bt_cal_chk = 0;
bool pg_ext_switch = false;
bool use_ext_switch = false;
- u8 h2c_parameter[2] = {0};
+ bool is_in_mp_mode = false;
+ u8 h2c_parameter[2] = {0}, u8tmp = 0;
+
+ coex_dm->cur_ant_pos_type = ant_pos_type;
btcoexist->btc_get(btcoexist, BTC_GET_BL_EXT_SWITCH, &pg_ext_switch);
/* [31:16] = fw ver, [15:0] = fw sub ver */
@@ -628,24 +818,103 @@ static void halbtc8723b1ant_set_ant_path(struct btc_coexist *btcoexist,
use_ext_switch = true;
if (init_hw_cfg) {
- /*BT select s0/s1 is controlled by WiFi */
- btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, 0x20, 0x1);
+ /* WiFi TRx Mask on */
+ btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff,
+ 0x780);
+ /* remove due to interrupt is disabled that polling c2h will
+ * fail and delay 100ms.
+ */
- /*Force GNT_BT to Normal */
- btcoexist->btc_write_1byte_bitmask(btcoexist, 0x765, 0x18, 0x0);
- } else if (wifi_off) {
- /*Force GNT_BT to High */
- btcoexist->btc_write_1byte_bitmask(btcoexist, 0x765, 0x18, 0x3);
- /*BT select s0/s1 is controlled by BT */
+ if (fw_ver >= 0x180000) {
+ /* Use H2C to set GNT_BT to HIGH */
+ h2c_parameter[0] = 1;
+ btcoexist->btc_fill_h2c(btcoexist, 0x6E, 1,
+ h2c_parameter);
+ } else {
+ /* set grant_bt to high */
+ btcoexist->btc_write_1byte(btcoexist, 0x765, 0x18);
+ }
+ /* set wlan_act control by PTA */
+ btcoexist->btc_write_1byte(btcoexist, 0x76e, 0x4);
+
+ /* BT select s0/s1 is controlled by BT */
btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, 0x20, 0x0);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x39, 0x8, 0x1);
+ btcoexist->btc_write_1byte(btcoexist, 0x974, 0xff);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x944, 0x3, 0x3);
+ btcoexist->btc_write_1byte(btcoexist, 0x930, 0x77);
+ } else if (wifi_off) {
+ if (fw_ver >= 0x180000) {
+ /* Use H2C to set GNT_BT to HIGH */
+ h2c_parameter[0] = 1;
+ btcoexist->btc_fill_h2c(btcoexist, 0x6E, 1,
+ h2c_parameter);
+ } else {
+ /* set grant_bt to high */
+ btcoexist->btc_write_1byte(btcoexist, 0x765, 0x18);
+ }
+ /* set wlan_act to always low */
+ btcoexist->btc_write_1byte(btcoexist, 0x76e, 0x4);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_IS_IN_MP_MODE,
+ &is_in_mp_mode);
+ if (!is_in_mp_mode)
+ /* BT select s0/s1 is controlled by BT */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67,
+ 0x20, 0x0);
+ else
+ /* BT select s0/s1 is controlled by WiFi */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67,
+ 0x20, 0x1);
- /* 0x4c[24:23] = 00, Set Antenna control by BT_RFE_CTRL
- * BT Vendor 0xac = 0xf002
+ /* 0x4c[24:23]=00, Set Antenna control by BT_RFE_CTRL
+ * BT Vendor 0xac=0xf002
*/
u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c);
u32tmp &= ~BIT23;
u32tmp &= ~BIT24;
btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp);
+ } else {
+ /* Use H2C to set GNT_BT to LOW */
+ if (fw_ver >= 0x180000) {
+ if (btcoexist->btc_read_1byte(btcoexist, 0x765) != 0) {
+ h2c_parameter[0] = 0;
+ btcoexist->btc_fill_h2c(btcoexist, 0x6E, 1,
+ h2c_parameter);
+ }
+ } else {
+ /* BT calibration check */
+ while (cnt_bt_cal_chk <= 20) {
+ u8tmp = btcoexist->btc_read_1byte(btcoexist,
+ 0x49d);
+ cnt_bt_cal_chk++;
+ if (u8tmp & BIT(0)) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], ########### BT is calibrating (wait cnt=%d) ###########\n",
+ cnt_bt_cal_chk);
+ mdelay(50);
+ } else {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST,
+ DBG_LOUD,
+ "[BTCoex], ********** BT is NOT calibrating (wait cnt=%d)**********\n",
+ cnt_bt_cal_chk);
+ break;
+ }
+ }
+
+ /* set grant_bt to PTA */
+ btcoexist->btc_write_1byte(btcoexist, 0x765, 0x0);
+ }
+
+ if (btcoexist->btc_read_1byte(btcoexist, 0x76e) != 0xc) {
+ /* set wlan_act control by PTA */
+ btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc);
+ }
+
+ btcoexist->btc_write_1byte_bitmask(
+ btcoexist, 0x67, 0x20,
+ 0x1); /* BT select s0/s1 is controlled by WiFi */
}
if (use_ext_switch) {
@@ -658,216 +927,278 @@ static void halbtc8723b1ant_set_ant_path(struct btc_coexist *btcoexist,
u32tmp |= BIT24;
btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp);
+ /* fixed internal switch S1->WiFi, S0->BT */
+ btcoexist->btc_write_4byte(btcoexist, 0x948, 0x0);
+
if (board_info->btdm_ant_pos ==
BTC_ANTENNA_AT_MAIN_PORT) {
- /* Main Ant to BT for IPS case 0x4c[23] = 1 */
- btcoexist->btc_write_1byte_bitmask(btcoexist,
- 0x64, 0x1,
- 0x1);
-
/* tell firmware "no antenna inverse" */
h2c_parameter[0] = 0;
- h2c_parameter[1] = 1; /*ext switch type*/
+ /* ext switch type */
+ h2c_parameter[1] = 1;
btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
h2c_parameter);
} else {
- /* Aux Ant to BT for IPS case 0x4c[23] = 1 */
- btcoexist->btc_write_1byte_bitmask(btcoexist,
- 0x64, 0x1,
- 0x0);
-
/* tell firmware "antenna inverse" */
h2c_parameter[0] = 1;
- h2c_parameter[1] = 1; /* ext switch type */
+ /* ext switch type */
+ h2c_parameter[1] = 1;
btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
h2c_parameter);
}
}
- /* fixed internal switch first
- * fixed internal switch S1->WiFi, S0->BT
- */
- if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT)
- btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0);
- else /* fixed internal switch S0->WiFi, S1->BT */
- btcoexist->btc_write_2byte(btcoexist, 0x948, 0x280);
-
- /* ext switch setting */
- switch (ant_pos_type) {
- case BTC_ANT_PATH_WIFI:
- if (board_info->btdm_ant_pos ==
- BTC_ANTENNA_AT_MAIN_PORT)
- btcoexist->btc_write_1byte_bitmask(btcoexist,
- 0x92c, 0x3,
- 0x1);
- else
- btcoexist->btc_write_1byte_bitmask(btcoexist,
- 0x92c, 0x3,
- 0x2);
- break;
- case BTC_ANT_PATH_BT:
- if (board_info->btdm_ant_pos ==
- BTC_ANTENNA_AT_MAIN_PORT)
- btcoexist->btc_write_1byte_bitmask(btcoexist,
- 0x92c, 0x3,
- 0x2);
- else
- btcoexist->btc_write_1byte_bitmask(btcoexist,
- 0x92c, 0x3,
- 0x1);
- break;
- default:
- case BTC_ANT_PATH_PTA:
- if (board_info->btdm_ant_pos ==
- BTC_ANTENNA_AT_MAIN_PORT)
- btcoexist->btc_write_1byte_bitmask(btcoexist,
- 0x92c, 0x3,
- 0x1);
- else
- btcoexist->btc_write_1byte_bitmask(btcoexist,
- 0x92c, 0x3,
- 0x2);
- break;
+ if (force_exec ||
+ (coex_dm->cur_ant_pos_type != coex_dm->pre_ant_pos_type)) {
+ /* ext switch setting */
+ switch (ant_pos_type) {
+ case BTC_ANT_PATH_WIFI:
+ if (board_info->btdm_ant_pos ==
+ BTC_ANTENNA_AT_MAIN_PORT)
+ btcoexist->btc_write_1byte_bitmask(
+ btcoexist, 0x92c, 0x3, 0x1);
+ else
+ btcoexist->btc_write_1byte_bitmask(
+ btcoexist, 0x92c, 0x3, 0x2);
+ break;
+ case BTC_ANT_PATH_BT:
+ if (board_info->btdm_ant_pos ==
+ BTC_ANTENNA_AT_MAIN_PORT)
+ btcoexist->btc_write_1byte_bitmask(
+ btcoexist, 0x92c, 0x3, 0x2);
+ else
+ btcoexist->btc_write_1byte_bitmask(
+ btcoexist, 0x92c, 0x3, 0x1);
+ break;
+ default:
+ case BTC_ANT_PATH_PTA:
+ if (board_info->btdm_ant_pos ==
+ BTC_ANTENNA_AT_MAIN_PORT)
+ btcoexist->btc_write_1byte_bitmask(
+ btcoexist, 0x92c, 0x3, 0x1);
+ else
+ btcoexist->btc_write_1byte_bitmask(
+ btcoexist, 0x92c, 0x3, 0x2);
+ break;
+ }
}
-
} else {
if (init_hw_cfg) {
- /* 0x4c[23] = 1, 0x4c[24] = 0 Antenna control by 0x64 */
+ /* 0x4c[23] = 1, 0x4c[24] = 0,
+ * Antenna control by 0x64
+ */
u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c);
u32tmp |= BIT23;
u32tmp &= ~BIT24;
btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp);
+ /* Fix Ext switch Main->S1, Aux->S0 */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x64, 0x1,
+ 0x0);
+
if (board_info->btdm_ant_pos ==
BTC_ANTENNA_AT_MAIN_PORT) {
- /* Main Ant to WiFi for IPS case 0x4c[23] = 1 */
- btcoexist->btc_write_1byte_bitmask(btcoexist,
- 0x64, 0x1,
- 0x0);
-
/* tell firmware "no antenna inverse" */
h2c_parameter[0] = 0;
- h2c_parameter[1] = 0; /* internal switch type */
+ /* internal switch type */
+ h2c_parameter[1] = 0;
btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
h2c_parameter);
} else {
- /* Aux Ant to BT for IPS case 0x4c[23] = 1 */
- btcoexist->btc_write_1byte_bitmask(btcoexist,
- 0x64, 0x1,
- 0x1);
-
/* tell firmware "antenna inverse" */
h2c_parameter[0] = 1;
- h2c_parameter[1] = 0; /* internal switch type */
+ /* internal switch type */
+ h2c_parameter[1] = 0;
btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
h2c_parameter);
}
}
- /* fixed external switch first
- * Main->WiFi, Aux->BT
- */
- if (board_info->btdm_ant_pos ==
- BTC_ANTENNA_AT_MAIN_PORT)
- btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c,
- 0x3, 0x1);
- else /* Main->BT, Aux->WiFi */
- btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c,
- 0x3, 0x2);
-
- /* internal switch setting */
- switch (ant_pos_type) {
- case BTC_ANT_PATH_WIFI:
- if (board_info->btdm_ant_pos ==
- BTC_ANTENNA_AT_MAIN_PORT)
- btcoexist->btc_write_2byte(btcoexist, 0x948,
- 0x0);
- else
- btcoexist->btc_write_2byte(btcoexist, 0x948,
- 0x280);
- break;
- case BTC_ANT_PATH_BT:
- if (board_info->btdm_ant_pos ==
- BTC_ANTENNA_AT_MAIN_PORT)
- btcoexist->btc_write_2byte(btcoexist, 0x948,
- 0x280);
- else
- btcoexist->btc_write_2byte(btcoexist, 0x948,
- 0x0);
- break;
- default:
- case BTC_ANT_PATH_PTA:
- if (board_info->btdm_ant_pos ==
- BTC_ANTENNA_AT_MAIN_PORT)
- btcoexist->btc_write_2byte(btcoexist, 0x948,
- 0x200);
- else
- btcoexist->btc_write_2byte(btcoexist, 0x948,
- 0x80);
- break;
+ if (force_exec ||
+ (coex_dm->cur_ant_pos_type != coex_dm->pre_ant_pos_type)) {
+ /* internal switch setting */
+ switch (ant_pos_type) {
+ case BTC_ANT_PATH_WIFI:
+ if (board_info->btdm_ant_pos ==
+ BTC_ANTENNA_AT_MAIN_PORT)
+ btcoexist->btc_write_4byte(btcoexist,
+ 0x948, 0x0);
+ else
+ btcoexist->btc_write_4byte(btcoexist,
+ 0x948, 0x280);
+ break;
+ case BTC_ANT_PATH_BT:
+ if (board_info->btdm_ant_pos ==
+ BTC_ANTENNA_AT_MAIN_PORT)
+ btcoexist->btc_write_4byte(btcoexist,
+ 0x948, 0x280);
+ else
+ btcoexist->btc_write_4byte(btcoexist,
+ 0x948, 0x0);
+ break;
+ default:
+ case BTC_ANT_PATH_PTA:
+ if (board_info->btdm_ant_pos ==
+ BTC_ANTENNA_AT_MAIN_PORT)
+ btcoexist->btc_write_4byte(btcoexist,
+ 0x948, 0x200);
+ else
+ btcoexist->btc_write_4byte(btcoexist,
+ 0x948, 0x80);
+ break;
+ }
}
}
+
+ coex_dm->pre_ant_pos_type = coex_dm->cur_ant_pos_type;
}
static void halbtc8723b1ant_ps_tdma(struct btc_coexist *btcoexist,
bool force_exec, bool turn_on, u8 type)
{
- struct rtl_priv *rtlpriv = btcoexist->adapter;
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
bool wifi_busy = false;
u8 rssi_adjust_val = 0;
+ u8 ps_tdma_byte0_val = 0x51;
+ u8 ps_tdma_byte3_val = 0x10;
+ u8 ps_tdma_byte4_val = 0x50;
+ s8 wifi_duration_adjust = 0x0;
+ static bool pre_wifi_busy;
coex_dm->cur_ps_tdma_on = turn_on;
coex_dm->cur_ps_tdma = type;
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
- if (!force_exec) {
- if (coex_dm->cur_ps_tdma_on)
- RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
- "[BTCoex], ******** TDMA(on, %d) *********\n",
- coex_dm->cur_ps_tdma);
- else
- RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
- "[BTCoex], ******** TDMA(off, %d) ********\n",
- coex_dm->cur_ps_tdma);
+ if (wifi_busy != pre_wifi_busy) {
+ force_exec = true;
+ pre_wifi_busy = wifi_busy;
+ }
+ if (!force_exec) {
if ((coex_dm->pre_ps_tdma_on == coex_dm->cur_ps_tdma_on) &&
(coex_dm->pre_ps_tdma == coex_dm->cur_ps_tdma))
return;
}
+
+ if (coex_sta->scan_ap_num <= 5) {
+ wifi_duration_adjust = 5;
+
+ if (coex_sta->a2dp_bit_pool >= 35)
+ wifi_duration_adjust = -10;
+ else if (coex_sta->a2dp_bit_pool >= 45)
+ wifi_duration_adjust = -15;
+ } else if (coex_sta->scan_ap_num >= 40) {
+ wifi_duration_adjust = -15;
+
+ if (coex_sta->a2dp_bit_pool < 35)
+ wifi_duration_adjust = -5;
+ else if (coex_sta->a2dp_bit_pool < 45)
+ wifi_duration_adjust = -10;
+ } else if (coex_sta->scan_ap_num >= 20) {
+ wifi_duration_adjust = -10;
+
+ if (coex_sta->a2dp_bit_pool >= 45)
+ wifi_duration_adjust = -15;
+ } else {
+ wifi_duration_adjust = 0;
+
+ if (coex_sta->a2dp_bit_pool >= 35)
+ wifi_duration_adjust = -10;
+ else if (coex_sta->a2dp_bit_pool >= 45)
+ wifi_duration_adjust = -15;
+ }
+
+ if ((type == 1) || (type == 2) || (type == 9) || (type == 11) ||
+ (type == 101) || (type == 102) || (type == 109) || (type == 101)) {
+ if (!coex_sta->force_lps_on) {
+ /* Native power save TDMA, only for A2DP-only case
+ * 1/2/9/11 while wifi noisy threshold > 30
+ */
+
+ /* no null-pkt */
+ ps_tdma_byte0_val = 0x61;
+ /* no tx-pause at BT-slot */
+ ps_tdma_byte3_val = 0x11;
+ /* 0x778 = d/1 toggle, no dynamic slot */
+ ps_tdma_byte4_val = 0x10;
+ } else {
+ /* null-pkt */
+ ps_tdma_byte0_val = 0x51;
+ /* tx-pause at BT-slot */
+ ps_tdma_byte3_val = 0x10;
+ /* 0x778 = d/1 toggle, dynamic slot */
+ ps_tdma_byte4_val = 0x50;
+ }
+ } else if ((type == 3) || (type == 13) || (type == 14) ||
+ (type == 103) || (type == 113) || (type == 114)) {
+ /* null-pkt */
+ ps_tdma_byte0_val = 0x51;
+ /* tx-pause at BT-slot */
+ ps_tdma_byte3_val = 0x10;
+ /* 0x778 = d/1 toggle, no dynamic slot */
+ ps_tdma_byte4_val = 0x10;
+ } else { /* native power save case */
+ /* no null-pkt */
+ ps_tdma_byte0_val = 0x61;
+ /* no tx-pause at BT-slot */
+ ps_tdma_byte3_val = 0x11;
+ /* 0x778 = d/1 toggle, no dynamic slot */
+ ps_tdma_byte4_val = 0x11;
+ /* psTdmaByte4Va is not define for 0x778 = d/1, 1/1 case */
+ }
+
+ /* if (bt_link_info->slave_role) */
+ if ((bt_link_info->slave_role) && (bt_link_info->a2dp_exist))
+ /* 0x778 = 0x1 at wifi slot (no blocking BT Low-Pri pkts) */
+ ps_tdma_byte4_val = ps_tdma_byte4_val | 0x1;
+
+ if (type > 100) {
+ /* set antenna control by SW */
+ ps_tdma_byte0_val = ps_tdma_byte0_val | 0x82;
+ /* set antenna no toggle, control by antenna diversity */
+ ps_tdma_byte3_val = ps_tdma_byte3_val | 0x60;
+ }
+
if (turn_on) {
switch (type) {
default:
halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x1a,
- 0x1a, 0x0, 0x50);
+ 0x1a, 0x0,
+ ps_tdma_byte4_val);
break;
case 1:
- halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x3a,
- 0x03, 0x10, 0x50);
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, ps_tdma_byte0_val,
+ 0x3a + wifi_duration_adjust, 0x03,
+ ps_tdma_byte3_val, ps_tdma_byte4_val);
rssi_adjust_val = 11;
break;
case 2:
- halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x2b,
- 0x03, 0x10, 0x50);
- rssi_adjust_val = 14;
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, ps_tdma_byte0_val,
+ 0x2d + wifi_duration_adjust, 0x03,
+ ps_tdma_byte3_val, ps_tdma_byte4_val);
break;
case 3:
- halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x1d,
- 0x1d, 0x0, 0x52);
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, ps_tdma_byte0_val, 0x30, 0x03,
+ ps_tdma_byte3_val, ps_tdma_byte4_val);
break;
case 4:
halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x15,
- 0x3, 0x14, 0x0);
- rssi_adjust_val = 17;
+ 0x3, 0x14, 0x0);
break;
case 5:
- halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x15,
- 0x3, 0x11, 0x10);
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, ps_tdma_byte0_val, 0x1f, 0x3,
+ ps_tdma_byte3_val, 0x11);
break;
case 6:
- halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x20,
- 0x3, 0x11, 0x13);
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, ps_tdma_byte0_val, 0x20, 0x3,
+ ps_tdma_byte3_val, 0x11);
break;
case 7:
halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xc,
@@ -875,33 +1206,44 @@ static void halbtc8723b1ant_ps_tdma(struct btc_coexist *btcoexist,
break;
case 8:
halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x25,
- 0x3, 0x10, 0x0);
+ 0x3, 0x10, 0x0);
break;
case 9:
- halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x21,
- 0x3, 0x10, 0x50);
- rssi_adjust_val = 18;
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, ps_tdma_byte0_val, 0x21, 0x3,
+ ps_tdma_byte3_val, ps_tdma_byte4_val);
break;
case 10:
halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xa,
0xa, 0x0, 0x40);
break;
case 11:
- halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x15,
- 0x03, 0x10, 0x50);
- rssi_adjust_val = 20;
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, ps_tdma_byte0_val, 0x21, 0x03,
+ ps_tdma_byte3_val, ps_tdma_byte4_val);
break;
case 12:
halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x0a,
- 0x0a, 0x0, 0x50);
+ 0x0a, 0x0, 0x50);
break;
case 13:
- halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x15,
- 0x15, 0x0, 0x50);
+ if (coex_sta->scan_ap_num <= 3)
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, ps_tdma_byte0_val, 0x40, 0x3,
+ ps_tdma_byte3_val, ps_tdma_byte4_val);
+ else
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, ps_tdma_byte0_val, 0x21, 0x3,
+ ps_tdma_byte3_val, ps_tdma_byte4_val);
break;
case 14:
- halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x21,
- 0x3, 0x10, 0x52);
+ if (coex_sta->scan_ap_num <= 3)
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, 0x51, 0x30, 0x3, 0x10, 0x50);
+ else
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, ps_tdma_byte0_val, 0x21, 0x3,
+ ps_tdma_byte3_val, ps_tdma_byte4_val);
break;
case 15:
halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xa,
@@ -909,103 +1251,173 @@ static void halbtc8723b1ant_ps_tdma(struct btc_coexist *btcoexist,
break;
case 16:
halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x15,
- 0x3, 0x10, 0x0);
- rssi_adjust_val = 18;
+ 0x3, 0x10, 0x0);
break;
case 18:
halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x25,
- 0x3, 0x10, 0x0);
- rssi_adjust_val = 14;
+ 0x3, 0x10, 0x0);
break;
case 20:
- halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x35,
- 0x03, 0x11, 0x10);
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, ps_tdma_byte0_val, 0x3f, 0x03,
+ ps_tdma_byte3_val, 0x10);
break;
case 21:
halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x25,
- 0x03, 0x11, 0x11);
+ 0x03, 0x11, 0x11);
break;
case 22:
- halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x25,
- 0x03, 0x11, 0x10);
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, ps_tdma_byte0_val, 0x25, 0x03,
+ ps_tdma_byte3_val, 0x10);
break;
case 23:
halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25,
- 0x3, 0x31, 0x18);
- rssi_adjust_val = 22;
+ 0x3, 0x31, 0x18);
break;
case 24:
halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x15,
- 0x3, 0x31, 0x18);
- rssi_adjust_val = 22;
+ 0x3, 0x31, 0x18);
break;
case 25:
halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa,
0x3, 0x31, 0x18);
- rssi_adjust_val = 22;
break;
case 26:
halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa,
0x3, 0x31, 0x18);
- rssi_adjust_val = 22;
break;
case 27:
halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25,
- 0x3, 0x31, 0x98);
- rssi_adjust_val = 22;
+ 0x3, 0x31, 0x98);
break;
case 28:
halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x69, 0x25,
- 0x3, 0x31, 0x0);
+ 0x3, 0x31, 0x0);
break;
case 29:
halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xab, 0x1a,
- 0x1a, 0x1, 0x10);
+ 0x1a, 0x1, 0x10);
break;
case 30:
- halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x14,
- 0x3, 0x10, 0x50);
+ halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x30,
+ 0x3, 0x10, 0x10);
break;
case 31:
halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x1a,
- 0x1a, 0, 0x58);
+ 0x1a, 0, 0x58);
break;
case 32:
- halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x61, 0xa,
- 0x3, 0x10, 0x0);
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, ps_tdma_byte0_val, 0x35, 0x3,
+ ps_tdma_byte3_val, ps_tdma_byte4_val);
break;
case 33:
- halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xa3, 0x25,
- 0x3, 0x30, 0x90);
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, ps_tdma_byte0_val, 0x35, 0x3,
+ ps_tdma_byte3_val, 0x10);
break;
case 34:
halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x53, 0x1a,
- 0x1a, 0x0, 0x10);
+ 0x1a, 0x0, 0x10);
break;
case 35:
halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x63, 0x1a,
- 0x1a, 0x0, 0x10);
+ 0x1a, 0x0, 0x10);
break;
case 36:
halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x12,
- 0x3, 0x14, 0x50);
+ 0x3, 0x14, 0x50);
break;
- /* SoftAP only with no sta associated, BT disable,
- * TDMA mode for power saving
- * here softap mode screen off will cost 70-80mA for phone
- */
case 40:
+ /* SoftAP only with no sta associated,BT disable ,TDMA
+ * mode for power saving
+ *
+ * here softap mode screen off will cost 70-80mA for
+ * phone
+ */
halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x23, 0x18,
- 0x00, 0x10, 0x24);
+ 0x00, 0x10, 0x24);
+ break;
+
+ case 101:
+ /* for 1-Ant translate to 2-Ant */
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, ps_tdma_byte0_val,
+ 0x3a + wifi_duration_adjust, 0x03,
+ ps_tdma_byte3_val, ps_tdma_byte4_val);
+ break;
+ case 102:
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, ps_tdma_byte0_val,
+ 0x2d + wifi_duration_adjust, 0x03,
+ ps_tdma_byte3_val, ps_tdma_byte4_val);
+ break;
+ case 103:
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, ps_tdma_byte0_val, 0x3a, 0x03,
+ ps_tdma_byte3_val, ps_tdma_byte4_val);
+ break;
+ case 105:
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, ps_tdma_byte0_val, 0x15, 0x3,
+ ps_tdma_byte3_val, 0x11);
+ break;
+ case 106:
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, ps_tdma_byte0_val, 0x20, 0x3,
+ ps_tdma_byte3_val, 0x11);
+ break;
+ case 109:
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, ps_tdma_byte0_val, 0x21, 0x3,
+ ps_tdma_byte3_val, ps_tdma_byte4_val);
+ break;
+ case 111:
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, ps_tdma_byte0_val, 0x21, 0x03,
+ ps_tdma_byte3_val, ps_tdma_byte4_val);
+ break;
+ case 113:
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, ps_tdma_byte0_val, 0x21, 0x3,
+ ps_tdma_byte3_val, ps_tdma_byte4_val);
+ break;
+ case 114:
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, ps_tdma_byte0_val, 0x21, 0x3,
+ ps_tdma_byte3_val, ps_tdma_byte4_val);
+ break;
+ case 120:
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, ps_tdma_byte0_val, 0x3f, 0x03,
+ ps_tdma_byte3_val, 0x10);
+ break;
+ case 122:
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, ps_tdma_byte0_val, 0x25, 0x03,
+ ps_tdma_byte3_val, 0x10);
+ break;
+ case 132:
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, ps_tdma_byte0_val, 0x25, 0x03,
+ ps_tdma_byte3_val, ps_tdma_byte4_val);
+ break;
+ case 133:
+ halbtc8723b1ant_set_fw_ps_tdma(
+ btcoexist, ps_tdma_byte0_val, 0x25, 0x03,
+ ps_tdma_byte3_val, 0x11);
break;
}
} else {
+ /* disable PS tdma */
switch (type) {
case 8: /* PTA Control */
halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x8, 0x0,
0x0, 0x0, 0x0);
halbtc8723b1ant_set_ant_path(btcoexist,
BTC_ANT_PATH_PTA,
+ FORCE_EXEC,
false, false);
break;
case 0:
@@ -1013,17 +1425,10 @@ static void halbtc8723b1ant_ps_tdma(struct btc_coexist *btcoexist,
/* Software control, Antenna at BT side */
halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0,
0x0, 0x0, 0x0);
- halbtc8723b1ant_set_ant_path(btcoexist,
- BTC_ANT_PATH_BT,
- false, false);
break;
- case 9:
- /* Software control, Antenna at WiFi side */
- halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0,
- 0x0, 0x0, 0x0);
- halbtc8723b1ant_set_ant_path(btcoexist,
- BTC_ANT_PATH_WIFI,
- false, false);
+ case 1: /* 2-Ant, 0x778=3, antenna control by ant diversity */
+ halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0,
+ 0x48, 0x0);
break;
}
}
@@ -1037,8 +1442,191 @@ static void halbtc8723b1ant_ps_tdma(struct btc_coexist *btcoexist,
coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma;
}
+void btc8723b1ant_tdma_dur_adj_for_acl(struct btc_coexist *btcoexist,
+ u8 wifi_status)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ static s32 up, dn, m, n, wait_count;
+ /* 0: no change, +1: increase WiFi duration,
+ * -1: decrease WiFi duration
+ */
+ s32 result;
+ u8 retry_count = 0, bt_info_ext;
+ bool wifi_busy = false;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], TdmaDurationAdjustForAcl()\n");
+
+ if (wifi_status == BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY)
+ wifi_busy = true;
+ else
+ wifi_busy = false;
+
+ if ((wifi_status ==
+ BT_8723B_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN) ||
+ (wifi_status == BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN) ||
+ (wifi_status == BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT)) {
+ if (coex_dm->cur_ps_tdma != 1 && coex_dm->cur_ps_tdma != 2 &&
+ coex_dm->cur_ps_tdma != 3 && coex_dm->cur_ps_tdma != 9) {
+ halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+ true, 9);
+ coex_dm->ps_tdma_du_adj_type = 9;
+
+ up = 0;
+ dn = 0;
+ m = 1;
+ n = 3;
+ result = 0;
+ wait_count = 0;
+ }
+ return;
+ }
+
+ if (!coex_dm->auto_tdma_adjust) {
+ coex_dm->auto_tdma_adjust = true;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], first run TdmaDurationAdjust()!!\n");
+
+ halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 2);
+ coex_dm->ps_tdma_du_adj_type = 2;
+
+ up = 0;
+ dn = 0;
+ m = 1;
+ n = 3;
+ result = 0;
+ wait_count = 0;
+ } else {
+ /* acquire the BT TRx retry count from BT_Info byte2 */
+ retry_count = coex_sta->bt_retry_cnt;
+ bt_info_ext = coex_sta->bt_info_ext;
+
+ if ((coex_sta->low_priority_tx) > 1050 ||
+ (coex_sta->low_priority_rx) > 1250)
+ retry_count++;
+
+ result = 0;
+ wait_count++;
+ /* no retry in the last 2-second duration */
+ if (retry_count == 0) {
+ up++;
+ dn--;
+
+ if (dn <= 0)
+ dn = 0;
+
+ if (up >= n) {
+ /* if retry count during continuous n*2 seconds
+ * is 0, enlarge WiFi duration
+ */
+ wait_count = 0;
+ n = 3;
+ up = 0;
+ dn = 0;
+ result = 1;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Increase wifi duration!!\n");
+ }
+ } else if (retry_count <= 3) {
+ /* <=3 retry in the last 2-second duration */
+ up--;
+ dn++;
+
+ if (up <= 0)
+ up = 0;
+
+ if (dn == 2) {
+ /* if continuous 2 retry count(every 2 seconds)
+ * >0 and < 3, reduce WiFi duration
+ */
+ if (wait_count <= 2)
+ /* avoid loop between the two levels */
+ m++;
+ else
+ m = 1;
+
+ if (m >= 20)
+ /* maximum of m = 20 ' will recheck if
+ * need to adjust wifi duration in
+ * maximum time interval 120 seconds
+ */
+ m = 20;
+
+ n = 3 * m;
+ up = 0;
+ dn = 0;
+ wait_count = 0;
+ result = -1;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Decrease wifi duration for retryCounter<3!!\n");
+ }
+ } else {
+ /* retry count > 3, once retry count > 3, to reduce
+ * WiFi duration
+ */
+ if (wait_count == 1)
+ /* to avoid loop between the two levels */
+ m++;
+ else
+ m = 1;
+
+ if (m >= 20)
+ /* maximum of m = 20 ' will recheck if need to
+ * adjust wifi duration in maximum time interval
+ * 120 seconds
+ */
+ m = 20;
+
+ n = 3 * m;
+ up = 0;
+ dn = 0;
+ wait_count = 0;
+ result = -1;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Decrease wifi duration for retryCounter>3!!\n");
+ }
+
+ if (result == -1) {
+ if (coex_dm->cur_ps_tdma == 1) {
+ halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+ true, 2);
+ coex_dm->ps_tdma_du_adj_type = 2;
+ } else if (coex_dm->cur_ps_tdma == 2) {
+ halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+ true, 9);
+ coex_dm->ps_tdma_du_adj_type = 9;
+ } else if (coex_dm->cur_ps_tdma == 9) {
+ halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+ true, 11);
+ coex_dm->ps_tdma_du_adj_type = 11;
+ }
+ } else if (result == 1) {
+ if (coex_dm->cur_ps_tdma == 11) {
+ halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+ true, 9);
+ coex_dm->ps_tdma_du_adj_type = 9;
+ } else if (coex_dm->cur_ps_tdma == 9) {
+ halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+ true, 2);
+ coex_dm->ps_tdma_du_adj_type = 2;
+ } else if (coex_dm->cur_ps_tdma == 2) {
+ halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
+ true, 1);
+ coex_dm->ps_tdma_du_adj_type = 1;
+ }
+ }
+
+ if (coex_dm->cur_ps_tdma != 1 && coex_dm->cur_ps_tdma != 2 &&
+ coex_dm->cur_ps_tdma != 9 && coex_dm->cur_ps_tdma != 11) {
+ /* recover to previous adjust type */
+ halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ coex_dm->ps_tdma_du_adj_type);
+ }
+ }
+}
+
static void halbtc8723b1ant_ps_tdma_chk_pwr_save(struct btc_coexist *btcoexist,
- bool new_ps_state)
+ bool new_ps_state)
{
u8 lps_mode = 0x0;
@@ -1078,6 +1666,7 @@ static void halbtc8723b1ant_power_save_state(struct btc_coexist *btcoexist,
btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
&low_pwr_disable);
btcoexist->btc_set(btcoexist, BTC_SET_ACT_NORMAL_LPS, NULL);
+ coex_sta->force_lps_on = false;
break;
case BTC_PS_LPS_ON:
halbtc8723b1ant_ps_tdma_chk_pwr_save(btcoexist, true);
@@ -1089,27 +1678,95 @@ static void halbtc8723b1ant_power_save_state(struct btc_coexist *btcoexist,
&low_pwr_disable);
/* power save must executed before psTdma */
btcoexist->btc_set(btcoexist, BTC_SET_ACT_ENTER_LPS, NULL);
+ coex_sta->force_lps_on = true;
break;
case BTC_PS_LPS_OFF:
halbtc8723b1ant_ps_tdma_chk_pwr_save(btcoexist, false);
btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL);
+ coex_sta->force_lps_on = false;
break;
default:
break;
}
}
+static void halbtc8723b1ant_action_wifi_only(struct btc_coexist *btcoexist)
+{
+ halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0);
+ halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8);
+ halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA,
+ FORCE_EXEC, false, false);
+}
+
+/* check if BT is disabled */
+static void halbtc8723b1ant_monitor_bt_enable_disable(struct btc_coexist
+ *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ static u32 bt_disable_cnt;
+ bool bt_active = true, bt_disabled = false;
+
+ if (coex_sta->high_priority_tx == 0 &&
+ coex_sta->high_priority_rx == 0 && coex_sta->low_priority_tx == 0 &&
+ coex_sta->low_priority_rx == 0)
+ bt_active = false;
+ if (coex_sta->high_priority_tx == 0xffff &&
+ coex_sta->high_priority_rx == 0xffff &&
+ coex_sta->low_priority_tx == 0xffff &&
+ coex_sta->low_priority_rx == 0xffff)
+ bt_active = false;
+ if (bt_active) {
+ bt_disable_cnt = 0;
+ bt_disabled = false;
+ } else {
+ bt_disable_cnt++;
+ if (bt_disable_cnt >= 2)
+ bt_disabled = true;
+ }
+ if (coex_sta->bt_disabled != bt_disabled) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], BT is from %s to %s!!\n",
+ (coex_sta->bt_disabled ? "disabled" : "enabled"),
+ (bt_disabled ? "disabled" : "enabled"));
+
+ coex_sta->bt_disabled = bt_disabled;
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_DISABLE,
+ &bt_disabled);
+ if (bt_disabled) {
+ halbtc8723b1ant_action_wifi_only(btcoexist);
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS,
+ NULL);
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_NORMAL_LPS,
+ NULL);
+ }
+ }
+}
+
/*****************************************************
*
* Non-Software Coex Mechanism start
*
*****************************************************/
+
+static void halbtc8723b1ant_action_bt_whck_test(struct btc_coexist *btcoexist)
+{
+ halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0,
+ 0x0);
+
+ halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
+ halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC,
+ false, false);
+ halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+}
+
static void halbtc8723b1ant_action_wifi_multiport(struct btc_coexist *btcoexist)
{
halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
0x0, 0x0);
halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
+ halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC,
+ false, false);
halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
}
@@ -1123,35 +1780,56 @@ static void halbtc8723b1ant_action_bt_inquiry(struct btc_coexist *btcoexist)
{
struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
bool wifi_connected = false, ap_enable = false;
+ bool wifi_busy = false, bt_busy = false;
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
&ap_enable);
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
&wifi_connected);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy);
- if (!wifi_connected) {
- halbtc8723b1ant_power_save_state(btcoexist,
- BTC_PS_WIFI_NATIVE, 0x0, 0x0);
+ if (coex_sta->bt_abnormal_scan) {
+ halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 33);
+ halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7);
+ } else if (!wifi_connected && !coex_sta->wifi_is_high_pri_task) {
+ halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
+ 0x0, 0x0);
halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
- halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
- } else if (bt_link_info->sco_exist || bt_link_info->hid_only) {
- /* SCO/HID-only busy */
+ halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA,
+ NORMAL_EXEC, false, false);
+ halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+ } else if (bt_link_info->sco_exist || bt_link_info->hid_exist ||
+ bt_link_info->a2dp_exist) {
+ /* SCO/HID/A2DP busy */
halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
0x0, 0x0);
- halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32);
- halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
- } else {
- if (ap_enable)
- halbtc8723b1ant_power_save_state(btcoexist,
- BTC_PS_WIFI_NATIVE,
- 0x0, 0x0);
+ if (coex_sta->c2h_bt_remote_name_req)
+ halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 33);
else
- halbtc8723b1ant_power_save_state(btcoexist,
- BTC_PS_LPS_ON,
- 0x50, 0x4);
+ halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 32);
+
+ halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
+ } else if (bt_link_info->pan_exist || wifi_busy) {
+ halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
+ 0x0, 0x0);
+ if (coex_sta->c2h_bt_remote_name_req)
+ halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 33);
+ else
+ halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
+ 32);
- halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 30);
- halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
+ halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
+ } else {
+ halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
+ 0x0, 0x0);
+ halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
+ halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA,
+ NORMAL_EXEC, false, false);
+ halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7);
}
}
@@ -1167,7 +1845,7 @@ static void btc8723b1ant_act_bt_sco_hid_only_busy(struct btc_coexist *btcoexist,
/* tdma and coex table */
if (bt_link_info->sco_exist) {
halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5);
- halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
+ halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 5);
} else {
/* HID */
halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 6);
@@ -1181,6 +1859,10 @@ static void halbtc8723b1ant_action_wifi_connected_bt_acl_busy(
{
struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+ if ((coex_sta->low_priority_rx >= 950) && (!coex_sta->under_ips))
+ bt_link_info->slave_role = true;
+ else
+ bt_link_info->slave_role = false;
if (bt_link_info->hid_only) { /* HID */
btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist, wifi_status);
@@ -1189,39 +1871,40 @@ static void halbtc8723b1ant_action_wifi_connected_bt_acl_busy(
} else if (bt_link_info->a2dp_only) { /* A2DP */
if (wifi_status == BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE) {
halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
- false, 8);
+ true, 32);
halbtc8723b1ant_coex_table_with_type(btcoexist,
- NORMAL_EXEC, 2);
+ NORMAL_EXEC, 4);
coex_dm->auto_tdma_adjust = false;
- } else { /* for low BT RSSI */
- halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
- true, 11);
+ } else {
+ btc8723b1ant_tdma_dur_adj_for_acl(btcoexist,
+ wifi_status);
halbtc8723b1ant_coex_table_with_type(btcoexist,
NORMAL_EXEC, 1);
- coex_dm->auto_tdma_adjust = false;
+ coex_dm->auto_tdma_adjust = true;
}
- } else if (bt_link_info->hid_exist &&
- bt_link_info->a2dp_exist) { /* HID + A2DP */
+ } else if (((bt_link_info->a2dp_exist) && (bt_link_info->pan_exist)) ||
+ (bt_link_info->hid_exist && bt_link_info->a2dp_exist &&
+ bt_link_info->pan_exist)) {
+ /* A2DP + PAN(OPP,FTP), HID + A2DP + PAN(OPP,FTP) */
+ halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 13);
+ halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
+ coex_dm->auto_tdma_adjust = false;
+ } else if (bt_link_info->hid_exist && bt_link_info->a2dp_exist) {
+ /* HID + A2DP */
halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14);
coex_dm->auto_tdma_adjust = false;
- halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 6);
- /* PAN(OPP,FTP), HID + PAN(OPP,FTP) */
+ halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
} else if (bt_link_info->pan_only ||
- (bt_link_info->hid_exist && bt_link_info->pan_exist)) {
+ (bt_link_info->hid_exist && bt_link_info->pan_exist)) {
+ /* PAN(OPP,FTP), HID + PAN(OPP,FTP) */
halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3);
- halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 6);
- coex_dm->auto_tdma_adjust = false;
- /* A2DP + PAN(OPP,FTP), HID + A2DP + PAN(OPP,FTP) */
- } else if ((bt_link_info->a2dp_exist && bt_link_info->pan_exist) ||
- (bt_link_info->hid_exist && bt_link_info->a2dp_exist &&
- bt_link_info->pan_exist)) {
- halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 13);
- halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
+ halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
coex_dm->auto_tdma_adjust = false;
} else {
- halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11);
- halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
+ /* BT no-profile busy (0x9) */
+ halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 33);
+ halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
coex_dm->auto_tdma_adjust = false;
}
}
@@ -1233,7 +1916,9 @@ static void btc8723b1ant_action_wifi_not_conn(struct btc_coexist *btcoexist)
0x0, 0x0);
/* tdma and coex table */
- halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
+ halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8);
+ halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, NORMAL_EXEC,
+ false, false);
halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
}
@@ -1246,30 +1931,31 @@ btc8723b1ant_action_wifi_not_conn_scan(struct btc_coexist *btcoexist)
0x0, 0x0);
/* tdma and coex table */
- if (BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) {
- if (bt_link_info->a2dp_exist && bt_link_info->pan_exist) {
+ if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_BUSY) {
+ if (bt_link_info->a2dp_exist) {
halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
- true, 22);
+ true, 32);
halbtc8723b1ant_coex_table_with_type(btcoexist,
- NORMAL_EXEC, 1);
- } else if (bt_link_info->pan_only) {
+ NORMAL_EXEC, 4);
+ } else if (bt_link_info->a2dp_exist) {
halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
- true, 20);
+ true, 22);
halbtc8723b1ant_coex_table_with_type(btcoexist,
- NORMAL_EXEC, 2);
+ NORMAL_EXEC, 4);
} else {
halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
true, 20);
halbtc8723b1ant_coex_table_with_type(btcoexist,
NORMAL_EXEC, 1);
}
- } else if ((BT_8723B_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) ||
- (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY ==
- coex_dm->bt_status)){
+ } else if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_SCO_BUSY ||
+ coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY){
btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist,
BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN);
} else {
halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
+ halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA,
+ NORMAL_EXEC, false, false);
halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
}
}
@@ -1282,14 +1968,19 @@ btc8723b1ant_act_wifi_not_conn_asso_auth(struct btc_coexist *btcoexist)
halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
0x0, 0x0);
- if ((BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE == coex_dm->bt_status) ||
- (bt_link_info->sco_exist) || (bt_link_info->hid_only) ||
- (bt_link_info->a2dp_only) || (bt_link_info->pan_only)) {
- halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
- halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7);
- } else {
+ /* tdma and coex table */
+ if ((bt_link_info->sco_exist) || (bt_link_info->hid_exist) ||
+ (bt_link_info->a2dp_exist)) {
+ halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32);
+ halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 4);
+ } else if (bt_link_info->pan_exist) {
halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20);
- halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
+ halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 4);
+ } else {
+ halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
+ halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA,
+ NORMAL_EXEC, false, false);
+ halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 2);
}
}
@@ -1301,30 +1992,32 @@ static void btc8723b1ant_action_wifi_conn_scan(struct btc_coexist *btcoexist)
0x0, 0x0);
/* tdma and coex table */
- if (BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) {
- if (bt_link_info->a2dp_exist && bt_link_info->pan_exist) {
+ if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_BUSY) {
+ if (bt_link_info->a2dp_exist) {
halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
- true, 22);
+ true, 32);
halbtc8723b1ant_coex_table_with_type(btcoexist,
- NORMAL_EXEC, 1);
- } else if (bt_link_info->pan_only) {
+ NORMAL_EXEC, 4);
+ } else if (bt_link_info->a2dp_exist &&
+ bt_link_info->pan_exist) {
halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
- true, 20);
+ true, 22);
halbtc8723b1ant_coex_table_with_type(btcoexist,
- NORMAL_EXEC, 2);
+ NORMAL_EXEC, 4);
} else {
halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
true, 20);
halbtc8723b1ant_coex_table_with_type(btcoexist,
- NORMAL_EXEC, 1);
+ NORMAL_EXEC, 4);
}
- } else if ((BT_8723B_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) ||
- (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY ==
- coex_dm->bt_status)) {
+ } else if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_SCO_BUSY ||
+ coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY) {
btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist,
BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN);
} else {
halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
+ halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA,
+ NORMAL_EXEC, false, false);
halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
}
}
@@ -1332,23 +2025,34 @@ static void btc8723b1ant_action_wifi_conn_scan(struct btc_coexist *btcoexist)
static void halbtc8723b1ant_action_wifi_connected_special_packet(
struct btc_coexist *btcoexist)
{
- bool hs_connecting = false;
struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+ bool wifi_busy = false;
- btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_CONNECTING, &hs_connecting);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+
+ /* no special packet process for both WiFi and BT very busy */
+ if ((wifi_busy) &&
+ ((bt_link_info->pan_exist) || (coex_sta->num_of_profile >= 2)))
+ return;
halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
0x0, 0x0);
/* tdma and coex table */
- if ((BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE == coex_dm->bt_status) ||
- (bt_link_info->sco_exist) || (bt_link_info->hid_only) ||
- (bt_link_info->a2dp_only) || (bt_link_info->pan_only)) {
- halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
- halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7);
- } else {
+ if ((bt_link_info->sco_exist) || (bt_link_info->hid_exist)) {
+ halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32);
+ halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 5);
+ } else if (bt_link_info->a2dp_exist) {
+ halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32);
+ halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
+ } else if (bt_link_info->pan_exist) {
halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20);
- halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
+ halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
+ } else {
+ halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
+ halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA,
+ NORMAL_EXEC, false, false);
+ halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
}
}
@@ -1391,12 +2095,31 @@ static void halbtc8723b1ant_action_wifi_connected(struct btc_coexist *btcoexist)
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
/* power save state */
if (!ap_enable &&
- BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status &&
+ coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_BUSY &&
!btcoexist->bt_link_info.hid_only) {
- if (!wifi_busy && btcoexist->bt_link_info.a2dp_only)
- halbtc8723b1ant_power_save_state(btcoexist,
+ if (btcoexist->bt_link_info.a2dp_only) {
+ if (!wifi_busy) {
+ halbtc8723b1ant_power_save_state(btcoexist,
BTC_PS_WIFI_NATIVE,
0x0, 0x0);
+ } else { /* busy */
+ if (coex_sta->scan_ap_num >=
+ BT_8723B_1ANT_WIFI_NOISY_THRESH)
+ /* no force LPS, no PS-TDMA,
+ * use pure TDMA
+ */
+ halbtc8723b1ant_power_save_state(
+ btcoexist, BTC_PS_WIFI_NATIVE,
+ 0x0, 0x0);
+ else
+ halbtc8723b1ant_power_save_state(
+ btcoexist, BTC_PS_LPS_ON, 0x50,
+ 0x4);
+ }
+ } else if ((!coex_sta->pan_exist) && (!coex_sta->a2dp_exist) &&
+ (!coex_sta->hid_exist))
+ halbtc8723b1ant_power_save_state(
+ btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
else
halbtc8723b1ant_power_save_state(btcoexist,
BTC_PS_LPS_ON,
@@ -1407,36 +2130,44 @@ static void halbtc8723b1ant_action_wifi_connected(struct btc_coexist *btcoexist)
}
/* tdma and coex table */
if (!wifi_busy) {
- if (BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) {
- halbtc8723b1ant_action_wifi_connected_bt_acl_busy(btcoexist,
- BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE);
- } else if ((BT_8723B_1ANT_BT_STATUS_SCO_BUSY ==
- coex_dm->bt_status) ||
- (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY ==
- coex_dm->bt_status)) {
+ if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_BUSY) {
+ halbtc8723b1ant_action_wifi_connected_bt_acl_busy(
+ btcoexist,
+ BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE);
+ } else if (coex_dm->bt_status ==
+ BT_8723B_1ANT_BT_STATUS_SCO_BUSY ||
+ coex_dm->bt_status ==
+ BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY) {
btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist,
BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE);
} else {
halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
false, 8);
+ halbtc8723b1ant_set_ant_path(btcoexist,
+ BTC_ANT_PATH_PTA,
+ NORMAL_EXEC, false, false);
halbtc8723b1ant_coex_table_with_type(btcoexist,
NORMAL_EXEC, 2);
}
} else {
- if (BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) {
- halbtc8723b1ant_action_wifi_connected_bt_acl_busy(btcoexist,
- BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY);
- } else if ((BT_8723B_1ANT_BT_STATUS_SCO_BUSY ==
- coex_dm->bt_status) ||
- (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY ==
- coex_dm->bt_status)) {
+ if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_BUSY) {
+ halbtc8723b1ant_action_wifi_connected_bt_acl_busy(
+ btcoexist,
+ BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY);
+ } else if (coex_dm->bt_status ==
+ BT_8723B_1ANT_BT_STATUS_SCO_BUSY ||
+ coex_dm->bt_status ==
+ BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY) {
btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist,
BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY);
} else {
halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
- false, 8);
+ true, 32);
+ halbtc8723b1ant_set_ant_path(btcoexist,
+ BTC_ANT_PATH_PTA,
+ NORMAL_EXEC, false, false);
halbtc8723b1ant_coex_table_with_type(btcoexist,
- NORMAL_EXEC, 2);
+ NORMAL_EXEC, 4);
}
}
}
@@ -1445,12 +2176,15 @@ static void halbtc8723b1ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
- bool wifi_connected = false, bt_hs_on = false;
+ bool wifi_connected = false, bt_hs_on = false, wifi_busy = false;
bool increase_scan_dev_num = false;
bool bt_ctrl_agg_buf_size = false;
+ bool miracast_plus_bt = false;
u8 agg_buf_size = 5;
+ u8 iot_peer = BTC_IOT_PEER_UNKNOWN;
u32 wifi_link_status = 0;
u32 num_of_wifi_link = 0;
+ u32 wifi_bw;
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
"[BTCoex], RunCoexistMechanism()===>\n");
@@ -1473,54 +2207,99 @@ static void halbtc8723b1ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
return;
}
- if ((BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) ||
- (BT_8723B_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) ||
- (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status)) {
- increase_scan_dev_num = true;
+ if (coex_sta->bt_whck_test) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], wifi is under IPS !!!\n");
+ halbtc8723b1ant_action_bt_whck_test(btcoexist);
+ return;
}
+ if (coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_BUSY ||
+ coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_SCO_BUSY ||
+ coex_dm->bt_status == BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY)
+ increase_scan_dev_num = true;
+
btcoexist->btc_set(btcoexist, BTC_SET_BL_INC_SCAN_DEV_NUM,
&increase_scan_dev_num);
-
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
&wifi_connected);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS,
&wifi_link_status);
num_of_wifi_link = wifi_link_status >> 16;
- if (num_of_wifi_link >= 2) {
- halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
+
+ if (num_of_wifi_link >= 2 ||
+ wifi_link_status & WIFI_P2P_GO_CONNECTED) {
+ if (bt_link_info->bt_link_exist) {
+ halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 1, 1,
+ 0, 1);
+ miracast_plus_bt = true;
+ } else {
+ halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0,
+ 0, 0);
+ miracast_plus_bt = false;
+ }
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_MIRACAST_PLUS_BT,
+ &miracast_plus_bt);
halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false,
- bt_ctrl_agg_buf_size,
- agg_buf_size);
- halbtc8723b1ant_action_wifi_multiport(btcoexist);
+ bt_ctrl_agg_buf_size, agg_buf_size);
+
+ if ((bt_link_info->a2dp_exist || wifi_busy) &&
+ (coex_sta->c2h_bt_inquiry_page))
+ halbtc8723b1ant_action_bt_inquiry(btcoexist);
+ else
+ halbtc8723b1ant_action_wifi_multiport(btcoexist);
+
return;
}
- if (!bt_link_info->sco_exist && !bt_link_info->hid_exist) {
- halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
+ miracast_plus_bt = false;
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_MIRACAST_PLUS_BT,
+ &miracast_plus_bt);
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+ if (bt_link_info->bt_link_exist && wifi_connected) {
+ halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 1, 1, 0, 1);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U1_IOT_PEER, &iot_peer);
+
+ if (iot_peer != BTC_IOT_PEER_CISCO &&
+ iot_peer != BTC_IOT_PEER_BROADCOM) {
+ if (bt_link_info->sco_exist)
+ halbtc8723b1ant_limited_rx(btcoexist,
+ NORMAL_EXEC, false,
+ false, 0x5);
+ else
+ halbtc8723b1ant_limited_rx(btcoexist,
+ NORMAL_EXEC, false,
+ false, 0x5);
+ } else {
+ if (bt_link_info->sco_exist) {
+ halbtc8723b1ant_limited_rx(btcoexist,
+ NORMAL_EXEC, true,
+ false, 0x5);
+ } else {
+ if (wifi_bw == BTC_WIFI_BW_HT40)
+ halbtc8723b1ant_limited_rx(
+ btcoexist, NORMAL_EXEC, false,
+ true, 0x10);
+ else
+ halbtc8723b1ant_limited_rx(
+ btcoexist, NORMAL_EXEC, false,
+ true, 0x8);
+ }
+ }
+
+ halbtc8723b1ant_sw_mechanism(btcoexist, true);
} else {
- if (wifi_connected)
- halbtc8723b1ant_limited_tx(btcoexist,
- NORMAL_EXEC, 1, 1, 1, 1);
- else
- halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC,
- 0, 0, 0, 0);
- }
+ halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
- if (bt_link_info->sco_exist) {
- bt_ctrl_agg_buf_size = true;
- agg_buf_size = 0x3;
- } else if (bt_link_info->hid_exist) {
- bt_ctrl_agg_buf_size = true;
- agg_buf_size = 0x5;
- } else if (bt_link_info->a2dp_exist || bt_link_info->pan_exist) {
- bt_ctrl_agg_buf_size = true;
- agg_buf_size = 0x8;
- }
- halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false,
- bt_ctrl_agg_buf_size, agg_buf_size);
+ halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false, false,
+ 0x5);
+ halbtc8723b1ant_sw_mechanism(btcoexist, false);
+ }
btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
if (coex_sta->c2h_bt_inquiry_page) {
@@ -1556,91 +2335,141 @@ static void halbtc8723b1ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
}
}
+/* force coex mechanism to reset */
static void halbtc8723b1ant_init_coex_dm(struct btc_coexist *btcoexist)
{
/* sw all off */
halbtc8723b1ant_sw_mechanism(btcoexist, false);
- halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8);
- halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0);
+ coex_sta->pop_event_cnt = 0;
}
static void halbtc8723b1ant_init_hw_config(struct btc_coexist *btcoexist,
- bool backup)
+ bool backup, bool wifi_only)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
u32 u32tmp = 0;
- u8 u8tmp = 0;
- u32 cnt_bt_cal_chk = 0;
+ u8 u8tmpa = 0, u8tmpb = 0;
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
"[BTCoex], 1Ant Init HW Config!!\n");
- if (backup) {/* backup rf 0x1e value */
- coex_dm->backup_arfr_cnt1 =
- btcoexist->btc_read_4byte(btcoexist, 0x430);
- coex_dm->backup_arfr_cnt2 =
- btcoexist->btc_read_4byte(btcoexist, 0x434);
- coex_dm->backup_retry_limit =
- btcoexist->btc_read_2byte(btcoexist, 0x42a);
- coex_dm->backup_ampdu_max_time =
- btcoexist->btc_read_1byte(btcoexist, 0x456);
- }
-
- /* WiFi goto standby while GNT_BT 0-->1 */
- btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x780);
- /* BT goto standby while GNT_BT 1-->0 */
- btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x2, 0xfffff, 0x500);
-
- btcoexist->btc_write_1byte(btcoexist, 0x974, 0xff);
- btcoexist->btc_write_1byte_bitmask(btcoexist, 0x944, 0x3, 0x3);
- btcoexist->btc_write_1byte(btcoexist, 0x930, 0x77);
-
- /* BT calibration check */
- while (cnt_bt_cal_chk <= 20) {
- u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x49d);
- cnt_bt_cal_chk++;
- if (u32tmp & BIT0) {
- RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
- "[BTCoex], ########### BT calibration(cnt=%d) ###########\n",
- cnt_bt_cal_chk);
- mdelay(50);
- } else {
- RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
- "[BTCoex], ********** BT NOT calibration (cnt=%d)**********\n",
- cnt_bt_cal_chk);
- break;
- }
- }
+ /* 0xf0[15:12] --> Chip Cut information */
+ coex_sta->cut_version =
+ (btcoexist->btc_read_1byte(btcoexist, 0xf1) & 0xf0) >> 4;
+ /* enable TBTT interrupt */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x550, 0x8, 0x1);
/* 0x790[5:0] = 0x5 */
- u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x790);
- u8tmp &= 0xc0;
- u8tmp |= 0x5;
- btcoexist->btc_write_1byte(btcoexist, 0x790, u8tmp);
+ btcoexist->btc_write_1byte(btcoexist, 0x790, 0x5);
/* Enable counter statistics */
- /*0x76e[3] = 1, WLAN_Act control by PTA */
- btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc);
btcoexist->btc_write_1byte(btcoexist, 0x778, 0x1);
btcoexist->btc_write_1byte_bitmask(btcoexist, 0x40, 0x20, 0x1);
+ halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8);
+
/* Antenna config */
- halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, true, false);
+ if (wifi_only)
+ halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_WIFI,
+ FORCE_EXEC, true, false);
+ else
+ halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT,
+ FORCE_EXEC, true, false);
+
/* PTA parameter */
halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0);
+
+ u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x948);
+ u8tmpa = btcoexist->btc_read_1byte(btcoexist, 0x765);
+ u8tmpb = btcoexist->btc_read_1byte(btcoexist, 0x67);
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "############# [BTCoex], 0x948=0x%x, 0x765=0x%x, 0x67=0x%x\n",
+ u32tmp, u8tmpa, u8tmpb);
}
/**************************************************************
- * extern function start with ex_halbtc8723b1ant_
+ * extern function start with ex_btc8723b1ant_
**************************************************************/
+void ex_btc8723b1ant_power_on_setting(struct btc_coexist *btcoexist)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ struct btc_board_info *board_info = &btcoexist->board_info;
+ u8 u8tmp = 0x0;
+ u16 u16tmp = 0x0;
+ u32 value;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "xxxxxxxxxxxxxxxx Execute 8723b 1-Ant PowerOn Setting xxxxxxxxxxxxxxxx!!\n");
+
+ btcoexist->stop_coex_dm = true;
+
+ btcoexist->btc_write_1byte(btcoexist, 0x67, 0x20);
+
+ /* enable BB, REG_SYS_FUNC_EN such that we can write 0x948 correctly. */
+ u16tmp = btcoexist->btc_read_2byte(btcoexist, 0x2);
+ btcoexist->btc_write_2byte(btcoexist, 0x2, u16tmp | BIT0 | BIT1);
+
+ /* set GRAN_BT = 1 */
+ btcoexist->btc_write_1byte(btcoexist, 0x765, 0x18);
+ /* set WLAN_ACT = 0 */
+ btcoexist->btc_write_1byte(btcoexist, 0x76e, 0x4);
+
+ /* S0 or S1 setting and Local register setting(By the setting fw can get
+ * ant number, S0/S1, ... info)
+ *
+ * Local setting bit define
+ * BIT0: "0" for no antenna inverse; "1" for antenna inverse
+ * BIT1: "0" for internal switch; "1" for external switch
+ * BIT2: "0" for one antenna; "1" for two antenna
+ * NOTE: here default all internal switch and 1-antenna ==> BIT1=0 and
+ * BIT2 = 0
+ */
+ if (btcoexist->chip_interface == BTC_INTF_USB) {
+ /* fixed at S0 for USB interface */
+ btcoexist->btc_write_4byte(btcoexist, 0x948, 0x0);
-void ex_halbtc8723b1ant_init_hwconfig(struct btc_coexist *btcoexist)
+ u8tmp |= 0x1; /* antenna inverse */
+ btcoexist->btc_write_local_reg_1byte(btcoexist, 0xfe08, u8tmp);
+
+ board_info->btdm_ant_pos = BTC_ANTENNA_AT_AUX_PORT;
+ } else {
+ /* for PCIE and SDIO interface, we check efuse 0xc3[6] */
+ if (board_info->single_ant_path == 0) {
+ /* set to S1 */
+ btcoexist->btc_write_4byte(btcoexist, 0x948, 0x280);
+ board_info->btdm_ant_pos = BTC_ANTENNA_AT_MAIN_PORT;
+ value = 1;
+ } else if (board_info->single_ant_path == 1) {
+ /* set to S0 */
+ btcoexist->btc_write_4byte(btcoexist, 0x948, 0x0);
+ u8tmp |= 0x1; /* antenna inverse */
+ board_info->btdm_ant_pos = BTC_ANTENNA_AT_AUX_PORT;
+ value = 0;
+ }
+
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_ANTPOSREGRISTRY_CTRL,
+ &value);
+
+ if (btcoexist->chip_interface == BTC_INTF_PCI)
+ btcoexist->btc_write_local_reg_1byte(btcoexist, 0x384,
+ u8tmp);
+ else if (btcoexist->chip_interface == BTC_INTF_SDIO)
+ btcoexist->btc_write_local_reg_1byte(btcoexist, 0x60,
+ u8tmp);
+ }
+}
+
+
+void ex_btc8723b1ant_init_hwconfig(struct btc_coexist *btcoexist,
+ bool wifi_only)
{
- halbtc8723b1ant_init_hw_config(btcoexist, true);
+ halbtc8723b1ant_init_hw_config(btcoexist, true, wifi_only);
+ btcoexist->stop_coex_dm = false;
}
-void ex_halbtc8723b1ant_init_coex_dm(struct btc_coexist *btcoexist)
+void ex_btc8723b1ant_init_coex_dm(struct btc_coexist *btcoexist)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
@@ -1654,7 +2483,7 @@ void ex_halbtc8723b1ant_init_coex_dm(struct btc_coexist *btcoexist)
halbtc8723b1ant_query_bt_info(btcoexist);
}
-void ex_halbtc8723b1ant_display_coex_info(struct btc_coexist *btcoexist)
+void ex_btc8723b1ant_display_coex_info(struct btc_coexist *btcoexist)
{
struct btc_board_info *board_info = &btcoexist->board_info;
struct btc_stack_info *stack_info = &btcoexist->stack_info;
@@ -1687,11 +2516,6 @@ void ex_halbtc8723b1ant_display_coex_info(struct btc_coexist *btcoexist)
"\r\n ==========================================");
}
- if (!board_info->bt_exist) {
- RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n BT not exists !!!");
- return;
- }
-
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d",
"Ant PG Num/ Ant Mech/ Ant Pos:",
board_info->pg_ant_num, board_info->btdm_ant_num,
@@ -1760,7 +2584,7 @@ void ex_halbtc8723b1ant_display_coex_info(struct btc_coexist *btcoexist)
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = [%s/ %d/ %d] ",
"BT [status/ rssi/ retryCnt]",
- ((btcoexist->bt_info.bt_disabled) ? ("disabled") :
+ ((coex_sta->bt_disabled) ? ("disabled") :
((coex_sta->c2h_bt_inquiry_page) ? ("inquiry/page scan") :
((BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE ==
coex_dm->bt_status) ?
@@ -1835,6 +2659,9 @@ void ex_halbtc8723b1ant_display_coex_info(struct btc_coexist *btcoexist)
coex_dm->error_condition);
}
+ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d",
+ "Coex Table Type", coex_sta->coex_table_type);
+
/* Hw setting */
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s",
"============[Hw setting]============");
@@ -1926,13 +2753,12 @@ void ex_halbtc8723b1ant_display_coex_info(struct btc_coexist *btcoexist)
RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d",
"0x774(low-pri rx/tx)", coex_sta->low_priority_rx,
coex_sta->low_priority_tx);
-#if (BT_AUTO_REPORT_ONLY_8723B_1ANT == 1)
- halbtc8723b1ant_monitor_bt_ctr(btcoexist);
-#endif
+ if (btcoexist->auto_report_1ant)
+ halbtc8723b1ant_monitor_bt_ctr(btcoexist);
btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_COEX_STATISTICS);
}
-void ex_halbtc8723b1ant_ips_notify(struct btc_coexist *btcoexist, u8 type)
+void ex_btc8723b1ant_ips_notify(struct btc_coexist *btcoexist, u8 type)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
@@ -1945,7 +2771,7 @@ void ex_halbtc8723b1ant_ips_notify(struct btc_coexist *btcoexist, u8 type)
coex_sta->under_ips = true;
halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT,
- false, true);
+ FORCE_EXEC, false, true);
/* set PTA control */
halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
halbtc8723b1ant_coex_table_with_type(btcoexist,
@@ -1955,13 +2781,13 @@ void ex_halbtc8723b1ant_ips_notify(struct btc_coexist *btcoexist, u8 type)
"[BTCoex], IPS LEAVE notify\n");
coex_sta->under_ips = false;
- halbtc8723b1ant_init_hw_config(btcoexist, false);
+ halbtc8723b1ant_init_hw_config(btcoexist, false, false);
halbtc8723b1ant_init_coex_dm(btcoexist);
halbtc8723b1ant_query_bt_info(btcoexist);
}
}
-void ex_halbtc8723b1ant_lps_notify(struct btc_coexist *btcoexist, u8 type)
+void ex_btc8723b1ant_lps_notify(struct btc_coexist *btcoexist, u8 type)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
@@ -1979,17 +2805,45 @@ void ex_halbtc8723b1ant_lps_notify(struct btc_coexist *btcoexist, u8 type)
}
}
-void ex_halbtc8723b1ant_scan_notify(struct btc_coexist *btcoexist, u8 type)
+void ex_btc8723b1ant_scan_notify(struct btc_coexist *btcoexist, u8 type)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
bool wifi_connected = false, bt_hs_on = false;
+ u8 u8tmpa, u8tmpb;
+ u32 u32tmp;
u32 wifi_link_status = 0;
u32 num_of_wifi_link = 0;
bool bt_ctrl_agg_buf_size = false;
u8 agg_buf_size = 5;
- if (btcoexist->manual_control || btcoexist->stop_coex_dm ||
- btcoexist->bt_info.bt_disabled)
+ if (btcoexist->manual_control || btcoexist->stop_coex_dm)
+ return;
+
+ if (type == BTC_SCAN_START) {
+ coex_sta->wifi_is_high_pri_task = true;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], SCAN START notify\n");
+ /* Force antenna setup for no scan result issue */
+ halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8);
+ halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA,
+ FORCE_EXEC, false, false);
+ u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x948);
+ u8tmpa = btcoexist->btc_read_1byte(btcoexist, 0x765);
+ u8tmpb = btcoexist->btc_read_1byte(btcoexist, 0x67);
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], 0x948=0x%x, 0x765=0x%x, 0x67=0x%x\n",
+ u32tmp, u8tmpa, u8tmpb);
+ } else {
+ coex_sta->wifi_is_high_pri_task = false;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], SCAN FINISH notify\n");
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM,
+ &coex_sta->scan_ap_num);
+ }
+
+ if (coex_sta->bt_disabled)
return;
btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
@@ -2037,19 +2891,38 @@ void ex_halbtc8723b1ant_scan_notify(struct btc_coexist *btcoexist, u8 type)
}
}
-void ex_halbtc8723b1ant_connect_notify(struct btc_coexist *btcoexist, u8 type)
+void ex_btc8723b1ant_connect_notify(struct btc_coexist *btcoexist, u8 type)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
bool wifi_connected = false, bt_hs_on = false;
u32 wifi_link_status = 0;
u32 num_of_wifi_link = 0;
- bool bt_ctrl_agg_buf_size = false;
+ bool bt_ctrl_agg_buf_size = false, under_4way = false;
u8 agg_buf_size = 5;
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS,
+ &under_4way);
+
if (btcoexist->manual_control || btcoexist->stop_coex_dm ||
- btcoexist->bt_info.bt_disabled)
+ coex_sta->bt_disabled)
return;
+ if (type == BTC_ASSOCIATE_START) {
+ coex_sta->wifi_is_high_pri_task = true;
+
+ /* Force antenna setup for no scan result issue */
+ halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8);
+ halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA,
+ FORCE_EXEC, false, false);
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], CONNECT START notify\n");
+ coex_dm->arp_cnt = 0;
+ } else {
+ coex_sta->wifi_is_high_pri_task = false;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], CONNECT FINISH notify\n");
+ }
+
btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS,
&wifi_link_status);
num_of_wifi_link = wifi_link_status>>16;
@@ -2088,33 +2961,68 @@ void ex_halbtc8723b1ant_connect_notify(struct btc_coexist *btcoexist, u8 type)
}
}
-void ex_halbtc8723b1ant_media_status_notify(struct btc_coexist *btcoexist,
- u8 type)
+void ex_btc8723b1ant_media_status_notify(struct btc_coexist *btcoexist,
+ u8 type)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
u8 h2c_parameter[3] = {0};
u32 wifi_bw;
- u8 wifiCentralChnl;
+ u8 wifi_central_chnl;
+ bool wifi_under_b_mode = false;
if (btcoexist->manual_control || btcoexist->stop_coex_dm ||
- btcoexist->bt_info.bt_disabled)
+ coex_sta->bt_disabled)
return;
- if (BTC_MEDIA_CONNECT == type)
+ if (type == BTC_MEDIA_CONNECT) {
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
"[BTCoex], MEDIA connect notify\n");
- else
+ /* Force antenna setup for no scan result issue */
+ halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8);
+ halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA,
+ FORCE_EXEC, false, false);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_B_MODE,
+ &wifi_under_b_mode);
+
+ /* Set CCK Tx/Rx high Pri except 11b mode */
+ if (wifi_under_b_mode) {
+ btcoexist->btc_write_1byte(btcoexist, 0x6cd,
+ 0x00); /* CCK Tx */
+ btcoexist->btc_write_1byte(btcoexist, 0x6cf,
+ 0x00); /* CCK Rx */
+ } else {
+ btcoexist->btc_write_1byte(btcoexist, 0x6cd,
+ 0x00); /* CCK Tx */
+ btcoexist->btc_write_1byte(btcoexist, 0x6cf,
+ 0x10); /* CCK Rx */
+ }
+
+ coex_dm->backup_arfr_cnt1 =
+ btcoexist->btc_read_4byte(btcoexist, 0x430);
+ coex_dm->backup_arfr_cnt2 =
+ btcoexist->btc_read_4byte(btcoexist, 0x434);
+ coex_dm->backup_retry_limit =
+ btcoexist->btc_read_2byte(btcoexist, 0x42a);
+ coex_dm->backup_ampdu_max_time =
+ btcoexist->btc_read_1byte(btcoexist, 0x456);
+ } else {
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
"[BTCoex], MEDIA disconnect notify\n");
+ coex_dm->arp_cnt = 0;
+
+ btcoexist->btc_write_1byte(btcoexist, 0x6cd, 0x0); /* CCK Tx */
+ btcoexist->btc_write_1byte(btcoexist, 0x6cf, 0x0); /* CCK Rx */
+
+ coex_sta->cck_ever_lock = false;
+ }
/* only 2.4G we need to inform bt the chnl mask */
btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL,
- &wifiCentralChnl);
+ &wifi_central_chnl);
- if ((BTC_MEDIA_CONNECT == type) &&
- (wifiCentralChnl <= 14)) {
+ if (type == BTC_MEDIA_CONNECT && wifi_central_chnl <= 14) {
h2c_parameter[0] = 0x0;
- h2c_parameter[1] = wifiCentralChnl;
+ h2c_parameter[1] = wifi_central_chnl;
btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
if (BTC_WIFI_BW_HT40 == wifi_bw)
h2c_parameter[2] = 0x30;
@@ -2134,20 +3042,53 @@ void ex_halbtc8723b1ant_media_status_notify(struct btc_coexist *btcoexist,
btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter);
}
-void ex_halbtc8723b1ant_special_packet_notify(struct btc_coexist *btcoexist,
- u8 type)
+void ex_btc8723b1ant_special_packet_notify(struct btc_coexist *btcoexist,
+ u8 type)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
bool bt_hs_on = false;
u32 wifi_link_status = 0;
u32 num_of_wifi_link = 0;
- bool bt_ctrl_agg_buf_size = false;
+ bool bt_ctrl_agg_buf_size = false, under_4way = false;
u8 agg_buf_size = 5;
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS,
+ &under_4way);
+
if (btcoexist->manual_control || btcoexist->stop_coex_dm ||
- btcoexist->bt_info.bt_disabled)
+ coex_sta->bt_disabled)
return;
+ if (type == BTC_PACKET_DHCP || type == BTC_PACKET_EAPOL ||
+ type == BTC_PACKET_ARP) {
+ if (type == BTC_PACKET_ARP) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], special Packet ARP notify\n");
+
+ coex_dm->arp_cnt++;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], ARP Packet Count = %d\n",
+ coex_dm->arp_cnt);
+
+ if ((coex_dm->arp_cnt >= 10) && (!under_4way))
+ /* if APR PKT > 10 after connect, do not go to
+ * ActionWifiConnectedSpecificPacket(btcoexist)
+ */
+ coex_sta->wifi_is_high_pri_task = false;
+ else
+ coex_sta->wifi_is_high_pri_task = true;
+ } else {
+ coex_sta->wifi_is_high_pri_task = true;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], special Packet DHCP or EAPOL notify\n");
+ }
+ } else {
+ coex_sta->wifi_is_high_pri_task = false;
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], special Packet [Type = %d] notify\n",
+ type);
+ }
+
btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS,
&wifi_link_status);
num_of_wifi_link = wifi_link_status >> 16;
@@ -2178,8 +3119,8 @@ void ex_halbtc8723b1ant_special_packet_notify(struct btc_coexist *btcoexist,
}
}
-void ex_halbtc8723b1ant_bt_info_notify(struct btc_coexist *btcoexist,
- u8 *tmp_buf, u8 length)
+void ex_btc8723b1ant_bt_info_notify(struct btc_coexist *btcoexist,
+ u8 *tmp_buf, u8 length)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
u8 bt_info = 0;
@@ -2209,16 +3150,58 @@ void ex_halbtc8723b1ant_bt_info_notify(struct btc_coexist *btcoexist,
"0x%02x, ", tmp_buf[i]);
}
- if (BT_INFO_SRC_8723B_1ANT_WIFI_FW != rsp_source) {
- coex_sta->bt_retry_cnt = /* [3:0] */
+ /* if 0xff, it means BT is under WHCK test */
+ if (bt_info == 0xff)
+ coex_sta->bt_whck_test = true;
+ else
+ coex_sta->bt_whck_test = false;
+
+ if (rsp_source != BT_INFO_SRC_8723B_1ANT_WIFI_FW) {
+ coex_sta->bt_retry_cnt = /* [3:0] */
coex_sta->bt_info_c2h[rsp_source][2] & 0xf;
+ if (coex_sta->bt_retry_cnt >= 1)
+ coex_sta->pop_event_cnt++;
+
+ if (coex_sta->bt_info_c2h[rsp_source][2] & 0x20)
+ coex_sta->c2h_bt_remote_name_req = true;
+ else
+ coex_sta->c2h_bt_remote_name_req = false;
+
coex_sta->bt_rssi =
- coex_sta->bt_info_c2h[rsp_source][3] * 2 + 10;
+ coex_sta->bt_info_c2h[rsp_source][3] * 2 - 90;
coex_sta->bt_info_ext =
coex_sta->bt_info_c2h[rsp_source][4];
+ if (coex_sta->bt_info_c2h[rsp_source][1] == 0x49) {
+ coex_sta->a2dp_bit_pool =
+ coex_sta->bt_info_c2h[rsp_source][6];
+ } else {
+ coex_sta->a2dp_bit_pool = 0;
+ }
+
+ coex_sta->bt_tx_rx_mask =
+ (coex_sta->bt_info_c2h[rsp_source][2] & 0x40);
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TX_RX_MASK,
+ &coex_sta->bt_tx_rx_mask);
+
+ if (!coex_sta->bt_tx_rx_mask) {
+ /* BT into is responded by BT FW and BT RF REG
+ * 0x3C != 0x15 => Need to switch BT TRx Mask
+ */
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], Switch BT TRx Mask since BT RF REG 0x3C != 0x15\n");
+ btcoexist->btc_set_bt_reg(btcoexist, BTC_BT_REG_RF,
+ 0x3c, 0x15);
+
+ /* BT TRx Mask lock 0x2c[0], 0x30[0] = 0 */
+ btcoexist->btc_set_bt_reg(btcoexist, BTC_BT_REG_RF,
+ 0x2c, 0x7c44);
+ btcoexist->btc_set_bt_reg(btcoexist, BTC_BT_REG_RF,
+ 0x30, 0x7c44);
+ }
+
/* Here we need to resend some wifi info to BT
* because bt is reset and loss of the info.
*/
@@ -2228,11 +3211,11 @@ void ex_halbtc8723b1ant_bt_info_notify(struct btc_coexist *btcoexist,
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
&wifi_connected);
if (wifi_connected)
- ex_halbtc8723b1ant_media_status_notify(btcoexist,
- BTC_MEDIA_CONNECT);
+ ex_btc8723b1ant_media_status_notify(btcoexist,
+ BTC_MEDIA_CONNECT);
else
- ex_halbtc8723b1ant_media_status_notify(btcoexist,
- BTC_MEDIA_DISCONNECT);
+ ex_btc8723b1ant_media_status_notify(btcoexist,
+ BTC_MEDIA_DISCONNECT);
}
if (coex_sta->bt_info_ext & BIT3) {
@@ -2247,14 +3230,15 @@ void ex_halbtc8723b1ant_bt_info_notify(struct btc_coexist *btcoexist,
} else {
/* BT already NOT ignore Wlan active, do nothing here.*/
}
-#if (BT_AUTO_REPORT_ONLY_8723B_1ANT == 0)
- if (coex_sta->bt_info_ext & BIT4) {
- /* BT auto report already enabled, do nothing */
- } else {
- halbtc8723b1ant_bt_auto_report(btcoexist, FORCE_EXEC,
- true);
+ if (!btcoexist->auto_report_1ant) {
+ if (coex_sta->bt_info_ext & BIT4) {
+ /* BT auto report already enabled, do nothing */
+ } else {
+ halbtc8723b1ant_bt_auto_report(btcoexist,
+ FORCE_EXEC,
+ true);
+ }
}
-#endif
}
/* check BIT2 first ==> check if bt is under inquiry or page scan */
@@ -2263,6 +3247,8 @@ void ex_halbtc8723b1ant_bt_info_notify(struct btc_coexist *btcoexist,
else
coex_sta->c2h_bt_inquiry_page = false;
+ coex_sta->num_of_profile = 0;
+
/* set link exist status */
if (!(bt_info & BT_INFO_8723B_1ANT_B_CONNECTION)) {
coex_sta->bt_link_exist = false;
@@ -2270,30 +3256,77 @@ void ex_halbtc8723b1ant_bt_info_notify(struct btc_coexist *btcoexist,
coex_sta->a2dp_exist = false;
coex_sta->hid_exist = false;
coex_sta->sco_exist = false;
+
+ coex_sta->bt_hi_pri_link_exist = false;
} else {
/* connection exists */
coex_sta->bt_link_exist = true;
- if (bt_info & BT_INFO_8723B_1ANT_B_FTP)
+ if (bt_info & BT_INFO_8723B_1ANT_B_FTP) {
coex_sta->pan_exist = true;
- else
+ coex_sta->num_of_profile++;
+ } else {
coex_sta->pan_exist = false;
- if (bt_info & BT_INFO_8723B_1ANT_B_A2DP)
+ }
+ if (bt_info & BT_INFO_8723B_1ANT_B_A2DP) {
coex_sta->a2dp_exist = true;
- else
+ coex_sta->num_of_profile++;
+ } else {
coex_sta->a2dp_exist = false;
- if (bt_info & BT_INFO_8723B_1ANT_B_HID)
+ }
+ if (bt_info & BT_INFO_8723B_1ANT_B_HID) {
coex_sta->hid_exist = true;
- else
+ coex_sta->num_of_profile++;
+ } else {
coex_sta->hid_exist = false;
- if (bt_info & BT_INFO_8723B_1ANT_B_SCO_ESCO)
+ }
+ if (bt_info & BT_INFO_8723B_1ANT_B_SCO_ESCO) {
coex_sta->sco_exist = true;
- else
+ coex_sta->num_of_profile++;
+ } else {
coex_sta->sco_exist = false;
+ }
+
+ if ((!coex_sta->hid_exist) &&
+ (!coex_sta->c2h_bt_inquiry_page) &&
+ (!coex_sta->sco_exist)) {
+ if (coex_sta->high_priority_tx +
+ coex_sta->high_priority_rx >=
+ 160) {
+ coex_sta->hid_exist = true;
+ coex_sta->wrong_profile_notification++;
+ coex_sta->num_of_profile++;
+ bt_info = bt_info | 0x28;
+ }
+ }
+
+ /* Add Hi-Pri Tx/Rx counter to avoid false detection */
+ if (((coex_sta->hid_exist) || (coex_sta->sco_exist)) &&
+ (coex_sta->high_priority_tx + coex_sta->high_priority_rx >=
+ 160) &&
+ (!coex_sta->c2h_bt_inquiry_page))
+ coex_sta->bt_hi_pri_link_exist = true;
+
+ if ((bt_info & BT_INFO_8723B_1ANT_B_ACL_BUSY) &&
+ (coex_sta->num_of_profile == 0)) {
+ if (coex_sta->low_priority_tx +
+ coex_sta->low_priority_rx >=
+ 160) {
+ coex_sta->pan_exist = true;
+ coex_sta->num_of_profile++;
+ coex_sta->wrong_profile_notification++;
+ bt_info = bt_info | 0x88;
+ }
+ }
}
halbtc8723b1ant_update_bt_link_info(btcoexist);
- if (!(bt_info&BT_INFO_8723B_1ANT_B_CONNECTION)) {
+ /* mask profile bit for connect-ilde identification
+ * ( for CSR case: A2DP idle --> 0x41)
+ */
+ bt_info = bt_info & 0x1f;
+
+ if (!(bt_info & BT_INFO_8723B_1ANT_B_CONNECTION)) {
coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE;
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
"[BTCoex], BtInfoNotify(), BT Non-Connected idle!\n");
@@ -2315,8 +3348,7 @@ void ex_halbtc8723b1ant_bt_info_notify(struct btc_coexist *btcoexist,
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
"[BTCoex], BtInfoNotify(), BT ACL busy!!!\n");
} else {
- coex_dm->bt_status =
- BT_8723B_1ANT_BT_STATUS_MAX;
+ coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_MAX;
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
"[BTCoex], BtInfoNotify(), BT Non-Defined state!!\n");
}
@@ -2332,7 +3364,44 @@ void ex_halbtc8723b1ant_bt_info_notify(struct btc_coexist *btcoexist,
halbtc8723b1ant_run_coexist_mechanism(btcoexist);
}
-void ex_halbtc8723b1ant_halt_notify(struct btc_coexist *btcoexist)
+void ex_btc8723b1ant_rf_status_notify(struct btc_coexist *btcoexist, u8 type)
+{
+ struct rtl_priv *rtlpriv = btcoexist->adapter;
+ u32 u32tmp;
+ u8 u8tmpa, u8tmpb, u8tmpc;
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], RF Status notify\n");
+
+ if (type == BTC_RF_ON) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], RF is turned ON!!\n");
+ btcoexist->stop_coex_dm = false;
+ } else if (type == BTC_RF_OFF) {
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "[BTCoex], RF is turned OFF!!\n");
+
+ halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
+ 0x0, 0x0);
+ halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 0);
+ halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT,
+ FORCE_EXEC, false, true);
+
+ halbtc8723b1ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true);
+ btcoexist->stop_coex_dm = true;
+
+ u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x948);
+ u8tmpa = btcoexist->btc_read_1byte(btcoexist, 0x765);
+ u8tmpb = btcoexist->btc_read_1byte(btcoexist, 0x67);
+ u8tmpc = btcoexist->btc_read_1byte(btcoexist, 0x76e);
+
+ RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+ "############# [BTCoex], 0x948=0x%x, 0x765=0x%x, 0x67=0x%x, 0x76e=0x%x\n",
+ u32tmp, u8tmpa, u8tmpb, u8tmpc);
+ }
+}
+
+void ex_btc8723b1ant_halt_notify(struct btc_coexist *btcoexist)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
@@ -2340,7 +3409,8 @@ void ex_halbtc8723b1ant_halt_notify(struct btc_coexist *btcoexist)
btcoexist->stop_coex_dm = true;
- halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, false, true);
+ halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, FORCE_EXEC,
+ false, true);
halbtc8723b1ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true);
@@ -2348,10 +3418,12 @@ void ex_halbtc8723b1ant_halt_notify(struct btc_coexist *btcoexist)
0x0, 0x0);
halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 0);
- ex_halbtc8723b1ant_media_status_notify(btcoexist, BTC_MEDIA_DISCONNECT);
+ ex_btc8723b1ant_media_status_notify(btcoexist, BTC_MEDIA_DISCONNECT);
+
+ btcoexist->stop_coex_dm = true;
}
-void ex_halbtc8723b1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state)
+void ex_btc8723b1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
@@ -2360,81 +3432,66 @@ void ex_halbtc8723b1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state)
if (BTC_WIFI_PNP_SLEEP == pnp_state) {
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
"[BTCoex], Pnp notify to SLEEP\n");
- btcoexist->stop_coex_dm = true;
- halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, false,
- true);
+ halbtc8723b1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT,
+ FORCE_EXEC, false, true);
halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
0x0, 0x0);
halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
+
+ /* Driver do not leave IPS/LPS when driver is going to sleep, so
+ * BTCoexistence think wifi is still under IPS/LPS
+ *
+ * BT should clear UnderIPS/UnderLPS state to avoid mismatch
+ * state after wakeup.
+ */
+ coex_sta->under_ips = false;
+ coex_sta->under_lps = false;
+ btcoexist->stop_coex_dm = true;
} else if (BTC_WIFI_PNP_WAKE_UP == pnp_state) {
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
"[BTCoex], Pnp notify to WAKE UP\n");
btcoexist->stop_coex_dm = false;
- halbtc8723b1ant_init_hw_config(btcoexist, false);
+ halbtc8723b1ant_init_hw_config(btcoexist, false, false);
halbtc8723b1ant_init_coex_dm(btcoexist);
halbtc8723b1ant_query_bt_info(btcoexist);
}
}
-void ex_halbtc8723b1ant_coex_dm_reset(struct btc_coexist *btcoexist)
+void ex_btc8723b1ant_coex_dm_reset(struct btc_coexist *btcoexist)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
"[BTCoex], *****************Coex DM Reset****************\n");
- halbtc8723b1ant_init_hw_config(btcoexist, false);
- btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
- btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x2, 0xfffff, 0x0);
+ halbtc8723b1ant_init_hw_config(btcoexist, false, false);
halbtc8723b1ant_init_coex_dm(btcoexist);
}
-void ex_halbtc8723b1ant_periodical(struct btc_coexist *btcoexist)
+void ex_btc8723b1ant_periodical(struct btc_coexist *btcoexist)
{
struct rtl_priv *rtlpriv = btcoexist->adapter;
- struct btc_board_info *board_info = &btcoexist->board_info;
- struct btc_stack_info *stack_info = &btcoexist->stack_info;
- static u8 dis_ver_info_cnt;
- u32 fw_ver = 0, bt_patch_ver = 0;
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
"[BTCoex], ==========================Periodical===========================\n");
- if (dis_ver_info_cnt <= 5) {
- dis_ver_info_cnt += 1;
- RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
- "[BTCoex], ****************************************************************\n");
- RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
- "[BTCoex], Ant PG Num/ Ant Mech/ Ant Pos = %d/ %d/ %d\n",
- board_info->pg_ant_num, board_info->btdm_ant_num,
- board_info->btdm_ant_pos);
- RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
- "[BTCoex], BT stack/ hci ext ver = %s / %d\n",
- stack_info->profile_notified ? "Yes" : "No",
- stack_info->hci_version);
- btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER,
- &bt_patch_ver);
- btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
- RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
- "[BTCoex], CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n",
- glcoex_ver_date_8723b_1ant,
- glcoex_ver_8723b_1ant, fw_ver,
- bt_patch_ver, bt_patch_ver);
- RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
- "[BTCoex], ****************************************************************\n");
- }
+ if (!btcoexist->auto_report_1ant) {
+ halbtc8723b1ant_query_bt_info(btcoexist);
+ halbtc8723b1ant_monitor_bt_enable_disable(btcoexist);
+ } else {
+ halbtc8723b1ant_monitor_bt_ctr(btcoexist);
+ halbtc8723b1ant_monitor_wifi_ctr(btcoexist);
-#if (BT_AUTO_REPORT_ONLY_8723B_1ANT == 0)
- halbtc8723b1ant_query_bt_info(btcoexist);
- halbtc8723b1ant_monitor_bt_ctr(btcoexist);
- halbtc8723b1ant_monitor_bt_enable_disable(btcoexist);
-#else
- if (btc8723b1ant_is_wifi_status_changed(btcoexist) ||
- coex_dm->auto_tdma_adjust) {
- halbtc8723b1ant_run_coexist_mechanism(btcoexist);
- }
+ if ((coex_sta->high_priority_tx + coex_sta->high_priority_rx < 50) &&
+ bt_link_info->hid_exist)
+ bt_link_info->hid_exist = false;
- coex_sta->special_pkt_period_cnt++;
-#endif
+ if (btc8723b1ant_is_wifi_status_changed(btcoexist) ||
+ coex_dm->auto_tdma_adjust) {
+ halbtc8723b1ant_run_coexist_mechanism(btcoexist);
+ }
+ coex_sta->special_pkt_period_cnt++;
+ }
}