CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
orangepi-xunlong

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: orangepi-xunlong/orangepi-build
Path: blob/next/external/cache/sources/hcitools/hciattach_ath3k.c
Views: 3959
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
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
*/
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
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
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 */
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 */
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
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
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
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 */
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
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
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
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
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
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
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
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
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
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
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
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
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
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
*/
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
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
*/
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
1046