123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373 |
- /*
- *
- * 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_HCIUART
- #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);
|