]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
wifi: rtw89: coex: Add protect to avoid A2DP lag while Wi-Fi connecting
authorChing-Te Ku <ku920601@realtek.com>
Fri, 10 Jan 2025 01:54:14 +0000 (09:54 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 May 2025 09:13:46 +0000 (11:13 +0200)
[ Upstream commit 5251fd321684b591245a072b765d01a6c22a112c ]

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
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/wireless/realtek/rtw89/coex.c
drivers/net/wireless/realtek/rtw89/coex.h
drivers/net/wireless/realtek/rtw89/core.h
drivers/net/wireless/realtek/rtw89/rtw8851b.c
drivers/net/wireless/realtek/rtw89/rtw8852a.c
drivers/net/wireless/realtek/rtw89/rtw8852b.c
drivers/net/wireless/realtek/rtw89/rtw8852bt.c
drivers/net/wireless/realtek/rtw89/rtw8852c.c

index 7b10ee97c627727dcd059dce575cb4a4aec190e4..86e8f78ec94a4b1eb781142c87d9703ce3311921 100644 (file)
@@ -4587,17 +4587,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);
@@ -4607,15 +4606,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);
@@ -4643,7 +4637,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);
@@ -4697,21 +4694,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 */
@@ -4719,15 +4715,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;
        }
 }
@@ -7001,7 +6992,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;
@@ -11040,3 +11031,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);
index dbdb56e063ef036fa32bcae2bd9dfbb7cc39714b..757d03675cf4e67e266480253783c3dbe276726c 100644 (file)
@@ -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,
index c493153ec77b350f1bca66bdda83bddf71e692f0..963f0046f0bc358ae09ff6b8baa19ada0903eeb4 100644 (file)
@@ -1762,7 +1762,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;
index a1df4ba97cd4d9ad0350c264ffbf6d6545a6a04c..546e88cd46493509906115a72575a746eea33e7f 100644 (file)
@@ -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,
index cd79a997fe0221797e2d915ffd5083e41991c3c7..e12e5bd402e5b83eb5c995d70c5d0e23f5e180ad 100644 (file)
@@ -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,
index fcb69fa6cf86d6884922dbef645dcc8548f48133..ab9365b0ec089e4b3a638ee2cf93d05717902e81 100644 (file)
@@ -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,
index bc740e9abf2630327ffb99fef375afea7ef1513c..412e633944f37176a764190368a4760480036649 100644 (file)
@@ -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,
index 63a2bc88cdbcdaf29711ffaf0db0f4acf54ed806..cd68f6cbeecbfe16f841db4d966343fab245b443 100644 (file)
@@ -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);
 }