Skip to content

Instantly share code, notes, and snippets.

@nevack
Last active December 19, 2023 00:56
Show Gist options
  • Save nevack/6b36b82d715dc025163d9e9124840a07 to your computer and use it in GitHub Desktop.
Save nevack/6b36b82d715dc025163d9e9124840a07 to your computer and use it in GitHub Desktop.
[ARCHIVED] Fix for CSR Dongle 0a12:0001 ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)

This gist is currenctly archived.

Please refer to previous revisions if you know what to do.

The patch proposed was merged into kernel in 5.8 release, but no longer working as of linux 5.11

@RezaT4795
Copy link

/drivers/bluetooth/btusb.c

Hi, can you please tell me how to apply this patch?

regards, Paulo

Copy and save the patch as a .diff file.
Get the latest linux 5.15.36 LTS source, unpack and cd to it.
apply the patch:
patch -p1 < /path/to/the/patch.diff

start compiling and then use the new kernel.

@NikitaSavc
Copy link

/драйверы/bluetooth/btusb.c

Привет, не могли бы вы сказать мне, как применить этот патч?
с уважением, Пауло

Скопируйте и сохраните исправление в виде файла. Получите последнюю версию исходного кода linux 5.15.36 LTS, распакуйте и к нему. применить патч:.diff``cd patch -p1 < /path/to/the/patch.diff

начните компиляцию, а затем используйте новое ядро.

Okay, where is patch?

@RezaT4795
Copy link

/драйверы/bluetooth/btusb.c

Привет, не могли бы вы сказать мне, как применить этот патч?
с уважением, Пауло

Скопируйте и сохраните исправление в виде файла. Получите последнюю версию исходного кода linux 5.15.36 LTS, распакуйте и к нему. применить патч: .diffcd `` patch -p1 < /path/to/the/patch.diff
начните компиляцию, а затем используйте новое ядро.

Okay, where is patch?

It's right up there in my earlier commets, can't you see?
Here's the comment's link

https://gist.github.com/nevack/6b36b82d715dc025163d9e9124840a07?permalink_comment_id=4119971#gistcomment-4119971

@NikitaSavc
Copy link

/драйверы/bluetooth/btusb.c

Привет, не могли бы вы сказать мне, как применить этот патч? с уважением, Пауло

Скопируйте и сохраните исправление в виде файла. Получите последнюю версию исходного кода linux 5.15.36 LTS, распакуйте и к нему. применить патч:cd '' начните компиляцию, а затем используйте новое ядро. .diff``patch -p1 < /path/to/the/patch.diff

Хорошо, где патч?

Это прямо там, в моих ранних комметах, не так ли? Вот ссылка на комментарий

https://gist.github.com/nevack/6b36b82d715dc025163d9e9124840a07?permalink_comment_id=4119971#gistcomment-4119971

Thank you!

@dreanmer
Copy link

dreanmer commented May 13, 2022

I'm in the same boat with this little guy, tried everything listed here, also tried with the patches from a known bug listed on the arch linux wiki bluetooth page but couldn't even compile the kernel with those patches (https://bugzilla.kernel.org/show_bug.cgi?id=60824) here is some info if someone can help me out:

image
here are some outputs from my tries:

lsusb

Bus 001 Device 024: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)

btmon

Bluetooth monitor ver 5.64
= Note: Linux version 5.15.32-1-MANJARO (x86_64)                                                                                                                                                                                   0.181266
= Note: Bluetooth subsystem version 2.22                           0.181268
= New Index: 00:00:00:00:00:00 (Primary,USB,hci1)                  [hci1] 0.181268
= New Index: 48:E2:44:F6:F3:F4 (Primary,USB,hci0)                  [hci0] 0.181269  # this one (wifi/tb card) is powered off
@ MGMT Open: bluetoothd (privileged) version 1.21

hciconfig -a

hci1:   Type: Primary  Bus: USB
        BD Address: 00:00:00:00:00:00  ACL MTU: 0:0  SCO MTU: 0:0
        DOWN
        RX bytes:14 acl:0 sco:0 events:1 errors:0
        TX bytes:3 acl:0 sco:0 commands:2 errors:1
        Features: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
        Packet type: DM1 DH1 HV1
        Link policy:
        Link mode: PERIPHERAL ACCEPT

hci0:   Type: Primary  Bus: USB
        BD Address: 48:E2:44:F6:F3:F4  ACL MTU: 1021:8  SCO MTU: 64:1
        DOWN

using manjaro latest lts kernel without patches:

mhwd-kernel -li

Currently running: 5.15.32-1-MANJARO (linux515)

sudo hciconfig hci1 up

Can't init device hci1: Connection timed out (110)

dmesg | grep Bluetooth

[68300.546822] Bluetooth: hci1: CSR: Unbranded CSR clone detected; adding workarounds and force-suspending once...
[68305.731582] Bluetooth: hci1: CSR: Failed to suspend the device for our Barrot 8041a02 receive-issue workaround
[68310.851263] Bluetooth: hci1: setting interface failed (110)

using manjaro latest lts kernel with the patch posted above:

https://gist.github.com/nevack/6b36b82d715dc025163d9e9124840a07?permalink_comment_id=4119971#gistcomment-4119971

mhwd-kernel -li

Currently running: 5.15.32-1-MANJARO (linux515)

sudo hciconfig hci0 up

Can't init device hci0: Connection timed out (110)

dmesg | grep Bluetooth

[    4.701306] Bluetooth: hci0: CSR: Unbranded CSR clone detected; adding workarounds and force-suspending once...
[    9.753582] Bluetooth: hci0: CSR: Couldn't suspend the device for our Barrot 8041a02 receive-issue workaround
[   14.873783] Bluetooth: hci0: setting interface failed (110)

using latest stable kernel (without manual patches):

mhwd-kernel -li

Currently running: 5.17.1-3-MANJARO (linux517)

hciconfig hci0 up

Can't init device hci0: Broken pipe (32)

dmesg | grep Bluetooth

[    5.017199] Bluetooth: hci0: CSR: Unbranded CSR clone detected; adding workarounds and force-suspending once...
[   10.176336] Bluetooth: hci0: CSR: Couldn't suspend the device for our Barrot 8041a02 receive-issue workaround
[   12.305840] Bluetooth: hci0: Opcode 0x c03 failed: -110
[  258.608877] Bluetooth: hci0: CSR: Local version failed (-32)

using latest disposable manjaro kernel (5.17.7)

mhwd-kernel -li

Currently running: 5.17.7-1-MANJARO (linux517)

hciconfig hci0 up

Can't init device hci0: Broken pipe (32)

dmesg | grep Bluetooth

[    4.579313] Bluetooth: Core ver 2.22
[    4.579378] Bluetooth: HCI device and connection manager initialized
[    4.579382] Bluetooth: HCI socket layer initialized
[    4.579384] Bluetooth: L2CAP socket layer initialized
[    4.579388] Bluetooth: SCO socket layer initialized
[    4.794437] Bluetooth: hci0: CSR: Unbranded CSR clone detected; adding workarounds and force-suspending once...
[    4.941822] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[    4.941826] Bluetooth: BNEP filters: protocol multicast
[    4.941831] Bluetooth: BNEP socket layer initialized
[    9.959543] Bluetooth: hci0: CSR: Couldn't suspend the device for our Barrot 8041a02 receive-issue workaround
[   12.092630] Bluetooth: hci0: Opcode 0x c03 failed: -110

bonus round: just plugged it on windows, and it worked like a charm lol (with generic driver):

image

@rebelate
Copy link

Mine's working with the kernel 5.10, it's working fine when connected to a typical bluetooth speaker or a single TWS but won't work properly when connected to a TWS (stereo), no sound at all..

@nevack
Copy link
Author

nevack commented Jun 2, 2022

Sorry, I have to remove my contact info from gist.
My initial purpose was to let people contact me if anybody finds some new fix/patch.
Everything I got is a ton of spam like "help me please to fix bluetooth dongle on linux [version]".
Have a good day, yall!

@viggo1337burner
Copy link

Hey :)
Is there any ETA for when the current working patch will be merged into the main kernel? I am currently on kernel version 5.18, and it does not work.. Alternatively is there anyone adding the patch to the AUR?

@nevack
Copy link
Author

nevack commented Jun 23, 2022

Hey :) Is there any ETA for when the current working patch will be merged into the main kernel? I am currently on kernel version 5.18, and it does not work.. Alternatively is there anyone adding the patch to the AUR?

There's no working patch at the moment.

@Swyter
Copy link

Swyter commented Jun 23, 2022

Well, it's fixed for all the dongles I have and the ones I bought just to fix more Linux kernel issues. Everything I submitted has been merged.

I can't really justify buying a sack of random AliExpress dongles and wait months for them to arrive and cross my fingers so that the seller is kind enough to not swap the advertised PCB (which happened two months ago, getting specific controllers is crazy hard) just to submit more patches. I bought one of the Barrot ones that still don't work and ended up with a duplicate that worked out of the box already. Super great.

--

I'm just a random Linux user doing it as a hobby after arriving at the same place, there is no ETA. Be the change you want to see in the world, if everyone did what I did with the hardware they own everything would be fixed.

Just make the jump and learn, even if it's through hacks and experimentation it will help getting to the correct solution if you stick around. Often you can fix a dongle by commenting out something or submitting an one-liner.

@spmiller
Copy link

Thank you for your work on this, @Swyter. You helped inspire me to compile the kernel for the first time and you got my dongle working. I really appreciate the time you took developing the patches and hanging out here answering questions.

@NikitaSavc
Copy link

I compilied kernel with this patch, but problem with Bluetooth didn't fixed.
System: Fedora Linux.
Compilied version: 5.15.70

@RezaT4795
Copy link

RezaT4795 commented Oct 11, 2022 via email

@Martzy303
Copy link

Martzy303 commented Nov 4, 2022

Have installed 5.17.1-051701-generic on Ubuntu 22.04.1 and still have the problem
lsusb: Bus 005 Device 002: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)

Have tried with 6.0.7-060007-generic and still same output

[    3.776546] Bluetooth: Core ver 2.22
[    3.776576] NET: Registered PF_BLUETOOTH protocol family
[    3.776577] Bluetooth: HCI device and connection manager initialized
[    3.776582] Bluetooth: HCI socket layer initialized
[    3.776585] Bluetooth: L2CAP socket layer initialized
[    3.776589] Bluetooth: SCO socket layer initialized
[    3.859412] Bluetooth: hci0: CSR: Unbranded CSR clone detected; adding workarounds and force-suspending once...
[    4.406985] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[    4.406988] Bluetooth: BNEP filters: protocol multicast
[    4.406992] Bluetooth: BNEP socket layer initialized
[    9.019046] Bluetooth: hci0: CSR: Couldn't suspend the device for our Barrot 8041a02 receive-issue workaround
[   11.032916] Bluetooth: hci0: Opcode 0x c03 failed: -110

Did somebody solve this?

@AndriiBakayev
Copy link

Got the same problems and outputs on Ubuntu 22.04.1 LTS.
My dongle CSR 8510 A10 works fine on windows 7 on Microsoft generic driver.
Tried kernels 5.15.0 and 5.19.16.

@Gustavo17pacheco
Copy link

I`m running Fedora 37 with kernel 6.0.7-301, unmodified.

Also getting errors, it used to work just fine on Fedora 35 and on older kernels in other distros.

[ 15.034386] Bluetooth: Core ver 2.22
[ 15.034400] Bluetooth: HCI device and connection manager initialized
[ 15.034402] Bluetooth: HCI socket layer initialized
[ 15.034404] Bluetooth: L2CAP socket layer initialized
[ 15.034407] Bluetooth: SCO socket layer initialized
[ 15.825231] Bluetooth: hci0: CSR: Unbranded CSR clone detected; adding workarounds and force-suspending once...
[ 15.825235] Bluetooth: hci0: CSR: Couldn't suspend the device for our Barrot 8041a02 receive-issue workaround
[ 15.825238] Bluetooth: hci0: HCI Delete Stored Link Key command is advertised, but not supported.
[ 15.825239] Bluetooth: hci0: HCI Set Event Filter command not supported.
[ 17.948972] Bluetooth: hci0: command 0x0c5a tx timeout
[ 17.949005] Bluetooth: hci0: Opcode 0x c5a failed: -110
[ 20.711035] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[ 20.711037] Bluetooth: BNEP filters: protocol multicast
[ 20.711041] Bluetooth: BNEP socket layer initialized

@Swyter
Copy link

Swyter commented Nov 22, 2022

See here: https://bugzilla.kernel.org/show_bug.cgi?id=60824#c242

Submitted a patch series here: https://bugzilla.kernel.org/show_bug.cgi?id=60824#c243

There was another simultaneous conversation in the mailing list here: https://linuxlists.cc/l/15/linux-bluetooth/t/4663230/(regression)_cambridge_silicon_radio,_ltd_bluetooth_dongle_unusable_again_with_kernel_6.0#post4683596

In the end, Luiz merged 2 out of the 3 patches upstream. There's radio silence about the third one.

Subscribe to the Bugzilla ticket if you want to stay up to date.

@Gustavo17pacheco
Copy link

The patch series talked above is currently empty: https://patchwork.kernel.org/project/bluetooth/list/?series=690177&state

I'd patch my own kernel if possible. This problem has kept me out of Linux entirely.

@dukercs
Copy link

dukercs commented Dec 21, 2022

Anyone who needs a patch for linux 5.15.x LTS series, can use this patch. Credit goes to @Swyter for creating the original patches. I just combined them and made it compatible with linux 5.15.x LTS. It has been tested on linux 5.15.27.

Just copy and save it as a .diff file and apply it on the kernel source.

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index ac90392cc..39b189b16 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -1942,6 +1942,8 @@ static int btusb_setup_csr(struct hci_dev *hdev)
 		 */
 		set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks);
 		set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks);
+		set_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks);
+		set_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks);
 
 		/* Clear the reset quirk since this is not an actual
 		 * early Bluetooth 1.1 device from CSR.
@@ -1952,16 +1954,16 @@ static int btusb_setup_csr(struct hci_dev *hdev)
 		/*
 		 * Special workaround for these BT 4.0 chip clones, and potentially more:
 		 *
-		 * - 0x0134: a Barrot 8041a02                 (HCI rev: 0x1012 sub: 0x0810)
+		 * - 0x0134: a Barrot 8041a02                 (HCI rev: 0x0810 sub: 0x1012)
 		 * - 0x7558: IC markings FR3191AHAL 749H15143 (HCI rev/sub-version: 0x0709)
 		 *
 		 * These controllers are really messed-up.
 		 *
 		 * 1. Their bulk RX endpoint will never report any data unless
-		 * the device was suspended at least once (yes, really).
+		 *    the device was suspended at least once (yes, really).
 		 * 2. They will not wakeup when autosuspended and receiving data
-		 * on their bulk RX endpoint from e.g. a keyboard or mouse
-		 * (IOW remote-wakeup support is broken for the bulk endpoint).
+		 *    on their bulk RX endpoint from e.g. a keyboard or mouse
+		 *    (IOW remote-wakeup support is broken for the bulk endpoint).
 		 *
 		 * To fix 1. enable runtime-suspend, force-suspend the
 		 * HCI and then wake-it up by disabling runtime-suspend.
@@ -1981,7 +1983,7 @@ static int btusb_setup_csr(struct hci_dev *hdev)
 		if (ret >= 0)
 			msleep(200);
 		else
-			bt_dev_err(hdev, "CSR: Failed to suspend the device for our Barrot 8041a02 receive-issue workaround");
+			bt_dev_warn(hdev, "CSR: Couldn't suspend the device for our Barrot 8041a02 receive-issue workaround");
 
 		pm_runtime_forbid(&data->udev->dev);
 
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 9ce46cb85..41f0026b6 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -255,6 +255,16 @@ enum {
 	 * during the hdev->setup vendor callback.
 	 */
 	HCI_QUIRK_BROKEN_READ_TRANSMIT_POWER,
+
+	/* When this quirk is set, HCI_OP_SET_EVENT_FLT requests with
+	 * HCI_FLT_CLEAR_ALL are ignored and event filtering is
+	 * completely avoided. A subset of the CSR controller
+	 * clones struggle with this and instantly lock up.
+	 *
+	 * Note that devices using this must (separately) disable
+	 * runtime suspend, because event filtering takes place there.
+	 */
+	HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL,
 };
 
 /* HCI device flags */
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 53f1b0801..4c7f748b8 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -271,6 +271,7 @@ static int hci_init1_req(struct hci_request *req, unsigned long opt)
 
 static void bredr_setup(struct hci_request *req)
 {
+	struct hci_dev *hdev = req->hdev;
 	__le16 param;
 	__u8 flt_type;
 
@@ -292,9 +293,14 @@ static void bredr_setup(struct hci_request *req)
 	/* Read Current IAC LAP */
 	hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL);
 
-	/* Clear Event Filters */
-	flt_type = HCI_FLT_CLEAR_ALL;
-	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
+	/* Clear Event Filters; some fake CSR controllers lock up after setting
+	 * this type of filter, so avoid sending the request altogether.
+	 */
+	if (!test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks))
+	{
+		flt_type = HCI_FLT_CLEAR_ALL;
+		hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
+	}
 
 	/* Connection accept timeout ~20 secs */
 	param = cpu_to_le16(0x7d00);
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index 1d34d330a..35308de87 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -1156,11 +1156,15 @@ static bool adv_instance_is_scannable(struct hci_dev *hdev, u8 instance)
 static void hci_req_clear_event_filter(struct hci_request *req)
 {
 	struct hci_cp_set_event_filter f;
+	struct hci_dev *hdev = req->hdev;
+
+	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
+		return;
 
-	if (!hci_dev_test_flag(req->hdev, HCI_BREDR_ENABLED))
+	if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks))
 		return;
 
-	if (hci_dev_test_flag(req->hdev, HCI_EVENT_FILTER_CONFIGURED)) {
+	if (hci_dev_test_flag(hdev, HCI_EVENT_FILTER_CONFIGURED)) {
 		memset(&f, 0, sizeof(f));
 		f.flt_type = HCI_FLT_CLEAR_ALL;
 		hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &f);
@@ -1169,15 +1173,18 @@ static void hci_req_clear_event_filter(struct hci_request *req)
 
 static void hci_req_set_event_filter(struct hci_request *req)
 {
+	struct hci_dev *hdev = req->hdev;
 	struct bdaddr_list_with_flags *b;
 	struct hci_cp_set_event_filter f;
-	struct hci_dev *hdev = req->hdev;
 	u8 scan = SCAN_DISABLED;
 	bool scanning = test_bit(HCI_PSCAN, &hdev->flags);
 
 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
 		return;
 
+	if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks))
+		return;
+
 	/* Always clear event filter when starting */
 	hci_req_clear_event_filter(req);
 

Thank you! Worked on Ubuntu 22.04!
uname -r
5.15.64-bluetooth

@superian
Copy link

superian commented Jan 5, 2023

How fascinating - on an earlier standard Ubuntu kernel, the one of these I have Just Worked (and worked better than the 1Mii B10 dongle that's supposed to be the gold standard for doing this on Linux!)

But on the 5.15 kernel, it doesn't. I am not sure I have the patience to patch it.

@Swyter
Copy link

Swyter commented Jan 5, 2023

Try a more updated or newer kernel instead of patching manually. Ubuntu and Debian are notorious for being extremely slow when moving from one version to another. The fix exists, it just hasn't arrived yet to your door. Arch Linux got it in early December, for example.

@olevenets2
Copy link

Anyone who needs a patch for linux 5.15.x LTS series, can use this patch. Credit goes to @Swyter for creating the original patches. I just combined them and made it compatible with linux 5.15.x LTS. It has been tested on linux 5.15.27.
Just copy and save it as a .diff file and apply it on the kernel source.

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index ac90392cc..39b189b16 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -1942,6 +1942,8 @@ static int btusb_setup_csr(struct hci_dev *hdev)
 		 */
 		set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks);
 		set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks);
+		set_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks);
+		set_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks);
 
 		/* Clear the reset quirk since this is not an actual
 		 * early Bluetooth 1.1 device from CSR.
@@ -1952,16 +1954,16 @@ static int btusb_setup_csr(struct hci_dev *hdev)
 		/*
 		 * Special workaround for these BT 4.0 chip clones, and potentially more:
 		 *
-		 * - 0x0134: a Barrot 8041a02                 (HCI rev: 0x1012 sub: 0x0810)
+		 * - 0x0134: a Barrot 8041a02                 (HCI rev: 0x0810 sub: 0x1012)
 		 * - 0x7558: IC markings FR3191AHAL 749H15143 (HCI rev/sub-version: 0x0709)
 		 *
 		 * These controllers are really messed-up.
 		 *
 		 * 1. Their bulk RX endpoint will never report any data unless
-		 * the device was suspended at least once (yes, really).
+		 *    the device was suspended at least once (yes, really).
 		 * 2. They will not wakeup when autosuspended and receiving data
-		 * on their bulk RX endpoint from e.g. a keyboard or mouse
-		 * (IOW remote-wakeup support is broken for the bulk endpoint).
+		 *    on their bulk RX endpoint from e.g. a keyboard or mouse
+		 *    (IOW remote-wakeup support is broken for the bulk endpoint).
 		 *
 		 * To fix 1. enable runtime-suspend, force-suspend the
 		 * HCI and then wake-it up by disabling runtime-suspend.
@@ -1981,7 +1983,7 @@ static int btusb_setup_csr(struct hci_dev *hdev)
 		if (ret >= 0)
 			msleep(200);
 		else
-			bt_dev_err(hdev, "CSR: Failed to suspend the device for our Barrot 8041a02 receive-issue workaround");
+			bt_dev_warn(hdev, "CSR: Couldn't suspend the device for our Barrot 8041a02 receive-issue workaround");
 
 		pm_runtime_forbid(&data->udev->dev);
 
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 9ce46cb85..41f0026b6 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -255,6 +255,16 @@ enum {
 	 * during the hdev->setup vendor callback.
 	 */
 	HCI_QUIRK_BROKEN_READ_TRANSMIT_POWER,
+
+	/* When this quirk is set, HCI_OP_SET_EVENT_FLT requests with
+	 * HCI_FLT_CLEAR_ALL are ignored and event filtering is
+	 * completely avoided. A subset of the CSR controller
+	 * clones struggle with this and instantly lock up.
+	 *
+	 * Note that devices using this must (separately) disable
+	 * runtime suspend, because event filtering takes place there.
+	 */
+	HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL,
 };
 
 /* HCI device flags */
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 53f1b0801..4c7f748b8 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -271,6 +271,7 @@ static int hci_init1_req(struct hci_request *req, unsigned long opt)
 
 static void bredr_setup(struct hci_request *req)
 {
+	struct hci_dev *hdev = req->hdev;
 	__le16 param;
 	__u8 flt_type;
 
@@ -292,9 +293,14 @@ static void bredr_setup(struct hci_request *req)
 	/* Read Current IAC LAP */
 	hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL);
 
-	/* Clear Event Filters */
-	flt_type = HCI_FLT_CLEAR_ALL;
-	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
+	/* Clear Event Filters; some fake CSR controllers lock up after setting
+	 * this type of filter, so avoid sending the request altogether.
+	 */
+	if (!test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks))
+	{
+		flt_type = HCI_FLT_CLEAR_ALL;
+		hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
+	}
 
 	/* Connection accept timeout ~20 secs */
 	param = cpu_to_le16(0x7d00);
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index 1d34d330a..35308de87 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -1156,11 +1156,15 @@ static bool adv_instance_is_scannable(struct hci_dev *hdev, u8 instance)
 static void hci_req_clear_event_filter(struct hci_request *req)
 {
 	struct hci_cp_set_event_filter f;
+	struct hci_dev *hdev = req->hdev;
+
+	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
+		return;
 
-	if (!hci_dev_test_flag(req->hdev, HCI_BREDR_ENABLED))
+	if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks))
 		return;
 
-	if (hci_dev_test_flag(req->hdev, HCI_EVENT_FILTER_CONFIGURED)) {
+	if (hci_dev_test_flag(hdev, HCI_EVENT_FILTER_CONFIGURED)) {
 		memset(&f, 0, sizeof(f));
 		f.flt_type = HCI_FLT_CLEAR_ALL;
 		hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &f);
@@ -1169,15 +1173,18 @@ static void hci_req_clear_event_filter(struct hci_request *req)
 
 static void hci_req_set_event_filter(struct hci_request *req)
 {
+	struct hci_dev *hdev = req->hdev;
 	struct bdaddr_list_with_flags *b;
 	struct hci_cp_set_event_filter f;
-	struct hci_dev *hdev = req->hdev;
 	u8 scan = SCAN_DISABLED;
 	bool scanning = test_bit(HCI_PSCAN, &hdev->flags);
 
 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
 		return;
 
+	if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks))
+		return;
+
 	/* Always clear event filter when starting */
 	hci_req_clear_event_filter(req);
 

Thank you! Worked on Ubuntu 22.04! uname -r 5.15.64-bluetooth

Hello, I tried this patch on my Raspberry OS aarch64 with kernel 5.15.89-v8 however it didn't work. My 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode). My usb is still down according to hciconfig. It doesn't work for arm?

@ilyakurdyukov
Copy link

This patch helped get the Ritmix RWA-350 working on Ubuntu 22.04.

Shown in lsusb as:

ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)

I cleaned up the patch:

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 8c41c76..9632251 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -1979,6 +1979,8 @@ static int btusb_setup_csr(struct hci_dev *hdev)
 		 */
 		set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks);
 		set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks);
+		set_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks);
+		set_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks);
 
 		/* Clear the reset quirk since this is not an actual
 		 * early Bluetooth 1.1 device from CSR.
@@ -2018,7 +2020,7 @@ static int btusb_setup_csr(struct hci_dev *hdev)
 		if (ret >= 0)
 			msleep(200);
 		else
-			bt_dev_err(hdev, "CSR: Failed to suspend the device for our Barrot 8041a02 receive-issue workaround");
+			bt_dev_warn(hdev, "CSR: Couldn't suspend the device for our Barrot 8041a02 receive-issue workaround");
 
 		pm_runtime_forbid(&data->udev->dev);
 
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 9ce46cb..b97602a 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -255,6 +255,7 @@ enum {
 	 * during the hdev->setup vendor callback.
 	 */
 	HCI_QUIRK_BROKEN_READ_TRANSMIT_POWER,
+	HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL,
 };
 
 /* HCI device flags */
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index bb84ff5..2a7af9a 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -294,6 +294,7 @@ static void bredr_setup(struct hci_request *req)
 
 	/* Clear Event Filters */
 	flt_type = HCI_FLT_CLEAR_ALL;
+	if (!test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &req->hdev->quirks))
 	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
 
 	/* Connection accept timeout ~20 secs */
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index c2db60a..39a871a 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -1160,6 +1160,9 @@ static void hci_req_clear_event_filter(struct hci_request *req)
 	if (!hci_dev_test_flag(req->hdev, HCI_BREDR_ENABLED))
 		return;
 
+	if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &req->hdev->quirks))
+		return;
+
 	if (hci_dev_test_flag(req->hdev, HCI_EVENT_FILTER_CONFIGURED)) {
 		memset(&f, 0, sizeof(f));
 		f.flt_type = HCI_FLT_CLEAR_ALL;
@@ -1178,6 +1181,9 @@ static void hci_req_set_event_filter(struct hci_request *req)
 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
 		return;
 
+	if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks))
+		return;
+
 	/* Always clear event filter when starting */
 	hci_req_clear_event_filter(req);

Extract the linux-source archive corresponding to your kernel and do the following:

$ patch -p1 < csr-clean.patch
$ make -C /lib/modules/$(uname -r)/build M=$(pwd)/net/bluetooth ccflags-y="$(echo "-include "$(pwd)/include/net/bluetooth/{bluetooth.h,hci.h})" modules
$ make -C /lib/modules/$(uname -r)/build M=$(pwd)/drivers/bluetooth ccflags-y="$(echo "-include "$(pwd)/include/net/bluetooth/{bluetooth.h,hci.h})" modules
$ strip --strip-debug net/bluetooth/bluetooth.ko
$ strip --strip-debug drivers/bluetooth/btusb.ko

Then you can replace the old drivers in /usr/lib/modules/$(uname -r)/kernel with the new ones. Don't forget to backup the old files.

@olevenets2
Copy link

I compiled this patch 5.15 but unfortunately it didn't work for my dongle.

It works if you remove the reset code from the bluetooth driver, no patches affect to this adapter

@Mehdidadash
Copy link

Anyone who needs a patch for linux 5.15.x LTS series, can use this patch. Credit goes to @Swyter for creating the original patches. I just combined them and made it compatible with linux 5.15.x LTS. It has been tested on linux 5.15.27.

Just copy and save it as a .diff file and apply it on the kernel source.

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index ac90392cc..39b189b16 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -1942,6 +1942,8 @@ static int btusb_setup_csr(struct hci_dev *hdev)
 		 */
 		set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks);
 		set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks);
+		set_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks);
+		set_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks);
 
 		/* Clear the reset quirk since this is not an actual
 		 * early Bluetooth 1.1 device from CSR.
@@ -1952,16 +1954,16 @@ static int btusb_setup_csr(struct hci_dev *hdev)
 		/*
 		 * Special workaround for these BT 4.0 chip clones, and potentially more:
 		 *
-		 * - 0x0134: a Barrot 8041a02                 (HCI rev: 0x1012 sub: 0x0810)
+		 * - 0x0134: a Barrot 8041a02                 (HCI rev: 0x0810 sub: 0x1012)
 		 * - 0x7558: IC markings FR3191AHAL 749H15143 (HCI rev/sub-version: 0x0709)
 		 *
 		 * These controllers are really messed-up.
 		 *
 		 * 1. Their bulk RX endpoint will never report any data unless
-		 * the device was suspended at least once (yes, really).
+		 *    the device was suspended at least once (yes, really).
 		 * 2. They will not wakeup when autosuspended and receiving data
-		 * on their bulk RX endpoint from e.g. a keyboard or mouse
-		 * (IOW remote-wakeup support is broken for the bulk endpoint).
+		 *    on their bulk RX endpoint from e.g. a keyboard or mouse
+		 *    (IOW remote-wakeup support is broken for the bulk endpoint).
 		 *
 		 * To fix 1. enable runtime-suspend, force-suspend the
 		 * HCI and then wake-it up by disabling runtime-suspend.
@@ -1981,7 +1983,7 @@ static int btusb_setup_csr(struct hci_dev *hdev)
 		if (ret >= 0)
 			msleep(200);
 		else
-			bt_dev_err(hdev, "CSR: Failed to suspend the device for our Barrot 8041a02 receive-issue workaround");
+			bt_dev_warn(hdev, "CSR: Couldn't suspend the device for our Barrot 8041a02 receive-issue workaround");
 
 		pm_runtime_forbid(&data->udev->dev);
 
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 9ce46cb85..41f0026b6 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -255,6 +255,16 @@ enum {
 	 * during the hdev->setup vendor callback.
 	 */
 	HCI_QUIRK_BROKEN_READ_TRANSMIT_POWER,
+
+	/* When this quirk is set, HCI_OP_SET_EVENT_FLT requests with
+	 * HCI_FLT_CLEAR_ALL are ignored and event filtering is
+	 * completely avoided. A subset of the CSR controller
+	 * clones struggle with this and instantly lock up.
+	 *
+	 * Note that devices using this must (separately) disable
+	 * runtime suspend, because event filtering takes place there.
+	 */
+	HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL,
 };
 
 /* HCI device flags */
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 53f1b0801..4c7f748b8 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -271,6 +271,7 @@ static int hci_init1_req(struct hci_request *req, unsigned long opt)
 
 static void bredr_setup(struct hci_request *req)
 {
+	struct hci_dev *hdev = req->hdev;
 	__le16 param;
 	__u8 flt_type;
 
@@ -292,9 +293,14 @@ static void bredr_setup(struct hci_request *req)
 	/* Read Current IAC LAP */
 	hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL);
 
-	/* Clear Event Filters */
-	flt_type = HCI_FLT_CLEAR_ALL;
-	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
+	/* Clear Event Filters; some fake CSR controllers lock up after setting
+	 * this type of filter, so avoid sending the request altogether.
+	 */
+	if (!test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks))
+	{
+		flt_type = HCI_FLT_CLEAR_ALL;
+		hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
+	}
 
 	/* Connection accept timeout ~20 secs */
 	param = cpu_to_le16(0x7d00);
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index 1d34d330a..35308de87 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -1156,11 +1156,15 @@ static bool adv_instance_is_scannable(struct hci_dev *hdev, u8 instance)
 static void hci_req_clear_event_filter(struct hci_request *req)
 {
 	struct hci_cp_set_event_filter f;
+	struct hci_dev *hdev = req->hdev;
+
+	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
+		return;
 
-	if (!hci_dev_test_flag(req->hdev, HCI_BREDR_ENABLED))
+	if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks))
 		return;
 
-	if (hci_dev_test_flag(req->hdev, HCI_EVENT_FILTER_CONFIGURED)) {
+	if (hci_dev_test_flag(hdev, HCI_EVENT_FILTER_CONFIGURED)) {
 		memset(&f, 0, sizeof(f));
 		f.flt_type = HCI_FLT_CLEAR_ALL;
 		hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &f);
@@ -1169,15 +1173,18 @@ static void hci_req_clear_event_filter(struct hci_request *req)
 
 static void hci_req_set_event_filter(struct hci_request *req)
 {
+	struct hci_dev *hdev = req->hdev;
 	struct bdaddr_list_with_flags *b;
 	struct hci_cp_set_event_filter f;
-	struct hci_dev *hdev = req->hdev;
 	u8 scan = SCAN_DISABLED;
 	bool scanning = test_bit(HCI_PSCAN, &hdev->flags);
 
 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
 		return;
 
+	if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks))
+		return;
+
 	/* Always clear event filter when starting */
 	hci_req_clear_event_filter(req);
 

بخدا مسلمون نیستی رضا. یه راهنمای قدم به قدمی چیزی مینوشتی که یکی با معلومات ضعیف مثل من هم بتونه استفاده کنه این رو. من debian 11 kernel 5.10-0.22rt دارم. میتونی یکم ساده تر توضیح بدی باید چیکار کنم ؟

@maikews
Copy link

maikews commented Jul 27, 2023

This patch helped get the Ritmix RWA-350 working on Ubuntu 22.04.

Shown in lsusb as:

ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)

I cleaned up the patch:

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 8c41c76..9632251 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -1979,6 +1979,8 @@ static int btusb_setup_csr(struct hci_dev *hdev)
 		 */
 		set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks);
 		set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks);
+		set_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks);
+		set_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks);
 
 		/* Clear the reset quirk since this is not an actual
 		 * early Bluetooth 1.1 device from CSR.
@@ -2018,7 +2020,7 @@ static int btusb_setup_csr(struct hci_dev *hdev)
 		if (ret >= 0)
 			msleep(200);
 		else
-			bt_dev_err(hdev, "CSR: Failed to suspend the device for our Barrot 8041a02 receive-issue workaround");
+			bt_dev_warn(hdev, "CSR: Couldn't suspend the device for our Barrot 8041a02 receive-issue workaround");
 
 		pm_runtime_forbid(&data->udev->dev);
 
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 9ce46cb..b97602a 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -255,6 +255,7 @@ enum {
 	 * during the hdev->setup vendor callback.
 	 */
 	HCI_QUIRK_BROKEN_READ_TRANSMIT_POWER,
+	HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL,
 };
 
 /* HCI device flags */
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index bb84ff5..2a7af9a 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -294,6 +294,7 @@ static void bredr_setup(struct hci_request *req)
 
 	/* Clear Event Filters */
 	flt_type = HCI_FLT_CLEAR_ALL;
+	if (!test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &req->hdev->quirks))
 	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
 
 	/* Connection accept timeout ~20 secs */
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index c2db60a..39a871a 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -1160,6 +1160,9 @@ static void hci_req_clear_event_filter(struct hci_request *req)
 	if (!hci_dev_test_flag(req->hdev, HCI_BREDR_ENABLED))
 		return;
 
+	if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &req->hdev->quirks))
+		return;
+
 	if (hci_dev_test_flag(req->hdev, HCI_EVENT_FILTER_CONFIGURED)) {
 		memset(&f, 0, sizeof(f));
 		f.flt_type = HCI_FLT_CLEAR_ALL;
@@ -1178,6 +1181,9 @@ static void hci_req_set_event_filter(struct hci_request *req)
 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
 		return;
 
+	if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks))
+		return;
+
 	/* Always clear event filter when starting */
 	hci_req_clear_event_filter(req);

Extract the linux-source archive corresponding to your kernel and do the following:

$ patch -p1 < csr-clean.patch
$ make -C /lib/modules/$(uname -r)/build M=$(pwd)/net/bluetooth ccflags-y="$(echo "-include "$(pwd)/include/net/bluetooth/{bluetooth.h,hci.h})" modules
$ make -C /lib/modules/$(uname -r)/build M=$(pwd)/drivers/bluetooth ccflags-y="$(echo "-include "$(pwd)/include/net/bluetooth/{bluetooth.h,hci.h})" modules
$ strip --strip-debug net/bluetooth/bluetooth.ko
$ strip --strip-debug drivers/bluetooth/btusb.ko

Then you can replace the old drivers in /usr/lib/modules/$(uname -r)/kernel with the new ones. Don't forget to backup the old files.

It worked for me, tanks.

I currently have kernel 5.15.0-78-generic

My archives copilled:
https://drive.google.com/drive/folders/1cn7CZZUWD4B8hi-y0RKCNZIo78Bw7wFV?usp=sharing

I backed up and replaced the files

btusb.ko in /usr/lib/modules/5.15.0-XX-generic/kernel/drivers/bluetooth
bluetooth.ko in /usr/lib/modules/5.15.0-XX-generic/kernel/net/bluetooth/

@JeffreyO
Copy link

JeffreyO commented Aug 12, 2023

Tossing my picture in for others. Was anyone lucky enough to find the exact chip used or have a module where the markings aren't etched away and replaced with what I assume is a serial number or datecode?

It was advertised as a Bluetooth 4.0 radio and it supposedly has the Qualcomm CSR8510A10 chip inside of it, but I seriously doubt it.

Chip markings which seem meaningless of EAG435 with 24 pins total (Those little copper rectangles on the edge) and 13 pins soldered in a Quad Flat No-Lead (QFN) package.
20230811_021747

Side view of chip with markings of 24Mhz crystal
20230812_161751

CSR4.0 outer casing
20230812_165113

Front of PCB with flash
2018.12.06
LV-B14-V1.0
20230812_165216

Front of PCB with flash disabled
20230812_165239

Back of PCB
20230812_165258

@JeffreyO
Copy link

JeffreyO commented Aug 12, 2023

Pinout so far: (Adding the pinout later. Beeping everything out currently.)

  1. Not soldered
  2. Soldered
  3. Soldered
  4. GND (Soldered)
  5. Vcc 5V (Soldered)
  6. Not soldered
  7. Not soldered
  8. Soldered
  9. Soldered
  10. Soldered
  11. BT Antenna (Soldered)
  12. Not soldered
  13. Not soldered
  14. Soldered
  15. Not soldered
  16. Soldered
  17. Soldered
  18. Not soldered
  19. Not soldered
  20. USB Data- (Soldered)
  21. USB Data+ (Soldered)
  22. Soldered
  23. Soldered
  24. Not soldered

@JeffreyO
Copy link

Front of PCB corrected for skew and cropped. Original orientation
20230812_165230~2

Back of PCB corrected for skew and cropped. Horizontally flipped
20230812_165258~Flipped Back PCB

Color coded back of PCB corrected for skew and cropped. Horizontally flipped
Throughholes: Blue
Blind vias: Red
IMG_20230812_204448

@Swyter
Copy link

Swyter commented Aug 14, 2023

@JeffreyO Thanks a lot for going above and beyond with your teardown! I remember trying to find the actual Chinese ASIC vendor, which (unless one takes a microscope photo of the bare die) it's going to be hard, but there are mentions to companies like Barrot in the kernel, which may be a good start point for more shady stuff: https://elixir.bootlin.com/linux/latest/source/drivers/bluetooth/btusb.c#L2322

If someone tried to clone the CSR chips they haven't done it correctly. ¯\_(ツ)_/¯

@jwrdegoede
Copy link

jwrdegoede commented Aug 14, 2023 via email

@JeffreyO
Copy link

@JeffreyO Thanks a lot for going above and beyond with your teardown! I remember trying to find the actual Chinese ASIC vendor, which (unless one takes a microscope photo of the bare die) it's going to be hard, but there are mentions to companies like Barrot in the kernel, which may be a good start point for more shady stuff: https://elixir.bootlin.com/linux/latest/source/drivers/bluetooth/btusb.c#L2322

If someone tried to clone the CSR chips they haven't done it correctly. ¯_(ツ)_/¯

Thank you. Also, for anyone wondering, there is a way to properly and nondestructively open up the USB dongle. I just gently pried it apart and wiggled it enough and was lucky not to break anything.
But, that's not the right way. The right way is that there's a clip in the USB part latching to the outside of the case. You press down on that and slide the dongle apart away from the metal. It should all come out in one piece.

To put it back together, you sandwich the plastic parts and the PCB back together and slide it into the metal part (Keep it mind that those 2 tiny divots in the metal are the clips. It only goes together one way.) while applying very light pressure to the clip. You should hear a click when everything is back together successfully.

@icaroerasmo
Copy link

icaroerasmo commented Dec 13, 2023

This patch helped get the Ritmix RWA-350 working on Ubuntu 22.04.
Shown in lsusb as:
ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
I cleaned up the patch:

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 8c41c76..9632251 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -1979,6 +1979,8 @@ static int btusb_setup_csr(struct hci_dev *hdev)
 		 */
 		set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks);
 		set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks);
+		set_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks);
+		set_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks);
 
 		/* Clear the reset quirk since this is not an actual
 		 * early Bluetooth 1.1 device from CSR.
@@ -2018,7 +2020,7 @@ static int btusb_setup_csr(struct hci_dev *hdev)
 		if (ret >= 0)
 			msleep(200);
 		else
-			bt_dev_err(hdev, "CSR: Failed to suspend the device for our Barrot 8041a02 receive-issue workaround");
+			bt_dev_warn(hdev, "CSR: Couldn't suspend the device for our Barrot 8041a02 receive-issue workaround");
 
 		pm_runtime_forbid(&data->udev->dev);
 
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 9ce46cb..b97602a 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -255,6 +255,7 @@ enum {
 	 * during the hdev->setup vendor callback.
 	 */
 	HCI_QUIRK_BROKEN_READ_TRANSMIT_POWER,
+	HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL,
 };
 
 /* HCI device flags */
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index bb84ff5..2a7af9a 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -294,6 +294,7 @@ static void bredr_setup(struct hci_request *req)
 
 	/* Clear Event Filters */
 	flt_type = HCI_FLT_CLEAR_ALL;
+	if (!test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &req->hdev->quirks))
 	hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
 
 	/* Connection accept timeout ~20 secs */
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index c2db60a..39a871a 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -1160,6 +1160,9 @@ static void hci_req_clear_event_filter(struct hci_request *req)
 	if (!hci_dev_test_flag(req->hdev, HCI_BREDR_ENABLED))
 		return;
 
+	if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &req->hdev->quirks))
+		return;
+
 	if (hci_dev_test_flag(req->hdev, HCI_EVENT_FILTER_CONFIGURED)) {
 		memset(&f, 0, sizeof(f));
 		f.flt_type = HCI_FLT_CLEAR_ALL;
@@ -1178,6 +1181,9 @@ static void hci_req_set_event_filter(struct hci_request *req)
 	if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
 		return;
 
+	if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks))
+		return;
+
 	/* Always clear event filter when starting */
 	hci_req_clear_event_filter(req);

Extract the linux-source archive corresponding to your kernel and do the following:

$ patch -p1 < csr-clean.patch
$ make -C /lib/modules/$(uname -r)/build M=$(pwd)/net/bluetooth ccflags-y="$(echo "-include "$(pwd)/include/net/bluetooth/{bluetooth.h,hci.h})" modules
$ make -C /lib/modules/$(uname -r)/build M=$(pwd)/drivers/bluetooth ccflags-y="$(echo "-include "$(pwd)/include/net/bluetooth/{bluetooth.h,hci.h})" modules
$ strip --strip-debug net/bluetooth/bluetooth.ko
$ strip --strip-debug drivers/bluetooth/btusb.ko

Then you can replace the old drivers in /usr/lib/modules/$(uname -r)/kernel with the new ones. Don't forget to backup the old files.

It worked for me, tanks.

I currently have kernel 5.15.0-78-generic

My archives copilled: https://drive.google.com/drive/folders/1cn7CZZUWD4B8hi-y0RKCNZIo78Bw7wFV?usp=sharing

I backed up and replaced the files

btusb.ko in /usr/lib/modules/5.15.0-XX-generic/kernel/drivers/bluetooth bluetooth.ko in /usr/lib/modules/5.15.0-XX-generic/kernel/net/bluetooth/

I have no idea on how to apply those patches and I'm willing a lot do so as my usb dongle shows up with same name in lsusb. Is there any material or could you explain me in a simple manner so I can reproduce it myself for kernel 6.6.6-arch1-1?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment