1 /******************************************************************************
2 *
3 * Copyright (C) 2009-2018 Realtek Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 #define LOG_TAG "bt_hwcfg_uart"
20 #define RTKBT_RELEASE_NAME "20190717_BT_ANDROID_9.0"
21
22 #include <utils/Log.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <signal.h>
26 #include <time.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <dirent.h>
30 #include <ctype.h>
31 #include <stdlib.h>
32 #include <unistd.h>
33 #include <endian.h>
34 #include <byteswap.h>
35 #include <unistd.h>
36 #include "bt_hci_bdroid.h"
37 #include "bt_vendor_rtk.h"
38 #include "userial.h"
39 #include "userial_vendor.h"
40 #include "upio.h"
41
42 #include "bt_vendor_lib.h"
43 #include "hardware.h"
44
45 /******************************************************************************
46 ** Constants & Macros
47 ******************************************************************************/
48
49 void hw_config_cback(void *p_evt_buf);
50
51 #define EXTRA_CONFIG_FILE "/vendor/etc/bluetooth/rtk_btconfig.txt"
52 static struct rtk_bt_vendor_config_entry *extra_extry;
53 static struct rtk_bt_vendor_config_entry *extra_entry_inx = NULL;
54
55 /******************************************************************************
56 ** Static variables
57 ******************************************************************************/
58
59 #ifdef BT_CHIP_PROBE_SIMULATION
60 static bt_hw_cfg_cb_t hw_cfg_test;
61 struct bt_chip_char {
62 uint16_t lmp_subversion;
63 uint8_t hci_version;
64 uint8_t hci_revision;
65 uint8_t chip_type;
66 };
67 struct bt_chip_char bt_chip_chars[] = {
68 {0x8723, 0x4, 0xb, CHIPTYPE_NONE}, // 8703as
69 {0x8723, 0x6, 0xb, CHIPTYPE_NONE}, // 8723bs
70 {0x8703, 0x4, 0xd, 0x7}, // 8703bs
71 {0x8703, 0x6, 0xb, 0x3}, // 8723cs-cg
72 {0x8703, 0x6, 0xb, 0x4}, // 8723cs-vf
73 {0x8703, 0x6, 0xb, 0x5}, // 8723cs-xx
74 {0x8723, 0x6, 0xd, CHIPTYPE_NONE}, // 8723ds
75 };
76 #endif
77
78 typedef struct {
79 uint16_t lmp_subversion;
80 uint32_t hci_version_mask;
81 uint32_t hci_revision_mask;
82 uint32_t chip_type_mask;
83 uint32_t project_id_mask;
84 char *patch_name;
85 char *config_name;
86 uint16_t mac_offset;
87 uint32_t max_patch_size;
88 } patch_info;
89
90 static patch_info patch_table[] = {
91 /* lmp_subv hci_version_mask
92 hci_revision_mask chip_type_mask
93 project_id_mask fw name
94 config name mac offset
95 max_patch_size */
96 {0x1200, HCI_VERSION_MASK_ALL, HCI_REVISION_MASK_ALL, CHIP_TYPE_MASK_ALL, 1 << 0, "rtl8723as_fw",
97 "rtl8723as_config", CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, // Rtl8723AS
98
99 {0x8723, ~(HCI_VERSION_MASK_21), ~(1 << 0xd), CHIP_TYPE_MASK_ALL, 1 << 1, "rtl8723bs_fw", "rtl8723bs_config",
100 CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, // Rtl8723BS
101 {0x8821, HCI_VERSION_MASK_ALL, ~(1 << 0xc), CHIP_TYPE_MASK_ALL, 1 << 2, "rtl8821as_fw", "rtl8821as_config",
102 CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, // Rtl8821AS
103 {0x8761, HCI_VERSION_MASK_ALL, ~(1 << 0xb), CHIP_TYPE_MASK_ALL, 1 << 3, "rtl8761at_fw", "rtl8761at_config",
104 CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, // Rtl8761AW
105 {0x8761, HCI_VERSION_MASK_ALL, (1 << 0xb), CHIP_TYPE_MASK_ALL, 1 << 14, "rtl8761bt_fw", "rtl8761bt_config",
106 CONFIG_MAC_OFFSET_GEN_4PLUS, MAX_PATCH_SIZE_40K}, // Rtl8761BW
107
108 {0x8723, HCI_VERSION_MASK_21, HCI_REVISION_MASK_ALL, CHIP_TYPE_MASK_ALL, 1 << 4, "rtl8703as_fw", "rtl8703as_config",
109 CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, // Rtl8703AS
110
111 {0x8703, HCI_VERSION_MASK_ALL, HCI_REVISION_MASK_ALL, 1 << 7, 1 << 6, "rtl8703bs_fw", "rtl8703bs_config",
112 CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_24K}, // Rtl8703BS
113 {0x8703, HCI_VERSION_MASK_ALL, HCI_REVISION_MASK_ALL, 1 << 5, 1 << 7, "rtl8723cs_xx_fw", "rtl8723cs_xx_config",
114 CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_24K}, // rtl8723cs_xx
115 {0x8703, HCI_VERSION_MASK_ALL, HCI_REVISION_MASK_ALL, 1 << 3, 1 << 7, "rtl8723cs_cg_fw", "rtl8723cs_cg_config",
116 CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_24K}, // rtl8723cs_cg
117 {0x8703, HCI_VERSION_MASK_ALL, HCI_REVISION_MASK_ALL, 1 << 4, 1 << 7, "rtl8723cs_vf_fw", "rtl8723cs_vf_config",
118 CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_24K}, // rtl8723cs_vf
119 {0x8822, HCI_VERSION_MASK_ALL, ~(1 << 0xc), CHIP_TYPE_MASK_ALL, 1 << 8, "rtl8822bs_fw", "rtl8822bs_config",
120 CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_24K}, // Rtl8822BS
121 {0x8822, HCI_VERSION_MASK_ALL, (1 << 0xc), CHIP_TYPE_MASK_ALL, 1 << 13, "rtl8822cs_fw", "rtl8822cs_config",
122 CONFIG_MAC_OFFSET_GEN_4PLUS, MAX_PATCH_SIZE_40K}, // Rtl8822CS
123
124 {0x8723, HCI_VERSION_MASK_ALL, (1 << 0xd), ~(1 << 7), 1 << 9, "rtl8723ds_fw", "rtl8723ds_config",
125 CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_40K}, // Rtl8723ds
126 {0x8723, HCI_VERSION_MASK_ALL, (1 << 0xd), 1 << 7, 1 << 9, "rtl8703cs_fw", "rtl8703cs_config",
127 CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_40K}, // Rtl8703cs
128 {0x8821, HCI_VERSION_MASK_ALL, (1 << 0xc), CHIP_TYPE_MASK_ALL, 1 << 10, "rtl8821cs_fw", "rtl8821cs_config",
129 CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_40K}, // RTL8821CS
130 /* todo: RTL8703CS */
131
132 {LMP_SUBVERSION_NONE, HCI_VERSION_MASK_ALL, HCI_REVISION_MASK_ALL, CHIP_TYPE_MASK_ALL, PROJECT_ID_MASK_ALL,
133 "rtl_none_fw", "rtl_none_config", CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}};
134
135 // signature: realtech
136 static const uint8_t RTK_EPATCH_SIGNATURE[8] = {0x52, 0x65, 0x61, 0x6C, 0x74, 0x65, 0x63, 0x68};
137 // Extension Section IGNATURE:0x77FD0451
138 static const uint8_t EXTENSION_SECTION_SIGNATURE[4] = {0x51, 0x04, 0xFD, 0x77};
139
check_match_state(bt_hw_cfg_cb_t * cfg,uint32_t mask)140 static int check_match_state(bt_hw_cfg_cb_t *cfg, uint32_t mask)
141 {
142 patch_info *patch_entry;
143 int res = 0;
144
145 for (patch_entry = patch_table; patch_entry->lmp_subversion != LMP_SUBVERSION_NONE; patch_entry++) {
146 if (patch_entry->lmp_subversion != cfg->lmp_subversion) {
147 continue;
148 }
149 if ((patch_entry->hci_version_mask != HCI_VERSION_MASK_ALL) &&
150 ((patch_entry->hci_version_mask & (1 << cfg->hci_version)) == 0)) {
151 continue;
152 }
153 if ((patch_entry->hci_revision_mask != HCI_REVISION_MASK_ALL) &&
154 ((patch_entry->hci_revision_mask & (1 << cfg->hci_revision)) == 0)) {
155 continue;
156 }
157 if ((mask & PATCH_OPTIONAL_MATCH_FLAG_CHIPTYPE) && (patch_entry->chip_type_mask != CHIP_TYPE_MASK_ALL) &&
158 ((patch_entry->chip_type_mask & (1 << cfg->chip_type)) == 0)) {
159 continue;
160 }
161 res++;
162 }
163 HILOGI("check_match_state return %d(cfg->lmp_subversion:0x%x cfg->hci_vesion:0x%x cfg->hci_revision:0x%x "
164 "cfg->chip_type:0x%x mask:%08x)\n",
165 res, cfg->lmp_subversion, cfg->hci_version, cfg->hci_revision, cfg->chip_type, mask);
166 return res;
167 }
168
get_patch_entry(bt_hw_cfg_cb_t * cfg)169 static patch_info *get_patch_entry(bt_hw_cfg_cb_t *cfg)
170 {
171 patch_info *patch_entry;
172
173 HILOGI("get_patch_entry(lmp_subversion:0x%x hci_vesion:0x%x cfg->hci_revision:0x%x chip_type:0x%x)\n",
174 cfg->lmp_subversion, cfg->hci_version, cfg->hci_revision, cfg->chip_type);
175 for (patch_entry = patch_table; patch_entry->lmp_subversion != LMP_SUBVERSION_NONE; patch_entry++) {
176 if (patch_entry->lmp_subversion != cfg->lmp_subversion) {
177 continue;
178 }
179 if ((patch_entry->hci_version_mask != HCI_VERSION_MASK_ALL) &&
180 ((patch_entry->hci_version_mask & (1 << cfg->hci_version)) == 0)) {
181 continue;
182 }
183 if ((patch_entry->hci_revision_mask != HCI_REVISION_MASK_ALL) &&
184 ((patch_entry->hci_revision_mask & (1 << cfg->hci_revision)) == 0)) {
185 continue;
186 }
187 if ((patch_entry->chip_type_mask != CHIP_TYPE_MASK_ALL) &&
188 ((patch_entry->chip_type_mask & (1 << cfg->chip_type)) == 0)) {
189 continue;
190 }
191 break;
192 }
193 HILOGI("get_patch_entry return(patch_name:%s config_name:%s mac_offset:0x%x)\n", patch_entry->patch_name,
194 patch_entry->config_name, patch_entry->mac_offset);
195 return patch_entry;
196 }
197
198 typedef struct _baudrate_ex {
199 uint32_t rtk_speed;
200 uint32_t uart_speed;
201 } baudrate_ex;
202
203 baudrate_ex baudrates[] = {
204 {0x00006004, 921600}, {0x05F75004, 921600}, // RTL8723BS
205 {0x00004003, 1500000}, {0x052A8002, 1500000}, // RTL8723BS
206 {0x04928002, 1500000}, // RTL8722CS
207 {0x00005002, 2000000}, // same as RTL8723AS
208 {0x00008001, 3000000}, {0x04928001, 3000000}, // RTL8723BS
209 {0x06B58001, 3000000}, // add RTL8703as
210 {0x00007001, 3500000}, {0x052A6001, 3500000}, // RTL8723BS
211 {0x00005001, 4000000}, // same as RTL8723AS
212 {0x0000701d, 115200}, {0x0252C014, 115200} // RTL8723BS
213 };
214
215 /**
216 * Change realtek Bluetooth speed to uart speed. It is matching in the struct baudrates:
217 *
218 * @code
219 * baudrate_ex baudrates[] =
220 * {
221 * {0x7001, 3500000},
222 * {0x6004, 921600},
223 * {0x4003, 1500000},
224 * {0x5001, 4000000},
225 * {0x5002, 2000000},
226 * {0x8001, 3000000},
227 * {0x701d, 115200}
228 * };
229 * @endcode
230 *
231 * If there is no match in baudrates, uart speed will be set as #115200.
232 *
233 * @param rtk_speed realtek Bluetooth speed
234 * @param uart_speed uart speed
235 *
236 */
rtk_speed_to_uart_speed(uint32_t rtk_speed,uint32_t * uart_speed)237 static void rtk_speed_to_uart_speed(uint32_t rtk_speed, uint32_t *uart_speed)
238 {
239 #define UART_SPEED 115200
240 *uart_speed = UART_SPEED;
241
242 uint8_t i;
243 for (i = 0; i < sizeof(baudrates) / sizeof(baudrate_ex); i++) {
244 if (baudrates[i].rtk_speed == rtk_speed) {
245 *uart_speed = baudrates[i].uart_speed;
246 return;
247 }
248 }
249 return;
250 }
251
252 /**
253 * Change uart speed to realtek Bluetooth speed. It is matching in the struct baudrates:
254 *
255 * @code
256 * baudrate_ex baudrates[] =
257 * {
258 * {0x7001, 3500000},
259 * {0x6004, 921600},
260 * {0x4003, 1500000},
261 * {0x5001, 4000000},
262 * {0x5002, 2000000},
263 * {0x8001, 3000000},
264 * {0x701d, 115200}
265 * };
266 * @endcode
267 *
268 * If there is no match in baudrates, realtek Bluetooth speed will be set as #0x701D.
269 *
270 * @param uart_speed uart speed
271 * @param rtk_speed realtek Bluetooth speed
272 *
273 */
274
275 /*******************************************************************************
276 **
277 ** Function hw_config_set_bdaddr
278 **
279 ** Description Program controller's Bluetooth Device Address
280 **
281 ** Returns TRUE, if valid address is sent
282 ** FALSE, otherwise
283 **
284 *******************************************************************************/
hw_config_set_controller_baudrate(HC_BT_HDR * p_buf,uint32_t baudrate)285 static uint8_t hw_config_set_controller_baudrate(HC_BT_HDR *p_buf, uint32_t baudrate)
286 {
287 uint8_t retval = FALSE;
288 uint8_t *p = (uint8_t *)(p_buf + 1);
289
290 UINT16_TO_STREAM(p, HCI_VSC_UPDATE_BAUDRATE);
291 #define PARAMETER_LENGTH 4
292 *p++ = PARAMETER_LENGTH; /* parameter length */
293 UINT32_TO_STREAM(p, baudrate);
294
295 #define HCI_CMD_PREAMBLE_SIZE_INCREMENT 4
296 p_buf->len = HCI_CMD_PREAMBLE_SIZE + HCI_CMD_PREAMBLE_SIZE_INCREMENT;
297
298 retval = bt_vendor_cbacks->xmit_cb(HCI_VSC_UPDATE_BAUDRATE, p_buf);
299
300 return (retval);
301 }
302
303 /*******************************************************************************
304 **
305 ** Function line_speed_to_userial_baud
306 **
307 ** Description helper function converts line speed number into USERIAL baud
308 ** rate symbol
309 **
310 ** Returns unit8_t (USERIAL baud symbol)
311 **
312 *******************************************************************************/
313
314 #define LINE_SPEED_4M 4000000
315 #define LINE_SPEED_3M 3000000
316 #define LINE_SPEED_2M 2000000
317 #define LINE_SPEED_1_5M 1500000
318 #define LINE_SPEED_1M 4000000
319 #define LINE_SPEED_921600 921600
320 #define LINE_SPEED_460800 460800
321 #define LINE_SPEED_230400 230400
322 #define LINE_SPEED_115200 115200
323 #define LINE_SPEED_57600 57600
324 #define LINE_SPEED_19200 19200
325 #define LINE_SPEED_9600 9600
326 #define LINE_SPEED_1200 1200
327 #define LINE_SPEED_600 600
328
line_speed_to_userial_baud(uint32_t line_speed)329 static uint8_t line_speed_to_userial_baud(uint32_t line_speed)
330 {
331 uint8_t baud;
332
333 if (line_speed == LINE_SPEED_4M) {
334 baud = USERIAL_BAUD_4M;
335 } else if (line_speed == LINE_SPEED_3M) {
336 baud = USERIAL_BAUD_3M;
337 } else if (line_speed == LINE_SPEED_2M) {
338 baud = USERIAL_BAUD_2M;
339 } else if (line_speed == LINE_SPEED_1_5M) {
340 baud = USERIAL_BAUD_1_5M;
341 } else if (line_speed == LINE_SPEED_1M) {
342 baud = USERIAL_BAUD_1M;
343 } else if (line_speed == LINE_SPEED_921600) {
344 baud = USERIAL_BAUD_921600;
345 } else if (line_speed == LINE_SPEED_460800) {
346 baud = USERIAL_BAUD_460800;
347 } else if (line_speed == LINE_SPEED_230400) {
348 baud = USERIAL_BAUD_230400;
349 } else if (line_speed == LINE_SPEED_115200) {
350 baud = USERIAL_BAUD_115200;
351 } else if (line_speed == LINE_SPEED_57600) {
352 baud = USERIAL_BAUD_57600;
353 } else if (line_speed == LINE_SPEED_19200) {
354 baud = USERIAL_BAUD_19200;
355 } else if (line_speed == LINE_SPEED_9600) {
356 baud = USERIAL_BAUD_9600;
357 } else if (line_speed == LINE_SPEED_1200) {
358 baud = USERIAL_BAUD_1200;
359 } else if (line_speed == LINE_SPEED_600) {
360 baud = USERIAL_BAUD_600;
361 } else {
362 HILOGE("userial vendor: unsupported baud speed %d", line_speed);
363 baud = USERIAL_BAUD_115200;
364 }
365
366 return baud;
367 }
368
369 /**
370 * Change uart speed to realtek Bluetooth speed. It is matching in the struct baudrates:
371 *
372 * @code
373 * baudrate_ex baudrates[] =
374 * {
375 * {0x7001, 3500000},
376 * {0x6004, 921600},
377 * {0x4003, 1500000},
378 * {0x5001, 4000000},
379 * {0x5002, 2000000},
380 * {0x8001, 3000000},
381 * {0x701d, 115200}
382 * };
383 * @endcode
384 *
385 * If there is no match in baudrates, realtek Bluetooth speed will be set as #0x701D.
386 *
387 * @param uart_speed uart speed
388 * @param rtk_speed realtek Bluetooth speed
389 *
390 */
391
line_process(char * buf,unsigned short * offset,int * t)392 static void line_process(char *buf, unsigned short *offset, int *t)
393 {
394 char *head = buf;
395 char *ptr = buf;
396 char *argv[32];
397 int argc = 0;
398 unsigned char len = 0;
399 int i = 0;
400 static int alt_size = 0;
401
402 if (buf[0] == '\0' || buf[0] == '#' || buf[0] == '[') {
403 return;
404 }
405 #define MAX_ALT_CONFIG_SIZE_DECREMENT 4
406 if (alt_size > MAX_ALT_CONFIG_SIZE - MAX_ALT_CONFIG_SIZE_DECREMENT) {
407 HILOGW("Extra Config file is too large");
408 return;
409 }
410 if (extra_entry_inx == NULL) {
411 extra_entry_inx = extra_extry;
412 }
413 HILOGI("line_process:%s", buf);
414 while ((ptr = strsep(&head, ", \t")) != NULL) {
415 if (!ptr[0]) {
416 continue;
417 }
418 argv[argc++] = ptr;
419 #define ARGC_32 32
420 if (argc >= ARGC_32) {
421 HILOGW("Config item is too long");
422 break;
423 }
424 }
425
426 #define ARGC_4 4
427 if (argc < ARGC_4) {
428 HILOGE("Invalid Config item, ignore");
429 return;
430 }
431
432 #define STRTOUL_PARAMETER_3 16
433 offset[(*t)] = (unsigned short)((strtoul(argv[0], NULL, STRTOUL_PARAMETER_3)) |
434 (strtoul(argv[1], NULL, STRTOUL_PARAMETER_3) << 8L));
435 HILOGI("Extra Config offset %04x", offset[(*t)]);
436 extra_entry_inx->offset = offset[(*t)];
437 (*t)++;
438 len = (unsigned char)strtoul(argv[2L], NULL, STRTOUL_PARAMETER_3);
439 #define ARGC_DECREMENT_3 3
440 if (len != (unsigned char)(argc - ARGC_DECREMENT_3)) {
441 HILOGE("Extra Config item len %d is not match, we assume the actual len is %d", len, (argc - ARGC_DECREMENT_3));
442 len = argc - ARGC_DECREMENT_3;
443 }
444 extra_entry_inx->entry_len = len;
445
446 alt_size += len + sizeof(struct rtk_bt_vendor_config_entry);
447 if (alt_size > MAX_ALT_CONFIG_SIZE) {
448 HILOGW("Extra Config file is too large");
449 extra_entry_inx->offset = 0;
450 extra_entry_inx->entry_len = 0;
451 alt_size -= (len + sizeof(struct rtk_bt_vendor_config_entry));
452 return;
453 }
454 for (i = 0; i < len; i++) {
455 #define ARGV_3 3
456 extra_entry_inx->entry_data[i] = (uint8_t)strtoul(argv[ARGV_3 + i], NULL, STRTOUL_PARAMETER_3);
457 HILOGI("data[%d]:%02x", i, extra_entry_inx->entry_data[i]);
458 }
459 extra_entry_inx = (struct rtk_bt_vendor_config_entry *)((uint8_t *)extra_entry_inx + len +
460 sizeof(struct rtk_bt_vendor_config_entry));
461 }
462
parse_extra_config(const char * path,patch_info * patch_entry,unsigned short * offset,int * t)463 static void parse_extra_config(const char *path, patch_info *patch_entry, unsigned short *offset, int *t)
464 {
465 int fd, ret;
466 unsigned char buf[1024];
467
468 fd = open(path, O_RDONLY);
469 if (fd == -1) {
470 HILOGI("Couldn't open extra config %s, err:%s", path, strerror(errno));
471 return;
472 }
473
474 ret = read(fd, buf, sizeof(buf));
475 if (ret == -1) {
476 HILOGE("Couldn't read %s, err:%s", path, strerror(errno));
477 close(fd);
478 return;
479 } else if (ret == 0) {
480 HILOGE("%s is empty", path);
481 close(fd);
482 return;
483 }
484
485 #define RET_1022 1022
486 if (ret > RET_1022) {
487 HILOGE("Extra config file is too big");
488 close(fd);
489 return;
490 }
491 buf[ret++] = '\n';
492 buf[ret++] = '\0';
493 close(fd);
494 char *head = (void *)buf;
495 char *ptr = (void *)buf;
496 ptr = strsep(&head, "\n\r");
497 if (strncmp(ptr, patch_entry->config_name, strlen(ptr))) {
498 HILOGW("Extra config file not set for %s, ignore", patch_entry->config_name);
499 return;
500 }
501 while ((ptr = strsep(&head, "\n\r")) != NULL) {
502 if (!ptr[0]) {
503 continue;
504 }
505 line_process(ptr, offset, t);
506 }
507 }
508
509 // (patch_info *patch_entry, unsigned short *offset, int max_group_cnt)
getAltSettings(patch_info * patch_entry,unsigned short * offset)510 static inline int getAltSettings(patch_info *patch_entry, unsigned short *offset)
511 {
512 int n = 0;
513 if (patch_entry) {
514 offset[n++] = patch_entry->mac_offset;
515 } else {
516 return n;
517 }
518 /*
519 //sample code, add special settings
520
521 offset[n++] = 0x15B;
522 */
523 if (extra_extry) {
524 parse_extra_config(EXTRA_CONFIG_FILE, patch_entry, offset, &n);
525 }
526
527 return n;
528 }
529
530 #define VAL_5 5
531 #define VAL_4 4
532 #define VAL_3 3
533 #define VAL_2 2
534 #define VAL_1 1
535 #define VAL_0 0
536
getAltSettingVal(patch_info * patch_entry,unsigned short offset,unsigned char * val)537 static inline int getAltSettingVal(patch_info *patch_entry, unsigned short offset, unsigned char *val)
538 {
539 int res = 0;
540 int i = 0;
541 struct rtk_bt_vendor_config_entry *ptr = extra_extry;
542
543 while (ptr->offset) {
544 if (ptr->offset == offset) {
545 if (offset != patch_entry->mac_offset) {
546 (void)memcpy_s(val, ptr->entry_len, ptr->entry_data, ptr->entry_len);
547 res = ptr->entry_len;
548 HILOGI("Get Extra offset:%04x, val:", offset);
549 for (i = 0; i < ptr->entry_len; i++) {
550 HILOGI("%02x", ptr->entry_data[i]);
551 }
552 }
553 break;
554 }
555 ptr = (struct rtk_bt_vendor_config_entry *)((uint8_t *)ptr + ptr->entry_len +
556 sizeof(struct rtk_bt_vendor_config_entry));
557 }
558
559 if ((patch_entry) && (offset == patch_entry->mac_offset) && (res == 0)) {
560 if (getmacaddr(val) == 0) {
561 HILOGI("MAC: %02x:%02x:%02x:%02x:%02x:%02x", val[VAL_5], val[VAL_4], val[VAL_3], val[VAL_2], val[VAL_1],
562 val[VAL_0]);
563 #define RES 6
564 res = RES;
565 }
566 }
567 return res;
568 }
569
rtk_update_altsettings(patch_info * patch_entry,unsigned char * config_buf_ptr,size_t * config_len_ptr)570 static void rtk_update_altsettings(patch_info *patch_entry, unsigned char *config_buf_ptr, size_t *config_len_ptr)
571 {
572 unsigned short offset[256], data_len;
573 unsigned char val[256];
574
575 struct rtk_bt_vendor_config *config = (struct rtk_bt_vendor_config *)config_buf_ptr;
576 struct rtk_bt_vendor_config_entry *entry = config->entry;
577 size_t config_len = *config_len_ptr;
578 unsigned int i = 0;
579 int count = 0, temp = 0, j;
580
581 if ((extra_extry = (struct rtk_bt_vendor_config_entry *)malloc(MAX_ALT_CONFIG_SIZE)) == NULL) {
582 HILOGE("malloc buffer for extra_extry failed");
583 } else {
584 (void)memset_s(extra_extry, MAX_ALT_CONFIG_SIZE, 0, MAX_ALT_CONFIG_SIZE);
585 }
586
587 HILOGI("ORG Config len=%08zx:\n", config_len);
588 for (i = 0; i <= config_len; i += 0x10) {
589 HILOGI("%08x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", i,
590 config_buf_ptr[i], config_buf_ptr[i + 1], config_buf_ptr[i + 2L],
591 config_buf_ptr[i + 3L], config_buf_ptr[i + 4L],
592 config_buf_ptr[i + 5L], config_buf_ptr[i + 6L],
593 config_buf_ptr[i + 7L], config_buf_ptr[i + 8L],
594 config_buf_ptr[i + 9L], config_buf_ptr[i + 10L],
595 config_buf_ptr[i + 11L], config_buf_ptr[i + 12L],
596 config_buf_ptr[i + 13L], config_buf_ptr[i + 14L],
597 config_buf_ptr[i + 15L]);
598 }
599
600 (void)memset_s(offset, sizeof(offset), 0, sizeof(offset));
601 (void)memset_s(val, sizeof(val), 0, sizeof(val));
602 data_len = le16_to_cpu(config->data_len);
603
604 count = getAltSettings(patch_entry, offset);
605 if (count <= 0) {
606 HILOGI("rtk_update_altsettings: No AltSettings");
607 return;
608 } else {
609 HILOGI("rtk_update_altsettings: %d AltSettings", count);
610 }
611
612 if (data_len != config_len - sizeof(struct rtk_bt_vendor_config)) {
613 HILOGE("rtk_update_altsettings: config len(%x) is not right(%lx)", data_len,
614 (unsigned long)(config_len - sizeof(struct rtk_bt_vendor_config)));
615 return;
616 }
617
618 for (i = 0; i < data_len;) {
619 for (j = 0; j < count; j++) {
620 if (le16_to_cpu(entry->offset) == offset[j]) {
621 if (offset[j] == patch_entry->mac_offset) {
622 offset[j] = 0;
623 } else {
624 struct rtk_bt_vendor_config_entry *t = extra_extry;
625 while (t->offset) {
626 if (t->offset == le16_to_cpu(entry->offset)) {
627 if (t->entry_len == entry->entry_len) {
628 offset[j] = 0;
629 }
630 break;
631 }
632 t = (struct rtk_bt_vendor_config_entry *)((uint8_t *)t + t->entry_len +
633 sizeof(struct rtk_bt_vendor_config_entry));
634 }
635 }
636 }
637 }
638 if (getAltSettingVal(patch_entry, le16_to_cpu(entry->offset), val) == entry->entry_len) {
639 HILOGI("rtk_update_altsettings: replace %04x[%02x]", le16_to_cpu(entry->offset), entry->entry_len);
640 (void)memcpy_s(entry->entry_data, entry->entry_len, val, entry->entry_len);
641 }
642 temp = entry->entry_len + sizeof(struct rtk_bt_vendor_config_entry);
643 i += temp;
644 entry = (struct rtk_bt_vendor_config_entry *)((uint8_t *)entry + temp);
645 }
646 for (j = 0; j < count; j++) {
647 if (offset[j] == 0) {
648 continue;
649 }
650 entry->entry_len = getAltSettingVal(patch_entry, offset[j], val);
651 if (entry->entry_len <= 0) {
652 continue;
653 }
654 entry->offset = cpu_to_le16(offset[j]);
655 (void)memcpy_s(entry->entry_data, entry->entry_len, val, entry->entry_len);
656 HILOGI("rtk_update_altsettings: add %04x[%02x]", le16_to_cpu(entry->offset), entry->entry_len);
657 temp = entry->entry_len + sizeof(struct rtk_bt_vendor_config_entry);
658 i += temp;
659 entry = (struct rtk_bt_vendor_config_entry *)((uint8_t *)entry + temp);
660 }
661 config->data_len = cpu_to_le16(i);
662 *config_len_ptr = i + sizeof(struct rtk_bt_vendor_config);
663
664 if (extra_extry) {
665 free(extra_extry);
666 extra_extry = NULL;
667 extra_entry_inx = NULL;
668 }
669
670 HILOGI("NEW Config len=%08zx:\n", *config_len_ptr);
671 for (i = 0; i <= (*config_len_ptr); i += 0x10) {
672 HILOGI("%08x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", i,
673 config_buf_ptr[i], config_buf_ptr[i + 1], config_buf_ptr[i + 2L],
674 config_buf_ptr[i + 3L], config_buf_ptr[i + 4L],
675 config_buf_ptr[i + 5L], config_buf_ptr[i + 6L],
676 config_buf_ptr[i + 7L], config_buf_ptr[i + 8L],
677 config_buf_ptr[i + 9L], config_buf_ptr[i + 10L],
678 config_buf_ptr[i + 11L], config_buf_ptr[i + 12L],
679 config_buf_ptr[i + 13L], config_buf_ptr[i + 14L],
680 config_buf_ptr[i + 15L]);
681 }
682 return;
683 }
684
rtk_parse_config_file(unsigned char ** config_buf,size_t * filelen,uint8_t bt_addr[6],uint16_t mac_offset)685 static uint32_t rtk_parse_config_file(unsigned char **config_buf, size_t *filelen, uint8_t bt_addr[6],
686 uint16_t mac_offset)
687 {
688 struct rtk_bt_vendor_config *config = (struct rtk_bt_vendor_config *)*config_buf;
689 uint16_t config_len = le16_to_cpu(config->data_len), temp = 0;
690 struct rtk_bt_vendor_config_entry *entry = config->entry;
691 unsigned int i = 0;
692 uint32_t baudrate = 0;
693 uint8_t heartbeat_buf = 0;
694 uint8_t *p;
695
696 HILOGD("bt_addr = %x", bt_addr[0]);
697 if (le32_to_cpu(config->signature) != RTK_VENDOR_CONFIG_MAGIC) {
698 HILOGE("config signature magic number(0x%x) is not set to RTK_VENDOR_CONFIG_MAGIC", config->signature);
699 return 0;
700 }
701
702 if (config_len != *filelen - sizeof(struct rtk_bt_vendor_config)) {
703 HILOGE("config len(0x%x) is not right(0x%lx)", config_len,
704 (unsigned long)(*filelen - sizeof(struct rtk_bt_vendor_config)));
705 return 0;
706 }
707
708 hw_cfg_cb.heartbeat = 0;
709 for (i = 0; i < config_len;) {
710 switch (le16_to_cpu(entry->offset)) {
711 case 0xc: {
712 p = (uint8_t *)entry->entry_data;
713 STREAM_TO_UINT32(baudrate, p);
714 #define ENTRY_LEN_12 12
715 if (entry->entry_len >= ENTRY_LEN_12) {
716 hw_cfg_cb.hw_flow_cntrl |= 0x80; /* bit7 set hw flow control */
717 if (entry->entry_data[ENTRY_LEN_12] & 0x04) { /* offset 0x18, bit2 */
718 hw_cfg_cb.hw_flow_cntrl |= 1; /* bit0 enable hw flow control */
719 }
720 }
721
722 HILOGI("config baud rate to :0x%08x, hwflowcontrol:0x%x, 0x%x", baudrate,
723 entry->entry_data[ENTRY_LEN_12], hw_cfg_cb.hw_flow_cntrl);
724 break;
725 }
726 case 0x017a: {
727 if (mac_offset == CONFIG_MAC_OFFSET_GEN_1_2) {
728 p = (uint8_t *)entry->entry_data;
729 STREAM_TO_UINT8(heartbeat_buf, p);
730 if ((heartbeat_buf & 0x02) && (heartbeat_buf & 0x10)) {
731 hw_cfg_cb.heartbeat = 1;
732 } else {
733 hw_cfg_cb.heartbeat = 0;
734 }
735
736 HILOGI("config 0x017a heartbeat = %d", hw_cfg_cb.heartbeat);
737 }
738 break;
739 }
740 case 0x01be: {
741 if (mac_offset == CONFIG_MAC_OFFSET_GEN_3PLUS || mac_offset == CONFIG_MAC_OFFSET_GEN_4PLUS) {
742 p = (uint8_t *)entry->entry_data;
743 STREAM_TO_UINT8(heartbeat_buf, p);
744 if ((heartbeat_buf & 0x02) && (heartbeat_buf & 0x10)) {
745 hw_cfg_cb.heartbeat = 1;
746 } else {
747 hw_cfg_cb.heartbeat = 0;
748 }
749
750 HILOGI("config 0x01be heartbeat = %d", hw_cfg_cb.heartbeat);
751 }
752 break;
753 }
754 default:
755 HILOGI("config offset(0x%x),length(0x%x)", entry->offset, entry->entry_len);
756 break;
757 }
758 temp = entry->entry_len + sizeof(struct rtk_bt_vendor_config_entry);
759 i += temp;
760 entry = (struct rtk_bt_vendor_config_entry *)((uint8_t *)entry + temp);
761 }
762
763 return baudrate;
764 }
765
rtk_get_bt_final_patch(bt_hw_cfg_cb_t * cfg_cb)766 static void rtk_get_bt_final_patch(bt_hw_cfg_cb_t *cfg_cb)
767 {
768 uint8_t proj_id = 0;
769 struct rtk_epatch_entry *entry = NULL;
770 struct rtk_epatch *patch = (struct rtk_epatch *)cfg_cb->fw_buf;
771
772 if (cfg_cb->lmp_subversion == LMPSUBVERSION_8723a) {
773 #define MEMCMP_8 8
774 if (memcmp(cfg_cb->fw_buf, RTK_EPATCH_SIGNATURE, MEMCMP_8) == 0) {
775 HILOGE("8723as check signature error!");
776 cfg_cb->dl_fw_flag = 0;
777 if (cfg_cb->fw_len > 0) {
778 free(cfg_cb->fw_buf);
779 cfg_cb->fw_len = 0;
780 }
781 if (cfg_cb->config_len > 0) {
782 free(cfg_cb->config_buf);
783 cfg_cb->config_len = 0;
784 }
785 if (entry) {
786 free(entry);
787 }
788 return;
789 } else {
790 cfg_cb->total_len = cfg_cb->fw_len + cfg_cb->config_len;
791 if (!(cfg_cb->total_buf = malloc(cfg_cb->total_len))) {
792 HILOGE("can't alloc memory for fw&config, errno:%d", errno);
793 cfg_cb->dl_fw_flag = 0;
794 if (cfg_cb->fw_len > 0) {
795 free(cfg_cb->fw_buf);
796 cfg_cb->fw_len = 0;
797 }
798 if (cfg_cb->config_len > 0) {
799 free(cfg_cb->config_buf);
800 cfg_cb->config_len = 0;
801 }
802 if (entry) {
803 free(entry);
804 }
805 return ;
806 } else {
807 HILOGI("8723as, fw copy direct");
808 (void)memcpy_s(cfg_cb->total_buf, cfg_cb->fw_len, cfg_cb->fw_buf, cfg_cb->fw_len);
809 (void)memcpy_s(cfg_cb->total_buf + cfg_cb->fw_len,
810 cfg_cb->config_len, cfg_cb->config_buf, cfg_cb->config_len);
811 cfg_cb->dl_fw_flag = 1;
812 if (cfg_cb->fw_len > 0) {
813 free(cfg_cb->fw_buf);
814 cfg_cb->fw_len = 0;
815 }
816 if (cfg_cb->config_len > 0) {
817 free(cfg_cb->config_buf);
818 cfg_cb->config_len = 0;
819 }
820 if (entry) {
821 free(entry);
822 }
823 return ;
824 }
825 }
826 }
827
828 if (memcmp(cfg_cb->fw_buf, RTK_EPATCH_SIGNATURE, MEMCMP_8)) {
829 HILOGE("check signature error");
830 cfg_cb->dl_fw_flag = 0;
831 if (cfg_cb->fw_len > 0) {
832 free(cfg_cb->fw_buf);
833 cfg_cb->fw_len = 0;
834 }
835 if (cfg_cb->config_len > 0) {
836 free(cfg_cb->config_buf);
837 cfg_cb->config_len = 0;
838 }
839 if (entry) {
840 free(entry);
841 }
842 return ;
843 }
844
845 /* check the extension section signature */
846 #define MEMCMP_4 4
847 if (memcmp(cfg_cb->fw_buf + cfg_cb->fw_len - MEMCMP_4, EXTENSION_SECTION_SIGNATURE, MEMCMP_4)) {
848 HILOGE("check extension section signature error");
849 cfg_cb->dl_fw_flag = 0;
850 if (cfg_cb->fw_len > 0) {
851 free(cfg_cb->fw_buf);
852 cfg_cb->fw_len = 0;
853 }
854 if (cfg_cb->config_len > 0) {
855 free(cfg_cb->config_buf);
856 cfg_cb->config_len = 0;
857 }
858 if (entry) {
859 free(entry);
860 }
861 return ;
862 }
863
864 #define PROJ_ID_LENTH_5 5
865 proj_id = rtk_get_fw_project_id(cfg_cb->fw_buf + cfg_cb->fw_len - PROJ_ID_LENTH_5);
866 if ((hw_cfg_cb.project_id_mask != PROJECT_ID_MASK_ALL) && ((hw_cfg_cb.project_id_mask & (1 << proj_id)) == 0)) {
867 HILOGE("hw_cfg_cb.project_id_mask is 0x%08x, fw project_id is %d, does not match!!!", hw_cfg_cb.project_id_mask,
868 proj_id);
869 cfg_cb->dl_fw_flag = 0;
870 if (cfg_cb->fw_len > 0) {
871 free(cfg_cb->fw_buf);
872 cfg_cb->fw_len = 0;
873 }
874 if (cfg_cb->config_len > 0) {
875 free(cfg_cb->config_buf);
876 cfg_cb->config_len = 0;
877 }
878 if (entry) {
879 free(entry);
880 }
881 return ;
882 }
883
884 entry = rtk_get_patch_entry(cfg_cb);
885 if (entry) {
886 cfg_cb->total_len = entry->patch_length + cfg_cb->config_len;
887 } else {
888 cfg_cb->dl_fw_flag = 0;
889 if (cfg_cb->fw_len > 0) {
890 free(cfg_cb->fw_buf);
891 cfg_cb->fw_len = 0;
892 }
893 if (cfg_cb->config_len > 0) {
894 free(cfg_cb->config_buf);
895 cfg_cb->config_len = 0;
896 }
897 if (entry) {
898 free(entry);
899 }
900 return ;
901 }
902
903 HILOGI("total_len = 0x%x", cfg_cb->total_len);
904
905 if (!(cfg_cb->total_buf = malloc(cfg_cb->total_len))) {
906 HILOGE("Can't alloc memory for multi fw&config, errno:%d", errno);
907 cfg_cb->dl_fw_flag = 0;
908 if (cfg_cb->fw_len > 0) {
909 free(cfg_cb->fw_buf);
910 cfg_cb->fw_len = 0;
911 }
912 if (cfg_cb->config_len > 0) {
913 free(cfg_cb->config_buf);
914 cfg_cb->config_len = 0;
915 }
916 if (entry) {
917 free(entry);
918 }
919 return ;
920 } else {
921 #define ENTRY_COEX_VERSION_16 16
922 #define ENTRY_COEX_VERSION_27 27
923 #define ENTRY_COEX_VERSION_10000 10000
924 (void)memcpy_s(cfg_cb->total_buf, entry->patch_length, cfg_cb->fw_buf + entry->patch_offset,
925 entry->patch_length);
926 (void)memcpy_s(cfg_cb->total_buf + entry->patch_length - 4L,
927 sizeof(cfg_cb->total_buf) + entry->patch_length, &patch->fw_version, 4L);
928 (void)memcpy_s(&entry->svn_version, sizeof(entry->svn_version), cfg_cb->total_buf + entry->patch_length - 8L,
929 4L);
930 (void)memcpy_s(&entry->coex_version, sizeof(entry->coex_version),
931 cfg_cb->total_buf + entry->patch_length - 12L, 4L);
932 HILOGI("BTCOEX:20%06d-%04x svn_version:%d lmp_subversion:0x%x hci_version:0x%x hci_revision:0x%x chip_type:%d"
933 "Cut:%d libbt-vendor_uart version:%s\n",
934 ((entry->coex_version >> ENTRY_COEX_VERSION_16) & 0x7ff) +
935 ((entry->coex_version >> ENTRY_COEX_VERSION_27) * ENTRY_COEX_VERSION_10000),
936 (entry->coex_version & 0xffff), entry->svn_version, cfg_cb->lmp_subversion, cfg_cb->hci_version,
937 cfg_cb->hci_revision, cfg_cb->chip_type, cfg_cb->eversion + 1, RTK_VERSION);
938 }
939
940 if (cfg_cb->config_len) {
941 (void)memcpy_s(cfg_cb->total_buf + entry->patch_length, cfg_cb->config_len, cfg_cb->config_buf,
942 cfg_cb->config_len);
943 }
944
945 cfg_cb->dl_fw_flag = 1;
946 HILOGI("Fw:%s exists, config file:%s exists", (cfg_cb->fw_len > 0) ? "" : "not",
947 (cfg_cb->config_len > 0) ? "" : "not");
948 }
949
rtk_get_bt_config(unsigned char ** config_buf,uint32_t * config_baud_rate,char * config_file_short_name,uint16_t mac_offset)950 static uint32_t rtk_get_bt_config(unsigned char **config_buf, uint32_t *config_baud_rate, char *config_file_short_name,
951 uint16_t mac_offset)
952 {
953 char bt_config_file_name[PATH_MAX] = {0};
954 struct stat st;
955 size_t filelen;
956 int fd;
957 uint8_t *p_vnd_local_bd_addr = get_vnd_local_bd_addr();
958
959 (void)sprintf_s(bt_config_file_name, sizeof(bt_config_file_name), BT_CONFIG_DIRECTORY, config_file_short_name);
960 HILOGI("BT config file: %s", bt_config_file_name);
961
962 if (stat(bt_config_file_name, &st) < 0) {
963 HILOGE("can't access bt config file:%s, errno:%d\n", bt_config_file_name, errno);
964 return 0;
965 }
966
967 filelen = st.st_size;
968 if (filelen > MAX_ORG_CONFIG_SIZE) {
969 HILOGE("bt config file is too large(>0x%04x)", MAX_ORG_CONFIG_SIZE);
970 return 0;
971 }
972
973 if ((fd = open(bt_config_file_name, O_RDONLY)) < 0) {
974 HILOGE("Can't open bt config file");
975 return 0;
976 }
977
978 if ((*config_buf = malloc(MAX_ORG_CONFIG_SIZE + MAX_ALT_CONFIG_SIZE)) == NULL) {
979 HILOGE("malloc buffer for config file fail(0x%zx)\n", filelen);
980 close(fd);
981 return 0;
982 }
983
984 if (read(fd, *config_buf, filelen) < (ssize_t)filelen) {
985 HILOGE("Can't load bt config file");
986 free(*config_buf);
987 close(fd);
988 return 0;
989 }
990
991 *config_baud_rate = rtk_parse_config_file(config_buf, &filelen, p_vnd_local_bd_addr, mac_offset);
992 HILOGI("Get config baud rate from config file:0x%x", *config_baud_rate);
993
994 close(fd);
995 return filelen;
996 }
997
hci_download_patch_h4(HC_BT_HDR * p_buf,int index,uint8_t * data,int len)998 static int hci_download_patch_h4(HC_BT_HDR *p_buf, int index, uint8_t *data, int len)
999 {
1000 int retval = FALSE;
1001 uint8_t *p = (uint8_t *)(p_buf + 1);
1002
1003 UINT16_TO_STREAM(p, HCI_VSC_DOWNLOAD_FW_PATCH);
1004 *p++ = 1 + len; /* parameter length */
1005 *p++ = index;
1006 (void)memcpy_s(p, len, data, len);
1007 p_buf->len = HCI_CMD_PREAMBLE_SIZE + 1 + len;
1008
1009 hw_cfg_cb.state = HW_CFG_DL_FW_PATCH;
1010
1011 retval = bt_vendor_cbacks->xmit_cb(HCI_VSC_DOWNLOAD_FW_PATCH, p_buf);
1012 return retval;
1013 }
1014
1015 /*******************************************************************************
1016 **
1017 ** Function hw_config_cback
1018 **
1019 ** Description Callback function for controller configuration
1020 **
1021 ** Returns None
1022 **
1023 *******************************************************************************/
hw_config_cback(void * p_evt_buf)1024 void hw_config_cback(void *p_evt_buf)
1025 {
1026 HC_BT_HDR *p_mem = NULL;
1027 uint8_t *p = NULL, *pp = NULL;
1028 uint8_t status = 0;
1029 uint16_t opcode = 0;
1030 HC_BT_HDR *p_buf = NULL;
1031 int is_proceeding = FALSE;
1032 int i = 0;
1033 uint8_t iIndexRx = 0;
1034 patch_info *prtk_patch_file_info = NULL;
1035 uint32_t host_baudrate = 0;
1036 bool rtkbt_auto_restart_onoff = get_rtkbt_auto_restart();
1037
1038 #if (USE_CONTROLLER_BDADDR == TRUE)
1039 #endif
1040
1041 if (p_evt_buf != NULL) {
1042 p_mem = (HC_BT_HDR *)p_evt_buf;
1043 status = *((uint8_t *)(p_mem + 1) + HCI_EVT_CMD_CMPL_STATUS_OFFSET);
1044 p = (uint8_t *)(p_mem + 1) + HCI_EVT_CMD_CMPL_OPCODE_OFFSET;
1045 STREAM_TO_UINT16(opcode, p);
1046 }
1047
1048 if (opcode == HCI_VSC_H5_INIT) {
1049 if (status != 0) {
1050 HILOGE("%s, status = %d", __func__, status);
1051 if (rtkbt_auto_restart_onoff) {
1052 bt_vendor_cbacks->init_cb(BTC_OP_RESULT_FAIL);
1053 kill(getpid(), SIGKILL);
1054 }
1055 return;
1056 }
1057 }
1058
1059 /* Ask a new buffer big enough to hold any HCI commands sent in here */
1060 /* a cut fc6d status==1 */
1061 if (((status == 0) || (opcode == HCI_VSC_READ_ROM_VERSION)) && bt_vendor_cbacks) {
1062 p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + HCI_CMD_MAX_LEN);
1063 }
1064
1065 if (p_buf != NULL) {
1066 p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
1067 p_buf->offset = 0;
1068 p_buf->len = 0;
1069 p_buf->layer_specific = 0;
1070
1071 BTVNDDBG("hw_cfg_cb.state = %i", hw_cfg_cb.state);
1072 switch (hw_cfg_cb.state) {
1073 case HW_CFG_H5_INIT: {
1074 p = (uint8_t *)(p_buf + 1);
1075 UINT16_TO_STREAM(p, HCI_READ_LMP_VERSION);
1076 *p++ = 0;
1077 p_buf->len = HCI_CMD_PREAMBLE_SIZE;
1078
1079 hw_cfg_cb.state = HW_CFG_READ_LOCAL_VER;
1080 is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_READ_LMP_VERSION, p_buf);
1081 break;
1082 }
1083 case HW_CFG_READ_LOCAL_VER: {
1084 if (status == 0 && p_mem) {
1085 p = ((uint8_t *)(p_mem + 1) + HCI_EVT_CMD_CMPL_OP1001_HCI_VERSION_OFFSET);
1086 STREAM_TO_UINT16(hw_cfg_cb.hci_version, p);
1087 p = ((uint8_t *)(p_mem + 1) + HCI_EVT_CMD_CMPL_OP1001_HCI_REVISION_OFFSET);
1088 STREAM_TO_UINT16(hw_cfg_cb.hci_revision, p);
1089 p = (uint8_t *)(p_mem + 1) + HCI_EVT_CMD_CMPL_OP1001_LMP_SUBVERSION_OFFSET;
1090 STREAM_TO_UINT16(hw_cfg_cb.lmp_subversion, p);
1091 BTVNDDBG("lmp_subversion = 0x%x hw_cfg_cb.hci_version = 0x%x hw_cfg_cb.hci_revision = 0x%x",
1092 hw_cfg_cb.lmp_subversion, hw_cfg_cb.hci_version, hw_cfg_cb.hci_revision);
1093 if (hw_cfg_cb.lmp_subversion == LMPSUBVERSION_8723a) {
1094 hw_cfg_cb.state = HW_CFG_START;
1095 goto CFG_START;
1096 } else {
1097 hw_cfg_cb.state = HW_CFG_READ_ECO_VER;
1098 p = (uint8_t *)(p_buf + 1);
1099 UINT16_TO_STREAM(p, HCI_VSC_READ_ROM_VERSION);
1100 *p++ = 0;
1101 p_buf->len = HCI_CMD_PREAMBLE_SIZE;
1102 is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_VSC_READ_ROM_VERSION, p_buf);
1103 }
1104 }
1105 break;
1106 }
1107 case HW_CFG_READ_ECO_VER: {
1108 if (status == 0 && p_mem) {
1109 hw_cfg_cb.eversion = *((uint8_t *)(p_mem + 1) + HCI_EVT_CMD_CMPL_OPFC6D_EVERSION_OFFSET);
1110 BTVNDDBG("hw_config_cback chip_id of the IC:%d", hw_cfg_cb.eversion + 1);
1111 } else if (status == 1) {
1112 hw_cfg_cb.eversion = 0;
1113 } else {
1114 is_proceeding = FALSE;
1115 break;
1116 }
1117
1118 // check if have multiple matched patch_entry by lmp_subversion,hci_version, hci_revision
1119 if (check_match_state(&hw_cfg_cb, 0) > 1) {
1120 hw_cfg_cb.state = HW_CFG_READ_CHIP_TYPE;
1121 p = (uint8_t *)(p_buf + 1);
1122 UINT16_TO_STREAM(p, HCI_VSC_READ_CHIP_TYPE);
1123 #define P_5 5
1124 *p++ = P_5;
1125 UINT8_TO_STREAM(p, 0x00);
1126 UINT32_TO_STREAM(p, 0xB000A094);
1127 p_buf->len = HCI_CMD_PREAMBLE_SIZE + HCI_CMD_READ_CHIP_TYPE_SIZE;
1128
1129 pp = (uint8_t *)(p_buf + 1);
1130 for (i = 0; i < p_buf->len; i++) {
1131 BTVNDDBG("get chip type command data[%d]= 0x%x", i, *(pp + i));
1132 }
1133
1134 is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_VSC_READ_CHIP_TYPE, p_buf);
1135 break;
1136 } else {
1137 hw_cfg_cb.state = HW_CFG_START;
1138 goto CFG_START;
1139 }
1140 }
1141 case HW_CFG_READ_CHIP_TYPE: {
1142 if (!p_mem) {
1143 HILOGE("%s, buffer is null", __func__);
1144 is_proceeding = FALSE;
1145 break;
1146 }
1147 BTVNDDBG("READ_CHIP_TYPE status = %d, length = %d", status, p_mem->len);
1148 p = (uint8_t *)(p_mem + 1);
1149 for (i = 0; i < p_mem->len; i++) {
1150 BTVNDDBG("READ_CHIP_TYPE event data[%d]= 0x%x", i, *(p + i));
1151 }
1152 if (status == 0) {
1153 hw_cfg_cb.chip_type =
1154 ((*((uint8_t *)(p_mem + 1) + HCI_EVT_CMD_CMPL_OPFC61_CHIPTYPE_OFFSET)) & 0x0F);
1155 BTVNDDBG("READ_CHIP_TYPE hw_cfg_cb.lmp_subversion = 0x%x", hw_cfg_cb.lmp_subversion);
1156 BTVNDDBG("READ_CHIP_TYPE hw_cfg_cb.hci_version = 0x%x", hw_cfg_cb.hci_version);
1157 BTVNDDBG("READ_CHIP_TYPE hw_cfg_cb.hci_revision = 0x%x", hw_cfg_cb.hci_revision);
1158 BTVNDDBG("READ_CHIP_TYPE hw_cfg_cb.chip_type = 0x%x", hw_cfg_cb.chip_type);
1159 } else {
1160 is_proceeding = FALSE;
1161 break;
1162 }
1163 // check if have multiple matched patch_entry by lmp_subversion,hci_version, hci_revision and chiptype
1164 if (check_match_state(&hw_cfg_cb, PATCH_OPTIONAL_MATCH_FLAG_CHIPTYPE) > 1) {
1165 BTVNDDBG("check_match_state(lmp_subversion:0x%04x, hci_version:%d,hci_revision:%d chip_type:%d): "
1166 "Multi Matched Patch\n",
1167 hw_cfg_cb.lmp_subversion, hw_cfg_cb.hci_version, hw_cfg_cb.hci_revision,
1168 hw_cfg_cb.chip_type);
1169 is_proceeding = FALSE;
1170 break;
1171 }
1172 hw_cfg_cb.state = HW_CFG_START;
1173 }
1174 CFG_START:
1175 case HW_CFG_START: {
1176 #ifdef BT_CHIP_PROBE_SIMULATION
1177 {
1178 int ii;
1179 (void)memcpy_s(&hw_cfg_test, sizeof(hw_cfg_test), &hw_cfg_cb, sizeof(hw_cfg_test));
1180 for (i = 0; i < sizeof(bt_chip_chars) / sizeof(bt_chip_chars[0]); i++) {
1181 BTVNDDBG("BT_CHIP_PROBE_SIMULATION loop:%d $$$ BEGIN $$$\n", i);
1182 hw_cfg_test.lmp_subversion = bt_chip_chars[i].lmp_subversion;
1183 hw_cfg_test.hci_version = bt_chip_chars[i].hci_version;
1184 hw_cfg_test.hci_revision = bt_chip_chars[i].hci_revision;
1185 hw_cfg_test.chip_type = CHIPTYPE_NONE;
1186 if (check_match_state(&hw_cfg_test, 0) > 1) {
1187 BTVNDDBG("check_match_state hw_cfg_test(lmp_subversion:0x%04x,
1188 hci_version:%d, hci_revision:%d chip_type:%d): Multi Matched Patch\n",
1189 hw_cfg_test.lmp_subversion, hw_cfg_test.hci_version, hw_cfg_test.hci_revision,
1190 hw_cfg_test.chip_type);
1191 if (bt_chip_chars[i].chip_type != CHIPTYPE_NONE) {
1192 BTVNDDBG("BT_CHIP_PROBE_SIMULATION loop:%d *** Include ChipType ***\n", i);
1193 hw_cfg_test.chip_type = bt_chip_chars[i].chip_type;
1194 if (check_match_state(&hw_cfg_test, PATCH_OPTIONAL_MATCH_FLAG_CHIPTYPE) > 1) {
1195 BTVNDDBG("check_match_state hw_cfg_test(lmp_subversion:0x%04x, hci_version:%d,
1196 hci_revision:%d chip_type:%d): Multi Matched Patch\n", hw_cfg_test.lmp_subversion,
1197 hw_cfg_test.hci_version, hw_cfg_test.hci_revision, hw_cfg_test.chip_type);
1198 } else {
1199 prtk_patch_file_info = get_patch_entry(&hw_cfg_test);
1200 }
1201 }
1202 } else {
1203 prtk_patch_file_info = get_patch_entry(&hw_cfg_test);
1204 }
1205 BTVNDDBG("BT_CHIP_PROBE_SIMULATION loop:%d $$$ END $$$\n", i);
1206 }
1207 }
1208 #endif
1209 // get efuse config file and patch code file
1210 prtk_patch_file_info = get_patch_entry(&hw_cfg_cb);
1211 if ((prtk_patch_file_info == NULL) || (prtk_patch_file_info->lmp_subversion == 0)) {
1212 HILOGE("get patch entry error");
1213 is_proceeding = FALSE;
1214 break;
1215 }
1216 hw_cfg_cb.max_patch_size = prtk_patch_file_info->max_patch_size;
1217 hw_cfg_cb.config_len =
1218 rtk_get_bt_config(&hw_cfg_cb.config_buf, &hw_cfg_cb.baudrate, prtk_patch_file_info->config_name,
1219 prtk_patch_file_info->mac_offset);
1220 if (hw_cfg_cb.config_len == 0) {
1221 HILOGE("Get Config file fail, just use efuse settings");
1222 }
1223 rtk_update_altsettings(prtk_patch_file_info, hw_cfg_cb.config_buf, &(hw_cfg_cb.config_len));
1224
1225 hw_cfg_cb.fw_len = rtk_get_bt_firmware(&hw_cfg_cb.fw_buf, prtk_patch_file_info->patch_name);
1226 if (hw_cfg_cb.fw_len < 0) {
1227 HILOGE("Get BT firmware fail");
1228 hw_cfg_cb.fw_len = 0;
1229 } else {
1230 hw_cfg_cb.project_id_mask = prtk_patch_file_info->project_id_mask;
1231 rtk_get_bt_final_patch(&hw_cfg_cb);
1232 }
1233 BTVNDDBG("Check total_len(0x%08x) max_patch_size(0x%08x)", hw_cfg_cb.total_len,
1234 hw_cfg_cb.max_patch_size);
1235 if (hw_cfg_cb.total_len > hw_cfg_cb.max_patch_size) {
1236 HILOGE("total length of fw&config(0x%08x) larger than max_patch_size(0x%08x)", hw_cfg_cb.total_len,
1237 hw_cfg_cb.max_patch_size);
1238 is_proceeding = FALSE;
1239 break;
1240 }
1241
1242 if ((hw_cfg_cb.total_len > 0) && hw_cfg_cb.dl_fw_flag) {
1243 hw_cfg_cb.patch_frag_cnt = hw_cfg_cb.total_len / PATCH_DATA_FIELD_MAX_SIZE;
1244 hw_cfg_cb.patch_frag_tail = hw_cfg_cb.total_len % PATCH_DATA_FIELD_MAX_SIZE;
1245 if (hw_cfg_cb.patch_frag_tail) {
1246 hw_cfg_cb.patch_frag_cnt += 1;
1247 } else {
1248 hw_cfg_cb.patch_frag_tail = PATCH_DATA_FIELD_MAX_SIZE;
1249 }
1250 BTVNDDBG("patch fragment count %d, tail len %d", hw_cfg_cb.patch_frag_cnt,
1251 hw_cfg_cb.patch_frag_tail);
1252 } else {
1253 is_proceeding = FALSE;
1254 break;
1255 }
1256
1257 if ((hw_cfg_cb.baudrate == 0) && ((hw_cfg_cb.hw_flow_cntrl & 0x80) == 0)) {
1258 BTVNDDBG("no baudrate to set and no need to set hw flow control");
1259 goto DOWNLOAD_FW;
1260 }
1261
1262 if ((hw_cfg_cb.baudrate == 0) && (hw_cfg_cb.hw_flow_cntrl & 0x80)) {
1263 BTVNDDBG("no baudrate to set but set hw flow control is needed");
1264 goto SET_HW_FLCNTRL;
1265 }
1266 }
1267 /* fall through intentionally */
1268 case HW_CFG_SET_UART_BAUD_CONTROLLER:
1269 BTVNDDBG("bt vendor lib: set CONTROLLER UART baud 0x%x", hw_cfg_cb.baudrate);
1270 hw_cfg_cb.state = HW_CFG_SET_UART_BAUD_HOST;
1271 is_proceeding = hw_config_set_controller_baudrate(p_buf, hw_cfg_cb.baudrate);
1272 break;
1273
1274 case HW_CFG_SET_UART_BAUD_HOST:
1275 /* update baud rate of host's UART port */
1276 BTVNDDBG("bt vendor lib: set HOST UART baud start");
1277 rtk_speed_to_uart_speed(hw_cfg_cb.baudrate, &host_baudrate);
1278 BTVNDDBG("bt vendor lib: set HOST UART baud %i", host_baudrate);
1279 userial_vendor_set_baud(line_speed_to_userial_baud(host_baudrate));
1280
1281 if ((hw_cfg_cb.hw_flow_cntrl & 0x80) == 0) {
1282 goto DOWNLOAD_FW;
1283 }
1284
1285 SET_HW_FLCNTRL:
1286 case HW_CFG_SET_UART_HW_FLOW_CONTROL:
1287 BTVNDDBG("Change HW flowcontrol setting");
1288 if (hw_cfg_cb.hw_flow_cntrl & 0x01) {
1289 userial_vendor_set_hw_fctrl(0); // default disable hw fctrl
1290 } else {
1291 userial_vendor_set_hw_fctrl(0);
1292 }
1293 #define MS_DELAY_50 50
1294 ms_delay(MS_DELAY_50);
1295 hw_cfg_cb.state = HW_CFG_DL_FW_PATCH;
1296 BTVNDDBG("start donwload fw");
1297
1298 DOWNLOAD_FW:
1299 case HW_CFG_DL_FW_PATCH:
1300 BTVNDDBG("bt vendor lib: HW_CFG_DL_FW_PATCH status:%i, opcode:0x%x", status, opcode);
1301
1302 // recv command complete event for patch code download command
1303 if (opcode == HCI_VSC_DOWNLOAD_FW_PATCH) {
1304 iIndexRx = *((uint8_t *)(p_mem + 1) + HCI_EVT_CMD_CMPL_STATUS_OFFSET + 1);
1305 BTVNDDBG("bt vendor lib: HW_CFG_DL_FW_PATCH status:%i, iIndexRx:%i", status, iIndexRx);
1306 hw_cfg_cb.patch_frag_idx++;
1307
1308 if (iIndexRx & 0x80) {
1309 BTVNDDBG("vendor lib fwcfg completed");
1310 free(hw_cfg_cb.total_buf);
1311 hw_cfg_cb.total_len = 0;
1312
1313 bt_vendor_cbacks->dealloc(p_buf);
1314 bt_vendor_cbacks->init_cb(BTC_OP_RESULT_SUCCESS);
1315
1316 hw_cfg_cb.state = 0;
1317 is_proceeding = TRUE;
1318 set_h5_init_datatrans_flag(0);
1319 break;
1320 }
1321 }
1322
1323 if (hw_cfg_cb.patch_frag_idx < hw_cfg_cb.patch_frag_cnt) {
1324 iIndexRx = hw_cfg_cb.patch_frag_idx ? ((hw_cfg_cb.patch_frag_idx - 1) % 0x7f + 1) : 0;
1325 if (hw_cfg_cb.patch_frag_idx == hw_cfg_cb.patch_frag_cnt - 1) {
1326 BTVNDDBG("HW_CFG_DL_FW_PATCH: send last fw fragment");
1327 iIndexRx |= 0x80;
1328 hw_cfg_cb.patch_frag_len = hw_cfg_cb.patch_frag_tail;
1329 } else {
1330 iIndexRx &= 0x7F;
1331 hw_cfg_cb.patch_frag_len = PATCH_DATA_FIELD_MAX_SIZE;
1332 }
1333 }
1334
1335 is_proceeding = hci_download_patch_h4(
1336 p_buf, iIndexRx, hw_cfg_cb.total_buf + (hw_cfg_cb.patch_frag_idx * PATCH_DATA_FIELD_MAX_SIZE),
1337 hw_cfg_cb.patch_frag_len);
1338 break;
1339
1340 default:
1341 break;
1342 } // switch(hw_cfg_cb.state)
1343 } // if (p_buf != NULL)
1344
1345 /* Free the RX event buffer */
1346
1347 if (is_proceeding == FALSE) {
1348 HILOGE("vendor lib fwcfg aborted!!!");
1349 if (bt_vendor_cbacks) {
1350 if (p_buf != NULL) {
1351 bt_vendor_cbacks->dealloc(p_buf);
1352 }
1353
1354 bt_vendor_cbacks->init_cb(BTC_OP_RESULT_FAIL);
1355 }
1356
1357 if (hw_cfg_cb.config_len) {
1358 free(hw_cfg_cb.config_buf);
1359 hw_cfg_cb.config_len = 0;
1360 }
1361
1362 if (hw_cfg_cb.fw_len) {
1363 free(hw_cfg_cb.fw_buf);
1364 hw_cfg_cb.fw_len = 0;
1365 }
1366
1367 if (hw_cfg_cb.total_len) {
1368 free(hw_cfg_cb.total_buf);
1369 hw_cfg_cb.total_len = 0;
1370 }
1371 hw_cfg_cb.state = 0;
1372 }
1373 }
1374
1375 /*****************************************************************************
1376 ** Hardware Configuration Interface Functions
1377 *****************************************************************************/
1378
1379 /*******************************************************************************
1380 **
1381 ** Function hw_config_start
1382 **
1383 ** Description Kick off controller initialization process
1384 **
1385 ** Returns None
1386 **
1387 *******************************************************************************/
hw_config_start(char transtype)1388 void hw_config_start(char transtype)
1389 {
1390 (void)memset_s(&hw_cfg_cb, sizeof(bt_hw_cfg_cb_t), 0, sizeof(bt_hw_cfg_cb_t));
1391 hw_cfg_cb.dl_fw_flag = 1;
1392 hw_cfg_cb.chip_type = CHIPTYPE_NONE;
1393 BTVNDDBG("RTKBT_RELEASE_NAME: %s", RTKBT_RELEASE_NAME);
1394 BTVNDDBG("\nRealtek libbt-vendor_uart Version %s \n", RTK_VERSION);
1395 HC_BT_HDR *p_buf = NULL;
1396 uint8_t *p;
1397
1398 BTVNDDBG("hw_config_start, transtype = 0x%x \n", transtype);
1399 /* Start from sending H5 INIT */
1400 if (bt_vendor_cbacks) {
1401 /* Must allocate command buffer via HC's alloc API */
1402 p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + HCI_CMD_PREAMBLE_SIZE);
1403 if (p_buf) {
1404 p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
1405 p_buf->offset = 0;
1406 p_buf->layer_specific = 0;
1407 p_buf->len = HCI_CMD_PREAMBLE_SIZE;
1408
1409 p = (uint8_t *)(p_buf + 1);
1410
1411 if (transtype & RTKBT_TRANS_H4) {
1412 p = (uint8_t *)(p_buf + 1);
1413 UINT16_TO_STREAM(p, HCI_READ_LMP_VERSION);
1414 *p++ = 0;
1415 p_buf->len = HCI_CMD_PREAMBLE_SIZE;
1416
1417 hw_cfg_cb.state = HW_CFG_READ_LOCAL_VER;
1418 bt_vendor_cbacks->xmit_cb(HCI_READ_LMP_VERSION, p_buf);
1419 } else {
1420 UINT16_TO_STREAM(p, HCI_VSC_H5_INIT);
1421 *p = 0; /* parameter length */
1422 hw_cfg_cb.state = HW_CFG_H5_INIT;
1423
1424 bt_vendor_cbacks->xmit_cb(HCI_VSC_H5_INIT, p_buf);
1425 }
1426 } else {
1427 HILOGE("%s buffer alloc fail!", __func__);
1428 bt_vendor_cbacks->init_cb(BTC_OP_RESULT_FAIL);
1429 }
1430 } else {
1431 HILOGE("%s call back is null", __func__);
1432 }
1433 }
1434