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