Commit a3b2ba86 authored by Yan-Hsuan Chuang's avatar Yan-Hsuan Chuang Committed by Kalle Valo

rtlwifi: btcoex: 21a 2ant: refine bt info notify to have more profilings

We add some profiling combinations when the bt notifies the coex
mechanism to detect more situations and adjust the coex to fit to it.

Also monitor if the wifi is under 5G mode, if so, the signals do net
intefere each other, bt can just ignore it
Signed-off-by: default avatarYan-Hsuan Chuang <yhchuang@realtek.com>
Signed-off-by: default avatarLarry Finger <Larry.Finger@lwfinger.net>
Cc: Pkshih <pkshih@realtek.com>
Cc: Birming Chiu <birming@realtek.com>
Cc: Shaofu <shaofu@realtek.com>
Cc: Steven Ting <steventing@realtek.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 728b6106
...@@ -4019,9 +4019,12 @@ void ex_btc8821a2ant_bt_info_notify(struct btc_coexist *btcoexist, ...@@ -4019,9 +4019,12 @@ void ex_btc8821a2ant_bt_info_notify(struct btc_coexist *btcoexist,
u8 bt_info = 0; u8 bt_info = 0;
u8 i, rsp_source = 0; u8 i, rsp_source = 0;
bool bt_busy = false, limited_dig = false; bool bt_busy = false, limited_dig = false;
bool wifi_connected = false, bt_hs_on = false; bool wifi_connected = false, wifi_under_5g = false;
coex_sta->c2h_bt_info_req_sent = false; coex_sta->c2h_bt_info_req_sent = false;
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
&wifi_connected);
rsp_source = tmp_buf[0] & 0xf; rsp_source = tmp_buf[0] & 0xf;
if (rsp_source >= BT_INFO_SRC_8821A_2ANT_MAX) if (rsp_source >= BT_INFO_SRC_8821A_2ANT_MAX)
...@@ -4044,16 +4047,35 @@ void ex_btc8821a2ant_bt_info_notify(struct btc_coexist *btcoexist, ...@@ -4044,16 +4047,35 @@ void ex_btc8821a2ant_bt_info_notify(struct btc_coexist *btcoexist,
} }
} }
if (btcoexist->manual_control) {
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
"[BTCoex], BtInfoNotify(), return for Manual CTRL<===\n");
return;
}
if (BT_INFO_SRC_8821A_2ANT_WIFI_FW != rsp_source) { if (BT_INFO_SRC_8821A_2ANT_WIFI_FW != rsp_source) {
/* [3:0] */ /* [3:0] */
coex_sta->bt_retry_cnt = coex_sta->bt_retry_cnt =
coex_sta->bt_info_c2h[rsp_source][2]&0xf; coex_sta->bt_info_c2h[rsp_source][2]&0xf;
coex_sta->bt_rssi = coex_sta->bt_rssi =
coex_sta->bt_info_c2h[rsp_source][3]*2+10; coex_sta->bt_info_c2h[rsp_source][3] * 2 + 10;
coex_sta->bt_info_ext = coex_sta->bt_info_ext = coex_sta->bt_info_c2h[rsp_source][4];
coex_sta->bt_info_c2h[rsp_source][4];
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 !=
* 0x01 => Need to switch BT TRx Mask
*/
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
"[BTCoex], Switch BT TRx Mask since BT RF REG 0x3C != 0x01\n");
btcoexist->btc_set_bt_reg(btcoexist, BTC_BT_REG_RF,
0x3c, 0x01);
}
/* Here we need to resend some wifi info to BT /* Here we need to resend some wifi info to BT
* because bt is reset and loss of the info * because bt is reset and loss of the info
...@@ -4071,70 +4093,121 @@ void ex_btc8821a2ant_bt_info_notify(struct btc_coexist *btcoexist, ...@@ -4071,70 +4093,121 @@ void ex_btc8821a2ant_bt_info_notify(struct btc_coexist *btcoexist,
} }
if ((coex_sta->bt_info_ext & BIT3)) { if (!btcoexist->manual_control && !wifi_under_5g) {
btc8821a2ant_ignore_wlan_act(btcoexist, RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
FORCE_EXEC, false); "[BTCoex], BT ext info = 0x%x!!\n",
} else { coex_sta->bt_info_ext);
/* BT already NOT ignore Wlan active, do nothing here.*/ if ((coex_sta->bt_info_ext & BIT(3))) {
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
"[BTCoex], BT ext info bit3=1, wifi_connected=%d\n",
wifi_connected);
if (wifi_connected) {
RT_TRACE(rtlpriv, COMP_BT_COEXIST,
DBG_LOUD,
"[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n");
btc8821a2ant_ignore_wlan_act(btcoexist,
FORCE_EXEC,
false);
}
} else {
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
"[BTCoex], BT ext info bit3=0, wifi_connected=%d\n",
wifi_connected);
/* BT already NOT ignore Wlan active, do nothing
* here.
*/
if (!wifi_connected) {
RT_TRACE(rtlpriv, COMP_BT_COEXIST,
DBG_LOUD,
"[BTCoex], BT ext info bit3 check, set BT to ignore Wlan active!!\n");
btc8821a2ant_ignore_wlan_act(
btcoexist, FORCE_EXEC, true);
}
}
} }
} }
btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
/* check BIT2 first ==> check if bt is under inquiry or page scan*/ /* check BIT2 first ==> check if bt is under inquiry or page scan*/
if (bt_info & BT_INFO_8821A_2ANT_B_INQ_PAGE) { if (bt_info & BT_INFO_8821A_2ANT_B_INQ_PAGE) {
coex_sta->c2h_bt_inquiry_page = true; coex_sta->c2h_bt_inquiry_page = true;
coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_NON_IDLE;
} else { } else {
coex_sta->c2h_bt_inquiry_page = false; coex_sta->c2h_bt_inquiry_page = false;
if (bt_info == 0x1) { }
/* connection exists but not busy*/ /* set link exist status */
coex_sta->bt_link_exist = true; if (!(bt_info & BT_INFO_8821A_2ANT_B_CONNECTION)) {
coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_CON_IDLE; coex_sta->bt_link_exist = false;
} else if (bt_info & BT_INFO_8821A_2ANT_B_CONNECTION) { coex_sta->pan_exist = false;
/* connection exists and some link is busy*/ coex_sta->a2dp_exist = false;
coex_sta->bt_link_exist = true; coex_sta->hid_exist = false;
if (bt_info & BT_INFO_8821A_2ANT_B_FTP) coex_sta->sco_exist = false;
coex_sta->pan_exist = true; } else { /* connection exists */
else coex_sta->bt_link_exist = true;
coex_sta->pan_exist = false; if (bt_info & BT_INFO_8821A_2ANT_B_FTP)
if (bt_info & BT_INFO_8821A_2ANT_B_A2DP) coex_sta->pan_exist = true;
coex_sta->a2dp_exist = true; else
else
coex_sta->a2dp_exist = false;
if (bt_info & BT_INFO_8821A_2ANT_B_HID)
coex_sta->hid_exist = true;
else
coex_sta->hid_exist = false;
if (bt_info & BT_INFO_8821A_2ANT_B_SCO_ESCO)
coex_sta->sco_exist = true;
else
coex_sta->sco_exist = false;
coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_NON_IDLE;
} else {
coex_sta->bt_link_exist = false;
coex_sta->pan_exist = false; coex_sta->pan_exist = false;
if (bt_info & BT_INFO_8821A_2ANT_B_A2DP)
coex_sta->a2dp_exist = true;
else
coex_sta->a2dp_exist = false; coex_sta->a2dp_exist = false;
if (bt_info & BT_INFO_8821A_2ANT_B_HID)
coex_sta->hid_exist = true;
else
coex_sta->hid_exist = false; coex_sta->hid_exist = false;
if (bt_info & BT_INFO_8821A_2ANT_B_SCO_ESCO)
coex_sta->sco_exist = true;
else
coex_sta->sco_exist = false; coex_sta->sco_exist = false;
coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_IDLE;
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;
} }
}
btc8821a2ant_update_bt_link_info(btcoexist);
btc8821a2ant_update_bt_link_info(btcoexist); if (!(bt_info & BT_INFO_8821A_2ANT_B_CONNECTION)) {
coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_IDLE;
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
"[BTCoex], BtInfoNotify(), BT Non-Connected idle!!!\n");
} else if (bt_info == BT_INFO_8821A_2ANT_B_CONNECTION) {
/* connection exists but no busy */
coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_CON_IDLE;
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
"[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n");
} else if ((bt_info & BT_INFO_8821A_2ANT_B_SCO_ESCO) ||
(bt_info & BT_INFO_8821A_2ANT_B_SCO_BUSY)) {
coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_SCO_BUSY;
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
"[BTCoex], BtInfoNotify(), BT SCO busy!!!\n");
} else if (bt_info & BT_INFO_8821A_2ANT_B_ACL_BUSY) {
coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_ACL_BUSY;
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
"[BTCoex], BtInfoNotify(), BT ACL busy!!!\n");
} else {
coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_MAX;
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
"[BTCoex], BtInfoNotify(), BT Non-Defined state!!!\n");
} }
if (BT_8821A_2ANT_BT_STATUS_NON_IDLE == coex_dm->bt_status) if ((coex_dm->bt_status == BT_8821A_2ANT_BT_STATUS_ACL_BUSY) ||
(coex_dm->bt_status == BT_8821A_2ANT_BT_STATUS_SCO_BUSY) ||
(coex_dm->bt_status == BT_8821A_2ANT_BT_STATUS_ACL_SCO_BUSY)) {
bt_busy = true; bt_busy = true;
else limited_dig = true;
} else {
bt_busy = false; bt_busy = false;
limited_dig = false;
}
btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy); btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy);
if (BT_8821A_2ANT_BT_STATUS_IDLE != coex_dm->bt_status)
limited_dig = true;
else
limited_dig = false;
coex_dm->limited_dig = limited_dig; coex_dm->limited_dig = limited_dig;
btcoexist->btc_set(btcoexist, btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_LIMITED_DIG, &limited_dig);
BTC_SET_BL_BT_LIMITED_DIG, &limited_dig);
btc8821a2ant_run_coexist_mechanism(btcoexist); btc8821a2ant_run_coexist_mechanism(btcoexist);
} }
......
...@@ -54,6 +54,9 @@ enum _BT_8821A_2ANT_BT_STATUS { ...@@ -54,6 +54,9 @@ enum _BT_8821A_2ANT_BT_STATUS {
BT_8821A_2ANT_BT_STATUS_IDLE = 0x0, BT_8821A_2ANT_BT_STATUS_IDLE = 0x0,
BT_8821A_2ANT_BT_STATUS_CON_IDLE = 0x1, BT_8821A_2ANT_BT_STATUS_CON_IDLE = 0x1,
BT_8821A_2ANT_BT_STATUS_NON_IDLE = 0x2, BT_8821A_2ANT_BT_STATUS_NON_IDLE = 0x2,
BT_8821A_2ANT_BT_STATUS_ACL_BUSY = 0x3,
BT_8821A_2ANT_BT_STATUS_SCO_BUSY = 0x4,
BT_8821A_2ANT_BT_STATUS_ACL_SCO_BUSY = 0x5,
BT_8821A_2ANT_BT_STATUS_MAX BT_8821A_2ANT_BT_STATUS_MAX
}; };
...@@ -143,6 +146,7 @@ struct coex_sta_8821a_2ant { ...@@ -143,6 +146,7 @@ struct coex_sta_8821a_2ant {
u32 low_priority_tx; u32 low_priority_tx;
u32 low_priority_rx; u32 low_priority_rx;
u8 bt_rssi; u8 bt_rssi;
bool bt_tx_rx_mask;
u8 pre_bt_rssi_state; u8 pre_bt_rssi_state;
u8 pre_wifi_rssi_state[4]; u8 pre_wifi_rssi_state[4];
bool c2h_bt_info_req_sent; bool c2h_bt_info_req_sent;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment