[meta-freescale] [PATCH 51/52] bluez5: Apply patches for QCA6174 and QCA9377-3

Tom Hochstein tom.hochstein at nxp.com
Mon Jul 30 12:44:10 PDT 2018


Signed-off-by: Tom Hochstein <tom.hochstein at nxp.com>
---
 recipes-connectivity/bluez5/bluez5_5.%.bbappend    |   14 +
 ...th-Add-bluetooth-support-for-QCA6174-chip.patch | 2404 ++++++++++++++++++++
 ...tach-set-flag-to-enable-HCI-reset-on-init.patch |   32 +
 ...nstead-of-strlcpy-with-strncpy-to-avoid-r.patch |   35 +
 4 files changed, 2485 insertions(+)
 create mode 100644 recipes-connectivity/bluez5/bluez5_5.%.bbappend
 create mode 100644 recipes-connectivity/bluez5/files/0001-bluetooth-Add-bluetooth-support-for-QCA6174-chip.patch
 create mode 100644 recipes-connectivity/bluez5/files/0002-hciattach-set-flag-to-enable-HCI-reset-on-init.patch
 create mode 100644 recipes-connectivity/bluez5/files/0003-hciattach-instead-of-strlcpy-with-strncpy-to-avoid-r.patch

diff --git a/recipes-connectivity/bluez5/bluez5_5.%.bbappend b/recipes-connectivity/bluez5/bluez5_5.%.bbappend
new file mode 100644
index 0000000..00eb248
--- /dev/null
+++ b/recipes-connectivity/bluez5/bluez5_5.%.bbappend
@@ -0,0 +1,14 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+# Do not start the service during system boot up
+INITSCRIPT_PARAMS_${PN} = "stop 20 0 1 6 ."
+
+# Add patch for module bcm43xx
+# Add patches for QCA modules with Qca6174 and Qca9377-3 chips
+SRC_URI += " \
+            file://0001-bluetooth-Add-bluetooth-support-for-QCA6174-chip.patch \
+            file://0002-hciattach-set-flag-to-enable-HCI-reset-on-init.patch \
+            file://0003-hciattach-instead-of-strlcpy-with-strncpy-to-avoid-r.patch \
+            file://0004-Add-support-for-Tufello-1.1-SOC.patch \
+            file://0005-bluetooth-Add-support-for-multi-baud-rate.patch \
+"
diff --git a/recipes-connectivity/bluez5/files/0001-bluetooth-Add-bluetooth-support-for-QCA6174-chip.patch b/recipes-connectivity/bluez5/files/0001-bluetooth-Add-bluetooth-support-for-QCA6174-chip.patch
new file mode 100644
index 0000000..5ae3c98
--- /dev/null
+++ b/recipes-connectivity/bluez5/files/0001-bluetooth-Add-bluetooth-support-for-QCA6174-chip.patch
@@ -0,0 +1,2404 @@
+From d509b84f237c11874087d7ea527e5ba2f460ed2c Mon Sep 17 00:00:00 2001
+From: Fugang Duan <fugang.duan at nxp.com>
+Date: Tue, 29 Aug 2017 10:12:57 +0800
+Subject: [PATCH 1/5] 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
+
+cherry-pick and merged from:
+	https://source.codeaurora.org/quic/la/platform/external/bluetooth/bluez
+	branch: LNX.LE.5.3
+	commit: commit bb96f3b759e0b99db70014302ca12929fb42f554
+
+Change-Id: I87f2927d7096904071a02d73d3afef0dc34db414
+Signed-off-by: Rupesh Tatiya <rtatiya at codeaurora.org>
+Signed-off-by: Fugang Duan <fugang.duan at nxp.com>
+---
+ Makefile.tools         |    3 +-
+ tools/hciattach.c      |   26 +-
+ tools/hciattach.h      |    2 +
+ tools/hciattach_rome.c | 1864 ++++++++++++++++++++++++++++++++++++++++++++++++
+ tools/hciattach_rome.h |  371 ++++++++++
+ 5 files changed, 2264 insertions(+), 2 deletions(-)
+
+diff --git a/Makefile.tools b/Makefile.tools
+index 0fd6dec..f1a1def 100644
+--- a/Makefile.tools
++++ b/Makefile.tools
+@@ -283,7 +283,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 fad176c..200f734 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,11 @@ 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 +1208,8 @@ static int init_uart(char *dev, struct uart_t *u, int send_break, int raw)
+ 		goto fail;
+ 	}
+ 
++if (line_disp) {
++	fprintf(stderr, "Setting TTY to N_HCI line discipline\n");
+ 	/* Set TTY to N_HCI line discipline */
+ 	i = N_HCI;
+ 	if (ioctl(fd, TIOCSETD, &i) < 0) {
+@@ -1211,6 +1226,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 +1265,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 +1298,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);
+@@ -1426,12 +1447,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 249aab4..59efa31 100644
+--- a/tools/hciattach.h
++++ b/tools/hciattach.h
+@@ -45,6 +45,7 @@
+ #define HCI_UART_AG6XX	9
+ #define HCI_UART_NOKIA	10
+ #define HCI_UART_MRVL	11
++#define HCI_UART_IBS	12
+ 
+ #define HCI_UART_RAW_DEVICE	0
+ #define HCI_UART_RESET_ON_INIT	1
+@@ -65,6 +66,7 @@ int bgb2xx_init(int dd, bdaddr_t *bdaddr);
+ int ath3k_init(int fd, int speed, int init_speed, char *bdaddr,
+ 						struct termios *ti);
+ int ath3k_post(int fd, int pm);
++int qca_soc_init(int fd, char *bdaddr);
+ int qualcomm_init(int fd, int speed, struct termios *ti, const 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,
+diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c
+new file mode 100644
+index 0000000..242a49f
+--- /dev/null
++++ b/tools/hciattach_rome.c
+@@ -0,0 +1,1864 @@
++/*
++ *
++ *  Copyright (c) 2013-2015, 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 <stdio.h>
++#include <unistd.h>
++#include <sys/socket.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <sys/ioctl.h>
++#include <signal.h>
++#include <time.h>
++#include <errno.h>
++#include <fcntl.h>
++#include <dirent.h>
++#include <ctype.h>
++#include <stdlib.h>
++#include <string.h>
++#include <termios.h>
++#include <bluetooth/bluetooth.h>
++#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;
++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
++******************************************************************************/
++//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);
++
++    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);
++    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;
++    ti.c_cflag |= CREAD;
++    ti.c_cflag |= CS8;
++
++    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;
++}
++
++
++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, retry = 0;
++    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__);
++
++    /* 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) {
++                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++;
++
++    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;
++    }
++
++    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__);
++    }
++
++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 get_value_from_config(char *file_path,char *param)
++{
++    FILE *pfile = NULL;
++    char *line = NULL;
++    char *pch = NULL;
++    char param_str[PARAM_LEN];
++    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;
++                strlcpy(param_str, line, sizeof(param_str));
++                if (position >= sizeof(param_str))
++                    position = sizeof(param_str) - 1;
++                if (strncmp(param_str, param, position) == 0) {
++                    ret = atoi(pch + 1);
++                    break;
++                }
++            }
++        }
++    }
++    /* getline() will allocate a buffer for storing the line. */
++    free(line);
++    fclose(pfile);
++    return ret;
++}
++
++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;
++    unsigned char bdaddr[6];
++    unsigned short pcm_value, ibs_value;
++
++    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);
++
++    if((fileSize = ftell(pFile)) < 0) {
++        fprintf(stderr, "%s: fail to get current file position\n", file_path);
++        fclose(pFile);
++        return -1;
++    }
++
++    if(fileSize == 0) {
++        fprintf(stderr, "%s: no content in the file\n", file_path);
++        fclose(pFile);
++        return -1;
++    }
++
++    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;
++    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");
++
++    } 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 && 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_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(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));
++                    }
++                }
++            }
++
++            for(i =0;(i<nvm_ptr->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);
++
++            /* Clear buffer */
++            memset(data_buf, 0x0, PRINT_BUF_SIZE);
++
++            /* increased by tag_len */
++            nvm_index+=nvm_ptr->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 = FALSE;
++
++    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);
++
++    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;
++    }
++
++    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);
++
++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;
++
++}
++
++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 (opt == MSM_ENABLE_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;
++    }
++    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)
++{
++   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_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 */
++    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);
++    if (err != size) {
++        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 */
++    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__);
++            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);
++
++    /* Flow off during baudrate change */
++    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);
++    if (err != size) {
++        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 */
++    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) {
++        fprintf(stderr, "%s: Failed to set patch info on Controller\n", __FUNCTION__);
++        goto error;
++    }
++
++error:
++    return err;
++
++}
++
++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)
++{
++    int err = -1;
++    int size;
++
++    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);
++        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:
++            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;
++
++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;
++            }
++            fprintf(stderr, "%s: Baud rate changed successfully \n", __FUNCTION__);
++
++            /* 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__);
++
++            /* 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:
++#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
+new file mode 100644
+index 0000000..9770d0b
+--- /dev/null
++++ b/tools/hciattach_rome.h
+@@ -0,0 +1,371 @@
++/*
++ * 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.
++ * 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))
++
++#define NVITEM              0
++#define RDWR_PROT           1
++#define NVITEM_SIZE         2
++#define PERSIST_HEADER_LEN  3
++#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 {
++    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_NUM_17			(17)
++#define TAG_NUM_44			44
++#define TAG_BDADDR_OFFSET     7
++
++/* 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 MAX_RETRY_CNT  1
++#define SELECT_TIMEOUT 3
++
++#define PARAM_LEN      20
++
++/* 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/rampatch_tlv_3.0.tlv"
++#define ROME_NVM_TLV_3_0_0_PATH         "/lib/firmware/nvm_tlv_3.0.bin"
++#define ROME_RAMPATCH_TLV_3_0_2_PATH    "/lib/firmware/rampatch_tlv_3.2.tlv"
++#define ROME_NVM_TLV_3_0_2_PATH         "/lib/firmware/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
++
++#define FW_CONFIG_FILE_PATH        "/etc/bluetooth/firmware.conf"
++/******************************************************************************
++**  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 int  tlv_data_len;
++    unsigned int  tlv_patch_data_len;
++    unsigned char sign_ver;
++    unsigned char sign_algorithm;
++    unsigned char dwnd_cfg;
++    unsigned char 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;
++
++    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,
++    ROME_PATCH_VER_0302 = 0x0302
++ };
++
++enum{
++    ROME_SOC_ID_00 = 0x00000000,
++    ROME_SOC_ID_11 = 0x00000011,
++    ROME_SOC_ID_13 = 0x00000013,
++    ROME_SOC_ID_22 = 0x00000022,
++    ROME_SOC_ID_44 = 0x00000044
++};
++
++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 ),
++    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 )
++};
++
++#ifdef USE_GLIB
++#include <glib.h>
++#define strlcpy g_strlcpy
++#endif
++
++#endif /* HW_ROME_H */
+-- 
+1.9.1
+
diff --git a/recipes-connectivity/bluez5/files/0002-hciattach-set-flag-to-enable-HCI-reset-on-init.patch b/recipes-connectivity/bluez5/files/0002-hciattach-set-flag-to-enable-HCI-reset-on-init.patch
new file mode 100644
index 0000000..a9ce17d
--- /dev/null
+++ b/recipes-connectivity/bluez5/files/0002-hciattach-set-flag-to-enable-HCI-reset-on-init.patch
@@ -0,0 +1,32 @@
+From 3648d3c33b1dd0e11707328d87101d8044d23302 Mon Sep 17 00:00:00 2001
+From: Fugang Duan <fugang.duan at nxp.com>
+Date: Tue, 29 Aug 2017 10:21:09 +0800
+Subject: [PATCH 2/5] hciattach: set flag to enable HCI reset on init
+
+On some qca devices, correct setup of BT+WLAN co-existance requires
+HCI reset being set at the start of power on sequence. Sending HCI
+resets has no side effect.
+
+Change-Id: I71cb367d10d4d19d82b41af6a4a0b8b2f770f691
+Signed-off-by: Rupesh Tatiya <rtatiya at codeaurora.org>
+---
+ tools/hciattach.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/tools/hciattach.c b/tools/hciattach.c
+index 200f734..d03ed46 100644
+--- a/tools/hciattach.c
++++ b/tools/hciattach.c
+@@ -1158,6 +1158,9 @@ static int init_uart(char *dev, struct uart_t *u, int send_break, int raw)
+ 	if (u->flags & AMP_DEV)
+ 		flags |= 1 << HCI_UART_CREATE_AMP;
+ 
++	if (!strncmp(u->type, "qca", 3))
++		flags |= 1 << HCI_UART_RESET_ON_INIT;
++
+ 	fd = open(dev, O_RDWR | O_NOCTTY);
+ 	if (fd < 0) {
+ 		perror("Can't open serial port");
+-- 
+1.9.1
+
diff --git a/recipes-connectivity/bluez5/files/0003-hciattach-instead-of-strlcpy-with-strncpy-to-avoid-r.patch b/recipes-connectivity/bluez5/files/0003-hciattach-instead-of-strlcpy-with-strncpy-to-avoid-r.patch
new file mode 100644
index 0000000..8ad2b32
--- /dev/null
+++ b/recipes-connectivity/bluez5/files/0003-hciattach-instead-of-strlcpy-with-strncpy-to-avoid-r.patch
@@ -0,0 +1,35 @@
+From 5877685b10560c40f1c4af375e30adf2a631fefc Mon Sep 17 00:00:00 2001
+From: Fugang Duan <fugang.duan at nxp.com>
+Date: Tue, 29 Aug 2017 14:54:44 +0800
+Subject: [PATCH 3/5] hciattach: instead of strlcpy with strncpy to avoid rome
+ build error
+
+Instead of strlcpy with strncpy to avoid rome build error.
+
+igned-off-by: Fugang Duan <fugang.duan at nxp.com>
+---
+ tools/hciattach_rome.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/hciattach_rome.c b/tools/hciattach_rome.c
+index 242a49f..c3e9fde 100644
+--- a/tools/hciattach_rome.c
++++ b/tools/hciattach_rome.c
+@@ -893,12 +893,12 @@ int get_value_from_config(char *file_path,char *param)
+         return ret;
+     }
+ 
+-    while (getline(&line, &bytes_read, pfile) > 0 ) {
++    while (getline(&line, (size_t *)&bytes_read, pfile) > 0 ) {
+         if (line[0] != '#'  && line[0] != '\n') {
+             pch = memchr(line, '=', strlen(line));
+             if (pch != NULL) {
+                 position = pch - line;
+-                strlcpy(param_str, line, sizeof(param_str));
++                strncpy(param_str, line, sizeof(param_str));
+                 if (position >= sizeof(param_str))
+                     position = sizeof(param_str) - 1;
+                 if (strncmp(param_str, param, position) == 0) {
+-- 
+1.9.1
+
-- 
2.7.4



More information about the meta-freescale mailing list