Linux wireless drivers development
 help / color / mirror / Atom feed
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


  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