/******************************************************************************
|
*
|
* Copyright(c) 2016 - 2017 Realtek Corporation.
|
*
|
* This program is free software; you can redistribute it and/or modify it
|
* under the terms of version 2 of the GNU General Public License as
|
* published by the Free Software Foundation.
|
*
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
* more details.
|
*
|
*****************************************************************************/
|
|
#include "mp_precomp.h"
|
|
#if (BT_SUPPORT == 1 && COEX_SUPPORT == 1)
|
|
static u8 *trace_buf = &gl_btc_trace_buf[0];
|
static const u32 coex_ver_date = 20211210;
|
static const u32 coex_ver = 0x27;
|
|
static u8
|
rtw_btc_rssi_state(struct btc_coexist *btc, u8 pre_state,
|
u8 rssi, u8 rssi_thresh)
|
{
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
u8 next_state, tol = chip_para->rssi_tolerance;
|
|
if (pre_state == BTC_RSSI_STATE_LOW ||
|
pre_state == BTC_RSSI_STATE_STAY_LOW) {
|
if (rssi >= (rssi_thresh + tol))
|
next_state = BTC_RSSI_STATE_HIGH;
|
else
|
next_state = BTC_RSSI_STATE_STAY_LOW;
|
} else {
|
if (rssi < rssi_thresh)
|
next_state = BTC_RSSI_STATE_LOW;
|
else
|
next_state = BTC_RSSI_STATE_STAY_HIGH;
|
}
|
|
return next_state;
|
}
|
|
static void
|
rtw_btc_limited_tx(struct btc_coexist *btc, boolean force_exec,
|
boolean tx_limit_en, boolean ampdu_limit_en)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_wifi_link_info_ext *link_info_ext = &btc->wifi_link_info_ext;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
boolean wl_b_mode = FALSE;
|
|
if (!chip_para->scbd_support)
|
return;
|
|
/* Force Max Tx retry limit = 8 */
|
if (!force_exec && tx_limit_en == coex_sta->wl_tx_limit_en &&
|
ampdu_limit_en == coex_sta->wl_ampdu_limit_en)
|
return;
|
|
/* backup MAC reg */
|
if (!coex_sta->wl_tx_limit_en) {
|
coex_sta->wl_arfb1 = btc->btc_read_4byte(btc, REG_DARFRC);
|
coex_sta->wl_arfb2 = btc->btc_read_4byte(btc, REG_DARFRCH);
|
|
coex_sta->wl_txlimit = btc->btc_read_2byte(btc,
|
REG_RETRY_LIMIT);
|
}
|
|
if (!coex_sta->wl_ampdu_limit_en)
|
coex_sta->wl_ampdulen =
|
btc->btc_read_1byte(btc, REG_AMPDU_MAX_TIME_V1);
|
|
coex_sta->wl_tx_limit_en = tx_limit_en;
|
coex_sta->wl_ampdu_limit_en = ampdu_limit_en;
|
|
if (tx_limit_en) {
|
/* Set BT polluted packet on for Tx rate adaptive
|
* Set queue life time to avoid can't reach tx retry limit
|
* if tx is always break by GNT_BT.
|
*/
|
btc->btc_write_1byte_bitmask(btc, REG_TX_HANG_CTRL,
|
BIT_EN_GNT_BT_AWAKE, 0x1);
|
|
/* queue life time can't on if 2-port */
|
if (link_info_ext->num_of_active_port <= 1)
|
btc->btc_write_1byte_bitmask(btc, REG_LIFETIME_EN, 0xf,
|
0xf);
|
else
|
btc->btc_write_1byte_bitmask(btc, REG_LIFETIME_EN, 0xf,
|
0x0);
|
|
/* Max Tx retry limit = 8*/
|
btc->btc_write_2byte(btc, REG_RETRY_LIMIT, 0x0808);
|
|
btc->btc_get(btc, BTC_GET_BL_WIFI_UNDER_B_MODE, &wl_b_mode);
|
|
/* Auto rate fallback step within 8 retry*/
|
if (wl_b_mode) {
|
btc->btc_write_4byte(btc, REG_DARFRC, 0x1000000);
|
btc->btc_write_4byte(btc, REG_DARFRCH, 0x1010101);
|
} else {
|
btc->btc_write_4byte(btc, REG_DARFRC, 0x1000000);
|
btc->btc_write_4byte(btc, REG_DARFRCH, 0x4030201);
|
}
|
} else {
|
/* Set BT polluted packet on for Tx rate adaptive not
|
*including Tx retry break by PTA, 0x45c[19] =1
|
*/
|
btc->btc_write_1byte_bitmask(btc, REG_TX_HANG_CTRL,
|
BIT_EN_GNT_BT_AWAKE, 0x0);
|
|
/* Set queue life time to avoid can't reach tx retry limit
|
* if tx is always break by GNT_BT.
|
*/
|
btc->btc_write_1byte_bitmask(btc, REG_LIFETIME_EN, 0xf, 0x0);
|
|
/* Recovery Max Tx retry limit*/
|
btc->btc_write_2byte(btc, REG_RETRY_LIMIT,
|
coex_sta->wl_txlimit);
|
btc->btc_write_4byte(btc, REG_DARFRC, coex_sta->wl_arfb1);
|
btc->btc_write_4byte(btc, REG_DARFRCH, coex_sta->wl_arfb2);
|
}
|
|
if (ampdu_limit_en)
|
btc->btc_write_1byte(btc, REG_AMPDU_MAX_TIME_V1, 0x20);
|
else
|
btc->btc_write_1byte(btc, REG_AMPDU_MAX_TIME_V1,
|
coex_sta->wl_ampdulen);
|
}
|
|
static void
|
rtw_btc_limited_rx(struct btc_coexist *btc, boolean force_exec,
|
boolean rej_ap_agg_pkt, boolean bt_ctrl_agg_buf_size,
|
u8 agg_buf_size)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
boolean reject_rx_agg = rej_ap_agg_pkt;
|
boolean bt_ctrl_rx_agg_size = bt_ctrl_agg_buf_size;
|
u8 rx_agg_size = agg_buf_size;
|
|
if (!force_exec &&
|
bt_ctrl_agg_buf_size == coex_sta->wl_rxagg_limit_en &&
|
agg_buf_size == coex_sta->wl_rxagg_size)
|
return;
|
|
coex_sta->wl_rxagg_limit_en = bt_ctrl_agg_buf_size;
|
coex_sta->wl_rxagg_size = agg_buf_size;
|
|
/*btc->btc_set(btc, BTC_SET_BL_TO_REJ_AP_AGG_PKT, &reject_rx_agg);*/
|
/* decide BT control aggregation buf size or not */
|
btc->btc_set(btc, BTC_SET_BL_BT_CTRL_AGG_SIZE, &bt_ctrl_rx_agg_size);
|
/* aggregation buf size, only work
|
* when BT control Rx aggregation size
|
*/
|
btc->btc_set(btc, BTC_SET_U1_AGG_BUF_SIZE, &rx_agg_size);
|
/* real update aggregation setting */
|
btc->btc_set(btc, BTC_SET_ACT_AGGREGATE_CTRL, NULL);
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], aggregation size = %d!!\n", agg_buf_size);
|
BTC_TRACE(trace_buf);
|
}
|
|
static void
|
rtw_btc_low_penalty_ra(struct btc_coexist *btc, boolean force_exec,
|
boolean low_penalty_ra, u8 thres)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
|
if (!force_exec) {
|
if (low_penalty_ra == coex_dm->cur_low_penalty_ra &&
|
thres == coex_sta->wl_ra_thres)
|
return;
|
}
|
|
if (low_penalty_ra)
|
btc->btc_phydm_modify_RA_PCR_threshold(btc, 0, thres);
|
else
|
btc->btc_phydm_modify_RA_PCR_threshold(btc, 0, 0);
|
|
coex_dm->cur_low_penalty_ra = low_penalty_ra;
|
coex_sta->wl_ra_thres = thres;
|
}
|
|
static void
|
rtw_btc_limited_wl(struct btc_coexist *btc)
|
{
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_wifi_link_info_ext *link_info_ext = &btc->wifi_link_info_ext;
|
|
if (link_info_ext->is_all_under_5g ||
|
link_info_ext->num_of_active_port == 0 ||
|
coex_dm->bt_status == BTC_BTSTATUS_NCON_IDLE) {
|
rtw_btc_low_penalty_ra(btc, NM_EXCU, FALSE, 0);
|
rtw_btc_limited_tx(btc, NM_EXCU, FALSE, FALSE);
|
rtw_btc_limited_rx(btc, NM_EXCU, FALSE, TRUE, 64);
|
} else if (link_info_ext->num_of_active_port > 1) {
|
rtw_btc_low_penalty_ra(btc, NM_EXCU, TRUE, 30);
|
rtw_btc_limited_tx(btc, NM_EXCU, TRUE, TRUE);
|
rtw_btc_limited_rx(btc, NM_EXCU, FALSE, TRUE, 16);
|
} else {
|
if (link_info_ext->is_p2p_connected)
|
rtw_btc_low_penalty_ra(btc, NM_EXCU, TRUE, 30);
|
else
|
rtw_btc_low_penalty_ra(btc, NM_EXCU, TRUE, 15);
|
|
if (coex_sta->bt_hid_exist || coex_sta->bt_hid_pair_num > 0 ||
|
coex_sta->bt_hfp_exist)
|
rtw_btc_limited_tx(btc, NM_EXCU, TRUE, TRUE);
|
else
|
rtw_btc_limited_tx(btc, NM_EXCU, TRUE, FALSE);
|
|
/*COEX-361, solve wifi poor performance when BLE HID exists*/
|
if ((coex_sta->bt_ble_hid_exist || coex_sta->bt_hfp_exist) &&
|
coex_sta->wl_iot_peer != BTC_IOT_PEER_ATHEROS &&
|
btc->board_info.btdm_ant_num == 1)
|
rtw_btc_limited_rx(btc, NM_EXCU, FALSE, TRUE, 4);
|
else
|
rtw_btc_limited_rx(btc, NM_EXCU, FALSE, TRUE, 64);
|
}
|
|
|
}
|
|
static void
|
rtw_btc_mailbox_operation(struct btc_coexist *btc, u8 h2c_id, u8 h2c_len,
|
u8 *h2c_para)
|
{
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
u8 buf[6] = {0};
|
|
if (chip_para->mailbox_support) {
|
btc->btc_fill_h2c(btc, h2c_id, h2c_len, h2c_para);
|
return;
|
}
|
|
switch (h2c_id) {
|
case 0x61:
|
buf[0] = 3;
|
buf[1] = 0x1; /* polling enable, 1=enable, 0=disable */
|
buf[2] = 0x2; /* polling time in seconds */
|
buf[3] = 0x1; /* auto report enable, 1=enable, 0=disable */
|
|
btc->btc_set(btc, BTC_SET_ACT_CTRL_BT_INFO, (void *)&buf[0]);
|
break;
|
case 0x62:
|
buf[0] = 4;
|
buf[1] = 0x3; /* OP_Code */
|
buf[2] = 0x2; /* OP_Code_Length */
|
buf[3] = (h2c_para[0] != 0) ? 0x1 : 0x0; /* OP_Code_Content */
|
buf[4] = h2c_para[0];/* pwr_level */
|
|
btc->btc_set(btc, BTC_SET_ACT_CTRL_BT_COEX, (void *)&buf[0]);
|
break;
|
case 0x63:
|
buf[0] = 3;
|
buf[1] = 0x1; /* OP_Code */
|
buf[2] = 0x1; /* OP_Code_Length */
|
buf[3] = (h2c_para[0] == 0x1) ? 0x1 : 0x0; /* OP_Code_Content */
|
|
btc->btc_set(btc, BTC_SET_ACT_CTRL_BT_COEX, (void *)&buf[0]);
|
break;
|
case 0x66:
|
buf[0] = 5;
|
buf[1] = 0x5; /* OP_Code */
|
buf[2] = 0x3; /* OP_Code_Length */
|
buf[3] = h2c_para[0]; /* OP_Code_Content */
|
buf[4] = h2c_para[1];
|
buf[5] = h2c_para[2];
|
|
btc->btc_set(btc, BTC_SET_ACT_CTRL_BT_COEX, (void *)&buf[0]);
|
break;
|
}
|
}
|
|
static boolean
|
rtw_btc_freerun_check(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
struct btc_wifi_link_info_ext *link_info_ext = &btc->wifi_link_info_ext;
|
u8 bt_rssi;
|
|
if (coex_sta->force_freerun)
|
return TRUE;
|
|
if (coex_sta->force_tdd)
|
return FALSE;
|
|
if (coex_sta->bt_disabled)
|
return FALSE;
|
|
if (btc->board_info.btdm_ant_num == 1 ||
|
btc->board_info.ant_distance <= 5 || !coex_sta->wl_gl_busy)
|
return FALSE;
|
|
if (btc->board_info.ant_distance >= 40 ||
|
coex_sta->bt_hid_pair_num >= 2)
|
return TRUE;
|
|
/* ant_distance = 5 ~ 40 */
|
if (BTC_RSSI_HIGH(coex_dm->wl_rssi_state[1]) &&
|
BTC_RSSI_HIGH(coex_dm->bt_rssi_state[0]))
|
return TRUE;
|
|
if (link_info_ext->traffic_dir == BTC_WIFI_TRAFFIC_TX)
|
bt_rssi = coex_dm->bt_rssi_state[0];
|
else
|
bt_rssi = coex_dm->bt_rssi_state[1];
|
|
if (BTC_RSSI_HIGH(coex_dm->wl_rssi_state[3]) &&
|
BTC_RSSI_HIGH(bt_rssi) &&
|
coex_sta->cnt_wl[BTC_CNT_WL_SCANAP] <= 5)
|
return TRUE;
|
|
return FALSE;
|
}
|
|
static void
|
rtw_btc_wl_leakap(struct btc_coexist *btc, boolean enable)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
u8 h2c_para[2] = {0xc, 0};
|
|
if (coex_sta->wl_leak_ap == enable)
|
return;
|
|
if (enable) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], turn on Leak-AP Rx Protection!!\n");
|
|
h2c_para[1] = 0x0;
|
} else {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], turn off Leak-AP Rx Protection!!\n");
|
|
h2c_para[1] = 0x1;
|
}
|
|
BTC_TRACE(trace_buf);
|
btc->btc_fill_h2c(btc, 0x69, 2, h2c_para);
|
coex_sta->wl_leak_ap = enable;
|
coex_sta->cnt_wl[BTC_CNT_WL_LEAKAP_NORX] = 0;
|
}
|
|
static void
|
rtw_btc_wl_ccklock_action(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
u8 h2c_parameter[2] = {0}, ap_leak_rx_cnt = 0;
|
boolean wifi_busy = FALSE;
|
|
if (btc->manual_control || btc->stop_coex_dm)
|
return;
|
|
if (!coex_sta->wl_gl_busy ||
|
coex_sta->wl_iot_peer == BTC_IOT_PEER_CISCO) {
|
coex_sta->cnt_wl[BTC_CNT_WL_LEAKAP_NORX] = 0;
|
return;
|
}
|
|
ap_leak_rx_cnt = coex_sta->wl_fw_dbg_info[7];
|
/* Get realtime wifi_busy status */
|
btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
|
|
if (coex_sta->wl_leak_ap && coex_sta->wl_force_lps_ctrl &&
|
!coex_sta->wl_cck_lock_ever) {
|
if (ap_leak_rx_cnt <= 5 && wifi_busy)
|
coex_sta->cnt_wl[BTC_CNT_WL_LEAKAP_NORX]++;
|
else
|
coex_sta->cnt_wl[BTC_CNT_WL_LEAKAP_NORX] = 0;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], Leak-AP Rx extend cnt = %d!!\n",
|
coex_sta->cnt_wl[BTC_CNT_WL_LEAKAP_NORX]);
|
BTC_TRACE(trace_buf);
|
|
/* If 7-streak ap_leak_rx_cnt <= 5, turn off leak-AP for TP*/
|
if (coex_sta->cnt_wl[BTC_CNT_WL_LEAKAP_NORX] >= 7)
|
rtw_btc_wl_leakap(btc, FALSE);
|
} else if (!coex_sta->wl_leak_ap && coex_sta->wl_cck_lock) {
|
rtw_btc_wl_leakap(btc, TRUE);
|
}
|
}
|
|
static void
|
rtw_btc_wl_ccklock_detect(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
struct btc_wifi_link_info_ext *link_info_ext = &btc->wifi_link_info_ext;
|
boolean is_cck_lock_rate = FALSE;
|
|
if (coex_dm->bt_status == BTC_BTSTATUS_INQ_PAGE ||
|
coex_sta->bt_setup_link)
|
return;
|
|
if (coex_sta->wl_rx_rate <= BTC_CCK_2 ||
|
coex_sta->wl_rts_rx_rate <= BTC_CCK_2)
|
is_cck_lock_rate = TRUE;
|
|
if (link_info_ext->is_connected && coex_sta->wl_gl_busy &&
|
BTC_RSSI_HIGH(coex_dm->wl_rssi_state[3]) &&
|
(coex_dm->bt_status == BTC_BTSTATUS_ACL_BUSY ||
|
coex_dm->bt_status == BTC_BTSTATUS_ACL_SCO_BUSY ||
|
coex_dm->bt_status == BTC_BTSTATUS_SCO_BUSY)) {
|
if (is_cck_lock_rate) {
|
coex_sta->wl_cck_lock = TRUE;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], cck locking...\n");
|
BTC_TRACE(trace_buf);
|
} else {
|
coex_sta->wl_cck_lock = FALSE;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], cck unlock...\n");
|
BTC_TRACE(trace_buf);
|
}
|
} else {
|
coex_sta->wl_cck_lock = FALSE;
|
}
|
|
/* CCK lock identification */
|
if (coex_sta->wl_cck_lock && !coex_sta->wl_cck_lock_pre)
|
btc->btc_set_timer(btc, BTC_TIMER_WL_CCKLOCK, 6);
|
|
coex_sta->wl_cck_lock_pre = coex_sta->wl_cck_lock;
|
}
|
|
static void
|
rtw_btc_set_extend_btautoslot(struct btc_coexist *btc, u8 thres)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
u8 h2c_para[2] = {0x9, 0x32};
|
|
if (coex_sta->bt_ext_autoslot_thres == thres)
|
return;
|
|
h2c_para[1] = thres; /* thres must be 50 ~ 80*/
|
|
coex_sta->bt_ext_autoslot_thres = h2c_para[1];
|
|
btc->btc_fill_h2c(btc, 0x69, 2, h2c_para);
|
}
|
|
static void
|
rtw_btc_set_tdma_timer_base(struct btc_coexist *btc, u8 type)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
u16 tbtt_interval = 100;
|
u8 h2c_para[2] = {0xb, 0x1};
|
|
btc->btc_get(btc, BTC_GET_U2_BEACON_PERIOD, &tbtt_interval);
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], tbtt_interval = %d\n", tbtt_interval);
|
BTC_TRACE(trace_buf);
|
|
/* Add for JIRA coex-256 */
|
if (type == 3 && tbtt_interval >= 100) { /* 50ms-slot */
|
if (coex_sta->tdma_timer_base == 3)
|
return;
|
|
h2c_para[1] = (tbtt_interval / 50) - 1;
|
h2c_para[1] = h2c_para[1] | 0xc0; /* 50ms-slot */
|
coex_sta->tdma_timer_base = 3;
|
} else if (tbtt_interval < 80 && tbtt_interval > 0) {
|
if (coex_sta->tdma_timer_base == 2)
|
return;
|
h2c_para[1] = (100 / tbtt_interval);
|
|
if (100 % tbtt_interval != 0)
|
h2c_para[1] = h2c_para[1] + 1;
|
|
h2c_para[1] = h2c_para[1] & 0x3f;
|
coex_sta->tdma_timer_base = 2;
|
} else if (tbtt_interval >= 180) {
|
if (coex_sta->tdma_timer_base == 1)
|
return;
|
h2c_para[1] = (tbtt_interval / 100);
|
|
if (tbtt_interval % 100 <= 80)
|
h2c_para[1] = h2c_para[1] - 1;
|
|
h2c_para[1] = h2c_para[1] & 0x3f;
|
h2c_para[1] = h2c_para[1] | 0x80;
|
coex_sta->tdma_timer_base = 1;
|
} else {
|
if (coex_sta->tdma_timer_base == 0)
|
return;
|
h2c_para[1] = 0x1;
|
coex_sta->tdma_timer_base = 0;
|
}
|
|
btc->btc_fill_h2c(btc, 0x69, 2, h2c_para);
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): h2c_0x69 = 0x%x\n", __func__, h2c_para[1]);
|
BTC_TRACE(trace_buf);
|
}
|
|
static void
|
rtw_btc_set_wl_pri_mask(struct btc_coexist *btc, u8 bitmap, u8 data)
|
{
|
u32 addr;
|
|
addr = REG_BT_COEX_TABLE_H + (bitmap / 8);
|
bitmap = bitmap % 8;
|
|
btc->btc_write_1byte_bitmask(btc, addr, BIT(bitmap), data);
|
}
|
|
static void
|
rtw_btc_set_bt_golden_rx_range(struct btc_coexist *btc, boolean force_exec,
|
u8 profile_id, u8 shift_level)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
u16 para;
|
|
if (profile_id > 3)
|
return;
|
|
if (!force_exec &&
|
shift_level == coex_sta->bt_golden_rx_shift[profile_id])
|
return;
|
|
coex_sta->bt_golden_rx_shift[profile_id] = shift_level;
|
|
para = (profile_id << 8) | ((0x100 - shift_level) & 0xff);
|
|
btc->btc_set(btc, BTC_SET_BL_BT_GOLDEN_RX_RANGE, ¶);
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): para = 0x%04x\n", __func__, para);
|
BTC_TRACE(trace_buf);
|
}
|
|
static void
|
rtw_btc_query_bt_info(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
u8 h2c_parameter[1] = {0x1};
|
|
if (coex_sta->bt_disabled)
|
return;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_mailbox_operation(btc, 0x61, 1, h2c_parameter);
|
}
|
|
static void
|
rtw_btc_gnt_debug(struct btc_coexist *btc, boolean isenable)
|
{
|
if (!isenable)
|
btc->btc_write_1byte_bitmask(btc, 0x73, 0x8, 0x0);
|
else
|
btc->chip_para->chip_setup(btc, BTC_CSETUP_GNT_DEBUG);
|
}
|
|
static void
|
rtw_btc_gnt_workaround(struct btc_coexist *btc, boolean force_exec, u8 mode)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
|
if (!force_exec) {
|
if (coex_sta->gnt_workaround_state == coex_sta->wl_coex_mode)
|
return;
|
}
|
|
coex_sta->gnt_workaround_state = coex_sta->wl_coex_mode;
|
|
btc->chip_para->chip_setup(btc, BTC_CSETUP_GNT_FIX);
|
}
|
|
static void
|
rtw_btc_monitor_bt_enable(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
boolean bt_disabled = FALSE;
|
u16 scbd;
|
u32 scbd_32;
|
|
if (chip_para->scbd_support) {
|
if (chip_para->scbd_bit_num == BTC_SCBD_16_BIT) {
|
btc->btc_read_scbd(btc, &scbd);
|
bt_disabled = (scbd & BTC_SCBD_BT_ONOFF) ? FALSE : TRUE;
|
} else {
|
btc->btc_read_scbd_32bit(btc, &scbd_32);
|
bt_disabled = (scbd_32 & BTC_SCBD_BT_ONOFF) ? FALSE : TRUE;
|
}
|
|
} else {
|
if (coex_sta->cnt_bt[BTC_CNT_BT_DISABLE] >= 2)
|
bt_disabled = TRUE;
|
}
|
|
btc->btc_set(btc, BTC_SET_BL_BT_DISABLE, &bt_disabled);
|
|
if (coex_sta->bt_disabled != bt_disabled) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], BT is from %s to %s!!\n",
|
(coex_sta->bt_disabled ? "disabled" : "enabled"),
|
(bt_disabled ? "disabled" : "enabled"));
|
BTC_TRACE(trace_buf);
|
coex_sta->bt_disabled = bt_disabled;
|
|
coex_sta->bt_supported_feature = 0;
|
coex_sta->bt_supported_version = 0;
|
coex_sta->bt_ble_scan_type = 0;
|
coex_sta->bt_ble_scan_para[0] = 0;
|
coex_sta->bt_ble_scan_para[1] = 0;
|
coex_sta->bt_ble_scan_para[2] = 0;
|
coex_sta->bt_reg_vendor_ac = 0xffff;
|
coex_sta->bt_reg_vendor_ae = 0xffff;
|
coex_sta->bt_a2dp_vendor_id = 0;
|
coex_sta->bt_a2dp_device_name = 0;
|
coex_sta->bt_iqk_state = 0;
|
coex_dm->cur_bt_lna_lvl = 0;
|
btc->bt_info.bt_get_fw_ver = 0;
|
|
/*for win10 BT disable->enable trigger wifi scan issue */
|
if (!coex_sta->bt_disabled) {
|
coex_sta->bt_reenable = TRUE;
|
btc->btc_set_timer(btc, BTC_TIMER_BT_REENABLE, 15);
|
} else {
|
coex_sta->bt_reenable = FALSE;
|
}
|
}
|
}
|
|
static void
|
rtw_btc_update_bt_sut_info(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
u32 val = 0;
|
|
if (coex_sta->bt_profile_num == 0) {
|
/* clear golden rx range if no PAN exist */
|
if (coex_sta->bt_golden_rx_shift[3] != 0)
|
rtw_btc_set_bt_golden_rx_range(btc, FC_EXCU, 3, 0);
|
return;
|
}
|
|
if (coex_sta->bt_a2dp_exist)
|
rtw_btc_set_bt_golden_rx_range(btc, FC_EXCU, 2, 0);
|
else
|
coex_sta->bt_sut_pwr_lvl[2] = 0xff;
|
|
if (coex_sta->bt_hfp_exist)
|
rtw_btc_set_bt_golden_rx_range(btc, FC_EXCU, 0, 0);
|
else
|
coex_sta->bt_sut_pwr_lvl[0] = 0xff;
|
|
if (coex_sta->bt_hid_exist)
|
rtw_btc_set_bt_golden_rx_range(btc, FC_EXCU, 1, 0);
|
else
|
coex_sta->bt_sut_pwr_lvl[1] = 0xff;
|
|
if (coex_sta->bt_pan_exist) {
|
rtw_btc_set_bt_golden_rx_range(btc, FC_EXCU, 3,
|
coex_sta->bt_golden_rx_shift[3]);
|
} else {
|
coex_sta->bt_golden_rx_shift[3] = 0;
|
coex_sta->bt_sut_pwr_lvl[3] = 0xff;
|
}
|
}
|
|
static void
|
rtw_btc_update_wl_link_info(struct btc_coexist *btc, u8 reason)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
struct btc_wifi_link_info_ext *linfo_ext = &btc->wifi_link_info_ext;
|
struct btc_wifi_link_info linfo;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
u8 wifi_central_chnl = 0, num_of_wifi_link = 0, i, rssi_state;
|
u32 wifi_link_status = 0, wifi_bw;
|
s32 wl_rssi;
|
boolean isunder5G = FALSE, ismcc25g = FALSE, is_p2p_connected = FALSE,
|
plus_bt = FALSE;
|
|
btc->btc_get(btc, BTC_GET_BL_WIFI_SCAN, &linfo_ext->is_scan);
|
btc->btc_get(btc, BTC_GET_BL_WIFI_LINK, &linfo_ext->is_link);
|
btc->btc_get(btc, BTC_GET_BL_WIFI_ROAM, &linfo_ext->is_roam);
|
btc->btc_get(btc, BTC_GET_BL_WIFI_LW_PWR_STATE, &linfo_ext->is_32k);
|
btc->btc_get(btc, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &linfo_ext->is_4way);
|
btc->btc_get(btc, BTC_GET_BL_WIFI_CONNECTED, &linfo_ext->is_connected);
|
btc->btc_get(btc, BTC_GET_U4_WIFI_TRAFFIC_DIR, &linfo_ext->traffic_dir);
|
btc->btc_get(btc, BTC_GET_U4_WIFI_BW, &linfo_ext->wifi_bw);
|
btc->btc_get(btc, BTC_GET_U4_WIFI_LINK_STATUS, &wifi_link_status);
|
linfo_ext->port_connect_status = wifi_link_status & 0xffff;
|
|
btc->btc_get(btc, BTC_GET_BL_WIFI_LINK_INFO, &linfo);
|
btc->wifi_link_info = linfo;
|
|
btc->btc_get(btc, BTC_GET_U1_WIFI_CENTRAL_CHNL, &wifi_central_chnl);
|
coex_sta->wl_center_ch = wifi_central_chnl;
|
|
btc->btc_get(btc, BTC_GET_S4_WIFI_RSSI, &wl_rssi);
|
for (i = 0; i < 4; i++) {
|
rssi_state = coex_dm->wl_rssi_state[i];
|
rssi_state = rtw_btc_rssi_state(btc, rssi_state,
|
(u8)(wl_rssi & 0xff),
|
chip_para->wl_rssi_step[i]);
|
coex_dm->wl_rssi_state[i] = rssi_state;
|
}
|
|
if (coex_sta->wl_linkscan_proc || coex_sta->wl_hi_pri_task1 ||
|
coex_sta->wl_hi_pri_task2 || coex_sta->wl_gl_busy) {
|
if (chip_para->scbd_bit_num == BTC_SCBD_16_BIT)
|
btc->btc_write_scbd(btc, BTC_SCBD_SCAN, TRUE);
|
else
|
btc->btc_write_scbd_32bit(btc, BTC_SCBD_SCAN, TRUE);
|
} else {
|
if (chip_para->scbd_bit_num == BTC_SCBD_16_BIT)
|
btc->btc_write_scbd(btc, BTC_SCBD_SCAN, FALSE);
|
else
|
btc->btc_write_scbd_32bit(btc, BTC_SCBD_SCAN, FALSE);
|
}
|
|
/* Check scan/connect/special-pkt action first */
|
switch (reason) {
|
case BTC_RSN_5GSCANSTART:
|
case BTC_RSN_5GSWITCHBAND:
|
case BTC_RSN_5GCONSTART:
|
|
isunder5G = TRUE;
|
break;
|
case BTC_RSN_2GSCANSTART:
|
case BTC_RSN_2GSWITCHBAND:
|
case BTC_RSN_2GCONSTART:
|
|
isunder5G = FALSE;
|
break;
|
case BTC_RSN_2GCONFINISH:
|
case BTC_RSN_5GCONFINISH:
|
case BTC_RSN_2GMEDIA:
|
case BTC_RSN_5GMEDIA:
|
case BTC_RSN_BTINFO:
|
case BTC_RSN_PERIODICAL:
|
case BTC_RSN_TIMERUP:
|
case BTC_RSN_WLSTATUS:
|
case BTC_RSN_2GSPECIALPKT:
|
case BTC_RSN_5GSPECIALPKT:
|
default:
|
switch (linfo.link_mode) {
|
case BTC_LINK_5G_MCC_GO_STA:
|
case BTC_LINK_5G_MCC_GC_STA:
|
case BTC_LINK_5G_SCC_GO_STA:
|
case BTC_LINK_5G_SCC_GC_STA:
|
|
isunder5G = TRUE;
|
break;
|
case BTC_LINK_2G_MCC_GO_STA:
|
case BTC_LINK_2G_MCC_GC_STA:
|
case BTC_LINK_2G_SCC_GO_STA:
|
case BTC_LINK_2G_SCC_GC_STA:
|
|
isunder5G = FALSE;
|
break;
|
case BTC_LINK_25G_MCC_GO_STA:
|
case BTC_LINK_25G_MCC_GC_STA:
|
|
isunder5G = FALSE;
|
ismcc25g = TRUE;
|
break;
|
case BTC_LINK_ONLY_STA:
|
if (linfo.sta_center_channel > 14)
|
isunder5G = TRUE;
|
else
|
isunder5G = FALSE;
|
break;
|
case BTC_LINK_ONLY_GO:
|
case BTC_LINK_ONLY_GC:
|
case BTC_LINK_ONLY_AP:
|
default:
|
if (linfo.p2p_center_channel > 14)
|
isunder5G = TRUE;
|
else
|
isunder5G = FALSE;
|
break;
|
}
|
break;
|
}
|
|
linfo_ext->is_all_under_5g = isunder5G;
|
linfo_ext->is_mcc_25g = ismcc25g;
|
|
if (wifi_link_status & WIFI_STA_CONNECTED)
|
num_of_wifi_link++;
|
|
if (wifi_link_status & WIFI_AP_CONNECTED)
|
num_of_wifi_link++;
|
|
if (wifi_link_status & WIFI_P2P_GO_CONNECTED) {
|
if (!(wifi_link_status & WIFI_AP_CONNECTED))
|
num_of_wifi_link++;
|
is_p2p_connected = TRUE;
|
}
|
|
if (wifi_link_status & WIFI_P2P_GC_CONNECTED) {
|
num_of_wifi_link++;
|
is_p2p_connected = TRUE;
|
}
|
|
linfo_ext->num_of_active_port = num_of_wifi_link;
|
linfo_ext->is_p2p_connected = is_p2p_connected;
|
|
if (linfo.link_mode == BTC_LINK_ONLY_GO && linfo.bhotspot)
|
linfo_ext->is_ap_mode = TRUE;
|
else
|
linfo_ext->is_ap_mode = FALSE;
|
|
if (linfo_ext->is_p2p_connected && coex_sta->bt_link_exist)
|
plus_bt = TRUE;
|
|
btc->btc_set(btc, BTC_SET_BL_MIRACAST_PLUS_BT, &plus_bt);
|
|
if (linfo_ext->is_scan || linfo_ext->is_link ||
|
linfo_ext->is_roam || linfo_ext->is_4way ||
|
reason == BTC_RSN_2GSCANSTART ||
|
reason == BTC_RSN_2GSWITCHBAND ||
|
reason == BTC_RSN_2GCONSTART ||
|
reason == BTC_RSN_2GSPECIALPKT)
|
coex_sta->wl_linkscan_proc = TRUE;
|
else
|
coex_sta->wl_linkscan_proc = FALSE;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], scan = %d, link = %d, roam = %d 4way = %d!!!\n",
|
linfo_ext->is_scan, linfo_ext->is_link,
|
linfo_ext->is_roam,
|
linfo_ext->is_4way);
|
BTC_TRACE(trace_buf);
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], wifi_link_info: link_mode=%d, STA_Ch=%d, P2P_Ch=%d, AnyClient_Join_Go=%d !\n",
|
linfo.link_mode,
|
linfo.sta_center_channel,
|
linfo.p2p_center_channel,
|
linfo.bany_client_join_go);
|
BTC_TRACE(trace_buf);
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], wifi_link_info: center_ch=%d, is_all_under_5g=%d, is_mcc_25g=%d!\n",
|
coex_sta->wl_center_ch,
|
linfo_ext->is_all_under_5g,
|
linfo_ext->is_mcc_25g);
|
BTC_TRACE(trace_buf);
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], wifi_link_info: port_connect_status=0x%x, active_port_cnt=%d, P2P_Connect=%d!\n",
|
linfo_ext->port_connect_status,
|
linfo_ext->num_of_active_port,
|
linfo_ext->is_p2p_connected);
|
BTC_TRACE(trace_buf);
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], Update reason = %s\n",
|
run_reason_string[reason]);
|
BTC_TRACE(trace_buf);
|
|
if (btc->manual_control || btc->stop_coex_dm)
|
return;
|
|
/* coex-276 P2P-Go beacon request can't release issue
|
* Only PCIe/USB can set 0x454[6] = 1 to solve this issue,
|
* WL SDIO/USB interface need driver support.
|
*/
|
#ifdef PLATFORM_WINDOWS
|
if (btc->chip_interface != BTC_INTF_SDIO)
|
btc->btc_write_1byte_bitmask(btc, REG_CCK_CHECK,
|
BIT_EN_BCN_PKT_REL, 0x1);
|
else
|
btc->btc_write_1byte_bitmask(btc, REG_CCK_CHECK,
|
BIT_EN_BCN_PKT_REL, 0x0);
|
#endif
|
}
|
|
static void
|
rtw_btc_update_bt_link_info(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
boolean bt_busy = FALSE, increase_scan_dev_num = FALSE,
|
scan_type_change = FALSE;
|
u8 i, scan_type, rssi_state;
|
|
/* update wl/bt rssi by btinfo */
|
for (i = 0; i < 4; i++) {
|
rssi_state = coex_dm->bt_rssi_state[i];
|
rssi_state = rtw_btc_rssi_state(btc, rssi_state,
|
coex_sta->bt_rssi,
|
chip_para->bt_rssi_step[i]);
|
coex_dm->bt_rssi_state[i] = rssi_state;
|
}
|
|
if (coex_sta->bt_ble_scan_en) {
|
scan_type = btc->btc_get_ble_scan_type_from_bt(btc);
|
|
if (scan_type != coex_sta->bt_ble_scan_type)
|
scan_type_change = TRUE;
|
|
coex_sta->bt_ble_scan_type = scan_type;
|
}
|
|
if (scan_type_change) {
|
u32 *p = NULL;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], BTinfo HiByte1[5] check, query BLE Scan type!!\n");
|
BTC_TRACE(trace_buf);
|
|
if ((coex_sta->bt_ble_scan_type & 0x1) == 0x1) {
|
coex_sta->bt_init_scan = TRUE;
|
p = &coex_sta->bt_ble_scan_para[0];
|
*p = btc->btc_get_ble_scan_para_from_bt(btc, 0x1);
|
} else {
|
coex_sta->bt_init_scan = FALSE;
|
}
|
|
if ((coex_sta->bt_ble_scan_type & 0x2) == 0x2) {
|
p = &coex_sta->bt_ble_scan_para[1];
|
*p = btc->btc_get_ble_scan_para_from_bt(btc, 0x2);
|
}
|
|
if ((coex_sta->bt_ble_scan_type & 0x4) == 0x4) {
|
p = &coex_sta->bt_ble_scan_para[2];
|
*p = btc->btc_get_ble_scan_para_from_bt(btc, 0x4);
|
}
|
}
|
|
coex_sta->bt_profile_num = 0;
|
|
/* set link exist status */
|
if (!(coex_sta->bt_info_lb2 & BTC_INFO_CONNECTION)) {
|
coex_sta->bt_link_exist = FALSE;
|
coex_sta->bt_pan_exist = FALSE;
|
coex_sta->bt_a2dp_exist = FALSE;
|
coex_sta->bt_hid_exist = FALSE;
|
coex_sta->bt_hfp_exist = FALSE;
|
coex_sta->bt_msft_mr_exist = FALSE;
|
} else { /* connection exists */
|
coex_sta->bt_link_exist = TRUE;
|
if (coex_sta->bt_info_lb2 & BTC_INFO_FTP) {
|
coex_sta->bt_pan_exist = TRUE;
|
coex_sta->bt_profile_num++;
|
} else {
|
coex_sta->bt_pan_exist = FALSE;
|
}
|
|
if (coex_sta->bt_info_lb2 & BTC_INFO_A2DP) {
|
coex_sta->bt_a2dp_exist = TRUE;
|
coex_sta->bt_profile_num++;
|
} else {
|
coex_sta->bt_a2dp_exist = FALSE;
|
}
|
|
if (coex_sta->bt_info_lb2 & BTC_INFO_HID) {
|
coex_sta->bt_hid_exist = TRUE;
|
coex_sta->bt_profile_num++;
|
} else {
|
coex_sta->bt_hid_exist = FALSE;
|
}
|
|
if (coex_sta->bt_info_lb2 & BTC_INFO_SCO_ESCO) {
|
coex_sta->bt_hfp_exist = TRUE;
|
coex_sta->bt_profile_num++;
|
} else {
|
coex_sta->bt_hfp_exist = FALSE;
|
}
|
}
|
|
if (coex_sta->bt_info_lb2 & BTC_INFO_INQ_PAGE) {
|
coex_dm->bt_status = BTC_BTSTATUS_INQ_PAGE;
|
} else if (!(coex_sta->bt_info_lb2 & BTC_INFO_CONNECTION)) {
|
coex_dm->bt_status = BTC_BTSTATUS_NCON_IDLE;
|
coex_sta->bt_multi_link_remain = FALSE;
|
} else if (coex_sta->bt_info_lb2 == BTC_INFO_CONNECTION) {
|
if (coex_sta->bt_msft_mr_exist)
|
coex_dm->bt_status = BTC_BTSTATUS_ACL_BUSY;
|
else
|
coex_dm->bt_status = BTC_BTSTATUS_CON_IDLE;
|
} else if ((coex_sta->bt_info_lb2 & BTC_INFO_SCO_ESCO) ||
|
(coex_sta->bt_info_lb2 & BTC_INFO_SCO_BUSY)) {
|
if (coex_sta->bt_info_lb2 & BTC_INFO_ACL_BUSY)
|
coex_dm->bt_status = BTC_BTSTATUS_ACL_SCO_BUSY;
|
else
|
coex_dm->bt_status = BTC_BTSTATUS_SCO_BUSY;
|
} else if (coex_sta->bt_info_lb2 & BTC_INFO_ACL_BUSY) {
|
coex_dm->bt_status = BTC_BTSTATUS_ACL_BUSY;
|
} else {
|
coex_dm->bt_status = BTC_BTSTATUS_MAX;
|
}
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s(), %s!!!\n",
|
__func__, bt_status_string[coex_dm->bt_status]);
|
BTC_TRACE(trace_buf);
|
|
if (coex_dm->bt_status == BTC_BTSTATUS_ACL_BUSY ||
|
coex_dm->bt_status == BTC_BTSTATUS_SCO_BUSY ||
|
coex_dm->bt_status == BTC_BTSTATUS_ACL_SCO_BUSY) {
|
bt_busy = TRUE;
|
increase_scan_dev_num = TRUE;
|
} else {
|
bt_busy = FALSE;
|
increase_scan_dev_num = FALSE;
|
}
|
|
btc->btc_set(btc, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy);
|
btc->btc_set(btc, BTC_SET_BL_INC_SCAN_DEV_NUM, &increase_scan_dev_num);
|
|
if (coex_sta->bt_profile_num != coex_sta->bt_profile_num_pre) {
|
rtw_btc_update_bt_sut_info(btc);
|
coex_sta->bt_profile_num_pre = coex_sta->bt_profile_num;
|
|
if (!coex_sta->bt_a2dp_exist) {
|
coex_sta->bt_a2dp_vendor_id = 0;
|
coex_sta->bt_a2dp_device_name = 0;
|
coex_sta->bt_a2dp_flush_time = 0;
|
}
|
}
|
|
coex_sta->cnt_bt[BTC_CNT_BT_INFOUPDATE]++;
|
}
|
|
static void
|
rtw_btc_update_wl_ch_info(struct btc_coexist *btc, u8 type)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
struct btc_wifi_link_info_ext *link_info_ext = &btc->wifi_link_info_ext;
|
struct btc_wifi_link_info *link_info = &btc->wifi_link_info;
|
u8 h2c_para[3] = {0}, i, wl_center_ch = 0;
|
|
if (btc->manual_control)
|
return;
|
|
if (btc->stop_coex_dm || btc->wl_rf_state_off) {
|
wl_center_ch = 0;
|
} else if (type != BTC_MEDIA_DISCONNECT ||
|
(type == BTC_MEDIA_DISCONNECT &&
|
link_info_ext->num_of_active_port > 0)) {
|
if (link_info_ext->num_of_active_port == 1) {
|
if (link_info_ext->is_p2p_connected)
|
wl_center_ch = link_info->p2p_center_channel;
|
else
|
wl_center_ch = link_info->sta_center_channel;
|
} else { /* port > 2 */
|
if (link_info->p2p_center_channel > 14 &&
|
link_info->sta_center_channel > 14)
|
wl_center_ch = link_info->p2p_center_channel;
|
else if (link_info->p2p_center_channel <= 14)
|
wl_center_ch = link_info->p2p_center_channel;
|
else if (link_info->sta_center_channel <= 14)
|
wl_center_ch = link_info->sta_center_channel;
|
}
|
}
|
|
if (wl_center_ch == 0) {
|
h2c_para[0] = 0x0;
|
h2c_para[1] = 0x0;
|
h2c_para[2] = 0x0;
|
} else if(btc->board_info.btdm_ant_num == 1 && wl_center_ch <= 14) {
|
h2c_para[0] = 0x1;
|
h2c_para[1] = wl_center_ch;
|
/* 8723f shared ant, BT should avoid wifi channel */
|
if (link_info_ext->wifi_bw == BTC_WIFI_BW_HT40)
|
h2c_para[2] = 0x28;
|
else
|
h2c_para[2] = 0x14;
|
} else if (wl_center_ch <= 14) {
|
h2c_para[0] = 0x1;
|
h2c_para[1] = wl_center_ch;
|
|
if (link_info_ext->wifi_bw == BTC_WIFI_BW_HT40)
|
h2c_para[2] = chip_para->bt_afh_span_bw40;
|
else
|
h2c_para[2] = chip_para->bt_afh_span_bw20;
|
} else if (chip_para->afh_5g_num > 1) { /* for 5G */
|
for (i = 0; i < chip_para->afh_5g_num; i++) {
|
if (wl_center_ch == chip_para->afh_5g[i].wl_5g_ch) {
|
h2c_para[0] = 0x3;
|
h2c_para[1] = chip_para->afh_5g[i].bt_skip_ch;
|
h2c_para[2] = chip_para->afh_5g[i].bt_skip_span;
|
break;
|
}
|
}
|
}
|
|
/* Only send mailbox if ch info change */
|
if (coex_dm->wl_chnl_info[0] != h2c_para[0] &&
|
coex_dm->wl_chnl_info[1] != h2c_para[1] &&
|
coex_dm->wl_chnl_info[2] != h2c_para[2]) {
|
|
coex_dm->wl_chnl_info[0] = h2c_para[0];
|
coex_dm->wl_chnl_info[1] = h2c_para[1];
|
coex_dm->wl_chnl_info[2] = h2c_para[2];
|
rtw_btc_mailbox_operation(btc, 0x66, 3, h2c_para);
|
}
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s: para[0:2] = 0x%x 0x%x 0x%x\n",
|
__func__, h2c_para[0], h2c_para[1], h2c_para[2]);
|
BTC_TRACE(trace_buf);
|
}
|
|
static void
|
rtw_btc_set_wl_tx_power(struct btc_coexist *btc,
|
boolean force_exec, u8 wl_pwr_dec_lvl)
|
{
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
|
if (!force_exec && wl_pwr_dec_lvl == coex_dm->cur_wl_pwr_lvl)
|
return;
|
|
coex_dm->cur_wl_pwr_lvl = wl_pwr_dec_lvl;
|
|
chip_para->chip_setup(btc, BTC_CSETUP_WL_TX_POWER);
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s(): level = %d\n",
|
__func__, wl_pwr_dec_lvl);
|
BTC_TRACE(trace_buf);
|
}
|
|
static void
|
rtw_btc_set_bt_tx_power(struct btc_coexist *btc,
|
boolean force_exec, u8 bt_pwr_dec_lvl)
|
{
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
u8 h2c_para[1] = {0};
|
|
if (!force_exec && bt_pwr_dec_lvl == coex_dm->cur_bt_pwr_lvl)
|
return;
|
|
h2c_para[0] = (0x100 - bt_pwr_dec_lvl) & 0xff;
|
|
rtw_btc_mailbox_operation(btc, 0x62, 1, h2c_para);
|
|
coex_dm->cur_bt_pwr_lvl = bt_pwr_dec_lvl;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(), bt_tx_power = 0x%x, level = %d\n",
|
__func__, h2c_para[0], bt_pwr_dec_lvl);
|
BTC_TRACE(trace_buf);
|
}
|
|
static void
|
rtw_btc_set_wl_rx_gain(struct btc_coexist *btc, boolean force_exec,
|
boolean low_gain_en)
|
{
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
|
if (!force_exec && low_gain_en == coex_dm->cur_wl_rx_low_gain_en)
|
return;
|
|
coex_dm->cur_wl_rx_low_gain_en = low_gain_en;
|
|
if (low_gain_en)
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], Hi-L Rx!\n");
|
else
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], Nm-L Rx!\n");
|
|
BTC_TRACE(trace_buf);
|
|
chip_para->chip_setup(btc, BTC_CSETUP_WL_RX_GAIN);
|
}
|
|
static void
|
rtw_btc_set_bt_rx_gain(struct btc_coexist *btc, boolean force_exec, u8 lna_lvl)
|
{
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
|
if (!force_exec && lna_lvl == coex_dm->cur_bt_lna_lvl)
|
return;
|
|
if (lna_lvl < 7) {
|
btc->btc_set(btc, BTC_SET_BL_BT_LNA_CONSTRAIN_LEVEL, &lna_lvl);
|
/* use scoreboard[4] to notify BT Rx gain table change */
|
if (chip_para->scbd_bit_num == BTC_SCBD_16_BIT)
|
btc->btc_write_scbd(btc, BTC_SCBD_RXGAIN, TRUE);
|
else
|
btc->btc_write_scbd_32bit(btc, BTC_SCBD_RXGAIN, TRUE);
|
} else {
|
if (chip_para->scbd_bit_num == BTC_SCBD_16_BIT)
|
btc->btc_write_scbd(btc, BTC_SCBD_RXGAIN, FALSE);
|
else
|
btc->btc_write_scbd_32bit(btc, BTC_SCBD_RXGAIN, FALSE);
|
}
|
|
coex_dm->cur_bt_lna_lvl = lna_lvl;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): bt_rx_LNA_level = %d\n",
|
__func__, lna_lvl);
|
BTC_TRACE(trace_buf);
|
}
|
|
static void
|
rtw_btc_set_rf_para(struct btc_coexist *btc, boolean force_exec,
|
struct btc_rf_para para)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
u8 tmp = 0;
|
|
if (coex_sta->coex_freerun) {
|
if (coex_sta->cnt_wl[BTC_CNT_WL_SCANAP] <= 5)
|
tmp = 3;
|
}
|
|
rtw_btc_set_wl_tx_power(btc, force_exec, para.wl_pwr_dec_lvl);
|
rtw_btc_set_bt_tx_power(btc, force_exec, para.bt_pwr_dec_lvl + tmp);
|
rtw_btc_set_wl_rx_gain(btc, force_exec, para.wl_low_gain_en);
|
rtw_btc_set_bt_rx_gain(btc, force_exec, para.bt_lna_lvl);
|
}
|
|
static void
|
rtw_btc_coex_ctrl_owner(struct btc_coexist *btc, boolean wifi_control)
|
{
|
u8 val;
|
|
val = (wifi_control) ? 1 : 0; /* 0x70[26] */
|
btc->btc_write_1byte_bitmask(btc, REG_SYS_SDIO_CTRL3, BIT(2), val);
|
|
if (!wifi_control)
|
btc->chip_para->chip_setup(btc, BTC_CSETUP_BT_CTRL_ACT);
|
}
|
|
static void
|
rtw_btc_set_gnt_bt(struct btc_coexist *btc, u8 state)
|
{
|
if (btc->chip_para->lte_indirect_access) {
|
btc->btc_write_linderct(btc, REG_LTE_IDR_COEX_CTRL, 0xc000, state);
|
btc->btc_write_linderct(btc, REG_LTE_IDR_COEX_CTRL, 0x0c00, state);
|
} else {
|
switch (state) {
|
case BTC_GNT_HW_PTA:
|
btc->btc_write_1byte_bitmask(btc, 0x765, 0x1e, 0x0);
|
btc->btc_write_1byte_bitmask(btc, REG_SYS_SDIO_CTRL3,
|
0x70, 0x0);
|
break;
|
case BTC_GNT_SW_LOW:
|
btc->btc_write_1byte_bitmask(btc, 0x765, 0x1e, 0xf);
|
btc->btc_write_1byte_bitmask(btc, REG_SYS_SDIO_CTRL3,
|
0x70, 0x1);
|
break;
|
case BTC_GNT_SW_HIGH:
|
btc->btc_write_1byte_bitmask(btc, 0x765, 0x1e, 0xf);
|
btc->btc_write_1byte_bitmask(btc, REG_SYS_SDIO_CTRL3,
|
0x70, 0x7);
|
break;
|
default:
|
break;
|
}
|
}
|
}
|
|
static void
|
rtw_btc_set_gnt_wl(struct btc_coexist *btc, u8 state)
|
{
|
if (btc->chip_para->lte_indirect_access) {
|
btc->btc_write_linderct(btc, REG_LTE_IDR_COEX_CTRL, 0x3000, state);
|
btc->btc_write_linderct(btc, REG_LTE_IDR_COEX_CTRL, 0x0300, state);
|
} else {
|
switch (state) {
|
case BTC_GNT_HW_PTA:
|
btc->btc_write_1byte_bitmask(btc, REG_SYS_SDIO_CTRL3,
|
BIT(4), 0x0);
|
btc->btc_write_1byte_bitmask(btc, REG_SYS_SDIO_CTRL3,
|
BIT(7), 0x0);
|
break;
|
case BTC_GNT_SW_LOW:
|
btc->btc_write_1byte_bitmask(btc, REG_SYS_SDIO_CTRL3,
|
BIT(4), 0x1);
|
btc->btc_write_1byte_bitmask(btc, REG_SYS_SDIO_CTRL3,
|
BIT(7), 0x0);
|
break;
|
case BTC_GNT_SW_HIGH:
|
btc->btc_write_1byte_bitmask(btc, REG_SYS_SDIO_CTRL3,
|
BIT(4), 0x1);
|
btc->btc_write_1byte_bitmask(btc, REG_SYS_SDIO_CTRL3,
|
BIT(7), 0x1);
|
break;
|
default:
|
break;
|
}
|
}
|
}
|
|
#ifdef PLATFORM_WINDOWS
|
static void
|
rtw_btc_mimo_ps(struct btc_coexist *btc, boolean force_exec,
|
u8 state)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
|
if (!force_exec && state == coex_sta->wl_mimo_ps)
|
return;
|
|
coex_sta->wl_mimo_ps = state;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): state = %d\n", __func__, state);
|
BTC_TRACE(trace_buf);
|
|
btc->btc_set(btc, BTC_SET_MIMO_PS_MODE, &state);
|
}
|
#endif
|
|
static void
|
rtw_btc_wltoggle_tableA(IN struct btc_coexist *btc,
|
IN boolean force_exec, IN u32 table_case)
|
{
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
u8 h2c_para[6] = {0};
|
u32 table_wl = 0x5a5a5a5a;
|
|
h2c_para[0] = 0xd; /* op_code, 0xd= wlan slot toggle-A*/
|
h2c_para[1] = 0x1; /* no definition */
|
|
if (btc->board_info.btdm_ant_num == 1) {
|
if (table_case < chip_para->table_sant_num)
|
table_wl = chip_para->table_sant[table_case].wl;
|
} else {
|
if (table_case < chip_para->table_nsant_num)
|
table_wl = chip_para->table_nsant[table_case].wl;
|
}
|
|
/* tell WL FW WL slot toggle table-A*/
|
h2c_para[2] = (u8)(table_wl & 0xff);
|
h2c_para[3] = (u8)((table_wl & 0xff00) >> 8);
|
h2c_para[4] = (u8)((table_wl & 0xff0000) >> 16);
|
h2c_para[5] = (u8)((table_wl & 0xff000000) >> 24);
|
|
btc->btc_fill_h2c(btc, 0x69, 6, h2c_para);
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): H2C = [%02x %02x %02x %02x %02x %02x]\n",
|
__func__, h2c_para[0], h2c_para[1], h2c_para[2],
|
h2c_para[3], h2c_para[4], h2c_para[5]);
|
BTC_TRACE(trace_buf);
|
}
|
|
static void
|
rtw_btc_wltoggle_tableB(IN struct btc_coexist *btc, IN boolean force_exec,
|
IN u8 interval, IN u32 table)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
u8 cur_h2c_para[6] = {0};
|
u8 i, match_cnt = 0;
|
|
cur_h2c_para[0] = 0x7; /* op_code, 0x7= wlan slot toggle-B*/
|
cur_h2c_para[1] = interval;
|
cur_h2c_para[2] = (u8)(table & 0xff);
|
cur_h2c_para[3] = (u8)((table & 0xff00) >> 8);
|
cur_h2c_para[4] = (u8)((table & 0xff0000) >> 16);
|
cur_h2c_para[5] = (u8)((table & 0xff000000) >> 24);
|
|
if (ARRAY_SIZE(coex_sta->wl_toggle_para) != 6)
|
return;
|
|
coex_sta->wl_toggle_interval = interval;
|
|
for (i = 0; i <= 5; i++)
|
coex_sta->wl_toggle_para[i] = cur_h2c_para[i];
|
|
btc->btc_fill_h2c(btc, 0x69, 6, cur_h2c_para);
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): H2C = [%02x %02x %02x %02x %02x %02x]\n",
|
__func__, cur_h2c_para[0], cur_h2c_para[1], cur_h2c_para[2],
|
cur_h2c_para[3], cur_h2c_para[4], cur_h2c_para[5]);
|
BTC_TRACE(trace_buf);
|
}
|
|
static void
|
rtw_btc_set_table(struct btc_coexist *btc, boolean force_exec, u32 val0x6c0,
|
u32 val0x6c4)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
|
/* If last tdma is wl slot toggle, force write table*/
|
if (!force_exec && coex_sta->coex_run_reason != BTC_RSN_LPS) {
|
if (val0x6c0 == btc->btc_read_4byte(btc, REG_BT_COEX_TABLE0) &&
|
val0x6c4 == btc->btc_read_4byte(btc, REG_BT_COEX_TABLE1))
|
return;
|
}
|
|
btc->btc_write_4byte(btc, REG_BT_COEX_TABLE0, val0x6c0);
|
btc->btc_write_4byte(btc, REG_BT_COEX_TABLE1, val0x6c4);
|
btc->btc_write_4byte(btc, REG_BT_COEX_BRK_TABLE, 0xf0ffffff);
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): 0x6c0 = %x, 0x6c4 = %x\n",
|
__func__, val0x6c0, val0x6c4);
|
BTC_TRACE(trace_buf);
|
}
|
|
static void
|
rtw_btc_table(struct btc_coexist *btc, boolean force_exec, u8 type)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
u32 table_wl = 0x0;
|
|
coex_sta->coex_table_type = type;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], ***** Coex_Table - %d *****\n", type);
|
BTC_TRACE(trace_buf);
|
|
if (btc->board_info.btdm_ant_num == 1) {
|
if (type < chip_para->table_sant_num)
|
rtw_btc_set_table(btc, force_exec,
|
chip_para->table_sant[type].bt,
|
chip_para->table_sant[type].wl);
|
} else {
|
type = type - 100;
|
if (type < chip_para->table_nsant_num)
|
rtw_btc_set_table(btc, force_exec,
|
chip_para->table_nsant[type].bt,
|
chip_para->table_nsant[type].wl);
|
}
|
|
if (coex_sta->wl_slot_toggle_change)
|
rtw_btc_wltoggle_tableA(btc, FC_EXCU, type);
|
}
|
|
static void
|
rtw_btc_ignore_wlan_act(struct btc_coexist *btc, boolean force_exec,
|
boolean enable)
|
{
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
u8 h2c_para[1] = {0};
|
|
if (btc->manual_control || btc->stop_coex_dm)
|
return;
|
|
if (!force_exec && enable == coex_dm->cur_ignore_wlan_act)
|
return;
|
|
if (enable)
|
h2c_para[0] = 0x1; /* function enable */
|
|
rtw_btc_mailbox_operation(btc, 0x63, 1, h2c_para);
|
|
coex_dm->cur_ignore_wlan_act = enable;
|
}
|
|
static void
|
rtw_btc_lps_rpwm(struct btc_coexist *btc, boolean force_exec, u8 lps_val,
|
u8 rpwm_val)
|
{
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
|
if (!force_exec) {
|
if (lps_val == coex_dm->cur_lps &&
|
rpwm_val == coex_dm->cur_rpwm)
|
return;
|
}
|
|
btc->btc_set(btc, BTC_SET_U1_LPS_VAL, &lps_val);
|
btc->btc_set(btc, BTC_SET_U1_RPWM_VAL, &rpwm_val);
|
|
coex_dm->cur_lps = lps_val;
|
coex_dm->cur_rpwm = rpwm_val;
|
}
|
|
static void
|
rtw_btc_power_save_state(struct btc_coexist *btc, u8 ps_type, u8 lps_val,
|
u8 rpwm_val)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
boolean low_pwr_dis = FALSE;
|
u8 lps_mode = 0x0;
|
u8 h2c_para[5] = {0, 0, 0, 0, 0};
|
|
btc->btc_get(btc, BTC_GET_U1_LPS_MODE, &lps_mode);
|
|
switch (ps_type) {
|
case BTC_PS_WIFI_NATIVE:
|
/* recover to original 32k low power setting */
|
coex_sta->wl_force_lps_ctrl = FALSE;
|
btc->btc_set(btc, BTC_SET_ACT_PRE_NORMAL_LPS, NULL);
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): BTC_PS_WIFI_NATIVE\n", __func__);
|
break;
|
case BTC_PS_LPS_ON:
|
/* WQCCE-1763: 8725A LPS lock issue*/
|
if (coex_sta->coex_run_reason == BTC_RSN_LPS)
|
break;
|
|
coex_sta->wl_force_lps_ctrl = TRUE;
|
/*set tdma off if LPS off */
|
if (!lps_mode)
|
btc->btc_fill_h2c(btc, 0x60, 5, h2c_para);
|
rtw_btc_lps_rpwm(btc, NM_EXCU, lps_val, rpwm_val);
|
/* when coex force to enter LPS, do not enter 32k low power. */
|
low_pwr_dis = TRUE;
|
btc->btc_set(btc, BTC_SET_ACT_DISABLE_LOW_POWER, &low_pwr_dis);
|
/* power save must executed before psTdma. */
|
btc->btc_set(btc, BTC_SET_ACT_ENTER_LPS, NULL);
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): BTC_PS_LPS_ON\n", __func__);
|
break;
|
case BTC_PS_LPS_OFF:
|
coex_sta->wl_force_lps_ctrl = TRUE;
|
/*set tdma off if LPS on */
|
if (lps_mode)
|
btc->btc_fill_h2c(btc, 0x60, 5, h2c_para);
|
if (btc->btc_set(btc, BTC_SET_ACT_LEAVE_LPS, NULL))
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): BTC_PS_LPS_OFF\n",
|
__func__);
|
else
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): BTC_PS_LPS_OFF Fail!!\n",
|
__func__);
|
break;
|
default:
|
break;
|
}
|
|
BTC_TRACE(trace_buf);
|
}
|
|
static void
|
rtw_btc_set_tdma(struct btc_coexist *btc, u8 byte1, u8 byte2, u8 byte3,
|
u8 byte4, u8 byte5)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
struct btc_wifi_link_info_ext *linfo_ext = &btc->wifi_link_info_ext;
|
u8 ps_type = BTC_PS_WIFI_NATIVE,
|
real_byte1 = byte1, real_byte5 = byte5;
|
|
if (linfo_ext->is_ap_mode && (byte1 & BIT(4) && !(byte1 & BIT(5)))) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): AP mode\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
real_byte1 &= ~BIT(4);
|
real_byte1 |= BIT(5);
|
|
real_byte5 |= BIT(5);
|
real_byte5 &= ~BIT(6);
|
|
ps_type = BTC_PS_WIFI_NATIVE;
|
rtw_btc_power_save_state(btc, ps_type, 0x0, 0x0);
|
} else if (byte1 & BIT(4) && !(byte1 & BIT(5))) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): Force LPS (byte1 = 0x%x)\n",
|
__func__, byte1);
|
BTC_TRACE(trace_buf);
|
|
if (btc->chip_para->pstdma_type == BTC_PSTDMA_FORCE_LPSOFF)
|
ps_type = BTC_PS_LPS_OFF;
|
else
|
ps_type = BTC_PS_LPS_ON;
|
rtw_btc_power_save_state(btc, ps_type, 0x50, 0x4);
|
} else {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): native power save (byte1 = 0x%x)\n",
|
__func__, byte1);
|
BTC_TRACE(trace_buf);
|
|
ps_type = BTC_PS_WIFI_NATIVE;
|
rtw_btc_power_save_state(btc, ps_type, 0x0, 0x0);
|
}
|
|
coex_dm->ps_tdma_para[0] = real_byte1;
|
coex_dm->ps_tdma_para[1] = byte2;
|
coex_dm->ps_tdma_para[2] = byte3;
|
coex_dm->ps_tdma_para[3] = byte4;
|
coex_dm->ps_tdma_para[4] = real_byte5;
|
|
btc->btc_fill_h2c(btc, 0x60, 5, coex_dm->ps_tdma_para);
|
|
/* Always forec excute rtw_btc_set_table To avoid
|
* coex table error if wl slot toggle mode on ->off
|
* ex: 5508031054 next state -> rtw_btc_table + 5108031054
|
* rtw_btc_table may be changed by 5508031054
|
*/
|
if (real_byte1 & BIT(2)) {
|
coex_sta->wl_slot_toggle = TRUE;
|
coex_sta->wl_slot_toggle_change = FALSE;
|
} else {
|
coex_sta->wl_slot_toggle_change = coex_sta->wl_slot_toggle;
|
coex_sta->wl_slot_toggle = FALSE;
|
}
|
|
if (ps_type == BTC_PS_WIFI_NATIVE)
|
btc->btc_set(btc, BTC_SET_ACT_POST_NORMAL_LPS, NULL);
|
}
|
|
static
|
void rtw_btc_tdma(struct btc_coexist *btc, boolean force_exec, u32 tcase)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
u8 type;
|
boolean turn_on, wifi_busy = FALSE;
|
|
btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
|
|
btc->btc_set_atomic(btc, &coex_dm->setting_tdma, TRUE);
|
/* tcase: bit0~7 --> tdma case index
|
* bit8 --> for 4-slot (50ms) mode
|
*/
|
|
if (tcase & TDMA_4SLOT)/* 4-slot (50ms) mode */
|
rtw_btc_set_tdma_timer_base(btc, 3);
|
else
|
rtw_btc_set_tdma_timer_base(btc, 0);
|
|
type = (u8)(tcase & 0xff);
|
turn_on = (type == 0 || type == 100) ? FALSE : TRUE;
|
|
/* To avoid TDMA H2C fail before Last LPS enter */
|
if (!force_exec && coex_sta->coex_run_reason != BTC_RSN_LPS) {
|
if (turn_on == coex_dm->cur_ps_tdma_on &&
|
type == coex_dm->cur_ps_tdma) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], Skip TDMA because no change TDMA(%s, %d)\n",
|
(coex_dm->cur_ps_tdma_on ? "on" : "off"),
|
coex_dm->cur_ps_tdma);
|
BTC_TRACE(trace_buf);
|
|
btc->btc_set_atomic(btc, &coex_dm->setting_tdma, FALSE);
|
return;
|
}
|
}
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], ***** TDMA - %d *****\n", type);
|
BTC_TRACE(trace_buf);
|
|
/* TRUE -> Page scan > ACL */
|
if (!wifi_busy ||
|
(coex_sta->bt_a2dp_exist && coex_sta->bt_inq_page_remain)) {
|
if (chip_para->scbd_bit_num == BTC_SCBD_16_BIT)
|
btc->btc_write_scbd(btc, BTC_SCBD_TDMA, FALSE);
|
else
|
btc->btc_write_scbd_32bit(btc, BTC_SCBD_TDMA, FALSE);
|
} else {
|
if (chip_para->scbd_bit_num == BTC_SCBD_16_BIT)
|
btc->btc_write_scbd(btc, BTC_SCBD_TDMA, TRUE);
|
else
|
btc->btc_write_scbd_32bit(btc, BTC_SCBD_TDMA, TRUE);
|
}
|
|
if (btc->board_info.btdm_ant_num == 1) {
|
if (type < chip_para->tdma_sant_num)
|
rtw_btc_set_tdma(btc,
|
chip_para->tdma_sant[type].para[0],
|
chip_para->tdma_sant[type].para[1],
|
chip_para->tdma_sant[type].para[2],
|
chip_para->tdma_sant[type].para[3],
|
chip_para->tdma_sant[type].para[4]);
|
} else {
|
type = type - 100;
|
if (type < chip_para->tdma_nsant_num)
|
rtw_btc_set_tdma(btc,
|
chip_para->tdma_nsant[type].para[0],
|
chip_para->tdma_nsant[type].para[1],
|
chip_para->tdma_nsant[type].para[2],
|
chip_para->tdma_nsant[type].para[3],
|
chip_para->tdma_nsant[type].para[4]);
|
}
|
|
coex_dm->cur_ps_tdma_on = turn_on;
|
coex_dm->cur_ps_tdma = type;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "change TDMA(%s, %d)\n",
|
(coex_dm->cur_ps_tdma_on ? "on" : "off"),
|
coex_dm->cur_ps_tdma);
|
BTC_TRACE(trace_buf);
|
|
btc->btc_set_atomic(btc, &coex_dm->setting_tdma, FALSE);
|
}
|
|
static
|
void rtw_btc_set_ant_switch(struct btc_coexist *btc, boolean force_exec,
|
u8 ctrl_type, u8 pos_type)
|
{
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
|
if (!force_exec) {
|
if (((ctrl_type << 8) + pos_type) == coex_dm->cur_switch_status)
|
return;
|
}
|
|
coex_dm->cur_switch_status = (ctrl_type << 8) + pos_type;
|
|
btc->chip_para->chip_setup(btc, BTC_CSETUP_ANT_SWITCH);
|
}
|
|
static
|
void rtw_btc_set_ant_path(struct btc_coexist *btc, boolean force_exec,
|
u8 phase)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
struct btc_rfe_type *rfe_type = &btc->rfe_type;
|
struct btc_wifi_link_info_ext *linfo_ext = &btc->wifi_link_info_ext;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
u8 ctrl_type = BTC_SWITCH_CTRL_MAX,
|
pos_type = BTC_SWITCH_TO_MAX, cnt = 0;
|
u16 scbd = 0;
|
u32 scbd_32 = 0;
|
boolean is_btk = 0, is_wlk = 0;
|
|
if (!force_exec && coex_dm->cur_ant_pos_type == phase)
|
return;
|
|
coex_dm->cur_ant_pos_type = phase;
|
|
/* To avoid switch coex_ctrl_owner during BT IQK */
|
if (btc->chip_para->scbd_support && coex_sta->bt_iqk_state != 0xff) {
|
|
while (++cnt < 60) {
|
/* BT RFK */
|
if (chip_para->scbd_bit_num == BTC_SCBD_16_BIT) {
|
if (btc->btc_read_scbd(btc, &scbd) & BIT(5))
|
is_btk = TRUE;
|
else
|
is_btk = FALSE;
|
} else {
|
if (btc->btc_read_scbd_32bit(btc, &scbd_32) & BIT(5))
|
is_btk = TRUE;
|
else
|
is_btk = FALSE;
|
}
|
/* WL RFK */
|
if ((phase != BTC_ANT_WOFF) &&
|
((btc->btc_read_1byte(btc, 0x49c) & BIT(0)) ||
|
coex_sta->wl_rfk))
|
is_wlk = TRUE;
|
else
|
is_wlk = FALSE;
|
|
if ((!is_btk && !is_wlk) || scbd == 0x7ff)
|
break;
|
|
delay_ms(10);
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], Ant Setup Delay by IQK\n, wlk=%d, btk=%d, cnt=%d\n",
|
is_wlk, is_btk, cnt);
|
BTC_TRACE(trace_buf);
|
}
|
/* wait timeout */
|
if (cnt >= 60)
|
coex_sta->bt_iqk_state = 0xff;
|
}
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], coex_sta->bt_disabled = 0x%x\n",
|
coex_sta->bt_disabled);
|
BTC_TRACE(trace_buf);
|
|
switch (phase) {
|
case BTC_ANT_POWERON:
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s() - PHASE_COEX_POWERON\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
/* set Path control owner to BT at power-on step */
|
if (coex_sta->bt_disabled)
|
rtw_btc_coex_ctrl_owner(btc, BTC_OWNER_WL);
|
else
|
rtw_btc_coex_ctrl_owner(btc, BTC_OWNER_BT);
|
|
/*Caution: Don't indirect access while power on phase */
|
|
ctrl_type = BTC_SWITCH_CTRL_BY_BBSW;
|
pos_type = BTC_SWITCH_TO_BT;
|
break;
|
case BTC_ANT_INIT:
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s() - PHASE_COEX_INIT\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
if (coex_sta->bt_disabled) {
|
/* set GNT_BT to SW low */
|
rtw_btc_set_gnt_bt(btc, BTC_GNT_SW_LOW);
|
/* set GNT_WL to SW high */
|
rtw_btc_set_gnt_wl(btc, BTC_GNT_SW_HIGH);
|
} else {
|
/* set GNT_BT to SW high */
|
rtw_btc_set_gnt_bt(btc, BTC_GNT_SW_HIGH);
|
/* set GNT_WL to SW low */
|
rtw_btc_set_gnt_wl(btc, BTC_GNT_SW_LOW);
|
}
|
|
/* set Path control owner to WL at initial step */
|
rtw_btc_coex_ctrl_owner(btc, BTC_OWNER_WL);
|
|
ctrl_type = BTC_SWITCH_CTRL_BY_BBSW;
|
pos_type = BTC_SWITCH_TO_BT;
|
break;
|
case BTC_ANT_WONLY:
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s() - PHASE_WLANONLY_INIT\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
/* set GNT_BT to SW Low */
|
rtw_btc_set_gnt_bt(btc, BTC_GNT_SW_LOW);
|
/* Set GNT_WL to SW high */
|
rtw_btc_set_gnt_wl(btc, BTC_GNT_SW_HIGH);
|
/* set Path control owner to WL at initial step */
|
rtw_btc_coex_ctrl_owner(btc, BTC_OWNER_WL);
|
|
ctrl_type = BTC_SWITCH_CTRL_BY_BBSW;
|
pos_type = BTC_SWITCH_TO_WLG;
|
break;
|
case BTC_ANT_WOFF:
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s() - PHASE_WLAN_OFF\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
/* set Path control owner to BT */
|
rtw_btc_coex_ctrl_owner(btc, BTC_OWNER_BT);
|
|
ctrl_type = BTC_SWITCH_CTRL_BY_BT;
|
pos_type = BTC_SWITCH_TO_NOCARE;
|
break;
|
case BTC_ANT_2G:
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s() - PHASE_2G_RUNTIME\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
/* set GNT_BT to PTA */
|
rtw_btc_set_gnt_bt(btc, BTC_GNT_HW_PTA);
|
/* Set GNT_WL to PTA */
|
rtw_btc_set_gnt_wl(btc, BTC_GNT_HW_PTA);
|
|
/* set Path control owner to WL at runtime step */
|
rtw_btc_coex_ctrl_owner(btc, BTC_OWNER_WL);
|
|
ctrl_type = BTC_SWITCH_CTRL_BY_PTA;
|
pos_type = BTC_SWITCH_TO_NOCARE;
|
break;
|
case BTC_ANT_5G:
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s() - PHASE_5G_RUNTIME\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
if (linfo_ext->is_ap_mode &&
|
strcmp(btc->chip_para->chip_name, "8723f") != 0) {
|
/* set GNT_BT to SW PTA
|
8723f cannot set GNT_BT PTA control when SW control*/
|
rtw_btc_set_gnt_bt(btc, BTC_GNT_HW_PTA);
|
} else {
|
/* set GNT_BT to SW Hi */
|
rtw_btc_set_gnt_bt(btc, BTC_GNT_SW_HIGH);
|
}
|
|
/* Set GNT_WL to SW Hi */
|
rtw_btc_set_gnt_wl(btc, BTC_GNT_SW_HIGH);
|
|
/* set Path control owner to WL at runtime step */
|
rtw_btc_coex_ctrl_owner(btc, BTC_OWNER_WL);
|
|
ctrl_type = BTC_SWITCH_CTRL_BY_BBSW;
|
pos_type = BTC_SWITCH_TO_WLA;
|
break;
|
case BTC_ANT_2G_FREERUN:
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s() - PHASE_2G_FREERUN\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
/*8723f cannot set GNT_BT PTA control when SW control*/
|
if (strcmp(btc->chip_para->chip_name, "8723f") == 0) {
|
/* Set GNT_BT to SW Hi */
|
rtw_btc_set_gnt_bt(btc, BTC_GNT_SW_HIGH);
|
} else {
|
/* set GNT_BT to SW PTA */
|
rtw_btc_set_gnt_bt(btc, BTC_GNT_HW_PTA);
|
}
|
|
/* Set GNT_WL to SW Hi */
|
rtw_btc_set_gnt_wl(btc, BTC_GNT_SW_HIGH);
|
|
/* set Path control owner to WL at runtime step */
|
rtw_btc_coex_ctrl_owner(btc, BTC_OWNER_WL);
|
|
ctrl_type = BTC_SWITCH_CTRL_BY_BBSW;
|
pos_type = BTC_SWITCH_TO_WLG_BT;
|
break;
|
case BTC_ANT_2G_WLBT:
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s() - PHASE_2G_WLBT\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
/* set GNT_BT to HW PTA */
|
rtw_btc_set_gnt_bt(btc, BTC_GNT_HW_PTA);
|
/* Set GNT_WL to HW PTA */
|
rtw_btc_set_gnt_wl(btc, BTC_GNT_HW_PTA);
|
/* set Path control owner to WL at runtime step */
|
rtw_btc_coex_ctrl_owner(btc, BTC_OWNER_WL);
|
|
ctrl_type = BTC_SWITCH_CTRL_BY_BBSW;
|
pos_type = BTC_SWITCH_TO_WLG_BT;
|
break;
|
case BTC_ANT_2G_WL:
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s() - PHASE_2G_WL\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
/* set GNT_BT to PTA */
|
rtw_btc_set_gnt_bt(btc, BTC_GNT_HW_PTA);
|
/* Set GNT_WL to PTA */
|
rtw_btc_set_gnt_wl(btc, BTC_GNT_HW_PTA);
|
/* set Path control owner to WL at runtime step */
|
rtw_btc_coex_ctrl_owner(btc, BTC_OWNER_WL);
|
|
ctrl_type = BTC_SWITCH_CTRL_BY_BBSW;
|
pos_type = BTC_SWITCH_TO_WLG;
|
break;
|
case BTC_ANT_2G_BT:
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s() - PHASE_2G_WL\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
/* set GNT_BT to PTA */
|
rtw_btc_set_gnt_bt(btc, BTC_GNT_HW_PTA);
|
/* Set GNT_WL to PTA */
|
rtw_btc_set_gnt_wl(btc, BTC_GNT_HW_PTA);
|
/* set Path control owner to WL at runtime step */
|
rtw_btc_coex_ctrl_owner(btc, BTC_OWNER_WL);
|
|
ctrl_type = BTC_SWITCH_CTRL_BY_BBSW;
|
pos_type = BTC_SWITCH_TO_BT;
|
break;
|
case BTC_ANT_BTMP:
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s() - PHASE_BTMP\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
/* set GNT_BT to SW Hi */
|
rtw_btc_set_gnt_bt(btc, BTC_GNT_SW_HIGH);
|
/* Set GNT_WL to SW Lo */
|
rtw_btc_set_gnt_wl(btc, BTC_GNT_SW_LOW);
|
/* set Path control owner to WL */
|
rtw_btc_coex_ctrl_owner(btc, BTC_OWNER_WL);
|
|
btc->stop_coex_dm = TRUE;
|
|
ctrl_type = BTC_SWITCH_CTRL_BY_BBSW;
|
pos_type = BTC_SWITCH_TO_BT;
|
break;
|
case BTC_ANT_MCC:
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s() - PHASE_MCC\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
/* set GNT_BT to PTA */
|
rtw_btc_set_gnt_bt(btc, BTC_GNT_HW_PTA);
|
/* Set GNT_WL to PTA */
|
rtw_btc_set_gnt_wl(btc, BTC_GNT_HW_PTA);
|
/* set Path control owner to WL at runtime step */
|
rtw_btc_coex_ctrl_owner(btc, BTC_OWNER_WL);
|
|
ctrl_type = BTC_SWITCH_CTRL_BY_FW;
|
pos_type = BTC_SWITCH_TO_NOCARE;
|
break;
|
}
|
|
if (ctrl_type < BTC_SWITCH_CTRL_MAX && pos_type < BTC_SWITCH_TO_MAX &&
|
rfe_type->ant_switch_exist)
|
rtw_btc_set_ant_switch(btc, force_exec, ctrl_type, pos_type);
|
}
|
|
static u8 rtw_btc_algorithm(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
u8 algorithm = BTC_COEX_NOPROFILE;
|
u8 profile_map = 0;
|
|
if (coex_sta->bt_hfp_exist)
|
profile_map = profile_map | BTC_BTPROFILE_HFP;
|
|
if (coex_sta->bt_hid_exist)
|
profile_map = profile_map | BTC_BTPROFILE_HID;
|
|
if (coex_sta->bt_a2dp_exist)
|
profile_map = profile_map | BTC_BTPROFILE_A2DP;
|
|
if (coex_sta->bt_pan_exist)
|
profile_map = profile_map | BTC_BTPROFILE_PAN;
|
|
switch (profile_map) {
|
case BTC_BTPROFILE_NONE:
|
algorithm = BTC_COEX_NOPROFILE;
|
break;
|
case BTC_BTPROFILE_HFP:
|
algorithm = BTC_COEX_HFP;
|
break;
|
case BTC_BTPROFILE_HID:
|
algorithm = BTC_COEX_HID;
|
break;
|
case (BTC_BTPROFILE_HID | BTC_BTPROFILE_HFP):
|
algorithm = BTC_COEX_HFP;
|
break;
|
case BTC_BTPROFILE_A2DP:
|
/* OPP may disappear during CPT_for_WiFi test */
|
if (coex_sta->bt_multi_link && coex_sta->bt_hid_pair_num > 0)
|
algorithm = BTC_COEX_A2DP_HID;
|
else if (coex_sta->bt_multi_link)
|
algorithm = BTC_COEX_A2DP_PAN;
|
else
|
algorithm = BTC_COEX_A2DP;
|
break;
|
case (BTC_BTPROFILE_A2DP | BTC_BTPROFILE_HFP):
|
algorithm = BTC_COEX_A2DP_HID;
|
break;
|
case (BTC_BTPROFILE_A2DP | BTC_BTPROFILE_HID):
|
algorithm = BTC_COEX_A2DP_HID;
|
break;
|
case (BTC_BTPROFILE_A2DP | BTC_BTPROFILE_HID | BTC_BTPROFILE_HFP):
|
algorithm = BTC_COEX_A2DP_HID;
|
break;
|
case BTC_BTPROFILE_PAN:
|
algorithm = BTC_COEX_PAN;
|
break;
|
case (BTC_BTPROFILE_PAN | BTC_BTPROFILE_HFP):
|
algorithm = BTC_COEX_PAN_HID;
|
break;
|
case (BTC_BTPROFILE_PAN | BTC_BTPROFILE_HID):
|
algorithm = BTC_COEX_PAN_HID;
|
break;
|
case (BTC_BTPROFILE_PAN | BTC_BTPROFILE_HID | BTC_BTPROFILE_HFP):
|
algorithm = BTC_COEX_PAN_HID;
|
break;
|
case (BTC_BTPROFILE_PAN | BTC_BTPROFILE_A2DP):
|
algorithm = BTC_COEX_A2DP_PAN;
|
break;
|
case (BTC_BTPROFILE_PAN | BTC_BTPROFILE_A2DP | BTC_BTPROFILE_HFP):
|
algorithm = BTC_COEX_A2DP_PAN_HID;
|
break;
|
case (BTC_BTPROFILE_PAN | BTC_BTPROFILE_A2DP | BTC_BTPROFILE_HID):
|
algorithm = BTC_COEX_A2DP_PAN_HID;
|
break;
|
case BTC_BTPROFILE_MAX:
|
algorithm = BTC_COEX_A2DP_PAN_HID;
|
break;
|
}
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], BT Profile = %s => Algorithm = %s\n",
|
bt_profile_string[profile_map],
|
coex_algo_string[algorithm]);
|
BTC_TRACE(trace_buf);
|
|
return algorithm;
|
}
|
|
static void rtw_btc_action_coex_all_off(struct btc_coexist *btc)
|
{
|
u8 table_case, tdma_case;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_set_rf_para(btc, NM_EXCU, btc->chip_para->wl_rf_para_rx[0]);
|
|
/* To avoid rtw_btc_set_ant_path here */
|
if (btc->board_info.btdm_ant_num == 1) { /* Shared-Ant */
|
table_case = 2;
|
tdma_case = 0;
|
} else { /* Non-Shared-Ant */
|
table_case = 100;
|
tdma_case = 100;
|
}
|
|
rtw_btc_table(btc, NM_EXCU, table_case);
|
rtw_btc_tdma(btc, NM_EXCU, tdma_case);
|
}
|
|
static void rtw_btc_action_freerun(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
const struct btc_chip_para *cpara = btc->chip_para;
|
struct btc_wifi_link_info_ext *link_info_ext = &btc->wifi_link_info_ext;
|
u8 level = 0, i, base = 0;
|
boolean bt_afh_loss = TRUE;
|
u32 ap_cnt;
|
|
if (btc->board_info.btdm_ant_num != 2)
|
return;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
coex_sta->coex_freerun = TRUE;
|
|
for (i = 0; i <= 8; i++) {
|
if (coex_sta->bt_afh_map[i] != 0xff) {
|
bt_afh_loss = FALSE;
|
break;
|
}
|
}
|
|
ap_cnt = coex_sta->cnt_wl[BTC_CNT_WL_SCANAP];
|
|
if (bt_afh_loss)
|
rtw_btc_update_wl_ch_info(btc, BTC_MEDIA_CONNECT);
|
|
rtw_btc_set_ant_path(btc, NM_EXCU, BTC_ANT_2G_FREERUN);
|
|
if (cpara->scbd_bit_num == BTC_SCBD_16_BIT)
|
btc->btc_write_scbd(btc, BTC_SCBD_FIX2M, FALSE);
|
else
|
btc->btc_write_scbd_32bit(btc, BTC_SCBD_FIX2M, FALSE);
|
|
/* select array index base for profile */
|
if (coex_sta->bt_hid_exist && !coex_sta->bt_multi_link)
|
base = 2;
|
else if (coex_sta->bt_a2dp_exist && !coex_sta->bt_multi_link)
|
base = 10;
|
else if (coex_sta->bt_hid_exist && coex_sta->bt_a2dp_exist
|
&& coex_sta->bt_profile_num == 2)
|
base = 18;
|
|
if (ap_cnt > 10) /* for office case */
|
base = base + 4;
|
|
/* decrease more BT Tx power for clear case */
|
if (BTC_RSSI_HIGH(coex_dm->wl_rssi_state[0]))
|
level = 0;
|
else if (BTC_RSSI_HIGH(coex_dm->wl_rssi_state[1]))
|
level = 1;
|
else if (BTC_RSSI_HIGH(coex_dm->wl_rssi_state[2]))
|
level = 2;
|
else
|
level = 3;
|
|
level = level + base;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], level = %d\n",
|
level);
|
BTC_TRACE(trace_buf);
|
|
if (level > cpara->wl_rf_para_tx_num - 1)
|
level = cpara->wl_rf_para_tx_num - 1;
|
|
if (coex_sta->wl_coex_mode != BTC_WLINK_2G1PORT)
|
rtw_btc_set_rf_para(btc, NM_EXCU, cpara->wl_rf_para_rx[0]);
|
else if (link_info_ext->traffic_dir == BTC_WIFI_TRAFFIC_TX)
|
rtw_btc_set_rf_para(btc, NM_EXCU, cpara->wl_rf_para_tx[level]);
|
else
|
rtw_btc_set_rf_para(btc, NM_EXCU, cpara->wl_rf_para_rx[level]);
|
|
rtw_btc_table(btc, NM_EXCU, 100);
|
rtw_btc_tdma(btc, NM_EXCU, 100);
|
}
|
|
static void rtw_btc_action_rf4ce(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
u8 table_case, tdma_case;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_set_rf_para(btc, NM_EXCU, chip_para->wl_rf_para_rx[0]);
|
rtw_btc_set_ant_path(btc, NM_EXCU, BTC_ANT_2G);
|
|
switch (coex_sta->ext_chip_mode) {
|
case 0:
|
table_case = 112;
|
tdma_case = 115;
|
|
if (coex_sta->bt_slave)
|
rtw_btc_set_extend_btautoslot(btc, 0x3c);
|
else
|
rtw_btc_set_extend_btautoslot(btc, 0x32);
|
|
rtw_btc_table(btc, NM_EXCU, table_case);
|
rtw_btc_tdma(btc, NM_EXCU, tdma_case);
|
break;
|
case 1:
|
table_case = 112;
|
tdma_case = 121;
|
|
rtw_btc_table(btc, NM_EXCU, table_case);
|
rtw_btc_tdma(btc, NM_EXCU, tdma_case);
|
break;
|
}
|
}
|
|
static void rtw_btc_action_ext_chip(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
|
if (btc->board_info.ext_chip_id == BTC_EXT_CHIP_RF4CE)
|
rtw_btc_action_rf4ce(btc);
|
}
|
|
u8 rtw_btc_action_rf4ce_new_tdma(struct btc_coexist *btc, u8 type)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
u8 table_case, tdma_case;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
switch (type) {
|
case 0: /*BT idle*/
|
if (coex_sta->ext_chip_mode == BTC_EXTMODE_VOICE)
|
tdma_case = 121;
|
else
|
tdma_case = 117;
|
break;
|
case 1: /*BT relink*/
|
if (coex_sta->ext_chip_mode == BTC_EXTMODE_VOICE)
|
tdma_case = 121;
|
else
|
tdma_case = 117;
|
break;
|
case 2: /*WIFI linkscan*/
|
if (coex_sta->ext_chip_mode == BTC_EXTMODE_VOICE) {
|
tdma_case = 125;
|
} else{
|
if (coex_sta->bt_slave)
|
rtw_btc_set_extend_btautoslot(btc, 0x3c);
|
else
|
rtw_btc_set_extend_btautoslot(btc, 0x32);
|
|
tdma_case = 124;
|
}
|
break;
|
case 3: /*WIFI only*/
|
if (coex_sta->ext_chip_mode == BTC_EXTMODE_VOICE) {
|
tdma_case = 121;
|
} else{
|
if (coex_sta->bt_slave)
|
rtw_btc_set_extend_btautoslot(btc, 0x3c);
|
else
|
rtw_btc_set_extend_btautoslot(btc, 0x32);
|
|
tdma_case = 115;
|
}
|
break;
|
default:
|
tdma_case = 0;
|
break;
|
}
|
return tdma_case;
|
}
|
|
u8 rtw_btc_ext_chip_new_tdma(struct btc_coexist *btc, u8 type)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
u8 tdma_case = 0;
|
|
if (btc->board_info.ext_chip_id == BTC_EXT_CHIP_RF4CE)
|
tdma_case = rtw_btc_action_rf4ce_new_tdma(btc, type);
|
|
return tdma_case;
|
}
|
|
static void rtw_btc_action_bt_whql_test(struct btc_coexist *btc)
|
{
|
u8 table_case, tdma_case;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_set_ant_path(btc, NM_EXCU, BTC_ANT_2G);
|
rtw_btc_set_rf_para(btc, NM_EXCU, btc->chip_para->wl_rf_para_rx[0]);
|
|
if (btc->board_info.btdm_ant_num == 1) { /* Shared-Ant */
|
table_case = 2;
|
tdma_case = 0;
|
} else { /* Non-Shared-Ant */
|
table_case = 100;
|
tdma_case = 100;
|
}
|
|
rtw_btc_table(btc, NM_EXCU, table_case);
|
rtw_btc_tdma(btc, NM_EXCU, tdma_case);
|
}
|
|
static void rtw_btc_action_bt_relink(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
u8 table_case, tdma_case;
|
u32 slot_type = 0;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_set_ant_path(btc, NM_EXCU, BTC_ANT_2G);
|
rtw_btc_set_rf_para(btc, NM_EXCU, btc->chip_para->wl_rf_para_rx[0]);
|
|
if (btc->board_info.btdm_ant_num == 1) { /* Shared-Ant */
|
if (coex_sta->wl_gl_busy) {
|
table_case = 26;
|
|
if (coex_sta->bt_hid_exist &&
|
coex_sta->bt_profile_num == 1) {
|
slot_type = TDMA_4SLOT;
|
tdma_case = 20;
|
} else {
|
tdma_case = 20;
|
}
|
} else {
|
table_case = 1;
|
tdma_case = 0;
|
}
|
} else { /* Non-Shared-Ant */
|
if (coex_sta->wl_gl_busy)
|
table_case = 115;
|
else
|
table_case = 100;
|
tdma_case = 100;
|
|
if (coex_sta->wl_gl_busy &&
|
btc->board_info.ext_chip_id != BTC_EXT_CHIP_NONE)
|
tdma_case = rtw_btc_ext_chip_new_tdma(btc, 1);
|
}
|
|
rtw_btc_table(btc, NM_EXCU, table_case);
|
rtw_btc_tdma(btc, NM_EXCU, tdma_case | slot_type);
|
}
|
|
static void rtw_btc_action_bt_idle(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
struct btc_rfe_type *rfe_type = &btc->rfe_type;
|
struct btc_wifi_link_info *link_info = &btc->wifi_link_info;
|
u8 table_case = 0xff, tdma_case = 0xff;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_set_rf_para(btc, NM_EXCU, btc->chip_para->wl_rf_para_rx[0]);
|
|
if (rfe_type->ant_switch_with_bt &&
|
coex_dm->bt_status == BTC_BTSTATUS_NCON_IDLE) {
|
if (btc->board_info.btdm_ant_num == 1 &&
|
BTC_RSSI_HIGH(coex_dm->wl_rssi_state[3]) &&
|
coex_sta->wl_gl_busy) {
|
table_case = 0;
|
tdma_case = 0;
|
} else if (btc->board_info.btdm_ant_num == 2) {
|
table_case = 100;
|
tdma_case = 100;
|
}
|
|
if (table_case != 0xff && tdma_case != 0xff) {
|
rtw_btc_set_ant_path(btc, NM_EXCU, BTC_ANT_2G_FREERUN);
|
goto exit;
|
}
|
}
|
|
rtw_btc_set_ant_path(btc, NM_EXCU, BTC_ANT_2G);
|
#if 0
|
#ifndef PLATFORM_WINDOWS
|
if (coex_sta->wl_noisy_level > 0) {
|
if (btc->board_info.btdm_ant_num == 1) { /* Shared-Ant */
|
table_case = 1;
|
tdma_case = 0;
|
} else { /* Non-Shared-Ant */
|
table_case = 123;
|
tdma_case = 0;
|
}
|
goto exit;
|
}
|
#endif
|
#endif
|
if (btc->board_info.btdm_ant_num == 1) { /* Shared-Ant */
|
if (!coex_sta->wl_gl_busy) {
|
table_case = 10;
|
tdma_case = 3;
|
} else if (coex_sta->bt_mesh) {
|
table_case = 26;
|
tdma_case = 7;
|
} else if (coex_dm->bt_status == BTC_BTSTATUS_NCON_IDLE) {
|
table_case = 11;
|
|
if (coex_sta->bt_ctr_ok &&
|
(coex_sta->lo_pri_rx + coex_sta->lo_pri_tx > 250))
|
tdma_case = 17;
|
else
|
tdma_case = 7;
|
} else {
|
table_case = 12;
|
tdma_case = 7;
|
}
|
} else { /* Non-Shared-Ant */
|
if (!coex_sta->wl_gl_busy) {
|
table_case = 112;
|
tdma_case = 104;
|
} else if ((coex_sta->bt_ble_scan_type & 0x2) &&
|
coex_dm->bt_status == BTC_BTSTATUS_NCON_IDLE) {
|
table_case = 114;
|
tdma_case = 103;
|
} else {
|
table_case = 112;
|
tdma_case = 103;
|
}
|
if (coex_sta->wl_gl_busy &&
|
btc->board_info.ext_chip_id != BTC_EXT_CHIP_NONE)
|
tdma_case = rtw_btc_ext_chip_new_tdma(btc, 0);
|
}
|
|
exit:
|
rtw_btc_table(btc, NM_EXCU, table_case);
|
rtw_btc_tdma(btc, NM_EXCU, tdma_case);
|
}
|
|
static void rtw_btc_action_bt_inquiry(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_wifi_link_info_ext *link_info_ext = &btc->wifi_link_info_ext;
|
boolean wl_hi_pri = FALSE;
|
u8 table_case, tdma_case;
|
u32 slot_type = 0;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_set_ant_path(btc, NM_EXCU, BTC_ANT_2G);
|
rtw_btc_set_rf_para(btc, NM_EXCU, btc->chip_para->wl_rf_para_rx[0]);
|
|
if (coex_sta->wl_linkscan_proc || coex_sta->wl_hi_pri_task1 ||
|
coex_sta->wl_hi_pri_task2)
|
wl_hi_pri = TRUE;
|
|
if (btc->board_info.btdm_ant_num == 1) { /* Shared-Ant */
|
if (wl_hi_pri) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], bt inq/page + wifi hi-pri task\n");
|
|
table_case = 15;
|
|
if (coex_sta->bt_profile_num > 0)
|
tdma_case = 10;
|
else if (coex_sta->wl_hi_pri_task1)
|
tdma_case = 6;
|
else if (!coex_sta->bt_page)
|
tdma_case = 8;
|
else
|
tdma_case = 9;
|
} else if (coex_sta->wl_gl_busy) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], bt inq/page + wifi busy\n");
|
#if 0
|
table_case = 15;
|
tdma_case = 20;
|
#else
|
if (coex_sta->bt_profile_num == 0) {
|
table_case = 12;
|
tdma_case = 18;
|
} else if (coex_sta->bt_profile_num == 1 &&
|
!coex_sta->bt_a2dp_exist) {
|
slot_type = TDMA_4SLOT;
|
table_case = 12;
|
tdma_case = 20;
|
} else {
|
slot_type = TDMA_4SLOT;
|
table_case = 12;
|
tdma_case = 26;
|
}
|
#endif
|
} else if (link_info_ext->is_connected) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], bt inq/page + wifi connected\n");
|
|
table_case = 9;
|
tdma_case = 27;
|
} else {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], bt inq/page + wifi not-connected\n");
|
|
table_case = 1;
|
tdma_case = 0;
|
}
|
} else { /* Non_Shared-Ant */
|
if (wl_hi_pri) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], bt inq/page + wifi hi-pri task\n");
|
|
table_case = 100;
|
tdma_case = 100;
|
} else if (coex_sta->wl_gl_busy) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], bt inq/page + wifi busy\n");
|
|
table_case = 114;
|
tdma_case = 121;
|
} else if (link_info_ext->is_connected) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], bt inq/page + wifi connected\n");
|
|
table_case = 101;
|
tdma_case = 100;
|
} else {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], bt inq/page + wifi not-connected\n");
|
|
table_case = 101;
|
tdma_case = 100;
|
}
|
}
|
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_table(btc, NM_EXCU, table_case);
|
rtw_btc_tdma(btc, NM_EXCU, tdma_case | slot_type);
|
}
|
|
static void rtw_btc_action_bt_hfp(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
u8 table_case, tdma_case;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_set_ant_path(btc, NM_EXCU, BTC_ANT_2G);
|
rtw_btc_set_rf_para(btc, NM_EXCU, btc->chip_para->wl_rf_para_rx[0]);
|
|
if (btc->board_info.btdm_ant_num == 1) { /* Shared-Ant */
|
if (coex_sta->wl_cck_lock_ever) {
|
coex_sta->wl_coex_mode = BTC_WLINK_2GFREE;
|
table_case = 33;
|
tdma_case = 0;
|
} else {
|
table_case = 10;
|
tdma_case = 5;
|
}
|
} else { /* Non-Shared-Ant */
|
if (coex_sta->bt_multi_link) {
|
table_case = 112;
|
tdma_case = 117;
|
} else {
|
table_case = 105;
|
tdma_case = 100;
|
}
|
}
|
|
rtw_btc_table(btc, NM_EXCU, table_case);
|
rtw_btc_tdma(btc, NM_EXCU, tdma_case);
|
}
|
|
static void rtw_btc_action_bt_hid(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
u8 table_case, tdma_case;
|
boolean is_toggle_table = FALSE, is_bt_ctr_hi = FALSE;
|
u32 slot_type = 0;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_set_ant_path(btc, NM_EXCU, BTC_ANT_2G);
|
rtw_btc_set_rf_para(btc, NM_EXCU, btc->chip_para->wl_rf_para_rx[0]);
|
|
if (coex_sta->bt_ctr_ok &&
|
(coex_sta->lo_pri_rx + coex_sta->lo_pri_tx > 360))
|
is_bt_ctr_hi = TRUE;
|
|
if (btc->board_info.btdm_ant_num == 1) { /* Shared-Ant */
|
if (coex_sta->wl_cck_lock_ever) {
|
coex_sta->wl_coex_mode = BTC_WLINK_2GFREE;
|
table_case = 33;
|
tdma_case = 0;
|
} else if (coex_sta->bt_ble_exist) { /* RCU */
|
table_case = 26;
|
tdma_case = 2;
|
} else { /* Legacy HID */
|
if (coex_sta->bt_a2dp_active ||
|
coex_sta->bt_a2dp_active_remain) {
|
table_case = 9;
|
tdma_case = 18;
|
} else if (coex_sta->bt_profile_num == 1 &&
|
(coex_sta->bt_multi_link &&
|
(is_bt_ctr_hi ||
|
coex_sta->bt_slave ||
|
coex_sta->bt_multi_link_remain))) {
|
slot_type = TDMA_4SLOT;
|
|
if (coex_sta->wl_gl_busy &&
|
(coex_sta->wl_rx_rate <= 3 ||
|
coex_sta->wl_rts_rx_rate <= 3))
|
table_case = 13;
|
else
|
table_case = 12;
|
|
tdma_case = 26;
|
} else if (coex_sta->bt_418_hid_exist &&
|
coex_sta->wl_gl_busy) {
|
slot_type = TDMA_4SLOT;
|
table_case = 32;
|
tdma_case = 27;
|
} else if (coex_sta->bt_ble_hid_exist &&
|
coex_sta->wl_gl_busy) {
|
table_case = 32;
|
tdma_case = 9;
|
} else {
|
table_case = 9;
|
tdma_case = 9;
|
}
|
}
|
} else { /* Non-Shared-Ant */
|
if (coex_sta->bt_ble_exist) { /* BLE */
|
table_case = 110;
|
tdma_case = 105;
|
} else if (coex_sta->bt_a2dp_active) {
|
table_case = 113;
|
tdma_case = 118;
|
} else {
|
table_case = 113;
|
tdma_case = 104;
|
}
|
}
|
|
rtw_btc_table(btc, NM_EXCU, table_case);
|
if (is_toggle_table) {
|
rtw_btc_wltoggle_tableA(btc, FC_EXCU, table_case);
|
rtw_btc_wltoggle_tableB(btc, NM_EXCU, 1, 0x5a5a5aaa);
|
}
|
|
rtw_btc_tdma(btc, NM_EXCU, tdma_case | slot_type);
|
}
|
|
static void rtw_btc_action_bt_a2dp(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
u8 table_case, tdma_case;
|
u32 slot_type = 0;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_set_ant_path(btc, NM_EXCU, BTC_ANT_2G);
|
rtw_btc_set_rf_para(btc, NM_EXCU, btc->chip_para->wl_rf_para_rx[0]);
|
|
slot_type = TDMA_4SLOT;
|
|
if (btc->board_info.btdm_ant_num == 1) { /* Shared-Ant */
|
if (coex_sta->wl_gl_busy && coex_sta->wl_noisy_level == 0)
|
table_case = 12;
|
else
|
table_case = 9;
|
|
if (coex_sta->wl_connecting || !coex_sta->wl_gl_busy)
|
tdma_case = 14;
|
else
|
tdma_case = 13;
|
} else { /* Non-Shared-Ant */
|
table_case = 121;
|
tdma_case = 113;
|
}
|
|
rtw_btc_table(btc, NM_EXCU, table_case);
|
rtw_btc_tdma(btc, NM_EXCU, tdma_case | slot_type);
|
}
|
|
static void rtw_btc_action_bt_a2dpsink(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
struct btc_wifi_link_info_ext *linfo_ext = &btc->wifi_link_info_ext;
|
u8 table_case, tdma_case;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_set_ant_path(btc, NM_EXCU, BTC_ANT_2G);
|
rtw_btc_set_rf_para(btc, NM_EXCU, btc->chip_para->wl_rf_para_rx[0]);
|
|
if (btc->board_info.btdm_ant_num == 1) { /* Shared-Ant */
|
if (linfo_ext->is_ap_mode) {
|
table_case = 2;
|
tdma_case = 0;
|
} else if (coex_sta->wl_gl_busy) {
|
table_case = 28;
|
tdma_case = 20;
|
} else {
|
table_case = 28;
|
tdma_case = 26;
|
}
|
} else { /* Non-Shared-Ant */
|
if (linfo_ext->is_ap_mode) {
|
table_case = 100;
|
tdma_case = 100;
|
} else {
|
table_case = 119;
|
tdma_case = 120;
|
}
|
}
|
|
rtw_btc_table(btc, NM_EXCU, table_case);
|
rtw_btc_tdma(btc, NM_EXCU, tdma_case);
|
}
|
|
static void rtw_btc_action_bt_pan(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
u8 table_case, tdma_case;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_set_ant_path(btc, NM_EXCU, BTC_ANT_2G);
|
rtw_btc_set_rf_para(btc, NM_EXCU, btc->chip_para->wl_rf_para_rx[0]);
|
|
if (btc->board_info.btdm_ant_num == 1) { /* Shared-Ant */
|
if (coex_sta->wl_gl_busy && coex_sta->wl_noisy_level == 0)
|
table_case = 14;
|
else
|
table_case = 10;
|
|
if (coex_sta->wl_gl_busy)
|
tdma_case = 17;
|
else
|
tdma_case = 20;
|
} else { /* Non-Shared-Ant */
|
table_case = 112;
|
|
if (coex_sta->wl_gl_busy)
|
tdma_case = 117;
|
else
|
tdma_case = 119;
|
}
|
|
if (coex_sta->bt_slave && coex_sta->wl_gl_busy)
|
rtw_btc_set_bt_golden_rx_range(btc, NM_EXCU, 3, 20);
|
else
|
rtw_btc_set_bt_golden_rx_range(btc, NM_EXCU, 3, 0);
|
|
rtw_btc_table(btc, NM_EXCU, table_case);
|
rtw_btc_tdma(btc, NM_EXCU, tdma_case);
|
}
|
|
static void rtw_btc_action_bt_a2dp_hid(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
u8 table_case = 0, tdma_case = 0, interval = 0;
|
boolean is_toggle_table = FALSE;
|
u32 slot_type = 0, tableB = 0;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_set_ant_path(btc, NM_EXCU, BTC_ANT_2G);
|
rtw_btc_set_rf_para(btc, NM_EXCU, btc->chip_para->wl_rf_para_rx[0]);
|
|
if (coex_sta->wl_iot_peer != BTC_IOT_PEER_CISCO)
|
slot_type = TDMA_4SLOT;
|
|
if (btc->board_info.btdm_ant_num == 1) { /* Shared-Ant */
|
if (coex_sta->bt_ble_exist) {
|
table_case = 26; /* for RCU */
|
} else if (coex_sta->bt_418_hid_exist) { /*for 4/18 HID*/
|
table_case = 9;
|
tableB = 0x5a5a5aaa;
|
interval = 1;
|
} else {
|
table_case = 9; /*for 2/18 HID, BLE HID*/
|
}
|
|
if (coex_sta->wl_connecting || !coex_sta->wl_gl_busy) {
|
tdma_case = 14;
|
} else if (coex_sta->bt_418_hid_exist) {
|
is_toggle_table = TRUE;
|
tdma_case = 23;
|
} else {
|
tdma_case = 13;
|
}
|
} else { /* Non-Shared-Ant */
|
if (coex_sta->bt_ble_exist)
|
table_case = 110;
|
else
|
table_case = 121;
|
|
tdma_case = 113;
|
}
|
|
rtw_btc_table(btc, NM_EXCU, table_case);
|
if (is_toggle_table) {
|
rtw_btc_wltoggle_tableA(btc, FC_EXCU, table_case);
|
rtw_btc_wltoggle_tableB(btc, NM_EXCU, interval, tableB);
|
}
|
|
rtw_btc_tdma(btc, NM_EXCU, tdma_case | slot_type);
|
}
|
|
static void rtw_btc_action_bt_a2dp_pan(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
u8 table_case, tdma_case;
|
boolean wl_cpt_test = FALSE, bt_cpt_test = FALSE;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
if (btc->board_info.customer_id == RT_CID_LENOVO_CHINA &&
|
coex_sta->cnt_wl[BTC_CNT_WL_SCANAP] <= 10 &&
|
coex_sta->wl_iot_peer == BTC_IOT_PEER_ATHEROS) {
|
if (BTC_RSSI_LOW(coex_dm->wl_rssi_state[2]))
|
wl_cpt_test = TRUE;
|
else
|
bt_cpt_test = TRUE;
|
}
|
|
if (wl_cpt_test)
|
rtw_btc_set_rf_para(btc, NM_EXCU, chip_para->wl_rf_para_rx[1]);
|
else
|
rtw_btc_set_rf_para(btc, NM_EXCU, chip_para->wl_rf_para_rx[0]);
|
|
rtw_btc_set_ant_path(btc, NM_EXCU, BTC_ANT_2G);
|
if (btc->board_info.btdm_ant_num == 1) { /* Shared-Ant */
|
if (wl_cpt_test) {
|
if (coex_sta->wl_gl_busy) {
|
table_case = 20;
|
tdma_case = 17;
|
} else {
|
table_case = 10;
|
tdma_case = 15;
|
}
|
} else if (bt_cpt_test) {
|
table_case = 26;
|
tdma_case = 26;
|
} else {
|
if (coex_sta->wl_gl_busy &&
|
coex_sta->wl_noisy_level == 0)
|
table_case = 14;
|
else
|
table_case = 10;
|
|
if (coex_sta->wl_gl_busy)
|
tdma_case = 15;
|
else
|
tdma_case = 20;
|
}
|
} else { /* Non-Shared-Ant */
|
table_case = 112;
|
|
if (coex_sta->wl_gl_busy)
|
tdma_case = 115;
|
else
|
tdma_case = 120;
|
}
|
|
if (coex_sta->bt_slave)
|
rtw_btc_set_extend_btautoslot(btc, 0x3c);
|
else
|
rtw_btc_set_extend_btautoslot(btc, 0x32);
|
|
rtw_btc_table(btc, NM_EXCU, table_case);
|
rtw_btc_tdma(btc, NM_EXCU, tdma_case);
|
}
|
|
static void rtw_btc_action_bt_pan_hid(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
u8 table_case, tdma_case;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_set_ant_path(btc, NM_EXCU, BTC_ANT_2G);
|
rtw_btc_set_rf_para(btc, NM_EXCU, btc->chip_para->wl_rf_para_rx[0]);
|
|
if (btc->board_info.btdm_ant_num == 1) { /* Shared-Ant */
|
table_case = 9;
|
|
if (coex_sta->wl_gl_busy)
|
tdma_case = 18;
|
else
|
tdma_case = 19;
|
} else { /* Non-Shared-Ant */
|
table_case = 113;
|
|
if (coex_sta->wl_gl_busy)
|
tdma_case = 117;
|
else
|
tdma_case = 119;
|
}
|
|
rtw_btc_table(btc, NM_EXCU, table_case);
|
rtw_btc_tdma(btc, NM_EXCU, tdma_case);
|
}
|
|
static void rtw_btc_action_bt_a2dp_pan_hid(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
u8 table_case, tdma_case;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_set_ant_path(btc, NM_EXCU, BTC_ANT_2G);
|
rtw_btc_set_rf_para(btc, NM_EXCU, btc->chip_para->wl_rf_para_rx[0]);
|
|
if (btc->board_info.btdm_ant_num == 1) { /* Shared-Ant */
|
table_case = 10;
|
|
if (coex_sta->wl_gl_busy)
|
tdma_case = 15;
|
else
|
tdma_case = 20;
|
} else { /* Non-Shared-Ant */
|
table_case = 113;
|
|
if (coex_sta->wl_gl_busy)
|
tdma_case = 115;
|
else
|
tdma_case = 120;
|
}
|
|
if (coex_sta->bt_slave)
|
rtw_btc_set_extend_btautoslot(btc, 0x3c);
|
else
|
rtw_btc_set_extend_btautoslot(btc, 0x32);
|
|
rtw_btc_table(btc, NM_EXCU, table_case);
|
rtw_btc_tdma(btc, NM_EXCU, tdma_case);
|
}
|
|
static void rtw_btc_action_wl_off(struct btc_coexist *btc)
|
{
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
|
rtw_btc_tdma(btc, FC_EXCU, 0);
|
rtw_btc_ignore_wlan_act(btc, FC_EXCU, TRUE);
|
rtw_btc_set_ant_path(btc, FC_EXCU, BTC_ANT_WOFF);
|
rtw_btc_set_rf_para(btc, NM_EXCU, btc->chip_para->wl_rf_para_rx[0]);
|
|
btc->stop_coex_dm = TRUE;
|
btc->wl_rf_state_off = TRUE;
|
|
/* must place in the last step */
|
rtw_btc_update_wl_ch_info(btc, BTC_MEDIA_DISCONNECT);
|
if (chip_para->scbd_bit_num == BTC_SCBD_16_BIT)
|
btc->btc_write_scbd(btc, BTC_SCBD_ALL, FALSE);
|
else
|
btc->btc_write_scbd_32bit(btc, BTC_SCBD_ALL_32BIT, FALSE);
|
}
|
|
static void rtw_btc_action_wl_under5g(struct btc_coexist *btc)
|
{
|
u8 table_case, tdma_case;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_set_ant_path(btc, FC_EXCU, BTC_ANT_5G);
|
rtw_btc_set_rf_para(btc, NM_EXCU, btc->chip_para->wl_rf_para_rx[0]);
|
|
if (chip_para->scbd_bit_num == BTC_SCBD_16_BIT)
|
btc->btc_write_scbd(btc, BTC_SCBD_FIX2M, FALSE);
|
else
|
btc->btc_write_scbd_32bit(btc, BTC_SCBD_FIX2M, FALSE);
|
|
if (btc->board_info.btdm_ant_num == 1) { /* Shared-Ant */
|
table_case = 0;
|
tdma_case = 0;
|
} else { /* Non-Shared-Ant */
|
table_case = 100;
|
tdma_case = 100;
|
}
|
|
rtw_btc_table(btc, NM_EXCU, table_case);
|
rtw_btc_tdma(btc, NM_EXCU, tdma_case);
|
}
|
|
static void rtw_btc_action_wl_only(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
u8 table_case, tdma_case;
|
|
rtw_btc_set_ant_path(btc, NM_EXCU, BTC_ANT_2G);
|
rtw_btc_set_rf_para(btc, NM_EXCU, btc->chip_para->wl_rf_para_rx[0]);
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
if (btc->board_info.btdm_ant_num == 1) { /* Shared-Ant */
|
table_case = 2;
|
tdma_case = 0;
|
} else { /* Non-Shared-Ant */
|
table_case = 100;
|
tdma_case = 100;
|
if (coex_sta->wl_gl_busy &&
|
btc->board_info.ext_chip_id != BTC_EXT_CHIP_NONE)
|
tdma_case = rtw_btc_ext_chip_new_tdma(btc, 3);
|
}
|
|
rtw_btc_table(btc, NM_EXCU, table_case);
|
rtw_btc_tdma(btc, NM_EXCU, tdma_case);
|
}
|
|
static void rtw_btc_action_wl_native_lps(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_wifi_link_info_ext *link_info_ext = &btc->wifi_link_info_ext;
|
u8 table_case, tdma_case;
|
|
if (link_info_ext->is_all_under_5g)
|
return;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_set_ant_path(btc, NM_EXCU, BTC_ANT_2G);
|
rtw_btc_set_rf_para(btc, NM_EXCU, btc->chip_para->wl_rf_para_rx[0]);
|
|
if (btc->board_info.btdm_ant_num == 1) { /* Shared-Ant */
|
table_case = 28; /*0x6c0 for A2DP, 0x6c4 for non-A2DP*/
|
tdma_case = 0;
|
} else { /* Non-Shared-Ant */
|
table_case = 100;
|
tdma_case = 100;
|
}
|
|
rtw_btc_table(btc, NM_EXCU, table_case);
|
rtw_btc_tdma(btc, NM_EXCU, tdma_case);
|
}
|
|
static void rtw_btc_action_wl_linkscan(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_wifi_link_info_ext *link_info_ext = &btc->wifi_link_info_ext;
|
u8 table_case, tdma_case;
|
u32 slot_type = 0;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_set_ant_path(btc, NM_EXCU, BTC_ANT_2G);
|
rtw_btc_set_rf_para(btc, NM_EXCU, btc->chip_para->wl_rf_para_rx[0]);
|
|
if (btc->board_info.btdm_ant_num == 1) { /* Shared-Ant */
|
if (coex_sta->bt_pan_exist) {
|
table_case = 34;
|
tdma_case = 8;
|
} else if (coex_sta->bt_a2dp_exist) {
|
slot_type = TDMA_4SLOT;
|
table_case = 9;
|
tdma_case = 11;
|
} else if (coex_sta->bt_hid_exist) {
|
if (link_info_ext->is_connected) {
|
table_case = 36;
|
} else {
|
table_case = 35;
|
}
|
tdma_case = 5;
|
} else {
|
table_case = 9;
|
tdma_case = 7;
|
}
|
} else { /* Non-Shared-Ant */
|
if (coex_sta->bt_pan_exist) {
|
table_case = 124;
|
tdma_case = 108;
|
} else if (coex_sta->bt_a2dp_exist) {
|
slot_type = TDMA_4SLOT;
|
table_case = 124;
|
tdma_case = 126;
|
} else {
|
table_case = 112;
|
tdma_case = 107;
|
}
|
if (coex_sta->wl_gl_busy &&
|
btc->board_info.ext_chip_id != BTC_EXT_CHIP_NONE)
|
tdma_case = rtw_btc_ext_chip_new_tdma(btc, 2);
|
}
|
|
rtw_btc_table(btc, NM_EXCU, table_case);
|
rtw_btc_tdma(btc, NM_EXCU, tdma_case | slot_type);
|
}
|
|
static void rtw_btc_action_wl_not_connected(struct btc_coexist *btc)
|
{
|
struct btc_wifi_link_info_ext *link_info_ext = &btc->wifi_link_info_ext;
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
u8 table_case, tdma_case;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
/* CCK Rx, Tx response, Tx beacon = low pri */
|
if (link_info_ext->num_of_active_port == 0)
|
rtw_btc_set_wl_pri_mask(btc, BTC_WLPRI_RX_CCK, 0);
|
|
coex_sta->wl_cck_lock_ever = FALSE;
|
coex_sta->wl_cck_lock = FALSE;
|
coex_sta->cnt_wl[BTC_CNT_WL_2G_TDDTRY] = FALSE;
|
coex_sta->cnt_wl[BTC_CNT_WL_2G_FDDSTAY] = FALSE;
|
|
rtw_btc_set_ant_path(btc, NM_EXCU, BTC_ANT_2G);
|
rtw_btc_set_rf_para(btc, NM_EXCU, btc->chip_para->wl_rf_para_rx[0]);
|
|
if (btc->board_info.btdm_ant_num == 1) { /* Shared-Ant */
|
table_case = 1;
|
tdma_case = 0;
|
} else { /* Non-Shared-Ant */
|
table_case = 100;
|
tdma_case = 100;
|
}
|
|
rtw_btc_table(btc, NM_EXCU, table_case);
|
rtw_btc_tdma(btc, NM_EXCU, tdma_case);
|
}
|
|
static void rtw_btc_action_wl_connected(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
u8 algorithm;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
/*Leap-AP protection will reopen when connecting AP*/
|
rtw_btc_wl_leakap(btc, TRUE);
|
|
if ((btc->board_info.btdm_ant_num == 2) &&
|
(btc->board_info.ext_chip_id != BTC_EXT_CHIP_NONE)) {
|
rtw_btc_action_ext_chip(btc);
|
return;
|
}
|
|
algorithm = rtw_btc_algorithm(btc);
|
|
switch (algorithm) {
|
case BTC_COEX_HFP:
|
if (rtw_btc_freerun_check(btc))
|
rtw_btc_action_freerun(btc);
|
else
|
rtw_btc_action_bt_hfp(btc);
|
break;
|
case BTC_COEX_HID:
|
if (rtw_btc_freerun_check(btc))
|
rtw_btc_action_freerun(btc);
|
else
|
rtw_btc_action_bt_hid(btc);
|
break;
|
case BTC_COEX_A2DP:
|
if (rtw_btc_freerun_check(btc))
|
rtw_btc_action_freerun(btc);
|
else if (coex_sta->bt_a2dp_sink)
|
rtw_btc_action_bt_a2dpsink(btc);
|
else
|
rtw_btc_action_bt_a2dp(btc);
|
break;
|
case BTC_COEX_PAN:
|
rtw_btc_action_bt_pan(btc);
|
break;
|
case BTC_COEX_A2DP_HID:
|
if (rtw_btc_freerun_check(btc))
|
rtw_btc_action_freerun(btc);
|
else
|
rtw_btc_action_bt_a2dp_hid(btc);
|
break;
|
case BTC_COEX_A2DP_PAN:
|
rtw_btc_action_bt_a2dp_pan(btc);
|
break;
|
case BTC_COEX_PAN_HID:
|
rtw_btc_action_bt_pan_hid(btc);
|
break;
|
case BTC_COEX_A2DP_PAN_HID:
|
rtw_btc_action_bt_a2dp_pan_hid(btc);
|
break;
|
default:
|
case BTC_COEX_NOPROFILE:
|
rtw_btc_action_bt_idle(btc);
|
break;
|
}
|
}
|
|
static void rtw_btc_action_wl_mcc25g(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
u8 table_case, tdma_case;
|
|
rtw_btc_set_ant_path(btc, NM_EXCU, BTC_ANT_MCC);
|
rtw_btc_set_rf_para(btc, NM_EXCU, btc->chip_para->wl_rf_para_rx[0]);
|
|
if (chip_para->scbd_bit_num == BTC_SCBD_16_BIT)
|
btc->btc_write_scbd(btc, BTC_SCBD_FIX2M, FALSE);
|
else
|
btc->btc_write_scbd_32bit(btc, BTC_SCBD_FIX2M, FALSE);
|
|
if (btc->board_info.btdm_ant_num == 1) { /* Shared-Ant */
|
if (coex_sta->bt_setup_link) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): BT Relink\n", __func__);
|
|
table_case = 24;
|
tdma_case = 0;
|
} else if (coex_sta->bt_inq_page) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): BT Inq-Pag\n", __func__);
|
|
table_case = 23;
|
tdma_case = 0;
|
} else {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): BT on\n", __func__);
|
|
if (coex_sta->wl_gl_busy) {
|
if (coex_sta->wl_rx_rate <= 3 ||
|
coex_sta->wl_rts_rx_rate <= 3)
|
table_case = 31;
|
else if (coex_sta->bt_hid_exist ||
|
coex_sta->bt_hfp_exist)
|
table_case = 26;
|
else
|
table_case = 27;
|
} else {
|
table_case = 27;
|
}
|
|
tdma_case = 0;
|
}
|
} else { /* Non-Shared-Ant */
|
if (coex_sta->bt_setup_link) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): BT Relink\n", __func__);
|
|
table_case = 100;
|
tdma_case = 100;
|
} else if (coex_sta->bt_inq_page) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): BT Inq-Pag\n", __func__);
|
|
table_case = 118;
|
tdma_case = 100;
|
} else {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): BT on!!\n", __func__);
|
|
table_case = 118;
|
tdma_case = 100;
|
}
|
}
|
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_table(btc, NM_EXCU, table_case);
|
rtw_btc_tdma(btc, NM_EXCU, tdma_case);
|
}
|
|
static void rtw_btc_action_wl_scc2g(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
u8 table_case = 0xff, tdma_case = 0xff;
|
boolean is_toggle_table = FALSE;
|
u32 slot_type = 0;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
if (coex_sta->bt_profile_num == 1) {
|
if (coex_sta->bt_hid_exist || coex_sta->bt_hfp_exist) {
|
if (coex_sta->bt_a2dp_active) {
|
table_case = 9;
|
tdma_case = 21;
|
} else if (coex_sta->bt_418_hid_exist) {
|
table_case = 10;
|
tdma_case = 24;
|
is_toggle_table = TRUE;
|
slot_type = TDMA_4SLOT;
|
} else {
|
table_case = 2;
|
tdma_case = 0;
|
}
|
} else if (coex_sta->bt_a2dp_exist) {
|
table_case = 10;
|
tdma_case = 22;
|
slot_type = TDMA_4SLOT;
|
} else { /* PAN or OPP */
|
table_case = 10;
|
tdma_case = 21;
|
}
|
} else {
|
if ((coex_sta->bt_hid_exist || coex_sta->bt_hfp_exist) &&
|
coex_sta->bt_a2dp_exist) {
|
table_case = 9;
|
tdma_case = 22;
|
|
slot_type = TDMA_4SLOT;
|
if (coex_sta->bt_418_hid_exist)
|
is_toggle_table = TRUE;
|
} else if (coex_sta->bt_pan_exist && coex_sta->bt_a2dp_exist) {
|
table_case = 10;
|
tdma_case = 22;
|
slot_type = TDMA_4SLOT;
|
} else { /* hid + pan */
|
table_case = 9;
|
tdma_case = 21;
|
}
|
}
|
|
rtw_btc_table(btc, NM_EXCU, table_case);
|
if (is_toggle_table) {
|
rtw_btc_wltoggle_tableA(btc, FC_EXCU, table_case);
|
rtw_btc_wltoggle_tableB(btc, NM_EXCU, 1, 0x5a5a5aaa);
|
}
|
|
rtw_btc_tdma(btc, NM_EXCU, tdma_case | slot_type);
|
}
|
|
static void rtw_btc_action_wl_p2p2g(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_rfe_type *rfe_type = &btc->rfe_type;
|
struct btc_wifi_link_info *link_info = &btc->wifi_link_info;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
u8 table_case = 0xff, tdma_case = 0xff, ant_phase;
|
|
if (rfe_type->ant_switch_with_bt)
|
ant_phase = BTC_ANT_2G_FREERUN;
|
else
|
ant_phase = BTC_ANT_2G;
|
|
rtw_btc_set_rf_para(btc, NM_EXCU, btc->chip_para->wl_rf_para_rx[0]);
|
|
if (chip_para->scbd_bit_num == BTC_SCBD_16_BIT)
|
btc->btc_write_scbd(btc, BTC_SCBD_FIX2M, FALSE);
|
else
|
btc->btc_write_scbd_32bit(btc, BTC_SCBD_FIX2M, FALSE);
|
|
if (coex_sta->bt_disabled) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): BT Disable!!\n", __func__);
|
BTC_TRACE(trace_buf);
|
rtw_btc_set_ant_path(btc, NM_EXCU, BTC_ANT_2G);
|
|
table_case = 0;
|
tdma_case = 0;
|
} else if (btc->board_info.btdm_ant_num == 2) { /* Non-Shared-Ant */
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): Non_Shared_Ant!!\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_action_freerun(btc);
|
return;
|
} else if (coex_sta->bt_setup_link) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): BT Relink!!\n", __func__);
|
|
rtw_btc_set_ant_path(btc, NM_EXCU, ant_phase);
|
|
table_case = 1;
|
tdma_case = 0;
|
} else if (coex_sta->bt_inq_page) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): BT Inq-Page!!\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_set_ant_path(btc, NM_EXCU, ant_phase);
|
|
table_case = 15;
|
tdma_case = 2;
|
} else if (coex_sta->bt_profile_num == 0) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): BT idle!!\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_set_ant_path(btc, NM_EXCU, ant_phase);
|
|
if (btc->chip_interface == BTC_INTF_PCI &&
|
(link_info->link_mode == BTC_LINK_ONLY_GO ||
|
link_info->link_mode == BTC_LINK_ONLY_GC) &&
|
coex_sta->wl_gl_busy)
|
table_case = 3;
|
else
|
table_case = 1;
|
|
tdma_case = 0;
|
} else if (coex_sta->wl_linkscan_proc) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): WL scan!!\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_action_wl_linkscan(btc);
|
} else {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): BT busy!!\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
switch (link_info->link_mode) {
|
case BTC_LINK_2G_SCC_GC_STA:
|
case BTC_LINK_2G_SCC_GO_STA:
|
rtw_btc_set_ant_path(btc, NM_EXCU, BTC_ANT_2G);
|
rtw_btc_action_wl_scc2g(btc);
|
break;
|
case BTC_LINK_ONLY_GO:
|
case BTC_LINK_ONLY_GC:
|
rtw_btc_set_ant_path(btc, NM_EXCU, BTC_ANT_2G);
|
#ifdef PLATFORM_WINDOWS
|
if (btc->chip_interface == BTC_INTF_PCI &&
|
coex_sta->bt_a2dp_exist && !coex_sta->bt_multi_link)
|
table_case = 3;
|
else
|
#endif
|
table_case = 2;
|
|
tdma_case = 0;
|
break;
|
default:
|
rtw_btc_set_ant_path(btc, NM_EXCU, ant_phase);
|
table_case = 2;
|
tdma_case = 0;
|
break;
|
}
|
}
|
|
if (table_case != 0xff && tdma_case != 0xff) {
|
rtw_btc_table(btc, NM_EXCU, table_case);
|
rtw_btc_tdma(btc, NM_EXCU, tdma_case);
|
}
|
}
|
|
static void rtw_btc_run_coex(struct btc_coexist *btc, u8 reason)
|
{
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_wifi_link_info_ext *link_info_ext = &btc->wifi_link_info_ext;
|
struct btc_wifi_link_info *link_info = &btc->wifi_link_info;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): reason = %d\n", __func__, reason);
|
BTC_TRACE(trace_buf);
|
|
coex_sta->coex_run_reason = reason;
|
|
/* update wifi_link_info_ext variable */
|
rtw_btc_update_wl_link_info(btc, reason);
|
|
rtw_btc_monitor_bt_enable(btc);
|
|
if (btc->manual_control) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], return for Manual CTRL!!\n");
|
BTC_TRACE(trace_buf);
|
return;
|
}
|
|
if (btc->stop_coex_dm) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], return for Stop Coex DM!!\n");
|
BTC_TRACE(trace_buf);
|
return;
|
}
|
|
if (coex_sta->wl_under_ips) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], return for wifi is under IPS!!\n");
|
BTC_TRACE(trace_buf);
|
return;
|
}
|
|
if (coex_sta->wl_under_lps && link_info_ext->is_32k) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], return for wifi is under LPS-32K!!\n");
|
BTC_TRACE(trace_buf);
|
return;
|
}
|
|
if (coex_sta->coex_freeze && reason == BTC_RSN_BTINFO &&
|
!coex_sta->bt_setup_link) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], return for coex_freeze!!\n");
|
BTC_TRACE(trace_buf);
|
return;
|
}
|
|
coex_sta->cnt_wl[BTC_CNT_WL_COEXRUN]++;
|
coex_sta->coex_freerun = FALSE;
|
|
/* Pure-5G Coex Process */
|
if (link_info_ext->is_all_under_5g) {
|
coex_sta->wl_coex_mode = BTC_WLINK_5G;
|
rtw_btc_action_wl_under5g(btc);
|
goto exit;
|
}
|
|
if (link_info_ext->is_mcc_25g) {
|
coex_sta->wl_coex_mode = BTC_WLINK_25GMPORT;
|
rtw_btc_action_wl_mcc25g(btc);
|
goto exit;
|
}
|
|
/* if multi-port, P2P-GO, P2P-GC */
|
if (link_info_ext->num_of_active_port > 1 ||
|
(link_info->link_mode == BTC_LINK_ONLY_GO &&
|
!link_info_ext->is_ap_mode) ||
|
link_info->link_mode == BTC_LINK_ONLY_GC) {
|
if (link_info->link_mode == BTC_LINK_ONLY_GO)
|
coex_sta->wl_coex_mode = BTC_WLINK_2GGO;
|
else if (link_info->link_mode == BTC_LINK_ONLY_GC)
|
coex_sta->wl_coex_mode = BTC_WLINK_2GGC;
|
else
|
coex_sta->wl_coex_mode = BTC_WLINK_2GMPORT;
|
rtw_btc_action_wl_p2p2g(btc);
|
goto exit;
|
}
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], WiFi is single-port 2G!!\n");
|
BTC_TRACE(trace_buf);
|
|
coex_sta->wl_coex_mode = BTC_WLINK_2G1PORT;
|
|
if (coex_sta->bt_disabled) {
|
if (!link_info_ext->is_connected)
|
rtw_btc_action_wl_not_connected(btc);
|
else
|
rtw_btc_action_wl_only(btc);
|
goto exit;
|
}
|
|
if (coex_sta->wl_under_lps && !coex_sta->wl_force_lps_ctrl) {
|
rtw_btc_action_wl_native_lps(btc);
|
goto exit;
|
}
|
|
if (coex_sta->bt_whck_test) {
|
rtw_btc_action_bt_whql_test(btc);
|
goto exit;
|
}
|
|
if (coex_sta->bt_setup_link) {
|
rtw_btc_action_bt_relink(btc);
|
goto exit;
|
}
|
|
if (coex_sta->bt_inq_page) {
|
rtw_btc_action_bt_inquiry(btc);
|
goto exit;
|
}
|
|
if ((coex_dm->bt_status == BTC_BTSTATUS_NCON_IDLE ||
|
coex_dm->bt_status == BTC_BTSTATUS_CON_IDLE) &&
|
link_info_ext->is_connected) {
|
rtw_btc_action_bt_idle(btc);
|
goto exit;
|
}
|
|
if (coex_sta->wl_linkscan_proc && !coex_sta->coex_freerun) {
|
rtw_btc_action_wl_linkscan(btc);
|
goto exit;
|
}
|
|
if (link_info_ext->is_connected) {
|
rtw_btc_action_wl_connected(btc);
|
goto exit;
|
} else {
|
rtw_btc_action_wl_not_connected(btc);
|
goto exit;
|
}
|
|
exit:
|
#ifdef PLATFORM_WINDOWS
|
/* 0:original, 1:1R */
|
if (coex_sta->wl_coex_mode == BTC_WLINK_2GFREE &&
|
chip_para->rx_path_num >= 2)
|
rtw_btc_mimo_ps(btc, FC_EXCU, 1);
|
else
|
rtw_btc_mimo_ps(btc, FC_EXCU, 0);
|
#endif
|
|
rtw_btc_gnt_workaround(btc, NM_EXCU, coex_sta->wl_coex_mode);
|
rtw_btc_limited_wl(btc);
|
}
|
|
static void rtw_btc_init_coex_var(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
u8 i;
|
|
/* Reset Coex variable */
|
btc->btc_set(btc, BTC_SET_RESET_COEX_VAR, NULL);
|
|
/* Init Coex variables that are not zero */
|
for (i = 0; i < ARRAY_SIZE(coex_dm->bt_rssi_state); i++)
|
coex_dm->bt_rssi_state[i] = BTC_RSSI_STATE_LOW;
|
|
for (i = 0; i < ARRAY_SIZE(coex_dm->wl_rssi_state); i++)
|
coex_dm->wl_rssi_state[i] = BTC_RSSI_STATE_LOW;
|
|
for (i = 0; i < ARRAY_SIZE(coex_sta->bt_sut_pwr_lvl); i++)
|
coex_sta->bt_sut_pwr_lvl[i] = 0xff;
|
|
coex_sta->bt_reg_vendor_ac = 0xffff;
|
coex_sta->bt_reg_vendor_ae = 0xffff;
|
|
coex_sta->gnt_workaround_state = BTC_WLINK_MAX;
|
btc->bt_info.bt_get_fw_ver = 0;
|
}
|
|
static void
|
rtw_btc_init_hw_config(struct btc_coexist *btc, boolean wifi_only)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
u8 table_case = 1, tdma_case = 0;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
/* init coex_dm, coex_sta variable to sync with chip status */
|
rtw_btc_init_coex_var(btc);
|
|
/* 0xf0[15:12] --> chip kt info */
|
coex_sta->kt_ver = (btc->btc_read_1byte(btc, 0xf1) & 0xf0) >> 4;
|
|
rtw_btc_monitor_bt_enable(btc);
|
|
/* TBTT enable */
|
btc->btc_write_1byte_bitmask(btc, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION,
|
0x1);
|
|
/* Setup RF front end type */
|
btc->chip_para->chip_setup(btc, BTC_CSETUP_RFE_TYPE);
|
|
/* Init coex relared register */
|
btc->chip_para->chip_setup(btc, BTC_CSETUP_INIT_HW);
|
|
/* set Tx response = Hi-Pri (ex: Transmitting ACK,BA,CTS) */
|
rtw_btc_set_wl_pri_mask(btc, BTC_WLPRI_TX_RSP, 1);
|
|
/* set Tx beacon = Hi-Pri */
|
rtw_btc_set_wl_pri_mask(btc, BTC_WLPRI_TX_BEACON, 1);
|
|
/* set Tx beacon queue = Hi-Pri */
|
rtw_btc_set_wl_pri_mask(btc, BTC_WLPRI_TX_BEACONQ, 1);
|
|
/* Antenna config */
|
if (btc->wl_rf_state_off) {
|
rtw_btc_set_ant_path(btc, FC_EXCU, BTC_ANT_WOFF);
|
if (chip_para->scbd_bit_num == BTC_SCBD_16_BIT)
|
btc->btc_write_scbd(btc, BTC_SCBD_ALL, FALSE);
|
else
|
btc->btc_write_scbd_32bit(btc, BTC_SCBD_ALL_32BIT, FALSE);
|
btc->stop_coex_dm = TRUE;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): RF Off\n", __func__);
|
BTC_TRACE(trace_buf);
|
} else if (wifi_only) {
|
rtw_btc_set_ant_path(btc, FC_EXCU, BTC_ANT_WONLY);
|
if (chip_para->scbd_bit_num == BTC_SCBD_16_BIT)
|
btc->btc_write_scbd(btc, BTC_SCBD_ACTIVE | BTC_SCBD_ON, TRUE);
|
else
|
btc->btc_write_scbd_32bit(btc, BTC_SCBD_ACTIVE | BTC_SCBD_ON, TRUE);
|
btc->stop_coex_dm = TRUE;
|
} else {
|
rtw_btc_set_ant_path(btc, FC_EXCU, BTC_ANT_INIT);
|
if (chip_para->scbd_bit_num == BTC_SCBD_16_BIT)
|
btc->btc_write_scbd(btc, BTC_SCBD_ACTIVE | BTC_SCBD_ON, TRUE);
|
else
|
btc->btc_write_scbd_32bit(btc, BTC_SCBD_ACTIVE | BTC_SCBD_ON, TRUE);
|
btc->stop_coex_dm = FALSE;
|
coex_sta->coex_freeze = TRUE;
|
}
|
|
/* PTA parameter */
|
rtw_btc_table(btc, FC_EXCU, table_case);
|
rtw_btc_tdma(btc, FC_EXCU, tdma_case);
|
|
rtw_btc_query_bt_info(btc);
|
}
|
|
void rtw_btc_ex_power_on_setting(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_board_info *board_info = &btc->board_info;
|
u8 table_case = 1;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
btc->stop_coex_dm = TRUE;
|
btc->wl_rf_state_off = FALSE;
|
|
/* enable BB, REG_SYS_FUNC_EN to write reg correctly. */
|
btc->btc_write_1byte_bitmask(btc, REG_SYS_FUNC_EN,
|
BIT_FEN_BB_GLB_RST | BIT_FEN_BB_RSTB, 0x3);
|
|
rtw_btc_monitor_bt_enable(btc);
|
|
/* Setup RF front end type */
|
btc->chip_para->chip_setup(btc, BTC_CSETUP_RFE_TYPE);
|
|
/* Set Antenna Path to BT side */
|
rtw_btc_set_ant_path(btc, FC_EXCU, BTC_ANT_POWERON);
|
|
rtw_btc_table(btc, FC_EXCU, table_case);
|
|
/* SD1 Chunchu red x issue */
|
btc->btc_write_1byte(btc, 0xff1a, 0x0);
|
|
rtw_btc_gnt_debug(btc, TRUE);
|
|
board_info->btdm_ant_pos = BTC_ANTENNA_AT_MAIN_PORT;
|
}
|
|
void rtw_btc_ex_pre_load_firmware(struct btc_coexist *btc) {}
|
|
void rtw_btc_ex_init_hw_config(struct btc_coexist *btc, boolean wifi_only)
|
{
|
rtw_btc_init_hw_config(btc, wifi_only);
|
}
|
|
void rtw_btc_ex_init_coex_dm(struct btc_coexist *btc)
|
{
|
}
|
|
void rtw_btc_ex_display_simple_coex_info(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
struct btc_rfe_type *rfe_type = &btc->rfe_type;
|
struct btc_board_info *board_info = &btc->board_info;
|
|
u8 *cli_buf = btc->cli_buf;
|
u32 bt_patch_ver = 0, bt_coex_ver = 0, val = 0;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n _____[BT Coexist info]____");
|
CL_PRINTF(cli_buf);
|
|
if (btc->manual_control) {
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n __[Under Manual Control]_");
|
CL_PRINTF(cli_buf);
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n _________________________");
|
CL_PRINTF(cli_buf);
|
}
|
|
if (btc->stop_coex_dm) {
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n ____[Coex is STOPPED]____");
|
CL_PRINTF(cli_buf);
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n _________________________");
|
CL_PRINTF(cli_buf);
|
}
|
|
if (!coex_sta->bt_disabled &&
|
(coex_sta->bt_supported_version == 0 ||
|
coex_sta->bt_supported_version == 0xffff) &&
|
coex_sta->cnt_wl[BTC_CNT_WL_COEXINFO2] % 3 == 0) {
|
btc->btc_get(btc, BTC_GET_U4_SUPPORTED_FEATURE,
|
&coex_sta->bt_supported_feature);
|
|
btc->btc_get(btc, BTC_GET_U4_SUPPORTED_VERSION,
|
&coex_sta->bt_supported_version);
|
|
val = btc->btc_get_bt_reg(btc, 3, 0xac);
|
coex_sta->bt_reg_vendor_ac = (u16)(val & 0xffff);
|
|
val = btc->btc_get_bt_reg(btc, 3, 0xae);
|
coex_sta->bt_reg_vendor_ae = (u16)(val & 0xffff);
|
|
btc->btc_get(btc, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver);
|
btc->bt_info.bt_get_fw_ver = bt_patch_ver;
|
}
|
|
/* BT coex. info. */
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n %-35s = %d/ %d/ %s / %d",
|
"Ant PG Num/ Mech/ Pos/ RFE", board_info->pg_ant_num,
|
board_info->btdm_ant_num,
|
(board_info->btdm_ant_pos ==
|
BTC_ANTENNA_AT_MAIN_PORT ? "Main" : "Aux"),
|
rfe_type->rfe_module_type);
|
CL_PRINTF(cli_buf);
|
|
bt_coex_ver = ((coex_sta->bt_supported_version & 0xff00) >> 8);
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n %-35s = %d_%02x/ %d_%02x/ 0x%02x/ 0x%02x (%s)",
|
"Ver Coex/ Para/ BT_Dez/ BT_Rpt",
|
coex_ver_date, coex_ver, chip_para->para_ver_date,
|
chip_para->para_ver, chip_para->bt_desired_ver, bt_coex_ver,
|
(bt_coex_ver == 0xff ? "Unknown" :
|
(coex_sta->bt_disabled ? "BT-disable" :
|
(bt_coex_ver >= chip_para->bt_desired_ver ?
|
"Match" : "Mis-Match"))));
|
CL_PRINTF(cli_buf);
|
|
/* BT Status */
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", "BT status",
|
((coex_sta->bt_disabled) ? ("disabled") :
|
((coex_sta->bt_inq_page) ? ("inquiry/page") :
|
((coex_dm->bt_status == BTC_BTSTATUS_NCON_IDLE) ?
|
"non-connected idle" :
|
((coex_dm->bt_status == BTC_BTSTATUS_CON_IDLE) ?
|
"connected-idle" : "busy")))));
|
CL_PRINTF(cli_buf);
|
|
/* HW Settings */
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d",
|
"0x770(Hi-pri rx/tx)", coex_sta->hi_pri_rx,
|
coex_sta->hi_pri_tx);
|
CL_PRINTF(cli_buf);
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d %s",
|
"0x774(Lo-pri rx/tx)", coex_sta->lo_pri_rx,
|
coex_sta->lo_pri_tx, (coex_sta->bt_slave ?
|
"(Slave!!)" : ""));
|
CL_PRINTF(cli_buf);
|
|
coex_sta->cnt_wl[BTC_CNT_WL_COEXINFO2]++;
|
}
|
|
void rtw_btc_ex_display_coex_info(struct btc_coexist *btc)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
struct btc_rfe_type *rfe_type = &btc->rfe_type;
|
struct btc_board_info *board_info = &btc->board_info;
|
|
u8 *cli_buf = btc->cli_buf, i, ps_tdma_case = 0;
|
u16 scbd;
|
u32 phy_ver = 0, fw_ver = 0,
|
bt_coex_ver = 0, val = 0,
|
fa_ofdm, fa_cck, cca_ofdm, cca_cck,
|
ok_11b, ok_11g, ok_11n, ok_11vht,
|
err_11b, err_11g, err_11n, err_11vht,
|
scbd_32, bt_slot_max , bt_slot_min, bt_slot_sum = 0;
|
boolean is_bt_reply = FALSE;
|
u8 * const p = &coex_sta->bt_afh_map[0];
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n ============[BT Coexist info %s]============",
|
chip_para->chip_name);
|
CL_PRINTF(cli_buf);
|
|
if (btc->manual_control) {
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n ============[Under Manual Control]============");
|
CL_PRINTF(cli_buf);
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n ==========================================");
|
CL_PRINTF(cli_buf);
|
} else if (btc->stop_coex_dm) {
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n ============[Coex is STOPPED]============");
|
CL_PRINTF(cli_buf);
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n ==========================================");
|
CL_PRINTF(cli_buf);
|
} else if (coex_sta->coex_freeze) {
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n ============[coex_freeze]============");
|
CL_PRINTF(cli_buf);
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n ==========================================");
|
CL_PRINTF(cli_buf);
|
}
|
|
if (!coex_sta->bt_disabled &&
|
coex_sta->cnt_wl[BTC_CNT_WL_COEXINFO1] % 3 == 0) {
|
if (coex_sta->bt_supported_version == 0 ||
|
coex_sta->bt_supported_version == 0xffff) {
|
btc->btc_get(btc, BTC_GET_U4_SUPPORTED_VERSION,
|
&coex_sta->bt_supported_version);
|
|
if (coex_sta->bt_supported_version > 0 &&
|
coex_sta->bt_supported_version < 0xffff)
|
is_bt_reply = TRUE;
|
} else {
|
is_bt_reply = TRUE;
|
}
|
|
if (coex_dm->bt_status != BTC_BTSTATUS_NCON_IDLE) {
|
btc->btc_get_bt_afh_map_from_bt(btc, 0, p);
|
val = btc->btc_get_bt_reg(btc, 1, 0xa);
|
coex_sta->bt_reg_modem_a = (u16)((val & 0x1c0) >> 6);
|
val = btc->btc_get_bt_reg(btc, 0, 0x2);
|
coex_sta->bt_reg_rf_2 = (u16)val;
|
}
|
}
|
|
if (is_bt_reply) {
|
if (coex_sta->bt_supported_feature == 0) {
|
btc->btc_get(btc, BTC_GET_U4_SUPPORTED_FEATURE,
|
&coex_sta->bt_supported_feature);
|
|
if (coex_sta->bt_supported_feature & BIT(11))
|
coex_sta->bt_slave_latency = TRUE;
|
else
|
coex_sta->bt_slave_latency = FALSE;
|
}
|
|
if (strcmp(btc->chip_para->chip_name, "8723f") == 0) {
|
/*8723f cannot read ae because ALIGNMENT_UNIT = 4byte
|
8723f should read bt vendor reg 0xdac*/
|
if (coex_sta->bt_reg_vendor_dac == 0xffffffff) {
|
val = btc->btc_get_bt_reg(btc, 3, 0xdac);
|
coex_sta->bt_reg_vendor_dac = val;
|
}
|
} else {
|
if (coex_sta->bt_reg_vendor_ac == 0xffff) {
|
val = btc->btc_get_bt_reg(btc, 3, 0xac);
|
coex_sta->bt_reg_vendor_ac = (u16)(val & 0xffff);
|
}
|
|
if (coex_sta->bt_reg_vendor_ae == 0xffff) {
|
val = btc->btc_get_bt_reg(btc, 3, 0xae);
|
coex_sta->bt_reg_vendor_ae = (u16)(val & 0xffff);
|
}
|
}
|
|
val = btc->btc_get_bt_reg(btc, 4, 0x200);
|
coex_sta->bt_reg_le_200 = (u16)(val & 0xffff);
|
|
if (btc->bt_info.bt_get_fw_ver == 0)
|
btc->btc_get(btc, BTC_GET_U4_BT_PATCH_VER,
|
&btc->bt_info.bt_get_fw_ver);
|
|
if (coex_sta->bt_a2dp_exist &&
|
coex_sta->bt_a2dp_vendor_id == 0 &&
|
coex_sta->bt_a2dp_device_name == 0) {
|
btc->btc_get(btc, BTC_GET_U4_BT_DEVICE_INFO, &val);
|
coex_sta->bt_a2dp_vendor_id = (u8)(val & 0xff);
|
coex_sta->bt_a2dp_device_name = (val & 0xffffff00) >> 8;
|
}
|
|
if (coex_sta->bt_a2dp_exist &&
|
coex_sta->bt_a2dp_flush_time == 0) {
|
btc->btc_get(btc, BTC_GET_U4_BT_A2DP_FLUSH_VAL, &val);
|
coex_sta->bt_a2dp_flush_time = val;
|
}
|
}
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %s/ %s / %d/ %d",
|
"Ant PG Num/ Mech/ Pos/ RFE/ Dist", board_info->pg_ant_num,
|
(board_info->btdm_ant_num == 1 ? "Shared" : "Non-Shared"),
|
(board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT ?
|
"Main" : "Aux"), rfe_type->rfe_module_type,
|
board_info->ant_distance);
|
CL_PRINTF(cli_buf);
|
|
btc->btc_get(btc, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
|
btc->btc_get(btc, BTC_GET_U4_WIFI_PHY_VER, &phy_ver);
|
bt_coex_ver = ((coex_sta->bt_supported_version & 0xff00) >> 8);
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n %-35s = %d_%02x/ %d_%02x/ 0x%02x/ 0x%02x (%s)",
|
"Ver Coex/ Para/ BT_Dez/ BT_Rpt",
|
coex_ver_date, coex_ver, chip_para->para_ver_date,
|
chip_para->para_ver, chip_para->bt_desired_ver, bt_coex_ver,
|
(bt_coex_ver == 0xff ? "Unknown" :
|
(coex_sta->bt_disabled ? "BT-disable" :
|
(bt_coex_ver >= chip_para->bt_desired_ver ?
|
"Match" : "Mis-Match"))));
|
CL_PRINTF(cli_buf);
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n %-35s = 0x%x(%s)/ 0x%08x/ v%d/ %c",
|
"W_FW/ B_FW/ Phy/ Kt", fw_ver,
|
(fw_ver >= chip_para->wl_desired_ver ? "Match" : "Mis-Match"),
|
btc->bt_info.bt_get_fw_ver, phy_ver, coex_sta->kt_ver + 65);
|
CL_PRINTF(cli_buf);
|
|
/* wifi status */
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s",
|
"============[Wifi Status]============");
|
CL_PRINTF(cli_buf);
|
btc->btc_disp_dbg_msg(btc, BTC_DBG_DISP_WIFI_STATUS);
|
|
/*EXT CHIP status*/
|
if (btc->board_info.ext_chip_id != BTC_EXT_CHIP_NONE) {
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s",
|
"============[EXT CHIP Status]============");
|
CL_PRINTF(cli_buf);
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s",
|
"EXT CHIP ID/EXT CHIP mode",
|
((btc->board_info.ext_chip_id ==
|
BTC_EXT_CHIP_RF4CE) ? "RF4CE" : "unknown"),
|
((coex_sta->ext_chip_mode ==
|
BTC_EXTMODE_VOICE) ? "VOICE" : "NORMAL"));
|
CL_PRINTF(cli_buf);
|
}
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s",
|
"============[BT Status]============");
|
CL_PRINTF(cli_buf);
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %ddBm/ %d/ %d",
|
"BT status/ rssi/ retryCnt/ popCnt",
|
((coex_sta->bt_disabled) ? ("disabled") :
|
((coex_sta->bt_inq_page) ? ("inquiry-page") :
|
((coex_dm->bt_status == BTC_BTSTATUS_NCON_IDLE) ?
|
"non-connecte-idle" : ((coex_dm->bt_status ==
|
BTC_BTSTATUS_CON_IDLE) ? "connected-idle" : "busy")))),
|
coex_sta->bt_rssi - 100, coex_sta->cnt_bt[BTC_CNT_BT_RETRY],
|
coex_sta->cnt_bt[BTC_CNT_BT_POPEVENT]);
|
CL_PRINTF(cli_buf);
|
|
if (coex_sta->bt_profile_num != 0) {
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n %-35s = %s%s%s%s%s%s (multilink = %d)",
|
"Profiles", ((coex_sta->bt_a2dp_exist) ?
|
((coex_sta->bt_a2dp_sink) ? "A2DP sink," :
|
"A2DP,") : ""),
|
((coex_sta->bt_hfp_exist) ? "HFP," : ""),
|
((coex_sta->bt_hid_exist) ?
|
((coex_sta->bt_ble_exist) ? "HID(RCU)" :
|
((coex_sta->bt_hid_slot >= 2) ? "HID(4/18)," :
|
(coex_sta->bt_ble_hid_exist ? "HID(BLE)" :
|
"HID(2/18),"))) : ""), ((coex_sta->bt_pan_exist) ?
|
((coex_sta->bt_opp_exist) ? "OPP," : "PAN,") :
|
""), ((coex_sta->bt_ble_voice) ? "Voice," : ""),
|
((coex_sta->bt_msft_mr_exist) ? "MR" : ""),
|
coex_sta->bt_multi_link);
|
CL_PRINTF(cli_buf);
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n %-35s = %d/ %d/ %d/ %d",
|
"SUT Power[3:0]",
|
coex_sta->bt_sut_pwr_lvl[3],
|
coex_sta->bt_sut_pwr_lvl[2],
|
coex_sta->bt_sut_pwr_lvl[1],
|
coex_sta->bt_sut_pwr_lvl[0]);
|
|
CL_PRINTF(cli_buf);
|
} else {
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s",
|
"Profiles",
|
(coex_sta->bt_msft_mr_exist) ? "MR" : "None");
|
|
CL_PRINTF(cli_buf);
|
}
|
|
/* for 8822b, Scoreboard[10]: 0: CQDDR off, 1: CQDDR on
|
* for 8822c, Scoreboard[10]: 0: CQDDR on, 1:CQDDR fix 2M
|
*/
|
|
if (coex_sta->bt_a2dp_exist) {
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n %-35s = %s/ %d/ 0x%x/ 0x%x/ %d",
|
"CQDDR/Bitpool/V_ID/D_name/Flush",
|
(chip_para->new_scbd10_def ?
|
((coex_sta->bt_fix_2M) ? "fix_2M" : "CQDDR_On") :
|
((coex_sta->bt_fix_2M) ? "CQDDR_On" : "CQDDR_Off")),
|
coex_sta->bt_a2dp_bitpool,
|
coex_sta->bt_a2dp_vendor_id,
|
coex_sta->bt_a2dp_device_name,
|
coex_sta->bt_a2dp_flush_time);
|
|
CL_PRINTF(cli_buf);
|
}
|
|
if (coex_sta->bt_hid_exist) {
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d",
|
"HID PairNum", coex_sta->bt_hid_pair_num);
|
CL_PRINTF(cli_buf);
|
}
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %d/ %s/ 0x%x",
|
"Role/RoleSwCnt/IgnWla/Feature",
|
((coex_sta->bt_slave) ? "Slave" : "Master"),
|
coex_sta->cnt_bt[BTC_CNT_BT_ROLESWITCH],
|
((coex_dm->cur_ignore_wlan_act) ? "Yes" : "No"),
|
coex_sta->bt_supported_feature);
|
CL_PRINTF(cli_buf);
|
|
if (coex_sta->bt_ble_scan_en) {
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
|
"BLEScan Type/TV/Init/Ble",
|
coex_sta->bt_ble_scan_type,
|
(coex_sta->bt_ble_scan_type & 0x1 ?
|
coex_sta->bt_ble_scan_para[0] : 0x0),
|
(coex_sta->bt_ble_scan_type & 0x2 ?
|
coex_sta->bt_ble_scan_para[1] : 0x0),
|
(coex_sta->bt_ble_scan_type & 0x4 ?
|
coex_sta->bt_ble_scan_para[2] : 0x0));
|
CL_PRINTF(cli_buf);
|
}
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n %-35s = %d/ %d/ %d/ %d/ %d/ %d/ %d %s",
|
"Init/ReLink/IgnWl/Pag/Inq/iqkO/iqkX",
|
coex_sta->cnt_bt[BTC_CNT_BT_REINIT],
|
coex_sta->cnt_bt[BTC_CNT_BT_SETUPLINK],
|
coex_sta->cnt_bt[BTC_CNT_BT_IGNWLANACT],
|
coex_sta->cnt_bt[BTC_CNT_BT_PAGE],
|
coex_sta->cnt_bt[BTC_CNT_BT_INQ],
|
coex_sta->cnt_bt[BTC_CNT_BT_IQK],
|
coex_sta->cnt_bt[BTC_CNT_BT_IQKFAIL],
|
(coex_sta->bt_setup_link ? "(Relink!!)" : ""));
|
CL_PRINTF(cli_buf);
|
|
if (coex_sta->bt_reg_vendor_ae != 0xffff ||
|
coex_sta->bt_reg_vendor_ac != 0xffff ||
|
coex_sta->bt_reg_vendor_dac != 0xffffffff) {
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x/ 0x%x/ %s",
|
"ae/ac/dac/m_a[8:6]/ScBd(B->W)/path",
|
coex_sta->bt_reg_vendor_ae,
|
coex_sta->bt_reg_vendor_ac,
|
coex_sta->bt_reg_vendor_dac,
|
coex_sta->bt_reg_modem_a,
|
((chip_para->scbd_bit_num == BTC_SCBD_16_BIT) ?
|
btc->btc_read_scbd(btc, &scbd) :
|
btc->btc_read_scbd_32bit(btc, &scbd_32)),
|
((coex_sta->bt_reg_vendor_ae & BIT(4)) ? "S1" : "S0"
|
));
|
CL_PRINTF(cli_buf);
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n %-35s = 0x%x/ 0x%x",
|
"rf_2/rf_9",
|
coex_sta->bt_reg_rf_2,
|
coex_sta->bt_reg_rf_9);
|
} else {
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n %-35s = x/ x/ x/ 0x%x",
|
"0xae[4]/0xac[1:0]/0xdac/ScBd(B->W)",
|
((chip_para->scbd_bit_num == BTC_SCBD_16_BIT) ?
|
btc->btc_read_scbd(btc, &scbd) :
|
btc->btc_read_scbd_32bit(btc, &scbd_32)));
|
}
|
CL_PRINTF(cli_buf);
|
|
/* COEX-662: LE reg 0x200[3:0] -> forbidden slot num */
|
if (coex_sta->bt_reg_le_200 == 0xffff)
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n %-35s = x",
|
"LE_FBDSLT_num");
|
else
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n %-35s = 0x%x",
|
"LE_FBDSLT_num",
|
coex_sta->bt_reg_le_200 & 0xf);
|
CL_PRINTF(cli_buf);
|
|
if (coex_dm->bt_status != BTC_BTSTATUS_NCON_IDLE) {
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n %-35s = %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x",
|
"AFH MAP", coex_sta->bt_afh_map[0],
|
coex_sta->bt_afh_map[1], coex_sta->bt_afh_map[2],
|
coex_sta->bt_afh_map[3], coex_sta->bt_afh_map[4],
|
coex_sta->bt_afh_map[5], coex_sta->bt_afh_map[6],
|
coex_sta->bt_afh_map[7], coex_sta->bt_afh_map[8],
|
coex_sta->bt_afh_map[9]);
|
CL_PRINTF(cli_buf);
|
}
|
|
for (i = 0; i < BTC_BTINFO_SRC_BT_IQK; i++) {
|
if (coex_sta->cnt_bt_info_c2h[i]) {
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x (%d)",
|
glbt_info_src[i],
|
coex_sta->bt_info_c2h[i][0],
|
coex_sta->bt_info_c2h[i][1],
|
coex_sta->bt_info_c2h[i][2],
|
coex_sta->bt_info_c2h[i][3],
|
coex_sta->bt_info_c2h[i][4],
|
coex_sta->bt_info_c2h[i][5],
|
coex_sta->bt_info_c2h[i][6],
|
coex_sta->cnt_bt_info_c2h[i]);
|
CL_PRINTF(cli_buf);
|
}
|
}
|
|
if (btc->manual_control) {
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s",
|
"============[mechanisms] (under Manual)============");
|
CL_PRINTF(cli_buf);
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n %-35s = %02x %02x %02x %02x %02x",
|
"TDMA_Now",
|
coex_dm->fw_tdma_para[0], coex_dm->fw_tdma_para[1],
|
coex_dm->fw_tdma_para[2], coex_dm->fw_tdma_para[3],
|
coex_dm->fw_tdma_para[4]);
|
CL_PRINTF(cli_buf);
|
} else {
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s",
|
"============[Mechanisms]============");
|
CL_PRINTF(cli_buf);
|
|
ps_tdma_case = coex_dm->cur_ps_tdma;
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n %-35s = %02x %02x %02x %02x %02x (case-%d, TDMA-%s, Ext-%d, Tog-%d)",
|
"TDMA",
|
coex_dm->ps_tdma_para[0], coex_dm->ps_tdma_para[1],
|
coex_dm->ps_tdma_para[2], coex_dm->ps_tdma_para[3],
|
coex_dm->ps_tdma_para[4], ps_tdma_case,
|
(coex_dm->cur_ps_tdma_on ? "On" : "Off"),
|
coex_sta->bt_ext_autoslot_thres,
|
coex_sta->wl_toggle_interval);
|
CL_PRINTF(cli_buf);
|
}
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s/ %d",
|
"Coex_Mode/Free_Run/Timer_base",
|
coex_mode_string[coex_sta->wl_coex_mode],
|
((coex_sta->coex_freerun) ? "Yes" : "No"),
|
coex_sta->tdma_timer_base);
|
|
CL_PRINTF(cli_buf);
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n %-35s = %d/ 0x%x/ 0x%x/ 0x%x",
|
"Table/0x6c0/0x6c4/0x6c8", coex_sta->coex_table_type,
|
btc->btc_read_4byte(btc, REG_BT_COEX_TABLE0),
|
btc->btc_read_4byte(btc, REG_BT_COEX_TABLE1),
|
btc->btc_read_4byte(btc, REG_BT_COEX_BRK_TABLE));
|
CL_PRINTF(cli_buf);
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ %d/ %s",
|
"0x778/0x6cc/ScBd(W->B)/RunCnt/Rsn",
|
btc->btc_read_1byte(btc, REG_BT_STAT_CTRL),
|
btc->btc_read_4byte(btc, REG_BT_COEX_TABLE_H),
|
((chip_para->scbd_bit_num == BTC_SCBD_16_BIT) ?
|
coex_sta->score_board_WB : coex_sta->score_board_WB_32bit),
|
coex_sta->cnt_wl[BTC_CNT_WL_COEXRUN],
|
run_reason_string[coex_sta->coex_run_reason]);
|
CL_PRINTF(cli_buf);
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n %-35s = %02x %02x %02x (RF-Ch = %d)", "AFH Map to BT",
|
coex_dm->wl_chnl_info[0], coex_dm->wl_chnl_info[1],
|
coex_dm->wl_chnl_info[2], coex_sta->wl_center_ch);
|
CL_PRINTF(cli_buf);
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s/ %s/ %d",
|
"AntDiv/BtCtrlLPS/LPRA/g_busy",
|
((board_info->ant_div_cfg) ? "On" : "Off"),
|
((coex_sta->wl_force_lps_ctrl) ? "On" : "Off"),
|
((coex_dm->cur_low_penalty_ra) ? "On" : "Off"),
|
coex_sta->wl_gl_busy);
|
CL_PRINTF(cli_buf);
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d/ %d",
|
"Null All/Retry/Ack/BT_Empty/BT_Late",
|
coex_sta->wl_fw_dbg_info[1], coex_sta->wl_fw_dbg_info[2],
|
coex_sta->wl_fw_dbg_info[3], coex_sta->wl_fw_dbg_info[4],
|
coex_sta->wl_fw_dbg_info[5]);
|
CL_PRINTF(cli_buf);
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %s/ %d",
|
"Cnt TDMA_Togg/LkRx/LKAP_On/fw",
|
coex_sta->wl_fw_dbg_info[6],
|
coex_sta->wl_fw_dbg_info[7],
|
((coex_sta->wl_leak_ap) ? "Yes" : "No"),
|
coex_sta->cnt_wl[BTC_CNT_WL_FW_NOTIFY]);
|
CL_PRINTF(cli_buf);
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %s/ %d",
|
"WL_TxPw/BT_TxPw/WL_Rx/BT_LNA_Lvl",
|
coex_dm->cur_wl_pwr_lvl, coex_dm->cur_bt_pwr_lvl,
|
((coex_dm->cur_wl_rx_low_gain_en) ? "On" : "Off"),
|
coex_dm->cur_bt_lna_lvl);
|
CL_PRINTF(cli_buf);
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %s",
|
"MIMO_PS On/Recover/BlackAP",
|
coex_sta->cnt_wl[BTC_CNT_WL_2G_FDDSTAY],
|
coex_sta->cnt_wl[BTC_CNT_WL_2G_TDDTRY],
|
((coex_sta->wl_blacklist_ap) ? "Yes": "No"));
|
CL_PRINTF(cli_buf);
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n %-35s = %02d %02d %02d %02d %02d %02d %02d %02d %02d %02d",
|
"BT slot length1 (ms)",
|
coex_dm->bt_slot_length1[0], coex_dm->bt_slot_length1[1],
|
coex_dm->bt_slot_length1[2], coex_dm->bt_slot_length1[3],
|
coex_dm->bt_slot_length1[4], coex_dm->bt_slot_length1[5],
|
coex_dm->bt_slot_length1[6], coex_dm->bt_slot_length1[7],
|
coex_dm->bt_slot_length1[8], coex_dm->bt_slot_length1[9]);
|
CL_PRINTF(cli_buf);
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n %-35s = %02d %02d %02d %02d %02d %02d %02d %02d %02d %02d",
|
"BT slot length2 (ms)",
|
coex_dm->bt_slot_length2[0], coex_dm->bt_slot_length2[1],
|
coex_dm->bt_slot_length2[2], coex_dm->bt_slot_length2[3],
|
coex_dm->bt_slot_length2[4], coex_dm->bt_slot_length2[5],
|
coex_dm->bt_slot_length2[6], coex_dm->bt_slot_length2[7],
|
coex_dm->bt_slot_length2[8], coex_dm->bt_slot_length2[9]);
|
CL_PRINTF(cli_buf);
|
|
for(i = 0; i < 10; i++){
|
bt_slot_sum += coex_dm->bt_slot_length1[i];
|
bt_slot_sum += coex_dm->bt_slot_length2[i];
|
}
|
|
bt_slot_min = coex_dm->bt_slot_length1[0];
|
for(i = 0; i < 10; i++){
|
if (bt_slot_min > coex_dm->bt_slot_length1[i])
|
bt_slot_min = coex_dm->bt_slot_length1[i];
|
if (bt_slot_min > coex_dm->bt_slot_length2[i])
|
bt_slot_min = coex_dm->bt_slot_length2[i];
|
}
|
|
bt_slot_max = coex_dm->bt_slot_length1[0];
|
for(i = 0; i < 10; i++){
|
if (bt_slot_max < coex_dm->bt_slot_length1[i])
|
bt_slot_max = coex_dm->bt_slot_length1[i];
|
if (bt_slot_max < coex_dm->bt_slot_length2[i])
|
bt_slot_max = coex_dm->bt_slot_length2[i];
|
}
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n %-35s = %02d %02d %02d",
|
"BT slot avg/BT slot max/BT slot min",
|
bt_slot_sum/20, bt_slot_max, bt_slot_min);
|
CL_PRINTF(cli_buf);
|
|
/* Hw setting */
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s",
|
"============[Hw setting]============");
|
CL_PRINTF(cli_buf);
|
|
btc->chip_para->chip_setup(btc, BTC_CSETUP_COEXINFO_HW);
|
|
fa_ofdm = btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_FA_OFDM);
|
fa_cck = btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_FA_CCK);
|
cca_ofdm = btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CCA_OFDM);
|
cca_cck = btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CCA_CCK);
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n %-35s = %d/ %d/ %d/ %d",
|
"CCK-CCA/CCK-FA/OFDM-CCA/OFDM-FA", cca_cck, fa_cck, cca_ofdm,
|
fa_ofdm);
|
CL_PRINTF(cli_buf);
|
|
ok_11b =
|
btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_OK_CCK);
|
ok_11g =
|
btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_OK_LEGACY);
|
ok_11n =
|
btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_OK_HT);
|
ok_11vht =
|
btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_OK_VHT);
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d",
|
"CRC_OK CCK/11g/11n/11ac", ok_11b, ok_11g, ok_11n, ok_11vht);
|
CL_PRINTF(cli_buf);
|
|
err_11b =
|
btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_ERROR_CCK);
|
err_11g =
|
btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_ERROR_LEGACY);
|
err_11n =
|
btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_ERROR_HT);
|
err_11vht =
|
btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_ERROR_VHT);
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d",
|
"CRC_Err CCK/11g/11n/11ac",
|
err_11b, err_11g, err_11n, err_11vht);
|
CL_PRINTF(cli_buf);
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
|
"\r\n %-35s = %d/ %d/ %s-%d/ %d (Tx macid: %d)",
|
"Rate RxD/RxRTS/TxD/TxRetry_ratio",
|
coex_sta->wl_rx_rate, coex_sta->wl_rts_rx_rate,
|
(coex_sta->wl_tx_rate & 0x80 ? "SGI" : "LGI"),
|
coex_sta->wl_tx_rate & 0x7f,
|
coex_sta->wl_tx_retry_ratio,
|
coex_sta->wl_tx_macid);
|
CL_PRINTF(cli_buf);
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s/ %s/ %d",
|
"HiPr/ Locking/ Locked/ Noisy",
|
(coex_sta->wl_hi_pri_task1 ? "Yes" : "No"),
|
(coex_sta->wl_cck_lock ? "Yes" : "No"),
|
(coex_sta->wl_cck_lock_ever ? "Yes" : "No"),
|
coex_sta->wl_noisy_level);
|
CL_PRINTF(cli_buf);
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d",
|
"0x770(Hi-pri rx/tx)", coex_sta->hi_pri_rx,
|
coex_sta->hi_pri_tx);
|
CL_PRINTF(cli_buf);
|
|
CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d %s",
|
"0x774(Lo-pri rx/tx)", coex_sta->lo_pri_rx,
|
coex_sta->lo_pri_tx, (coex_sta->bt_slave ?
|
"(Slave!!)" : ""));
|
CL_PRINTF(cli_buf);
|
|
btc->btc_disp_dbg_msg(btc, BTC_DBG_DISP_COEX_STATISTICS);
|
|
coex_sta->cnt_wl[BTC_CNT_WL_COEXINFO1]++;
|
|
if (coex_sta->cnt_wl[BTC_CNT_WL_COEXINFO1] % 5 == 0)
|
coex_sta->cnt_bt[BTC_CNT_BT_POPEVENT] = 0;
|
}
|
|
void rtw_btc_ex_ips_notify(struct btc_coexist *btc, u8 type)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
|
if (btc->manual_control || btc->stop_coex_dm)
|
return;
|
|
if (type == BTC_IPS_ENTER) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], IPS ENTER notify\n");
|
BTC_TRACE(trace_buf);
|
coex_sta->wl_under_ips = TRUE;
|
|
/* Write WL "Active" in Score-board for LPS off */
|
if (chip_para->scbd_bit_num == BTC_SCBD_16_BIT)
|
btc->btc_write_scbd(btc, BTC_SCBD_ALL, FALSE);
|
else
|
btc->btc_write_scbd_32bit(btc, BTC_SCBD_ALL_32BIT, FALSE);
|
btc->chip_para->chip_setup(btc, BTC_CSETUP_WLAN_ACT_IPS);
|
rtw_btc_set_ant_path(btc, FC_EXCU, BTC_ANT_WOFF);
|
rtw_btc_action_coex_all_off(btc);
|
} else if (type == BTC_IPS_LEAVE) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], IPS LEAVE notify\n");
|
BTC_TRACE(trace_buf);
|
if (chip_para->scbd_bit_num == BTC_SCBD_16_BIT)
|
btc->btc_write_scbd(btc, BTC_SCBD_ACTIVE | BTC_SCBD_ON, TRUE);
|
else
|
btc->btc_write_scbd_32bit(btc, BTC_SCBD_ACTIVE | BTC_SCBD_ON, TRUE);
|
/*leave IPS : run ini hw config (exclude wifi only)*/
|
rtw_btc_init_hw_config(btc, FALSE);
|
|
coex_sta->wl_under_ips = FALSE;
|
}
|
}
|
|
void rtw_btc_ex_lps_notify(struct btc_coexist *btc, u8 type)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
|
if (btc->manual_control || btc->stop_coex_dm)
|
return;
|
|
if (type == BTC_LPS_ENABLE) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], LPS ENABLE notify\n");
|
BTC_TRACE(trace_buf);
|
coex_sta->wl_under_lps = TRUE;
|
|
if (coex_sta->wl_force_lps_ctrl) { /* LPS No-32K */
|
/* Write WL "Active" in Score-board for PS-TDMA */
|
if (chip_para->scbd_bit_num == BTC_SCBD_16_BIT)
|
btc->btc_write_scbd(btc, BTC_SCBD_ACTIVE, TRUE);
|
else
|
btc->btc_write_scbd_32bit(btc, BTC_SCBD_ACTIVE, TRUE);
|
} else {
|
/* Write WL "Non-Active" in Score-board for Native-PS */
|
if (chip_para->scbd_bit_num == BTC_SCBD_16_BIT) {
|
btc->btc_write_scbd(btc, BTC_SCBD_ACTIVE, FALSE);
|
btc->btc_write_scbd(btc, BTC_SCBD_WLBUSY, FALSE);
|
} else {
|
btc->btc_write_scbd_32bit(btc, BTC_SCBD_ACTIVE, FALSE);
|
btc->btc_write_scbd_32bit(btc, BTC_SCBD_WLBUSY, FALSE);
|
}
|
|
rtw_btc_run_coex(btc, BTC_RSN_LPS);
|
}
|
} else if (type == BTC_LPS_DISABLE) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], LPS DISABLE notify\n");
|
BTC_TRACE(trace_buf);
|
coex_sta->wl_under_lps = FALSE;
|
|
/* Write WL "Active" in Score-board for LPS off */
|
if (chip_para->scbd_bit_num == BTC_SCBD_16_BIT)
|
btc->btc_write_scbd(btc, BTC_SCBD_ACTIVE, TRUE);
|
else
|
btc->btc_write_scbd_32bit(btc, BTC_SCBD_ACTIVE, TRUE);
|
|
if (!coex_sta->wl_force_lps_ctrl)
|
rtw_btc_query_bt_info(btc);
|
|
rtw_btc_run_coex(btc, BTC_RSN_LPS);
|
} else if (type == BTC_LPS_PRE) {
|
/* COEX-649, prevent LeisurePSLeave() is called in LeisurePSEnter()*/
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], LPS PRE notify(before enter LPS)\n");
|
BTC_TRACE(trace_buf);
|
|
coex_sta->wl_in_lps_enter = TRUE;
|
} else if (type == BTC_LPS_RET) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], LPS RET notify(LPS enter end)\n");
|
BTC_TRACE(trace_buf);
|
|
coex_sta->wl_in_lps_enter = FALSE;
|
rtw_btc_run_coex(btc, BTC_RSN_LPS);
|
} else {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], LPS unknown notify!!\n");
|
BTC_TRACE(trace_buf);
|
}
|
}
|
|
void rtw_btc_ex_scan_notify(struct btc_coexist *btc, u8 type)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
|
if (btc->manual_control || btc->stop_coex_dm)
|
return;
|
|
coex_sta->coex_freeze = FALSE;
|
|
if (chip_para->scbd_bit_num == BTC_SCBD_16_BIT)
|
btc->btc_write_scbd(btc, BTC_SCBD_ACTIVE | BTC_SCBD_ON, TRUE);
|
else
|
btc->btc_write_scbd_32bit(btc, BTC_SCBD_ACTIVE | BTC_SCBD_ON, TRUE);
|
|
if (type == BTC_SCAN_START_5G) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], SCAN START notify (5G)\n");
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_set_ant_path(btc, FC_EXCU, BTC_ANT_5G);
|
rtw_btc_run_coex(btc, BTC_RSN_5GSCANSTART);
|
} else if (type == BTC_SCAN_START_2G || type == BTC_SCAN_START) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], SCAN START notify (2G)\n");
|
BTC_TRACE(trace_buf);
|
|
coex_sta->wl_hi_pri_task2 = TRUE;
|
|
/* Force antenna setup for no scan result issue */
|
rtw_btc_set_ant_path(btc, FC_EXCU, BTC_ANT_2G);
|
rtw_btc_run_coex(btc, BTC_RSN_2GSCANSTART);
|
} else {
|
btc->btc_get(btc, BTC_GET_U1_AP_NUM,
|
&coex_sta->cnt_wl[BTC_CNT_WL_SCANAP]);
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], SCAN FINISH notify (Scan-AP = %d)\n",
|
coex_sta->cnt_wl[BTC_CNT_WL_SCANAP]);
|
BTC_TRACE(trace_buf);
|
|
coex_sta->wl_hi_pri_task2 = FALSE;
|
|
rtw_btc_run_coex(btc, BTC_RSN_SCANFINISH);
|
}
|
}
|
|
void rtw_btc_ex_scan_notify_without_bt(struct btc_coexist *btc, u8 type)
|
{
|
struct btc_wifi_link_info_ext *link_info_ext = &btc->wifi_link_info_ext;
|
struct btc_rfe_type *rfe_type = &btc->rfe_type;
|
u8 ctrl_type = BTC_SWITCH_CTRL_BY_BBSW, pos_type = BTC_SWITCH_TO_WLG;
|
|
if (!rfe_type->ant_switch_exist)
|
return;
|
|
if (type == BTC_SCAN_START && link_info_ext->is_all_under_5g)
|
pos_type = BTC_SWITCH_TO_WLA;
|
|
rtw_btc_set_ant_switch(btc, FC_EXCU, ctrl_type, pos_type);
|
}
|
|
void rtw_btc_ex_switchband_notify(struct btc_coexist *btc, u8 type)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
|
if (btc->manual_control || btc->stop_coex_dm)
|
return;
|
|
if (type == BTC_SWITCH_TO_5G) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): TO_5G\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_run_coex(btc, BTC_RSN_5GSWITCHBAND);
|
} else if (type == BTC_SWITCH_TO_24G_NOFORSCAN) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): TO_24G_NOFORSCAN\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_run_coex(btc, BTC_RSN_2GSWITCHBAND);
|
} else {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): TO_2G\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_ex_scan_notify(btc, BTC_SCAN_START_2G);
|
}
|
}
|
|
void rtw_btc_ex_switchband_notify_without_bt(struct btc_coexist *btc, u8 type)
|
{
|
struct btc_rfe_type *rfe_type = &btc->rfe_type;
|
u8 ctrl_type = BTC_SWITCH_CTRL_BY_BBSW, pos_type = BTC_SWITCH_TO_WLG;
|
|
if (!rfe_type->ant_switch_exist)
|
return;
|
|
if (type == BTC_SWITCH_TO_5G) {
|
pos_type = BTC_SWITCH_TO_WLA;
|
} else if (type == BTC_SWITCH_TO_24G_NOFORSCAN) {
|
pos_type = BTC_SWITCH_TO_WLG;
|
} else {
|
rtw_btc_ex_scan_notify_without_bt(btc, BTC_SCAN_START_2G);
|
return;
|
}
|
|
rtw_btc_set_ant_switch(btc, FC_EXCU, ctrl_type, pos_type);
|
}
|
|
void rtw_btc_ex_connect_notify(struct btc_coexist *btc, u8 type)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
|
if (btc->manual_control || btc->stop_coex_dm)
|
return;
|
|
if (chip_para->scbd_bit_num == BTC_SCBD_16_BIT)
|
btc->btc_write_scbd(btc, BTC_SCBD_ACTIVE | BTC_SCBD_ON, TRUE);
|
else
|
btc->btc_write_scbd_32bit(btc, BTC_SCBD_ACTIVE | BTC_SCBD_ON, TRUE);
|
|
if (type == BTC_ASSOCIATE_5G_START) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): 5G start\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_set_ant_path(btc, FC_EXCU, BTC_ANT_5G);
|
|
rtw_btc_run_coex(btc, BTC_RSN_5GCONSTART);
|
} else if (type == BTC_ASSOCIATE_5G_FINISH) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): 5G finish\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_set_ant_path(btc, FC_EXCU, BTC_ANT_5G);
|
|
rtw_btc_run_coex(btc, BTC_RSN_5GCONFINISH);
|
} else if (type == BTC_ASSOCIATE_START) {
|
coex_sta->wl_hi_pri_task1 = TRUE;
|
coex_sta->cnt_wl[BTC_CNT_WL_ARP] = 0;
|
coex_sta->wl_connecting = TRUE;
|
btc->btc_set_timer(btc, BTC_TIMER_WL_CONNPKT, 2);
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): 2G start\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
/* Force antenna setup for no scan result issue */
|
rtw_btc_set_ant_path(btc, FC_EXCU, BTC_ANT_2G);
|
|
rtw_btc_run_coex(btc, BTC_RSN_2GCONSTART);
|
|
/* To keep TDMA case during connect process,
|
* to avoid changed by Btinfo and run_coex
|
*/
|
coex_sta->coex_freeze = TRUE;
|
btc->btc_set_timer(btc, BTC_TIMER_WL_COEXFREEZE, 5);
|
} else {
|
coex_sta->wl_hi_pri_task1 = FALSE;
|
coex_sta->coex_freeze = FALSE;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): 2G finish\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_run_coex(btc, BTC_RSN_2GCONFINISH);
|
}
|
}
|
|
void rtw_btc_ex_media_status_notify(struct btc_coexist *btc, u8 type)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
boolean wl_b_mode = FALSE;
|
u8 i;
|
|
if (btc->manual_control || btc->stop_coex_dm)
|
return;
|
|
coex_sta->coex_freeze = FALSE;
|
|
btc->btc_get(btc, BTC_GET_BL_WIFI_BSSID, btc->wifi_bssid);
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): BSSID = %02x %02X %02X %02x %02X %02X\n",
|
__func__, btc->wifi_bssid[0],
|
btc->wifi_bssid[1], btc->wifi_bssid[2],
|
btc->wifi_bssid[3], btc->wifi_bssid[4],
|
btc->wifi_bssid[5]);
|
BTC_TRACE(trace_buf);
|
|
/* check if black-list ap */
|
for (i = 0; i <= 5; i++) {
|
if (btc->wifi_bssid[i] != btc->wifi_black_bssid[i])
|
break;
|
}
|
|
if (i <= 5)
|
coex_sta->wl_blacklist_ap = FALSE;
|
else
|
coex_sta->wl_blacklist_ap = TRUE;
|
|
if (type == BTC_MEDIA_CONNECT_5G) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): 5G\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
if (chip_para->scbd_bit_num == BTC_SCBD_16_BIT)
|
btc->btc_write_scbd(btc, BTC_SCBD_ACTIVE, TRUE);
|
else
|
btc->btc_write_scbd_32bit(btc, BTC_SCBD_ACTIVE, TRUE);
|
rtw_btc_set_ant_path(btc, FC_EXCU, BTC_ANT_5G);
|
|
rtw_btc_run_coex(btc, BTC_RSN_5GMEDIA);
|
} else if (type == BTC_MEDIA_CONNECT) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): 2G\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
if (chip_para->scbd_bit_num == BTC_SCBD_16_BIT)
|
btc->btc_write_scbd(btc, BTC_SCBD_ACTIVE, TRUE);
|
else
|
btc->btc_write_scbd_32bit(btc, BTC_SCBD_ACTIVE, TRUE);
|
|
/* Force antenna setup for no scan result issue */
|
rtw_btc_set_ant_path(btc, FC_EXCU, BTC_ANT_2G);
|
|
btc->btc_get(btc, BTC_GET_BL_WIFI_UNDER_B_MODE, &wl_b_mode);
|
|
/* Set CCK Tx/Rx high Pri except 11b mode */
|
if (wl_b_mode)/* CCK Rx */
|
rtw_btc_set_wl_pri_mask(btc, BTC_WLPRI_RX_CCK, 0);
|
else /* CCK Rx */
|
rtw_btc_set_wl_pri_mask(btc, BTC_WLPRI_RX_CCK, 1);
|
|
rtw_btc_run_coex(btc, BTC_RSN_2GMEDIA);
|
} else {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): disconnect!!\n", __func__);
|
BTC_TRACE(trace_buf);
|
coex_sta->cnt_wl[BTC_CNT_WL_ARP] = 0;
|
|
rtw_btc_run_coex(btc, BTC_RSN_MEDIADISCON);
|
}
|
|
btc->btc_get(btc, BTC_GET_U1_IOT_PEER, &coex_sta->wl_iot_peer);
|
rtw_btc_update_wl_ch_info(btc, type);
|
}
|
|
void rtw_btc_ex_specific_packet_notify(struct btc_coexist *btc, u8 type)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
boolean under_4way = FALSE;
|
|
if (btc->manual_control || btc->stop_coex_dm)
|
return;
|
|
if (type & BTC_5G_BAND) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): 5G\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_run_coex(btc, BTC_RSN_5GSPECIALPKT);
|
return;
|
}
|
|
btc->btc_get(btc, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &under_4way);
|
|
if (under_4way) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): under_4way!!\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
coex_sta->wl_hi_pri_task1 = TRUE;
|
btc->btc_set_timer(btc, BTC_TIMER_WL_SPECPKT, 2);
|
} else if (type == BTC_PACKET_ARP) {
|
coex_sta->cnt_wl[BTC_CNT_WL_ARP]++;
|
|
if (coex_sta->wl_hi_pri_task1) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): ARP cnt = %d\n",
|
__func__, coex_sta->cnt_wl[BTC_CNT_WL_ARP]);
|
BTC_TRACE(trace_buf);
|
}
|
} else {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): DHCP or EAPOL Type = %d\n",
|
__func__, type);
|
BTC_TRACE(trace_buf);
|
|
coex_sta->wl_hi_pri_task1 = TRUE;
|
btc->btc_set_timer(btc, BTC_TIMER_WL_SPECPKT, 2);
|
}
|
|
if (coex_sta->wl_hi_pri_task1)
|
rtw_btc_run_coex(btc, BTC_RSN_2GSPECIALPKT);
|
}
|
|
void rtw_btc_ex_bt_info_notify(struct btc_coexist *btc, u8 *tmp_buf, u8 length)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_coex_dm *coex_dm = &btc->coex_dm;
|
struct btc_wifi_link_info_ext *link_info_ext = &btc->wifi_link_info_ext;
|
u8 i, rsp_source = 0, type;
|
|
rsp_source = tmp_buf[0] & 0xf;
|
if (rsp_source >= BTC_BTINFO_SRC_MAX)
|
return;
|
|
/* COEX-649, prevent TDMA parametet change in LeisurePSEnter()*/
|
if (coex_sta->wl_in_lps_enter) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): wl_in_LPSenter = %d\n",
|
__func__, coex_sta->wl_in_lps_enter);
|
BTC_TRACE(trace_buf);
|
}
|
|
coex_sta->cnt_bt_info_c2h[rsp_source]++;
|
|
/* bt_iqk_state-> 1: start, 0: ok, 2:fail */
|
if (rsp_source == BTC_BTINFO_SRC_BT_IQK) {
|
coex_sta->bt_iqk_state = tmp_buf[1];
|
if (coex_sta->bt_iqk_state == 0x0)
|
coex_sta->cnt_bt[BTC_CNT_BT_IQK]++;
|
else if (coex_sta->bt_iqk_state == 0x2)
|
coex_sta->cnt_bt[BTC_CNT_BT_IQKFAIL]++;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], BT IQK by bt_info, data0 = 0x%02x\n",
|
tmp_buf[1]);
|
BTC_TRACE(trace_buf);
|
return;
|
}
|
|
if (rsp_source == BTC_BTINFO_SRC_BT_SCBD) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], BT Scoreboard change notify by WL FW c2h, 0xaa = 0x%02x, 0xab = 0x%02x\n",
|
tmp_buf[1], tmp_buf[2]);
|
BTC_TRACE(trace_buf);
|
rtw_btc_monitor_bt_enable(btc);
|
|
if (coex_sta->bt_disabled != coex_sta->bt_disabled_pre) {
|
coex_sta->bt_disabled_pre = coex_sta->bt_disabled;
|
rtw_btc_run_coex(btc, BTC_RSN_BTINFO);
|
}
|
return;
|
}
|
|
if (rsp_source == BTC_BTINFO_SRC_H2C60) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], H2C 0x60 content replied by WL FW: H2C_0x60 = [%02x %02x %02x %02x %02x]\n",
|
tmp_buf[1], tmp_buf[2], tmp_buf[3], tmp_buf[4],
|
tmp_buf[5]);
|
BTC_TRACE(trace_buf);
|
|
for (i = 1; i <= 5; i++)
|
coex_dm->fw_tdma_para[i - 1] = tmp_buf[i];
|
return;
|
}
|
|
if (rsp_source == BTC_BTINFO_SRC_WL_FW) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], bt_info reply by WL FW\n");
|
BTC_TRACE(trace_buf);
|
rtw_btc_update_bt_link_info(btc);
|
/* rtw_btc_run_coex(btc, BTC_RSN_BTINFO); */
|
return;
|
}
|
|
if (rsp_source == BTC_BTINFO_SRC_BT_RSP ||
|
rsp_source == BTC_BTINFO_SRC_BT_ACT) {
|
if (coex_sta->bt_disabled) {
|
coex_sta->bt_disabled = FALSE;
|
coex_sta->bt_reenable = TRUE;
|
btc->btc_set_timer(btc, BTC_TIMER_BT_REENABLE, 15);
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], BT enable detected by bt_info\n");
|
BTC_TRACE(trace_buf);
|
}
|
}
|
|
if (rsp_source == BTC_BTINFO_SRC_BT_SLOT1) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], BT slot length = [%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x]\n",
|
tmp_buf[1], tmp_buf[2], tmp_buf[3], tmp_buf[4],
|
tmp_buf[5], tmp_buf[6], tmp_buf[7], tmp_buf[8],
|
tmp_buf[9], tmp_buf[10]);
|
BTC_TRACE(trace_buf);
|
|
for (i = 1; i <= 10; i++)
|
coex_dm->bt_slot_length1[i - 1] = tmp_buf[i];
|
return;
|
}
|
|
if (rsp_source == BTC_BTINFO_SRC_BT_SLOT2) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], BT slot length = [%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x]\n",
|
tmp_buf[1], tmp_buf[2], tmp_buf[3], tmp_buf[4],
|
tmp_buf[5], tmp_buf[6], tmp_buf[7], tmp_buf[8],
|
tmp_buf[9], tmp_buf[10]);
|
BTC_TRACE(trace_buf);
|
|
for (i = 1; i <= 10; i++)
|
coex_dm->bt_slot_length2[i - 1] = tmp_buf[i];
|
return;
|
}
|
|
if (length != 7) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], Bt_info length = %d invalid!!\n",
|
length);
|
BTC_TRACE(trace_buf);
|
return;
|
}
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], Bt_info[%d], len=%d, data=[%02x %02x %02x %02x %02x %02x]\n",
|
tmp_buf[0], length, tmp_buf[1], tmp_buf[2], tmp_buf[3],
|
tmp_buf[4], tmp_buf[5], tmp_buf[6]);
|
BTC_TRACE(trace_buf);
|
|
for (i = 0; i < 7; i++)
|
coex_sta->bt_info_c2h[rsp_source][i] = tmp_buf[i];
|
|
if (coex_sta->bt_info_c2h[rsp_source][1] == coex_sta->bt_info_lb2 &&
|
coex_sta->bt_info_c2h[rsp_source][2] == coex_sta->bt_info_lb3 &&
|
coex_sta->bt_info_c2h[rsp_source][3] == coex_sta->bt_info_hb0 &&
|
coex_sta->bt_info_c2h[rsp_source][4] == coex_sta->bt_info_hb1 &&
|
coex_sta->bt_info_c2h[rsp_source][5] == coex_sta->bt_info_hb2 &&
|
coex_sta->bt_info_c2h[rsp_source][6] == coex_sta->bt_info_hb3) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], Return because Btinfo duplicate!!\n");
|
BTC_TRACE(trace_buf);
|
return;
|
}
|
|
coex_sta->bt_info_lb2 = coex_sta->bt_info_c2h[rsp_source][1];
|
coex_sta->bt_info_lb3 = coex_sta->bt_info_c2h[rsp_source][2];
|
coex_sta->bt_info_hb0 = coex_sta->bt_info_c2h[rsp_source][3];
|
coex_sta->bt_info_hb1 = coex_sta->bt_info_c2h[rsp_source][4];
|
coex_sta->bt_info_hb2 = coex_sta->bt_info_c2h[rsp_source][5];
|
coex_sta->bt_info_hb3 = coex_sta->bt_info_c2h[rsp_source][6];
|
|
/* ========== BT info Low-Byte2 ========== */
|
/* if 0xff, it means BT is under WHCK test */
|
coex_sta->bt_whck_test = (coex_sta->bt_info_lb2 == 0xff);
|
coex_sta->bt_inq_page = ((coex_sta->bt_info_lb2 & BIT(2)) == BIT(2));
|
|
if (coex_sta->bt_inq_page_pre != coex_sta->bt_inq_page) {
|
coex_sta->bt_inq_page_pre = coex_sta->bt_inq_page;
|
coex_sta->bt_inq_page_remain = TRUE;
|
|
if (!coex_sta->bt_inq_page)
|
btc->btc_set_timer(btc, BTC_TIMER_BT_INQPAGE, 2);
|
}
|
coex_sta->bt_acl_busy = ((coex_sta->bt_info_lb2 & BIT(3)) == BIT(3));
|
|
if (coex_sta->bt_info_lb2 & BIT(5)) {
|
if ((coex_sta->bt_info_hb1 & BIT(0)) == BIT(0)) {
|
/*BLE HID*/
|
coex_sta->bt_ble_hid_exist = TRUE;
|
coex_sta->bt_ble_exist = FALSE;
|
}
|
} else if ((coex_sta->bt_info_hb1 & BIT(0)) == BIT(0)) {
|
/*RCU*/
|
coex_sta->bt_ble_exist = TRUE;
|
} else {
|
coex_sta->bt_ble_hid_exist = FALSE;
|
coex_sta->bt_ble_exist = FALSE;
|
}
|
|
/* ========== BT info Low-Byte3 ========== */
|
coex_sta->cnt_bt[BTC_CNT_BT_RETRY] = coex_sta->bt_info_lb3 & 0xf;
|
|
if (coex_sta->cnt_bt[BTC_CNT_BT_RETRY] >= 1)
|
coex_sta->cnt_bt[BTC_CNT_BT_POPEVENT]++;
|
|
coex_sta->bt_fix_2M = ((coex_sta->bt_info_lb3 & BIT(4)) == BIT(4));
|
|
coex_sta->bt_inq = ((coex_sta->bt_info_lb3 & BIT(5)) == BIT(5));
|
|
coex_sta->bt_mesh = ((coex_sta->bt_info_lb3 & BIT(6)) == BIT(6));
|
|
if (coex_sta->bt_inq)
|
coex_sta->cnt_bt[BTC_CNT_BT_INQ]++;
|
|
coex_sta->bt_page = ((coex_sta->bt_info_lb3 & BIT(7)) == BIT(7));
|
|
if (coex_sta->bt_page)
|
coex_sta->cnt_bt[BTC_CNT_BT_PAGE]++;
|
|
/* ========== BT info High-Byte0 ========== */
|
/* unit: %, value-100 to translate to unit: dBm */
|
if (btc->chip_para->bt_rssi_type == BTC_BTRSSI_RATIO) {
|
coex_sta->bt_rssi = coex_sta->bt_info_hb0 * 2 + 10;
|
} else { /* coex_sta->bt_info_hb0 is just dbm */
|
if (coex_sta->bt_info_hb0 <= 127)
|
coex_sta->bt_rssi = 100;
|
else if (256 - coex_sta->bt_info_hb0 <= 100)
|
coex_sta->bt_rssi = 100 - (256 - coex_sta->bt_info_hb0);
|
else
|
coex_sta->bt_rssi = 0;
|
}
|
|
/* ========== BT info High-Byte1 ========== */
|
if (coex_sta->bt_info_hb1 & BIT(1))
|
coex_sta->cnt_bt[BTC_CNT_BT_REINIT]++;
|
|
if ((coex_sta->bt_info_hb1 & BIT(2)) ||
|
(coex_sta->bt_page && coex_sta->wl_pnp_wakeup)) {
|
coex_sta->cnt_bt[BTC_CNT_BT_SETUPLINK]++;
|
coex_sta->bt_setup_link = TRUE;
|
|
if (coex_sta->bt_reenable)
|
btc->btc_set_timer(btc, BTC_TIMER_BT_RELINK, 6);
|
else
|
btc->btc_set_timer(btc, BTC_TIMER_BT_RELINK, 1);
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], Re-Link start in BT info!!\n");
|
BTC_TRACE(trace_buf);
|
}
|
|
if (coex_sta->bt_info_hb1 & BIT(3))
|
coex_sta->cnt_bt[BTC_CNT_BT_IGNWLANACT]++;
|
|
coex_sta->bt_ble_voice = ((coex_sta->bt_info_hb1 & BIT(4)) == BIT(4));
|
coex_sta->bt_ble_scan_en = ((coex_sta->bt_info_hb1 & BIT(5)) == BIT(5));
|
|
if (coex_sta->bt_info_hb1 & BIT(6))
|
coex_sta->cnt_bt[BTC_CNT_BT_ROLESWITCH]++;
|
|
coex_sta->bt_multi_link = ((coex_sta->bt_info_hb1 & BIT(7)) == BIT(7));
|
|
/* for multi_link = 0 but bt pkt remain exist ->
|
* Use PS-TDMA to protect WL RX
|
*/
|
if (!coex_sta->bt_multi_link && coex_sta->bt_multi_link_pre) {
|
coex_sta->bt_multi_link_remain = TRUE;
|
btc->btc_set_timer(btc, BTC_TIMER_BT_MULTILINK, 3);
|
}
|
|
coex_sta->bt_multi_link_pre = coex_sta->bt_multi_link;
|
|
/* Here we need to resend some wifi info to BT */
|
/* because bt is reset and loss of the info. */
|
/* Re-Init */
|
if ((coex_sta->bt_info_hb1 & BIT(1))) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], BT Re-init, send wifi BW & Chnl to BT!!\n");
|
BTC_TRACE(trace_buf);
|
if (link_info_ext->is_connected)
|
type = BTC_MEDIA_CONNECT;
|
else
|
type = BTC_MEDIA_DISCONNECT;
|
rtw_btc_update_wl_ch_info(btc, type);
|
}
|
|
/* If Ignore_WLanAct && not SetUp_Link */
|
if ((coex_sta->bt_info_hb1 & BIT(3)) &&
|
(!(coex_sta->bt_info_hb1 & BIT(2)))) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n");
|
BTC_TRACE(trace_buf);
|
rtw_btc_ignore_wlan_act(btc, FC_EXCU, FALSE);
|
}
|
|
/* ========== BT info High-Byte2 ========== */
|
coex_sta->bt_opp_exist = ((coex_sta->bt_info_hb2 & BIT(0)) == BIT(0));
|
|
if (coex_sta->bt_info_hb2 & BIT(1))
|
coex_sta->cnt_bt[BTC_CNT_BT_AFHUPDATE]++;
|
|
coex_sta->bt_a2dp_active = ((coex_sta->bt_info_hb2 & BIT(2)) == BIT(2));
|
|
/*for a2dp_active = 0 but bt pkt remain exist ->
|
* Use PS-TDMA to protect WL RX*/
|
if (!coex_sta->bt_a2dp_active && coex_sta->bt_a2dp_active_pre) {
|
coex_sta->bt_a2dp_active_remain = TRUE;
|
btc->btc_set_timer(btc, BTC_TIMER_BT_A2DP_ACT, 5);
|
}
|
|
coex_sta->bt_a2dp_active_pre = coex_sta->bt_a2dp_active;
|
|
coex_sta->bt_slave = ((coex_sta->bt_info_hb2 & BIT(3)) == BIT(3));
|
coex_sta->bt_hid_slot = (coex_sta->bt_info_hb2 & 0x30) >> 4;
|
coex_sta->bt_hid_pair_num = (coex_sta->bt_info_hb2 & 0xc0) >> 6;
|
|
if (coex_sta->bt_hid_pair_num > 0 && coex_sta->bt_hid_slot >= 2) {
|
coex_sta->bt_418_hid_exist = TRUE;
|
} else if (coex_sta->bt_hid_pair_num == 0 ||
|
coex_sta->bt_hid_slot == 1) {
|
coex_sta->bt_418_hid_exist = FALSE;
|
}
|
|
/* ========== BT info High-Byte3 ========== */
|
if ((coex_sta->bt_info_lb2 & 0x49) == 0x49)
|
coex_sta->bt_a2dp_bitpool = (coex_sta->bt_info_hb3 & 0x7f);
|
else
|
coex_sta->bt_a2dp_bitpool = 0;
|
|
coex_sta->bt_a2dp_sink = ((coex_sta->bt_info_hb3 & BIT(7)) == BIT(7));
|
|
rtw_btc_update_bt_link_info(btc);
|
|
if (!coex_sta->wl_in_lps_enter)
|
rtw_btc_run_coex(btc, BTC_RSN_BTINFO);
|
}
|
|
void rtw_btc_ex_wl_fwdbginfo_notify(struct btc_coexist *btc, u8 *tmp_buf,
|
u8 length)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
u8 i = 0, val = 0;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], WiFi Fw Dbg info = %d %d %d %d %d %d %d %d (len = %d)\n",
|
tmp_buf[0], tmp_buf[1], tmp_buf[2], tmp_buf[3], tmp_buf[4],
|
tmp_buf[5], tmp_buf[6], tmp_buf[7], length);
|
BTC_TRACE(trace_buf);
|
|
if (tmp_buf[0] != 0x8)
|
return;
|
|
for (i = 1; i <= 7; i++) {
|
val = coex_sta->wl_fw_dbg_info_pre[i];
|
if (tmp_buf[i] >= val)
|
coex_sta->wl_fw_dbg_info[i] = tmp_buf[i] - val;
|
else
|
coex_sta->wl_fw_dbg_info[i] = 255 - val + tmp_buf[i];
|
|
coex_sta->wl_fw_dbg_info_pre[i] = tmp_buf[i];
|
}
|
|
/* wl_fwdbginfo_notify is auto send by WL FW if TDMA slot toggle = 20
|
* coex_sta->wl_fw_dbg_info[6] = TDMA slot toggle
|
* For debug, TDMA slot toggle should be calculated by 2-second
|
*/
|
coex_sta->cnt_wl[BTC_CNT_WL_FW_NOTIFY]++;
|
rtw_btc_wl_ccklock_action(btc);
|
}
|
|
void rtw_btc_ex_rx_rate_change_notify(struct btc_coexist *btc,
|
BOOLEAN is_data_frame, u8 btc_rate_id)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
|
if (is_data_frame)
|
coex_sta->wl_rx_rate = btc_rate_id;
|
|
else
|
coex_sta->wl_rts_rx_rate = btc_rate_id;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): rate id = %d, RTS_Rate = %d\n", __func__,
|
coex_sta->wl_rx_rate, coex_sta->wl_rts_rx_rate);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_wl_ccklock_detect(btc);
|
}
|
|
void rtw_btc_ex_tx_rate_change_notify(struct btc_coexist *btc, u8 tx_rate,
|
u8 tx_retry_ratio, u8 macid)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): Tx_Rate = %d, Tx_Retry_Ratio = %d, macid =%d\n",
|
__func__, tx_rate, tx_retry_ratio, macid);
|
BTC_TRACE(trace_buf);
|
|
coex_sta->wl_tx_rate = tx_rate;
|
coex_sta->wl_tx_retry_ratio = tx_retry_ratio;
|
coex_sta->wl_tx_macid = macid;
|
}
|
|
void rtw_btc_ex_rf_status_notify(struct btc_coexist *btc, u8 type)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
|
if (type == BTC_RF_ON) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): RF is turned ON!!\n", __func__);
|
BTC_TRACE(trace_buf);
|
btc->stop_coex_dm = FALSE;
|
btc->wl_rf_state_off = FALSE;
|
|
} else if (type == BTC_RF_OFF) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): RF is turned Off!!\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_action_wl_off(btc);
|
}
|
}
|
|
void rtw_btc_ex_halt_notify(struct btc_coexist *btc)
|
{
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_action_wl_off(btc);
|
}
|
|
void rtw_btc_ex_pnp_notify(struct btc_coexist *btc, u8 pnp_state)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
struct btc_wifi_link_info_ext *link_info_ext = &btc->wifi_link_info_ext;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
u8 phase;
|
|
if (pnp_state == BTC_WIFI_PNP_SLEEP ||
|
pnp_state == BTC_WIFI_PNP_SLEEP_KEEP_ANT) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): Sleep\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
if (chip_para->scbd_bit_num == BTC_SCBD_16_BIT)
|
btc->btc_write_scbd(btc, BTC_SCBD_ALL, FALSE);
|
else
|
btc->btc_write_scbd_32bit(btc, BTC_SCBD_ALL_32BIT, FALSE);
|
|
if (pnp_state == BTC_WIFI_PNP_SLEEP_KEEP_ANT) {
|
if (link_info_ext->is_all_under_5g)
|
phase = BTC_ANT_5G;
|
else
|
phase = BTC_ANT_2G;
|
} else {
|
phase = BTC_ANT_WOFF;
|
}
|
rtw_btc_set_ant_path(btc, FC_EXCU, phase);
|
|
btc->stop_coex_dm = TRUE;
|
} else {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): Wake up\n", __func__);
|
BTC_TRACE(trace_buf);
|
coex_sta->wl_pnp_wakeup = TRUE;
|
btc->btc_set_timer(btc, BTC_TIMER_WL_PNPWAKEUP, 3);
|
|
/*WoWLAN*/
|
if (coex_sta->wl_pnp_state_pre == BTC_WIFI_PNP_SLEEP_KEEP_ANT ||
|
pnp_state == BTC_WIFI_PNP_WOWLAN) {
|
btc->stop_coex_dm = FALSE;
|
rtw_btc_run_coex(btc, BTC_RSN_PNP);
|
}
|
}
|
|
coex_sta->wl_pnp_state_pre = pnp_state;
|
}
|
|
void rtw_btc_ex_coex_dm_reset(struct btc_coexist *btc)
|
{
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()\n", __func__);
|
BTC_TRACE(trace_buf);
|
|
rtw_btc_init_hw_config(btc, FALSE);
|
}
|
|
void rtw_btc_ex_periodical(struct btc_coexist *btc)
|
{
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], ============== Periodical ==============\n");
|
BTC_TRACE(trace_buf);
|
}
|
|
void rtw_btc_ex_timerup_notify(struct btc_coexist *btc, u32 type)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
const struct btc_chip_para *chip_para = btc->chip_para;
|
boolean is_change = FALSE;
|
|
/* COEX-649, prevent TDMA parametet change in LeisurePSEnter()*/
|
if (coex_sta->wl_in_lps_enter) {
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): wl_in_LPSenter = %d\n",
|
__func__, coex_sta->wl_in_lps_enter);
|
BTC_TRACE(trace_buf);
|
}
|
|
if (type & BIT(BTC_TIMER_WL_STAYBUSY)) {
|
if (!coex_sta->wl_busy_pre) {
|
coex_sta->wl_gl_busy = FALSE;
|
is_change = TRUE;
|
rtw_btc_update_wl_ch_info(btc, BTC_MEDIA_DISCONNECT);
|
if (chip_para->scbd_bit_num == BTC_SCBD_16_BIT)
|
btc->btc_write_scbd(btc, BTC_SCBD_WLBUSY, FALSE);
|
else
|
btc->btc_write_scbd_32bit(btc, BTC_SCBD_WLBUSY, FALSE);
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): WL busy -> idle!!\n", __func__);
|
BTC_TRACE(trace_buf);
|
}
|
}
|
|
/*avoid no connect finish notify */
|
if (type & BIT(BTC_TIMER_WL_COEXFREEZE)) {
|
coex_sta->coex_freeze = FALSE;
|
coex_sta->wl_hi_pri_task1 = FALSE;
|
is_change = TRUE;
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): Coex is de-freeze!!\n", __func__);
|
BTC_TRACE(trace_buf);
|
}
|
|
if (type & BIT(BTC_TIMER_WL_SPECPKT)) {
|
if (!coex_sta->coex_freeze) {
|
coex_sta->wl_hi_pri_task1 = FALSE;
|
is_change = TRUE;
|
}
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): WL SPECPKT finish!\n", __func__);
|
BTC_TRACE(trace_buf);
|
}
|
|
/*for A2DP glitch during connecting AP*/
|
if (type & BIT(BTC_TIMER_WL_CONNPKT)) {
|
coex_sta->wl_connecting = FALSE;
|
is_change = TRUE;
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): WL connecting stop!!\n", __func__);
|
BTC_TRACE(trace_buf);
|
}
|
|
if (type & BIT(BTC_TIMER_WL_PNPWAKEUP)) {
|
coex_sta->wl_pnp_wakeup = FALSE;
|
is_change = TRUE;
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): WL pnp wakeup stop!!\n", __func__);
|
BTC_TRACE(trace_buf);
|
}
|
|
if (type & BIT(BTC_TIMER_WL_CCKLOCK)) {
|
if (coex_sta->wl_cck_lock_pre) {
|
coex_sta->wl_cck_lock_ever = TRUE;
|
is_change = TRUE;
|
}
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): WL CCK Lock Detect!!\n", __func__);
|
BTC_TRACE(trace_buf);
|
}
|
|
if (type & BIT(BTC_TIMER_BT_RELINK)) {
|
coex_sta->bt_setup_link = FALSE;
|
is_change = TRUE;
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): Re-Link stop!!\n", __func__);
|
BTC_TRACE(trace_buf);
|
}
|
|
if (type & BIT(BTC_TIMER_BT_REENABLE)) {
|
coex_sta->bt_reenable = FALSE;
|
is_change = TRUE;
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): BT renable finish!!\n", __func__);
|
BTC_TRACE(trace_buf);
|
}
|
|
if (type & BIT(BTC_TIMER_BT_MULTILINK)) {
|
coex_sta->bt_multi_link_remain = FALSE;
|
is_change = TRUE;
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): BT multilink disappear !!\n",
|
__func__);
|
BTC_TRACE(trace_buf);
|
}
|
|
if (type & BIT(BTC_TIMER_BT_INQPAGE)) {
|
coex_sta->bt_inq_page_remain = FALSE;
|
is_change = TRUE;
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): BT inq_page disappear !!\n",
|
__func__);
|
BTC_TRACE(trace_buf);
|
}
|
|
if (type & BIT(BTC_TIMER_BT_A2DP_ACT)) {
|
coex_sta->bt_a2dp_active_remain = FALSE;
|
is_change = TRUE;
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): BT A2DP active disappear !!\n",
|
__func__);
|
BTC_TRACE(trace_buf);
|
}
|
|
if (is_change && !coex_sta->wl_in_lps_enter)
|
rtw_btc_run_coex(btc, BTC_RSN_TIMERUP);
|
}
|
|
void rtw_btc_ex_wl_status_change_notify(struct btc_coexist *btc, u32 type)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
boolean is_change = FALSE;
|
|
if (type & BIT(BTC_WLSTATUS_CHANGE_TOIDLE)) { /* if busy->idle */
|
coex_sta->wl_busy_pre = FALSE;
|
btc->btc_set_timer(btc, BTC_TIMER_WL_STAYBUSY, 6);
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): WL busy -> idle!!\n", __func__);
|
BTC_TRACE(trace_buf);
|
}
|
|
if (type & BIT(BTC_WLSTATUS_CHANGE_TOBUSY)) { /* if idle->busy */
|
coex_sta->wl_gl_busy = TRUE;
|
coex_sta->wl_busy_pre = TRUE;
|
is_change = TRUE;
|
rtw_btc_update_wl_ch_info(btc, BTC_MEDIA_CONNECT);
|
#if 0
|
btc->btc_write_scbd(btc, BTC_SCBD_WLBUSY, TRUE);
|
#endif
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): WL idle -> busy!!\n", __func__);
|
BTC_TRACE(trace_buf);
|
}
|
|
if (type & BIT(BTC_WLSTATUS_CHANGE_RSSI)) { /* if RSSI change */
|
is_change = TRUE;
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): WL RSSI change!!\n", __func__);
|
BTC_TRACE(trace_buf);
|
}
|
|
if (type & BIT(BTC_WLSTATUS_CHANGE_LINKINFO)) { /* if linkinfo change */
|
is_change = TRUE;
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): WL LinkInfo change!!\n", __func__);
|
BTC_TRACE(trace_buf);
|
}
|
|
if (type & BIT(BTC_WLSTATUS_CHANGE_DIR)) { /*if WL UL-DL change*/
|
is_change = TRUE;
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(): WL UL-DL change!!\n", __func__);
|
BTC_TRACE(trace_buf);
|
}
|
|
if (type & BIT(BTC_WLSTATUS_CHANGE_NOISY)) { /*if noisy level change*/
|
is_change = TRUE;
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s():Noisy Level change!!\n", __func__);
|
BTC_TRACE(trace_buf);
|
}
|
|
if (type & BIT(BTC_WLSTATUS_CHANGE_BTCNT)) { /*if BT counter change*/
|
is_change = TRUE;
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s():BT counter change!!\n", __func__);
|
BTC_TRACE(trace_buf);
|
}
|
|
if (type & BIT(BTC_WLSTATUS_CHANGE_LOCKTRY)) { /*if WL CCK lock try*/
|
is_change = TRUE;
|
coex_sta->wl_cck_lock_ever = FALSE;
|
coex_sta->wl_cck_lock = FALSE;
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s():WL CCK lock try!!\n", __func__);
|
BTC_TRACE(trace_buf);
|
}
|
|
if (is_change)
|
rtw_btc_run_coex(btc, BTC_RSN_WLSTATUS);
|
}
|
|
void rtw_btc_ex_wl_rfk_notify(struct btc_coexist *btc, u8 path, u8 type, u8 state)
|
{
|
struct btc_coex_sta *coex_sta = &btc->coex_sta;
|
|
BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
|
"[BTCoex], %s(), RFK path = %d, type = %d, state = %d\n",
|
__func__, path, type, state);
|
BTC_TRACE(trace_buf);
|
|
if (state == BTC_RFK_START) {
|
coex_sta->wl_rfk = TRUE;
|
} else {
|
coex_sta->wl_rfk = FALSE;
|
|
/*Run coex due to RFK end*/
|
rtw_btc_run_coex(btc, BTC_RSN_RFK);
|
}
|
}
|
#endif
|
/* #if (BT_SUPPORT == 1 && COEX_SUPPORT == 1) */
|