All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH rtw-next 0/7] wifi: rtw89: 8922d: fix and cleanup coex code and enable RTL8922DE
@ 2026-07-30  6:02 Ping-Ke Shih
  2026-07-30  6:02 ` [PATCH rtw-next 1/7] wifi: rtw89: coex: Fix Bluetooth link weight not updated on profile change Ping-Ke Shih
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Ping-Ke Shih @ 2026-07-30  6:02 UTC (permalink / raw)
  To: linux-wireless; +Cc: ku920601

Update the final BT-coexistence patchset needed by RTL8922DE, so we
can enable RTL8922DE eventually.

Ching-Te Ku (6):
  wifi: rtw89: coex: Fix Bluetooth link weight not updated on profile
    change
  wifi: rtw89: coex: Fix BT-info parsing for 5/6 GHz band & dual
    Bluetooth
  wifi: rtw89: coex: Clear BT link weight when BT is disabled
  wifi: rtw89: coex: Change Wi-Fi link_mode_v0 translating timing
  wifi: rtw89: coex: Port _update_bt_ctrl_lps() for BT profile-based LPS
    control
  wifi: rtw89: coex: Update Wi-Fi/Bluetooth coexistence version to
    9.24.1

Ping-Ke Shih (1):
  wifi: rtw89: 8922d: enable Makefile and Kconfig for RTL8922DE

 drivers/net/wireless/realtek/rtw89/Kconfig  |  15 +
 drivers/net/wireless/realtek/rtw89/Makefile |   7 +
 drivers/net/wireless/realtek/rtw89/coex.c   | 383 +++++++++++---------
 drivers/net/wireless/realtek/rtw89/core.h   |   4 +-
 4 files changed, 234 insertions(+), 175 deletions(-)


base-commit: 9f2948010764d708bda27369d09ce6f194abe8e3
-- 
2.25.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH rtw-next 1/7] wifi: rtw89: coex: Fix Bluetooth link weight not updated on profile change
  2026-07-30  6:02 [PATCH rtw-next 0/7] wifi: rtw89: 8922d: fix and cleanup coex code and enable RTL8922DE Ping-Ke Shih
@ 2026-07-30  6:02 ` Ping-Ke Shih
  2026-07-30  6:02 ` [PATCH rtw-next 2/7] wifi: rtw89: coex: Fix BT-info parsing for 5/6 GHz band & dual Bluetooth Ping-Ke Shih
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Ping-Ke Shih @ 2026-07-30  6:02 UTC (permalink / raw)
  To: linux-wireless; +Cc: ku920601

From: Ching-Te Ku <ku920601@realtek.com>

_update_bt_link_cnt() was missing the bt->link_weight[].
Without it, link_weight stays at the initial value of 5
(set on BT re-enable) regardless of the active BT profile.

_set_bind_info() uses link_weight to compute b2g_score/b5g_score, which
determines tdd_bind.rf_band. With a stale weight of 5 (below the active
profile threshold), tdd_bind.rf_band may not reflect the actual RF band,
causing mode_v0 in _run_coex() to remain 0 (BTC_WLINK_NOLINK), which
incorrectly triggers _action_wl_nc() instead of the BT-profile action.

Add the link_weight calculation to _update_bt_link_cnt() using the same
weighting table as Formal (BIS/A2DP-sink: 70, A2DP: 40-60, PAN/active: 30,
no-profile: 5, else: 9) and call _update_bt_link_cnt() from
_update_bt_info() after parsing the profile exist flags, replacing the
open-coded link_cnt increment that omitted le-audio profiles.

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 | 30 ++++++++++++++++++-----
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index 0e42c720819a..fd9ddd55c192 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -7973,6 +7973,8 @@ static void _update_bt_link_cnt(struct rtw89_dev *rtwdev,
 	struct rtw89_btc_bt_hfp_desc *hfp = &b->hfp_desc;
 	struct rtw89_btc_bt_hid_desc *hid = &b->hid_desc;
 	struct rtw89_btc_bt_pan_desc *pan = &b->pan_desc;
+	u8 bt_rf_band = b56g ? BTC_BT_B5G : BTC_BT_B2G;
+	u8 val;
 
 	b->link_cnt.last = b->link_cnt.now;
 	b->link_cnt.now = 0;
@@ -7984,6 +7986,27 @@ static void _update_bt_link_cnt(struct rtw89_dev *rtwdev,
 	b->link_cnt.now += pan->exist;
 	b->link_cnt.now += leaudio->bis_exist;
 	b->link_cnt.now += leaudio->cis_exist;
+
+	if (leaudio->bis_exist || a2dp->sink) {
+		val = 70;
+	} else if (a2dp->exist) {
+		val = 40;
+		if (a2dp->vendor_id == 0x4c)
+			val += 10;
+		if (hid->exist)
+			val += 10;
+	} else if (pan->exist || pan->active || a2dp->active ||
+		   b->status.map.inq_pag) {
+		val = 30;
+	} else if (b->link_cnt.now == 0) {
+		val = 5;
+	} else {
+		val = 9;
+	}
+	bt->link_weight[bt_rf_band] = val;
+
+	if (b->link_cnt.last != b->link_cnt.now)
+		b->link_cnt.chg = 1;
 }
 
 static void _update_bt_leaudio_info(struct rtw89_dev *rtwdev, u8 bid,
@@ -9012,8 +9035,6 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
 		    "[BTC], %s(): bt_info[2]=0x%02x\n",
 		    __func__, bt->raw_info[2]);
 
-	b->link_cnt.last = b->link_cnt.now;
-	b->link_cnt.now = 0;
 	hid->type = 0;
 
 	/* parse raw info low-Byte2 */
@@ -9026,13 +9047,10 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
 	bt->bcnt[BTC_BCNT_INQPAG] += !!(bt->inq_pag.now && !bt->inq_pag.last);
 
 	hfp->exist = btinfo.lb2.hfp;
-	b->link_cnt.now += (u8)hfp->exist;
 	hid->exist = btinfo.lb2.hid;
-	b->link_cnt.now += (u8)hid->exist;
 	a2dp->exist = btinfo.lb2.a2dp;
-	b->link_cnt.now += (u8)a2dp->exist;
 	pan->exist = btinfo.lb2.pan;
-	b->link_cnt.now += (u8)pan->exist;
+	_update_bt_link_cnt(rtwdev, bt, 0);
 	btc->dm.trx_info.bt_profile = u32_get_bits(btinfo.val, BT_PROFILE_PROTOCOL_MASK);
 
 	/* parse raw info low-Byte3 */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH rtw-next 2/7] wifi: rtw89: coex: Fix BT-info parsing for 5/6 GHz band & dual Bluetooth
  2026-07-30  6:02 [PATCH rtw-next 0/7] wifi: rtw89: 8922d: fix and cleanup coex code and enable RTL8922DE Ping-Ke Shih
  2026-07-30  6:02 ` [PATCH rtw-next 1/7] wifi: rtw89: coex: Fix Bluetooth link weight not updated on profile change Ping-Ke Shih
@ 2026-07-30  6:02 ` Ping-Ke Shih
  2026-07-30  6:02 ` [PATCH rtw-next 3/7] wifi: rtw89: coex: Clear BT link weight when BT is disabled Ping-Ke Shih
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Ping-Ke Shih @ 2026-07-30  6:02 UTC (permalink / raw)
  To: linux-wireless; +Cc: ku920601

From: Ching-Te Ku <ku920601@realtek.com>

The _update_bt_info() function always parsed BT-info for bt0 and used a
single raw_info buffer regardless of which BT device sent the packet or
which RF band it belongs to. This caused two bugs:

1. BT-info packets from bt1 were incorrectly parsed into bt0's state.

2. BT-info packets from 5/6 GHz BT (L1 bit7=1) overwrote the 2.4 GHz
   link_info and raw_info, breaking duplicate detection across bands.

Fix by adding the bid parameter to select bt0/bt1, detecting the 5/6 GHz
band flag (L1 bit7) to route packets into link_info_56g with a dedicated
raw_info_56g buffer, and updating the early-return mask to ignore bit7
when checking the length field.

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 | 61 ++++++++++++++++-------
 drivers/net/wireless/realtek/rtw89/core.h |  3 +-
 2 files changed, 44 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index fd9ddd55c192..d5b1c68539d9 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -9005,23 +9005,46 @@ static u8 _update_bt_rssi_level(struct rtw89_dev *rtwdev, u8 rssi)
 
 #define BT_PROFILE_PROTOCOL_MASK GENMASK(7, 4)
 
-static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
+static void _update_bt_info(struct rtw89_dev *rtwdev, u8 bid, u8 *buf, u32 len)
 {
 	const struct rtw89_chip_info *chip = rtwdev->chip;
 	struct rtw89_btc *btc = &rtwdev->btc;
+	struct rtw89_btc_bt_a2dp_desc *a2dp;
 	struct rtw89_btc_cx *cx = &btc->cx;
-	struct rtw89_btc_bt_info *bt = &cx->bt0;
-	struct rtw89_btc_bt_link_info *b = &bt->link_info;
-	struct rtw89_btc_bt_hfp_desc *hfp = &b->hfp_desc;
-	struct rtw89_btc_bt_hid_desc *hid = &b->hid_desc;
-	struct rtw89_btc_bt_a2dp_desc *a2dp = &b->a2dp_desc;
-	struct rtw89_btc_bt_pan_desc *pan = &b->pan_desc;
+	struct rtw89_btc_bt_hfp_desc *hfp;
+	struct rtw89_btc_bt_hid_desc *hid;
+	struct rtw89_btc_bt_pan_desc *pan;
+	struct rtw89_btc_bt_link_info *b;
+	struct rtw89_btc_bt_info *bt;
 	union btc_btinfo btinfo;
+	u8 is_bt_56g = 0;
+	u8 *raw_info;
 
-	if (buf[BTC_BTINFO_L1] != 6)
+	/* Bit7 is used for RF-band: 0:BT_2.4 GHz, 1:BT_5/6 GHz */
+	if ((buf[BTC_BTINFO_L1] & 0x7f) != 6)
 		return;
 
-	if (!memcmp(bt->raw_info, buf, BTC_BTINFO_MAX)) {
+	bt = (bid == BTC_BT_1ST) ? &cx->bt0 : &cx->bt1;
+
+	if ((buf[BTC_BTINFO_L1] & BIT(7)) && bt->band_56G_support) {
+		b = &bt->link_info_56g;
+		is_bt_56g = 1;
+		if (b->status.map.connect)
+			bt->rf_band_map |= BIT(RTW89_BAND_5G);
+		else
+			bt->rf_band_map &= ~BIT(RTW89_BAND_5G);
+	} else {
+		b = &bt->link_info;
+		bt->rf_band_map |= BIT(RTW89_BAND_2G);
+	}
+
+	hfp = &b->hfp_desc;
+	hid = &b->hid_desc;
+	a2dp = &b->a2dp_desc;
+	pan = &b->pan_desc;
+	raw_info = is_bt_56g ? bt->raw_info_56g : bt->raw_info;
+
+	if (!memcmp(raw_info, buf, BTC_BTINFO_MAX)) {
 		rtw89_debug(rtwdev, RTW89_DBG_BTC,
 			    "[BTC], %s(): return by bt-info duplicate!!\n",
 			    __func__);
@@ -9029,16 +9052,16 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
 		return;
 	}
 
-	memcpy(bt->raw_info, buf, BTC_BTINFO_MAX);
+	memcpy(raw_info, buf, BTC_BTINFO_MAX);
 
 	rtw89_debug(rtwdev, RTW89_DBG_BTC,
 		    "[BTC], %s(): bt_info[2]=0x%02x\n",
-		    __func__, bt->raw_info[2]);
+		    __func__, raw_info[2]);
 
 	hid->type = 0;
 
 	/* parse raw info low-Byte2 */
-	btinfo.val = bt->raw_info[BTC_BTINFO_L2];
+	btinfo.val = raw_info[BTC_BTINFO_L2];
 	b->status.map.connect = btinfo.lb2.connect;
 	b->status.map.sco_busy = btinfo.lb2.sco_busy;
 	b->status.map.acl_busy = btinfo.lb2.acl_busy;
@@ -9050,11 +9073,11 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
 	hid->exist = btinfo.lb2.hid;
 	a2dp->exist = btinfo.lb2.a2dp;
 	pan->exist = btinfo.lb2.pan;
-	_update_bt_link_cnt(rtwdev, bt, 0);
+	_update_bt_link_cnt(rtwdev, bt, is_bt_56g);
 	btc->dm.trx_info.bt_profile = u32_get_bits(btinfo.val, BT_PROFILE_PROTOCOL_MASK);
 
 	/* parse raw info low-Byte3 */
-	btinfo.val = bt->raw_info[BTC_BTINFO_L3];
+	btinfo.val = raw_info[BTC_BTINFO_L3];
 	if (btinfo.lb3.retry != 0)
 		bt->bcnt[BTC_BCNT_RETRY]++;
 	b->cqddr = btinfo.lb3.cqddr;
@@ -9065,14 +9088,14 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
 
 	b->status.map.mesh_busy = btinfo.lb3.mesh_busy;
 	/* parse raw info high-Byte0 */
-	btinfo.val = bt->raw_info[BTC_BTINFO_H0];
+	btinfo.val = raw_info[BTC_BTINFO_H0];
 	/* raw val is dBm unit, translate from -100~ 0dBm to 0~100%*/
 	b->rssi = chip->ops->btc_get_bt_rssi(rtwdev, btinfo.hb0.rssi);
 	bt->rssi_level = _update_bt_rssi_level(rtwdev, b->rssi);
 	btc->dm.trx_info.bt_rssi = bt->rssi_level;
 
 	/* parse raw info high-Byte1 */
-	btinfo.val = bt->raw_info[BTC_BTINFO_H1];
+	btinfo.val = raw_info[BTC_BTINFO_H1];
 	b->status.map.ble_connect = btinfo.hb1.ble_connect;
 	if (btinfo.hb1.ble_connect) {
 		if (hid->exist)
@@ -9101,7 +9124,7 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
 	b->multi_link.now = btinfo.hb1.multi_link;
 
 	/* parse raw info high-Byte2 */
-	btinfo.val = bt->raw_info[BTC_BTINFO_H2];
+	btinfo.val = raw_info[BTC_BTINFO_H2];
 	pan->active = !!btinfo.hb2.pan_active;
 
 	bt->bcnt[BTC_BCNT_AFH] += !!(btinfo.hb2.afh_update && !b->afh_update);
@@ -9114,7 +9137,7 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
 		hid->type |= (hid->slot_info == BTC_HID_218 ?
 			      BTC_HID_218 : BTC_HID_418);
 	/* parse raw info high-Byte3 */
-	btinfo.val = bt->raw_info[BTC_BTINFO_H3];
+	btinfo.val = raw_info[BTC_BTINFO_H3];
 	a2dp->bitpool = btinfo.hb3.a2dp_bitpool;
 
 	if (b->tx_3m != (u32)btinfo.hb3.tx_3m)
@@ -9785,7 +9808,7 @@ void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
 		rtw89_debug(rtwdev, RTW89_DBG_BTC,
 			    "[BTC], handle C2H BT INFO with data %8ph\n", buf);
 		bt->bcnt[BTC_BCNT_INFOUPDATE]++;
-		_update_bt_info(rtwdev, buf, len);
+		_update_bt_info(rtwdev, bid, buf, len);
 		break;
 	case BTF_EVNT_BT_SCBD:
 		bt->bcnt[BTC_BCNT_SCBDUPDATE]++;
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 09c19a6b9058..bc9db0c16473 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -2705,7 +2705,8 @@ struct rtw89_btc_bt_info {
 	struct rtw89_btc_rf_para rf_para;
 	union rtw89_btc_bt_rfk_info_map rfk_info;
 
-	u8 raw_info[BTC_BTINFO_MAX]; /* raw bt info from mailbox */
+	u8 raw_info[BTC_BTINFO_MAX]; /* raw bt info from mailbox (2.4G) */
+	u8 raw_info_56g[BTC_BTINFO_MAX]; /* raw bt info from mailbox (5/6G) */
 	u8 txpwr_info[BTC_BTINFO_MAX];
 	u8 link_weight[BTC_BT_BMAX]; /* Link Weight for RF-band/HWB selection */
 	u8 rssi_level;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH rtw-next 3/7] wifi: rtw89: coex: Clear BT link weight when BT is disabled
  2026-07-30  6:02 [PATCH rtw-next 0/7] wifi: rtw89: 8922d: fix and cleanup coex code and enable RTL8922DE Ping-Ke Shih
  2026-07-30  6:02 ` [PATCH rtw-next 1/7] wifi: rtw89: coex: Fix Bluetooth link weight not updated on profile change Ping-Ke Shih
  2026-07-30  6:02 ` [PATCH rtw-next 2/7] wifi: rtw89: coex: Fix BT-info parsing for 5/6 GHz band & dual Bluetooth Ping-Ke Shih
@ 2026-07-30  6:02 ` Ping-Ke Shih
  2026-07-30  6:02 ` [PATCH rtw-next 4/7] wifi: rtw89: coex: Change Wi-Fi link_mode_v0 translating timing Ping-Ke Shih
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Ping-Ke Shih @ 2026-07-30  6:02 UTC (permalink / raw)
  To: linux-wireless; +Cc: ku920601

From: Ching-Te Ku <ku920601@realtek.com>

When a BT device is disabled, _update_bt_link_cnt() is no longer called
for that device, so its link_weight[] retains stale values from the last
active period. _set_bind_info() then computes a non-zero band score for
the disabled device, which can lead to an incorrect tdd_bind.rf_band
selection and ultimately wrong coexistence policy.

Clear link_weight[] for any disabled BT device at the start of the
_set_bind_info() loop so that stale scores are not carried forward.

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 | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index d5b1c68539d9..ac3d0c63f930 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -8167,6 +8167,10 @@ static void _set_bind_info(struct rtw89_btc *btc, u8 type)
 	memset(bd, 0, sizeof(*bd));
 	/* compare BT 2GHz/5GHz profile by link-weighting */
 	for (i = 0; i < BTC_BT_BMAX; i++) {
+		if (!cx->bt0.enable.now)
+			cx->bt0.link_weight[i] = 0;
+		if (!cx->bt1.enable.now)
+			cx->bt1.link_weight[i] = 0;
 		link_weight[BTC_BT_1ST][i] = cx->bt0.link_weight[i];
 		link_weight[BTC_BT_2ND][i] = cx->bt1.link_weight[i];
 		link_weight[BTC_BT_EXT][i] = cx->bt_ext.link_weight[i];
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH rtw-next 4/7] wifi: rtw89: coex: Change Wi-Fi link_mode_v0 translating timing
  2026-07-30  6:02 [PATCH rtw-next 0/7] wifi: rtw89: 8922d: fix and cleanup coex code and enable RTL8922DE Ping-Ke Shih
                   ` (2 preceding siblings ...)
  2026-07-30  6:02 ` [PATCH rtw-next 3/7] wifi: rtw89: coex: Clear BT link weight when BT is disabled Ping-Ke Shih
@ 2026-07-30  6:02 ` Ping-Ke Shih
  2026-07-30  6:02 ` [PATCH rtw-next 5/7] wifi: rtw89: coex: Port _update_bt_ctrl_lps() for BT profile-based LPS control Ping-Ke Shih
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Ping-Ke Shih @ 2026-07-30  6:02 UTC (permalink / raw)
  To: linux-wireless; +Cc: ku920601

From: Ching-Te Ku <ku920601@realtek.com>

Logic should only get explicit link_mode only, to cover the old branch
link_mode_v0 using (old branch firmware needed) should do translating
after link_mode is settled. And the coexistence logic has already updated
to new branch style, so the logic should use new link_mode, don't need
to consider link_mode_v0. To prevent unexpected logic bug, refine the
related logic.

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 | 247 ++++++++++------------
 1 file changed, 112 insertions(+), 135 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index ac3d0c63f930..2f06fcf0d67f 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -4095,15 +4095,10 @@ static void _set_rf_trx_para(struct rtw89_dev *rtwdev)
 
 	if (bmode == BTC_WLINK_NOLINK) {
 		return;
-	} else if (btc->ver->fwlrole == 10) {
-		if (rf_band == RTW89_BAND_5G) {
-			mode = BTC_WLINK_V0_5G;
-		} else if (rf_band == RTW89_BAND_2G &&
-			   bmode == BTC_WLINK_STA) {
-			mode = BTC_WLINK_V0_2G_STA;
-		}
-	} else {
-		mode = r->link_mode_v0;
+	} else if (rf_band == RTW89_BAND_5G) {
+		mode = BTC_WLINK_V0_5G;
+	} else if (rf_band == RTW89_BAND_2G && bmode == BTC_WLINK_STA) {
+		mode = BTC_WLINK_V0_2G_STA;
 	}
 
 	/* decide trx_para_level */
@@ -6212,14 +6207,15 @@ static void _set_btg_ctrl(struct rtw89_dev *rtwdev)
 	if (btc->ant_type == BTC_ANT_SHARED) {
 		if (!(bt->run_patch_code && bt->enable.now))
 			is_btg = BTC_BTGCTRL_DISABLE;
-		else if (wl_rinfo->link_mode_v0 != BTC_WLINK_V0_5G)
+		else if (wl->rf_band_map[RTW89_MAC_0] & BIT(RTW89_BAND_2G) ||
+			 wl->rf_band_map[RTW89_MAC_1] & BIT(RTW89_BAND_2G))
 			is_btg = BTC_BTGCTRL_ENABLE;
 		else
 			is_btg = BTC_BTGCTRL_DISABLE;
 
 		/* bb call ctrl_btg() in WL FW by slot */
 		if (!btc->ver->fcxosi &&
-		    wl_rinfo->link_mode_v0 == BTC_WLINK_V0_25G_MCC)
+		    wl_rinfo->link_mode == BTC_WLINK_DB_MCC)
 			is_btg = BTC_BTGCTRL_BB_GNT_FWCTRL;
 	}
 
@@ -7107,25 +7103,17 @@ void _update_dbcc_band(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
 #define BTC_CHK_HANG_MAX 3
 #define BTC_SCB_INV_VALUE GENMASK(31, 0)
 
-static u8 _get_role_link_mode(struct rtw89_btc_wl_role_info *r, u8 role, bool notv10)
+static u8 _get_role_link_mode(u8 role)
 {
 	switch (role) {
 	case RTW89_WIFI_ROLE_STATION:
 	default:
-		if (notv10)
-			r->link_mode_v0 = BTC_WLINK_V0_2G_STA;
 		return BTC_WLINK_STA;
 	case RTW89_WIFI_ROLE_P2P_GO:
-		if (notv10)
-			r->link_mode_v0 = BTC_WLINK_V0_2G_GO;
 		return BTC_WLINK_GO;
 	case RTW89_WIFI_ROLE_P2P_CLIENT:
-		if (notv10)
-			r->link_mode_v0 = BTC_WLINK_V0_2G_GC;
 		return BTC_WLINK_GC;
 	case RTW89_WIFI_ROLE_AP:
-		if (notv10)
-			r->link_mode_v0 = BTC_WLINK_V0_2G_AP;
 		return BTC_WLINK_AP;
 	}
 }
@@ -7144,13 +7132,12 @@ static bool _chk_role_ch_group(const struct rtw89_btc_chdef *r1,
 }
 
 static u8 _chk_dbcc(struct rtw89_dev *rtwdev, struct rtw89_btc_chdef *ch,
-		    u8 *phy, u8 *role, u8 link_cnt, bool notv10)
+		    u8 *phy, u8 *role, u8 link_cnt)
 {
 	struct rtw89_btc_wl_info *wl = &rtwdev->btc.cx.wl;
 	struct rtw89_btc_wl_role_info *rinfo = &wl->role_info;
 	bool is_2g_ch_exist = false, is_multi_role_in_2g_phy = false;
 	u8 j, k, dbcc_2g_cid = 0, dbcc_2g_cid2 = 0;
-	u8 mode;
 
 	/* find out the 2G-PHY by connect-id ->ch  */
 	for (j = 0; j < link_cnt; j++) {
@@ -7161,12 +7148,8 @@ static u8 _chk_dbcc(struct rtw89_dev *rtwdev, struct rtw89_btc_chdef *ch,
 	}
 
 	/* If no any 2G-port exist, it's impossible because 5G-exclude */
-	if (!is_2g_ch_exist) {
-		mode = BTC_WLINK_SB_MCC;
-		if (notv10)
-			rinfo->link_mode_v0 = BTC_WLINK_V0_5G;
-		return mode;
-	}
+	if (!is_2g_ch_exist)
+		return BTC_WLINK_SB_MCC;
 
 	dbcc_2g_cid = j;
 	rinfo->dbcc_2g_phy = phy[dbcc_2g_cid];
@@ -7178,7 +7161,7 @@ static u8 _chk_dbcc(struct rtw89_dev *rtwdev, struct rtw89_btc_chdef *ch,
 
 	/* connect_cnt <= 2 */
 	if (link_cnt < BTC_TDMA_WLROLE_MAX)
-		return _get_role_link_mode(rinfo, role[dbcc_2g_cid], notv10);
+		return _get_role_link_mode(role[dbcc_2g_cid]);
 
 	/* find the other-port in the 2G-PHY, ex: PHY-0:6G, PHY1: mcc/scc */
 	for (k = 0; k < link_cnt; k++) {
@@ -7194,33 +7177,24 @@ static u8 _chk_dbcc(struct rtw89_dev *rtwdev, struct rtw89_btc_chdef *ch,
 
 	/* Single-role in 2G-PHY */
 	if (!is_multi_role_in_2g_phy)
-		return _get_role_link_mode(rinfo, role[dbcc_2g_cid], notv10);
+		return _get_role_link_mode(role[dbcc_2g_cid]);
 
 	/* 2-role in 2G-PHY */
-	if (ch[dbcc_2g_cid2].center_ch > 14) {
-		if (notv10)
-			rinfo->link_mode_v0 = BTC_WLINK_V0_25G_MCC;
+	if (ch[dbcc_2g_cid2].center_ch > 14)
 		return BTC_WLINK_DB_MCC;
-	} else if (_chk_role_ch_group(&ch[dbcc_2g_cid], &ch[dbcc_2g_cid2])) {
-		if (notv10)
-			rinfo->link_mode_v0 = BTC_WLINK_V0_2G_SCC;
+	else if (_chk_role_ch_group(&ch[dbcc_2g_cid], &ch[dbcc_2g_cid2]))
 		return BTC_WLINK_SCC;
-	} else {
-		if (notv10)
-			rinfo->link_mode_v0 = BTC_WLINK_V0_2G_MCC;
+	else
 		return BTC_WLINK_SB_MCC;
-	}
 }
 
 static void _update_wl_link_mode(struct rtw89_dev *rtwdev, u8 hw_band, u8 type)
 {
 	struct rtw89_btc *btc = &rtwdev->btc;
-	const struct rtw89_btc_ver *ver = btc->ver;
 	struct rtw89_btc_wl_info *wl = &btc->cx.wl;
 	struct rtw89_btc_wl_mlo_info *mlo_info = &wl->mlo_info;
 	struct rtw89_btc_wl_role_info *r = &wl->role_info;
 	u8 p2p_exist = wl->role_info.p2p_exist;
-	u8 rver = ver->fwlrole;
 
 	if (hw_band == RTW89_PHY_1)
 		p2p_exist = wl->role_info.p2p_exist_hb1;
@@ -7240,20 +7214,6 @@ static void _update_wl_link_mode(struct rtw89_dev *rtwdev, u8 hw_band, u8 type)
 		} else {
 			r->link_mode = BTC_WLINK_STA;
 		}
-
-		if (rver >= 10 && rver < 100)
-			break;
-
-		if (mlo_info->hwb_rf_band[hw_band] != RTW89_BAND_2G) {
-			r->link_mode_v0 = BTC_WLINK_V0_5G;
-		} else if (mlo_info->wmode[hw_band] == RTW89_MR_WMODE_1AP) {
-			r->link_mode_v0 = BTC_WLINK_V0_2G_GO;
-		} else if (mlo_info->wmode[hw_band] == RTW89_MR_WMODE_1CLIENT) {
-			if (wl->role_info.p2p_2g)
-				r->link_mode_v0 = BTC_WLINK_V0_2G_GC;
-			else
-				r->link_mode_v0 = BTC_WLINK_V0_2G_STA;
-		}
 		break;
 	case RTW89_MR_WTYPE_NONMLD_NONMLD: /* Non_MLO 2-role 2+0/0+2 */
 	case RTW89_MR_WTYPE_MLD1L1R_NONMLD: /* MLO only-1 link + P2P 2+0/0+2 */
@@ -7268,36 +7228,12 @@ static void _update_wl_link_mode(struct rtw89_dev *rtwdev, u8 hw_band, u8 type)
 		} else {
 			r->link_mode = BTC_WLINK_SCC;
 		}
-
-		if (rver >= 10 && rver < 100)
-			break;
-
-		if (mlo_info->hwb_rf_band[hw_band] != RTW89_BAND_2G) {
-			r->link_mode_v0 = BTC_WLINK_V0_5G;
-		} else if (mlo_info->ch_type[hw_band] == RTW89_MR_CTX2_2GHZ_5GHZ ||
-			   mlo_info->ch_type[hw_band] == RTW89_MR_CTX2_2GHZ_6GHZ) {
-			r->link_mode_v0 = BTC_WLINK_V0_25G_MCC;
-		} else if (mlo_info->ch_type[hw_band] == RTW89_MR_CTX2_2GHZ) {
-			r->link_mode_v0 = BTC_WLINK_V0_2G_MCC;
-		} else if (mlo_info->ch_type[hw_band] == RTW89_MR_CTX1_2GHZ) {
-			r->link_mode_v0 = BTC_WLINK_V0_2G_SCC;
-		}
 		break;
 	case RTW89_MR_WTYPE_MLD2L1R: /* MLO_MLSR 2+0/0+2 */
 		if (p2p_exist) /* MLO_MLSR only support STA/GC */
 			r->link_mode = BTC_WLINK_GC;
 		else
 			r->link_mode = BTC_WLINK_STA;
-
-		if (rver >= 10 && rver < 100)
-			break;
-
-		if (mlo_info->hwb_rf_band[hw_band] != RTW89_BAND_2G)
-			r->link_mode_v0 = BTC_WLINK_V0_5G;
-		else if (wl->role_info.p2p_2g)
-			r->link_mode_v0 = BTC_WLINK_V0_2G_GC;
-		else
-			r->link_mode_v0 = BTC_WLINK_V0_2G_STA;
 		break;
 	case RTW89_MR_WTYPE_MLD2L1R_NONMLD: /* MLO_MLSR + P2P 2+0/0+2 */
 	case RTW89_MR_WTYPE_MLD2L2R_NONMLD: /* MLO_MLMR + P2P 1+1/2+2*/
@@ -7306,29 +7242,10 @@ static void _update_wl_link_mode(struct rtw89_dev *rtwdev, u8 hw_band, u8 type)
 		 * 5G only -> TDMA slot switch by E5G
 		 */
 		r->link_mode = BTC_WLINK_DB_MCC;
-
-		if (rver >= 10 && rver < 100)
-			break;
-
-		r->link_mode_v0 = BTC_WLINK_V0_25G_MCC;
 		break;
 	case RTW89_MR_WTYPE_MLD2L2R: /* MLO_MLMR  1+1/2+2 */
 		/* MLMR only support STA now (2024) */
 		r->link_mode = BTC_WLINK_STA;
-
-		if (rver >= 10 && rver < 100)
-			break;
-
-		if (mlo_info->hwb_rf_band[hw_band] != RTW89_BAND_2G) {
-			r->link_mode_v0 = BTC_WLINK_V0_5G;
-		} else if (mlo_info->wmode[hw_band] == RTW89_MR_WMODE_1AP) {
-			r->link_mode_v0 = BTC_WLINK_V0_2G_GO;
-		} else if (mlo_info->wmode[hw_band] == RTW89_MR_WMODE_1CLIENT) {
-			if (wl->role_info.p2p_2g)
-				r->link_mode_v0 = BTC_WLINK_V0_2G_GC;
-			else
-				r->link_mode_v0 = BTC_WLINK_V0_2G_STA;
-		}
 		break;
 	}
 }
@@ -7494,8 +7411,6 @@ static void _update_wl_non_mlo_info(struct rtw89_dev *rtwdev)
 	u8 cid_role[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER] = {};
 	u8 cid_phy[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER] = {};
 	bool b2g = false, b5g = false, outloop = false;
-	bool notv10 = rtwdev->btc.ver->fwlrole != 10;
-	u8 mode_v0 = BTC_WLINK_V0_NOLINK;
 	u8 mode = BTC_WLINK_NOLINK;
 	u8 cnt_2g = 0, cnt_5g = 0;
 	u8 i, j, cnt = 0;
@@ -7540,33 +7455,72 @@ static void _update_wl_non_mlo_info(struct rtw89_dev *rtwdev)
 	/* Be careful to change the following sequence!! */
 	if (cnt == 0) {
 		mode = BTC_WLINK_NOLINK;
-		mode_v0 = BTC_WLINK_V0_NOLINK;
 	} else if (wl_rinfo->dbcc_en) {
 		/* update pta_req_band to 2.4GHz HW-BAND for DBCC = 1*/
-		mode = _chk_dbcc(rtwdev, cid_ch, cid_phy, cid_role, cnt, notv10);
-		mode_v0 = wl_rinfo->link_mode_v0;
-	} else if (!b2g && b5g && notv10) {
-		mode = _get_role_link_mode(wl_rinfo, cid_role[0], notv10);
-		mode_v0 = BTC_WLINK_V0_5G;
+		mode = _chk_dbcc(rtwdev, cid_ch, cid_phy, cid_role, cnt);
+	} else if (!b2g && b5g) {
+		mode = _get_role_link_mode(cid_role[0]);
 	} else if (b2g && b5g) {
 		mode = BTC_WLINK_DB_MCC;
-		mode_v0 = BTC_WLINK_V0_25G_MCC;
 	} else if (cnt >= 2) {
-		if (_chk_role_ch_group(&cid_ch[0], &cid_ch[1])) {
+		if (_chk_role_ch_group(&cid_ch[0], &cid_ch[1]))
 			mode = BTC_WLINK_SCC;
-			mode_v0 = BTC_WLINK_V0_2G_SCC;
-		} else {
+		else
 			mode = BTC_WLINK_SB_MCC;
-			mode_v0 = BTC_WLINK_V0_2G_MCC;
-		}
 	} else {
-		mode = _get_role_link_mode(wl_rinfo, cid_role[0], notv10);
-		mode_v0 = wl_rinfo->link_mode_v0;
+		mode = _get_role_link_mode(cid_role[0]);
 	}
 
 	wl_rinfo->link_mode = mode;
 	wl_rinfo->link_mode_hb1 = mode;
-	wl_rinfo->link_mode_v0 = mode_v0;
+}
+
+static void _sync_wl_link_mode_v0(struct rtw89_dev *rtwdev)
+{
+	struct rtw89_btc_wl_role_info *r = &rtwdev->btc.cx.wl.role_info;
+	bool has_2g = false;
+	int i, j;
+
+	for (i = 0; i < RTW89_BE_BTC_WL_MAX_ROLE_NUMBER && !has_2g; i++)
+		for (j = 0; j < RTW89_MAC_NUM && !has_2g; j++)
+			if (r->rlink[i][j].connected &&
+			    r->rlink[i][j].rf_band == RTW89_BAND_2G)
+				has_2g = true;
+
+	if (!has_2g && r->link_mode != BTC_WLINK_NOLINK) {
+		r->link_mode_v0 = BTC_WLINK_V0_5G;
+		return;
+	}
+
+	switch (r->link_mode) {
+	case BTC_WLINK_NOLINK:
+		r->link_mode_v0 = BTC_WLINK_V0_NOLINK;
+		break;
+	case BTC_WLINK_STA:
+		r->link_mode_v0 = BTC_WLINK_V0_2G_STA;
+		break;
+	case BTC_WLINK_AP:
+		r->link_mode_v0 = BTC_WLINK_V0_2G_AP;
+		break;
+	case BTC_WLINK_GO:
+		r->link_mode_v0 = BTC_WLINK_V0_2G_GO;
+		break;
+	case BTC_WLINK_GC:
+		r->link_mode_v0 = BTC_WLINK_V0_2G_GC;
+		break;
+	case BTC_WLINK_SCC:
+		r->link_mode_v0 = BTC_WLINK_V0_2G_SCC;
+		break;
+	case BTC_WLINK_SB_MCC:
+		r->link_mode_v0 = BTC_WLINK_V0_2G_MCC;
+		break;
+	case BTC_WLINK_DB_MCC:
+		r->link_mode_v0 = BTC_WLINK_V0_25G_MCC;
+		break;
+	default:
+		r->link_mode_v0 = BTC_WLINK_V0_OTHER;
+		break;
+	}
 }
 
 static void _modify_role_link_mode(struct rtw89_dev *rtwdev, u8 hw_band)
@@ -7746,6 +7700,7 @@ static void _update_wl_info(struct rtw89_dev *rtwdev, struct rtw89_btc_wl_link_i
 	}
 
 	_modify_role_link_mode(rtwdev, rlink_id);
+	_sync_wl_link_mode_v0(rtwdev);
 
 	if ((rlink_id == RTW89_PHY_0 && wl_rinfo->link_mode != link_mode_ori) ||
 	    (rlink_id == RTW89_PHY_1 && wl_rinfo->link_mode_hb1 != link_mode_ori)) {
@@ -7827,28 +7782,16 @@ static void _update_bt_scbd(struct rtw89_dev *rtwdev, u8 bid)
 {
 	struct rtw89_btc_bt_link_info *bt_2g, *bt_56g;
 	struct rtw89_btc *btc = &rtwdev->btc;
-	const struct rtw89_btc_ver *ver = btc->ver;
 	struct rtw89_btc_cx *cx = &btc->cx;
-	struct rtw89_btc_wl_info *wl = &cx->wl;
 	struct rtw89_btc_dm *dm = &btc->dm;
 	struct rtw89_btc_bt_info *bt;
 	u32 val, any_bt_connect, any_bt_6g_connect = 0;
-	u8 id, id_start, id_stop, mode = 0;
-	bool bt_link_change = false;
-	bool lps_ctrl = false;
+	bool bt_link_change = false, lps_ctrl = false;
+	u8 id, id_start, id_stop;
 
 	if (!rtwdev->chip->scbd || bid > BTC_ALL_BT)
 		return;
 
-	if (ver->fwlrole == 10) {
-		if (wl->role_info.link_mode == BTC_WLINK_STA &&
-		    (dm->tdd_en && wl->rf_band_map[RTW89_MAC_0] &
-		     BIT(RTW89_BAND_2G)))
-			mode = BTC_WLINK_V0_2G_STA;
-	} else {
-		mode = wl->role_info.link_mode_v0;
-	}
-
 	if (bid == BTC_ALL_BT) {
 		id_start = BTC_BT_1ST;
 		id_stop = BTC_BT_2ND;
@@ -7937,10 +7880,9 @@ static void _update_bt_scbd(struct rtw89_dev *rtwdev, u8 bid)
 		}
 
 		/* 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_V0_2G_STA) ||
+		if (bt->link_info.a2dp_desc.exist ||
+		    bt->link_info.pan_desc.exist ||
+		    bt->link_info.hfp_desc.exist ||
 		    bt->whql_test)
 			lps_ctrl = true;
 
@@ -8468,7 +8410,8 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
 	struct rtw89_btc_wl_info *wl = &btc->cx.wl;
 	struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
 	u8 mode = btc->dm.tdd_bind.wl_link_mode;
-	u8 mode_v0 = wl->role_info.link_mode_v0;
+	u8 mode_v0 = BTC_WLINK_V0_OTHER;
+	bool has_2ghz;
 
 	lockdep_assert_wiphy(rtwdev->hw->wiphy);
 
@@ -8601,6 +8544,40 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
 			mode_v0 = BTC_WLINK_V0_OTHER;
 			break;
 		}
+	} else {
+		/* No binding (out_of_band): derive mode_v0 from link_mode + rf_band_map */
+		has_2ghz = wl->rf_band_map[RTW89_MAC_0] & BIT(RTW89_BAND_2G) ||
+			   wl->rf_band_map[RTW89_MAC_1] & BIT(RTW89_BAND_2G);
+
+		if (!has_2ghz) {
+			mode_v0 = BTC_WLINK_V0_5G;
+		} else if (mode == BTC_WLINK_DB_MCC) {
+			mode_v0 = BTC_WLINK_V0_25G_MCC;
+		} else {
+			switch (mode) {
+			case BTC_WLINK_STA:
+				mode_v0 = BTC_WLINK_V0_2G_STA;
+				break;
+			case BTC_WLINK_AP:
+				mode_v0 = BTC_WLINK_V0_2G_AP;
+				break;
+			case BTC_WLINK_GO:
+				mode_v0 = BTC_WLINK_V0_2G_GO;
+				break;
+			case BTC_WLINK_GC:
+				mode_v0 = BTC_WLINK_V0_2G_GC;
+				break;
+			case BTC_WLINK_SCC:
+				mode_v0 = BTC_WLINK_V0_2G_SCC;
+				break;
+			case BTC_WLINK_SB_MCC:
+				mode_v0 = BTC_WLINK_V0_2G_MCC;
+				break;
+			default:
+				mode_v0 = BTC_WLINK_V0_OTHER;
+				break;
+			}
+		}
 	}
 
 	switch (mode_v0) {
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH rtw-next 5/7] wifi: rtw89: coex: Port _update_bt_ctrl_lps() for BT profile-based LPS control
  2026-07-30  6:02 [PATCH rtw-next 0/7] wifi: rtw89: 8922d: fix and cleanup coex code and enable RTL8922DE Ping-Ke Shih
                   ` (3 preceding siblings ...)
  2026-07-30  6:02 ` [PATCH rtw-next 4/7] wifi: rtw89: coex: Change Wi-Fi link_mode_v0 translating timing Ping-Ke Shih
@ 2026-07-30  6:02 ` Ping-Ke Shih
  2026-07-30  6:02 ` [PATCH rtw-next 6/7] wifi: rtw89: coex: Update Wi-Fi/Bluetooth coexistence version to 9.24.1 Ping-Ke Shih
  2026-07-30  6:02 ` [PATCH rtw-next 7/7] wifi: rtw89: 8922d: enable Makefile and Kconfig for RTL8922DE Ping-Ke Shih
  6 siblings, 0 replies; 8+ messages in thread
From: Ping-Ke Shih @ 2026-07-30  6:02 UTC (permalink / raw)
  To: linux-wireless; +Cc: ku920601

From: Ching-Te Ku <ku920601@realtek.com>

The old lps_ctrl_scbd logic in _update_bt_scbd() blocked WiFi LPS only
when mode == BTC_WLINK_V0_2G_STA, which created a dead-lock while
WiFi already in LPS suppressed TDD binding so mode was never set to
BTC_WLINK_V0_2G_STA, lps_ctrl_scbd stayed 0, and WiFi remained stuck
in LPS. Port _update_bt_ctrl_lps() from the reference implementation to
check BT profile existence (A2DP, HFP, PAN) for both radios directly,
with out_of_band and freerun guards so LPS is only blocked when WiFi and
Bluetooth actually share a band. Call it from both _update_bt_scbd() and
_update_bt_info() so profile changes reported via either SCBD or BT info
C2H correctly update lps_ctrl_scbd. Also remove the dead
lps_ctrl_scbd_last field.

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 | 51 +++++++++++++++--------
 drivers/net/wireless/realtek/rtw89/core.h |  1 -
 2 files changed, 33 insertions(+), 19 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index 2f06fcf0d67f..39dff9fdc1cd 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -3238,8 +3238,6 @@ static void _fw_set_policy(struct rtw89_dev *rtwdev, u16 policy_type,
 	else
 		btc->btc_ctrl_lps = dm->lps_ctrl_scbd;
 
-	dm->lps_ctrl_scbd_last = dm->lps_ctrl_scbd;
-
 	if (btc->btc_ctrl_lps == 1)
 		rtw89_set_coex_ctrl_lps(rtwdev, btc->btc_ctrl_lps);
 
@@ -7778,6 +7776,35 @@ void rtw89_coex_rfk_chk_work(struct wiphy *wiphy, struct wiphy_work *work)
 	}
 }
 
+static void _update_bt_ctrl_lps(struct rtw89_dev *rtwdev)
+{
+	struct rtw89_btc *btc = &rtwdev->btc;
+	struct rtw89_btc_bt_info *bt0 = &btc->cx.bt0;
+	struct rtw89_btc_bt_info *bt1 = &btc->cx.bt1;
+	struct rtw89_btc_dm *dm = &btc->dm;
+	bool lps_ctrl = false;
+
+	if (dm->out_of_band || dm->freerun)
+		lps_ctrl = false;
+	else if (bt0->whql_test || bt1->whql_test)
+		lps_ctrl = true;
+	else if (bt0->link_info.a2dp_desc.exist ||
+		 bt0->link_info.hfp_desc.exist ||
+		 bt0->link_info.pan_desc.exist)
+		lps_ctrl = true;
+	else if (bt1->link_info.a2dp_desc.exist ||
+		 bt1->link_info.hfp_desc.exist ||
+		 bt1->link_info.pan_desc.exist)
+		lps_ctrl = true;
+
+	if (dm->lps_ctrl_scbd != lps_ctrl) {
+		dm->lps_ctrl_scbd = lps_ctrl;
+		dm->lps_ctrl_change = true;
+	} else {
+		dm->lps_ctrl_change = false;
+	}
+}
+
 static void _update_bt_scbd(struct rtw89_dev *rtwdev, u8 bid)
 {
 	struct rtw89_btc_bt_link_info *bt_2g, *bt_56g;
@@ -7786,7 +7813,7 @@ static void _update_bt_scbd(struct rtw89_dev *rtwdev, u8 bid)
 	struct rtw89_btc_dm *dm = &btc->dm;
 	struct rtw89_btc_bt_info *bt;
 	u32 val, any_bt_connect, any_bt_6g_connect = 0;
-	bool bt_link_change = false, lps_ctrl = false;
+	bool bt_link_change = false;
 	u8 id, id_start, id_stop;
 
 	if (!rtwdev->chip->scbd || bid > BTC_ALL_BT)
@@ -7879,25 +7906,12 @@ static void _update_bt_scbd(struct rtw89_dev *rtwdev, u8 bid)
 			bt_56g->status.map.connect = any_bt_6g_connect;
 		}
 
-		/* if specific profile exist */
-		if (bt->link_info.a2dp_desc.exist ||
-		    bt->link_info.pan_desc.exist ||
-		    bt->link_info.hfp_desc.exist ||
-		    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->run_patch_code = !!(val & BTC_BSCB_PATCH_CODE);
 		bt->scbd = val;
 	}
 
+	_update_bt_ctrl_lps(rtwdev);
+
 	if (bt_link_change) {
 		rtw89_debug(rtwdev, RTW89_DBG_BTC,
 			    "[BTC], %s: bt status change!!\n", __func__);
@@ -9136,6 +9150,7 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 bid, u8 *buf, u32 len)
 					 RTW89_COEX_BT_DEVINFO_WORK_PERIOD);
 	}
 
+	_update_bt_ctrl_lps(rtwdev);
 	_run_coex(rtwdev, BTC_RSN_UPDATE_BT_INFO);
 }
 
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index bc9db0c16473..34187b6c820b 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -4116,7 +4116,6 @@ struct rtw89_btc_dm {
 	u8 fdd_en: 1;
 	u8 tdd_en: 1;
 	u8 lps_ctrl_scbd: 1;
-	u8 lps_ctrl_scbd_last: 1;
 	u8 lps_ctrl_change: 1;
 	u8 bis_tdma: 1; /* BIS TDMA mode active */
 	u8 scbd_write_instant;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH rtw-next 6/7] wifi: rtw89: coex: Update Wi-Fi/Bluetooth coexistence version to 9.24.1
  2026-07-30  6:02 [PATCH rtw-next 0/7] wifi: rtw89: 8922d: fix and cleanup coex code and enable RTL8922DE Ping-Ke Shih
                   ` (4 preceding siblings ...)
  2026-07-30  6:02 ` [PATCH rtw-next 5/7] wifi: rtw89: coex: Port _update_bt_ctrl_lps() for BT profile-based LPS control Ping-Ke Shih
@ 2026-07-30  6:02 ` Ping-Ke Shih
  2026-07-30  6:02 ` [PATCH rtw-next 7/7] wifi: rtw89: 8922d: enable Makefile and Kconfig for RTL8922DE Ping-Ke Shih
  6 siblings, 0 replies; 8+ messages in thread
From: Ping-Ke Shih @ 2026-07-30  6:02 UTC (permalink / raw)
  To: linux-wireless; +Cc: ku920601

From: Ching-Te Ku <ku920601@realtek.com>

The 9.24.1 coexistence version included firmware 0.35.111.X support for
RTL8922A/D, 0.24.97.X support for RTL8852C, 0.29.133.X support for
RTL8852B chip family.

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 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index 39dff9fdc1cd..5a9dc4d8a00b 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 0x09180013
+#define RTW89_COEX_VERSION 0x09180113
 #define FCXDEF_STEP 50 /* MUST <= FCXMAX_STEP and match with wl fw*/
 #define BTC_E2G_LIMIT_DEF 80
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH rtw-next 7/7] wifi: rtw89: 8922d: enable Makefile and Kconfig for RTL8922DE
  2026-07-30  6:02 [PATCH rtw-next 0/7] wifi: rtw89: 8922d: fix and cleanup coex code and enable RTL8922DE Ping-Ke Shih
                   ` (5 preceding siblings ...)
  2026-07-30  6:02 ` [PATCH rtw-next 6/7] wifi: rtw89: coex: Update Wi-Fi/Bluetooth coexistence version to 9.24.1 Ping-Ke Shih
@ 2026-07-30  6:02 ` Ping-Ke Shih
  6 siblings, 0 replies; 8+ messages in thread
From: Ping-Ke Shih @ 2026-07-30  6:02 UTC (permalink / raw)
  To: linux-wireless; +Cc: ku920601

RTL8922DE is a WiFi 7 chipset, supporting 2x2 2GHz/5GHz/6GHz 4096/1024-QAM
160MHz channels. As STA, AP and P2P modes work well, enable this chipset.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
 drivers/net/wireless/realtek/rtw89/Kconfig  | 15 +++++++++++++++
 drivers/net/wireless/realtek/rtw89/Makefile |  7 +++++++
 2 files changed, 22 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw89/Kconfig b/drivers/net/wireless/realtek/rtw89/Kconfig
index 7200a944260f..7c678dd1f6b3 100644
--- a/drivers/net/wireless/realtek/rtw89/Kconfig
+++ b/drivers/net/wireless/realtek/rtw89/Kconfig
@@ -41,6 +41,9 @@ config RTW89_8852C
 config RTW89_8922A
 	tristate
 
+config RTW89_8922D
+	tristate
+
 config RTW89_8851BE
 	tristate "Realtek 8851BE PCI wireless network (Wi-Fi 6) adapter"
 	depends on PCI
@@ -169,6 +172,18 @@ config RTW89_8922AU
 	  802.11be USB wireless network (Wi-Fi 7) adapter
 	  supporting 2x2 2GHz/5GHz/6GHz 4096-QAM 160MHz channels.
 
+config RTW89_8922DE
+	tristate "Realtek 8922DE/8922DE-VS PCI wireless network (Wi-Fi 7) adapter"
+	depends on PCI
+	select RTW89_CORE
+	select RTW89_PCI
+	select RTW89_8922D
+	help
+	  Select this option will enable support for 8922DE/8922DE-VS chipset
+
+	  802.11be PCIe wireless network (Wi-Fi 7) adapter
+	  supporting 2x2 2GHz/5GHz/6GHz 4096/1024-QAM 160MHz channels.
+
 config RTW89_DEBUG
 	bool
 
diff --git a/drivers/net/wireless/realtek/rtw89/Makefile b/drivers/net/wireless/realtek/rtw89/Makefile
index 5536714e0268..a85b7785330c 100644
--- a/drivers/net/wireless/realtek/rtw89/Makefile
+++ b/drivers/net/wireless/realtek/rtw89/Makefile
@@ -91,6 +91,13 @@ rtw89_8922ae-objs := rtw8922ae.o
 obj-$(CONFIG_RTW89_8922AU) += rtw89_8922au.o
 rtw89_8922au-objs := rtw8922au.o
 
+obj-$(CONFIG_RTW89_8922D) += rtw89_8922d.o
+rtw89_8922d-objs := rtw8922d.o \
+		    rtw8922d_rfk.o
+
+obj-$(CONFIG_RTW89_8922DE) += rtw89_8922de.o
+rtw89_8922de-objs := rtw8922de.o
+
 rtw89_core-$(CONFIG_RTW89_DEBUG) += debug.o
 rtw89_core-$(CONFIG_RTW89_LEDS) += led.o
 rtw89_core-$(CONFIG_RTW89_LEDS_MC) += led_mc.o
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-07-30  6:03 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-30  6:02 [PATCH rtw-next 0/7] wifi: rtw89: 8922d: fix and cleanup coex code and enable RTL8922DE Ping-Ke Shih
2026-07-30  6:02 ` [PATCH rtw-next 1/7] wifi: rtw89: coex: Fix Bluetooth link weight not updated on profile change Ping-Ke Shih
2026-07-30  6:02 ` [PATCH rtw-next 2/7] wifi: rtw89: coex: Fix BT-info parsing for 5/6 GHz band & dual Bluetooth Ping-Ke Shih
2026-07-30  6:02 ` [PATCH rtw-next 3/7] wifi: rtw89: coex: Clear BT link weight when BT is disabled Ping-Ke Shih
2026-07-30  6:02 ` [PATCH rtw-next 4/7] wifi: rtw89: coex: Change Wi-Fi link_mode_v0 translating timing Ping-Ke Shih
2026-07-30  6:02 ` [PATCH rtw-next 5/7] wifi: rtw89: coex: Port _update_bt_ctrl_lps() for BT profile-based LPS control Ping-Ke Shih
2026-07-30  6:02 ` [PATCH rtw-next 6/7] wifi: rtw89: coex: Update Wi-Fi/Bluetooth coexistence version to 9.24.1 Ping-Ke Shih
2026-07-30  6:02 ` [PATCH rtw-next 7/7] wifi: rtw89: 8922d: enable Makefile and Kconfig for RTL8922DE Ping-Ke Shih

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.