2010-07-05 12:37:02

by Bala Shanmugam

[permalink] [raw]
Subject: [RFC] Bluetooth: Add firmware load infrastructure for BT devices

Added support to load firmware to target RAM from Bluetooth USB transport
driver. Each BT device vendor need to specify the product ID, firmware file,
load and unload function. When the device is inserted, btusb will call
appropriate firmware load function to load firmware to target RAM.

This framework is needed for devices that are detected as BT devices when
powered on and still require firmware to be downaloded.

Signed-off-by: Bala Shanmugam <[email protected]>
---
drivers/bluetooth/Makefile | 1 +
drivers/bluetooth/btusb.c | 50 ++++++++++++
drivers/bluetooth/fwload.c | 187 ++++++++++++++++++++++++++++++++++++++++++++
drivers/bluetooth/fwload.h | 37 +++++++++
4 files changed, 275 insertions(+), 0 deletions(-)
create mode 100644 drivers/bluetooth/fwload.c
create mode 100644 drivers/bluetooth/fwload.h

diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile
index 7e5aed5..43df710 100644
--- a/drivers/bluetooth/Makefile
+++ b/drivers/bluetooth/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_BT_HCIBLUECARD) += bluecard_cs.o
obj-$(CONFIG_BT_HCIBTUART) += btuart_cs.o

obj-$(CONFIG_BT_HCIBTUSB) += btusb.o
+obj-$(CONFIG_BT_HCIBTUSB) += fwload.o
obj-$(CONFIG_BT_HCIBTSDIO) += btsdio.o

obj-$(CONFIG_BT_ATH3K) += ath3k.o
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 5d9cc53..816c772 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -34,6 +34,7 @@

#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
+#include "fwload.h"

#define VERSION "0.6"

@@ -55,6 +56,24 @@ static struct usb_driver btusb_driver;
#define BTUSB_BROKEN_ISOC 0x20
#define BTUSB_WRONG_SCO_MTU 0x40

+static struct usb_device_id ath_table[] = {
+ /* Atheros AR3011 */
+ { USB_DEVICE(0x0CF3, 0x3002) },
+ { } /* Terminating entry */
+};
+
+/* Add firmware file, load and unload function
+ * to download the firmware to target RAM
+ */
+static struct fw_cb_config btusb_fwcbs[] = {
+ {
+ .fwfile = "ath3k-1.fw",
+ .usb_id_table = ath_table,
+ .fwload = ath_fw_load,
+ .fwunload = ath_fw_unload,
+ },
+ {}
+};
static struct usb_device_id btusb_table[] = {
/* Generic Bluetooth USB device */
{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
@@ -862,6 +881,7 @@ static int btusb_probe(struct usb_interface *intf,
struct btusb_data *data;
struct hci_dev *hdev;
int i, err;
+ const struct usb_device_id *match;

BT_DBG("intf %p id %p", intf, id);

@@ -921,6 +941,15 @@ static int btusb_probe(struct usb_interface *intf,
data->udev = interface_to_usbdev(intf);
data->intf = intf;

+ for (i = 0; btusb_fwcbs[i].fwfile; i++) {
+ match = usb_match_id(intf, btusb_fwcbs[i].usb_id_table);
+ if (match && btusb_fwcbs[i].fwload) {
+ btusb_fwcbs[i].data = btusb_fwcbs[i].fwload(intf,
+ btusb_fwcbs[i].fwfile);
+ break;
+ }
+ }
+
spin_lock_init(&data->lock);

INIT_WORK(&data->work, btusb_work);
@@ -1029,12 +1058,25 @@ static void btusb_disconnect(struct usb_interface *intf)
{
struct btusb_data *data = usb_get_intfdata(intf);
struct hci_dev *hdev;
+ const struct usb_device_id *match;
+ int i;

BT_DBG("intf %p", intf);

if (!data)
return;

+ for (i = 0; btusb_fwcbs[i].fwfile; i++) {
+ match = usb_match_id(intf, btusb_fwcbs[i].usb_id_table);
+ if (match) {
+ if (btusb_fwcbs[i].fwunload) {
+ btusb_fwcbs[i].fwunload(btusb_fwcbs[i].data);
+ btusb_fwcbs[i].data = NULL;
+ }
+ break;
+ }
+ }
+
hdev = data->hdev;

__hci_dev_hold(hdev);
@@ -1178,6 +1220,14 @@ static int __init btusb_init(void)

static void __exit btusb_exit(void)
{
+ int i;
+
+ for (i = 0; btusb_fwcbs[i].fwfile; i++) {
+ if (btusb_fwcbs[i].fwunload && btusb_fwcbs[i].data) {
+ btusb_fwcbs[i].fwunload(btusb_fwcbs[i].data);
+ btusb_fwcbs[i].data = NULL;
+ }
+ }
usb_deregister(&btusb_driver);
}

diff --git a/drivers/bluetooth/fwload.c b/drivers/bluetooth/fwload.c
new file mode 100644
index 0000000..1135abc
--- /dev/null
+++ b/drivers/bluetooth/fwload.c
@@ -0,0 +1,187 @@
+/*
+ *
+ * Generic Bluetooth USB DFU driver to download firmware to target RAM
+ *
+ * Copyright (c) 2009-2010 Atheros Communications Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/firmware.h>
+#include <linux/usb.h>
+#include <net/bluetooth/bluetooth.h>
+
+#define USB_REQ_DFU_DNLOAD 1
+#define USB_REQ_GET_STATE 5
+#define USB_FIRMWARE_RAM_MODE 11
+#define USB_FIRMWARE_FLASH_MODE 12
+#define BULK_SIZE 4096
+#define VERSION "1.0"
+
+struct firmware_data {
+ struct usb_device *udev;
+ u8 *fw_data;
+ u32 fw_size;
+ u32 fw_sent;
+};
+
+static int load_firmware(struct firmware_data *data,
+ unsigned char *firmware,
+ int count)
+{
+ u8 *send_buf;
+ int err, pipe, len, size, sent = 0;
+ char ucFirmware = 0;
+
+ BT_DBG("ath3k %p udev %p", data, data->udev);
+
+ if ((usb_control_msg(data->udev, usb_rcvctrlpipe(data->udev, 0),
+ USB_REQ_GET_STATE,
+ USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
+ &ucFirmware, 1, USB_CTRL_SET_TIMEOUT)) < 0) {
+ BT_ERR("Can't change to loading configuration err");
+ return -EBUSY;
+ }
+
+ if (ucFirmware == USB_FIRMWARE_RAM_MODE) {
+ /* RAM based firmware is available in the target.
+ * No need to load the firmware to RAM */
+ BT_DBG("RAM based firmware is available");
+ return 0;
+ }
+
+ pipe = usb_sndctrlpipe(data->udev, 0);
+ if ((usb_control_msg(data->udev, pipe,
+ USB_REQ_DFU_DNLOAD,
+ USB_TYPE_VENDOR, 0, 0,
+ firmware, 20, USB_CTRL_SET_TIMEOUT)) < 0) {
+ BT_ERR("Can't change to loading configuration err");
+ return -EBUSY;
+ }
+ sent += 20;
+ count -= 20;
+
+ send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC);
+ if (!send_buf) {
+ BT_ERR("Can't allocate memory chunk for firmware");
+ return -ENOMEM;
+ }
+
+ while (count) {
+ size = min_t(uint, count, BULK_SIZE);
+ pipe = usb_sndbulkpipe(data->udev, 0x02);
+ memcpy(send_buf, firmware + sent, size);
+
+ err = usb_bulk_msg(data->udev, pipe, send_buf, size,
+ &len, 3000);
+
+ if (err || (len != size)) {
+ BT_ERR("Error in firmware loading err = %d,"
+ "len = %d, size = %d", err, len, size);
+ goto error;
+ }
+
+ sent += size;
+ count -= size;
+ }
+
+ kfree(send_buf);
+ return 0;
+
+error:
+ kfree(send_buf);
+ return err;
+}
+
+void *ath_fw_load(struct usb_interface *intf, const char *fwfile)
+{
+ const struct firmware *firmware;
+ struct usb_device *udev = interface_to_usbdev(intf);
+ struct firmware_data *data;
+ int size;
+
+ BT_DBG("intf %p ", intf);
+
+ if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
+ return NULL;
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return NULL;
+
+ data->udev = udev;
+
+ if (request_firmware(&firmware, fwfile, &udev->dev) < 0) {
+ kfree(data);
+ return NULL;
+ }
+
+ size = max_t(uint, firmware->size, 4096);
+ data->fw_data = kmalloc(size, GFP_KERNEL);
+ if (!data->fw_data) {
+ release_firmware(firmware);
+ kfree(data);
+ return NULL;
+ }
+
+ memcpy(data->fw_data, firmware->data, firmware->size);
+ data->fw_size = firmware->size;
+ data->fw_sent = 0;
+ release_firmware(firmware);
+
+ if (load_firmware(data, data->fw_data, data->fw_size)) {
+ kfree(data->fw_data);
+ kfree(data);
+ return NULL;
+ }
+ return data;
+}
+EXPORT_SYMBOL(ath_fw_load);
+
+void ath_fw_unload(void *pdata)
+{
+ struct firmware_data *data = (struct firmware_data *)pdata;
+ if (data == NULL)
+ return;
+ kfree(data->fw_data);
+ kfree(data);
+}
+EXPORT_SYMBOL(ath_fw_unload);
+
+static int __init fwload_init(void)
+{
+ BT_INFO("Firmware load driver init. Version:%s", VERSION);
+ return 0;
+}
+
+static void __exit fwload_deinit(void)
+{
+ BT_INFO("Firmware load driver deinit");
+}
+
+module_init(fwload_init);
+module_exit(fwload_deinit);
+
+MODULE_AUTHOR("Atheros Communications");
+MODULE_DESCRIPTION("Firmware load driver");
+MODULE_VERSION(VERSION);
+MODULE_LICENSE("GPL");
diff --git a/drivers/bluetooth/fwload.h b/drivers/bluetooth/fwload.h
new file mode 100644
index 0000000..ce1c841
--- /dev/null
+++ b/drivers/bluetooth/fwload.h
@@ -0,0 +1,37 @@
+/*
+ *
+ * Generic Bluetooth USB DFU driver to download firmware to target RAM
+ *
+ * Copyright (c) 2009-2010 Atheros Communications Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef __FWLOAD_H_
+#define __FWLOAD_H_
+
+/* callbacks to load firmware to BT device RAM
+ * when it is inserted */
+struct fw_cb_config {
+ const char *fwfile;
+ void * (*fwload)(struct usb_interface *intf, const char *fwfile);
+ void (*fwunload)(void *);
+ const struct usb_device_id *usb_id_table;
+ void *data;
+};
+void *ath_fw_load(struct usb_interface *intf, const char *);
+void ath_fw_unload(void *pdata);
+
+#endif /* __FWLOAD_H_ */
--
1.6.3.3


2010-07-13 12:43:02

by Marcel Holtmann

[permalink] [raw]
Subject: RE: [RFC] Bluetooth: Add firmware load infrastructure for BT devices

Hi Bala,

> > > Firmware loading to target RAM needs to be done once when the device is inserted. Firmware loading will not be required every time
> > > the device goes from DOWN to UP. I think each HCI driver requires
> > > a separate firmware loading code as firmware loading is
> > > different for different interfaces. Please advice if my understanding is wrong.
> > >
> > > I initially thought of registration
> > > mechanism with btusb transport driver to load firmware, but before
> > > the device is inserted btusb will not be loaded and registering the
> > > firmware load function with btusb was not possible.
> > >
> > > Please advice alternate solution to load firmware from transport driver.
> >
> > >my advise would be to just build devices that change their USB VID/PID
> > >after the firmware got loaded. That way it is easy to have a firmware
> > >loading driver and just btusb for real operation. Why is it so hard to
> > >build just simple hardware that would just work.
> >
> > Thanks for the suggestion.
> > This is what is done for some of the devices.
> > For performance reasons few other devices comes with
> > small firmware in flash and the device gets detected as
> > generic bluetooth device when plugged in. So control reaches btusb
> > once the device is plugged in. In this case actual firmware
> > needs to be downloaded to target from btusb transport driver.
>
> is this simple firmware already talking HCI at that point or is it some
> USB protocol to load the rest of the firmware.
>
> Firmware in the flash does not talk to HCI. Yes it supports some USB commands which are required to load the rest of the firmware.

so you are basically saying you created a device with generic USB
Bluetooth class that is not following the Bluetooth H:2 specification.
And now you expect the btusb driver to make this work. I think the
screw-up here is clearly on your side by violating the USB Bluetooth
specification in the first place.

If your USB descriptors tell you something like this:

I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms
E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms

Then you better support HCI commands (H:2 protocol) at that point.

I could understand if the firmware gets loaded via HCI vendor commands,
but just a random other USB protocol is pretty much wrong.

Regards

Marcel



Subject: RE: [RFC] Bluetooth: Add firmware load infrastructure for BT devices



-----Original Message-----
From: [email protected] [mailto:linux-bluetooth-owner@v=
ger.kernel.org] On Behalf Of Marcel Holtmann
Sent: Monday, July 12, 2010 6:21 PM
To: Shanmugamkamatchi Balashanmugam
Cc: Perelet, Oleg; [email protected]
Subject: RE: [RFC] Bluetooth: Add firmware load infrastructure for BT devic=
es

Hi Bala,

> > Firmware loading to target RAM needs to be done once when the device is=
inserted. Firmware loading will not be required every time=20
> > the device goes from DOWN to UP. I think each HCI driver requires
> > a separate firmware loading code as firmware loading is=20
> > different for different interfaces. Please advice if my understanding =
is wrong.
> >=20
> > I initially thought of registration=20
> > mechanism with btusb transport driver to load firmware, but before
> > the device is inserted btusb will not be loaded and registering the=20
> > firmware load function with btusb was not possible.
> >=20
> > Please advice alternate solution to load firmware from transport driver=
.
>=20
> >my advise would be to just build devices that change their USB VID/PID
> >after the firmware got loaded. That way it is easy to have a firmware
> >loading driver and just btusb for real operation. Why is it so hard to
> >build just simple hardware that would just work.
>=20
> Thanks for the suggestion.
> This is what is done for some of the devices.
> For performance reasons few other devices comes with=20
> small firmware in flash and the device gets detected as=20
> generic bluetooth device when plugged in. So control reaches btusb
> once the device is plugged in. In this case actual firmware
> needs to be downloaded to target from btusb transport driver.

is this simple firmware already talking HCI at that point or is it some
USB protocol to load the rest of the firmware.

Regards

Marcel

Firmware in the flash does not talk to HCI. Yes it supports some USB comman=
ds which are required to load the rest of the firmware.

Regards,
Bala.

2010-07-12 12:50:57

by Marcel Holtmann

[permalink] [raw]
Subject: RE: [RFC] Bluetooth: Add firmware load infrastructure for BT devices

Hi Bala,

> > Firmware loading to target RAM needs to be done once when the device is inserted. Firmware loading will not be required every time
> > the device goes from DOWN to UP. I think each HCI driver requires
> > a separate firmware loading code as firmware loading is
> > different for different interfaces. Please advice if my understanding is wrong.
> >
> > I initially thought of registration
> > mechanism with btusb transport driver to load firmware, but before
> > the device is inserted btusb will not be loaded and registering the
> > firmware load function with btusb was not possible.
> >
> > Please advice alternate solution to load firmware from transport driver.
>
> >my advise would be to just build devices that change their USB VID/PID
> >after the firmware got loaded. That way it is easy to have a firmware
> >loading driver and just btusb for real operation. Why is it so hard to
> >build just simple hardware that would just work.
>
> Thanks for the suggestion.
> This is what is done for some of the devices.
> For performance reasons few other devices comes with
> small firmware in flash and the device gets detected as
> generic bluetooth device when plugged in. So control reaches btusb
> once the device is plugged in. In this case actual firmware
> needs to be downloaded to target from btusb transport driver.

is this simple firmware already talking HCI at that point or is it some
USB protocol to load the rest of the firmware.

Regards

Marcel



Subject: RE: [RFC] Bluetooth: Add firmware load infrastructure for BT devices

Hi Marcel,

-----Original Message-----
From: Marcel Holtmann [mailto:[email protected]]=20
Sent: Thursday, July 08, 2010 7:13 PM
To: Shanmugamkamatchi Balashanmugam
Cc: Perelet, Oleg; [email protected]
Subject: RE: [RFC] Bluetooth: Add firmware load infrastructure for BT devic=
es

Hi Bala,

> Firmware loading to target RAM needs to be done once when the device is i=
nserted. Firmware loading will not be required every time=20
> the device goes from DOWN to UP. I think each HCI driver requires
> a separate firmware loading code as firmware loading is=20
> different for different interfaces. Please advice if my understanding is=
wrong.
>=20
> I initially thought of registration=20
> mechanism with btusb transport driver to load firmware, but before
> the device is inserted btusb will not be loaded and registering the=20
> firmware load function with btusb was not possible.
>=20
> Please advice alternate solution to load firmware from transport driver.

>my advise would be to just build devices that change their USB VID/PID
>after the firmware got loaded. That way it is easy to have a firmware
>loading driver and just btusb for real operation. Why is it so hard to
>build just simple hardware that would just work.

>Regards

>Marcel

Thanks for the suggestion.
This is what is done for some of the devices.
For performance reasons few other devices comes with=20
small firmware in flash and the device gets detected as=20
generic bluetooth device when plugged in. So control reaches btusb
once the device is plugged in. In this case actual firmware
needs to be downloaded to target from btusb transport driver.

Please suggest if there is other way to handle these devices in linux.

Regards,
Bala.

2010-07-08 13:42:52

by Marcel Holtmann

[permalink] [raw]
Subject: RE: [RFC] Bluetooth: Add firmware load infrastructure for BT devices

Hi Bala,

> Firmware loading to target RAM needs to be done once when the device is inserted. Firmware loading will not be required every time
> the device goes from DOWN to UP. I think each HCI driver requires
> a separate firmware loading code as firmware loading is
> different for different interfaces. Please advice if my understanding is wrong.
>
> I initially thought of registration
> mechanism with btusb transport driver to load firmware, but before
> the device is inserted btusb will not be loaded and registering the
> firmware load function with btusb was not possible.
>
> Please advice alternate solution to load firmware from transport driver.

my advise would be to just build devices that change their USB VID/PID
after the firmware got loaded. That way it is easy to have a firmware
loading driver and just btusb for real operation. Why is it so hard to
build just simple hardware that would just work.

Regards

Marcel



Subject: RE: [RFC] Bluetooth: Add firmware load infrastructure for BT devices



-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Perelet, Oleg
Sent: Wednesday, July 07, 2010 2:00 AM
To: Marcel Holtmann; Shanmugamkamatchi Balashanmugam
Cc: [email protected]
Subject: RE: [RFC] Bluetooth: Add firmware load infrastructure for BT devices

>> Added support to load firmware to target RAM from Bluetooth USB transport
>> driver.

>we have discussed this a long time ago and the better approach would be
>to create a setup stage for all HCI drivers. For example for special HCI
>commands to set BD_ADDR and other details. Maybe also a firmware loading
>stage should be used. Making this USB specific sounds pretty much wrong
>to me at this point. At least SDIO might have similar issues.

>>The current approach looks more hackish than actually nicely integrated.

>Thanks for bringing up old topic. We discussed this few years ago and >things been somehow stalled. Besides, USB, SDIO there's UART which is used >in a lot of embedded platforms and everybody hacks custom code around.

>Overall Marcel suggests to have intermediate stage between DOWN and UP >states for hci device aka - SETUP (call it any name).


>Here are low level BT setup states that I "think" are common for majority >of embedded implementations:

>1. low level GPIO, CLC etc setup - can not talk to chip before that.

>2. Initial firmware/patch download - at this state one can talk HCI to >chip, but chip is barely functional, firmware, patches etc are downloaded >at this stage.

>3. "Run time config download" (often combined with #2, but I suggest to >separate) this is when BDADDR is programmed and chip run time parameters >for given platform are set up. For majority of chips this stage also >defines Sleep algorithm to be used. There are few ways of doing BT sleep - >HCI, UART signaling or usage of extra WAKE GPIO's to determine sleep >condition. Most of them require initial HCI setup.

>4. Enable Sleep and low power mode. Currently everybody hardcodes this >step, some platforms have programmatic ifaces (aka sysfs)

>5. WiFI coex setup if needed.

>Feel free to add more here ....

>At this stage hci can be brought to UP stage and be functional.


>All of that is tight with RFKILL of course and also suspend/resume entries >in transport driver. I'm also not doing in to details of sleep mode >implementation in this thread but welcome to discuss it in separate thread.

>Oleg.

Thanks for the comments.
Firmware loading to target RAM needs to be done once when the device is inserted. Firmware loading will not be required every time
the device goes from DOWN to UP. I think each HCI driver requires
a separate firmware loading code as firmware loading is
different for different interfaces. Please advice if my understanding is wrong.

I initially thought of registration
mechanism with btusb transport driver to load firmware, but before
the device is inserted btusb will not be loaded and registering the
firmware load function with btusb was not possible.

Please advice alternate solution to load firmware from transport driver.

Regards,
Bala.

2010-07-06 20:29:56

by Perelet, Oleg

[permalink] [raw]
Subject: RE: [RFC] Bluetooth: Add firmware load infrastructure for BT devices

>> Added support to load firmware to target RAM from Bluetooth USB transpor=
t
>> driver.=20

>we have discussed this a long time ago and the better approach would be
>to create a setup stage for all HCI drivers. For example for special HCI
>commands to set BD_ADDR and other details. Maybe also a firmware loading
>stage should be used. Making this USB specific sounds pretty much wrong
>to me at this point. At least SDIO might have similar issues.

>>The current approach looks more hackish than actually nicely integrated.

Thanks for bringing up old topic. We discussed this few years ago and thing=
s been somehow stalled. Besides, USB, SDIO there's UART which is used in a =
lot of embedded platforms and everybody hacks custom code around.

Overall Marcel suggests to have intermediate stage between DOWN and UP stat=
es for hci device aka - SETUP (call it any name).


Here are low level BT setup states that I "think" are common for majority o=
f embedded implementations:

1. low level GPIO, CLC etc setup - can not talk to chip before that.

2. Initial firmware/patch download - at this state one can talk HCI to chip=
, but chip is barely functional, firmware, patches etc are downloaded at th=
is stage.

3. "Run time config download" (often combined with #2, but I suggest to sep=
arate) this is when BDADDR is programmed and chip run time parameters for g=
iven platform are set up. For majority of chips this stage also defines Sle=
ep algorithm to be used. There are few ways of doing BT sleep - HCI, UART s=
ignaling or usage of extra WAKE GPIO's to determine sleep condition. Most o=
f them require initial HCI setup.

4. Enable Sleep and low power mode. Currently everybody hardcodes this step=
, some platforms have programmatic ifaces (aka sysfs)

5. WiFI coex setup if needed.

Feel free to add more here ....

At this stage hci can be brought to UP stage and be functional.


All of that is tight with RFKILL of course and also suspend/resume entries =
in transport driver. I'm also not doing in to details of sleep mode impleme=
ntation in this thread but welcome to discuss it in separate thread.

Oleg.




2010-07-06 17:24:21

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [RFC] Bluetooth: Add firmware load infrastructure for BT devices

Hi Bala,

> Added support to load firmware to target RAM from Bluetooth USB transport
> driver. Each BT device vendor need to specify the product ID, firmware file,
> load and unload function. When the device is inserted, btusb will call
> appropriate firmware load function to load firmware to target RAM.
>
> This framework is needed for devices that are detected as BT devices when
> powered on and still require firmware to be downaloded.

we have discussed this a long time ago and the better approach would be
to create a setup stage for all HCI drivers. For example for special HCI
commands to set BD_ADDR and other details. Maybe also a firmware loading
stage should be used. Making this USB specific sounds pretty much wrong
to me at this point. At least SDIO might have similar issues.

The current approach looks more hackish than actually nicely integrated.

Regards

Marcel