RE: rtw89: BT connect state differs between scoreboard and bt_info on RTL8851B

Ping-Ke Shih posted 1 patch 1 week, 2 days ago
RE: rtw89: BT connect state differs between scoreboard and bt_info on RTL8851B
Posted by Ping-Ke Shih 1 week, 2 days ago
Maxim Skokov <skokovmaksimevg@gmail.com> wrote:
> Same on WL_FW 0.29.41.5, the newest in linux-firmware, with the sink
> connected and playing:
> 
>   [status]     : enable:Y, btg:N, connect:N, mailbox_avl:Y
>   [profile]    : profile: , A2DP_active:Y, PAN_active:N
>   [bt_info]    : raw_data[49 00 d0 00 04 00] (type:auto/cnt:82/same:3)
>   [scoreboard] : BT0->WL:0x40000003(total:0, bt_update:26)
> 
> BTC_BSCB_BT_CONNECT is not set here either.

We found the problem recently, and ongoing to send out the patch. 
Please try the attachment.

diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index 5a9dc4d8a00b..df49f62f566b 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -1000,7 +1000,7 @@ static void _run_coex(struct rtw89_dev *rtwdev,
 		      enum btc_reason_and_action reason);
 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 void _update_bt_scbd(struct rtw89_dev *rtwdev, u8 bid, bool is_c2h);
 static const char *id_to_h2c(u32 id);
 
 static void _reset_h2c_macro(struct rtw89_btc *btc)
@@ -3602,7 +3602,7 @@ void btc_fw_event(struct rtw89_dev *rtwdev, u8 evt_id, void *data, u32 len)
 				    "[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);
+			_update_bt_scbd(rtwdev, i, true);
 			btc->dm.scbd_b2w_update = false;
 		}
 	}
@@ -7805,7 +7805,21 @@ static void _update_bt_ctrl_lps(struct rtw89_dev *rtwdev)
 	}
 }
 
-static void _update_bt_scbd(struct rtw89_dev *rtwdev, u8 bid)
+static u32 _read_scbd(struct rtw89_dev *rtwdev, u8 id)
+{
+	const struct rtw89_chip_info *chip = rtwdev->chip;
+	u32 val;
+
+	if (!chip->scbd)
+		return 0;
+
+	val = rtw89_read32(rtwdev, chip->btc_sb.n[id].get);
+	rtw89_debug(rtwdev, RTW89_DBG_BTC,
+		    "[BTC], read scbd bt%d: 0x%08x\n", id, val);
+	return val;
+}
+
+static void _update_bt_scbd(struct rtw89_dev *rtwdev, u8 bid, bool is_c2h)
 {
 	struct rtw89_btc_bt_link_info *bt_2g, *bt_56g;
 	struct rtw89_btc *btc = &rtwdev->btc;
@@ -7838,7 +7852,7 @@ static void _update_bt_scbd(struct rtw89_dev *rtwdev, u8 bid)
 		if (!(rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT) && id == BTC_BT_2ND)
 			break;
 
-		val = bt->scbd_c2h;
+		val = is_c2h ? bt->scbd_c2h : _read_scbd(rtwdev, id);
 
 		if (val == 0xffffffff) {
 			rtw89_debug(rtwdev, RTW89_DBG_BTC,
@@ -8473,8 +8487,8 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
 
 	_update_run_ctrl_info(rtwdev);
 
-	if (reason == BTC_RSN_NTFY_INIT || reason == BTC_RSN_NTFY_RADIO_STATE)
-		_update_bt_scbd(rtwdev, false);
+	if (reason == BTC_RSN_NTFY_RADIO_STATE)
+		_update_bt_scbd(rtwdev, BTC_ALL_BT, false);
 
 	dm->freerun = false;
 	dm->cnt_dm[BTC_DCNT_RUN]++;
@@ -9814,7 +9828,7 @@ void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
 		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);
+		_update_bt_scbd(rtwdev, bid, true);
 		_run_coex(rtwdev, BTC_RSN_UPDATE_BT_SCBD);
 		break;
 	case BTF_EVNT_BT_PSD:
Re: rtw89: BT connect state differs between scoreboard and bt_info on RTL8851B
Posted by Maxim Skokov 1 week, 2 days ago
> We found the problem recently, and ongoing to send out the patch.
> Please try the attachment.

Applied on 7.3.0-rc1, rebuilt the rtw89 modules only. RTL8851BE,
WL_FW 0.29.41.5.

The hardware read works. With RTW89_DBG_BTC on, during a radio state
change:

  [BTC], read scbd bt0: 0x40000013
  [BTC], read scbd bt0: 0xc0000013

BTC_BSCB_BT_CONNECT, BIT(16), is not set in either value, so the register
holds what the C2H path was already reporting.

status.map.connect still alternates. 90 samples of btc_info, one per
second, with the mechanism reason and the WL link mode beside it:

  16  connect:Y  reason:UPDATE_BT_INFO   link_mode:STA
   1  connect:Y  reason:NTFY_SWBAND      link_mode:STA
  70  connect:N  reason:NTFY_POWEROFF    link_mode:STA
   2  connect:N  reason:UPDATE_BT_SCBD   link_mode:STA
   1  connect:N  reason:NTFY_SCAN_START  link_mode:STA

The same sampling on the unpatched module, 30 samples two seconds apart,
gave 28 N and 2 Y, so this part is unchanged.

The mailbox reports the device as connected throughout:
raw_data[49 01 c9 00 04 00], so raw_info[2] = 0x49 and lb2.connect = 1,
with A2DP_active:Y. The sink was connected and playing for all of the
above, and WL stayed in STA mode, retrying association without completing
it.

Is BTC_BSCB_BT_CONNECT expected to be set by BT firmware on this chip? If
not, status.map.connect will keep being overwritten from the scoreboard
after _update_bt_info() has written it from the mailbox.
RE: rtw89: BT connect state differs between scoreboard and bt_info on RTL8851B
Posted by Ping-Ke Shih 1 week, 1 day ago
Maxim Skokov <skokovmaksimevg@gmail.com> wrote:
> 
> The sink was connected and playing for all of the
> above, and WL stayed in STA mode, retrying association without completing
> it.

To be clear. The problem you encountered was failed to connect an AP, or
this was newly introduced by the patch I shared?

> 
> Is BTC_BSCB_BT_CONNECT expected to be set by BT firmware on this chip? If
> not, status.map.connect will keep being overwritten from the scoreboard
> after _update_bt_info() has written it from the mailbox.

The BTC_BSCB_BT_CONNECT should be set by BT firmware. The internal BT
expert is helping to dig the cause.
Re: rtw89: BT connect state differs between scoreboard and bt_info on RTL8851B
Posted by Maxim Skokov 1 week ago
> To be clear. The problem you encountered was failed to connect an AP, or
> this was newly introduced by the patch I shared?

Not introduced by the patch. It predates it by a day.

On 15 September, with an unmodified driver, the same machine logged 21
"authentication timed out" and one 4WAY_HANDSHAKE_TIMEOUT in a single
boot, with an A2DP sink connected and playing:

  wlp2s0: authentication with 02:0c:43:16:60:e8 timed out
  wlp2s0: deauthenticated from b2:39:56:12:24:f0 (Reason: 15=4WAY_HANDSHAKE_TIMEOUT)

It follows the audio, not the driver build. With the sink stopped,
association completes in a few seconds on both the patched and the
unpatched module; while it plays, the interface stays in STA mode
retrying. That is the coexistence behaviour from the first mail in this
thread. I mentioned it in the last one only to describe the conditions of
the sampling, not as a regression.

> The BTC_BSCB_BT_CONNECT should be set by BT firmware. The internal BT
> expert is helping to dig the cause.

Understood. In case it is relevant to what they find, btc_info here
reports the BT side as

  [coex_version] : BT_FW_coex:0(Mismatch, desired:7)
  [sub_module]   : BT_FW:0x0(patch)

while the mailbox itself works, mailbox_avl:Y and raw_data updating.

I can run any test build you want on RTL8851BE.