Skip to content

Instantly share code, notes, and snippets.

@nevack
Last active December 19, 2023 00:56
Show Gist options
  • Star 60 You must be signed in to star a gist
  • Fork 16 You must be signed in to fork a gist
  • 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

@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