1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun * 3*4882a593Smuzhiyun * BlueZ - Bluetooth protocol stack for Linux 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Copyright (C) 2003-2009 Marcel Holtmann <marcel@holtmann.org> 6*4882a593Smuzhiyun * 7*4882a593Smuzhiyun * 8*4882a593Smuzhiyun * This program is free software; you can redistribute it and/or modify 9*4882a593Smuzhiyun * it under the terms of the GNU General Public License as published by 10*4882a593Smuzhiyun * the Free Software Foundation; either version 2 of the License, or 11*4882a593Smuzhiyun * (at your option) any later version. 12*4882a593Smuzhiyun * 13*4882a593Smuzhiyun * This program is distributed in the hope that it will be useful, 14*4882a593Smuzhiyun * but WITHOUT ANY WARRANTY; without even the implied warranty of 15*4882a593Smuzhiyun * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*4882a593Smuzhiyun * GNU General Public License for more details. 17*4882a593Smuzhiyun * 18*4882a593Smuzhiyun * You should have received a copy of the GNU General Public License 19*4882a593Smuzhiyun * along with this program; if not, write to the Free Software 20*4882a593Smuzhiyun * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21*4882a593Smuzhiyun * 22*4882a593Smuzhiyun */ 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun #include <termios.h> 25*4882a593Smuzhiyun #include <stdint.h> 26*4882a593Smuzhiyun #include <syslog.h> 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun #if __BYTE_ORDER == __LITTLE_ENDIAN 29*4882a593Smuzhiyun #define cpu_to_le16(d) (d) 30*4882a593Smuzhiyun #define cpu_to_le32(d) (d) 31*4882a593Smuzhiyun #define le16_to_cpu(d) (d) 32*4882a593Smuzhiyun #define le32_to_cpu(d) (d) 33*4882a593Smuzhiyun #elif __BYTE_ORDER == __BIG_ENDIAN 34*4882a593Smuzhiyun #define cpu_to_le16(d) bswap_16(d) 35*4882a593Smuzhiyun #define cpu_to_le32(d) bswap_32(d) 36*4882a593Smuzhiyun #define le16_to_cpu(d) bswap_16(d) 37*4882a593Smuzhiyun #define le32_to_cpu(d) bswap_32(d) 38*4882a593Smuzhiyun #else 39*4882a593Smuzhiyun #error "Unknown byte order" 40*4882a593Smuzhiyun #endif 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun #ifndef N_HCI 43*4882a593Smuzhiyun #define N_HCI 15 44*4882a593Smuzhiyun #endif 45*4882a593Smuzhiyun 46*4882a593Smuzhiyun #define HCIUARTSETPROTO _IOW('U', 200, int) 47*4882a593Smuzhiyun #define HCIUARTGETPROTO _IOR('U', 201, int) 48*4882a593Smuzhiyun #define HCIUARTGETDEVICE _IOR('U', 202, int) 49*4882a593Smuzhiyun #define HCIUARTSETFLAGS _IOW('U', 203, int) 50*4882a593Smuzhiyun #define HCIUARTGETFLAGS _IOR('U', 204, int) 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun #define HCI_UART_H4 0 53*4882a593Smuzhiyun #define HCI_UART_BCSP 1 54*4882a593Smuzhiyun #define HCI_UART_3WIRE 2 55*4882a593Smuzhiyun #define HCI_UART_H4DS 3 56*4882a593Smuzhiyun #define HCI_UART_LL 4 57*4882a593Smuzhiyun #define HCI_UART_RAW_DEVICE 0 58*4882a593Smuzhiyun 59*4882a593Smuzhiyun extern uint8_t DBG_ON; 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun /* #define SYSLOG */ 62*4882a593Smuzhiyun 63*4882a593Smuzhiyun #define LOG_STR "Realtek Bluetooth" 64*4882a593Smuzhiyun #ifdef SYSLOG 65*4882a593Smuzhiyun #define RS_DBG(fmt, arg...) \ 66*4882a593Smuzhiyun do{ \ 67*4882a593Smuzhiyun if (DBG_ON) \ 68*4882a593Smuzhiyun syslog(LOG_DEBUG, "%s :" fmt "\n" , LOG_STR, ##arg); \ 69*4882a593Smuzhiyun }while(0) 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun #define RS_INFO(fmt, arg...) \ 72*4882a593Smuzhiyun do{ \ 73*4882a593Smuzhiyun syslog(LOG_INFO, "%s :" fmt "\n", LOG_STR, ##arg); \ 74*4882a593Smuzhiyun }while(0) 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun #define RS_WARN(fmt, arg...) \ 77*4882a593Smuzhiyun do{ \ 78*4882a593Smuzhiyun syslog(LOG_WARNING, "%s WARN: " fmt "\n", LOG_STR, ##arg); \ 79*4882a593Smuzhiyun }while(0) 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun #define RS_ERR(fmt, arg...) \ 82*4882a593Smuzhiyun do{ \ 83*4882a593Smuzhiyun syslog(LOG_ERR, "%s ERROR: " fmt "\n", LOG_STR, ##arg); \ 84*4882a593Smuzhiyun }while(0) 85*4882a593Smuzhiyun #else 86*4882a593Smuzhiyun #define RS_DBG(fmt, arg...) \ 87*4882a593Smuzhiyun do{ \ 88*4882a593Smuzhiyun if (DBG_ON) \ 89*4882a593Smuzhiyun printf("%s :" fmt "\n" , LOG_STR, ##arg); \ 90*4882a593Smuzhiyun }while(0) 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun #define RS_INFO(fmt, arg...) \ 93*4882a593Smuzhiyun do{ \ 94*4882a593Smuzhiyun printf("%s :" fmt "\n", LOG_STR, ##arg); \ 95*4882a593Smuzhiyun }while(0) 96*4882a593Smuzhiyun 97*4882a593Smuzhiyun #define RS_WARN(fmt, arg...) \ 98*4882a593Smuzhiyun do{ \ 99*4882a593Smuzhiyun printf("%s WARN: " fmt "\n", LOG_STR, ##arg); \ 100*4882a593Smuzhiyun }while(0) 101*4882a593Smuzhiyun 102*4882a593Smuzhiyun #define RS_ERR(fmt, arg...) \ 103*4882a593Smuzhiyun do{ \ 104*4882a593Smuzhiyun printf("%s ERROR: " fmt "\n", LOG_STR, ##arg); \ 105*4882a593Smuzhiyun }while(0) 106*4882a593Smuzhiyun #endif 107*4882a593Smuzhiyun 108*4882a593Smuzhiyun typedef enum _H5_RX_STATE { 109*4882a593Smuzhiyun H5_W4_PKT_DELIMITER, 110*4882a593Smuzhiyun H5_W4_PKT_START, 111*4882a593Smuzhiyun H5_W4_HDR, 112*4882a593Smuzhiyun H5_W4_DATA, 113*4882a593Smuzhiyun H5_W4_CRC 114*4882a593Smuzhiyun } H5_RX_STATE; 115*4882a593Smuzhiyun 116*4882a593Smuzhiyun typedef enum _H5_RX_ESC_STATE { 117*4882a593Smuzhiyun H5_ESCSTATE_NOESC, 118*4882a593Smuzhiyun H5_ESCSTATE_ESC 119*4882a593Smuzhiyun } H5_RX_ESC_STATE; 120*4882a593Smuzhiyun 121*4882a593Smuzhiyun typedef enum _H5_LINK_STATE { 122*4882a593Smuzhiyun H5_SYNC, 123*4882a593Smuzhiyun H5_CONFIG, 124*4882a593Smuzhiyun H5_INIT, 125*4882a593Smuzhiyun H5_PATCH, 126*4882a593Smuzhiyun H5_HCI_RESET, 127*4882a593Smuzhiyun H5_ACTIVE 128*4882a593Smuzhiyun } H5_LINK_STATE; 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun struct patch_info; 131*4882a593Smuzhiyun typedef struct rtb_struct { 132*4882a593Smuzhiyun /* three wire releated */ 133*4882a593Smuzhiyun uint8_t rxseq_txack; /* expected rx seq number */ 134*4882a593Smuzhiyun uint8_t rxack; /* last packet that the peer ack'ed */ 135*4882a593Smuzhiyun uint8_t use_crc; 136*4882a593Smuzhiyun uint8_t is_txack_req; /* txack required */ 137*4882a593Smuzhiyun uint8_t msgq_txseq; /* next pkt seq */ 138*4882a593Smuzhiyun uint16_t message_crc; 139*4882a593Smuzhiyun uint32_t rx_count; /* expected pkts to recv */ 140*4882a593Smuzhiyun 141*4882a593Smuzhiyun H5_RX_STATE rx_state; 142*4882a593Smuzhiyun H5_RX_ESC_STATE rx_esc_state; 143*4882a593Smuzhiyun H5_LINK_STATE link_estab_state; 144*4882a593Smuzhiyun 145*4882a593Smuzhiyun struct sk_buff *rx_skb; 146*4882a593Smuzhiyun 147*4882a593Smuzhiyun uint16_t num_of_cmd_sent; 148*4882a593Smuzhiyun uint16_t lmp_subver; 149*4882a593Smuzhiyun uint16_t hci_rev; 150*4882a593Smuzhiyun uint8_t hci_ver; 151*4882a593Smuzhiyun uint8_t eversion; 152*4882a593Smuzhiyun uint8_t chip_type; 153*4882a593Smuzhiyun uint8_t chip_ver; 154*4882a593Smuzhiyun 155*4882a593Smuzhiyun uint32_t vendor_baud; 156*4882a593Smuzhiyun uint8_t dl_fw_flag; 157*4882a593Smuzhiyun int serial_fd; 158*4882a593Smuzhiyun uint32_t uart_flow_ctrl; 159*4882a593Smuzhiyun uint32_t parenb: 16; 160*4882a593Smuzhiyun uint32_t pareven: 16; 161*4882a593Smuzhiyun int final_speed; 162*4882a593Smuzhiyun int total_num; /* total pkt number */ 163*4882a593Smuzhiyun int tx_index; /* current sending pkt number */ 164*4882a593Smuzhiyun int rx_index; /* ack index from board */ 165*4882a593Smuzhiyun int fw_len; /* fw patch file len */ 166*4882a593Smuzhiyun int config_len; /* config patch file len */ 167*4882a593Smuzhiyun int total_len; /* fw & config extracted buf len */ 168*4882a593Smuzhiyun uint8_t *fw_buf; /* fw patch file buf */ 169*4882a593Smuzhiyun uint8_t *config_buf; /* config patch file buf */ 170*4882a593Smuzhiyun uint8_t *total_buf; /* fw & config extracted buf */ 171*4882a593Smuzhiyun #define CMD_STATE_UNKNOWN 0x00 172*4882a593Smuzhiyun #define CMD_STATE_SUCCESS 0x01 173*4882a593Smuzhiyun struct __cmd_state { 174*4882a593Smuzhiyun uint16_t opcode; 175*4882a593Smuzhiyun uint16_t state; 176*4882a593Smuzhiyun } cmd_state; 177*4882a593Smuzhiyun 178*4882a593Smuzhiyun struct patch_info *patch_ent; 179*4882a593Smuzhiyun 180*4882a593Smuzhiyun int proto; 181*4882a593Smuzhiyun int timerfd; 182*4882a593Smuzhiyun int epollfd; 183*4882a593Smuzhiyun } rtb_struct_t; 184*4882a593Smuzhiyun extern struct rtb_struct rtb_cfg; 185*4882a593Smuzhiyun int timeout_set(int fd, unsigned int msec); 186*4882a593Smuzhiyun int set_speed(int fd, struct termios *ti, int speed); 187*4882a593Smuzhiyun int rtb_init(int fd, int proto, int speed, struct termios *ti); 188*4882a593Smuzhiyun int rtb_post(int fd, int proto, struct termios *ti); 189*4882a593Smuzhiyun void util_hexdump(const uint8_t *buf, size_t len); 190