mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
wifi: rtw89: coex: Add protect to avoid A2DP lag while Wi-Fi connecting
To get a well Wi-Fi RF quality, Wi-Fi need to do RF calibrations. While Wi-Fi is doing RF calibrations, driver will pause the Bluetooth traffic to make sure the RF calibration will not be interfered by Bluetooth. However, if the RF calibrations take too much time, Bluetooth audio will perform a lag sound. Add a function to make Bluetooth can do traffic between the individual calibrations to avoid Bluetooth sound lag. And patch related A2DP coexistence mechanism actions. Signed-off-by: Ching-Te Ku <ku920601@realtek.com> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com> Link: https://patch.msgid.link/20250110015416.10704-2-pkshih@realtek.com
This commit is contained in:
parent
59372af69d
commit
5251fd3216
8 changed files with 85 additions and 40 deletions
|
@ -4589,17 +4589,16 @@ static void _action_bt_a2dp(struct rtw89_dev *rtwdev)
|
|||
|
||||
_set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
|
||||
|
||||
if (a2dp.vendor_id == 0x4c || dm->leak_ap || bt_linfo->slave_role)
|
||||
dm->slot_dur[CXST_W1] = 20;
|
||||
else
|
||||
dm->slot_dur[CXST_W1] = 40;
|
||||
|
||||
dm->slot_dur[CXST_B1] = BTC_B1_MAX;
|
||||
|
||||
switch (btc->cx.state_map) {
|
||||
case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2DP */
|
||||
if (a2dp.vendor_id == 0x4c || dm->leak_ap) {
|
||||
dm->slot_dur[CXST_W1] = 40;
|
||||
dm->slot_dur[CXST_B1] = 200;
|
||||
_set_policy(rtwdev,
|
||||
BTC_CXP_PAUTO_TDW1B1, BTC_ACT_BT_A2DP);
|
||||
} else {
|
||||
_set_policy(rtwdev,
|
||||
BTC_CXP_PAUTO_TD50B1, BTC_ACT_BT_A2DP);
|
||||
}
|
||||
_set_policy(rtwdev, BTC_CXP_PAUTO_TDW1B1, BTC_ACT_BT_A2DP);
|
||||
break;
|
||||
case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2DP */
|
||||
_set_policy(rtwdev, BTC_CXP_PAUTO2_TD3050, BTC_ACT_BT_A2DP);
|
||||
|
@ -4609,15 +4608,10 @@ static void _action_bt_a2dp(struct rtw89_dev *rtwdev)
|
|||
break;
|
||||
case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2DP */
|
||||
case BTC_WLINKING: /* wl-connecting + bt-A2DP */
|
||||
if (a2dp.vendor_id == 0x4c || dm->leak_ap) {
|
||||
dm->slot_dur[CXST_W1] = 40;
|
||||
dm->slot_dur[CXST_B1] = 200;
|
||||
_set_policy(rtwdev, BTC_CXP_AUTO_TDW1B1,
|
||||
BTC_ACT_BT_A2DP);
|
||||
} else {
|
||||
_set_policy(rtwdev, BTC_CXP_AUTO_TD50B1,
|
||||
BTC_ACT_BT_A2DP);
|
||||
}
|
||||
if (btc->cx.wl.rfk_info.con_rfk)
|
||||
_set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_BT_A2DP);
|
||||
else
|
||||
_set_policy(rtwdev, BTC_CXP_AUTO_TDW1B1, BTC_ACT_BT_A2DP);
|
||||
break;
|
||||
case BTC_WIDLE: /* wl-idle + bt-A2DP */
|
||||
_set_policy(rtwdev, BTC_CXP_AUTO_TD20B1, BTC_ACT_BT_A2DP);
|
||||
|
@ -4645,7 +4639,10 @@ static void _action_bt_a2dpsink(struct rtw89_dev *rtwdev)
|
|||
_set_policy(rtwdev, BTC_CXP_FIX_TD2060, BTC_ACT_BT_A2DPSINK);
|
||||
break;
|
||||
case BTC_WLINKING: /* wl-connecting + bt-A2dp_Sink */
|
||||
_set_policy(rtwdev, BTC_CXP_FIX_TD3030, BTC_ACT_BT_A2DPSINK);
|
||||
if (btc->cx.wl.rfk_info.con_rfk)
|
||||
_set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_BT_A2DPSINK);
|
||||
else
|
||||
_set_policy(rtwdev, BTC_CXP_FIX_TD3030, BTC_ACT_BT_A2DPSINK);
|
||||
break;
|
||||
case BTC_WIDLE: /* wl-idle + bt-A2dp_Sink */
|
||||
_set_policy(rtwdev, BTC_CXP_FIX_TD2080, BTC_ACT_BT_A2DPSINK);
|
||||
|
@ -4699,21 +4696,20 @@ static void _action_bt_a2dp_hid(struct rtw89_dev *rtwdev)
|
|||
|
||||
_set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
|
||||
|
||||
if (a2dp.vendor_id == 0x4c || dm->leak_ap || bt_linfo->slave_role)
|
||||
dm->slot_dur[CXST_W1] = 20;
|
||||
else
|
||||
dm->slot_dur[CXST_W1] = 40;
|
||||
|
||||
dm->slot_dur[CXST_B1] = BTC_B1_MAX;
|
||||
|
||||
switch (btc->cx.state_map) {
|
||||
case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-A2DP+HID */
|
||||
case BTC_WIDLE: /* wl-idle + bt-A2DP */
|
||||
if (a2dp.vendor_id == 0x4c || dm->leak_ap) {
|
||||
dm->slot_dur[CXST_W1] = 40;
|
||||
dm->slot_dur[CXST_B1] = 200;
|
||||
_set_policy(rtwdev,
|
||||
BTC_CXP_PAUTO_TDW1B1, BTC_ACT_BT_A2DP_HID);
|
||||
} else {
|
||||
_set_policy(rtwdev,
|
||||
BTC_CXP_PAUTO_TD50B1, BTC_ACT_BT_A2DP_HID);
|
||||
}
|
||||
_set_policy(rtwdev, BTC_CXP_PAUTO_TDW1B1, BTC_ACT_BT_A2DP_HID);
|
||||
break;
|
||||
case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-A2DP+HID */
|
||||
_set_policy(rtwdev, BTC_CXP_PAUTO2_TD3050, BTC_ACT_BT_A2DP_HID);
|
||||
_set_policy(rtwdev, BTC_CXP_PAUTO2_TD3070, BTC_ACT_BT_A2DP_HID);
|
||||
break;
|
||||
|
||||
case BTC_WSCAN_BSCAN: /* wl-scan + bt-inq + bt-A2DP+HID */
|
||||
|
@ -4721,15 +4717,10 @@ static void _action_bt_a2dp_hid(struct rtw89_dev *rtwdev)
|
|||
break;
|
||||
case BTC_WSCAN_BNOSCAN: /* wl-scan + bt-A2DP+HID */
|
||||
case BTC_WLINKING: /* wl-connecting + bt-A2DP+HID */
|
||||
if (a2dp.vendor_id == 0x4c || dm->leak_ap) {
|
||||
dm->slot_dur[CXST_W1] = 40;
|
||||
dm->slot_dur[CXST_B1] = 200;
|
||||
_set_policy(rtwdev, BTC_CXP_AUTO_TDW1B1,
|
||||
BTC_ACT_BT_A2DP_HID);
|
||||
} else {
|
||||
_set_policy(rtwdev, BTC_CXP_AUTO_TD50B1,
|
||||
BTC_ACT_BT_A2DP_HID);
|
||||
}
|
||||
if (btc->cx.wl.rfk_info.con_rfk)
|
||||
_set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_BT_A2DP_HID);
|
||||
else
|
||||
_set_policy(rtwdev, BTC_CXP_AUTO_TDW1B1, BTC_ACT_BT_A2DP_HID);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -7002,7 +6993,7 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
|
|||
goto exit;
|
||||
}
|
||||
|
||||
if (wl->status.val & btc_scanning_map.val) {
|
||||
if (wl->status.val & btc_scanning_map.val && !wl->rfk_info.con_rfk) {
|
||||
_action_wl_scan(rtwdev);
|
||||
bt->scan_rx_low_pri = true;
|
||||
goto exit;
|
||||
|
@ -11037,3 +11028,24 @@ out:
|
|||
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC] use version def[%d] = 0x%08x\n",
|
||||
(int)(btc->ver - rtw89_btc_ver_defs), btc->ver->fw_ver_code);
|
||||
}
|
||||
|
||||
void rtw89_btc_ntfy_preserve_bt_time(struct rtw89_dev *rtwdev, u32 ms)
|
||||
{
|
||||
struct rtw89_btc_bt_link_info *bt_linfo = &rtwdev->btc.cx.bt.link_info;
|
||||
struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc;
|
||||
|
||||
if (test_bit(RTW89_FLAG_SER_HANDLING, rtwdev->flags))
|
||||
return;
|
||||
|
||||
if (!a2dp.exist)
|
||||
return;
|
||||
|
||||
fsleep(ms * 1000);
|
||||
}
|
||||
EXPORT_SYMBOL(rtw89_btc_ntfy_preserve_bt_time);
|
||||
|
||||
void rtw89_btc_ntfy_conn_rfk(struct rtw89_dev *rtwdev, bool state)
|
||||
{
|
||||
rtwdev->btc.cx.wl.rfk_info.con_rfk = state;
|
||||
}
|
||||
EXPORT_SYMBOL(rtw89_btc_ntfy_conn_rfk);
|
||||
|
|
|
@ -290,6 +290,8 @@ void rtw89_coex_power_on(struct rtw89_dev *rtwdev);
|
|||
void rtw89_btc_set_policy(struct rtw89_dev *rtwdev, u16 policy_type);
|
||||
void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type);
|
||||
void rtw89_coex_recognize_ver(struct rtw89_dev *rtwdev);
|
||||
void rtw89_btc_ntfy_preserve_bt_time(struct rtw89_dev *rtwdev, u32 ms);
|
||||
void rtw89_btc_ntfy_conn_rfk(struct rtw89_dev *rtwdev, bool state);
|
||||
|
||||
static inline u8 rtw89_btc_phymap(struct rtw89_dev *rtwdev,
|
||||
enum rtw89_phy_idx phy_idx,
|
||||
|
|
|
@ -1761,7 +1761,8 @@ struct rtw89_btc_wl_rfk_info {
|
|||
u32 phy_map: 2;
|
||||
u32 band: 2;
|
||||
u32 type: 8;
|
||||
u32 rsvd: 14;
|
||||
u32 con_rfk: 1;
|
||||
u32 rsvd: 13;
|
||||
|
||||
u32 start_time;
|
||||
u32 proc_time;
|
||||
|
|
|
@ -1596,10 +1596,16 @@ static void rtw8851b_rfk_channel(struct rtw89_dev *rtwdev,
|
|||
enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
|
||||
enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
|
||||
|
||||
rtw89_btc_ntfy_conn_rfk(rtwdev, true);
|
||||
|
||||
rtw8851b_rx_dck(rtwdev, phy_idx, chanctx_idx);
|
||||
rtw8851b_iqk(rtwdev, phy_idx, chanctx_idx);
|
||||
rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
|
||||
rtw8851b_tssi(rtwdev, phy_idx, true, chanctx_idx);
|
||||
rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
|
||||
rtw8851b_dpk(rtwdev, phy_idx, chanctx_idx);
|
||||
|
||||
rtw89_btc_ntfy_conn_rfk(rtwdev, false);
|
||||
}
|
||||
|
||||
static void rtw8851b_rfk_band_changed(struct rtw89_dev *rtwdev,
|
||||
|
|
|
@ -1356,10 +1356,16 @@ static void rtw8852a_rfk_channel(struct rtw89_dev *rtwdev,
|
|||
enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
|
||||
enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
|
||||
|
||||
rtw89_btc_ntfy_conn_rfk(rtwdev, true);
|
||||
|
||||
rtw8852a_rx_dck(rtwdev, phy_idx, true, chanctx_idx);
|
||||
rtw8852a_iqk(rtwdev, phy_idx, chanctx_idx);
|
||||
rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
|
||||
rtw8852a_tssi(rtwdev, phy_idx, chanctx_idx);
|
||||
rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
|
||||
rtw8852a_dpk(rtwdev, phy_idx, chanctx_idx);
|
||||
|
||||
rtw89_btc_ntfy_conn_rfk(rtwdev, false);
|
||||
}
|
||||
|
||||
static void rtw8852a_rfk_band_changed(struct rtw89_dev *rtwdev,
|
||||
|
|
|
@ -568,10 +568,16 @@ static void rtw8852b_rfk_channel(struct rtw89_dev *rtwdev,
|
|||
enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
|
||||
enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
|
||||
|
||||
rtw89_btc_ntfy_conn_rfk(rtwdev, true);
|
||||
|
||||
rtw8852b_rx_dck(rtwdev, phy_idx, chanctx_idx);
|
||||
rtw8852b_iqk(rtwdev, phy_idx, chanctx_idx);
|
||||
rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
|
||||
rtw8852b_tssi(rtwdev, phy_idx, true, chanctx_idx);
|
||||
rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
|
||||
rtw8852b_dpk(rtwdev, phy_idx, chanctx_idx);
|
||||
|
||||
rtw89_btc_ntfy_conn_rfk(rtwdev, false);
|
||||
}
|
||||
|
||||
static void rtw8852b_rfk_band_changed(struct rtw89_dev *rtwdev,
|
||||
|
|
|
@ -541,10 +541,16 @@ static void rtw8852bt_rfk_channel(struct rtw89_dev *rtwdev,
|
|||
enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
|
||||
enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
|
||||
|
||||
rtw89_btc_ntfy_conn_rfk(rtwdev, true);
|
||||
|
||||
rtw8852bt_rx_dck(rtwdev, phy_idx, chanctx_idx);
|
||||
rtw8852bt_iqk(rtwdev, phy_idx, chanctx_idx);
|
||||
rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
|
||||
rtw8852bt_tssi(rtwdev, phy_idx, true, chanctx_idx);
|
||||
rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
|
||||
rtw8852bt_dpk(rtwdev, phy_idx, chanctx_idx);
|
||||
|
||||
rtw89_btc_ntfy_conn_rfk(rtwdev, false);
|
||||
}
|
||||
|
||||
static void rtw8852bt_rfk_band_changed(struct rtw89_dev *rtwdev,
|
||||
|
|
|
@ -1853,10 +1853,16 @@ static void rtw8852c_rfk_channel(struct rtw89_dev *rtwdev,
|
|||
enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
|
||||
|
||||
rtw8852c_mcc_get_ch_info(rtwdev, phy_idx);
|
||||
rtw89_btc_ntfy_conn_rfk(rtwdev, true);
|
||||
|
||||
rtw8852c_rx_dck(rtwdev, phy_idx, false);
|
||||
rtw8852c_iqk(rtwdev, phy_idx, chanctx_idx);
|
||||
rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
|
||||
rtw8852c_tssi(rtwdev, phy_idx, chanctx_idx);
|
||||
rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
|
||||
rtw8852c_dpk(rtwdev, phy_idx, chanctx_idx);
|
||||
|
||||
rtw89_btc_ntfy_conn_rfk(rtwdev, false);
|
||||
rtw89_fw_h2c_rf_ntfy_mcc(rtwdev);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue