• 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_usb"
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 #include "rtk_common.h"
45 
46 /******************************************************************************
47 **  Constants &  Macros
48 ******************************************************************************/
49 
50 extern uint8_t vnd_local_bd_addr[BD_ADDR_LEN];
51 extern bool rtkbt_auto_restart;
52 void hw_usb_config_cback(void *p_evt_buf);
53 extern bt_hw_cfg_cb_t hw_cfg_cb;
54 extern int getmacaddr(unsigned char *addr);
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 uint8_t rtk_get_fw_project_id(uint8_t *p_buf);
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 #define BT_VENDOR_CFG_TIMEDELAY_ 40
64 
65 typedef void (*tTIMER_HANDLE_CBACK)(union sigval sigval_value);
66 
OsAllocateTimer(tTIMER_HANDLE_CBACK timer_callback)67 static timer_t OsAllocateTimer(tTIMER_HANDLE_CBACK timer_callback)
68 {
69     struct sigevent sigev;
70     timer_t timerid;
71 
72     (void)memset_s(&sigev, sizeof(struct sigevent), 0, sizeof(struct sigevent));
73     // Create the POSIX timer to generate signo
74     sigev.sigev_notify = SIGEV_THREAD;
75     sigev.sigev_notify_function = timer_callback;
76     sigev.sigev_value.sival_ptr = &timerid;
77 
78     // Create the Timer using timer_create signal
79 
80     if (timer_create(CLOCK_REALTIME, &sigev, &timerid) == 0)
81     {
82         return timerid;
83     }
84     else
85     {
86         HILOGE("timer_create error!");
87         return (timer_t)-1;
88     }
89 }
90 
OsFreeTimer(timer_t timerid)91 static int OsFreeTimer(timer_t timerid)
92 {
93     int ret = 0;
94     ret = timer_delete(timerid);
95     if (ret != 0)
96     {
97         HILOGE("timer_delete fail with errno(%d)", errno);
98     }
99 
100     return ret;
101 }
102 
OsStartTimer(timer_t timerid,int msec,int mode)103 static int OsStartTimer(timer_t timerid, int msec, int mode)
104 {
105     struct itimerspec itval;
106 
107     itval.it_value.tv_sec = msec / 1000;
108     itval.it_value.tv_nsec = (long)(msec % 1000) * (1000000L);
109 
110     if (mode == 1)
111     {
112         itval.it_interval.tv_sec = itval.it_value.tv_sec;
113         itval.it_interval.tv_nsec = itval.it_value.tv_nsec;
114     }
115     else
116     {
117         itval.it_interval.tv_sec = 0;
118         itval.it_interval.tv_nsec = 0;
119     }
120 
121     // Set the Timer when to expire through timer_settime
122 
123     if (timer_settime(timerid, 0, &itval, NULL) != 0)
124     {
125         HILOGE("time_settime error!");
126         return -1;
127     }
128 
129     return 0;
130 }
131 
132 static timer_t localtimer = 0;
local_timer_handler(union sigval sigev_value)133 static void local_timer_handler(union sigval sigev_value)
134 {
135     bt_vendor_cbacks->init_cb(BTC_OP_RESULT_SUCCESS);
136     OsFreeTimer(localtimer);
137 }
138 
start_fwcfg_cbtimer(void)139 static void start_fwcfg_cbtimer(void)
140 {
141     if (localtimer == 0)
142     {
143         localtimer = OsAllocateTimer(local_timer_handler);
144     }
145     OsStartTimer(localtimer, BT_VENDOR_CFG_TIMEDELAY_, 0);
146 }
147 
148 /******************************************************************************
149 **  Static variables
150 ******************************************************************************/
151 // static bt_hw_cfg_cb_t hw_cfg_cb;
152 
153 typedef struct
154 {
155     uint16_t vid;
156     uint16_t pid;
157     uint16_t lmp_sub_default;
158     uint16_t lmp_sub;
159     uint16_t eversion;
160     char *mp_patch_name;
161     char *patch_name;
162     char *config_name;
163     uint8_t *fw_cache;
164     int fw_len;
165     uint16_t mac_offset;
166     uint32_t max_patch_size;
167 } usb_patch_info;
168 
169 static usb_patch_info usb_fw_patch_table[] = {
170     /* { vid, pid, lmp_sub_default, lmp_sub, everion, mp_fw_name, fw_name, config_name, fw_cache, fw_len, mac_offset } */
171     {0x0BDA, 0xD723, 0x8723, 0, 0, "mp_rtl8723d_fw", "rtl8723d_fw", "rtl8723d_config", NULL, 0, CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_40K}, /* RTL8723DU */
172     /* todo: RTL8703CU */
173 
174     /* NOTE: must append patch entries above the null entry */
175     {0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, 0, 0, 0}};
176 
177 uint16_t usb_project_id[] = {
178     ROM_LMP_8723a,
179     ROM_LMP_8723b,
180     ROM_LMP_8821a,
181     ROM_LMP_8761a,
182     ROM_LMP_8703a,
183     ROM_LMP_8763a,
184     ROM_LMP_8703b,
185     ROM_LMP_8723c,
186     ROM_LMP_8822b,
187     ROM_LMP_8723d,
188     ROM_LMP_8821c,
189     ROM_LMP_NONE,
190     ROM_LMP_NONE,
191     ROM_LMP_8822c,
192     ROM_LMP_8761b,
193     ROM_LMP_NONE};
194 // signature: realtech
195 static const uint8_t RTK_EPATCH_SIGNATURE[8] = {0x52, 0x65, 0x61, 0x6C, 0x74, 0x65, 0x63, 0x68};
196 // Extension Section IGNATURE:0x77FD0451
197 static const uint8_t EXTENSION_SECTION_SIGNATURE[4] = {0x51, 0x04, 0xFD, 0x77};
198 
usb_line_process(char * buf,unsigned short * offset,int * t)199 static void usb_line_process(char *buf, unsigned short *offset, int *t)
200 {
201     char *head = buf;
202     char *ptr = buf;
203     char *argv[32];
204     int argc = 0;
205     unsigned char len = 0;
206     int i = 0;
207     static int alt_size = 0;
208 
209     if (buf[0] == '\0' || buf[0] == '#' || buf[0] == '[')
210         return;
211     if (alt_size > MAX_ALT_CONFIG_SIZE - 4)
212     {
213         HILOGW("Extra Config file is too large");
214         return;
215     }
216     if (extra_entry_inx == NULL)
217         extra_entry_inx = extra_extry;
218     HILOGI("line_process:%s", buf);
219     while ((ptr = strsep(&head, ", \t")) != NULL)
220     {
221         if (!ptr[0])
222             continue;
223         argv[argc++] = ptr;
224         if (argc >= 32)
225         {
226             HILOGW("Config item is too long");
227             break;
228         }
229     }
230 
231     if (argc < 4)
232     {
233         HILOGE("Invalid Config item, ignore");
234         return;
235     }
236 
237     offset[(*t)] = (unsigned short)((strtoul(argv[0], NULL, 16)) | (strtoul(argv[1], NULL, 16) << 8));
238     HILOGI("Extra Config offset %04x", offset[(*t)]);
239     extra_entry_inx->offset = offset[(*t)];
240     (*t)++;
241     len = (unsigned char)strtoul(argv[2], NULL, 16);
242     if (len != (unsigned char)(argc - 3))
243     {
244         HILOGE("Extra Config item len %d is not match, we assume the actual len is %d", len, (argc - 3));
245         len = argc - 3;
246     }
247     extra_entry_inx->entry_len = len;
248 
249     alt_size += len + sizeof(struct rtk_bt_vendor_config_entry);
250     if (alt_size > MAX_ALT_CONFIG_SIZE)
251     {
252         HILOGW("Extra Config file is too large");
253         extra_entry_inx->offset = 0;
254         extra_entry_inx->entry_len = 0;
255         alt_size -= (len + sizeof(struct rtk_bt_vendor_config_entry));
256         return;
257     }
258     for (i = 0; i < len; i++)
259     {
260         extra_entry_inx->entry_data[i] = (uint8_t)strtoul(argv[3 + i], NULL, 16);
261         HILOGI("data[%d]:%02x", i, extra_entry_inx->entry_data[i]);
262     }
263     extra_entry_inx = (struct rtk_bt_vendor_config_entry *)((uint8_t *)extra_entry_inx + len + sizeof(struct rtk_bt_vendor_config_entry));
264 }
265 
usb_parse_extra_config(const char * path,usb_patch_info * patch_entry,unsigned short * offset,int * t)266 static void usb_parse_extra_config(const char *path, usb_patch_info *patch_entry, unsigned short *offset, int *t)
267 {
268     int fd, ret;
269     unsigned char buf[1024];
270 
271     fd = open(path, O_RDONLY);
272     if (fd == -1)
273     {
274         HILOGI("Couldn't open extra config %s, err:%s", path, strerror(errno));
275         return;
276     }
277 
278     ret = read(fd, buf, sizeof(buf));
279     if (ret == -1)
280     {
281         HILOGE("Couldn't read %s, err:%s", path, strerror(errno));
282         close(fd);
283         return;
284     }
285     else if (ret == 0)
286     {
287         HILOGE("%s is empty", path);
288         close(fd);
289         return;
290     }
291 
292     if (ret > 1022)
293     {
294         HILOGE("Extra config file is too big");
295         close(fd);
296         return;
297     }
298     buf[ret++] = '\n';
299     buf[ret++] = '\0';
300     close(fd);
301     char *head = (void *)buf;
302     char *ptr = (void *)buf;
303     ptr = strsep(&head, "\n\r");
304     if (strncmp(ptr, patch_entry->config_name, strlen(ptr)))
305     {
306         HILOGW("Extra config file not set for %s, ignore", patch_entry->config_name);
307         return;
308     }
309     while ((ptr = strsep(&head, "\n\r")) != NULL)
310     {
311         if (!ptr[0])
312             continue;
313         usb_line_process(ptr, offset, t);
314     }
315 }
316 
getUsbAltSettings(usb_patch_info * patch_entry,unsigned short * offset)317 static inline int getUsbAltSettings(usb_patch_info *patch_entry, unsigned short *offset) //(patch_info *patch_entry, unsigned short *offset, int max_group_cnt)
318 {
319     int n = 0;
320     if (patch_entry)
321         offset[n++] = patch_entry->mac_offset;
322     else
323         return n;
324     /*
325     //sample code, add special settings
326 
327         offset[n++] = 0x15B;
328     */
329     if (extra_extry)
330         usb_parse_extra_config(EXTRA_CONFIG_FILE, patch_entry, offset, &n);
331 
332     return n;
333 }
334 
getUsbAltSettingVal(usb_patch_info * patch_entry,unsigned short offset,unsigned char * val)335 static inline int getUsbAltSettingVal(usb_patch_info *patch_entry, unsigned short offset, unsigned char *val)
336 {
337     int res = 0;
338 
339     int i = 0;
340     struct rtk_bt_vendor_config_entry *ptr = extra_extry;
341 
342     while (ptr->offset)
343     {
344         if (ptr->offset == offset)
345         {
346             if (offset != patch_entry->mac_offset)
347             {
348                 memcpy(val, ptr->entry_data, ptr->entry_len);
349                 res = ptr->entry_len;
350                 HILOGI("Get Extra offset:%04x, val:", offset);
351                 for (i = 0; i < ptr->entry_len; i++)
352                     HILOGI("%02x", ptr->entry_data[i]);
353             }
354             break;
355         }
356         ptr = (struct rtk_bt_vendor_config_entry *)((uint8_t *)ptr + ptr->entry_len + sizeof(struct rtk_bt_vendor_config_entry));
357     }
358 
359     /*    switch(offset)
360         {
361     //sample code, add special settings
362             case 0x15B:
363                 val[0] = 0x0B;
364                 val[1] = 0x0B;
365                 val[2] = 0x0B;
366                 val[3] = 0x0B;
367                 res = 4;
368                 break;
369 
370             default:
371                 res = 0;
372                 break;
373         }
374     */
375     if ((patch_entry) && (offset == patch_entry->mac_offset) && (res == 0))
376     {
377         if (getmacaddr(val) == 0)
378         {
379             HILOGI("MAC: %02x:%02x:%02x:%02x:%02x:%02x", val[5], val[4], val[3], val[2], val[1], val[0]);
380             res = 6;
381         }
382     }
383     return res;
384 }
385 
rtk_usb_update_altsettings(usb_patch_info * patch_entry,unsigned char * config_buf_ptr,size_t * config_len_ptr)386 static void rtk_usb_update_altsettings(usb_patch_info *patch_entry, unsigned char *config_buf_ptr, size_t *config_len_ptr)
387 {
388     unsigned short offset[256], data_len;
389     unsigned char val[256];
390 
391     struct rtk_bt_vendor_config *config = (struct rtk_bt_vendor_config *)config_buf_ptr;
392     struct rtk_bt_vendor_config_entry *entry = config->entry;
393     size_t config_len = *config_len_ptr;
394     unsigned int i = 0;
395     int count = 0, temp = 0, j;
396 
397     if ((extra_extry = (struct rtk_bt_vendor_config_entry *)malloc(MAX_ALT_CONFIG_SIZE)) == NULL)
398     {
399         HILOGE("malloc buffer for extra_extry failed");
400     }
401     else
402         memset(extra_extry, 0, MAX_ALT_CONFIG_SIZE);
403 
404     HILOGI("ORG Config len=%08zx:\n", config_len);
405     for (i = 0; i <= config_len; i += 0x10)
406     {
407         HILOGI("%08x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", i,
408                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],
409                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]);
410     }
411 
412     memset(offset, 0, sizeof(offset));
413     memset(val, 0, sizeof(val));
414     data_len = le16_to_cpu(config->data_len);
415 
416     count = getUsbAltSettings(patch_entry, offset); // getAltSettings(patch_entry, offset, sizeof(offset)/sizeof(unsigned short));
417     if (count <= 0)
418     {
419         HILOGI("rtk_update_altsettings: No AltSettings");
420         return;
421     }
422     else
423     {
424         HILOGI("rtk_update_altsettings: %d AltSettings", count);
425     }
426 
427     if (data_len != config_len - sizeof(struct rtk_bt_vendor_config))
428     {
429         HILOGE("rtk_update_altsettings: config len(%x) is not right(%lx)", data_len, (unsigned long)(config_len - sizeof(struct rtk_bt_vendor_config)));
430         return;
431     }
432 
433     for (i = 0; i < data_len;)
434     {
435         for (j = 0; j < count; j++)
436         {
437             if (le16_to_cpu(entry->offset) == offset[j])
438             {
439                 if (offset[j] == patch_entry->mac_offset)
440                     offset[j] = 0;
441                 else
442                 {
443                     struct rtk_bt_vendor_config_entry *t = extra_extry;
444                     while (t->offset)
445                     {
446                         if (t->offset == le16_to_cpu(entry->offset))
447                         {
448                             if (t->entry_len == entry->entry_len)
449                                 offset[j] = 0;
450                             break;
451                         }
452                         t = (struct rtk_bt_vendor_config_entry *)((uint8_t *)t + t->entry_len + sizeof(struct rtk_bt_vendor_config_entry));
453                     }
454                 }
455             }
456         }
457         if (getUsbAltSettingVal(patch_entry, le16_to_cpu(entry->offset), val) == entry->entry_len)
458         {
459             HILOGI("rtk_update_altsettings: replace %04x[%02x]", le16_to_cpu(entry->offset), entry->entry_len);
460             memcpy(entry->entry_data, val, entry->entry_len);
461         }
462         temp = entry->entry_len + sizeof(struct rtk_bt_vendor_config_entry);
463         i += temp;
464         entry = (struct rtk_bt_vendor_config_entry *)((uint8_t *)entry + temp);
465     }
466 
467     for (j = 0; j < count; j++)
468     {
469         if (offset[j] == 0)
470             continue;
471         entry->entry_len = getUsbAltSettingVal(patch_entry, offset[j], val);
472         if (entry->entry_len <= 0)
473             continue;
474         entry->offset = cpu_to_le16(offset[j]);
475         memcpy(entry->entry_data, val, entry->entry_len);
476         HILOGI("rtk_update_altsettings: add %04x[%02x]", le16_to_cpu(entry->offset), entry->entry_len);
477         temp = entry->entry_len + sizeof(struct rtk_bt_vendor_config_entry);
478         i += temp;
479         entry = (struct rtk_bt_vendor_config_entry *)((uint8_t *)entry + temp);
480     }
481     config->data_len = cpu_to_le16(i);
482     *config_len_ptr = i + sizeof(struct rtk_bt_vendor_config);
483 
484     if (extra_extry)
485     {
486         free(extra_extry);
487         extra_extry = NULL;
488         extra_entry_inx = NULL;
489     }
490 
491     HILOGI("NEW Config len=%08zx:\n", *config_len_ptr);
492     for (i = 0; i <= (*config_len_ptr); i += 0x10)
493     {
494         HILOGI("%08x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", i,
495                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],
496                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]);
497     }
498     return;
499 }
500 
rtk_usb_parse_config_file(unsigned char ** config_buf,size_t * filelen,uint8_t bt_addr[6],uint16_t mac_offset)501 static void rtk_usb_parse_config_file(unsigned char **config_buf, size_t *filelen, uint8_t bt_addr[6], uint16_t mac_offset)
502 {
503     struct rtk_bt_vendor_config *config = (struct rtk_bt_vendor_config *)*config_buf;
504     uint16_t config_len = le16_to_cpu(config->data_len), temp = 0;
505     struct rtk_bt_vendor_config_entry *entry = config->entry;
506     unsigned int i = 0;
507     uint8_t heartbeat_buf = 0;
508     // uint32_t config_has_bdaddr = 0;
509     uint8_t *p;
510 
511     HILOGD("bt_addr = %x", bt_addr[0]);
512     if (le32_to_cpu(config->signature) != RTK_VENDOR_CONFIG_MAGIC)
513     {
514         HILOGE("config signature magic number(0x%x) is not set to RTK_VENDOR_CONFIG_MAGIC", config->signature);
515         return;
516     }
517 
518     if (config_len != *filelen - sizeof(struct rtk_bt_vendor_config))
519     {
520         HILOGE("config len(0x%x) is not right(0x%zx)", config_len, *filelen - sizeof(struct rtk_bt_vendor_config));
521         return;
522     }
523 
524     hw_cfg_cb.heartbeat = 0;
525     for (i = 0; i < config_len;)
526     {
527         switch (le16_to_cpu(entry->offset))
528         {
529         case 0x017a:
530         {
531             if (mac_offset == CONFIG_MAC_OFFSET_GEN_1_2)
532             {
533                 p = (uint8_t *)entry->entry_data;
534                 STREAM_TO_UINT8(heartbeat_buf, p);
535                 if ((heartbeat_buf & 0x02) && (heartbeat_buf & 0x10))
536                     hw_cfg_cb.heartbeat = 1;
537                 else
538                     hw_cfg_cb.heartbeat = 0;
539 
540                 HILOGI("config 0x017a heartbeat = %d", hw_cfg_cb.heartbeat);
541             }
542             break;
543         }
544         case 0x01be:
545         {
546             if (mac_offset == CONFIG_MAC_OFFSET_GEN_3PLUS || mac_offset == CONFIG_MAC_OFFSET_GEN_4PLUS)
547             {
548                 p = (uint8_t *)entry->entry_data;
549                 STREAM_TO_UINT8(heartbeat_buf, p);
550                 if ((heartbeat_buf & 0x02) && (heartbeat_buf & 0x10))
551                     hw_cfg_cb.heartbeat = 1;
552                 else
553                     hw_cfg_cb.heartbeat = 0;
554 
555                 HILOGI("config 0x01be heartbeat = %d", hw_cfg_cb.heartbeat);
556             }
557             break;
558         }
559         default:
560             HILOGI("config offset(0x%x),length(0x%x)", entry->offset, entry->entry_len);
561             break;
562         }
563         temp = entry->entry_len + sizeof(struct rtk_bt_vendor_config_entry);
564         i += temp;
565         entry = (struct rtk_bt_vendor_config_entry *)((uint8_t *)entry + temp);
566     }
567 
568     return;
569 }
570 
rtk_usb_get_bt_config(unsigned char ** config_buf,char * config_file_short_name,uint16_t mac_offset)571 static uint32_t rtk_usb_get_bt_config(unsigned char **config_buf,
572                                       char *config_file_short_name, uint16_t mac_offset)
573 {
574     char bt_config_file_name[PATH_MAX] = {0};
575     struct stat st;
576     size_t filelen;
577     int fd;
578     // FILE* file = NULL;
579 
580     sprintf(bt_config_file_name, BT_CONFIG_DIRECTORY, config_file_short_name);
581     HILOGI("BT config file: %s", bt_config_file_name);
582 
583     if (stat(bt_config_file_name, &st) < 0)
584     {
585         HILOGE("can't access bt config file:%s, errno:%d\n", bt_config_file_name, errno);
586         return 0;
587     }
588 
589     filelen = st.st_size;
590     if (filelen > MAX_ORG_CONFIG_SIZE)
591     {
592         HILOGE("bt config file is too large(>0x%04x)", MAX_ORG_CONFIG_SIZE);
593         return 0;
594     }
595 
596     if ((fd = open(bt_config_file_name, O_RDONLY)) < 0)
597     {
598         HILOGE("Can't open bt config file");
599         return 0;
600     }
601 
602     if ((*config_buf = malloc(MAX_ORG_CONFIG_SIZE + MAX_ALT_CONFIG_SIZE)) == NULL)
603     {
604         HILOGE("malloc buffer for config file fail(0x%zx)\n", filelen);
605         close(fd);
606         return 0;
607     }
608 
609     if (read(fd, *config_buf, filelen) < (ssize_t)filelen)
610     {
611         HILOGE("Can't load bt config file");
612         free(*config_buf);
613         close(fd);
614         return 0;
615     }
616 
617     rtk_usb_parse_config_file(config_buf, &filelen, vnd_local_bd_addr, mac_offset);
618 
619     close(fd);
620     return filelen;
621 }
622 
rtk_usb_get_fw_table_entry(uint16_t vid,uint16_t pid)623 static usb_patch_info *rtk_usb_get_fw_table_entry(uint16_t vid, uint16_t pid)
624 {
625     usb_patch_info *patch_entry = usb_fw_patch_table;
626 
627     uint32_t entry_size = sizeof(usb_fw_patch_table) / sizeof(usb_fw_patch_table[0]);
628     uint32_t i;
629 
630     for (i = 0; i < entry_size; i++, patch_entry++)
631     {
632         if ((vid == patch_entry->vid) && (pid == patch_entry->pid))
633             break;
634     }
635 
636     if (i == entry_size)
637     {
638         HILOGE("%s: No fw table entry found", __func__);
639         return NULL;
640     }
641 
642     return patch_entry;
643 }
644 
rtk_usb_get_bt_final_patch(bt_hw_cfg_cb_t * cfg_cb)645 static void rtk_usb_get_bt_final_patch(bt_hw_cfg_cb_t *cfg_cb)
646 {
647     uint8_t proj_id = 0;
648     struct rtk_epatch_entry *entry = NULL;
649     struct rtk_epatch *patch = (struct rtk_epatch *)cfg_cb->fw_buf;
650     // int iBtCalLen = 0;
651 
652     if (cfg_cb->lmp_subversion == LMPSUBVERSION_8723a)
653     {
654         if (memcmp(cfg_cb->fw_buf, RTK_EPATCH_SIGNATURE, 8) == 0)
655         {
656             HILOGE("8723as check signature error!");
657             cfg_cb->dl_fw_flag = 0;
658             goto free_buf;
659         }
660         else
661         {
662             cfg_cb->total_len = cfg_cb->fw_len + cfg_cb->config_len;
663             if (!(cfg_cb->total_buf = malloc(cfg_cb->total_len)))
664             {
665                 HILOGE("can't alloc memory for fw&config, errno:%d", errno);
666                 cfg_cb->dl_fw_flag = 0;
667                 goto free_buf;
668             }
669             else
670             {
671                 HILOGI("8723as, fw copy direct");
672                 memcpy(cfg_cb->total_buf, cfg_cb->fw_buf, cfg_cb->fw_len);
673                 memcpy(cfg_cb->total_buf + cfg_cb->fw_len, cfg_cb->config_buf, cfg_cb->config_len);
674                 // cfg_cb->lmp_sub_current = *(uint16_t *)(cfg_cb->total_buf + cfg_cb->total_len - cfg_cb->config_len - 4);
675                 cfg_cb->dl_fw_flag = 1;
676                 goto free_buf;
677             }
678         }
679     }
680 
681     if (memcmp(cfg_cb->fw_buf, RTK_EPATCH_SIGNATURE, 8))
682     {
683         HILOGE("check signature error");
684         cfg_cb->dl_fw_flag = 0;
685         goto free_buf;
686     }
687 
688     /* check the extension section signature */
689     if (memcmp(cfg_cb->fw_buf + cfg_cb->fw_len - 4, EXTENSION_SECTION_SIGNATURE, 4))
690     {
691         HILOGE("check extension section signature error");
692         cfg_cb->dl_fw_flag = 0;
693         goto free_buf;
694     }
695 
696     proj_id = rtk_get_fw_project_id(cfg_cb->fw_buf + cfg_cb->fw_len - 5);
697     if (usb_project_id[proj_id] != hw_cfg_cb.lmp_subversion_default)
698     {
699         HILOGE("usb_project_id is 0x%08x, fw project_id is %d, does not match!!!",
700                usb_project_id[proj_id], hw_cfg_cb.lmp_subversion);
701         cfg_cb->dl_fw_flag = 0;
702         goto free_buf;
703     }
704 
705     entry = rtk_get_patch_entry(cfg_cb);
706     if (entry)
707     {
708         cfg_cb->total_len = entry->patch_length + cfg_cb->config_len;
709     }
710     else
711     {
712         cfg_cb->dl_fw_flag = 0;
713         goto free_buf;
714     }
715 
716     HILOGI("total_len = 0x%x", cfg_cb->total_len);
717 
718     if (!(cfg_cb->total_buf = malloc(cfg_cb->total_len)))
719     {
720         HILOGE("Can't alloc memory for multi fw&config, errno:%d", errno);
721         cfg_cb->dl_fw_flag = 0;
722         goto free_buf;
723     }
724     else
725     {
726         memcpy(cfg_cb->total_buf, cfg_cb->fw_buf + entry->patch_offset, entry->patch_length);
727         memcpy(cfg_cb->total_buf + entry->patch_length - 4, &patch->fw_version, 4);
728         memcpy(&entry->svn_version, cfg_cb->total_buf + entry->patch_length - 8, 4);
729         memcpy(&entry->coex_version, cfg_cb->total_buf + entry->patch_length - 12, 4);
730 
731         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, patch->fw_version = %x\n",
732                ((entry->coex_version >> 16) & 0x7ff) + ((entry->coex_version >> 27) * 10000),
733                (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, patch->fw_version);
734     }
735 
736     if (cfg_cb->config_len)
737     {
738         memcpy(cfg_cb->total_buf + entry->patch_length, cfg_cb->config_buf, cfg_cb->config_len);
739     }
740 
741     cfg_cb->dl_fw_flag = 1;
742     HILOGI("Fw:%s exists, config file:%s exists", (cfg_cb->fw_len > 0) ? "" : "not", (cfg_cb->config_len > 0) ? "" : "not");
743 
744 free_buf:
745     if (cfg_cb->fw_len > 0)
746     {
747         free(cfg_cb->fw_buf);
748         cfg_cb->fw_len = 0;
749     }
750 
751     if (cfg_cb->config_len > 0)
752     {
753         free(cfg_cb->config_buf);
754         cfg_cb->config_len = 0;
755     }
756 
757     if (entry)
758     {
759         free(entry);
760     }
761 }
762 
usb_hci_download_patch_h4(HC_BT_HDR * p_buf,int index,uint8_t * data,int len)763 static int usb_hci_download_patch_h4(HC_BT_HDR *p_buf, int index, uint8_t *data, int len)
764 {
765     int retval = FALSE;
766     uint8_t *p = (uint8_t *)(p_buf + 1);
767 
768     UINT16_TO_STREAM(p, HCI_VSC_DOWNLOAD_FW_PATCH);
769     *p++ = 1 + len; /* parameter length */
770     *p++ = index;
771     memcpy(p, data, len);
772     p_buf->len = HCI_CMD_PREAMBLE_SIZE + 1 + len;
773 
774     hw_cfg_cb.state = HW_CFG_DL_FW_PATCH;
775 
776     retval = bt_vendor_cbacks->xmit_cb(HCI_VSC_DOWNLOAD_FW_PATCH, p_buf);
777     return retval;
778 }
779 
rtk_usb_get_fw_version(bt_hw_cfg_cb_t * cfg_cb)780 static void rtk_usb_get_fw_version(bt_hw_cfg_cb_t *cfg_cb)
781 {
782     struct rtk_epatch *patch = (struct rtk_epatch *)cfg_cb->fw_buf;
783 
784     if (cfg_cb->lmp_subversion == LMPSUBVERSION_8723a)
785     {
786         cfg_cb->lmp_sub_current = 0;
787     }
788     else
789     {
790         cfg_cb->lmp_sub_current = (uint16_t)patch->fw_version;
791     }
792 }
793 /*******************************************************************************
794 **
795 ** Function         hw_usb_config_cback
796 **
797 ** Description      Callback function for controller configuration
798 **
799 ** Returns          None
800 **
801 *******************************************************************************/
hw_usb_config_cback(void * p_mem)802 void hw_usb_config_cback(void *p_mem)
803 {
804     HC_BT_HDR *p_evt_buf = NULL;
805     uint8_t *p = NULL; //, *pp=NULL;
806     uint8_t status = 0;
807     uint16_t opcode = 0;
808     HC_BT_HDR *p_buf = NULL;
809     int is_proceeding = FALSE;
810     // int         i = 0;
811     uint8_t iIndexRx = 0;
812     // patch_info* prtk_patch_file_info = NULL;
813     usb_patch_info *prtk_usb_patch_file_info = NULL;
814     // uint32_t    host_baudrate = 0;
815 
816 #if (USE_CONTROLLER_BDADDR == TRUE)
817     // const uint8_t null_bdaddr[BD_ADDR_LEN] = {0,0,0,0,0,0};
818 #endif
819 
820     if (p_mem != NULL)
821     {
822         p_evt_buf = (HC_BT_HDR *)p_mem;
823         status = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_OFFSET);
824         p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE_OFFSET;
825         STREAM_TO_UINT16(opcode, p);
826     }
827 
828     /* Ask a new buffer big enough to hold any HCI commands sent in here */
829     /*a cut fc6d status==1*/
830     if (((status == 0) || (opcode == HCI_VSC_READ_ROM_VERSION)) && bt_vendor_cbacks)
831         p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + HCI_CMD_MAX_LEN);
832 
833     if (p_buf != NULL)
834     {
835         p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
836         p_buf->offset = 0;
837         p_buf->len = 0;
838         p_buf->layer_specific = 0;
839 
840         BTVNDDBG("hw_cfg_cb.state = %i", hw_cfg_cb.state);
841         switch (hw_cfg_cb.state)
842         {
843         case HW_CFG_RESET_CHANNEL_CONTROLLER:
844         {
845             usleep(300000);
846             hw_cfg_cb.state = HW_CFG_READ_LOCAL_VER;
847             p = (uint8_t *)(p_buf + 1);
848             UINT16_TO_STREAM(p, HCI_READ_LMP_VERSION);
849             *p++ = 0;
850             p_buf->len = HCI_CMD_PREAMBLE_SIZE;
851             is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_READ_LMP_VERSION, p_buf);
852             break;
853         }
854         case HW_CFG_READ_LOCAL_VER:
855         {
856             if (status == 0 && p_evt_buf)
857             {
858                 p = ((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OP1001_HCI_VERSION_OFFSET);
859                 STREAM_TO_UINT16(hw_cfg_cb.hci_version, p);
860                 p = ((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OP1001_HCI_REVISION_OFFSET);
861                 STREAM_TO_UINT16(hw_cfg_cb.hci_revision, p);
862                 p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OP1001_LMP_SUBVERSION_OFFSET;
863                 STREAM_TO_UINT16(hw_cfg_cb.lmp_subversion, p);
864 
865                 prtk_usb_patch_file_info = rtk_usb_get_fw_table_entry(hw_cfg_cb.vid, hw_cfg_cb.pid);
866                 if ((prtk_usb_patch_file_info == NULL) || (prtk_usb_patch_file_info->lmp_sub_default == 0))
867                 {
868                     HILOGE("get patch entry error");
869                     is_proceeding = FALSE;
870                     break;
871                 }
872                 hw_cfg_cb.config_len = rtk_usb_get_bt_config(&hw_cfg_cb.config_buf, prtk_usb_patch_file_info->config_name, prtk_usb_patch_file_info->mac_offset);
873                 hw_cfg_cb.fw_len = rtk_get_bt_firmware(&hw_cfg_cb.fw_buf, prtk_usb_patch_file_info->patch_name);
874                 rtk_usb_get_fw_version(&hw_cfg_cb);
875 
876                 hw_cfg_cb.lmp_subversion_default = prtk_usb_patch_file_info->lmp_sub_default;
877                 BTVNDDBG("lmp_subversion = 0x%x hw_cfg_cb.hci_version = 0x%x hw_cfg_cb.hci_revision = 0x%x, hw_cfg_cb.lmp_sub_current = 0x%x",
878                          hw_cfg_cb.lmp_subversion, hw_cfg_cb.hci_version, hw_cfg_cb.hci_revision, hw_cfg_cb.lmp_sub_current);
879 
880                 if (prtk_usb_patch_file_info->lmp_sub_default == hw_cfg_cb.lmp_subversion)
881                 {
882                     BTVNDDBG("%s: Cold BT controller startup", __func__);
883                     // hw_cfg_cb.state = HW_CFG_START;
884                     // goto CFG_USB_START;
885                     hw_cfg_cb.state = HW_CFG_READ_ECO_VER;
886                     p = (uint8_t *)(p_buf + 1);
887                     UINT16_TO_STREAM(p, HCI_VSC_READ_ROM_VERSION);
888                     *p++ = 0;
889                     p_buf->len = HCI_CMD_PREAMBLE_SIZE;
890                     is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_VSC_READ_ROM_VERSION, p_buf);
891                 }
892                 else if (hw_cfg_cb.lmp_subversion != hw_cfg_cb.lmp_sub_current)
893                 {
894                     BTVNDDBG("%s: Warm BT controller startup with updated lmp", __func__);
895                     goto RESET_HW_CONTROLLER;
896                 }
897                 else
898                 {
899                     BTVNDDBG("%s: Warm BT controller startup with same lmp", __func__);
900                     userial_vendor_usb_ioctl(DWFW_CMPLT, &hw_cfg_cb.lmp_sub_current);
901                     free(hw_cfg_cb.total_buf);
902                     hw_cfg_cb.total_len = 0;
903 
904                     bt_vendor_cbacks->dealloc(p_buf);
905                     start_fwcfg_cbtimer();
906                     hw_cfg_cb.state = 0;
907                     is_proceeding = TRUE;
908                 }
909 
910                 /*                   if(hw_cfg_cb.lmp_subversion == LMPSUBVERSION_8723a)
911                                    {
912                                        hw_cfg_cb.state = HW_CFG_START;
913                                        goto CFG_USB_START;
914                                    }
915                                    else
916                                    {
917                                        hw_cfg_cb.state = HW_CFG_READ_ECO_VER;
918                                        p = (uint8_t *) (p_buf + 1);
919                                        UINT16_TO_STREAM(p, HCI_VSC_READ_ROM_VERSION);
920                                        *p++ = 0;
921                                        p_buf->len = HCI_CMD_PREAMBLE_SIZE;
922                                        is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_VSC_READ_ROM_VERSION, p_buf);
923                                    }*/
924             }
925             else
926             {
927                 HILOGE("status = %d, or p_evt_buf is NULL", status);
928             }
929             break;
930         }
931 RESET_HW_CONTROLLER:
932         case HW_RESET_CONTROLLER:
933         {
934             if (status == 0)
935             {
936                 // usleep(300000);//300ms
937                 userial_vendor_usb_ioctl(RESET_CONTROLLER, NULL); // reset controller
938                 hw_cfg_cb.state = HW_CFG_READ_ECO_VER;
939                 p = (uint8_t *)(p_buf + 1);
940                 UINT16_TO_STREAM(p, HCI_VSC_READ_ROM_VERSION);
941                 *p++ = 0;
942                 p_buf->len = HCI_CMD_PREAMBLE_SIZE;
943                 is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_VSC_READ_ROM_VERSION, p_buf);
944             }
945             break;
946         }
947         case HW_CFG_READ_ECO_VER:
948         {
949             if (status == 0 && p_evt_buf)
950             {
951                 hw_cfg_cb.eversion = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPFC6D_EVERSION_OFFSET);
952                 BTVNDDBG("hw_usb_config_cback chip_id of the IC:%d", hw_cfg_cb.eversion + 1);
953             }
954             else if (1 == status)
955             {
956                 hw_cfg_cb.eversion = 0;
957             }
958             else
959             {
960                 is_proceeding = FALSE;
961                 break;
962             }
963 
964             hw_cfg_cb.state = HW_CFG_START;
965             goto CFG_USB_START;
966         }
967 CFG_USB_START:
968         case HW_CFG_START:
969         {
970             // get efuse config file and patch code file
971             prtk_usb_patch_file_info = rtk_usb_get_fw_table_entry(hw_cfg_cb.vid, hw_cfg_cb.pid);
972 
973             if ((prtk_usb_patch_file_info == NULL) || (prtk_usb_patch_file_info->lmp_sub_default == 0))
974             {
975                 HILOGE("get patch entry error");
976                 is_proceeding = FALSE;
977                 break;
978             }
979             hw_cfg_cb.max_patch_size = prtk_usb_patch_file_info->max_patch_size;
980             hw_cfg_cb.config_len = rtk_usb_get_bt_config(&hw_cfg_cb.config_buf, prtk_usb_patch_file_info->config_name, prtk_usb_patch_file_info->mac_offset);
981             if (hw_cfg_cb.config_len)
982             {
983                 HILOGE("update altsettings");
984                 rtk_usb_update_altsettings(prtk_usb_patch_file_info, hw_cfg_cb.config_buf, &(hw_cfg_cb.config_len));
985             }
986 
987             hw_cfg_cb.fw_len = rtk_get_bt_firmware(&hw_cfg_cb.fw_buf, prtk_usb_patch_file_info->patch_name);
988             if (hw_cfg_cb.fw_len < 0)
989             {
990                 HILOGE("Get BT firmware fail");
991                 hw_cfg_cb.fw_len = 0;
992                 is_proceeding = FALSE;
993                 break;
994             }
995             else
996             {
997                 // hw_cfg_cb.project_id_mask = prtk_usb_patch_file_info->project_id_mask;
998                 rtk_usb_get_bt_final_patch(&hw_cfg_cb);
999             }
1000 
1001             BTVNDDBG("Check total_len(0x%08x) max_patch_size(0x%08x)", hw_cfg_cb.total_len, hw_cfg_cb.max_patch_size);
1002             if (hw_cfg_cb.total_len > hw_cfg_cb.max_patch_size)
1003             {
1004                 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);
1005                 is_proceeding = FALSE;
1006                 break;
1007             }
1008 
1009             if ((hw_cfg_cb.total_len > 0) && hw_cfg_cb.dl_fw_flag)
1010             {
1011                 hw_cfg_cb.patch_frag_cnt = hw_cfg_cb.total_len / PATCH_DATA_FIELD_MAX_SIZE;
1012                 hw_cfg_cb.patch_frag_tail = hw_cfg_cb.total_len % PATCH_DATA_FIELD_MAX_SIZE;
1013                 if (hw_cfg_cb.patch_frag_tail)
1014                     hw_cfg_cb.patch_frag_cnt += 1;
1015                 else
1016                     hw_cfg_cb.patch_frag_tail = PATCH_DATA_FIELD_MAX_SIZE;
1017                 BTVNDDBG("patch fragment count %d, tail len %d", hw_cfg_cb.patch_frag_cnt, hw_cfg_cb.patch_frag_tail);
1018             }
1019             else
1020             {
1021                 is_proceeding = FALSE;
1022                 break;
1023             }
1024 
1025             goto DOWNLOAD_USB_FW;
1026         }
1027             /* fall through intentionally */
1028 
1029 DOWNLOAD_USB_FW:
1030         case HW_CFG_DL_FW_PATCH:
1031             BTVNDDBG("bt vendor lib: HW_CFG_DL_FW_PATCH status:%i, opcode:0x%x", status, opcode);
1032 
1033             // recv command complete event for patch code download command
1034             if (opcode == HCI_VSC_DOWNLOAD_FW_PATCH)
1035             {
1036                 iIndexRx = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_OFFSET + 1);
1037                 BTVNDDBG("bt vendor lib: HW_CFG_DL_FW_PATCH status:%i, iIndexRx:%i", status, iIndexRx);
1038                 hw_cfg_cb.patch_frag_idx++;
1039 
1040                 if (iIndexRx & 0x80)
1041                 {
1042                     BTVNDDBG("vendor lib fwcfg completed");
1043                     userial_vendor_usb_ioctl(DWFW_CMPLT, &hw_cfg_cb.lmp_sub_current);
1044                     free(hw_cfg_cb.total_buf);
1045                     hw_cfg_cb.total_len = 0;
1046 
1047                     bt_vendor_cbacks->dealloc(p_buf);
1048                     // bt_vendor_cbacks->fwcfg_cb(BTC_OP_RESULT_SUCCESS);
1049                     start_fwcfg_cbtimer();
1050 
1051                     hw_cfg_cb.state = 0;
1052                     is_proceeding = TRUE;
1053                     break;
1054                 }
1055             }
1056 
1057             if (hw_cfg_cb.patch_frag_idx < hw_cfg_cb.patch_frag_cnt)
1058             {
1059                 iIndexRx = hw_cfg_cb.patch_frag_idx ? ((hw_cfg_cb.patch_frag_idx - 1) % 0x7f + 1) : 0;
1060                 if (hw_cfg_cb.patch_frag_idx == hw_cfg_cb.patch_frag_cnt - 1)
1061                 {
1062                     BTVNDDBG("HW_CFG_DL_FW_PATCH: send last fw fragment");
1063                     iIndexRx |= 0x80;
1064                     hw_cfg_cb.patch_frag_len = hw_cfg_cb.patch_frag_tail;
1065                 }
1066                 else
1067                 {
1068                     iIndexRx &= 0x7F;
1069                     hw_cfg_cb.patch_frag_len = PATCH_DATA_FIELD_MAX_SIZE;
1070                 }
1071             }
1072 
1073             is_proceeding = usb_hci_download_patch_h4(p_buf, iIndexRx,
1074                                                       hw_cfg_cb.total_buf + (hw_cfg_cb.patch_frag_idx * PATCH_DATA_FIELD_MAX_SIZE),
1075                                                       hw_cfg_cb.patch_frag_len);
1076             break;
1077         default:
1078             break;
1079         } // switch(hw_cfg_cb.state)
1080     }     // if (p_buf != NULL)
1081 
1082     if (is_proceeding == FALSE)
1083     {
1084         HILOGE("vendor lib fwcfg aborted!!!");
1085         if (bt_vendor_cbacks)
1086         {
1087             if (p_buf != NULL)
1088                 bt_vendor_cbacks->dealloc(p_buf);
1089 
1090             userial_vendor_usb_ioctl(DWFW_CMPLT, &hw_cfg_cb.lmp_sub_current);
1091             // bt_vendor_cbacks->fwcfg_cb(BTC_OP_RESULT_FAIL);
1092 
1093             bt_vendor_cbacks->init_cb(BTC_OP_RESULT_FAIL);
1094         }
1095 
1096         if (hw_cfg_cb.config_len)
1097         {
1098             free(hw_cfg_cb.config_buf);
1099             hw_cfg_cb.config_len = 0;
1100         }
1101 
1102         if (hw_cfg_cb.fw_len)
1103         {
1104             free(hw_cfg_cb.fw_buf);
1105             hw_cfg_cb.fw_len = 0;
1106         }
1107 
1108         if (hw_cfg_cb.total_len)
1109         {
1110             free(hw_cfg_cb.total_buf);
1111             hw_cfg_cb.total_len = 0;
1112         }
1113         hw_cfg_cb.state = 0;
1114     }
1115 }
1116 
1117 /*******************************************************************************
1118 **
1119 ** Function        hw__usb_config_start
1120 **
1121 ** Description     Kick off controller initialization process
1122 **
1123 ** Returns         None
1124 **
1125 *******************************************************************************/
hw_usb_config_start(char transtype,uint32_t usb_id)1126 void hw_usb_config_start(char transtype, uint32_t usb_id)
1127 {
1128     RTK_UNUSED(transtype);
1129     memset(&hw_cfg_cb, 0, sizeof(bt_hw_cfg_cb_t));
1130     hw_cfg_cb.dl_fw_flag = 1;
1131     hw_cfg_cb.chip_type = CHIPTYPE_NONE;
1132     hw_cfg_cb.pid = usb_id & 0x0000ffff;
1133     hw_cfg_cb.vid = (usb_id >> 16) & 0x0000ffff;
1134     BTVNDDBG("RTKBT_RELEASE_NAME: %s", RTKBT_RELEASE_NAME);
1135     BTVNDDBG("\nRealtek libbt-vendor_usb Version %s \n", RTK_VERSION);
1136     HC_BT_HDR *p_buf = NULL;
1137     uint8_t *p;
1138 
1139     BTVNDDBG("hw_usb_config_start, transtype = 0x%x, pid = 0x%04x, vid = 0x%04x \n", transtype, hw_cfg_cb.pid, hw_cfg_cb.vid);
1140 
1141     if (bt_vendor_cbacks)
1142     {
1143         /* Must allocate command buffer via HC's alloc API */
1144         p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE +
1145                                                      HCI_CMD_PREAMBLE_SIZE);
1146         if (p_buf)
1147         {
1148             p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
1149             p_buf->offset = 0;
1150             p_buf->layer_specific = 0;
1151             p_buf->len = HCI_CMD_PREAMBLE_SIZE;
1152 
1153             p = (uint8_t *)(p_buf + 1);
1154 
1155             p = (uint8_t *)(p_buf + 1);
1156             UINT16_TO_STREAM(p, HCI_VENDOR_RESET);
1157             *p++ = 0;
1158             p_buf->len = HCI_CMD_PREAMBLE_SIZE;
1159 
1160             hw_cfg_cb.state = HW_CFG_RESET_CHANNEL_CONTROLLER;
1161             bt_vendor_cbacks->xmit_cb(HCI_VENDOR_RESET, p_buf);
1162         }
1163         else
1164         {
1165             HILOGE("%s buffer alloc fail!", __func__);
1166             bt_vendor_cbacks->init_cb(BTC_OP_RESULT_FAIL);
1167         }
1168     }
1169     else
1170         HILOGE("%s call back is null", __func__);
1171 }
1172