• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2009-2010 Atheros Communications Inc.
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  *
18  */
19 
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 
24 #include <stdio.h>
25 #include <errno.h>
26 #include <unistd.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <ctype.h>
30 #include <time.h>
31 #include <sys/time.h>
32 #include <sys/types.h>
33 #include <sys/param.h>
34 #include <sys/ioctl.h>
35 
36 #include <bluetooth/bluetooth.h>
37 #include <bluetooth/hci.h>
38 #include <bluetooth/hci_lib.h>
39 
40 #include "hciattach.h"
41 
42 #define TRUE    1
43 #define FALSE   0
44 
45 #define FW_PATH "/lib/firmware/ar3k/"
46 
47 struct ps_cfg_entry {
48 	uint32_t id;
49 	uint32_t len;
50 	uint8_t *data;
51 };
52 
53 struct ps_entry_type {
54 	unsigned char type;
55 	unsigned char array;
56 };
57 
58 #define MAX_TAGS              50
59 #define PS_HDR_LEN            4
60 #define HCI_VENDOR_CMD_OGF    0x3F
61 #define HCI_PS_CMD_OCF        0x0B
62 
63 struct ps_cfg_entry ps_list[MAX_TAGS];
64 
load_hci_ps_hdr(uint8_t * cmd,uint8_t ps_op,int len,int index)65 static void load_hci_ps_hdr(uint8_t *cmd, uint8_t ps_op, int len, int index)
66 {
67 	hci_command_hdr *ch = (void *)cmd;
68 
69 	ch->opcode = htobs(cmd_opcode_pack(HCI_VENDOR_CMD_OGF,
70 						HCI_PS_CMD_OCF));
71 	ch->plen = len + PS_HDR_LEN;
72 	cmd += HCI_COMMAND_HDR_SIZE;
73 
74 	cmd[0] = ps_op;
75 	cmd[1] = index;
76 	cmd[2] = index >> 8;
77 	cmd[3] = len;
78 }
79 
80 #define PS_EVENT_LEN 100
81 
82 /*
83  * Send HCI command and wait for command complete event.
84  * The event buffer has to be freed by the caller.
85  */
send_hci_cmd_sync(int dev,uint8_t * cmd,int len,uint8_t ** event)86 static int send_hci_cmd_sync(int dev, uint8_t *cmd, int len, uint8_t **event)
87 {
88 	int err;
89 	uint8_t *hci_event;
90 	uint8_t pkt_type = HCI_COMMAND_PKT;
91 
92 	if (len == 0)
93 		return len;
94 
95 	if (write(dev, &pkt_type, 1) != 1)
96 		return -EILSEQ;
97 	if (write(dev, (unsigned char *)cmd, len) != len)
98 		return -EILSEQ;
99 
100 	hci_event = (uint8_t *)malloc(PS_EVENT_LEN);
101 	if (!hci_event)
102 		return -ENOMEM;
103 
104 	err = read_hci_event(dev, (unsigned char *)hci_event, PS_EVENT_LEN);
105 	if (err > 0) {
106 		*event = hci_event;
107 	} else {
108 		free(hci_event);
109 		return -EILSEQ;
110 	}
111 
112 	return len;
113 }
114 
115 #define HCI_EV_SUCCESS        0x00
116 
read_ps_event(uint8_t * event,uint16_t ocf)117 static int read_ps_event(uint8_t *event, uint16_t ocf)
118 {
119 	hci_event_hdr *eh;
120 	uint16_t opcode = htobs(cmd_opcode_pack(HCI_VENDOR_CMD_OGF, ocf));
121 
122 	event++;
123 
124 	eh = (void *)event;
125 	event += HCI_EVENT_HDR_SIZE;
126 
127 	if (eh->evt == EVT_CMD_COMPLETE) {
128 		evt_cmd_complete *cc = (void *)event;
129 
130 		event += EVT_CMD_COMPLETE_SIZE;
131 
132 		if (cc->opcode == opcode && event[0] == HCI_EV_SUCCESS)
133 			return 0;
134 		else
135 			return -EILSEQ;
136 	}
137 
138 	return -EILSEQ;
139 }
140 
write_cmd(int fd,uint8_t * buffer,int len)141 static int write_cmd(int fd, uint8_t *buffer, int len)
142 {
143 	uint8_t *event;
144 	int err;
145 
146 	err = send_hci_cmd_sync(fd, buffer, len, &event);
147 	if (err < 0)
148 		return err;
149 
150 	err = read_ps_event(event, HCI_PS_CMD_OCF);
151 
152 	free(event);
153 
154 	return err;
155 }
156 
157 #define PS_WRITE           1
158 #define PS_RESET           2
159 #define WRITE_PATCH        8
160 #define ENABLE_PATCH       11
161 
162 #define HCI_PS_CMD_HDR_LEN 7
163 
164 #define PS_RESET_PARAM_LEN 6
165 #define HCI_MAX_CMD_SIZE   260
166 #define PS_RESET_CMD_LEN   (HCI_PS_CMD_HDR_LEN + PS_RESET_PARAM_LEN)
167 
168 #define PS_ID_MASK         0xFF
169 
170 /* Sends PS commands using vendor specficic HCI commands */
write_ps_cmd(int fd,uint8_t opcode,uint32_t ps_param)171 static int write_ps_cmd(int fd, uint8_t opcode, uint32_t ps_param)
172 {
173 	uint8_t cmd[HCI_MAX_CMD_SIZE];
174 	uint32_t i;
175 
176 	switch (opcode) {
177 	case ENABLE_PATCH:
178 		load_hci_ps_hdr(cmd, opcode, 0, 0x00);
179 
180 		if (write_cmd(fd, cmd, HCI_PS_CMD_HDR_LEN) < 0)
181 			return -EILSEQ;
182 		break;
183 
184 	case PS_RESET:
185 		load_hci_ps_hdr(cmd, opcode, PS_RESET_PARAM_LEN, 0x00);
186 
187 		cmd[7] = 0x00;
188 		cmd[PS_RESET_CMD_LEN - 2] = ps_param & PS_ID_MASK;
189 		cmd[PS_RESET_CMD_LEN - 1] = (ps_param >> 8) & PS_ID_MASK;
190 
191 		if (write_cmd(fd, cmd, PS_RESET_CMD_LEN) < 0)
192 			return -EILSEQ;
193 		break;
194 
195 	case PS_WRITE:
196 		for (i = 0; i < ps_param; i++) {
197 			load_hci_ps_hdr(cmd, opcode, ps_list[i].len,
198 							ps_list[i].id);
199 
200 			memcpy(&cmd[HCI_PS_CMD_HDR_LEN], ps_list[i].data,
201 							ps_list[i].len);
202 
203 			if (write_cmd(fd, cmd, ps_list[i].len +
204 						HCI_PS_CMD_HDR_LEN) < 0)
205 				return -EILSEQ;
206 		}
207 		break;
208 	}
209 
210 	return 0;
211 }
212 
213 #define __is_delim(ch) ((ch) == ':')
214 #define MAX_PREAMBLE_LEN 4
215 
216 /* Parse PS entry preamble of format [X:X] for main type and subtype */
get_ps_type(char * ptr,int index,char * type,char * sub_type)217 static int get_ps_type(char *ptr, int index, char *type, char *sub_type)
218 {
219 	int i;
220 	int delim = FALSE;
221 
222 	if (index > MAX_PREAMBLE_LEN)
223 		return -EILSEQ;
224 
225 	for (i = 1; i < index; i++) {
226 		if (__is_delim(ptr[i])) {
227 			delim = TRUE;
228 			continue;
229 		}
230 
231 		if (isalpha(ptr[i])) {
232 			if (delim == FALSE)
233 				(*type) = toupper(ptr[i]);
234 			else
235 				(*sub_type) = toupper(ptr[i]);
236 		}
237 	}
238 
239 	return 0;
240 }
241 
242 #define ARRAY   'A'
243 #define STRING  'S'
244 #define DECIMAL 'D'
245 #define BINARY  'B'
246 
247 #define PS_HEX           0
248 #define PS_DEC           1
249 
get_input_format(char * buf,struct ps_entry_type * format)250 static int get_input_format(char *buf, struct ps_entry_type *format)
251 {
252 	char *ptr = NULL;
253 	char type = '\0';
254 	char sub_type = '\0';
255 
256 	format->type = PS_HEX;
257 	format->array = TRUE;
258 
259 	if (strstr(buf, "[") != buf)
260 		return 0;
261 
262 	ptr = strstr(buf, "]");
263 	if (!ptr)
264 		return -EILSEQ;
265 
266 	if (get_ps_type(buf, ptr - buf, &type, &sub_type) < 0)
267 		return -EILSEQ;
268 
269 	/* Check is data type is of array */
270 	if (type == ARRAY || sub_type == ARRAY)
271 		format->array = TRUE;
272 
273 	if (type == STRING || sub_type == STRING)
274 		format->array = FALSE;
275 
276 	if (type == DECIMAL || type == BINARY)
277 		format->type = PS_DEC;
278 	else
279 		format->type = PS_HEX;
280 
281 	return 0;
282 }
283 
284 #define UNDEFINED 0xFFFF
285 
read_data_in_section(char * buf,struct ps_entry_type type)286 static unsigned int read_data_in_section(char *buf, struct ps_entry_type type)
287 {
288 	char *ptr = buf;
289 
290 	if (!buf)
291 		return UNDEFINED;
292 
293 	if (buf == strstr(buf, "[")) {
294 		ptr = strstr(buf, "]");
295 		if (!ptr)
296 			return UNDEFINED;
297 
298 		ptr++;
299 	}
300 
301 	if (type.type == PS_HEX && type.array != TRUE)
302 		return strtol(ptr, NULL, 16);
303 
304 	return UNDEFINED;
305 }
306 
307 struct tag_info {
308 	unsigned section;
309 	unsigned line_count;
310 	unsigned char_cnt;
311 	unsigned byte_count;
312 };
313 
update_char_count(const char * buf)314 static inline int update_char_count(const char *buf)
315 {
316 	char *end_ptr;
317 
318 	if (strstr(buf, "[") == buf) {
319 		end_ptr = strstr(buf, "]");
320 		if (!end_ptr)
321 			return 0;
322 		else
323 			return (end_ptr - buf) + 1;
324 	}
325 
326 	return 0;
327 }
328 
329 /* Read PS entries as string, convert and add to Hex array */
update_tag_data(struct ps_cfg_entry * tag,struct tag_info * info,const char * ptr)330 static void update_tag_data(struct ps_cfg_entry *tag,
331 				struct tag_info *info, const char *ptr)
332 {
333 	char buf[3];
334 
335 	buf[2] = '\0';
336 
337 	strncpy(buf, &ptr[info->char_cnt], 2);
338 	tag->data[info->byte_count] = strtol(buf, NULL, 16);
339 	info->char_cnt += 3;
340 	info->byte_count++;
341 
342 	strncpy(buf, &ptr[info->char_cnt], 2);
343 	tag->data[info->byte_count] = strtol(buf, NULL, 16);
344 	info->char_cnt += 3;
345 	info->byte_count++;
346 }
347 
348 #define PS_UNDEF   0
349 #define PS_ID      1
350 #define PS_LEN     2
351 #define PS_DATA    3
352 
353 #define PS_MAX_LEN         500
354 #define LINE_SIZE_MAX      (PS_MAX_LEN * 2)
355 #define ENTRY_PER_LINE     16
356 
357 #define __check_comment(buf) (((buf)[0] == '/') && ((buf)[1] == '/'))
358 #define __skip_space(str)      while (*(str) == ' ') ((str)++)
359 
ath_parse_ps(FILE * stream)360 static int ath_parse_ps(FILE *stream)
361 {
362 	char buf[LINE_SIZE_MAX + 1];
363 	char *ptr;
364 	uint8_t tag_cnt = 0;
365 	int16_t byte_count = 0;
366 	struct ps_entry_type format;
367 	struct tag_info status = { 0, 0, 0, 0 };
368 
369 	do {
370 		int read_count;
371 		struct ps_cfg_entry *tag;
372 
373 		ptr = fgets(buf, LINE_SIZE_MAX, stream);
374 		if (!ptr)
375 			break;
376 
377 		__skip_space(ptr);
378 		if (__check_comment(ptr))
379 			continue;
380 
381 		/* Lines with a '#' will be followed by new PS entry */
382 		if (ptr == strstr(ptr, "#")) {
383 			if (status.section != PS_UNDEF) {
384 				return -EILSEQ;
385 			} else {
386 				status.section = PS_ID;
387 				continue;
388 			}
389 		}
390 
391 		tag = &ps_list[tag_cnt];
392 
393 		switch (status.section) {
394 		case PS_ID:
395 			if (get_input_format(ptr, &format) < 0)
396 				return -EILSEQ;
397 
398 			tag->id = read_data_in_section(ptr, format);
399 			status.section = PS_LEN;
400 			break;
401 
402 		case PS_LEN:
403 			if (get_input_format(ptr, &format) < 0)
404 				return -EILSEQ;
405 
406 			byte_count = read_data_in_section(ptr, format);
407 			if (byte_count > PS_MAX_LEN)
408 				return -EILSEQ;
409 
410 			tag->len = byte_count;
411 			tag->data = (uint8_t *)malloc(byte_count);
412 
413 			status.section = PS_DATA;
414 			status.line_count = 0;
415 			break;
416 
417 		case PS_DATA:
418 			if (status.line_count == 0)
419 				if (get_input_format(ptr, &format) < 0)
420 					return -EILSEQ;
421 
422 			__skip_space(ptr);
423 
424 			status.char_cnt = update_char_count(ptr);
425 
426 			read_count = (byte_count > ENTRY_PER_LINE) ?
427 					ENTRY_PER_LINE : byte_count;
428 
429 			if (format.type == PS_HEX && format.array == TRUE) {
430 				while (read_count > 0) {
431 					update_tag_data(tag, &status, ptr);
432 					read_count -= 2;
433 				}
434 
435 				if (byte_count > ENTRY_PER_LINE)
436 					byte_count -= ENTRY_PER_LINE;
437 				else
438 					byte_count = 0;
439 			}
440 
441 			status.line_count++;
442 
443 			if (byte_count == 0)
444 				memset(&status, 0x00, sizeof(struct tag_info));
445 
446 			if (status.section == PS_UNDEF)
447 				tag_cnt++;
448 
449 			if (tag_cnt == MAX_TAGS)
450 				return -EILSEQ;
451 			break;
452 		}
453 	} while (ptr);
454 
455 	return tag_cnt;
456 }
457 
458 #define MAX_PATCH_CMD 244
459 struct patch_entry {
460 	int16_t len;
461 	uint8_t data[MAX_PATCH_CMD];
462 };
463 
464 #define SET_PATCH_RAM_ID	0x0D
465 #define SET_PATCH_RAM_CMD_SIZE	11
466 #define ADDRESS_LEN		4
set_patch_ram(int dev,char * patch_loc,int len)467 static int set_patch_ram(int dev, char *patch_loc, int len)
468 {
469 	int err;
470 	uint8_t cmd[20];
471 	int i, j;
472 	char loc_byte[3];
473 	uint8_t *event;
474 	uint8_t *loc_ptr = &cmd[7];
475 
476 	if (!patch_loc)
477 		return -1;
478 
479 	loc_byte[2] = '\0';
480 
481 	load_hci_ps_hdr(cmd, SET_PATCH_RAM_ID, ADDRESS_LEN, 0);
482 
483 	for (i = 0, j = 3; i < 4; i++, j--) {
484 		loc_byte[0] = patch_loc[0];
485 		loc_byte[1] = patch_loc[1];
486 		loc_ptr[j] = strtol(loc_byte, NULL, 16);
487 		patch_loc += 2;
488 	}
489 
490 	err = send_hci_cmd_sync(dev, cmd, SET_PATCH_RAM_CMD_SIZE, &event);
491 	if (err < 0)
492 		return err;
493 
494 	err = read_ps_event(event, HCI_PS_CMD_OCF);
495 
496 	free(event);
497 
498 	return err;
499 }
500 
501 #define PATCH_LOC_KEY    "DA:"
502 #define PATCH_LOC_STRING_LEN    8
ps_patch_download(int fd,FILE * stream)503 static int ps_patch_download(int fd, FILE *stream)
504 {
505 	char byte[3];
506 	char ptr[MAX_PATCH_CMD + 1];
507 	int byte_cnt;
508 	int patch_count = 0;
509 	char patch_loc[PATCH_LOC_STRING_LEN + 1];
510 
511 	byte[2] = '\0';
512 
513 	while (fgets(ptr, MAX_PATCH_CMD, stream)) {
514 		if (strlen(ptr) <= 1)
515 			continue;
516 		else if (strstr(ptr, PATCH_LOC_KEY) == ptr) {
517 			strncpy(patch_loc, &ptr[sizeof(PATCH_LOC_KEY) - 1],
518 							PATCH_LOC_STRING_LEN);
519 			if (set_patch_ram(fd, patch_loc, sizeof(patch_loc)) < 0)
520 				return -1;
521 		} else if (isxdigit(ptr[0]))
522 			break;
523 		else
524 			return -1;
525 	}
526 
527 	byte_cnt = strtol(ptr, NULL, 16);
528 
529 	while (byte_cnt > 0) {
530 		int i;
531 		uint8_t cmd[HCI_MAX_CMD_SIZE];
532 		struct patch_entry patch;
533 
534 		if (byte_cnt > MAX_PATCH_CMD)
535 			patch.len = MAX_PATCH_CMD;
536 		else
537 			patch.len = byte_cnt;
538 
539 		for (i = 0; i < patch.len; i++) {
540 			if (!fgets(byte, 3, stream))
541 				return -1;
542 
543 			patch.data[i] = strtoul(byte, NULL, 16);
544 		}
545 
546 		load_hci_ps_hdr(cmd, WRITE_PATCH, patch.len, patch_count);
547 		memcpy(&cmd[HCI_PS_CMD_HDR_LEN], patch.data, patch.len);
548 
549 		if (write_cmd(fd, cmd, patch.len + HCI_PS_CMD_HDR_LEN) < 0)
550 			return -1;
551 
552 		patch_count++;
553 		byte_cnt = byte_cnt - MAX_PATCH_CMD;
554 	}
555 
556 	if (write_ps_cmd(fd, ENABLE_PATCH, 0) < 0)
557 		return -1;
558 
559 	return patch_count;
560 }
561 
562 #define PS_RAM_SIZE 2048
563 
ps_config_download(int fd,int tag_count)564 static int ps_config_download(int fd, int tag_count)
565 {
566 	if (write_ps_cmd(fd, PS_RESET, PS_RAM_SIZE) < 0)
567 		return -1;
568 
569 	if (tag_count > 0)
570 		if (write_ps_cmd(fd, PS_WRITE, tag_count) < 0)
571 			return -1;
572 	return 0;
573 }
574 
575 #define PS_ASIC_FILE			"PS_ASIC.pst"
576 #define PS_FPGA_FILE			"PS_FPGA.pst"
577 
get_ps_file_name(uint32_t devtype,uint32_t rom_version,char * path)578 static void get_ps_file_name(uint32_t devtype, uint32_t rom_version,
579 							char *path)
580 {
581 	char *filename;
582 
583 	if (devtype == 0xdeadc0de)
584 		filename = PS_ASIC_FILE;
585 	else
586 		filename = PS_FPGA_FILE;
587 
588 	snprintf(path, MAXPATHLEN, "%s%x/%s", FW_PATH, rom_version, filename);
589 }
590 
591 #define PATCH_FILE        "RamPatch.txt"
592 #define FPGA_ROM_VERSION  0x99999999
593 #define ROM_DEV_TYPE      0xdeadc0de
594 
get_patch_file_name(uint32_t dev_type,uint32_t rom_version,uint32_t build_version,char * path)595 static void get_patch_file_name(uint32_t dev_type, uint32_t rom_version,
596 				uint32_t build_version, char *path)
597 {
598 	if (rom_version == FPGA_ROM_VERSION && dev_type != ROM_DEV_TYPE &&
599 					dev_type != 0 && build_version == 1)
600 		path[0] = '\0';
601 	else
602 		snprintf(path, MAXPATHLEN, "%s%x/%s",
603 				FW_PATH, rom_version, PATCH_FILE);
604 }
605 
606 #define VERIFY_CRC   9
607 #define PS_REGION    1
608 #define PATCH_REGION 2
609 
get_ath3k_crc(int dev)610 static int get_ath3k_crc(int dev)
611 {
612 	uint8_t cmd[7];
613 	uint8_t *event;
614 	int err;
615 
616 	load_hci_ps_hdr(cmd, VERIFY_CRC, 0, PS_REGION | PATCH_REGION);
617 
618 	err = send_hci_cmd_sync(dev, cmd, sizeof(cmd), &event);
619 	if (err < 0)
620 		return err;
621 	/* Send error code if CRC check patched */
622 	if (read_ps_event(event, HCI_PS_CMD_OCF) >= 0)
623 		err = -EILSEQ;
624 
625 	free(event);
626 
627 	return err;
628 }
629 
630 #define DEV_REGISTER      0x4FFC
631 #define GET_DEV_TYPE_OCF  0x05
632 
get_device_type(int dev,uint32_t * code)633 static int get_device_type(int dev, uint32_t *code)
634 {
635 	uint8_t cmd[8];
636 	uint8_t *event;
637 	uint32_t reg;
638 	int err;
639 	uint8_t *ptr = cmd;
640 	hci_command_hdr *ch = (void *)cmd;
641 
642 	ch->opcode = htobs(cmd_opcode_pack(HCI_VENDOR_CMD_OGF,
643 						GET_DEV_TYPE_OCF));
644 	ch->plen = 5;
645 	ptr += HCI_COMMAND_HDR_SIZE;
646 
647 	ptr[0] = (uint8_t)DEV_REGISTER;
648 	ptr[1] = (uint8_t)DEV_REGISTER >> 8;
649 	ptr[2] = (uint8_t)DEV_REGISTER >> 16;
650 	ptr[3] = (uint8_t)DEV_REGISTER >> 24;
651 	ptr[4] = 0x04;
652 
653 	err = send_hci_cmd_sync(dev, cmd, sizeof(cmd), &event);
654 	if (err < 0)
655 		return err;
656 
657 	err = read_ps_event(event, GET_DEV_TYPE_OCF);
658 	if (err < 0)
659 		goto cleanup;
660 
661 	reg = event[10];
662 	reg = (reg << 8) | event[9];
663 	reg = (reg << 8) | event[8];
664 	reg = (reg << 8) | event[7];
665 	*code = reg;
666 
667 cleanup:
668 	free(event);
669 
670 	return err;
671 }
672 
673 #define GET_VERSION_OCF 0x1E
674 
read_ath3k_version(int pConfig,uint32_t * rom_version,uint32_t * build_version)675 static int read_ath3k_version(int pConfig, uint32_t *rom_version,
676 					uint32_t *build_version)
677 {
678 	uint8_t cmd[3];
679 	uint8_t *event;
680 	int err;
681 	int status;
682 	hci_command_hdr *ch = (void *)cmd;
683 
684 	ch->opcode = htobs(cmd_opcode_pack(HCI_VENDOR_CMD_OGF,
685 						GET_VERSION_OCF));
686 	ch->plen = 0;
687 
688 	err = send_hci_cmd_sync(pConfig, cmd, sizeof(cmd), &event);
689 	if (err < 0)
690 		return err;
691 
692 	err = read_ps_event(event, GET_VERSION_OCF);
693 	if (err < 0)
694 		goto cleanup;
695 
696 	status = event[10];
697 	status = (status << 8) | event[9];
698 	status = (status << 8) | event[8];
699 	status = (status << 8) | event[7];
700 	*rom_version = status;
701 
702 	status = event[14];
703 	status = (status << 8) | event[13];
704 	status = (status << 8) | event[12];
705 	status = (status << 8) | event[11];
706 	*build_version = status;
707 
708 cleanup:
709 	free(event);
710 
711 	return err;
712 }
713 
convert_bdaddr(char * str_bdaddr,char * bdaddr)714 static void convert_bdaddr(char *str_bdaddr, char *bdaddr)
715 {
716 	char bdbyte[3];
717 	char *str_byte = str_bdaddr;
718 	int i, j;
719 	int colon_present = 0;
720 
721 	if (strstr(str_bdaddr, ":"))
722 		colon_present = 1;
723 
724 	bdbyte[2] = '\0';
725 
726 	/* Reverse the BDADDR to LSB first */
727 	for (i = 0, j = 5; i < 6; i++, j--) {
728 		bdbyte[0] = str_byte[0];
729 		bdbyte[1] = str_byte[1];
730 		bdaddr[j] = strtol(bdbyte, NULL, 16);
731 
732 		if (colon_present == 1)
733 			str_byte += 3;
734 		else
735 			str_byte += 2;
736 	}
737 }
738 
write_bdaddr(int pConfig,char * bdaddr)739 static int write_bdaddr(int pConfig, char *bdaddr)
740 {
741 	uint8_t *event;
742 	int err;
743 	uint8_t cmd[13];
744 	uint8_t *ptr = cmd;
745 	hci_command_hdr *ch = (void *)cmd;
746 
747 	memset(cmd, 0, sizeof(cmd));
748 
749 	ch->opcode = htobs(cmd_opcode_pack(HCI_VENDOR_CMD_OGF,
750 						HCI_PS_CMD_OCF));
751 	ch->plen = 10;
752 	ptr += HCI_COMMAND_HDR_SIZE;
753 
754 	ptr[0] = 0x01;
755 	ptr[1] = 0x01;
756 	ptr[2] = 0x00;
757 	ptr[3] = 0x06;
758 
759 	convert_bdaddr(bdaddr, (char *)&ptr[4]);
760 
761 	err = send_hci_cmd_sync(pConfig, cmd, sizeof(cmd), &event);
762 	if (err < 0)
763 		return err;
764 
765 	err = read_ps_event(event, HCI_PS_CMD_OCF);
766 
767 	free(event);
768 
769 	return err;
770 }
771 
772 #define BDADDR_FILE "ar3kbdaddr.pst"
773 
write_bdaddr_from_file(int rom_version,int fd)774 static void write_bdaddr_from_file(int rom_version, int fd)
775 {
776 	FILE *stream;
777 	char bdaddr[PATH_MAX];
778 	char bdaddr_file[PATH_MAX];
779 
780 	snprintf(bdaddr_file, MAXPATHLEN, "%s%x/%s",
781 			FW_PATH, rom_version, BDADDR_FILE);
782 
783 	stream = fopen(bdaddr_file, "r");
784 	if (!stream)
785 		return;
786 
787 	if (fgets(bdaddr, PATH_MAX - 1, stream))
788 		write_bdaddr(fd, bdaddr);
789 
790 	fclose(stream);
791 }
792 
ath_ps_download(int fd)793 static int ath_ps_download(int fd)
794 {
795 	int err = 0;
796 	int tag_count;
797 	int patch_count = 0;
798 	uint32_t rom_version = 0;
799 	uint32_t build_version = 0;
800 	uint32_t dev_type = 0;
801 	char patch_file[PATH_MAX];
802 	char ps_file[PATH_MAX];
803 	FILE *stream;
804 
805 	/*
806 	 * Verfiy firmware version. depending on it select the PS
807 	 * config file to download.
808 	 */
809 	if (get_device_type(fd, &dev_type) < 0) {
810 		err = -EILSEQ;
811 		goto download_cmplete;
812 	}
813 
814 	if (read_ath3k_version(fd, &rom_version, &build_version) < 0) {
815 		err = -EILSEQ;
816 		goto download_cmplete;
817 	}
818 
819 	/* Do not download configuration if CRC passes */
820 	if (get_ath3k_crc(fd) < 0) {
821 		err = 0;
822 		goto download_cmplete;
823 	}
824 
825 	get_ps_file_name(dev_type, rom_version, ps_file);
826 	get_patch_file_name(dev_type, rom_version, build_version, patch_file);
827 
828 	stream = fopen(ps_file, "r");
829 	if (!stream) {
830 		perror("firmware file open error\n");
831 		err = -EILSEQ;
832 		goto download_cmplete;
833 	}
834 	tag_count = ath_parse_ps(stream);
835 
836 	fclose(stream);
837 
838 	if (tag_count < 0) {
839 		err = -EILSEQ;
840 		goto download_cmplete;
841 	}
842 
843 	/*
844 	 * It is not necessary that Patch file be available,
845 	 * continue with PS Operations if patch file is not available.
846 	 */
847 	if (patch_file[0] == '\0')
848 		err = 0;
849 
850 	stream = fopen(patch_file, "r");
851 	if (!stream)
852 		err = 0;
853 	else {
854 		patch_count = ps_patch_download(fd, stream);
855 		fclose(stream);
856 
857 		if (patch_count < 0) {
858 			err = -EILSEQ;
859 			goto download_cmplete;
860 		}
861 	}
862 
863 	err = ps_config_download(fd, tag_count);
864 
865 download_cmplete:
866 	if (!err)
867 		write_bdaddr_from_file(rom_version, fd);
868 
869 	return err;
870 }
871 
872 #define HCI_SLEEP_CMD_OCF     0x04
873 
874 /*
875  * Atheros AR300x specific initialization post callback
876  */
ath3k_post(int fd,int pm)877 int ath3k_post(int fd, int pm)
878 {
879 	int dev_id, dd;
880 	struct timespec tm = { 0, 50000 };
881 
882 	sleep(1);
883 
884 	dev_id = ioctl(fd, HCIUARTGETDEVICE, 0);
885 	if (dev_id < 0) {
886 		perror("cannot get device id");
887 		return dev_id;
888 	}
889 
890 	dd = hci_open_dev(dev_id);
891 	if (dd < 0) {
892 		perror("HCI device open failed");
893 		return dd;
894 	}
895 
896 	if (ioctl(dd, HCIDEVUP, dev_id) < 0 && errno != EALREADY) {
897 		perror("hci down:Power management Disabled");
898 		hci_close_dev(dd);
899 		return -1;
900 	}
901 
902 	/* send vendor specific command with Sleep feature Enabled */
903 	if (hci_send_cmd(dd, OGF_VENDOR_CMD, HCI_SLEEP_CMD_OCF,	1, &pm) < 0)
904 		perror("PM command failed, power management Disabled");
905 
906 	nanosleep(&tm, NULL);
907 	hci_close_dev(dd);
908 
909 	return 0;
910 }
911 
912 #define HCI_VENDOR_CMD_OGF    0x3F
913 #define HCI_PS_CMD_OCF        0x0B
914 #define HCI_CHG_BAUD_CMD_OCF  0x0C
915 
916 #define WRITE_BDADDR_CMD_LEN 14
917 #define WRITE_BAUD_CMD_LEN   6
918 #define MAX_CMD_LEN          WRITE_BDADDR_CMD_LEN
919 
set_cntrlr_baud(int fd,int speed)920 static int set_cntrlr_baud(int fd, int speed)
921 {
922 	int baud;
923 	struct timespec tm = { 0, 500000 };
924 	unsigned char cmd[MAX_CMD_LEN], rsp[HCI_MAX_EVENT_SIZE];
925 	unsigned char *ptr = cmd + 1;
926 	hci_command_hdr *ch = (void *)ptr;
927 
928 	cmd[0] = HCI_COMMAND_PKT;
929 
930 	/* set controller baud rate to user specified value */
931 	ptr = cmd + 1;
932 	ch->opcode = htobs(cmd_opcode_pack(HCI_VENDOR_CMD_OGF,
933 						HCI_CHG_BAUD_CMD_OCF));
934 	ch->plen = 2;
935 	ptr += HCI_COMMAND_HDR_SIZE;
936 
937 	baud = speed/100;
938 	ptr[0] = (char)baud;
939 	ptr[1] = (char)(baud >> 8);
940 
941 	if (write(fd, cmd, WRITE_BAUD_CMD_LEN) != WRITE_BAUD_CMD_LEN) {
942 		perror("Failed to write change baud rate command");
943 		return -ETIMEDOUT;
944 	}
945 
946 	nanosleep(&tm, NULL);
947 
948 	if (read_hci_event(fd, rsp, sizeof(rsp)) < 0)
949 		return -ETIMEDOUT;
950 
951 	return 0;
952 }
953 
954 /*
955  * Atheros AR300x specific initialization and configuration file
956  * download
957  */
ath3k_init(int fd,int speed,int init_speed,char * bdaddr,struct termios * ti)958 int ath3k_init(int fd, int speed, int init_speed, char *bdaddr,
959 						struct termios *ti)
960 {
961 	int r;
962 	int err = 0;
963 	struct timespec tm = { 0, 500000 };
964 	unsigned char cmd[MAX_CMD_LEN], rsp[HCI_MAX_EVENT_SIZE];
965 	unsigned char *ptr = cmd + 1;
966 	hci_command_hdr *ch = (void *)ptr;
967 
968 	cmd[0] = HCI_COMMAND_PKT;
969 
970 	/* set both controller and host baud rate to maximum possible value */
971 	err = set_cntrlr_baud(fd, speed);
972 	if (err < 0)
973 		return err;
974 
975 	err = set_speed(fd, ti, speed);
976 	if (err < 0) {
977 		perror("Can't set required baud rate");
978 		return err;
979 	}
980 
981 	/* Download PS and patch */
982 	r = ath_ps_download(fd);
983 	if (r < 0) {
984 		perror("Failed to Download configuration");
985 		err = -ETIMEDOUT;
986 		goto failed;
987 	}
988 
989 	/* Write BDADDR */
990 	if (bdaddr) {
991 		ch->opcode = htobs(cmd_opcode_pack(HCI_VENDOR_CMD_OGF,
992 							HCI_PS_CMD_OCF));
993 		ch->plen = 10;
994 		ptr += HCI_COMMAND_HDR_SIZE;
995 
996 		ptr[0] = 0x01;
997 		ptr[1] = 0x01;
998 		ptr[2] = 0x00;
999 		ptr[3] = 0x06;
1000 		str2ba(bdaddr, (bdaddr_t *)(ptr + 4));
1001 
1002 		if (write(fd, cmd, WRITE_BDADDR_CMD_LEN) !=
1003 					WRITE_BDADDR_CMD_LEN) {
1004 			perror("Failed to write BD_ADDR command\n");
1005 			err = -ETIMEDOUT;
1006 			goto failed;
1007 		}
1008 
1009 		if (read_hci_event(fd, rsp, sizeof(rsp)) < 0) {
1010 			perror("Failed to set BD_ADDR\n");
1011 			err = -ETIMEDOUT;
1012 			goto failed;
1013 		}
1014 	}
1015 
1016 	/* Send HCI Reset */
1017 	cmd[1] = 0x03;
1018 	cmd[2] = 0x0C;
1019 	cmd[3] = 0x00;
1020 
1021 	r = write(fd, cmd, 4);
1022 	if (r != 4) {
1023 		err = -ETIMEDOUT;
1024 		goto failed;
1025 	}
1026 
1027 	nanosleep(&tm, NULL);
1028 	if (read_hci_event(fd, rsp, sizeof(rsp)) < 0) {
1029 		err = -ETIMEDOUT;
1030 		goto failed;
1031 	}
1032 
1033 	err = set_cntrlr_baud(fd, speed);
1034 	if (err < 0)
1035 		return err;
1036 
1037 failed:
1038 	if (err < 0) {
1039 		set_cntrlr_baud(fd, init_speed);
1040 		set_speed(fd, ti, init_speed);
1041 	}
1042 
1043 	return err;
1044 }
1045