From: Ping-Ke Shih <pkshih@realtek.com>
To: <linux-wireless@vger.kernel.org>
Cc: <ku920601@realtek.com>
Subject: [PATCH rtw-next 2/7] wifi: rtw89: coex: Fix BT-info parsing for 5/6 GHz band & dual Bluetooth
Date: Thu, 30 Jul 2026 14:02:15 +0800 [thread overview]
Message-ID: <20260730060220.55844-3-pkshih@realtek.com> (raw)
In-Reply-To: <20260730060220.55844-1-pkshih@realtek.com>
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
next prev parent reply other threads:[~2026-07-30 6:02 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
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
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=20260730060220.55844-3-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 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.