Skip to content

Commit

Permalink
rtw88: coex: add feature to enhance HID coexistence performance
Browse files Browse the repository at this point in the history
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: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20201126021059.11981-11-pkshih@realtek.com
  • Loading branch information
Ching-Te Ku authored and Kalle Valo committed Dec 2, 2020
1 parent 1a74dae commit 5b2e9a3
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 6 deletions.
102 changes: 96 additions & 6 deletions drivers/net/wireless/realtek/rtw88/coex.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;

Expand All @@ -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)
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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;

Expand All @@ -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;
Expand All @@ -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);
}

Expand Down
3 changes: 3 additions & 0 deletions drivers/net/wireless/realtek/rtw88/coex.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions drivers/net/wireless/realtek/rtw88/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down

0 comments on commit 5b2e9a3

Please sign in to comment.