Re: [Linux-4.9.30] Broadcom BCM20702 bluetooth in ThinkPad-T530 not usable

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



My latest howto and the two patches from bluetooth-next to fix the
issue on Debian/stretch AMD64.

- Sedat -
ISSUE: A Broadcom BCM20702A0 bluetooth dongle in a ThinkPad-T530 does not really support HCI_Set_Event_Mask_Page_2 command and is not usable.

HELP-1: See discussion on linux-bluetooth Mailing-list with the topic
HELP-1: "[Linux-4.9.30] Broadcom BCM20702 bluetooth in ThinkPad-T530 not usable"
HELP-2: Build-instructions adapted from <https://github.com/neurobin/MT7630E/issues/6>

NOTE-1: My system is a Debian/stretch 9.0 with linux-image-4.9.0-3-amd64 (4.9.30-1) package installed.
NOTE-2: Debian does not ship a fitting firmware, see <https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=801084>.

PREREQ: You need a firmware file from <https://github.com/winterheart/broadcom-bt-firmware>.
PREREQ: You should have a /lib/firmware/brcm/BCM20702A1-0a5c-21e6.hcd

PATCH-1: "[PATCH] Bluetooth: Send HCI Set Event Mask Page 2 command only when needed"
PATCH-1: <https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git/patch/?id=313f6888c8fbb1bc8b36c9012ce4e1de848df696>
PATCH-1: Backport for Linux v4.9.30 see <http://marc.info/?l=linux-bluetooth&m=149726402220677&w=2>
PATCH-2: "[PATCH] Bluetooth: btbcm: Read controller features during configuration"
PATCH-2: <https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git/commit/?id=4284ecbeda81083f4c7a3ce325b4a9d675657e61>
PATCH-3: "[PATCH] Bluetooth: btusb: set HCI_QUIRK_BROKEN_LOCAL_COMMANDS for 0x0a5c:0x21f3"
PATCH-3: Sample patch to demonstrate HCI_QUIRK_BROKEN_LOCAL_COMMANDS usage, see <https://www.spinics.net/lists/linux-bluetooth/msg70436.html>

[ CHECK STATUS AND STOP BLUETOOTH SERVICE ]

sudo systemctl status bluetooth.service
sudo systemctl stop bluetooth.service

[ DOWNLOAD DEBIAN-KERNEL HEADERS AND TOOLS ]  

sudo apt-get install build-essential linux-headers-$(uname -r)
sudo apt-get build-dep linux-image-$(uname -r)

[ CREATE A BUILD-ENVIRONMENT ]

mkdir -p ~/src/linux-kernel
cd ~/src/linux-kernel

[ DOWNLOAD AND UNPACK DEBIAN-KERNEL SOURCES ]

apt-get source linux-image-$(uname -r) -d
dpkg-source -x *.dsc

[ PREPARE, GENERATE AND COPY BLUETOOTH.KO AND BTBCM.KO KERNEL-MODULES ]

KVER="4.9.30"
cd linux-$KVER

[ PATCH-1 REQUIRES A REBUILD OF BLUETOOTH.KO KERNEL-MODULE ]
patch -Np1 -i ../patches/bluetooth-fixes-4.9.30/1-2-Bluetooth-Send-HCI-Set-Event-Mask-Page-2-command-only-when-needed-for-4-9-30.patch

[ PATCH-2 REQUIRES A REBUILD OF BTBCM.KO KERNEL-MODULE ]
patch -Np1 -i ../patches/bluetooth-fixes-4.9.30/2-2-Bluetooth-btbcm-Read-controller-features-during-configuration.patch 

cp -av /boot/config-$(uname -r) .config
cp -av /usr/src/linux-headers-$(uname -r)/Module.symvers ./

make prepare
make modules_prepare
make M=scripts/mod
make M=net/bluetooth modules
make M=drivers/bluetooth modules

KPATH_MODULES="/lib/modules/$(uname -r)/kernel"
sudo cp -av net/bluetooth/bluetooth.ko $KPATH_MODULES/net/bluetooth/
sudo cp -av drivers/bluetooth/btbcm.ko $KPATH_MODULES/drivers/bluetooth/
sudo chown root:root $KPATH_MODULES/net/bluetooth/bluetooth.ko $KPATH_MODULES/drivers/bluetooth/btbcm.ko 
ll $KPATH_MODULES/net/bluetooth/bluetooth.ko $KPATH_MODULES/drivers/bluetooth/btbcm.ko

[ START BLUETOOTH SERVICE ]

sudo systemctl start bluetooth.service

[ ALTERNATIVELY MONITOR HCI0 ]

[ SESSION #1 ]

modprobe -r -v btusb
modprobe -v btusb

rfkill list bluetooth
( rfkill unblock bluetooth )

hciconfig hci0 up

bluetoothctl
( list & show )

[ SESSION #2 ]

[ BTMON BTSNOOP-FORMAT ]
btmon -w btmom-w_bcm20702-fixed.log

[ CONVERT TO ASCII TEXT ]
btmod -r btmom-w_bcm20702-fixed.log > btmom-w_bcm20702-fixed.txt

[ SUCCESS ]

The bluetooth dongle should now work!


-dileks // 13-JUN-2017
From 313f6888c8fbb1bc8b36c9012ce4e1de848df696 Mon Sep 17 00:00:00 2001
From: Marcel Holtmann <marcel@xxxxxxxxxxxx>
Date: Fri, 9 Jun 2017 18:43:56 +0200
Subject: [4.9.30] Bluetooth: Send HCI Set Event Mask Page 2 command only when needed

The Broadcom BCM20702 Bluetooth controller in ThinkPad-T530 devices
report support for the Set Event Mask Page 2 command, but actually do
return an error when trying to use it.

  < HCI Command: Read Local Supported Commands (0x04|0x0002) plen 0
  > HCI Event: Command Complete (0x0e) plen 68
       Read Local Supported Commands (0x04|0x0002) ncmd 1
         Status: Success (0x00)
         Commands: 162 entries
           ...
           Set Event Mask Page 2 (Octet 22 - Bit 2)
           ...

  < HCI Command: Set Event Mask Page 2 (0x03|0x0063) plen 8
         Mask: 0x0000000000000000
  > HCI Event: Command Complete (0x0e) plen 4
       Set Event Mask Page 2 (0x03|0x0063) ncmd 1
         Status: Unknown HCI Command (0x01)

Since these controllers do not support any feature that would require
the event mask page 2 to be modified, it is safe to not send this
command at all. The default value is all bits set to zero.

T:  Bus=01 Lev=02 Prnt=02 Port=03 Cnt=03 Dev#=  9 Spd=12   MxCh= 0
D:  Ver= 2.00 Cls=ff(vend.) Sub=01 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=0a5c ProdID=21e6 Rev= 1.12
S:  Manufacturer=Broadcom Corp
S:  Product=BCM20702A0
S:  SerialNumber=F82FA8E8CFC0
C:* #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E:  Ad=81(I) Atr=03(Int.) MxPS=  16 Ivl=1ms
E:  Ad=82(I) Atr=02(Bulk) MxPS=  64 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS=  64 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=   0 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=   0 Ivl=1ms
I:  If#= 1 Alt= 1 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=   9 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=   9 Ivl=1ms
I:  If#= 1 Alt= 2 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=  17 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=  17 Ivl=1ms
I:  If#= 1 Alt= 3 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=  25 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=  25 Ivl=1ms
I:  If#= 1 Alt= 4 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=  33 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=  33 Ivl=1ms
I:  If#= 1 Alt= 5 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=  49 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=  49 Ivl=1ms
I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=btusb
E:  Ad=84(I) Atr=02(Bulk) MxPS=  32 Ivl=0ms
E:  Ad=04(O) Atr=02(Bulk) MxPS=  32 Ivl=0ms
I:* If#= 3 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=01 Driver=(none)

Signed-off-by: Marcel Holtmann <marcel@xxxxxxxxxxxx>
Reported-by: Sedat Dilek <sedat.dilek@xxxxxxxxx>
Tested-by: Sedat Dilek <sedat.dilek@xxxxxxxxx>
Signed-off-by: Szymon Janc <szymon.janc@xxxxxxxxxxx>
---
[ Backported to fit Linux v4.9.30. -dileks ]

 net/bluetooth/hci_core.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 3ac89e9..5049433 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -548,6 +548,7 @@ static void hci_set_event_mask_page_2(struct hci_request *req)
 {
 	struct hci_dev *hdev = req->hdev;
 	u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+	bool changed = false;
 
 	/* If Connectionless Slave Broadcast master role is supported
 	 * enable all necessary events for it.
@@ -557,6 +558,7 @@ static void hci_set_event_mask_page_2(struct hci_request *req)
 		events[1] |= 0x80;	/* Synchronization Train Complete */
 		events[2] |= 0x10;	/* Slave Page Response Timeout */
 		events[2] |= 0x20;	/* CSB Channel Map Change */
+		changed = true;
 	}
 
 	/* If Connectionless Slave Broadcast slave role is supported
@@ -570,10 +572,20 @@ static void hci_set_event_mask_page_2(struct hci_request *req)
 	}
 
 	/* Enable Authenticated Payload Timeout Expired event if supported */
-	if (lmp_ping_capable(hdev) || hdev->le_features[0] & HCI_LE_PING)
+	if (lmp_ping_capable(hdev) || hdev->le_features[0] & HCI_LE_PING) {
 		events[2] |= 0x80;
+		changed = true;
+	}
 
-	hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events);
+	/* Some Broadcom based controllers indicate support for Set Event
+	 * Mask Page 2 command, but then actually do not support it. Since
+	 * the default value is all bits set to zero, the command is only
+	 * required if the event mask has to be changed. In case no change
+	 * to the event mask is needed, skip this command.
+	 */
+	if (changed)
+		hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2,
+			    sizeof(events), events);
 }
 
 static int hci_init3_req(struct hci_request *req, unsigned long opt)
From 4284ecbeda81083f4c7a3ce325b4a9d675657e61 Mon Sep 17 00:00:00 2001
From: Marcel Holtmann <marcel@xxxxxxxxxxxx>
Date: Sat, 10 Jun 2017 14:33:16 +0200
Subject: Bluetooth: btbcm: Read controller features during configuration

Read the Broadcom specific controller features during configuration and
print them for informational purposes.

  < HCI Command: Broadcom Read Controller Features (0x3f|0x006e) plen 0
  > HCI Event: Command Complete (0x0e) plen 12
        Broadcom Read Controller Features (0x3f|0x006e) ncmd 1
          Status: Success (0x00)
          Features: 0x07 0x00 0x00 0x00 0x00 0x00 0x00 0x00
            Multi-AV transport bandwidth reducer
            WBS SBC
            FW LC-PLC

Signed-off-by: Marcel Holtmann <marcel@xxxxxxxxxxxx>
Signed-off-by: Szymon Janc <szymon.janc@xxxxxxxxxxx>
---
 drivers/bluetooth/btbcm.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c
index ba3dd2e..24f8c4e 100644
--- a/drivers/bluetooth/btbcm.c
+++ b/drivers/bluetooth/btbcm.c
@@ -246,6 +246,27 @@ static struct sk_buff *btbcm_read_verbose_config(struct hci_dev *hdev)
 	return skb;
 }
 
+static struct sk_buff *btbcm_read_controller_features(struct hci_dev *hdev)
+{
+	struct sk_buff *skb;
+
+	skb = __hci_cmd_sync(hdev, 0xfc6e, 0, NULL, HCI_INIT_TIMEOUT);
+	if (IS_ERR(skb)) {
+		BT_ERR("%s: BCM: Read controller features failed (%ld)",
+		       hdev->name, PTR_ERR(skb));
+		return skb;
+	}
+
+	if (skb->len != 9) {
+		BT_ERR("%s: BCM: Controller features length mismatch",
+		       hdev->name);
+		kfree_skb(skb);
+		return ERR_PTR(-EIO);
+	}
+
+	return skb;
+}
+
 static struct sk_buff *btbcm_read_usb_product(struct hci_dev *hdev)
 {
 	struct sk_buff *skb;
@@ -417,6 +438,14 @@ int btbcm_setup_patchram(struct hci_dev *hdev)
 	BT_INFO("%s: BCM: chip id %u", hdev->name, skb->data[1]);
 	kfree_skb(skb);
 
+	/* Read Controller Features */
+	skb = btbcm_read_controller_features(hdev);
+	if (IS_ERR(skb))
+		return PTR_ERR(skb);
+
+	BT_INFO("%s: BCM: features 0x%2.2x", hdev->name, skb->data[1]);
+	kfree_skb(skb);
+
 	/* Read Local Name */
 	skb = btbcm_read_local_name(hdev);
 	if (IS_ERR(skb))
@@ -540,6 +569,13 @@ int btbcm_setup_apple(struct hci_dev *hdev)
 		kfree_skb(skb);
 	}
 
+	/* Read Controller Features */
+	skb = btbcm_read_controller_features(hdev);
+	if (!IS_ERR(skb)) {
+		BT_INFO("%s: BCM: features 0x%2.2x", hdev->name, skb->data[1]);
+		kfree_skb(skb);
+	}
+
 	/* Read Local Name */
 	skb = btbcm_read_local_name(hdev);
 	if (!IS_ERR(skb)) {
-- 
cgit v1.1


[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux