summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorSuraj Sumangala <suraj@atheros.com>2010-11-23 16:29:23 +0530
committerJohan Hedberg <johan.hedberg@nokia.com>2010-11-23 12:09:20 +0100
commit4e0e44626dacd6d2165cfaa7073fd0a9eb4187f2 (patch)
tree813e50364b3854ec0b1b973441cc0eff42982756 /tools
parent429877099f0e5414665f1910cf1cb85ee2eb5ad1 (diff)
downloadbluez-4e0e44626dacd6d2165cfaa7073fd0a9eb4187f2.tar.gz
hciattach: download configuration at user requested baud rate
This patch support downloading configuration for Atheros AR300x HCI UART chip at user requested baud rate instead of the initial baud rate.
Diffstat (limited to 'tools')
-rw-r--r--tools/hciattach.c2
-rw-r--r--tools/hciattach.h3
-rw-r--r--tools/hciattach_ath3k.c98
3 files changed, 73 insertions, 30 deletions
diff --git a/tools/hciattach.c b/tools/hciattach.c
index 7cb8e9e5d..e4d5aa184 100644
--- a/tools/hciattach.c
+++ b/tools/hciattach.c
@@ -311,7 +311,7 @@ static int texasalt(int fd, struct uart_t *u, struct termios *ti)
static int ath3k_ps(int fd, struct uart_t *u, struct termios *ti)
{
- return ath3k_init(fd, u->bdaddr, u->speed);
+ return ath3k_init(fd, u->speed, u->init_speed, u->bdaddr, ti);
}
static int ath3k_pm(int fd, struct uart_t *u, struct termios *ti)
diff --git a/tools/hciattach.h b/tools/hciattach.h
index 2d26b77c2..fed0d1146 100644
--- a/tools/hciattach.h
+++ b/tools/hciattach.h
@@ -50,6 +50,7 @@ int texas_post(int fd, struct termios *ti);
int texasalt_init(int fd, int speed, struct termios *ti);
int stlc2500_init(int fd, bdaddr_t *bdaddr);
int bgb2xx_init(int dd, bdaddr_t *bdaddr);
-int ath3k_init(int fd, char *bdaddr, int speed);
+int ath3k_init(int fd, int speed, int init_speed, char *bdaddr,
+ struct termios *ti);
int ath3k_post(int fd, int pm);
int qualcomm_init(int fd, int speed, struct termios *ti, const char *bdaddr);
diff --git a/tools/hciattach_ath3k.c b/tools/hciattach_ath3k.c
index 70ade304c..728e6605f 100644
--- a/tools/hciattach_ath3k.c
+++ b/tools/hciattach_ath3k.c
@@ -922,14 +922,49 @@ int ath3k_post(int fd, int pm)
#define WRITE_BAUD_CMD_LEN 6
#define MAX_CMD_LEN WRITE_BDADDR_CMD_LEN
+static int set_cntrlr_baud(int fd, int speed)
+{
+ int baud;
+ struct timespec tm = { 0, 500000 };
+ unsigned char cmd[MAX_CMD_LEN], rsp[HCI_MAX_EVENT_SIZE];
+ unsigned char *ptr = cmd + 1;
+ hci_command_hdr *ch = (void *)ptr;
+
+ cmd[0] = HCI_COMMAND_PKT;
+
+ /* set controller baud rate to user specified value */
+ ptr = cmd + 1;
+ ch->opcode = htobs(cmd_opcode_pack(HCI_VENDOR_CMD_OGF,
+ HCI_CHG_BAUD_CMD_OCF));
+ ch->plen = 2;
+ ptr += HCI_COMMAND_HDR_SIZE;
+
+ baud = speed/100;
+ ptr[0] = (char)baud;
+ ptr[1] = (char)(baud >> 8);
+
+ if (write(fd, cmd, WRITE_BAUD_CMD_LEN) != WRITE_BAUD_CMD_LEN) {
+ perror("Failed to write change baud rate command");
+ return -ETIMEDOUT;
+ }
+
+ nanosleep(&tm, NULL);
+
+ if (read_hci_event(fd, rsp, sizeof(rsp)) < 0)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
/*
* Atheros AR300x specific initialization and configuration file
* download
*/
-int ath3k_init(int fd, char *bdaddr, int speed)
+int ath3k_init(int fd, int speed, int init_speed, char *bdaddr,
+ struct termios *ti)
{
int r;
- int baud;
+ int err = 0;
struct timespec tm = { 0, 500000 };
unsigned char cmd[MAX_CMD_LEN], rsp[HCI_MAX_EVENT_SIZE];
unsigned char *ptr = cmd + 1;
@@ -937,11 +972,23 @@ int ath3k_init(int fd, char *bdaddr, int speed)
cmd[0] = HCI_COMMAND_PKT;
+ /* set both controller and host baud rate to maximum possible value */
+ err = set_cntrlr_baud(fd, speed);
+ if (err < 0)
+ return err;
+
+ err = set_speed(fd, ti, speed);
+ if (err < 0) {
+ perror("Can't set required baud rate");
+ return err;
+ }
+
/* Download PS and patch */
r = ath_ps_download(fd);
if (r < 0) {
perror("Failed to Download configuration");
- return -ETIMEDOUT;
+ err = -ETIMEDOUT;
+ goto failed;
}
/* Write BDADDR */
@@ -960,12 +1007,14 @@ int ath3k_init(int fd, char *bdaddr, int speed)
if (write(fd, cmd, WRITE_BDADDR_CMD_LEN) !=
WRITE_BDADDR_CMD_LEN) {
perror("Failed to write BD_ADDR command\n");
- return -ETIMEDOUT;
+ err = -ETIMEDOUT;
+ goto failed;
}
if (read_hci_event(fd, rsp, sizeof(rsp)) < 0) {
perror("Failed to set BD_ADDR\n");
- return -ETIMEDOUT;
+ err = -ETIMEDOUT;
+ goto failed;
}
}
@@ -975,33 +1024,26 @@ int ath3k_init(int fd, char *bdaddr, int speed)
cmd[3] = 0x00;
r = write(fd, cmd, 4);
- if (r != 4)
- return -ETIMEDOUT;
+ if (r != 4) {
+ err = -ETIMEDOUT;
+ goto failed;
+ }
nanosleep(&tm, NULL);
- if (read_hci_event(fd, rsp, sizeof(rsp)) < 0)
- return -ETIMEDOUT;
-
- /* set controller baud rate to user specified value */
- ptr = cmd + 1;
- ch->opcode = htobs(cmd_opcode_pack(HCI_VENDOR_CMD_OGF,
- HCI_CHG_BAUD_CMD_OCF));
- ch->plen = 2;
- ptr += HCI_COMMAND_HDR_SIZE;
-
- baud = speed/100;
- ptr[0] = (char)baud;
- ptr[1] = (char)(baud >> 8);
-
- if (write(fd, cmd, WRITE_BAUD_CMD_LEN) != WRITE_BAUD_CMD_LEN) {
- perror("Failed to write change baud rate command");
- return -ETIMEDOUT;
+ if (read_hci_event(fd, rsp, sizeof(rsp)) < 0) {
+ err = -ETIMEDOUT;
+ goto failed;
}
- nanosleep(&tm, NULL);
+ err = set_cntrlr_baud(fd, speed);
+ if (err < 0)
+ return err;
- if (read_hci_event(fd, rsp, sizeof(rsp)) < 0)
- return -ETIMEDOUT;
+failed:
+ if (err < 0) {
+ set_cntrlr_baud(fd, init_speed);
+ set_speed(fd, ti, init_speed);
+ }
- return 0;
+ return err;
}