From: Ping-Ke Shih <pkshih@realtek.com>
To: <linux-wireless@vger.kernel.org>
Cc: <ku920601@realtek.com>
Subject: [PATCH rtw-next 8/9] wifi: rtw89: coex: Update scoreboard related logic for dual Bluetooth
Date: Fri, 3 Jul 2026 19:43:10 +0800 [thread overview]
Message-ID: <20260703114311.2609942-9-pkshih@realtek.com> (raw)
In-Reply-To: <20260703114311.2609942-1-pkshih@realtek.com>
From: Ching-Te Ku <ku920601@realtek.com>
Update WiFi status to each Bluetooth & collect status from the two
Bluetooth adapter by non-stop power zone register. To correct the meaning
of variable, redefine the naming for the variables.
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 | 525 ++++++++++++++--------
drivers/net/wireless/realtek/rtw89/coex.h | 9 +
drivers/net/wireless/realtek/rtw89/core.c | 4 +-
drivers/net/wireless/realtek/rtw89/core.h | 33 +-
4 files changed, 370 insertions(+), 201 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index 86833b0cd47c..d45fab32ab46 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -461,7 +461,14 @@ enum btc_b2w_scoreboard {
BTC_BSCB_BT_LNAB1 = BIT(10),
BTC_BSCB_WLRFK = BIT(11),
BTC_BSCB_BT_HILNA = BIT(13),
+ BTC_BSCB_BT_HILNA_56G = BIT(14),
+ BTC_BSCB_CTCODE = BIT(15),
BTC_BSCB_BT_CONNECT = BIT(16),
+ BTC_BSCB_BT_CONNECT_56G = BIT(17),
+ BTC_BSCB_BT_LNAB0_56G = BIT(18),
+ BTC_BSCB_BT_LNAB1_56G = BIT(19),
+ BTC_BSCB_BT_15DOT4 = BIT(24),
+ BTC_BSCB_BT_PROTECT = BIT(27),
BTC_BSCB_PAN_ACT = BIT(28),
BTC_BSCB_HFP_ACT = BIT(29),
BTC_BSCB_PATCH_CODE = BIT(30),
@@ -808,6 +815,8 @@ enum btc_reset_module {
BTC_RESET_CXDM = BIT(0) | BIT(1),
BTC_RESET_BTINFO = BIT(3),
BTC_RESET_MDINFO = BIT(4),
+ BTC_RESET_BT_PSD_DM = BIT(5),
+ BTC_RESET_BTINFO2 = BIT(6),
BTC_RESET_ALL = GENMASK(7, 0),
};
@@ -905,8 +914,9 @@ enum btc_reason_and_action {
static void _run_coex(struct rtw89_dev *rtwdev,
enum btc_reason_and_action reason);
-static void _write_scbd(struct rtw89_dev *rtwdev, u32 val, bool state);
-static void _update_bt_scbd(struct rtw89_dev *rtwdev, bool only_update);
+static void _write_scbd(struct rtw89_dev *rtwdev, u8 bid, u32 val, bool state);
+static u8 _sned_h2c_w2bscbd(struct rtw89_dev *rtwdev, bool force_exec, u8 bid);
+static void _update_bt_scbd(struct rtw89_dev *rtwdev, u8 bid);
static int _send_fw_cmd(struct rtw89_dev *rtwdev, u8 h2c_class, u8 h2c_func,
void *param, u16 len)
@@ -1272,11 +1282,6 @@ static void _chk_btc_err(struct rtw89_dev *rtwdev, u8 type, u32 cnt)
dm->cnt_dm[BTC_DCNT_BTCNT_HANG]++;
else
dm->cnt_dm[BTC_DCNT_BTCNT_HANG] = 0;
-
- if ((dm->cnt_dm[BTC_DCNT_BTCNT_HANG] >= BTC_CHK_HANG_MAX &&
- bt->enable.now) || (!dm->cnt_dm[BTC_DCNT_BTCNT_HANG] &&
- !bt->enable.now))
- _update_bt_scbd(rtwdev, false);
break;
case BTC_DCNT_WL_SLOT_DRIFT:
if (cnt >= BTC_CHK_WLSLOT_DRIFT_MAX)
@@ -1755,7 +1760,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
rtwdev->chip->ops->btc_update_bt_cnt(rtwdev);
_chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0);
- bt->bcnt[BTC_BCNT_POLUT] =
+ bt->bcnt[BTC_BCNT_POLLUTED] =
rtw89_mac_get_plt_cnt(rtwdev,
RTW89_MAC_0);
}
@@ -1778,7 +1783,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_LO_TX]);
bt->bcnt[BTC_BCNT_LOPRI_RX] =
le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_LO_RX]);
- bt->bcnt[BTC_BCNT_POLUT] =
+ bt->bcnt[BTC_BCNT_POLLUTED] =
le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_POLLUTED]);
_chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0);
@@ -1810,7 +1815,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_LO_TX]);
bt->bcnt[BTC_BCNT_LOPRI_RX] =
le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_LO_RX]);
- bt->bcnt[BTC_BCNT_POLUT] =
+ bt->bcnt[BTC_BCNT_POLLUTED] =
le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_POLLUTED]);
_chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0);
@@ -1837,7 +1842,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_LO_TX_V105]);
bt->bcnt[BTC_BCNT_LOPRI_RX] =
le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_LO_RX_V105]);
- bt->bcnt[BTC_BCNT_POLUT] =
+ bt->bcnt[BTC_BCNT_POLLUTED] =
le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_POLLUTED_V105]);
_chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0);
@@ -2791,14 +2796,14 @@ static void _fw_set_policy(struct rtw89_dev *rtwdev, u16 policy_type,
if (dm->tdma.rxflctrl == CXFLC_NULLP ||
dm->tdma.rxflctrl == CXFLC_QOSNULL)
- btc->lps = 1;
+ btc->btc_ctrl_lps = 1;
else
- btc->lps = dm->lps_ctrl_scbd;
+ btc->btc_ctrl_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);
+ if (btc->btc_ctrl_lps == 1)
+ rtw89_set_coex_ctrl_lps(rtwdev, btc->btc_ctrl_lps);
ret = _send_fw_cmd(rtwdev, BTFC_SET, SET_CX_POLICY,
btc->policy, btc->policy_len);
@@ -2813,8 +2818,8 @@ static void _fw_set_policy(struct rtw89_dev *rtwdev, u16 policy_type,
if (btc->update_policy_force)
btc->update_policy_force = false;
- if (btc->lps == 0)
- rtw89_set_coex_ctrl_lps(rtwdev, btc->lps);
+ if (btc->btc_ctrl_lps == 0)
+ rtw89_set_coex_ctrl_lps(rtwdev, btc->btc_ctrl_lps);
}
static void _fw_set_drv_info(struct rtw89_dev *rtwdev, u8 index)
@@ -2913,21 +2918,35 @@ void btc_fw_event(struct rtw89_dev *rtwdev, u8 evt_id, void *data, u32 len)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
+ u8 i;
- rtw89_debug(rtwdev, RTW89_DBG_BTC,
- "[BTC], %s(): evt_id:%d len:%d\n",
- __func__, evt_id, len);
+ _parse_btc_report(rtwdev, pfwinfo, data, len);
- if (!len || !data)
+ if (!rtwdev->chip->scbd)
return;
- switch (evt_id) {
- case BTF_EVNT_RPT:
- _parse_btc_report(rtwdev, pfwinfo, data, len);
- break;
- default:
- break;
+ if (!btc->dm.scbd_b2w_update)
+ return; /* skip if init or no-update */
+
+ for (i = BTC_BT_1ST; i <= BTC_BT_2ND; i++) {
+ bt = (i == BTC_BT_1ST) ? &btc->cx.bt0 : &btc->cx.bt1;
+
+ if (bt->scbd_c2h != bt->scbd_rb) {
+ /* if btx b2w scbd non-sync */
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "[BTC], %s() bt%d:c2h->0x%08x, rb->0x%08x\n",
+ __func__, i, bt->scbd_c2h, bt->scbd_rb);
+ bt->scbd_c2h = bt->scbd_rb;
+ _update_bt_scbd(rtwdev, i);
+ btc->dm.scbd_b2w_update = false;
+ }
}
+
+ if (!btc->dm.scbd_b2w_update)
+ _run_coex(rtwdev, BTC_RSN_UPDATE_BT_SCBD);
+ else
+ btc->dm.scbd_b2w_update = 0;
}
static void _set_gnt(struct rtw89_dev *rtwdev, u8 phy_map, u8 wl_state, u8 bt_state)
@@ -3298,7 +3317,7 @@ static void _set_bt_rx_gain(struct rtw89_dev *rtwdev, bool force_exec, u8 bid,
if (buf[0] != BTC_BT_RX_NORMAL_LVL)
state = true;
- _write_scbd(rtwdev, scbd_bit, state);
+ _write_scbd(rtwdev, bid, scbd_bit, state);
}
}
@@ -3406,7 +3425,7 @@ static void _set_rf_trx_para(struct rtw89_dev *rtwdev)
if (dm->fddt_train) {
_set_wl_rx_gain(rtwdev, 1, RTW89_PHY_0);
- _write_scbd(rtwdev, BTC_WSCB_RXGAIN, true);
+ _write_scbd(rtwdev, bid, BTC_WSCB_RXGAIN, true);
} else {
_set_wl_tx_power(rtwdev, para.wl_tx_power[RTW89_PHY_0], RTW89_PHY_0);
_set_wl_rx_gain(rtwdev, para.wl_rx_gain[RTW89_PHY_0], RTW89_PHY_0);
@@ -3899,14 +3918,22 @@ static void _set_tdma_bind(struct rtw89_dev *rtwdev, bool tdma_on)
struct rtw89_btc_dm *dm = &rtwdev->btc.dm;
struct rtw89_btc_bind_info *bind;
u8 null_role = RTW89_WIFI_ROLE_STATION;
+ u8 bt_sel;
if (dm->tdd_en)
bind = &dm->tdd_bind; /* tdd = 1 && fdd = 0 or 1 */
else
bind = &dm->fdd_bind; /* tdd = 0 && fdd = 1 */
+ if (bind->bt_sel >= (BIT(BTC_BT_1ST) | BIT(BTC_BT_2ND)))
+ bt_sel = BTC_ALL_BT;
+ else if (bind->bt_sel == BIT(BTC_BT_2ND))
+ bt_sel = BTC_BT_2ND;
+ else
+ bt_sel = BTC_BT_1ST;
+
/* notify BT TDMA on/off by scoreboard for ACL/Scan schedule */
- _write_scbd(rtwdev, BTC_WSCB_TDMA, tdma_on);
+ _write_scbd(rtwdev, bt_sel, BTC_WSCB_TDMA, tdma_on);
/*
* set hwb/bt bind to TDMA policy parameter
@@ -5849,7 +5876,7 @@ static void _set_bt_rx_agc(struct rtw89_dev *rtwdev)
if (bt_hi_lna_rx == bt->hi_lna_rx)
return;
- _write_scbd(rtwdev, BTC_WSCB_BT_HILNA, bt_hi_lna_rx);
+ _write_scbd(rtwdev, BTC_BT_1ST, BTC_WSCB_BT_HILNA, bt_hi_lna_rx);
}
static void _set_bt_rx_scan_pri(struct rtw89_dev *rtwdev)
@@ -5857,7 +5884,8 @@ static void _set_bt_rx_scan_pri(struct rtw89_dev *rtwdev)
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
- _write_scbd(rtwdev, BTC_WSCB_RXSCAN_PRI, (bool)(!!bt->scan_rx_low_pri));
+ _write_scbd(rtwdev, BTC_ALL_BT, BTC_WSCB_RXSCAN_PRI,
+ (bool)(!!bt->scan_rx_low_pri));
}
static void _wl_req_mac(struct rtw89_dev *rtwdev, u8 mac)
@@ -5897,6 +5925,7 @@ static void _action_common(struct rtw89_dev *rtwdev)
struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_btc_dm *dm = &btc->dm;
u32 bt_rom_code_id, bt_fw_ver;
+ u8 i;
if (btc->ver->fwlrole == 8)
_wl_req_mac(rtwdev, rinfo_v8->pta_req_band);
@@ -5929,13 +5958,8 @@ static void _action_common(struct rtw89_dev *rtwdev)
rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_MREG, 1);
}
- if (wl->scbd_change) {
- rtw89_mac_cfg_sb(rtwdev, wl->scbd);
- rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], write scbd: 0x%08x\n",
- wl->scbd);
- wl->scbd_change = false;
- wl->wcnt[BTC_WCNT_SCBDUPDATE]++;
- }
+ for (i = BTC_BT_1ST; i <= BTC_BT_2ND; i++)
+ _sned_h2c_w2bscbd(rtwdev, false, i);
if (btc->ver->fcxosi) {
if (memcmp(&dm->ost_info_last, &dm->ost_info,
@@ -6187,42 +6211,97 @@ static void _action_wl_2g_nan(struct rtw89_dev *rtwdev)
}
}
-static u32 _read_scbd(struct rtw89_dev *rtwdev)
+static u8 _sned_h2c_w2bscbd(struct rtw89_dev *rtwdev, bool force_exec, u8 bid)
{
- const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_btc *btc = &rtwdev->btc;
- u32 scbd_val = 0;
+ struct rtw89_btc_cx *cx = &btc->cx;
+ struct rtw89_btc_wl_info *wl = &cx->wl;
+ u8 cnt_idx = BTC_WCNT_SCBDUPDATE;
+ u8 h2c_func = SET_IOFLD_SCBD;
+ u8 buf[4];
- if (!chip->scbd)
- return 0;
+ if (bid == BTC_BT_2ND) {
+ if (!(rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT))
+ return 0;
+
+ h2c_func |= BT_H2C_FUNC_BT2ND;
+ cnt_idx = BTC_WCNT_SCBDUPDATE2;
+ }
- scbd_val = rtw89_mac_get_sb(rtwdev);
- rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], read scbd: 0x%08x\n",
- scbd_val);
+ if (wl->scbd_chg[bid] || force_exec) {
+ /* Add delay to avoid BT FW loss information */
- btc->cx.bt0.bcnt[BTC_BCNT_SCBDREAD]++;
- return scbd_val;
+ btc_dw2b(buf, 0, (wl->scbd[bid] | BIT(31))); /* trig */
+ if (rtwdev->chip->para_ver & BTC_FEAT_H2C_MACRO) {
+ if (!_send_fw_cmd(rtwdev, BTFC_SET,
+ h2c_func, buf, sizeof(buf)))
+ return 0;
+ } else {
+ rtw89_mac_cfg_sb(rtwdev, wl->scbd[bid]);
+ }
+ wl->scbd_chg[bid] = 0;
+ wl->wcnt[cnt_idx]++;
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "[BTC], %s() write BT%d scbd:0x%08x\n",
+ __func__, bid, wl->scbd[bid]);
+ }
+ return 1;
}
-static void _write_scbd(struct rtw89_dev *rtwdev, u32 val, bool state)
+static void _write_scbd(struct rtw89_dev *rtwdev, u8 bid, u32 val, bool state)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- u32 scbd_val = 0;
- u8 force_exec = false;
+ struct rtw89_btc_dm *dm = &btc->dm;
+ u8 force_exec, id, id_start, id_stop;
+ u32 scbd = 0;
if (!chip->scbd)
return;
- scbd_val = state ? wl->scbd | val : wl->scbd & ~val;
+ if (bid == BTC_ALL_BT) {
+ id_start = BTC_BT_1ST;
+ id_stop = BTC_BT_2ND;
+ } else {
+ id_start = bid;
+ id_stop = bid;
+ }
- if (val & BTC_WSCB_ACTIVE || val & BTC_WSCB_ON)
- force_exec = true;
+ for (id = id_start; id <= id_stop; id++) {
+ force_exec = false;
+ if (!(rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT) &&
+ id == BTC_BT_2ND)
+ continue;
- if (scbd_val != wl->scbd || force_exec) {
- wl->scbd = scbd_val;
- wl->scbd_change = true;
+ if (state)
+ scbd = wl->scbd[id] | val;
+ else
+ scbd = wl->scbd[id] & (~val);
+
+ if (val & BTC_WSCB_CTCODE ||
+ val & BTC_WSCB_RXGAIN ||
+ val & BTC_WSCB_RXGAIN_56G) { /* instant exec */
+ force_exec = true;
+ wl->scbd[id] = scbd;
+ dm->scbd_write_instant = 1;
+ if (rtwdev->chip->para_ver & BTC_FEAT_H2C_MACRO)
+ _sned_h2c_w2bscbd(rtwdev, force_exec, id);
+ else
+ rtw89_mac_cfg_sb(rtwdev, wl->scbd[id]);
+ dm->scbd_write_instant = 0;
+ } else if ((val & BTC_WSCB_ACTIVE ||
+ val & BTC_WSCB_ON ||
+ val & BTC_WSCB_WLRFK) ||
+ scbd != wl->scbd[id]) {
+ /*
+ * Just update wl->scbd[] and set wl->scbd_chg[],
+ * moved "Write scoreboard I/O" to _action_common()
+ * _write_scbd will be executed if run_coex()
+ */
+ wl->scbd[id] = scbd;
+ wl->scbd_chg[id] = 1;
+ }
}
}
@@ -7522,34 +7601,27 @@ void rtw89_coex_rfk_chk_work(struct wiphy *wiphy, struct wiphy_work *work)
wl->wcnt[BTC_WCNT_RFK_TIMEOUT]++;
dm->error.map.wl_rfk_timeout = true;
wl->rfk_info.state = BTC_WRFK_STOP;
- _write_scbd(rtwdev, BTC_WSCB_WLRFK, false);
+ _write_scbd(rtwdev, BTC_ALL_BT, BTC_WSCB_WLRFK, false);
_run_coex(rtwdev, BTC_RSN_RFK_CHK_WORK);
}
}
-static void _update_bt_scbd(struct rtw89_dev *rtwdev, bool only_update)
+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;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
const struct rtw89_btc_ver *ver = btc->ver;
- 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 (rtwdev->chip->scbd)
- return;
-
- rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s\n", __func__);
+ 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;
+ bool bt_link_change = false;
+ bool lps_ctrl = false;
- val = _read_scbd(rtwdev);
- if (val == BTC_SCB_INV_VALUE) {
- rtw89_debug(rtwdev, RTW89_DBG_BTC,
- "[BTC], %s(): return by invalid scbd value\n",
- __func__);
+ if (!rtwdev->chip->scbd || bid > BTC_ALL_BT)
return;
- }
if (ver->fwlrole == 0)
mode = wl->role_info.link_mode;
@@ -7564,66 +7636,112 @@ static void _update_bt_scbd(struct rtw89_dev *rtwdev, bool only_update)
else
return;
- if (!(val & BTC_BSCB_ON))
- bt->enable.now = 0;
- else
- bt->enable.now = 1;
+ if (bid == BTC_ALL_BT) {
+ id_start = BTC_BT_1ST;
+ id_stop = BTC_BT_2ND;
+ } else {
+ id_start = bid;
+ id_stop = bid;
+ }
+
+ dm->lps_ctrl_change = false;
+ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s()\n", __func__);
- if (bt->enable.now != bt->enable.last)
- bt_link_change = true;
+ for (id = id_start; id <= id_stop; id++) {
+ bt = (id == BTC_BT_1ST) ? &cx->bt0 : &cx->bt1;
+ bt_2g = &bt->link_info;
+ bt_56g = &bt->link_info_56g;
- /* reset bt info if bt re-enable */
- if (bt->enable.now && !bt->enable.last) {
- _reset_btc_var(rtwdev, BTC_RESET_BTINFO);
- bt->bcnt[BTC_BCNT_REENABLE]++;
- bt->enable.now = 1;
- }
+ if (!(rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT) && id == BTC_BT_2ND)
+ break;
+
+ val = bt->scbd_c2h;
- bt->enable.last = bt->enable.now;
- bt->scbd = val;
- bt->mbx_avl = !!(val & BTC_BSCB_ACT);
+ if (val == 0xffffffff) {
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "[BTC], %s return by invalid scbd value\n",
+ __func__);
+ return;
+ }
- if (bt->whql_test != !!(val & BTC_BSCB_WHQL))
- bt_link_change = true;
+ if (!(val & BTC_BSCB_ON))
+ bt->enable.now = 0;
+ else
+ bt->enable.now = 1;
- 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);
+ if (bt->enable.now != bt->enable.last)
+ bt_link_change = true;
- bt->lna_constrain = !!(val & BTC_BSCB_BT_LNAB0) +
- !!(val & BTC_BSCB_BT_LNAB1) * 2 + 4;
+ /* reset bt info if bt re-enable */
+ if (bt->enable.now && !bt->enable.last) {
+ if (id == BTC_BT_1ST)
+ _reset_btc_var(rtwdev, BTC_RESET_BTINFO);
+ else
+ _reset_btc_var(rtwdev, BTC_RESET_BTINFO2);
- /* if rfk run 1->0 */
- if (bt->rfk_info.map.run && !(val & BTC_BSCB_RFK_RUN))
- bt_link_change = true;
+ bt->bcnt[BTC_BCNT_REENABLE]++;
+ bt->enable.now = 1;
+ bt->rf_band_map = BIT(RTW89_BAND_2G);
+ bt->link_weight[BTC_BT_B2G] = 5; /* no-profile */
+ }
+ bt->enable.last = bt->enable.now;
- 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);
- any_bt_connect = !!(val & BTC_BSCB_BT_CONNECT);
+ /* if BT will disconnect and adopt protect plan */
+ if ((val & BTC_BSCB_BT_PROTECT) &&
+ !(bt->scbd & BTC_BSCB_BT_PROTECT))
+ bt->bcnt[BTC_BCNT_PROTECT]++;
- /* if connect change */
- if (bt->link_info.status.map.connect != any_bt_connect)
- bt_link_change = true;
+ bt->mbx_avl = !!(val & BTC_BSCB_ACT);
+ if (bt->whql_test != !!(val & BTC_BSCB_WHQL))
+ 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;
+ bt->whql_test = !!(val & BTC_BSCB_WHQL);
+ bt->btg_type = (val & BTC_BSCB_BT_S1 ? BTC_BT_BTG : BTC_BT_ALONE);
- 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_2g->a2dp_desc.exist = !!(val & BTC_BSCB_A2DP_ACT);
+ bt_2g->pan_desc.exist = !!(val & BTC_BSCB_PAN_ACT);
+ bt_2g->hfp_desc.exist = !!(val & BTC_BSCB_HFP_ACT);
- bt->link_info.status.map.connect = any_bt_connect;
- bt->run_patch_code = !!(val & BTC_BSCB_PATCH_CODE);
+ bt->lna_constrain = 4 + !!(val & BTC_BSCB_BT_LNAB0) +
+ !!(val & BTC_BSCB_BT_LNAB1) * 2;
+
+ if (rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT) {
+ if (val & BTC_BSCB_BT_15DOT4)
+ bt->func_type |= (BTC_BTF_THREAD | BTC_BTF_ZB);
+ else
+ bt->func_type &= ~(BTC_BTF_THREAD | BTC_BTF_ZB);
+ }
+
+ bt->hi_lna_rx = !!(val & BTC_BSCB_BT_HILNA);
+ any_bt_connect = !!(val & BTC_BSCB_BT_CONNECT);
+
+ /* if connect change */
+ if (bt_2g->status.map.connect != any_bt_connect ||
+ bt_56g->status.map.connect != any_bt_6g_connect) {
+ bt_link_change = true;
+ bt_2g->status.map.connect = any_bt_connect;
+ 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) &&
+ 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->run_patch_code = !!(val & BTC_BSCB_PATCH_CODE);
+ bt->scbd = val;
+ }
if (bt_link_change) {
rtw89_debug(rtwdev, RTW89_DBG_BTC,
@@ -7651,26 +7769,6 @@ static void _update_bt_txpwr_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
memcpy(&b->bt_txpwr_desc, &buf[2], sizeof(b->bt_txpwr_desc));
}
-static bool _chk_wl_rfk_request(struct rtw89_dev *rtwdev)
-{
- struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_cx *cx = &btc->cx;
- struct rtw89_btc_bt_info *bt = &cx->bt0;
-
- _update_bt_scbd(rtwdev, true);
-
- cx->wl.wcnt[BTC_WCNT_RFK_REQ]++;
-
- if ((bt->rfk_info.map.run || bt->rfk_info.map.req) &&
- !bt->rfk_info.map.timeout) {
- cx->wl.wcnt[BTC_WCNT_RFK_REJECT]++;
- } else {
- cx->wl.wcnt[BTC_WCNT_RFK_GO]++;
- return true;
- }
- return false;
-}
-
static void _set_bind_info(struct rtw89_btc *btc, u8 type)
{
struct rtw89_btc_cx *cx = &btc->cx;
@@ -8181,7 +8279,7 @@ void rtw89_btc_ntfy_poweroff(struct rtw89_dev *rtwdev)
btc->cx.wl.status.map.busy = 0;
wl->status.map.lps = BTC_LPS_OFF;
- _write_scbd(rtwdev, BTC_WSCB_ALL, false);
+ _write_scbd(rtwdev, BTC_ALL_BT, BTC_WSCB_ALL, false);
_run_coex(rtwdev, BTC_RSN_NTFY_POWEROFF);
rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_ALL, 0);
@@ -8266,24 +8364,22 @@ void rtw89_btc_ntfy_init(struct rtw89_dev *rtwdev, u8 mode)
return;
}
+ btc->cx.bt0.enable.now = 1;
+ btc->cx.bt0.run_patch_code = 1;
if (rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT) {
btc->cx.bt1.enable.now = 1;
btc->cx.bt1.run_patch_code = 1;
}
- if (rtwdev->chip->para_ver & BTC_FEAT_H2C_MACRO) {
- btc->cx.bt0.enable.now = 1;
- btc->cx.bt0.run_patch_code = 1;
+ if (rtwdev->chip->para_ver & BTC_FEAT_H2C_MACRO)
btc->io_oflld_type = BTC_IO_OFLD_BTC_H2C;
- } else {
+ else
btc->io_oflld_type = BTC_IO_OFLD_NO_SUPPORT;
- _update_bt_scbd(rtwdev, true);
- }
chip->ops->btc_set_rfe(rtwdev);
chip->ops->btc_init_cfg(rtwdev);
- _write_scbd(rtwdev,
+ _write_scbd(rtwdev, BTC_ALL_BT,
BTC_WSCB_ACTIVE | BTC_WSCB_ON | BTC_WSCB_BTLOG, true);
if (rtw89_mac_get_ctrl_path(rtwdev)) {
@@ -8842,16 +8938,16 @@ void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_sta
if (rf_state == BTC_RFCTRL_WL_ON) {
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);
+ _write_scbd(rtwdev, BTC_ALL_BT, val, true);
chip->ops->btc_init_cfg(rtwdev);
} else {
rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_ALL, false);
if (rf_state == BTC_RFCTRL_FW_CTRL)
- _write_scbd(rtwdev, BTC_WSCB_ACTIVE, false);
+ _write_scbd(rtwdev, BTC_ALL_BT, BTC_WSCB_ACTIVE, false);
else if (rf_state == BTC_RFCTRL_WL_OFF)
- _write_scbd(rtwdev, BTC_WSCB_ALL, false);
+ _write_scbd(rtwdev, BTC_ALL_BT, BTC_WSCB_ALL, false);
else
- _write_scbd(rtwdev, BTC_WSCB_ACTIVE, false);
+ _write_scbd(rtwdev, BTC_ALL_BT, BTC_WSCB_ACTIVE, false);
}
btc->dm.cnt_dm[BTC_DCNT_BTCNT_HANG] = 0;
@@ -8883,27 +8979,26 @@ static bool _ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_path,
switch (state) {
case BTC_WRFK_START:
- result = _chk_wl_rfk_request(rtwdev);
- wl->rfk_info.state = result ? BTC_WRFK_START : BTC_WRFK_STOP;
-
- _write_scbd(rtwdev, BTC_WSCB_WLRFK, result);
+ result = BTC_WRFK_ALLOW;
+ wl->rfk_info.state = BTC_WRFK_START;
+ btc->cx.wl.wcnt[BTC_WCNT_RFK_REQ]++;
+ btc->cx.wl.wcnt[BTC_WCNT_RFK_GO]++;
btc->dm.cnt_notify[BTC_NCNT_WL_RFK]++;
+
+ _write_scbd(rtwdev, BTC_ALL_BT, BTC_WSCB_WLRFK, true);
break;
case BTC_WRFK_ONESHOT_START:
case BTC_WRFK_ONESHOT_STOP:
- if (wl->rfk_info.state == BTC_WRFK_STOP) {
- result = BTC_WRFK_REJECT;
- } else {
- result = BTC_WRFK_ALLOW;
- wl->rfk_info.state = state;
- }
+ wl->rfk_info.state = state;
+ if (type != BTC_WRFKT_RXDCK)
+ return BTC_WRFK_ALLOW;
break;
case BTC_WRFK_STOP:
result = BTC_WRFK_ALLOW;
wl->rfk_info.state = BTC_WRFK_STOP;
- _write_scbd(rtwdev, BTC_WSCB_WLRFK, false);
+ _write_scbd(rtwdev, BTC_ALL_BT, BTC_WSCB_WLRFK, false);
wiphy_delayed_work_cancel(rtwdev->hw->wiphy, &rtwdev->coex_rfk_chk_work);
break;
default:
@@ -8927,7 +9022,7 @@ static bool _ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_path,
"[BTC], %s()_finish: rfk_cnt=%d, result=%d\n",
__func__, btc->dm.cnt_notify[BTC_NCNT_WL_RFK], result);
- return result == BTC_WRFK_ALLOW;
+ return result;
}
void rtw89_btc_ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_map,
@@ -9160,7 +9255,7 @@ void rtw89_btc_ntfy_wl_sta(struct rtw89_dev *rtwdev)
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): busy=%d\n",
__func__, !!wl->status.map.busy);
- _write_scbd(rtwdev, BTC_WSCB_WLBUSY, (!!wl->status.map.busy));
+ _write_scbd(rtwdev, BTC_ALL_BT, BTC_WSCB_WLBUSY, (!!wl->status.map.busy));
if (data.is_traffic_change)
_fw_set_drv_info(rtwdev, CXDRVINFO_ROLE);
@@ -9251,6 +9346,7 @@ void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
struct rtw89_btc_bt_info *bt = &rtwdev->btc.cx.bt0;
struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
u8 *buf = &skb->data[RTW89_C2H_HEADER_LEN];
+ u8 bid = BTC_BT_1ST;
len -= RTW89_C2H_HEADER_LEN;
@@ -9261,6 +9357,12 @@ void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
if (class != BTFC_FW_EVENT)
return;
+ if (func & BT_C2H_FUNC_BT2ND) {
+ bid = BTC_BT_2ND;
+ func &= ~BT_C2H_FUNC_BT2ND;
+ bt = &btc->cx.bt1;
+ }
+
func = rtw89_btc_c2h_get_index_by_ver(rtwdev, func);
pfwinfo->cnt_c2h++;
@@ -9280,10 +9382,15 @@ void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
_update_bt_info(rtwdev, buf, len);
break;
case BTF_EVNT_BT_SCBD:
- rtw89_debug(rtwdev, RTW89_DBG_BTC,
- "[BTC], handle C2H BT SCBD with data %8ph\n", buf);
bt->bcnt[BTC_BCNT_SCBDUPDATE]++;
- _update_bt_scbd(rtwdev, false);
+ bt->scbd_c2h = ((buf[3] << 24) | (buf[2] << 16) |
+ (buf[1] << 8) | (buf[0]));
+ bt->scbd_rb = bt->scbd_c2h;
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "[BTC], handle C2H BT%d SCBD with data 0x%08x\n",
+ bid, bt->scbd_c2h);
+ _update_bt_scbd(rtwdev, bid);
+ _run_coex(rtwdev, BTC_RSN_UPDATE_BT_SCBD);
break;
case BTF_EVNT_BT_PSD:
break;
@@ -9300,7 +9407,7 @@ void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
btc->dm.cnt_dm[BTC_DCNT_CX_RUNINFO]++;
break;
case BTF_EVNT_BT_QUERY_TXPWR:
- bt->bcnt[BTC_BCNT_BTTXPWR_UPDATE]++;
+ bt->bcnt[BTC_BCNT_TXPWR_UPDATE]++;
_update_bt_txpwr_info(rtwdev, buf, len);
}
}
@@ -9680,7 +9787,7 @@ static int _show_bt_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
bt->bcnt[BTC_BCNT_HIPRI_TX],
bt->bcnt[BTC_BCNT_LOPRI_RX],
bt->bcnt[BTC_BCNT_LOPRI_TX],
- bt->bcnt[BTC_BCNT_POLUT]);
+ bt->bcnt[BTC_BCNT_POLLUTED]);
if (!bt->scan_info_update) {
rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_SCAN_INFO, true);
@@ -9716,7 +9823,7 @@ static int _show_bt_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
else
rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_TX_PWR_LVL, false);
- if (bt->bcnt[BTC_BCNT_BTTXPWR_UPDATE]) {
+ if (bt->bcnt[BTC_BCNT_TXPWR_UPDATE]) {
p += scnprintf(p, end - p,
" %-15s : br_index:0x%x, le_index:0x%x",
"[bt_txpwr_lvl]",
@@ -10127,7 +10234,7 @@ static int _show_dm_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
p += scnprintf(p, end - p,
" %-15s : wl_only:%d, bt_only:%d, igno_bt:%d, free_run:%d, wl_ps_ctrl:%d, wl_mimo_ps:%d, ",
"[dm_flag]", dm->wl_only, dm->bt_only, igno_bt,
- dm->freerun, btc->lps, dm->wl_mimo_ps);
+ dm->freerun, btc->btc_ctrl_lps, dm->wl_mimo_ps);
p += scnprintf(p, end - p, "leak_ap:%d, fw_offload:%s%s\n",
dm->leak_ap,
@@ -11353,10 +11460,11 @@ static int _show_mreg_v1(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
- struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
struct rtw89_btc_fbtc_mreg_val_v1 *pmreg = NULL;
+ struct rtw89_btc_bt_info *bt0 = &btc->cx.bt0;
+ struct rtw89_btc_bt_info *bt1 = &btc->cx.bt1;
+ struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_mac_ax_coex_gnt gnt_cfg = {};
struct rtw89_mac_ax_gnt gnt;
char *p = buf, *end = buf + bufsz;
@@ -11369,11 +11477,20 @@ static int _show_mreg_v1(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
p += scnprintf(p, end - p, "========== [HW Status] ==========\n");
p += scnprintf(p, end - p,
- " %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)\n",
- "[scoreboard]", wl->scbd,
+ " %-15s : WL->BT0:0x%08x(cnt:%d), BT0->WL:0x%08x(total:%d, bt_update:%d)\n",
+ "[scoreboard]", wl->scbd[BTC_BT_1ST],
wl->wcnt[BTC_WCNT_SCBDUPDATE],
- bt->scbd, bt->bcnt[BTC_BCNT_SCBDREAD],
- bt->bcnt[BTC_BCNT_SCBDUPDATE]);
+ bt0->scbd, bt0->bcnt[BTC_BCNT_SCBDREAD],
+ bt0->bcnt[BTC_BCNT_SCBDUPDATE]);
+
+ if (rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT) {
+ p += scnprintf(p, end - p,
+ " %-15s : WL->BT1:0x%08x(cnt:%d), BT1->WL:0x%08x(total:%d, bt_update:%d)\n",
+ "[scoreboard]", wl->scbd[BTC_BT_2ND],
+ wl->wcnt[BTC_WCNT_SCBDUPDATE2],
+ bt1->scbd, bt1->bcnt[BTC_BCNT_SCBDREAD],
+ bt1->bcnt[BTC_BCNT_SCBDUPDATE]);
+ }
btc->dm.pta_owner = rtw89_mac_get_ctrl_path(rtwdev);
_get_gnt(rtwdev, &gnt_cfg);
@@ -11437,10 +11554,11 @@ static int _show_mreg_v2(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo;
- struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
struct rtw89_btc_fbtc_mreg_val_v2 *pmreg = NULL;
+ struct rtw89_btc_bt_info *bt0 = &btc->cx.bt0;
+ struct rtw89_btc_bt_info *bt1 = &btc->cx.bt1;
+ struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_mac_ax_coex_gnt gnt_cfg = {};
struct rtw89_mac_ax_gnt gnt;
char *p = buf, *end = buf + bufsz;
@@ -11453,11 +11571,20 @@ static int _show_mreg_v2(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
p += scnprintf(p, end - p, "========== [HW Status] ==========\n");
p += scnprintf(p, end - p,
- " %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)\n",
- "[scoreboard]", wl->scbd,
+ " %-15s : WL->BT0:0x%08x(cnt:%d), BT0->WL:0x%08x(total:%d, bt_update:%d)\n",
+ "[scoreboard]", wl->scbd[BTC_BT_1ST],
wl->wcnt[BTC_WCNT_SCBDUPDATE],
- bt->scbd, bt->bcnt[BTC_BCNT_SCBDREAD],
- bt->bcnt[BTC_BCNT_SCBDUPDATE]);
+ bt0->scbd, bt0->bcnt[BTC_BCNT_SCBDREAD],
+ bt0->bcnt[BTC_BCNT_SCBDUPDATE]);
+
+ if (rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT) {
+ p += scnprintf(p, end - p,
+ " %-15s : WL->BT1:0x%08x(cnt:%d), BT1->WL:0x%08x(total:%d, bt_update:%d)\n",
+ "[scoreboard]", wl->scbd[BTC_BT_2ND],
+ wl->wcnt[BTC_WCNT_SCBDUPDATE2],
+ bt1->scbd, bt1->bcnt[BTC_BCNT_SCBDREAD],
+ bt1->bcnt[BTC_BCNT_SCBDUPDATE]);
+ }
btc->dm.pta_owner = rtw89_mac_get_ctrl_path(rtwdev);
_get_gnt(rtwdev, &gnt_cfg);
@@ -11524,8 +11651,9 @@ static int _show_mreg_v7(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
struct rtw89_btc_fbtc_mreg_val_v7 *pmreg = NULL;
struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
struct rtw89_btc_cx *cx = &btc->cx;
+ struct rtw89_btc_bt_info *bt0 = &cx->bt0;
+ struct rtw89_btc_bt_info *bt1 = &cx->bt1;
struct rtw89_btc_wl_info *wl = &cx->wl;
- struct rtw89_btc_bt_info *bt = &cx->bt0;
struct rtw89_mac_ax_gnt *gnt = NULL;
struct rtw89_btc_dm *dm = &btc->dm;
char *p = buf, *end = buf + bufsz;
@@ -11538,11 +11666,20 @@ static int _show_mreg_v7(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
p += scnprintf(p, end - p, "\n\r========== [HW Status] ==========");
p += scnprintf(p, end - p,
- "\n\r %-15s : WL->BT:0x%08x(cnt:%d), BT->WL:0x%08x(total:%d, bt_update:%d)",
- "[scoreboard]", wl->scbd,
+ " %-15s : WL->BT0:0x%08x(cnt:%d), BT0->WL:0x%08x(total:%d, bt_update:%d)\n",
+ "[scoreboard]", wl->scbd[BTC_BT_1ST],
wl->wcnt[BTC_WCNT_SCBDUPDATE],
- bt->scbd, bt->bcnt[BTC_BCNT_SCBDREAD],
- bt->bcnt[BTC_BCNT_SCBDUPDATE]);
+ bt0->scbd, bt0->bcnt[BTC_BCNT_SCBDREAD],
+ bt0->bcnt[BTC_BCNT_SCBDUPDATE]);
+
+ if (rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT) {
+ p += scnprintf(p, end - p,
+ " %-15s : WL->BT1:0x%08x(cnt:%d), BT1->WL:0x%08x(total:%d, bt_update:%d)\n",
+ "[scoreboard]", wl->scbd[BTC_BT_2ND],
+ wl->wcnt[BTC_WCNT_SCBDUPDATE2],
+ bt1->scbd, bt1->bcnt[BTC_BCNT_SCBDREAD],
+ bt1->bcnt[BTC_BCNT_SCBDUPDATE]);
+ }
/* To avoid I/O if WL LPS or power-off */
dm->pta_owner = rtw89_mac_get_ctrl_path(rtwdev);
diff --git a/drivers/net/wireless/realtek/rtw89/coex.h b/drivers/net/wireless/realtek/rtw89/coex.h
index fb151f68eb64..74027ca4eccc 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.h
+++ b/drivers/net/wireless/realtek/rtw89/coex.h
@@ -391,4 +391,13 @@ void _slot_set_tbl(struct rtw89_btc *btc, u8 sid, u32 tbl)
btc->dm.slot.v7[sid].cxtbl = cpu_to_le32(tbl);
}
+static inline
+void btc_dw2b(u8 *buf, size_t idx, u32 val)
+{
+ buf[idx] = u32_get_bits(val, MASKBYTE0);
+ buf[idx + 1] = u32_get_bits(val, MASKBYTE1);
+ buf[idx + 2] = u32_get_bits(val, MASKBYTE2);
+ buf[idx + 3] = u32_get_bits(val, MASKBYTE3);
+}
+
#endif
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 85aeb9e90812..b3376fadf593 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -5417,7 +5417,7 @@ static void rtw89_track_ps_work(struct wiphy *wiphy, struct wiphy_work *work)
if (rtwdev->scanning)
return;
- if (rtwdev->lps_enabled && !rtwdev->btc.lps)
+ if (rtwdev->lps_enabled && !rtwdev->btc.btc_ctrl_lps)
rtw89_enter_lps_track(rtwdev, RTW89_TFC_INTERVAL_100MS);
}
@@ -5465,7 +5465,7 @@ static void rtw89_track_work(struct wiphy *wiphy, struct wiphy_work *work)
rtw89_core_rfkill_poll(rtwdev, false);
rtw89_core_mlo_track(rtwdev);
- if (rtwdev->lps_enabled && !rtwdev->btc.lps)
+ if (rtwdev->lps_enabled && !rtwdev->btc.btc_ctrl_lps)
rtw89_enter_lps_track(rtwdev, RTW89_TFC_INTERVAL_2SEC);
}
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index eb814425f536..8646a13bfd79 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -1415,6 +1415,7 @@ enum rtw89_btc_wl_state_cnt {
BTC_WCNT_RX_ERR_LAST,
BTC_WCNT_RX_ERR_LAST2S,
BTC_WCNT_RX_LAST,
+ BTC_WCNT_SCBDUPDATE2,
BTC_WCNT_NUM
};
@@ -1431,17 +1432,25 @@ enum rtw89_btc_bt_state_cnt {
BTC_BCNT_ROLESW,
BTC_BCNT_AFH,
BTC_BCNT_INFOUPDATE,
+ BTC_BCNT_LEAUDIO_INFOUPDATE,
BTC_BCNT_INFOSAME,
+ BTC_BCNT_LEAUDIO_INFOSAME,
BTC_BCNT_SCBDUPDATE,
BTC_BCNT_HIPRI_TX,
BTC_BCNT_HIPRI_RX,
BTC_BCNT_LOPRI_TX,
BTC_BCNT_LOPRI_RX,
- BTC_BCNT_POLUT,
BTC_BCNT_POLUT_NOW,
BTC_BCNT_POLUT_DIFF,
BTC_BCNT_RATECHG,
- BTC_BCNT_BTTXPWR_UPDATE,
+ BTC_BCNT_AFH_CONFLICT,
+ BTC_BCNT_AFH_LE_CONFLICT,
+ BTC_BCNT_AFH_UPDATE,
+ BTC_BCNT_AFH_LE_UPDATE,
+ BTC_BCNT_AFH_CHN,
+ BTC_BCNT_AFH_LE_CHN,
+ BTC_BCNT_TXPWR_UPDATE,
+ BTC_BCNT_PROTECT,
BTC_BCNT_NUM,
};
@@ -2188,12 +2197,13 @@ struct rtw89_btc_wl_info {
bool pta_reg_mac_chg;
bool bg_mode;
bool he_mode;
- bool scbd_change;
+ bool scbd_chg[BTC_ALL_BT];
bool fw_ver_mismatch;
bool client_cnt_inc_2g;
bool link_mode_chg;
bool dbcc_chg;
- u32 scbd;
+ u32 scbd[BTC_ALL_BT];
+ u32 scbd_rb[BTC_ALL_BT];
u32 wcnt[BTC_WCNT_NUM];
};
@@ -2323,6 +2333,15 @@ enum rtw89_btc_ble_scan_type {
CXSCAN_MAX
};
+enum rtw89_btc_bt_func_type {
+ BTC_BTF_NONE = 0,
+ BTC_BTF_BT = BIT(0),
+ BTC_BTF_ZB = BIT(1),
+ BTC_BTF_THREAD = BIT(2),
+ BTC_BTF_24GPRO = BIT(3), /* 2.4GHz Proprietary */
+ BTC_BTF_ULL = BIT(4),
+};
+
#define RTW89_BTC_BTC_SCAN_V1_FLAG_ENABLE BIT(0)
#define RTW89_BTC_BTC_SCAN_V1_FLAG_INTERLACE BIT(1)
@@ -2394,6 +2413,8 @@ struct rtw89_btc_bt_info {
u8 rsvd: 6;
u32 scbd;
+ u32 scbd_rb;
+ u32 scbd_c2h;
u32 feature;
u32 mbx_avl: 1;
@@ -3338,6 +3359,8 @@ struct rtw89_btc_dm {
u8 lps_ctrl_scbd: 1;
u8 lps_ctrl_scbd_last: 1;
u8 lps_ctrl_change: 1;
+ u8 scbd_write_instant;
+ bool scbd_b2w_update;
};
struct rtw89_btc_ctrl {
@@ -3585,7 +3608,7 @@ struct rtw89_btc {
u32 hubmsg_cnt;
bool bt_req_en;
bool update_policy_force;
- bool lps;
+ bool btc_ctrl_lps;
bool manual_ctrl;
bool cli_h2c_cmd;
};
--
2.25.1
next prev parent reply other threads:[~2026-07-03 11:43 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-03 11:43 [PATCH rtw-next 0/9] wifi: rtw89: coex: implement components for dual Bluetooth Ping-Ke Shih
2026-07-03 11:43 ` [PATCH rtw-next 1/9] wifi: rtw89: coex: Add Init info version 10 Ping-Ke Shih
2026-07-03 11:43 ` [PATCH rtw-next 2/9] wifi: rtw89: coex: add rtw89_btc_init() entry for initialization once Ping-Ke Shih
2026-07-03 11:43 ` [PATCH rtw-next 3/9] wifi: rtw89: coex: Update TDMA descriptor for dual MAC Ping-Ke Shih
2026-07-03 11:43 ` [PATCH rtw-next 4/9] wifi: rtw89: coex: Add Bluetooth binding for Bluetooth TX power setting Ping-Ke Shih
2026-07-03 11:43 ` [PATCH rtw-next 5/9] wifi: rtw89: coex: Add Bluetooth binding for Bluetooth RX gain setting Ping-Ke Shih
2026-07-03 11:43 ` [PATCH rtw-next 6/9] wifi: rtw89: coex: Add WiFi/Bluetooth adapter binding info Ping-Ke Shih
2026-07-03 11:43 ` [PATCH rtw-next 7/9] wifi: rtw89: coex: Add TDMA binding for dual MAC Ping-Ke Shih
2026-07-03 11:43 ` Ping-Ke Shih [this message]
2026-07-03 11:43 ` [PATCH rtw-next 9/9] wifi: rtw89: coex: Add Co-RX logic 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=20260703114311.2609942-9-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