summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Kondik <shade@chemlab.org>2013-07-05 14:25:52 -0700
committerSteve Kondik <shade@chemlab.org>2013-07-05 15:21:06 -0700
commit5e53640d63b7c140294e57d397df0c047f869923 (patch)
tree316500d37a06bc57731892b4363f4bbe9123da2f
parent6747b2697931fe6eb2b9f92b787be64f2f548690 (diff)
downloaddevice_common-5e53640d63b7c140294e57d397df0c047f869923.zip
device_common-5e53640d63b7c140294e57d397df0c047f869923.tar.gz
device_common-5e53640d63b7c140294e57d397df0c047f869923.tar.bz2
libbt: Add prepatch support
* We need to apply an initial patch to the BCM4335 hardware to prevent chip crashes, so add support for a prepatch designated by FW_PRE_PATCH. Change-Id: I2d2ec59094a1ae2cb39e1f41d4853ac4a45d1902
-rw-r--r--libbt/include/bt_vendor_brcm.h4
-rw-r--r--libbt/src/hardware.c42
2 files changed, 45 insertions, 1 deletions
diff --git a/libbt/include/bt_vendor_brcm.h b/libbt/include/bt_vendor_brcm.h
index 4ba62ac..58feda0 100644
--- a/libbt/include/bt_vendor_brcm.h
+++ b/libbt/include/bt_vendor_brcm.h
@@ -72,6 +72,10 @@
#define UART_TARGET_BAUD_RATE 3000000
#endif
+#ifndef FW_PRE_PATCH
+#define FW_PRE_PATCH ""
+#endif
+
/* The millisecond delay pauses on HCI transport after firmware patches
* were downloaded. This gives some time for firmware to restart with
* patches before host attempts to send down any HCI commands.
diff --git a/libbt/src/hardware.c b/libbt/src/hardware.c
index 759e8a8..b72de51 100644
--- a/libbt/src/hardware.c
+++ b/libbt/src/hardware.c
@@ -117,7 +117,8 @@ enum {
HW_CFG_DL_MINIDRIVER,
HW_CFG_DL_FW_PATCH,
HW_CFG_SET_UART_BAUD_2,
- HW_CFG_SET_BD_ADDR
+ HW_CFG_SET_BD_ADDR,
+ HW_CFG_DL_FW_PRE_PATCH,
#if (USE_CONTROLLER_BDADDR == TRUE)
, HW_CFG_READ_BD_ADDR
#endif
@@ -170,6 +171,7 @@ extern uint8_t vnd_local_bd_addr[BD_ADDR_LEN];
static char fw_patchfile_path[256] = FW_PATCHFILE_LOCATION;
static char fw_patchfile_name[128] = { 0 };
+static char fw_prepatch_name[384] = FW_PRE_PATCH;
#if (VENDOR_LIB_RUNTIME_TUNING_ENABLED == TRUE)
static int fw_patch_settlement_delay = -1;
#endif
@@ -673,6 +675,44 @@ void hw_config_cback(void *p_mem)
line_speed_to_userial_baud(UART_TARGET_BAUD_RATE) \
);
+ hw_cfg_cb.fw_fd = -1;
+
+ // load the prepatch
+ if (strlen(fw_prepatch_name) &&
+ (hw_cfg_cb.fw_fd = open(fw_prepatch_name, O_RDONLY)) > -1)
+ {
+ ALOGI("bt vendor lib: loading prepatch %s", fw_prepatch_name);
+ }
+
+ hw_cfg_cb.state = HW_CFG_DL_FW_PRE_PATCH;
+ // intentional fallthru
+
+ case HW_CFG_DL_FW_PRE_PATCH:
+ if (hw_cfg_cb.fw_fd > -1) {
+ p_buf->len = read(hw_cfg_cb.fw_fd, p, HCI_CMD_PREAMBLE_SIZE);
+ if (p_buf->len > 0)
+ {
+ if ((p_buf->len < HCI_CMD_PREAMBLE_SIZE) || \
+ (opcode == HCI_VSC_LAUNCH_RAM))
+ {
+ ALOGW("firmware patch file might be altered!");
+ }
+ else
+ {
+ p_buf->len += read(hw_cfg_cb.fw_fd, \
+ p+HCI_CMD_PREAMBLE_SIZE,\
+ *(p+HCD_REC_PAYLOAD_LEN_BYTE));
+ STREAM_TO_UINT16(opcode,p);
+ is_proceeding = bt_vendor_cbacks->xmit_cb(opcode, \
+ p_buf, hw_config_cback);
+ break;
+ }
+ }
+
+ close(hw_cfg_cb.fw_fd);
+ hw_cfg_cb.fw_fd = -1;
+ }
+
/* read local name */
UINT16_TO_STREAM(p, HCI_READ_LOCAL_NAME);
*p = 0; /* parameter length */