Commit 5b2e9a35 authored by Ching-Te Ku's avatar Ching-Te Ku Committed by Kalle Valo

rtw88: coex: add feature to enhance HID coexistence performance

Add toggle table related function to enhance WL throughput when WL coexist
with 4/18 HID.
The toggle table feature will toggle WL/BT priority table during WL slot,
it can decrease the impact from HID's frequently packets and prevent HID
lag.
Signed-off-by: default avatarChing-Te Ku <ku920601@realtek.com>
Signed-off-by: default avatarPing-Ke Shih <pkshih@realtek.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20201126021059.11981-11-pkshih@realtek.com
parent 1a74daed
......@@ -937,6 +937,69 @@ static void rtw_coex_set_gnt_wl(struct rtw_dev *rtwdev, u8 state)
rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0x0300, state);
}
static void rtw_btc_wltoggle_table_a(struct rtw_dev *rtwdev, bool force,
u8 table_case)
{
struct rtw_chip_info *chip = rtwdev->chip;
struct rtw_efuse *efuse = &rtwdev->efuse;
u8 h2c_para[6] = {0};
u32 table_wl = 0x5a5a5a5a;
h2c_para[0] = COEX_H2C69_TOGGLE_TABLE_A;
/* no definition */
h2c_para[1] = 0x1;
if (efuse->share_ant) {
if (table_case < chip->table_sant_num)
table_wl = chip->table_sant[table_case].wl;
} else {
if (table_case < chip->table_nsant_num)
table_wl = chip->table_nsant[table_case].wl;
}
/* tell WL FW WL slot toggle table-A*/
h2c_para[2] = (u8)u32_get_bits(table_wl, GENMASK(7, 0));
h2c_para[3] = (u8)u32_get_bits(table_wl, GENMASK(15, 8));
h2c_para[4] = (u8)u32_get_bits(table_wl, GENMASK(23, 16));
h2c_para[5] = (u8)u32_get_bits(table_wl, GENMASK(31, 24));
rtw_fw_bt_wifi_control(rtwdev, h2c_para[0], &h2c_para[1]);
rtw_dbg(rtwdev, RTW_DBG_COEX,
"[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]);
}
#define COEX_WL_SLOT_TOGLLE 0x5a5a5aaa
static void rtw_btc_wltoggle_table_b(struct rtw_dev *rtwdev, bool force,
u8 interval, u32 table)
{
struct rtw_coex *coex = &rtwdev->coex;
struct rtw_coex_stat *coex_stat = &coex->stat;
u8 cur_h2c_para[6] = {0};
u8 i;
cur_h2c_para[0] = COEX_H2C69_TOGGLE_TABLE_B;
cur_h2c_para[1] = interval;
cur_h2c_para[2] = (u8)u32_get_bits(table, GENMASK(7, 0));
cur_h2c_para[3] = (u8)u32_get_bits(table, GENMASK(15, 8));
cur_h2c_para[4] = (u8)u32_get_bits(table, GENMASK(23, 16));
cur_h2c_para[5] = (u8)u32_get_bits(table, GENMASK(31, 24));
coex_stat->wl_toggle_interval = interval;
for (i = 0; i <= 5; i++)
coex_stat->wl_toggle_para[i] = cur_h2c_para[i];
rtw_fw_bt_wifi_control(rtwdev, cur_h2c_para[0], &cur_h2c_para[1]);
rtw_dbg(rtwdev, RTW_DBG_COEX,
"[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]);
}
static void rtw_coex_set_table(struct rtw_dev *rtwdev, bool force, u32 table0,
u32 table1)
{
......@@ -965,6 +1028,7 @@ static void rtw_coex_table(struct rtw_dev *rtwdev, bool force, u8 type)
struct rtw_coex_dm *coex_dm = &coex->dm;
struct rtw_chip_info *chip = rtwdev->chip;
struct rtw_efuse *efuse = &rtwdev->efuse;
struct rtw_coex_stat *coex_stat = &coex->stat;
coex_dm->cur_table = type;
......@@ -982,6 +1046,8 @@ static void rtw_coex_table(struct rtw_dev *rtwdev, bool force, u8 type)
chip->table_nsant[type].bt,
chip->table_nsant[type].wl);
}
if (coex_stat->wl_slot_toggle_change)
rtw_btc_wltoggle_table_a(rtwdev, true, type);
}
static void rtw_coex_ignore_wlan_act(struct rtw_dev *rtwdev, bool enable)
......@@ -1031,6 +1097,7 @@ static void rtw_coex_set_tdma(struct rtw_dev *rtwdev, u8 byte1, u8 byte2,
struct rtw_coex *coex = &rtwdev->coex;
struct rtw_coex_dm *coex_dm = &coex->dm;
struct rtw_chip_info *chip = rtwdev->chip;
struct rtw_coex_stat *coex_stat = &coex->stat;
u8 ps_type = COEX_PS_WIFI_NATIVE;
bool ap_enable = false;
......@@ -1072,6 +1139,14 @@ static void rtw_coex_set_tdma(struct rtw_dev *rtwdev, u8 byte1, u8 byte2,
coex_dm->ps_tdma_para[4] = byte5;
rtw_fw_coex_tdma_type(rtwdev, byte1, byte2, byte3, byte4, byte5);
if (byte1 & BIT(2)) {
coex_stat->wl_slot_toggle = true;
coex_stat->wl_slot_toggle_change = false;
} else {
coex_stat->wl_slot_toggle_change = coex_stat->wl_slot_toggle;
coex_stat->wl_slot_toggle = false;
}
}
static void rtw_coex_tdma(struct rtw_dev *rtwdev, bool force, u32 tcase)
......@@ -1776,7 +1851,7 @@ static void rtw_coex_action_bt_hid(struct rtw_dev *rtwdev)
struct rtw_chip_info *chip = rtwdev->chip;
u8 table_case, tdma_case;
u32 slot_type = 0;
bool bt_multi_link_remain = false;
bool bt_multi_link_remain = false, is_toggle_table = false;
rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
......@@ -1809,6 +1884,7 @@ static void rtw_coex_action_bt_hid(struct rtw_dev *rtwdev)
tdma_case = 18;
} else if (coex_stat->bt_418_hid_exist &&
coex_stat->wl_gl_busy) {
is_toggle_table = true;
slot_type = TDMA_4SLOT;
table_case = 9;
tdma_case = 24;
......@@ -1842,6 +1918,11 @@ static void rtw_coex_action_bt_hid(struct rtw_dev *rtwdev)
}
rtw_coex_table(rtwdev, false, table_case);
if (is_toggle_table) {
rtw_btc_wltoggle_table_a(rtwdev, true, table_case);
rtw_btc_wltoggle_table_b(rtwdev, false, 1, COEX_WL_SLOT_TOGLLE);
}
rtw_coex_tdma(rtwdev, false, tdma_case | slot_type);
}
......@@ -1970,8 +2051,9 @@ static void rtw_coex_action_bt_a2dp_hid(struct rtw_dev *rtwdev)
struct rtw_coex_dm *coex_dm = &coex->dm;
struct rtw_efuse *efuse = &rtwdev->efuse;
struct rtw_chip_info *chip = rtwdev->chip;
u8 table_case, tdma_case;
u8 table_case, tdma_case, interval;
u32 slot_type = 0;
bool is_toggle_table = false;
slot_type = TDMA_4SLOT;
......@@ -1981,15 +2063,19 @@ static void rtw_coex_action_bt_a2dp_hid(struct rtw_dev *rtwdev)
if (efuse->share_ant) {
/* Shared-Ant */
if (coex_stat->bt_ble_exist)
if (coex_stat->bt_ble_exist) {
table_case = 26; /* for RCU */
else
} else if (coex_stat->bt_418_hid_exist) {
table_case = 9;
interval = 1;
} else {
table_case = 9;
}
if (coex_stat->wl_connecting || !coex_stat->wl_gl_busy) {
tdma_case = 14;
} else if (coex_stat->bt_418_hid_exist ||
coex_stat->bt_ble_hid_exist) {
} else if (coex_stat->bt_418_hid_exist) {
is_toggle_table = true;
tdma_case = 23;
} else {
tdma_case = 13;
......@@ -2008,6 +2094,10 @@ static void rtw_coex_action_bt_a2dp_hid(struct rtw_dev *rtwdev)
}
rtw_coex_table(rtwdev, false, table_case);
if (is_toggle_table) {
rtw_btc_wltoggle_table_a(rtwdev, true, table_case);
rtw_btc_wltoggle_table_b(rtwdev, false, interval, COEX_WL_SLOT_TOGLLE);
}
rtw_coex_tdma(rtwdev, false, tdma_case | slot_type);
}
......
......@@ -25,6 +25,9 @@
#define PARA1_H2C69_TBTT_TIMES GENMASK(5, 0)
#define PARA1_H2C69_TBTT_DIV100 BIT(7)
#define COEX_H2C69_TOGGLE_TABLE_A 0xd
#define COEX_H2C69_TOGGLE_TABLE_B 0x7
#define TDMA_4SLOT BIT(8)
#define TDMA_TIMER_TYPE_2SLOT 0
......
......@@ -1335,6 +1335,8 @@ struct rtw_coex_stat {
bool wl_cck_lock_pre;
bool wl_cck_lock_ever;
bool wl_connecting;
bool wl_slot_toggle;
bool wl_slot_toggle_change; /* if toggle to no-toggle */
u32 bt_supported_version;
u32 bt_supported_feature;
......@@ -1375,6 +1377,9 @@ struct rtw_coex_stat {
u8 ampdu_max_time;
u8 wl_tput_dir;
u8 wl_toggle_para[6];
u8 wl_toggle_interval;
u16 score_board;
u16 retry_limit;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment