• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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