From: Ping-Ke Shih <pkshih@realtek.com>
To: <linux-wireless@vger.kernel.org>
Cc: <ku920601@realtek.com>
Subject: [PATCH rtw-next 01/10] wifi: rtw89: coex: force to exit Wi-Fi LPS while Bluetooth profile exist
Date: Wed, 24 Jun 2026 11:39:32 +0800 [thread overview]
Message-ID: <20260624033941.45918-2-pkshih@realtek.com> (raw)
In-Reply-To: <20260624033941.45918-1-pkshih@realtek.com>
From: Ching-Te Ku <ku920601@realtek.com>
Wi-Fi can not reach LPS leave threshold while Wi-Fi only throughput
not good & Bluetooth share bandwidth. Add logic to let force leave
Wi-Fi LPS while Bluetooth profile exist. Update COEX version to 9.0.1.
Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/coex.c | 87 +++++++++++++++++------
drivers/net/wireless/realtek/rtw89/core.h | 4 ++
2 files changed, 69 insertions(+), 22 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index 0f7ae572ef91..73f271a7ae7a 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -11,7 +11,7 @@
#include "ps.h"
#include "reg.h"
-#define RTW89_COEX_VERSION 0x09000013
+#define RTW89_COEX_VERSION 0x09000113
#define FCXDEF_STEP 50 /* MUST <= FCXMAX_STEP and match with wl fw*/
#define BTC_E2G_LIMIT_DEF 80
@@ -434,6 +434,8 @@ enum btc_b2w_scoreboard {
BTC_BSCB_WLRFK = BIT(11),
BTC_BSCB_BT_HILNA = BIT(13),
BTC_BSCB_BT_CONNECT = BIT(16),
+ BTC_BSCB_PAN_ACT = BIT(28),
+ BTC_BSCB_HFP_ACT = BIT(29),
BTC_BSCB_PATCH_CODE = BIT(30),
BTC_BSCB_ALL = GENMASK(30, 0),
};
@@ -2747,7 +2749,9 @@ static void _fw_set_policy(struct rtw89_dev *rtwdev, u16 policy_type,
dm->tdma.rxflctrl == CXFLC_QOSNULL)
btc->lps = 1;
else
- btc->lps = 0;
+ btc->lps = dm->lps_ctrl_scbd;
+
+ dm->lps_ctrl_scbd_last = dm->lps_ctrl_scbd;
if (btc->lps == 1)
rtw89_set_coex_ctrl_lps(rtwdev, btc->lps);
@@ -4434,7 +4438,7 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
if (dm->leak_ap && dm->tdma.leak_n > 1)
_tdma_set_lek(btc, 1);
- if (dm->tdma_instant_excute) {
+ if (dm->tdma_instant_excute || dm->lps_ctrl_change) {
btc->dm.tdma.option_ctrl |= BIT(0);
btc->update_policy_force = true;
}
@@ -5638,7 +5642,8 @@ static void _action_common(struct rtw89_dev *rtwdev)
_fw_set_drv_info(rtwdev, CXDRVINFO_OSI);
}
}
- btc->dm.tdma_instant_excute = 0;
+ dm->tdma_instant_excute = 0;
+ dm->lps_ctrl_change = false;
wl->pta_reg_mac_chg = false;
}
@@ -7384,11 +7389,15 @@ void rtw89_coex_rfk_chk_work(struct wiphy *wiphy, struct wiphy_work *work)
static void _update_bt_scbd(struct rtw89_dev *rtwdev, bool only_update)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
+ const struct rtw89_btc_ver *ver = rtwdev->btc.ver;
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_bt_info *bt = &btc->cx.bt;
- u32 val;
- bool status_change = false;
+ struct rtw89_btc_wl_info *wl = &btc->cx.wl;
+ struct rtw89_btc_dm *dm = &rtwdev->btc.dm;
+ bool bt_link_change = false, lps_ctrl = false;
+ u32 val, any_bt_connect;
+ u8 mode;
if (!chip->scbd)
return;
@@ -7403,13 +7412,26 @@ static void _update_bt_scbd(struct rtw89_dev *rtwdev, bool only_update)
return;
}
+ if (ver->fwlrole == 0)
+ mode = wl->role_info.link_mode;
+ else if (ver->fwlrole == 1)
+ mode = wl->role_info_v1.link_mode;
+ else if (ver->fwlrole == 2)
+ mode = wl->role_info_v2.link_mode;
+ else if (ver->fwlrole == 7)
+ mode = wl->role_info_v7.link_mode;
+ else if (ver->fwlrole == 8)
+ mode = wl->role_info_v8.link_mode;
+ else
+ return;
+
if (!(val & BTC_BSCB_ON))
bt->enable.now = 0;
else
bt->enable.now = 1;
if (bt->enable.now != bt->enable.last)
- status_change = true;
+ bt_link_change = true;
/* reset bt info if bt re-enable */
if (bt->enable.now && !bt->enable.last) {
@@ -7423,29 +7445,52 @@ static void _update_bt_scbd(struct rtw89_dev *rtwdev, bool only_update)
bt->mbx_avl = !!(val & BTC_BSCB_ACT);
if (bt->whql_test != !!(val & BTC_BSCB_WHQL))
- status_change = true;
+ bt_link_change = true;
bt->whql_test = !!(val & BTC_BSCB_WHQL);
bt->btg_type = val & BTC_BSCB_BT_S1 ? BTC_BT_BTG : BTC_BT_ALONE;
bt->link_info.a2dp_desc.exist = !!(val & BTC_BSCB_A2DP_ACT);
+ bt->link_info.pan_desc.exist = !!(val & BTC_BSCB_PAN_ACT);
+ bt->link_info.hfp_desc.exist = !!(val & BTC_BSCB_HFP_ACT);
bt->lna_constrain = !!(val & BTC_BSCB_BT_LNAB0) +
!!(val & BTC_BSCB_BT_LNAB1) * 2 + 4;
/* if rfk run 1->0 */
if (bt->rfk_info.map.run && !(val & BTC_BSCB_RFK_RUN))
- status_change = true;
+ bt_link_change = true;
bt->rfk_info.map.run = !!(val & BTC_BSCB_RFK_RUN);
bt->rfk_info.map.req = !!(val & BTC_BSCB_RFK_REQ);
bt->hi_lna_rx = !!(val & BTC_BSCB_BT_HILNA);
- bt->link_info.status.map.connect = !!(val & BTC_BSCB_BT_CONNECT);
- if (bt->run_patch_code != !!(val & BTC_BSCB_PATCH_CODE))
- status_change = true;
+ any_bt_connect = !!(val & BTC_BSCB_BT_CONNECT);
+
+ /* if connect change */
+ if (bt->link_info.status.map.connect != any_bt_connect)
+ bt_link_change = true;
+
+ /* if specific profile exist */
+ if (((bt->link_info.a2dp_desc.exist || bt->link_info.pan_desc.exist ||
+ bt->link_info.hfp_desc.exist) && mode == BTC_WLINK_2G_STA) ||
+ bt->whql_test)
+ lps_ctrl = true;
+
+ if (dm->lps_ctrl_scbd != lps_ctrl) {
+ dm->lps_ctrl_scbd = lps_ctrl;
+ bt_link_change = true;
+ dm->lps_ctrl_change = true;
+ } else {
+ dm->lps_ctrl_change = false;
+ }
+
+ bt->link_info.status.map.connect = any_bt_connect;
bt->run_patch_code = !!(val & BTC_BSCB_PATCH_CODE);
- if (!only_update && status_change)
- _run_coex(rtwdev, BTC_RSN_UPDATE_BT_SCBD);
+ if (bt_link_change) {
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "[BTC], %s: bt status change!!\n", __func__);
+ /* TODO: Need to notify driver to update EXT-CTRL-BT-SLOT */
+ }
}
#define BTC_BTINFO_PWR_LEN 5
@@ -7560,7 +7605,8 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
}
if (wl->status.map.rf_off_pre == wl->status.map.rf_off &&
- wl->status.map.lps_pre == wl->status.map.lps) {
+ wl->status.map.lps_pre == wl->status.map.lps &&
+ !dm->lps_ctrl_change && !dm->lps_ctrl_scbd) {
if (reason == BTC_RSN_NTFY_POWEROFF ||
reason == BTC_RSN_NTFY_RADIO_STATE) {
rtw89_debug(rtwdev, RTW89_DBG_BTC,
@@ -7577,6 +7623,9 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
}
}
+ if (reason == BTC_RSN_NTFY_INIT || reason == BTC_RSN_NTFY_RADIO_STATE)
+ _update_bt_scbd(rtwdev, false);
+
dm->freerun = false;
dm->cnt_dm[BTC_DCNT_RUN]++;
dm->fddt_train = BTC_FDDT_DISABLE;
@@ -7597,7 +7646,7 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
goto exit;
}
- if (wl->status.map.rf_off || wl->status.map.lps || dm->bt_only) {
+ if (wl->status.map.rf_off || dm->bt_only || wl->status.map.lps) {
_action_wl_off(rtwdev, mode);
igno_bt = true;
goto exit;
@@ -7781,7 +7830,6 @@ void rtw89_btc_ntfy_init(struct rtw89_dev *rtwdev, u8 mode)
_write_scbd(rtwdev,
BTC_WSCB_ACTIVE | BTC_WSCB_ON | BTC_WSCB_BTLOG, true);
- _update_bt_scbd(rtwdev, true);
if (rtw89_mac_get_ctrl_path(rtwdev)) {
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): PTA owner warning!!\n",
@@ -8339,7 +8387,6 @@ void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_sta
rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_MREG, true);
val = BTC_WSCB_ACTIVE | BTC_WSCB_ON | BTC_WSCB_BTLOG;
_write_scbd(rtwdev, val, true);
- _update_bt_scbd(rtwdev, true);
chip->ops->btc_init_cfg(rtwdev);
} else {
rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_ALL, false);
@@ -8349,10 +8396,6 @@ void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_sta
_write_scbd(rtwdev, BTC_WSCB_ALL, false);
else
_write_scbd(rtwdev, BTC_WSCB_ACTIVE, false);
-
- if (rf_state == BTC_RFCTRL_LPS_WL_ON &&
- wl->status.map.lps_pre != BTC_LPS_OFF)
- _update_bt_scbd(rtwdev, true);
}
btc->dm.cnt_dm[BTC_DCNT_BTCNT_HANG] = 0;
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 5547888d7e67..de92e42da614 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -3153,6 +3153,10 @@ struct rtw89_btc_dm {
u8 wl_pre_agc_rb: 2;
u8 bt_select: 2; /* 0:s0, 1:s1, 2:s0 & s1, refer to enum btc_bt_index */
u8 slot_req_more: 1;
+ u8 lps_ctrl_scbd: 1;
+
+ u8 lps_ctrl_scbd_last: 1;
+ u8 lps_ctrl_change: 1;
};
struct rtw89_btc_ctrl {
--
2.25.1
next prev parent reply other threads:[~2026-06-24 3:40 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-24 3:39 [PATCH rtw-next 00/10] wifi: rtw89: coex: update BT coexistence to support dual BT for RTL8922D Ping-Ke Shih
2026-06-24 3:39 ` Ping-Ke Shih [this message]
2026-06-24 3:39 ` [PATCH rtw-next 02/10] wifi: rtw89: coex: offset current BT info to BT0 for dual BT configuration Ping-Ke Shih
2026-06-24 3:39 ` [PATCH rtw-next 03/10] wifi: rtw89: coex: Move wifi related counters to wifi info Ping-Ke Shih
2026-06-24 3:39 ` [PATCH rtw-next 04/10] wifi: rtw89: coex: Extend bt_slot_req for dual MAC wifi Ping-Ke Shih
2026-06-24 3:39 ` [PATCH rtw-next 05/10] wifi: rtw89: coex: Move Bluetooth related counters to BT info Ping-Ke Shih
2026-06-24 3:39 ` [PATCH rtw-next 06/10] wifi: rtw89: coex: Refine third party module related coexistence Ping-Ke Shih
2026-06-24 3:39 ` [PATCH rtw-next 07/10] wifi: rtw89: coex: Add TX/RX RF parameter format version 9 Ping-Ke Shih
2026-06-24 3:39 ` [PATCH rtw-next 08/10] wifi: rtw89: coex: Renaming drvinfo_type to drvinfo_ver Ping-Ke Shih
2026-06-24 3:39 ` [PATCH rtw-next 09/10] wifi: rtw89: coex: Add Wi-Fi firmware 0.35.94.1 support for RTL8922D Ping-Ke Shih
2026-06-24 3:39 ` [PATCH rtw-next 10/10] wifi: rtw89: coex: Add RTL8922D chip string Ping-Ke Shih
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260624033941.45918-2-pkshih@realtek.com \
--to=pkshih@realtek.com \
--cc=ku920601@realtek.com \
--cc=linux-wireless@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox