aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Lechner <david@lechnology.com>2017-12-12 16:59:16 -0500
committerMarcel Holtmann <marcel@holtmann.org>2017-12-12 18:28:42 -0500
commitaa0993986932fe0ac7694b22c26c84e67abec53d (patch)
treec1e6ce147f30fb4e3be8b9f6754de07620fb6f97
parent94386b6a5b2c2102e832507ced90a14e6e3568eb (diff)
Bluetooth: hci_ll: add support for setting public address
This adds support for setting the public address on Texas Instruments Bluetooth chips using a vendor-specific command. This has been tested on a CC2560A chip. The TI wiki also indicates that this command should work on TI WL17xx/WL18xx Bluetooth chips. During review, there was some question as to the correctness of the byte swapping since TI's documentation is not clear on this matter. This can be tested with the btmgmt utility from bluez. The adapter must be powered off to change the address. If the baswap() is omitted, address is reversed. In case there is a issue in the future, here is the output of btmon during the command `btmgmt public-addr 00:11:22:33:44:55`: Bluetooth monitor ver 5.43 = Note: Linux version 4.15.0-rc2-08561-gcb132a1-dirty (armv5tejl) 0.707043 = Note: Bluetooth subsystem version 2.22 0.707091 = New Index: 00:17:E7:BD:1C:8E (Primary,UART,hci0) [hci0] 0.707106 @ MGMT Open: btmgmt (privileged) version 1.14 {0x0002} 0.707124 @ MGMT Open: bluetoothd (privileged) version 1.14 {0x0001} 0.707137 @ MGMT Open: btmon (privileged) version 1.14 {0x0003} 0.707540 @ MGMT Command: Set Public Address (0x0039) plen 6 {0x0002} [hci0] 11.167991 Address: 00:11:22:33:44:55 (CIMSYS Inc) @ MGMT Event: Command Complete (0x0001) plen 7 {0x0002} [hci0] 11.175681 Set Public Address (0x0039) plen 4 Status: Success (0x00) Missing options: 0x00000000 @ MGMT Event: Index Removed (0x0005) plen 0 {0x0003} [hci0] 11.175757 @ MGMT Event: Index Removed (0x0005) plen 0 {0x0002} [hci0] 11.175757 @ MGMT Event: Index Removed (0x0005) plen 0 {0x0001} [hci0] 11.175757 = Open Index: 00:17:E7:BD:1C:8E [hci0] 11.176807 < HCI Command: Vendor (0x3f|0x0006) plen 6 [hci0] 11.176975 00 11 22 33 44 55 .."3DU > HCI Event: Command Complete (0x0e) plen 4 [hci0] 11.188260 Vendor (0x3f|0x0006) ncmd 1 Status: Success (0x00) ... < HCI Command: Read Local Version Info.. (0x04|0x0001) plen 0 [hci0] 11.189859 > HCI Event: Command Complete (0x0e) plen 12 [hci0] 11.190732 Read Local Version Information (0x04|0x0001) ncmd 1 Status: Success (0x00) HCI version: Bluetooth 2.1 (0x04) - Revision 0 (0x0000) LMP version: Bluetooth 2.1 (0x04) - Subversion 6431 (0x191f) Manufacturer: Texas Instruments Inc. (13) < HCI Command: Read BD ADDR (0x04|0x0009) plen 0 [hci0] 11.191027 > HCI Event: Command Complete (0x0e) plen 10 [hci0] 11.192101 Read BD ADDR (0x04|0x0009) ncmd 1 Status: Success (0x00) Address: 00:11:22:33:44:55 (CIMSYS Inc) ... Signed-off-by: David Lechner <david@lechnology.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r--drivers/bluetooth/hci_ll.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c
index efcfbe9aac21..c948e8dcc553 100644
--- a/drivers/bluetooth/hci_ll.c
+++ b/drivers/bluetooth/hci_ll.c
@@ -57,6 +57,7 @@
57#include "hci_uart.h" 57#include "hci_uart.h"
58 58
59/* Vendor-specific HCI commands */ 59/* Vendor-specific HCI commands */
60#define HCI_VS_WRITE_BD_ADDR 0xfc06
60#define HCI_VS_UPDATE_UART_HCI_BAUDRATE 0xff36 61#define HCI_VS_UPDATE_UART_HCI_BAUDRATE 0xff36
61 62
62/* HCILL commands */ 63/* HCILL commands */
@@ -662,6 +663,24 @@ out_rel_fw:
662 return err; 663 return err;
663} 664}
664 665
666static int ll_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
667{
668 bdaddr_t bdaddr_swapped;
669 struct sk_buff *skb;
670
671 /* HCI_VS_WRITE_BD_ADDR (at least on a CC2560A chip) expects the BD
672 * address to be MSB first, but bdaddr_t has the convention of being
673 * LSB first.
674 */
675 baswap(&bdaddr_swapped, bdaddr);
676 skb = __hci_cmd_sync(hdev, HCI_VS_WRITE_BD_ADDR, sizeof(bdaddr_t),
677 &bdaddr_swapped, HCI_INIT_TIMEOUT);
678 if (!IS_ERR(skb))
679 kfree_skb(skb);
680
681 return PTR_ERR_OR_ZERO(skb);
682}
683
665static int ll_setup(struct hci_uart *hu) 684static int ll_setup(struct hci_uart *hu)
666{ 685{
667 int err, retry = 3; 686 int err, retry = 3;
@@ -674,6 +693,8 @@ static int ll_setup(struct hci_uart *hu)
674 693
675 lldev = serdev_device_get_drvdata(serdev); 694 lldev = serdev_device_get_drvdata(serdev);
676 695
696 hu->hdev->set_bdaddr = ll_set_bdaddr;
697
677 serdev_device_set_flow_control(serdev, true); 698 serdev_device_set_flow_control(serdev, true);
678 699
679 do { 700 do {