hc
2025-02-14 bbb9540dc49f70f6b703d1c8d1b85fa5f602d86e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
/*
*
*  Realtek Bluetooth USB driver
*
*
*  This program is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
*/
#include <net/bluetooth/hci_core.h>
#include <linux/list.h>
 
/***********************************
** Realtek - For coexistence **
***********************************/
#define BTRTL_HCIUSB    0
#define BTRTL_HCIUART   1
 
#define BTRTL_HCI_IF    BTRTL_HCIUSB
 
#define TRUE                1
#define FALSE               0
 
#define CONNECT_PORT        30001
#define CONNECT_PORT_WIFI   30000
 
#define invite_req          "INVITE_REQ"
#define invite_rsp          "INVITE_RSP"
#define attend_req          "ATTEND_REQ"
#define attend_ack          "ATTEND_ACK"
#define wifi_leave          "WIFI_LEAVE"
#define leave_ack           "LEAVE_ACK"
#define bt_leave            "BT_LEAVE"
 
#define HCI_OP_PERIODIC_INQ                                0x0403
#define HCI_EV_LE_META                                    0x3e
#define HCI_EV_LE_CONN_COMPLETE                            0x01
#define HCI_EV_LE_CONN_UPDATE_COMPLETE                    0x03
#define HCI_EV_LE_ENHANCED_CONN_COMPLETE    0x0a
 
//vendor cmd to fw
#define HCI_VENDOR_ENABLE_PROFILE_REPORT_COMMAND        0xfc18
#define HCI_VENDOR_SET_PROFILE_REPORT_COMMAND           0xfc19
#define HCI_VENDOR_MAILBOX_CMD                          0xfc8f
#define HCI_VENDOR_SET_BITPOOL                0xfc51
 
//subcmd to fw
#define HCI_VENDOR_SUB_CMD_WIFI_CHANNEL_AND_BANDWIDTH_CMD   0x11
#define HCI_VENDOR_SUB_CMD_WIFI_FORCE_TX_POWER_CMD          0x17
#define HCI_VENDOR_SUB_CMD_BT_ENABLE_IGNORE_WLAN_ACT_CMD    0x1B
#define HCI_VENDOR_SUB_CMD_BT_REPORT_CONN_SCO_INQ_INFO      0x23
#define HCI_VENDOR_SUB_CMD_BT_AUTO_REPORT_STATUS_INFO       0x27
#define HCI_VENDOR_SUB_CMD_BT_AUTO_REPORT_ENABLE            0x28
#define HCI_VENDOR_SUB_CMD_BT_SET_TXRETRY_REPORT_PARAM      0x29
#define HCI_VENDOR_SUB_CMD_BT_SET_PTATABLE                  0x2A
#define HCI_VENDOR_SUB_CMD_SET_BT_PSD_MODE                  0x31
#define HCI_VENDOR_SUB_CMD_SET_BT_LNA_CONSTRAINT            0x32
#define HCI_VENDOR_SUB_CMD_GET_AFH_MAP_L                    0x40
#define HCI_VENDOR_SUB_CMD_GET_AFH_MAP_M                    0x41
#define HCI_VENDOR_SUB_CMD_GET_AFH_MAP_H                    0x42
#define HCI_VENDOR_SUB_CMD_RD_REG_REQ                       0x43
#define HCI_VENDOR_SUB_CMD_WR_REG_REQ                       0x44
 
#define HCI_EV_VENDOR_SPECIFIC      0xff
 
//sub event from fw start
#define HCI_VENDOR_PTA_REPORT_EVENT         0x24
#define HCI_VENDOR_PTA_AUTO_REPORT_EVENT    0x25
 
//vendor cmd to wifi driver
#define HCI_GRP_VENDOR_SPECIFIC             (0x3f << 10)
#define HCI_OP_HCI_EXTENSION_VERSION_NOTIFY (0x0100 | HCI_GRP_VENDOR_SPECIFIC)
#define HCI_OP_BT_OPERATION_NOTIFY          (0x0102 | HCI_GRP_VENDOR_SPECIFIC)
#define HCI_OP_HCI_BT_INFO_NOTIFY           (0x0106 | HCI_GRP_VENDOR_SPECIFIC)
#define HCI_OP_HCI_BT_COEX_NOTIFY           (0x0107 | HCI_GRP_VENDOR_SPECIFIC)
#define HCI_OP_HCI_BT_PATCH_VER_NOTIFY      (0x0108 | HCI_GRP_VENDOR_SPECIFIC)
#define HCI_OP_HCI_BT_AFH_MAP_NOTIFY        (0x0109 | HCI_GRP_VENDOR_SPECIFIC)
#define HCI_OP_HCI_BT_REGISTER_VALUE_NOTIFY (0x010a | HCI_GRP_VENDOR_SPECIFIC)
 
//bt info reason to wifi
#define HOST_RESPONSE                   0    //Host response when receive the BT Info Control Event
#define POLLING_RESPONSE                1    //The BT Info response for polling by BT firmware.
#define AUTO_REPORT                     2    //BT auto report by BT firmware.
#define STACK_REPORT_WHILE_DEVICE_D2    3    //Stack report when BT firmware is under power save state(ex:D2)
 
// vendor event from wifi
#define RTK_HS_EXTENSION_EVENT_WIFI_SCAN            0x01
#define RTK_HS_EXTENSION_EVENT_RADIO_STATUS_NOTIFY  0x02
#define RTK_HS_EXTENSION_EVENT_HCI_BT_INFO_CONTROL  0x03
#define RTK_HS_EXTENSION_EVENT_HCI_BT_COEX_CONTROL  0x04
 
//op code from wifi
#define BT_PATCH_VERSION_QUERY      0x00
#define IGNORE_WLAN_ACTIVE_CONTROL  0x01
#define LNA_CONSTRAIN_CONTROL       0x02
#define BT_POWER_DECREASE_CONTROL   0x03
#define BT_PSD_MODE_CONTROL         0x04
#define WIFI_BW_CHNL_NOTIFY         0x05
#define QUERY_BT_AFH_MAP            0x06
#define BT_REGISTER_ACCESS          0x07
 
//bt operation to notify
#define BT_OPCODE_NONE                  0
#define BT_OPCODE_INQUIRY_START         1
#define BT_OPCODE_INQUIRY_END           2
#define BT_OPCODE_PAGE_START            3
#define BT_OPCODE_PAGE_SUCCESS_END      4
#define BT_OPCODE_PAGE_UNSUCCESS_END    5
#define BT_OPCODE_PAIR_START            6
#define BT_OPCODE_PAIR_END              7
#define BT_OPCODE_ENABLE_BT             8
#define BT_OPCODE_DISABLE_BT            9
 
#define HCI_EXTENSION_VERSION           0x0004
#define HCI_CMD_PREAMBLE_SIZE           3
#define PAN_PACKET_COUNT                5
 
#define STREAM_TO_UINT16(u16, p) {u16 = ((uint16_t)(*(p)) + (((uint16_t)(*((p) + 1))) << 8)); (p) += 2;}
#define UINT16_TO_STREAM(p, u16) {*(p)++ = (uint8_t)(u16); *(p)++ = (uint8_t)((u16) >> 8);}
 
#define PSM_SDP     0x0001
#define PSM_RFCOMM  0x0003
#define PSM_PAN     0x000F
#define PSM_HID     0x0011
#define PSM_HID_INT 0x0013
#define PSM_AVCTP   0x0017
#define PSM_AVDTP   0x0019
#define PSM_FTP     0x1001
#define PSM_BIP     0x1003
#define PSM_OPP     0x1015
//--add more if needed--//
 
enum {
   profile_sco = 0,
   profile_hid = 1,
   profile_a2dp = 2,
   profile_pan = 3,
   profile_hid_interval = 4,
   profile_hogp = 5,
   profile_voice = 6,
   profile_sink = 7,
   profile_max = 8
};
 
#define A2DP_SIGNAL    0x01
#define A2DP_MEDIA    0x02
//profile info data
typedef struct {
   struct list_head list;
   uint16_t handle;
   uint16_t psm;
   uint16_t dcid;
   uint16_t scid;
   uint8_t profile_index;
   uint8_t flags;
} rtk_prof_info, *prtk_prof_info;
 
//profile info for each connection
typedef struct rtl_hci_conn {
   struct list_head list;
   uint16_t handle;
   uint8_t type;        // 0:l2cap, 1:sco/esco, 2:le
   uint8_t profile_bitmap;
   int8_t profile_refcount[8];
} rtk_conn_prof, *prtk_conn_prof;
 
#ifdef RTB_SOFTWARE_MAILBOX
 
struct rtl_btinfo {
   u8 cmd;
   u8 len;
   u8 data[6];
};
#define RTL_BTINFO_LEN    (sizeof(struct rtl_btinfo))
/* typedef struct {
 *     uint8_t cmd_index;
 *     uint8_t cmd_length;
 *     uint8_t link_status;
 *     uint8_t retry_cnt;
 *     uint8_t rssi;
 *     uint8_t mailbox_info;
 *     uint16_t acl_throughput;
 * } hci_linkstatus_report; */
 
typedef struct {
   uint8_t type;
   uint32_t offset;
   uint32_t value;
} hci_mailbox_register;
 
struct rtl_btinfo_ctl {
   uint8_t polling_enable;
   uint8_t polling_time;
   uint8_t autoreport_enable;
};
#endif /* RTB_SOFTWARE_MAILBOX */
 
#define MAX_LEN_OF_HCI_EV    32
#define NUM_RTL_HCI_EV        32
struct rtl_hci_ev {
   __u8 data[MAX_LEN_OF_HCI_EV];
   __u16 len;
   struct list_head list;
};
 
#define L2_MAX_SUBSEC_LEN    128
#define L2_MAX_PKTS    16
struct rtl_l2_buff {
   __u8 data[L2_MAX_SUBSEC_LEN];
   __u16 len;
   __u16 out;
   struct list_head list;
};
 
struct rtl_coex_struct {
   struct list_head conn_hash;    //hash for connections
   struct list_head profile_list;    //hash for profile info
   struct hci_dev *hdev;
#ifdef RTB_SOFTWARE_MAILBOX
   struct socket *udpsock;
   struct sockaddr_in addr;
   struct sockaddr_in wifi_addr;
   struct timer_list polling_timer;
#endif
   struct timer_list a2dp_count_timer;
   struct timer_list pan_count_timer;
   struct timer_list hogp_count_timer;
#ifdef RTB_SOFTWARE_MAILBOX
   struct workqueue_struct *sock_wq;
   struct delayed_work sock_work;
#endif
   struct workqueue_struct *fw_wq;
   struct delayed_work fw_work;
   struct delayed_work l2_work;
#ifdef RTB_SOFTWARE_MAILBOX
   struct sock *sk;
#endif
   struct urb *urb;
   spinlock_t spin_lock_sock;
   spinlock_t spin_lock_profile;
   uint32_t a2dp_packet_count;
   uint32_t pan_packet_count;
   uint32_t hogp_packet_count;
   uint32_t voice_packet_count;
   uint8_t profile_bitmap;
   uint8_t profile_status;
   int8_t profile_refcount[8];
   uint8_t ispairing;
   uint8_t isinquirying;
   uint8_t ispaging;
#ifdef RTB_SOFTWARE_MAILBOX
   uint8_t wifi_state;
   uint8_t autoreport;
   uint8_t polling_enable;
   uint8_t polling_interval;
   uint8_t piconet_id;
   uint8_t mode;
   uint8_t afh_map[10];
#endif
   uint16_t hci_reversion;
   uint16_t lmp_subversion;
#ifdef RTB_SOFTWARE_MAILBOX
   uint8_t wifi_on;
   uint8_t sock_open;
#endif
   unsigned long cmd_last_tx;
 
   /* hci ev buff */
   struct list_head ev_used_list;
   struct list_head ev_free_list;
 
   spinlock_t rxlock;
   __u8 pkt_type;
   __u16 expect;
   __u8 *tbuff;
   __u16 elen;
   __u8 back_buff[HCI_MAX_EVENT_SIZE];
 
   /* l2cap rx buff */
   struct list_head l2_used_list;
   struct list_head l2_free_list;
 
   /* buff addr and size */
   spinlock_t buff_lock;
   unsigned long pages_addr;
   unsigned long buff_size;
 
#define RTL_COEX_RUNNING    (1 << 0)
   unsigned long flags;
 
};
 
#ifdef __LITTLE_ENDIAN
struct sbc_frame_hdr {
   uint8_t syncword:8;        /* Sync word */
   uint8_t subbands:1;        /* Subbands */
   uint8_t allocation_method:1;    /* Allocation method */
   uint8_t channel_mode:2;        /* Channel mode */
   uint8_t blocks:2;        /* Blocks */
   uint8_t sampling_frequency:2;    /* Sampling frequency */
   uint8_t bitpool:8;        /* Bitpool */
   uint8_t crc_check:8;        /* CRC check */
} __attribute__ ((packed));
 
/* NOTE: The code is copied from pa.
 * only the bit field in 8-bit is affected by endian, not the 16-bit or 32-bit.
 * why?
 */
struct rtp_header {
   unsigned cc:4;
   unsigned x:1;
   unsigned p:1;
   unsigned v:2;
 
   unsigned pt:7;
   unsigned m:1;
 
   uint16_t sequence_number;
   uint32_t timestamp;
   uint32_t ssrc;
   uint32_t csrc[0];
} __attribute__ ((packed));
 
#else
/* big endian */
struct sbc_frame_hdr {
   uint8_t syncword:8;        /* Sync word */
   uint8_t sampling_frequency:2;    /* Sampling frequency */
   uint8_t blocks:2;        /* Blocks */
   uint8_t channel_mode:2;        /* Channel mode */
   uint8_t allocation_method:1;    /* Allocation method */
   uint8_t subbands:1;        /* Subbands */
   uint8_t bitpool:8;        /* Bitpool */
   uint8_t crc_check:8;        /* CRC check */
} __attribute__ ((packed));
 
struct rtp_header {
   unsigned v:2;
   unsigned p:1;
   unsigned x:1;
   unsigned cc:4;
 
   unsigned m:1;
   unsigned pt:7;
 
   uint16_t sequence_number;
   uint32_t timestamp;
   uint32_t ssrc;
   uint32_t csrc[0];
} __attribute__ ((packed));
#endif /* __LITTLE_ENDIAN */
 
void rtk_btcoex_parse_event(uint8_t *buffer, int count);
void rtk_btcoex_parse_cmd(uint8_t *buffer, int count);
void rtk_btcoex_parse_l2cap_data_tx(uint8_t *buffer, int count);
void rtk_btcoex_parse_l2cap_data_rx(uint8_t *buffer, int count);
 
void rtk_btcoex_open(struct hci_dev *hdev);
void rtk_btcoex_close(void);
void rtk_btcoex_probe(struct hci_dev *hdev);
void rtk_btcoex_init(void);
void rtk_btcoex_exit(void);