Android-x86
Fork
Donation

  • R/O
  • HTTP
  • SSH
  • HTTPS

external-bluetooth-bluez: Commit

external/bluetooth/bluez


Commit MetaInfo

Revisionde7b62e01ae65b3c7a8412515996387fbc431834 (tree)
Time2017-06-07 10:52:44
AuthorChih-Wei Huang <cwhuang@linu...>
CommiterChih-Wei Huang

Log Message

Add RTL8723BS Bluetooth tool

Copy and modify from https://github.com/lwfinger/rtl8723bs_bt.

Change Summary

Incremental Difference

--- a/android/Android.mk
+++ b/android/Android.mk
@@ -716,6 +716,25 @@ LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/bluez/configure.ac
716716 include $(BUILD_EXECUTABLE)
717717
718718 #
719+# rtk_hciattach
720+#
721+
722+include $(CLEAR_VARS)
723+
724+LOCAL_SRC_FILES := \
725+ bluez/tools/hciattach.c \
726+ bluez/tools/hciattach_rtk.c \
727+
728+LOCAL_C_INCLUDES := \
729+ $(LOCAL_PATH)/bluez \
730+
731+LOCAL_MODULE_TAGS := optional
732+LOCAL_MODULE := rtk_hciattach
733+LOCAL_PROPRIETARY_MODULE := true
734+
735+include $(BUILD_EXECUTABLE)
736+
737+#
719738 # brcm_patchram_plus
720739 #
721740 include $(CLEAR_VARS)
--- a/tools/hciattach.c
+++ b/tools/hciattach.c
@@ -146,6 +146,7 @@ int read_hci_event(int fd, unsigned char* buf, int size)
146146 return count;
147147 }
148148
149+#if 0
149150 /*
150151 * Ericsson specific initialization
151152 */
@@ -989,11 +990,28 @@ static int bcm2035(int fd, struct uart_t *u, struct termios *ti)
989990
990991 return 0;
991992 }
993+#endif
994+
995+int rtk_init(int fd, int proto, int speed, struct termios *ti);
996+int rtk_post(int fd, int proto, struct termios *ti);
997+
998+static int realtek_init(int fd, struct uart_t *u, struct termios *ti)
999+{
1000+ fprintf(stderr, "Realtek Bluetooth init uart with init speed:%d, final_speed:%d, type:HCI UART %s\n", u->init_speed, u->speed, (u->proto == HCI_UART_H4)? "H4":"H5" );
1001+ return rtk_init(fd, u->proto, u->speed, ti);
1002+}
1003+
1004+static int realtek_post(int fd, struct uart_t *u, struct termios *ti)
1005+{
1006+ fprintf(stderr, "Realtek Bluetooth post process\n");
1007+ return rtk_post(fd, u->proto, ti);
1008+}
9921009
9931010 struct uart_t uart[] = {
9941011 { "any", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200,
9951012 FLOW_CTL, DISABLE_PM, NULL, NULL },
9961013
1014+#if 0
9971015 { "ericsson", 0x0000, 0x0000, HCI_UART_H4, 57600, 115200,
9981016 FLOW_CTL, DISABLE_PM, NULL, ericsson },
9991017
@@ -1109,6 +1127,18 @@ struct uart_t uart[] = {
11091127 { "amp", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200,
11101128 AMP_DEV, DISABLE_PM, NULL, NULL, NULL },
11111129
1130+#endif
1131+
1132+ /* Realtek Bluetooth H4*/
1133+ /* H4 will set 115200 baudrate and flow control enable by default*/
1134+ { "rtk_h4", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200,
1135+ 0, DISABLE_PM, NULL, realtek_init, realtek_post },
1136+
1137+ /* Realtek Bluetooth H5*/
1138+ /* H5 will set 115200 baudrate and flow control disable by default */
1139+ { "rtk_h5", 0x0000, 0x0000, HCI_UART_3WIRE, 115200, 115200,
1140+ 0, DISABLE_PM, NULL, realtek_init, realtek_post },
1141+
11121142 { NULL, 0 }
11131143 };
11141144
@@ -1370,7 +1400,9 @@ int main(int argc, char *argv[])
13701400
13711401 /* 10 seconds should be enough for initialization */
13721402 alarm(to);
1403+#if 0
13731404 bcsp_max_retries = to;
1405+#endif
13741406
13751407 n = init_uart(dev, u, send_break, raw);
13761408 if (n < 0) {
--- /dev/null
+++ b/tools/hciattach_rtk.c
@@ -0,0 +1,2454 @@
1+/**
2+*Copyright @ Realtek Semiconductor Corp. All Rights Reserved.
3+*
4+
5+*Module Name:
6+* hciattach_rtk.c
7+*
8+*Description:
9+* H4/H5 specific initialization
10+*
11+*Revision History:
12+* Date Version Author Comment
13+* ---------- --------- --------------- -----------------------
14+* 2013-06-06 1.0.0 gordon_yang Create
15+* 2013-06-18 1.0.1 lory_xu add support for multi fw
16+* 2013-06-21 1.0.2 gordon_yang add timeout for get version cmd
17+* 2013-07-01 1.0.3 lory_xu close file handle
18+* 2013-07-01 2.0 champion_chen add IC check
19+* 2013-12-16 2.1 champion_chen fix bug in Additional packet number
20+* 2013-12-25 2.2 champion_chen open host flow control after send last fw packet
21+*/
22+
23+#ifdef HAVE_CONFIG_H
24+#include <config.h>
25+#endif
26+
27+#include <stdio.h>
28+#include <errno.h>
29+#include <unistd.h>
30+#include <stdlib.h>
31+#include <termios.h>
32+#include <time.h>
33+#include <sys/time.h>
34+#include <sys/types.h>
35+#include <sys/param.h>
36+#include <sys/ioctl.h>
37+#include <sys/socket.h>
38+#include <sys/uio.h>
39+#include <sys/stat.h>
40+#include <fcntl.h>
41+#include <signal.h>
42+#include <stdint.h>
43+#include <string.h>
44+#include <endian.h>
45+#include <byteswap.h>
46+#include <netinet/in.h>
47+
48+#include "lib/bluetooth.h"
49+#include "hciattach.h"
50+
51+#define RTK_VERSION "2.5"
52+
53+#define BAUDRATE_4BYTES
54+//#define USE_CUSTUMER_ADDRESS
55+#define FIRMWARE_DIRECTORY "/lib/firmware/rtl_bt/"
56+#define BT_CONFIG_DIRECTORY "/lib/firmware/rtl_bt/"
57+
58+#ifdef USE_CUSTUMER_ADDRESS
59+#define BT_ADDR_DIR "/data/bt_mac/"
60+#define BT_ADDR_FILE "/data/bt_mac/btmac.txt"
61+#endif
62+
63+#if __BYTE_ORDER == __LITTLE_ENDIAN
64+#define cpu_to_le16(d) (d)
65+#define cpu_to_le32(d) (d)
66+#define le16_to_cpu(d) (d)
67+#define le32_to_cpu(d) (d)
68+#elif __BYTE_ORDER == __BIG_ENDIAN
69+#define cpu_to_le16(d) bswap_16(d)
70+#define cpu_to_le32(d) bswap_32(d)
71+#define le16_to_cpu(d) bswap_16(d)
72+#define le32_to_cpu(d) bswap_32(d)
73+#else
74+#error "Unknown byte order"
75+#endif
76+
77+typedef uint8_t RT_U8, *PRT_U8;
78+typedef int8_t RT_S8, *PRT_S8;
79+typedef uint16_t RT_U16, *PRT_U16;
80+typedef int32_t RT_S32, *PRT_S32;
81+typedef uint32_t RT_U32, *PRT_U32;
82+
83+RT_U8 DBG_ON = 1;
84+#define LOG_STR "Realtek Bluetooth"
85+#define RS_DBG(fmt, arg...) \
86+ do{ \
87+ if (DBG_ON) \
88+ fprintf(stderr, "%s :" fmt "\n" , LOG_STR, ##arg); \
89+ }while(0)
90+
91+#define RS_ERR(fmt, arg...) \
92+ do{ \
93+ fprintf(stderr, "%s ERROR: " fmt "\n", LOG_STR, ##arg); \
94+ }while(0)
95+
96+
97+#define HCI_COMMAND_HDR_SIZE 3
98+#define HCI_EVENT_HDR_SIZE 2
99+#define RTK_PATCH_LENGTH_MAX 24576 //24*1024
100+#define PATCH_DATA_FIELD_MAX_SIZE 252
101+#define READ_DATA_SIZE 16
102+#define H5_MAX_RETRY_COUNT 40
103+
104+#define RTK_VENDOR_CONFIG_MAGIC 0x8723ab55
105+const RT_U8 RTK_EPATCH_SIGNATURE[8] = {0x52,0x65,0x61,0x6C,0x74,0x65,0x63,0x68};
106+const RT_U8 Extension_Section_SIGNATURE[4] = {0x51,0x04,0xFD,0x77};
107+
108+#define HCI_CMD_READ_BD_ADDR 0x1009
109+#define HCI_VENDOR_CHANGE_BDRATE 0xfc17
110+#define HCI_VENDOR_READ_RTK_ROM_VERISION 0xfc6d
111+#define HCI_VENDOR_READ_LMP_VERISION 0x1001
112+
113+#define ROM_LMP_NONE 0x0000
114+#define ROM_LMP_8723a 0x1200
115+#define ROM_LMP_8723b 0x8723
116+#define ROM_LMP_8821a 0x8821
117+#define ROM_LMP_8761a 0x8761
118+
119+/* HCI data types */
120+#define H5_ACK_PKT 0x00
121+#define HCI_COMMAND_PKT 0x01
122+#define HCI_ACLDATA_PKT 0x02
123+#define HCI_SCODATA_PKT 0x03
124+#define HCI_EVENT_PKT 0x04
125+#define H5_VDRSPEC_PKT 0x0E
126+#define H5_LINK_CTL_PKT 0x0F
127+
128+#define H5_HDR_SEQ(hdr) ((hdr)[0] & 0x07)
129+#define H5_HDR_ACK(hdr) (((hdr)[0] >> 3) & 0x07)
130+#define H5_HDR_CRC(hdr) (((hdr)[0] >> 6) & 0x01)
131+#define H5_HDR_RELIABLE(hdr) (((hdr)[0] >> 7) & 0x01)
132+#define H5_HDR_PKT_TYPE(hdr) ((hdr)[1] & 0x0f)
133+#define H5_HDR_LEN(hdr) ((((hdr)[1] >> 4) & 0xff) + ((hdr)[2] << 4))
134+#define H5_HDR_SIZE 4
135+
136+struct sk_buff
137+{
138+ RT_U32 max_len;
139+ RT_U32 data_len;
140+ RT_U8 data[0];
141+};
142+
143+/* Skb helpers */
144+struct bt_skb_cb
145+{
146+ RT_U8 pkt_type;
147+ RT_U8 incoming;
148+ RT_U16 expect;
149+ RT_U8 tx_seq;
150+ RT_U8 retries;
151+ RT_U8 sar;
152+ unsigned short channel;
153+};
154+
155+typedef struct {
156+ uint8_t index;
157+ uint8_t data[252];
158+} __attribute__ ((packed)) download_vendor_patch_cp;
159+
160+struct hci_command_hdr {
161+ RT_U16 opcode;
162+ RT_U8 plen;
163+} __attribute__ ((packed));
164+
165+struct hci_event_hdr {
166+ RT_U8 evt;
167+ RT_U8 plen;
168+} __attribute__ ((packed));
169+
170+struct hci_ev_cmd_complete {
171+ RT_U8 ncmd;
172+ RT_U16 opcode;
173+} __attribute__ ((packed));
174+
175+struct rtk_bt_vendor_config_entry{
176+ RT_U16 offset;
177+ RT_U8 entry_len;
178+ RT_U8 entry_data[0];
179+} __attribute__ ((packed));
180+
181+struct rtk_bt_vendor_config{
182+ RT_U32 signature;
183+ RT_U16 data_len;
184+ struct rtk_bt_vendor_config_entry entry[0];
185+} __attribute__ ((packed));
186+
187+struct rtk_epatch_entry{
188+ RT_U16 chipID;
189+ RT_U16 patch_length;
190+ RT_U32 start_offset;
191+} __attribute__ ((packed));
192+
193+struct rtk_epatch{
194+ RT_U8 signature[8];
195+ RT_U32 fw_version;
196+ RT_U16 number_of_patch;
197+ struct rtk_epatch_entry entry[0];
198+} __attribute__ ((packed));
199+
200+struct rtk_extension_entry{
201+ uint8_t opcode;
202+ uint8_t length;
203+ uint8_t *data;
204+} __attribute__ ((packed));
205+
206+typedef enum _RTK_ROM_VERSION_CMD_STATE
207+{
208+ cmd_not_send,
209+ cmd_has_sent,
210+ event_received
211+} RTK_ROM_VERSION_CMD_STATE;
212+
213+typedef enum _H5_RX_STATE
214+{
215+ H5_W4_PKT_DELIMITER,
216+ H5_W4_PKT_START,
217+ H5_W4_HDR,
218+ H5_W4_DATA,
219+ H5_W4_CRC
220+} H5_RX_STATE;
221+
222+typedef enum _H5_RX_ESC_STATE
223+{
224+ H5_ESCSTATE_NOESC,
225+ H5_ESCSTATE_ESC
226+} H5_RX_ESC_STATE;
227+
228+typedef enum _H5_LINK_STATE
229+{
230+ H5_SYNC,
231+ H5_CONFIG,
232+ H5_INIT,
233+ H5_PATCH,
234+ H5_ACTIVE
235+} H5_LINK_STATE;
236+
237+typedef struct {
238+/**********************h5 releated*************************/
239+ RT_U8 rxseq_txack; /* expected rx seq number */
240+ RT_U8 rxack; /* last packet sent by us that the peer ack'ed */
241+ RT_U8 use_crc;
242+ RT_U8 is_txack_req; /* txack required */
243+ RT_U8 msgq_txseq; /* next pkt seq */
244+ RT_U16 message_crc;
245+ RT_U32 rx_count; /* expected pkts to recv */
246+
247+ H5_RX_STATE rx_state;
248+ H5_RX_ESC_STATE rx_esc_state;
249+ H5_LINK_STATE link_estab_state;
250+
251+ struct sk_buff *rx_skb;
252+ struct sk_buff *host_last_cmd;
253+
254+ RT_U16 lmp_version;
255+ RT_U8 eversion;
256+ int h5_max_retries;
257+
258+/**********************patch releated************************/
259+ uint32_t baudrate;
260+ uint8_t dl_fw_flag;
261+ int serial_fd;
262+ int hw_flow_control;
263+ int final_speed;
264+ int total_num; /* total pkt number */
265+ int tx_index; /* current sending pkt number */
266+ int rx_index; /* ack index from board */
267+ int fw_len; /* fw patch file len */
268+ int config_len; /* config patch file len */
269+ int total_len; /* fw & config extracted buf len */
270+ uint8_t *fw_buf; /* fw patch file buf */
271+ uint8_t *config_buf; /* config patch file buf */
272+ uint8_t *total_buf; /* fw & config extracted buf */
273+ RTK_ROM_VERSION_CMD_STATE rom_version_cmd_state;
274+ RTK_ROM_VERSION_CMD_STATE hci_version_cmd_state;
275+}rtk_hw_cfg_t;
276+
277+static rtk_hw_cfg_t rtk_hw_cfg;
278+
279+uint16_t project_id[]=
280+{
281+ ROM_LMP_8723a,
282+ ROM_LMP_8723b,
283+ ROM_LMP_8821a,
284+ ROM_LMP_8761a,
285+ ROM_LMP_NONE
286+};
287+
288+
289+// bite reverse in bytes
290+// 00000001 -> 10000000
291+// 00000100 -> 00100000
292+const RT_U8 byte_rev_table[256] = {
293+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
294+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
295+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
296+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
297+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
298+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
299+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
300+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
301+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
302+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
303+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
304+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
305+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
306+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
307+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
308+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
309+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
310+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
311+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
312+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
313+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
314+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
315+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
316+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
317+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
318+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
319+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
320+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
321+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
322+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
323+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
324+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
325+};
326+
327+static __inline RT_U8 bit_rev8(RT_U8 byte)
328+{
329+ return byte_rev_table[byte];
330+}
331+
332+static __inline RT_U16 bit_rev16(RT_U16 x)
333+{
334+ return (bit_rev8(x & 0xff) << 8) | bit_rev8(x >> 8);
335+}
336+
337+static const RT_U16 crc_table[] =
338+{
339+ 0x0000, 0x1081, 0x2102, 0x3183,
340+ 0x4204, 0x5285, 0x6306, 0x7387,
341+ 0x8408, 0x9489, 0xa50a, 0xb58b,
342+ 0xc60c, 0xd68d, 0xe70e, 0xf78f
343+};
344+
345+// Initialise the crc calculator
346+#define H5_CRC_INIT(x) x = 0xffff
347+
348+/**
349+* Malloc the socket buffer
350+*
351+* @param skb socket buffer
352+* @return the point to the malloc buffer
353+*/
354+static __inline struct sk_buff * skb_alloc(unsigned int len)
355+{
356+ struct sk_buff *skb = NULL;
357+ if ((skb = malloc(len + 8))) {
358+ skb->max_len= len;
359+ skb->data_len = 0;
360+ } else {
361+ RS_ERR("Allocate skb fails!!!");
362+ skb = NULL;
363+ }
364+ memset(skb->data, 0, len);
365+ return skb;
366+}
367+/**
368+* Free the socket buffer
369+*
370+* @param skb socket buffer
371+*/
372+static __inline void skb_free(struct sk_buff *skb)
373+{
374+ free(skb);
375+ return;
376+}
377+
378+/**
379+* Increase the date length in sk_buffer by len,
380+* and return the increased header pointer
381+*
382+* @param skb socket buffer
383+* @param len length want to increase
384+* @return the pointer to increased header
385+*/
386+static RT_U8 *skb_put(struct sk_buff* skb, RT_U32 len)
387+{
388+ RT_U32 old_len = skb->data_len;
389+ if((skb->data_len + len) > (skb->max_len)) {
390+ RS_ERR("Buffer too small");
391+ return NULL;
392+ }
393+ skb->data_len += len;
394+ return (skb->data + old_len);
395+}
396+
397+/**
398+* decrease data length in sk_buffer by to len by cut the tail
399+*
400+* @warning len should be less than skb->len
401+*
402+* @param skb socket buffer
403+* @param len length want to be changed
404+*/
405+static void skb_trim(struct sk_buff *skb, unsigned int len)
406+{
407+ if (skb->data_len > len) {
408+ skb->data_len = len;
409+ } else {
410+ RS_ERR("Error: skb->data_len(%d) < len(%d)", skb->data_len, len);
411+ }
412+}
413+
414+/**
415+* Decrease the data length in sk_buffer by len,
416+* and move the content forward to the header.
417+* the data in header will be removed.
418+*
419+* @param skb socket buffer
420+* @param len length of data
421+* @return new data
422+*/
423+static RT_U8 * skb_pull(struct sk_buff * skb, RT_U32 len)
424+{
425+ skb->data_len -= len;
426+ unsigned char *buf;
427+ if (!(buf = malloc(skb->data_len))) {
428+ RS_ERR("Unable to allocate file buffer");
429+ exit(1);
430+ }
431+ memcpy(buf, skb->data+len, skb->data_len);
432+ memcpy(skb->data, buf, skb->data_len);
433+ free(buf);
434+ return (skb->data);
435+}
436+/**
437+* Add "d" into crc scope, caculate the new crc value
438+*
439+* @param crc crc data
440+* @param d one byte data
441+*/
442+static void h5_crc_update(RT_U16 *crc, RT_U8 d)
443+{
444+ RT_U16 reg = *crc;
445+
446+ reg = (reg >> 4) ^ crc_table[(reg ^ d) & 0x000f];
447+ reg = (reg >> 4) ^ crc_table[(reg ^ (d >> 4)) & 0x000f];
448+
449+ *crc = reg;
450+}
451+
452+struct __una_u16 { RT_U16 x; };
453+static __inline RT_U16 __get_unaligned_cpu16(const void *p)
454+{
455+ const struct __una_u16 *ptr = (const struct __una_u16 *)p;
456+ return ptr->x;
457+}
458+
459+
460+static __inline RT_U16 get_unaligned_be16(const void *p)
461+{
462+ return __get_unaligned_cpu16((const RT_U8 *)p);
463+}
464+
465+static __inline RT_U16 get_unaligned_le16(RT_U8 *p)
466+{
467+ return (RT_U16)(*p)+((RT_U16)(*(p+1))<<8);
468+}
469+
470+static __inline RT_U32 get_unaligned_le32(RT_U8 *p)
471+{
472+ return (RT_U32)(*p) + ((RT_U32)(*(p+1))<<8) + ((RT_U32)(*(p+2))<<16) + ((RT_U32)(*(p+3))<<24);
473+}
474+
475+/**
476+* Get crc data.
477+*
478+* @param h5 realtek h5 struct
479+* @return crc data
480+*/
481+static RT_U16 h5_get_crc(rtk_hw_cfg_t *h5)
482+{
483+ RT_U16 crc = 0;
484+ RT_U8 * data = h5->rx_skb->data + h5->rx_skb->data_len - 2;
485+ crc = data[1] + (data[0] << 8);
486+ return crc;
487+// return get_unaligned_be16(&h5->rx_skb->data[h5->rx_skb->data_len - 2]);
488+}
489+
490+/**
491+* Just add 0xc0 at the end of skb,
492+* we can also use this to add 0xc0 at start while there is no data in skb
493+*
494+* @param skb socket buffer
495+*/
496+static void h5_slip_msgdelim(struct sk_buff *skb)
497+{
498+ const char pkt_delim = 0xc0;
499+ memcpy(skb_put(skb, 1), &pkt_delim, 1);
500+}
501+
502+/**
503+* Slip ecode one byte in h5 proto, as follows:
504+* 0xc0 -> 0xdb, 0xdc
505+* 0xdb -> 0xdb, 0xdd
506+* 0x11 -> 0xdb, 0xde
507+* 0x13 -> 0xdb, 0xdf
508+* others will not change
509+*
510+* @param skb socket buffer
511+* @c pure data in the one byte
512+*/
513+static void h5_slip_one_byte(struct sk_buff *skb, RT_U8 c)
514+{
515+ const RT_S8 esc_c0[2] = { 0xdb, 0xdc };
516+ const RT_S8 esc_db[2] = { 0xdb, 0xdd };
517+ const RT_S8 esc_11[2] = { 0xdb, 0xde };
518+ const RT_S8 esc_13[2] = { 0xdb, 0xdf };
519+
520+ switch (c) {
521+ case 0xc0:
522+ memcpy(skb_put(skb, 2), &esc_c0, 2);
523+ break;
524+
525+ case 0xdb:
526+ memcpy(skb_put(skb, 2), &esc_db, 2);
527+ break;
528+
529+ case 0x11:
530+ memcpy(skb_put(skb, 2), &esc_11, 2);
531+ break;
532+
533+ case 0x13:
534+ memcpy(skb_put(skb, 2), &esc_13, 2);
535+ break;
536+
537+ default:
538+ memcpy(skb_put(skb, 1), &c, 1);
539+ break;
540+ }
541+}
542+
543+/**
544+* Decode one byte in h5 proto, as follows:
545+* 0xdb, 0xdc -> 0xc0
546+* 0xdb, 0xdd -> 0xdb
547+* 0xdb, 0xde -> 0x11
548+* 0xdb, 0xdf -> 0x13
549+* others will not change
550+*
551+* @param h5 realtek h5 struct
552+* @byte pure data in the one byte
553+*/
554+static void h5_unslip_one_byte(rtk_hw_cfg_t *h5, unsigned char byte)
555+{
556+ const RT_U8 c0 = 0xc0, db = 0xdb;
557+ const RT_U8 oof1 = 0x11, oof2 = 0x13;
558+
559+ if (H5_ESCSTATE_NOESC == h5->rx_esc_state) {
560+ if (0xdb == byte) {
561+ h5->rx_esc_state = H5_ESCSTATE_ESC;
562+ } else {
563+ memcpy(skb_put(h5->rx_skb, 1), &byte, 1);
564+ //Check Pkt Header's CRC enable bit
565+ if ((h5->rx_skb->data[0] & 0x40) != 0 && h5->rx_state != H5_W4_CRC) {
566+ h5_crc_update(&h5->message_crc, byte);
567+ }
568+ h5->rx_count--;
569+ }
570+ } else if (H5_ESCSTATE_ESC == h5->rx_esc_state) {
571+ switch (byte) {
572+ case 0xdc:
573+ memcpy(skb_put(h5->rx_skb, 1), &c0, 1);
574+ if ((h5->rx_skb->data[0] & 0x40) != 0 && h5->rx_state != H5_W4_CRC)
575+ h5_crc_update(&h5->message_crc, 0xc0);
576+ h5->rx_esc_state = H5_ESCSTATE_NOESC;
577+ h5->rx_count--;
578+ break;
579+
580+ case 0xdd:
581+ memcpy(skb_put(h5->rx_skb, 1), &db, 1);
582+ if ((h5->rx_skb->data[0] & 0x40) != 0 && h5->rx_state != H5_W4_CRC)
583+ h5_crc_update(&h5->message_crc, 0xdb);
584+ h5->rx_esc_state = H5_ESCSTATE_NOESC;
585+ h5->rx_count--;
586+ break;
587+
588+ case 0xde:
589+ memcpy(skb_put(h5->rx_skb, 1), &oof1, 1);
590+ if ((h5->rx_skb->data[0] & 0x40) != 0 && h5->rx_state != H5_W4_CRC)
591+ h5_crc_update(&h5->message_crc, oof1);
592+ h5->rx_esc_state = H5_ESCSTATE_NOESC;
593+ h5->rx_count--;
594+ break;
595+
596+ case 0xdf:
597+ memcpy(skb_put(h5->rx_skb, 1), &oof2, 1);
598+ if ((h5->rx_skb->data[0] & 0x40) != 0 && h5->rx_state != H5_W4_CRC)
599+ h5_crc_update(&h5->message_crc, oof2);
600+ h5->rx_esc_state = H5_ESCSTATE_NOESC;
601+ h5->rx_count--;
602+ break;
603+
604+ default:
605+ RS_ERR("Error: Invalid byte %02x after esc byte", byte);
606+ skb_free(h5->rx_skb);
607+ h5->rx_skb = NULL;
608+ h5->rx_state = H5_W4_PKT_DELIMITER;
609+ h5->rx_count = 0;
610+ break;
611+ }
612+ }
613+}
614+
615+/**
616+* Prepare h5 packet, packet format as follow:
617+* | LSB 4 octets | 0 ~4095| 2 MSB
618+* |packet header | payload | data integrity check |
619+*
620+* pakcket header fromat is show below:
621+* | LSB 3 bits | 3 bits | 1 bits | 1 bits |
622+* | 4 bits | 12 bits | 8 bits MSB
623+* |sequence number | acknowledgement number | data integrity check present | reliable packet |
624+* |packet type | payload length | header checksum
625+*
626+* @param h5 realtek h5 struct
627+* @param data pure data
628+* @param len the length of data
629+* @param pkt_type packet type
630+* @return socket buff after prepare in h5 proto
631+*/
632+static struct sk_buff * h5_prepare_pkt(rtk_hw_cfg_t *h5, RT_U8 *data, RT_S32 len, RT_S32 pkt_type)
633+{
634+ struct sk_buff *nskb;
635+ RT_U8 hdr[4];
636+ RT_U16 H5_CRC_INIT(h5_txmsg_crc);
637+ int rel, i;
638+
639+ switch (pkt_type) {
640+ case HCI_ACLDATA_PKT:
641+ case HCI_COMMAND_PKT:
642+ case HCI_EVENT_PKT:
643+ rel = 1; // reliable
644+ break;
645+
646+ case H5_ACK_PKT:
647+ case H5_VDRSPEC_PKT:
648+ case H5_LINK_CTL_PKT:
649+ rel = 0; // unreliable
650+ break;
651+
652+ default:
653+ RS_ERR("Unknown packet type");
654+ return NULL;
655+ }
656+
657+ // Max len of packet: (original len +4(h5 hdr) +2(crc))*2
658+ // (because bytes 0xc0 and 0xdb are escaped, worst case is
659+ // when the packet is all made of 0xc0 and 0xdb :) )
660+ // + 2 (0xc0 delimiters at start and end).
661+
662+ nskb = skb_alloc((len + 6) * 2 + 2);
663+ if (!nskb)
664+ return NULL;
665+
666+ //Add SLIP start byte: 0xc0
667+ h5_slip_msgdelim(nskb);
668+ // set AckNumber in SlipHeader
669+ hdr[0] = h5->rxseq_txack << 3;
670+ h5->is_txack_req = 0;
671+
672+ //RS_DBG("We request packet no(%u) to card", h5->rxseq_txack);
673+ //RS_DBG("Sending packet with seqno %u and wait %u", h5->msgq_txseq, h5->rxseq_txack);
674+ if (rel) {
675+ // set reliable pkt bit and SeqNumber
676+ hdr[0] |= 0x80 + h5->msgq_txseq;
677+ //RS_DBG("Sending packet with seqno(%u)", h5->msgq_txseq);
678+ ++(h5->msgq_txseq);
679+ h5->msgq_txseq = (h5->msgq_txseq) & 0x07;
680+ }
681+
682+ // set DicPresent bit
683+ if (h5->use_crc)
684+ hdr[0] |= 0x40;
685+
686+ // set packet type and payload length
687+ hdr[1] = ((len << 4) & 0xff) | pkt_type;
688+ hdr[2] = (RT_U8)(len >> 4);
689+ // set checksum
690+ hdr[3] = ~(hdr[0] + hdr[1] + hdr[2]);
691+
692+ // Put h5 header */
693+ for (i = 0; i < 4; i++) {
694+ h5_slip_one_byte(nskb, hdr[i]);
695+
696+ if (h5->use_crc)
697+ h5_crc_update(&h5_txmsg_crc, hdr[i]);
698+ }
699+
700+ // Put payload */
701+ for (i = 0; i < len; i++) {
702+ h5_slip_one_byte(nskb, data[i]);
703+
704+ if (h5->use_crc)
705+ h5_crc_update(&h5_txmsg_crc, data[i]);
706+ }
707+
708+ // Put CRC */
709+ if (h5->use_crc) {
710+ h5_txmsg_crc = bit_rev16(h5_txmsg_crc);
711+ h5_slip_one_byte(nskb, (RT_U8) ((h5_txmsg_crc >> 8) & 0x00ff));
712+ h5_slip_one_byte(nskb, (RT_U8) (h5_txmsg_crc & 0x00ff));
713+ }
714+
715+ // Add SLIP end byte: 0xc0
716+ h5_slip_msgdelim(nskb);
717+ return nskb;
718+}
719+/**
720+* Removed controller acked packet from Host's unacked lists
721+*
722+* @param h5 realtek h5 struct
723+*/
724+static void h5_remove_acked_pkt(rtk_hw_cfg_t *h5)
725+{
726+ int pkts_to_be_removed = 0;
727+ int seqno = 0;
728+ int i = 0;
729+
730+ seqno = h5->msgq_txseq;
731+ //pkts_to_be_removed = GetListLength(h5->unacked);
732+
733+ while (pkts_to_be_removed) {
734+ if (h5->rxack == seqno)
735+ break;
736+
737+ pkts_to_be_removed--;
738+ seqno = (seqno - 1) & 0x07;
739+ }
740+
741+ if (h5->rxack != seqno) {
742+ RS_DBG("Peer acked invalid packet");
743+ }
744+
745+ //skb_queue_walk_safe(&h5->unack, skb, tmp) // remove ack'ed packet from h5->unack queue
746+ for (i = 0; i < 5; ++i) {
747+ if (i >= pkts_to_be_removed)
748+ break;
749+ i++;
750+ //__skb_unlink(skb, &h5->unack);
751+ //skb_free(skb);
752+ }
753+
754+ // if (skb_queue_empty(&h5->unack))
755+ // del_timer(&h5->th5);
756+ // spin_unlock_irqrestore(&h5->unack.lock, flags);
757+
758+ if (i != pkts_to_be_removed)
759+ RS_DBG("Removed only (%u) out of (%u) pkts", i, pkts_to_be_removed);
760+}
761+/**
762+* Realtek send pure ack, send a packet only with an ack
763+*
764+* @param fd uart file descriptor
765+*
766+*/
767+static void rtk_send_pure_ack_down(int fd)
768+{
769+ struct sk_buff *nskb = h5_prepare_pkt(&rtk_hw_cfg, NULL, 0, H5_ACK_PKT);
770+ write(fd, nskb->data, nskb->data_len);
771+ skb_free(nskb);
772+ return;
773+}
774+
775+/**
776+* Parse hci event command complete, pull the cmd complete event header
777+*
778+* @param skb socket buffer
779+*
780+*/
781+static void hci_event_cmd_complete(struct sk_buff* skb)
782+{
783+ struct hci_event_hdr *hdr = (struct hci_event_hdr *) skb->data;
784+ struct hci_ev_cmd_complete* ev = NULL;
785+ RT_U16 opcode = 0;
786+ RT_U8 status = 0;
787+
788+ //pull hdr
789+ skb_pull(skb, HCI_EVENT_HDR_SIZE);
790+ ev = (struct hci_ev_cmd_complete*)skb->data;
791+ opcode = le16_to_cpu(ev->opcode);
792+
793+ RS_DBG("receive hci command complete event with command:%x\n", opcode);
794+
795+ //pull command complete event header
796+ skb_pull(skb, sizeof(struct hci_ev_cmd_complete));
797+
798+ switch (opcode) {
799+ case HCI_VENDOR_CHANGE_BDRATE:
800+ status = skb->data[0];
801+ RS_DBG("Change BD Rate with status:%x", status);
802+ skb_free(rtk_hw_cfg.host_last_cmd);
803+ rtk_hw_cfg.host_last_cmd = NULL;
804+ rtk_hw_cfg.link_estab_state = H5_PATCH;
805+ break;
806+
807+ case HCI_CMD_READ_BD_ADDR:
808+ status = skb->data[0];
809+ RS_DBG("Read BD Address with Status:%x", status);
810+ if (!status) {
811+ RS_DBG("BD Address: %8x%8x", *(int*)&skb->data[1], *(int*)&skb->data[5]);
812+ }
813+ break;
814+
815+ case HCI_VENDOR_READ_LMP_VERISION:
816+ rtk_hw_cfg.hci_version_cmd_state = event_received;
817+ status = skb->data[0];
818+ RS_DBG("Read RTK LMP version with Status:%x", status);
819+ if (0 == status)
820+ rtk_hw_cfg.lmp_version = skb->data[7] | (skb->data[8] << 8);
821+ else {
822+ RS_ERR("READ_RTK_ROM_VERISION return status error!");
823+ //Need to do more
824+ }
825+ skb_free(rtk_hw_cfg.host_last_cmd);
826+ rtk_hw_cfg.host_last_cmd = NULL;
827+ break;
828+
829+ case HCI_VENDOR_READ_RTK_ROM_VERISION:
830+ rtk_hw_cfg.rom_version_cmd_state = event_received;
831+ status = skb->data[0];
832+ RS_DBG("Read RTK rom version with Status:%x", status);
833+ if (0 == status)
834+ rtk_hw_cfg.eversion = skb->data[1];
835+ else if (1 == status)
836+ rtk_hw_cfg.eversion = 0;
837+ else {
838+ RS_ERR("READ_RTK_ROM_VERISION return status error!");
839+ //Need to do more
840+ }
841+
842+ skb_free(rtk_hw_cfg.host_last_cmd);
843+ rtk_hw_cfg.host_last_cmd = NULL;
844+ break;
845+
846+ default:
847+ break;
848+ }
849+}
850+
851+/**
852+* Check if it's a hci frame, if it is, complete it with response or parse the cmd complete event
853+*
854+* @param skb socket buffer
855+*
856+*/
857+static void hci_recv_frame(struct sk_buff *skb)
858+{
859+ int len;
860+ unsigned char h5sync[2] = {0x01, 0x7E},
861+ h5syncresp[2] = {0x02, 0x7D},
862+ h5_sync_resp_pkt[0x8] = {0xc0, 0x00, 0x2F, 0x00, 0xD0, 0x02, 0x7D, 0xc0},
863+ h5_conf_resp_pkt_to_Ctrl[0x8] = {0xc0, 0x00, 0x2F, 0x00, 0xD0, 0x04, 0x7B, 0xc0},
864+ h5conf[3] = {0x03, 0xFC, 0x10},
865+ h5confresp[3] = {0x04, 0x7B, 0x10},
866+ cmd_complete_evt_code = 0xe;
867+
868+ if(rtk_hw_cfg.link_estab_state == H5_SYNC) {
869+ if (!memcmp(skb->data, h5sync, 2)) {
870+ RS_DBG("Get SYNC Pkt\n");
871+ len = write(rtk_hw_cfg.serial_fd, &h5_sync_resp_pkt,0x8);
872+ } else if (!memcmp(skb->data, h5syncresp, 2)) {
873+ RS_DBG("Get SYNC Resp Pkt\n");
874+ rtk_hw_cfg.link_estab_state = H5_CONFIG;
875+ }
876+ skb_free(skb);
877+ } else if(rtk_hw_cfg.link_estab_state == H5_CONFIG) {
878+ if (!memcmp(skb->data, h5sync, 0x2)) {
879+ len = write(rtk_hw_cfg.serial_fd, &h5_sync_resp_pkt, 0x8);
880+ RS_DBG("Get SYNC pkt-active mode\n");
881+ } else if (!memcmp(skb->data, h5conf, 0x2)) {
882+ len = write(rtk_hw_cfg.serial_fd, &h5_conf_resp_pkt_to_Ctrl, 0x8);
883+ RS_DBG("Get CONFG pkt-active mode\n");
884+ } else if (!memcmp(skb->data, h5confresp, 0x2)) {
885+ RS_DBG("Get CONFG resp pkt-active mode\n");
886+ rtk_hw_cfg.link_estab_state = H5_INIT;
887+ } else {
888+ RS_DBG("H5_CONFIG receive event\n");
889+ rtk_send_pure_ack_down(rtk_hw_cfg.serial_fd);
890+ }
891+ skb_free(skb);
892+ } else if (rtk_hw_cfg.link_estab_state == H5_INIT) {
893+ if (skb->data[0] == cmd_complete_evt_code) {
894+ hci_event_cmd_complete(skb);
895+ }
896+
897+ rtk_send_pure_ack_down(rtk_hw_cfg.serial_fd);
898+ usleep(10000);
899+ rtk_send_pure_ack_down(rtk_hw_cfg.serial_fd);
900+ usleep(10000);
901+ rtk_send_pure_ack_down(rtk_hw_cfg.serial_fd);
902+ skb_free(skb);
903+ } else if(rtk_hw_cfg.link_estab_state == H5_PATCH) {
904+ rtk_hw_cfg.rx_index = skb->data[6];
905+ if (rtk_hw_cfg.rx_index & 0x80)
906+ rtk_hw_cfg.rx_index &= ~0x80;
907+
908+ RS_DBG("rtk_hw_cfg.rx_index %d\n", rtk_hw_cfg.rx_index );
909+ if (rtk_hw_cfg.rx_index == rtk_hw_cfg.total_num)
910+ rtk_hw_cfg.link_estab_state = H5_ACTIVE;
911+ skb_free(skb);
912+ } else {
913+ RS_ERR("receive packets in active state");
914+ skb_free(skb);
915+ }
916+}
917+
918+/**
919+* after rx data is parsed, and we got a rx frame saved in h5->rx_skb,
920+* this routinue is called.
921+* things todo in this function:
922+* 1. check if it's a hci frame, if it is, complete it with response or ack
923+* 2. see the ack number, free acked frame in queue
924+* 3. reset h5->rx_state, set rx_skb to null.
925+*
926+* @param h5 realtek h5 struct
927+*
928+*/
929+static void h5_complete_rx_pkt(rtk_hw_cfg_t *h5)
930+{
931+ int pass_up = 1;
932+ uint8_t* h5_hdr = NULL;
933+
934+ h5_hdr = (uint8_t *)(h5->rx_skb->data);
935+ if (H5_HDR_RELIABLE(h5_hdr)) {
936+ RS_DBG("Received reliable seqno %u from card", h5->rxseq_txack);
937+ h5->rxseq_txack = H5_HDR_SEQ(h5_hdr) + 1;
938+ h5->rxseq_txack %= 8;
939+ h5->is_txack_req = 1;
940+ }
941+
942+ h5->rxack = H5_HDR_ACK(h5_hdr);
943+
944+ switch (H5_HDR_PKT_TYPE(h5_hdr)) {
945+ case HCI_ACLDATA_PKT:
946+ case HCI_EVENT_PKT:
947+ case HCI_SCODATA_PKT:
948+ case HCI_COMMAND_PKT:
949+ case H5_LINK_CTL_PKT:
950+ pass_up = 1;
951+ break;
952+
953+ default:
954+ pass_up = 0;
955+ break;
956+ }
957+
958+ h5_remove_acked_pkt(h5);
959+
960+ if (pass_up) {
961+ skb_pull(h5->rx_skb, H5_HDR_SIZE);
962+ hci_recv_frame(h5->rx_skb);
963+ } else {
964+ skb_free(h5->rx_skb);
965+ }
966+
967+ h5->rx_state = H5_W4_PKT_DELIMITER;
968+ h5->rx_skb = NULL;
969+}
970+
971+/**
972+* Parse the receive data in h5 proto.
973+*
974+* @param h5 realtek h5 struct
975+* @param data point to data received before parse
976+* @param count num of data
977+* @return reserved count
978+*/
979+static int h5_recv(rtk_hw_cfg_t *h5, void *data, int count)
980+{
981+ unsigned char *ptr;
982+ //RS_DBG("count %d rx_state %d rx_count %ld", count, h5->rx_state, h5->rx_count);
983+ ptr = (unsigned char *)data;
984+
985+ while (count) {
986+ if (h5->rx_count) {
987+ if (*ptr == 0xc0) {
988+ RS_ERR("short h5 packet");
989+ skb_free(h5->rx_skb);
990+ h5->rx_state = H5_W4_PKT_START;
991+ h5->rx_count = 0;
992+ } else
993+ h5_unslip_one_byte(h5, *ptr);
994+
995+ ptr++; count--;
996+ continue;
997+ }
998+
999+ switch (h5->rx_state) {
1000+ case H5_W4_HDR:
1001+ /* check header checksum. see Core Spec V4 "3-wire uart" page 67 */
1002+ if ((0xff & (RT_U8) ~ (h5->rx_skb->data[0] + h5->rx_skb->data[1] +
1003+ h5->rx_skb->data[2])) != h5->rx_skb->data[3]) {
1004+ RS_ERR("h5 hdr checksum error!!!");
1005+ skb_free(h5->rx_skb);
1006+ h5->rx_state = H5_W4_PKT_DELIMITER;
1007+ h5->rx_count = 0;
1008+ continue;
1009+ }
1010+
1011+ /* reliable pkt & h5->hdr->SeqNumber != h5->Rxseq_txack */
1012+ if (h5->rx_skb->data[0] & 0x80
1013+ && (h5->rx_skb->data[0] & 0x07) != h5->rxseq_txack) {
1014+ RS_ERR("Out-of-order packet arrived, got(%u)expected(%u)",
1015+ h5->rx_skb->data[0] & 0x07, h5->rxseq_txack);
1016+ h5->is_txack_req = 1;
1017+
1018+ skb_free(h5->rx_skb);
1019+ h5->rx_state = H5_W4_PKT_DELIMITER;
1020+ h5->rx_count = 0;
1021+
1022+ /* depend on weather remote will reset ack numb or not!!!!!!special */
1023+ if (rtk_hw_cfg.tx_index == rtk_hw_cfg.total_num) {
1024+ rtk_hw_cfg.rxseq_txack = h5->rx_skb->data[0] & 0x07;
1025+ }
1026+ continue;
1027+ }
1028+ h5->rx_state = H5_W4_DATA;
1029+ h5->rx_count = (h5->rx_skb->data[1] >> 4) + (h5->rx_skb->data[2] << 4);
1030+ continue;
1031+
1032+ case H5_W4_DATA:
1033+ /* pkt with crc */
1034+ if (h5->rx_skb->data[0] & 0x40){
1035+ h5->rx_state = H5_W4_CRC;
1036+ h5->rx_count = 2;
1037+ } else {
1038+ h5_complete_rx_pkt(h5);
1039+ //RS_DBG(DF_SLIP,("--------> H5_W4_DATA ACK\n"));
1040+ }
1041+ continue;
1042+
1043+ case H5_W4_CRC:
1044+ if (bit_rev16(h5->message_crc) != h5_get_crc(h5)) {
1045+ RS_ERR("Checksum failed, computed(%04x)received(%04x)",
1046+ bit_rev16(h5->message_crc), h5_get_crc(h5));
1047+ skb_free(h5->rx_skb);
1048+ h5->rx_state = H5_W4_PKT_DELIMITER;
1049+ h5->rx_count = 0;
1050+ continue;
1051+ }
1052+ skb_trim(h5->rx_skb, h5->rx_skb->data_len - 2);
1053+ h5_complete_rx_pkt(h5);
1054+ continue;
1055+
1056+ case H5_W4_PKT_DELIMITER:
1057+ switch (*ptr) {
1058+ case 0xc0:
1059+ h5->rx_state = H5_W4_PKT_START;
1060+ break;
1061+
1062+ default:
1063+ break;
1064+ }
1065+ ptr++; count--;
1066+ break;
1067+
1068+ case H5_W4_PKT_START:
1069+ switch (*ptr) {
1070+ case 0xc0:
1071+ ptr++; count--;
1072+ break;
1073+
1074+ default:
1075+ h5->rx_state = H5_W4_HDR;
1076+ h5->rx_count = 4;
1077+ h5->rx_esc_state = H5_ESCSTATE_NOESC;
1078+ H5_CRC_INIT(h5->message_crc);
1079+
1080+ // Do not increment ptr or decrement count
1081+ // Allocate packet. Max len of a H5 pkt=
1082+ // 0xFFF (payload) +4 (header) +2 (crc)
1083+ h5->rx_skb = skb_alloc(0x1005);
1084+ if (!h5->rx_skb)
1085+ {
1086+ h5->rx_state = H5_W4_PKT_DELIMITER;
1087+ h5->rx_count = 0;
1088+ return 0;
1089+ }
1090+ break;
1091+ }
1092+ break;
1093+
1094+ default:
1095+ break;
1096+ }
1097+ }
1098+ return count;
1099+}
1100+
1101+/**
1102+* Read data to buf from uart.
1103+*
1104+* @param fd uart file descriptor
1105+* @param buf point to the addr where read data stored
1106+* @param count num of data want to read
1107+* @return num of data successfully read
1108+*/
1109+static int read_check_rtk(int fd, void *buf, int count)
1110+{
1111+ int res;
1112+ do {
1113+ res = read(fd, buf, count);
1114+ if (res != -1) {
1115+ buf = (RT_U8*)buf + res;
1116+ count -= res;
1117+ return res;
1118+ }
1119+ } while (count && (errno == 0 || errno == EINTR));
1120+ return res;
1121+}
1122+
1123+/**
1124+* Retry to sync when timeout in h5 proto, max retry times is 10.
1125+*
1126+* @warning Each time to retry, the time for timeout will be set as 1s.
1127+*
1128+* @param sig signaction for timeout
1129+*
1130+*/
1131+static void h5_tsync_sig_alarm(int sig)
1132+{
1133+ unsigned char h5sync[2] = {0x01, 0x7E};
1134+ static int retries = 0;
1135+ struct itimerval value;
1136+
1137+ if (retries < rtk_hw_cfg.h5_max_retries) {
1138+ retries++;
1139+ struct sk_buff *nskb = h5_prepare_pkt(&rtk_hw_cfg, h5sync, sizeof(h5sync), H5_LINK_CTL_PKT);
1140+ int len = write(rtk_hw_cfg.serial_fd, nskb->data, nskb->data_len);
1141+ RS_DBG("3-wire sync pattern resend : %d, len: %d\n", retries, len);
1142+
1143+ skb_free(nskb);
1144+ //gordon add 2013-6-7 retry per 250ms
1145+ value.it_value.tv_sec = 0;
1146+ value.it_value.tv_usec = 250000;
1147+ value.it_interval.tv_sec = 0;
1148+ value.it_interval.tv_usec = 250000;
1149+ setitimer(ITIMER_REAL, &value, NULL);
1150+ //gordon end
1151+
1152+ return;
1153+ }
1154+
1155+ tcflush(rtk_hw_cfg.serial_fd, TCIOFLUSH);
1156+ RS_ERR("H5 sync timed out\n");
1157+ exit(1);
1158+}
1159+
1160+/**
1161+* Retry to config when timeout in h5 proto, max retry times is 10.
1162+*
1163+* @warning Each time to retry, the time for timeout will be set as 1s.
1164+*
1165+* @param sig signaction for timeout
1166+*
1167+*/
1168+static void h5_tconf_sig_alarm(int sig)
1169+{
1170+ unsigned char h5conf[3] = {0x03, 0xFC, 0x14};
1171+ static int retries = 0;
1172+ struct itimerval value;
1173+
1174+ if (retries < rtk_hw_cfg.h5_max_retries) {
1175+ retries++;
1176+ struct sk_buff *nskb = h5_prepare_pkt(&rtk_hw_cfg, h5conf, 3, H5_LINK_CTL_PKT);
1177+ int len = write(rtk_hw_cfg.serial_fd, nskb->data, nskb->data_len);
1178+ RS_DBG("3-wire config pattern resend : %d , len: %d", retries, len);
1179+ skb_free(nskb);
1180+
1181+ //gordon add 2013-6-7 retry per 250ms
1182+ value.it_value.tv_sec = 0;
1183+ value.it_value.tv_usec = 250000;
1184+ value.it_interval.tv_sec = 0;
1185+ value.it_interval.tv_usec = 250000;
1186+ setitimer(ITIMER_REAL, &value, NULL);
1187+
1188+ return;
1189+ }
1190+
1191+ tcflush(rtk_hw_cfg.serial_fd, TCIOFLUSH);
1192+ RS_ERR("H5 config timed out\n");
1193+ exit(1);
1194+}
1195+
1196+/**
1197+* Retry to init when timeout in h5 proto, max retry times is 10.
1198+*
1199+* @warning Each time to retry, the time for timeout will be set as 1s.
1200+*
1201+* @param sig signaction for timeout
1202+*
1203+*/
1204+static void h5_tinit_sig_alarm(int sig)
1205+{
1206+ static int retries = 0;
1207+ if (retries < rtk_hw_cfg.h5_max_retries) {
1208+ retries++;
1209+ if (rtk_hw_cfg.host_last_cmd) {
1210+ int len = write(rtk_hw_cfg.serial_fd, rtk_hw_cfg.host_last_cmd->data, rtk_hw_cfg.host_last_cmd->data_len);
1211+ RS_DBG("3-wire change baudrate re send:%d, len:%d", retries, len);
1212+ alarm(1);
1213+ return;
1214+ } else {
1215+ RS_DBG("3-wire init timeout without last command stored\n");
1216+ }
1217+ }
1218+
1219+ tcflush(rtk_hw_cfg.serial_fd, TCIOFLUSH);
1220+ RS_ERR("H5 init process timed out");
1221+ exit(1);
1222+}
1223+
1224+/**
1225+* Retry to download patch when timeout in h5 proto, max retry times is 10.
1226+*
1227+* @warning Each time to retry, the time for timeout will be set as 3s.
1228+*
1229+* @param sig signaction for timeout
1230+*
1231+*/
1232+static void h5_tpatch_sig_alarm(int sig)
1233+{
1234+ static int retries = 0;
1235+ if (retries < rtk_hw_cfg.h5_max_retries) {
1236+ RS_ERR("patch timerout, retry:\n");
1237+ if (rtk_hw_cfg.host_last_cmd) {
1238+ int len = write(rtk_hw_cfg.serial_fd, rtk_hw_cfg.host_last_cmd->data, rtk_hw_cfg.host_last_cmd->data_len);
1239+ RS_DBG("3-wire download patch re send:%d", retries );
1240+ }
1241+ retries++;
1242+ alarm(3);
1243+ return;
1244+ }
1245+ RS_ERR("H5 patch timed out\n");
1246+ exit(1);
1247+}
1248+
1249+/**
1250+* Download patch using hci. For h5 proto, not recv reply for 2s will timeout.
1251+* Call h5_tpatch_sig_alarm for retry.
1252+*
1253+* @param dd uart file descriptor
1254+* @param index current index
1255+* @param data point to the config file
1256+* @param len current buf length
1257+* @return #0 on success
1258+*
1259+*/
1260+static int hci_download_patch(int dd, int index, uint8_t *data, int len,struct termios *ti)
1261+{
1262+ unsigned char hcipatch[256] = {0x20, 0xfc, 00};
1263+ unsigned char bytes[READ_DATA_SIZE];
1264+ int retlen;
1265+ struct sigaction sa;
1266+
1267+ sa.sa_handler = h5_tpatch_sig_alarm;
1268+ sigaction(SIGALRM, &sa, NULL);
1269+ alarm(2);
1270+
1271+ download_vendor_patch_cp cp;
1272+ memset(&cp, 0, sizeof(cp));
1273+ cp.index = index;
1274+ if (data != NULL) {
1275+ memcpy(cp.data, data, len);
1276+ }
1277+
1278+ int nValue = rtk_hw_cfg.total_num|0x80;
1279+ if (index == nValue) {
1280+ rtk_hw_cfg.tx_index = rtk_hw_cfg.total_num;
1281+ } else {
1282+ rtk_hw_cfg.tx_index = index;
1283+ }
1284+ hcipatch[2] = len+1;
1285+ memcpy(hcipatch+3, &cp, len+1);
1286+
1287+ struct sk_buff *nskb = h5_prepare_pkt(&rtk_hw_cfg, hcipatch, len+4, HCI_COMMAND_PKT); //data:len+head:4
1288+
1289+ if (rtk_hw_cfg.host_last_cmd) {
1290+ skb_free(rtk_hw_cfg.host_last_cmd);
1291+ rtk_hw_cfg.host_last_cmd = NULL;
1292+ }
1293+
1294+ rtk_hw_cfg.host_last_cmd = nskb;
1295+
1296+ len = write(dd, nskb->data, nskb->data_len);
1297+ RS_DBG("hci_download_patch tx_index:%d rx_index: %d\n", rtk_hw_cfg.tx_index, rtk_hw_cfg.rx_index);
1298+
1299+ while (rtk_hw_cfg.rx_index != rtk_hw_cfg.tx_index ) { //receive data and wait last pkt
1300+ if ((retlen = read_check_rtk(dd, &bytes, READ_DATA_SIZE)) == -1) {
1301+ perror("read fail");
1302+ return -1;
1303+ }
1304+ h5_recv(&rtk_hw_cfg, &bytes, retlen);
1305+ }
1306+
1307+ alarm(0);
1308+
1309+ return 0;
1310+}
1311+
1312+/**
1313+* Download h4 patch
1314+*
1315+* @param dd uart file descriptor
1316+* @param index current index
1317+* @param data point to the config file
1318+* @param len current buf length
1319+* @return ret_index
1320+*
1321+*/
1322+static int hci_download_patch_h4(int dd, int index, uint8_t *data, int len)
1323+{
1324+ unsigned char bytes[257] = {0};
1325+ unsigned char buf[257] = {0x01, 0x20, 0xfc, 00};
1326+ uint16_t readbytes = 0;
1327+ int cur_index = index;
1328+ int ret_Index = -1;
1329+ uint16_t res = 0;
1330+ int i = 0;
1331+ size_t total_len;
1332+ uint16_t w_len;
1333+ uint8_t rstatus;
1334+
1335+ RS_DBG("dd:%d, index:%d, len:%d", dd, index, len);
1336+ if (NULL != data) {
1337+ memcpy(&buf[5], data, len);
1338+ }
1339+
1340+ buf[3] = len + 1;
1341+ buf[4] = cur_index;
1342+ total_len = len + 5;
1343+
1344+ w_len = write(dd, buf, total_len);
1345+ RS_DBG("h4 write success with len: %d\n", w_len);
1346+
1347+ while(readbytes < 8) {
1348+ res = read(dd, bytes+i, 8);
1349+ if (res < 0)
1350+ break;
1351+ readbytes += res;
1352+ i = readbytes;
1353+ }
1354+
1355+ if((0x04 == bytes[0]) && (0x20 == bytes[4]) && (0xfc == bytes[5])) {
1356+ ret_Index = bytes[7];
1357+ rstatus = bytes[6];
1358+ RS_DBG("---->ret_Index:%d, ----->rstatus:%d\n", ret_Index, rstatus);
1359+ if(0x00 != rstatus) {
1360+ RS_ERR("---->read event status is wrong\n");
1361+ return -1;
1362+ }
1363+ } else {
1364+ RS_ERR("==========>Didn't read curret data\n");
1365+ return -1;
1366+ }
1367+
1368+ return ret_Index;
1369+}
1370+
1371+/**
1372+* Realtek change speed with h4 proto. Using vendor specified command packet to achieve this.
1373+*
1374+* @warning before write, need to wait 1s for device up
1375+*
1376+* @param fd uart file descriptor
1377+* @param baudrate the speed want to change
1378+* @return #0 on success
1379+*/
1380+static int rtk_vendor_change_speed_h4(int fd, RT_U32 baudrate)
1381+{
1382+ int res;
1383+ unsigned char bytes[257];
1384+ RT_U8 cmd[8] = {0};
1385+
1386+ cmd[0] = 1; //cmd;
1387+ cmd[1] = 0x17; //ocf
1388+ cmd[2] = 0xfc; //ogf
1389+ cmd[3] = 4; //length;
1390+
1391+ baudrate = cpu_to_le32(baudrate);
1392+#ifdef BAUDRATE_4BYTES
1393+ memcpy((RT_U16*)&cmd[4], &baudrate, 4);
1394+#else
1395+ memcpy((RT_U16*)&cmd[4], &baudrate, 2);
1396+ cmd[6] = 0;
1397+ cmd[7] = 0;
1398+#endif
1399+
1400+ //wait for a while for device to up, just h4 need it
1401+ sleep(1);
1402+ RS_DBG("baudrate in change speed command: 0x%x 0x%x 0x%x 0x%x \n", cmd[4], cmd[5], cmd[6], cmd[7]);
1403+
1404+ if( write(fd, cmd, 8) != 8)
1405+ {
1406+ RS_ERR("H4 change uart speed error when writing vendor command");
1407+ return -1;
1408+ }
1409+ RS_DBG("H4 Change uart Baudrate after write ");
1410+ res = read(fd, bytes, sizeof(bytes));
1411+
1412+ if((0x04 == bytes[0]) && (0x17 == bytes[4]) && (0xfc == bytes[5]))
1413+ {
1414+ RS_DBG("H4 change uart speed success, receving status:%x", bytes[6]);
1415+ if (bytes[6] == 0)
1416+ return 0;
1417+ }
1418+ return -1;
1419+}
1420+
1421+/**
1422+* Get firmware name, Generally is /system/etc/firmware/rtl8723as/rlt8723a_chip_b_cut_bt40_fw
1423+*
1424+*/
1425+static const char *get_firmware_name()
1426+{
1427+ static char firmware_file_name[PATH_MAX] = {0};
1428+ int ret = 0;
1429+ struct stat st;
1430+
1431+ ret = sprintf(firmware_file_name, FIRMWARE_DIRECTORY"rtlbt_fw");
1432+
1433+ return firmware_file_name;
1434+}
1435+
1436+/**
1437+* Parse realtek Bluetooth config file.
1438+* The config file if begin with vendor magic: RTK_VENDOR_CONFIG_MAGIC(8723ab55)
1439+* bt_addr is followed by 0x3c offset, it will be changed by bt_addr param
1440+* proto, baudrate and flow control is followed by 0xc offset,
1441+*
1442+* @param config_buf point to config file content
1443+* @param filelen length of config file
1444+* @param bt_addr where bt addr is stored
1445+* @return baudrate in config file
1446+*
1447+*/
1448+
1449+RT_U32 rtk_parse_config_file(RT_U8* config_buf, size_t filelen, char bt_addr[6])
1450+{
1451+ struct rtk_bt_vendor_config* config = (struct rtk_bt_vendor_config*) config_buf;
1452+ RT_U16 config_len = 0, temp = 0;
1453+ struct rtk_bt_vendor_config_entry* entry = NULL;
1454+ RT_U16 i;
1455+ RT_U32 baudrate = 0;
1456+
1457+ if(config == NULL)
1458+ return 0;
1459+
1460+ config_len = le16_to_cpu(config->data_len);
1461+ entry = config->entry;
1462+
1463+ if (le32_to_cpu(config->signature) != RTK_VENDOR_CONFIG_MAGIC) {
1464+ RS_ERR("config signature magic number(%x) is not set to RTK_VENDOR_CONFIG_MAGIC", (unsigned int)config->signature);
1465+ return 0;
1466+ }
1467+
1468+ if (config_len != filelen - sizeof(struct rtk_bt_vendor_config)) {
1469+ RS_ERR("config len(%d) is not right(%zd)", config_len, filelen-sizeof(struct rtk_bt_vendor_config));
1470+ return 0;
1471+ }
1472+
1473+ for (i=0; i<config_len;) {
1474+
1475+ switch(le16_to_cpu(entry->offset)) {
1476+#ifdef USE_CUSTUMER_ADDRESS
1477+ case 0x3c:
1478+ {
1479+ int j=0;
1480+ for (j=0; j<entry->entry_len; j++)
1481+ entry->entry_data[j] = bt_addr[entry->entry_len - 1 - j];
1482+ break;
1483+ }
1484+#endif
1485+ case 0xc:
1486+ {
1487+#ifdef BAUDRATE_4BYTES
1488+ baudrate = get_unaligned_le32(entry->entry_data);
1489+#else
1490+ baudrate = get_unaligned_le16(entry->entry_data);
1491+#endif
1492+
1493+ if (entry->entry_len >= 12) { //0ffset 0x18 - 0xc
1494+ rtk_hw_cfg.hw_flow_control = (entry->entry_data[12] & 0x4) ? 1:0; //0x18 byte bit2
1495+ }
1496+ RS_DBG("config baud rate to :%x, hwflowcontrol:%x, %x",
1497+ (unsigned int)baudrate, entry->entry_data[12], rtk_hw_cfg.hw_flow_control);
1498+ break;
1499+ }
1500+ default:
1501+ RS_DBG("config offset(%x),length(%x)", entry->offset, entry->entry_len);
1502+ break;
1503+ }
1504+ temp = entry->entry_len + sizeof(struct rtk_bt_vendor_config_entry);
1505+ i += temp;
1506+ entry = (struct rtk_bt_vendor_config_entry *)((RT_U8*)entry + temp);
1507+ }
1508+
1509+ return baudrate;
1510+}
1511+
1512+#ifdef USE_CUSTUMER_ADDRESS
1513+/**
1514+* get random realtek Bluetooth addr.
1515+*
1516+* @param bt_addr where bt addr is stored
1517+*
1518+*/
1519+static void rtk_get_ram_addr(char bt_addr[0])
1520+{
1521+ srand(time(NULL)+getpid()+getpid()*987654+rand());
1522+
1523+ RT_U32 addr = rand();
1524+ memcpy(bt_addr, &addr, sizeof(RT_U8));
1525+}
1526+
1527+/**
1528+* Write the random bt addr to the file /data/misc/bluetoothd/bt_mac/btmac.txt.
1529+*
1530+* @param bt_addr where bt addr is stored
1531+*
1532+*/
1533+static void rtk_write_btmac2file(char bt_addr[6])
1534+{
1535+ int fd;
1536+ mkdir(BT_ADDR_DIR, 0777);
1537+ fd = open(BT_ADDR_FILE, O_CREAT|O_RDWR|O_TRUNC);
1538+
1539+ if(fd > 0) {
1540+ chmod(BT_ADDR_FILE, 0666);
1541+ char addr[18]={0};
1542+ addr[17] = '\0';
1543+ sprintf(addr, "%2x:%2x:%2x:%2x:%2x:%2x", bt_addr[0], bt_addr[1], bt_addr[2], bt_addr[3], bt_addr[4], bt_addr[5]);
1544+ write(fd, addr, strlen(addr));
1545+ close(fd);
1546+ } else {
1547+ RS_ERR("open file error:%s\n", BT_ADDR_FILE);
1548+ }
1549+}
1550+#endif
1551+
1552+/**
1553+* Get realtek Bluetooth config file. The bt addr arg is stored in /data/btmac.txt, if there is not this file,
1554+* change to /data/misc/bluetoothd/bt_mac/btmac.txt. If both of them are not found, using
1555+* random bt addr.
1556+*
1557+* @param config_buf point to the content of realtek Bluetooth config file
1558+* @param config_baud_rate the baudrate set in the config file
1559+* @return file_len the length of config file
1560+*/
1561+int rtk_get_bt_config(unsigned char** config_buf, RT_U32* config_baud_rate)
1562+{
1563+ char bt_config_file_name[PATH_MAX] = {0};
1564+ RT_U8* bt_addr_temp = NULL;
1565+ char bt_addr[6]={0x00, 0xe0, 0x4c, 0x88, 0x88, 0x88};
1566+ struct stat st;
1567+ size_t filelen;
1568+ int fd;
1569+ FILE* file = NULL;
1570+ int ret = 0;
1571+ int i = 0;
1572+
1573+#ifdef USE_CUSTUMER_ADDRESS
1574+ sprintf(bt_config_file_name, BT_ADDR_FILE);
1575+ if (stat(bt_config_file_name, &st) < 0) {
1576+ RS_ERR("can't access bt bt_mac_addr file:%s, try use ramdom BT Addr\n", bt_config_file_name);
1577+
1578+ for(i = 0; i < 6; i++)
1579+ rtk_get_ram_addr(&bt_addr[i]);
1580+ rtk_write_btmac2file(bt_addr);
1581+ goto GET_CONFIG;
1582+ }
1583+
1584+
1585+ filelen = st.st_size;
1586+ if ((file= fopen(bt_config_file_name, "rb")) == NULL) {
1587+ RS_ERR("Can't open bt btaddr file, just use preset BT Addr");
1588+ } else {
1589+ int i = 0;
1590+ char temp;
1591+ fscanf(file, "%2x:%2x:%2x:%2x:%2x:%2x", (unsigned int *)&bt_addr[0], (unsigned int*)&bt_addr[1], (unsigned int*)&bt_addr[2], (unsigned int*)&bt_addr[3], (unsigned int*)&bt_addr[4], (unsigned int*)&bt_addr[5]);
1592+
1593+ /*reserve LAP addr from 0x9e8b00 to 0x9e8b3f, change to 0x008b***/
1594+ if(0x9e == bt_addr[3] && 0x8b == bt_addr[4] && (bt_addr[5] <= 0x3f)){
1595+ bt_addr[3] = 0x00;
1596+ }
1597+ RS_DBG("BT MAC IS : %X,%X,%X,%X,%X,%X\n", bt_addr[0], bt_addr[1], bt_addr[2], bt_addr[3], bt_addr[4], bt_addr[5]);
1598+
1599+ fclose(file);
1600+ }
1601+#endif
1602+
1603+GET_CONFIG:
1604+ ret = sprintf(bt_config_file_name, BT_CONFIG_DIRECTORY"rtlbt_config");
1605+ if (stat(bt_config_file_name, &st) < 0) {
1606+ RS_ERR("can't access bt config file:%s, errno:%d\n", bt_config_file_name, errno);
1607+ return -1;
1608+ }
1609+
1610+ filelen = st.st_size;
1611+
1612+ if ((fd = open(bt_config_file_name, O_RDONLY)) < 0) {
1613+ perror("Can't open bt config file");
1614+ return -1;
1615+ }
1616+
1617+ if ((*config_buf = malloc(filelen)) == NULL) {
1618+ RS_DBG("malloc buffer for config file fail(%zd)\n", filelen);
1619+ close(fd);
1620+ return -1;
1621+ }
1622+
1623+ //we may need to parse this config file.
1624+ //for easy debug, only get need data.
1625+
1626+ if (read(fd, *config_buf, filelen) < (ssize_t)filelen) {
1627+ perror("Can't load bt config file");
1628+ free(*config_buf);
1629+ close(fd);
1630+ return -1;
1631+ }
1632+
1633+ *config_baud_rate = rtk_parse_config_file(*config_buf, filelen, bt_addr);
1634+ RS_DBG("Get config baud rate from config file:%x",(unsigned int) *config_baud_rate);
1635+
1636+ close(fd);
1637+ return filelen;
1638+}
1639+
1640+/**
1641+* Realtek change speed with h5 proto. Using vendor specified command packet to achieve this.
1642+*
1643+* @warning it will waiting 2s for reply.
1644+*
1645+* @param fd uart file descriptor
1646+* @param baudrate the speed want to change
1647+*
1648+*/
1649+int rtk_vendor_change_speed_h5(int fd, RT_U32 baudrate)
1650+{
1651+ struct sk_buff* cmd_change_bdrate = NULL;
1652+ unsigned char cmd[7] = {0};
1653+ int retlen;
1654+ unsigned char bytes[READ_DATA_SIZE];
1655+ struct sigaction sa;
1656+
1657+ sa.sa_handler = h5_tinit_sig_alarm;
1658+ sigaction(SIGALRM, &sa, NULL);
1659+
1660+ cmd[0] = 0x17; //ocf
1661+ cmd[1] = 0xfc; //ogf, vendor specified
1662+
1663+ cmd[2] = 4; //length;
1664+
1665+ baudrate = cpu_to_le32(baudrate);
1666+#ifdef BAUDRATE_4BYTES
1667+ memcpy((RT_U16*)&cmd[3], &baudrate, 4);
1668+#else
1669+ memcpy((RT_U16*)&cmd[3], &baudrate, 2);
1670+
1671+ cmd[5] = 0;
1672+ cmd[6] = 0;
1673+#endif
1674+
1675+ RS_DBG("baudrate in change speed command: 0x%x 0x%x 0x%x 0x%x \n", cmd[3], cmd[4], cmd[5], cmd[6]);
1676+
1677+ cmd_change_bdrate = h5_prepare_pkt(&rtk_hw_cfg, cmd, 7, HCI_COMMAND_PKT);
1678+ if (!cmd_change_bdrate) {
1679+ RS_ERR("Prepare command packet for change speed fail");
1680+ return -1;
1681+ }
1682+
1683+ rtk_hw_cfg.host_last_cmd = cmd_change_bdrate;
1684+ alarm(1);
1685+ write(fd, cmd_change_bdrate->data, cmd_change_bdrate->data_len);
1686+
1687+ while (rtk_hw_cfg.link_estab_state == H5_INIT) {
1688+ if ((retlen = read_check_rtk(fd, &bytes, READ_DATA_SIZE)) == -1) {
1689+ perror("read fail");
1690+ return -1;
1691+ }
1692+ //add pure ack check
1693+ h5_recv(&rtk_hw_cfg, &bytes, retlen);
1694+ }
1695+
1696+ alarm(0);
1697+ return 0;
1698+}
1699+
1700+/**
1701+* Init realtek Bluetooth h5 proto. h5 proto is added by realtek in the right kernel.
1702+* Generally there are two steps: h5 sync and h5 config
1703+*
1704+* @param fd uart file descriptor
1705+* @param ti termios struct
1706+*
1707+*/
1708+int rtk_init_h5(int fd, struct termios *ti)
1709+{
1710+ unsigned char bytes[READ_DATA_SIZE];
1711+ struct sigaction sa;
1712+ int retlen;
1713+ struct itimerval value;
1714+
1715+ /* set even parity */
1716+ ti->c_cflag |= PARENB;
1717+ ti->c_cflag &= ~(PARODD);
1718+ if (tcsetattr(fd, TCSANOW, ti) < 0) {
1719+ RS_ERR("Can't set port settings");
1720+ return -1;
1721+ }
1722+
1723+ rtk_hw_cfg.h5_max_retries = H5_MAX_RETRY_COUNT;
1724+
1725+ alarm(0);
1726+ memset(&sa, 0, sizeof(sa));
1727+ sa.sa_flags = SA_NOCLDSTOP;
1728+ sa.sa_handler = h5_tsync_sig_alarm;
1729+ sigaction(SIGALRM, &sa, NULL);
1730+
1731+ /* h5 sync */
1732+ h5_tsync_sig_alarm(0);
1733+ rtk_hw_cfg.link_estab_state = H5_SYNC;
1734+ while (rtk_hw_cfg.link_estab_state == H5_SYNC) {
1735+ if ((retlen = read_check_rtk(fd, &bytes, READ_DATA_SIZE)) == -1) {
1736+ RS_ERR("H5 Read Sync Response Failed");
1737+
1738+ value.it_value.tv_sec = 0;
1739+ value.it_value.tv_usec = 0;
1740+ value.it_interval.tv_sec = 0;
1741+ value.it_interval.tv_usec = 0;
1742+ setitimer(ITIMER_REAL, &value, NULL);
1743+
1744+ return -1;
1745+ }
1746+ h5_recv(&rtk_hw_cfg, &bytes, retlen);
1747+ }
1748+
1749+ value.it_value.tv_sec = 0;
1750+ value.it_value.tv_usec = 0;
1751+ value.it_interval.tv_sec = 0;
1752+ value.it_interval.tv_usec = 0;
1753+ setitimer(ITIMER_REAL, &value, NULL);
1754+
1755+ /* h5 config */
1756+ sa.sa_handler = h5_tconf_sig_alarm;
1757+ sigaction(SIGALRM, &sa, NULL);
1758+ h5_tconf_sig_alarm(0);
1759+ while (rtk_hw_cfg.link_estab_state == H5_CONFIG) {
1760+ if ((retlen = read_check_rtk(fd, &bytes, READ_DATA_SIZE)) == -1) {
1761+ RS_ERR("H5 Read Config Response Failed");
1762+ value.it_value.tv_sec = 0;
1763+ value.it_value.tv_usec = 0;
1764+ value.it_interval.tv_sec = 0;
1765+ value.it_interval.tv_usec = 0;
1766+ setitimer(ITIMER_REAL, &value, NULL);
1767+ return -1;
1768+ }
1769+ h5_recv(&rtk_hw_cfg, &bytes, retlen);
1770+ }
1771+
1772+ value.it_value.tv_sec = 0;
1773+ value.it_value.tv_usec = 0;
1774+ value.it_interval.tv_sec = 0;
1775+ value.it_interval.tv_usec = 0;
1776+ setitimer(ITIMER_REAL, &value, NULL);
1777+
1778+ rtk_send_pure_ack_down(fd);
1779+ RS_DBG("H5 init finished\n");
1780+
1781+ rtk_hw_cfg.rom_version_cmd_state = cmd_not_send;
1782+ rtk_hw_cfg.hci_version_cmd_state = cmd_not_send;
1783+ return 0;
1784+}
1785+
1786+/**
1787+* Download realtek firmware and config file from uart with the proto.
1788+* Parse the content to serval packets follow the proto and then write the packets from uart
1789+*
1790+* @param fd uart file descriptor
1791+* @param buf addr where stor the content of firmware and config file
1792+* @param filesize length of buf
1793+* @param is_sent_changerate if baudrate need to be changed
1794+* @param proto realtek Bluetooth protocol, shall be either HCI_UART_H4 or HCI_UART_3WIRE
1795+*
1796+*/
1797+static int rtk_download_fw_config(int fd, RT_U8* buf, size_t filesize, int is_sent_changerate, int proto,struct termios *ti)
1798+{
1799+ uint8_t iCurIndex = 0;
1800+ uint8_t iCurLen = 0;
1801+ uint8_t iEndIndex = 0;
1802+ uint8_t iLastPacketLen = 0;
1803+ uint8_t iAdditionPkt = 0;
1804+ uint8_t iTotalIndex = 0;
1805+ uint8_t iCmdSentNum = 0;
1806+ unsigned char *bufpatch;
1807+
1808+ iEndIndex = (uint8_t)((filesize-1)/PATCH_DATA_FIELD_MAX_SIZE);
1809+ iLastPacketLen = (filesize)%PATCH_DATA_FIELD_MAX_SIZE;
1810+
1811+ if(is_sent_changerate)
1812+ iCmdSentNum++;
1813+ if(rtk_hw_cfg.rom_version_cmd_state >= cmd_has_sent)
1814+ iCmdSentNum++;
1815+ if(rtk_hw_cfg.hci_version_cmd_state >= cmd_has_sent)
1816+ iCmdSentNum++;
1817+
1818+ iAdditionPkt = (iEndIndex+1+iCmdSentNum)%8?(8-(iEndIndex+1+iCmdSentNum)%8):0;
1819+ iTotalIndex = iAdditionPkt + iEndIndex;
1820+ rtk_hw_cfg.total_num = iTotalIndex; //init TotalIndex
1821+
1822+ RS_DBG("iEndIndex:%d iLastPacketLen:%d iAdditionpkt:%d\n", iEndIndex, iLastPacketLen, iAdditionPkt);
1823+
1824+ if (iLastPacketLen == 0)
1825+ iLastPacketLen = PATCH_DATA_FIELD_MAX_SIZE;
1826+
1827+ bufpatch = buf;
1828+
1829+ int i;
1830+ for (i=0; i<=iTotalIndex; i++) {
1831+ if (iCurIndex < iEndIndex) {
1832+ iCurIndex = iCurIndex&0x7F;
1833+ iCurLen = PATCH_DATA_FIELD_MAX_SIZE;
1834+ } else if (iCurIndex == iEndIndex) { //send last data packet
1835+ if (iCurIndex == iTotalIndex)
1836+ iCurIndex = iCurIndex | 0x80;
1837+ else
1838+ iCurIndex = iCurIndex&0x7F;
1839+ iCurLen = iLastPacketLen;
1840+ } else if (iCurIndex < iTotalIndex) {
1841+ iCurIndex = iCurIndex&0x7F;
1842+ bufpatch = NULL;
1843+ iCurLen = 0;
1844+ } else { //send end packet
1845+ bufpatch = NULL;
1846+ iCurLen = 0;
1847+ iCurIndex = iCurIndex|0x80;
1848+ }
1849+
1850+ if (iCurIndex & 0x80)
1851+ RS_DBG("Send FW last command");
1852+
1853+ if (proto == HCI_UART_H4) {
1854+ iCurIndex = hci_download_patch_h4(fd, iCurIndex, bufpatch, iCurLen);
1855+ if ((iCurIndex != i) && (i != rtk_hw_cfg.total_num)) {
1856+ RS_DBG("index mismatch i:%d iCurIndex:%d, patch fail\n", i, iCurIndex);
1857+ return -1;
1858+ }
1859+ } else if (proto == HCI_UART_3WIRE) {
1860+ if (hci_download_patch(fd, iCurIndex, bufpatch, iCurLen, ti) < 0)
1861+ return -1;
1862+ }
1863+
1864+ if (iCurIndex < iEndIndex) {
1865+ bufpatch += PATCH_DATA_FIELD_MAX_SIZE;
1866+ }
1867+ iCurIndex ++;
1868+ }
1869+
1870+ //set last ack packet down
1871+ if (proto == HCI_UART_3WIRE) {
1872+ rtk_send_pure_ack_down(fd);
1873+ }
1874+
1875+ return 0;
1876+}
1877+
1878+/**
1879+* Get realtek Bluetooth firmaware file. The content will be saved in *fw_buf which is malloc here.
1880+* The length malloc here will be lager than length of firmware file if there is a config file.
1881+* The content of config file will copy to the tail of *fw_buf in rtk_config.
1882+*
1883+* @param fw_buf point to the addr where stored the content of firmware.
1884+* @param addi_len length of config file.
1885+* @return length of *fw_buf.
1886+*
1887+*/
1888+int rtk_get_bt_firmware(RT_U8** fw_buf)
1889+{
1890+ const char *filename;
1891+ struct stat st;
1892+ int fd = -1;
1893+ size_t fwsize;
1894+
1895+ filename = get_firmware_name();
1896+
1897+ if (stat(filename, &st) < 0) {
1898+ RS_ERR("Can't access firmware, errno:%d", errno);
1899+ return -1;
1900+ }
1901+
1902+ fwsize = st.st_size;
1903+
1904+ if ((fd = open(filename, O_RDONLY)) < 0) {
1905+ RS_ERR("Can't open firmware, errno:%d", errno);
1906+ return -1;
1907+ }
1908+
1909+ if (!(*fw_buf = malloc(fwsize))) {
1910+ RS_ERR("Can't alloc memory for fw&config, errno:%d", errno);
1911+ close(fd);
1912+ return -1;
1913+ }
1914+
1915+ if (read(fd, *fw_buf, fwsize) < (ssize_t) fwsize) {
1916+ free(*fw_buf);
1917+ *fw_buf = NULL;
1918+ close(fd);
1919+ return -1;
1920+ }
1921+ RS_DBG("Load FW OK");
1922+ close(fd);
1923+ return fwsize;
1924+}
1925+
1926+//These two function(rtk<-->uart speed transfer) need check Host uart speed at first!!!! IMPORTANT
1927+//add more speed if neccessary
1928+typedef struct _baudrate_ex
1929+{
1930+ RT_U32 rtk_speed;
1931+ int uart_speed;
1932+}baudrate_ex;
1933+
1934+#ifdef BAUDRATE_4BYTES
1935+baudrate_ex baudrates[] =
1936+{
1937+ {0x0252C014, 115200},
1938+ {0x0252C00A, 230400},
1939+ {0x05F75004, 921600},
1940+ {0x00005004, 1000000},
1941+ {0x04928002, 1500000},
1942+ {0x01128002, 1500000}, //8761AT
1943+ {0x00005002, 2000000},
1944+ {0x0000B001, 2500000},
1945+ {0x04928001, 3000000},
1946+ {0x052A6001, 3500000},
1947+ {0x00005001, 4000000},
1948+};
1949+#else
1950+baudrate_ex baudrates[] =
1951+{
1952+ {0x701d, 115200}
1953+ {0x6004, 921600},
1954+ {0x4003, 1500000},
1955+ {0x5002, 2000000},
1956+ {0x8001, 3000000},
1957+ {0x9001, 3000000},
1958+ {0x7001, 3500000},
1959+ {0x5001, 4000000},
1960+};
1961+#endif
1962+
1963+/**
1964+* Change realtek Bluetooth speed to uart speed. It is matching in the struct baudrates:
1965+*
1966+* @code
1967+* baudrate_ex baudrates[] =
1968+* {
1969+* {0x7001, 3500000},
1970+* {0x6004, 921600},
1971+* {0x4003, 1500000},
1972+* {0x5001, 4000000},
1973+* {0x5002, 2000000},
1974+* {0x8001, 3000000},
1975+* {0x701d, 115200}
1976+* };
1977+* @endcode
1978+*
1979+* If there is no match in baudrates, uart speed will be set as #115200.
1980+*
1981+* @param rtk_speed realtek Bluetooth speed
1982+* @param uart_speed uart speed
1983+*
1984+*/
1985+static void rtk_speed_to_uart_speed(RT_U32 rtk_speed, RT_U32* uart_speed)
1986+{
1987+ *uart_speed = 115200;
1988+
1989+ unsigned int i;
1990+ for (i = 0; i < sizeof(baudrates)/sizeof(baudrate_ex); i++)
1991+ {
1992+ if (baudrates[i].rtk_speed == rtk_speed){
1993+ *uart_speed = baudrates[i].uart_speed;
1994+ return;
1995+ }
1996+ }
1997+ return;
1998+}
1999+
2000+/**
2001+* Change uart speed to realtek Bluetooth speed. It is matching in the struct baudrates:
2002+*
2003+* @code
2004+* baudrate_ex baudrates[] =
2005+* {
2006+* {0x7001, 3500000},
2007+* {0x6004, 921600},
2008+* {0x4003, 1500000},
2009+* {0x5001, 4000000},
2010+* {0x5002, 2000000},
2011+* {0x8001, 3000000},
2012+* {0x701d, 115200}
2013+* };
2014+* @endcode
2015+*
2016+* If there is no match in baudrates, realtek Bluetooth speed will be set as #0x701D.
2017+*
2018+* @param uart_speed uart speed
2019+* @param rtk_speed realtek Bluetooth speed
2020+*
2021+*/
2022+static inline void uart_speed_to_rtk_speed(int uart_speed, RT_U32* rtk_speed)
2023+{
2024+ *rtk_speed = 0x701D;
2025+
2026+ unsigned int i;
2027+ for (i=0; i< sizeof(baudrates)/sizeof(baudrate_ex); i++)
2028+ {
2029+ if (baudrates[i].uart_speed == uart_speed){
2030+ *rtk_speed = baudrates[i].rtk_speed;
2031+ return;
2032+ }
2033+ }
2034+
2035+ return;
2036+}
2037+
2038+static void rtk_get_eversion_timeout(int sig)
2039+{
2040+ static int retries = 0;
2041+ int len = 0;
2042+
2043+ RS_DBG("RTK get HCI_VENDOR_READ_RTK_ROM_VERISION_Command\n");
2044+ if (retries < rtk_hw_cfg.h5_max_retries) {
2045+ RS_DBG("rtk get eversion timerout, retry:%d\n", retries);
2046+ if (rtk_hw_cfg.host_last_cmd) {
2047+ len = write(rtk_hw_cfg.serial_fd,
2048+ rtk_hw_cfg.host_last_cmd->data, rtk_hw_cfg.host_last_cmd->data_len);
2049+ }
2050+ retries++;
2051+ alarm(3);
2052+ return;
2053+ }
2054+ tcflush(rtk_hw_cfg.serial_fd, TCIOFLUSH);
2055+ RS_ERR("rtk get eversion cmd complete event timed out\n");
2056+ exit(1);
2057+}
2058+
2059+/**
2060+* Send vendor cmd to get eversion: 0xfc6d
2061+* If Rom code does not support this cmd, use default.
2062+*/
2063+void rtk_get_eversion(int dd)
2064+{
2065+ unsigned char bytes[READ_DATA_SIZE];
2066+ int retlen;
2067+ struct sigaction sa;
2068+ unsigned char read_rom_patch_cmd[3] = {0x6d, 0xfc, 00};
2069+ struct sk_buff *nskb = h5_prepare_pkt(&rtk_hw_cfg, read_rom_patch_cmd, 3, HCI_COMMAND_PKT);
2070+
2071+ if (rtk_hw_cfg.host_last_cmd){
2072+ skb_free(rtk_hw_cfg.host_last_cmd);
2073+ rtk_hw_cfg.host_last_cmd = NULL;
2074+ }
2075+
2076+ rtk_hw_cfg.host_last_cmd = nskb;
2077+
2078+ write(dd, nskb->data, nskb->data_len);
2079+ rtk_hw_cfg.rom_version_cmd_state = cmd_has_sent;
2080+ RS_DBG("RTK send HCI_VENDOR_READ_RTK_ROM_VERISION_Command\n");
2081+
2082+ alarm(0);
2083+ memset(&sa, 0, sizeof(sa));
2084+ sa.sa_flags = SA_NOCLDSTOP;
2085+ sa.sa_handler = rtk_get_eversion_timeout;
2086+ sigaction(SIGALRM, &sa, NULL);
2087+
2088+ alarm(3);
2089+ while (rtk_hw_cfg.rom_version_cmd_state != event_received) {
2090+ if ((retlen = read_check_rtk(dd, &bytes, READ_DATA_SIZE)) == -1)
2091+ {
2092+ perror("rtk get eversion: read fail");
2093+ return;
2094+ }
2095+ h5_recv(&rtk_hw_cfg, &bytes, retlen);
2096+ }
2097+ alarm(0);
2098+ return;
2099+}
2100+
2101+static void rtk_get_lmp_version_timeout(int sig)
2102+{
2103+ static int retries = 0;
2104+ RS_DBG("RTK get HCI_VENDOR_READ_RTK_LMP_VERISION_Command\n");
2105+ if (retries < rtk_hw_cfg.h5_max_retries) {
2106+ RS_DBG("rtk get lmp version timeout, retry: %d\n", retries);
2107+ if (rtk_hw_cfg.host_last_cmd)
2108+ {
2109+ int len = write(rtk_hw_cfg.serial_fd,
2110+ rtk_hw_cfg.host_last_cmd->data, rtk_hw_cfg.host_last_cmd->data_len);
2111+ }
2112+ retries++;
2113+ alarm(3);
2114+ return;
2115+ }
2116+ tcflush(rtk_hw_cfg.serial_fd, TCIOFLUSH);
2117+ RS_ERR("rtk get lmp version cmd complete event timed out\n");
2118+ exit(1);
2119+}
2120+
2121+void rtk_get_lmp_version(int dd)
2122+{
2123+ unsigned char bytes[READ_DATA_SIZE];
2124+ int retlen;
2125+ struct sigaction sa;
2126+ unsigned char read_rom_patch_cmd[3] = {0x01, 0x10, 00};
2127+ struct sk_buff *nskb = h5_prepare_pkt(&rtk_hw_cfg, read_rom_patch_cmd, 3, HCI_COMMAND_PKT); //data:len+head:4
2128+
2129+ if (rtk_hw_cfg.host_last_cmd){
2130+ skb_free(rtk_hw_cfg.host_last_cmd);
2131+ rtk_hw_cfg.host_last_cmd = NULL;
2132+ }
2133+
2134+ rtk_hw_cfg.host_last_cmd = nskb;
2135+
2136+ write(dd, nskb->data, nskb->data_len);
2137+ rtk_hw_cfg.hci_version_cmd_state = cmd_has_sent;
2138+ RS_DBG("RTK send HCI_VENDOR_READ_RTK_ROM_VERISION_Command\n");
2139+
2140+ alarm(0);
2141+ memset(&sa, 0, sizeof(sa));
2142+ sa.sa_flags = SA_NOCLDSTOP;
2143+ sa.sa_handler = rtk_get_lmp_version_timeout;
2144+ sigaction(SIGALRM, &sa, NULL);
2145+
2146+ alarm(3);
2147+ while (rtk_hw_cfg.hci_version_cmd_state != event_received) {
2148+ if ((retlen = read_check_rtk(dd, &bytes, READ_DATA_SIZE)) == -1)
2149+ {
2150+ perror("read fail");
2151+ return;
2152+ }
2153+ h5_recv(&rtk_hw_cfg, &bytes, retlen);
2154+ }
2155+ alarm(0);
2156+ return;
2157+}
2158+
2159+uint8_t rtk_get_fw_project_id(uint8_t *p_buf)
2160+{
2161+ uint8_t opcode;
2162+ uint8_t len;
2163+ uint8_t data = 0;
2164+
2165+ do {
2166+ opcode = *p_buf;
2167+ len = *(p_buf - 1);
2168+ if (opcode == 0x00) {
2169+ if (len == 1) {
2170+ data = *(p_buf - 2);
2171+ RS_DBG("rtk_get_fw_project_id: opcode %d, len %d, data %d", opcode, len, data);
2172+ break;
2173+ } else {
2174+ RS_ERR("rtk_get_fw_project_id: invalid len %d", len);
2175+ }
2176+ }
2177+ p_buf -= len + 2;
2178+ } while (*p_buf != 0xFF);
2179+
2180+ return data;
2181+}
2182+
2183+struct rtk_epatch_entry *rtk_get_patch_entry(void)
2184+{
2185+ uint16_t i;
2186+ struct rtk_epatch *patch;
2187+ struct rtk_epatch_entry *entry;
2188+ uint8_t *p;
2189+ uint16_t chip_id;
2190+
2191+ patch = (struct rtk_epatch *)rtk_hw_cfg.fw_buf;
2192+ entry = (struct rtk_epatch_entry *)malloc(sizeof(*entry));
2193+ if(!entry) {
2194+ RS_ERR("failed to allocate mem for patch entry");
2195+ return NULL;
2196+ }
2197+
2198+ patch->number_of_patch = le16_to_cpu(patch->number_of_patch);
2199+
2200+ RS_DBG("fw_ver 0x%08x, patch_num %d",
2201+ le32_to_cpu(patch->fw_version), patch->number_of_patch);
2202+
2203+ for (i = 0; i < patch->number_of_patch; i++) {
2204+ if(get_unaligned_le16(rtk_hw_cfg.fw_buf+14+2*i) == rtk_hw_cfg.eversion + 1) {
2205+ entry->chipID = rtk_hw_cfg.eversion + 1;
2206+ entry->patch_length = get_unaligned_le16(rtk_hw_cfg.fw_buf+14+2*patch->number_of_patch+2*i);
2207+ entry->start_offset = get_unaligned_le32(rtk_hw_cfg.fw_buf+14+4*patch->number_of_patch+4*i);
2208+ RS_DBG("patch length is 0x%x", entry->patch_length);
2209+ RS_DBG("start offset is 0x%x", entry->start_offset);
2210+ break;
2211+ }
2212+
2213+ }
2214+
2215+ if (i == patch->number_of_patch) {
2216+ RS_ERR("failed to get etnry");
2217+ free(entry);
2218+ entry = NULL;
2219+ }
2220+
2221+ return entry;
2222+}
2223+
2224+void rtk_get_final_patch(int fd, int proto)
2225+{
2226+ uint8_t proj_id = 0;
2227+ struct rtk_epatch_entry* entry = NULL;
2228+ struct rtk_epatch *patch = (struct rtk_epatch *)rtk_hw_cfg.fw_buf;
2229+
2230+ if (proto == HCI_UART_3WIRE) {
2231+ rtk_get_lmp_version(fd);
2232+ RS_DBG("gLmpVersion = 0x%x", rtk_hw_cfg.lmp_version);
2233+ }
2234+
2235+ if ((proto == HCI_UART_H4) || ((proto == HCI_UART_3WIRE) && (rtk_hw_cfg.lmp_version == ROM_LMP_8723a))){
2236+ if(memcmp(rtk_hw_cfg.fw_buf, RTK_EPATCH_SIGNATURE, 8) == 0){
2237+ RS_ERR("Check signature error!");
2238+ rtk_hw_cfg.dl_fw_flag = 0;
2239+ goto free_buf;
2240+ } else {
2241+ rtk_hw_cfg.total_len = rtk_hw_cfg.config_len + rtk_hw_cfg.fw_len;
2242+ if (!(rtk_hw_cfg.total_buf = malloc(rtk_hw_cfg.total_len))) {
2243+ RS_ERR("Can't alloc memory for fw&config, errno:%d", errno);
2244+ rtk_hw_cfg.dl_fw_flag = 0;
2245+ rtk_hw_cfg.total_len = 0;
2246+ goto free_buf;
2247+ } else {
2248+ RS_DBG("fw copy directy");
2249+ memcpy(rtk_hw_cfg.total_buf, rtk_hw_cfg.fw_buf, rtk_hw_cfg.fw_len);
2250+ if (rtk_hw_cfg.config_len)
2251+ memcpy(rtk_hw_cfg.total_buf+rtk_hw_cfg.fw_len, rtk_hw_cfg.config_buf, rtk_hw_cfg.config_len);
2252+ rtk_hw_cfg.dl_fw_flag = 1;
2253+ goto free_buf;
2254+ }
2255+ }
2256+ }
2257+
2258+ rtk_get_eversion(fd);
2259+ RS_DBG("rtk_hw_cfg.eversion = %d", rtk_hw_cfg.eversion);
2260+
2261+ if (memcmp(rtk_hw_cfg.fw_buf, RTK_EPATCH_SIGNATURE, 8)) {
2262+ RS_DBG("check signature error!");
2263+ rtk_hw_cfg.dl_fw_flag = 0;
2264+ goto free_buf;
2265+ }
2266+
2267+ if (memcmp(rtk_hw_cfg.fw_buf + rtk_hw_cfg.fw_len - 4, Extension_Section_SIGNATURE, 4)) {
2268+ RS_ERR("check extension section signature error");
2269+ rtk_hw_cfg.dl_fw_flag = 0;
2270+ goto free_buf;
2271+ }
2272+
2273+ proj_id = rtk_get_fw_project_id(rtk_hw_cfg.fw_buf + rtk_hw_cfg.fw_len - 5);
2274+ if(rtk_hw_cfg.lmp_version != project_id[proj_id]) {
2275+ RS_ERR("lmp_version is %x, project_id is %x, does not match!!!",
2276+ rtk_hw_cfg.lmp_version, project_id[proj_id]);
2277+ rtk_hw_cfg.dl_fw_flag = 0;
2278+ goto free_buf;
2279+ }
2280+
2281+ entry = rtk_get_patch_entry();
2282+
2283+ if(entry)
2284+ rtk_hw_cfg.total_len = entry->patch_length + rtk_hw_cfg.config_len;
2285+ else {
2286+ rtk_hw_cfg.dl_fw_flag = 0;
2287+ goto free_buf;
2288+ }
2289+
2290+ if (!(rtk_hw_cfg.total_buf = malloc(rtk_hw_cfg.total_len))) {
2291+ RS_ERR("Can't alloc memory for multi fw&config, errno:%d", errno);
2292+ rtk_hw_cfg.dl_fw_flag = 0;
2293+ rtk_hw_cfg.total_len = 0;
2294+ goto free_buf;
2295+ } else {
2296+ memcpy(rtk_hw_cfg.total_buf, rtk_hw_cfg.fw_buf + entry->start_offset, entry->patch_length);
2297+ memcpy(rtk_hw_cfg.total_buf + entry->patch_length - 4, &patch->fw_version, 4);
2298+ if (rtk_hw_cfg.config_len)
2299+ memcpy(rtk_hw_cfg.total_buf+entry->patch_length, rtk_hw_cfg.config_buf, rtk_hw_cfg.config_len);
2300+ rtk_hw_cfg.dl_fw_flag = 1;
2301+ }
2302+
2303+ RS_DBG("fw:%s exists, config file:%s exists", (rtk_hw_cfg.fw_len>0)?"":"not", (rtk_hw_cfg.config_len>0)?"":"not");
2304+
2305+free_buf:
2306+ if (rtk_hw_cfg.fw_len > 0) {
2307+ free(rtk_hw_cfg.fw_buf);
2308+ rtk_hw_cfg.fw_len = 0;
2309+ }
2310+
2311+ if (rtk_hw_cfg.config_len > 0) {
2312+ free(rtk_hw_cfg.config_buf);
2313+ rtk_hw_cfg.config_len = 0;
2314+ }
2315+
2316+ if(entry)
2317+ free(entry);
2318+}
2319+
2320+/**
2321+* Config realtek Bluetooth. The configuration parameter is get from config file and fw.
2322+* Config file is rtk8723_bt_config. which is set in rtk_get_bt_config.
2323+* fw file is "rlt8723a_chip_b_cut_bt40_fw", which is set in get_firmware_name.
2324+*
2325+* @warning maybe only one of config file and fw file exists. The bt_addr arg is stored in "/data/btmac.txt"
2326+* or "/data/misc/bluetoothd/bt_mac/btmac.txt",
2327+*
2328+* @param fd uart file descriptor
2329+* @param proto realtek Bluetooth protocol, shall be either HCI_UART_H4 or HCI_UART_3WIRE
2330+* @param speed init_speed in uart struct
2331+* @param ti termios struct
2332+* @returns #0 on success
2333+*/
2334+static int rtk_config(int fd, int proto, int speed, struct termios *ti)
2335+{
2336+ int final_speed = 0;
2337+ int ret = 0;
2338+
2339+ rtk_hw_cfg.config_len = rtk_get_bt_config(&rtk_hw_cfg.config_buf, &rtk_hw_cfg.baudrate);
2340+ if (rtk_hw_cfg.config_len < 0) {
2341+ RS_ERR("Get Config file error, just use efuse settings");
2342+ rtk_hw_cfg.config_len = 0;
2343+ }
2344+
2345+ rtk_hw_cfg.fw_len = rtk_get_bt_firmware(&rtk_hw_cfg.fw_buf);
2346+ if (rtk_hw_cfg.fw_len < 0) {
2347+ RS_ERR("Get BT firmware error");
2348+ rtk_hw_cfg.fw_len = 0;
2349+ return -1;
2350+ }else {
2351+ rtk_get_final_patch(fd, proto);
2352+ }
2353+
2354+ if (rtk_hw_cfg.total_len > RTK_PATCH_LENGTH_MAX) {
2355+ RS_ERR("total length of fw&config larger than allowed");
2356+ return -1;
2357+ }
2358+
2359+ /* change baudrate if needed */
2360+ if (rtk_hw_cfg.baudrate == 0) {
2361+ uart_speed_to_rtk_speed(speed, &rtk_hw_cfg.baudrate);
2362+ RS_DBG("no config file to set uart baudrate, use input parameters:%x, %x",
2363+ (unsigned int)speed, (unsigned int)rtk_hw_cfg.baudrate);
2364+ goto SET_FLOW_CONTRL;
2365+ } else
2366+ rtk_speed_to_uart_speed(rtk_hw_cfg.baudrate, (RT_U32*)&(rtk_hw_cfg.final_speed));
2367+
2368+ if (proto == HCI_UART_3WIRE)
2369+ rtk_vendor_change_speed_h5(fd, rtk_hw_cfg.baudrate);
2370+ else
2371+ rtk_vendor_change_speed_h4(fd, rtk_hw_cfg.baudrate);
2372+
2373+ usleep(50000);
2374+ final_speed = rtk_hw_cfg.final_speed ? rtk_hw_cfg.final_speed : speed;
2375+ RS_DBG("final_speed %d\n",final_speed);
2376+ if (set_speed(fd, ti, final_speed) < 0) {
2377+ RS_ERR("Can't set baud rate:%x, %x, %x", final_speed, rtk_hw_cfg.final_speed, speed);
2378+ return -1;
2379+ }
2380+
2381+SET_FLOW_CONTRL:
2382+ if (rtk_hw_cfg.hw_flow_control) {
2383+ RS_DBG("hw flow control enable");
2384+ ti->c_cflag |= CRTSCTS;
2385+
2386+ if (tcsetattr(fd, TCSANOW, ti) < 0) {
2387+ RS_ERR("Can't set port settings");
2388+ return -1;
2389+ }
2390+ } else {
2391+ RS_DBG("hw flow control disable");
2392+ ti->c_cflag &= ~CRTSCTS;
2393+ }
2394+
2395+ /* wait for while for controller to setup */
2396+ usleep(10000);
2397+
2398+ if ((rtk_hw_cfg.total_len > 0) && (rtk_hw_cfg.dl_fw_flag)) {
2399+ rtk_hw_cfg.link_estab_state = H5_PATCH;
2400+ rtk_hw_cfg.rx_index = -1;
2401+
2402+ ret = rtk_download_fw_config(fd, rtk_hw_cfg.total_buf, rtk_hw_cfg.total_len, rtk_hw_cfg.baudrate, proto, ti);
2403+ free(rtk_hw_cfg.total_buf);
2404+
2405+ if (ret < 0)
2406+ return ret;
2407+ }
2408+ RS_DBG("Init Process finished");
2409+ return 0;
2410+}
2411+
2412+/**
2413+* Init uart by realtek Bluetooth.
2414+*
2415+* @param fd uart file descriptor
2416+* @param proto realtek Bluetooth protocol, shall be either HCI_UART_H4 or HCI_UART_3WIRE
2417+* @param speed init_speed in uart struct
2418+* @param ti termios struct
2419+* @returns #0 on success, depend on rtk_config
2420+*/
2421+int rtk_init(int fd, int proto, int speed, struct termios *ti)
2422+{
2423+ struct sigaction sa;
2424+ int retlen;
2425+ RS_DBG("Realtek hciattach version %s \n", RTK_VERSION);
2426+
2427+ memset(&rtk_hw_cfg, 0, sizeof(rtk_hw_cfg));
2428+ rtk_hw_cfg.serial_fd = fd;
2429+ rtk_hw_cfg.dl_fw_flag = 1;
2430+
2431+ /* h4 will do nothing for init */
2432+ if (proto == HCI_UART_3WIRE) {
2433+ if(rtk_init_h5(fd, ti) < 0)
2434+ return -1;;
2435+ }
2436+
2437+ return rtk_config(fd, proto, speed, ti);
2438+}
2439+
2440+/**
2441+* Post uart by realtek Bluetooth. If gFinalSpeed is set, set uart speed with it.
2442+*
2443+* @param fd uart file descriptor
2444+* @param proto realtek Bluetooth protocol, shall be either HCI_UART_H4 or HCI_UART_3WIRE
2445+* @param ti termios struct
2446+* @returns #0 on success.
2447+*/
2448+int rtk_post(int fd, int proto, struct termios *ti)
2449+{
2450+ if (rtk_hw_cfg.final_speed)
2451+ return set_speed(fd, ti, rtk_hw_cfg.final_speed);
2452+
2453+ return 0;
2454+}
Show on old repository browser