diff --git a/meta-digi-dey/conf/distro/dey.conf b/meta-digi-dey/conf/distro/dey.conf index 1baea77ba..c5dfe8f01 100644 --- a/meta-digi-dey/conf/distro/dey.conf +++ b/meta-digi-dey/conf/distro/dey.conf @@ -43,6 +43,11 @@ FEATURE_PACKAGES_dey-qt = "packagegroup-dey-qt" FEATURE_PACKAGES_dey-trustfence = "packagegroup-dey-trustfence" FEATURE_PACKAGES_dey-wireless = "packagegroup-dey-wireless" +# Our layer only provides version 5.41, which we want to keep because +# it was used for Bluetooth certification. However by default the newer +# 5.46 version should be used, which is provided by the poky layer. +PREFERRED_VERSION_bluez5 ?= "5.46" + # Set the PREFERRED_PROVIDER for jpeg functionality based on the MACHINE # architecture. For armv7a devices libjpeg-turbo should be used to take # advantage of the SIMD instructions. diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0001-Allow-using-obexd-without-systemd-in-the-user-sessio.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0001-Allow-using-obexd-without-systemd-in-the-user-sessio.patch new file mode 100644 index 000000000..2fde7bc06 --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0001-Allow-using-obexd-without-systemd-in-the-user-sessio.patch @@ -0,0 +1,63 @@ +From: Giovanni Campagna +Date: Sat, 12 Oct 2013 17:45:25 +0200 +Subject: [PATCH] Allow using obexd without systemd in the user session + +Not all sessions run systemd --user (actually, the majority +doesn't), so the dbus daemon must be able to spawn obexd +directly, and to do so it needs the full path of the daemon. + +Upstream-Status: Denied + +Not accepted by upstream maintainer for being a distro specific +configuration. See thread: + +http://thread.gmane.org/gmane.linux.bluez.kernel/38725/focus=38843 + +Signed-off-by: Javier Viguera +--- + Makefile.obexd | 4 ++-- + obexd/src/org.bluez.obex.service | 4 ---- + obexd/src/org.bluez.obex.service.in | 4 ++++ + 3 files changed, 6 insertions(+), 6 deletions(-) + delete mode 100644 obexd/src/org.bluez.obex.service + create mode 100644 obexd/src/org.bluez.obex.service.in + +diff --git a/Makefile.obexd b/Makefile.obexd +index 2e33cbc72f2b..d5d858c857b4 100644 +--- a/Makefile.obexd ++++ b/Makefile.obexd +@@ -2,12 +2,12 @@ + if SYSTEMD + systemduserunitdir = @SYSTEMD_USERUNITDIR@ + systemduserunit_DATA = obexd/src/obex.service ++endif + + dbussessionbusdir = @DBUS_SESSIONBUSDIR@ + dbussessionbus_DATA = obexd/src/org.bluez.obex.service +-endif + +-EXTRA_DIST += obexd/src/obex.service.in obexd/src/org.bluez.obex.service ++EXTRA_DIST += obexd/src/obex.service.in obexd/src/org.bluez.obex.service.in + + obex_plugindir = $(libdir)/obex/plugins + +diff --git a/obexd/src/org.bluez.obex.service b/obexd/src/org.bluez.obex.service +deleted file mode 100644 +index a53808884554..000000000000 +--- a/obexd/src/org.bluez.obex.service ++++ /dev/null +@@ -1,4 +0,0 @@ +-[D-BUS Service] +-Name=org.bluez.obex +-Exec=/bin/false +-SystemdService=dbus-org.bluez.obex.service +diff --git a/obexd/src/org.bluez.obex.service.in b/obexd/src/org.bluez.obex.service.in +new file mode 100644 +index 000000000000..9c815f246b77 +--- /dev/null ++++ b/obexd/src/org.bluez.obex.service.in +@@ -0,0 +1,4 @@ ++[D-BUS Service] ++Name=org.bluez.obex ++Exec=@libexecdir@/obexd ++SystemdService=dbus-org.bluez.obex.service diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0001-hcitool-do-not-show-unsupported-refresh-option.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0001-hcitool-do-not-show-unsupported-refresh-option.patch new file mode 100644 index 000000000..0d0375dad --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0001-hcitool-do-not-show-unsupported-refresh-option.patch @@ -0,0 +1,22 @@ +From: Isaac Hermida +Date: Fri, 8 Jul 2016 12:19:33 +0200 +Subject: [PATCH] hcitool: do not show unsupported refresh option + +Signed-off-by: Isaac Hermida +--- + tools/hcitool.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/hcitool.c b/tools/hcitool.c +index 02c4ebe1b71b..229c22c49909 100644 +--- a/tools/hcitool.c ++++ b/tools/hcitool.c +@@ -568,7 +568,7 @@ static struct option scan_options[] = { + + static const char *scan_help = + "Usage:\n" +- "\tscan [--length=N] [--numrsp=N] [--iac=lap] [--flush] [--class] [--info] [--oui] [--refresh]\n"; ++ "\tscan [--length=N] [--numrsp=N] [--iac=lap] [--flush] [--class] [--info] [--oui]\n"; + + static void cmd_scan(int dev_id, int argc, char **argv) + { diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0001-tests-add-a-target-for-building-tests-without-runnin.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0001-tests-add-a-target-for-building-tests-without-runnin.patch new file mode 100644 index 000000000..24ddae6b6 --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0001-tests-add-a-target-for-building-tests-without-runnin.patch @@ -0,0 +1,28 @@ +From 4bdf0f96dcaa945fd29f26d56e5b36d8c23e4c8b Mon Sep 17 00:00:00 2001 +From: Alexander Kanavin +Date: Fri, 1 Apr 2016 17:07:34 +0300 +Subject: [PATCH] tests: add a target for building tests without running them + +Upstream-Status: Inappropriate [oe specific] +Signed-off-by: Alexander Kanavin +--- + Makefile.am | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/Makefile.am b/Makefile.am +index 1a48a71..ba3b92f 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -425,6 +425,9 @@ endif + TESTS = $(unit_tests) + AM_TESTS_ENVIRONMENT = MALLOC_CHECK_=3 MALLOC_PERTURB_=69 + ++# This allows building tests without running them ++buildtests: $(TESTS) ++ + if DBUS_RUN_SESSION + AM_TESTS_ENVIRONMENT += dbus-run-session -- + endif +-- +2.8.0.rc3 + diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0002-hcitool-increase-the-shown-connection-limit-to-20.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0002-hcitool-increase-the-shown-connection-limit-to-20.patch new file mode 100644 index 000000000..fd81a1960 --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0002-hcitool-increase-the-shown-connection-limit-to-20.patch @@ -0,0 +1,57 @@ +From: Isaac Hermida +Date: Fri, 8 Jul 2016 10:42:57 +0200 +Subject: [PATCH] hcitool: increase the shown connection limit to 20 + +Created a variable to set the number of connections to shown and increase that +value so we can list more current LE connections. + +https://jira.digi.com/browse/DEL-2735 + +Signed-off-by: Isaac Hermida +--- + tools/hcitool.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/tools/hcitool.c b/tools/hcitool.c +index 229c22c49909..ae70c9c0d3b4 100644 +--- a/tools/hcitool.c ++++ b/tools/hcitool.c +@@ -69,6 +69,8 @@ + #define EIR_TX_POWER 0x0A /* transmit power level */ + #define EIR_DEVICE_ID 0x10 /* device ID */ + ++#define MAX_CONNECTIONS_SHOWN 20 /* Max number of "hcitool conn" items to shown */ ++ + #define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, NULL)) != -1) + + static volatile int signal_received = 0; +@@ -156,12 +158,12 @@ static int conn_list(int s, int dev_id, long arg) + if (id != -1 && dev_id != id) + return 0; + +- if (!(cl = malloc(10 * sizeof(*ci) + sizeof(*cl)))) { ++ if (!(cl = malloc(MAX_CONNECTIONS_SHOWN * sizeof(*ci) + sizeof(*cl)))) { + perror("Can't allocate memory"); + exit(1); + } + cl->dev_id = dev_id; +- cl->conn_num = 10; ++ cl->conn_num = MAX_CONNECTIONS_SHOWN; + ci = cl->conn_info; + + if (ioctl(s, HCIGETCONNLIST, (void *) cl)) { +@@ -190,12 +192,12 @@ static int find_conn(int s, int dev_id, long arg) + struct hci_conn_info *ci; + int i; + +- if (!(cl = malloc(10 * sizeof(*ci) + sizeof(*cl)))) { ++ if (!(cl = malloc(MAX_CONNECTIONS_SHOWN * sizeof(*ci) + sizeof(*cl)))) { + perror("Can't allocate memory"); + exit(1); + } + cl->dev_id = dev_id; +- cl->conn_num = 10; ++ cl->conn_num = MAX_CONNECTIONS_SHOWN; + ci = cl->conn_info; + + if (ioctl(s, HCIGETCONNLIST, (void *) cl)) { diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0003-port-test-discovery-to-python3.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0003-port-test-discovery-to-python3.patch new file mode 100644 index 000000000..25cc37ccf --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0003-port-test-discovery-to-python3.patch @@ -0,0 +1,99 @@ +From: Isaac Hermida +Date: Thu, 3 Aug 2017 14:10:43 +0200 +Subject: [PATCH] port test-discovery to python3 + +Signed-off-by: Isaac Hermida +--- + test/bluezutils.py | 4 ++-- + test/test-discovery | 16 +++++++++------- + 2 files changed, 11 insertions(+), 9 deletions(-) + +diff --git a/test/bluezutils.py b/test/bluezutils.py +index de08cbdcb712..cd8964082450 100644 +--- a/test/bluezutils.py ++++ b/test/bluezutils.py +@@ -15,7 +15,7 @@ def find_adapter(pattern=None): + + def find_adapter_in_objects(objects, pattern=None): + bus = dbus.SystemBus() +- for path, ifaces in objects.iteritems(): ++ for path, ifaces in objects.items(): + adapter = ifaces.get(ADAPTER_INTERFACE) + if adapter is None: + continue +@@ -35,7 +35,7 @@ def find_device_in_objects(objects, device_address, adapter_pattern=None): + if adapter_pattern: + adapter = find_adapter_in_objects(objects, adapter_pattern) + path_prefix = adapter.object_path +- for path, ifaces in objects.iteritems(): ++ for path, ifaces in objects.items(): + device = ifaces.get(DEVICE_INTERFACE) + if device is None: + continue +diff --git a/test/test-discovery b/test/test-discovery +index cea77683d726..852611c862ea 100755 +--- a/test/test-discovery ++++ b/test/test-discovery +@@ -1,4 +1,4 @@ +-#!/usr/bin/python ++#!/usr/bin/python3 + + from __future__ import absolute_import, print_function, unicode_literals + +@@ -18,9 +18,9 @@ def print_compact(address, properties): + name = "" + address = "" + +- for key, value in properties.iteritems(): ++ for key, value in properties.items(): + if type(value) is dbus.String: +- value = unicode(value).encode('ascii', 'replace') ++ value = str(value) + if (key == "Name"): + name = value + elif (key == "Address"): +@@ -41,7 +41,7 @@ def print_normal(address, properties): + for key in properties.keys(): + value = properties[key] + if type(value) is dbus.String: +- value = unicode(value).encode('ascii', 'replace') ++ value = str(value) + if (key == "Class"): + print(" %s = 0x%06x" % (key, value)) + else: +@@ -61,6 +61,8 @@ def skip_dev(old_dev, new_dev): + return False + + def interfaces_added(path, interfaces): ++ if "org.bluez.Device1" not in interfaces.keys(): ++ return + properties = interfaces["org.bluez.Device1"] + if not properties: + return +@@ -70,7 +72,7 @@ def interfaces_added(path, interfaces): + + if compact and skip_dev(dev, properties): + return +- devices[path] = dict(devices[path].items() + properties.items()) ++ devices[path] = dict(list(devices[path].items()) + list(properties.items())) + else: + devices[path] = properties + +@@ -93,7 +95,7 @@ def properties_changed(interface, changed, invalidated, path): + + if compact and skip_dev(dev, changed): + return +- devices[path] = dict(devices[path].items() + changed.items()) ++ devices[path] = dict(list(devices[path].items()) + list(changed.items())) + else: + devices[path] = changed + +@@ -152,7 +154,7 @@ if __name__ == '__main__': + om = dbus.Interface(bus.get_object("org.bluez", "/"), + "org.freedesktop.DBus.ObjectManager") + objects = om.GetManagedObjects() +- for path, interfaces in objects.iteritems(): ++ for path, interfaces in objects.items(): + if "org.bluez.Device1" in interfaces: + devices[path] = interfaces["org.bluez.Device1"] + diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0004-example-gatt-server-update-example-to-master-version.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0004-example-gatt-server-update-example-to-master-version.patch new file mode 100644 index 000000000..081a65dbc --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0004-example-gatt-server-update-example-to-master-version.patch @@ -0,0 +1,124 @@ +From: Isaac Hermida +Date: Wed, 27 Sep 2017 10:00:15 +0200 +Subject: [PATCH] example-gatt-server: update example to master version + +Current test example was not registering correctly the services, so the BLEGATT +server was not working properly. +Update this example to current version in master (commit ed63d7e5a9f6). + +Note: In order to run it, the bluetoothd daemon needs to be started with the +experimental (-E) flag and needs to enable and advertise the BLE +functionallity (btmgmt le on/connectable on/advertisement on). + +https://jira.digi.com/browse/DEL-5023 + +Signed-off-by: Isaac Hermida +--- + test/example-gatt-server | 28 +++++++++++++++++++++------- + 1 file changed, 21 insertions(+), 7 deletions(-) + +diff --git a/test/example-gatt-server b/test/example-gatt-server +index 84905f3d0856..24aaff973b11 100755 +--- a/test/example-gatt-server ++++ b/test/example-gatt-server +@@ -42,6 +42,9 @@ class FailedException(dbus.exceptions.DBusException): + + + class Application(dbus.service.Object): ++ """ ++ org.bluez.GattApplication1 interface implementation ++ """ + def __init__(self, bus): + self.path = '/' + self.services = [] +@@ -74,6 +77,9 @@ class Application(dbus.service.Object): + + + class Service(dbus.service.Object): ++ """ ++ org.bluez.GattService1 interface implementation ++ """ + PATH_BASE = '/org/bluez/example/service' + + def __init__(self, bus, index, uuid, primary): +@@ -121,6 +127,9 @@ class Service(dbus.service.Object): + + + class Characteristic(dbus.service.Object): ++ """ ++ org.bluez.GattCharacteristic1 interface implementation ++ """ + def __init__(self, bus, index, uuid, flags, service): + self.path = service.path + '/char' + str(index) + self.bus = bus +@@ -195,6 +204,9 @@ class Characteristic(dbus.service.Object): + + + class Descriptor(dbus.service.Object): ++ """ ++ org.bluez.GattDescriptor1 interface implementation ++ """ + def __init__(self, bus, index, uuid, flags, characteristic): + self.path = characteristic.path + '/desc' + str(index) + self.bus = bus +@@ -222,7 +234,7 @@ class Descriptor(dbus.service.Object): + if interface != GATT_DESC_IFACE: + raise InvalidArgsException() + +- return self.get_properties()[GATT_CHRC_IFACE] ++ return self.get_properties()[GATT_DESC_IFACE] + + @dbus.service.method(GATT_DESC_IFACE, + in_signature='a{sv}', +@@ -426,7 +438,7 @@ class TestService(Service): + TEST_SVC_UUID = '12345678-1234-5678-1234-56789abcdef0' + + def __init__(self, bus, index): +- Service.__init__(self, bus, index, self.TEST_SVC_UUID, False) ++ Service.__init__(self, bus, index, self.TEST_SVC_UUID, True) + self.add_characteristic(TestCharacteristic(bus, 0, self)) + self.add_characteristic(TestEncryptCharacteristic(bus, 1, self)) + self.add_characteristic(TestSecureCharacteristic(bus, 2, self)) +@@ -523,11 +535,11 @@ class TestEncryptCharacteristic(Characteristic): + CharacteristicUserDescriptionDescriptor(bus, 3, self)) + + def ReadValue(self, options): +- print('TestCharacteristic Read: ' + repr(self.value)) ++ print('TestEncryptCharacteristic Read: ' + repr(self.value)) + return self.value + + def WriteValue(self, value, options): +- print('TestCharacteristic Write: ' + repr(value)) ++ print('TestEncryptCharacteristic Write: ' + repr(value)) + self.value = value + + class TestEncryptDescriptor(Descriptor): +@@ -564,16 +576,16 @@ class TestSecureCharacteristic(Characteristic): + ['secure-read', 'secure-write'], + service) + self.value = [] +- self.add_descriptor(TestEncryptDescriptor(bus, 2, self)) ++ self.add_descriptor(TestSecureDescriptor(bus, 2, self)) + self.add_descriptor( + CharacteristicUserDescriptionDescriptor(bus, 3, self)) + + def ReadValue(self, options): +- print('TestCharacteristic Read: ' + repr(self.value)) ++ print('TestSecureCharacteristic Read: ' + repr(self.value)) + return self.value + + def WriteValue(self, value, options): +- print('TestCharacteristic Write: ' + repr(value)) ++ print('TestSecureCharacteristic Write: ' + repr(value)) + self.value = value + + +@@ -636,6 +648,8 @@ def main(): + + mainloop = GObject.MainLoop() + ++ print('Registering GATT application...') ++ + service_manager.RegisterApplication(app.get_path(), {}, + reply_handler=register_app_cb, + error_handler=register_app_error_cb) diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0005-core-Prefer-BR-EDR-over-LE-if-it-set-in-advertisemen.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0005-core-Prefer-BR-EDR-over-LE-if-it-set-in-advertisemen.patch new file mode 100644 index 000000000..310dd5a1b --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0005-core-Prefer-BR-EDR-over-LE-if-it-set-in-advertisemen.patch @@ -0,0 +1,47 @@ +From 2f78f64aee11dde478fd76f1e15bb1b977ba7099 Mon Sep 17 00:00:00 2001 +From: Luiz Augusto von Dentz +Date: Wed, 10 Aug 2016 16:23:56 +0300 +Subject: [PATCH 1/7] core: Prefer BR/EDR over LE if it set in advertisement + flag + +This makes the code prefer BR/EDR if the last advertisement has it set +in the flags. +--- + src/adapter.c | 5 ++++- + src/device.c | 6 +++++- + 2 files changed, 9 insertions(+), 2 deletions(-) + +diff --git a/src/adapter.c b/src/adapter.c +index 37423985dfb4..ddabf2de5462 100644 +--- a/src/adapter.c ++++ b/src/adapter.c +@@ -5488,8 +5488,11 @@ static void update_found_devices(struct btd_adapter *adapter, + * supports this we can make the non-zero check conditional. + */ + if (bdaddr_type != BDADDR_BREDR && eir_data.flags && +- !(eir_data.flags & EIR_BREDR_UNSUP)) ++ !(eir_data.flags & EIR_BREDR_UNSUP)) { + device_set_bredr_support(dev); ++ /* Update last seen for BR/EDR in case its flag is set */ ++ device_update_last_seen(dev, BDADDR_BREDR); ++ } + + if (eir_data.name != NULL && eir_data.name_complete) + device_store_cached_name(dev, eir_data.name); +diff --git a/src/device.c b/src/device.c +index 82704f8bb343..7f40af44cd01 100644 +--- a/src/device.c ++++ b/src/device.c +@@ -1763,7 +1763,11 @@ static uint8_t select_conn_bearer(struct btd_device *dev) + if (dev->le && (!dev->bredr || bredr_last == NVAL_TIME)) + return dev->bdaddr_type; + +- if (bredr_last < le_last) ++ /* ++ * Prefer BR/EDR if time is the same since it might be from an ++ * advertisement with BR/EDR flag set. ++ */ ++ if (bredr_last <= le_last) + return BDADDR_BREDR; + + return dev->bdaddr_type; diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0006-core-device-Fix-not-connecting-services-properly.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0006-core-device-Fix-not-connecting-services-properly.patch new file mode 100644 index 000000000..11fa4e12f --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0006-core-device-Fix-not-connecting-services-properly.patch @@ -0,0 +1,38 @@ +From 727cf85d5c710193df9b386b2a87afccbbc766ff Mon Sep 17 00:00:00 2001 +From: Luiz Augusto von Dentz +Date: Fri, 12 Aug 2016 11:20:10 +0300 +Subject: [PATCH 2/7] core/device: Fix not connecting services properly + +Device.Connect shall check if the service discovery is pending or no +service have been connected yet before switching to LE otherwise these +services may never be connected. +--- + src/device.c | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/src/device.c b/src/device.c +index 7f40af44cd01..460a9980fc63 100644 +--- a/src/device.c ++++ b/src/device.c +@@ -1779,9 +1779,18 @@ static DBusMessage *dev_connect(DBusConnection *conn, DBusMessage *msg, + struct btd_device *dev = user_data; + uint8_t bdaddr_type; + +- if (dev->bredr_state.connected) +- bdaddr_type = dev->bdaddr_type; +- else if (dev->le_state.connected && dev->bredr) ++ if (dev->bredr_state.connected) { ++ /* ++ * Check if services have been resolved and there is at list ++ * one connected before switching to connect LE. ++ */ ++ if (dev->bredr_state.svc_resolved && ++ find_service_with_state(dev->services, ++ BTD_SERVICE_STATE_CONNECTED)) ++ bdaddr_type = dev->bdaddr_type; ++ else ++ bdaddr_type = BDADDR_BREDR; ++ } else if (dev->le_state.connected && dev->bredr) + bdaddr_type = BDADDR_BREDR; + else + bdaddr_type = select_conn_bearer(dev); diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0007-core-device-Fix-marking-auto-connect-flag.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0007-core-device-Fix-marking-auto-connect-flag.patch new file mode 100644 index 000000000..39278978b --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0007-core-device-Fix-marking-auto-connect-flag.patch @@ -0,0 +1,29 @@ +From 7e6b4a0de4580af0cefa8b3d45677f2f9f103f65 Mon Sep 17 00:00:00 2001 +From: Luiz Augusto von Dentz +Date: Mon, 22 Aug 2016 13:04:15 +0300 +Subject: [PATCH 3/7] core/device: Fix marking auto-connect flag + +Device auto-connect shall be set only if the profile is able to accept +incoming connections, this fixes the wrong behavior or connecting LE +with dual mode devices immediatelly after probing service as profiles +may have auto-connect flag for outgoing connection (usually BR/EDR only). +--- + src/device.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/device.c b/src/device.c +index 460a9980fc63..0b13a3190539 100644 +--- a/src/device.c ++++ b/src/device.c +@@ -4084,7 +4084,10 @@ static struct btd_service *probe_service(struct btd_device *device, + return NULL; + } + +- if (profile->auto_connect) ++ /* Only set auto connect if profile has set the flag and can really ++ * accept connections. ++ */ ++ if (profile->auto_connect && profile->accept) + device_set_auto_connect(device, TRUE); + + return service; diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0008-core-device-Prefer-bonded-bearers-when-connecting.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0008-core-device-Prefer-bonded-bearers-when-connecting.patch new file mode 100644 index 000000000..bf111f2f2 --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0008-core-device-Prefer-bonded-bearers-when-connecting.patch @@ -0,0 +1,30 @@ +From 3a908f611b0ea84e3388215ae800d9bec05b10b6 Mon Sep 17 00:00:00 2001 +From: Luiz Augusto von Dentz +Date: Tue, 23 Aug 2016 12:58:03 +0300 +Subject: [PATCH 4/7] core/device: Prefer bonded bearers when connecting + +When attempting to connect a dual-mode device prefer bonded bearer if +only one has been marked as bonded. This prevents connecting to a +different bearer after pairing is complete and cross transport pairing +is not supported. +--- + src/device.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/device.c b/src/device.c +index 0b13a3190539..ade74e58a3bf 100644 +--- a/src/device.c ++++ b/src/device.c +@@ -1742,6 +1742,12 @@ static uint8_t select_conn_bearer(struct btd_device *dev) + time_t bredr_last = NVAL_TIME, le_last = NVAL_TIME; + time_t current = time(NULL); + ++ /* Prefer bonded bearer in case only one is bonded */ ++ if (dev->bredr_state.bonded && !dev->le_state.bonded ) ++ return BDADDR_BREDR; ++ else if (!dev->bredr_state.bonded && dev->le_state.bonded) ++ return dev->bdaddr_type; ++ + if (dev->bredr_seen) { + bredr_last = current - dev->bredr_seen; + if (bredr_last > SEEN_TRESHHOLD) diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0009-input-hog-Use-.accept-and-.disconnect-instead-of-att.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0009-input-hog-Use-.accept-and-.disconnect-instead-of-att.patch new file mode 100644 index 000000000..168932afc --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0009-input-hog-Use-.accept-and-.disconnect-instead-of-att.patch @@ -0,0 +1,137 @@ +From ddaa8ad58cd798c218ed9cc2c798cdaac6ed4924 Mon Sep 17 00:00:00 2001 +From: Luiz Augusto von Dentz +Date: Mon, 26 Sep 2016 16:44:03 +0300 +Subject: [PATCH 5/7] input/hog: Use .accept and .disconnect instead of attio + +This adds .accept and .disconnect callbacks instead of attio which +is deprecated. +--- + profiles/input/hog.c | 56 ++++++++++++++++++++++++++-------------------------- + src/device.c | 8 ++++++++ + src/device.h | 1 + + 3 files changed, 37 insertions(+), 28 deletions(-) + +diff --git a/profiles/input/hog.c b/profiles/input/hog.c +index a934c6238525..b25437917188 100644 +--- a/profiles/input/hog.c ++++ b/profiles/input/hog.c +@@ -69,24 +69,6 @@ struct hog_device { + static gboolean suspend_supported = FALSE; + static struct queue *devices = NULL; + +-static void attio_connected_cb(GAttrib *attrib, gpointer user_data) +-{ +- struct hog_device *dev = user_data; +- +- DBG("HoG connected"); +- +- bt_hog_attach(dev->hog, attrib); +-} +- +-static void attio_disconnected_cb(gpointer user_data) +-{ +- struct hog_device *dev = user_data; +- +- DBG("HoG disconnected"); +- +- bt_hog_detach(dev->hog); +-} +- + static struct hog_device *hog_device_new(struct btd_device *device, + struct gatt_primary *prim) + { +@@ -115,15 +97,6 @@ static struct hog_device *hog_device_new(struct btd_device *device, + + dev->device = btd_device_ref(device); + +- /* +- * TODO: Remove attio callback and use .accept once using +- * bt_gatt_client. +- */ +- dev->attioid = btd_device_add_attio_callback(device, +- attio_connected_cb, +- attio_disconnected_cb, +- dev); +- + if (!devices) + devices = queue_new(); + +@@ -142,7 +115,6 @@ static void hog_device_free(void *data) + devices = NULL; + } + +- btd_device_remove_attio_callback(dev->device, dev->attioid); + btd_device_unref(dev->device); + bt_hog_unref(dev->hog); + free(dev); +@@ -215,11 +187,39 @@ static void hog_remove(struct btd_service *service) + hog_device_free(dev); + } + ++static int hog_accept(struct btd_service *service) ++{ ++ struct hog_device *dev = btd_service_get_user_data(service); ++ struct btd_device *device = btd_service_get_device(service); ++ GAttrib *attrib = btd_device_get_attrib(device); ++ ++ /* TODO: Replace GAttrib with bt_gatt_client */ ++ bt_hog_attach(dev->hog, attrib); ++ ++ btd_service_connecting_complete(service, 0); ++ ++ return 0; ++} ++ ++static int hog_disconnect(struct btd_service *service) ++{ ++ struct hog_device *dev = btd_service_get_user_data(service); ++ ++ bt_hog_detach(dev->hog); ++ ++ btd_service_disconnecting_complete(service, 0); ++ ++ return 0; ++} ++ + static struct btd_profile hog_profile = { + .name = "input-hog", + .remote_uuid = HOG_UUID, + .device_probe = hog_probe, + .device_remove = hog_remove, ++ .accept = hog_accept, ++ .disconnect = hog_disconnect, ++ .auto_connect = true, + }; + + static int hog_init(void) +diff --git a/src/device.c b/src/device.c +index ade74e58a3bf..2a77a2e67232 100644 +--- a/src/device.c ++++ b/src/device.c +@@ -5921,6 +5921,14 @@ struct bt_gatt_client *btd_device_get_gatt_client(struct btd_device *device) + return device->client; + } + ++void *btd_device_get_attrib(struct btd_device *device) ++{ ++ if (!device) ++ return NULL; ++ ++ return device->attrib; ++} ++ + struct bt_gatt_server *btd_device_get_gatt_server(struct btd_device *device) + { + if (!device) +diff --git a/src/device.h b/src/device.h +index db108278a12e..387f598fb2e5 100644 +--- a/src/device.h ++++ b/src/device.h +@@ -70,6 +70,7 @@ GSList *btd_device_get_primaries(struct btd_device *device); + struct gatt_db *btd_device_get_gatt_db(struct btd_device *device); + struct bt_gatt_client *btd_device_get_gatt_client(struct btd_device *device); + struct bt_gatt_server *btd_device_get_gatt_server(struct btd_device *device); ++void *btd_device_get_attrib(struct btd_device *device); + void btd_device_gatt_set_service_changed(struct btd_device *device, + uint16_t start, uint16_t end); + bool device_attach_att(struct btd_device *dev, GIOChannel *io); diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0010-src-device-Free-bonding-while-failed-to-pair-device.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0010-src-device-Free-bonding-while-failed-to-pair-device.patch new file mode 100644 index 000000000..3e11556d4 --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0010-src-device-Free-bonding-while-failed-to-pair-device.patch @@ -0,0 +1,99 @@ +From c0202538bc31e25f37fc45681d07873c8a127ecb Mon Sep 17 00:00:00 2001 +From: Jiangbo Wu +Date: Sun, 2 Oct 2016 20:38:31 +0800 +Subject: [PATCH 6/7] src/device: Free bonding while failed to pair device + +device unable pair since another pairng is in progress, and need to +free bonding before it created for next pairing. +--- + src/device.c | 62 +++++++++++++++++++++++++++++++----------------------------- + 1 file changed, 32 insertions(+), 30 deletions(-) + +diff --git a/src/device.c b/src/device.c +index 2a77a2e67232..97d7c4e899f6 100644 +--- a/src/device.c ++++ b/src/device.c +@@ -2330,6 +2330,35 @@ static void create_bond_req_exit(DBusConnection *conn, void *user_data) + } + } + ++static void bonding_request_free(struct bonding_req *bonding) ++{ ++ if (!bonding) ++ return; ++ ++ if (bonding->listener_id) ++ g_dbus_remove_watch(dbus_conn, bonding->listener_id); ++ ++ if (bonding->msg) ++ dbus_message_unref(bonding->msg); ++ ++ if (bonding->cb_iter) ++ g_free(bonding->cb_iter); ++ ++ if (bonding->agent) { ++ agent_cancel(bonding->agent); ++ agent_unref(bonding->agent); ++ bonding->agent = NULL; ++ } ++ ++ if (bonding->retry_timer) ++ g_source_remove(bonding->retry_timer); ++ ++ if (bonding->device) ++ bonding->device->bonding = NULL; ++ ++ g_free(bonding); ++} ++ + static DBusMessage *pair_device(DBusConnection *conn, DBusMessage *msg, + void *data) + { +@@ -2400,8 +2429,10 @@ static DBusMessage *pair_device(DBusConnection *conn, DBusMessage *msg, + BDADDR_BREDR, io_cap); + } + +- if (err < 0) ++ if (err < 0) { ++ bonding_request_free(device->bonding); + return btd_error_failed(msg, strerror(-err)); ++ } + + return NULL; + } +@@ -2442,35 +2473,6 @@ static DBusMessage *new_authentication_return(DBusMessage *msg, uint8_t status) + } + } + +-static void bonding_request_free(struct bonding_req *bonding) +-{ +- if (!bonding) +- return; +- +- if (bonding->listener_id) +- g_dbus_remove_watch(dbus_conn, bonding->listener_id); +- +- if (bonding->msg) +- dbus_message_unref(bonding->msg); +- +- if (bonding->cb_iter) +- g_free(bonding->cb_iter); +- +- if (bonding->agent) { +- agent_cancel(bonding->agent); +- agent_unref(bonding->agent); +- bonding->agent = NULL; +- } +- +- if (bonding->retry_timer) +- g_source_remove(bonding->retry_timer); +- +- if (bonding->device) +- bonding->device->bonding = NULL; +- +- g_free(bonding); +-} +- + static void device_cancel_bonding(struct btd_device *device, uint8_t status) + { + struct bonding_req *bonding = device->bonding; diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0011-core-Fix-BR-EDR-pairing-for-dual-mode-devices.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0011-core-Fix-BR-EDR-pairing-for-dual-mode-devices.patch new file mode 100644 index 000000000..f667587a9 --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0011-core-Fix-BR-EDR-pairing-for-dual-mode-devices.patch @@ -0,0 +1,189 @@ +From 4fbef59d01931111c3181194ec4d38cbcb4da45a Mon Sep 17 00:00:00 2001 +From: Szymon Janc +Date: Fri, 21 Oct 2016 21:41:18 +0200 +Subject: [PATCH 7/7] core: Fix BR/EDR pairing for dual mode devices + +For dual mode devices we need to pass address type used in pairing +events to reply with correct one on agent reply. Otherwise reply for +BR/EDR pairing of dual mode device would use address type (which is +valid only for LE address) resulting in reply being ignored by kernel +and eventually pairing timeout. +--- + src/adapter.c | 7 ++++--- + src/device.c | 31 +++++++++++++++++-------------- + src/device.h | 10 +++++----- + 3 files changed, 26 insertions(+), 22 deletions(-) + +diff --git a/src/adapter.c b/src/adapter.c +index ddabf2de5462..5ebe3d7c8eec 100644 +--- a/src/adapter.c ++++ b/src/adapter.c +@@ -6180,7 +6180,7 @@ static void user_confirm_request_callback(uint16_t index, uint16_t length, + return; + } + +- err = device_confirm_passkey(device, btohl(ev->value), ++ err = device_confirm_passkey(device, ev->addr.type, btohl(ev->value), + ev->confirm_hint); + if (err < 0) { + btd_error(adapter->dev_id, +@@ -6254,7 +6254,7 @@ static void user_passkey_request_callback(uint16_t index, uint16_t length, + return; + } + +- err = device_request_passkey(device); ++ err = device_request_passkey(device, ev->addr.type); + if (err < 0) { + btd_error(adapter->dev_id, + "device_request_passkey: %s", strerror(-err)); +@@ -6293,7 +6293,8 @@ static void user_passkey_notify_callback(uint16_t index, uint16_t length, + + DBG("passkey %06u entered %u", passkey, ev->entered); + +- err = device_notify_passkey(device, passkey, ev->entered); ++ err = device_notify_passkey(device, ev->addr.type, passkey, ++ ev->entered); + if (err < 0) + btd_error(adapter->dev_id, + "device_notify_passkey: %s", strerror(-err)); +diff --git a/src/device.c b/src/device.c +index 97d7c4e899f6..d6be3fcf82c2 100644 +--- a/src/device.c ++++ b/src/device.c +@@ -127,6 +127,7 @@ struct authentication_req { + auth_type_t type; + struct agent *agent; + struct btd_device *device; ++ uint8_t addr_type; + uint32_t passkey; + char *pincode; + gboolean secure; +@@ -5644,7 +5645,7 @@ static void confirm_cb(struct agent *agent, DBusError *err, void *data) + return; + + btd_adapter_confirm_reply(device->adapter, &device->bdaddr, +- device->bdaddr_type, ++ auth->addr_type, + err ? FALSE : TRUE); + + agent_unref(device->authr->agent); +@@ -5665,7 +5666,7 @@ static void passkey_cb(struct agent *agent, DBusError *err, + passkey = INVALID_PASSKEY; + + btd_adapter_passkey_reply(device->adapter, &device->bdaddr, +- device->bdaddr_type, passkey); ++ auth->addr_type, passkey); + + agent_unref(device->authr->agent); + device->authr->agent = NULL; +@@ -5683,7 +5684,9 @@ static void display_pincode_cb(struct agent *agent, DBusError *err, void *data) + } + + static struct authentication_req *new_auth(struct btd_device *device, +- auth_type_t type, gboolean secure) ++ uint8_t addr_type, ++ auth_type_t type, ++ gboolean secure) + { + struct authentication_req *auth; + struct agent *agent; +@@ -5711,6 +5714,7 @@ static struct authentication_req *new_auth(struct btd_device *device, + auth->agent = agent; + auth->device = device; + auth->type = type; ++ auth->addr_type = addr_type; + auth->secure = secure; + device->authr = auth; + +@@ -5722,7 +5726,7 @@ int device_request_pincode(struct btd_device *device, gboolean secure) + struct authentication_req *auth; + int err; + +- auth = new_auth(device, AUTH_TYPE_PINCODE, secure); ++ auth = new_auth(device, BDADDR_BREDR, AUTH_TYPE_PINCODE, secure); + if (!auth) + return -EPERM; + +@@ -5736,12 +5740,12 @@ int device_request_pincode(struct btd_device *device, gboolean secure) + return err; + } + +-int device_request_passkey(struct btd_device *device) ++int device_request_passkey(struct btd_device *device, uint8_t type) + { + struct authentication_req *auth; + int err; + +- auth = new_auth(device, AUTH_TYPE_PASSKEY, FALSE); ++ auth = new_auth(device, type, AUTH_TYPE_PASSKEY, FALSE); + if (!auth) + return -EPERM; + +@@ -5755,14 +5759,13 @@ int device_request_passkey(struct btd_device *device) + return err; + } + +-int device_confirm_passkey(struct btd_device *device, uint32_t passkey, +- uint8_t confirm_hint) +- ++int device_confirm_passkey(struct btd_device *device, uint8_t type, ++ int32_t passkey, uint8_t confirm_hint) + { + struct authentication_req *auth; + int err; + +- auth = new_auth(device, AUTH_TYPE_CONFIRM, FALSE); ++ auth = new_auth(device, type, AUTH_TYPE_CONFIRM, FALSE); + if (!auth) + return -EPERM; + +@@ -5783,8 +5786,8 @@ int device_confirm_passkey(struct btd_device *device, uint32_t passkey, + return err; + } + +-int device_notify_passkey(struct btd_device *device, uint32_t passkey, +- uint8_t entered) ++int device_notify_passkey(struct btd_device *device, uint8_t type, ++ uint32_t passkey, uint8_t entered) + { + struct authentication_req *auth; + int err; +@@ -5794,7 +5797,7 @@ int device_notify_passkey(struct btd_device *device, uint32_t passkey, + if (auth->type != AUTH_TYPE_NOTIFY_PASSKEY) + return -EPERM; + } else { +- auth = new_auth(device, AUTH_TYPE_NOTIFY_PASSKEY, FALSE); ++ auth = new_auth(device, type, AUTH_TYPE_NOTIFY_PASSKEY, FALSE); + if (!auth) + return -EPERM; + } +@@ -5814,7 +5817,7 @@ int device_notify_pincode(struct btd_device *device, gboolean secure, + struct authentication_req *auth; + int err; + +- auth = new_auth(device, AUTH_TYPE_NOTIFY_PINCODE, secure); ++ auth = new_auth(device, BDADDR_BREDR, AUTH_TYPE_NOTIFY_PINCODE, secure); + if (!auth) + return -EPERM; + +diff --git a/src/device.h b/src/device.h +index 387f598fb2e5..dd7c4f300be1 100644 +--- a/src/device.h ++++ b/src/device.h +@@ -110,11 +110,11 @@ int device_bonding_attempt_retry(struct btd_device *device); + long device_bonding_last_duration(struct btd_device *device); + void device_bonding_restart_timer(struct btd_device *device); + int device_request_pincode(struct btd_device *device, gboolean secure); +-int device_request_passkey(struct btd_device *device); +-int device_confirm_passkey(struct btd_device *device, uint32_t passkey, +- uint8_t confirm_hint); +-int device_notify_passkey(struct btd_device *device, uint32_t passkey, +- uint8_t entered); ++int device_request_passkey(struct btd_device *device, uint8_t type); ++int device_confirm_passkey(struct btd_device *device, uint8_t type, ++ int32_t passkey, uint8_t confirm_hint); ++int device_notify_passkey(struct btd_device *device, uint8_t type, ++ uint32_t passkey, uint8_t entered); + int device_notify_pincode(struct btd_device *device, gboolean secure, + const char *pincode); + void device_cancel_authentication(struct btd_device *device, gboolean aborted); diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0012-QCA_bluetooth_chip_support.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0012-QCA_bluetooth_chip_support.patch new file mode 100644 index 000000000..1f6e178c4 --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0012-QCA_bluetooth_chip_support.patch @@ -0,0 +1,4190 @@ +Add hciattach rome support for Qualcomm chip QCA6564 + +This is a multiple patch including all the specific qualcomm commits to add +support for its chip in bluez stack (hciattach rome). + +Signed-off-by: Isaac Hermida + +From e6d2fb7efcde66f9ab22a42bd6d7039a4f0c02cd Mon Sep 17 00:00:00 2001 +From: Anantha Krishnan +Date: Tue, 19 Aug 2014 20:23:01 +0530 +Subject: [PATCH 01/19] bluetooth : Add bluetooth support for QCA6174 chip. + +Register the QCA6174 initialization routine with hciattach for +downloading firmware patches to the bluetooth controller. +Add optional support 'f' to control installation of line +discipline driver. Invoke hciattach from command line and +download the firmware patches: + hciattach /dev/ttyHS0 qca 3000000 -t120 flow -f0 + +Change-Id: I87f2927d7096904071a02d73d3afef0dc34db414 +Signed-off-by: Rupesh Tatiya +--- + Makefile.tools | 3 +- + tools/hciattach.c | 25 +- + tools/hciattach.h | 8 +- + tools/hciattach_rome.c | 1578 ++++++++++++++++++++++++++++++++++++++++++++++++ + tools/hciattach_rome.h | 317 ++++++++++ + 5 files changed, 1926 insertions(+), 5 deletions(-) + create mode 100644 tools/hciattach_rome.c + create mode 100644 tools/hciattach_rome.h + +diff --git a/Makefile.tools b/Makefile.tools +index 0d5f1431e013..8f087c597490 100644 +--- a/Makefile.tools ++++ b/Makefile.tools +@@ -164,7 +164,8 @@ tools_hciattach_SOURCES = tools/hciattach.c tools/hciattach.h \ + tools/hciattach_ath3k.c \ + tools/hciattach_qualcomm.c \ + tools/hciattach_intel.c \ +- tools/hciattach_bcm43xx.c ++ tools/hciattach_bcm43xx.c \ ++ tools/hciattach_rome.c tools/hciattach_rome.h + tools_hciattach_LDADD = lib/libbluetooth-internal.la + + tools_hciconfig_SOURCES = tools/hciconfig.c tools/csr.h tools/csr.c +diff --git a/tools/hciattach.c b/tools/hciattach.c +index fad176c9b804..73811d4c4c2a 100644 +--- a/tools/hciattach.c ++++ b/tools/hciattach.c +@@ -69,6 +69,8 @@ struct uart_t { + #define ENABLE_PM 1 + #define DISABLE_PM 0 + ++int line_disp = 1; ++ + static volatile sig_atomic_t __io_canceled = 0; + + static void sig_hup(int sig) +@@ -263,6 +265,12 @@ static int ath3k_pm(int fd, struct uart_t *u, struct termios *ti) + return ath3k_post(fd, u->pm); + } + ++static int qca(int fd, struct uart_t *u, struct termios *ti) ++{ ++ fprintf(stderr,"qca\n"); ++ return qca_soc_init(fd, u->bdaddr); ++} ++ + static int qualcomm(int fd, struct uart_t *u, struct termios *ti) + { + return qualcomm_init(fd, u->speed, ti, u->bdaddr); +@@ -1093,6 +1101,10 @@ struct uart_t uart[] = { + { "ath3k", 0x0000, 0x0000, HCI_UART_ATH3K, 115200, 115200, + FLOW_CTL, DISABLE_PM, NULL, ath3k_ps, ath3k_pm }, + ++ /* QCA ROME */ ++ { "qca", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, ++ FLOW_CTL, DISABLE_PM, NULL, qca, NULL }, ++ + /* QUALCOMM BTS */ + { "qualcomm", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, + FLOW_CTL, DISABLE_PM, NULL, qualcomm, NULL }, +@@ -1195,6 +1207,7 @@ static int init_uart(char *dev, struct uart_t *u, int send_break, int raw) + goto fail; + } + ++if (line_disp) { + /* Set TTY to N_HCI line discipline */ + i = N_HCI; + if (ioctl(fd, TIOCSETD, &i) < 0) { +@@ -1211,6 +1224,7 @@ static int init_uart(char *dev, struct uart_t *u, int send_break, int raw) + perror("Can't set device"); + goto fail; + } ++} + + if (u->post && u->post(fd, u, &ti) < 0) + goto fail; +@@ -1249,7 +1263,7 @@ int main(int argc, char *argv[]) + printpid = 0; + raw = 0; + +- while ((opt=getopt(argc, argv, "bnpt:s:lr")) != EOF) { ++ while ((opt=getopt(argc, argv, "bnpt:s:lrf:")) != EOF) { + switch(opt) { + case 'b': + send_break = 1; +@@ -1282,6 +1296,11 @@ int main(int argc, char *argv[]) + raw = 1; + break; + ++ case 'f': ++ line_disp = atoi(optarg); ++ fprintf(stderr, "Line_disp val : %d\n", line_disp); ++ break; ++ + default: + usage(); + exit(1); +@@ -1350,6 +1369,7 @@ int main(int argc, char *argv[]) + case 5: + u->bdaddr = argv[optind]; + break; ++ + } + } + +@@ -1426,12 +1446,15 @@ int main(int argc, char *argv[]) + break; + } + ++if (line_disp) { + /* Restore TTY line discipline */ ++ fprintf(stderr, "Restoring the Line Discipline driver\n"); + ld = N_TTY; + if (ioctl(n, TIOCSETD, &ld) < 0) { + perror("Can't restore line discipline"); + exit(1); + } ++} + + return 0; + } +diff --git a/tools/hciattach.h b/tools/hciattach.h +index 4279a3361749..0656a845223c 100644 +--- a/tools/hciattach.h ++++ b/tools/hciattach.h +@@ -39,9 +39,10 @@ + #define HCI_UART_H4DS 3 + #define HCI_UART_LL 4 + #define HCI_UART_ATH3K 5 +-#define HCI_UART_INTEL 6 +-#define HCI_UART_BCM 7 +-#define HCI_UART_QCA 8 ++#define HCI_UART_IBS 6 ++#define HCI_UART_INTEL 7 ++#define HCI_UART_BCM 8 ++#define HCI_UART_QCA 9 + + #define HCI_UART_RAW_DEVICE 0 + #define HCI_UART_RESET_ON_INIT 1 +@@ -63,6 +64,7 @@ int ath3k_init(int fd, int speed, int init_speed, char *bdaddr, + struct termios *ti); + int ath3k_post(int fd, int pm); + int qualcomm_init(int fd, int speed, struct termios *ti, const char *bdaddr); ++int qca_soc_init(int fd, char *bdaddr); + int intel_init(int fd, int init_speed, int *speed, struct termios *ti); + int bcm43xx_init(int fd, int def_speed, int speed, struct termios *ti, + const char *bdaddr); +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +new file mode 100644 +index 000000000000..f31be43c09e4 +--- /dev/null ++++ b/tools/hciattach_rome.c +@@ -0,0 +1,1578 @@ ++/* ++ * ++ * Copyright (c) 2013, The Linux Foundation. All rights reserved. ++ * Not a Contribution. ++ * ++ * Copyright 2012 The Android Open Source Project ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); you ++ * may not use this file except in compliance with the License. You may ++ * obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or ++ * implied. See the License for the specific language governing ++ * permissions and limitations under the License. ++ * ++ */ ++ ++/****************************************************************************** ++ * ++ * Filename: hciattach_rome.c ++ * ++ * Description: Contains controller-specific functions, like ++ * firmware patch download ++ * low power mode operations ++ * ++ ******************************************************************************/ ++ ++#define LOG_TAG "bt_vendor" ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "hciattach_rome.h" ++#include "hciattach.h" ++ ++#ifdef __cplusplus ++} ++#endif ++ ++ ++/****************************************************************************** ++** Variables ++******************************************************************************/ ++FILE *file; ++unsigned char *phdr_buffer; ++unsigned char *pdata_buffer = NULL; ++patch_info rampatch_patch_info; ++int rome_ver = ROME_VER_UNKNOWN; ++unsigned char gTlv_type; ++char *rampatch_file_path; ++char *nvm_file_path; ++vnd_userial_cb_t vnd_userial; ++/****************************************************************************** ++** Extern variables ++******************************************************************************/ ++//extern unsigned char vnd_local_bd_addr[6]; ++ ++/***************************************************************************** ++** Functions ++*****************************************************************************/ ++ ++/******************************************************************************* ++** ++** Function userial_to_tcio_baud ++** ++** Description helper function converts USERIAL baud rates into TCIO ++** conforming baud rates ++** ++** Returns TRUE/FALSE ++** ++*******************************************************************************/ ++unsigned char userial_to_tcio_baud(unsigned char cfg_baud, unsigned int *baud) ++{ ++ if (cfg_baud == USERIAL_BAUD_115200) ++ *baud = B115200; ++ else if (cfg_baud == USERIAL_BAUD_4M) ++ *baud = B4000000; ++ else if (cfg_baud == USERIAL_BAUD_3M) ++ *baud = B3000000; ++ else if (cfg_baud == USERIAL_BAUD_2M) ++ *baud = B2000000; ++ else if (cfg_baud == USERIAL_BAUD_1M) ++ *baud = B1000000; ++ else if (cfg_baud == USERIAL_BAUD_921600) ++ *baud = B921600; ++ else if (cfg_baud == USERIAL_BAUD_460800) ++ *baud = B460800; ++ else if (cfg_baud == USERIAL_BAUD_230400) ++ *baud = B230400; ++ else if (cfg_baud == USERIAL_BAUD_57600) ++ *baud = B57600; ++ else if (cfg_baud == USERIAL_BAUD_19200) ++ *baud = B19200; ++ else if (cfg_baud == USERIAL_BAUD_9600) ++ *baud = B9600; ++ else if (cfg_baud == USERIAL_BAUD_1200) ++ *baud = B1200; ++ else if (cfg_baud == USERIAL_BAUD_600) ++ *baud = B600; ++ else ++ { ++ fprintf(stderr, "userial vendor open: unsupported baud idx %i\n", cfg_baud); ++ *baud = B115200; ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++ ++/******************************************************************************* ++** ++** Function userial_vendor_set_baud ++** ++** Description Set new baud rate ++** ++** Returns None ++** ++*******************************************************************************/ ++void userial_vendor_set_baud(unsigned char userial_baud) ++{ ++ unsigned int tcio_baud; ++ fprintf(stderr, "## userial_vendor_set_baud: %d\n", userial_baud); ++ ++ userial_to_tcio_baud(userial_baud, &tcio_baud); ++ ++ cfsetospeed(&vnd_userial.termios, tcio_baud); ++ cfsetispeed(&vnd_userial.termios, tcio_baud); ++ tcsetattr(vnd_userial.fd, TCSADRAIN, &vnd_userial.termios); /* don't change speed until last write done */ ++ ++} ++ ++ ++/******************************************************************************* ++** ++** Function userial_vendor_ioctl ++** ++** Description ioctl inteface ++** ++** Returns None ++** ++*******************************************************************************/ ++int userial_vendor_ioctl(int fd, userial_vendor_ioctl_op_t op, int *p_data) ++{ ++ int err = -1; ++ struct termios ti; ++ ++ if (tcgetattr(fd, &ti) < 0) { ++ perror("Can't get port settings"); ++ return -1; ++ } ++ cfmakeraw(&ti); ++ ti.c_cflag |= CLOCAL; ++ ++ switch(op) ++ { ++#if (BT_WAKE_VIA_USERIAL_IOCTL==TRUE) ++ case USERIAL_OP_ASSERT_BT_WAKE: ++ VNDUSERIALDBG("## userial_vendor_ioctl: Asserting BT_Wake ##"); ++ err = ioctl(fd, USERIAL_IOCTL_BT_WAKE_ASSERT, NULL); ++ break; ++ ++ case USERIAL_OP_DEASSERT_BT_WAKE: ++ VNDUSERIALDBG("## userial_vendor_ioctl: De-asserting BT_Wake ##"); ++ err = ioctl(fd, USERIAL_IOCTL_BT_WAKE_DEASSERT, NULL); ++ break; ++ ++ case USERIAL_OP_GET_BT_WAKE_STATE: ++ err = ioctl(fd, USERIAL_IOCTL_BT_WAKE_GET_ST, p_data); ++ break; ++#endif // (BT_WAKE_VIA_USERIAL_IOCTL==TRUE) ++ case USERIAL_OP_FLOW_ON: ++ fprintf(stderr, "## userial_vendor_ioctl: UART Flow On\n "); ++ ti.c_cflag |= CRTSCTS; ++ ++ if (err = tcsetattr(fd, TCSANOW, &ti) < 0) { ++ perror("Can't set port settings"); ++ return -1; ++ } ++ ++ break; ++ ++ case USERIAL_OP_FLOW_OFF: ++ fprintf(stderr, "## userial_vendor_ioctl: UART Flow Off\n "); ++ ti.c_cflag &= ~CRTSCTS; ++ if (err = tcsetattr(fd, TCSANOW, &ti) < 0) { ++ fprintf(stderr, "Can't set port settings"); ++ return -1; ++ } ++ break; ++ ++ default: ++ break; ++ } ++ ++ return err; ++} ++ ++ ++int get_vs_hci_event(unsigned char *rsp) ++{ ++ int err = 0, soc_id =0; ++ unsigned char paramlen = 0; ++ ++ if( (rsp[EVENTCODE_OFFSET] == VSEVENT_CODE) || (rsp[EVENTCODE_OFFSET] == EVT_CMD_COMPLETE)) ++ fprintf(stderr, "%s: Received HCI-Vendor Specific event\n", __FUNCTION__); ++ else { ++ fprintf(stderr, "%s: Failed to receive HCI-Vendor Specific event\n", __FUNCTION__); ++ err = -EIO; ++ goto failed; ++ } ++ ++ fprintf(stderr, "%s: Parameter Length: 0x%x\n", __FUNCTION__, paramlen = rsp[EVT_PLEN]); ++ fprintf(stderr, "%s: Command response: 0x%x\n", __FUNCTION__, rsp[CMD_RSP_OFFSET]); ++ fprintf(stderr, "%s: Response type : 0x%x\n", __FUNCTION__, rsp[RSP_TYPE_OFFSET]); ++ ++ /* Check the status of the operation */ ++ switch ( rsp[CMD_RSP_OFFSET] ) ++ { ++ case EDL_CMD_REQ_RES_EVT: ++ fprintf(stderr, "%s: Command Request Response\n", __FUNCTION__); ++ switch(rsp[RSP_TYPE_OFFSET]) ++ { ++ case EDL_PATCH_VER_RES_EVT: ++ case EDL_APP_VER_RES_EVT: ++ fprintf(stderr, "\t Current Product ID\t\t: 0x%08x\n", ++ (unsigned int)(rsp[PATCH_PROD_ID_OFFSET +3] << 24 | ++ rsp[PATCH_PROD_ID_OFFSET+2] << 16 | ++ rsp[PATCH_PROD_ID_OFFSET+1] << 8 | ++ rsp[PATCH_PROD_ID_OFFSET] )); ++ ++ /* Patch Version indicates FW patch version */ ++ fprintf(stderr, "\t Current Patch Version\t\t: 0x%04x\n", ++ (unsigned short)(rsp[PATCH_PATCH_VER_OFFSET + 1] << 8 | ++ rsp[PATCH_PATCH_VER_OFFSET] )); ++ ++ /* ROM Build Version indicates ROM build version like 1.0/1.1/2.0 */ ++ fprintf(stderr, "\t Current ROM Build Version\t: 0x%04x\n", rome_ver = ++ (int)(rsp[PATCH_ROM_BUILD_VER_OFFSET + 1] << 8 | ++ rsp[PATCH_ROM_BUILD_VER_OFFSET] )); ++ ++ /* In case rome 1.0/1.1, there is no SOC ID version available */ ++ if (paramlen - 10) ++ { ++ fprintf(stderr, "\t Current SOC Version\t\t: 0x%08x\n", soc_id = ++ (unsigned int)(rsp[PATCH_SOC_VER_OFFSET +3] << 24 | ++ rsp[PATCH_SOC_VER_OFFSET+2] << 16 | ++ rsp[PATCH_SOC_VER_OFFSET+1] << 8 | ++ rsp[PATCH_SOC_VER_OFFSET] )); ++ } ++ ++ /* Rome Chipset Version can be decided by Patch version and SOC version, ++ Upper 2 bytes will be used for Patch version and Lower 2 bytes will be ++ used for SOC as combination for BT host driver */ ++ rome_ver = (rome_ver << 16) | (soc_id & 0x0000ffff); ++ break; ++ case EDL_TVL_DNLD_RES_EVT: ++ case EDL_CMD_EXE_STATUS_EVT: ++ switch (err = rsp[CMD_STATUS_OFFSET]) ++ { ++ case HCI_CMD_SUCCESS: ++ fprintf(stderr, "%s: Download Packet successfully!\n", __FUNCTION__); ++ break; ++ case PATCH_LEN_ERROR: ++ fprintf(stderr, "%s: Invalid patch length argument passed for EDL PATCH " ++ "SET REQ cmd\n", __FUNCTION__); ++ break; ++ case PATCH_VER_ERROR: ++ fprintf(stderr, "%s: Invalid patch version argument passed for EDL PATCH " ++ "SET REQ cmd\n", __FUNCTION__); ++ break; ++ case PATCH_CRC_ERROR: ++ fprintf(stderr, "%s: CRC check of patch failed!!!\n", __FUNCTION__); ++ break; ++ case PATCH_NOT_FOUND: ++ fprintf(stderr, "%s: Invalid patch data!!!\n", __FUNCTION__); ++ break; ++ case TLV_TYPE_ERROR: ++ fprintf(stderr, "%s: TLV Type Error !!!\n", __FUNCTION__); ++ break; ++ default: ++ fprintf(stderr, "%s: Undefined error (0x%x)", __FUNCTION__, err); ++ break; ++ } ++ break; ++ } ++ break; ++ ++ case NVM_ACCESS_CODE: ++ fprintf(stderr, "%s: NVM Access Code!!!\n", __FUNCTION__); ++ err = HCI_CMD_SUCCESS; ++ break; ++ case EDL_SET_BAUDRATE_RSP_EVT: ++ /* Rome 1.1 has bug with the response, so it should ignore it. */ ++ if (rsp[BAUDRATE_RSP_STATUS_OFFSET] != BAUDRATE_CHANGE_SUCCESS) ++ { ++ fprintf(stderr, "%s: Set Baudrate request failed - 0x%x\n", __FUNCTION__, ++ rsp[CMD_STATUS_OFFSET]); ++ err = -1; ++ } ++ break; ++ default: ++ fprintf(stderr, "%s: Not a valid status!!!\n", __FUNCTION__); ++ err = -1; ++ break; ++ } ++ ++failed: ++ return err; ++} ++ ++ ++/* ++ * Read an VS HCI event from the given file descriptor. ++ */ ++int read_vs_hci_event(int fd, unsigned char* buf, int size) ++{ ++ int remain, r; ++ int count = 0; ++ ++ if (size <= 0) { ++ fprintf(stderr, "Invalid size arguement!\n"); ++ return -1; ++ } ++ ++ fprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC\n", __FUNCTION__); ++ ++ /* The first byte identifies the packet type. For HCI event packets, it ++ * should be 0x04, so we read until we get to the 0x04. */ ++ /* It will keep reading until find 0x04 byte */ ++ while (1) { ++ r = read(fd, buf, 1); ++ if (r <= 0) ++ return -1; ++ if (buf[0] == 0x04) ++ break; ++ } ++ count++; ++ ++ fprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC, buf[0] - 0x%x\n", __FUNCTION__, buf[0]); ++ /* The next two bytes are the event code and parameter total length. */ ++ while (count < 3) { ++ r = read(fd, buf + count, 3 - count); ++ if ((r <= 0) || (buf[1] != 0xFF )) { ++ fprintf(stderr, "It is not VS event !!\n"); ++ return -1; ++ } ++ count += r; ++ } ++ ++ fprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC, buf[1] - 0x%x\n", __FUNCTION__, buf[1]); ++ /* Now we read the parameters. */ ++ if (buf[2] < (size - 3)) ++ remain = buf[2]; ++ else ++ remain = size - 3; ++ ++ while ((count - 3) < remain) { ++ r = read(fd, buf + count, remain - (count - 3)); ++ if (r <= 0) ++ return -1; ++ count += r; ++ } ++ ++ /* Check if the set patch command is successful or not */ ++ if(get_vs_hci_event(buf) != HCI_CMD_SUCCESS) ++ return -1; ++ ++ fprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC, count - 0x%x\n", __FUNCTION__, count); ++ return count; ++} ++ ++ ++int hci_send_vs_cmd(int fd, unsigned char *cmd, unsigned char *rsp, int size) ++{ ++ int ret = 0; ++ ++ /* Send the HCI command packet to UART for transmission */ ++ ret = write(fd, cmd, size); ++ if (ret != size) { ++ fprintf(stderr, "%s: Send failed with ret value: %d\n", __FUNCTION__, ret); ++ goto failed; ++ } ++ ++ /* Check for response from the Controller */ ++ if (read_vs_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE) < 0) { ++ ret = -ETIMEDOUT; ++ fprintf(stderr, "%s: Failed to get HCI-VS Event from SOC\n", __FUNCTION__); ++ goto failed; ++ } ++ ++ fprintf(stderr, "%s: Received HCI-Vendor Specific Event from SOC\n", __FUNCTION__); ++failed: ++ return ret; ++} ++ ++void frame_hci_cmd_pkt( ++ unsigned char *cmd, ++ int edl_cmd, unsigned int p_base_addr, ++ int segtNo, int size ++ ) ++{ ++ int offset = 0; ++ hci_command_hdr *cmd_hdr; ++ ++ memset(cmd, 0x0, HCI_MAX_CMD_SIZE); ++ ++ cmd_hdr = (void *) (cmd + 1); ++ ++ cmd[0] = HCI_COMMAND_PKT; ++ cmd_hdr->opcode = cmd_opcode_pack(HCI_VENDOR_CMD_OGF, HCI_PATCH_CMD_OCF); ++ cmd_hdr->plen = size; ++ cmd[4] = edl_cmd; ++ ++ switch (edl_cmd) ++ { ++ case EDL_PATCH_SET_REQ_CMD: ++ /* Copy the patch header info as CMD params */ ++ memcpy(&cmd[5], phdr_buffer, PATCH_HDR_LEN); ++ fprintf(stderr, "%s: Sending EDL_PATCH_SET_REQ_CMD\n", __FUNCTION__); ++ fprintf(stderr, "HCI-CMD %d:\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n", ++ segtNo, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]); ++ break; ++ case EDL_PATCH_DLD_REQ_CMD: ++ offset = ((segtNo - 1) * MAX_DATA_PER_SEGMENT); ++ p_base_addr += offset; ++ cmd_hdr->plen = (size + 6); ++ cmd[5] = (size + 4); ++ cmd[6] = EXTRACT_BYTE(p_base_addr, 0); ++ cmd[7] = EXTRACT_BYTE(p_base_addr, 1); ++ cmd[8] = EXTRACT_BYTE(p_base_addr, 2); ++ cmd[9] = EXTRACT_BYTE(p_base_addr, 3); ++ memcpy(&cmd[10], (pdata_buffer + offset), size); ++ ++ fprintf(stderr, "%s: Sending EDL_PATCH_DLD_REQ_CMD: size: %d bytes\n", ++ __FUNCTION__, size); ++ fprintf(stderr, "HCI-CMD %d:\t0x%x\t0x%x\t0x%x\t0x%x\t0x%x\t0x%x\t0x%x\t" ++ "0x%x\t0x%x\t0x%x\t\n", segtNo, cmd[0], cmd[1], cmd[2], ++ cmd[3], cmd[4], cmd[5], cmd[6], cmd[7], cmd[8], cmd[9]); ++ break; ++ case EDL_PATCH_ATCH_REQ_CMD: ++ fprintf(stderr, "%s: Sending EDL_PATCH_ATTACH_REQ_CMD\n", __FUNCTION__); ++ fprintf(stderr, "HCI-CMD %d:\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n", ++ segtNo, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]); ++ break; ++ case EDL_PATCH_RST_REQ_CMD: ++ fprintf(stderr, "%s: Sending EDL_PATCH_RESET_REQ_CMD\n", __FUNCTION__); ++ fprintf(stderr, "HCI-CMD %d:\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n", ++ segtNo, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]); ++ break; ++ case EDL_PATCH_VER_REQ_CMD: ++ fprintf(stderr, "%s: Sending EDL_PATCH_VER_REQ_CMD\n", __FUNCTION__); ++ fprintf(stderr, "HCI-CMD %d:\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n", ++ segtNo, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]); ++ break; ++ case EDL_PATCH_TLV_REQ_CMD: ++ fprintf(stderr, "%s: Sending EDL_PATCH_TLV_REQ_CMD\n", __FUNCTION__); ++ /* Parameter Total Length */ ++ cmd[3] = size +2; ++ ++ /* TLV Segment Length */ ++ cmd[5] = size; ++ fprintf(stderr, "HCI-CMD %d:\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n", ++ segtNo, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5]); ++ offset = (segtNo * MAX_SIZE_PER_TLV_SEGMENT); ++ memcpy(&cmd[6], (pdata_buffer + offset), size); ++ break; ++ default: ++ fprintf(stderr, "%s: Unknown EDL CMD !!!\n", __FUNCTION__); ++ } ++} ++ ++void rome_extract_patch_header_info(unsigned char *buf) ++{ ++ int index; ++ ++ /* Extract patch id */ ++ for (index = 0; index < 4; index++) ++ rampatch_patch_info.patch_id |= ++ (LSH(buf[index + P_ID_OFFSET], (index * 8))); ++ ++ /* Extract (ROM and BUILD) version information */ ++ for (index = 0; index < 2; index++) ++ rampatch_patch_info.patch_ver.rom_version |= ++ (LSH(buf[index + P_ROME_VER_OFFSET], (index * 8))); ++ ++ for (index = 0; index < 2; index++) ++ rampatch_patch_info.patch_ver.build_version |= ++ (LSH(buf[index + P_BUILD_VER_OFFSET], (index * 8))); ++ ++ /* Extract patch base and entry addresses */ ++ for (index = 0; index < 4; index++) ++ rampatch_patch_info.patch_base_addr |= ++ (LSH(buf[index + P_BASE_ADDR_OFFSET], (index * 8))); ++ ++ /* Patch BASE & ENTRY addresses are same */ ++ rampatch_patch_info.patch_entry_addr = rampatch_patch_info.patch_base_addr; ++ ++ /* Extract total length of the patch payload */ ++ for (index = 0; index < 4; index++) ++ rampatch_patch_info.patch_length |= ++ (LSH(buf[index + P_LEN_OFFSET], (index * 8))); ++ ++ /* Extract the CRC checksum of the patch payload */ ++ for (index = 0; index < 4; index++) ++ rampatch_patch_info.patch_crc |= ++ (LSH(buf[index + P_CRC_OFFSET], (index * 8))); ++ ++ /* Extract patch control value */ ++ for (index = 0; index < 4; index++) ++ rampatch_patch_info.patch_ctrl |= ++ (LSH(buf[index + P_CONTROL_OFFSET], (index * 8))); ++ ++ fprintf(stderr, "PATCH_ID\t : 0x%x\n", rampatch_patch_info.patch_id); ++ fprintf(stderr, "ROM_VERSION\t : 0x%x\n", rampatch_patch_info.patch_ver.rom_version); ++ fprintf(stderr, "BUILD_VERSION\t : 0x%x\n", rampatch_patch_info.patch_ver.build_version); ++ fprintf(stderr, "PATCH_LENGTH\t : 0x%x\n", rampatch_patch_info.patch_length); ++ fprintf(stderr, "PATCH_CRC\t : 0x%x\n", rampatch_patch_info.patch_crc); ++ fprintf(stderr, "PATCH_CONTROL\t : 0x%x\n", rampatch_patch_info.patch_ctrl); ++ fprintf(stderr, "PATCH_BASE_ADDR\t : 0x%x\n", rampatch_patch_info.patch_base_addr); ++ ++} ++ ++int rome_edl_set_patch_request(int fd) ++{ ++ int size, err; ++ unsigned char cmd[HCI_MAX_CMD_SIZE]; ++ unsigned char rsp[HCI_MAX_EVENT_SIZE]; ++ ++ /* Frame the HCI CMD to be sent to the Controller */ ++ frame_hci_cmd_pkt(cmd, EDL_PATCH_SET_REQ_CMD, 0, ++ -1, PATCH_HDR_LEN + 1); ++ ++ /* Total length of the packet to be sent to the Controller */ ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); ++ ++ /* Send HCI Command packet to Controller */ ++ err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size); ++ if ( err != size) { ++ fprintf(stderr, "Failed to set the patch info to the Controller!\n"); ++ goto error; ++ } ++ ++ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); ++ if ( err < 0) { ++ fprintf(stderr, "%s: Failed to set patch info on Controller\n", __FUNCTION__); ++ goto error; ++ } ++ fprintf(stderr, "%s: Successfully set patch info on the Controller\n", __FUNCTION__); ++error: ++ return err; ++} ++ ++int rome_edl_patch_download_request(int fd) ++{ ++ int no_of_patch_segment; ++ int index = 1, err = 0, size = 0; ++ unsigned int p_base_addr; ++ unsigned char cmd[HCI_MAX_CMD_SIZE]; ++ unsigned char rsp[HCI_MAX_EVENT_SIZE]; ++ ++ no_of_patch_segment = (rampatch_patch_info.patch_length / ++ MAX_DATA_PER_SEGMENT); ++ fprintf(stderr, "%s: %d patch segments to be d'loaded from patch base addr: 0x%x\n", ++ __FUNCTION__, no_of_patch_segment, ++ rampatch_patch_info.patch_base_addr); ++ ++ /* Initialize the patch base address from the one read from bin file */ ++ p_base_addr = rampatch_patch_info.patch_base_addr; ++ ++ /* ++ * Depending upon size of the patch payload, download the patches in ++ * segments with a max. size of 239 bytes ++ */ ++ for (index = 1; index <= no_of_patch_segment; index++) { ++ ++ fprintf(stderr, "%s: Downloading patch segment: %d\n", __FUNCTION__, index); ++ ++ /* Frame the HCI CMD PKT to be sent to Controller*/ ++ frame_hci_cmd_pkt(cmd, EDL_PATCH_DLD_REQ_CMD, p_base_addr, ++ index, MAX_DATA_PER_SEGMENT); ++ ++ /* Total length of the packet to be sent to the Controller */ ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); ++ ++ /* Initialize the RSP packet everytime to 0 */ ++ memset(rsp, 0x0, HCI_MAX_EVENT_SIZE); ++ ++ /* Send HCI Command packet to Controller */ ++ err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size); ++ if ( err != size) { ++ fprintf(stderr, "Failed to send the patch payload to the Controller!\n"); ++ goto error; ++ } ++ ++ /* Read Command Complete Event */ ++ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); ++ if ( err < 0) { ++ fprintf(stderr, "%s: Failed to downlaod patch segment: %d!\n", ++ __FUNCTION__, index); ++ goto error; ++ } ++ fprintf(stderr, "%s: Successfully downloaded patch segment: %d\n", ++ __FUNCTION__, index); ++ } ++ ++ /* Check if any pending patch data to be sent */ ++ size = (rampatch_patch_info.patch_length < MAX_DATA_PER_SEGMENT) ? ++ rampatch_patch_info.patch_length : ++ (rampatch_patch_info.patch_length % MAX_DATA_PER_SEGMENT); ++ ++ if (size) ++ { ++ /* Frame the HCI CMD PKT to be sent to Controller*/ ++ frame_hci_cmd_pkt(cmd, EDL_PATCH_DLD_REQ_CMD, p_base_addr, index, size); ++ ++ /* Initialize the RSP packet everytime to 0 */ ++ memset(rsp, 0x0, HCI_MAX_EVENT_SIZE); ++ ++ /* Total length of the packet to be sent to the Controller */ ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); ++ ++ /* Send HCI Command packet to Controller */ ++ err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size); ++ if ( err != size) { ++ fprintf(stderr, "Failed to send the patch payload to the Controller!\n"); ++ goto error; ++ } ++ ++ /* Read Command Complete Event */ ++ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); ++ if ( err < 0) { ++ fprintf(stderr, "%s: Failed to downlaod patch segment: %d!\n", ++ __FUNCTION__, index); ++ goto error; ++ } ++ ++ fprintf(stderr, "%s: Successfully downloaded patch segment: %d\n", ++ __FUNCTION__, index); ++ } ++ ++error: ++ return err; ++} ++ ++static int rome_download_rampatch(int fd) ++{ ++ int c, size, index, ret = -1; ++ ++ fprintf(stderr, "%s:\n", __FUNCTION__); ++ ++ /* Get handle to the RAMPATCH binary file */ ++ fprintf(stderr, "%s: Getting handle to the RAMPATCH binary file from %s\n", __FUNCTION__, ROME_FW_PATH); ++ file = fopen(ROME_FW_PATH, "r"); ++ if (file == NULL) { ++ fprintf(stderr, "%s: Failed to get handle to the RAMPATCH bin file!\n", ++ __FUNCTION__); ++ return -ENFILE; ++ } ++ ++ /* Allocate memory for the patch headder info */ ++ fprintf(stderr, "%s: Allocating memory for the patch header\n", __FUNCTION__); ++ phdr_buffer = (unsigned char *) malloc(PATCH_HDR_LEN + 1); ++ if (phdr_buffer == NULL) { ++ fprintf(stderr, "%s: Failed to allocate memory for patch header\n", ++ __FUNCTION__); ++ goto phdr_alloc_failed; ++ } ++ for (index = 0; index < PATCH_HDR_LEN + 1; index++) ++ phdr_buffer[index] = 0x0; ++ ++ /* Read 28 bytes of patch header information */ ++ fprintf(stderr, "%s: Reading patch header info\n", __FUNCTION__); ++ index = 0; ++ do { ++ c = fgetc (file); ++ phdr_buffer[index++] = (unsigned char)c; ++ } while (index != PATCH_HDR_LEN); ++ ++ /* Save the patch header info into local structure */ ++ fprintf(stderr, "%s: Saving patch hdr. info\n", __FUNCTION__); ++ rome_extract_patch_header_info((unsigned char *)phdr_buffer); ++ ++ /* Set the patch header info onto the Controller */ ++ ret = rome_edl_set_patch_request(fd); ++ if (ret < 0) { ++ fprintf(stderr, "%s: Error setting the patchheader info!\n", __FUNCTION__); ++ goto pdata_alloc_failed; ++ } ++ ++ /* Allocate memory for the patch payload */ ++ fprintf(stderr, "%s: Allocating memory for patch payload\n", __FUNCTION__); ++ size = rampatch_patch_info.patch_length; ++ pdata_buffer = (unsigned char *) malloc(size+1); ++ if (pdata_buffer == NULL) { ++ fprintf(stderr, "%s: Failed to allocate memory for patch payload\n", ++ __FUNCTION__); ++ goto pdata_alloc_failed; ++ } ++ for (index = 0; index < size+1; index++) ++ pdata_buffer[index] = 0x0; ++ ++ /* Read the patch data from Rampatch binary image */ ++ fprintf(stderr, "%s: Reading patch payload from RAMPATCH file\n", __FUNCTION__); ++ index = 0; ++ do { ++ c = fgetc (file); ++ pdata_buffer[index++] = (unsigned char)c; ++ } while (c != EOF); ++ ++ /* Downloading patches in segments to controller */ ++ ret = rome_edl_patch_download_request(fd); ++ if (ret < 0) { ++ fprintf(stderr, "%s: Error downloading patch segments!\n", __FUNCTION__); ++ goto cleanup; ++ } ++cleanup: ++ free(pdata_buffer); ++pdata_alloc_failed: ++ free(phdr_buffer); ++phdr_alloc_failed: ++ fclose(file); ++ ++ return ret; ++} ++ ++int rome_attach_rampatch(int fd) ++{ ++ int size, err; ++ unsigned char cmd[HCI_MAX_CMD_SIZE]; ++ unsigned char rsp[HCI_MAX_EVENT_SIZE]; ++ ++ /* Frame the HCI CMD to be sent to the Controller */ ++ frame_hci_cmd_pkt(cmd, EDL_PATCH_ATCH_REQ_CMD, 0, ++ -1, EDL_PATCH_CMD_LEN); ++ ++ /* Total length of the packet to be sent to the Controller */ ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); ++ ++ /* Send HCI Command packet to Controller */ ++ err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size); ++ if ( err != size) { ++ fprintf(stderr, "Failed to attach the patch payload to the Controller!\n"); ++ goto error; ++ } ++ ++ /* Read Command Complete Event */ ++ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); ++ if ( err < 0) { ++ fprintf(stderr, "%s: Failed to attach the patch segment(s)\n", __FUNCTION__); ++ goto error; ++ } ++error: ++ return err; ++} ++ ++int rome_rampatch_reset(int fd) ++{ ++ int size, err = 0; ++ unsigned char cmd[HCI_MAX_CMD_SIZE]; ++ struct timespec tm = { 0, 100*1000*1000 }; /* 100 ms */ ++ ++ /* Frame the HCI CMD to be sent to the Controller */ ++ frame_hci_cmd_pkt(cmd, EDL_PATCH_RST_REQ_CMD, 0, ++ -1, EDL_PATCH_CMD_LEN); ++ ++ /* Total length of the packet to be sent to the Controller */ ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + EDL_PATCH_CMD_LEN); ++ ++ /* Send HCI Command packet to Controller */ ++ err = write(fd, cmd, size); ++ if (err != size) { ++ fprintf(stderr, "%s: Send failed with ret value: %d\n", __FUNCTION__, err); ++ goto error; ++ } ++ ++ /* ++ * Controller doesn't sends any response for the patch reset ++ * command. HOST has to wait for 100ms before proceeding. ++ */ ++ nanosleep(&tm, NULL); ++ ++error: ++ return err; ++} ++ ++int rome_get_tlv_file(char *file_path) ++{ ++ FILE * pFile; ++ long fileSize; ++ int readSize, nvm_length, nvm_index, i; ++ unsigned short nvm_tag_len; ++ tlv_patch_info *ptlv_header; ++ tlv_nvm_hdr *nvm_ptr; ++ unsigned char data_buf[PRINT_BUF_SIZE]={0,}; ++ unsigned char *nvm_byte_ptr; ++ ++ fprintf(stderr, "File Open (%s)\n", file_path); ++ pFile = fopen ( file_path , "r" ); ++ if (pFile==NULL) {; ++ fprintf(stderr, "%s File Open Fail\n", file_path); ++ return -1; ++ } ++ ++ /* Get File Size */ ++ fseek (pFile , 0 , SEEK_END); ++ fileSize = ftell (pFile); ++ rewind (pFile); ++ ++ pdata_buffer = (unsigned char*) malloc (sizeof(char)*fileSize); ++ if (pdata_buffer == NULL) { ++ fprintf(stderr, "Allocated Memory failed\n"); ++ fclose (pFile); ++ return -1; ++ } ++ ++ /* Copy file into allocated buffer */ ++ readSize = fread (pdata_buffer,1,fileSize,pFile); ++ ++ /* File Close */ ++ fclose (pFile); ++ ++ if (readSize != fileSize) { ++ fprintf(stderr, "Read file size(%d) not matched with actual file size (%ld bytes)\n",readSize,fileSize); ++ return -1; ++ } ++ ++ ptlv_header = (tlv_patch_info *) pdata_buffer; ++ ++ /* To handle different event between rampatch and NVM */ ++ gTlv_type = ptlv_header->tlv_type; ++ ++ if(ptlv_header->tlv_type == TLV_TYPE_PATCH){ ++ fprintf(stderr, "====================================================\n"); ++ fprintf(stderr, "TLV Type\t\t\t : 0x%x\n", ptlv_header->tlv_type); ++ fprintf(stderr, "Length\t\t\t : %d bytes\n", (ptlv_header->tlv_length1) | ++ (ptlv_header->tlv_length2 << 8) | ++ (ptlv_header->tlv_length3 << 16)); ++ fprintf(stderr, "Total Length\t\t\t : %d bytes\n", ptlv_header->tlv_data_len); ++ fprintf(stderr, "Patch Data Length\t\t\t : %d bytes\n",ptlv_header->tlv_patch_data_len); ++ fprintf(stderr, "Signing Format Version\t : 0x%x\n", ptlv_header->tlv.patch.sign_ver); ++ fprintf(stderr, "Signature Algorithm\t\t : 0x%x\n", ptlv_header->tlv.patch.sign_algorithm); ++ fprintf(stderr, "Reserved\t\t\t : 0x%x\n", ptlv_header->tlv.patch.reserved1); ++ fprintf(stderr, "Product ID\t\t\t : 0x%04x\n", ptlv_header->tlv.patch.prod_id); ++ fprintf(stderr, "Rom Build Version\t\t : 0x%04x\n", ptlv_header->tlv.patch.build_ver); ++ fprintf(stderr, "Patch Version\t\t : 0x%04x\n", ptlv_header->tlv.patch.patch_ver); ++ fprintf(stderr, "Reserved\t\t\t : 0x%x\n", ptlv_header->tlv.patch.reserved2); ++ fprintf(stderr, "Patch Entry Address\t\t : 0x%x\n", (ptlv_header->tlv.patch.patch_entry_addr)); ++ fprintf(stderr, "====================================================\n"); ++ ++ } else if(ptlv_header->tlv_type == TLV_TYPE_NVM) { ++ fprintf(stderr, "====================================================\n"); ++ fprintf(stderr, "TLV Type\t\t\t : 0x%x\n", ptlv_header->tlv_type); ++ fprintf(stderr, "Length\t\t\t : %d bytes\n", nvm_length = (ptlv_header->tlv_length1) | ++ (ptlv_header->tlv_length2 << 8) | ++ (ptlv_header->tlv_length3 << 16)); ++ ++ if(nvm_length <= 0) ++ return readSize; ++ ++ for(nvm_byte_ptr=(unsigned char *)(nvm_ptr = &(ptlv_header->tlv.nvm)), nvm_index=0; ++ nvm_index < nvm_length ; nvm_ptr = (tlv_nvm_hdr *) nvm_byte_ptr) ++ { ++ fprintf(stderr, "TAG ID\t\t\t : %d\n", nvm_ptr->tag_id); ++ fprintf(stderr, "TAG Length\t\t\t : %d\n", nvm_tag_len = nvm_ptr->tag_len); ++ fprintf(stderr, "TAG Pointer\t\t\t : %d\n", nvm_ptr->tag_ptr); ++ fprintf(stderr, "TAG Extended Flag\t\t : %d\n", nvm_ptr->tag_ex_flag); ++ ++ /* Increase nvm_index to NVM data */ ++ nvm_index+=sizeof(tlv_nvm_hdr); ++ nvm_byte_ptr+=sizeof(tlv_nvm_hdr); ++ ++ /* Write BD Address */ ++ if(nvm_ptr->tag_id == TAG_NUM_2){ ++ memcpy(nvm_byte_ptr, vnd_local_bd_addr, 6); ++ fprintf(stderr, "BD Address: %.02x:%.02x:%.02x:%.02x:%.02x:%.02x\n", ++ *nvm_byte_ptr, *(nvm_byte_ptr+1), *(nvm_byte_ptr+2), ++ *(nvm_byte_ptr+3), *(nvm_byte_ptr+4), *(nvm_byte_ptr+5)); ++ } ++ ++ for(i =0;(itag_len && (i*3 + 2) tag_len; ++ nvm_byte_ptr +=nvm_ptr->tag_len; ++ } ++ ++ fprintf(stderr, "====================================================\n"); ++ ++ } else { ++ fprintf(stderr, "TLV Header type is unknown (%d) \n", ptlv_header->tlv_type); ++ } ++ ++ return readSize; ++} ++ ++int rome_tlv_dnld_segment(int fd, int index, int seg_size, unsigned char wait_cc_evt) ++{ ++ int size=0, err = -1; ++ unsigned char cmd[HCI_MAX_CMD_SIZE]; ++ unsigned char rsp[HCI_MAX_EVENT_SIZE]; ++ ++ fprintf(stderr, "%s: Downloading TLV Patch segment no.%d, size:%d\n", __FUNCTION__, index, seg_size); ++ ++ /* Frame the HCI CMD PKT to be sent to Controller*/ ++ frame_hci_cmd_pkt(cmd, EDL_PATCH_TLV_REQ_CMD, 0, index, seg_size); ++ ++ /* Total length of the packet to be sent to the Controller */ ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); ++ ++ /* Initialize the RSP packet everytime to 0 */ ++ memset(rsp, 0x0, HCI_MAX_EVENT_SIZE); ++ ++ /* Send HCI Command packet to Controller */ ++ err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size); ++ if ( err != size) { ++ fprintf(stderr, "Failed to send the patch payload to the Controller! 0x%x\n", err); ++ return err; ++ } ++ ++ if(wait_cc_evt) { ++ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); ++ if ( err < 0) { ++ fprintf(stderr, "%s: Failed to downlaod patch segment: %d!\n", __FUNCTION__, index); ++ return err; ++ } ++ } ++ ++ fprintf(stderr, "%s: Successfully downloaded patch segment: %d\n", __FUNCTION__, index); ++ return err; ++} ++ ++int rome_tlv_dnld_req(int fd, int tlv_size) ++{ ++ int total_segment, remain_size, i, err = -1; ++ unsigned char wait_cc_evt; ++ ++ total_segment = tlv_size/MAX_SIZE_PER_TLV_SEGMENT; ++ remain_size = (tlv_size < MAX_SIZE_PER_TLV_SEGMENT)?\ ++ tlv_size: (tlv_size%MAX_SIZE_PER_TLV_SEGMENT); ++ ++ fprintf(stderr, "%s: TLV size: %d, Total Seg num: %d, remain size: %d\n", ++ __FUNCTION__,tlv_size, total_segment, remain_size); ++ ++ for(i=0;i= ROME_VER_1_1) && (gTlv_type == TLV_TYPE_PATCH ) ++ && !remain_size && ((i+1) == total_segment))? FALSE: TRUE; ++ if((err = rome_tlv_dnld_segment(fd, i, MAX_SIZE_PER_TLV_SEGMENT, wait_cc_evt )) < 0) ++ goto error; ++ } ++ ++ /* In case remain data still remain, last rampatch segment command will not wait ++ for command complete event here */ ++ wait_cc_evt = ((rome_ver >= ROME_VER_1_1) && (gTlv_type == TLV_TYPE_PATCH ) ++ && remain_size )? FALSE:TRUE; ++ ++ if(remain_size) err =rome_tlv_dnld_segment(fd, i, remain_size, wait_cc_evt); ++ ++error: ++ return err; ++} ++ ++int rome_download_tlv_file(int fd) ++{ ++ int tlv_size, err = -1; ++ ++ /* Rampatch TLV file Downloading */ ++ pdata_buffer = NULL; ++ ++ if((tlv_size = rome_get_tlv_file(rampatch_file_path)) < 0) ++ goto error; ++ ++ if((err =rome_tlv_dnld_req(fd, tlv_size)) <0 ) ++ goto error; ++ ++ if (pdata_buffer != NULL){ ++ free (pdata_buffer); ++ pdata_buffer = NULL; ++ } ++ ++ /* NVM TLV file Downloading */ ++ if((tlv_size = rome_get_tlv_file(nvm_file_path)) < 0) ++ goto error; ++ ++ if((err =rome_tlv_dnld_req(fd, tlv_size)) <0 ) ++ goto error; ++ ++error: ++ if (pdata_buffer != NULL) ++ free (pdata_buffer); ++ ++ return err; ++} ++ ++int rome_1_0_nvm_tag_dnld(int fd) ++{ ++ int i, size, err = 0; ++ unsigned char rsp[HCI_MAX_EVENT_SIZE]; ++ ++#if (NVM_VERSION >= ROME_1_0_100019) ++ unsigned char cmds[MAX_TAG_CMD][HCI_MAX_CMD_SIZE] = ++ { ++ /* Tag 2 */ /* BD Address */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 9, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 2, ++ /* Tag Len */ 6, ++ /* Tag Value */ 0x77,0x78,0x23,0x01,0x56,0x22 ++ }, ++ /* Tag 6 */ /* Bluetooth Support Features */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 11, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 6, ++ /* Tag Len */ 8, ++ /* Tag Value */ 0xFF,0xFE,0x8B,0xFE,0xD8,0x3F,0x5B,0x8B ++ }, ++ /* Tag 17 */ /* HCI Transport Layer Setting */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 11, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 17, ++ /* Tag Len */ 8, ++ /* Tag Value */ 0x82,0x01,0x0E,0x08,0x04,0x32,0x0A,0x00 ++ }, ++ /* Tag 35 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 58, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 35, ++ /* Tag Len */ 55, ++ /* Tag Value */ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x58, 0x59, ++ 0x0E, 0x0E, 0x16, 0x16, 0x16, 0x1E, 0x26, 0x5F, 0x2F, 0x5F, ++ 0x0E, 0x0E, 0x16, 0x16, 0x16, 0x1E, 0x26, 0x5F, 0x2F, 0x5F, ++ 0x0C, 0x18, 0x14, 0x24, 0x40, 0x4C, 0x70, 0x80, 0x80, 0x80, ++ 0x0C, 0x18, 0x14, 0x24, 0x40, 0x4C, 0x70, 0x80, 0x80, 0x80, ++ 0x1B, 0x14, 0x01, 0x04, 0x48 ++ }, ++ /* Tag 36 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 15, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 36, ++ /* Tag Len */ 12, ++ /* Tag Value */ 0x0F,0x00,0x03,0x03,0x03,0x03,0x00,0x00,0x03,0x03,0x04,0x00 ++ }, ++ /* Tag 39 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 7, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 39, ++ /* Tag Len */ 4, ++ /* Tag Value */ 0x12,0x00,0x00,0x00 ++ }, ++ /* Tag 41 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 91, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 41, ++ /* Tag Len */ 88, ++ /* Tag Value */ 0x15, 0x00, 0x00, 0x00, 0xF6, 0x02, 0x00, 0x00, 0x76, 0x00, ++ 0x1E, 0x00, 0x29, 0x02, 0x1F, 0x00, 0x61, 0x00, 0x1A, 0x00, ++ 0x76, 0x00, 0x1E, 0x00, 0x7D, 0x00, 0x40, 0x00, 0x91, 0x00, ++ 0x06, 0x00, 0x92, 0x00, 0x03, 0x00, 0xA6, 0x01, 0x50, 0x00, ++ 0xAA, 0x01, 0x15, 0x00, 0xAB, 0x01, 0x0A, 0x00, 0xAC, 0x01, ++ 0x00, 0x00, 0xB0, 0x01, 0xC5, 0x00, 0xB3, 0x01, 0x03, 0x00, ++ 0xB4, 0x01, 0x13, 0x00, 0xB5, 0x01, 0x0C, 0x00, 0xC5, 0x01, ++ 0x0D, 0x00, 0xC6, 0x01, 0x10, 0x00, 0xCA, 0x01, 0x2B, 0x00, ++ 0xCB, 0x01, 0x5F, 0x00, 0xCC, 0x01, 0x48, 0x00 ++ }, ++ /* Tag 42 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 63, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 42, ++ /* Tag Len */ 60, ++ /* Tag Value */ 0xD7, 0xC0, 0x00, 0x00, 0x8F, 0x5C, 0x02, 0x00, 0x80, 0x47, ++ 0x60, 0x0C, 0x70, 0x4C, 0x00, 0x00, 0x00, 0x01, 0x1F, 0x01, ++ 0x42, 0x01, 0x69, 0x01, 0x95, 0x01, 0xC7, 0x01, 0xFE, 0x01, ++ 0x3D, 0x02, 0x83, 0x02, 0xD1, 0x02, 0x29, 0x03, 0x00, 0x0A, ++ 0x10, 0x00, 0x1F, 0x00, 0x3F, 0x00, 0x7F, 0x00, 0xFD, 0x00, ++ 0xF9, 0x01, 0xF1, 0x03, 0xDE, 0x07, 0x00, 0x00, 0x9A, 0x01 ++ }, ++ /* Tag 84 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 153, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 84, ++ /* Tag Len */ 150, ++ /* Tag Value */ 0x7C, 0x6A, 0x59, 0x47, 0x19, 0x36, 0x35, 0x25, 0x25, 0x28, ++ 0x2C, 0x2B, 0x2B, 0x28, 0x2C, 0x28, 0x29, 0x28, 0x29, 0x28, ++ 0x29, 0x29, 0x2C, 0x29, 0x2C, 0x29, 0x2C, 0x28, 0x29, 0x28, ++ 0x29, 0x28, 0x29, 0x2A, 0x00, 0x00, 0x2C, 0x2A, 0x2C, 0x18, ++ 0x98, 0x98, 0x98, 0x98, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, ++ 0x1E, 0x13, 0x1E, 0x1E, 0x1E, 0x1E, 0x13, 0x13, 0x11, 0x13, ++ 0x1E, 0x1E, 0x13, 0x12, 0x12, 0x12, 0x11, 0x12, 0x1F, 0x12, ++ 0x12, 0x12, 0x10, 0x0C, 0x18, 0x0D, 0x01, 0x01, 0x01, 0x01, ++ 0x01, 0x01, 0x01, 0x0C, 0x01, 0x01, 0x01, 0x01, 0x0D, 0x0D, ++ 0x0E, 0x0D, 0x01, 0x01, 0x0D, 0x0D, 0x0D, 0x0D, 0x0F, 0x0D, ++ 0x10, 0x0D, 0x0D, 0x0D, 0x0D, 0x10, 0x05, 0x10, 0x03, 0x00, ++ 0x7E, 0x7B, 0x7B, 0x72, 0x71, 0x50, 0x50, 0x50, 0x00, 0x40, ++ 0x60, 0x60, 0x30, 0x08, 0x02, 0x0F, 0x00, 0x01, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x08, 0x16, 0x16, 0x08, 0x08, 0x00, ++ 0x00, 0x00, 0x1E, 0x34, 0x2B, 0x1B, 0x23, 0x2B, 0x15, 0x0D ++ }, ++ /* Tag 85 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 119, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 85, ++ /* Tag Len */ 116, ++ /* Tag Value */ 0x03, 0x00, 0x38, 0x00, 0x45, 0x77, 0x00, 0xE8, 0x00, 0x59, ++ 0x01, 0xCA, 0x01, 0x3B, 0x02, 0xAC, 0x02, 0x1D, 0x03, 0x8E, ++ 0x03, 0x00, 0x89, 0x01, 0x0E, 0x02, 0x5C, 0x02, 0xD7, 0x02, ++ 0xF8, 0x08, 0x01, 0x00, 0x1F, 0x00, 0x0A, 0x02, 0x55, 0x02, ++ 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xD7, 0x00, 0x00, ++ 0x00, 0x1E, 0xDE, 0x00, 0x00, 0x00, 0x14, 0x0F, 0x0A, 0x0F, ++ 0x0A, 0x0C, 0x0C, 0x0C, 0x0C, 0x04, 0x04, 0x04, 0x0C, 0x0C, ++ 0x0C, 0x0C, 0x06, 0x06, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, ++ 0x01, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, ++ 0x06, 0x0F, 0x14, 0x05, 0x47, 0xCF, 0x77, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0xAC, 0x7C, 0xFF, 0x40, 0x00, 0x00, 0x00, ++ 0x12, 0x04, 0x04, 0x01, 0x04, 0x03 ++ }, ++ {TAG_END} ++ }; ++#elif (NVM_VERSION == ROME_1_0_6002) ++ unsigned char cmds[MAX_TAG_CMD][HCI_MAX_CMD_SIZE] = ++ { ++ /* Tag 2 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 9, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 2, ++ /* Tag Len */ 6, ++ /* Tag Value */ 0x77,0x78,0x23,0x01,0x56,0x22 /* BD Address */ ++ }, ++ /* Tag 6 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 11, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 6, ++ /* Tag Len */ 8, ++ /* Tag Value */ 0xFF,0xFE,0x8B,0xFE,0xD8,0x3F,0x5B,0x8B ++ }, ++ /* Tag 17 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 11, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 17, ++ /* Tag Len */ 8, ++ /* Tag Value */ 0x82,0x01,0x0E,0x08,0x04,0x32,0x0A,0x00 ++ }, ++ /* Tag 36 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 15, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 36, ++ /* Tag Len */ 12, ++ /* Tag Value */ 0x0F,0x00,0x03,0x03,0x03,0x03,0x00,0x00,0x03,0x03,0x04,0x00 ++ }, ++ ++ /* Tag 39 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 7, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 39, ++ /* Tag Len */ 4, ++ /* Tag Value */ 0x12,0x00,0x00,0x00 ++ }, ++ ++ /* Tag 41 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 199, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 41, ++ /* Tag Len */ 196, ++ /* Tag Value */ 0x30,0x00,0x00,0x00,0xD5,0x00,0x0E,0x00,0xD6,0x00,0x0E,0x00, ++ 0xD7,0x00,0x16,0x00,0xD8,0x00,0x16,0x00,0xD9,0x00,0x16,0x00, ++ 0xDA,0x00,0x1E,0x00,0xDB,0x00,0x26,0x00,0xDC,0x00,0x5F,0x00, ++ 0xDD,0x00,0x2F,0x00,0xDE,0x00,0x5F,0x00,0xE0,0x00,0x0E,0x00, ++ 0xE1,0x00,0x0E,0x00,0xE2,0x00,0x16,0x00,0xE3,0x00,0x16,0x00, ++ 0xE4,0x00,0x16,0x00,0xE5,0x00,0x1E,0x00,0xE6,0x00,0x26,0x00, ++ 0xE7,0x00,0x5F,0x00,0xE8,0x00,0x2F,0x00,0xE9,0x00,0x5F,0x00, ++ 0xEC,0x00,0x0C,0x00,0xED,0x00,0x08,0x00,0xEE,0x00,0x14,0x00, ++ 0xEF,0x00,0x24,0x00,0xF0,0x00,0x40,0x00,0xF1,0x00,0x4C,0x00, ++ 0xF2,0x00,0x70,0x00,0xF3,0x00,0x80,0x00,0xF4,0x00,0x80,0x00, ++ 0xF5,0x00,0x80,0x00,0xF8,0x00,0x0C,0x00,0xF9,0x00,0x18,0x00, ++ 0xFA,0x00,0x14,0x00,0xFB,0x00,0x24,0x00,0xFC,0x00,0x40,0x00, ++ 0xFD,0x00,0x4C,0x00,0xFE,0x00,0x70,0x00,0xFF,0x00,0x80,0x00, ++ 0x00,0x01,0x80,0x00,0x01,0x01,0x80,0x00,0x04,0x01,0x1B,0x00, ++ 0x05,0x01,0x14,0x00,0x06,0x01,0x01,0x00,0x07,0x01,0x04,0x00, ++ 0x08,0x01,0x00,0x00,0x09,0x01,0x00,0x00,0x0A,0x01,0x03,0x00, ++ 0x0B,0x01,0x03,0x00 ++ }, ++ ++ /* Tag 44 */ ++ { /* Packet Type */HCI_COMMAND_PKT, ++ /* Opcode */ 0x0b,0xfc, ++ /* Total Len */ 44, ++ /* NVM CMD */ NVM_ACCESS_SET, ++ /* Tag Num */ 44, ++ /* Tag Len */ 41, ++ /* Tag Value */ 0x6F,0x0A,0x00,0x00,0x00,0x00,0x00,0x50,0xFF,0x10,0x02,0x02, ++ 0x01,0x00,0x14,0x01,0x06,0x28,0xA0,0x62,0x03,0x64,0x01,0x01, ++ 0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0xA0,0xFF,0x10,0x02,0x01, ++ 0x00,0x14,0x01,0x02,0x03 ++ }, ++ {TAG_END} ++ }; ++#endif ++ ++ fprintf(stderr, "%s: Start sending NVM Tags (ver: 0x%x)\n", __FUNCTION__, (unsigned int) NVM_VERSION); ++ ++ for (i=0; (i < MAX_TAG_CMD) && (cmds[i][0] != TAG_END); i++) ++ { ++ /* Write BD Address */ ++ if(cmds[i][TAG_NUM_OFFSET] == TAG_NUM_2){ ++ memcpy(&cmds[i][TAG_BDADDR_OFFSET], vnd_local_bd_addr, 6); ++ fprintf(stderr, "BD Address: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", ++ cmds[i][TAG_BDADDR_OFFSET ], cmds[i][TAG_BDADDR_OFFSET + 1], ++ cmds[i][TAG_BDADDR_OFFSET + 2], cmds[i][TAG_BDADDR_OFFSET + 3], ++ cmds[i][TAG_BDADDR_OFFSET + 4], cmds[i][TAG_BDADDR_OFFSET + 5]); ++ } ++ size = cmds[i][3] + HCI_COMMAND_HDR_SIZE + 1; ++ /* Send HCI Command packet to Controller */ ++ err = hci_send_vs_cmd(fd, (unsigned char *)&cmds[i][0], rsp, size); ++ if ( err != size) { ++ fprintf(stderr, "Failed to attach the patch payload to the Controller!\n"); ++ goto error; ++ } ++ ++ /* Read Command Complete Event - This is extra routine for ROME 1.0. From ROM 2.0, it should be removed. */ ++ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); ++ if ( err < 0) { ++ fprintf(stderr, "%s: Failed to get patch version(s)\n", __FUNCTION__); ++ goto error; ++ } ++ } ++ ++error: ++ return err; ++} ++ ++ ++ ++int rome_patch_ver_req(int fd) ++{ ++ int size, err = 0; ++ unsigned char cmd[HCI_MAX_CMD_SIZE]; ++ unsigned char rsp[HCI_MAX_EVENT_SIZE]; ++ ++ /* Frame the HCI CMD to be sent to the Controller */ ++ frame_hci_cmd_pkt(cmd, EDL_PATCH_VER_REQ_CMD, 0, ++ -1, EDL_PATCH_CMD_LEN); ++ ++ /* Total length of the packet to be sent to the Controller */ ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + EDL_PATCH_CMD_LEN); ++ ++ /* Send HCI Command packet to Controller */ ++ err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size); ++ if ( err != size) { ++ fprintf(stderr, "Failed to attach the patch payload to the Controller!\n"); ++ goto error; ++ } ++ ++ /* Read Command Complete Event - This is extra routine for ROME 1.0. From ROM 2.0, it should be removed. */ ++ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); ++ if ( err < 0) { ++ fprintf(stderr, "%s: Failed to get patch version(s)\n", __FUNCTION__); ++ goto error; ++ } ++error: ++ return err; ++ ++} ++ ++int rome_disable_sleep(int fd) ++{ ++ int size, err = 0; ++ unsigned char cmd[HCI_MAX_CMD_SIZE]; ++ unsigned char rsp[HCI_MAX_EVENT_SIZE]; ++ hci_command_hdr *cmd_hdr; ++ int flags; ++ ++ memset(cmd, 0x0, HCI_MAX_CMD_SIZE); ++ ++ cmd_hdr = (void *) (cmd + 1); ++ cmd[0] = HCI_COMMAND_PKT; ++ cmd_hdr->opcode = cmd_opcode_pack(HCI_VENDOR_CMD_OGF, NVM_ACCESS_CODE); ++ cmd_hdr->plen = VSC_DISABLE_IBS_LEN; ++ cmd[4] = 0x01; ++ cmd[5] = 0x1B; ++ cmd[6] = 0x01; ++ cmd[7] = 0x00; ++ ++ /* Total length of the packet to be sent to the Controller */ ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + VSC_DISABLE_IBS_LEN); ++ /* Send the HCI command packet to UART for transmission */ ++ fprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6], cmd[7]) ; ++ err = write(fd, cmd, size); ++ if (err != size) { ++ fprintf(stderr, "%s: Send failed with ret value: %d\n", __FUNCTION__, err); ++ goto error; ++ } ++ ++ /* Check for response from the Controller */ ++ if ((err =read_vs_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE)) < 0) { ++ fprintf(stderr, "%s: Failed to get HCI-VS Event from SOC\n", __FUNCTION__); ++ goto error; ++ } ++ ++ fprintf(stderr, "%s: Received HCI-Vendor Specific Event from SOC\n", __FUNCTION__); ++ ++ /* Wait for command complete event */ ++ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); ++ if ( err < 0) { ++ fprintf(stderr, "%s: Failed to set patch info on Controller\n", __FUNCTION__); ++ goto error; ++ } ++ fprintf(stderr, "%s\n", __FUNCTION__); ++error: ++ return err; ++ ++} ++ ++int rome_set_baudrate_req(int fd) ++{ ++ int size, err = 0; ++ unsigned char cmd[HCI_MAX_CMD_SIZE]; ++ unsigned char rsp[HCI_MAX_EVENT_SIZE]; ++ hci_command_hdr *cmd_hdr; ++ int flags; ++ ++ memset(cmd, 0x0, HCI_MAX_CMD_SIZE); ++ ++ cmd_hdr = (void *) (cmd + 1); ++ cmd[0] = HCI_COMMAND_PKT; ++ cmd_hdr->opcode = cmd_opcode_pack(HCI_VENDOR_CMD_OGF, EDL_SET_BAUDRATE_CMD_OCF); ++ cmd_hdr->plen = VSC_SET_BAUDRATE_REQ_LEN; ++ cmd[4] = BAUDRATE_115200; ++ ++ /* Total length of the packet to be sent to the Controller */ ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + VSC_SET_BAUDRATE_REQ_LEN); ++ /* Send the HCI command packet to UART for transmission */ ++ fprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3],cmd[4]) ; ++ err = write(fd, cmd, size); ++ if (err != size) { ++ fprintf(stderr, "%s: Send failed with ret value: %d\n", __FUNCTION__, err); ++ goto error; ++ } ++ ++ /* Check for response from the Controller */ ++ if ((err =read_vs_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE)) < 0) { ++ fprintf(stderr, "%s: Failed to get HCI-VS Event from SOC\n", __FUNCTION__); ++ goto error; ++ } ++ ++ fprintf(stderr, "%s: Received HCI-Vendor Specific Event from SOC\n", __FUNCTION__); ++ ++ /* Wait for command complete event */ ++ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); ++ if ( err < 0) { ++ fprintf(stderr, "%s: Failed to set patch info on Controller\n", __FUNCTION__); ++ goto error; ++ } ++ fprintf(stderr, "%s\n", __FUNCTION__); ++error: ++ return err; ++ ++} ++ ++ ++int rome_hci_reset_req(int fd) ++{ ++ int size, err = 0; ++ unsigned char cmd[HCI_MAX_CMD_SIZE]; ++ unsigned char rsp[HCI_MAX_EVENT_SIZE]; ++ hci_command_hdr *cmd_hdr; ++ int flags; ++ ++ fprintf(stderr, "%s: HCI RESET \n", __FUNCTION__); ++ ++ memset(cmd, 0x0, HCI_MAX_CMD_SIZE); ++ ++ cmd_hdr = (void *) (cmd + 1); ++ cmd[0] = HCI_COMMAND_PKT; ++ cmd_hdr->opcode = HCI_RESET; ++ cmd_hdr->plen = 0; ++ ++ /* Total length of the packet to be sent to the Controller */ ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE); ++ ++ /* Send the HCI command packet to UART for transmission */ ++ fprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3]); ++ err = write(fd, cmd, size); ++ if (err != size) { ++ fprintf(stderr, "%s: Send failed with ret value: %d\n", __FUNCTION__, err); ++ goto error; ++ } ++ ++ /* Wait for command complete event */ ++ err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); ++ if ( err < 0) { ++ fprintf(stderr, "%s: Failed to set patch info on Controller\n", __FUNCTION__); ++ goto error; ++ } ++ ++error: ++ return err; ++ ++} ++ ++ ++int qca_soc_init(int fd, char *bdaddr) ++{ ++ int err = -1; ++ int size; ++ ++ fprintf(stderr, " %s \n", __FUNCTION__); ++ vnd_userial.fd = fd; ++ /* Get Rome version information */ ++ if((err = rome_patch_ver_req(fd)) <0){ ++ fprintf(stderr, "%s: Fail to get Rome Version (0x%x)\n", __FUNCTION__, err); ++ goto error; ++ } ++ ++ fprintf(stderr, "%s: Rome Version (0x%08x)\n", __FUNCTION__, rome_ver); ++ ++ switch (rome_ver){ ++ case ROME_VER_1_0: ++ { ++ /* Set and Download the RAMPATCH */ ++ fprintf(stderr, "%s: Setting Patch Header & Downloading Patches\n", __FUNCTION__); ++ err = rome_download_rampatch(fd); ++ if (err < 0) { ++ fprintf(stderr, "%s: DOWNLOAD RAMPATCH failed!\n", __FUNCTION__); ++ goto error; ++ } ++ fprintf(stderr, "%s: DOWNLOAD RAMPTACH complete\n", __FUNCTION__); ++ ++ /* Attach the RAMPATCH */ ++ fprintf(stderr, "%s: Attaching the patches\n", __FUNCTION__); ++ err = rome_attach_rampatch(fd); ++ if (err < 0) { ++ fprintf(stderr, "%s: ATTACH RAMPATCH failed!\n", __FUNCTION__); ++ goto error; ++ } ++ fprintf(stderr, "%s: ATTACH RAMPTACH complete\n", __FUNCTION__); ++ ++ /* Send Reset */ ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + EDL_PATCH_CMD_LEN); ++ err = rome_rampatch_reset(fd); ++ if ( err < 0 ) { ++ fprintf(stderr, "Failed to RESET after RAMPATCH upgrade!\n"); ++ goto error; ++ } ++ ++ /* NVM download */ ++ fprintf(stderr, "%s: Downloading NVM\n", __FUNCTION__); ++ err = rome_1_0_nvm_tag_dnld(fd); ++ if ( err <0 ) { ++ fprintf(stderr, "Downloading NVM Failed !!\n"); ++ goto error; ++ } ++ ++ /* Change baud rate 115.2 kbps to 3Mbps*/ ++ err = rome_hci_reset_req(fd); ++ if ( err <0 ) { ++ fprintf(stderr, "HCI Reset Failed !!\n"); ++ goto error; ++ } ++ ++ fprintf(stderr, "HCI Reset is done\n"); ++ } ++ break; ++ case ROME_VER_1_1: ++ rampatch_file_path = ROME_RAMPATCH_TLV_PATH; ++ nvm_file_path = ROME_NVM_TLV_PATH; ++ goto download; ++ case ROME_VER_1_3: ++ rampatch_file_path = ROME_RAMPATCH_TLV_1_0_3_PATH; ++ nvm_file_path = ROME_NVM_TLV_1_0_3_PATH; ++ goto download; ++ case ROME_VER_2_1: ++ rampatch_file_path = ROME_RAMPATCH_TLV_2_0_1_PATH; ++ nvm_file_path = ROME_NVM_TLV_2_0_1_PATH; ++ goto download; ++ case ROME_VER_3_0: ++ case TUFELLO_VER_1_0: ++ rampatch_file_path = ROME_RAMPATCH_TLV_3_0_0_PATH; ++ nvm_file_path = ROME_NVM_TLV_3_0_0_PATH; ++ ++download: ++ /* Donwload TLV files (rampatch, NVM) */ ++ err = rome_download_tlv_file(fd); ++ if (err < 0) { ++ fprintf(stderr, "%s: Download TLV file failed!\n", __FUNCTION__); ++ goto error; ++ } ++ fprintf(stderr, "%s: Download TLV file successfully \n", __FUNCTION__); ++ ++ /* Change baud rate back to user requested */ ++ fprintf(stderr, "Changing baud rate back from 3M --> 115K\n"); ++ err = rome_set_baudrate_req(fd); ++ if (err < 0) { ++ fprintf(stderr, "%s: Baud rate change failed!\n", __FUNCTION__); ++ goto error; ++ } ++ fprintf(stderr, "%s: Baud rate changed successfully \n", __FUNCTION__); ++ ++ fprintf(stderr, "%s: Disabling In Band Sleep functionality\n", __FUNCTION__); ++ err = rome_disable_sleep(fd); ++ if (err < 0) { ++ fprintf(stderr, "%s: Failed to disable IBS!\n", __FUNCTION__); ++ goto error; ++ } ++ fprintf(stderr, "%s: IBS disabled successfully \n", __FUNCTION__); ++ ++ /* Perform HCI reset here*/ ++ err = rome_hci_reset_req(fd); ++ if ( err <0 ) { ++ fprintf(stderr, "HCI Reset Failed !!!\n"); ++ goto error; ++ } ++ fprintf(stderr, "HCI Reset is done\n"); ++ ++ break; ++ case ROME_VER_UNKNOWN: ++ default: ++ fprintf(stderr, "%s: Detected unknown ROME version\n", __FUNCTION__); ++ err = -1; ++ break; ++ } ++ ++error: ++ return err; ++} +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +new file mode 100644 +index 000000000000..aa59965643ec +--- /dev/null ++++ b/tools/hciattach_rome.h +@@ -0,0 +1,317 @@ ++/* ++ * Copyright 2012 The Android Open Source Project ++ * Copyright (c) 2013, The Linux Foundation. All rights reserved. ++ * Not a Contribution. ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++#ifndef HW_ROME_H ++#define HW_ROME_H ++ ++/****************************************************************************** ++** Constants & Macros ++******************************************************************************/ ++#define HCI_MAX_CMD_SIZE 260 ++#define HCI_MAX_EVENT_SIZE 260 ++#define PRINT_BUF_SIZE ((HCI_MAX_CMD_SIZE * 3) + 2) ++/* HCI Command/Event Opcode */ ++#define HCI_RESET 0x0C03 ++#define EVT_CMD_COMPLETE 0x0E ++/* HCI Packet types */ ++#define HCI_COMMAND_PKT 0x01 ++#define HCI_ACLDATA_PKT 0x02 ++#define HCI_SCODATA_PKT 0x03 ++#define HCI_EVENT_PKT 0x04 ++#define HCI_VENDOR_PKT 0xff ++#define cmd_opcode_pack(ogf, ocf) (unsigned short)((ocf & 0x03ff)|(ogf << 10)) ++unsigned char vnd_local_bd_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; ++typedef enum { ++ USERIAL_OP_FLOW_ON, ++ USERIAL_OP_FLOW_OFF, ++ USERIAL_OP_NOP, ++} userial_vendor_ioctl_op_t; ++ ++ ++/* vendor serial control block */ ++typedef struct ++{ ++ int fd; /* fd to Bluetooth device */ ++ struct termios termios; /* serial terminal of BT port */ ++ char port_name[256]; ++} vnd_userial_cb_t; ++ ++/**** baud rates ****/ ++#define USERIAL_BAUD_300 0 ++#define USERIAL_BAUD_600 1 ++#define USERIAL_BAUD_1200 2 ++#define USERIAL_BAUD_2400 3 ++#define USERIAL_BAUD_9600 4 ++#define USERIAL_BAUD_19200 5 ++#define USERIAL_BAUD_57600 6 ++#define USERIAL_BAUD_115200 7 ++#define USERIAL_BAUD_230400 8 ++#define USERIAL_BAUD_460800 9 ++#define USERIAL_BAUD_921600 10 ++#define USERIAL_BAUD_1M 11 ++#define USERIAL_BAUD_1_5M 12 ++#define USERIAL_BAUD_2M 13 ++#define USERIAL_BAUD_3M 14 ++#define USERIAL_BAUD_4M 15 ++#define USERIAL_BAUD_AUTO 16 ++ ++#ifndef FALSE ++#define FALSE 0 ++#endif ++ ++#ifndef TRUE ++#define TRUE (!FALSE) ++#endif ++ ++#define HCI_CHG_BAUD_CMD_OCF 0x0C ++#define HCI_VENDOR_CMD_OGF 0x3F ++#define WRITE_BDADDR_CMD_LEN 14 ++#define WRITE_BAUD_CMD_LEN 6 ++#define MAX_CMD_LEN WRITE_BDADDR_CMD_LEN ++#define GET_VERSION_OCF 0x1E ++ ++#define PS_HDR_LEN 4 ++#define HCI_VENDOR_CMD_OGF 0x3F ++#define HCI_PS_CMD_OCF 0x0B ++ ++#define HCI_COMMAND_HDR_SIZE 3 ++#define EVT_CMD_COMPLETE_SIZE 3 ++#define EVT_CMD_STATUS 0x0F ++#define EVT_CMD_STATUS_SIZE 4 ++#define HCI_EVENT_HDR_SIZE 2 ++#define HCI_EV_SUCCESS 0x00 ++/* HCI Socket options */ ++#define HCI_DATA_DIR 1 ++#define HCI_FILTER 2 ++#define HCI_TIME_STAMP 3 ++ ++#define P_ID_OFFSET (0) ++#define HCI_CMD_IND (1) ++#define EVENTCODE_OFFSET (1) ++#define EVT_PLEN (2) ++#define PLEN (3) ++#define CMD_RSP_OFFSET (3) ++#define RSP_TYPE_OFFSET (4) ++#define BAUDRATE_RSP_STATUS_OFFSET (4) ++#define CMD_STATUS_OFFSET (5) ++#define P_ROME_VER_OFFSET (4) ++#define P_BUILD_VER_OFFSET (6) ++#define P_BASE_ADDR_OFFSET (8) ++#define P_ENTRY_ADDR_OFFSET (12) ++#define P_LEN_OFFSET (16) ++#define P_CRC_OFFSET (20) ++#define P_CONTROL_OFFSET (24) ++#define PATCH_HDR_LEN (28) ++#define MAX_DATA_PER_SEGMENT (239) ++#define VSEVENT_CODE (0xFF) ++#define HC_VS_MAX_CMD_EVENT (0xFF) ++#define PATCH_PROD_ID_OFFSET (5) ++#define PATCH_PATCH_VER_OFFSET (9) ++#define PATCH_ROM_BUILD_VER_OFFSET (11) ++#define PATCH_SOC_VER_OFFSET (13) ++#define MAX_SIZE_PER_TLV_SEGMENT (243) ++ ++/* VS Opcode */ ++#define HCI_PATCH_CMD_OCF (0) ++#define EDL_SET_BAUDRATE_CMD_OCF (0x48) ++ ++/* VS Commands */ ++#define VSC_SET_BAUDRATE_REQ_LEN (1) ++#define EDL_PATCH_CMD_LEN (1) ++#define EDL_PATCH_CMD_REQ_LEN (1) ++#define EDL_PATCH_DLD_REQ_CMD (0x01) ++#define EDL_PATCH_RST_REQ_CMD (0x05) ++#define EDL_PATCH_SET_REQ_CMD (0x16) ++#define EDL_PATCH_ATCH_REQ_CMD (0x17) ++#define EDL_PATCH_VER_REQ_CMD (0x19) ++#define EDL_PATCH_TLV_REQ_CMD (0x1E) ++#define VSC_DISABLE_IBS_LEN (0x04) ++ ++/* VS Event */ ++#define EDL_CMD_REQ_RES_EVT (0x00) ++#define EDL_CMD_EXE_STATUS_EVT (0x00) ++#define EDL_SET_BAUDRATE_RSP_EVT (0x92) ++#define EDL_PATCH_VER_RES_EVT (0x19) ++#define EDL_TVL_DNLD_RES_EVT (0x04) ++#define EDL_APP_VER_RES_EVT (0x02) ++ ++ ++/* Status Codes of HCI CMD execution*/ ++#define HCI_CMD_SUCCESS (0x0) ++#define PATCH_LEN_ERROR (0x1) ++#define PATCH_VER_ERROR (0x2) ++#define PATCH_CRC_ERROR (0x3) ++#define PATCH_NOT_FOUND (0x4) ++#define TLV_TYPE_ERROR (0x10) ++#define NVM_ACCESS_CODE (0x0B) ++#define BAUDRATE_CHANGE_SUCCESS (1) ++ ++/* TLV_TYPE */ ++#define TLV_TYPE_PATCH (1) ++#define TLV_TYPE_NVM (2) ++ ++/* NVM */ ++#define MAX_TAG_CMD 30 ++#define TAG_END 0xFF ++#define NVM_ACCESS_SET 0x01 ++#define TAG_NUM_OFFSET 5 ++#define TAG_NUM_2 2 ++#define TAG_BDADDR_OFFSET 7 ++ ++/* NVM Tags specifically used for ROME 1.0 */ ++#define ROME_1_0_100022_1 0x101000221 ++#define ROME_1_0_100019 0x101000190 ++#define ROME_1_0_6002 0x100600200 ++ ++/* Default NVM Version setting for ROME 1.0 */ ++#define NVM_VERSION ROME_1_0_100022_1 ++ ++ ++#define LSH(val, n) ((unsigned int)(val) << (n)) ++#define EXTRACT_BYTE(val, pos) (char) (((val) >> (8 * (pos))) & 0xFF) ++#define CALC_SEG_SIZE(len, max) ((plen) % (max))?((plen/max)+1) : ((plen) / (max)) ++ ++#define ROME_FW_PATH "/lib/firmware/rampatch.img" ++#define ROME_RAMPATCH_TLV_PATH "/lib/firmware/rampatch_tlv.img" ++#define ROME_NVM_TLV_PATH "/lib/firmware/nvm_tlv.bin" ++#define ROME_RAMPATCH_TLV_1_0_3_PATH "/lib/firmware/rampatch_tlv_1.3.tlv" ++#define ROME_NVM_TLV_1_0_3_PATH "/lib/firmware/nvm_tlv_1.3.bin" ++#define ROME_RAMPATCH_TLV_2_0_1_PATH "/lib/firmware/rampatch_tlv_2.1.tlv" ++#define ROME_NVM_TLV_2_0_1_PATH "/lib/firmware/nvm_tlv_2.1.bin" ++#define ROME_RAMPATCH_TLV_3_0_0_PATH "/lib/firmware/qca/rampatch_tlv_3.0.tlv" ++#define ROME_NVM_TLV_3_0_0_PATH "/lib/firmware/qca/nvm_tlv_3.0.bin" ++ ++ ++/****************************************************************************** ++** Local type definitions ++******************************************************************************/ ++ ++typedef struct { ++ unsigned char ncmd; ++ unsigned short opcode; ++} __attribute__ ((packed)) evt_cmd_complete; ++ ++typedef struct { ++ unsigned char status; ++ unsigned char ncmd; ++ unsigned short opcode; ++} __attribute__ ((packed)) evt_cmd_status; ++ ++typedef struct { ++ unsigned short opcode; ++ unsigned char plen; ++} __attribute__ ((packed)) hci_command_hdr; ++ ++typedef struct { ++ unsigned char evt; ++ unsigned char plen; ++} __attribute__ ((packed)) hci_event_hdr; ++typedef struct { ++ unsigned short rom_version; ++ unsigned short build_version; ++} __attribute__ ((packed)) patch_version; ++ ++typedef struct { ++ unsigned int patch_id; ++ patch_version patch_ver; ++ unsigned int patch_base_addr; ++ unsigned int patch_entry_addr; ++ unsigned short patch_length; ++ int patch_crc; ++ unsigned short patch_ctrl; ++} __attribute__ ((packed)) patch_info; ++ ++typedef struct { ++ unsigned char sign_ver; ++ unsigned char sign_algorithm; ++ unsigned short reserved1; ++ unsigned short prod_id; ++ unsigned short build_ver; ++ unsigned short patch_ver; ++ unsigned short reserved2; ++ unsigned int patch_entry_addr; ++} __attribute__ ((packed)) tlv_patch_hdr; ++ ++typedef struct { ++ unsigned short tag_id; ++ unsigned short tag_len; ++ unsigned int tag_ptr; ++ unsigned int tag_ex_flag; ++} __attribute__ ((packed)) tlv_nvm_hdr; ++ ++typedef struct { ++ unsigned char tlv_type; ++ unsigned char tlv_length1; ++ unsigned char tlv_length2; ++ unsigned char tlv_length3; ++ unsigned int tlv_data_len; ++ unsigned int tlv_patch_data_len; ++ ++ union{ ++ tlv_patch_hdr patch; ++ tlv_nvm_hdr nvm; ++ }tlv; ++} __attribute__ ((packed)) tlv_patch_info; ++ ++enum{ ++ BAUDRATE_115200 = 0x00, ++ BAUDRATE_57600 = 0x01, ++ BAUDRATE_38400 = 0x02, ++ BAUDRATE_19200 = 0x03, ++ BAUDRATE_9600 = 0x04, ++ BAUDRATE_230400 = 0x05, ++ BAUDRATE_250000 = 0x06, ++ BAUDRATE_460800 = 0x07, ++ BAUDRATE_500000 = 0x08, ++ BAUDRATE_720000 = 0x09, ++ BAUDRATE_921600 = 0x0A, ++ BAUDRATE_1000000 = 0x0B, ++ BAUDRATE_1250000 = 0x0C, ++ BAUDRATE_2000000 = 0x0D, ++ BAUDRATE_3000000 = 0x0E, ++ BAUDRATE_4000000 = 0x0F, ++ BAUDRATE_1600000 = 0x10, ++ BAUDRATE_3200000 = 0x11, ++ BAUDRATE_3500000 = 0x12, ++ BAUDRATE_AUTO = 0xFE, ++ BAUDRATE_Reserved = 0xFF ++}; ++ ++enum{ ++ ROME_PATCH_VER_0100 = 0x0100, ++ ROME_PATCH_VER_0101 = 0x0101, ++ ROME_PATCH_VER_0200 = 0x0200, ++ ROME_PATCH_VER_0300 = 0x0300 ++ }; ++ ++enum{ ++ ROME_SOC_ID_00 = 0x00000000, ++ ROME_SOC_ID_11 = 0x00000011, ++ ROME_SOC_ID_13 = 0x00000013, ++ ROME_SOC_ID_22 = 0x00000022, ++}; ++ ++enum{ ++ ROME_VER_UNKNOWN = 0, ++ ROME_VER_1_0 = ((ROME_PATCH_VER_0100 << 16 ) | ROME_SOC_ID_00 ), ++ ROME_VER_1_1 = ((ROME_PATCH_VER_0101 << 16 ) | ROME_SOC_ID_00 ), ++ ROME_VER_1_3 = ((ROME_PATCH_VER_0200 << 16 ) | ROME_SOC_ID_00 ), ++ ROME_VER_2_1 = ((ROME_PATCH_VER_0200 << 16 ) | ROME_SOC_ID_11 ), ++ ROME_VER_3_0 = ((ROME_PATCH_VER_0300 << 16 ) | ROME_SOC_ID_22 ), ++ TUFELLO_VER_1_0 = ((ROME_PATCH_VER_0300 << 16 ) | ROME_SOC_ID_13 ) ++}; ++#endif /* HW_ROME_H */ + +From 333676e63694e137558e7a685d2fa1a50c499436 Mon Sep 17 00:00:00 2001 +From: Anantha Krishnan +Date: Thu, 11 Sep 2014 19:20:02 +0530 +Subject: [PATCH 02/19] bluetooth: Enable bluetooth low power mode + functionality + +During periods of inactivity the bluetooth controller and the +application processor will indicate each other to enter into +low power mode and signal each other when they have data to be +exchanged, thereby saving considerable amount of power. + +Change-Id: I9e0d579ac8a9d61a2ebde78b031f4101cb6bc443 +Signed-off-by: Rupesh Tatiya +--- + tools/hciattach.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/hciattach.c b/tools/hciattach.c +index 73811d4c4c2a..e3a915061440 100644 +--- a/tools/hciattach.c ++++ b/tools/hciattach.c +@@ -1102,7 +1102,7 @@ struct uart_t uart[] = { + FLOW_CTL, DISABLE_PM, NULL, ath3k_ps, ath3k_pm }, + + /* QCA ROME */ +- { "qca", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, ++ { "qca", 0x0000, 0x0000, HCI_UART_IBS, 115200, 115200, + FLOW_CTL, DISABLE_PM, NULL, qca, NULL }, + + /* QUALCOMM BTS */ + +From 0518592a10bff2ac0b99e4081bd01154f2eeacb6 Mon Sep 17 00:00:00 2001 +From: Anantha Krishnan +Date: Thu, 11 Sep 2014 18:57:45 +0530 +Subject: [PATCH 03/19] bluetooth: Fix bug in firmware parsing mechanism + +Reorganize the RAMPATCH members to be present as part of the +RAMPATCH header structre instead of the main firmware structure + +Change-Id: If523e1bb20edcd52b7c6f623c07af492e6305bd0 +Signed-off-by: Rupesh Tatiya +--- + tools/hciattach_rome.c | 4 ++-- + tools/hciattach_rome.h | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index f31be43c09e4..122a0f4b89bc 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -851,8 +851,8 @@ int rome_get_tlv_file(char *file_path) + fprintf(stderr, "Length\t\t\t : %d bytes\n", (ptlv_header->tlv_length1) | + (ptlv_header->tlv_length2 << 8) | + (ptlv_header->tlv_length3 << 16)); +- fprintf(stderr, "Total Length\t\t\t : %d bytes\n", ptlv_header->tlv_data_len); +- fprintf(stderr, "Patch Data Length\t\t\t : %d bytes\n",ptlv_header->tlv_patch_data_len); ++ fprintf(stderr, "Total Length\t\t\t : %d bytes\n", ptlv_header->tlv.patch.tlv_data_len); ++ fprintf(stderr, "Patch Data Length\t\t\t : %d bytes\n",ptlv_header->tlv.patch.tlv_patch_data_len); + fprintf(stderr, "Signing Format Version\t : 0x%x\n", ptlv_header->tlv.patch.sign_ver); + fprintf(stderr, "Signature Algorithm\t\t : 0x%x\n", ptlv_header->tlv.patch.sign_algorithm); + fprintf(stderr, "Reserved\t\t\t : 0x%x\n", ptlv_header->tlv.patch.reserved1); +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +index aa59965643ec..07127f30a70a 100644 +--- a/tools/hciattach_rome.h ++++ b/tools/hciattach_rome.h +@@ -236,6 +236,8 @@ typedef struct { + } __attribute__ ((packed)) patch_info; + + typedef struct { ++ unsigned int tlv_data_len; ++ unsigned int tlv_patch_data_len; + unsigned char sign_ver; + unsigned char sign_algorithm; + unsigned short reserved1; +@@ -258,8 +260,6 @@ typedef struct { + unsigned char tlv_length1; + unsigned char tlv_length2; + unsigned char tlv_length3; +- unsigned int tlv_data_len; +- unsigned int tlv_patch_data_len; + + union{ + tlv_patch_hdr patch; + +From 78f1ab9c20956f4e6f009d7bc2b94fe1d4474a08 Mon Sep 17 00:00:00 2001 +From: Anantha Krishnan +Date: Mon, 8 Sep 2014 15:11:02 +0530 +Subject: [PATCH 04/19] bluetooth: Configure BD Address + +Read the BD Address programmed by user from persist location. +If there is no user programmed BD address then use the default +BD address present in the firmware file. + +Change-Id: Id702d1476bae765dfd23f88542bfd5a8a1f26056 +Signed-off-by: Rupesh Tatiya +--- + tools/hciattach_rome.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++--- + tools/hciattach_rome.h | 7 +++++++ + 2 files changed, 60 insertions(+), 3 deletions(-) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index 122a0f4b89bc..947e1abb96c4 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -809,6 +809,7 @@ int rome_get_tlv_file(char *file_path) + tlv_nvm_hdr *nvm_ptr; + unsigned char data_buf[PRINT_BUF_SIZE]={0,}; + unsigned char *nvm_byte_ptr; ++ unsigned char bdaddr[6]; + + fprintf(stderr, "File Open (%s)\n", file_path); + pFile = fopen ( file_path , "r" ); +@@ -886,9 +887,10 @@ int rome_get_tlv_file(char *file_path) + nvm_byte_ptr+=sizeof(tlv_nvm_hdr); + + /* Write BD Address */ +- if(nvm_ptr->tag_id == TAG_NUM_2){ +- memcpy(nvm_byte_ptr, vnd_local_bd_addr, 6); +- fprintf(stderr, "BD Address: %.02x:%.02x:%.02x:%.02x:%.02x:%.02x\n", ++ if(nvm_ptr->tag_id == TAG_NUM_2 && read_bd_address(&bdaddr) == 0) { ++ memcpy(nvm_byte_ptr, bdaddr, 6); ++ fprintf(stderr, "Overriding default BD ADDR with user" ++ " programmed BD Address: %02x:%02x:%02x:%02x:%02x:%02x\n", + *nvm_byte_ptr, *(nvm_byte_ptr+1), *(nvm_byte_ptr+2), + *(nvm_byte_ptr+3), *(nvm_byte_ptr+4), *(nvm_byte_ptr+5)); + } +@@ -1451,6 +1453,54 @@ error: + + } + ++int read_bd_address(unsigned char *bdaddr) ++{ ++ int fd = -1; ++ int readPtr = 0; ++ unsigned char data[BD_ADDR_LEN]; ++ ++ /* Open the persist file for reading device address*/ ++ fd = open("/etc/bluetooth/.bt_nv.bin", O_RDONLY); ++ if(fd < 0) ++ { ++ fprintf(stderr, "%s: Open failed: Programming default BD ADDR\n", __func__); ++ return -1; ++ } ++ ++ /* Read the NVM Header : fp will be advanced by readPtr number of bytes */ ++ readPtr = read(fd, data, PERSIST_HEADER_LEN); ++ if (readPtr > 0) ++ fprintf(stderr, "%s: Persist header data: %02x \t %02x \t %02x\n", __func__, ++ data[NVITEM], data[RDWR_PROT], data[NVITEM_SIZE]); ++ else { ++ fprintf(stderr, "%s: Read from persist memory failed : Programming default" ++ " BD ADDR\n"); ++ close(fd); ++ return -1; ++ } ++ ++ /* Check for BD ADDR length before programming */ ++ if(data[NVITEM_SIZE] != BD_ADDR_LEN) { ++ fprintf(stderr, "Invalid BD ADDR: Programming default BD ADDR!\n"); ++ close(fd); ++ return -1; ++ } ++ ++ /* Read the BD ADDR info */ ++ readPtr = read(fd, data, BD_ADDR_LEN); ++ if (readPtr > 0) ++ fprintf(stderr, "BD-ADDR: ==> %02x:%02x:%02x:%02x:%02x:%02x\n", data[0], ++ data[1], data[2], data[3], data[4], data[5]); ++ else { ++ fprintf(stderr, "%s: Read from persist memory failed : Programming default" ++ " BD ADDR\n"); ++ close(fd); ++ return -1; ++ } ++ memcpy(bdaddr, data, BD_ADDR_LEN); ++ close(fd); ++ return 0; ++} + + int qca_soc_init(int fd, char *bdaddr) + { +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +index 07127f30a70a..a4abe9f73080 100644 +--- a/tools/hciattach_rome.h ++++ b/tools/hciattach_rome.h +@@ -34,6 +34,13 @@ + #define HCI_EVENT_PKT 0x04 + #define HCI_VENDOR_PKT 0xff + #define cmd_opcode_pack(ogf, ocf) (unsigned short)((ocf & 0x03ff)|(ogf << 10)) ++ ++#define NVITEM 0 ++#define RDWR_PROT 1 ++#define NVITEM_SIZE 2 ++#define PERSIST_HEADER_LEN 3 ++#define BD_ADDR_LEN 6 ++ + unsigned char vnd_local_bd_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + typedef enum { + USERIAL_OP_FLOW_ON, + +From 7f148243e9d36427734de874f291911e1f3d60d0 Mon Sep 17 00:00:00 2001 +From: Anantha Krishnan +Date: Mon, 8 Sep 2014 14:33:24 +0530 +Subject: [PATCH 05/19] bluetooth: Remove unused functions in the firmware + download process + +rome_disable_sleep() function is not used anywhere in the code and +hence remove it. + +Change-Id: Iec1f9b1478850af3023ff297493693283a5338d7 +Signed-off-by: Rupesh Tatiya +--- + tools/hciattach_rome.c | 48 ------------------------------------------------ + 1 file changed, 48 deletions(-) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index 947e1abb96c4..4fcbdf2ab82a 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -1317,54 +1317,6 @@ error: + + } + +-int rome_disable_sleep(int fd) +-{ +- int size, err = 0; +- unsigned char cmd[HCI_MAX_CMD_SIZE]; +- unsigned char rsp[HCI_MAX_EVENT_SIZE]; +- hci_command_hdr *cmd_hdr; +- int flags; +- +- memset(cmd, 0x0, HCI_MAX_CMD_SIZE); +- +- cmd_hdr = (void *) (cmd + 1); +- cmd[0] = HCI_COMMAND_PKT; +- cmd_hdr->opcode = cmd_opcode_pack(HCI_VENDOR_CMD_OGF, NVM_ACCESS_CODE); +- cmd_hdr->plen = VSC_DISABLE_IBS_LEN; +- cmd[4] = 0x01; +- cmd[5] = 0x1B; +- cmd[6] = 0x01; +- cmd[7] = 0x00; +- +- /* Total length of the packet to be sent to the Controller */ +- size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + VSC_DISABLE_IBS_LEN); +- /* Send the HCI command packet to UART for transmission */ +- fprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6], cmd[7]) ; +- err = write(fd, cmd, size); +- if (err != size) { +- fprintf(stderr, "%s: Send failed with ret value: %d\n", __FUNCTION__, err); +- goto error; +- } +- +- /* Check for response from the Controller */ +- if ((err =read_vs_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE)) < 0) { +- fprintf(stderr, "%s: Failed to get HCI-VS Event from SOC\n", __FUNCTION__); +- goto error; +- } +- +- fprintf(stderr, "%s: Received HCI-Vendor Specific Event from SOC\n", __FUNCTION__); +- +- /* Wait for command complete event */ +- err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); +- if ( err < 0) { +- fprintf(stderr, "%s: Failed to set patch info on Controller\n", __FUNCTION__); +- goto error; +- } +- fprintf(stderr, "%s\n", __FUNCTION__); +-error: +- return err; +- +-} + + int rome_set_baudrate_req(int fd) + { + +From 175fe3690522afc91f38933f821e4b00bd1a12c8 Mon Sep 17 00:00:00 2001 +From: Anantha Krishnan +Date: Mon, 8 Sep 2014 14:31:18 +0530 +Subject: [PATCH 06/19] bluetooth: Enable 3Mbps baud rate support + +Allow APPS PROC and BT Controller to operate at 3Mbps baud rate +for faster exchange of commands, events and data between the two + +Change-Id: I55651633027ea60a762b11abea84fe1abd6574a9 +Signed-off-by: Rupesh Tatiya +--- + tools/hciattach_rome.c | 63 ++++++++++++++++++++++++++++++++++++++------------ + 1 file changed, 48 insertions(+), 15 deletions(-) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index 4fcbdf2ab82a..d0e2935b9997 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -166,6 +166,7 @@ int userial_vendor_ioctl(int fd, userial_vendor_ioctl_op_t op, int *p_data) + } + cfmakeraw(&ti); + ti.c_cflag |= CLOCAL; ++ ti.c_cflag |= CREAD; + + switch(op) + { +@@ -332,6 +333,8 @@ int read_vs_hci_event(int fd, unsigned char* buf, int size) + { + int remain, r; + int count = 0; ++ fd_set infids; ++ struct timeval timeout; + + if (size <= 0) { + fprintf(stderr, "Invalid size arguement!\n"); +@@ -340,6 +343,16 @@ int read_vs_hci_event(int fd, unsigned char* buf, int size) + + fprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC\n", __FUNCTION__); + ++ FD_ZERO (&infids); ++ FD_SET (fd, &infids); ++ timeout.tv_sec = 3; ++ timeout.tv_usec = 0; /* half second is a long time at 115.2 Kbps */ ++ ++ if (select (fd + 1, &infids, NULL, NULL, &timeout) < 1) ++ fprintf(stderr, "%s: Timing out on select for 3 secs.\n", __FUNCTION__); ++ else ++ fprintf(stderr, "%s: Data available in TTY Serial buffer\n", __FUNCTION__); ++ + /* The first byte identifies the packet type. For HCI event packets, it + * should be 0x04, so we read until we get to the 0x04. */ + /* It will keep reading until find 0x04 byte */ +@@ -1332,10 +1345,16 @@ int rome_set_baudrate_req(int fd) + cmd[0] = HCI_COMMAND_PKT; + cmd_hdr->opcode = cmd_opcode_pack(HCI_VENDOR_CMD_OGF, EDL_SET_BAUDRATE_CMD_OCF); + cmd_hdr->plen = VSC_SET_BAUDRATE_REQ_LEN; +- cmd[4] = BAUDRATE_115200; ++ cmd[4] = BAUDRATE_3000000; + + /* Total length of the packet to be sent to the Controller */ + size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + VSC_SET_BAUDRATE_REQ_LEN); ++ /* Flow off during baudrate change */ ++ if ((err = userial_vendor_ioctl(fd, USERIAL_OP_FLOW_OFF , &flags)) < 0) ++ { ++ fprintf(stderr, "%s: HW Flow-off error: 0x%x\n", __FUNCTION__, err); ++ goto error; ++ } + /* Send the HCI command packet to UART for transmission */ + fprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3],cmd[4]) ; + err = write(fd, cmd, size); +@@ -1343,7 +1362,15 @@ int rome_set_baudrate_req(int fd) + fprintf(stderr, "%s: Send failed with ret value: %d\n", __FUNCTION__, err); + goto error; + } ++ /* Change Local UART baudrate to high speed UART */ ++ userial_vendor_set_baud(USERIAL_BAUD_3M); + ++ /* Flow on after changing local uart baudrate */ ++ if ((err = userial_vendor_ioctl(fd, USERIAL_OP_FLOW_ON , &flags)) < 0) ++ { ++ fprintf(stderr, "%s: HW Flow-on error: 0x%x \n", __FUNCTION__, err); ++ return err; ++ } + /* Check for response from the Controller */ + if ((err =read_vs_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE)) < 0) { + fprintf(stderr, "%s: Failed to get HCI-VS Event from SOC\n", __FUNCTION__); +@@ -1385,6 +1412,12 @@ int rome_hci_reset_req(int fd) + /* Total length of the packet to be sent to the Controller */ + size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE); + ++ /* Flow off during baudrate change */ ++ if ((err = userial_vendor_ioctl(fd, USERIAL_OP_FLOW_OFF , &flags)) < 0) ++ { ++ fprintf(stderr, "%s: HW Flow-off error: 0x%x\n", __FUNCTION__, err); ++ goto error; ++ } + /* Send the HCI command packet to UART for transmission */ + fprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3]); + err = write(fd, cmd, size); +@@ -1393,6 +1426,15 @@ int rome_hci_reset_req(int fd) + goto error; + } + ++ /* Change Local UART baudrate to high speed UART */ ++ userial_vendor_set_baud(USERIAL_BAUD_3M); ++ ++ /* Flow on after changing local uart baudrate */ ++ if ((err = userial_vendor_ioctl(fd, USERIAL_OP_FLOW_ON , &flags)) < 0) ++ { ++ fprintf(stderr, "%s: HW Flow-on error: 0x%x \n", __FUNCTION__, err); ++ return err; ++ } + /* Wait for command complete event */ + err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); + if ( err < 0) { +@@ -1534,16 +1576,7 @@ int qca_soc_init(int fd, char *bdaddr) + nvm_file_path = ROME_NVM_TLV_3_0_0_PATH; + + download: +- /* Donwload TLV files (rampatch, NVM) */ +- err = rome_download_tlv_file(fd); +- if (err < 0) { +- fprintf(stderr, "%s: Download TLV file failed!\n", __FUNCTION__); +- goto error; +- } +- fprintf(stderr, "%s: Download TLV file successfully \n", __FUNCTION__); +- +- /* Change baud rate back to user requested */ +- fprintf(stderr, "Changing baud rate back from 3M --> 115K\n"); ++ /* Change baud rate 115.2 kbps to 3Mbps*/ + err = rome_set_baudrate_req(fd); + if (err < 0) { + fprintf(stderr, "%s: Baud rate change failed!\n", __FUNCTION__); +@@ -1551,13 +1584,13 @@ download: + } + fprintf(stderr, "%s: Baud rate changed successfully \n", __FUNCTION__); + +- fprintf(stderr, "%s: Disabling In Band Sleep functionality\n", __FUNCTION__); +- err = rome_disable_sleep(fd); ++ /* Donwload TLV files (rampatch, NVM) */ ++ err = rome_download_tlv_file(fd); + if (err < 0) { +- fprintf(stderr, "%s: Failed to disable IBS!\n", __FUNCTION__); ++ fprintf(stderr, "%s: Download TLV file failed!\n", __FUNCTION__); + goto error; + } +- fprintf(stderr, "%s: IBS disabled successfully \n", __FUNCTION__); ++ fprintf(stderr, "%s: Download TLV file successfully \n", __FUNCTION__); + + /* Perform HCI reset here*/ + err = rome_hci_reset_req(fd); + +From 1911a9d5799d110a7d010e154b44e43c65e838ff Mon Sep 17 00:00:00 2001 +From: Anantha Krishnan +Date: Tue, 30 Sep 2014 12:13:00 +0530 +Subject: [PATCH 07/19] bluetooth: Check TTY buffer for data availability + before reading + +When operating at higher baud rates check the TTY buffer for +availability of data before proceeding to read. Call select() with +a 3 sec timeout value to check for the availablitiy of data. +select() will return once data is available in the TTY buffers +and will allow read() to fetch the data. If data is not available +in the TTY buffer until the timeout valueexpires, do not proceed +to read the data from the TTY buffers as there is none. + +Occasionally corrupt data is received on UART lines while we wait +for vendor specific event from Controller. Expected vendor specific +events are received after the corrupt data. But we do not retry +and exit and this causes firmware download failures. So, retry once +if we did not get HCI event. + +Change-Id: I3b672a7762403690f8b934ca216492f16285e8da +Signed-off-by: Rupesh Tatiya +--- + tools/hciattach.c | 20 ++++++++++++- + tools/hciattach_rome.c | 77 +++++++++++++++++++++++++++++++++++++++----------- + tools/hciattach_rome.h | 3 ++ + 3 files changed, 83 insertions(+), 17 deletions(-) + +diff --git a/tools/hciattach.c b/tools/hciattach.c +index e3a915061440..c3cf10843303 100644 +--- a/tools/hciattach.c ++++ b/tools/hciattach.c +@@ -109,16 +109,34 @@ int read_hci_event(int fd, unsigned char* buf, int size) + { + int remain, r; + int count = 0; ++ fd_set infids; ++ struct timeval timeout; + + if (size <= 0) + return -1; + ++ FD_ZERO (&infids); ++ FD_SET (fd, &infids); ++ timeout.tv_sec = 3; ++ timeout.tv_usec = 0; ++ ++ /* Check whether data is available in TTY buffer before calling read() */ ++ if (select (fd + 1, &infids, NULL, NULL, &timeout) < 1) { ++ fprintf(stderr, "%s: Timing out on select for 3 secs.\n", __FUNCTION__); ++ return -1; ++ } ++ else ++ fprintf(stderr, "%s: Data(HCI-CMD-COMP-EVENT) available in TTY Serial buffer\n", __FUNCTION__); ++ + /* The first byte identifies the packet type. For HCI event packets, it + * should be 0x04, so we read until we get to the 0x04. */ + while (1) { + r = read(fd, buf, 1); +- if (r <= 0) ++ if (r <= 0) { ++ fprintf(stderr, "%s: read() failed with return value: %d\n", ++ __FUNCTION__, r); + return -1; ++ } + if (buf[0] == 0x04) + break; + } +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index d0e2935b9997..d2687b1ef01a 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -326,42 +326,87 @@ failed: + } + + ++int wait_for_data(int fd, int maxTimeOut) ++{ ++ fd_set infids; ++ struct timeval timeout; ++ ++ if (maxTimeOut <= 0) { ++ fprintf(stderr, "%s: Invalid timeout value specified", __func__); ++ return -EINVAL; ++ } ++ ++ FD_ZERO (&infids); ++ FD_SET (fd, &infids); ++ timeout.tv_sec = maxTimeOut; ++ timeout.tv_usec = 0; ++ ++ /* Check whether data is available in TTY buffer before calling read() */ ++ if (select (fd + 1, &infids, NULL, NULL, &timeout) < 1) { ++ fprintf(stderr, "%s: Timing out on select for %d secs.\n", __FUNCTION__, maxTimeOut); ++ return -1; ++ } ++ else ++ fprintf(stderr, "%s: HCI-VS-EVENT available in TTY Serial buffer\n", ++ __FUNCTION__); ++ ++ return 1; ++} ++ + /* + * Read an VS HCI event from the given file descriptor. + */ + int read_vs_hci_event(int fd, unsigned char* buf, int size) + { +- int remain, r; ++ int remain, r, retry = 0; + int count = 0; +- fd_set infids; +- struct timeval timeout; + + if (size <= 0) { + fprintf(stderr, "Invalid size arguement!\n"); + return -1; + } + +- fprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC\n", __FUNCTION__); +- +- FD_ZERO (&infids); +- FD_SET (fd, &infids); +- timeout.tv_sec = 3; +- timeout.tv_usec = 0; /* half second is a long time at 115.2 Kbps */ ++ fprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC\n", ++ __FUNCTION__); + +- if (select (fd + 1, &infids, NULL, NULL, &timeout) < 1) +- fprintf(stderr, "%s: Timing out on select for 3 secs.\n", __FUNCTION__); +- else +- fprintf(stderr, "%s: Data available in TTY Serial buffer\n", __FUNCTION__); ++ /* Check whether data is available in TTY buffer before calling read() */ ++ if (wait_for_data(fd, SELECT_TIMEOUT) < 1) ++ return -1; + + /* The first byte identifies the packet type. For HCI event packets, it + * should be 0x04, so we read until we get to the 0x04. */ + /* It will keep reading until find 0x04 byte */ + while (1) { ++ /* Read UART Buffer for HCI-DATA */ + r = read(fd, buf, 1); +- if (r <= 0) +- return -1; +- if (buf[0] == 0x04) ++ if (r <= 0) { ++ fprintf(stderr, "%s: read() failed. error: %d\n", ++ __FUNCTION__, r); ++ return -1; ++ } ++ ++ /* Check if received data is HCI-DATA or not. ++ * If not HCI-DATA, then retry reading the UART Buffer once. ++ * Sometimes there could be corruption on the UART lines and to ++ * avoid that retry once reading the UART Buffer for HCI-DATA. ++ */ ++ if (buf[0] == 0x04) { /* Recvd. HCI DATA */ ++ retry = 0; + break; ++ } ++ else if (retry < MAX_RETRY_CNT){ /* Retry mechanism */ ++ retry++; ++ fprintf(stderr, "%s: Not an HCI-VS-Event! buf[0]: %d", ++ __FUNCTION__, buf[0]); ++ if (wait_for_data(fd, SELECT_TIMEOUT) < 1) ++ return -1; ++ else /* Data available in UART Buffer: Continue to read */ ++ continue; ++ } ++ else { /* RETRY failed : Exiting with failure */ ++ fprintf(stderr, "%s: RETRY failed!", __FUNCTION__); ++ return -1; ++ } + } + count++; + +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +index a4abe9f73080..3efb71995c45 100644 +--- a/tools/hciattach_rome.h ++++ b/tools/hciattach_rome.h +@@ -179,6 +179,9 @@ typedef struct + #define TAG_NUM_2 2 + #define TAG_BDADDR_OFFSET 7 + ++#define MAX_RETRY_CNT 1 ++#define SELECT_TIMEOUT 3 ++ + /* NVM Tags specifically used for ROME 1.0 */ + #define ROME_1_0_100022_1 0x101000221 + #define ROME_1_0_100019 0x101000190 + +From 9d81b1dd643966ba6f2ffb3f7658a24cfcb37df4 Mon Sep 17 00:00:00 2001 +From: Anantha Krishnan +Date: Wed, 20 Aug 2014 12:13:19 +0530 +Subject: [PATCH 08/19] bluetooth : Add support for TUFEELO firmware download + +Add TUFELLO chip version to allow firmware download. + +Change-Id: Ie3760fa64e8345bf9a84b2f047fde0ac1003b393 +--- + tools/hciattach_rome.c | 5 ++++- + tools/hciattach_rome.h | 3 ++- + 2 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index d2687b1ef01a..84dfc97b5140 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -1616,9 +1616,12 @@ int qca_soc_init(int fd, char *bdaddr) + nvm_file_path = ROME_NVM_TLV_2_0_1_PATH; + goto download; + case ROME_VER_3_0: +- case TUFELLO_VER_1_0: + rampatch_file_path = ROME_RAMPATCH_TLV_3_0_0_PATH; + nvm_file_path = ROME_NVM_TLV_3_0_0_PATH; ++ goto download; ++ case TUFELLO_VER_1_0: ++ rampatch_file_path = TF_RAMPATCH_TLV_1_0_0_PATH; ++ nvm_file_path = TF_NVM_TLV_1_0_0_PATH; + + download: + /* Change baud rate 115.2 kbps to 3Mbps*/ +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +index 3efb71995c45..9d18c576fcae 100644 +--- a/tools/hciattach_rome.h ++++ b/tools/hciattach_rome.h +@@ -204,7 +204,8 @@ typedef struct + #define ROME_NVM_TLV_2_0_1_PATH "/lib/firmware/nvm_tlv_2.1.bin" + #define ROME_RAMPATCH_TLV_3_0_0_PATH "/lib/firmware/qca/rampatch_tlv_3.0.tlv" + #define ROME_NVM_TLV_3_0_0_PATH "/lib/firmware/qca/nvm_tlv_3.0.bin" +- ++#define TF_RAMPATCH_TLV_1_0_0_PATH "/lib/firmware/rampatch_tlv_tf_1.0.tlv" ++#define TF_NVM_TLV_1_0_0_PATH "/lib/firmware/nvm_tlv_tf_1.0.bin" + + /****************************************************************************** + ** Local type definitions + +From ac12a2a733ad6cc6eed8ccdd3462d1fe1969fc54 Mon Sep 17 00:00:00 2001 +From: Anantha Krishnan +Date: Mon, 8 Dec 2014 14:52:16 +0530 +Subject: [PATCH 09/19] bluetooth: Add support for ROME 3.2 SOC. + +Add firmware download support for ROME 3.2 version. As part +of this, the Bluetooth on time is optimized based on event +handling while downloading rampatch files.From ROME 3.2 onwards, +the VS and command complete events will be sent depending the flag +indication present in the header. HOST can wait for VS and command +complete events only if specified in the header info. This greatly +reduces the time spent by HOST in waiting for 2 events from the +Controller before downloading each segment of the RAMPATCH file + +Change-Id: I9c4227a7a529455f4d120b2c9d065f3ec6b439e9 +--- + tools/hciattach_rome.c | 104 ++++++++++++++++++++++++++++++++++++++++++------- + tools/hciattach_rome.h | 16 +++++++- + 2 files changed, 103 insertions(+), 17 deletions(-) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index 84dfc97b5140..c6d528f118e1 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -62,9 +62,11 @@ unsigned char *pdata_buffer = NULL; + patch_info rampatch_patch_info; + int rome_ver = ROME_VER_UNKNOWN; + unsigned char gTlv_type; ++unsigned char gtlv_dwndcfg; + char *rampatch_file_path; + char *nvm_file_path; + vnd_userial_cb_t vnd_userial; ++unsigned char wait_vsc_evt = TRUE; + /****************************************************************************** + ** Extern variables + ******************************************************************************/ +@@ -455,14 +457,16 @@ int hci_send_vs_cmd(int fd, unsigned char *cmd, unsigned char *rsp, int size) + goto failed; + } + +- /* Check for response from the Controller */ +- if (read_vs_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE) < 0) { +- ret = -ETIMEDOUT; +- fprintf(stderr, "%s: Failed to get HCI-VS Event from SOC\n", __FUNCTION__); +- goto failed; ++ if (wait_vsc_evt) { ++ /* Check for response from the Controller */ ++ if (read_vs_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE) < 0) { ++ ret = -ETIMEDOUT; ++ fprintf(stderr, "%s: Failed to get HCI-VS Event from SOC\n", __FUNCTION__); ++ goto failed; ++ } ++ fprintf(stderr, "%s: Received HCI-Vendor Specific Event from SOC\n", __FUNCTION__); + } + +- fprintf(stderr, "%s: Received HCI-Vendor Specific Event from SOC\n", __FUNCTION__); + failed: + return ret; + } +@@ -903,6 +907,7 @@ int rome_get_tlv_file(char *file_path) + + /* To handle different event between rampatch and NVM */ + gTlv_type = ptlv_header->tlv_type; ++ gtlv_dwndcfg = ptlv_header->tlv.patch.dwnd_cfg; + + if(ptlv_header->tlv_type == TLV_TYPE_PATCH){ + fprintf(stderr, "====================================================\n"); +@@ -914,6 +919,7 @@ int rome_get_tlv_file(char *file_path) + fprintf(stderr, "Patch Data Length\t\t\t : %d bytes\n",ptlv_header->tlv.patch.tlv_patch_data_len); + fprintf(stderr, "Signing Format Version\t : 0x%x\n", ptlv_header->tlv.patch.sign_ver); + fprintf(stderr, "Signature Algorithm\t\t : 0x%x\n", ptlv_header->tlv.patch.sign_algorithm); ++ fprintf(stderr, "Event Handling\t\t\t : 0x%x", ptlv_header->tlv.patch.dwnd_cfg); + fprintf(stderr, "Reserved\t\t\t : 0x%x\n", ptlv_header->tlv.patch.reserved1); + fprintf(stderr, "Product ID\t\t\t : 0x%04x\n", ptlv_header->tlv.patch.prod_id); + fprintf(stderr, "Rom Build Version\t\t : 0x%04x\n", ptlv_header->tlv.patch.build_ver); +@@ -1023,19 +1029,83 @@ int rome_tlv_dnld_req(int fd, int tlv_size) + fprintf(stderr, "%s: TLV size: %d, Total Seg num: %d, remain size: %d\n", + __FUNCTION__,tlv_size, total_segment, remain_size); + +- for(i=0;i= ROME_VER_1_1) && (gTlv_type == TLV_TYPE_PATCH ) +- && !remain_size && ((i+1) == total_segment))? FALSE: TRUE; ++ if (gTlv_type == TLV_TYPE_PATCH) { ++ /* Prior to Rome version 3.2(including inital few rampatch release of ++ * Rome 3.2), the event handling mechanism is ROME_SKIP_EVT_NONE. After ++ * few release of rampatch for Rome 3.2, the mechamism is changed to ++ * ROME_SKIP_EVT_VSE_CC. Rest of the mechanism is not used for now ++ */ ++ switch(gtlv_dwndcfg) ++ { ++ case ROME_SKIP_EVT_NONE: ++ wait_vsc_evt = TRUE; ++ wait_cc_evt = TRUE; ++ fprintf(stderr, "%s: Event handling type: ROME_SKIP_EVT_NONE", __func__); ++ break; ++ case ROME_SKIP_EVT_VSE_CC: ++ wait_vsc_evt = FALSE; ++ wait_cc_evt = FALSE; ++ fprintf(stderr, "%s: Event handling type: ROME_SKIP_EVT_VSE_CC", __func__); ++ break; ++ /* Not handled for now */ ++ case ROME_SKIP_EVT_VSE: ++ case ROME_SKIP_EVT_CC: ++ default: ++ fprintf(stderr, "%s: Unsupported Event handling: %d", __func__, gtlv_dwndcfg); ++ break; ++ } ++ } else { ++ wait_vsc_evt = TRUE; ++ wait_cc_evt = TRUE; ++ } ++ ++ for(i = 0; i < total_segment; i++) { ++ if((i+1) == total_segment) { ++ if ((rome_ver >= ROME_VER_1_1) && (rome_ver < ROME_VER_3_2) && ++ (gTlv_type == TLV_TYPE_PATCH)) { ++ /* If the Rome version is from 1.1 to 3.1 ++ * 1. No CCE for the last command segment but all other segment ++ * 2. All the command segments get VSE including the last one ++ */ ++ wait_cc_evt = !remain_size ? FALSE: TRUE; ++ } else if ((rome_ver == ROME_VER_3_2) && (gTlv_type == TLV_TYPE_PATCH)) { ++ /* If the Rome version is 3.2 ++ * 1. None of the command segments receive CCE ++ * 2. No command segments receive VSE except the last one ++ * 3. If gtlv_dwndcfg is ROME_SKIP_EVT_NONE then the logic is ++ * same as Rome 2.1, 2.2, 3.0 ++ */ ++ if (gtlv_dwndcfg == ROME_SKIP_EVT_NONE) { ++ wait_cc_evt = !remain_size ? FALSE: TRUE; ++ } else if (gtlv_dwndcfg == ROME_SKIP_EVT_VSE_CC) { ++ wait_vsc_evt = !remain_size ? TRUE: FALSE; ++ } ++ } ++ } ++ + if((err = rome_tlv_dnld_segment(fd, i, MAX_SIZE_PER_TLV_SEGMENT, wait_cc_evt )) < 0) + goto error; + } + +- /* In case remain data still remain, last rampatch segment command will not wait +- for command complete event here */ +- wait_cc_evt = ((rome_ver >= ROME_VER_1_1) && (gTlv_type == TLV_TYPE_PATCH ) +- && remain_size )? FALSE:TRUE; ++ if ((rome_ver >= ROME_VER_1_1) && (rome_ver < ROME_VER_3_2) && (gTlv_type == TLV_TYPE_PATCH)) { ++ /* If the Rome version is from 1.1 to 3.1 ++ * 1. No CCE for the last command segment but all other segment ++ * 2. All the command segments get VSE including the last one ++ */ ++ wait_cc_evt = remain_size ? FALSE: TRUE; ++ } else if ((rome_ver == ROME_VER_3_2) && (gTlv_type == TLV_TYPE_PATCH)) { ++ /* If the Rome version is 3.2 ++ * 1. None of the command segments receive CCE ++ * 2. No command segments receive VSE except the last one ++ * 3. If gtlv_dwndcfg is ROME_SKIP_EVT_NONE then the logic is ++ * same as Rome 2.1, 2.2, 3.0 ++ */ ++ if (gtlv_dwndcfg == ROME_SKIP_EVT_NONE) { ++ wait_cc_evt = remain_size ? FALSE: TRUE; ++ } else if (gtlv_dwndcfg == ROME_SKIP_EVT_VSE_CC) { ++ wait_vsc_evt = remain_size ? TRUE: FALSE; ++ } ++ } + + if(remain_size) err =rome_tlv_dnld_segment(fd, i, remain_size, wait_cc_evt); + +@@ -1619,6 +1689,10 @@ int qca_soc_init(int fd, char *bdaddr) + rampatch_file_path = ROME_RAMPATCH_TLV_3_0_0_PATH; + nvm_file_path = ROME_NVM_TLV_3_0_0_PATH; + goto download; ++ case ROME_VER_3_2: ++ rampatch_file_path = ROME_RAMPATCH_TLV_3_0_2_PATH; ++ nvm_file_path = ROME_NVM_TLV_3_0_2_PATH; ++ goto download; + case TUFELLO_VER_1_0: + rampatch_file_path = TF_RAMPATCH_TLV_1_0_0_PATH; + nvm_file_path = TF_NVM_TLV_1_0_0_PATH; +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +index 9d18c576fcae..77e85e7e7b19 100644 +--- a/tools/hciattach_rome.h ++++ b/tools/hciattach_rome.h +@@ -204,9 +204,17 @@ typedef struct + #define ROME_NVM_TLV_2_0_1_PATH "/lib/firmware/nvm_tlv_2.1.bin" + #define ROME_RAMPATCH_TLV_3_0_0_PATH "/lib/firmware/qca/rampatch_tlv_3.0.tlv" + #define ROME_NVM_TLV_3_0_0_PATH "/lib/firmware/qca/nvm_tlv_3.0.bin" ++#define ROME_RAMPATCH_TLV_3_0_2_PATH "/lib/firmware/qca/rampatch_tlv_3.2.tlv" ++#define ROME_NVM_TLV_3_0_2_PATH "/lib/firmware/qca/nvm_tlv_3.2.bin" + #define TF_RAMPATCH_TLV_1_0_0_PATH "/lib/firmware/rampatch_tlv_tf_1.0.tlv" + #define TF_NVM_TLV_1_0_0_PATH "/lib/firmware/nvm_tlv_tf_1.0.bin" + ++/* This header value in rampatch file decides event handling mechanism in the HOST */ ++#define ROME_SKIP_EVT_NONE 0x00 ++#define ROME_SKIP_EVT_VSE 0x01 ++#define ROME_SKIP_EVT_CC 0x02 ++#define ROME_SKIP_EVT_VSE_CC 0x03 ++ + /****************************************************************************** + ** Local type definitions + ******************************************************************************/ +@@ -251,7 +259,8 @@ typedef struct { + unsigned int tlv_patch_data_len; + unsigned char sign_ver; + unsigned char sign_algorithm; +- unsigned short reserved1; ++ unsigned char dwnd_cfg; ++ unsigned char reserved1; + unsigned short prod_id; + unsigned short build_ver; + unsigned short patch_ver; +@@ -306,7 +315,8 @@ enum{ + ROME_PATCH_VER_0100 = 0x0100, + ROME_PATCH_VER_0101 = 0x0101, + ROME_PATCH_VER_0200 = 0x0200, +- ROME_PATCH_VER_0300 = 0x0300 ++ ROME_PATCH_VER_0300 = 0x0300, ++ ROME_PATCH_VER_0302 = 0x0302 + }; + + enum{ +@@ -314,6 +324,7 @@ enum{ + ROME_SOC_ID_11 = 0x00000011, + ROME_SOC_ID_13 = 0x00000013, + ROME_SOC_ID_22 = 0x00000022, ++ ROME_SOC_ID_44 = 0x00000044 + }; + + enum{ +@@ -323,6 +334,7 @@ enum{ + ROME_VER_1_3 = ((ROME_PATCH_VER_0200 << 16 ) | ROME_SOC_ID_00 ), + ROME_VER_2_1 = ((ROME_PATCH_VER_0200 << 16 ) | ROME_SOC_ID_11 ), + ROME_VER_3_0 = ((ROME_PATCH_VER_0300 << 16 ) | ROME_SOC_ID_22 ), ++ ROME_VER_3_2 = ((ROME_PATCH_VER_0302 << 16 ) | ROME_SOC_ID_44 ), + TUFELLO_VER_1_0 = ((ROME_PATCH_VER_0300 << 16 ) | ROME_SOC_ID_13 ) + }; + #endif /* HW_ROME_H */ + +From f7cc3b22522cfc66a7c4126630c6222f22be17f6 Mon Sep 17 00:00:00 2001 +From: Anantha Krishnan +Date: Thu, 4 Dec 2014 17:23:58 +0530 +Subject: [PATCH 10/19] bluetooth: Use correct TTY ioctl calls for flow control + operations + +BT firmware download application is using incorrect APIs for +performing flow off and flow on operations. As a result, the local +UART Controller is detecting breaks errors on the UART HW lines. + +Appliaction should use TIOCMGET and TIOCMSET ioctl()'s for flow +control operations instead of the tcsetattr() call. Also, the +application should set the value of "number of bits per character" +value to 8 and not as 5. + +Due to incorrect APIs used for flow control operation and wrong +value configured for CSIZE parameter, the local UART Controller +detected break errors on the UART HW lines. This caused the +firmware download operation to fail and resulted in BT ON failure. + +Change-Id: Id0ac1276609eceb528163860cc87267aaa50fede +--- + tools/hciattach_rome.c | 67 +++++++++++++++++++++++++++++++++----------------- + tools/hciattach_rome.h | 6 +++-- + 2 files changed, 49 insertions(+), 24 deletions(-) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index c6d528f118e1..1e689273b851 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -1,6 +1,6 @@ + /* + * +- * Copyright (c) 2013, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * Not a Contribution. + * + * Copyright 2012 The Android Open Source Project +@@ -31,6 +31,7 @@ + + #define LOG_TAG "bt_vendor" + #include ++#include + #include + #include + #include +@@ -139,6 +140,16 @@ void userial_vendor_set_baud(unsigned char userial_baud) + unsigned int tcio_baud; + fprintf(stderr, "## userial_vendor_set_baud: %d\n", userial_baud); + ++ if (tcgetattr(vnd_userial.fd, &vnd_userial.termios) < 0) { ++ perror("Can't get port settings"); ++ return; ++ } ++ cfmakeraw(&vnd_userial.termios); ++ vnd_userial.termios.c_cflag |= CLOCAL; ++ vnd_userial.termios.c_cflag |= CREAD; ++ vnd_userial.termios.c_cflag |= CS8; ++ tcsetattr(vnd_userial.fd, TCSANOW, &vnd_userial.termios); ++ + userial_to_tcio_baud(userial_baud, &tcio_baud); + + cfsetospeed(&vnd_userial.termios, tcio_baud); +@@ -169,6 +180,7 @@ int userial_vendor_ioctl(int fd, userial_vendor_ioctl_op_t op, int *p_data) + cfmakeraw(&ti); + ti.c_cflag |= CLOCAL; + ti.c_cflag |= CREAD; ++ ti.c_cflag |= CS8; + + switch(op) + { +@@ -1445,6 +1457,29 @@ error: + + } + ++static void flow_control(int fd, int opt) ++{ ++ struct termios c_opt; ++ ++ ioctl(fd, TIOCMGET, &c_opt); ++ c_opt.c_cc[VTIME] = 0; /* inter-character timer unused */ ++ c_opt.c_cc[VMIN] = 0; /* blocking read until 8 chars received */ ++ c_opt.c_cflag &= ~CSIZE; ++ c_opt.c_cflag |= (CS8 | CLOCAL | CREAD); ++ if (MSM_ENABLE_FLOW_CTRL) ++ c_opt.c_cflag |= CRTSCTS; ++ else if (MSM_DISABLE_FLOW_CTRL) ++ c_opt.c_cflag |= ~CRTSCTS; ++ else { ++ fprintf(stderr, "%s: Incorrect option passed for TIOCMSET\n", __func__); ++ return; ++ } ++ c_opt.c_iflag = IGNPAR; ++ c_opt.c_oflag = 0; ++ c_opt.c_lflag = 0; ++ ioctl(fd, TIOCMSET, &c_opt); ++} ++ + + int rome_set_baudrate_req(int fd) + { +@@ -1464,12 +1499,10 @@ int rome_set_baudrate_req(int fd) + + /* Total length of the packet to be sent to the Controller */ + size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + VSC_SET_BAUDRATE_REQ_LEN); ++ + /* Flow off during baudrate change */ +- if ((err = userial_vendor_ioctl(fd, USERIAL_OP_FLOW_OFF , &flags)) < 0) +- { +- fprintf(stderr, "%s: HW Flow-off error: 0x%x\n", __FUNCTION__, err); +- goto error; +- } ++ flow_control(fd, MSM_DISABLE_FLOW_CTRL); ++ + /* Send the HCI command packet to UART for transmission */ + fprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3],cmd[4]) ; + err = write(fd, cmd, size); +@@ -1481,11 +1514,8 @@ int rome_set_baudrate_req(int fd) + userial_vendor_set_baud(USERIAL_BAUD_3M); + + /* Flow on after changing local uart baudrate */ +- if ((err = userial_vendor_ioctl(fd, USERIAL_OP_FLOW_ON , &flags)) < 0) +- { +- fprintf(stderr, "%s: HW Flow-on error: 0x%x \n", __FUNCTION__, err); +- return err; +- } ++ flow_control(fd, MSM_ENABLE_FLOW_CTRL); ++ + /* Check for response from the Controller */ + if ((err =read_vs_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE)) < 0) { + fprintf(stderr, "%s: Failed to get HCI-VS Event from SOC\n", __FUNCTION__); +@@ -1528,11 +1558,8 @@ int rome_hci_reset_req(int fd) + size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE); + + /* Flow off during baudrate change */ +- if ((err = userial_vendor_ioctl(fd, USERIAL_OP_FLOW_OFF , &flags)) < 0) +- { +- fprintf(stderr, "%s: HW Flow-off error: 0x%x\n", __FUNCTION__, err); +- goto error; +- } ++ flow_control(fd, MSM_DISABLE_FLOW_CTRL); ++ + /* Send the HCI command packet to UART for transmission */ + fprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3]); + err = write(fd, cmd, size); +@@ -1545,11 +1572,8 @@ int rome_hci_reset_req(int fd) + userial_vendor_set_baud(USERIAL_BAUD_3M); + + /* Flow on after changing local uart baudrate */ +- if ((err = userial_vendor_ioctl(fd, USERIAL_OP_FLOW_ON , &flags)) < 0) +- { +- fprintf(stderr, "%s: HW Flow-on error: 0x%x \n", __FUNCTION__, err); +- return err; +- } ++ flow_control(fd, MSM_ENABLE_FLOW_CTRL); ++ + /* Wait for command complete event */ + err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); + if ( err < 0) { +@@ -1616,7 +1640,6 @@ int qca_soc_init(int fd, char *bdaddr) + int err = -1; + int size; + +- fprintf(stderr, " %s \n", __FUNCTION__); + vnd_userial.fd = fd; + /* Get Rome version information */ + if((err = rome_patch_ver_req(fd)) <0){ +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +index 77e85e7e7b19..ef3647e6a69b 100644 +--- a/tools/hciattach_rome.h ++++ b/tools/hciattach_rome.h +@@ -1,7 +1,7 @@ + /* +- * Copyright 2012 The Android Open Source Project +- * Copyright (c) 2013, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * Not a Contribution. ++ * Copyright 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. +@@ -40,6 +40,8 @@ + #define NVITEM_SIZE 2 + #define PERSIST_HEADER_LEN 3 + #define BD_ADDR_LEN 6 ++#define MSM_ENABLE_FLOW_CTRL 16 ++#define MSM_DISABLE_FLOW_CTRL 17 + + unsigned char vnd_local_bd_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + typedef enum { + +From bd7d1fce8de4639445563442a8448468d671fad2 Mon Sep 17 00:00:00 2001 +From: Anantha Krishnan +Date: Tue, 20 Jan 2015 12:43:20 +0530 +Subject: [PATCH 11/19] bluetooth: Add support for multi baud rate + +Currently BT operates only at 3M baud rate. Provide option +to configure the pre-defined baud rate values as supported by the +target platform. + +Change-Id: I4bbaf7db01ffb983c38dca7c4a4a56f579c678a8 +--- + tools/hciattach.c | 2 +- + tools/hciattach.h | 2 +- + tools/hciattach_rome.c | 109 ++++++++++++++++++++++++++++++++++++++++++------- + tools/hciattach_rome.h | 23 +++++++++++ + 4 files changed, 119 insertions(+), 17 deletions(-) + +diff --git a/tools/hciattach.c b/tools/hciattach.c +index c3cf10843303..dda639cabca3 100644 +--- a/tools/hciattach.c ++++ b/tools/hciattach.c +@@ -286,7 +286,7 @@ static int ath3k_pm(int fd, struct uart_t *u, struct termios *ti) + static int qca(int fd, struct uart_t *u, struct termios *ti) + { + fprintf(stderr,"qca\n"); +- return qca_soc_init(fd, u->bdaddr); ++ return qca_soc_init(fd, u->speed, u->bdaddr); + } + + static int qualcomm(int fd, struct uart_t *u, struct termios *ti) +diff --git a/tools/hciattach.h b/tools/hciattach.h +index 0656a845223c..49e59321fcac 100644 +--- a/tools/hciattach.h ++++ b/tools/hciattach.h +@@ -64,7 +64,7 @@ int ath3k_init(int fd, int speed, int init_speed, char *bdaddr, + struct termios *ti); + int ath3k_post(int fd, int pm); + int qualcomm_init(int fd, int speed, struct termios *ti, const char *bdaddr); +-int qca_soc_init(int fd, char *bdaddr); ++int qca_soc_init(int fd, int speed, char *bdaddr); + int intel_init(int fd, int init_speed, int *speed, struct termios *ti); + int bcm43xx_init(int fd, int def_speed, int speed, struct termios *ti, + const char *bdaddr); +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index 1e689273b851..37974290ae0a 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -1481,7 +1481,7 @@ static void flow_control(int fd, int opt) + } + + +-int rome_set_baudrate_req(int fd) ++int rome_set_baudrate_req(int fd, int local_baud_rate, int controller_baud_rate) + { + int size, err = 0; + unsigned char cmd[HCI_MAX_CMD_SIZE]; +@@ -1495,7 +1495,7 @@ int rome_set_baudrate_req(int fd) + cmd[0] = HCI_COMMAND_PKT; + cmd_hdr->opcode = cmd_opcode_pack(HCI_VENDOR_CMD_OGF, EDL_SET_BAUDRATE_CMD_OCF); + cmd_hdr->plen = VSC_SET_BAUDRATE_REQ_LEN; +- cmd[4] = BAUDRATE_3000000; ++ cmd[4] = controller_baud_rate; + + /* Total length of the packet to be sent to the Controller */ + size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + VSC_SET_BAUDRATE_REQ_LEN); +@@ -1511,7 +1511,7 @@ int rome_set_baudrate_req(int fd) + goto error; + } + /* Change Local UART baudrate to high speed UART */ +- userial_vendor_set_baud(USERIAL_BAUD_3M); ++ userial_vendor_set_baud(local_baud_rate); + + /* Flow on after changing local uart baudrate */ + flow_control(fd, MSM_ENABLE_FLOW_CTRL); +@@ -1537,7 +1537,7 @@ error: + } + + +-int rome_hci_reset_req(int fd) ++int rome_hci_reset_req(int fd, char baud) + { + int size, err = 0; + unsigned char cmd[HCI_MAX_CMD_SIZE]; +@@ -1569,7 +1569,7 @@ int rome_hci_reset_req(int fd) + } + + /* Change Local UART baudrate to high speed UART */ +- userial_vendor_set_baud(USERIAL_BAUD_3M); ++ userial_vendor_set_baud(baud); + + /* Flow on after changing local uart baudrate */ + flow_control(fd, MSM_ENABLE_FLOW_CTRL); +@@ -1635,10 +1635,69 @@ int read_bd_address(unsigned char *bdaddr) + return 0; + } + +-int qca_soc_init(int fd, char *bdaddr) ++int isSpeedValid(int speed, int *local_baud_rate, int *controller_baud_rate) ++{ ++ switch(speed) { ++ case 9600: ++ *local_baud_rate = USERIAL_BAUD_9600; ++ *controller_baud_rate = BAUDRATE_9600; ++ break; ++ case 19200: ++ *local_baud_rate = USERIAL_BAUD_19200; ++ *controller_baud_rate = BAUDRATE_19200; ++ break; ++ case 57600: ++ *local_baud_rate = USERIAL_BAUD_57600; ++ *controller_baud_rate = BAUDRATE_57600; ++ break; ++ case 115200: ++ *local_baud_rate = USERIAL_BAUD_115200; ++ *controller_baud_rate = BAUDRATE_115200; ++ break; ++ case 230400: ++ *local_baud_rate = USERIAL_BAUD_230400; ++ *controller_baud_rate = BAUDRATE_230400; ++ break; ++ case 460800: ++ *local_baud_rate = USERIAL_BAUD_460800; ++ *controller_baud_rate = BAUDRATE_460800; ++ break; ++ case 921600: ++ *local_baud_rate = USERIAL_BAUD_921600; ++ *controller_baud_rate = BAUDRATE_921600; ++ break; ++ case 1000000: ++ *local_baud_rate = USERIAL_BAUD_1M; ++ *controller_baud_rate = BAUDRATE_1000000; ++ break; ++ case 2000000: ++ *local_baud_rate = USERIAL_BAUD_2M; ++ *controller_baud_rate = BAUDRATE_2000000; ++ break; ++ case 3000000: ++ *local_baud_rate = USERIAL_BAUD_3M; ++ *controller_baud_rate = BAUDRATE_3000000; ++ break; ++ case 4000000: ++ *local_baud_rate = USERIAL_BAUD_4M; ++ *controller_baud_rate = BAUDRATE_4000000; ++ break; ++ case 300: ++ case 600: ++ case 1200: ++ case 2400: ++ default: ++ fprintf(stderr, "Invalid baud rate passed!\n"); ++ *local_baud_rate = *controller_baud_rate = -1; ++ break; ++ } ++ return -1; ++} ++ ++int qca_soc_init(int fd, int speed, char *bdaddr) + { + int err = -1; +- int size; ++ int size, local_baud_rate = 0, controller_baud_rate = 0; + + vnd_userial.fd = fd; + /* Get Rome version information */ +@@ -1687,7 +1746,7 @@ int qca_soc_init(int fd, char *bdaddr) + } + + /* Change baud rate 115.2 kbps to 3Mbps*/ +- err = rome_hci_reset_req(fd); ++ err = rome_hci_reset_req(fd, local_baud_rate); + if ( err <0 ) { + fprintf(stderr, "HCI Reset Failed !!\n"); + goto error; +@@ -1721,13 +1780,23 @@ int qca_soc_init(int fd, char *bdaddr) + nvm_file_path = TF_NVM_TLV_1_0_0_PATH; + + download: +- /* Change baud rate 115.2 kbps to 3Mbps*/ +- err = rome_set_baudrate_req(fd); +- if (err < 0) { +- fprintf(stderr, "%s: Baud rate change failed!\n", __FUNCTION__); +- goto error; ++ /* Check if user requested for 115200 kbps */ ++ if (speed == 115200) { ++ local_baud_rate = USERIAL_BAUD_115200; ++ controller_baud_rate = BAUDRATE_115200; + } +- fprintf(stderr, "%s: Baud rate changed successfully \n", __FUNCTION__); ++ else { ++ /* Change only if baud rate requested is valid or not */ ++ isSpeedValid(speed, &local_baud_rate, &controller_baud_rate); ++ if (local_baud_rate < 0 || controller_baud_rate < 0) ++ goto error; ++ ++ err = rome_set_baudrate_req(fd, local_baud_rate, controller_baud_rate); ++ if (err < 0) { ++ fprintf(stderr, "%s: Baud rate change failed!\n", __FUNCTION__); ++ goto error; ++ } ++ } + + /* Donwload TLV files (rampatch, NVM) */ + err = rome_download_tlv_file(fd); +@@ -1737,8 +1806,18 @@ download: + } + fprintf(stderr, "%s: Download TLV file successfully \n", __FUNCTION__); + ++ /* ++ * Overriding the baud rate value in NVM file with the user ++ * requested baud rate, since default baud rate in NVM file is 3M. ++ */ ++ err = rome_set_baudrate_req(fd, local_baud_rate, controller_baud_rate); ++ if (err < 0) { ++ fprintf(stderr, "%s: Baud rate change failed!\n", __FUNCTION__); ++ goto error; ++ } ++ + /* Perform HCI reset here*/ +- err = rome_hci_reset_req(fd); ++ err = rome_hci_reset_req(fd, local_baud_rate); + if ( err <0 ) { + fprintf(stderr, "HCI Reset Failed !!!\n"); + goto error; +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +index ef3647e6a69b..1500ddd3a79f 100644 +--- a/tools/hciattach_rome.h ++++ b/tools/hciattach_rome.h +@@ -78,6 +78,29 @@ typedef struct + #define USERIAL_BAUD_4M 15 + #define USERIAL_BAUD_AUTO 16 + ++/* Vendor specific baud rate values */ ++#define UART_Baud_Rate_Baud_9600 4 ++#define UART_Baud_Rate_Baud_19200 3 ++#define UART_Baud_Rate_Baud_57600 1 ++#define UART_Baud_Rate_Baud_115200 0 ++#define UART_Baud_Rate_Baud_230400 5 ++#define UART_Baud_Rate_Baud_460800 7 ++#define UART_Baud_Rate_Baud_921600 10 ++#define UART_Baud_Rate_Baud_1000000 11 ++#define UART_Baud_Rate_Baud_2000000 13 ++#define UART_Baud_Rate_Baud_3000000 14 ++#define UART_Baud_Rate_Baud_4000000 15 ++ ++#define UART_Baud_Rate_Baud_250000 6 ++#define UART_Baud_Rate_Baud_500000 8 ++#define UART_Baud_Rate_Baud_720000 9 ++#define UART_Baud_Rate_Baud_125000 12 ++#define UART_Baud_Rate_Baud_1600000 16 ++#define UART_Baud_Rate_Baud_3200000 17 ++#define UART_Baud_Rate_Baud_3500000 18 ++ ++ ++ + #ifndef FALSE + #define FALSE 0 + #endif + +From 7dc9c5e316aa9a22899259ce296136b2e257735d Mon Sep 17 00:00:00 2001 +From: Kamal Negi +Date: Tue, 30 Dec 2014 19:15:08 +0530 +Subject: [PATCH 12/19] Override PCM Settings by reading configuration file + +Configure the PCM role as master or slave depending upon +the platform's support. This configuration is provided +in the config file which is read during the firmware +download process and the default PCM configuration is +overwritten with this value. + +Change-Id: If0eae58b4cd32d75b3bcb669bc73dca67652473c +Signed-off-by: Kamal Negi +--- + tools/hciattach_rome.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++--- + tools/hciattach_rome.h | 8 ++++++ + 2 files changed, 71 insertions(+), 4 deletions(-) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index 37974290ae0a..99866e23e99e 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -1,6 +1,6 @@ + /* + * +- * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * Not a Contribution. + * + * Copyright 2012 The Android Open Source Project +@@ -873,6 +873,44 @@ error: + return err; + } + ++int get_value_from_config(char *file_path,char *param) ++{ ++ FILE *pfile = NULL; ++ char *line = NULL; ++ char *pch = NULL; ++ char param_str[20]; ++ int bytes_read = 0, position; ++ int ret = -1; ++ ++ if (!file_path || !param) { ++ fprintf(stderr,"Invalid arguments\n"); ++ return -EINVAL; ++ } ++ ++ pfile = fopen(file_path, "r" ); ++ if (!pfile) { ++ fprintf(stderr, "Failed to open %s\n", file_path); ++ return ret; ++ } ++ ++ while (getline(&line, &bytes_read, pfile) > 0 ) { ++ if (line[0] != '#' && line[0] != '\n') { ++ pch = memchr(line, '=', strlen(line)); ++ if (pch != NULL) { ++ position = pch - line; ++ strncpy(param_str, line, position); ++ if (strncmp(param_str, param, position) == 0) { ++ ret = atoi(pch + 1); ++ break; ++ } ++ } ++ } ++ } ++ free(line); ++ fclose(pfile); ++ return ret; ++} ++ + int rome_get_tlv_file(char *file_path) + { + FILE * pFile; +@@ -884,7 +922,7 @@ int rome_get_tlv_file(char *file_path) + unsigned char data_buf[PRINT_BUF_SIZE]={0,}; + unsigned char *nvm_byte_ptr; + unsigned char bdaddr[6]; +- ++ unsigned short pcm_value; + fprintf(stderr, "File Open (%s)\n", file_path); + pFile = fopen ( file_path , "r" ); + if (pFile==NULL) {; +@@ -970,9 +1008,30 @@ int rome_get_tlv_file(char *file_path) + *nvm_byte_ptr, *(nvm_byte_ptr+1), *(nvm_byte_ptr+2), + *(nvm_byte_ptr+3), *(nvm_byte_ptr+4), *(nvm_byte_ptr+5)); + } ++ /* Read from file and check what PCM Configuration is required: ++ * Master = 0 /Slave = 1 */ ++ /* Override PCM configuration */ ++ if (nvm_ptr->tag_id == TAG_NUM_44) { ++ if ((pcm_value = ++ get_value_from_config(PCM_CONFIG_FILE_PATH, "PCM")) >= 0) { ++ ++ if (pcm_value == PCM_SLAVE) { ++ nvm_byte_ptr[PCM_MS_OFFSET_1] |= ++ (1 << PCM_ROLE_BIT_OFFSET); ++ nvm_byte_ptr[PCM_MS_OFFSET_2] |= ++ (1 << PCM_ROLE_BIT_OFFSET); ++ } else if (pcm_value == PCM_MASTER) { ++ nvm_byte_ptr[PCM_MS_OFFSET_1] &= ++ (~(1 << PCM_ROLE_BIT_OFFSET)); ++ nvm_byte_ptr[PCM_MS_OFFSET_2] &= ++ (~(1 << PCM_ROLE_BIT_OFFSET)); ++ } ++ } ++ } + +- for(i =0;(itag_len && (i*3 + 2) tag_len && (i*3 + 2) < PRINT_BUF_SIZE);i++) ++ snprintf((char *) data_buf, PRINT_BUF_SIZE, "%s%.02x ", ++ (char *)data_buf, *(nvm_byte_ptr + i)); + + fprintf(stderr, "TAG Data\t\t\t : %s\n", data_buf); + +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +index 1500ddd3a79f..f591c10e4f2b 100644 +--- a/tools/hciattach_rome.h ++++ b/tools/hciattach_rome.h +@@ -202,8 +202,15 @@ typedef struct + #define NVM_ACCESS_SET 0x01 + #define TAG_NUM_OFFSET 5 + #define TAG_NUM_2 2 ++#define TAG_NUM_44 44 + #define TAG_BDADDR_OFFSET 7 + ++#define PCM_MS_OFFSET_1 9 ++#define PCM_MS_OFFSET_2 33 ++ ++#define PCM_SLAVE 1 ++#define PCM_MASTER 0 ++#define PCM_ROLE_BIT_OFFSET 4 + #define MAX_RETRY_CNT 1 + #define SELECT_TIMEOUT 3 + +@@ -240,6 +247,7 @@ typedef struct + #define ROME_SKIP_EVT_CC 0x02 + #define ROME_SKIP_EVT_VSE_CC 0x03 + ++#define PCM_CONFIG_FILE_PATH "/etc/bluetooth/pcm.conf" + /****************************************************************************** + ** Local type definitions + ******************************************************************************/ + +From 9eb8220969598d63be3b918b49b6258387629bf3 Mon Sep 17 00:00:00 2001 +From: Rupesh Tatiya +Date: Thu, 29 Jan 2015 15:36:27 +0530 +Subject: [PATCH 13/19] Add support for Tufello 1.1 SOC + +Enable mechanism to download firmware for Tufello 1.1 SOC. +Also, use correct firmware file path for Tufello 1.0. + +Change-Id: I915e48023e45de9e2550336a3de9a07f2b788189 +Signed-off-by: Rupesh Tatiya +--- + tools/hciattach_rome.c | 29 ++++++++++++++++++----------- + tools/hciattach_rome.h | 10 +++++++--- + 2 files changed, 25 insertions(+), 14 deletions(-) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index 99866e23e99e..fee36f904e04 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -621,7 +621,7 @@ int rome_edl_set_patch_request(int fd) + -1, PATCH_HDR_LEN + 1); + + /* Total length of the packet to be sent to the Controller */ +- size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); + + /* Send HCI Command packet to Controller */ + err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size); +@@ -670,7 +670,7 @@ int rome_edl_patch_download_request(int fd) + index, MAX_DATA_PER_SEGMENT); + + /* Total length of the packet to be sent to the Controller */ +- size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); + + /* Initialize the RSP packet everytime to 0 */ + memset(rsp, 0x0, HCI_MAX_EVENT_SIZE); +@@ -707,7 +707,7 @@ int rome_edl_patch_download_request(int fd) + memset(rsp, 0x0, HCI_MAX_EVENT_SIZE); + + /* Total length of the packet to be sent to the Controller */ +- size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); + + /* Send HCI Command packet to Controller */ + err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size); +@@ -824,7 +824,7 @@ int rome_attach_rampatch(int fd) + -1, EDL_PATCH_CMD_LEN); + + /* Total length of the packet to be sent to the Controller */ +- size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + cmd[PLEN]); + + /* Send HCI Command packet to Controller */ + err = hci_send_vs_cmd(fd, (unsigned char *)cmd, rsp, size); +@@ -854,7 +854,7 @@ int rome_rampatch_reset(int fd) + -1, EDL_PATCH_CMD_LEN); + + /* Total length of the packet to be sent to the Controller */ +- size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + EDL_PATCH_CMD_LEN); ++ size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + EDL_PATCH_CMD_LEN); + + /* Send HCI Command packet to Controller */ + err = write(fd, cmd, size); +@@ -1058,7 +1058,7 @@ int rome_tlv_dnld_segment(int fd, int index, int seg_size, unsigned char wait_cc + unsigned char cmd[HCI_MAX_CMD_SIZE]; + unsigned char rsp[HCI_MAX_EVENT_SIZE]; + +- fprintf(stderr, "%s: Downloading TLV Patch segment no.%d, size:%d\n", __FUNCTION__, index, seg_size); ++ fprintf(stderr, "%s: Downloading TLV Patch segment no.%d, size:%d wait_cc_evt = 0x%x\n", __FUNCTION__, index, seg_size, wait_cc_evt); + + /* Frame the HCI CMD PKT to be sent to Controller*/ + frame_hci_cmd_pkt(cmd, EDL_PATCH_TLV_REQ_CMD, 0, index, seg_size); +@@ -1092,6 +1092,7 @@ int rome_tlv_dnld_req(int fd, int tlv_size) + { + int total_segment, remain_size, i, err = -1; + unsigned char wait_cc_evt; ++ unsigned int rom = rome_ver >> 16; + + total_segment = tlv_size/MAX_SIZE_PER_TLV_SEGMENT; + remain_size = (tlv_size < MAX_SIZE_PER_TLV_SEGMENT)?\ +@@ -1132,14 +1133,15 @@ int rome_tlv_dnld_req(int fd, int tlv_size) + + for(i = 0; i < total_segment; i++) { + if((i+1) == total_segment) { +- if ((rome_ver >= ROME_VER_1_1) && (rome_ver < ROME_VER_3_2) && ++ if ((rom >= ROME_PATCH_VER_0100) && (rom < ROME_PATCH_VER_0302) && + (gTlv_type == TLV_TYPE_PATCH)) { + /* If the Rome version is from 1.1 to 3.1 + * 1. No CCE for the last command segment but all other segment + * 2. All the command segments get VSE including the last one + */ + wait_cc_evt = !remain_size ? FALSE: TRUE; +- } else if ((rome_ver == ROME_VER_3_2) && (gTlv_type == TLV_TYPE_PATCH)) { ++ } else if ((rom == ROME_PATCH_VER_0302) && ++ (gTlv_type == TLV_TYPE_PATCH)) { + /* If the Rome version is 3.2 + * 1. None of the command segments receive CCE + * 2. No command segments receive VSE except the last one +@@ -1158,13 +1160,14 @@ int rome_tlv_dnld_req(int fd, int tlv_size) + goto error; + } + +- if ((rome_ver >= ROME_VER_1_1) && (rome_ver < ROME_VER_3_2) && (gTlv_type == TLV_TYPE_PATCH)) { ++ if ((rom >= ROME_PATCH_VER_0100) && (rom < ROME_PATCH_VER_0302) && ++ (gTlv_type == TLV_TYPE_PATCH)) { + /* If the Rome version is from 1.1 to 3.1 + * 1. No CCE for the last command segment but all other segment + * 2. All the command segments get VSE including the last one + */ + wait_cc_evt = remain_size ? FALSE: TRUE; +- } else if ((rome_ver == ROME_VER_3_2) && (gTlv_type == TLV_TYPE_PATCH)) { ++ } else if ((rom == ROME_PATCH_VER_0302) && (gTlv_type == TLV_TYPE_PATCH)) { + /* If the Rome version is 3.2 + * 1. None of the command segments receive CCE + * 2. No command segments receive VSE except the last one +@@ -1837,6 +1840,10 @@ int qca_soc_init(int fd, int speed, char *bdaddr) + case TUFELLO_VER_1_0: + rampatch_file_path = TF_RAMPATCH_TLV_1_0_0_PATH; + nvm_file_path = TF_NVM_TLV_1_0_0_PATH; ++ goto download; ++ case TUFELLO_VER_1_1: ++ rampatch_file_path = TF_RAMPATCH_TLV_1_0_1_PATH; ++ nvm_file_path = TF_NVM_TLV_1_0_1_PATH; + + download: + /* Check if user requested for 115200 kbps */ +@@ -1881,7 +1888,7 @@ download: + fprintf(stderr, "HCI Reset Failed !!!\n"); + goto error; + } +- fprintf(stderr, "HCI Reset is done\n"); ++ fprintf(stderr, "HCI Reset is done\n"); + + break; + case ROME_VER_UNKNOWN: +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +index f591c10e4f2b..95d5f1e8a5c2 100644 +--- a/tools/hciattach_rome.h ++++ b/tools/hciattach_rome.h +@@ -238,8 +238,10 @@ typedef struct + #define ROME_NVM_TLV_3_0_0_PATH "/lib/firmware/qca/nvm_tlv_3.0.bin" + #define ROME_RAMPATCH_TLV_3_0_2_PATH "/lib/firmware/qca/rampatch_tlv_3.2.tlv" + #define ROME_NVM_TLV_3_0_2_PATH "/lib/firmware/qca/nvm_tlv_3.2.bin" +-#define TF_RAMPATCH_TLV_1_0_0_PATH "/lib/firmware/rampatch_tlv_tf_1.0.tlv" +-#define TF_NVM_TLV_1_0_0_PATH "/lib/firmware/nvm_tlv_tf_1.0.bin" ++#define TF_RAMPATCH_TLV_1_0_0_PATH "/lib/firmware/qca/rampatch_tlv_tf_1.0.tlv" ++#define TF_NVM_TLV_1_0_0_PATH "/lib/firmware/qca/nvm_tlv_tf_1.0.bin" ++#define TF_RAMPATCH_TLV_1_0_1_PATH "/lib/firmware/qca/rampatch_tlv_tf_1.1.tlv" ++#define TF_NVM_TLV_1_0_1_PATH "/lib/firmware/qca/nvm_tlv_tf_1.1.bin" + + /* This header value in rampatch file decides event handling mechanism in the HOST */ + #define ROME_SKIP_EVT_NONE 0x00 +@@ -357,6 +359,7 @@ enum{ + ROME_SOC_ID_11 = 0x00000011, + ROME_SOC_ID_13 = 0x00000013, + ROME_SOC_ID_22 = 0x00000022, ++ ROME_SOC_ID_23 = 0x00000023, + ROME_SOC_ID_44 = 0x00000044 + }; + +@@ -368,6 +371,7 @@ enum{ + ROME_VER_2_1 = ((ROME_PATCH_VER_0200 << 16 ) | ROME_SOC_ID_11 ), + ROME_VER_3_0 = ((ROME_PATCH_VER_0300 << 16 ) | ROME_SOC_ID_22 ), + ROME_VER_3_2 = ((ROME_PATCH_VER_0302 << 16 ) | ROME_SOC_ID_44 ), +- TUFELLO_VER_1_0 = ((ROME_PATCH_VER_0300 << 16 ) | ROME_SOC_ID_13 ) ++ TUFELLO_VER_1_0 = ((ROME_PATCH_VER_0300 << 16 ) | ROME_SOC_ID_13 ), ++ TUFELLO_VER_1_1 = ((ROME_PATCH_VER_0302 << 16 ) | ROME_SOC_ID_23 ) + }; + #endif /* HW_ROME_H */ + +From f55d710cf43d008e42ce06ead49dc0dfbf97d3a1 Mon Sep 17 00:00:00 2001 +From: Anantha Krishnan +Date: Wed, 4 Feb 2015 12:29:07 +0530 +Subject: [PATCH 14/19] bluetooth: Vote UART CLK ON prior to firmware download + process + +Before starting the firmware download process, vote UART CLK ON +to avoid triggering the dynamic suspend of UART driver. Post +firmware download and in error scenarios vote UART CLK OFF. + +As per design, the UART driver enters into dynamic suspend if +there are no activity on the UART lines for 100ms. Depending upon +the rampatch size, the BT Controller takes time to apply the +downloaded rampatch segments and in sending the vendor specific +event. If the BT Controller takes > 100ms time in sending the +vendor specific event, the UART driver enters into suspend state. + +As a result, UART driver fails to process the last vendor specific +event sent by the BT Controller. The VSE sent by BT Controller +wakes up the UART driver, but the data is not processed causing +firmware download failures. + +Hence, vote UART CLK ON prior to firmware download process and +vote UART CLK OFF post firmware download proess and in error +scenarios. + +Change-Id: I447ded33ad1cfaa020b491effce368fbfe41f894 +--- + tools/hciattach_rome.c | 13 +++++++++++++ + tools/hciattach_rome.h | 2 ++ + 2 files changed, 15 insertions(+) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index fee36f904e04..574ceac6c750 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -1762,6 +1762,14 @@ int qca_soc_init(int fd, int speed, char *bdaddr) + int size, local_baud_rate = 0, controller_baud_rate = 0; + + vnd_userial.fd = fd; ++ ++ /* Vote for UART CLK prior to FW download */ ++ err = ioctl(fd, USERIAL_OP_CLK_ON); ++ if (err < 0) { ++ fprintf(stderr, "%s: Failed to vote UART CLK ON\n", __func__); ++ return -1; ++ } ++ + /* Get Rome version information */ + if((err = rome_patch_ver_req(fd)) <0){ + fprintf(stderr, "%s: Fail to get Rome Version (0x%x)\n", __FUNCTION__, err); +@@ -1899,5 +1907,10 @@ download: + } + + error: ++ /* Vote UART CLK OFF post to FW download */ ++ err = ioctl(fd, USERIAL_OP_CLK_OFF); ++ if (err < 0) ++ fprintf(stderr, "%s: Failed to vote UART CLK OFF!!!\n", __func__); ++ + return err; + } +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +index 95d5f1e8a5c2..20264f9978d9 100644 +--- a/tools/hciattach_rome.h ++++ b/tools/hciattach_rome.h +@@ -42,6 +42,8 @@ + #define BD_ADDR_LEN 6 + #define MSM_ENABLE_FLOW_CTRL 16 + #define MSM_DISABLE_FLOW_CTRL 17 ++#define USERIAL_OP_CLK_ON 0x5441 ++#define USERIAL_OP_CLK_OFF 0x5442 + + unsigned char vnd_local_bd_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + typedef enum { + +From b09f8b12c937ec58df0581b2d95493e036c86432 Mon Sep 17 00:00:00 2001 +From: Kamal Negi +Date: Thu, 30 Apr 2015 15:53:06 +0530 +Subject: [PATCH 15/19] Override IBS settings by reading configuration file + +Configure the IBS value in Firmware by reading the +configuration file.This configuration value is +provided in the config file which is read during +the firmware download process and the default +configuration value is overwritten with this value. + +Change-Id: I47992a573b3137ac9bfb80538727981f56b328c4 +Signed-off-by: Kamal Negi +--- + tools/hciattach_rome.c | 42 +++++++++++++++++++++++++++++------------- + tools/hciattach_rome.h | 24 ++++++++++++++++-------- + 2 files changed, 45 insertions(+), 21 deletions(-) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index 574ceac6c750..6a3f33867c12 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -922,7 +922,8 @@ int rome_get_tlv_file(char *file_path) + unsigned char data_buf[PRINT_BUF_SIZE]={0,}; + unsigned char *nvm_byte_ptr; + unsigned char bdaddr[6]; +- unsigned short pcm_value; ++ unsigned short pcm_value, ibs_value; ++ + fprintf(stderr, "File Open (%s)\n", file_path); + pFile = fopen ( file_path , "r" ); + if (pFile==NULL) {; +@@ -1008,23 +1009,38 @@ int rome_get_tlv_file(char *file_path) + *nvm_byte_ptr, *(nvm_byte_ptr+1), *(nvm_byte_ptr+2), + *(nvm_byte_ptr+3), *(nvm_byte_ptr+4), *(nvm_byte_ptr+5)); + } ++ ++ if (nvm_ptr->tag_id == TAG_NUM_17) { ++ if ((ibs_value = ++ get_value_from_config(FW_CONFIG_FILE_PATH, "IBS")) >= 0) { ++ if (ibs_value == FWCONF_IBS_DISABLE) { ++ nvm_byte_ptr[FWCONF_IBS_VAL_OFFSET] &= ++ (~(FWCONF_IBS_ENABLE << ++ FWCONF_IBS_VAL_BIT)); ++ } else if (ibs_value == FWCONF_IBS_ENABLE) { ++ nvm_byte_ptr[FWCONF_IBS_VAL_OFFSET] |= ++ (FWCONF_IBS_ENABLE << ++ FWCONF_IBS_VAL_BIT); ++ } ++ } ++ } + /* Read from file and check what PCM Configuration is required: + * Master = 0 /Slave = 1 */ + /* Override PCM configuration */ + if (nvm_ptr->tag_id == TAG_NUM_44) { + if ((pcm_value = +- get_value_from_config(PCM_CONFIG_FILE_PATH, "PCM")) >= 0) { +- +- if (pcm_value == PCM_SLAVE) { +- nvm_byte_ptr[PCM_MS_OFFSET_1] |= +- (1 << PCM_ROLE_BIT_OFFSET); +- nvm_byte_ptr[PCM_MS_OFFSET_2] |= +- (1 << PCM_ROLE_BIT_OFFSET); +- } else if (pcm_value == PCM_MASTER) { +- nvm_byte_ptr[PCM_MS_OFFSET_1] &= +- (~(1 << PCM_ROLE_BIT_OFFSET)); +- nvm_byte_ptr[PCM_MS_OFFSET_2] &= +- (~(1 << PCM_ROLE_BIT_OFFSET)); ++ get_value_from_config(FW_CONFIG_FILE_PATH, "PCM")) >= 0) { ++ ++ if (pcm_value == FWCONF_PCM_SLAVE) { ++ nvm_byte_ptr[FWCONF_PCM_MS_OFFSET_1] |= ++ (1 << FWCONF_PCM_ROLE_BIT_OFFSET); ++ nvm_byte_ptr[FWCONF_PCM_MS_OFFSET_2] |= ++ (1 << FWCONF_PCM_ROLE_BIT_OFFSET); ++ } else if (pcm_value == FWCONF_PCM_MASTER) { ++ nvm_byte_ptr[FWCONF_PCM_MS_OFFSET_1] &= ++ (~(1 << FWCONF_PCM_ROLE_BIT_OFFSET)); ++ nvm_byte_ptr[FWCONF_PCM_MS_OFFSET_2] &= ++ (~(1 << FWCONF_PCM_ROLE_BIT_OFFSET)); + } + } + } +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +index 20264f9978d9..8eaeeed8bc96 100644 +--- a/tools/hciattach_rome.h ++++ b/tools/hciattach_rome.h +@@ -203,16 +203,24 @@ typedef struct + #define TAG_END 0xFF + #define NVM_ACCESS_SET 0x01 + #define TAG_NUM_OFFSET 5 +-#define TAG_NUM_2 2 +-#define TAG_NUM_44 44 ++#define TAG_NUM_2 2 ++#define TAG_NUM_17 (17) ++#define TAG_NUM_44 44 + #define TAG_BDADDR_OFFSET 7 + +-#define PCM_MS_OFFSET_1 9 +-#define PCM_MS_OFFSET_2 33 ++/* FW PCM Configuration */ ++#define FWCONF_PCM_MS_OFFSET_1 9 ++#define FWCONF_PCM_MS_OFFSET_2 33 ++#define FWCONF_PCM_SLAVE 1 ++#define FWCONF_PCM_MASTER 0 ++#define FWCONF_PCM_ROLE_BIT_OFFSET 4 ++ ++/* FW IBS Configuration */ ++#define FWCONF_IBS_DISABLE (0) ++#define FWCONF_IBS_ENABLE (1) ++#define FWCONF_IBS_VAL_BIT (7) ++#define FWCONF_IBS_VAL_OFFSET (0) + +-#define PCM_SLAVE 1 +-#define PCM_MASTER 0 +-#define PCM_ROLE_BIT_OFFSET 4 + #define MAX_RETRY_CNT 1 + #define SELECT_TIMEOUT 3 + +@@ -251,7 +259,7 @@ typedef struct + #define ROME_SKIP_EVT_CC 0x02 + #define ROME_SKIP_EVT_VSE_CC 0x03 + +-#define PCM_CONFIG_FILE_PATH "/etc/bluetooth/pcm.conf" ++#define FW_CONFIG_FILE_PATH "/etc/bluetooth/firmware.conf" + /****************************************************************************** + ** Local type definitions + ******************************************************************************/ + +From b307659dc988054c1fef32c131417cfab2b74c3e Mon Sep 17 00:00:00 2001 +From: Dibyendu Roy +Date: Fri, 22 May 2015 18:57:05 +0530 +Subject: [PATCH 16/19] bluetooth: Fix flow control operation + +Flow off operation was not actually happening at the UART line level, +since the argument passed was not being used correctly. As a result, +sometimes command complete and VS event were sent by BT SOC even +before the local UART Controller could change its baud rate to the +newer one(3 Mbps). This led to VS event being processed +incorrectly which in turn causes baud rate change to fail. + +CRs-Fixed: 844730 +Change-Id: I06d8c4ed7807aa47dd5498642c7a23c9189a1cff +Signed-off-by: Dibyendu Roy +--- + tools/hciattach_rome.c | 6 +++--- + tools/hciattach_rome.h | 4 ++-- + 2 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index 6a3f33867c12..0d7014f1d2f6 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -1544,10 +1544,10 @@ static void flow_control(int fd, int opt) + c_opt.c_cc[VMIN] = 0; /* blocking read until 8 chars received */ + c_opt.c_cflag &= ~CSIZE; + c_opt.c_cflag |= (CS8 | CLOCAL | CREAD); +- if (MSM_ENABLE_FLOW_CTRL) ++ if (opt == MSM_ENABLE_FLOW_CTRL) + c_opt.c_cflag |= CRTSCTS; +- else if (MSM_DISABLE_FLOW_CTRL) +- c_opt.c_cflag |= ~CRTSCTS; ++ else if (opt == MSM_DISABLE_FLOW_CTRL) ++ c_opt.c_cflag &= ~CRTSCTS; + else { + fprintf(stderr, "%s: Incorrect option passed for TIOCMSET\n", __func__); + return; +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +index 8eaeeed8bc96..3fdaf208e522 100644 +--- a/tools/hciattach_rome.h ++++ b/tools/hciattach_rome.h +@@ -40,8 +40,8 @@ + #define NVITEM_SIZE 2 + #define PERSIST_HEADER_LEN 3 + #define BD_ADDR_LEN 6 +-#define MSM_ENABLE_FLOW_CTRL 16 +-#define MSM_DISABLE_FLOW_CTRL 17 ++#define MSM_DISABLE_FLOW_CTRL 0 ++#define MSM_ENABLE_FLOW_CTRL 1 + #define USERIAL_OP_CLK_ON 0x5441 + #define USERIAL_OP_CLK_OFF 0x5442 + + +From bec6be1174e250c60b48b51933ab6f80a27a093e Mon Sep 17 00:00:00 2001 +From: Dibyendu Roy +Date: Thu, 11 Jun 2015 12:07:43 +0530 +Subject: [PATCH 17/19] Adding MDM specific code under _PLATFORM_MDM_ + +This patch is added to comment out the commit +84cc0e12983b5761c67789ef93fd6fb164c7314d in x86 as +dynamic suspend feature is not available in x86. However, +this code shall be active for MDM platform due to +dynamic suspend feature. + +Change-Id: I998f0521b4a5f9744412db40f2c2d3bff2ac3d11 +--- + tools/hciattach_rome.c | 5 ++++- + tools/hciattach_rome.h | 3 +++ + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index 0d7014f1d2f6..1891de24e21a 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -1779,13 +1779,14 @@ int qca_soc_init(int fd, int speed, char *bdaddr) + + vnd_userial.fd = fd; + ++#ifdef _PLATFORM_MDM_ + /* Vote for UART CLK prior to FW download */ + err = ioctl(fd, USERIAL_OP_CLK_ON); + if (err < 0) { + fprintf(stderr, "%s: Failed to vote UART CLK ON\n", __func__); + return -1; + } +- ++#endif + /* Get Rome version information */ + if((err = rome_patch_ver_req(fd)) <0){ + fprintf(stderr, "%s: Fail to get Rome Version (0x%x)\n", __FUNCTION__, err); +@@ -1923,10 +1924,12 @@ download: + } + + error: ++#ifdef _PLATFORM_MDM_ + /* Vote UART CLK OFF post to FW download */ + err = ioctl(fd, USERIAL_OP_CLK_OFF); + if (err < 0) + fprintf(stderr, "%s: Failed to vote UART CLK OFF!!!\n", __func__); ++#endif + + return err; + } +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +index 3fdaf208e522..89f7db3bef86 100644 +--- a/tools/hciattach_rome.h ++++ b/tools/hciattach_rome.h +@@ -42,8 +42,11 @@ + #define BD_ADDR_LEN 6 + #define MSM_DISABLE_FLOW_CTRL 0 + #define MSM_ENABLE_FLOW_CTRL 1 ++ ++#ifdef _PLATFORM_MDM_ + #define USERIAL_OP_CLK_ON 0x5441 + #define USERIAL_OP_CLK_OFF 0x5442 ++#endif + + unsigned char vnd_local_bd_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + typedef enum { + +From 5ab2a193c11eaa8a68a0e060a560a5bd2ee2459c Mon Sep 17 00:00:00 2001 +From: Dibyendu Roy +Date: Mon, 6 Jul 2015 13:30:53 +0530 +Subject: [PATCH 18/19] Bluetooth: Fix static analysis issues + +Change-Id: Ida91f012544c39a8aaa6e7db23f1d5b68d3bec08 +--- + tools/hciattach_rome.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index 1891de24e21a..59bdc16e4e8f 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -933,7 +933,13 @@ int rome_get_tlv_file(char *file_path) + + /* Get File Size */ + fseek (pFile , 0 , SEEK_END); +- fileSize = ftell (pFile); ++ ++ if((fileSize = ftell(pFile)) < 0) { ++ fprintf(stderr, "%s: fail to get current file position\n", file_path); ++ fclose (pFile); ++ return -1; ++ } ++ + rewind (pFile); + + pdata_buffer = (unsigned char*) malloc (sizeof(char)*fileSize); +@@ -1107,7 +1113,7 @@ int rome_tlv_dnld_segment(int fd, int index, int seg_size, unsigned char wait_cc + int rome_tlv_dnld_req(int fd, int tlv_size) + { + int total_segment, remain_size, i, err = -1; +- unsigned char wait_cc_evt; ++ unsigned char wait_cc_evt = FALSE; + unsigned int rom = rome_ver >> 16; + + total_segment = tlv_size/MAX_SIZE_PER_TLV_SEGMENT; + +From ca52faad6e23bee353e3315f136efb43d1e9d143 Mon Sep 17 00:00:00 2001 +From: Kamal Negi +Date: Fri, 8 May 2015 15:01:02 +0530 +Subject: [PATCH 19/19] Handle NULL Pointer derefrencing in AVRCP Target role + +Check NULL pointer to AVRCP controller role initialized or not. +If remote device don't support the AVRCP target role, then HOST dont +initialize AVRCP controller role and directly dereference the controller +role and segfault happens. + +Change-Id: Ibbb9452f17a576c3a79a53ea72e0211982752144 +Signed-off-by: Kamal Negi +--- + profiles/audio/avrcp.c | 27 ++++++++++++++++++++++----- + 1 file changed, 22 insertions(+), 5 deletions(-) + +diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c +index c100149acf42..d8cb0ed96a1f 100644 +--- a/profiles/audio/avrcp.c ++++ b/profiles/audio/avrcp.c +@@ -2082,13 +2082,19 @@ static gboolean avrcp_get_play_status_rsp(struct avctp *conn, uint8_t code, + void *user_data) + { + struct avrcp *session = user_data; +- struct avrcp_player *player = session->controller->player; +- struct media_player *mp = player->user_data; ++ struct avrcp_player *player; ++ struct media_player *mp; + struct avrcp_header *pdu = (void *) operands; + uint32_t duration; + uint32_t position; + uint8_t status; + ++ if (!session || !session->controller) ++ return FALSE; ++ ++ player = session->controller->player; ++ mp = player->user_data; ++ + if (pdu == NULL || code == AVC_CTYPE_REJECTED || + ntohs(pdu->params_len) != 9) + return FALSE; +@@ -2146,12 +2152,18 @@ static gboolean avrcp_player_value_rsp(struct avctp *conn, uint8_t code, + void *user_data) + { + struct avrcp *session = user_data; +- struct avrcp_player *player = session->controller->player; +- struct media_player *mp = player->user_data; ++ struct avrcp_player *player; ++ struct media_player *mp; + struct avrcp_header *pdu = (void *) operands; + uint8_t count; + int i; + ++ if (!session || !session->controller) ++ return FALSE; ++ ++ player = session->controller->player; ++ mp = player->user_data; ++ + if (pdu == NULL) { + media_player_set_setting(mp, "Error", "Timeout"); + return FALSE; +@@ -2303,10 +2315,15 @@ static gboolean avrcp_get_element_attributes_rsp(struct avctp *conn, + void *user_data) + { + struct avrcp *session = user_data; +- struct avrcp_player *player = session->controller->player; ++ struct avrcp_player *player; + struct avrcp_header *pdu = (void *) operands; + uint8_t count; + ++ if (!session || !session->controller) ++ return FALSE; ++ ++ player = session->controller->player; ++ + if (code == AVC_CTYPE_REJECTED) + return FALSE; + diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0013-hciattach_rome-Respect-the-user-indication-for-noflo.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0013-hciattach_rome-Respect-the-user-indication-for-noflo.patch new file mode 100644 index 000000000..e5d76303a --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0013-hciattach_rome-Respect-the-user-indication-for-noflo.patch @@ -0,0 +1,186 @@ +From: Alex Gonzalez +Date: Thu, 6 Apr 2017 09:27:09 +0200 +Subject: [PATCH] hciattach_rome: Respect the user indication for noflow + +When hciattach is called with noflow, it should not assume the hardware +supports hardware flow control. + +Basically, use 'flow' or 'noflow' on the hciattach command line arguments +to indicate whether to use or not hardware flow control. + +Signed-off-by: Alex Gonzalez +--- + tools/hciattach.c | 2 +- + tools/hciattach.h | 2 +- + tools/hciattach_rome.c | 50 +++++++++++++++++++++++++++++++++++--------------- + tools/hciattach_rome.h | 1 + + 4 files changed, 38 insertions(+), 17 deletions(-) + +diff --git a/tools/hciattach.c b/tools/hciattach.c +index dda639cabca3..81d78ab3f69a 100644 +--- a/tools/hciattach.c ++++ b/tools/hciattach.c +@@ -286,7 +286,7 @@ static int ath3k_pm(int fd, struct uart_t *u, struct termios *ti) + static int qca(int fd, struct uart_t *u, struct termios *ti) + { + fprintf(stderr,"qca\n"); +- return qca_soc_init(fd, u->speed, u->bdaddr); ++ return qca_soc_init(fd, u->speed, u->bdaddr, ti); + } + + static int qualcomm(int fd, struct uart_t *u, struct termios *ti) +diff --git a/tools/hciattach.h b/tools/hciattach.h +index 49e59321fcac..3524e716c847 100644 +--- a/tools/hciattach.h ++++ b/tools/hciattach.h +@@ -64,7 +64,7 @@ int ath3k_init(int fd, int speed, int init_speed, char *bdaddr, + struct termios *ti); + int ath3k_post(int fd, int pm); + int qualcomm_init(int fd, int speed, struct termios *ti, const char *bdaddr); +-int qca_soc_init(int fd, int speed, char *bdaddr); ++int qca_soc_init(int fd, int speed, char *bdaddr , struct termios * ti); + int intel_init(int fd, int init_speed, int *speed, struct termios *ti); + int bcm43xx_init(int fd, int def_speed, int speed, struct termios *ti, + const char *bdaddr); +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index 59bdc16e4e8f..ee67bb068c09 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -1565,7 +1565,8 @@ static void flow_control(int fd, int opt) + } + + +-int rome_set_baudrate_req(int fd, int local_baud_rate, int controller_baud_rate) ++int rome_set_baudrate_req(int fd, int local_baud_rate, ++ int controller_baud_rate, int hwfc) + { + int size, err = 0; + unsigned char cmd[HCI_MAX_CMD_SIZE]; +@@ -1575,6 +1576,12 @@ int rome_set_baudrate_req(int fd, int local_baud_rate, int controller_baud_rate) + + memset(cmd, 0x0, HCI_MAX_CMD_SIZE); + ++ /* If not using hardware flow control limit baud rate to 115200 */ ++ if (!hwfc) { ++ local_baud_rate = USERIAL_BAUD_115200; ++ controller_baud_rate = BAUDRATE_115200; ++ } ++ + cmd_hdr = (void *) (cmd + 1); + cmd[0] = HCI_COMMAND_PKT; + cmd_hdr->opcode = cmd_opcode_pack(HCI_VENDOR_CMD_OGF, EDL_SET_BAUDRATE_CMD_OCF); +@@ -1621,7 +1628,7 @@ error: + } + + +-int rome_hci_reset_req(int fd, char baud) ++int rome_hci_reset_req(int fd, char baud, int hwfc) + { + int size, err = 0; + unsigned char cmd[HCI_MAX_CMD_SIZE]; +@@ -1641,8 +1648,9 @@ int rome_hci_reset_req(int fd, char baud) + /* Total length of the packet to be sent to the Controller */ + size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE); + +- /* Flow off during baudrate change */ +- flow_control(fd, MSM_DISABLE_FLOW_CTRL); ++ /* If using hardware flow control, turn off during baudrate change */ ++ if (hwfc) ++ flow_control(fd, MSM_DISABLE_FLOW_CTRL); + + /* Send the HCI command packet to UART for transmission */ + fprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3]); +@@ -1655,8 +1663,9 @@ int rome_hci_reset_req(int fd, char baud) + /* Change Local UART baudrate to high speed UART */ + userial_vendor_set_baud(baud); + +- /* Flow on after changing local uart baudrate */ +- flow_control(fd, MSM_ENABLE_FLOW_CTRL); ++ /* If using hardware flow control, turn on after changing local uart baudrate */ ++ if (hwfc) ++ flow_control(fd, MSM_ENABLE_FLOW_CTRL); + + /* Wait for command complete event */ + err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); +@@ -1778,7 +1787,7 @@ int isSpeedValid(int speed, int *local_baud_rate, int *controller_baud_rate) + return -1; + } + +-int qca_soc_init(int fd, int speed, char *bdaddr) ++int qca_soc_init(int fd, int speed, char *bdaddr , struct termios * ti) + { + int err = -1; + int size, local_baud_rate = 0, controller_baud_rate = 0; +@@ -1793,6 +1802,12 @@ int qca_soc_init(int fd, int speed, char *bdaddr) + return -1; + } + #endif ++ ++ /* Assume we don't use hardware flow control unless user requested 'flow' */ ++ vnd_userial.hwfc = 0; ++ if (ti->c_cflag & ~CRTSCTS) ++ vnd_userial.hwfc = 1; ++ + /* Get Rome version information */ + if((err = rome_patch_ver_req(fd)) <0){ + fprintf(stderr, "%s: Fail to get Rome Version (0x%x)\n", __FUNCTION__, err); +@@ -1838,11 +1853,14 @@ int qca_soc_init(int fd, int speed, char *bdaddr) + goto error; + } + +- /* Change baud rate 115.2 kbps to 3Mbps*/ +- err = rome_hci_reset_req(fd, local_baud_rate); +- if ( err <0 ) { +- fprintf(stderr, "HCI Reset Failed !!\n"); +- goto error; ++ /* If using hw flow control, change baud rate 115.2 kbps to 3Mbps*/ ++ if (vnd_userial.hwfc) { ++ err = rome_hci_reset_req(fd, local_baud_rate, ++ vnd_userial.hwfc); ++ if ( err <0 ) { ++ fprintf(stderr, "HCI Reset Failed !!\n"); ++ goto error; ++ } + } + + fprintf(stderr, "HCI Reset is done\n"); +@@ -1888,7 +1906,8 @@ download: + if (local_baud_rate < 0 || controller_baud_rate < 0) + goto error; + +- err = rome_set_baudrate_req(fd, local_baud_rate, controller_baud_rate); ++ err = rome_set_baudrate_req(fd, local_baud_rate, ++ controller_baud_rate, vnd_userial.hwfc); + if (err < 0) { + fprintf(stderr, "%s: Baud rate change failed!\n", __FUNCTION__); + goto error; +@@ -1907,14 +1926,15 @@ download: + * Overriding the baud rate value in NVM file with the user + * requested baud rate, since default baud rate in NVM file is 3M. + */ +- err = rome_set_baudrate_req(fd, local_baud_rate, controller_baud_rate); ++ err = rome_set_baudrate_req(fd, local_baud_rate, ++ controller_baud_rate, vnd_userial.hwfc); + if (err < 0) { + fprintf(stderr, "%s: Baud rate change failed!\n", __FUNCTION__); + goto error; + } + + /* Perform HCI reset here*/ +- err = rome_hci_reset_req(fd, local_baud_rate); ++ err = rome_hci_reset_req(fd, local_baud_rate, vnd_userial.hwfc); + if ( err <0 ) { + fprintf(stderr, "HCI Reset Failed !!!\n"); + goto error; +diff --git a/tools/hciattach_rome.h b/tools/hciattach_rome.h +index 89f7db3bef86..760685ad7915 100644 +--- a/tools/hciattach_rome.h ++++ b/tools/hciattach_rome.h +@@ -62,6 +62,7 @@ typedef struct + int fd; /* fd to Bluetooth device */ + struct termios termios; /* serial terminal of BT port */ + char port_name[256]; ++ int hwfc; + } vnd_userial_cb_t; + + /**** baud rates ****/ diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0014-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0014-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch new file mode 100644 index 000000000..208f587a2 --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0014-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch @@ -0,0 +1,177 @@ +From: Alex Gonzalez +Date: Thu, 6 Apr 2017 14:37:57 +0200 +Subject: [PATCH] hciattach: If the user supplies a bdaddr, use it + +The QCA6564 has no non-volatile configuration file for the bluetooth +MAC, so use the one supplied on the command line. + +Signed-off-by: Alex Gonzalez +--- + tools/hciattach.c | 4 +-- + tools/hciattach_rome.c | 76 ++++++++++---------------------------------------- + 2 files changed, 17 insertions(+), 63 deletions(-) + +diff --git a/tools/hciattach.c b/tools/hciattach.c +index 81d78ab3f69a..022bbe5fa6d5 100644 +--- a/tools/hciattach.c ++++ b/tools/hciattach.c +@@ -285,7 +285,7 @@ static int ath3k_pm(int fd, struct uart_t *u, struct termios *ti) + + static int qca(int fd, struct uart_t *u, struct termios *ti) + { +- fprintf(stderr,"qca\n"); ++ fprintf(stderr,"qca, bdaddr %s\n", u->bdaddr ? u->bdaddr : "Default"); + return qca_soc_init(fd, u->speed, u->bdaddr, ti); + } + +@@ -1363,7 +1363,7 @@ int main(int argc, char *argv[]) + fprintf(stderr, "Unknown device type or id\n"); + exit(1); + } +- ++ u->bdaddr = NULL; + break; + + case 2: +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index ee67bb068c09..854cfff707aa 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -45,6 +45,7 @@ + #include + #include + #include ++#include + #include + #include "hciattach_rome.h" + #include "hciattach.h" +@@ -911,7 +912,7 @@ int get_value_from_config(char *file_path,char *param) + return ret; + } + +-int rome_get_tlv_file(char *file_path) ++int rome_get_tlv_file(char *file_path, unsigned char * bdaddr) + { + FILE * pFile; + long fileSize; +@@ -921,7 +922,6 @@ int rome_get_tlv_file(char *file_path) + tlv_nvm_hdr *nvm_ptr; + unsigned char data_buf[PRINT_BUF_SIZE]={0,}; + unsigned char *nvm_byte_ptr; +- unsigned char bdaddr[6]; + unsigned short pcm_value, ibs_value; + + fprintf(stderr, "File Open (%s)\n", file_path); +@@ -1008,12 +1008,15 @@ int rome_get_tlv_file(char *file_path) + nvm_byte_ptr+=sizeof(tlv_nvm_hdr); + + /* Write BD Address */ +- if(nvm_ptr->tag_id == TAG_NUM_2 && read_bd_address(&bdaddr) == 0) { +- memcpy(nvm_byte_ptr, bdaddr, 6); +- fprintf(stderr, "Overriding default BD ADDR with user" +- " programmed BD Address: %02x:%02x:%02x:%02x:%02x:%02x\n", +- *nvm_byte_ptr, *(nvm_byte_ptr+1), *(nvm_byte_ptr+2), +- *(nvm_byte_ptr+3), *(nvm_byte_ptr+4), *(nvm_byte_ptr+5)); ++ if(nvm_ptr->tag_id == TAG_NUM_2 && bdaddr) { ++ bdaddr_t ba; ++ if (!str2ba(bdaddr, &ba)) { ++ memcpy(nvm_byte_ptr, &ba, 6); ++ fprintf(stderr, "Overriding default BD ADDR with user" ++ " programmed BD Address: %02x:%02x:%02x:%02x:%02x:%02x\n", ++ *(nvm_byte_ptr+5), *(nvm_byte_ptr+4), *(nvm_byte_ptr+3), ++ *(nvm_byte_ptr+2), *(nvm_byte_ptr+1), *nvm_byte_ptr); ++ } + } + + if (nvm_ptr->tag_id == TAG_NUM_17) { +@@ -1209,14 +1212,14 @@ error: + return err; + } + +-int rome_download_tlv_file(int fd) ++int rome_download_tlv_file(int fd, char * bdaddr) + { + int tlv_size, err = -1; + + /* Rampatch TLV file Downloading */ + pdata_buffer = NULL; + +- if((tlv_size = rome_get_tlv_file(rampatch_file_path)) < 0) ++ if((tlv_size = rome_get_tlv_file(rampatch_file_path, bdaddr)) < 0) + goto error; + + if((err =rome_tlv_dnld_req(fd, tlv_size)) <0 ) +@@ -1228,7 +1231,7 @@ int rome_download_tlv_file(int fd) + } + + /* NVM TLV file Downloading */ +- if((tlv_size = rome_get_tlv_file(nvm_file_path)) < 0) ++ if((tlv_size = rome_get_tlv_file(nvm_file_path, bdaddr)) < 0) + goto error; + + if((err =rome_tlv_dnld_req(fd, tlv_size)) <0 ) +@@ -1679,55 +1682,6 @@ error: + + } + +-int read_bd_address(unsigned char *bdaddr) +-{ +- int fd = -1; +- int readPtr = 0; +- unsigned char data[BD_ADDR_LEN]; +- +- /* Open the persist file for reading device address*/ +- fd = open("/etc/bluetooth/.bt_nv.bin", O_RDONLY); +- if(fd < 0) +- { +- fprintf(stderr, "%s: Open failed: Programming default BD ADDR\n", __func__); +- return -1; +- } +- +- /* Read the NVM Header : fp will be advanced by readPtr number of bytes */ +- readPtr = read(fd, data, PERSIST_HEADER_LEN); +- if (readPtr > 0) +- fprintf(stderr, "%s: Persist header data: %02x \t %02x \t %02x\n", __func__, +- data[NVITEM], data[RDWR_PROT], data[NVITEM_SIZE]); +- else { +- fprintf(stderr, "%s: Read from persist memory failed : Programming default" +- " BD ADDR\n"); +- close(fd); +- return -1; +- } +- +- /* Check for BD ADDR length before programming */ +- if(data[NVITEM_SIZE] != BD_ADDR_LEN) { +- fprintf(stderr, "Invalid BD ADDR: Programming default BD ADDR!\n"); +- close(fd); +- return -1; +- } +- +- /* Read the BD ADDR info */ +- readPtr = read(fd, data, BD_ADDR_LEN); +- if (readPtr > 0) +- fprintf(stderr, "BD-ADDR: ==> %02x:%02x:%02x:%02x:%02x:%02x\n", data[0], +- data[1], data[2], data[3], data[4], data[5]); +- else { +- fprintf(stderr, "%s: Read from persist memory failed : Programming default" +- " BD ADDR\n"); +- close(fd); +- return -1; +- } +- memcpy(bdaddr, data, BD_ADDR_LEN); +- close(fd); +- return 0; +-} +- + int isSpeedValid(int speed, int *local_baud_rate, int *controller_baud_rate) + { + switch(speed) { +@@ -1915,7 +1869,7 @@ download: + } + + /* Donwload TLV files (rampatch, NVM) */ +- err = rome_download_tlv_file(fd); ++ err = rome_download_tlv_file(fd, bdaddr); + if (err < 0) { + fprintf(stderr, "%s: Download TLV file failed!\n", __FUNCTION__); + goto error; diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0015-hciattach-Add-verbosity-option.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0015-hciattach-Add-verbosity-option.patch new file mode 100644 index 000000000..d1e540a92 --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/0015-hciattach-Add-verbosity-option.patch @@ -0,0 +1,723 @@ +From: Alex Gonzalez +Date: Mon, 10 Apr 2017 12:44:00 +0200 +Subject: [PATCH] hciattach: Add verbosity option + +And reduce the verbosity of the hciattach_rome plugin. + +Signed-off-by: Alex Gonzalez +--- + lib/bluetooth.h | 3 + + tools/hciattach.c | 13 ++- + tools/hciattach_rome.c | 244 ++++++++++++++++++++++++------------------------- + 3 files changed, 132 insertions(+), 128 deletions(-) + +diff --git a/lib/bluetooth.h b/lib/bluetooth.h +index eb279260e009..38e3e6900744 100644 +--- a/lib/bluetooth.h ++++ b/lib/bluetooth.h +@@ -136,6 +136,9 @@ enum { + BT_CLOSED + }; + ++extern int verbose_on; ++#define hciprintf(fd, arg...) if (verbose_on) { fprintf(fd, ##arg);} else { do {} while (0);} ++ + /* Byte order conversions */ + #if __BYTE_ORDER == __LITTLE_ENDIAN + #define htobs(d) (d) +diff --git a/tools/hciattach.c b/tools/hciattach.c +index 022bbe5fa6d5..4aacdafeda7d 100644 +--- a/tools/hciattach.c ++++ b/tools/hciattach.c +@@ -50,6 +50,8 @@ + + #include "hciattach.h" + ++int verbose_on = 0; ++ + struct uart_t { + char *type; + int m_id; +@@ -125,8 +127,6 @@ int read_hci_event(int fd, unsigned char* buf, int size) + fprintf(stderr, "%s: Timing out on select for 3 secs.\n", __FUNCTION__); + return -1; + } +- else +- fprintf(stderr, "%s: Data(HCI-CMD-COMP-EVENT) available in TTY Serial buffer\n", __FUNCTION__); + + /* The first byte identifies the packet type. For HCI event packets, it + * should be 0x04, so we read until we get to the 0x04. */ +@@ -285,7 +285,7 @@ static int ath3k_pm(int fd, struct uart_t *u, struct termios *ti) + + static int qca(int fd, struct uart_t *u, struct termios *ti) + { +- fprintf(stderr,"qca, bdaddr %s\n", u->bdaddr ? u->bdaddr : "Default"); ++ fprintf(stderr,"qca, bdaddr %s, verbose %d\n", u->bdaddr ? u->bdaddr : "Default", verbose_on); + return qca_soc_init(fd, u->speed, u->bdaddr, ti); + } + +@@ -1258,7 +1258,7 @@ static void usage(void) + { + printf("hciattach - HCI UART driver initialization utility\n"); + printf("Usage:\n"); +- printf("\thciattach [-n] [-p] [-b] [-r] [-t timeout] [-s initial_speed]" ++ printf("\thciattach [-n] [-p] [-b] [-r] [-v] [-t timeout] [-s initial_speed]" + " [speed] [flow|noflow]" + " [sleep|nosleep] [bdaddr]\n"); + printf("\thciattach -l\n"); +@@ -1281,7 +1281,7 @@ int main(int argc, char *argv[]) + printpid = 0; + raw = 0; + +- while ((opt=getopt(argc, argv, "bnpt:s:lrf:")) != EOF) { ++ while ((opt=getopt(argc, argv, "bnpt:s:lrf:v")) != EOF) { + switch(opt) { + case 'b': + send_break = 1; +@@ -1319,6 +1319,9 @@ int main(int argc, char *argv[]) + fprintf(stderr, "Line_disp val : %d\n", line_disp); + break; + ++ case 'v': ++ verbose_on = 1; ++ break; + default: + usage(); + exit(1); +diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c +index 854cfff707aa..40983fc087c0 100644 +--- a/tools/hciattach_rome.c ++++ b/tools/hciattach_rome.c +@@ -139,7 +139,7 @@ unsigned char userial_to_tcio_baud(unsigned char cfg_baud, unsigned int *baud) + void userial_vendor_set_baud(unsigned char userial_baud) + { + unsigned int tcio_baud; +- fprintf(stderr, "## userial_vendor_set_baud: %d\n", userial_baud); ++ hciprintf(stderr, "## userial_vendor_set_baud: %d\n", userial_baud); + + if (tcgetattr(vnd_userial.fd, &vnd_userial.termios) < 0) { + perror("Can't get port settings"); +@@ -201,7 +201,7 @@ int userial_vendor_ioctl(int fd, userial_vendor_ioctl_op_t op, int *p_data) + break; + #endif // (BT_WAKE_VIA_USERIAL_IOCTL==TRUE) + case USERIAL_OP_FLOW_ON: +- fprintf(stderr, "## userial_vendor_ioctl: UART Flow On\n "); ++ hciprintf(stderr, "## userial_vendor_ioctl: UART Flow On\n "); + ti.c_cflag |= CRTSCTS; + + if (err = tcsetattr(fd, TCSANOW, &ti) < 0) { +@@ -212,7 +212,7 @@ int userial_vendor_ioctl(int fd, userial_vendor_ioctl_op_t op, int *p_data) + break; + + case USERIAL_OP_FLOW_OFF: +- fprintf(stderr, "## userial_vendor_ioctl: UART Flow Off\n "); ++ hciprintf(stderr, "## userial_vendor_ioctl: UART Flow Off\n "); + ti.c_cflag &= ~CRTSCTS; + if (err = tcsetattr(fd, TCSANOW, &ti) < 0) { + fprintf(stderr, "Can't set port settings"); +@@ -233,51 +233,51 @@ int get_vs_hci_event(unsigned char *rsp) + int err = 0, soc_id =0; + unsigned char paramlen = 0; + +- if( (rsp[EVENTCODE_OFFSET] == VSEVENT_CODE) || (rsp[EVENTCODE_OFFSET] == EVT_CMD_COMPLETE)) +- fprintf(stderr, "%s: Received HCI-Vendor Specific event\n", __FUNCTION__); +- else { ++ if( (rsp[EVENTCODE_OFFSET] == VSEVENT_CODE) || (rsp[EVENTCODE_OFFSET] == EVT_CMD_COMPLETE)) { ++ hciprintf(stderr, "%s: Received HCI-Vendor Specific event\n", __FUNCTION__); ++ } else { + fprintf(stderr, "%s: Failed to receive HCI-Vendor Specific event\n", __FUNCTION__); + err = -EIO; + goto failed; + } + +- fprintf(stderr, "%s: Parameter Length: 0x%x\n", __FUNCTION__, paramlen = rsp[EVT_PLEN]); +- fprintf(stderr, "%s: Command response: 0x%x\n", __FUNCTION__, rsp[CMD_RSP_OFFSET]); +- fprintf(stderr, "%s: Response type : 0x%x\n", __FUNCTION__, rsp[RSP_TYPE_OFFSET]); ++ paramlen = rsp[EVT_PLEN]; ++ hciprintf(stderr, "%s: Parameter Length: 0x%x\n", __FUNCTION__, paramlen); ++ hciprintf(stderr, "%s: Command response: 0x%x\n", __FUNCTION__, rsp[CMD_RSP_OFFSET]); ++ hciprintf(stderr, "%s: Response type : 0x%x\n", __FUNCTION__, rsp[RSP_TYPE_OFFSET]); + + /* Check the status of the operation */ + switch ( rsp[CMD_RSP_OFFSET] ) + { + case EDL_CMD_REQ_RES_EVT: +- fprintf(stderr, "%s: Command Request Response\n", __FUNCTION__); ++ hciprintf(stderr, "%s: Command Request Response\n", __FUNCTION__); + switch(rsp[RSP_TYPE_OFFSET]) + { + case EDL_PATCH_VER_RES_EVT: + case EDL_APP_VER_RES_EVT: +- fprintf(stderr, "\t Current Product ID\t\t: 0x%08x\n", +- (unsigned int)(rsp[PATCH_PROD_ID_OFFSET +3] << 24 | ++ hciprintf(stderr, "\t Current Product ID\t\t: 0x%08x\n", ++ (unsigned int)(rsp[PATCH_PROD_ID_OFFSET +3] << 24 | + rsp[PATCH_PROD_ID_OFFSET+2] << 16 | + rsp[PATCH_PROD_ID_OFFSET+1] << 8 | + rsp[PATCH_PROD_ID_OFFSET] )); + + /* Patch Version indicates FW patch version */ +- fprintf(stderr, "\t Current Patch Version\t\t: 0x%04x\n", +- (unsigned short)(rsp[PATCH_PATCH_VER_OFFSET + 1] << 8 | ++ hciprintf(stderr, "\t Current Patch Version\t\t: 0x%04x\n", ++ (unsigned short)(rsp[PATCH_PATCH_VER_OFFSET + 1] << 8 | + rsp[PATCH_PATCH_VER_OFFSET] )); + + /* ROM Build Version indicates ROM build version like 1.0/1.1/2.0 */ +- fprintf(stderr, "\t Current ROM Build Version\t: 0x%04x\n", rome_ver = +- (int)(rsp[PATCH_ROM_BUILD_VER_OFFSET + 1] << 8 | +- rsp[PATCH_ROM_BUILD_VER_OFFSET] )); ++ rome_ver = (int)(rsp[PATCH_ROM_BUILD_VER_OFFSET + 1] << 8 | ++ rsp[PATCH_ROM_BUILD_VER_OFFSET] ); ++ hciprintf(stderr, "\t Current ROM Build Version\t: 0x%04x\n", rome_ver); + + /* In case rome 1.0/1.1, there is no SOC ID version available */ +- if (paramlen - 10) +- { +- fprintf(stderr, "\t Current SOC Version\t\t: 0x%08x\n", soc_id = +- (unsigned int)(rsp[PATCH_SOC_VER_OFFSET +3] << 24 | +- rsp[PATCH_SOC_VER_OFFSET+2] << 16 | +- rsp[PATCH_SOC_VER_OFFSET+1] << 8 | +- rsp[PATCH_SOC_VER_OFFSET] )); ++ if (paramlen - 10) { ++ soc_id = (unsigned int)(rsp[PATCH_SOC_VER_OFFSET +3] << 24 | ++ rsp[PATCH_SOC_VER_OFFSET+2] << 16 | ++ rsp[PATCH_SOC_VER_OFFSET+1] << 8 | ++ rsp[PATCH_SOC_VER_OFFSET]); ++ hciprintf(stderr, "\t Current SOC Version\t\t: 0x%08x\n", soc_id); + } + + /* Rome Chipset Version can be decided by Patch version and SOC version, +@@ -290,7 +290,7 @@ int get_vs_hci_event(unsigned char *rsp) + switch (err = rsp[CMD_STATUS_OFFSET]) + { + case HCI_CMD_SUCCESS: +- fprintf(stderr, "%s: Download Packet successfully!\n", __FUNCTION__); ++ hciprintf(stderr, "%s: Download Packet successfully!\n", __FUNCTION__); + break; + case PATCH_LEN_ERROR: + fprintf(stderr, "%s: Invalid patch length argument passed for EDL PATCH " +@@ -318,7 +318,7 @@ int get_vs_hci_event(unsigned char *rsp) + break; + + case NVM_ACCESS_CODE: +- fprintf(stderr, "%s: NVM Access Code!!!\n", __FUNCTION__); ++ hciprintf(stderr, "%s: NVM Access Code!!!\n", __FUNCTION__); + err = HCI_CMD_SUCCESS; + break; + case EDL_SET_BAUDRATE_RSP_EVT: +@@ -362,7 +362,7 @@ int wait_for_data(int fd, int maxTimeOut) + return -1; + } + else +- fprintf(stderr, "%s: HCI-VS-EVENT available in TTY Serial buffer\n", ++ hciprintf(stderr, "%s: HCI-VS-EVENT available in TTY Serial buffer\n", + __FUNCTION__); + + return 1; +@@ -381,7 +381,7 @@ int read_vs_hci_event(int fd, unsigned char* buf, int size) + return -1; + } + +- fprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC\n", ++ hciprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC\n", + __FUNCTION__); + + /* Check whether data is available in TTY buffer before calling read() */ +@@ -425,7 +425,7 @@ int read_vs_hci_event(int fd, unsigned char* buf, int size) + } + count++; + +- fprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC, buf[0] - 0x%x\n", __FUNCTION__, buf[0]); ++ hciprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC, buf[0] - 0x%x\n", __FUNCTION__, buf[0]); + /* The next two bytes are the event code and parameter total length. */ + while (count < 3) { + r = read(fd, buf + count, 3 - count); +@@ -436,7 +436,7 @@ int read_vs_hci_event(int fd, unsigned char* buf, int size) + count += r; + } + +- fprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC, buf[1] - 0x%x\n", __FUNCTION__, buf[1]); ++ hciprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC, buf[1] - 0x%x\n", __FUNCTION__, buf[1]); + /* Now we read the parameters. */ + if (buf[2] < (size - 3)) + remain = buf[2]; +@@ -454,7 +454,7 @@ int read_vs_hci_event(int fd, unsigned char* buf, int size) + if(get_vs_hci_event(buf) != HCI_CMD_SUCCESS) + return -1; + +- fprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC, count - 0x%x\n", __FUNCTION__, count); ++ hciprintf(stderr, "%s: Wait for HCI-Vendor Specfic Event from SOC, count - 0x%x\n", __FUNCTION__, count); + return count; + } + +@@ -477,7 +477,7 @@ int hci_send_vs_cmd(int fd, unsigned char *cmd, unsigned char *rsp, int size) + fprintf(stderr, "%s: Failed to get HCI-VS Event from SOC\n", __FUNCTION__); + goto failed; + } +- fprintf(stderr, "%s: Received HCI-Vendor Specific Event from SOC\n", __FUNCTION__); ++ hciprintf(stderr, "%s: Received HCI-Vendor Specific Event from SOC\n", __FUNCTION__); + } + + failed: +@@ -507,8 +507,8 @@ void frame_hci_cmd_pkt( + case EDL_PATCH_SET_REQ_CMD: + /* Copy the patch header info as CMD params */ + memcpy(&cmd[5], phdr_buffer, PATCH_HDR_LEN); +- fprintf(stderr, "%s: Sending EDL_PATCH_SET_REQ_CMD\n", __FUNCTION__); +- fprintf(stderr, "HCI-CMD %d:\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n", ++ hciprintf(stderr, "%s: Sending EDL_PATCH_SET_REQ_CMD\n", __FUNCTION__); ++ hciprintf(stderr, "HCI-CMD %d:\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n", + segtNo, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]); + break; + case EDL_PATCH_DLD_REQ_CMD: +@@ -522,36 +522,36 @@ void frame_hci_cmd_pkt( + cmd[9] = EXTRACT_BYTE(p_base_addr, 3); + memcpy(&cmd[10], (pdata_buffer + offset), size); + +- fprintf(stderr, "%s: Sending EDL_PATCH_DLD_REQ_CMD: size: %d bytes\n", ++ hciprintf(stderr, "%s: Sending EDL_PATCH_DLD_REQ_CMD: size: %d bytes\n", + __FUNCTION__, size); +- fprintf(stderr, "HCI-CMD %d:\t0x%x\t0x%x\t0x%x\t0x%x\t0x%x\t0x%x\t0x%x\t" ++ hciprintf(stderr, "HCI-CMD %d:\t0x%x\t0x%x\t0x%x\t0x%x\t0x%x\t0x%x\t0x%x\t" + "0x%x\t0x%x\t0x%x\t\n", segtNo, cmd[0], cmd[1], cmd[2], + cmd[3], cmd[4], cmd[5], cmd[6], cmd[7], cmd[8], cmd[9]); + break; + case EDL_PATCH_ATCH_REQ_CMD: +- fprintf(stderr, "%s: Sending EDL_PATCH_ATTACH_REQ_CMD\n", __FUNCTION__); +- fprintf(stderr, "HCI-CMD %d:\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n", +- segtNo, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]); ++ hciprintf(stderr, "%s: Sending EDL_PATCH_ATTACH_REQ_CMD\n", __FUNCTION__); ++ hciprintf(stderr, "HCI-CMD %d:\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n", ++ segtNo, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]); + break; + case EDL_PATCH_RST_REQ_CMD: +- fprintf(stderr, "%s: Sending EDL_PATCH_RESET_REQ_CMD\n", __FUNCTION__); +- fprintf(stderr, "HCI-CMD %d:\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n", +- segtNo, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]); ++ hciprintf(stderr, "%s: Sending EDL_PATCH_RESET_REQ_CMD\n", __FUNCTION__); ++ hciprintf(stderr, "HCI-CMD %d:\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n", ++ segtNo, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]); + break; + case EDL_PATCH_VER_REQ_CMD: +- fprintf(stderr, "%s: Sending EDL_PATCH_VER_REQ_CMD\n", __FUNCTION__); +- fprintf(stderr, "HCI-CMD %d:\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n", +- segtNo, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]); +- break; ++ hciprintf(stderr, "%s: Sending EDL_PATCH_VER_REQ_CMD\n", __FUNCTION__); ++ hciprintf(stderr, "HCI-CMD %d:\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n", ++ segtNo, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]); ++ break; + case EDL_PATCH_TLV_REQ_CMD: +- fprintf(stderr, "%s: Sending EDL_PATCH_TLV_REQ_CMD\n", __FUNCTION__); ++ hciprintf(stderr, "%s: Sending EDL_PATCH_TLV_REQ_CMD\n", __FUNCTION__); + /* Parameter Total Length */ + cmd[3] = size +2; + + /* TLV Segment Length */ + cmd[5] = size; +- fprintf(stderr, "HCI-CMD %d:\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n", +- segtNo, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5]); ++ hciprintf(stderr, "HCI-CMD %d:\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n", ++ segtNo, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5]); + offset = (segtNo * MAX_SIZE_PER_TLV_SEGMENT); + memcpy(&cmd[6], (pdata_buffer + offset), size); + break; +@@ -601,14 +601,13 @@ void rome_extract_patch_header_info(unsigned char *buf) + rampatch_patch_info.patch_ctrl |= + (LSH(buf[index + P_CONTROL_OFFSET], (index * 8))); + +- fprintf(stderr, "PATCH_ID\t : 0x%x\n", rampatch_patch_info.patch_id); +- fprintf(stderr, "ROM_VERSION\t : 0x%x\n", rampatch_patch_info.patch_ver.rom_version); +- fprintf(stderr, "BUILD_VERSION\t : 0x%x\n", rampatch_patch_info.patch_ver.build_version); +- fprintf(stderr, "PATCH_LENGTH\t : 0x%x\n", rampatch_patch_info.patch_length); +- fprintf(stderr, "PATCH_CRC\t : 0x%x\n", rampatch_patch_info.patch_crc); +- fprintf(stderr, "PATCH_CONTROL\t : 0x%x\n", rampatch_patch_info.patch_ctrl); +- fprintf(stderr, "PATCH_BASE_ADDR\t : 0x%x\n", rampatch_patch_info.patch_base_addr); +- ++ hciprintf(stderr, "PATCH_ID\t : 0x%x\n", rampatch_patch_info.patch_id); ++ hciprintf(stderr, "ROM_VERSION\t : 0x%x\n", rampatch_patch_info.patch_ver.rom_version); ++ hciprintf(stderr, "BUILD_VERSION\t : 0x%x\n", rampatch_patch_info.patch_ver.build_version); ++ hciprintf(stderr, "PATCH_LENGTH\t : 0x%x\n", rampatch_patch_info.patch_length); ++ hciprintf(stderr, "PATCH_CRC\t : 0x%x\n", rampatch_patch_info.patch_crc); ++ hciprintf(stderr, "PATCH_CONTROL\t : 0x%x\n", rampatch_patch_info.patch_ctrl); ++ hciprintf(stderr, "PATCH_BASE_ADDR\t : 0x%x\n", rampatch_patch_info.patch_base_addr); + } + + int rome_edl_set_patch_request(int fd) +@@ -636,7 +635,7 @@ int rome_edl_set_patch_request(int fd) + fprintf(stderr, "%s: Failed to set patch info on Controller\n", __FUNCTION__); + goto error; + } +- fprintf(stderr, "%s: Successfully set patch info on the Controller\n", __FUNCTION__); ++ hciprintf(stderr, "%s: Successfully set patch info on the Controller\n", __FUNCTION__); + error: + return err; + } +@@ -651,7 +650,7 @@ int rome_edl_patch_download_request(int fd) + + no_of_patch_segment = (rampatch_patch_info.patch_length / + MAX_DATA_PER_SEGMENT); +- fprintf(stderr, "%s: %d patch segments to be d'loaded from patch base addr: 0x%x\n", ++ hciprintf(stderr, "%s: %d patch segments to be d'loaded from patch base addr: 0x%x\n", + __FUNCTION__, no_of_patch_segment, + rampatch_patch_info.patch_base_addr); + +@@ -663,8 +662,7 @@ int rome_edl_patch_download_request(int fd) + * segments with a max. size of 239 bytes + */ + for (index = 1; index <= no_of_patch_segment; index++) { +- +- fprintf(stderr, "%s: Downloading patch segment: %d\n", __FUNCTION__, index); ++ hciprintf(stderr, "%s: Downloading patch segment: %d\n", __FUNCTION__, index); + + /* Frame the HCI CMD PKT to be sent to Controller*/ + frame_hci_cmd_pkt(cmd, EDL_PATCH_DLD_REQ_CMD, p_base_addr, +@@ -690,8 +688,9 @@ int rome_edl_patch_download_request(int fd) + __FUNCTION__, index); + goto error; + } +- fprintf(stderr, "%s: Successfully downloaded patch segment: %d\n", +- __FUNCTION__, index); ++ ++ hciprintf(stderr, "%s: Successfully downloaded patch segment: %d\n", ++ __FUNCTION__, index); + } + + /* Check if any pending patch data to be sent */ +@@ -725,8 +724,8 @@ int rome_edl_patch_download_request(int fd) + goto error; + } + +- fprintf(stderr, "%s: Successfully downloaded patch segment: %d\n", +- __FUNCTION__, index); ++ hciprintf(stderr, "%s: Successfully downloaded patch segment: %d\n", ++ __FUNCTION__, index); + } + + error: +@@ -740,7 +739,7 @@ static int rome_download_rampatch(int fd) + fprintf(stderr, "%s:\n", __FUNCTION__); + + /* Get handle to the RAMPATCH binary file */ +- fprintf(stderr, "%s: Getting handle to the RAMPATCH binary file from %s\n", __FUNCTION__, ROME_FW_PATH); ++ hciprintf(stderr, "%s: Getting handle to the RAMPATCH binary file from %s\n", __FUNCTION__, ROME_FW_PATH); + file = fopen(ROME_FW_PATH, "r"); + if (file == NULL) { + fprintf(stderr, "%s: Failed to get handle to the RAMPATCH bin file!\n", +@@ -749,7 +748,7 @@ static int rome_download_rampatch(int fd) + } + + /* Allocate memory for the patch headder info */ +- fprintf(stderr, "%s: Allocating memory for the patch header\n", __FUNCTION__); ++ hciprintf(stderr, "%s: Allocating memory for the patch header\n", __FUNCTION__); + phdr_buffer = (unsigned char *) malloc(PATCH_HDR_LEN + 1); + if (phdr_buffer == NULL) { + fprintf(stderr, "%s: Failed to allocate memory for patch header\n", +@@ -760,7 +759,7 @@ static int rome_download_rampatch(int fd) + phdr_buffer[index] = 0x0; + + /* Read 28 bytes of patch header information */ +- fprintf(stderr, "%s: Reading patch header info\n", __FUNCTION__); ++ hciprintf(stderr, "%s: Reading patch header info\n", __FUNCTION__); + index = 0; + do { + c = fgetc (file); +@@ -768,7 +767,7 @@ static int rome_download_rampatch(int fd) + } while (index != PATCH_HDR_LEN); + + /* Save the patch header info into local structure */ +- fprintf(stderr, "%s: Saving patch hdr. info\n", __FUNCTION__); ++ hciprintf(stderr, "%s: Saving patch hdr. info\n", __FUNCTION__); + rome_extract_patch_header_info((unsigned char *)phdr_buffer); + + /* Set the patch header info onto the Controller */ +@@ -779,7 +778,7 @@ static int rome_download_rampatch(int fd) + } + + /* Allocate memory for the patch payload */ +- fprintf(stderr, "%s: Allocating memory for patch payload\n", __FUNCTION__); ++ hciprintf(stderr, "%s: Allocating memory for patch payload\n", __FUNCTION__); + size = rampatch_patch_info.patch_length; + pdata_buffer = (unsigned char *) malloc(size+1); + if (pdata_buffer == NULL) { +@@ -791,7 +790,7 @@ static int rome_download_rampatch(int fd) + pdata_buffer[index] = 0x0; + + /* Read the patch data from Rampatch binary image */ +- fprintf(stderr, "%s: Reading patch payload from RAMPATCH file\n", __FUNCTION__); ++ hciprintf(stderr, "%s: Reading patch payload from RAMPATCH file\n", __FUNCTION__); + index = 0; + do { + c = fgetc (file); +@@ -924,7 +923,7 @@ int rome_get_tlv_file(char *file_path, unsigned char * bdaddr) + unsigned char *nvm_byte_ptr; + unsigned short pcm_value, ibs_value; + +- fprintf(stderr, "File Open (%s)\n", file_path); ++ hciprintf(stderr, "File Open (%s)\n", file_path); + pFile = fopen ( file_path , "r" ); + if (pFile==NULL) {; + fprintf(stderr, "%s File Open Fail\n", file_path); +@@ -967,30 +966,30 @@ int rome_get_tlv_file(char *file_path, unsigned char * bdaddr) + gtlv_dwndcfg = ptlv_header->tlv.patch.dwnd_cfg; + + if(ptlv_header->tlv_type == TLV_TYPE_PATCH){ +- fprintf(stderr, "====================================================\n"); +- fprintf(stderr, "TLV Type\t\t\t : 0x%x\n", ptlv_header->tlv_type); +- fprintf(stderr, "Length\t\t\t : %d bytes\n", (ptlv_header->tlv_length1) | +- (ptlv_header->tlv_length2 << 8) | +- (ptlv_header->tlv_length3 << 16)); +- fprintf(stderr, "Total Length\t\t\t : %d bytes\n", ptlv_header->tlv.patch.tlv_data_len); +- fprintf(stderr, "Patch Data Length\t\t\t : %d bytes\n",ptlv_header->tlv.patch.tlv_patch_data_len); +- fprintf(stderr, "Signing Format Version\t : 0x%x\n", ptlv_header->tlv.patch.sign_ver); +- fprintf(stderr, "Signature Algorithm\t\t : 0x%x\n", ptlv_header->tlv.patch.sign_algorithm); +- fprintf(stderr, "Event Handling\t\t\t : 0x%x", ptlv_header->tlv.patch.dwnd_cfg); +- fprintf(stderr, "Reserved\t\t\t : 0x%x\n", ptlv_header->tlv.patch.reserved1); +- fprintf(stderr, "Product ID\t\t\t : 0x%04x\n", ptlv_header->tlv.patch.prod_id); +- fprintf(stderr, "Rom Build Version\t\t : 0x%04x\n", ptlv_header->tlv.patch.build_ver); +- fprintf(stderr, "Patch Version\t\t : 0x%04x\n", ptlv_header->tlv.patch.patch_ver); +- fprintf(stderr, "Reserved\t\t\t : 0x%x\n", ptlv_header->tlv.patch.reserved2); +- fprintf(stderr, "Patch Entry Address\t\t : 0x%x\n", (ptlv_header->tlv.patch.patch_entry_addr)); +- fprintf(stderr, "====================================================\n"); +- ++ hciprintf(stderr, "====================================================\n"); ++ hciprintf(stderr, "TLV Type\t\t\t : 0x%x\n", ptlv_header->tlv_type); ++ hciprintf(stderr, "Length\t\t\t : %d bytes\n", (ptlv_header->tlv_length1) | ++ (ptlv_header->tlv_length2 << 8) | ++ (ptlv_header->tlv_length3 << 16)); ++ hciprintf(stderr, "Total Length\t\t\t : %d bytes\n", ptlv_header->tlv.patch.tlv_data_len); ++ hciprintf(stderr, "Patch Data Length\t\t\t : %d bytes\n",ptlv_header->tlv.patch.tlv_patch_data_len); ++ hciprintf(stderr, "Signing Format Version\t : 0x%x\n", ptlv_header->tlv.patch.sign_ver); ++ hciprintf(stderr, "Signature Algorithm\t\t : 0x%x\n", ptlv_header->tlv.patch.sign_algorithm); ++ hciprintf(stderr, "Event Handling\t\t\t : 0x%x", ptlv_header->tlv.patch.dwnd_cfg); ++ hciprintf(stderr, "Reserved\t\t\t : 0x%x\n", ptlv_header->tlv.patch.reserved1); ++ hciprintf(stderr, "Product ID\t\t\t : 0x%04x\n", ptlv_header->tlv.patch.prod_id); ++ hciprintf(stderr, "Rom Build Version\t\t : 0x%04x\n", ptlv_header->tlv.patch.build_ver); ++ hciprintf(stderr, "Patch Version\t\t : 0x%04x\n", ptlv_header->tlv.patch.patch_ver); ++ hciprintf(stderr, "Reserved\t\t\t : 0x%x\n", ptlv_header->tlv.patch.reserved2); ++ hciprintf(stderr, "Patch Entry Address\t\t : 0x%x\n", (ptlv_header->tlv.patch.patch_entry_addr)); ++ hciprintf(stderr, "====================================================\n"); + } else if(ptlv_header->tlv_type == TLV_TYPE_NVM) { +- fprintf(stderr, "====================================================\n"); +- fprintf(stderr, "TLV Type\t\t\t : 0x%x\n", ptlv_header->tlv_type); +- fprintf(stderr, "Length\t\t\t : %d bytes\n", nvm_length = (ptlv_header->tlv_length1) | +- (ptlv_header->tlv_length2 << 8) | +- (ptlv_header->tlv_length3 << 16)); ++ nvm_length = (ptlv_header->tlv_length1) | ++ (ptlv_header->tlv_length2 << 8) | ++ (ptlv_header->tlv_length3 << 16); ++ hciprintf(stderr, "====================================================\n"); ++ hciprintf(stderr, "TLV Type\t\t\t : 0x%x\n", ptlv_header->tlv_type); ++ hciprintf(stderr, "Length\t\t\t : %d bytes\n", nvm_length); + + if(nvm_length <= 0) + return readSize; +@@ -998,11 +997,11 @@ int rome_get_tlv_file(char *file_path, unsigned char * bdaddr) + for(nvm_byte_ptr=(unsigned char *)(nvm_ptr = &(ptlv_header->tlv.nvm)), nvm_index=0; + nvm_index < nvm_length ; nvm_ptr = (tlv_nvm_hdr *) nvm_byte_ptr) + { +- fprintf(stderr, "TAG ID\t\t\t : %d\n", nvm_ptr->tag_id); +- fprintf(stderr, "TAG Length\t\t\t : %d\n", nvm_tag_len = nvm_ptr->tag_len); +- fprintf(stderr, "TAG Pointer\t\t\t : %d\n", nvm_ptr->tag_ptr); +- fprintf(stderr, "TAG Extended Flag\t\t : %d\n", nvm_ptr->tag_ex_flag); +- ++ nvm_tag_len = nvm_ptr->tag_len; ++ hciprintf(stderr, "TAG ID\t\t\t : %d\n", nvm_ptr->tag_id); ++ hciprintf(stderr, "TAG Length\t\t\t : %d\n", nvm_tag_len); ++ hciprintf(stderr, "TAG Pointer\t\t\t : %d\n", nvm_ptr->tag_ptr); ++ hciprintf(stderr, "TAG Extended Flag\t\t : %d\n", nvm_ptr->tag_ex_flag); + /* Increase nvm_index to NVM data */ + nvm_index+=sizeof(tlv_nvm_hdr); + nvm_byte_ptr+=sizeof(tlv_nvm_hdr); +@@ -1058,7 +1057,7 @@ int rome_get_tlv_file(char *file_path, unsigned char * bdaddr) + snprintf((char *) data_buf, PRINT_BUF_SIZE, "%s%.02x ", + (char *)data_buf, *(nvm_byte_ptr + i)); + +- fprintf(stderr, "TAG Data\t\t\t : %s\n", data_buf); ++ hciprintf(stderr, "TAG Data\t\t\t : %s\n", data_buf); + + /* Clear buffer */ + memset(data_buf, 0x0, PRINT_BUF_SIZE); +@@ -1068,7 +1067,7 @@ int rome_get_tlv_file(char *file_path, unsigned char * bdaddr) + nvm_byte_ptr +=nvm_ptr->tag_len; + } + +- fprintf(stderr, "====================================================\n"); ++ hciprintf(stderr, "====================================================\n"); + + } else { + fprintf(stderr, "TLV Header type is unknown (%d) \n", ptlv_header->tlv_type); +@@ -1083,7 +1082,7 @@ int rome_tlv_dnld_segment(int fd, int index, int seg_size, unsigned char wait_cc + unsigned char cmd[HCI_MAX_CMD_SIZE]; + unsigned char rsp[HCI_MAX_EVENT_SIZE]; + +- fprintf(stderr, "%s: Downloading TLV Patch segment no.%d, size:%d wait_cc_evt = 0x%x\n", __FUNCTION__, index, seg_size, wait_cc_evt); ++ hciprintf(stderr, "%s: Downloading TLV Patch segment no.%d, size:%d wait_cc_evt = 0x%x\n", __FUNCTION__, index, seg_size, wait_cc_evt); + + /* Frame the HCI CMD PKT to be sent to Controller*/ + frame_hci_cmd_pkt(cmd, EDL_PATCH_TLV_REQ_CMD, 0, index, seg_size); +@@ -1109,7 +1108,7 @@ int rome_tlv_dnld_segment(int fd, int index, int seg_size, unsigned char wait_cc + } + } + +- fprintf(stderr, "%s: Successfully downloaded patch segment: %d\n", __FUNCTION__, index); ++ hciprintf(stderr, "%s: Successfully downloaded patch segment: %d\n", __FUNCTION__, index); + return err; + } + +@@ -1123,7 +1122,7 @@ int rome_tlv_dnld_req(int fd, int tlv_size) + remain_size = (tlv_size < MAX_SIZE_PER_TLV_SEGMENT)?\ + tlv_size: (tlv_size%MAX_SIZE_PER_TLV_SEGMENT); + +- fprintf(stderr, "%s: TLV size: %d, Total Seg num: %d, remain size: %d\n", ++ hciprintf(stderr, "%s: TLV size: %d, Total Seg num: %d, remain size: %d\n", + __FUNCTION__,tlv_size, total_segment, remain_size); + + if (gTlv_type == TLV_TYPE_PATCH) { +@@ -1137,12 +1136,12 @@ int rome_tlv_dnld_req(int fd, int tlv_size) + case ROME_SKIP_EVT_NONE: + wait_vsc_evt = TRUE; + wait_cc_evt = TRUE; +- fprintf(stderr, "%s: Event handling type: ROME_SKIP_EVT_NONE", __func__); ++ hciprintf(stderr, "%s: Event handling type: ROME_SKIP_EVT_NONE", __func__); + break; + case ROME_SKIP_EVT_VSE_CC: + wait_vsc_evt = FALSE; + wait_cc_evt = FALSE; +- fprintf(stderr, "%s: Event handling type: ROME_SKIP_EVT_VSE_CC", __func__); ++ hciprintf(stderr, "%s: Event handling type: ROME_SKIP_EVT_VSE_CC", __func__); + break; + /* Not handled for now */ + case ROME_SKIP_EVT_VSE: +@@ -1479,14 +1478,14 @@ int rome_1_0_nvm_tag_dnld(int fd) + }; + #endif + +- fprintf(stderr, "%s: Start sending NVM Tags (ver: 0x%x)\n", __FUNCTION__, (unsigned int) NVM_VERSION); ++ hciprintf(stderr, "%s: Start sending NVM Tags (ver: 0x%x)\n", __FUNCTION__, (unsigned int) NVM_VERSION); + + for (i=0; (i < MAX_TAG_CMD) && (cmds[i][0] != TAG_END); i++) + { + /* Write BD Address */ + if(cmds[i][TAG_NUM_OFFSET] == TAG_NUM_2){ + memcpy(&cmds[i][TAG_BDADDR_OFFSET], vnd_local_bd_addr, 6); +- fprintf(stderr, "BD Address: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", ++ hciprintf(stderr, "BD Address: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", + cmds[i][TAG_BDADDR_OFFSET ], cmds[i][TAG_BDADDR_OFFSET + 1], + cmds[i][TAG_BDADDR_OFFSET + 2], cmds[i][TAG_BDADDR_OFFSET + 3], + cmds[i][TAG_BDADDR_OFFSET + 4], cmds[i][TAG_BDADDR_OFFSET + 5]); +@@ -1598,7 +1597,7 @@ int rome_set_baudrate_req(int fd, int local_baud_rate, + flow_control(fd, MSM_DISABLE_FLOW_CTRL); + + /* Send the HCI command packet to UART for transmission */ +- fprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3],cmd[4]) ; ++ hciprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3],cmd[4]) ; + err = write(fd, cmd, size); + if (err != size) { + fprintf(stderr, "%s: Send failed with ret value: %d\n", __FUNCTION__, err); +@@ -1616,7 +1615,7 @@ int rome_set_baudrate_req(int fd, int local_baud_rate, + goto error; + } + +- fprintf(stderr, "%s: Received HCI-Vendor Specific Event from SOC\n", __FUNCTION__); ++ hciprintf(stderr, "%s: Received HCI-Vendor Specific Event from SOC\n", __FUNCTION__); + + /* Wait for command complete event */ + err = read_hci_event(fd, rsp, HCI_MAX_EVENT_SIZE); +@@ -1624,7 +1623,6 @@ int rome_set_baudrate_req(int fd, int local_baud_rate, + fprintf(stderr, "%s: Failed to set patch info on Controller\n", __FUNCTION__); + goto error; + } +- fprintf(stderr, "%s\n", __FUNCTION__); + error: + return err; + +@@ -1639,7 +1637,7 @@ int rome_hci_reset_req(int fd, char baud, int hwfc) + hci_command_hdr *cmd_hdr; + int flags; + +- fprintf(stderr, "%s: HCI RESET \n", __FUNCTION__); ++ hciprintf(stderr, "%s: HCI RESET \n", __FUNCTION__); + + memset(cmd, 0x0, HCI_MAX_CMD_SIZE); + +@@ -1656,7 +1654,7 @@ int rome_hci_reset_req(int fd, char baud, int hwfc) + flow_control(fd, MSM_DISABLE_FLOW_CTRL); + + /* Send the HCI command packet to UART for transmission */ +- fprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3]); ++ hciprintf(stderr, "%s: HCI CMD: 0x%x 0x%x 0x%x 0x%x\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3]); + err = write(fd, cmd, size); + if (err != size) { + fprintf(stderr, "%s: Send failed with ret value: %d\n", __FUNCTION__, err); +@@ -1768,28 +1766,28 @@ int qca_soc_init(int fd, int speed, char *bdaddr , struct termios * ti) + goto error; + } + +- fprintf(stderr, "%s: Rome Version (0x%08x)\n", __FUNCTION__, rome_ver); ++ hciprintf(stderr, "%s: Rome Version (0x%08x)\n", __FUNCTION__, rome_ver); + + switch (rome_ver){ + case ROME_VER_1_0: + { + /* Set and Download the RAMPATCH */ +- fprintf(stderr, "%s: Setting Patch Header & Downloading Patches\n", __FUNCTION__); ++ hciprintf(stderr, "%s: Setting Patch Header & Downloading Patches\n", __FUNCTION__); + err = rome_download_rampatch(fd); + if (err < 0) { + fprintf(stderr, "%s: DOWNLOAD RAMPATCH failed!\n", __FUNCTION__); + goto error; + } +- fprintf(stderr, "%s: DOWNLOAD RAMPTACH complete\n", __FUNCTION__); ++ hciprintf(stderr, "%s: DOWNLOAD RAMPTACH complete\n", __FUNCTION__); + + /* Attach the RAMPATCH */ +- fprintf(stderr, "%s: Attaching the patches\n", __FUNCTION__); ++ hciprintf(stderr, "%s: Attaching the patches\n", __FUNCTION__); + err = rome_attach_rampatch(fd); + if (err < 0) { + fprintf(stderr, "%s: ATTACH RAMPATCH failed!\n", __FUNCTION__); + goto error; + } +- fprintf(stderr, "%s: ATTACH RAMPTACH complete\n", __FUNCTION__); ++ hciprintf(stderr, "%s: ATTACH RAMPTACH complete\n", __FUNCTION__); + + /* Send Reset */ + size = (HCI_CMD_IND + HCI_COMMAND_HDR_SIZE + EDL_PATCH_CMD_LEN); +@@ -1800,7 +1798,7 @@ int qca_soc_init(int fd, int speed, char *bdaddr , struct termios * ti) + } + + /* NVM download */ +- fprintf(stderr, "%s: Downloading NVM\n", __FUNCTION__); ++ hciprintf(stderr, "%s: Downloading NVM\n", __FUNCTION__); + err = rome_1_0_nvm_tag_dnld(fd); + if ( err <0 ) { + fprintf(stderr, "Downloading NVM Failed !!\n"); +@@ -1817,7 +1815,7 @@ int qca_soc_init(int fd, int speed, char *bdaddr , struct termios * ti) + } + } + +- fprintf(stderr, "HCI Reset is done\n"); ++ hciprintf(stderr, "HCI Reset is done\n"); + } + break; + case ROME_VER_1_1: +@@ -1874,7 +1872,7 @@ download: + fprintf(stderr, "%s: Download TLV file failed!\n", __FUNCTION__); + goto error; + } +- fprintf(stderr, "%s: Download TLV file successfully \n", __FUNCTION__); ++ hciprintf(stderr, "%s: Download TLV file successfully \n", __FUNCTION__); + + /* + * Overriding the baud rate value in NVM file with the user +@@ -1893,7 +1891,7 @@ download: + fprintf(stderr, "HCI Reset Failed !!!\n"); + goto error; + } +- fprintf(stderr, "HCI Reset is done\n"); ++ hciprintf(stderr, "HCI Reset is done\n"); + + break; + case ROME_VER_UNKNOWN: diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6qpsbc/bluetooth-init b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6qpsbc/bluetooth-init new file mode 100644 index 000000000..f6fbc3047 --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6qpsbc/bluetooth-init @@ -0,0 +1,93 @@ +#!/bin/sh +#=============================================================================== +# +# Copyright (C) 2012-2017 by Digi International Inc. +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 as published by +# the Free Software Foundation. +# +# +# !Description: Initialize bluetooth hardware +# +#=============================================================================== + +# Bluetooth power GPIO +BT_EN_QCA_GPIO_NR="244" + +# set_gpio_value +set_gpio_value() { + local SG_GPIONR="${1}" + local SG_GPIOVAL="${2}" + local SG_GPIOPATH="/sys/class/gpio/gpio${SG_GPIONR}" + + [ -d "${SG_GPIOPATH}" ] || printf "%s" "${SG_GPIONR}" > /sys/class/gpio/export + printf out > "${SG_GPIOPATH}/direction" && sleep .2 + printf "${SG_GPIOVAL}" > "${SG_GPIOPATH}/value" && sleep .2 + [ -d "${SG_GPIOPATH}" ] && printf "%s" "${SG_GPIONR}" > /sys/class/gpio/unexport +} + +# powercycle_gpio +powercycle_gpio() { + set_gpio_value "${1}" 0 + set_gpio_value "${1}" 1 +} + +error() { + echo ${1} + exit 1 +} + +bluetooth_init() { + # Get MAC address from the device tree. Use a default value if it has not been set. + BT_MACADDR="$(hexdump -ve '1/1 "%02X" ":"' /proc/device-tree/bluetooth/mac-address 2>/dev/null | sed 's/:$//g')" + if [ -z "${BT_MACADDR}" ] || [ "${BT_MACADDR}" = "00:00:00:00:00:00" ]; then + BT_MACADDR="00:04:F3:FF:FF:BB" + fi + + # Start the Bluetooth driver and bring up the interface + HCIATTACH_LOG="/var/log/hciattach.log" + + for RETRY in $(seq 1 5) + do + killproc hciattach + powercycle_gpio "${BT_EN_QCA_GPIO_NR}" + if hciattach ttyBt qca ${BT_RATE:-3000000} -t30 ${BT_FLOW:-flow} unused ${BT_MACADDR} >${HCIATTACH_LOG} 2>&1; then + return + fi + sleep 1 + done + BT_ERROR="FAIL (hciattach)" +} + +# Source function library +. /etc/init.d/functions + +case "$1" in + start) + if [ -d "/proc/device-tree/bluetooth" ]; then + echo -n "Starting bluetooth hardware: " + bluetooth_init + echo "${BT_ERROR:-done.}" + fi + ;; + stop) + if [ -d "/sys/class/bluetooth/hci0" ]; then + echo -n "Stopping bluetooth hardware: " + killproc hciattach + # Power down bluetooth + set_gpio_value "${BT_EN_QCA_GPIO_NR}" 0 + echo "done." + fi + ;; + restart) + $0 stop + sleep 1 + $0 start + ;; + *) + echo "Usage: $0 {start|stop|restart}" + exit 1 + ;; +esac diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6qpsbc/main.conf b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6qpsbc/main.conf new file mode 100644 index 000000000..332d38fad --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6qpsbc/main.conf @@ -0,0 +1,12 @@ +[General] + +# Default adapter name +# Defaults to 'BlueZ X.YZ' +Name = cc6qp + +[Policy] + +# AutoEnable defines option to enable all controllers when they are found. +# This includes adapters present on start as well as adapters that are plugged +# in later on. Defaults to 'false'. +AutoEnable=true diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6sbc/bluetooth-init b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6sbc/bluetooth-init new file mode 100644 index 000000000..6e43617c6 --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6sbc/bluetooth-init @@ -0,0 +1,138 @@ +#!/bin/sh +#=============================================================================== +# +# Copyright (C) 2012-2017 by Digi International Inc. +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 as published by +# the Free Software Foundation. +# +# +# !Description: Initialize bluetooth hardware +# +#=============================================================================== + +# Bluetooth power GPIO +BT_PWR_GPIO_NR="244" + +# set_gpio_value +set_gpio_value() { + local SG_GPIONR="${1}" + local SG_GPIOVAL="${2}" + local SG_GPIOPATH="/sys/class/gpio/gpio${SG_GPIONR}" + + [ -d "${SG_GPIOPATH}" ] || printf "%s" "${SG_GPIONR}" > /sys/class/gpio/export + printf out > "${SG_GPIOPATH}/direction" && sleep .2 + printf "${SG_GPIOVAL}" > "${SG_GPIOPATH}/value" && sleep .2 + [ -d "${SG_GPIOPATH}" ] && printf "%s" "${SG_GPIONR}" > /sys/class/gpio/unexport +} + +# powercycle_gpio +powercycle_gpio() { + set_gpio_value "${1}" 0 + set_gpio_value "${1}" 1 +} + +error() { + echo ${1} + exit 1 +} + +bluetooth_init() { + # Get MAC address from the device tree. Use a default value if it has not been set. + BT_MACADDR="$(hexdump -ve '1/1 "%02X" ":"' /proc/device-tree/bluetooth/mac-address 2>/dev/null | sed 's/:$//g')" + if [ -z "${BT_MACADDR}" ] || [ "${BT_MACADDR}" = "00:00:00:00:00:00" ]; then + BT_MACADDR="00:04:F3:FF:FF:BB" + fi + + # Use a sub-shell here to change to firmware directory + ( + cd /lib/firmware/ar3k/1020200 + + # Update the MAC address file only if it has changed. + FW_MAC="ar3kbdaddr.pst" + [ -f "${FW_MAC}" ] && [ "$(cat ${FW_MAC})" = "${BT_MACADDR}" ] || echo ${BT_MACADDR} > ${FW_MAC} + + # Symlink the correct firmware file depending on region code + JPN_REGCODE="0x2" + REGCODE="$(cat /proc/device-tree/digi,hwid,cert 2>/dev/null)" + BT_CLASS_LINK="PS_ASIC.pst" + BT_CLASS_FILE="PS_ASIC_class_1.pst" + if [ -n "${REGCODE}" ] && [ "${JPN_REGCODE}" = "${REGCODE}" ]; then + BT_CLASS_FILE="PS_ASIC_class_2.pst" + fi + if ! cmp -s ${BT_CLASS_FILE} ${BT_CLASS_LINK}; then + ln -sf ${BT_CLASS_FILE} ${BT_CLASS_LINK} + fi + # Remove not used configuration and readme files + # -- Do not quote the subcommand to avoid leading/trailing whitespace + # -- being part of the file name. + rm -f $(echo PS_ASIC_class_?.pst | sed -e "s,${BT_CLASS_FILE},,g") readme.txt + ) + + # Start the Bluetooth driver and bring up the interface + HCIATTACH_LOG="/var/log/hciattach.log" + BT_CMD="HCIATTACH" + RETRIES="5" + while [ "${RETRIES}" -gt "0" ]; do + case "${BT_CMD}" in + HCIATTACH) + # Reset BT + killproc hciattach + powercycle_gpio "${BT_PWR_GPIO_NR}" + if hciattach ttyBt ath3k 4000000 >${HCIATTACH_LOG} 2>&1; then + BT_CMD="HCICONFIG_UP" + else + BT_ERROR="FAILED (hciattach)" + BT_CMD="BT_INIT_FAIL" + fi + ;; + HCICONFIG_UP) + if hciconfig hci0 up; then + break + else + BT_ERROR="FAILED (hciconfig up)" + BT_CMD="BT_INIT_FAIL" + fi + ;; + BT_INIT_FAIL) + RETRIES="$((RETRIES - 1))" + BT_CMD="HCIATTACH" + ;; + esac + done + [ "${RETRIES}" = "0" ] && error "${BT_ERROR}" +} + +# Source function library +. /etc/init.d/functions + +case "$1" in + start) + if [ -d "/proc/device-tree/bluetooth" ]; then + echo -n "Starting bluetooth hardware: " + bluetooth_init + echo "done." + fi + ;; + stop) + if [ -d "/sys/class/bluetooth/hci0" ]; then + echo -n "Stopping bluetooth hardware: " + hciconfig hci0 down || BT_ERROR="FAILED (hciconfig down)" + killproc hciattach + # Power down bluetooth + set_gpio_value "${BT_PWR_GPIO_NR}" 0 + echo "${BT_ERROR:-done.}" + fi + ;; + restart) + $0 stop + sleep 1 + $0 start + ;; + *) + echo "Usage: $0 {start|stop|restart}" + exit 1 + ;; +esac diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6sbc/main.conf b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6sbc/main.conf new file mode 100644 index 000000000..c0908f0b2 --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6sbc/main.conf @@ -0,0 +1,12 @@ +[General] + +# Default adapter name +# Defaults to 'BlueZ X.YZ' +Name = cc6 + +#[Policy] + +# AutoEnable defines option to enable all controllers when they are found. +# This includes adapters present on start as well as adapters that are plugged +# in later on. Defaults to 'false'. +#AutoEnable=true diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/bluetooth-init b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/bluetooth-init new file mode 100644 index 000000000..6cad5a082 --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/bluetooth-init @@ -0,0 +1,112 @@ +#!/bin/sh +#=============================================================================== +# +# Copyright (C) 2012-2017 by Digi International Inc. +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 as published by +# the Free Software Foundation. +# +# +# !Description: Initialize bluetooth hardware +# +#=============================================================================== + +# Bluetooth power GPIO +BT_EN_QCA_GPIO_NR="137" + +# set_gpio_value +set_gpio_value() { + local SG_GPIONR="${1}" + local SG_GPIOVAL="${2}" + local SG_GPIOPATH="/sys/class/gpio/gpio${SG_GPIONR}" + + [ -d "${SG_GPIOPATH}" ] || printf "%s" "${SG_GPIONR}" > /sys/class/gpio/export + printf out > "${SG_GPIOPATH}/direction" && sleep .2 + printf "${SG_GPIOVAL}" > "${SG_GPIOPATH}/value" && sleep .2 + [ -d "${SG_GPIOPATH}" ] && printf "%s" "${SG_GPIONR}" > /sys/class/gpio/unexport +} + +# powercycle_gpio +powercycle_gpio() { + set_gpio_value "${1}" 0 + set_gpio_value "${1}" 1 +} + +error() { + echo ${1} + exit 1 +} + +bluetooth_init() { + # Get MAC address from the device tree. Use a default value if it has not been set. + BT_MACADDR="$(hexdump -ve '1/1 "%02X" ":"' /proc/device-tree/bluetooth/mac-address 2>/dev/null | sed 's/:$//g')" + if [ -z "${BT_MACADDR}" ] || [ "${BT_MACADDR}" = "00:00:00:00:00:00" ]; then + BT_MACADDR="00:04:F3:FF:FF:BB" + fi + + # Module version older than revision 4 has swapped TX and RX lines + MOD_VERSION="$(($(cat /proc/device-tree/digi,hwid,hv 2>/dev/null || true)))" + if [ "${MOD_VERSION}" -lt "4" ]; then + # Ignore the CTS flow control + BT_CTS_QCA_GPIO_NR="18" + set_gpio_value "${BT_CTS_QCA_GPIO_NR}" 0 + + # Reduce the rate to avoid the need for HW flow control + BT_RATE="115200" + BT_RATE_CODE="00" # 115200 bps + BT_FLOW="noflow" + + # Modify the baudrate in the firmware file + BT_FW_FILE="/lib/firmware/qca/nvm_tlv_3.2.bin" + if [ "$(hexdump -s 56 -n 1 -ve '1/1 "%.2x"' ${BT_FW_FILE})" != "${BT_RATE_CODE}" ]; then + printf "\x${BT_RATE_CODE}" | dd of="${BT_FW_FILE}" bs=1 seek=56 count=1 conv=notrunc,fsync 2>/dev/null + fi + fi + + # Start the Bluetooth driver and bring up the interface + HCIATTACH_LOG="/var/log/hciattach.log" + + for RETRY in $(seq 1 5) + do + killproc hciattach + powercycle_gpio "${BT_EN_QCA_GPIO_NR}" + if hciattach ttyBt qca ${BT_RATE:-3000000} -t30 ${BT_FLOW:-flow} unused ${BT_MACADDR} >${HCIATTACH_LOG} 2>&1; then + return + fi + sleep 1 + done + BT_ERROR="FAIL (hciattach)" +} + +# Source function library +. /etc/init.d/functions + +case "$1" in + start) + if [ -d "/proc/device-tree/bluetooth" ]; then + echo -n "Starting bluetooth hardware: " + bluetooth_init + echo "${BT_ERROR:-done.}" + fi + ;; + stop) + if [ -d "/sys/class/bluetooth/hci0" ]; then + echo -n "Stopping bluetooth hardware: " + killproc hciattach + # Power down bluetooth + set_gpio_value "${BT_EN_QCA_GPIO_NR}" 0 + echo "done." + fi + ;; + restart) + $0 stop + sleep 1 + $0 start + ;; + *) + echo "Usage: $0 {start|stop|restart}" + exit 1 + ;; +esac diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/main.conf b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/main.conf new file mode 100644 index 000000000..e3c0cacbc --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/ccimx6ul/main.conf @@ -0,0 +1,12 @@ +[General] + +# Default adapter name +# Defaults to 'BlueZ X.YZ' +Name = cc6ul + +[Policy] + +# AutoEnable defines option to enable all controllers when they are found. +# This includes adapters present on start as well as adapters that are plugged +# in later on. Defaults to 'false'. +AutoEnable=true diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/cve-2017-1000250.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/cve-2017-1000250.patch new file mode 100644 index 000000000..9fac961bc --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/cve-2017-1000250.patch @@ -0,0 +1,34 @@ +All versions of the SDP server in BlueZ 5.46 and earlier are vulnerable to an +information disclosure vulnerability which allows remote attackers to obtain +sensitive information from the bluetoothd process memory. This vulnerability +lies in the processing of SDP search attribute requests. + +CVE: CVE-2017-1000250 +Upstream-Status: Backport +Signed-off-by: Ross Burton + +From 9e009647b14e810e06626dde7f1bb9ea3c375d09 Mon Sep 17 00:00:00 2001 +From: Luiz Augusto von Dentz +Date: Wed, 13 Sep 2017 10:01:40 +0300 +Subject: sdp: Fix Out-of-bounds heap read in service_search_attr_req function + +Check if there is enough data to continue otherwise return an error. +--- + src/sdpd-request.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/sdpd-request.c b/src/sdpd-request.c +index 1eefdce..318d044 100644 +--- a/src/sdpd-request.c ++++ b/src/sdpd-request.c +@@ -917,7 +917,7 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) + } else { + /* continuation State exists -> get from cache */ + sdp_buf_t *pCache = sdp_get_cached_rsp(cstate); +- if (pCache) { ++ if (pCache && cstate->cStateValue.maxBytesSent < pCache->data_size) { + uint16_t sent = MIN(max, pCache->data_size - cstate->cStateValue.maxBytesSent); + pResponse = pCache->data; + memcpy(buf->data, pResponse + cstate->cStateValue.maxBytesSent, sent); +-- +cgit v1.1 diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/init b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/init new file mode 100644 index 000000000..489e9b9eb --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/init @@ -0,0 +1,68 @@ +#!/bin/sh + +PATH=/sbin:/bin:/usr/sbin:/usr/bin +DESC=bluetooth + +DAEMON=@LIBEXECDIR@/bluetooth/bluetoothd + +# If you want to be ignore error of "org.freedesktop.hostname1", +# please enable NOPLUGIN_OPTION. +# NOPLUGIN_OPTION="--noplugin=hostname" +NOPLUGIN_OPTION="" +SSD_OPTIONS="--oknodo --quiet --exec $DAEMON -- $NOPLUGIN_OPTION" + +test -f $DAEMON || exit 0 + +# FIXME: any of the sourced files may fail if/with syntax errors +test -f /etc/default/bluetooth && . /etc/default/bluetooth +test -f /etc/default/rcS && . /etc/default/rcS + +set -e + +case $1 in + start) + echo "Starting $DESC" + + if test "$BLUETOOTH_ENABLED" = 0; then + echo "disabled. see /etc/default/bluetooth" + exit 0 + fi + + start-stop-daemon --start --background $SSD_OPTIONS + echo "${DAEMON##*/}" + + ;; + stop) + echo "Stopping $DESC" + if test "$BLUETOOTH_ENABLED" = 0; then + echo "disabled." + exit 0 + fi + start-stop-daemon --stop $SSD_OPTIONS + echo "${DAEMON}" + ;; + restart|force-reload) + $0 stop + sleep 1 + $0 start + ;; + status) + pidof ${DAEMON} >/dev/null + status=$? + if [ $status -eq 0 ]; then + echo "bluetooth is running." + else + echo "bluetooth is not running" + fi + exit $status + ;; + *) + N=/etc/init.d/bluetooth + echo "Usage: $N {start|stop|restart|force-reload|status}" >&2 + exit 1 + ;; +esac + +exit 0 + +# vim:noet diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/out-of-tree.patch b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/out-of-tree.patch new file mode 100644 index 000000000..3ee79d704 --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/out-of-tree.patch @@ -0,0 +1,26 @@ +From ed55b49a226ca3909f52416be2ae5ce1c5ca2cb2 Mon Sep 17 00:00:00 2001 +From: Ross Burton +Date: Fri, 22 Apr 2016 15:40:37 +0100 +Subject: [PATCH] Makefile.obexd: add missing mkdir in builtin.h generation + +In parallel out-of-tree builds it's possible that obexd/src/builtin.h is +generated before the target directory has been implicitly created. Solve this by +creating the directory before writing into it. + +Upstream-Status: Submitted +Signed-off-by: Ross Burton +--- + Makefile.obexd | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Makefile.obexd b/Makefile.obexd +index 2e33cbc..c8286f0 100644 +--- a/Makefile.obexd ++++ b/Makefile.obexd +@@ -105,2 +105,3 @@ obexd/src/plugin.$(OBJEXT): obexd/src/builtin.h + obexd/src/builtin.h: obexd/src/genbuiltin $(obexd_builtin_sources) ++ $(AM_V_at)$(MKDIR_P) $(dir $@) + $(AM_V_GEN)$(srcdir)/obexd/src/genbuiltin $(obexd_builtin_modules) > $@ +-- +2.8.0.rc3 + diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/run-ptest b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/run-ptest new file mode 100644 index 000000000..21df00c32 --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-5.41/run-ptest @@ -0,0 +1,31 @@ +#! /bin/sh + +cd unit + +failed=0 +all=0 + +for f in test-*; do + "./$f" + case "$?" in + 0) + echo "PASS: $f" + all=$((all + 1)) + ;; + 77) + echo "SKIP: $f" + ;; + *) + echo "FAIL: $f" + failed=$((failed + 1)) + all=$((all + 1)) + ;; + esac +done + +if [ "$failed" -eq 0 ] ; then + echo "All $all tests passed" +else + echo "$failed of $all tests failed" +fi + diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5.inc b/meta-digi-dey/recipes-connectivity/bluez/bluez5.inc new file mode 100644 index 000000000..3421c3820 --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5.inc @@ -0,0 +1,122 @@ +SUMMARY = "Linux Bluetooth Stack Userland V5" +DESCRIPTION = "Linux Bluetooth stack V5 userland components. These include a system configurations, daemons, tools and system libraries." +HOMEPAGE = "http://www.bluez.org" +SECTION = "libs" +LICENSE = "GPLv2+ & LGPLv2.1+" +LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e \ + file://COPYING.LIB;md5=fb504b67c50331fc78734fed90fb0e09 \ + file://src/main.c;beginline=1;endline=24;md5=9bc54b93cd7e17bf03f52513f39f926e" +DEPENDS = "udev libusb dbus-glib glib-2.0 libcheck readline" +PROVIDES += "bluez-hcidump" +RPROVIDES_${PN} += "bluez-hcidump" + +RCONFLICTS_${PN} = "bluez4" + +PACKAGECONFIG ??= "obex-profiles" +PACKAGECONFIG[obex-profiles] = "--enable-obex,--disable-obex,libical" +PACKAGECONFIG[experimental] = "--enable-experimental,--disable-experimental," + +SRC_URI = "\ + ${KERNELORG_MIRROR}/linux/bluetooth/bluez-${PV}.tar.xz \ + file://out-of-tree.patch \ + file://init \ + file://run-ptest \ + ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '', 'file://0001-Allow-using-obexd-without-systemd-in-the-user-sessio.patch', d)} \ + file://0001-tests-add-a-target-for-building-tests-without-runnin.patch \ + file://cve-2017-1000250.patch \ +" +S = "${WORKDIR}/bluez-${PV}" + +inherit autotools pkgconfig systemd update-rc.d distro_features_check ptest + +EXTRA_OECONF = "\ + --enable-tools \ + --disable-cups \ + --enable-test \ + --enable-datafiles \ + ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '--enable-systemd', '--disable-systemd', d)} \ + --enable-library \ +" + +# bluez5 builds a large number of useful utilities but does not +# install them. Specify which ones we want put into ${PN}-noinst-tools. +NOINST_TOOLS_READLINE ??= "" +NOINST_TOOLS_EXPERIMENTAL ??= "" +NOINST_TOOLS = " \ + ${NOINST_TOOLS_READLINE} \ + ${@bb.utils.contains('PACKAGECONFIG', 'experimental', '${NOINST_TOOLS_EXPERIMENTAL}', '', d)} \ +" + +do_install_append() { + install -d ${D}${INIT_D_DIR} + install -m 0755 ${WORKDIR}/init ${D}${INIT_D_DIR}/bluetooth + + install -d ${D}${sysconfdir}/bluetooth/ + if [ -f ${S}/profiles/audio/audio.conf ]; then + install -m 0644 ${S}/profiles/audio/audio.conf ${D}/${sysconfdir}/bluetooth/ + fi + if [ -f ${S}/profiles/network/network.conf ]; then + install -m 0644 ${S}/profiles/network/network.conf ${D}/${sysconfdir}/bluetooth/ + fi + if [ -f ${S}/profiles/input/input.conf ]; then + install -m 0644 ${S}/profiles/input/input.conf ${D}/${sysconfdir}/bluetooth/ + fi + + if [ -f ${D}/${sysconfdir}/init.d/bluetooth ]; then + sed -i -e 's#@LIBEXECDIR@#${libexecdir}#g' ${D}/${sysconfdir}/init.d/bluetooth + fi + + # Install desired tools that upstream leaves in build area + for f in ${NOINST_TOOLS} ; do + install -m 755 ${B}/$f ${D}/${bindir} + done + + # Patch python tools to use Python 3; they should be source compatible, but + # still refer to Python 2 in the shebang + sed -i -e '1s,#!.*python.*,#!${bindir}/python3,' ${D}${libdir}/bluez/test/* +} + +ALLOW_EMPTY_libasound-module-bluez = "1" +PACKAGES =+ "libasound-module-bluez ${PN}-testtools ${PN}-obex ${PN}-noinst-tools" + +FILES_libasound-module-bluez = "${libdir}/alsa-lib/lib*.so ${datadir}/alsa" +FILES_${PN} += "${libdir}/bluetooth/plugins/*.so ${systemd_unitdir}/ ${datadir}/dbus-1" +FILES_${PN}-dev += "\ + ${libdir}/bluetooth/plugins/*.la \ + ${libdir}/alsa-lib/*.la \ +" + +FILES_${PN}-obex = "${libexecdir}/bluetooth/obexd \ + ${exec_prefix}/lib/systemd/user/obex.service \ + ${datadir}/dbus-1/services/org.bluez.obex.service \ + " +SYSTEMD_SERVICE_${PN}-obex = "obex.service" + +FILES_${PN}-testtools = "${libdir}/bluez/test/*" + +def get_noinst_tools_paths (d, bb, tools): + s = list() + bindir = d.getVar("bindir", True) + for bdp in tools.split(): + f = os.path.basename(bdp) + s.append("%s/%s" % (bindir, f)) + return "\n".join(s) + +FILES_${PN}-noinst-tools = "${@get_noinst_tools_paths(d, bb, d.getVar('NOINST_TOOLS', True))}" + +RDEPENDS_${PN}-testtools += "python3 python3-dbus python3-pygobject" + +SYSTEMD_SERVICE_${PN} = "bluetooth.service" +INITSCRIPT_PACKAGES = "${PN}" +INITSCRIPT_NAME_${PN} = "bluetooth" + +EXCLUDE_FROM_WORLD = "1" + +do_compile_ptest() { + oe_runmake buildtests +} + +do_install_ptest() { + cp -r ${B}/unit/ ${D}${PTEST_PATH} + rm -f ${D}${PTEST_PATH}/unit/*.o +} diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bb b/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bb new file mode 100644 index 000000000..522aab7d5 --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bb @@ -0,0 +1,55 @@ +require bluez5.inc + +REQUIRED_DISTRO_FEATURES = "bluez5" + +SRC_URI[md5sum] = "318341b2188698130adb73236ee69244" +SRC_URI[sha256sum] = "df7dc4462494dad4e60a2943240d584f6e760235dca64f5f10eba46dbab7f5f0" + +# noinst programs in Makefile.tools that are conditional on READLINE +# support +NOINST_TOOLS_READLINE ?= " \ + attrib/gatttool \ + tools/obex-client-tool \ + tools/obex-server-tool \ + tools/bluetooth-player \ + tools/obexctl \ + tools/btmgmt \ +" + +# noinst programs in Makefile.tools that are conditional on EXPERIMENTAL +# support +NOINST_TOOLS_EXPERIMENTAL ?= " \ + emulator/btvirt \ + emulator/b1ee \ + emulator/hfp \ + tools/3dsp \ + tools/mgmt-tester \ + tools/gap-tester \ + tools/l2cap-tester \ + tools/sco-tester \ + tools/smp-tester \ + tools/hci-tester \ + tools/rfcomm-tester \ + tools/bdaddr \ + tools/avinfo \ + tools/avtest \ + tools/scotest \ + tools/amptest \ + tools/hwdb \ + tools/hcieventmask \ + tools/hcisecfilter \ + tools/btinfo \ + tools/btattach \ + tools/btsnoop \ + tools/btproxy \ + tools/btiotest \ + tools/mcaptest \ + tools/cltest \ + tools/oobtest \ + tools/seq2bseq \ + tools/ibeacon \ + tools/btgatt-client \ + tools/btgatt-server \ + tools/gatt-service \ + profiles/iap/iapd \ +" diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend b/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend new file mode 100644 index 000000000..368f0f698 --- /dev/null +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5_5.41.bbappend @@ -0,0 +1,53 @@ +# Copyright (C) 2015-2018 Digi International. + +FILESEXTRAPATHS_prepend := "${THISDIR}/${BP}:" + +SRC_URI += " \ + file://bluetooth-init \ + file://main.conf \ + file://0001-hcitool-do-not-show-unsupported-refresh-option.patch \ + file://0002-hcitool-increase-the-shown-connection-limit-to-20.patch \ + file://0003-port-test-discovery-to-python3.patch \ + file://0004-example-gatt-server-update-example-to-master-version.patch \ + file://0005-core-Prefer-BR-EDR-over-LE-if-it-set-in-advertisemen.patch \ + file://0006-core-device-Fix-not-connecting-services-properly.patch \ + file://0007-core-device-Fix-marking-auto-connect-flag.patch \ + file://0008-core-device-Prefer-bonded-bearers-when-connecting.patch \ + file://0009-input-hog-Use-.accept-and-.disconnect-instead-of-att.patch \ + file://0010-src-device-Free-bonding-while-failed-to-pair-device.patch \ + file://0011-core-Fix-BR-EDR-pairing-for-dual-mode-devices.patch \ +" + +QCA6564_COMMON_PATCHES = " \ + file://0012-QCA_bluetooth_chip_support.patch \ + file://0013-hciattach_rome-Respect-the-user-indication-for-noflo.patch \ + file://0014-hciattach-If-the-user-supplies-a-bdaddr-use-it.patch \ + file://0015-hciattach-Add-verbosity-option.patch \ +" + +SRC_URI_append_ccimx6ul = " ${QCA6564_COMMON_PATCHES}" +SRC_URI_append_ccimx6qpsbc = " ${QCA6564_COMMON_PATCHES}" + +inherit update-rc.d + +PACKAGECONFIG_append = " experimental" + +do_install_append() { + install -d ${D}${sysconfdir}/init.d/ + install -m 0755 ${WORKDIR}/bluetooth-init ${D}${sysconfdir}/init.d/bluetooth-init + install -m 0644 ${WORKDIR}/main.conf ${D}${sysconfdir}/bluetooth/ + if [ -n "${@bb.utils.contains('PACKAGECONFIG', 'experimental', 'experimental', '', d)}" ]; then + sed -i '/^SSD_OPTIONS/a SSD_OPTIONS="${SSD_OPTIONS} --experimental"' ${D}${INIT_D_DIR}/bluetooth + fi +} + +PACKAGES =+ "${PN}-init" + +FILES_${PN} += " ${sysconfdir}/bluetooth/main.conf" +FILES_${PN}-init = "${sysconfdir}/init.d/bluetooth-init" + +INITSCRIPT_PACKAGES += "${PN}-init" +INITSCRIPT_NAME_${PN}-init = "bluetooth-init" +INITSCRIPT_PARAMS_${PN}-init = "start 19 2 3 4 5 . stop 21 0 1 6 ." + +PACKAGE_ARCH = "${MACHINE_ARCH}"