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