• 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 "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